[PATCH] winebus.sys: Allow mapping of SDL controllers

Aric Stewart aric at codeweavers.com
Thu Mar 7 11:03:16 CST 2019



On 3/5/19 11:01 PM, Zebediah Figura wrote:
> On 3/5/19 1:32 PM, Aric Stewart wrote:
>  > diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
>  > index 55891138c8..863660ee89 100644
>  > --- a/dlls/winebus.sys/bus_sdl.c
>  > +++ b/dlls/winebus.sys/bus_sdl.c
>  > @@ -106,6 +106,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);
>  > @@ -904,6 +905,59 @@ static DWORD CALLBACK deviceloop_thread(void *args)
>  >      pSDL_JoystickEventState(SDL_ENABLE);
>  >      pSDL_GameControllerEventState(SDL_ENABLE);
>  >
>  > +    /* Process mappings */
>  > +    if (pSDL_GameControllerAddMapping != NULL)
>  > +    {
>  > +        HANDLE key;
>  > +        OBJECT_ATTRIBUTES attr;
>  > +        static const WCHAR szPath[] = {'\\',
>  > +           'R','e','g','i','s','t','r','y','\\',
>  > +           'U','s','e','r','\\',
>  > + 'S','-','1','-','5','-','2','1','-','0','-','0','-','0','-','1','0','0','0','\\',
>  > +           'S','o','f','t','w','a','r','e','\\',
>  > +           'W','i','n','e','\\',
>  > +           'S','D','L',0};
> 
> I think this should use RtlFormatCurrentUserKeyPath() rather than hardcoding it. But why do we need to use NT APIs here? Also, why are we storing this in a new key instead of in the existing key for the SDL driver?

The initial goal was to have AppDefaults be able to be used to have different mapping for different applications. However that would be impossible because at the layer that this runs we are in the winedevices service, also talking to others and thinking about it we should not need to have multiple mappings.

I will pull the setting back into the existing SDL device key. 

As for using the NT APIs here is just because this technically is driver level and those would be the approperate APIs. I know Alexandre does not really care and using the user level advapi entry points would fine but it feels more right to me. 

-aric


>  > +        static const UNICODE_STRING path = {sizeof(szPath) - sizeof(WCHAR), sizeof(szPath), (WCHAR*)szPath};
>  > +
>  > +        InitializeObjectAttributes(&attr, &path, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
>  > +        if (NtOpenKey(&key, KEY_ALL_ACCESS, &attr) == STATUS_SUCCESS)
>  > +        {
>  > +            ULONG index = 0;
>  > +            KEY_VALUE_PARTIAL_INFORMATION *info;
>  > +            DWORD length, result_len;
>  > +            NTSTATUS status;
>  > +
>  > +            length = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + (1000 * sizeof(WCHAR));
>  > +            info = HeapAlloc(GetProcessHeap(), 0, length);
>  > +
>  > +            do {
>  > +                status = NtEnumerateValueKey(key, index, KeyValuePartialInformation,
>  > +                                             info, length, &result_len);
>  > +                if (status == STATUS_SUCCESS)
>  > +                {
>  > +                    CHAR mapping[1000] = {0};
>  > +                    WideCharToMultiByte(CP_ACP, 0, info->Data,
>  > +                        (info->DataLength / sizeof(WCHAR)), mapping, sizeof(mapping),
>  > +                        NULL, NULL);
>  > +                    if (mapping[0] != 0)
>  > +                    {
>  > +                        TRACE("Setting mapping %s\n",debugstr_a(mapping));
>  > +                        pSDL_GameControllerAddMapping(mapping);
>  > +                    } else {
>  > +                        ERR("Failed to convert mapping %s\n",debugstr_w(info->Data));
>  > +                    }
>  > +                    index ++;
>  > +                }
>  > +            } while (status == STATUS_SUCCESS);
>  > +            HeapFree(GetProcessHeap(), 0, info);
>  > +            NtClose(key);
>  > +        }
>  > +    }
>  > +    else
>  > +    {
>  > +        ERR("Controller Mapping unsuported in this version of SDL\n");
>  > +    }
>  > +
>  >      SetEvent(init_done);
>  >
>  >      while (1)
>  > @@ -969,6 +1023,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);
> 
> 
> 



More information about the wine-devel mailing list