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(tmpStrCat("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  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::lessImpl(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::lessImpl(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::lessImpl(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 bool JoystickEvent::lessImpl(const Event& other) const
161 {
162  const 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(tmpStrCat("button", getButton()), direction);
181  return result;
182 }
183 
184 bool JoystickButtonEvent::lessImpl(const JoystickEvent& other) const
185 {
186  const 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(tmpStrCat("axis", getAxis()), getValue());
230  return result;
231 }
232 
233 bool JoystickAxisMotionEvent::lessImpl(const JoystickEvent& other) const
234 {
235  const 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: return "up";
255  case SDL_HAT_RIGHT: return "right";
256  case SDL_HAT_DOWN: return "down";
257  case SDL_HAT_LEFT: return "left";
258  case SDL_HAT_RIGHTUP: return "rightup";
259  case SDL_HAT_RIGHTDOWN: return "rightdown";
260  case SDL_HAT_LEFTUP: return "leftup";
261  case SDL_HAT_LEFTDOWN: return "leftdown";
262  default: return "center";
263  }
264  }();
265  result.addListElement(tmpStrCat("hat", getHat()), str);
266  return result;
267 }
268 
269 bool JoystickHatEvent::lessImpl(const JoystickEvent& other) const
270 {
271  const auto& o = checked_cast<const JoystickHatEvent&>(other);
272  return std::tuple( getHat(), getValue()) <
273  std::tuple(o.getHat(), o.getValue());
274 }
275 
276 
277 // class FocusEvent
278 
280  : Event(OPENMSX_FOCUS_EVENT), gain(gain_)
281 {
282 }
283 
285 {
286  return makeTclList("focus", getGain());
287 }
288 
289 bool FocusEvent::lessImpl(const Event& other) const
290 {
291  const auto& o = checked_cast<const FocusEvent&>(other);
292  return getGain() < o.getGain();
293 }
294 
295 
296 // class ResizeEvent
297 
298 ResizeEvent::ResizeEvent(unsigned x_, unsigned y_)
299  : Event(OPENMSX_RESIZE_EVENT), x(x_), y(y_)
300 {
301 }
302 
304 {
305  return makeTclList("resize", int(getX()), int(getY()));
306 }
307 
308 bool ResizeEvent::lessImpl(const Event& other) const
309 {
310  const auto& o = checked_cast<const ResizeEvent&>(other);
311  return std::tuple( getX(), getY()) <
312  std::tuple(o.getX(), o.getY());
313 }
314 
315 
316 // class FileDropEvent
317 
318 FileDropEvent::FileDropEvent(std::string fileName_)
319  : Event(OPENMSX_FILEDROP_EVENT), fileName(std::move(fileName_))
320 {
321 }
322 
324 {
325  return makeTclList("filedrop", fileName);
326 }
327 
328 bool FileDropEvent::lessImpl(const Event& other) const
329 {
330  const auto& o = checked_cast<const FileDropEvent&>(other);
331  return getFileName() < o.getFileName();
332 }
333 
334 
335 // class QuitEvent
336 
338 {
339 }
340 
342 {
343  return makeTclList("quit");
344 }
345 
346 bool QuitEvent::lessImpl(const Event& /*other*/) const
347 {
348  return false;
349 }
350 
351 // class OsdControlEvent
352 
354  EventType type_, unsigned button_,
355  std::shared_ptr<const Event> origEvent_)
356  : TimedEvent(type_), origEvent(std::move(origEvent_)), button(button_)
357 {
358 }
359 
360 bool OsdControlEvent::isRepeatStopper(const Event& other) const
361 {
362  // If this OsdControlEvent was generated by the other event, then
363  // repeat should not be stopped.
364  if (origEvent.get() == &other) return false;
365 
366  // If this OsdControlEvent event was generated by a joystick motion
367  // event and the new event is also a joystick motion event then don't
368  // stop repeat. We don't need to check the actual values of the events
369  // (it also isn't trivial), because when the values differ by enough,
370  // a new OsdControlEvent will be generated and that one will stop
371  // repeat.
372  return !dynamic_cast<const JoystickAxisMotionEvent*>(origEvent.get()) ||
373  !dynamic_cast<const JoystickAxisMotionEvent*>(&other);
374 }
375 
376 TclObject OsdControlEvent::toTclHelper(std::string_view direction) const
377 {
378  static constexpr const char* const names[] = {
379  "LEFT", "RIGHT", "UP", "DOWN", "A", "B"
380  };
381  return makeTclList("OSDcontrol", names[getButton()], direction);
382 }
383 
384 bool OsdControlEvent::lessImpl(const Event& other) const
385 {
386  const auto& o = checked_cast<const OsdControlEvent&>(other);
387  return getButton() < o.getButton();
388 }
389 
390 
391 // class OsdControlReleaseEvent
392 
394  unsigned button_, const std::shared_ptr<const Event>& origEvent_)
395  : OsdControlEvent(OPENMSX_OSD_CONTROL_RELEASE_EVENT, button_, origEvent_)
396 {
397 }
398 
400 {
401  return toTclHelper("RELEASE");
402 }
403 
404 
405 // class OsdControlPressEvent
406 
408  unsigned button_, const std::shared_ptr<const Event>& origEvent_)
409  : OsdControlEvent(OPENMSX_OSD_CONTROL_PRESS_EVENT, button_, origEvent_)
410 {
411 }
412 
414 {
415  return toTclHelper("PRESS");
416 }
417 
418 
419 // class GroupEvent
420 
421 GroupEvent::GroupEvent(EventType type_, std::vector<EventType> typesToMatch_, TclObject tclListComponents_)
422  : Event(type_)
423  , typesToMatch(std::move(typesToMatch_))
424  , tclListComponents(std::move(tclListComponents_))
425 {
426 }
427 
429 {
430  return tclListComponents;
431 }
432 
433 bool GroupEvent::lessImpl(const Event& /*other*/) const
434 {
435  // All Group events are equivalent
436  return false;
437 }
438 
439 bool GroupEvent::matches(const Event& other) const
440 {
441  return contains(typesToMatch, other.getType());
442 }
443 
444 
445 } // namespace openmsx
FileDropEvent(std::string fileName)
Definition: InputEvents.cc:318
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:323
const std::string & getFileName() const
Definition: InputEvents.hh:246
bool getGain() const
Definition: InputEvents.hh:218
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:284
FocusEvent(bool gain)
Definition: InputEvents.cc:279
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:428
GroupEvent(EventType type, std::vector< EventType > typesToMatch, TclObject tclListComponents)
Definition: InputEvents.cc:421
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:226
JoystickAxisMotionEvent(unsigned joystick, unsigned axis, int value)
Definition: InputEvents.cc:219
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:211
JoystickButtonDownEvent(unsigned joystick, unsigned button)
Definition: InputEvents.cc:206
JoystickButtonEvent(EventType type, unsigned joystick, unsigned button)
Definition: InputEvents.cc:171
unsigned getButton() const
Definition: InputEvents.hh:156
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:198
JoystickButtonUpEvent(unsigned joystick, unsigned button)
Definition: InputEvents.cc:193
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:204
unsigned getHat() const
Definition: InputEvents.hh:203
JoystickHatEvent(unsigned joystick, unsigned hat, unsigned value)
Definition: InputEvents.cc:243
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:249
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:269
TclObject toTclHelper(std::string_view direction) const
Definition: InputEvents.cc:376
bool isRepeatStopper(const Event &other) const final
Get the event that actually triggered the creation of this event.
Definition: InputEvents.cc:360
unsigned getButton() const
Definition: InputEvents.hh:274
OsdControlEvent(EventType type, unsigned button_, std::shared_ptr< const Event > origEvent)
Definition: InputEvents.cc:353
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:413
OsdControlPressEvent(unsigned button, const std::shared_ptr< const Event > &origEvent)
Definition: InputEvents.cc:407
OsdControlReleaseEvent(unsigned button, const std::shared_ptr< const Event > &origEvent)
Definition: InputEvents.cc:393
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:399
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:341
unsigned getY() const
Definition: InputEvents.hh:232
unsigned getX() const
Definition: InputEvents.hh:231
ResizeEvent(unsigned x, unsigned y)
Definition: InputEvents.cc:298
TclObject toTclList() const override
Similar to toString(), but retains the structure of the event.
Definition: InputEvents.cc:303
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