openMSX
InputEvents.cc
Go to the documentation of this file.
1 #include "InputEvents.hh"
2 #include "Keys.hh"
3 #include "TclObject.hh"
4 #include "Timer.hh"
5 #include "checked_cast.hh"
6 #include "strCat.hh"
7 #include "stl.hh"
8 #include <string>
9 #include <tuple>
10 #include <SDL.h>
11 
12 using std::string;
13 
14 namespace openmsx {
15 
16 // class TimedEvent
17 
19  : Event(type_)
20  , realtime(Timer::getTime()) // TODO use SDL2 event timestamp
21 {
22 }
23 
24 
25 // class KeyEvent
26 
27 KeyEvent::KeyEvent(EventType type_, Keys::KeyCode keyCode_, Keys::KeyCode scanCode_, uint32_t unicode_)
28  : TimedEvent(type_), keyCode(keyCode_), scanCode(scanCode_), unicode(unicode_)
29 {
30 }
31 
32 TclObject KeyEvent::toTclList() const
33 {
34  // Note: 'scanCode' is not included (also not in equalImpl()).
35  //
36  // At the moment 'scanCode' is only used in the MSX Keyboard code when
37  // the POSITIONAL mapping mode is active. It is not used for key
38  // bindings (the 'bind' or the 'after' commands) or for the openMSX
39  // console. KeyEvents also don't end up in 'reverse replay' files
40  // (instead those files contain more low level MSX keyboard matrix
41  // changes).
42  //
43  // Within these constraints it's fine to ignore 'scanCode' in this
44  // method.
45  auto result = makeTclList("keyb", Keys::getName(getKeyCode()));
46  if (getUnicode() != 0) {
47  result.addListElement(tmpStrCat("unicode", getUnicode()));
48  }
49  return result;
50 }
51 
52 bool KeyEvent::equalImpl(const Event& other) const
53 {
54  // note: don't compare scancode, unicode
55  const auto& o = checked_cast<const KeyEvent&>(other);
56  return getKeyCode() == o.getKeyCode();
57 }
58 
59 
60 // class MouseButtonEvent
61 
63  : TimedEvent(type_), button(button_)
64 {
65 }
66 
67 TclObject MouseButtonEvent::toTclHelper(std::string_view direction) const
68 {
69  return makeTclList("mouse", tmpStrCat("button", getButton()), direction);
70 }
71 
72 bool MouseButtonEvent::equalImpl(const Event& other) const
73 {
74  const auto& o = checked_cast<const MouseButtonEvent&>(other);
75  return getButton() == o.getButton();
76 }
77 
78 
79 // class MouseButtonUpEvent
80 
83 {
84 }
85 
87 {
88  return toTclHelper("up");
89 }
90 
91 
92 // class MouseButtonDownEvent
93 
96 {
97 }
98 
100 {
101  return toTclHelper("down");
102 }
103 
104 
105 // class MouseWheelEvent
106 
109  , x(x_), y(y_)
110 {
111 }
112 
114 {
115  return makeTclList("mouse", "wheel", getX(), getY());
116 }
117 
118 bool MouseWheelEvent::equalImpl(const Event& other) const
119 {
120  const auto& o = checked_cast<const MouseWheelEvent&>(other);
121  return std::tuple( getX(), getY()) ==
122  std::tuple(o.getX(), o.getY());
123 }
124 
125 
126 // class MouseMotionEvent
127 
128 MouseMotionEvent::MouseMotionEvent(int xrel_, int yrel_, int xabs_, int yabs_)
130  , xrel(xrel_), yrel(yrel_)
131  , xabs(xabs_), yabs(yabs_)
132 {
133 }
134 
136 {
137  return makeTclList("mouse", "motion", getX(), getY(), getAbsX(), getAbsY());
138 }
139 
140 bool MouseMotionEvent::equalImpl(const Event& other) const
141 {
142  const auto& o = checked_cast<const MouseMotionEvent&>(other);
143  return std::tuple( getX(), getY(), getAbsX(), getAbsY()) ==
144  std::tuple(o.getX(), o.getY(), o.getAbsX(), o.getAbsY());
145 }
146 
147 
148 // class JoystickEvent
149 
150 JoystickEvent::JoystickEvent(EventType type_, unsigned joystick_)
151  : TimedEvent(type_), joystick(joystick_)
152 {
153 }
154 
156 {
157  return makeTclList(tmpStrCat("joy", getJoystick() + 1));
158 }
159 
160 
161 // class JoystickButtonEvent
162 
164  EventType type_, unsigned joystick_, unsigned button_)
165  : JoystickEvent(type_, joystick_), button(button_)
166 {
167 }
168 
169 TclObject JoystickButtonEvent::toTclHelper(std::string_view direction) const
170 {
171  auto result = JoystickEvent::toTclHelper();
172  result.addListElement(tmpStrCat("button", getButton()), direction);
173  return result;
174 }
175 
176 bool JoystickButtonEvent::equalImpl(const Event& other) const
177 {
178  const auto& o = checked_cast<const JoystickButtonEvent&>(other);
179  return std::tuple( getJoystick(), getButton()) ==
180  std::tuple(o.getJoystick(), o.getButton());
181 }
182 
183 
184 // class JoystickButtonUpEvent
185 
186 JoystickButtonUpEvent::JoystickButtonUpEvent(unsigned joystick_, unsigned button_)
187  : JoystickButtonEvent(OPENMSX_JOY_BUTTON_UP_EVENT, joystick_, button_)
188 {
189 }
190 
192 {
193  return toTclHelper("up");
194 }
195 
196 
197 // class JoystickButtonDownEvent
198 
199 JoystickButtonDownEvent::JoystickButtonDownEvent(unsigned joystick_, unsigned button_)
201 {
202 }
203 
205 {
206  return toTclHelper("down");
207 }
208 
209 
210 // class JoystickAxisMotionEvent
211 
213  unsigned joystick_, unsigned axis_, int value_)
215  , axis(axis_), value(value_)
216 {
217 }
218 
220 {
221  auto result = JoystickEvent::toTclHelper();
222  result.addListElement(tmpStrCat("axis", getAxis()), getValue());
223  return result;
224 }
225 
226 bool JoystickAxisMotionEvent::equalImpl(const Event& other) const
227 {
228  const auto& o = checked_cast<const JoystickAxisMotionEvent&>(other);
229  return std::tuple( getJoystick(), getAxis(), getValue()) ==
230  std::tuple(o.getJoystick(), o.getAxis(), o.getValue());
231 }
232 
233 
234 // class JoystickHatEvent
235 
236 JoystickHatEvent::JoystickHatEvent(unsigned joystick_, unsigned hat_, unsigned value_)
238  , hat(hat_), value(value_)
239 {
240 }
241 
243 {
244  auto result = JoystickEvent::toTclHelper();
245  const char* str = [&] {
246  switch (getValue()) {
247  case SDL_HAT_UP: return "up";
248  case SDL_HAT_RIGHT: return "right";
249  case SDL_HAT_DOWN: return "down";
250  case SDL_HAT_LEFT: return "left";
251  case SDL_HAT_RIGHTUP: return "rightup";
252  case SDL_HAT_RIGHTDOWN: return "rightdown";
253  case SDL_HAT_LEFTUP: return "leftup";
254  case SDL_HAT_LEFTDOWN: return "leftdown";
255  default: return "center";
256  }
257  }();
258  result.addListElement(tmpStrCat("hat", getHat()), str);
259  return result;
260 }
261 
262 bool JoystickHatEvent::equalImpl(const Event& other) const
263 {
264  const auto& o = checked_cast<const JoystickHatEvent&>(other);
265  return std::tuple( getJoystick(), getHat(), getValue()) ==
266  std::tuple(o.getJoystick(), o.getHat(), o.getValue());
267 }
268 
269 
270 // class FocusEvent
271 
273  : Event(OPENMSX_FOCUS_EVENT), gain(gain_)
274 {
275 }
276 
278 {
279  return makeTclList("focus", getGain());
280 }
281 
282 bool FocusEvent::equalImpl(const Event& other) const
283 {
284  const auto& o = checked_cast<const FocusEvent&>(other);
285  return getGain() == o.getGain();
286 }
287 
288 
289 // class ResizeEvent
290 
291 ResizeEvent::ResizeEvent(unsigned x_, unsigned y_)
292  : Event(OPENMSX_RESIZE_EVENT), x(x_), y(y_)
293 {
294 }
295 
297 {
298  return makeTclList("resize", int(getX()), int(getY()));
299 }
300 
301 bool ResizeEvent::equalImpl(const Event& other) const
302 {
303  const auto& o = checked_cast<const ResizeEvent&>(other);
304  return std::tuple( getX(), getY()) ==
305  std::tuple(o.getX(), o.getY());
306 }
307 
308 
309 // class FileDropEvent
310 
311 FileDropEvent::FileDropEvent(std::string fileName_)
312  : Event(OPENMSX_FILEDROP_EVENT), fileName(std::move(fileName_))
313 {
314 }
315 
317 {
318  return makeTclList("filedrop", fileName);
319 }
320 
321 bool FileDropEvent::equalImpl(const Event& other) const
322 {
323  const auto& o = checked_cast<const FileDropEvent&>(other);
324  return getFileName() == o.getFileName();
325 }
326 
327 
328 // class QuitEvent
329 
331 {
332 }
333 
335 {
336  return makeTclList("quit");
337 }
338 
339 bool QuitEvent::equalImpl(const Event& /*other*/) const
340 {
341  return true;
342 }
343 
344 // class OsdControlEvent
345 
347  EventType type_, unsigned button_,
348  std::shared_ptr<const Event> origEvent_)
349  : TimedEvent(type_), origEvent(std::move(origEvent_)), button(button_)
350 {
351 }
352 
353 bool OsdControlEvent::isRepeatStopper(const Event& other) const
354 {
355  // If this OsdControlEvent was generated by the other event, then
356  // repeat should not be stopped.
357  if (origEvent.get() == &other) return false;
358 
359  // If this OsdControlEvent event was generated by a joystick motion
360  // event and the new event is also a joystick motion event then don't
361  // stop repeat. We don't need to check the actual values of the events
362  // (it also isn't trivial), because when the values differ by enough,
363  // a new OsdControlEvent will be generated and that one will stop
364  // repeat.
365  return !dynamic_cast<const JoystickAxisMotionEvent*>(origEvent.get()) ||
366  !dynamic_cast<const JoystickAxisMotionEvent*>(&other);
367 }
368 
369 TclObject OsdControlEvent::toTclHelper(std::string_view direction) const
370 {
371  static constexpr const char* const names[] = {
372  "LEFT", "RIGHT", "UP", "DOWN", "A", "B"
373  };
374  return makeTclList("OSDcontrol", names[getButton()], direction);
375 }
376 
377 bool OsdControlEvent::equalImpl(const Event& other) const
378 {
379  const auto& o = checked_cast<const OsdControlEvent&>(other);
380  return getButton() == o.getButton();
381 }
382 
383 
384 // class OsdControlReleaseEvent
385 
387  unsigned button_, const std::shared_ptr<const Event>& origEvent_)
388  : OsdControlEvent(OPENMSX_OSD_CONTROL_RELEASE_EVENT, button_, origEvent_)
389 {
390 }
391 
393 {
394  return toTclHelper("RELEASE");
395 }
396 
397 
398 // class OsdControlPressEvent
399 
401  unsigned button_, const std::shared_ptr<const Event>& origEvent_)
402  : OsdControlEvent(OPENMSX_OSD_CONTROL_PRESS_EVENT, button_, origEvent_)
403 {
404 }
405 
407 {
408  return toTclHelper("PRESS");
409 }
410 
411 
412 // class GroupEvent
413 
414 GroupEvent::GroupEvent(EventType type_, std::vector<EventType> typesToMatch_, TclObject tclListComponents_)
415  : Event(type_)
416  , typesToMatch(std::move(typesToMatch_))
417  , tclListComponents(std::move(tclListComponents_))
418 {
419 }
420 
422 {
423  return tclListComponents;
424 }
425 
426 bool GroupEvent::equalImpl(const Event& /*other*/) const
427 {
428  // All Group events are equivalent
429  return true;
430 }
431 
432 bool GroupEvent::matches(const Event& other) const
433 {
434  return contains(typesToMatch, other.getType());
435 }
436 
437 
438 } // namespace openmsx
FileDropEvent(std::string fileName)
Definition: InputEvents.cc:311
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:316
const std::string & getFileName() const
Definition: InputEvents.hh:244
bool getGain() const
Definition: InputEvents.hh:216
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:277
FocusEvent(bool gain)
Definition: InputEvents.cc:272
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:421
GroupEvent(EventType type, std::vector< EventType > typesToMatch, TclObject tclListComponents)
Definition: InputEvents.cc:414
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:219
JoystickAxisMotionEvent(unsigned joystick, unsigned axis, int value)
Definition: InputEvents.cc:212
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:204
JoystickButtonDownEvent(unsigned joystick, unsigned button)
Definition: InputEvents.cc:199
JoystickButtonEvent(EventType type, unsigned joystick, unsigned button)
Definition: InputEvents.cc:163
unsigned getButton() const
Definition: InputEvents.hh:154
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:191
JoystickButtonUpEvent(unsigned joystick, unsigned button)
Definition: InputEvents.cc:186
JoystickEvent(EventType type, unsigned joystick)
Definition: InputEvents.cc:150
TclObject toTclHelper() const
Definition: InputEvents.cc:155
unsigned getJoystick() const
Definition: InputEvents.hh:140
unsigned getValue() const
Definition: InputEvents.hh:202
unsigned getHat() const
Definition: InputEvents.hh:201
JoystickHatEvent(unsigned joystick, unsigned hat, unsigned value)
Definition: InputEvents.cc:236
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:242
Keys::KeyCode getKeyCode() const
Definition: InputEvents.hh:29
uint32_t getUnicode() const
Definition: InputEvents.hh:31
KeyEvent(EventType type, Keys::KeyCode keyCode, Keys::KeyCode scanCode, uint32_t unicode)
Definition: InputEvents.cc:27
MouseButtonDownEvent(unsigned button)
Definition: InputEvents.cc:94
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:99
MouseButtonEvent(EventType type, unsigned button_)
Definition: InputEvents.cc:62
unsigned getButton() const
Definition: InputEvents.hh:79
TclObject toTclHelper(std::string_view direction) const
Definition: InputEvents.cc:67
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:86
MouseButtonUpEvent(unsigned button)
Definition: InputEvents.cc:81
MouseMotionEvent(int xrel, int yrel, int xabs, int yabs)
Definition: InputEvents.cc:128
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:135
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:113
MouseWheelEvent(int x, int y)
Definition: InputEvents.cc:107
OSD events are triggered by other events.
Definition: InputEvents.hh:267
TclObject toTclHelper(std::string_view direction) const
Definition: InputEvents.cc:369
bool isRepeatStopper(const Event &other) const final
Get the event that actually triggered the creation of this event.
Definition: InputEvents.cc:353
unsigned getButton() const
Definition: InputEvents.hh:272
OsdControlEvent(EventType type, unsigned button_, std::shared_ptr< const Event > origEvent)
Definition: InputEvents.cc:346
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:406
OsdControlPressEvent(unsigned button, const std::shared_ptr< const Event > &origEvent)
Definition: InputEvents.cc:400
OsdControlReleaseEvent(unsigned button, const std::shared_ptr< const Event > &origEvent)
Definition: InputEvents.cc:386
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:392
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:334
unsigned getY() const
Definition: InputEvents.hh:230
unsigned getX() const
Definition: InputEvents.hh:229
ResizeEvent(unsigned x, unsigned y)
Definition: InputEvents.cc:291
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:296
TimedEvent(EventType type)
Definition: InputEvents.cc:18
KeyCode
Constants that identify keys and key modifiers.
Definition: Keys.hh:26
string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:742
This file implemented 3 utility functions:
Definition: Autofire.cc:9
EventType
Definition: Event.hh:11
@ OPENMSX_RESIZE_EVENT
Definition: Event.hh:30
@ OPENMSX_OSD_CONTROL_PRESS_EVENT
Definition: Event.hh:35
@ OPENMSX_MOUSE_BUTTON_DOWN_EVENT
Definition: Event.hh:18
@ OPENMSX_MOUSE_BUTTON_UP_EVENT
Definition: Event.hh:17
@ OPENMSX_OSD_CONTROL_RELEASE_EVENT
Definition: Event.hh:34
@ OPENMSX_MOUSE_WHEEL_EVENT
Definition: Event.hh:20
@ OPENMSX_MOUSE_MOTION_EVENT
Definition: Event.hh:15
@ OPENMSX_QUIT_EVENT
Definition: Event.hh:33
@ OPENMSX_FILEDROP_EVENT
Definition: Event.hh:31
@ OPENMSX_FOCUS_EVENT
Definition: Event.hh:29
@ OPENMSX_JOY_HAT_EVENT
Definition: Event.hh:24
@ OPENMSX_JOY_BUTTON_UP_EVENT
Definition: Event.hh:26
@ OPENMSX_JOY_BUTTON_DOWN_EVENT
Definition: Event.hh:27
@ OPENMSX_JOY_AXIS_MOTION_EVENT
Definition: Event.hh:22
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:124
TclObject makeTclList(Args &&... args)
Definition: TclObject.hh:291
constexpr bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.
Definition: stl.hh:92
TemporaryString tmpStrCat(Ts &&... ts)
Definition: strCat.hh:659