From 9c0c0e2b57e0a5e27a1e0a8d1d2ca4660a0e4a86 Mon Sep 17 00:00:00 2001 From: Brendan Shanks Date: Mon, 23 Nov 2020 16:48:44 -0800 Subject: [PATCH] winebus.sys: Open IOHID devices individually to fix macOS Catalina and Big Sur. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50153 Signed-off-by: Brendan Shanks Signed-off-by: Alexandre Julliard --- dlls/winebus.sys/bus_iohid.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index df578b4b9d6..ee6225bf398 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -297,6 +297,13 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void * if (str) CFStringToWSTR(str, serial_string, ARRAY_SIZE(serial_string)); uid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDLocationIDKey))); + if (IOHIDDeviceOpen(IOHIDDevice, 0) != kIOReturnSuccess) + { + ERR("Failed to open HID device %p (vid %04x, pid %04x)\n", IOHIDDevice, vid, pid); + return; + } + IOHIDDeviceScheduleWithRunLoop(IOHIDDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + if (IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad) || IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) { @@ -365,6 +372,8 @@ static void handle_RemovalCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRegisterInputReportCallback(IOHIDDevice, NULL, 0, NULL, NULL); /* Note: Yes, we leak the buffer. But according to research there is no safe way to deallocate that buffer. */ + IOHIDDeviceUnscheduleFromRunLoop(IOHIDDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + IOHIDDeviceClose(IOHIDDevice, 0); device = bus_find_hid_device(&iohid_vtbl, IOHIDDevice); if (device) { @@ -383,13 +392,6 @@ static DWORD CALLBACK runloop_thread(void *args) IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, handle_DeviceMatchingCallback, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, handle_RemovalCallback, NULL); IOHIDManagerScheduleWithRunLoop(hid_manager, run_loop, kCFRunLoopDefaultMode); - if (IOHIDManagerOpen( hid_manager, 0 ) != kIOReturnSuccess) - { - ERR("Couldn't open IOHIDManager.\n"); - IOHIDManagerUnscheduleFromRunLoop(hid_manager, run_loop, kCFRunLoopDefaultMode); - CFRelease(hid_manager); - return 0; - } CFRunLoopRun(); TRACE("Run Loop exiting\n");