X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mozilla%2Fvlcshell.cpp;h=3268b09bc5f656dc2456c973d13c9434129a1b82;hb=26714f229b249ab989cecd121344689354ff355a;hp=1983daf4255084edeacfe10c08b2708c01e23424;hpb=0815f48408a4db1c0bc3e12ca55fa08591fbc8cd;p=vlc diff --git a/mozilla/vlcshell.cpp b/mozilla/vlcshell.cpp index 1983daf425..3268b09bc5 100644 --- a/mozilla/vlcshell.cpp +++ b/mozilla/vlcshell.cpp @@ -1,7 +1,7 @@ /***************************************************************************** * vlcshell.cpp: a VLC plugin for Mozilla ***************************************************************************** - * Copyright (C) 2002 VideoLAN + * Copyright (C) 2002-2005 the VideoLAN team * $Id$ * * Authors: Samuel Hocevar @@ -18,12 +18,9 @@ * * 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. *****************************************************************************/ -/* XXX: disable VLC here */ -#define USE_LIBVLC 1 - /***************************************************************************** * Preamble *****************************************************************************/ @@ -33,84 +30,54 @@ #include #include -/* vlc stuff */ -#ifdef USE_LIBVLC -# include -#endif - /* Mozilla stuff */ #ifdef HAVE_MOZILLA_CONFIG_H # include #endif -#include -#include -#include -/* This is from mozilla java, do we really need it? */ -#if 0 -#include -#endif - -#if !defined(XP_MACOSX) && !defined(XP_UNIX) && !defined(XP_WIN) -#define XP_UNIX 1 -#elif defined(XP_MACOSX) -#undef XP_UNIX -#endif - -#ifdef XP_WIN - /* Windows stuff */ +#ifdef XP_UNIX +#ifndef __APPLE__ +#include #endif - -#ifdef XP_MACOSX - /* Mac OS X stuff */ -# include #endif -#ifdef XP_UNIX - /* 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" -#if USE_LIBVLC -# define WINDOW_TEXT "(no picture)" -#else -# define WINDOW_TEXT "(no libvlc)" -#endif +/* Enable/disable debugging printf's for X11 resizing */ +#undef X11_RESIZE_DEBUG + +#define WINDOW_TEXT "Video is loading..." +#define CONTROL_HEIGHT 45 /***************************************************************************** * Unix-only declarations ******************************************************************************/ #ifdef XP_UNIX -# define VOUT_PLUGINS "xvideo,x11,dummy" -# define AOUT_PLUGINS "oss,dummy" 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 /***************************************************************************** * MacOS-only declarations ******************************************************************************/ #ifdef XP_MACOSX -# define VOUT_PLUGINS "macosx" -# define AOUT_PLUGINS "macosx" - #endif /***************************************************************************** * Windows-only declarations *****************************************************************************/ #ifdef XP_WIN -# define VOUT_PLUGINS "directx,wingdi,dummy" -# define AOUT_PLUGINS "directx,waveout,dummy" -#if defined(XP_WIN) && !USE_LIBVLC -LRESULT CALLBACK Manage( HWND, UINT, WPARAM, LPARAM ); -#endif +static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ); + #endif /****************************************************************************** @@ -124,9 +91,9 @@ 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: @@ -134,18 +101,13 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) return NPERR_NO_ERROR; case NPPVpluginDescriptionString: -#if USE_LIBVLC - snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, VLC_Version() ); -#else - snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, "(disabled)" ); -#endif - psz_desc[1000-1] = 0; + snprintf( psz_desc, sizeof(psz_desc), PLUGIN_DESCRIPTION, VLC_Version() ); *((char **)value) = psz_desc; return NPERR_NO_ERROR; default: - /* go on... */ - break; + /* move on to instance variables ... */ + ; } if( instance == NULL ) @@ -153,32 +115,44 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) return NPERR_INVALID_INSTANCE_ERROR; } - VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata; + /* plugin instance variables */ - switch( variable ) + VlcPlugin* p_plugin = reinterpret_cast(instance->pdata); + if( NULL == p_plugin ) { - case NPPVpluginScriptableInstance: - *(nsISupports**)value = p_plugin->GetPeer(); - if( *(nsISupports**)value == NULL ) - { - return NPERR_OUT_OF_MEMORY_ERROR; - } - break; + // plugin has not been initialized yet ! + return NPERR_INVALID_INSTANCE_ERROR; + } - case NPPVpluginScriptableIID: - *(nsIID**)value = (nsIID*)NPN_MemAlloc( sizeof(nsIID) ); - if( *(nsIID**)value == NULL ) + switch( variable ) + { + 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; } - **(nsIID**)value = nsid; break; + } default: - return NPERR_GENERIC_ERROR; + ; } + return NPERR_GENERIC_ERROR; +} - return NPERR_NO_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; } /****************************************************************************** @@ -187,28 +161,133 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) #ifdef XP_MACOSX int16 NPP_HandleEvent( NPP instance, void * event ) { - VlcPlugin *p_plugin = (VlcPlugin*)instance->pdata; - vlc_value_t value; + static UInt32 lastMouseUp = 0; if( instance == NULL ) { return false; } - EventRecord *pouetEvent = (EventRecord*)event; + VlcPlugin *p_plugin = (VlcPlugin*)instance->pdata; - if (pouetEvent->what == 6) + if( p_plugin == NULL ) { - value.i_int = 1; - VLC_VariableSet( p_plugin->i_vlc, "drawableredraw", value ); - return true; + return false; } - Boolean eventHandled = false; + EventRecord *myEvent = (EventRecord*)event; - return eventHandled; + switch( myEvent->what ) + { + case nullEvent: + 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_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); + } + } + } + } + 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 false; } -#endif +#endif /* XP_MACOSX */ /****************************************************************************** * General Plug-in Calls @@ -231,517 +310,305 @@ void NPP_Shutdown( void ) NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved ) { - int i; - -#if USE_LIBVLC - vlc_value_t value; - int i_ret; - -#endif + 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; - -#ifdef XP_WIN - p_plugin->p_hwnd = NULL; - p_plugin->pf_wndproc = NULL; -#endif - -#ifdef XP_UNIX - p_plugin->window = 0; - p_plugin->p_display = NULL; + status = p_plugin->init(argc, argn, argv); + if( NPERR_NO_ERROR == status ) + { + instance->pdata = reinterpret_cast(p_plugin); +#if 0 + NPN_SetValue(instance, NPPVpluginWindowBool, (void *)false); + NPN_SetValue(instance, NPPVpluginTransparentBool, (void *)false); #endif - - p_plugin->p_npwin = NULL; - p_plugin->i_npmode = mode; - p_plugin->i_width = 0; - p_plugin->i_height = 0; - -#if USE_LIBVLC - p_plugin->i_vlc = VLC_Create(); - if( p_plugin->i_vlc < 0 ) + } + else { - p_plugin->i_vlc = 0; delete p_plugin; - p_plugin = NULL; - return NPERR_GENERIC_ERROR; } + return status; +} - { -#ifdef XP_MACOSX - char *home_user; - char *directory; - char *plugin_path; - char *ppsz_argv[] = { "vlc", "--plugin-path", NULL }; - - home_user = strdup( getenv("HOME") ); - directory = strdup( "/Library/Internet Plug-Ins/VLC Plugin.plugin/" - "Contents/MacOS/modules" ); - plugin_path = malloc( strlen( directory ) + strlen( home_user ) ); - memcpy( plugin_path , home_user , strlen(home_user) ); - memcpy( plugin_path + strlen( home_user ) , directory , - strlen( directory ) ); - - ppsz_argv[2] = plugin_path; - -#elif defined(XP_WIN) - char *ppsz_argv[] = { NULL, "-vv" }; - HKEY h_key; - DWORD i_type, i_data = MAX_PATH + 1; - char p_data[MAX_PATH + 1]; - if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\VideoLAN\\VLC", - 0, KEY_READ, &h_key ) == ERROR_SUCCESS ) - { - if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type, - (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS ) - { - if( i_type == REG_SZ ) - { - strcat( p_data, "\\vlc" ); - ppsz_argv[0] = p_data; - } - } - RegCloseKey( h_key ); - } +NPError NPP_Destroy( NPP instance, NPSavedData** save ) +{ + if( NULL == instance ) + return NPERR_INVALID_INSTANCE_ERROR; - if( !ppsz_argv[0] ) ppsz_argv[0] = "vlc"; + VlcPlugin* p_plugin = reinterpret_cast(instance->pdata); + if( NULL == p_plugin ) + return NPERR_NO_ERROR; -#else - char *ppsz_argv[] = - { - "vlc" - /*, "--plugin-path", "/home/sam/videolan/vlc_MAIN/plugins"*/ - }; + 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 - i_ret = VLC_Init( p_plugin->i_vlc, sizeof(ppsz_argv)/sizeof(char*), - ppsz_argv ); + delete p_plugin; -#ifdef XP_MACOSX - free( home_user ); - free( directory ); - free( plugin_path ); -#endif - } + return NPERR_NO_ERROR; +} - if( i_ret ) +NPError NPP_SetWindow( NPP instance, NPWindow* window ) +{ + if( ! instance ) { - VLC_Destroy( p_plugin->i_vlc ); - p_plugin->i_vlc = 0; - delete p_plugin; - p_plugin = NULL; - return NPERR_GENERIC_ERROR; + return NPERR_INVALID_INSTANCE_ERROR; } - value.psz_string = "dummy"; - VLC_VariableSet( p_plugin->i_vlc, "conf::intf", value ); - value.psz_string = VOUT_PLUGINS; - VLC_VariableSet( p_plugin->i_vlc, "conf::vout", value ); - value.psz_string = AOUT_PLUGINS; - VLC_VariableSet( p_plugin->i_vlc, "conf::aout", value ); + /* 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; + } -#else - p_plugin->i_vlc = 1; + libvlc_instance_t *p_vlc = p_plugin->getVLC(); -#endif /* USE_LIBVLC */ + /* + * PLUGIN DEVELOPERS: + * Before setting window to point to the + * new window, you may wish to compare the new window + * info to the previous window (if any) to note window + * size changes, etc. + */ - p_plugin->b_stream = VLC_FALSE; - p_plugin->b_autoplay = VLC_FALSE; - p_plugin->psz_target = NULL; + /* retrieve current window */ + NPWindow& curwin = p_plugin->getWindow(); - for( i = 0; i < argc ; i++ ) +#ifdef XP_MACOSX + if( window && window->window ) { - 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], "autostart" ) ) - { - if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "true" ) ) - { - p_plugin->b_autoplay = 1; - } - } - else if( !strcmp( argn[i], "filename" ) ) + /* check if plugin has a new parent window */ + CGrafPtr drawable = (((NP_Port*) (window->window))->port); + if( !curwin.window || drawable != (((NP_Port*) (curwin.window))->port) ) { - p_plugin->psz_target = argv[i]; - } - else if( !strcmp( argn[i], "src" ) ) - { - p_plugin->psz_target = argv[i]; + /* set/change parent window */ + libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL); } -#if USE_LIBVLC - else if( !strcmp( argn[i], "loop" ) ) - { - if( !strcmp( argv[i], "yes" ) ) - { - value.b_bool = VLC_TRUE; - VLC_VariableSet( p_plugin->i_vlc, "conf::loop", value ); - } - } - else if( !strcmp( argn[i], "fullscreen" ) ) - { - if( !strcmp( argv[i], "yes" ) ) - { - value.b_bool = VLC_TRUE; - VLC_VariableSet( p_plugin->i_vlc, "conf::fullscreen", value ); - } - } - else if( !strcmp( argn[i], "mute" ) ) - { - if( !strcmp( argv[i], "yes" ) ) - { - VLC_VolumeMute( p_plugin->i_vlc ); - } - } -#endif + /* 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); } - - if( p_plugin->psz_target ) - { - p_plugin->psz_target = strdup( p_plugin->psz_target ); + else if( curwin.window ) { + /* change/set parent */ + libvlc_video_set_parent(p_vlc, 0, NULL); + curwin.window = NULL; } - - return NPERR_NO_ERROR; -} +#endif /* XP_MACOSX */ #ifdef XP_WIN -/* This is really ugly but there is a deadlock when stopping a stream - * (in VLC_CleanUp()) because the video output is a child of the drawable but - * is in a different thread. */ -static void HackStopVout( VlcPlugin* p_plugin ) -{ - MSG msg; - HWND hwnd; - vlc_value_t value; + 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)); - VLC_VariableGet( p_plugin->i_vlc, "drawable", &value ); + /* install our WNDPROC */ + p_plugin->setWindowProc( (WNDPROC)SetWindowLong( drawable, + GWL_WNDPROC, (LONG)Manage ) ); - hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 ); - if( !hwnd ) return; + /* change window style to our liking */ + LONG style = GetWindowLong((HWND)drawable, GWL_STYLE); + style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS; + SetWindowLong((HWND)drawable, GWL_STYLE, style); - PostMessage( hwnd, WM_CLOSE, 0, 0 ); + /* change/set parent */ + libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL); - do - { - fprintf( stderr, "FindWindow: %p\n", hwnd ); - while( PeekMessage( &msg, (HWND)value.i_int, 0, 0, PM_REMOVE ) ) - { - TranslateMessage(&msg); - DispatchMessage(&msg); + /* remember new window */ + p_plugin->setWindow(*window); + + /* Redraw window */ + InvalidateRect( (HWND)drawable, NULL, TRUE ); + UpdateWindow( (HWND)drawable ); } - if( FindWindowEx( (HWND)value.i_int, 0, 0, 0 ) ) Sleep( 10 ); } - while( (hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 )) ); -} -#endif - -NPError NPP_Destroy( NPP instance, NPSavedData** save ) -{ - if( instance == NULL ) + else if ( curwin.window ) { - return NPERR_INVALID_INSTANCE_ERROR; + /* 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 */ - VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata; - - if( p_plugin != NULL ) +#ifdef XP_UNIX + if( window && window->window ) { - if( p_plugin->i_vlc ) + Window parent = (Window) window->window; + if( !curwin.window || (parent != (Window)curwin.window) ) { -#if USE_LIBVLC -# ifdef XP_WIN - HackStopVout( p_plugin ); -# endif - VLC_CleanUp( p_plugin->i_vlc ); - VLC_Destroy( p_plugin->i_vlc ); -#endif - p_plugin->i_vlc = 0; - } + Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display; - if( p_plugin->psz_target ) - { - free( p_plugin->psz_target ); - p_plugin->psz_target = NULL; - } + XResizeWindow( p_display, parent, window->width, window->height ); - delete p_plugin; - } + int i_blackColor = BlackPixel(p_display, DefaultScreen(p_display)); - instance->pdata = NULL; + 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 ); - return NPERR_NO_ERROR; -} + XMapWindow( p_display, parent ); + XMapWindow( p_display, video ); + XMapWindow( p_display, controls ); -NPError NPP_SetWindow( NPP instance, NPWindow* window ) -{ - vlc_value_t value; -#ifdef XP_MACOSX - vlc_value_t valuex; - vlc_value_t valuey; - vlc_value_t valuew; - vlc_value_t valueh; - vlc_value_t valuet; - vlc_value_t valuel; - vlc_value_t valueb; - vlc_value_t valuer; - vlc_value_t valueportx; - vlc_value_t valueporty; - Rect black_rect; - char * text; -#endif + XFlush(p_display); - if( instance == NULL ) - { - return NPERR_INVALID_INSTANCE_ERROR; - } + Widget w = XtWindowToWidget( p_display, parent ); - VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata; + XtAddEventHandler( w, ExposureMask, FALSE, + (XtEventHandler)Redraw, p_plugin ); + XtAddEventHandler( w, StructureNotifyMask, FALSE, + (XtEventHandler)Resize, p_plugin ); + XtAddEventHandler( w, ButtonReleaseMask, FALSE, + (XtEventHandler)ControlHandler, p_plugin ); - /* Write the window ID for vlc */ -#if USE_LIBVLC + /* callback */ +/* + libvlc_media_instance_t *p_md; -#ifdef XP_MACOSX - value.i_int = ((NP_Port*) (window->window))->port; - VLC_VariableSet( p_plugin->i_vlc, "drawable", value ); - - valueportx.i_int = ((NP_Port*) (window->window))->portx; - valueporty.i_int = ((NP_Port*) (window->window))->porty; - VLC_VariableSet( p_plugin->i_vlc, "drawableportx", valueportx ); - VLC_VariableSet( p_plugin->i_vlc, "drawableporty", valueporty ); - - valuex.i_int = window->x; - valuey.i_int = window->y; - valuew.i_int = window->width; - valueh.i_int = window->height; - valuet.i_int = window->clipRect.top; - valuel.i_int = window->clipRect.left; - valueb.i_int = window->clipRect.bottom; - valuer.i_int = window->clipRect.right; - - VLC_VariableSet( p_plugin->i_vlc, "drawablet", valuet ); - VLC_VariableSet( p_plugin->i_vlc, "drawablel", valuel ); - VLC_VariableSet( p_plugin->i_vlc, "drawableb", valueb ); - VLC_VariableSet( p_plugin->i_vlc, "drawabler", valuer ); - VLC_VariableSet( p_plugin->i_vlc, "drawablex", valuex ); - VLC_VariableSet( p_plugin->i_vlc, "drawabley", valuey ); - VLC_VariableSet( p_plugin->i_vlc, "drawablew", valuew ); - VLC_VariableSet( p_plugin->i_vlc, "drawableh", valueh ); - - p_plugin->window = window; - - /* draw the beautiful "No Picture" */ - - black_rect.top = valuet.i_int - valuey.i_int; - black_rect.left = valuel.i_int - valuex.i_int; - black_rect.bottom = valueb.i_int - valuey.i_int; - black_rect.right = valuer.i_int - valuex.i_int; - - SetPort( value.i_int ); - SetOrigin( valueportx.i_int , valueporty.i_int ); - ForeColor(blackColor); - PenMode( patCopy ); - PaintRect( &black_rect ); - - ForeColor(whiteColor); - text = strdup( WINDOW_TEXT ); - MoveTo( valuew.i_int / 2 - 40 , valueh.i_int / 2 ); - DrawText( text , 0 , strlen(text) ); - free(text); - -#else - /* FIXME: this cast sucks */ - value.i_int = (int) (ptrdiff_t) (void *) window->window; - VLC_VariableSet( p_plugin->i_vlc, "drawable", value ); -#endif + 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 ); +*/ -#endif + /* set/change parent window */ + libvlc_video_set_parent( p_vlc, (libvlc_drawable_t) video, NULL ); - /* - * PLUGIN DEVELOPERS: - * Before setting window to point to the - * new window, you may wish to compare the new window - * info to the previous window (if any) to note window - * size changes, etc. - */ + /* remember window */ + p_plugin->setWindow( *window ); + p_plugin->setVideoWindow( video ); + p_plugin->setControlWindow( controls ); -#ifdef XP_WIN - if( !window || !window->window ) - { - /* Window was destroyed. Invalidate everything. */ - if( p_plugin->p_npwin ) - { -#if !USE_LIBVLC - SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC, - (LONG)p_plugin->pf_wndproc ); -#endif - p_plugin->pf_wndproc = NULL; - p_plugin->p_hwnd = NULL; + Redraw( w, (XtPointer)p_plugin, NULL ); } - - p_plugin->p_npwin = window; - return NPERR_NO_ERROR; } - - if( p_plugin->p_npwin ) + else if ( curwin.window ) { - if( p_plugin->p_hwnd == (HWND)window->window ) - { - /* Same window, but something may have changed. First we - * update the plugin structure, then we redraw the window */ - p_plugin->i_width = window->width; - p_plugin->i_height = window->height; - p_plugin->p_npwin = window; -#if !USE_LIBVLC - InvalidateRect( p_plugin->p_hwnd, NULL, TRUE ); - UpdateWindow( p_plugin->p_hwnd ); -#endif - return NPERR_NO_ERROR; - } - - /* Window has changed. Destroy the one we have, and go - * on as if it was a real initialization. */ -#if !USE_LIBVLC - SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC, - (LONG)p_plugin->pf_wndproc ); -#endif - p_plugin->pf_wndproc = NULL; - p_plugin->p_hwnd = NULL; + /* change/set parent */ + libvlc_video_set_parent(p_vlc, 0, NULL); + curwin.window = NULL; } - -#if !USE_LIBVLC - p_plugin->pf_wndproc = (WNDPROC)SetWindowLong( (HWND)window->window, - GWL_WNDPROC, (LONG)Manage ); -#endif - - p_plugin->p_hwnd = (HWND)window->window; - SetProp( p_plugin->p_hwnd, "w00t", (HANDLE)p_plugin ); - InvalidateRect( p_plugin->p_hwnd, NULL, TRUE ); - UpdateWindow( p_plugin->p_hwnd ); -#endif - -#ifdef XP_UNIX - p_plugin->window = (Window) window->window; - p_plugin->p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display; - - Widget w = XtWindowToWidget( p_plugin->p_display, p_plugin->window ); - XtAddEventHandler( w, ExposureMask, FALSE, - (XtEventHandler)Redraw, p_plugin ); - Redraw( w, (XtPointer)p_plugin, NULL ); -#endif - - p_plugin->p_npwin = window; - - p_plugin->i_width = window->width; - p_plugin->i_height = window->height; +#endif /* XP_UNIX */ if( !p_plugin->b_stream ) { - int i_mode = PLAYLIST_APPEND; - - if( p_plugin->b_autoplay ) - { - i_mode |= PLAYLIST_GO; - } - if( p_plugin->psz_target ) { -#if USE_LIBVLC - VLC_AddTarget( p_plugin->i_vlc, p_plugin->psz_target, - 0, 0, i_mode, PLAYLIST_END ); -#endif + 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; } } - 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 ) + VlcPlugin *p_plugin = reinterpret_cast(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 = (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; } @@ -751,7 +618,6 @@ NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason ) { return NPERR_INVALID_INSTANCE_ERROR; } - return NPERR_NO_ERROR; } @@ -763,14 +629,19 @@ void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname ) return; } - /* fprintf(stderr, "NPP_StreamAsFile %s\n", fname); */ - -#if USE_LIBVLC - VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata; + VlcPlugin *p_plugin = reinterpret_cast(instance->pdata); + if( NULL == p_plugin ) + { + return; + } - VLC_AddTarget( p_plugin->i_vlc, fname, 0, 0, - PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END ); -#endif + 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); + } + } } @@ -855,13 +726,16 @@ void NPP_Print( NPP instance, NPPrint* printInfo ) /****************************************************************************** * Windows-only methods *****************************************************************************/ -#if defined(XP_WIN) && !USE_LIBVLC -LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ) +#if XP_WIN +static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ) { - VlcPlugin* p_plugin = (VlcPlugin*) GetProp( p_hwnd, "w00t" ); + VlcPlugin* p_plugin = reinterpret_cast(GetWindowLongPtr(p_hwnd, GWLP_USERDATA)); switch( i_msg ) { + case WM_ERASEBKGND: + return 1L; + case WM_PAINT: { PAINTSTRUCT paintstruct; @@ -871,20 +745,22 @@ LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ) hdc = BeginPaint( p_hwnd, &paintstruct ); GetClientRect( p_hwnd, &rect ); - FillRect( hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH) ); - TextOut( hdc, p_plugin->i_width / 2 - 40, p_plugin->i_height / 2, - WINDOW_TEXT, strlen(WINDOW_TEXT) ); + + 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 ); - break; + return 0L; } default: - p_plugin->pf_wndproc( p_hwnd, i_msg, wpar, lpar ); - break; + /* delegate to default handler */ + return CallWindowProc(p_plugin->getWindowProc(), p_hwnd, i_msg, wpar, lpar ); } - return 0; } -#endif +#endif /* XP_WIN */ /****************************************************************************** * UNIX-only methods @@ -892,24 +768,338 @@ LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ) #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; - gcv.foreground = BlackPixel( p_plugin->p_display, 0 ); - gc = XCreateGC( p_plugin->p_display, p_plugin->window, GCForeground, &gcv ); + /* 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; - XFillRectangle( p_plugin->p_display, p_plugin->window, gc, - 0, 0, p_plugin->i_width, p_plugin->i_height ); + gcv.foreground = BlackPixel( p_display, 0 ); + gc = XCreateGC( p_display, video, GCForeground, &gcv ); - gcv.foreground = WhitePixel( p_plugin->p_display, 0 ); - XChangeGC( p_plugin->p_display, gc, GCForeground, &gcv ); + XFillRectangle( p_display, video, gc, + 0, 0, window.width, window.height - CONTROL_HEIGHT ); - XDrawString( p_plugin->p_display, p_plugin->window, gc, - p_plugin->i_width / 2 - 40, p_plugin->i_height / 2, + gcv.foreground = WhitePixel( p_display, 0 ); + XChangeGC( p_display, gc, GCForeground, &gcv ); + + XDrawString( p_display, video, gc, + window.width / 2 - 40, (window.height - CONTROL_HEIGHT) / 2, WINDOW_TEXT, strlen(WINDOW_TEXT) ); - XFreeGC( p_plugin->p_display, gc ); -} + /* 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(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(closure); + const NPWindow& window = 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; + 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 - CONTROL_HEIGHT)) ) + { + /* size already set */ + return; + } + + + i_ret = XResizeWindow( p_display, drawable, window.width, (window.height - CONTROL_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 - CONTROL_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 */ +