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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * vlcplugin.cpp: a VLC plugin for Mozilla
  3.  *****************************************************************************
  4.  * Copyright (C) 2002-2009 the VideoLAN team
  5.  * $Id: 6fe41a232852e85dae57aaf0efa5fe28afc595a4 $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  8.  *          Damien Fouilleul <damienf.fouilleul@laposte.net>
  9.  *          Jean-Paul Saman <jpsaman@videolan.org>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  24.  *****************************************************************************/
  25. /*****************************************************************************
  26.  * Preamble
  27.  *****************************************************************************/
  28. #include "config.h"
  29. #ifdef HAVE_MOZILLA_CONFIG_H
  30. #   include <mozilla-config.h>
  31. #endif
  32. #include "vlcplugin.h"
  33. #include "control/npolibvlc.h"
  34. #include <ctype.h>
  35. /*****************************************************************************
  36.  * VlcPlugin constructor and destructor
  37.  *****************************************************************************/
  38. VlcPlugin::VlcPlugin( NPP instance, uint16 mode ) :
  39.     i_npmode(mode),
  40.     b_stream(0),
  41.     b_autoplay(1),
  42.     b_toolbar(0),
  43.     psz_target(NULL),
  44.     playlist_index(-1),
  45.     libvlc_instance(NULL),
  46.     libvlc_media_list(NULL),
  47.     libvlc_media_player(NULL),
  48.     p_scriptClass(NULL),
  49.     p_browser(instance),
  50.     psz_baseURL(NULL)
  51. #if XP_WIN
  52.     ,pf_wndproc(NULL)
  53. #endif
  54. #if XP_UNIX
  55.     ,i_width((unsigned)-1)
  56.     ,i_height((unsigned)-1)
  57.     ,i_tb_width(0)
  58.     ,i_tb_height(0)
  59.     ,i_last_position(0)
  60.     ,p_btnPlay(NULL)
  61.     ,p_btnPause(NULL)
  62.     ,p_btnStop(NULL)
  63.     ,p_btnMute(NULL)
  64.     ,p_btnUnmute(NULL)
  65.     ,p_btnFullscreen(NULL)
  66.     ,p_btnTime(NULL)
  67.     ,p_timeline(NULL)
  68. #endif
  69. {
  70.     memset(&npwindow, 0, sizeof(NPWindow));
  71. #if XP_UNIX
  72.     memset(&npvideo, 0, sizeof(Window));
  73.     memset(&npcontrol, 0, sizeof(Window));
  74. #endif
  75. }
  76. static bool boolValue(const char *value) {
  77.     return ( !strcmp(value, "1") ||
  78.              !strcasecmp(value, "true") ||
  79.              !strcasecmp(value, "yes") );
  80. }
  81. NPError VlcPlugin::init(int argc, char* const argn[], char* const argv[])
  82. {
  83.     /* prepare VLC command line */
  84.     const char *ppsz_argv[32];
  85.     int ppsz_argc = 0;
  86. #ifndef NDEBUG
  87.     ppsz_argv[ppsz_argc++] = "--no-plugins-cache";
  88. #endif
  89.     /* locate VLC module path */
  90. #ifdef XP_MACOSX
  91.     ppsz_argv[ppsz_argc++] = "--plugin-path=/Library/Internet\ Plug-Ins/VLC\ Plugin.plugin/Contents/MacOS/modules";
  92.     ppsz_argv[ppsz_argc++] = "--vout=minimal_macosx";
  93. #elif defined(XP_WIN)
  94.     HKEY h_key;
  95.     DWORD i_type, i_data = MAX_PATH + 1;
  96.     char p_data[MAX_PATH + 1];
  97.     if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\VideoLAN\VLC",
  98.                       0, KEY_READ, &h_key ) == ERROR_SUCCESS )
  99.     {
  100.          if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type,
  101.                               (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS )
  102.          {
  103.              if( i_type == REG_SZ )
  104.              {
  105.                  strcat( p_data, "\plugins" );
  106.                  ppsz_argv[ppsz_argc++] = "--plugin-path";
  107.                  ppsz_argv[ppsz_argc++] = p_data;
  108.              }
  109.          }
  110.          RegCloseKey( h_key );
  111.     }
  112.     ppsz_argv[ppsz_argc++] = "--no-one-instance";
  113. #endif /* XP_MACOSX */
  114.     /* common settings */
  115.     ppsz_argv[ppsz_argc++] = "-vv";
  116.     ppsz_argv[ppsz_argc++] = "--no-stats";
  117.     ppsz_argv[ppsz_argc++] = "--no-media-library";
  118.     ppsz_argv[ppsz_argc++] = "--ignore-config";
  119.     ppsz_argv[ppsz_argc++] = "--intf=dummy";
  120.     ppsz_argv[ppsz_argc++] = "--no-video-title-show";
  121.     const char *progid = NULL;
  122.     /* parse plugin arguments */
  123.     for( int i = 0; (i < argc) && (ppsz_argc < 32); i++ )
  124.     {
  125.        /* fprintf(stderr, "argn=%s, argv=%sn", argn[i], argv[i]); */
  126.         if( !strcmp( argn[i], "target" )
  127.          || !strcmp( argn[i], "mrl")
  128.          || !strcmp( argn[i], "filename")
  129.          || !strcmp( argn[i], "src") )
  130.         {
  131.             psz_target = argv[i];
  132.         }
  133.         else if( !strcmp( argn[i], "autoplay")
  134.               || !strcmp( argn[i], "autostart") )
  135.         {
  136.             b_autoplay = boolValue(argv[i]);
  137.         }
  138.         else if( !strcmp( argn[i], "fullscreen" ) )
  139.         {
  140.             if( boolValue(argv[i]) )
  141.             {
  142.                 ppsz_argv[ppsz_argc++] = "--fullscreen";
  143.             }
  144.             else
  145.             {
  146.                 ppsz_argv[ppsz_argc++] = "--no-fullscreen";
  147.             }
  148.         }
  149.         else if( !strcmp( argn[i], "mute" ) )
  150.         {
  151.             if( boolValue(argv[i]) )
  152.             {
  153.                 ppsz_argv[ppsz_argc++] = "--volume=0";
  154.             }
  155.         }
  156.         else if( !strcmp( argn[i], "loop")
  157.               || !strcmp( argn[i], "autoloop") )
  158.         {
  159.             if( boolValue(argv[i]) )
  160.             {
  161.                 ppsz_argv[ppsz_argc++] = "--loop";
  162.             }
  163.             else
  164.             {
  165.                 ppsz_argv[ppsz_argc++] = "--no-loop";
  166.             }
  167.         }
  168.         else if( !strcmp( argn[i], "version")
  169.               || !strcmp( argn[i], "progid") )
  170.         {
  171.             progid = argv[i];
  172.         }
  173.         else if( !strcmp( argn[i], "toolbar" ) )
  174.         {
  175. /* FIXME: Remove this when toolbar functionality has been implemented on
  176.  * MacOS X and Win32 for Firefox/Mozilla/Safari. */
  177. #ifdef XP_UNIX
  178.             b_toolbar = boolValue(argv[i]);
  179. #endif
  180.         }
  181.     }
  182.     libvlc_exception_t ex;
  183.     libvlc_exception_init(&ex);
  184.     libvlc_instance = libvlc_new(ppsz_argc, ppsz_argv, &ex);
  185.     if( libvlc_exception_raised(&ex) )
  186.     {
  187.         libvlc_exception_clear(&ex);
  188.         return NPERR_GENERIC_ERROR;
  189.     }
  190.     libvlc_media_list = libvlc_media_list_new(libvlc_instance,&ex);
  191.     if( libvlc_exception_raised(&ex) )
  192.     {
  193.         libvlc_exception_clear(&ex);
  194.         return NPERR_GENERIC_ERROR;
  195.     }
  196.     /*
  197.     ** fetch plugin base URL, which is the URL of the page containing the plugin
  198.     ** this URL is used for making absolute URL from relative URL that may be
  199.     ** passed as an MRL argument
  200.     */
  201.     NPObject *plugin = NULL;
  202.     if( NPERR_NO_ERROR == NPN_GetValue(p_browser, NPNVWindowNPObject, &plugin) )
  203.     {
  204.         /*
  205.         ** is there a better way to get that info ?
  206.         */
  207.         static const char docLocHref[] = "document.location.href";
  208.         NPString script;
  209.         NPVariant result;
  210.         script.utf8characters = docLocHref;
  211.         script.utf8length = sizeof(docLocHref)-1;
  212.         if( NPN_Evaluate(p_browser, plugin, &script, &result) )
  213.         {
  214.             if( NPVARIANT_IS_STRING(result) )
  215.             {
  216.                 NPString &location = NPVARIANT_TO_STRING(result);
  217.                 psz_baseURL = (char *) malloc(location.utf8length+1);
  218.                 if( psz_baseURL )
  219.                 {
  220.                     strncpy(psz_baseURL, location.utf8characters, location.utf8length);
  221.                     psz_baseURL[location.utf8length] = '';
  222.                 }
  223.             }
  224.             NPN_ReleaseVariantValue(&result);
  225.         }
  226.         NPN_ReleaseObject(plugin);
  227.     }
  228.     if( psz_target )
  229.     {
  230.         // get absolute URL from src
  231.         char *psz_absurl = getAbsoluteURL(psz_target);
  232.         psz_target = psz_absurl ? psz_absurl : strdup(psz_target);
  233.     }
  234.     /* assign plugin script root class */
  235.     /* new APIs */
  236.     p_scriptClass = RuntimeNPClass<LibvlcRootNPObject>::getClass();
  237.     return NPERR_NO_ERROR;
  238. }
  239. VlcPlugin::~VlcPlugin()
  240. {
  241.     free(psz_baseURL);
  242.     free(psz_target);
  243.     if( libvlc_media_player )
  244.         libvlc_media_player_release( libvlc_media_player );
  245.     if( libvlc_media_list )
  246.         libvlc_media_list_release( libvlc_media_list );
  247.     if( libvlc_instance )
  248.         libvlc_release(libvlc_instance);
  249. }
  250. /*****************************************************************************
  251.  * VlcPlugin playlist replacement methods
  252.  *****************************************************************************/
  253. void VlcPlugin::set_player_window( libvlc_exception_t *ex )
  254. {
  255. #ifdef XP_UNIX
  256.     libvlc_media_player_set_xwindow(libvlc_media_player,
  257.                                     (libvlc_drawable_t)getVideoWindow(),
  258.                                     ex);
  259. #endif
  260. #ifdef XP_MACOSX
  261.     // XXX FIXME insert appropriate call here
  262. #endif
  263. #ifdef XP_WIN
  264.     libvlc_media_player_set_hwnd(libvlc_media_player,
  265.                                  getWindow().window,
  266.                                  ex);
  267. #endif
  268. }
  269. int VlcPlugin::playlist_add( const char *mrl, libvlc_exception_t *ex )
  270. {
  271.     int item = -1;
  272.     libvlc_media_t *p_m = libvlc_media_new(libvlc_instance,mrl,ex);
  273.     if( libvlc_exception_raised(ex) )
  274.         return -1;
  275.     libvlc_media_list_lock(libvlc_media_list);
  276.     libvlc_media_list_add_media(libvlc_media_list,p_m,ex);
  277.     if( !libvlc_exception_raised(ex) )
  278.         item = libvlc_media_list_count(libvlc_media_list,ex)-1;
  279.     libvlc_media_list_unlock(libvlc_media_list);
  280.     libvlc_media_release(p_m);
  281.     return item;
  282. }
  283. int VlcPlugin::playlist_add_extended_untrusted( const char *mrl, const char *name,
  284.                     int optc, const char **optv, libvlc_exception_t *ex )
  285. {
  286.     libvlc_media_t *p_m = libvlc_media_new(libvlc_instance, mrl,ex);
  287.     int item = -1;
  288.     if( libvlc_exception_raised(ex) )
  289.         return -1;
  290.     for( int i = 0; i < optc; ++i )
  291.     {
  292.         libvlc_media_add_option_untrusted(p_m, optv[i],ex);
  293.         if( libvlc_exception_raised(ex) )
  294.         {
  295.             libvlc_media_release(p_m);
  296.             return -1;
  297.         }
  298.     }
  299.     libvlc_media_list_lock(libvlc_media_list);
  300.     libvlc_media_list_add_media(libvlc_media_list,p_m,ex);
  301.     if( !libvlc_exception_raised(ex) )
  302.         item = libvlc_media_list_count(libvlc_media_list,ex)-1;
  303.     libvlc_media_list_unlock(libvlc_media_list);
  304.     libvlc_media_release(p_m);
  305.     return item;
  306. }
  307. bool VlcPlugin::playlist_select( int idx, libvlc_exception_t *ex )
  308. {
  309.     libvlc_media_t *p_m = NULL;
  310.     libvlc_media_list_lock(libvlc_media_list);
  311.     int count = libvlc_media_list_count(libvlc_media_list,ex);
  312.     if( libvlc_exception_raised(ex) )
  313.         goto bad_unlock;
  314.     if( idx<0||idx>=count )
  315.         goto bad_unlock;
  316.     playlist_index = idx;
  317.     p_m = libvlc_media_list_item_at_index(libvlc_media_list,playlist_index,ex);
  318.     libvlc_media_list_unlock(libvlc_media_list);
  319.     if( libvlc_exception_raised(ex) )
  320.         return false;
  321.     if( libvlc_media_player )
  322.     {
  323.         libvlc_media_player_release( libvlc_media_player );
  324.         libvlc_media_player = NULL;
  325.     }
  326.     libvlc_media_player = libvlc_media_player_new_from_media(p_m,ex);
  327.     if( libvlc_media_player )
  328.         set_player_window(ex);
  329.     libvlc_media_release( p_m );
  330.     return !libvlc_exception_raised(ex);
  331. bad_unlock:
  332.     libvlc_media_list_unlock(libvlc_media_list);
  333.     return false;
  334. }
  335. void VlcPlugin::playlist_delete_item( int idx, libvlc_exception_t *ex )
  336. {
  337.     libvlc_media_list_lock(libvlc_media_list);
  338.     libvlc_media_list_remove_index(libvlc_media_list,idx,ex);
  339.     libvlc_media_list_unlock(libvlc_media_list);
  340. }
  341. void VlcPlugin::playlist_clear( libvlc_exception_t *ex )
  342. {
  343.     if( libvlc_media_list )
  344.         libvlc_media_list_release(libvlc_media_list);
  345.     libvlc_media_list = libvlc_media_list_new(getVLC(),ex);
  346. }
  347. int VlcPlugin::playlist_count( libvlc_exception_t *ex )
  348. {
  349.     int items_count = 0;
  350.     libvlc_media_list_lock(libvlc_media_list);
  351.     items_count = libvlc_media_list_count(libvlc_media_list,ex);
  352.     libvlc_media_list_unlock(libvlc_media_list);
  353.     return items_count;
  354. }
  355. void VlcPlugin::toggle_fullscreen( libvlc_exception_t *ex )
  356. {
  357.     if( playlist_isplaying(ex) )
  358.         libvlc_toggle_fullscreen(libvlc_media_player,ex);
  359. }
  360. void VlcPlugin::set_fullscreen( int yes, libvlc_exception_t *ex )
  361. {
  362.     if( playlist_isplaying(ex) )
  363.         libvlc_set_fullscreen(libvlc_media_player,yes,ex);
  364. }
  365. int  VlcPlugin::get_fullscreen( libvlc_exception_t *ex )
  366. {
  367.     int r = 0;
  368.     if( playlist_isplaying(ex) )
  369.         r = libvlc_get_fullscreen(libvlc_media_player,ex);
  370.     return r;
  371. }
  372. bool  VlcPlugin::player_has_vout( libvlc_exception_t *ex )
  373. {
  374.     bool r = false;
  375.     if( playlist_isplaying(ex) )
  376.         r = libvlc_media_player_has_vout(libvlc_media_player, ex);
  377.     return r;
  378. }
  379. /*****************************************************************************
  380.  * VlcPlugin methods
  381.  *****************************************************************************/
  382. char *VlcPlugin::getAbsoluteURL(const char *url)
  383. {
  384.     if( NULL != url )
  385.     {
  386.         // check whether URL is already absolute
  387.         const char *end=strchr(url, ':');
  388.         if( (NULL != end) && (end != url) )
  389.         {
  390.             // validate protocol header
  391.             const char *start = url;
  392.             char c = *start;
  393.             if( isalpha(c) )
  394.             {
  395.                 ++start;
  396.                 while( start != end )
  397.                 {
  398.                     c  = *start;
  399.                     if( ! (isalnum(c)
  400.                        || ('-' == c)
  401.                        || ('+' == c)
  402.                        || ('.' == c)
  403.                        || ('/' == c)) ) /* VLC uses / to allow user to specify a demuxer */
  404.                         // not valid protocol header, assume relative URL
  405.                         goto relativeurl;
  406.                     ++start;
  407.                 }
  408.                 /* we have a protocol header, therefore URL is absolute */
  409.                 return strdup(url);
  410.             }
  411.             // not a valid protocol header, assume relative URL
  412.         }
  413. relativeurl:
  414.         if( psz_baseURL )
  415.         {
  416.             size_t baseLen = strlen(psz_baseURL);
  417.             char *href = (char *) malloc(baseLen+strlen(url)+1);
  418.             if( href )
  419.             {
  420.                 /* prepend base URL */
  421.                 strcpy(href, psz_baseURL);
  422.                 /*
  423.                 ** relative url could be empty,
  424.                 ** in which case return base URL
  425.                 */
  426.                 if( '' == *url )
  427.                     return href;
  428.                 /*
  429.                 ** locate pathname part of base URL
  430.                 */
  431.                 /* skip over protocol part  */
  432.                 char *pathstart = strchr(href, ':');
  433.                 char *pathend;
  434.                 if( pathstart )
  435.                 {
  436.                     if( '/' == *(++pathstart) )
  437.                     {
  438.                         if( '/' == *(++pathstart) )
  439.                         {
  440.                             ++pathstart;
  441.                         }
  442.                     }
  443.                     /* skip over host part */
  444.                     pathstart = strchr(pathstart, '/');
  445.                     pathend = href+baseLen;
  446.                     if( ! pathstart )
  447.                     {
  448.                         // no path, add a / past end of url (over '')
  449.                         pathstart = pathend;
  450.                         *pathstart = '/';
  451.                     }
  452.                 }
  453.                 else
  454.                 {
  455.                     /* baseURL is just a UNIX path */
  456.                     if( '/' != *href )
  457.                     {
  458.                         /* baseURL is not an absolute path */
  459.                         free(href);
  460.                         return NULL;
  461.                     }
  462.                     pathstart = href;
  463.                     pathend = href+baseLen;
  464.                 }
  465.                 /* relative URL made of an absolute path ? */
  466.                 if( '/' == *url )
  467.                 {
  468.                     /* replace path completely */
  469.                     strcpy(pathstart, url);
  470.                     return href;
  471.                 }
  472.                 /* find last path component and replace it */
  473.                 while( '/' != *pathend)
  474.                     --pathend;
  475.                 /*
  476.                 ** if relative url path starts with one or more '../',
  477.                 ** factor them out of href so that we return a
  478.                 ** normalized URL
  479.                 */
  480.                 while( pathend != pathstart )
  481.                 {
  482.                     const char *p = url;
  483.                     if( '.' != *p )
  484.                         break;
  485.                     ++p;
  486.                     if( '' == *p  )
  487.                     {
  488.                         /* relative url is just '.' */
  489.                         url = p;
  490.                         break;
  491.                     }
  492.                     if( '/' == *p  )
  493.                     {
  494.                         /* relative url starts with './' */
  495.                         url = ++p;
  496.                         continue;
  497.                     }
  498.                     if( '.' != *p )
  499.                         break;
  500.                     ++p;
  501.                     if( '' == *p )
  502.                     {
  503.                         /* relative url is '..' */
  504.                     }
  505.                     else
  506.                     {
  507.                         if( '/' != *p )
  508.                             break;
  509.                         /* relative url starts with '../' */
  510.                         ++p;
  511.                     }
  512.                     url = p;
  513.                     do
  514.                     {
  515.                         --pathend;
  516.                     }
  517.                     while( '/' != *pathend );
  518.                 }
  519.                 /* skip over '/' separator */
  520.                 ++pathend;
  521.                 /* concatenate remaining base URL and relative URL */
  522.                 strcpy(pathend, url);
  523.             }
  524.             return href;
  525.         }
  526.     }
  527.     return NULL;
  528. }
  529. #if XP_UNIX
  530. int  VlcPlugin::setSize(unsigned width, unsigned height)
  531. {
  532.     int diff = (width != i_width) || (height != i_height);
  533.     i_width = width;
  534.     i_height = height;
  535.     /* return size */
  536.     return diff;
  537. }
  538. #define BTN_SPACE ((unsigned int)4)
  539. void VlcPlugin::showToolbar()
  540. {
  541.     const NPWindow& window = getWindow();
  542.     Window control = getControlWindow();
  543.     Window video = getVideoWindow();
  544.     Display *p_display = ((NPSetWindowCallbackStruct *)window.ws_info)->display;
  545.     unsigned int i_height = 0, i_width = BTN_SPACE;
  546.     /* load icons */
  547.     if( !p_btnPlay )
  548.         XpmReadFileToImage( p_display, DATA_PATH "/mozilla/play.xpm",
  549.                             &p_btnPlay, NULL, NULL);
  550.     if( p_btnPlay )
  551.     {
  552.         i_height = __MAX( i_height, p_btnPlay->height );
  553.     }
  554.     if( !p_btnPause )
  555.         XpmReadFileToImage( p_display, DATA_PATH "/mozilla/pause.xpm",
  556.                             &p_btnPause, NULL, NULL);
  557.     if( p_btnPause )
  558.     {
  559.         i_height = __MAX( i_height, p_btnPause->height );
  560.     }
  561.     i_width += __MAX( p_btnPause->width, p_btnPlay->width );
  562.     if( !p_btnStop )
  563.         XpmReadFileToImage( p_display, DATA_PATH "/mozilla/stop.xpm",
  564.                             &p_btnStop, NULL, NULL );
  565.     if( p_btnStop )
  566.     {
  567.         i_height = __MAX( i_height, p_btnStop->height );
  568.         i_width += BTN_SPACE + p_btnStop->width;
  569.     }
  570.     if( !p_timeline )
  571.         XpmReadFileToImage( p_display, DATA_PATH "/mozilla/time_line.xpm",
  572.                             &p_timeline, NULL, NULL);
  573.     if( p_timeline )
  574.     {
  575.         i_height = __MAX( i_height, p_timeline->height );
  576.         i_width += BTN_SPACE + p_timeline->width;
  577.     }
  578.     if( !p_btnTime )
  579.         XpmReadFileToImage( p_display, DATA_PATH "/mozilla/time_icon.xpm",
  580.                             &p_btnTime, NULL, NULL);
  581.     if( p_btnTime )
  582.     {
  583.         i_height = __MAX( i_height, p_btnTime->height );
  584.         i_width += BTN_SPACE + p_btnTime->width;
  585.     }
  586.     if( !p_btnFullscreen )
  587.         XpmReadFileToImage( p_display, DATA_PATH "/mozilla/fullscreen.xpm",
  588.                             &p_btnFullscreen, NULL, NULL);
  589.     if( p_btnFullscreen )
  590.     {
  591.         i_height = __MAX( i_height, p_btnFullscreen->height );
  592.         i_width += BTN_SPACE + p_btnFullscreen->width;
  593.     }
  594.     if( !p_btnMute )
  595.         XpmReadFileToImage( p_display, DATA_PATH "/mozilla/volume_max.xpm",
  596.                             &p_btnMute, NULL, NULL);
  597.     if( p_btnMute )
  598.     {
  599.         i_height = __MAX( i_height, p_btnMute->height );
  600.     }
  601.     if( !p_btnUnmute )
  602.         XpmReadFileToImage( p_display, DATA_PATH "/mozilla/volume_mute.xpm",
  603.                             &p_btnUnmute, NULL, NULL);
  604.     if( p_btnUnmute )
  605.     {
  606.         i_height = __MAX( i_height, p_btnUnmute->height );
  607.     }
  608.     i_width += BTN_SPACE + __MAX( p_btnUnmute->width, p_btnMute->width );
  609.     setToolbarSize( i_width, i_height );
  610.     if( !p_btnPlay || !p_btnPause || !p_btnStop || !p_timeline ||
  611.         !p_btnTime || !p_btnFullscreen || !p_btnMute || !p_btnUnmute )
  612.         fprintf(stderr, "Error: some button images not found in %sn", DATA_PATH );
  613.     /* reset panels position and size */
  614.     /* XXX  use i_width */
  615.     XResizeWindow( p_display, video, window.width, window.height - i_height);
  616.     XMoveWindow( p_display, control, 0, window.height - i_height );
  617.     XResizeWindow( p_display, control, window.width, i_height -1);
  618.     b_toolbar = 1; /* says toolbar is now shown */
  619.     redrawToolbar();
  620. }
  621. void VlcPlugin::hideToolbar()
  622. {
  623.     const NPWindow& window = getWindow();
  624.     Display *p_display = ((NPSetWindowCallbackStruct *)window.ws_info)->display;
  625.     Window control = getControlWindow();
  626.     Window video = getVideoWindow();
  627.     i_tb_width = i_tb_height = 0;
  628.     if( p_btnPlay )  XDestroyImage( p_btnPlay );
  629.     if( p_btnPause ) XDestroyImage( p_btnPause );
  630.     if( p_btnStop )  XDestroyImage( p_btnStop );
  631.     if( p_timeline ) XDestroyImage( p_timeline );
  632.     if( p_btnTime )  XDestroyImage( p_btnTime );
  633.     if( p_btnFullscreen ) XDestroyImage( p_btnFullscreen );
  634.     if( p_btnMute )  XDestroyImage( p_btnMute );
  635.     if( p_btnUnmute ) XDestroyImage( p_btnUnmute );
  636.     p_btnPlay = NULL;
  637.     p_btnPause = NULL;
  638.     p_btnStop = NULL;
  639.     p_timeline = NULL;
  640.     p_btnTime = NULL;
  641.     p_btnFullscreen = NULL;
  642.     p_btnMute = NULL;
  643.     p_btnUnmute = NULL;
  644.     /* reset panels position and size */
  645.     /* XXX  use i_width */
  646.     XResizeWindow( p_display, video, window.width, window.height );
  647.     XMoveWindow( p_display, control, 0, window.height-1 );
  648.     XResizeWindow( p_display, control, window.width, 1 );
  649.     b_toolbar = 0; /* says toolbar is now hidden */
  650.     redrawToolbar();
  651. }
  652. void VlcPlugin::redrawToolbar()
  653. {
  654.     libvlc_exception_t ex;
  655.     int is_playing = 0;
  656.     bool b_mute = false;
  657.     unsigned int dst_x, dst_y;
  658.     GC gc;
  659.     XGCValues gcv;
  660.     unsigned int i_tb_width, i_tb_height;
  661.     /* This method does nothing if toolbar is hidden. */
  662.     if( !b_toolbar )
  663.         return;
  664.     const NPWindow& window = getWindow();
  665.     Window control = getControlWindow();
  666.     Display *p_display = ((NPSetWindowCallbackStruct *)window.ws_info)->display;
  667.     getToolbarSize( &i_tb_width, &i_tb_height );
  668.     libvlc_exception_init( &ex );
  669.     /* get mute info */
  670.     b_mute = libvlc_audio_get_mute( getVLC(), &ex );
  671.     libvlc_exception_clear( &ex );
  672.     gcv.foreground = BlackPixel( p_display, 0 );
  673.     gc = XCreateGC( p_display, control, GCForeground, &gcv );
  674.     XFillRectangle( p_display, control, gc,
  675.                     0, 0, window.width, i_tb_height );
  676.     gcv.foreground = WhitePixel( p_display, 0 );
  677.     XChangeGC( p_display, gc, GCForeground, &gcv );
  678.     /* position icons */
  679.     dst_x = BTN_SPACE;
  680.     dst_y = i_tb_height >> 1; /* baseline = vertical middle */
  681.     if( p_btnPause && (is_playing == 1) )
  682.     {
  683.         XPutImage( p_display, control, gc, p_btnPause, 0, 0, dst_x,
  684.                    dst_y - (p_btnPause->height >> 1),
  685.                    p_btnPause->width, p_btnPause->height );
  686.         dst_x += BTN_SPACE + p_btnPause->width;
  687.     }
  688.     else if( p_btnPlay )
  689.     {
  690.         XPutImage( p_display, control, gc, p_btnPlay, 0, 0, dst_x,
  691.                    dst_y - (p_btnPlay->height >> 1),
  692.                    p_btnPlay->width, p_btnPlay->height );
  693.         dst_x += BTN_SPACE + p_btnPlay->width;
  694.     }
  695.     if( p_btnStop )
  696.         XPutImage( p_display, control, gc, p_btnStop, 0, 0, dst_x,
  697.                    dst_y - (p_btnStop->height >> 1),
  698.                    p_btnStop->width, p_btnStop->height );
  699.     dst_x += BTN_SPACE + ( p_btnStop ? p_btnStop->width : 0 );
  700.     if( p_btnFullscreen )
  701.         XPutImage( p_display, control, gc, p_btnFullscreen, 0, 0, dst_x,
  702.                    dst_y - (p_btnFullscreen->height >> 1),
  703.                    p_btnFullscreen->width, p_btnFullscreen->height );
  704.     dst_x += BTN_SPACE + ( p_btnFullscreen ? p_btnFullscreen->width : 0 );
  705.     if( p_btnUnmute && b_mute )
  706.     {
  707.         XPutImage( p_display, control, gc, p_btnUnmute, 0, 0, dst_x,
  708.                    dst_y - (p_btnUnmute->height >> 1),
  709.                    p_btnUnmute->width, p_btnUnmute->height );
  710.         dst_x += BTN_SPACE + ( p_btnUnmute ? p_btnUnmute->width : 0 );
  711.     }
  712.     else if( p_btnMute )
  713.     {
  714.         XPutImage( p_display, control, gc, p_btnMute, 0, 0, dst_x,
  715.                    dst_y - (p_btnMute->height >> 1),
  716.                    p_btnMute->width, p_btnMute->height );
  717.         dst_x += BTN_SPACE + ( p_btnMute ? p_btnMute->width : 0 );
  718.     }
  719.     if( p_timeline )
  720.         XPutImage( p_display, control, gc, p_timeline, 0, 0, dst_x,
  721.                    dst_y - (p_timeline->height >> 1),
  722.                    (window.width-(dst_x+BTN_SPACE)), p_timeline->height );
  723.     /* get movie position in % */
  724.     if( playlist_isplaying(&ex) )
  725.     {
  726.         i_last_position = (int)((window.width-(dst_x+BTN_SPACE))*
  727.                    libvlc_media_player_get_position(libvlc_media_player,&ex));
  728.     }
  729.     libvlc_exception_clear( &ex );
  730.     if( p_btnTime )
  731.         XPutImage( p_display, control, gc, p_btnTime,
  732.                    0, 0, (dst_x+i_last_position),
  733.                    dst_y - (p_btnTime->height >> 1),
  734.                    p_btnTime->width, p_btnTime->height );
  735.     XFreeGC( p_display, gc );
  736. }
  737. vlc_toolbar_clicked_t VlcPlugin::getToolbarButtonClicked( int i_xpos, int i_ypos )
  738. {
  739.     unsigned int i_dest = BTN_SPACE;
  740.     int is_playing = 0;
  741.     bool b_mute = false;
  742.     libvlc_exception_t ex;
  743. #ifndef NDEBUG
  744.     fprintf( stderr, "ToolbarButtonClicked:: "
  745.                      "trying to match (%d,%d) (%d,%d)n",
  746.              i_xpos, i_ypos, i_tb_height, i_tb_width );
  747. #endif
  748.     if( i_ypos >= i_tb_width )
  749.         return clicked_Unknown;
  750.     /* Note: the order of testing is dependend on the original
  751.      * drawing positions of the icon buttons. Buttons are tested
  752.      * left to right.
  753.      */
  754.     /* get isplaying */
  755.     libvlc_exception_init( &ex );
  756.     is_playing = playlist_isplaying( &ex );
  757.     libvlc_exception_clear( &ex );
  758.     /* get mute info */
  759.     b_mute = libvlc_audio_get_mute( getVLC(), &ex );
  760.     libvlc_exception_clear( &ex );
  761.     /* is Pause of Play button clicked */
  762.     if( (is_playing != 1) &&
  763.         (i_xpos >= (BTN_SPACE>>1)) &&
  764.         (i_xpos <= i_dest + p_btnPlay->width + (BTN_SPACE>>1)) )
  765.         return clicked_Play;
  766.     else if( (i_xpos >= (BTN_SPACE>>1))  &&
  767.              (i_xpos <= i_dest + p_btnPause->width) )
  768.         return clicked_Pause;
  769.     /* is Stop button clicked */
  770.     if( is_playing != 1 )
  771.         i_dest += (p_btnPlay->width + (BTN_SPACE>>1));
  772.     else
  773.         i_dest += (p_btnPause->width + (BTN_SPACE>>1));
  774.     if( (i_xpos >= i_dest) &&
  775.         (i_xpos <= i_dest + p_btnStop->width + (BTN_SPACE>>1)) )
  776.         return clicked_Stop;
  777.     /* is Fullscreen button clicked */
  778.     i_dest += (p_btnStop->width + (BTN_SPACE>>1));
  779.     if( (i_xpos >= i_dest) &&
  780.         (i_xpos <= i_dest + p_btnFullscreen->width + (BTN_SPACE>>1)) )
  781.         return clicked_Fullscreen;
  782.     /* is Mute or Unmute button clicked */
  783.     i_dest += (p_btnFullscreen->width + (BTN_SPACE>>1));
  784.     if( !b_mute && (i_xpos >= i_dest) &&
  785.         (i_xpos <= i_dest + p_btnMute->width + (BTN_SPACE>>1)) )
  786.         return clicked_Mute;
  787.     else if( (i_xpos >= i_dest) &&
  788.              (i_xpos <= i_dest + p_btnUnmute->width + (BTN_SPACE>>1)) )
  789.         return clicked_Unmute;
  790.     /* is timeline clicked */
  791.     if( !b_mute )
  792.         i_dest += (p_btnMute->width + (BTN_SPACE>>1));
  793.     else
  794.         i_dest += (p_btnUnmute->width + (BTN_SPACE>>1));
  795.     if( (i_xpos >= i_dest) &&
  796.         (i_xpos <= i_dest + p_timeline->width + (BTN_SPACE>>1)) )
  797.         return clicked_timeline;
  798.     /* is time button clicked */
  799.     i_dest += (p_timeline->width + (BTN_SPACE>>1));
  800.     if( (i_xpos >= i_dest) &&
  801.         (i_xpos <= i_dest + p_btnTime->width + (BTN_SPACE>>1)) )
  802.         return clicked_Time;
  803.     return clicked_Unknown;
  804. }
  805. #undef BTN_SPACE
  806. #endif