SDL_winrtkeyboard.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  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. /* Standard C++11 includes */
  21. #include <unordered_map>
  22. /* Windows-specific includes */
  23. #include <Windows.h>
  24. #include <agile.h>
  25. /* SDL-specific includes */
  26. #include <SDL.h>
  27. #include "SDL_winrtevents_c.h"
  28. extern "C" {
  29. #include "../../events/scancodes_windows.h"
  30. #include "../../events/SDL_keyboard_c.h"
  31. }
  32. static SDL_Scancode WinRT_Official_Keycodes[] = {
  33. SDL_SCANCODE_UNKNOWN, // VirtualKey.None -- 0
  34. SDL_SCANCODE_UNKNOWN, // VirtualKey.LeftButton -- 1
  35. SDL_SCANCODE_UNKNOWN, // VirtualKey.RightButton -- 2
  36. SDL_SCANCODE_CANCEL, // VirtualKey.Cancel -- 3
  37. SDL_SCANCODE_UNKNOWN, // VirtualKey.MiddleButton -- 4
  38. SDL_SCANCODE_UNKNOWN, // VirtualKey.XButton1 -- 5
  39. SDL_SCANCODE_UNKNOWN, // VirtualKey.XButton2 -- 6
  40. SDL_SCANCODE_UNKNOWN, // -- 7
  41. SDL_SCANCODE_BACKSPACE, // VirtualKey.Back -- 8
  42. SDL_SCANCODE_TAB, // VirtualKey.Tab -- 9
  43. SDL_SCANCODE_UNKNOWN, // -- 10
  44. SDL_SCANCODE_UNKNOWN, // -- 11
  45. SDL_SCANCODE_CLEAR, // VirtualKey.Clear -- 12
  46. SDL_SCANCODE_RETURN, // VirtualKey.Enter -- 13
  47. SDL_SCANCODE_UNKNOWN, // -- 14
  48. SDL_SCANCODE_UNKNOWN, // -- 15
  49. SDL_SCANCODE_LSHIFT, // VirtualKey.Shift -- 16
  50. SDL_SCANCODE_LCTRL, // VirtualKey.Control -- 17
  51. SDL_SCANCODE_MENU, // VirtualKey.Menu -- 18
  52. SDL_SCANCODE_PAUSE, // VirtualKey.Pause -- 19
  53. SDL_SCANCODE_CAPSLOCK, // VirtualKey.CapitalLock -- 20
  54. SDL_SCANCODE_UNKNOWN, // VirtualKey.Kana or VirtualKey.Hangul -- 21
  55. SDL_SCANCODE_UNKNOWN, // -- 22
  56. SDL_SCANCODE_UNKNOWN, // VirtualKey.Junja -- 23
  57. SDL_SCANCODE_UNKNOWN, // VirtualKey.Final -- 24
  58. SDL_SCANCODE_UNKNOWN, // VirtualKey.Hanja or VirtualKey.Kanji -- 25
  59. SDL_SCANCODE_UNKNOWN, // -- 26
  60. SDL_SCANCODE_ESCAPE, // VirtualKey.Escape -- 27
  61. SDL_SCANCODE_UNKNOWN, // VirtualKey.Convert -- 28
  62. SDL_SCANCODE_UNKNOWN, // VirtualKey.NonConvert -- 29
  63. SDL_SCANCODE_UNKNOWN, // VirtualKey.Accept -- 30
  64. SDL_SCANCODE_UNKNOWN, // VirtualKey.ModeChange -- 31 (maybe SDL_SCANCODE_MODE ?)
  65. SDL_SCANCODE_SPACE, // VirtualKey.Space -- 32
  66. SDL_SCANCODE_PAGEUP, // VirtualKey.PageUp -- 33
  67. SDL_SCANCODE_PAGEDOWN, // VirtualKey.PageDown -- 34
  68. SDL_SCANCODE_END, // VirtualKey.End -- 35
  69. SDL_SCANCODE_HOME, // VirtualKey.Home -- 36
  70. SDL_SCANCODE_LEFT, // VirtualKey.Left -- 37
  71. SDL_SCANCODE_UP, // VirtualKey.Up -- 38
  72. SDL_SCANCODE_RIGHT, // VirtualKey.Right -- 39
  73. SDL_SCANCODE_DOWN, // VirtualKey.Down -- 40
  74. SDL_SCANCODE_SELECT, // VirtualKey.Select -- 41
  75. SDL_SCANCODE_UNKNOWN, // VirtualKey.Print -- 42 (maybe SDL_SCANCODE_PRINTSCREEN ?)
  76. SDL_SCANCODE_EXECUTE, // VirtualKey.Execute -- 43
  77. SDL_SCANCODE_UNKNOWN, // VirtualKey.Snapshot -- 44
  78. SDL_SCANCODE_INSERT, // VirtualKey.Insert -- 45
  79. SDL_SCANCODE_DELETE, // VirtualKey.Delete -- 46
  80. SDL_SCANCODE_HELP, // VirtualKey.Help -- 47
  81. SDL_SCANCODE_0, // VirtualKey.Number0 -- 48
  82. SDL_SCANCODE_1, // VirtualKey.Number1 -- 49
  83. SDL_SCANCODE_2, // VirtualKey.Number2 -- 50
  84. SDL_SCANCODE_3, // VirtualKey.Number3 -- 51
  85. SDL_SCANCODE_4, // VirtualKey.Number4 -- 52
  86. SDL_SCANCODE_5, // VirtualKey.Number5 -- 53
  87. SDL_SCANCODE_6, // VirtualKey.Number6 -- 54
  88. SDL_SCANCODE_7, // VirtualKey.Number7 -- 55
  89. SDL_SCANCODE_8, // VirtualKey.Number8 -- 56
  90. SDL_SCANCODE_9, // VirtualKey.Number9 -- 57
  91. SDL_SCANCODE_UNKNOWN, // -- 58
  92. SDL_SCANCODE_UNKNOWN, // -- 59
  93. SDL_SCANCODE_UNKNOWN, // -- 60
  94. SDL_SCANCODE_UNKNOWN, // -- 61
  95. SDL_SCANCODE_UNKNOWN, // -- 62
  96. SDL_SCANCODE_UNKNOWN, // -- 63
  97. SDL_SCANCODE_UNKNOWN, // -- 64
  98. SDL_SCANCODE_A, // VirtualKey.A -- 65
  99. SDL_SCANCODE_B, // VirtualKey.B -- 66
  100. SDL_SCANCODE_C, // VirtualKey.C -- 67
  101. SDL_SCANCODE_D, // VirtualKey.D -- 68
  102. SDL_SCANCODE_E, // VirtualKey.E -- 69
  103. SDL_SCANCODE_F, // VirtualKey.F -- 70
  104. SDL_SCANCODE_G, // VirtualKey.G -- 71
  105. SDL_SCANCODE_H, // VirtualKey.H -- 72
  106. SDL_SCANCODE_I, // VirtualKey.I -- 73
  107. SDL_SCANCODE_J, // VirtualKey.J -- 74
  108. SDL_SCANCODE_K, // VirtualKey.K -- 75
  109. SDL_SCANCODE_L, // VirtualKey.L -- 76
  110. SDL_SCANCODE_M, // VirtualKey.M -- 77
  111. SDL_SCANCODE_N, // VirtualKey.N -- 78
  112. SDL_SCANCODE_O, // VirtualKey.O -- 79
  113. SDL_SCANCODE_P, // VirtualKey.P -- 80
  114. SDL_SCANCODE_Q, // VirtualKey.Q -- 81
  115. SDL_SCANCODE_R, // VirtualKey.R -- 82
  116. SDL_SCANCODE_S, // VirtualKey.S -- 83
  117. SDL_SCANCODE_T, // VirtualKey.T -- 84
  118. SDL_SCANCODE_U, // VirtualKey.U -- 85
  119. SDL_SCANCODE_V, // VirtualKey.V -- 86
  120. SDL_SCANCODE_W, // VirtualKey.W -- 87
  121. SDL_SCANCODE_X, // VirtualKey.X -- 88
  122. SDL_SCANCODE_Y, // VirtualKey.Y -- 89
  123. SDL_SCANCODE_Z, // VirtualKey.Z -- 90
  124. SDL_SCANCODE_UNKNOWN, // VirtualKey.LeftWindows -- 91 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_LGUI ?)
  125. SDL_SCANCODE_UNKNOWN, // VirtualKey.RightWindows -- 92 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_RGUI ?)
  126. SDL_SCANCODE_APPLICATION, // VirtualKey.Application -- 93
  127. SDL_SCANCODE_UNKNOWN, // -- 94
  128. SDL_SCANCODE_SLEEP, // VirtualKey.Sleep -- 95
  129. SDL_SCANCODE_KP_0, // VirtualKey.NumberPad0 -- 96
  130. SDL_SCANCODE_KP_1, // VirtualKey.NumberPad1 -- 97
  131. SDL_SCANCODE_KP_2, // VirtualKey.NumberPad2 -- 98
  132. SDL_SCANCODE_KP_3, // VirtualKey.NumberPad3 -- 99
  133. SDL_SCANCODE_KP_4, // VirtualKey.NumberPad4 -- 100
  134. SDL_SCANCODE_KP_5, // VirtualKey.NumberPad5 -- 101
  135. SDL_SCANCODE_KP_6, // VirtualKey.NumberPad6 -- 102
  136. SDL_SCANCODE_KP_7, // VirtualKey.NumberPad7 -- 103
  137. SDL_SCANCODE_KP_8, // VirtualKey.NumberPad8 -- 104
  138. SDL_SCANCODE_KP_9, // VirtualKey.NumberPad9 -- 105
  139. SDL_SCANCODE_KP_MULTIPLY, // VirtualKey.Multiply -- 106
  140. SDL_SCANCODE_KP_PLUS, // VirtualKey.Add -- 107
  141. SDL_SCANCODE_UNKNOWN, // VirtualKey.Separator -- 108
  142. SDL_SCANCODE_KP_MINUS, // VirtualKey.Subtract -- 109
  143. SDL_SCANCODE_UNKNOWN, // VirtualKey.Decimal -- 110 (maybe SDL_SCANCODE_DECIMALSEPARATOR, SDL_SCANCODE_KP_DECIMAL, or SDL_SCANCODE_KP_PERIOD ?)
  144. SDL_SCANCODE_KP_DIVIDE, // VirtualKey.Divide -- 111
  145. SDL_SCANCODE_F1, // VirtualKey.F1 -- 112
  146. SDL_SCANCODE_F2, // VirtualKey.F2 -- 113
  147. SDL_SCANCODE_F3, // VirtualKey.F3 -- 114
  148. SDL_SCANCODE_F4, // VirtualKey.F4 -- 115
  149. SDL_SCANCODE_F5, // VirtualKey.F5 -- 116
  150. SDL_SCANCODE_F6, // VirtualKey.F6 -- 117
  151. SDL_SCANCODE_F7, // VirtualKey.F7 -- 118
  152. SDL_SCANCODE_F8, // VirtualKey.F8 -- 119
  153. SDL_SCANCODE_F9, // VirtualKey.F9 -- 120
  154. SDL_SCANCODE_F10, // VirtualKey.F10 -- 121
  155. SDL_SCANCODE_F11, // VirtualKey.F11 -- 122
  156. SDL_SCANCODE_F12, // VirtualKey.F12 -- 123
  157. SDL_SCANCODE_F13, // VirtualKey.F13 -- 124
  158. SDL_SCANCODE_F14, // VirtualKey.F14 -- 125
  159. SDL_SCANCODE_F15, // VirtualKey.F15 -- 126
  160. SDL_SCANCODE_F16, // VirtualKey.F16 -- 127
  161. SDL_SCANCODE_F17, // VirtualKey.F17 -- 128
  162. SDL_SCANCODE_F18, // VirtualKey.F18 -- 129
  163. SDL_SCANCODE_F19, // VirtualKey.F19 -- 130
  164. SDL_SCANCODE_F20, // VirtualKey.F20 -- 131
  165. SDL_SCANCODE_F21, // VirtualKey.F21 -- 132
  166. SDL_SCANCODE_F22, // VirtualKey.F22 -- 133
  167. SDL_SCANCODE_F23, // VirtualKey.F23 -- 134
  168. SDL_SCANCODE_F24, // VirtualKey.F24 -- 135
  169. SDL_SCANCODE_UNKNOWN, // -- 136
  170. SDL_SCANCODE_UNKNOWN, // -- 137
  171. SDL_SCANCODE_UNKNOWN, // -- 138
  172. SDL_SCANCODE_UNKNOWN, // -- 139
  173. SDL_SCANCODE_UNKNOWN, // -- 140
  174. SDL_SCANCODE_UNKNOWN, // -- 141
  175. SDL_SCANCODE_UNKNOWN, // -- 142
  176. SDL_SCANCODE_UNKNOWN, // -- 143
  177. SDL_SCANCODE_NUMLOCKCLEAR, // VirtualKey.NumberKeyLock -- 144
  178. SDL_SCANCODE_SCROLLLOCK, // VirtualKey.Scroll -- 145
  179. SDL_SCANCODE_UNKNOWN, // -- 146
  180. SDL_SCANCODE_UNKNOWN, // -- 147
  181. SDL_SCANCODE_UNKNOWN, // -- 148
  182. SDL_SCANCODE_UNKNOWN, // -- 149
  183. SDL_SCANCODE_UNKNOWN, // -- 150
  184. SDL_SCANCODE_UNKNOWN, // -- 151
  185. SDL_SCANCODE_UNKNOWN, // -- 152
  186. SDL_SCANCODE_UNKNOWN, // -- 153
  187. SDL_SCANCODE_UNKNOWN, // -- 154
  188. SDL_SCANCODE_UNKNOWN, // -- 155
  189. SDL_SCANCODE_UNKNOWN, // -- 156
  190. SDL_SCANCODE_UNKNOWN, // -- 157
  191. SDL_SCANCODE_UNKNOWN, // -- 158
  192. SDL_SCANCODE_UNKNOWN, // -- 159
  193. SDL_SCANCODE_LSHIFT, // VirtualKey.LeftShift -- 160
  194. SDL_SCANCODE_RSHIFT, // VirtualKey.RightShift -- 161
  195. SDL_SCANCODE_LCTRL, // VirtualKey.LeftControl -- 162
  196. SDL_SCANCODE_RCTRL, // VirtualKey.RightControl -- 163
  197. SDL_SCANCODE_MENU, // VirtualKey.LeftMenu -- 164
  198. SDL_SCANCODE_MENU, // VirtualKey.RightMenu -- 165
  199. };
  200. static std::unordered_map<int, SDL_Scancode> WinRT_Unofficial_Keycodes;
  201. static SDL_Scancode
  202. TranslateKeycode(int keycode)
  203. {
  204. if (WinRT_Unofficial_Keycodes.empty()) {
  205. /* Set up a table of undocumented (by Microsoft), WinRT-specific,
  206. key codes: */
  207. // TODO, WinRT: move content declarations of WinRT_Unofficial_Keycodes into a C++11 initializer list, when possible
  208. WinRT_Unofficial_Keycodes[220] = SDL_SCANCODE_GRAVE;
  209. WinRT_Unofficial_Keycodes[222] = SDL_SCANCODE_BACKSLASH;
  210. }
  211. /* Try to get a documented, WinRT, 'VirtualKey' first (as documented at
  212. http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.virtualkey.aspx ).
  213. If that fails, fall back to a Win32 virtual key.
  214. */
  215. // TODO, WinRT: try filling out the WinRT keycode table as much as possible, using the Win32 table for interpretation hints
  216. //SDL_Log("WinRT TranslateKeycode, keycode=%d\n", (int)keycode);
  217. SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
  218. if (keycode < SDL_arraysize(WinRT_Official_Keycodes)) {
  219. scancode = WinRT_Official_Keycodes[keycode];
  220. }
  221. if (scancode == SDL_SCANCODE_UNKNOWN) {
  222. if (WinRT_Unofficial_Keycodes.find(keycode) != WinRT_Unofficial_Keycodes.end()) {
  223. scancode = WinRT_Unofficial_Keycodes[keycode];
  224. }
  225. }
  226. if (scancode == SDL_SCANCODE_UNKNOWN) {
  227. if (keycode < SDL_arraysize(windows_scancode_table)) {
  228. scancode = windows_scancode_table[keycode];
  229. }
  230. }
  231. if (scancode == SDL_SCANCODE_UNKNOWN) {
  232. SDL_Log("WinRT TranslateKeycode, unknown keycode=%d\n", (int)keycode);
  233. }
  234. return scancode;
  235. }
  236. void
  237. WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args)
  238. {
  239. SDL_Scancode sdlScancode = TranslateKeycode((int)args->VirtualKey);
  240. #if 0
  241. SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
  242. SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, native scan code=%d, was down?=%s, vkey=%d, sdl scan code=%d (%s), sdl key code=%d (%s)\n",
  243. (args->Handled ? "1" : "0"),
  244. (args->KeyStatus.IsExtendedKey ? "1" : "0"),
  245. (args->KeyStatus.IsKeyReleased ? "1" : "0"),
  246. (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
  247. args->KeyStatus.RepeatCount,
  248. args->KeyStatus.ScanCode,
  249. (args->KeyStatus.WasKeyDown ? "1" : "0"),
  250. args->VirtualKey,
  251. sdlScancode,
  252. SDL_GetScancodeName(sdlScancode),
  253. keycode,
  254. SDL_GetKeyName(keycode));
  255. //args->Handled = true;
  256. //VirtualKey vkey = args->VirtualKey;
  257. #endif
  258. SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode);
  259. }
  260. void
  261. WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args)
  262. {
  263. SDL_Scancode sdlScancode = TranslateKeycode((int)args->VirtualKey);
  264. #if 0
  265. SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
  266. SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, native scan code=%d, was down?=%s, vkey=%d, sdl scan code=%d (%s), sdl key code=%d (%s)\n",
  267. (args->Handled ? "1" : "0"),
  268. (args->KeyStatus.IsExtendedKey ? "1" : "0"),
  269. (args->KeyStatus.IsKeyReleased ? "1" : "0"),
  270. (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
  271. args->KeyStatus.RepeatCount,
  272. args->KeyStatus.ScanCode,
  273. (args->KeyStatus.WasKeyDown ? "1" : "0"),
  274. args->VirtualKey,
  275. sdlScancode,
  276. SDL_GetScancodeName(sdlScancode),
  277. keycode,
  278. SDL_GetKeyName(keycode));
  279. //args->Handled = true;
  280. #endif
  281. SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode);
  282. }
  283. #endif // SDL_VIDEO_DRIVER_WINRT