Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

vlcshell.cpp

00001 /*****************************************************************************
00002  * vlcshell.cpp: a VLC plugin for Mozilla
00003  *****************************************************************************
00004  * Copyright (C) 2002-2005 the VideoLAN team
00005  * $Id: vlcshell.cpp 13236 2005-11-14 00:52:36Z adn $
00006  *
00007  * Authors: Samuel Hocevar <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /* XXX: disable VLC here */
00025 #define USE_LIBVLC 1
00026 
00027 /*****************************************************************************
00028  * Preamble
00029  *****************************************************************************/
00030 #include "config.h"
00031 
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <stdlib.h>
00035 
00036 /* vlc stuff */
00037 #ifdef USE_LIBVLC
00038 #   include <vlc/vlc.h>
00039 #endif
00040 
00041 /* Mozilla stuff */
00042 #ifdef HAVE_MOZILLA_CONFIG_H
00043 #   include <mozilla-config.h>
00044 #endif
00045 #include <nsISupports.h>
00046 #include <nsMemory.h>
00047 #include <npapi.h>
00048 
00049 /* This is from mozilla java, do we really need it? */
00050 #if 0
00051 #include <jri.h>
00052 #endif
00053 
00054 #if !defined(XP_MACOSX) && !defined(XP_UNIX) && !defined(XP_WIN)
00055 #define XP_UNIX 1
00056 #elif defined(XP_MACOSX)
00057 #undef XP_UNIX
00058 #endif
00059 
00060 #ifdef XP_WIN
00061     /* Windows stuff */
00062 #endif
00063 
00064 #ifdef XP_MACOSX
00065     /* Mac OS X stuff */
00066 #   include <Quickdraw.h>
00067 #endif
00068 
00069 #ifdef XP_UNIX
00070     /* X11 stuff */
00071 #   include <X11/Xlib.h>
00072 #   include <X11/Intrinsic.h>
00073 #   include <X11/StringDefs.h>
00074 #endif
00075 
00076 #include "vlcpeer.h"
00077 #include "vlcplugin.h"
00078 
00079 #if USE_LIBVLC
00080 #   define WINDOW_TEXT "(no picture)"
00081 #else
00082 #   define WINDOW_TEXT "(no libvlc)"
00083 #endif
00084 
00085 /* Enable/disable debugging printf's for X11 resizing */
00086 #undef X11_RESIZE_DEBUG
00087 
00088 /*****************************************************************************
00089  * Unix-only declarations
00090 ******************************************************************************/
00091 #ifdef XP_UNIX
00092 #   define VOUT_PLUGINS "xvideo,x11,dummy"
00093 #   define AOUT_PLUGINS "alsa,oss,dummy"
00094 
00095 static unsigned int i_previous_height = 100000;
00096 static unsigned int i_previous_width = 100000;
00097 
00098 static void Redraw( Widget w, XtPointer closure, XEvent *event );
00099 static void Resize( Widget w, XtPointer closure, XEvent *event );
00100 #endif
00101 
00102 /*****************************************************************************
00103  * MacOS-only declarations
00104 ******************************************************************************/
00105 #ifdef XP_MACOSX
00106 #   define VOUT_PLUGINS "macosx"
00107 #   define AOUT_PLUGINS "macosx"
00108 
00109 #endif
00110 
00111 /*****************************************************************************
00112  * Windows-only declarations
00113  *****************************************************************************/
00114 #ifdef XP_WIN
00115 #   define VOUT_PLUGINS "directx,wingdi,dummy"
00116 #   define AOUT_PLUGINS "directx,waveout,dummy"
00117 
00118 #if defined(XP_WIN) && !USE_LIBVLC
00119 LRESULT CALLBACK Manage( HWND, UINT, WPARAM, LPARAM );
00120 #endif
00121 #endif
00122 
00123 /******************************************************************************
00124  * UNIX-only API calls
00125  *****************************************************************************/
00126 char * NPP_GetMIMEDescription( void )
00127 {
00128     return PLUGIN_MIMETYPES;
00129 }
00130 
00131 NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
00132 {
00133 
00134     static nsIID nsid = VLCINTF_IID;
00135     static char psz_desc[1000];
00136 
00137     switch( variable )
00138     {
00139         case NPPVpluginNameString:
00140             *((char **)value) = PLUGIN_NAME;
00141             return NPERR_NO_ERROR;
00142 
00143         case NPPVpluginDescriptionString:
00144 #if USE_LIBVLC
00145             snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, VLC_Version() );
00146 #else /* USE_LIBVLC */
00147             snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, "(disabled)" );
00148 #endif /* USE_LIBVLC */
00149             psz_desc[1000-1] = 0;
00150             *((char **)value) = psz_desc;
00151             return NPERR_NO_ERROR;
00152 
00153         default:
00154             /* go on... */
00155             break;
00156     }
00157 
00158     if( instance == NULL )
00159     {
00160         return NPERR_INVALID_INSTANCE_ERROR;
00161     }
00162 
00163     VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata;
00164 
00165     switch( variable )
00166     {
00167         case NPPVpluginScriptableInstance:
00168             *(nsISupports**)value = p_plugin->GetPeer();
00169             if( *(nsISupports**)value == NULL )
00170             {
00171                 return NPERR_OUT_OF_MEMORY_ERROR;
00172             }
00173             break;
00174 
00175         case NPPVpluginScriptableIID:
00176             *(nsIID**)value = (nsIID*)NPN_MemAlloc( sizeof(nsIID) );
00177             if( *(nsIID**)value == NULL )
00178             {
00179                 return NPERR_OUT_OF_MEMORY_ERROR;
00180             }
00181             **(nsIID**)value = nsid;
00182             break;
00183 
00184         default:
00185             return NPERR_GENERIC_ERROR;
00186     }
00187 
00188     return NPERR_NO_ERROR;
00189 }
00190 
00191 /******************************************************************************
00192  * Mac-only API calls
00193  *****************************************************************************/
00194 #ifdef XP_MACOSX
00195 int16 NPP_HandleEvent( NPP instance, void * event )
00196 {
00197     VlcPlugin *p_plugin = (VlcPlugin*)instance->pdata;
00198     vlc_value_t value;
00199 
00200     if( instance == NULL )
00201     {
00202         return false;
00203     }
00204 
00205     EventRecord *pouetEvent = (EventRecord*)event;
00206 
00207     if (pouetEvent->what == 6)
00208     {
00209         value.i_int = 1;
00210         VLC_VariableSet( p_plugin->i_vlc, "drawableredraw", value );
00211         return true;
00212     }
00213 
00214     Boolean eventHandled = false;
00215 
00216     return eventHandled;
00217 }
00218 #endif /* XP_MACOSX */
00219 
00220 /******************************************************************************
00221  * General Plug-in Calls
00222  *****************************************************************************/
00223 NPError NPP_Initialize( void )
00224 {
00225     return NPERR_NO_ERROR;
00226 }
00227 
00228 jref NPP_GetJavaClass( void )
00229 {
00230     return NULL;
00231 }
00232 
00233 void NPP_Shutdown( void )
00234 {
00235     ;
00236 }
00237 
00238 NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
00239                  char* argn[], char* argv[], NPSavedData* saved )
00240 {
00241     int i;
00242 
00243 #if USE_LIBVLC
00244     vlc_value_t value;
00245     int i_ret;
00246 
00247 #endif /* USE_LIBVLC */
00248 
00249     if( instance == NULL )
00250     {
00251         return NPERR_INVALID_INSTANCE_ERROR;
00252     }
00253 
00254     VlcPlugin * p_plugin = new VlcPlugin( instance );
00255 
00256     if( p_plugin == NULL )
00257     {
00258         return NPERR_OUT_OF_MEMORY_ERROR;
00259     }
00260 
00261     instance->pdata = p_plugin;
00262 
00263 #ifdef XP_WIN
00264     p_plugin->p_hwnd = NULL;
00265     p_plugin->pf_wndproc = NULL;
00266 #endif /* XP_WIN */
00267 
00268 #ifdef XP_UNIX
00269     p_plugin->window = 0;
00270     p_plugin->p_display = NULL;
00271 #endif /* XP_UNIX */
00272 
00273     p_plugin->p_npwin = NULL;
00274     p_plugin->i_npmode = mode;
00275     p_plugin->i_width = 0;
00276     p_plugin->i_height = 0;
00277 
00278 #if USE_LIBVLC
00279     p_plugin->i_vlc = VLC_Create();
00280     if( p_plugin->i_vlc < 0 )
00281     {
00282         p_plugin->i_vlc = 0;
00283         delete p_plugin;
00284         p_plugin = NULL;
00285         return NPERR_GENERIC_ERROR;
00286     }
00287 
00288     {
00289 #ifdef XP_MACOSX
00290         char *home_user;
00291         char *directory;
00292         char *plugin_path;
00293         char *ppsz_argv[] = { "vlc", "--plugin-path", NULL };
00294 
00295         home_user = strdup( getenv("HOME") );
00296         directory = strdup( "/Library/Internet Plug-Ins/VLC Plugin.plugin/"
00297                             "Contents/MacOS/modules" );
00298         plugin_path = malloc( strlen( directory ) + strlen( home_user ) );
00299         memcpy( plugin_path , home_user , strlen(home_user) );
00300         memcpy( plugin_path + strlen( home_user ) , directory ,
00301                 strlen( directory ) );
00302 
00303         ppsz_argv[2] = plugin_path;
00304 
00305 #elif defined(XP_WIN)
00306         char *ppsz_argv[] = { NULL, "-vv" };
00307         HKEY h_key;
00308         DWORD i_type, i_data = MAX_PATH + 1;
00309         char p_data[MAX_PATH + 1];
00310         if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\VideoLAN\\VLC",
00311                           0, KEY_READ, &h_key ) == ERROR_SUCCESS )
00312         {
00313              if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type,
00314                                   (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS )
00315              {
00316                  if( i_type == REG_SZ )
00317                  {
00318                      strcat( p_data, "\\vlc" );
00319                      ppsz_argv[0] = p_data;
00320                  }
00321              }
00322              RegCloseKey( h_key );
00323         }
00324 
00325         if( !ppsz_argv[0] ) ppsz_argv[0] = "vlc";
00326 
00327 #else /* XP_MACOSX */
00328         char *ppsz_argv[] =
00329         {
00330             "vlc"
00331             /*, "--plugin-path", "/home/sam/videolan/vlc_MAIN/plugins"*/
00332         };
00333 
00334 #endif /* XP_MACOSX */
00335 
00336         /* HACK: special case for loop, to have it set before playlist startup
00337          */
00338         for( i = 0; i < argc ; i++ )
00339         {
00340             if( !strcmp( argn[i], "loop" ) )
00341             {
00342                 if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) )
00343                 {
00344                     value.b_bool = VLC_TRUE;
00345                     VLC_VariableSet( p_plugin->i_vlc, "conf::loop", value );
00346                 }
00347             }
00348         }
00349 
00350         i_ret = VLC_Init( p_plugin->i_vlc, sizeof(ppsz_argv)/sizeof(char*),
00351                           ppsz_argv );
00352 
00353 #ifdef XP_MACOSX
00354         free( home_user );
00355         free( directory );
00356         free( plugin_path );
00357 #endif /* XP_MACOSX */
00358     }
00359 
00360     if( i_ret )
00361     {
00362         VLC_Destroy( p_plugin->i_vlc );
00363         p_plugin->i_vlc = 0;
00364         delete p_plugin;
00365         p_plugin = NULL;
00366         return NPERR_GENERIC_ERROR;
00367     }
00368 
00369     value.psz_string = "dummy";
00370     VLC_VariableSet( p_plugin->i_vlc, "conf::intf", value );
00371     value.psz_string = VOUT_PLUGINS;
00372     VLC_VariableSet( p_plugin->i_vlc, "conf::vout", value );
00373     value.psz_string = AOUT_PLUGINS;
00374     VLC_VariableSet( p_plugin->i_vlc, "conf::aout", value );
00375 
00376 #else /* USE_LIBVLC */
00377     p_plugin->i_vlc = 1;
00378 
00379 #endif /* USE_LIBVLC */
00380 
00381     p_plugin->b_stream = VLC_FALSE;
00382     p_plugin->b_autoplay = VLC_FALSE;
00383     p_plugin->psz_target = NULL;
00384 
00385     for( i = 0; i < argc ; i++ )
00386     {
00387         if( !strcmp( argn[i], "target" ) )
00388         {
00389             p_plugin->psz_target = argv[i];
00390         }
00391         else if( !strcmp( argn[i], "autoplay" ) )
00392         {
00393             if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) )
00394             {
00395                 p_plugin->b_autoplay = 1;
00396             }
00397         }
00398         else if( !strcmp( argn[i], "autostart" ) )
00399         {
00400             if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "true" ) )
00401             {
00402                 p_plugin->b_autoplay = 1;
00403             }
00404         }
00405         else if( !strcmp( argn[i], "filename" ) )
00406         {
00407             p_plugin->psz_target = argv[i];
00408         }
00409         else if( !strcmp( argn[i], "src" ) )
00410         {
00411             p_plugin->psz_target = argv[i];
00412         }
00413 
00414 #if USE_LIBVLC
00415         else if( !strcmp( argn[i], "fullscreen" ) )
00416         {
00417             if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) )
00418             {
00419                 value.b_bool = VLC_TRUE;
00420                 VLC_VariableSet( p_plugin->i_vlc, "conf::fullscreen", value );
00421             }
00422         }
00423         else if( !strcmp( argn[i], "mute" ) )
00424         {
00425             if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) )
00426             {
00427                 VLC_VolumeMute( p_plugin->i_vlc );
00428             }
00429         }
00430 #endif /* USE_LIBVLC */
00431     }
00432 
00433     if( p_plugin->psz_target )
00434     {
00435         p_plugin->psz_target = strdup( p_plugin->psz_target );
00436     }
00437 
00438     return NPERR_NO_ERROR;
00439 }
00440 
00441 #ifdef XP_WIN
00442 /* This is really ugly but there is a deadlock when stopping a stream
00443  * (in VLC_CleanUp()) because the video output is a child of the drawable but
00444  * is in a different thread. */
00445 static void HackStopVout( VlcPlugin* p_plugin )
00446 {
00447     MSG msg;
00448     HWND hwnd;
00449     vlc_value_t value;
00450 
00451     VLC_VariableGet( p_plugin->i_vlc, "drawable", &value );
00452 
00453     hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 );
00454     if( !hwnd ) return;
00455 
00456     PostMessage( hwnd, WM_CLOSE, 0, 0 );
00457 
00458     do
00459     {
00460         while( PeekMessage( &msg, (HWND)value.i_int, 0, 0, PM_REMOVE ) )
00461         {
00462             TranslateMessage(&msg);
00463             DispatchMessage(&msg);
00464         }
00465         if( FindWindowEx( (HWND)value.i_int, 0, 0, 0 ) ) Sleep( 10 );
00466     }
00467     while( (hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 )) );
00468 }
00469 #endif /* XP_WIN */
00470 
00471 NPError NPP_Destroy( NPP instance, NPSavedData** save )
00472 {
00473     if( instance == NULL )
00474     {
00475         return NPERR_INVALID_INSTANCE_ERROR;
00476     }
00477 
00478     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
00479 
00480     if( p_plugin != NULL )
00481     {
00482         if( p_plugin->i_vlc )
00483         {
00484 #if USE_LIBVLC
00485 #   ifdef XP_WIN
00486             HackStopVout( p_plugin );
00487 #   endif /* XP_WIN */
00488             VLC_CleanUp( p_plugin->i_vlc );
00489             VLC_Destroy( p_plugin->i_vlc );
00490 #endif /* USE_LIBVLC */
00491             p_plugin->i_vlc = 0;
00492         }
00493 
00494         if( p_plugin->psz_target )
00495         {
00496             free( p_plugin->psz_target );
00497             p_plugin->psz_target = NULL;
00498         }
00499 
00500         delete p_plugin;
00501     }
00502 
00503     instance->pdata = NULL;
00504 
00505     return NPERR_NO_ERROR;
00506 }
00507 
00508 NPError NPP_SetWindow( NPP instance, NPWindow* window )
00509 {
00510     vlc_value_t value;
00511 #ifdef XP_MACOSX
00512     vlc_value_t valuex;
00513     vlc_value_t valuey;
00514     vlc_value_t valuew;
00515     vlc_value_t valueh;
00516     vlc_value_t valuet;
00517     vlc_value_t valuel;
00518     vlc_value_t valueb;
00519     vlc_value_t valuer;
00520     vlc_value_t valueportx;
00521     vlc_value_t valueporty;
00522     Rect black_rect;
00523     char * text;
00524 #endif /* XP_MACOSX */
00525 
00526     if( instance == NULL )
00527     {
00528         return NPERR_INVALID_INSTANCE_ERROR;
00529     }
00530 
00531     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
00532 
00533     /* Write the window ID for vlc */
00534 #if USE_LIBVLC
00535 
00536 #ifdef XP_MACOSX
00537     value.i_int = ((NP_Port*) (window->window))->port;
00538     VLC_VariableSet( p_plugin->i_vlc, "drawable", value );
00539 
00540     valueportx.i_int = ((NP_Port*) (window->window))->portx;
00541     valueporty.i_int = ((NP_Port*) (window->window))->porty;
00542     VLC_VariableSet( p_plugin->i_vlc, "drawableportx", valueportx );
00543     VLC_VariableSet( p_plugin->i_vlc, "drawableporty", valueporty );
00544 
00545     valuex.i_int = window->x;
00546     valuey.i_int = window->y;
00547     valuew.i_int = window->width;
00548     valueh.i_int = window->height;
00549     valuet.i_int = window->clipRect.top;
00550     valuel.i_int = window->clipRect.left;
00551     valueb.i_int = window->clipRect.bottom;
00552     valuer.i_int = window->clipRect.right;
00553 
00554     VLC_VariableSet( p_plugin->i_vlc, "drawablet", valuet );
00555     VLC_VariableSet( p_plugin->i_vlc, "drawablel", valuel );
00556     VLC_VariableSet( p_plugin->i_vlc, "drawableb", valueb );
00557     VLC_VariableSet( p_plugin->i_vlc, "drawabler", valuer );
00558     VLC_VariableSet( p_plugin->i_vlc, "drawablex", valuex );
00559     VLC_VariableSet( p_plugin->i_vlc, "drawabley", valuey );
00560     VLC_VariableSet( p_plugin->i_vlc, "drawablew", valuew );
00561     VLC_VariableSet( p_plugin->i_vlc, "drawableh", valueh );
00562 
00563     p_plugin->window = window;
00564 
00565     /* draw the beautiful "No Picture" */
00566 
00567     black_rect.top = valuet.i_int - valuey.i_int;
00568     black_rect.left = valuel.i_int - valuex.i_int;
00569     black_rect.bottom = valueb.i_int - valuey.i_int;
00570     black_rect.right = valuer.i_int - valuex.i_int;
00571 
00572     SetPort( value.i_int );
00573     SetOrigin( valueportx.i_int , valueporty.i_int );
00574     ForeColor(blackColor);
00575     PenMode( patCopy );
00576     PaintRect( &black_rect );
00577 
00578     ForeColor(whiteColor);
00579     text = strdup( WINDOW_TEXT );
00580     MoveTo( valuew.i_int / 2 - 40 , valueh.i_int / 2 );
00581     DrawText( text , 0 , strlen(text) );
00582     free(text);
00583 
00584 #else /* XP_MACOSX */
00585     /* FIXME: this cast sucks */
00586     value.i_int = (int) (ptrdiff_t) (void *) window->window;
00587     VLC_VariableSet( p_plugin->i_vlc, "drawable", value );
00588 #endif /* XP_MACOSX */
00589 
00590 #endif /* USE_LIBVLC */
00591 
00592     /*
00593      * PLUGIN DEVELOPERS:
00594      *  Before setting window to point to the
00595      *  new window, you may wish to compare the new window
00596      *  info to the previous window (if any) to note window
00597      *  size changes, etc.
00598      */
00599 
00600 #ifdef XP_WIN
00601     if( !window || !window->window )
00602     {
00603         /* Window was destroyed. Invalidate everything. */
00604         if( p_plugin->p_npwin )
00605         {
00606 #if !USE_LIBVLC
00607             SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
00608                            (LONG)p_plugin->pf_wndproc );
00609 #endif /* !USE_LIBVLC */
00610             p_plugin->pf_wndproc = NULL;
00611             p_plugin->p_hwnd = NULL;
00612         }
00613 
00614         p_plugin->p_npwin = window;
00615         return NPERR_NO_ERROR;
00616     }
00617 
00618     if( p_plugin->p_npwin )
00619     {
00620         if( p_plugin->p_hwnd == (HWND)window->window )
00621         {
00622             /* Same window, but something may have changed. First we
00623              * update the plugin structure, then we redraw the window */
00624             p_plugin->i_width = window->width;
00625             p_plugin->i_height = window->height;
00626             p_plugin->p_npwin = window;
00627 #if !USE_LIBVLC
00628             InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
00629             UpdateWindow( p_plugin->p_hwnd );
00630 #endif /* !USE_LIBVLC */
00631             return NPERR_NO_ERROR;
00632         }
00633 
00634         /* Window has changed. Destroy the one we have, and go
00635          * on as if it was a real initialization. */
00636 #if !USE_LIBVLC
00637         SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC,
00638                        (LONG)p_plugin->pf_wndproc );
00639 #endif /* !USE_LIBVLC */
00640         p_plugin->pf_wndproc = NULL;
00641         p_plugin->p_hwnd = NULL;
00642     }
00643 
00644 #if !USE_LIBVLC
00645     p_plugin->pf_wndproc = (WNDPROC)SetWindowLong( (HWND)window->window,
00646                                                    GWL_WNDPROC, (LONG)Manage );
00647 #endif /* !USE_LIBVLC */
00648 
00649     p_plugin->p_hwnd = (HWND)window->window;
00650     SetProp( p_plugin->p_hwnd, "w00t", (HANDLE)p_plugin );
00651     InvalidateRect( p_plugin->p_hwnd, NULL, TRUE );
00652     UpdateWindow( p_plugin->p_hwnd );
00653 #endif /* XP_WIN */
00654 
00655     p_plugin->i_width = window->width;
00656     p_plugin->i_height = window->height;
00657     p_plugin->p_npwin = window;
00658 
00659 #ifdef XP_UNIX
00660     p_plugin->window = (Window) window->window;
00661     p_plugin->p_display =
00662         ((NPSetWindowCallbackStruct *)window->ws_info)->display;
00663 
00664     XResizeWindow( p_plugin->p_display, p_plugin->window,
00665                    p_plugin->i_width, p_plugin->i_height );
00666     Widget w = XtWindowToWidget( p_plugin->p_display, p_plugin->window );
00667 
00668     XtAddEventHandler( w, ExposureMask, FALSE,
00669                        (XtEventHandler)Redraw, p_plugin );
00670     XtAddEventHandler( w, StructureNotifyMask, FALSE,
00671                        (XtEventHandler)Resize, p_plugin );
00672     Redraw( w, (XtPointer)p_plugin, NULL );
00673 #endif /* XP_UNIX */
00674 
00675     if( !p_plugin->b_stream )
00676     {
00677         int i_mode = PLAYLIST_APPEND;
00678 
00679         if( p_plugin->b_autoplay )
00680         {
00681             i_mode |= PLAYLIST_GO;
00682         }
00683 
00684         if( p_plugin->psz_target )
00685         {
00686 #if USE_LIBVLC
00687             VLC_AddTarget( p_plugin->i_vlc, p_plugin->psz_target,
00688                            0, 0, PLAYLIST_INSERT, 0 );
00689 #endif
00690             p_plugin->b_stream = VLC_TRUE;
00691         }
00692     }
00693 
00694     return NPERR_NO_ERROR;
00695 }
00696 
00697 NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
00698                        NPBool seekable, uint16 *stype )
00699 {
00700     if( instance == NULL )
00701     {
00702         return NPERR_INVALID_INSTANCE_ERROR;
00703     }
00704 
00705 #if 0
00706     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
00707 #endif
00708 
00709     /* fprintf(stderr, "NPP_NewStream - FILE mode !!\n"); */
00710 
00711     /* We want a *filename* ! */
00712     *stype = NP_ASFILE;
00713 
00714 #if 0
00715     if( !p_plugin->b_stream )
00716     {
00717         p_plugin->psz_target = strdup( stream->url );
00718         p_plugin->b_stream = VLC_TRUE;
00719     }
00720 #endif
00721 
00722     return NPERR_NO_ERROR;
00723 }
00724 
00725 int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
00726                    * mode so we can take any size stream in our
00727                    * write call (since we ignore it) */
00728 
00729 #define SARASS_SIZE (1024*1024)
00730 
00731 int32 NPP_WriteReady( NPP instance, NPStream *stream )
00732 {
00733     VlcPlugin* p_plugin;
00734 
00735     /* fprintf(stderr, "NPP_WriteReady\n"); */
00736 
00737     if (instance != NULL)
00738     {
00739         p_plugin = (VlcPlugin*) instance->pdata;
00740         /* Muahahahahahahaha */
00741         return STREAMBUFSIZE;
00742         /*return SARASS_SIZE;*/
00743     }
00744 
00745     /* Number of bytes ready to accept in NPP_Write() */
00746     return STREAMBUFSIZE;
00747     /*return 0;*/
00748 }
00749 
00750 
00751 int32 NPP_Write( NPP instance, NPStream *stream, int32 offset,
00752                  int32 len, void *buffer )
00753 {
00754     /* fprintf(stderr, "NPP_Write %i\n", (int)len); */
00755 
00756     if( instance != NULL )
00757     {
00758         /*VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata;*/
00759     }
00760 
00761     return len;         /* The number of bytes accepted */
00762 }
00763 
00764 
00765 NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason )
00766 {
00767     if( instance == NULL )
00768     {
00769         return NPERR_INVALID_INSTANCE_ERROR;
00770     }
00771 
00772     return NPERR_NO_ERROR;
00773 }
00774 
00775 
00776 void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
00777 {
00778     if( instance == NULL )
00779     {
00780         return;
00781     }
00782 
00783     /* fprintf(stderr, "NPP_StreamAsFile %s\n", fname); */
00784 
00785 #if USE_LIBVLC
00786     VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata;
00787 
00788     VLC_AddTarget( p_plugin->i_vlc, fname, 0, 0,
00789                    PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
00790 #endif /* USE_LIBVLC */
00791 }
00792 
00793 
00794 void NPP_URLNotify( NPP instance, const char* url,
00795                     NPReason reason, void* notifyData )
00796 {
00797     /***** Insert NPP_URLNotify code here *****\
00798     PluginInstance* p_plugin;
00799     if (instance != NULL)
00800         p_plugin = (PluginInstance*) instance->pdata;
00801     \*********************************************/
00802 }
00803 
00804 
00805 void NPP_Print( NPP instance, NPPrint* printInfo )
00806 {
00807     if( printInfo == NULL )
00808     {
00809         return;
00810     }
00811 
00812     if( instance != NULL )
00813     {
00814         /***** Insert NPP_Print code here *****\
00815         PluginInstance* p_plugin = (PluginInstance*) instance->pdata;
00816         \**************************************/
00817 
00818         if( printInfo->mode == NP_FULL )
00819         {
00820             /*
00821              * PLUGIN DEVELOPERS:
00822              *  If your plugin would like to take over
00823              *  printing completely when it is in full-screen mode,
00824              *  set printInfo->pluginPrinted to TRUE and print your
00825              *  plugin as you see fit.  If your plugin wants Netscape
00826              *  to handle printing in this case, set
00827              *  printInfo->pluginPrinted to FALSE (the default) and
00828              *  do nothing.  If you do want to handle printing
00829              *  yourself, printOne is true if the print button
00830              *  (as opposed to the print menu) was clicked.
00831              *  On the Macintosh, platformPrint is a THPrint; on
00832              *  Windows, platformPrint is a structure
00833              *  (defined in npapi.h) containing the printer name, port,
00834              *  etc.
00835              */
00836 
00837             /***** Insert NPP_Print code here *****\
00838             void* platformPrint =
00839                 printInfo->print.fullPrint.platformPrint;
00840             NPBool printOne =
00841                 printInfo->print.fullPrint.printOne;
00842             \**************************************/
00843 
00844             /* Do the default*/
00845             printInfo->print.fullPrint.pluginPrinted = FALSE;
00846         }
00847         else
00848         {
00849             /* If not fullscreen, we must be embedded */
00850             /*
00851              * PLUGIN DEVELOPERS:
00852              *  If your plugin is embedded, or is full-screen
00853              *  but you returned false in pluginPrinted above, NPP_Print
00854              *  will be called with mode == NP_EMBED.  The NPWindow
00855              *  in the printInfo gives the location and dimensions of
00856              *  the embedded plugin on the printed page.  On the
00857              *  Macintosh, platformPrint is the printer port; on
00858              *  Windows, platformPrint is the handle to the printing
00859              *  device context.
00860              */
00861 
00862             /***** Insert NPP_Print code here *****\
00863             NPWindow* printWindow =
00864                 &(printInfo->print.embedPrint.window);
00865             void* platformPrint =
00866                 printInfo->print.embedPrint.platformPrint;
00867             \**************************************/
00868         }
00869     }
00870 }
00871 
00872 /******************************************************************************
00873  * Windows-only methods
00874  *****************************************************************************/
00875 #if defined(XP_WIN) && !USE_LIBVLC
00876 LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar )
00877 {
00878     VlcPlugin* p_plugin = (VlcPlugin*) GetProp( p_hwnd, "w00t" );
00879 
00880     switch( i_msg )
00881     {
00882         case WM_PAINT:
00883         {
00884             PAINTSTRUCT paintstruct;
00885             HDC hdc;
00886             RECT rect;
00887 
00888             hdc = BeginPaint( p_hwnd, &paintstruct );
00889 
00890             GetClientRect( p_hwnd, &rect );
00891             FillRect( hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH) );
00892             TextOut( hdc, p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
00893                      WINDOW_TEXT, strlen(WINDOW_TEXT) );
00894 
00895             EndPaint( p_hwnd, &paintstruct );
00896             break;
00897         }
00898         default:
00899             p_plugin->pf_wndproc( p_hwnd, i_msg, wpar, lpar );
00900             break;
00901     }
00902     return 0;
00903 }
00904 #endif /* XP_WIN */
00905 
00906 /******************************************************************************
00907  * UNIX-only methods
00908  *****************************************************************************/
00909 #ifdef XP_UNIX
00910 static void Redraw( Widget w, XtPointer closure, XEvent *event )
00911 {
00912     VlcPlugin* p_plugin = (VlcPlugin*)closure;
00913     GC gc;
00914     XGCValues gcv;
00915 
00916     gcv.foreground = BlackPixel( p_plugin->p_display, 0 );
00917     gc = XCreateGC( p_plugin->p_display, p_plugin->window, GCForeground, &gcv );
00918 
00919     XFillRectangle( p_plugin->p_display, p_plugin->window, gc,
00920                     0, 0, p_plugin->i_width, p_plugin->i_height );
00921 
00922     gcv.foreground = WhitePixel( p_plugin->p_display, 0 );
00923     XChangeGC( p_plugin->p_display, gc, GCForeground, &gcv );
00924 
00925     XDrawString( p_plugin->p_display, p_plugin->window, gc,
00926                  p_plugin->i_width / 2 - 40, p_plugin->i_height / 2,
00927                  WINDOW_TEXT, strlen(WINDOW_TEXT) );
00928 
00929     XFreeGC( p_plugin->p_display, gc );
00930 }
00931 
00932 static void Resize ( Widget w, XtPointer closure, XEvent *event )
00933 {
00934     VlcPlugin* p_plugin = (VlcPlugin*)closure;
00935     int i_ret;
00936     Window root_return, parent_return, * children_return;
00937     Window base_window;
00938     unsigned int i_nchildren;
00939 
00940 #ifdef X11_RESIZE_DEBUG
00941     XWindowAttributes attr;
00942 
00943     if( event && event->type == ConfigureNotify )
00944     {
00945         fprintf( stderr, "vlcshell::Resize() ConfigureNotify %d x %d, "
00946                  "send_event ? %s\n", event->xconfigure.width,
00947                  event->xconfigure.height,
00948                  event->xconfigure.send_event ? "TRUE" : "FALSE" );
00949     }
00950 #endif /* X11_RESIZE_DEBUG */
00951 
00952     if( p_plugin->i_height == i_previous_height &&
00953         p_plugin->i_width == i_previous_width )
00954     {
00955         return;
00956     }
00957     i_previous_height = p_plugin->i_height;
00958     i_previous_width  = p_plugin->i_width;
00959 
00960 
00961     i_ret = XResizeWindow( p_plugin->p_display, p_plugin->window,
00962             p_plugin->i_width, p_plugin->i_height );
00963 
00964 #ifdef X11_RESIZE_DEBUG
00965     fprintf( stderr,
00966              "vlcshell::Resize() XResizeWindow(owner) returned %d\n", i_ret );
00967 
00968     XGetWindowAttributes ( p_plugin->p_display, p_plugin->window, &attr );
00969 
00970     /* X is asynchronous, so the current size reported here is not
00971        necessarily the requested size as the Resize request may not
00972        yet have been handled by the plugin host */
00973     fprintf( stderr, "vlcshell::Resize() current (owner) size %d x %d\n",
00974              attr.width, attr.height );
00975 #endif /* X11_RESIZE_DEBUG */
00976 
00977     XQueryTree( p_plugin->p_display, p_plugin->window,
00978                 &root_return, &parent_return, &children_return,
00979                 &i_nchildren );
00980 
00981     if( i_nchildren > 0 )
00982     {
00983         /* XXX: Make assumptions related to the window parenting structure in
00984            vlc/modules/video_output/x11/xcommon.c */
00985         base_window = children_return[i_nchildren - 1];
00986 
00987 #ifdef X11_RESIZE_DEBUG
00988         fprintf( stderr, "vlcshell::Resize() got %d children\n", i_nchildren );
00989         fprintf( stderr, "vlcshell::Resize() got base_window %p\n",
00990                  base_window );
00991 #endif /* X11_RESIZE_DEBUG */
00992 
00993         i_ret = XResizeWindow( p_plugin->p_display, base_window,
00994                 p_plugin->i_width, p_plugin->i_height );
00995 
00996 #ifdef X11_RESIZE_DEBUG
00997         fprintf( stderr,
00998                  "vlcshell::Resize() XResizeWindow(base) returned %d\n",
00999                  i_ret );
01000 
01001         XGetWindowAttributes( p_plugin->p_display, base_window, &attr );
01002 
01003         fprintf( stderr, "vlcshell::Resize() new size %d x %d\n",
01004                  attr.width, attr.height );
01005 #endif /* X11_RESIZE_DEBUG */
01006     }
01007 }
01008 
01009 #endif /* XP_UNIX */
01010 

Generated on Tue Dec 20 10:14:59 2005 for vlc-0.8.4a by  doxygen 1.4.2