]> git.sesse.net Git - vlc/blob - projects/mozilla/control/npolibvlc.cpp
Simplicifations, and arbitrarily take 78 cols as a better right margin than 100+.
[vlc] / projects / mozilla / control / npolibvlc.cpp
1 /*****************************************************************************
2  * npolibvlc.cpp: official Javascript APIs
3  *****************************************************************************
4  * Copyright (C) 2002-2006 the VideoLAN team
5  *
6  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 #include "config.h"
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28
29 /* Mozilla stuff */
30 #ifdef HAVE_MOZILLA_CONFIG_H
31 #   include <mozilla-config.h>
32 #endif
33
34 #include "vlcplugin.h"
35 #include "npolibvlc.h"
36
37 #define COUNTNAMES(a,b,c) const int a::b = sizeof(a::c)/sizeof(NPUTF8 *)
38
39 /*
40 ** implementation of libvlc root object
41 */
42
43 LibvlcRootNPObject::~LibvlcRootNPObject()
44 {
45     /*
46     ** When the plugin is destroyed, firefox takes it upon itself to
47     ** destroy all 'live' script objects and ignores refcounting.
48     ** Therefore we cannot safely assume that refcounting will control
49     ** lifespan of objects. Hence they are only lazily created on
50     ** request, so that firefox can take ownership, and are not released
51     ** when the plugin is destroyed.
52     */
53     if( isValid() )
54     {
55         if( audioObj    ) NPN_ReleaseObject(audioObj);
56         if( inputObj    ) NPN_ReleaseObject(inputObj);
57         if( logObj      ) NPN_ReleaseObject(logObj);
58         if( playlistObj ) NPN_ReleaseObject(playlistObj);
59         if( videoObj    ) NPN_ReleaseObject(videoObj);
60     }
61 }
62
63 const NPUTF8 * const LibvlcRootNPObject::propertyNames[] = 
64 {
65     "audio",
66     "input",
67     "log",
68     "playlist",
69     "video",
70     "VersionInfo",
71 };
72 COUNTNAMES(LibvlcRootNPObject,propertyCount,propertyNames);
73
74 enum LibvlcRootNPObjectPropertyIds
75 {
76     ID_root_audio = 0,
77     ID_root_input,
78     ID_root_log,
79     ID_root_playlist,
80     ID_root_video,
81     ID_root_VersionInfo,
82 };
83
84 RuntimeNPObject::InvokeResult
85 LibvlcRootNPObject::getProperty(int index, NPVariant &result)
86 {
87     /* is plugin still running */
88     if( _instance->pdata )
89     {
90         switch( index )
91         {
92             case ID_root_audio:
93                 // create child object in lazyman fashion to avoid
94                 // ownership problem with firefox
95                 if( ! audioObj )
96                     audioObj = NPN_CreateObject(_instance,
97                              RuntimeNPClass<LibvlcAudioNPObject>::getClass());
98                 OBJECT_TO_NPVARIANT(NPN_RetainObject(audioObj), result);
99                 return INVOKERESULT_NO_ERROR;
100             case ID_root_input:
101                 // create child object in lazyman fashion to avoid
102                 // ownership problem with firefox
103                 if( ! inputObj )
104                     inputObj = NPN_CreateObject(_instance,
105                              RuntimeNPClass<LibvlcInputNPObject>::getClass());
106                 OBJECT_TO_NPVARIANT(NPN_RetainObject(inputObj), result);
107                 return INVOKERESULT_NO_ERROR;
108             case ID_root_log:
109                 // create child object in lazyman fashion to avoid
110                 // ownership problem with firefox
111                 if( ! logObj )
112                     logObj = NPN_CreateObject(_instance,
113                                RuntimeNPClass<LibvlcLogNPObject>::getClass());
114                 OBJECT_TO_NPVARIANT(NPN_RetainObject(logObj), 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
119                 if( ! playlistObj )
120                     playlistObj = NPN_CreateObject(_instance,
121                           RuntimeNPClass<LibvlcPlaylistNPObject>::getClass());
122                 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistObj), result);
123                 return INVOKERESULT_NO_ERROR;
124             case ID_root_video:
125                 // create child object in lazyman fashion to avoid
126                 // ownership problem with firefox
127                 if( ! videoObj )
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             {
134                 int len = strlen(libvlc_get_version());
135                 NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);
136                 if( retval )
137                 {
138                     memcpy(retval, libvlc_get_version(), len);
139                     STRINGN_TO_NPVARIANT(retval, len, result);
140                 }
141                 else
142                 {
143                     NULL_TO_NPVARIANT(result);
144                 }
145                 return INVOKERESULT_NO_ERROR;
146             }
147             default:
148                 ;
149         }
150     }
151     return INVOKERESULT_GENERIC_ERROR;
152 }
153
154 const NPUTF8 * const LibvlcRootNPObject::methodNames[] =
155 {
156     "versionInfo",
157 };
158 COUNTNAMES(LibvlcRootNPObject,methodCount,methodNames);
159
160 enum LibvlcRootNPObjectMethodIds
161 {
162     ID_root_versionInfo,
163 };
164
165 RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index,
166                   const NPVariant *args, uint32_t argCount, NPVariant &result)
167 {
168     /* is plugin still running */
169     if( _instance->pdata )
170     {
171         libvlc_exception_t ex;
172         libvlc_exception_init(&ex);
173
174         switch( index )
175         {
176             case ID_root_versionInfo:
177                 if( argCount == 0 )
178                 {
179                     int len = strlen(libvlc_get_version());
180                     NPUTF8 *retval =(NPUTF8*)NPN_MemAlloc(len);
181                     if( retval )
182                     {
183                         memcpy(retval, libvlc_get_version(), len);
184                         STRINGN_TO_NPVARIANT(retval, len, result);
185                     }
186                     else
187                     {
188                         NULL_TO_NPVARIANT(result);
189                     }
190                     return INVOKERESULT_NO_ERROR;
191                 }
192                 return INVOKERESULT_NO_SUCH_METHOD;
193             default:
194                 ;
195         }
196     }
197     return INVOKERESULT_GENERIC_ERROR;
198 }
199
200 /*
201 ** implementation of libvlc audio object
202 */
203
204 const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] = 
205 {
206     "mute",
207     "volume",
208     "track",
209     "channel",
210 };
211 COUNTNAMES(LibvlcAudioNPObject,propertyCount,propertyNames);
212
213 enum LibvlcAudioNPObjectPropertyIds
214 {
215     ID_audio_mute,
216     ID_audio_volume,
217     ID_audio_track,
218     ID_audio_channel,
219 };
220
221 RuntimeNPObject::InvokeResult
222 LibvlcAudioNPObject::getProperty(int index, NPVariant &result)
223 {
224     /* is plugin still running */
225     if( _instance->pdata )
226     {
227         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
228         libvlc_exception_t ex;
229         libvlc_exception_init(&ex);
230
231         switch( index )
232         {
233             case ID_audio_mute:
234             {
235                 bool muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex);
236                 if( libvlc_exception_raised(&ex) )
237                 {
238                     NPN_SetException(this, libvlc_exception_get_message(&ex));
239                     libvlc_exception_clear(&ex);
240                     return INVOKERESULT_GENERIC_ERROR;
241                 }
242                 BOOLEAN_TO_NPVARIANT(muted, result);
243                 return INVOKERESULT_NO_ERROR;
244             }
245             case ID_audio_volume:
246             {
247                 int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex);
248                 if( libvlc_exception_raised(&ex) )
249                 {
250                     NPN_SetException(this, libvlc_exception_get_message(&ex));
251                     libvlc_exception_clear(&ex);
252                     return INVOKERESULT_GENERIC_ERROR;
253                 }
254                 INT32_TO_NPVARIANT(volume, result);
255                 return INVOKERESULT_NO_ERROR;
256             }
257             case ID_audio_track:
258             {
259                 libvlc_media_player_t *p_md =
260                     libvlc_playlist_get_media_player(p_plugin->getVLC(), &ex);
261                 if( libvlc_exception_raised(&ex) )
262                 {
263                     NPN_SetException(this, libvlc_exception_get_message(&ex));
264                     libvlc_exception_clear(&ex);
265                     return INVOKERESULT_GENERIC_ERROR;
266                 }
267                 int track = libvlc_audio_get_track(p_md, &ex);
268                 libvlc_media_player_release(p_md);
269                 if( libvlc_exception_raised(&ex) )
270                 {
271                     NPN_SetException(this, libvlc_exception_get_message(&ex));
272                     libvlc_exception_clear(&ex);
273                     return INVOKERESULT_GENERIC_ERROR;
274                 }
275                 INT32_TO_NPVARIANT(track, result);
276                 return INVOKERESULT_NO_ERROR;
277             }
278             case ID_audio_channel:
279             {
280                 int channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex);
281                 if( libvlc_exception_raised(&ex) )
282                 {
283                     NPN_SetException(this, libvlc_exception_get_message(&ex));
284                     libvlc_exception_clear(&ex);
285                     return INVOKERESULT_GENERIC_ERROR;
286                 }
287                 INT32_TO_NPVARIANT(channel, result);
288                 return INVOKERESULT_NO_ERROR;
289             }
290             default:
291                 ;
292         }
293     }
294     return INVOKERESULT_GENERIC_ERROR;
295 }
296
297 RuntimeNPObject::InvokeResult
298 LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)
299 {
300     /* is plugin still running */
301     if( _instance->pdata )
302     {
303         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
304         libvlc_exception_t ex;
305         libvlc_exception_init(&ex);
306
307         switch( index )
308         {
309             case ID_audio_mute:
310                 if( NPVARIANT_IS_BOOLEAN(value) )
311                 {
312                     libvlc_audio_set_mute(p_plugin->getVLC(),
313                                           NPVARIANT_TO_BOOLEAN(value), &ex);
314                     if( libvlc_exception_raised(&ex) )
315                     {
316                         NPN_SetException(this, libvlc_exception_get_message(&ex));
317                         libvlc_exception_clear(&ex);
318                         return INVOKERESULT_GENERIC_ERROR;
319                     }
320                     return INVOKERESULT_NO_ERROR;
321                 }
322                 return INVOKERESULT_INVALID_VALUE;
323             case ID_audio_volume:
324                 if( isNumberValue(value) )
325                 {
326                     libvlc_audio_set_volume(p_plugin->getVLC(),
327                                             numberValue(value), &ex);
328                     if( libvlc_exception_raised(&ex) )
329                     {
330                         NPN_SetException(this, libvlc_exception_get_message(&ex));
331                         libvlc_exception_clear(&ex);
332                         return INVOKERESULT_GENERIC_ERROR;
333                     }
334                     return INVOKERESULT_NO_ERROR;
335                 }
336                 return INVOKERESULT_INVALID_VALUE;
337             case ID_audio_track:
338                 if( isNumberValue(value) )
339                 {
340                     libvlc_media_player_t *p_md =
341                       libvlc_playlist_get_media_player(p_plugin->getVLC(), &ex);
342                     if( libvlc_exception_raised(&ex) )
343                     {
344                         NPN_SetException(this, libvlc_exception_get_message(&ex));
345                         libvlc_exception_clear(&ex);
346                         return INVOKERESULT_GENERIC_ERROR;
347                     }
348                     libvlc_audio_set_track(p_md,
349                                            numberValue(value), &ex);
350                     libvlc_media_player_release(p_md);
351                     if( libvlc_exception_raised(&ex) )
352                     {
353                         NPN_SetException(this, libvlc_exception_get_message(&ex));
354                         libvlc_exception_clear(&ex);
355                         return INVOKERESULT_GENERIC_ERROR;
356                     }
357                     return INVOKERESULT_NO_ERROR;
358                 }
359                 return INVOKERESULT_INVALID_VALUE;
360             case ID_audio_channel:
361                 if( isNumberValue(value) )
362                 {
363                     libvlc_audio_set_channel(p_plugin->getVLC(),
364                                              numberValue(value), &ex);
365                     if( libvlc_exception_raised(&ex) )
366                     {
367                         NPN_SetException(this, libvlc_exception_get_message(&ex));
368                         libvlc_exception_clear(&ex);
369                         return INVOKERESULT_GENERIC_ERROR;
370                     }
371                     return INVOKERESULT_NO_ERROR;
372                 }
373                 return INVOKERESULT_INVALID_VALUE;
374             default:
375                 ;
376         }
377     }
378     return INVOKERESULT_GENERIC_ERROR;
379 }
380
381 const NPUTF8 * const LibvlcAudioNPObject::methodNames[] =
382 {
383     "toggleMute",
384 };
385 COUNTNAMES(LibvlcAudioNPObject,methodCount,methodNames);
386
387 enum LibvlcAudioNPObjectMethodIds
388 {
389     ID_audio_togglemute,
390 };
391
392 RuntimeNPObject::InvokeResult
393 LibvlcAudioNPObject::invoke(int index, const NPVariant *args,
394                             uint32_t argCount, NPVariant &result)
395 {
396     /* is plugin still running */
397     if( _instance->pdata )
398     {
399         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
400         libvlc_exception_t ex;
401         libvlc_exception_init(&ex);
402
403         switch( index )
404         {
405             case ID_audio_togglemute:
406                 if( argCount == 0 )
407                 {
408                     libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex);
409                     if( libvlc_exception_raised(&ex) )
410                     {
411                         NPN_SetException(this, libvlc_exception_get_message(&ex));
412                         libvlc_exception_clear(&ex);
413                         return INVOKERESULT_GENERIC_ERROR;
414                     }
415                     else
416                     {
417                         VOID_TO_NPVARIANT(result);
418                         return INVOKERESULT_NO_ERROR;
419                     }
420                 }
421                 return INVOKERESULT_NO_SUCH_METHOD;
422             default:
423                 ;
424         }
425     }
426     return INVOKERESULT_GENERIC_ERROR;
427 }
428
429 /*
430 ** implementation of libvlc input object
431 */
432
433 const NPUTF8 * const LibvlcInputNPObject::propertyNames[] = 
434 {
435     "length",
436     "position",
437     "time",
438     "state",
439     "rate",
440     "fps",
441     "hasVout",
442 };
443 COUNTNAMES(LibvlcInputNPObject,propertyCount,propertyNames);
444
445 enum LibvlcInputNPObjectPropertyIds
446 {
447     ID_input_length,
448     ID_input_position,
449     ID_input_time,
450     ID_input_state,
451     ID_input_rate,
452     ID_input_fps,
453     ID_input_hasvout,
454 };
455
456 RuntimeNPObject::InvokeResult
457 LibvlcInputNPObject::getProperty(int index, NPVariant &result)
458 {
459     /* is plugin still running */
460     if( _instance->pdata )
461     {
462         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
463         libvlc_exception_t ex;
464         libvlc_exception_init(&ex);
465
466         libvlc_media_player_t *p_md =
467                     libvlc_playlist_get_media_player(p_plugin->getVLC(), &ex);
468         if( libvlc_exception_raised(&ex) )
469         {
470             if( index != ID_input_state )
471             {
472                 NPN_SetException(this, libvlc_exception_get_message(&ex));
473                 libvlc_exception_clear(&ex);
474                 return INVOKERESULT_GENERIC_ERROR;
475             }
476             else
477             {
478                 /* for input state, return CLOSED rather than an exception */
479                 INT32_TO_NPVARIANT(0, result);
480                 libvlc_exception_clear(&ex);
481                 return INVOKERESULT_NO_ERROR;
482             }
483         }
484
485         switch( index )
486         {
487             case ID_input_length:
488             {
489                 double val = (double)libvlc_media_player_get_length(p_md, &ex);
490                 libvlc_media_player_release(p_md);
491                 if( libvlc_exception_raised(&ex) )
492                 {
493                     NPN_SetException(this, libvlc_exception_get_message(&ex));
494                     libvlc_exception_clear(&ex);
495                     return INVOKERESULT_GENERIC_ERROR;
496                 }
497                 DOUBLE_TO_NPVARIANT(val, result);
498                 return INVOKERESULT_NO_ERROR;
499             }
500             case ID_input_position:
501             {
502                 double val = libvlc_media_player_get_position(p_md, &ex);
503                 libvlc_media_player_release(p_md);
504                 if( libvlc_exception_raised(&ex) )
505                 {
506                     NPN_SetException(this, libvlc_exception_get_message(&ex));
507                     libvlc_exception_clear(&ex);
508                     return INVOKERESULT_GENERIC_ERROR;
509                 }
510                 DOUBLE_TO_NPVARIANT(val, result);
511                 return INVOKERESULT_NO_ERROR;
512             }
513             case ID_input_time:
514             {
515                 double val = (double)libvlc_media_player_get_time(p_md, &ex);
516                 libvlc_media_player_release(p_md);
517                 if( libvlc_exception_raised(&ex) )
518                 {
519                     NPN_SetException(this, libvlc_exception_get_message(&ex));
520                     libvlc_exception_clear(&ex);
521                     return INVOKERESULT_GENERIC_ERROR;
522                 }
523                 DOUBLE_TO_NPVARIANT(val, result);
524                 return INVOKERESULT_NO_ERROR;
525             }
526             case ID_input_state:
527             {
528                 int val = libvlc_media_player_get_state(p_md, &ex);
529                 libvlc_media_player_release(p_md);
530                 if( libvlc_exception_raised(&ex) )
531                 {
532                     NPN_SetException(this, libvlc_exception_get_message(&ex));
533                     libvlc_exception_clear(&ex);
534                     return INVOKERESULT_GENERIC_ERROR;
535                 }
536                 INT32_TO_NPVARIANT(val, result);
537                 return INVOKERESULT_NO_ERROR;
538             }
539             case ID_input_rate:
540             {
541                 float val = libvlc_media_player_get_rate(p_md, &ex);
542                 libvlc_media_player_release(p_md);
543                 if( libvlc_exception_raised(&ex) )
544                 {
545                     NPN_SetException(this, libvlc_exception_get_message(&ex));
546                     libvlc_exception_clear(&ex);
547                     return INVOKERESULT_GENERIC_ERROR;
548                 }
549                 DOUBLE_TO_NPVARIANT(val, result);
550                 return INVOKERESULT_NO_ERROR;
551             }
552             case ID_input_fps:
553             {
554                 double val = libvlc_media_player_get_fps(p_md, &ex);
555                 libvlc_media_player_release(p_md);
556                 if( libvlc_exception_raised(&ex) )
557                 {
558                     NPN_SetException(this, libvlc_exception_get_message(&ex));
559                     libvlc_exception_clear(&ex);
560                     return INVOKERESULT_GENERIC_ERROR;
561                 }
562                 DOUBLE_TO_NPVARIANT(val, result);
563                 return INVOKERESULT_NO_ERROR;
564             }
565             case ID_input_hasvout:
566             {
567                 bool val = libvlc_media_player_has_vout(p_md, &ex);
568                 libvlc_media_player_release(p_md);
569                 if( libvlc_exception_raised(&ex) )
570                 {
571                     NPN_SetException(this, libvlc_exception_get_message(&ex));
572                     libvlc_exception_clear(&ex);
573                     return INVOKERESULT_GENERIC_ERROR;
574                 }
575                 BOOLEAN_TO_NPVARIANT(val, result);
576                 return INVOKERESULT_NO_ERROR;
577             }
578             default:
579                 ;
580         }
581         libvlc_media_player_release(p_md);
582     }
583     return INVOKERESULT_GENERIC_ERROR;
584 }
585
586 RuntimeNPObject::InvokeResult
587 LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
588 {
589     /* is plugin still running */
590     if( _instance->pdata )
591     {
592         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
593         libvlc_exception_t ex;
594         libvlc_exception_init(&ex);
595
596         libvlc_media_player_t *p_md =
597                     libvlc_playlist_get_media_player(p_plugin->getVLC(), &ex);
598         if( libvlc_exception_raised(&ex) )
599         {
600             NPN_SetException(this, libvlc_exception_get_message(&ex));
601             libvlc_exception_clear(&ex);
602             return INVOKERESULT_GENERIC_ERROR;
603         }
604
605         switch( index )
606         {
607             case ID_input_position:
608             {
609                 if( ! NPVARIANT_IS_DOUBLE(value) )
610                 {
611                     libvlc_media_player_release(p_md);
612                     return INVOKERESULT_INVALID_VALUE;
613                 }
614
615                 float val = (float)NPVARIANT_TO_DOUBLE(value);
616                 libvlc_media_player_set_position(p_md, val, &ex);
617                 libvlc_media_player_release(p_md);
618                 if( libvlc_exception_raised(&ex) )
619                 {
620                     NPN_SetException(this, libvlc_exception_get_message(&ex));
621                     libvlc_exception_clear(&ex);
622                     return INVOKERESULT_GENERIC_ERROR;
623                 }
624                 return INVOKERESULT_NO_ERROR;
625             }
626             case ID_input_time:
627             {
628                 int64_t val;
629                 if( NPVARIANT_IS_INT32(value) )
630                     val = (int64_t)NPVARIANT_TO_INT32(value);
631                 else if( NPVARIANT_IS_DOUBLE(value) )
632                     val = (int64_t)NPVARIANT_TO_DOUBLE(value);
633                 else
634                 {
635                     libvlc_media_player_release(p_md);
636                     return INVOKERESULT_INVALID_VALUE;
637                 }
638
639                 libvlc_media_player_set_time(p_md, val, &ex);
640                 libvlc_media_player_release(p_md);
641                 if( libvlc_exception_raised(&ex) )
642                 {
643                     NPN_SetException(this, libvlc_exception_get_message(&ex));
644                     libvlc_exception_clear(&ex);
645                     return INVOKERESULT_GENERIC_ERROR;
646                 }
647                 return INVOKERESULT_NO_ERROR;
648             }
649             case ID_input_rate:
650             {
651                 float val;
652                 if( NPVARIANT_IS_INT32(value) )
653                     val = (float)NPVARIANT_TO_INT32(value);
654                 else if( NPVARIANT_IS_DOUBLE(value) )
655                     val = (float)NPVARIANT_TO_DOUBLE(value);
656                 else
657                 {
658                     libvlc_media_player_release(p_md);
659                     return INVOKERESULT_INVALID_VALUE;
660                 }
661
662                 libvlc_media_player_set_rate(p_md, val, &ex);
663                 libvlc_media_player_release(p_md);
664                 if( libvlc_exception_raised(&ex) )
665                 {
666                     NPN_SetException(this, libvlc_exception_get_message(&ex));
667                     libvlc_exception_clear(&ex);
668                     return INVOKERESULT_GENERIC_ERROR;
669                 }
670                 return INVOKERESULT_NO_ERROR;
671             }
672             default:
673                 ;
674         }
675         libvlc_media_player_release(p_md);
676     }
677     return INVOKERESULT_GENERIC_ERROR;
678 }
679
680 const NPUTF8 * const LibvlcInputNPObject::methodNames[] =
681 {
682     /* no methods */
683 };
684
685 COUNTNAMES(LibvlcInputNPObject,methodCount,methodNames);
686
687 /*
688 ** implementation of libvlc message object
689 */
690
691 const NPUTF8 * const LibvlcMessageNPObject::propertyNames[] = 
692 {
693     "severity",
694     "type",
695     "name",
696     "header",
697     "message",
698 };
699 COUNTNAMES(LibvlcMessageNPObject,propertyCount,propertyNames);
700
701 enum LibvlcMessageNPObjectPropertyIds
702 {
703     ID_message_severity,
704     ID_message_type,
705     ID_message_name,
706     ID_message_header,
707     ID_message_message,
708 };
709
710 RuntimeNPObject::InvokeResult
711 LibvlcMessageNPObject::getProperty(int index, NPVariant &result)
712 {
713     /* is plugin still running */
714     if( _instance->pdata )
715     {
716         switch( index )
717         {
718             case ID_message_severity:
719             {
720                 INT32_TO_NPVARIANT(_msg.i_severity, result);
721                 return INVOKERESULT_NO_ERROR;
722             }
723             case ID_message_type:
724             {
725                 if( _msg.psz_type )
726                 {
727                     int len = strlen(_msg.psz_type);
728                     NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);
729                     if( retval )
730                     {
731                         memcpy(retval, _msg.psz_type, len);
732                         STRINGN_TO_NPVARIANT(retval, len, result);
733                     }
734                 }
735                 else
736                 {
737                     NULL_TO_NPVARIANT(result);
738                 }
739                 return INVOKERESULT_NO_ERROR;
740             }
741             case ID_message_name:
742             {
743                 if( _msg.psz_name )
744                 {
745                     int len = strlen(_msg.psz_name);
746                     NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);
747                     if( retval )
748                     {
749                         memcpy(retval, _msg.psz_name, len);
750                         STRINGN_TO_NPVARIANT(retval, len, result);
751                     }
752                 }
753                 else
754                 {
755                     NULL_TO_NPVARIANT(result);
756                 }
757                 return INVOKERESULT_NO_ERROR;
758             }
759             case ID_message_header:
760             {
761                 if( _msg.psz_header )
762                 {
763                     int len = strlen(_msg.psz_header);
764                     NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);
765                     if( retval )
766                     {
767                         memcpy(retval, _msg.psz_header, len);
768                         STRINGN_TO_NPVARIANT(retval, len, result);
769                     }
770                 }
771                 else
772                 {
773                     NULL_TO_NPVARIANT(result);
774                 }
775                 return INVOKERESULT_NO_ERROR;
776             }
777             case ID_message_message:
778             {
779                 if( _msg.psz_message )
780                 {
781                     int len = strlen(_msg.psz_message);
782                     NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);
783                     if( retval )
784                     {
785                         memcpy(retval, _msg.psz_message, len);
786                         STRINGN_TO_NPVARIANT(retval, len, result);
787                     }
788                 }
789                 else
790                 {
791                     NULL_TO_NPVARIANT(result);
792                 }
793                 return INVOKERESULT_NO_ERROR;
794             }
795             default:
796                 ;
797         }
798     }
799     return INVOKERESULT_GENERIC_ERROR;
800 }
801
802 const NPUTF8 * const LibvlcMessageNPObject::methodNames[] =
803 {
804     /* no methods */
805 };
806 COUNTNAMES(LibvlcMessageNPObject,methodCount,methodNames);
807
808 /*
809 ** implementation of libvlc message iterator object
810 */
811
812 LibvlcMessageIteratorNPObject::LibvlcMessageIteratorNPObject(NPP instance,
813                                                       const NPClass *aClass) :
814     RuntimeNPObject(instance, aClass),
815     _p_iter(NULL)
816 {
817     /* is plugin still running */
818     if( instance->pdata )
819     {
820         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata);
821         libvlc_log_t *p_log = p_plugin->getLog();
822         if( p_log )
823         {
824             _p_iter = libvlc_log_get_iterator(p_log, NULL);
825         }
826     }
827 };
828
829 LibvlcMessageIteratorNPObject::~LibvlcMessageIteratorNPObject()
830 {
831     if( _p_iter )
832         libvlc_log_iterator_free(_p_iter, NULL);
833 }
834
835 const NPUTF8 * const LibvlcMessageIteratorNPObject::propertyNames[] = 
836 {
837     "hasNext",
838 };
839 COUNTNAMES(LibvlcMessageIteratorNPObject,propertyCount,propertyNames);
840
841 enum LibvlcMessageIteratorNPObjectPropertyIds
842 {
843     ID_messageiterator_hasNext,
844 };
845
846 RuntimeNPObject::InvokeResult
847 LibvlcMessageIteratorNPObject::getProperty(int index, NPVariant &result)
848 {
849     /* is plugin still running */
850     if( _instance->pdata )
851     {
852         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
853         switch( index )
854         {
855             case ID_messageiterator_hasNext:
856             {
857                 if( _p_iter && p_plugin->getLog() )
858                 {
859                     libvlc_exception_t ex;
860                     libvlc_exception_init(&ex);
861
862                     BOOLEAN_TO_NPVARIANT(
863                          libvlc_log_iterator_has_next(_p_iter, &ex), result );
864                     if( libvlc_exception_raised(&ex) )
865                     {
866                         NPN_SetException(this, libvlc_exception_get_message(&ex));
867                         libvlc_exception_clear(&ex);
868                         return INVOKERESULT_GENERIC_ERROR;
869                     }
870                 }
871                 else
872                 {
873                     BOOLEAN_TO_NPVARIANT(0, result);
874                 }
875                 return INVOKERESULT_NO_ERROR;
876             }
877             default:
878                 ;
879         }
880     }
881     return INVOKERESULT_GENERIC_ERROR;
882 }
883
884 const NPUTF8 * const LibvlcMessageIteratorNPObject::methodNames[] =
885 {
886     "next",
887 };
888 COUNTNAMES(LibvlcMessageIteratorNPObject,methodCount,methodNames);
889
890 enum LibvlcMessageIteratorNPObjectMethodIds
891 {
892     ID_messageiterator_next,
893 };
894
895 RuntimeNPObject::InvokeResult
896 LibvlcMessageIteratorNPObject::invoke(int index, const NPVariant *args,
897                                       uint32_t argCount, NPVariant &result)
898 {
899     /* is plugin still running */
900     if( _instance->pdata )
901     {
902         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
903         libvlc_exception_t ex;
904         libvlc_exception_init(&ex);
905
906         switch( index )
907         {
908             case ID_messageiterator_next:
909                 if( argCount == 0 )
910                 {
911                     if( _p_iter && p_plugin->getLog() )
912                     {
913                         struct libvlc_log_message_t buffer;
914
915                         buffer.sizeof_msg = sizeof(buffer);
916
917                         libvlc_log_iterator_next(_p_iter, &buffer, &ex);
918                         if( libvlc_exception_raised(&ex) )
919                         {
920                             NPN_SetException(this, libvlc_exception_get_message(&ex));
921                             libvlc_exception_clear(&ex);
922                             return INVOKERESULT_GENERIC_ERROR;
923                         }
924                         else
925                         {
926                             LibvlcMessageNPObject* message =
927                                 static_cast<LibvlcMessageNPObject*>(
928                                   NPN_CreateObject(_instance, RuntimeNPClass<
929                                   LibvlcMessageNPObject>::getClass()));
930                             if( message )
931                             {
932                                 message->setMessage(buffer);
933                                 OBJECT_TO_NPVARIANT(message, result);
934                                 return INVOKERESULT_NO_ERROR;
935                             }
936                             return INVOKERESULT_OUT_OF_MEMORY;
937                         }
938                     }
939                     return INVOKERESULT_GENERIC_ERROR;
940                 }
941                 return INVOKERESULT_NO_SUCH_METHOD;
942             default:
943                 ;
944         }
945     }
946     return INVOKERESULT_GENERIC_ERROR;
947 }
948  
949 /*
950 ** implementation of libvlc message object
951 */
952
953 const NPUTF8 * const LibvlcMessagesNPObject::propertyNames[] = 
954 {
955     "count",
956 };
957 COUNTNAMES(LibvlcMessagesNPObject,propertyCount,propertyNames);
958
959 enum LibvlcMessagesNPObjectPropertyIds
960 {
961     ID_messages_count,
962 };
963
964 RuntimeNPObject::InvokeResult
965 LibvlcMessagesNPObject::getProperty(int index, NPVariant &result)
966 {
967     /* is plugin still running */
968     if( _instance->pdata )
969     {
970         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
971         switch( index )
972         {
973             case ID_messages_count:
974             {
975                 libvlc_log_t *p_log = p_plugin->getLog();
976                 if( p_log )
977                 {
978                     libvlc_exception_t ex;
979                     libvlc_exception_init(&ex);
980
981                     INT32_TO_NPVARIANT(libvlc_log_count(p_log, &ex), result);
982                     if( libvlc_exception_raised(&ex) )
983                     {
984                         NPN_SetException(this, libvlc_exception_get_message(&ex));
985                         libvlc_exception_clear(&ex);
986                         return INVOKERESULT_GENERIC_ERROR;
987                     }
988                 }
989                 else
990                 {
991                     INT32_TO_NPVARIANT(0, result);
992                 }
993                 return INVOKERESULT_NO_ERROR;
994             }
995             default:
996                 ;
997         }
998     }
999     return INVOKERESULT_GENERIC_ERROR;
1000 }
1001
1002 const NPUTF8 * const LibvlcMessagesNPObject::methodNames[] =
1003 {
1004     "clear",
1005     "iterator",
1006 };
1007 COUNTNAMES(LibvlcMessagesNPObject,methodCount,methodNames);
1008
1009 enum LibvlcMessagesNPObjectMethodIds
1010 {
1011     ID_messages_clear,
1012     ID_messages_iterator,
1013 };
1014
1015 RuntimeNPObject::InvokeResult
1016 LibvlcMessagesNPObject::invoke(int index, const NPVariant *args,
1017                                uint32_t argCount, NPVariant &result)
1018 {
1019     /* is plugin still running */
1020     if( _instance->pdata )
1021     {
1022         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
1023         libvlc_exception_t ex;
1024         libvlc_exception_init(&ex);
1025
1026         switch( index )
1027         {
1028             case ID_messages_clear:
1029                 if( argCount == 0 )
1030                 {
1031                     libvlc_log_t *p_log = p_plugin->getLog();
1032                     if( p_log )
1033                     {
1034                         libvlc_log_clear(p_log, &ex);
1035                         if( libvlc_exception_raised(&ex) )
1036                         {
1037                             NPN_SetException(this, libvlc_exception_get_message(&ex));
1038                             libvlc_exception_clear(&ex);
1039                             return INVOKERESULT_GENERIC_ERROR;
1040                         }
1041                     }
1042                     return INVOKERESULT_NO_ERROR;
1043                 }
1044                 return INVOKERESULT_NO_SUCH_METHOD;
1045
1046             case ID_messages_iterator:
1047                 if( argCount == 0 )
1048                 {
1049                     LibvlcMessageIteratorNPObject* iter =
1050                         static_cast<LibvlcMessageIteratorNPObject*>(
1051                         NPN_CreateObject(_instance, RuntimeNPClass<
1052                         LibvlcMessageIteratorNPObject>::getClass()));
1053                     if( iter )
1054                     {
1055                         OBJECT_TO_NPVARIANT(iter, result);
1056                         return INVOKERESULT_NO_ERROR;
1057                     }
1058                     return INVOKERESULT_OUT_OF_MEMORY;
1059                 }
1060                 return INVOKERESULT_NO_SUCH_METHOD;
1061
1062             default:
1063                 ;
1064         }
1065     }
1066     return INVOKERESULT_GENERIC_ERROR;
1067 }
1068
1069  
1070 /*
1071 ** implementation of libvlc message object
1072 */
1073
1074
1075 LibvlcLogNPObject::~LibvlcLogNPObject()
1076 {
1077     if( isValid() )
1078     {
1079         if( messagesObj ) NPN_ReleaseObject(messagesObj);
1080     }
1081 };
1082
1083 const NPUTF8 * const LibvlcLogNPObject::propertyNames[] = 
1084 {
1085     "messages",
1086     "verbosity",
1087 };
1088 COUNTNAMES(LibvlcLogNPObject,propertyCount,propertyNames);
1089
1090 enum LibvlcLogNPObjectPropertyIds
1091 {
1092     ID_log_messages,
1093     ID_log_verbosity,
1094 };
1095
1096 RuntimeNPObject::InvokeResult
1097 LibvlcLogNPObject::getProperty(int index, NPVariant &result)
1098 {
1099     /* is plugin still running */
1100     if( _instance->pdata )
1101     {
1102         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
1103         libvlc_exception_t ex;
1104         libvlc_exception_init(&ex);
1105
1106         switch( index )
1107         {
1108             case ID_log_messages:
1109             {
1110                 // create child object in lazyman fashion to avoid
1111                 // ownership problem with firefox
1112                 if( ! messagesObj )
1113                     messagesObj = NPN_CreateObject(_instance,
1114                           RuntimeNPClass<LibvlcMessagesNPObject>::getClass());
1115                 OBJECT_TO_NPVARIANT(NPN_RetainObject(messagesObj), result);
1116                 return INVOKERESULT_NO_ERROR;
1117             }
1118             case ID_log_verbosity:
1119             {
1120                 if( p_plugin->getLog() )
1121                 {
1122                     INT32_TO_NPVARIANT( libvlc_get_log_verbosity(
1123                                         p_plugin->getVLC(), &ex), result);
1124                     if( libvlc_exception_raised(&ex) )
1125                     {
1126                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1127                         libvlc_exception_clear(&ex);
1128                         return INVOKERESULT_GENERIC_ERROR;
1129                     }
1130                 }
1131                 else
1132                 {
1133                     /* log is not enabled, return -1 */
1134                     DOUBLE_TO_NPVARIANT(-1.0, result);
1135                 }
1136                 return INVOKERESULT_NO_ERROR;
1137             }
1138             default:
1139                 ;
1140         }
1141     }
1142     return INVOKERESULT_GENERIC_ERROR;
1143 }
1144
1145 RuntimeNPObject::InvokeResult
1146 LibvlcLogNPObject::setProperty(int index, const NPVariant &value)
1147 {
1148     /* is plugin still running */
1149     if( _instance->pdata )
1150     {
1151         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
1152         libvlc_exception_t ex;
1153         libvlc_exception_init(&ex);
1154
1155         switch( index )
1156         {
1157             case ID_log_verbosity:
1158                 if( isNumberValue(value) )
1159                 {
1160                     libvlc_instance_t* p_libvlc = p_plugin->getVLC();
1161                     libvlc_log_t *p_log = p_plugin->getLog();
1162                     int verbosity = numberValue(value);
1163                     if( verbosity >= 0 )
1164                     {
1165                         if( !p_log )
1166                         {
1167                             p_log = libvlc_log_open(p_libvlc, &ex);
1168                             if( libvlc_exception_raised(&ex) )
1169                             {
1170                                 NPN_SetException(this, libvlc_exception_get_message(&ex));
1171                                 libvlc_exception_clear(&ex);
1172                                 return INVOKERESULT_GENERIC_ERROR;
1173                             }
1174                             p_plugin->setLog(p_log);
1175                         }
1176                         libvlc_set_log_verbosity(p_libvlc, (unsigned)verbosity, &ex);
1177                         if( libvlc_exception_raised(&ex) )
1178                         {
1179                             NPN_SetException(this, libvlc_exception_get_message(&ex));
1180                             libvlc_exception_clear(&ex);
1181                             return INVOKERESULT_GENERIC_ERROR;
1182                         }
1183                     }
1184                     else if( p_log )
1185                     {
1186                         /* close log  when verbosity is set to -1 */
1187                         p_plugin->setLog(NULL);
1188                         libvlc_log_close(p_log, &ex);
1189                         if( libvlc_exception_raised(&ex) )
1190                         {
1191                             NPN_SetException(this, libvlc_exception_get_message(&ex));
1192                             libvlc_exception_clear(&ex);
1193                             return INVOKERESULT_GENERIC_ERROR;
1194                         }
1195                     }
1196                     return INVOKERESULT_NO_ERROR;
1197                 }
1198                 return INVOKERESULT_INVALID_VALUE;
1199             default:
1200                 ;
1201         }
1202     }
1203     return INVOKERESULT_GENERIC_ERROR;
1204 }
1205
1206 const NPUTF8 * const LibvlcLogNPObject::methodNames[] =
1207 {
1208     /* no methods */
1209 };
1210 COUNTNAMES(LibvlcLogNPObject,methodCount,methodNames);
1211
1212 /*
1213 ** implementation of libvlc playlist items object
1214 */
1215
1216 const NPUTF8 * const LibvlcPlaylistItemsNPObject::propertyNames[] = 
1217 {
1218     "count",
1219 };
1220 COUNTNAMES(LibvlcPlaylistItemsNPObject,propertyCount,propertyNames);
1221
1222 enum LibvlcPlaylistItemsNPObjectPropertyIds
1223 {
1224     ID_playlistitems_count,
1225 };
1226
1227 RuntimeNPObject::InvokeResult
1228 LibvlcPlaylistItemsNPObject::getProperty(int index, NPVariant &result)
1229 {
1230     /* is plugin still running */
1231     if( _instance->pdata )
1232     {
1233         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
1234         libvlc_exception_t ex;
1235         libvlc_exception_init(&ex);
1236
1237         switch( index )
1238         {
1239             case ID_playlistitems_count:
1240             {
1241                 libvlc_playlist_lock(p_plugin->getVLC());
1242                 int val = libvlc_playlist_items_count(p_plugin->getVLC(), &ex);
1243                 libvlc_playlist_unlock(p_plugin->getVLC());
1244                 if( libvlc_exception_raised(&ex) )
1245                 {
1246                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1247                     libvlc_exception_clear(&ex);
1248                     return INVOKERESULT_GENERIC_ERROR;
1249                 }
1250                 INT32_TO_NPVARIANT(val, result);
1251                 return INVOKERESULT_NO_ERROR;
1252             }
1253             default:
1254                 ;
1255         }
1256     }
1257     return INVOKERESULT_GENERIC_ERROR;
1258 }
1259
1260 const NPUTF8 * const LibvlcPlaylistItemsNPObject::methodNames[] =
1261 {
1262     "clear",
1263     "remove",
1264 };
1265 COUNTNAMES(LibvlcPlaylistItemsNPObject,methodCount,methodNames);
1266
1267 enum LibvlcPlaylistItemsNPObjectMethodIds
1268 {
1269     ID_playlistitems_clear,
1270     ID_playlistitems_remove,
1271 };
1272
1273 RuntimeNPObject::InvokeResult
1274 LibvlcPlaylistItemsNPObject::invoke(int index, const NPVariant *args,
1275                                     uint32_t argCount, NPVariant &result)
1276 {
1277     /* is plugin still running */
1278     if( _instance->pdata )
1279     {
1280         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
1281         libvlc_exception_t ex;
1282         libvlc_exception_init(&ex);
1283
1284         switch( index )
1285         {
1286             case ID_playlistitems_clear:
1287                 if( argCount == 0 )
1288                 {
1289                     libvlc_playlist_clear(p_plugin->getVLC(), &ex);
1290                     if( libvlc_exception_raised(&ex) )
1291                     {
1292                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1293                         libvlc_exception_clear(&ex);
1294                         return INVOKERESULT_GENERIC_ERROR;
1295                     }
1296                     else
1297                     {
1298                         VOID_TO_NPVARIANT(result);
1299                         return INVOKERESULT_NO_ERROR;
1300                     }
1301                 }
1302                 return INVOKERESULT_NO_SUCH_METHOD;
1303             case ID_playlistitems_remove:
1304                 if( (argCount == 1) && isNumberValue(args[0]) )
1305                 {
1306                     libvlc_playlist_delete_item(p_plugin->getVLC(),
1307                                                 numberValue(args[0]), &ex);
1308                     if( libvlc_exception_raised(&ex) )
1309                     {
1310                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1311                         libvlc_exception_clear(&ex);
1312                         return INVOKERESULT_GENERIC_ERROR;
1313                     }
1314                     else
1315                     {
1316                         VOID_TO_NPVARIANT(result);
1317                         return INVOKERESULT_NO_ERROR;
1318                     }
1319                 }
1320                 return INVOKERESULT_NO_SUCH_METHOD;
1321             default:
1322                 ;
1323         }
1324     }
1325     return INVOKERESULT_GENERIC_ERROR;
1326 }
1327
1328 /*
1329 ** implementation of libvlc playlist object
1330 */
1331
1332
1333 LibvlcPlaylistNPObject::~LibvlcPlaylistNPObject()
1334 {
1335     if( isValid() )
1336     {
1337         if( playlistItemsObj ) NPN_ReleaseObject(playlistItemsObj);
1338     }
1339 };
1340
1341 const NPUTF8 * const LibvlcPlaylistNPObject::propertyNames[] = 
1342 {
1343     "itemCount", /* deprecated */
1344     "isPlaying",
1345     "items",
1346 };
1347 COUNTNAMES(LibvlcPlaylistNPObject,propertyCount,propertyNames);
1348
1349 enum LibvlcPlaylistNPObjectPropertyIds
1350 {
1351     ID_playlist_itemcount,
1352     ID_playlist_isplaying,
1353     ID_playlist_items,
1354 };
1355
1356 RuntimeNPObject::InvokeResult
1357 LibvlcPlaylistNPObject::getProperty(int index, NPVariant &result)
1358 {
1359     /* is plugin still running */
1360     if( _instance->pdata )
1361     {
1362         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
1363         libvlc_exception_t ex;
1364         libvlc_exception_init(&ex);
1365
1366         switch( index )
1367         {
1368             case ID_playlist_itemcount: /* deprecated */
1369             {
1370                 libvlc_playlist_lock(p_plugin->getVLC());
1371                 int val = libvlc_playlist_items_count(p_plugin->getVLC(), &ex);
1372                 libvlc_playlist_unlock(p_plugin->getVLC());
1373                 if( libvlc_exception_raised(&ex) )
1374                 {
1375                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1376                     libvlc_exception_clear(&ex);
1377                     return INVOKERESULT_GENERIC_ERROR;
1378                 }
1379                 INT32_TO_NPVARIANT(val, result);
1380                 return INVOKERESULT_NO_ERROR;
1381             }
1382             case ID_playlist_isplaying:
1383             {
1384                 libvlc_playlist_lock(p_plugin->getVLC());
1385                 int val = libvlc_playlist_isplaying(p_plugin->getVLC(), &ex);
1386                 libvlc_playlist_unlock(p_plugin->getVLC());
1387                 if( libvlc_exception_raised(&ex) )
1388                 {
1389                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1390                     libvlc_exception_clear(&ex);
1391                     return INVOKERESULT_GENERIC_ERROR;
1392                 }
1393                 BOOLEAN_TO_NPVARIANT(val, result);
1394                 return INVOKERESULT_NO_ERROR;
1395             }
1396             case ID_playlist_items:
1397             {
1398                 // create child object in lazyman fashion to avoid
1399                 // ownership problem with firefox
1400                 if( ! playlistItemsObj )
1401                     playlistItemsObj =
1402                         NPN_CreateObject(_instance, RuntimeNPClass<
1403                         LibvlcPlaylistItemsNPObject>::getClass());
1404                 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistItemsObj), result);
1405                 return INVOKERESULT_NO_ERROR;
1406             }
1407             default:
1408                 ;
1409         }
1410     }
1411     return INVOKERESULT_GENERIC_ERROR;
1412 }
1413
1414 const NPUTF8 * const LibvlcPlaylistNPObject::methodNames[] =
1415 {
1416     "add",
1417     "play",
1418     "playItem",
1419     "togglePause",
1420     "stop",
1421     "next",
1422     "prev",
1423     "clear", /* deprecated */
1424     "removeItem", /* deprecated */
1425 };
1426 COUNTNAMES(LibvlcPlaylistNPObject,methodCount,methodNames);
1427
1428 enum LibvlcPlaylistNPObjectMethodIds
1429 {
1430     ID_playlist_add,
1431     ID_playlist_play,
1432     ID_playlist_playItem,
1433     ID_playlist_togglepause,
1434     ID_playlist_stop,
1435     ID_playlist_next,
1436     ID_playlist_prev,
1437     ID_playlist_clear,
1438     ID_playlist_removeitem
1439 };
1440
1441 RuntimeNPObject::InvokeResult
1442 LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
1443                                uint32_t argCount, NPVariant &result)
1444 {
1445     /* is plugin still running */
1446     if( _instance->pdata )
1447     {
1448         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
1449         libvlc_exception_t ex;
1450         libvlc_exception_init(&ex);
1451
1452         switch( index )
1453         {
1454             case ID_playlist_add:
1455             {
1456                 if( (argCount < 1) || (argCount > 3) )
1457                     return INVOKERESULT_NO_SUCH_METHOD;
1458
1459                 char *url = NULL;
1460
1461                 // grab URL
1462                 if( NPVARIANT_IS_STRING(args[0]) )
1463                 {
1464                     char *s = stringValue(NPVARIANT_TO_STRING(args[0]));
1465                     if( s )
1466                     {
1467                         url = p_plugin->getAbsoluteURL(s);
1468                         if( url )
1469                             free(s);
1470                         else
1471                             // problem with combining url, use argument
1472                             url = s;
1473                     }
1474                     else
1475                         return INVOKERESULT_OUT_OF_MEMORY;
1476                 }
1477                 else
1478                     return INVOKERESULT_NO_SUCH_METHOD;
1479
1480                 char *name = NULL;
1481
1482                 // grab name if available
1483                 if( argCount > 1 )
1484                 {
1485                     if( NPVARIANT_IS_NULL(args[1]) )
1486                     {
1487                         // do nothing
1488                     }
1489                     else if( NPVARIANT_IS_STRING(args[1]) )
1490                     {
1491                         name = stringValue(NPVARIANT_TO_STRING(args[1]));
1492                     }
1493                     else
1494                     {
1495                         free(url);
1496                         return INVOKERESULT_INVALID_VALUE;
1497                     }
1498                 }
1499
1500                 int i_options = 0;
1501                 char** ppsz_options = NULL;
1502
1503                 // grab options if available
1504                 if( argCount > 2 )
1505                 {
1506                     if( NPVARIANT_IS_NULL(args[2]) )
1507                     {
1508                         // do nothing
1509                     }
1510                     else if( NPVARIANT_IS_STRING(args[2]) )
1511                     {
1512                         parseOptions(NPVARIANT_TO_STRING(args[2]),
1513                                      &i_options, &ppsz_options);
1514
1515                     }
1516                     else if( NPVARIANT_IS_OBJECT(args[2]) )
1517                     {
1518                         parseOptions(NPVARIANT_TO_OBJECT(args[2]),
1519                                      &i_options, &ppsz_options);
1520                     }
1521                     else
1522                     {
1523                         free(url);
1524                         free(name);
1525                         return INVOKERESULT_INVALID_VALUE;
1526                     }
1527                 }
1528
1529                 int item = libvlc_playlist_add_extended_untrusted(
1530                                p_plugin->getVLC(), url, name, i_options,
1531                                const_cast<const char **>(ppsz_options), &ex);
1532                 free(url);
1533                 free(name);
1534                 for( int i=0; i< i_options; ++i )
1535                 {
1536                     free(ppsz_options[i]);
1537                 }
1538                 free(ppsz_options);
1539
1540                 if( libvlc_exception_raised(&ex) )
1541                 {
1542                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1543                     libvlc_exception_clear(&ex);
1544                     return INVOKERESULT_GENERIC_ERROR;
1545                 }
1546                 else
1547                 {
1548                     INT32_TO_NPVARIANT(item, result);
1549                     return INVOKERESULT_NO_ERROR;
1550                 }
1551             }
1552             case ID_playlist_play:
1553                 if( argCount == 0 )
1554                 {
1555                     libvlc_playlist_play(p_plugin->getVLC(), -1, 0, NULL, &ex);
1556                     if( libvlc_exception_raised(&ex) )
1557                     {
1558                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1559                         libvlc_exception_clear(&ex);
1560                         return INVOKERESULT_GENERIC_ERROR;
1561                     }
1562                     else
1563                     {
1564                         VOID_TO_NPVARIANT(result);
1565                         return INVOKERESULT_NO_ERROR;
1566                     }
1567                 }
1568                 return INVOKERESULT_NO_SUCH_METHOD;
1569             case ID_playlist_playItem:
1570                 if( (argCount == 1) && isNumberValue(args[0]) )
1571                 {
1572                     libvlc_playlist_play(p_plugin->getVLC(),
1573                                          numberValue(args[0]), 0, NULL, &ex);
1574                     if( libvlc_exception_raised(&ex) )
1575                     {
1576                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1577                         libvlc_exception_clear(&ex);
1578                         return INVOKERESULT_GENERIC_ERROR;
1579                     }
1580                     else
1581                     {
1582                         VOID_TO_NPVARIANT(result);
1583                         return INVOKERESULT_NO_ERROR;
1584                     }
1585                 }
1586                 return INVOKERESULT_NO_SUCH_METHOD;
1587             case ID_playlist_togglepause:
1588                 if( argCount == 0 )
1589                 {
1590                     libvlc_playlist_pause(p_plugin->getVLC(), &ex);
1591                     if( libvlc_exception_raised(&ex) )
1592                     {
1593                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1594                         libvlc_exception_clear(&ex);
1595                         return INVOKERESULT_GENERIC_ERROR;
1596                     }
1597                     else
1598                     {
1599                         VOID_TO_NPVARIANT(result);
1600                         return INVOKERESULT_NO_ERROR;
1601                     }
1602                 }
1603                 return INVOKERESULT_NO_SUCH_METHOD;
1604             case ID_playlist_stop:
1605                 if( argCount == 0 )
1606                 {
1607                     libvlc_playlist_stop(p_plugin->getVLC(), &ex);
1608                     if( libvlc_exception_raised(&ex) )
1609                     {
1610                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1611                         libvlc_exception_clear(&ex);
1612                         return INVOKERESULT_GENERIC_ERROR;
1613                     }
1614                     else
1615                     {
1616                         VOID_TO_NPVARIANT(result);
1617                         return INVOKERESULT_NO_ERROR;
1618                     }
1619                 }
1620                 return INVOKERESULT_NO_SUCH_METHOD;
1621             case ID_playlist_next:
1622                 if( argCount == 0 )
1623                 {
1624                     libvlc_playlist_next(p_plugin->getVLC(), &ex);
1625                     if( libvlc_exception_raised(&ex) )
1626                     {
1627                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1628                         libvlc_exception_clear(&ex);
1629                         return INVOKERESULT_GENERIC_ERROR;
1630                     }
1631                     else
1632                     {
1633                         VOID_TO_NPVARIANT(result);
1634                         return INVOKERESULT_NO_ERROR;
1635                     }
1636                 }
1637                 return INVOKERESULT_NO_SUCH_METHOD;
1638             case ID_playlist_prev:
1639                 if( argCount == 0 )
1640                 {
1641                     libvlc_playlist_prev(p_plugin->getVLC(), &ex);
1642                     if( libvlc_exception_raised(&ex) )
1643                     {
1644                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1645                         libvlc_exception_clear(&ex);
1646                         return INVOKERESULT_GENERIC_ERROR;
1647                     }
1648                     else
1649                     {
1650                         VOID_TO_NPVARIANT(result);
1651                         return INVOKERESULT_NO_ERROR;
1652                     }
1653                 }
1654                 return INVOKERESULT_NO_SUCH_METHOD;
1655             case ID_playlist_clear: /* deprecated */
1656                 if( argCount == 0 )
1657                 {
1658                     libvlc_playlist_clear(p_plugin->getVLC(), &ex);
1659                     if( libvlc_exception_raised(&ex) )
1660                     {
1661                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1662                         libvlc_exception_clear(&ex);
1663                         return INVOKERESULT_GENERIC_ERROR;
1664                     }
1665                     else
1666                     {
1667                         VOID_TO_NPVARIANT(result);
1668                         return INVOKERESULT_NO_ERROR;
1669                     }
1670                 }
1671                 return INVOKERESULT_NO_SUCH_METHOD;
1672             case ID_playlist_removeitem: /* deprecated */
1673                 if( (argCount == 1) && isNumberValue(args[0]) )
1674                 {
1675                     libvlc_playlist_delete_item(p_plugin->getVLC(),
1676                                                 numberValue(args[0]), &ex);
1677                     if( libvlc_exception_raised(&ex) )
1678                     {
1679                         NPN_SetException(this, libvlc_exception_get_message(&ex));
1680                         libvlc_exception_clear(&ex);
1681                         return INVOKERESULT_GENERIC_ERROR;
1682                     }
1683                     else
1684                     {
1685                         VOID_TO_NPVARIANT(result);
1686                         return INVOKERESULT_NO_ERROR;
1687                     }
1688                 }
1689                 return INVOKERESULT_NO_SUCH_METHOD;
1690             default:
1691                 ;
1692         }
1693     }
1694     return INVOKERESULT_GENERIC_ERROR;
1695 }
1696
1697 void LibvlcPlaylistNPObject::parseOptions(const NPString &nps,
1698                                          int *i_options, char*** ppsz_options)
1699 {
1700     if( nps.utf8length )
1701     {
1702         char *s = stringValue(nps);
1703         char *val = s;
1704         if( val )
1705         {
1706             long capacity = 16;
1707             char **options = (char **)malloc(capacity*sizeof(char *));
1708             if( options )
1709             {
1710                 int nOptions = 0;
1711
1712                 char *end = val + nps.utf8length;
1713                 while( val < end )
1714                 {
1715                     // skip leading blanks
1716                     while( (val < end)
1717                         && ((*val == ' ' ) || (*val == '\t')) )
1718                         ++val;
1719
1720                     char *start = val;
1721                     // skip till we get a blank character
1722                     while( (val < end)
1723                         && (*val != ' ' )
1724                         && (*val != '\t') )
1725                     {
1726                         char c = *(val++);
1727                         if( ('\'' == c) || ('"' == c) )
1728                         {
1729                             // skip till end of string
1730                             while( (val < end) && (*(val++) != c ) );
1731                         }
1732                     }
1733
1734                     if( val > start )
1735                     {
1736                         if( nOptions == capacity )
1737                         {
1738                             capacity += 16;
1739                             char **moreOptions = (char **)realloc(options, capacity*sizeof(char*)); 
1740                             if( ! moreOptions )
1741                             {
1742                                 /* failed to allocate more memory */
1743                                 free(s);
1744                                 /* return what we got so far */
1745                                 *i_options = nOptions;
1746                                 *ppsz_options = options;
1747                                 return;
1748                             }
1749                             options = moreOptions;
1750                         }
1751                         *(val++) = '\0';
1752                         options[nOptions++] = strdup(start);
1753                     }
1754                     else
1755                         // must be end of string
1756                         break;
1757                 }
1758                 *i_options = nOptions;
1759                 *ppsz_options = options;
1760             }
1761             free(s);
1762         }
1763     }
1764 }
1765
1766 void LibvlcPlaylistNPObject::parseOptions(NPObject *obj, int *i_options,
1767                                           char*** ppsz_options)
1768 {
1769     /* WARNING: Safari does not implement NPN_HasProperty/NPN_HasMethod */
1770
1771     NPVariant value;
1772
1773     /* we are expecting to have a Javascript Array object */
1774     NPIdentifier propId = NPN_GetStringIdentifier("length");
1775     if( NPN_GetProperty(_instance, obj, propId, &value) )
1776     {
1777         int count = numberValue(value);
1778         NPN_ReleaseVariantValue(&value);
1779
1780         if( count )
1781         {
1782             long capacity = 16;
1783             char **options = (char **)malloc(capacity*sizeof(char *));
1784             if( options )
1785             {
1786                 int nOptions = 0;
1787
1788                 while( nOptions < count )
1789                 {
1790                     propId = NPN_GetIntIdentifier(nOptions);
1791                     if( ! NPN_GetProperty(_instance, obj, propId, &value) )
1792                         /* return what we got so far */
1793                         break;
1794
1795                     if( ! NPVARIANT_IS_STRING(value) )
1796                     {
1797                         /* return what we got so far */
1798                         NPN_ReleaseVariantValue(&value);
1799                         break;
1800                     }
1801
1802                     if( nOptions == capacity )
1803                     {
1804                         capacity += 16;
1805                         char **moreOptions = (char **)realloc(options, capacity*sizeof(char*)); 
1806                         if( ! moreOptions )
1807                         {
1808                             /* failed to allocate more memory */
1809                             NPN_ReleaseVariantValue(&value);
1810                             /* return what we got so far */
1811                             *i_options = nOptions;
1812                             *ppsz_options = options;
1813                             break;
1814                         }
1815                         options = moreOptions;
1816                     }
1817
1818                     options[nOptions++] = stringValue(value);
1819                 }
1820                 *i_options = nOptions;
1821                 *ppsz_options = options;
1822             }
1823         }
1824     }
1825 }
1826
1827 /*
1828 ** implementation of libvlc video object
1829 */
1830
1831 const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] = 
1832 {
1833     "fullscreen",
1834     "height",
1835     "width",
1836     "aspectRatio",
1837     "subtitle",
1838     "crop",
1839     "teletext"
1840 };
1841
1842 enum LibvlcVideoNPObjectPropertyIds
1843 {
1844     ID_video_fullscreen,
1845     ID_video_height,
1846     ID_video_width,
1847     ID_video_aspectratio,
1848     ID_video_subtitle,
1849     ID_video_crop,
1850     ID_video_teletext
1851 };
1852 COUNTNAMES(LibvlcVideoNPObject,propertyCount,propertyNames);
1853
1854 RuntimeNPObject::InvokeResult
1855 LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
1856 {
1857     /* is plugin still running */
1858     if( _instance->pdata )
1859     {
1860         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
1861         libvlc_exception_t ex;
1862         libvlc_exception_init(&ex);
1863
1864         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_plugin->getVLC(), &ex);
1865         if( libvlc_exception_raised(&ex) )
1866         {
1867             NPN_SetException(this, libvlc_exception_get_message(&ex));
1868             libvlc_exception_clear(&ex);
1869             return INVOKERESULT_GENERIC_ERROR;
1870         }
1871
1872         switch( index )
1873         {
1874             case ID_video_fullscreen:
1875             {
1876                 int val = libvlc_get_fullscreen(p_md, &ex);
1877                 libvlc_media_player_release(p_md);
1878                 if( libvlc_exception_raised(&ex) )
1879                 {
1880                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1881                     libvlc_exception_clear(&ex);
1882                     return INVOKERESULT_GENERIC_ERROR;
1883                 }
1884                 BOOLEAN_TO_NPVARIANT(val, result);
1885                 return INVOKERESULT_NO_ERROR;
1886             }
1887             case ID_video_height:
1888             {
1889                 int val = libvlc_video_get_height(p_md, &ex);
1890                 libvlc_media_player_release(p_md);
1891                 if( libvlc_exception_raised(&ex) )
1892                 {
1893                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1894                     libvlc_exception_clear(&ex);
1895                     return INVOKERESULT_GENERIC_ERROR;
1896                 }
1897                 INT32_TO_NPVARIANT(val, result);
1898                 return INVOKERESULT_NO_ERROR;
1899             }
1900             case ID_video_width:
1901             {
1902                 int val = libvlc_video_get_width(p_md, &ex);
1903                 libvlc_media_player_release(p_md);
1904                 if( libvlc_exception_raised(&ex) )
1905                 {
1906                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1907                     libvlc_exception_clear(&ex);
1908                     return INVOKERESULT_GENERIC_ERROR;
1909                 }
1910                 INT32_TO_NPVARIANT(val, result);
1911                 return INVOKERESULT_NO_ERROR;
1912             }
1913             case ID_video_aspectratio:
1914             {
1915                 NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1916                 libvlc_media_player_release(p_md);
1917                 if( libvlc_exception_raised(&ex) )
1918                 {
1919                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1920                     libvlc_exception_clear(&ex);
1921                     return INVOKERESULT_GENERIC_ERROR;
1922                 }
1923                 if( !psz_aspect )
1924                     return INVOKERESULT_GENERIC_ERROR;
1925
1926                 STRINGZ_TO_NPVARIANT(psz_aspect, result);
1927                 return INVOKERESULT_NO_ERROR;
1928             }
1929             case ID_video_subtitle:
1930             {
1931                 int i_spu = libvlc_video_get_spu(p_md, &ex);
1932                 libvlc_media_player_release(p_md);
1933                 if( libvlc_exception_raised(&ex) )
1934                 {
1935                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1936                     libvlc_exception_clear(&ex);
1937                     return INVOKERESULT_GENERIC_ERROR;
1938                 }
1939                 INT32_TO_NPVARIANT(i_spu, result);
1940                 return INVOKERESULT_NO_ERROR;
1941             }
1942             case ID_video_crop:
1943             {
1944                 NPUTF8 *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1945                 libvlc_media_player_release(p_md);
1946                 if( libvlc_exception_raised(&ex) )
1947                 {
1948                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1949                     libvlc_exception_clear(&ex);
1950                     return INVOKERESULT_GENERIC_ERROR;
1951                 }
1952                 if( !psz_geometry )
1953                     return INVOKERESULT_GENERIC_ERROR;
1954
1955                 STRINGZ_TO_NPVARIANT(psz_geometry, result);
1956                 return INVOKERESULT_NO_ERROR;
1957             }
1958             case ID_video_teletext:
1959             {
1960                 int i_page = libvlc_video_get_teletext(p_md, &ex);
1961                 libvlc_media_player_release(p_md);
1962                 if( libvlc_exception_raised(&ex) )
1963                 {
1964                     NPN_SetException(this, libvlc_exception_get_message(&ex));
1965                     libvlc_exception_clear(&ex);
1966                     return INVOKERESULT_GENERIC_ERROR;
1967                 }
1968                 INT32_TO_NPVARIANT(i_page, result);
1969                 return INVOKERESULT_NO_ERROR;
1970             }
1971         }
1972         libvlc_media_player_release(p_md);
1973     }
1974     return INVOKERESULT_GENERIC_ERROR;
1975 }
1976
1977 RuntimeNPObject::InvokeResult
1978 LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
1979 {
1980     /* is plugin still running */
1981     if( _instance->pdata )
1982     {
1983         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
1984         libvlc_exception_t ex;
1985         libvlc_exception_init(&ex);
1986
1987         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_plugin->getVLC(), &ex);
1988         if( libvlc_exception_raised(&ex) )
1989         {
1990             NPN_SetException(this, libvlc_exception_get_message(&ex));
1991             libvlc_exception_clear(&ex);
1992             return INVOKERESULT_GENERIC_ERROR;
1993         }
1994
1995         switch( index )
1996         {
1997             case ID_video_fullscreen:
1998             {
1999                 if( ! NPVARIANT_IS_BOOLEAN(value) )
2000                 {
2001                     libvlc_media_player_release(p_md);
2002                     return INVOKERESULT_INVALID_VALUE;
2003                 }
2004
2005                 int val = NPVARIANT_TO_BOOLEAN(value);
2006                 libvlc_set_fullscreen(p_md, val, &ex);
2007                 libvlc_media_player_release(p_md);
2008
2009                 if( libvlc_exception_raised(&ex) )
2010                 {
2011                     NPN_SetException(this, libvlc_exception_get_message(&ex));
2012                     libvlc_exception_clear(&ex);
2013                     return INVOKERESULT_GENERIC_ERROR;
2014                 }
2015                 return INVOKERESULT_NO_ERROR;
2016             }
2017             case ID_video_aspectratio:
2018             {
2019                 char *psz_aspect = NULL;
2020
2021                 if( ! NPVARIANT_IS_STRING(value) )
2022                 {
2023                     libvlc_media_player_release(p_md);
2024                     return INVOKERESULT_INVALID_VALUE;
2025                 }
2026
2027                 psz_aspect = stringValue(NPVARIANT_TO_STRING(value));
2028                 if( !psz_aspect )
2029                 {
2030                     libvlc_media_player_release(p_md);
2031                     return INVOKERESULT_GENERIC_ERROR;
2032                 }
2033
2034                 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
2035                 free(psz_aspect);
2036                 libvlc_media_player_release(p_md);
2037
2038                 if( libvlc_exception_raised(&ex) )
2039                 {
2040                     NPN_SetException(this, libvlc_exception_get_message(&ex));
2041                     libvlc_exception_clear(&ex);
2042                     return INVOKERESULT_GENERIC_ERROR;
2043                 }
2044                 return INVOKERESULT_NO_ERROR;
2045             }
2046             case ID_video_subtitle:
2047             {
2048                 if( isNumberValue(value) )
2049                 {
2050                     libvlc_video_set_spu(p_md,
2051                                          numberValue(value), &ex);
2052                     libvlc_media_player_release(p_md);
2053                     if( libvlc_exception_raised(&ex) )
2054                     {
2055                         NPN_SetException(this, libvlc_exception_get_message(&ex));
2056                         libvlc_exception_clear(&ex);
2057                         return INVOKERESULT_GENERIC_ERROR;
2058                     }
2059                     return INVOKERESULT_NO_ERROR;
2060                 }
2061                 libvlc_media_player_release(p_md);
2062                 return INVOKERESULT_INVALID_VALUE;
2063             }
2064             case ID_video_crop:
2065             {
2066                 char *psz_geometry = NULL;
2067
2068                 if( ! NPVARIANT_IS_STRING(value) )
2069                 {
2070                     libvlc_media_player_release(p_md);
2071                     return INVOKERESULT_INVALID_VALUE;
2072                 }
2073
2074                 psz_geometry = stringValue(NPVARIANT_TO_STRING(value));
2075                 if( !psz_geometry )
2076                 {
2077                     libvlc_media_player_release(p_md);
2078                     return INVOKERESULT_GENERIC_ERROR;
2079                 }
2080
2081                 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
2082                 free(psz_geometry);
2083                 libvlc_media_player_release(p_md);
2084
2085                 if( libvlc_exception_raised(&ex) )
2086                 {
2087                     NPN_SetException(this, libvlc_exception_get_message(&ex));
2088                     libvlc_exception_clear(&ex);
2089                     return INVOKERESULT_GENERIC_ERROR;
2090                 }
2091                 return INVOKERESULT_NO_ERROR;
2092             }
2093             case ID_video_teletext:
2094             {
2095                 if( isNumberValue(value) )
2096                 {
2097                     libvlc_video_set_teletext(p_md,
2098                                          numberValue(value), &ex);
2099                     libvlc_media_player_release(p_md);
2100                     if( libvlc_exception_raised(&ex) )
2101                     {
2102                         NPN_SetException(this, libvlc_exception_get_message(&ex));
2103                         libvlc_exception_clear(&ex);
2104                         return INVOKERESULT_GENERIC_ERROR;
2105                     }
2106                     return INVOKERESULT_NO_ERROR;
2107                 }
2108                 libvlc_media_player_release(p_md);
2109                 return INVOKERESULT_INVALID_VALUE;
2110             }
2111         }
2112         libvlc_media_player_release(p_md);
2113     }
2114     return INVOKERESULT_GENERIC_ERROR;
2115 }
2116
2117 const NPUTF8 * const LibvlcVideoNPObject::methodNames[] =
2118 {
2119     "toggleFullscreen",
2120     "toggleTeletext"
2121 };
2122 COUNTNAMES(LibvlcVideoNPObject,methodCount,methodNames);
2123
2124 enum LibvlcVideoNPObjectMethodIds
2125 {
2126     ID_video_togglefullscreen,
2127     ID_video_toggleteletext
2128 };
2129
2130 RuntimeNPObject::InvokeResult
2131 LibvlcVideoNPObject::invoke(int index, const NPVariant *args,
2132                             uint32_t argCount, NPVariant &result)
2133 {
2134     /* is plugin still running */
2135     if( _instance->pdata )
2136     {
2137         VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(_instance->pdata);
2138         libvlc_exception_t ex;
2139         libvlc_exception_init(&ex);
2140
2141         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_plugin->getVLC(), &ex);
2142         if( libvlc_exception_raised(&ex) )
2143         {
2144             NPN_SetException(this, libvlc_exception_get_message(&ex));
2145             libvlc_exception_clear(&ex);
2146             return INVOKERESULT_GENERIC_ERROR;
2147         }
2148
2149         switch( index )
2150         {
2151             case ID_video_togglefullscreen:
2152                 if( argCount == 0 )
2153                 {
2154                     libvlc_toggle_fullscreen(p_md, &ex);
2155                     libvlc_media_player_release(p_md);
2156                     if( libvlc_exception_raised(&ex) )
2157                     {
2158                         NPN_SetException(this, libvlc_exception_get_message(&ex));
2159                         libvlc_exception_clear(&ex);
2160                         return INVOKERESULT_GENERIC_ERROR;
2161                     }
2162                     else
2163                     {
2164                         VOID_TO_NPVARIANT(result);
2165                         return INVOKERESULT_NO_ERROR;
2166                     }
2167                 }
2168                 else
2169                 {
2170                     /* cannot get md, probably not playing */
2171                     if( libvlc_exception_raised(&ex) )
2172                     {
2173                         NPN_SetException(this, libvlc_exception_get_message(&ex));
2174                         libvlc_exception_clear(&ex);
2175                     }
2176                     return INVOKERESULT_GENERIC_ERROR;
2177                 }
2178                 return INVOKERESULT_NO_SUCH_METHOD;
2179             case ID_video_toggleteletext:
2180                 if( argCount == 0 )
2181                 {
2182                     libvlc_toggle_teletext(p_md, &ex);
2183                     libvlc_media_player_release(p_md);
2184                     if( libvlc_exception_raised(&ex) )
2185                     {
2186                         NPN_SetException(this, libvlc_exception_get_message(&ex));
2187                         libvlc_exception_clear(&ex);
2188                         return INVOKERESULT_GENERIC_ERROR;
2189                     }
2190                     else
2191                     {
2192                         VOID_TO_NPVARIANT(result);
2193                         return INVOKERESULT_NO_ERROR;
2194                     }
2195                 }
2196                 else
2197                 {
2198                     /* cannot get md, probably not playing */
2199                     if( libvlc_exception_raised(&ex) )
2200                     {
2201                         NPN_SetException(this, libvlc_exception_get_message(&ex));
2202                         libvlc_exception_clear(&ex);
2203                     }
2204                     return INVOKERESULT_GENERIC_ERROR;
2205                 }
2206                 return INVOKERESULT_NO_SUCH_METHOD;
2207             default:
2208                 return INVOKERESULT_NO_SUCH_METHOD;
2209         }
2210     }
2211     return INVOKERESULT_GENERIC_ERROR;
2212 }