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