Support for SDL_HapticName in darwin. gsoc2008_force_feedback
authorEdgar Simo <bobbens@gmail.com>
Sat, 19 Jul 2008 17:05:30 +0000
branchgsoc2008_force_feedback
changeset 25378d92ec01f92f
parent 2536 fe3ee345a5d2
child 2538 1f9c20580ab4
Support for SDL_HapticName in darwin.
Fixed memleak.
src/haptic/darwin/SDL_syshaptic.c
     1.1 --- a/src/haptic/darwin/SDL_syshaptic.c	Sat Jul 19 16:06:43 2008 +0000
     1.2 +++ b/src/haptic/darwin/SDL_syshaptic.c	Sat Jul 19 17:05:30 2008 +0000
     1.3 @@ -43,6 +43,7 @@
     1.4   */
     1.5  static struct
     1.6  {
     1.7 +   char name[256];
     1.8     io_service_t dev;
     1.9     SDL_Haptic *haptic;
    1.10  } SDL_hapticlist[MAX_HAPTICS];
    1.11 @@ -69,7 +70,8 @@
    1.12  /*
    1.13   * Prototypes.
    1.14   */
    1.15 -static void SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect, int type );
    1.16 +static void SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type);
    1.17 +static int HIDGetDeviceProduct(io_service_t dev, char * name);
    1.18  
    1.19  
    1.20  /*
    1.21 @@ -84,6 +86,9 @@
    1.22     CFDictionaryRef match;
    1.23     io_service_t device;
    1.24  
    1.25 +   /* Clear all the memory. */
    1.26 +   SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist));
    1.27 +
    1.28     /* Get HID devices. */
    1.29     match = IOServiceMatching(kIOHIDDeviceKey);
    1.30     if (match == NULL) {
    1.31 @@ -104,10 +109,14 @@
    1.32  
    1.33        /* Check for force feedback. */
    1.34        if (FFIsForceFeedback(device) == FF_OK) {
    1.35 +         HIDGetDeviceProduct(device, SDL_hapticlist[numhaptics].name);
    1.36           SDL_hapticlist[numhaptics].dev = device;
    1.37           SDL_hapticlist[numhaptics].haptic = NULL;
    1.38           numhaptics++;
    1.39        }
    1.40 +      else { /* Free the unused device. */
    1.41 +         IOObjectRelease(device);
    1.42 +      }
    1.43  
    1.44        /* Reached haptic limit. */
    1.45        if (numhaptics >= MAX_HAPTICS)
    1.46 @@ -125,7 +134,68 @@
    1.47  const char *
    1.48  SDL_SYS_HapticName(int index)
    1.49  {
    1.50 -   return NULL;
    1.51 +   return SDL_hapticlist[index].name;
    1.52 +}
    1.53 +
    1.54 +/*
    1.55 + * Gets the device's product name.
    1.56 + */
    1.57 +static int
    1.58 +HIDGetDeviceProduct(io_service_t dev, char *name)
    1.59 +{
    1.60 +   CFMutableDictionaryRef hidProperties, usbProperties;
    1.61 +   io_registry_entry_t parent1, parent2;
    1.62 +
    1.63 +   hidProperties = usbProperties = 0;
    1.64 +
    1.65 +   /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
    1.66 +    * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
    1.67 +    */
    1.68 +   if ((KERN_SUCCESS ==
    1.69 +            IORegistryEntryGetParentEntry(dev, kIOServicePlane, &parent1))
    1.70 +         && (KERN_SUCCESS ==
    1.71 +            IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
    1.72 +         && (KERN_SUCCESS ==
    1.73 +            IORegistryEntryCreateCFProperties(parent2, &usbProperties,
    1.74 +               kCFAllocatorDefault,
    1.75 +               kNilOptions))) {
    1.76 +      if (usbProperties) {
    1.77 +         CFTypeRef refCF = 0;
    1.78 +         /* get device info
    1.79 +          * try hid dictionary first, if fail then go to usb dictionary
    1.80 +          */
    1.81 +
    1.82 +
    1.83 +         /* Get product name */
    1.84 +         refCF =
    1.85 +            CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
    1.86 +         if (!refCF)
    1.87 +            refCF =
    1.88 +               CFDictionaryGetValue(usbProperties, CFSTR("USB Product Name"));
    1.89 +         if (refCF) {
    1.90 +            if (!CFStringGetCString(refCF, name, 256,
    1.91 +                                    CFStringGetSystemEncoding())) {
    1.92 +               SDL_SetError("CFStringGetCString error retrieving pDevice->product.");
    1.93 +               return -1;
    1.94 +            }
    1.95 +         }
    1.96 +
    1.97 +         CFRelease(usbProperties);
    1.98 +      }
    1.99 +      else {
   1.100 +         SDL_SetError("IORegistryEntryCreateCFProperties failed to create usbProperties.");
   1.101 +         return -1;
   1.102 +      }
   1.103 +
   1.104 +      /* Release stuff. */
   1.105 +      if (kIOReturnSuccess != IOObjectRelease(parent2)) {
   1.106 +         SDL_SetError("IOObjectRelease error with parent2.");
   1.107 +      }
   1.108 +      if (kIOReturnSuccess != IOObjectRelease(parent1))  {
   1.109 +         SDL_SetError("IOObjectRelease error with parent1.");
   1.110 +      }
   1.111 +   }
   1.112 +   return 0;
   1.113  }
   1.114  
   1.115