vlcshell.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:30k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * vlcshell.cpp: a VLC plugin for Mozilla
  3.  *****************************************************************************
  4.  * Copyright (C) 2002-2009 the VideoLAN team
  5.  * $Id: 4399b5470a163d868fac691099016f3ac3eaf209 $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  8.  *          Jean-Paul Saman <jpsaman@videolan.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include "config.h"
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <stdlib.h>
  31. /* Mozilla stuff */
  32. #ifdef HAVE_MOZILLA_CONFIG_H
  33. #   include <mozilla-config.h>
  34. #endif
  35. /* This is from mozilla java, do we really need it? */
  36. #if 0
  37. #include <jri.h>
  38. #endif
  39. #include "vlcplugin.h"
  40. #include "vlcshell.h"
  41. /* Enable/disable debugging printf's for X11 resizing */
  42. #undef X11_RESIZE_DEBUG
  43. #define WINDOW_TEXT "Waiting for video"
  44. /*****************************************************************************
  45.  * Unix-only declarations
  46. ******************************************************************************/
  47. #if defined(XP_UNIX)
  48. static void Redraw( Widget w, XtPointer closure, XEvent *event );
  49. static void ControlHandler( Widget w, XtPointer closure, XEvent *event );
  50. static void Resize( Widget w, XtPointer closure, XEvent *event );
  51. #endif
  52. /*****************************************************************************
  53.  * MacOS-only declarations
  54. ******************************************************************************/
  55. #ifdef XP_MACOSX
  56. #endif
  57. /*****************************************************************************
  58.  * Windows-only declarations
  59.  *****************************************************************************/
  60. #ifdef XP_WIN
  61. static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar );
  62. #endif
  63. /******************************************************************************
  64.  * UNIX-only API calls
  65.  *****************************************************************************/
  66. char * NPP_GetMIMEDescription( void )
  67. {
  68.     static char mimetype[] = PLUGIN_MIMETYPES;
  69.     return mimetype;
  70. }
  71. NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value )
  72. {
  73.     static char psz_name[] = PLUGIN_NAME;
  74.     static char psz_desc[1000];
  75.     /* plugin class variables */
  76.     switch( variable )
  77.     {
  78.         case NPPVpluginNameString:
  79.             *((char **)value) = psz_name;
  80.             return NPERR_NO_ERROR;
  81.         case NPPVpluginDescriptionString:
  82.             snprintf( psz_desc, sizeof(psz_desc), PLUGIN_DESCRIPTION,
  83.                       libvlc_get_version() );
  84.             *((char **)value) = psz_desc;
  85.             return NPERR_NO_ERROR;
  86.         default:
  87.             /* move on to instance variables ... */
  88.             ;
  89.     }
  90.     if( instance == NULL )
  91.     {
  92.         return NPERR_INVALID_INSTANCE_ERROR;
  93.     }
  94.     /* plugin instance variables */
  95.     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
  96.     if( NULL == p_plugin )
  97.     {
  98.         // plugin has not been initialized yet !
  99.         return NPERR_INVALID_INSTANCE_ERROR;
  100.     }
  101.     switch( variable )
  102.     {
  103.         case NPPVpluginScriptableNPObject:
  104.         {
  105.             /* retrieve plugin root class */
  106.             NPClass *scriptClass = p_plugin->getScriptClass();
  107.             if( scriptClass )
  108.             {
  109.                 /* create an instance and return it */
  110.                 *(NPObject**)value = NPN_CreateObject(instance, scriptClass);
  111.                 return NPERR_NO_ERROR;
  112.             }
  113.             break;
  114.         }
  115.         default:
  116.             ;
  117.     }
  118.     return NPERR_GENERIC_ERROR;
  119. }
  120. /*
  121.  * there is some confusion in gecko headers regarding definition of this API
  122.  * NPPVariable is wrongly defined as NPNVariable, which sounds incorrect.
  123.  */
  124. NPError NPP_SetValue( NPP instance, NPNVariable variable, void *value )
  125. {
  126.     return NPERR_GENERIC_ERROR;
  127. }
  128. /******************************************************************************
  129.  * Mac-only API calls
  130.  *****************************************************************************/
  131. #ifdef XP_MACOSX
  132. int16 NPP_HandleEvent( NPP instance, void * event )
  133. {
  134.     static UInt32 lastMouseUp = 0;
  135.     libvlc_exception_t ex;
  136.     libvlc_exception_init(&ex);
  137.     if( instance == NULL )
  138.     {
  139.         return false;
  140.     }
  141.     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
  142.     if( p_plugin == NULL )
  143.     {
  144.         return false;
  145.     }
  146.     EventRecord *myEvent = (EventRecord*)event;
  147.     switch( myEvent->what )
  148.     {
  149.         case nullEvent:
  150.             return true;
  151.         case mouseDown:
  152.         {
  153.             if( (myEvent->when - lastMouseUp) < GetDblTime() )
  154.             {
  155.                 /* double click */
  156.                 p_plugin->toggle_fullscreen(&ex);
  157.                 libvlc_exception_clear(&ex);
  158.             }
  159.             return true;
  160.         }
  161.         case mouseUp:
  162.             lastMouseUp = myEvent->when;
  163.             return true;
  164.         case keyUp:
  165.         case keyDown:
  166.         case autoKey:
  167.             return true;
  168.         case updateEvt:
  169.         {
  170.             const NPWindow& npwindow = p_plugin->getWindow();
  171.             if( npwindow.window )
  172.             {
  173.                 bool hasVout = false;
  174.                 if( p_plugin->playlist_isplaying(&ex) )
  175.                 {
  176.                     hasVout = p_plugin->player_has_vout(NULL);
  177.                 }
  178.                 libvlc_exception_clear(&ex);
  179.                 if( ! hasVout )
  180.                 {
  181.                     /* draw the beautiful "No Picture" */
  182.                     ForeColor(blackColor);
  183.                     PenMode( patCopy );
  184.                     /* seems that firefox forgets to set the following
  185.                      * on occasion (reload) */
  186.                     SetOrigin(((NP_Port *)npwindow.window)->portx,
  187.                               ((NP_Port *)npwindow.window)->porty);
  188.                     Rect rect;
  189.                     rect.left = 0;
  190.                     rect.top = 0;
  191.                     rect.right = npwindow.width;
  192.                     rect.bottom = npwindow.height;
  193.                     PaintRect( &rect );
  194.                     ForeColor(whiteColor);
  195.                     MoveTo( (npwindow.width-80)/ 2  , npwindow.height / 2 );
  196.                     DrawText( WINDOW_TEXT , 0 , strlen(WINDOW_TEXT) );
  197.                 }
  198.             }
  199.             return true;
  200.         }
  201.         case activateEvt:
  202.             return false;
  203.         case NPEventType_GetFocusEvent:
  204.         case NPEventType_LoseFocusEvent:
  205.             return true;
  206.         case NPEventType_AdjustCursorEvent:
  207.             return false;
  208.         case NPEventType_MenuCommandEvent:
  209.             return false;
  210.         case NPEventType_ClippingChangedEvent:
  211.             return false;
  212.         case NPEventType_ScrollingBeginsEvent:
  213.             return true;
  214.         case NPEventType_ScrollingEndsEvent:
  215.             return true;
  216.         default:
  217.             ;
  218.     }
  219.     return false;
  220. }
  221. #endif /* XP_MACOSX */
  222. /******************************************************************************
  223.  * General Plug-in Calls
  224.  *****************************************************************************/
  225. NPError NPP_Initialize( void )
  226. {
  227.     return NPERR_NO_ERROR;
  228. }
  229. jref NPP_GetJavaClass( void )
  230. {
  231.     return NULL;
  232. }
  233. void NPP_Shutdown( void )
  234. {
  235.     ;
  236. }
  237. NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
  238.                  char* argn[], char* argv[], NPSavedData* saved )
  239. {
  240.     NPError status;
  241.     if( instance == NULL )
  242.     {
  243.         return NPERR_INVALID_INSTANCE_ERROR;
  244.     }
  245.     VlcPlugin * p_plugin = new VlcPlugin( instance, mode );
  246.     if( NULL == p_plugin )
  247.     {
  248.         return NPERR_OUT_OF_MEMORY_ERROR;
  249.     }
  250.     status = p_plugin->init(argc, argn, argv);
  251.     if( NPERR_NO_ERROR == status )
  252.     {
  253.         instance->pdata = reinterpret_cast<void*>(p_plugin);
  254. #if 0
  255.         NPN_SetValue(instance, NPPVpluginWindowBool, (void *)false);
  256.         NPN_SetValue(instance, NPPVpluginTransparentBool, (void *)false);
  257. #endif
  258.     }
  259.     else
  260.     {
  261.         delete p_plugin;
  262.     }
  263.     return status;
  264. }
  265. NPError NPP_Destroy( NPP instance, NPSavedData** save )
  266. {
  267.     if( NULL == instance )
  268.         return NPERR_INVALID_INSTANCE_ERROR;
  269.     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
  270.     if( NULL == p_plugin )
  271.         return NPERR_NO_ERROR;
  272.     instance->pdata = NULL;
  273. #if XP_WIN
  274.     HWND win = (HWND)p_plugin->getWindow().window;
  275.     WNDPROC winproc = p_plugin->getWindowProc();
  276.     if( winproc )
  277.     {
  278.         /* reset WNDPROC */
  279.         SetWindowLong( win, GWL_WNDPROC, (LONG)winproc );
  280.     }
  281. #endif
  282.     libvlc_exception_t ex;
  283.     libvlc_exception_init(&ex);
  284.     int val = p_plugin->playlist_isplaying(&ex);
  285.     libvlc_exception_clear(&ex);
  286.     if(val)
  287.     {
  288.         p_plugin->playlist_stop(&ex);
  289.         libvlc_exception_clear(&ex);
  290.     }
  291.     delete p_plugin;
  292.     return NPERR_NO_ERROR;
  293. }
  294. NPError NPP_SetWindow( NPP instance, NPWindow* window )
  295. {
  296. #if defined(XP_UNIX)
  297.     Window control;
  298.     unsigned int i_control_height = 0, i_control_width = 0;
  299. #endif
  300.     if( ! instance )
  301.     {
  302.         return NPERR_INVALID_INSTANCE_ERROR;
  303.     }
  304.     /* NPP_SetWindow may be called before NPP_New (Opera) */
  305.     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
  306.     if( NULL == p_plugin )
  307.     {
  308.         /* we should probably show a splash screen here */
  309.         return NPERR_NO_ERROR;
  310.     }
  311. #if defined(XP_UNIX)
  312.     control = p_plugin->getControlWindow();
  313. #endif
  314.     libvlc_exception_t ex;
  315.     libvlc_exception_init(&ex);
  316.     libvlc_instance_t *p_vlc = p_plugin->getVLC();
  317.     /*
  318.      * PLUGIN DEVELOPERS:
  319.      *  Before setting window to point to the
  320.      *  new window, you may wish to compare the new window
  321.      *  info to the previous window (if any) to note window
  322.      *  size changes, etc.
  323.      */
  324.     /* retrieve current window */
  325.     NPWindow& curwin = p_plugin->getWindow();
  326. #ifdef XP_MACOSX
  327.     if( window && window->window )
  328.     {
  329.         /* check if plugin has a new parent window */
  330.         CGrafPtr drawable = (((NP_Port*) (window->window))->port);
  331.         if( !curwin.window || drawable != (((NP_Port*) (curwin.window))->port) )
  332.         {
  333.             /* set/change parent window */
  334.             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, &ex);
  335.             libvlc_exception_clear(&ex);
  336.         }
  337.         /* as MacOS X video output is windowless, set viewport */
  338.         libvlc_rectangle_t view, clip;
  339.         /*
  340.         ** browser sets port origin to top-left location of plugin
  341.         ** relative to GrafPort window origin is set relative to document,
  342.         ** which of little use for drawing
  343.         */
  344.         view.top     = ((NP_Port*) (window->window))->porty;
  345.         view.left    = ((NP_Port*) (window->window))->portx;
  346.         view.bottom  = window->height+view.top;
  347.         view.right   = window->width+view.left;
  348.         /* clipRect coordinates are also relative to GrafPort */
  349.         clip.top     = window->clipRect.top;
  350.         clip.left    = window->clipRect.left;
  351.         clip.bottom  = window->clipRect.bottom;
  352.         clip.right   = window->clipRect.right;
  353.         libvlc_video_set_viewport(p_vlc, p_plugin->getMD(&ex), &view, &clip, &ex);
  354.         libvlc_exception_clear(&ex);
  355.         /* remember new window */
  356.         p_plugin->setWindow(*window);
  357.     }
  358.     else if( curwin.window )
  359.     {
  360.         /* change/set parent */
  361.         libvlc_video_set_parent(p_vlc, 0, &ex);
  362.         libvlc_exception_clear(&ex);
  363.         curwin.window = NULL;
  364.     }
  365. #endif /* XP_MACOSX */
  366. #ifdef XP_WIN
  367.     if( window && window->window )
  368.     {
  369.         /* check if plugin has a new parent window */
  370.         HWND drawable = (HWND) (window->window);
  371.         if( !curwin.window || drawable != curwin.window )
  372.         {
  373.             /* reset previous window settings */
  374.             HWND oldwin = (HWND)p_plugin->getWindow().window;
  375.             WNDPROC oldproc = p_plugin->getWindowProc();
  376.             if( oldproc )
  377.             {
  378.                 /* reset WNDPROC */
  379.                 SetWindowLong( oldwin, GWL_WNDPROC, (LONG)oldproc );
  380.             }
  381.             /* attach our plugin object */
  382.             SetWindowLongPtr((HWND)drawable, GWLP_USERDATA,
  383.                              reinterpret_cast<LONG_PTR>(p_plugin));
  384.             /* install our WNDPROC */
  385.             p_plugin->setWindowProc( (WNDPROC)SetWindowLong( drawable,
  386.                                              GWL_WNDPROC, (LONG)Manage ) );
  387.             /* change window style to our liking */
  388.             LONG style = GetWindowLong((HWND)drawable, GWL_STYLE);
  389.             style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
  390.             SetWindowLong((HWND)drawable, GWL_STYLE, style);
  391.             /* change/set parent */
  392.             libvlc_video_set_parent(p_vlc, (libvlc_drawable_t)drawable, &ex);
  393.             libvlc_exception_clear(&ex);
  394.             /* remember new window */
  395.             p_plugin->setWindow(*window);
  396.             /* Redraw window */
  397.             InvalidateRect( (HWND)drawable, NULL, TRUE );
  398.             UpdateWindow( (HWND)drawable );
  399.         }
  400.     }
  401.     else if( curwin.window )
  402.     {
  403.         /* reset WNDPROC */
  404.         HWND oldwin = (HWND)curwin.window;
  405.         SetWindowLong( oldwin, GWL_WNDPROC, (LONG)(p_plugin->getWindowProc()) );
  406.         p_plugin->setWindowProc(NULL);
  407.         /* change/set parent */
  408.         libvlc_video_set_parent(p_vlc, 0, &ex);
  409.         libvlc_exception_clear(&ex);
  410.         curwin.window = NULL;
  411.     }
  412. #endif /* XP_WIN */
  413. #if defined(XP_UNIX)
  414.     /* default to hidden toolbar, shown at the end of this method if asked *
  415.      * developers note : getToolbarSize need to wait the end of this method
  416.      */
  417.     i_control_height = 0;
  418.     i_control_width = window->width;
  419.     if( window && window->window )
  420.     {
  421.         Window  parent  = (Window) window->window;
  422.         if( !curwin.window || (parent != (Window)curwin.window) )
  423.         {
  424.             Display *p_display = ( (NPSetWindowCallbackStruct *)
  425.                                    window->ws_info )->display;
  426.             XResizeWindow( p_display, parent, window->width, window->height );
  427.             int i_blackColor = BlackPixel(p_display, DefaultScreen(p_display));
  428.             /* create windows */
  429.             Window video = XCreateSimpleWindow( p_display, parent, 0, 0,
  430.                            window->width, window->height - i_control_height,
  431.                            0, i_blackColor, i_blackColor );
  432.             Window controls = (Window) NULL;
  433.             controls = XCreateSimpleWindow( p_display, parent,
  434.                             0, window->height - i_control_height-1,
  435.                             window->width, i_control_height-1,
  436.                             0, i_blackColor, i_blackColor );
  437.             XMapWindow( p_display, parent );
  438.             XMapWindow( p_display, video );
  439.             if( controls ) { XMapWindow( p_display, controls ); }
  440.             XFlush(p_display);
  441.             /* bind events */
  442.             Widget w = XtWindowToWidget( p_display, parent );
  443.             XtAddEventHandler( w, ExposureMask, FALSE,
  444.                                (XtEventHandler)Redraw, p_plugin );
  445.             XtAddEventHandler( w, StructureNotifyMask, FALSE,
  446.                                (XtEventHandler)Resize, p_plugin );
  447.             XtAddEventHandler( w, ButtonReleaseMask, FALSE,
  448.                                (XtEventHandler)ControlHandler, p_plugin );
  449.             /* set/change parent window */
  450.             libvlc_video_set_parent( p_vlc, (libvlc_drawable_t) video, &ex );
  451.             libvlc_exception_clear(&ex);
  452.             /* remember window */
  453.             p_plugin->setWindow( *window );
  454.             p_plugin->setVideoWindow( video );
  455.             if( controls )
  456.             {
  457.                 p_plugin->setControlWindow( controls );
  458.             }
  459.             Redraw( w, (XtPointer)p_plugin, NULL );
  460.             /* now display toolbar if asked through parameters */
  461.             if( p_plugin->b_toolbar )
  462.             {
  463.                 p_plugin->showToolbar();
  464.             }
  465.         }
  466.     }
  467.     else if( curwin.window )
  468.     {
  469.         /* change/set parent */
  470.         libvlc_video_set_parent(p_vlc, 0, &ex);
  471.         libvlc_exception_clear(&ex);
  472.         curwin.window = NULL;
  473.     }
  474. #endif /* XP_UNIX */
  475.     if( !p_plugin->b_stream )
  476.     {
  477.         if( p_plugin->psz_target )
  478.         {
  479.             if( p_plugin->playlist_add( p_plugin->psz_target, NULL ) != -1 )
  480.             {
  481.                 if( p_plugin->b_autoplay )
  482.                 {
  483.                     p_plugin->playlist_play(NULL);
  484.                 }
  485.             }
  486.             p_plugin->b_stream = true;
  487.         }
  488.     }
  489.     return NPERR_NO_ERROR;
  490. }
  491. NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream *stream,
  492.                        NPBool seekable, uint16 *stype )
  493. {
  494.     if( NULL == instance  )
  495.     {
  496.         return NPERR_INVALID_INSTANCE_ERROR;
  497.     }
  498.     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(instance->pdata);
  499.     if( NULL == p_plugin )
  500.     {
  501.         return NPERR_INVALID_INSTANCE_ERROR;
  502.     }
  503.    /*
  504.    ** Firefox/Mozilla may decide to open a stream from the URL specified
  505.    ** in the SRC parameter of the EMBED tag and pass it to us
  506.    **
  507.    ** since VLC will open the SRC URL as well, we're not interested in
  508.    ** that stream. Otherwise, we'll take it and queue it up in the playlist
  509.    */
  510.     if( !p_plugin->psz_target || strcmp(stream->url, p_plugin->psz_target) )
  511.     {
  512.         /* TODO: use pipes !!!! */
  513.         *stype = NP_ASFILEONLY;
  514.         return NPERR_NO_ERROR;
  515.     }
  516.     return NPERR_GENERIC_ERROR;
  517. }
  518. int32 NPP_WriteReady( NPP instance, NPStream *stream )
  519. {
  520.     /* TODO */
  521.     return 8*1024;
  522. }
  523. int32 NPP_Write( NPP instance, NPStream *stream, int32 offset,
  524.                  int32 len, void *buffer )
  525. {
  526.     /* TODO */
  527.     return len;
  528. }
  529. NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason )
  530. {
  531.     if( instance == NULL )
  532.     {
  533.         return NPERR_INVALID_INSTANCE_ERROR;
  534.     }
  535.     return NPERR_NO_ERROR;
  536. }
  537. void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname )
  538. {
  539.     if( instance == NULL )
  540.     {
  541.         return;
  542.     }
  543.     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(instance->pdata);
  544.     if( NULL == p_plugin )
  545.     {
  546.         return;
  547.     }
  548.     if( p_plugin->playlist_add( stream->url, NULL ) != -1 )
  549.     {
  550.         if( p_plugin->b_autoplay )
  551.         {
  552.             p_plugin->playlist_play(NULL);
  553.         }
  554.     }
  555. }
  556. void NPP_URLNotify( NPP instance, const char* url,
  557.                     NPReason reason, void* notifyData )
  558. {
  559.     /***** Insert NPP_URLNotify code here *****
  560.     PluginInstance* p_plugin;
  561.     if (instance != NULL)
  562.         p_plugin = (PluginInstance*) instance->pdata;
  563.     *********************************************/
  564. }
  565. void NPP_Print( NPP instance, NPPrint* printInfo )
  566. {
  567.     if( printInfo == NULL )
  568.     {
  569.         return;
  570.     }
  571.     if( instance != NULL )
  572.     {
  573.         /***** Insert NPP_Print code here *****
  574.         PluginInstance* p_plugin = (PluginInstance*) instance->pdata;
  575.         **************************************/
  576.         if( printInfo->mode == NP_FULL )
  577.         {
  578.             /*
  579.              * PLUGIN DEVELOPERS:
  580.              *  If your plugin would like to take over
  581.              *  printing completely when it is in full-screen mode,
  582.              *  set printInfo->pluginPrinted to TRUE and print your
  583.              *  plugin as you see fit.  If your plugin wants Netscape
  584.              *  to handle printing in this case, set
  585.              *  printInfo->pluginPrinted to FALSE (the default) and
  586.              *  do nothing.  If you do want to handle printing
  587.              *  yourself, printOne is true if the print button
  588.              *  (as opposed to the print menu) was clicked.
  589.              *  On the Macintosh, platformPrint is a THPrint; on
  590.              *  Windows, platformPrint is a structure
  591.              *  (defined in npapi.h) containing the printer name, port,
  592.              *  etc.
  593.              */
  594.             /***** Insert NPP_Print code here *****
  595.             void* platformPrint =
  596.                 printInfo->print.fullPrint.platformPrint;
  597.             NPBool printOne =
  598.                 printInfo->print.fullPrint.printOne;
  599.             **************************************/
  600.             /* Do the default*/
  601.             printInfo->print.fullPrint.pluginPrinted = FALSE;
  602.         }
  603.         else
  604.         {
  605.             /* If not fullscreen, we must be embedded */
  606.             /*
  607.              * PLUGIN DEVELOPERS:
  608.              *  If your plugin is embedded, or is full-screen
  609.              *  but you returned false in pluginPrinted above, NPP_Print
  610.              *  will be called with mode == NP_EMBED.  The NPWindow
  611.              *  in the printInfo gives the location and dimensions of
  612.              *  the embedded plugin on the printed page.  On the
  613.              *  Macintosh, platformPrint is the printer port; on
  614.              *  Windows, platformPrint is the handle to the printing
  615.              *  device context.
  616.              */
  617.             /***** Insert NPP_Print code here *****
  618.             NPWindow* printWindow =
  619.                 &(printInfo->print.embedPrint.window);
  620.             void* platformPrint =
  621.                 printInfo->print.embedPrint.platformPrint;
  622.             **************************************/
  623.         }
  624.     }
  625. }
  626. /******************************************************************************
  627.  * Windows-only methods
  628.  *****************************************************************************/
  629. #if XP_WIN
  630. static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar )
  631. {
  632.     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(GetWindowLongPtr(p_hwnd, GWLP_USERDATA));
  633.     switch( i_msg )
  634.     {
  635.         case WM_ERASEBKGND:
  636.             return 1L;
  637.         case WM_PAINT:
  638.         {
  639.             PAINTSTRUCT paintstruct;
  640.             HDC hdc;
  641.             RECT rect;
  642.             hdc = BeginPaint( p_hwnd, &paintstruct );
  643.             GetClientRect( p_hwnd, &rect );
  644.             FillRect( hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH) );
  645.             SetTextColor(hdc, RGB(255, 255, 255));
  646.             SetBkColor(hdc, RGB(0, 0, 0));
  647.             DrawText( hdc, WINDOW_TEXT, strlen(WINDOW_TEXT), &rect,
  648.                       DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  649.             EndPaint( p_hwnd, &paintstruct );
  650.             return 0L;
  651.         }
  652.         default:
  653.             /* delegate to default handler */
  654.             return CallWindowProc( p_plugin->getWindowProc(), p_hwnd,
  655.                                    i_msg, wpar, lpar );
  656.     }
  657. }
  658. #endif /* XP_WIN */
  659. /******************************************************************************
  660.  * UNIX-only methods
  661.  *****************************************************************************/
  662. #if defined(XP_UNIX)
  663. static void Redraw( Widget w, XtPointer closure, XEvent *event )
  664. {
  665.     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
  666.     Window control = p_plugin->getControlWindow();
  667.     const NPWindow& window = p_plugin->getWindow();
  668.     GC gc;
  669.     XGCValues gcv;
  670.     unsigned int i_control_height, i_control_width;
  671.     if( p_plugin->b_toolbar )
  672.         p_plugin->getToolbarSize( &i_control_width, &i_control_height );
  673.     else
  674.         i_control_height = i_control_width = 0;
  675.     Window video = p_plugin->getVideoWindow();
  676.     Display *p_display = ((NPSetWindowCallbackStruct *)window.ws_info)->display;
  677.     gcv.foreground = BlackPixel( p_display, 0 );
  678.     gc = XCreateGC( p_display, video, GCForeground, &gcv );
  679.     XFillRectangle( p_display, video, gc,
  680.                     0, 0, window.width, window.height - i_control_height);
  681.     gcv.foreground = WhitePixel( p_display, 0 );
  682.     XChangeGC( p_display, gc, GCForeground, &gcv );
  683.     XDrawString( p_display, video, gc,
  684.                  window.width / 2 - 40, (window.height - i_control_height) / 2,
  685.                  WINDOW_TEXT, strlen(WINDOW_TEXT) );
  686.     XFreeGC( p_display, gc );
  687.     p_plugin->redrawToolbar();
  688. }
  689. static void ControlHandler( Widget w, XtPointer closure, XEvent *event )
  690. {
  691.     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
  692.     const NPWindow& window = p_plugin->getWindow();
  693.     int i_height = window.height;
  694.     int i_width = window.width;
  695.     int i_xPos = event->xbutton.x;
  696.     int i_yPos = event->xbutton.y;
  697.     if( p_plugin && p_plugin->b_toolbar )
  698.     {
  699.         int i_playing;
  700.         libvlc_exception_t ex;
  701.         libvlc_exception_init( &ex );
  702.         libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
  703.         libvlc_exception_clear( &ex );
  704.         i_playing = p_plugin->playlist_isplaying( &ex );
  705.         libvlc_exception_clear( &ex );
  706.         vlc_toolbar_clicked_t clicked;
  707.         clicked = p_plugin->getToolbarButtonClicked( i_xPos, i_yPos );
  708.         switch( clicked )
  709.         {
  710.             case clicked_Play:
  711.             case clicked_Pause:
  712.             {
  713.                 if( i_playing == 1 )
  714.                     p_plugin->playlist_pause( &ex );
  715.                 else
  716.                     p_plugin->playlist_play( &ex );
  717.                 libvlc_exception_clear( &ex );
  718.             }
  719.             break;
  720.             case clicked_Stop:
  721.             {
  722.                 p_plugin->playlist_stop(&ex);
  723.                 libvlc_exception_clear( &ex );
  724.             }
  725.             break;
  726.             case clicked_Fullscreen:
  727.             {
  728.                 p_plugin->set_fullscreen( 1, &ex );
  729.                 libvlc_exception_clear( &ex );
  730.             }
  731.             break;
  732.             case clicked_Mute:
  733.             case clicked_Unmute:
  734.             {
  735.                 libvlc_audio_toggle_mute( p_plugin->getVLC(), &ex );
  736.                 libvlc_exception_clear( &ex );
  737.             }
  738.             break;
  739.             case clicked_timeline:
  740.             {
  741.                 /* if a movie is loaded */
  742.                 if( p_md )
  743.                 {
  744.                     int64_t f_length;
  745.                     f_length = libvlc_media_player_get_length( p_md, &ex ) / 100;
  746.                     libvlc_exception_clear( &ex );
  747.                     f_length = (float)f_length *
  748.                             ( ((float)i_xPos-4.0 ) / ( ((float)i_width-8.0)/100) );
  749.                     libvlc_media_player_set_time( p_md, f_length, &ex );
  750.                     libvlc_exception_clear( &ex );
  751.                 }
  752.             }
  753.             break;
  754.             case clicked_Time:
  755.             {
  756.                 /* Not implemented yet*/
  757.             }
  758.             break;
  759.             default: /* button_Unknown */
  760.             break;
  761.         }
  762.     }
  763.     Redraw( w, closure, event );
  764. }
  765. static void Resize ( Widget w, XtPointer closure, XEvent *event )
  766. {
  767.     VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure);
  768.     Window control = p_plugin->getControlWindow();
  769.     const NPWindow& window = p_plugin->getWindow();
  770.     Window  drawable   = p_plugin->getVideoWindow();
  771.     Display *p_display = ((NPSetWindowCallbackStruct *)window.ws_info)->display;
  772.     int i_ret;
  773.     Window root_return, parent_return, * children_return;
  774.     Window base_window;
  775.     unsigned int i_nchildren;
  776.     unsigned int i_control_height, i_control_width;
  777.     if( p_plugin->b_toolbar )
  778.     {
  779.         p_plugin->getToolbarSize( &i_control_width, &i_control_height );
  780.     }
  781.     else
  782.     {
  783.         i_control_height = i_control_width = 0;
  784.     }
  785. #ifdef X11_RESIZE_DEBUG
  786.     XWindowAttributes attr;
  787.     if( event && event->type == ConfigureNotify )
  788.     {
  789.         fprintf( stderr, "vlcshell::Resize() ConfigureNotify %d x %d, "
  790.                  "send_event ? %sn", event->xconfigure.width,
  791.                  event->xconfigure.height,
  792.                  event->xconfigure.send_event ? "TRUE" : "FALSE" );
  793.     }
  794. #endif /* X11_RESIZE_DEBUG */
  795.     if( ! p_plugin->setSize(window.width, (window.height - i_control_height)) )
  796.     {
  797.         /* size already set */
  798.         return;
  799.     }
  800.     i_ret = XResizeWindow( p_display, drawable,
  801.                            window.width, (window.height - i_control_height) );
  802. #ifdef X11_RESIZE_DEBUG
  803.     fprintf( stderr,
  804.              "vlcshell::Resize() XResizeWindow(owner) returned %dn", i_ret );
  805.     XGetWindowAttributes ( p_display, drawable, &attr );
  806.     /* X is asynchronous, so the current size reported here is not
  807.        necessarily the requested size as the Resize request may not
  808.        yet have been handled by the plugin host */
  809.     fprintf( stderr, "vlcshell::Resize() current (owner) size %d x %dn",
  810.              attr.width, attr.height );
  811. #endif /* X11_RESIZE_DEBUG */
  812.     XQueryTree( p_display, drawable,
  813.                 &root_return, &parent_return, &children_return,
  814.                 &i_nchildren );
  815.     if( i_nchildren > 0 )
  816.     {
  817.         /* XXX: Make assumptions related to the window parenting structure in
  818.            vlc/modules/video_output/x11/xcommon.c */
  819.         base_window = children_return[i_nchildren - 1];
  820. #ifdef X11_RESIZE_DEBUG
  821.         fprintf( stderr, "vlcshell::Resize() got %d childrenn", i_nchildren );
  822.         fprintf( stderr, "vlcshell::Resize() got base_window %pn",
  823.                  base_window );
  824. #endif /* X11_RESIZE_DEBUG */
  825.         i_ret = XResizeWindow( p_display, base_window,
  826.                 window.width, ( window.height - i_control_height ) );
  827. #ifdef X11_RESIZE_DEBUG
  828.         fprintf( stderr,
  829.                  "vlcshell::Resize() XResizeWindow(base) returned %dn",
  830.                  i_ret );
  831.         XGetWindowAttributes( p_display, base_window, &attr );
  832.         fprintf( stderr, "vlcshell::Resize() new size %d x %dn",
  833.                  attr.width, attr.height );
  834. #endif /* X11_RESIZE_DEBUG */
  835.     }
  836. }
  837. #endif /* XP_UNIX */