1 /*****************************************************************************
2 * npolibvlc.cpp: official Javascript APIs
3 *****************************************************************************
4 * Copyright (C) 2002-2009 the VideoLAN team
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
7 * Jan Paul Dinger <jpd@m2x.nl>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
31 #ifdef HAVE_MOZILLA_CONFIG_H
32 # include <mozilla-config.h>
35 #include "vlcplugin.h"
36 #include "npolibvlc.h"
39 ** Local helper macros and function
41 #define COUNTNAMES(a,b,c) const int a::b = sizeof(a::c)/sizeof(NPUTF8 *)
42 #define RETURN_ON_EXCEPTION(this,ex) \
43 do { if( libvlc_exception_raised(&ex) ) \
45 NPN_SetException(this, libvlc_exception_get_message(&ex)); \
46 libvlc_exception_clear(&ex); \
47 return INVOKERESULT_GENERIC_ERROR; \
51 ** implementation of libvlc root object
54 LibvlcRootNPObject::~LibvlcRootNPObject()
57 ** When the plugin is destroyed, firefox takes it upon itself to
58 ** destroy all 'live' script objects and ignores refcounting.
59 ** Therefore we cannot safely assume that refcounting will control
60 ** lifespan of objects. Hence they are only lazily created on
61 ** request, so that firefox can take ownership, and are not released
62 ** when the plugin is destroyed.
66 if( audioObj ) NPN_ReleaseObject(audioObj);
67 if( inputObj ) NPN_ReleaseObject(inputObj);
68 if( playlistObj ) NPN_ReleaseObject(playlistObj);
69 if( videoObj ) NPN_ReleaseObject(videoObj);
73 const NPUTF8 * const LibvlcRootNPObject::propertyNames[] =
81 COUNTNAMES(LibvlcRootNPObject,propertyCount,propertyNames);
83 enum LibvlcRootNPObjectPropertyIds
92 RuntimeNPObject::InvokeResult
93 LibvlcRootNPObject::getProperty(int index, NPVariant &result)
95 /* is plugin still running */
96 if( isPluginRunning() )
101 // create child object in lazyman fashion to avoid
102 // ownership problem with firefox
104 audioObj = NPN_CreateObject(_instance,
105 RuntimeNPClass<LibvlcAudioNPObject>::getClass());
106 OBJECT_TO_NPVARIANT(NPN_RetainObject(audioObj), result);
107 return INVOKERESULT_NO_ERROR;
109 // create child object in lazyman fashion to avoid
110 // ownership problem with firefox
112 inputObj = NPN_CreateObject(_instance,
113 RuntimeNPClass<LibvlcInputNPObject>::getClass());
114 OBJECT_TO_NPVARIANT(NPN_RetainObject(inputObj), result);
115 return INVOKERESULT_NO_ERROR;
116 case ID_root_playlist:
117 // create child object in lazyman fashion to avoid
118 // ownership problem with firefox
120 playlistObj = NPN_CreateObject(_instance,
121 RuntimeNPClass<LibvlcPlaylistNPObject>::getClass());
122 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistObj), result);
123 return INVOKERESULT_NO_ERROR;
125 // create child object in lazyman fashion to avoid
126 // ownership problem with firefox
128 videoObj = NPN_CreateObject(_instance,
129 RuntimeNPClass<LibvlcVideoNPObject>::getClass());
130 OBJECT_TO_NPVARIANT(NPN_RetainObject(videoObj), result);
131 return INVOKERESULT_NO_ERROR;
132 case ID_root_VersionInfo:
134 const char *s = libvlc_get_version();
136 NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);
138 return INVOKERESULT_OUT_OF_MEMORY;
140 memcpy(retval, s, len);
141 STRINGN_TO_NPVARIANT(retval, len, result);
142 return INVOKERESULT_NO_ERROR;
148 return INVOKERESULT_GENERIC_ERROR;
151 const NPUTF8 * const LibvlcRootNPObject::methodNames[] =
155 COUNTNAMES(LibvlcRootNPObject,methodCount,methodNames);
157 enum LibvlcRootNPObjectMethodIds
162 RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index,
163 const NPVariant *args, uint32_t argCount, NPVariant &result)
165 /* is plugin still running */
166 if( isPluginRunning() )
168 libvlc_exception_t ex;
169 libvlc_exception_init(&ex);
173 case ID_root_versionInfo:
176 const char *s = libvlc_get_version();
178 NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);
180 return INVOKERESULT_OUT_OF_MEMORY;
181 memcpy(retval, s, len);
182 STRINGN_TO_NPVARIANT(retval, len, result);
183 return INVOKERESULT_NO_ERROR;
185 return INVOKERESULT_NO_SUCH_METHOD;
190 return INVOKERESULT_GENERIC_ERROR;
194 ** implementation of libvlc audio object
197 const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] =
204 COUNTNAMES(LibvlcAudioNPObject,propertyCount,propertyNames);
206 enum LibvlcAudioNPObjectPropertyIds
214 RuntimeNPObject::InvokeResult
215 LibvlcAudioNPObject::getProperty(int index, NPVariant &result)
217 /* is plugin still running */
218 if( isPluginRunning() )
220 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
221 libvlc_exception_t ex;
222 libvlc_exception_init(&ex);
228 bool muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex);
229 RETURN_ON_EXCEPTION(this,ex);
230 BOOLEAN_TO_NPVARIANT(muted, result);
231 return INVOKERESULT_NO_ERROR;
233 case ID_audio_volume:
235 int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex);
236 RETURN_ON_EXCEPTION(this,ex);
237 INT32_TO_NPVARIANT(volume, result);
238 return INVOKERESULT_NO_ERROR;
242 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
243 RETURN_ON_EXCEPTION(this,ex);
244 int track = libvlc_audio_get_track(p_md, &ex);
245 RETURN_ON_EXCEPTION(this,ex);
246 INT32_TO_NPVARIANT(track, result);
247 return INVOKERESULT_NO_ERROR;
249 case ID_audio_channel:
251 int channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex);
252 RETURN_ON_EXCEPTION(this,ex);
253 INT32_TO_NPVARIANT(channel, result);
254 return INVOKERESULT_NO_ERROR;
260 return INVOKERESULT_GENERIC_ERROR;
263 RuntimeNPObject::InvokeResult
264 LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)
266 /* is plugin still running */
267 if( isPluginRunning() )
269 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
270 libvlc_exception_t ex;
271 libvlc_exception_init(&ex);
276 if( NPVARIANT_IS_BOOLEAN(value) )
278 libvlc_audio_set_mute(p_plugin->getVLC(),
279 NPVARIANT_TO_BOOLEAN(value), &ex);
280 RETURN_ON_EXCEPTION(this,ex);
281 return INVOKERESULT_NO_ERROR;
283 return INVOKERESULT_INVALID_VALUE;
284 case ID_audio_volume:
285 if( isNumberValue(value) )
287 libvlc_audio_set_volume(p_plugin->getVLC(),
288 numberValue(value), &ex);
289 RETURN_ON_EXCEPTION(this,ex);
290 return INVOKERESULT_NO_ERROR;
292 return INVOKERESULT_INVALID_VALUE;
294 if( isNumberValue(value) )
296 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
297 RETURN_ON_EXCEPTION(this,ex);
298 libvlc_audio_set_track(p_md, numberValue(value), &ex);
299 RETURN_ON_EXCEPTION(this,ex);
300 return INVOKERESULT_NO_ERROR;
302 return INVOKERESULT_INVALID_VALUE;
303 case ID_audio_channel:
304 if( isNumberValue(value) )
306 libvlc_audio_set_channel(p_plugin->getVLC(),
307 numberValue(value), &ex);
308 RETURN_ON_EXCEPTION(this,ex);
309 return INVOKERESULT_NO_ERROR;
311 return INVOKERESULT_INVALID_VALUE;
316 return INVOKERESULT_GENERIC_ERROR;
319 const NPUTF8 * const LibvlcAudioNPObject::methodNames[] =
323 COUNTNAMES(LibvlcAudioNPObject,methodCount,methodNames);
325 enum LibvlcAudioNPObjectMethodIds
330 RuntimeNPObject::InvokeResult
331 LibvlcAudioNPObject::invoke(int index, const NPVariant *args,
332 uint32_t argCount, NPVariant &result)
334 /* is plugin still running */
335 if( isPluginRunning() )
337 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
338 libvlc_exception_t ex;
339 libvlc_exception_init(&ex);
343 case ID_audio_togglemute:
346 libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex);
347 RETURN_ON_EXCEPTION(this,ex);
348 VOID_TO_NPVARIANT(result);
349 return INVOKERESULT_NO_ERROR;
351 return INVOKERESULT_NO_SUCH_METHOD;
356 return INVOKERESULT_GENERIC_ERROR;
360 ** implementation of libvlc input object
363 const NPUTF8 * const LibvlcInputNPObject::propertyNames[] =
373 COUNTNAMES(LibvlcInputNPObject,propertyCount,propertyNames);
375 enum LibvlcInputNPObjectPropertyIds
386 RuntimeNPObject::InvokeResult
387 LibvlcInputNPObject::getProperty(int index, NPVariant &result)
389 /* is plugin still running */
390 if( isPluginRunning() )
392 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
393 libvlc_exception_t ex;
394 libvlc_exception_init(&ex);
396 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
397 if( libvlc_exception_raised(&ex) )
399 if( index != ID_input_state )
401 NPN_SetException(this, libvlc_exception_get_message(&ex));
402 libvlc_exception_clear(&ex);
403 return INVOKERESULT_GENERIC_ERROR;
407 /* for input state, return CLOSED rather than an exception */
408 INT32_TO_NPVARIANT(0, result);
409 libvlc_exception_clear(&ex);
410 return INVOKERESULT_NO_ERROR;
416 case ID_input_length:
418 double val = (double)libvlc_media_player_get_length(p_md, &ex);
419 RETURN_ON_EXCEPTION(this,ex);
420 DOUBLE_TO_NPVARIANT(val, result);
421 return INVOKERESULT_NO_ERROR;
423 case ID_input_position:
425 double val = libvlc_media_player_get_position(p_md, &ex);
426 RETURN_ON_EXCEPTION(this,ex);
427 DOUBLE_TO_NPVARIANT(val, result);
428 return INVOKERESULT_NO_ERROR;
432 double val = (double)libvlc_media_player_get_time(p_md, &ex);
433 RETURN_ON_EXCEPTION(this,ex);
434 DOUBLE_TO_NPVARIANT(val, result);
435 return INVOKERESULT_NO_ERROR;
439 int val = libvlc_media_player_get_state(p_md, &ex);
440 RETURN_ON_EXCEPTION(this,ex);
441 INT32_TO_NPVARIANT(val, result);
442 return INVOKERESULT_NO_ERROR;
446 float val = libvlc_media_player_get_rate(p_md, &ex);
447 RETURN_ON_EXCEPTION(this,ex);
448 DOUBLE_TO_NPVARIANT(val, result);
449 return INVOKERESULT_NO_ERROR;
453 double val = libvlc_media_player_get_fps(p_md, &ex);
454 RETURN_ON_EXCEPTION(this,ex);
455 DOUBLE_TO_NPVARIANT(val, result);
456 return INVOKERESULT_NO_ERROR;
458 case ID_input_hasvout:
460 bool val = p_plugin->player_has_vout(&ex);
461 RETURN_ON_EXCEPTION(this,ex);
462 BOOLEAN_TO_NPVARIANT(val, result);
463 return INVOKERESULT_NO_ERROR;
469 return INVOKERESULT_GENERIC_ERROR;
472 RuntimeNPObject::InvokeResult
473 LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
475 /* is plugin still running */
476 if( isPluginRunning() )
478 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
479 libvlc_exception_t ex;
480 libvlc_exception_init(&ex);
482 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
483 RETURN_ON_EXCEPTION(this,ex);
487 case ID_input_position:
489 if( ! NPVARIANT_IS_DOUBLE(value) )
491 return INVOKERESULT_INVALID_VALUE;
494 float val = (float)NPVARIANT_TO_DOUBLE(value);
495 libvlc_media_player_set_position(p_md, val, &ex);
496 RETURN_ON_EXCEPTION(this,ex);
497 return INVOKERESULT_NO_ERROR;
502 if( NPVARIANT_IS_INT32(value) )
503 val = (int64_t)NPVARIANT_TO_INT32(value);
504 else if( NPVARIANT_IS_DOUBLE(value) )
505 val = (int64_t)NPVARIANT_TO_DOUBLE(value);
508 return INVOKERESULT_INVALID_VALUE;
511 libvlc_media_player_set_time(p_md, val, &ex);
512 RETURN_ON_EXCEPTION(this,ex);
513 return INVOKERESULT_NO_ERROR;
518 if( NPVARIANT_IS_INT32(value) )
519 val = (float)NPVARIANT_TO_INT32(value);
520 else if( NPVARIANT_IS_DOUBLE(value) )
521 val = (float)NPVARIANT_TO_DOUBLE(value);
524 return INVOKERESULT_INVALID_VALUE;
527 libvlc_media_player_set_rate(p_md, val, &ex);
528 RETURN_ON_EXCEPTION(this,ex);
529 return INVOKERESULT_NO_ERROR;
535 return INVOKERESULT_GENERIC_ERROR;
538 const NPUTF8 * const LibvlcInputNPObject::methodNames[] =
543 COUNTNAMES(LibvlcInputNPObject,methodCount,methodNames);
546 ** implementation of libvlc playlist items object
549 const NPUTF8 * const LibvlcPlaylistItemsNPObject::propertyNames[] =
553 COUNTNAMES(LibvlcPlaylistItemsNPObject,propertyCount,propertyNames);
555 enum LibvlcPlaylistItemsNPObjectPropertyIds
557 ID_playlistitems_count,
560 RuntimeNPObject::InvokeResult
561 LibvlcPlaylistItemsNPObject::getProperty(int index, NPVariant &result)
563 /* is plugin still running */
564 if( isPluginRunning() )
566 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
567 libvlc_exception_t ex;
568 libvlc_exception_init(&ex);
572 case ID_playlistitems_count:
574 int val = p_plugin->playlist_count(&ex);
575 RETURN_ON_EXCEPTION(this,ex);
576 INT32_TO_NPVARIANT(val, result);
577 return INVOKERESULT_NO_ERROR;
583 return INVOKERESULT_GENERIC_ERROR;
586 const NPUTF8 * const LibvlcPlaylistItemsNPObject::methodNames[] =
591 COUNTNAMES(LibvlcPlaylistItemsNPObject,methodCount,methodNames);
593 enum LibvlcPlaylistItemsNPObjectMethodIds
595 ID_playlistitems_clear,
596 ID_playlistitems_remove,
599 RuntimeNPObject::InvokeResult
600 LibvlcPlaylistItemsNPObject::invoke(int index, const NPVariant *args,
601 uint32_t argCount, NPVariant &result)
603 /* is plugin still running */
604 if( isPluginRunning() )
606 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
607 libvlc_exception_t ex;
608 libvlc_exception_init(&ex);
612 case ID_playlistitems_clear:
615 p_plugin->playlist_clear(&ex);
616 RETURN_ON_EXCEPTION(this,ex);
617 VOID_TO_NPVARIANT(result);
618 return INVOKERESULT_NO_ERROR;
620 return INVOKERESULT_NO_SUCH_METHOD;
621 case ID_playlistitems_remove:
622 if( (argCount == 1) && isNumberValue(args[0]) )
624 p_plugin->playlist_delete_item(numberValue(args[0]),&ex);
625 RETURN_ON_EXCEPTION(this,ex);
626 VOID_TO_NPVARIANT(result);
627 return INVOKERESULT_NO_ERROR;
629 return INVOKERESULT_NO_SUCH_METHOD;
634 return INVOKERESULT_GENERIC_ERROR;
638 ** implementation of libvlc playlist object
641 LibvlcPlaylistNPObject::~LibvlcPlaylistNPObject()
645 if( playlistItemsObj ) NPN_ReleaseObject(playlistItemsObj);
649 const NPUTF8 * const LibvlcPlaylistNPObject::propertyNames[] =
651 "itemCount", /* deprecated */
655 COUNTNAMES(LibvlcPlaylistNPObject,propertyCount,propertyNames);
657 enum LibvlcPlaylistNPObjectPropertyIds
659 ID_playlist_itemcount,
660 ID_playlist_isplaying,
664 RuntimeNPObject::InvokeResult
665 LibvlcPlaylistNPObject::getProperty(int index, NPVariant &result)
667 /* is plugin still running */
668 if( isPluginRunning() )
670 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
671 libvlc_exception_t ex;
672 libvlc_exception_init(&ex);
676 case ID_playlist_itemcount: /* deprecated */
678 int val = p_plugin->playlist_count(&ex);
679 RETURN_ON_EXCEPTION(this,ex);
680 INT32_TO_NPVARIANT(val, result);
681 return INVOKERESULT_NO_ERROR;
683 case ID_playlist_isplaying:
685 int val = p_plugin->playlist_isplaying(&ex);
686 RETURN_ON_EXCEPTION(this,ex);
687 BOOLEAN_TO_NPVARIANT(val, result);
688 return INVOKERESULT_NO_ERROR;
690 case ID_playlist_items:
692 // create child object in lazyman fashion to avoid
693 // ownership problem with firefox
694 if( ! playlistItemsObj )
696 NPN_CreateObject(_instance, RuntimeNPClass<
697 LibvlcPlaylistItemsNPObject>::getClass());
698 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistItemsObj), result);
699 return INVOKERESULT_NO_ERROR;
705 return INVOKERESULT_GENERIC_ERROR;
708 const NPUTF8 * const LibvlcPlaylistNPObject::methodNames[] =
717 "clear", /* deprecated */
718 "removeItem", /* deprecated */
720 COUNTNAMES(LibvlcPlaylistNPObject,methodCount,methodNames);
722 enum LibvlcPlaylistNPObjectMethodIds
726 ID_playlist_playItem,
727 ID_playlist_togglepause,
732 ID_playlist_removeitem
735 RuntimeNPObject::InvokeResult
736 LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
737 uint32_t argCount, NPVariant &result)
739 /* is plugin still running */
740 if( isPluginRunning() )
742 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
743 libvlc_exception_t ex;
744 libvlc_exception_init(&ex);
748 // XXX FIXME this needs squashing into something much smaller
749 case ID_playlist_add:
751 if( (argCount < 1) || (argCount > 3) )
752 return INVOKERESULT_NO_SUCH_METHOD;
757 if( NPVARIANT_IS_STRING(args[0]) )
759 char *s = stringValue(NPVARIANT_TO_STRING(args[0]));
762 url = p_plugin->getAbsoluteURL(s);
766 // problem with combining url, use argument
770 return INVOKERESULT_OUT_OF_MEMORY;
773 return INVOKERESULT_NO_SUCH_METHOD;
777 // grab name if available
780 if( NPVARIANT_IS_NULL(args[1]) )
784 else if( NPVARIANT_IS_STRING(args[1]) )
786 name = stringValue(NPVARIANT_TO_STRING(args[1]));
791 return INVOKERESULT_INVALID_VALUE;
796 char** ppsz_options = NULL;
798 // grab options if available
801 if( NPVARIANT_IS_NULL(args[2]) )
805 else if( NPVARIANT_IS_STRING(args[2]) )
807 parseOptions(NPVARIANT_TO_STRING(args[2]),
808 &i_options, &ppsz_options);
811 else if( NPVARIANT_IS_OBJECT(args[2]) )
813 parseOptions(NPVARIANT_TO_OBJECT(args[2]),
814 &i_options, &ppsz_options);
820 return INVOKERESULT_INVALID_VALUE;
824 int item = p_plugin->playlist_add_extended_untrusted(url, name, i_options,
825 const_cast<const char **>(ppsz_options), &ex);
828 for( int i=0; i< i_options; ++i )
830 free(ppsz_options[i]);
834 RETURN_ON_EXCEPTION(this,ex);
835 INT32_TO_NPVARIANT(item, result);
836 return INVOKERESULT_NO_ERROR;
838 case ID_playlist_play:
841 p_plugin->playlist_play(&ex);
842 RETURN_ON_EXCEPTION(this,ex);
843 VOID_TO_NPVARIANT(result);
844 return INVOKERESULT_NO_ERROR;
846 return INVOKERESULT_NO_SUCH_METHOD;
847 case ID_playlist_playItem:
848 if( (argCount == 1) && isNumberValue(args[0]) )
850 p_plugin->playlist_play_item(numberValue(args[0]),&ex);
851 RETURN_ON_EXCEPTION(this,ex);
852 VOID_TO_NPVARIANT(result);
853 return INVOKERESULT_NO_ERROR;
855 return INVOKERESULT_NO_SUCH_METHOD;
856 case ID_playlist_togglepause:
859 p_plugin->playlist_pause(&ex);
860 RETURN_ON_EXCEPTION(this,ex);
861 VOID_TO_NPVARIANT(result);
862 return INVOKERESULT_NO_ERROR;
864 return INVOKERESULT_NO_SUCH_METHOD;
865 case ID_playlist_stop:
868 p_plugin->playlist_stop(&ex);
869 RETURN_ON_EXCEPTION(this,ex);
870 VOID_TO_NPVARIANT(result);
871 return INVOKERESULT_NO_ERROR;
873 return INVOKERESULT_NO_SUCH_METHOD;
874 case ID_playlist_next:
877 p_plugin->playlist_next(&ex);
878 RETURN_ON_EXCEPTION(this,ex);
879 VOID_TO_NPVARIANT(result);
880 return INVOKERESULT_NO_ERROR;
882 return INVOKERESULT_NO_SUCH_METHOD;
883 case ID_playlist_prev:
886 p_plugin->playlist_prev(&ex);
887 RETURN_ON_EXCEPTION(this,ex);
888 VOID_TO_NPVARIANT(result);
889 return INVOKERESULT_NO_ERROR;
891 return INVOKERESULT_NO_SUCH_METHOD;
892 case ID_playlist_clear: /* deprecated */
895 p_plugin->playlist_clear(&ex);
896 RETURN_ON_EXCEPTION(this,ex);
897 VOID_TO_NPVARIANT(result);
898 return INVOKERESULT_NO_ERROR;
900 return INVOKERESULT_NO_SUCH_METHOD;
901 case ID_playlist_removeitem: /* deprecated */
902 if( (argCount == 1) && isNumberValue(args[0]) )
904 p_plugin->playlist_delete_item(numberValue(args[0]), &ex);
905 RETURN_ON_EXCEPTION(this,ex);
906 VOID_TO_NPVARIANT(result);
907 return INVOKERESULT_NO_ERROR;
909 return INVOKERESULT_NO_SUCH_METHOD;
914 return INVOKERESULT_GENERIC_ERROR;
917 // XXX FIXME The new playlist_add creates a media instance and feeds it
918 // XXX FIXME these options one at a time, so this hunk of code does lots
919 // XXX FIXME of unnecessairy work. Break out something that can do one
920 // XXX FIXME option at a time and doesn't need to realloc().
921 // XXX FIXME Same for the other version of parseOptions.
923 void LibvlcPlaylistNPObject::parseOptions(const NPString &nps,
924 int *i_options, char*** ppsz_options)
928 char *s = stringValue(nps);
933 char **options = (char **)malloc(capacity*sizeof(char *));
938 char *end = val + nps.utf8length;
941 // skip leading blanks
943 && ((*val == ' ' ) || (*val == '\t')) )
947 // skip till we get a blank character
953 if( ('\'' == c) || ('"' == c) )
955 // skip till end of string
956 while( (val < end) && (*(val++) != c ) );
962 if( nOptions == capacity )
965 char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
968 /* failed to allocate more memory */
970 /* return what we got so far */
971 *i_options = nOptions;
972 *ppsz_options = options;
975 options = moreOptions;
978 options[nOptions++] = strdup(start);
981 // must be end of string
984 *i_options = nOptions;
985 *ppsz_options = options;
992 // XXX FIXME See comment at the other parseOptions variant.
993 void LibvlcPlaylistNPObject::parseOptions(NPObject *obj, int *i_options,
994 char*** ppsz_options)
996 /* WARNING: Safari does not implement NPN_HasProperty/NPN_HasMethod */
1000 /* we are expecting to have a Javascript Array object */
1001 NPIdentifier propId = NPN_GetStringIdentifier("length");
1002 if( NPN_GetProperty(_instance, obj, propId, &value) )
1004 int count = numberValue(value);
1005 NPN_ReleaseVariantValue(&value);
1010 char **options = (char **)malloc(capacity*sizeof(char *));
1015 while( nOptions < count )
1017 propId = NPN_GetIntIdentifier(nOptions);
1018 if( ! NPN_GetProperty(_instance, obj, propId, &value) )
1019 /* return what we got so far */
1022 if( ! NPVARIANT_IS_STRING(value) )
1024 /* return what we got so far */
1025 NPN_ReleaseVariantValue(&value);
1029 if( nOptions == capacity )
1032 char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
1035 /* failed to allocate more memory */
1036 NPN_ReleaseVariantValue(&value);
1037 /* return what we got so far */
1038 *i_options = nOptions;
1039 *ppsz_options = options;
1042 options = moreOptions;
1045 options[nOptions++] = stringValue(value);
1047 *i_options = nOptions;
1048 *ppsz_options = options;
1055 ** implementation of libvlc video object
1058 const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] =
1069 enum LibvlcVideoNPObjectPropertyIds
1071 ID_video_fullscreen,
1074 ID_video_aspectratio,
1079 COUNTNAMES(LibvlcVideoNPObject,propertyCount,propertyNames);
1081 RuntimeNPObject::InvokeResult
1082 LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
1084 /* is plugin still running */
1085 if( isPluginRunning() )
1087 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1088 libvlc_exception_t ex;
1089 libvlc_exception_init(&ex);
1091 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1092 RETURN_ON_EXCEPTION(this,ex);
1096 case ID_video_fullscreen:
1098 int val = p_plugin->get_fullscreen(&ex);
1099 RETURN_ON_EXCEPTION(this,ex);
1100 BOOLEAN_TO_NPVARIANT(val, result);
1101 return INVOKERESULT_NO_ERROR;
1103 case ID_video_height:
1105 int val = libvlc_video_get_height(p_md, &ex);
1106 RETURN_ON_EXCEPTION(this,ex);
1107 INT32_TO_NPVARIANT(val, result);
1108 return INVOKERESULT_NO_ERROR;
1110 case ID_video_width:
1112 int val = libvlc_video_get_width(p_md, &ex);
1113 RETURN_ON_EXCEPTION(this,ex);
1114 INT32_TO_NPVARIANT(val, result);
1115 return INVOKERESULT_NO_ERROR;
1117 case ID_video_aspectratio:
1119 NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1120 RETURN_ON_EXCEPTION(this,ex);
1122 return INVOKERESULT_GENERIC_ERROR;
1124 STRINGZ_TO_NPVARIANT(psz_aspect, result);
1125 return INVOKERESULT_NO_ERROR;
1127 case ID_video_subtitle:
1129 int i_spu = libvlc_video_get_spu(p_md, &ex);
1130 RETURN_ON_EXCEPTION(this,ex);
1131 INT32_TO_NPVARIANT(i_spu, result);
1132 return INVOKERESULT_NO_ERROR;
1136 NPUTF8 *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1137 RETURN_ON_EXCEPTION(this,ex);
1139 return INVOKERESULT_GENERIC_ERROR;
1141 STRINGZ_TO_NPVARIANT(psz_geometry, result);
1142 return INVOKERESULT_NO_ERROR;
1144 case ID_video_teletext:
1146 int i_page = libvlc_video_get_teletext(p_md, &ex);
1147 RETURN_ON_EXCEPTION(this,ex);
1148 INT32_TO_NPVARIANT(i_page, result);
1149 return INVOKERESULT_NO_ERROR;
1153 return INVOKERESULT_GENERIC_ERROR;
1156 RuntimeNPObject::InvokeResult
1157 LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
1159 /* is plugin still running */
1160 if( isPluginRunning() )
1162 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1163 libvlc_exception_t ex;
1164 libvlc_exception_init(&ex);
1166 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1167 RETURN_ON_EXCEPTION(this,ex);
1171 case ID_video_fullscreen:
1173 if( ! NPVARIANT_IS_BOOLEAN(value) )
1175 return INVOKERESULT_INVALID_VALUE;
1178 int val = NPVARIANT_TO_BOOLEAN(value);
1179 p_plugin->set_fullscreen(val, &ex);
1180 RETURN_ON_EXCEPTION(this,ex);
1181 return INVOKERESULT_NO_ERROR;
1183 case ID_video_aspectratio:
1185 char *psz_aspect = NULL;
1187 if( ! NPVARIANT_IS_STRING(value) )
1189 return INVOKERESULT_INVALID_VALUE;
1192 psz_aspect = stringValue(NPVARIANT_TO_STRING(value));
1195 return INVOKERESULT_GENERIC_ERROR;
1198 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
1200 RETURN_ON_EXCEPTION(this,ex);
1202 return INVOKERESULT_NO_ERROR;
1204 case ID_video_subtitle:
1206 if( isNumberValue(value) )
1208 libvlc_video_set_spu(p_md, numberValue(value), &ex);
1209 RETURN_ON_EXCEPTION(this,ex);
1211 return INVOKERESULT_NO_ERROR;
1213 return INVOKERESULT_INVALID_VALUE;
1217 char *psz_geometry = NULL;
1219 if( ! NPVARIANT_IS_STRING(value) )
1221 return INVOKERESULT_INVALID_VALUE;
1224 psz_geometry = stringValue(NPVARIANT_TO_STRING(value));
1227 return INVOKERESULT_GENERIC_ERROR;
1230 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
1232 RETURN_ON_EXCEPTION(this,ex);
1234 return INVOKERESULT_NO_ERROR;
1236 case ID_video_teletext:
1238 if( isNumberValue(value) )
1240 libvlc_video_set_teletext(p_md, numberValue(value), &ex);
1241 RETURN_ON_EXCEPTION(this,ex);
1243 return INVOKERESULT_NO_ERROR;
1245 return INVOKERESULT_INVALID_VALUE;
1249 return INVOKERESULT_GENERIC_ERROR;
1252 const NPUTF8 * const LibvlcVideoNPObject::methodNames[] =
1257 COUNTNAMES(LibvlcVideoNPObject,methodCount,methodNames);
1259 enum LibvlcVideoNPObjectMethodIds
1261 ID_video_togglefullscreen,
1262 ID_video_toggleteletext
1265 RuntimeNPObject::InvokeResult
1266 LibvlcVideoNPObject::invoke(int index, const NPVariant *args,
1267 uint32_t argCount, NPVariant &result)
1269 /* is plugin still running */
1270 if( isPluginRunning() )
1272 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1273 libvlc_exception_t ex;
1274 libvlc_exception_init(&ex);
1276 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1277 RETURN_ON_EXCEPTION(this,ex);
1281 case ID_video_togglefullscreen:
1284 p_plugin->toggle_fullscreen(&ex);
1285 RETURN_ON_EXCEPTION(this,ex);
1286 VOID_TO_NPVARIANT(result);
1287 return INVOKERESULT_NO_ERROR;
1289 return INVOKERESULT_NO_SUCH_METHOD;
1290 case ID_video_toggleteletext:
1293 libvlc_toggle_teletext(p_md, &ex);
1294 RETURN_ON_EXCEPTION(this,ex);
1295 VOID_TO_NPVARIANT(result);
1296 return INVOKERESULT_NO_ERROR;
1298 return INVOKERESULT_NO_SUCH_METHOD;
1300 return INVOKERESULT_NO_SUCH_METHOD;
1303 return INVOKERESULT_GENERIC_ERROR;