1 /*****************************************************************************
2 * vlcplugin.c: a VideoLAN Client plugin for Mozilla
3 *****************************************************************************
4 * Copyright (C) 2002 VideoLAN
5 * $Id: vlcplugin.c,v 1.5 2002/08/20 18:08:51 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <plugin/npapi.h>
35 #include <X11/Intrinsic.h>
36 #include <X11/StringDefs.h>
41 #include "vlcplugin.h"
43 /*******************************************************************************
44 * Unix-only declarations
45 ******************************************************************************/
46 static void Redraw( Widget w, XtPointer closure, XEvent *event );
48 /*******************************************************************************
50 ******************************************************************************/
51 char* NPP_GetMIMEDescription( void )
53 return( PLUGIN_MIMETYPES );
56 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
58 NPError err = NPERR_NO_ERROR;
59 if (variable == NPPVpluginNameString)
60 *((char **)value) = PLUGIN_NAME;
61 else if (variable == NPPVpluginDescriptionString)
62 *((char **)value) = PLUGIN_DESCRIPTION;
64 err = NPERR_GENERIC_ERROR;
69 /*******************************************************************************
70 * General Plug-in Calls
71 ******************************************************************************/
72 NPError NPP_Initialize( void )
74 fprintf(stderr, "NPP_Initialize\n");
75 return NPERR_NO_ERROR;
78 jref NPP_GetJavaClass( void )
80 return NULL; /* Java disabled */
83 void NPP_Shutdown( void )
88 NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
89 char* argn[], char* argv[], NPSavedData* saved )
91 NPError result = NPERR_NO_ERROR;
99 /*, "--plugin-path", "/home/sam/videolan/vlc_MAIN/plugins"*/
100 , "--vout", "xvideo,x11,dummy"
106 fprintf(stderr, "NPP_New\n");
108 if (instance == NULL)
109 return NPERR_INVALID_INSTANCE_ERROR;
111 instance->pdata = NPN_MemAlloc(sizeof(PluginInstance));
113 This = (PluginInstance*) instance->pdata;
116 return NPERR_OUT_OF_MEMORY_ERROR;
119 /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */
121 This->fWindow = NULL;
126 This->p_vlc = vlc_create_r();
127 if( This->p_vlc == NULL )
129 return NPERR_GENERIC_ERROR;
132 i_ret = vlc_init_r( This->p_vlc, sizeof(ppsz_foo)/sizeof(char*), ppsz_foo );
135 vlc_destroy_r( This->p_vlc );
137 return NPERR_GENERIC_ERROR;
140 vlc_set_r( This->p_vlc, "vout", "xvideo,x11,dummy" );
141 vlc_set_r( This->p_vlc, "intf", "dummy" );
142 vlc_set_r( This->p_vlc, "audio", 0 );
144 i_ret = vlc_run_r( This->p_vlc );
147 vlc_destroy_r( This->p_vlc );
149 return NPERR_GENERIC_ERROR;
153 This->psz_target = NULL;
155 for( i = 0; i < argc ; i++ )
157 fprintf(stderr, "arg %i: '%s' = '%s'\n", i, argn[i], argv[i]);
158 if(!strcmp(argn[i],"target"))
160 fprintf(stderr, "target specified: %s\n", argv[i]);
161 This->psz_target = strdup( argv[i] );
165 /*vlc_set_r( This->psz_target, argn[i], argv[i] );*/
172 NPError NPP_Destroy( NPP instance, NPSavedData** save )
174 PluginInstance* This;
176 fprintf(stderr, "NPP_Destroy\n");
178 if (instance == NULL)
179 return NPERR_INVALID_INSTANCE_ERROR;
181 This = (PluginInstance*) instance->pdata;
183 if( This->p_vlc != NULL )
185 vlc_destroy_r( This->p_vlc );
189 if( This->psz_target )
191 free( This->psz_target );
192 This->psz_target = NULL;
196 NPN_MemFree(instance->pdata);
197 instance->pdata = NULL;
200 return NPERR_NO_ERROR;
203 NPError NPP_SetWindow( NPP instance, NPWindow* window )
205 NPError result = NPERR_NO_ERROR;
206 PluginInstance* This;
208 fprintf(stderr, "NPP_SetWindow\n");
210 if (instance == NULL)
211 return NPERR_INVALID_INSTANCE_ERROR;
213 This = (PluginInstance*) instance->pdata;
215 vlc_set_r( This->p_vlc, "x11-drawable", window->window );
216 vlc_set_r( This->p_vlc, "xvideo-drawable", window->window );
219 * Before setting window to point to the
220 * new window, you may wish to compare the new window
221 * info to the previous window (if any) to note window
226 Widget netscape_widget;
228 This->window = (Window) window->window;
231 This->width = window->width;
232 This->height = window->height;
233 This->display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
235 netscape_widget = XtWindowToWidget(This->display, This->window);
236 XtAddEventHandler(netscape_widget, ExposureMask, FALSE, (XtEventHandler)Redraw, This);
237 Redraw(netscape_widget, (XtPointer)This, NULL);
240 This->fWindow = window;
243 if( !This->b_stream )
246 if( This->psz_target )
248 vlc_add_target_r( This->p_vlc, This->psz_target, PLAYLIST_APPEND, PLAYLIST_END );
250 vlc_add_target_r( This->p_vlc, "vlc:loop", PLAYLIST_APPEND, PLAYLIST_END );
259 NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
260 NPBool seekable, uint16 *stype )
262 PluginInstance* This;
264 fprintf(stderr, "NPP_NewStream - FILE mode !!\n");
266 if (instance == NULL)
267 return NPERR_INVALID_INSTANCE_ERROR;
269 This = (PluginInstance*) instance->pdata;
271 /* We want a *filename* ! */
275 if( This->b_stream == 0 )
277 This->psz_target = strdup( stream->url );
282 return NPERR_NO_ERROR;
286 /* PLUGIN DEVELOPERS:
287 * These next 2 functions are directly relevant in a plug-in which
288 * handles the data in a streaming manner. If you want zero bytes
289 * because no buffer space is YET available, return 0. As long as
290 * the stream has not been written to the plugin, Navigator will
291 * continue trying to send bytes. If the plugin doesn't want them,
292 * just return some large number from NPP_WriteReady(), and
293 * ignore them in NPP_Write(). For a NP_ASFILE stream, they are
294 * still called but can safely be ignored using this strategy.
297 int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
298 * mode so we can take any size stream in our
299 * write call (since we ignore it) */
301 #define SARASS_SIZE (1024*1024)
303 int32 NPP_WriteReady( NPP instance, NPStream *stream )
305 PluginInstance* This;
307 fprintf(stderr, "NPP_WriteReady\n");
309 if (instance != NULL)
311 This = (PluginInstance*) instance->pdata;
312 /* Muahahahahahahaha */
313 return STREAMBUFSIZE;
314 /*return SARASS_SIZE;*/
317 /* Number of bytes ready to accept in NPP_Write() */
318 return STREAMBUFSIZE;
323 int32 NPP_Write( NPP instance, NPStream *stream, int32 offset,
324 int32 len, void *buffer )
326 fprintf(stderr, "NPP_Write %i\n", len);
328 if (instance != NULL)
330 /*PluginInstance* This = (PluginInstance*) instance->pdata;*/
333 return len; /* The number of bytes accepted */
337 NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason )
339 PluginInstance* This;
340 fprintf(stderr, "NPP_DestroyStream\n");
342 if (instance == NULL)
343 return NPERR_INVALID_INSTANCE_ERROR;
344 This = (PluginInstance*) instance->pdata;
346 return NPERR_NO_ERROR;
350 void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
352 PluginInstance* This;
353 fprintf(stderr, "NPP_StreamAsFile\n");
354 if (instance != NULL)
356 This = (PluginInstance*) instance->pdata;
357 vlc_add_target_r( This->p_vlc, fname, PLAYLIST_APPEND, PLAYLIST_END );
359 vlc_add_target_r( This->p_vlc, "vlc:loop", PLAYLIST_APPEND, PLAYLIST_END );
364 void NPP_Print( NPP instance, NPPrint* printInfo )
366 fprintf(stderr, "NPP_Print\n");
368 if(printInfo == NULL)
371 if (instance != NULL) {
372 PluginInstance* This = (PluginInstance*) instance->pdata;
374 if (printInfo->mode == NP_FULL) {
377 * If your plugin would like to take over
378 * printing completely when it is in full-screen mode,
379 * set printInfo->pluginPrinted to TRUE and print your
380 * plugin as you see fit. If your plugin wants Netscape
381 * to handle printing in this case, set
382 * printInfo->pluginPrinted to FALSE (the default) and
383 * do nothing. If you do want to handle printing
384 * yourself, printOne is true if the print button
385 * (as opposed to the print menu) was clicked.
386 * On the Macintosh, platformPrint is a THPrint; on
387 * Windows, platformPrint is a structure
388 * (defined in npapi.h) containing the printer name, port,
392 void* platformPrint =
393 printInfo->print.fullPrint.platformPrint;
395 printInfo->print.fullPrint.printOne;
398 printInfo->print.fullPrint.pluginPrinted = FALSE;
400 else { /* If not fullscreen, we must be embedded */
403 * If your plugin is embedded, or is full-screen
404 * but you returned false in pluginPrinted above, NPP_Print
405 * will be called with mode == NP_EMBED. The NPWindow
406 * in the printInfo gives the location and dimensions of
407 * the embedded plugin on the printed page. On the
408 * Macintosh, platformPrint is the printer port; on
409 * Windows, platformPrint is the handle to the printing
413 NPWindow* printWindow =
414 &(printInfo->print.embedPrint.window);
415 void* platformPrint =
416 printInfo->print.embedPrint.platformPrint;
421 /*******************************************************************************
423 // Notifies the instance of the completion of a URL request.
425 // NPP_URLNotify is called when Netscape completes a NPN_GetURLNotify or
426 // NPN_PostURLNotify request, to inform the plug-in that the request,
427 // identified by url, has completed for the reason specified by reason. The most
428 // common reason code is NPRES_DONE, indicating simply that the request
429 // completed normally. Other possible reason codes are NPRES_USER_BREAK,
430 // indicating that the request was halted due to a user action (for example,
431 // clicking the "Stop" button), and NPRES_NETWORK_ERR, indicating that the
432 // request could not be completed (for example, because the URL could not be
433 // found). The complete list of reason codes is found in npapi.h.
435 // The parameter notifyData is the same plug-in-private value passed as an
436 // argument to the corresponding NPN_GetURLNotify or NPN_PostURLNotify
437 // call, and can be used by your plug-in to uniquely identify the request.
438 ******************************************************************************/
439 void NPP_URLNotify( NPP instance, const char* url, NPReason reason,
444 /*******************************************************************************
446 ******************************************************************************/
447 static void Redraw( Widget w, XtPointer closure, XEvent *event )
449 PluginInstance* This = (PluginInstance*)closure;
452 const char* text = "hello d00dZ, I'm in void Redraw()";
454 XtVaGetValues(w, XtNbackground, &gcv.background,
455 XtNforeground, &gcv.foreground, 0);
456 gc = XCreateGC(This->display, This->window,
457 GCForeground|GCBackground, &gcv);
458 XDrawRectangle(This->display, This->window, gc,
459 0, 0, This->width-1, This->height-1);
460 XDrawString(This->display, This->window, gc,
461 This->width/2 - 100, This->height/2,