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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * npolibvlc.cpp: official Javascript APIs
  3.  *****************************************************************************
  4.  * Copyright (C) 2002-2009 the VideoLAN team
  5.  *
  6.  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
  7.  *          Jan Paul Dinger <jpd@m2x.nl>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. #include "config.h"
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. /* Mozilla stuff */
  28. #ifdef HAVE_MOZILLA_CONFIG_H
  29. #   include <mozilla-config.h>
  30. #endif
  31. #include "vlcplugin.h"
  32. #include "npolibvlc.h"
  33. /*
  34. ** Local helper macros and function
  35. */
  36. #define COUNTNAMES(a,b,c) const int a::b = sizeof(a::c)/sizeof(NPUTF8 *)
  37. #define RETURN_ON_EXCEPTION(this,ex) 
  38.     do { if( libvlc_exception_raised(&ex) ) 
  39.     { 
  40.         NPN_SetException(this, libvlc_exception_get_message(&ex)); 
  41.         libvlc_exception_clear(&ex); 
  42.         return INVOKERESULT_GENERIC_ERROR; 
  43.     } } while(false)
  44. /*
  45. ** implementation of libvlc root object
  46. */
  47. LibvlcRootNPObject::~LibvlcRootNPObject()
  48. {
  49.     /*
  50.     ** When the plugin is destroyed, firefox takes it upon itself to
  51.     ** destroy all 'live' script objects and ignores refcounting.
  52.     ** Therefore we cannot safely assume that refcounting will control
  53.     ** lifespan of objects. Hence they are only lazily created on
  54.     ** request, so that firefox can take ownership, and are not released
  55.     ** when the plugin is destroyed.
  56.     */
  57.     if( isValid() )
  58.     {
  59.         if( audioObj    ) NPN_ReleaseObject(audioObj);
  60.         if( inputObj    ) NPN_ReleaseObject(inputObj);
  61.         if( playlistObj ) NPN_ReleaseObject(playlistObj);
  62.         if( videoObj    ) NPN_ReleaseObject(videoObj);
  63.     }
  64. }
  65. const NPUTF8 * const LibvlcRootNPObject::propertyNames[] =
  66. {
  67.     "audio",
  68.     "input",
  69.     "playlist",
  70.     "video",
  71.     "VersionInfo",
  72. };
  73. COUNTNAMES(LibvlcRootNPObject,propertyCount,propertyNames);
  74. enum LibvlcRootNPObjectPropertyIds
  75. {
  76.     ID_root_audio = 0,
  77.     ID_root_input,
  78.     ID_root_playlist,
  79.     ID_root_video,
  80.     ID_root_VersionInfo,
  81. };
  82. RuntimeNPObject::InvokeResult
  83. LibvlcRootNPObject::getProperty(int index, NPVariant &result)
  84. {
  85.     /* is plugin still running */
  86.     if( isPluginRunning() )
  87.     {
  88.         switch( index )
  89.         {
  90.             case ID_root_audio:
  91.                 // create child object in lazyman fashion to avoid
  92.                 // ownership problem with firefox
  93.                 if( ! audioObj )
  94.                     audioObj = NPN_CreateObject(_instance,
  95.                              RuntimeNPClass<LibvlcAudioNPObject>::getClass());
  96.                 OBJECT_TO_NPVARIANT(NPN_RetainObject(audioObj), result);
  97.                 return INVOKERESULT_NO_ERROR;
  98.             case ID_root_input:
  99.                 // create child object in lazyman fashion to avoid
  100.                 // ownership problem with firefox
  101.                 if( ! inputObj )
  102.                     inputObj = NPN_CreateObject(_instance,
  103.                              RuntimeNPClass<LibvlcInputNPObject>::getClass());
  104.                 OBJECT_TO_NPVARIANT(NPN_RetainObject(inputObj), result);
  105.                 return INVOKERESULT_NO_ERROR;
  106.             case ID_root_playlist:
  107.                 // create child object in lazyman fashion to avoid
  108.                 // ownership problem with firefox
  109.                 if( ! playlistObj )
  110.                     playlistObj = NPN_CreateObject(_instance,
  111.                           RuntimeNPClass<LibvlcPlaylistNPObject>::getClass());
  112.                 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistObj), result);
  113.                 return INVOKERESULT_NO_ERROR;
  114.             case ID_root_video:
  115.                 // create child object in lazyman fashion to avoid
  116.                 // ownership problem with firefox
  117.                 if( ! videoObj )
  118.                     videoObj = NPN_CreateObject(_instance,
  119.                              RuntimeNPClass<LibvlcVideoNPObject>::getClass());
  120.                 OBJECT_TO_NPVARIANT(NPN_RetainObject(videoObj), result);
  121.                 return INVOKERESULT_NO_ERROR;
  122.             case ID_root_VersionInfo:
  123.             {
  124.                 const char *s = libvlc_get_version();
  125.                 int len = strlen(s);
  126.                 NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);
  127.                 if( !retval )
  128.                     return INVOKERESULT_OUT_OF_MEMORY;
  129.                 memcpy(retval, s, len);
  130.                 STRINGN_TO_NPVARIANT(retval, len, result);
  131.                 return INVOKERESULT_NO_ERROR;
  132.             }
  133.             default:
  134.                 ;
  135.         }
  136.     }
  137.     return INVOKERESULT_GENERIC_ERROR;
  138. }
  139. const NPUTF8 * const LibvlcRootNPObject::methodNames[] =
  140. {
  141.     "versionInfo",
  142. };
  143. COUNTNAMES(LibvlcRootNPObject,methodCount,methodNames);
  144. enum LibvlcRootNPObjectMethodIds
  145. {
  146.     ID_root_versionInfo,
  147. };
  148. RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index,
  149.                   const NPVariant *args, uint32_t argCount, NPVariant &result)
  150. {
  151.     /* is plugin still running */
  152.     if( isPluginRunning() )
  153.     {
  154.         libvlc_exception_t ex;
  155.         libvlc_exception_init(&ex);
  156.         switch( index )
  157.         {
  158.             case ID_root_versionInfo:
  159.                 if( argCount == 0 )
  160.                 {
  161.                     const char *s = libvlc_get_version();
  162.                     int len = strlen(s);
  163.                     NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);
  164.                     if( !retval )
  165.                         return INVOKERESULT_OUT_OF_MEMORY;
  166.                     memcpy(retval, s, len);
  167.                     STRINGN_TO_NPVARIANT(retval, len, result);
  168.                     return INVOKERESULT_NO_ERROR;
  169.                 }
  170.                 return INVOKERESULT_NO_SUCH_METHOD;
  171.             default:
  172.                 ;
  173.         }
  174.     }
  175.     return INVOKERESULT_GENERIC_ERROR;
  176. }
  177. /*
  178. ** implementation of libvlc audio object
  179. */
  180. const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] =
  181. {
  182.     "mute",
  183.     "volume",
  184.     "track",
  185.     "channel",
  186. };
  187. COUNTNAMES(LibvlcAudioNPObject,propertyCount,propertyNames);
  188. enum LibvlcAudioNPObjectPropertyIds
  189. {
  190.     ID_audio_mute,
  191.     ID_audio_volume,
  192.     ID_audio_track,
  193.     ID_audio_channel,
  194. };
  195. RuntimeNPObject::InvokeResult
  196. LibvlcAudioNPObject::getProperty(int index, NPVariant &result)
  197. {
  198.     /* is plugin still running */
  199.     if( isPluginRunning() )
  200.     {
  201.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  202.         libvlc_exception_t ex;
  203.         libvlc_exception_init(&ex);
  204.         switch( index )
  205.         {
  206.             case ID_audio_mute:
  207.             {
  208.                 bool muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex);
  209.                 RETURN_ON_EXCEPTION(this,ex);
  210.                 BOOLEAN_TO_NPVARIANT(muted, result);
  211.                 return INVOKERESULT_NO_ERROR;
  212.             }
  213.             case ID_audio_volume:
  214.             {
  215.                 int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex);
  216.                 RETURN_ON_EXCEPTION(this,ex);
  217.                 INT32_TO_NPVARIANT(volume, result);
  218.                 return INVOKERESULT_NO_ERROR;
  219.             }
  220.             case ID_audio_track:
  221.             {
  222.                 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
  223.                 RETURN_ON_EXCEPTION(this,ex);
  224.                 int track = libvlc_audio_get_track(p_md, &ex);
  225.                 RETURN_ON_EXCEPTION(this,ex);
  226.                 INT32_TO_NPVARIANT(track, result);
  227.                 return INVOKERESULT_NO_ERROR;
  228.             }
  229.             case ID_audio_channel:
  230.             {
  231.                 int channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex);
  232.                 RETURN_ON_EXCEPTION(this,ex);
  233.                 INT32_TO_NPVARIANT(channel, result);
  234.                 return INVOKERESULT_NO_ERROR;
  235.             }
  236.             default:
  237.                 ;
  238.         }
  239.     }
  240.     return INVOKERESULT_GENERIC_ERROR;
  241. }
  242. RuntimeNPObject::InvokeResult
  243. LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)
  244. {
  245.     /* is plugin still running */
  246.     if( isPluginRunning() )
  247.     {
  248.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  249.         libvlc_exception_t ex;
  250.         libvlc_exception_init(&ex);
  251.         switch( index )
  252.         {
  253.             case ID_audio_mute:
  254.                 if( NPVARIANT_IS_BOOLEAN(value) )
  255.                 {
  256.                     libvlc_audio_set_mute(p_plugin->getVLC(),
  257.                                           NPVARIANT_TO_BOOLEAN(value), &ex);
  258.                     RETURN_ON_EXCEPTION(this,ex);
  259.                     return INVOKERESULT_NO_ERROR;
  260.                 }
  261.                 return INVOKERESULT_INVALID_VALUE;
  262.             case ID_audio_volume:
  263.                 if( isNumberValue(value) )
  264.                 {
  265.                     libvlc_audio_set_volume(p_plugin->getVLC(),
  266.                                             numberValue(value), &ex);
  267.                     RETURN_ON_EXCEPTION(this,ex);
  268.                     return INVOKERESULT_NO_ERROR;
  269.                 }
  270.                 return INVOKERESULT_INVALID_VALUE;
  271.             case ID_audio_track:
  272.                 if( isNumberValue(value) )
  273.                 {
  274.                     libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
  275.                     RETURN_ON_EXCEPTION(this,ex);
  276.                     libvlc_audio_set_track(p_md, numberValue(value), &ex);
  277.                     RETURN_ON_EXCEPTION(this,ex);
  278.                     return INVOKERESULT_NO_ERROR;
  279.                 }
  280.                 return INVOKERESULT_INVALID_VALUE;
  281.             case ID_audio_channel:
  282.                 if( isNumberValue(value) )
  283.                 {
  284.                     libvlc_audio_set_channel(p_plugin->getVLC(),
  285.                                              numberValue(value), &ex);
  286.                     RETURN_ON_EXCEPTION(this,ex);
  287.                     return INVOKERESULT_NO_ERROR;
  288.                 }
  289.                 return INVOKERESULT_INVALID_VALUE;
  290.             default:
  291.                 ;
  292.         }
  293.     }
  294.     return INVOKERESULT_GENERIC_ERROR;
  295. }
  296. const NPUTF8 * const LibvlcAudioNPObject::methodNames[] =
  297. {
  298.     "toggleMute",
  299. };
  300. COUNTNAMES(LibvlcAudioNPObject,methodCount,methodNames);
  301. enum LibvlcAudioNPObjectMethodIds
  302. {
  303.     ID_audio_togglemute,
  304. };
  305. RuntimeNPObject::InvokeResult
  306. LibvlcAudioNPObject::invoke(int index, const NPVariant *args,
  307.                             uint32_t argCount, NPVariant &result)
  308. {
  309.     /* is plugin still running */
  310.     if( isPluginRunning() )
  311.     {
  312.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  313.         libvlc_exception_t ex;
  314.         libvlc_exception_init(&ex);
  315.         switch( index )
  316.         {
  317.             case ID_audio_togglemute:
  318.                 if( argCount == 0 )
  319.                 {
  320.                     libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex);
  321.                     RETURN_ON_EXCEPTION(this,ex);
  322.                     VOID_TO_NPVARIANT(result);
  323.                     return INVOKERESULT_NO_ERROR;
  324.                 }
  325.                 return INVOKERESULT_NO_SUCH_METHOD;
  326.             default:
  327.                 ;
  328.         }
  329.     }
  330.     return INVOKERESULT_GENERIC_ERROR;
  331. }
  332. /*
  333. ** implementation of libvlc input object
  334. */
  335. const NPUTF8 * const LibvlcInputNPObject::propertyNames[] =
  336. {
  337.     "length",
  338.     "position",
  339.     "time",
  340.     "state",
  341.     "rate",
  342.     "fps",
  343.     "hasVout",
  344. };
  345. COUNTNAMES(LibvlcInputNPObject,propertyCount,propertyNames);
  346. enum LibvlcInputNPObjectPropertyIds
  347. {
  348.     ID_input_length,
  349.     ID_input_position,
  350.     ID_input_time,
  351.     ID_input_state,
  352.     ID_input_rate,
  353.     ID_input_fps,
  354.     ID_input_hasvout,
  355. };
  356. RuntimeNPObject::InvokeResult
  357. LibvlcInputNPObject::getProperty(int index, NPVariant &result)
  358. {
  359.     /* is plugin still running */
  360.     if( isPluginRunning() )
  361.     {
  362.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  363.         libvlc_exception_t ex;
  364.         libvlc_exception_init(&ex);
  365.         libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
  366.         if( libvlc_exception_raised(&ex) )
  367.         {
  368.             if( index != ID_input_state )
  369.             {
  370.                 NPN_SetException(this, libvlc_exception_get_message(&ex));
  371.                 libvlc_exception_clear(&ex);
  372.                 return INVOKERESULT_GENERIC_ERROR;
  373.             }
  374.             else
  375.             {
  376.                 /* for input state, return CLOSED rather than an exception */
  377.                 INT32_TO_NPVARIANT(0, result);
  378.                 libvlc_exception_clear(&ex);
  379.                 return INVOKERESULT_NO_ERROR;
  380.             }
  381.         }
  382.         switch( index )
  383.         {
  384.             case ID_input_length:
  385.             {
  386.                 double val = (double)libvlc_media_player_get_length(p_md, &ex);
  387.                 RETURN_ON_EXCEPTION(this,ex);
  388.                 DOUBLE_TO_NPVARIANT(val, result);
  389.                 return INVOKERESULT_NO_ERROR;
  390.             }
  391.             case ID_input_position:
  392.             {
  393.                 double val = libvlc_media_player_get_position(p_md, &ex);
  394.                 RETURN_ON_EXCEPTION(this,ex);
  395.                 DOUBLE_TO_NPVARIANT(val, result);
  396.                 return INVOKERESULT_NO_ERROR;
  397.             }
  398.             case ID_input_time:
  399.             {
  400.                 double val = (double)libvlc_media_player_get_time(p_md, &ex);
  401.                 RETURN_ON_EXCEPTION(this,ex);
  402.                 DOUBLE_TO_NPVARIANT(val, result);
  403.                 return INVOKERESULT_NO_ERROR;
  404.             }
  405.             case ID_input_state:
  406.             {
  407.                 int val = libvlc_media_player_get_state(p_md, &ex);
  408.                 RETURN_ON_EXCEPTION(this,ex);
  409.                 INT32_TO_NPVARIANT(val, result);
  410.                 return INVOKERESULT_NO_ERROR;
  411.             }
  412.             case ID_input_rate:
  413.             {
  414.                 float val = libvlc_media_player_get_rate(p_md, &ex);
  415.                 RETURN_ON_EXCEPTION(this,ex);
  416.                 DOUBLE_TO_NPVARIANT(val, result);
  417.                 return INVOKERESULT_NO_ERROR;
  418.             }
  419.             case ID_input_fps:
  420.             {
  421.                 double val = libvlc_media_player_get_fps(p_md, &ex);
  422.                 RETURN_ON_EXCEPTION(this,ex);
  423.                 DOUBLE_TO_NPVARIANT(val, result);
  424.                 return INVOKERESULT_NO_ERROR;
  425.             }
  426.             case ID_input_hasvout:
  427.             {
  428.                 bool val = p_plugin->player_has_vout(&ex);
  429.                 RETURN_ON_EXCEPTION(this,ex);
  430.                 BOOLEAN_TO_NPVARIANT(val, result);
  431.                 return INVOKERESULT_NO_ERROR;
  432.             }
  433.             default:
  434.                 ;
  435.         }
  436.     }
  437.     return INVOKERESULT_GENERIC_ERROR;
  438. }
  439. RuntimeNPObject::InvokeResult
  440. LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
  441. {
  442.     /* is plugin still running */
  443.     if( isPluginRunning() )
  444.     {
  445.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  446.         libvlc_exception_t ex;
  447.         libvlc_exception_init(&ex);
  448.         libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
  449.         RETURN_ON_EXCEPTION(this,ex);
  450.         switch( index )
  451.         {
  452.             case ID_input_position:
  453.             {
  454.                 if( ! NPVARIANT_IS_DOUBLE(value) )
  455.                 {
  456.                     return INVOKERESULT_INVALID_VALUE;
  457.                 }
  458.                 float val = (float)NPVARIANT_TO_DOUBLE(value);
  459.                 libvlc_media_player_set_position(p_md, val, &ex);
  460.                 RETURN_ON_EXCEPTION(this,ex);
  461.                 return INVOKERESULT_NO_ERROR;
  462.             }
  463.             case ID_input_time:
  464.             {
  465.                 int64_t val;
  466.                 if( NPVARIANT_IS_INT32(value) )
  467.                     val = (int64_t)NPVARIANT_TO_INT32(value);
  468.                 else if( NPVARIANT_IS_DOUBLE(value) )
  469.                     val = (int64_t)NPVARIANT_TO_DOUBLE(value);
  470.                 else
  471.                 {
  472.                     return INVOKERESULT_INVALID_VALUE;
  473.                 }
  474.                 libvlc_media_player_set_time(p_md, val, &ex);
  475.                 RETURN_ON_EXCEPTION(this,ex);
  476.                 return INVOKERESULT_NO_ERROR;
  477.             }
  478.             case ID_input_rate:
  479.             {
  480.                 float val;
  481.                 if( NPVARIANT_IS_INT32(value) )
  482.                     val = (float)NPVARIANT_TO_INT32(value);
  483.                 else if( NPVARIANT_IS_DOUBLE(value) )
  484.                     val = (float)NPVARIANT_TO_DOUBLE(value);
  485.                 else
  486.                 {
  487.                     return INVOKERESULT_INVALID_VALUE;
  488.                 }
  489.                 libvlc_media_player_set_rate(p_md, val, &ex);
  490.                 RETURN_ON_EXCEPTION(this,ex);
  491.                 return INVOKERESULT_NO_ERROR;
  492.             }
  493.             default:
  494.                 ;
  495.         }
  496.     }
  497.     return INVOKERESULT_GENERIC_ERROR;
  498. }
  499. const NPUTF8 * const LibvlcInputNPObject::methodNames[] =
  500. {
  501.     /* no methods */
  502.     "none",
  503. };
  504. COUNTNAMES(LibvlcInputNPObject,methodCount,methodNames);
  505. enum LibvlcInputNPObjectMethodIds
  506. {
  507.     ID_none,
  508. };
  509. RuntimeNPObject::InvokeResult
  510. LibvlcInputNPObject::invoke(int index, const NPVariant *args,
  511.                                     uint32_t argCount, NPVariant &result)
  512. {
  513.     /* is plugin still running */
  514.     if( isPluginRunning() )
  515.     {
  516.         switch( index )
  517.         {
  518.             case ID_none:
  519.                 return INVOKERESULT_NO_SUCH_METHOD;
  520.             default:
  521.                 ;
  522.         }
  523.     }
  524.     return INVOKERESULT_GENERIC_ERROR;
  525. }
  526. /*
  527. ** implementation of libvlc playlist items object
  528. */
  529. const NPUTF8 * const LibvlcPlaylistItemsNPObject::propertyNames[] =
  530. {
  531.     "count",
  532. };
  533. COUNTNAMES(LibvlcPlaylistItemsNPObject,propertyCount,propertyNames);
  534. enum LibvlcPlaylistItemsNPObjectPropertyIds
  535. {
  536.     ID_playlistitems_count,
  537. };
  538. RuntimeNPObject::InvokeResult
  539. LibvlcPlaylistItemsNPObject::getProperty(int index, NPVariant &result)
  540. {
  541.     /* is plugin still running */
  542.     if( isPluginRunning() )
  543.     {
  544.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  545.         libvlc_exception_t ex;
  546.         libvlc_exception_init(&ex);
  547.         switch( index )
  548.         {
  549.             case ID_playlistitems_count:
  550.             {
  551.                 int val = p_plugin->playlist_count(&ex);
  552.                 RETURN_ON_EXCEPTION(this,ex);
  553.                 INT32_TO_NPVARIANT(val, result);
  554.                 return INVOKERESULT_NO_ERROR;
  555.             }
  556.             default:
  557.                 ;
  558.         }
  559.     }
  560.     return INVOKERESULT_GENERIC_ERROR;
  561. }
  562. const NPUTF8 * const LibvlcPlaylistItemsNPObject::methodNames[] =
  563. {
  564.     "clear",
  565.     "remove",
  566. };
  567. COUNTNAMES(LibvlcPlaylistItemsNPObject,methodCount,methodNames);
  568. enum LibvlcPlaylistItemsNPObjectMethodIds
  569. {
  570.     ID_playlistitems_clear,
  571.     ID_playlistitems_remove,
  572. };
  573. RuntimeNPObject::InvokeResult
  574. LibvlcPlaylistItemsNPObject::invoke(int index, const NPVariant *args,
  575.                                     uint32_t argCount, NPVariant &result)
  576. {
  577.     /* is plugin still running */
  578.     if( isPluginRunning() )
  579.     {
  580.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  581.         libvlc_exception_t ex;
  582.         libvlc_exception_init(&ex);
  583.         switch( index )
  584.         {
  585.             case ID_playlistitems_clear:
  586.                 if( argCount == 0 )
  587.                 {
  588.                     p_plugin->playlist_clear(&ex);
  589.                     RETURN_ON_EXCEPTION(this,ex);
  590.                     VOID_TO_NPVARIANT(result);
  591.                     return INVOKERESULT_NO_ERROR;
  592.                 }
  593.                 return INVOKERESULT_NO_SUCH_METHOD;
  594.             case ID_playlistitems_remove:
  595.                 if( (argCount == 1) && isNumberValue(args[0]) )
  596.                 {
  597.                     p_plugin->playlist_delete_item(numberValue(args[0]),&ex);
  598.                     RETURN_ON_EXCEPTION(this,ex);
  599.                     VOID_TO_NPVARIANT(result);
  600.                     return INVOKERESULT_NO_ERROR;
  601.                 }
  602.                 return INVOKERESULT_NO_SUCH_METHOD;
  603.             default:
  604.                 ;
  605.         }
  606.     }
  607.     return INVOKERESULT_GENERIC_ERROR;
  608. }
  609. /*
  610. ** implementation of libvlc playlist object
  611. */
  612. LibvlcPlaylistNPObject::~LibvlcPlaylistNPObject()
  613. {
  614.     if( isValid() )
  615.     {
  616.         if( playlistItemsObj ) NPN_ReleaseObject(playlistItemsObj);
  617.     }
  618. };
  619. const NPUTF8 * const LibvlcPlaylistNPObject::propertyNames[] =
  620. {
  621.     "itemCount", /* deprecated */
  622.     "isPlaying",
  623.     "items",
  624. };
  625. COUNTNAMES(LibvlcPlaylistNPObject,propertyCount,propertyNames);
  626. enum LibvlcPlaylistNPObjectPropertyIds
  627. {
  628.     ID_playlist_itemcount,
  629.     ID_playlist_isplaying,
  630.     ID_playlist_items,
  631. };
  632. RuntimeNPObject::InvokeResult
  633. LibvlcPlaylistNPObject::getProperty(int index, NPVariant &result)
  634. {
  635.     /* is plugin still running */
  636.     if( isPluginRunning() )
  637.     {
  638.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  639.         libvlc_exception_t ex;
  640.         libvlc_exception_init(&ex);
  641.         switch( index )
  642.         {
  643.             case ID_playlist_itemcount: /* deprecated */
  644.             {
  645.                 int val = p_plugin->playlist_count(&ex);
  646.                 RETURN_ON_EXCEPTION(this,ex);
  647.                 INT32_TO_NPVARIANT(val, result);
  648.                 return INVOKERESULT_NO_ERROR;
  649.             }
  650.             case ID_playlist_isplaying:
  651.             {
  652.                 int val = p_plugin->playlist_isplaying(&ex);
  653.                 RETURN_ON_EXCEPTION(this,ex);
  654.                 BOOLEAN_TO_NPVARIANT(val, result);
  655.                 return INVOKERESULT_NO_ERROR;
  656.             }
  657.             case ID_playlist_items:
  658.             {
  659.                 // create child object in lazyman fashion to avoid
  660.                 // ownership problem with firefox
  661.                 if( ! playlistItemsObj )
  662.                     playlistItemsObj =
  663.                         NPN_CreateObject(_instance, RuntimeNPClass<
  664.                         LibvlcPlaylistItemsNPObject>::getClass());
  665.                 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistItemsObj), result);
  666.                 return INVOKERESULT_NO_ERROR;
  667.             }
  668.             default:
  669.                 ;
  670.         }
  671.     }
  672.     return INVOKERESULT_GENERIC_ERROR;
  673. }
  674. const NPUTF8 * const LibvlcPlaylistNPObject::methodNames[] =
  675. {
  676.     "add",
  677.     "play",
  678.     "playItem",
  679.     "togglePause",
  680.     "stop",
  681.     "next",
  682.     "prev",
  683.     "clear", /* deprecated */
  684.     "removeItem", /* deprecated */
  685. };
  686. COUNTNAMES(LibvlcPlaylistNPObject,methodCount,methodNames);
  687. enum LibvlcPlaylistNPObjectMethodIds
  688. {
  689.     ID_playlist_add,
  690.     ID_playlist_play,
  691.     ID_playlist_playItem,
  692.     ID_playlist_togglepause,
  693.     ID_playlist_stop,
  694.     ID_playlist_next,
  695.     ID_playlist_prev,
  696.     ID_playlist_clear,
  697.     ID_playlist_removeitem
  698. };
  699. RuntimeNPObject::InvokeResult
  700. LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
  701.                                uint32_t argCount, NPVariant &result)
  702. {
  703.     /* is plugin still running */
  704.     if( isPluginRunning() )
  705.     {
  706.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  707.         libvlc_exception_t ex;
  708.         libvlc_exception_init(&ex);
  709.         switch( index )
  710.         {
  711.             // XXX FIXME this needs squashing into something much smaller
  712.             case ID_playlist_add:
  713.             {
  714.                 if( (argCount < 1) || (argCount > 3) )
  715.                     return INVOKERESULT_NO_SUCH_METHOD;
  716.                 char *url = NULL;
  717.                 // grab URL
  718.                 if( NPVARIANT_IS_NULL(args[0]) )
  719.                     return INVOKERESULT_NO_SUCH_METHOD;
  720.                 if( NPVARIANT_IS_STRING(args[0]) )
  721.                 {
  722.                     char *s = stringValue(NPVARIANT_TO_STRING(args[0]));
  723.                     if( s )
  724.                     {
  725.                         url = p_plugin->getAbsoluteURL(s);
  726.                         if( url )
  727.                             free(s);
  728.                         else
  729.                             // problem with combining url, use argument
  730.                             url = s;
  731.                     }
  732.                     else
  733.                         return INVOKERESULT_OUT_OF_MEMORY;
  734.                 }
  735.                 else
  736.                     return INVOKERESULT_NO_SUCH_METHOD;
  737.                 char *name = NULL;
  738.                 // grab name if available
  739.                 if( argCount > 1 )
  740.                 {
  741.                     if( NPVARIANT_IS_NULL(args[1]) )
  742.                     {
  743.                         // do nothing
  744.                     }
  745.                     else if( NPVARIANT_IS_STRING(args[1]) )
  746.                     {
  747.                         name = stringValue(NPVARIANT_TO_STRING(args[1]));
  748.                     }
  749.                     else
  750.                     {
  751.                         free(url);
  752.                         return INVOKERESULT_INVALID_VALUE;
  753.                     }
  754.                 }
  755.                 int i_options = 0;
  756.                 char** ppsz_options = NULL;
  757.                 // grab options if available
  758.                 if( argCount > 2 )
  759.                 {
  760.                     if( NPVARIANT_IS_NULL(args[2]) )
  761.                     {
  762.                         // do nothing
  763.                     }
  764.                     else if( NPVARIANT_IS_STRING(args[2]) )
  765.                     {
  766.                         parseOptions(NPVARIANT_TO_STRING(args[2]),
  767.                                      &i_options, &ppsz_options);
  768.                     }
  769.                     else if( NPVARIANT_IS_OBJECT(args[2]) )
  770.                     {
  771.                         parseOptions(NPVARIANT_TO_OBJECT(args[2]),
  772.                                      &i_options, &ppsz_options);
  773.                     }
  774.                     else
  775.                     {
  776.                         free(url);
  777.                         free(name);
  778.                         return INVOKERESULT_INVALID_VALUE;
  779.                     }
  780.                 }
  781.                 int item = p_plugin->playlist_add_extended_untrusted(url, name, i_options,
  782.                                const_cast<const char **>(ppsz_options), &ex);
  783.                 free(url);
  784.                 free(name);
  785.                 for( int i=0; i< i_options; ++i )
  786.                 {
  787.                     free(ppsz_options[i]);
  788.                 }
  789.                 free(ppsz_options);
  790.                 RETURN_ON_EXCEPTION(this,ex);
  791.                 INT32_TO_NPVARIANT(item, result);
  792.                 return INVOKERESULT_NO_ERROR;
  793.             }
  794.             case ID_playlist_play:
  795.                 if( argCount == 0 )
  796.                 {
  797.                     p_plugin->playlist_play(&ex);
  798.                     RETURN_ON_EXCEPTION(this,ex);
  799.                     VOID_TO_NPVARIANT(result);
  800.                     return INVOKERESULT_NO_ERROR;
  801.                 }
  802.                 return INVOKERESULT_NO_SUCH_METHOD;
  803.             case ID_playlist_playItem:
  804.                 if( (argCount == 1) && isNumberValue(args[0]) )
  805.                 {
  806.                     p_plugin->playlist_play_item(numberValue(args[0]),&ex);
  807.                     RETURN_ON_EXCEPTION(this,ex);
  808.                     VOID_TO_NPVARIANT(result);
  809.                     return INVOKERESULT_NO_ERROR;
  810.                 }
  811.                 return INVOKERESULT_NO_SUCH_METHOD;
  812.             case ID_playlist_togglepause:
  813.                 if( argCount == 0 )
  814.                 {
  815.                     p_plugin->playlist_pause(&ex);
  816.                     RETURN_ON_EXCEPTION(this,ex);
  817.                     VOID_TO_NPVARIANT(result);
  818.                     return INVOKERESULT_NO_ERROR;
  819.                 }
  820.                 return INVOKERESULT_NO_SUCH_METHOD;
  821.             case ID_playlist_stop:
  822.                 if( argCount == 0 )
  823.                 {
  824.                     p_plugin->playlist_stop(&ex);
  825.                     RETURN_ON_EXCEPTION(this,ex);
  826.                     VOID_TO_NPVARIANT(result);
  827.                     return INVOKERESULT_NO_ERROR;
  828.                 }
  829.                 return INVOKERESULT_NO_SUCH_METHOD;
  830.             case ID_playlist_next:
  831.                 if( argCount == 0 )
  832.                 {
  833.                     p_plugin->playlist_next(&ex);
  834.                     RETURN_ON_EXCEPTION(this,ex);
  835.                     VOID_TO_NPVARIANT(result);
  836.                     return INVOKERESULT_NO_ERROR;
  837.                 }
  838.                 return INVOKERESULT_NO_SUCH_METHOD;
  839.             case ID_playlist_prev:
  840.                 if( argCount == 0 )
  841.                 {
  842.                     p_plugin->playlist_prev(&ex);
  843.                     RETURN_ON_EXCEPTION(this,ex);
  844.                     VOID_TO_NPVARIANT(result);
  845.                     return INVOKERESULT_NO_ERROR;
  846.                 }
  847.                 return INVOKERESULT_NO_SUCH_METHOD;
  848.             case ID_playlist_clear: /* deprecated */
  849.                 if( argCount == 0 )
  850.                 {
  851.                     p_plugin->playlist_clear(&ex);
  852.                     RETURN_ON_EXCEPTION(this,ex);
  853.                     VOID_TO_NPVARIANT(result);
  854.                     return INVOKERESULT_NO_ERROR;
  855.                 }
  856.                 return INVOKERESULT_NO_SUCH_METHOD;
  857.             case ID_playlist_removeitem: /* deprecated */
  858.                 if( (argCount == 1) && isNumberValue(args[0]) )
  859.                 {
  860.                     p_plugin->playlist_delete_item(numberValue(args[0]), &ex);
  861.                     RETURN_ON_EXCEPTION(this,ex);
  862.                     VOID_TO_NPVARIANT(result);
  863.                     return INVOKERESULT_NO_ERROR;
  864.                 }
  865.                 return INVOKERESULT_NO_SUCH_METHOD;
  866.             default:
  867.                 ;
  868.         }
  869.     }
  870.     return INVOKERESULT_GENERIC_ERROR;
  871. }
  872. // XXX FIXME The new playlist_add creates a media instance and feeds it
  873. // XXX FIXME these options one at a time, so this hunk of code does lots
  874. // XXX FIXME of unnecessairy work. Break out something that can do one
  875. // XXX FIXME option at a time and doesn't need to realloc().
  876. // XXX FIXME Same for the other version of parseOptions.
  877. void LibvlcPlaylistNPObject::parseOptions(const NPString &nps,
  878.                                          int *i_options, char*** ppsz_options)
  879. {
  880.     if( nps.utf8length )
  881.     {
  882.         char *s = stringValue(nps);
  883.         char *val = s;
  884.         if( val )
  885.         {
  886.             long capacity = 16;
  887.             char **options = (char **)malloc(capacity*sizeof(char *));
  888.             if( options )
  889.             {
  890.                 int nOptions = 0;
  891.                 char *end = val + nps.utf8length;
  892.                 while( val < end )
  893.                 {
  894.                     // skip leading blanks
  895.                     while( (val < end)
  896.                         && ((*val == ' ' ) || (*val == 't')) )
  897.                         ++val;
  898.                     char *start = val;
  899.                     // skip till we get a blank character
  900.                     while( (val < end)
  901.                         && (*val != ' ' )
  902.                         && (*val != 't') )
  903.                     {
  904.                         char c = *(val++);
  905.                         if( (''' == c) || ('"' == c) )
  906.                         {
  907.                             // skip till end of string
  908.                             while( (val < end) && (*(val++) != c ) );
  909.                         }
  910.                     }
  911.                     if( val > start )
  912.                     {
  913.                         if( nOptions == capacity )
  914.                         {
  915.                             capacity += 16;
  916.                             char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
  917.                             if( ! moreOptions )
  918.                             {
  919.                                 /* failed to allocate more memory */
  920.                                 free(s);
  921.                                 /* return what we got so far */
  922.                                 *i_options = nOptions;
  923.                                 *ppsz_options = options;
  924.                                 return;
  925.                             }
  926.                             options = moreOptions;
  927.                         }
  928.                         *(val++) = '';
  929.                         options[nOptions++] = strdup(start);
  930.                     }
  931.                     else
  932.                         // must be end of string
  933.                         break;
  934.                 }
  935.                 *i_options = nOptions;
  936.                 *ppsz_options = options;
  937.             }
  938.             free(s);
  939.         }
  940.     }
  941. }
  942. // XXX FIXME See comment at the other parseOptions variant.
  943. void LibvlcPlaylistNPObject::parseOptions(NPObject *obj, int *i_options,
  944.                                           char*** ppsz_options)
  945. {
  946.     /* WARNING: Safari does not implement NPN_HasProperty/NPN_HasMethod */
  947.     NPVariant value;
  948.     /* we are expecting to have a Javascript Array object */
  949.     NPIdentifier propId = NPN_GetStringIdentifier("length");
  950.     if( NPN_GetProperty(_instance, obj, propId, &value) )
  951.     {
  952.         int count = numberValue(value);
  953.         NPN_ReleaseVariantValue(&value);
  954.         if( count )
  955.         {
  956.             long capacity = 16;
  957.             char **options = (char **)malloc(capacity*sizeof(char *));
  958.             if( options )
  959.             {
  960.                 int nOptions = 0;
  961.                 while( nOptions < count )
  962.                 {
  963.                     propId = NPN_GetIntIdentifier(nOptions);
  964.                     if( ! NPN_GetProperty(_instance, obj, propId, &value) )
  965.                         /* return what we got so far */
  966.                         break;
  967.                     if( ! NPVARIANT_IS_STRING(value) )
  968.                     {
  969.                         /* return what we got so far */
  970.                         NPN_ReleaseVariantValue(&value);
  971.                         break;
  972.                     }
  973.                     if( nOptions == capacity )
  974.                     {
  975.                         capacity += 16;
  976.                         char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
  977.                         if( ! moreOptions )
  978.                         {
  979.                             /* failed to allocate more memory */
  980.                             NPN_ReleaseVariantValue(&value);
  981.                             /* return what we got so far */
  982.                             *i_options = nOptions;
  983.                             *ppsz_options = options;
  984.                             break;
  985.                         }
  986.                         options = moreOptions;
  987.                     }
  988.                     options[nOptions++] = stringValue(value);
  989.                     NPN_ReleaseVariantValue(&value);
  990.                 }
  991.                 *i_options = nOptions;
  992.                 *ppsz_options = options;
  993.             }
  994.         }
  995.     }
  996. }
  997. /*
  998. ** implementation of libvlc video object
  999. */
  1000. const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] =
  1001. {
  1002.     "fullscreen",
  1003.     "height",
  1004.     "width",
  1005.     "aspectRatio",
  1006.     "subtitle",
  1007.     "crop",
  1008.     "teletext"
  1009. };
  1010. enum LibvlcVideoNPObjectPropertyIds
  1011. {
  1012.     ID_video_fullscreen,
  1013.     ID_video_height,
  1014.     ID_video_width,
  1015.     ID_video_aspectratio,
  1016.     ID_video_subtitle,
  1017.     ID_video_crop,
  1018.     ID_video_teletext
  1019. };
  1020. COUNTNAMES(LibvlcVideoNPObject,propertyCount,propertyNames);
  1021. RuntimeNPObject::InvokeResult
  1022. LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
  1023. {
  1024.     /* is plugin still running */
  1025.     if( isPluginRunning() )
  1026.     {
  1027.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  1028.         libvlc_exception_t ex;
  1029.         libvlc_exception_init(&ex);
  1030.         libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
  1031.         RETURN_ON_EXCEPTION(this,ex);
  1032.         switch( index )
  1033.         {
  1034.             case ID_video_fullscreen:
  1035.             {
  1036.                 int val = p_plugin->get_fullscreen(&ex);
  1037.                 RETURN_ON_EXCEPTION(this,ex);
  1038.                 BOOLEAN_TO_NPVARIANT(val, result);
  1039.                 return INVOKERESULT_NO_ERROR;
  1040.             }
  1041.             case ID_video_height:
  1042.             {
  1043.                 int val = libvlc_video_get_height(p_md, &ex);
  1044.                 RETURN_ON_EXCEPTION(this,ex);
  1045.                 INT32_TO_NPVARIANT(val, result);
  1046.                 return INVOKERESULT_NO_ERROR;
  1047.             }
  1048.             case ID_video_width:
  1049.             {
  1050.                 int val = libvlc_video_get_width(p_md, &ex);
  1051.                 RETURN_ON_EXCEPTION(this,ex);
  1052.                 INT32_TO_NPVARIANT(val, result);
  1053.                 return INVOKERESULT_NO_ERROR;
  1054.             }
  1055.             case ID_video_aspectratio:
  1056.             {
  1057.                 NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
  1058.                 RETURN_ON_EXCEPTION(this,ex);
  1059.                 if( !psz_aspect )
  1060.                     return INVOKERESULT_GENERIC_ERROR;
  1061.                 STRINGZ_TO_NPVARIANT(psz_aspect, result);
  1062.                 return INVOKERESULT_NO_ERROR;
  1063.             }
  1064.             case ID_video_subtitle:
  1065.             {
  1066.                 int i_spu = libvlc_video_get_spu(p_md, &ex);
  1067.                 RETURN_ON_EXCEPTION(this,ex);
  1068.                 INT32_TO_NPVARIANT(i_spu, result);
  1069.                 return INVOKERESULT_NO_ERROR;
  1070.             }
  1071.             case ID_video_crop:
  1072.             {
  1073.                 NPUTF8 *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
  1074.                 RETURN_ON_EXCEPTION(this,ex);
  1075.                 if( !psz_geometry )
  1076.                     return INVOKERESULT_GENERIC_ERROR;
  1077.                 STRINGZ_TO_NPVARIANT(psz_geometry, result);
  1078.                 return INVOKERESULT_NO_ERROR;
  1079.             }
  1080.             case ID_video_teletext:
  1081.             {
  1082.                 int i_page = libvlc_video_get_teletext(p_md, &ex);
  1083.                 RETURN_ON_EXCEPTION(this,ex);
  1084.                 INT32_TO_NPVARIANT(i_page, result);
  1085.                 return INVOKERESULT_NO_ERROR;
  1086.             }
  1087.         }
  1088.     }
  1089.     return INVOKERESULT_GENERIC_ERROR;
  1090. }
  1091. RuntimeNPObject::InvokeResult
  1092. LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
  1093. {
  1094.     /* is plugin still running */
  1095.     if( isPluginRunning() )
  1096.     {
  1097.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  1098.         libvlc_exception_t ex;
  1099.         libvlc_exception_init(&ex);
  1100.         libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
  1101.         RETURN_ON_EXCEPTION(this,ex);
  1102.         switch( index )
  1103.         {
  1104.             case ID_video_fullscreen:
  1105.             {
  1106.                 if( ! NPVARIANT_IS_BOOLEAN(value) )
  1107.                 {
  1108.                     return INVOKERESULT_INVALID_VALUE;
  1109.                 }
  1110.                 int val = NPVARIANT_TO_BOOLEAN(value);
  1111.                 p_plugin->set_fullscreen(val, &ex);
  1112.                 RETURN_ON_EXCEPTION(this,ex);
  1113.                 return INVOKERESULT_NO_ERROR;
  1114.             }
  1115.             case ID_video_aspectratio:
  1116.             {
  1117.                 char *psz_aspect = NULL;
  1118.                 if( ! NPVARIANT_IS_STRING(value) )
  1119.                 {
  1120.                     return INVOKERESULT_INVALID_VALUE;
  1121.                 }
  1122.                 psz_aspect = stringValue(NPVARIANT_TO_STRING(value));
  1123.                 if( !psz_aspect )
  1124.                 {
  1125.                     return INVOKERESULT_GENERIC_ERROR;
  1126.                 }
  1127.                 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
  1128.                 free(psz_aspect);
  1129.                 RETURN_ON_EXCEPTION(this,ex);
  1130.                 return INVOKERESULT_NO_ERROR;
  1131.             }
  1132.             case ID_video_subtitle:
  1133.             {
  1134.                 if( isNumberValue(value) )
  1135.                 {
  1136.                     libvlc_video_set_spu(p_md, numberValue(value), &ex);
  1137.                     RETURN_ON_EXCEPTION(this,ex);
  1138.                     return INVOKERESULT_NO_ERROR;
  1139.                 }
  1140.                 return INVOKERESULT_INVALID_VALUE;
  1141.             }
  1142.             case ID_video_crop:
  1143.             {
  1144.                 char *psz_geometry = NULL;
  1145.                 if( ! NPVARIANT_IS_STRING(value) )
  1146.                 {
  1147.                     return INVOKERESULT_INVALID_VALUE;
  1148.                 }
  1149.                 psz_geometry = stringValue(NPVARIANT_TO_STRING(value));
  1150.                 if( !psz_geometry )
  1151.                 {
  1152.                     return INVOKERESULT_GENERIC_ERROR;
  1153.                 }
  1154.                 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
  1155.                 free(psz_geometry);
  1156.                 RETURN_ON_EXCEPTION(this,ex);
  1157.                 return INVOKERESULT_NO_ERROR;
  1158.             }
  1159.             case ID_video_teletext:
  1160.             {
  1161.                 if( isNumberValue(value) )
  1162.                 {
  1163.                     libvlc_video_set_teletext(p_md, numberValue(value), &ex);
  1164.                     RETURN_ON_EXCEPTION(this,ex);
  1165.                     return INVOKERESULT_NO_ERROR;
  1166.                 }
  1167.                 return INVOKERESULT_INVALID_VALUE;
  1168.             }
  1169.         }
  1170.     }
  1171.     return INVOKERESULT_GENERIC_ERROR;
  1172. }
  1173. const NPUTF8 * const LibvlcVideoNPObject::methodNames[] =
  1174. {
  1175.     "toggleFullscreen",
  1176.     "toggleTeletext"
  1177. };
  1178. COUNTNAMES(LibvlcVideoNPObject,methodCount,methodNames);
  1179. enum LibvlcVideoNPObjectMethodIds
  1180. {
  1181.     ID_video_togglefullscreen,
  1182.     ID_video_toggleteletext
  1183. };
  1184. RuntimeNPObject::InvokeResult
  1185. LibvlcVideoNPObject::invoke(int index, const NPVariant *args,
  1186.                             uint32_t argCount, NPVariant &result)
  1187. {
  1188.     /* is plugin still running */
  1189.     if( isPluginRunning() )
  1190.     {
  1191.         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
  1192.         libvlc_exception_t ex;
  1193.         libvlc_exception_init(&ex);
  1194.         libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
  1195.         RETURN_ON_EXCEPTION(this,ex);
  1196.         switch( index )
  1197.         {
  1198.             case ID_video_togglefullscreen:
  1199.                 if( argCount == 0 )
  1200.                 {
  1201.                     p_plugin->toggle_fullscreen(&ex);
  1202.                     RETURN_ON_EXCEPTION(this,ex);
  1203.                     VOID_TO_NPVARIANT(result);
  1204.                     return INVOKERESULT_NO_ERROR;
  1205.                 }
  1206.                 return INVOKERESULT_NO_SUCH_METHOD;
  1207.             case ID_video_toggleteletext:
  1208.                 if( argCount == 0 )
  1209.                 {
  1210.                     libvlc_toggle_teletext(p_md, &ex);
  1211.                     RETURN_ON_EXCEPTION(this,ex);
  1212.                     VOID_TO_NPVARIANT(result);
  1213.                     return INVOKERESULT_NO_ERROR;
  1214.                 }
  1215.                 return INVOKERESULT_NO_SUCH_METHOD;
  1216.             default:
  1217.                 return INVOKERESULT_NO_SUCH_METHOD;
  1218.         }
  1219.     }
  1220.     return INVOKERESULT_GENERIC_ERROR;
  1221. }