]> git.sesse.net Git - vlc/blob - mozilla/vlcshell.cpp
* backport of [11386]
[vlc] / mozilla / vlcshell.cpp
1 /*****************************************************************************
2  * vlcshell.cpp: a VLC plugin for Mozilla
3  *****************************************************************************
4  * Copyright (C) 2002-2005 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         /* HACK: special case for loop, to have it set before playlist startup
334          */
335         for( i = 0; i < argc ; i++ )
336         {
337             if( !strcmp( argn[i], "loop" ) )
338             {
339                 if( !strcmp( argv[i], "yes" ) )
340                 {
341                     value.b_bool = VLC_TRUE;
342                     VLC_VariableSet( p_plugin->i_vlc, "conf::loop", value );
343                 }
344             }
345         }
346
347         i_ret = VLC_Init( p_plugin->i_vlc, sizeof(ppsz_argv)/sizeof(char*),
348                           ppsz_argv );
349
350 #ifdef XP_MACOSX
351         free( home_user );
352         free( directory );
353         free( plugin_path );
354 #endif /* XP_MACOSX */
355     }
356
357     if( i_ret )
358     {
359         VLC_Destroy( p_plugin->i_vlc );
360         p_plugin->i_vlc = 0;
361         delete p_plugin;
362         p_plugin = NULL;
363         return NPERR_GENERIC_ERROR;
364     }
365
366     value.psz_string = "dummy";
367     VLC_VariableSet( p_plugin->i_vlc, "conf::intf", value );
368     value.psz_string = VOUT_PLUGINS;
369     VLC_VariableSet( p_plugin->i_vlc, "conf::vout", value );
370     value.psz_string = AOUT_PLUGINS;
371     VLC_VariableSet( p_plugin->i_vlc, "conf::aout", value );
372
373 #else /* USE_LIBVLC */
374     p_plugin->i_vlc = 1;
375
376 #endif /* USE_LIBVLC */
377
378     p_plugin->b_stream = VLC_FALSE;
379     p_plugin->b_autoplay = VLC_FALSE;
380     p_plugin->psz_target = NULL;
381
382     for( i = 0; i < argc ; i++ )
383     {
384         if( !strcmp( argn[i], "target" ) )
385         {
386             p_plugin->psz_target = argv[i];
387         }
388         else if( !strcmp( argn[i], "autoplay" ) )
389         {
390             if( !strcmp( argv[i], "yes" ) )
391             {
392                 p_plugin->b_autoplay = 1;
393             }
394         }
395         else if( !strcmp( argn[i], "autostart" ) )
396         {
397             if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "true" ) )
398             {
399                 p_plugin->b_autoplay = 1;
400             }
401         }
402         else if( !strcmp( argn[i], "filename" ) )
403         {
404             p_plugin->psz_target = argv[i];
405         }
406         else if( !strcmp( argn[i], "src" ) )
407         {
408             p_plugin->psz_target = argv[i];
409         }
410
411 #if USE_LIBVLC
412         else if( !strcmp( argn[i], "fullscreen" ) )
413         {
414             if( !strcmp( argv[i], "yes" ) )
415             {
416                 value.b_bool = VLC_TRUE;
417                 VLC_VariableSet( p_plugin->i_vlc, "conf::fullscreen", value );
418             }
419         }
420         else if( !strcmp( argn[i], "mute" ) )
421         {
422             if( !strcmp( argv[i], "yes" ) )
423             {
424                 VLC_VolumeMute( p_plugin->i_vlc );
425             }
426         }
427 #endif /* USE_LIBVLC */
428     }
429
430     if( p_plugin->psz_target )
431     {
432         p_plugin->psz_target = strdup( p_plugin->psz_target );
433     }
434
435     return NPERR_NO_ERROR;
436 }
437
438 #ifdef XP_WIN
439 /* This is really ugly but there is a deadlock when stopping a stream
440  * (in VLC_CleanUp()) because the video output is a child of the drawable but
441  * is in a different thread. */
442 static void HackStopVout( VlcPlugin* p_plugin )
443 {
444     MSG msg;
445     HWND hwnd;
446     vlc_value_t value;
447
448     VLC_VariableGet( p_plugin->i_vlc, "drawable", &value );
449
450     hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 );
451     if( !hwnd ) return;
452
453     PostMessage( hwnd, WM_CLOSE, 0, 0 );
454
455     do
456     {
457         while( PeekMessage( &msg, (HWND)value.i_int, 0, 0, PM_REMOVE ) )
458         {
459             TranslateMessage(&msg);
460             DispatchMessage(&msg);
461         }
462         if( FindWindowEx( (HWND)value.i_int, 0, 0, 0 ) ) Sleep( 10 );
463     }
464     while( (hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 )) );
465 }
466 #endif /* XP_WIN */
467
468 NPError NPP_Destroy( NPP instance, NPSavedData** save )
469 {
470     if( instance == NULL )
471     {
472         return NPERR_INVALID_INSTANCE_ERROR;
473     }
474
475     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
476
477     if( p_plugin != NULL )
478     {
479         if( p_plugin->i_vlc )
480         {
481 #if USE_LIBVLC
482 #   ifdef XP_WIN
483             HackStopVout( p_plugin );
484 #   endif /* XP_WIN */
485             VLC_CleanUp( p_plugin->i_vlc );
486             VLC_Destroy( p_plugin->i_vlc );
487 #endif /* USE_LIBVLC */
488             p_plugin->i_vlc = 0;
489         }
490
491         if( p_plugin->psz_target )
492         {
493             free( p_plugin->psz_target );
494             p_plugin->psz_target = NULL;
495         }
496
497         delete p_plugin;
498     }
499
500     instance->pdata = NULL;
501
502     return NPERR_NO_ERROR;
503 }
504
505 NPError NPP_SetWindow( NPP instance, NPWindow* window )
506 {
507     vlc_value_t value;
508 #ifdef XP_MACOSX
509     vlc_value_t valuex;
510     vlc_value_t valuey;
511     vlc_value_t valuew;
512     vlc_value_t valueh;
513     vlc_value_t valuet;
514     vlc_value_t valuel;
515     vlc_value_t valueb;
516     vlc_value_t valuer;
517     vlc_value_t valueportx;
518     vlc_value_t valueporty;
519     Rect black_rect;
520     char * text;
521 #endif /* XP_MACOSX */
522
523     if( instance == NULL )
524     {
525         return NPERR_INVALID_INSTANCE_ERROR;
526     }
527
528     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
529
530     /* Write the window ID for vlc */
531 #if USE_LIBVLC
532
533 #ifdef XP_MACOSX
534     value.i_int = ((NP_Port*) (window->window))->port;
535     VLC_VariableSet( p_plugin->i_vlc, "drawable", value );
536
537     valueportx.i_int = ((NP_Port*) (window->window))->portx;
538     valueporty.i_int = ((NP_Port*) (window->window))->porty;
539     VLC_VariableSet( p_plugin->i_vlc, "drawableportx", valueportx );
540     VLC_VariableSet( p_plugin->i_vlc, "drawableporty", valueporty );
541
542     valuex.i_int = window->x;
543     valuey.i_int = window->y;
544     valuew.i_int = window->width;
545     valueh.i_int = window->height;
546     valuet.i_int = window->clipRect.top;
547     valuel.i_int = window->clipRect.left;
548     valueb.i_int = window->clipRect.bottom;
549     valuer.i_int = window->clipRect.right;
550
551     VLC_VariableSet( p_plugin->i_vlc, "drawablet", valuet );
552     VLC_VariableSet( p_plugin->i_vlc, "drawablel", valuel );
553     VLC_VariableSet( p_plugin->i_vlc, "drawableb", valueb );
554     VLC_VariableSet( p_plugin->i_vlc, "drawabler", valuer );
555     VLC_VariableSet( p_plugin->i_vlc, "drawablex", valuex );
556     VLC_VariableSet( p_plugin->i_vlc, "drawabley", valuey );
557     VLC_VariableSet( p_plugin->i_vlc, "drawablew", valuew );
558     VLC_VariableSet( p_plugin->i_vlc, "drawableh", valueh );
559
560     p_plugin->window = window;
561
562     /* draw the beautiful "No Picture" */
563
564     black_rect.top = valuet.i_int - valuey.i_int;
565     black_rect.left = valuel.i_int - valuex.i_int;
566     black_rect.bottom = valueb.i_int - valuey.i_int;
567     black_rect.right = valuer.i_int - valuex.i_int;
568
569     SetPort( value.i_int );
570     SetOrigin( valueportx.i_int , valueporty.i_int );
571     ForeColor(blackColor);
572     PenMode( patCopy );
573     PaintRect( &black_rect );
574
575     ForeColor(whiteColor);
576     text = strdup( WINDOW_TEXT );
577     MoveTo( valuew.i_int / 2 - 40 , valueh.i_int / 2 );
578     DrawText( text , 0 , strlen(text) );
579     free(text);
580
581 #else /* XP_MACOSX */
582     /* FIXME: this cast sucks */
583     value.i_int = (int) (ptrdiff_t) (void *) window->window;
584     VLC_VariableSet( p_plugin->i_vlc, "drawable", value );
585 #endif /* XP_MACOSX */
586
587 #endif /* USE_LIBVLC */
588
589     /*
590      * PLUGIN DEVELOPERS:
591      *  Before setting window to point to the
592      *  new window, you may wish to compare the new window
593      *  info to the previous window (if any) to note window
594      *  size changes, etc.
595      */
596
597 #ifdef XP_WIN
598     if( !window || !window->window )
599     {
600         /* Window was destroyed. Invalidate everything. */
601         if( p_plugin->p_npwin )
602         {
603 #if !USE_LIBVLC
604             SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
605                            (LONG)p_plugin->pf_wndproc );
606 #endif /* !USE_LIBVLC */
607             p_plugin->pf_wndproc = NULL;
608             p_plugin->p_hwnd = NULL;
609         }
610
611         p_plugin->p_npwin = window;
612         return NPERR_NO_ERROR;
613     }
614
615     if( p_plugin->p_npwin )
616     {
617         if( p_plugin->p_hwnd == (HWND)window->window )
618         {
619             /* Same window, but something may have changed. First we
620              * update the plugin structure, then we redraw the window */
621             p_plugin->i_width = window->width;
622             p_plugin->i_height = window->height;
623             p_plugin->p_npwin = window;
624 #if !USE_LIBVLC
625             InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
626             UpdateWindow( p_plugin->p_hwnd );
627 #endif /* !USE_LIBVLC */
628             return NPERR_NO_ERROR;
629         }
630
631         /* Window has changed. Destroy the one we have, and go
632          * on as if it was a real initialization. */
633 #if !USE_LIBVLC
634         SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
635                        (LONG)p_plugin->pf_wndproc );
636 #endif /* !USE_LIBVLC */
637         p_plugin->pf_wndproc = NULL;
638         p_plugin->p_hwnd = NULL;
639     }
640
641 #if !USE_LIBVLC
642     p_plugin->pf_wndproc = (WNDPROC)SetWindowLong( (HWND)window->window,
643                                                    GWL_WNDPROC, (LONG)Manage );
644 #endif /* !USE_LIBVLC */
645
646     p_plugin->p_hwnd = (HWND)window->window;
647     SetProp( p_plugin->p_hwnd, "w00t", (HANDLE)p_plugin );
648     InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
649     UpdateWindow( p_plugin->p_hwnd );
650 #endif /* XP_WIN */
651
652     p_plugin->i_width = window->width;
653     p_plugin->i_height = window->height;
654     p_plugin->p_npwin = window;
655
656 #ifdef XP_UNIX
657     p_plugin->window = (Window) window->window;
658     p_plugin->p_display =
659         ((NPSetWindowCallbackStruct *)window->ws_info)->display;
660
661     XResizeWindow( p_plugin->p_display, p_plugin->window,
662                    p_plugin->i_width, p_plugin->i_height );
663     Widget w = XtWindowToWidget( p_plugin->p_display, p_plugin->window );
664     XtAddEventHandler( w, ExposureMask, FALSE,
665                        (XtEventHandler)Redraw, p_plugin );
666     XtAddEventHandler( w, StructureNotifyMask, FALSE,
667                        (XtEventHandler)Resize, p_plugin );
668     Redraw( w, (XtPointer)p_plugin, NULL );
669 #endif /* XP_UNIX */
670
671     if( !p_plugin->b_stream )
672     {
673         int i_mode = PLAYLIST_APPEND;
674
675         if( p_plugin->b_autoplay )
676         {
677             i_mode |= PLAYLIST_GO;
678         }
679
680         if( p_plugin->psz_target )
681         {
682 #if USE_LIBVLC
683             VLC_AddTarget( p_plugin->i_vlc, p_plugin->psz_target,
684                            0, 0, PLAYLIST_INSERT, 0 );
685 #endif
686             p_plugin->b_stream = VLC_TRUE;
687         }
688     }
689
690     return NPERR_NO_ERROR;
691 }
692
693 NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
694                        NPBool seekable, uint16 *stype )
695 {
696     if( instance == NULL )
697     {
698         return NPERR_INVALID_INSTANCE_ERROR;
699     }
700
701 #if 0
702     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
703 #endif
704
705     /* fprintf(stderr, "NPP_NewStream - FILE mode !!\n"); */
706
707     /* We want a *filename* ! */
708     *stype = NP_ASFILE;
709
710 #if 0
711     if( !p_plugin->b_stream )
712     {
713         p_plugin->psz_target = strdup( stream->url );
714         p_plugin->b_stream = VLC_TRUE;
715     }
716 #endif
717
718     return NPERR_NO_ERROR;
719 }
720
721 int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
722                    * mode so we can take any size stream in our
723                    * write call (since we ignore it) */
724
725 #define SARASS_SIZE (1024*1024)
726
727 int32 NPP_WriteReady( NPP instance, NPStream *stream )
728 {
729     VlcPlugin* p_plugin;
730
731     /* fprintf(stderr, "NPP_WriteReady\n"); */
732
733     if (instance != NULL)
734     {
735         p_plugin = (VlcPlugin*) instance->pdata;
736         /* Muahahahahahahaha */
737         return STREAMBUFSIZE;
738         /*return SARASS_SIZE;*/
739     }
740
741     /* Number of bytes ready to accept in NPP_Write() */
742     return STREAMBUFSIZE;
743     /*return 0;*/
744 }
745
746
747 int32 NPP_Write( NPP instance, NPStream *stream, int32 offset,
748                  int32 len, void *buffer )
749 {
750     /* fprintf(stderr, "NPP_Write %i\n", (int)len); */
751
752     if( instance != NULL )
753     {
754         /*VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata;*/
755     }
756
757     return len;         /* The number of bytes accepted */
758 }
759
760
761 NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason )
762 {
763     if( instance == NULL )
764     {
765         return NPERR_INVALID_INSTANCE_ERROR;
766     }
767
768     return NPERR_NO_ERROR;
769 }
770
771
772 void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
773 {
774     if( instance == NULL )
775     {
776         return;
777     }
778
779     /* fprintf(stderr, "NPP_StreamAsFile %s\n", fname); */
780
781 #if USE_LIBVLC
782     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
783
784     VLC_AddTarget( p_plugin->i_vlc, fname, 0, 0,
785                    PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
786 #endif /* USE_LIBVLC */
787 }
788
789
790 void NPP_URLNotify( NPP instance, const char* url,
791                     NPReason reason, void* notifyData )
792 {
793     /***** Insert NPP_URLNotify code here *****\
794     PluginInstance* p_plugin;
795     if (instance != NULL)
796         p_plugin = (PluginInstance*) instance->pdata;
797     \*********************************************/
798 }
799
800
801 void NPP_Print( NPP instance, NPPrint* printInfo )
802 {
803     if( printInfo == NULL )
804     {
805         return;
806     }
807
808     if( instance != NULL )
809     {
810         /***** Insert NPP_Print code here *****\
811         PluginInstance* p_plugin = (PluginInstance*) instance->pdata;
812         \**************************************/
813
814         if( printInfo->mode == NP_FULL )
815         {
816             /*
817              * PLUGIN DEVELOPERS:
818              *  If your plugin would like to take over
819              *  printing completely when it is in full-screen mode,
820              *  set printInfo->pluginPrinted to TRUE and print your
821              *  plugin as you see fit.  If your plugin wants Netscape
822              *  to handle printing in this case, set
823              *  printInfo->pluginPrinted to FALSE (the default) and
824              *  do nothing.  If you do want to handle printing
825              *  yourself, printOne is true if the print button
826              *  (as opposed to the print menu) was clicked.
827              *  On the Macintosh, platformPrint is a THPrint; on
828              *  Windows, platformPrint is a structure
829              *  (defined in npapi.h) containing the printer name, port,
830              *  etc.
831              */
832
833             /***** Insert NPP_Print code here *****\
834             void* platformPrint =
835                 printInfo->print.fullPrint.platformPrint;
836             NPBool printOne =
837                 printInfo->print.fullPrint.printOne;
838             \**************************************/
839
840             /* Do the default*/
841             printInfo->print.fullPrint.pluginPrinted = FALSE;
842         }
843         else
844         {
845             /* If not fullscreen, we must be embedded */
846             /*
847              * PLUGIN DEVELOPERS:
848              *  If your plugin is embedded, or is full-screen
849              *  but you returned false in pluginPrinted above, NPP_Print
850              *  will be called with mode == NP_EMBED.  The NPWindow
851              *  in the printInfo gives the location and dimensions of
852              *  the embedded plugin on the printed page.  On the
853              *  Macintosh, platformPrint is the printer port; on
854              *  Windows, platformPrint is the handle to the printing
855              *  device context.
856              */
857
858             /***** Insert NPP_Print code here *****\
859             NPWindow* printWindow =
860                 &(printInfo->print.embedPrint.window);
861             void* platformPrint =
862                 printInfo->print.embedPrint.platformPrint;
863             \**************************************/
864         }
865     }
866 }
867
868 /******************************************************************************
869  * Windows-only methods
870  *****************************************************************************/
871 #if defined(XP_WIN) && !USE_LIBVLC
872 LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar )
873 {
874     VlcPlugin* p_plugin = (VlcPlugin*) GetProp( p_hwnd, "w00t" );
875
876     switch( i_msg )
877     {
878         case WM_PAINT:
879         {
880             PAINTSTRUCT paintstruct;
881             HDC hdc;
882             RECT rect;
883
884             hdc = BeginPaint( p_hwnd, &paintstruct );
885
886             GetClientRect( p_hwnd, &rect );
887             FillRect( hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH) );
888             TextOut( hdc, p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
889                      WINDOW_TEXT, strlen(WINDOW_TEXT) );
890
891             EndPaint( p_hwnd, &paintstruct );
892             break;
893         }
894         default:
895             p_plugin->pf_wndproc( p_hwnd, i_msg, wpar, lpar );
896             break;
897     }
898     return 0;
899 }
900 #endif /* XP_WIN */
901
902 /******************************************************************************
903  * UNIX-only methods
904  *****************************************************************************/
905 #ifdef XP_UNIX
906 static void Redraw( Widget w, XtPointer closure, XEvent *event )
907 {
908     VlcPlugin* p_plugin = (VlcPlugin*)closure;
909     GC gc;
910     XGCValues gcv;
911
912     gcv.foreground = BlackPixel( p_plugin->p_display, 0 );
913     gc = XCreateGC( p_plugin->p_display, p_plugin->window, GCForeground, &gcv );
914
915     XFillRectangle( p_plugin->p_display, p_plugin->window, gc,
916                     0, 0, p_plugin->i_width, p_plugin->i_height );
917
918     gcv.foreground = WhitePixel( p_plugin->p_display, 0 );
919     XChangeGC( p_plugin->p_display, gc, GCForeground, &gcv );
920
921     XDrawString( p_plugin->p_display, p_plugin->window, gc,
922                  p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
923                  WINDOW_TEXT, strlen(WINDOW_TEXT) );
924
925     XFreeGC( p_plugin->p_display, gc );
926 }
927
928 static void Resize ( Widget w, XtPointer closure, XEvent *event )
929 {
930     VlcPlugin* p_plugin = (VlcPlugin*)closure;
931     int i_ret;
932     Window root_return, parent_return, * children_return;
933     Window base_window;
934     unsigned int i_nchildren;
935
936 #ifdef X11_RESIZE_DEBUG
937     XWindowAttributes attr;
938
939     if( event && event->type == ConfigureNotify )
940     {
941         fprintf( stderr, "vlcshell::Resize() ConfigureNotify %d x %d, "
942                  "send_event ? %s\n", event->xconfigure.width,
943                  event->xconfigure.height,
944                  event->xconfigure.send_event ? "TRUE" : "FALSE" );
945     }
946 #endif /* X11_RESIZE_DEBUG */
947
948     i_ret = XResizeWindow( p_plugin->p_display, p_plugin->window,
949             p_plugin->i_width, p_plugin->i_height );
950
951 #ifdef X11_RESIZE_DEBUG
952     fprintf( stderr,
953              "vlcshell::Resize() XResizeWindow(owner) returned %d\n", i_ret );
954
955     XGetWindowAttributes ( p_plugin->p_display, p_plugin->window, &attr );
956
957     /* X is asynchronous, so the current size reported here is not
958        necessarily the requested size as the Resize request may not
959        yet have been handled by the plugin host */
960     fprintf( stderr, "vlcshell::Resize() current (owner) size %d x %d\n",
961              attr.width, attr.height );
962 #endif /* X11_RESIZE_DEBUG */
963
964     XQueryTree( p_plugin->p_display, p_plugin->window,
965                 &root_return, &parent_return, &children_return,
966                 &i_nchildren );
967
968     if( i_nchildren > 0 )
969     {
970         /* XXX: Make assumptions related to the window parenting structure in
971            vlc/modules/video_output/x11/xcommon.c */
972         base_window = children_return[i_nchildren - 1];
973
974 #ifdef X11_RESIZE_DEBUG
975         fprintf( stderr, "vlcshell::Resize() got %d children\n", i_nchildren );
976         fprintf( stderr, "vlcshell::Resize() got base_window %p\n",
977                  base_window );
978 #endif /* X11_RESIZE_DEBUG */
979
980         i_ret = XResizeWindow( p_plugin->p_display, base_window,
981                 p_plugin->i_width, p_plugin->i_height );
982
983 #ifdef X11_RESIZE_DEBUG
984         fprintf( stderr,
985                  "vlcshell::Resize() XResizeWindow(base) returned %d\n",
986                  i_ret );
987
988         XGetWindowAttributes( p_plugin->p_display, base_window, &attr );
989
990         fprintf( stderr, "vlcshell::Resize() new size %d x %d\n",
991                  attr.width, attr.height );
992 #endif /* X11_RESIZE_DEBUG */
993     }
994 }
995
996 #endif /* XP_UNIX */
997