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