]> git.sesse.net Git - vlc/blob - mozilla/control/npolibvlc.cpp
60f9a0c26bb550624a4975cb96ede0248f951402
[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 "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     "playlist",\r
65     "video",\r
66     "VersionInfo",\r
67 };\r
68 \r
69 const int LibvlcRootNPObject::propertyCount = sizeof(LibvlcRootNPObject::propertyNames)/sizeof(NPUTF8 *);\r
70 \r
71 enum LibvlcRootNPObjectPropertyIds\r
72 {\r
73     ID_audio = 0,\r
74     ID_input,\r
75     ID_playlist,\r
76     ID_video,\r
77     ID_VersionInfo,\r
78 };\r
79 \r
80 RuntimeNPObject::InvokeResult LibvlcRootNPObject::getProperty(int index, NPVariant &result)\r
81 {\r
82     switch( index )\r
83     {\r
84         case ID_audio:\r
85             OBJECT_TO_NPVARIANT(NPN_RetainObject(audioObj), result);\r
86             return INVOKERESULT_NO_ERROR;\r
87         case ID_input:\r
88             OBJECT_TO_NPVARIANT(NPN_RetainObject(inputObj), result);\r
89             return INVOKERESULT_NO_ERROR;\r
90         case ID_playlist:\r
91             OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistObj), result);\r
92             return INVOKERESULT_NO_ERROR;\r
93         case ID_video:\r
94             OBJECT_TO_NPVARIANT(NPN_RetainObject(videoObj), result);\r
95             return INVOKERESULT_NO_ERROR;\r
96         case ID_VersionInfo:\r
97             NPUTF8 *versionStr = NULL;\r
98 \r
99             versionStr = strdup( VLC_Version() );\r
100             if (!versionStr)\r
101                 return INVOKERESULT_GENERIC_ERROR;\r
102 \r
103             STRINGZ_TO_NPVARIANT(versionStr, result);\r
104             return INVOKERESULT_NO_ERROR;\r
105     }\r
106     return INVOKERESULT_GENERIC_ERROR;\r
107 }\r
108 \r
109 const NPUTF8 * const LibvlcRootNPObject::methodNames[] =\r
110 {\r
111     "versionInfo",\r
112 };\r
113 \r
114 const int LibvlcRootNPObject::methodCount = sizeof(LibvlcRootNPObject::methodNames)/sizeof(NPUTF8 *);\r
115 \r
116 enum LibvlcRootNPObjectMethodIds\r
117 {\r
118     ID_version,\r
119 };\r
120 \r
121 RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
122 {\r
123     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
124     if( p_plugin )\r
125     {\r
126         libvlc_exception_t ex;\r
127         libvlc_exception_init(&ex);\r
128 \r
129         switch( index )\r
130         {\r
131             case ID_version:\r
132                 if( argCount == 0 )\r
133                 {\r
134                     NPUTF8 *versionStr = NULL;\r
135 \r
136                     versionStr = strdup( VLC_Version() );\r
137                     if (!versionStr)\r
138                         return INVOKERESULT_GENERIC_ERROR;\r
139 \r
140                     STRINGZ_TO_NPVARIANT(versionStr, result);\r
141                     return INVOKERESULT_NO_ERROR;\r
142                 }\r
143                 return INVOKERESULT_NO_SUCH_METHOD;\r
144             default:\r
145                 return INVOKERESULT_NO_SUCH_METHOD;\r
146         }\r
147     }\r
148     return INVOKERESULT_GENERIC_ERROR;\r
149 }\r
150 \r
151 /*\r
152 ** implementation of libvlc audio object\r
153 */\r
154 \r
155 const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] = \r
156 {\r
157     "mute",\r
158     "volume",\r
159 };\r
160 \r
161 const int LibvlcAudioNPObject::propertyCount = sizeof(LibvlcAudioNPObject::propertyNames)/sizeof(NPUTF8 *);\r
162 \r
163 enum LibvlcAudioNPObjectPropertyIds\r
164 {\r
165     ID_mute,\r
166     ID_volume,\r
167 };\r
168 \r
169 RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVariant &result)\r
170 {\r
171     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
172     if( p_plugin )\r
173     {\r
174         libvlc_exception_t ex;\r
175         libvlc_exception_init(&ex);\r
176 \r
177         switch( index )\r
178         {\r
179             case ID_mute:\r
180             {\r
181                 vlc_bool_t muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex);\r
182                 if( libvlc_exception_raised(&ex) )\r
183                 {\r
184                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
185                     libvlc_exception_clear(&ex);\r
186                     return INVOKERESULT_GENERIC_ERROR;\r
187                 }\r
188                 BOOLEAN_TO_NPVARIANT(muted, result);\r
189                 return INVOKERESULT_NO_ERROR;\r
190             }\r
191             case ID_volume:\r
192             {\r
193                 int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex);\r
194                 if( libvlc_exception_raised(&ex) )\r
195                 {\r
196                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
197                     libvlc_exception_clear(&ex);\r
198                     return INVOKERESULT_GENERIC_ERROR;\r
199                 }\r
200                 INT32_TO_NPVARIANT(volume, result);\r
201                 return INVOKERESULT_NO_ERROR;\r
202             }\r
203         }\r
204     }\r
205     return INVOKERESULT_GENERIC_ERROR;\r
206 }\r
207 \r
208 RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)\r
209 {\r
210     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
211     if( p_plugin )\r
212     {\r
213         libvlc_exception_t ex;\r
214         libvlc_exception_init(&ex);\r
215 \r
216         switch( index )\r
217         {\r
218             case ID_mute:\r
219                 if( NPVARIANT_IS_BOOLEAN(value) )\r
220                 {\r
221                     libvlc_audio_set_mute(p_plugin->getVLC(),\r
222                                           NPVARIANT_TO_BOOLEAN(value), &ex);\r
223                     if( libvlc_exception_raised(&ex) )\r
224                     {\r
225                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
226                         libvlc_exception_clear(&ex);\r
227                         return INVOKERESULT_GENERIC_ERROR;\r
228                     }\r
229                     return INVOKERESULT_NO_ERROR;\r
230                 }\r
231                 return INVOKERESULT_INVALID_VALUE;\r
232             case ID_volume:\r
233                 if( isNumberValue(value) )\r
234                 {\r
235                     libvlc_audio_set_volume(p_plugin->getVLC(),\r
236                                             numberValue(value), &ex);\r
237                     if( libvlc_exception_raised(&ex) )\r
238                     {\r
239                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
240                         libvlc_exception_clear(&ex);\r
241                         return INVOKERESULT_GENERIC_ERROR;\r
242                     }\r
243                     return INVOKERESULT_NO_ERROR;\r
244                 }\r
245                 return INVOKERESULT_INVALID_VALUE;\r
246         }\r
247     }\r
248     return INVOKERESULT_GENERIC_ERROR;\r
249 }\r
250 \r
251 const NPUTF8 * const LibvlcAudioNPObject::methodNames[] =\r
252 {\r
253     "toggleMute",\r
254 };\r
255 \r
256 const int LibvlcAudioNPObject::methodCount = sizeof(LibvlcAudioNPObject::methodNames)/sizeof(NPUTF8 *);\r
257 \r
258 enum LibvlcAudioNPObjectMethodIds\r
259 {\r
260     ID_togglemute,\r
261 };\r
262 \r
263 RuntimeNPObject::InvokeResult LibvlcAudioNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
264 {\r
265     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
266     if( p_plugin )\r
267     {\r
268         libvlc_exception_t ex;\r
269         libvlc_exception_init(&ex);\r
270 \r
271         switch( index )\r
272         {\r
273             case ID_togglemute:\r
274                 if( argCount == 0 )\r
275                 {\r
276                     libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex);\r
277                     if( libvlc_exception_raised(&ex) )\r
278                     {\r
279                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
280                         libvlc_exception_clear(&ex);\r
281                         return INVOKERESULT_GENERIC_ERROR;\r
282                     }\r
283                     else\r
284                     {\r
285                         VOID_TO_NPVARIANT(result);\r
286                         return INVOKERESULT_NO_ERROR;\r
287                     }\r
288                 }\r
289                 return INVOKERESULT_NO_SUCH_METHOD;\r
290             default:\r
291                 return INVOKERESULT_NO_SUCH_METHOD;\r
292         }\r
293     }\r
294     return INVOKERESULT_GENERIC_ERROR;\r
295 }\r
296 \r
297 /*\r
298 ** implementation of libvlc input object\r
299 */\r
300 \r
301 const NPUTF8 * const LibvlcInputNPObject::propertyNames[] = \r
302 {\r
303     "length",\r
304     "position",\r
305     "time",\r
306     "state",\r
307     "rate",\r
308     "fps",\r
309     "hasVout",\r
310 };\r
311 \r
312 const int LibvlcInputNPObject::propertyCount = sizeof(LibvlcInputNPObject::propertyNames)/sizeof(NPUTF8 *);\r
313 \r
314 enum LibvlcInputNPObjectPropertyIds\r
315 {\r
316     ID_length,\r
317     ID_position,\r
318     ID_time,\r
319     ID_state,\r
320     ID_rate,\r
321     ID_fps,\r
322     ID_hasvout,\r
323 };\r
324 \r
325 RuntimeNPObject::InvokeResult LibvlcInputNPObject::getProperty(int index, NPVariant &result)\r
326 {\r
327     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
328     if( p_plugin )\r
329     {\r
330         libvlc_exception_t ex;\r
331         libvlc_exception_init(&ex);\r
332 \r
333         libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
334         if( libvlc_exception_raised(&ex) )\r
335         {\r
336             if( index != ID_state )\r
337             {\r
338                 NPN_SetException(this, libvlc_exception_get_message(&ex));\r
339                 libvlc_exception_clear(&ex);\r
340                 return INVOKERESULT_GENERIC_ERROR;\r
341             }\r
342             else\r
343             {\r
344                 /* for input state, return CLOSED rather than an exception */\r
345                 INT32_TO_NPVARIANT(0, result);\r
346                 return INVOKERESULT_NO_ERROR;\r
347             }\r
348         }\r
349 \r
350         switch( index )\r
351         {\r
352             case ID_length:\r
353             {\r
354                 double val = (double)libvlc_input_get_length(p_input, &ex);\r
355                 libvlc_input_free(p_input);\r
356                 if( libvlc_exception_raised(&ex) )\r
357                 {\r
358                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
359                     libvlc_exception_clear(&ex);\r
360                     return INVOKERESULT_GENERIC_ERROR;\r
361                 }\r
362                 DOUBLE_TO_NPVARIANT(val, result);\r
363                 return INVOKERESULT_NO_ERROR;\r
364             }\r
365             case ID_position:\r
366             {\r
367                 double val = libvlc_input_get_position(p_input, &ex);\r
368                 libvlc_input_free(p_input);\r
369                 if( libvlc_exception_raised(&ex) )\r
370                 {\r
371                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
372                     libvlc_exception_clear(&ex);\r
373                     return INVOKERESULT_GENERIC_ERROR;\r
374                 }\r
375                 DOUBLE_TO_NPVARIANT(val, result);\r
376                 return INVOKERESULT_NO_ERROR;\r
377             }\r
378             case ID_time:\r
379             {\r
380                 double val = (double)libvlc_input_get_time(p_input, &ex);\r
381                 libvlc_input_free(p_input);\r
382                 if( libvlc_exception_raised(&ex) )\r
383                 {\r
384                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
385                     libvlc_exception_clear(&ex);\r
386                     return INVOKERESULT_GENERIC_ERROR;\r
387                 }\r
388                 DOUBLE_TO_NPVARIANT(val, result);\r
389                 return INVOKERESULT_NO_ERROR;\r
390             }\r
391             case ID_state:\r
392             {\r
393                 int val = libvlc_input_get_state(p_input, &ex);\r
394                 libvlc_input_free(p_input);\r
395                 if( libvlc_exception_raised(&ex) )\r
396                 {\r
397                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
398                     libvlc_exception_clear(&ex);\r
399                     return INVOKERESULT_GENERIC_ERROR;\r
400                 }\r
401                 INT32_TO_NPVARIANT(val, result);\r
402                 return INVOKERESULT_NO_ERROR;\r
403             }\r
404             case ID_rate:\r
405             {\r
406                 float val = libvlc_input_get_rate(p_input, &ex);\r
407                 libvlc_input_free(p_input);\r
408                 if( libvlc_exception_raised(&ex) )\r
409                 {\r
410                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
411                     libvlc_exception_clear(&ex);\r
412                     return INVOKERESULT_GENERIC_ERROR;\r
413                 }\r
414                 DOUBLE_TO_NPVARIANT(val, result);\r
415                 return INVOKERESULT_NO_ERROR;\r
416             }\r
417             case ID_fps:\r
418             {\r
419                 double val = libvlc_input_get_fps(p_input, &ex);\r
420                 libvlc_input_free(p_input);\r
421                 if( libvlc_exception_raised(&ex) )\r
422                 {\r
423                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
424                     libvlc_exception_clear(&ex);\r
425                     return INVOKERESULT_GENERIC_ERROR;\r
426                 }\r
427                 DOUBLE_TO_NPVARIANT(val, result);\r
428                 return INVOKERESULT_NO_ERROR;\r
429             }\r
430             case ID_hasvout:\r
431             {\r
432                 vlc_bool_t val = libvlc_input_has_vout(p_input, &ex);\r
433                 libvlc_input_free(p_input);\r
434                 if( libvlc_exception_raised(&ex) )\r
435                 {\r
436                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
437                     libvlc_exception_clear(&ex);\r
438                     return INVOKERESULT_GENERIC_ERROR;\r
439                 }\r
440                 BOOLEAN_TO_NPVARIANT(val, result);\r
441                 return INVOKERESULT_NO_ERROR;\r
442             }\r
443         }\r
444         libvlc_input_free(p_input);\r
445     }\r
446     return INVOKERESULT_GENERIC_ERROR;\r
447 }\r
448 \r
449 RuntimeNPObject::InvokeResult LibvlcInputNPObject::setProperty(int index, const NPVariant &value)\r
450 {\r
451     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
452     if( p_plugin )\r
453     {\r
454         libvlc_exception_t ex;\r
455         libvlc_exception_init(&ex);\r
456 \r
457         libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
458         if( libvlc_exception_raised(&ex) )\r
459         {\r
460             NPN_SetException(this, libvlc_exception_get_message(&ex));\r
461             libvlc_exception_clear(&ex);\r
462             return INVOKERESULT_GENERIC_ERROR;\r
463         }\r
464 \r
465         switch( index )\r
466         {\r
467             case ID_position:\r
468             {\r
469                 if( ! NPVARIANT_IS_DOUBLE(value) )\r
470                 {\r
471                     libvlc_input_free(p_input);\r
472                     return INVOKERESULT_INVALID_VALUE;\r
473                 }\r
474 \r
475                 float val = (float)NPVARIANT_TO_DOUBLE(value);\r
476                 libvlc_input_set_position(p_input, val, &ex);\r
477                 libvlc_input_free(p_input);\r
478                 if( libvlc_exception_raised(&ex) )\r
479                 {\r
480                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
481                     libvlc_exception_clear(&ex);\r
482                     return INVOKERESULT_GENERIC_ERROR;\r
483                 }\r
484                 return INVOKERESULT_NO_ERROR;\r
485             }\r
486             case ID_time:\r
487             {\r
488                 vlc_int64_t val;\r
489                 if( NPVARIANT_IS_INT32(value) )\r
490                     val = (vlc_int64_t)NPVARIANT_TO_INT32(value);\r
491                 else if( NPVARIANT_IS_DOUBLE(value) )\r
492                     val = (vlc_int64_t)NPVARIANT_TO_DOUBLE(value);\r
493                 else\r
494                 {\r
495                     libvlc_input_free(p_input);\r
496                     return INVOKERESULT_INVALID_VALUE;\r
497                 }\r
498 \r
499                 libvlc_input_set_time(p_input, val, &ex);\r
500                 libvlc_input_free(p_input);\r
501                 if( libvlc_exception_raised(&ex) )\r
502                 {\r
503                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
504                     libvlc_exception_clear(&ex);\r
505                     return INVOKERESULT_GENERIC_ERROR;\r
506                 }\r
507                 return INVOKERESULT_NO_ERROR;\r
508             }\r
509             case ID_rate:\r
510             {\r
511                 float val;\r
512                 if( NPVARIANT_IS_INT32(value) )\r
513                     val = (float)NPVARIANT_TO_INT32(value);\r
514                 else if( NPVARIANT_IS_DOUBLE(value) )\r
515                     val = (float)NPVARIANT_TO_DOUBLE(value);\r
516                 else\r
517                 {\r
518                     libvlc_input_free(p_input);\r
519                     return INVOKERESULT_INVALID_VALUE;\r
520                 }\r
521 \r
522                 libvlc_input_set_rate(p_input, val, &ex);\r
523                 libvlc_input_free(p_input);\r
524                 if( libvlc_exception_raised(&ex) )\r
525                 {\r
526                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
527                     libvlc_exception_clear(&ex);\r
528                     return INVOKERESULT_GENERIC_ERROR;\r
529                 }\r
530                 return INVOKERESULT_NO_ERROR;\r
531             }\r
532         }\r
533         libvlc_input_free(p_input);\r
534     }\r
535     return INVOKERESULT_GENERIC_ERROR;\r
536 }\r
537 \r
538 const NPUTF8 * const LibvlcInputNPObject::methodNames[] =\r
539 {\r
540     /* no methods */\r
541 };\r
542 \r
543 const int LibvlcInputNPObject::methodCount = sizeof(LibvlcInputNPObject::methodNames)/sizeof(NPUTF8 *);\r
544 \r
545 /*\r
546 ** implementation of libvlc message object\r
547 */\r
548 \r
549 const NPUTF8 * const LibvlcMessageNPObject::propertyNames[] = \r
550 {\r
551     "severity",\r
552     "type",\r
553     "name",\r
554     "header",\r
555     "message",\r
556 };\r
557 \r
558 const int LibvlcMessageNPObject::propertyCount = sizeof(LibvlcMessageNPObject::propertyNames)/sizeof(NPUTF8 *);\r
559 \r
560 enum LibvlcMessageNPObjectPropertyIds\r
561 {\r
562     ID_severity,\r
563     ID_type,\r
564     ID_name,\r
565     ID_header,\r
566     ID_message,\r
567 };\r
568 \r
569 RuntimeNPObject::InvokeResult LibvlcMessageNPObject::getProperty(int index, NPVariant &result)\r
570 {\r
571     switch( index )\r
572     {\r
573         case ID_severity:\r
574         {\r
575             INT32_TO_NPVARIANT(_msg.i_severity, result);\r
576             return INVOKERESULT_NO_ERROR;\r
577         }\r
578         case ID_type:\r
579         {\r
580             if( _msg.psz_type )\r
581             {\r
582                 int len = strlen(_msg.psz_type);\r
583                 NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);\r
584                 if( retval )\r
585                 {\r
586                     memcpy(retval, _msg.psz_type, len);\r
587                     STRINGN_TO_NPVARIANT(retval, len, result);\r
588                 }\r
589             }\r
590             else\r
591             {\r
592                 NULL_TO_NPVARIANT(result);\r
593             }\r
594             return INVOKERESULT_NO_ERROR;\r
595         }\r
596         case ID_name:\r
597         {\r
598             if( _msg.psz_name )\r
599             {\r
600                 int len = strlen(_msg.psz_name);\r
601                 NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);\r
602                 if( retval )\r
603                 {\r
604                     memcpy(retval, _msg.psz_name, len);\r
605                     STRINGN_TO_NPVARIANT(retval, len, result);\r
606                 }\r
607             }\r
608             else\r
609             {\r
610                 NULL_TO_NPVARIANT(result);\r
611             }\r
612             return INVOKERESULT_NO_ERROR;\r
613         }\r
614         case ID_header:\r
615         {\r
616             if( _msg.psz_header )\r
617             {\r
618                 int len = strlen(_msg.psz_header);\r
619                 NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);\r
620                 if( retval )\r
621                 {\r
622                     memcpy(retval, _msg.psz_header, len);\r
623                     STRINGN_TO_NPVARIANT(retval, len, result);\r
624                 }\r
625             }\r
626             else\r
627             {\r
628                 NULL_TO_NPVARIANT(result);\r
629             }\r
630             return INVOKERESULT_NO_ERROR;\r
631         }\r
632         case ID_message:\r
633         {\r
634             if( _msg.psz_message )\r
635             {\r
636                 int len = strlen(_msg.psz_message);\r
637                 NPUTF8* retval = (NPUTF8*)NPN_MemAlloc(len);\r
638                 if( retval )\r
639                 {\r
640                     memcpy(retval, _msg.psz_message, len);\r
641                     STRINGN_TO_NPVARIANT(retval, len, result);\r
642                 }\r
643             }\r
644             else\r
645             {\r
646                 NULL_TO_NPVARIANT(result);\r
647             }\r
648             return INVOKERESULT_NO_ERROR;\r
649         }\r
650     }\r
651     return INVOKERESULT_GENERIC_ERROR;\r
652 }\r
653 \r
654 const NPUTF8 * const LibvlcMessageNPObject::methodNames[] =\r
655 {\r
656     /* no methods */\r
657 };\r
658 \r
659 const int LibvlcMessageNPObject::methodCount = sizeof(LibvlcMessageNPObject::methodNames)/sizeof(NPUTF8 *);\r
660 \r
661 /*\r
662 ** implementation of libvlc message iterator object\r
663 */\r
664 \r
665 void LibvlcMessageIteratorNPObject::setLog(LibvlcLogNPObject* p_vlclog)\r
666 {\r
667     _p_vlclog = p_vlclog;\r
668     if( p_vlclog->_p_log )\r
669     {\r
670         _p_iter = libvlc_log_get_iterator(p_vlclog->_p_log, NULL);\r
671     }\r
672     else\r
673         _p_iter = NULL;\r
674 };\r
675 \r
676 const NPUTF8 * const LibvlcMessageIteratorNPObject::propertyNames[] = \r
677 {\r
678     "hasNext",\r
679 };\r
680 \r
681 const int LibvlcMessageIteratorNPObject::propertyCount = sizeof(LibvlcMessageIteratorNPObject::propertyNames)/sizeof(NPUTF8 *);\r
682 \r
683 enum LibvlcMessageIteratorNPObjectPropertyIds\r
684 {\r
685     ID_hasNext,\r
686 };\r
687 \r
688 RuntimeNPObject::InvokeResult LibvlcMessageIteratorNPObject::getProperty(int index, NPVariant &result)\r
689 {\r
690     switch( index )\r
691     {\r
692         case ID_hasNext:\r
693         {\r
694             if( _p_iter &&  _p_vlclog->_p_log )\r
695             {\r
696                 libvlc_exception_t ex;\r
697                 libvlc_exception_init(&ex);\r
698 \r
699                 BOOLEAN_TO_NPVARIANT(libvlc_log_iterator_has_next(_p_iter, &ex), result);\r
700                 if( libvlc_exception_raised(&ex) )\r
701                 {\r
702                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
703                     libvlc_exception_clear(&ex);\r
704                     return INVOKERESULT_GENERIC_ERROR;\r
705                 }\r
706             }\r
707             else\r
708             {\r
709                 BOOLEAN_TO_NPVARIANT(0, result);\r
710             }\r
711             return INVOKERESULT_NO_ERROR;\r
712         }\r
713     }\r
714     return INVOKERESULT_GENERIC_ERROR;\r
715 }\r
716 \r
717 const NPUTF8 * const LibvlcMessageIteratorNPObject::methodNames[] =\r
718 {\r
719     "next",\r
720 };\r
721 \r
722 const int LibvlcMessageIteratorNPObject::methodCount = sizeof(LibvlcMessageIteratorNPObject::methodNames)/sizeof(NPUTF8 *);\r
723 \r
724 enum LibvlcMessageIteratorNPObjectMethodIds\r
725 {\r
726     ID_messageiterator_next,\r
727 };\r
728 \r
729 RuntimeNPObject::InvokeResult LibvlcMessageIteratorNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
730 {\r
731     if( _p_iter &&  _p_vlclog->_p_log )\r
732     {\r
733         libvlc_exception_t ex;\r
734         libvlc_exception_init(&ex);\r
735 \r
736         switch( index )\r
737         {\r
738             case ID_messageiterator_next:\r
739                 if( argCount == 0 )\r
740                 {\r
741                     struct libvlc_log_message_t buffer;\r
742 \r
743                     buffer.sizeof_msg = sizeof(buffer);\r
744 \r
745                     libvlc_log_iterator_next(_p_iter, &buffer, &ex);\r
746                     if( libvlc_exception_raised(&ex) )\r
747                     {\r
748                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
749                         libvlc_exception_clear(&ex);\r
750                         return INVOKERESULT_GENERIC_ERROR;\r
751                     }\r
752                     else\r
753                     {\r
754                         LibvlcMessageNPObject* message =\r
755                             static_cast<LibvlcMessageNPObject*>(NPN_CreateObject(_instance, RuntimeNPClass<LibvlcMessageNPObject>::getClass()));\r
756                         if( message )\r
757                         {\r
758                             message->setMessage(buffer);\r
759                             OBJECT_TO_NPVARIANT(message, result);\r
760                             return INVOKERESULT_NO_ERROR;\r
761                         }\r
762                         return INVOKERESULT_OUT_OF_MEMORY;\r
763                     }\r
764                 }\r
765             default:\r
766                 return INVOKERESULT_NO_SUCH_METHOD;\r
767         }\r
768     }\r
769     return INVOKERESULT_GENERIC_ERROR;\r
770 }\r
771  \r
772 /*\r
773 ** implementation of libvlc message object\r
774 */\r
775 \r
776 const NPUTF8 * const LibvlcMessagesNPObject::propertyNames[] = \r
777 {\r
778     "count",\r
779 };\r
780 \r
781 const int LibvlcMessagesNPObject::propertyCount = sizeof(LibvlcMessagesNPObject::propertyNames)/sizeof(NPUTF8 *);\r
782 \r
783 enum LibvlcMessagesNPObjectPropertyIds\r
784 {\r
785     ID_count,\r
786 };\r
787 \r
788 RuntimeNPObject::InvokeResult LibvlcMessagesNPObject::getProperty(int index, NPVariant &result)\r
789 {\r
790     switch( index )\r
791     {\r
792         case ID_count:\r
793         {\r
794             libvlc_log_t *p_log = _p_vlclog->_p_log;\r
795             if( p_log )\r
796             {\r
797                 libvlc_exception_t ex;\r
798                 libvlc_exception_init(&ex);\r
799 \r
800                 INT32_TO_NPVARIANT(libvlc_log_count(p_log, &ex), result);\r
801                 if( libvlc_exception_raised(&ex) )\r
802                 {\r
803                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
804                     libvlc_exception_clear(&ex);\r
805                     return INVOKERESULT_GENERIC_ERROR;\r
806                 }\r
807             }\r
808             else\r
809             {\r
810                 INT32_TO_NPVARIANT(0, result);\r
811             }\r
812             return INVOKERESULT_NO_ERROR;\r
813         }\r
814     }\r
815     return INVOKERESULT_GENERIC_ERROR;\r
816 }\r
817 \r
818 const NPUTF8 * const LibvlcMessagesNPObject::methodNames[] =\r
819 {\r
820     "clear",\r
821     "iterator",\r
822 };\r
823 \r
824 const int LibvlcMessagesNPObject::methodCount = sizeof(LibvlcMessagesNPObject::methodNames)/sizeof(NPUTF8 *);\r
825 \r
826 enum LibvlcMessagesNPObjectMethodIds\r
827 {\r
828     ID_messages_clear,\r
829     ID_iterator,\r
830 };\r
831 \r
832 RuntimeNPObject::InvokeResult LibvlcMessagesNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
833 {\r
834     libvlc_exception_t ex;\r
835     libvlc_exception_init(&ex);\r
836 \r
837     switch( index )\r
838     {\r
839         case ID_messages_clear:\r
840             if( argCount == 0 )\r
841             {\r
842                 libvlc_log_t *p_log = _p_vlclog->_p_log;\r
843                 if( p_log )\r
844                 {\r
845                     libvlc_log_clear(p_log, &ex);\r
846                     if( libvlc_exception_raised(&ex) )\r
847                     {\r
848                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
849                         libvlc_exception_clear(&ex);\r
850                         return INVOKERESULT_GENERIC_ERROR;\r
851                     }\r
852                 }\r
853                 return INVOKERESULT_NO_ERROR;\r
854             }\r
855             return INVOKERESULT_NO_SUCH_METHOD;\r
856 \r
857         case ID_iterator:\r
858             if( argCount == 0 )\r
859             {\r
860                 LibvlcMessageIteratorNPObject* iter =\r
861                     static_cast<LibvlcMessageIteratorNPObject*>(NPN_CreateObject(_instance, RuntimeNPClass<LibvlcMessageIteratorNPObject>::getClass()));\r
862                 if( iter )\r
863                 {\r
864                     iter->setLog(_p_vlclog);\r
865                     OBJECT_TO_NPVARIANT(iter, result);\r
866                     return INVOKERESULT_NO_ERROR;\r
867                 }\r
868                 return INVOKERESULT_OUT_OF_MEMORY;\r
869             }\r
870             return INVOKERESULT_NO_SUCH_METHOD;\r
871 \r
872         default:\r
873             return INVOKERESULT_NO_SUCH_METHOD;\r
874     }\r
875     return INVOKERESULT_GENERIC_ERROR;\r
876 }\r
877  \r
878 /*\r
879 ** implementation of libvlc message object\r
880 */\r
881 \r
882 const NPUTF8 * const LibvlcLogNPObject::propertyNames[] = \r
883 {\r
884     "messages",\r
885     "verbosity",\r
886 };\r
887 \r
888 const int LibvlcLogNPObject::propertyCount = sizeof(LibvlcLogNPObject::propertyNames)/sizeof(NPUTF8 *);\r
889 \r
890 enum LibvlcLogNPObjectPropertyIds\r
891 {\r
892     ID_messages,\r
893     ID_verbosity,\r
894 };\r
895 \r
896 RuntimeNPObject::InvokeResult LibvlcLogNPObject::getProperty(int index, NPVariant &result)\r
897 {\r
898     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
899     if( p_plugin )\r
900     {\r
901         libvlc_exception_t ex;\r
902         libvlc_exception_init(&ex);\r
903 \r
904         switch( index )\r
905         {\r
906             case ID_messages:\r
907             {\r
908                 OBJECT_TO_NPVARIANT(NPN_RetainObject(_p_vlcmessages), result);\r
909                 return INVOKERESULT_NO_ERROR;\r
910             }\r
911             case ID_verbosity:\r
912             {\r
913                 if( _p_log )\r
914                 {\r
915                     INT32_TO_NPVARIANT(libvlc_get_log_verbosity(p_plugin->getVLC(),\r
916                                                                     &ex), result);\r
917                     if( libvlc_exception_raised(&ex) )\r
918                     {\r
919                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
920                         libvlc_exception_clear(&ex);\r
921                         return INVOKERESULT_GENERIC_ERROR;\r
922                     }\r
923                 }\r
924                 else\r
925                 {\r
926                     /* log is not enabled, return -1 */\r
927                     DOUBLE_TO_NPVARIANT(-1.0, result);\r
928                 }\r
929                 return INVOKERESULT_NO_ERROR;\r
930             }\r
931         }\r
932     }\r
933     return INVOKERESULT_GENERIC_ERROR;\r
934 }\r
935 \r
936 RuntimeNPObject::InvokeResult LibvlcLogNPObject::setProperty(int index, const NPVariant &value)\r
937 {\r
938     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
939     if( p_plugin )\r
940     {\r
941         libvlc_exception_t ex;\r
942         libvlc_exception_init(&ex);\r
943 \r
944         switch( index )\r
945         {\r
946             case ID_verbosity:\r
947                 if( isNumberValue(value) )\r
948                 {\r
949                     libvlc_instance_t* p_libvlc = p_plugin->getVLC();\r
950                     int verbosity = numberValue(value);\r
951                     if( verbosity >= 0 )\r
952                     {\r
953                         if( ! _p_log )\r
954                         {\r
955                             _p_log = libvlc_log_open(p_libvlc, &ex);\r
956                             if( libvlc_exception_raised(&ex) )\r
957                             {\r
958                                 NPN_SetException(this, libvlc_exception_get_message(&ex));\r
959                                 libvlc_exception_clear(&ex);\r
960                                 return INVOKERESULT_GENERIC_ERROR;\r
961                             }\r
962                         }\r
963                         libvlc_set_log_verbosity(p_libvlc, (unsigned)verbosity, &ex);\r
964                         if( libvlc_exception_raised(&ex) )\r
965                         {\r
966                             NPN_SetException(this, libvlc_exception_get_message(&ex));\r
967                             libvlc_exception_clear(&ex);\r
968                             return INVOKERESULT_GENERIC_ERROR;\r
969                         }\r
970                     }\r
971                     else if( _p_log )\r
972                     {\r
973                         /* close log  when verbosity is set to -1 */\r
974                         libvlc_log_close(_p_log, &ex);\r
975                         _p_log = NULL;\r
976                         if( libvlc_exception_raised(&ex) )\r
977                         {\r
978                             NPN_SetException(this, libvlc_exception_get_message(&ex));\r
979                             libvlc_exception_clear(&ex);\r
980                             return INVOKERESULT_GENERIC_ERROR;\r
981                         }\r
982                     }\r
983                     return INVOKERESULT_NO_ERROR;\r
984                 }\r
985                 return INVOKERESULT_INVALID_VALUE;\r
986         }\r
987     }\r
988     return INVOKERESULT_GENERIC_ERROR;\r
989 }\r
990 \r
991 const NPUTF8 * const LibvlcLogNPObject::methodNames[] =\r
992 {\r
993     /* no methods */\r
994 };\r
995 \r
996 const int LibvlcLogNPObject::methodCount = sizeof(LibvlcLogNPObject::methodNames)/sizeof(NPUTF8 *);\r
997 \r
998 /*\r
999 ** implementation of libvlc playlist object\r
1000 */\r
1001 \r
1002 \r
1003 const NPUTF8 * const LibvlcPlaylistNPObject::propertyNames[] = \r
1004 {\r
1005     "itemCount",\r
1006     "isPlaying",\r
1007 };\r
1008 \r
1009 const int LibvlcPlaylistNPObject::propertyCount = sizeof(LibvlcPlaylistNPObject::propertyNames)/sizeof(NPUTF8 *);\r
1010 \r
1011 enum LibvlcPlaylistNPObjectPropertyIds\r
1012 {\r
1013     ID_itemcount,\r
1014     ID_isplaying,\r
1015 };\r
1016 \r
1017 RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::getProperty(int index, NPVariant &result)\r
1018 {\r
1019     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
1020     if( p_plugin )\r
1021     {\r
1022         libvlc_exception_t ex;\r
1023         libvlc_exception_init(&ex);\r
1024 \r
1025         switch( index )\r
1026         {\r
1027             case ID_itemcount:\r
1028             {\r
1029                 int val = libvlc_playlist_items_count(p_plugin->getVLC(), &ex);\r
1030                 if( libvlc_exception_raised(&ex) )\r
1031                 {\r
1032                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1033                     libvlc_exception_clear(&ex);\r
1034                     return INVOKERESULT_GENERIC_ERROR;\r
1035                 }\r
1036                 INT32_TO_NPVARIANT(val, result);\r
1037                 return INVOKERESULT_NO_ERROR;\r
1038             }\r
1039             case ID_isplaying:\r
1040             {\r
1041                 int val = libvlc_playlist_isplaying(p_plugin->getVLC(), &ex);\r
1042                 if( libvlc_exception_raised(&ex) )\r
1043                 {\r
1044                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1045                     libvlc_exception_clear(&ex);\r
1046                     return INVOKERESULT_GENERIC_ERROR;\r
1047                 }\r
1048                 BOOLEAN_TO_NPVARIANT(val, result);\r
1049                 return INVOKERESULT_NO_ERROR;\r
1050             }\r
1051         }\r
1052     }\r
1053     return INVOKERESULT_GENERIC_ERROR;\r
1054 }\r
1055 \r
1056 const NPUTF8 * const LibvlcPlaylistNPObject::methodNames[] =\r
1057 {\r
1058     "add",\r
1059     "play",\r
1060     "playItem",\r
1061     "togglePause",\r
1062     "stop",\r
1063     "next",\r
1064     "prev",\r
1065     "clear",\r
1066     "removeItem"\r
1067 };\r
1068 \r
1069 const int LibvlcPlaylistNPObject::methodCount = sizeof(LibvlcPlaylistNPObject::methodNames)/sizeof(NPUTF8 *);\r
1070 \r
1071 enum LibvlcPlaylistNPObjectMethodIds\r
1072 {\r
1073     ID_add,\r
1074     ID_play,\r
1075     ID_playItem,\r
1076     ID_togglepause,\r
1077     ID_stop,\r
1078     ID_next,\r
1079     ID_prev,\r
1080     ID_clear,\r
1081     ID_removeitem\r
1082 };\r
1083 \r
1084 RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
1085 {\r
1086     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
1087     if( p_plugin )\r
1088     {\r
1089         libvlc_exception_t ex;\r
1090         libvlc_exception_init(&ex);\r
1091 \r
1092         switch( index )\r
1093         {\r
1094             case ID_add:\r
1095             {\r
1096                 if( (argCount < 1) || (argCount > 3) )\r
1097                     return INVOKERESULT_NO_SUCH_METHOD;\r
1098 \r
1099                 char *url = NULL;\r
1100 \r
1101                 // grab URL\r
1102                 if( NPVARIANT_IS_STRING(args[0]) )\r
1103                 {\r
1104                     char *s = stringValue(NPVARIANT_TO_STRING(args[0]));\r
1105                     if( s )\r
1106                     {\r
1107                         url = p_plugin->getAbsoluteURL(s);\r
1108                         delete s;\r
1109                         if( ! url )\r
1110                             // what happened ?\r
1111                             return INVOKERESULT_GENERIC_ERROR;\r
1112                     }\r
1113                     else\r
1114                         return INVOKERESULT_OUT_OF_MEMORY;\r
1115                 }\r
1116                 else\r
1117                     return INVOKERESULT_NO_SUCH_METHOD;\r
1118 \r
1119                 char *name = NULL;\r
1120 \r
1121                 // grab name if available\r
1122                 if( argCount > 1 )\r
1123                 {\r
1124                     if( NPVARIANT_IS_NULL(args[1]) )\r
1125                     {\r
1126                         // do nothing\r
1127                     }\r
1128                     else if( NPVARIANT_IS_STRING(args[1]) )\r
1129                     {\r
1130                         name = stringValue(NPVARIANT_TO_STRING(args[0]));\r
1131                     }\r
1132                     else\r
1133                         return INVOKERESULT_NO_SUCH_METHOD;\r
1134                 }\r
1135 \r
1136                 int i_options = 0;\r
1137                 char** ppsz_options = NULL;\r
1138 \r
1139                 // grab options if available\r
1140                 if( argCount > 2 )\r
1141                 {\r
1142                     if( NPVARIANT_IS_NULL(args[2]) )\r
1143                     {\r
1144                         // do nothing\r
1145                     }\r
1146                     else if( NPVARIANT_IS_STRING(args[2]) )\r
1147                     {\r
1148                         parseOptions(NPVARIANT_TO_STRING(args[2]), &i_options, &ppsz_options);\r
1149 \r
1150                     }\r
1151                     else if( NPVARIANT_IS_OBJECT(args[2]) )\r
1152                     {\r
1153                         parseOptions(NPVARIANT_TO_OBJECT(args[2]), &i_options, &ppsz_options);\r
1154                     }\r
1155                 }\r
1156 \r
1157                 int item = libvlc_playlist_add_extended(p_plugin->getVLC(),\r
1158                                                         url,\r
1159                                                         name,\r
1160                                                         i_options,\r
1161                                                         const_cast<const char **>(ppsz_options),\r
1162                                                         &ex);\r
1163                 delete url;\r
1164                 delete name;\r
1165                 for( int i=0; i< i_options; ++i )\r
1166                 {\r
1167                     if( ppsz_options[i] )\r
1168                         free(ppsz_options[i]);\r
1169                 }\r
1170                 if( ppsz_options )\r
1171                     free(ppsz_options);\r
1172                 if( libvlc_exception_raised(&ex) )\r
1173                 {\r
1174                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1175                     libvlc_exception_clear(&ex);\r
1176                     return INVOKERESULT_GENERIC_ERROR;\r
1177                 }\r
1178                 else\r
1179                 {\r
1180                     INT32_TO_NPVARIANT(item, result);\r
1181                     return INVOKERESULT_NO_ERROR;\r
1182                 }\r
1183             }\r
1184             case ID_play:\r
1185                 if( argCount == 0 )\r
1186                 {\r
1187                     libvlc_playlist_play(p_plugin->getVLC(), -1, 0, NULL, &ex);\r
1188                     if( libvlc_exception_raised(&ex) )\r
1189                     {\r
1190                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1191                         libvlc_exception_clear(&ex);\r
1192                         return INVOKERESULT_GENERIC_ERROR;\r
1193                     }\r
1194                     else\r
1195                     {\r
1196                         VOID_TO_NPVARIANT(result);\r
1197                         return INVOKERESULT_NO_ERROR;\r
1198                     }\r
1199                 }\r
1200                 return INVOKERESULT_NO_SUCH_METHOD;\r
1201             case ID_playItem:\r
1202                 if( (argCount == 1) && isNumberValue(args[0]) )\r
1203                 {\r
1204                     libvlc_playlist_play(p_plugin->getVLC(), numberValue(args[0]), 0, NULL, &ex);\r
1205                     if( libvlc_exception_raised(&ex) )\r
1206                     {\r
1207                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1208                         libvlc_exception_clear(&ex);\r
1209                         return INVOKERESULT_GENERIC_ERROR;\r
1210                     }\r
1211                     else\r
1212                     {\r
1213                         VOID_TO_NPVARIANT(result);\r
1214                         return INVOKERESULT_NO_ERROR;\r
1215                     }\r
1216                 }\r
1217                 return INVOKERESULT_NO_SUCH_METHOD;\r
1218             case ID_togglepause:\r
1219                 if( argCount == 0 )\r
1220                 {\r
1221                     libvlc_playlist_pause(p_plugin->getVLC(), &ex);\r
1222                     if( libvlc_exception_raised(&ex) )\r
1223                     {\r
1224                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1225                         libvlc_exception_clear(&ex);\r
1226                         return INVOKERESULT_GENERIC_ERROR;\r
1227                     }\r
1228                     else\r
1229                     {\r
1230                         VOID_TO_NPVARIANT(result);\r
1231                         return INVOKERESULT_NO_ERROR;\r
1232                     }\r
1233                 }\r
1234                 return INVOKERESULT_NO_SUCH_METHOD;\r
1235             case ID_stop:\r
1236                 if( argCount == 0 )\r
1237                 {\r
1238                     libvlc_playlist_stop(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_next:\r
1253                 if( argCount == 0 )\r
1254                 {\r
1255                     libvlc_playlist_next(p_plugin->getVLC(), &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             case ID_prev:\r
1270                 if( argCount == 0 )\r
1271                 {\r
1272                     libvlc_playlist_prev(p_plugin->getVLC(), &ex);\r
1273                     if( libvlc_exception_raised(&ex) )\r
1274                     {\r
1275                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1276                         libvlc_exception_clear(&ex);\r
1277                         return INVOKERESULT_GENERIC_ERROR;\r
1278                     }\r
1279                     else\r
1280                     {\r
1281                         VOID_TO_NPVARIANT(result);\r
1282                         return INVOKERESULT_NO_ERROR;\r
1283                     }\r
1284                 }\r
1285                 return INVOKERESULT_NO_SUCH_METHOD;\r
1286             case ID_clear:\r
1287                 if( argCount == 0 )\r
1288                 {\r
1289                     libvlc_playlist_clear(p_plugin->getVLC(), &ex);\r
1290                     if( libvlc_exception_raised(&ex) )\r
1291                     {\r
1292                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1293                         libvlc_exception_clear(&ex);\r
1294                         return INVOKERESULT_GENERIC_ERROR;\r
1295                     }\r
1296                     else\r
1297                     {\r
1298                         VOID_TO_NPVARIANT(result);\r
1299                         return INVOKERESULT_NO_ERROR;\r
1300                     }\r
1301                 }\r
1302                 return INVOKERESULT_NO_SUCH_METHOD;\r
1303             case ID_removeitem:\r
1304                 if( (argCount == 1) && isNumberValue(args[0]) )\r
1305                 {\r
1306                     libvlc_playlist_delete_item(p_plugin->getVLC(), numberValue(args[0]), &ex);\r
1307                     if( libvlc_exception_raised(&ex) )\r
1308                     {\r
1309                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1310                         libvlc_exception_clear(&ex);\r
1311                         return INVOKERESULT_GENERIC_ERROR;\r
1312                     }\r
1313                     else\r
1314                     {\r
1315                         VOID_TO_NPVARIANT(result);\r
1316                         return INVOKERESULT_NO_ERROR;\r
1317                     }\r
1318                 }\r
1319                 return INVOKERESULT_NO_SUCH_METHOD;\r
1320             default:\r
1321                 return INVOKERESULT_NO_SUCH_METHOD;\r
1322         }\r
1323     }\r
1324     return INVOKERESULT_GENERIC_ERROR;\r
1325 }\r
1326 \r
1327 void LibvlcPlaylistNPObject::parseOptions(const NPString &s, int *i_options, char*** ppsz_options)\r
1328 {\r
1329     if( s.utf8length )\r
1330     {\r
1331         char *val = stringValue(s);\r
1332         if( val )\r
1333         {\r
1334             long capacity = 16;\r
1335             char **options = (char **)malloc(capacity*sizeof(char *));\r
1336             if( options )\r
1337             {\r
1338                 int nOptions = 0;\r
1339 \r
1340                 char *end = val + s.utf8length;\r
1341                 while( val < end )\r
1342                 {\r
1343                     // skip leading blanks\r
1344                     while( (val < end)\r
1345                         && ((*val == ' ' ) || (*val == '\t')) )\r
1346                         ++val;\r
1347 \r
1348                     char *start = val;\r
1349                     // skip till we get a blank character\r
1350                     while( (val < end)\r
1351                         && (*val != ' ' )\r
1352                         && (*val != '\t') )\r
1353                     {\r
1354                         char c = *(val++);\r
1355                         if( ('\'' == c) || ('"' == c) )\r
1356                         {\r
1357                             // skip till end of string\r
1358                             while( (val < end) && (*(val++) != c ) );\r
1359                         }\r
1360                     }\r
1361 \r
1362                     if( val > start )\r
1363                     {\r
1364                         if( nOptions == capacity )\r
1365                         {\r
1366                             capacity += 16;\r
1367                             char **moreOptions = (char **)realloc(options, capacity*sizeof(char*)); \r
1368                             if( ! moreOptions )\r
1369                             {\r
1370                                 /* failed to allocate more memory */\r
1371                                 delete val;\r
1372                                 /* return what we got so far */\r
1373                                 *i_options = nOptions;\r
1374                                 *ppsz_options = options;\r
1375                                 break;\r
1376                             }\r
1377                             options = moreOptions;\r
1378                         }\r
1379                         *(val++) = '\0';\r
1380                         options[nOptions++] = strdup(start);\r
1381                     }\r
1382                     else\r
1383                         // must be end of string\r
1384                         break;\r
1385                 }\r
1386                 *i_options = nOptions;\r
1387                 *ppsz_options = options;\r
1388             }\r
1389             delete val;\r
1390         }\r
1391     }\r
1392 }\r
1393 \r
1394 void LibvlcPlaylistNPObject::parseOptions(NPObject *obj, int *i_options, char*** ppsz_options)\r
1395 {\r
1396     /* WARNING: Safari does not implement NPN_HasProperty/NPN_HasMethod */\r
1397 \r
1398     NPVariant value;\r
1399 \r
1400     /* we are expecting to have a Javascript Array object */\r
1401     NPIdentifier propId = NPN_GetStringIdentifier("length");\r
1402     if( NPN_GetProperty(_instance, obj, propId, &value) )\r
1403     {\r
1404         int count = numberValue(value);\r
1405         NPN_ReleaseVariantValue(&value);\r
1406 \r
1407         if( count )\r
1408         {\r
1409             long capacity = 16;\r
1410             char **options = (char **)malloc(capacity*sizeof(char *));\r
1411             if( options )\r
1412             {\r
1413                 int nOptions = 0;\r
1414 \r
1415                 while( nOptions < count )\r
1416                 {\r
1417                     propId = NPN_GetIntIdentifier(nOptions);\r
1418                     if( ! NPN_GetProperty(_instance, obj, propId, &value) )\r
1419                         /* return what we got so far */\r
1420                         break;\r
1421 \r
1422                     if( ! NPVARIANT_IS_STRING(value) )\r
1423                     {\r
1424                         /* return what we got so far */\r
1425                         NPN_ReleaseVariantValue(&value);\r
1426                         break;\r
1427                     }\r
1428 \r
1429                     if( nOptions == capacity )\r
1430                     {\r
1431                         capacity += 16;\r
1432                         char **moreOptions = (char **)realloc(options, capacity*sizeof(char*)); \r
1433                         if( ! moreOptions )\r
1434                         {\r
1435                             /* failed to allocate more memory */\r
1436                             NPN_ReleaseVariantValue(&value);\r
1437                             /* return what we got so far */\r
1438                             *i_options = nOptions;\r
1439                             *ppsz_options = options;\r
1440                             break;\r
1441                         }\r
1442                         options = moreOptions;\r
1443                     }\r
1444 \r
1445                     options[nOptions++] = stringValue(value);\r
1446                 }\r
1447                 *i_options = nOptions;\r
1448                 *ppsz_options = options;\r
1449             }\r
1450         }\r
1451     }\r
1452 }\r
1453 \r
1454 /*\r
1455 ** implementation of libvlc video object\r
1456 */\r
1457 \r
1458 const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] = \r
1459 {\r
1460     "fullscreen",\r
1461     "height",\r
1462     "width",\r
1463     "aspectRatio"\r
1464 };\r
1465 \r
1466 enum LibvlcVideoNPObjectPropertyIds\r
1467 {\r
1468     ID_fullscreen,\r
1469     ID_height,\r
1470     ID_width,\r
1471     ID_aspectratio\r
1472 };\r
1473 \r
1474 const int LibvlcVideoNPObject::propertyCount = sizeof(LibvlcVideoNPObject::propertyNames)/sizeof(NPUTF8 *);\r
1475 \r
1476 RuntimeNPObject::InvokeResult LibvlcVideoNPObject::getProperty(int index, NPVariant &result)\r
1477 {\r
1478     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
1479     if( p_plugin )\r
1480     {\r
1481         libvlc_exception_t ex;\r
1482         libvlc_exception_init(&ex);\r
1483 \r
1484         libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
1485         if( libvlc_exception_raised(&ex) )\r
1486         {\r
1487             NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1488             libvlc_exception_clear(&ex);\r
1489             return INVOKERESULT_GENERIC_ERROR;\r
1490         }\r
1491 \r
1492         switch( index )\r
1493         {\r
1494             case ID_fullscreen:\r
1495             {\r
1496                 int val = libvlc_get_fullscreen(p_input, &ex);\r
1497                 libvlc_input_free(p_input);\r
1498                 if( libvlc_exception_raised(&ex) )\r
1499                 {\r
1500                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1501                     libvlc_exception_clear(&ex);\r
1502                     return INVOKERESULT_GENERIC_ERROR;\r
1503                 }\r
1504                 BOOLEAN_TO_NPVARIANT(val, result);\r
1505                 return INVOKERESULT_NO_ERROR;\r
1506             }\r
1507             case ID_height:\r
1508             {\r
1509                 int val = libvlc_video_get_height(p_input, &ex);\r
1510                 libvlc_input_free(p_input);\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                 INT32_TO_NPVARIANT(val, result);\r
1518                 return INVOKERESULT_NO_ERROR;\r
1519             }\r
1520             case ID_width:\r
1521             {\r
1522                 int val = libvlc_video_get_width(p_input, &ex);\r
1523                 libvlc_input_free(p_input);\r
1524                 if( libvlc_exception_raised(&ex) )\r
1525                 {\r
1526                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1527                     libvlc_exception_clear(&ex);\r
1528                     return INVOKERESULT_GENERIC_ERROR;\r
1529                 }\r
1530                 INT32_TO_NPVARIANT(val, result);\r
1531                 return INVOKERESULT_NO_ERROR;\r
1532             }\r
1533             case ID_aspectratio:\r
1534             {\r
1535                 NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_input, &ex);\r
1536                 libvlc_input_free(p_input);\r
1537                 if( libvlc_exception_raised(&ex) )\r
1538                 {\r
1539                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1540                     libvlc_exception_clear(&ex);\r
1541                     return INVOKERESULT_GENERIC_ERROR;\r
1542                 }\r
1543                 if( !psz_aspect )\r
1544                     return INVOKERESULT_GENERIC_ERROR;\r
1545 \r
1546                 STRINGZ_TO_NPVARIANT(psz_aspect, result);\r
1547                 return INVOKERESULT_NO_ERROR;\r
1548             }\r
1549         }\r
1550         libvlc_input_free(p_input);\r
1551     }\r
1552     return INVOKERESULT_GENERIC_ERROR;\r
1553 }\r
1554 \r
1555 RuntimeNPObject::InvokeResult LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)\r
1556 {\r
1557     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
1558     if( p_plugin )\r
1559     {\r
1560         libvlc_exception_t ex;\r
1561         libvlc_exception_init(&ex);\r
1562 \r
1563         libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
1564         if( libvlc_exception_raised(&ex) )\r
1565         {\r
1566             NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1567             libvlc_exception_clear(&ex);\r
1568             return INVOKERESULT_GENERIC_ERROR;\r
1569         }\r
1570 \r
1571         switch( index )\r
1572         {\r
1573             case ID_fullscreen:\r
1574             {\r
1575                 if( ! NPVARIANT_IS_BOOLEAN(value) )\r
1576                 {\r
1577                     libvlc_input_free(p_input);\r
1578                     return INVOKERESULT_INVALID_VALUE;\r
1579                 }\r
1580 \r
1581                 int val = NPVARIANT_TO_BOOLEAN(value);\r
1582                 libvlc_set_fullscreen(p_input, val, &ex);\r
1583                 libvlc_input_free(p_input);\r
1584                 if( libvlc_exception_raised(&ex) )\r
1585                 {\r
1586                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1587                     libvlc_exception_clear(&ex);\r
1588                     return INVOKERESULT_GENERIC_ERROR;\r
1589                 }\r
1590                 return INVOKERESULT_NO_ERROR;\r
1591             }\r
1592             case ID_aspectratio:\r
1593             {\r
1594                 char *psz_aspect = NULL;\r
1595 \r
1596                 if( ! NPVARIANT_IS_STRING(value) )\r
1597                 {\r
1598                     libvlc_input_free(p_input);\r
1599                     return INVOKERESULT_INVALID_VALUE;\r
1600                 }\r
1601 \r
1602                 psz_aspect = stringValue(NPVARIANT_TO_STRING(value));\r
1603                 if( !psz_aspect )\r
1604                     return INVOKERESULT_GENERIC_ERROR;\r
1605 \r
1606                 libvlc_video_set_aspect_ratio(p_input, psz_aspect, &ex);\r
1607                 if( psz_aspect )\r
1608                     free(psz_aspect );\r
1609 \r
1610                 libvlc_input_free(p_input);\r
1611                 if( libvlc_exception_raised(&ex) )\r
1612                 {\r
1613                     NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1614                     libvlc_exception_clear(&ex);\r
1615                     return INVOKERESULT_GENERIC_ERROR;\r
1616                 }\r
1617                 return INVOKERESULT_NO_ERROR;\r
1618             }\r
1619         }\r
1620         libvlc_input_free(p_input);\r
1621     }\r
1622     return INVOKERESULT_GENERIC_ERROR;\r
1623 }\r
1624 \r
1625 const NPUTF8 * const LibvlcVideoNPObject::methodNames[] =\r
1626 {\r
1627     "toggleFullscreen",\r
1628 };\r
1629 \r
1630 enum LibvlcVideoNPObjectMethodIds\r
1631 {\r
1632     ID_togglefullscreen,\r
1633 };\r
1634 \r
1635 const int LibvlcVideoNPObject::methodCount = sizeof(LibvlcVideoNPObject::methodNames)/sizeof(NPUTF8 *);\r
1636 \r
1637 RuntimeNPObject::InvokeResult LibvlcVideoNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result)\r
1638 {\r
1639     VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata);\r
1640     if( p_plugin )\r
1641     {\r
1642         libvlc_exception_t ex;\r
1643         libvlc_exception_init(&ex);\r
1644 \r
1645         libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex);\r
1646         if( libvlc_exception_raised(&ex) )\r
1647         {\r
1648             NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1649             libvlc_exception_clear(&ex);\r
1650             return INVOKERESULT_GENERIC_ERROR;\r
1651         }\r
1652 \r
1653         switch( index )\r
1654         {\r
1655             case ID_togglefullscreen:\r
1656                 if( argCount == 0 )\r
1657                 {\r
1658                     libvlc_toggle_fullscreen(p_input, &ex);\r
1659                     libvlc_input_free(p_input);\r
1660                     if( libvlc_exception_raised(&ex) )\r
1661                     {\r
1662                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1663                         libvlc_exception_clear(&ex);\r
1664                         return INVOKERESULT_GENERIC_ERROR;\r
1665                     }\r
1666                     else\r
1667                     {\r
1668                         VOID_TO_NPVARIANT(result);\r
1669                         return INVOKERESULT_NO_ERROR;\r
1670                     }\r
1671                 }\r
1672                 else\r
1673                 {\r
1674                     /* cannot get input, probably not playing */\r
1675                     if( libvlc_exception_raised(&ex) )\r
1676                     {\r
1677                         NPN_SetException(this, libvlc_exception_get_message(&ex));\r
1678                         libvlc_exception_clear(&ex);\r
1679                     }\r
1680                     return INVOKERESULT_GENERIC_ERROR;\r
1681                 }\r
1682                 return INVOKERESULT_NO_SUCH_METHOD;\r
1683             default:\r
1684                 return INVOKERESULT_NO_SUCH_METHOD;\r
1685         }\r
1686     }\r
1687     return INVOKERESULT_GENERIC_ERROR;\r
1688 }\r
1689 \r