Aric Stewart : winebus.sys: Process SDL device reports.

Alexandre Julliard julliard at winehq.org
Wed Feb 21 18:39:41 CST 2018


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Wed Feb 21 06:56:46 2018 -0600

winebus.sys: Process SDL device reports.

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

---

 dlls/winebus.sys/bus_sdl.c    | 120 ++++++++++++++++++++++++++++++++++++++++++
 dlls/winebus.sys/bus_udev.c   |  19 +------
 dlls/winebus.sys/controller.h |  16 ++++++
 3 files changed, 137 insertions(+), 18 deletions(-)

diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 0091132..7318320 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -85,6 +85,8 @@ MAKE_FUNCPTR(SDL_WaitEvent);
 MAKE_FUNCPTR(SDL_JoystickNumButtons);
 MAKE_FUNCPTR(SDL_JoystickNumBalls);
 MAKE_FUNCPTR(SDL_JoystickNumHats);
+MAKE_FUNCPTR(SDL_JoystickGetAxis);
+MAKE_FUNCPTR(SDL_JoystickGetHat);
 #endif
 static Uint16 (*pSDL_JoystickGetProduct)(SDL_Joystick * joystick);
 static Uint16 (*pSDL_JoystickGetProductVersion)(SDL_Joystick * joystick);
@@ -101,6 +103,9 @@ struct platform_private
 
     int report_descriptor_size;
     BYTE *report_descriptor;
+
+    int buffer_length;
+    BYTE *report_buffer;
 };
 
 static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
@@ -146,6 +151,43 @@ static BYTE *add_axis_block(BYTE *report_ptr, BYTE count, BYTE page, const BYTE
     return report_ptr;
 }
 
+static void set_axis_value(struct platform_private *ext, int index, short value)
+{
+    int offset;
+    offset = ext->axis_start + index * 2;
+    *((WORD*)&ext->report_buffer[offset]) = LE_WORD(value);
+}
+
+static void set_ball_value(struct platform_private *ext, int index, int value1, int value2)
+{
+    int offset;
+    offset = ext->ball_start + (index * 2);
+    if (value1 > 127) value1 = 127;
+    if (value1 < -127) value1 = -127;
+    if (value2 > 127) value2 = 127;
+    if (value2 < -127) value2 = -127;
+    ext->report_buffer[offset] = value1;
+    ext->report_buffer[offset + 1] = value2;
+}
+
+static void set_hat_value(struct platform_private *ext, int index, int value)
+{
+    int offset;
+    offset = ext->hat_start + index;
+    switch (value)
+    {
+        case SDL_HAT_CENTERED: ext->report_buffer[offset] = 8; break;
+        case SDL_HAT_UP: ext->report_buffer[offset] = 0; break;
+        case SDL_HAT_RIGHTUP: ext->report_buffer[offset] = 1; break;
+        case SDL_HAT_RIGHT: ext->report_buffer[offset] = 2; break;
+        case SDL_HAT_RIGHTDOWN: ext->report_buffer[offset] = 3; break;
+        case SDL_HAT_DOWN: ext->report_buffer[offset] = 4; break;
+        case SDL_HAT_LEFTDOWN: ext->report_buffer[offset] = 5; break;
+        case SDL_HAT_LEFT: ext->report_buffer[offset] = 6; break;
+        case SDL_HAT_LEFTUP: ext->report_buffer[offset] = 7; break;
+    }
+}
+
 static BOOL build_report_descriptor(struct platform_private *ext)
 {
     BYTE *report_ptr;
@@ -269,6 +311,20 @@ static BOOL build_report_descriptor(struct platform_private *ext)
     memcpy(report_ptr, REPORT_TAIL, sizeof(REPORT_TAIL));
 
     ext->report_descriptor_size = descript_size;
+    ext->buffer_length = report_size;
+    ext->report_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, report_size);
+    if (ext->report_buffer == NULL)
+    {
+        ERR("Failed to alloc report buffer\n");
+        HeapFree(GetProcessHeap(), 0, ext->report_descriptor);
+        return FALSE;
+    }
+
+    /* Initialize axis in the report */
+    for (i = 0; i < axis_count; i++)
+        set_axis_value(ext, i, pSDL_JoystickGetAxis(ext->sdl_joystick, i));
+    for (i = 0; i < hat_count; i++)
+        set_hat_value(ext, i, pSDL_JoystickGetHat(ext->sdl_joystick, i));
 
     return TRUE;
 }
@@ -356,6 +412,66 @@ static const platform_vtbl sdl_vtbl =
     set_feature_report,
 };
 
+static BOOL set_report_from_event(SDL_Event *event)
+{
+    DEVICE_OBJECT *device;
+    struct platform_private *private;
+    /* All the events coming in will have 'which' as a 3rd field */
+    SDL_JoystickID index = ((SDL_JoyButtonEvent*)event)->which;
+
+    device = bus_find_hid_device(&sdl_vtbl, ULongToPtr(index));
+    if (!device)
+    {
+        ERR("Failed to find device at index %i\n",index);
+        return FALSE;
+    }
+    private = impl_from_DEVICE_OBJECT(device);
+
+    switch(event->type)
+    {
+        case SDL_JOYBUTTONDOWN:
+        case SDL_JOYBUTTONUP:
+        {
+            SDL_JoyButtonEvent *ie = &event->jbutton;
+
+            set_button_value(ie->button, ie->state, private->report_buffer);
+
+            process_hid_report(device, private->report_buffer, private->buffer_length);
+            break;
+        }
+        case SDL_JOYAXISMOTION:
+        {
+            SDL_JoyAxisEvent *ie = &event->jaxis;
+
+            if (ie->axis < 6)
+            {
+                set_axis_value(private, ie->axis, ie->value);
+                process_hid_report(device, private->report_buffer, private->buffer_length);
+            }
+            break;
+        }
+        case SDL_JOYBALLMOTION:
+        {
+            SDL_JoyBallEvent *ie = &event->jball;
+
+            set_ball_value(private, ie->ball, ie->xrel, ie->yrel);
+            process_hid_report(device, private->report_buffer, private->buffer_length);
+            break;
+        }
+        case SDL_JOYHATMOTION:
+        {
+            SDL_JoyHatEvent *ie = &event->jhat;
+
+            set_hat_value(private, ie->hat, ie->value);
+            process_hid_report(device, private->report_buffer, private->buffer_length);
+            break;
+        }
+        default:
+            ERR("TODO: Process Report (%x)\n",event->type);
+    }
+    return FALSE;
+}
+
 static void try_remove_device(SDL_JoystickID index)
 {
     DEVICE_OBJECT *device = NULL;
@@ -441,6 +557,8 @@ static void process_device_event(SDL_Event *event)
         try_add_device(((SDL_JoyDeviceEvent*)event)->which);
     else if (event->type == SDL_JOYDEVICEREMOVED)
         try_remove_device(((SDL_JoyDeviceEvent*)event)->which);
+    else if (event->type >= SDL_JOYAXISMOTION && event->type <= SDL_JOYBUTTONUP)
+        set_report_from_event(event);
 }
 
 static DWORD CALLBACK deviceloop_thread(void *args)
@@ -494,6 +612,8 @@ NTSTATUS WINAPI sdl_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_
         LOAD_FUNCPTR(SDL_JoystickNumButtons);
         LOAD_FUNCPTR(SDL_JoystickNumBalls);
         LOAD_FUNCPTR(SDL_JoystickNumHats);
+        LOAD_FUNCPTR(SDL_JoystickGetAxis);
+        LOAD_FUNCPTR(SDL_JoystickGetHat);
 #undef LOAD_FUNCPTR
         pSDL_JoystickGetProduct = wine_dlsym(sdl_handle, "SDL_JoystickGetProduct", NULL, 0);
         pSDL_JoystickGetProductVersion = wine_dlsym(sdl_handle, "SDL_JoystickGetProductVersion", NULL, 0);
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 9d78f19..417573f 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -271,23 +271,6 @@ static const BYTE* what_am_I(struct udev_device *dev)
     return Unknown;
 }
 
-static void set_button_value(struct wine_input_private *ext, int code, int value)
-{
-    int index = ext->button_map[code];
-    int bindex = index / 8;
-    int b = index % 8;
-    BYTE mask;
-
-    mask = 1<<b;
-    if (value)
-        ext->current_report_buffer[bindex] = ext->current_report_buffer[bindex] | mask;
-    else
-    {
-        mask = ~mask;
-        ext->current_report_buffer[bindex] = ext->current_report_buffer[bindex] & mask;
-    }
-}
-
 static void set_abs_axis_value(struct wine_input_private *ext, int code, int value)
 {
     int index;
@@ -608,7 +591,7 @@ static BOOL set_report_from_event(struct wine_input_private *ext, struct input_e
             return FALSE;
 #endif
         case EV_KEY:
-            set_button_value(ext, ie->code, ie->value);
+            set_button_value(ext->button_map[ie->code], ie->value, ext->current_report_buffer);
             return FALSE;
         case EV_ABS:
             set_abs_axis_value(ext, ie->code, ie->value);
diff --git a/dlls/winebus.sys/controller.h b/dlls/winebus.sys/controller.h
index a4fc36e..9546fe9 100644
--- a/dlls/winebus.sys/controller.h
+++ b/dlls/winebus.sys/controller.h
@@ -113,3 +113,19 @@ static inline BYTE *add_hatswitch(BYTE *report_ptr, INT count)
     report_ptr[IDX_HATSWITCH_COUNT] = count;
     return report_ptr + sizeof(REPORT_HATSWITCH);
 }
+
+static inline void set_button_value(int index, int value, BYTE* buffer)
+{
+    int bindex = index / 8;
+    int b = index % 8;
+    BYTE mask;
+
+    mask = 1<<b;
+    if (value)
+        buffer[bindex] = buffer[bindex] | mask;
+    else
+    {
+        mask = ~mask;
+        buffer[bindex] = buffer[bindex] & mask;
+    }
+}




More information about the wine-cvs mailing list