gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] [SCM] Gnash branch, openvg, updated. 7f95ccd6d18c8081eca4


From: Rob Savoye
Subject: [Gnash-commit] [SCM] Gnash branch, openvg, updated. 7f95ccd6d18c8081eca44c606fb2c9cb94755314
Date: Sat, 18 Dec 2010 18:31:15 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, openvg has been updated
       via  7f95ccd6d18c8081eca44c606fb2c9cb94755314 (commit)
       via  3134ec21fae0aef40245796c281cb3872a90b858 (commit)
       via  4a7b3634992ea434ab369c2de8faf645c57f65ec (commit)
       via  e1044ac68c3b414d03a69a029d2305b44179d408 (commit)
       via  fc87019588762d7596119c7b50e18242772398de (commit)
      from  155611ce1b08eaf733112743baa5256eeb5a2be2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=7f95ccd6d18c8081eca44c606fb2c9cb94755314


commit 7f95ccd6d18c8081eca44c606fb2c9cb94755314
Author: Rob Savoye <address@hidden>
Date:   Sat Dec 18 11:30:35 2010 -0700

    add simple test case for input events.

diff --git a/libdevice/events/events.am b/libdevice/events/events.am
index 5cd8c61..71e2392 100644
--- a/libdevice/events/events.am
+++ b/libdevice/events/events.am
@@ -36,3 +36,14 @@ if ENABLE_INPUT_EVENTS
 libgnashdevice_la_SOURCES += events/EventDevice.cpp
 endif
 endif
+
+check_PROGRAMS += test_events 
+test_events_SOURCES = events/test_events.cpp
+test_events_CPPFLAGS = $(AM_CPPFLAGS)
+test_events_LDADD = \
+       libgnashdevice.la \
+       $(EXTRA_EVENTS_LIBS) \
+       $(CURL_LIBS) \
+       $(EVENTS_LIBS) \
+       $(GNASH_LIBS)
+
diff --git a/libdevice/events/test_events.cpp b/libdevice/events/test_events.cpp
index 59590c5..c50f261 100644
--- a/libdevice/events/test_events.cpp
+++ b/libdevice/events/test_events.cpp
@@ -27,6 +27,9 @@
 #include <map>
 #include <cassert>
 #include <regex.h>
+#include <unistd.h>
+#include <signal.h>
+
 #include <boost/assign/list_of.hpp>
 
 #include "log.h"
@@ -42,40 +45,77 @@ using namespace std;
 
 // The debug log used by all the gnash libraries.
 static LogFile& dbglogfile = LogFile::getDefaultInstance();
-    
+
+// Trap a Sig Alarm, so this test doesn't hang forever if there
+// is no input.
+static void
+alarm_handler (int sig)
+{
+    cerr << endl << "Ending test beacuse of no input. This is normal if" << 
endl
+         << "running this in an automated fashion, ie... \"make check\"" << 
endl
+         << "This is an interactive test, not a unit or regression test" << 
endl;
+    exit(0);
+}
+
 int
 main(int argc, char *argv[])
 {
-    // FIXME: for now, always run verbose till this supports command line args
-    dbglogfile.setVerbosity();
-
-    MouseDevice me;
-
-    bool loop = true;
+    struct sigaction act;
+    act.sa_handler = alarm_handler;
+    sigaction (SIGALRM, &act, NULL);
 
+    bool loop = false;
     std::vector<boost::shared_ptr<InputDevice> > inputs
         = InputDevice::scanForDevices();
+    cerr << "Found " << inputs.size() << " input devices" << endl;
     if (inputs.empty()) {
         runtest.fail("InputDevice::scanForDevices()");
-        loop = false;
     } else {
         runtest.pass("InputDevice::scanForDevices()");
+        loop = true;
     }    
     
+    std::vector<boost::shared_ptr<InputDevice> >::iterator it;
+    
+    // check input devices
+    for (it = inputs.begin(); it != inputs.end(); ++it) {
+        boost::shared_ptr<InputDevice> id = *it;
+        cerr << "Found " << id->id() << " device" << endl;
+        if (id->init()) {
+            runtest.pass("InputDevice::init()");
+        } else {
+            runtest.fail("InputDevice::init()()");
+        }
+    }
+
+    cerr << "Starting inactivity timeout to 10 seconds..." << endl;
+    alarm(10);
     // This loops endlessly at the frame rate
     while (loop) {  
+        std::vector<boost::shared_ptr<InputDevice> >::iterator it;
+        // // check input devices
+        for (it = inputs.begin(); it != inputs.end(); ++it) {
+            boost::shared_ptr<InputDevice> id = *it;
+            if (id->check()) {
+                // FIXME: process the input data
+                boost::shared_ptr<InputDevice::input_data_t> ie = 
id->popData();
+#if 1
+                if (ie) {
+                    std::cerr << "Got data: " << ie->pressed;
+                    std::cerr << ", " << ie->key << ", " << ie->modifier;
+                    std::cerr << ", " << ie->x << ", " << ie->y << std::endl;
+                }
+            } else {
+                std::cerr << ".";
+            }
+#endif
+        }
+        
         // wait the "heartbeat" inteval
         sleep(1);    
-        // TODO: Do we need to check the real time slept or is it OK when we 
woke
-        // up early because of some Linux signal sent to our process (and thus
-        // "advance" faster than the "heartbeat" interval)? - Udo
-
-        // check input devices
-        me.check();
-
-        // FIXME: process the input data
-        // boost::shared_ptr<input_event_t> popData();
-    }    
+    }
+    
+    std::cerr << std::endl;
 }
 
 // Local Variables:

http://git.savannah.gnu.org/cgit//commit/?id=3134ec21fae0aef40245796c281cb3872a90b858


commit 3134ec21fae0aef40245796c281cb3872a90b858
Author: Rob Savoye <address@hidden>
Date:   Sat Dec 18 11:30:04 2010 -0700

    Use 0x7 instead of 0x1 for the mouse button mask, so it works with 3 button 
mice.

diff --git a/libdevice/events/MouseDevice.cpp b/libdevice/events/MouseDevice.cpp
index ce1096f..08b2262 100644
--- a/libdevice/events/MouseDevice.cpp
+++ b/libdevice/events/MouseDevice.cpp
@@ -241,7 +241,7 @@ MouseDevice::check()
     // A Touchscreen works similar to a Mouse, but not exactly.
     // At least for the eTurboTouch, it has a different layout
     // in the packet for the location as it has an additional byte
-    btn   = buf[0] & 1;
+    btn   = buf[0] & 0x7;
     if (_type == InputDevice::TOUCHMOUSE) {
         xmove = (buf[1] << 7) | (buf[2]);
         ymove = (buf[3] << 7) | (buf[4]);
@@ -260,7 +260,8 @@ MouseDevice::check()
         xmove = xmove * _gui->getStage()->getStageWidth() / 2048;
         ymove = (2048-ymove) * _gui->getStage()->getStageHeight() / 2048;
 #endif
-    } else {                    // end of InputDevice::MOUSE
+    } else {                    // end of InputDevice::TOUCHMOUSE
+        // PS/2 Mouse
         xmove = buf[1];
         ymove = buf[2];
     

http://git.savannah.gnu.org/cgit//commit/?id=4a7b3634992ea434ab369c2de8faf645c57f65ec


commit 4a7b3634992ea434ab369c2de8faf645c57f65ec
Author: Rob Savoye <address@hidden>
Date:   Sat Dec 18 11:29:06 2010 -0700

    use a std::queue for all input events

diff --git a/libdevice/events/InputDevice.cpp b/libdevice/events/InputDevice.cpp
index b27f782..0a5a4b8 100644
--- a/libdevice/events/InputDevice.cpp
+++ b/libdevice/events/InputDevice.cpp
@@ -77,6 +77,18 @@ InputDevice::init(InputDevice::devicetype_e type, const 
std::string &filespec,
     return init(filespec, size);
 }
 
+boost::shared_ptr<InputDevice::input_data_t>
+InputDevice::popData()
+{
+    boost::shared_ptr<InputDevice::input_data_t> input;
+    if (_data.size()) {
+        // std::cerr << "FIXME: " <<_data.size() << std::endl;
+        input = _data.front();
+        _data.pop();
+    }
+    return input;
+}
+
 void
 InputDevice::addData(bool pressed, key::code key, int modifier, int x, int y)
 {
@@ -88,12 +100,12 @@ InputDevice::addData(bool pressed, key::code key, int 
modifier, int x, int y)
     _newdata->modifier = modifier;
     _newdata->x = x;
     _newdata->y = y;
-#if 1
+#if 0
     std::cerr << "Adding data: " << _newdata->pressed;
     std::cerr << ", " << _newdata->key << ", " << _newdata->modifier;
     std::cerr << ", " << _newdata->x << ", " << _newdata->y << std::endl;
 #endif
-    _data.push_back(_newdata);
+    _data.push(_newdata);
 }
 
 // Read data into the Device input buffer.
diff --git a/libdevice/events/InputDevice.h b/libdevice/events/InputDevice.h
index c1cfce8..ffdb82a 100644
--- a/libdevice/events/InputDevice.h
+++ b/libdevice/events/InputDevice.h
@@ -28,6 +28,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/cstdint.hpp>
 #include <vector>
+#include <queue>
 #include <linux/input.h>
 
 #include "GnashKey.h"
@@ -68,6 +69,8 @@ public:
     } devicetype_e;
     InputDevice();
     virtual ~InputDevice();
+
+    virtual const char *id() = 0;
     
     virtual bool init();
     bool init(devicetype_e type);
@@ -84,7 +87,7 @@ public:
     // Read data into the Device input buffer.
     boost::shared_array<boost::uint8_t> readData(size_t size);
 
-    boost::shared_ptr<input_data_t> popData() { return _data.front();};
+    boost::shared_ptr<input_data_t> popData();
     
     void dump();
 protected:
@@ -99,16 +102,17 @@ protected:
     int                 _button;
     size_t              _position;
     boost::scoped_array<boost::uint8_t> _buffer;
-    std::vector<boost::shared_ptr<input_data_t> > _data;
+    std::queue<boost::shared_ptr<input_data_t> > _data;
 };
 
 class MouseDevice : public InputDevice
 {
 public:
     MouseDevice();
-    virtual bool init();
-    virtual bool init(const std::string &filespec, size_t size);
-    virtual bool check();
+    const char *id() { return "Mouse"; };
+    bool init();
+    bool init(const std::string &filespec, size_t size);
+    bool check();
 
     static std::vector<boost::shared_ptr<InputDevice> > scanForDevices();
     
@@ -119,11 +123,12 @@ public:
 class TouchDevice : public InputDevice
 {
 public:
+    const char *id() { return "TouchScreen"; };
     TouchDevice();
     virtual ~TouchDevice();
-    virtual bool init();
-    virtual bool init(const std::string &filespec, size_t size);
-    virtual bool check();
+    bool init();
+    bool init(const std::string &filespec, size_t size);
+    bool check();
 
     void apply_ts_calibration(float* cx, float* cy, int rawx, int rawy);
     
@@ -138,6 +143,7 @@ class EventDevice : public InputDevice
 {
 public:
     EventDevice();
+    const char *id() { return "InputEvent"; };
     virtual bool init();
     virtual bool init(const std::string &filespec, size_t size);
     virtual bool check();

http://git.savannah.gnu.org/cgit//commit/?id=e1044ac68c3b414d03a69a029d2305b44179d408


commit e1044ac68c3b414d03a69a029d2305b44179d408
Author: Rob Savoye <address@hidden>
Date:   Sat Dec 18 09:31:46 2010 -0700

    new test cases

diff --git a/gui/test_glue.cpp b/gui/test_glue.cpp
new file mode 100644
index 0000000..9b0ace4
--- /dev/null
+++ b/gui/test_glue.cpp
@@ -0,0 +1,336 @@
+// 
+//   Copyright (C) 2010 Free Software Foundation, Inc
+// 
+// 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <fcntl.h>
+#include <iostream>
+#include <string>
+#include <cstdlib>
+#include <vector>
+#include <sstream>
+#include <map>
+#include <cassert>
+#include <regex.h>
+#include <boost/assign/list_of.hpp>
+#include <boost/date_time/date.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+#include "log.h"
+#include "dejagnu.h"
+#include "SWFMatrix.h"
+#include "Renderer.h"
+#include "Transform.h"
+#include "CachedBitmap.h"
+#include "GnashVaapiImage.h"
+#include "GnashVaapiImageProxy.h"
+#include "boost/date_time/posix_time/posix_time.hpp"
+
+#ifdef RENDERER_AGG
+# include "fb/fb_glue_agg.h"
+//# include "gtk/gtk_glue_agg.h"
+#endif
+#ifdef RENDERER_OPENGL
+#endif
+#ifdef RENDERER_OPENVG
+#endif
+#ifdef RENDERER_GLES1
+#endif
+#ifdef RENDERER_GLES2
+#endif
+#ifdef RENDERER_CAIRO
+#endif
+
+TestState runtest;
+
+using namespace gnash; 
+using namespace renderer; 
+using namespace gui; 
+using namespace std;
+using namespace boost::posix_time;
+
+// The debug log used by all the gnash libraries.
+static LogFile& dbglogfile = LogFile::getDefaultInstance();
+
+//------------------------------------------------------------
+
+// Simple class to do nanosecond based timing for performance analysis
+class Timer {
+public:
+    Timer(const std::string &name, bool flag)
+        {
+            _print = flag;
+            _name = name;
+            start();
+        }
+    Timer(const std::string &name) : _print(false) { _name = name; start(); }
+    Timer() : _print(false) { start(); }
+    ~Timer()
+        {
+            stop();
+            if (_print) {
+                cerr << "Total time for " << _name << " was: " << elapsed() << 
endl;
+            }
+        };
+    
+    void start() {
+        _starttime = boost::posix_time::microsec_clock::local_time(); 
+    }
+    
+    void stop() {
+        _stoptime = boost::posix_time::microsec_clock::local_time(); 
+    }
+
+    std::string elapsed() {
+        stringstream ss;
+        time_duration td = _stoptime - _starttime;
+        ss << td.total_nanoseconds() << "ns elapsed";
+        return ss.str();
+    }
+    void setName(const std::string &name) { _name = name; };
+    std::string &getName() { return _name; };
+    
+private:
+    bool _print;
+    std::string _name;
+    boost::posix_time::ptime _starttime;
+    boost::posix_time::ptime _stoptime;
+};
+
+int
+main(int argc, char *argv[])
+{
+    // FIXME: for now, always run verbose till this supports command line args
+    dbglogfile.setVerbosity();
+
+    // Create fake data for the fake framebuffer, This was copied off a
+    // working PC.
+    struct fb_var_screeninfo varinfo;
+    memset(&varinfo, 0, sizeof(struct fb_var_screeninfo));
+    varinfo.xres = 1200;
+    varinfo.yres = 1024;
+    varinfo.xres_virtual = 1280;
+    varinfo.yres_virtual = 1024;
+    varinfo.bits_per_pixel = 32;
+    varinfo.red.offset = 16;
+    varinfo.red.length = 8;
+    varinfo.green.offset = 8;
+    varinfo.green.length = 8;
+    varinfo.blue.offset = 0;
+    varinfo.blue.length = 8;
+    varinfo.width = 4294967295;
+    varinfo.height = 4294967295;
+    
+    size_t memsize = 5242880;
+    struct fb_fix_screeninfo fixinfo = {
+        "test_glue",
+        0,                      // replaced later by drawing_area
+        5242880,                // the memory size
+        0,
+        0,
+        2,
+        1,
+        1, 0,
+        5120,                   // the rowsize
+        4289200128,
+        524288,                 // the framebuffer memory size
+        0,
+        {0, 0, 0}};
+
+    // We're not testing the virtual terminals here, so we just pass 0 as
+    // the file descriptor.
+    FBAggGlue fbag(0);
+
+    // Test the defaults. These need to properly handle an unitialized
+    // Renderer without segfaulting.
+    if (fbag.width() == 0) {
+        runtest.pass("FBAggGlue::width(0)");
+    } else {
+        runtest.fail("FBAggGlue::width(0)");
+    }
+    
+    if (fbag.height() == 0) {
+        runtest.pass("FBAggGlue::height(0)");
+    } else {
+        runtest.fail("FBAggGlue::height(0)");
+    }    
+
+    // These next two will display an error, because the renderer isn't
+    // set but we know that, we want to test if nothiung crashes when
+    // unitilized.
+    SWFRect bounds;
+    fbag.setInvalidatedRegion(bounds);
+    if (fbag.getBounds() == 0) {
+        runtest.pass("FBAggGlue::setInvalidatedRegion(0)");
+    } else {
+        runtest.fail("FBAggGlue::setInvalidatedRegion(0)");
+    }    
+
+    InvalidatedRanges ranges;
+    fbag.setInvalidatedRegions(ranges);
+    if (fbag.getBounds() == 0) {
+        runtest.pass("FBAggGlue::setInvalidatedRegions(0)");
+    } else {
+        runtest.fail("FBAggGlue::setInvalidatedRegions(0)");
+    }    
+
+#if 0
+    fbag.prepDrawingArea(reinterpret_cast<void *>(fixinfo.smem_start));
+    if (fbag.getBounds() == 0) {
+        runtest.pass("FBAggGlue::setInvalidatedRegions(0)");
+    } else {
+        runtest.fail("FBAggGlue::setInvalidatedRegions(0)");
+    }
+#endif
+
+    // This initlizes the device and renderer
+    if (fbag.init(argc, &argv)) {
+        runtest.pass("FBAggGlue::init()");
+    } else {
+        runtest.fail("FBAggGlue::init()");
+    }
+
+    if (fbag.width() > 0) {
+        runtest.pass("FBAggGlue::width()");
+    } else {
+        runtest.fail("FBAggGlue::width()");
+    }
+    
+    if (fbag.height() > 0) {
+        runtest.pass("FBAggGlue::height()");
+    } else {
+        runtest.fail("FBAggGlue::height()");
+    }
+
+    fbag.render();
+}
+
+#ifdef ENABLE_FAKE_FRAMEBUFFER
+// Simulate the ioctls used to get information from the framebuffer
+// driver. Since this is an emulator, we have to set these fields
+// to a reasonable default.
+int
+fakefb_ioctl(int /* fd */, int request, void *data)
+{
+    // GNASH_REPORT_FUNCTION;
+    
+    switch (request) {
+      case FBIOGET_VSCREENINFO:
+      {
+          struct fb_var_screeninfo *ptr =
+              reinterpret_cast<struct fb_var_screeninfo *>(data);
+          // If we are using a simulated framebuffer, the default for
+          // fbe us 640x480, 8bits. So use that as a sensible
+          // default. Note that the fake framebuffer is only used for
+          // debugging and development.
+          ptr->xres          = 640; // visible resolution
+          ptr->xres_virtual  = 640; // virtual resolution
+          ptr->yres          = 480; // visible resolution
+          ptr->yres_virtual  = 480; // virtual resolution
+          ptr->width         = 640; // width of picture in mm
+          ptr->height        = 480; // height of picture in mm
+
+          // Android and fbe use a 16bit 5/6/5 framebuffer
+          ptr->bits_per_pixel = 16;
+          ptr->red.length    = 5;
+          ptr->red.offset    = 11;
+          ptr->green.length  = 6;
+          ptr->green.offset  = 5;
+          ptr->blue.length   = 5;
+          ptr->blue.offset   = 0;
+          ptr->transp.offset = 0;
+          ptr->transp.length = 0;
+          // 8bit framebuffer
+          // ptr->bits_per_pixel = 8;
+          // ptr->red.length    = 8;
+          // ptr->red.offset    = 0;
+          // ptr->green.length  = 8;
+          // ptr->green.offset  = 0;
+          // ptr->blue.length   = 8;
+          // ptr->blue.offset   = 0;
+          // ptr->transp.offset = 0;
+          // ptr->transp.length = 0;
+          ptr->grayscale     = 1; // != 0 Graylevels instead of color
+          
+          break;
+      }
+      case FBIOGET_FSCREENINFO:
+      {
+          struct fb_fix_screeninfo *ptr =
+              reinterpret_cast<struct fb_fix_screeninfo *>(data);
+          ptr->smem_len = 307200; // Length of frame buffer mem
+          ptr->type = FB_TYPE_PACKED_PIXELS; // see FB_TYPE_*
+          ptr->visual = FB_VISUAL_PSEUDOCOLOR; // see FB_VISUAL_*
+          ptr->xpanstep = 0;      // zero if no hardware panning
+          ptr->ypanstep = 0;      // zero if no hardware panning
+          ptr->ywrapstep = 0;     // zero if no hardware panning
+          ptr->accel = FB_ACCEL_NONE; // Indicate to driver which specific
+                                  // chip/card we have
+          break;
+      }
+      case FBIOPUTCMAP:
+      {
+          // Fbe uses this name for the fake framebuffer, so in this
+          // case assume we're using fbe, so write to the known fbe
+          // cmap file.
+          std::string str = FAKEFB;
+          if (str == "/tmp/fbe_buffer") {
+              int fd = open("/tmp/fbe_cmap", O_WRONLY);
+              if (fd) {
+                  write(fd, data, sizeof(struct fb_cmap));
+                  close(fd);
+              } else {
+                  gnash::log_error("Couldn't write to the fake cmap!");
+                  return -1;
+              }
+          } else {
+              gnash::log_error("Couldn't write to the fake cmap, unknown 
type!");
+              return -1;
+          }
+          // If we send a SIGUSR1 signal to fbe, it'll reload the
+          // color map.
+          int fd = open("/tmp/fbe.pid", O_RDONLY);
+          char buf[10];
+          if (fd) {
+              if (read(fd, buf, 10) == 0) {
+                  close(fd);
+                  return -1;
+              } else {
+                  pid_t pid = strtol(buf, 0, NULL);
+                  kill(pid, SIGUSR1);
+                  gnash::log_debug("Signaled fbe to reload it's colormap.");
+              }
+              close(fd);
+          }
+          break;
+      }
+      default:
+          gnash::log_unimpl("fakefb_ioctl(%d)", request);
+          break;
+    }
+
+    return 0;
+}
+#endif  // ENABLE_FAKE_FRAMEBUFFER
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/libdevice/events/test_events.cpp b/libdevice/events/test_events.cpp
new file mode 100644
index 0000000..59590c5
--- /dev/null
+++ b/libdevice/events/test_events.cpp
@@ -0,0 +1,84 @@
+// 
+//   Copyright (C) 2010 Free Software Foundation, Inc
+// 
+// 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <iostream>
+#include <string>
+#include <cstdlib>
+#include <vector>
+#include <map>
+#include <cassert>
+#include <regex.h>
+#include <boost/assign/list_of.hpp>
+
+#include "log.h"
+#include "dejagnu.h"
+
+#include "GnashDevice.h"
+#include "InputDevice.h"
+
+TestState runtest;
+
+using namespace gnash;
+using namespace std;
+
+// The debug log used by all the gnash libraries.
+static LogFile& dbglogfile = LogFile::getDefaultInstance();
+    
+int
+main(int argc, char *argv[])
+{
+    // FIXME: for now, always run verbose till this supports command line args
+    dbglogfile.setVerbosity();
+
+    MouseDevice me;
+
+    bool loop = true;
+
+    std::vector<boost::shared_ptr<InputDevice> > inputs
+        = InputDevice::scanForDevices();
+    if (inputs.empty()) {
+        runtest.fail("InputDevice::scanForDevices()");
+        loop = false;
+    } else {
+        runtest.pass("InputDevice::scanForDevices()");
+    }    
+    
+    // This loops endlessly at the frame rate
+    while (loop) {  
+        // wait the "heartbeat" inteval
+        sleep(1);    
+        // TODO: Do we need to check the real time slept or is it OK when we 
woke
+        // up early because of some Linux signal sent to our process (and thus
+        // "advance" faster than the "heartbeat" interval)? - Udo
+
+        // check input devices
+        me.check();
+
+        // FIXME: process the input data
+        // boost::shared_ptr<input_event_t> popData();
+    }    
+}
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:

http://git.savannah.gnu.org/cgit//commit/?id=fc87019588762d7596119c7b50e18242772398de


commit fc87019588762d7596119c7b50e18242772398de
Author: Rob Savoye <address@hidden>
Date:   Sat Dec 18 09:16:03 2010 -0700

    drop the usage of the Gui class, instead just queue up event data to be 
retrieved by the Gui later.

diff --git a/libdevice/events/EventDevice.cpp b/libdevice/events/EventDevice.cpp
new file mode 100644
index 0000000..4374cb4
--- /dev/null
+++ b/libdevice/events/EventDevice.cpp
@@ -0,0 +1,495 @@
+// 
+//   Copyright (C) 2010 Free Software Foundation, Inc
+// 
+// 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include "log.h"
+#include "InputDevice.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/input.h>
+#include <linux/kd.h>
+
+namespace gnash {
+
+static const char *INPUT_DEVICE = "/dev/input/event0";
+
+EventDevice::EventDevice()
+{
+    // GNASH_REPORT_FUNCTION;
+}
+
+bool
+EventDevice::init()
+{
+    GNASH_REPORT_FUNCTION;
+
+    return init(INPUT_DEVICE, DEFAULT_BUFFER_SIZE);
+}
+
+bool
+EventDevice::init(const std::string &filespec, size_t /* size */)
+{
+    GNASH_REPORT_FUNCTION;
+    
+    _filespec = filespec;
+    
+    // Try to open mouse device, be error tolerant (FD is kept open all the 
time)
+    _fd = open(filespec.c_str(), O_RDONLY);
+  
+    if (_fd < 0) {
+        log_debug(_("Could not open %s: %s"), filespec.c_str(), 
strerror(errno));    
+        return false;
+    }
+  
+    if (fcntl(_fd, F_SETFL, fcntl(_fd, F_GETFL) | O_NONBLOCK) < 0) {
+        log_error(_("Could not set non-blocking mode for pointing device: %s"),
+                  strerror(errno));
+        close(_fd);
+        _fd = -1;
+        return false; 
+    }
+
+    // Get the version number of the input event subsystem
+    int version;
+    if (ioctl(_fd, EVIOCGVERSION, &version)) {
+        perror("evdev ioctl");
+    }
+    log_debug("evdev driver version is %d.%d.%d",
+              version >> 16, (version >> 8) & 0xff,
+              version & 0xff);
+    
+    if(ioctl(_fd, EVIOCGID, &_device_info)) {
+        perror("evdev ioctl");
+    }
+    
+    char name[256]= "Unknown";
+    if(ioctl(_fd, EVIOCGNAME(sizeof(name)), name) < 0) {
+        perror("evdev ioctl");
+    }
+    log_debug("The device on %s says its name is %s", filespec, name);
+    
+    log_debug("vendor %04hx product %04hx version %04hx",
+              _device_info.vendor, _device_info.product,
+              _device_info.version);
+    switch (_device_info.bustype) {
+      case BUS_PCI:
+          log_unimpl("is a PCI bus type");
+          break;
+      case BUS_ISAPNP:
+          log_unimpl("is a PNP bus type");
+          break;          
+      case BUS_USB:
+          // FIXME: this probably needs a better way of checking what
+          // device things truly are.          
+          log_debug("is on a Universal Serial Bus");
+          // ID 0eef:0001 D-WAV Scientific Co., Ltd eGalax TouchScreen
+          if ((_device_info.product == 0x0001) && (_device_info.vendor == 
0x0eef)) {
+              _type = InputDevice::TOUCHMOUSE;
+              // ID 046d:c001 Logitech, Inc. N48/M-BB48 [FirstMouse Plus]
+          } else if ((_device_info.product == 0xc001) && (_device_info.vendor 
== 0x046d)) {
+              _type = InputDevice::MOUSE;
+              // ID 0001:0001 AT Translated Set 2 keyboard
+          } else if ((_device_info.product == 0x0001) && (_device_info.vendor 
== 0x0001)) {
+              _type = InputDevice::MOUSE;
+              // ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
+          } else if ((_device_info.product == 0x2303) && (_device_info.vendor 
== 0x067b)) {
+              _type = InputDevice::SERIALUSB ;
+                  // ID 0471:0815 Philips (or NXP) eHome Infrared Receiver
+          } else if ((_device_info.product == 0x0815) && (_device_info.vendor 
== 0x0471)) {
+              _type = InputDevice::INFRARED;
+          }
+          break;
+      case BUS_HIL:
+          log_unimpl("is a HIL bus type");
+          break;
+      case BUS_BLUETOOTH:
+          log_unimpl("is Bluetooth bus type ");
+          break;
+#ifdef BUS_VIRTUAL
+      case BUS_VIRTUAL:
+          log_unimpl("is a Virtual bus type ");
+          break;
+#endif
+      case BUS_ISA:
+          log_unimpl("is an ISA bus type");
+          break;
+      case BUS_I8042:
+          // This is for keyboards and mice
+          log_debug("is an I8042 bus type");
+          if (strstr(name, "keyboard") != 0) {
+              _type = InputDevice::KEYBOARD;
+          } else {
+              if (strstr(name, "Mouse") != 0) {
+                  _type = InputDevice::MOUSE;
+              }
+          }
+          break;
+      case BUS_XTKBD:
+          log_unimpl("is an XTKBD bus type");
+          break;
+      case BUS_RS232:
+          log_unimpl("is a serial port bus type");
+          break;
+      case BUS_GAMEPORT:
+          log_unimpl("is a gameport bus type");
+          break;
+      case BUS_PARPORT:
+          log_unimpl("is a parallel port bus type");
+          break;
+      case BUS_AMIGA:
+          log_unimpl("is an Amiga bus type");
+          break;
+      case BUS_ADB:
+          log_unimpl("is an AOB bus type");
+          break;
+      case BUS_I2C:
+          log_unimpl("is an i2C bus type ");
+          break;
+      case BUS_HOST:
+          log_debug("is Host bus type");
+          _type = InputDevice::POWERBUTTON;
+          break;
+      case BUS_GSC:
+          log_unimpl("is a GSC bus type");
+          break;
+#ifdef BUS_ATARI
+      case BUS_ATARI:
+          log_unimpl("is an Atari bus type");
+          break;
+#endif
+      default:
+          log_error("Unknown bus type %d!", _device_info.bustype);
+    }
+    
+    log_debug("Event enabled for %s on fd #%d", _filespec, _fd);
+    
+    return true;
+}
+
+bool
+EventDevice::check()
+{
+    GNASH_REPORT_FUNCTION;
+    
+    bool activity = false;
+  
+    if (_fd < 0) {
+        return false;           // no device
+    }
+
+    // Try to read something from the device
+    boost::shared_array<boost::uint8_t> buf = readData(sizeof( struct 
input_event));
+    // time,type,code,value
+    if (!buf) {
+        return false;
+    }
+    
+    struct input_event *ev = reinterpret_cast<struct input_event *>(buf.get());
+    // log_debug("Type is: %hd, Code is: %hd, Val us: %d", ev->type, ev->code,
+    //           ev->value);
+    switch (ev->type) {
+      case EV_SYN:
+          log_unimpl("Sync event from Input Event Device");
+          break;
+        // Keyboard event
+      case EV_KEY:
+      {
+          // code == scan code of the key (KEY_xxxx defines in input.h)        
 
+          // value == 0  key has been released
+          // value == 1  key has been pressed
+          // value == 2  repeated key reporting (while holding the key)
+          if (ev->code == KEY_LEFTSHIFT) {
+              keyb_lshift = ev->value;
+          } else if (ev->code == KEY_RIGHTSHIFT) {
+              keyb_rshift = ev->value;
+          } else if (ev->code == KEY_LEFTCTRL) {
+              keyb_lctrl = ev->value;
+          } else if (ev->code == KEY_RIGHTCTRL) {
+              keyb_rctrl = ev->value;
+          } else if (ev->code == KEY_LEFTALT) {
+              keyb_lalt = ev->value;
+          } else if (ev->code == KEY_RIGHTALT) {
+              keyb_ralt = ev->value;
+          } else {
+              gnash::key::code  c = scancode_to_gnash_key(ev->code,
+                                            keyb_lshift || keyb_rshift);
+                  // build modifier
+              int modifier = gnash::key::GNASH_MOD_NONE;
+              
+              if (keyb_lshift || keyb_rshift) {
+                  modifier = modifier | gnash::key::GNASH_MOD_SHIFT;
+              }
+              
+              if (keyb_lctrl || keyb_rctrl) {
+                  modifier = modifier | gnash::key::GNASH_MOD_CONTROL;
+              }
+              
+              if (keyb_lalt || keyb_ralt) {
+                  modifier = modifier | gnash::key::GNASH_MOD_ALT;
+              }
+              
+              // send event
+              if (c != gnash::key::INVALID) {
+                  addData(true, c, modifier, 0, 0);
+//                  _gui->notify_key_event(c, modifier, ev->value);
+                  activity = true;
+              }
+          } // if normal key
+          break;
+      } // case EV_KEY
+      // Mouse
+      case EV_REL:
+          log_unimpl("Relative move event from Input Event Device");
+          // Touchscreen or joystick
+          break;
+      case EV_ABS:
+          log_unimpl("Absolute move event from Input Event Device");
+          break;
+      case EV_MSC:
+          log_unimpl("Misc event from Input Event Device");
+          break;
+      case EV_LED:
+          log_unimpl("LED event from Input Event Device");
+          break;
+      case EV_SND:
+          log_unimpl("Sound event from Input Event Device");
+          break;
+      case EV_REP:
+          log_unimpl("Key autorepeat event from Input Event Device");
+          break;
+      case EV_FF:
+          log_unimpl("Force Feedback event from Input Event Device");
+          break;
+      case EV_FF_STATUS:  
+          log_unimpl("Force Feedback status event from Input Event Device");
+          break;
+      case EV_PWR:
+          log_unimpl("Power event from Input Event Device");
+          break;
+    }
+
+    return activity;
+}
+
+gnash::key::code
+EventDevice::scancode_to_gnash_key(int code, bool shift)
+{ 
+    // NOTE: Scancodes are mostly keyboard oriented (ie. Q, W, E, R, T, ...)
+    // while Gnash codes are mostly ASCII-oriented (A, B, C, D, ...) so no
+    // direct conversion is possible.
+    
+    // TODO: This is a very *incomplete* list and I also dislike this method
+    // very much because it depends on the keyboard layout (ie. pressing "Z"
+    // on a german keyboard will print "Y" instead). So we need some 
+    // alternative...
+    
+    switch (code) {
+      case KEY_1      : return !shift ? gnash::key::_1 : gnash::key::EXCLAM;
+      case KEY_2      : return !shift ? gnash::key::_2 : 
gnash::key::DOUBLE_QUOTE; 
+      case KEY_3      : return !shift ? gnash::key::_3 : gnash::key::HASH; 
+      case KEY_4      : return !shift ? gnash::key::_4 : gnash::key::DOLLAR; 
+      case KEY_5      : return !shift ? gnash::key::_5 : gnash::key::PERCENT; 
+      case KEY_6      : return !shift ? gnash::key::_6 : 
gnash::key::AMPERSAND; 
+      case KEY_7      : return !shift ? gnash::key::_7 : 
gnash::key::SINGLE_QUOTE; 
+      case KEY_8      : return !shift ? gnash::key::_8 : 
gnash::key::PAREN_LEFT; 
+      case KEY_9      : return !shift ? gnash::key::_9 : 
gnash::key::PAREN_RIGHT; 
+      case KEY_0      : return !shift ? gnash::key::_0 : gnash::key::ASTERISK;
+                            
+      case KEY_A      : return shift ? gnash::key::A : gnash::key::a;
+      case KEY_B      : return shift ? gnash::key::B : gnash::key::b;
+      case KEY_C      : return shift ? gnash::key::C : gnash::key::c;
+      case KEY_D      : return shift ? gnash::key::D : gnash::key::d;
+      case KEY_E      : return shift ? gnash::key::E : gnash::key::e;
+      case KEY_F      : return shift ? gnash::key::F : gnash::key::f;
+      case KEY_G      : return shift ? gnash::key::G : gnash::key::g;
+      case KEY_H      : return shift ? gnash::key::H : gnash::key::h;
+      case KEY_I      : return shift ? gnash::key::I : gnash::key::i;
+      case KEY_J      : return shift ? gnash::key::J : gnash::key::j;
+      case KEY_K      : return shift ? gnash::key::K : gnash::key::k;
+      case KEY_L      : return shift ? gnash::key::L : gnash::key::l;
+      case KEY_M      : return shift ? gnash::key::M : gnash::key::m;
+      case KEY_N      : return shift ? gnash::key::N : gnash::key::n;
+      case KEY_O      : return shift ? gnash::key::O : gnash::key::o;
+      case KEY_P      : return shift ? gnash::key::P : gnash::key::p;
+      case KEY_Q      : return shift ? gnash::key::Q : gnash::key::q;
+      case KEY_R      : return shift ? gnash::key::R : gnash::key::r;
+      case KEY_S      : return shift ? gnash::key::S : gnash::key::s;
+      case KEY_T      : return shift ? gnash::key::T : gnash::key::t;
+      case KEY_U      : return shift ? gnash::key::U : gnash::key::u;
+      case KEY_V      : return shift ? gnash::key::V : gnash::key::v;
+      case KEY_W      : return shift ? gnash::key::W : gnash::key::w;
+      case KEY_X      : return shift ? gnash::key::X : gnash::key::x;
+      case KEY_Y      : return shift ? gnash::key::Y : gnash::key::y;
+      case KEY_Z      : return shift ? gnash::key::Z : gnash::key::z;
+
+      case KEY_F1     : return gnash::key::F1; 
+      case KEY_F2     : return gnash::key::F2; 
+      case KEY_F3     : return gnash::key::F3; 
+      case KEY_F4     : return gnash::key::F4; 
+      case KEY_F5     : return gnash::key::F5; 
+      case KEY_F6     : return gnash::key::F6; 
+      case KEY_F7     : return gnash::key::F7; 
+      case KEY_F8     : return gnash::key::F8; 
+      case KEY_F9     : return gnash::key::F9;
+      case KEY_F10    : return gnash::key::F10;
+      case KEY_F11    : return gnash::key::F11;
+      case KEY_F12    : return gnash::key::F12;
+    
+      case KEY_KP0    : return gnash::key::KP_0; 
+      case KEY_KP1    : return gnash::key::KP_1; 
+      case KEY_KP2    : return gnash::key::KP_2; 
+      case KEY_KP3    : return gnash::key::KP_3; 
+      case KEY_KP4    : return gnash::key::KP_4; 
+      case KEY_KP5    : return gnash::key::KP_5; 
+      case KEY_KP6    : return gnash::key::KP_6; 
+      case KEY_KP7    : return gnash::key::KP_7; 
+      case KEY_KP8    : return gnash::key::KP_8; 
+      case KEY_KP9    : return gnash::key::KP_9;
+
+      case KEY_KPMINUS       : return gnash::key::KP_SUBTRACT;
+      case KEY_KPPLUS        : return gnash::key::KP_ADD;
+      case KEY_KPDOT         : return gnash::key::KP_DECIMAL;
+      case KEY_KPASTERISK    : return gnash::key::KP_MULTIPLY;
+      case KEY_KPENTER       : return gnash::key::KP_ENTER;
+    
+      case KEY_ESC           : return gnash::key::ESCAPE;
+      case KEY_MINUS         : return gnash::key::MINUS;
+      case KEY_EQUAL         : return gnash::key::EQUALS;
+      case KEY_BACKSPACE     : return gnash::key::BACKSPACE;
+      case KEY_TAB           : return gnash::key::TAB;
+      case KEY_LEFTBRACE     : return gnash::key::LEFT_BRACE;
+      case KEY_RIGHTBRACE    : return gnash::key::RIGHT_BRACE;
+      case KEY_ENTER         : return gnash::key::ENTER;
+      case KEY_LEFTCTRL      : return gnash::key::CONTROL;
+      case KEY_SEMICOLON     : return gnash::key::SEMICOLON;
+          //case KEY_APOSTROPHE    : return gnash::key::APOSTROPHE;  
+          //case KEY_GRAVE         : return gnash::key::GRAVE;
+      case KEY_LEFTSHIFT     : return gnash::key::SHIFT;
+      case KEY_BACKSLASH     : return gnash::key::BACKSLASH;
+      case KEY_COMMA         : return gnash::key::COMMA;
+      case KEY_SLASH         : return gnash::key::SLASH;
+      case KEY_RIGHTSHIFT    : return gnash::key::SHIFT;
+      case KEY_LEFTALT       : return gnash::key::ALT;
+      case KEY_SPACE         : return gnash::key::SPACE;
+      case KEY_CAPSLOCK      : return gnash::key::CAPSLOCK;
+      case KEY_NUMLOCK       : return gnash::key::NUM_LOCK;
+          //case KEY_SCROLLLOCK    : return gnash::key::SCROLLLOCK;
+    
+      case KEY_UP            : return gnash::key::UP;
+      case KEY_DOWN          : return gnash::key::DOWN;
+      case KEY_LEFT          : return gnash::key::LEFT;
+      case KEY_RIGHT         : return gnash::key::RIGHT;
+      case KEY_PAGEUP        : return gnash::key::PGUP;
+      case KEY_PAGEDOWN      : return gnash::key::PGDN;
+      case KEY_INSERT        : return gnash::key::INSERT;
+      case KEY_DELETE        : return gnash::key::DELETEKEY;
+      case KEY_HOME          : return gnash::key::HOME;
+      case KEY_END           : return gnash::key::END;
+    
+    }
+  
+    return gnash::key::INVALID;  
+}
+
+// This looks in the input event devices
+std::vector<boost::shared_ptr<InputDevice> > 
+EventDevice::scanForDevices()
+{
+    // GNASH_REPORT_FUNCTION;
+
+    struct stat st;
+
+    int total = 0;
+    std::vector<boost::shared_ptr<InputDevice> > devices;
+    
+    // The default path for input event devices.
+    char *filespec = strdup("/dev/input/eventX");
+    int len = strlen(filespec) - 1;
+
+    // Walk through all the input event devices for the ones that
+    // match the type we want. There can be multiple devices of the same
+    // type, so we return the ID of the event devices.
+    filespec[len] = '0';
+    int fd = 0;
+    while (fd >= 0) {
+        // First see if the file exists
+        if (stat(filespec, &st) == 0) {
+            // Then see if we can open it
+            if ((fd = open(filespec, O_RDWR)) < 0) {
+                log_error("You don't have the proper permissions to open %s",
+                          filespec);
+                // Try the next input event device file
+                total++;
+                filespec[len] = '0' + total;
+                fd = 0;
+                continue;
+            }
+        } else {
+            // No more device files to try, so we're done scanning
+            break;
+        }
+
+        char name[256] = "Unknown";
+        if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) {
+            perror("evdev ioctl");
+        }
+        log_debug("The device on %s says its name is %s", filespec, name);
+
+        struct input_id device_info;
+        if(ioctl(fd, EVIOCGID, &device_info)) {
+            perror("evdev ioctl");
+        }
+        log_debug("vendor %04hx product %04hx version %04hx",
+                  device_info.vendor, device_info.product,
+                  device_info.version);
+        close(fd);
+        boost::shared_ptr<InputDevice> dev;
+        dev = boost::shared_ptr<InputDevice>(new EventDevice());
+        // For now we only want keyboards, as the mouse interface
+        // default of /dev/input/mice supports hotpluging devices,
+        // unlike the regular event.
+        if (dev->init(filespec, DEFAULT_BUFFER_SIZE)) {
+            if ((dev->getType() == InputDevice::KEYBOARD)) {
+                devices.push_back(dev);
+            }
+        }
+
+//        dev->dump();
+        
+        // setup the next device filespec to try
+        total++;
+        filespec[len] = '0' + total;
+    }
+    
+    free (filespec);
+    
+    return devices;
+}
+
+// end of namespace
+}
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/libdevice/events/InputDevice.cpp b/libdevice/events/InputDevice.cpp
new file mode 100644
index 0000000..b27f782
--- /dev/null
+++ b/libdevice/events/InputDevice.cpp
@@ -0,0 +1,201 @@
+// 
+//   Copyright (C) 2010 Free Software Foundation, Inc
+// 
+// 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include "log.h"
+#include "InputDevice.h"
+#include "GnashKey.h"
+
+namespace gnash {
+
+InputDevice::InputDevice()
+    : _type(InputDevice::UNKNOWN),
+      _fd(-1),
+      _x(0),
+      _y(0),
+      _button(0),
+      _position(0)
+{
+    // GNASH_REPORT_FUNCTION;
+}
+
+InputDevice::~InputDevice()
+{
+    // GNASH_REPORT_FUNCTION;
+}
+
+bool
+InputDevice::init()
+{
+    // GNASH_REPORT_FUNCTION;
+    
+    return true;
+}
+
+bool
+InputDevice::init(InputDevice::devicetype_e type)
+{
+    GNASH_REPORT_FUNCTION;
+    return init(type, std::string(), DEFAULT_BUFFER_SIZE);
+}
+
+bool
+InputDevice::init(InputDevice::devicetype_e type, size_t size)
+{
+    GNASH_REPORT_FUNCTION;
+
+    return init(type, std::string(), size);
+}
+
+bool
+InputDevice::init(InputDevice::devicetype_e type, const std::string &filespec,
+                  size_t size)
+{
+    GNASH_REPORT_FUNCTION;
+
+    _type = type;
+    _filespec = filespec;
+    
+    return init(filespec, size);
+}
+
+void
+InputDevice::addData(bool pressed, key::code key, int modifier, int x, int y)
+{
+    GNASH_REPORT_FUNCTION;
+    
+    boost::shared_ptr<input_data_t> _newdata(new input_data_t);
+    _newdata->pressed = pressed;
+    _newdata->key = key;
+    _newdata->modifier = modifier;
+    _newdata->x = x;
+    _newdata->y = y;
+#if 1
+    std::cerr << "Adding data: " << _newdata->pressed;
+    std::cerr << ", " << _newdata->key << ", " << _newdata->modifier;
+    std::cerr << ", " << _newdata->x << ", " << _newdata->y << std::endl;
+#endif
+    _data.push_back(_newdata);
+}
+
+// Read data into the Device input buffer.
+boost::shared_array<boost::uint8_t>
+InputDevice::readData(size_t size)
+{
+    GNASH_REPORT_FUNCTION;
+
+    boost::shared_array<boost::uint8_t> inbuf;
+
+    if (_fd < 0) {
+        return inbuf;   // no mouse available
+    }
+
+    fd_set fdset;
+    FD_ZERO(&fdset);
+    FD_SET(_fd, &fdset);
+    struct timeval tval;
+    tval.tv_sec  = 0;
+    tval.tv_usec = 1;
+    errno = 0;
+    int ret = ::select(_fd+1, &fdset, NULL, NULL, &tval);
+    if (ret == 0) {
+//            log_debug ("The pipe for fd #%d timed out waiting to read", fd);
+        return inbuf;
+    } else if (ret == 1) {
+        log_debug ("The device for fd #%d is ready", _fd);
+    } else {
+        log_error("The device has this error: %s", strerror(errno));
+        return inbuf;
+    }
+    
+    inbuf.reset(new boost::uint8_t[size]);
+    ret = ::read(_fd, inbuf.get(), size);
+    if (ret > 0) {
+        log_debug("Read %d bytes, %s", ret, hexify(inbuf.get(), ret, false));
+    } else {
+        inbuf.reset();
+    }
+
+    return inbuf;
+}   
+
+void
+InputDevice::dump()
+{
+    // Debug strings to make output more readable
+    const char *debug[] = {
+        "UNKNOWN",
+        "Keyboard",
+        "Mouse",
+        "Touchscreen",
+        "Touchscreen Mouse",
+        "Power Button",
+        "Sleep Button",
+        "Serial-USB Adapter",
+        "Infrared Receiver"
+    };    
+
+    std::cerr << "Device type is: " << debug[_type] << std::endl;
+    std::cerr << "\tfilespec is: " << _filespec
+              << ", fd #" << _fd << std::endl;
+    std::cerr << "\tX is: " << _x << ", Y is: " << _y << std::endl;
+}
+
+// Scan for all the possible input devices. This aggregates all
+// the devices from each type into a single big vector.
+std::vector<boost::shared_ptr<InputDevice> >
+InputDevice::scanForDevices()
+{
+    // GNASH_REPORT_FUNCTION;
+
+    std::vector<boost::shared_ptr<InputDevice> > devices;
+    
+    std::vector<boost::shared_ptr<InputDevice> > id;
+    std::vector<boost::shared_ptr<InputDevice> >::iterator it;
+#ifdef USE_INPUT_EVENTS
+    id = EventDevice::scanForDevices();
+    for (it=id.begin(); it!=id.end(); ++it) {
+        devices.push_back(*it);
+    }
+#endif
+#if defined(USE_MOUSE_PS2) || defined(USE_MOUSE_ETT)
+    id = MouseDevice::scanForDevices();
+    for (it=id.begin(); it!=id.end(); ++it) {
+        devices.push_back(*it);
+    }
+#endif
+#if defined(HAVE_TSLIB_H) && defined(USE_TSLIB)
+    id = TouchDevice::scanForDevices();
+    for (it=id.begin(); it!=id.end(); ++it) {
+        devices.push_back(*it);
+    }
+#endif
+
+    return devices;
+}
+
+// end of gnash namespace
+}
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/libdevice/events/InputDevice.h b/libdevice/events/InputDevice.h
new file mode 100644
index 0000000..c1cfce8
--- /dev/null
+++ b/libdevice/events/InputDevice.h
@@ -0,0 +1,164 @@
+// 
+//   Copyright (C) 2010 Free Software Foundation, Inc
+// 
+// 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef GNASH_INPUTDEVICE_H
+#define GNASH_INPUTDEVICE_H
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <boost/scoped_array.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/cstdint.hpp>
+#include <vector>
+#include <linux/input.h>
+
+#include "GnashKey.h"
+
+namespace gnash {
+
+// Define if you want to support multiple input devices of the same type.
+// The default is to support the devices we prefer for moluse, keyboard,
+// and touchscreen.
+// #define MULTIPLE_DEVICES 1
+
+// If we have a mouse, but the size isn't specified, then this is the
+// default size.
+static const int DEFAULT_BUFFER_SIZE = 256;
+
+// This is an InputDevice class to cover the various touchscreens, Mice, or
+// keyboards supported.
+class InputDevice
+{
+public:
+    typedef struct {
+        bool pressed;
+        gnash::key::code key;
+        int modifier;
+        int x;
+        int y;
+    } input_data_t;
+    typedef enum {
+        UNKNOWN,
+        KEYBOARD,
+        MOUSE,
+        TOUCHSCREEN,
+        TOUCHMOUSE,
+        POWERBUTTON,
+        SLEEPBUTTON,
+        SERIALUSB,
+        INFRARED
+    } devicetype_e;
+    InputDevice();
+    virtual ~InputDevice();
+    
+    virtual bool init();
+    bool init(devicetype_e type);
+    bool init(devicetype_e type, size_t size);
+    bool init(devicetype_e type, const std::string &filespec);
+    bool init(devicetype_e type, const std::string &filespec, size_t size);
+    virtual bool init(const std::string &filespec, size_t size) = 0;
+    virtual bool check() = 0;
+
+    static std::vector<boost::shared_ptr<InputDevice> > scanForDevices();
+
+    InputDevice::devicetype_e getType() { return _type; };
+
+    // Read data into the Device input buffer.
+    boost::shared_array<boost::uint8_t> readData(size_t size);
+
+    boost::shared_ptr<input_data_t> popData() { return _data.front();};
+    
+    void dump();
+protected:
+    void addData(bool pressed, key::code key, int modifier, int x, int y);
+    
+    devicetype_e        _type;
+    std::string         _filespec;
+    int                 _fd;
+    int                 _x;
+    int                 _y;
+    // Touchscreens don't have buttons
+    int                 _button;
+    size_t              _position;
+    boost::scoped_array<boost::uint8_t> _buffer;
+    std::vector<boost::shared_ptr<input_data_t> > _data;
+};
+
+class MouseDevice : public InputDevice
+{
+public:
+    MouseDevice();
+    virtual bool init();
+    virtual bool init(const std::string &filespec, size_t size);
+    virtual bool check();
+
+    static std::vector<boost::shared_ptr<InputDevice> > scanForDevices();
+    
+    /// Sends a command to the mouse and waits for the response
+    bool command(unsigned char cmd, unsigned char *buf, int count);
+};
+
+class TouchDevice : public InputDevice
+{
+public:
+    TouchDevice();
+    virtual ~TouchDevice();
+    virtual bool init();
+    virtual bool init(const std::string &filespec, size_t size);
+    virtual bool check();
+
+    void apply_ts_calibration(float* cx, float* cy, int rawx, int rawy);
+    
+    static std::vector<boost::shared_ptr<InputDevice> > scanForDevices();
+private:
+    // Although the value is only set when using a touchscreen, it takes up 
little
+    // memory to initialize a pointer to avoid lots of messy ifdefs.
+    struct tsdev *_tsDev;
+};
+
+class EventDevice : public InputDevice
+{
+public:
+    EventDevice();
+    virtual bool init();
+    virtual bool init(const std::string &filespec, size_t size);
+    virtual bool check();
+
+    gnash::key::code scancode_to_gnash_key(int code, bool shift);
+
+    // This looks for all the input event devices.
+    static std::vector<boost::shared_ptr<InputDevice> > scanForDevices();
+    
+private:
+    // Keyboard SHIFT/CTRL/ALT states (left + right)
+     bool keyb_lshift, keyb_rshift, keyb_lctrl, keyb_rctrl, keyb_lalt, 
keyb_ralt;
+    struct input_id _device_info;
+};
+
+} // end of gnash namespace
+
+// end of GNASH_INPUTDEVICE_H
+#endif
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/libdevice/events/MouseDevice.cpp b/libdevice/events/MouseDevice.cpp
new file mode 100644
index 0000000..ce1096f
--- /dev/null
+++ b/libdevice/events/MouseDevice.cpp
@@ -0,0 +1,354 @@
+// 
+//   Copyright (C) 2010 Free Software Foundation, Inc
+// 
+// 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "GnashSleep.h"
+#include "log.h"
+#include "InputDevice.h"
+
+namespace gnash {
+
+static const char *MOUSE_DEVICE = "/dev/input/mice";
+
+MouseDevice::MouseDevice()
+{
+    GNASH_REPORT_FUNCTION;
+}
+
+std::vector<boost::shared_ptr<InputDevice> >
+MouseDevice::scanForDevices()
+{
+    // GNASH_REPORT_FUNCTION;
+
+    struct stat st;
+
+    std::vector<boost::shared_ptr<InputDevice> > devices;
+
+    // Look for these files for mouse input
+    struct mouse_types {
+        InputDevice::devicetype_e type;
+        const char *filespec;
+    };
+
+    // Debug strings to make output more readable
+    const char *debug[] = {
+        "UNKNOWN",
+        "Keyboard",
+        "Mouse",
+        "Touchscreen",
+        "Touchscreen Mouse",
+        "Power Button",
+        "Sleep Button",
+        "Serial-USB Adapter",
+        "Infrared Receiver"
+    };    
+
+    struct mouse_types mice[] = {
+        {InputDevice::MOUSE, "/dev/input/mice"},      // PS/2 Mouse
+#ifdef MULTIPLE_DEVICES
+        {InputDevice::MOUSE, "/dev/input/mouse0"},
+        {InputDevice::MOUSE, "/dev/input/mouse1"},
+        {InputDevice::MOUSE, "/dev/usb/tkpanel0"},    // eTurboTouch 
touchscreen
+#endif
+        {InputDevice::UNKNOWN, 0}
+    };
+
+    int i = 0;
+    while (mice[i].type != InputDevice::UNKNOWN) {
+        int fd = 0;
+        if (stat(mice[i].filespec, &st) == 0) {
+            // Then see if we can open it
+            if ((fd = open(mice[i].filespec, O_RDWR)) < 0) {
+                log_error("You don't have the proper permissions to open %s",
+                          mice[i].filespec);
+                i++;
+                continue;
+            }
+            close(fd);
+            log_debug("Found a %s device for mouse input using %s",
+                      debug[mice[i].type], mice[i].filespec);
+            
+            boost::shared_ptr<InputDevice> dev;
+#if defined(USE_MOUSE_PS2) || defined(USE_MOUSE_ETT)
+            dev = boost::shared_ptr<InputDevice>(new MouseDevice());
+            if (dev->init(mice[i].filespec, DEFAULT_BUFFER_SIZE)) {
+                devices.push_back(dev);
+            }
+//            dev->dump();
+#endif
+        }     // stat()
+        i++;
+    }         // while()
+    
+    return devices;
+}
+
+bool
+MouseDevice::init()
+{
+    GNASH_REPORT_FUNCTION;
+
+    return init(MOUSE_DEVICE, DEFAULT_BUFFER_SIZE);
+}
+
+bool
+MouseDevice::init(const std::string &filespec, size_t size)
+{
+    GNASH_REPORT_FUNCTION;
+
+    _type = MOUSE;
+    _filespec = filespec;
+    _buffer.reset(new boost::uint8_t[size]);
+
+    // see http://www.computer-engineering.org/ps2mouse/ 
+    
+    // Try to open mouse device, be error tolerant (FD is kept open all the 
time)
+    _fd = open(filespec.c_str(), O_RDWR);
+    
+    if (_fd < 0) {
+        log_debug("Could not open %s: %s", filespec, strerror(errno));
+        return false;
+    }
+    
+    if (fcntl(_fd, F_SETFL, fcntl(_fd, F_GETFL) | O_NONBLOCK) < 0) {
+        log_error("Could not set non-blocking mode for mouse device: %s", 
strerror(errno));
+        close(_fd);
+        _fd = -1;
+        return false; 
+    }
+    
+    // Clear input buffer
+    unsigned char buf[10], byte;
+    while (read(_fd, buf, sizeof buf) > 0 ) { }
+
+    // A touchscreen works similar to a Mouse, but not exactly...
+    if (_type == InputDevice::MOUSE) {
+        // Reset mouse
+        if ((!command(0xFF, buf, 3)) || (buf[0] != 0xFA)) {
+            log_debug(_("Mouse reset failed"));
+            close(_fd);
+            _fd = -1;
+            return false; 
+        }
+        
+        // Get Device ID (not crucial, debug only)
+        if ((!command(0xF2, buf, 2)) || (buf[0] != 0xFA)) {
+            log_debug(_("WARNING: Could not detect mouse device ID"));
+        } else {
+            unsigned char devid = buf[1];
+            if (devid != 0)
+                log_debug(_("WARNING: Non-standard mouse device ID %d"), 
devid);
+        }
+        
+        // Enable mouse data reporting
+        if ((!command(0xF4, &byte, 1)) || (byte != 0xFA)) {
+            log_debug(_("Could not activate Data Reporting mode for mouse"));
+            close(_fd);
+            _fd = -1;
+            return false; 
+        }  
+        
+        log_debug("Mouse enabled for %s on fd #%d", _filespec, _fd);
+    }
+      
+    return true;
+}
+
+// From http://www.computer-engineering.org/ps2mouse
+//
+// PS/2 Mouse mouse data is always in a 3 byte packet that looks like this:
+//
+//            Bit 7       Bit 6         Bit 5        Bit 4      Bit 3     Bit 
2    Bit 1   Bit 0
+// Byte 1 | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | 
Middle | Right | Left
+// Byte 2                               X movement
+// Byte 3                               Y movement
+//
+// The movement values are 9-bit 2's complement integers, where the
+// most significant bit appears as a "sign" bit in byte 1 of the
+// movement data packet. Their value represents the mouse's offset
+// relative to its position when the previous packet was sent, in
+// units determined by the current resolution. The range of values
+// that can be expressed is -255 to +255. If this range is exceeded,
+// the appropriate overflow bit is set.
+//
+// Note that reporting is disabled by default. The mouse will not
+// actually issue any movement data packets until it receives the
+// "Enable Data Reporting" (0xF4) command. 
+//
+// Stream mode is the default operating mode, and is otherwise set
+// using the "Set Stream Mode" (0xEA) command.
+//
+// In remote mode the mouse reads its inputs and updates its
+// counters/flags at the current sample rate, but it does not
+// automatically issue data packets when movement has
+// occured. Instead, the host polls the mouse using the "Read Data"
+// (0xEB) command. Upon receiving this command the mouse will issue a
+// single movement data packet and reset its movement counters. 
+
+// The mouse enters remote mode upon receiving the "Set Remote Mode"
+// (0xF0) command.
+bool
+MouseDevice::check()
+{
+    GNASH_REPORT_FUNCTION;
+
+    if (_fd < 0) {
+        return false;   // no mouse available
+    }
+    
+    int xmove, ymove, btn;
+    boost::shared_array<boost::uint8_t> buf;
+    if (_type == InputDevice::TOUCHMOUSE) {
+        // The eTurboTouch has a 4 byte packet
+        buf = readData(4);
+    } else {
+        // PS/2 Mouse packets are always 3 bytes
+        buf = readData(3);
+    }
+    
+    if (!buf) {
+        return false;
+    }
+    
+    // resync
+    if (!buf[0] & 8) { // bit 3 us always set in the first byte
+        log_error("No sync in first byte!");
+        return false;
+    }
+
+    // A Touchscreen works similar to a Mouse, but not exactly.
+    // At least for the eTurboTouch, it has a different layout
+    // in the packet for the location as it has an additional byte
+    btn   = buf[0] & 1;
+    if (_type == InputDevice::TOUCHMOUSE) {
+        xmove = (buf[1] << 7) | (buf[2]);
+        ymove = (buf[3] << 7) | (buf[4]);
+        /*
+          printf("touchscreen: %02x %02x %02x %02x %02x | status %d, pos: 
%d/%d\n",
+          mouse_buf[0], mouse_buf[1], mouse_buf[2], mouse_buf[3], 
mouse_buf[4],   
+          new_btn, new_x, new_y);
+        */    
+        
+        xmove = static_cast<int>(((static_cast<double>(xmove)- 355) / (1702 - 
355)
+                                  * 1536 + 256));
+        ymove = static_cast<int>(((static_cast<double>(ymove) - 482) / (1771 - 
482)
+                                  * 1536 + 256));
+#if 0
+        // FIXME: don't calculate here, this should be done by the GUI
+        xmove = xmove * _gui->getStage()->getStageWidth() / 2048;
+        ymove = (2048-ymove) * _gui->getStage()->getStageHeight() / 2048;
+#endif
+    } else {                    // end of InputDevice::MOUSE
+        xmove = buf[1];
+        ymove = buf[2];
+    
+        if (buf[0] & 0x10) {
+            xmove = -(256-xmove);
+        }
+        if (buf[0] & 0x20) {
+            ymove = -(256-ymove);
+        }
+        
+        ymove *= -1; // vertical movement is upside-down
+        
+        log_debug(_("x/y %d/%d button %d"), xmove, ymove, btn);
+        
+        // movement    
+        _x += xmove;
+        _y += ymove;
+        
+        if (_x < 0) {
+            _x = 0;
+        }
+        if (_y < 0) {
+            _y = 0;
+        }
+#if 0
+        // FIXME: don't calculate here, this should be done by the GUI
+        if (_x > static_cast<int>(_gui->getStage()->getStageWidth())) {
+            _x = static_cast<int>(_gui->getStage()->getStageWidth());
+        }
+        if (_y > static_cast<int>(_gui->getStage()->getStageHeight())) {
+            _y = static_cast<int>(_gui->getStage()->getStageHeight());
+        }
+#endif
+    } // end of InputDevice::MOUSE
+    
+    log_debug(_("read mouse @ %d / %d, btn %d"), _x, _y, _button);
+    addData(false, gnash::key::INVALID, 0, _x, _y);
+    
+    // button
+    if (btn != _button) {
+        _button = btn;
+        log_debug("clicked: %d", btn); 
+        addData(true, gnash::key::INVALID, 0, _x, _y);
+        log_debug(_("mouse click! %d"), btn);
+    }
+    
+    return true;
+}
+
+bool
+MouseDevice::command(unsigned char cmd, unsigned char *buf, int count)
+{
+    GNASH_REPORT_FUNCTION;
+
+    int n;
+    
+    // flush input buffer
+    char trash[16];
+    do {
+        n = read(_fd, trash, sizeof trash);
+        if (n > 0) 
+            log_debug(_("mouse_command: discarded %d bytes from input 
buffer"), n);
+    } while (n > 0);
+    
+    // send command
+    if ( -1 == write(_fd, &cmd, 1) ) {
+        return false;
+    }
+
+    // read response (if any)
+    while (count > 0) {
+        gnashSleep(250*1000); // 250 ms inter-char timeout (simple method)
+        // TODO: use select() instead
+        
+        n = read(_fd, buf, count);
+        if (n <= 0) return false;
+        count -= n;
+        buf += n;
+    }
+    
+    return true;
+    
+} // command()
+
+// end of namespace
+}
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/libdevice/events/TouchDevice.cpp b/libdevice/events/TouchDevice.cpp
new file mode 100644
index 0000000..4564467
--- /dev/null
+++ b/libdevice/events/TouchDevice.cpp
@@ -0,0 +1,326 @@
+// 
+//   Copyright (C) 2010 Free Software Foundation, Inc
+// 
+// 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 3 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifdef HAVE_TSLIB_H
+# include <tslib.h>
+#endif
+#if defined(USE_TSLIB) && !defined(HAVE_TSLIB_H)
+# warning "No tslib.h! Disabling touchscreen support"
+#endif
+
+#include "log.h"
+#include "InputDevice.h"
+
+namespace gnash {
+
+#ifdef USE_TSLIB
+// Either use environment variable or hardcoded value
+// Hint: /dev/ts can be a symlink to the real ts device.
+// TSLIB_DEVICE environment variable should point to the
+// touchscreen device the library is using.
+static const char *TSLIB_DEVICE_ENV = "TSLIB_TSDEVICE";
+static const char *TSLIB_DEVICE_NAME = "/dev/ts";
+#endif
+
+//static const char *MOUSE_DEVICE = "/dev/usb/tkpanel0";
+
+TouchDevice::TouchDevice()
+{
+    GNASH_REPORT_FUNCTION;
+}
+
+TouchDevice::~TouchDevice()
+{
+    if (_tsDev) {
+        ts_close(_tsDev);
+    }
+}    
+
+bool
+TouchDevice::init()
+{
+    return init(TSLIB_DEVICE_NAME, DEFAULT_BUFFER_SIZE);
+}
+
+bool
+TouchDevice::init(const std::string &filespec, size_t /* size */)
+{
+    GNASH_REPORT_FUNCTION;
+
+    _type = TouchDevice::TOUCHSCREEN;
+    _filespec = filespec;
+    
+    char *devname = getenv(TSLIB_DEVICE_ENV);
+    if (!devname) {
+        devname = const_cast<char *>(TSLIB_DEVICE_NAME);
+    } else {
+        if (!filespec.empty()) {
+            devname = const_cast<char *>(_filespec.c_str());
+        } else {
+            log_error("No filespec specified for the touchscreen device.");
+        }
+    }
+    
+    _tsDev = ts_open(devname, 1);  //Open tslib non-blocking
+    if (_tsDev == 0) {
+        log_debug("Could not open touchscreen %s: %s", devname, 
strerror(errno));
+        return false;
+    }
+    
+    ts_config(_tsDev); 
+    if (ts_fd(_tsDev) < 0) {
+        log_debug("Could not get touchscreen fd %s: %s", devname, 
strerror(errno));
+        return false;
+    }
+    
+    log_debug("Using TSLIB on %s", devname);
+    return true;
+}
+
+bool
+TouchDevice::check()
+{
+    GNASH_REPORT_FUNCTION;
+
+    // Read events from the touchscreen and transport them into Gnash
+    // Tslib should be setup so the output is pretty clean.
+    struct ts_sample event;
+    // unsigned long    flags;
+    // unsigned long    buttons;
+    
+    if (_tsDev == 0) {
+        return false;           // No tslib device initialized, exit!
+    }
+    
+    int n = ts_read(_tsDev, &event, 1);     // read one event
+
+    // Did we read an event?
+    if (n == 1) {
+        if (event.pressure > 0) {
+            // the screen is touched
+#if 0
+        // FIXME: don't calculate here, this should be done by the GUI
+            if (event.x > static_cast<int>(_gui->getStage()->getStageWidth())) 
{
+                event.x = static_cast<int>(_gui->getStage()->getStageWidth());
+            }
+            if (event.y > 
static_cast<int>(_gui->getStage()->getStageHeight())) {
+                event.y = static_cast<int>(_gui->getStage()->getStageHeight());
+            }
+#endif
+            // FIXME: the API for these mouse events has changed, so this 
needs to be
+            // updated.
+            _gui->notifyMouseMove(int(event.x / _gui->getXScale()),
+                                  int(event.y / _gui->getYScale()));
+            _gui->notifyMouseClick(true);  //fire mouse click event into Gnash
+            
+            log_debug("Touched x: %d y: %d width: %d height: %d",
+                      event.x , event.y, _gui->getStage()->getStageWidth(),
+                      _gui->getStage()->getStageHeight());
+#endif
+            addData(true, gnash::key::INVALID, 0, event.x, event.y);
+        } else {
+            addData(false, gnash::key::INVALID, 0, event.x, event.y);
+//            _gui->notifyMouseClick(false);  //button released
+            log_debug("lifted x: %d y: %d", event.x, event.y); //debug
+        }
+    }
+
+    return true;
+}
+
+void
+TouchDevice::apply_ts_calibration(float* cx, float* cy, int rawx, int rawy)
+{
+    // This method use 3 points calibration
+    // it is described in http://www.embedded.com/story/OEG20020529S0046
+    
+    float k,a,b,c,d,e,f;
+    
+    float ref0x = _gui->getStage()->getStageWidth() / 5 * 1;
+    float ref0y = _gui->getStage()->getStageHeight() / 5 * 1;
+    float ref1x = _gui->getStage()->getStageWidth() / 5 * 4;
+
+    float ref1y = _gui->getStage()->getStageHeight() / 5 * 1;
+    float ref2x = _gui->getStage()->getStageWidth() / 5 * 4;
+    float ref2y = _gui->getStage()->getStageHeight() / 5 * 4;
+  
+    static float cal0x = 2048/5*1;   // very approximative default values
+    static float cal0y = 2048/5*4;
+    static float cal1x = 2048/5*1;
+    static float cal1y = 2048/5*1;
+    static float cal2x = 2048/5*4;
+    static float cal2y = 2048/5*1;
+  
+    static bool initialized=false; // woohooo.. better don't look at this 
code...
+    if (!initialized) {
+        initialized = true;
+    
+        char* settings = std::getenv("TSCALIB");
+    
+        if (settings) {
+    
+            // expected format: 
+            // 491,1635,451,537,1581,646
+            // (cal0x,cal0y,cal1x,cal1y,cal2x,cal2y; all integers)
+            char buffer[1024];      
+            char* p1;
+            char* p2;
+            bool ok = false;
+      
+            snprintf(buffer, sizeof buffer, "%s", settings);
+            p1 = buffer;
+      
+            do {
+                p2 = strchr(p1, ',');
+                if (!p2) continue; // stop here
+                *p2 = 0;
+                cal0x = atoi(p1);        
+                p1=p2+1;
+                
+                // cal0y        
+                p2 = strchr(p1, ',');
+                if (!p2) continue; // stop here
+                *p2 = 0;
+                cal0y = atoi(p1);        
+                p1=p2+1;
+                
+                // cal1x        
+                p2 = strchr(p1, ',');
+                if (!p2) continue; // stop here
+                *p2 = 0;
+                cal1x = atoi(p1);        
+                p1=p2+1;
+        
+                // cal1y        
+                p2 = strchr(p1, ',');
+                if (!p2) continue; // stop here
+                *p2 = 0;
+                cal1y = atoi(p1);        
+                p1=p2+1;
+        
+                // cal2x        
+                p2 = strchr(p1, ',');
+                if (!p2) continue; // stop here
+                *p2 = 0;
+                cal2x = atoi(p1);        
+                p1=p2+1;
+        
+                // cal2y        
+                cal2y = atoi(p1);
+        
+                ok = true;        
+        
+            } while (0);
+      
+            if (!ok)
+                log_debug(_("WARNING: Error parsing calibration data!"));
+      
+            log_debug(_("Using touchscreen calibration data: %.0f / %.0f / 
%.0f / %.0f / %.0f / %.0f"),
+                      cal0x, cal0y, cal1x, cal1y, cal2x, cal2y);
+        } else {
+            log_debug(_("WARNING: No touchscreen calibration settings found. "
+                        "The mouse pointer most probably won't work precisely. 
Set "
+                        "TSCALIB environment variable with correct values for 
better results"));
+        }
+    
+    } //!initialized
+
+      // calcul of K, A, B, C, D, E and F
+    k = (cal0x - cal2x) * (cal1y - cal2y) - (cal1x - cal2x) * (cal0y - cal2y);
+    a = ((ref0x - ref2x) * (cal1y - cal2y) - (ref1x - ref2x) * (cal0y - 
cal2y)) / k;
+    b = ((ref1x - ref2x) * (cal0x - cal2x) - (ref0x - ref2x) * (cal1x - 
cal2x)) / k;
+    c = (cal0y * (cal2x * ref1x - cal1x * ref2x) + cal1y * (cal0x * ref2x - 
cal2x * ref0x) + cal2y * (cal1x * ref0x - cal0x * ref1x)) / k;
+    d = ((ref0y - ref2y) * (cal1y - cal2y) - (ref1y - ref2y) * (cal0y - 
cal2y)) / k;
+    e = ((ref1y - ref2y) * (cal0x - cal2x) - (ref0y - ref2y) * (cal1x - 
cal2x)) / k;
+    f = (cal0y * (cal2x * ref1y - cal1x * ref2y) + cal1y * (cal0x * ref2y - 
cal2x * ref0y) + cal2y * (cal1x * ref0y - cal0x * ref1y)) / k;
+    
+    // real duty:
+    *cx = a * rawx + b * rawy + c;
+    *cy = d * rawx + e * rawy + f;
+}
+
+std::vector<boost::shared_ptr<InputDevice> >
+TouchDevice::scanForDevices()
+{
+    // GNASH_REPORT_FUNCTION;
+
+    struct stat st;
+
+    std::vector<boost::shared_ptr<InputDevice> > devices;
+
+    // Debug strings to make output more readable
+    const char *debug[] = {
+        "TSlib"
+    };
+    
+    // Look for these files for mouse input
+    struct ts_types {
+        InputDevice::devicetype_e type;
+        const char *filespec;
+    };
+
+    struct ts_types touch[] = {
+        {InputDevice::TOUCHSCREEN, "/dev/input/ts0"},
+        {InputDevice::TOUCHSCREEN, "/dev/ts"},
+        {InputDevice::UNKNOWN, 0}
+    };
+
+    int i = 0;
+    while (touch[i].type != InputDevice::UNKNOWN) {
+        int fd = 0;
+        if (stat(touch[i].filespec, &st) == 0) {
+            // Then see if we can open it
+            if ((fd = open(touch[i].filespec, O_RDWR)) < 0) {
+                log_error("You don't have the proper permissions to open %s",
+                          touch[i].filespec);
+                i++;
+                continue;
+            } // open()
+            log_debug("Found a %s device for mouse input using %s",
+                      debug[touch[i].type], touch[i].filespec);
+            boost::shared_ptr<InputDevice> dev;
+            dev = boost::shared_ptr<InputDevice>(new TouchDevice());
+            if (dev->init(touch[i].filespec, DEFAULT_BUFFER_SIZE)) {
+                devices.push_back(dev);
+            }
+            dev->dump();
+            
+            devices.push_back(dev);
+        }     // stat()
+        close(fd);
+        i++;
+    }         // while()
+    
+    return devices;
+}
+
+// end of namespace
+}
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/libdevice/events/events.am b/libdevice/events/events.am
index 86fd37d..5cd8c61 100644
--- a/libdevice/events/events.am
+++ b/libdevice/events/events.am
@@ -20,20 +20,19 @@
 # touchscreen. These are only used by the Framebuffer GUI, as without
 # X11, it has no event handling. We do it this way so the optionally
 # built source files still get included in the source tarball.
-DEVICES =
 if ENABLE_INPUT_DEVICES
-DEVICES += fb/InputDevice.cpp fb/InputDevice.h
+libgnashdevice_la_SOURCES += events/InputDevice.cpp events/InputDevice.h
 
 # Touchscreen
 if ENABLE_TSLIB
-libgnashdevice_la_SOURCES += fb/TouchDevice.cpp
+libgnashdevice_la_SOURCES += events/TouchDevice.cpp
 endif
 # PS/2 Mouse
 if ENABLE_MOUSE
-libgnashdevice_la_SOURCES += fb/MouseDevice.cpp
+libgnashdevice_la_SOURCES += events/MouseDevice.cpp
 endif
 # Linux input events
 if ENABLE_INPUT_EVENTS
-libgnashdevice_la_SOURCES += fb/EventDevice.cpp
+libgnashdevice_la_SOURCES += events/EventDevice.cpp
 endif
 endif

-----------------------------------------------------------------------

Summary of changes:
 gui/test_glue.cpp                            |  336 ++++++++++++++++++++++++++
 {gui/fb => libdevice/events}/EventDevice.cpp |   14 +-
 {gui/fb => libdevice/events}/InputDevice.cpp |   56 +++--
 {gui/fb => libdevice/events}/InputDevice.h   |   59 +++--
 {gui/fb => libdevice/events}/MouseDevice.cpp |   27 +-
 {gui/fb => libdevice/events}/TouchDevice.cpp |   20 +-
 libdevice/events/events.am                   |   20 ++-
 libdevice/events/test_events.cpp             |  124 ++++++++++
 8 files changed, 572 insertions(+), 84 deletions(-)
 create mode 100644 gui/test_glue.cpp
 copy {gui/fb => libdevice/events}/EventDevice.cpp (98%)
 copy {gui/fb => libdevice/events}/InputDevice.cpp (80%)
 copy {gui/fb => libdevice/events}/InputDevice.h (83%)
 copy {gui/fb => libdevice/events}/MouseDevice.cpp (96%)
 copy {gui/fb => libdevice/events}/TouchDevice.cpp (96%)
 create mode 100644 libdevice/events/test_events.cpp


hooks/post-receive
-- 
Gnash



reply via email to

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