]> git.sesse.net Git - vlc/blob - mozilla/vlcshell.cpp
SRTP/SRTCP receive window for replay attack protection
[vlc] / mozilla / vlcshell.cpp
1 /*****************************************************************************
2  * vlcshell.cpp: a VLC plugin for Mozilla
3  *****************************************************************************
4  * Copyright (C) 2002-2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include "config.h"
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32
33 /* Mozilla stuff */
34 #ifdef HAVE_MOZILLA_CONFIG_H
35 #   include <mozilla-config.h>
36 #endif
37
38 /* This is from mozilla java, do we really need it? */
39 #if 0
40 #include <jri.h>
41 #endif
42
43 #include "vlcplugin.h"
44
45 /* Enable/disable debugging printf's for X11 resizing */
46 #undef X11_RESIZE_DEBUG
47
48 #define WINDOW_TEXT "(no video)"
49
50 /*****************************************************************************
51  * Unix-only declarations
52 ******************************************************************************/
53 #ifdef XP_UNIX
54
55 static void Redraw( Widget w, XtPointer closure, XEvent *event );
56 static void Resize( Widget w, XtPointer closure, XEvent *event );
57
58 #endif
59
60 /*****************************************************************************
61  * MacOS-only declarations
62 ******************************************************************************/
63 #ifdef XP_MACOSX
64 #endif
65
66 /*****************************************************************************
67  * Windows-only declarations
68  *****************************************************************************/
69 #ifdef XP_WIN
70
71 static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar );
72
73 #endif
74
75 /******************************************************************************
76  * UNIX-only API calls
77  *****************************************************************************/
78 char * NPP_GetMIMEDescription( void )
79 {
80     return PLUGIN_MIMETYPES;
81 }
82
83 NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
84 {
85
86     static char psz_desc[1000];
87
88     /* plugin class variables */
89     switch( variable )
90     {
91         case NPPVpluginNameString:
92             *((char **)value) = PLUGIN_NAME;
93             return NPERR_NO_ERROR;
94
95         case NPPVpluginDescriptionString:
96             snprintf( psz_desc, sizeof(psz_desc), PLUGIN_DESCRIPTION, VLC_Version() );
97             *((char **)value) = psz_desc;
98             return NPERR_NO_ERROR;
99
100         default:
101             /* move on to instance variables ... */
102             break;
103     }
104
105     if( instance == NULL )
106     {
107         return NPERR_INVALID_INSTANCE_ERROR;
108     }
109
110     /* plugin instance variables */
111
112     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
113     if( NULL == p_plugin )
114     {
115         // plugin has not been initialized yet !
116         return NPERR_INVALID_INSTANCE_ERROR;
117     }
118
119     switch( variable )
120     {
121         case NPPVpluginScriptableNPObject:
122             /* create an instance and return it */
123             *(NPObject**)value = p_plugin->getScriptObject();
124             if( NULL == *(NPObject**)value )
125             {
126                 return NPERR_OUT_OF_MEMORY_ERROR;
127             }
128             break;
129
130         default:
131             return NPERR_GENERIC_ERROR;
132     }
133     return NPERR_NO_ERROR;
134 }
135
136 /******************************************************************************
137  * Mac-only API calls
138  *****************************************************************************/
139 #ifdef XP_MACOSX
140 int16 NPP_HandleEvent( NPP instance, void * event )
141 {
142     static UInt32 lastMouseUp = 0;
143
144     if( instance == NULL )
145     {
146         return false;
147     }
148
149     VlcPlugin *p_plugin = (VlcPlugin*)instance->pdata;
150     EventRecord *myEvent = (EventRecord*)event;
151
152     switch( myEvent->what )
153     {
154         case nullEvent:
155             break;
156         case mouseDown:
157         {
158             if( (myEvent->when - lastMouseUp) < GetDblTime() )
159             {
160                 /* double click */
161                 libvlc_instance_t *p_vlc = p_plugin->getVLC();
162
163                 if( p_vlc )
164                 {
165                     if( libvlc_playlist_isplaying(p_vlc, NULL) )
166                     {
167                         libvlc_input_t *p_input = libvlc_playlist_get_input(p_vlc, NULL);
168                         if( p_input )
169                         {
170                             libvlc_toggle_fullscreen(p_input, NULL);
171                             libvlc_input_free(p_input);
172                         }
173                     }
174                 }
175             }
176             return true;
177         }
178         case mouseUp:
179             lastMouseUp = myEvent->when;
180             return true;
181         case keyUp:
182         case keyDown:
183         case autoKey:
184             return true;
185         case updateEvt:
186         {
187             int needsDisplay = TRUE;
188             libvlc_instance_t *p_vlc = p_plugin->getVLC();
189
190             if( p_vlc )
191             {
192                 if( libvlc_playlist_isplaying(p_vlc, NULL) )
193                 {
194                     libvlc_input_t *p_input = libvlc_playlist_get_input(p_vlc, NULL);
195                     if( p_input )
196                     {
197                         needsDisplay = ! libvlc_input_has_vout(p_input, NULL);
198                         libvlc_input_free(p_input);
199                     }
200                 }
201             }
202
203             const NPWindow *npwindow = p_plugin->getWindow();
204
205             if( needsDisplay && npwindow->window )
206             {
207                 /* draw the beautiful "No Picture" */
208
209                 ForeColor(blackColor);
210                 PenMode( patCopy );
211
212                 /* seems that firefox forgets to set the following on occasion (reload) */
213                 SetOrigin(((NP_Port *)npwindow->window)->portx, ((NP_Port *)npwindow->window)->porty);
214
215                 Rect rect;
216                 rect.left = 0;
217                 rect.top = 0;
218                 rect.right = npwindow->width;
219                 rect.bottom = npwindow->height;
220                 PaintRect( &rect );
221
222                 ForeColor(whiteColor);
223                 MoveTo( (npwindow->width-80)/ 2  , npwindow->height / 2 );
224                 DrawText( WINDOW_TEXT , 0 , strlen(WINDOW_TEXT) );
225             }
226             return true;
227         }
228         case activateEvt:
229             return false;
230         case NPEventType_GetFocusEvent:
231         case NPEventType_LoseFocusEvent:
232             return true;
233         case NPEventType_AdjustCursorEvent:
234             return false;
235         case NPEventType_MenuCommandEvent:
236             return false;
237         case NPEventType_ClippingChangedEvent:
238             return false;
239         case NPEventType_ScrollingBeginsEvent:
240         case NPEventType_ScrollingEndsEvent:
241             return true;
242         default:
243             ;
244     }
245     return false;
246 }
247 #endif /* XP_MACOSX */
248
249 /******************************************************************************
250  * General Plug-in Calls
251  *****************************************************************************/
252 NPError NPP_Initialize( void )
253 {
254     return NPERR_NO_ERROR;
255 }
256
257 jref NPP_GetJavaClass( void )
258 {
259     return NULL;
260 }
261
262 void NPP_Shutdown( void )
263 {
264     ;
265 }
266
267 NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
268                  char* argn[], char* argv[], NPSavedData* saved )
269 {
270     NPError status;
271
272     if( instance == NULL )
273     {
274         return NPERR_INVALID_INSTANCE_ERROR;
275     }
276
277     VlcPlugin * p_plugin = new VlcPlugin( instance, mode );
278     if( NULL == p_plugin )
279     {
280         return NPERR_OUT_OF_MEMORY_ERROR;
281     }
282
283     status = p_plugin->init(argc, argn, argv);
284     if( NPERR_NO_ERROR == status ) {
285         instance->pdata = reinterpret_cast<void*>(p_plugin);
286     }
287     else {
288         delete p_plugin;
289     }
290     return status;
291 }
292
293 NPError NPP_Destroy( NPP instance, NPSavedData** save )
294 {
295     if( NULL == instance )
296         return NPERR_INVALID_INSTANCE_ERROR;
297
298     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
299     if( NULL == p_plugin )
300         return NPERR_NO_ERROR;
301
302     instance->pdata = NULL;
303
304 #if XP_WIN
305     HWND win = (HWND)p_plugin->getWindow()->window;
306     WNDPROC winproc = p_plugin->getWindowProc();
307     if( winproc )
308     {
309         /* reset WNDPROC */
310         SetWindowLong( win, GWL_WNDPROC, (LONG)winproc );
311     }
312 #endif
313
314     if( p_plugin )
315         delete p_plugin;
316
317     return NPERR_NO_ERROR;
318 }
319
320 NPError NPP_SetWindow( NPP instance, NPWindow* window )
321 {
322     if( ! instance )
323     {
324         return NPERR_INVALID_INSTANCE_ERROR;
325     }
326
327     /* NPP_SetWindow may be called before NPP_New (Opera) */
328     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
329     if( ! p_plugin )
330     {
331         /* we should probably show a splash screen here */
332         return NPERR_NO_ERROR;
333     }
334
335     libvlc_instance_t *p_vlc = p_plugin->getVLC();
336
337     /*
338      * PLUGIN DEVELOPERS:
339      *  Before setting window to point to the
340      *  new window, you may wish to compare the new window
341      *  info to the previous window (if any) to note window
342      *  size changes, etc.
343      */
344
345     const NPWindow *curwin = p_plugin->getWindow();
346
347 #ifdef XP_MACOSX
348     if( window && window->window )
349     {
350         /* check if plugin has a new parent window */
351         CGrafPtr drawable = (((NP_Port*) (window->window))->port);
352         if( !curwin->window || drawable != (((NP_Port*) (curwin->window))->port) )
353         {
354             /* set/change parent window */
355             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
356         }
357
358         /* as MacOS X video output is windowless, set viewport */
359         libvlc_rectangle_t view, clip;
360
361         /*
362         ** browser sets port origin to top-left location of plugin relative to GrafPort
363         ** window origin is set relative to document, which of little use for drawing
364         */
365         view.top     = ((NP_Port*) (window->window))->porty;
366         view.left    = ((NP_Port*) (window->window))->portx;
367         view.bottom  = window->height+view.top;
368         view.right   = window->width+view.left;
369         /* clipRect coordinates are also relative to GrafPort */
370         clip.top     = window->clipRect.top;
371         clip.left    = window->clipRect.left;
372         clip.bottom  = window->clipRect.bottom;
373         clip.right   = window->clipRect.right;
374
375         libvlc_video_set_viewport(p_vlc, &view, &clip, NULL);
376
377         /* remember window details */
378         p_plugin->setWindow(window);
379     }
380 #endif /* XP_MACOSX */
381
382 #ifdef XP_WIN
383     if( window && window->window )
384     {
385         /* check if plugin has a new parent window */
386         HWND drawable = (HWND) (window->window);
387         if( !curwin->window || drawable != curwin->window )
388         {
389             /* reset previous window settings */
390             HWND oldwin = (HWND)p_plugin->getWindow()->window;
391             WNDPROC oldproc = p_plugin->getWindowProc();
392             if( oldproc )
393             {
394                 /* reset WNDPROC */
395                 SetWindowLong( oldwin, GWL_WNDPROC, (LONG)oldproc );
396             }
397             /* attach our plugin object */
398             SetWindowLongPtr((HWND)drawable, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(p_plugin));
399
400             /* install our WNDPROC */
401             p_plugin->setWindowProc( (WNDPROC)SetWindowLong( drawable,
402                                                            GWL_WNDPROC, (LONG)Manage ) );
403
404             /* change window style to our liking */
405             LONG style = GetWindowLong((HWND)drawable, GWL_STYLE);
406             style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
407             SetWindowLong((HWND)drawable, GWL_STYLE, style);
408
409             /* change/set parent */
410             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
411         }
412
413         /* remember window details */
414         p_plugin->setWindow(window);
415
416         /* Redraw window */
417         InvalidateRect( (HWND)drawable, NULL, TRUE );
418         UpdateWindow( (HWND)drawable );
419     }
420     else
421     {
422         /* reset WNDPROC */
423         HWND oldwin = (HWND)curwin->window;
424         SetWindowLong( oldwin, GWL_WNDPROC, (LONG)(p_plugin->getWindowProc()) );
425         p_plugin->setWindowProc(NULL);
426         /* change/set parent */
427         libvlc_video_set_parent(p_vlc, 0, NULL);
428     }
429 #endif /* XP_WIN */
430
431 #ifdef XP_UNIX
432     if( window && window->window )
433     {
434         Window  drawable   = (Window) window->window;
435         if( !curwin->window || drawable != (Window)curwin->window )
436         {
437             Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
438
439             XResizeWindow( p_display, drawable, window->width, window->height );
440             Widget w = XtWindowToWidget( p_display, drawable );
441
442             XtAddEventHandler( w, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin );
443             XtAddEventHandler( w, StructureNotifyMask, FALSE, (XtEventHandler)Resize, p_plugin );
444
445             /* set/change parent window */
446             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
447
448             /* remember window */
449             p_plugin->setWindow(window);
450
451             Redraw( w, (XtPointer)p_plugin, NULL );
452         }
453     }
454 #endif /* XP_UNIX */
455
456     if( !p_plugin->b_stream )
457     {
458         if( p_plugin->psz_target )
459         {
460             if( libvlc_playlist_add( p_vlc, p_plugin->psz_target, NULL, NULL ) != -1 )
461             {
462                 if( p_plugin->b_autoplay )
463                 {
464                     libvlc_playlist_play(p_vlc, 0, 0, NULL, NULL);
465                 }
466             }
467             p_plugin->b_stream = VLC_TRUE;
468         }
469     }
470     return NPERR_NO_ERROR;
471 }
472
473 NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
474                        NPBool seekable, uint16 *stype )
475 {
476     if( NULL == instance  )
477     {
478         return NPERR_INVALID_INSTANCE_ERROR;
479     }
480
481     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(instance->pdata);
482
483    /*
484    ** Firefox/Mozilla may decide to open a stream from the URL specified
485    ** in the SRC parameter of the EMBED tag and pass it to us
486    **
487    ** since VLC will open the SRC URL as well, we're not interested in
488    ** that stream. Otherwise, we'll take it and queue it up in the playlist
489    */
490     if( !p_plugin->psz_target || strcmp(stream->url, p_plugin->psz_target) )
491     {
492         /* TODO: use pipes !!!! */
493         *stype = NP_ASFILEONLY;
494         return NPERR_NO_ERROR;
495     }
496     return NPERR_GENERIC_ERROR;
497 }
498
499 int32 NPP_WriteReady( NPP instance, NPStream *stream )
500 {
501     /* TODO */
502     return 8*1024;
503 }
504
505
506 int32 NPP_Write( NPP instance, NPStream *stream, int32 offset,
507                  int32 len, void *buffer )
508 {
509     /* TODO */
510     return len;
511 }
512
513
514 NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason )
515 {
516     if( instance == NULL )
517     {
518         return NPERR_INVALID_INSTANCE_ERROR;
519     }
520     return NPERR_NO_ERROR;
521 }
522
523
524 void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
525 {
526     if( instance == NULL )
527     {
528         return;
529     }
530
531     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(instance->pdata);
532
533     if( libvlc_playlist_add( p_plugin->getVLC(), fname, stream->url, NULL ) != -1 )
534     {
535         if( p_plugin->b_autoplay )
536         {
537             libvlc_playlist_play( p_plugin->getVLC(), 0, 0, NULL, NULL);
538         }
539     }
540 }
541
542
543 void NPP_URLNotify( NPP instance, const char* url,
544                     NPReason reason, void* notifyData )
545 {
546     /***** Insert NPP_URLNotify code here *****\
547     PluginInstance* p_plugin;
548     if (instance != NULL)
549         p_plugin = (PluginInstance*) instance->pdata;
550     \*********************************************/
551 }
552
553
554 void NPP_Print( NPP instance, NPPrint* printInfo )
555 {
556     if( printInfo == NULL )
557     {
558         return;
559     }
560
561     if( instance != NULL )
562     {
563         /***** Insert NPP_Print code here *****\
564         PluginInstance* p_plugin = (PluginInstance*) instance->pdata;
565         \**************************************/
566
567         if( printInfo->mode == NP_FULL )
568         {
569             /*
570              * PLUGIN DEVELOPERS:
571              *  If your plugin would like to take over
572              *  printing completely when it is in full-screen mode,
573              *  set printInfo->pluginPrinted to TRUE and print your
574              *  plugin as you see fit.  If your plugin wants Netscape
575              *  to handle printing in this case, set
576              *  printInfo->pluginPrinted to FALSE (the default) and
577              *  do nothing.  If you do want to handle printing
578              *  yourself, printOne is true if the print button
579              *  (as opposed to the print menu) was clicked.
580              *  On the Macintosh, platformPrint is a THPrint; on
581              *  Windows, platformPrint is a structure
582              *  (defined in npapi.h) containing the printer name, port,
583              *  etc.
584              */
585
586             /***** Insert NPP_Print code here *****\
587             void* platformPrint =
588                 printInfo->print.fullPrint.platformPrint;
589             NPBool printOne =
590                 printInfo->print.fullPrint.printOne;
591             \**************************************/
592
593             /* Do the default*/
594             printInfo->print.fullPrint.pluginPrinted = FALSE;
595         }
596         else
597         {
598             /* If not fullscreen, we must be embedded */
599             /*
600              * PLUGIN DEVELOPERS:
601              *  If your plugin is embedded, or is full-screen
602              *  but you returned false in pluginPrinted above, NPP_Print
603              *  will be called with mode == NP_EMBED.  The NPWindow
604              *  in the printInfo gives the location and dimensions of
605              *  the embedded plugin on the printed page.  On the
606              *  Macintosh, platformPrint is the printer port; on
607              *  Windows, platformPrint is the handle to the printing
608              *  device context.
609              */
610
611             /***** Insert NPP_Print code here *****\
612             NPWindow* printWindow =
613                 &(printInfo->print.embedPrint.window);
614             void* platformPrint =
615                 printInfo->print.embedPrint.platformPrint;
616             \**************************************/
617         }
618     }
619 }
620
621 /******************************************************************************
622  * Windows-only methods
623  *****************************************************************************/
624 #if XP_WIN
625 static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar )
626 {
627     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(GetWindowLongPtr(p_hwnd, GWLP_USERDATA));
628
629     switch( i_msg )
630     {
631         case WM_ERASEBKGND:
632             return 1L;
633
634         case WM_PAINT:
635         {
636             PAINTSTRUCT paintstruct;
637             HDC hdc;
638             RECT rect;
639
640             hdc = BeginPaint( p_hwnd, &paintstruct );
641
642             GetClientRect( p_hwnd, &rect );
643
644             FillRect( hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH) );
645             SetTextColor(hdc, RGB(255, 255, 255));
646             SetBkColor(hdc, RGB(0, 0, 0));
647             DrawText( hdc, WINDOW_TEXT, strlen(WINDOW_TEXT), &rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
648
649             EndPaint( p_hwnd, &paintstruct );
650             return 0L;
651         }
652         default:
653             /* delegate to default handler */
654             return p_plugin->getWindowProc()( p_hwnd, i_msg, wpar, lpar );
655     }
656 }
657 #endif /* XP_WIN */
658
659 /******************************************************************************
660  * UNIX-only methods
661  *****************************************************************************/
662 #ifdef XP_UNIX
663 static void Redraw( Widget w, XtPointer closure, XEvent *event )
664 {
665     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
666     const NPWindow *window = p_plugin->getWindow();
667     GC gc;
668     XGCValues gcv;
669
670     Window  drawable   = (Window) window->window;
671     Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
672
673     gcv.foreground = BlackPixel( p_display, 0 );
674     gc = XCreateGC( p_display, drawable, GCForeground, &gcv );
675
676     XFillRectangle( p_display, drawable, gc,
677                     0, 0, window->width, window->height );
678
679     gcv.foreground = WhitePixel( p_display, 0 );
680     XChangeGC( p_display, gc, GCForeground, &gcv );
681
682     XDrawString( p_display, drawable, gc,
683                  window->width / 2 - 40, window->height / 2,
684                  WINDOW_TEXT, strlen(WINDOW_TEXT) );
685
686     XFreeGC( p_display, gc );
687 }
688
689 static void Resize ( Widget w, XtPointer closure, XEvent *event )
690 {
691     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
692     const NPWindow *window = p_plugin->getWindow();
693     Window  drawable   = (Window) window->window;
694     Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
695
696     int i_ret;
697     Window root_return, parent_return, * children_return;
698     Window base_window;
699     unsigned int i_nchildren;
700
701 #ifdef X11_RESIZE_DEBUG
702     XWindowAttributes attr;
703
704     if( event && event->type == ConfigureNotify )
705     {
706         fprintf( stderr, "vlcshell::Resize() ConfigureNotify %d x %d, "
707                  "send_event ? %s\n", event->xconfigure.width,
708                  event->xconfigure.height,
709                  event->xconfigure.send_event ? "TRUE" : "FALSE" );
710     }
711 #endif /* X11_RESIZE_DEBUG */
712
713     if( ! p_plugin->setSize(window->width, window->height) )
714     {
715         /* size already set */
716         return;
717     }
718
719
720     i_ret = XResizeWindow( p_display, drawable, window->width, window->height );
721
722 #ifdef X11_RESIZE_DEBUG
723     fprintf( stderr,
724              "vlcshell::Resize() XResizeWindow(owner) returned %d\n", i_ret );
725
726     XGetWindowAttributes ( p_display, drawable, &attr );
727
728     /* X is asynchronous, so the current size reported here is not
729        necessarily the requested size as the Resize request may not
730        yet have been handled by the plugin host */
731     fprintf( stderr, "vlcshell::Resize() current (owner) size %d x %d\n",
732              attr.width, attr.height );
733 #endif /* X11_RESIZE_DEBUG */
734
735     XQueryTree( p_display, drawable,
736                 &root_return, &parent_return, &children_return,
737                 &i_nchildren );
738
739     if( i_nchildren > 0 )
740     {
741         /* XXX: Make assumptions related to the window parenting structure in
742            vlc/modules/video_output/x11/xcommon.c */
743         base_window = children_return[i_nchildren - 1];
744
745 #ifdef X11_RESIZE_DEBUG
746         fprintf( stderr, "vlcshell::Resize() got %d children\n", i_nchildren );
747         fprintf( stderr, "vlcshell::Resize() got base_window %p\n",
748                  base_window );
749 #endif /* X11_RESIZE_DEBUG */
750
751         i_ret = XResizeWindow( p_display, base_window,
752                 window->width, window->height );
753
754 #ifdef X11_RESIZE_DEBUG
755         fprintf( stderr,
756                  "vlcshell::Resize() XResizeWindow(base) returned %d\n",
757                  i_ret );
758
759         XGetWindowAttributes( p_display, base_window, &attr );
760
761         fprintf( stderr, "vlcshell::Resize() new size %d x %d\n",
762                  attr.width, attr.height );
763 #endif /* X11_RESIZE_DEBUG */
764     }
765 }
766
767 #endif /* XP_UNIX */
768