X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=mozilla%2Fvlcshell.cpp;h=94df4df8d7cdc7cfd84269a11dca8a52893b447b;hb=66af5fd9ea0c7f4c22406b24cc728af3b6b2ced1;hp=d6910f230559eeac1a827b4c909a3a136cf17374;hpb=2799d36bc8abdc28df29a202acdb27223b25a7a7;p=vlc diff --git a/mozilla/vlcshell.cpp b/mozilla/vlcshell.cpp index d6910f2305..94df4df8d7 100644 --- a/mozilla/vlcshell.cpp +++ b/mozilla/vlcshell.cpp @@ -1,8 +1,8 @@ /***************************************************************************** - * vlcshell.c: a VideoLAN Client plugin for Mozilla + * vlcshell.cpp: a VLC plugin for Mozilla ***************************************************************************** - * Copyright (C) 2002 VideoLAN - * $Id: vlcshell.cpp,v 1.2 2002/09/30 11:05:41 sam Exp $ + * Copyright (C) 2002-2005 the VideoLAN team + * $Id$ * * Authors: Samuel Hocevar * @@ -18,63 +18,58 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ +#include "config.h" + #include #include - -/* vlc stuff */ -#include -#include "config.h" +#include /* Mozilla stuff */ -#include - -#ifdef WIN32 +#ifdef HAVE_MOZILLA_CONFIG_H +# include +#endif -#else - /* X11 stuff */ -# include -# include -# include +/* This is from mozilla java, do we really need it? */ +#if 0 +#include #endif -#include "vlcpeer.h" #include "vlcplugin.h" +/* Enable/disable debugging printf's for X11 resizing */ +#undef X11_RESIZE_DEBUG + +#define WINDOW_TEXT "(no video)" + /***************************************************************************** * Unix-only declarations ******************************************************************************/ -#ifndef WIN32 +#ifdef XP_UNIX + static void Redraw( Widget w, XtPointer closure, XEvent *event ); +static void Resize( Widget w, XtPointer closure, XEvent *event ); + +#endif + +/***************************************************************************** + * MacOS-only declarations +******************************************************************************/ +#ifdef XP_MACOSX #endif /***************************************************************************** * Windows-only declarations *****************************************************************************/ -#ifdef WIN32 -HINSTANCE g_hDllInstance = NULL; +#ifdef XP_WIN + +static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ); -BOOL WINAPI -DllMain( HINSTANCE hinstDLL, // handle of DLL module - DWORD fdwReason, // reason for calling function - LPVOID lpvReserved) -{ - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - g_hDllInstance = hinstDLL; - break; - case DLL_THREAD_ATTACH: - case DLL_PROCESS_DETACH: - case DLL_THREAD_DETACH: - break; - } - return TRUE; -} #endif /****************************************************************************** @@ -87,8 +82,10 @@ char * NPP_GetMIMEDescription( void ) NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) { - static nsIID nsid = VLCINTF_IID; + static char psz_desc[1000]; + + /* plugin class variables */ switch( variable ) { case NPPVpluginNameString: @@ -96,8 +93,13 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) return NPERR_NO_ERROR; case NPPVpluginDescriptionString: - *((char **)value) = PLUGIN_DESCRIPTION; + snprintf( psz_desc, sizeof(psz_desc), PLUGIN_DESCRIPTION, VLC_Version() ); + *((char **)value) = psz_desc; return NPERR_NO_ERROR; + + default: + /* move on to instance variables ... */ + ; } if( instance == NULL ) @@ -105,33 +107,176 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) return NPERR_INVALID_INSTANCE_ERROR; } - VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata; + /* plugin instance variables */ + + VlcPlugin* p_plugin = reinterpret_cast(instance->pdata); + if( NULL == p_plugin ) + { + // plugin has not been initialized yet ! + return NPERR_INVALID_INSTANCE_ERROR; + } switch( variable ) { - case NPPVpluginScriptableInstance: - *(nsISupports**)value = p_plugin->GetPeer(); - if( *(nsISupports**)value == NULL ) + case NPPVpluginScriptableNPObject: + { + /* 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; +} + +/* + * 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; +} + +/****************************************************************************** + * Mac-only API calls + *****************************************************************************/ +#ifdef XP_MACOSX +int16 NPP_HandleEvent( NPP instance, void * event ) +{ + static UInt32 lastMouseUp = 0; + + if( instance == NULL ) + { + return false; + } - case NPPVpluginScriptableIID: - *(nsIID**)value = (nsIID*)NPN_MemAlloc( sizeof(nsIID) ); - if( *(nsIID**)value == NULL ) + VlcPlugin *p_plugin = (VlcPlugin*)instance->pdata; + + if( p_plugin == NULL ) + { + return false; + } + + EventRecord *myEvent = (EventRecord*)event; + + switch( myEvent->what ) + { + case nullEvent: + return true; + case mouseDown: + { + if( (myEvent->when - lastMouseUp) < GetDblTime() ) { - return NPERR_OUT_OF_MEMORY_ERROR; + /* double click */ + libvlc_instance_t *p_vlc = p_plugin->getVLC(); + + if( p_vlc ) + { + if( libvlc_playlist_isplaying(p_vlc, NULL) ) + { + libvlc_media_instance_t *p_md = libvlc_playlist_get_media_instance(p_vlc, NULL); + if( p_md ) + { + libvlc_toggle_fullscreen(p_md, NULL); + libvlc_media_instance_release(p_md); + } + } + } } - **(nsIID**)value = nsid; - break; - + return true; + } + case mouseUp: + lastMouseUp = myEvent->when; + return true; + case keyUp: + case keyDown: + case autoKey: + return true; + case updateEvt: + { + const NPWindow& npwindow = p_plugin->getWindow(); + if( npwindow.window ) + { + int hasVout = FALSE; + libvlc_instance_t *p_vlc = p_plugin->getVLC(); + + if( p_vlc ) + { + if( libvlc_playlist_isplaying(p_vlc, NULL) ) + { + 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); + } + } + } + + 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; + } + case activateEvt: + return false; + case NPEventType_GetFocusEvent: + case NPEventType_LoseFocusEvent: + return true; + case NPEventType_AdjustCursorEvent: + return false; + case NPEventType_MenuCommandEvent: + return false; + case NPEventType_ClippingChangedEvent: + return false; + case NPEventType_ScrollingBeginsEvent: + return true; + case NPEventType_ScrollingEndsEvent: + return true; default: - return NPERR_GENERIC_ERROR; + ; } - - return NPERR_NO_ERROR; + return false; } +#endif /* XP_MACOSX */ /****************************************************************************** * General Plug-in Calls @@ -154,141 +299,77 @@ void NPP_Shutdown( void ) NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved ) { - int i_ret; - int i; - - char *ppsz_foo[] = - { - "vlc" - /*, "--plugin-path", "/home/sam/videolan/vlc_MAIN/plugins"*/ - , "--vout", "xvideo,x11,dummy" - , "--aout", "dsp" - , "--intf", "dummy" - /*, "--noaudio"*/ - /*, "-q"*/ - , "-v" - }; + NPError status; if( instance == NULL ) { return NPERR_INVALID_INSTANCE_ERROR; } - VlcPlugin * p_plugin = new VlcPlugin( instance ); - - if( p_plugin == NULL ) + VlcPlugin * p_plugin = new VlcPlugin( instance, mode ); + if( NULL == p_plugin ) { return NPERR_OUT_OF_MEMORY_ERROR; } - instance->pdata = p_plugin; - - p_plugin->fMode = mode; - p_plugin->fWindow = NULL; - p_plugin->window = 0; - - p_plugin->p_vlc = vlc_create_r(); - if( p_plugin->p_vlc == NULL ) + status = p_plugin->init(argc, argn, argv); + if( NPERR_NO_ERROR == status ) { - delete p_plugin; - p_plugin = NULL; - return NPERR_GENERIC_ERROR; + instance->pdata = reinterpret_cast(p_plugin); +#if 0 + NPN_SetValue(instance, NPPVpluginWindowBool, (void *)false); + NPN_SetValue(instance, NPPVpluginTransparentBool, (void *)false); +#endif } - - i_ret = vlc_init_r( p_plugin->p_vlc, sizeof(ppsz_foo)/sizeof(char*), ppsz_foo ); - if( i_ret ) + else { - vlc_destroy_r( p_plugin->p_vlc ); - p_plugin->p_vlc = NULL; delete p_plugin; - p_plugin = NULL; - return NPERR_GENERIC_ERROR; - } - - vlc_set_r( p_plugin->p_vlc, "vout", "xvideo,x11,dummy" ); - vlc_set_r( p_plugin->p_vlc, "intf", "dummy" ); - - p_plugin->b_stream = 0; - p_plugin->b_autoplay = 0; - p_plugin->psz_target = NULL; - - for( i = 0; i < argc ; i++ ) - { - if( !strcmp( argn[i], "target" ) ) - { - p_plugin->psz_target = argv[i]; - } - else if( !strcmp( argn[i], "autoplay" ) ) - { - if( !strcmp( argv[i], "yes" ) ) - { - p_plugin->b_autoplay = 1; - } - } - else if( !strcmp( argn[i], "loop" ) ) - { - if( !strcmp( argv[i], "yes" ) ) - { - vlc_set_r( p_plugin->p_vlc, "loop", "1" ); - } - } } - - if( p_plugin->psz_target ) - { - p_plugin->psz_target = strdup( p_plugin->psz_target ); - } - - return NPERR_NO_ERROR; + return status; } NPError NPP_Destroy( NPP instance, NPSavedData** save ) { - if( instance == NULL ) - { + if( NULL == instance ) return NPERR_INVALID_INSTANCE_ERROR; - } - VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata; + VlcPlugin* p_plugin = reinterpret_cast(instance->pdata); + if( NULL == p_plugin ) + return NPERR_NO_ERROR; - if( p_plugin != NULL ) - { - if( p_plugin->p_vlc != NULL ) - { - vlc_stop_r( p_plugin->p_vlc ); - vlc_destroy_r( p_plugin->p_vlc ); - p_plugin->p_vlc = NULL; - } - - if( p_plugin->psz_target ) - { - free( p_plugin->psz_target ); - p_plugin->psz_target = NULL; - } + instance->pdata = NULL; - delete p_plugin; +#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 - instance->pdata = NULL; + delete p_plugin; return NPERR_NO_ERROR; } NPError NPP_SetWindow( NPP instance, NPWindow* window ) { - char psz_window[32]; - - if( instance == NULL ) + if( ! instance ) { return NPERR_INVALID_INSTANCE_ERROR; } - VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata; + /* NPP_SetWindow may be called before NPP_New (Opera) */ + VlcPlugin* p_plugin = reinterpret_cast(instance->pdata); + if( ! p_plugin ) + { + /* we should probably show a splash screen here */ + return NPERR_NO_ERROR; + } - /* Write the window ID for vlc */ - sprintf( psz_window, "%li", (long int)window->window ); - vlc_set_r( p_plugin->p_vlc, "x11-drawable", psz_window ); - vlc_set_r( p_plugin->p_vlc, "xvideo-drawable", psz_window ); + libvlc_instance_t *p_vlc = p_plugin->getVLC(); /* * PLUGIN DEVELOPERS: @@ -298,108 +379,189 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window ) * size changes, etc. */ - Widget netscape_widget; + /* retrieve current window */ + NPWindow& curwin = p_plugin->getWindow(); - p_plugin->window = (Window) window->window; - p_plugin->x = window->x; - p_plugin->y = window->y; - p_plugin->width = window->width; - p_plugin->height = window->height; - p_plugin->display = ((NPSetWindowCallbackStruct *)window->ws_info)->display; +#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) ) + { + /* set/change parent window */ + libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL); + } - netscape_widget = XtWindowToWidget(p_plugin->display, p_plugin->window); - XtAddEventHandler(netscape_widget, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin); - Redraw(netscape_widget, (XtPointer)p_plugin, NULL); + /* as MacOS X video output is windowless, set viewport */ + libvlc_rectangle_t view, clip; + + /* + ** browser sets port origin to top-left location of plugin relative to GrafPort + ** window origin is set relative to document, which of little use for drawing + */ + view.top = ((NP_Port*) (window->window))->porty; + 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; + clip.bottom = window->clipRect.bottom; + clip.right = window->clipRect.right; + + libvlc_video_set_viewport(p_vlc, &view, &clip, NULL); + + /* 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 */ - p_plugin->fWindow = window; +#ifdef XP_WIN + if( window && window->window ) + { + /* check if plugin has a new parent window */ + HWND drawable = (HWND) (window->window); + if( !curwin.window || drawable != curwin.window ) + { + /* reset previous window settings */ + 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(p_plugin)); -#if 1 - if( !p_plugin->b_stream ) + /* install our WNDPROC */ + p_plugin->setWindowProc( (WNDPROC)SetWindowLong( drawable, + GWL_WNDPROC, (LONG)Manage ) ); + + /* change window style to our liking */ + LONG style = GetWindowLong((HWND)drawable, GWL_STYLE); + style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS; + SetWindowLong((HWND)drawable, GWL_STYLE, style); + + /* change/set parent */ + libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL); + + /* remember new window */ + p_plugin->setWindow(*window); + + /* Redraw window */ + InvalidateRect( (HWND)drawable, NULL, TRUE ); + UpdateWindow( (HWND)drawable ); + } + } + else if ( curwin.window ) { - int i_mode = PLAYLIST_APPEND; + /* reset WNDPROC */ + 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 */ - if( p_plugin->b_autoplay ) +#ifdef XP_UNIX + if( window && window->window ) + { + Window drawable = (Window) window->window; + if( !curwin.window || drawable != (Window)curwin.window ) { - i_mode |= PLAYLIST_GO; + Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display; + + 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 ); + + /* set/change parent window */ + libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL); + + /* remember window */ + p_plugin->setWindow(*window); + + 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 ) { - vlc_add_target_r( p_plugin->p_vlc, p_plugin->psz_target, - i_mode, PLAYLIST_END ); - p_plugin->b_stream = 1; + 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; } } -#endif - return NPERR_NO_ERROR; } 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 == 0 ) + VlcPlugin *p_plugin = reinterpret_cast(instance->pdata); + if( NULL == p_plugin ) { - p_plugin->psz_target = strdup( stream->url ); - p_plugin->b_stream = 1; + 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 = (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", len); - - if( instance != NULL ) - { - /*VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata;*/ - } - - return len; /* The number of bytes accepted */ + /* TODO */ + return len; } @@ -409,7 +571,6 @@ NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason ) { return NPERR_INVALID_INSTANCE_ERROR; } - return NPERR_NO_ERROR; } @@ -421,22 +582,20 @@ void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname ) return; } - VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata; - - fprintf(stderr, "NPP_StreamAsFile\n"); - vlc_add_target_r( p_plugin->p_vlc, fname, - PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END ); -} - -#if 0 -void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname ) -{ - fprintf(stderr,"filename : %s\n", fname); - ((VlcPlugin*) instance->pdata)->SetFileName(fname); + VlcPlugin *p_plugin = reinterpret_cast(instance->pdata); + if( NULL == p_plugin ) + { + return; + } - fprintf(stderr,"SetFileNeme ok. \n"); + 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); + } + } } -#endif void NPP_URLNotify( NPP instance, const char* url, @@ -517,31 +676,151 @@ void NPP_Print( NPP instance, NPPrint* printInfo ) } } +/****************************************************************************** + * Windows-only methods + *****************************************************************************/ +#if XP_WIN +static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ) +{ + VlcPlugin* p_plugin = reinterpret_cast(GetWindowLongPtr(p_hwnd, GWLP_USERDATA)); + + switch( i_msg ) + { + case WM_ERASEBKGND: + return 1L; + + case WM_PAINT: + { + PAINTSTRUCT paintstruct; + HDC hdc; + RECT rect; + + hdc = BeginPaint( p_hwnd, &paintstruct ); + + GetClientRect( p_hwnd, &rect ); + + 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); + + EndPaint( p_hwnd, &paintstruct ); + return 0L; + } + default: + /* delegate to default handler */ + return CallWindowProc(p_plugin->getWindowProc(), p_hwnd, i_msg, wpar, lpar ); + } +} +#endif /* XP_WIN */ + /****************************************************************************** * UNIX-only methods *****************************************************************************/ -#ifndef WIN32 +#ifdef XP_UNIX static void Redraw( Widget w, XtPointer closure, XEvent *event ) { - VlcPlugin* p_plugin = (VlcPlugin*)closure; + VlcPlugin* p_plugin = reinterpret_cast(closure); + const NPWindow& window = p_plugin->getWindow(); GC gc; XGCValues gcv; - const char * psz_text = "(no picture)"; - gcv.foreground = BlackPixel( p_plugin->display, 0 ); - gc = XCreateGC( p_plugin->display, p_plugin->window, GCForeground, &gcv ); + Window drawable = (Window) window.window; + Display *p_display = ((NPSetWindowCallbackStruct *)window.ws_info)->display; + + gcv.foreground = BlackPixel( p_display, 0 ); + gc = XCreateGC( p_display, drawable, GCForeground, &gcv ); - XFillRectangle( p_plugin->display, p_plugin->window, gc, - 0, 0, p_plugin->width, p_plugin->height ); + XFillRectangle( p_display, drawable, gc, + 0, 0, window.width, window.height ); - gcv.foreground = WhitePixel( p_plugin->display, 0 ); - XChangeGC( p_plugin->display, gc, GCForeground, &gcv ); + gcv.foreground = WhitePixel( p_display, 0 ); + XChangeGC( p_display, gc, GCForeground, &gcv ); - XDrawString( p_plugin->display, p_plugin->window, gc, - p_plugin->width / 2 - 40, p_plugin->height / 2, - psz_text, strlen(psz_text) ); + XDrawString( p_display, drawable, gc, + window.width / 2 - 40, window.height / 2, + WINDOW_TEXT, strlen(WINDOW_TEXT) ); - XFreeGC( p_plugin->display, gc ); + XFreeGC( p_display, gc ); } -#endif + +static void Resize ( Widget w, XtPointer closure, XEvent *event ) +{ + VlcPlugin* p_plugin = reinterpret_cast(closure); + const NPWindow& window = p_plugin->getWindow(); + Window drawable = (Window) window.window; + Display *p_display = ((NPSetWindowCallbackStruct *)window.ws_info)->display; + + int i_ret; + Window root_return, parent_return, * children_return; + Window base_window; + unsigned int i_nchildren; + +#ifdef X11_RESIZE_DEBUG + XWindowAttributes attr; + + if( event && event->type == ConfigureNotify ) + { + fprintf( stderr, "vlcshell::Resize() ConfigureNotify %d x %d, " + "send_event ? %s\n", event->xconfigure.width, + event->xconfigure.height, + event->xconfigure.send_event ? "TRUE" : "FALSE" ); + } +#endif /* X11_RESIZE_DEBUG */ + + if( ! p_plugin->setSize(window.width, window.height) ) + { + /* size already set */ + return; + } + + + i_ret = XResizeWindow( p_display, drawable, window.width, window.height ); + +#ifdef X11_RESIZE_DEBUG + fprintf( stderr, + "vlcshell::Resize() XResizeWindow(owner) returned %d\n", i_ret ); + + XGetWindowAttributes ( p_display, drawable, &attr ); + + /* X is asynchronous, so the current size reported here is not + necessarily the requested size as the Resize request may not + yet have been handled by the plugin host */ + fprintf( stderr, "vlcshell::Resize() current (owner) size %d x %d\n", + attr.width, attr.height ); +#endif /* X11_RESIZE_DEBUG */ + + XQueryTree( p_display, drawable, + &root_return, &parent_return, &children_return, + &i_nchildren ); + + if( i_nchildren > 0 ) + { + /* XXX: Make assumptions related to the window parenting structure in + vlc/modules/video_output/x11/xcommon.c */ + base_window = children_return[i_nchildren - 1]; + +#ifdef X11_RESIZE_DEBUG + fprintf( stderr, "vlcshell::Resize() got %d children\n", i_nchildren ); + fprintf( stderr, "vlcshell::Resize() got base_window %p\n", + base_window ); +#endif /* X11_RESIZE_DEBUG */ + + i_ret = XResizeWindow( p_display, base_window, + window.width, window.height ); + +#ifdef X11_RESIZE_DEBUG + fprintf( stderr, + "vlcshell::Resize() XResizeWindow(base) returned %d\n", + i_ret ); + + XGetWindowAttributes( p_display, base_window, &attr ); + + fprintf( stderr, "vlcshell::Resize() new size %d x %d\n", + attr.width, attr.height ); +#endif /* X11_RESIZE_DEBUG */ + } +} + +#endif /* XP_UNIX */