comparison src/haptic/darwin/SDL_syshaptic.c @ 2537:8d92ec01f92f gsoc2008_force_feedback

Support for SDL_HapticName in darwin. Fixed memleak.
author Edgar Simo <bobbens@gmail.com>
date Sat, 19 Jul 2008 17:05:30 +0000
parents f0ed8471497d
children 1f9c20580ab4
comparison
equal deleted inserted replaced
2536:fe3ee345a5d2 2537:8d92ec01f92f
41 /* 41 /*
42 * List of available haptic devices. 42 * List of available haptic devices.
43 */ 43 */
44 static struct 44 static struct
45 { 45 {
46 char name[256];
46 io_service_t dev; 47 io_service_t dev;
47 SDL_Haptic *haptic; 48 SDL_Haptic *haptic;
48 } SDL_hapticlist[MAX_HAPTICS]; 49 } SDL_hapticlist[MAX_HAPTICS];
49 50
50 51
67 }; 68 };
68 69
69 /* 70 /*
70 * Prototypes. 71 * Prototypes.
71 */ 72 */
72 static void SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect, int type ); 73 static void SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type);
74 static int HIDGetDeviceProduct(io_service_t dev, char * name);
73 75
74 76
75 /* 77 /*
76 * Initializes the haptic subsystem. 78 * Initializes the haptic subsystem.
77 */ 79 */
82 IOReturn result; 84 IOReturn result;
83 io_iterator_t iter; 85 io_iterator_t iter;
84 CFDictionaryRef match; 86 CFDictionaryRef match;
85 io_service_t device; 87 io_service_t device;
86 88
89 /* Clear all the memory. */
90 SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist));
91
87 /* Get HID devices. */ 92 /* Get HID devices. */
88 match = IOServiceMatching(kIOHIDDeviceKey); 93 match = IOServiceMatching(kIOHIDDeviceKey);
89 if (match == NULL) { 94 if (match == NULL) {
90 SDL_SetError("Haptic: Failed to get IOServiceMatching."); 95 SDL_SetError("Haptic: Failed to get IOServiceMatching.");
91 return -1; 96 return -1;
102 numhaptics = 0; 107 numhaptics = 0;
103 while ((device = IOIteratorNext(iter)) != IO_OBJECT_NULL) { 108 while ((device = IOIteratorNext(iter)) != IO_OBJECT_NULL) {
104 109
105 /* Check for force feedback. */ 110 /* Check for force feedback. */
106 if (FFIsForceFeedback(device) == FF_OK) { 111 if (FFIsForceFeedback(device) == FF_OK) {
112 HIDGetDeviceProduct(device, SDL_hapticlist[numhaptics].name);
107 SDL_hapticlist[numhaptics].dev = device; 113 SDL_hapticlist[numhaptics].dev = device;
108 SDL_hapticlist[numhaptics].haptic = NULL; 114 SDL_hapticlist[numhaptics].haptic = NULL;
109 numhaptics++; 115 numhaptics++;
110 } 116 }
117 else { /* Free the unused device. */
118 IOObjectRelease(device);
119 }
111 120
112 /* Reached haptic limit. */ 121 /* Reached haptic limit. */
113 if (numhaptics >= MAX_HAPTICS) 122 if (numhaptics >= MAX_HAPTICS)
114 break; 123 break;
115 } 124 }
123 * Return the name of a haptic device, does not need to be opened. 132 * Return the name of a haptic device, does not need to be opened.
124 */ 133 */
125 const char * 134 const char *
126 SDL_SYS_HapticName(int index) 135 SDL_SYS_HapticName(int index)
127 { 136 {
128 return NULL; 137 return SDL_hapticlist[index].name;
138 }
139
140 /*
141 * Gets the device's product name.
142 */
143 static int
144 HIDGetDeviceProduct(io_service_t dev, char *name)
145 {
146 CFMutableDictionaryRef hidProperties, usbProperties;
147 io_registry_entry_t parent1, parent2;
148
149 hidProperties = usbProperties = 0;
150
151 /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
152 * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
153 */
154 if ((KERN_SUCCESS ==
155 IORegistryEntryGetParentEntry(dev, kIOServicePlane, &parent1))
156 && (KERN_SUCCESS ==
157 IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
158 && (KERN_SUCCESS ==
159 IORegistryEntryCreateCFProperties(parent2, &usbProperties,
160 kCFAllocatorDefault,
161 kNilOptions))) {
162 if (usbProperties) {
163 CFTypeRef refCF = 0;
164 /* get device info
165 * try hid dictionary first, if fail then go to usb dictionary
166 */
167
168
169 /* Get product name */
170 refCF =
171 CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
172 if (!refCF)
173 refCF =
174 CFDictionaryGetValue(usbProperties, CFSTR("USB Product Name"));
175 if (refCF) {
176 if (!CFStringGetCString(refCF, name, 256,
177 CFStringGetSystemEncoding())) {
178 SDL_SetError("CFStringGetCString error retrieving pDevice->product.");
179 return -1;
180 }
181 }
182
183 CFRelease(usbProperties);
184 }
185 else {
186 SDL_SetError("IORegistryEntryCreateCFProperties failed to create usbProperties.");
187 return -1;
188 }
189
190 /* Release stuff. */
191 if (kIOReturnSuccess != IOObjectRelease(parent2)) {
192 SDL_SetError("IOObjectRelease error with parent2.");
193 }
194 if (kIOReturnSuccess != IOObjectRelease(parent1)) {
195 SDL_SetError("IOObjectRelease error with parent1.");
196 }
197 }
198 return 0;
129 } 199 }
130 200
131 201
132 #define FF_TEST(ff, s) \ 202 #define FF_TEST(ff, s) \
133 if (features.supportedEffects & ff) supported |= s 203 if (features.supportedEffects & ff) supported |= s