[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: Re: dinput: the DIK_ keycode is not the same as the scancode.
From: Aric Stewart <aric () codeweavers ! com>
Date: 2008-07-31 17:30:46
Message-ID: 4891F6C6.2050708 () codeweavers ! com
[Download RAW message or body]
Here is a revised patch which builds the scancode->DIK table on
initialization making no xserver round trips required on lookup.
How does this look?
-aric
Aric Stewart wrote:
> Yes, I have verified those vkeys in windows.
> the VK_OEM_* keys are specificaly VK codes that vary from keyboard to
> keyboard. VK_OEM_3 is just one example.
>
> -aric
>
> Vitaliy Margolen wrote:
>> Aric Stewart wrote:
>>> vkey codes similarly do not produce a clean 1 to 1 correspondance.
>>> the '@' key (0x1a) is vkey (VK_OEM_3) which is the vkey of the '`'
>>> key on the us keyboard.
>> This is needs to be fixed in x11drv then. Not in dinput. Have you
>> verified what v_keys you getting from windows for these keys?
>>
>> Vitaliy.
>>
>
["dinput.diff" (text/plain)]
commit f32b8b281a5df115881f2c5c6dd2f273d5b2b657
Author: Aric Stewart <aric@codeweavers.com>
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:
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic