[DINPUT] Sync with Wine Staging 3.17. CORE-15127
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 30 Sep 2018 23:20:57 +0000 (00:20 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 30 Sep 2018 23:20:57 +0000 (00:20 +0100)
dll/directx/wine/dinput/data_formats.c
dll/directx/wine/dinput/device.c
dll/directx/wine/dinput/dinput_main.c
dll/directx/wine/dinput/joystick_osx.c
dll/directx/wine/dinput/keyboard.c
media/doc/README.WINE

index 5fac7b7..9c9f00f 100644 (file)
@@ -25,8 +25,6 @@
 #include "windef.h"
 #include "dinput.h"
 
-#define numObjects(x) (sizeof(x) / sizeof(x[0]))
-
 static const DIOBJECTDATAFORMAT dfDIJoystick[] = {
   { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
   { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
@@ -79,7 +77,7 @@ const DIDATAFORMAT c_dfDIJoystick = {
     sizeof(DIOBJECTDATAFORMAT),
     DIDF_ABSAXIS,
     sizeof(DIJOYSTATE),
-    numObjects(dfDIJoystick),
+    ARRAY_SIZE(dfDIJoystick),
     (LPDIOBJECTDATAFORMAT)dfDIJoystick
 };
 
@@ -255,7 +253,7 @@ const DIDATAFORMAT c_dfDIJoystick2 = {
     sizeof(DIOBJECTDATAFORMAT),
     DIDF_ABSAXIS,
     sizeof(DIJOYSTATE2),
-    numObjects(dfDIJoystick2),
+    ARRAY_SIZE(dfDIJoystick2),
     (LPDIOBJECTDATAFORMAT)dfDIJoystick2
 };
 
@@ -274,7 +272,7 @@ const DIDATAFORMAT c_dfDIMouse = {
     sizeof(DIOBJECTDATAFORMAT),
     DIDF_RELAXIS,
     sizeof(DIMOUSESTATE),
-    numObjects(dfDIMouse),
+    ARRAY_SIZE(dfDIMouse),
     (LPDIOBJECTDATAFORMAT)dfDIMouse
 };
 
@@ -297,7 +295,7 @@ const DIDATAFORMAT c_dfDIMouse2 = {
     sizeof(DIOBJECTDATAFORMAT),
     DIDF_RELAXIS,
     sizeof(DIMOUSESTATE2),
-    numObjects(dfDIMouse2),
+    ARRAY_SIZE(dfDIMouse2),
     (LPDIOBJECTDATAFORMAT)dfDIMouse2
 };
 
@@ -565,6 +563,6 @@ const DIDATAFORMAT c_dfDIKeyboard = {
     sizeof(DIOBJECTDATAFORMAT),
     DIDF_RELAXIS,
     256,
-    numObjects(dfDIKeyboard),
+    ARRAY_SIZE(dfDIKeyboard),
     (LPDIOBJECTDATAFORMAT)dfDIKeyboard
 };
index bb2a641..50ad76f 100644 (file)
@@ -39,6 +39,8 @@
 #include "device_private.h"
 #include "dinput_private.h"
 
+#define WM_WINE_NOTIFY_ACTIVITY WM_USER
+
 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
 
 static inline IDirectInputDeviceImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
@@ -935,6 +937,8 @@ void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DWORD tim
     /* Event is being set regardless of the queue state */
     if (This->hEvent) SetEvent(This->hEvent);
 
+    PostMessageW(GetDesktopWindow(), WM_WINE_NOTIFY_ACTIVITY, 0, 0);
+
     if (!This->queue_len || This->overflow || ofs < 0) return;
 
     next_pos = (This->queue_head + 1) % This->queue_len;
index 69b9ff0..82c0d14 100644 (file)
@@ -92,7 +92,6 @@ static const struct dinput_device *dinput_devices[] =
     &joystick_linux_device,
     &joystick_osx_device
 };
-#define NB_DINPUT_DEVICES (sizeof(dinput_devices)/sizeof(dinput_devices[0]))
 
 static HINSTANCE DINPUT_instance = NULL;
 
@@ -165,6 +164,63 @@ HRESULT WINAPI DirectInputCreateEx(
     return DI_OK;
 }
 
+/******************************************************************************
+ *     DirectInput8Create (DINPUT8.@)
+ */
+HRESULT WINAPI DECLSPEC_HOTPATCH DirectInput8Create(HINSTANCE hinst,
+    DWORD version, REFIID iid, void **out, IUnknown *outer)
+{
+    IDirectInputImpl *This;
+    HRESULT hr;
+
+    TRACE("hinst %p, version %#x, iid %s, out %p, outer %p.\n",
+        hinst, version, debugstr_guid(iid), out, outer);
+
+    if (!out)
+        return E_POINTER;
+
+    if (!IsEqualGUID(&IID_IDirectInput8A, iid) &&
+        !IsEqualGUID(&IID_IDirectInput8W, iid) &&
+        !IsEqualGUID(&IID_IUnknown, iid))
+    {
+        *out = NULL;
+        return DIERR_NOINTERFACE;
+    }
+
+    hr = create_directinput_instance(iid, out, &This);
+
+    if (FAILED(hr))
+    {
+        ERR("Failed to create DirectInput, hr %#x.\n", hr);
+        return hr;
+    }
+
+    /* When aggregation is used, the application needs to manually call Initialize(). */
+    if (!outer && IsEqualGUID(&IID_IDirectInput8A, iid))
+    {
+        hr = IDirectInput8_Initialize(&This->IDirectInput8A_iface, hinst, version);
+        if (FAILED(hr))
+        {
+            IDirectInput8_Release(&This->IDirectInput8A_iface);
+            *out = NULL;
+            return hr;
+        }
+    }
+
+    if (!outer && IsEqualGUID(&IID_IDirectInput8W, iid))
+    {
+        hr = IDirectInput8_Initialize(&This->IDirectInput8W_iface, hinst, version);
+        if (FAILED(hr))
+        {
+            IDirectInput8_Release(&This->IDirectInput8W_iface);
+            *out = NULL;
+            return hr;
+        }
+    }
+
+    return S_OK;
+}
+
 /******************************************************************************
  *     DirectInputCreateA (DINPUT.@)
  */
@@ -409,7 +465,7 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
     if (!This->initialized)
         return DIERR_NOTINITIALIZED;
 
-    for (i = 0; i < NB_DINPUT_DEVICES; i++) {
+    for (i = 0; i < ARRAY_SIZE(dinput_devices); i++) {
         if (!dinput_devices[i]->enum_deviceA) continue;
         for (j = 0, r = S_OK; SUCCEEDED(r); j++) {
             devInstance.dwSize = sizeof(devInstance);
@@ -449,7 +505,7 @@ static HRESULT WINAPI IDirectInputWImpl_EnumDevices(
     if (!This->initialized)
         return DIERR_NOTINITIALIZED;
 
-    for (i = 0; i < NB_DINPUT_DEVICES; i++) {
+    for (i = 0; i < ARRAY_SIZE(dinput_devices); i++) {
         if (!dinput_devices[i]->enum_deviceW) continue;
         for (j = 0, r = S_OK; SUCCEEDED(r); j++) {
             devInstance.dwSize = sizeof(devInstance);
@@ -750,7 +806,7 @@ static HRESULT create_device(IDirectInputImpl *This, REFGUID rguid, REFIID riid,
         return DIERR_NOTINITIALIZED;
 
     /* Loop on all the devices to see if anyone matches the given GUID */
-    for (i = 0; i < NB_DINPUT_DEVICES; i++)
+    for (i = 0; i < ARRAY_SIZE(dinput_devices); i++)
     {
         HRESULT ret;
 
@@ -1006,7 +1062,7 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
     }
 
     /* Enumerate all the joysticks */
-    for (i = 0; i < NB_DINPUT_DEVICES; i++)
+    for (i = 0; i < ARRAY_SIZE(dinput_devices); i++)
     {
         HRESULT enumSuccess;
 
@@ -1107,7 +1163,7 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
     didevi.dwSize = sizeof(didevi);
 
     /* Enumerate all the joysticks */
-    for (i = 0; i < NB_DINPUT_DEVICES; i++)
+    for (i = 0; i < ARRAY_SIZE(dinput_devices); i++)
     {
         HRESULT enumSuccess;
 
@@ -1330,7 +1386,7 @@ static HRESULT WINAPI JoyConfig8Impl_GetConfig(IDirectInputJoyConfig8 *iface, UI
 #undef X
 
     /* Enumerate all joysticks in order */
-    for (i = 0; i < NB_DINPUT_DEVICES; i++)
+    for (i = 0; i < ARRAY_SIZE(dinput_devices); i++)
     {
         if (!dinput_devices[i]->enum_deviceA) continue;
 
@@ -1520,7 +1576,10 @@ static HRESULT WINAPI DICF_CreateInstance(
             IsEqualGUID( &IID_IDirectInput2A, riid ) ||
             IsEqualGUID( &IID_IDirectInput2W, riid ) ||
             IsEqualGUID( &IID_IDirectInput7A, riid ) ||
-            IsEqualGUID( &IID_IDirectInput7W, riid ) ) {
+            IsEqualGUID( &IID_IDirectInput7W, riid ) ||
+            IsEqualGUID( &IID_IDirectInput8A, riid ) ||
+            IsEqualGUID( &IID_IDirectInput8W, riid ) )
+        {
                return create_directinput_instance(riid, ppobj, NULL);
        }
 
index b0dcdd9..2b2aade 100644 (file)
@@ -932,18 +932,31 @@ static INT find_joystick_devices(void)
     return  joystick_devices_count;
 }
 
+static DWORD make_vid_pid(IOHIDDeviceRef device)
+{
+    long vendID, prodID;
+
+    vendID = get_device_property_long(device, CFSTR(kIOHIDVendorIDKey));
+    prodID = get_device_property_long(device, CFSTR(kIOHIDProductIDKey));
+
+    return MAKELONG(vendID, prodID);
+}
+
 static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
 {
+    IOHIDDeviceRef device;
+
     TRACE("dwDevType %u dwFlags 0x%08x version 0x%04x id %d\n", dwDevType, dwFlags, version, id);
 
     if (id >= find_joystick_devices()) return E_FAIL;
 
+    device = get_device_ref(id);
+
     if ((dwDevType == 0) ||
     ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
     (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800)))
     {
         if (dwFlags & DIEDFL_FORCEFEEDBACK) {
-            IOHIDDeviceRef device = get_device_ref(id);
             if(!device)
                 return S_FALSE;
             if(get_ff(device, NULL) != S_OK)
@@ -953,6 +966,7 @@ static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS
         lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID;
         lpddi->guidInstance.Data3 = id;
         lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID;
+        lpddi->guidProduct.Data1 = make_vid_pid(device);
         /* we only support traditional joysticks for now */
         if (version >= 0x0800)
             lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
@@ -974,16 +988,19 @@ static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS
 {
     char name[MAX_PATH];
     char friendly[32];
+    IOHIDDeviceRef device;
 
     TRACE("dwDevType %u dwFlags 0x%08x version 0x%04x id %d\n", dwDevType, dwFlags, version, id);
 
     if (id >= find_joystick_devices()) return E_FAIL;
 
+    device = get_device_ref(id);
+
     if ((dwDevType == 0) ||
     ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
     (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
+
         if (dwFlags & DIEDFL_FORCEFEEDBACK) {
-            IOHIDDeviceRef device = get_device_ref(id);
             if(!device)
                 return S_FALSE;
             if(get_ff(device, NULL) != S_OK)
@@ -993,6 +1010,7 @@ static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS
         lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID;
         lpddi->guidInstance.Data3 = id;
         lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID;
+        lpddi->guidProduct.Data1 = make_vid_pid(device);
         /* we only support traditional joysticks for now */
         if (version >= 0x0800)
             lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
@@ -1060,9 +1078,12 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
 
     newDevice->id = index;
 
+    device = get_device_ref(index);
+
     newDevice->generic.guidInstance = DInput_Wine_OsX_Joystick_GUID;
     newDevice->generic.guidInstance.Data3 = index;
     newDevice->generic.guidProduct = DInput_Wine_OsX_Joystick_GUID;
+    newDevice->generic.guidProduct.Data1 = make_vid_pid(device);
     newDevice->generic.joy_polldev = poll_osx_device_state;
 
     /* get the device name */
@@ -1074,7 +1095,6 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
     strcpy(newDevice->generic.name, name);
 
     list_init(&newDevice->effects);
-    device = get_device_ref(index);
     if(get_ff(device, &newDevice->ff) == S_OK){
         newDevice->generic.devcaps.dwFlags |= DIDC_FORCEFEEDBACK;
 
index 8a59ce0..6c7b535 100644 (file)
@@ -48,6 +48,7 @@ struct SysKeyboardImpl
 {
     struct IDirectInputDeviceImpl base;
     BYTE DInputKeyState[WINE_DINPUT_KEYBOARD_MAX_KEYS];
+    DWORD subtype;
 };
 
 static inline SysKeyboardImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
@@ -67,11 +68,38 @@ static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(SysKeyboardIm
     return &This->base.IDirectInputDevice8W_iface;
 }
 
-static BYTE map_dik_code(DWORD scanCode, DWORD vkCode)
+static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType)
 {
     if (!scanCode)
         scanCode = MapVirtualKeyW(vkCode, MAPVK_VK_TO_VSC);
 
+    if (subType == DIDEVTYPEKEYBOARD_JAPAN106)
+    {
+        switch (scanCode)
+        {
+        case 0x0d: /* ^ */
+            scanCode = DIK_CIRCUMFLEX;
+            break;
+        case 0x1a: /* @ */
+            scanCode = DIK_AT;
+            break;
+        case 0x1b: /* [ */
+            scanCode = DIK_LBRACKET;
+            break;
+        case 0x28: /* : */
+            scanCode = DIK_COLON;
+            break;
+        case 0x29: /* Hankaku/Zenkaku */
+            scanCode = DIK_KANJI;
+            break;
+        case 0x2b: /* ] */
+            scanCode = DIK_RBRACKET;
+            break;
+        case 0x73: /* \ */
+            scanCode = DIK_BACKSLASH;
+            break;
+        }
+    }
     return scanCode;
 }
 
@@ -97,7 +125,7 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM
         case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break;
         case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break;
         default:
-            dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode);
+            dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype);
             if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
     }
     new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;
@@ -121,7 +149,24 @@ const GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441
     0x0ab8648a, 0x7735, 0x11d2, {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
 };
 
-static void fill_keyboard_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version) {
+static DWORD get_keyboard_subtype(void)
+{
+    DWORD kbd_type, kbd_subtype, dev_subtype;
+    kbd_type = GetKeyboardType(0);
+    kbd_subtype = GetKeyboardType(1);
+
+    if (kbd_type == 4 || (kbd_type == 7 && kbd_subtype == 0))
+        dev_subtype = DIDEVTYPEKEYBOARD_PCENH;
+    else if (kbd_type == 7 && kbd_subtype == 2)
+        dev_subtype = DIDEVTYPEKEYBOARD_JAPAN106;
+    else {
+        FIXME("Unknown keyboard type=%u, subtype=%u\n", kbd_type, kbd_subtype);
+        dev_subtype = DIDEVTYPEKEYBOARD_PCENH;
+    }
+    return dev_subtype;
+}
+
+static void fill_keyboard_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version, DWORD subtype) {
     DWORD dwSize;
     DIDEVICEINSTANCEA ddi;
     
@@ -136,16 +181,16 @@ static void fill_keyboard_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD ver
     ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
     ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
     if (version >= 0x0800)
-        ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8);
+        ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (subtype << 8);
     else
-        ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
+        ddi.dwDevType = DIDEVTYPE_KEYBOARD | (subtype << 8);
     strcpy(ddi.tszInstanceName, "Keyboard");
     strcpy(ddi.tszProductName, "Wine Keyboard");
 
     memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
 }
 
-static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version) {
+static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version, DWORD subtype) {
     DWORD dwSize;
     DIDEVICEINSTANCEW ddi;
     
@@ -160,9 +205,9 @@ static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
     ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
     ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
     if (version >= 0x0800)
-        ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8);
+        ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (subtype << 8);
     else
-        ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
+        ddi.dwDevType = DIDEVTYPE_KEYBOARD | (subtype << 8);
     MultiByteToWideChar(CP_ACP, 0, "Keyboard", -1, ddi.tszInstanceName, MAX_PATH);
     MultiByteToWideChar(CP_ACP, 0, "Wine Keyboard", -1, ddi.tszProductName, MAX_PATH);
 
@@ -179,7 +224,7 @@ static HRESULT keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVI
       (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 0x0800))) {
     TRACE("Enumerating the Keyboard device\n");
  
-    fill_keyboard_dideviceinstanceA(lpddi, version);
+    fill_keyboard_dideviceinstanceA(lpddi, version, get_keyboard_subtype());
     
     return S_OK;
   }
@@ -197,7 +242,7 @@ static HRESULT keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVI
       (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 0x0800))) {
     TRACE("Enumerating the Keyboard device\n");
 
-    fill_keyboard_dideviceinstanceW(lpddi, version);
+    fill_keyboard_dideviceinstanceW(lpddi, version, get_keyboard_subtype());
     
     return S_OK;
   }
@@ -220,6 +265,7 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
     newDevice->base.event_proc = KeyboardCallback;
     InitializeCriticalSection(&newDevice->base.crit);
     newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit");
+    newDevice->subtype = get_keyboard_subtype();
 
     /* Create copy of default data format */
     if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIKeyboard.dwSize))) goto failed;
@@ -229,12 +275,14 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
     for (i = 0; i < df->dwNumObjs; i++)
     {
         char buf[MAX_PATH];
+        BYTE dik_code;
 
         if (!GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), buf, sizeof(buf)))
             continue;
 
-        memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[i], df->dwObjSize);
-        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
+        dik_code = map_dik_code(i, 0, newDevice->subtype);
+        memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[dik_code], df->dwObjSize);
+        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON;
     }
     df->dwNumObjs = idx;
 
@@ -362,9 +410,9 @@ static HRESULT WINAPI SysKeyboardWImpl_GetCapabilities(LPDIRECTINPUTDEVICE8W ifa
     devcaps.dwSize = lpDIDevCaps->dwSize;
     devcaps.dwFlags = DIDC_ATTACHED | DIDC_EMULATED;
     if (This->base.dinput->dwVersion >= 0x0800)
-        devcaps.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_PCENH << 8);
+        devcaps.dwDevType = DI8DEVTYPE_KEYBOARD | (This->subtype << 8);
     else
-        devcaps.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_PCENH << 8);
+        devcaps.dwDevType = DIDEVTYPE_KEYBOARD | (This->subtype << 8);
     devcaps.dwAxes = 0;
     devcaps.dwButtons = This->base.data_format.wine_df->dwNumObjs;
     devcaps.dwPOVs = 0;
@@ -385,6 +433,40 @@ static HRESULT WINAPI SysKeyboardAImpl_GetCapabilities(LPDIRECTINPUTDEVICE8A ifa
     return SysKeyboardWImpl_GetCapabilities(IDirectInputDevice8W_from_impl(This), lpDIDevCaps);
 }
 
+static DWORD map_dik_to_scan(DWORD dik_code, DWORD subtype)
+{
+    if (dik_code == DIK_PAUSE || dik_code == DIK_NUMLOCK) dik_code ^= 0x80;
+    if (subtype == DIDEVTYPEKEYBOARD_JAPAN106)
+    {
+        switch (dik_code)
+        {
+        case DIK_CIRCUMFLEX:
+            dik_code = 0x0d;
+            break;
+        case DIK_AT:
+            dik_code = 0x1a;
+            break;
+        case DIK_LBRACKET:
+            dik_code = 0x1b;
+            break;
+        case DIK_COLON:
+            dik_code = 0x28;
+            break;
+        case DIK_KANJI:
+            dik_code = 0x29;
+            break;
+        case DIK_RBRACKET:
+            dik_code = 0x2b;
+            break;
+        case DIK_BACKSLASH:
+            dik_code = 0x73;
+            break;
+        }
+    }
+
+    return dik_code;
+}
+
 /******************************************************************************
   *     GetObjectInfo : get information about a device object such as a button
   *                     or axis
@@ -396,14 +478,14 @@ SysKeyboardAImpl_GetObjectInfo(
        DWORD dwObj,
        DWORD dwHow)
 {
+    SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface);
     HRESULT res;
     LONG scan;
 
     res = IDirectInputDevice2AImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
     if (res != DI_OK) return res;
 
-    scan = DIDFT_GETINSTANCE(pdidoi->dwType);
-    if (scan == DIK_PAUSE || scan == DIK_NUMLOCK) scan ^= 0x80;
+    scan = map_dik_to_scan(DIDFT_GETINSTANCE(pdidoi->dwType), This->subtype);
     if (!GetKeyNameTextA((scan & 0x80) << 17 | (scan & 0x7f) << 16,
                          pdidoi->tszName, sizeof(pdidoi->tszName)))
         return DIERR_OBJECTNOTFOUND;
@@ -417,14 +499,14 @@ static HRESULT WINAPI SysKeyboardWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface
                                                     DWORD dwObj,
                                                     DWORD dwHow)
 {
+    SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface);
     HRESULT res;
     LONG scan;
 
     res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
     if (res != DI_OK) return res;
 
-    scan = DIDFT_GETINSTANCE(pdidoi->dwType);
-    if (scan == DIK_PAUSE || scan == DIK_NUMLOCK) scan ^= 0x80;
+    scan = map_dik_to_scan(DIDFT_GETINSTANCE(pdidoi->dwType), This->subtype);
     if (!GetKeyNameTextW((scan & 0x80) << 17 | (scan & 0x7f) << 16,
                          pdidoi->tszName, sizeof(pdidoi->tszName)/sizeof(pdidoi->tszName[0])))
         return DIERR_OBJECTNOTFOUND;
@@ -448,7 +530,7 @@ static HRESULT WINAPI SysKeyboardAImpl_GetDeviceInfo(
        return DI_OK;
     }
 
-    fill_keyboard_dideviceinstanceA(pdidi, This->base.dinput->dwVersion);
+    fill_keyboard_dideviceinstanceA(pdidi, This->base.dinput->dwVersion, This->subtype);
     
     return DI_OK;
 }
@@ -463,7 +545,7 @@ static HRESULT WINAPI SysKeyboardWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface
        return DI_OK;
     }
 
-    fill_keyboard_dideviceinstanceW(pdidi, This->base.dinput->dwVersion);
+    fill_keyboard_dideviceinstanceW(pdidi, This->base.dinput->dwVersion, This->subtype);
     
     return DI_OK;
 }
index d017ab9..df4d66c 100644 (file)
@@ -30,7 +30,7 @@ reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-3.17
 reactos/dll/directx/wine/d3dxof         # Synced to WineStaging-3.17
 reactos/dll/directx/wine/ddraw          # Synced to WineStaging-3.9
 reactos/dll/directx/wine/devenum        # Synced to WineStaging-3.9
-reactos/dll/directx/wine/dinput         # Synced to WineStaging-3.9
+reactos/dll/directx/wine/dinput         # Synced to WineStaging-3.17
 reactos/dll/directx/wine/dinput8        # Synced to WineStaging-3.3
 reactos/dll/directx/wine/dmusic         # Synced to WineStaging-3.9
 reactos/dll/directx/wine/dplay          # Synced to WineStaging-3.3