[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