]> git.sesse.net Git - vlc/blobdiff - mozilla/vlcshell.cpp
- mozilla: support for libvlc_video_redraw_rectangle() message for PAINT events and...
[vlc] / mozilla / vlcshell.cpp
index 5fb274361331693f58b738a7fb1174523c5c8ed0..1c928310c72884d6ee0786a091e51c7cdbef8088 100644 (file)
@@ -93,14 +93,13 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
             return NPERR_NO_ERROR;
 
         case NPPVpluginDescriptionString:
-            snprintf( psz_desc, sizeof(psz_desc)-1, PLUGIN_DESCRIPTION, VLC_Version() );
-            psz_desc[sizeof(psz_desc)-1] = 0;
+            snprintf( psz_desc, sizeof(psz_desc), PLUGIN_DESCRIPTION, VLC_Version() );
             *((char **)value) = psz_desc;
             return NPERR_NO_ERROR;
 
         default:
             /* move on to instance variables ... */
-            break;
+            ;
     }
 
     if( instance == NULL )
@@ -120,18 +119,32 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
     switch( variable )
     {
         case NPPVpluginScriptableNPObject:
-            /* create an instance and return it */
-            *(NPObject**)value = NPN_CreateObject(instance, p_plugin->getScriptClass());
-            if( NULL == *(NPObject**)value )
+        {
+            /* retrieve plugin root class */
+            NPClass *scriptClass = p_plugin->getScriptClass();
+            if( scriptClass )
             {
-                return NPERR_OUT_OF_MEMORY_ERROR;
+                /* create an instance and return it */
+                *(NPObject**)value = NPN_CreateObject(instance, scriptClass);
+                return NPERR_NO_ERROR;
             }
             break;
+        }
 
         default:
-            return NPERR_GENERIC_ERROR;
+            ;
     }
-    return NPERR_NO_ERROR;
+    return NPERR_GENERIC_ERROR;
+}
+
+/*
+ * there is some confusion in gecko headers regarding definition of this API
+ * NPPVariable is wrongly defined as NPNVariable, which sounds incorrect.
+ */
+
+NPError NPP_SetValue( NPP instance, NPNVariable variable, void *value )
+{
+    return NPERR_GENERIC_ERROR;
 }
 
 /******************************************************************************
@@ -140,20 +153,50 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
 #ifdef XP_MACOSX
 int16 NPP_HandleEvent( NPP instance, void * event )
 {
+    static UInt32 lastMouseUp = 0;
+
     if( instance == NULL )
     {
         return false;
     }
 
     VlcPlugin *p_plugin = (VlcPlugin*)instance->pdata;
+
+    if( p_plugin == NULL )
+    {
+        return false;
+    }
+
     EventRecord *myEvent = (EventRecord*)event;
 
     switch( myEvent->what )
     {
         case nullEvent:
-            break;
+            return true;
         case mouseDown:
+        {
+            if( (myEvent->when - lastMouseUp) < GetDblTime() )
+            {
+                /* double click */
+                libvlc_instance_t *p_vlc = p_plugin->getVLC();
+
+                if( p_vlc )
+                {
+                    if( libvlc_playlist_isplaying(p_vlc, NULL) )
+                    {
+                        libvlc_input_t *p_input = libvlc_playlist_get_input(p_vlc, NULL);
+                        if( p_input )
+                        {
+                            libvlc_toggle_fullscreen(p_input, NULL);
+                            libvlc_input_free(p_input);
+                        }
+                    }
+                }
+            }
+            return true;
+        }
         case mouseUp:
+            lastMouseUp = myEvent->when;
             return true;
         case keyUp:
         case keyDown:
@@ -161,40 +204,55 @@ 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_input_t *p_input = libvlc_playlist_get_input(p_vlc, NULL);
+                        if( p_input )
+                        {
+                            hasVout = libvlc_input_has_vout(p_input, 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_input, &area, NULL);
+                            }
+                            libvlc_input_free(p_input);
+                        }
                     }
                 }
-            }
-            if( needsDisplay )
-            {
-                const NPWindow *npwindow = p_plugin->getWindow();
-                
-                /* draw the beautiful "No Picture" */
-
-                ForeColor(blackColor);
-                PenMode( patCopy );
-
-                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) );
+
+                if( ! hasVout )
+                {
+                    /* draw the beautiful "No Picture" */
+
+                    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);
+
+                    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) );
+                }
             }
             return true;
         }
@@ -210,6 +268,7 @@ int16 NPP_HandleEvent( NPP instance, void * event )
         case NPEventType_ClippingChangedEvent:
             return false;
         case NPEventType_ScrollingBeginsEvent:
+            return true;
         case NPEventType_ScrollingEndsEvent:
             return true;
         default:
@@ -254,10 +313,16 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
     }
 
     status = p_plugin->init(argc, argn, argv);
-    if( NPERR_NO_ERROR == status ) {
+    if( NPERR_NO_ERROR == status )
+    {
         instance->pdata = reinterpret_cast<void*>(p_plugin);
+#if 0
+        NPN_SetValue(instance, NPPVpluginWindowBool, (void *)false);
+        NPN_SetValue(instance, NPPVpluginTransparentBool, (void *)false);
+#endif
     }
-    else {
+    else
+    {
         delete p_plugin;
     }
     return status;
@@ -265,18 +330,27 @@ NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
 
 NPError NPP_Destroy( NPP instance, NPSavedData** save )
 {
-    if( instance == NULL )
-    {
+    if( NULL == instance )
         return NPERR_INVALID_INSTANCE_ERROR;
-    }
 
     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
-
-    if( p_plugin )
-        delete p_plugin;
+    if( NULL == p_plugin )
+        return NPERR_NO_ERROR;
 
     instance->pdata = NULL;
 
+#if XP_WIN
+    HWND win = (HWND)p_plugin->getWindow().window;
+    WNDPROC winproc = p_plugin->getWindowProc();
+    if( winproc )
+    {
+        /* reset WNDPROC */
+        SetWindowLong( win, GWL_WNDPROC, (LONG)winproc );
+    }
+#endif
+
+    delete p_plugin;
+
     return NPERR_NO_ERROR;
 }
 
@@ -305,14 +379,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);
@@ -329,7 +404,6 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
         view.left    = ((NP_Port*) (window->window))->portx;
         view.bottom  = window->height+view.top;
         view.right   = window->width+view.left;
-
         /* clipRect coordinates are also relative to GrafPort */
         clip.top     = window->clipRect.top;
         clip.left    = window->clipRect.left;
@@ -338,8 +412,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 */
 
@@ -348,23 +427,23 @@ 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 )
             {
                 /* reset WNDPROC */
                 SetWindowLong( oldwin, GWL_WNDPROC, (LONG)oldproc );
             }
+            /* attach our plugin object */
+            SetWindowLongPtr((HWND)drawable, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(p_plugin));
+
             /* install our WNDPROC */
             p_plugin->setWindowProc( (WNDPROC)SetWindowLong( drawable,
                                                            GWL_WNDPROC, (LONG)Manage ) );
 
-            /* attach our plugin object */
-            SetWindowLongPtr((HWND)drawable, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(p_plugin));
-
             /* change window style to our liking */
             LONG style = GetWindowLong((HWND)drawable, GWL_STYLE);
             style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
@@ -372,23 +451,24 @@ 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 */
 
@@ -396,21 +476,30 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
     if( window && window->window )
     {
         Window  drawable   = (Window) window->window;
-       if( !curwin->window || drawable != (Window)curwin->window )
-       {
-           Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
+        if( !curwin->window || drawable != (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, drawable, window->width, window->height );
-           Widget w = XtWindowToWidget( p_display, drawable );
+            XtAddEventHandler( w, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin );
+            XtAddEventHandler( w, StructureNotifyMask, FALSE, (XtEventHandler)Resize, p_plugin );
 
-           XtAddEventHandler( w, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin );
-           XtAddEventHandler( w, StructureNotifyMask, FALSE, (XtEventHandler)Resize, p_plugin );
+            /* set/change parent window */
+            libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
 
-           /* remember window */
-           p_plugin->setWindow(window);
+            /* remember window */
+            p_plugin->setWindow(*window);
 
-           Redraw( w, (XtPointer)p_plugin, NULL );
-       }
+            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 */
 
@@ -418,14 +507,14 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
     {
         if( p_plugin->psz_target )
         {
-            if( VLC_SUCCESS == libvlc_playlist_add( p_vlc, p_plugin->psz_target, NULL, NULL ) )
+            if( libvlc_playlist_add( p_vlc, p_plugin->psz_target, NULL, NULL ) != -1 )
             {
                 if( p_plugin->b_autoplay )
                 {
                     libvlc_playlist_play(p_vlc, 0, 0, NULL, NULL);
                 }
-                p_plugin->b_stream = VLC_TRUE;
             }
+            p_plugin->b_stream = VLC_TRUE;
         }
     }
     return NPERR_NO_ERROR;
@@ -434,68 +523,45 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window )
 NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
                        NPBool seekable, uint16 *stype )
 {
-    if( instance == NULL )
+    if( NULL == instance  )
     {
         return NPERR_INVALID_INSTANCE_ERROR;
     }
 
-#if 0
-    VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
-#endif
-
-    /* fprintf(stderr, "NPP_NewStream - FILE mode !!\n"); */
-
-    /* We want a *filename* ! */
-    *stype = NP_ASFILE;
-
-#if 0
-    if( !p_plugin->b_stream )
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(instance->pdata);
+    if( NULL == p_plugin )
     {
-        p_plugin->psz_target = strdup( stream->url );
-        p_plugin->b_stream = VLC_TRUE;
+        return NPERR_INVALID_INSTANCE_ERROR;
     }
-#endif
 
-    return NPERR_NO_ERROR;
+   /*
+   ** Firefox/Mozilla may decide to open a stream from the URL specified
+   ** in the SRC parameter of the EMBED tag and pass it to us
+   **
+   ** since VLC will open the SRC URL as well, we're not interested in
+   ** that stream. Otherwise, we'll take it and queue it up in the playlist
+   */
+    if( !p_plugin->psz_target || strcmp(stream->url, p_plugin->psz_target) )
+    {
+        /* TODO: use pipes !!!! */
+        *stype = NP_ASFILEONLY;
+        return NPERR_NO_ERROR;
+    }
+    return NPERR_GENERIC_ERROR;
 }
 
-int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
-                   * mode so we can take any size stream in our
-                   * write call (since we ignore it) */
-
-#define SARASS_SIZE (1024*1024)
-
 int32 NPP_WriteReady( NPP instance, NPStream *stream )
 {
-    VlcPlugin* p_plugin;
-
-    /* fprintf(stderr, "NPP_WriteReady\n"); */
-
-    if (instance != NULL)
-    {
-        p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
-        /* Muahahahahahahaha */
-        return STREAMBUFSIZE;
-        /*return SARASS_SIZE;*/
-    }
-
-    /* Number of bytes ready to accept in NPP_Write() */
-    return STREAMBUFSIZE;
-    /*return 0;*/
+    /* TODO */
+    return 8*1024;
 }
 
 
 int32 NPP_Write( NPP instance, NPStream *stream, int32 offset,
                  int32 len, void *buffer )
 {
-    /* fprintf(stderr, "NPP_Write %i\n", (int)len); */
-
-    if( instance != NULL )
-    {
-        /*VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata;*/
-    }
-
-    return len;         /* The number of bytes accepted */
+    /* TODO */
+    return len;
 }
 
 
@@ -505,7 +571,6 @@ NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason )
     {
         return NPERR_INVALID_INSTANCE_ERROR;
     }
-
     return NPERR_NO_ERROR;
 }
 
@@ -517,14 +582,19 @@ void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
         return;
     }
 
-    /* fprintf(stderr, "NPP_StreamAsFile %s\n", fname); */
-
-#if 0
-    VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
+    VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(instance->pdata);
+    if( NULL == p_plugin )
+    {
+        return;
+    }
 
-    VLC_AddTarget( p_plugin->i_vlc, fname, 0, 0,
-                   PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
-#endif /* USE_LIBVLC */
+    if( libvlc_playlist_add( p_plugin->getVLC(), fname, stream->url, NULL ) != -1 )
+    {
+        if( p_plugin->b_autoplay )
+        {
+            libvlc_playlist_play( p_plugin->getVLC(), 0, 0, NULL, NULL);
+        }
+    }
 }
 
 
@@ -632,9 +702,7 @@ 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));
-            TextOut( hdc, (rect.right-rect.left)/ 2 - 40,
-                          (rect.bottom-rect.top)/ 2,
-                     WINDOW_TEXT, strlen(WINDOW_TEXT) );
+            DrawText( hdc, WINDOW_TEXT, strlen(WINDOW_TEXT), &rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
 
             EndPaint( p_hwnd, &paintstruct );
             return 0L;
@@ -653,11 +721,11 @@ 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;
+    Window  drawable   = (Window) window.window;
     Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
 
     gcv.foreground = BlackPixel( p_display, 0 );
@@ -679,8 +747,8 @@ static void Redraw( Widget w, XtPointer closure, XEvent *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;
+    const NPWindowwindow = p_plugin->getWindow();
+    Window  drawable   = (Window) window.window;
     Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
 
     int i_ret;