Improved some ioctl handling. gsoc2008_force_feedback
authorEdgar Simo <bobbens@gmail.com>
Thu, 10 Jul 2008 08:38:08 +0000
branchgsoc2008_force_feedback
changeset 2512 ef147ee4896c
parent 2511 f12ae0bae468
child 2513 55fd9103a330
Improved some ioctl handling. Implemented SDL_MouseIsHaptic and SDL_HapticOpenFromMouse. More code comments.
include/SDL_haptic.h
src/haptic/SDL_haptic.c
src/haptic/SDL_syshaptic.h
src/haptic/dummy/SDL_syshaptic.c
src/haptic/linux/SDL_syshaptic.c
--- a/include/SDL_haptic.h	Wed Jul 09 18:29:11 2008 +0000
+++ b/include/SDL_haptic.h	Thu Jul 10 08:38:08 2008 +0000
@@ -638,6 +638,7 @@
  *    \return Device identifier or NULL on error.
  *
  * \sa SDL_HapticIndex
+ * \sa SDL_HapticOpenFromMouse
  * \sa SDL_HapticOpenFromJoystick
  * \sa SDL_HapticClose
  * \sa SDL_HapticSetGain
@@ -672,6 +673,29 @@
 extern DECLSPEC int SDL_HapticIndex(SDL_Haptic * haptic);
 
 /**
+ * \fn int SDL_MouseIsHaptic(void)
+ *
+ * \brief Gets whether or not the current mouse has haptic capabilities.
+ *
+ *    \return SDL_TRUE if the mouse is haptic, SDL_FALSE if it isn't.
+ *
+ * \sa SDL_HapticOpenFromMouse
+ */
+extern DECLSPEC SDL_MouseIsHaptic(void);
+
+/**
+ * \fn SDL_Haptic * SDL_HapticOpenFromMouse(void)
+ *
+ * \brief Tries to open a haptic device from the current mouse.
+ *
+ *    \return The haptic device identifier or NULL on error.
+ *
+ * \sa SDL_MouseIsHaptic
+ * \sa SDL_HapticOpen
+ */
+extern DECLSPEC SDL_Haptic * SDL_HapticOpenFromMouse(void);
+
+/**
  * \fn int SDL_JoystickIsHaptic(SDL_Joystick * joystick)
  *
  * \brief Checks to see if a joystick has haptic features.
--- a/src/haptic/SDL_haptic.c	Wed Jul 09 18:29:11 2008 +0000
+++ b/src/haptic/SDL_haptic.c	Thu Jul 10 08:38:08 2008 +0000
@@ -25,7 +25,7 @@
 #include "../joystick/SDL_joystick_c.h" /* For SDL_PrivateJoystickValid */
 
 
-static Uint8 SDL_numhaptics = 0;
+Uint8 SDL_numhaptics = 0;
 SDL_Haptic **SDL_haptics = NULL;
 static SDL_Haptic *default_haptic = NULL;
 
@@ -188,6 +188,37 @@
 
 
 /*
+ * Returns SDL_TRUE if mouse is haptic, SDL_FALSE if it isn't.
+ */
+int
+SDL_MouseIsHaptic(void)
+{
+   if (SDL_SYS_HapticMouse() < 0)
+      return SDL_FALSE;
+   return SDL_TRUE;
+}
+
+
+/*
+ * Returns the haptic device if mouse is haptic or NULL elsewise.
+ */
+SDL_Haptic *
+SDL_HapticOpenFromMouse(void)
+{
+   int device_index;
+
+   device_index = SDL_SYS_HapticMouse();
+
+   if (device_index < 0) {
+      SDL_SetError("Mouse isn't a haptic device.");
+      return NULL;
+   }
+
+   return SDL_HapticOpen(device_index);
+}
+
+
+/*
  * Returns SDL_TRUE if joystick has haptic features.
  */
 int
--- a/src/haptic/SDL_syshaptic.h	Wed Jul 09 18:29:11 2008 +0000
+++ b/src/haptic/SDL_syshaptic.h	Thu Jul 10 08:38:08 2008 +0000
@@ -25,6 +25,12 @@
 #include "SDL_haptic.h"
 
 
+/*
+ * Number of haptic devices on the system.
+ */
+extern Uint8 SDL_numhaptics;
+
+
 struct haptic_effect
 {
    SDL_HapticEffect effect; /* The current event */
@@ -68,6 +74,11 @@
 extern int SDL_SYS_HapticOpen(SDL_Haptic * haptic);
 
 /*
+ * Returns the index of the haptic core pointer or -1 if none is found.
+ */
+int SDL_SYS_HapticMouse(void);
+
+/*
  * Checks to see if the joystick has haptic capabilities.
  *
  * Returns >0 if haptic capabilities are detected, 0 if haptic
@@ -83,7 +94,6 @@
  */
 extern int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic,
                                           SDL_Joystick * joystick);
-
 /*
  * Checks to see if haptic device and joystick device are the same.
  *
--- a/src/haptic/dummy/SDL_syshaptic.c	Wed Jul 09 18:29:11 2008 +0000
+++ b/src/haptic/dummy/SDL_syshaptic.c	Thu Jul 10 08:38:08 2008 +0000
@@ -51,6 +51,13 @@
 
 
 int
+SDL_SYS_HapticMouse(void)
+{
+   return -1;
+}
+
+
+int
 SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
 {
    return 0;
--- a/src/haptic/linux/SDL_syshaptic.c	Wed Jul 09 18:29:11 2008 +0000
+++ b/src/haptic/linux/SDL_syshaptic.c	Thu Jul 10 08:38:08 2008 +0000
@@ -91,13 +91,14 @@
    unsigned int ret;
    unsigned long features[1 + FF_MAX/sizeof(unsigned long)];
 
+   /* Ask device for what it has. */
    ret = 0;
-
-   if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features) < 0) {
+   if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(features)), features) < 0) {
       SDL_SetError("Unable to get device's haptic abilities: %s", strerror(errno));
       return -1;
    }
 
+   /* Convert supported features to SDL_HAPTIC platform-neutral features. */
    EV_TEST(FF_CONSTANT,   SDL_HAPTIC_CONSTANT);
    EV_TEST(FF_PERIODIC,   SDL_HAPTIC_SINE |
                           SDL_HAPTIC_SQUARE |
@@ -113,9 +114,32 @@
    EV_TEST(FF_GAIN,       SDL_HAPTIC_GAIN);
    EV_TEST(FF_AUTOCENTER, SDL_HAPTIC_AUTOCENTER);
 
+   /* Return what it supports. */
    return ret;
 }
 
+
+/*
+ * Tests whether a device is a mouse or not.
+ */
+static int
+EV_IsMouse(int fd)
+{
+   unsigned long argp[40];
+
+   /* Ask for supported features. */
+   if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(argp)), argp) < 0) {
+      return -1;
+   }
+
+   /* Currently we only test for BTN_MOUSE which can give fake positives. */
+   if (test_bit(BTN_MOUSE,argp) != 0) {
+      return 1;
+   }
+
+   return 0;
+}
+
 /*
  * Initializes the haptic subsystem by finding available devices.
  */
@@ -133,6 +157,10 @@
 
    numhaptics = 0;
 
+   /* 
+    * Limit amount of checks to MAX_HAPTICS since we may or may not have
+    * permission to some or all devices.
+    */
    i = 0;
    for (j = 0; j < MAX_HAPTICS; ++j) {
 
@@ -185,12 +213,19 @@
    static char namebuf[128];
    char *name;
 
+   /* Open the haptic device. */
    name = NULL;
    fd = open(SDL_hapticlist[index].fname, O_RDONLY, 0);
+
    if (fd >= 0) {
+
+      /* Check for name ioctl. */
       if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) {
+
+         /* No name found, return device character device */
          name = SDL_hapticlist[index].fname;
       }
+      /* Name found, return name. */
       else {
          name = namebuf;
       }
@@ -215,6 +250,7 @@
       goto open_err;
    }
    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
+
    /* Set the data */
    haptic->hwdata->fd = fd;
    haptic->supported = EV_IsHaptic(fd);
@@ -264,7 +300,38 @@
    }
    
    return SDL_SYS_HapticOpenFromFD(haptic,fd);
-} 
+}
+
+
+/*
+ * Opens a haptic device from first mouse it finds for usage.
+ */
+int
+SDL_SYS_HapticMouse(void)
+{
+   int fd;
+   int i;
+
+   for (i=0; i<SDL_numhaptics; i++) {
+
+      /* Open the device. */
+      fd = open(SDL_hapticlist[i].fname, O_RDWR, 0);
+      if (fd < 0) {
+         SDL_SetError("Unable to open %s: %s",
+               SDL_hapticlist[i], strerror(errno));
+         return -1;
+      }
+
+      if (EV_IsMouse(fd)) {
+         close(fd);
+         return i;
+      }
+
+      close(fd);
+   }
+   
+   return -1;
+}
 
 
 /*