Staging dinput-scancode fix

DodoGTA GT <[email protected]>
Newsgroups gmane.comp.emulators.wine.devel
Message-ID <CAKNqjs1u4yCiQAj+jEOecpeZU24MrGCkdm_L51+nO89Hs4n97Q@mail.gmail.com>
Hello

Here's a better regression fix for the dinput-scancode
patchset (the 0001 patch of that patchset caused NFS
Underground to segfault since Wine 9.15 with the addition
of a keycode loop in keyboard_create_device() because of
DIPROP_SCANCODE stuff); I modified the existing 0001
patch to solve this by copying the duplicate object checks
to that new loop (maybe I should create a separate 0003
patch to show the changes better?)

Hopefully the patch can be merged before 9.16 to not
re-introduce that regression after it has been worked
around in wine-staging 9.15

Thanks
0001-dinput-Avoid-duplicated-objects-in-keyboard-devices.patch (text/x-patch, 2.2 KB)
From 0cf643808826c87e6539ec04777905a714ee7155 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <[email protected]>
Date: Fri, 7 Jul 2023 12:44:26 +0200
Subject: [PATCH] dinput: Avoid duplicated objects in keyboard devices.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55205
---
 dlls/dinput/keyboard.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 8ec9dd47150..bbbac8b5bdd 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -188,6 +188,7 @@ HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instan
 HRESULT keyboard_create_device( struct dinput *dinput, const GUID *guid, IDirectInputDevice8W **out )
 {
     DIDEVICEOBJECTINSTANCEW instance;
+    BOOL mapped[0x100] = {0};
     struct keyboard *impl;
     DWORD i, index, dik;
     BYTE subtype;
@@ -215,6 +216,8 @@ HRESULT keyboard_create_device( struct dinput *dinput, const GUID *guid, IDirect
     {
         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 (mapped[dik]) continue;
+        mapped[dik] = TRUE;
 
         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;
@@ -280,13 +283,15 @@ static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPH
         .dwOfs = DIK_ESCAPE,
         .dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ),
     };
+    BOOL ret, mapped[0x100] = {0};
     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;
+        if (mapped[dik]) continue;
+        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 );
-- 
2.46.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.