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