diff src/haptic/linux/SDL_syshaptic.c @ 2472:3f73c88c9abb gsoc2008_force_feedback

First commit of the SDL_haptic subsystem. Code compiles and works, very limited functionality (linux only).
author Edgar Simo <bobbens@gmail.com>
date Sun, 01 Jun 2008 11:44:25 +0000
parents
children 3f80bf1528b4
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/haptic/linux/SDL_syshaptic.c	Sun Jun 01 11:44:25 2008 +0000
@@ -0,0 +1,185 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 2008 Edgar Simo
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#ifdef SDL_JOYSTICK_LINUX
+
+#include "SDL_haptic.h"
+#include "../SDL_haptic_c.h"
+#include "../SDL_syshaptic.h"
+
+#include <unistd.h> /* close */
+#include <linux/input.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <string.h>
+
+
+#include <stdio.h>
+
+
+#define MAX_HAPTICS  32
+
+
+static struct
+{
+   char *fname;
+   SDL_Haptic *haptic;
+} SDL_hapticlist[MAX_HAPTICS];
+
+struct haptic_hwdata
+{
+   int fd;
+};
+
+
+#define test_bit(nr, addr) \
+   (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)
+#define EV_TEST(ev,f) \
+   if (test_bit((ev), features)) ret |= (f);
+static int
+EV_IsHaptic(int fd)
+{
+   unsigned int ret;
+   unsigned long features[1 + FF_MAX/sizeof(unsigned long)];
+
+   ret = 0;
+
+   ioctl(fd, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features);
+
+   EV_TEST(FF_CONSTANT,   SDL_HAPTIC_CONSTANT);
+   EV_TEST(FF_PERIODIC,   SDL_HAPTIC_PERIODIC);
+   EV_TEST(FF_RAMP,       SDL_HAPTIC_RAMP);
+   EV_TEST(FF_SPRING,     SDL_HAPTIC_SPRING);
+   EV_TEST(FF_FRICTION,   SDL_HAPTIC_FRICTION);
+   EV_TEST(FF_DAMPER,     SDL_HAPTIC_DAMPER);
+   EV_TEST(FF_RUMBLE,     SDL_HAPTIC_RUMBLE);
+   EV_TEST(FF_INERTIA,    SDL_HAPTIC_INERTIA);
+   EV_TEST(FF_GAIN,       SDL_HAPTIC_GAIN);
+   EV_TEST(FF_AUTOCENTER, SDL_HAPTIC_AUTOCENTER);
+
+   return ret;
+}
+
+int
+SDL_SYS_HapticInit(void)
+{
+   const char joydev_pattern[] = "/dev/input/event%d";
+   dev_t dev_nums[MAX_HAPTICS];
+   char path[PATH_MAX];
+   struct stat sb;
+   int fd;
+   int i, j, k;
+   int duplicate;
+   int numhaptics;
+
+   numhaptics = 0;
+
+   i = 0;
+   for (j = 0; j < MAX_HAPTICS; ++j) {
+
+      snprintf(path, PATH_MAX, joydev_pattern, i++);
+
+      /* check to see if file exists */
+      if (stat(path,&sb) != 0)
+         break;
+
+      /* check for duplicates */
+      duplicate = 0;
+      for (k = 0; (k < numhaptics) && !duplicate; ++k) {
+         if (sb.st_rdev == dev_nums[k]) {
+            duplicate = 1;
+         }                                                     
+      }                                                         
+      if (duplicate) {
+         continue;
+      }
+
+      /* try to open */
+      fd = open(path, O_RDWR, 0);
+      if (fd < 0) continue;
+
+#ifdef DEBUG_INPUT_EVENTS
+      printf("Checking %s\n", path);
+#endif          
+
+      /* see if it works */
+      if (EV_IsHaptic(fd)!=0) {
+         SDL_hapticlist[numhaptics].fname = SDL_strdup(path);
+         SDL_hapticlist[numhaptics].haptic = NULL;
+         dev_nums[numhaptics] = sb.st_rdev;
+         ++numhaptics;
+      }
+      close(fd);
+   }
+
+   return numhaptics;
+}
+
+
+const char *
+SDL_SYS_HapticName(int index)
+{
+   int fd;
+   static char namebuf[128];
+   char *name;
+
+   name = NULL;
+   fd = open(SDL_hapticlist[index].fname, O_RDONLY, 0);
+   if (fd >= 0) {
+      if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) {
+         name = SDL_hapticlist[index].fname;
+      }
+      else {
+         name = namebuf;
+      }
+   }
+   close(fd);
+
+   return name;
+}
+
+
+int
+SDL_SYS_HapticOpen(SDL_Haptic * haptic)
+{
+   /* TODO finish
+   int fd;
+
+   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 0;
+   */
+}
+
+
+#endif /* SDL_HAPTIC_LINUX */