]> git.mxchange.org Git - flightgear.git/blobdiff - src/Input/FGLinuxEventInput.cxx
Merge branch 'attenuation' into navaids-radio
[flightgear.git] / src / Input / FGLinuxEventInput.cxx
index 183c7b3ab805c319b84bee27b0c3de372d611ac6..e41f6e195ebc76f01c9e89cc80f4ea5ff56b6872 100644 (file)
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//
-// $Id$
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
 
+#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"
 
 #include <poll.h>
 #include <linux/input.h>
 #include <dbus/dbus.h>
+#include <fcntl.h>
+
+#include <string.h>
 
 struct TypeCode {
   unsigned type;
@@ -217,7 +225,7 @@ static struct enbet {
 };
 
 
-class EventNameByEventType : public map<unsigned,const char*> {
+class EventNameByEventType : public std::map<unsigned,const char*> {
 public:
   EventNameByEventType() {
     for( unsigned i = 0; i < sizeof(EVENT_NAMES_BY_EVENT_TYPE)/sizeof(EVENT_NAMES_BY_EVENT_TYPE[0]); i++ )
@@ -226,7 +234,7 @@ public:
 };
 static EventNameByEventType EVENT_NAME_BY_EVENT_TYPE;
 
-class EventNameByType : public map<TypeCode,const char*> {
+class EventNameByType : public std::map<TypeCode,const char*> {
 public:
   EventNameByType() {
     for( unsigned i = 0; i < sizeof(EVENT_TYPES)/sizeof(EVENT_TYPES[0]); i++ )
@@ -238,11 +246,11 @@ static EventNameByType EVENT_NAME_BY_TYPE;
 
 struct ltstr {
   bool operator()(const char * s1, const char * s2 ) const {
-    return strcmp( s1, s2 ) < 0;
+    return std::string(s1).compare( s2 ) < 0;
   }
 };
 
-class EventTypeByName : public map<const char *,TypeCode,ltstr> {
+class EventTypeByName : public std::map<const char *,TypeCode,ltstr> {
 public:
   EventTypeByName() {
     for( unsigned i = 0; i < sizeof(EVENT_TYPES)/sizeof(EVENT_TYPES[0]); i++ )
@@ -252,7 +260,7 @@ public:
 static EventTypeByName EVENT_TYPE_BY_NAME;
 
 
-FGLinuxInputDevice::FGLinuxInputDevice( string aName, string aDevname ) :
+FGLinuxInputDevice::FGLinuxInputDevice( std::string aName, std::string aDevname ) :
   FGInputDevice(aName),
   devname( aDevname ),
   fd(-1)
@@ -273,35 +281,93 @@ FGLinuxInputDevice::FGLinuxInputDevice() :
 {
 }
 
-static inline bool bitSet( unsigned char * buf, unsigned char bit )
+static inline bool bitSet( unsigned char * buf, unsigned bit )
 {
-  return (buf[bit/sizeof(bit)/8] >> (bit%(sizeof(bit)*8))) & 1;
+  return (buf[bit/sizeof(unsigned char)/8] >> (bit%(sizeof(unsigned char)*8))) & 1;
 }
 
 void FGLinuxInputDevice::Open()
 {
   if( fd != -1 ) return;
   if( (fd = ::open( devname.c_str(), O_RDWR )) == -1 ) { 
-    throw exception();
+    throw std::exception();
   }
 
   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;
+  {
+    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;
+/*
+          SG_LOG( SG_INPUT, SG_INFO, "Axis #" << i <<
+            ": value=" << ai.value << 
+            ": minimum=" << ai.minimum << 
+            ": maximum=" << ai.maximum << 
+            ": fuzz=" << ai.fuzz << 
+            ": flat=" << ai.flat << 
+            ": resolution=" << ai.resolution );
+*/
+
+          // kick an initial event
+          struct input_event event;
+          event.type = EV_ABS;
+          event.code = i;
+          event.value = ai.value;
+          FGLinuxEventData eventData( event, 0, 0 );
+          eventData.value = Normalize( event );
+          HandleEvent(eventData);
+        }
+      }
+    }
+  }
+  {
+    unsigned char mask[KEY_CNT/sizeof(unsigned char)/8];
+    unsigned char flag[KEY_CNT/sizeof(unsigned char)/8];
+    memset(mask,0,sizeof(mask));
+    memset(flag,0,sizeof(flag));
+    if( ioctl( fd, EVIOCGKEY(sizeof(flag)), flag ) == -1 ||
+        ioctl( fd, EVIOCGBIT(EV_KEY, sizeof(mask)), mask ) == -1 ) {
+      SG_LOG( SG_INPUT, SG_WARN, "Can't get keys for " << devname );
+    } else {
+      for( unsigned i = 0; i < KEY_MAX; i++ ) {
+        if( bitSet( mask, i ) ) {
+          struct input_event event;
+          event.type = EV_KEY;
+          event.code = i;
+          event.value = bitSet(flag,i);
+          FGLinuxEventData eventData( event, 0, 0 );
+          HandleEvent(eventData);
+        }
+      }
+    }
+  }
+  {
+    unsigned char buf[SW_CNT/sizeof(unsigned char)/8];
+    if( ioctl( fd, EVIOCGSW(sizeof(buf)), buf ) == -1 ) {
+      SG_LOG( SG_INPUT, SG_WARN, "Can't get switches for " << devname );
+    } else {
+      for( unsigned i = 0; i < SW_MAX; i++ ) {
+        if( bitSet( buf, i ) ) {
+          struct input_event event;
+          event.type = EV_SW;
+          event.code = i;
+          event.value = 1;
+          FGLinuxEventData eventData( event, 0, 0 );
+          HandleEvent(eventData);
         }
-        absinfo[i] = ai;
       }
     }
   }
@@ -374,7 +440,7 @@ const char * FGLinuxInputDevice::TranslateEventName( FGEventData & eventData )
   return EVENT_NAME_BY_TYPE[typeCode];
 }
 
-void FGLinuxInputDevice::SetDevname( string name )
+void FGLinuxInputDevice::SetDevname( std::string name )
 {
   this->devname = name; 
 }
@@ -474,8 +540,8 @@ void FGLinuxEventInput::update( double 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()];
-  map<int,FGLinuxInputDevice*> devicesByFd;
-  map<int,FGInputDevice*>::const_iterator it;
+  std::map<int,FGLinuxInputDevice*> devicesByFd;
+  std::map<int,FGInputDevice*>::const_iterator it;
   int i;
   for( i=0, it = input_devices.begin(); it != input_devices.end(); ++it, i++ ) {
     FGInputDevice* p = (*it).second;
@@ -510,3 +576,4 @@ void FGLinuxEventInput::update( double dt )
     }
   }
 }
+