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 lessImpl()).
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(strCat("unicode", getUnicode()));
48  }
49  return result;
50 }
51 
52 bool KeyEvent::lessImpl(const Event& other) const
53 {
54  // note: don't compare scancode, unicode
55  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", strCat("button", getButton()), direction);
70 }
71 
72 bool MouseButtonEvent::lessImpl(const Event& other) const
73 {
74  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::lessImpl(const Event& other) const
119 {
120  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::lessImpl(const Event& other) const
141 {
142  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(strCat("joy", getJoystick() + 1));
158 }
159 
160 bool JoystickEvent::lessImpl(const Event& other) const
161 {
162  auto& o = checked_cast<const JoystickEvent&>(other);
163  return (getJoystick() != o.getJoystick())
164  ? (getJoystick() < o.getJoystick())
165  : lessImpl(o);
166 }
167 
168 
169 // class JoystickButtonEvent
170 
172  EventType type_, unsigned joystick_, unsigned button_)
173  : JoystickEvent(type_, joystick_), button(button_)
174 {
175 }
176 
177 TclObject JoystickButtonEvent::toTclHelper(std::string_view direction) const
178 {
179  auto result = JoystickEvent::toTclHelper();
180  result.addListElement(strCat("button", getButton()), direction);
181  return result;
182 }
183 
184 bool JoystickButtonEvent::lessImpl(const JoystickEvent& other) const
185 {
186  auto& o = checked_cast<const JoystickButtonEvent&>(other);
187  return getButton() < o.getButton();
188 }
189 
190 
191 // class JoystickButtonUpEvent
192 
193 JoystickButtonUpEvent::JoystickButtonUpEvent(unsigned joystick_, unsigned button_)
194  : JoystickButtonEvent(OPENMSX_JOY_BUTTON_UP_EVENT, joystick_, button_)
195 {
196 }
197 
199 {
200  return toTclHelper("up");
201 }
202 
203 
204 // class JoystickButtonDownEvent
205 
206 JoystickButtonDownEvent::JoystickButtonDownEvent(unsigned joystick_, unsigned button_)
208 {
209 }
210 
212 {
213  return toTclHelper("down");
214 }
215 
216 
217 // class JoystickAxisMotionEvent
218 
220  unsigned joystick_, unsigned axis_, int value_)
222  , axis(axis_), value(value_)
223 {
224 }
225 
227 {
228  auto result = JoystickEvent::toTclHelper();
229  result.addListElement(strCat("axis", getAxis()), getValue());
230  return result;
231 }
232 
233 bool JoystickAxisMotionEvent::lessImpl(const JoystickEvent& other) const
234 {
235  auto& o = checked_cast<const JoystickAxisMotionEvent&>(other);
236  return std::tuple( getAxis(), getValue()) <
237  std::tuple(o.getAxis(), o.getValue());
238 }
239 
240 
241 // class JoystickHatEvent
242 
243 JoystickHatEvent::JoystickHatEvent(unsigned joystick_, unsigned hat_, unsigned value_)
245  , hat(hat_), value(value_)
246 {
247 }
248 
250 {
251  auto result = JoystickEvent::toTclHelper();
252  const char* str;
253  switch (getValue()) {
254  case SDL_HAT_UP: str = "up"; break;
255  case SDL_HAT_RIGHT: str = "right"; break;
256  case SDL_HAT_DOWN: str = "down"; break;
257  case SDL_HAT_LEFT: str = "left"; break;
258  case SDL_HAT_RIGHTUP: str = "rightup"; break;
259  case SDL_HAT_RIGHTDOWN: str = "rightdown"; break;
260  case SDL_HAT_LEFTUP: str = "leftup"; break;
261  case SDL_HAT_LEFTDOWN: str = "leftdown"; break;
262  default: str = "center"; break;
263  }
264  result.addListElement(strCat("hat", getHat()), str);
265  return result;
266 }
267 
268 bool JoystickHatEvent::lessImpl(const JoystickEvent& other) const
269 {
270  auto& o = checked_cast<const JoystickHatEvent&>(other);
271  return std::tuple( getHat(), getValue()) <
272  std::tuple(o.getHat(), o.getValue());
273 }
274 
275 
276 // class FocusEvent
277 
279  : Event(OPENMSX_FOCUS_EVENT), gain(gain_)
280 {
281 }
282 
284 {
285  return makeTclList("focus", getGain());
286 }
287 
288 bool FocusEvent::lessImpl(const Event& other) const
289 {
290  auto& o = checked_cast<const FocusEvent&>(other);
291  return getGain() < o.getGain();
292 }
293 
294 
295 // class ResizeEvent
296 
297 ResizeEvent::ResizeEvent(unsigned x_, unsigned y_)
298  : Event(OPENMSX_RESIZE_EVENT), x(x_), y(y_)
299 {
300 }
301 
303 {
304  return makeTclList("resize", int(getX()), int(getY()));
305 }
306 
307 bool ResizeEvent::lessImpl(const Event& other) const
308 {
309  auto& o = checked_cast<const ResizeEvent&>(other);
310  return std::tuple( getX(), getY()) <
311  std::tuple(o.getX(), o.getY());
312 }
313 
314 
315 // class FileDropEvent
316 
317 FileDropEvent::FileDropEvent(std::string fileName_)
318  : Event(OPENMSX_FILEDROP_EVENT), fileName(std::move(fileName_))
319 {
320 }
321 
323 {
324  return makeTclList("filedrop", fileName);
325 }
326 
327 bool FileDropEvent::lessImpl(const Event& other) const
328 {
329  auto& o = checked_cast<const FileDropEvent&>(other);
330  return getFileName() < o.getFileName();
331 }
332 
333 
334 // class QuitEvent
335 
337 {
338 }
339 
341 {
342  return makeTclList("quit");
343 }
344 
345 bool QuitEvent::lessImpl(const Event& /*other*/) const
346 {
347  return false;
348 }
349 
350 // class OsdControlEvent
351 
353  EventType type_, unsigned button_,
354  std::shared_ptr<const Event> origEvent_)
355  : TimedEvent(type_), origEvent(std::move(origEvent_)), button(button_)
356 {
357 }
358 
359 bool OsdControlEvent::isRepeatStopper(const Event& other) const
360 {
361  // If this OsdControlEvent was geneated by the other event, then
362  // repeat should not be stopped.
363  if (origEvent.get() == &other) return false;
364 
365  // If this OsdControlEvent event was generated by a joystick motion
366  // event and the new event is also a joystick motion event then don't
367  // stop repeat. We don't need to check the actual values of the events
368  // (it also isn't trivial), because when the values differ by enough,
369  // a new OsdControlEvent will be generated and that one will stop
370  // repeat.
371  return !dynamic_cast<const JoystickAxisMotionEvent*>(origEvent.get()) ||
372  !dynamic_cast<const JoystickAxisMotionEvent*>(&other);
373 }
374 
375 TclObject OsdControlEvent::toTclHelper(std::string_view direction) const
376 {
377  static constexpr const char* const names[] = {
378  "LEFT", "RIGHT", "UP", "DOWN", "A", "B"
379  };
380  return makeTclList("OSDcontrol", names[getButton()], direction);
381 }
382 
383 bool OsdControlEvent::lessImpl(const Event& other) const
384 {
385  auto& o = checked_cast<const OsdControlEvent&>(other);
386  return getButton() < o.getButton();
387 }
388 
389 
390 // class OsdControlReleaseEvent
391 
393  unsigned button_, const std::shared_ptr<const Event>& origEvent_)
394  : OsdControlEvent(OPENMSX_OSD_CONTROL_RELEASE_EVENT, button_, origEvent_)
395 {
396 }
397 
399 {
400  return toTclHelper("RELEASE");
401 }
402 
403 
404 // class OsdControlPressEvent
405 
407  unsigned button_, const std::shared_ptr<const Event>& origEvent_)
408  : OsdControlEvent(OPENMSX_OSD_CONTROL_PRESS_EVENT, button_, origEvent_)
409 {
410 }
411 
413 {
414  return toTclHelper("PRESS");
415 }
416 
417 
418 // class GroupEvent
419 
420 GroupEvent::GroupEvent(EventType type_, std::vector<EventType> typesToMatch_, const TclObject& tclListComponents_)
421  : Event(type_)
422  , typesToMatch(std::move(typesToMatch_))
423  , tclListComponents(tclListComponents_)
424 {
425 }
426 
428 {
429  return tclListComponents;
430 }
431 
432 bool GroupEvent::lessImpl(const Event& /*other*/) const
433 {
434  // All Group events are equivalent
435  return false;
436 }
437 
438 bool GroupEvent::matches(const Event& other) const
439 {
440  return contains(typesToMatch, other.getType());
441 }
442 
443 
444 } // namespace openmsx
openmsx::OPENMSX_MOUSE_WHEEL_EVENT
@ OPENMSX_MOUSE_WHEEL_EVENT
Definition: Event.hh:20
openmsx::JoystickButtonUpEvent::JoystickButtonUpEvent
JoystickButtonUpEvent(unsigned joystick, unsigned button)
Definition: InputEvents.cc:193
openmsx::OPENMSX_JOY_AXIS_MOTION_EVENT
@ OPENMSX_JOY_AXIS_MOTION_EVENT
Definition: Event.hh:22
openmsx::ResizeEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:302
openmsx::OPENMSX_QUIT_EVENT
@ OPENMSX_QUIT_EVENT
Definition: Event.hh:33
openmsx::MouseButtonEvent::MouseButtonEvent
MouseButtonEvent(EventType type, unsigned button_)
Definition: InputEvents.cc:62
openmsx::OPENMSX_MOUSE_MOTION_EVENT
@ OPENMSX_MOUSE_MOTION_EVENT
Definition: Event.hh:15
Timer.hh
openmsx::KeyEvent::KeyEvent
KeyEvent(EventType type, Keys::KeyCode keyCode, Keys::KeyCode scanCode, uint32_t unicode)
Definition: InputEvents.cc:27
openmsx::OsdControlReleaseEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:398
openmsx::Event
Definition: Event.hh:83
openmsx::JoystickHatEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:249
TclObject.hh
openmsx::MouseMotionEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:135
contains
bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.
Definition: stl.hh:92
openmsx::MouseButtonEvent::toTclHelper
TclObject toTclHelper(std::string_view direction) const
Definition: InputEvents.cc:67
openmsx::OsdControlPressEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:412
openmsx::OPENMSX_JOY_HAT_EVENT
@ OPENMSX_JOY_HAT_EVENT
Definition: Event.hh:24
openmsx::JoystickButtonEvent
Definition: InputEvents.hh:153
openmsx::MouseButtonEvent::getButton
unsigned getButton() const
Definition: InputEvents.hh:79
openmsx::KeyEvent::getUnicode
uint32_t getUnicode() const
Definition: InputEvents.hh:31
openmsx::OsdControlEvent::toTclHelper
TclObject toTclHelper(std::string_view direction) const
Definition: InputEvents.cc:375
openmsx::OPENMSX_OSD_CONTROL_PRESS_EVENT
@ OPENMSX_OSD_CONTROL_PRESS_EVENT
Definition: Event.hh:35
openmsx::TimedEvent
Definition: InputEvents.hh:13
openmsx::JoystickButtonDownEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:211
openmsx::JoystickEvent::getJoystick
unsigned getJoystick() const
Definition: InputEvents.hh:140
openmsx::MouseButtonDownEvent::MouseButtonDownEvent
MouseButtonDownEvent(unsigned button)
Definition: InputEvents.cc:94
openmsx::OsdControlEvent::getButton
unsigned getButton() const
Definition: InputEvents.hh:274
openmsx::ResizeEvent::getY
unsigned getY() const
Definition: InputEvents.hh:232
openmsx::JoystickAxisMotionEvent::JoystickAxisMotionEvent
JoystickAxisMotionEvent(unsigned joystick, unsigned axis, int value)
Definition: InputEvents.cc:219
openmsx::MouseWheelEvent::MouseWheelEvent
MouseWheelEvent(int x, int y)
Definition: InputEvents.cc:107
openmsx::ResizeEvent::getX
unsigned getX() const
Definition: InputEvents.hh:231
openmsx::JoystickAxisMotionEvent::getValue
int getValue() const
Definition: InputEvents.hh:190
openmsx::OPENMSX_MOUSE_BUTTON_UP_EVENT
@ OPENMSX_MOUSE_BUTTON_UP_EVENT
Definition: Event.hh:17
openmsx::JoystickAxisMotionEvent::getAxis
unsigned getAxis() const
Definition: InputEvents.hh:189
openmsx::Keys::getName
string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:740
openmsx::OsdControlEvent::isRepeatStopper
bool isRepeatStopper(const Event &other) const final override
Get the event that actually triggered the creation of this event.
Definition: InputEvents.cc:359
openmsx::JoystickAxisMotionEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:226
openmsx::ResizeEvent::ResizeEvent
ResizeEvent(unsigned x, unsigned y)
Definition: InputEvents.cc:297
openmsx::MouseMotionEvent::MouseMotionEvent
MouseMotionEvent(int xrel, int yrel, int xabs, int yabs)
Definition: InputEvents.cc:128
openmsx::MouseWheelEvent::getX
int getX() const
Definition: InputEvents.hh:109
openmsx::FocusEvent::getGain
bool getGain() const
Definition: InputEvents.hh:218
openmsx::OPENMSX_RESIZE_EVENT
@ OPENMSX_RESIZE_EVENT
Definition: Event.hh:30
InputEvents.hh
openmsx::OsdControlPressEvent::OsdControlPressEvent
OsdControlPressEvent(unsigned button, const std::shared_ptr< const Event > &origEvent)
Definition: InputEvents.cc:406
openmsx::FileDropEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:322
openmsx::JoystickEvent::JoystickEvent
JoystickEvent(EventType type, unsigned joystick)
Definition: InputEvents.cc:150
openmsx::JoystickHatEvent::getValue
unsigned getValue() const
Definition: InputEvents.hh:204
openmsx::JoystickHatEvent::JoystickHatEvent
JoystickHatEvent(unsigned joystick, unsigned hat, unsigned value)
Definition: InputEvents.cc:243
openmsx::MouseMotionEvent::getY
int getY() const
Definition: InputEvents.hh:124
openmsx::JoystickButtonEvent::getButton
unsigned getButton() const
Definition: InputEvents.hh:156
openmsx::MouseButtonUpEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:86
openmsx::GroupEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:427
Keys.hh
openmsx::JoystickButtonUpEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:198
openmsx::FileDropEvent::FileDropEvent
FileDropEvent(std::string fileName)
Definition: InputEvents.cc:317
openmsx::JoystickEvent
Definition: InputEvents.hh:137
openmsx::MouseWheelEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:113
openmsx::OPENMSX_FILEDROP_EVENT
@ OPENMSX_FILEDROP_EVENT
Definition: Event.hh:31
openmsx::OsdControlReleaseEvent::OsdControlReleaseEvent
OsdControlReleaseEvent(unsigned button, const std::shared_ptr< const Event > &origEvent)
Definition: InputEvents.cc:392
openmsx::x
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:1419
openmsx::MouseMotionEvent::getX
int getX() const
Definition: InputEvents.hh:123
checked_cast.hh
openmsx::TimedEvent::TimedEvent
TimedEvent(EventType type)
Definition: InputEvents.cc:18
openmsx::OPENMSX_FOCUS_EVENT
@ OPENMSX_FOCUS_EVENT
Definition: Event.hh:29
openmsx::MouseMotionEvent::getAbsX
int getAbsX() const
Definition: InputEvents.hh:125
openmsx::MouseButtonUpEvent::MouseButtonUpEvent
MouseButtonUpEvent(unsigned button)
Definition: InputEvents.cc:81
openmsx::JoystickEvent::toTclHelper
TclObject toTclHelper() const
Definition: InputEvents.cc:155
strCat.hh
openmsx::FocusEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:283
openmsx::EventType
EventType
Definition: Event.hh:10
openmsx::OPENMSX_MOUSE_BUTTON_DOWN_EVENT
@ OPENMSX_MOUSE_BUTTON_DOWN_EVENT
Definition: Event.hh:18
openmsx::makeTclList
TclObject makeTclList(Args &&... args)
Definition: TclObject.hh:280
openmsx::QuitEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:340
openmsx::MouseMotionEvent::getAbsY
int getAbsY() const
Definition: InputEvents.hh:126
stl.hh
openmsx::TclObject
Definition: TclObject.hh:21
openmsx::GroupEvent::GroupEvent
GroupEvent(EventType type, std::vector< EventType > typesToMatch, const TclObject &tclListComponents)
Definition: InputEvents.cc:420
openmsx::Keys::KeyCode
KeyCode
Constants that identify keys and key modifiers.
Definition: Keys.hh:26
openmsx::OPENMSX_JOY_BUTTON_DOWN_EVENT
@ OPENMSX_JOY_BUTTON_DOWN_EVENT
Definition: Event.hh:27
openmsx::JoystickAxisMotionEvent
Definition: InputEvents.hh:182
openmsx::MouseButtonDownEvent::toTclList
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:99
openmsx::OsdControlEvent
OSD events are triggered by other events.
Definition: InputEvents.hh:268
strCat
std::string strCat(Ts &&...ts)
Definition: strCat.hh:573
openmsx::KeyEvent::getKeyCode
Keys::KeyCode getKeyCode() const
Definition: InputEvents.hh:29
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
openmsx::FileDropEvent::getFileName
const std::string & getFileName() const
Definition: InputEvents.hh:246
openmsx::JoystickButtonDownEvent::JoystickButtonDownEvent
JoystickButtonDownEvent(unsigned joystick, unsigned button)
Definition: InputEvents.cc:206
openmsx::FocusEvent::FocusEvent
FocusEvent(bool gain)
Definition: InputEvents.cc:278
openmsx::OPENMSX_JOY_BUTTON_UP_EVENT
@ OPENMSX_JOY_BUTTON_UP_EVENT
Definition: Event.hh:26
openmsx::QuitEvent::QuitEvent
QuitEvent()
Definition: InputEvents.cc:336
openmsx::JoystickHatEvent::getHat
unsigned getHat() const
Definition: InputEvents.hh:203
openmsx::OsdControlEvent::OsdControlEvent
OsdControlEvent(EventType type, unsigned button_, std::shared_ptr< const Event > origEvent)
Definition: InputEvents.cc:352
openmsx::MouseWheelEvent::getY
int getY() const
Definition: InputEvents.hh:110
openmsx::MouseButtonEvent
Definition: InputEvents.hh:72
openmsx::OPENMSX_OSD_CONTROL_RELEASE_EVENT
@ OPENMSX_OSD_CONTROL_RELEASE_EVENT
Definition: Event.hh:34
openmsx::JoystickButtonEvent::JoystickButtonEvent
JoystickButtonEvent(EventType type, unsigned joystick, unsigned button)
Definition: InputEvents.cc:171