From dd591eedfd6ca778a7b9801adb36be0e9c9df815 Mon Sep 17 00:00:00 2001 From: Edgar Simo Date: Wed, 2 Jul 2008 09:52:44 +0000 Subject: [PATCH] Some more error checking. Implemented SDL_HapticOpenFromJoystick(). --- src/haptic/SDL_haptic.c | 46 ++++++++++++++++++-- src/haptic/linux/SDL_syshaptic.c | 58 +++++++++++++++++++------- src/joystick/linux/SDL_sysjoystick.c | 5 +++ src/joystick/linux/SDL_sysjoystick_c.h | 2 + 4 files changed, 92 insertions(+), 19 deletions(-) diff --git a/src/haptic/SDL_haptic.c b/src/haptic/SDL_haptic.c index c983e2e31..f293cfa1b 100644 --- a/src/haptic/SDL_haptic.c +++ b/src/haptic/SDL_haptic.c @@ -123,7 +123,7 @@ SDL_HapticOpen(int device_index) /* Add haptic to list */ ++haptic->ref_count; - for (i = 0; SDL_haptics[i]; ++i) + for (i=0; SDL_haptics[i]; i++) /* Skip to next haptic */ ; SDL_haptics[i] = haptic; @@ -139,6 +139,7 @@ SDL_JoystickIsHaptic(SDL_Joystick * joystick) { int ret; + /* Must be a valid joystick */ if (!SDL_PrivateJoystickValid(&joystick)) { return -1; } @@ -157,10 +158,49 @@ SDL_JoystickIsHaptic(SDL_Joystick * joystick) SDL_Haptic * SDL_HapticOpenFromJoystick(SDL_Joystick * joystick) { + int i; + SDL_Haptic *haptic; + + /* Must be a valid joystick */ if (!SDL_PrivateJoystickValid(&joystick)) { - return -1; + return NULL; } - return -1; + + /* Joystick must be haptic */ + if (SDL_SYS_JoystickIsHaptic(joystick) <= 0) { + return NULL; + } + + /* Check to see if joystick's haptic is already open */ + for (i=0; SDL_haptics[i]; i++) { + if (SDL_SYS_JoystickSameHaptic(&SDL_haptics[i],joystick)) { + haptic = SDL_haptics[i]; + ++haptic->ref_count; + return haptic; + } + } + + /* Create the haptic device */ + haptic = (SDL_Haptic *) SDL_malloc((sizeof *haptic)); + if (haptic == NULL) { + SDL_OutOfMemory(); + return NULL; + } + + /* Initialize the haptic device */ + SDL_memset(haptic, 0, (sizeof *haptic)); + if (SDL_SYS_HapticOpenFromJoystick(haptic,joystick) < 0) { + SDL_free(haptic); + return NULL; + } + + /* Add haptic to list */ + ++haptic->ref_count; + for (i=0; SDL_haptics[i]; i++) + /* Skip to next haptic */ ; + SDL_haptics[i] = haptic; + + return haptic; } diff --git a/src/haptic/linux/SDL_syshaptic.c b/src/haptic/linux/SDL_syshaptic.c index 5f830e657..a14285038 100644 --- a/src/haptic/linux/SDL_syshaptic.c +++ b/src/haptic/linux/SDL_syshaptic.c @@ -88,7 +88,10 @@ EV_IsHaptic(int fd) ret = 0; - ioctl(fd, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features); + if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features) < 0) { + SDL_SetError("Unable to get device's haptic abilities."); + return -1; + } EV_TEST(FF_CONSTANT, SDL_HAPTIC_CONSTANT); EV_TEST(FF_PERIODIC, SDL_HAPTIC_SINE | @@ -151,7 +154,7 @@ SDL_SYS_HapticInit(void) #endif /* see if it works */ - if (EV_IsHaptic(fd)!=0) { + if (EV_IsHaptic(fd) > 0) { SDL_hapticlist[numhaptics].fname = SDL_strdup(path); SDL_hapticlist[numhaptics].haptic = NULL; dev_nums[numhaptics] = sb.st_rdev; @@ -191,21 +194,11 @@ SDL_SYS_HapticName(int index) /* - * Opens a haptic device for usage. + * Opens the haptic device from the file descriptor. */ -int -SDL_SYS_HapticOpen(SDL_Haptic * haptic) +static int +SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd) { - int i; - int fd; - - /* Open the character device */ - fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0); - if (fd < 0) { - SDL_SetError("Unable to open %s\n", SDL_hapticlist[haptic->index]); - return -1; - } - /* Allocate the hwdata */ haptic->hwdata = (struct haptic_hwdata *) SDL_malloc(sizeof(*haptic->hwdata)); @@ -246,14 +239,44 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic) } +/* + * Opens a haptic device for usage. + */ +int +SDL_SYS_HapticOpen(SDL_Haptic * haptic) +{ + int fd; + + /* Open the character device */ + fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0); + if (fd < 0) { + SDL_SetError("Unable to open %s\n", SDL_hapticlist[haptic->index]); + return -1; + } + + return SDL_SYS_HapticOpenFromFD(haptic,fd); +} + + /* * Checks to see if a joystick has haptic features. */ int SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) { - if (EV_IsHaptic(joystick->hwdata->fd) > 0) + return EV_IsHaptic(joystick->hwdata->fd); +} + + +/* + * Checks to see if the haptic device and joystick and in reality the same. + */ +int +SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +{ + if (SDL_strcmp(joystick->name,haptic->name)==0) { return 1; + } return 0; } @@ -264,6 +287,9 @@ SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) { + int fd; + fd = open(joystick->hwdata->fname, O_RDWR, 0); + return SDL_SYS_HapticOpenFromFD(haptic,fd); } diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index 8c6637cd7..c31dace49 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -774,6 +774,7 @@ int SDL_SYS_JoystickOpen(SDL_Joystick * joystick) { int fd; + char *fname; SDL_logical_joydecl(int realindex); SDL_logical_joydecl(SDL_Joystick * realjoy = NULL); @@ -787,13 +788,16 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) return (-1); fd = realjoy->hwdata->fd; + fname = realjoy->hwdata->fname; } else { fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0); + fname = SDL_joylist[joystick->index].fname; } SDL_joylist[joystick->index].joy = joystick; #else fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0); + fname = SDL_joylist[joystick->index].fname; #endif if (fd < 0) { @@ -809,6 +813,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) } SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); joystick->hwdata->fd = fd; + joystick->hwdata->fname = fname; /* Set the joystick to non-blocking read mode */ fcntl(fd, F_SETFL, O_NONBLOCK); diff --git a/src/joystick/linux/SDL_sysjoystick_c.h b/src/joystick/linux/SDL_sysjoystick_c.h index b319c8ba5..0479a69d4 100644 --- a/src/joystick/linux/SDL_sysjoystick_c.h +++ b/src/joystick/linux/SDL_sysjoystick_c.h @@ -28,6 +28,8 @@ struct joystick_hwdata { int fd; + char *fname; /* Used in haptic subsystem */ + /* The current linux joystick driver maps hats to two axes */ struct hwdata_hat {