diff --git a/patches/dinput-scancode/0001-dinput-Factor-keyboard-initialization-and-enumeratio.patch b/patches/dinput-scancode/0001-dinput-Factor-keyboard-initialization-and-enumeratio.patch new file mode 100644 index 00000000..d747d6ed --- /dev/null +++ b/patches/dinput-scancode/0001-dinput-Factor-keyboard-initialization-and-enumeratio.patch @@ -0,0 +1,175 @@ +From 77a518b61884ef4e06f4fe8b94dd5c855c5e8daf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Fri, 23 Aug 2024 08:49:13 +0200 +Subject: [PATCH] dinput: Factor keyboard initialization and enumeration loops. + +--- + dlls/dinput/keyboard.c | 129 +++++++++++++++++++++++------------------ + 1 file changed, 72 insertions(+), 57 deletions(-) + +diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c +index 8ec9dd47150..d1fa242574e 100644 +--- a/dlls/dinput/keyboard.c ++++ b/dlls/dinput/keyboard.c +@@ -185,12 +185,79 @@ HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instan + return DI_OK; + } + ++static BOOL enum_object( struct keyboard *impl, const DIPROPHEADER *filter, DWORD flags, enum_object_callback callback, ++ UINT index, DIDEVICEOBJECTINSTANCEW *instance, void *data ) ++{ ++ if (flags != DIDFT_ALL && !(flags & DIDFT_GETTYPE( instance->dwType ))) return DIENUM_CONTINUE; ++ ++ switch (filter->dwHow) ++ { ++ case DIPH_DEVICE: ++ return callback( &impl->base, index, NULL, instance, data ); ++ case DIPH_BYOFFSET: ++ if (filter->dwObj != instance->dwOfs) return DIENUM_CONTINUE; ++ return callback( &impl->base, index, NULL, instance, data ); ++ case DIPH_BYID: ++ if ((filter->dwObj & 0x00ffffff) != (instance->dwType & 0x00ffffff)) return DIENUM_CONTINUE; ++ return callback( &impl->base, index, NULL, instance, data ); ++ } ++ ++ return DIENUM_CONTINUE; ++} ++ ++static HRESULT enum_objects( struct keyboard *impl, const DIPROPHEADER *filter, ++ DWORD flags, enum_object_callback callback, void *data ) ++{ ++ BYTE subtype = GET_DIDEVICE_SUBTYPE( impl->base.instance.dwDevType ); ++ DIDEVICEOBJECTINSTANCEW instance = ++ { ++ .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), ++ .guidType = GUID_Key, ++ .dwOfs = DIK_ESCAPE, ++ .dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ), ++ }; ++ DWORD index, i, dik; ++ BOOL ret; ++ ++ for (i = 0, index = 0; i < 512; ++i) ++ { ++ if (!GetKeyNameTextW( i << 16, instance.tszName, ARRAY_SIZE(instance.tszName) )) continue; ++ if (!(dik = map_dik_code( i, 0, subtype, impl->base.dinput->dwVersion ))) continue; ++ instance.dwOfs = dik; ++ instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik ); ++ ret = enum_object( impl, filter, flags, callback, index++, &instance, data ); ++ if (ret != DIENUM_CONTINUE) return DIENUM_STOP; ++ } ++ ++ return DIENUM_CONTINUE; ++} ++ ++static BOOL init_object_properties( struct dinput_device *device, UINT index, struct hid_value_caps *caps, ++ const DIDEVICEOBJECTINSTANCEW *instance, void *data ) ++{ ++ struct object_properties *properties; ++ UINT dik = instance->dwOfs; ++ ++ if (index == -1) return DIENUM_STOP; ++ properties = device->object_properties + index; ++ ++ if (dik == DIK_NUMLOCK) properties->scan_code = 0x451de1; ++ else if (dik == DIK_PAUSE) properties->scan_code = 0x45; ++ else if (dik < 0x80) properties->scan_code = dik; ++ else properties->scan_code = (dik - 0x80) << 8 | 0x00e0; ++ ++ return DIENUM_CONTINUE; ++} ++ + HRESULT keyboard_create_device( struct dinput *dinput, const GUID *guid, IDirectInputDevice8W **out ) + { +- DIDEVICEOBJECTINSTANCEW instance; ++ static const DIPROPHEADER filter = ++ { ++ .dwSize = sizeof(filter), ++ .dwHeaderSize = sizeof(filter), ++ .dwHow = DIPH_DEVICE, ++ }; + struct keyboard *impl; +- DWORD i, index, dik; +- BYTE subtype; + HRESULT hr; + + TRACE( "dinput %p, guid %s, out %p.\n", dinput, debugstr_guid( guid ), out ); +@@ -207,20 +274,9 @@ HRESULT keyboard_create_device( struct dinput *dinput, const GUID *guid, IDirect + impl->base.caps.dwFirmwareRevision = 100; + impl->base.caps.dwHardwareRevision = 100; + if (dinput->dwVersion >= 0x0800) impl->base.use_raw_input = TRUE; +- subtype = GET_DIDEVICE_SUBTYPE( impl->base.instance.dwDevType ); + + if (FAILED(hr = dinput_device_init_device_format( &impl->base.IDirectInputDevice8W_iface ))) goto failed; +- +- for (i = 0, index = 0; i < 512; ++i) +- { +- if (!GetKeyNameTextW( i << 16, instance.tszName, ARRAY_SIZE(instance.tszName) )) continue; +- if (!(dik = map_dik_code( i, 0, subtype, impl->base.dinput->dwVersion ))) continue; +- +- if (dik == DIK_NUMLOCK) impl->base.object_properties[index++].scan_code = 0x451de1; +- else if (dik == DIK_PAUSE) impl->base.object_properties[index++].scan_code = 0x45; +- else if (dik < 0x80) impl->base.object_properties[index++].scan_code = dik; +- else impl->base.object_properties[index++].scan_code = (dik - 0x80) << 8 | 0x00e0; +- } ++ enum_objects( impl, &filter, DIDFT_BUTTON, init_object_properties, NULL ); + + *out = &impl->base.IDirectInputDevice8W_iface; + return DI_OK; +@@ -248,52 +304,11 @@ static HRESULT keyboard_unacquire( IDirectInputDevice8W *iface ) + return DI_OK; + } + +-static BOOL try_enum_object( struct dinput_device *impl, const DIPROPHEADER *filter, DWORD flags, enum_object_callback callback, +- UINT index, DIDEVICEOBJECTINSTANCEW *instance, void *data ) +-{ +- if (flags != DIDFT_ALL && !(flags & DIDFT_GETTYPE( instance->dwType ))) return DIENUM_CONTINUE; +- +- switch (filter->dwHow) +- { +- case DIPH_DEVICE: +- return callback( impl, index, NULL, instance, data ); +- case DIPH_BYOFFSET: +- if (filter->dwObj != instance->dwOfs) return DIENUM_CONTINUE; +- return callback( impl, index, NULL, instance, data ); +- case DIPH_BYID: +- if ((filter->dwObj & 0x00ffffff) != (instance->dwType & 0x00ffffff)) return DIENUM_CONTINUE; +- return callback( impl, index, NULL, instance, data ); +- } +- +- return DIENUM_CONTINUE; +-} +- + static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *filter, + DWORD flags, enum_object_callback callback, void *context ) + { + struct keyboard *impl = impl_from_IDirectInputDevice8W( iface ); +- BYTE subtype = GET_DIDEVICE_SUBTYPE( impl->base.instance.dwDevType ); +- DIDEVICEOBJECTINSTANCEW instance = +- { +- .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), +- .guidType = GUID_Key, +- .dwOfs = DIK_ESCAPE, +- .dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ), +- }; +- DWORD index, i, dik; +- BOOL ret; +- +- for (i = 0, index = 0; i < 512; ++i) +- { +- if (!GetKeyNameTextW( i << 16, instance.tszName, ARRAY_SIZE(instance.tszName) )) continue; +- if (!(dik = map_dik_code( i, 0, subtype, impl->base.dinput->dwVersion ))) continue; +- instance.dwOfs = dik; +- instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik ); +- ret = try_enum_object( &impl->base, filter, flags, callback, index++, &instance, context ); +- if (ret != DIENUM_CONTINUE) return DIENUM_STOP; +- } +- +- return DIENUM_CONTINUE; ++ return enum_objects( impl, filter, flags, callback, context ); + } + + static HRESULT keyboard_get_property( IDirectInputDevice8W *iface, DWORD property, +-- +2.43.0 + diff --git a/patches/dinput-scancode/0001-dinput-Avoid-duplicated-objects-in-keyboard-devices.patch b/patches/dinput-scancode/0002-dinput-Avoid-duplicated-objects-in-keyboard-devices.patch similarity index 74% rename from patches/dinput-scancode/0001-dinput-Avoid-duplicated-objects-in-keyboard-devices.patch rename to patches/dinput-scancode/0002-dinput-Avoid-duplicated-objects-in-keyboard-devices.patch index 801cdd71..90f6de34 100644 --- a/patches/dinput-scancode/0001-dinput-Avoid-duplicated-objects-in-keyboard-devices.patch +++ b/patches/dinput-scancode/0002-dinput-Avoid-duplicated-objects-in-keyboard-devices.patch @@ -1,6 +1,6 @@ -From b2764b3d21a64c3c194b29b9cb71379456e03b06 Mon Sep 17 00:00:00 2001 +From b9f850d5ba2d36ae39a2e88b31a687e2d9745c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 7 Jul 2023 12:44:26 +0200 +Date: Fri, 23 Aug 2024 08:51:44 +0200 Subject: [PATCH] dinput: Avoid duplicated objects in keyboard devices. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55205 @@ -9,10 +9,10 @@ Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55205 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c -index cbcbf94f0f6..3fd75bb10e6 100644 +index d1fa242574e..d9c73cd7367 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c -@@ -265,13 +265,15 @@ static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPH +@@ -216,13 +216,15 @@ static HRESULT enum_objects( struct keyboard *impl, const DIPROPHEADER *filter, .dwOfs = DIK_ESCAPE, .dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ), }; @@ -28,7 +28,7 @@ index cbcbf94f0f6..3fd75bb10e6 100644 + mapped[dik] = TRUE; instance.dwOfs = dik; instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik ); - ret = try_enum_object( &impl->base, filter, flags, callback, index++, &instance, context ); + ret = enum_object( impl, filter, flags, callback, index++, &instance, data ); -- -2.40.1 +2.43.0 diff --git a/patches/dinput-scancode/0002-dinput-Enumerate-lower-keyboard-scancodes-values-fir.patch b/patches/dinput-scancode/0003-dinput-Enumerate-lower-keyboard-scancodes-values-fir.patch similarity index 72% rename from patches/dinput-scancode/0002-dinput-Enumerate-lower-keyboard-scancodes-values-fir.patch rename to patches/dinput-scancode/0003-dinput-Enumerate-lower-keyboard-scancodes-values-fir.patch index b5ca4cd8..a6eec19d 100644 --- a/patches/dinput-scancode/0002-dinput-Enumerate-lower-keyboard-scancodes-values-fir.patch +++ b/patches/dinput-scancode/0003-dinput-Enumerate-lower-keyboard-scancodes-values-fir.patch @@ -1,6 +1,6 @@ -From bdf952bf0711a7cf22fee840197234bd413ae611 Mon Sep 17 00:00:00 2001 +From c133a17f33a7cce87df6a56c7e265b1553726134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 7 Jul 2023 12:45:04 +0200 +Date: Fri, 23 Aug 2024 08:52:34 +0200 Subject: [PATCH] dinput: Enumerate lower keyboard scancodes values first. Windows usually doesn't have scancodes higher than 0x7f, or extended @@ -16,18 +16,18 @@ Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55205 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c -index 3fd75bb10e6..1f1db883b80 100644 +index d9c73cd7367..407634967de 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c -@@ -256,6 +256,7 @@ static BOOL try_enum_object( struct dinput_device *impl, const DIPROPHEADER *fil - static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *filter, - DWORD flags, enum_object_callback callback, void *context ) +@@ -208,6 +208,7 @@ static BOOL enum_object( struct keyboard *impl, const DIPROPHEADER *filter, DWOR + static HRESULT enum_objects( struct keyboard *impl, const DIPROPHEADER *filter, + DWORD flags, enum_object_callback callback, void *data ) { + static const UINT vsc_base[] = {0, 0x100, 0x80, 0x180}; - struct keyboard *impl = impl_from_IDirectInputDevice8W( iface ); BYTE subtype = GET_DIDEVICE_SUBTYPE( impl->base.instance.dwDevType ); DIDEVICEOBJECTINSTANCEW instance = -@@ -266,18 +267,21 @@ static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPH + { +@@ -217,18 +218,21 @@ static HRESULT enum_objects( struct keyboard *impl, const DIPROPHEADER *filter, .dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ), }; BOOL ret, mapped[0x100] = {0}; @@ -43,7 +43,7 @@ index 3fd75bb10e6..1f1db883b80 100644 - mapped[dik] = TRUE; - instance.dwOfs = dik; - instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik ); -- ret = try_enum_object( &impl->base, filter, flags, callback, index++, &instance, context ); +- ret = enum_object( impl, filter, flags, callback, index++, &instance, data ); - if (ret != DIENUM_CONTINUE) return DIENUM_STOP; + for (vsc = vsc_base[i]; vsc < vsc_base[i] + 0x80; vsc++) + { @@ -53,12 +53,12 @@ index 3fd75bb10e6..1f1db883b80 100644 + mapped[dik] = TRUE; + instance.dwOfs = dik; + instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik ); -+ ret = try_enum_object( &impl->base, filter, flags, callback, index++, &instance, context ); ++ ret = enum_object( impl, filter, flags, callback, index++, &instance, data ); + if (ret != DIENUM_CONTINUE) return DIENUM_STOP; + } } return DIENUM_CONTINUE; -- -2.40.1 +2.43.0