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