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