src/video/winrt/SDL_winrtkeyboard.cpp
author David Ludwig
Thu, 17 Apr 2014 12:43:51 -0400
changeset 8701 cb93e566a0c4
parent 8615 097646deaef2
child 9188 480d583ce7ea
permissions -rw-r--r--
WinRT: keyboard VirtualKey translation improvements from Sylvain Becker

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