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