Mercurial > sdl-ios-xcode
comparison src/haptic/linux/SDL_syshaptic.c @ 2524:1a55848ce198 gsoc2008_force_feedback
Better handling of opening haptics from joysticks.
Fixed segfault when opening from joystick.
author | Edgar Simo <bobbens@gmail.com> |
---|---|
date | Thu, 17 Jul 2008 16:07:20 +0000 |
parents | 366d84fdf8d1 |
children | 2d88b82ce781 |
comparison
equal
deleted
inserted
replaced
2523:366d84fdf8d1 | 2524:1a55848ce198 |
---|---|
63 * Haptic system hardware data. | 63 * Haptic system hardware data. |
64 */ | 64 */ |
65 struct haptic_hwdata | 65 struct haptic_hwdata |
66 { | 66 { |
67 int fd; | 67 int fd; |
68 char *fname; /* Points to the name in SDL_hapticlist. */ | |
68 }; | 69 }; |
69 | 70 |
70 | 71 |
71 /* | 72 /* |
72 * Haptic system effect data. | 73 * Haptic system effect data. |
203 return numhaptics; | 204 return numhaptics; |
204 } | 205 } |
205 | 206 |
206 | 207 |
207 /* | 208 /* |
209 * Gets the name from a file descriptor. | |
210 */ | |
211 static const char * | |
212 SDL_SYS_HapticNameFromFD(int fd) | |
213 { | |
214 static char namebuf[128]; | |
215 | |
216 /* We use the evdev name ioctl. */ | |
217 if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) { | |
218 return NULL; | |
219 } | |
220 | |
221 return namebuf; | |
222 } | |
223 | |
224 | |
225 /* | |
208 * Return the name of a haptic device, does not need to be opened. | 226 * Return the name of a haptic device, does not need to be opened. |
209 */ | 227 */ |
210 const char * | 228 const char * |
211 SDL_SYS_HapticName(int index) | 229 SDL_SYS_HapticName(int index) |
212 { | 230 { |
213 int fd; | 231 int fd; |
214 static char namebuf[128]; | 232 const char *name; |
215 char *name; | |
216 | 233 |
217 /* Open the haptic device. */ | 234 /* Open the haptic device. */ |
218 name = NULL; | 235 name = NULL; |
219 fd = open(SDL_hapticlist[index].fname, O_RDONLY, 0); | 236 fd = open(SDL_hapticlist[index].fname, O_RDONLY, 0); |
220 | 237 |
221 if (fd >= 0) { | 238 if (fd >= 0) { |
222 | 239 |
223 /* Check for name ioctl. */ | 240 name = SDL_SYS_HapticNameFromFD(fd); |
224 if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) { | 241 if (name==NULL) { |
225 | |
226 /* No name found, return device character device */ | 242 /* No name found, return device character device */ |
227 name = SDL_hapticlist[index].fname; | 243 name = SDL_hapticlist[index].fname; |
228 } | 244 } |
229 /* Name found, return name. */ | |
230 else { | |
231 name = namebuf; | |
232 } | |
233 } | 245 } |
234 close(fd); | 246 close(fd); |
235 | 247 |
236 return name; | 248 return name; |
237 } | 249 } |
241 * Opens the haptic device from the file descriptor. | 253 * Opens the haptic device from the file descriptor. |
242 */ | 254 */ |
243 static int | 255 static int |
244 SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd) | 256 SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd) |
245 { | 257 { |
258 const char *name; | |
259 | |
246 /* Allocate the hwdata */ | 260 /* Allocate the hwdata */ |
247 haptic->hwdata = (struct haptic_hwdata *) | 261 haptic->hwdata = (struct haptic_hwdata *) |
248 SDL_malloc(sizeof(*haptic->hwdata)); | 262 SDL_malloc(sizeof(*haptic->hwdata)); |
249 if (haptic->hwdata == NULL) { | 263 if (haptic->hwdata == NULL) { |
250 SDL_OutOfMemory(); | 264 SDL_OutOfMemory(); |
251 goto open_err; | 265 goto open_err; |
252 } | 266 } |
253 SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); | 267 SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); |
254 | 268 |
255 /* Set the data */ | 269 /* Set the data. */ |
256 haptic->hwdata->fd = fd; | 270 haptic->hwdata->fd = fd; |
257 haptic->supported = EV_IsHaptic(fd); | 271 haptic->supported = EV_IsHaptic(fd); |
258 haptic->naxes = 2; /* Hardcoded for now, not sure if it's possible to find out. */ | 272 haptic->naxes = 2; /* Hardcoded for now, not sure if it's possible to find out. */ |
259 | 273 |
260 /* Set the effects */ | 274 /* Set the effects */ |
291 */ | 305 */ |
292 int | 306 int |
293 SDL_SYS_HapticOpen(SDL_Haptic * haptic) | 307 SDL_SYS_HapticOpen(SDL_Haptic * haptic) |
294 { | 308 { |
295 int fd; | 309 int fd; |
310 int ret; | |
296 | 311 |
297 /* Open the character device */ | 312 /* Open the character device */ |
298 fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0); | 313 fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0); |
299 if (fd < 0) { | 314 if (fd < 0) { |
300 SDL_SetError("Haptic: Unable to open %s: %s", | 315 SDL_SetError("Haptic: Unable to open %s: %s", |
301 SDL_hapticlist[haptic->index], strerror(errno)); | 316 SDL_hapticlist[haptic->index], strerror(errno)); |
302 return -1; | 317 return -1; |
303 } | 318 } |
304 | 319 |
305 return SDL_SYS_HapticOpenFromFD(haptic,fd); | 320 /* Try to create the haptic. */ |
321 ret = SDL_SYS_HapticOpenFromFD(haptic,fd); /* Already closes on error. */ | |
322 if (ret < 0) { | |
323 return -1; | |
324 } | |
325 | |
326 /* Set the fname. */ | |
327 haptic->hwdata->fname = SDL_hapticlist[haptic->index].fname; | |
328 return 0; | |
306 } | 329 } |
307 | 330 |
308 | 331 |
309 /* | 332 /* |
310 * Opens a haptic device from first mouse it finds for usage. | 333 * Opens a haptic device from first mouse it finds for usage. |
351 * Checks to see if the haptic device and joystick and in reality the same. | 374 * Checks to see if the haptic device and joystick and in reality the same. |
352 */ | 375 */ |
353 int | 376 int |
354 SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) | 377 SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) |
355 { | 378 { |
356 if (SDL_strcmp(joystick->name,haptic->name)==0) { | 379 /* We are assuming linux is using evdev which should trump the old |
380 * joystick methods. */ | |
381 if (SDL_strcmp(joystick->hwdata->fname,haptic->hwdata->fname)==0) { | |
357 return 1; | 382 return 1; |
358 } | 383 } |
359 return 0; | 384 return 0; |
360 } | 385 } |
361 | 386 |
364 * Opens a SDL_Haptic from a SDL_Joystick. | 389 * Opens a SDL_Haptic from a SDL_Joystick. |
365 */ | 390 */ |
366 int | 391 int |
367 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) | 392 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) |
368 { | 393 { |
394 int i; | |
369 int fd; | 395 int fd; |
396 int ret; | |
397 | |
398 /* Find the joystick in the haptic list. */ | |
399 for (i=0; i<MAX_HAPTICS; i++) { | |
400 if (SDL_hapticlist[i].fname != NULL) { | |
401 if (SDL_strcmp(SDL_hapticlist[i].fname, joystick->hwdata->fname)==0) { | |
402 haptic->index = i; | |
403 } | |
404 } | |
405 } | |
406 | |
370 fd = open(joystick->hwdata->fname, O_RDWR, 0); | 407 fd = open(joystick->hwdata->fname, O_RDWR, 0); |
371 return SDL_SYS_HapticOpenFromFD(haptic,fd); | 408 ret = SDL_SYS_HapticOpenFromFD(haptic,fd); /* Already closes on error. */ |
409 if (ret < 0) { | |
410 return -1; | |
411 } | |
412 | |
413 haptic->hwdata->fname = SDL_hapticlist[haptic->index].fname; | |
414 return 0; | |
372 } | 415 } |
373 | 416 |
374 | 417 |
375 /* | 418 /* |
376 * Closes the haptic device. | 419 * Closes the haptic device. |
383 /* Clean up */ | 426 /* Clean up */ |
384 close(haptic->hwdata->fd); | 427 close(haptic->hwdata->fd); |
385 | 428 |
386 /* Free */ | 429 /* Free */ |
387 SDL_free(haptic->hwdata); | 430 SDL_free(haptic->hwdata); |
388 haptic->hwdata = NULL; | |
389 SDL_free(haptic->effects); | 431 SDL_free(haptic->effects); |
390 haptic->neffects = 0; | 432 } |
391 } | 433 |
434 /* Clear the rest. */ | |
435 SDL_memset(haptic, 0, sizeof(SDL_Haptic)); | |
392 } | 436 } |
393 | 437 |
394 | 438 |
395 /* | 439 /* |
396 * Clean up after system specific haptic stuff | 440 * Clean up after system specific haptic stuff |