winebus.sys: Return an event from SDL bus wait on device removal.
Instead of calling bus_unlink_hid_device or IoInvalidateDeviceRelations. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f6d567d3e3
commit
6006758ca8
|
@ -64,6 +64,7 @@ static struct sdl_bus_options options;
|
|||
|
||||
static void *sdl_handle = NULL;
|
||||
static UINT quit_event = -1;
|
||||
static struct list event_queue = LIST_INIT(event_queue);
|
||||
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
|
||||
MAKE_FUNCPTR(SDL_GetError);
|
||||
|
@ -730,12 +731,6 @@ static BOOL set_mapped_report_from_event(DEVICE_OBJECT *device, SDL_Event *event
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void try_remove_device(DEVICE_OBJECT *device)
|
||||
{
|
||||
bus_unlink_hid_device(device);
|
||||
IoInvalidateDeviceRelations(bus_pdo, BusRelations);
|
||||
}
|
||||
|
||||
static void try_add_device(unsigned int index)
|
||||
{
|
||||
DWORD vid = 0, pid = 0, version = 0;
|
||||
|
@ -821,9 +816,7 @@ static void process_device_event(SDL_Event *event)
|
|||
else if (event->type == SDL_JOYDEVICEREMOVED)
|
||||
{
|
||||
id = ((SDL_JoyDeviceEvent *)event)->which;
|
||||
device = bus_find_hid_device(sdl_busidW, ULongToPtr(id));
|
||||
if (device) try_remove_device(device);
|
||||
else WARN("failed to find device with id %d\n", id);
|
||||
bus_event_queue_device_removed(&event_queue, sdl_busidW, ULongToPtr(id));
|
||||
}
|
||||
else if (event->type >= SDL_JOYAXISMOTION && event->type <= SDL_JOYBUTTONUP)
|
||||
{
|
||||
|
@ -980,15 +973,18 @@ failed:
|
|||
|
||||
NTSTATUS sdl_bus_wait(void *args)
|
||||
{
|
||||
struct bus_event *result = args;
|
||||
SDL_Event event;
|
||||
|
||||
do
|
||||
{
|
||||
if (bus_event_queue_pop(&event_queue, result)) return STATUS_PENDING;
|
||||
if (pSDL_WaitEvent(&event) != 0) process_device_event(&event);
|
||||
else WARN("SDL_WaitEvent failed: %s\n", pSDL_GetError());
|
||||
} while (event.type != quit_event);
|
||||
|
||||
TRACE("SDL main loop exiting\n");
|
||||
bus_event_queue_destroy(&event_queue);
|
||||
dlclose(sdl_handle);
|
||||
sdl_handle = NULL;
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -654,6 +654,7 @@ struct bus_main_params
|
|||
static DWORD CALLBACK bus_main_thread(void *args)
|
||||
{
|
||||
struct bus_main_params bus = *(struct bus_main_params *)args;
|
||||
DEVICE_OBJECT *device;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE("%s main loop starting\n", debugstr_w(bus.name));
|
||||
|
@ -663,7 +664,24 @@ static DWORD CALLBACK bus_main_thread(void *args)
|
|||
|
||||
bus.bus_event->type = BUS_EVENT_TYPE_NONE;
|
||||
if (status) WARN("%s bus init returned status %#x\n", debugstr_w(bus.name), status);
|
||||
else while ((status = winebus_call(bus.wait_code, bus.bus_event)) == STATUS_PENDING) {}
|
||||
else while ((status = winebus_call(bus.wait_code, bus.bus_event)) == STATUS_PENDING)
|
||||
{
|
||||
struct bus_event *event = bus.bus_event;
|
||||
switch (event->type)
|
||||
{
|
||||
case BUS_EVENT_TYPE_NONE: break;
|
||||
case BUS_EVENT_TYPE_DEVICE_REMOVED:
|
||||
EnterCriticalSection(&device_list_cs);
|
||||
if (!(device = bus_find_hid_device(event->device_removed.bus_id, event->device_removed.context)))
|
||||
WARN("could not find removed device matching bus %s, context %p\n",
|
||||
debugstr_w(event->device_removed.bus_id), event->device_removed.context);
|
||||
else
|
||||
bus_unlink_hid_device(device);
|
||||
LeaveCriticalSection(&device_list_cs);
|
||||
IoInvalidateDeviceRelations(bus_pdo, BusRelations);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status) WARN("%s bus wait returned status %#x\n", debugstr_w(bus.name), status);
|
||||
else TRACE("%s main loop exited\n", debugstr_w(bus.name));
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include "unixlib.h"
|
||||
|
||||
#include "wine/list.h"
|
||||
|
||||
struct unix_device
|
||||
{
|
||||
};
|
||||
|
@ -43,4 +45,8 @@ extern NTSTATUS iohid_bus_init(void *) DECLSPEC_HIDDEN;
|
|||
extern NTSTATUS iohid_bus_wait(void *) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS iohid_bus_stop(void *) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void bus_event_queue_destroy(struct list *queue) DECLSPEC_HIDDEN;
|
||||
extern BOOL bus_event_queue_device_removed(struct list *queue, const WCHAR *bus_id, void *context) DECLSPEC_HIDDEN;
|
||||
extern BOOL bus_event_queue_pop(struct list *queue, struct bus_event *event) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINEBUS_UNIX_PRIVATE_H */
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "winternl.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/unixlib.h"
|
||||
|
||||
#include "unix_private.h"
|
||||
|
@ -42,3 +43,41 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
|
|||
iohid_bus_wait,
|
||||
iohid_bus_stop,
|
||||
};
|
||||
|
||||
void bus_event_queue_destroy(struct list *queue)
|
||||
{
|
||||
struct bus_event *event, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(event, next, queue, struct bus_event, entry)
|
||||
HeapFree(GetProcessHeap(), 0, event);
|
||||
}
|
||||
|
||||
BOOL bus_event_queue_device_removed(struct list *queue, const WCHAR *bus_id, void *context)
|
||||
{
|
||||
ULONG size = sizeof(struct bus_event);
|
||||
struct bus_event *event = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
if (!event) return FALSE;
|
||||
|
||||
event->type = BUS_EVENT_TYPE_DEVICE_REMOVED;
|
||||
event->device_removed.bus_id = bus_id;
|
||||
event->device_removed.context = context;
|
||||
list_add_tail(queue, &event->entry);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL bus_event_queue_pop(struct list *queue, struct bus_event *event)
|
||||
{
|
||||
struct list *entry = list_head(queue);
|
||||
struct bus_event *tmp;
|
||||
|
||||
if (!entry) return FALSE;
|
||||
|
||||
tmp = LIST_ENTRY(entry, struct bus_event, entry);
|
||||
list_remove(entry);
|
||||
|
||||
memcpy(event, tmp, sizeof(*event));
|
||||
HeapFree(GetProcessHeap(), 0, tmp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <ddk/wdm.h>
|
||||
#include <hidusage.h>
|
||||
|
||||
#include "wine/list.h"
|
||||
#include "wine/unixlib.h"
|
||||
|
||||
struct sdl_bus_options
|
||||
|
@ -49,11 +50,22 @@ struct unix_device;
|
|||
enum bus_event_type
|
||||
{
|
||||
BUS_EVENT_TYPE_NONE,
|
||||
BUS_EVENT_TYPE_DEVICE_REMOVED,
|
||||
};
|
||||
|
||||
struct bus_event
|
||||
{
|
||||
enum bus_event_type type;
|
||||
struct list entry;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
const WCHAR *bus_id;
|
||||
void *context;
|
||||
} device_removed;
|
||||
};
|
||||
};
|
||||
|
||||
enum unix_funcs
|
||||
|
|
Loading…
Reference in New Issue