diff -Naur ../MPlayer-1.0rc2/configure ./configure
--- ../MPlayer-1.0rc2/configure	2007-10-07 21:49:33.000000000 +0200
+++ ./configure	2007-10-10 13:07:05.000000000 +0200
@@ -373,6 +373,7 @@
   --enable-x11             enable X11 video output [autodetect]
   --enable-xshape          enable XShape support [autodetect]
   --enable-fbdev           enable FBDev video output [autodetect]
+  --enable-rolf            enable ROLF video output [autodetect]
   --enable-mlib            enable mediaLib video output (Solaris) [disable]
   --enable-3dfx            enable obsolete /dev/3dfx video output [disable]
   --enable-tdfxfb          enable tdfxfb video output [disable]
@@ -544,6 +545,7 @@
 _svga=auto
 _vesa=auto
 _fbdev=auto
+_rolf=auto
 _dvb=auto
 _dvbhead=auto
 _dxr2=auto
@@ -857,6 +859,8 @@
   --disable-vesa)	_vesa=no	;;
   --enable-fbdev)	_fbdev=yes	;;
   --disable-fbdev)	_fbdev=no	;;
+  --enable-rolf)	_rolf=yes	;;
+  --disable-rolf)	_rolf=no	;;
   --enable-dvb)		_dvb=yes	;;
   --disable-dvb)        _dvb=no		;;
   --enable-dvbhead)	_dvbhead=yes	;;
@@ -4443,6 +4447,30 @@
 echores "$_fbdev"
 
 
+echocheck "ROLF"
+if test "$_rolf" = auto ; then
+  _rolf=no
+cat > $TMPC << EOF
+#include "rolf/app/rolf_raw.h"
+int main(void) {
+  return 0;
+}
+EOF
+  _rolf=no
+  cc_check -lRolfApp -lRolfImage $_ld_lm && _rolf=yes
+fi
+if test "$_rolf" = yes ; then
+  _def_rolf='#define HAVE_ROLF 1'
+  _vosrc="$_vosrc vo_rolf.c "
+  _libs_mplayer="$_libs_mplayer -lRolfApp -lRolfImage"
+  _vomodules="rolf $_vomodules"
+else
+  _def_rolf='#undef HAVE_ROLF'
+  _novomodules="rolf $_novomodules"
+fi
+echores "$_rolf"
+
+
 
 echocheck "DVB"
 if test "$_dvb" = auto ; then
@@ -8449,6 +8477,7 @@
 $_def_mga
 $_def_xmga
 $_def_fbdev
+$_def_rolf
 $_def_dxr2
 $_def_dxr3
 $_def_ivtv
diff -Naur ../MPlayer-1.0rc2/libvo/video_out.c ./libvo/video_out.c
--- ../MPlayer-1.0rc2/libvo/video_out.c	2007-10-07 21:49:28.000000000 +0200
+++ ./libvo/video_out.c	2007-10-10 13:07:05.000000000 +0200
@@ -85,6 +85,9 @@
 extern vo_functions_t video_out_bl;
 extern vo_functions_t video_out_fbdev;
 extern vo_functions_t video_out_fbdev2;
+#if HAVE_ROLF
+extern vo_functions_t video_out_rolf;
+#endif
 extern vo_functions_t video_out_svga;
 extern vo_functions_t video_out_png;
 extern vo_functions_t video_out_ggi;
@@ -199,6 +202,9 @@
 #ifdef HAVE_GGI
 	&video_out_ggi,
 #endif
+#ifdef HAVE_ROLF
+	&video_out_rolf,
+#endif
 #ifdef HAVE_FBDEV
 	&video_out_fbdev,
 	&video_out_fbdev2,
diff -Naur ../MPlayer-1.0rc2/libvo/vo_rolf.c ./libvo/vo_rolf.c
--- ../MPlayer-1.0rc2/libvo/vo_rolf.c	1970-01-01 01:00:00.000000000 +0100
+++ ./libvo/vo_rolf.c	2007-10-11 09:52:40.000000000 +0200
@@ -0,0 +1,490 @@
+/*
+ * Video driver for ROLF GUI
+ * by Simon Willcocks <simon.willcocks@t-online.de>
+ * (C) 2006
+ * 
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ctype.h>
+#include <strings.h>
+#include <sys/time.h>
+
+#include "config.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+#include "fastmemcpy.h"
+#include "sub.h"
+#include "aspect.h"
+#include "mp_msg.h"
+
+#include "rolf/image/bitmaps.h"
+#include "rolf/image/font.h"
+#include "rolf/image/psf_font.h"
+#include "rolf/screen_rectangle.h"
+#include "rolf/app/furniture.h"
+#include "rolf/app/services.h"
+#include "rolf/app/dirinfo.h"
+
+// For keyboard input
+#include "rolf/app/toascii.h"
+extern void mplayer_put_key(int code);
+#include "osdep/keycodes.h"
+
+#include <assert.h>
+#include "rolf/image/image_internals.h"
+
+static vo_info_t info = {
+        .name = "ROLF GUI",
+        .short_name = "rolf",
+        .author = "Simon Willcocks <simon.willcocks@t-online.de>",
+        .comment = "Version 0.01"
+};
+
+LIBVO_EXTERN(rolf)
+
+CreatedWindow *window = 0;
+WindowPane pane;
+
+const Bitmap *frame[2] = { 0, 0 };
+static int display_frame = 0;
+
+bool idle = 0;
+const Bitmap *(*bitmap_maker)( unsigned char *data, Rectangle area ) = 0;
+const SourceImage *(*yuv_source_maker)( const void *Y, const void *U, const void *V, int width, int height ) = 0;
+
+struct YUVImage {
+    SourceImage me;
+    int width;
+    int height;
+    const unsigned char *Y;
+    const unsigned char *U;
+    const unsigned char *V;
+} yuv;
+
+rgba16 YUVGetPixel( const SourceImage *s, int x, int y )
+{
+    rgba16 result;
+    Rectangle area = s->GetArea( s );
+    int width = Rectangle_Width( area );
+    assert( s == &yuv.me );
+    unsigned char c = yuv.Y[(x + width * y)];
+    result.r = c;
+    result.r = result.r | (result.r << 8);
+    result.g = result.r;
+    result.b = result.r;
+    result.a = 0xffff;
+
+    return result;
+}
+
+void YUVFree( const SourceImage *s )
+{
+}
+
+Rectangle YUVGetArea( const SourceImage *image )
+{
+    struct YUVImage *yuv = (struct YUVImage *) image;
+    Rectangle result = { 0, 0, yuv->width, yuv->height };
+    return result;
+}
+
+const SourceImage *MakeYUV( const void *Y, const void *U, const void *V, int width, int height )
+{
+    yuv.width = width;
+    yuv.height = height;
+
+    yuv.me.GetArea = YUVGetArea;
+    yuv.me.GetPixel = YUVGetPixel;
+    yuv.me.RenderTo = DefaultRenderTo;
+    yuv.me.Free = YUVFree;
+
+    yuv.Y = Y;
+    yuv.U = U;
+    yuv.V = V;
+
+    return &yuv.me;
+}
+
+void NullEvent()
+{
+    idle = 1;
+}
+
+/* Normal behaviour for a window */
+void OpenTopReq( void *user_handle ) { OpenTop( window ); }
+void OpenBottomReq( void *user_handle ) { OpenBottom( window ); }
+void SetPositionReq( void *user_handle, ScreenRectangle r ) { SetPosition( window, r ); }
+
+void Event_MouseSelect( void *user_handle, int hotspot, short x, short y )
+{
+    if (window != 0)
+        GetFocus( window );
+}
+
+void DrawWorkArea( void *handle, const DestinationImage *area, Rectangle work_area )
+{
+    Rectangle dst_area = area->GetArea( area );
+struct timeval in_time;
+struct timeval out_time;
+gettimeofday( &in_time, 0 );
+
+    frame[display_frame]->source.RenderTo( &frame[display_frame]->source, work_area, area, dst_area.left - work_area.left, dst_area.bottom - work_area.bottom );
+
+gettimeofday( &out_time, 0 );
+int duration = out_time.tv_usec - in_time.tv_usec;
+if (duration < 0) duration += 1000000;
+printf( "Rendered to screen in %d usecs at %d.%06d\n", duration, out_time.tv_sec, out_time.tv_usec );
+}
+
+/*
+ * Preinitializes driver (real INITIALIZATION)
+ *   arg - currently it's vo_subdevice
+ *   returns: zero on successful initialization, non-zero on error.
+ */
+static int preinit(const char *arg)
+{
+    ROLF_Initialise( "MPlayer" );
+    return 0;
+}
+
+/*
+ * Initialize (means CONFIGURE) the display driver.
+ * params:
+ *   width,height: image source size
+ *   d_width,d_height: size of the requested window size, just a hint
+ *   fullscreen: flag, 0=windowd 1=fullscreen, just a hint
+ *   title: window title, if available
+ *   format: fourcc of pixel format
+ * returns : zero on successful initialization, non-zero on error.
+ */
+static int config(uint32_t width, uint32_t height, uint32_t d_width,
+                 uint32_t d_height, uint32_t fullscreen, char *title,
+                 uint32_t format)
+{
+    static WindowPaneHotspot hotspot;
+
+    bzero( &pane, sizeof( pane ) );
+
+    pane.work_area.left = 0;
+    pane.work_area.right_plus_one = width;
+    pane.work_area.bottom = 0;
+    pane.work_area.top_plus_one = height;
+
+    const DisplayCache *dc = AppDisplayCache();
+    char frame_name[32];
+    if (frame[0] != 0)
+        frame[0]->Free( frame[0] );
+    sprintf( frame_name, "MPlayer%dFrame%d", getpid(), 0 );
+    frame[0] = dc->NewOpaqueBitmap( dc, frame_name, pane.work_area );
+
+    if (frame[1] != 0)
+        frame[1]->Free( frame[1] );
+    sprintf( frame_name, "MPlayer%dFrame%d", getpid(), 1 );
+    frame[1] = dc->NewOpaqueBitmap( dc, frame_name, pane.work_area );
+
+    pane.number_of_hotspots = 1;
+    pane.hotspots = &hotspot;
+
+    pane.hotspots[0].work_area_rectangle = pane.work_area;
+    pane.hotspots[0].code = HOTSPOT_CLICK;
+
+    if (window == 0)
+    {
+        window = CreateWindowWithFurniture( &window, ROLF_BORDER_BIT | ROLF_BACK_BIT | ROLF_CLOSE_BIT | ROLF_TITLE_BIT, &pane );
+    }
+    else
+    {
+        ChangePane( window, &pane );
+    }
+    if (title != 0)
+        SetTitle( window, title );
+    else
+        SetTitle( window, "MPlayer" );
+
+    switch (format) {
+    case IMGFMT_BGR32:
+        bitmap_maker = MakeB8G8R8U8Bitmap;
+        break;
+    case IMGFMT_RGB24:
+        bitmap_maker = MakeR8G8B8Bitmap;
+        break;
+    case IMGFMT_YV12:
+        yuv_source_maker = MakeYUV;
+        break;
+    };
+
+    SetPosition( window, ScreenRectangle_FromRectangle( Rectangle_OffsetBy( pane.work_area, 100, 100 ) ) );
+    SetScroll( window, pane.work_area.left, pane.work_area.top_plus_one );
+    OpenTop( window );
+    GetFocus( window );
+    idle = 0;
+    while (!idle) {
+        Poll();
+    }
+    ROLF_Detatch();
+
+    return 0;
+}
+
+/*
+ * Control interface
+ */
+static int control(uint32_t request, void *data, ...)
+{
+    switch (request) {
+    case VOCTRL_QUERY_FORMAT:
+    {
+        uint32_t fmt = *((uint32_t*)data);
+        switch (fmt) {
+        case IMGFMT_BGR32: // Preferred format
+            return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW  | VFCAP_ACCEPT_STRIDE;
+        case IMGFMT_RGB24:
+            return VFCAP_CSP_SUPPORTED;
+        case IMGFMT_YV12:
+            //return VFCAP_CSP_SUPPORTED;
+        default:
+            return 0;
+        };
+        break;
+    }
+    default:
+        printf( "Control %d\n", request );
+    }
+    return 0;
+}
+
+/*
+ * Display a new RGB/BGR frame of the video to the screen.
+ * params:
+ *   src[0] - pointer to the image
+ */
+static int draw_frame(uint8_t *src[])
+{
+    assert( bitmap_maker != 0 );
+printf( "Source %08d\n", src[0] );
+    static uint8_t *old_src = 0;
+    const SourceImage *current_source = 0;
+
+    if (old_src != src[0])
+    {
+        if (current_source != 0)
+            current_source->Free( current_source );
+
+        current_source = &bitmap_maker( (unsigned char*)src[0], pane.work_area )->source;
+        FlipBitmapVertically( current_source );
+    }
+
+struct timeval in_time;
+struct timeval out_time;
+gettimeofday( &in_time, 0 );
+//printf( "IN  PollEventsUntilIdleOrBored %d %d\n", in_time.tv_sec, in_time.tv_usec );
+    current_source->RenderTo( current_source, pane.work_area, &frame[1-display_frame]->destination, 0, 0 );
+gettimeofday( &out_time, 0 );
+int duration = out_time.tv_usec - in_time.tv_usec;
+if (duration < 0) duration += 1000000;
+printf( "Rendered to cache in %d usecs at %d.%06d\n", duration, out_time.tv_sec, out_time.tv_usec );
+
+    return 0;
+}
+
+/*
+ * Draw a planar YUV slice to the buffer:
+ * params:
+ *   src[3] = source image planes (Y,U,V)
+ *   stride[3] = source image planes line widths (in bytes)
+ *   w,h = width*height of area to be copied (in Y pixels)
+ *   x,y = position at the destination image (in Y pixels)
+ */
+static int draw_slice(uint8_t *src[], int stride[], int w,int h, int x,int y)
+{
+    assert( bitmap_maker != 0 );
+printf( "Slice source %08d (%d %d %d %d)\n", src[0], x, y, w, h );
+    static uint8_t *old_src = 0;
+    static Rectangle old_area = { 0, 0, 0, 0 };
+    const SourceImage *current_source = 0;
+
+    Rectangle area = { 0, 0, w, h };
+
+    if (old_src != src[0] || !Rectangle_Equal( old_area, area ))
+    {
+        if (current_source != 0)
+            current_source->Free( current_source );
+
+        current_source = &bitmap_maker( (unsigned char*)src[0], area )->source;
+        old_area = area;
+        FlipBitmapVertically( current_source );
+    }
+
+struct timeval in_time;
+struct timeval out_time;
+gettimeofday( &in_time, 0 );
+//printf( "IN  PollEventsUntilIdleOrBored %d %d\n", in_time.tv_sec, in_time.tv_usec );
+    current_source->RenderTo( current_source, area, &frame[1-display_frame]->destination, x, y );
+gettimeofday( &out_time, 0 );
+int duration = out_time.tv_usec - in_time.tv_usec;
+if (duration < 0) duration += 1000000;
+printf( "Rendered to cache in %d usecs at %d.%06d\n", duration, out_time.tv_sec, out_time.tv_usec );
+
+    return 0;
+}
+/*{
+    assert( yuv_source_maker != 0 );
+
+    const SourceImage *current_source = yuv_source_maker( src[0], src[1], src[2], w, h );
+    current_source->RenderTo( current_source, current_source->GetArea( current_source ), &frame[1-display_frame]->destination, x, y );
+    current_source->Free( current_source );
+
+    return 0;
+} */
+
+/*
+ * Draws OSD to the screen buffer
+ */
+static void draw_osd(void)
+{
+}
+
+static void PollEventsUntilIdleOrBored()
+{
+    struct timeval now;
+    struct timeval give_up;
+    struct timeval timeout;
+
+struct timeval in_time;
+gettimeofday( &in_time, 0 );
+//printf( "IN  PollEventsUntilIdleOrBored %d %d\n", in_time.tv_sec, in_time.tv_usec );
+
+    gettimeofday( &now, 0 );
+
+    give_up.tv_sec = now.tv_sec;
+    give_up.tv_usec = now.tv_usec + 20000;
+    if (give_up.tv_usec > 1000000)
+    {
+        give_up.tv_usec -= 1000000;
+        give_up.tv_sec ++;
+    }
+
+    idle = 0;
+    while (!idle) {
+        gettimeofday( &now, 0 );
+        if (now.tv_sec > give_up.tv_sec)
+        {
+            break; // We'll try again later
+        }
+        else if (now.tv_sec == give_up.tv_sec)
+        {
+            if (now.tv_usec > give_up.tv_usec)
+                break; // Past time to give up
+
+            assert(now.tv_usec <= give_up.tv_usec);
+
+            timeout.tv_sec = 0;
+            timeout.tv_usec = give_up.tv_usec - now.tv_usec;
+        }
+        else // (now.tv_sec <= give_up.tv_sec)
+        {
+            timeout.tv_sec = give_up.tv_sec - now.tv_sec;
+            if (now.tv_usec < give_up.tv_usec)
+                timeout.tv_usec = give_up.tv_usec - now.tv_usec;
+            else
+            {
+                timeout.tv_usec = 1000000 + give_up.tv_usec - now.tv_usec;
+                timeout.tv_sec --;
+            }
+        }
+printf( "Timeout after %d %d is %d %d\n", now.tv_sec, now.tv_usec, timeout.tv_sec, timeout.tv_usec );
+        PollActive( timeout );
+    }
+gettimeofday( &now, 0 );
+if (in_time.tv_usec > now.tv_usec)
+{
+    in_time.tv_usec = now.tv_usec + 1000000 - in_time.tv_usec;
+    in_time.tv_sec = now.tv_sec - in_time.tv_sec - 1;
+}
+else
+{
+    in_time.tv_usec = now.tv_usec - in_time.tv_usec;
+    in_time.tv_sec = now.tv_sec - in_time.tv_sec;
+}
+//printf( "OUT PollEventsUntilIdleOrBored %d %d (%d.%06d)\n", now.tv_sec, now.tv_usec, in_time.tv_sec, in_time.tv_usec );
+}
+
+/*
+ * Blit/Flip buffer to the screen. Must be called after each frame!
+ */
+static void flip_page(void)
+{
+    display_frame = 1 - display_frame;
+
+    PollEventsUntilIdleOrBored();
+
+    if (!idle)
+        return; // No chance to display this frame, better luck with the next one.
+
+    RedrawWorkArea( window, pane.work_area );
+    PollEventsUntilIdleOrBored();
+
+    if (idle)
+        ROLF_Detatch();
+}
+
+void Event_Keypress( unsigned int code )
+{
+    const char *ascii = ToAscii( code );
+
+    switch (ascii[0]) {
+        case '\033': {
+            switch (ascii[1]) {
+
+                case '\0': mplayer_put_key(KEY_ESC); return;
+                case '[': {
+                    switch( ascii[2] ) {
+                        case '5': mplayer_put_key(KEY_PAGE_UP); return;
+                        case '6': mplayer_put_key(KEY_PAGE_DOWN); return;
+                        case 'A': mplayer_put_key(KEY_UP); return;
+                        case 'B': mplayer_put_key(KEY_DOWN); return;
+                        case 'D': mplayer_put_key(KEY_LEFT); return;
+                        case 'C': mplayer_put_key(KEY_RIGHT); return;
+                        case '2': mplayer_put_key(KEY_INSERT); return;
+                        case '3': mplayer_put_key(KEY_DELETE); return;
+                        case '1': mplayer_put_key(KEY_HOME); return;
+                        case '4': mplayer_put_key(KEY_END); return;
+                    }
+                }
+            }
+        }
+
+        default:mplayer_put_key( ascii[0] );
+    };
+}
+
+/*
+ * This func is called after every frames to handle keyboard and
+ * other events. It's called in PAUSE mode too!
+ */
+static void check_events(void)
+{
+    PollEventsUntilIdleOrBored();
+    if (idle)
+        ROLF_Detatch();
+}
+
+/*
+ * Closes driver. Should restore the original state of the system.
+ */
+static void uninit(void)
+{
+    idle = 0;
+    while (!idle) {
+        Poll();
+    }
+
+    ROLF_Shutdown();
+}
+
