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