src/video/winrt/SDL_winrtkeyboard.cpp
author David Ludwig
Sat, 25 Oct 2014 08:43:51 -0400
changeset 9190 ff12797f287b
parent 9189 5dc3c7c2864c
child 9191 7a728256c5f5
permissions -rw-r--r--
WinRT: more keyboard code cleanups
- use SDL_arraysize where appropriate
- made long lines of debug-logging code span multiple lines, for easier reading
     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 /* 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
   219 WINRT_TranslateUnofficialKeycode(int keycode)
   220 {
   221     switch (keycode) {
   222         case 173: return SDL_SCANCODE_MUTE;
   223         case 174: return SDL_SCANCODE_VOLUMEDOWN;
   224         case 175: return SDL_SCANCODE_VOLUMEUP;
   225         case 176: return SDL_SCANCODE_AUDIONEXT;
   226         case 177: return SDL_SCANCODE_AUDIOPREV;
   227         // case 178: return ;
   228         case 179: return SDL_SCANCODE_AUDIOPLAY;
   229         case 180: return SDL_SCANCODE_MAIL;
   230         case 181: return SDL_SCANCODE_MEDIASELECT;
   231         // case 182: return ;
   232         case 183: return SDL_SCANCODE_CALCULATOR;
   233         // case 184: return ;
   234         // case 185: return ;
   235         case 186: return SDL_SCANCODE_SEMICOLON;
   236         case 187: return SDL_SCANCODE_EQUALS;
   237         case 188: return SDL_SCANCODE_COMMA;
   238         case 189: return SDL_SCANCODE_MINUS;
   239         case 190: return SDL_SCANCODE_PERIOD;
   240         case 191: return SDL_SCANCODE_SLASH;
   241         case 192: return SDL_SCANCODE_GRAVE;
   242         // ?
   243         // ...
   244         // ?
   245         case 219: return SDL_SCANCODE_LEFTBRACKET;
   246         case 220: return SDL_SCANCODE_BACKSLASH;
   247         case 221: return SDL_SCANCODE_RIGHTBRACKET;
   248         case 222: return SDL_SCANCODE_APOSTROPHE;
   249         default: break;
   250     }
   251     return SDL_SCANCODE_UNKNOWN;
   252 }
   253 
   254 static SDL_Scancode
   255 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     //SDL_Log("WinRT TranslateKeycode, keycode=%d\n", (int)keycode);
   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     */
   296     if (keycode < SDL_arraysize(WinRT_Official_Keycodes)) {
   297         scancode = WinRT_Official_Keycodes[keycode];
   298     }
   299     if (scancode == SDL_SCANCODE_UNKNOWN) {
   300         scancode = WINRT_TranslateUnofficialKeycode(keycode);
   301     }
   302     if (scancode == SDL_SCANCODE_UNKNOWN) {
   303         SDL_Log("WinRT TranslateKeycode, unknown keycode=%d\n", (int)keycode);
   304     }
   305     return scancode;
   306 }
   307 
   308 void
   309 WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args)
   310 {
   311     SDL_Scancode sdlScancode = TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
   312 #if 0
   313     SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
   314     SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
   315             "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
   316             "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
   317         (args->Handled ? "1" : "0"),
   318         (args->KeyStatus.IsExtendedKey ? "1" : "0"),
   319         (args->KeyStatus.IsKeyReleased ? "1" : "0"),
   320         (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
   321         args->KeyStatus.RepeatCount,
   322         args->KeyStatus.ScanCode,
   323         (args->KeyStatus.WasKeyDown ? "1" : "0"),
   324         args->VirtualKey,
   325         sdlScancode,
   326         SDL_GetScancodeName(sdlScancode),
   327         keycode,
   328         SDL_GetKeyName(keycode));
   329     //args->Handled = true;
   330     //VirtualKey vkey = args->VirtualKey;
   331 #endif
   332     SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode);
   333 }
   334 
   335 void
   336 WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args)
   337 {
   338     SDL_Scancode sdlScancode = TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
   339 #if 0
   340     SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
   341     SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
   342             "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
   343             "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
   344         (args->Handled ? "1" : "0"),
   345         (args->KeyStatus.IsExtendedKey ? "1" : "0"),
   346         (args->KeyStatus.IsKeyReleased ? "1" : "0"),
   347         (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
   348         args->KeyStatus.RepeatCount,
   349         args->KeyStatus.ScanCode,
   350         (args->KeyStatus.WasKeyDown ? "1" : "0"),
   351         args->VirtualKey,
   352         sdlScancode,
   353         SDL_GetScancodeName(sdlScancode),
   354         keycode,
   355         SDL_GetKeyName(keycode));
   356     //args->Handled = true;
   357 #endif
   358     SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode);
   359 }
   360 
   361 #endif // SDL_VIDEO_DRIVER_WINRT