Friggin' Windows remaps alphabetic keys based on keyboard layout.
authorSam Lantinga <slouken@libsdl.org>
Sat, 09 Feb 2008 22:28:27 +0000
changeset 231154e21acfec5a
parent 2310 2f31ce8f1149
child 2312 bcec4b189f5b
Friggin' Windows remaps alphabetic keys based on keyboard layout.
We try to figure out what the actual layout independent values are.
src/video/win32/SDL_win32events.c
src/video/win32/SDL_win32keyboard.c
src/video/win32/SDL_win32keyboard.h
     1.1 --- a/src/video/win32/SDL_win32events.c	Sat Feb 09 07:18:38 2008 +0000
     1.2 +++ b/src/video/win32/SDL_win32events.c	Sat Feb 09 22:28:27 2008 +0000
     1.3 @@ -54,17 +54,12 @@
     1.4         We try to provide USB scancodes, so undo this mapping.
     1.5       */
     1.6      if (wParam >= 'A' && wParam <= 'Z') {
     1.7 -        /* Alphabetic scancodes for PC keyboards */
     1.8 -        static BYTE scancodes[26] = {
     1.9 -            30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50, 49, 24,
    1.10 -            25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44
    1.11 -        };
    1.12          BYTE scancode = (lParam >> 16) & 0xFF;
    1.13          int i;
    1.14  
    1.15 -        if (scancode != scancodes[wParam - 'A']) {
    1.16 -            for (i = 0; i < SDL_arraysize(scancodes); ++i) {
    1.17 -                if (scancode == scancodes[i]) {
    1.18 +        if (scancode != alpha_scancodes[wParam - 'A']) {
    1.19 +            for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) {
    1.20 +                if (scancode == alpha_scancodes[i]) {
    1.21                      wParam = 'A' + i;
    1.22                      break;
    1.23                  }
    1.24 @@ -448,6 +443,12 @@
    1.25          }
    1.26          return (0);
    1.27  
    1.28 +    case WM_INPUTLANGCHANGE:
    1.29 +        {
    1.30 +            WIN_UpdateKeymap(data->videodata->keyboard);
    1.31 +        }
    1.32 +        return (1);
    1.33 +
    1.34      case WM_GETMINMAXINFO:
    1.35          {
    1.36              MINMAXINFO *info;
     2.1 --- a/src/video/win32/SDL_win32keyboard.c	Sat Feb 09 07:18:38 2008 +0000
     2.2 +++ b/src/video/win32/SDL_win32keyboard.c	Sat Feb 09 22:28:27 2008 +0000
     2.3 @@ -26,17 +26,43 @@
     2.4  #include "../../events/SDL_keyboard_c.h"
     2.5  #include "../../events/scancodes_win32.h"
     2.6  
     2.7 +#ifndef MAPVK_VK_TO_VSC
     2.8 +#define MAPVK_VK_TO_VSC     0
     2.9 +#endif
    2.10 +#ifndef MAPVK_VSC_TO_VK
    2.11 +#define MAPVK_VSC_TO_VK     1
    2.12 +#endif
    2.13 +#ifndef MAPVK_VK_TO_CHAR
    2.14 +#define MAPVK_VK_TO_CHAR    2
    2.15 +#endif
    2.16 +
    2.17 +/* Alphabetic scancodes for PC keyboards */
    2.18 +BYTE alpha_scancodes[26] = {
    2.19 +    30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50, 49, 24,
    2.20 +    25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44
    2.21 +};
    2.22 +
    2.23  void
    2.24  WIN_InitKeyboard(_THIS)
    2.25  {
    2.26      SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    2.27      SDL_Keyboard keyboard;
    2.28 +    int i;
    2.29 +
    2.30 +    /* Make sure the alpha scancodes are correct.  T isn't usually remapped */
    2.31 +    if (MapVirtualKey('T', MAPVK_VK_TO_VSC) != alpha_scancodes['T'-'A']) {
    2.32 +printf("Fixing alpha scancode map, assuming US QWERTY layout!\nPlease send the following 26 lines of output to the SDL mailing list <sdl@libsdl.org>, including a description of your keyboard hardware.\n");
    2.33 +        for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) {
    2.34 +            alpha_scancodes[i] = MapVirtualKey('A'+i, MAPVK_VK_TO_VSC);
    2.35 +printf("%d = %d\n", i, alpha_scancodes[i]);
    2.36 +        }
    2.37 +    }
    2.38  
    2.39      data->key_layout = win32_scancode_table;
    2.40  
    2.41      SDL_zero(keyboard);
    2.42      data->keyboard = SDL_AddKeyboard(&keyboard, -1);
    2.43 -    WIN_UpdateKeymap(_this);
    2.44 +    WIN_UpdateKeymap(data->keyboard);
    2.45  
    2.46      SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
    2.47      SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Windows");
    2.48 @@ -44,9 +70,8 @@
    2.49  }
    2.50  
    2.51  void
    2.52 -WIN_UpdateKeymap(_THIS)
    2.53 +WIN_UpdateKeymap(int keyboard)
    2.54  {
    2.55 -    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    2.56      int i;
    2.57      SDL_scancode scancode;
    2.58      SDLKey keymap[SDL_NUM_SCANCODES];
    2.59 @@ -61,12 +86,16 @@
    2.60              (keymap[scancode] & SDLK_SCANCODE_MASK)) {
    2.61              continue;
    2.62          }
    2.63 -#ifndef MAPVK_VK_TO_CHAR
    2.64 -#define MAPVK_VK_TO_CHAR    2
    2.65 -#endif
    2.66 -        keymap[scancode] = (MapVirtualKey(i, MAPVK_VK_TO_CHAR) & 0x7FFF);
    2.67 +
    2.68 +        /* Alphabetic keys are handled specially, since Windows remaps them */
    2.69 +        if (i >= 'A' && i <= 'Z') {
    2.70 +            BYTE vsc = alpha_scancodes[i-'A'];
    2.71 +            keymap[scancode] = MapVirtualKey(vsc, MAPVK_VSC_TO_VK) + 0x20;
    2.72 +        } else {
    2.73 +            keymap[scancode] = (MapVirtualKey(i, MAPVK_VK_TO_CHAR) & 0x7FFF);
    2.74 +        }
    2.75      }
    2.76 -    SDL_SetKeymap(data->keyboard, 0, keymap, SDL_NUM_SCANCODES);
    2.77 +    SDL_SetKeymap(keyboard, 0, keymap, SDL_NUM_SCANCODES);
    2.78  }
    2.79  
    2.80  void
     3.1 --- a/src/video/win32/SDL_win32keyboard.h	Sat Feb 09 07:18:38 2008 +0000
     3.2 +++ b/src/video/win32/SDL_win32keyboard.h	Sat Feb 09 22:28:27 2008 +0000
     3.3 @@ -24,8 +24,10 @@
     3.4  #ifndef _SDL_win32keyboard_h
     3.5  #define _SDL_win32keyboard_h
     3.6  
     3.7 +extern BYTE alpha_scancodes[26];
     3.8 +
     3.9  extern void WIN_InitKeyboard(_THIS);
    3.10 -extern void WIN_UpdateKeymap(_THIS);
    3.11 +extern void WIN_UpdateKeymap(int keyboard);
    3.12  extern void WIN_QuitKeyboard(_THIS);
    3.13  
    3.14  #endif /* _SDL_win32keyboard_h */