|
38 | 38 | #include "../../events/SDL_events_c.h"
|
39 | 39 | #endif
|
40 | 40 |
|
| 41 | +#define SDL_JOYSTICK_RUNLOOP_MODE CFSTR("SDLJoystick") |
| 42 | + |
41 | 43 | /* The base object of the HID Manager API */
|
42 | 44 | static IOHIDManagerRef hidman = NULL;
|
43 | 45 |
|
@@ -67,6 +69,11 @@ FreeDevice(recDevice *removeDevice)
|
67 | 69 | {
|
68 | 70 | recDevice *pDeviceNext = NULL;
|
69 | 71 | if (removeDevice) {
|
| 72 | + if (removeDevice->deviceRef) { |
| 73 | + IOHIDDeviceUnscheduleFromRunLoop(removeDevice->deviceRef, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE); |
| 74 | + removeDevice->deviceRef = NULL; |
| 75 | + } |
| 76 | + |
70 | 77 | /* save next device prior to disposing of this device */
|
71 | 78 | pDeviceNext = removeDevice->pNext;
|
72 | 79 |
|
@@ -378,7 +385,7 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic
|
378 | 385 |
|
379 | 386 | /* Get notified when this device is disconnected. */
|
380 | 387 | IOHIDDeviceRegisterRemovalCallback(ioHIDDeviceObject, JoystickDeviceWasRemovedCallback, device);
|
381 |
| - IOHIDDeviceScheduleWithRunLoop(ioHIDDeviceObject, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); |
| 388 | + IOHIDDeviceScheduleWithRunLoop(ioHIDDeviceObject, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE); |
382 | 389 |
|
383 | 390 | /* Allocate an instance ID for this device */
|
384 | 391 | device->instance_id = ++s_joystick_instance_id;
|
@@ -420,25 +427,19 @@ ConfigHIDManager(CFArrayRef matchingArray)
|
420 | 427 | {
|
421 | 428 | CFRunLoopRef runloop = CFRunLoopGetCurrent();
|
422 | 429 |
|
423 |
| - /* Run in a custom RunLoop mode just while initializing, |
424 |
| - so we can detect sticks without messing with everything else. */ |
425 |
| - CFStringRef tempRunLoopMode = CFSTR("SDLJoystickInit"); |
426 |
| - |
427 | 430 | if (IOHIDManagerOpen(hidman, kIOHIDOptionsTypeNone) != kIOReturnSuccess) {
|
428 | 431 | return SDL_FALSE;
|
429 | 432 | }
|
430 | 433 |
|
431 | 434 | IOHIDManagerRegisterDeviceMatchingCallback(hidman, JoystickDeviceWasAddedCallback, NULL);
|
432 |
| - IOHIDManagerScheduleWithRunLoop(hidman, runloop, tempRunLoopMode); |
| 435 | + IOHIDManagerScheduleWithRunLoop(hidman, runloop, SDL_JOYSTICK_RUNLOOP_MODE); |
433 | 436 | IOHIDManagerSetDeviceMatchingMultiple(hidman, matchingArray);
|
434 | 437 |
|
435 |
| - while (CFRunLoopRunInMode(tempRunLoopMode,0,TRUE)==kCFRunLoopRunHandledSource) { |
| 438 | + while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) { |
436 | 439 | /* no-op. Callback fires once per existing device. */
|
437 | 440 | }
|
438 | 441 |
|
439 |
| - /* Put this in the normal RunLoop mode now, for future hotplug events. */ |
440 |
| - IOHIDManagerUnscheduleFromRunLoop(hidman, runloop, tempRunLoopMode); |
441 |
| - IOHIDManagerScheduleWithRunLoop(hidman, runloop, kCFRunLoopDefaultMode); |
| 442 | + /* future hotplug events will come through SDL_JOYSTICK_RUNLOOP_MODE now. */ |
442 | 443 |
|
443 | 444 | return SDL_TRUE; /* good to go. */
|
444 | 445 | }
|
@@ -544,6 +545,10 @@ SDL_SYS_NumJoysticks()
|
544 | 545 | void
|
545 | 546 | SDL_SYS_JoystickDetect()
|
546 | 547 | {
|
| 548 | + while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) { |
| 549 | + /* no-op. Pending callbacks will fire in CFRunLoopRunInMode(). */ |
| 550 | + } |
| 551 | + |
547 | 552 | if (s_bDeviceAdded || s_bDeviceRemoved) {
|
548 | 553 | recDevice *device = gpDeviceList;
|
549 | 554 | s_bDeviceAdded = SDL_FALSE;
|
@@ -793,6 +798,7 @@ SDL_SYS_JoystickQuit(void)
|
793 | 798 | }
|
794 | 799 |
|
795 | 800 | if (hidman) {
|
| 801 | + IOHIDManagerUnscheduleFromRunLoop(hidman, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE); |
796 | 802 | IOHIDManagerClose(hidman, kIOHIDOptionsTypeNone);
|
797 | 803 | CFRelease(hidman);
|
798 | 804 | hidman = NULL;
|
|
0 commit comments