SDL_winrtkeyboard.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "../../SDL_internal.h"
  19. #if SDL_VIDEO_DRIVER_WINRT
  20. /* Windows-specific includes */
  21. #include <Windows.h>
  22. #include <agile.h>
  23. /* SDL-specific includes */
  24. #include <SDL.h>
  25. #include "SDL_winrtevents_c.h"
  26. extern "C" {
  27. #include "../../events/scancodes_windows.h"
  28. #include "../../events/SDL_keyboard_c.h"
  29. }
  30. static SDL_Scancode WinRT_Official_Keycodes[] = {
  31. SDL_SCANCODE_UNKNOWN, // VirtualKey.None -- 0
  32. SDL_SCANCODE_UNKNOWN, // VirtualKey.LeftButton -- 1
  33. SDL_SCANCODE_UNKNOWN, // VirtualKey.RightButton -- 2
  34. SDL_SCANCODE_CANCEL, // VirtualKey.Cancel -- 3
  35. SDL_SCANCODE_UNKNOWN, // VirtualKey.MiddleButton -- 4
  36. SDL_SCANCODE_UNKNOWN, // VirtualKey.XButton1 -- 5
  37. SDL_SCANCODE_UNKNOWN, // VirtualKey.XButton2 -- 6
  38. SDL_SCANCODE_UNKNOWN, // -- 7
  39. SDL_SCANCODE_BACKSPACE, // VirtualKey.Back -- 8
  40. SDL_SCANCODE_TAB, // VirtualKey.Tab -- 9
  41. SDL_SCANCODE_UNKNOWN, // -- 10
  42. SDL_SCANCODE_UNKNOWN, // -- 11
  43. SDL_SCANCODE_CLEAR, // VirtualKey.Clear -- 12
  44. SDL_SCANCODE_RETURN, // VirtualKey.Enter -- 13
  45. SDL_SCANCODE_UNKNOWN, // -- 14
  46. SDL_SCANCODE_UNKNOWN, // -- 15
  47. SDL_SCANCODE_LSHIFT, // VirtualKey.Shift -- 16
  48. SDL_SCANCODE_LCTRL, // VirtualKey.Control -- 17
  49. SDL_SCANCODE_MENU, // VirtualKey.Menu -- 18
  50. SDL_SCANCODE_PAUSE, // VirtualKey.Pause -- 19
  51. SDL_SCANCODE_CAPSLOCK, // VirtualKey.CapitalLock -- 20
  52. SDL_SCANCODE_UNKNOWN, // VirtualKey.Kana or VirtualKey.Hangul -- 21
  53. SDL_SCANCODE_UNKNOWN, // -- 22
  54. SDL_SCANCODE_UNKNOWN, // VirtualKey.Junja -- 23
  55. SDL_SCANCODE_UNKNOWN, // VirtualKey.Final -- 24
  56. SDL_SCANCODE_UNKNOWN, // VirtualKey.Hanja or VirtualKey.Kanji -- 25
  57. SDL_SCANCODE_UNKNOWN, // -- 26
  58. SDL_SCANCODE_ESCAPE, // VirtualKey.Escape -- 27
  59. SDL_SCANCODE_UNKNOWN, // VirtualKey.Convert -- 28
  60. SDL_SCANCODE_UNKNOWN, // VirtualKey.NonConvert -- 29
  61. SDL_SCANCODE_UNKNOWN, // VirtualKey.Accept -- 30
  62. SDL_SCANCODE_UNKNOWN, // VirtualKey.ModeChange -- 31 (maybe SDL_SCANCODE_MODE ?)
  63. SDL_SCANCODE_SPACE, // VirtualKey.Space -- 32
  64. SDL_SCANCODE_PAGEUP, // VirtualKey.PageUp -- 33
  65. SDL_SCANCODE_PAGEDOWN, // VirtualKey.PageDown -- 34
  66. SDL_SCANCODE_END, // VirtualKey.End -- 35
  67. SDL_SCANCODE_HOME, // VirtualKey.Home -- 36
  68. SDL_SCANCODE_LEFT, // VirtualKey.Left -- 37
  69. SDL_SCANCODE_UP, // VirtualKey.Up -- 38
  70. SDL_SCANCODE_RIGHT, // VirtualKey.Right -- 39
  71. SDL_SCANCODE_DOWN, // VirtualKey.Down -- 40
  72. SDL_SCANCODE_SELECT, // VirtualKey.Select -- 41
  73. SDL_SCANCODE_UNKNOWN, // VirtualKey.Print -- 42 (maybe SDL_SCANCODE_PRINTSCREEN ?)
  74. SDL_SCANCODE_EXECUTE, // VirtualKey.Execute -- 43
  75. SDL_SCANCODE_UNKNOWN, // VirtualKey.Snapshot -- 44
  76. SDL_SCANCODE_INSERT, // VirtualKey.Insert -- 45
  77. SDL_SCANCODE_DELETE, // VirtualKey.Delete -- 46
  78. SDL_SCANCODE_HELP, // VirtualKey.Help -- 47
  79. SDL_SCANCODE_0, // VirtualKey.Number0 -- 48
  80. SDL_SCANCODE_1, // VirtualKey.Number1 -- 49
  81. SDL_SCANCODE_2, // VirtualKey.Number2 -- 50
  82. SDL_SCANCODE_3, // VirtualKey.Number3 -- 51
  83. SDL_SCANCODE_4, // VirtualKey.Number4 -- 52
  84. SDL_SCANCODE_5, // VirtualKey.Number5 -- 53
  85. SDL_SCANCODE_6, // VirtualKey.Number6 -- 54
  86. SDL_SCANCODE_7, // VirtualKey.Number7 -- 55
  87. SDL_SCANCODE_8, // VirtualKey.Number8 -- 56
  88. SDL_SCANCODE_9, // VirtualKey.Number9 -- 57
  89. SDL_SCANCODE_UNKNOWN, // -- 58
  90. SDL_SCANCODE_UNKNOWN, // -- 59
  91. SDL_SCANCODE_UNKNOWN, // -- 60
  92. SDL_SCANCODE_UNKNOWN, // -- 61
  93. SDL_SCANCODE_UNKNOWN, // -- 62
  94. SDL_SCANCODE_UNKNOWN, // -- 63
  95. SDL_SCANCODE_UNKNOWN, // -- 64
  96. SDL_SCANCODE_A, // VirtualKey.A -- 65
  97. SDL_SCANCODE_B, // VirtualKey.B -- 66
  98. SDL_SCANCODE_C, // VirtualKey.C -- 67
  99. SDL_SCANCODE_D, // VirtualKey.D -- 68
  100. SDL_SCANCODE_E, // VirtualKey.E -- 69
  101. SDL_SCANCODE_F, // VirtualKey.F -- 70
  102. SDL_SCANCODE_G, // VirtualKey.G -- 71
  103. SDL_SCANCODE_H, // VirtualKey.H -- 72
  104. SDL_SCANCODE_I, // VirtualKey.I -- 73
  105. SDL_SCANCODE_J, // VirtualKey.J -- 74
  106. SDL_SCANCODE_K, // VirtualKey.K -- 75
  107. SDL_SCANCODE_L, // VirtualKey.L -- 76
  108. SDL_SCANCODE_M, // VirtualKey.M -- 77
  109. SDL_SCANCODE_N, // VirtualKey.N -- 78
  110. SDL_SCANCODE_O, // VirtualKey.O -- 79
  111. SDL_SCANCODE_P, // VirtualKey.P -- 80
  112. SDL_SCANCODE_Q, // VirtualKey.Q -- 81
  113. SDL_SCANCODE_R, // VirtualKey.R -- 82
  114. SDL_SCANCODE_S, // VirtualKey.S -- 83
  115. SDL_SCANCODE_T, // VirtualKey.T -- 84
  116. SDL_SCANCODE_U, // VirtualKey.U -- 85
  117. SDL_SCANCODE_V, // VirtualKey.V -- 86
  118. SDL_SCANCODE_W, // VirtualKey.W -- 87
  119. SDL_SCANCODE_X, // VirtualKey.X -- 88
  120. SDL_SCANCODE_Y, // VirtualKey.Y -- 89
  121. SDL_SCANCODE_Z, // VirtualKey.Z -- 90
  122. SDL_SCANCODE_UNKNOWN, // VirtualKey.LeftWindows -- 91 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_LGUI ?)
  123. SDL_SCANCODE_UNKNOWN, // VirtualKey.RightWindows -- 92 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_RGUI ?)
  124. SDL_SCANCODE_APPLICATION, // VirtualKey.Application -- 93
  125. SDL_SCANCODE_UNKNOWN, // -- 94
  126. SDL_SCANCODE_SLEEP, // VirtualKey.Sleep -- 95
  127. SDL_SCANCODE_KP_0, // VirtualKey.NumberPad0 -- 96
  128. SDL_SCANCODE_KP_1, // VirtualKey.NumberPad1 -- 97
  129. SDL_SCANCODE_KP_2, // VirtualKey.NumberPad2 -- 98
  130. SDL_SCANCODE_KP_3, // VirtualKey.NumberPad3 -- 99
  131. SDL_SCANCODE_KP_4, // VirtualKey.NumberPad4 -- 100
  132. SDL_SCANCODE_KP_5, // VirtualKey.NumberPad5 -- 101
  133. SDL_SCANCODE_KP_6, // VirtualKey.NumberPad6 -- 102
  134. SDL_SCANCODE_KP_7, // VirtualKey.NumberPad7 -- 103
  135. SDL_SCANCODE_KP_8, // VirtualKey.NumberPad8 -- 104
  136. SDL_SCANCODE_KP_9, // VirtualKey.NumberPad9 -- 105
  137. SDL_SCANCODE_KP_MULTIPLY, // VirtualKey.Multiply -- 106
  138. SDL_SCANCODE_KP_PLUS, // VirtualKey.Add -- 107
  139. SDL_SCANCODE_UNKNOWN, // VirtualKey.Separator -- 108
  140. SDL_SCANCODE_KP_MINUS, // VirtualKey.Subtract -- 109
  141. SDL_SCANCODE_UNKNOWN, // VirtualKey.Decimal -- 110 (maybe SDL_SCANCODE_DECIMALSEPARATOR, SDL_SCANCODE_KP_DECIMAL, or SDL_SCANCODE_KP_PERIOD ?)
  142. SDL_SCANCODE_KP_DIVIDE, // VirtualKey.Divide -- 111
  143. SDL_SCANCODE_F1, // VirtualKey.F1 -- 112
  144. SDL_SCANCODE_F2, // VirtualKey.F2 -- 113
  145. SDL_SCANCODE_F3, // VirtualKey.F3 -- 114
  146. SDL_SCANCODE_F4, // VirtualKey.F4 -- 115
  147. SDL_SCANCODE_F5, // VirtualKey.F5 -- 116
  148. SDL_SCANCODE_F6, // VirtualKey.F6 -- 117
  149. SDL_SCANCODE_F7, // VirtualKey.F7 -- 118
  150. SDL_SCANCODE_F8, // VirtualKey.F8 -- 119
  151. SDL_SCANCODE_F9, // VirtualKey.F9 -- 120
  152. SDL_SCANCODE_F10, // VirtualKey.F10 -- 121
  153. SDL_SCANCODE_F11, // VirtualKey.F11 -- 122
  154. SDL_SCANCODE_F12, // VirtualKey.F12 -- 123
  155. SDL_SCANCODE_F13, // VirtualKey.F13 -- 124
  156. SDL_SCANCODE_F14, // VirtualKey.F14 -- 125
  157. SDL_SCANCODE_F15, // VirtualKey.F15 -- 126
  158. SDL_SCANCODE_F16, // VirtualKey.F16 -- 127
  159. SDL_SCANCODE_F17, // VirtualKey.F17 -- 128
  160. SDL_SCANCODE_F18, // VirtualKey.F18 -- 129
  161. SDL_SCANCODE_F19, // VirtualKey.F19 -- 130
  162. SDL_SCANCODE_F20, // VirtualKey.F20 -- 131
  163. SDL_SCANCODE_F21, // VirtualKey.F21 -- 132
  164. SDL_SCANCODE_F22, // VirtualKey.F22 -- 133
  165. SDL_SCANCODE_F23, // VirtualKey.F23 -- 134
  166. SDL_SCANCODE_F24, // VirtualKey.F24 -- 135
  167. SDL_SCANCODE_UNKNOWN, // -- 136
  168. SDL_SCANCODE_UNKNOWN, // -- 137
  169. SDL_SCANCODE_UNKNOWN, // -- 138
  170. SDL_SCANCODE_UNKNOWN, // -- 139
  171. SDL_SCANCODE_UNKNOWN, // -- 140
  172. SDL_SCANCODE_UNKNOWN, // -- 141
  173. SDL_SCANCODE_UNKNOWN, // -- 142
  174. SDL_SCANCODE_UNKNOWN, // -- 143
  175. SDL_SCANCODE_NUMLOCKCLEAR, // VirtualKey.NumberKeyLock -- 144
  176. SDL_SCANCODE_SCROLLLOCK, // VirtualKey.Scroll -- 145
  177. SDL_SCANCODE_UNKNOWN, // -- 146
  178. SDL_SCANCODE_UNKNOWN, // -- 147
  179. SDL_SCANCODE_UNKNOWN, // -- 148
  180. SDL_SCANCODE_UNKNOWN, // -- 149
  181. SDL_SCANCODE_UNKNOWN, // -- 150
  182. SDL_SCANCODE_UNKNOWN, // -- 151
  183. SDL_SCANCODE_UNKNOWN, // -- 152
  184. SDL_SCANCODE_UNKNOWN, // -- 153
  185. SDL_SCANCODE_UNKNOWN, // -- 154
  186. SDL_SCANCODE_UNKNOWN, // -- 155
  187. SDL_SCANCODE_UNKNOWN, // -- 156
  188. SDL_SCANCODE_UNKNOWN, // -- 157
  189. SDL_SCANCODE_UNKNOWN, // -- 158
  190. SDL_SCANCODE_UNKNOWN, // -- 159
  191. SDL_SCANCODE_LSHIFT, // VirtualKey.LeftShift -- 160
  192. SDL_SCANCODE_RSHIFT, // VirtualKey.RightShift -- 161
  193. SDL_SCANCODE_LCTRL, // VirtualKey.LeftControl -- 162
  194. SDL_SCANCODE_RCTRL, // VirtualKey.RightControl -- 163
  195. SDL_SCANCODE_MENU, // VirtualKey.LeftMenu -- 164
  196. SDL_SCANCODE_MENU, // VirtualKey.RightMenu -- 165
  197. SDL_SCANCODE_AC_BACK, // VirtualKey.GoBack -- 166 : The go back key.
  198. SDL_SCANCODE_AC_FORWARD, // VirtualKey.GoForward -- 167 : The go forward key.
  199. SDL_SCANCODE_AC_REFRESH, // VirtualKey.Refresh -- 168 : The refresh key.
  200. SDL_SCANCODE_AC_STOP, // VirtualKey.Stop -- 169 : The stop key.
  201. SDL_SCANCODE_AC_SEARCH, // VirtualKey.Search -- 170 : The search key.
  202. SDL_SCANCODE_AC_BOOKMARKS, // VirtualKey.Favorites -- 171 : The favorites key.
  203. SDL_SCANCODE_AC_HOME // VirtualKey.GoHome -- 172 : The go home key.
  204. };
  205. /* Attempt to translate a keycode that isn't listed in WinRT's VirtualKey enum.
  206. */
  207. static SDL_Scancode
  208. WINRT_TranslateUnofficialKeycode(int keycode)
  209. {
  210. switch (keycode) {
  211. case 173: return SDL_SCANCODE_MUTE;
  212. case 174: return SDL_SCANCODE_VOLUMEDOWN;
  213. case 175: return SDL_SCANCODE_VOLUMEUP;
  214. case 176: return SDL_SCANCODE_AUDIONEXT;
  215. case 177: return SDL_SCANCODE_AUDIOPREV;
  216. // case 178: return ;
  217. case 179: return SDL_SCANCODE_AUDIOPLAY;
  218. case 180: return SDL_SCANCODE_MAIL;
  219. case 181: return SDL_SCANCODE_MEDIASELECT;
  220. // case 182: return ;
  221. case 183: return SDL_SCANCODE_CALCULATOR;
  222. // case 184: return ;
  223. // case 185: return ;
  224. case 186: return SDL_SCANCODE_SEMICOLON;
  225. case 187: return SDL_SCANCODE_EQUALS;
  226. case 188: return SDL_SCANCODE_COMMA;
  227. case 189: return SDL_SCANCODE_MINUS;
  228. case 190: return SDL_SCANCODE_PERIOD;
  229. case 191: return SDL_SCANCODE_SLASH;
  230. case 192: return SDL_SCANCODE_GRAVE;
  231. // ?
  232. // ...
  233. // ?
  234. case 219: return SDL_SCANCODE_LEFTBRACKET;
  235. case 220: return SDL_SCANCODE_BACKSLASH;
  236. case 221: return SDL_SCANCODE_RIGHTBRACKET;
  237. case 222: return SDL_SCANCODE_APOSTROPHE;
  238. default: break;
  239. }
  240. return SDL_SCANCODE_UNKNOWN;
  241. }
  242. static SDL_Scancode
  243. TranslateKeycode(int keycode, unsigned int nativeScancode)
  244. {
  245. // TODO, WinRT: try filling out the WinRT keycode table as much as possible, using the Win32 table for interpretation hints
  246. //SDL_Log("WinRT TranslateKeycode, keycode=%d\n", (int)keycode);
  247. SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
  248. /* HACK ALERT: At least one VirtualKey constant (Shift) with a left/right
  249. * designation might not get reported with its correct handedness, however
  250. * its hardware scan code can fill in the gaps. If this is detected,
  251. * use the hardware scan code to try telling if the left, or the right
  252. * side's key was used.
  253. *
  254. * If Microsoft ever allows MapVirtualKey or MapVirtualKeyEx to be used
  255. * in WinRT apps, or something similar to these (it doesn't appear to be,
  256. * at least not for Windows [Phone] 8/8.1, as of Oct 24, 2014), then this
  257. * hack might become deprecated, or obsolete.
  258. */
  259. if (nativeScancode < SDL_arraysize(windows_scancode_table)) {
  260. switch (keycode) {
  261. case 16: // VirtualKey.Shift
  262. switch (windows_scancode_table[nativeScancode]) {
  263. case SDL_SCANCODE_LSHIFT:
  264. case SDL_SCANCODE_RSHIFT:
  265. return windows_scancode_table[nativeScancode];
  266. }
  267. break;
  268. // Add others, as necessary.
  269. //
  270. // Unfortunately, this hack doesn't seem to work in determining
  271. // handedness with Control keys.
  272. default:
  273. break;
  274. }
  275. }
  276. /* Try to get a documented, WinRT, 'VirtualKey' next (as documented at
  277. http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.virtualkey.aspx ).
  278. If that fails, fall back to a Win32 virtual key.
  279. */
  280. if (keycode < SDL_arraysize(WinRT_Official_Keycodes)) {
  281. scancode = WinRT_Official_Keycodes[keycode];
  282. }
  283. if (scancode == SDL_SCANCODE_UNKNOWN) {
  284. scancode = WINRT_TranslateUnofficialKeycode(keycode);
  285. }
  286. if (scancode == SDL_SCANCODE_UNKNOWN) {
  287. SDL_Log("WinRT TranslateKeycode, unknown keycode=%d\n", (int)keycode);
  288. }
  289. return scancode;
  290. }
  291. void
  292. WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args)
  293. {
  294. SDL_Scancode sdlScancode = TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
  295. #if 0
  296. SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
  297. SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
  298. "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
  299. "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
  300. (args->Handled ? "1" : "0"),
  301. (args->KeyStatus.IsExtendedKey ? "1" : "0"),
  302. (args->KeyStatus.IsKeyReleased ? "1" : "0"),
  303. (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
  304. args->KeyStatus.RepeatCount,
  305. args->KeyStatus.ScanCode,
  306. (args->KeyStatus.WasKeyDown ? "1" : "0"),
  307. args->VirtualKey,
  308. sdlScancode,
  309. SDL_GetScancodeName(sdlScancode),
  310. keycode,
  311. SDL_GetKeyName(keycode));
  312. //args->Handled = true;
  313. //VirtualKey vkey = args->VirtualKey;
  314. #endif
  315. SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode);
  316. }
  317. void
  318. WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args)
  319. {
  320. SDL_Scancode sdlScancode = TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
  321. #if 0
  322. SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
  323. SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
  324. "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
  325. "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
  326. (args->Handled ? "1" : "0"),
  327. (args->KeyStatus.IsExtendedKey ? "1" : "0"),
  328. (args->KeyStatus.IsKeyReleased ? "1" : "0"),
  329. (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
  330. args->KeyStatus.RepeatCount,
  331. args->KeyStatus.ScanCode,
  332. (args->KeyStatus.WasKeyDown ? "1" : "0"),
  333. args->VirtualKey,
  334. sdlScancode,
  335. SDL_GetScancodeName(sdlScancode),
  336. keycode,
  337. SDL_GetKeyName(keycode));
  338. //args->Handled = true;
  339. #endif
  340. SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode);
  341. }
  342. #endif // SDL_VIDEO_DRIVER_WINRT