Some more error checking. gsoc2008_force_feedback
authorEdgar Simo <bobbens@gmail.com>
Wed, 02 Jul 2008 09:52:44 +0000
branchgsoc2008_force_feedback
changeset 2490 be9b206d44af
parent 2489 96adc8025331
child 2491 10bc7aaf5114
Some more error checking. Implemented SDL_HapticOpenFromJoystick().
src/haptic/SDL_haptic.c
src/haptic/linux/SDL_syshaptic.c
src/joystick/linux/SDL_sysjoystick.c
src/joystick/linux/SDL_sysjoystick_c.h
--- a/src/haptic/SDL_haptic.c	Wed Jul 02 08:24:35 2008 +0000
+++ b/src/haptic/SDL_haptic.c	Wed Jul 02 09:52:44 2008 +0000
@@ -123,7 +123,7 @@
 
    /* 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 @@
 {
    int ret;
 
+   /* Must be a valid joystick */
    if (!SDL_PrivateJoystickValid(&joystick)) {
       return -1;
    }
@@ -157,10 +158,49 @@
 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;
+   }
+
+   /* 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;
+      }
    }
-   return -1;
+
+   /* 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;
 }
 
 
--- a/src/haptic/linux/SDL_syshaptic.c	Wed Jul 02 08:24:35 2008 +0000
+++ b/src/haptic/linux/SDL_syshaptic.c	Wed Jul 02 09:52:44 2008 +0000
@@ -88,7 +88,10 @@
 
    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 @@
 #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 @@
 
 
 /*
- * 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));
@@ -247,13 +240,43 @@
 
 
 /*
+ * 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 @@
 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);
 }
 
 
--- a/src/joystick/linux/SDL_sysjoystick.c	Wed Jul 02 08:24:35 2008 +0000
+++ b/src/joystick/linux/SDL_sysjoystick.c	Wed Jul 02 09:52:44 2008 +0000
@@ -774,6 +774,7 @@
 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 @@
             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_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);
--- a/src/joystick/linux/SDL_sysjoystick_c.h	Wed Jul 02 08:24:35 2008 +0000
+++ b/src/joystick/linux/SDL_sysjoystick_c.h	Wed Jul 02 09:52:44 2008 +0000
@@ -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
    {