]> git.sesse.net Git - vlc/blobdiff - mozilla/vlcshell.cpp
test/headers.c: Make sure __LIBVLC__ isn't defined.
[vlc] / mozilla / vlcshell.cpp
index 28df94e82b841dffadc0fbbcd2b213f71c82971f..3268b09bc5f656dc2456c973d13c9434129a1b82 100644 (file)
 #   include <mozilla-config.h>
 #endif
 
+#ifdef XP_UNIX
+#ifndef __APPLE__
+#include <X11/xpm.h>
+#endif
+#endif
+
 /* This is from mozilla java, do we really need it? */
 #if 0
 #include <jri.h>
@@ -45,7 +51,8 @@
 /* Enable/disable debugging printf's for X11 resizing */
 #undef X11_RESIZE_DEBUG
 
-#define WINDOW_TEXT "(no video)"
+#define WINDOW_TEXT "Video is loading..."
+#define CONTROL_HEIGHT 45
 
 /*****************************************************************************
  * Unix-only declarations
@@ -53,6 +60,7 @@
 #ifdef XP_UNIX
 
 static void Redraw( Widget w, XtPointer closure, XEvent *event );
+static void ControlHandler( Widget w, XtPointer closure, XEvent *event );
 static void Resize( Widget w, XtPointer closure, XEvent *event );
 
 #endif
@@ -119,6 +127,7 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
     switch( variable )
     {
         case NPPVpluginScriptableNPObject:
+        {
             /* retrieve plugin root class */
             NPClass *scriptClass = p_plugin->getScriptClass();
             if( scriptClass )
@@ -128,6 +137,7 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
                 return NPERR_NO_ERROR;
             }
             break;
+        }
 
         default:
             ;
@@ -170,7 +180,7 @@ int16 NPP_HandleEvent( NPP instance, void * event )
     switch( myEvent->what )
     {
         case nullEvent:
-            break;
+            return true;
         case mouseDown:
         {
             if( (myEvent->when - lastMouseUp) < GetDblTime() )
@@ -182,11 +192,12 @@ int16 NPP_HandleEvent( NPP instance, void * event )
                 {
                     if( libvlc_playlist_isplaying(p_vlc, NULL) )
                     {
-                        libvlc_input_t *p_input = libvlc_playlist_get_input(p_vlc, NULL);
-                        if( p_input )
+                        libvlc_media_instance_t *p_md =
+                            libvlc_playlist_get_media_instance(p_vlc, NULL);
+                        if( p_md )
                         {
-                            libvlc_toggle_fullscreen(p_input, NULL);
-                            libvlc_input_free(p_input);
+                            libvlc_toggle_fullscreen(p_md, NULL);
+                            libvlc_media_instance_release(p_md);
                         }
                     }
                 }
@@ -202,44 +213,57 @@ int16 NPP_HandleEvent( NPP instance, void * event )
             return true;
         case updateEvt:
         {
-            int needsDisplay = TRUE;
-            libvlc_instance_t *p_vlc = p_plugin->getVLC();
-
-            if( p_vlc )
+            const NPWindow& npwindow = p_plugin->getWindow();
+            if( npwindow.window )
             {
-                if( libvlc_playlist_isplaying(p_vlc, NULL) )
+                int hasVout = FALSE;
+                libvlc_instance_t *p_vlc = p_plugin->getVLC();
+
+                if( p_vlc )
                 {
-                    libvlc_input_t *p_input = libvlc_playlist_get_input(p_vlc, NULL);
-                    if( p_input )
+                    if( libvlc_playlist_isplaying(p_vlc, NULL) )
                     {
-                        needsDisplay = ! libvlc_input_has_vout(p_input, NULL);
-                        libvlc_input_free(p_input);
+                        libvlc_media_instance_t *p_md =
+                            libvlc_playlist_get_media_instance(p_vlc, NULL);
+                        if( p_md )
+                        {
+                            hasVout = libvlc_media_instance_has_vout(p_md, NULL);
+                            if( hasVout )
+                            {
+                                libvlc_rectangle_t area;
+                                area.left = 0;
+                                area.top = 0;
+                                area.right = npwindow.width;
+                                area.bottom = npwindow.height;
+                                libvlc_video_redraw_rectangle(p_md, &area, NULL);
+                            }
+                            libvlc_media_instance_release(p_md);
+                        }
                     }
                 }
-            }
 
-            const NPWindow *npwindow = p_plugin->getWindow();
-
-            if( needsDisplay && npwindow->window )
-            {
-                /* draw the beautiful "No Picture" */
+                if( ! hasVout )
+                {
+                    /* draw the beautiful "No Picture" */
 
-                ForeColor(blackColor);
-                PenMode( patCopy );
+                    ForeColor(blackColor);
+                    PenMode( patCopy );
 
-                /* seems that firefox forgets to set the following on occasion (reload) */
-                SetOrigin(((NP_Port *)npwindow->window)->portx, ((NP_Port *)npwindow->window)->porty);
+                    /* seems that firefox forgets to set the following on occasion (reload) */
+                    SetOrigin(((NP_Port *)npwindow.window)->portx,
+                              ((NP_Port *)npwindow.window)->porty);
 
-                Rect rect;
-                rect.left = 0;
-                rect.top = 0;
-                rect.right = npwindow->width;
-                rect.bottom = npwindow->height;
-                PaintRect( &rect );
+                    Rect rect;
+                    rect.left = 0;
+                    rect.top = 0;
+                    rect.right = npwindow.width;
+                    rect.bottom = npwindow.height;
+                    PaintRect( &rect );
 
-                ForeColor(whiteColor);
-                MoveTo( (npwindow->width-80)/ 2  , npwindow->height / 2 );
-                DrawText( WINDOW_TEXT , 0 , strlen(WINDOW_TEXT) );
+                    ForeColor(whiteColor);
+                    MoveTo( (npwindow.width-80)/ 2  , npwindow.height / 2 );
+                    DrawText( WINDOW_TEXT , 0 , strlen(WINDOW_TEXT) );
+                }
             }
             return true;
         }
@@ -255,6 +279,7 @@ int16 NPP_HandleEvent( NPP instance, void * event )
         case NPEventType_ClippingChangedEvent:
             return false;
         case NPEventType_ScrollingBeginsEvent:
+            return true;
         case NPEventType_ScrollingEndsEvent:
             return true;
         default:
@@ -302,8 +327,10 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
     if( NPERR_NO_ERROR == status )
     {
         instance->pdata = reinterpret_cast<void*>(p_plugin);
-        //NPN_SetValue(instance, NPPVpluginWindowBool, (void *)false);
+#if 0
+        NPN_SetValue(instance, NPPVpluginWindowBool, (void *)false);
         NPN_SetValue(instance, NPPVpluginTransparentBool, (void *)false);
+#endif
     }
     else
     {
@@ -324,7 +351,7 @@ NPError NPP_Destroy( NPP instance, NPSavedData** save )
     instance->pdata = NULL;
 
 #if XP_WIN
-    HWND win = (HWND)p_plugin->getWindow()->window;
+    HWND win = (HWND)p_plugin->getWindow().window;
     WNDPROC winproc = p_plugin->getWindowProc();
     if( winproc )
     {
@@ -363,14 +390,15 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
      *  size changes, etc.
      */
 
-    const NPWindow *curwin = p_plugin->getWindow();
+    /* retrieve current window */
+    NPWindow& curwin = p_plugin->getWindow();
 
 #ifdef XP_MACOSX
     if( window && window->window )
     {
         /* check if plugin has a new parent window */
         CGrafPtr drawable = (((NP_Port*) (window->window))->port);
-        if( !curwin->window || drawable != (((NP_Port*) (curwin->window))->port) )
+        if( !curwin.window || drawable != (((NP_Port*) (curwin.window))->port) )
         {
             /* set/change parent window */
             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
@@ -395,8 +423,13 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
 
         libvlc_video_set_viewport(p_vlc, &view, &clip, NULL);
 
-        /* remember window details */
-        p_plugin->setWindow(window);
+        /* remember new window */
+        p_plugin->setWindow(*window);
+    }
+    else if( curwin.window ) {
+        /* change/set parent */
+        libvlc_video_set_parent(p_vlc, 0, NULL);
+        curwin.window = NULL;
     }
 #endif /* XP_MACOSX */
 
@@ -405,10 +438,10 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
     {
         /* check if plugin has a new parent window */
         HWND drawable = (HWND) (window->window);
-        if( !curwin->window || drawable != curwin->window )
+        if( !curwin.window || drawable != curwin.window )
         {
             /* reset previous window settings */
-            HWND oldwin = (HWND)p_plugin->getWindow()->window;
+            HWND oldwin = (HWND)p_plugin->getWindow().window;
             WNDPROC oldproc = p_plugin->getWindowProc();
             if( oldproc )
             {
@@ -416,11 +449,12 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
                 SetWindowLong( oldwin, GWL_WNDPROC, (LONG)oldproc );
             }
             /* attach our plugin object */
-            SetWindowLongPtr((HWND)drawable, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(p_plugin));
+            SetWindowLongPtr((HWND)drawable, GWLP_USERDATA,
+                             reinterpret_cast<LONG_PTR>(p_plugin));
 
             /* install our WNDPROC */
             p_plugin->setWindowProc( (WNDPROC)SetWindowLong( drawable,
-                                                           GWL_WNDPROC, (LONG)Manage ) );
+                                             GWL_WNDPROC, (LONG)Manage ) );
 
             /* change window style to our liking */
             LONG style = GetWindowLong((HWND)drawable, GWL_STYLE);
@@ -429,56 +463,98 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
 
             /* change/set parent */
             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
-        }
 
-        /* remember window details */
-        p_plugin->setWindow(window);
+            /* remember new window */
+            p_plugin->setWindow(*window);
 
-        /* Redraw window */
-        InvalidateRect( (HWND)drawable, NULL, TRUE );
-        UpdateWindow( (HWND)drawable );
+            /* Redraw window */
+            InvalidateRect( (HWND)drawable, NULL, TRUE );
+            UpdateWindow( (HWND)drawable );
+        }
     }
-    else
+    else if ( curwin.window )
     {
         /* reset WNDPROC */
-        HWND oldwin = (HWND)curwin->window;
+        HWND oldwin = (HWND)curwin.window;
         SetWindowLong( oldwin, GWL_WNDPROC, (LONG)(p_plugin->getWindowProc()) );
         p_plugin->setWindowProc(NULL);
         /* change/set parent */
         libvlc_video_set_parent(p_vlc, 0, NULL);
+        curwin.window = NULL;
     }
 #endif /* XP_WIN */
 
 #ifdef XP_UNIX
     if( window && window->window )
     {
-        Window  drawable   = (Window) window->window;
-        if( !curwin->window || drawable != (Window)curwin->window )
+        Window  parent   = (Window) window->window;
+        if( !curwin.window || (parent != (Window)curwin.window) )
         {
             Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
 
-            XResizeWindow( p_display, drawable, window->width, window->height );
-            Widget w = XtWindowToWidget( p_display, drawable );
+            XResizeWindow( p_display, parent, window->width, window->height );
+
+            int i_blackColor = BlackPixel(p_display, DefaultScreen(p_display));
+
+            Window video = XCreateSimpleWindow( p_display, parent, 0, 0,
+                           window->width, window->height - CONTROL_HEIGHT, 0,
+                           i_blackColor, i_blackColor );
+            Window controls = XCreateSimpleWindow( p_display, parent, 0,
+                            window->height - CONTROL_HEIGHT-1, window->width,
+                            CONTROL_HEIGHT-1, 0, i_blackColor, i_blackColor );
+
+            XMapWindow( p_display, parent );
+            XMapWindow( p_display, video );
+            XMapWindow( p_display, controls );
+
+            XFlush(p_display);
+
+            Widget w = XtWindowToWidget( p_display, parent );
+
+            XtAddEventHandler( w, ExposureMask, FALSE,
+                               (XtEventHandler)Redraw, p_plugin );
+            XtAddEventHandler( w, StructureNotifyMask, FALSE,
+                               (XtEventHandler)Resize, p_plugin );
+            XtAddEventHandler( w, ButtonReleaseMask, FALSE,
+                               (XtEventHandler)ControlHandler, p_plugin );
 
-            XtAddEventHandler( w, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin );
-            XtAddEventHandler( w, StructureNotifyMask, FALSE, (XtEventHandler)Resize, p_plugin );
+            /* callback */
+/*
+            libvlc_media_instance_t *p_md;
+
+            libvlc_exception_t ex;
+            libvlc_exception_init(& ex );
+            p_md = libvlc_playlist_get_media_instance( p_plugin->getVLC(), &ex );
+            libvlc_exception_init( &ex );
+            libvlc_event_attach( libvlc_media_instance_event_manager( p_md, &ex ),
+                                 libvlc_MediaInstancePositionChanged, Redraw, NULL, &ex );
+*/
 
             /* set/change parent window */
-            libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
+            libvlc_video_set_parent( p_vlc, (libvlc_drawable_t) video, NULL );
 
             /* remember window */
-            p_plugin->setWindow(window);
+            p_plugin->setWindow( *window );
+            p_plugin->setVideoWindow( video );
+            p_plugin->setControlWindow( controls );
 
             Redraw( w, (XtPointer)p_plugin, NULL );
         }
     }
+    else if ( curwin.window )
+    {
+        /* change/set parent */
+        libvlc_video_set_parent(p_vlc, 0, NULL);
+        curwin.window = NULL;
+    }
 #endif /* XP_UNIX */
 
     if( !p_plugin->b_stream )
     {
         if( p_plugin->psz_target )
         {
-            if( libvlc_playlist_add( p_vlc, p_plugin->psz_target, NULL, NULL ) != -1 )
+            if( libvlc_playlist_add( p_vlc, p_plugin->psz_target,
+                                     NULL, NULL ) != -1 )
             {
                 if( p_plugin->b_autoplay )
                 {
@@ -673,14 +749,15 @@ static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpa
             FillRect( hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH) );
             SetTextColor(hdc, RGB(255, 255, 255));
             SetBkColor(hdc, RGB(0, 0, 0));
-            DrawText( hdc, WINDOW_TEXT, strlen(WINDOW_TEXT), &rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
+            DrawText( hdc, WINDOW_TEXT, strlen(WINDOW_TEXT), &rect,
+                      DT_CENTER|DT_VCENTER|DT_SINGLELINE);
 
             EndPaint( p_hwnd, &paintstruct );
             return 0L;
         }
         default:
             /* delegate to default handler */
-            return p_plugin->getWindowProc()( p_hwnd, i_msg, wpar, lpar );
+            return CallWindowProc(p_plugin->getWindowProc(), p_hwnd, i_msg, wpar, lpar );
     }
 }
 #endif /* XP_WIN */
@@ -692,35 +769,266 @@ static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpa
 static void Redraw( Widget w, XtPointer closure, XEvent *event )
 {
     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
-    const NPWindow *window = p_plugin->getWindow();
+    const NPWindowwindow = p_plugin->getWindow();
     GC gc;
     XGCValues gcv;
 
-    Window  drawable   = (Window) window->window;
-    Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
+    /* Toolbar */
+    XImage *p_playIcon = NULL;
+    XImage *p_pauseIcon = NULL;
+    XImage *p_stopIcon = NULL;
+    XImage *p_timeline = NULL;
+    XImage *p_timeKnob = NULL;
+    XImage *p_fscreen = NULL;
+    XImage *p_muteIcon = NULL;
+    XImage *p_unmuteIcon = NULL;
+
+    libvlc_media_instance_t *p_md = NULL;
+    float f_position = 0;
+    int i_playing = 0;
+    bool b_mute = false;
+
+    Window video = p_plugin->getVideoWindow();
+    Window control = p_plugin->getControlWindow();
+    Display *p_display = ((NPSetWindowCallbackStruct *)window.ws_info)->display;
 
     gcv.foreground = BlackPixel( p_display, 0 );
-    gc = XCreateGC( p_display, drawable, GCForeground, &gcv );
+    gc = XCreateGC( p_display, video, GCForeground, &gcv );
 
-    XFillRectangle( p_display, drawable, gc,
-                    0, 0, window->width, window->height );
+    XFillRectangle( p_display, video, gc,
+                    0, 0, window.width, window.height - CONTROL_HEIGHT );
 
     gcv.foreground = WhitePixel( p_display, 0 );
     XChangeGC( p_display, gc, GCForeground, &gcv );
 
-    XDrawString( p_display, drawable, gc,
-                 window->width / 2 - 40, window->height / 2,
+    XDrawString( p_display, video, gc,
+                 window.width / 2 - 40, (window.height - CONTROL_HEIGHT) / 2,
                  WINDOW_TEXT, strlen(WINDOW_TEXT) );
 
+    /* RedrawToolbar */
+    gcv.foreground = BlackPixel( p_display, 0 );
+    gc = XCreateGC( p_display, control, GCForeground, &gcv );
+
+    XFillRectangle( p_display, control, gc,
+                    0, 0, window.width, CONTROL_HEIGHT );
+
+
+    gcv.foreground = WhitePixel( p_display, 0 );
+    XChangeGC( p_display, gc, GCForeground, &gcv );
+
+    /* get media instance */
+    libvlc_exception_t ex;
+    libvlc_exception_init( &ex );
+    p_md = libvlc_playlist_get_media_instance( p_plugin->getVLC(), &ex );
+    libvlc_exception_clear( &ex );
+
+    /* get isplaying */
+    libvlc_exception_init( &ex );
+    i_playing = libvlc_playlist_isplaying( p_plugin->getVLC(), &ex );
+    libvlc_exception_clear( &ex );
+
+    /* get mute info */
+    libvlc_exception_init(&ex);
+    b_mute = libvlc_audio_get_mute( p_plugin->getVLC(), &ex );
+    libvlc_exception_clear( &ex );
+
+    /* get movie position in % */
+    if( i_playing == 1 )
+    {
+        libvlc_exception_init( &ex );
+        f_position = libvlc_media_instance_get_position(p_md, &ex)*100;
+        libvlc_exception_clear( &ex );
+    }
+    libvlc_media_instance_release(p_md);
+
+    /* load icons */
+    XpmReadFileToImage( p_display, DATA_PATH "/mozilla/play.xpm",
+                        &p_playIcon, NULL, NULL);
+    XpmReadFileToImage( p_display, DATA_PATH "/mozilla/pause.xpm",
+                        &p_pauseIcon, NULL, NULL);
+    XpmReadFileToImage( p_display, DATA_PATH "/mozilla/stop.xpm",
+                        &p_stopIcon, NULL, NULL );
+    XpmReadFileToImage( p_display, DATA_PATH "/mozilla/time_line.xpm",
+                        &p_timeline, NULL, NULL);
+    XpmReadFileToImage( p_display, DATA_PATH "/mozilla/time_icon.xpm",
+                        &p_timeKnob, NULL, NULL);
+    XpmReadFileToImage( p_display, DATA_PATH "/mozilla/fullscreen.xpm",
+                        &p_fscreen, NULL, NULL);
+    XpmReadFileToImage( p_display, DATA_PATH "/mozilla/volume_max.xpm",
+                        &p_muteIcon, NULL, NULL);
+    XpmReadFileToImage( p_display, DATA_PATH "/mozilla/volume_mute.xpm",
+                        &p_unmuteIcon, NULL, NULL);
+
+#if 1 /* DEBUG */
+    if( !p_playIcon )
+    {
+        fprintf(stderr, "Error: playImage not found\n");
+    }
+    if( !p_pauseIcon )
+    {
+        fprintf(stderr, "Error: pauseImage not found\n");
+    }
+    if( !p_stopIcon )
+    {
+        fprintf(stderr, "Error: stopImage not found\n");
+    }
+    if( !p_timeline )
+    {
+        fprintf(stderr, "Error: TimeLineImage not found\n");
+    }
+    if( !p_timeKnob )
+    {
+        fprintf(stderr, "Error: TimeIcon not found\n");
+    }
+    if( !p_fscreen )
+    {
+        fprintf(stderr, "Error: FullscreenImage not found\n");
+    }
+    if( !p_muteIcon )
+    {
+        fprintf(stderr, "Error: MuteImage not found\n");
+    }
+    if( !p_unmuteIcon )
+    {
+        fprintf(stderr, "Error: UnMuteImage not found\n");
+    }
+#endif
+
+    /* position icons */
+    if( p_pauseIcon && (i_playing == 1) )
+    {
+        XPutImage( p_display, control, gc, p_pauseIcon, 0, 0, 4, 14,
+                   p_pauseIcon->width, p_pauseIcon->height );
+    }
+    else if( p_playIcon )
+    {
+        XPutImage( p_display, control, gc, p_playIcon, 0, 0, 4, 14,
+                   p_playIcon->width, p_playIcon->height );
+    }
+
+    if( p_stopIcon )
+        XPutImage( p_display, control, gc, p_stopIcon, 0, 0, 39, 14,
+                   p_stopIcon->width, p_stopIcon->height );
+    if( p_fscreen )
+        XPutImage( p_display, control, gc, p_fscreen, 0, 0, 67, 21,
+                   p_fscreen->width, p_fscreen->height );
+
+    if( p_unmuteIcon && b_mute )
+    {
+        XPutImage( p_display, control, gc, p_unmuteIcon, 0, 0, 94, 30,
+                 p_unmuteIcon->width, p_unmuteIcon->height );
+    }
+    else if( p_muteIcon )
+    {
+        XPutImage( p_display, control, gc, p_muteIcon, 0, 0, 94, 30,
+                   p_muteIcon->width, p_muteIcon->height );
+    }
+
+    if( p_timeline )
+        XPutImage( p_display, control, gc, p_timeline, 0, 0, 4, 4,
+                   (window.width-8), p_timeline->height );
+    if( p_timeKnob && (f_position > 0) )
+    {
+        f_position = (((float)window.width-8)/100)*f_position;
+        XPutImage( p_display, control, gc, p_timeKnob, 0, 0, (4+f_position), 2,
+                   p_timeKnob->width, p_timeKnob->height );
+    }
+
+    /* Cleanup */
+    if( p_playIcon )   XDestroyImage( p_playIcon );
+    if( p_pauseIcon )  XDestroyImage( p_pauseIcon );
+    if( p_stopIcon )   XDestroyImage( p_stopIcon );
+    if( p_timeline )   XDestroyImage( p_timeline );
+    if( p_timeKnob )   XDestroyImage( p_timeKnob );
+    if( p_fscreen )    XDestroyImage( p_fscreen );
+    if( p_muteIcon )   XDestroyImage( p_muteIcon );
+    if( p_unmuteIcon ) XDestroyImage( p_unmuteIcon );
+
     XFreeGC( p_display, gc );
 }
 
+static void ControlHandler( Widget w, XtPointer closure, XEvent *event )
+{
+    VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
+    const NPWindow& window = p_plugin->getWindow();
+
+    int i_height = window.height;
+    int i_width = window.width;
+    int i_xPos = event->xbutton.x;
+    int i_yPos = event->xbutton.y;
+
+    libvlc_exception_t ex;
+    libvlc_exception_init( &ex );
+    libvlc_media_instance_t *p_md =
+            libvlc_playlist_get_media_instance(p_plugin->getVLC(), &ex);
+    libvlc_exception_clear( &ex );
+
+    /* jump in the movie */
+    if( i_yPos <= (i_height-30) )
+    {
+        vlc_int64_t f_length;
+        libvlc_exception_init( &ex );
+        f_length = libvlc_media_instance_get_length( p_md, &ex ) / 100;
+        libvlc_exception_clear( &ex );
+
+        f_length = (float)f_length *
+                   ( ((float)i_xPos-4 ) / ( ((float)i_width-8)/100) );
+
+        libvlc_exception_init( &ex );
+        libvlc_media_instance_set_time( p_md, f_length, &ex );
+        libvlc_exception_clear( &ex );
+    }
+
+    /* play/pause toggle */
+    if( (i_yPos > (i_height-30)) && (i_xPos > 4) && (i_xPos <= 39) )
+    {
+        int i_playing;
+        libvlc_exception_init( &ex );
+        i_playing = libvlc_playlist_isplaying( p_plugin->getVLC(), &ex );
+        libvlc_exception_clear( &ex );
+
+        libvlc_exception_init( &ex );
+        if( i_playing == 1 )
+            libvlc_playlist_pause( p_plugin->getVLC(), &ex );
+        else
+            libvlc_playlist_play( p_plugin->getVLC(), -1, 0, NULL, &ex );
+        libvlc_exception_clear( &ex );
+    }
+
+    /* stop */
+    if( (i_yPos > (i_height-30)) && (i_xPos > 39) && (i_xPos < 67) )
+    {
+        libvlc_exception_init( &ex );
+        libvlc_playlist_stop( p_plugin->getVLC(), &ex );
+        libvlc_exception_clear( &ex );
+    }
+
+    /* fullscreen */
+    if( (i_yPos > (i_height-30)) && (i_xPos >= 67) && (i_xPos < 94) )
+    {
+        libvlc_exception_init( &ex );
+        libvlc_set_fullscreen( p_md, 1, &ex );
+        libvlc_exception_clear( &ex );
+    }
+
+    /* mute toggle */
+    if( (i_yPos > (i_height-30)) && (i_xPos >= 94) && (i_xPos < 109))
+    {
+        libvlc_exception_init( &ex );
+        libvlc_audio_toggle_mute( p_plugin->getVLC(), &ex );
+        libvlc_exception_clear( &ex );
+    }
+    libvlc_media_instance_release( p_md );
+
+    Redraw( w, closure, event );
+}
+
 static void Resize ( Widget w, XtPointer closure, XEvent *event )
 {
     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
-    const NPWindow *window = p_plugin->getWindow();
-    Window  drawable   = (Window) window->window;
-    Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
+    const NPWindowwindow = p_plugin->getWindow();
+    Window  drawable   = p_plugin->getVideoWindow();
+    Display *p_display = ((NPSetWindowCallbackStruct *)window.ws_info)->display;
 
     int i_ret;
     Window root_return, parent_return, * children_return;
@@ -739,14 +1047,14 @@ static void Resize ( Widget w, XtPointer closure, XEvent *event )
     }
 #endif /* X11_RESIZE_DEBUG */
 
-    if( ! p_plugin->setSize(window->width, window->height) )
+    if( ! p_plugin->setSize(window.width, (window.height - CONTROL_HEIGHT)) )
     {
         /* size already set */
         return;
     }
 
 
-    i_ret = XResizeWindow( p_display, drawable, window->width, window->height );
+    i_ret = XResizeWindow( p_display, drawable, window.width, (window.height - CONTROL_HEIGHT) );
 
 #ifdef X11_RESIZE_DEBUG
     fprintf( stderr,
@@ -778,7 +1086,7 @@ static void Resize ( Widget w, XtPointer closure, XEvent *event )
 #endif /* X11_RESIZE_DEBUG */
 
         i_ret = XResizeWindow( p_display, base_window,
-                window->width, window->height );
+                window.width, ( window.height - CONTROL_HEIGHT ) );
 
 #ifdef X11_RESIZE_DEBUG
         fprintf( stderr,