1 //============================================================================
2 //
3 //   SSSS    tt          lll  lll
4 //  SS  SS   tt           ll   ll
5 //  SS     tttttt  eeee   ll   ll   aaaa
6 //   SSSS    tt   ee  ee  ll   ll      aa
7 //      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
8 //  SS  SS   tt   ee      ll   ll  aa  aa
9 //   SSSS     ttt  eeeee llll llll  aaaaa
10 //
11 // Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
12 // and the Stella Team
13 //
14 // See the file "License.txt" for information on usage and redistribution of
15 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 //============================================================================
17 
18 #ifndef STELLA_KEYS_HXX
19 #define STELLA_KEYS_HXX
20 
21 #ifdef SDL_SUPPORT
22   #include "SDL_lib.hxx"
23 #endif
24 
25 /**
26   This class implements a thin wrapper around the SDL keysym enumerations,
27   such that SDL-specific code doesn't have to go into the internal parts of
28   the codebase.  The keycodes are exactly the same, but from the POV of the
29   rest of the code, they are *KBD* (keyboard) keys, not *SDL* keys.
30 
31   If the codebase is ported to future SDL versions or to some other toolkit,
32   the intent is to simply change this file without having to modify all
33   other classes that use StellaKey.
34 
35   @author  Stephen Anthony
36 */
37 
38 // This comes directly from SDL_scancode.h
39 enum StellaKey
40 {
41     KBDK_UNKNOWN = 0,
42 
43     /**
44      *  \name Usage page 0x07
45      *
46      *  These values are from usage page 0x07 (USB keyboard page).
47      */
48     /* @{ */
49 
50     KBDK_A = 4,
51     KBDK_B = 5,
52     KBDK_C = 6,
53     KBDK_D = 7,
54     KBDK_E = 8,
55     KBDK_F = 9,
56     KBDK_G = 10,
57     KBDK_H = 11,
58     KBDK_I = 12,
59     KBDK_J = 13,
60     KBDK_K = 14,
61     KBDK_L = 15,
62     KBDK_M = 16,
63     KBDK_N = 17,
64     KBDK_O = 18,
65     KBDK_P = 19,
66     KBDK_Q = 20,
67     KBDK_R = 21,
68     KBDK_S = 22,
69     KBDK_T = 23,
70     KBDK_U = 24,
71     KBDK_V = 25,
72     KBDK_W = 26,
73     KBDK_X = 27,
74     KBDK_Y = 28,
75     KBDK_Z = 29,
76 
77     KBDK_1 = 30,
78     KBDK_2 = 31,
79     KBDK_3 = 32,
80     KBDK_4 = 33,
81     KBDK_5 = 34,
82     KBDK_6 = 35,
83     KBDK_7 = 36,
84     KBDK_8 = 37,
85     KBDK_9 = 38,
86     KBDK_0 = 39,
87 
88     KBDK_RETURN = 40,
89     KBDK_ESCAPE = 41,
90     KBDK_BACKSPACE = 42,
91     KBDK_TAB = 43,
92     KBDK_SPACE = 44,
93 
94     KBDK_MINUS = 45,
95     KBDK_EQUALS = 46,
96     KBDK_LEFTBRACKET = 47,
97     KBDK_RIGHTBRACKET = 48,
98     KBDK_BACKSLASH = 49, /**< Located at the lower left of the return
99                                   *   key on ISO keyboards and at the right end
100                                   *   of the QWERTY row on ANSI keyboards.
101                                   *   Produces REVERSE SOLIDUS (backslash) and
102                                   *   VERTICAL LINE in a US layout, REVERSE
103                                   *   SOLIDUS and VERTICAL LINE in a UK Mac
104                                   *   layout, NUMBER SIGN and TILDE in a UK
105                                   *   Windows layout, DOLLAR SIGN and POUND SIGN
106                                   *   in a Swiss German layout, NUMBER SIGN and
107                                   *   APOSTROPHE in a German layout, GRAVE
108                                   *   ACCENT and POUND SIGN in a French Mac
109                                   *   layout, and ASTERISK and MICRO SIGN in a
110                                   *   French Windows layout.
111                                   */
112     KBDK_NONUSHASH = 50, /**< ISO USB keyboards actually use this code
113                                   *   instead of 49 for the same key, but all
114                                   *   OSes I've seen treat the two codes
115                                   *   identically. So, as an implementor, unless
116                                   *   your keyboard generates both of those
117                                   *   codes and your OS treats them differently,
118                                   *   you should generate KBDK_BACKSLASH
119                                   *   instead of this code. As a user, you
120                                   *   should not rely on this code because SDL
121                                   *   will never generate it with most (all?)
122                                   *   keyboards.
123                                   */
124     KBDK_SEMICOLON = 51,
125     KBDK_APOSTROPHE = 52,
126     KBDK_GRAVE = 53, /**< Located in the top left corner (on both ANSI
127                               *   and ISO keyboards). Produces GRAVE ACCENT and
128                               *   TILDE in a US Windows layout and in US and UK
129                               *   Mac layouts on ANSI keyboards, GRAVE ACCENT
130                               *   and NOT SIGN in a UK Windows layout, SECTION
131                               *   SIGN and PLUS-MINUS SIGN in US and UK Mac
132                               *   layouts on ISO keyboards, SECTION SIGN and
133                               *   DEGREE SIGN in a Swiss German layout (Mac:
134                               *   only on ISO keyboards), CIRCUMFLEX ACCENT and
135                               *   DEGREE SIGN in a German layout (Mac: only on
136                               *   ISO keyboards), SUPERSCRIPT TWO and TILDE in a
137                               *   French Windows layout, COMMERCIAL AT and
138                               *   NUMBER SIGN in a French Mac layout on ISO
139                               *   keyboards, and LESS-THAN SIGN and GREATER-THAN
140                               *   SIGN in a Swiss German, German, or French Mac
141                               *   layout on ANSI keyboards.
142                               */
143     KBDK_COMMA = 54,
144     KBDK_PERIOD = 55,
145     KBDK_SLASH = 56,
146 
147     KBDK_CAPSLOCK = 57,
148 
149     KBDK_F1 = 58,
150     KBDK_F2 = 59,
151     KBDK_F3 = 60,
152     KBDK_F4 = 61,
153     KBDK_F5 = 62,
154     KBDK_F6 = 63,
155     KBDK_F7 = 64,
156     KBDK_F8 = 65,
157     KBDK_F9 = 66,
158     KBDK_F10 = 67,
159     KBDK_F11 = 68,
160     KBDK_F12 = 69,
161 
162     KBDK_PRINTSCREEN = 70,
163     KBDK_SCROLLLOCK = 71,
164     KBDK_PAUSE = 72,
165     KBDK_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but
166                                    does send code 73, not 117) */
167     KBDK_HOME = 74,
168     KBDK_PAGEUP = 75,
169     KBDK_DELETE = 76,
170     KBDK_END = 77,
171     KBDK_PAGEDOWN = 78,
172     KBDK_RIGHT = 79,
173     KBDK_LEFT = 80,
174     KBDK_DOWN = 81,
175     KBDK_UP = 82,
176 
177     KBDK_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards
178                                      */
179     KBDK_KP_DIVIDE = 84,
180     KBDK_KP_MULTIPLY = 85,
181     KBDK_KP_MINUS = 86,
182     KBDK_KP_PLUS = 87,
183     KBDK_KP_ENTER = 88,
184     KBDK_KP_1 = 89,
185     KBDK_KP_2 = 90,
186     KBDK_KP_3 = 91,
187     KBDK_KP_4 = 92,
188     KBDK_KP_5 = 93,
189     KBDK_KP_6 = 94,
190     KBDK_KP_7 = 95,
191     KBDK_KP_8 = 96,
192     KBDK_KP_9 = 97,
193     KBDK_KP_0 = 98,
194     KBDK_KP_PERIOD = 99,
195 
196     KBDK_NONUSBACKSLASH = 100, /**< This is the additional key that ISO
197                                         *   keyboards have over ANSI ones,
198                                         *   located between left shift and Y.
199                                         *   Produces GRAVE ACCENT and TILDE in a
200                                         *   US or UK Mac layout, REVERSE SOLIDUS
201                                         *   (backslash) and VERTICAL LINE in a
202                                         *   US or UK Windows layout, and
203                                         *   LESS-THAN SIGN and GREATER-THAN SIGN
204                                         *   in a Swiss German, German, or French
205                                         *   layout. */
206     KBDK_APPLICATION = 101, /**< windows contextual menu, compose */
207     KBDK_POWER = 102, /**< The USB document says this is a status flag,
208                                *   not a physical key - but some Mac keyboards
209                                *   do have a power key. */
210     KBDK_KP_EQUALS = 103,
211     KBDK_F13 = 104,
212     KBDK_F14 = 105,
213     KBDK_F15 = 106,
214     KBDK_F16 = 107,
215     KBDK_F17 = 108,
216     KBDK_F18 = 109,
217     KBDK_F19 = 110,
218     KBDK_F20 = 111,
219     KBDK_F21 = 112,
220     KBDK_F22 = 113,
221     KBDK_F23 = 114,
222     KBDK_F24 = 115,
223     KBDK_EXECUTE = 116,
224     KBDK_HELP = 117,
225     KBDK_MENU = 118,
226     KBDK_SELECT = 119,
227     KBDK_STOP = 120,
228     KBDK_AGAIN = 121,   /**< redo */
229     KBDK_UNDO = 122,
230     KBDK_CUT = 123,
231     KBDK_COPY = 124,
232     KBDK_PASTE = 125,
233     KBDK_FIND = 126,
234     KBDK_MUTE = 127,
235     KBDK_VOLUMEUP = 128,
236     KBDK_VOLUMEDOWN = 129,
237 /* not sure whether there's a reason to enable these */
238 /*     KBDK_LOCKINGCAPSLOCK = 130,  */
239 /*     KBDK_LOCKINGNUMLOCK = 131, */
240 /*     KBDK_LOCKINGSCROLLLOCK = 132, */
241     KBDK_KP_COMMA = 133,
242     KBDK_KP_EQUALSAS400 = 134,
243 
244     KBDK_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see
245                                             footnotes in USB doc */
246     KBDK_INTERNATIONAL2 = 136,
247     KBDK_INTERNATIONAL3 = 137, /**< Yen */
248     KBDK_INTERNATIONAL4 = 138,
249     KBDK_INTERNATIONAL5 = 139,
250     KBDK_INTERNATIONAL6 = 140,
251     KBDK_INTERNATIONAL7 = 141,
252     KBDK_INTERNATIONAL8 = 142,
253     KBDK_INTERNATIONAL9 = 143,
254     KBDK_LANG1 = 144, /**< Hangul/English toggle */
255     KBDK_LANG2 = 145, /**< Hanja conversion */
256     KBDK_LANG3 = 146, /**< Katakana */
257     KBDK_LANG4 = 147, /**< Hiragana */
258     KBDK_LANG5 = 148, /**< Zenkaku/Hankaku */
259     KBDK_LANG6 = 149, /**< reserved */
260     KBDK_LANG7 = 150, /**< reserved */
261     KBDK_LANG8 = 151, /**< reserved */
262     KBDK_LANG9 = 152, /**< reserved */
263 
264     KBDK_ALTERASE = 153, /**< Erase-Eaze */
265     KBDK_SYSREQ = 154,
266     KBDK_CANCEL = 155,
267     KBDK_CLEAR = 156,
268     KBDK_PRIOR = 157,
269     KBDK_RETURN2 = 158,
270     KBDK_SEPARATOR = 159,
271     KBDK_OUT = 160,
272     KBDK_OPER = 161,
273     KBDK_CLEARAGAIN = 162,
274     KBDK_CRSEL = 163,
275     KBDK_EXSEL = 164,
276 
277     KBDK_KP_00 = 176,
278     KBDK_KP_000 = 177,
279     KBDK_THOUSANDSSEPARATOR = 178,
280     KBDK_DECIMALSEPARATOR = 179,
281     KBDK_CURRENCYUNIT = 180,
282     KBDK_CURRENCYSUBUNIT = 181,
283     KBDK_KP_LEFTPAREN = 182,
284     KBDK_KP_RIGHTPAREN = 183,
285     KBDK_KP_LEFTBRACE = 184,
286     KBDK_KP_RIGHTBRACE = 185,
287     KBDK_KP_TAB = 186,
288     KBDK_KP_BACKSPACE = 187,
289     KBDK_KP_A = 188,
290     KBDK_KP_B = 189,
291     KBDK_KP_C = 190,
292     KBDK_KP_D = 191,
293     KBDK_KP_E = 192,
294     KBDK_KP_F = 193,
295     KBDK_KP_XOR = 194,
296     KBDK_KP_POWER = 195,
297     KBDK_KP_PERCENT = 196,
298     KBDK_KP_LESS = 197,
299     KBDK_KP_GREATER = 198,
300     KBDK_KP_AMPERSAND = 199,
301     KBDK_KP_DBLAMPERSAND = 200,
302     KBDK_KP_VERTICALBAR = 201,
303     KBDK_KP_DBLVERTICALBAR = 202,
304     KBDK_KP_COLON = 203,
305     KBDK_KP_HASH = 204,
306     KBDK_KP_SPACE = 205,
307     KBDK_KP_AT = 206,
308     KBDK_KP_EXCLAM = 207,
309     KBDK_KP_MEMSTORE = 208,
310     KBDK_KP_MEMRECALL = 209,
311     KBDK_KP_MEMCLEAR = 210,
312     KBDK_KP_MEMADD = 211,
313     KBDK_KP_MEMSUBTRACT = 212,
314     KBDK_KP_MEMMULTIPLY = 213,
315     KBDK_KP_MEMDIVIDE = 214,
316     KBDK_KP_PLUSMINUS = 215,
317     KBDK_KP_CLEAR = 216,
318     KBDK_KP_CLEARENTRY = 217,
319     KBDK_KP_BINARY = 218,
320     KBDK_KP_OCTAL = 219,
321     KBDK_KP_DECIMAL = 220,
322     KBDK_KP_HEXADECIMAL = 221,
323 
324     KBDK_LCTRL = 224,
325     KBDK_LSHIFT = 225,
326     KBDK_LALT = 226, /**< alt, option */
327     KBDK_LGUI = 227, /**< windows, command (apple), meta */
328     KBDK_RCTRL = 228,
329     KBDK_RSHIFT = 229,
330     KBDK_RALT = 230, /**< alt gr, option */
331     KBDK_RGUI = 231, /**< windows, command (apple), meta */
332 
333     KBDK_MODE = 257,    /**< ALT-GR(aph) key on non-American keyboards
334                          *   This is like pressing KBDK_RALT + KBDK_RCTRL
335                          *   on some keyboards
336                          */
337 
338     /* @} *//* Usage page 0x07 */
339 
340     /**
341      *  \name Usage page 0x0C
342      *
343      *  These values are mapped from usage page 0x0C (USB consumer page).
344      */
345     /* @{ */
346 
347     KBDK_AUDIONEXT = 258,
348     KBDK_AUDIOPREV = 259,
349     KBDK_AUDIOSTOP = 260,
350     KBDK_AUDIOPLAY = 261,
351     KBDK_AUDIOMUTE = 262,
352     KBDK_MEDIASELECT = 263,
353     KBDK_WWW = 264,
354     KBDK_MAIL = 265,
355     KBDK_CALCULATOR = 266,
356     KBDK_COMPUTER = 267,
357     KBDK_AC_SEARCH = 268,
358     KBDK_AC_HOME = 269,
359     KBDK_AC_BACK = 270,
360     KBDK_AC_FORWARD = 271,
361     KBDK_AC_STOP = 272,
362     KBDK_AC_REFRESH = 273,
363     KBDK_AC_BOOKMARKS = 274,
364 
365     /* @} *//* Usage page 0x0C */
366 
367     /**
368      *  \name Walther keys
369      *
370      *  These are values that Christian Walther added (for mac keyboard?).
371      */
372     /* @{ */
373 
374     KBDK_BRIGHTNESSDOWN = 275,
375     KBDK_BRIGHTNESSUP = 276,
376     KBDK_DISPLAYSWITCH = 277, /**< display mirroring/dual display
377                                            switch, video mode switch */
378     KBDK_KBDILLUMTOGGLE = 278,
379     KBDK_KBDILLUMDOWN = 279,
380     KBDK_KBDILLUMUP = 280,
381     KBDK_EJECT = 281,
382     KBDK_SLEEP = 282,
383 
384     KBDK_APP1 = 283,
385     KBDK_APP2 = 284,
386 
387     /* @} *//* Walther keys */
388 
389     /* Add any other keys here. */
390 
391     KBDK_LAST = 512 /**< not a key, just marks the number of scancodes
392                                  for array bounds */
393 };
394 
395 // This comes directly from SDL_keycode.h
396 enum StellaMod
397 {
398     KBDM_NONE = 0x0000,
399     KBDM_LSHIFT = 0x0001,
400     KBDM_RSHIFT = 0x0002,
401     KBDM_LCTRL = 0x0040,
402     KBDM_RCTRL = 0x0080,
403     KBDM_LALT = 0x0100,
404     KBDM_RALT = 0x0200,
405     KBDM_LGUI = 0x0400,
406     KBDM_RGUI = 0x0800,
407     KBDM_NUM = 0x1000,
408     KBDM_CAPS = 0x2000,
409     KBDM_MODE = 0x4000,
410     KBDM_RESERVED = 0x8000,
411     KBDM_CTRL = (KBDM_LCTRL|KBDM_RCTRL),
412     KBDM_SHIFT = (KBDM_LSHIFT|KBDM_RSHIFT),
413     KBDM_ALT = (KBDM_LALT|KBDM_RALT),
414     KBDM_GUI = (KBDM_LGUI|KBDM_RGUI)
415 };
416 
417 // Test if specified modifier is pressed
418 namespace StellaModTest
419 {
isAlt(int mod)420   inline bool isAlt(int mod)
421   {
422 #if defined(BSPF_MACOS) || defined(MACOS_KEYS)
423     return (mod & KBDM_GUI);
424 #else
425     return (mod & KBDM_ALT);
426 #endif
427   }
428 
isControl(int mod)429   inline bool isControl(int mod)
430   {
431     return (mod & KBDM_CTRL);
432   }
433 
isShift(int mod)434   inline bool isShift(int mod)
435   {
436     return (mod & KBDM_SHIFT);
437   }
438 }
439 
440 namespace StellaKeyName
441 {
forKey(StellaKey key)442   inline const char* forKey(StellaKey key)
443   {
444   #ifdef SDL_SUPPORT
445     return SDL_GetScancodeName(SDL_Scancode(key));
446   #else
447     return "";
448   #endif
449   }
450 }
451 
452 #endif /* StellaKeys */
453