Mercurial > sdl-ios-xcode
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 |