[AD] Linux joysytick and force feedback

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Dear allegro list members,

In attachment, find two patches to the 5.1 branch of today. The first
one beoran_linux_event_joystick.diff changes the implementation of the
Linux joystick driver to use the newer /dev/input/eventxx Linux API in
stead of the older /dev/input/jsxx API. This has several benefits,
such as better axis detection. However the main one is that it makes
it easier to support haptics (force feedback) on Linux. This patch
makes some changes hat expose the internals of the Linux Joystick
driver into an internal header file for use with the haptic device.

The second patch beoran_haptics.diff, which should be applied after
the first patch, contains the whole high level machinery for playing
back haptic effects as well as a Linux driver. I am a pure 100% Linux
user so I'm unable to contribute a Windows or a OSX driver at the
moment, but I hope that with this framework in place, some people will
step up to generously contribute them. The patch contains
documentation, but I'll admit everything still has some rough corners.
But it works for me so I hope it will be a nice beginning for adding
haptic affects to Allegro.  I'm open to all suggestions.

Kind Regards,

Beoran.
diff --git a/include/allegro5/internal/aintern_ljoynu.h b/include/allegro5/internal/aintern_ljoynu.h
deleted file mode 100644
index c16c372..0000000
--- a/include/allegro5/internal/aintern_ljoynu.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __al_included_allegro_aintern_ljoynu_h
-#define __al_included_allegro_aintern_ljoynu_h
-
-
-#include "allegro5/joystick.h"
-#include "allegro5/internal/aintern_joystick.h"
-
-
-
-
-/* State transitions:
- *    unused -> born
- *    born -> alive
- *    born -> dying
- *    active -> dying
- *    dying -> unused
- */
-typedef enum {
-   LJOY_STATE_UNUSED,
-   LJOY_STATE_BORN,
-   LJOY_STATE_ALIVE,
-   LJOY_STATE_DYING
-} CONFIG_STATE;
-
-#define ACTIVE_STATE(st) \
-   ((st) == LJOY_STATE_ALIVE || (st) == LJOY_STATE_DYING)
-
-
-/* Map a Linux joystick axis number to an Allegro (stick,axis) pair 
- * Uses the input event interface's numbering. ABS_MISC = 0x28,
- * So that is the maximum of allowed axes on Linux.
- */
-#define TOTAL_JOYSTICK_AXES  0x28
-
-typedef struct {
-   int stick;
-   int axis;
-   int value;
-   int min;
-   int max;    
-   int fuzz;
-   int flat;
-} AXIS_MAPPING;
-
-
-typedef struct ALLEGRO_JOYSTICK_LINUX
-{
-   ALLEGRO_JOYSTICK parent;
-   int config_state;
-   bool marked;
-   int fd;
-   ALLEGRO_USTR *device_name;
-
-   AXIS_MAPPING axis_mapping[TOTAL_JOYSTICK_AXES];
-   ALLEGRO_JOYSTICK_STATE joystate;
-   char name[100];
-} ALLEGRO_JOYSTICK_LINUX;
-
-
-#endif
\ No newline at end of file
diff --git a/src/linux/ljoynu.c b/src/linux/ljoynu.c
index 6d62b7c..f291f81 100644
--- a/src/linux/ljoynu.c
+++ b/src/linux/ljoynu.c
@@ -41,7 +41,6 @@
  */
 #include <sys/types.h>
 #include <linux/joystick.h>
-#include <linux/input.h>
 
 #if defined(ALLEGRO_HAVE_SYS_INOTIFY_H) && defined(ALLEGRO_HAVE_SYS_TIMERFD_H)
    #define SUPPORT_HOTPLUG
@@ -51,7 +50,47 @@
 
 ALLEGRO_DEBUG_CHANNEL("ljoy");
 
-#include "allegro5/internal/aintern_ljoynu.h"
+#define TOTAL_JOYSTICK_AXES  (_AL_MAX_JOYSTICK_STICKS * _AL_MAX_JOYSTICK_AXES)
+
+
+/* State transitions:
+ *    unused -> born
+ *    born -> alive
+ *    born -> dying
+ *    active -> dying
+ *    dying -> unused
+ */
+typedef enum {
+   LJOY_STATE_UNUSED,
+   LJOY_STATE_BORN,
+   LJOY_STATE_ALIVE,
+   LJOY_STATE_DYING
+} CONFIG_STATE;
+
+#define ACTIVE_STATE(st) \
+   ((st) == LJOY_STATE_ALIVE || (st) == LJOY_STATE_DYING)
+
+
+/* map a Linux joystick axis number to an Allegro (stick,axis) pair */
+typedef struct {
+   int stick;
+   int axis;
+} AXIS_MAPPING;
+
+
+typedef struct ALLEGRO_JOYSTICK_LINUX
+{
+   ALLEGRO_JOYSTICK parent;
+   int config_state;
+   bool marked;
+   int fd;
+   ALLEGRO_USTR *device_name;
+
+   AXIS_MAPPING axis_mapping[TOTAL_JOYSTICK_AXES];
+   ALLEGRO_JOYSTICK_STATE joystate;
+   char name[100];
+} ALLEGRO_JOYSTICK_LINUX;
+
 
 
 /* forward declarations */
@@ -100,43 +139,34 @@ static int timer_fd = -1;
 #endif
 
 
-
-#define LONG_BITS (sizeof(long) * 8)
-#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
-/* Tests if a bit in an array of longs is set. */
-#define TEST_BIT(nr, addr) \
-    (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
-
-/* check_is_event_joystick: 
+/* check_js_api_version: [primary thread]
  *
- *  Return true if this fd supports the /dev/inputt/eventxx API and 
- * is a joystick indeed.
+ *  Return true if the joystick API used by the device is supported by
+ *  this driver.
  */
-static bool check_is_event_joystick(int fd) {
-
-  
-  // unsigned long device_bits[(EV_MAX + 8) / sizeof(unsigned long)];  
-  unsigned long bitmask[NLONGS(EV_CNT)]   = {0};
-  
-  if (ioctl (fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) {
-    perror ("EVIOCGBIT ioctl failed");
-    fprintf(stderr, "For fd %d\n", fd);
-    return false;
-  }
-  /* If we see buttons and axes, it's most likely a joystick */
-   if (TEST_BIT(EV_ABS, bitmask) && TEST_BIT(EV_KEY, bitmask)) {   
-     return true;
-   }
-   
-   /* Force feedback device is always a joystick. */
-   if (TEST_BIT(EV_FF, bitmask)) {
-     return true;
+static bool check_js_api_version(int fd)
+{
+   unsigned int raw_version;
+
+   if (ioctl(fd, JSIOCGVERSION, &raw_version) < 0) {
+      /* NOTE: IOCTL fails if the joystick API is version 0.x */
+      ALLEGRO_WARN("Your Linux joystick API is version 0.x which is unsupported.\n");
+      return false;
    }
-   
-   return false;
+
+   /*
+   struct { unsigned char build, minor, major; } version;
+
+   version.major = (raw_version & 0xFF0000) >> 16;
+   version.minor = (raw_version & 0xFF00) >> 8;
+   version.build = (raw_version & 0xFF);
+   */
+
+   return true;
 }
 
 
+
 static bool ljoy_detect_device_name(int num, ALLEGRO_USTR *device_name)
 {
    ALLEGRO_CONFIG *cfg;
@@ -155,7 +185,7 @@ static bool ljoy_detect_device_name(int num, ALLEGRO_USTR *device_name)
    }
 
    if (al_ustr_size(device_name) == 0)
-      al_ustr_appendf(device_name, "/dev/input/event%d", num);
+      al_ustr_appendf(device_name, "/dev/input/js%d", num);
 
    return (stat(al_cstr(device_name), &stbuf) == 0);
 }
@@ -237,26 +267,6 @@ static void inactivate_joy(ALLEGRO_JOYSTICK_LINUX *joy)
 }
 
 
-static bool get_num_buttons(int fd, int * num_buttons)
-{
-    unsigned long key_bits[NLONGS(KEY_CNT)]  = {0};
-    int nbut = 0;
-    
-    int res, i;
- 
-    res = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits);
-    if (res < 0) return false;
-    
-    for (i = BTN_MISC ; i <= KEY_MAX; i++) {
-      if(TEST_BIT(i, key_bits)) {
-          nbut++;
-      }
-    }
-    (*num_buttons) = nbut;
-    return true;
-}
-
-
 
 static void ljoy_scan(bool configure)
 {
@@ -275,11 +285,8 @@ static void ljoy_scan(bool configure)
 
    device_name = al_ustr_new("");
 
-   /* This is a big number, but there can be gaps, and other unrelated event queues. 
-    * Perhaps it would be better to use glob() here in stead o gessing the numbers 
-    * like this?
-    */
-   for (num = 0; num < 32; num++) {
+   /* This is a big number, but there can be gaps. */
+   for (num = 0; num < 16; num++) {
       if (!ljoy_detect_device_name(num, device_name))
          continue;
 
@@ -290,20 +297,16 @@ static void ljoy_scan(bool configure)
          continue;
       }
 
-      /* Try to open the device. The device must be pened in O_RDWR mode to allow 
-       * writing of haptic effects! The haptic driver for linux 
-       * reuses the joystick driver's FD. */
-      fd = open(al_cstr(device_name), O_RDWR|O_NONBLOCK);
+      /* Try to open the device. */
+      fd = open(al_cstr(device_name), O_RDONLY|O_NONBLOCK);
       if (fd == -1) {
          ALLEGRO_WARN("Failed to open device %s\n", al_cstr(device_name));
          continue;
       }
- 
-      if (!check_is_event_joystick(fd)) {
+      if (!check_js_api_version(fd)) {
          close(fd);
          continue;
       }
- 
       ALLEGRO_DEBUG("Device %s is new\n", al_cstr(device_name));
 
       joy = ljoy_allocate_structure();
@@ -313,94 +316,76 @@ static void ljoy_scan(bool configure)
       joy->marked = true;
       config_needs_merging = true;
 
-      if (ioctl(fd, EVIOCGNAME(sizeof(joy->name)), joy->name) < 0)
+      if (ioctl(fd, JSIOCGNAME(sizeof(joy->name)), joy->name) < 0)
          strcpy(joy->name, "Unknown");
 
       /* Fill in the joystick information fields. */
       {
-         int num_axes = 0;
-         int num_buttons;
-         int b;
-         unsigned long abs_bits[NLONGS(ABS_CNT)]  = {0};
-         int res, i;  
-         int stick = 0;
-         int axis  = 0;
-         
+         char num_axes;
+         char num_buttons;
+         int throttle;
+         int s, a, b;
+   
+         ioctl(fd, JSIOCGAXES, &num_axes);
+         ioctl(fd, JSIOCGBUTTONS, &num_buttons);
    
-         // get_num_axes(fd, &num_axes);
-         get_num_buttons(fd, &num_buttons);
+         if (num_axes > TOTAL_JOYSTICK_AXES)
+            num_axes = TOTAL_JOYSTICK_AXES;
    
          if (num_buttons > _AL_MAX_JOYSTICK_BUTTONS)
             num_buttons = _AL_MAX_JOYSTICK_BUTTONS;
-         
-         /* Scan the axes to get their properties. */
-        res = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);    
-        if (res < 0) continue;
-        for (i = 0; i <= ABS_MISC; i++) {
-          if(TEST_BIT(i, abs_bits)) {
-          struct input_absinfo absinfo;
-          if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0)
-                    continue;
-            if (
-                 (i == ABS_THROTTLE) || (i == ABS_RUDDER) || (i == ABS_WHEEL) 
-              || (i == ABS_GAS)      || (i == ABS_BRAKE) || (i== ABS_BRAKE) 
-              || (i == ABS_PRESSURE) || (i == ABS_DISTANCE) || (i== ABS_TOOL_WIDTH) 
-            ) { 
-              /* One axis throttle. */
-               joy->parent.info.stick[stick].flags = ALLEGRO_JOYFLAG_ANALOGUE;
-               joy->parent.info.stick[stick].num_axes = 1;
-               joy->parent.info.stick[stick].axis[0].name = "Throttle";
-               char *name = joy->parent.info.stick[stick].axis[0].name;
-               joy->parent.info.stick[stick].name = al_malloc(strlen(name) + 1);
-               strcpy(joy->parent.info.stick[stick].name, name);
-               joy->axis_mapping[i].stick = stick;
-               joy->axis_mapping[i].axis  = 0;
-               joy->axis_mapping[i].min   = absinfo.minimum;
-               joy->axis_mapping[i].max   = absinfo.maximum;
-               joy->axis_mapping[i].value = absinfo.value;
-               joy->axis_mapping[i].fuzz  = absinfo.fuzz;
-               joy->axis_mapping[i].flat  = absinfo.flat;
-              /* Consider all these types of axis as throttle axis. */
-               stick++;
-            } else { /* regular axis, two axis stick. */
-              int digital = ((i >= ABS_HAT0X) && (i <=  ABS_HAT3Y));
-               if (axis == 0) { /* first axis of new joystick */
-                if (digital) {
-                  joy->parent.info.stick[stick].flags = ALLEGRO_JOYFLAG_DIGITAL;
-                } else { 
-                  joy->parent.info.stick[stick].flags = ALLEGRO_JOYFLAG_ANALOGUE;
-                }
-                joy->parent.info.stick[stick].num_axes = 2;
-                joy->parent.info.stick[stick].axis[0].name = "X";
-                joy->parent.info.stick[stick].axis[1].name = "Y";
-                joy->parent.info.stick[stick].name = al_malloc (32);
-                snprintf((char *)joy->parent.info.stick[stick].name, 32, "Stick %d", stick+1);
-                joy->axis_mapping[i].stick = stick;
-                joy->axis_mapping[i].axis  = axis;
-                joy->axis_mapping[i].min   = absinfo.minimum;
-                joy->axis_mapping[i].max   = absinfo.maximum;
-                joy->axis_mapping[i].value = absinfo.value;
-                joy->axis_mapping[i].fuzz  = absinfo.fuzz;
-                joy->axis_mapping[i].flat  = absinfo.flat;                
-                axis++;
-               } else { /* Second axis. */
-                joy->axis_mapping[i].stick = stick;
-                joy->axis_mapping[i].axis  = axis;
-                joy->axis_mapping[i].min   = absinfo.minimum;
-                joy->axis_mapping[i].max   = absinfo.maximum;
-                joy->axis_mapping[i].value = absinfo.value;
-                joy->axis_mapping[i].fuzz  = absinfo.fuzz;
-                joy->axis_mapping[i].flat  = absinfo.flat;
-                stick++;
-                axis = 0;
-               }
+   
+         /* XXX use configuration system when we get one */
+         throttle = -1;
+   #if 0
+         /* User is allowed to override our simple assumption of which
+          * axis number (kernel) the throttle is located at. */
+         snprintf(tmp, sizeof(tmp), "throttle_axis_%d", num);
+         throttle = get_config_int("joystick", tmp, -1);
+         if (throttle == -1) {
+            throttle = get_config_int("joystick", 
+                                      "throttle_axis", -1);
+         }
+   #endif
+   
+         /* Each pair of axes is assumed to make up a stick unless it 
+          * is the sole remaining axis, or has been user specified, in 
+          * which case it is a throttle. */
+   
+         for (s = 0, a = 0;
+              s < _AL_MAX_JOYSTICK_STICKS && a < num_axes;
+              s++)
+         {
+            if ((a == throttle) || (a == num_axes-1)) {
+               /* One axis throttle. */
+               joy->parent.info.stick[s].flags = ALLEGRO_JOYFLAG_ANALOGUE;
+               joy->parent.info.stick[s].num_axes = 1;
+               joy->parent.info.stick[s].axis[0].name = "Throttle";
+               char *name = joy->parent.info.stick[s].axis[0].name;
+               joy->parent.info.stick[s].name = al_malloc(strlen(name) + 1);
+               strcpy(joy->parent.info.stick[s].name, name);
+               joy->axis_mapping[a].stick = s;
+               joy->axis_mapping[a].axis = 0;
+               a++;
+            }
+            else {
+               /* Two axis stick. */
+               joy->parent.info.stick[s].flags = ALLEGRO_JOYFLAG_ANALOGUE;
+               joy->parent.info.stick[s].num_axes = 2;
+               joy->parent.info.stick[s].axis[0].name = "X";
+               joy->parent.info.stick[s].axis[1].name = "Y";
+               joy->parent.info.stick[s].name = al_malloc (32);
+               snprintf((char *)joy->parent.info.stick[s].name, 32, "Stick %d", s+1);
+               joy->axis_mapping[a].stick = s;
+               joy->axis_mapping[a].axis = 0;
+               a++;
+               joy->axis_mapping[a].stick = s;
+               joy->axis_mapping[a].axis = 1;
+               a++;
             }
-            num_axes++;
-          }
-        }
-    
+         }
    
-        joy->parent.info.num_sticks = stick;
+         joy->parent.info.num_sticks = s;
    
          /* Do the buttons. */
    
@@ -725,52 +710,44 @@ static void ljoy_process_new_data(void *data)
    
    _al_event_source_lock(es);
    {
-      struct input_event input_events[32];
+      struct js_event js_events[32];
       int bytes, nr, i;
 
-      while ((bytes = read(joy->fd, &input_events, sizeof input_events)) > 0) {
+      while ((bytes = read(joy->fd, &js_events, sizeof js_events)) > 0) {
 
-         nr = bytes / sizeof(struct input_event);
+         nr = bytes / sizeof(struct js_event);
 
          for (i = 0; i < nr; i++) {
-            int type   = input_events[i].type;
-            int code   = input_events[i].code;
-            int value  = input_events[i].value;
-            if (type == EV_KEY) {
-              int number = code - BTN_JOYSTICK;
-              if (number < _AL_MAX_JOYSTICK_BUTTONS) {              
-              if (value)
+
+            int type   = js_events[i].type;
+            int number = js_events[i].number;
+            int value  = js_events[i].value;
+
+            if (type & JS_EVENT_BUTTON) {
+               if (number < _AL_MAX_JOYSTICK_BUTTONS) {
+                  if (value)
                      joy->joystate.button[number] = 32767;
                   else
                      joy->joystate.button[number] = 0;
 
-              ljoy_generate_button_event(joy, number,
+                  ljoy_generate_button_event(joy, number,
                                              (value
                                               ? ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN
                                               : ALLEGRO_EVENT_JOYSTICK_BUTTON_UP));
-              } 
-            } else if ((type == EV_ABS ) && (code < ABS_MISC)) {
-                int       stick = -1;
-                int       axis  = -1;
-                float     range, pos;
-                
-              
-                AXIS_MAPPING * map = joy->axis_mapping +code;
-                axis  = map->axis;
-                stick = map->stick;                
-                range = (float) map->max - (float) map->min;
-                /* Normalize around 0. */
-                pos   = (float) value    - (float) map->min;
-                /* Divide by range, to get value between 0.0 and 1.0  */
-                pos   = pos              / range;
-                /* Now multiply by 2.0 and substract 1.0 to get a value between 
-                * -1.0 and 1.0
-                */
-                pos   = pos * 2.0f - 1.0f;
-                joy->joystate.stick[stick].axis[axis] = pos;
-                ljoy_generate_axis_event(joy, stick, axis, pos);           
+               }
             }
-         }   
+            else if (type & JS_EVENT_AXIS) {
+               if (number < TOTAL_JOYSTICK_AXES) {
+                  int stick = joy->axis_mapping[number].stick;
+                  int axis  = joy->axis_mapping[number].axis;
+                  float pos = value / 32767.0;
+
+                  joy->joystate.stick[stick].axis[axis] = pos;
+
+                  ljoy_generate_axis_event(joy, stick, axis, pos);
+               }
+            }
+         }
       }
    }
    _al_event_source_unlock(es);
diff --git a/cmake/FileList.cmake b/cmake/FileList.cmake
index 12754f6..3a33c50 100644
--- a/cmake/FileList.cmake
+++ b/cmake/FileList.cmake
@@ -23,7 +23,6 @@ set(ALLEGRO_SRC_FILES
     src/fshook.c
     src/fshook_stdio.c
     src/fullscreen_mode.c
-    src/haptic.c
     src/inline.c
     src/joynu.c
     src/keybdnu.c
@@ -113,8 +112,7 @@ set(ALLEGRO_SRC_X_FILES
     src/x/xmousenu.c
     src/x/xrandr.c
     src/x/xsystem.c
-    src/x/xwindow.c    
-    src/linux/lhaptic.c
+    src/x/xwindow.c
     src/linux/ljoynu.c
     )
 
@@ -166,7 +164,6 @@ set(ALLEGRO_SRC_RASPBERRYPI_FILES
    src/linux/lkeybdnu.c
    src/linux/lmseev.c
    src/linux/lmsedrv.c
-   src/linux/lhaptic.c
    src/linux/ljoynu.c
    src/x/xevents.c
    src/x/xkeyboard.c
@@ -199,7 +196,6 @@ set(ALLEGRO_INCLUDE_ALLEGRO_FILES
     include/allegro5/fmaths.h
     include/allegro5/fshook.h
     include/allegro5/fullscreen_mode.h
-    include/allegro5/haptic.h
     include/allegro5/joystick.h
     include/allegro5/keyboard.h
     include/allegro5/keycodes.h
diff --git a/docs/Refman.cmake b/docs/Refman.cmake
index 869228a..634359b 100644
--- a/docs/Refman.cmake
+++ b/docs/Refman.cmake
@@ -13,8 +13,7 @@ set(PAGES
     fshook
     fullscreen_mode
     graphics
-    haptic
-    joystick    
+    joystick
     keyboard
     memory
     misc
diff --git a/docs/inc.a.html b/docs/inc.a.html
deleted file mode 100644
index 79c8fee..0000000
--- a/docs/inc.a.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<div class="sidebar">
-
-<div>
-<ul>
-<li><a href="index.html"><strong>Contents</strong></a></li>
-<li><a href="config.html">Configuration files</a></li>
-<li><a href="display.html">Display</a></li>
-<li><a href="events.html">Events</a></li>
-<li><a href="file.html">File I/O</a></li>
-<li><a href="fshook.html">Filesystem</a></li>
-<li><a href="fixed.html">Fixed point math</a></li>
-<li><a href="fullscreen_mode.html">Fullscreen modes</a></li>
-<li><a href="graphics.html">Graphics</a></li>
-<li><a href="haptic.html">Haptic</a></li>
-<li><a href="joystick.html">Joystick</a></li>
-<li><a href="keyboard.html">Keyboard</a></li>
-<li><a href="memory.html">Memory</a></li>
-<li><a href="monitor.html">Monitor</a></li>
-<li><a href="mouse.html">Mouse</a></li>
-<li><a href="path.html">Path</a></li>
-<li><a href="shader.html">Shader</a></li>
-<li><a href="state.html">State</a></li>
-<li><a href="system.html">System</a></li>
-<li><a href="threads.html">Threads</a></li>
-<li><a href="time.html">Time</a></li>
-<li><a href="timer.html">Timer</a></li>
-<li><a href="touch.html">Touch input</a></li>
-<li><a href="transformations.html">Transformations</a></li>
-<li><a href="utf8.html">UTF-8</a></li>
-<li><a href="misc.html">Miscellaneous</a></li>
-<li><a href="platform.html">Platform-specific</a></li>
-<li><a href="direct3d.html">Direct3D</a></li>
-<li><a href="opengl.html">OpenGL</a></li>
-</ul>
-<!-- The preceding blank line forces pandoc to terminate the list -->
-</div>
-
-<div>
-<ul>
-<li><a href="index.html#addons"><strong>Addons</strong></a></li>
-<li><a href="audio.html">Audio addon</a></li>
-<li><a href="acodec.html">Audio codecs</a></li>
-<li><a href="color.html">Color addon</a></li>
-<li><a href="font.html">Font addons</a></li>
-<li><a href="image.html">Image I/O addon</a></li>
-<li><a href="main.html">Main addon</a></li>
-<li><a href="memfile.html">Memfile addon</a></li>
-<li><a href="native_dialog.html">Native dialogs addon</a></li>
-<li><a href="physfs.html">PhysicsFS addon</a></li>
-<li><a href="primitives.html">Primitives addon</a></li>
-<li><a href="video.html">Video streaming addon</a></li>
-</ul>
-<!-- The preceding blank line forces pandoc to terminate the list -->
-</div>
-
-<div>
-<ul>
-<li><a href="index_all.html"><strong>Index</strong></a></li>
-</ul>
-<!-- The preceding blank line forces pandoc to terminate the list -->
-</div>
-
-<div class="searchbox">
-<script type="text/javascript">
-function on_search(index, control) {
-    // Note to self: the less-than sign must NOT converted to an entity!
-    // SCRIPT elements are special.  The HTML validator gives bad advice.
-    for (i = 0; i < search_index.length; i++) {
-        if (search_index[i] == control.keywords[index]) {
-            break;
-        }
-    }
-    location.href = search_urls[i];
-}
-</script>
-Search<br/> <input type="text" name="q" id="q" size="15" autocomplete="off"/><br/>
-<script type="text/javascript"> new autosuggest("q", search_index, null, on_search); </script>
-</div>
-
-</div>
-
-<div class="content">
-
-
-
diff --git a/docs/src/refman/haptic.txt b/docs/src/refman/haptic.txt
deleted file mode 100644
index 026bc83..0000000
--- a/docs/src/refman/haptic.txt
+++ /dev/null
@@ -1,386 +0,0 @@
-# Haptic routines
-
-Haptic functions support force feedback and vibration on input devices.
-These functions are declared in the main Allegro header file:
-
-    #include <allegro5/allegro.h>
-
-## API: ALLEGRO_HAPTIC
-
-This is an abstract data type representing a haptic device that supports force 
-feedback or vibration.
-
-See also: [al_get_haptic_from_joystick]
-
-## API: ALLEGRO_HAPTIC_CONSTANTS
-
-This enum contains flags that are used to define haptic effects and capabilities. 
-If the flag is set in the return value of [al_get_haptic_capabilities], it means
-the device supports the given effect. The value of these flags should be set 
-into a [ALLEGRO_HAPTIC_EFFECT] struct to determine what kind of haptic effect 
-should be caused when it is played. 
-
-* ALLEGRO_HAPTIC_RUMBLE       - simple vibration effects
-* ALLEGRO_HAPTIC_PERIODIC     - periodic, wave-form effects
-* ALLEGRO_HAPTIC_CONSTANT     - constant effects
-* ALLEGRO_HAPTIC_SPRING       - spring effects
-* ALLEGRO_HAPTIC_FRICTION     - friction effects
-* ALLEGRO_HAPTIC_DAMPER       - damper effects
-* ALLEGRO_HAPTIC_INERTIA      - inertia effects
-* ALLEGRO_HAPTIC_RAMP         - ramp effects
-* ALLEGRO_HAPTIC_SQUARE       - square wave periodic effect
-* ALLEGRO_HAPTIC_TRIANGLE     - triangle wave periodic effect
-* ALLEGRO_HAPTIC_SINE         - sine wave periodic effect
-* ALLEGRO_HAPTIC_SAW_UP       - upwards saw wave periodic effect
-* ALLEGRO_HAPTIC_SAW_DOWN     - downwards saw wave periodic effect
-* ALLEGRO_HAPTIC_CUSTOM       - custom wave periodic effect
-* ALLEGRO_HAPTIC_GAIN         - the haptic device supports gain setting
-* ALLEGRO_HAPTIC_ANGLE        - the haptic device supports angle coordinates
-* ALLEGRO_HAPTIC_RADIUS       - the haptic device supports radius coordinates
-* ALLEGRO_HAPTIC_AZIMUTH      - the haptic device supports azimuth coordinates
-
-See also: [al_get_haptic_capabilities], [ALLEGRO_HAPTIC_EFFECT]
-
-## API: ALLEGRO_HAPTIC_EFFECT
-
-This struct models a particular haptic or vibration effect. It needs to be filled 
-correctly in and uploaded to a haptic device, before the device can play it back. 
-
-*Fields:*
-* type - The type of the haptic effect. May be one of the [ALLEGRO_HAPTIC_CONSTANTS]
-   constants between or equal to [ALLEGRO_HAPTIC_RUMBLE] and [ALLEGRO_HAPTIC_RAMP].
-   
-   If `type` is set to [ALLEGRO_HAPTIC_RUMBLE], then the effect is a simple "rumble" 
-   or vibration effect that shakes the device. In some cases, such as on a mobile 
-   platform, the whole device may shake.
-   
-   If `type` is set to  [ALLEGRO_HAPTIC_PERIODIC], the effect is a shake or 
-   vibration of which the intensity is a periodic wave form. 
-   
-   If `type` is set to  [ALLEGRO_HAPTIC_CONSTANT], the effect is a constant 
-   pressure, motion  or push-back in a certain direction of the axes of the device. 
-   
-   If `type` is set to  [ALLEGRO_HAPTIC_SPRING], the effect is a springy kind of 
-   resistance against motion of the axes of the haptic device. 
-   
-   If `type` is set to  [ALLEGRO_HAPTIC_FRICTION], the effect is a friction kind
-   of resistance against motion of the axes of the haptic device. 
-   
-   If `type` is set to  [ALLEGRO_HAPTIC_DAMPER], the effect is a damper kind
-   of resistance against motion of the axes of the haptic device. 
-   
-   If `type` is set to  [ALLEGRO_HAPTIC_INERTIA], the effect causes inertia or 
-   slowness of motions on the axes of the haptic device. 
-     
-   If `type` is set to  [ALLEGRO_HAPTIC_RAMP], the effect causes a pressure 
-   or push-back that ramps up or down depending on the position of the axis.
-   
-* direction - The direction of location in 3D space where the effect should be 
-   played. Allegro haptic devices model directions in 3D space using spherical 
-   coordinates. However, the haptic device may not support localized effects, or may 
-   not support all coordinate components. 
-   
-   In Allegro's coordinate system, the value in `direction.angle` determines 
-   the planar angle between the effect and the direction of the user who holds the 
-   device, expressed in radians.  So, an effect with an angle 0.0 takes place in 
-   the direction of the user of the  haptic device, and an angle of PI means in the 
-   direction away  from the user. 
-   
-   If [al_get_haptic_capabilities] has the flag [ALLEGRO_HAPTIC_ANGLE] set, 
-   then setting `direction.angle`  is supported. Otherwise,  it is unsupported, 
-   and you should set it to 0.
-   
-   The value in `direction.radius` is a relative value between 0.0 and 1.0 that 
-   determines the relative distance from the center of the haptic device at which 
-   the effect will play back. A value of 0 means that the effect should play back 
-   at the center of the device. A value of 1.0 means that the effect should play 
-   back away from the center as far as is possible.  
-   
-   If [al_get_haptic_capabilities] 
-   has the flag [ALLEGRO_HAPTIC_RADIUS] set,  then setting `direction.radius`  
-   is supported. Otherwise, it is unsupported, and you should set it to 0.
-   
-   The value in `direction.azimuth` determines the elevation angle between the 
-   effect and the plane in which the user is holding the device, expressed in 
-   radians. An effect with an azimuth 0.0 plays back in the plane in which
-   the user is holding the device, an azimuth +PI/2 means the effect plays back 
-   vertically  above the user plane, and an azimuth -PI/2 means the effect plays 
-   back vertically below the user plane.
-   
-   If [al_get_haptic_capabilities] has the flag [ALLEGRO_HAPTIC_AZIMUTH] set, 
-   then setting `direction.azimuth` is supported. Otherwise,  it is unsupported, 
-   and you should set it to 0.   
-   
-* replay - Determines how the effect should be played back. 
-   `replay.length` is the duration in seconds of the effect, and `replay.delay`
-   is the time in seconds that the effect playback should be delayed when playback 
-   is started with [al_play_haptic_effect].
-   
-* data - Determines in detail the parameters of the haptic effect to play back.  
-
-   If `type` is set to [ALLEGRO_HAPTIC_RUMBLE], then `data.rumble.strong_magnitude` 
-   must be set to a relative magnitude between 0.0 and 1.0 to determine how intensely 
-   the "large" rumble motor of the haptic device will vibrate. And 
-   `data.rumble.weak_magnitude` must be set to relative magnitude between 0.0 
-   and 1.0  to determine how intensely the "weak" ruble motor of the haptic device 
-   will vibrate. Not all devices have a "weak" motor, in which case the value set 
-   in `data.rumble.weak_magnitude` will be ignored.
-  
-   If `type` is set to  [ALLEGRO_HAPTIC_PERIODIC], then `data.periodic.waveform` 
-   must be set to one of [ALLEGRO_HAPTIC_SQUARE], [ALLEGRO_HAPTIC_TRIANGLE],
-   [ALLEGRO_HAPTIC_SINE], [ALLEGRO_HAPTIC_SAW_UP], [ALLEGRO_HAPTIC_SAW_DOWN],
-   [ALLEGRO_HAPTIC_CUSTOM]. This will then determine the wave form of the vibration
-   effect that will be played on the haptic device. 
-  
-   In these cases, `data.periodic.period` muust be set to the period in seconds 
-   of the wave form. The field `data.periodic.magnitude must be set to the relative 
-   magnitude of intensity between -1.0 and 1.0 at  which the wave form of the 
-   vibration  will be played back. The field `data.periodic.offset` must be filled 
-   in with the  offset from origin in seconds of the wave form of vibration. And the 
-   field `data.periodic.pahe` is the phase of the wave form of vibration in seconds.
-  
-   If `data.periodic.waveform` is set to [ALLEGRO_HAPTIC_CUSTOM], then 
-   `data.periodic.custom_data` must point to an array of `data.periodic.custom_len`
-   doubles, each with values between -1.0 and 1.0. This value array 
-   will determine the shape of the wave form of the haptic effect. 
-   [ALLEGRO_HAPTIC_CUSTOM] is not supported on some platforms, so use 
-   [al_get_haptic_capabilities] to check if it's available. If not, then 
-   it's a good idea play back a non-cusytom wave effect in stead as a substitute. 
-  
-   If `type` is set to  [ALLEGRO_HAPTIC_CONSTANT], then `data.constant.level` 
-   must be set to a relative intensity value between 0.0 and 1.0 to determine the 
-   intensity of the effect.
-   
-   
-   If `type` is set to  any of [ALLEGRO_HAPTIC_SPRING], [ALLEGRO_HAPTIC_FRICTION], 
-   [ALLEGRO_HAPTIC_DAMPER], [ALLEGRO_HAPTIC_INERTIA], [ALLEGRO_HAPTIC_RAMP], then
-   the `data.condition` struct shuld be filled in. To explain this better, 
-   it's best to keep in mind that this  kind of effects is most useful for 
-   steering-wheel kind of devices, where resistance or inertia should be applied
-   when turning the wheel of the device a certain distance to the right or the left. 
-   
-   The field `data.condition.right_saturation` must be filled in with a relative 
-   magnitude between -1.0 and 1.0 to determine the the intensity of resistance 
-   or inertia on the "right" side of the axis. Likewise, 
-   `data.condition.left_saturation` must be filled in with a relative 
-   magnitude between -1.0 and 1.0 to determine the the intensity of resistance 
-   or inertia on the "left" side of the axis. 
-   
-   The field 'data.condition.deadband' must be filled in with a relative value 
-   between 0.0 and 1.0, to determine the relative width of the "dead band" of the 
-   haptic effect. As long as the axis of the haptic device remains in the 
-   "dead band" area, the effect will not be applied. A value of 0.0 means there is 
-   no dead band, and a value of 1.0 means it applied over the whole range of the 
-   axis in question.   
-   
-   The field 'data.condition.center' must be filled in with a relative value between 
-   -1.0 and 1.0, to determine the relative position of the "center" of the effect 
-   around which the dead band is centered.  It should be set to 0.0 in case 
-   the center should not be shifted.
-   
-   The field `data.condition.right_coef`  and `data.condition.right_left_coef` must 
-   be filled in with a relative  coefficient, that will detemine how quickly the 
-   effect ramps up on the right and  left side. If set to 1.0, then the effect will 
-   be immediately at full intensity when outside of the dead band. If set to 0.0 
-   the effect will not be felt at all.
-
-   If ` type` is set to [ALLEGRO_HAPTIC_RAMP], then `data.ramp.start_level` should 
-   be set to a relative magnitude value between  -1.0 and 1.0 to determine the 
-   initial intensity of the haptic effect. The field  `data.ramp.end_level` should 
-   be set to a relative magnitude value between -1.0 and 1.0 to determine the final  
-   intensity of the haptic effect at the end of playback.
-  
-   If 'type' is set to any of [ALLEGRO_HAPTIC_PERIODIC], [ALLEGRO_HAPTIC_CONSTANT], 
-   [ALLEGRO_HAPTIC_RAMP], then  `data.envelope` determines the "envelope" of 
-   the effect. That is, it determines the duration and intensity for the ramp-up 
-   attack or "fade in" and the ramp-down "fade out" of the effect. 
-  
-   In these cases the field `data.envelope.attack_level` must be set to a relative 
-   value between 0.0 and 1.0 that determines the intensity the effect should have 
-   when it starts playing after `replay.delay` seconds have passed since the playback 
-   started. The field  `data.envelope.attack_length` must be set to the time in seconds 
-   that the effect should  ramp up to the maximum intensity as set by the other 
-   parameters of the effect. If `data.envelope.attack_length` is 0, 
-   then the effect will play immediately at full intensity. 
-  
-   The field `data.envelope.fade_level` must be set to a relative value between 
-   0.0 and 1.0 that determines the intensity the effect should have 
-   when at the moment it stops playing after `replay.length` + 'replay.delay' seconds 
-   have passed since the playback of the effect started. The field 
-   `data.envelope.fade_length` must be set to the time in seconds that the effect 
-   should fade out before it finished playing. If `data.envelope.fade_length` is 0, 
-   then the effect will not fade out.
-  
-   If you don't want to use an envelope, then set all four fields of
-   `data.envelope` to 0.0. The effect will then play back at full intensity 
-   throughout it's playback.
-   
-
-## API: ALLEGRO_HAPTIC_EFFECT_ID
-
-This struct is used as a handle to control playback of a haptic effect.
-The struct should be considered opaque. It's implementation is visible merely to 
-allow allocation by the users of the Allegro library. 
-
-## API: al_install_haptic 
-
-Installs the haptic (force feedback) device subsystem. This must be called before 
-using any other haptic related functions. Returns true if the haptics subsystem
-could be initialized correctly, false if not.
-
-## API: al_uninstall_haptic
-
-Uninstalls the haptic device subsystem.
-
-## API: al_is_haptic_installed
-
-Returns true if the haptic device subsystem is installed, false if not.
-
-## API: al_is_mouse_haptic
-
-Returns true if the mouse has haptic capabilities, false if not.
-
-## API: al_is_keyboard_haptic
-
-Returns true if the keyboard has haptic capabilities, false if not.
-
-## API: al_is_display_haptic
-
-Returns true if the display has haptic capabilities, false if not. To be more 
-precise, this is mainly meant for force feedback that shakes a hand held device,
-such as a phone or a tablet.
-
-## API: al_is_joystick_haptic
-
-Returns true if the joystick has haptic capabilities, false if not.
-
-## API: al_is_touch_input_haptic
-
-Returns true if the touch input device has haptic capabilities, false if not.
-
-
-## API: al_get_haptic_from_mouse
-If the mouse has haptic capabilities, returns the associated haptic device handle. 
-Otherwise returns NULL.
-
-## API: al_get_haptic_from_keyboard
-If the keyboard has haptic capabilities, returns the associated haptic device handle. 
-Otherwise returns NULL.
-
-## API: al_get_haptic_from_display
-If the display has haptic capabilities, returns the associated haptic device handle. 
-Otherwise returns NULL.
-
-## API: al_get_haptic_from_joystick
-If the joystick has haptic capabilities, returns the associated haptic device handle. 
-Otherwise returns NULL. It's neccesary to call this again every time the joystick 
-configuration changes, such as though hot plugging.
-
-## API: al_get_haptic_from_touch_input
-If the touch input device has haptic capabilities, returns the associated haptic 
-device handle. Otherwise returns NULL.
-
-## API: al_release_haptic
-
-Releases the haptic device and it's resources when it's not needed anymore. 
-Should also be used in case the joystick configuration changed, such as when a 
-joystick is hot plugged. 
-
-
-## API:  al_get_haptic_active 
-
-Returns true if the haptic device can currently be used, false if not.
-
-## API:  al_get_haptic_capabilities
-
-Returns an integer with or'ed values from [ALLEGRO_HAPTIC_CONSTANTS], 
-which, if set, indicate that the haptic device supports the given feature. 
-
-## API: al_set_haptic_gain 
-
-Sets the gain of the haptic device if supported. Gain is much like volume for sound, 
-it is as if every effect's intensity is multiplied by it. Gain is a value between 
-0.0 and 1.0. Returns true if set sucessfully, false if not. Only works if 
-[al_get_haptic_capabilities] returns a value that has [ALLEGRO_HAPTIC_GAIN] set. 
-If not, this function returns false, and all effects will be played without any gain 
-influence.
-
-## API: al_get_haptic_gain 
-Returns the current gain of the device. Gain is much like volume for sound, 
-it is as if every effect's intensity is multiplied by it. Gain is a value between 
-0.0 and 1.0. Only works correctly if [al_get_haptic_capabilities] returns a value 
-that has [ALLEGRO_HAPTIC_GAIN] set. If this is not set, this function will simply 
-return 1.0 and all effects will be played without any gain influence.
-
-## API: al_get_num_haptic_effects
-
-Returns the maximum amount of haptic effects that can be uploaded to the device.
-This depends on the platform and the device.
-
-## API: al_is_haptic_effect_ok
-
-Returns true if the haptic device can play the haptic effect as given, false if not.
-The haptic effect must have been filled in completely and correctly.
-
-## API: al_upload_haptic_effect 
-
-Uploads the haptic effect to the device. 
-The haptic effect must have been filled in completely and correctly.
-You must also pass in a pointer to a user allocated [ALLEGRO_HAPTIC_EFFECT_ID]. 
-This `id` can be used to control playback of the effect. 
-Returns true if the effect was sucesfully uploaded, false if not.
-
-The same haptic effect can be uploaded several times, as long as care is taken to 
-pass in a different [ALLEGRO_HAPTIC_EFFECT_ID].
-
-## API: al_play_haptic_effect 
-
-Plays back a previously uploaded haptic effect. The play_id must be a valid
-[ALLEGRO_HAPTIC_EFFECT_ID] obtained from [al_upload_haptic_effect], 
-[al_upload_and_play_haptic_effect] or [al_rumble_haptic]. 
-
-The haptic effect will be played back loop times in sequence. If loop is less than 
-or equal to 1, then the effect will be played once only. 
-
-This function returns immediately and doesn't wait for the playback to finish. It 
-returns true if the playback was started sucessfully or false ir not.
-
-## API: al_upload_and_play_haptic_effect
-
-Uploads and immediately plays back the haptic effect to the device. Returns 
-true if the upload and playback were sucessful, false if either failed.
-
-See also: [al_upload_haptic_effect], [al_play_haptic_effect]
-
-## API: al_stop_haptic_effect
-
-Stops playing a previously uploaded haptic effect. The play_id must be a valid
-[ALLEGRO_HAPTIC_EFFECT_ID] obtained from [al_upload_haptic_effect], 
-[al_upload_and_play_haptic_effect] or [al_rumble_haptic]. 
-
-## API: al_is_haptic_effect_playing
-
-Returns true if the haptic effect is currently playing. Returns false 
-if the effect has been stopped or if it finsihed playing, or if it has not been 
-played yet. The play_id must be a valid [ALLEGRO_HAPTIC_EFFECT_ID] obtained from 
-[al_upload_haptic_effect], [al_upload_and_play_haptic_effect] or [al_rumble_haptic]. 
-
-## API: al_release_haptic_effect
-
-Releases a previously uploaded haptic effect from the device it has been uploaded 
-to, allowing for other effects to be uploaded. The play_id must be a valid 
-[ALLEGRO_HAPTIC_EFFECT_ID] obtained from [al_upload_haptic_effect], 
-[al_upload_and_play_haptic_effect] or [al_rumble_haptic]. 
-
-## API: al_rumble_haptic
-
-Uploads a simple rumble effect to the haptic device and starts playback immediately.
-The parameter `intensity` is a relative magnitude between 0.0 and 1.0 that 
-determines the intensity of the rumble effect. The `duration` determines the 
-duration of the effect in seconds.  
-
-You must also pass in a pointer to a user allocated [ALLEGRO_HAPTIC_EFFECT_ID]. 
-It it is stored a reference to be used to control playback of the effect. 
-Returns true if the rumble effect was succesfully uploaded and started, false if 
-not.
-
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index a7ed1bd..babde1a 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -135,7 +135,6 @@ example(ex_fs_resize ${IMAGE} ${PRIM})
 example(ex_fs_window ${IMAGE} ${PRIM} ${FONT})
 example(ex_icon ${IMAGE})
 example(ex_icon2 ${IMAGE})
-example(ex_haptic ${PRIM})
 example(ex_joystick_events ${PRIM})
 example(ex_joystick_hotplugging ${PRIM})
 example(ex_keyboard_events)
diff --git a/examples/ex_haptic.c b/examples/ex_haptic.c
deleted file mode 100644
index d7e1cbf..0000000
--- a/examples/ex_haptic.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *    Example program for the Allegro library, by Beoran.
- *
- *    This program tests haptic effects.examples/ex_hapti
- */
-
-#include <allegro5/allegro.h>
-#include <allegro5/allegro_primitives.h>
-
-#include "common.c"
-
-
-#define MAX_HAPTICS  32
-
-/* globals */
-ALLEGRO_EVENT_QUEUE  *event_queue;
-
-
-
-int main(void)
-{
-   int index;
-   ALLEGRO_DISPLAY * display;
-   ALLEGRO_HAPTIC  * haptic = NULL;
-   ALLEGRO_HAPTIC_EFFECT effect = {0};
-   double intensity = 1.0;
-   double duration  = 1.0;
-   int num_joysticks;
-
-   effect.type                           = ALLEGRO_HAPTIC_RUMBLE;
-   effect.data.rumble.strong_magnitude   = intensity;
-   effect.data.rumble.weak_magnitude     = intensity;  
-   effect.replay.delay                   = 0.1;
-   effect.replay.length                  = duration;   
-   
-   if (!al_init()) {
-      abort_example("Could not init Allegro.\n");
-   }
-
-   display = al_create_display(640, 480);
-   if (!display) {
-      abort_example("al_create_display failed\n");
-   }
-   al_install_joystick();
-   al_install_haptic();
-
-   event_queue = al_create_event_queue();
-   if (!event_queue) {
-      abort_example("al_create_event_queue failed\n");
-   }
-   open_log();
-     
-   num_joysticks = al_get_num_joysticks();
-   for(index = 0; index < num_joysticks; index++) {
-     ALLEGRO_JOYSTICK * joy = al_get_joystick(index);
-     if(!joy) continue;
-     if (!al_is_joystick_haptic(joy)) {  
-       log_printf("Joystick %s does not support force feedback.\n", al_get_joystick_name(joy));
-       al_release_joystick(joy);
-       continue;
-     } else {
-       ALLEGRO_HAPTIC_EFFECT_ID id;
-       log_printf("Joystick %s supports force feedback.\n", al_get_joystick_name(joy));
-       haptic = al_get_haptic_from_joystick(joy);
-       log_printf("Can play back %d haptic effects.\n", al_get_num_haptic_effects(haptic));
-       log_printf("Set gain to 0.8: %d.\n", al_set_haptic_gain(haptic, 0.8));
-       log_printf("Get gain: %lf.\n", al_get_haptic_gain(haptic));
-       log_printf("Capabilities: %d.\n", al_get_haptic_capabilities(haptic));
-       log_printf("Upload effect: %d.\n ", al_upload_haptic_effect(haptic, &effect, &id));
-       log_printf("Playing effect: %d.\n ", al_play_haptic_effect(&id, 5));
-       while (al_is_haptic_effect_playing(&id)) {
-       }
-       log_printf("Set gain to 0.4: %d.\n", al_set_haptic_gain(haptic, 0.4));
-       log_printf("Get gain: %lf.\n", al_get_haptic_gain(haptic));
-       log_printf("Playing effect again: %d.\n ", al_play_haptic_effect(&id, 5));
-       al_rest(2.0);
-       log_printf("Stopping effect: %d.\n ", al_stop_haptic_effect(&id));
-       
-       while (al_is_haptic_effect_playing(&id)) {
-         //log_printf(".");
-       }
-       log_printf("Release effect: %d.\n ", al_release_haptic_effect(&id));
-       log_printf("Release haptic: %d.\n ", al_release_haptic(haptic));
-     }
-   }
-          
-   log_printf("\nAll done!\n");       
-   close_log(true);
-   // al_register_event_source(event_queue, al_get_display_event_source(display));
-   // al_register_event_source(event_queue, al_get_haptic_event_source());
-
-   
-   return 0;
-}
-
-/* vim: set ts=8 sts=3 sw=3 et: */
diff --git a/include/allegro5/allegro.h b/include/allegro5/allegro.h
index e1d8f19..fe33fc8 100644
--- a/include/allegro5/allegro.h
+++ b/include/allegro5/allegro.h
@@ -59,7 +59,6 @@
 #include "allegro5/touch_input.h"
 #include "allegro5/transformations.h"
 #include "allegro5/utf8.h"
-#include "allegro5/haptic.h"
 
 
 #ifndef ALLEGRO_NO_COMPATIBILITY
diff --git a/include/allegro5/haptic.h b/include/allegro5/haptic.h
deleted file mode 100644
index 7463bba..0000000
--- a/include/allegro5/haptic.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/*         ______   ___    ___
- *        /\  _  \ /\_ \  /\_ \
- *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
- *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
- *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
- *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
- *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
- *                                           /\____/
- *                                           \_/__/
- *
- *      Haptic (that is, force feedback) routines for Allegro. 
- *      By Beoran (beoran@xxxxxxxxx), 2013.
- *
- *      See readme.txt for copyright information.
- */
-
-#ifndef __al_included_allegro5_haptic_h
-#define __al_included_allegro5_haptic_h
-
-#include "allegro5/base.h"
-#include "allegro5/events.h"
-#include "allegro5/mouse.h"
-#include "allegro5/joystick.h"
-
-#ifdef __cplusplus
-   extern "C" {
-#endif
-
-/* Enum: ALLEGRO_HAPTIC_CONSTANTS
- */
-enum ALLEGRO_HAPTIC_CONSTANTS 
-{ 
-  ALLEGRO_HAPTIC_RUMBLE       = 1 << 0,
-  ALLEGRO_HAPTIC_PERIODIC     = 1 << 1,
-  ALLEGRO_HAPTIC_CONSTANT     = 1 << 2,
-  ALLEGRO_HAPTIC_SPRING       = 1 << 3,
-  ALLEGRO_HAPTIC_FRICTION     = 1 << 4,
-  ALLEGRO_HAPTIC_DAMPER       = 1 << 5,
-  ALLEGRO_HAPTIC_INERTIA      = 1 << 6,
-  ALLEGRO_HAPTIC_RAMP         = 1 << 7,
-  ALLEGRO_HAPTIC_SQUARE       = 1 << 8,
-  ALLEGRO_HAPTIC_TRIANGLE     = 1 << 9,
-  ALLEGRO_HAPTIC_SINE         = 1 << 10,
-  ALLEGRO_HAPTIC_SAW_UP       = 1 << 11,
-  ALLEGRO_HAPTIC_SAW_DOWN     = 1 << 12,
-  ALLEGRO_HAPTIC_CUSTOM       = 1 << 13,  
-  ALLEGRO_HAPTIC_GAIN         = 1 << 14,   
-  ALLEGRO_HAPTIC_ANGLE        = 1 << 15,
-  ALLEGRO_HAPTIC_RADIUS       = 1 << 16,
-  ALLEGRO_HAPTIC_AZIMUTH      = 1 << 17,
-};
-
-
-
-/* Type: ALLEGRO_HAPTIC
- */
-typedef struct ALLEGRO_HAPTIC ALLEGRO_HAPTIC;
-
-/* Direction of a haptic effect. Angle is a value between 0 and 2*M_PI.
- * An angle 0 means oriented towards the user, M_PI is away from the user 
- * (towards the screen). Angle is only supported if the device capabilities include
- * ALLEGRO_HAPTIC_ANGLE.  
- * Radius (if supported ) is the distance of the effect from the user 
- * as a value between 0 and 1. Normally it is 0. Radius is only supported if the 
- * device capabilities include ALLEGRO_HAPTIC_RADIUS .  
- * Azimuth is the angle of elevation, between -M_PI/2 and M_PI/2. 0 points to the 
- * horizontal plane, -M_PI/2 points down, and M_PI/2 points up.
- * Azimuth is only supported if the device capabilities include 
- * ALLEGRO_HAPTIC_AZIMUTH.
- * 
- */
-struct ALLEGRO_HAPTIC_DIRECTION 
-{
-  double angle; 
-  double radius;
-  double azimuth;
-};
-
-/* In all of the following structs, the doubles that express duration represent 
- * time in seconds. The double that represent levels of intensity are between 0.0 
- * and 1.0 that mean no effect and full 100% effect. */
-
-/* Delay to start the replay and duration of the replay, expressed  in seconds. */
-struct ALLEGRO_HAPTIC_REPLAY 
-{
-    double length;
-    double delay;
-};
-
-/* Envelope of the effect. */
-struct ALLEGRO_HAPTIC_ENVELOPE 
-{
-    double attack_length;
-    double attack_level;
-    double fade_length;
-    double fade_level;
-};
-
-/* Constant effect.  Level is between 0.0 and 1.0. */
-struct ALLEGRO_HAPTIC_CONSTANT_EFFECT 
-{
-    double level;
-    struct ALLEGRO_HAPTIC_ENVELOPE envelope;
-};
-
-/* Ramp effect. Both start_level and end level are between 0.0 and 1.0.  */
-struct ALLEGRO_HAPTIC_RAMP_EFFECT 
-{
-    double start_level;
-    double end_level;
-    struct ALLEGRO_HAPTIC_ENVELOPE envelope;
-};
-
-/* Condition effect. */
-struct ALLEGRO_HAPTIC_CONDITION_EFFECT 
-{
-    double right_saturation;
-    double left_saturation;
-    double right_coeff;
-    double left_coeff;
-    double deadband;
-    double center;
-};
-
-/* Periodic (wave) effect. */
-struct ALLEGRO_HAPTIC_PERIODIC_EFFECT 
-{
-    int waveform;
-    double period;
-    double magnitude;
-    double offset;
-    double phase;
-    
-    struct ALLEGRO_HAPTIC_ENVELOPE envelope;
-    int    custom_len;
-    double *custom_data;
-};
-
-/* Simple rumble effect with a magnitude between 0.0 and 1.0 for both 
- the strong and the weak rumble motors in the haptic device.  */
-struct ALLEGRO_HAPTIC_RUMBLE_EFFECT 
-{
-    double strong_magnitude;
-    double weak_magnitude;
-};
-
-union ALLEGRO_HAPTIC_EFFECT_UNION 
-{
-    struct ALLEGRO_HAPTIC_CONSTANT_EFFECT   constant;
-    struct ALLEGRO_HAPTIC_RAMP_EFFECT       ramp;
-    struct ALLEGRO_HAPTIC_PERIODIC_EFFECT   periodic;
-    struct ALLEGRO_HAPTIC_CONDITION_EFFECT  condition; 
-    struct ALLEGRO_HAPTIC_RUMBLE_EFFECT     rumble;
-};
-
-/* Type: ALLEGRO_HAPTIC_EFFECT
- */
-struct ALLEGRO_HAPTIC_EFFECT 
-{
-  
-    int                                type;
-    struct ALLEGRO_HAPTIC_DIRECTION    direction;
-    struct ALLEGRO_HAPTIC_REPLAY       replay;
-    union ALLEGRO_HAPTIC_EFFECT_UNION  data; 
-};
-
-typedef struct ALLEGRO_HAPTIC_EFFECT ALLEGRO_HAPTIC_EFFECT;
-
-
-/* Type: ALLEGRO_HAPTIC_EFFECT_ID
- */
-typedef struct ALLEGRO_HAPTIC_EFFECT_ID ALLEGRO_HAPTIC_EFFECT_ID;
-
-struct ALLEGRO_HAPTIC_EFFECT_ID 
-{
-  ALLEGRO_HAPTIC        * _haptic;
-  ALLEGRO_HAPTIC_EFFECT * _effect;
-  int                     _id;
-  int                     _handle;
-  bool                    _playing;  
-  double                  _started;
-  int                     _loops; 
-};
-
-
-/* Installs the haptic (force feedback) device subsystem. */
-AL_FUNC(bool,             al_install_haptic          , (void));
-/* Uninstalls the haptic device subsystem. */
-AL_FUNC(void,             al_uninstall_haptic        , (void));
-/* Returns true if the haptic device subsystem is installed, false if not. */
-AL_FUNC(bool,             al_is_haptic_installed     , (void));
-
-/* Returns true if the mouse has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_mouse_haptic         , (ALLEGRO_MOUSE *));
-/* Returns true if the joystick has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_joystick_haptic      , (ALLEGRO_JOYSTICK *));
-/* Returns true if the keyboard has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_keyboard_haptic      , (ALLEGRO_KEYBOARD *));
-/* Returns true if the display has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_display_haptic       , (ALLEGRO_DISPLAY *));
-/* Returns true if the touch input has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_touch_input_haptic   , (ALLEGRO_TOUCH_INPUT *));
-
-
-/* If the mouse has haptic capabilities, returns the associated haptic device handle. 
- * Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_mouse    , (ALLEGRO_MOUSE *));
-/* If the mouse has haptic capabilities, returns the associated haptic device handle. 
- * Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_joystick , (ALLEGRO_JOYSTICK *));
-/* If the keyboard has haptic capabilities, returns the associated haptic device handle. 
- * Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_keyboard , (ALLEGRO_KEYBOARD *));
-/* If the display has haptic capabilities, returns the associated haptic device handle. 
- * Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_display  , (ALLEGRO_DISPLAY *));
-/* If the touch input has haptic capabilities, returns the associated haptic 
- * device handle. Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_touch_input, (ALLEGRO_TOUCH_INPUT *));
-
-/* Releases the haptic device when it's not needed anymore. Should also be used in 
- * case the joystick configuration changed, such as when a joystick is hot plugged.  
- */
-AL_FUNC(bool, al_release_haptic, (ALLEGRO_HAPTIC *));
-
-
-
-/* Returns true if the haptic device can currently be used, false if not.*/
-AL_FUNC(bool,   al_get_haptic_active       , (ALLEGRO_HAPTIC *));
-
-/* Returns an integer with or'ed values from ALLEGRO_HAPTIC_CONSTANTS, that if
- set indicate that the haptic device supports the given feature. */
-AL_FUNC(int,    al_get_haptic_capabilities , (ALLEGRO_HAPTIC *));
-
-/* Sets the gain of the haptic device if supported. Gain is much like volume for sound, 
- it is as if every effect's intensity is multiplied by it. Gain is a value between 
- 0.0 and 1.0. Returns true if set sucessfully, false if not.*/
-AL_FUNC(bool,   al_set_haptic_gain         , (ALLEGRO_HAPTIC *, double gain));
-/* Returns the current gain of the device. */
-AL_FUNC(double, al_get_haptic_gain         , (ALLEGRO_HAPTIC *));
-
-
-/* Returns the maximum amount of haptic effects that can be uploaded to the device. */
-AL_FUNC(int,    al_get_num_haptic_effects  , (ALLEGRO_HAPTIC *));
-
-/* Returns true if the haptic device can play the haptic effect as given, false if not. */
-AL_FUNC(bool,   al_is_haptic_effect_ok     , (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *));
-
-/* Uploads the haptic effect to the device. In play_id, a handle is stored that is 
- a reference to be used to control playback of the effect. */
-AL_FUNC(bool,   al_upload_haptic_effect    , (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, ALLEGRO_HAPTIC_EFFECT_ID * play_id));
-
-/* Plays back a previously uploaded haptic effect. */
-AL_FUNC(bool,   al_play_haptic_effect      , (ALLEGRO_HAPTIC_EFFECT_ID *, int loop));
-
-/* Uploads and immediately plays back the haptic effect to the device. */
-AL_FUNC(bool,   al_upload_and_play_haptic_effect , (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, int loop, ALLEGRO_HAPTIC_EFFECT_ID * play_id));
-
-/* Stops playing a haptic effect . */
-AL_FUNC(bool,   al_stop_haptic_effect      , (ALLEGRO_HAPTIC_EFFECT_ID *));
-
-/* Returns true if the haptic effect is playing or false if not or if stopped. */
-AL_FUNC(bool,   al_is_haptic_effect_playing, (ALLEGRO_HAPTIC_EFFECT_ID *));
-
-/* Releases the haptic effect from the device it has been uploaded to, allowing for 
- other effects to be uploaded. */
-AL_FUNC(bool,   al_release_haptic_effect, (ALLEGRO_HAPTIC_EFFECT_ID *));
-
-/* Uploads a simple rumble effect to the haptic device and starts playback immediately.
- */
-AL_FUNC(bool,   al_rumble_haptic, (ALLEGRO_HAPTIC *, double intensity, double duration, ALLEGRO_HAPTIC_EFFECT_ID *));
-
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/include/allegro5/internal/aintern_haptic.h b/include/allegro5/internal/aintern_haptic.h
deleted file mode 100644
index ebce39c..0000000
--- a/include/allegro5/internal/aintern_haptic.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef __al_included_allegro5_aintern_haptic_h
-#define __al_included_allegro5_aintern_haptic_h
-
-#include "allegro5/haptic.h"
-
-#include "allegro5/internal/aintern_driver.h"
-#include "allegro5/internal/aintern_events.h"
-
-#ifdef __cplusplus
-   extern "C" {
-#endif
-
-/* Haptic devices driver virtual table.  */
-typedef struct ALLEGRO_HAPTIC_DRIVER
-{
-   int          hapdrv_id;
-   const char * hapdrv_name;
-   const char * hapdrv_desc;
-   const char * hapdrv_ascii_name;
-   AL_METHOD(bool, init_haptic, (void));
-   AL_METHOD(void, exit_haptic, (void));
-   
-   AL_METHOD(bool, is_mouse_haptic   , (ALLEGRO_MOUSE *));
-   AL_METHOD(bool, is_joystick_haptic, (ALLEGRO_JOYSTICK *));
-   AL_METHOD(bool, is_keyboard_haptic, (ALLEGRO_KEYBOARD *));
-   AL_METHOD(bool, is_display_haptic , (ALLEGRO_DISPLAY *));
-   AL_METHOD(bool, is_touch_input_haptic , (ALLEGRO_TOUCH_INPUT *));
-   
-   AL_METHOD(ALLEGRO_HAPTIC *, get_from_mouse   , (ALLEGRO_MOUSE *));
-   AL_METHOD(ALLEGRO_HAPTIC *, get_from_joystick, (ALLEGRO_JOYSTICK *));
-   AL_METHOD(ALLEGRO_HAPTIC *, get_from_keyboard, (ALLEGRO_KEYBOARD *));
-   AL_METHOD(ALLEGRO_HAPTIC *, get_from_display , (ALLEGRO_DISPLAY *));
-   AL_METHOD(ALLEGRO_HAPTIC *, get_from_touch_input, (ALLEGRO_TOUCH_INPUT *));
-
-   AL_METHOD(bool  , get_active        , (ALLEGRO_HAPTIC *)); 
-   AL_METHOD(int   , get_capabilities  , (ALLEGRO_HAPTIC *));   
-   AL_METHOD(double, get_gain          , (ALLEGRO_HAPTIC *));
-   AL_METHOD(bool  , set_gain          , (ALLEGRO_HAPTIC *, double));
-   AL_METHOD(int   , get_num_effects   , (ALLEGRO_HAPTIC *));   
-   
-   AL_METHOD(bool, is_effect_ok      , (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *));
-   AL_METHOD(bool, upload_effect     , (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, ALLEGRO_HAPTIC_EFFECT_ID *));
-   AL_METHOD(bool, play_effect       , (ALLEGRO_HAPTIC_EFFECT_ID *, int));
-   AL_METHOD(bool, stop_effect       , (ALLEGRO_HAPTIC_EFFECT_ID *));   
-   AL_METHOD(bool, is_effect_playing , (ALLEGRO_HAPTIC_EFFECT_ID *));   
-   AL_METHOD(bool, release_effect    , (ALLEGRO_HAPTIC_EFFECT_ID *));
-   AL_METHOD(bool, release           , (ALLEGRO_HAPTIC *));
-   
-} ALLEGRO_HAPTIC_DRIVER;
-
-
-extern ALLEGRO_HAPTIC_DRIVER * _al_haptic_driver;
-
-
-
-/* macros for constructing the driver list */
-#define _AL_BEGIN_HAPTIC_DRIVER_LIST                         \
-   _AL_DRIVER_INFO _al_haptic_driver_list[] =                \
-   {
-
-#define _AL_END_HAPTIC_DRIVER_LIST                           \
-      {  0,                NULL,                false }      \
-   };
-
-#define _AL_HAPTIC_INFO_NAME_MAX            256
-   
-/* Can upload at most 32 haptic effects at the same time. */   
-#define _AL_HAPTIC_EFFECT_PLAYBACK_MAX      32    
-
-   
-#define _AL_HAPTIC_FROM_JOYSTICK        1
-#define _AL_HAPTIC_FROM_MOUSE           2
-#define _AL_HAPTIC_FROM_KEYBOARD        3
-#define _AL_HAPTIC_FROM_DISPLAY         4
-#define _AL_HAPTIC_FROM_TOUCH_INPUT     5
-
-
-struct ALLEGRO_HAPTIC
-{
-  int    from;
-  void * device;
-  double gain;
-};
-
-void _al_generate_haptic_event(ALLEGRO_EVENT *event);
-
-#ifdef __cplusplus
-   }
-#endif
-
-#endif
-
-/* vi ts=8 sts=3 sw=3 et */
diff --git a/include/allegro5/internal/aintern_system.h b/include/allegro5/internal/aintern_system.h
index ee54836..669a97c 100644
--- a/include/allegro5/internal/aintern_system.h
+++ b/include/allegro5/internal/aintern_system.h
@@ -5,7 +5,6 @@
 #include "allegro5/internal/aintern_display.h"
 #include "allegro5/internal/aintern_dtor.h"
 #include "allegro5/internal/aintern_events.h"
-#include "allegro5/internal/aintern_haptic.h"
 #include "allegro5/internal/aintern_joystick.h"
 #include "allegro5/internal/aintern_keyboard.h"
 #include "allegro5/internal/aintern_mouse.h"
@@ -27,7 +26,6 @@ struct ALLEGRO_SYSTEM_INTERFACE
    ALLEGRO_MOUSE_DRIVER *(*get_mouse_driver)(void);
    ALLEGRO_TOUCH_INPUT_DRIVER *(*get_touch_input_driver)(void);
    ALLEGRO_JOYSTICK_DRIVER *(*get_joystick_driver)(void);
-   ALLEGRO_HAPTIC_DRIVER *(*get_haptic_driver)(void);   
    int (*get_num_display_modes)(void);
    ALLEGRO_DISPLAY_MODE *(*get_display_mode)(int index, ALLEGRO_DISPLAY_MODE *mode);
    void (*shutdown_system)(void);
diff --git a/include/allegro5/platform/aintunix.h b/include/allegro5/platform/aintunix.h
index 2863df2..d08cc72 100644
--- a/include/allegro5/platform/aintunix.h
+++ b/include/allegro5/platform/aintunix.h
@@ -74,15 +74,6 @@ void _al_unix_stop_watching_fd(int fd);
 AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_linux);
 #endif
 
-/* lhaptic.c */
-/* This isn't in aintlnx.h because it's needed for the X11 port as well. */
-#define _ALLEGRO_HAPDRV_LINUX    AL_ID('L','N','X','H')
-
-#ifdef ALLEGRO_HAVE_LINUX_HAPTIC_H
-AL_VAR(struct ALLEGRO_HAPTIC_DRIVER, _al_hapdrv_linux);
-#endif
-
-
 #ifdef __cplusplus
    }
 #endif
diff --git a/lib/Headers/allegro5/haptic.h b/lib/Headers/allegro5/haptic.h
deleted file mode 100644
index 7463bba..0000000
--- a/lib/Headers/allegro5/haptic.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/*         ______   ___    ___
- *        /\  _  \ /\_ \  /\_ \
- *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
- *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
- *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
- *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
- *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
- *                                           /\____/
- *                                           \_/__/
- *
- *      Haptic (that is, force feedback) routines for Allegro. 
- *      By Beoran (beoran@xxxxxxxxx), 2013.
- *
- *      See readme.txt for copyright information.
- */
-
-#ifndef __al_included_allegro5_haptic_h
-#define __al_included_allegro5_haptic_h
-
-#include "allegro5/base.h"
-#include "allegro5/events.h"
-#include "allegro5/mouse.h"
-#include "allegro5/joystick.h"
-
-#ifdef __cplusplus
-   extern "C" {
-#endif
-
-/* Enum: ALLEGRO_HAPTIC_CONSTANTS
- */
-enum ALLEGRO_HAPTIC_CONSTANTS 
-{ 
-  ALLEGRO_HAPTIC_RUMBLE       = 1 << 0,
-  ALLEGRO_HAPTIC_PERIODIC     = 1 << 1,
-  ALLEGRO_HAPTIC_CONSTANT     = 1 << 2,
-  ALLEGRO_HAPTIC_SPRING       = 1 << 3,
-  ALLEGRO_HAPTIC_FRICTION     = 1 << 4,
-  ALLEGRO_HAPTIC_DAMPER       = 1 << 5,
-  ALLEGRO_HAPTIC_INERTIA      = 1 << 6,
-  ALLEGRO_HAPTIC_RAMP         = 1 << 7,
-  ALLEGRO_HAPTIC_SQUARE       = 1 << 8,
-  ALLEGRO_HAPTIC_TRIANGLE     = 1 << 9,
-  ALLEGRO_HAPTIC_SINE         = 1 << 10,
-  ALLEGRO_HAPTIC_SAW_UP       = 1 << 11,
-  ALLEGRO_HAPTIC_SAW_DOWN     = 1 << 12,
-  ALLEGRO_HAPTIC_CUSTOM       = 1 << 13,  
-  ALLEGRO_HAPTIC_GAIN         = 1 << 14,   
-  ALLEGRO_HAPTIC_ANGLE        = 1 << 15,
-  ALLEGRO_HAPTIC_RADIUS       = 1 << 16,
-  ALLEGRO_HAPTIC_AZIMUTH      = 1 << 17,
-};
-
-
-
-/* Type: ALLEGRO_HAPTIC
- */
-typedef struct ALLEGRO_HAPTIC ALLEGRO_HAPTIC;
-
-/* Direction of a haptic effect. Angle is a value between 0 and 2*M_PI.
- * An angle 0 means oriented towards the user, M_PI is away from the user 
- * (towards the screen). Angle is only supported if the device capabilities include
- * ALLEGRO_HAPTIC_ANGLE.  
- * Radius (if supported ) is the distance of the effect from the user 
- * as a value between 0 and 1. Normally it is 0. Radius is only supported if the 
- * device capabilities include ALLEGRO_HAPTIC_RADIUS .  
- * Azimuth is the angle of elevation, between -M_PI/2 and M_PI/2. 0 points to the 
- * horizontal plane, -M_PI/2 points down, and M_PI/2 points up.
- * Azimuth is only supported if the device capabilities include 
- * ALLEGRO_HAPTIC_AZIMUTH.
- * 
- */
-struct ALLEGRO_HAPTIC_DIRECTION 
-{
-  double angle; 
-  double radius;
-  double azimuth;
-};
-
-/* In all of the following structs, the doubles that express duration represent 
- * time in seconds. The double that represent levels of intensity are between 0.0 
- * and 1.0 that mean no effect and full 100% effect. */
-
-/* Delay to start the replay and duration of the replay, expressed  in seconds. */
-struct ALLEGRO_HAPTIC_REPLAY 
-{
-    double length;
-    double delay;
-};
-
-/* Envelope of the effect. */
-struct ALLEGRO_HAPTIC_ENVELOPE 
-{
-    double attack_length;
-    double attack_level;
-    double fade_length;
-    double fade_level;
-};
-
-/* Constant effect.  Level is between 0.0 and 1.0. */
-struct ALLEGRO_HAPTIC_CONSTANT_EFFECT 
-{
-    double level;
-    struct ALLEGRO_HAPTIC_ENVELOPE envelope;
-};
-
-/* Ramp effect. Both start_level and end level are between 0.0 and 1.0.  */
-struct ALLEGRO_HAPTIC_RAMP_EFFECT 
-{
-    double start_level;
-    double end_level;
-    struct ALLEGRO_HAPTIC_ENVELOPE envelope;
-};
-
-/* Condition effect. */
-struct ALLEGRO_HAPTIC_CONDITION_EFFECT 
-{
-    double right_saturation;
-    double left_saturation;
-    double right_coeff;
-    double left_coeff;
-    double deadband;
-    double center;
-};
-
-/* Periodic (wave) effect. */
-struct ALLEGRO_HAPTIC_PERIODIC_EFFECT 
-{
-    int waveform;
-    double period;
-    double magnitude;
-    double offset;
-    double phase;
-    
-    struct ALLEGRO_HAPTIC_ENVELOPE envelope;
-    int    custom_len;
-    double *custom_data;
-};
-
-/* Simple rumble effect with a magnitude between 0.0 and 1.0 for both 
- the strong and the weak rumble motors in the haptic device.  */
-struct ALLEGRO_HAPTIC_RUMBLE_EFFECT 
-{
-    double strong_magnitude;
-    double weak_magnitude;
-};
-
-union ALLEGRO_HAPTIC_EFFECT_UNION 
-{
-    struct ALLEGRO_HAPTIC_CONSTANT_EFFECT   constant;
-    struct ALLEGRO_HAPTIC_RAMP_EFFECT       ramp;
-    struct ALLEGRO_HAPTIC_PERIODIC_EFFECT   periodic;
-    struct ALLEGRO_HAPTIC_CONDITION_EFFECT  condition; 
-    struct ALLEGRO_HAPTIC_RUMBLE_EFFECT     rumble;
-};
-
-/* Type: ALLEGRO_HAPTIC_EFFECT
- */
-struct ALLEGRO_HAPTIC_EFFECT 
-{
-  
-    int                                type;
-    struct ALLEGRO_HAPTIC_DIRECTION    direction;
-    struct ALLEGRO_HAPTIC_REPLAY       replay;
-    union ALLEGRO_HAPTIC_EFFECT_UNION  data; 
-};
-
-typedef struct ALLEGRO_HAPTIC_EFFECT ALLEGRO_HAPTIC_EFFECT;
-
-
-/* Type: ALLEGRO_HAPTIC_EFFECT_ID
- */
-typedef struct ALLEGRO_HAPTIC_EFFECT_ID ALLEGRO_HAPTIC_EFFECT_ID;
-
-struct ALLEGRO_HAPTIC_EFFECT_ID 
-{
-  ALLEGRO_HAPTIC        * _haptic;
-  ALLEGRO_HAPTIC_EFFECT * _effect;
-  int                     _id;
-  int                     _handle;
-  bool                    _playing;  
-  double                  _started;
-  int                     _loops; 
-};
-
-
-/* Installs the haptic (force feedback) device subsystem. */
-AL_FUNC(bool,             al_install_haptic          , (void));
-/* Uninstalls the haptic device subsystem. */
-AL_FUNC(void,             al_uninstall_haptic        , (void));
-/* Returns true if the haptic device subsystem is installed, false if not. */
-AL_FUNC(bool,             al_is_haptic_installed     , (void));
-
-/* Returns true if the mouse has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_mouse_haptic         , (ALLEGRO_MOUSE *));
-/* Returns true if the joystick has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_joystick_haptic      , (ALLEGRO_JOYSTICK *));
-/* Returns true if the keyboard has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_keyboard_haptic      , (ALLEGRO_KEYBOARD *));
-/* Returns true if the display has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_display_haptic       , (ALLEGRO_DISPLAY *));
-/* Returns true if the touch input has haptic capabilities, false if not.*/
-AL_FUNC(bool,             al_is_touch_input_haptic   , (ALLEGRO_TOUCH_INPUT *));
-
-
-/* If the mouse has haptic capabilities, returns the associated haptic device handle. 
- * Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_mouse    , (ALLEGRO_MOUSE *));
-/* If the mouse has haptic capabilities, returns the associated haptic device handle. 
- * Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_joystick , (ALLEGRO_JOYSTICK *));
-/* If the keyboard has haptic capabilities, returns the associated haptic device handle. 
- * Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_keyboard , (ALLEGRO_KEYBOARD *));
-/* If the display has haptic capabilities, returns the associated haptic device handle. 
- * Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_display  , (ALLEGRO_DISPLAY *));
-/* If the touch input has haptic capabilities, returns the associated haptic 
- * device handle. Otherwise returns NULL. */
-AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_touch_input, (ALLEGRO_TOUCH_INPUT *));
-
-/* Releases the haptic device when it's not needed anymore. Should also be used in 
- * case the joystick configuration changed, such as when a joystick is hot plugged.  
- */
-AL_FUNC(bool, al_release_haptic, (ALLEGRO_HAPTIC *));
-
-
-
-/* Returns true if the haptic device can currently be used, false if not.*/
-AL_FUNC(bool,   al_get_haptic_active       , (ALLEGRO_HAPTIC *));
-
-/* Returns an integer with or'ed values from ALLEGRO_HAPTIC_CONSTANTS, that if
- set indicate that the haptic device supports the given feature. */
-AL_FUNC(int,    al_get_haptic_capabilities , (ALLEGRO_HAPTIC *));
-
-/* Sets the gain of the haptic device if supported. Gain is much like volume for sound, 
- it is as if every effect's intensity is multiplied by it. Gain is a value between 
- 0.0 and 1.0. Returns true if set sucessfully, false if not.*/
-AL_FUNC(bool,   al_set_haptic_gain         , (ALLEGRO_HAPTIC *, double gain));
-/* Returns the current gain of the device. */
-AL_FUNC(double, al_get_haptic_gain         , (ALLEGRO_HAPTIC *));
-
-
-/* Returns the maximum amount of haptic effects that can be uploaded to the device. */
-AL_FUNC(int,    al_get_num_haptic_effects  , (ALLEGRO_HAPTIC *));
-
-/* Returns true if the haptic device can play the haptic effect as given, false if not. */
-AL_FUNC(bool,   al_is_haptic_effect_ok     , (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *));
-
-/* Uploads the haptic effect to the device. In play_id, a handle is stored that is 
- a reference to be used to control playback of the effect. */
-AL_FUNC(bool,   al_upload_haptic_effect    , (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, ALLEGRO_HAPTIC_EFFECT_ID * play_id));
-
-/* Plays back a previously uploaded haptic effect. */
-AL_FUNC(bool,   al_play_haptic_effect      , (ALLEGRO_HAPTIC_EFFECT_ID *, int loop));
-
-/* Uploads and immediately plays back the haptic effect to the device. */
-AL_FUNC(bool,   al_upload_and_play_haptic_effect , (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, int loop, ALLEGRO_HAPTIC_EFFECT_ID * play_id));
-
-/* Stops playing a haptic effect . */
-AL_FUNC(bool,   al_stop_haptic_effect      , (ALLEGRO_HAPTIC_EFFECT_ID *));
-
-/* Returns true if the haptic effect is playing or false if not or if stopped. */
-AL_FUNC(bool,   al_is_haptic_effect_playing, (ALLEGRO_HAPTIC_EFFECT_ID *));
-
-/* Releases the haptic effect from the device it has been uploaded to, allowing for 
- other effects to be uploaded. */
-AL_FUNC(bool,   al_release_haptic_effect, (ALLEGRO_HAPTIC_EFFECT_ID *));
-
-/* Uploads a simple rumble effect to the haptic device and starts playback immediately.
- */
-AL_FUNC(bool,   al_rumble_haptic, (ALLEGRO_HAPTIC *, double intensity, double duration, ALLEGRO_HAPTIC_EFFECT_ID *));
-
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/haptic.c b/src/haptic.c
deleted file mode 100644
index 2dc0e06..0000000
--- a/src/haptic.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*         ______   ___    ___ 
- *        /\  _  \ /\_ \  /\_ \ 
- *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___ 
- *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
- *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
- *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
- *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
- *                                           /\____/
- *                                           \_/__/
- *
- *      New haptic API.
- * 
- *      By Peter Wang.
- *
- *      See readme.txt for copyright information.
- */
-
-/* Title: Joystick routines
- */
-
-
-#define ALLEGRO_NO_COMPATIBILITY
-
-#include "allegro5/allegro.h"
-#include "allegro5/haptic.h"
-#include "allegro5/internal/aintern.h"
-#include "allegro5/internal/aintern_events.h"
-#include "allegro5/internal/aintern_exitfunc.h"
-#include "allegro5/internal/aintern_haptic.h"
-#include "allegro5/internal/aintern_system.h"
-
-
-
-/* the active haptic driver */
-static ALLEGRO_HAPTIC_DRIVER *haptic_driver = NULL;
-
-
-/* Function: al_install_haptic
- */
-bool al_install_haptic(void)
-{
-   ALLEGRO_SYSTEM *sysdrv;
-   ALLEGRO_HAPTIC_DRIVER *hapdrv;
-
-   if (haptic_driver)
-      return true;
-
-   sysdrv = al_get_system_driver();
-   ASSERT(sysdrv);
-
-   /* Currently every platform only has at most one haptic driver. */
-   if (sysdrv->vt->get_haptic_driver) {
-      hapdrv = sysdrv->vt->get_haptic_driver();
-      /* Avoid race condition in case the haptic driver generates an
-       * event right after ->init_haptic.
-       */
-      if (hapdrv && hapdrv->init_haptic()) {
-         haptic_driver = hapdrv;
-         _al_add_exit_func(al_uninstall_haptic, "al_uninstall_haptic");
-         return true;
-      }
-   }
-
-   return false;
-}
-
-
-
-/* Function: al_uninstall_haptic
- */
-void al_uninstall_haptic(void)
-{
-   if (haptic_driver) {
-      /* perform driver clean up */
-      haptic_driver->exit_haptic();
-      haptic_driver = NULL;
-   }
-}
-
-
-/* Function: al_is_haptic_installed
- */
-bool al_is_haptic_installed(void)
-{
-   return (haptic_driver) ? true : false;
-}
-
-
-/* Function: al_is_joystick_haptic
- */
-bool al_is_joystick_haptic(ALLEGRO_JOYSTICK * dev) 
-{
-  ASSERT(dev);
-
-  return haptic_driver->is_joystick_haptic(dev);
-}
-
-/* Function: al_is_mouse_haptic
- */
-bool al_is_mouse_haptic(ALLEGRO_MOUSE * mouse) 
-{
-  ASSERT(mouse);
-
-  return haptic_driver->is_mouse_haptic(mouse);
-}
-
-/* Function: al_is_keyboard_haptic
- */
-bool al_is_keyboard_haptic(ALLEGRO_KEYBOARD * dev) 
-{
-  ASSERT(dev);
-
-  return haptic_driver->is_keyboard_haptic(dev);
-}
-
-/* Function: al_is_display_haptic
- */
-bool al_is_display_haptic(ALLEGRO_DISPLAY * dev) 
-{
-  ASSERT(dev);
-
-  return haptic_driver->is_display_haptic(dev);
-}
-
-
-/* Function: al_get_haptic_from_joystick
- */
-ALLEGRO_HAPTIC * al_get_haptic_from_joystick (ALLEGRO_JOYSTICK * dev) 
-{
-  ASSERT(dev);
-  
-  return haptic_driver->get_from_joystick(dev);
-}
-
-/* Function: al_get_haptic_from_mouse
- */
-ALLEGRO_HAPTIC * al_get_haptic_from_mouse (ALLEGRO_MOUSE * dev) 
-{
-  ASSERT(dev);
-  
-  return haptic_driver->get_from_mouse(dev);
-}
-
-/* Function: al_get_haptic_from_keyboard
- */
-ALLEGRO_HAPTIC * al_get_haptic_from_keyboard(ALLEGRO_KEYBOARD * dev) 
-{
-  ASSERT(dev);
-  
-  return haptic_driver->get_from_keyboard(dev);
-}
-
-/* Function: al_get_haptic_from_display
- */
-ALLEGRO_HAPTIC * al_get_haptic_from_display(ALLEGRO_DISPLAY * dev) 
-{
-  ASSERT(dev);
-  
-  return haptic_driver->get_from_display(dev);
-}
-
-/* Function: al_get_haptic_from_touch_input
- */
-ALLEGRO_HAPTIC * al_get_haptic_from_touch_input(ALLEGRO_TOUCH_INPUT * dev) {
-  ASSERT(dev);
-  
-  return haptic_driver->get_from_touch_input(dev);
-}
-
-/* Function: al_get_haptic_active
- */
-bool al_get_haptic_active(ALLEGRO_HAPTIC *hap)
-{
-   ASSERT(hap);
-   
-   return haptic_driver->get_active(hap);
-}
-
-
-/* Function: al_get_haptic_flags
- */
-int al_get_haptic_capabilities(ALLEGRO_HAPTIC *hap)
-{
-   ASSERT(hap);
-
-   return haptic_driver->get_capabilities(hap);
-}
-
-
-
-/* Function: al_get_haptic_gain
- */
-double al_get_haptic_gain (ALLEGRO_HAPTIC * hap) 
-{
-   ASSERT(hap);
-   
-   return haptic_driver->get_gain(hap);
-}
-
-/* Function: al_set_haptic_gain
- */
-bool al_set_haptic_gain (ALLEGRO_HAPTIC * hap, double gain) 
-{
-  ASSERT(hap);
-     
-  return haptic_driver->set_gain(hap, gain);
-}
-
-/* Function: al_get_num_haptic_effects
- */
-int al_get_num_haptic_effects (ALLEGRO_HAPTIC * hap) 
-{
-   ASSERT(hap);
-
-   return haptic_driver->get_num_effects(hap);
-}
-
-/* Function: al_is_haptic_effect_ok
- */
-bool al_is_haptic_effect_ok(ALLEGRO_HAPTIC * hap, ALLEGRO_HAPTIC_EFFECT * effect) 
-{
-  ASSERT(hap);
-     
-  return haptic_driver->is_effect_ok(hap, effect);
-}
-
-
-/* Function: al_upload_haptic_effect 
- */
-bool al_upload_haptic_effect(ALLEGRO_HAPTIC * hap, ALLEGRO_HAPTIC_EFFECT * effect,  ALLEGRO_HAPTIC_EFFECT_ID * id) 
-{
-  ASSERT(hap);  
-  
-  return haptic_driver->upload_effect(hap, effect, id);
-}
-
-
-/* Function: al_play_haptic_effect
- */
-bool al_play_haptic_effect (ALLEGRO_HAPTIC_EFFECT_ID * id, int loop) 
-{
-  return haptic_driver->play_effect(id, loop);
-}
-
-
-/* Function: al_upload_and_play_haptic_effect
- */
-bool al_upload_and_play_haptic_effect 
-(ALLEGRO_HAPTIC * hap, ALLEGRO_HAPTIC_EFFECT * effect , int loop, ALLEGRO_HAPTIC_EFFECT_ID * id) 
-{
-  if (!al_upload_haptic_effect(hap, effect, id)) return false;
-  return al_play_haptic_effect(id, loop);
-}
-
-
-/* Function: al_stop_haptic_effect
- */
-bool al_stop_haptic_effect (ALLEGRO_HAPTIC_EFFECT_ID * id) 
-{
-    return haptic_driver->stop_effect(id);
-}
-
-/* Function: al_is_haptic_effect_playing
- */
-bool al_is_haptic_effect_playing (ALLEGRO_HAPTIC_EFFECT_ID * id) 
-{
-  return haptic_driver->is_effect_playing(id);
-}
-
-
-/* Function: al_rumble_haptic
- */
-bool al_rumble_haptic (ALLEGRO_HAPTIC * hap,  double intensity, double duration,  ALLEGRO_HAPTIC_EFFECT_ID * id) {
-  ALLEGRO_HAPTIC_EFFECT effect;
-  effect.type                           = ALLEGRO_HAPTIC_RUMBLE;
-  effect.data.rumble.strong_magnitude   = intensity;
-  effect.data.rumble.weak_magnitude     = intensity;  
-  effect.replay.delay                   = 0.0;
-  effect.replay.length                  = duration;
-  return al_upload_and_play_haptic_effect(hap, &effect, 1, id);
-}
-
-
-/* Function: al_release_haptic_effect 
- */
-bool al_release_haptic_effect (ALLEGRO_HAPTIC_EFFECT_ID * id) 
-{
-  return haptic_driver->release_effect(id);
-}
-
-
-/* Function: al_release_haptic
- */
-bool al_release_haptic(ALLEGRO_HAPTIC * haptic) 
-{
-  return haptic_driver->release(haptic);
-}
-
-
-
-
-
diff --git a/src/linux/lhaptic.c b/src/linux/lhaptic.c
deleted file mode 100644
index 0b3366f..0000000
--- a/src/linux/lhaptic.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*         ______   ___    ___ 
- *        /\  _  \ /\_ \  /\_ \ 
- *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___ 
- *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
- *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
- *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
- *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
- *                                           /\____/
- *                                           \_/__/
- *
- *      Linux haptic (force-feedback) device driver.
- *
- *      By Beoran.
- * 
- *      See readme.txt for copyright information.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <linux/input.h>
-#include <fcntl.h>      
-#include <limits.h>     
-#include <errno.h>      
-#include <math.h>
-#include <glob.h>
-
-
-#define ALLEGRO_NO_KEY_DEFINES
-#define ALLEGRO_NO_COMPATIBILITY
-
-#include "allegro5/allegro.h"
-#include "allegro5/joystick.h"
-#include "allegro5/haptic.h"
-#include "allegro5/path.h"
-#include "allegro5/platform/alplatf.h"
-#include "allegro5/internal/aintern.h"
-#include "allegro5/internal/aintern_events.h"
-#include "allegro5/internal/aintern_haptic.h"
-#include "allegro5/internal/aintern_ljoynu.h"
-#include "allegro5/platform/aintunix.h"
-
-
-
-
-#if defined(ALLEGRO_HAVE_SYS_INOTIFY_H) && defined(ALLEGRO_HAVE_SYS_TIMERFD_H)
-   #define SUPPORT_HOTPLUG
-   #include <sys/inotify.h>
-   #include <sys/timerfd.h>
-#endif
-
-ALLEGRO_DEBUG_CHANNEL("lhaptic");
-
-/* Support at most 32 haptic devices. */
-#define HAPTICS_MAX             32
-/* Use dumb char buffers of 100 characters. whihc is "enough 
- *for everyone" for now. :p */
-#define HAPTICS_BUF_MAX         1000
-
-/* Support at most 16 effects per device. */
-#define HAPTICS_EFFECTS_MAX     16
-
-/* Tests if a bit in a byte array is set. */
-#define test_bit(bit, array)  (array [bit / (sizeof(long) * 8)] & (1 << (bit % (8 * sizeof(long)) )))
-
-
-typedef struct ALLEGRO_HAPTIC_LINUX
-{
-   struct ALLEGRO_HAPTIC parent;
-   int in_use;
-   int config_state;
-   bool marked;
-   int fd;
-   char device_name[HAPTICS_BUF_MAX];
-   int state;
-   char name[HAPTICS_BUF_MAX];
-   int flags;
-   int effects[HAPTICS_EFFECTS_MAX];
-} ALLEGRO_HAPTIC_LINUX;
-
-
-
-static bool lhap_init_haptic(void);
-static void lhap_exit_haptic(void);
-
-
-
-
-static bool lhap_is_mouse_haptic(ALLEGRO_MOUSE * dev);
-static bool lhap_is_joystick_haptic(ALLEGRO_JOYSTICK *);
-static bool lhap_is_keyboard_haptic(ALLEGRO_KEYBOARD * dev);
-static bool lhap_is_display_haptic(ALLEGRO_DISPLAY * dev);
-static bool lhap_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT * dev);
-
-static ALLEGRO_HAPTIC * lhap_get_from_mouse(ALLEGRO_MOUSE *dev);
-static ALLEGRO_HAPTIC * lhap_get_from_joystick(ALLEGRO_JOYSTICK *dev);
-static ALLEGRO_HAPTIC * lhap_get_from_keyboard(ALLEGRO_KEYBOARD *dev);
-static ALLEGRO_HAPTIC * lhap_get_from_display(ALLEGRO_DISPLAY *dev);
-static ALLEGRO_HAPTIC * lhap_get_from_touch_input(ALLEGRO_TOUCH_INPUT *dev);
-
-static bool lhap_release(ALLEGRO_HAPTIC * haptic);
-
-static bool   lhap_get_active(ALLEGRO_HAPTIC * hap);
-static int    lhap_get_capabilities(ALLEGRO_HAPTIC * dev);   
-static double lhap_get_gain(ALLEGRO_HAPTIC * dev);
-static bool   lhap_set_gain(ALLEGRO_HAPTIC * dev, double);
-static int    lhap_get_num_effects(ALLEGRO_HAPTIC * dev);   
-
-static bool lhap_is_effect_ok(ALLEGRO_HAPTIC *dev, ALLEGRO_HAPTIC_EFFECT *eff);
-static bool lhap_upload_effect(ALLEGRO_HAPTIC *dev, ALLEGRO_HAPTIC_EFFECT *eff, ALLEGRO_HAPTIC_EFFECT_ID * id);
-static bool lhap_play_effect(ALLEGRO_HAPTIC_EFFECT_ID * id, int loop);
-static bool lhap_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID * id);
-static bool lhap_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID * id);
-static bool lhap_release_effect(ALLEGRO_HAPTIC_EFFECT_ID * id);
-
-/* The haptics driver vtable. */
-ALLEGRO_HAPTIC_DRIVER hapdrv_linux = 
-{
-   _ALLEGRO_HAPDRV_LINUX,
-   "",
-   "",
-   "Linux haptic(s)",
-   lhap_init_haptic,
-   lhap_exit_haptic,
-   
-   lhap_is_mouse_haptic,
-   lhap_is_joystick_haptic,
-   lhap_is_keyboard_haptic,
-   lhap_is_display_haptic,
-   lhap_is_touch_input_haptic,
-      
-   lhap_get_from_mouse,
-   lhap_get_from_joystick,
-   lhap_get_from_keyboard,
-   lhap_get_from_display,
-   lhap_get_from_touch_input,
-   
-   lhap_get_active,
-   lhap_get_capabilities,
-   lhap_get_gain,
-   lhap_set_gain,
-   lhap_get_num_effects,
-   
-   lhap_is_effect_ok,
-   lhap_upload_effect,
-   lhap_play_effect,
-   lhap_stop_effect,
-   lhap_is_effect_playing,
-   lhap_release_effect,
-   
-   lhap_release
-};
-
-ALLEGRO_HAPTIC_DRIVER * _al_haptic_driver = &hapdrv_linux;
-
-ALLEGRO_HAPTIC_DRIVER *_al_linux_haptic_driver(void)
-{
-   return &hapdrv_linux;
-}
-
-
-
-// static unsigned                 num_haptics = 0;  
-/* number of haptics known to the user */
-static ALLEGRO_HAPTIC_LINUX     haptics[HAPTICS_MAX];
-static ALLEGRO_MUTEX          * haptic_mutex = NULL;
-
-
-static bool lhap_init_haptic(void) {
-  int index;
-  haptic_mutex = al_create_mutex();
-  if (!haptic_mutex) return false;
-  for (index = 0; index < HAPTICS_MAX; index ++) {
-    haptics[index].in_use = false;
-  }
-  
-  return true;
-}
-
-static ALLEGRO_HAPTIC_LINUX * lhap_get_available_haptic() {
-  int index;
-  haptic_mutex = al_create_mutex();
-  if(!haptic_mutex) return false;
-  for (index = 0; index < HAPTICS_MAX; index ++) {
-    if(!haptics[index].in_use) {
-      haptics[index].in_use = true;
-      return haptics + index;
-    }
-  }
-  return NULL;
-}
-
-/* Converts a generic haptic device to a linux specific one. */
-static ALLEGRO_HAPTIC_LINUX * lhap_from_al(ALLEGRO_HAPTIC * hap) {
-  void * ptr = hap;
-  if (!ptr) return NULL;
-  return (ALLEGRO_HAPTIC_LINUX *) (ptr - offsetof(ALLEGRO_HAPTIC_LINUX, parent));
-}
-
-static void lhap_exit_haptic() {
-  al_destroy_mutex(haptic_mutex);
-  return;
-}
-
-
-static bool lhap_type2lin(__u16 * res, int type) {
-  ASSERT(res);
-  
-  switch (type) {
-    case ALLEGRO_HAPTIC_RUMBLE          : (*res) = FF_RUMBLE       ; break;
-    case ALLEGRO_HAPTIC_PERIODIC        : (*res) = FF_PERIODIC     ; break;
-    case ALLEGRO_HAPTIC_CONSTANT        : (*res) = FF_CONSTANT     ; break;
-    case ALLEGRO_HAPTIC_SPRING          : (*res) = FF_SPRING       ; break;
-    case ALLEGRO_HAPTIC_FRICTION        : (*res) = FF_FRICTION     ; break;
-    case ALLEGRO_HAPTIC_DAMPER          : (*res) = FF_DAMPER       ; break;
-    case ALLEGRO_HAPTIC_INERTIA         : (*res) = FF_INERTIA      ; break;
-    case ALLEGRO_HAPTIC_RAMP            : (*res) = FF_RAMP         ; break;
-    default: 
-      return false;
-  }
-  return true;
-}
-
-static bool lhap_wave2lin(__u16 * res, int type) {
-  ASSERT(res);
-  
-  switch (type) {
-    case ALLEGRO_HAPTIC_SQUARE          : (*res) = FF_SQUARE       ; break;
-    case ALLEGRO_HAPTIC_TRIANGLE        : (*res) = FF_TRIANGLE     ; break;
-    case ALLEGRO_HAPTIC_SINE            : (*res) = FF_SINE         ; break;
-    case ALLEGRO_HAPTIC_SAW_UP          : (*res) = FF_SAW_UP       ; break;
-    case ALLEGRO_HAPTIC_SAW_DOWN        : (*res) = FF_SAW_DOWN     ; break;
-    case ALLEGRO_HAPTIC_CUSTOM          : (*res) = FF_CUSTOM       ; break;    
-    default: 
-      return false;
-  }
-  return true;
-}
-
-/* converts the time in seconds to a linux compatible time. Return false if
- out of bounds. */
-static bool lhap_time2lin(__u16 * res, double sec) {
-  ASSERT(res); 
-  
-  if (sec < 0.0)        return false; 
-  if (sec > 32.767)     return false;
-  (*res) = (__u16) round(sec * 1000.0);
-  return true;
-}
-
-/* converts the time in seconds to a linux compatible time. 
- * Return false if out of bounds. This one allows negative times. */
-static bool lhap_stime2lin(__s16 * res, double sec) {
-  ASSERT(res); 
-  
-  if (sec < -32.767)    return false; 
-  if (sec > 32.767)     return false;
-  (*res) = (__s16) round(sec * 1000.0);
-  return true;
-}
-
-
-/* Converts replay data to linux. */
-static bool lhap_replay2lin(struct ff_replay * lin, struct ALLEGRO_HAPTIC_REPLAY * al) {
-  if(!lhap_time2lin(&lin->delay, al->delay))  return false;
-  if(!lhap_time2lin(&lin->length, al->length)) return false;
-  return true;
-}
-
-/* Converts the level in range 0.0 to 1.0 to a linux compatible level. 
- * Returns false if out of bounds. */
-static bool lhap_level2lin(__u16 * res, double level) {
-  ASSERT(res);   
-  if (level < 0.0)        return false; 
-  if (level > 1.0)        return false;
-  (*res) = (__u16) round(level * ((double) 0x7fff));
-  return true;
-}
-
-
-/* Converts the level in range -1.0 to 1.0 to a linux compatible level. 
- * Returns false if out of bounds. */
-static bool lhap_slevel2lin(__s16 * res, double level) {
-  ASSERT(res);   
-  if (level < -1.0)        return false; 
-  if (level > 1.0)        return false;
-  (*res) = (__s16) round(level * ((double) 0x7ffe));
-  return true;
-}
-
-
-/* Converts an allegro haptic effect envelope to the linux structure. */
-static bool lhap_envelope2lin(struct ff_envelope * lin, struct ALLEGRO_HAPTIC_ENVELOPE * al) {
-  if (!lhap_time2lin(&lin->attack_length, al->attack_length)) return false;
-  if (!lhap_time2lin(&lin->fade_length  , al->fade_length)) return false;
-  if (!lhap_level2lin(&lin->attack_level, al->attack_level)) return false;
-  if (!lhap_level2lin(&lin->fade_level, al->fade_level)) return false;
-  return true;
-}
-
-/* Converts a rumble effect to linux. */
-static bool lhap_rumble2lin(struct ff_rumble_effect * lin, struct ALLEGRO_HAPTIC_RUMBLE_EFFECT * al) {
-  if(!lhap_level2lin(&lin->strong_magnitude, al->strong_magnitude)) return false;
-  if(!lhap_level2lin(&lin->weak_magnitude  , al->weak_magnitude)) return false;
-  return true;
-}
-
-
-/* Converts a constant effect to linux. */
-static bool lhap_constant2lin(struct ff_constant_effect * lin, struct ALLEGRO_HAPTIC_CONSTANT_EFFECT * al) {
-  if(!lhap_envelope2lin(&lin->envelope , &al->envelope)) return false;
-  if(!lhap_slevel2lin(&lin->level, al->level)) return false;  
-  return true;
-}
-
-/* Converts a ramp effect to linux. */
-static bool lhap_ramp2lin(struct ff_ramp_effect * lin, struct ALLEGRO_HAPTIC_RAMP_EFFECT * al) {
-  if(!lhap_envelope2lin(&lin->envelope , &al->envelope)) return false;
-  if(!lhap_slevel2lin(&lin->start_level, al->start_level)) return false;
-  if(!lhap_slevel2lin(&lin->end_level, al->end_level)) return false;
-  return true;
-}
-
-/* Converts a ramp effect to linux. */
-static bool lhap_condition2lin(struct ff_condition_effect * lin, struct ALLEGRO_HAPTIC_CONDITION_EFFECT * al) {
-  if(!lhap_slevel2lin(&lin->center      , al->center)) return false;
-  if(!lhap_level2lin(&lin->deadband    , al->deadband)) return false;
-  if(!lhap_slevel2lin(&lin->right_coeff , al->right_coeff)) return false;
-  if(!lhap_level2lin(&lin->right_saturation , al->right_saturation)) return false;  
-  if(!lhap_slevel2lin(&lin->left_coeff  , al->left_coeff)) return false;
-  if(!lhap_level2lin(&lin->left_saturation , al->left_saturation)) return false;
-  return true;
-}
-
-
-/* converts a periodic effect  to linux */
-static bool lhap_periodic2lin(struct ff_periodic_effect * lin, struct ALLEGRO_HAPTIC_PERIODIC_EFFECT * al) {
-  if(!lhap_slevel2lin(&lin->magnitude, al->magnitude)) return false;
-  if(!lhap_stime2lin(&lin->offset, al->offset)) return false;
-  if(!lhap_time2lin(&lin->period, al->period)) return false;
-  if(!lhap_time2lin(&lin->phase, al->phase)) return false;
-  if(!lhap_wave2lin(&lin->waveform, al->waveform)) return false; 
-  if (al->custom_data) {
-    /* Custom data is not supported yet, because currently no Linux 
-     * haptic driver supports it. 
-     */
-    return false;
-  }
-  if(!lhap_envelope2lin(&lin->envelope , &al->envelope)) return false;
-  return true;
-}
-
-/* Converts allegro haptic effect to linux haptic effect. */
-static bool lhap_effect2lin(struct ff_effect * lin, ALLEGRO_HAPTIC_EFFECT * al) {
-  if(!lhap_type2lin(&lin->type, al->type)) return false;
-  /* lin_effect->replay = effect->re; */
-  lin->direction = (__u16) round(((double)0xC000 * al->direction.angle) / (2 * M_PI));
-  lin->id        = -1;
-  if(!lhap_replay2lin(&lin->replay, &al->replay)) return false;
-  switch(lin->type) {
-    case FF_RUMBLE:
-      if(!lhap_rumble2lin(&lin->u.rumble, &al->data.rumble)) return false;
-      break;
-    case FF_PERIODIC:      
-      if(!lhap_periodic2lin(&lin->u.periodic, &al->data.periodic)) return false;
-      break;
-    case FF_CONSTANT: 
-      if(!lhap_constant2lin(&lin->u.constant, &al->data.constant)) return false;
-      break;
-    
-    case FF_RAMP:
-    if(!lhap_ramp2lin(&lin->u.ramp, &al->data.ramp)) return false;
-      break;
-    
-    case FF_SPRING:
-    case FF_FRICTION:
-    case FF_DAMPER:
-    case FF_INERTIA:      
-      if(!lhap_condition2lin(&lin->u.condition[0],  &al->data.condition)) return false;
-    break;
-    default:
-      return false;      
-  }
-     
-  return true;
-}
-
-
-
-static bool lhap_get_active(ALLEGRO_HAPTIC * haptic) {
-  ALLEGRO_HAPTIC_LINUX * lhap = lhap_from_al(haptic);
-  return lhap->in_use;
-}
-
-static bool lhap_is_mouse_haptic(ALLEGRO_MOUSE * mouse) {
-  (void) mouse;
-  return false;
-}
-
-#define LONG_BITS (sizeof(long) * 8)
-#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
-/* Tests if a bit in an array of longs is set. */
-#define TEST_BIT(nr, addr) \
-    (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
-
-bool lhap_fd_can_ff(int fd) 
-{
-  long bitmask[NLONGS(EV_CNT)]   = {0};
-      
-  if (ioctl (fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) {
-    return false;
-  }
-  if (TEST_BIT(EV_FF, bitmask)) {
-     return true;
-  }
-  return false;
-}
-
-
-
-
-static bool lhap_is_joystick_haptic(ALLEGRO_JOYSTICK * joy) {
-  // int newfd = -1;
-  ALLEGRO_JOYSTICK_LINUX * ljoy = (ALLEGRO_JOYSTICK_LINUX *) joy;
-  if (!al_is_joystick_installed())      return false;
-  if (!al_get_joystick_active(joy))     return false;  
-  if (ljoy->fd <= 0)                    return false; 
-  // al_cstr(ljoy->device_name)
-  // newfd = open("/dev/input/event8", O_RDWR);  
-  // close(newfd);
-  return lhap_fd_can_ff(ljoy->fd); 
-}
-
-static bool lhap_is_display_haptic (ALLEGRO_DISPLAY * dev) {
-  (void) dev;
-  return false;
-}
-
-static bool lhap_is_keyboard_haptic (ALLEGRO_KEYBOARD * dev) {
-  (void) dev;
-  return false;
-}
-
-static bool lhap_is_touch_input_haptic (ALLEGRO_TOUCH_INPUT * dev) {
-  (void) dev;
-  return false;
-}
-
-
-static ALLEGRO_HAPTIC *  lhap_get_from_mouse(ALLEGRO_MOUSE * mouse) 
-{
-  (void) mouse;
-  return NULL;
-}
-
-
-#define TEST_CAPA(BIT, MASK, CAP, ALCAPA) do { \
-  if (TEST_BIT(FF_PERIODIC, bitmask)) { cap |= ALCAPA; } \
-} while (0)
-  
-
-static bool get_haptic_capabilities(int fd, int * capabilities) {
-
-  int cap = 0;
-  // unsigned long device_bits[(EV_MAX + 8) / sizeof(unsigned long)];  
-  unsigned long bitmask[NLONGS(FF_CNT)]   = {0};
-  if (ioctl (fd, EVIOCGBIT(EV_FF, sizeof(bitmask)), bitmask) < 0) {
-    perror ("EVIOCGBIT ioctl failed");
-    fprintf(stderr, "For fd %d\n", fd);
-    return false;
-  }
-  TEST_CAPA(FF_PERIODIC, bitmask, cap, ALLEGRO_HAPTIC_PERIODIC); 
-  TEST_CAPA(FF_RUMBLE, bitmask, cap, ALLEGRO_HAPTIC_RUMBLE); 
-  TEST_CAPA(FF_CONSTANT, bitmask, cap, ALLEGRO_HAPTIC_CONSTANT);
-  TEST_CAPA(FF_SPRING, bitmask, cap, ALLEGRO_HAPTIC_SPRING); 
-  TEST_CAPA(FF_FRICTION, bitmask, cap, ALLEGRO_HAPTIC_FRICTION);   
-  TEST_CAPA(FF_DAMPER, bitmask, cap, ALLEGRO_HAPTIC_DAMPER);   
-  TEST_CAPA(FF_INERTIA, bitmask, cap, ALLEGRO_HAPTIC_INERTIA); 
-  TEST_CAPA(FF_RAMP, bitmask, cap, ALLEGRO_HAPTIC_RAMP); 
-  TEST_CAPA(FF_SQUARE, bitmask, cap, ALLEGRO_HAPTIC_SQUARE); 
-  TEST_CAPA(FF_TRIANGLE, bitmask, cap, ALLEGRO_HAPTIC_TRIANGLE); 
-  TEST_CAPA(FF_SINE, bitmask, cap, ALLEGRO_HAPTIC_SINE); 
-  TEST_CAPA(FF_SAW_UP, bitmask, cap, ALLEGRO_HAPTIC_SAW_UP); 
-  TEST_CAPA(FF_SAW_DOWN, bitmask, cap, ALLEGRO_HAPTIC_SAW_DOWN); 
-  TEST_CAPA(FF_CUSTOM, bitmask, cap, ALLEGRO_HAPTIC_CUSTOM); 
-  TEST_CAPA(FF_GAIN, bitmask, cap, ALLEGRO_HAPTIC_GAIN); 
-  
-  (*capabilities) = cap;
-  
-  return true;
-}
-
-static ALLEGRO_HAPTIC *  lhap_get_from_joystick(ALLEGRO_JOYSTICK * joy) 
-{
-  int index;
-  ALLEGRO_HAPTIC_LINUX *lhap;
-  ALLEGRO_JOYSTICK_LINUX * ljoy = (ALLEGRO_JOYSTICK_LINUX *) joy;
-  
-  if (!al_is_joystick_haptic(joy)) return NULL;  
-  
-  al_lock_mutex(haptic_mutex);
-  
-  lhap = lhap_get_available_haptic();
-  if (!lhap) return NULL;
-  
-  lhap->parent.device = joy; 
-  lhap->parent.from   = _AL_HAPTIC_FROM_JOYSTICK;
-  
-  
-  lhap->fd            = ljoy->fd;
-  lhap->in_use        = true;
-  for (index = 0; index < HAPTICS_EFFECTS_MAX; index ++) {
-    lhap->effects[index] = -1; // negative means not in use. 
-  }
-  lhap->parent.gain   = 1.0;
-  get_haptic_capabilities(lhap->fd, &lhap->flags);
-  al_unlock_mutex(haptic_mutex);
-  return &(lhap->parent);
-}
-
-static ALLEGRO_HAPTIC * lhap_get_from_display (ALLEGRO_DISPLAY * dev) 
-{
-  (void) dev;
-  return NULL;
-}
-
-static  ALLEGRO_HAPTIC * lhap_get_from_keyboard (ALLEGRO_KEYBOARD * dev) 
-{
-  (void) dev;
-  return NULL;
-}
-
-static ALLEGRO_HAPTIC * lhap_get_from_touch_input (ALLEGRO_TOUCH_INPUT * dev) 
-{
-  (void) dev;
-  return NULL;
-}
-
-
-static int lhap_get_capabilities (ALLEGRO_HAPTIC * dev) 
-{
-  ALLEGRO_HAPTIC_LINUX * lhap = lhap_from_al(dev);
-  return lhap->flags;
-}
-
-
-static double lhap_get_gain(ALLEGRO_HAPTIC * dev) {
-  (void) dev;
-  ALLEGRO_HAPTIC_LINUX * lhap = lhap_from_al(dev);
-  /* Unfortunately there seems to be no API to GET gain, only to set?! 
-   * So, retururn the stored gain.
-   */
-  return lhap->parent.gain;
-}
-
-static bool lhap_set_gain(ALLEGRO_HAPTIC * dev, double gain) {  
-  ALLEGRO_HAPTIC_LINUX * lhap = lhap_from_al(dev);
-  struct input_event ie ;  
-  lhap->parent.gain     = gain;
-  timerclear(&ie.time); 
-  ie.type     = EV_FF;
-  ie.code     = FF_GAIN;
-  ie.value    =  (__s32)((double)0xFFFF * gain);
-  if (write(lhap->fd, &ie, sizeof(ie)) < 0) {
-    return false;
-  }
-  return true;
-}
-
-int lhap_get_num_effects (ALLEGRO_HAPTIC * dev) {
-  ALLEGRO_HAPTIC_LINUX * lhap = lhap_from_al(dev);
-  int n_effects; /* Number of effects the device can play at the same time */
-  
-  if (ioctl(lhap->fd, EVIOCGEFFECTS, &n_effects) < 0) {
-    perror("Cannot check amount of effects");
-    fprintf(stderr, "on FD %d\n", lhap->fd);
-    return HAPTICS_EFFECTS_MAX;
-  } 
-  if (n_effects > HAPTICS_EFFECTS_MAX) return HAPTICS_EFFECTS_MAX;
-  return n_effects;
-}
-
-
-static bool lhap_is_effect_ok(ALLEGRO_HAPTIC * haptic, ALLEGRO_HAPTIC_EFFECT * effect) {
-  struct ff_effect leff;
-  int caps = al_get_haptic_capabilities(haptic);
-  if(!((caps & effect->type) == effect->type)) return false;  
-  if(!lhap_effect2lin(&leff, effect)) return false;
-  return true;  
-}
-
-static double lhap_effect_duration(ALLEGRO_HAPTIC_EFFECT * effect) {
-  return effect->replay.delay + effect->replay.length;   
-}
-
-
-static bool lhap_upload_effect(ALLEGRO_HAPTIC * dev, ALLEGRO_HAPTIC_EFFECT * effect, ALLEGRO_HAPTIC_EFFECT_ID * id) { 
-  ALLEGRO_HAPTIC_LINUX * lhap = lhap_from_al(dev);
-  struct ff_effect leff;
-  int index;
-  int found = -1;
-  
-  ASSERT(dev);
-  ASSERT(id);
-  ASSERT(effect);
-  
-  /* set id's values to indicate failure. */
-  id->_haptic   = NULL;
-  id->_effect   = NULL;
-  id->_id       = -1;
-  id->_handle   = -1;
-  
-  
-  if(!lhap_effect2lin(&leff, effect)) { 
-    return false;
-  }
-  
-  leff.id = -1;
-  
-  /* Find empty spot for effect . */
-  for(index = 0; index < al_get_num_haptic_effects(dev); index ++) {
-    if(lhap->effects[index] < 0) {
-      found = index; 
-      break;
-    }
-  }
-  
-  /* No more space for an effect. */
-  if(found < 0) {
-    return false;
-  }
-  
-  /* Upload effect. */
-  if (ioctl(lhap->fd, EVIOCSFF, &leff) < 0 ) {
-    return false;
-  }
-  
-  id->_haptic   = dev;
-  id->_effect   = effect;
-  id->_id       = found;
-  id->_handle   = leff.id;
-  id->_playing  = false;
-    
-  return true;
-}
-
-static bool lhap_play_effect(ALLEGRO_HAPTIC_EFFECT_ID * id, int loops) {
-  struct input_event     play;
-  ALLEGRO_HAPTIC_LINUX * lhap = (ALLEGRO_HAPTIC_LINUX *) id->_haptic;    
-  int fd                     ;
-  
-  if(!lhap) return false; 
-  
-  fd = lhap->fd;
-  
-  timerclear(&play.time);
-  play.type     = EV_FF;
-  play.code     = id->_handle; 
-  loops         = (loops < 0 ) ? 1 : loops; 
-  play.value    = loops; /* play: 1, stop: 0 */
-   
-  if (write(fd, (const void*) &play, sizeof(play)) < 0) {    
-    perror("Effect play failed.");
-    return false;
-  }
-  id->_playing = true;
-  id->_started = al_get_time(); 
-  id->_loops   = loops;
-  
-  return true;  
-}
-
-
-static bool lhap_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID * id) {
-  struct input_event play;
-  ALLEGRO_HAPTIC_LINUX * lhap = (ALLEGRO_HAPTIC_LINUX *) id->_haptic;    
-  if(!lhap) return false; 
-  
-  play.type     = EV_FF;
-  play.code     = id->_handle; 
-  play.value    = 0;  
-  
-  if (write(lhap->fd, (const void*) &play, sizeof(play)) < 0) {
-    return false;
-  }
-  id->_playing  = false;
-  return true;   
-}
-
-
-static bool lhap_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID * id) {  
-  double duration;
-  ASSERT(id); 
-  
-  if(!id->_playing) return false;
-  /* Since AFAICS there is no Linux API to test this, use a timer to check if the 
-   effect has been playing long enough to be finished or not. */
-  duration = lhap_effect_duration(id->_effect) * id->_loops;
-  if((id->_started + duration) >= al_get_time()) return true;  
-  return false;
-}
-
-static bool lhap_release_effect(ALLEGRO_HAPTIC_EFFECT_ID * id) {
-  ALLEGRO_HAPTIC_LINUX * lhap =  (ALLEGRO_HAPTIC_LINUX *) id->_haptic;  
-  lhap_stop_effect(id);
-  
-  if (ioctl(lhap->fd, EVIOCRMFF, id->_handle) < 0) {
-    return false;
-  }  
-  lhap->effects[id->_id] = -1; // negative means not in use.
-  return true;
-}
-
-
-static bool lhap_release(ALLEGRO_HAPTIC * haptic) {
-  ALLEGRO_HAPTIC_LINUX * lhap = lhap_from_al(haptic);
-  
-  ASSERT(haptic);
-  
-  if(!lhap->in_use) return false;
-  
-  lhap->in_use = false;
-  lhap->fd     = -1;
-  return true;
-}
-
diff --git a/src/macosx/ohaptic.m b/src/macosx/ohaptic.m
deleted file mode 100644
index e69de29..0000000
diff --git a/src/win/whaptic.c b/src/win/whaptic.c
deleted file mode 100644
index e69de29..0000000
diff --git a/src/x/xsystem.c b/src/x/xsystem.c
index 81a6855..ae4c41e 100644
--- a/src/x/xsystem.c
+++ b/src/x/xsystem.c
@@ -173,13 +173,6 @@ static ALLEGRO_JOYSTICK_DRIVER *xglx_get_joystick_driver(void)
    return _al_joystick_driver_list[0].driver;
 }
 
-
-static ALLEGRO_HAPTIC_DRIVER *xglx_get_haptic_driver(void)
-{
-   return _al_haptic_driver;
-}
-
-
 static int xglx_get_num_video_adapters(void)
 {
    ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
@@ -246,7 +239,6 @@ ALLEGRO_SYSTEM_INTERFACE *_al_system_xglx_driver(void)
    xglx_vt->get_keyboard_driver = xglx_get_keyboard_driver;
    xglx_vt->get_mouse_driver = xglx_get_mouse_driver;
    xglx_vt->get_joystick_driver = xglx_get_joystick_driver;
-   xglx_vt->get_haptic_driver     = xglx_get_haptic_driver;
    xglx_vt->get_num_display_modes = xglx_get_num_display_modes;
    xglx_vt->get_display_mode = xglx_get_display_mode;
    xglx_vt->shutdown_system = xglx_shutdown_system;
@@ -259,7 +251,6 @@ ALLEGRO_SYSTEM_INTERFACE *_al_system_xglx_driver(void)
    xglx_vt->ungrab_mouse = _al_xwin_ungrab_mouse;
    xglx_vt->get_path = _al_unix_get_path;
    xglx_vt->inhibit_screensaver = xglx_inhibit_screensaver;
-   
 
    return xglx_vt;
 }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/