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( 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:
144 return invokeResultString(libvlc_get_version(),result);
149 return INVOKERESULT_GENERIC_ERROR;
152 const NPUTF8 * const LibvlcRootNPObject::methodNames[] =
156 COUNTNAMES(LibvlcRootNPObject,methodCount,methodNames);
158 enum LibvlcRootNPObjectMethodIds
163 RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index,
164 const NPVariant *args, uint32_t argCount, NPVariant &result)
166 /* is plugin still running */
167 if( isPluginRunning() )
169 libvlc_exception_t ex;
170 libvlc_exception_init(&ex);
174 case ID_root_versionInfo:
176 return INVOKERESULT_NO_SUCH_METHOD;
177 return invokeResultString(libvlc_get_version(),result);
182 return INVOKERESULT_GENERIC_ERROR;
186 ** implementation of libvlc audio object
189 const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] =
196 COUNTNAMES(LibvlcAudioNPObject,propertyCount,propertyNames);
198 enum LibvlcAudioNPObjectPropertyIds
206 RuntimeNPObject::InvokeResult
207 LibvlcAudioNPObject::getProperty(int index, NPVariant &result)
209 /* is plugin still running */
210 if( isPluginRunning() )
212 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
213 libvlc_exception_t ex;
214 libvlc_exception_init(&ex);
220 bool muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex);
221 RETURN_ON_EXCEPTION(this,ex);
222 BOOLEAN_TO_NPVARIANT(muted, result);
223 return INVOKERESULT_NO_ERROR;
225 case ID_audio_volume:
227 int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex);
228 RETURN_ON_EXCEPTION(this,ex);
229 INT32_TO_NPVARIANT(volume, result);
230 return INVOKERESULT_NO_ERROR;
234 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
235 RETURN_ON_EXCEPTION(this,ex);
236 int track = libvlc_audio_get_track(p_md, &ex);
237 RETURN_ON_EXCEPTION(this,ex);
238 INT32_TO_NPVARIANT(track, result);
239 return INVOKERESULT_NO_ERROR;
241 case ID_audio_channel:
243 int channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex);
244 RETURN_ON_EXCEPTION(this,ex);
245 INT32_TO_NPVARIANT(channel, result);
246 return INVOKERESULT_NO_ERROR;
252 return INVOKERESULT_GENERIC_ERROR;
255 RuntimeNPObject::InvokeResult
256 LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)
258 /* is plugin still running */
259 if( isPluginRunning() )
261 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
262 libvlc_exception_t ex;
263 libvlc_exception_init(&ex);
268 if( NPVARIANT_IS_BOOLEAN(value) )
270 libvlc_audio_set_mute(p_plugin->getVLC(),
271 NPVARIANT_TO_BOOLEAN(value), &ex);
272 RETURN_ON_EXCEPTION(this,ex);
273 return INVOKERESULT_NO_ERROR;
275 return INVOKERESULT_INVALID_VALUE;
276 case ID_audio_volume:
277 if( isNumberValue(value) )
279 libvlc_audio_set_volume(p_plugin->getVLC(),
280 numberValue(value), &ex);
281 RETURN_ON_EXCEPTION(this,ex);
282 return INVOKERESULT_NO_ERROR;
284 return INVOKERESULT_INVALID_VALUE;
286 if( isNumberValue(value) )
288 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
289 RETURN_ON_EXCEPTION(this,ex);
290 libvlc_audio_set_track(p_md, numberValue(value), &ex);
291 RETURN_ON_EXCEPTION(this,ex);
292 return INVOKERESULT_NO_ERROR;
294 return INVOKERESULT_INVALID_VALUE;
295 case ID_audio_channel:
296 if( isNumberValue(value) )
298 libvlc_audio_set_channel(p_plugin->getVLC(),
299 numberValue(value), &ex);
300 RETURN_ON_EXCEPTION(this,ex);
301 return INVOKERESULT_NO_ERROR;
303 return INVOKERESULT_INVALID_VALUE;
308 return INVOKERESULT_GENERIC_ERROR;
311 const NPUTF8 * const LibvlcAudioNPObject::methodNames[] =
315 COUNTNAMES(LibvlcAudioNPObject,methodCount,methodNames);
317 enum LibvlcAudioNPObjectMethodIds
322 RuntimeNPObject::InvokeResult
323 LibvlcAudioNPObject::invoke(int index, const NPVariant *args,
324 uint32_t argCount, NPVariant &result)
326 /* is plugin still running */
327 if( isPluginRunning() )
329 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
330 libvlc_exception_t ex;
331 libvlc_exception_init(&ex);
335 case ID_audio_togglemute:
338 libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex);
339 RETURN_ON_EXCEPTION(this,ex);
340 VOID_TO_NPVARIANT(result);
341 return INVOKERESULT_NO_ERROR;
343 return INVOKERESULT_NO_SUCH_METHOD;
348 return INVOKERESULT_GENERIC_ERROR;
352 ** implementation of libvlc input object
355 const NPUTF8 * const LibvlcInputNPObject::propertyNames[] =
365 COUNTNAMES(LibvlcInputNPObject,propertyCount,propertyNames);
367 enum LibvlcInputNPObjectPropertyIds
378 RuntimeNPObject::InvokeResult
379 LibvlcInputNPObject::getProperty(int index, NPVariant &result)
381 /* is plugin still running */
382 if( isPluginRunning() )
384 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
385 libvlc_exception_t ex;
386 libvlc_exception_init(&ex);
388 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
389 if( libvlc_exception_raised(&ex) )
391 if( index != ID_input_state )
393 NPN_SetException(this, libvlc_exception_get_message(&ex));
394 libvlc_exception_clear(&ex);
395 return INVOKERESULT_GENERIC_ERROR;
399 /* for input state, return CLOSED rather than an exception */
400 INT32_TO_NPVARIANT(0, result);
401 libvlc_exception_clear(&ex);
402 return INVOKERESULT_NO_ERROR;
408 case ID_input_length:
410 double val = (double)libvlc_media_player_get_length(p_md, &ex);
411 RETURN_ON_EXCEPTION(this,ex);
412 DOUBLE_TO_NPVARIANT(val, result);
413 return INVOKERESULT_NO_ERROR;
415 case ID_input_position:
417 double val = libvlc_media_player_get_position(p_md, &ex);
418 RETURN_ON_EXCEPTION(this,ex);
419 DOUBLE_TO_NPVARIANT(val, result);
420 return INVOKERESULT_NO_ERROR;
424 double val = (double)libvlc_media_player_get_time(p_md, &ex);
425 RETURN_ON_EXCEPTION(this,ex);
426 DOUBLE_TO_NPVARIANT(val, result);
427 return INVOKERESULT_NO_ERROR;
431 int val = libvlc_media_player_get_state(p_md, &ex);
432 RETURN_ON_EXCEPTION(this,ex);
433 INT32_TO_NPVARIANT(val, result);
434 return INVOKERESULT_NO_ERROR;
438 float val = libvlc_media_player_get_rate(p_md, &ex);
439 RETURN_ON_EXCEPTION(this,ex);
440 DOUBLE_TO_NPVARIANT(val, result);
441 return INVOKERESULT_NO_ERROR;
445 double val = libvlc_media_player_get_fps(p_md, &ex);
446 RETURN_ON_EXCEPTION(this,ex);
447 DOUBLE_TO_NPVARIANT(val, result);
448 return INVOKERESULT_NO_ERROR;
450 case ID_input_hasvout:
452 bool val = p_plugin->player_has_vout(&ex);
453 RETURN_ON_EXCEPTION(this,ex);
454 BOOLEAN_TO_NPVARIANT(val, result);
455 return INVOKERESULT_NO_ERROR;
461 return INVOKERESULT_GENERIC_ERROR;
464 RuntimeNPObject::InvokeResult
465 LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
467 /* is plugin still running */
468 if( isPluginRunning() )
470 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
471 libvlc_exception_t ex;
472 libvlc_exception_init(&ex);
474 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
475 RETURN_ON_EXCEPTION(this,ex);
479 case ID_input_position:
481 if( ! NPVARIANT_IS_DOUBLE(value) )
483 return INVOKERESULT_INVALID_VALUE;
486 float val = (float)NPVARIANT_TO_DOUBLE(value);
487 libvlc_media_player_set_position(p_md, val, &ex);
488 RETURN_ON_EXCEPTION(this,ex);
489 return INVOKERESULT_NO_ERROR;
494 if( NPVARIANT_IS_INT32(value) )
495 val = (int64_t)NPVARIANT_TO_INT32(value);
496 else if( NPVARIANT_IS_DOUBLE(value) )
497 val = (int64_t)NPVARIANT_TO_DOUBLE(value);
500 return INVOKERESULT_INVALID_VALUE;
503 libvlc_media_player_set_time(p_md, val, &ex);
504 RETURN_ON_EXCEPTION(this,ex);
505 return INVOKERESULT_NO_ERROR;
510 if( NPVARIANT_IS_INT32(value) )
511 val = (float)NPVARIANT_TO_INT32(value);
512 else if( NPVARIANT_IS_DOUBLE(value) )
513 val = (float)NPVARIANT_TO_DOUBLE(value);
516 return INVOKERESULT_INVALID_VALUE;
519 libvlc_media_player_set_rate(p_md, val, &ex);
520 RETURN_ON_EXCEPTION(this,ex);
521 return INVOKERESULT_NO_ERROR;
527 return INVOKERESULT_GENERIC_ERROR;
530 const NPUTF8 * const LibvlcInputNPObject::methodNames[] =
535 COUNTNAMES(LibvlcInputNPObject,methodCount,methodNames);
538 ** implementation of libvlc message object
541 const NPUTF8 * const LibvlcMessageNPObject::propertyNames[] =
549 COUNTNAMES(LibvlcMessageNPObject,propertyCount,propertyNames);
551 enum LibvlcMessageNPObjectPropertyIds
560 RuntimeNPObject::InvokeResult
561 LibvlcMessageNPObject::getProperty(int index, NPVariant &result)
563 /* is plugin still running */
564 if( isPluginRunning() )
568 case ID_message_severity:
570 INT32_TO_NPVARIANT(_msg.i_severity, result);
571 return INVOKERESULT_NO_ERROR;
573 case ID_message_type:
574 return invokeResultString(_msg.psz_type,result);
575 case ID_message_name:
576 return invokeResultString(_msg.psz_name,result);
577 case ID_message_header:
578 return invokeResultString(_msg.psz_header,result);
579 case ID_message_message:
580 return invokeResultString(_msg.psz_message,result);
585 return INVOKERESULT_GENERIC_ERROR;
588 const NPUTF8 * const LibvlcMessageNPObject::methodNames[] =
592 COUNTNAMES(LibvlcMessageNPObject,methodCount,methodNames);
595 ** implementation of libvlc message iterator object
598 LibvlcMessageIteratorNPObject::LibvlcMessageIteratorNPObject(NPP instance,
599 const NPClass *aClass) :
600 RuntimeNPObject(instance, aClass),
603 // XXX FIXME use _instance or instance in this method?
605 /* is plugin still running */
606 if( instance->pdata )
608 VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
609 libvlc_log_t *p_log = p_plugin->getLog();
612 _p_iter = libvlc_log_get_iterator(p_log, NULL);
617 LibvlcMessageIteratorNPObject::~LibvlcMessageIteratorNPObject()
620 libvlc_log_iterator_free(_p_iter, NULL);
623 const NPUTF8 * const LibvlcMessageIteratorNPObject::propertyNames[] =
627 COUNTNAMES(LibvlcMessageIteratorNPObject,propertyCount,propertyNames);
629 enum LibvlcMessageIteratorNPObjectPropertyIds
631 ID_messageiterator_hasNext,
634 RuntimeNPObject::InvokeResult
635 LibvlcMessageIteratorNPObject::getProperty(int index, NPVariant &result)
637 /* is plugin still running */
638 if( isPluginRunning() )
640 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
643 case ID_messageiterator_hasNext:
645 if( _p_iter && p_plugin->getLog() )
647 libvlc_exception_t ex;
648 libvlc_exception_init(&ex);
650 BOOLEAN_TO_NPVARIANT(
651 libvlc_log_iterator_has_next(_p_iter, &ex), result );
652 RETURN_ON_EXCEPTION(this,ex);
656 BOOLEAN_TO_NPVARIANT(0, result);
658 return INVOKERESULT_NO_ERROR;
664 return INVOKERESULT_GENERIC_ERROR;
667 const NPUTF8 * const LibvlcMessageIteratorNPObject::methodNames[] =
671 COUNTNAMES(LibvlcMessageIteratorNPObject,methodCount,methodNames);
673 enum LibvlcMessageIteratorNPObjectMethodIds
675 ID_messageiterator_next,
678 RuntimeNPObject::InvokeResult
679 LibvlcMessageIteratorNPObject::invoke(int index, const NPVariant *args,
680 uint32_t argCount, NPVariant &result)
682 /* is plugin still running */
683 if( isPluginRunning() )
685 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
686 libvlc_exception_t ex;
687 libvlc_exception_init(&ex);
691 case ID_messageiterator_next:
694 if( _p_iter && p_plugin->getLog() )
696 struct libvlc_log_message_t buffer;
698 buffer.sizeof_msg = sizeof(buffer);
700 libvlc_log_iterator_next(_p_iter, &buffer, &ex);
701 RETURN_ON_EXCEPTION(this,ex);
703 LibvlcMessageNPObject* message =
704 static_cast<LibvlcMessageNPObject*>(
705 NPN_CreateObject(_instance, RuntimeNPClass<
706 LibvlcMessageNPObject>::getClass()));
709 message->setMessage(buffer);
710 OBJECT_TO_NPVARIANT(message, result);
711 return INVOKERESULT_NO_ERROR;
713 return INVOKERESULT_OUT_OF_MEMORY;
715 return INVOKERESULT_GENERIC_ERROR;
717 return INVOKERESULT_NO_SUCH_METHOD;
722 return INVOKERESULT_GENERIC_ERROR;
726 ** implementation of libvlc message object
729 const NPUTF8 * const LibvlcMessagesNPObject::propertyNames[] =
733 COUNTNAMES(LibvlcMessagesNPObject,propertyCount,propertyNames);
735 enum LibvlcMessagesNPObjectPropertyIds
740 RuntimeNPObject::InvokeResult
741 LibvlcMessagesNPObject::getProperty(int index, NPVariant &result)
743 /* is plugin still running */
744 if( isPluginRunning() )
746 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
749 case ID_messages_count:
751 libvlc_log_t *p_log = p_plugin->getLog();
754 libvlc_exception_t ex;
755 libvlc_exception_init(&ex);
757 INT32_TO_NPVARIANT(libvlc_log_count(p_log, &ex), result);
758 RETURN_ON_EXCEPTION(this,ex);
762 INT32_TO_NPVARIANT(0, result);
764 return INVOKERESULT_NO_ERROR;
770 return INVOKERESULT_GENERIC_ERROR;
773 const NPUTF8 * const LibvlcMessagesNPObject::methodNames[] =
778 COUNTNAMES(LibvlcMessagesNPObject,methodCount,methodNames);
780 enum LibvlcMessagesNPObjectMethodIds
783 ID_messages_iterator,
786 RuntimeNPObject::InvokeResult
787 LibvlcMessagesNPObject::invoke(int index, const NPVariant *args,
788 uint32_t argCount, NPVariant &result)
790 /* is plugin still running */
791 if( isPluginRunning() )
793 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
794 libvlc_exception_t ex;
795 libvlc_exception_init(&ex);
799 case ID_messages_clear:
802 libvlc_log_t *p_log = p_plugin->getLog();
805 libvlc_log_clear(p_log, &ex);
806 RETURN_ON_EXCEPTION(this,ex);
808 return INVOKERESULT_NO_ERROR;
810 return INVOKERESULT_NO_SUCH_METHOD;
812 case ID_messages_iterator:
815 LibvlcMessageIteratorNPObject* iter =
816 static_cast<LibvlcMessageIteratorNPObject*>(
817 NPN_CreateObject(_instance, RuntimeNPClass<
818 LibvlcMessageIteratorNPObject>::getClass()));
821 OBJECT_TO_NPVARIANT(iter, result);
822 return INVOKERESULT_NO_ERROR;
824 return INVOKERESULT_OUT_OF_MEMORY;
826 return INVOKERESULT_NO_SUCH_METHOD;
832 return INVOKERESULT_GENERIC_ERROR;
836 ** implementation of libvlc message object
839 LibvlcLogNPObject::~LibvlcLogNPObject()
843 if( messagesObj ) NPN_ReleaseObject(messagesObj);
847 const NPUTF8 * const LibvlcLogNPObject::propertyNames[] =
852 COUNTNAMES(LibvlcLogNPObject,propertyCount,propertyNames);
854 enum LibvlcLogNPObjectPropertyIds
860 RuntimeNPObject::InvokeResult
861 LibvlcLogNPObject::getProperty(int index, NPVariant &result)
863 /* is plugin still running */
864 if( isPluginRunning() )
866 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
867 libvlc_exception_t ex;
868 libvlc_exception_init(&ex);
872 case ID_log_messages:
874 // create child object in lazyman fashion to avoid
875 // ownership problem with firefox
877 messagesObj = NPN_CreateObject(_instance,
878 RuntimeNPClass<LibvlcMessagesNPObject>::getClass());
879 OBJECT_TO_NPVARIANT(NPN_RetainObject(messagesObj), result);
880 return INVOKERESULT_NO_ERROR;
882 case ID_log_verbosity:
884 if( p_plugin->getLog() )
886 INT32_TO_NPVARIANT( libvlc_get_log_verbosity(
887 p_plugin->getVLC(), &ex), result);
888 RETURN_ON_EXCEPTION(this,ex);
892 /* log is not enabled, return -1 */
893 DOUBLE_TO_NPVARIANT(-1.0, result);
895 return INVOKERESULT_NO_ERROR;
901 return INVOKERESULT_GENERIC_ERROR;
904 RuntimeNPObject::InvokeResult
905 LibvlcLogNPObject::setProperty(int index, const NPVariant &value)
907 /* is plugin still running */
908 if( isPluginRunning() )
910 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
911 libvlc_exception_t ex;
912 libvlc_exception_init(&ex);
916 case ID_log_verbosity:
917 if( isNumberValue(value) )
919 libvlc_instance_t* p_libvlc = p_plugin->getVLC();
920 libvlc_log_t *p_log = p_plugin->getLog();
921 int verbosity = numberValue(value);
926 p_log = libvlc_log_open(p_libvlc, &ex);
927 RETURN_ON_EXCEPTION(this,ex);
928 p_plugin->setLog(p_log);
930 libvlc_set_log_verbosity(p_libvlc, (unsigned)verbosity, &ex);
931 RETURN_ON_EXCEPTION(this,ex);
935 /* close log when verbosity is set to -1 */
936 p_plugin->setLog(NULL);
937 libvlc_log_close(p_log, &ex);
938 RETURN_ON_EXCEPTION(this,ex);
940 return INVOKERESULT_NO_ERROR;
942 return INVOKERESULT_INVALID_VALUE;
947 return INVOKERESULT_GENERIC_ERROR;
950 const NPUTF8 * const LibvlcLogNPObject::methodNames[] =
954 COUNTNAMES(LibvlcLogNPObject,methodCount,methodNames);
957 ** implementation of libvlc playlist items object
960 const NPUTF8 * const LibvlcPlaylistItemsNPObject::propertyNames[] =
964 COUNTNAMES(LibvlcPlaylistItemsNPObject,propertyCount,propertyNames);
966 enum LibvlcPlaylistItemsNPObjectPropertyIds
968 ID_playlistitems_count,
971 RuntimeNPObject::InvokeResult
972 LibvlcPlaylistItemsNPObject::getProperty(int index, NPVariant &result)
974 /* is plugin still running */
975 if( isPluginRunning() )
977 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
978 libvlc_exception_t ex;
979 libvlc_exception_init(&ex);
983 case ID_playlistitems_count:
985 int val = p_plugin->playlist_count(&ex);
986 RETURN_ON_EXCEPTION(this,ex);
987 INT32_TO_NPVARIANT(val, result);
988 return INVOKERESULT_NO_ERROR;
994 return INVOKERESULT_GENERIC_ERROR;
997 const NPUTF8 * const LibvlcPlaylistItemsNPObject::methodNames[] =
1002 COUNTNAMES(LibvlcPlaylistItemsNPObject,methodCount,methodNames);
1004 enum LibvlcPlaylistItemsNPObjectMethodIds
1006 ID_playlistitems_clear,
1007 ID_playlistitems_remove,
1010 RuntimeNPObject::InvokeResult
1011 LibvlcPlaylistItemsNPObject::invoke(int index, const NPVariant *args,
1012 uint32_t argCount, NPVariant &result)
1014 /* is plugin still running */
1015 if( isPluginRunning() )
1017 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1018 libvlc_exception_t ex;
1019 libvlc_exception_init(&ex);
1023 case ID_playlistitems_clear:
1026 p_plugin->playlist_clear(&ex);
1027 RETURN_ON_EXCEPTION(this,ex);
1028 VOID_TO_NPVARIANT(result);
1029 return INVOKERESULT_NO_ERROR;
1031 return INVOKERESULT_NO_SUCH_METHOD;
1032 case ID_playlistitems_remove:
1033 if( (argCount == 1) && isNumberValue(args[0]) )
1035 p_plugin->playlist_delete_item(numberValue(args[0]),&ex);
1036 RETURN_ON_EXCEPTION(this,ex);
1037 VOID_TO_NPVARIANT(result);
1038 return INVOKERESULT_NO_ERROR;
1040 return INVOKERESULT_NO_SUCH_METHOD;
1045 return INVOKERESULT_GENERIC_ERROR;
1049 ** implementation of libvlc playlist object
1052 LibvlcPlaylistNPObject::~LibvlcPlaylistNPObject()
1054 // Why the isValid()?
1055 if( isValid() && playlistItemsObj )
1056 NPN_ReleaseObject(playlistItemsObj);
1059 const NPUTF8 * const LibvlcPlaylistNPObject::propertyNames[] =
1061 "itemCount", /* deprecated */
1065 COUNTNAMES(LibvlcPlaylistNPObject,propertyCount,propertyNames);
1067 enum LibvlcPlaylistNPObjectPropertyIds
1069 ID_playlist_itemcount,
1070 ID_playlist_isplaying,
1074 RuntimeNPObject::InvokeResult
1075 LibvlcPlaylistNPObject::getProperty(int index, NPVariant &result)
1077 /* is plugin still running */
1078 if( isPluginRunning() )
1080 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1081 libvlc_exception_t ex;
1082 libvlc_exception_init(&ex);
1086 case ID_playlist_itemcount: /* deprecated */
1088 int val = p_plugin->playlist_count(&ex);
1089 RETURN_ON_EXCEPTION(this,ex);
1090 INT32_TO_NPVARIANT(val, result);
1091 return INVOKERESULT_NO_ERROR;
1093 case ID_playlist_isplaying:
1095 int val = p_plugin->playlist_isplaying(&ex);
1096 RETURN_ON_EXCEPTION(this,ex);
1097 BOOLEAN_TO_NPVARIANT(val, result);
1098 return INVOKERESULT_NO_ERROR;
1100 case ID_playlist_items:
1102 // create child object in lazyman fashion to avoid
1103 // ownership problem with firefox
1104 if( ! playlistItemsObj )
1106 NPN_CreateObject(_instance, RuntimeNPClass<
1107 LibvlcPlaylistItemsNPObject>::getClass());
1108 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistItemsObj), result);
1109 return INVOKERESULT_NO_ERROR;
1115 return INVOKERESULT_GENERIC_ERROR;
1118 const NPUTF8 * const LibvlcPlaylistNPObject::methodNames[] =
1127 "clear", /* deprecated */
1128 "removeItem", /* deprecated */
1130 COUNTNAMES(LibvlcPlaylistNPObject,methodCount,methodNames);
1132 enum LibvlcPlaylistNPObjectMethodIds
1136 ID_playlist_playItem,
1137 ID_playlist_togglepause,
1142 ID_playlist_removeitem
1145 RuntimeNPObject::InvokeResult
1146 LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
1147 uint32_t argCount, NPVariant &result)
1149 /* is plugin still running */
1150 if( isPluginRunning() )
1152 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1153 libvlc_exception_t ex;
1154 libvlc_exception_init(&ex);
1158 // XXX FIXME this needs squashing into something much smaller
1159 case ID_playlist_add:
1161 if( (argCount < 1) || (argCount > 3) )
1162 return INVOKERESULT_NO_SUCH_METHOD;
1167 if( NPVARIANT_IS_STRING(args[0]) )
1169 char *s = stringValue(NPVARIANT_TO_STRING(args[0]));
1172 url = p_plugin->getAbsoluteURL(s);
1176 // problem with combining url, use argument
1180 return INVOKERESULT_OUT_OF_MEMORY;
1183 return INVOKERESULT_NO_SUCH_METHOD;
1187 // grab name if available
1190 if( NPVARIANT_IS_NULL(args[1]) )
1194 else if( NPVARIANT_IS_STRING(args[1]) )
1196 name = stringValue(NPVARIANT_TO_STRING(args[1]));
1201 return INVOKERESULT_INVALID_VALUE;
1206 char** ppsz_options = NULL;
1208 // grab options if available
1211 if( NPVARIANT_IS_NULL(args[2]) )
1215 else if( NPVARIANT_IS_STRING(args[2]) )
1217 parseOptions(NPVARIANT_TO_STRING(args[2]),
1218 &i_options, &ppsz_options);
1221 else if( NPVARIANT_IS_OBJECT(args[2]) )
1223 parseOptions(NPVARIANT_TO_OBJECT(args[2]),
1224 &i_options, &ppsz_options);
1230 return INVOKERESULT_INVALID_VALUE;
1234 int item = p_plugin->playlist_add_extended_untrusted(url, name,
1235 i_options, const_cast<const char **>(ppsz_options), &ex);
1238 for( int i=0; i< i_options; ++i )
1240 free(ppsz_options[i]);
1244 RETURN_ON_EXCEPTION(this,ex);
1245 INT32_TO_NPVARIANT(item, result);
1246 return INVOKERESULT_NO_ERROR;
1248 case ID_playlist_play:
1251 p_plugin->playlist_play(&ex);
1252 RETURN_ON_EXCEPTION(this,ex);
1253 VOID_TO_NPVARIANT(result);
1254 return INVOKERESULT_NO_ERROR;
1256 return INVOKERESULT_NO_SUCH_METHOD;
1257 case ID_playlist_playItem:
1258 if( (argCount == 1) && isNumberValue(args[0]) )
1260 p_plugin->playlist_play_item(numberValue(args[0]),&ex);
1261 RETURN_ON_EXCEPTION(this,ex);
1262 VOID_TO_NPVARIANT(result);
1263 return INVOKERESULT_NO_ERROR;
1265 return INVOKERESULT_NO_SUCH_METHOD;
1266 case ID_playlist_togglepause:
1269 p_plugin->playlist_pause(&ex);
1270 RETURN_ON_EXCEPTION(this,ex);
1271 VOID_TO_NPVARIANT(result);
1272 return INVOKERESULT_NO_ERROR;
1274 return INVOKERESULT_NO_SUCH_METHOD;
1275 case ID_playlist_stop:
1278 p_plugin->playlist_stop(&ex);
1279 RETURN_ON_EXCEPTION(this,ex);
1280 VOID_TO_NPVARIANT(result);
1281 return INVOKERESULT_NO_ERROR;
1283 return INVOKERESULT_NO_SUCH_METHOD;
1284 case ID_playlist_next:
1287 p_plugin->playlist_next(&ex);
1288 RETURN_ON_EXCEPTION(this,ex);
1289 VOID_TO_NPVARIANT(result);
1290 return INVOKERESULT_NO_ERROR;
1292 return INVOKERESULT_NO_SUCH_METHOD;
1293 case ID_playlist_prev:
1296 p_plugin->playlist_prev(&ex);
1297 RETURN_ON_EXCEPTION(this,ex);
1298 VOID_TO_NPVARIANT(result);
1299 return INVOKERESULT_NO_ERROR;
1301 return INVOKERESULT_NO_SUCH_METHOD;
1302 case ID_playlist_clear: /* deprecated */
1305 p_plugin->playlist_clear(&ex);
1306 RETURN_ON_EXCEPTION(this,ex);
1307 VOID_TO_NPVARIANT(result);
1308 return INVOKERESULT_NO_ERROR;
1310 return INVOKERESULT_NO_SUCH_METHOD;
1311 case ID_playlist_removeitem: /* deprecated */
1312 if( (argCount == 1) && isNumberValue(args[0]) )
1314 p_plugin->playlist_delete_item(numberValue(args[0]), &ex);
1315 RETURN_ON_EXCEPTION(this,ex);
1316 VOID_TO_NPVARIANT(result);
1317 return INVOKERESULT_NO_ERROR;
1319 return INVOKERESULT_NO_SUCH_METHOD;
1324 return INVOKERESULT_GENERIC_ERROR;
1327 // XXX FIXME The new playlist_add creates a media instance and feeds it
1328 // XXX FIXME these options one at a time, so this hunk of code does lots
1329 // XXX FIXME of unnecessairy work. Break out something that can do one
1330 // XXX FIXME option at a time and doesn't need to realloc().
1331 // XXX FIXME Same for the other version of parseOptions.
1333 void LibvlcPlaylistNPObject::parseOptions(const NPString &nps,
1334 int *i_options, char*** ppsz_options)
1336 if( nps.utf8length )
1338 char *s = stringValue(nps);
1343 char **options = (char **)malloc(capacity*sizeof(char *));
1348 char *end = val + nps.utf8length;
1351 // skip leading blanks
1353 && ((*val == ' ' ) || (*val == '\t')) )
1357 // skip till we get a blank character
1363 if( ('\'' == c) || ('"' == c) )
1365 // skip till end of string
1366 while( (val < end) && (*(val++) != c ) );
1372 if( nOptions == capacity )
1375 char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
1378 /* failed to allocate more memory */
1380 /* return what we got so far */
1381 *i_options = nOptions;
1382 *ppsz_options = options;
1385 options = moreOptions;
1388 options[nOptions++] = strdup(start);
1391 // must be end of string
1394 *i_options = nOptions;
1395 *ppsz_options = options;
1402 // XXX FIXME See comment at the other parseOptions variant.
1403 void LibvlcPlaylistNPObject::parseOptions(NPObject *obj, int *i_options,
1404 char*** ppsz_options)
1406 /* WARNING: Safari does not implement NPN_HasProperty/NPN_HasMethod */
1410 /* we are expecting to have a Javascript Array object */
1411 NPIdentifier propId = NPN_GetStringIdentifier("length");
1412 if( NPN_GetProperty(_instance, obj, propId, &value) )
1414 int count = numberValue(value);
1415 NPN_ReleaseVariantValue(&value);
1420 char **options = (char **)malloc(capacity*sizeof(char *));
1425 while( nOptions < count )
1427 propId = NPN_GetIntIdentifier(nOptions);
1428 if( ! NPN_GetProperty(_instance, obj, propId, &value) )
1429 /* return what we got so far */
1432 if( ! NPVARIANT_IS_STRING(value) )
1434 /* return what we got so far */
1435 NPN_ReleaseVariantValue(&value);
1439 if( nOptions == capacity )
1442 char **moreOptions = (char **)realloc(options, capacity*sizeof(char*));
1445 /* failed to allocate more memory */
1446 NPN_ReleaseVariantValue(&value);
1447 /* return what we got so far */
1448 *i_options = nOptions;
1449 *ppsz_options = options;
1452 options = moreOptions;
1455 options[nOptions++] = stringValue(value);
1457 *i_options = nOptions;
1458 *ppsz_options = options;
1465 ** implementation of libvlc video object
1468 const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] =
1479 enum LibvlcVideoNPObjectPropertyIds
1481 ID_video_fullscreen,
1484 ID_video_aspectratio,
1489 COUNTNAMES(LibvlcVideoNPObject,propertyCount,propertyNames);
1491 RuntimeNPObject::InvokeResult
1492 LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
1494 /* is plugin still running */
1495 if( isPluginRunning() )
1497 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1498 libvlc_exception_t ex;
1499 libvlc_exception_init(&ex);
1501 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1502 RETURN_ON_EXCEPTION(this,ex);
1506 case ID_video_fullscreen:
1508 int val = p_plugin->get_fullscreen(&ex);
1509 RETURN_ON_EXCEPTION(this,ex);
1510 BOOLEAN_TO_NPVARIANT(val, result);
1511 return INVOKERESULT_NO_ERROR;
1513 case ID_video_height:
1515 int val = libvlc_video_get_height(p_md, &ex);
1516 RETURN_ON_EXCEPTION(this,ex);
1517 INT32_TO_NPVARIANT(val, result);
1518 return INVOKERESULT_NO_ERROR;
1520 case ID_video_width:
1522 int val = libvlc_video_get_width(p_md, &ex);
1523 RETURN_ON_EXCEPTION(this,ex);
1524 INT32_TO_NPVARIANT(val, result);
1525 return INVOKERESULT_NO_ERROR;
1527 case ID_video_aspectratio:
1529 NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1530 RETURN_ON_EXCEPTION(this,ex);
1532 return INVOKERESULT_GENERIC_ERROR;
1534 STRINGZ_TO_NPVARIANT(psz_aspect, result);
1535 return INVOKERESULT_NO_ERROR;
1537 case ID_video_subtitle:
1539 int i_spu = libvlc_video_get_spu(p_md, &ex);
1540 RETURN_ON_EXCEPTION(this,ex);
1541 INT32_TO_NPVARIANT(i_spu, result);
1542 return INVOKERESULT_NO_ERROR;
1546 NPUTF8 *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1547 RETURN_ON_EXCEPTION(this,ex);
1549 return INVOKERESULT_GENERIC_ERROR;
1551 STRINGZ_TO_NPVARIANT(psz_geometry, result);
1552 return INVOKERESULT_NO_ERROR;
1554 case ID_video_teletext:
1556 int i_page = libvlc_video_get_teletext(p_md, &ex);
1557 RETURN_ON_EXCEPTION(this,ex);
1558 INT32_TO_NPVARIANT(i_page, result);
1559 return INVOKERESULT_NO_ERROR;
1563 return INVOKERESULT_GENERIC_ERROR;
1566 RuntimeNPObject::InvokeResult
1567 LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
1569 /* is plugin still running */
1570 if( isPluginRunning() )
1572 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1573 libvlc_exception_t ex;
1574 libvlc_exception_init(&ex);
1576 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1577 RETURN_ON_EXCEPTION(this,ex);
1581 case ID_video_fullscreen:
1583 if( ! NPVARIANT_IS_BOOLEAN(value) )
1585 return INVOKERESULT_INVALID_VALUE;
1588 int val = NPVARIANT_TO_BOOLEAN(value);
1589 p_plugin->set_fullscreen(val, &ex);
1590 RETURN_ON_EXCEPTION(this,ex);
1591 return INVOKERESULT_NO_ERROR;
1593 case ID_video_aspectratio:
1595 char *psz_aspect = NULL;
1597 if( ! NPVARIANT_IS_STRING(value) )
1599 return INVOKERESULT_INVALID_VALUE;
1602 psz_aspect = stringValue(NPVARIANT_TO_STRING(value));
1605 return INVOKERESULT_GENERIC_ERROR;
1608 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
1610 RETURN_ON_EXCEPTION(this,ex);
1612 return INVOKERESULT_NO_ERROR;
1614 case ID_video_subtitle:
1616 if( isNumberValue(value) )
1618 libvlc_video_set_spu(p_md, numberValue(value), &ex);
1619 RETURN_ON_EXCEPTION(this,ex);
1621 return INVOKERESULT_NO_ERROR;
1623 return INVOKERESULT_INVALID_VALUE;
1627 char *psz_geometry = NULL;
1629 if( ! NPVARIANT_IS_STRING(value) )
1631 return INVOKERESULT_INVALID_VALUE;
1634 psz_geometry = stringValue(NPVARIANT_TO_STRING(value));
1637 return INVOKERESULT_GENERIC_ERROR;
1640 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
1642 RETURN_ON_EXCEPTION(this,ex);
1644 return INVOKERESULT_NO_ERROR;
1646 case ID_video_teletext:
1648 if( isNumberValue(value) )
1650 libvlc_video_set_teletext(p_md, numberValue(value), &ex);
1651 RETURN_ON_EXCEPTION(this,ex);
1653 return INVOKERESULT_NO_ERROR;
1655 return INVOKERESULT_INVALID_VALUE;
1659 return INVOKERESULT_GENERIC_ERROR;
1662 const NPUTF8 * const LibvlcVideoNPObject::methodNames[] =
1667 COUNTNAMES(LibvlcVideoNPObject,methodCount,methodNames);
1669 enum LibvlcVideoNPObjectMethodIds
1671 ID_video_togglefullscreen,
1672 ID_video_toggleteletext
1675 RuntimeNPObject::InvokeResult
1676 LibvlcVideoNPObject::invoke(int index, const NPVariant *args,
1677 uint32_t argCount, NPVariant &result)
1679 /* is plugin still running */
1680 if( isPluginRunning() )
1682 VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
1683 libvlc_exception_t ex;
1684 libvlc_exception_init(&ex);
1686 libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
1687 RETURN_ON_EXCEPTION(this,ex);
1691 case ID_video_togglefullscreen:
1694 p_plugin->toggle_fullscreen(&ex);
1695 RETURN_ON_EXCEPTION(this,ex);
1696 VOID_TO_NPVARIANT(result);
1697 return INVOKERESULT_NO_ERROR;
1699 return INVOKERESULT_NO_SUCH_METHOD;
1700 case ID_video_toggleteletext:
1703 libvlc_toggle_teletext(p_md, &ex);
1704 RETURN_ON_EXCEPTION(this,ex);
1705 VOID_TO_NPVARIANT(result);
1706 return INVOKERESULT_NO_ERROR;
1708 return INVOKERESULT_NO_SUCH_METHOD;
1710 return INVOKERESULT_NO_SUCH_METHOD;
1713 return INVOKERESULT_GENERIC_ERROR;