Forward port of rev 17335. Implement versionInfo() method
[vlc.git] / 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 = NPN_CreateObject(instance, p_plugin->getScriptClass());
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     if( instance == NULL )
143     {
144         return false;
145     }
146
147     VlcPlugin *p_plugin = (VlcPlugin*)instance->pdata;
148     EventRecord *myEvent = (EventRecord*)event;
149
150     switch( myEvent->what )
151     {
152         case nullEvent:
153             break;
154         case mouseDown:
155         case mouseUp:
156             return true;
157         case keyUp:
158         case keyDown:
159         case autoKey:
160             return true;
161         case updateEvt:
162         {
163             int needsDisplay = TRUE;
164             libvlc_instance_t *p_vlc = p_plugin->getVLC();
165
166             if( p_vlc )
167             {
168                 if( libvlc_playlist_isplaying(p_vlc, NULL) )
169                 {
170                     libvlc_input_t *p_input = libvlc_playlist_get_input(p_vlc, NULL);
171                     if( p_input )
172                     {
173                         needsDisplay = ! libvlc_input_has_vout(p_input, NULL);
174                         libvlc_input_free(p_input);
175                     }
176                 }
177             }
178
179             const NPWindow *npwindow = p_plugin->getWindow();
180
181             if( needsDisplay && npwindow->window )
182             {
183                 /* draw the beautiful "No Picture" */
184
185                 ForeColor(blackColor);
186                 PenMode( patCopy );
187
188                 /* seems that firefox forgets to set the following on occasion (reload) */
189                 SetOrigin(((NP_Port *)npwindow->window)->portx, ((NP_Port *)npwindow->window)->porty);
190
191                 Rect rect;
192                 rect.left = 0;
193                 rect.top = 0;
194                 rect.right = npwindow->width;
195                 rect.bottom = npwindow->height;
196                 PaintRect( &rect );
197
198                 ForeColor(whiteColor);
199                 MoveTo( (npwindow->width-80)/ 2  , npwindow->height / 2 );
200                 DrawText( WINDOW_TEXT , 0 , strlen(WINDOW_TEXT) );
201             }
202             return true;
203         }
204         case activateEvt:
205             return false;
206         case NPEventType_GetFocusEvent:
207         case NPEventType_LoseFocusEvent:
208             return true;
209         case NPEventType_AdjustCursorEvent:
210             return false;
211         case NPEventType_MenuCommandEvent:
212             return false;
213         case NPEventType_ClippingChangedEvent:
214             return false;
215         case NPEventType_ScrollingBeginsEvent:
216         case NPEventType_ScrollingEndsEvent:
217             return true;
218         default:
219             ;
220     }
221     return false;
222 }
223 #endif /* XP_MACOSX */
224
225 /******************************************************************************
226  * General Plug-in Calls
227  *****************************************************************************/
228 NPError NPP_Initialize( void )
229 {
230     return NPERR_NO_ERROR;
231 }
232
233 jref NPP_GetJavaClass( void )
234 {
235     return NULL;
236 }
237
238 void NPP_Shutdown( void )
239 {
240     ;
241 }
242
243 NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
244                  char* argn[], char* argv[], NPSavedData* saved )
245 {
246     NPError status;
247
248     if( instance == NULL )
249     {
250         return NPERR_INVALID_INSTANCE_ERROR;
251     }
252
253     VlcPlugin * p_plugin = new VlcPlugin( instance, mode );
254     if( NULL == p_plugin )
255     {
256         return NPERR_OUT_OF_MEMORY_ERROR;
257     }
258
259     status = p_plugin->init(argc, argn, argv);
260     if( NPERR_NO_ERROR == status ) {
261         instance->pdata = reinterpret_cast<void*>(p_plugin);
262     }
263     else {
264         delete p_plugin;
265     }
266     return status;
267 }
268
269 NPError NPP_Destroy( NPP instance, NPSavedData** save )
270 {
271     if( instance == NULL )
272     {
273         return NPERR_INVALID_INSTANCE_ERROR;
274     }
275
276     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
277
278 #if XP_WIN
279     HWND win = (HWND)p_plugin->getWindow()->window;
280     WNDPROC winproc = p_plugin->getWindowProc();
281     if( winproc )
282     {
283         /* reset WNDPROC */
284         SetWindowLong( win, GWL_WNDPROC, (LONG)winproc );
285     }
286 #endif
287
288     if( p_plugin )
289         delete p_plugin;
290
291     instance->pdata = NULL;
292
293     return NPERR_NO_ERROR;
294 }
295
296 NPError NPP_SetWindow( NPP instance, NPWindow* window )
297 {
298     if( ! instance )
299     {
300         return NPERR_INVALID_INSTANCE_ERROR;
301     }
302
303     /* NPP_SetWindow may be called before NPP_New (Opera) */
304     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
305     if( ! p_plugin )
306     {
307         /* we should probably show a splash screen here */
308         return NPERR_NO_ERROR;
309     }
310
311     libvlc_instance_t *p_vlc = p_plugin->getVLC();
312
313     /*
314      * PLUGIN DEVELOPERS:
315      *  Before setting window to point to the
316      *  new window, you may wish to compare the new window
317      *  info to the previous window (if any) to note window
318      *  size changes, etc.
319      */
320
321     const NPWindow *curwin = p_plugin->getWindow();
322
323 #ifdef XP_MACOSX
324     if( window && window->window )
325     {
326         /* check if plugin has a new parent window */
327         CGrafPtr drawable = (((NP_Port*) (window->window))->port);
328         if( !curwin->window || drawable != (((NP_Port*) (curwin->window))->port) )
329         {
330             /* set/change parent window */
331             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
332         }
333
334         /* as MacOS X video output is windowless, set viewport */
335         libvlc_rectangle_t view, clip;
336
337         /*
338         ** browser sets port origin to top-left location of plugin relative to GrafPort
339         ** window origin is set relative to document, which of little use for drawing
340         */
341         view.top     = ((NP_Port*) (window->window))->porty;
342         view.left    = ((NP_Port*) (window->window))->portx;
343         view.bottom  = window->height+view.top;
344         view.right   = window->width+view.left;
345         /* clipRect coordinates are also relative to GrafPort */
346         clip.top     = window->clipRect.top;
347         clip.left    = window->clipRect.left;
348         clip.bottom  = window->clipRect.bottom;
349         clip.right   = window->clipRect.right;
350
351         libvlc_video_set_viewport(p_vlc, &view, &clip, NULL);
352
353         /* remember window details */
354         p_plugin->setWindow(window);
355     }
356 #endif /* XP_MACOSX */
357
358 #ifdef XP_WIN
359     if( window && window->window )
360     {
361         /* check if plugin has a new parent window */
362         HWND drawable = (HWND) (window->window);
363         if( !curwin->window || drawable != curwin->window )
364         {
365             /* reset previous window settings */
366             HWND oldwin = (HWND)p_plugin->getWindow()->window;
367             WNDPROC oldproc = p_plugin->getWindowProc();
368             if( oldproc )
369             {
370                 /* reset WNDPROC */
371                 SetWindowLong( oldwin, GWL_WNDPROC, (LONG)oldproc );
372             }
373             /* attach our plugin object */
374             SetWindowLongPtr((HWND)drawable, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(p_plugin));
375
376             /* install our WNDPROC */
377             p_plugin->setWindowProc( (WNDPROC)SetWindowLong( drawable,
378                                                            GWL_WNDPROC, (LONG)Manage ) );
379
380             /* change window style to our liking */
381             LONG style = GetWindowLong((HWND)drawable, GWL_STYLE);
382             style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
383             SetWindowLong((HWND)drawable, GWL_STYLE, style);
384
385             /* change/set parent */
386             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
387         }
388
389         /* remember window details */
390         p_plugin->setWindow(window);
391
392         /* Redraw window */
393         InvalidateRect( (HWND)drawable, NULL, TRUE );
394         UpdateWindow( (HWND)drawable );
395     }
396     else
397     {
398         /* reset WNDPROC */
399         HWND oldwin = (HWND)curwin->window;
400         SetWindowLong( oldwin, GWL_WNDPROC, (LONG)(p_plugin->getWindowProc()) );
401         p_plugin->setWindowProc(NULL);
402         /* change/set parent */
403         libvlc_video_set_parent(p_vlc, 0, NULL);
404     }
405 #endif /* XP_WIN */
406
407 #ifdef XP_UNIX
408     if( window && window->window )
409     {
410         Window  drawable   = (Window) window->window;
411         if( !curwin->window || drawable != (Window)curwin->window )
412         {
413             Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
414
415             XResizeWindow( p_display, drawable, window->width, window->height );
416             Widget w = XtWindowToWidget( p_display, drawable );
417
418             XtAddEventHandler( w, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin );
419             XtAddEventHandler( w, StructureNotifyMask, FALSE, (XtEventHandler)Resize, p_plugin );
420
421             /* set/change parent window */
422             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, NULL);
423
424             /* remember window */
425             p_plugin->setWindow(window);
426
427             Redraw( w, (XtPointer)p_plugin, NULL );
428         }
429     }
430 #endif /* XP_UNIX */
431
432     if( !p_plugin->b_stream )
433     {
434         if( p_plugin->psz_target )
435         {
436             if( VLC_SUCCESS == libvlc_playlist_add( p_vlc, p_plugin->psz_target, NULL, NULL ) )
437             {
438                 if( p_plugin->b_autoplay )
439                 {
440                     libvlc_playlist_play(p_vlc, 0, 0, NULL, NULL);
441                 }
442                 p_plugin->b_stream = VLC_TRUE;
443             }
444         }
445     }
446     return NPERR_NO_ERROR;
447 }
448
449 NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
450                        NPBool seekable, uint16 *stype )
451 {
452     if( NULL == instance  )
453     {
454         return NPERR_INVALID_INSTANCE_ERROR;
455     }
456
457     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(instance->pdata);
458
459    /*
460    ** Firefox/Mozilla may decide to open a stream from the URL specified
461    ** in the SRC parameter of the EMBED tag and pass it to us
462    **
463    ** since VLC will open the SRC URL as well, we're not interested in
464    ** that stream. Otherwise, we'll take it and queue it up in the playlist
465    */
466     if( !p_plugin->psz_target || strcmp(stream->url, p_plugin->psz_target) )
467     {
468         /* TODO: use pipes !!!! */
469         *stype = NP_ASFILEONLY;
470         return NPERR_NO_ERROR;
471     }
472     return NPERR_GENERIC_ERROR;
473 }
474
475 int32 NPP_WriteReady( NPP instance, NPStream *stream )
476 {
477     /* TODO */
478     return 8*1024;
479 }
480
481
482 int32 NPP_Write( NPP instance, NPStream *stream, int32 offset,
483                  int32 len, void *buffer )
484 {
485     /* TODO */
486     return len;
487 }
488
489
490 NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason )
491 {
492     if( instance == NULL )
493     {
494         return NPERR_INVALID_INSTANCE_ERROR;
495     }
496     return NPERR_NO_ERROR;
497 }
498
499
500 void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
501 {
502     if( instance == NULL )
503     {
504         return;
505     }
506
507     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(instance->pdata);
508
509     if( VLC_SUCCESS == libvlc_playlist_add( p_plugin->getVLC(), fname, stream->url, NULL ) )
510     {
511         if( p_plugin->b_autoplay )
512         {
513             libvlc_playlist_play( p_plugin->getVLC(), 0, 0, NULL, NULL);
514         }
515     }
516 }
517
518
519 void NPP_URLNotify( NPP instance, const char* url,
520                     NPReason reason, void* notifyData )
521 {
522     /***** Insert NPP_URLNotify code here *****\
523     PluginInstance* p_plugin;
524     if (instance != NULL)
525         p_plugin = (PluginInstance*) instance->pdata;
526     \*********************************************/
527 }
528
529
530 void NPP_Print( NPP instance, NPPrint* printInfo )
531 {
532     if( printInfo == NULL )
533     {
534         return;
535     }
536
537     if( instance != NULL )
538     {
539         /***** Insert NPP_Print code here *****\
540         PluginInstance* p_plugin = (PluginInstance*) instance->pdata;
541         \**************************************/
542
543         if( printInfo->mode == NP_FULL )
544         {
545             /*
546              * PLUGIN DEVELOPERS:
547              *  If your plugin would like to take over
548              *  printing completely when it is in full-screen mode,
549              *  set printInfo->pluginPrinted to TRUE and print your
550              *  plugin as you see fit.  If your plugin wants Netscape
551              *  to handle printing in this case, set
552              *  printInfo->pluginPrinted to FALSE (the default) and
553              *  do nothing.  If you do want to handle printing
554              *  yourself, printOne is true if the print button
555              *  (as opposed to the print menu) was clicked.
556              *  On the Macintosh, platformPrint is a THPrint; on
557              *  Windows, platformPrint is a structure
558              *  (defined in npapi.h) containing the printer name, port,
559              *  etc.
560              */
561
562             /***** Insert NPP_Print code here *****\
563             void* platformPrint =
564                 printInfo->print.fullPrint.platformPrint;
565             NPBool printOne =
566                 printInfo->print.fullPrint.printOne;
567             \**************************************/
568
569             /* Do the default*/
570             printInfo->print.fullPrint.pluginPrinted = FALSE;
571         }
572         else
573         {
574             /* If not fullscreen, we must be embedded */
575             /*
576              * PLUGIN DEVELOPERS:
577              *  If your plugin is embedded, or is full-screen
578              *  but you returned false in pluginPrinted above, NPP_Print
579              *  will be called with mode == NP_EMBED.  The NPWindow
580              *  in the printInfo gives the location and dimensions of
581              *  the embedded plugin on the printed page.  On the
582              *  Macintosh, platformPrint is the printer port; on
583              *  Windows, platformPrint is the handle to the printing
584              *  device context.
585              */
586
587             /***** Insert NPP_Print code here *****\
588             NPWindow* printWindow =
589                 &(printInfo->print.embedPrint.window);
590             void* platformPrint =
591                 printInfo->print.embedPrint.platformPrint;
592             \**************************************/
593         }
594     }
595 }
596
597 /******************************************************************************
598  * Windows-only methods
599  *****************************************************************************/
600 #if XP_WIN
601 static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar )
602 {
603     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(GetWindowLongPtr(p_hwnd, GWLP_USERDATA));
604
605     switch( i_msg )
606     {
607         case WM_ERASEBKGND:
608             return 1L;
609
610         case WM_PAINT:
611         {
612             PAINTSTRUCT paintstruct;
613             HDC hdc;
614             RECT rect;
615
616             hdc = BeginPaint( p_hwnd, &paintstruct );
617
618             GetClientRect( p_hwnd, &rect );
619
620             FillRect( hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH) );
621             SetTextColor(hdc, RGB(255, 255, 255));
622             SetBkColor(hdc, RGB(0, 0, 0));
623             DrawText( hdc, WINDOW_TEXT, strlen(WINDOW_TEXT), &rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
624
625             EndPaint( p_hwnd, &paintstruct );
626             return 0L;
627         }
628         default:
629             /* delegate to default handler */
630             return p_plugin->getWindowProc()( p_hwnd, i_msg, wpar, lpar );
631     }
632 }
633 #endif /* XP_WIN */
634
635 /******************************************************************************
636  * UNIX-only methods
637  *****************************************************************************/
638 #ifdef XP_UNIX
639 static void Redraw( Widget w, XtPointer closure, XEvent *event )
640 {
641     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
642     const NPWindow *window = p_plugin->getWindow();
643     GC gc;
644     XGCValues gcv;
645
646     Window  drawable   = (Window) window->window;
647     Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
648
649     gcv.foreground = BlackPixel( p_display, 0 );
650     gc = XCreateGC( p_display, drawable, GCForeground, &gcv );
651
652     XFillRectangle( p_display, drawable, gc,
653                     0, 0, window->width, window->height );
654
655     gcv.foreground = WhitePixel( p_display, 0 );
656     XChangeGC( p_display, gc, GCForeground, &gcv );
657
658     XDrawString( p_display, drawable, gc,
659                  window->width / 2 - 40, window->height / 2,
660                  WINDOW_TEXT, strlen(WINDOW_TEXT) );
661
662     XFreeGC( p_display, gc );
663 }
664
665 static void Resize ( Widget w, XtPointer closure, XEvent *event )
666 {
667     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
668     const NPWindow *window = p_plugin->getWindow();
669     Window  drawable   = (Window) window->window;
670     Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
671
672     int i_ret;
673     Window root_return, parent_return, * children_return;
674     Window base_window;
675     unsigned int i_nchildren;
676
677 #ifdef X11_RESIZE_DEBUG
678     XWindowAttributes attr;
679
680     if( event && event->type == ConfigureNotify )
681     {
682         fprintf( stderr, "vlcshell::Resize() ConfigureNotify %d x %d, "
683                  "send_event ? %s\n", event->xconfigure.width,
684                  event->xconfigure.height,
685                  event->xconfigure.send_event ? "TRUE" : "FALSE" );
686     }
687 #endif /* X11_RESIZE_DEBUG */
688
689     if( ! p_plugin->setSize(window->width, window->height) )
690     {
691         /* size already set */
692         return;
693     }
694
695
696     i_ret = XResizeWindow( p_display, drawable, window->width, window->height );
697
698 #ifdef X11_RESIZE_DEBUG
699     fprintf( stderr,
700              "vlcshell::Resize() XResizeWindow(owner) returned %d\n", i_ret );
701
702     XGetWindowAttributes ( p_display, drawable, &attr );
703
704     /* X is asynchronous, so the current size reported here is not
705        necessarily the requested size as the Resize request may not
706        yet have been handled by the plugin host */
707     fprintf( stderr, "vlcshell::Resize() current (owner) size %d x %d\n",
708              attr.width, attr.height );
709 #endif /* X11_RESIZE_DEBUG */
710
711     XQueryTree( p_display, drawable,
712                 &root_return, &parent_return, &children_return,
713                 &i_nchildren );
714
715     if( i_nchildren > 0 )
716     {
717         /* XXX: Make assumptions related to the window parenting structure in
718            vlc/modules/video_output/x11/xcommon.c */
719         base_window = children_return[i_nchildren - 1];
720
721 #ifdef X11_RESIZE_DEBUG
722         fprintf( stderr, "vlcshell::Resize() got %d children\n", i_nchildren );
723         fprintf( stderr, "vlcshell::Resize() got base_window %p\n",
724                  base_window );
725 #endif /* X11_RESIZE_DEBUG */
726
727         i_ret = XResizeWindow( p_display, base_window,
728                 window->width, window->height );
729
730 #ifdef X11_RESIZE_DEBUG
731         fprintf( stderr,
732                  "vlcshell::Resize() XResizeWindow(base) returned %d\n",
733                  i_ret );
734
735         XGetWindowAttributes( p_display, base_window, &attr );
736
737         fprintf( stderr, "vlcshell::Resize() new size %d x %d\n",
738                  attr.width, attr.height );
739 #endif /* X11_RESIZE_DEBUG */
740     }
741 }
742
743 #endif /* XP_UNIX */
744