Aric Stewart : winebus.sys: Allow mapping of SDL controllers.

Alexandre Julliard julliard at winehq.org
Tue Apr 9 16:31:03 CDT 2019


Module: wine
Branch: master
Commit: 1528d1685a43f820a04da3041499c354b26038ad
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1528d1685a43f820a04da3041499c354b26038ad

Author: Aric Stewart <aric at codeweavers.com>
Date:   Wed Mar 20 08:28:43 2019 -0500

winebus.sys: Allow mapping of SDL controllers.

Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winebus.sys/Makefile.in |  2 +-
 dlls/winebus.sys/bus_sdl.c   | 68 ++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/dlls/winebus.sys/Makefile.in b/dlls/winebus.sys/Makefile.in
index eda3c26..78e3da1 100644
--- a/dlls/winebus.sys/Makefile.in
+++ b/dlls/winebus.sys/Makefile.in
@@ -1,5 +1,5 @@
 MODULE    = winebus.sys
-IMPORTS   = ntoskrnl setupapi
+IMPORTS   = ntoskrnl setupapi advapi32
 EXTRALIBS = $(IOKIT_LIBS) $(UDEV_LIBS)
 EXTRAINCL = $(UDEV_CFLAGS) $(SDL2_CFLAGS)
 EXTRADLLFLAGS = -Wl,--subsystem,native
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 5589113..b774df7 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -38,6 +38,7 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
+#include "winreg.h"
 #include "winternl.h"
 #include "ddk/wdm.h"
 #include "ddk/hidtypes.h"
@@ -106,6 +107,7 @@ MAKE_FUNCPTR(SDL_HapticRunEffect);
 MAKE_FUNCPTR(SDL_HapticStopAll);
 MAKE_FUNCPTR(SDL_JoystickIsHaptic);
 MAKE_FUNCPTR(SDL_memset);
+MAKE_FUNCPTR(SDL_GameControllerAddMapping);
 #endif
 static Uint16 (*pSDL_JoystickGetProduct)(SDL_Joystick * joystick);
 static Uint16 (*pSDL_JoystickGetProductVersion)(SDL_Joystick * joystick);
@@ -890,9 +892,14 @@ static void process_device_event(SDL_Event *event)
         set_mapped_report_from_event(event);
 }
 
+typedef struct _thread_args {
+    HANDLE event;
+    UNICODE_STRING *registry_path;
+} thread_arguments;
+
 static DWORD CALLBACK deviceloop_thread(void *args)
 {
-    HANDLE init_done = args;
+    thread_arguments *thread_args = args;
     SDL_Event event;
 
     if (pSDL_Init(SDL_INIT_GAMECONTROLLER|SDL_INIT_HAPTIC) < 0)
@@ -904,7 +911,58 @@ static DWORD CALLBACK deviceloop_thread(void *args)
     pSDL_JoystickEventState(SDL_ENABLE);
     pSDL_GameControllerEventState(SDL_ENABLE);
 
-    SetEvent(init_done);
+    /* Process mappings */
+    if (pSDL_GameControllerAddMapping != NULL)
+    {
+        HANDLE key;
+        OBJECT_ATTRIBUTES attr;
+        WCHAR buffer[MAX_PATH];
+        UNICODE_STRING regpath = {0, sizeof(buffer), buffer};
+        static const WCHAR szPath[] = {'\\','m','a','p',0};
+
+        RtlCopyUnicodeString(&regpath, thread_args->registry_path);
+        RtlAppendUnicodeToString(&regpath, szPath);
+        InitializeObjectAttributes(&attr, &regpath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
+        if (NtOpenKey(&key, KEY_ALL_ACCESS, &attr) == STATUS_SUCCESS)
+        {
+            DWORD index = 0;
+            CHAR *buffer = NULL;
+            DWORD buffer_len = 0;
+            LSTATUS rc;
+
+            do {
+                CHAR name[255];
+                DWORD name_len;
+                DWORD type;
+                DWORD data_len = buffer_len;
+
+                name_len = sizeof(name);
+                rc = RegEnumValueA(key, index, name, &name_len, NULL, &type, (LPBYTE)buffer, &data_len);
+                if (rc == ERROR_MORE_DATA || buffer == NULL)
+                {
+                    if (buffer)
+                        buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, data_len);
+                    else
+                        buffer = HeapAlloc(GetProcessHeap(), 0, data_len);
+                    buffer_len = data_len;
+
+                    name_len = sizeof(name);
+                    rc = RegEnumValueA(key, index, name, &name_len, NULL, &type, (LPBYTE)buffer, &data_len);
+                }
+
+                if (rc == STATUS_SUCCESS)
+                {
+                    TRACE("Setting mapping %s...\n",debugstr_an(buffer,29));
+                    pSDL_GameControllerAddMapping(buffer);
+                    index ++;
+                }
+            } while (rc == STATUS_SUCCESS);
+            HeapFree(GetProcessHeap(), 0, buffer);
+            NtClose(key);
+        }
+    }
+
+    SetEvent(thread_args->event);
 
     while (1)
         while (pSDL_WaitEvent(&event) != 0)
@@ -926,6 +984,7 @@ NTSTATUS WINAPI sdl_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_
 
     HANDLE events[2];
     DWORD result;
+    thread_arguments args;
 
     TRACE("(%p, %s)\n", driver, debugstr_w(registry_path->Buffer));
     if (sdl_handle == NULL)
@@ -969,6 +1028,7 @@ NTSTATUS WINAPI sdl_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_
         LOAD_FUNCPTR(SDL_HapticStopAll);
         LOAD_FUNCPTR(SDL_JoystickIsHaptic);
         LOAD_FUNCPTR(SDL_memset);
+        LOAD_FUNCPTR(SDL_GameControllerAddMapping);
 #undef LOAD_FUNCPTR
         pSDL_JoystickGetProduct = wine_dlsym(sdl_handle, "SDL_JoystickGetProduct", NULL, 0);
         pSDL_JoystickGetProductVersion = wine_dlsym(sdl_handle, "SDL_JoystickGetProductVersion", NULL, 0);
@@ -983,7 +1043,9 @@ NTSTATUS WINAPI sdl_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_
 
     if (!(events[0] = CreateEventW(NULL, TRUE, FALSE, NULL)))
         goto error;
-    if (!(events[1] = CreateThread(NULL, 0, deviceloop_thread, events[0], 0, NULL)))
+    args.event = events[0];
+    args.registry_path = registry_path;
+    if (!(events[1] = CreateThread(NULL, 0, deviceloop_thread, &args, 0, NULL)))
     {
         CloseHandle(events[0]);
         goto error;




More information about the wine-cvs mailing list