gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] [SCM] Gnash branch, openvg, created. 25d315301e008059e614


From: Rob Savoye
Subject: [Gnash-commit] [SCM] Gnash branch, openvg, created. 25d315301e008059e614f299bdd16bbb40d7ab73
Date: Tue, 17 Aug 2010 04:11:31 +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 created
        at  25d315301e008059e614f299bdd16bbb40d7ab73 (commit)

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=25d315301e008059e614f299bdd16bbb40d7ab73


commit 25d315301e008059e614f299bdd16bbb40d7ab73
Author: Rob Savoye <address@hidden>
Date:   Mon Aug 16 21:35:33 2010 -0600

    copy files from old bzr branch to get around merge conflicts.

diff --git a/gui/fb/fb.cpp b/gui/fb/fb.cpp
index f3315ab..1a5c0a7 100644
--- a/gui/fb/fb.cpp
+++ b/gui/fb/fb.cpp
@@ -699,142 +699,6 @@ FBGui::enable_terminal()
     } //command()
 #endif
 
-#ifdef USE_MOUSE_PS2    
-bool
-FBGui::init_mouse() 
-{
-
-       // see http://www.computer-engineering.org/ps2mouse/
-  
-
-       // Try to open mouse device, be error tolerant (FD is kept open all the 
time)
-       input_fd = open(MOUSE_DEVICE, O_RDWR);
-  
-       if (input_fd<0) {
-           log_debug(_("Could not open " MOUSE_DEVICE ": %s"), 
strerror(errno));    
-           return false;
-       }
-  
-       unsigned char buf[10], byte;
-
-       if (fcntl(input_fd, F_SETFL, fcntl(input_fd, F_GETFL) | O_NONBLOCK)<0) {
-           log_error("Could not set non-blocking mode for mouse device: %s", 
strerror(errno));
-           close(input_fd);
-           input_fd=-1;
-           return false; 
-       }
-  
-       // Clear input buffer
-       while ( read(input_fd, buf, sizeof buf) > 0 ) { }
-  
-       // Reset mouse
-       if ((!mouse_command(0xFF, buf, 3)) || (buf[0]!=0xFA)) {
-           log_debug(_("Mouse reset failed"));
-           close(input_fd);
-           input_fd=-1;
-           return false; 
-       }
-  
-       // Get Device ID (not crucial, debug only)
-       if ((!mouse_command(0xF2, buf, 2)) || (buf[0]!=0xFA)) {
-           log_debug(_("WARNING: Could not detect mouse device ID"));
-       } else {
-           unsigned char devid = buf[1];
-           if (devid!=0)
-               log_debug(_("WARNING: Non-standard mouse device ID %d"), devid);
-       }
-  
-       // Enable mouse data reporting
-       if ((!mouse_command(0xF4, &byte, 1)) || (byte!=0xFA)) {
-           log_debug(_("Could not activate Data Reporting mode for mouse"));
-           close(input_fd);
-           input_fd=-1;
-           return false; 
-       }
-  
-  
-       log_debug(_("Mouse enabled."));
-      
-       mouse_x = 0;
-       mouse_y = 0;
-       mouse_btn = 0;
-  
-       return true;
-    }
-#endif
-
-#ifdef USE_MOUSE_PS2    
-    bool FBGui::check_mouse() 
-    {
-       if (input_fd<0) return false;   // no mouse available
-  
-       int i;
-       int xmove, ymove, btn, btn_changed;
-  
-       read_mouse_data();
-  
-       // resync
-       int pos = -1;
-       for (i=0; i<mouse_buf_size; i++)
-           if (mouse_buf[i] & 8) { // bit 3 must be high for the first byte
-               pos = i;
-               break;    
-           }
-       if (pos<0) return false; // no sync or no data
-  
-       if (pos>0) {
-           // remove garbage:
-           memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
-           mouse_buf_size -= pos;
-       }
-  
-  
-       if (mouse_buf_size >= 3) {
-  
-           xmove = mouse_buf[1];
-           ymove = mouse_buf[2];
-           btn = mouse_buf[0] & 1;
-    
-           if (mouse_buf[0] & 0x10) xmove = -(256-xmove);
-           if (mouse_buf[0] & 0x20) ymove = -(256-ymove);
-    
-           ymove *= -1; // vertical movement is upside-down
-    
-           log_debug(_("x/y %d/%d btn %d"), xmove, ymove, btn);
-
-           // movement    
-           mouse_x += xmove;
-           mouse_y += ymove;
-    
-           if (mouse_x<0) mouse_x=0;
-           if (mouse_y<0) mouse_y=0;
-           if (mouse_x>m_stage_width) mouse_x=m_stage_width;
-           if (mouse_y>m_stage_height) mouse_y=m_stage_height;
-    
-           //log_debug(_("mouse @ %d / %d, btn %d"), mouse_x, mouse_y, 
mouse_btn);
-    
-           notify_mouse_moved(mouse_x, mouse_y);
-    
-           // button
-           if (btn != mouse_btn) {
-               mouse_btn = btn;
-               printf("clicked: %d\n", btn);      
-               notify_mouse_clicked(btn, 1);  // mark=??
-               //log_debug(_("mouse click! %d"), btn);
-           }    
-
-           // remove from buffer
-           pos=3;
-           memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
-           mouse_buf_size -= pos;  
-    
-           return true;
-  
-       }
-  
-    }
-#endif
-
 #ifdef USE_MOUSE_ETT    
     bool FBGui::init_mouse()
     {
diff --git a/gui/fb/fbsup.h b/gui/fb/fbsup.h
index 506a3bc..05ed5b1 100644
--- a/gui/fb/fbsup.h
+++ b/gui/fb/fbsup.h
@@ -31,17 +31,6 @@
 #define PIXELFORMAT_LUT8
 #define CMAP_SIZE (256*2)
 
-// Define this to read from /dev/input/mice (any PS/2 compatbile mouse or
-// emulated by the Kernel) 
-//#define USE_MOUSE_PS2
-
-// Define this to read from /dev/input/event0 (new generic input subsystem)
-#define USE_INPUT_EVENTS
-
-// Define this to support eTurboTouch / eGalax touchscreens. When reading from
-// a serial device, it must be initialized (stty) externally. 
-//#define USE_MOUSE_ETT
-
 #ifdef USE_MOUSE_PS2
 #define MOUSE_DEVICE "/dev/input/mice"
 #endif

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


commit 62e55ddc82c6384de5f45df0b1046716f8ae1ec9
Merge: c028bb7 78b457f
Author: Rob Savoye <address@hidden>
Date:   Mon Aug 16 20:52:05 2010 -0600

    merge master into older OpenVG bzr branch, which was imported into git.

diff --cc configure.ac
index 908755b,aab5c82..4eeb05a
--- a/configure.ac
+++ b/configure.ac
@@@ -743,14 -710,213 +710,208 @@@ operating system." >&
    fi
  fi
  
+ dnl We can use Xephyr or fbe to create a fake framebuffer instead of real
+ dnl video memory. This lets us test on a desktop machine.
+ AC_ARG_WITH(fakefb,
+ AC_HELP_STRING([--with-fakefb],
+  [specify a file to be mapped instead of a real framebuffer]),
+  with_fakefb=${withval})
+ 
+ fakefb=
+ if test x"${with_fakefb}" = xyes; then
+   dnl This is the default file name fbe uses.
+   fakefb=/tmp/fbe_buffer
+ else
+   if test x"${with_fakefb}" != x; then
+     fakefb=${with_fakefb}
+   fi
+ fi
+ FAKEFB=${fakefb}
+ AC_SUBST(FAKEFB)
+ 
+ if test x"${fakefb}" != x; then
+     AC_DEFINE(ENABLE_FAKE_FRAMEBUFFER, [1], [Enable using a file instead of a 
real framebuffer])
+ fi
+ 
+ 
+ dnl --------------------------------------------------------
+ dnl  Sound handler selection
+ dnl --------------------------------------------------------
+ add_sound=
+ build_sound_sdl=no
+ build_sound_ahi=no
+ build_sound_mkit=no
+ AC_ARG_ENABLE(sound,
+   AC_HELP_STRING([--enable-sound=[[sdl|ahi|mkit]]], [Use the specified sound 
handler (default=sdl)]),
+      [case "${enableval}" in
+       sdl|SDL|Sdl)
+         build_sound_sdl=yes
+         add_sound="sdl"
+         ;;
+       ahi|AHI|Ahi)
+         build_sound_ahi=yes
+         add_sound="ahi"
+         ;;
+       mkit|MKIT|Mkit)
+         build_sound_mkit=yes
+         add_sound="mkit"
+         ;;
+      esac],
+   [if test x"${haiku}" = xyes; then
+      build_sound_mkit=yes
+      add_sound="mkit"
+    else
+      build_sound_sdl=yes
+      add_sound=sdl
+    fi]
+ )
+ 
+ 
+ dnl --------------------------------------------------------
+ dnl  Media handler selection
+ dnl --------------------------------------------------------
 -build_media_gst=no
++build_media_gst=yes
+ build_media_ffmpeg=no
+ AC_ARG_ENABLE(media,
+   AC_HELP_STRING([--enable-media=handler],
+     [Enable media handling support using the specified handler: gst, ffmpeg 
or none (no sound) [[gst]] ]),
+   
+     if test -n ${enableval}; then
+       enableval=`echo ${enableval} | tr '\054' ' ' `
+     fi
+     while test -n "${enableval}"; do
+       val=`echo ${enableval} | cut -d ' ' -f 1`
+       [case "${val}" in
+         GST|gst)
+           build_media_gst=yes
+           media_list="${media_list}gst "
+           ;;
+         FFMPEG|ffmpeg)
+           build_media_ffmpeg=yes
+           media_list="${media_list}ffmpeg "
+           ;;
+         no|NO|none)
+           media_list="none"
+           ;;
+         *)
+           AC_MSG_ERROR([bad value ${enableval} for --enable-media option])
+           ;;
+      
+       esac]
+       enableval=`echo ${enableval} | cut -d ' ' -f 2-6`
+       if test "x$val" = "x$enableval"; then
+         break;
+       fi
+     done,
+     [if test x"${build_haiku}" = xyes; then
+         build_media_ffmpeg=yes
+         build_media_haiku=yes
+         media_list="ffmpeg haiku"
+      else
+         build_media_gst=yes
+         media_list="gst"
+     fi]
+ )
+ 
+ MEDIA_CONFIG="${media_list}"
+ AC_SUBST(MEDIA_CONFIG)
+ 
 -dnl if no media handler is selected, default to Gstreamer.
 -if test x"$build_media_ffmpeg" = x"no" -a x"$build_media_gst" = x"no"; then
 -   build_media_gst=yes
 -fi
 -
+ if test x"$build_media_ffmpeg" = x"yes"; then
+   GNASH_PATH_FFMPEG
+ fi
+ 
+ dnl -------------------------------
+ dnl Input Device selection
+ dnl -------------------------------
+ 
+ dnl Multiple input devices are supported. These can all work in
+ dnl varying combinations, so several may be listed. These are only
+ dnl required when using the Framebuffer, as without the X11 desktop,
+ dnl Gnash has to handle all these internally. This can get
+ dnl messy, as one might want to use a touchscreen with a normal mouse
+ dnl or keyboard attached. 
+ dnl By default, don't build any of these, as they are only for the Framebuffer
+ dnl running without X11.
+ if test x"${build_fb}" = xyes; then
+ build_ps2mouse=yes
+ build_ps2keyboard=no
+ build_input_events=yes
+ build_tslib=yes
+ input_events="PS/2 Mouse, Input Devices, Touchscreen via Tslib"
+ else
+ build_ps2mouse=no
+ build_ps2keyboard=no
+ build_input_events=no
+ build_tslib=no
+ input_events=
+ fi
+ AC_ARG_ENABLE(input,
+   AC_HELP_STRING([--enable-input=], [Enable support for the specified input 
devices for the framebuffer GUI 
(default=ps2mouse|ps2keyboard|events|touchscreen)]),
+   [if test -n ${enableval}; then
+     enableval=`echo ${enableval} | tr '\054' ' ' `
+   fi
+   while test -n "${enableval}" ; do
+     val=`echo ${enableval} | cut -d ' ' -f 1`
+     case "${val}" in
+       ps2m*|PS2m*|m*|M*)        dnl a PS/2 style mouse
+         build_ps2mouse=yes
+         input_events="${input_events}, PS/2 Mouse"
+         ;;
+       ps2k*|PS2K*|k*|K*)        dnl a PS/2 style keyboard
+         build_ps2keyboard=yes
+         input_events="${input_events}, PS/2 Keyboard"
+         ;;
+       i*|I*|ev*|Ev*)    dnl use the new Input Event, which supports both
+         input_events="${input_events}, Input Event Device"
+         build_input_events=yes
+         ;;
+       t*|T*) dnl use a touchscreen with tslib, which works like a mouse
+         build_tslib=yes
+         input_events="${input_events}, Touchscreen"
+         ;;
+       *) AC_MSG_ERROR([invalid input device list! ${enableval} given (accept: 
ps2mouse|keyboard|events,touchscreen)])
+          ;;
+       esac
+     enableval=`echo ${enableval} | cut -d ' ' -f 2-6`
+     if test "x$val" = "x$enableval"; then
+       break;
+     fi
+   done],
+ )
+ 
+ if test x"${build_tslib}" = xyes; then
+   AC_DEFINE(USE_TSLIB, [1], [Use a tslib supported touchscreen])
+   GNASH_PKG_FIND(ts, [tslib.h], [Touchscreen library], ts_config)
+ fi
+ AM_CONDITIONAL(ENABLE_TSLIB, [test x${ac_cv_header_tslib_h} != xno])
+ 
+ if test x"${build_ps2mouse}" = xyes; then
+   AC_DEFINE(USE_MOUSE_PS2, [1], [Add support for a directly using a PS/2 
Mouse])
+ fi
+ AM_CONDITIONAL(ENABLE_MOUSE, [test x"${build_ps2mouse}" = xyes])
+ 
+ if test x"${build_ps2keyboard}" = xyes; then
+   AC_DEFINE(USE_KEYBOARD_PS2, [1], [Add support for directly using a PS/2 
Keyboard])
+ fi
+ if test x"${build_input_events}" = xyes; then
+   AC_DEFINE(USE_INPUT_EVENTS, [1], [Add support for a directly using Linux 
Input Event Devices])
+ fi
+ AM_CONDITIONAL(ENABLE_INPUT_EVENTS, [test x"${build_input_events}" = xyes])
+ dnl this is enabled if we have any input devices at all
+ AM_CONDITIONAL(ENABLE_INPUT_DEVICES, [test x"${input_events}" != x])
+ 
+ dnl -------------------------------
+ dnl Renderer Selection
+ dnl -------------------------------
+ input_events=
  dnl By default, we want to to build all renderers
- build_gles=no   dnl OpenGL-ES 1.1 and 2.x
- build_ovg=yes   dnl OpenVG
- build_ogl=yes   dnl OpenGL
- build_agg=yes   dnl AntiGrain
- build_cairo=yes dnl Cairo
- renderer_list="OpenGL OpenVG AGG Cairo"
- nrender=4
+ build_ovg=no
+ build_gles=no
+ build_ogl=yes
+ build_agg=yes
+ build_cairo=yes
+ renderer_list="OpenGL AGG Cairo"
+ nrender=3
  AC_ARG_ENABLE(renderer,
    AC_HELP_STRING([--enable-renderer=], [Enable support for the specified 
renderers (ogl|gles|cairo|agg|all, default=all)]),
    if test -n ${enableval}; then
diff --cc gui/fb/.#fbsup.h
index 0000000,0000000..1d9fded
new file mode 120000
--- /dev/null
+++ b/gui/fb/.#fbsup.h
@@@ -1,0 -1,0 +1,1 @@@
address@hidden:1281627622

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


commit c028bb7d68b8d36b42d642862e43b12d46773867
Author: Rob Savoye <address@hidden>
Date:   Sat Jul 24 10:43:34 2010 -0600

    new files from branch, seperate the rendeer from the fb gui. Add OpenVG 
support.

diff --git a/gui/fb/fb_glue_agg.cpp b/gui/fb/fb_glue_agg.cpp
new file mode 100644
index 0000000..c1b0486
--- /dev/null
+++ b/gui/fb/fb_glue_agg.cpp
@@ -0,0 +1,271 @@
+//
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+//   Foundation, Inc
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <cstring>
+#include <boost/cstdint.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "Renderer.h"
+#include "Renderer_agg.h"
+#include "fbsup.h"
+#include "fb_glue_agg.h"
+#include "RunResources.h"
+#include "log.h"
+
+namespace gnash {
+
+FBAggGlue::FBAggGlue(int fd)
+    : _fd(fd),
+      _rowsize(0)
+{
+    GNASH_REPORT_FUNCTION;
+
+    memset(&_var_screeninfo, 0, sizeof(struct fb_var_screeninfo));
+    memset(&_fix_screeninfo, 0, sizeof(struct fb_fix_screeninfo));
+}
+
+FBAggGlue::~FBAggGlue()
+{
+    GNASH_REPORT_FUNCTION;    
+
+    // Close the memory
+    if (_fd) {
+        ::close(_fd);
+    }
+}
+
+void
+FBAggGlue::setInvalidatedRegions(const InvalidatedRanges &ranges)
+{
+    GNASH_REPORT_FUNCTION;
+
+}
+
+bool
+FBAggGlue::init (int argc, char ***argv)
+{
+    GNASH_REPORT_FUNCTION;
+
+    // Load framebuffer properties
+#ifdef ENABLE_FAKE_FRAMEBUFFER
+    fakefb_ioctl(_fd, FBIOGET_VSCREENINFO, &_var_screeninfo);
+    fakefb_ioctl(_fd, FBIOGET_FSCREENINFO, &_fix_screeninfo);
+#else  // ENABLE_FAKE_FRAMEBUFFER
+    ioctl(_fd, FBIOGET_VSCREENINFO, &_var_screeninfo);
+    ioctl(_fd, FBIOGET_FSCREENINFO, &_fix_screeninfo);
+#endif
+    
+    log_debug(_("Framebuffer device uses %d bytes of memory."),
+             _fix_screeninfo.smem_len);
+    log_debug(_("Video mode: %dx%d with %d bits per pixel."),
+             _var_screeninfo.xres, _var_screeninfo.yres,
+              _var_screeninfo.bits_per_pixel);
+    
+    // map framebuffer into memory
+    _fbmem.reset(static_cast<boost::uint8_t *>(mmap(0, 
_fix_screeninfo.smem_len,
+                                          PROT_READ|PROT_WRITE, MAP_SHARED,
+                                          _fd, 0)));
+    
+#ifdef ENABLE_DOUBLE_BUFFERING
+    // allocate offscreen buffer
+    _buffer.reset(new boost::uint8_t[_fix_screeninfo.smem_len]);
+    memset(_buffer.get(), 0, _fix_screeninfo.smem_len);
+#endif  
+    
+#ifdef PIXELFORMAT_LUT8
+    // Set grayscale for 8 bit modes
+    if (_var_screeninfo.bits_per_pixel == 8) {
+       if (!set_grayscale_lut8())
+           return false;
+    }
+#endif
+
+    return true;
+}
+
+#define TO_16BIT(x) (x | (x<<8))
+
+bool
+FBAggGlue::set_grayscale_lut8()
+{
+    GNASH_REPORT_FUNCTION;
+    
+    struct fb_cmap cmap;
+    int i;
+    
+    log_debug(_("LUT8: Setting up colormap"));
+    
+    cmap.start = 0;
+    cmap.len = 256;
+    cmap.red = new boost::uint16_t[CMAP_SIZE];
+    cmap.green = new boost::uint16_t[CMAP_SIZE];
+    cmap.blue = new boost::uint16_t[CMAP_SIZE];
+    cmap.transp = NULL;
+    
+    for (i=0; i<256; i++) {
+       
+       int r = i;
+       int g = i;
+       int b = i;
+       
+       cmap.red[i] = TO_16BIT(r);
+       cmap.green[i] = TO_16BIT(g);
+       cmap.blue[i] = TO_16BIT(b);
+       
+    }
+    
+#ifdef ENABLE_FAKE_FRAMEBUFFER
+    if (fakefb_ioctl(_fd, FBIOPUTCMAP, &cmap))
+#else
+    if (ioctl(_fd, FBIOPUTCMAP, &cmap))
+#endif
+    {
+       log_error(_("LUT8: Error setting colormap: %s"), strerror(errno));
+       return false;
+    }
+    
+    return true;
+     
+#undef TO_16BIT
+}    
+
+Renderer *
+FBAggGlue::createRenderHandler()
+{
+    GNASH_REPORT_FUNCTION;
+
+    const int width     = _var_screeninfo.xres;
+    const int height    = _var_screeninfo.yres;
+    const int bpp       = _var_screeninfo.bits_per_pixel;
+    const int size      = _fix_screeninfo.smem_len; 
+    
+    // TODO: should recalculate!  
+    boost::uint8_t       *mem;
+    Renderer_agg_base   *agg_handler;
+
+    agg_handler = NULL;
+
+    // _validbounds.setTo(0, 0, width - 1, height - 1);
+    
+#ifdef ENABLE_DOUBLE_BUFFERING
+    log_debug(_("Double buffering enabled"));
+    mem = _buffer;
+#else
+    log_debug(_("Double buffering disabled"));
+    mem = _fbmem.get();
+#endif
+    
+    agg_handler = NULL;
+  
+    // choose apropriate pixel format
+    
+    log_debug(_("red channel: %d / %d"), _var_screeninfo.red.offset, 
+             _var_screeninfo.red.length);
+    log_debug(_("green channel: %d / %d"), _var_screeninfo.green.offset, 
+             _var_screeninfo.green.length);
+    log_debug(_("blue channel: %d / %d"), _var_screeninfo.blue.offset, 
+             _var_screeninfo.blue.length);
+    log_debug(_("Total bits per pixel: %d"), _var_screeninfo.bits_per_pixel);
+    
+    const char* pixelformat = agg_detect_pixel_format(
+        _var_screeninfo.red.offset, _var_screeninfo.red.length,
+        _var_screeninfo.green.offset, _var_screeninfo.green.length,
+        _var_screeninfo.blue.offset, _var_screeninfo.blue.length,
+        bpp
+        );
+    
+    if (pixelformat) {    
+       agg_handler = create_Renderer_agg(pixelformat);      
+    } else {
+       log_error("The pixel format of your framebuffer could not be 
detected.");
+       return false;
+    }
+    
+    assert(agg_handler != NULL);
+
+    _rowsize = _var_screeninfo.xres_virtual*((bpp+7)/8);
+    
+    agg_handler->init_buffer(mem, size, width, height, _rowsize);
+    
+    return (Renderer *)agg_handler;
+}    
+
+void
+FBAggGlue::render()
+{
+    // GNASH_REPORT_FUNCTION;
+
+    if ( _drawbounds.size() == 0 ) {
+        return; // nothing to do..
+    }
+    
+#ifdef ENABLE_DOUBLE_BUFFERING
+    // Size of a pixel in bytes
+    // NOTE: +7 to support 15 bpp
+    const unsigned int pixel_size = (var_screeninfo.bits_per_pixel+7)/8;
+    
+    for (unsigned int bno=0; bno < _drawbounds.size(); bno++) {
+       geometry::Range2d<int>& bounds = _drawbounds[bno];
+        
+       assert ( ! bounds.isWorld() );
+       
+       // Size, in bytes, of a row that has to be copied
+       const unsigned int row_size = (bounds.width()+1) * pixel_size;
+       
+       // copy each row
+       const int minx = bounds.getMinX();
+       const int maxy = bounds.getMaxY();
+       
+       for (int y=bounds.getMinY(); y<=maxy; ++y) {    
+           const unsigned int pixel_index = y * _rowsize + minx*pixel_size;
+           memcpy(&fbmem[pixel_index], &buffer[pixel_index], row_size);
+           
+       }
+    }  
+    
+#endif
+    
+#ifdef DEBUG_SHOW_FPS
+    profile();
+#endif
+}    
+
+int
+FBAggGlue::width()
+{
+    return _var_screeninfo.xres_virtual;
+}
+
+int
+FBAggGlue::height()
+{
+    return _var_screeninfo.yres_virtual;
+}
+
+} // end of namespace gnash
+    
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/gui/fb/fb_glue_agg.h b/gui/fb/fb_glue_agg.h
new file mode 100644
index 0000000..6ce3e79
--- /dev/null
+++ b/gui/fb/fb_glue_agg.h
@@ -0,0 +1,78 @@
+//
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+//   Foundation, Inc
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef GNASH_FB_GLUE_AGG_H
+#define GNASH_FB_GLUE_AGG_H
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <boost/cstdint.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "fbsup.h"
+
+namespace gnash {
+
+class Renderer;
+
+class FBAggGlue: public FBGlue
+{
+public:
+    FBAggGlue(int fd);
+
+    // All of these virtuals are all defined in the base FBGlue class
+    virtual ~FBAggGlue();
+    virtual bool init(int argc, char ***argv);    
+    virtual Renderer *createRenderHandler();
+    virtual void setInvalidatedRegions(const InvalidatedRanges &ranges);
+    virtual int width();
+    virtual int height();
+    virtual void render();
+
+    /// For 8 bit (palette / LUT) modes, sets a grayscale palette.
+    //
+    /// This GUI currently does not support palette modes. 
+    //
+    bool set_grayscale_lut8();
+
+protected:
+    int                 _fd;
+    struct fb_var_screeninfo _var_screeninfo;
+    struct fb_fix_screeninfo _fix_screeninfo;
+    struct fb_cmap           _cmap;
+    
+    boost::shared_ptr<boost::uint8_t> _fbmem;  // framebuffer memory
+#ifdef ENABLE_DOUBLE_BUFFERING
+    boost::shared_ptr<boost::uint8_t> _buffer; // offscreen buffer
+#endif
+    boost::uint32_t             _rowsize;
+    std::vector< geometry::Range2d<int> > _drawbounds;
+
+    boost::shared_ptr<Renderer> _renderer;
+};
+
+} // end of gnash namespace
+
+#endif  // GNASH_FB_GLUE_AGG_H
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/gui/fb/fb_glue_gles.cpp b/gui/fb/fb_glue_gles.cpp
new file mode 100644
index 0000000..ea884e4
--- /dev/null
+++ b/gui/fb/fb_glue_gles.cpp
@@ -0,0 +1,181 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+//              Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+// gles-1.0c for Linux
+#ifdef HAVE_GLES_GL_H
+# include <GLES/gl.h>
+#endif
+#ifdef HAVE_GLES_EGL_H
+#include <GLES/egl.h>
+#endif
+// Mali Developer Tools for ARM 1.x
+#ifdef HAVE_EGL_EGL_H
+# include <EGL/egl.h>
+# include <EGL/eglext.h>
+#endif
+// Mali Developer Tools for ARM 2.x and Android 2.1
+#ifdef HAVE_GLES2_GL2_H
+# include <GLES2/gl2.h>
+# include <GLES2/gl2ext.h>
+#endif
+
+#include "log.h"
+#include "fb_gles_glue.h"
+
+namespace gnash
+{
+
+bool 
+FBglesGlue::init(int /*argc*/, char *** /*argv*/) {
+    EGLint majorVersion, minorVersion;
+    EGLint numOfConfigs = 0;
+    EGLint result;
+    const EGLint main_attrib_list[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_BUFFER_SIZE, 32,
+        EGL_DEPTH_SIZE, 16,
+        EGL_NONE
+    };
+    
+    _display = eglGetDisplay((NativeDisplayType)0);
+    if (_display == EGL_NO_DISPLAY) {
+        return false;
+    }
+    log_trace("EGL: getDisplay ok");
+    
+    result = eglInitialize(_display, &majorVersion, &minorVersion);
+    if (result == EGL_FALSE) {
+        return false;
+    }
+    log_trace("EGL: initialize ok");
+    
+    result = eglChooseConfig(_display, main_attrib_list, &_config, 1,
+                             &numOfConfigs);
+    if (result == EGL_FALSE || numOfConfigs != 1) {
+        return false;
+    }
+    log_trace("EGL: config ok");
+    
+    _surface = eglCreateWindowSurface(_display, _config, (NativeWindowType)0,
+                                      NULL);
+    if (eglGetError () != EGL_SUCCESS) {
+        return false;
+    }
+    log_trace("EGL: surface ok");
+    
+    _context = eglCreateContext(_display, _config, NULL, NULL);
+    if (eglGetError () != EGL_SUCCESS) {
+        return false;
+    }
+    log_trace("EGL: context ok");
+    
+    eglMakeCurrent(_display, _surface, _surface, _context);
+    if (eglGetError () != EGL_SUCCESS) {
+        return false;
+    }
+    log_trace("EGL: current ok");
+    
+    const EGLint pbuffer_config_list[] = {
+        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+        EGL_BUFFER_SIZE, 32,
+        EGL_DEPTH_SIZE, 0,
+        EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
+        EGL_CONFIG_CAVEAT, EGL_NONE,
+        EGL_NONE
+    };
+    
+    result = eglChooseConfig(_display, pbuffer_config_list, &_pbuffer_config,
+                             1, &numOfConfigs);
+    if (result == EGL_FALSE || numOfConfigs == 0) {
+        return false;
+    }
+    log_trace("EGL: pbuffer config ok");
+    
+    const EGLint pbuffer_attrib_list[] = {
+        EGL_WIDTH, PBUFFER_WIDTH,
+        EGL_HEIGHT, PBUFFER_HEIGHT,
+        EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
+        EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
+        EGL_MIPMAP_TEXTURE, EGL_FALSE,
+        EGL_NONE
+    };
+    
+    _pbuffer = eglCreatePbufferSurface(_display, _pbuffer_config,
+                                       pbuffer_attrib_list);
+    if (eglGetError () != EGL_SUCCESS) {
+        return false;
+    }
+    log_trace("EGL: pbuffer surface ok");
+    
+    return true;
+}
+
+FBglesGlue::~FBglesGlue () {
+    eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglTerminate(_display);
+}
+
+int 
+FBglesGlue::width() {
+    EGLint result;
+    eglQuerySurface (_display, _surface, EGL_WIDTH, &result);
+    log_trace("EGL: width %d", result);
+    return result;
+}
+
+int
+FBglesGlue::height() {
+    EGLint result;
+    eglQuerySurface (_display, _surface, EGL_HEIGHT, &result);
+    log_trace("EGL: height %d", result);
+    return result;
+}
+
+void
+FBglesGlue::render() {
+    eglSwapBuffers(_display, _surface);
+}
+
+void 
+FBglesGlue::render_to_pbuffer () {
+    if (_pbuffer != EGL_NO_SURFACE)
+        eglMakeCurrent(_display, _pbuffer, _pbuffer, _context);
+}
+
+void 
+FBglesGlue::prepare_copy_from_pbuffer () {
+    if (_pbuffer != EGL_NO_SURFACE)
+        eglMakeCurrent(_display, _surface, _pbuffer, _context);
+}
+
+void 
+FBglesGlue::render_to_display () {
+    if (_pbuffer != EGL_NO_SURFACE)
+        eglMakeCurrent(_display, _surface, _surface, _context);
+}
+
+} // namespace gnash
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/gui/fb/fb_glue_gles.h b/gui/fb/fb_glue_gles.h
new file mode 100644
index 0000000..3962ea6
--- /dev/null
+++ b/gui/fb/fb_glue_gles.h
@@ -0,0 +1,93 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+//              Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef FB_OGL_GLUE_H
+#define FB_OGL_GLUE_H
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+// gles-1.0c for Linux
+#ifdef HAVE_GLES_GL_H
+# include <GLES/gl.h>
+# endif
+#ifdef HAVE_GLES_EGL_H
+#include <GLES/egl.h>
+#endif
+// Mali Developer Tools for ARM 1.x
+#ifdef HAVE_EGL_EGL_H
+# include <EGL/egl.h>
+# include <EGL/eglext.h>
+#endif
+// Mali Developer Tools for ARM 2.x and Android 2.1
+#ifdef HAVE_GLES2_GL2_H
+# include <GLES2/gl2.h>
+# include <GLES2/gl2ext.h>
+#endif
+
+#include "ogl_glue.h"
+#include "fbsup.h"
+#include "render_handler_gles.h"
+
+namespace gnash
+{
+
+class FBglesGlue: public FBGlue, public OglGlue
+{
+public:
+    FBglesGlue() :
+        _surface (EGL_NO_SURFACE),
+        _pbuffer (EGL_NO_SURFACE) {}
+    virtual ~FBglesGlue();
+    
+    virtual bool init(int /*argc*/, char *** /*argv*/);
+    
+    virtual render_handler* createRenderHandler() {
+        //_render_handler = create_render_handler_ogl (true, this);
+        return _render_handler;
+    }
+    
+    virtual void setInvalidatedRegions(const InvalidatedRanges& /* ranges */) 
{}
+    
+    virtual int width ();
+    virtual int height ();
+    virtual void render ();
+    
+    virtual void render_to_pbuffer ();
+    virtual void prepare_copy_from_pbuffer ();
+    virtual void render_to_display ();
+    
+private:
+    render_handler* _render_handler;
+    EGLDisplay      _display;
+    EGLConfig       _config;
+    EGLContext      _context;
+    EGLSurface      _surface;
+    EGLConfig       _pbuffer_config;
+    EGLSurface      _pbuffer;
+};
+
+} // namespace gnash
+
+#endif // FB_OGL_GLUE_H
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/gui/fb/fb_glue_ovg.cpp b/gui/fb/fb_glue_ovg.cpp
new file mode 100644
index 0000000..4739b4a
--- /dev/null
+++ b/gui/fb/fb_glue_ovg.cpp
@@ -0,0 +1,30 @@
+//
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+//   Foundation, Inc
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+namespace gnash {
+    
+} // end of namespace gnash
+    
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/gui/gtk/gtk_glue_egl.h b/gui/gtk/gtk_glue_egl.h
new file mode 100644
index 0000000..2cb1888
--- /dev/null
+++ b/gui/gtk/gtk_glue_egl.h
@@ -0,0 +1,106 @@
+//
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+//   Foundation, Inc
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include "gtk_glue.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <boost/scoped_array.hpp>
+#include "Renderer_ovg.h"
+
+#ifdef HAVE_VG_OPENVG_H
+#include <VG/openvg.h>
+#endif
+
+#ifdef HAVE_EGL_EGL_H
+# include <EGL/egl.h>
+#else
+# error "This file needs EGL, which is part of OpenGL-ES"
+#endif
+
+namespace gnash
+{
+
+class GtkEGLGlue : public GtkGlue
+{
+  public:
+    GtkEGLGlue();
+    ~GtkEGLGlue();
+
+    // Initialize EGL
+    bool init(int argc, char **argv[]);
+
+    // Prepare the drawing area
+    void prepDrawingArea(GtkWidget *drawing_area);
+
+    // Create the renderer
+    Renderer* createRenderHandler();
+
+    // Set the size of the rendering window
+    void setRenderHandlerSize(int width, int height);
+    void beforeRendering();
+
+    // Render the drawing area to the display
+    void render();
+    void render(int minx, int miny, int maxx, int maxy);
+
+    // Configure EGL
+    void configure(GtkWidget *const widget, GdkEventConfigure *const event);
+
+    // Utility methods not in the base class
+    /// Return a string with the error code as text, instead of a numeric value
+    const char *getErrorString(int error);
+    /// Check the requested EGl configuration against the current one
+    bool checkEGLConfig(EGLConfig config);
+    /// Query the system for all supported configs
+    int queryEGLConfig(EGLDisplay display);
+    void printEGLConfig(EGLConfig config);
+    void printEGLContext(EGLContext context);
+    void printEGLSurface(EGLSurface surface);
+
+  private:
+    // offscreenbuf is only used with ENABLE_EGL_OFFSCREEN
+    GdkImage            *_offscreenbuf;
+    Renderer_ovg_base   *_renderer;
+    
+    EGLConfig           _eglConfig;
+    EGLContext          _eglContext;
+    EGLSurface          _eglSurface;
+    EGLDisplay          _eglDisplay;
+    EGLint              _eglNumOfConfigs;
+    EGLNativeWindowType _nativeWindow;
+    EGLint              _max_num_config;
+    unsigned int        _bpp;
+    unsigned int        _width;
+    unsigned int        _height;
+};
+
+#define DUMP_CURRENT_SURFACE printEGLSurface(eglGetCurrentSurface(EGL_DRAW))
+#define DUMP_CURRENT_CONTEXT printEGLContext(eglGetCurrentContext())
+
+} // namespace gnash
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/librender/Renderer_ovg.cpp b/librender/Renderer_ovg.cpp
new file mode 100644
index 0000000..d592a35
--- /dev/null
+++ b/librender/Renderer_ovg.cpp
@@ -0,0 +1,1483 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software 
Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+///
+/// Author: Visor <address@hidden>
+///
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <sys/time.h>
+#include <cstring>
+#include <cmath>
+#include <boost/utility.hpp>
+#include <boost/bind.hpp>
+
+#include "gnash.h"
+#include "log.h"
+#include "RGBA.h"
+#include "smart_ptr.h"
+#include "GnashImage.h"
+#include "GnashNumeric.h"
+#include "log.h"
+#include "utility.h"
+#include "Range2d.h"
+#include "cxform.h"
+#include "Renderer_ovg.h"
+#include "Renderer_ovg_bitmap.h"
+#include "SWFMatrix.h"
+#include "swf/ShapeRecord.h"
+
+#define GNASH_IMAGE_QUALITY     VG_IMAGE_QUALITY_FASTER
+#define GNASH_RENDER_QUALITY    VG_RENDERING_QUALITY_FASTER
+
+#define  MAX_POINTS (4096)
+
+/// \file Renderer_ovg.cpp
+/// \brief The OpenVG renderer and related code.
+///
+
+namespace gnash {
+
+static int tex_size;
+
+typedef std::vector<Path> PathVec;
+typedef std::vector<geometry::Range2d<int> > ClipBounds;
+
+class eglScopeMatrix : public boost::noncopyable
+{
+public:
+    eglScopeMatrix(const SWFMatrix& m)
+        {
+            vgGetMatrix(orig_mat);
+
+            float mat[9];
+            memset(mat, 0, sizeof(mat));
+            mat[0] = m.sx  / 65536.0f;
+            mat[1] = m.shx / 65536.0f;
+            mat[3] = m.shy / 65536.0f;
+            mat[4] = m.sy  / 65536.0f;
+            mat[6] = m.tx;
+            mat[7] = m.ty;
+            vgMultMatrix(mat);
+        }
+  
+    ~eglScopeMatrix()
+        {
+            vgLoadMatrix(orig_mat);
+        }
+private:
+    VGfloat orig_mat[9];
+};
+
+#define MAX_SEG  (256)
+
+inline void
+startpath(VGPath path, const int x, const int y)
+{
+    VGubyte     gseg[1];
+    VGfloat     gdata[2];
+  
+    gseg[0] = VG_MOVE_TO;
+    gdata[0] = x;
+    gdata[1] = y;
+    vgAppendPathData (path, 1, gseg, gdata);
+}
+
+inline void
+closepath(VGPath path)
+{
+    VGubyte     gseg[1];
+    VGfloat     gdata[2];
+  
+    gseg[0] = VG_CLOSE_PATH;
+    vgAppendPathData (path, 1, gseg, gdata);
+}
+
+inline void
+preparepath(VGPath path, const std::vector<Edge>& edges,
+                        const float& anchor_x, const float& anchor_y)
+{
+    VGubyte     gseg[MAX_SEG];
+    VGfloat     gdata[MAX_SEG*3*2];
+    int         scount = 0;
+    int         dcount = 0; 
+
+    point start(anchor_x, anchor_y);
+    point anchor(anchor_x, anchor_y);
+  
+    for (std::vector<Edge>::const_iterator it = edges.begin(), end = 
edges.end();
+         it != end; ++it) {
+        const Edge& the_edge = *it;
+      
+        point target(the_edge.ap.x, the_edge.ap.y);
+
+        if (the_edge.straight()) {
+            gseg[scount++]  = VG_LINE_TO;
+            gdata[dcount++] = target.x;
+            gdata[dcount++] = target.y;
+        } else {
+            gseg[scount++]  = VG_QUAD_TO;
+            gdata[dcount++] = the_edge.cp.x;
+            gdata[dcount++] = the_edge.cp.y;
+            gdata[dcount++] = target.x;
+            gdata[dcount++] = target.y; 
+        }
+        if (scount >= MAX_SEG-2) {
+            vgAppendPathData(path, scount, gseg, gdata);
+            scount = 0;
+            dcount = 0;
+        }
+        anchor = target;
+    }
+  
+    if (scount > 0)
+        vgAppendPathData (path, scount, gseg, gdata);
+}
+
+// Use the image class copy constructor; it's not important any more
+// what kind of image it is.
+bitmap_info_ovg::bitmap_info_ovg(GnashImage* img, VGImageFormat pixelformat, 
VGPaint paint) 
+    :
+    _img(img),
+    _pixel_format(pixelformat),
+    _paint(paint)
+{
+    _width = _img->width();
+    _height = _img->height();
+  
+    if (_pixel_format == VG_sARGB_8888)
+        _image = vgCreateImage(VG_sARGB_8888, _width, _height, 
GNASH_IMAGE_QUALITY);    
+    
+    vgImageSubData(_image, _img->data(), _width * 4, VG_sARGB_8888,
+                   0, 0, _width, _height);
+    
+    tex_size += _width * _height * 4;
+    log_debug("Add Texture size:%d (%d x %d x %dbpp)", _width * _height * 4, 
_width, _height, 4);
+    log_debug("Current Texture size: %d", tex_size);
+}   
+    
+bitmap_info_ovg::~bitmap_info_ovg()
+{
+    tex_size -= _width * _height * 4;
+    log_debug("Remove Texture size:%d (%d x %d x %dbpp)", _width * _height * 
4, _width, _height, 4);
+    log_debug("Current Texture size: %d", tex_size);
+
+    vgDestroyImage(_image);
+}
+
+void
+bitmap_info_ovg::apply(const gnash::SWFMatrix& bitmap_matrix,
+                       bitmap_wrap_mode wrap_mode) const
+{
+    gnash::SWFMatrix mat;
+    VGfloat     vmat[9];
+    
+    mat = bitmap_matrix;
+
+    vgSetParameteri (_paint, VG_PAINT_TYPE, VG_PAINT_TYPE_PATTERN);
+    vgPaintPattern (_paint, _image);
+    
+    mat.invert();
+    memset(vmat, 0, sizeof(vmat));
+    vmat[0] = mat.sx  / 65536.0f;
+    vmat[1] = mat.shx / 65536.0f;
+    vmat[3] = mat.shy / 65536.0f;
+    vmat[4] = mat.sy  / 65536.0f;
+    vmat[6] = mat.tx;
+    vmat[7] = mat.ty;
+    
+    vgSeti (VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
+    vgLoadMatrix (vmat);
+    vgSeti (VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER);
+    vgLoadMatrix (vmat);
+    vgSeti (VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+
+    if (wrap_mode == WRAP_CLAMP) {  
+        vgSetParameteri (_paint, VG_PAINT_PATTERN_TILING_MODE, VG_TILE_PAD);
+    } else {
+        vgSetParameteri (_paint, VG_PAINT_PATTERN_TILING_MODE, VG_TILE_REPEAT);
+    }
+}
+
+template<typename C, typename T, typename R, typename A>
+void 
+for_each(C& container, R (T::*pmf)(const A&),const A& arg)
+{
+    std::for_each(container.begin(), container.end(),
+                  boost::bind(pmf, _1, boost::ref(arg)));
+}
+
+class Renderer_ovg : public Renderer_ovg_base
+{
+public: 
+    Renderer_ovg()
+        : m_display_width(0.0),
+          m_display_height(0.0),
+          _drawing_mask(false)
+    {
+        set_scale(1.0f, 1.0f);
+        m_fillpaint = vgCreatePaint();
+        m_strokepaint = vgCreatePaint();
+        
+        vgSetPaint (m_fillpaint,   VG_FILL_PATH);
+        vgSetPaint (m_strokepaint, VG_STROKE_PATH);
+    }
+    
+    void init(float x, float y)
+    {
+        GNASH_REPORT_FUNCTION;
+#if 0
+        static const VGubyte sqrCmds[5] = {VG_MOVE_TO_ABS, VG_HLINE_TO_ABS, 
VG_VLINE_TO_ABS, VG_HLINE_TO_ABS, VG_CLOSE_PATH};
+        static const VGfloat sqrCoords[5]   = {50.0f, 50.0f, 250.0f, 250.0f, 
50.0f};
+        path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 
0, 0,
+                            VG_PATH_CAPABILITY_APPEND_TO);
+        vgAppendPathData(path, 5, sqrCmds, sqrCoords);
+        
+        fill = vgCreatePaint();
+        vgSetParameterfv(fill, VG_PAINT_COLOR, 4, color);
+        vgSetPaint(fill, VG_FILL_PATH);
+        
+        vgSetfv(VG_CLEAR_COLOR, 4, white_color);
+        vgSetf(VG_STROKE_LINE_WIDTH, 10);
+        vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_BUTT);
+        vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_ROUND);
+        vgSetf(VG_STROKE_MITER_LIMIT, 4.0f);
+#else
+        m_display_width = x;
+        m_display_height = y;
+        
+        // Turn on alpha blending.
+        vgSeti (VG_BLEND_MODE, VG_BLEND_SRC_OVER);
+        
+        vgSeti(VG_RENDERING_QUALITY, GNASH_RENDER_QUALITY);
+        vgSetf(VG_STROKE_LINE_WIDTH, 20.0f);
+    
+        VGfloat clearColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+        vgSetfv( VG_CLEAR_COLOR, 4, clearColor );
+        
+#ifdef OPENVG_VERSION_1_1    
+        m_mask = vgCreateMaskLayer(x, y);
+#endif
+#endif
+        log_debug("VG Vendor is %s, VG Version is %s, VG Renderer is %s",
+                  vgGetString(VG_VENDOR), vgGetString(VG_VERSION),
+                  vgGetString(VG_RENDERER));
+        log_debug("VG Extensions are: ", vgGetString(VG_EXTENSIONS));
+        printVGParams();
+    }
+  
+    ~Renderer_ovg()
+        {
+            vgDestroyPaint(m_fillpaint);
+            vgDestroyPaint(m_strokepaint);
+#ifdef OPENVG_VERSION_1_1    
+            vgDestroyMaskLayer(m_mask);
+#endif
+        }
+
+    // Given an image, returns a pointer to a bitmap_info class
+    // that can later be passed to fill_styleX_bitmap(), to set a
+    // bitmap fill style.
+    gnash::BitmapInfo* createBitmapInfo(std::auto_ptr<GnashImage> im)
+    {
+        GNASH_REPORT_FUNCTION;
+        
+        // OpenVG don't support 24bit RGB, need translate colorspace
+        switch (im->type()) {
+          case GNASH_IMAGE_RGBA:   
+              return new bitmap_info_ovg(im.get(), VG_sARGB_8888, m_fillpaint);
+          default:
+              std::abort();
+        }
+    }
+
+    // Since we store drawing operations in display lists, we take special care
+    // to store video frame operations in their own display list, lest they be
+    // anti-aliased with the rest of the drawing. Since display lists cannot be
+    // concatenated this means we'll add up with several display lists for 
normal
+    // drawing operations.
+    void drawVideoFrame(GnashImage* /* frame */, const SWFMatrix* /* m */,
+                                const SWFRect* /* bounds */, bool /*smooth*/)
+    {
+        log_unimpl("drawVideoFrame");  
+    }
+  
+    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(rect&)
+        // 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<float>& wb)
+    {
+        if (wb.isNull() || wb.isWorld()) return wb;
+
+        int xmin, ymin, xmax, ymax;
+
+        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);
+    }
+
+    point pixel_to_world(int x, int y)
+    {
+        point p(x, y);
+        SWFMatrix mat = stage_matrix;
+        mat.invert().transform(p);
+        return p;
+    };
+
+    void  begin_display(const rgba& /* bg_color */, int /* viewport_x0 */,
+                        int /* viewport_y0 */, int /* viewport_width */,
+                        int /* viewport_height */, float x0, float x1,
+                        float y0, float y1)
+    {
+        // GNASH_REPORT_FUNCTION;
+        
+        vgSeti (VG_MASKING, VG_FALSE);
+
+        float mat[9];
+        memset(mat, 0, sizeof(mat));
+        mat[0] = (float)m_display_width / float(x1 - x0);  // scale sx
+        mat[1] = 0; // shx
+        mat[3] = 0; // shy
+        mat[4] = -((float)m_display_height / float(y1 - y0)); // scale sy
+        mat[6] = 0;   // shift tx
+        mat[7] = m_display_height;   // shift ty
+
+        vgSeti (VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+        vgLoadMatrix (mat);
+    }
+  
+    void end_display()
+    {
+        // GNASH_REPORT_FUNCTION;
+        
+    }
+  
+    /// Draw a line-strip directly, using a thin, solid line. 
+    //
+    /// Can be used to draw empty boxes and cursors.
+    void drawLine(const std::vector<point>& coords, const rgba& fill,
+                          const SWFMatrix& mat)
+    {
+        VGubyte     gseg[MAX_SEG];
+        VGfloat     gdata[MAX_SEG*3*2];
+        int         scount = 0;
+        int         dcount = 0;
+    
+        if (coords.empty()) return;
+
+        eglScopeMatrix scope_mat(mat);
+
+        VGfloat color[] = {
+            fill.m_r / 255.0f,
+            fill.m_g / 255.0f,
+            fill.m_b / 255.0f,
+            1.0f
+        };
+        VGPath      vg_path;
+        vg_path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
+                                VG_PATH_DATATYPE_F,
+                                1, 0, 0, 0,
+                                VG_PATH_CAPABILITY_ALL);
+        vgSetf (VG_FILL_RULE, VG_EVEN_ODD );
+        vgSetParameteri (m_strokepaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+        vgSetParameterfv (m_strokepaint, VG_PAINT_COLOR, 4, color);
+    
+        std::vector<point>::const_iterator  it = coords.begin();
+        std::vector<point>::const_iterator end = coords.end();
+    
+        gseg[scount++] = VG_MOVE_TO;
+        gdata[dcount++] = (float)(*it).x;
+        gdata[dcount++] = (float)(*it).y;
+        ++it;            
+
+        for (; it != end; ++it) {
+            gseg[scount++] = VG_LINE_TO;
+            gdata[dcount++] = (float)(*it).x;
+            gdata[dcount++] = (float)(*it).y;
+            if (scount >= MAX_SEG-1) {
+                vgAppendPathData(vg_path, scount, gseg, gdata);
+                scount = 0;
+                dcount = 0;
+            }
+        }
+        
+        if (scount > 0) {
+            vgAppendPathData(vg_path, scount, gseg, gdata);
+
+        }
+
+        vgSetf (VG_STROKE_JOIN_STYLE, VG_JOIN_ROUND);
+        vgSetf (VG_STROKE_CAP_STYLE, VG_CAP_ROUND);
+        vgSetf (VG_STROKE_LINE_WIDTH, 20.0f);
+
+        vgDrawPath (vg_path, VG_STROKE_PATH);
+        vgDestroyPath(vg_path);
+    }
+
+    void drawPoly(const point* corners, size_t corner_count, 
+                            const rgba& fill, const rgba& /* outline */,
+                            const SWFMatrix& mat, bool /* masked */)
+    {
+        VGubyte     gseg[MAX_SEG];
+        VGfloat     gdata[MAX_SEG*3*2];
+        int         scount = 0;
+        int         dcount = 0;
+    
+        if (corner_count < 1) {
+            return;
+        }
+
+        unsigned int i;
+    
+        eglScopeMatrix scope_mat(mat);
+    
+        VGfloat color[] = {
+            fill.m_r / 255.0f,
+            fill.m_g / 255.0f,
+            fill.m_b / 255.0f,
+            fill.m_a / 255.0f
+        };
+        VGPath      vg_path;
+        vg_path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
+                                VG_PATH_DATATYPE_F,
+                                1, 0, 0, 0,
+                                VG_PATH_CAPABILITY_ALL);
+        vgSetf (VG_FILL_RULE, VG_NON_ZERO );
+
+        vgSetParameteri (m_fillpaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+        vgSetParameterfv (m_fillpaint, VG_PAINT_COLOR, 4, color);
+
+        const point *ptr = corners;
+        gseg[scount++] = VG_MOVE_TO;
+        gdata[dcount++] = (float)ptr->x;
+        gdata[dcount++] = (float)ptr->y;
+        ptr++;
+
+        for (i = 1; i < corner_count; i++) {
+            gseg[scount++] = VG_LINE_TO;
+            gdata[dcount++] = (float)ptr->x;
+            gdata[dcount++] = (float)ptr->y;
+            ptr++;
+            if (scount >= MAX_SEG-2) {
+                vgAppendPathData(vg_path, scount, gseg, gdata);
+                scount = 0;
+                dcount = 0;
+            }
+        }
+        gseg[scount++] = VG_CLOSE_PATH;
+        vgAppendPathData (vg_path, scount, gseg, gdata);
+
+        vgDrawPath (vg_path, VG_FILL_PATH);
+        vgDestroyPath(vg_path);
+    }
+
+    void set_antialiased(bool /* enable */)
+    {
+        log_unimpl("set_antialiased");
+    }
+    
+    void begin_submit_mask()
+    {
+        PathVec mask;
+        _masks.push_back(mask);
+    
+        _drawing_mask = true;
+    
+    }
+  
+    void end_submit_mask()
+    {
+        _drawing_mask = false;
+    
+        apply_mask();
+    }
+
+    /// Apply the current mask; nesting is supported.
+    ///
+    /// This method marks the stencil buffer by incrementing every stencil 
pixel
+    /// by one every time a solid from one of the current masks is drawn. When
+    /// all the mask solids are drawn, we change the stencil operation to 
permit
+    /// only drawing where all masks have drawn, in other words, where all 
masks
+    /// intersect, or in even other words, where the stencil pixel buffer 
equals
+    /// the number of masks.
+    void apply_mask()
+    {  
+        if (_masks.empty()) {
+            return;
+        }
+
+        float mat[9];
+        float omat[9];
+    
+        vgSeti (VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+        vgGetMatrix (omat);
+    
+        memset(mat, 0, sizeof(mat));
+        mat[0] =  stage_matrix.get_x_scale(); // scale sx
+        mat[1] =  0.0f; // shx
+        mat[3] =  0.0f; // shy
+        mat[4] =  -stage_matrix.get_x_scale(); // scale sy
+        mat[6] =  0;    // shift tx
+        mat[7] =  m_display_height;   // shift ty
+        vgLoadMatrix(mat);
+    
+#ifdef OPENVG_VERSION_1_1    
+        vgMask(m_mask, VG_FILL_MASK, 0, 0, m_display_width, m_display_height); 
FIXME
+#endif
+
+        // Call add_paths for each mask.
+        std::for_each(_masks.begin(), _masks.end(),
+                      boost::bind(&Renderer_ovg::add_paths, this, _1));    
+        vgSeti(VG_MASKING, VG_TRUE);      
+        vgLoadMatrix (omat);
+    }
+  
+    void add_paths(const PathVec& path_vec)
+    {
+        cxform dummy_cx;
+    
+        fill_style coloring;
+        coloring.setSolid(rgba(0,255,0,255));
+            
+        draw_submask(path_vec, SWFMatrix(), dummy_cx, coloring);
+    }
+  
+    void disable_mask()
+    {
+        _masks.pop_back();
+    
+        if (_masks.empty()) {
+            vgSeti (VG_MASKING, VG_FALSE);
+        } else {
+            apply_mask();
+        }
+            
+    }
+
+    Path reverse_path(const Path& cur_path)
+    {
+        const Edge& cur_end = cur_path.m_edges.back();    
+        
+        float prev_cx = cur_end.cp.x;
+        float prev_cy = cur_end.cp.y;        
+                
+        Path newpath(cur_end.ap.x, cur_end.ap.y, cur_path.m_fill1, 
cur_path.m_fill0, cur_path.m_line, cur_path.m_new_shape);
+    
+        float prev_ax = cur_end.ap.x;
+        float prev_ay = cur_end.ap.y; 
+
+        for (std::vector<Edge>::const_reverse_iterator it = 
cur_path.m_edges.rbegin()+1, end = cur_path.m_edges.rend();
+             it != end; ++it) {
+            const Edge& cur_edge = *it;
+
+            if (prev_ax == prev_cx && prev_ay == prev_cy) {
+                prev_cx = cur_edge.ap.x;
+                prev_cy = cur_edge.ap.y;      
+            }
+
+            Edge newedge(prev_cx, prev_cy, cur_edge.ap.x, cur_edge.ap.y); 
+          
+            newpath.m_edges.push_back(newedge);
+          
+            prev_cx = cur_edge.cp.x;
+            prev_cy = cur_edge.cp.y;
+            prev_ax = cur_edge.ap.x;
+            prev_ay = cur_edge.ap.y;
+           
+        }
+        
+        Edge newlastedge(prev_cx, prev_cy, cur_path.ap.x, cur_path.ap.y);    
+        newpath.m_edges.push_back(newlastedge);
+        
+        return newpath;
+    }
+  
+    const Path* find_connecting_path(const Path& to_connect,
+                                     std::list<const Path*> path_refs)
+    {        
+        float target_x = to_connect.m_edges.back().ap.x;
+        float target_y = to_connect.m_edges.back().ap.y;
+
+        if (target_x == to_connect.ap.x &&
+            target_y == to_connect.ap.y) {
+            return NULL;
+        }
+  
+        for (std::list<const Path*>::const_iterator it = path_refs.begin(),
+                 end = path_refs.end(); it != end; ++it) {
+            const Path* cur_path = *it;
+      
+            if (cur_path == &to_connect) {
+      
+                continue;
+      
+            }
+      
+            
+            if (cur_path->ap.x == target_x && cur_path->ap.y == target_y) {
+ 
+                if (cur_path->m_fill1 != to_connect.m_fill1) {
+                    continue;
+                }
+                return cur_path;
+            }
+        }
+  
+  
+        return NULL;  
+    }
+  
+    PathVec normalize_paths(const PathVec &paths)
+    {
+        PathVec normalized;
+  
+        for (PathVec::const_iterator it = paths.begin(), end = paths.end();
+             it != end; ++it) {
+            const Path& cur_path = *it;
+            
+            if (cur_path.m_edges.empty()) {
+                continue;
+                
+            } else if (cur_path.m_fill0 && cur_path.m_fill1) {     
+                
+                // Two fill styles; duplicate and then reverse the left-filled 
one.
+                normalized.push_back(cur_path);
+                normalized.back().m_fill0 = 0; 
+                
+                Path newpath = reverse_path(cur_path);
+                newpath.m_fill0 = 0;        
+                
+                normalized.push_back(newpath);       
+                
+            } else if (cur_path.m_fill0) {
+                // Left fill style.
+                Path newpath = reverse_path(cur_path);
+                newpath.m_fill0 = 0;
+                
+                normalized.push_back(newpath);
+            } else if (cur_path.m_fill1) {
+                // Right fill style.
+                normalized.push_back(cur_path);
+            } else {
+                // No fill styles; copy without modifying.
+                normalized.push_back(cur_path);
+            }
+            
+        }
+        
+        return normalized;
+    }
+    
+  
+    /// Analyzes a set of paths to detect real presence of fills and/or 
outlines
+    /// TODO: This should be something the character tells us and should be 
+    /// cached. 
+    void analyze_paths(const PathVec &paths, bool& have_shape,
+                       bool& have_outline) 
+    {
+        have_shape=false;
+        have_outline=false;
+    
+        int pcount = paths.size();
+    
+        for (int pno=0; pno<pcount; pno++) {
+    
+            const Path &the_path = paths[pno];
+    
+            if ((the_path.m_fill0>0) || (the_path.m_fill1>0)) {
+                have_shape=true;
+                if (have_outline) return; // have both
+            }
+    
+            if (the_path.m_line>0) {
+                have_outline=true;
+                if (have_shape) return; // have both
+            }
+    
+        }    
+    }
+
+    void apply_fill_style(const fill_style& style, const SWFMatrix& /* mat */,
+                          const cxform& cx)
+    {
+        int fill_type = style.get_type();
+      
+        switch (fill_type) {
+
+          case SWF::FILL_LINEAR_GRADIENT:
+          case SWF::FILL_RADIAL_GRADIENT:
+          case SWF::FILL_FOCAL_GRADIENT:
+          {
+              const bitmap_info_ovg* binfo = static_cast<const 
bitmap_info_ovg*>(
+                  style.need_gradient_bitmap(*this));       
+
+              binfo->apply(style.getGradientMatrix(), 
bitmap_info_ovg::WRAP_CLAMP); 
+              vgSetParameteri (m_fillpaint, VG_PAINT_TYPE, 
VG_PAINT_TYPE_PATTERN);
+              break;
+          }        
+          case SWF::FILL_TILED_BITMAP_HARD:
+          case SWF::FILL_TILED_BITMAP:
+          {
+              const bitmap_info_ovg* binfo = static_cast<const 
bitmap_info_ovg*>(
+                  style.get_bitmap_info(*this));
+
+              binfo->apply(style.getBitmapMatrix(), 
bitmap_info_ovg::WRAP_REPEAT);
+              vgSetParameteri (m_fillpaint, VG_PAINT_TYPE, 
VG_PAINT_TYPE_PATTERN);
+              break;
+          }
+                
+          case SWF::FILL_CLIPPED_BITMAP:
+          case SWF::FILL_CLIPPED_BITMAP_HARD:
+          {     
+              const bitmap_info_ovg* binfo = dynamic_cast<const 
bitmap_info_ovg*>(
+                  style.get_bitmap_info(*this));
+          
+              binfo->apply(style.getBitmapMatrix(), 
bitmap_info_ovg::WRAP_CLAMP);
+              vgSetParameteri (m_fillpaint, VG_PAINT_TYPE, 
VG_PAINT_TYPE_PATTERN);
+              break;
+          } 
+
+          case SWF::FILL_SOLID:
+          {
+              rgba c = cx.transform(style.get_color());
+              VGfloat color[] = {
+                  c.m_r / 255.0f,
+                  c.m_g / 255.0f,
+                  c.m_b / 255.0f,
+                  c.m_a / 255.0f
+              };
+
+              vgSetParameteri (m_fillpaint, VG_PAINT_TYPE, 
VG_PAINT_TYPE_COLOR);
+              vgSetParameterfv (m_fillpaint, VG_PAINT_COLOR, 4, color);
+          }
+        
+        } // switch
+    }
+  
+    bool apply_line_style(const LineStyle& style, const cxform& cx, const 
SWFMatrix& mat)
+    {
+    
+        bool rv = true;
+    
+        switch(style.joinStyle()) {
+          case JOIN_ROUND:
+              vgSetf (VG_STROKE_JOIN_STYLE, VG_JOIN_ROUND);
+              break;
+          case JOIN_BEVEL:
+              vgSetf (VG_STROKE_JOIN_STYLE, VG_JOIN_BEVEL);
+              break;
+          case JOIN_MITER:
+              vgSetf (VG_STROKE_JOIN_STYLE, VG_JOIN_MITER);
+              break;
+          default:
+              log_unimpl("join style");
+        }
+
+        switch(style.startCapStyle()) {
+          case CAP_ROUND:
+              vgSetf (VG_STROKE_CAP_STYLE, VG_CAP_ROUND);
+              break;
+          case CAP_NONE:
+              vgSetf (VG_STROKE_CAP_STYLE, VG_CAP_BUTT);
+              break;
+          case CAP_SQUARE:
+              vgSetf (VG_STROKE_CAP_STYLE, VG_CAP_SQUARE);
+              break;
+          default:
+              log_unimpl("cap style");
+        }
+
+        vgSetf (VG_STROKE_MITER_LIMIT, style.miterLimitFactor());
+
+        float width = style.getThickness();
+    
+        if (!width) {
+            vgSetf(VG_STROKE_LINE_WIDTH, 20.0f);
+            rv = false; // Don't draw rounded lines.
+        } else if ( (!style.scaleThicknessVertically()) && 
(!style.scaleThicknessHorizontally()) ) {
+            vgSetf(VG_STROKE_LINE_WIDTH, width);
+        } else {
+            if ( (!style.scaleThicknessVertically()) || 
(!style.scaleThicknessHorizontally()) ) {
+                LOG_ONCE( log_unimpl(_("Unidirectionally scaled strokes in OGL 
renderer")) );
+            }
+            
+            float stroke_scale = fabsf(mat.get_x_scale()) + 
fabsf(mat.get_y_scale());
+            stroke_scale /= 2.0f;
+            stroke_scale *= (stage_matrix.get_x_scale() + 
stage_matrix.get_y_scale()) / 2.0f;
+            width *= stroke_scale;
+            
+            if (width < 20.0f) {
+                width = 20.0f;
+            }
+            
+            vgSetf(VG_STROKE_LINE_WIDTH, width);
+        }
+
+        rgba c = cx.transform(style.get_color());
+        VGfloat color[] = {
+            c.m_r / 255.0f,
+            c.m_g / 255.0f,
+            c.m_b / 255.0f,
+            c.m_a / 255.0f
+        };
+    
+
+        vgSetParameteri (m_strokepaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+        vgSetParameterfv (m_strokepaint, VG_PAINT_COLOR, 4, color);
+
+        return rv;
+    }
+ 
+  
+    typedef std::vector<const Path*> PathPtrVec;
+  
+    void draw_outlines(const PathVec& path_vec, const SWFMatrix& mat,
+                      const cxform& cx, const std::vector<LineStyle>& 
line_styles)
+    {
+        for (PathVec::const_iterator it = path_vec.begin(), end = 
path_vec.end();
+             it != end; ++it) {
+            
+            const Path& cur_path = *it;
+            
+            if (!cur_path.m_line) {
+                continue;
+            }
+            
+            VGPath      vpath;
+            vpath = vgCreatePath (VG_PATH_FORMAT_STANDARD,
+                                  VG_PATH_DATATYPE_F,
+                                  1, 0, 0, 0,
+                                  VG_PATH_CAPABILITY_ALL);
+            vgSetf (VG_FILL_RULE, VG_EVEN_ODD );
+            startpath(vpath, cur_path.ap.x, cur_path.ap.y);
+            preparepath(vpath, cur_path.m_edges, cur_path.ap.x,
+                        cur_path.ap.y);
+            
+            apply_line_style(line_styles[cur_path.m_line-1], cx, mat);
+            vgDrawPath (vpath, VG_STROKE_PATH);
+            vgDestroyPath(vpath);
+        }
+    }
+
+    std::list<PathPtrVec> get_contours(const PathPtrVec &paths)
+    {
+        std::list<const Path*> path_refs;
+        std::list<PathPtrVec> contours;
+    
+        for (PathPtrVec::const_iterator it = paths.begin(), end = paths.end();
+             it != end; ++it) {
+            const Path* cur_path = *it;
+            path_refs.push_back(cur_path);
+        }
+        
+        for (std::list<const Path*>::const_iterator it = path_refs.begin(), 
end = path_refs.end();
+             it != end; ++it) {
+            const Path* cur_path = *it;
+      
+            if (cur_path->m_edges.empty()) {
+                continue;
+            }
+      
+            if (!cur_path->m_fill0 && !cur_path->m_fill1) {
+                continue;
+            }
+      
+            PathPtrVec contour;
+            
+            contour.push_back(cur_path);
+        
+            const Path* connector = find_connecting_path(*cur_path, path_refs);
+
+            while (connector) {       
+                contour.push_back(connector);
+
+                const Path* tmp = connector;
+                connector = find_connecting_path(*connector, std::list<const 
Path*>(boost::next(it), end));
+  
+                // make sure we don't iterate over the connecting path in the 
for loop.
+                path_refs.remove(tmp);
+        
+            } 
+      
+            contours.push_back(contour);   
+        }
+    
+        return contours;
+    }
+  
+    void draw_mask(const PathVec& path_vec)
+    { 
+   
+        for (PathVec::const_iterator it = path_vec.begin(), end = 
path_vec.end();
+             it != end; ++it) {
+            const Path& cur_path = *it;
+      
+            if (cur_path.m_fill0 || cur_path.m_fill1) {
+                _masks.back().push_back(cur_path);
+                _masks.back().back().m_line = 0;    
+            }
+        }  
+
+    }
+  
+    PathPtrVec paths_by_style(const PathVec& path_vec, unsigned int style)
+    {
+        PathPtrVec paths;
+        for (PathVec::const_iterator it = path_vec.begin(), end = 
path_vec.end();
+             it != end; ++it) {
+            const Path& cur_path = *it;
+      
+            if (cur_path.m_fill0 == style) {
+                paths.push_back(&cur_path);
+            }
+      
+            if (cur_path.m_fill1 == style) {
+                paths.push_back(&cur_path);
+            }
+      
+        }
+        return paths;
+    }
+  
+  
+    std::vector<PathVec::const_iterator>
+        find_subshapes(const PathVec& path_vec)
+    {
+        std::vector<PathVec::const_iterator> subshapes;
+    
+        PathVec::const_iterator it = path_vec.begin(),
+            end = path_vec.end();
+                            
+        subshapes.push_back(it);
+        ++it;
+
+        for (;it != end; ++it) {
+            const Path& cur_path = *it;
+    
+            if (cur_path.m_new_shape) {
+                subshapes.push_back(it); 
+            } 
+        }
+
+        if (subshapes.back() != end) {
+            subshapes.push_back(end);
+        }
+    
+        return subshapes;
+    }
+  
+    /// Takes a path and translates it using the given SWFMatrix.
+    void apply_matrix_to_paths(std::vector<Path>& paths, const SWFMatrix& mat)
+    {  
+        std::for_each(paths.begin(), paths.end(),
+                      boost::bind(&Path::transform, _1, boost::ref(mat)));
+    }  
+
+    void draw_subshape(const PathVec& path_vec,
+                      const SWFMatrix& mat,
+                      const cxform& cx,
+                      const std::vector<fill_style>& fill_styles,
+                      const std::vector<LineStyle>& line_styles)
+    {
+        PathVec normalized = normalize_paths(path_vec);
+
+        for (size_t i = 0; i < fill_styles.size(); ++i) {
+            PathPtrVec paths = paths_by_style(normalized, i+1);
+            
+            if (!paths.size()) {
+                continue;
+            }
+            
+            std::list<PathPtrVec> contours = get_contours(paths);
+            
+            apply_fill_style(fill_styles[i], mat, cx);
+            
+            VGPath      vg_path;
+            vg_path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
+                                    VG_PATH_DATATYPE_F,
+                                    1, 0, 0, 0,
+                                    VG_PATH_CAPABILITY_ALL);              
+            vgSetf (VG_FILL_RULE, VG_EVEN_ODD );                               
   
+            
+            for (std::list<PathPtrVec>::const_iterator iter = contours.begin(),
+                     final = contours.end(); iter != final; ++iter) {
+                const PathPtrVec& refs = *iter;
+                
+                startpath(vg_path, (*(refs[0])).ap.x, (*(refs[0])).ap.y);
+                
+                for (PathPtrVec::const_iterator it = refs.begin(), end = 
refs.end();
+                     it != end; ++it) {
+                    const Path& cur_path = *(*it);
+                    if (!cur_path.m_fill0 && !cur_path.m_fill1)
+                        continue;
+                    preparepath(vg_path, cur_path.m_edges, cur_path.ap.x,
+                                cur_path.ap.y);
+                }
+                closepath(vg_path);
+            }
+            vgDrawPath (vg_path, VG_FILL_PATH);
+            vgDestroyPath(vg_path);    
+        }
+        
+        draw_outlines(normalized, mat, cx, line_styles);
+    }
+
+    void draw_submask(const PathVec& path_vec,
+                      const SWFMatrix& /* mat */,
+                      const cxform& /* cx */,
+                      const fill_style& /* f_style */)
+    {
+
+        PathVec normalized = normalize_paths(path_vec);
+
+        PathPtrVec paths = paths_by_style(normalized, 1);
+
+        std::list<PathPtrVec> contours = get_contours(paths);
+
+        VGfloat color[] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+        vgSetParameteri (m_fillpaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+        vgSetParameterfv (m_fillpaint, VG_PAINT_COLOR, 4, color);
+
+            
+        VGPath      vg_path;
+        vg_path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
+                                VG_PATH_DATATYPE_F,
+                                1, 0, 0, 0,
+                                VG_PATH_CAPABILITY_ALL);
+        vgSetf (VG_FILL_RULE, VG_EVEN_ODD );
+
+        for (std::list<PathPtrVec>::const_iterator iter = contours.begin(),
+                 final = contours.end(); iter != final; ++iter) {
+            const PathPtrVec& refs = *iter;
+            startpath(vg_path, (*(refs[0])).ap.x, (*(refs[0])).ap.y);
+            for (PathPtrVec::const_iterator it = refs.begin(), end = 
refs.end();
+                 it != end; ++it) {
+                const Path& cur_path = *(*it);
+                preparepath(vg_path, cur_path.m_edges, cur_path.ap.x,
+                            cur_path.ap.y);
+            }
+            closepath(vg_path);
+        }
+        
+#ifdef OPENVG_VERSION_1_1    
+        vgRenderToMask(vg_path, VG_FILL_PATH, VG_INTERSECT_MASK); FIXME
+#endif
+        vgDestroyPath(vg_path);
+    }
+
+// Drawing procedure:
+// 1. Separate paths by subshape.
+// 2. Separate subshapes by fill style.
+// 3. For every subshape/fill style combo:
+//  a. Separate contours: find closed shapes by connecting ends.
+//  b. Apply fill style.
+//  c. Feed the contours in the tesselator. (Render.)
+//  d. Draw outlines for every path in the subshape with a line style.
+
+    void drawShape(const SWF::ShapeRecord& shape, const cxform& cx,
+                  const SWFMatrix& mat)
+    {
+        const PathVec& path_vec = shape.paths();
+
+        if (!path_vec.size()) {
+            // No paths. Nothing to draw...
+            return;
+        }
+        if (_drawing_mask) {
+            PathVec scaled_path_vec = path_vec;
+            apply_matrix_to_paths(scaled_path_vec, mat);
+            draw_mask(scaled_path_vec); 
+            return;
+        }    
+
+        bool have_shape, have_outline;
+    
+        analyze_paths(path_vec, have_shape, have_outline);
+    
+        if (!have_shape && !have_outline) {
+            return;
+        }    
+    
+        eglScopeMatrix scope_mat(mat);
+
+        std::vector<PathVec::const_iterator> subshapes = 
find_subshapes(path_vec);
+    
+        const std::vector<fill_style>& fill_styles = shape.fillStyles();
+        const std::vector<LineStyle>& line_styles = shape.lineStyles();
+    
+        for (size_t i = 0; i < subshapes.size()-1; ++i) {
+            PathVec subshape_paths;
+      
+            if (subshapes[i] != subshapes[i+1]) {
+                subshape_paths = PathVec(subshapes[i], subshapes[i+1]);
+            } else {
+                subshape_paths.push_back(*subshapes[i]);
+            }
+      
+            draw_subshape(subshape_paths, mat, cx, fill_styles,
+                          line_styles);
+        }
+    }
+
+    void drawGlyph(const SWF::ShapeRecord& rec, const rgba& c,
+                           const SWFMatrix& mat)
+    {
+        if (_drawing_mask) abort();
+
+        if (rec.getBounds().is_null()) {
+            return;
+        }
+    
+        cxform dummy_cx;
+        std::vector<fill_style> glyph_fs;
+    
+        fill_style coloring;
+        coloring.setSolid(c);
+    
+        glyph_fs.push_back(coloring);
+    
+        std::vector<LineStyle> dummy_ls;
+    
+        eglScopeMatrix scope_mat(mat);
+    
+        draw_subshape(rec.paths(), mat, dummy_cx, glyph_fs, dummy_ls);
+
+    }
+
+    virtual void set_scale(float xscale, float yscale) {
+        _xscale = xscale;
+        _yscale = yscale;
+        stage_matrix.set_identity();
+        stage_matrix.set_scale(xscale/20.0f, yscale/20.0f);
+    }
+
+    virtual void set_invalidated_regions(const InvalidatedRanges& /* ranges */)
+    {
+    }
+
+
+  private:
+  
+    float _xscale;
+    float _yscale;
+    float _width; // Width of the movie, in world coordinates.
+    float _height;
+  
+    // Output size.
+    float m_display_width;
+    float m_display_height;
+  
+    std::vector<PathVec> _masks;
+    bool _drawing_mask;
+  
+    gnash::SWFMatrix stage_matrix;  // conversion from TWIPS to pixels
+    
+    VGPaint     m_fillpaint;
+    VGPaint     m_strokepaint;
+
+#ifdef OPENVG_VERSION_1_1    
+    VGMaskLayer m_mask;
+#endif
+}; // class Renderer_ovg
+  
+Renderer_ovg_base *
+create_Renderer_ovg(const char */* pixelformat */)
+{
+    //    Renderer_ovg_base* renderer = new Renderer_ovg();
+    // return renderer;
+}
+
+    // These methods are only for debugging and development
+void
+Renderer_ovg_base::printVGParams()
+{
+    // vgGetVectorSize();
+
+    std::string str;
+    switch(vgGeti(VG_MATRIX_MODE)) {
+      case VG_MATRIX_PATH_USER_TO_SURFACE:
+          str = "VG_MATRIX_PATH_USER_TO_SURFACE";
+          break;
+      case VG_MATRIX_IMAGE_USER_TO_SURFACE:
+          str = "VG_MATRIX_IMAGE_USER_TO_SURFACE";
+          break;
+      case VG_MATRIX_FILL_PAINT_TO_USER:
+          str = "VG_MATRIX_FILL_PAINT_TO_USER";
+          break;
+      case VG_MATRIX_STROKE_PAINT_TO_USER:
+          str = "VG_MATRIX_STROKE_PAINT_TO_USER";
+          break;
+      case VG_MATRIX_MODE_FORCE_SIZE:
+          str = "VG_MATRIX_MODE_FORCE_SIZE";
+          break;
+      default:
+          log_error("unsupported VG_MATRIX_MODE!");
+    }
+    log_debug("VG_MATRIX_MODE is %s", str);
+    str.clear();
+
+    switch(vgGeti(VG_FILL_RULE)) {
+      case VG_EVEN_ODD:
+          str = "VG_EVEN_ODD";
+          break;
+      case VG_NON_ZERO:
+          str = "VG_NON_ZERO";
+          break;
+      default:
+          log_error("unsupported VG_FILL_RULE!");          
+    }
+    log_debug("VG_FILL_RULE is %s", str);
+    str.clear();
+
+    switch(vgGeti(VG_IMAGE_QUALITY)) {
+      case VG_IMAGE_QUALITY_NONANTIALIASED:
+          str = "VG_IMAGE_QUALITY_NONANTIALIASED";
+          break;
+      case VG_IMAGE_QUALITY_FASTER:
+          str = "VG_IMAGE_QUALITY_FASTER";
+          break;
+      case VG_IMAGE_QUALITY_BETTER:
+          str = "VG_IMAGE_QUALITY_BETTER";
+          break;
+      case VG_IMAGE_QUALITY_FORCE_SIZE:
+          str = "VG_IMAGE_QUALITY_FORCE_SIZE";
+          break;
+      default:
+          log_error("unsupported VG_IMAGE_QUALITY!");
+    }
+    log_debug("VG_IMAGE_QUALITY is %s", str);
+    str.clear();
+    
+    switch(vgGeti(VG_RENDERING_QUALITY)) {
+      case VG_RENDERING_QUALITY_NONANTIALIASED:
+          str = "VG_RENDERING_QUALITY_NONANTIALIASED";
+          break;
+      case VG_RENDERING_QUALITY_FASTER:
+          str = "VG_RENDERING_QUALITY_FASTER";
+          break;
+      case VG_RENDERING_QUALITY_BETTER:
+          str = "VG_RENDERING_QUALITY_BETTER";
+          break;
+      case VG_RENDERING_QUALITY_FORCE_SIZE:
+          str = "VG_RENDERING_QUALITY_FORCE_SIZE";
+          break;
+      default:
+          log_error("unsupported VG_RENDERING_QUALITY!");
+    }
+    log_debug("VG_RENDERING_QUALITY is %s", str);
+    str.clear();
+    
+    switch(vgGeti(VG_BLEND_MODE)) {
+      case VG_BLEND_SRC:
+          str = "VG_BLEND_SRC";
+          break;
+      case VG_BLEND_SRC_OVER:
+          str = "VG_BLEND_SRC_OVER";
+          break;
+      case VG_BLEND_DST_OVER:
+          str = "VG_BLEND_DST_OVER";
+          break;
+      case VG_BLEND_SRC_IN:
+          str = "VG_BLEND_SRC_IN";
+          break;
+      case VG_BLEND_DST_IN:
+          str = "VG_BLEND_DST_IN";
+          break;
+      case VG_BLEND_MULTIPLY: 
+          str = "VG_BLEND_MULTIPLY";
+          break;
+      case VG_BLEND_SCREEN:
+          str = "VG_BLEND_SCREEN";
+          break;
+      case VG_BLEND_DARKEN:
+          str = "VG_BLEND_DARKEN";
+          break;
+      case VG_BLEND_LIGHTEN:
+          str = "VG_BLEND_LIGHTEN";
+          break;
+      case VG_BLEND_ADDITIVE:
+          str = "VG_BLEND_ADDITIVE";
+          break;
+      default:
+          log_error("unsupported VG_BLEND_MODE!");
+    }
+    log_debug("VG_BLEND_MODE is %s", str);    
+    str.clear();
+    
+    switch(vgGeti(VG_IMAGE_MODE)) {
+      case VG_DRAW_IMAGE_NORMAL:
+          str = "VG_DRAW_IMAGE_MULTIPLY";
+          break;
+      case VG_DRAW_IMAGE_MULTIPLY:
+          str = "VG_DRAW_IMAGE_MULTIPLY";
+          break;
+      case VG_DRAW_IMAGE_STENCIL:
+          str = "VG_DRAW_IMAGE_STENCIL";
+          break;
+      case VG_IMAGE_MODE_FORCE_SIZE:
+          str = "VG_IMAGE_MODE_FORCE_SIZE";
+          break;
+      default:
+          log_error("unsupported VG_IMAGE_MODE!");
+    }
+    log_debug("VG_IMAGE_MODE is %s", str);
+    str.clear();
+    
+    log_debug("VG_STROKE_LINE_WIDTH is %d", vgGeti(VG_STROKE_LINE_WIDTH));    
+    str.clear();
+    
+    switch(vgGeti(VG_STROKE_CAP_STYLE)) {
+      case VG_CAP_BUTT:
+          str = "VG_CAP_BUTT";
+          break;
+      case VG_CAP_ROUND:
+          str = "VG_CAP_ROUND";
+          break;
+      case VG_CAP_SQUARE:
+          str = "VG_CAP_SQUARE";
+          break;
+      case VG_CAP_STYLE_FORCE_SIZE:
+          str = "VG_CAP_STYLE_FORCE_SIZE";
+          break;
+      default:
+          log_error("unsupported VG_STROKE_CAP_STYLE!");
+    }
+    log_debug("VG_STROKE_CAP_STYLE is %s", str);
+    str.clear();
+    
+    switch(vgGeti(VG_STROKE_JOIN_STYLE)) {
+      case VG_JOIN_MITER:
+          str = "VG_JOIN_MITER";
+          break;
+      case VG_JOIN_ROUND:
+          str = "VG_JOIN_ROUND";
+          break;
+      case VG_JOIN_BEVEL:
+          str = "VG_JOIN_BEVEL";
+          break;
+      case VG_JOIN_STYLE_FORCE_SIZE:
+          str = "VG_JOIN_STYLE_FORCE_SIZE";
+          break;
+      default:
+          log_error("unsupported VG_STROKE_JOIN_STYLE!");
+    }
+    log_debug("VG_STROKE_JOIN_STYLE is %s", str);
+    str.clear();
+    
+    log_debug("VG_STROKE_MITER_LIMIT is %d", vgGeti(VG_STROKE_MITER_LIMIT));
+    log_debug("VG_MASKING is %d", vgGeti(VG_MASKING));
+    log_debug("VG_SCISSORING is %d", vgGeti(VG_SCISSORING));    
+    str.clear();
+    
+    switch(vgGeti(VG_PIXEL_LAYOUT)) {
+      case VG_PIXEL_LAYOUT_UNKNOWN:
+          str = "VG_PIXEL_LAYOUT_UNKNOWN";
+          break;
+      case VG_PIXEL_LAYOUT_RGB_VERTICAL:
+          str = "VG_PIXEL_LAYOUT_RGB_VERTICAL";
+          break;
+      case VG_PIXEL_LAYOUT_BGR_VERTICAL:
+          str = "VG_PIXEL_LAYOUT_BGR_VERTICAL";
+          break;
+      case VG_PIXEL_LAYOUT_RGB_HORIZONTAL:
+          str = "VG_PIXEL_LAYOUT_RGB_HORIZONTAL";
+          break;
+      case VG_PIXEL_LAYOUT_BGR_HORIZONTAL:
+          str = "VG_PIXEL_LAYOUT_BGR_HORIZONTAL";
+          break;
+      case VG_PIXEL_LAYOUT_FORCE_SIZE:
+          str = "VG_PIXEL_LAYOUT_FORCE_SIZE";
+          break;
+      default:
+          log_error("unsupported VG_PIXEL_LAYOUT!");
+    }
+    log_debug("VG_PIXEL_LAYOUT is %s", str);
+    
+    log_debug("VG_STROKE_DASH_PHASE_RESET is %s",
+              (vgGeti(VG_STROKE_DASH_PHASE_RESET) == true) ? "true" : "false");
+    log_debug("VG_FILTER_FORMAT_LINEAR is %s",
+              (vgGeti(VG_FILTER_FORMAT_LINEAR) == true) ? "true" : "false");
+    log_debug("VG_FILTER_FORMAT_PREMULTIPLIED is %s",
+              (vgGeti(VG_FILTER_FORMAT_PREMULTIPLIED) == true) ? "true" : 
"false");
+    str.clear();
+    
+    VGint value = vgGeti(VG_FILTER_CHANNEL_MASK);
+    if (value & VG_RED) {
+        str += " VG_RED";
+    }
+    if (value & VG_GREEN) {
+        str += " VG_GREEN";
+    }
+    if (value & VG_BLUE) {
+        str += " VG_BLUE";
+    }
+    if (value & VG_ALPHA) {
+        str += " VG_ALPHA";
+    }
+    log_debug("VG_FILTER_CHANNEL_MASK is %s", str);
+    
+    log_debug("VG_MAX_IMAGE_WIDTH is %d", vgGeti(VG_MAX_IMAGE_WIDTH));
+    log_debug("VG_MAX_IMAGE_HEIGHT is %d", vgGeti(VG_MAX_IMAGE_HEIGHT));
+    log_debug("VG_MAX_IMAGE_PIXELS is %d", vgGeti(VG_MAX_IMAGE_PIXELS));
+    log_debug("VG_MAX_IMAGE_BYTES is %d", vgGeti(VG_MAX_IMAGE_BYTES));
+}
+
+void
+Renderer_ovg_base::printVGHardware()
+{
+
+}
+
+void
+Renderer_ovg_base::Renderer_ovg_base::printVGPath()
+{
+}
+
+} // namespace gnash
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/librender/Renderer_ovg.h b/librender/Renderer_ovg.h
new file mode 100644
index 0000000..e5ccd54
--- /dev/null
+++ b/librender/Renderer_ovg.h
@@ -0,0 +1,82 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software 
Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+///
+/// Author: Visor <address@hidden>
+///
+
+#ifndef GNASH_RENDER_HANDLER_OVG_H
+#define GNASH_RENDER_HANDLER_OVG_H
+
+#include <EGL/egl.h>
+#include <VG/openvg.h>
+#include <VG/vgu.h>
+#include <VG/vgext.h>
+
+#include "Geometry.h"
+#include "BitmapInfo.h"
+#include "Renderer.h"
+
+namespace gnash {
+
+typedef std::vector<const Path*> PathRefs;
+
+struct eglVertex {
+    eglVertex(float x, float y)
+        : _x(x), _y(y)
+        {
+        }
+  
+    eglVertex(const point& p)
+        : _x(p.x), _y(p.y)
+        {
+        }
+
+    VGfloat _x;
+    VGfloat _y;
+};
+
+typedef std::map<const Path*, VGPath > PathPointMap;
+
+class Renderer_ovg_base : public Renderer
+{
+public:
+
+    Renderer_ovg_base() { }
+
+    // virtual classes should have virtual destructors
+    virtual ~Renderer_ovg_base() {}
+
+    // these methods need to be accessed from outside:
+    virtual void init(float x, float y)=0;
+
+    // These methods are only for debugging and development
+    void printVGParams();
+    void printVGHardware();
+    void printVGPath();
+};
+
+DSOEXPORT Renderer_ovg_base* create_Renderer_ovg(const char *pixelformat);
+
+} // namespace gnash
+
+#endif // __RENDER_HANDLER_OVG_H__
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/librender/Renderer_ovg_bitmap.h b/librender/Renderer_ovg_bitmap.h
new file mode 100644
index 0000000..0a401a5
--- /dev/null
+++ b/librender/Renderer_ovg_bitmap.h
@@ -0,0 +1,70 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software 
Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+///
+/// Author: Visor <address@hidden>
+///
+
+#ifndef GNASH_RENDER_HANDLER_OVG_BITMAP_H
+#define GNASH_RENDER_HANDLER_OVG_BITMAP_H
+
+#include "Geometry.h"
+#include "BitmapInfo.h"
+#include "Renderer.h"
+
+namespace gnash {
+
+/// The class itself uses a template. Currently this is unnecessary and it may
+/// be removed but an older implementation required this method and it may be
+/// necessary again when the last missing parts of the renderer will be
+/// implemented. And when might that be? I don't think I'll wait.
+class bitmap_info_ovg : public BitmapInfo
+{
+public:
+  
+    /// Set line and fill styles for mesh & line_strip rendering.
+    enum bitmap_wrap_mode
+    {
+        WRAP_REPEAT,
+        WRAP_CLAMP
+    };
+    
+    bitmap_info_ovg(GnashImage* img, VGImageFormat pixelformat, VGPaint paint);
+    ~bitmap_info_ovg();
+
+    void apply(const gnash::SWFMatrix& bitmap_matrix,
+               bitmap_wrap_mode wrap_mode) const;
+
+    int _width;
+    int _height;
+
+private:
+    
+    mutable GnashImage *_img;
+    VGImageFormat   _pixel_format;
+    mutable VGImage _image;
+    VGPaint         _paint;
+};
+
+} // namespace gnash
+
+#endif // __RENDER_HANDLER_OVG_BITMAP_H__
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:

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


commit 4a2363c0c92cec0eea20c3c6254c64db27d14fcc
Author: Rob Savoye <address@hidden>
Date:   Sat Jul 24 10:42:43 2010 -0600

    add double buffering and off screen rendering options from branch.

diff --git a/configure.ac b/configure.ac
index ad676f9..908755b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -272,6 +272,52 @@ fi
 SOLDIR=${soldir}
 AC_SUBST(SOLDIR)
 
+AC_ARG_ENABLE(doublebuf,
+  AC_HELP_STRING([--enable-doublebuf], [Enable support for double buffering 
when rendering]),
+  [case "${enableval}" in
+    yes) doublebuf=yes ;;
+    no)  doublebuf=no ;;
+    *)   AC_MSG_ERROR([bad value ${enableval} for enable-doublebuf option]) ;;
+  esac], doublebuf=no
+)
+AM_CONDITIONAL(ENABLE_DBUF, [test x"$doublebuf" = xyes])
+if test x$doublebuf = xyes; then
+    AC_DEFINE(ENABLE_DOUBLE_BUFFERING, [1], [Enable double buffering])
+fi
+
+dnl This enables rendering to an offscreen buffer, instead of directly to 
window
+AC_ARG_ENABLE(offscreen,
+  AC_HELP_STRING([--enable-offscreen], [Enable support for rendering 
offscreen]),
+  [case "${enableval}" in
+    yes) offscreen=yes ;;
+    no)  offscreen=no ;;
+    *)   AC_MSG_ERROR([bad value ${enableval} for enable-offscreen option]) ;;
+  esac], offscreen=yes
+)
+
+dnl We can use Xephyr or fbe to create a fake framebuffer instead of real
+dnl video memory. This lets us test on a desktop machine.
+AC_ARG_WITH(fakefb,
+AC_HELP_STRING([--with-fakefb],
+ [specify a file to be mapped instead of a real framebuffer]),
+ with_fakefb=${withval})
+
+fakefb=
+if test x"${with_fakefb}" = xyes; then
+  dnl This is the default file name fbe uses.
+  fakefb=/tmp/fbe_buffer
+else
+  if test x"${with_fakefb}" != x; then
+    fakefb=${with_fakefb}
+  fi
+fi
+FAKEFB=${fakefb}
+AC_SUBST(FAKEFB)
+
+if test x"${fakefb}" != x; then
+    AC_DEFINE(ENABLE_FAKE_FRAMEBUFFER, [1], [Enable using a file instead of a 
real framebuffer])
+fi
+
 AC_ARG_ENABLE(avm2,
   AC_HELP_STRING([--enable-avm2], [Enable support for AS3]),
   [case "${enableval}" in
@@ -698,13 +744,13 @@ operating system." >&3
 fi
 
 dnl By default, we want to to build all renderers
-build_ovg=no
-build_gles=no
-build_ogl=yes
-build_agg=yes
-build_cairo=yes
-renderer_list="OpenGL AGG Cairo"
-nrender=3
+build_gles=no   dnl OpenGL-ES 1.1 and 2.x
+build_ovg=yes   dnl OpenVG
+build_ogl=yes   dnl OpenGL
+build_agg=yes   dnl AntiGrain
+build_cairo=yes dnl Cairo
+renderer_list="OpenGL OpenVG AGG Cairo"
+nrender=4
 AC_ARG_ENABLE(renderer,
   AC_HELP_STRING([--enable-renderer=], [Enable support for the specified 
renderers (ogl|gles|cairo|agg|all, default=all)]),
   if test -n ${enableval}; then
@@ -757,7 +803,7 @@ AC_ARG_ENABLE(renderer,
         ;;
       ovg|OVG|OpenVG|openvg)
         renderer_list="${renderer_list} OpenVG"
-        build_ogv=yes
+        build_ovg=yes
         nrender=$((nrender+1))
         ;;
       agg|AGG)
@@ -896,6 +942,18 @@ if test x$pixelformat = xall; then
   fi
 fi
 
+dnl For now, always enable offscreeen rendering for AGG, as that's how it
+dnl currently works.
+AC_DEFINE(ENABLE_AGG_OFFSCREEN, [1], [Enable offscreen rendering for AGG])
+dnl OpenVG uses EGL for the device layer, currently we only support
+dnl rendering directly to a window.
+if test x"${build_ovg}" = xyes; then
+   offscreen=no
+fi
+if test x"${build_ovg}" = xyes -a x"${offscreen}" = xyes; then
+  AC_DEFINE(ENABLE_EGL_OFFSCREEN, [1], [Enable offscreen rendering for EGL])
+fi
+
 dnl --------------------------------------------------------
 dnl  Select media handler
 dnl --------------------------------------------------------
@@ -1095,8 +1153,12 @@ AM_CONDITIONAL(ENABLE_SHARED, [test x"${enable_shared}" 
= xyes])
 AM_CONDITIONAL(ENABLE_STATIC, [test x"${enable_shared}" = xno])
 dnl -- AM_CONDITIONAL(STATIC_GUI, test x"${dynamic_gui}" = xno -o 
x"${enable_shared}" = xno)
 
+dnl DejaGnu is only used for testing.
 AC_PATH_PROG(DEJAGNU, runtest)
 
+dnl These conditionals are triggers only when the selected Renderers
+dnl are chosen to be built, and not on whether they are actually
+dnl supported. So if configure fails, make will fail at build time.
 AM_CONDITIONAL(BUILD_OVG_RENDERER, [ test x$build_ovg = xyes ])
 AM_CONDITIONAL(BUILD_GLES_RENDERER, [ test x$build_gles = xyes ])
 AM_CONDITIONAL(BUILD_OGL_RENDERER, [ test x$build_ogl = xyes])
@@ -1277,9 +1339,20 @@ fi
 SECURITY_LIST="$security_list"
 AC_SUBST(SECURITY_LIST)
 
+if test x"${build_agg}" = xyes; then
+  AC_DEFINE([RENDERER_AGG], [1], [Use AntiGrain renderer])
+fi
+
+if test x"${build_ovg}" = xyes; then
+  AC_DEFINE([RENDERER_OPENVG], [1], [Use OpenVG renderer])
+fi
+
+if test x"${build_gles}" = xyes; then
+  AC_DEFINE([RENDERER_GLES], [1], [Use the OpenGL-ES 1.1 renderer])
+fi
 
-if test x$build_agg = xyes; then
-  AC_DEFINE([RENDERER_AGG], [], [Use AntiGrain renderer])
+if test x"${build_gles}" = xyes; then
+  AC_DEFINE([RENDERER_GLES2], [1], [Use the OpenGL-ES 2.x renderer])
 fi
 
 dnl For Haiku, we know the sysroot is in a non-standard place
@@ -2139,9 +2212,12 @@ if test x"${build_gles}" = xyes; then
   GNASH_PATH_GLES
 fi
 
-if test x"${build_ogv}" = xyes; then
+dnl The current version of OpenVG supported by most ARM platforms
+dnl is OpenVG 1.1. Mesa 7.8.x implements only OpenVG 1.0.1, so
+dnl some features like Masks and Fonts are missing on the desktop.
+if test x"${build_ovg}" = xyes; then
   GNASH_PKG_FIND(EGL, [EGL/egl.h], [EGL library], eglGetDisplay)
-  GNASH_PKG_FIND(OpenVG, [vg/openvg.h], [OpenVG library], vgDrawImage)
+  GNASH_PKG_FIND(OpenVG, [VG/openvg.h], [OpenVG library], vgDrawImage)
 fi
 
 if test x"${build_ogl}" = xyes; then
@@ -3829,6 +3905,13 @@ else
   echo "        DocBook document processing disabled (default)"
 fi
 
+if test x"${offscreen}" = xyes; then
+  echo "        Using offscreen rendering"
+fi
+if test x"${doublebuf}" = xyes; then
+  echo "        Using double buffering when rendering"
+fi
+
 if test -s $cwarn; then
   echo ""
   cat $cwarn

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


commit 287c0d6c0db8f902b88a9d612bc96419e6a1ed65
Author: Rob Savoye <address@hidden>
Date:   Sat Jul 24 10:42:03 2010 -0600

    new files from branch, seperate the rendeer from the fb gui. Add OpenVG 
support.

diff --git a/gui/fb/fb.am b/gui/fb/fb.am
index 544a1d3..84216e2 100644
--- a/gui/fb/fb.am
+++ b/gui/fb/fb.am
@@ -20,8 +20,11 @@
 #
 if BUILD_FB_GUI
 bin_PROGRAMS += fb-gnash
-fb_gnash_SOURCES = $(GUI_SRCS) fb/gui_fb.cpp fb/fb.cpp fb/fbsup.h
-fb_gnash_CPPFLAGS = -DGUI_FB -DGUI_CONFIG=\"FB\" \
+fb_gnash_SOURCES = $(GUI_SRCS) \
+       fb/gui_fb.cpp \
+       fb/fb.cpp \
+       fb/fbsup.h
+fb_gnash_CPPFLAGS = -DGUI_FB -DGUI_CONFIG=\"FB\" -DFAKEFB=\"$(FAKEFB)\" \
        $(AM_CPPFLAGS) 
 fb_gnash_LDFLAGS = $(LIBLTDL) -export-dynamic $(AM_LDFLAGS)
 #fb_gnash_DEPENDENCIES = .configline
@@ -29,9 +32,26 @@ fb_gnash_LDADD = \
        $(top_builddir)/librender/libgnashrender.la \
        $(GNASH_LIBS) 
 
+# Build support for AntiGrain.
 if BUILD_AGG_RENDERER
+fb_gnash_SOURCES += fb/fb_glue_agg.cpp fb/fb_glue_agg.h
 fb_gnash_CPPFLAGS += $(AGG_CFLAGS)
 fb_gnash_LDADD += $(AGG_LIBS)
-endif                          # BUILD_AGG_RENDERER
-endif                          # BUILD_FB_GUI
+endif  # BUILD_AGG_RENDERER
+
+# Build support for OpenVG.
+if BUILD_OVG_RENDERER
+fb_gnash_SOURCES += fb/fb_glue_ovg.cpp fb/fb_glue_ovg.h
+fb_gnash_CPPFLAGS += $(OPENVG_CFLAGS) $(EGL_CFLAGS)
+fb_gnash_LDADD += $(OPENVG_LIBS) $(EGL_LIBS)
+endif  # BUILD_OVG_RENDERER
+
+# This supports only OpenGL-ES 1.1 with EGL support.
+if BUILD_GLES_RENDERER
+fb_gnash_SOURCES += fb/fb_glue_gles.cpp fb/fb_glue_gles.h
+fb_gnash_CPPFLAGS += $(GLES_CFLAGS)
+fb_gnash_LDADD += $(GLES__LIBS)
+endif  # BUILD_OVG_RENDERER
+
+endif  # BUILD_FB_GUI
 
diff --git a/gui/fb/fb.cpp b/gui/fb/fb.cpp
index a658ccc..f3315ab 100644
--- a/gui/fb/fb.cpp
+++ b/gui/fb/fb.cpp
@@ -74,29 +74,38 @@
 #include <sys/time.h>
 #include <fcntl.h>
 #include <cerrno>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
 #include <linux/fb.h>
 #include <linux/kd.h>
 #include <linux/vt.h>
-#include "GnashSystemIOHeaders.h"
+#include <boost/shared_ptr.hpp>
+
+#include <boost/cstdint.hpp>
 #include <csignal>
 #include <cstdlib> // getenv
 
+#include "GnashSystemIOHeaders.h"
 #include "gnash.h"
 #include "gui.h"
 #include "fbsup.h"
 #include "log.h"
 #include "movie_root.h"
 #include "RunResources.h"
-
 #include "Renderer.h"
-#include "Renderer_agg.h"
 #include "GnashSleep.h" // for gnashSleep
 
-#include <linux/input.h>    // for /dev/input/event*
+#ifdef RENDERER_AGG
+#include "fb_glue_agg.h"
+#endif
 
-//#define DEBUG_SHOW_FPS  // prints number of frames per second to STDOUT
+#ifdef RENDERER_OPENVG
+#include "fb_glue_ovg.h"
+#endif
+
+#ifdef RENDERER_GLES
+#include "fb_glue_gles.h"
+#endif
+
+#include <linux/input.h>    // for /dev/input/event*
 
 #ifdef DEBUG_SHOW_FPS
 # include <sys/types.h>
@@ -104,1370 +113,1395 @@
 # include <fcntl.h>
 #endif
 
-// workaround until fatal_error() is implemented
-// that is not silent without -v switch
-//
-// The do { } while (0) strangeness here is the only general way to get a
-// compound statement that is lexically equivalent to a single one. Example:
-//   #define foo() { this(); that(); }
-//   if (a) foo();
-//   else bar();
-// would become
-//   if (a) { this(); that() ; } ; else bar()
-// which is a syntax error.
-
-#define fatal_error(args ...) \
-  do { fprintf(stderr, args); putc('\n', stderr); } while(0)
-
-//--
-
+//#define DEBUG_SHOW_FPS  // prints number of frames per second to STDOUT
 
 namespace gnash
 {
 
-
-//---------------
-#ifdef DEBUG_SHOW_FPS
-double fps_timer=0;
-int fps_counter=0;
-void profile() {
-  int fd;
-  double uptime, idletime;
-  char buffer[20];
-  int readcount;
-
-  fd = open("/proc/uptime", O_RDONLY);
-  if (fd<0) return;
-  readcount = read(fd, buffer, sizeof(buffer)-1);
-  buffer[readcount]=0;
-  sscanf(buffer, "%lf %lf", &uptime, &idletime);
-  close(fd);
-  
-  fps_counter++;
-
-  if (fps_counter<2) {
-    fps_timer = uptime;
-    return;    
-  }
-  
-  printf("FPS: %.3f (%.2f)\n", fps_counter/(uptime-fps_timer), 
uptime-fps_timer);
-  
+FBGlue::FBGlue ()
+{
+    GNASH_REPORT_FUNCTION;
+    
+    /* do nothing */
 }
-#endif
-//---------------
-
-int terminate_request=false;  // global scope to avoid GUI access
 
-/// Called on CTRL-C and alike
-void terminate_signal(int /*signo*/) {
-  terminate_request=true;
+FBGlue::~FBGlue ()
+{
+    GNASH_REPORT_FUNCTION;
+    /* do nothing */
 }
 
+#ifdef DEBUG_SHOW_FPS
 
-//---------------
+double fps_timer = 0;
+int fps_counter = 0;
 
-FBGui::FBGui(unsigned long xid, float scale, bool loop, RunResources& r)
-  : Gui(xid, scale, loop, r)
+void
+profile()
 {
-  fd      = -1;
-  fbmem   = NULL;
-  #ifdef DOUBLE_BUFFER
-  buffer  = NULL;
-  #endif
-
-  input_fd=-1;
-  
-  signal(SIGINT, terminate_signal);
-  signal(SIGTERM, terminate_signal);
-}
-
-FBGui::~FBGui()
-{
-  
-  if (fd>0) {
-    enable_terminal();
-    log_debug(_("Closing framebuffer device"));
+    GNASH_REPORT_FUNCTION;
+    
+    int fd;
+    double uptime, idletime;
+    char buffer[20];
+    int readcount;
+    
+    fd = open("/proc/uptime", O_RDONLY);
+    if (fd < 0) {
+        return;
+    }
+    readcount = read(fd, buffer, sizeof(buffer)-1);
+    buffer[readcount]=0;
+    sscanf(buffer, "%lf %lf", &uptime, &idletime);
     close(fd);
-  }
-  
-  close(input_fd);
-
-  #ifdef DOUBLE_BUFFER
-  if (buffer) {
-    log_debug(_("Free'ing offscreen buffer"));
-    free(buffer);
-  }
-  #endif
+    
+    fps_counter++;
+    
+    if (fps_counter<2) {
+       fps_timer = uptime;
+       return;    
+    }
+    
+    log_debug("FPS: %.3f (%.2f)\n", fps_counter/(uptime-fps_timer), 
uptime-fps_timer);
+    
 }
+#endif  // DEBUG_SHOW_FPS
 
+int terminate_request=false;  // global scope to avoid GUI access
 
-bool FBGui::set_grayscale_lut8()
+/// Called on CTRL-C and alike
+void 
+terminate_signal(int /*signo*/)
 {
-  #define TO_16BIT(x) (x | (x<<8))
-
-  struct fb_cmap cmap;
-  int i;
-
-  log_debug(_("LUT8: Setting up colormap"));
-
-  cmap.start=0;
-  cmap.len=256;
-  cmap.red = (__u16*)malloc(CMAP_SIZE);
-  cmap.green = (__u16*)malloc(CMAP_SIZE);
-  cmap.blue = (__u16*)malloc(CMAP_SIZE);
-  cmap.transp = NULL;
-
-  for (i=0; i<256; i++) {
-
-    int r = i;
-    int g = i;
-    int b = i;
-
-    cmap.red[i] = TO_16BIT(r);
-    cmap.green[i] = TO_16BIT(g);
-    cmap.blue[i] = TO_16BIT(b);
-
-  }
-
-  if (ioctl(fd, FBIOPUTCMAP, &cmap)) {
-    log_error(_("LUT8: Error setting colormap: %s"), strerror(errno));
-    return false;
-  }
-
-  return true;
-
-  #undef TO_16BIT
+    terminate_request = true;
 }
 
-
-bool FBGui::init(int /*argc*/, char *** /*argv*/)
+FBGui::FBGui(unsigned long xid, float scale, bool loop, RunResources& r)
+    : Gui(xid, scale, loop, r),
+      _fd(-1),
+      original_vt(0),
+      original_kd(0),
+      own_vt(0),
+      m_stage_width(0),
+      m_stage_height(0),
+      input_fd(-1),
+      keyb_fd(0),
+      mouse_x(0),
+      mouse_y(0),
+      mouse_btn(0),
+      mouse_buf_size(0)
 {
+    GNASH_REPORT_FUNCTION;
 
-  // Initialize mouse (don't abort if no mouse found)
-  if (!init_mouse()) {
-    // just report to the user, keep on going...
-    log_debug(_("You won't have any pointing input device, sorry."));
-  }
-  
-  // Initialize keyboard (still not critical)
-  if (!init_keyboard()) {   
-    log_debug(_("You won't have any keyboard input device, sorry."));
-  }
-
-  // Open the framebuffer device
-  fd = open("/dev/fb0", O_RDWR);
-  if (fd<0) {
-    fatal_error("Could not open framebuffer device: %s", strerror(errno));
-    return false;
-  }
-  
-  // Load framebuffer properties
-  ioctl(fd, FBIOGET_VSCREENINFO, &var_screeninfo);
-  ioctl(fd, FBIOGET_FSCREENINFO, &fix_screeninfo);
-  log_debug(_("Framebuffer device uses %d bytes of memory."),
-    fix_screeninfo.smem_len);
-  log_debug(_("Video mode: %dx%d with %d bits per pixel."),
-    var_screeninfo.xres, var_screeninfo.yres, var_screeninfo.bits_per_pixel);
-
-  // map framebuffer into memory
-  fbmem = (unsigned char *)
-    mmap(0, fix_screeninfo.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-
-#ifdef DOUBLE_BUFFER
-  // allocate offscreen buffer
-  buffer = (unsigned char*)malloc(fix_screeninfo.smem_len);
-  memset(buffer, 0, fix_screeninfo.smem_len);
-#endif  
-
-#ifdef PIXELFORMAT_LUT8
-  // Set grayscale for 8 bit modes
-  if (var_screeninfo.bits_per_pixel==8) {
-    if (!set_grayscale_lut8())
-      return false;
-  }
+    memset(mouse_buf, 0, 256);
+        
+    signal(SIGINT, terminate_signal);
+    signal(SIGTERM, terminate_signal);
+}
+    
+FBGui::~FBGui()
+{
+    GNASH_REPORT_FUNCTION;
+    
+    if (_fd > 0) {
+       enable_terminal();
+       log_debug(_("Closing framebuffer device"));
+       close(_fd);
+    }
+    
+    close(input_fd);
+    
+#ifdef ENABLE_DOUBLE_BUFFERING
+    if (_buffer) {
+       log_debug(_("Free'ing offscreen buffer"));
+       delete[] _buffer;
+    }
 #endif
-
-  // Ok, now initialize AGG
-  return initialize_renderer();
 }
-
-bool FBGui::initialize_renderer() {
-  const int width    = var_screeninfo.xres;
-  const int height   = var_screeninfo.yres;
-  const int bpp = var_screeninfo.bits_per_pixel;
-  const int size = fix_screeninfo.smem_len; 
-
-  // TODO: should recalculate!  
-  unsigned char* mem;
-  Renderer_agg_base* agg_handler;
-  
-  m_stage_width = width;
-  m_stage_height = height;
-  
-  _validbounds.setTo(0, 0, width - 1, height - 1);
     
-  
-#ifdef DOUBLE_BUFFER
-  log_debug(_("Double buffering enabled"));
-  mem = buffer;
+bool
+FBGui::init(int argc, char ***argv)
+{
+    GNASH_REPORT_FUNCTION;
+    
+    // Initialize mouse (don't abort if no mouse found)
+    if (!init_mouse()) {
+       // just report to the user, keep on going...
+       log_debug(_("You won't have any pointing input device, sorry."));
+    }
+    
+    // Initialize keyboard (still not critical)
+    if (!init_keyboard()) {   
+       log_debug(_("You won't have any keyboard input device, sorry."));
+    }
+    
+    // Open the framebuffer device
+#ifdef ENABLE_FAKE_FRAMEBUFFER
+    _fd = open(FAKEFB, O_RDWR);
 #else
-  log_debug(_("Double buffering disabled"));
-  mem = fbmem;
+    _fd = open("/dev/fb0", O_RDWR);
 #endif
-  
-  
-  agg_handler = NULL;
-  
-  // choose apropriate pixel format
-  
-  log_debug(_("red channel: %d / %d"), var_screeninfo.red.offset, 
-    var_screeninfo.red.length);
-  log_debug(_("green channel: %d / %d"), var_screeninfo.green.offset, 
-    var_screeninfo.green.length);
-  log_debug(_("blue channel: %d / %d"), var_screeninfo.blue.offset, 
-    var_screeninfo.blue.length);
-  log_debug(_("Total bits per pixel: %d"), var_screeninfo.bits_per_pixel);
-  
-  const char* pixelformat = agg_detect_pixel_format(
-    var_screeninfo.red.offset, var_screeninfo.red.length,
-    var_screeninfo.green.offset, var_screeninfo.green.length,
-    var_screeninfo.blue.offset, var_screeninfo.blue.length,
-    bpp
-  );
-
-  if (pixelformat) {    
-    agg_handler = create_Renderer_agg(pixelformat);      
-  } else {
-    fatal_error("The pixel format of your framebuffer could not be detected.");
-    return false;
-  }
-
-  assert(agg_handler);
-
-  _renderer.reset(agg_handler);
-
-  _runResources.setRenderer(_renderer);
-  
-  m_rowsize = var_screeninfo.xres_virtual*((bpp+7)/8);
-  
-  agg_handler->init_buffer(mem, size, width, height, m_rowsize);
-  
-  disable_terminal();
+    if (_fd < 0) {
+       log_error("Could not open framebuffer device: %s", strerror(errno));
+       return false;
+    }
 
-  return true;
-}
+#ifdef RENDERER_AGG
+    fb_glue = new FBAggGlue(_fd);
+#endif
+// #ifdef RENDERER_OPENVG
+//     fb_glue = 0; // new FBOvgGlue(_fd);
+// #endif
+// #ifdef RENDERER_GLES
+//     fb_glue = new FBglesGlue(_fd);
+// #endif
+
+    if (fb_glue == 0) {
+        log_error("No renderer created!");
+        return false;
+    } else if (!fb_glue->init(argc, argv)) {
+        return false;
+    }
 
-bool FBGui::run()
-{
-  struct timeval tv;
+    m_stage_width = fb_glue->width();
+    m_stage_height = fb_glue->height();
+    _validbounds.setTo(0, 0, m_stage_width-1, m_stage_height-1);
 
-  double start_timer;
-  
-  if (!gettimeofday(&tv, NULL))
-    start_timer = static_cast<double>(tv.tv_sec) +
-    static_cast<double>(tv.tv_usec) / 1000000.0;
-  else
-    start_timer = 0.0;
+    _renderer.reset(fb_glue->createRenderHandler());
+    _runResources.setRenderer(_renderer);
     
-  
-  // let the GUI recompute the x/y scale factors to best fit the whole screen
-  resize_view(_validbounds.width(), _validbounds.height());
+    disable_terminal();
 
-  while (!terminate_request) {
-  
-    // wait the "heartbeat" inteval
-    gnashSleep(_interval * 1000);    
-    // TODO: Do we need to check the real time slept or is it OK when we woke
-    // up early because of some Linux signal sent to our process (and thus
-    // "advance" faster than the "heartbeat" interval)? - Udo
-  
-    // check input devices
-    check_mouse();
-    check_keyboard();
-  
-    // advance movie  
-    Gui::advance_movie(this);
-    
-  }
-  
-  return true;
+    return true;
 }
-
-void FBGui::renderBuffer()
+    
+bool
+FBGui::run()
 {
-  if ( _drawbounds.size() == 0 ) return; // nothing to do..
-
-#ifdef DOUBLE_BUFFER
-
-  // Size of a pixel in bytes
-  // NOTE: +7 to support 15 bpp
-  const unsigned int pixel_size = (var_screeninfo.bits_per_pixel+7)/8;
+    GNASH_REPORT_FUNCTION;
 
+    struct timeval tv;
+    double start_timer;
     
-  for (unsigned int bno=0; bno < _drawbounds.size(); bno++) {
-  
-    geometry::Range2d<int>& bounds = _drawbounds[bno];
+    if (!gettimeofday(&tv, NULL))
+       start_timer = static_cast<double>(tv.tv_sec) +
+           static_cast<double>(tv.tv_usec) / 1000000.0;
+    else
+       start_timer = 0.0;
     
-    assert ( ! bounds.isWorld() );  
     
-    // Size, in bytes, of a row that has to be copied
-    const unsigned int row_size = (bounds.width()+1) * pixel_size;
-      
-    // copy each row
-    const int minx = bounds.getMinX();
-    const int maxy = bounds.getMaxY();
-    
-    for (int y=bounds.getMinY(); y<=maxy; ++y) {
+    // let the GUI recompute the x/y scale factors to best fit the whole screen
+    resize_view(_validbounds.width(), _validbounds.height());
     
-      const unsigned int pixel_index = y * m_rowsize + minx*pixel_size;
-      
-      memcpy(&fbmem[pixel_index], &buffer[pixel_index], row_size);
-      
+    while (!terminate_request) {
+       
+       // wait the "heartbeat" inteval
+       gnashSleep(_interval * 1000);    
+       // TODO: Do we need to check the real time slept or is it OK when we 
woke
+       // up early because of some Linux signal sent to our process (and thus
+       // "advance" faster than the "heartbeat" interval)? - Udo
+       
+       // check input devices
+       check_mouse();
+       check_keyboard();
+       
+       // advance movie  
+       Gui::advance_movie(this);
+       
     }
-  }  
-       
-#endif
-  
-#ifdef DEBUG_SHOW_FPS
-  profile();
-#endif
+    
+    return true;
 }
 
-bool FBGui::createWindow(const char* /*title*/, int /*width*/, int /*height*/,
-                     int /*xPosition*/, int /*yPosition*/)
+void FBGui::renderBuffer()
 {
-  // Framebuffer has no windows... :-)
-
-  return true;
+    fb_glue->render();
 }
 
-bool FBGui::createMenu()
+bool
+FBGui::createWindow(const char* /*title*/, int /*width*/, int /*height*/,
+                    int /*xPosition*/, int /*yPosition*/)
 {
-  // no menu support! 
-  return true;
+    // Framebuffer has no windows... :-)
+    
+    return true;
 }
 
-bool FBGui::setupEvents()
+bool
+FBGui::createMenu()
 {
-  // events currently not supported!
-  return true;
+    // no menu support! 
+    return true;
 }
 
-void FBGui::setInterval(unsigned int interval)
+bool
+FBGui::setupEvents()
 {
-  _interval = interval;
+    // events currently not supported!
+    return true;
 }
 
-void FBGui::setTimeout(unsigned int /*timeout*/)
+void
+FBGui::setInterval(unsigned int interval)
 {
+    _interval = interval;
+}
 
+void
+FBGui::setTimeout(unsigned int /*timeout*/)
+{
+    
 }
 
-void FBGui::setFullscreen()
+void
+FBGui::setFullscreen()
 {
-  // FB GUI always runs fullscreen; ignore...
+    // FB GUI always runs fullscreen; ignore...
 }
 
-void FBGui::unsetFullscreen()
+void
+FBGui::unsetFullscreen()
 {
-  // FB GUI always runs fullscreen; ignore...
+    // FB GUI always runs fullscreen; ignore...
 }
 
-void FBGui::showMenu(bool /*show*/)
+void
+FBGui::showMenu(bool /*show*/)
 {
-  log_unimpl(_("This GUI does not yet support menus"));
+    log_unimpl(_("This GUI does not yet support menus"));
 }
 
-bool FBGui::showMouse(bool /*show*/)
+bool
+FBGui::showMouse(bool /*show*/)
 {
-  log_unimpl(_("This GUI does not yet support a mouse pointer"));
-  // Should return true if the pointer was visible before call,
-  // otherwise false;
-  return true;
+    log_unimpl(_("This GUI does not yet support a mouse pointer"));
+    // Should return true if the pointer was visible before call,
+    // otherwise false;
+    return true;
 }
 
 
-int FBGui::valid_x(int x) {
-  if (x<0) x=0;
-  if (x>=m_stage_width) x=m_stage_width-1;
-  return x;
+int
+FBGui::valid_x(int x)
+{
+    if (x < 0) {
+        x = 0;
+    }
+    if (x >= m_stage_width) {
+        x = m_stage_width - 1;
+    }
+    return x;
 }
 
-int FBGui::valid_y(int y) {
-  if (y<0) y=0;
-  if (y>=m_stage_height) y=m_stage_height-1;
-  return y;
+int
+FBGui::valid_y(int y)
+{
+    if (y < 0) {
+        y = 0;
+    }
+    if (y >= m_stage_height) {
+        y = m_stage_height - 1;
+    }
+    return y;
 }
 
-void FBGui::setInvalidatedRegions(const InvalidatedRanges& ranges)
+void
+FBGui::setInvalidatedRegions(const InvalidatedRanges& ranges)
 {
-  _renderer->set_invalidated_regions(ranges);
+    // GNASH_REPORT_FUNCTION;
 
-  _drawbounds.clear();
+    // We can't proceed without a renderer
+    assert(_renderer);
     
-  for (unsigned int rno=0; rno<ranges.size(); rno++) {
-  
-    geometry::Range2d<int> bounds = Intersection(
-      _renderer->world_to_pixel(ranges.getRange(rno)),
-      _validbounds);
-      
-    // it may happen that a particular range is out of the screen, which 
-    // will lead to bounds==null. 
-    if (bounds.isNull()) continue; 
+    _renderer->set_invalidated_regions(ranges);
+    _drawbounds.clear();
+    
+    for (size_t rno=0; rno<ranges.size(); rno++) {        
+        geometry::Range2d<int> bounds = Intersection(
+            _renderer->world_to_pixel(ranges.getRange(rno)),
+            _validbounds);
+        
+        // it may happen that a particular range is out of the screen, which 
+        // will lead to bounds == null. 
+        if (bounds.isNull()) continue; 
+        
+        _drawbounds.push_back(bounds);
+        
+    }
     
-    _drawbounds.push_back(bounds);
-      
-  }
-  
 }
 
-char* FBGui::find_accessible_tty(int no) {
-
-  char* fn;
-  
-  fn = find_accessible_tty("/dev/vc/%d", no);   if (fn) return fn;
-  fn = find_accessible_tty("/dev/tty%d", no);   if (fn) return fn;
-  fn = find_accessible_tty("/dev/tty%02x", no); if (fn) return fn;
-  fn = find_accessible_tty("/dev/tty%x", no);   if (fn) return fn;
-  fn = find_accessible_tty("/dev/tty%02d", no); if (fn) return fn;
-  
-  if (no==0) {
-    fn = find_accessible_tty("/dev/tty", no);  // just "/dev/tty" 
-    if (fn) return fn;
-  }
+char *
+FBGui::find_accessible_tty(int no)
+{
+    GNASH_REPORT_FUNCTION;
     
-  return NULL;
-
+    char* fn;
+    
+    fn = find_accessible_tty("/dev/vc/%d", no);   if (fn) return fn;
+    fn = find_accessible_tty("/dev/tty%d", no);   if (fn) return fn;
+    fn = find_accessible_tty("/dev/tty%02x", no); if (fn) return fn;
+    fn = find_accessible_tty("/dev/tty%x", no);   if (fn) return fn;
+    fn = find_accessible_tty("/dev/tty%02d", no); if (fn) return fn;
+    
+    if (no == 0) {
+        fn = find_accessible_tty("/dev/tty", no);  // just "/dev/tty" 
+        if (fn) return fn;
+    }
+    
+    return 0;    
 }
 
-char* FBGui::find_accessible_tty(const char* format, int no) {
-
-  static char fname[1024];
-  
-  snprintf(fname, sizeof fname, format, no);
+char *
+FBGui::find_accessible_tty(const char* format, int no)
+{
+    // GNASH_REPORT_FUNCTION;
     
-  if (access(fname, R_OK|W_OK) != -1) {
-    return fname;
-  }
-
-  return NULL; 
+    static char fname[1024];
+    
+    snprintf(fname, sizeof fname, format, no);
+    
+    if (access(fname, R_OK|W_OK) != -1) {
+        return fname;
+    }
+    
+    return 0; 
 }
 
-bool FBGui::disable_terminal() 
+bool
+FBGui::disable_terminal() 
 {
-  original_kd = -1;
-  
-  struct vt_stat vts;
-  
-  // Find the TTY device name
-  
-  char* tty = find_accessible_tty(0);
-  
-  int fd;
-  
-  if (!tty) {
-    log_debug(_("WARNING: Could not detect controlling TTY"));
-    return false;
-  }
-  
-  
-  // Detect the currently active virtual terminal (so we can switch back to
-  // it later)
-  
-  fd = open(tty, O_RDWR);
-  if (fd<0) {
-    log_debug(_("WARNING: Could not open %s"), tty);
-    return false;
-  }
-  
-  if (ioctl(fd, VT_GETSTATE, &vts) == -1) {
-    log_debug(_("WARNING: Could not get current VT state"));
-    close(fd);
-    return false;
-  }
+    GNASH_REPORT_FUNCTION;
+
+    original_kd = -1;
+    
+    struct vt_stat vts;
+    
+    // Find the TTY device name
+    
+    char* tty = find_accessible_tty(0);
+    
+    int fd;
+    
+    if (!tty) {
+        log_debug(_("WARNING: Could not detect controlling TTY"));
+           return false;
+    }
+    
+    
+    // Detect the currently active virtual terminal (so we can switch back to
+    // it later)
+    
+    fd = open(tty, O_RDWR);
+    if (fd<0) {
+        log_debug(_("WARNING: Could not open %s"), tty);
+        return false;
+    }
+    
+    if (ioctl(fd, VT_GETSTATE, &vts) == -1) {
+        log_debug(_("WARNING: Could not get current VT state"));
+        close(fd);
+        return false;
+    }
+    
+    original_vt = vts.v_active;
+    log_debug(_("Original TTY NO = %d"), original_vt);   
     
-  original_vt = vts.v_active;
-  log_debug(_("Original TTY NO = %d"), original_vt);   
-  
 #ifdef REQUEST_NEW_VT
-
-  // Request a new VT number
-  if (ioctl(fd, VT_OPENQRY, &own_vt) == -1) {
-    log_debug(_("WARNING: Could not request a new VT"));
-    close(fd);
-    return false;
-  }
-  
-  log_debug(_("Own TTY NO = %d"), own_vt);
-  
-  close(fd);
-  
-  // Activate our new VT
-  tty = find_accessible_tty(own_vt);
-  if (!tty) {
-    log_debug(_("WARNING: Could not find device for VT number %d"), own_vt);
-    return false;
-  }
-  
-  fd = open(tty, O_RDWR);
-  if (fd<0) {
-    log_debug(_("WARNING: Could not open %s"), tty);
-    return false;
-  }
-  
-  if (ioctl(fd, VT_ACTIVATE, own_vt) == -1) {
-    log_debug(_("WARNING: Could not activate VT number %d"), own_vt);
+    
+    // Request a new VT number
+    if (ioctl(fd, VT_OPENQRY, &own_vt) == -1) {
+           log_debug(_("WARNING: Could not request a new VT"));
+           close(fd);
+           return false;
+    }
+    
+    log_debug(_("Own TTY NO = %d"), own_vt);
+    
     close(fd);
-    return false;
-  }
+    
+    // Activate our new VT
+    tty = find_accessible_tty(own_vt);
+    if (!tty) {
+        log_debug(_("WARNING: Could not find device for VT number %d"), 
own_vt);
+        return false;
+    }
+    
+    fd = open(tty, O_RDWR);
+    if (fd<0) {
+        log_debug(_("WARNING: Could not open %s"), tty);
+           return false;
+    }
   
-  if (ioctl(fd, VT_WAITACTIVE, own_vt) == -1) {
-    log_debug(_("WARNING: Error waiting for VT %d becoming active"), own_vt);
-    //close(tty);
-    //return false;   don't abort
-  }
+    if (ioctl(fd, VT_ACTIVATE, own_vt) == -1) {
+        log_debug(_("WARNING: Could not activate VT number %d"), own_vt);
+        close(fd);
+        return false;
+    }
+    
+    if (ioctl(fd, VT_WAITACTIVE, own_vt) == -1) {
+        log_debug(_("WARNING: Error waiting for VT %d becoming active"), 
own_vt);
+        //close(tty);
+        //return false;   don't abort
+    }
 
 #else
-
-  own_vt = original_vt;   // keep on using the original VT
-  
-  close(fd);
-  
-  // Activate our new VT
-  tty = find_accessible_tty(own_vt);
-  if (!tty) {
-    log_debug(_("WARNING: Could not find device for VT number %d"), own_vt);
-    return false;
-  }
-  
-  fd = open(tty, O_RDWR);
-  if (fd<0) {
-    log_debug(_("WARNING: Could not open %s"), tty);
-    return false;
-  }
-  
-  /*
-  // Become session leader and attach to terminal
-  setsid();
-  if (ioctl(fd, TIOCSCTTY, 0) == -1) {
+    
+    own_vt = original_vt;   // keep on using the original VT
+    
+    close(fd);
+    
+    // Activate our new VT
+    tty = find_accessible_tty(own_vt);
+    if (!tty) {
+        log_debug(_("WARNING: Could not find device for VT number %d"), 
own_vt);
+        return false;
+    }
+    
+    fd = open(tty, O_RDWR);
+    if (fd<0) {
+        log_debug(_("WARNING: Could not open %s"), tty);
+        return false;
+    }
+    
+    /*
+    // Become session leader and attach to terminal
+    setsid();
+    if (ioctl(fd, TIOCSCTTY, 0) == -1) {
     log_debug(_("WARNING: Could not attach controlling terminal (%s)"), tty);
-  }
-  */
-  
-
+    }
+    */
+    
+    
 #endif  
-  
-  // Disable keyboard cursor
-  
-  if (ioctl(fd, KDGETMODE, &original_kd) == -1) {
-    log_debug(_("WARNING: Could not query current keyboard mode on VT"));
-  }
-
-  if (ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1) {
-    log_debug(_("WARNING: Could not switch to graphics mode on new VT"));
-  }
-   
-  close(fd);
-  
-  log_debug(_("VT %d ready"), own_vt);
-  
-  
-  // NOTE: We could also implement virtual console switching by using 
-  // VT_GETMODE / VT_SETMODE ioctl calls and handling their signals, but
-  // probably nobody will ever want to switch consoles, so I don't bother... 
-  
-  return true;
+    
+       // Disable keyboard cursor
+    
+    if (ioctl(fd, KDGETMODE, &original_kd) == -1) {
+        log_debug(_("WARNING: Could not query current keyboard mode on VT"));
+    }
+    
+    if (ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1) {
+        log_debug(_("WARNING: Could not switch to graphics mode on new VT"));
+    }
+    
+    close(fd);
+    
+    log_debug(_("VT %d ready"), own_vt);
+    
+    
+    // NOTE: We could also implement virtual console switching by using 
+    // VT_GETMODE / VT_SETMODE ioctl calls and handling their signals, but
+    // probably nobody will ever want to switch consoles, so I don't bother... 
+    
+    return true;
 }
 
-bool FBGui::enable_terminal() 
+bool
+FBGui::enable_terminal() 
 {
+    GNASH_REPORT_FUNCTION;
 
-  log_debug(_("Restoring terminal..."));
-
-  char* tty = find_accessible_tty(own_vt);
-  if (!tty) {
-    log_debug(_("WARNING: Could not find device for VT number %d"), own_vt);
-    return false;
-  }
+    log_debug(_("Restoring terminal..."));
+    
+       char* tty = find_accessible_tty(own_vt);
+       if (!tty) {
+           log_debug(_("WARNING: Could not find device for VT number %d"), 
own_vt);
+           return false;
+       }
 
-  int fd = open(tty, O_RDWR);
-  if (fd<0) {
-    log_debug(_("WARNING: Could not open %s"), tty);
-    return false;
-  }
+       int fd = open(tty, O_RDWR);
+       if (fd<0) {
+           log_debug(_("WARNING: Could not open %s"), tty);
+           return false;
+       }
 
-  if (ioctl(fd, VT_ACTIVATE, original_vt)) {
-    log_debug(_("WARNING: Could not activate VT number %d"), original_vt);
-    close(fd);
-    return false;
-  }
+       if (ioctl(fd, VT_ACTIVATE, original_vt)) {
+           log_debug(_("WARNING: Could not activate VT number %d"), 
original_vt);
+           close(fd);
+           return false;
+       }
 
-  if (ioctl(fd, VT_WAITACTIVE, original_vt)) {
-    log_debug(_("WARNING: Error waiting for VT %d becoming active"), 
original_vt);
-    //close(tty);
-    //return false;   don't abort
-  }
+       if (ioctl(fd, VT_WAITACTIVE, original_vt)) {
+           log_debug(_("WARNING: Error waiting for VT %d becoming active"), 
original_vt);
+           //close(tty);
+           //return false;   don't abort
+       }
 
   
   
-  // Restore keyboard
+       // Restore keyboard
   
-  if (ioctl(fd, KDSETMODE, original_kd)) {
-    log_debug(_("WARNING: Could not restore keyboard mode"));
-  }  
+       if (ioctl(fd, KDSETMODE, original_kd)) {
+           log_debug(_("WARNING: Could not restore keyboard mode"));
+       }  
   
-  close(fd);
+       close(fd);
   
-  return true;
-}
+       return true;
+    }
 
-void FBGui::read_mouse_data()
-{
-  if (input_fd<0) return;   // no mouse available
+    void FBGui::read_mouse_data()
+    {
+       if (input_fd<0) return;   // no mouse available
   
-  int count;  
+       int count;  
   
-  unsigned char *ptr;
+       unsigned char *ptr;
   
-  ptr = mouse_buf + mouse_buf_size;
+       ptr = mouse_buf + mouse_buf_size;
   
-  count = read(input_fd, mouse_buf + mouse_buf_size, 
-    sizeof(mouse_buf) - mouse_buf_size);
+       count = read(input_fd, mouse_buf + mouse_buf_size, 
+                    sizeof(mouse_buf) - mouse_buf_size);
     
-  if (count<=0) return;
+       if (count<=0) return;
   
-  /*
-  printf("read data: ");
-  int i;
-  for (i=0; i<count; i++) 
-    printf("%02x ", ptr[i]);
-  printf("\n");
-  */
+       /*
+         printf("read data: ");
+         int i;
+         for (i=0; i<count; i++) 
+         printf("%02x ", ptr[i]);
+         printf("\n");
+       */
   
-  mouse_buf_size += count;
+       mouse_buf_size += count;
   
-}
+    }
 
 #ifdef USE_MOUSE_PS2    
-bool FBGui::mouse_command(unsigned char cmd, unsigned char *buf, int count) {
-  int n;
-  
-  // flush input buffer
-  char trash[16];
-  do {
-    n = read(input_fd, trash, sizeof trash);
-    if (n>0) 
-      log_debug(_("mouse_command: discarded %d bytes from input buffer"), n);
-  } while (n>0);
-  
-  // send command
-  write(input_fd, &cmd, 1);
-  
-  // read response (if any)
-  while (count>0) {
-    gnashSleep(250*1000); // 250 ms inter-char timeout (simple method)
-    // TODO: use select() instead
-    
-    n = read(input_fd, buf, count);
-    if (n<=0) return false;
-    count-=n;
-    buf+=n;
-  }
-  
-  return true;
-  
-} //command()
+    bool FBGui::mouse_command(unsigned char cmd, unsigned char *buf, int 
count) {
+       int n;
+  
+       // flush input buffer
+       char trash[16];
+       do {
+           n = read(input_fd, trash, sizeof trash);
+           if (n>0) 
+               log_debug(_("mouse_command: discarded %d bytes from input 
buffer"), n);
+       } while (n>0);
+  
+       // send command
+       write(input_fd, &cmd, 1);
+  
+       // read response (if any)
+       while (count>0) {
+           gnashSleep(250*1000); // 250 ms inter-char timeout (simple method)
+           // TODO: use select() instead
+    
+           n = read(input_fd, buf, count);
+           if (n<=0) return false;
+           count-=n;
+           buf+=n;
+       }
+  
+       return true;
+  
+    } //command()
 #endif
 
 #ifdef USE_MOUSE_PS2    
-bool FBGui::init_mouse() 
+bool
+FBGui::init_mouse() 
 {
 
-  // see http://www.computer-engineering.org/ps2mouse/
+       // see http://www.computer-engineering.org/ps2mouse/
   
 
-  // Try to open mouse device, be error tolerant (FD is kept open all the time)
-  input_fd = open(MOUSE_DEVICE, O_RDWR);
+       // Try to open mouse device, be error tolerant (FD is kept open all the 
time)
+       input_fd = open(MOUSE_DEVICE, O_RDWR);
   
-  if (input_fd<0) {
-    log_debug(_("Could not open " MOUSE_DEVICE ": %s"), strerror(errno));    
-    return false;
-  }
+       if (input_fd<0) {
+           log_debug(_("Could not open " MOUSE_DEVICE ": %s"), 
strerror(errno));    
+           return false;
+       }
   
-  unsigned char buf[10], byte;
+       unsigned char buf[10], byte;
 
-  if (fcntl(input_fd, F_SETFL, fcntl(input_fd, F_GETFL) | O_NONBLOCK)<0) {
-    log_error("Could not set non-blocking mode for mouse device: %s", 
strerror(errno));
-    close(input_fd);
-    input_fd=-1;
-    return false; 
-  }
+       if (fcntl(input_fd, F_SETFL, fcntl(input_fd, F_GETFL) | O_NONBLOCK)<0) {
+           log_error("Could not set non-blocking mode for mouse device: %s", 
strerror(errno));
+           close(input_fd);
+           input_fd=-1;
+           return false; 
+       }
   
-  // Clear input buffer
-  while ( read(input_fd, buf, sizeof buf) > 0 ) { }
+       // Clear input buffer
+       while ( read(input_fd, buf, sizeof buf) > 0 ) { }
   
-  // Reset mouse
-  if ((!mouse_command(0xFF, buf, 3)) || (buf[0]!=0xFA)) {
-    log_debug(_("Mouse reset failed"));
-    close(input_fd);
-    input_fd=-1;
-    return false; 
-  }
-  
-  // Get Device ID (not crucial, debug only)
-  if ((!mouse_command(0xF2, buf, 2)) || (buf[0]!=0xFA)) {
-    log_debug(_("WARNING: Could not detect mouse device ID"));
-  } else {
-    unsigned char devid = buf[1];
-    if (devid!=0)
-      log_debug(_("WARNING: Non-standard mouse device ID %d"), devid);
-  }
-  
-  // Enable mouse data reporting
-  if ((!mouse_command(0xF4, &byte, 1)) || (byte!=0xFA)) {
-    log_debug(_("Could not activate Data Reporting mode for mouse"));
-    close(input_fd);
-    input_fd=-1;
-    return false; 
-  }
+       // Reset mouse
+       if ((!mouse_command(0xFF, buf, 3)) || (buf[0]!=0xFA)) {
+           log_debug(_("Mouse reset failed"));
+           close(input_fd);
+           input_fd=-1;
+           return false; 
+       }
+  
+       // Get Device ID (not crucial, debug only)
+       if ((!mouse_command(0xF2, buf, 2)) || (buf[0]!=0xFA)) {
+           log_debug(_("WARNING: Could not detect mouse device ID"));
+       } else {
+           unsigned char devid = buf[1];
+           if (devid!=0)
+               log_debug(_("WARNING: Non-standard mouse device ID %d"), devid);
+       }
   
+       // Enable mouse data reporting
+       if ((!mouse_command(0xF4, &byte, 1)) || (byte!=0xFA)) {
+           log_debug(_("Could not activate Data Reporting mode for mouse"));
+           close(input_fd);
+           input_fd=-1;
+           return false; 
+       }
   
-  log_debug(_("Mouse enabled."));
+  
+       log_debug(_("Mouse enabled."));
       
-  mouse_x = 0;
-  mouse_y = 0;
-  mouse_btn = 0;
+       mouse_x = 0;
+       mouse_y = 0;
+       mouse_btn = 0;
   
-  return true;
-}
+       return true;
+    }
 #endif
 
 #ifdef USE_MOUSE_PS2    
-bool FBGui::check_mouse() 
-{
-  if (input_fd<0) return false;   // no mouse available
+    bool FBGui::check_mouse() 
+    {
+       if (input_fd<0) return false;   // no mouse available
   
-  int i;
-  int xmove, ymove, btn, btn_changed;
+       int i;
+       int xmove, ymove, btn, btn_changed;
   
-  read_mouse_data();
+       read_mouse_data();
   
-  // resync
-  int pos = -1;
-  for (i=0; i<mouse_buf_size; i++)
-  if (mouse_buf[i] & 8) { // bit 3 must be high for the first byte
-    pos = i;
-    break;    
-  }
-  if (pos<0) return false; // no sync or no data
+       // resync
+       int pos = -1;
+       for (i=0; i<mouse_buf_size; i++)
+           if (mouse_buf[i] & 8) { // bit 3 must be high for the first byte
+               pos = i;
+               break;    
+           }
+       if (pos<0) return false; // no sync or no data
   
-  if (pos>0) {
-    // remove garbage:
-    memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
-    mouse_buf_size -= pos;
-  }
+       if (pos>0) {
+           // remove garbage:
+           memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
+           mouse_buf_size -= pos;
+       }
   
   
-  if (mouse_buf_size >= 3) {
+       if (mouse_buf_size >= 3) {
   
-    xmove = mouse_buf[1];
-    ymove = mouse_buf[2];
-    btn = mouse_buf[0] & 1;
+           xmove = mouse_buf[1];
+           ymove = mouse_buf[2];
+           btn = mouse_buf[0] & 1;
     
-    if (mouse_buf[0] & 0x10) xmove = -(256-xmove);
-    if (mouse_buf[0] & 0x20) ymove = -(256-ymove);
+           if (mouse_buf[0] & 0x10) xmove = -(256-xmove);
+           if (mouse_buf[0] & 0x20) ymove = -(256-ymove);
     
-    ymove *= -1; // vertical movement is upside-down
+           ymove *= -1; // vertical movement is upside-down
     
-    log_debug(_("x/y %d/%d btn %d"), xmove, ymove, btn);
+           log_debug(_("x/y %d/%d btn %d"), xmove, ymove, btn);
 
-    // movement    
-    mouse_x += xmove;
-    mouse_y += ymove;
+           // movement    
+           mouse_x += xmove;
+           mouse_y += ymove;
     
-    if (mouse_x<0) mouse_x=0;
-    if (mouse_y<0) mouse_y=0;
-    if (mouse_x>m_stage_width) mouse_x=m_stage_width;
-    if (mouse_y>m_stage_height) mouse_y=m_stage_height;
+           if (mouse_x<0) mouse_x=0;
+           if (mouse_y<0) mouse_y=0;
+           if (mouse_x>m_stage_width) mouse_x=m_stage_width;
+           if (mouse_y>m_stage_height) mouse_y=m_stage_height;
     
-    //log_debug(_("mouse @ %d / %d, btn %d"), mouse_x, mouse_y, mouse_btn);
+           //log_debug(_("mouse @ %d / %d, btn %d"), mouse_x, mouse_y, 
mouse_btn);
     
-    notifyMouseMove(mouse_x, mouse_y);
+           notify_mouse_moved(mouse_x, mouse_y);
     
-    // button
-    if (btn != mouse_btn) {
-      mouse_btn = btn;
-printf("clicked: %d\n", btn);      
-      notifyMouseClick(btn);  // mark=??
-      //log_debug(_("mouse click! %d"), btn);
-    }    
-
-    // remove from buffer
-    pos=3;
-    memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
-    mouse_buf_size -= pos;  
+           // button
+           if (btn != mouse_btn) {
+               mouse_btn = btn;
+               printf("clicked: %d\n", btn);      
+               notify_mouse_clicked(btn, 1);  // mark=??
+               //log_debug(_("mouse click! %d"), btn);
+           }    
+
+           // remove from buffer
+           pos=3;
+           memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
+           mouse_buf_size -= pos;  
     
-    return true;
+           return true;
   
-  }
+       }
   
-}
+    }
 #endif
 
 #ifdef USE_MOUSE_ETT    
-bool FBGui::init_mouse()
-{
-  // Try to open mouse device, be error tolerant (FD is kept open all the time)
-  input_fd = open(MOUSE_DEVICE, O_RDWR);
+    bool FBGui::init_mouse()
+    {
+       // Try to open mouse device, be error tolerant (FD is kept open all the 
time)
+       input_fd = open(MOUSE_DEVICE, O_RDWR);
   
-  if (input_fd<0) {
-    log_debug(_("Could not open " MOUSE_DEVICE ": %s"), strerror(errno));    
-    return false;
-  }
+       if (input_fd<0) {
+           log_debug(_("Could not open " MOUSE_DEVICE ": %s"), 
strerror(errno));    
+           return false;
+       }
   
-  unsigned char buf[10];
+       unsigned char buf[10];
 
-  if (fcntl(input_fd, F_SETFL, fcntl(input_fd, F_GETFL) | O_NONBLOCK)<0) {
-    log_error("Could not set non-blocking mode for touchpad device: %s", 
strerror(errno));
-    close(input_fd);
-    input_fd=-1;
-    return false; 
-  }
+       if (fcntl(input_fd, F_SETFL, fcntl(input_fd, F_GETFL) | O_NONBLOCK)<0) {
+           log_error("Could not set non-blocking mode for touchpad device: 
%s", strerror(errno));
+           close(input_fd);
+           input_fd=-1;
+           return false; 
+       }
   
-  // Clear input buffer
-  while ( read(input_fd, buf, sizeof buf) > 0 ) { }
+       // Clear input buffer
+       while ( read(input_fd, buf, sizeof buf) > 0 ) { }
   
-  mouse_buf_size=0;
+       mouse_buf_size=0;
   
-  log_debug(_("Touchpad enabled."));
-  return true;
-} 
+       log_debug(_("Touchpad enabled."));
+       return true;
+    } 
 #endif
 
 #ifdef USE_MOUSE_ETT    
-bool FBGui::check_mouse() 
-{
-  bool activity = false;
-  
-  if (input_fd<0) return false;   // no mouse available
-  
-  read_mouse_data();
-  
-  // resync
-  int pos = -1;
-  int i;
-  for (i=0; i<mouse_buf_size; i++)
-  if (mouse_buf[i] & 0x80) { 
-    pos = i;
-    break;    
-  }
-  if (pos<0) return false; // no sync or no data
-  
-  if (pos>0) {
-    //printf("touchscreen: removing %d bytes garbage!\n", pos);  
-    memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
-    mouse_buf_size -= pos;
-  }
-    
-  // packet complete?
-  while (mouse_buf_size > 4) {
-    /*
-    eTurboTouch version??
-    mouse_btn = ((mouse_buf[0] >> 4) & 1);
-    mouse_x = (mouse_buf[1] << 4) | (mouse_buf[2] >> 3);
-    mouse_y = (mouse_buf[3] << 4) | (mouse_buf[4] >> 3);
-    */
-
-    int new_btn = (mouse_buf[0] & 1);
-    int new_x = (mouse_buf[1] << 7) | (mouse_buf[2]);
-    int new_y = (mouse_buf[3] << 7) | (mouse_buf[4]);
+    bool FBGui::check_mouse() 
+    {
+       bool activity = false;
+  
+       if (input_fd<0) return false;   // no mouse available
+  
+       read_mouse_data();
+  
+       // resync
+       int pos = -1;
+       int i;
+       for (i=0; i<mouse_buf_size; i++)
+           if (mouse_buf[i] & 0x80) { 
+               pos = i;
+               break;    
+           }
+       if (pos<0) return false; // no sync or no data
+  
+       if (pos>0) {
+           //printf("touchscreen: removing %d bytes garbage!\n", pos);  
+           memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
+           mouse_buf_size -= pos;
+       }
     
-    /*
-    printf("touchscreen: %02x %02x %02x %02x %02x | status %d, pos: %d/%d\n",
-      mouse_buf[0], mouse_buf[1], mouse_buf[2], mouse_buf[3], mouse_buf[4],   
-      new_btn, new_x, new_y);
-    */
+       // packet complete?
+       while (mouse_buf_size > 4) {
+           /*
+             eTurboTouch version??
+             mouse_btn = ((mouse_buf[0] >> 4) & 1);
+             mouse_x = (mouse_buf[1] << 4) | (mouse_buf[2] >> 3);
+             mouse_y = (mouse_buf[3] << 4) | (mouse_buf[4] >> 3);
+           */
+
+           int new_btn = (mouse_buf[0] & 1);
+           int new_x = (mouse_buf[1] << 7) | (mouse_buf[2]);
+           int new_y = (mouse_buf[3] << 7) | (mouse_buf[4]);
     
+           /*
+             printf("touchscreen: %02x %02x %02x %02x %02x | status %d, pos: 
%d/%d\n",
+             mouse_buf[0], mouse_buf[1], mouse_buf[2], mouse_buf[3], 
mouse_buf[4],   
+             new_btn, new_x, new_y);
+           */
     
-    new_x = static_cast<int>(((static_cast<double>(new_x )- 355) / (1702 - 355)
-    * 1536 + 256));
-    new_y = static_cast<int>(((static_cast<double>(new_y) - 482) / (1771 - 482)
-    * 1536 + 256));
     
+           new_x = static_cast<int>(((static_cast<double>(new_x )- 355) / 
(1702 - 355)
+                                     * 1536 + 256));
+           new_y = static_cast<int>(((static_cast<double>(new_y) - 482) / 
(1771 - 482)
+                                     * 1536 + 256));
     
-    new_x = new_x * m_stage_width / 2048;
-    new_y = (2048-new_y) * m_stage_height / 2048;
     
-    if ((new_x!=mouse_x) || (new_y!=mouse_y)) {
-      mouse_x = new_x;
-      mouse_y = new_y;
-      notifyMouseMove(mouse_x, mouse_y);
-      activity = true;
-    }
+           new_x = new_x * m_stage_width / 2048;
+           new_y = (2048-new_y) * m_stage_height / 2048;
     
-    if (new_btn != mouse_btn) {
-      mouse_btn = new_btn;      
-printf("clicked: %d\n", mouse_btn);      
-      notifyMouseClick(mouse_btn);  // mask=?
-      activity = true;
-    }
+           if ((new_x!=mouse_x) || (new_y!=mouse_y)) {
+               mouse_x = new_x;
+               mouse_y = new_y;
+               notify_mouse_moved(mouse_x, mouse_y);
+               activity = true;
+           }
+    
+           if (new_btn != mouse_btn) {
+               mouse_btn = new_btn;      
+               printf("clicked: %d\n", mouse_btn);      
+               notify_mouse_clicked(mouse_btn, 1);  // mask=?
+               activity = true;
+           }
     
-    // remove from buffer
-    pos=5;
-    memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
-    mouse_buf_size -= pos;    
-  }
+           // remove from buffer
+           pos=5;
+           memmove(mouse_buf, mouse_buf + pos, mouse_buf_size - pos);
+           mouse_buf_size -= pos;    
+       }
   
-  return activity;
+       return activity;
   
-}
+    }
 #endif
 
 #ifdef USE_INPUT_EVENTS   
-bool FBGui::init_mouse()
-{
-  std::string dev;
-
-  char* devname = std::getenv("POINTING_DEVICE");
-  if (devname) dev = devname;
-  else dev = "/dev/input/event0";
-
-  // Try to open mouse device, be error tolerant (FD is kept open all the time)
-  input_fd = open(dev.c_str(), O_RDONLY);
-  
-  if (input_fd<0) {
-    log_debug(_("Could not open %s: %s"), dev.c_str(), strerror(errno));    
-    return false;
-  }
-  
-  log_debug(_("Pointing device %s open"), dev.c_str());
-  
-  if (fcntl(input_fd, F_SETFL, fcntl(input_fd, F_GETFL) | O_NONBLOCK)<0) {
-    log_error(_("Could not set non-blocking mode for pointing device: %s"), 
strerror(errno));
-    close(input_fd);
-    input_fd=-1;
-    return false; 
-  }
-  
-  return true;
-
-} //init_mouse
-
-void FBGui::apply_ts_calibration(float* cx, float* cy, int rawx, int rawy) {
-
-  /*
-  <UdoG>:
-  This is a *very* simple method to translate raw touchscreen coordinates to
-  the screen coordinates. We simply to linear interpolation between two points.
-  Note this won't work well when the touchscreen is not perfectly aligned to
-  the screen (ie. slightly rotated). Standard touchscreen calibration uses
-  5 calibration points (or even 25). If someone can give me the formula, tell
-  me! I'm too lazy right now to do the math myself... ;)  
-  
-  And sorry for the quick-and-dirty implementation! I'm in a hurry...
-  */
-
-  float ref1x = m_stage_width  / 5 * 1;
-  float ref1y = m_stage_height / 5 * 1;
-  float ref2x = m_stage_width  / 5 * 4;
-  float ref2y = m_stage_height / 5 * 4;
-  
-  static float cal1x = 2048/5*1;   // very approximative default values
-  static float cal1y = 2048/5*4;
-  static float cal2x = 2048/5*4;
-  static float cal2y = 2048/5*1;
-  
-  static bool initialized=false; // woohooo.. better don't look at this code...
-  if (!initialized) {
-    initialized=true;
+    bool FBGui::init_mouse()
+    {
+       std::string dev;
+
+       char* devname = std::getenv("POINTING_DEVICE");
+       if (devname) dev = devname;
+       else dev = "/dev/input/event0";
+
+       // Try to open mouse device, be error tolerant (FD is kept open all the 
time)
+       input_fd = open(dev.c_str(), O_RDONLY);
+  
+       if (input_fd<0) {
+           log_debug(_("Could not open %s: %s"), dev.c_str(), 
strerror(errno));    
+           return false;
+       }
+  
+       log_debug(_("Pointing device %s open"), dev.c_str());
+  
+       if (fcntl(input_fd, F_SETFL, fcntl(input_fd, F_GETFL) | O_NONBLOCK)<0) {
+           log_error(_("Could not set non-blocking mode for pointing device: 
%s"), strerror(errno));
+           close(input_fd);
+           input_fd=-1;
+           return false; 
+       }
+  
+       return true;
+
+    } //init_mouse
+
+    void FBGui::apply_ts_calibration(float* cx, float* cy, int rawx, int rawy) 
{
+
+       /*
+         <UdoG>:
+         This is a *very* simple method to translate raw touchscreen 
coordinates to
+         the screen coordinates. We simply to linear interpolation between two 
points.
+         Note this won't work well when the touchscreen is not perfectly 
aligned to
+         the screen (ie. slightly rotated). Standard touchscreen calibration 
uses
+         5 calibration points (or even 25). If someone can give me the 
formula, tell
+         me! I'm too lazy right now to do the math myself... ;)  
+  
+         And sorry for the quick-and-dirty implementation! I'm in a hurry...
+       */
+
+       float ref1x = m_stage_width  / 5 * 1;
+       float ref1y = m_stage_height / 5 * 1;
+       float ref2x = m_stage_width  / 5 * 4;
+       float ref2y = m_stage_height / 5 * 4;
+  
+       static float cal1x = 2048/5*1;   // very approximative default values
+       static float cal1y = 2048/5*4;
+       static float cal2x = 2048/5*4;
+       static float cal2y = 2048/5*1;
+  
+       static bool initialized=false; // woohooo.. better don't look at this 
code...
+       if (!initialized) {
+           initialized=true;
     
-    char* settings = std::getenv("TSCALIB");
+           char* settings = std::getenv("TSCALIB");
     
-    if (settings) {
+           if (settings) {
     
-      // expected format: 
-      // 491,1635,1581,646      (cal1x,cal1y,cal2x,cal2y; all integers)
+               // expected format: 
+               // 491,1635,1581,646      (cal1x,cal1y,cal2x,cal2y; all 
integers)
 
-      char buffer[1024];      
-      char* p1;
-      char* p2;
-      bool ok = false;
+               char buffer[1024];      
+               char* p1;
+               char* p2;
+               bool ok = false;
       
-      snprintf(buffer, sizeof buffer, "%s", settings);
-      p1 = buffer;
+               snprintf(buffer, sizeof buffer, "%s", settings);
+               p1 = buffer;
       
-      do {
-        // cal1x        
-        p2 = strchr(p1, ',');
-        if (!p2) continue; // stop here
-        *p2 = 0;
-        cal1x = atoi(p1);        
-        p1=p2+1;
+               do {
+                   // cal1x        
+                   p2 = strchr(p1, ',');
+                   if (!p2) continue; // stop here
+                   *p2 = 0;
+                   cal1x = atoi(p1);        
+                   p1=p2+1;
         
-        // cal1y        
-        p2 = strchr(p1, ',');
-        if (!p2) continue; // stop here
-        *p2 = 0;
-        cal1y = atoi(p1);        
-        p1=p2+1;
+                   // cal1y        
+                   p2 = strchr(p1, ',');
+                   if (!p2) continue; // stop here
+                   *p2 = 0;
+                   cal1y = atoi(p1);        
+                   p1=p2+1;
         
-        // cal2x        
-        p2 = strchr(p1, ',');
-        if (!p2) continue; // stop here
-        *p2 = 0;
-        cal2x = atoi(p1);        
-        p1=p2+1;
+                   // cal2x        
+                   p2 = strchr(p1, ',');
+                   if (!p2) continue; // stop here
+                   *p2 = 0;
+                   cal2x = atoi(p1);        
+                   p1=p2+1;
         
-        // cal2y        
-        cal2y = atoi(p1);
+                   // cal2y        
+                   cal2y = atoi(p1);
         
-        ok = true;        
+                   ok = true;        
         
-      } while (0);
+               } while (0);
       
-      if (!ok)
-        log_debug(_("WARNING: Error parsing calibration data!"));
+               if (!ok)
+                   log_debug(_("WARNING: Error parsing calibration data!"));
       
-      log_debug(_("Using touchscreen calibration data: %.0f / %.0f / %.0f / 
%.0f"),
-        cal1x, cal1y, cal2x, cal2y);
+               log_debug(_("Using touchscreen calibration data: %.0f / %.0f / 
%.0f / %.0f"),
+                         cal1x, cal1y, cal2x, cal2y);
     
-    } else {
-      log_debug(_("WARNING: No touchscreen calibration settings found. "
-        "The mouse pointer most probably won't work precisely. Set "
-        "TSCALIB environment variable with correct values for better 
results"));
-    }
+           } else {
+               log_debug(_("WARNING: No touchscreen calibration settings 
found. "
+                           "The mouse pointer most probably won't work 
precisely. Set "
+                           "TSCALIB environment variable with correct values 
for better results"));
+           }
     
-  } //!initialized
+       } //!initialized
 
 
-  // real duty: 
-  *cx = (rawx-cal1x) / (cal2x-cal1x) * (ref2x-ref1x) + ref1x;
-  *cy = (rawy-cal1y) / (cal2y-cal1y) * (ref2y-ref1y) + ref1y;
-}
+       // real duty: 
+       *cx = (rawx-cal1x) / (cal2x-cal1x) * (ref2x-ref1x) + ref1x;
+       *cy = (rawy-cal1y) / (cal2y-cal1y) * (ref2y-ref1y) + ref1y;
+    }
 
-bool FBGui::check_mouse()
-{
-  bool activity = false;
+    bool FBGui::check_mouse()
+    {
+       bool activity = false;
   
-  if (input_fd < 0) return false;
+       if (input_fd < 0) return false;
 
-  struct input_event ev;  // time,type,code,value
+       struct input_event ev;  // time,type,code,value
   
-  static int new_mouse_x = 0; // all uncalibrated!
-  static int new_mouse_y = 0;
-  static int new_mouse_btn = 0;
+       static int new_mouse_x = 0; // all uncalibrated!
+       static int new_mouse_y = 0;
+       static int new_mouse_btn = 0;
   
-  int notify_x=0;     // coordinate to be sent via notifyMouseMove()
-  int notify_y=0;
-  bool move_pending = false;  // true: notifyMouseMove() should be called
+       int notify_x=0;     // coordinate to be sent via notify_mouse_moved()
+       int notify_y=0;
+       bool move_pending = false;  // true: notify_mouse_moved() should be 
called
   
-  // this is necessary for our quick'n'dirty touchscreen calibration: 
-  static int coordinatedebug = std::getenv("DUMP_RAW")!=NULL;
+       // this is necessary for our quick'n'dirty touchscreen calibration: 
+       static int coordinatedebug = std::getenv("DUMP_RAW")!=NULL;
   
-  // The while loop is limited because the kernel tends to send us hundreds
-  // of events while the touchscreen is touched. We don't loose any 
-  // information if we stop reading because the kernel will stop
-  // sending redundant information.
-  int loops=0;  
+       // The while loop is limited because the kernel tends to send us 
hundreds
+       // of events while the touchscreen is touched. We don't loose any 
+       // information if we stop reading because the kernel will stop
+       // sending redundant information.
+       int loops=0;  
   
-  // Assuming we will never read less than one full struct...  
+       // Assuming we will never read less than one full struct...  
   
-  while ((loops++ < 100) && (read(input_fd, &ev, sizeof ev) == (sizeof ev))) {
+       while ((loops++ < 100) && (read(input_fd, &ev, sizeof ev) == (sizeof 
ev))) {
 
-    if (ev.type == EV_SYN) {    // synchronize (apply information)
-      if ((new_mouse_x != mouse_x) || (new_mouse_y != mouse_y)) {
+           if (ev.type == EV_SYN) {    // synchronize (apply information)
+               if ((new_mouse_x != mouse_x) || (new_mouse_y != mouse_y)) {
       
-        mouse_x = new_mouse_x;
-        mouse_y = new_mouse_y;
+                   mouse_x = new_mouse_x;
+                   mouse_y = new_mouse_y;
         
-        float cx, cy;
+                   float cx, cy;
         
-        if (std::getenv("TSCALIB"))  // ONLY convert when requested
-          apply_ts_calibration(&cx, &cy, mouse_x, mouse_y);
-        else
-          { cx=mouse_x; cy=mouse_y; }
+                   if (std::getenv("TSCALIB"))  // ONLY convert when requested
+                       apply_ts_calibration(&cx, &cy, mouse_x, mouse_y);
+                   else
+                       { cx=mouse_x; cy=mouse_y; }
               
-        // Don't call notifyMouseMove() here because this would lead to
-        // lots of calls, especially for touchscreens. Instead we save the
-        // coordinate and call notifyMouseMove() only once.
-        notify_x = cx;
-        notify_y = cy;
-        move_pending = true;        
-      }
+                   // Don't call notify_mouse_moved() here because this would 
lead to
+                   // lots of calls, especially for touchscreens. Instead we 
save the
+                   // coordinate and call notify_mouse_moved() only once.
+                   notify_x = cx;
+                   notify_y = cy;
+                   move_pending = true;        
+               }
       
-      if (new_mouse_btn != mouse_btn) {
+               if (new_mouse_btn != mouse_btn) {
       
-        if (move_pending) {
-          notifyMouseMove(notify_x, notify_y);
-          activity = true;
-          move_pending = false;
-        }
+                   if (move_pending) {
+                       notifyMouseMove(notify_x, notify_y);
+                       activity = true;
+                       move_pending = false;
+                   }
       
-        mouse_btn = new_mouse_btn;
-        notifyMouseClick(mouse_btn);  // mark=??
-        activity = true;
-      }
+                   mouse_btn = new_mouse_btn;
+                   notifyMouseClick(mouse_btn);  // mark=??
+                   activity = true;
+               }
 
-      if (coordinatedebug)
-        printf("DEBUG: % 5d / % 5d / % 5d\n", mouse_x, mouse_y, mouse_btn);
+               if (coordinatedebug)
+                   printf("DEBUG: % 5d / % 5d / % 5d\n", mouse_x, mouse_y, 
mouse_btn);
       
-    }
+           }
   
-    if (ev.type == EV_KEY) {    // button down/up
+           if (ev.type == EV_KEY) {    // button down/up
     
-      // don't care which button, we support only one...
-      new_mouse_btn = ev.value;      
+               // don't care which button, we support only one...
+               new_mouse_btn = ev.value;      
       
-    }
+           }
       
-    if (ev.type == EV_ABS) {    // absolute coordinate
-      if (ev.code == ABS_X) new_mouse_x = ev.value;
-      if (ev.code == ABS_Y) new_mouse_y = ev.value;
-      if (ev.code == ABS_PRESSURE) new_mouse_btn = ev.value >= 128;
-    }
+           if (ev.type == EV_ABS) {    // absolute coordinate
+               if (ev.code == ABS_X) new_mouse_x = ev.value;
+               if (ev.code == ABS_Y) new_mouse_y = ev.value;
+               if (ev.code == ABS_PRESSURE) new_mouse_btn = ev.value >= 128;
+           }
     
-    if (ev.type == EV_REL) {    // relative movement
-      if (ev.code == REL_X) new_mouse_x += ev.value;
-      if (ev.code == REL_Y) new_mouse_y += ev.value;
+           if (ev.type == EV_REL) {    // relative movement
+               if (ev.code == REL_X) new_mouse_x += ev.value;
+               if (ev.code == REL_Y) new_mouse_y += ev.value;
       
-      if (new_mouse_x < 0) new_mouse_x=0;
-      if (new_mouse_y < 0) new_mouse_y=0;
+               if (new_mouse_x < 0) new_mouse_x=0;
+               if (new_mouse_y < 0) new_mouse_y=0;
       
-      if (new_mouse_x > m_stage_width ) new_mouse_x = m_stage_width;
-      if (new_mouse_y > m_stage_height) new_mouse_y = m_stage_height;
-    }      
+               if (new_mouse_x > m_stage_width ) new_mouse_x = m_stage_width;
+               if (new_mouse_y > m_stage_height) new_mouse_y = m_stage_height;
+           }      
   
-  } 
+       } 
   
-  if (move_pending) {
-    notifyMouseMove(notify_x, notify_y);
-    activity = true;
-  }
+       if (move_pending) {
+           notifyMouseMove(notify_x, notify_y);
+           activity = true;
+       }
   
-  return activity;
+       return activity;
  
-} //check_mouse
+    } //check_mouse
 #endif
 
 
-bool FBGui::init_keyboard() 
-{
-  std::string dev;
+    bool FBGui::init_keyboard() 
+    {
+       std::string dev;
 
-  char* devname = std::getenv("KEYBOARD_DEVICE");
-  if (devname) dev = devname;
-  else dev = "/dev/input/event0";
+       char* devname = std::getenv("KEYBOARD_DEVICE");
+       if (devname) dev = devname;
+       else dev = "/dev/input/event0";
 
-  // Try to open keyboard device, be error tolerant (FD is kept open all the 
time)
-  keyb_fd = open(dev.c_str(), O_RDONLY);
+       // Try to open keyboard device, be error tolerant (FD is kept open all 
the time)
+       keyb_fd = open(dev.c_str(), O_RDONLY);
   
-  if (keyb_fd<0) {
-    log_debug(_("Could not open %s: %s"), dev.c_str(), strerror(errno));    
-    return false;
-  }
+       if (keyb_fd<0) {
+           log_debug(_("Could not open %s: %s"), dev.c_str(), 
strerror(errno));    
+           return false;
+       }
   
-  log_debug(_("Keyboard device %s open"), dev.c_str());
+       log_debug(_("Keyboard device %s open"), dev.c_str());
   
-  if (fcntl(keyb_fd, F_SETFL, fcntl(keyb_fd, F_GETFL) | O_NONBLOCK)<0) {
-    log_error(_("Could not set non-blocking mode for keyboard device: %s"), 
strerror(errno));
-    close(keyb_fd);
-    keyb_fd=-1;
-    return false; 
-  }
+       if (fcntl(keyb_fd, F_SETFL, fcntl(keyb_fd, F_GETFL) | O_NONBLOCK)<0) {
+           log_error(_("Could not set non-blocking mode for keyboard device: 
%s"), strerror(errno));
+           close(keyb_fd);
+           keyb_fd=-1;
+           return false; 
+       }
   
-  return true;
-}
+       return true;
+    }
 
-gnash::key::code FBGui::scancode_to_gnash_key(int code, bool shift) {
+    gnash::key::code FBGui::scancode_to_gnash_key(int code, bool shift) {
  
-  // NOTE: Scancodes are mostly keyboard oriented (ie. Q, W, E, R, T, ...)
-  // while Gnash codes are mostly ASCII-oriented (A, B, C, D, ...) so no
-  // direct conversion is possible.
-  
-  // TODO: This is a very *incomplete* list and I also dislike this method
-  // very much because it depends on the keyboard layout (ie. pressing "Z"
-  // on a german keyboard will print "Y" instead). So we need some 
-  // alternative...
-  
-  switch (code) {
-  
-    case KEY_1      : return !shift ? gnash::key::_1 : gnash::key::EXCLAM;
-    case KEY_2      : return !shift ? gnash::key::_2 : 
gnash::key::DOUBLE_QUOTE; 
-    case KEY_3      : return !shift ? gnash::key::_3 : gnash::key::HASH; 
-    case KEY_4      : return !shift ? gnash::key::_4 : gnash::key::DOLLAR; 
-    case KEY_5      : return !shift ? gnash::key::_5 : gnash::key::PERCENT; 
-    case KEY_6      : return !shift ? gnash::key::_6 : gnash::key::AMPERSAND; 
-    case KEY_7      : return !shift ? gnash::key::_7 : 
gnash::key::SINGLE_QUOTE; 
-    case KEY_8      : return !shift ? gnash::key::_8 : gnash::key::PAREN_LEFT; 
-    case KEY_9      : return !shift ? gnash::key::_9 : 
gnash::key::PAREN_RIGHT; 
-    case KEY_0      : return !shift ? gnash::key::_0 : gnash::key::ASTERISK;
+       // NOTE: Scancodes are mostly keyboard oriented (ie. Q, W, E, R, T, ...)
+       // while Gnash codes are mostly ASCII-oriented (A, B, C, D, ...) so no
+       // direct conversion is possible.
+  
+       // TODO: This is a very *incomplete* list and I also dislike this method
+       // very much because it depends on the keyboard layout (ie. pressing "Z"
+       // on a german keyboard will print "Y" instead). So we need some 
+       // alternative...
+  
+       switch (code) {
+  
+       case KEY_1      : return !shift ? gnash::key::_1 : gnash::key::EXCLAM;
+       case KEY_2      : return !shift ? gnash::key::_2 : 
gnash::key::DOUBLE_QUOTE; 
+       case KEY_3      : return !shift ? gnash::key::_3 : gnash::key::HASH; 
+       case KEY_4      : return !shift ? gnash::key::_4 : gnash::key::DOLLAR; 
+       case KEY_5      : return !shift ? gnash::key::_5 : gnash::key::PERCENT; 
+       case KEY_6      : return !shift ? gnash::key::_6 : 
gnash::key::AMPERSAND; 
+       case KEY_7      : return !shift ? gnash::key::_7 : 
gnash::key::SINGLE_QUOTE; 
+       case KEY_8      : return !shift ? gnash::key::_8 : 
gnash::key::PAREN_LEFT; 
+       case KEY_9      : return !shift ? gnash::key::_9 : 
gnash::key::PAREN_RIGHT; 
+       case KEY_0      : return !shift ? gnash::key::_0 : gnash::key::ASTERISK;
                             
-    case KEY_A      : return shift ? gnash::key::A : gnash::key::a;
-    case KEY_B      : return shift ? gnash::key::B : gnash::key::b;
-    case KEY_C      : return shift ? gnash::key::C : gnash::key::c;
-    case KEY_D      : return shift ? gnash::key::D : gnash::key::d;
-    case KEY_E      : return shift ? gnash::key::E : gnash::key::e;
-    case KEY_F      : return shift ? gnash::key::F : gnash::key::f;
-    case KEY_G      : return shift ? gnash::key::G : gnash::key::g;
-    case KEY_H      : return shift ? gnash::key::H : gnash::key::h;
-    case KEY_I      : return shift ? gnash::key::I : gnash::key::i;
-    case KEY_J      : return shift ? gnash::key::J : gnash::key::j;
-    case KEY_K      : return shift ? gnash::key::K : gnash::key::k;
-    case KEY_L      : return shift ? gnash::key::L : gnash::key::l;
-    case KEY_M      : return shift ? gnash::key::M : gnash::key::m;
-    case KEY_N      : return shift ? gnash::key::N : gnash::key::n;
-    case KEY_O      : return shift ? gnash::key::O : gnash::key::o;
-    case KEY_P      : return shift ? gnash::key::P : gnash::key::p;
-    case KEY_Q      : return shift ? gnash::key::Q : gnash::key::q;
-    case KEY_R      : return shift ? gnash::key::R : gnash::key::r;
-    case KEY_S      : return shift ? gnash::key::S : gnash::key::s;
-    case KEY_T      : return shift ? gnash::key::T : gnash::key::t;
-    case KEY_U      : return shift ? gnash::key::U : gnash::key::u;
-    case KEY_V      : return shift ? gnash::key::V : gnash::key::v;
-    case KEY_W      : return shift ? gnash::key::W : gnash::key::w;
-    case KEY_X      : return shift ? gnash::key::X : gnash::key::x;
-    case KEY_Y      : return shift ? gnash::key::Y : gnash::key::y;
-    case KEY_Z      : return shift ? gnash::key::Z : gnash::key::z;
-
-    case KEY_F1     : return gnash::key::F1; 
-    case KEY_F2     : return gnash::key::F2; 
-    case KEY_F3     : return gnash::key::F3; 
-    case KEY_F4     : return gnash::key::F4; 
-    case KEY_F5     : return gnash::key::F5; 
-    case KEY_F6     : return gnash::key::F6; 
-    case KEY_F7     : return gnash::key::F7; 
-    case KEY_F8     : return gnash::key::F8; 
-    case KEY_F9     : return gnash::key::F9;
-    case KEY_F10    : return gnash::key::F10;
-    case KEY_F11    : return gnash::key::F11;
-    case KEY_F12    : return gnash::key::F12;
-    
-    case KEY_KP0    : return gnash::key::KP_0; 
-    case KEY_KP1    : return gnash::key::KP_1; 
-    case KEY_KP2    : return gnash::key::KP_2; 
-    case KEY_KP3    : return gnash::key::KP_3; 
-    case KEY_KP4    : return gnash::key::KP_4; 
-    case KEY_KP5    : return gnash::key::KP_5; 
-    case KEY_KP6    : return gnash::key::KP_6; 
-    case KEY_KP7    : return gnash::key::KP_7; 
-    case KEY_KP8    : return gnash::key::KP_8; 
-    case KEY_KP9    : return gnash::key::KP_9;
-
-    case KEY_KPMINUS       : return gnash::key::KP_SUBTRACT;
-    case KEY_KPPLUS        : return gnash::key::KP_ADD;
-    case KEY_KPDOT         : return gnash::key::KP_DECIMAL;
-    case KEY_KPASTERISK    : return gnash::key::KP_MULTIPLY;
-    case KEY_KPENTER       : return gnash::key::KP_ENTER;
-    
-    case KEY_ESC           : return gnash::key::ESCAPE;
-    case KEY_MINUS         : return gnash::key::MINUS;
-    case KEY_EQUAL         : return gnash::key::EQUALS;
-    case KEY_BACKSPACE     : return gnash::key::BACKSPACE;
-    case KEY_TAB           : return gnash::key::TAB;
-    case KEY_LEFTBRACE     : return gnash::key::LEFT_BRACE;
-    case KEY_RIGHTBRACE    : return gnash::key::RIGHT_BRACE;
-    case KEY_ENTER         : return gnash::key::ENTER;
-    case KEY_LEFTCTRL      : return gnash::key::CONTROL;
-    case KEY_SEMICOLON     : return gnash::key::SEMICOLON;
-    //case KEY_APOSTROPHE    : return gnash::key::APOSTROPHE;  
-    //case KEY_GRAVE         : return gnash::key::GRAVE;
-    case KEY_LEFTSHIFT     : return gnash::key::SHIFT;
-    case KEY_BACKSLASH     : return gnash::key::BACKSLASH;
-    case KEY_COMMA         : return gnash::key::COMMA;
-    case KEY_SLASH         : return gnash::key::SLASH;
-    case KEY_RIGHTSHIFT    : return gnash::key::SHIFT;
-    case KEY_LEFTALT       : return gnash::key::ALT;
-    case KEY_SPACE         : return gnash::key::SPACE;
-    case KEY_CAPSLOCK      : return gnash::key::CAPSLOCK;
-    case KEY_NUMLOCK       : return gnash::key::NUM_LOCK;
-    //case KEY_SCROLLLOCK    : return gnash::key::SCROLLLOCK;
-    
-    case KEY_UP            : return gnash::key::UP;
-    case KEY_DOWN          : return gnash::key::DOWN;
-    case KEY_LEFT          : return gnash::key::LEFT;
-    case KEY_RIGHT         : return gnash::key::RIGHT;
-    case KEY_PAGEUP        : return gnash::key::PGUP;
-    case KEY_PAGEDOWN      : return gnash::key::PGDN;
-    case KEY_INSERT        : return gnash::key::INSERT;
-    case KEY_DELETE        : return gnash::key::DELETEKEY;
-    case KEY_HOME          : return gnash::key::HOME;
-    case KEY_END           : return gnash::key::END;
-    
-  }
-  
-  return gnash::key::INVALID;  
-}
+       case KEY_A      : return shift ? gnash::key::A : gnash::key::a;
+       case KEY_B      : return shift ? gnash::key::B : gnash::key::b;
+       case KEY_C      : return shift ? gnash::key::C : gnash::key::c;
+       case KEY_D      : return shift ? gnash::key::D : gnash::key::d;
+       case KEY_E      : return shift ? gnash::key::E : gnash::key::e;
+       case KEY_F      : return shift ? gnash::key::F : gnash::key::f;
+       case KEY_G      : return shift ? gnash::key::G : gnash::key::g;
+       case KEY_H      : return shift ? gnash::key::H : gnash::key::h;
+       case KEY_I      : return shift ? gnash::key::I : gnash::key::i;
+       case KEY_J      : return shift ? gnash::key::J : gnash::key::j;
+       case KEY_K      : return shift ? gnash::key::K : gnash::key::k;
+       case KEY_L      : return shift ? gnash::key::L : gnash::key::l;
+       case KEY_M      : return shift ? gnash::key::M : gnash::key::m;
+       case KEY_N      : return shift ? gnash::key::N : gnash::key::n;
+       case KEY_O      : return shift ? gnash::key::O : gnash::key::o;
+       case KEY_P      : return shift ? gnash::key::P : gnash::key::p;
+       case KEY_Q      : return shift ? gnash::key::Q : gnash::key::q;
+       case KEY_R      : return shift ? gnash::key::R : gnash::key::r;
+       case KEY_S      : return shift ? gnash::key::S : gnash::key::s;
+       case KEY_T      : return shift ? gnash::key::T : gnash::key::t;
+       case KEY_U      : return shift ? gnash::key::U : gnash::key::u;
+       case KEY_V      : return shift ? gnash::key::V : gnash::key::v;
+       case KEY_W      : return shift ? gnash::key::W : gnash::key::w;
+       case KEY_X      : return shift ? gnash::key::X : gnash::key::x;
+       case KEY_Y      : return shift ? gnash::key::Y : gnash::key::y;
+       case KEY_Z      : return shift ? gnash::key::Z : gnash::key::z;
+
+       case KEY_F1     : return gnash::key::F1; 
+       case KEY_F2     : return gnash::key::F2; 
+       case KEY_F3     : return gnash::key::F3; 
+       case KEY_F4     : return gnash::key::F4; 
+       case KEY_F5     : return gnash::key::F5; 
+       case KEY_F6     : return gnash::key::F6; 
+       case KEY_F7     : return gnash::key::F7; 
+       case KEY_F8     : return gnash::key::F8; 
+       case KEY_F9     : return gnash::key::F9;
+       case KEY_F10    : return gnash::key::F10;
+       case KEY_F11    : return gnash::key::F11;
+       case KEY_F12    : return gnash::key::F12;
+    
+       case KEY_KP0    : return gnash::key::KP_0; 
+       case KEY_KP1    : return gnash::key::KP_1; 
+       case KEY_KP2    : return gnash::key::KP_2; 
+       case KEY_KP3    : return gnash::key::KP_3; 
+       case KEY_KP4    : return gnash::key::KP_4; 
+       case KEY_KP5    : return gnash::key::KP_5; 
+       case KEY_KP6    : return gnash::key::KP_6; 
+       case KEY_KP7    : return gnash::key::KP_7; 
+       case KEY_KP8    : return gnash::key::KP_8; 
+       case KEY_KP9    : return gnash::key::KP_9;
+
+       case KEY_KPMINUS       : return gnash::key::KP_SUBTRACT;
+       case KEY_KPPLUS        : return gnash::key::KP_ADD;
+       case KEY_KPDOT         : return gnash::key::KP_DECIMAL;
+       case KEY_KPASTERISK    : return gnash::key::KP_MULTIPLY;
+       case KEY_KPENTER       : return gnash::key::KP_ENTER;
+    
+       case KEY_ESC           : return gnash::key::ESCAPE;
+       case KEY_MINUS         : return gnash::key::MINUS;
+       case KEY_EQUAL         : return gnash::key::EQUALS;
+       case KEY_BACKSPACE     : return gnash::key::BACKSPACE;
+       case KEY_TAB           : return gnash::key::TAB;
+       case KEY_LEFTBRACE     : return gnash::key::LEFT_BRACE;
+       case KEY_RIGHTBRACE    : return gnash::key::RIGHT_BRACE;
+       case KEY_ENTER         : return gnash::key::ENTER;
+       case KEY_LEFTCTRL      : return gnash::key::CONTROL;
+       case KEY_SEMICOLON     : return gnash::key::SEMICOLON;
+           //case KEY_APOSTROPHE    : return gnash::key::APOSTROPHE;  
+           //case KEY_GRAVE         : return gnash::key::GRAVE;
+       case KEY_LEFTSHIFT     : return gnash::key::SHIFT;
+       case KEY_BACKSLASH     : return gnash::key::BACKSLASH;
+       case KEY_COMMA         : return gnash::key::COMMA;
+       case KEY_SLASH         : return gnash::key::SLASH;
+       case KEY_RIGHTSHIFT    : return gnash::key::SHIFT;
+       case KEY_LEFTALT       : return gnash::key::ALT;
+       case KEY_SPACE         : return gnash::key::SPACE;
+       case KEY_CAPSLOCK      : return gnash::key::CAPSLOCK;
+       case KEY_NUMLOCK       : return gnash::key::NUM_LOCK;
+           //case KEY_SCROLLLOCK    : return gnash::key::SCROLLLOCK;
+    
+       case KEY_UP            : return gnash::key::UP;
+       case KEY_DOWN          : return gnash::key::DOWN;
+       case KEY_LEFT          : return gnash::key::LEFT;
+       case KEY_RIGHT         : return gnash::key::RIGHT;
+       case KEY_PAGEUP        : return gnash::key::PGUP;
+       case KEY_PAGEDOWN      : return gnash::key::PGDN;
+       case KEY_INSERT        : return gnash::key::INSERT;
+       case KEY_DELETE        : return gnash::key::DELETEKEY;
+       case KEY_HOME          : return gnash::key::HOME;
+       case KEY_END           : return gnash::key::END;
+    
+       }
+  
+       return gnash::key::INVALID;  
+    }
 
-bool FBGui::check_keyboard()
-{
-  bool activity = false;
+    bool FBGui::check_keyboard()
+    {
+       bool activity = false;
   
-  if (keyb_fd < 0) return false;
+       if (keyb_fd < 0) return false;
 
-  struct input_event ev;  // time,type,code,value
+       struct input_event ev;  // time,type,code,value
 
   
-  while (read(keyb_fd, &ev, sizeof ev) == (sizeof ev)) {
+       while (read(keyb_fd, &ev, sizeof ev) == (sizeof ev)) {
   
-    if (ev.type == EV_KEY) {
+           if (ev.type == EV_KEY) {
     
-      // code == scan code of the key (KEY_xxxx defines in input.h)
+               // code == scan code of the key (KEY_xxxx defines in input.h)
       
-      // value == 0  key has been released
-      // value == 1  key has been pressed
-      // value == 2  repeated key reporting (while holding the key) 
-
-      if (ev.code==KEY_LEFTSHIFT) 
-        keyb_lshift = ev.value;
-      else
-      if (ev.code==KEY_RIGHTSHIFT) 
-        keyb_rshift = ev.value;
-      else
-      if (ev.code==KEY_LEFTCTRL) 
-        keyb_lctrl = ev.value;
-      else
-      if (ev.code==KEY_RIGHTCTRL) 
-        keyb_rctrl = ev.value;
-      else
-      if (ev.code==KEY_LEFTALT) 
-        keyb_lalt = ev.value;
-      else
-      if (ev.code==KEY_RIGHTALT) 
-        keyb_ralt = ev.value;
-      else {
+               // value == 0  key has been released
+               // value == 1  key has been pressed
+               // value == 2  repeated key reporting (while holding the key) 
+
+               if (ev.code==KEY_LEFTSHIFT) 
+                   keyb_lshift = ev.value;
+               else
+                   if (ev.code==KEY_RIGHTSHIFT) 
+                       keyb_rshift = ev.value;
+                   else
+                       if (ev.code==KEY_LEFTCTRL) 
+                           keyb_lctrl = ev.value;
+                       else
+                           if (ev.code==KEY_RIGHTCTRL) 
+                               keyb_rctrl = ev.value;
+                           else
+                               if (ev.code==KEY_LEFTALT) 
+                                   keyb_lalt = ev.value;
+                               else
+                                   if (ev.code==KEY_RIGHTALT) 
+                                       keyb_ralt = ev.value;
+                                   else {
       
-        gnash::key::code  c = scancode_to_gnash_key(ev.code, 
-          keyb_lshift || keyb_rshift);
+                                       gnash::key::code  c = 
scancode_to_gnash_key(ev.code, 
+                                                                               
    keyb_lshift || keyb_rshift);
       
-        // build modifier
+                                       // build modifier
       
-        int modifier = gnash::key::GNASH_MOD_NONE;
+                                       int modifier = 
gnash::key::GNASH_MOD_NONE;
         
-        if (keyb_lshift || keyb_rshift)
-          modifier = modifier | gnash::key::GNASH_MOD_SHIFT;
+                                       if (keyb_lshift || keyb_rshift)
+                                           modifier = modifier | 
gnash::key::GNASH_MOD_SHIFT;
 
-        if (keyb_lctrl || keyb_rctrl)
-          modifier = modifier | gnash::key::GNASH_MOD_CONTROL;
+                                       if (keyb_lctrl || keyb_rctrl)
+                                           modifier = modifier | 
gnash::key::GNASH_MOD_CONTROL;
 
-        if (keyb_lalt || keyb_ralt)
-          modifier = modifier | gnash::key::GNASH_MOD_ALT;
+                                       if (keyb_lalt || keyb_ralt)
+                                           modifier = modifier | 
gnash::key::GNASH_MOD_ALT;
           
           
-        // send event
-        if (c != gnash::key::INVALID) {
-          Gui::notify_key_event(c, modifier, ev.value);
-          activity=true;
-        }
+                                       // send event
+                                       if (c != gnash::key::INVALID) {
+                                           Gui::notify_key_event(c, modifier, 
ev.value);
+                                           activity=true;
+                                       }
               
-      } //if normal key
+                                   } //if normal key
 
-    } //if EV_KEY      
+           } //if EV_KEY      
   
-  } //while
+       } //while
   
-  return activity;
+       return activity;
+
+    }
 
+    // end of namespace gnash
 }
 
-// end of namespace gnash
+#ifdef ENABLE_FAKE_FRAMEBUFFER
+// Simulate the ioctls used to get information from the framebuffer
+// driver. Since this is an emulator, we have to set these fields
+// to a reasonable default.
+int
+fakefb_ioctl(int /* fd */, int request, void *data)
+{
+    // GNASH_REPORT_FUNCTION;
+    
+    switch (request) {
+      case FBIOGET_VSCREENINFO:
+      {
+          struct fb_var_screeninfo *ptr =
+              reinterpret_cast<struct fb_var_screeninfo *>(data);
+          // If we are using a simulated framebuffer, the default for
+          // fbe us 640x480, 8bits. So use that as a sensible
+          // default. Note that the fake framebuffer is only used for
+          // debugging and development.
+          ptr->xres          = 640; // visible resolution
+          ptr->xres_virtual  = 640; // virtual resolution
+          ptr->yres          = 480; // visible resolution
+          ptr->yres_virtual  = 480; // virtual resolution
+          ptr->width         = 640; // width of picture in mm
+          ptr->height        = 480; // height of picture in mm
+
+          // Android uses a 16bit framebuffer
+          ptr->bits_per_pixel = 16;
+          ptr->red.length    = 5;
+          ptr->red.offset    = 11;
+          ptr->green.length  = 6;
+          ptr->green.offset  = 5;
+          ptr->blue.length   = 5;
+          ptr->blue.offset   = 0;
+          ptr->transp.offset = 0;
+          ptr->transp.length = 0;
+          // 8bit framebuffer
+          // ptr->bits_per_pixel = 8;
+          // ptr->red.length    = 8;
+          // ptr->red.offset    = 0;
+          // ptr->green.length  = 8;
+          // ptr->green.offset  = 0;
+          // ptr->blue.length   = 8;
+          // ptr->blue.offset   = 0;
+          // ptr->transp.offset = 0;
+          // ptr->transp.length = 0;
+          ptr->grayscale     = 1; // != 0 Graylevels instead of color
+          
+          break;
+      }
+      case FBIOGET_FSCREENINFO:
+      {
+          struct fb_fix_screeninfo *ptr =
+              reinterpret_cast<struct fb_fix_screeninfo *>(data);
+          ptr->smem_len = 307200; // Length of frame buffer mem
+          ptr->type = FB_TYPE_PACKED_PIXELS; // see FB_TYPE_*
+          ptr->visual = FB_VISUAL_PSEUDOCOLOR; // see FB_VISUAL_*
+          ptr->xpanstep = 0;      // zero if no hardware panning
+          ptr->ypanstep = 0;      // zero if no hardware panning
+          ptr->ywrapstep = 0;     // zero if no hardware panning
+          ptr->accel = FB_ACCEL_NONE; // Indicate to driver which specific
+                                  // chip/card we have
+          break;
+      }
+      case FBIOPUTCMAP:
+      {
+          // Fbe uses this name for the fake framebuffer, so in this
+          // case assume we're using fbe, so write to the known fbe
+          // cmap file.
+          std::string str = FAKEFB;
+          if (str == "/tmp/fbe_buffer") {
+              int fd = open("/tmp/fbe_cmap", O_WRONLY);
+              if (fd) {
+                  write(fd, data, sizeof(struct fb_cmap));
+                  close(fd);
+              } else {
+                  gnash::log_error("Couldn't write to the fake cmap!");
+                  return -1;
+              }
+          } else {
+              gnash::log_error("Couldn't write to the fake cmap, unknown 
type!");
+              return -1;
+          }
+          // If we send a SIGUSR1 signal to fbe, it'll reload the
+          // color map.
+          int fd = open("/tmp/fbe.pid", O_RDONLY);
+          char buf[10];
+          if (fd) {
+              if (read(fd, buf, 10) == 0) {
+                  close(fd);
+                  return -1;
+              } else {
+                  pid_t pid = strtol(buf, 0, NULL);
+                  kill(pid, SIGUSR1);
+                  gnash::log_debug("Signaled fbe to reload it's colormap.");
+              }
+              close(fd);
+          }
+          break;
+      }
+      default:
+          gnash::log_unimpl("fakefb_ioctl(%d)", request);
+          break;
+    }
+
+    return 0;
 }
+#endif  // ENABLE_FAKE_FRAMEBUFFER
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/gui/fb/fb_glue_ovg.h b/gui/fb/fb_glue_ovg.h
new file mode 100644
index 0000000..2a5c992
--- /dev/null
+++ b/gui/fb/fb_glue_ovg.h
@@ -0,0 +1,74 @@
+//
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+//   Foundation, Inc
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef FB_GLUE_OVG_H
+#define FB_GLUE_OVG_H 1
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <boost/cstdint.hpp>
+
+#include "fbsup.h"
+
+#ifdef HAVE_VG_OPENVG_H
+#include <VG/openvg.h>
+#endif
+
+namespace gnash {
+
+class render_handler;
+
+class FBOvgGlue : public FBGlue
+{
+public:
+    FBOvgGlue(int fd);
+    FBOvgGlue(int x, int y, int width, int height);
+    ~FBOvgGlue();
+    
+    virtual bool init(int argc, char ***argv);
+    virtual void render();
+    
+    // resize(int width, int height);
+    void draw();
+    // Renderer* createRenderHandler();
+    void initBuffer(int width, int height);
+    void resize(int width, int height);
+    // void render(geometry::Range2d<int>& bounds);
+    
+private:
+    int         _width;
+    int         _height;
+    int         _stride;
+    boost::uint8_t *_offscreenbuf;
+    // Renderer *_renderer;
+    
+    //Rectangle _bounds;
+    geometry::Range2d<int> _drawbounds;
+    geometry::Range2d<int> _validbounds;
+};
+    
+} // end of namespace gnash
+
+#endif  // end of FB_GLUE_OVG_H
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/gui/fb/fbsup.h b/gui/fb/fbsup.h
index 2d3a4a1..506a3bc 100644
--- a/gui/fb/fbsup.h
+++ b/gui/fb/fbsup.h
@@ -31,16 +31,6 @@
 #define PIXELFORMAT_LUT8
 #define CMAP_SIZE (256*2)
 
-// If defined, an internal software-buffer is used for rendering and is then
-// copied to the video RAM. This avoids flicker and is faster for complex 
-// graphics, as video RAM access is usually slower. 
-// (strongly suggested)
-#define DOUBLE_BUFFER
-
-
-// TODO: Make this configurable via ./configure!
-
-
 // Define this to read from /dev/input/mice (any PS/2 compatbile mouse or
 // emulated by the Kernel) 
 //#define USE_MOUSE_PS2
@@ -60,16 +50,13 @@
 #define MOUSE_DEVICE "/dev/usb/tkpanel0"
 #endif
 
-
 // Define this to request a new virtual terminal at startup. This doesn't 
always
 // work and probably is not necessary anyway
 //#define REQUEST_NEW_VT
 
-
 namespace gnash
 {
 
-
 /// A Framebuffer-based GUI for Gnash.
 /// ----------------------------------
 ///
@@ -108,87 +95,98 @@ namespace gnash
 ///
 ///   any PS/2 compatible mouse (may be emulated by the kernel) talking 
 ///   to /dev/input/mice
+
+class Renderer;
+
+/// Base class for Framebuffer renderer used by the GUI
+class FBGlue
+{
+public:
+    FBGlue();
+    virtual ~FBGlue();
+
+    /// Initialize the glue between the Renderer and the GUI
+    virtual bool init(int argc, char ***argv) = 0;
+
+    /// Create a new render handler
+    virtual Renderer *createRenderHandler() = 0;
+    
+    virtual void setInvalidatedRegions(const InvalidatedRanges& ranges) = 0;
+    
+    virtual int width() = 0;
+    virtual int height() = 0;
+    
+    virtual void render() = 0;
+};
+
+/// Base class for Framebuffer based displays
 class FBGui : public Gui
 {
-       private:
-               int fd;
-               int original_vt;       // virtual terminal that was active at 
startup
-               int original_kd;       // keyboard mode at startup
-               int own_vt;            // virtual terminal we are running in   
-               unsigned char *fbmem;  // framebuffer memory
-#ifdef DOUBLE_BUFFER
-               unsigned char *buffer; // offscreen buffer
-#endif         
+private:
+    int _fd;
+    int original_vt;       // virtual terminal that was active at startup
+    int original_kd;       // keyboard mode at startup
+    int own_vt;            // virtual terminal we are running in   
 
     std::vector< geometry::Range2d<int> > _drawbounds;
-
+    
     int m_stage_width;
     int m_stage_height;
-    unsigned m_rowsize;
-
-       int input_fd; /// file descriptor for /dev/input/mice
-       int keyb_fd; /// file descriptor for /dev/input/event* (keyboard)
-       int mouse_x, mouse_y, mouse_btn;
-       unsigned char mouse_buf[256];
-       int mouse_buf_size;
-       
-       // Keyboard SHIFT/CTRL/ALT states (left + right)
-       bool keyb_lshift, keyb_rshift, keyb_lctrl, keyb_rctrl, keyb_lalt, 
keyb_ralt;
-
-    struct fb_var_screeninfo var_screeninfo;
-       struct fb_fix_screeninfo fix_screeninfo;
-
-       /// For 8 bit (palette / LUT) modes, sets a grayscale palette.
-       //
-       /// This GUI currently does not support palette modes. 
-       ///
-       bool set_grayscale_lut8();
-       
-       bool initialize_renderer();
-       
-       /// Tries to find a accessible tty
-       char* find_accessible_tty(int no);
-       char* find_accessible_tty(const char* format, int no);
-       
-       /// switches from text mode to graphics mode (disables the text 
terminal)
-       bool disable_terminal();
-       
-       /// reverts disable_terminal() changes
-       bool enable_terminal();
-
+    
+    int input_fd; /// file descriptor for /dev/input/mice
+    int keyb_fd; /// file descriptor for /dev/input/event* (keyboard)
+    int mouse_x, mouse_y, mouse_btn;
+    unsigned char mouse_buf[256];
+    int mouse_buf_size;
+    
+    // Keyboard SHIFT/CTRL/ALT states (left + right)
+    bool keyb_lshift, keyb_rshift, keyb_lctrl, keyb_rctrl, keyb_lalt, 
keyb_ralt;
+    
+    FBGlue *fb_glue;
+    
+    /// Tries to find a accessible tty
+    char* find_accessible_tty(int no);
+    char* find_accessible_tty(const char* format, int no);
+    
+    /// switches from text mode to graphics mode (disables the text terminal)
+    bool disable_terminal();
+    
+    /// reverts disable_terminal() changes
+    bool enable_terminal();
+    
 #ifdef USE_MOUSE_PS2   
-       /// Sends a command to the mouse and waits for the response
-       bool mouse_command(unsigned char cmd, unsigned char *buf, int count);
+    /// Sends a command to the mouse and waits for the response
+    bool mouse_command(unsigned char cmd, unsigned char *buf, int count);
 #endif
-
+    
     /// Fills the mouse data input buffer with fresh data
     void read_mouse_data();    
-       
-       /// Initializes mouse routines
-       bool init_mouse();
-       
-       /// Checks for and processes any mouse activity. Returns true on 
activity.
-       bool check_mouse();
-       
-       /// Initializes keyboard routines 
-       bool init_keyboard();
-               
-       /// Translates a scancode from the Linux Input Subsystem to a Gnash key 
code 
+    
+    /// Initializes mouse routines
+    bool init_mouse();
+    
+    /// Checks for and processes any mouse activity. Returns true on activity.
+    bool check_mouse();
+    
+    /// Initializes keyboard routines 
+    bool init_keyboard();
+    
+    /// Translates a scancode from the Linux Input Subsystem to a Gnash key 
code 
     gnash::key::code scancode_to_gnash_key(int code, bool shift);
-       
-       /// Checks for and processes any keyboard activity. Returns true on 
activity.
-       bool check_keyboard();
-       
+    
+    /// Checks for and processes any keyboard activity. Returns true on 
activity.
+    bool check_keyboard();
+    
 #ifdef USE_INPUT_EVENTS        
     /// Applies builtin touchscreen calibration
-       void apply_ts_calibration(float* cx, float* cy, int rawx, int rawy);
+    void apply_ts_calibration(float* cx, float* cy, int rawx, int rawy);
 #endif
-       
-       int valid_x(int x);
-       int valid_y(int y);
-               
-       public:
-               FBGui(unsigned long xid, float scale, bool loop, RunResources& 
r);
+    
+    int valid_x(int x);
+    int valid_y(int y);
+    
+public:
+    FBGui(unsigned long xid, float scale, bool loop, RunResources& r);
     virtual ~FBGui();
     virtual bool init(int argc, char ***argv);
     virtual bool createWindow(const char *title, int width, int height,
@@ -209,9 +207,21 @@ class FBGui : public Gui
     virtual void setInvalidatedRegions(const InvalidatedRanges& ranges);
     virtual bool want_multiple_regions() { return true; }
 };
-
-// end of namespace gnash
+    
+    // end of namespace gnash
 }
 
+#ifdef ENABLE_FAKE_FRAMEBUFFER
+/// Simulate the ioctls used to get information from the framebuffer driver.
+///
+/// Since this is an emulator, we have to set these fields to a reasonable 
default.
+int
+fakefb_ioctl(int /* fd */, int request, void *data);
 #endif
 
+#endif // end of GNASH_FBSUP_H
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/gui/gtk/gtk.am b/gui/gtk/gtk.am
index 8bbc3bd..78aece7 100644
--- a/gui/gtk/gtk.am
+++ b/gui/gtk/gtk.am
@@ -75,5 +75,13 @@ gtk_gnash_LDADD = 
$(top_builddir)/librender/libgnashrender.la \
                $(GNASH_LIBS) $(GTK_LIBS) $(CAIRO_LIBS)
 endif  # BUILD_CAIRO_RENDERER
 
+if BUILD_OVG_RENDERER
+gtk_gnash_CPPFLAGS += $(OPENVG_CFLAGS) $(EGL_CFLAGS)
+gtk_gnash_SOURCES += gtk/gtk_glue_egl.cpp gtk/gtk_glue_egl.h 
+gtk_gnash_LDADD = $(top_builddir)/librender/libgnashrender.la \
+               $(GNASH_LIBS) $(GTK_LIBS) $(OPENVG_LIBS) $(EGL_LIBS)
+
+endif  # BUILD_OVG_RENDERER
+
 endif  # BUILD_GTK_GUI
 
diff --git a/gui/gtk/gtk_canvas.cpp b/gui/gtk/gtk_canvas.cpp
index 42a57df..e7ea3ea 100644
--- a/gui/gtk/gtk_canvas.cpp
+++ b/gui/gtk/gtk_canvas.cpp
@@ -36,25 +36,29 @@
 // OpenGL support for rendering in the canvas. This also requires
 // the GtkGL widget for GTK2.
 #ifdef HAVE_GTK_GTKGL_H
-#include "gtk_glue_gtkglext.h"
+# include "gtk_glue_gtkglext.h"
+#endif
+
+#ifdef HAVE_VG_OPENVG_H
+# include "gtk_glue_egl.h"
 #endif
 
 // Cairo support for rendering in the canvas.
 #ifdef HAVE_CAIRO_H
-#include "gtk_glue_cairo.h"
+# include "gtk_glue_cairo.h"
 #endif
 
 // This uses the Xv extension to X11, which has widespread support
 // for Hw video scaling.
 #ifdef HAVE_XV
-#include "gtk_glue_agg_xv.h"
+# include "gtk_glue_agg_xv.h"
 #endif
 
 // AGG support, which is the default, for rendering in the canvas.
 #include "gtk_glue_agg.h"
 
 #ifdef HAVE_VA_VA_H
-#include "gtk_glue_agg_vaapi.h"
+# include "gtk_glue_agg_vaapi.h"
 #endif
 
 struct _GnashCanvas
@@ -80,6 +84,7 @@ namespace {
     gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance();
 }
 
+// allocate memory for GtkCanvas
 GtkWidget *
 gnash_canvas_new ()
 {
@@ -87,6 +92,7 @@ gnash_canvas_new ()
     return GTK_WIDGET(g_object_new (GNASH_TYPE_CANVAS, NULL));
 }
 
+// Initialize canvas,set allocate, expose, comfigure, realize event handlers
 static void
 gnash_canvas_class_init(GnashCanvasClass *gnash_canvas_class)
 {
@@ -101,6 +107,7 @@ gnash_canvas_class_init(GnashCanvasClass 
*gnash_canvas_class)
     widget_class->realize = gnash_canvas_realize;
 }
 
+// Disable double bufferinf in the canvas, add reaize event handlers
 static void
 gnash_canvas_init(GnashCanvas *canvas)
 {
@@ -163,6 +170,7 @@ static void
 gnash_canvas_realize(GtkWidget *widget)
 {
     GNASH_REPORT_FUNCTION;
+    
     GnashCanvas *canvas = GNASH_CANVAS(widget);
     GdkWindowAttr attributes;
     gint attributes_mask;
@@ -197,6 +205,7 @@ static void
 gnash_canvas_after_realize(GtkWidget *widget)
 {
     GNASH_REPORT_FUNCTION;
+    
     GnashCanvas *canvas = GNASH_CANVAS(widget);
 
     canvas->renderer.reset(canvas->glue->createRenderHandler());
@@ -205,14 +214,14 @@ gnash_canvas_after_realize(GtkWidget *widget)
                                         widget->allocation.height);
 }
 
+// Select renderer and hwaccel, prep canvas for drawing
 void
 gnash_canvas_setup(GnashCanvas *canvas, std::string& hwaccel,
         std::string& renderer, int argc, char **argv[])
 {
-
     GNASH_REPORT_FUNCTION;
 
-    // Order should be VAAPI, Xv, X11
+    // Order should be VAAPI, Xv, Omap
     bool initialized_renderer = false;
 
     // If a renderer hasn't been defined in gnashrc, or on the command
@@ -230,6 +239,7 @@ gnash_canvas_setup(GnashCanvas *canvas, std::string& 
hwaccel,
     std::string next_hwaccel = hwaccel;
 
     while (!initialized_renderer) {
+        gnash::log_debug("Trying Renderer %s, and HWAccel %s", renderer, 
hwaccel);
         renderer = next_renderer;
         hwaccel = next_hwaccel;
 #ifdef HAVE_VA_VA_H
@@ -262,6 +272,17 @@ gnash_canvas_setup(GnashCanvas *canvas, std::string& 
hwaccel,
             // rendering performance issues.
         }
 #endif
+#ifdef RENDERER_OPENVG
+       // Use OpenVG, which uses EGL as the display API. This works with
+       // Mesa on desktop unix systems, and on ARM based devices running
+       // Linux, often with manufacturer provided SDKs.
+        if (renderer == "openvg") {
+            canvas->glue.reset(new gnash::GtkEGLGlue);
+            // Set the renderer to the next one to try if initializing
+            // fails.
+            next_renderer = "agg";
+        }
+#endif
         if (renderer == "agg") {
             // Use LibVva, which works on Nvidia, AT, or Intel 965 GPUs
             // with AGG or OpenGL.
@@ -297,9 +318,13 @@ gnash_canvas_setup(GnashCanvas *canvas, std::string& 
hwaccel,
                 (hwaccel == "none")) {
             break;
         }
+        if (!initialized_renderer) {
+            gnash::log_debug("Trying to find new Renderer %s, and HWAccel %s",
+                             renderer, hwaccel);
+        }
     }
         
-    if (initialized_renderer && renderer == "opengl") {
+    if (initialized_renderer && (renderer == "opengl" || renderer == 
"openvg")) {
         // OpenGL glue needs to prepare the drawing area for OpenGL
         // rendering before
         // widgets are realized and before the configure event is fired.
@@ -312,12 +337,16 @@ gnash_canvas_setup(GnashCanvas *canvas, std::string& 
hwaccel,
 void
 gnash_canvas_before_rendering(GnashCanvas *canvas)
 {
+    // GNASH_REPORT_FUNCTION;
+
     canvas->glue->beforeRendering();
 }
 
 boost::shared_ptr<gnash::Renderer>
 gnash_canvas_get_renderer(GnashCanvas *canvas)
 {
+    // GNASH_REPORT_FUNCTION;
+
     return canvas->renderer;
 }
 
diff --git a/gui/gtk/gtk_canvas.h b/gui/gtk/gtk_canvas.h
index 15684df..caa66f9 100644
--- a/gui/gtk/gtk_canvas.h
+++ b/gui/gtk/gtk_canvas.h
@@ -36,7 +36,7 @@ typedef struct _GnashCanvasClass       GnashCanvasClass;
 
 #define GNASH_TYPE_CANVAS              (gnash_canvas_get_type())
 #define GNASH_CANVAS(object)           (G_TYPE_CHECK_INSTANCE_CAST((object), 
GNASH_TYPE_CANVAS, GnashCanvas))
-#define GNASH_CANVAS_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST((klass), 
GNASH_TYPE_CANVAS, GnashCanvasClass))
+#define GNASH_CANVAS_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), 
GNASH_TYPE_CANVAS, GnashCanvasClass))
 #define GNASH_IS_CANVAS(object)        (G_TYPE_CHECK_INSTANCE_TYPE((object), 
GNASH_TYPE_CANVAS))
 #define GNASH_IS_CANVAS_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), 
GNASH_TYPE_CANVAS))
 #define GNASH_CANVAS_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), 
GNASH_TYPE_CANVAS, GnashCanvasClass))
@@ -45,12 +45,19 @@ struct _GnashCanvasClass {
     GtkDrawingAreaClass base_class;
 };
 
-GType            gnash_canvas_get_type              ();
-GtkWidget       *gnash_canvas_new                   ();
+GType gnash_canvas_get_type();
 
-void             gnash_canvas_setup                 (GnashCanvas *canvas, 
std::string &hwaccel, std::string &renderer, int argc, char **argv[]);
-void             gnash_canvas_before_rendering      (GnashCanvas *canvas);
-boost::shared_ptr<gnash::Renderer>  gnash_canvas_get_renderer   (GnashCanvas 
*canvas);
+/// allocate memory for canvas to draw in
+GtkWidget *gnash_canvas_new();
+
+/// Select renderer and hwaccel, prep canvas for drawing
+void gnash_canvas_setup (GnashCanvas *canvas, std::string &hwaccel,
+                         std::string &renderer, int argc, char **argv[]);
+
+void gnash_canvas_before_rendering (GnashCanvas *canvas);
+
+/// Get the Renderer for this canvas
+boost::shared_ptr<gnash::Renderer> gnash_canvas_get_renderer(GnashCanvas 
*canvas);
 
 G_END_DECLS
 
diff --git a/gui/gtk/gtk_glue_cairo.cpp b/gui/gtk/gtk_glue_cairo.cpp
index 7729179..ad6b9e7 100644
--- a/gui/gtk/gtk_glue_cairo.cpp
+++ b/gui/gtk/gtk_glue_cairo.cpp
@@ -53,6 +53,8 @@ void
 GtkCairoGlue::prepDrawingArea(GtkWidget *drawing_area)
 {
     _drawing_area = drawing_area;
+    // Disable double buffering, otherwise gtk tries to update widget
+    // contents from its internal offscreen buffer at the end of expose event
     gtk_widget_set_double_buffered(_drawing_area, FALSE);
 }
 
diff --git a/gui/gtk/gtk_glue_egl.cpp b/gui/gtk/gtk_glue_egl.cpp
new file mode 100644
index 0000000..112563a
--- /dev/null
+++ b/gui/gtk/gtk_glue_egl.cpp
@@ -0,0 +1,747 @@
+//
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+//   Foundation, Inc
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <cerrno>
+#include <exception>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gnash.h"
+#include "log.h"
+#include "RunResources.h"
+#include "Renderer.h"
+#include "Renderer_ovg.h"
+#include "gtk_glue_egl.h"
+#include "GnashException.h"
+
+#ifdef HAVE_VG_OPENVG_H
+#include <VG/openvg.h>
+#endif
+
+#ifdef HAVE_EGL_EGL_H
+# include <EGL/egl.h>
+#else
+# error "This file needs EGL, which is part of OpenGL-ES"
+#endif
+
+#include <GL/gl.h>
+
+namespace gnash
+{
+
+static const EGLint attrib32_list[] = {
+    EGL_RED_SIZE,       8,
+    EGL_GREEN_SIZE,     8,
+    EGL_BLUE_SIZE,      8,
+    EGL_ALPHA_SIZE,     0,
+#ifdef RENDERER_GLES    
+    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+#endif
+#ifdef RENDERER_OPENVG
+    EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
+    EGL_DEPTH_SIZE,     24,
+    EGL_STENCIL_SIZE,   8,
+#endif
+    EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
+    EGL_NONE
+};
+
+static EGLint const attrib16_list[] = {
+    EGL_RED_SIZE,       5,
+    EGL_GREEN_SIZE,     6,
+    EGL_BLUE_SIZE,      5,
+    EGL_ALPHA_SIZE,     0,
+#ifdef RENDERER_GLES    
+    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+#endif
+#ifdef RENDERER_OPENVG
+    EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
+    EGL_DEPTH_SIZE,     0,
+    EGL_STENCIL_SIZE,   0,
+#endif
+    EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
+    EGL_SAMPLE_BUFFERS, 0,
+    EGL_NONE
+};
+
+const EGLint window_attrib_list[] = {
+    // Back buffering is used for window and pbuffer surfaces. Windows
+    // require eglSwapBuffers() to become visible, and pbuffers don't.   
+    // EGL_SINGLE_BUFFER is by pixmap surfaces. With OpenVG, windows
+    // can also be single buffered. eglCopyBuffers() can be used to copy
+    // both back and single buffered surfaces to a pixmap.
+    EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
+    EGL_COLORSPACE,    EGL_COLORSPACE_sRGB,
+    EGL_NONE
+};
+
+// From the EGL 1.4 spec:
+//
+// EGL defines several types of drawing surfaces collectively referred
+// to as EGLSurfaces. These include windows, used for onscreen
+// rendering; pbuffers, used for offscreen rendering; and pixmaps,
+// used for offscreen rendering into buffers that may be accessed
+// through native APIs. EGL windows and pixmaps are tied to native
+// window system windows and pixmaps.
+//
+// depth, multisample, and stencil buffers are currently used only by
+// OpenGL-ES.
+
+// EGL and OpenGL ES supports two rendering models: back buffered and
+// single buffered. Back buffered rendering is used by window and
+// pbuffer surfaces. Memory for the color buffer used during rendering
+// is allocated and owned by EGL. When the client is finished drawing
+// a frame, the back buffer may be copied to a visible window using
+// eglSwapBuffers. Pbuffer surfaces have a back buffer but no
+// associated window, so the back buffer need not be copied.
+//
+// Single buffered rendering is used by pixmap surfaces. Memory for
+// the color buffer is specified at surface creation time in the form
+// of a native pixmap, and client APIs are required to use that memory
+// during rendering. When the client is finished drawing a frame, the
+// native pixmap contains the final image. Pixmap surfaces typically
+// do not support multisampling, since the native pixmap used as the
+// color buffer is unlikely to provide space to store multisample
+// information. Some client APIs , such as OpenGL and OpenVG , also
+// support single buffered rendering to window surfaces. This behavior
+// can be selected when creating the window surface, as defined in
+// section 3.5.1. When mixing use of client APIs which do not support
+// single buffered rendering into windows, like OpenGL ES , with
+// client APIs which do support it, back color buffers and visible
+// window contents must be kept consistent when binding window
+// surfaces to contexts for each API type. Both back and single
+// buffered surfaces may also be copied to a specified native pixmap
+// using eglCopyBuffers.
+
+// Native rendering will always be supported by pixmap surfaces (to
+// the extent that native rendering APIs can draw to native
+// pixmaps). Pixmap surfaces are typically used when mixing native and
+// client API rendering is desirable, since there is no need to move
+// data between the back buffer visible to the client APIs and the
+// native pixmap visible to native rendering APIs. However, pixmap
+// surfaces may, for the same reason, have restricted capabilities and
+// performance relative to window and pbuffer surfaces.
+
+GtkEGLGlue::GtkEGLGlue()
+:   _offscreenbuf(0),
+    _renderer(0),
+    _eglConfig(0),
+    _eglContext(EGL_NO_CONTEXT),
+    _eglSurface(EGL_NO_SURFACE),
+    _eglDisplay(EGL_NO_DISPLAY),
+    _eglNumOfConfigs(0),
+    _nativeWindow(0),
+    _max_num_config(1),
+    _bpp(32),
+    _width(0),
+    _height(0)
+{
+    GNASH_REPORT_FUNCTION;
+}
+
+GtkEGLGlue::~GtkEGLGlue()
+{
+    GNASH_REPORT_FUNCTION;
+
+#ifdef ENABLE_EGL_OFFSCREEN
+    if (_offscreenbuf) {
+        gdk_image_destroy(_offscreenbuf);
+    }
+#endif    
+    if (_eglDisplay != EGL_NO_DISPLAY) {  
+        eglMakeCurrent(_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 
EGL_NO_CONTEXT);
+        
+        if (_eglContext != EGL_NO_CONTEXT)
+            eglDestroyContext(_eglDisplay, _eglContext);
+        
+        if (_eglSurface != EGL_NO_SURFACE)
+            eglDestroySurface(_eglDisplay, _eglSurface);
+        
+        // if (_eglwin_native)
+        //     free(_eglwin_native);
+        
+        eglTerminate(_eglDisplay);
+    }
+}
+
+bool
+GtkEGLGlue::init(int /*argc*/, char ** /*argv*/[])
+{
+    GNASH_REPORT_FUNCTION;
+    
+    EGLint major, minor;
+    // see egl_config.c for a list of supported configs, this looks for
+    // a 5650 (rgba) config, supporting OpenGL ES and windowed surfaces
+
+    // step 1 - get an EGL display
+    
+    // This can be called multiple times, and always returns the same display
+    _eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); // FIXME: gdk_display ?
+    if (EGL_NO_DISPLAY == _eglDisplay) {
+        log_error( "eglGetDisplay() failed (error 0x%x)", eglGetError() );
+        return false;
+    }
+
+    // This can be called multiple times safely
+    if (EGL_FALSE == eglInitialize(_eglDisplay, &major, &minor)) {
+        log_error( "eglInitialize() failed (error %s)",
+                   getErrorString(eglGetError()));
+        return false;
+    }
+    // log_debug("EGL_CLIENT_APIS = %s", eglQueryString(_eglDisplay, 
EGL_CLIENT_APIS));
+    // log_debug("EGL_EXTENSIONS = %s",  eglQueryString(_eglDisplay, 
EGL_EXTENSIONS));
+    log_debug("EGL_VERSION = %s, EGL_VENDOR = %s",
+              eglQueryString(_eglDisplay, EGL_VERSION),
+              eglQueryString(_eglDisplay, EGL_VENDOR));
+
+    // step2 - bind to the wanted client API
+#ifdef  RENDERER_GLES
+    if(EGL_FALSE == eglBindAPI(EGL_OPENGL_ES_API)) {
+        log_error("eglBindAPI() failed to retrive the number of configs (error 
%s)",
+                  getErrorString(eglGetError()));
+        return false;
+    }
+#endif
+#ifdef RENDERER_OPENVG
+    if(EGL_FALSE == eglBindAPI(EGL_OPENVG_API)) {
+        log_error("eglBindAPI() failed to retrive the number of configs (error 
%s)",
+                  getErrorString(eglGetError()));
+        return false;
+    }
+#endif
+
+//    queryEGLConfig(_eglDisplay);
+    
+    // step3 - find a suitable config
+    if (_bpp == 32) {
+        if (EGL_FALSE == eglChooseConfig(_eglDisplay, attrib32_list, 
&_eglConfig,
+                                          1, &_eglNumOfConfigs)) {
+            log_error("eglChooseConfig() failed (error %s)", 
+                       getErrorString(eglGetError()));
+            return false;
+        }
+    } else if (_bpp == 16) {
+        if (EGL_FALSE == eglChooseConfig(_eglDisplay, attrib16_list, 
&_eglConfig,
+                                         1, &_eglNumOfConfigs)) {
+            log_error("eglChooseConfig() failed (error %s)",
+                       getErrorString(eglGetError()));
+            return false;
+        }
+    } else {
+        log_error("No supported bpp value!");
+    }
+
+    if (0 == _eglNumOfConfigs) {
+        log_error("eglChooseConfig() was unable to find a suitable config");
+        return false;
+    }
+
+    EGLint vid;
+    if (!eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_NATIVE_VISUAL_ID, 
&vid)) {
+        log_error("eglGetConfigAttrib() failed (error %s)",
+                  getErrorString(eglGetError()));
+        return false;
+    }
+    
+    XVisualInfo *visInfo, visTemplate;
+    int num_visuals;
+    // The X window visual must match the EGL config
+   visTemplate.visualid = vid;
+   visInfo = XGetVisualInfo(gdk_display, VisualIDMask, &visTemplate, 
&num_visuals);
+   if (!visInfo) {
+       log_error("couldn't get X visual");
+       return false;
+   }
+   XFree(visInfo);
+    
+   if (!checkEGLConfig(_eglConfig)) {
+       log_error("EGL configuration doesn't match!");
+//       return false;
+   } else {
+       //printEGLConfig(_eglConfig);
+   }
+
+    // step4 - create a window surface
+    _nativeWindow = gdk_x11_get_default_root_xwindow();
+    
+
+#ifdef  RENDERER_GLES
+    _eglSurface = eglCreateWindowSurface(_eglDisplay, &_eglConfig, 
_nativeWindow, NULL);
+#endif
+#ifdef  RENDERER_OPENVG
+    if (_nativeWindow) {
+        _eglSurface = eglCreateWindowSurface(_eglDisplay, _eglConfig,
+                                             _nativeWindow, 0); // was 
window_attrib_list
+    } else {
+        log_error("No native window!");
+        return false;
+    }
+#endif
+
+    if (EGL_NO_SURFACE == _eglSurface) {
+        log_error("eglCreateWindowSurface failed (error %s)", 
+                  getErrorString(eglGetError()));
+        return false;
+    } else {
+        //printEGLSurface(_eglSurface);
+    }
+
+    // step5 - create a context
+    _eglContext = eglCreateContext(_eglDisplay, _eglConfig, EGL_NO_CONTEXT, 
NULL);
+    if (EGL_NO_CONTEXT == _eglContext) {
+        log_error("eglCreateContext failed (error %s)",
+                   getErrorString(eglGetError()));
+        return false;
+    } else {
+        printEGLContext(_eglContext);
+    }
+    
+    // step6 - make the context and surface current
+    if (EGL_FALSE == eglMakeCurrent(_eglDisplay, _eglSurface, _eglSurface, 
_eglContext)) {
+        log_error("eglMakeCurrent failed (error %s)",
+                  getErrorString(eglGetError()));
+        return false;
+    }       // begin user code
+
+#if 0
+#if 1
+    eglSwapInterval(_eglDisplay, 0);
+#else
+    eglSwapBuffers(_eglDisplay, _eglSurface);
+#endif
+
+    log_debug("Gnash EGL Frame width %d height %d bpp %d \n", _width, _height, 
_bpp);
+#endif
+    
+    return true;
+}
+
+void
+GtkEGLGlue::prepDrawingArea(GtkWidget *drawing_area)
+{
+    GNASH_REPORT_FUNCTION;
+
+    _drawing_area = drawing_area;
+
+    // Disable double buffering, otherwise gtk tries to update widget
+    // contents from its internal offscreen buffer at the end of expose event
+    gtk_widget_set_double_buffered(_drawing_area, FALSE);
+
+    DUMP_CURRENT_SURFACE;
+    DUMP_CURRENT_CONTEXT;
+}
+
+Renderer*
+GtkEGLGlue::createRenderHandler()
+{
+    GNASH_REPORT_FUNCTION;
+
+    if (!_drawing_area) {
+        log_error("No area to draw in!");
+        return 0;
+    }
+    
+    GdkVisual* wvisual = gdk_drawable_get_visual(_drawing_area->window);
+
+    GdkImage* tmpimage = gdk_image_new (GDK_IMAGE_FASTEST, wvisual, 1, 1);
+
+    const GdkVisual* visual = tmpimage->visual;
+
+    // FIXME: we use bpp instead of depth, because depth doesn't appear to
+    // include the padding byte(s) the GdkImage actually has.
+    const char *pixelformat = 0;
+    // agg_detect_pixel_format(visual->red_shift, visual->red_prec,
+    // visual->green_shift, visual->green_prec, visual->blue_shift, 
visual->blue_prec,
+    // tmpimage->bpp * 8);
+
+    gdk_image_destroy(tmpimage);
+
+    _renderer = create_Renderer_ovg(pixelformat);
+    if (! _renderer) {
+        boost::format fmt = boost::format(
+            _("Could not create OPENVG renderer with pixelformat %s")
+            ) % pixelformat;
+        throw GnashException(fmt.str());
+    }
+
+    return _renderer;
+}
+
+void
+GtkEGLGlue::setRenderHandlerSize(int width, int height)
+{
+    GNASH_REPORT_FUNCTION;
+
+    assert(width > 0);
+    assert(height > 0);
+    assert(_renderer != NULL);
+    
+#ifdef ENABLE_EGL_OFFSCREEN
+    if (_offscreenbuf && _offscreenbuf->width == width &&
+        _offscreenbuf->height == height) {
+        return; 
+    }
+
+    if (_offscreenbuf) {
+        gdk_image_destroy(_offscreenbuf);
+    }
+
+    GdkVisual* visual = gdk_drawable_get_visual(_drawing_area->window);
+
+    _offscreenbuf = gdk_image_new (GDK_IMAGE_FASTEST, visual, width,
+                                   height);
+    
+    static_cast<Renderer_ovg_base *>(_renderer)->init_buffer(
+        (unsigned char*) _offscreenbuf->mem,
+        _offscreenbuf->bpl * _offscreenbuf->height,
+        _offscreenbuf->width,
+        _offscreenbuf->height,
+        _offscreenbuf->bpl);
+#else
+        _renderer->init(width, height);
+#endif
+}
+
+void 
+GtkEGLGlue::beforeRendering()
+{
+    GNASH_REPORT_FUNCTION;
+
+#ifdef ENABLE_EGL_OFFSCREEN
+    if (_offscreenbuf && _offscreenbuf->type == GDK_IMAGE_SHARED) {
+         gdk_flush();
+    }
+#endif
+}
+
+void
+GtkEGLGlue::render()
+{
+    GNASH_REPORT_FUNCTION;
+
+#if 0
+    // clear the color buffer
+    glClearColor(1.0, 1.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glFlush();
+#endif
+
+#ifdef ENABLE_EGL_OFFSCREEN
+    if ( _drawbounds.size() == 0 ) {
+        return; // nothing to do
+    }
+
+    if (!_offscreenbuf) {
+        log_error("No off screen buffer!");
+        return;
+    }
+    
+    render(0, 0, _offscreenbuf->width, _offscreenbuf->height);
+#else
+    render(0, 0, _width, _height);
+#endif
+}
+
+void
+GtkEGLGlue::render(int minx, int miny, int maxx, int maxy)
+{
+    GNASH_REPORT_FUNCTION;
+
+#ifdef ENABLE_EGL_OFFSCREEN
+    if (!_offscreenbuf) {
+        log_error("No off screen buffer!");
+        return;
+    }
+    
+    const int& x = minx;
+    const int& y = miny;
+    size_t width = std::min(_offscreenbuf->width, maxx - minx);
+    size_t height = std::min(_offscreenbuf->height, maxy - miny);
+    
+    GdkGC* gc = gdk_gc_new(_drawing_area->window);
+    
+    gdk_draw_image(_drawing_area->window, gc, _offscreenbuf, x, y, x, y, width,
+                   height);
+    gdk_gc_unref(gc);
+#else
+    eglSwapBuffers(_eglDisplay, _eglSurface);
+#endif
+}
+
+void
+GtkEGLGlue::configure(GtkWidget *const /*widget*/, GdkEventConfigure *const 
event)
+{
+    GNASH_REPORT_FUNCTION;
+
+    if (_renderer) {
+        setRenderHandlerSize(event->width, event->height);
+    }
+}
+
+const char *
+GtkEGLGlue::getErrorString(int error)
+{
+    switch (error) {
+    case EGL_SUCCESS:
+        return "EGL_SUCCESS";
+    case EGL_NOT_INITIALIZED:
+        return "EGL_NOT_INITIALIZED";
+    case EGL_BAD_ACCESS:
+        return "EGL_BAD_ACCESS";
+    case EGL_BAD_ALLOC:
+        return "EGL_BAD_ALLOC";
+    case EGL_BAD_ATTRIBUTE:
+        return "EGL_BAD_ATTRIBUTE";
+    case EGL_BAD_CONFIG:
+        return "EGL_BAD_CONFIG";
+    case EGL_BAD_CONTEXT:
+        return "EGL_BAD_CONTEXT";
+    case EGL_BAD_CURRENT_SURFACE:
+        return "EGL_BAD_CURRENT_SURFACE";
+    case EGL_BAD_DISPLAY:
+        return "EGL_BAD_DISPLAY";
+    case EGL_BAD_MATCH:
+        return "EGL_BAD_MATCH";
+    case EGL_BAD_NATIVE_PIXMAP:
+        return "EGL_BAD_NATIVE_PIXMAP";
+    case EGL_BAD_NATIVE_WINDOW:
+        return "EGL_BAD_NATIVE_WINDOW";
+    case EGL_BAD_PARAMETER:
+        return "EGL_BAD_PARAMETER";
+    case EGL_BAD_SURFACE:
+        return "EGL_BAD_SURFACE";
+    case EGL_CONTEXT_LOST:
+        return "EGL_CONTEXT_LOST";
+    default:
+        return "unknown error code";
+    }
+}
+
+bool
+GtkEGLGlue::checkEGLConfig(EGLConfig config)
+{
+    // GNASH_REPORT_FUNCTION;
+    
+    // Use this to explicitly check that the EGL config has the expected color 
depths
+    EGLint value;
+    if (_bpp == 32) {            
+        eglGetConfigAttrib(_eglDisplay, config, EGL_RED_SIZE, &value);
+        if (8 != value) {
+            return false;
+        }
+        eglGetConfigAttrib(_eglDisplay, config, EGL_GREEN_SIZE, &value);
+        if (8 != value) {
+            return false;
+        }
+        eglGetConfigAttrib(_eglDisplay, config, EGL_BLUE_SIZE, &value);
+        if (8 != value) {
+            return false;
+        }
+        eglGetConfigAttrib(_eglDisplay, config, EGL_ALPHA_SIZE, &value);
+        if (8 != value) {
+            return false;
+        }
+        eglGetConfigAttrib(_eglDisplay, config, EGL_SAMPLES, &value);
+        if (0 != value) {
+            return false;
+        }
+    } else if (_bpp == 16) {
+        eglGetConfigAttrib(_eglDisplay, config, EGL_RED_SIZE, &value);
+        if ( 5 != value ) {
+            return false;
+        }
+        eglGetConfigAttrib(_eglDisplay, config, EGL_GREEN_SIZE, &value);
+        if (6 != value) {
+            return false;
+        }
+        eglGetConfigAttrib(_eglDisplay, config, EGL_BLUE_SIZE, &value);
+        if (5 != value) {
+            return false;
+        }
+        eglGetConfigAttrib(_eglDisplay, config, EGL_ALPHA_SIZE, &value);
+        if (0 != value) {
+            return false;
+        }
+        eglGetConfigAttrib(_eglDisplay, config, EGL_SAMPLES, &value);
+#ifdef  RENDERER_GLES            
+        if (4 != value) {
+            return false;
+        }
+#endif
+#ifdef  RENDERER_OPENVG
+        if (0 != value) {
+            return false;
+            }
+#endif
+    } else {
+        return false;
+    }
+
+    return true;
+}
+
+/// Query the system for all supported configs
+int
+GtkEGLGlue::queryEGLConfig(EGLDisplay display)
+{
+     GNASH_REPORT_FUNCTION;
+     EGLConfig *configs = 0;
+     EGLint max_num_config = 0;
+
+     // Get the number of supported configurations
+     if ( EGL_FALSE == eglGetConfigs(display, 0, 0, &max_num_config) ) {
+         log_error("eglGetConfigs() failed to retrive the number of configs 
(error %s)",
+                   getErrorString(eglGetError()));
+         return 0;
+     }
+     if(max_num_config <= 0) {
+         printf( "No EGLconfigs found\n" );
+         return 0;
+     }
+     log_debug("Max number of EGL Configs is %d", max_num_config);     
+     
+     configs = new EGLConfig[max_num_config];
+     if (0 == configs) {
+         log_error( "Out of memory\n" );
+         return 0;
+     }
+
+     if ( EGL_FALSE == eglGetConfigs(display, configs, max_num_config, 
&max_num_config)) {
+         log_error("eglGetConfigs() failed to retrive the configs (error %s)",
+                   getErrorString(eglGetError()));
+         return 0;
+     }
+     for (int i=0; i<max_num_config; i++ ) {
+         log_debug("Config[%d] is:", i);
+         printEGLConfig(configs[i]);
+     }
+
+     return max_num_config;
+}
+
+void
+GtkEGLGlue::printEGLConfig(EGLConfig config)
+{
+    EGLint red, blue, green;
+    EGLint value;
+    eglGetConfigAttrib(_eglDisplay, config, EGL_RED_SIZE, &red);
+    eglGetConfigAttrib(_eglDisplay, config, EGL_GREEN_SIZE, &green);
+    eglGetConfigAttrib(_eglDisplay, config, EGL_BLUE_SIZE, &blue);
+    log_debug("\tConfig has RED = %d, GREEN = %d, BLUE = %d", red, green, 
blue);
+    
+    eglGetConfigAttrib(_eglDisplay, config, EGL_ALPHA_SIZE, &value);
+    log_debug("\tEGL_ALPHA_SIZE is %d", value);
+    eglGetConfigAttrib(_eglDisplay, config, EGL_STENCIL_SIZE, &value);
+    log_debug("\tEGL_STENCIL_SIZE is %d", value);
+    eglGetConfigAttrib(_eglDisplay, config, EGL_SAMPLES, &value);
+    log_debug("\tEGL_SAMPLES is %d", value);
+    eglGetConfigAttrib(_eglDisplay, config, EGL_DEPTH_SIZE, &value);
+    log_debug("\tEGL_DEPTH_SIZE is %d", value);
+    eglGetConfigAttrib(_eglDisplay, config, EGL_MAX_SWAP_INTERVAL, &value);
+    log_debug("\tEGL_MAX_SWAP_INTERVAL is %d", value);
+    eglGetConfigAttrib(_eglDisplay, config, EGL_MIN_SWAP_INTERVAL, &value);
+    log_debug("\tEGL_MIN_SWAP_INTERVAL is %d", value);
+    eglGetConfigAttrib(_eglDisplay, config, EGL_NATIVE_RENDERABLE, &value);
+    log_debug("\tEGL_NATIVE_RENDERABLE is %s", (value)? "true" : "false");
+    eglGetConfigAttrib(_eglDisplay, config, EGL_SAMPLE_BUFFERS, &value);
+    log_debug("\tEGL_SAMPLE_BUFFERS is %d", value);
+    eglGetConfigAttrib(_eglDisplay, config, EGL_RENDERABLE_TYPE, &value);
+    if (value > 0) {
+        std::string str;
+        if (value & EGL_OPENGL_ES_BIT) {
+            str += " OpenGL-ES 1.1";
+        }
+        if (value & EGL_OPENVG_BIT) {
+            str += " OpenVG";
+        }
+        if (value & EGL_OPENGL_BIT) {
+            str += " OpenGL";
+        }
+        log_debug("\tEGL_RENDERABLE_TYPE = %s", str);
+    } else {
+        log_debug("\tEGL_RENDERABLE_TYPE (default)");
+    }
+    eglGetConfigAttrib(_eglDisplay, config, EGL_SURFACE_TYPE, &value);
+    if (value > 0) {
+        std::string str;
+        if (value & EGL_WINDOW_BIT) {
+            str += " Window";
+        }
+        if (value & EGL_PIXMAP_BIT) {
+            str += " Pixmap";
+        }
+        if (value & EGL_PBUFFER_BIT) {
+            str += " Pbuffer";
+        }
+        log_debug("\tEGL_SURFACE_TYPE = %s", str);
+    } else {
+        log_debug("\tEGL_SURFACE_TYPE (default)");
+    }
+}
+
+void
+GtkEGLGlue::printEGLContext(EGLContext context)
+{
+    EGLint value;
+    eglQueryContext(_eglDisplay, context, EGL_CONFIG_ID, &value);
+    log_debug("Context EGL_CONFIG_ID is %d", value);
+    eglQueryContext(_eglDisplay, context, EGL_CONTEXT_CLIENT_TYPE, &value);
+    log_debug("\tEGL_CONTEXT_CLIENT_TYPE is %d", (value == EGL_OPENVG_API)
+              ? "EGL_OPENVG_API" : "EGL_OPENGL_ES_API");
+    // eglQueryContext(_eglDisplay, context, EGL_CONTEXT_CLIENT_VERSION, 
&value);
+    // log_debug("EGL_CONTEXT_CLIENT_VERSION is %d", value);
+    eglQueryContext(_eglDisplay, context, EGL_RENDER_BUFFER, &value);
+    log_debug("\tEGL_RENDER_BUFFER is %s", (value == EGL_BACK_BUFFER)
+              ? "EGL_BACK_BUFFER" : "EGL_SINGLE_BUFFER");
+}
+
+void
+GtkEGLGlue::printEGLSurface(EGLSurface surface)
+{
+    EGLint value;
+    eglQuerySurface(_eglDisplay, surface, EGL_CONFIG_ID, &value);
+    log_debug("Surface EGL_CONFIG_ID is %d", value);
+    eglQuerySurface(_eglDisplay, surface, EGL_HEIGHT, &value);
+    log_debug("\tEGL_HEIGHT is %d", value);
+    eglQuerySurface(_eglDisplay, surface, EGL_WIDTH, &value);
+    log_debug("\tEGL_WIDTH is %d", value);
+    eglQuerySurface(_eglDisplay, surface, EGL_RENDER_BUFFER, &value);
+    log_debug("\tEGL_RENDER_BUFFER is %s", (value == EGL_BACK_BUFFER)
+              ? "EGL_BACK_BUFFER" : "EGL_SINGLE_BUFFER");
+    eglQuerySurface(_eglDisplay, surface, EGL_VERTICAL_RESOLUTION, &value);
+    log_debug("\tEGL_VERTICAL_RESOLUTION is %d", value);
+    eglQuerySurface(_eglDisplay, surface, EGL_HORIZONTAL_RESOLUTION, &value);
+    log_debug("\tEGL_HORIZONTAL_RESOLUTION is %d", value);
+    eglQuerySurface(_eglDisplay, surface, EGL_SWAP_BEHAVIOR, &value);
+    log_debug("\tEGL_SWAP_BEHAVIOR is %d", (value == EGL_BUFFER_DESTROYED)
+              ? "EGL_BUFFER_DESTROYED" : "EGL_BUFFER_PRESERVED");
+    eglQuerySurface(_eglDisplay, surface, EGL_MULTISAMPLE_RESOLVE, &value);
+    log_debug("\tEGL_MULTISAMPLE_RESOLVE is %d", (value == 
EGL_MULTISAMPLE_RESOLVE_BOX)
+              ? "EGL_MULTISAMPLE_RESOLVE_BOX" : 
"EGL_MULTISAMPLE_RESOLVE_DEFAULT");
+}
+
+} // namespace gnash
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/gui/gtk/gtksup.h b/gui/gtk/gtksup.h
index 1f5a470..60c97ce 100644
--- a/gui/gtk/gtksup.h
+++ b/gui/gtk/gtksup.h
@@ -47,7 +47,6 @@ extern "C" {
 namespace gnash
 {
 
-
 class GtkGui : public Gui
 {
 public:
@@ -187,3 +186,8 @@ private:
 } // namespace gnash
 
 #endif
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
diff --git a/librender/Makefile.am b/librender/Makefile.am
index f6f0165..1c6ecd4 100644
--- a/librender/Makefile.am
+++ b/librender/Makefile.am
@@ -16,7 +16,6 @@
 #   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #
 
-
 ## Process this file with automake to generate Makefile.in
 
 AUTOMAKE_OPTIONS =
@@ -58,8 +57,10 @@ GNASH_LIBS = \
 
 noinst_HEADERS = \
        Renderer.h \
+       Renderer_ovg.h \
        Renderer_agg.h \
        Renderer_agg_bitmap.h \
+       Renderer_ovg_bitmap.h \
        Renderer_agg_style.h \
        Renderer_cairo.h \
        Renderer_ogl.h \
@@ -79,6 +80,11 @@ libgnashrender_la_SOURCES += Renderer_agg.cpp
 libgnashrender_la_LIBADD += $(AGG_LIBS) $(LIBVA)
 endif
 
+if  BUILD_OVG_RENDERER
+libgnashrender_la_SOURCES += Renderer_ovg.cpp 
+libgnashrender_la_LIBADD += $(AGG_LIBS) $(LIBVA)
+endif
+
 if  BUILD_CAIRO_RENDERER
 libgnashrender_la_SOURCES += Renderer_cairo.cpp
 libgnashrender_la_LIBADD += $(CAIRO_LIBS)
@@ -92,7 +98,6 @@ mudflap:
 clean-hook:
        -rm -f core.*
 
-
 if ENABLE_PCH
 AM_CXXFLAGS = $(PCH_FLAGS)
 endif

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


hooks/post-receive
-- 
Gnash



reply via email to

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