src/joystick/darwin/SDL_sysjoystick.c
changeset 9629 9242a9b29c7d
parent 9619 b94b6d0bff0f
child 9632 6ae6b0b46e78
equal deleted inserted replaced
9628:065e4ddc8753 9629:9242a9b29c7d
    44 static IOHIDManagerRef hidman = NULL;
    44 static IOHIDManagerRef hidman = NULL;
    45 
    45 
    46 /* Linked list of all available devices */
    46 /* Linked list of all available devices */
    47 static recDevice *gpDeviceList = NULL;
    47 static recDevice *gpDeviceList = NULL;
    48 
    48 
    49 /* if SDL_TRUE then a device was added since the last update call */
       
    50 static SDL_bool s_bDeviceAdded = SDL_FALSE;
       
    51 static SDL_bool s_bDeviceRemoved = SDL_FALSE;
       
    52 
       
    53 /* static incrementing counter for new joystick devices seen on the system. Devices should start with index 0 */
    49 /* static incrementing counter for new joystick devices seen on the system. Devices should start with index 0 */
    54 static int s_joystick_instance_id = -1;
    50 static int s_joystick_instance_id = -1;
    55 
    51 
       
    52 static recDevice *GetDeviceForIndex(int device_index)
       
    53 {
       
    54     recDevice *device = gpDeviceList;
       
    55     while (device) {
       
    56         if (!device->removed) {
       
    57             if (device_index == 0)
       
    58                 break;
       
    59 
       
    60             --device_index;
       
    61         }
       
    62         device = device->pNext;
       
    63     }
       
    64     return device;
       
    65 }
    56 
    66 
    57 static void
    67 static void
    58 FreeElementList(recElement *pElement)
    68 FreeElementList(recElement *pElement)
    59 {
    69 {
    60     while (pElement) {
    70     while (pElement) {
   141     device->removed = SDL_TRUE;
   151     device->removed = SDL_TRUE;
   142     device->deviceRef = NULL; // deviceRef was invalidated due to the remove
   152     device->deviceRef = NULL; // deviceRef was invalidated due to the remove
   143 #if SDL_HAPTIC_IOKIT
   153 #if SDL_HAPTIC_IOKIT
   144     MacHaptic_MaybeRemoveDevice(device->ffservice);
   154     MacHaptic_MaybeRemoveDevice(device->ffservice);
   145 #endif
   155 #endif
   146     s_bDeviceRemoved = SDL_TRUE;
   156 
       
   157 /* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceRemoved()? */
       
   158 #if !SDL_EVENTS_DISABLED
       
   159     {
       
   160         SDL_Event event;
       
   161         event.type = SDL_JOYDEVICEREMOVED;
       
   162 
       
   163         if (SDL_GetEventState(event.type) == SDL_ENABLE) {
       
   164             event.jdevice.which = device->instance_id;
       
   165             if ((SDL_EventOK == NULL)
       
   166                 || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
       
   167                 SDL_PushEvent(&event);
       
   168             }
       
   169         }
       
   170     }
       
   171 #endif /* !SDL_EVENTS_DISABLED */
   147 }
   172 }
   148 
   173 
   149 
   174 
   150 static void AddHIDElement(const void *value, void *parameter);
   175 static void AddHIDElement(const void *value, void *parameter);
   151 
   176 
   379 
   404 
   380 static void
   405 static void
   381 JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject)
   406 JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject)
   382 {
   407 {
   383     recDevice *device;
   408     recDevice *device;
       
   409     int device_index = 0;
   384 
   410 
   385     if (res != kIOReturnSuccess) {
   411     if (res != kIOReturnSuccess) {
   386         return;
   412         return;
   387     }
   413     }
   388 
   414 
   418             MacHaptic_MaybeAddDevice(ioservice);
   444             MacHaptic_MaybeAddDevice(ioservice);
   419         }
   445         }
   420 #endif
   446 #endif
   421     }
   447     }
   422 
   448 
   423     device->send_open_event = 1;
       
   424     s_bDeviceAdded = SDL_TRUE;
       
   425 
       
   426     /* Add device to the end of the list */
   449     /* Add device to the end of the list */
   427     if ( !gpDeviceList ) {
   450     if ( !gpDeviceList ) {
   428         gpDeviceList = device;
   451         gpDeviceList = device;
   429     } else {
   452     } else {
   430         recDevice *curdevice;
   453         recDevice *curdevice;
   431 
   454 
   432         curdevice = gpDeviceList;
   455         curdevice = gpDeviceList;
   433         while ( curdevice->pNext ) {
   456         while ( curdevice->pNext ) {
       
   457             ++device_index;
   434             curdevice = curdevice->pNext;
   458             curdevice = curdevice->pNext;
   435         }
   459         }
   436         curdevice->pNext = device;
   460         curdevice->pNext = device;
   437     }
   461     }
       
   462 
       
   463 /* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceAdded()? */
       
   464 #if !SDL_EVENTS_DISABLED
       
   465     {
       
   466         SDL_Event event;
       
   467         event.type = SDL_JOYDEVICEADDED;
       
   468 
       
   469         if (SDL_GetEventState(event.type) == SDL_ENABLE) {
       
   470             event.jdevice.which = device_index;
       
   471             if ((SDL_EventOK == NULL)
       
   472                 || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
       
   473                 SDL_PushEvent(&event);
       
   474             }
       
   475         }
       
   476     }
       
   477 #endif /* !SDL_EVENTS_DISABLED */
   438 }
   478 }
   439 
   479 
   440 static SDL_bool
   480 static SDL_bool
   441 ConfigHIDManager(CFArrayRef matchingArray)
   481 ConfigHIDManager(CFArrayRef matchingArray)
   442 {
   482 {
   558 /* Function to cause any queued joystick insertions to be processed
   598 /* Function to cause any queued joystick insertions to be processed
   559  */
   599  */
   560 void
   600 void
   561 SDL_SYS_JoystickDetect()
   601 SDL_SYS_JoystickDetect()
   562 {
   602 {
   563     if (s_bDeviceAdded || s_bDeviceRemoved) {
   603     recDevice *device = gpDeviceList;
   564         recDevice *device = gpDeviceList;
   604     while (device) {
   565         s_bDeviceAdded = SDL_FALSE;
   605         if (device->removed) {
   566         s_bDeviceRemoved = SDL_FALSE;
   606             device = FreeDevice(device);
   567         int device_index = 0;
   607         } else {
   568         /* send notifications */
   608             device = device->pNext;
   569         while (device) {
       
   570             if (device->send_open_event) {
       
   571                 device->send_open_event = 0;
       
   572 /* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceAdded()? */
       
   573 #if !SDL_EVENTS_DISABLED
       
   574                 SDL_Event event;
       
   575                 event.type = SDL_JOYDEVICEADDED;
       
   576 
       
   577                 if (SDL_GetEventState(event.type) == SDL_ENABLE) {
       
   578                     event.jdevice.which = device_index;
       
   579                     if ((SDL_EventOK == NULL)
       
   580                         || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
       
   581                         SDL_PushEvent(&event);
       
   582                     }
       
   583                 }
       
   584 #endif /* !SDL_EVENTS_DISABLED */
       
   585 
       
   586             }
       
   587 
       
   588             if (device->removed) {
       
   589                 const int instance_id = device->instance_id;
       
   590                 device = FreeDevice(device);
       
   591 
       
   592 /* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceRemoved()? */
       
   593 #if !SDL_EVENTS_DISABLED
       
   594                 SDL_Event event;
       
   595                 event.type = SDL_JOYDEVICEREMOVED;
       
   596 
       
   597                 if (SDL_GetEventState(event.type) == SDL_ENABLE) {
       
   598                     event.jdevice.which = instance_id;
       
   599                     if ((SDL_EventOK == NULL)
       
   600                         || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
       
   601                         SDL_PushEvent(&event);
       
   602                     }
       
   603                 }
       
   604 #endif /* !SDL_EVENTS_DISABLED */
       
   605 
       
   606             } else {
       
   607                 device = device->pNext;
       
   608                 device_index++;
       
   609             }
       
   610         }
   609         }
   611     }
   610     }
   612 
   611 
   613 	// run this after the checks above so we don't set device->removed and delete the device before
   612 	// run this after the checks above so we don't set device->removed and delete the device before
   614 	// SDL_SYS_JoystickUpdate can run to clean up the SDL_Joystick object that owns this device
   613 	// SDL_SYS_JoystickUpdate can run to clean up the SDL_Joystick object that owns this device
   619 
   618 
   620 /* Function to get the device-dependent name of a joystick */
   619 /* Function to get the device-dependent name of a joystick */
   621 const char *
   620 const char *
   622 SDL_SYS_JoystickNameForDeviceIndex(int device_index)
   621 SDL_SYS_JoystickNameForDeviceIndex(int device_index)
   623 {
   622 {
   624     recDevice *device = gpDeviceList;
   623     recDevice *device = GetDeviceForIndex(device_index);
   625 
   624     return device ? device->product : "UNKNOWN";
   626     while (device_index-- > 0) {
       
   627         device = device->pNext;
       
   628     }
       
   629 
       
   630     return device->product;
       
   631 }
   625 }
   632 
   626 
   633 /* Function to return the instance id of the joystick at device_index
   627 /* Function to return the instance id of the joystick at device_index
   634  */
   628  */
   635 SDL_JoystickID
   629 SDL_JoystickID
   636 SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
   630 SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
   637 {
   631 {
   638     recDevice *device = gpDeviceList;
   632     recDevice *device = GetDeviceForIndex(device_index);
   639     int index;
   633     return device ? device->instance_id : 0;
   640 
       
   641     for (index = device_index; index > 0; index--) {
       
   642         device = device->pNext;
       
   643     }
       
   644 
       
   645     return device->instance_id;
       
   646 }
   634 }
   647 
   635 
   648 /* Function to open a joystick for use.
   636 /* Function to open a joystick for use.
   649  * The joystick to open is specified by the device index.
   637  * The joystick to open is specified by the device index.
   650  * This should fill the nbuttons and naxes fields of the joystick structure.
   638  * This should fill the nbuttons and naxes fields of the joystick structure.
   651  * It returns 0, or -1 if there is an error.
   639  * It returns 0, or -1 if there is an error.
   652  */
   640  */
   653 int
   641 int
   654 SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
   642 SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
   655 {
   643 {
   656     recDevice *device = gpDeviceList;
   644     recDevice *device = GetDeviceForIndex(device_index);
   657     int index;
       
   658 
       
   659     for (index = device_index; index > 0; index--) {
       
   660         device = device->pNext;
       
   661     }
       
   662 
   645 
   663     joystick->instance_id = device->instance_id;
   646     joystick->instance_id = device->instance_id;
   664     joystick->hwdata = device;
   647     joystick->hwdata = device;
   665     joystick->name = device->product;
   648     joystick->name = device->product;
   666 
   649 
   803         IOHIDManagerUnscheduleFromRunLoop(hidman, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE);
   786         IOHIDManagerUnscheduleFromRunLoop(hidman, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE);
   804         IOHIDManagerClose(hidman, kIOHIDOptionsTypeNone);
   787         IOHIDManagerClose(hidman, kIOHIDOptionsTypeNone);
   805         CFRelease(hidman);
   788         CFRelease(hidman);
   806         hidman = NULL;
   789         hidman = NULL;
   807     }
   790     }
   808 
       
   809     s_bDeviceAdded = s_bDeviceRemoved = SDL_FALSE;
       
   810 }
   791 }
   811 
   792 
   812 
   793 
   813 SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   794 SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   814 {
   795 {
   815     recDevice *device = gpDeviceList;
   796     recDevice *device = GetDeviceForIndex(device_index);
   816     int index;
   797     SDL_JoystickGUID guid;
   817 
   798     if (device) {
   818     for (index = device_index; index > 0; index--) {
   799         guid = device->guid;
   819         device = device->pNext;
   800     } else {
   820     }
   801         SDL_zero(guid);
   821 
   802     }
   822     return device->guid;
   803     return guid;
   823 }
   804 }
   824 
   805 
   825 SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
   806 SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
   826 {
   807 {
   827     return joystick->hwdata->guid;
   808     return joystick->hwdata->guid;