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. 516fc91dd2bbb638ac6a


From: Rob Savoye
Subject: [Gnash-commit] [SCM] Gnash branch, openvg, updated. 516fc91dd2bbb638ac6a5e632772f0a0ad9288cc
Date: Sat, 22 Jan 2011 01:04:24 +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  516fc91dd2bbb638ac6a5e632772f0a0ad9288cc (commit)
       via  0c41a37f696e34bd1a98bd9cc2ba53f5419c9bfb (commit)
       via  0e16b062d6df07b425f4b33f4b60648f1f9cfca4 (commit)
       via  6791e5a9dd60c4463955c10ac3060a0a5d931a5b (commit)
       via  2b011a109017894358505d78711bff446b9e3fc3 (commit)
       via  439d154a5eb8a9c72e58fc15fd18f0de004f8d37 (commit)
       via  e2337eac41e0802575dc72a0194a4e0ac7a68642 (commit)
      from  f5244d73f5ca7944b0aa0abf58adbe0faa7a54a2 (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=516fc91dd2bbb638ac6a5e632772f0a0ad9288cc


commit 516fc91dd2bbb638ac6a5e632772f0a0ad9288cc
Author: Rob Savoye <address@hidden>
Date:   Fri Jan 21 18:04:13 2011 -0700

    properly support Linux input events types that use absolute position 
reporting. Initize the touchscreen input_absinfo.

diff --git a/libdevice/events/EventDevice.cpp b/libdevice/events/EventDevice.cpp
index 425bbac..509d640 100644
--- a/libdevice/events/EventDevice.cpp
+++ b/libdevice/events/EventDevice.cpp
@@ -181,9 +181,10 @@ EventDevice::init(const std::string &filespec, size_t /* 
size */)
           // ON the Babbage board, this is the evdev driver version 1.0.0 
           if (strstr(name, "mxc_ts") != 0) {
               log_debug("Babbage Touchscreen found!");
-              _type = InputDevice::TOUCHSCREEN;
+              _type = InputDevice::TABLET;
           }
           if (strstr(name, "mxckpd") != 0) {
+              log_debug("Babbage Power Button found!");
               _type = InputDevice::POWERBUTTON;
           }
           break;
@@ -201,13 +202,33 @@ EventDevice::init(const std::string &filespec, size_t /* 
size */)
     
     log_debug("Event enabled for %s on fd #%d", _filespec, _fd);
     
+    // Set the scale of the display so the absolute postions
+    // we get from the touchscreen driver are correct.
+    struct input_absinfo abs;
+    abs.minimum = 0;
+    abs.fuzz = 4;
+    abs.flat = 8;
+    abs.resolution = 0;
+    abs.maximum = 800;
+    if (ioctl(_fd, EVIOCSABS(ABS_X), &abs) < 0) {
+        perror("ioctl(EVIOCSABS(ABS_X))");
+    }
+    abs.maximum = 480;
+    if (ioctl(_fd, EVIOCSABS(ABS_Y), &abs) < 0) {
+        perror("ioctl(EVIOCSABS(ABS_Y))");
+    }
+#if 0
+    if (ioctl(_fd, EVIOCGRAB, (void *)1) < 0) {
+        perror("ioctl(EVIOCGRAB(1))");
+    }
+#endif
     return true;
 }
 
 bool
 EventDevice::check()
 {
-    GNASH_REPORT_FUNCTION;
+//    GNASH_REPORT_FUNCTION;
     
     bool activity = false;
   
@@ -221,15 +242,55 @@ EventDevice::check()
     if (!buf) {
         return false;
     }
-    
+
+    /// @note
+    /// A typical touchscreen event is actuall a series of events, one for each
+    /// piece of data. The sequence is terminated by the EV_SYN message. An
+    /// example from evtests looks like this:
+    /// Event: time 697585.633672, type 3 (Absolute), code 0 (X), value 127
+    /// Event: time 697585.633679, type 3 (Absolute), code 1 (Y), value 72
+    /// Event: time 697585.633681, type 3 (Absolute), code 24 (Pressure), 
value 41
+    /// Event: time 697585.633684, type 1 (Key), code 330 (Touch), value 1
+    /// Event: time 697585.633686, -------------- Report Sync ------------
+    ///
+    /// Everytime we get the EV_SYN message we add this fully populated event 
to
+    /// queue of events. As the GUI polls for events, there may be multiple 
events
+    /// in the queue by the time the main event loop comes around to process 
the
+    /// events.
     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);
+    // 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");
+      {
+          boost::shared_ptr<InputDevice::input_data_t> _newdata(new 
InputDevice::input_data_t);
+#if 0
+          std::copy(_input_data.begin(), _input_data.end(), _newdata.begin());
+#else
+          _newdata->pressed = _input_data.pressed;
+          _newdata->key = _input_data.key;
+          _newdata->modifier = _input_data.modifier;
+          _newdata->x = _input_data.x;
+          _newdata->y = _input_data.y;
+          _newdata->button = _input_data.button;
+          _newdata->position = _input_data.position;
+          _newdata->pressure = _input_data.pressure;
+          _newdata->volumne = _input_data.volumne;
+          _newdata->distance = _input_data.distance;
+          _newdata->rx = _input_data.rx;
+          _newdata->ry = _input_data.ry;
+          _newdata->rz = _input_data.rz;
+          _newdata->throttle = _input_data.throttle;
+          _newdata->rudder = _input_data.rudder;
+          _newdata->gas = _input_data.gas;
+          _newdata->brake = _input_data.brake;
+          _newdata->tiltX = _input_data.tiltX;
+          _newdata->tiltY = _input_data.tiltY;
+#endif
+          _data.push(_newdata);
+          activity = true;
           break;
-        // Keyboard event
+      }
+      // Keyboard event
       case EV_KEY:
       {
           // code == scan code of the key (KEY_xxxx defines in input.h)        
 
@@ -248,30 +309,26 @@ EventDevice::check()
               keyb_lalt = ev->value;
           } else if (ev->code == KEY_RIGHTALT) {
               keyb_ralt = ev->value;
+          } else if (ev->code == BTN_TOUCH) {
+              // keyb_ralt = ev->value;
           } else {
-              gnash::key::code  c = scancode_to_gnash_key(ev->code,
-                                            keyb_lshift || keyb_rshift);
+              _input_data.key = scancode_to_gnash_key(ev->code,
+                                                      keyb_lshift || 
keyb_rshift);
                   // build modifier
-              int modifier = gnash::key::GNASH_MOD_NONE;
+              _input_data.modifier = gnash::key::GNASH_MOD_NONE;
               
               if (keyb_lshift || keyb_rshift) {
-                  modifier = modifier | gnash::key::GNASH_MOD_SHIFT;
+                  _input_data.modifier = _input_data.modifier | 
gnash::key::GNASH_MOD_SHIFT;
               }
               
               if (keyb_lctrl || keyb_rctrl) {
-                  modifier = modifier | gnash::key::GNASH_MOD_CONTROL;
+                  _input_data.modifier = _input_data.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;
+                  _input_data.modifier = _input_data.modifier | 
gnash::key::GNASH_MOD_ALT;
               }
+              activity = true;
           } // if normal key
           break;
       } // case EV_KEY
@@ -280,9 +337,79 @@ EventDevice::check()
           log_unimpl("Relative move event from Input Event Device");
           // Touchscreen or joystick
           break;
+          // Absolute coordinates come as multiple events, one for
+          // each axis.
       case EV_ABS:
-          log_unimpl("Absolute move event from Input Event Device");
+      {
+          switch (ev->code) {
+            case ABS_X:
+                // log_debug("ABS_X: %d", ev->value);
+                _input_data.x = ev->value;
+                break;
+            case ABS_Y:
+            {
+                // log_debug("ABS_X: %d ABS_Y: %d", _x, ev->value);
+                _input_data.y = ev->value;
+            }
+                break;
+                // FIXME: Currently the Z axis is ignored
+            case ABS_Z:
+            case ABS_WHEEL:
+                log_debug("ABS_Z: %d", ev->value);
+                break;
+            case ABS_PRESSURE:
+                //log_debug("Pressure: %d", ev->value);
+                _input_data.pressure = ev->value;
+                break;
+            case ABS_VOLUME:
+                log_debug("ABS_VOLUME: %d", ev->value);
+                _input_data.volumne = ev->value;
+                break;
+            case ABS_DISTANCE:
+                log_debug("ABS_DISTANCE: %d", ev->value);
+                _input_data.distance = ev->value;
+                break;
+            case ABS_RX:
+                log_debug("ABS_RX: %d", ev->value);
+                _input_data.rx = ev->value;
+                break;
+            case ABS_RY:
+                log_debug("ABS_RY: %d", ev->value);
+                _input_data.ry = ev->value;
+                break;
+            case ABS_RZ:
+                log_debug("ABS_RZ: %d", ev->value);
+                _input_data.rz = ev->value;
+                break;
+            case ABS_THROTTLE:
+                log_debug("ABS_THROTTLE: %d", ev->value);
+                _input_data.throttle = ev->value;
+                break;
+            case ABS_RUDDER:
+                log_debug("ABS_RUDDER: %d", ev->value);
+                _input_data.rudder = ev->value;
+                break;
+            case ABS_GAS:
+                log_debug("ABS_GAS: %d", ev->value);
+                _input_data.gas = ev->value;
+                break;
+            case ABS_BRAKE:
+                log_debug("ABS_BRAKE: %d", ev->value);
+                _input_data.brake = ev->value;
+                break;
+            case ABS_TILT_X:
+                log_debug("ABS_TILT_X: %d", ev->value);
+                _input_data.tiltX = ev->value;
+                break;
+            case ABS_TILT_Y:
+                log_debug("ABS_TILT_Y: %d", ev->value);
+                _input_data.tiltY = ev->value;
+                break;
+            default:
+                break;
+          }
           break;
+      }
       case EV_MSC:
           log_unimpl("Misc event from Input Event Device");
           break;
@@ -423,7 +550,6 @@ EventDevice::scancode_to_gnash_key(int code, bool shift)
       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;  
@@ -433,7 +559,7 @@ EventDevice::scancode_to_gnash_key(int code, bool shift)
 std::vector<boost::shared_ptr<InputDevice> > 
 EventDevice::scanForDevices()
 {
-    // GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
 
     struct stat st;
 
@@ -483,15 +609,9 @@ EventDevice::scanForDevices()
         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);
-            }
+            devices.push_back(dev);
         }
-
 //        dev->dump();
         
         // setup the next device filespec to try
diff --git a/libdevice/events/MouseDevice.cpp b/libdevice/events/MouseDevice.cpp
index af38ea6..741adcf 100644
--- a/libdevice/events/MouseDevice.cpp
+++ b/libdevice/events/MouseDevice.cpp
@@ -286,36 +286,36 @@ MouseDevice::check()
         log_debug(_("x/y %d/%d button %d"), xmove, ymove, btn);
         
         // movement    
-        _x += xmove;
-        _y += ymove;
+        _input_data.x += xmove;
+        _input_data.y += ymove;
         
-        if (_x < 0) {
-            _x = 0;
+        if (_input_data.x < 0) {
+            _input_data.x = 0;
         }
-        if (_y < 0) {
-            _y = 0;
+        if (_input_data.y < 0) {
+            _input_data.y = 0;
         }
         // FIXME: this is a bit of a temporary hack. The last two
         // arguments are a range, so hardcoding them is safe for
         // now. In the future more conversion may be done, making this
         // then be incorrect.
         boost::shared_array<int> coords =
-            MouseDevice::convertCoordinates(_x, _y, 1024, 768);
+            MouseDevice::convertCoordinates(_input_data.x, _input_data.y, 
1024, 768);
 //          MouseDevice::convertCoordinates(_x, _y,
 //                                 _gui->getStage()->getStageWidth(),
 //                                 _gui->getStage()->getStageHeight());
-        _x = coords[0];
-        _y = coords[1];
+        _input_data.x = coords[0];
+        _input_data.y = coords[1];
     } // end of InputDevice::MOUSE
     
-    log_debug(_("read mouse @ %d / %d, btn %d"), _x, _y, _button);
-    addData(false, gnash::key::INVALID, 0, _x, _y);
+    log_debug(_("read mouse @ %d / %d, btn %d"), _input_data.x, _input_data.y, 
_input_data.button);
+    addData(false, gnash::key::INVALID, 0, _input_data.x, _input_data.y);
     
     // button
-    if (btn != _button) {
-        _button = btn;
+    if (btn != _input_data.button) {
+        _input_data.button = btn;
         log_debug("clicked: %d", btn); 
-        addData(true, gnash::key::INVALID, 0, _x, _y);
+        addData(true, gnash::key::INVALID, 0, _input_data.x, _input_data.y);
         log_debug(_("mouse click! %d"), btn);
     }
     
@@ -363,7 +363,7 @@ MouseDevice::command(unsigned char cmd, unsigned char *buf, 
int count)
 boost::shared_array<int>
 MouseDevice::convertCoordinates(int x, int y, int width, int height)
 {
-    GNASH_REPORT_FUNCTION;
+    // GNASH_REPORT_FUNCTION;
     
     boost::shared_array<int> coords(new int[2]);
 
diff --git a/libdevice/events/TouchDevice.cpp b/libdevice/events/TouchDevice.cpp
index 5a5fbfd..2063071 100644
--- a/libdevice/events/TouchDevice.cpp
+++ b/libdevice/events/TouchDevice.cpp
@@ -98,6 +98,8 @@ TouchDevice::init(const std::string &filespec, size_t /* size 
*/)
         return false;
     }
     
+    _fd = ts_fd(_tsDev);
+    
     log_debug("Using TSLIB on %s", devname);
     return true;
 }
@@ -283,7 +285,16 @@ TouchDevice::scanForDevices()
 
     // Debug strings to make output more readable
     const char *debug[] = {
-        "TSlib"
+        "UNKNOWN",
+        "KEYBOARD",
+        "MOUSE",
+        "TABLET",
+        "TOUCHSCREEN",
+        "TOUCHMOUSE",
+        "POWERBUTTON",
+        "SLEEPBUTTON",
+        "SERIALUSB",
+        "INFRARED"
     };
     
     // Look for these files for mouse input
@@ -301,6 +312,7 @@ TouchDevice::scanForDevices()
     int i = 0;
     while (touch[i].type != InputDevice::UNKNOWN) {
         int fd = 0;
+        // log_debug("Checking for device %s...", touch[i].filespec);
         if (stat(touch[i].filespec, &st) == 0) {
             // Then see if we can open it
             if ((fd = open(touch[i].filespec, O_RDWR)) < 0) {
@@ -309,18 +321,17 @@ TouchDevice::scanForDevices()
                 i++;
                 continue;
             } // open()
-            log_debug("Found a %s device for mouse input using %s",
+            close(fd);
+            log_debug("Found a %s device for touchscreen 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);
+                break;
             }
-            dev->dump();
-            
-            devices.push_back(dev);
+//            dev->dump();
         }     // stat()
-        close(fd);
         i++;
     }         // while()
     
diff --git a/libdevice/events/events.am b/libdevice/events/events.am
index b4bd0c0..1808a06 100644
--- a/libdevice/events/events.am
+++ b/libdevice/events/events.am
@@ -41,7 +41,7 @@ endif
 endif
 
 if ENABLE_DEVELOPER_TESTS
-check_PROGRAMS += test_events 
+check_PROGRAMS += test_events evtest
 test_events_SOURCES = events/test_events.cpp
 test_events_CPPFLAGS = $(AM_CPPFLAGS)
 test_events_LDADD = \
@@ -51,4 +51,12 @@ test_events_LDADD = \
        $(CURL_LIBS) \
        $(EVENTS_LIBS) \
        $(GNASH_LIBS)
+
+evtest_SOURCES = events/evtest.c
+evtest_CPPFLAGS = $(AM_CPPFLAGS)
+evtest_LDADD = \
+       $(EXTRA_EVENTS_LIBS) \
+       $(TS_LIBS) \
+       $(EVENTS_LIBS) \
+       $(GNASH_LIBS)
 endif
\ No newline at end of file
diff --git a/libdevice/events/test_events.cpp b/libdevice/events/test_events.cpp
index 342a822..6779eb4 100644
--- a/libdevice/events/test_events.cpp
+++ b/libdevice/events/test_events.cpp
@@ -102,7 +102,7 @@ main(int argc, char *argv[])
             if (id->check()) {
                 // FIXME: process the input data
                 boost::shared_ptr<InputDevice::input_data_t> ie = 
id->popData();
-#if 1
+#if 0
                 if (ie) {
                     cerr << "Got data: " << ie->pressed;
                     cerr << ", " << ie->key << ", " << ie->modifier;
@@ -113,10 +113,10 @@ main(int argc, char *argv[])
                     cerr << "X = " << coords[0] << endl;
                     cerr << "Y = " << coords[1] << endl;
                 }
+#endif
             } else {
                 std::cerr << ".";
             }
-#endif
         }
         
         // wait the "heartbeat" interval. The default mouse update rate is

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


commit 0c41a37f696e34bd1a98bd9cc2ba53f5419c9bfb
Author: Rob Savoye <address@hidden>
Date:   Fri Jan 21 18:01:55 2011 -0700

    add more event types

diff --git a/libdevice/events/InputDevice.cpp b/libdevice/events/InputDevice.cpp
index e5902fb..73a949b 100644
--- a/libdevice/events/InputDevice.cpp
+++ b/libdevice/events/InputDevice.cpp
@@ -28,13 +28,10 @@ namespace gnash {
 
 InputDevice::InputDevice()
     : _type(InputDevice::UNKNOWN),
-      _fd(-1),
-      _x(0),
-      _y(0),
-      _button(0),
-      _position(0)
+      _fd(-1)
 {
     // GNASH_REPORT_FUNCTION;
+    memset(&_input_data, 0, sizeof(InputDevice::input_data_t));
 }
 
 InputDevice::~InputDevice()
@@ -92,7 +89,7 @@ InputDevice::popData()
 void
 InputDevice::addData(bool pressed, key::code key, int modifier, int x, int y)
 {
-    GNASH_REPORT_FUNCTION;
+    // GNASH_REPORT_FUNCTION;
     
     boost::shared_ptr<input_data_t> _newdata(new input_data_t);
     _newdata->pressed = pressed;
@@ -132,7 +129,7 @@ InputDevice::readData(size_t size)
 //            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);
+        // log_debug ("The device for fd #%d is ready", _fd);
     } else {
         log_error("The device has this error: %s", strerror(errno));
         return inbuf;
@@ -141,7 +138,7 @@ InputDevice::readData(size_t size)
     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));
+        // log_debug("Read %d bytes, %s", ret, hexify(inbuf.get(), ret, 
false));
     } else {
         inbuf.reset();
     }
@@ -157,6 +154,7 @@ InputDevice::dump()
         "UNKNOWN",
         "Keyboard",
         "Mouse",
+        "Tablet",
         "Touchscreen",
         "Touchscreen Mouse",
         "Power Button",
@@ -204,6 +202,22 @@ InputDevice::scanForDevices()
     return devices;
 }
 
+// The Babbage touchscreen gives is absolute coordinates, but they don't
+// match the actual screen resolution. So we convert the coordinates
+// to a new absolute location.
+// For example, if the LCD is 480 x 800, the tablet thinks this is 1010 x 960.
+// This should really use a calibration function, but as we know the numbers...
+boost::shared_array<int>
+InputDevice::convertAbsCoords(int x, int y, int width, int height)
+{
+    boost::shared_array<int> coords(new int[2]);
+
+    coords[0] = (x/width) * x;
+    coords[1] = (y/height) * y;
+    
+    return coords;
+}
+
 // end of gnash namespace
 }
 

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


commit 0e16b062d6df07b425f4b33f4b60648f1f9cfca4
Author: Rob Savoye <address@hidden>
Date:   Fri Jan 21 18:01:29 2011 -0700

    libdevice/events/InputDevice.cpp

diff --git a/libdevice/events/InputDevice.h b/libdevice/events/InputDevice.h
index ddc0c84..9245e34 100644
--- a/libdevice/events/InputDevice.h
+++ b/libdevice/events/InputDevice.h
@@ -36,7 +36,7 @@
 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,
+// The default is to support the devices we prefer for mouse, keyboard,
 // and touchscreen.
 // #define MULTIPLE_DEVICES 1
 
@@ -55,11 +55,26 @@ public:
         int modifier;
         int x;
         int y;
+        int button;
+        int position;
+        int pressure;
+        int volumne;
+        int distance;
+        int rx;
+        int ry;
+        int rz;
+        int throttle;
+        int rudder;
+        int gas;
+        int brake;
+        int tiltX;
+        int tiltY;        
     } input_data_t;
     typedef enum {
         UNKNOWN,
         KEYBOARD,
         MOUSE,
+        TABLET,
         TOUCHSCREEN,
         TOUCHMOUSE,
         POWERBUTTON,
@@ -86,9 +101,11 @@ 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();
-    
+
+    static boost::shared_array<int> convertAbsCoords(int x, int y,
+                                                     int width, int height);
+
     void dump();
 protected:
     void addData(bool pressed, key::code key, int modifier, int x, int y);
@@ -96,11 +113,8 @@ protected:
     devicetype_e        _type;
     std::string         _filespec;
     int                 _fd;
-    int                 _x;
-    int                 _y;
-    // Touchscreens don't have buttons
-    int                 _button;
-    size_t              _position;
+    input_data_t        _input_data;
+    // These hold the data queue
     boost::scoped_array<boost::uint8_t> _buffer;
     std::queue<boost::shared_ptr<input_data_t> > _data;
 };

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


commit 6791e5a9dd60c4463955c10ac3060a0a5d931a5b
Author: Rob Savoye <address@hidden>
Date:   Fri Jan 21 17:44:37 2011 -0700

    only minor reformatting changes

diff --git a/librender/agg/Renderer_agg.cpp b/librender/agg/Renderer_agg.cpp
index a245617..a0cbb88 100644
--- a/librender/agg/Renderer_agg.cpp
+++ b/librender/agg/Renderer_agg.cpp
@@ -209,8 +209,7 @@ analyzePaths(const GnashPaths &paths, bool& have_shape,
     
     const int pcount = paths.size();
     
-    for (int pno=0; pno<pcount; ++pno) {
-       
+    for (int pno=0; pno<pcount; ++pno) {       
         const Path &the_path = paths[pno];
        
         if ((the_path.m_fill0 > 0) || (the_path.m_fill1 > 0)) {
@@ -233,7 +232,7 @@ public:
         :
         _path(path),
         _shift(shift)
-    {}
+    { }
 
     void operator()(const Edge& edge)
     {
@@ -264,8 +263,7 @@ public:
         _dest(dest),
         _it(_dest.begin()),
         _shift(shift)
-    {
-    }
+    { }
 
     void operator()(const Path& in)
     {
@@ -457,7 +455,7 @@ public:
     EmptyVideoRenderer(const ClipBounds& clipbounds)
         :
         _clipbounds(clipbounds)
-    {}
+    { }
 
     void render(agg::path_storage& path, Renderer& rbase,
         const AlphaMasks& masks)
@@ -466,8 +464,7 @@ public:
             // No mask active
             agg::scanline_p8 sl;
             renderScanlines(path, rbase, sl);
-        }
-        else {
+        } else {
             // Untested.
             typedef agg::scanline_u8_am<agg::alpha_mask_gray8> Scanline;
             Scanline sl(masks.back()->getMask());
@@ -485,8 +482,7 @@ private:
         agg::renderer_scanline_aa_solid<Renderer> ren_sl(rbase);
 
         for (ClipBounds::const_iterator i = _clipbounds.begin(),
-            e = _clipbounds.end(); i != e; ++i)
-        {
+            e = _clipbounds.end(); i != e; ++i) {
             const ClipBounds::value_type& cb = *i;
             applyClipBox<Rasterizer>(ras, cb);
             ras.add_path(path);
@@ -584,20 +580,19 @@ public:
     void render(agg::path_storage& path, Renderer& rbase,
             const AlphaMasks& masks)
     {
-        switch (_quality)
-        {
-            case QUALITY_BEST:
-            case QUALITY_HIGH:
-                if (_smoothing) {
-                    renderFrame<HighQualityFilter>(path, rbase, masks);
-                }
-                else renderFrame<LowQualityFilter>(path, rbase, masks);
-                break;
-            case QUALITY_MEDIUM:
-            case QUALITY_LOW:
-                // FIXME: Should this be still lower quality?
-                renderFrame<LowQualityFilter>(path, rbase, masks);
-                break;
+        switch (_quality) {
+         case QUALITY_BEST:
+         case QUALITY_HIGH:
+             if (_smoothing) {
+                 renderFrame<HighQualityFilter>(path, rbase, masks);
+             }
+             else renderFrame<LowQualityFilter>(path, rbase, masks);
+             break;
+         case QUALITY_MEDIUM:
+         case QUALITY_LOW:
+             // FIXME: Should this be still lower quality?
+             renderFrame<LowQualityFilter>(path, rbase, masks);
+             break;
         }
     }
     
@@ -613,8 +608,7 @@ private:
             // No mask active
             agg::scanline_u8 sl;
             renderScanlines(path, rbase, sl, sg);
-        }
-        else {
+        } else {
             // Untested.
             typedef agg::scanline_u8_am<agg::alpha_mask_gray8> Scanline;
             Scanline sl(masks.back()->getMask());
@@ -628,13 +622,11 @@ private:
     {
         Rasterizer _ras;
         for (ClipBounds::const_iterator i = _clipbounds.begin(),
-            e = _clipbounds.end(); i != e; ++i)
-        {
+                e = _clipbounds.end(); i != e; ++i) {
             const ClipBounds::value_type& cb = *i;
             applyClipBox<Rasterizer> (_ras, cb);
-
+           
             _ras.add_path(path);
-
             agg::render_scanlines_aa(_ras, sl, rbase, _sa, sg);
         }
     }
@@ -685,14 +677,12 @@ public:
     // bitmap fill style.
     gnash::CachedBitmap* createCachedBitmap(std::auto_ptr<image::GnashImage> 
im)
     {        
-       GNASH_REPORT_FUNCTION;
         return new agg_bitmap_info(im);
     }
 
     virtual void renderToImage(boost::shared_ptr<IOChannel> io,
             FileType type, int quality) const
     {
-       GNASH_REPORT_FUNCTION;
         image::ImageRGBA im(xres, yres);
         for (int x = 0; x < xres; ++x) {
             for (int y = 0; y < yres; ++y) {
@@ -785,95 +775,89 @@ public:
         }
 #endif
 
-        switch (frame->type())
-        {
-            case image::TYPE_RGBA:
-                renderVideo<agg::pixfmt_rgba32_pre>(*frame, mtx, path, smooth);
-                break;
-            case image::TYPE_RGB:
-                renderVideo<agg::pixfmt_rgb24_pre>(*frame, mtx, path, smooth);
-                break;
-            default:
-                log_error("Can't render this type of frame");
-                break;
+        switch (frame->type()) {
+         case image::TYPE_RGBA:
+             renderVideo<agg::pixfmt_rgba32_pre>(*frame, mtx, path, smooth);
+             break;
+         case image::TYPE_RGB:
+             renderVideo<agg::pixfmt_rgb24_pre>(*frame, mtx, path, smooth);
+             break;
+         default:
+             log_error("Can't render this type of frame");
+             break;
         }
-
     } 
 
   // Constructor
-  Renderer_agg(int bits_per_pixel)
-      :
-      xres(1),
-      yres(1),
-      bpp(bits_per_pixel),
-      scale_set(false),
-      m_display_width(0.0),
-      m_display_height(0.0),
-      m_drawing_mask(false)
-  {
-      // TODO: we really don't want to set the scale here as the core should
-      // tell us the right values before rendering anything. However this is
-      // currently difficult to implement. Removing the next call will
-      // lead to an assertion failure in begin_display() because we check
-      // whether the scale is known there.
-      set_scale(1.0f, 1.0f);
-  }   
-
-  /// Initializes the rendering buffer. The memory pointed by "mem" is not
-  /// owned by the renderer and init_buffer() may be called multiple times
-  /// when the buffer size changes, for example. However, bits_per_pixel must
-  /// remain the same. 
-  /// rowstride is the size, in bytes, of one row.
-  /// This method *must* be called prior to any other method of the class!
+    Renderer_agg(int bits_per_pixel)
+       :
+       xres(1),
+       yres(1),
+       bpp(bits_per_pixel),
+       scale_set(false),
+       m_display_width(0.0),
+       m_display_height(0.0),
+       m_drawing_mask(false)
+       {
+           // TODO: we really don't want to set the scale here as the core 
should
+           // tell us the right values before rendering anything. However this 
is
+           // currently difficult to implement. Removing the next call will
+           // lead to an assertion failure in begin_display() because we check
+           // whether the scale is known there.
+           set_scale(1.0f, 1.0f);
+       }   
+    
+    /// Initializes the rendering buffer. The memory pointed by "mem" is not
+    /// owned by the renderer and init_buffer() may be called multiple times
+    /// when the buffer size changes, for example. However, bits_per_pixel must
+    /// remain the same. 
+    /// rowstride is the size, in bytes, of one row.
+    /// This method *must* be called prior to any other method of the class!
     void init_buffer(unsigned char *mem, int /* size */, int x, int y, int 
rowstride)
-  {
-       GNASH_REPORT_FUNCTION;
-      assert(x > 0);
-      assert(y > 0);
-
-    xres    = x;
-    yres    = y;
-    
-    m_rbuf.attach(mem, xres, yres, rowstride);
-
-    // allocate pixel format accessor and renderer_base
-    m_pixf.reset(new PixelFormat(m_rbuf));
-    m_rbase.reset(new renderer_base(*m_pixf));  
-    
-    // by default allow drawing everywhere
-    set_invalidated_region_world();
-  }
-  
-
-  void begin_display(const gnash::rgba& bg,
-      int /*viewport_width*/, int /*viewport_height*/,
-      float /*x0*/, float /*x1*/, float /*y0*/, float /*y1*/)
-  {
-       GNASH_REPORT_FUNCTION;
-       assert(m_pixf.get());
-       
-       assert(scale_set);
-       
-       // Render images list is cleared here because the GUI may want
-    // them for display after ::end_display()
-    _render_images.clear();
-
-    // clear the stage using the background color
-    if ( ! _clipbounds.empty() ) {
-        const agg::rgba8& col = agg::rgba8_pre(bg.m_r, bg.m_g, bg.m_b, bg.m_a);
-        for (ClipBounds::const_iterator i = _clipbounds.begin(),
-                e = _clipbounds.end(); i!= e; ++i) {
-           clear_framebuffer(*i, col);
+       {
+           assert(x > 0);
+           assert(y > 0);
+           
+           xres    = x;
+           yres    = y;
+           
+           m_rbuf.attach(mem, xres, yres, rowstride);
+           
+           // allocate pixel format accessor and renderer_base
+           m_pixf.reset(new PixelFormat(m_rbuf));
+           m_rbase.reset(new renderer_base(*m_pixf));  
+           
+           // by default allow drawing everywhere
+           set_invalidated_region_world();
        }
-    }
     
-    // reset status variables
-    m_drawing_mask = false;
-  }
- 
-    virtual Renderer* startInternalRender(image::GnashImage& im) {
-       GNASH_REPORT_FUNCTION;
+    void begin_display(const gnash::rgba& bg,
+                      int /*viewport_width*/, int /*viewport_height*/,
+                      float /*x0*/, float /*x1*/, float /*y0*/, float /*y1*/)
+       {
+           assert(m_pixf.get());
+           
+           assert(scale_set);
+           
+           // Render images list is cleared here because the GUI may want
+           // them for display after ::end_display()
+           _render_images.clear();
+           
+           // clear the stage using the background color
+           if ( ! _clipbounds.empty() ) {
+               const agg::rgba8& col = agg::rgba8_pre(bg.m_r, bg.m_g, bg.m_b, 
bg.m_a);
+               for (ClipBounds::const_iterator i = _clipbounds.begin(),
+                        e = _clipbounds.end(); i!= e; ++i) {
+                   clear_framebuffer(*i, col);
+               }
+           }
+           
+           // reset status variables
+           m_drawing_mask = false;
+       }
     
+    virtual Renderer* startInternalRender(image::GnashImage& im)
+       {
         std::auto_ptr<Renderer_agg_base> in;
     
         switch (im.type()) {
@@ -897,7 +881,6 @@ public:
     }
 
     virtual void endInternalRender() {
-       GNASH_REPORT_FUNCTION;
         _external.reset();
     }
 
@@ -909,8 +892,6 @@ public:
     void clear_framebuffer(const geometry::Range2d<int>& region,
         const agg::rgba8& color)
     {
-       GNASH_REPORT_FUNCTION;
-
         assert(region.isFinite());
 
         // add 1 to width since we have still to draw a pixel when 
@@ -933,8 +914,6 @@ public:
     // Clean up after rendering a frame. 
     void end_display()
     {
-       GNASH_REPORT_FUNCTION;
-       
         if (m_drawing_mask) {
             log_debug(_("Warning: rendering ended while drawing a mask"));
         }
@@ -950,8 +929,6 @@ public:
     void drawLine(const std::vector<point>& coords, const rgba& color,
             const SWFMatrix& line_mat)
     {
-       GNASH_REPORT_FUNCTION;
-
         assert(m_pixf.get());
         
         if (_clipbounds.empty()) return;
@@ -974,7 +951,6 @@ public:
         
         // We've asserted that it has at least one element.
         Points::const_iterator i = coords.begin();
-
         point pnt;
 
         mat.transform(&pnt, *i);
@@ -982,26 +958,22 @@ public:
 
         ++i;
 
-        for (const Points::const_iterator e = coords.end(); i != e; ++i)
-        {
+        for (const Points::const_iterator e = coords.end(); i != e; ++i) {
             mat.transform(&pnt, *i);
             path.line_to(pnt.x, pnt.y);
         }
-
+       
         if (_alphaMasks.empty()) {
             // No mask active
             agg::scanline_p8 sl;      
             lr.render(sl, stroke, color);
-        }
-        else {
+        } else {
             // Mask is active!
             typedef agg::scanline_u8_am<agg::alpha_mask_gray8> sl_type;
             sl_type sl(_alphaMasks.back()->getMask());      
             lr.render(sl, stroke, color);
         }
-
-    } 
-
+    }
 
     void begin_submit_mask()
     {
@@ -1011,126 +983,121 @@ public:
         AlphaMask* new_mask = new AlphaMask(xres, yres);
 
         for (ClipBounds::const_iterator i = _clipbounds.begin(), 
-                e = _clipbounds.end(); i != e; ++i) {
+                e = _clipbounds.end(); i != e; ++i) {
             new_mask->clear(*i);
         }
-
+       
         _alphaMasks.push_back(new_mask);
     }
-
-    void end_submit_mask()
-    {
-        m_drawing_mask = false;
-    }
-
-    void disable_mask()
-    {
-        assert( ! _alphaMasks.empty() );
-        delete _alphaMasks.back();
-        _alphaMasks.pop_back();
-    }
-  
-
-  void drawGlyph(const SWF::ShapeRecord& shape, const rgba& color,
-          const SWFMatrix& mat) 
-  {
-       GNASH_REPORT_FUNCTION;
     
-    // select relevant clipping bounds
-    if (shape.getBounds().is_null()) {
-        return;
-    } 
-    select_clipbounds(shape.getBounds(), mat);
-    
-    if (_clipbounds_selected.empty()) return; 
-      
-    GnashPaths paths;
-    apply_matrix_to_path(shape.paths(), paths, mat);
-
-    // If it's a mask, we don't need the rest.
-    if (m_drawing_mask) {
-      draw_mask_shape(paths, false);
-      return;
-    }
-
-    // convert gnash paths to agg paths.
-    AggPaths agg_paths;    
-    buildPaths(agg_paths, paths);
- 
-    std::vector<FillStyle> v(1, FillStyle(SolidFill(color)));
-
-    // prepare style handler
-    StyleHandler sh;
-    build_agg_styles(sh, v, mat, SWFCxForm());
-    
-    draw_shape(-1, paths, agg_paths, sh, false);
+    void end_submit_mask()
+       {
+           m_drawing_mask = false;
+       }
     
-    // NOTE: Do not use even-odd filling rule for glyphs!
+    void disable_mask()
+       {
+           assert( ! _alphaMasks.empty() );
+           delete _alphaMasks.back();
+           _alphaMasks.pop_back();
+       }
     
-    // clear clipping ranges to ease debugging
-    _clipbounds_selected.clear();
-  }
-
-
-  /// Fills _clipbounds_selected with pointers to _clipbounds members who
-  /// intersect with the given character (transformed by mat). This avoids
-  /// rendering of characters outside a particular clipping range.
-  /// "_clipbounds_selected" is used by draw_shape() and draw_outline() and
-  /// *must* be initialized prior to using those function.
-  void select_clipbounds(const SWFRect& objectBounds, const SWFMatrix& 
source_mat)
-  {
     
-    SWFMatrix mat = stage_matrix;
-    mat.concatenate(source_mat);
-  
-    _clipbounds_selected.clear();
-    _clipbounds_selected.reserve(_clipbounds.size());
-
-    if (objectBounds.is_null()) {
-      log_debug(_("Warning: select_clipbounds encountered a character "
-                  "definition with null bounds"));
-      return;
-    }   
-
-    SWFRect bounds;    
-    bounds.set_null();
-    bounds.expand_to_transformed_rect(mat, objectBounds);
+    void drawGlyph(const SWF::ShapeRecord& shape, const rgba& color,
+                  const SWFMatrix& mat) 
+       {
+           // select relevant clipping bounds
+           if (shape.getBounds().is_null()) {
+               return;
+           } 
+           select_clipbounds(shape.getBounds(), mat);
+           
+           if (_clipbounds_selected.empty()) return; 
+           
+           GnashPaths paths;
+           apply_matrix_to_path(shape.paths(), paths, mat);
+           
+           // If it's a mask, we don't need the rest.
+           if (m_drawing_mask) {
+               draw_mask_shape(paths, false);
+               return;
+           }
+           
+           // convert gnash paths to agg paths.
+           AggPaths agg_paths;    
+           buildPaths(agg_paths, paths);
+           
+           std::vector<FillStyle> v(1, FillStyle(SolidFill(color)));
+           
+           // prepare style handler
+           StyleHandler sh;
+           build_agg_styles(sh, v, mat, SWFCxForm());
+           
+           draw_shape(-1, paths, agg_paths, sh, false);
+           
+           // NOTE: Do not use even-odd filling rule for glyphs!
+           
+           // clear clipping ranges to ease debugging
+           _clipbounds_selected.clear();
+       }
     
-    assert(bounds.getRange().isFinite());
     
-    const int count = _clipbounds.size();
-    for (int cno=0; cno<count; ++cno) {
-          
-      if (_clipbounds[cno].intersects(bounds.getRange())) 
-        _clipbounds_selected.push_back(&_clipbounds[cno]);
-
-    }  
-  }
-  
-  void select_all_clipbounds() {
-  
-    if (_clipbounds_selected.size() == _clipbounds.size()) return; 
-  
-    _clipbounds_selected.clear();
-    _clipbounds_selected.reserve(_clipbounds.size());
+    /// Fills _clipbounds_selected with pointers to _clipbounds members who
+    /// intersect with the given character (transformed by mat). This avoids
+    /// rendering of characters outside a particular clipping range.
+    /// "_clipbounds_selected" is used by draw_shape() and draw_outline() and
+    /// *must* be initialized prior to using those function.
+    void select_clipbounds(const SWFRect& objectBounds, const SWFMatrix& 
source_mat)
+       {
+           
+           SWFMatrix mat = stage_matrix;
+           mat.concatenate(source_mat);
+           
+           _clipbounds_selected.clear();
+           _clipbounds_selected.reserve(_clipbounds.size());
+           
+           if (objectBounds.is_null()) {
+               log_debug(_("Warning: select_clipbounds encountered a character 
"
+                           "definition with null bounds"));
+               return;
+           }   
+           
+           SWFRect bounds;    
+           bounds.set_null();
+           bounds.expand_to_transformed_rect(mat, objectBounds);
+           
+           assert(bounds.getRange().isFinite());
+           
+           const int count = _clipbounds.size();
+           for (int cno=0; cno<count; ++cno) {
+               
+               if (_clipbounds[cno].intersects(bounds.getRange())) 
+                   _clipbounds_selected.push_back(&_clipbounds[cno]);
+               
+           }  
+       }
     
-    for (ClipBounds::iterator i = _clipbounds.begin(),
-            e = _clipbounds.end(); i != e; ++i)
-    {
-      _clipbounds_selected.push_back(&(*i));
+    void select_all_clipbounds() {
+       
+       if (_clipbounds_selected.size() == _clipbounds.size()) return; 
+       
+       _clipbounds_selected.clear();
+       _clipbounds_selected.reserve(_clipbounds.size());
+       
+       for (ClipBounds::iterator i = _clipbounds.begin(),
+                e = _clipbounds.end(); i != e; ++i) {
+           _clipbounds_selected.push_back(&(*i));
+       }
     }
-  }
-
+    
     void drawShape(const SWF::ShapeRecord& shape, const Transform& xform)
     {
-       GNASH_REPORT_FUNCTION;
         // check if the character needs to be rendered at all
         SWFRect cur_bounds;
 
         cur_bounds.expand_to_transformed_rect(xform.matrix, shape.getBounds());
                 
-        if (!Renderer::bounds_in_clipping_area(cur_bounds))
-        {
+        if (!Renderer::bounds_in_clipping_area(cur_bounds)) {
             return; // no need to draw
         }        
         
@@ -1151,8 +1118,6 @@ public:
         const std::vector<Path>& objpaths, const SWFMatrix& mat,
         const SWFCxForm& cx)
     {
-       GNASH_REPORT_FUNCTION;
-
         bool have_shape, have_outline;
 
         analyzePaths(objpaths, have_shape, have_outline);
@@ -1168,7 +1133,6 @@ public:
         // Masks apparently do not use agg_paths, so return
         // early
         if (m_drawing_mask) {
-
             // Shape is drawn inside a mask, skip sub-shapes handling and
             // outlines
             draw_mask_shape(paths, false); 
@@ -1203,8 +1167,7 @@ public:
         // We need to separate sub-shapes during rendering. 
         const unsigned int subshape_count = count_sub_shapes(paths);
 
-        for (unsigned int subshape=0; subshape<subshape_count; ++subshape)
-        {
+        for (unsigned int subshape=0; subshape<subshape_count; ++subshape) {
             if (have_shape) {
                 draw_shape(subshape, paths, agg_paths, sh, true);        
             }
@@ -1240,830 +1203,801 @@ public:
     } 
 
 
-  /// A shape can have sub-shapes. This can happen when there are multiple
-  /// layers of the same frame count. Flash combines them to one single shape.
-  /// The problem with sub-shapes is, that outlines can be hidden by other
-  /// layers so they must be rendered separately. 
-  unsigned int count_sub_shapes(const GnashPaths &path_in)
-  {
-    unsigned int sscount=1;
-    const size_t pcnt = path_in.size();
-    
-    for (size_t pno=0; pno<pcnt; ++pno) {
-      const Path& this_path = path_in[pno];
-      
-      if (this_path.m_new_shape)
-        sscount++;
-    }
+    /// A shape can have sub-shapes. This can happen when there are multiple
+    /// layers of the same frame count. Flash combines them to one single 
shape.
+    /// The problem with sub-shapes is, that outlines can be hidden by other
+    /// layers so they must be rendered separately. 
+    unsigned int count_sub_shapes(const GnashPaths &path_in)
+       {
+           unsigned int sscount=1;
+           const size_t pcnt = path_in.size();
+           
+           for (size_t pno=0; pno<pcnt; ++pno) {
+               const Path& this_path = path_in[pno];
+               
+               if (this_path.m_new_shape)
+                   sscount++;
+           }
+           
+           return sscount;
+       }
     
-    return sscount;
-  }
-
-  // Version of buildPaths that uses rounded coordinates (pixel hinting)
-  // for line styles that want it.  
-  // This is used for outlines which are aligned to the pixel grid to avoid
-  // anti-aliasing problems (a perfect horizontal line being drawn over two
-  // lines and looking blurry). The proprietary player does this too.  
-  //
-  // Not all points are aligned, only those lines that:
-  //   - are straight
-  //   - are pure horizontal or vertical
-  // Also, single segments of a path may be aligned or not depending on 
-  // the segment properties (this matches MM player behaviour)
-  //
-  // This function - in contrast to buildPaths() - also checks noClose 
-  // flag and automatically closes polygons.
-  //
-  // TODO: Flash never aligns lines that are wider than 1 pixel on *screen*,
-  // but we currently don't check the width.  
-  void buildPaths_rounded(AggPaths& dest, 
-    const GnashPaths& paths, const std::vector<LineStyle>& line_styles)
-  {
-
-    const float subpixel_offset = 0.5f;
-    
-    const size_t pcount = paths.size();
-
-    dest.resize(pcount);    
-    
-    for (size_t pno=0; pno<pcount; ++pno) {
-      
-      const Path& this_path = paths[pno];
-      agg::path_storage& new_path = dest[pno];
-      
-      bool hinting=false, closed=false, hairline=false;
-      
-      if (this_path.m_line) {
-        const LineStyle& lstyle = line_styles[this_path.m_line-1];
-        
-        hinting = lstyle.doPixelHinting();
-        closed = this_path.isClosed() && !lstyle.noClose();
-        
-        // check if this line is a hairline ON SCREEN
-        // TODO: we currently only check for hairlines per definiton, not
-        // for thin lines that become hair lines due to scaling
-        if (lstyle.getThickness()<=20)
-          hairline = true;
-      }
-      
-      float prev_ax = twipsToPixels(this_path.ap.x);
-      float prev_ay = twipsToPixels(this_path.ap.y);  
-      bool prev_align_x = true;
-      bool prev_align_y = true;
-      
-      size_t ecount = this_path.m_edges.size();
-
-      // avoid extra edge when doing implicit close later
-      if (closed && ecount && 
-        this_path.m_edges.back().straight()) --ecount;  
-      
-      for (size_t eno=0; eno<ecount; ++eno) {
-        
-        const Edge& this_edge = this_path.m_edges[eno];
-        
-        float this_ax = twipsToPixels(this_edge.ap.x);  
-        float this_ay = twipsToPixels(this_edge.ap.y);  
-        
-        if (hinting || this_edge.straight()) {
-        
-          // candidate for alignment?
-          bool align_x = hinting || (hairline && (prev_ax == this_ax));
-          bool align_y = hinting || (hairline && (prev_ay == this_ay));
-          
-          if (align_x) 
-            this_ax = round(this_ax);
-          
-          if (align_y)
-            this_ay = round(this_ay);
-          
-          // first line?
-          if (eno==0) {
-          
-            if (align_x) 
-              prev_ax = round(prev_ax);
-              
-            if (align_y)
-              prev_ay = round(prev_ay);
-              
-            new_path.move_to(prev_ax + subpixel_offset, 
-              prev_ay + subpixel_offset);
-            
-          } else {
-          
-            // not the first line, but the previous anchor point
-            // might belong to a curve and thus may not be aligned.
-            // We need to have both anchors of this new line to be
-            // aligned, so it may be neccesary to add a line
-            if ((align_x && !prev_align_x) || (align_y && !prev_align_y)) {
-            
-              if (align_x) 
-                prev_ax = round(prev_ax);
-                
-              if (align_y)
-                prev_ay = round(prev_ay);
-                
-              new_path.line_to(prev_ax + subpixel_offset, 
-                prev_ay + subpixel_offset);
-              
-            }
-            
-            // TODO: (minor flaw) Flash player never aligns anchor points
-            // of curves, even if they are attached to straight vertical
-            // or horizontal lines. It can be seen easily with rounded
-            // rectangles, where the curves are never aligned and all 
-            // straight lines are. AGG backend will align the curve anchor
-            // point that follows the straight line. It's not a big problem
-            // but it's not exact...
-          
-          }
-        
-          new_path.line_to(this_ax + subpixel_offset, 
-            this_ay + subpixel_offset);
-          
-          prev_align_x = align_x;
-          prev_align_y = align_y;  
-          
-          
-        } else {
-          
-          // first line?
-          if (eno==0) 
-            new_path.move_to(prev_ax, prev_ay);
-        
-          // never align curves!
-          new_path.curve3(
-            twipsToPixels(this_edge.cp.x) + subpixel_offset, 
-            twipsToPixels(this_edge.cp.y) + subpixel_offset,
-            this_ax + subpixel_offset, 
-            this_ay + subpixel_offset);
-            
-          prev_align_x = false;
-          prev_align_y = false;  
-            
-        }
-        
-        prev_ax = this_ax;
-        prev_ay = this_ay;    
-        
-      } //for
-      
-      if (closed)
-        new_path.close_polygon();
+    // Version of buildPaths that uses rounded coordinates (pixel hinting)
+    // for line styles that want it.  
+    // This is used for outlines which are aligned to the pixel grid to avoid
+    // anti-aliasing problems (a perfect horizontal line being drawn over two
+    // lines and looking blurry). The proprietary player does this too.  
+    //
+    // Not all points are aligned, only those lines that:
+    //   - are straight
+    //   - are pure horizontal or vertical
+    // Also, single segments of a path may be aligned or not depending on 
+    // the segment properties (this matches MM player behaviour)
+    //
+    // This function - in contrast to buildPaths() - also checks noClose 
+    // flag and automatically closes polygons.
+    //
+    // TODO: Flash never aligns lines that are wider than 1 pixel on *screen*,
+    // but we currently don't check the width.  
+    void buildPaths_rounded(AggPaths& dest, 
+                           const GnashPaths& paths, const 
std::vector<LineStyle>& line_styles)
+       {
+           
+           const float subpixel_offset = 0.5f;
+           
+           const size_t pcount = paths.size();
+           
+           dest.resize(pcount);    
+           
+           for (size_t pno=0; pno<pcount; ++pno) {
+               
+               const Path& this_path = paths[pno];
+               agg::path_storage& new_path = dest[pno];
+               
+               bool hinting=false, closed=false, hairline=false;
+               
+               if (this_path.m_line) {
+                   const LineStyle& lstyle = line_styles[this_path.m_line-1];
+                   
+                   hinting = lstyle.doPixelHinting();
+                   closed = this_path.isClosed() && !lstyle.noClose();
+                   
+                   // check if this line is a hairline ON SCREEN
+                   // TODO: we currently only check for hairlines per 
definiton, not
+                   // for thin lines that become hair lines due to scaling
+                   if (lstyle.getThickness()<=20)
+                       hairline = true;
+               }
+               
+               float prev_ax = twipsToPixels(this_path.ap.x);
+               float prev_ay = twipsToPixels(this_path.ap.y);  
+               bool prev_align_x = true;
+               bool prev_align_y = true;
+               
+               size_t ecount = this_path.m_edges.size();
+               
+               // avoid extra edge when doing implicit close later
+               if (closed && ecount && 
+                   this_path.m_edges.back().straight()) --ecount;  
+               
+               for (size_t eno=0; eno<ecount; ++eno) {
+                   
+                   const Edge& this_edge = this_path.m_edges[eno];
+                   
+                   float this_ax = twipsToPixels(this_edge.ap.x);  
+                   float this_ay = twipsToPixels(this_edge.ap.y);  
+                   
+                   if (hinting || this_edge.straight()) {
+                       
+                       // candidate for alignment?
+                       bool align_x = hinting || (hairline && (prev_ax == 
this_ax));
+                       bool align_y = hinting || (hairline && (prev_ay == 
this_ay));
+                       
+                       if (align_x) {
+                           this_ax = round(this_ax);
+                       }
+                       if (align_y) {
+                           this_ay = round(this_ay);
+                       }
+                       
+                       // first line?
+                       if (eno==0) {
+                           if (align_x) {
+                               prev_ax = round(prev_ax);
+                           }
+                           if (align_y) {
+                               prev_ay = round(prev_ay);
+                           }
+                           new_path.move_to(prev_ax + subpixel_offset, 
+                                            prev_ay + subpixel_offset);
+                       } else {
+                           
+                           // not the first line, but the previous anchor point
+                           // might belong to a curve and thus may not be 
aligned.
+                           // We need to have both anchors of this new line to 
be
+                           // aligned, so it may be neccesary to add a line
+                           if ((align_x && !prev_align_x) || (align_y && 
!prev_align_y)) {
+                               
+                               if (align_x) 
+                                   prev_ax = round(prev_ax);
+                               
+                               if (align_y)
+                                   prev_ay = round(prev_ay);
+                               
+                               new_path.line_to(prev_ax + subpixel_offset, 
+                                                prev_ay + subpixel_offset);
+                               
+                           }
+                           
+                           // TODO: (minor flaw) Flash player never aligns 
anchor points
+                           // of curves, even if they are attached to straight 
vertical
+                           // or horizontal lines. It can be seen easily with 
rounded
+                           // rectangles, where the curves are never aligned 
and all 
+                           // straight lines are. AGG backend will align the 
curve anchor
+                           // point that follows the straight line. It's not a 
big problem
+                           // but it's not exact...
+                           
+                       }
+                       
+                       new_path.line_to(this_ax + subpixel_offset, 
+                                        this_ay + subpixel_offset);
+                       
+                       prev_align_x = align_x;
+                       prev_align_y = align_y;  
+                       
+                       
+                   } else {
+                       
+                       // first line?
+                       if (eno==0) 
+                           new_path.move_to(prev_ax, prev_ay);
+                       
+                       // never align curves!
+                       new_path.curve3(
+                           twipsToPixels(this_edge.cp.x) + subpixel_offset, 
+                           twipsToPixels(this_edge.cp.y) + subpixel_offset,
+                           this_ax + subpixel_offset, 
+                           this_ay + subpixel_offset);
+                       
+                       prev_align_x = false;
+                       prev_align_y = false;  
+                       
+                   }
+                   
+                   prev_ax = this_ax;
+                   prev_ay = this_ay;    
+                   
+               } //for
+               
+               if (closed)
+                   new_path.close_polygon();
+               
+           }
+       } //buildPaths_rounded
     
-    }
-  } //buildPaths_rounded
-
     // Initializes the internal styles class for AGG renderer
     void build_agg_styles(StyleHandler& sh,
-        const std::vector<FillStyle>& FillStyles,
-        const SWFMatrix& fillstyle_matrix, const SWFCxForm& cx) {
-    
+                         const std::vector<FillStyle>& FillStyles,
+                         const SWFMatrix& fillstyle_matrix, const SWFCxForm& 
cx) {
+       
         SWFMatrix inv_stage_matrix = stage_matrix;
         inv_stage_matrix.invert();
-    
+       
         const size_t fcount = FillStyles.size();
-
+       
         for (size_t fno = 0; fno < fcount; ++fno) {
             const AddStyles st(stage_matrix, fillstyle_matrix, cx, sh,
-                    _quality);
+                              _quality);
             boost::apply_visitor(st, FillStyles[fno].fill);
         } 
     } 
-  
-
-  /// Draws the given path using the given fill style and color transform.
-  //
-  /// Normally, Flash shapes are drawn using even-odd filling rule. However,
-  /// for glyphs non-zero filling rule should be used (even_odd=0).
-  /// Note the paths have already been transformed by the SWFMatrix and 
-  /// 'subshape_id' defines which sub-shape should be drawn (-1 means all 
-  /// subshapes).
-  ///
-  /// Note the *coordinates* in "paths" are not used because they are 
-  /// already prepared in agg_paths. The (nearly ambiguous) "path" parameter
-  /// is used to access other properties like fill styles and subshapes.   
-  ///
-  /// @param subshape_id
-  ///    Defines which subshape to draw. -1 means all subshapes.
-  ///
-  void draw_shape(int subshape_id, const GnashPaths &paths,
-    const AggPaths& agg_paths,  
-    StyleHandler& sh, bool even_odd) {
-    
-    if (_alphaMasks.empty()) {
-    
-      // No mask active, use normal scanline renderer
-      
-      typedef agg::scanline_u8 scanline_type;
-      
-      scanline_type sl;
-      
-      draw_shape_impl<scanline_type> (subshape_id, paths, agg_paths, 
-        sh, even_odd, sl);
-        
-    } else {
     
-      // Mask is active, use alpha mask scanline renderer
-      
-      typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
-      
-      scanline_type sl(_alphaMasks.back()->getMask());
-      
-      draw_shape_impl<scanline_type> (subshape_id, paths, agg_paths, 
-        sh, even_odd, sl);
-        
-    }
     
-  }
-   
-  /// Template for draw_shape(). Two different scanline types are suppored, 
-  /// one with and one without an alpha mask. This makes drawing without masks
-  /// much faster.  
-  template <class scanline_type>
-  void draw_shape_impl(int subshape_id, const GnashPaths &paths,
-    const AggPaths& agg_paths,
-    StyleHandler& sh, bool even_odd, scanline_type& sl) {
-    /*
-    Fortunately, AGG provides a rasterizer that fits perfectly to the flash
-    data model. So we just have to feed AGG with all data and we're done. :-)
-    This is also far better than recomposing the polygons as the rasterizer
-    can do everything in one pass and it is also better for adjacent edges
-    (anti aliasing).
-    Thank to Maxim Shemanarev for providing us such a great tool with AGG...
-    */
+    /// Draws the given path using the given fill style and color transform.
+    //
+    /// Normally, Flash shapes are drawn using even-odd filling rule. However,
+    /// for glyphs non-zero filling rule should be used (even_odd=0).
+    /// Note the paths have already been transformed by the SWFMatrix and 
+    /// 'subshape_id' defines which sub-shape should be drawn (-1 means all 
+    /// subshapes).
+    ///
+    /// Note the *coordinates* in "paths" are not used because they are 
+    /// already prepared in agg_paths. The (nearly ambiguous) "path" parameter
+    /// is used to access other properties like fill styles and subshapes.   
+    ///
+    /// @param subshape_id
+    ///    Defines which subshape to draw. -1 means all subshapes.
+    ///
+    void draw_shape(int subshape_id, const GnashPaths &paths,
+                   const AggPaths& agg_paths,  
+                   StyleHandler& sh, bool even_odd) {
+       
+       if (_alphaMasks.empty()) {
+           
+           // No mask active, use normal scanline renderer
+           
+           typedef agg::scanline_u8 scanline_type;
+           
+           scanline_type sl;
+           
+           draw_shape_impl<scanline_type> (subshape_id, paths, agg_paths, 
+                                           sh, even_odd, sl);
+           
+       } else {
+           
+           // Mask is active, use alpha mask scanline renderer
+           
+           typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
+           
+           scanline_type sl(_alphaMasks.back()->getMask());
+           
+           draw_shape_impl<scanline_type> (subshape_id, paths, agg_paths, 
+                                           sh, even_odd, sl);
+           
+       }
+       
+    }
     
-    assert(m_pixf.get());
+    /// Template for draw_shape(). Two different scanline types are suppored, 
+    /// one with and one without an alpha mask. This makes drawing without 
masks
+    /// much faster.  
+    template <class scanline_type>
+    void draw_shape_impl(int subshape_id, const GnashPaths &paths,
+                        const AggPaths& agg_paths,
+                        StyleHandler& sh, bool even_odd, scanline_type& sl) {
+       /*
+         Fortunately, AGG provides a rasterizer that fits perfectly to the 
flash
+         data model. So we just have to feed AGG with all data and we're done. 
:-)
+         This is also far better than recomposing the polygons as the 
rasterizer
+         can do everything in one pass and it is also better for adjacent edges
+         (anti aliasing).
+         Thank to Maxim Shemanarev for providing us such a great tool with 
AGG...
+       */
+       
+       assert(m_pixf.get());
     
-    assert(!m_drawing_mask);
+       assert(!m_drawing_mask);
     
-    if ( _clipbounds.empty() ) return;
+       if ( _clipbounds.empty() ) return;
 
-    // Target renderer
-    renderer_base& rbase = *m_rbase;
+       // Target renderer
+       renderer_base& rbase = *m_rbase;
 
-    typedef agg::rasterizer_compound_aa<agg::rasterizer_sl_clip_int> ras_type;
-    ras_type rasc;  // flash-like renderer
+       typedef agg::rasterizer_compound_aa<agg::rasterizer_sl_clip_int> 
ras_type;
+       ras_type rasc;  // flash-like renderer
 
-    agg::renderer_scanline_aa_solid<
-      agg::renderer_base<PixelFormat> > ren_sl(rbase); // solid fills
-    agg::span_allocator<agg::rgba8> alloc;  // span allocator (?)
+       agg::renderer_scanline_aa_solid<
+           agg::renderer_base<PixelFormat> > ren_sl(rbase); // solid fills
+       agg::span_allocator<agg::rgba8> alloc;  // span allocator (?)
     
 
-    // activate even-odd filling rule
-    if (even_odd)
-      rasc.filling_rule(agg::fill_even_odd);
-    else
-      rasc.filling_rule(agg::fill_non_zero);
+       // activate even-odd filling rule
+       if (even_odd)
+           rasc.filling_rule(agg::fill_even_odd);
+       else
+           rasc.filling_rule(agg::fill_non_zero);
       
     
-    for (unsigned int cno=0; cno<_clipbounds_selected.size(); ++cno) {
-    
-      const geometry::Range2d<int>* bounds = _clipbounds_selected[cno];
-      
-      applyClipBox<ras_type> (rasc, *bounds);
-      
-      int current_subshape=0;
-        
-      // push paths to AGG
-      const size_t pcount = paths.size();
-  
-      for (size_t pno=0; pno<pcount; ++pno) {
-          
-        const Path &this_path_gnash = paths[pno];
-        agg::path_storage &this_path_agg = 
-          const_cast<agg::path_storage&>(agg_paths[pno]);
-        
-        agg::conv_curve<agg::path_storage> curve(this_path_agg);        
-        
-        if (this_path_gnash.m_new_shape) ++current_subshape;
-          
-        if ((subshape_id >= 0) && (current_subshape!=subshape_id)) {
-          // Skip this path as it is not part of the requested sub-shape.
-          continue;
-        }
-        
-        if ((this_path_gnash.m_fill0==0) && (this_path_gnash.m_fill1==0)) {
-          // Skip this path as it contains no fill style
-          continue;
-        } 
+       for (unsigned int cno=0; cno<_clipbounds_selected.size(); ++cno) {
+           
+           const geometry::Range2d<int>* bounds = _clipbounds_selected[cno];
+           
+           applyClipBox<ras_type> (rasc, *bounds);
+           
+           int current_subshape=0;
+           
+           // push paths to AGG
+           const size_t pcount = paths.size();
+           
+           for (size_t pno=0; pno<pcount; ++pno) {
+               
+               const Path &this_path_gnash = paths[pno];
+               agg::path_storage &this_path_agg = 
+                   const_cast<agg::path_storage&>(agg_paths[pno]);
+               
+               agg::conv_curve<agg::path_storage> curve(this_path_agg);        
+               
+               if (this_path_gnash.m_new_shape) ++current_subshape;
+               
+               if ((subshape_id >= 0) && (current_subshape!=subshape_id)) {
+                   // Skip this path as it is not part of the requested 
sub-shape.
+                   continue;
+               }
+               
+               if ((this_path_gnash.m_fill0==0) && 
(this_path_gnash.m_fill1==0)) {
+                   // Skip this path as it contains no fill style
+                   continue;
+               } 
                 
-        
-        // Tell the rasterizer which styles the following path will use.
-        // The good thing is, that it already supports two fill styles out of
-        // the box. 
-        // Flash uses value "0" for "no fill", whereas AGG uses "-1" for that. 
-        rasc.styles(this_path_gnash.m_fill0-1, this_path_gnash.m_fill1-1);
+               
+               // Tell the rasterizer which styles the following path will use.
+               // The good thing is, that it already supports two fill styles 
out of
+               // the box. 
+               // Flash uses value "0" for "no fill", whereas AGG uses "-1" 
for that. 
+               rasc.styles(this_path_gnash.m_fill0-1, 
this_path_gnash.m_fill1-1);
                 
-        // add path to the compound rasterizer
-        rasc.add_path(curve);
-      
-      }
-              
-      agg::render_scanlines_compound_layered(rasc, sl, rbase, alloc, sh);
-    }
-    
-  } // draw_shape_impl
-
-
-
-
-  // very similar to draw_shape but used for generating masks. There are no
-  // fill styles nor subshapes and such. Just render plain solid shapes.
-  void draw_mask_shape(const GnashPaths& paths, bool even_odd)
-  {
-
-    const AlphaMasks::size_type mask_count = _alphaMasks.size();
-    
-    if (mask_count < 2) {
-    
-      // This is the first level mask
-      
-      typedef agg::scanline_u8 scanline_type;
-      
-      scanline_type sl;
-      
-      draw_mask_shape_impl(paths, even_odd, sl);
-        
-    }
-    else {
-    
-      // Woohoo! We're drawing a nested mask! Use the previous mask while 
-      // drawing the new one, the result will be the intersection.
-      
-      typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
-      
-      scanline_type sl(_alphaMasks[mask_count-2]->getMask());
-      
-      draw_mask_shape_impl(paths, even_odd, sl);
-        
-    }
-    
-  }
-  
-  
-  template <class scanline_type>
-  void draw_mask_shape_impl(const GnashPaths& paths, bool even_odd,
-    scanline_type& sl) {
-    
-    typedef agg::pixfmt_gray8 pixfmt;
-    typedef agg::renderer_base<pixfmt> renderer_base;
-    
-    assert(!_alphaMasks.empty());
-    
-    // dummy style handler
-    typedef agg_mask_style_handler sh_type;
-    sh_type sh;                   
-       
-    // compound rasterizer used for flash shapes
-    typedef agg::rasterizer_compound_aa<agg::rasterizer_sl_clip_int> rasc_type;
-    rasc_type rasc;
+               // add path to the compound rasterizer
+               rasc.add_path(curve);
+               
+           }
+           
+           agg::render_scanlines_compound_layered(rasc, sl, rbase, alloc, sh);
+       }
+       
+    } // draw_shape_impl
+    
+    // very similar to draw_shape but used for generating masks. There are no
+    // fill styles nor subshapes and such. Just render plain solid shapes.
+    void draw_mask_shape(const GnashPaths& paths, bool even_odd)
+       {
+           const AlphaMasks::size_type mask_count = _alphaMasks.size();   
+           if (mask_count < 2) {
+               
+               // This is the first level mask
+               typedef agg::scanline_u8 scanline_type;
+               scanline_type sl;
+               draw_mask_shape_impl(paths, even_odd, sl);
+           } else {
+               // Woohoo! We're drawing a nested mask! Use the previous mask 
while 
+               // drawing the new one, the result will be the intersection.
+               typedef agg::scanline_u8_am<agg::alpha_mask_gray8> 
scanline_type;
+               scanline_type sl(_alphaMasks[mask_count-2]->getMask());
+               draw_mask_shape_impl(paths, even_odd, sl);      
+           }
+       }
     
+    template <class scanline_type>
+    void draw_mask_shape_impl(const GnashPaths& paths, bool even_odd,
+                             scanline_type& sl) {
+       
+       typedef agg::pixfmt_gray8 pixfmt;
+       typedef agg::renderer_base<pixfmt> renderer_base;
+       
+       assert(!_alphaMasks.empty());
+       
+       // dummy style handler
+       typedef agg_mask_style_handler sh_type;
+       sh_type sh;                   
+       
+       // compound rasterizer used for flash shapes
+       typedef agg::rasterizer_compound_aa<agg::rasterizer_sl_clip_int> 
rasc_type;
+       rasc_type rasc;
+       
+       
+       // activate even-odd filling rule
+       if (even_odd) rasc.filling_rule(agg::fill_even_odd);
+       else rasc.filling_rule(agg::fill_non_zero);
+       
+       // push paths to AGG
+       agg::path_storage path; 
+       agg::conv_curve<agg::path_storage> curve(path);
+       
+       for (size_t pno=0, pcount=paths.size(); pno < pcount; ++pno) {
+           
+           const Path& this_path = paths[pno];
 
-    // activate even-odd filling rule
-    if (even_odd) rasc.filling_rule(agg::fill_even_odd);
-    else rasc.filling_rule(agg::fill_non_zero);
-      
-    // push paths to AGG
-    agg::path_storage path; 
-    agg::conv_curve<agg::path_storage> curve(path);
-
-    for (size_t pno=0, pcount=paths.size(); pno < pcount; ++pno) {
-
-      const Path& this_path = paths[pno];
-
-      path.remove_all();
+           path.remove_all();
       
-      // reduce everything to just one fill style!
-      rasc.styles(this_path.m_fill0==0 ? -1 : 0,
-                  this_path.m_fill1==0 ? -1 : 0);
+           // reduce everything to just one fill style!
+           rasc.styles(this_path.m_fill0==0 ? -1 : 0,
+                       this_path.m_fill1==0 ? -1 : 0);
                   
-      // starting point of path
-      path.move_to(twipsToPixels(this_path.ap.x), 
-                   twipsToPixels(this_path.ap.y));
+           // starting point of path
+           path.move_to(twipsToPixels(this_path.ap.x), 
+                        twipsToPixels(this_path.ap.y));
     
-      // Add all edges to the path.
-      std::for_each(this_path.m_edges.begin(), this_path.m_edges.end(),
-              EdgeToPath(path));
+           // Add all edges to the path.
+           std::for_each(this_path.m_edges.begin(), this_path.m_edges.end(),
+                         EdgeToPath(path));
       
-      // add to rasterizer
-      rasc.add_path(curve);
+           // add to rasterizer
+           rasc.add_path(curve);
     
-    } // for path
+       } // for path
     
-    // renderer base
-    renderer_base& rbase = _alphaMasks.back()->get_rbase();
+       // renderer base
+       renderer_base& rbase = _alphaMasks.back()->get_rbase();
     
-    // span allocator
-    typedef agg::span_allocator<agg::gray8> alloc_type;
-    alloc_type alloc; 
+       // span allocator
+       typedef agg::span_allocator<agg::gray8> alloc_type;
+       alloc_type alloc; 
       
     
-    // now render that thing!
-    agg::render_scanlines_compound_layered (rasc, sl, rbase, alloc, sh);
+       // now render that thing!
+       agg::render_scanlines_compound_layered (rasc, sl, rbase, alloc, sh);
         
-  } // draw_mask_shape
+    } // draw_mask_shape
 
 
 
-  /// Just like draw_shapes() except that it draws an outline.
-  void draw_outlines(int subshape_id, const GnashPaths &paths,
-    const AggPaths& agg_paths,
-    const std::vector<LineStyle> &line_styles, const SWFCxForm& cx,
-    const SWFMatrix& linestyle_matrix) {
+    /// Just like draw_shapes() except that it draws an outline.
+    void draw_outlines(int subshape_id, const GnashPaths &paths,
+                      const AggPaths& agg_paths,
+                      const std::vector<LineStyle> &line_styles, const 
SWFCxForm& cx,
+                      const SWFMatrix& linestyle_matrix) {
     
-    if (_alphaMasks.empty()) {
+       if (_alphaMasks.empty()) {
     
-      // No mask active, use normal scanline renderer
+           // No mask active, use normal scanline renderer
       
-      typedef agg::scanline_u8 scanline_type;
+           typedef agg::scanline_u8 scanline_type;
       
-      scanline_type sl;
+           scanline_type sl;
       
-      draw_outlines_impl<scanline_type> (subshape_id, paths, agg_paths, 
-        line_styles, cx, linestyle_matrix, sl);
+           draw_outlines_impl<scanline_type> (subshape_id, paths, agg_paths, 
+                                              line_styles, cx, 
linestyle_matrix, sl);
         
-    } else {
+       } else {
     
-      // Mask is active, use alpha mask scanline renderer
+           // Mask is active, use alpha mask scanline renderer
       
-      typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
+           typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
       
-      scanline_type sl(_alphaMasks.back()->getMask());
+           scanline_type sl(_alphaMasks.back()->getMask());
       
-      draw_outlines_impl<scanline_type> (subshape_id, paths, agg_paths,
-        line_styles, cx, linestyle_matrix, sl);
+           draw_outlines_impl<scanline_type> (subshape_id, paths, agg_paths,
+                                              line_styles, cx, 
linestyle_matrix, sl);
         
-    }
+       }
     
-  } //draw_outlines
+    } //draw_outlines
 
 
-  /// Template for draw_outlines(), see draw_shapes_impl().
-  template <class scanline_type>
-  void draw_outlines_impl(int subshape_id, const GnashPaths &paths,
-    const AggPaths& agg_paths,
-    const std::vector<LineStyle> &line_styles, const SWFCxForm& cx, 
-    const SWFMatrix& linestyle_matrix, scanline_type& sl) {
+    /// Template for draw_outlines(), see draw_shapes_impl().
+    template <class scanline_type>
+    void draw_outlines_impl(int subshape_id, const GnashPaths &paths,
+                           const AggPaths& agg_paths,
+                           const std::vector<LineStyle> &line_styles, const 
SWFCxForm& cx, 
+                           const SWFMatrix& linestyle_matrix, scanline_type& 
sl) {
     
-    assert(m_pixf.get());
+       assert(m_pixf.get());
 
-    // Flash ignores lines in mask /definitions/ 
-    if (m_drawing_mask) return;    
+       // Flash ignores lines in mask /definitions/ 
+       if (m_drawing_mask) return;    
     
-    if ( _clipbounds.empty() ) return;
+       if ( _clipbounds.empty() ) return;
 
-    // TODO: While walking the paths for filling them, remember when a path
-    // has a line style associated, so that we avoid walking the paths again
-    // when there really are no outlines to draw...
+       // TODO: While walking the paths for filling them, remember when a path
+       // has a line style associated, so that we avoid walking the paths again
+       // when there really are no outlines to draw...
     
-    // use avg between x and y scale
-    const float stroke_scale = (std::abs(linestyle_matrix.get_x_scale()) + 
-       std::abs(linestyle_matrix.get_y_scale())) / 2.0f * get_stroke_scale();
+       // use avg between x and y scale
+       const float stroke_scale = (std::abs(linestyle_matrix.get_x_scale()) + 
+                                   std::abs(linestyle_matrix.get_y_scale())) / 
2.0f * get_stroke_scale();
     
     
-    // AGG stuff
-    typedef agg::rasterizer_scanline_aa<> ras_type; 
-    ras_type ras;  // anti alias
+       // AGG stuff
+       typedef agg::rasterizer_scanline_aa<> ras_type; 
+       ras_type ras;  // anti alias
 
-    renderer_base& rbase = *m_rbase;
+       renderer_base& rbase = *m_rbase;
 
-    agg::renderer_scanline_aa_solid<
-      agg::renderer_base<PixelFormat> > ren_sl(rbase); // solid fills
+       agg::renderer_scanline_aa_solid<
+           agg::renderer_base<PixelFormat> > ren_sl(rbase); // solid fills
       
     
-    for (unsigned int cno=0; cno<_clipbounds_selected.size(); ++cno) {
+       for (unsigned int cno=0; cno<_clipbounds_selected.size(); ++cno) {
     
-      const geometry::Range2d<int>* bounds = _clipbounds_selected[cno];
+           const geometry::Range2d<int>* bounds = _clipbounds_selected[cno];
           
-      applyClipBox<ras_type> (ras, *bounds);
+           applyClipBox<ras_type> (ras, *bounds);
       
-      int current_subshape=0;
+           int current_subshape=0;
 
-      for (size_t pno=0, pcount=paths.size(); pno<pcount; ++pno) {
+           for (size_t pno=0, pcount=paths.size(); pno<pcount; ++pno) {
 
-        const Path& this_path_gnash = paths[pno];
+               const Path& this_path_gnash = paths[pno];
 
-        agg::path_storage &this_path_agg = 
-          const_cast<agg::path_storage&>(agg_paths[pno]);
+               agg::path_storage &this_path_agg = 
+                   const_cast<agg::path_storage&>(agg_paths[pno]);
         
-        if (this_path_gnash.m_new_shape)
-          ++current_subshape;
+               if (this_path_gnash.m_new_shape)
+                   ++current_subshape;
           
-        if ((subshape_id>=0) && (current_subshape!=subshape_id)) {
-          // Skip this path as it is not part of the requested sub-shape.
-          continue;
-        }
+               if ((subshape_id>=0) && (current_subshape!=subshape_id)) {
+                   // Skip this path as it is not part of the requested 
sub-shape.
+                   continue;
+               }
         
-        if (this_path_gnash.m_line==0) {
-          // Skip this path as it contains no line style
-          continue;
-        } 
+               if (this_path_gnash.m_line==0) {
+                   // Skip this path as it contains no line style
+                   continue;
+               } 
         
-        agg::conv_curve< agg::path_storage > curve(this_path_agg); // to 
render curves
-        agg::conv_stroke< agg::conv_curve < agg::path_storage > > 
-          stroke(curve);  // to get an outline
+               agg::conv_curve< agg::path_storage > curve(this_path_agg); // 
to render curves
+               agg::conv_stroke< agg::conv_curve < agg::path_storage > > 
+                   stroke(curve);  // to get an outline
         
-        const LineStyle& lstyle = line_styles[this_path_gnash.m_line-1];
+               const LineStyle& lstyle = line_styles[this_path_gnash.m_line-1];
           
-        int thickness = lstyle.getThickness();
-        if (!thickness) stroke.width(1); // hairline
-        else if ( (!lstyle.scaleThicknessVertically()) && 
(!lstyle.scaleThicknessHorizontally()) )
-        {
-          stroke.width(twipsToPixels(thickness));
-        }
-        else
-        {
-          if ((!lstyle.scaleThicknessVertically()) ||
-                  (!lstyle.scaleThicknessHorizontally()))
-          {
-             LOG_ONCE( log_unimpl(_("Unidirectionally scaled strokes in "
-                             "AGG renderer (we'll scale by the "
-                             "scalable one)")) );
-          }
-          stroke.width(std::max(1.0f, thickness*stroke_scale));
-        }
-        
-        // TODO: support endCapStyle
-        
-        // TODO: When lstyle.noClose==0 and the start and end point matches,
-        // then render a real join instead of the caps.
-
-        switch (lstyle.startCapStyle()) {
-          case CAP_NONE   : stroke.line_cap(agg::butt_cap); break; 
-          case CAP_SQUARE : stroke.line_cap(agg::square_cap); break;          
-          default : case CAP_ROUND : stroke.line_cap(agg::round_cap); 
-        }
-        
-        switch (lstyle.joinStyle()) {
-          case JOIN_BEVEL : stroke.line_join(agg::bevel_join); break;
-          case JOIN_MITER : stroke.line_join(agg::miter_join); break;
-          default : case JOIN_ROUND : stroke.line_join(agg::round_join);
-        }
-        
-        stroke.miter_limit(lstyle.miterLimitFactor());
+               int thickness = lstyle.getThickness();
+               if (!thickness) stroke.width(1); // hairline
+               else if ( (!lstyle.scaleThicknessVertically()) && 
(!lstyle.scaleThicknessHorizontally()) )
+                   {
+                       stroke.width(twipsToPixels(thickness));
+                   } else {
+                   if ((!lstyle.scaleThicknessVertically()) ||
+                       (!lstyle.scaleThicknessHorizontally())) {
+                       LOG_ONCE( log_unimpl(_("Unidirectionally scaled strokes 
in "
+                                              "AGG renderer (we'll scale by 
the "
+                                              "scalable one)")) );
+                   }
+                   stroke.width(std::max(1.0f, thickness*stroke_scale));
+               }
+               
+               // TODO: support endCapStyle
+               
+               // TODO: When lstyle.noClose==0 and the start and end point 
matches,
+               // then render a real join instead of the caps.
+               
+               switch (lstyle.startCapStyle()) {
+                 case CAP_NONE   : stroke.line_cap(agg::butt_cap); break; 
+                 case CAP_SQUARE : stroke.line_cap(agg::square_cap); break;    
      
+                 default : case CAP_ROUND : stroke.line_cap(agg::round_cap); 
+               }
+               
+               switch (lstyle.joinStyle()) {
+                 case JOIN_BEVEL : stroke.line_join(agg::bevel_join); break;
+                 case JOIN_MITER : stroke.line_join(agg::miter_join); break;
+                 default : case JOIN_ROUND : stroke.line_join(agg::round_join);
+               }
+               
+               stroke.miter_limit(lstyle.miterLimitFactor());
                 
-        ras.reset();
-        ras.add_path(stroke);
-        
-        rgba color = cx.transform(lstyle.get_color());
-        ren_sl.color(agg::rgba8_pre(color.m_r, color.m_g, color.m_b, 
color.m_a));       
-                
-        agg::render_scanlines(ras, sl, ren_sl);
-        
-      }
-    
-    
-    }
-      
-  } // draw_outlines_impl
-
-
-  
-  /// Draws the given polygon.
-  template <class scanline_type>
-  void draw_poly_impl(const point* corners, size_t corner_count, const rgba& 
fill, 
-    const rgba& outline, scanline_type& sl, const SWFMatrix& poly_mat) {
-    
-    assert(m_pixf.get());
-
-    if (corner_count<1) return;
-    
-    if ( _clipbounds.empty() ) return;
-    
-    SWFMatrix mat = stage_matrix;
-    mat.concatenate(poly_mat);
+               ras.reset();
+               ras.add_path(stroke);
+               
+               rgba color = cx.transform(lstyle.get_color());
+               ren_sl.color(agg::rgba8_pre(color.m_r, color.m_g, color.m_b, 
color.m_a));       
+               agg::render_scanlines(ras, sl, ren_sl);
+               
+           }    
+       }
+       
+    } // draw_outlines_impl
     
-    typedef agg::rasterizer_scanline_aa<> ras_type;
-    renderer_base& rbase = *m_rbase;
+    /// Draws the given polygon.
+    template <class scanline_type>
+    void draw_poly_impl(const point* corners, size_t corner_count, const rgba& 
fill, 
+                       const rgba& outline, scanline_type& sl, const 
SWFMatrix& poly_mat) {
+       
+       assert(m_pixf.get());
+       
+       if (corner_count<1) return;
+       
+       if ( _clipbounds.empty() ) return;
+       
+       SWFMatrix mat = stage_matrix;
+       mat.concatenate(poly_mat);
+       
+       typedef agg::rasterizer_scanline_aa<> ras_type;
+       renderer_base& rbase = *m_rbase;
 
-    ras_type ras;
-    agg::renderer_scanline_aa_solid<
-      agg::renderer_base<PixelFormat> > ren_sl(rbase);
+       ras_type ras;
+       agg::renderer_scanline_aa_solid<
+           agg::renderer_base<PixelFormat> > ren_sl(rbase);
       
-    // -- create path --
-    agg::path_storage path;
-    point pnt, origin;
+       // -- create path --
+       agg::path_storage path;
+       point pnt, origin;
     
     
-    // Note: The coordinates are rounded and 0.5 is added to snap them to the 
-    // center of the pixel. This avoids blurring caused by anti-aliasing.
+       // Note: The coordinates are rounded and 0.5 is added to snap them to 
the 
+       // center of the pixel. This avoids blurring caused by anti-aliasing.
     
-    // The default conversion of the boost converter is truncation.
-    boost::numeric::converter<int,float> truncator;
+       // The default conversion of the boost converter is truncation.
+       boost::numeric::converter<int,float> truncator;
 
-    mat.transform(&origin, 
-      point(truncator(corners[0].x), truncator(corners[0].y)));
-    path.move_to(truncator(origin.x)+0.5, truncator(origin.y)+0.5);
+       mat.transform(&origin, 
+                     point(truncator(corners[0].x), truncator(corners[0].y)));
+       path.move_to(truncator(origin.x)+0.5, truncator(origin.y)+0.5);
     
-    for (unsigned int i=1; i<corner_count; ++i) {
-    
-      mat.transform(&pnt, point(corners[i].x, corners[i].y));
-        
-      path.line_to(truncator(pnt.x)+0.5, truncator(pnt.y)+0.5);
-    }
+       for (unsigned int i=1; i<corner_count; ++i) {
+           mat.transform(&pnt, point(corners[i].x, corners[i].y));
+           path.line_to(truncator(pnt.x)+0.5, truncator(pnt.y)+0.5);
+       }
     
-    // close polygon
-    path.line_to(truncator(origin.x)+0.5, truncator(origin.y)+0.5);
+       // close polygon
+       path.line_to(truncator(origin.x)+0.5, truncator(origin.y)+0.5);
     
     
     
-    // -- render --
+       // -- render --
       
-    // iterate through clipping bounds
-    for (unsigned int cno=0; cno<_clipbounds.size(); ++cno) {
+       // iterate through clipping bounds
+       for (unsigned int cno=0; cno<_clipbounds.size(); ++cno) {
     
-      const ClipBounds::value_type& bounds = _clipbounds[cno];         
-      applyClipBox<ras_type> (ras, bounds);     
+           const ClipBounds::value_type& bounds = _clipbounds[cno];         
+           applyClipBox<ras_type> (ras, bounds);     
             
       
-      // fill polygon
-      if (fill.m_a>0) {
-        ras.add_path(path);
-        ren_sl.color(agg::rgba8_pre(fill.m_r, fill.m_g, fill.m_b, fill.m_a));
+           // fill polygon
+           if (fill.m_a>0) {
+               ras.add_path(path);
+               ren_sl.color(agg::rgba8_pre(fill.m_r, fill.m_g, fill.m_b, 
fill.m_a));
         
-        agg::render_scanlines(ras, sl, ren_sl);
-      }
+               agg::render_scanlines(ras, sl, ren_sl);
+           }
       
-      // draw outline
-      if (outline.m_a>0) {
-        agg::conv_stroke<agg::path_storage> stroke(path);
+           // draw outline
+           if (outline.m_a>0) {
+               agg::conv_stroke<agg::path_storage> stroke(path);
         
-        stroke.width(1);
+               stroke.width(1);
         
-        ren_sl.color(agg::rgba8_pre(outline.m_r, outline.m_g, outline.m_b, 
outline.m_a));
+               ren_sl.color(agg::rgba8_pre(outline.m_r, outline.m_g, 
outline.m_b, outline.m_a));
         
-        ras.add_path(stroke);
+               ras.add_path(stroke);
         
-        agg::render_scanlines(ras, sl, ren_sl);
-      }
-    }
+               agg::render_scanlines(ras, sl, ren_sl);
+           }
+       }
     
-  } //draw_poly_impl
+    } //draw_poly_impl
   
   
-  void drawPoly(const point* corners, size_t corner_count, const rgba& fill, 
-    const rgba& outline, const SWFMatrix& mat, bool masked) {
+    void drawPoly(const point* corners, size_t corner_count, const rgba& fill, 
+                 const rgba& outline, const SWFMatrix& mat, bool masked) {
     
-       GNASH_REPORT_FUNCTION;
-    if (masked && !_alphaMasks.empty()) {
+       if (masked && !_alphaMasks.empty()) {
     
-      // apply mask
+           // apply mask
       
-      typedef agg::scanline_u8_am<agg::alpha_mask_gray8> sl_type; 
+           typedef agg::scanline_u8_am<agg::alpha_mask_gray8> sl_type; 
       
-      sl_type sl(_alphaMasks.back()->getMask());
+           sl_type sl(_alphaMasks.back()->getMask());
          
-      draw_poly_impl<sl_type> (corners, corner_count, fill, outline, sl, mat); 
      
+           draw_poly_impl<sl_type> (corners, corner_count, fill, outline, sl, 
mat);       
     
-    } else {
+       } else {
     
-      // no mask
+           // no mask
       
-      typedef agg::scanline_p8 sl_type; // packed scanline (faster for solid 
fills)
+           typedef agg::scanline_p8 sl_type; // packed scanline (faster for 
solid fills)
       
-      sl_type sl;
+           sl_type sl;
          
-      draw_poly_impl<sl_type> (corners, corner_count, fill, outline, sl, mat);
+           draw_poly_impl<sl_type> (corners, corner_count, fill, outline, sl, 
mat);
     
-    }
+       }
     
-  }
+    }
 
 
-  inline float get_stroke_scale() {
-    return (stage_matrix.get_x_scale() + stage_matrix.get_y_scale()) / 2.0f;
-  }                      
+    inline float get_stroke_scale() {
+       return (stage_matrix.get_x_scale() + stage_matrix.get_y_scale()) / 2.0f;
+    }                      
   
-  inline void world_to_pixel(int& x, int& y,
-    float world_x, float world_y)
-  {
-    // negative pixels seems ok here... we don't 
-    // clip to valid range, use world_to_pixel(SWFRect&)
-    // and Intersect() against valid range instead.
-    point p(world_x, world_y);
-    stage_matrix.transform(p);
-    x = (int)p.x;
-    y = (int)p.y;
-  }
-
-  geometry::Range2d<int> world_to_pixel(const SWFRect& wb)
-  {
-      using namespace gnash::geometry;
-
-    if ( wb.is_null() ) return Range2d<int>(nullRange);
-    if ( wb.is_world() ) return Range2d<int>(worldRange);
-
-    int xmin, ymin, xmax, ymax;
-
-    world_to_pixel(xmin, ymin, wb.get_x_min(), wb.get_y_min());
-    world_to_pixel(xmax, ymax, wb.get_x_max(), wb.get_y_max());
-
-    return Range2d<int>(xmin, ymin, xmax, ymax);
-  }
+    inline void world_to_pixel(int& x, int& y,
+                              float world_x, float world_y)
+       {
+           // negative pixels seems ok here... we don't 
+           // clip to valid range, use world_to_pixel(SWFRect&)
+           // and Intersect() against valid range instead.
+           point p(world_x, world_y);
+           stage_matrix.transform(p);
+           x = (int)p.x;
+           y = (int)p.y;
+       }
+
+    geometry::Range2d<int> world_to_pixel(const SWFRect& wb)
+       {
+           using namespace gnash::geometry;
+
+           if ( wb.is_null() ) return Range2d<int>(nullRange);
+           if ( wb.is_world() ) return Range2d<int>(worldRange);
+
+           int xmin, ymin, xmax, ymax;
+
+           world_to_pixel(xmin, ymin, wb.get_x_min(), wb.get_y_min());
+           world_to_pixel(xmax, ymax, wb.get_x_max(), wb.get_y_max());
+
+           return Range2d<int>(xmin, ymin, xmax, ymax);
+       }
   
-  geometry::Range2d<int> world_to_pixel(const geometry::Range2d<int>& wb)
-  {
-    if (wb.isNull() || wb.isWorld()) return wb;
+    geometry::Range2d<int> world_to_pixel(const geometry::Range2d<int>& wb)
+       {
+           if (wb.isNull() || wb.isWorld()) return wb;
     
-    int xmin, ymin, xmax, ymax;
+           int xmin, ymin, xmax, ymax;
 
-    world_to_pixel(xmin, ymin, wb.getMinX(), wb.getMinY());
-    world_to_pixel(xmax, ymax, wb.getMaxX(), wb.getMaxY());
+           world_to_pixel(xmin, ymin, wb.getMinX(), wb.getMinY());
+           world_to_pixel(xmax, ymax, wb.getMaxX(), wb.getMaxY());
 
-    return geometry::Range2d<int>(xmin, ymin, xmax, ymax);
-  }
+           return geometry::Range2d<int>(xmin, ymin, xmax, ymax);
+       }
   
-  point 
-  pixel_to_world(int x, int y)
-  {
-    point p(x, y);
-    SWFMatrix mat = stage_matrix;
-    mat.invert().transform(p);
-    return p;    
-  };
+    point 
+    pixel_to_world(int x, int y)
+       {
+           point p(x, y);
+           SWFMatrix mat = stage_matrix;
+           mat.invert().transform(p);
+           return p;    
+       };
   
-  void set_invalidated_region_world() {
-    InvalidatedRanges ranges;
-    ranges.setWorld();
-    set_invalidated_regions(ranges);
-  }
+    void set_invalidated_region_world() {
+       InvalidatedRanges ranges;
+       ranges.setWorld();
+       set_invalidated_regions(ranges);
+    }
   
-  virtual void set_invalidated_regions(const InvalidatedRanges& ranges) {
-    using gnash::geometry::Range2d;
+    virtual void set_invalidated_regions(const InvalidatedRanges& ranges) {
+       using gnash::geometry::Range2d;
     
-    int count=0;
+       int count=0;
 
-    _clipbounds_selected.clear();
-    _clipbounds.clear();    
+       _clipbounds_selected.clear();
+       _clipbounds.clear();    
 
-    // TODO: cache 'visiblerect' and maintain in sync with
-    //       xres/yres.
-    Range2d<int> visiblerect;
-    if ( xres && yres ) visiblerect = Range2d<int>(0, 0, xres-1, yres-1);
+       // TODO: cache 'visiblerect' and maintain in sync with
+       //       xres/yres.
+       Range2d<int> visiblerect;
+       if ( xres && yres ) visiblerect = Range2d<int>(0, 0, xres-1, yres-1);
     
-    for (size_t rno=0; rno<ranges.size(); ++rno) {
+       for (size_t rno=0; rno<ranges.size(); ++rno) {
     
-      const Range2d<int>& range = ranges.getRange(rno);
+           const Range2d<int>& range = ranges.getRange(rno);
 
-      Range2d<int> pixbounds = world_to_pixel(range);
+           Range2d<int> pixbounds = world_to_pixel(range);
       
-      geometry::Range2d<int> bounds = Intersection(pixbounds, visiblerect);
+           geometry::Range2d<int> bounds = Intersection(pixbounds, 
visiblerect);
       
-      if (bounds.isNull()) continue; // out of screen
+           if (bounds.isNull()) continue; // out of screen
       
-      assert(bounds.isFinite());
+           assert(bounds.isFinite());
       
-      _clipbounds.push_back(bounds);
+           _clipbounds.push_back(bounds);
       
-      ++count;
-    }
-    //log_debug("%d inv. bounds in frame", count);
+           ++count;
+       }
+       //log_debug("%d inv. bounds in frame", count);
     
-  }
+    }
   
   
-  virtual bool bounds_in_clipping_area(const geometry::Range2d<int>& bounds) { 
   
+    virtual bool bounds_in_clipping_area(const geometry::Range2d<int>& bounds) 
{    
     
-    using gnash::geometry::Range2d;
+       using gnash::geometry::Range2d;
   
-    Range2d<int> pixbounds = world_to_pixel(bounds);
+       Range2d<int> pixbounds = world_to_pixel(bounds);
     
-    for (unsigned int cno=0; cno<_clipbounds.size(); ++cno) {  
-      if (Intersect(pixbounds, _clipbounds[cno]))
-        return true;
+       for (unsigned int cno=0; cno<_clipbounds.size(); ++cno) {  
+           if (Intersect(pixbounds, _clipbounds[cno]))
+               return true;
+       }
+       return false;
     }
-    return false;
-  }
 
-  bool getPixel(rgba& color_return, int x, int y) const {
+    bool getPixel(rgba& color_return, int x, int y) const {
   
-    if ((x<0) || (y<0) || (x>=xres) || (y>=yres))
-      return false;
+       if ((x<0) || (y<0) || (x>=xres) || (y>=yres))
+           return false;
 
-    agg::rgba8 color = m_pixf->pixel(x, y);    
+       agg::rgba8 color = m_pixf->pixel(x, y);    
     
-    color_return.m_r = color.r;
-    color_return.m_g = color.g;
-    color_return.m_b = color.b;
-    color_return.m_a = color.a;
+       color_return.m_r = color.r;
+       color_return.m_g = color.g;
+       color_return.m_b = color.b;
+       color_return.m_a = color.a;
     
-    return true;
-  }
+       return true;
+    }
   
-  void set_scale(float new_xscale, float new_yscale) {
+    void set_scale(float new_xscale, float new_yscale) {
     
-    scale_set=true;
-    stage_matrix.set_identity();
-    stage_matrix.set_scale(new_xscale/20.0f, new_yscale/20.0f);
-  }
+       scale_set=true;
+       stage_matrix.set_identity();
+       stage_matrix.set_scale(new_xscale/20.0f, new_yscale/20.0f);
+    }
 
-  void set_translation(float xoff, float yoff) {
-    stage_matrix.set_translation(xoff, yoff);
-  }
+    void set_translation(float xoff, float yoff) {
+       stage_matrix.set_translation(xoff, yoff);
+    }
 
-  virtual unsigned int getBytesPerPixel() const {
-    return bpp/8;
-  }  
+    virtual unsigned int getBytesPerPixel() const {
+       return bpp/8;
+    }  
   
 private:  // private variables
     
@@ -2111,87 +2045,85 @@ private:  // private variables
 // here)
 bool is_little_endian_host() {
 
-  union {
-    boost::uint16_t word;
-    struct {
-      boost::uint8_t b1;
-      boost::uint8_t b2;
-    } s;
-  } u;
+    union {
+       boost::uint16_t word;
+       struct {
+           boost::uint8_t b1;
+           boost::uint8_t b2;
+       } s;
+    } u;
     
-  u.s.b1 = 1;
-  u.s.b2 = 2;
+    u.s.b1 = 1;
+    u.s.b2 = 2;
   
-  return u.word == 0x0201;
+    return u.word == 0x0201;
 
 }
 
 
 DSOEXPORT Renderer_agg_base*  create_Renderer_agg(const char *pixelformat)
 {
-       GNASH_REPORT_FUNCTION;
-
-  if (!pixelformat) return NULL;
+    if (!pixelformat) return NULL;
 
-  if (is_little_endian_host())
-    log_debug(_("Framebuffer pixel format is %s (little-endian host)"), 
pixelformat);
-  else
-    log_debug(_("Framebuffer pixel format is %s (big-endian host)"), 
pixelformat);
+    if (is_little_endian_host())
+       log_debug(_("Framebuffer pixel format is %s (little-endian host)"), 
pixelformat);
+    else
+       log_debug(_("Framebuffer pixel format is %s (big-endian host)"), 
pixelformat);
   
 #ifdef PIXELFORMAT_RGB555  
-  if (!strcmp(pixelformat, "RGB555"))
-    return new Renderer_agg<agg::pixfmt_rgb555_pre> (16); // yep, 16!
+    if (!strcmp(pixelformat, "RGB555"))
+       return new Renderer_agg<agg::pixfmt_rgb555_pre> (16); // yep, 16!
   
-  else
+    else
 #endif   
 #ifdef PIXELFORMAT_RGB565  
-  if (!strcmp(pixelformat, "RGB565") || !strcmp(pixelformat, "RGBA16"))
-    return new Renderer_agg<agg::pixfmt_rgb565_pre> (16); 
-  else 
+       if (!strcmp(pixelformat, "RGB565") || !strcmp(pixelformat, "RGBA16"))
+           return new Renderer_agg<agg::pixfmt_rgb565_pre> (16); 
+       else 
 #endif   
 #ifdef PIXELFORMAT_RGB24  
-  if (!strcmp(pixelformat, "RGB24"))
-    return new Renderer_agg<agg::pixfmt_rgb24_pre> (24);    
-  else 
+           if (!strcmp(pixelformat, "RGB24"))
+               return new Renderer_agg<agg::pixfmt_rgb24_pre> (24);    
+           else 
 #endif   
 #ifdef PIXELFORMAT_BGR24  
-  if (!strcmp(pixelformat, "BGR24"))
-    return new Renderer_agg<agg::pixfmt_bgr24_pre> (24);
-  else 
+               if (!strcmp(pixelformat, "BGR24"))
+                   return new Renderer_agg<agg::pixfmt_bgr24_pre> (24);
+               else 
 #endif   
 #ifdef PIXELFORMAT_RGBA32 
-  if (!strcmp(pixelformat, "RGBA32"))
-    return new Renderer_agg<agg::pixfmt_rgba32_pre> (32);
-  else 
+                   if (!strcmp(pixelformat, "RGBA32"))
+                       return new Renderer_agg<agg::pixfmt_rgba32_pre> (32);
+                   else 
 #endif   
 #ifdef PIXELFORMAT_BGRA32  
-  if (!strcmp(pixelformat, "BGRA32"))
-    return new Renderer_agg<agg::pixfmt_bgra32_pre> (32);
+                       if (!strcmp(pixelformat, "BGRA32"))
+                           return new Renderer_agg<agg::pixfmt_bgra32_pre> 
(32);
 #endif   
 #ifdef PIXELFORMAT_RGBA32 
-  if (!strcmp(pixelformat, "ARGB32"))
-    return new Renderer_agg<agg::pixfmt_argb32_pre> (32);
-  else 
+    if (!strcmp(pixelformat, "ARGB32"))
+       return new Renderer_agg<agg::pixfmt_argb32_pre> (32);
+    else 
 #endif   
 #ifdef PIXELFORMAT_BGRA32  
-  if (!strcmp(pixelformat, "ABGR32"))
-    return new Renderer_agg<agg::pixfmt_abgr32_pre> (32);
+       if (!strcmp(pixelformat, "ABGR32"))
+           return new Renderer_agg<agg::pixfmt_abgr32_pre> (32);
         
-  else 
+       else 
 #endif
-  {
-    log_error("Unknown pixelformat: %s\n", pixelformat);
-    return NULL;
-    //abort();
-  }
+           {
+               log_error("Unknown pixelformat: %s\n", pixelformat);
+               return NULL;
+               //abort();
+           }
   
-  return NULL; // avoid compiler warning
+    return NULL; // avoid compiler warning
 }
 
 
 DSOEXPORT const char *agg_detect_pixel_format(unsigned int rofs,
-        unsigned int rsize, unsigned int gofs, unsigned int gsize,
-        unsigned int bofs, unsigned int bsize, unsigned int bpp)
+                                             unsigned int rsize, unsigned int 
gofs, unsigned int gsize,
+                                             unsigned int bofs, unsigned int 
bsize, unsigned int bpp)
 {
     
     if (!is_little_endian_host() && (bpp>=24)) {
@@ -2248,6 +2180,6 @@ DSOEXPORT const char *agg_detect_pixel_format(unsigned 
int rofs,
 
 // Local Variables:
 // mode: C++
-// indent-tabs-mode: t
+// indent-tabs-mode: NIL
 // End:
 /* vim: set cindent tabstop=8 softtabstop=4 shiftwidth=4: */

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


commit 2b011a109017894358505d78711bff446b9e3fc3
Author: Rob Savoye <address@hidden>
Date:   Fri Jan 21 17:43:51 2011 -0700

    Select a subset of possible input devices, in our case, just the Babbage 
touchscreen.

diff --git a/gui/fb/fb.cpp b/gui/fb/fb.cpp
index c7b5409..36a5e91 100644
--- a/gui/fb/fb.cpp
+++ b/gui/fb/fb.cpp
@@ -221,9 +221,38 @@ FBGui::init(int argc, char *** argv)
     // Initialize all the input devices
 
     // Look for Mice that use the PS/2 mouse protocol
-    _inputs = InputDevice::scanForDevices();
-    if (_inputs.empty()) {
+    std::vector<boost::shared_ptr<InputDevice> > possibles
+        = InputDevice::scanForDevices();
+    if (possibles.empty()) {
         log_error("Found no accessible input event devices");
+    } else {
+        log_debug("Found %d input event devices.", possibles.size());
+    }
+    
+    std::vector<boost::shared_ptr<InputDevice> >::iterator it;
+    for (it=possibles.begin(); it!=possibles.end(); ++it) {
+        (*it)->dump();
+        if ((*it)->getType() == InputDevice::MOUSE) {
+            log_debug("WARNING: Mouse support disabled as it conflicts with 
the input event support.");
+            // For now we only want keyboards input events, as the mouse
+            // interface default of /dev/input/mice supports hotpluging 
devices,
+            // unlike the regular events.
+            // _inputs.push_back(*it);
+        }
+        if ((*it)->getType() == InputDevice::KEYBOARD) {
+            _inputs.push_back(*it);
+        }
+        if ((*it)->getType() == InputDevice::TOUCHSCREEN) {
+            log_debug("WARNING: Touchscreen support disabled as it conflicts 
with the input event support.");
+//            _inputs.push_back(*it);
+        }
+        if ((*it)->getType() == InputDevice::TABLET) {
+            log_debug("Enabling Babbage Touchscreen support");
+            _inputs.push_back(*it);
+        }
+        if ((*it)->getType() == InputDevice::POWERBUTTON) {
+            _inputs.push_back(*it);
+        }
     }
     
 #if 0
@@ -259,7 +288,7 @@ FBGui::init(int argc, char *** argv)
     log_debug("X:%d, Y:%d", _xpos, _ypos);
 #endif
 
-    _validbounds.setTo(0, 0, _width - 1, _height - 1);
+_validbounds.setTo(0, 0, _width - 1, _height - 1);
 
     _renderer.reset(renderer::openvg::create_handler(0));
   
@@ -283,7 +312,7 @@ FBGui::run()
     
     // let the GUI recompute the x/y scale factors to best fit the whole screen
     resize_view(_validbounds.width(), _validbounds.height());
-
+    
     // This loops endlessly at the frame rate
     while (!terminate_request) {  
         // wait the "heartbeat" inteval
@@ -672,26 +701,34 @@ FBGui::checkForData()
         boost::shared_ptr<InputDevice::input_data_t> ie = (*it)->popData();
         if (ie) {
 #if 0
-            std::cerr << "Got data: " << ie->pressed;
+            std::cerr << "Got data: " << ((ie->pressed) ? "true" : "false");
             std::cerr << ", " << ie->key << ", " << ie->modifier;
             std::cerr << ", " << ie->x << ", " << ie->y << std::endl;
             // cerr << "X = " << coords[0] << endl;
             // cerr << "Y = " << coords[1] << endl;
 #endif
-            // Range check and convert the position
+#if 0
+            // Range check and convert the position from relative to
+            // absolute
             boost::shared_array<int> coords =
                 MouseDevice::convertCoordinates(ie->x, ie->y,
                                                 getStage()->getStageWidth(),
                                                 getStage()->getStageHeight());
-            // See if a mouse button was clicked
-            if (ie->pressed) {
-                notifyMouseClick(true);
-            }
-            
             // The mouse was moved
             if (coords) {
                 notifyMouseMove(coords[0], coords[1]);
             }
+#endif
+            // See if a mouse button was clicked
+            //if (ie->pressed) {
+            notifyMouseClick(true);
+            double x = 0.655 * ie->x;
+            double y = 0.46875 * ie->y;
+            log_debug("Mouse clicked at: %g:%g", x, y);
+            notifyMouseMove(ie->x, ie->y);
+//                notifyMouseMove(int(x), int(y));
+//        }
+            
         }
     }
 }
diff --git a/gui/fb/fbsup.h b/gui/fb/fbsup.h
index e39b644..a7d0944 100644
--- a/gui/fb/fbsup.h
+++ b/gui/fb/fbsup.h
@@ -197,7 +197,7 @@ private:
     boost::shared_ptr<FBGlue> _glue;
 
     /// This is the array of functioning input devices.
-    std::vector<boost::shared_ptr<InputDevice> > _inputs;    
+    std::vector<boost::shared_ptr<InputDevice> > _inputs;
 
     boost::shared_ptr<Renderer> _renderer;
 };

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


commit 439d154a5eb8a9c72e58fc15fd18f0de004f8d37
Author: Rob Savoye <address@hidden>
Date:   Fri Jan 21 17:23:11 2011 -0700

    add evtest from freedesktop.org

diff --git a/libdevice/events/evtest.c b/libdevice/events/evtest.c
new file mode 100644
index 0000000..8460641
--- /dev/null
+++ b/libdevice/events/evtest.c
@@ -0,0 +1,463 @@
+/*
+ *  Copyright (c) 1999-2000 Vojtech Pavlik
+ *  Copyright (c) 2009 Red Hat, Inc
+ *
+ *  Event device test program
+ *
+ * See INSTALL for installation details or manually compile with
+ * gcc -o evtest evtest.c
+ */
+
+/*
+ * 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
+ * 
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <address@hidden>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
+ */
+
+#include <stdint.h>
+
+#include <linux/version.h>
+#include <linux/input.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#ifndef EV_SYN
+#define EV_SYN 0
+#endif
+
+char *events[EV_MAX + 1] = {
+       [0 ... EV_MAX] = NULL,
+       [EV_SYN] = "Sync",                      [EV_KEY] = "Key",
+       [EV_REL] = "Relative",                  [EV_ABS] = "Absolute",
+       [EV_MSC] = "Misc",                      [EV_LED] = "LED",
+       [EV_SND] = "Sound",                     [EV_REP] = "Repeat",
+       [EV_FF] = "ForceFeedback",              [EV_PWR] = "Power",
+       [EV_FF_STATUS] = "ForceFeedbackStatus",
+};
+
+char *keys[KEY_MAX + 1] = {
+       [0 ... KEY_MAX] = NULL,
+       [KEY_RESERVED] = "Reserved",            [KEY_ESC] = "Esc",
+       [KEY_1] = "1",                          [KEY_2] = "2",
+       [KEY_3] = "3",                          [KEY_4] = "4",
+       [KEY_5] = "5",                          [KEY_6] = "6",
+       [KEY_7] = "7",                          [KEY_8] = "8",
+       [KEY_9] = "9",                          [KEY_0] = "0",
+       [KEY_MINUS] = "Minus",                  [KEY_EQUAL] = "Equal",
+       [KEY_BACKSPACE] = "Backspace",          [KEY_TAB] = "Tab",
+       [KEY_Q] = "Q",                          [KEY_W] = "W",
+       [KEY_E] = "E",                          [KEY_R] = "R",
+       [KEY_T] = "T",                          [KEY_Y] = "Y",
+       [KEY_U] = "U",                          [KEY_I] = "I",
+       [KEY_O] = "O",                          [KEY_P] = "P",
+       [KEY_LEFTBRACE] = "LeftBrace",          [KEY_RIGHTBRACE] = "RightBrace",
+       [KEY_ENTER] = "Enter",                  [KEY_LEFTCTRL] = "LeftControl",
+       [KEY_A] = "A",                          [KEY_S] = "S",
+       [KEY_D] = "D",                          [KEY_F] = "F",
+       [KEY_G] = "G",                          [KEY_H] = "H",
+       [KEY_J] = "J",                          [KEY_K] = "K",
+       [KEY_L] = "L",                          [KEY_SEMICOLON] = "Semicolon",
+       [KEY_APOSTROPHE] = "Apostrophe",        [KEY_GRAVE] = "Grave",
+       [KEY_LEFTSHIFT] = "LeftShift",          [KEY_BACKSLASH] = "BackSlash",
+       [KEY_Z] = "Z",                          [KEY_X] = "X",
+       [KEY_C] = "C",                          [KEY_V] = "V",
+       [KEY_B] = "B",                          [KEY_N] = "N",
+       [KEY_M] = "M",                          [KEY_COMMA] = "Comma",
+       [KEY_DOT] = "Dot",                      [KEY_SLASH] = "Slash",
+       [KEY_RIGHTSHIFT] = "RightShift",        [KEY_KPASTERISK] = "KPAsterisk",
+       [KEY_LEFTALT] = "LeftAlt",              [KEY_SPACE] = "Space",
+       [KEY_CAPSLOCK] = "CapsLock",            [KEY_F1] = "F1",
+       [KEY_F2] = "F2",                        [KEY_F3] = "F3",
+       [KEY_F4] = "F4",                        [KEY_F5] = "F5",
+       [KEY_F6] = "F6",                        [KEY_F7] = "F7",
+       [KEY_F8] = "F8",                        [KEY_F9] = "F9",
+       [KEY_F10] = "F10",                      [KEY_NUMLOCK] = "NumLock",
+       [KEY_SCROLLLOCK] = "ScrollLock",        [KEY_KP7] = "KP7",
+       [KEY_KP8] = "KP8",                      [KEY_KP9] = "KP9",
+       [KEY_KPMINUS] = "KPMinus",              [KEY_KP4] = "KP4",
+       [KEY_KP5] = "KP5",                      [KEY_KP6] = "KP6",
+       [KEY_KPPLUS] = "KPPlus",                [KEY_KP1] = "KP1",
+       [KEY_KP2] = "KP2",                      [KEY_KP3] = "KP3",
+       [KEY_KP0] = "KP0",                      [KEY_KPDOT] = "KPDot",
+       [KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd",
+       [KEY_F11] = "F11",                      [KEY_F12] = "F12",
+       [KEY_RO] = "RO",                        [KEY_KATAKANA] = "Katakana",
+       [KEY_HIRAGANA] = "HIRAGANA",            [KEY_HENKAN] = "Henkan",
+       [KEY_KATAKANAHIRAGANA] = "Katakana/Hiragana", [KEY_MUHENKAN] = 
"Muhenkan",
+       [KEY_KPJPCOMMA] = "KPJpComma",          [KEY_KPENTER] = "KPEnter",
+       [KEY_RIGHTCTRL] = "RightCtrl",          [KEY_KPSLASH] = "KPSlash",
+       [KEY_SYSRQ] = "SysRq",                  [KEY_RIGHTALT] = "RightAlt",
+       [KEY_LINEFEED] = "LineFeed",            [KEY_HOME] = "Home",
+       [KEY_UP] = "Up",                        [KEY_PAGEUP] = "PageUp",
+       [KEY_LEFT] = "Left",                    [KEY_RIGHT] = "Right",
+       [KEY_END] = "End",                      [KEY_DOWN] = "Down",
+       [KEY_PAGEDOWN] = "PageDown",            [KEY_INSERT] = "Insert",
+       [KEY_DELETE] = "Delete",                [KEY_MACRO] = "Macro",
+       [KEY_MUTE] = "Mute",                    [KEY_VOLUMEDOWN] = "VolumeDown",
+       [KEY_VOLUMEUP] = "VolumeUp",            [KEY_POWER] = "Power",
+       [KEY_KPEQUAL] = "KPEqual",              [KEY_KPPLUSMINUS] = 
"KPPlusMinus",
+       [KEY_PAUSE] = "Pause",                  [KEY_KPCOMMA] = "KPComma",
+       [KEY_HANGUEL] = "Hanguel",              [KEY_HANJA] = "Hanja",
+       [KEY_YEN] = "Yen",                      [KEY_LEFTMETA] = "LeftMeta",
+       [KEY_RIGHTMETA] = "RightMeta",          [KEY_COMPOSE] = "Compose",
+       [KEY_STOP] = "Stop",                    [KEY_AGAIN] = "Again",
+       [KEY_PROPS] = "Props",                  [KEY_UNDO] = "Undo",
+       [KEY_FRONT] = "Front",                  [KEY_COPY] = "Copy",
+       [KEY_OPEN] = "Open",                    [KEY_PASTE] = "Paste",
+       [KEY_FIND] = "Find",                    [KEY_CUT] = "Cut",
+       [KEY_HELP] = "Help",                    [KEY_MENU] = "Menu",
+       [KEY_CALC] = "Calc",                    [KEY_SETUP] = "Setup",
+       [KEY_SLEEP] = "Sleep",                  [KEY_WAKEUP] = "WakeUp",
+       [KEY_FILE] = "File",                    [KEY_SENDFILE] = "SendFile",
+       [KEY_DELETEFILE] = "DeleteFile",        [KEY_XFER] = "X-fer",
+       [KEY_PROG1] = "Prog1",                  [KEY_PROG2] = "Prog2",
+       [KEY_WWW] = "WWW",                      [KEY_MSDOS] = "MSDOS",
+       [KEY_COFFEE] = "Coffee",                [KEY_DIRECTION] = "Direction",
+       [KEY_CYCLEWINDOWS] = "CycleWindows",    [KEY_MAIL] = "Mail",
+       [KEY_BOOKMARKS] = "Bookmarks",          [KEY_COMPUTER] = "Computer",
+       [KEY_BACK] = "Back",                    [KEY_FORWARD] = "Forward",
+       [KEY_CLOSECD] = "CloseCD",              [KEY_EJECTCD] = "EjectCD",
+       [KEY_EJECTCLOSECD] = "EjectCloseCD",    [KEY_NEXTSONG] = "NextSong",
+       [KEY_PLAYPAUSE] = "PlayPause",          [KEY_PREVIOUSSONG] = 
"PreviousSong",
+       [KEY_STOPCD] = "StopCD",                [KEY_RECORD] = "Record",
+       [KEY_REWIND] = "Rewind",                [KEY_PHONE] = "Phone",
+       [KEY_ISO] = "ISOKey",                   [KEY_CONFIG] = "Config",
+       [KEY_HOMEPAGE] = "HomePage",            [KEY_REFRESH] = "Refresh",
+       [KEY_EXIT] = "Exit",                    [KEY_MOVE] = "Move",
+       [KEY_EDIT] = "Edit",                    [KEY_SCROLLUP] = "ScrollUp",
+       [KEY_SCROLLDOWN] = "ScrollDown",        [KEY_KPLEFTPAREN] = 
"KPLeftParenthesis",
+       [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_F13] = "F13",
+       [KEY_F14] = "F14",                      [KEY_F15] = "F15",
+       [KEY_F16] = "F16",                      [KEY_F17] = "F17",
+       [KEY_F18] = "F18",                      [KEY_F19] = "F19",
+       [KEY_F20] = "F20",                      [KEY_F21] = "F21",
+       [KEY_F22] = "F22",                      [KEY_F23] = "F23",
+       [KEY_F24] = "F24",                      [KEY_PLAYCD] = "PlayCD",
+       [KEY_PAUSECD] = "PauseCD",              [KEY_PROG3] = "Prog3",
+       [KEY_PROG4] = "Prog4",                  [KEY_SUSPEND] = "Suspend",
+       [KEY_CLOSE] = "Close",                  [KEY_PLAY] = "Play",
+       [KEY_FASTFORWARD] = "Fast Forward",     [KEY_BASSBOOST] = "Bass Boost",
+       [KEY_PRINT] = "Print",                  [KEY_HP] = "HP",
+       [KEY_CAMERA] = "Camera",                [KEY_SOUND] = "Sound",
+       [KEY_QUESTION] = "Question",            [KEY_EMAIL] = "Email",
+       [KEY_CHAT] = "Chat",                    [KEY_SEARCH] = "Search",
+       [KEY_CONNECT] = "Connect",              [KEY_FINANCE] = "Finance",
+       [KEY_SPORT] = "Sport",                  [KEY_SHOP] = "Shop",
+       [KEY_ALTERASE] = "Alternate Erase",     [KEY_CANCEL] = "Cancel",
+       [KEY_BRIGHTNESSDOWN] = "Brightness down", [KEY_BRIGHTNESSUP] = 
"Brightness up",
+       [KEY_MEDIA] = "Media",                  [KEY_UNKNOWN] = "Unknown",
+       [BTN_0] = "Btn0",                       [BTN_1] = "Btn1",
+       [BTN_2] = "Btn2",                       [BTN_3] = "Btn3",
+       [BTN_4] = "Btn4",                       [BTN_5] = "Btn5",
+       [BTN_6] = "Btn6",                       [BTN_7] = "Btn7",
+       [BTN_8] = "Btn8",                       [BTN_9] = "Btn9",
+       [BTN_LEFT] = "LeftBtn",                 [BTN_RIGHT] = "RightBtn",
+       [BTN_MIDDLE] = "MiddleBtn",             [BTN_SIDE] = "SideBtn",
+       [BTN_EXTRA] = "ExtraBtn",               [BTN_FORWARD] = "ForwardBtn",
+       [BTN_BACK] = "BackBtn",                 [BTN_TASK] = "TaskBtn",
+       [BTN_TRIGGER] = "Trigger",              [BTN_THUMB] = "ThumbBtn",
+       [BTN_THUMB2] = "ThumbBtn2",             [BTN_TOP] = "TopBtn",
+       [BTN_TOP2] = "TopBtn2",                 [BTN_PINKIE] = "PinkieBtn",
+       [BTN_BASE] = "BaseBtn",                 [BTN_BASE2] = "BaseBtn2",
+       [BTN_BASE3] = "BaseBtn3",               [BTN_BASE4] = "BaseBtn4",
+       [BTN_BASE5] = "BaseBtn5",               [BTN_BASE6] = "BaseBtn6",
+       [BTN_DEAD] = "BtnDead",                 [BTN_A] = "BtnA",
+       [BTN_B] = "BtnB",                       [BTN_C] = "BtnC",
+       [BTN_X] = "BtnX",                       [BTN_Y] = "BtnY",
+       [BTN_Z] = "BtnZ",                       [BTN_TL] = "BtnTL",
+       [BTN_TR] = "BtnTR",                     [BTN_TL2] = "BtnTL2",
+       [BTN_TR2] = "BtnTR2",                   [BTN_SELECT] = "BtnSelect",
+       [BTN_START] = "BtnStart",               [BTN_MODE] = "BtnMode",
+       [BTN_THUMBL] = "BtnThumbL",             [BTN_THUMBR] = "BtnThumbR",
+       [BTN_TOOL_PEN] = "ToolPen",             [BTN_TOOL_RUBBER] = 
"ToolRubber",
+       [BTN_TOOL_BRUSH] = "ToolBrush",         [BTN_TOOL_PENCIL] = 
"ToolPencil",
+       [BTN_TOOL_AIRBRUSH] = "ToolAirbrush",   [BTN_TOOL_FINGER] = 
"ToolFinger",
+       [BTN_TOOL_MOUSE] = "ToolMouse",         [BTN_TOOL_LENS] = "ToolLens",
+       [BTN_TOUCH] = "Touch",                  [BTN_STYLUS] = "Stylus",
+       [BTN_STYLUS2] = "Stylus2",              [BTN_TOOL_DOUBLETAP] = "Tool 
Doubletap",
+       [BTN_TOOL_TRIPLETAP] = "Tool Tripletap", [BTN_TOOL_QUADTAP] = "Tool 
Quadtap",
+       [BTN_GEAR_DOWN] = "WheelBtn",
+       [BTN_GEAR_UP] = "Gear up",              [KEY_OK] = "Ok",
+       [KEY_SELECT] = "Select",                [KEY_GOTO] = "Goto",
+       [KEY_CLEAR] = "Clear",                  [KEY_POWER2] = "Power2",
+       [KEY_OPTION] = "Option",                [KEY_INFO] = "Info",
+       [KEY_TIME] = "Time",                    [KEY_VENDOR] = "Vendor",
+       [KEY_ARCHIVE] = "Archive",              [KEY_PROGRAM] = "Program",
+       [KEY_CHANNEL] = "Channel",              [KEY_FAVORITES] = "Favorites",
+       [KEY_EPG] = "EPG",                      [KEY_PVR] = "PVR",
+       [KEY_MHP] = "MHP",                      [KEY_LANGUAGE] = "Language",
+       [KEY_TITLE] = "Title",                  [KEY_SUBTITLE] = "Subtitle",
+       [KEY_ANGLE] = "Angle",                  [KEY_ZOOM] = "Zoom",
+       [KEY_MODE] = "Mode",                    [KEY_KEYBOARD] = "Keyboard",
+       [KEY_SCREEN] = "Screen",                [KEY_PC] = "PC",
+       [KEY_TV] = "TV",                        [KEY_TV2] = "TV2",
+       [KEY_VCR] = "VCR",                      [KEY_VCR2] = "VCR2",
+       [KEY_SAT] = "Sat",                      [KEY_SAT2] = "Sat2",
+       [KEY_CD] = "CD",                        [KEY_TAPE] = "Tape",
+       [KEY_RADIO] = "Radio",                  [KEY_TUNER] = "Tuner",
+       [KEY_PLAYER] = "Player",                [KEY_TEXT] = "Text",
+       [KEY_DVD] = "DVD",                      [KEY_AUX] = "Aux",
+       [KEY_MP3] = "MP3",                      [KEY_AUDIO] = "Audio",
+       [KEY_VIDEO] = "Video",                  [KEY_DIRECTORY] = "Directory",
+       [KEY_LIST] = "List",                    [KEY_MEMO] = "Memo",
+       [KEY_CALENDAR] = "Calendar",            [KEY_RED] = "Red",
+       [KEY_GREEN] = "Green",                  [KEY_YELLOW] = "Yellow",
+       [KEY_BLUE] = "Blue",                    [KEY_CHANNELUP] = "ChannelUp",
+       [KEY_CHANNELDOWN] = "ChannelDown",      [KEY_FIRST] = "First",
+       [KEY_LAST] = "Last",                    [KEY_AB] = "AB",
+       [KEY_NEXT] = "Next",                    [KEY_RESTART] = "Restart",
+       [KEY_SLOW] = "Slow",                    [KEY_SHUFFLE] = "Shuffle",
+       [KEY_BREAK] = "Break",                  [KEY_PREVIOUS] = "Previous",
+       [KEY_DIGITS] = "Digits",                [KEY_TEEN] = "TEEN",
+       [KEY_TWEN] = "TWEN",                    [KEY_DEL_EOL] = "Delete EOL",
+       [KEY_DEL_EOS] = "Delete EOS",           [KEY_INS_LINE] = "Insert line",
+       [KEY_DEL_LINE] = "Delete line",
+       [KEY_VIDEOPHONE] = "Videophone",        [KEY_GAMES] = "Games",
+       [KEY_ZOOMIN] = "Zoom In",               [KEY_ZOOMOUT] = "Zoom Out",
+       [KEY_ZOOMRESET] = "Zoom Reset",         [KEY_WORDPROCESSOR] = "Word 
Processor",
+       [KEY_EDITOR] = "Editor",                [KEY_SPREADSHEET] = 
"Spreadsheet",
+       [KEY_GRAPHICSEDITOR] = "Graphics Editor", [KEY_PRESENTATION] = 
"Presentation",
+       [KEY_DATABASE] = "Database",            [KEY_NEWS] = "News",
+       [KEY_VOICEMAIL] = "Voicemail",          [KEY_ADDRESSBOOK] = 
"Addressbook",
+       [KEY_MESSENGER] = "Messenger",          [KEY_DISPLAYTOGGLE] = "Display 
Toggle",
+       [KEY_SPELLCHECK] = "Spellcheck",        [KEY_LOGOFF] = "Log Off",
+       [KEY_DOLLAR] = "Dollar",                [KEY_EURO] = "Euro",
+       [KEY_FRAMEBACK] = "Frame Back",  [KEY_FRAMEFORWARD] = "Frame Forward",
+       [KEY_CONTEXT_MENU] = "Context Menu",    [KEY_MEDIA_REPEAT] = "Media 
Repeat",
+       [KEY_DEL_EOL] = "Delete EOL",           [KEY_DEL_EOS] = "Delete EOS",
+       [KEY_INS_LINE] = "Insert Line",  [KEY_DEL_LINE] = "Delete Line",
+       [KEY_FN] = "Fn",                        [KEY_FN_ESC] = "Fn Esc",
+       [KEY_FN_F1] = "Fn F1",                  [KEY_FN_F2] = "Fn F2",
+       [KEY_FN_F3] = "Fn F3",                  [KEY_FN_F4] = "Fn F4",
+       [KEY_FN_F5] = "Fn F5",                  [KEY_FN_F6] = "Fn F6",
+       [KEY_FN_F7] = "Fn F7",                  [KEY_FN_F8] = "Fn F8",
+       [KEY_FN_F9] = "Fn F9",                  [KEY_FN_F10] = "Fn F10",
+       [KEY_FN_F11] = "Fn F11",                [KEY_FN_F12] = "Fn F12",
+       [KEY_FN_1] = "Fn 1",                    [KEY_FN_2] = "Fn 2",
+       [KEY_FN_D] = "Fn D",                    [KEY_FN_E] = "Fn E",
+       [KEY_FN_F] = "Fn F",                    [KEY_FN_S] = "Fn S",
+       [KEY_FN_B] = "Fn B",
+       [KEY_BRL_DOT1] = "Braille Dot 1",       [KEY_BRL_DOT2] = "Braille Dot 
2",
+       [KEY_BRL_DOT3] = "Braille Dot 3",       [KEY_BRL_DOT4] = "Braille Dot 
4",
+       [KEY_BRL_DOT5] = "Braille Dot 5",       [KEY_BRL_DOT6] = "Braille Dot 
6",
+       [KEY_BRL_DOT7] = "Braille Dot 7",       [KEY_BRL_DOT8] = "Braille Dot 
8",
+       [KEY_BRL_DOT9] = "Braille Dot 9",       [KEY_BRL_DOT10] = "Braille Dot 
10",
+       [KEY_NUMERIC_0] = "Numeric 0",          [KEY_NUMERIC_1] = "Numeric 1",
+       [KEY_NUMERIC_2] = "Numeric 2",          [KEY_NUMERIC_3] = "Numeric 3",
+       [KEY_NUMERIC_4] = "Numeric 4",          [KEY_NUMERIC_5] = "Numeric 5",
+       [KEY_NUMERIC_6] = "Numeric 6",          [KEY_NUMERIC_7] = "Numeric 7",
+       [KEY_NUMERIC_8] = "Numeric 8",          [KEY_NUMERIC_9] = "Numeric 9",
+       [KEY_NUMERIC_STAR] = "Numeric *",       [KEY_NUMERIC_POUND] = "Numeric 
#",
+       [KEY_BATTERY] = "Battery",
+       [KEY_BLUETOOTH] = "Bluetooth",          [KEY_BRIGHTNESS_CYCLE] = 
"Brightness Cycle",
+       [KEY_BRIGHTNESS_ZERO] = "Brightness Zero", [KEY_DASHBOARD] = 
"Dashboard",
+       [KEY_DISPLAY_OFF] = "Display Off",      [KEY_DOCUMENTS] = "Documents",
+       [KEY_FORWARDMAIL] = "Forward Mail",     [KEY_NEW]  = "New",
+       [KEY_KBDILLUMDOWN] = "Kbd Illum Down",  [KEY_KBDILLUMUP] = "Kbd Illum 
Up",
+       [KEY_KBDILLUMTOGGLE] = "Kbd Illum Toggle", [KEY_REDO] = "Redo",
+       [KEY_REPLY] = "Reply",                  [KEY_SAVE] = "Save",
+       [KEY_SCALE] = "Scale",                  [KEY_SEND] = "Send",
+       [KEY_SCREENLOCK] = "Screen Lock",       [KEY_SWITCHVIDEOMODE] = "Switch 
Video Mode",
+       [KEY_UWB] = "UWB",                      [KEY_VIDEO_NEXT] = "Video Next",
+       [KEY_VIDEO_PREV] = "Video Prev",        [KEY_WIMAX] = "WIMAX",
+       [KEY_WLAN] = "WLAN"
+
+};
+
+char *absval[6] = { "Value", "Min  ", "Max  ", "Fuzz ", "Flat ", "Resolution 
"};
+
+char *relatives[REL_MAX + 1] = {
+       [0 ... REL_MAX] = NULL,
+       [REL_X] = "X",                  [REL_Y] = "Y",
+       [REL_Z] = "Z",                  [REL_HWHEEL] = "HWheel",
+       [REL_DIAL] = "Dial",            [REL_WHEEL] = "Wheel", 
+       [REL_MISC] = "Misc",    
+};
+
+char *absolutes[ABS_MAX + 1] = {
+       [0 ... ABS_MAX] = NULL,
+       [ABS_X] = "X",                  [ABS_Y] = "Y",
+       [ABS_Z] = "Z",                  [ABS_RX] = "Rx",
+       [ABS_RY] = "Ry",                [ABS_RZ] = "Rz",
+       [ABS_THROTTLE] = "Throttle",    [ABS_RUDDER] = "Rudder",
+       [ABS_WHEEL] = "Wheel",          [ABS_GAS] = "Gas",
+       [ABS_BRAKE] = "Brake",          [ABS_HAT0X] = "Hat0X",
+       [ABS_HAT0Y] = "Hat0Y",          [ABS_HAT1X] = "Hat1X",
+       [ABS_HAT1Y] = "Hat1Y",          [ABS_HAT2X] = "Hat2X",
+       [ABS_HAT2Y] = "Hat2Y",          [ABS_HAT3X] = "Hat3X",
+       [ABS_HAT3Y] = "Hat 3Y",         [ABS_PRESSURE] = "Pressure",
+       [ABS_DISTANCE] = "Distance",    [ABS_TILT_X] = "XTilt",
+       [ABS_TILT_Y] = "YTilt",         [ABS_TOOL_WIDTH] = "Tool Width",
+       [ABS_VOLUME] = "Volume",        [ABS_MISC] = "Misc",
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
+       [ABS_MT_TOUCH_MAJOR] = "Touch Major",
+       [ABS_MT_TOUCH_MINOR] = "Touch Minor",
+       [ABS_MT_WIDTH_MAJOR] = "Width Major",
+       [ABS_MT_WIDTH_MINOR] = "Width Minor",
+       [ABS_MT_ORIENTATION] = "Orientation",
+       [ABS_MT_POSITION_X] = "Position X",
+       [ABS_MT_POSITION_Y] = "Position Y",
+       [ABS_MT_TOOL_TYPE] = "Tool Type",
+       [ABS_MT_BLOB_ID] = "Blob ID",
+       [ABS_MT_TRACKING_ID] = "Tracking ID",
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
+       [ABS_MT_PRESSURE] = "Pressure",
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
+       [ABS_MT_SLOT] = "Slot",
+#endif
+
+};
+
+char *misc[MSC_MAX + 1] = {
+       [ 0 ... MSC_MAX] = NULL,
+       [MSC_SERIAL] = "Serial",        [MSC_PULSELED] = "Pulseled",
+       [MSC_GESTURE] = "Gesture",      [MSC_RAW] = "RawData",
+       [MSC_SCAN] = "ScanCode",
+};
+
+char *leds[LED_MAX + 1] = {
+       [0 ... LED_MAX] = NULL,
+       [LED_NUML] = "NumLock",         [LED_CAPSL] = "CapsLock", 
+       [LED_SCROLLL] = "ScrollLock",   [LED_COMPOSE] = "Compose",
+       [LED_KANA] = "Kana",            [LED_SLEEP] = "Sleep", 
+       [LED_SUSPEND] = "Suspend",      [LED_MUTE] = "Mute",
+       [LED_MISC] = "Misc",
+};
+
+char *repeats[REP_MAX + 1] = {
+       [0 ... REP_MAX] = NULL,
+       [REP_DELAY] = "Delay",          [REP_PERIOD] = "Period"
+};
+
+char *sounds[SND_MAX + 1] = {
+       [0 ... SND_MAX] = NULL,
+       [SND_CLICK] = "Click",          [SND_BELL] = "Bell",
+       [SND_TONE] = "Tone"
+};
+
+char **names[EV_MAX + 1] = {
+       [0 ... EV_MAX] = NULL,
+       [EV_SYN] = events,                      [EV_KEY] = keys,
+       [EV_REL] = relatives,                   [EV_ABS] = absolutes,
+       [EV_MSC] = misc,                        [EV_LED] = leds,
+       [EV_SND] = sounds,                      [EV_REP] = repeats,
+};
+
+#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)
+
+int main (int argc, char **argv)
+{
+       int fd, rd, i, j, k;
+       struct input_event ev[64];
+       int version;
+       unsigned short id[4];
+       unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
+       char name[256] = "Unknown";
+       int abs[6] = {0};
+
+       if (argc < 2) {
+               printf("Usage: evtest /dev/input/eventX\n");
+               printf("Where X = input device number\n");
+               return 1;
+       }
+
+       if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
+               perror("evtest");
+               return 1;
+       }
+
+       if (ioctl(fd, EVIOCGVERSION, &version)) {
+               perror("evtest: can't get version");
+               return 1;
+       }
+
+       printf("Input driver version is %d.%d.%d\n",
+               version >> 16, (version >> 8) & 0xff, version & 0xff);
+
+       ioctl(fd, EVIOCGID, id);
+       printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 
0x%x\n",
+               id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);
+
+       ioctl(fd, EVIOCGNAME(sizeof(name)), name);
+       printf("Input device name: \"%s\"\n", name);
+
+       memset(bit, 0, sizeof(bit));
+       ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
+       printf("Supported events:\n");
+
+       for (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 (j = 0; j < KEY_MAX; j++) 
+                               if (test_bit(j, bit[i])) {
+                                       printf("    Event code %d (%s)\n", j, 
names[i] ? (names[i][j] ? names[i][j] : "?") : "?");
+                                       if (i == EV_ABS) {
+                                               ioctl(fd, EVIOCGABS(j), abs);
+                                               for (k = 0; k < 6; k++)
+                                                       if ((k < 3) || abs[k])
+                                                               printf("      
%s %6d\n", absval[k], abs[k]);
+                                       }
+                               }
+               }
+               
+
+       printf("Testing ... (interrupt to exit)\n");
+
+       while (1) {
+               rd = read(fd, ev, sizeof(struct input_event) * 64);
+
+               if (rd < (int) sizeof(struct input_event)) {
+                       printf("yyy\n");
+                       perror("\nevtest: error reading");
+                       return 1;
+               }
+
+               for (i = 0; i < rd / sizeof(struct input_event); i++)
+
+                       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);
+                       }       
+
+       }
+}

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


commit e2337eac41e0802575dc72a0194a4e0ac7a68642
Author: Rob Savoye <address@hidden>
Date:   Wed Jan 19 21:19:42 2011 -0700

    reset input devices to no, or we can't select just one

diff --git a/configure.ac b/configure.ac
index b9c8e1d..5a9d339 100644
--- a/configure.ac
+++ b/configure.ac
@@ -853,6 +853,10 @@ AC_ARG_ENABLE(input,
   [if test -n ${enableval}; then
     enableval=`echo ${enableval} | tr '\054' ' ' `
   fi
+  build_ps2mouse=no
+  build_ps2keyboard=no
+  build_input_events=no
+  build_tslib=no
   while test -n "${enableval}" ; do
     val=`echo ${enableval} | cut -d ' ' -f 1`
     case "${val}" in

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

Summary of changes:
 configure.ac                     |    4 +
 gui/fb/fb.cpp                    |   59 +-
 gui/fb/fbsup.h                   |    2 +-
 libdevice/events/EventDevice.cpp |  180 +++-
 libdevice/events/InputDevice.cpp |   30 +-
 libdevice/events/InputDevice.h   |   30 +-
 libdevice/events/MouseDevice.cpp |   30 +-
 libdevice/events/TouchDevice.cpp |   23 +-
 libdevice/events/events.am       |   10 +-
 libdevice/events/evtest.c        |  463 ++++++++++
 libdevice/events/test_events.cpp |    4 +-
 librender/agg/Renderer_agg.cpp   | 1842 ++++++++++++++++++--------------------
 12 files changed, 1640 insertions(+), 1037 deletions(-)
 create mode 100644 libdevice/events/evtest.c


hooks/post-receive
-- 
Gnash



reply via email to

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