pingus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pingus-CVS] r3252 - in trunk/pingus: . src/input


From: grumbel at BerliOS
Subject: [Pingus-CVS] r3252 - in trunk/pingus: . src/input
Date: Fri, 28 Sep 2007 03:35:57 +0200

Author: grumbel
Date: 2007-09-28 03:35:56 +0200 (Fri, 28 Sep 2007)
New Revision: 3252

Added:
   trunk/pingus/src/input/evdev_device.cpp
   trunk/pingus/src/input/evdev_device.hpp
Modified:
   trunk/pingus/SConstruct
   trunk/pingus/src/input/evdev_driver.cpp
   trunk/pingus/src/input/manager.cpp
Log:
- added some more evdev code (linux only again)

Modified: trunk/pingus/SConstruct
===================================================================
--- trunk/pingus/SConstruct     2007-09-28 00:48:28 UTC (rev 3251)
+++ trunk/pingus/SConstruct     2007-09-28 01:35:56 UTC (rev 3252)
@@ -358,7 +358,8 @@
     else:
         reports += "  * Linux evdev support: ok\n"
         config_h_defines  += [('HAVE_LINUXEVDEV', 1)]
-        env['optional_sources'] += ['src/input/evdev_driver.cpp']
+        env['optional_sources'] += ['src/input/evdev_driver.cpp',
+                                    'src/input/evdev_device.cpp']
     
     if not env['with_wiimote']:
         reports += "  * Wiimote support: disabled\n"        

Added: trunk/pingus/src/input/evdev_device.cpp
===================================================================
--- trunk/pingus/src/input/evdev_device.cpp     2007-09-28 00:48:28 UTC (rev 
3251)
+++ trunk/pingus/src/input/evdev_device.cpp     2007-09-28 01:35:56 UTC (rev 
3252)
@@ -0,0 +1,298 @@
+//  $Id$
+//
+//  Pingus - A free Lemmings clone
+//  Copyright (C) 2007 Ingo Ruhnke <address@hidden>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#include <assert.h>
+#include <linux/input.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdexcept>
+#include <iostream>
+#include <errno.h>
+
+#include "evdev_device.hpp"
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define OFF(x)  ((x)%BITS_PER_LONG)
+#define BIT(x)  (1UL<<OFF(x))
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define test_bit(bit, array)   ((array[LONG(bit)] >> OFF(bit)) & 1)
+
+namespace Input {
+
+EvdevDevice::EvdevDevice(const std::string& filename)
+  : device(filename)
+{
+  fd = open(device.c_str(), O_RDONLY | O_NONBLOCK);
+
+  if (fd == -1)
+    {
+      throw std::runtime_error(strerror(errno));
+    }
+
+  if (ioctl(fd, EVIOCGVERSION, &version)) 
+    {
+      throw std::runtime_error("Error: EvdevDevice: Couldn't get version");
+    }
+
+  if (1)
+    { // FIXME: Some versions of linux don't have these structs, use arrays 
there
+      struct input_id id;
+      ioctl(fd, EVIOCGID, &id);
+      printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 
0x%x\n",
+             id.bustype, id.vendor, id.product, id.vendor);
+    }
+
+  {  // Get the human readable name
+    char c_name[256] = "unknown";
+    ioctl(fd, EVIOCGNAME(sizeof(c_name)), c_name);
+    name = c_name;
+    std::cout << "Name: " << name << std::endl;
+  }
+
+  { // Read in how many buttons the device has
+    unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
+    memset(bit, 0, sizeof(bit));
+    ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
+
+    for (int i = 0; i < EV_MAX; i++)
+      {
+        if (test_bit(i, bit[0])) 
+          {
+            //printf("  Event type %d (%s)\n", i, events[i] ? events[i] : "?");
+                               
+            if (!i) continue;
+
+            ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
+            for (int j = 0; j < KEY_MAX; j++) 
+              {
+                if (test_bit(j, bit[i])) 
+                  {
+                    if (i == EV_KEY) 
+                      { 
+                        keys.push_back(Key(j));
+                      } 
+                    else if (i == EV_ABS)
+                      { 
+                        // FIXME: Some Linuxes don't have these struct
+                        struct input_absinfo absinfo;
+                        ioctl(fd, EVIOCGABS(j), &absinfo);
+                        // FIXME: we are ignoring absinfo.fuzz and
+                        // absinfo.flat, not sure what they are good for
+                        absolutes.push_back(Absolute(j, absinfo.minimum, 
absinfo.maximum, absinfo.value));
+                      }
+                    else if (i == EV_REL) 
+                      {
+                        relatives.push_back(Relative(j));
+                      }
+                  }
+              }
+          }
+      }
+  }
+}
+
+EvdevDevice::~EvdevDevice()
+{
+}
+
+void
+EvdevDevice::process_absolute(struct input_event& ev)
+{
+  int axis_index = get_absolute_index_by_code(ev.code);
+  if (axis_index != -1)
+    {
+      absolutes[axis_index].pos = ev.value;
+
+#if 0
+      CL_InputEvent e; 
+                                       
+      e.device   = CL_InputDevice(this);
+      e.type     = CL_InputEvent::axis_moved;
+      e.id       = axis_index;
+      e.axis_pos = absolutes[axis_index].get_posf();
+      e.repeat_count = 0;
+
+      sig_axis_move(e);
+#endif
+    }
+}
+
+void
+EvdevDevice::process_relative(struct input_event& ev)
+{
+  int relative_index = get_relative_index_by_code(ev.code);
+
+  relatives[relative_index].pos += ev.value;
+
+#if 0
+  CL_InputEvent e; 
+                               
+  e.device       = CL_InputDevice(this);
+  e.type         = CL_InputEvent::relative_moved;
+  e.id           = relative_index;
+  e.mouse_pos.x  = ev.value;
+  e.mouse_pos.y  = 0;
+  e.axis_pos     = 0;
+  e.repeat_count = 0;
+
+  sig_relative_move(e);
+#endif
+}
+
+void
+EvdevDevice::process_key(struct input_event& ev)
+{
+  int button_index = get_key_index_by_code(ev.code);
+
+  keys[button_index].pressed = ev.value;
+
+#if 0
+  CL_InputEvent e; 
+                       
+  e.device = CL_InputDevice(this);
+  e.id     = button_index;
+  e.repeat_count = 0;
+
+  if (ev.value)
+    {
+      e.type = CL_InputEvent::pressed;
+      sig_key_down(e);
+    }
+  else
+    {
+      e.type = CL_InputEvent::released;
+      sig_key_up(e);
+    }               
+#endif
+}
+
+int
+EvdevDevice::get_relative_index_by_code(int code)
+{
+  for(std::vector<Relative>::size_type i = 0; i != relatives.size(); ++i)
+    if (relatives[i].code == code)
+      return i;
+  return -1;
+}
+
+int
+EvdevDevice::get_key_index_by_code(int code)
+{
+  for(std::vector<Key>::size_type i = 0; i != keys.size(); ++i)
+    if (keys[i].code == code)
+      return i;
+  return -1;
+}
+
+int
+EvdevDevice::get_absolute_index_by_code(int code)
+{
+  for(std::vector<Absolute>::size_type i = 0; i != absolutes.size(); ++i)
+    if (absolutes[i].code == code)
+      return i;
+  return -1;
+}
+
+void
+EvdevDevice::update(float delta)
+{
+  struct input_event ev[64];
+       
+  int rd = read(fd, ev, sizeof(struct input_event) * 64);
+
+  if (rd >= (int) sizeof(struct input_event))
+    {
+      for (int i = 0; i < rd / (int)sizeof(struct input_event); ++i)
+        {
+          std::cout << ev[i].type << " " << ev[i].code << " " << ev[i].value 
<< std::endl;
+
+          switch (ev[i].type)
+            {
+              case EV_ABS:
+                process_absolute(ev[i]);
+                break;
+
+              case EV_REL:
+                process_relative(ev[i]);
+                break;
+
+              case EV_KEY:
+                process_key(ev[i]);
+                break;
+
+              default:
+#if 0
+                if (ev[i].type == EV_SYN) 
+                  {
+                    printf("Event: time %ld.%06ld, -------------- %s 
------------\n",
+                           ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? 
"Config Sync" : "Report Sync" );
+                  }
+                else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || 
ev[i].code == MSC_SCAN)) 
+                  {
+                    printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), 
value %02x\n",
+                           ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
+                           events[ev[i].type] ? events[ev[i].type] : "?",
+                           ev[i].code,
+                           names[ev[i].type] ? (names[ev[i].type][ev[i].code] 
? names[ev[i].type][ev[i].code] : "?") : "?",
+                           ev[i].value);
+                  } 
+                else 
+                  {
+                    printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), 
value %d\n",
+                           ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
+                           events[ev[i].type] ? events[ev[i].type] : "?",
+                           ev[i].code,
+                           names[ev[i].type] ? (names[ev[i].type][ev[i].code] 
? names[ev[i].type][ev[i].code] : "?") : "?",
+                           ev[i].value);
+                  }    
+#endif                  
+                break;
+            }
+        }
+    }
+}
+
+} // namespace Input
+
+#ifdef __TEST__
+// g++ -D__TEST__ evdev_device.cpp -o evdev -Wall -Werror
+int main(int argc, char** argv)
+{
+  if (argc != 2)
+    {
+      std::cout << "Usage: evdev FILENAME" << std::endl;
+    }
+  else
+    {
+      std::cout << "EvdevDevice: " << argv[1] << std::endl;
+
+      Input::EvdevDevice dev(argv[1]);
+      while(true)
+        {
+          dev.update(0.0f);
+        }
+    }
+  return 0;
+}
+
+#endif
+
+/* EOF */


Property changes on: trunk/pingus/src/input/evdev_device.cpp
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: trunk/pingus/src/input/evdev_device.hpp
===================================================================
--- trunk/pingus/src/input/evdev_device.hpp     2007-09-28 00:48:28 UTC (rev 
3251)
+++ trunk/pingus/src/input/evdev_device.hpp     2007-09-28 01:35:56 UTC (rev 
3252)
@@ -0,0 +1,89 @@
+//  $Id$
+//
+//  Pingus - A free Lemmings clone
+//  Copyright (C) 2007 Ingo Ruhnke <address@hidden>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef HEADER_EVDEV_DEVICE_HPP
+#define HEADER_EVDEV_DEVICE_HPP
+
+#include <vector>
+#include <string>
+
+namespace Input {
+
+/** */
+class EvdevDevice
+{
+private:
+  // Absolute Input Event
+  struct Absolute {
+    Absolute(int code_, int min_, int max_, int pos_)
+      : code(code_), min(min_), max(max_), pos(pos_) {}
+
+    int code;
+    int min;
+    int max;
+    int pos;
+
+    inline float get_posf() const {
+      return float(pos - min)/(max - min) * 2.0f - 1.0f;
+    }
+  };
+       
+  // Relative Input Event
+  struct Relative {
+    Relative(int code_) : code(code_), pos(0) {}
+    int code;
+    int pos;
+  };
+
+  // Key Input Event
+  struct Key {
+    Key(int code_) : code(code_), pressed(false) {}
+    int code;
+    bool pressed;
+  };
+
+  int fd;
+  int version;
+
+  std::vector<Relative>   relatives;
+  std::vector<Absolute>   absolutes;
+  std::vector<Key> keys;
+
+  std::string name;
+  std::string device;
+
+public:
+  EvdevDevice(const std::string& filename);
+  ~EvdevDevice();
+  
+  void update(float delta);
+  void process_absolute(struct input_event& ev);
+  void process_relative(struct input_event& ev);
+  void process_key(struct input_event& ev);
+
+  int get_key_index_by_code(int code);
+  int get_relative_index_by_code(int code);
+  int get_absolute_index_by_code(int code);
+};
+
+} // namespace Input
+
+#endif
+
+/* EOF */


Property changes on: trunk/pingus/src/input/evdev_device.hpp
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: trunk/pingus/src/input/evdev_driver.cpp
===================================================================
--- trunk/pingus/src/input/evdev_driver.cpp     2007-09-28 00:48:28 UTC (rev 
3251)
+++ trunk/pingus/src/input/evdev_driver.cpp     2007-09-28 01:35:56 UTC (rev 
3252)
@@ -26,7 +26,7 @@
 }
 
 EvdevDriver::~EvdevDriver() 
-{
+{ 
 }
 
 std::string
@@ -59,7 +59,7 @@
 }
 
 Pointer*
-EvdevDriver::create_pointer (const FileReader& reader, Control* parent)
+EvdevDriver::create_pointer(const FileReader& reader, Control* parent)
 {
   return 0;
 }

Modified: trunk/pingus/src/input/manager.cpp
===================================================================
--- trunk/pingus/src/input/manager.cpp  2007-09-28 00:48:28 UTC (rev 3251)
+++ trunk/pingus/src/input/manager.cpp  2007-09-28 01:35:56 UTC (rev 3252)
@@ -34,6 +34,9 @@
 #ifdef HAVE_LINUXUSBMOUSE
 #  include "usbmouse_driver.hpp"
 #endif
+#ifdef HAVE_LINUXEVDEV
+#  include "evdev_driver.hpp"
+#endif
 #include "manager.hpp"
 
 namespace Input {
@@ -235,6 +238,10 @@
       } else if (name == "usbmouse") {
         driver = new USBMouseDriver();
 #endif
+#ifdef HAVE_LINUXEVDEV
+      } else if (name == "evdev") {
+        driver = new EvdevDriver();
+#endif
 #ifdef HAVE_XINPUT
       } else if (name == "xinput") {
         driver = new XInputDriver();





reply via email to

[Prev in Thread] Current Thread [Next in Thread]