Better handling of opening haptics from joysticks. gsoc2008_force_feedback
authorEdgar Simo <bobbens@gmail.com>
Thu, 17 Jul 2008 16:07:20 +0000
branchgsoc2008_force_feedback
changeset 25241a55848ce198
parent 2523 366d84fdf8d1
child 2525 1fb3fba13a2c
Better handling of opening haptics from joysticks.
Fixed segfault when opening from joystick.
src/haptic/SDL_haptic.c
src/haptic/SDL_syshaptic.h
src/haptic/linux/SDL_syshaptic.c
     1.1 --- a/src/haptic/SDL_haptic.c	Thu Jul 17 11:47:48 2008 +0000
     1.2 +++ b/src/haptic/SDL_haptic.c	Thu Jul 17 16:07:20 2008 +0000
     1.3 @@ -274,7 +274,7 @@
     1.4     }
     1.5  
     1.6     /* Initialize the haptic device */
     1.7 -   SDL_memset(haptic, 0, (sizeof *haptic));
     1.8 +   SDL_memset(haptic, 0, sizeof(SDL_Haptic));
     1.9     if (SDL_SYS_HapticOpenFromJoystick(haptic,joystick) < 0) {
    1.10        SDL_free(haptic);
    1.11        return NULL;
     2.1 --- a/src/haptic/SDL_syshaptic.h	Thu Jul 17 11:47:48 2008 +0000
     2.2 +++ b/src/haptic/SDL_syshaptic.h	Thu Jul 17 16:07:20 2008 +0000
     2.3 @@ -43,7 +43,6 @@
     2.4  struct _SDL_Haptic
     2.5  {  
     2.6     Uint8 index; /* Stores index it is attached to */
     2.7 -   const char* name; /* Stores the name of the device */
     2.8  
     2.9     struct haptic_effect *effects; /* Allocated effects */
    2.10     int neffects; /* Maximum amount of effects */
     3.1 --- a/src/haptic/linux/SDL_syshaptic.c	Thu Jul 17 11:47:48 2008 +0000
     3.2 +++ b/src/haptic/linux/SDL_syshaptic.c	Thu Jul 17 16:07:20 2008 +0000
     3.3 @@ -65,6 +65,7 @@
     3.4  struct haptic_hwdata
     3.5  {
     3.6     int fd;
     3.7 +   char *fname; /* Points to the name in SDL_hapticlist. */
     3.8  };
     3.9  
    3.10  
    3.11 @@ -205,14 +206,30 @@
    3.12  
    3.13  
    3.14  /*
    3.15 + * Gets the name from a file descriptor.
    3.16 + */
    3.17 +static const char *
    3.18 +SDL_SYS_HapticNameFromFD(int fd)
    3.19 +{
    3.20 +   static char namebuf[128];
    3.21 +
    3.22 +   /* We use the evdev name ioctl. */
    3.23 +   if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) {
    3.24 +      return NULL;
    3.25 +   }
    3.26 +
    3.27 +   return namebuf;
    3.28 +}
    3.29 +
    3.30 +
    3.31 +/*
    3.32   * Return the name of a haptic device, does not need to be opened.
    3.33   */
    3.34  const char *
    3.35  SDL_SYS_HapticName(int index)
    3.36  {
    3.37     int fd;
    3.38 -   static char namebuf[128];
    3.39 -   char *name;
    3.40 +   const char *name;
    3.41  
    3.42     /* Open the haptic device. */
    3.43     name = NULL;
    3.44 @@ -220,16 +237,11 @@
    3.45  
    3.46     if (fd >= 0) {
    3.47  
    3.48 -      /* Check for name ioctl. */
    3.49 -      if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) {
    3.50 -
    3.51 +      name = SDL_SYS_HapticNameFromFD(fd);
    3.52 +      if (name==NULL) {
    3.53           /* No name found, return device character device */
    3.54           name = SDL_hapticlist[index].fname;
    3.55        }
    3.56 -      /* Name found, return name. */
    3.57 -      else {
    3.58 -         name = namebuf;
    3.59 -      }
    3.60     }
    3.61     close(fd);
    3.62  
    3.63 @@ -243,6 +255,8 @@
    3.64  static int
    3.65  SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd)
    3.66  {
    3.67 +   const char *name;
    3.68 +
    3.69     /* Allocate the hwdata */
    3.70     haptic->hwdata = (struct haptic_hwdata *)
    3.71           SDL_malloc(sizeof(*haptic->hwdata));
    3.72 @@ -252,7 +266,7 @@
    3.73     }
    3.74     SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
    3.75  
    3.76 -   /* Set the data */
    3.77 +   /* Set the data. */
    3.78     haptic->hwdata->fd = fd;
    3.79     haptic->supported = EV_IsHaptic(fd);
    3.80     haptic->naxes = 2; /* Hardcoded for now, not sure if it's possible to find out. */
    3.81 @@ -293,6 +307,7 @@
    3.82  SDL_SYS_HapticOpen(SDL_Haptic * haptic)
    3.83  {
    3.84     int fd;
    3.85 +   int ret;
    3.86  
    3.87     /* Open the character device */
    3.88     fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0);
    3.89 @@ -301,8 +316,16 @@
    3.90              SDL_hapticlist[haptic->index], strerror(errno));
    3.91        return -1;
    3.92     }
    3.93 -   
    3.94 -   return SDL_SYS_HapticOpenFromFD(haptic,fd);
    3.95 +
    3.96 +   /* Try to create the haptic. */
    3.97 +   ret =  SDL_SYS_HapticOpenFromFD(haptic,fd); /* Already closes on error. */
    3.98 +   if (ret < 0) {
    3.99 +      return -1;
   3.100 +   }
   3.101 +
   3.102 +   /* Set the fname. */
   3.103 +   haptic->hwdata->fname = SDL_hapticlist[haptic->index].fname;
   3.104 +   return 0;
   3.105  }
   3.106  
   3.107  
   3.108 @@ -353,7 +376,9 @@
   3.109  int
   3.110  SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
   3.111  {
   3.112 -   if (SDL_strcmp(joystick->name,haptic->name)==0) {
   3.113 +   /* We are assuming linux is using evdev which should trump the old
   3.114 +    * joystick methods. */
   3.115 +   if (SDL_strcmp(joystick->hwdata->fname,haptic->hwdata->fname)==0) {
   3.116        return 1;
   3.117     }
   3.118     return 0;
   3.119 @@ -366,9 +391,27 @@
   3.120  int
   3.121  SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
   3.122  {
   3.123 +   int i;
   3.124     int fd;
   3.125 +   int ret;
   3.126 +
   3.127 +   /* Find the joystick in the haptic list. */
   3.128 +   for (i=0; i<MAX_HAPTICS; i++) {
   3.129 +      if (SDL_hapticlist[i].fname != NULL) {
   3.130 +         if (SDL_strcmp(SDL_hapticlist[i].fname, joystick->hwdata->fname)==0) {
   3.131 +            haptic->index = i;
   3.132 +         }
   3.133 +      }
   3.134 +   }
   3.135 +
   3.136     fd = open(joystick->hwdata->fname, O_RDWR, 0);
   3.137 -   return SDL_SYS_HapticOpenFromFD(haptic,fd);
   3.138 +   ret =  SDL_SYS_HapticOpenFromFD(haptic,fd); /* Already closes on error. */
   3.139 +   if (ret < 0) {
   3.140 +      return -1;
   3.141 +   }
   3.142 +
   3.143 +   haptic->hwdata->fname = SDL_hapticlist[haptic->index].fname;
   3.144 +   return 0;
   3.145  }
   3.146  
   3.147  
   3.148 @@ -385,10 +428,11 @@
   3.149  
   3.150        /* Free */
   3.151        SDL_free(haptic->hwdata);
   3.152 -      haptic->hwdata = NULL;
   3.153        SDL_free(haptic->effects);
   3.154 -      haptic->neffects = 0;
   3.155     }
   3.156 +
   3.157 +   /* Clear the rest. */
   3.158 +   SDL_memset(haptic, 0, sizeof(SDL_Haptic));
   3.159  }
   3.160  
   3.161