]> git.sesse.net Git - vlc/blob - mozilla/vlcshell.cpp
* Lets at the very least remove icons we don't use anymore. Should save some space.
[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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /* XXX: disable VLC here */
25 #define USE_LIBVLC 1
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include "config.h"
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35
36 /* vlc stuff */
37 #ifdef USE_LIBVLC
38 #   include <vlc/vlc.h>
39 #endif
40
41 /* Mozilla stuff */
42 #ifdef HAVE_MOZILLA_CONFIG_H
43 #   include <mozilla-config.h>
44 #endif
45 #include <nsISupports.h>
46 #include <nsMemory.h>
47 #include <npapi.h>
48
49 /* This is from mozilla java, do we really need it? */
50 #if 0
51 #include <jri.h>
52 #endif
53
54 #if !defined(XP_MACOSX) && !defined(XP_UNIX) && !defined(XP_WIN)
55 #define XP_UNIX 1
56 #elif defined(XP_MACOSX)
57 #undef XP_UNIX
58 #endif
59
60 #ifdef XP_WIN
61     /* Windows stuff */
62 #endif
63
64 #ifdef XP_MACOSX
65     /* Mac OS X stuff */
66 #   include <Quickdraw.h>
67 #endif
68
69 #ifdef XP_UNIX
70     /* X11 stuff */
71 #   include <X11/Xlib.h>
72 #   include <X11/Intrinsic.h>
73 #   include <X11/StringDefs.h>
74 #endif
75
76 #include "vlcpeer.h"
77 #include "vlcplugin.h"
78
79 #if USE_LIBVLC
80 #   define WINDOW_TEXT "(no picture)"
81 #else
82 #   define WINDOW_TEXT "(no libvlc)"
83 #endif
84
85 /* Enable/disable debugging printf's for X11 resizing */
86 #undef X11_RESIZE_DEBUG
87
88 /*****************************************************************************
89  * Unix-only declarations
90 ******************************************************************************/
91 #ifdef XP_UNIX
92 #   define VOUT_PLUGINS "xvideo,x11,dummy"
93 #   define AOUT_PLUGINS "alsa,oss,dummy"
94
95 static unsigned int i_previous_height = 100000;
96 static unsigned int i_previous_width = 100000;
97
98 static void Redraw( Widget w, XtPointer closure, XEvent *event );
99 static void Resize( Widget w, XtPointer closure, XEvent *event );
100 #endif
101
102 /*****************************************************************************
103  * MacOS-only declarations
104 ******************************************************************************/
105 #ifdef XP_MACOSX
106 #   define VOUT_PLUGINS "macosx"
107 #   define AOUT_PLUGINS "macosx"
108
109 #endif
110
111 /*****************************************************************************
112  * Windows-only declarations
113  *****************************************************************************/
114 #ifdef XP_WIN
115 #   define VOUT_PLUGINS "directx,wingdi,dummy"
116 #   define AOUT_PLUGINS "directx,waveout,dummy"
117
118 #if defined(XP_WIN) && !USE_LIBVLC
119 LRESULT CALLBACK Manage( HWND, UINT, WPARAM, LPARAM );
120 #endif
121 #endif
122
123 /******************************************************************************
124  * UNIX-only API calls
125  *****************************************************************************/
126 char * NPP_GetMIMEDescription( void )
127 {
128     return PLUGIN_MIMETYPES;
129 }
130
131 NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
132 {
133
134     static nsIID nsid = VLCINTF_IID;
135     static char psz_desc[1000];
136
137     switch( variable )
138     {
139         case NPPVpluginNameString:
140             *((char **)value) = PLUGIN_NAME;
141             return NPERR_NO_ERROR;
142
143         case NPPVpluginDescriptionString:
144 #if USE_LIBVLC
145             snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, VLC_Version() );
146 #else /* USE_LIBVLC */
147             snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, "(disabled)" );
148 #endif /* USE_LIBVLC */
149             psz_desc[1000-1] = 0;
150             *((char **)value) = psz_desc;
151             return NPERR_NO_ERROR;
152
153         default:
154             /* go on... */
155             break;
156     }
157
158     if( instance == NULL )
159     {
160         return NPERR_INVALID_INSTANCE_ERROR;
161     }
162
163     VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata;
164
165     switch( variable )
166     {
167         case NPPVpluginScriptableInstance:
168             *(nsISupports**)value = p_plugin->GetPeer();
169             if( *(nsISupports**)value == NULL )
170             {
171                 return NPERR_OUT_OF_MEMORY_ERROR;
172             }
173             break;
174
175         case NPPVpluginScriptableIID:
176             *(nsIID**)value = (nsIID*)NPN_MemAlloc( sizeof(nsIID) );
177             if( *(nsIID**)value == NULL )
178             {
179                 return NPERR_OUT_OF_MEMORY_ERROR;
180             }
181             **(nsIID**)value = nsid;
182             break;
183
184         default:
185             return NPERR_GENERIC_ERROR;
186     }
187
188     return NPERR_NO_ERROR;
189 }
190
191 /******************************************************************************
192  * Mac-only API calls
193  *****************************************************************************/
194 #ifdef XP_MACOSX
195 int16 NPP_HandleEvent( NPP instance, void * event )
196 {
197     VlcPlugin *p_plugin = (VlcPlugin*)instance->pdata;
198     vlc_value_t value;
199
200     if( instance == NULL )
201     {
202         return false;
203     }
204
205     EventRecord *pouetEvent = (EventRecord*)event;
206
207     if (pouetEvent->what == 6)
208     {
209         value.i_int = 1;
210         VLC_VariableSet( p_plugin->i_vlc, "drawableredraw", value );
211         return true;
212     }
213
214     Boolean eventHandled = false;
215
216     return eventHandled;
217 }
218 #endif /* XP_MACOSX */
219
220 /******************************************************************************
221  * General Plug-in Calls
222  *****************************************************************************/
223 NPError NPP_Initialize( void )
224 {
225     return NPERR_NO_ERROR;
226 }
227
228 jref NPP_GetJavaClass( void )
229 {
230     return NULL;
231 }
232
233 void NPP_Shutdown( void )
234 {
235     ;
236 }
237
238 NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
239                  char* argn[], char* argv[], NPSavedData* saved )
240 {
241     int i;
242
243 #if USE_LIBVLC
244     vlc_value_t value;
245     int i_ret;
246
247 #endif /* USE_LIBVLC */
248
249     if( instance == NULL )
250     {
251         return NPERR_INVALID_INSTANCE_ERROR;
252     }
253
254     VlcPlugin * p_plugin = new VlcPlugin( instance );
255
256     if( p_plugin == NULL )
257     {
258         return NPERR_OUT_OF_MEMORY_ERROR;
259     }
260
261     instance->pdata = p_plugin;
262
263 #ifdef XP_WIN
264     p_plugin->p_hwnd = NULL;
265     p_plugin->pf_wndproc = NULL;
266 #endif /* XP_WIN */
267
268 #ifdef XP_UNIX
269     p_plugin->window = 0;
270     p_plugin->p_display = NULL;
271 #endif /* XP_UNIX */
272
273     p_plugin->p_npwin = NULL;
274     p_plugin->i_npmode = mode;
275     p_plugin->i_width = 0;
276     p_plugin->i_height = 0;
277
278 #if USE_LIBVLC
279     p_plugin->i_vlc = VLC_Create();
280     if( p_plugin->i_vlc < 0 )
281     {
282         p_plugin->i_vlc = 0;
283         delete p_plugin;
284         p_plugin = NULL;
285         return NPERR_GENERIC_ERROR;
286     }
287
288     {
289 #ifdef XP_MACOSX
290         char *home_user;
291         char *directory;
292         char *plugin_path;
293         char *ppsz_argv[] = { "vlc", "--plugin-path", NULL };
294
295         home_user = strdup( getenv("HOME") );
296         directory = strdup( "/Library/Internet Plug-Ins/VLC Plugin.plugin/"
297                             "Contents/MacOS/modules" );
298         plugin_path = malloc( strlen( directory ) + strlen( home_user ) );
299         memcpy( plugin_path , home_user , strlen(home_user) );
300         memcpy( plugin_path + strlen( home_user ) , directory ,
301                 strlen( directory ) );
302
303         ppsz_argv[2] = plugin_path;
304
305 #elif defined(XP_WIN)
306         char *ppsz_argv[] = { NULL, "-vv" };
307         HKEY h_key;
308         DWORD i_type, i_data = MAX_PATH + 1;
309         char p_data[MAX_PATH + 1];
310         if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\VideoLAN\\VLC",
311                           0, KEY_READ, &h_key ) == ERROR_SUCCESS )
312         {
313              if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type,
314                                   (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS )
315              {
316                  if( i_type == REG_SZ )
317                  {
318                      strcat( p_data, "\\vlc" );
319                      ppsz_argv[0] = p_data;
320                  }
321              }
322              RegCloseKey( h_key );
323         }
324
325         if( !ppsz_argv[0] ) ppsz_argv[0] = "vlc";
326
327 #else /* XP_MACOSX */
328         char *ppsz_argv[] =
329         {
330             "vlc"
331             /*, "--plugin-path", "/home/sam/videolan/vlc_MAIN/plugins"*/
332         };
333
334 #endif /* XP_MACOSX */
335
336         /* HACK: special case for loop, to have it set before playlist startup
337          */
338         for( i = 0; i < argc ; i++ )
339         {
340             if( !strcmp( argn[i], "loop" ) )
341             {
342                 if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) )
343                 {
344                     value.b_bool = VLC_TRUE;
345                     VLC_VariableSet( p_plugin->i_vlc, "conf::loop", value );
346                 }
347             }
348         }
349
350         i_ret = VLC_Init( p_plugin->i_vlc, sizeof(ppsz_argv)/sizeof(char*),
351                           ppsz_argv );
352
353 #ifdef XP_MACOSX
354         free( home_user );
355         free( directory );
356         free( plugin_path );
357 #endif /* XP_MACOSX */
358     }
359
360     if( i_ret )
361     {
362         VLC_Destroy( p_plugin->i_vlc );
363         p_plugin->i_vlc = 0;
364         delete p_plugin;
365         p_plugin = NULL;
366         return NPERR_GENERIC_ERROR;
367     }
368
369     value.psz_string = "dummy";
370     VLC_VariableSet( p_plugin->i_vlc, "conf::intf", value );
371     value.psz_string = VOUT_PLUGINS;
372     VLC_VariableSet( p_plugin->i_vlc, "conf::vout", value );
373     value.psz_string = AOUT_PLUGINS;
374     VLC_VariableSet( p_plugin->i_vlc, "conf::aout", value );
375
376 #else /* USE_LIBVLC */
377     p_plugin->i_vlc = 1;
378
379 #endif /* USE_LIBVLC */
380
381     p_plugin->b_stream = VLC_FALSE;
382     p_plugin->b_autoplay = VLC_FALSE;
383     p_plugin->psz_target = NULL;
384
385     for( i = 0; i < argc ; i++ )
386     {
387         if( !strcmp( argn[i], "target" ) )
388         {
389             p_plugin->psz_target = argv[i];
390         }
391         else if( !strcmp( argn[i], "autoplay" ) )
392         {
393             if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) )
394             {
395                 p_plugin->b_autoplay = 1;
396             }
397         }
398         else if( !strcmp( argn[i], "autostart" ) )
399         {
400             if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "true" ) )
401             {
402                 p_plugin->b_autoplay = 1;
403             }
404         }
405         else if( !strcmp( argn[i], "filename" ) )
406         {
407             p_plugin->psz_target = argv[i];
408         }
409         else if( !strcmp( argn[i], "src" ) )
410         {
411             p_plugin->psz_target = argv[i];
412         }
413
414 #if USE_LIBVLC
415         else if( !strcmp( argn[i], "fullscreen" ) )
416         {
417             if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) )
418             {
419                 value.b_bool = VLC_TRUE;
420                 VLC_VariableSet( p_plugin->i_vlc, "conf::fullscreen", value );
421             }
422         }
423         else if( !strcmp( argn[i], "mute" ) )
424         {
425             if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) )
426             {
427                 VLC_VolumeMute( p_plugin->i_vlc );
428             }
429         }
430 #endif /* USE_LIBVLC */
431     }
432
433     if( p_plugin->psz_target )
434     {
435         p_plugin->psz_target = strdup( p_plugin->psz_target );
436     }
437
438     return NPERR_NO_ERROR;
439 }
440
441 #ifdef XP_WIN
442 /* This is really ugly but there is a deadlock when stopping a stream
443  * (in VLC_CleanUp()) because the video output is a child of the drawable but
444  * is in a different thread. */
445 static void HackStopVout( VlcPlugin* p_plugin )
446 {
447     MSG msg;
448     HWND hwnd;
449     vlc_value_t value;
450
451     VLC_VariableGet( p_plugin->i_vlc, "drawable", &value );
452
453     hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 );
454     if( !hwnd ) return;
455
456     PostMessage( hwnd, WM_CLOSE, 0, 0 );
457
458     do
459     {
460         while( PeekMessage( &msg, (HWND)value.i_int, 0, 0, PM_REMOVE ) )
461         {
462             TranslateMessage(&msg);
463             DispatchMessage(&msg);
464         }
465         if( FindWindowEx( (HWND)value.i_int, 0, 0, 0 ) ) Sleep( 10 );
466     }
467     while( (hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 )) );
468 }
469 #endif /* XP_WIN */
470
471 NPError NPP_Destroy( NPP instance, NPSavedData** save )
472 {
473     if( instance == NULL )
474     {
475         return NPERR_INVALID_INSTANCE_ERROR;
476     }
477
478     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
479
480     if( p_plugin != NULL )
481     {
482         if( p_plugin->i_vlc )
483         {
484 #if USE_LIBVLC
485 #   ifdef XP_WIN
486             HackStopVout( p_plugin );
487 #   endif /* XP_WIN */
488             VLC_CleanUp( p_plugin->i_vlc );
489             VLC_Destroy( p_plugin->i_vlc );
490 #endif /* USE_LIBVLC */
491             p_plugin->i_vlc = 0;
492         }
493
494         if( p_plugin->psz_target )
495         {
496             free( p_plugin->psz_target );
497             p_plugin->psz_target = NULL;
498         }
499
500         delete p_plugin;
501     }
502
503     instance->pdata = NULL;
504
505     return NPERR_NO_ERROR;
506 }
507
508 NPError NPP_SetWindow( NPP instance, NPWindow* window )
509 {
510     vlc_value_t value;
511 #ifdef XP_MACOSX
512     vlc_value_t valuex;
513     vlc_value_t valuey;
514     vlc_value_t valuew;
515     vlc_value_t valueh;
516     vlc_value_t valuet;
517     vlc_value_t valuel;
518     vlc_value_t valueb;
519     vlc_value_t valuer;
520     vlc_value_t valueportx;
521     vlc_value_t valueporty;
522     Rect black_rect;
523     char * text;
524 #endif /* XP_MACOSX */
525
526     if( instance == NULL )
527     {
528         return NPERR_INVALID_INSTANCE_ERROR;
529     }
530
531     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
532
533     /* Write the window ID for vlc */
534 #if USE_LIBVLC
535
536 #ifdef XP_MACOSX
537     value.i_int = ((NP_Port*) (window->window))->port;
538     VLC_VariableSet( p_plugin->i_vlc, "drawable", value );
539
540     valueportx.i_int = ((NP_Port*) (window->window))->portx;
541     valueporty.i_int = ((NP_Port*) (window->window))->porty;
542     VLC_VariableSet( p_plugin->i_vlc, "drawableportx", valueportx );
543     VLC_VariableSet( p_plugin->i_vlc, "drawableporty", valueporty );
544
545     valuex.i_int = window->x;
546     valuey.i_int = window->y;
547     valuew.i_int = window->width;
548     valueh.i_int = window->height;
549     valuet.i_int = window->clipRect.top;
550     valuel.i_int = window->clipRect.left;
551     valueb.i_int = window->clipRect.bottom;
552     valuer.i_int = window->clipRect.right;
553
554     VLC_VariableSet( p_plugin->i_vlc, "drawablet", valuet );
555     VLC_VariableSet( p_plugin->i_vlc, "drawablel", valuel );
556     VLC_VariableSet( p_plugin->i_vlc, "drawableb", valueb );
557     VLC_VariableSet( p_plugin->i_vlc, "drawabler", valuer );
558     VLC_VariableSet( p_plugin->i_vlc, "drawablex", valuex );
559     VLC_VariableSet( p_plugin->i_vlc, "drawabley", valuey );
560     VLC_VariableSet( p_plugin->i_vlc, "drawablew", valuew );
561     VLC_VariableSet( p_plugin->i_vlc, "drawableh", valueh );
562
563     p_plugin->window = window;
564
565     /* draw the beautiful "No Picture" */
566
567     black_rect.top = valuet.i_int - valuey.i_int;
568     black_rect.left = valuel.i_int - valuex.i_int;
569     black_rect.bottom = valueb.i_int - valuey.i_int;
570     black_rect.right = valuer.i_int - valuex.i_int;
571
572     SetPort( value.i_int );
573     SetOrigin( valueportx.i_int , valueporty.i_int );
574     ForeColor(blackColor);
575     PenMode( patCopy );
576     PaintRect( &black_rect );
577
578     ForeColor(whiteColor);
579     text = strdup( WINDOW_TEXT );
580     MoveTo( valuew.i_int / 2 - 40 , valueh.i_int / 2 );
581     DrawText( text , 0 , strlen(text) );
582     free(text);
583
584 #else /* XP_MACOSX */
585     /* FIXME: this cast sucks */
586     value.i_int = (int) (ptrdiff_t) (void *) window->window;
587     VLC_VariableSet( p_plugin->i_vlc, "drawable", value );
588 #endif /* XP_MACOSX */
589
590 #endif /* USE_LIBVLC */
591
592     /*
593      * PLUGIN DEVELOPERS:
594      *  Before setting window to point to the
595      *  new window, you may wish to compare the new window
596      *  info to the previous window (if any) to note window
597      *  size changes, etc.
598      */
599
600 #ifdef XP_WIN
601     if( !window || !window->window )
602     {
603         /* Window was destroyed. Invalidate everything. */
604         if( p_plugin->p_npwin )
605         {
606 #if !USE_LIBVLC
607             SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
608                            (LONG)p_plugin->pf_wndproc );
609 #endif /* !USE_LIBVLC */
610             p_plugin->pf_wndproc = NULL;
611             p_plugin->p_hwnd = NULL;
612         }
613
614         p_plugin->p_npwin = window;
615         return NPERR_NO_ERROR;
616     }
617
618     if( p_plugin->p_npwin )
619     {
620         if( p_plugin->p_hwnd == (HWND)window->window )
621         {
622             /* Same window, but something may have changed. First we
623              * update the plugin structure, then we redraw the window */
624             p_plugin->i_width = window->width;
625             p_plugin->i_height = window->height;
626             p_plugin->p_npwin = window;
627 #if !USE_LIBVLC
628             InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
629             UpdateWindow( p_plugin->p_hwnd );
630 #endif /* !USE_LIBVLC */
631             return NPERR_NO_ERROR;
632         }
633
634         /* Window has changed. Destroy the one we have, and go
635          * on as if it was a real initialization. */
636 #if !USE_LIBVLC
637         SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
638                        (LONG)p_plugin->pf_wndproc );
639 #endif /* !USE_LIBVLC */
640         p_plugin->pf_wndproc = NULL;
641         p_plugin->p_hwnd = NULL;
642     }
643
644 #if !USE_LIBVLC
645     p_plugin->pf_wndproc = (WNDPROC)SetWindowLong( (HWND)window->window,
646                                                    GWL_WNDPROC, (LONG)Manage );
647 #endif /* !USE_LIBVLC */
648
649     p_plugin->p_hwnd = (HWND)window->window;
650     SetProp( p_plugin->p_hwnd, "w00t", (HANDLE)p_plugin );
651     InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
652     UpdateWindow( p_plugin->p_hwnd );
653 #endif /* XP_WIN */
654
655     p_plugin->i_width = window->width;
656     p_plugin->i_height = window->height;
657     p_plugin->p_npwin = window;
658
659 #ifdef XP_UNIX
660     p_plugin->window = (Window) window->window;
661     p_plugin->p_display =
662         ((NPSetWindowCallbackStruct *)window->ws_info)->display;
663
664     XResizeWindow( p_plugin->p_display, p_plugin->window,
665                    p_plugin->i_width, p_plugin->i_height );
666     Widget w = XtWindowToWidget( p_plugin->p_display, p_plugin->window );
667
668     XtAddEventHandler( w, ExposureMask, FALSE,
669                        (XtEventHandler)Redraw, p_plugin );
670     XtAddEventHandler( w, StructureNotifyMask, FALSE,
671                        (XtEventHandler)Resize, p_plugin );
672     Redraw( w, (XtPointer)p_plugin, NULL );
673 #endif /* XP_UNIX */
674
675     if( !p_plugin->b_stream )
676     {
677         int i_mode = PLAYLIST_APPEND;
678
679         if( p_plugin->b_autoplay )
680         {
681             i_mode |= PLAYLIST_GO;
682         }
683
684         if( p_plugin->psz_target )
685         {
686 #if USE_LIBVLC
687             VLC_AddTarget( p_plugin->i_vlc, p_plugin->psz_target,
688                            0, 0, PLAYLIST_INSERT, 0 );
689 #endif
690             p_plugin->b_stream = VLC_TRUE;
691         }
692     }
693
694     return NPERR_NO_ERROR;
695 }
696
697 NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
698                        NPBool seekable, uint16 *stype )
699 {
700     if( instance == NULL )
701     {
702         return NPERR_INVALID_INSTANCE_ERROR;
703     }
704
705 #if 0
706     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
707 #endif
708
709     /* fprintf(stderr, "NPP_NewStream - FILE mode !!\n"); */
710
711     /* We want a *filename* ! */
712     *stype = NP_ASFILE;
713
714 #if 0
715     if( !p_plugin->b_stream )
716     {
717         p_plugin->psz_target = strdup( stream->url );
718         p_plugin->b_stream = VLC_TRUE;
719     }
720 #endif
721
722     return NPERR_NO_ERROR;
723 }
724
725 int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
726                    * mode so we can take any size stream in our
727                    * write call (since we ignore it) */
728
729 #define SARASS_SIZE (1024*1024)
730
731 int32 NPP_WriteReady( NPP instance, NPStream *stream )
732 {
733     VlcPlugin* p_plugin;
734
735     /* fprintf(stderr, "NPP_WriteReady\n"); */
736
737     if (instance != NULL)
738     {
739         p_plugin = (VlcPlugin*) instance->pdata;
740         /* Muahahahahahahaha */
741         return STREAMBUFSIZE;
742         /*return SARASS_SIZE;*/
743     }
744
745     /* Number of bytes ready to accept in NPP_Write() */
746     return STREAMBUFSIZE;
747     /*return 0;*/
748 }
749
750
751 int32 NPP_Write( NPP instance, NPStream *stream, int32 offset,
752                  int32 len, void *buffer )
753 {
754     /* fprintf(stderr, "NPP_Write %i\n", (int)len); */
755
756     if( instance != NULL )
757     {
758         /*VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata;*/
759     }
760
761     return len;         /* The number of bytes accepted */
762 }
763
764
765 NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason )
766 {
767     if( instance == NULL )
768     {
769         return NPERR_INVALID_INSTANCE_ERROR;
770     }
771
772     return NPERR_NO_ERROR;
773 }
774
775
776 void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
777 {
778     if( instance == NULL )
779     {
780         return;
781     }
782
783     /* fprintf(stderr, "NPP_StreamAsFile %s\n", fname); */
784
785 #if USE_LIBVLC
786     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
787
788     VLC_AddTarget( p_plugin->i_vlc, fname, 0, 0,
789                    PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
790 #endif /* USE_LIBVLC */
791 }
792
793
794 void NPP_URLNotify( NPP instance, const char* url,
795                     NPReason reason, void* notifyData )
796 {
797     /***** Insert NPP_URLNotify code here *****\
798     PluginInstance* p_plugin;
799     if (instance != NULL)
800         p_plugin = (PluginInstance*) instance->pdata;
801     \*********************************************/
802 }
803
804
805 void NPP_Print( NPP instance, NPPrint* printInfo )
806 {
807     if( printInfo == NULL )
808     {
809         return;
810     }
811
812     if( instance != NULL )
813     {
814         /***** Insert NPP_Print code here *****\
815         PluginInstance* p_plugin = (PluginInstance*) instance->pdata;
816         \**************************************/
817
818         if( printInfo->mode == NP_FULL )
819         {
820             /*
821              * PLUGIN DEVELOPERS:
822              *  If your plugin would like to take over
823              *  printing completely when it is in full-screen mode,
824              *  set printInfo->pluginPrinted to TRUE and print your
825              *  plugin as you see fit.  If your plugin wants Netscape
826              *  to handle printing in this case, set
827              *  printInfo->pluginPrinted to FALSE (the default) and
828              *  do nothing.  If you do want to handle printing
829              *  yourself, printOne is true if the print button
830              *  (as opposed to the print menu) was clicked.
831              *  On the Macintosh, platformPrint is a THPrint; on
832              *  Windows, platformPrint is a structure
833              *  (defined in npapi.h) containing the printer name, port,
834              *  etc.
835              */
836
837             /***** Insert NPP_Print code here *****\
838             void* platformPrint =
839                 printInfo->print.fullPrint.platformPrint;
840             NPBool printOne =
841                 printInfo->print.fullPrint.printOne;
842             \**************************************/
843
844             /* Do the default*/
845             printInfo->print.fullPrint.pluginPrinted = FALSE;
846         }
847         else
848         {
849             /* If not fullscreen, we must be embedded */
850             /*
851              * PLUGIN DEVELOPERS:
852              *  If your plugin is embedded, or is full-screen
853              *  but you returned false in pluginPrinted above, NPP_Print
854              *  will be called with mode == NP_EMBED.  The NPWindow
855              *  in the printInfo gives the location and dimensions of
856              *  the embedded plugin on the printed page.  On the
857              *  Macintosh, platformPrint is the printer port; on
858              *  Windows, platformPrint is the handle to the printing
859              *  device context.
860              */
861
862             /***** Insert NPP_Print code here *****\
863             NPWindow* printWindow =
864                 &(printInfo->print.embedPrint.window);
865             void* platformPrint =
866                 printInfo->print.embedPrint.platformPrint;
867             \**************************************/
868         }
869     }
870 }
871
872 /******************************************************************************
873  * Windows-only methods
874  *****************************************************************************/
875 #if defined(XP_WIN) && !USE_LIBVLC
876 LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar )
877 {
878     VlcPlugin* p_plugin = (VlcPlugin*) GetProp( p_hwnd, "w00t" );
879
880     switch( i_msg )
881     {
882         case WM_PAINT:
883         {
884             PAINTSTRUCT paintstruct;
885             HDC hdc;
886             RECT rect;
887
888             hdc = BeginPaint( p_hwnd, &paintstruct );
889
890             GetClientRect( p_hwnd, &rect );
891             FillRect( hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH) );
892             TextOut( hdc, p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
893                      WINDOW_TEXT, strlen(WINDOW_TEXT) );
894
895             EndPaint( p_hwnd, &paintstruct );
896             break;
897         }
898         default:
899             p_plugin->pf_wndproc( p_hwnd, i_msg, wpar, lpar );
900             break;
901     }
902     return 0;
903 }
904 #endif /* XP_WIN */
905
906 /******************************************************************************
907  * UNIX-only methods
908  *****************************************************************************/
909 #ifdef XP_UNIX
910 static void Redraw( Widget w, XtPointer closure, XEvent *event )
911 {
912     VlcPlugin* p_plugin = (VlcPlugin*)closure;
913     GC gc;
914     XGCValues gcv;
915
916     gcv.foreground = BlackPixel( p_plugin->p_display, 0 );
917     gc = XCreateGC( p_plugin->p_display, p_plugin->window, GCForeground, &gcv );
918
919     XFillRectangle( p_plugin->p_display, p_plugin->window, gc,
920                     0, 0, p_plugin->i_width, p_plugin->i_height );
921
922     gcv.foreground = WhitePixel( p_plugin->p_display, 0 );
923     XChangeGC( p_plugin->p_display, gc, GCForeground, &gcv );
924
925     XDrawString( p_plugin->p_display, p_plugin->window, gc,
926                  p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
927                  WINDOW_TEXT, strlen(WINDOW_TEXT) );
928
929     XFreeGC( p_plugin->p_display, gc );
930 }
931
932 static void Resize ( Widget w, XtPointer closure, XEvent *event )
933 {
934     VlcPlugin* p_plugin = (VlcPlugin*)closure;
935     int i_ret;
936     Window root_return, parent_return, * children_return;
937     Window base_window;
938     unsigned int i_nchildren;
939
940 #ifdef X11_RESIZE_DEBUG
941     XWindowAttributes attr;
942
943     if( event && event->type == ConfigureNotify )
944     {
945         fprintf( stderr, "vlcshell::Resize() ConfigureNotify %d x %d, "
946                  "send_event ? %s\n", event->xconfigure.width,
947                  event->xconfigure.height,
948                  event->xconfigure.send_event ? "TRUE" : "FALSE" );
949     }
950 #endif /* X11_RESIZE_DEBUG */
951
952     if( p_plugin->i_height == i_previous_height &&
953         p_plugin->i_width == i_previous_width )
954     {
955         return;
956     }
957     i_previous_height = p_plugin->i_height;
958     i_previous_width  = p_plugin->i_width;
959
960
961     i_ret = XResizeWindow( p_plugin->p_display, p_plugin->window,
962             p_plugin->i_width, p_plugin->i_height );
963
964 #ifdef X11_RESIZE_DEBUG
965     fprintf( stderr,
966              "vlcshell::Resize() XResizeWindow(owner) returned %d\n", i_ret );
967
968     XGetWindowAttributes ( p_plugin->p_display, p_plugin->window, &attr );
969
970     /* X is asynchronous, so the current size reported here is not
971        necessarily the requested size as the Resize request may not
972        yet have been handled by the plugin host */
973     fprintf( stderr, "vlcshell::Resize() current (owner) size %d x %d\n",
974              attr.width, attr.height );
975 #endif /* X11_RESIZE_DEBUG */
976
977     XQueryTree( p_plugin->p_display, p_plugin->window,
978                 &root_return, &parent_return, &children_return,
979                 &i_nchildren );
980
981     if( i_nchildren > 0 )
982     {
983         /* XXX: Make assumptions related to the window parenting structure in
984            vlc/modules/video_output/x11/xcommon.c */
985         base_window = children_return[i_nchildren - 1];
986
987 #ifdef X11_RESIZE_DEBUG
988         fprintf( stderr, "vlcshell::Resize() got %d children\n", i_nchildren );
989         fprintf( stderr, "vlcshell::Resize() got base_window %p\n",
990                  base_window );
991 #endif /* X11_RESIZE_DEBUG */
992
993         i_ret = XResizeWindow( p_plugin->p_display, base_window,
994                 p_plugin->i_width, p_plugin->i_height );
995
996 #ifdef X11_RESIZE_DEBUG
997         fprintf( stderr,
998                  "vlcshell::Resize() XResizeWindow(base) returned %d\n",
999                  i_ret );
1000
1001         XGetWindowAttributes( p_plugin->p_display, base_window, &attr );
1002
1003         fprintf( stderr, "vlcshell::Resize() new size %d x %d\n",
1004                  attr.width, attr.height );
1005 #endif /* X11_RESIZE_DEBUG */
1006     }
1007 }
1008
1009 #endif /* XP_UNIX */
1010