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( logObj ) NPN_ReleaseObject(logObj);
69 if( playlistObj ) NPN_ReleaseObject(playlistObj);
70 if( videoObj ) NPN_ReleaseObject(videoObj);
74 const NPUTF8 * const LibvlcRootNPObject::propertyNames[] =
83 COUNTNAMES(LibvlcRootNPObject,propertyCount,propertyNames);
85 enum LibvlcRootNPObjectPropertyIds
95 RuntimeNPObject::InvokeResult
96 LibvlcRootNPObject::getProperty(int index, NPVariant &result)
98 /* is plugin still running */
99 if( isPluginRunning() )
104 // create child object in lazyman fashion to avoid
105 // ownership problem with firefox
107 audioObj = NPN_CreateObject(_instance,
108 RuntimeNPClass<LibvlcAudioNPObject>::getClass());
109 OBJECT_TO_NPVARIANT(NPN_RetainObject(audioObj), result);
110 return INVOKERESULT_NO_ERROR;
112 // create child object in lazyman fashion to avoid
113 // ownership problem with firefox
115 inputObj = NPN_CreateObject(_instance,
116 RuntimeNPClass<LibvlcInputNPObject>::getClass());
117 OBJECT_TO_NPVARIANT(NPN_RetainObject(inputObj), result);
118 return INVOKERESULT_NO_ERROR;
120 // create child object in lazyman fashion to avoid
121 // ownership problem with firefox
123 logObj = NPN_CreateObject(_instance,
124 RuntimeNPClass<LibvlcLogNPObject>::getClass());
125 OBJECT_TO_NPVARIANT(NPN_RetainObject(logObj), result);
126 return INVOKERESULT_NO_ERROR;
127 case ID_root_playlist:
128 // create child object in lazyman fashion to avoid
129 // ownership problem with firefox
131 playlistObj = NPN_CreateObject(_instance,
132 RuntimeNPClass<LibvlcPlaylistNPObject>::getClass());
133 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistObj), result);
134 return INVOKERESULT_NO_ERROR;
136 // create child object in lazyman fashion to avoid
137 // ownership problem with firefox
139 videoObj = NPN_CreateObject(_instance,
140 RuntimeNPClass<LibvlcVideoNPObject>::getClass());
141 OBJECT_TO_NPVARIANT(NPN_RetainObject(videoObj), result);
142 return INVOKERESULT_NO_ERROR;
143 case ID_root_VersionInfo:
145 const char *s = libvlc_get_version();
147 NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);
149 return INVOKERESULT_OUT_OF_MEMORY;
151 memcpy(retval, s, len);
152 STRINGN_TO_NPVARIANT(retval, len, result);
153 return INVOKERESULT_NO_ERROR;
159 return INVOKERESULT_GENERIC_ERROR;
162 const NPUTF8 * const LibvlcRootNPObject::methodNames[] =
166 COUNTNAMES(LibvlcRootNPObject,methodCount,methodNames);
168 enum LibvlcRootNPObjectMethodIds
173 RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index,
174 const NPVariant *args, uint32_t argCount, NPVariant &result)
176 /* is plugin still running */
177 if( isPluginRunning() )
179 libvlc_exception_t ex;
180 libvlc_exception_init(&ex);
184 case ID_root_versionInfo:
187 const char *s = libvlc_get_version();
189 NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);
191 return INVOKERESULT_OUT_OF_MEMORY;
192 memcpy(retval, s, len);
193 STRINGN_TO_NPVARIANT(retval, len, result);
194 return INVOKERESULT_NO_ERROR;
196 return INVOKERESULT_NO_SUCH_METHOD;
201 return INVOKERESULT_GENERIC_ERROR;
205 ** implementation of libvlc audio object
208 const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] =
215 COUNTNAMES(LibvlcAudioNPObject,propertyCount,propertyNames);
217 enum LibvlcAudioNPObjectPropertyIds
225 RuntimeNPObject::InvokeResult
226 LibvlcAudioNPObject::getProperty(int index, NPVariant &result)
228 /* is plugin still running */
229 if( isPluginRunning() )
231 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
232 libvlc_exception_t ex;
233 libvlc_exception_init(&ex);
239 bool muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex);
240 RETURN_ON_EXCEPTION(this,ex);
241 BOOLEAN_TO_NPVARIANT(muted, result);
242 return INVOKERESULT_NO_ERROR;
244 case ID_audio_volume:
246 int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex);
247 RETURN_ON_EXCEPTION(this,ex);
248 INT32_TO_NPVARIANT(volume, result);
249 return INVOKERESULT_NO_ERROR;
253 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
254 RETURN_ON_EXCEPTION(this,ex);
255 int track = libvlc_audio_get_track(p_md, &ex);
256 RETURN_ON_EXCEPTION(this,ex);
257 INT32_TO_NPVARIANT(track, result);
258 return INVOKERESULT_NO_ERROR;
260 case ID_audio_channel:
262 int channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex);
263 RETURN_ON_EXCEPTION(this,ex);
264 INT32_TO_NPVARIANT(channel, result);
265 return INVOKERESULT_NO_ERROR;
271 return INVOKERESULT_GENERIC_ERROR;
274 RuntimeNPObject::InvokeResult
275 LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)
277 /* is plugin still running */
278 if( isPluginRunning() )
280 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
281 libvlc_exception_t ex;
282 libvlc_exception_init(&ex);
287 if( NPVARIANT_IS_BOOLEAN(value) )
289 libvlc_audio_set_mute(p_plugin->getVLC(),
290 NPVARIANT_TO_BOOLEAN(value), &ex);
291 RETURN_ON_EXCEPTION(this,ex);
292 return INVOKERESULT_NO_ERROR;
294 return INVOKERESULT_INVALID_VALUE;
295 case ID_audio_volume:
296 if( isNumberValue(value) )
298 libvlc_audio_set_volume(p_plugin->getVLC(),
299 numberValue(value), &ex);
300 RETURN_ON_EXCEPTION(this,ex);
301 return INVOKERESULT_NO_ERROR;
303 return INVOKERESULT_INVALID_VALUE;
305 if( isNumberValue(value) )
307 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
308 RETURN_ON_EXCEPTION(this,ex);
309 libvlc_audio_set_track(p_md, numberValue(value), &ex);
310 RETURN_ON_EXCEPTION(this,ex);
311 return INVOKERESULT_NO_ERROR;
313 return INVOKERESULT_INVALID_VALUE;
314 case ID_audio_channel:
315 if( isNumberValue(value) )
317 libvlc_audio_set_channel(p_plugin->getVLC(),
318 numberValue(value), &ex);
319 RETURN_ON_EXCEPTION(this,ex);
320 return INVOKERESULT_NO_ERROR;
322 return INVOKERESULT_INVALID_VALUE;
327 return INVOKERESULT_GENERIC_ERROR;
330 const NPUTF8 * const LibvlcAudioNPObject::methodNames[] =
334 COUNTNAMES(LibvlcAudioNPObject,methodCount,methodNames);
336 enum LibvlcAudioNPObjectMethodIds
341 RuntimeNPObject::InvokeResult
342 LibvlcAudioNPObject::invoke(int index, const NPVariant *args,
343 uint32_t argCount, NPVariant &result)
345 /* is plugin still running */
346 if( isPluginRunning() )
348 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
349 libvlc_exception_t ex;
350 libvlc_exception_init(&ex);
354 case ID_audio_togglemute:
357 libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex);
358 RETURN_ON_EXCEPTION(this,ex);
359 VOID_TO_NPVARIANT(result);
360 return INVOKERESULT_NO_ERROR;
362 return INVOKERESULT_NO_SUCH_METHOD;
367 return INVOKERESULT_GENERIC_ERROR;
371 ** implementation of libvlc input object
374 const NPUTF8 * const LibvlcInputNPObject::propertyNames[] =
384 COUNTNAMES(LibvlcInputNPObject,propertyCount,propertyNames);
386 enum LibvlcInputNPObjectPropertyIds
397 RuntimeNPObject::InvokeResult
398 LibvlcInputNPObject::getProperty(int index, NPVariant &result)
400 /* is plugin still running */
401 if( isPluginRunning() )
403 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
404 libvlc_exception_t ex;
405 libvlc_exception_init(&ex);
407 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
408 if( libvlc_exception_raised(&ex) )
410 if( index != ID_input_state )
412 NPN_SetException(this, libvlc_exception_get_message(&ex));
413 libvlc_exception_clear(&ex);
414 return INVOKERESULT_GENERIC_ERROR;
418 /* for input state, return CLOSED rather than an exception */
419 INT32_TO_NPVARIANT(0, result);
420 libvlc_exception_clear(&ex);
421 return INVOKERESULT_NO_ERROR;
427 case ID_input_length:
429 double val = (double)libvlc_media_player_get_length(p_md, &ex);
430 RETURN_ON_EXCEPTION(this,ex);
431 DOUBLE_TO_NPVARIANT(val, result);
432 return INVOKERESULT_NO_ERROR;
434 case ID_input_position:
436 double val = libvlc_media_player_get_position(p_md, &ex);
437 RETURN_ON_EXCEPTION(this,ex);
438 DOUBLE_TO_NPVARIANT(val, result);
439 return INVOKERESULT_NO_ERROR;
443 double val = (double)libvlc_media_player_get_time(p_md, &ex);
444 RETURN_ON_EXCEPTION(this,ex);
445 DOUBLE_TO_NPVARIANT(val, result);
446 return INVOKERESULT_NO_ERROR;
450 int val = libvlc_media_player_get_state(p_md, &ex);
451 RETURN_ON_EXCEPTION(this,ex);
452 INT32_TO_NPVARIANT(val, result);
453 return INVOKERESULT_NO_ERROR;
457 float val = libvlc_media_player_get_rate(p_md, &ex);
458 RETURN_ON_EXCEPTION(this,ex);
459 DOUBLE_TO_NPVARIANT(val, result);
460 return INVOKERESULT_NO_ERROR;
464 double val = libvlc_media_player_get_fps(p_md, &ex);
465 RETURN_ON_EXCEPTION(this,ex);
466 DOUBLE_TO_NPVARIANT(val, result);
467 return INVOKERESULT_NO_ERROR;
469 case ID_input_hasvout:
471 bool val = p_plugin->player_has_vout(&ex);
472 RETURN_ON_EXCEPTION(this,ex);
473 BOOLEAN_TO_NPVARIANT(val, result);
474 return INVOKERESULT_NO_ERROR;
480 return INVOKERESULT_GENERIC_ERROR;
483 RuntimeNPObject::InvokeResult
484 LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
486 /* is plugin still running */
487 if( isPluginRunning() )
489 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
490 libvlc_exception_t ex;
491 libvlc_exception_init(&ex);
493 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
494 RETURN_ON_EXCEPTION(this,ex);
498 case ID_input_position:
500 if( ! NPVARIANT_IS_DOUBLE(value) )
502 return INVOKERESULT_INVALID_VALUE;
505 float val = (float)NPVARIANT_TO_DOUBLE(value);
506 libvlc_media_player_set_position(p_md, val, &ex);
507 RETURN_ON_EXCEPTION(this,ex);
508 return INVOKERESULT_NO_ERROR;
513 if( NPVARIANT_IS_INT32(value) )
514 val = (int64_t)NPVARIANT_TO_INT32(value);
515 else if( NPVARIANT_IS_DOUBLE(value) )
516 val = (int64_t)NPVARIANT_TO_DOUBLE(value);
519 return INVOKERESULT_INVALID_VALUE;
522 libvlc_media_player_set_time(p_md, val, &ex);
523 RETURN_ON_EXCEPTION(this,ex);
524 return INVOKERESULT_NO_ERROR;
529 if( NPVARIANT_IS_INT32(value) )
530 val = (float)NPVARIANT_TO_INT32(value);
531 else if( NPVARIANT_IS_DOUBLE(value) )
532 val = (float)NPVARIANT_TO_DOUBLE(value);
535 return INVOKERESULT_INVALID_VALUE;
538 libvlc_media_player_set_rate(p_md, val, &ex);
539 RETURN_ON_EXCEPTION(this,ex);
540 return INVOKERESULT_NO_ERROR;
546 return INVOKERESULT_GENERIC_ERROR;
549 const NPUTF8 * const LibvlcInputNPObject::methodNames[] =
554 COUNTNAMES(LibvlcInputNPObject,methodCount,methodNames);
557 ** implementation of libvlc message object
560 const NPUTF8 * const LibvlcMessageNPObject::propertyNames[] =
568 COUNTNAMES(LibvlcMessageNPObject,propertyCount,propertyNames);
570 enum LibvlcMessageNPObjectPropertyIds
579 RuntimeNPObject::InvokeResult
580 LibvlcMessageNPObject::getProperty(int index, NPVariant &result)
582 /* is plugin still running */
583 if( isPluginRunning() )
587 case ID_message_severity:
589 INT32_TO_NPVARIANT(_msg.i_severity, result);
590 return INVOKERESULT_NO_ERROR;
592 case ID_message_type:
596 int len = strlen(_msg.psz_type);
597 NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);
600 memcpy(retval, _msg.psz_type, len);
601 STRINGN_TO_NPVARIANT(retval, len, result);
606 NULL_TO_NPVARIANT(result);
608 return INVOKERESULT_NO_ERROR;
610 case ID_message_name:
614 int len = strlen(_msg.psz_name);
615 NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);
618 memcpy(retval, _msg.psz_name, len);
619 STRINGN_TO_NPVARIANT(retval, len, result);
624 NULL_TO_NPVARIANT(result);
626 return INVOKERESULT_NO_ERROR;
628 case ID_message_header:
630 if( _msg.psz_header )
632 int len = strlen(_msg.psz_header);
633 NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);
636 memcpy(retval, _msg.psz_header, len);
637 STRINGN_TO_NPVARIANT(retval, len, result);
642 NULL_TO_NPVARIANT(result);
644 return INVOKERESULT_NO_ERROR;
646 case ID_message_message:
648 if( _msg.psz_message )
650 int len = strlen(_msg.psz_message);
651 NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);
654 memcpy(retval, _msg.psz_message, len);
655 STRINGN_TO_NPVARIANT(retval, len, result);
660 NULL_TO_NPVARIANT(result);
662 return INVOKERESULT_NO_ERROR;
668 return INVOKERESULT_GENERIC_ERROR;
671 const NPUTF8 * const LibvlcMessageNPObject::methodNames[] =
675 COUNTNAMES(LibvlcMessageNPObject,methodCount,methodNames);
678 ** implementation of libvlc message iterator object
681 LibvlcMessageIteratorNPObject::LibvlcMessageIteratorNPObject(NPP instance,
682 const NPClass *aClass) :
683 RuntimeNPObject(instance, aClass),
686 // XXX FIXME use _instance or instance in this method?
688 /* is plugin still running */
689 if( instance->pdata )
691 VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
692 libvlc_log_t *p_log = p_plugin->getLog();
695 _p_iter = libvlc_log_get_iterator(p_log, NULL);
700 LibvlcMessageIteratorNPObject::~LibvlcMessageIteratorNPObject()
703 libvlc_log_iterator_free(_p_iter, NULL);
706 const NPUTF8 * const LibvlcMessageIteratorNPObject::propertyNames[] =
710 COUNTNAMES(LibvlcMessageIteratorNPObject,propertyCount,propertyNames);
712 enum LibvlcMessageIteratorNPObjectPropertyIds
714 ID_messageiterator_hasNext,
717 RuntimeNPObject::InvokeResult
718 LibvlcMessageIteratorNPObject::getProperty(int index, NPVariant &result)
720 /* is plugin still running */
721 if( isPluginRunning() )
723 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
726 case ID_messageiterator_hasNext:
728 if( _p_iter && p_plugin->getLog() )
730 libvlc_exception_t ex;
731 libvlc_exception_init(&ex);
733 BOOLEAN_TO_NPVARIANT(
734 libvlc_log_iterator_has_next(_p_iter, &ex), result );
735 RETURN_ON_EXCEPTION(this,ex);
739 BOOLEAN_TO_NPVARIANT(0, result);
741 return INVOKERESULT_NO_ERROR;
747 return INVOKERESULT_GENERIC_ERROR;
750 const NPUTF8 * const LibvlcMessageIteratorNPObject::methodNames[] =
754 COUNTNAMES(LibvlcMessageIteratorNPObject,methodCount,methodNames);
756 enum LibvlcMessageIteratorNPObjectMethodIds
758 ID_messageiterator_next,
761 RuntimeNPObject::InvokeResult
762 LibvlcMessageIteratorNPObject::invoke(int index, const NPVariant *args,
763 uint32_t argCount, NPVariant &result)
765 /* is plugin still running */
766 if( isPluginRunning() )
768 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
769 libvlc_exception_t ex;
770 libvlc_exception_init(&ex);
774 case ID_messageiterator_next:
777 if( _p_iter && p_plugin->getLog() )
779 struct libvlc_log_message_t buffer;
781 buffer.sizeof_msg = sizeof(buffer);
783 libvlc_log_iterator_next(_p_iter, &buffer, &ex);
784 RETURN_ON_EXCEPTION(this,ex);
786 LibvlcMessageNPObject* message =
787 static_cast<LibvlcMessageNPObject*>(
788 NPN_CreateObject(_instance, RuntimeNPClass<
789 LibvlcMessageNPObject>::getClass()));
792 message->setMessage(buffer);
793 OBJECT_TO_NPVARIANT(message, result);
794 return INVOKERESULT_NO_ERROR;
796 return INVOKERESULT_OUT_OF_MEMORY;
798 return INVOKERESULT_GENERIC_ERROR;
800 return INVOKERESULT_NO_SUCH_METHOD;
805 return INVOKERESULT_GENERIC_ERROR;
809 ** implementation of libvlc message object
812 const NPUTF8 * const LibvlcMessagesNPObject::propertyNames[] =
816 COUNTNAMES(LibvlcMessagesNPObject,propertyCount,propertyNames);
818 enum LibvlcMessagesNPObjectPropertyIds
823 RuntimeNPObject::InvokeResult
824 LibvlcMessagesNPObject::getProperty(int index, NPVariant &result)
826 /* is plugin still running */
827 if( isPluginRunning() )
829 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
832 case ID_messages_count:
834 libvlc_log_t *p_log = p_plugin->getLog();
837 libvlc_exception_t ex;
838 libvlc_exception_init(&ex);
840 INT32_TO_NPVARIANT(libvlc_log_count(p_log, &ex), result);
841 RETURN_ON_EXCEPTION(this,ex);
845 INT32_TO_NPVARIANT(0, result);
847 return INVOKERESULT_NO_ERROR;
853 return INVOKERESULT_GENERIC_ERROR;
856 const NPUTF8 * const LibvlcMessagesNPObject::methodNames[] =
861 COUNTNAMES(LibvlcMessagesNPObject,methodCount,methodNames);
863 enum LibvlcMessagesNPObjectMethodIds
866 ID_messages_iterator,
869 RuntimeNPObject::InvokeResult
870 LibvlcMessagesNPObject::invoke(int index, const NPVariant *args,
871 uint32_t argCount, NPVariant &result)
873 /* is plugin still running */
874 if( isPluginRunning() )
876 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
877 libvlc_exception_t ex;
878 libvlc_exception_init(&ex);
882 case ID_messages_clear:
885 libvlc_log_t *p_log = p_plugin->getLog();
888 libvlc_log_clear(p_log, &ex);
889 RETURN_ON_EXCEPTION(this,ex);
891 return INVOKERESULT_NO_ERROR;
893 return INVOKERESULT_NO_SUCH_METHOD;
895 case ID_messages_iterator:
898 LibvlcMessageIteratorNPObject* iter =
899 static_cast<LibvlcMessageIteratorNPObject*>(
900 NPN_CreateObject(_instance, RuntimeNPClass<
901 LibvlcMessageIteratorNPObject>::getClass()));
904 OBJECT_TO_NPVARIANT(iter, result);
905 return INVOKERESULT_NO_ERROR;
907 return INVOKERESULT_OUT_OF_MEMORY;
909 return INVOKERESULT_NO_SUCH_METHOD;
915 return INVOKERESULT_GENERIC_ERROR;
919 ** implementation of libvlc message object
922 LibvlcLogNPObject::~LibvlcLogNPObject()
926 if( messagesObj ) NPN_ReleaseObject(messagesObj);
930 const NPUTF8 * const LibvlcLogNPObject::propertyNames[] =
935 COUNTNAMES(LibvlcLogNPObject,propertyCount,propertyNames);
937 enum LibvlcLogNPObjectPropertyIds
943 RuntimeNPObject::InvokeResult
944 LibvlcLogNPObject::getProperty(int index, NPVariant &result)
946 /* is plugin still running */
947 if( isPluginRunning() )
949 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
950 libvlc_exception_t ex;
951 libvlc_exception_init(&ex);
955 case ID_log_messages:
957 // create child object in lazyman fashion to avoid
958 // ownership problem with firefox
960 messagesObj = NPN_CreateObject(_instance,
961 RuntimeNPClass<LibvlcMessagesNPObject>::getClass());
962 OBJECT_TO_NPVARIANT(NPN_RetainObject(messagesObj), result);
963 return INVOKERESULT_NO_ERROR;
965 case ID_log_verbosity:
967 if( p_plugin->getLog() )
969 INT32_TO_NPVARIANT( libvlc_get_log_verbosity(
970 p_plugin->getVLC(), &ex), result);
971 RETURN_ON_EXCEPTION(this,ex);
975 /* log is not enabled, return -1 */
976 DOUBLE_TO_NPVARIANT(-1.0, result);
978 return INVOKERESULT_NO_ERROR;
984 return INVOKERESULT_GENERIC_ERROR;
987 RuntimeNPObject::InvokeResult
988 LibvlcLogNPObject::setProperty(int index, const NPVariant &value)
990 /* is plugin still running */
991 if( isPluginRunning() )
993 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
994 libvlc_exception_t ex;
995 libvlc_exception_init(&ex);
999 case ID_log_verbosity:
1000 if( isNumberValue(value) )
1002 libvlc_instance_t* p_libvlc = p_plugin->getVLC();
1003 libvlc_log_t *p_log = p_plugin->getLog();
1004 int verbosity = numberValue(value);
1005 if( verbosity >= 0 )
1009 p_log = libvlc_log_open(p_libvlc, &ex);
1010 RETURN_ON_EXCEPTION(this,ex);
1011 p_plugin->setLog(p_log);
1013 libvlc_set_log_verbosity(p_libvlc, (unsigned)verbosity, &ex);
1014 RETURN_ON_EXCEPTION(this,ex);
1018 /* close log when verbosity is set to -1 */
1019 p_plugin->setLog(NULL);
1020 libvlc_log_close(p_log, &ex);
1021 RETURN_ON_EXCEPTION(this,ex);
1023 return INVOKERESULT_NO_ERROR;
1025 return INVOKERESULT_INVALID_VALUE;
1030 return INVOKERESULT_GENERIC_ERROR;
1033 const NPUTF8 * const LibvlcLogNPObject::methodNames[] =
1037 COUNTNAMES(LibvlcLogNPObject,methodCount,methodNames);
1040 ** implementation of libvlc playlist items object
1043 const NPUTF8 * const LibvlcPlaylistItemsNPObject::propertyNames[] =
1047 COUNTNAMES(LibvlcPlaylistItemsNPObject,propertyCount,propertyNames);
1049 enum LibvlcPlaylistItemsNPObjectPropertyIds
1051 ID_playlistitems_count,
1054 RuntimeNPObject::InvokeResult
1055 LibvlcPlaylistItemsNPObject::getProperty(int index, NPVariant &result)
1057 /* is plugin still running */
1058 if( isPluginRunning() )
1060 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1061 libvlc_exception_t ex;
1062 libvlc_exception_init(&ex);
1066 case ID_playlistitems_count:
1068 int val = p_plugin->playlist_count(&ex);
1069 RETURN_ON_EXCEPTION(this,ex);
1070 INT32_TO_NPVARIANT(val, result);
1071 return INVOKERESULT_NO_ERROR;
1077 return INVOKERESULT_GENERIC_ERROR;
1080 const NPUTF8 * const LibvlcPlaylistItemsNPObject::methodNames[] =
1085 COUNTNAMES(LibvlcPlaylistItemsNPObject,methodCount,methodNames);
1087 enum LibvlcPlaylistItemsNPObjectMethodIds
1089 ID_playlistitems_clear,
1090 ID_playlistitems_remove,
1093 RuntimeNPObject::InvokeResult
1094 LibvlcPlaylistItemsNPObject::invoke(int index, const NPVariant *args,
1095 uint32_t argCount, NPVariant &result)
1097 /* is plugin still running */
1098 if( isPluginRunning() )
1100 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1101 libvlc_exception_t ex;
1102 libvlc_exception_init(&ex);
1106 case ID_playlistitems_clear:
1109 p_plugin->playlist_clear(&ex);
1110 RETURN_ON_EXCEPTION(this,ex);
1111 VOID_TO_NPVARIANT(result);
1112 return INVOKERESULT_NO_ERROR;
1114 return INVOKERESULT_NO_SUCH_METHOD;
1115 case ID_playlistitems_remove:
1116 if( (argCount == 1) && isNumberValue(args[0]) )
1118 p_plugin->playlist_delete_item(numberValue(args[0]),&ex);
1119 RETURN_ON_EXCEPTION(this,ex);
1120 VOID_TO_NPVARIANT(result);
1121 return INVOKERESULT_NO_ERROR;
1123 return INVOKERESULT_NO_SUCH_METHOD;
1128 return INVOKERESULT_GENERIC_ERROR;
1132 ** implementation of libvlc playlist object
1135 LibvlcPlaylistNPObject::~LibvlcPlaylistNPObject()
1139 if( playlistItemsObj ) NPN_ReleaseObject(playlistItemsObj);
1143 const NPUTF8 * const LibvlcPlaylistNPObject::propertyNames[] =
1145 "itemCount", /* deprecated */
1149 COUNTNAMES(LibvlcPlaylistNPObject,propertyCount,propertyNames);
1151 enum LibvlcPlaylistNPObjectPropertyIds
1153 ID_playlist_itemcount,
1154 ID_playlist_isplaying,
1158 RuntimeNPObject::InvokeResult
1159 LibvlcPlaylistNPObject::getProperty(int index, NPVariant &result)
1161 /* is plugin still running */
1162 if( isPluginRunning() )
1164 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1165 libvlc_exception_t ex;
1166 libvlc_exception_init(&ex);
1170 case ID_playlist_itemcount: /* deprecated */
1172 int val = p_plugin->playlist_count(&ex);
1173 RETURN_ON_EXCEPTION(this,ex);
1174 INT32_TO_NPVARIANT(val, result);
1175 return INVOKERESULT_NO_ERROR;
1177 case ID_playlist_isplaying:
1179 int val = p_plugin->playlist_isplaying(&ex);
1180 RETURN_ON_EXCEPTION(this,ex);
1181 BOOLEAN_TO_NPVARIANT(val, result);
1182 return INVOKERESULT_NO_ERROR;
1184 case ID_playlist_items:
1186 // create child object in lazyman fashion to avoid
1187 // ownership problem with firefox
1188 if( ! playlistItemsObj )
1190 NPN_CreateObject(_instance, RuntimeNPClass<
1191 LibvlcPlaylistItemsNPObject>::getClass());
1192 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistItemsObj), result);
1193 return INVOKERESULT_NO_ERROR;
1199 return INVOKERESULT_GENERIC_ERROR;
1202 const NPUTF8 * const LibvlcPlaylistNPObject::methodNames[] =
1211 "clear", /* deprecated */
1212 "removeItem", /* deprecated */
1214 COUNTNAMES(LibvlcPlaylistNPObject,methodCount,methodNames);
1216 enum LibvlcPlaylistNPObjectMethodIds
1220 ID_playlist_playItem,
1221 ID_playlist_togglepause,
1226 ID_playlist_removeitem
1229 RuntimeNPObject::InvokeResult
1230 LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
1231 uint32_t argCount, NPVariant &result)
1233 /* is plugin still running */
1234 if( isPluginRunning() )
1236 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1237 libvlc_exception_t ex;
1238 libvlc_exception_init(&ex);
1242 // XXX FIXME this needs squashing into something much smaller
1243 case ID_playlist_add:
1245 if( (argCount < 1) || (argCount > 3) )
1246 return INVOKERESULT_NO_SUCH_METHOD;
1251 if( NPVARIANT_IS_STRING(args[0]) )
1253 char *s = stringValue(NPVARIANT_TO_STRING(args[0]));
1256 url = p_plugin->getAbsoluteURL(s);
1260 // problem with combining url, use argument
1264 return INVOKERESULT_OUT_OF_MEMORY;
1267 return INVOKERESULT_NO_SUCH_METHOD;
1271 // grab name if available
1274 if( NPVARIANT_IS_NULL(args[1]) )
1278 else if( NPVARIANT_IS_STRING(args[1]) )
1280 name = stringValue(NPVARIANT_TO_STRING(args[1]));
1285 return INVOKERESULT_INVALID_VALUE;
1290 char** ppsz_options = NULL;
1292 // grab options if available
1295 if( NPVARIANT_IS_NULL(args[2]) )
1299 else if( NPVARIANT_IS_STRING(args[2]) )
1301 parseOptions(NPVARIANT_TO_STRING(args[2]),
1302 &i_options, &ppsz_options);
1305 else if( NPVARIANT_IS_OBJECT(args[2]) )
1307 parseOptions(NPVARIANT_TO_OBJECT(args[2]),
1308 &i_options, &ppsz_options);
1314 return INVOKERESULT_INVALID_VALUE;
1318 int item = p_plugin->playlist_add_extended_untrusted(url, name, i_options,
1319 const_cast<const char **>(ppsz_options), &ex);
1322 for( int i=0; i< i_options; ++i )
1324 free(ppsz_options[i]);
1328 RETURN_ON_EXCEPTION(this,ex);
1329 INT32_TO_NPVARIANT(item, result);
1330 return INVOKERESULT_NO_ERROR;
1332 case ID_playlist_play:
1335 p_plugin->playlist_play(&ex);
1336 RETURN_ON_EXCEPTION(this,ex);
1337 VOID_TO_NPVARIANT(result);
1338 return INVOKERESULT_NO_ERROR;
1340 return INVOKERESULT_NO_SUCH_METHOD;
1341 case ID_playlist_playItem:
1342 if( (argCount == 1) && isNumberValue(args[0]) )
1344 p_plugin->playlist_play_item(numberValue(args[0]),&ex);
1345 RETURN_ON_EXCEPTION(this,ex);
1346 VOID_TO_NPVARIANT(result);
1347 return INVOKERESULT_NO_ERROR;
1349 return INVOKERESULT_NO_SUCH_METHOD;
1350 case ID_playlist_togglepause:
1353 p_plugin->playlist_pause(&ex);
1354 RETURN_ON_EXCEPTION(this,ex);
1355 VOID_TO_NPVARIANT(result);
1356 return INVOKERESULT_NO_ERROR;
1358 return INVOKERESULT_NO_SUCH_METHOD;
1359 case ID_playlist_stop:
1362 p_plugin->playlist_stop(&ex);
1363 RETURN_ON_EXCEPTION(this,ex);
1364 VOID_TO_NPVARIANT(result);
1365 return INVOKERESULT_NO_ERROR;
1367 return INVOKERESULT_NO_SUCH_METHOD;
1368 case ID_playlist_next:
1371 p_plugin->playlist_next(&ex);
1372 RETURN_ON_EXCEPTION(this,ex);
1373 VOID_TO_NPVARIANT(result);
1374 return INVOKERESULT_NO_ERROR;
1376 return INVOKERESULT_NO_SUCH_METHOD;
1377 case ID_playlist_prev:
1380 p_plugin->playlist_prev(&ex);
1381 RETURN_ON_EXCEPTION(this,ex);
1382 VOID_TO_NPVARIANT(result);
1383 return INVOKERESULT_NO_ERROR;
1385 return INVOKERESULT_NO_SUCH_METHOD;
1386 case ID_playlist_clear: /* deprecated */
1389 p_plugin->playlist_clear(&ex);
1390 RETURN_ON_EXCEPTION(this,ex);
1391 VOID_TO_NPVARIANT(result);
1392 return INVOKERESULT_NO_ERROR;
1394 return INVOKERESULT_NO_SUCH_METHOD;
1395 case ID_playlist_removeitem: /* deprecated */
1396 if( (argCount == 1) && isNumberValue(args[0]) )
1398 p_plugin->playlist_delete_item(numberValue(args[0]), &ex);
1399 RETURN_ON_EXCEPTION(this,ex);
1400 VOID_TO_NPVARIANT(result);
1401 return INVOKERESULT_NO_ERROR;
1403 return INVOKERESULT_NO_SUCH_METHOD;
1408 return INVOKERESULT_GENERIC_ERROR;
1411 // XXX FIXME The new playlist_add creates a media instance and feeds it
1412 // XXX FIXME these options one at a time, so this hunk of code does lots
1413 // XXX FIXME of unnecessairy work. Break out something that can do one
1414 // XXX FIXME option at a time and doesn't need to realloc().
1415 // XXX FIXME Same for the other version of parseOptions.
1417 void LibvlcPlaylistNPObject::parseOptions(const NPString &nps,
1418 int *i_options, char*** ppsz_options)
1420 if( nps.utf8length )
1422 char *s = stringValue(nps);
1427 char **options = (char **)malloc(capacity*sizeof(char *));
1432 char *end = val + nps.utf8length;
1435 // skip leading blanks
1437 && ((*val == ' ' ) || (*val == '\t')) )
1441 // skip till we get a blank character
1447 if( ('\'' == c) || ('"' == c) )
1449 // skip till end of string
1450 while( (val < end) && (*(val++) != c ) );
1456 if( nOptions == capacity )
1459 char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
1462 /* failed to allocate more memory */
1464 /* return what we got so far */
1465 *i_options = nOptions;
1466 *ppsz_options = options;
1469 options = moreOptions;
1472 options[nOptions++] = strdup(start);
1475 // must be end of string
1478 *i_options = nOptions;
1479 *ppsz_options = options;
1486 // XXX FIXME See comment at the other parseOptions variant.
1487 void LibvlcPlaylistNPObject::parseOptions(NPObject *obj, int *i_options,
1488 char*** ppsz_options)
1490 /* WARNING: Safari does not implement NPN_HasProperty/NPN_HasMethod */
1494 /* we are expecting to have a Javascript Array object */
1495 NPIdentifier propId = NPN_GetStringIdentifier("length");
1496 if( NPN_GetProperty(_instance, obj, propId, &value) )
1498 int count = numberValue(value);
1499 NPN_ReleaseVariantValue(&value);
1504 char **options = (char **)malloc(capacity*sizeof(char *));
1509 while( nOptions < count )
1511 propId = NPN_GetIntIdentifier(nOptions);
1512 if( ! NPN_GetProperty(_instance, obj, propId, &value) )
1513 /* return what we got so far */
1516 if( ! NPVARIANT_IS_STRING(value) )
1518 /* return what we got so far */
1519 NPN_ReleaseVariantValue(&value);
1523 if( nOptions == capacity )
1526 char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
1529 /* failed to allocate more memory */
1530 NPN_ReleaseVariantValue(&value);
1531 /* return what we got so far */
1532 *i_options = nOptions;
1533 *ppsz_options = options;
1536 options = moreOptions;
1539 options[nOptions++] = stringValue(value);
1541 *i_options = nOptions;
1542 *ppsz_options = options;
1549 ** implementation of libvlc video object
1552 const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] =
1563 enum LibvlcVideoNPObjectPropertyIds
1565 ID_video_fullscreen,
1568 ID_video_aspectratio,
1573 COUNTNAMES(LibvlcVideoNPObject,propertyCount,propertyNames);
1575 RuntimeNPObject::InvokeResult
1576 LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
1578 /* is plugin still running */
1579 if( isPluginRunning() )
1581 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1582 libvlc_exception_t ex;
1583 libvlc_exception_init(&ex);
1585 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1586 RETURN_ON_EXCEPTION(this,ex);
1590 case ID_video_fullscreen:
1592 int val = p_plugin->get_fullscreen(&ex);
1593 RETURN_ON_EXCEPTION(this,ex);
1594 BOOLEAN_TO_NPVARIANT(val, result);
1595 return INVOKERESULT_NO_ERROR;
1597 case ID_video_height:
1599 int val = libvlc_video_get_height(p_md, &ex);
1600 RETURN_ON_EXCEPTION(this,ex);
1601 INT32_TO_NPVARIANT(val, result);
1602 return INVOKERESULT_NO_ERROR;
1604 case ID_video_width:
1606 int val = libvlc_video_get_width(p_md, &ex);
1607 RETURN_ON_EXCEPTION(this,ex);
1608 INT32_TO_NPVARIANT(val, result);
1609 return INVOKERESULT_NO_ERROR;
1611 case ID_video_aspectratio:
1613 NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1614 RETURN_ON_EXCEPTION(this,ex);
1616 return INVOKERESULT_GENERIC_ERROR;
1618 STRINGZ_TO_NPVARIANT(psz_aspect, result);
1619 return INVOKERESULT_NO_ERROR;
1621 case ID_video_subtitle:
1623 int i_spu = libvlc_video_get_spu(p_md, &ex);
1624 RETURN_ON_EXCEPTION(this,ex);
1625 INT32_TO_NPVARIANT(i_spu, result);
1626 return INVOKERESULT_NO_ERROR;
1630 NPUTF8 *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1631 RETURN_ON_EXCEPTION(this,ex);
1633 return INVOKERESULT_GENERIC_ERROR;
1635 STRINGZ_TO_NPVARIANT(psz_geometry, result);
1636 return INVOKERESULT_NO_ERROR;
1638 case ID_video_teletext:
1640 int i_page = libvlc_video_get_teletext(p_md, &ex);
1641 RETURN_ON_EXCEPTION(this,ex);
1642 INT32_TO_NPVARIANT(i_page, result);
1643 return INVOKERESULT_NO_ERROR;
1647 return INVOKERESULT_GENERIC_ERROR;
1650 RuntimeNPObject::InvokeResult
1651 LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
1653 /* is plugin still running */
1654 if( isPluginRunning() )
1656 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1657 libvlc_exception_t ex;
1658 libvlc_exception_init(&ex);
1660 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1661 RETURN_ON_EXCEPTION(this,ex);
1665 case ID_video_fullscreen:
1667 if( ! NPVARIANT_IS_BOOLEAN(value) )
1669 return INVOKERESULT_INVALID_VALUE;
1672 int val = NPVARIANT_TO_BOOLEAN(value);
1673 p_plugin->set_fullscreen(val, &ex);
1674 RETURN_ON_EXCEPTION(this,ex);
1675 return INVOKERESULT_NO_ERROR;
1677 case ID_video_aspectratio:
1679 char *psz_aspect = NULL;
1681 if( ! NPVARIANT_IS_STRING(value) )
1683 return INVOKERESULT_INVALID_VALUE;
1686 psz_aspect = stringValue(NPVARIANT_TO_STRING(value));
1689 return INVOKERESULT_GENERIC_ERROR;
1692 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
1694 RETURN_ON_EXCEPTION(this,ex);
1696 return INVOKERESULT_NO_ERROR;
1698 case ID_video_subtitle:
1700 if( isNumberValue(value) )
1702 libvlc_video_set_spu(p_md, numberValue(value), &ex);
1703 RETURN_ON_EXCEPTION(this,ex);
1705 return INVOKERESULT_NO_ERROR;
1707 return INVOKERESULT_INVALID_VALUE;
1711 char *psz_geometry = NULL;
1713 if( ! NPVARIANT_IS_STRING(value) )
1715 return INVOKERESULT_INVALID_VALUE;
1718 psz_geometry = stringValue(NPVARIANT_TO_STRING(value));
1721 return INVOKERESULT_GENERIC_ERROR;
1724 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
1726 RETURN_ON_EXCEPTION(this,ex);
1728 return INVOKERESULT_NO_ERROR;
1730 case ID_video_teletext:
1732 if( isNumberValue(value) )
1734 libvlc_video_set_teletext(p_md, numberValue(value), &ex);
1735 RETURN_ON_EXCEPTION(this,ex);
1737 return INVOKERESULT_NO_ERROR;
1739 return INVOKERESULT_INVALID_VALUE;
1743 return INVOKERESULT_GENERIC_ERROR;
1746 const NPUTF8 * const LibvlcVideoNPObject::methodNames[] =
1751 COUNTNAMES(LibvlcVideoNPObject,methodCount,methodNames);
1753 enum LibvlcVideoNPObjectMethodIds
1755 ID_video_togglefullscreen,
1756 ID_video_toggleteletext
1759 RuntimeNPObject::InvokeResult
1760 LibvlcVideoNPObject::invoke(int index, const NPVariant *args,
1761 uint32_t argCount, NPVariant &result)
1763 /* is plugin still running */
1764 if( isPluginRunning() )
1766 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1767 libvlc_exception_t ex;
1768 libvlc_exception_init(&ex);
1770 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1771 RETURN_ON_EXCEPTION(this,ex);
1775 case ID_video_togglefullscreen:
1778 p_plugin->toggle_fullscreen(&ex);
1779 RETURN_ON_EXCEPTION(this,ex);
1780 VOID_TO_NPVARIANT(result);
1781 return INVOKERESULT_NO_ERROR;
1783 return INVOKERESULT_NO_SUCH_METHOD;
1784 case ID_video_toggleteletext:
1787 libvlc_toggle_teletext(p_md, &ex);
1788 RETURN_ON_EXCEPTION(this,ex);
1789 VOID_TO_NPVARIANT(result);
1790 return INVOKERESULT_NO_ERROR;
1792 return INVOKERESULT_NO_SUCH_METHOD;
1794 return INVOKERESULT_NO_SUCH_METHOD;
1797 return INVOKERESULT_GENERIC_ERROR;