commit f32b8b281a5df115881f2c5c6dd2f273d5b2b657 Author: Aric Stewart Date: Fri Jul 25 16:07:30 2008 +0900 dinput: the DIK_ keycode is not the same as the scancode. It is mapped with the keyboard mapping to the resulting character. so the key 'A' is DIK_A nomatter what its scancode or vkey would be. This is relevent to Japanese keymapping where the '@' key is in the '[' location the scancode for both is 0x22 but dinput generates DIK_AT in japanese and DIK_LBRACKET in us_qwerty reworked to remove the giant case statement and hopefully be more clear. remove japan specific stuff diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index b2c4942..f4918b0 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -48,8 +48,32 @@ struct SysKeyboardImpl { struct IDirectInputDevice2AImpl base; BYTE DInputKeyState[WINE_DINPUT_KEYBOARD_MAX_KEYS]; + BYTE ScanCodemap[WINE_DINPUT_KEYBOARD_MAX_KEYS]; }; +static int map_dik_code(DWORD scanCode) +{ + static const int asciiCodes[] = + {/*32*/ DIK_SPACE,0,0,0,0,0,0,DIK_APOSTROPHE,0,0,0,0, DIK_COMMA, /*44*/ \ + /*45*/ DIK_MINUS, DIK_PERIOD, DIK_SLASH,DIK_0,DIK_1,DIK_2,DIK_3, /*51*/ \ + /*52*/ DIK_4,DIK_5,DIK_6,DIK_7,DIK_8,DIK_9,DIK_COLON,DIK_SEMICOLON,0, /*60*/ \ + /*61*/ DIK_EQUALS, 0,0,DIK_AT,DIK_A,DIK_B,DIK_C,DIK_D,DIK_E,DIK_F, /*70*/ \ + /*71*/ DIK_G,DIK_H,DIK_I,DIK_J,DIK_K,DIK_L,DIK_M,DIK_N,DIK_O,DIK_P, /*80*/ \ + /*81*/ DIK_Q,DIK_R,DIK_S,DIK_T,DIK_U,DIK_V,DIK_W,DIK_X,DIK_Y,DIK_Z, /*90*/ \ + /*91*/ DIK_LBRACKET,0,DIK_RBRACKET,DIK_CIRCUMFLEX,DIK_UNDERLINE} /*95*/ ; + int out_code = 0; + DWORD vkCode = MapVirtualKeyA(scanCode,MAPVK_VSC_TO_VK); + CHAR c = MapVirtualKeyA(vkCode,MAPVK_VK_TO_CHAR); + + if (c && c >31 && c < 96) + out_code = asciiCodes[c - 32]; + + if (out_code == 0) + out_code = scanCode; + + return out_code; +} + static void KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam ) { SysKeyboardImpl *This = (SysKeyboardImpl *)iface; @@ -63,7 +87,7 @@ static void KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM TRACE("(%p) %ld,%ld\n", iface, wparam, lparam); - dik_code = hook->scanCode & 0xff; + dik_code = This->ScanCodemap[hook->scanCode]; /* R-Shift is special - it is an extended key with separate scan code */ if (hook->flags & LLKHF_EXTENDED && dik_code != 0x36) dik_code |= 0x80; @@ -205,6 +229,10 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, const void *kvt, IDirectInpu newDevice->base.data_format.wine_df = df; IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->base.dinput); + /* Initialize scancode lookup */ + for (i = 0; i < WINE_DINPUT_KEYBOARD_MAX_KEYS; i++) + newDevice->ScanCodemap[i] = map_dik_code(i); + return newDevice; failed: