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 * JP 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:
133 return invokeResultString(libvlc_get_version(),result);
138 return INVOKERESULT_GENERIC_ERROR;
141 const NPUTF8 * const LibvlcRootNPObject::methodNames[] =
145 COUNTNAMES(LibvlcRootNPObject,methodCount,methodNames);
147 enum LibvlcRootNPObjectMethodIds
152 RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index,
153 const NPVariant *args, uint32_t argCount, NPVariant &result)
155 /* is plugin still running */
156 if( isPluginRunning() )
158 libvlc_exception_t ex;
159 libvlc_exception_init(&ex);
163 case ID_root_versionInfo:
165 return INVOKERESULT_NO_SUCH_METHOD;
166 return invokeResultString(libvlc_get_version(),result);
171 return INVOKERESULT_GENERIC_ERROR;
175 ** implementation of libvlc audio object
178 const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] =
185 COUNTNAMES(LibvlcAudioNPObject,propertyCount,propertyNames);
187 enum LibvlcAudioNPObjectPropertyIds
195 RuntimeNPObject::InvokeResult
196 LibvlcAudioNPObject::getProperty(int index, NPVariant &result)
198 /* is plugin still running */
199 if( isPluginRunning() )
201 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
202 libvlc_exception_t ex;
203 libvlc_exception_init(&ex);
209 bool muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex);
210 RETURN_ON_EXCEPTION(this,ex);
211 BOOLEAN_TO_NPVARIANT(muted, result);
212 return INVOKERESULT_NO_ERROR;
214 case ID_audio_volume:
216 int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex);
217 RETURN_ON_EXCEPTION(this,ex);
218 INT32_TO_NPVARIANT(volume, result);
219 return INVOKERESULT_NO_ERROR;
223 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
224 RETURN_ON_EXCEPTION(this,ex);
225 int track = libvlc_audio_get_track(p_md, &ex);
226 RETURN_ON_EXCEPTION(this,ex);
227 INT32_TO_NPVARIANT(track, result);
228 return INVOKERESULT_NO_ERROR;
230 case ID_audio_channel:
232 int channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex);
233 RETURN_ON_EXCEPTION(this,ex);
234 INT32_TO_NPVARIANT(channel, result);
235 return INVOKERESULT_NO_ERROR;
241 return INVOKERESULT_GENERIC_ERROR;
244 RuntimeNPObject::InvokeResult
245 LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)
247 /* is plugin still running */
248 if( isPluginRunning() )
250 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
251 libvlc_exception_t ex;
252 libvlc_exception_init(&ex);
257 if( NPVARIANT_IS_BOOLEAN(value) )
259 libvlc_audio_set_mute(p_plugin->getVLC(),
260 NPVARIANT_TO_BOOLEAN(value), &ex);
261 RETURN_ON_EXCEPTION(this,ex);
262 return INVOKERESULT_NO_ERROR;
264 return INVOKERESULT_INVALID_VALUE;
265 case ID_audio_volume:
266 if( isNumberValue(value) )
268 libvlc_audio_set_volume(p_plugin->getVLC(),
269 numberValue(value), &ex);
270 RETURN_ON_EXCEPTION(this,ex);
271 return INVOKERESULT_NO_ERROR;
273 return INVOKERESULT_INVALID_VALUE;
275 if( isNumberValue(value) )
277 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
278 RETURN_ON_EXCEPTION(this,ex);
279 libvlc_audio_set_track(p_md, numberValue(value), &ex);
280 RETURN_ON_EXCEPTION(this,ex);
281 return INVOKERESULT_NO_ERROR;
283 return INVOKERESULT_INVALID_VALUE;
284 case ID_audio_channel:
285 if( isNumberValue(value) )
287 libvlc_audio_set_channel(p_plugin->getVLC(),
288 numberValue(value), &ex);
289 RETURN_ON_EXCEPTION(this,ex);
290 return INVOKERESULT_NO_ERROR;
292 return INVOKERESULT_INVALID_VALUE;
297 return INVOKERESULT_GENERIC_ERROR;
300 const NPUTF8 * const LibvlcAudioNPObject::methodNames[] =
304 COUNTNAMES(LibvlcAudioNPObject,methodCount,methodNames);
306 enum LibvlcAudioNPObjectMethodIds
311 RuntimeNPObject::InvokeResult
312 LibvlcAudioNPObject::invoke(int index, const NPVariant *args,
313 uint32_t argCount, NPVariant &result)
315 /* is plugin still running */
316 if( isPluginRunning() )
318 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
319 libvlc_exception_t ex;
320 libvlc_exception_init(&ex);
324 case ID_audio_togglemute:
327 libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex);
328 RETURN_ON_EXCEPTION(this,ex);
329 VOID_TO_NPVARIANT(result);
330 return INVOKERESULT_NO_ERROR;
332 return INVOKERESULT_NO_SUCH_METHOD;
337 return INVOKERESULT_GENERIC_ERROR;
341 ** implementation of libvlc input object
344 const NPUTF8 * const LibvlcInputNPObject::propertyNames[] =
354 COUNTNAMES(LibvlcInputNPObject,propertyCount,propertyNames);
356 enum LibvlcInputNPObjectPropertyIds
367 RuntimeNPObject::InvokeResult
368 LibvlcInputNPObject::getProperty(int index, NPVariant &result)
370 /* is plugin still running */
371 if( isPluginRunning() )
373 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
374 libvlc_exception_t ex;
375 libvlc_exception_init(&ex);
377 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
378 if( libvlc_exception_raised(&ex) )
380 if( index != ID_input_state )
382 NPN_SetException(this, libvlc_exception_get_message(&ex));
383 libvlc_exception_clear(&ex);
384 return INVOKERESULT_GENERIC_ERROR;
388 /* for input state, return CLOSED rather than an exception */
389 INT32_TO_NPVARIANT(0, result);
390 libvlc_exception_clear(&ex);
391 return INVOKERESULT_NO_ERROR;
397 case ID_input_length:
399 double val = (double)libvlc_media_player_get_length(p_md, &ex);
400 RETURN_ON_EXCEPTION(this,ex);
401 DOUBLE_TO_NPVARIANT(val, result);
402 return INVOKERESULT_NO_ERROR;
404 case ID_input_position:
406 double val = libvlc_media_player_get_position(p_md, &ex);
407 RETURN_ON_EXCEPTION(this,ex);
408 DOUBLE_TO_NPVARIANT(val, result);
409 return INVOKERESULT_NO_ERROR;
413 double val = (double)libvlc_media_player_get_time(p_md, &ex);
414 RETURN_ON_EXCEPTION(this,ex);
415 DOUBLE_TO_NPVARIANT(val, result);
416 return INVOKERESULT_NO_ERROR;
420 int val = libvlc_media_player_get_state(p_md, &ex);
421 RETURN_ON_EXCEPTION(this,ex);
422 INT32_TO_NPVARIANT(val, result);
423 return INVOKERESULT_NO_ERROR;
427 float val = libvlc_media_player_get_rate(p_md, &ex);
428 RETURN_ON_EXCEPTION(this,ex);
429 DOUBLE_TO_NPVARIANT(val, result);
430 return INVOKERESULT_NO_ERROR;
434 double val = libvlc_media_player_get_fps(p_md, &ex);
435 RETURN_ON_EXCEPTION(this,ex);
436 DOUBLE_TO_NPVARIANT(val, result);
437 return INVOKERESULT_NO_ERROR;
439 case ID_input_hasvout:
441 bool val = p_plugin->player_has_vout(&ex);
442 RETURN_ON_EXCEPTION(this,ex);
443 BOOLEAN_TO_NPVARIANT(val, result);
444 return INVOKERESULT_NO_ERROR;
450 return INVOKERESULT_GENERIC_ERROR;
453 RuntimeNPObject::InvokeResult
454 LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
456 /* is plugin still running */
457 if( isPluginRunning() )
459 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
460 libvlc_exception_t ex;
461 libvlc_exception_init(&ex);
463 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
464 RETURN_ON_EXCEPTION(this,ex);
468 case ID_input_position:
470 if( ! NPVARIANT_IS_DOUBLE(value) )
472 return INVOKERESULT_INVALID_VALUE;
475 float val = (float)NPVARIANT_TO_DOUBLE(value);
476 libvlc_media_player_set_position(p_md, val, &ex);
477 RETURN_ON_EXCEPTION(this,ex);
478 return INVOKERESULT_NO_ERROR;
483 if( NPVARIANT_IS_INT32(value) )
484 val = (int64_t)NPVARIANT_TO_INT32(value);
485 else if( NPVARIANT_IS_DOUBLE(value) )
486 val = (int64_t)NPVARIANT_TO_DOUBLE(value);
489 return INVOKERESULT_INVALID_VALUE;
492 libvlc_media_player_set_time(p_md, val, &ex);
493 RETURN_ON_EXCEPTION(this,ex);
494 return INVOKERESULT_NO_ERROR;
499 if( NPVARIANT_IS_INT32(value) )
500 val = (float)NPVARIANT_TO_INT32(value);
501 else if( NPVARIANT_IS_DOUBLE(value) )
502 val = (float)NPVARIANT_TO_DOUBLE(value);
505 return INVOKERESULT_INVALID_VALUE;
508 libvlc_media_player_set_rate(p_md, val, &ex);
509 RETURN_ON_EXCEPTION(this,ex);
510 return INVOKERESULT_NO_ERROR;
516 return INVOKERESULT_GENERIC_ERROR;
519 const NPUTF8 * const LibvlcInputNPObject::methodNames[] =
524 COUNTNAMES(LibvlcInputNPObject,methodCount,methodNames);
527 ** implementation of libvlc playlist items object
530 const NPUTF8 * const LibvlcPlaylistItemsNPObject::propertyNames[] =
534 COUNTNAMES(LibvlcPlaylistItemsNPObject,propertyCount,propertyNames);
536 enum LibvlcPlaylistItemsNPObjectPropertyIds
538 ID_playlistitems_count,
541 RuntimeNPObject::InvokeResult
542 LibvlcPlaylistItemsNPObject::getProperty(int index, NPVariant &result)
544 /* is plugin still running */
545 if( isPluginRunning() )
547 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
548 libvlc_exception_t ex;
549 libvlc_exception_init(&ex);
553 case ID_playlistitems_count:
555 int val = p_plugin->playlist_count(&ex);
556 RETURN_ON_EXCEPTION(this,ex);
557 INT32_TO_NPVARIANT(val, result);
558 return INVOKERESULT_NO_ERROR;
564 return INVOKERESULT_GENERIC_ERROR;
567 const NPUTF8 * const LibvlcPlaylistItemsNPObject::methodNames[] =
572 COUNTNAMES(LibvlcPlaylistItemsNPObject,methodCount,methodNames);
574 enum LibvlcPlaylistItemsNPObjectMethodIds
576 ID_playlistitems_clear,
577 ID_playlistitems_remove,
580 RuntimeNPObject::InvokeResult
581 LibvlcPlaylistItemsNPObject::invoke(int index, const NPVariant *args,
582 uint32_t argCount, NPVariant &result)
584 /* is plugin still running */
585 if( isPluginRunning() )
587 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
588 libvlc_exception_t ex;
589 libvlc_exception_init(&ex);
593 case ID_playlistitems_clear:
596 p_plugin->playlist_clear(&ex);
597 RETURN_ON_EXCEPTION(this,ex);
598 VOID_TO_NPVARIANT(result);
599 return INVOKERESULT_NO_ERROR;
601 return INVOKERESULT_NO_SUCH_METHOD;
602 case ID_playlistitems_remove:
603 if( (argCount == 1) && isNumberValue(args[0]) )
605 p_plugin->playlist_delete_item(numberValue(args[0]),&ex);
606 RETURN_ON_EXCEPTION(this,ex);
607 VOID_TO_NPVARIANT(result);
608 return INVOKERESULT_NO_ERROR;
610 return INVOKERESULT_NO_SUCH_METHOD;
615 return INVOKERESULT_GENERIC_ERROR;
619 ** implementation of libvlc playlist object
622 LibvlcPlaylistNPObject::~LibvlcPlaylistNPObject()
624 // Why the isValid()?
625 if( isValid() && playlistItemsObj )
626 NPN_ReleaseObject(playlistItemsObj);
629 const NPUTF8 * const LibvlcPlaylistNPObject::propertyNames[] =
631 "itemCount", /* deprecated */
635 COUNTNAMES(LibvlcPlaylistNPObject,propertyCount,propertyNames);
637 enum LibvlcPlaylistNPObjectPropertyIds
639 ID_playlist_itemcount,
640 ID_playlist_isplaying,
644 RuntimeNPObject::InvokeResult
645 LibvlcPlaylistNPObject::getProperty(int index, NPVariant &result)
647 /* is plugin still running */
648 if( isPluginRunning() )
650 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
651 libvlc_exception_t ex;
652 libvlc_exception_init(&ex);
656 case ID_playlist_itemcount: /* deprecated */
658 int val = p_plugin->playlist_count(&ex);
659 RETURN_ON_EXCEPTION(this,ex);
660 INT32_TO_NPVARIANT(val, result);
661 return INVOKERESULT_NO_ERROR;
663 case ID_playlist_isplaying:
665 int val = p_plugin->playlist_isplaying(&ex);
666 RETURN_ON_EXCEPTION(this,ex);
667 BOOLEAN_TO_NPVARIANT(val, result);
668 return INVOKERESULT_NO_ERROR;
670 case ID_playlist_items:
672 // create child object in lazyman fashion to avoid
673 // ownership problem with firefox
674 if( ! playlistItemsObj )
676 NPN_CreateObject(_instance, RuntimeNPClass<
677 LibvlcPlaylistItemsNPObject>::getClass());
678 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistItemsObj), result);
679 return INVOKERESULT_NO_ERROR;
685 return INVOKERESULT_GENERIC_ERROR;
688 const NPUTF8 * const LibvlcPlaylistNPObject::methodNames[] =
697 "clear", /* deprecated */
698 "removeItem", /* deprecated */
700 COUNTNAMES(LibvlcPlaylistNPObject,methodCount,methodNames);
702 enum LibvlcPlaylistNPObjectMethodIds
706 ID_playlist_playItem,
707 ID_playlist_togglepause,
712 ID_playlist_removeitem
715 RuntimeNPObject::InvokeResult
716 LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
717 uint32_t argCount, NPVariant &result)
719 /* is plugin still running */
720 if( isPluginRunning() )
722 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
723 libvlc_exception_t ex;
724 libvlc_exception_init(&ex);
728 // XXX FIXME this needs squashing into something much smaller
729 case ID_playlist_add:
731 if( (argCount < 1) || (argCount > 3) )
732 return INVOKERESULT_NO_SUCH_METHOD;
737 if( NPVARIANT_IS_STRING(args[0]) )
739 char *s = stringValue(NPVARIANT_TO_STRING(args[0]));
742 url = p_plugin->getAbsoluteURL(s);
746 // problem with combining url, use argument
750 return INVOKERESULT_OUT_OF_MEMORY;
753 return INVOKERESULT_NO_SUCH_METHOD;
757 // grab name if available
760 if( NPVARIANT_IS_NULL(args[1]) )
764 else if( NPVARIANT_IS_STRING(args[1]) )
766 name = stringValue(NPVARIANT_TO_STRING(args[1]));
771 return INVOKERESULT_INVALID_VALUE;
776 char** ppsz_options = NULL;
778 // grab options if available
781 if( NPVARIANT_IS_NULL(args[2]) )
785 else if( NPVARIANT_IS_STRING(args[2]) )
787 parseOptions(NPVARIANT_TO_STRING(args[2]),
788 &i_options, &ppsz_options);
791 else if( NPVARIANT_IS_OBJECT(args[2]) )
793 parseOptions(NPVARIANT_TO_OBJECT(args[2]),
794 &i_options, &ppsz_options);
800 return INVOKERESULT_INVALID_VALUE;
804 int item = p_plugin->playlist_add_extended_untrusted(url, name,
805 i_options, const_cast<const char **>(ppsz_options), &ex);
808 for( int i=0; i< i_options; ++i )
810 free(ppsz_options[i]);
814 RETURN_ON_EXCEPTION(this,ex);
815 INT32_TO_NPVARIANT(item, result);
816 return INVOKERESULT_NO_ERROR;
818 case ID_playlist_play:
821 p_plugin->playlist_play(&ex);
822 RETURN_ON_EXCEPTION(this,ex);
823 VOID_TO_NPVARIANT(result);
824 return INVOKERESULT_NO_ERROR;
826 return INVOKERESULT_NO_SUCH_METHOD;
827 case ID_playlist_playItem:
828 if( (argCount == 1) && isNumberValue(args[0]) )
830 p_plugin->playlist_play_item(numberValue(args[0]),&ex);
831 RETURN_ON_EXCEPTION(this,ex);
832 VOID_TO_NPVARIANT(result);
833 return INVOKERESULT_NO_ERROR;
835 return INVOKERESULT_NO_SUCH_METHOD;
836 case ID_playlist_togglepause:
839 p_plugin->playlist_pause(&ex);
840 RETURN_ON_EXCEPTION(this,ex);
841 VOID_TO_NPVARIANT(result);
842 return INVOKERESULT_NO_ERROR;
844 return INVOKERESULT_NO_SUCH_METHOD;
845 case ID_playlist_stop:
848 p_plugin->playlist_stop(&ex);
849 RETURN_ON_EXCEPTION(this,ex);
850 VOID_TO_NPVARIANT(result);
851 return INVOKERESULT_NO_ERROR;
853 return INVOKERESULT_NO_SUCH_METHOD;
854 case ID_playlist_next:
857 p_plugin->playlist_next(&ex);
858 RETURN_ON_EXCEPTION(this,ex);
859 VOID_TO_NPVARIANT(result);
860 return INVOKERESULT_NO_ERROR;
862 return INVOKERESULT_NO_SUCH_METHOD;
863 case ID_playlist_prev:
866 p_plugin->playlist_prev(&ex);
867 RETURN_ON_EXCEPTION(this,ex);
868 VOID_TO_NPVARIANT(result);
869 return INVOKERESULT_NO_ERROR;
871 return INVOKERESULT_NO_SUCH_METHOD;
872 case ID_playlist_clear: /* deprecated */
875 p_plugin->playlist_clear(&ex);
876 RETURN_ON_EXCEPTION(this,ex);
877 VOID_TO_NPVARIANT(result);
878 return INVOKERESULT_NO_ERROR;
880 return INVOKERESULT_NO_SUCH_METHOD;
881 case ID_playlist_removeitem: /* deprecated */
882 if( (argCount == 1) && isNumberValue(args[0]) )
884 p_plugin->playlist_delete_item(numberValue(args[0]), &ex);
885 RETURN_ON_EXCEPTION(this,ex);
886 VOID_TO_NPVARIANT(result);
887 return INVOKERESULT_NO_ERROR;
889 return INVOKERESULT_NO_SUCH_METHOD;
894 return INVOKERESULT_GENERIC_ERROR;
897 // XXX FIXME The new playlist_add creates a media instance and feeds it
898 // XXX FIXME these options one at a time, so this hunk of code does lots
899 // XXX FIXME of unnecessairy work. Break out something that can do one
900 // XXX FIXME option at a time and doesn't need to realloc().
901 // XXX FIXME Same for the other version of parseOptions.
903 void LibvlcPlaylistNPObject::parseOptions(const NPString &nps,
904 int *i_options, char*** ppsz_options)
908 char *s = stringValue(nps);
913 char **options = (char **)malloc(capacity*sizeof(char *));
918 char *end = val + nps.utf8length;
921 // skip leading blanks
923 && ((*val == ' ' ) || (*val == '\t')) )
927 // skip till we get a blank character
933 if( ('\'' == c) || ('"' == c) )
935 // skip till end of string
936 while( (val < end) && (*(val++) != c ) );
942 if( nOptions == capacity )
945 char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
948 /* failed to allocate more memory */
950 /* return what we got so far */
951 *i_options = nOptions;
952 *ppsz_options = options;
955 options = moreOptions;
958 options[nOptions++] = strdup(start);
961 // must be end of string
964 *i_options = nOptions;
965 *ppsz_options = options;
972 // XXX FIXME See comment at the other parseOptions variant.
973 void LibvlcPlaylistNPObject::parseOptions(NPObject *obj, int *i_options,
974 char*** ppsz_options)
976 /* WARNING: Safari does not implement NPN_HasProperty/NPN_HasMethod */
980 /* we are expecting to have a Javascript Array object */
981 NPIdentifier propId = NPN_GetStringIdentifier("length");
982 if( NPN_GetProperty(_instance, obj, propId, &value) )
984 int count = numberValue(value);
985 NPN_ReleaseVariantValue(&value);
990 char **options = (char **)malloc(capacity*sizeof(char *));
995 while( nOptions < count )
997 propId = NPN_GetIntIdentifier(nOptions);
998 if( ! NPN_GetProperty(_instance, obj, propId, &value) )
999 /* return what we got so far */
1002 if( ! NPVARIANT_IS_STRING(value) )
1004 /* return what we got so far */
1005 NPN_ReleaseVariantValue(&value);
1009 if( nOptions == capacity )
1012 char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
1015 /* failed to allocate more memory */
1016 NPN_ReleaseVariantValue(&value);
1017 /* return what we got so far */
1018 *i_options = nOptions;
1019 *ppsz_options = options;
1022 options = moreOptions;
1025 options[nOptions++] = stringValue(value);
1027 *i_options = nOptions;
1028 *ppsz_options = options;
1035 ** implementation of libvlc video object
1038 const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] =
1049 enum LibvlcVideoNPObjectPropertyIds
1051 ID_video_fullscreen,
1054 ID_video_aspectratio,
1059 COUNTNAMES(LibvlcVideoNPObject,propertyCount,propertyNames);
1061 RuntimeNPObject::InvokeResult
1062 LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
1064 /* is plugin still running */
1065 if( isPluginRunning() )
1067 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1068 libvlc_exception_t ex;
1069 libvlc_exception_init(&ex);
1071 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1072 RETURN_ON_EXCEPTION(this,ex);
1076 case ID_video_fullscreen:
1078 int val = p_plugin->get_fullscreen(&ex);
1079 RETURN_ON_EXCEPTION(this,ex);
1080 BOOLEAN_TO_NPVARIANT(val, result);
1081 return INVOKERESULT_NO_ERROR;
1083 case ID_video_height:
1085 int val = libvlc_video_get_height(p_md, &ex);
1086 RETURN_ON_EXCEPTION(this,ex);
1087 INT32_TO_NPVARIANT(val, result);
1088 return INVOKERESULT_NO_ERROR;
1090 case ID_video_width:
1092 int val = libvlc_video_get_width(p_md, &ex);
1093 RETURN_ON_EXCEPTION(this,ex);
1094 INT32_TO_NPVARIANT(val, result);
1095 return INVOKERESULT_NO_ERROR;
1097 case ID_video_aspectratio:
1099 NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1100 RETURN_ON_EXCEPTION(this,ex);
1102 return INVOKERESULT_GENERIC_ERROR;
1104 STRINGZ_TO_NPVARIANT(psz_aspect, result);
1105 return INVOKERESULT_NO_ERROR;
1107 case ID_video_subtitle:
1109 int i_spu = libvlc_video_get_spu(p_md, &ex);
1110 RETURN_ON_EXCEPTION(this,ex);
1111 INT32_TO_NPVARIANT(i_spu, result);
1112 return INVOKERESULT_NO_ERROR;
1116 NPUTF8 *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1117 RETURN_ON_EXCEPTION(this,ex);
1119 return INVOKERESULT_GENERIC_ERROR;
1121 STRINGZ_TO_NPVARIANT(psz_geometry, result);
1122 return INVOKERESULT_NO_ERROR;
1124 case ID_video_teletext:
1126 int i_page = libvlc_video_get_teletext(p_md, &ex);
1127 RETURN_ON_EXCEPTION(this,ex);
1128 INT32_TO_NPVARIANT(i_page, result);
1129 return INVOKERESULT_NO_ERROR;
1133 return INVOKERESULT_GENERIC_ERROR;
1136 RuntimeNPObject::InvokeResult
1137 LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
1139 /* is plugin still running */
1140 if( isPluginRunning() )
1142 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1143 libvlc_exception_t ex;
1144 libvlc_exception_init(&ex);
1146 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1147 RETURN_ON_EXCEPTION(this,ex);
1151 case ID_video_fullscreen:
1153 if( ! NPVARIANT_IS_BOOLEAN(value) )
1155 return INVOKERESULT_INVALID_VALUE;
1158 int val = NPVARIANT_TO_BOOLEAN(value);
1159 p_plugin->set_fullscreen(val, &ex);
1160 RETURN_ON_EXCEPTION(this,ex);
1161 return INVOKERESULT_NO_ERROR;
1163 case ID_video_aspectratio:
1165 char *psz_aspect = NULL;
1167 if( ! NPVARIANT_IS_STRING(value) )
1169 return INVOKERESULT_INVALID_VALUE;
1172 psz_aspect = stringValue(NPVARIANT_TO_STRING(value));
1175 return INVOKERESULT_GENERIC_ERROR;
1178 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
1180 RETURN_ON_EXCEPTION(this,ex);
1182 return INVOKERESULT_NO_ERROR;
1184 case ID_video_subtitle:
1186 if( isNumberValue(value) )
1188 libvlc_video_set_spu(p_md, numberValue(value), &ex);
1189 RETURN_ON_EXCEPTION(this,ex);
1191 return INVOKERESULT_NO_ERROR;
1193 return INVOKERESULT_INVALID_VALUE;
1197 char *psz_geometry = NULL;
1199 if( ! NPVARIANT_IS_STRING(value) )
1201 return INVOKERESULT_INVALID_VALUE;
1204 psz_geometry = stringValue(NPVARIANT_TO_STRING(value));
1207 return INVOKERESULT_GENERIC_ERROR;
1210 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
1212 RETURN_ON_EXCEPTION(this,ex);
1214 return INVOKERESULT_NO_ERROR;
1216 case ID_video_teletext:
1218 if( isNumberValue(value) )
1220 libvlc_video_set_teletext(p_md, numberValue(value), &ex);
1221 RETURN_ON_EXCEPTION(this,ex);
1223 return INVOKERESULT_NO_ERROR;
1225 return INVOKERESULT_INVALID_VALUE;
1229 return INVOKERESULT_GENERIC_ERROR;
1232 const NPUTF8 * const LibvlcVideoNPObject::methodNames[] =
1237 COUNTNAMES(LibvlcVideoNPObject,methodCount,methodNames);
1239 enum LibvlcVideoNPObjectMethodIds
1241 ID_video_togglefullscreen,
1242 ID_video_toggleteletext
1245 RuntimeNPObject::InvokeResult
1246 LibvlcVideoNPObject::invoke(int index, const NPVariant *args,
1247 uint32_t argCount, NPVariant &result)
1249 /* is plugin still running */
1250 if( isPluginRunning() )
1252 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1253 libvlc_exception_t ex;
1254 libvlc_exception_init(&ex);
1256 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1257 RETURN_ON_EXCEPTION(this,ex);
1261 case ID_video_togglefullscreen:
1264 p_plugin->toggle_fullscreen(&ex);
1265 RETURN_ON_EXCEPTION(this,ex);
1266 VOID_TO_NPVARIANT(result);
1267 return INVOKERESULT_NO_ERROR;
1269 return INVOKERESULT_NO_SUCH_METHOD;
1270 case ID_video_toggleteletext:
1273 libvlc_toggle_teletext(p_md, &ex);
1274 RETURN_ON_EXCEPTION(this,ex);
1275 VOID_TO_NPVARIANT(result);
1276 return INVOKERESULT_NO_ERROR;
1278 return INVOKERESULT_NO_SUCH_METHOD;
1280 return INVOKERESULT_NO_SUCH_METHOD;
1283 return INVOKERESULT_GENERIC_ERROR;