]> git.mxchange.org Git - flightgear.git/blobdiff - src/Input/FGLinuxEventInput.cxx
Revert joystick patch. One would have to provide a better one
[flightgear.git] / src / Input / FGLinuxEventInput.cxx
index 382a99c8aa0d2b9c5ef51997ae0d26a72e66d795..03e7e05817ee7629d742810516ce84a6bfabd211 100644 (file)
 #  include <config.h>
 #endif
 
-#include "FGLinuxEventInput.hxx"
-
+#include <cstring>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <poll.h>
 #include <linux/input.h>
 #include <dbus/dbus.h>
+#include <fcntl.h>
+#include "FGLinuxEventInput.hxx"
+
 
 struct TypeCode {
   unsigned type;
@@ -238,7 +242,7 @@ static EventNameByType EVENT_NAME_BY_TYPE;
 
 struct ltstr {
   bool operator()(const char * s1, const char * s2 ) const {
-    return strcmp( s1, s2 ) < 0;
+    return string(s1).compare( s2 ) < 0;
   }
 };
 
@@ -273,6 +277,11 @@ FGLinuxInputDevice::FGLinuxInputDevice() :
 {
 }
 
+static inline bool bitSet( unsigned char * buf, unsigned char bit )
+{
+  return (buf[bit/sizeof(bit)/8] >> (bit%(sizeof(bit)*8))) & 1;
+}
+
 void FGLinuxInputDevice::Open()
 {
   if( fd != -1 ) return;
@@ -280,9 +289,38 @@ void FGLinuxInputDevice::Open()
     throw exception();
   }
 
-  if( GetGrab() && ioctl( fd, EVIOCGRAB, 2 ) != 0 ) {
+  if( GetGrab() && ioctl( fd, EVIOCGRAB, 2 ) == -1 ) {
     SG_LOG( SG_INPUT, SG_WARN, "Can't grab " << devname << " for exclusive access" );
   }
+
+  unsigned char buf[ABS_CNT/sizeof(unsigned char)/8];
+  // get axes maximums
+  if( ioctl( fd, EVIOCGBIT(EV_ABS,ABS_MAX), buf ) == -1 ) {
+    SG_LOG( SG_INPUT, SG_WARN, "Can't get abs-axes for " << devname );
+  } else {
+    for( unsigned i = 0; i < ABS_MAX; i++ ) {
+      if( bitSet( buf, i ) ) {
+        struct input_absinfo ai;
+        if( ioctl(fd, EVIOCGABS(i), &ai) == -1 ) {
+          SG_LOG( SG_INPUT, SG_WARN, "Can't get abs-axes maximums for " << devname );
+          continue;
+        }
+        absinfo[i] = ai;
+      }
+    }
+  }
+}
+
+double FGLinuxInputDevice::Normalize( struct input_event & event ) 
+{
+  if( absinfo.count(event.code) > 0 ) {
+     const struct input_absinfo & ai = absinfo[(unsigned int)event.code];
+     if( ai.maximum == ai.minimum )
+       return 0.0;
+     return ((double)event.value-(double)ai.minimum)/((double)ai.maximum-(double)ai.minimum);
+  } else {
+    return (double)event.value;
+  }
 }
 
 void FGLinuxInputDevice::Close()
@@ -437,7 +475,6 @@ void FGLinuxEventInput::AddHalDevice( const char * udi )
 void FGLinuxEventInput::update( double dt )
 {
   FGEventInput::update( dt );
-
   // index the input devices by the associated fd and prepare
   // the pollfd array by filling in the file descriptor
   struct pollfd fds[input_devices.size()];
@@ -468,6 +505,9 @@ void FGLinuxEventInput::update( double dt )
 
         FGLinuxEventData eventData( event, dt, modifiers );
 
+        if( event.type == EV_ABS )
+          eventData.value = devicesByFd[fds[i].fd]->Normalize( event );
+
         // let the FGInputDevice handle the data
         devicesByFd[fds[i].fd]->HandleEvent( eventData );
       }