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