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