]> git.sesse.net Git - vlc/blob - projects/activex/vlccontrol2.cpp
Spell developer properly
[vlc] / projects / activex / vlccontrol2.cpp
1 /*****************************************************************************
2  * vlccontrol2.cpp: ActiveX control for VLC
3  *****************************************************************************
4  * Copyright (C) 2006 the VideoLAN team
5  *
6  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
7  *          Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #include "plugin.h"
25 #include "vlccontrol2.h"
26 #include "vlccontrol.h"
27
28 #include "utils.h"
29
30 #include <stdio.h>
31 #include <shlwapi.h>
32 #include <wininet.h>
33 #include <tchar.h>
34
35
36 static inline
37 HRESULT _exception_bridge(VLCPlugin *p,REFIID riid, libvlc_exception_t *ex)
38 {
39     if( libvlc_exception_raised(ex) )
40     {
41         p->setErrorInfo(riid,libvlc_exception_get_message(ex));
42         libvlc_exception_clear(ex);
43         return E_FAIL;
44     }
45     return NOERROR;
46 }
47
48 #define EMIT_EXCEPTION_BRIDGE( classname ) \
49     HRESULT classname::exception_bridge( libvlc_exception_t *ex ) \
50     { return _exception_bridge( _p_instance, IID_I##classname, ex ); }
51
52 EMIT_EXCEPTION_BRIDGE( VLCAudio )
53 EMIT_EXCEPTION_BRIDGE( VLCInput )
54 EMIT_EXCEPTION_BRIDGE( VLCMarquee )
55 EMIT_EXCEPTION_BRIDGE( VLCMessageIterator )
56 EMIT_EXCEPTION_BRIDGE( VLCMessages )
57 EMIT_EXCEPTION_BRIDGE( VLCLog )
58 EMIT_EXCEPTION_BRIDGE( VLCPlaylistItems )
59 EMIT_EXCEPTION_BRIDGE( VLCPlaylist )
60 EMIT_EXCEPTION_BRIDGE( VLCVideo )
61 EMIT_EXCEPTION_BRIDGE( VLCSubtitle )
62
63 #undef  EMIT_EXCEPTION_BRIDGE
64
65
66 VLCAudio::~VLCAudio()
67 {
68     if( _p_typeinfo )
69         _p_typeinfo->Release();
70 };
71
72 HRESULT VLCAudio::loadTypeInfo(void)
73 {
74     HRESULT hr = NOERROR;
75     if( NULL == _p_typeinfo )
76     {
77         ITypeLib *p_typelib;
78
79         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
80         if( SUCCEEDED(hr) )
81         {
82             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCAudio, &_p_typeinfo);
83             if( FAILED(hr) )
84             {
85                 _p_typeinfo = NULL;
86             }
87             p_typelib->Release();
88         }
89     }
90     return hr;
91 };
92
93 STDMETHODIMP VLCAudio::GetTypeInfoCount(UINT* pctInfo)
94 {
95     if( NULL == pctInfo )
96         return E_INVALIDARG;
97
98     if( SUCCEEDED(loadTypeInfo()) )
99         *pctInfo = 1;
100     else
101         *pctInfo = 0;
102
103     return NOERROR;
104 };
105
106 STDMETHODIMP VLCAudio::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
107 {
108     if( NULL == ppTInfo )
109         return E_INVALIDARG;
110
111     if( SUCCEEDED(loadTypeInfo()) )
112     {
113         _p_typeinfo->AddRef();
114         *ppTInfo = _p_typeinfo;
115         return NOERROR;
116     }
117     *ppTInfo = NULL;
118     return E_NOTIMPL;
119 };
120
121 STDMETHODIMP VLCAudio::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
122         UINT cNames, LCID lcid, DISPID* rgDispID)
123 {
124     if( SUCCEEDED(loadTypeInfo()) )
125     {
126         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
127     }
128     return E_NOTIMPL;
129 };
130
131 STDMETHODIMP VLCAudio::Invoke(DISPID dispIdMember, REFIID riid,
132         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
133         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
134 {
135     if( SUCCEEDED(loadTypeInfo()) )
136     {
137         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
138                 pVarResult, pExcepInfo, puArgErr);
139     }
140     return E_NOTIMPL;
141 };
142
143 STDMETHODIMP VLCAudio::get_mute(VARIANT_BOOL* mute)
144 {
145     if( NULL == mute )
146         return E_POINTER;
147
148     libvlc_instance_t* p_libvlc;
149     HRESULT hr = _p_instance->getVLC(&p_libvlc);
150     if( SUCCEEDED(hr) )
151     {
152         libvlc_exception_t ex;
153         libvlc_exception_init(&ex);
154
155         *mute = libvlc_audio_get_mute(p_libvlc, &ex) ?
156                         VARIANT_TRUE : VARIANT_FALSE;
157         hr = exception_bridge(&ex);
158     }
159     return hr;
160 };
161
162 STDMETHODIMP VLCAudio::put_mute(VARIANT_BOOL mute)
163 {
164     libvlc_instance_t* p_libvlc;
165     HRESULT hr = _p_instance->getVLC(&p_libvlc);
166     if( SUCCEEDED(hr) )
167     {
168         libvlc_exception_t ex;
169         libvlc_exception_init(&ex);
170
171         libvlc_audio_set_mute(p_libvlc, VARIANT_FALSE != mute, &ex);
172         hr = exception_bridge(&ex);
173     }
174     return hr;
175 };
176
177 STDMETHODIMP VLCAudio::get_volume(long* volume)
178 {
179     if( NULL == volume )
180         return E_POINTER;
181
182     libvlc_instance_t* p_libvlc;
183     HRESULT hr = _p_instance->getVLC(&p_libvlc);
184     if( SUCCEEDED(hr) )
185     {
186         libvlc_exception_t ex;
187         libvlc_exception_init(&ex);
188
189         *volume = libvlc_audio_get_volume(p_libvlc, &ex);
190         hr = exception_bridge(&ex);
191     }
192     return hr;
193 };
194
195 STDMETHODIMP VLCAudio::put_volume(long volume)
196 {
197     libvlc_instance_t* p_libvlc;
198     HRESULT hr = _p_instance->getVLC(&p_libvlc);
199     if( SUCCEEDED(hr) )
200     {
201         libvlc_exception_t ex;
202         libvlc_exception_init(&ex);
203
204         libvlc_audio_set_volume(p_libvlc, volume, &ex);
205         hr = exception_bridge(&ex);
206     }
207     return hr;
208 };
209
210 STDMETHODIMP VLCAudio::get_track(long* track)
211 {
212     if( NULL == track )
213         return E_POINTER;
214
215     libvlc_media_player_t* p_md;
216     HRESULT hr = _p_instance->getMD(&p_md);
217     if( SUCCEEDED(hr) )
218     {
219         libvlc_exception_t ex;
220         libvlc_exception_init(&ex);
221
222         *track = libvlc_audio_get_track(p_md, &ex);
223         hr = exception_bridge(&ex);
224     }
225     return hr;
226 };
227
228 STDMETHODIMP VLCAudio::put_track(long track)
229 {
230     libvlc_media_player_t *p_md;
231     HRESULT hr = _p_instance->getMD(&p_md);
232     if( SUCCEEDED(hr) )
233     {
234         libvlc_exception_t ex;
235         libvlc_exception_init(&ex);
236
237         libvlc_audio_set_track(p_md, track, &ex);
238         hr = exception_bridge(&ex);
239     }
240     return hr;
241 };
242
243 STDMETHODIMP VLCAudio::get_count(long* trackNumber)
244 {
245     if( NULL == trackNumber )
246         return E_POINTER;
247
248     libvlc_media_player_t* p_md;
249     HRESULT hr = _p_instance->getMD(&p_md);
250     if( SUCCEEDED(hr) )
251     {
252         libvlc_exception_t ex;
253         libvlc_exception_init(&ex);
254         // get the number of audio track available and return it
255         *trackNumber = libvlc_audio_get_track_count(p_md, &ex);
256         hr = exception_bridge(&ex);
257     }
258     return hr;
259 };
260
261
262 STDMETHODIMP VLCAudio::description(long trackID, BSTR* name)
263 {
264     if( NULL == name )
265         return E_POINTER;
266
267     libvlc_media_player_t* p_md;
268     libvlc_exception_t ex;
269     libvlc_exception_init(&ex);
270
271     HRESULT hr = _p_instance->getMD(&p_md);
272     if( SUCCEEDED(hr) )
273     {
274         int i, i_limit;
275         const char *psz_name;
276         libvlc_track_description_t *p_trackDesc;
277
278         // get tracks description
279         p_trackDesc = libvlc_audio_get_track_description(p_md, &ex);
280         hr = exception_bridge(&ex);
281         if( FAILED(hr) )
282             return hr;
283
284         //get the number of available track
285         i_limit = libvlc_audio_get_track_count(p_md, &ex);
286         hr = exception_bridge(&ex);
287         if( FAILED(hr) )
288             return hr;
289
290         // check if the number given is a good one
291         if ( ( trackID > ( i_limit -1 ) ) || ( trackID < 0 ) )
292                 return E_FAIL;
293
294         // get the good trackDesc
295         for( i = 0 ; i < trackID ; i++ )
296         {
297             p_trackDesc = p_trackDesc->p_next;
298         }
299         // get the track name
300         psz_name = p_trackDesc->psz_name;
301
302         // return it
303         if( psz_name != NULL )
304         {
305             *name = BSTRFromCStr(CP_UTF8, psz_name);
306             return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
307         }
308         *name = NULL;
309         return E_FAIL;
310     }
311     return hr;
312 };
313
314 STDMETHODIMP VLCAudio::get_channel(long *channel)
315 {
316     if( NULL == channel )
317         return E_POINTER;
318
319     libvlc_instance_t* p_libvlc;
320     HRESULT hr = _p_instance->getVLC(&p_libvlc);
321     if( SUCCEEDED(hr) )
322     {
323         libvlc_exception_t ex;
324         libvlc_exception_init(&ex);
325
326         *channel = libvlc_audio_get_channel(p_libvlc, &ex);
327         hr = exception_bridge(&ex);
328     }
329     return hr;
330 };
331
332 STDMETHODIMP VLCAudio::put_channel(long channel)
333 {
334     libvlc_instance_t* p_libvlc;
335     HRESULT hr = _p_instance->getVLC(&p_libvlc);
336     if( SUCCEEDED(hr) )
337     {
338         libvlc_exception_t ex;
339         libvlc_exception_init(&ex);
340
341         libvlc_audio_set_channel(p_libvlc, channel, &ex);
342         hr = exception_bridge(&ex);
343     }
344     return hr;
345 };
346
347 STDMETHODIMP VLCAudio::toggleMute()
348 {
349     libvlc_instance_t* p_libvlc;
350     HRESULT hr = _p_instance->getVLC(&p_libvlc);
351     if( SUCCEEDED(hr) )
352     {
353         libvlc_exception_t ex;
354         libvlc_exception_init(&ex);
355
356         libvlc_audio_toggle_mute(p_libvlc, &ex);
357         hr = exception_bridge(&ex);
358     }
359     return hr;
360 };
361
362 /*******************************************************************************/
363
364 VLCInput::~VLCInput()
365 {
366     if( _p_typeinfo )
367         _p_typeinfo->Release();
368 };
369
370 HRESULT VLCInput::loadTypeInfo(void)
371 {
372     HRESULT hr = NOERROR;
373     if( NULL == _p_typeinfo )
374     {
375         ITypeLib *p_typelib;
376
377         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
378         if( SUCCEEDED(hr) )
379         {
380             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCInput, &_p_typeinfo);
381             if( FAILED(hr) )
382             {
383                 _p_typeinfo = NULL;
384             }
385             p_typelib->Release();
386         }
387     }
388     return hr;
389 };
390
391 STDMETHODIMP VLCInput::GetTypeInfoCount(UINT* pctInfo)
392 {
393     if( NULL == pctInfo )
394         return E_INVALIDARG;
395
396     if( SUCCEEDED(loadTypeInfo()) )
397         *pctInfo = 1;
398     else
399         *pctInfo = 0;
400
401     return NOERROR;
402 };
403
404 STDMETHODIMP VLCInput::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
405 {
406     if( NULL == ppTInfo )
407         return E_INVALIDARG;
408
409     if( SUCCEEDED(loadTypeInfo()) )
410     {
411         _p_typeinfo->AddRef();
412         *ppTInfo = _p_typeinfo;
413         return NOERROR;
414     }
415     *ppTInfo = NULL;
416     return E_NOTIMPL;
417 };
418
419 STDMETHODIMP VLCInput::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
420         UINT cNames, LCID lcid, DISPID* rgDispID)
421 {
422     if( SUCCEEDED(loadTypeInfo()) )
423     {
424         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
425     }
426     return E_NOTIMPL;
427 };
428
429 STDMETHODIMP VLCInput::Invoke(DISPID dispIdMember, REFIID riid,
430         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
431         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
432 {
433     if( SUCCEEDED(loadTypeInfo()) )
434     {
435         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
436                 pVarResult, pExcepInfo, puArgErr);
437     }
438     return E_NOTIMPL;
439 };
440
441 STDMETHODIMP VLCInput::get_length(double* length)
442 {
443     if( NULL == length )
444         return E_POINTER;
445     *length = 0;
446
447     libvlc_media_player_t *p_md;
448     HRESULT hr = _p_instance->getMD(&p_md);
449     if( SUCCEEDED(hr) )
450     {
451         libvlc_exception_t ex;
452         libvlc_exception_init(&ex);
453
454         *length = (double)libvlc_media_player_get_length(p_md, &ex);
455         hr = exception_bridge(&ex);
456     }
457     return hr;
458 };
459
460 STDMETHODIMP VLCInput::get_position(double* position)
461 {
462     if( NULL == position )
463         return E_POINTER;
464
465     *position = 0.0f;
466     libvlc_media_player_t *p_md;
467     HRESULT hr = _p_instance->getMD(&p_md);
468     if( SUCCEEDED(hr) )
469     {
470         libvlc_exception_t ex;
471         libvlc_exception_init(&ex);
472
473         *position = libvlc_media_player_get_position(p_md, &ex);
474         hr = exception_bridge(&ex);
475     }
476     return hr;
477 };
478
479 STDMETHODIMP VLCInput::put_position(double position)
480 {
481     libvlc_media_player_t *p_md;
482     HRESULT hr = _p_instance->getMD(&p_md);
483     if( SUCCEEDED(hr) )
484     {
485         libvlc_exception_t ex;
486         libvlc_exception_init(&ex);
487
488         libvlc_media_player_set_position(p_md, position, &ex);
489         hr = exception_bridge(&ex);
490     }
491     return hr;
492 };
493
494 STDMETHODIMP VLCInput::get_time(double* time)
495 {
496     if( NULL == time )
497         return E_POINTER;
498
499     libvlc_media_player_t *p_md;
500     HRESULT hr = _p_instance->getMD(&p_md);
501     if( SUCCEEDED(hr) )
502     {
503         libvlc_exception_t ex;
504         libvlc_exception_init(&ex);
505
506         *time = (double)libvlc_media_player_get_time(p_md, &ex);
507         hr = exception_bridge(&ex);
508     }
509     return hr;
510 };
511
512 STDMETHODIMP VLCInput::put_time(double time)
513 {
514     libvlc_media_player_t *p_md;
515     HRESULT hr = _p_instance->getMD(&p_md);
516     if( SUCCEEDED(hr) )
517     {
518         libvlc_exception_t ex;
519         libvlc_exception_init(&ex);
520
521         libvlc_media_player_set_time(p_md, (int64_t)time, &ex);
522         hr = exception_bridge(&ex);
523     }
524     return hr;
525 };
526
527 STDMETHODIMP VLCInput::get_state(long* state)
528 {
529     if( NULL == state )
530         return E_POINTER;
531
532     libvlc_media_player_t *p_md;
533     HRESULT hr = _p_instance->getMD(&p_md);
534     if( SUCCEEDED(hr) )
535     {
536         libvlc_exception_t ex;
537         libvlc_exception_init(&ex);
538
539         *state = libvlc_media_player_get_state(p_md, &ex);
540         if( libvlc_exception_raised(&ex) )
541         {
542             // don't fail, just return the idle state
543             *state = 0;
544             libvlc_exception_clear(&ex);
545         }
546     }
547     return hr;
548 };
549
550 STDMETHODIMP VLCInput::get_rate(double* rate)
551 {
552     if( NULL == rate )
553         return E_POINTER;
554
555     libvlc_media_player_t *p_md;
556     HRESULT hr = _p_instance->getMD(&p_md);
557     if( SUCCEEDED(hr) )
558     {
559         libvlc_exception_t ex;
560         libvlc_exception_init(&ex);
561
562         *rate = libvlc_media_player_get_rate(p_md, &ex);
563         hr = exception_bridge(&ex);
564     }
565     return hr;
566 };
567
568 STDMETHODIMP VLCInput::put_rate(double rate)
569 {
570     libvlc_media_player_t *p_md;
571     HRESULT hr = _p_instance->getMD(&p_md);
572     if( SUCCEEDED(hr) )
573     {
574         libvlc_exception_t ex;
575         libvlc_exception_init(&ex);
576
577         libvlc_media_player_set_rate(p_md, rate, &ex);
578         hr = exception_bridge(&ex);
579     }
580     return hr;
581 };
582
583 STDMETHODIMP VLCInput::get_fps(double* fps)
584 {
585     if( NULL == fps )
586         return E_POINTER;
587
588     *fps = 0.0;
589     libvlc_media_player_t *p_md;
590     HRESULT hr = _p_instance->getMD(&p_md);
591     if( SUCCEEDED(hr) )
592     {
593         libvlc_exception_t ex;
594         libvlc_exception_init(&ex);
595
596         *fps = libvlc_media_player_get_fps(p_md, &ex);
597         hr = exception_bridge(&ex);
598     }
599     return hr;
600 };
601
602 STDMETHODIMP VLCInput::get_hasVout(VARIANT_BOOL* hasVout)
603 {
604     if( NULL == hasVout )
605         return E_POINTER;
606
607     libvlc_media_player_t *p_md;
608     HRESULT hr = _p_instance->getMD(&p_md);
609     if( SUCCEEDED(hr) )
610     {
611         libvlc_exception_t ex;
612         libvlc_exception_init(&ex);
613
614         *hasVout = libvlc_media_player_has_vout(p_md, &ex) ?
615                                 VARIANT_TRUE : VARIANT_FALSE;
616         hr = exception_bridge(&ex);
617     }
618     return hr;
619 };
620
621 /*******************************************************************************/
622
623 VLCLog::~VLCLog()
624 {
625     delete _p_vlcmessages;
626     if( _p_log )
627         libvlc_log_close(_p_log, NULL);
628
629     if( _p_typeinfo )
630         _p_typeinfo->Release();
631 };
632
633 HRESULT VLCLog::loadTypeInfo(void)
634 {
635     HRESULT hr = NOERROR;
636     if( NULL == _p_typeinfo )
637     {
638         ITypeLib *p_typelib;
639
640         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
641         if( SUCCEEDED(hr) )
642         {
643             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCLog, &_p_typeinfo);
644             if( FAILED(hr) )
645             {
646                 _p_typeinfo = NULL;
647             }
648             p_typelib->Release();
649         }
650     }
651     return hr;
652 };
653
654 STDMETHODIMP VLCLog::GetTypeInfoCount(UINT* pctInfo)
655 {
656     if( NULL == pctInfo )
657         return E_INVALIDARG;
658
659     if( SUCCEEDED(loadTypeInfo()) )
660         *pctInfo = 1;
661     else
662         *pctInfo = 0;
663
664     return NOERROR;
665 };
666
667 STDMETHODIMP VLCLog::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
668 {
669     if( NULL == ppTInfo )
670         return E_INVALIDARG;
671
672     if( SUCCEEDED(loadTypeInfo()) )
673     {
674         _p_typeinfo->AddRef();
675         *ppTInfo = _p_typeinfo;
676         return NOERROR;
677     }
678     *ppTInfo = NULL;
679     return E_NOTIMPL;
680 };
681
682 STDMETHODIMP VLCLog::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
683         UINT cNames, LCID lcid, DISPID* rgDispID)
684 {
685     if( SUCCEEDED(loadTypeInfo()) )
686     {
687         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
688     }
689     return E_NOTIMPL;
690 };
691
692 STDMETHODIMP VLCLog::Invoke(DISPID dispIdMember, REFIID riid,
693         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
694         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
695 {
696     if( SUCCEEDED(loadTypeInfo()) )
697     {
698         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
699                 pVarResult, pExcepInfo, puArgErr);
700     }
701     return E_NOTIMPL;
702 };
703
704 STDMETHODIMP VLCLog::get_messages(IVLCMessages** obj)
705 {
706     if( NULL == obj )
707         return E_POINTER;
708
709     *obj = _p_vlcmessages;
710     if( NULL != _p_vlcmessages )
711     {
712         _p_vlcmessages->AddRef();
713         return NOERROR;
714     }
715     return E_OUTOFMEMORY;
716 };
717
718 STDMETHODIMP VLCLog::get_verbosity(long* level)
719 {
720     if( NULL == level )
721         return E_POINTER;
722
723     if( _p_log )
724     {
725         libvlc_instance_t* p_libvlc;
726         HRESULT hr = _p_instance->getVLC(&p_libvlc);
727         if( SUCCEEDED(hr) )
728         {
729             libvlc_exception_t ex;
730             libvlc_exception_init(&ex);
731
732             *level = libvlc_get_log_verbosity(p_libvlc, &ex);
733             hr = exception_bridge(&ex);
734         }
735         return hr;
736     }
737     else
738     {
739         /* log is not enabled, return -1 */
740         *level = -1;
741         return NOERROR;
742     }
743 };
744
745 STDMETHODIMP VLCLog::put_verbosity(long verbosity)
746 {
747     libvlc_instance_t* p_libvlc;
748     HRESULT hr = _p_instance->getVLC(&p_libvlc);
749     if( SUCCEEDED(hr) )
750     {
751         libvlc_exception_t ex;
752         libvlc_exception_init(&ex);
753
754         if( verbosity >= 0 )
755         {
756             if( ! _p_log )
757             {
758                 _p_log = libvlc_log_open(p_libvlc, &ex);
759                 hr = exception_bridge(&ex);
760             }
761             if( SUCCEEDED(hr) )
762                 libvlc_set_log_verbosity(p_libvlc, (unsigned)verbosity, &ex);
763         }
764         else if( _p_log )
765         {
766             /* close log  when verbosity is set to -1 */
767             libvlc_log_close(_p_log, &ex);
768             _p_log = NULL;
769         }
770         hr = exception_bridge(&ex);
771     }
772     return hr;
773 };
774
775 /*******************************************************************************/
776
777 VLCMarquee::~VLCMarquee()
778 {
779     if( _p_typeinfo )
780         _p_typeinfo->Release();
781 };
782
783 HRESULT VLCMarquee::loadTypeInfo(void)
784 {
785     HRESULT hr = NOERROR;
786     if( NULL == _p_typeinfo )
787     {
788         ITypeLib *p_typelib;
789
790         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
791         if( SUCCEEDED(hr) )
792         {
793             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCMarquee, &_p_typeinfo);
794             if( FAILED(hr) )
795             {
796                 _p_typeinfo = NULL;
797             }
798             p_typelib->Release();
799         }
800     }
801     return hr;
802 };
803
804 STDMETHODIMP VLCMarquee::GetTypeInfoCount(UINT* pctInfo)
805 {
806     if( NULL == pctInfo )
807         return E_INVALIDARG;
808
809     if( SUCCEEDED(loadTypeInfo()) )
810         *pctInfo = 1;
811     else
812         *pctInfo = 0;
813
814     return NOERROR;
815 };
816
817 STDMETHODIMP VLCMarquee::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
818 {
819     if( NULL == ppTInfo )
820         return E_INVALIDARG;
821
822     if( SUCCEEDED(loadTypeInfo()) )
823     {
824         _p_typeinfo->AddRef();
825         *ppTInfo = _p_typeinfo;
826         return NOERROR;
827     }
828     *ppTInfo = NULL;
829     return E_NOTIMPL;
830 };
831
832 STDMETHODIMP VLCMarquee::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
833         UINT cNames, LCID lcid, DISPID* rgDispID)
834 {
835     if( SUCCEEDED(loadTypeInfo()) )
836     {
837         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
838     }
839     return E_NOTIMPL;
840 };
841
842 STDMETHODIMP VLCMarquee::Invoke(DISPID dispIdMember, REFIID riid,
843         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
844         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
845 {
846     if( SUCCEEDED(loadTypeInfo()) )
847     {
848         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
849                 pVarResult, pExcepInfo, puArgErr);
850     }
851     return E_NOTIMPL;
852 };
853
854 STDMETHODIMP VLCMarquee::enable()
855 {
856     libvlc_media_player_t *p_md;
857     HRESULT hr = _p_instance->getMD(&p_md);
858     if( SUCCEEDED(hr) )
859     {
860         libvlc_exception_t ex;
861         libvlc_exception_init(&ex);
862
863         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Enabled, true, &ex);
864         hr = exception_bridge(&ex);
865     }
866     return hr;
867 };
868
869 STDMETHODIMP VLCMarquee::disable()
870 {
871     libvlc_media_player_t *p_md;
872     HRESULT hr = _p_instance->getMD(&p_md);
873     if( SUCCEEDED(hr) )
874     {
875         libvlc_exception_t ex;
876         libvlc_exception_init(&ex);
877
878         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Enabled, false, &ex);
879         hr = exception_bridge(&ex);
880     }
881     return hr;
882 };
883
884 STDMETHODIMP VLCMarquee::color(long val)
885 {
886     libvlc_media_player_t *p_md;
887     HRESULT hr = _p_instance->getMD(&p_md);
888     if( SUCCEEDED(hr) )
889     {
890         libvlc_exception_t ex;
891         libvlc_exception_init(&ex);
892
893         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Color, val, &ex);
894         hr = exception_bridge(&ex);
895     }
896     return hr;
897 };
898
899 STDMETHODIMP VLCMarquee::opacity(long val)
900 {
901     libvlc_media_player_t *p_md;
902     HRESULT hr = _p_instance->getMD(&p_md);
903     if( SUCCEEDED(hr) )
904     {
905         libvlc_exception_t ex;
906         libvlc_exception_init(&ex);
907
908         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Opacity, val, &ex);
909         hr = exception_bridge(&ex);
910     }
911     return hr;
912 };
913
914 STDMETHODIMP VLCMarquee::position(long val)
915 {
916     libvlc_media_player_t *p_md;
917     HRESULT hr = _p_instance->getMD(&p_md);
918     if( SUCCEEDED(hr) )
919     {
920         libvlc_exception_t ex;
921         libvlc_exception_init(&ex);
922
923         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Position, val, &ex);
924         hr = exception_bridge(&ex);
925     }
926     return hr;
927 };
928
929 STDMETHODIMP VLCMarquee::refresh(long val)
930 {
931     libvlc_media_player_t *p_md;
932     HRESULT hr = _p_instance->getMD(&p_md);
933     if( SUCCEEDED(hr) )
934     {
935         libvlc_exception_t ex;
936         libvlc_exception_init(&ex);
937
938         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Refresh, val, &ex);
939         hr = exception_bridge(&ex);
940     }
941     return hr;
942 };
943
944 STDMETHODIMP VLCMarquee::size(long val)
945 {
946     libvlc_media_player_t *p_md;
947     HRESULT hr = _p_instance->getMD(&p_md);
948     if( SUCCEEDED(hr) )
949     {
950         libvlc_exception_t ex;
951         libvlc_exception_init(&ex);
952
953         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Size, val, &ex);
954         hr = exception_bridge(&ex);
955     }
956     return hr;
957 };
958
959 STDMETHODIMP VLCMarquee::text(BSTR text)
960 {
961     libvlc_media_player_t *p_md;
962     HRESULT hr = _p_instance->getMD(&p_md);
963     if( SUCCEEDED(hr) )
964     {
965         libvlc_exception_t ex;
966         libvlc_exception_init(&ex);
967
968         char *psz_text = CStrFromBSTR(CP_UTF8, text);
969         libvlc_video_set_marquee_option_as_string(p_md, libvlc_marquee_Text, psz_text, &ex);
970         hr = exception_bridge(&ex);
971         CoTaskMemFree(psz_text);
972     }
973     return hr;
974 };
975
976 STDMETHODIMP VLCMarquee::timeout(long val)
977 {
978     libvlc_media_player_t *p_md;
979     HRESULT hr = _p_instance->getMD(&p_md);
980     if( SUCCEEDED(hr) )
981     {
982         libvlc_exception_t ex;
983         libvlc_exception_init(&ex);
984
985         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Timeout, val, &ex);
986         hr = exception_bridge(&ex);
987     }
988     return hr;
989 };
990
991 STDMETHODIMP VLCMarquee::x(long val)
992 {
993     libvlc_media_player_t *p_md;
994     HRESULT hr = _p_instance->getMD(&p_md);
995     if( SUCCEEDED(hr) )
996     {
997         libvlc_exception_t ex;
998         libvlc_exception_init(&ex);
999
1000         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_X, val, &ex);
1001         hr = exception_bridge(&ex);
1002     }
1003     return hr;
1004 };
1005
1006 STDMETHODIMP VLCMarquee::y(long val)
1007 {
1008     libvlc_media_player_t *p_md;
1009     HRESULT hr = _p_instance->getMD(&p_md);
1010     if( SUCCEEDED(hr) )
1011     {
1012         libvlc_exception_t ex;
1013         libvlc_exception_init(&ex);
1014
1015         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Y, val, &ex);
1016         hr = exception_bridge(&ex);
1017     }
1018     return hr;
1019 };
1020
1021 /*******************************************************************************/
1022
1023 /* STL forward iterator used by VLCEnumIterator class to implement IEnumVARIANT */
1024
1025 class VLCMessageSTLIterator
1026 {
1027
1028 public:
1029
1030     VLCMessageSTLIterator(IVLCMessageIterator* iter) : iter(iter), msg(NULL)
1031     {
1032         // get first message
1033         operator++();
1034     };
1035
1036     VLCMessageSTLIterator(const VLCMessageSTLIterator& other)
1037     {
1038         iter = other.iter;
1039         if( iter )
1040             iter->AddRef();
1041         msg = other.msg;
1042         if( msg )
1043             msg->AddRef();
1044     };
1045
1046     virtual ~VLCMessageSTLIterator()
1047     {
1048         if( msg )
1049             msg->Release();
1050
1051         if( iter )
1052             iter->Release();
1053     };
1054
1055     // we only need prefix ++ operator
1056     VLCMessageSTLIterator& operator++()
1057     {
1058         VARIANT_BOOL hasNext = VARIANT_FALSE;
1059         if( iter )
1060         {
1061             iter->get_hasNext(&hasNext);
1062
1063             if( msg )
1064             {
1065                 msg->Release();
1066                 msg = NULL;
1067             }
1068             if( VARIANT_TRUE == hasNext ) {
1069                 iter->next(&msg);
1070             }
1071         }
1072         return *this;
1073     };
1074
1075     VARIANT operator*() const
1076     {
1077         VARIANT v;
1078         VariantInit(&v);
1079         if( msg )
1080         {
1081             if( SUCCEEDED(msg->QueryInterface(IID_IDispatch,
1082                           (LPVOID*)&V_DISPATCH(&v))) )
1083             {
1084                 V_VT(&v) = VT_DISPATCH;
1085             }
1086         }
1087         return v;
1088     };
1089
1090     bool operator==(const VLCMessageSTLIterator& other) const
1091     {
1092         return msg == other.msg;
1093     };
1094
1095     bool operator!=(const VLCMessageSTLIterator& other) const
1096     {
1097         return msg != other.msg;
1098     };
1099
1100 private:
1101     IVLCMessageIterator* iter;
1102     IVLCMessage*         msg;
1103 };
1104
1105 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1106
1107 VLCMessages::~VLCMessages()
1108 {
1109     if( _p_typeinfo )
1110         _p_typeinfo->Release();
1111 };
1112
1113 HRESULT VLCMessages::loadTypeInfo(void)
1114 {
1115     HRESULT hr = NOERROR;
1116     if( NULL == _p_typeinfo )
1117     {
1118         ITypeLib *p_typelib;
1119
1120         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1121         if( SUCCEEDED(hr) )
1122         {
1123             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCMessages, &_p_typeinfo);
1124             if( FAILED(hr) )
1125             {
1126                 _p_typeinfo = NULL;
1127             }
1128             p_typelib->Release();
1129         }
1130     }
1131     return hr;
1132 };
1133
1134 STDMETHODIMP VLCMessages::GetTypeInfoCount(UINT* pctInfo)
1135 {
1136     if( NULL == pctInfo )
1137         return E_INVALIDARG;
1138
1139     if( SUCCEEDED(loadTypeInfo()) )
1140         *pctInfo = 1;
1141     else
1142         *pctInfo = 0;
1143
1144     return NOERROR;
1145 };
1146
1147 STDMETHODIMP VLCMessages::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1148 {
1149     if( NULL == ppTInfo )
1150         return E_INVALIDARG;
1151
1152     if( SUCCEEDED(loadTypeInfo()) )
1153     {
1154         _p_typeinfo->AddRef();
1155         *ppTInfo = _p_typeinfo;
1156         return NOERROR;
1157     }
1158     *ppTInfo = NULL;
1159     return E_NOTIMPL;
1160 };
1161
1162 STDMETHODIMP VLCMessages::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1163         UINT cNames, LCID lcid, DISPID* rgDispID)
1164 {
1165     if( SUCCEEDED(loadTypeInfo()) )
1166     {
1167         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1168     }
1169     return E_NOTIMPL;
1170 };
1171
1172 STDMETHODIMP VLCMessages::Invoke(DISPID dispIdMember, REFIID riid,
1173         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1174         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1175 {
1176     if( SUCCEEDED(loadTypeInfo()) )
1177     {
1178         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1179                 pVarResult, pExcepInfo, puArgErr);
1180     }
1181     return E_NOTIMPL;
1182 };
1183
1184 STDMETHODIMP VLCMessages::get__NewEnum(LPUNKNOWN* _NewEnum)
1185 {
1186     if( NULL == _NewEnum )
1187         return E_POINTER;
1188
1189     IVLCMessageIterator* iter = NULL;
1190     iterator(&iter);
1191
1192     *_NewEnum= new VLCEnumIterator<IID_IEnumVARIANT,
1193                        IEnumVARIANT,
1194                        VARIANT,
1195                        VLCMessageSTLIterator>
1196                        (VLCMessageSTLIterator(iter), VLCMessageSTLIterator(NULL));
1197
1198     return *_NewEnum ? S_OK : E_OUTOFMEMORY;
1199 };
1200
1201 STDMETHODIMP VLCMessages::clear()
1202 {
1203     HRESULT hr = NOERROR;
1204     libvlc_log_t *p_log = _p_vlclog->_p_log;
1205     if( p_log )
1206     {
1207         libvlc_exception_t ex;
1208         libvlc_exception_init(&ex);
1209
1210         libvlc_log_clear(p_log, &ex);
1211         hr = exception_bridge(&ex);
1212     }
1213     return hr;
1214 };
1215
1216 STDMETHODIMP VLCMessages::get_count(long* count)
1217 {
1218     HRESULT hr = S_OK;
1219
1220     if( NULL == count )
1221         return E_POINTER;
1222
1223     libvlc_log_t *p_log = _p_vlclog->_p_log;
1224     if( p_log )
1225     {
1226         libvlc_exception_t ex;
1227         libvlc_exception_init(&ex);
1228
1229         *count = libvlc_log_count(p_log, &ex);
1230         hr = exception_bridge(&ex);
1231     }
1232     else
1233         *count = 0;
1234     return hr;
1235 };
1236
1237 STDMETHODIMP VLCMessages::iterator(IVLCMessageIterator** iter)
1238 {
1239     if( NULL == iter )
1240         return E_POINTER;
1241
1242     *iter = new VLCMessageIterator(_p_instance, _p_vlclog);
1243
1244     return *iter ? S_OK : E_OUTOFMEMORY;
1245 };
1246
1247 /*******************************************************************************/
1248
1249 VLCMessageIterator::VLCMessageIterator(VLCPlugin *p_instance, VLCLog* p_vlclog ) :
1250     _p_instance(p_instance),
1251     _p_typeinfo(NULL),
1252     _refcount(1),
1253     _p_vlclog(p_vlclog)
1254 {
1255     if( p_vlclog->_p_log )
1256     {
1257         _p_iter = libvlc_log_get_iterator(p_vlclog->_p_log, NULL);
1258     }
1259     else
1260         _p_iter = NULL;
1261 };
1262
1263 VLCMessageIterator::~VLCMessageIterator()
1264 {
1265     if( _p_iter )
1266         libvlc_log_iterator_free(_p_iter, NULL);
1267
1268     if( _p_typeinfo )
1269         _p_typeinfo->Release();
1270 };
1271
1272 HRESULT VLCMessageIterator::loadTypeInfo(void)
1273 {
1274     HRESULT hr = NOERROR;
1275     if( NULL == _p_typeinfo )
1276     {
1277         ITypeLib *p_typelib;
1278
1279         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1280         if( SUCCEEDED(hr) )
1281         {
1282             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCMessageIterator, &_p_typeinfo);
1283             if( FAILED(hr) )
1284             {
1285                 _p_typeinfo = NULL;
1286             }
1287             p_typelib->Release();
1288         }
1289     }
1290     return hr;
1291 };
1292
1293 STDMETHODIMP VLCMessageIterator::GetTypeInfoCount(UINT* pctInfo)
1294 {
1295     if( NULL == pctInfo )
1296         return E_INVALIDARG;
1297
1298     if( SUCCEEDED(loadTypeInfo()) )
1299         *pctInfo = 1;
1300     else
1301         *pctInfo = 0;
1302
1303     return NOERROR;
1304 };
1305
1306 STDMETHODIMP VLCMessageIterator::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1307 {
1308     if( NULL == ppTInfo )
1309         return E_INVALIDARG;
1310
1311     if( SUCCEEDED(loadTypeInfo()) )
1312     {
1313         _p_typeinfo->AddRef();
1314         *ppTInfo = _p_typeinfo;
1315         return NOERROR;
1316     }
1317     *ppTInfo = NULL;
1318     return E_NOTIMPL;
1319 };
1320
1321 STDMETHODIMP VLCMessageIterator::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1322         UINT cNames, LCID lcid, DISPID* rgDispID)
1323 {
1324     if( SUCCEEDED(loadTypeInfo()) )
1325     {
1326         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1327     }
1328     return E_NOTIMPL;
1329 };
1330
1331 STDMETHODIMP VLCMessageIterator::Invoke(DISPID dispIdMember, REFIID riid,
1332         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1333         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1334 {
1335     if( SUCCEEDED(loadTypeInfo()) )
1336     {
1337         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1338                 pVarResult, pExcepInfo, puArgErr);
1339     }
1340     return E_NOTIMPL;
1341 };
1342
1343 STDMETHODIMP VLCMessageIterator::get_hasNext(VARIANT_BOOL* hasNext)
1344 {
1345     HRESULT hr = S_OK;
1346
1347     if( NULL == hasNext )
1348         return E_POINTER;
1349
1350     if( _p_iter &&  _p_vlclog->_p_log )
1351     {
1352         libvlc_exception_t ex;
1353         libvlc_exception_init(&ex);
1354
1355         *hasNext = libvlc_log_iterator_has_next(_p_iter, &ex) ?
1356                    VARIANT_TRUE : VARIANT_FALSE;
1357         hr = exception_bridge(&ex);
1358     }
1359     else
1360     {
1361         *hasNext = VARIANT_FALSE;
1362     }
1363     return hr;
1364 };
1365
1366 STDMETHODIMP VLCMessageIterator::next(IVLCMessage** message)
1367 {
1368     HRESULT hr = S_OK;
1369
1370     if( NULL == message )
1371         return E_POINTER;
1372
1373     if( _p_iter &&  _p_vlclog->_p_log )
1374     {
1375         struct libvlc_log_message_t buffer;
1376
1377         buffer.sizeof_msg = sizeof(buffer);
1378
1379         libvlc_exception_t ex;
1380         libvlc_exception_init(&ex);
1381
1382         libvlc_log_iterator_next(_p_iter, &buffer, &ex);
1383         hr = exception_bridge(&ex);
1384         if( SUCCEEDED(hr) )
1385         {
1386             *message = new VLCMessage(_p_instance, buffer);
1387             if( !message )
1388                 hr = E_OUTOFMEMORY;
1389         }
1390     }
1391     return hr;
1392 };
1393
1394 /*******************************************************************************/
1395
1396 VLCMessage::~VLCMessage()
1397 {
1398     if( _p_typeinfo )
1399         _p_typeinfo->Release();
1400 };
1401
1402 HRESULT VLCMessage::loadTypeInfo(void)
1403 {
1404     HRESULT hr = NOERROR;
1405     if( NULL == _p_typeinfo )
1406     {
1407         ITypeLib *p_typelib;
1408
1409         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1410         if( SUCCEEDED(hr) )
1411         {
1412             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCMessage, &_p_typeinfo);
1413             if( FAILED(hr) )
1414             {
1415                 _p_typeinfo = NULL;
1416             }
1417             p_typelib->Release();
1418         }
1419     }
1420     return hr;
1421 };
1422
1423 STDMETHODIMP VLCMessage::GetTypeInfoCount(UINT* pctInfo)
1424 {
1425     if( NULL == pctInfo )
1426         return E_INVALIDARG;
1427
1428     if( SUCCEEDED(loadTypeInfo()) )
1429         *pctInfo = 1;
1430     else
1431         *pctInfo = 0;
1432
1433     return NOERROR;
1434 };
1435
1436 STDMETHODIMP VLCMessage::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1437 {
1438     if( NULL == ppTInfo )
1439         return E_INVALIDARG;
1440
1441     if( SUCCEEDED(loadTypeInfo()) )
1442     {
1443         _p_typeinfo->AddRef();
1444         *ppTInfo = _p_typeinfo;
1445         return NOERROR;
1446     }
1447     *ppTInfo = NULL;
1448     return E_NOTIMPL;
1449 };
1450
1451 STDMETHODIMP VLCMessage::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1452         UINT cNames, LCID lcid, DISPID* rgDispID)
1453 {
1454     if( SUCCEEDED(loadTypeInfo()) )
1455     {
1456         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1457     }
1458     return E_NOTIMPL;
1459 };
1460
1461 STDMETHODIMP VLCMessage::Invoke(DISPID dispIdMember, REFIID riid,
1462         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1463         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1464 {
1465     if( SUCCEEDED(loadTypeInfo()) )
1466     {
1467         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1468                 pVarResult, pExcepInfo, puArgErr);
1469     }
1470     return E_NOTIMPL;
1471 };
1472
1473 inline const char *msgSeverity(int sev)
1474 {
1475     switch( sev )
1476     {
1477         case 0:
1478             return "info";
1479         case 1:
1480             return "error";
1481         case 2:
1482             return "warning";
1483         default:
1484             return "debug";
1485     }
1486 };
1487
1488 STDMETHODIMP VLCMessage::get__Value(VARIANT* _Value)
1489 {
1490     if( NULL == _Value )
1491         return E_POINTER;
1492
1493     char buffer[256];
1494
1495     snprintf(buffer, sizeof(buffer), "%s %s %s: %s",
1496         _msg.psz_type, _msg.psz_name, msgSeverity(_msg.i_severity), _msg.psz_message);
1497
1498     V_VT(_Value) = VT_BSTR;
1499     V_BSTR(_Value) = BSTRFromCStr(CP_UTF8, buffer);
1500
1501     return S_OK;
1502 };
1503
1504 STDMETHODIMP VLCMessage::get_severity(long* level)
1505 {
1506     if( NULL == level )
1507         return E_POINTER;
1508
1509     *level = _msg.i_severity;
1510
1511     return S_OK;
1512 };
1513
1514 STDMETHODIMP VLCMessage::get_type(BSTR* type)
1515 {
1516     if( NULL == type )
1517         return E_POINTER;
1518
1519     *type = BSTRFromCStr(CP_UTF8, _msg.psz_type);
1520
1521     return NOERROR;
1522 };
1523
1524 STDMETHODIMP VLCMessage::get_name(BSTR* name)
1525 {
1526     if( NULL == name )
1527         return E_POINTER;
1528
1529     *name = BSTRFromCStr(CP_UTF8, _msg.psz_name);
1530
1531     return NOERROR;
1532 };
1533
1534 STDMETHODIMP VLCMessage::get_header(BSTR* header)
1535 {
1536     if( NULL == header )
1537         return E_POINTER;
1538
1539     *header = BSTRFromCStr(CP_UTF8, _msg.psz_header);
1540
1541     return NOERROR;
1542 };
1543
1544 STDMETHODIMP VLCMessage::get_message(BSTR* message)
1545 {
1546     if( NULL == message )
1547         return E_POINTER;
1548
1549     *message = BSTRFromCStr(CP_UTF8, _msg.psz_message);
1550
1551     return NOERROR;
1552 };
1553
1554 /*******************************************************************************/
1555
1556 VLCPlaylistItems::~VLCPlaylistItems()
1557 {
1558     if( _p_typeinfo )
1559         _p_typeinfo->Release();
1560 };
1561
1562 HRESULT VLCPlaylistItems::loadTypeInfo(void)
1563 {
1564     HRESULT hr = NOERROR;
1565     if( NULL == _p_typeinfo )
1566     {
1567         ITypeLib *p_typelib;
1568
1569         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1570         if( SUCCEEDED(hr) )
1571         {
1572             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCPlaylistItems, &_p_typeinfo);
1573             if( FAILED(hr) )
1574             {
1575                 _p_typeinfo = NULL;
1576             }
1577             p_typelib->Release();
1578         }
1579     }
1580     return hr;
1581 };
1582
1583 STDMETHODIMP VLCPlaylistItems::GetTypeInfoCount(UINT* pctInfo)
1584 {
1585     if( NULL == pctInfo )
1586         return E_INVALIDARG;
1587
1588     if( SUCCEEDED(loadTypeInfo()) )
1589         *pctInfo = 1;
1590     else
1591         *pctInfo = 0;
1592
1593     return NOERROR;
1594 };
1595
1596 STDMETHODIMP VLCPlaylistItems::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1597 {
1598     if( NULL == ppTInfo )
1599         return E_INVALIDARG;
1600
1601     if( SUCCEEDED(loadTypeInfo()) )
1602     {
1603         _p_typeinfo->AddRef();
1604         *ppTInfo = _p_typeinfo;
1605         return NOERROR;
1606     }
1607     *ppTInfo = NULL;
1608     return E_NOTIMPL;
1609 };
1610
1611 STDMETHODIMP VLCPlaylistItems::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1612         UINT cNames, LCID lcid, DISPID* rgDispID)
1613 {
1614     if( SUCCEEDED(loadTypeInfo()) )
1615     {
1616         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1617     }
1618     return E_NOTIMPL;
1619 };
1620
1621 STDMETHODIMP VLCPlaylistItems::Invoke(DISPID dispIdMember, REFIID riid,
1622         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1623         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1624 {
1625     if( SUCCEEDED(loadTypeInfo()) )
1626     {
1627         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1628                 pVarResult, pExcepInfo, puArgErr);
1629     }
1630     return E_NOTIMPL;
1631 };
1632
1633 STDMETHODIMP VLCPlaylistItems::get_count(long* count)
1634 {
1635     if( NULL == count )
1636         return E_POINTER;
1637
1638     libvlc_exception_t ex;
1639     libvlc_exception_init(&ex);
1640
1641     *count = _p_instance->playlist_count(&ex);
1642     return exception_bridge(&ex);
1643 };
1644
1645 STDMETHODIMP VLCPlaylistItems::clear()
1646 {
1647     libvlc_exception_t ex;
1648     libvlc_exception_init(&ex);
1649
1650     _p_instance->playlist_clear(&ex);
1651     return exception_bridge(&ex);
1652 };
1653
1654 STDMETHODIMP VLCPlaylistItems::remove(long item)
1655 {
1656     libvlc_instance_t* p_libvlc;
1657     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1658     if( SUCCEEDED(hr) )
1659     {
1660         libvlc_exception_t ex;
1661         libvlc_exception_init(&ex);
1662
1663         _p_instance->playlist_delete_item(item, &ex);
1664         hr = exception_bridge(&ex);
1665     }
1666     return hr;
1667 };
1668
1669 /*******************************************************************************/
1670
1671 VLCPlaylist::~VLCPlaylist()
1672 {
1673     delete _p_vlcplaylistitems;
1674     if( _p_typeinfo )
1675         _p_typeinfo->Release();
1676 };
1677
1678 HRESULT VLCPlaylist::loadTypeInfo(void)
1679 {
1680     HRESULT hr = NOERROR;
1681     if( NULL == _p_typeinfo )
1682     {
1683         ITypeLib *p_typelib;
1684
1685         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1686         if( SUCCEEDED(hr) )
1687         {
1688             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCPlaylist, &_p_typeinfo);
1689             if( FAILED(hr) )
1690             {
1691                 _p_typeinfo = NULL;
1692             }
1693             p_typelib->Release();
1694         }
1695     }
1696     return hr;
1697 };
1698
1699 STDMETHODIMP VLCPlaylist::GetTypeInfoCount(UINT* pctInfo)
1700 {
1701     if( NULL == pctInfo )
1702         return E_INVALIDARG;
1703
1704     if( SUCCEEDED(loadTypeInfo()) )
1705         *pctInfo = 1;
1706     else
1707         *pctInfo = 0;
1708
1709     return NOERROR;
1710 };
1711
1712 STDMETHODIMP VLCPlaylist::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1713 {
1714     if( NULL == ppTInfo )
1715         return E_INVALIDARG;
1716
1717     if( SUCCEEDED(loadTypeInfo()) )
1718     {
1719         _p_typeinfo->AddRef();
1720         *ppTInfo = _p_typeinfo;
1721         return NOERROR;
1722     }
1723     *ppTInfo = NULL;
1724     return E_NOTIMPL;
1725 };
1726
1727 STDMETHODIMP VLCPlaylist::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1728         UINT cNames, LCID lcid, DISPID* rgDispID)
1729 {
1730     if( SUCCEEDED(loadTypeInfo()) )
1731     {
1732         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1733     }
1734     return E_NOTIMPL;
1735 };
1736
1737 STDMETHODIMP VLCPlaylist::Invoke(DISPID dispIdMember, REFIID riid,
1738         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1739         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1740 {
1741     if( SUCCEEDED(loadTypeInfo()) )
1742     {
1743         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1744                 pVarResult, pExcepInfo, puArgErr);
1745     }
1746     return E_NOTIMPL;
1747 };
1748
1749 STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
1750 {
1751     if( NULL == count )
1752         return E_POINTER;
1753
1754     *count = 0;
1755     libvlc_exception_t ex;
1756     libvlc_exception_init(&ex);
1757
1758     *count = _p_instance->playlist_count(&ex);
1759     return exception_bridge(&ex);
1760 };
1761
1762 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
1763 {
1764     if( NULL == isPlaying )
1765         return E_POINTER;
1766
1767     libvlc_media_player_t *p_md;
1768     HRESULT hr = _p_instance->getMD(&p_md);
1769     if( SUCCEEDED(hr) )
1770     {
1771         libvlc_exception_t ex;
1772         libvlc_exception_init(&ex);
1773
1774         *isPlaying = libvlc_media_player_is_playing(p_md, &ex) ?
1775                      VARIANT_TRUE: VARIANT_FALSE;
1776         libvlc_exception_clear(&ex);
1777     }
1778     return hr;
1779 };
1780
1781 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
1782 {
1783     if( NULL == item )
1784         return E_POINTER;
1785
1786     if( 0 == SysStringLen(uri) )
1787         return E_INVALIDARG;
1788
1789     libvlc_instance_t* p_libvlc;
1790     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1791     if( SUCCEEDED(hr) )
1792     {
1793         libvlc_exception_t ex;
1794         libvlc_exception_init(&ex);
1795
1796         char *psz_uri = NULL;
1797         if( SysStringLen(_p_instance->getBaseURL()) > 0 )
1798         {
1799             /*
1800             ** if the MRL a relative URL, we should end up with an absolute URL
1801             */
1802             LPWSTR abs_url = CombineURL(_p_instance->getBaseURL(), uri);
1803             if( NULL != abs_url )
1804             {
1805                 psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
1806                 CoTaskMemFree(abs_url);
1807             }
1808             else
1809             {
1810                 psz_uri = CStrFromBSTR(CP_UTF8, uri);
1811             }
1812         }
1813         else
1814         {
1815             /*
1816             ** baseURL is empty, assume MRL is absolute
1817             */
1818             psz_uri = CStrFromBSTR(CP_UTF8, uri);
1819         }
1820
1821         if( NULL == psz_uri )
1822         {
1823             return E_OUTOFMEMORY;
1824         }
1825
1826         int i_options;
1827         char **ppsz_options;
1828
1829         hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
1830         if( FAILED(hr) )
1831         {
1832             CoTaskMemFree(psz_uri);
1833             return hr;
1834         }
1835
1836         char *psz_name = NULL;
1837         VARIANT v_name;
1838         VariantInit(&v_name);
1839         if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
1840         {
1841             if( SysStringLen(V_BSTR(&v_name)) > 0 )
1842                 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
1843
1844             VariantClear(&v_name);
1845         }
1846
1847         *item = _p_instance->playlist_add_extended_untrusted(psz_uri,
1848                     i_options, const_cast<const char **>(ppsz_options), &ex);
1849
1850         VLCControl::FreeTargetOptions(ppsz_options, i_options);
1851         CoTaskMemFree(psz_uri);
1852         if( psz_name ) /* XXX Do we even need to check? */
1853             CoTaskMemFree(psz_name);
1854         hr = exception_bridge(&ex);
1855     }
1856     return hr;
1857 };
1858
1859 STDMETHODIMP VLCPlaylist::play()
1860 {
1861     libvlc_exception_t ex;
1862     libvlc_exception_init(&ex);
1863
1864     _p_instance->playlist_play(&ex);
1865     return exception_bridge(&ex);
1866 };
1867
1868 STDMETHODIMP VLCPlaylist::playItem(long item)
1869 {
1870     libvlc_exception_t ex;
1871     libvlc_exception_init(&ex);
1872
1873     _p_instance->playlist_play_item(item,&ex);
1874     return exception_bridge(&ex);;
1875 };
1876
1877 STDMETHODIMP VLCPlaylist::togglePause()
1878 {
1879     libvlc_media_player_t* p_md;
1880     HRESULT hr = _p_instance->getMD(&p_md);
1881     if( SUCCEEDED(hr) )
1882     {
1883         libvlc_exception_t ex;
1884         libvlc_exception_init(&ex);
1885
1886         libvlc_media_player_pause(p_md, &ex);
1887         hr = exception_bridge(&ex);;
1888     }
1889     return hr;
1890 };
1891
1892 STDMETHODIMP VLCPlaylist::stop()
1893 {
1894     libvlc_media_player_t *p_md;
1895     HRESULT hr = _p_instance->getMD(&p_md);
1896     if( SUCCEEDED(hr) )
1897     {
1898         libvlc_exception_t ex;
1899         libvlc_exception_init(&ex);
1900
1901         libvlc_media_player_stop(p_md, &ex);
1902         hr = exception_bridge(&ex);;
1903     }
1904     return hr;
1905 };
1906
1907 STDMETHODIMP VLCPlaylist::next()
1908 {
1909     libvlc_exception_t ex;
1910     libvlc_exception_init(&ex);
1911
1912     _p_instance->playlist_next(&ex);
1913     return exception_bridge(&ex);;
1914 };
1915
1916 STDMETHODIMP VLCPlaylist::prev()
1917 {
1918     libvlc_exception_t ex;
1919     libvlc_exception_init(&ex);
1920
1921     _p_instance->playlist_prev(&ex);
1922     return exception_bridge(&ex);;
1923 };
1924
1925 STDMETHODIMP VLCPlaylist::clear()
1926 {
1927     libvlc_exception_t ex;
1928     libvlc_exception_init(&ex);
1929
1930     _p_instance->playlist_clear(&ex);
1931     return exception_bridge(&ex);;
1932 };
1933
1934 STDMETHODIMP VLCPlaylist::removeItem(long item)
1935 {
1936     libvlc_instance_t* p_libvlc;
1937     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1938     if( SUCCEEDED(hr) )
1939     {
1940         libvlc_exception_t ex;
1941         libvlc_exception_init(&ex);
1942
1943         _p_instance->playlist_delete_item(item, &ex);
1944         hr = exception_bridge(&ex);;
1945     }
1946     return hr;
1947 };
1948
1949 STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
1950 {
1951     if( NULL == obj )
1952         return E_POINTER;
1953
1954     *obj = _p_vlcplaylistitems;
1955     if( NULL != _p_vlcplaylistitems )
1956     {
1957         _p_vlcplaylistitems->AddRef();
1958         return NOERROR;
1959     }
1960     return E_OUTOFMEMORY;
1961 };
1962
1963 /*******************************************************************************/
1964
1965 VLCSubtitle::~VLCSubtitle()
1966 {
1967     if( _p_typeinfo )
1968         _p_typeinfo->Release();
1969 };
1970
1971 HRESULT VLCSubtitle::loadTypeInfo(void)
1972 {
1973     HRESULT hr = NOERROR;
1974     if( NULL == _p_typeinfo )
1975     {
1976         ITypeLib *p_typelib;
1977
1978         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1979         if( SUCCEEDED(hr) )
1980         {
1981             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCSubtitle, &_p_typeinfo);
1982             if( FAILED(hr) )
1983             {
1984                 _p_typeinfo = NULL;
1985             }
1986             p_typelib->Release();
1987         }
1988     }
1989     return hr;
1990 };
1991
1992 STDMETHODIMP VLCSubtitle::GetTypeInfoCount(UINT* pctInfo)
1993 {
1994     if( NULL == pctInfo )
1995         return E_INVALIDARG;
1996
1997     if( SUCCEEDED(loadTypeInfo()) )
1998         *pctInfo = 1;
1999     else
2000         *pctInfo = 0;
2001
2002     return NOERROR;
2003 };
2004
2005 STDMETHODIMP VLCSubtitle::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
2006 {
2007     if( NULL == ppTInfo )
2008         return E_INVALIDARG;
2009
2010     if( SUCCEEDED(loadTypeInfo()) )
2011     {
2012         _p_typeinfo->AddRef();
2013         *ppTInfo = _p_typeinfo;
2014         return NOERROR;
2015     }
2016     *ppTInfo = NULL;
2017     return E_NOTIMPL;
2018 };
2019
2020 STDMETHODIMP VLCSubtitle::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
2021         UINT cNames, LCID lcid, DISPID* rgDispID)
2022 {
2023     if( SUCCEEDED(loadTypeInfo()) )
2024     {
2025         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
2026     }
2027     return E_NOTIMPL;
2028 };
2029
2030 STDMETHODIMP VLCSubtitle::Invoke(DISPID dispIdMember, REFIID riid,
2031         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
2032         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
2033 {
2034     if( SUCCEEDED(loadTypeInfo()) )
2035     {
2036         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
2037                 pVarResult, pExcepInfo, puArgErr);
2038     }
2039     return E_NOTIMPL;
2040 };
2041
2042 STDMETHODIMP VLCSubtitle::get_track(long* spu)
2043 {
2044     if( NULL == spu )
2045         return E_POINTER;
2046
2047     libvlc_media_player_t *p_md;
2048     HRESULT hr = _p_instance->getMD(&p_md);
2049     if( SUCCEEDED(hr) )
2050     {
2051         libvlc_exception_t ex;
2052         libvlc_exception_init(&ex);
2053
2054         *spu = libvlc_video_get_spu(p_md, &ex);
2055         hr = exception_bridge(&ex);
2056     }
2057     return hr;
2058 };
2059
2060 STDMETHODIMP VLCSubtitle::put_track(long spu)
2061 {
2062     libvlc_media_player_t *p_md;
2063     HRESULT hr = _p_instance->getMD(&p_md);
2064     if( SUCCEEDED(hr) )
2065     {
2066         libvlc_exception_t ex;
2067         libvlc_exception_init(&ex);
2068
2069         libvlc_video_set_spu(p_md, spu, &ex);
2070         hr = exception_bridge(&ex);
2071     }
2072     return hr;
2073 };
2074
2075 STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
2076 {
2077     if( NULL == spuNumber )
2078         return E_POINTER;
2079
2080     libvlc_media_player_t *p_md;
2081     HRESULT hr = _p_instance->getMD(&p_md);
2082     if( SUCCEEDED(hr) )
2083     {
2084         libvlc_exception_t ex;
2085         libvlc_exception_init(&ex);
2086         // get the number of video subtitle available and return it
2087         *spuNumber = libvlc_video_get_spu_count(p_md, &ex);
2088         hr = exception_bridge(&ex);
2089     }
2090     return hr;
2091 };
2092
2093
2094 STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
2095 {
2096     if( NULL == name )
2097        return E_POINTER;
2098
2099     libvlc_media_player_t* p_md;
2100     libvlc_exception_t ex;
2101     libvlc_exception_init(&ex);
2102
2103     HRESULT hr = _p_instance->getMD(&p_md);
2104     if( SUCCEEDED(hr) )
2105     {
2106         int i, i_limit;
2107         const char *psz_name;
2108         libvlc_track_description_t *p_spuDesc;
2109
2110         // get subtitles description
2111         p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
2112         hr = exception_bridge(&ex);
2113         if( FAILED(hr) )
2114             return hr;
2115
2116         // get the number of available subtitle
2117         i_limit = libvlc_video_get_spu_count(p_md, &ex);
2118         hr = exception_bridge(&ex);
2119         if( FAILED(hr) )
2120             return hr;
2121
2122         // check if the number given is a good one
2123         if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
2124             return E_FAIL;
2125
2126         // get the good spuDesc
2127         for( i = 0 ; i < nameID ; i++ )
2128         {
2129             p_spuDesc = p_spuDesc->p_next;
2130         }
2131         // get the subtitle name
2132         psz_name = p_spuDesc->psz_name;
2133
2134         // return it
2135         if( psz_name != NULL )
2136         {
2137             *name = BSTRFromCStr(CP_UTF8, psz_name);
2138             return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
2139         }
2140         *name = NULL;
2141         return E_FAIL;
2142     }
2143     return hr;
2144 };
2145
2146 /*******************************************************************************/
2147
2148 VLCVideo::~VLCVideo()
2149 {
2150     delete _p_vlcmarquee;
2151     if( _p_typeinfo )
2152         _p_typeinfo->Release();
2153 };
2154
2155 HRESULT VLCVideo::loadTypeInfo(void)
2156 {
2157     HRESULT hr = NOERROR;
2158     if( NULL == _p_typeinfo )
2159     {
2160         ITypeLib *p_typelib;
2161
2162         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
2163         if( SUCCEEDED(hr) )
2164         {
2165             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCVideo, &_p_typeinfo);
2166             if( FAILED(hr) )
2167             {
2168                 _p_typeinfo = NULL;
2169             }
2170             p_typelib->Release();
2171         }
2172     }
2173     return hr;
2174 };
2175
2176 STDMETHODIMP VLCVideo::GetTypeInfoCount(UINT* pctInfo)
2177 {
2178     if( NULL == pctInfo )
2179         return E_INVALIDARG;
2180
2181     if( SUCCEEDED(loadTypeInfo()) )
2182         *pctInfo = 1;
2183     else
2184         *pctInfo = 0;
2185
2186     return NOERROR;
2187 };
2188
2189 STDMETHODIMP VLCVideo::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
2190 {
2191     if( NULL == ppTInfo )
2192         return E_INVALIDARG;
2193
2194     if( SUCCEEDED(loadTypeInfo()) )
2195     {
2196         _p_typeinfo->AddRef();
2197         *ppTInfo = _p_typeinfo;
2198         return NOERROR;
2199     }
2200     *ppTInfo = NULL;
2201     return E_NOTIMPL;
2202 };
2203
2204 STDMETHODIMP VLCVideo::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
2205         UINT cNames, LCID lcid, DISPID* rgDispID)
2206 {
2207     if( SUCCEEDED(loadTypeInfo()) )
2208     {
2209         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
2210     }
2211     return E_NOTIMPL;
2212 };
2213
2214 STDMETHODIMP VLCVideo::Invoke(DISPID dispIdMember, REFIID riid,
2215         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
2216         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
2217 {
2218     if( SUCCEEDED(loadTypeInfo()) )
2219     {
2220         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
2221                 pVarResult, pExcepInfo, puArgErr);
2222     }
2223     return E_NOTIMPL;
2224 };
2225
2226 STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
2227 {
2228     if( NULL == fullscreen )
2229         return E_POINTER;
2230
2231     libvlc_media_player_t *p_md;
2232     HRESULT hr = _p_instance->getMD(&p_md);
2233     if( SUCCEEDED(hr) )
2234     {
2235         libvlc_exception_t ex;
2236         libvlc_exception_init(&ex);
2237
2238         *fullscreen = libvlc_get_fullscreen(p_md, &ex) ?
2239                       VARIANT_TRUE : VARIANT_FALSE;
2240         hr = exception_bridge(&ex);
2241     }
2242     return hr;
2243 };
2244
2245 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
2246 {
2247     libvlc_media_player_t *p_md;
2248     HRESULT hr = _p_instance->getMD(&p_md);
2249     if( SUCCEEDED(hr) )
2250     {
2251         libvlc_exception_t ex;
2252         libvlc_exception_init(&ex);
2253
2254         libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen, &ex);
2255         hr = exception_bridge(&ex);
2256     }
2257     return hr;
2258 };
2259
2260 STDMETHODIMP VLCVideo::get_width(long* width)
2261 {
2262     if( NULL == width )
2263         return E_POINTER;
2264
2265     libvlc_media_player_t *p_md;
2266     HRESULT hr = _p_instance->getMD(&p_md);
2267     if( SUCCEEDED(hr) )
2268     {
2269         libvlc_exception_t ex;
2270         libvlc_exception_init(&ex);
2271
2272         *width = libvlc_video_get_width(p_md, &ex);
2273         hr = exception_bridge(&ex);
2274     }
2275     return hr;
2276 };
2277
2278 STDMETHODIMP VLCVideo::get_height(long* height)
2279 {
2280     if( NULL == height )
2281         return E_POINTER;
2282
2283     libvlc_media_player_t *p_md;
2284     HRESULT hr = _p_instance->getMD(&p_md);
2285     if( SUCCEEDED(hr) )
2286     {
2287         libvlc_exception_t ex;
2288         libvlc_exception_init(&ex);
2289
2290         *height = libvlc_video_get_height(p_md, &ex);
2291         hr = exception_bridge(&ex);
2292     }
2293     return hr;
2294 };
2295
2296 STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
2297 {
2298     if( NULL == aspect )
2299         return E_POINTER;
2300
2301     libvlc_media_player_t *p_md;
2302     HRESULT hr = _p_instance->getMD(&p_md);
2303     if( SUCCEEDED(hr) )
2304     {
2305         libvlc_exception_t ex;
2306         libvlc_exception_init(&ex);
2307
2308         char *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
2309
2310         hr = exception_bridge(&ex);
2311         if( SUCCEEDED(hr) && NULL != psz_aspect )
2312         {
2313             *aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
2314             if( NULL == *aspect )
2315                 hr = E_OUTOFMEMORY;
2316         } else if( NULL == psz_aspect) hr = E_OUTOFMEMORY; // strdup("") failed
2317         free( psz_aspect );
2318     }
2319     return hr;
2320 };
2321
2322 STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
2323 {
2324     if( NULL == aspect )
2325         return E_POINTER;
2326
2327     libvlc_media_player_t *p_md;
2328     HRESULT hr = _p_instance->getMD(&p_md);
2329     if( SUCCEEDED(hr) )
2330     {
2331         libvlc_exception_t ex;
2332         libvlc_exception_init(&ex);
2333
2334         char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
2335         if( NULL == psz_aspect )
2336         {
2337             return E_OUTOFMEMORY;
2338         }
2339
2340         libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
2341
2342         CoTaskMemFree(psz_aspect);
2343         hr = exception_bridge(&ex);
2344     }
2345     return hr;
2346 };
2347
2348 STDMETHODIMP VLCVideo::get_subtitle(long* spu)
2349 {
2350     if( NULL == spu )
2351         return E_POINTER;
2352
2353     libvlc_media_player_t *p_md;
2354     HRESULT hr = _p_instance->getMD(&p_md);
2355     if( SUCCEEDED(hr) )
2356     {
2357         libvlc_exception_t ex;
2358         libvlc_exception_init(&ex);
2359
2360         *spu = libvlc_video_get_spu(p_md, &ex);
2361         hr = exception_bridge(&ex);
2362     }
2363     return hr;
2364 };
2365
2366 STDMETHODIMP VLCVideo::put_subtitle(long spu)
2367 {
2368     libvlc_media_player_t *p_md;
2369     HRESULT hr = _p_instance->getMD(&p_md);
2370     if( SUCCEEDED(hr) )
2371     {
2372         libvlc_exception_t ex;
2373         libvlc_exception_init(&ex);
2374
2375         libvlc_video_set_spu(p_md, spu, &ex);
2376         hr = exception_bridge(&ex);
2377     }
2378     return hr;
2379 };
2380
2381 STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
2382 {
2383     if( NULL == geometry )
2384         return E_POINTER;
2385
2386     libvlc_media_player_t *p_md;
2387     HRESULT hr = _p_instance->getMD(&p_md);
2388     if( SUCCEEDED(hr) )
2389     {
2390         libvlc_exception_t ex;
2391         libvlc_exception_init(&ex);
2392
2393         char *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
2394
2395         hr = exception_bridge(&ex);
2396         if( SUCCEEDED(&ex) && NULL != psz_geometry )
2397         {
2398             *geometry = BSTRFromCStr(CP_UTF8, psz_geometry);
2399             if( NULL == geometry ) hr = E_OUTOFMEMORY;
2400         } else if( NULL == psz_geometry ) hr = E_OUTOFMEMORY;
2401         free( psz_geometry );
2402     }
2403     return hr;
2404 };
2405
2406 STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
2407 {
2408     if( NULL == geometry )
2409         return E_POINTER;
2410
2411     if( 0 == SysStringLen(geometry) )
2412         return E_INVALIDARG;
2413
2414     libvlc_media_player_t *p_md;
2415     HRESULT hr = _p_instance->getMD(&p_md);
2416     if( SUCCEEDED(hr) )
2417     {
2418         libvlc_exception_t ex;
2419         libvlc_exception_init(&ex);
2420
2421         char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
2422         if( NULL == psz_geometry )
2423         {
2424             return E_OUTOFMEMORY;
2425         }
2426
2427         libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
2428
2429         CoTaskMemFree(psz_geometry);
2430         hr = exception_bridge(&ex);
2431     }
2432     return hr;
2433 };
2434
2435 STDMETHODIMP VLCVideo::get_teletext(long* page)
2436 {
2437     if( NULL == page )
2438         return E_POINTER;
2439
2440     libvlc_media_player_t *p_md;
2441     HRESULT hr = _p_instance->getMD(&p_md);
2442     if( SUCCEEDED(hr) )
2443     {
2444         libvlc_exception_t ex;
2445         libvlc_exception_init(&ex);
2446
2447         *page = libvlc_video_get_teletext(p_md, &ex);
2448         hr = exception_bridge(&ex);
2449     }
2450     return hr;
2451 };
2452
2453 STDMETHODIMP VLCVideo::put_teletext(long page)
2454 {
2455     libvlc_media_player_t *p_md;
2456     HRESULT hr = _p_instance->getMD(&p_md);
2457     if( SUCCEEDED(hr) )
2458     {
2459         libvlc_exception_t ex;
2460         libvlc_exception_init(&ex);
2461
2462         libvlc_video_set_teletext(p_md, page, &ex);
2463         hr = exception_bridge(&ex);
2464     }
2465     return hr;
2466 };
2467
2468 STDMETHODIMP VLCVideo::deinterlaceDisable()
2469 {
2470     libvlc_media_player_t *p_md;
2471     HRESULT hr = _p_instance->getMD(&p_md);
2472     if( SUCCEEDED(hr) )
2473     {
2474         libvlc_exception_t ex;
2475         libvlc_exception_init(&ex);
2476
2477         libvlc_video_set_deinterlace(p_md, 0, "", &ex);
2478         hr = exception_bridge(&ex);
2479     }
2480     return hr;
2481 };
2482
2483 STDMETHODIMP VLCVideo::deinterlaceEnable(BSTR mode)
2484 {
2485     libvlc_media_player_t *p_md;
2486     HRESULT hr = _p_instance->getMD(&p_md);
2487     if( SUCCEEDED(hr) )
2488     {
2489         libvlc_exception_t ex;
2490         libvlc_exception_init(&ex);
2491         /* get deinterlace mode from the user */
2492         char *psz_mode = CStrFromBSTR(CP_UTF8, mode);
2493         /* enable deinterlace filter if possible */
2494         libvlc_video_set_deinterlace(p_md, 1, psz_mode, &ex);
2495         hr = exception_bridge(&ex);
2496         CoTaskMemFree(psz_mode);
2497     }
2498     return hr;
2499 };
2500
2501 STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
2502 {
2503     if( NULL == picture )
2504         return E_POINTER;
2505
2506     libvlc_media_player_t *p_md;
2507     HRESULT hr = _p_instance->getMD(&p_md);
2508     if( SUCCEEDED(hr) )
2509     {
2510         libvlc_exception_t ex;
2511         libvlc_exception_init(&ex);
2512
2513         static int uniqueId = 0;
2514         TCHAR path[MAX_PATH+1];
2515
2516         int pathlen = GetTempPath(MAX_PATH-24, path);
2517         if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
2518             return E_FAIL;
2519
2520         /* check temp directory path by openning it */
2521         {
2522             HANDLE dirHandle = CreateFile(path, GENERIC_READ,
2523                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2524                        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
2525             if( INVALID_HANDLE_VALUE == dirHandle )
2526             {
2527                 _p_instance->setErrorInfo(IID_IVLCVideo,
2528                         "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
2529                 return E_FAIL;
2530             }
2531             else
2532             {
2533                 BY_HANDLE_FILE_INFORMATION bhfi;
2534                 BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
2535                 CloseHandle(dirHandle);
2536                 if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
2537                 {
2538                     _p_instance->setErrorInfo(IID_IVLCVideo,
2539                             "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
2540                     return E_FAIL;
2541                 }
2542             }
2543         }
2544
2545         TCHAR filepath[MAX_PATH+1];
2546
2547         _stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
2548                  path, GetCurrentProcessId(), ++uniqueId);
2549
2550 #ifdef _UNICODE
2551         /* reuse path storage for UTF8 string */
2552         char *psz_filepath = (char *)path;
2553         WCHAR* wpath = filepath;
2554 #else
2555         char *psz_filepath = path;
2556         /* first convert to unicode using current code page */
2557         WCHAR wpath[MAX_PATH+1];
2558         if( 0 == MultiByteToWideChar(CP_ACP, 0, filepath, -1,
2559                                      wpath, sizeof(wpath)/sizeof(WCHAR)) )
2560             return E_FAIL;
2561 #endif
2562         /* convert to UTF8 */
2563         pathlen = WideCharToMultiByte(CP_UTF8, 0, wpath, -1,
2564                                       psz_filepath, sizeof(path), NULL, NULL);
2565         // fail if path is 0 or too short (i.e pathlen is the same as
2566         // storage size)
2567
2568         if( (0 == pathlen) || (sizeof(path) == pathlen) )
2569             return E_FAIL;
2570
2571         /* take snapshot into file */
2572         libvlc_video_take_snapshot(p_md, psz_filepath, 0, 0, &ex);
2573         hr = exception_bridge(&ex);
2574         if( SUCCEEDED(hr) )
2575         {
2576             /* open snapshot file */
2577             HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP, 0, 0,
2578                                        LR_CREATEDIBSECTION|LR_LOADFROMFILE);
2579             if( snapPic )
2580             {
2581                 PICTDESC snapDesc;
2582
2583                 snapDesc.cbSizeofstruct = sizeof(PICTDESC);
2584                 snapDesc.picType        = PICTYPE_BITMAP;
2585                 snapDesc.bmp.hbitmap    = (HBITMAP)snapPic;
2586                 snapDesc.bmp.hpal       = NULL;
2587
2588                 hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp,
2589                                               TRUE, (LPVOID*)picture);
2590                 if( FAILED(hr) )
2591                 {
2592                     *picture = NULL;
2593                     DeleteObject(snapPic);
2594                 }
2595             }
2596             DeleteFile(filepath);
2597         }
2598     }
2599     return hr;
2600 };
2601
2602 STDMETHODIMP VLCVideo::toggleFullscreen()
2603 {
2604     libvlc_media_player_t *p_md;
2605     HRESULT hr = _p_instance->getMD(&p_md);
2606     if( SUCCEEDED(hr) )
2607     {
2608         libvlc_exception_t ex;
2609         libvlc_exception_init(&ex);
2610
2611         libvlc_toggle_fullscreen(p_md, &ex);
2612         hr = exception_bridge(&ex);
2613     }
2614     return hr;
2615 };
2616
2617 STDMETHODIMP VLCVideo::toggleTeletext()
2618 {
2619     libvlc_media_player_t *p_md;
2620     HRESULT hr = _p_instance->getMD(&p_md);
2621     if( SUCCEEDED(hr) )
2622     {
2623         libvlc_exception_t ex;
2624         libvlc_exception_init(&ex);
2625
2626         libvlc_toggle_teletext(p_md, &ex);
2627         hr = exception_bridge(&ex);
2628     }
2629     return hr;
2630 };
2631
2632 STDMETHODIMP VLCVideo::get_marquee(IVLCMarquee** obj)
2633 {
2634     if( NULL == obj )
2635         return E_POINTER;
2636
2637     *obj = _p_vlcmarquee;
2638     if( NULL != _p_vlcmarquee )
2639     {
2640         _p_vlcmarquee->AddRef();
2641         return NOERROR;
2642     }
2643     return E_OUTOFMEMORY;
2644 };
2645
2646 /*******************************************************************************/
2647
2648 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
2649     _p_instance(p_instance),
2650     _p_typeinfo(NULL),
2651     _p_vlcaudio(NULL),
2652     _p_vlcinput(NULL),
2653     _p_vlcplaylist(NULL),
2654     _p_vlcsubtitle(NULL),
2655     _p_vlcvideo(NULL)
2656 {
2657     _p_vlcaudio     = new VLCAudio(p_instance);
2658     _p_vlcinput     = new VLCInput(p_instance);
2659     _p_vlclog       = new VLCLog(p_instance);
2660     _p_vlcplaylist  = new VLCPlaylist(p_instance);
2661     _p_vlcsubtitle  = new VLCSubtitle(p_instance);
2662     _p_vlcvideo     = new VLCVideo(p_instance);
2663 };
2664
2665 VLCControl2::~VLCControl2()
2666 {
2667     delete _p_vlcvideo;
2668     delete _p_vlcsubtitle;
2669     delete _p_vlcplaylist;
2670     delete _p_vlclog;
2671     delete _p_vlcinput;
2672     delete _p_vlcaudio;
2673     if( _p_typeinfo )
2674         _p_typeinfo->Release();
2675 };
2676
2677 HRESULT VLCControl2::loadTypeInfo(void)
2678 {
2679     HRESULT hr = NOERROR;
2680     if( NULL == _p_typeinfo )
2681     {
2682         ITypeLib *p_typelib;
2683
2684         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
2685         if( SUCCEEDED(hr) )
2686         {
2687             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
2688             if( FAILED(hr) )
2689             {
2690                 _p_typeinfo = NULL;
2691             }
2692             p_typelib->Release();
2693         }
2694     }
2695     return hr;
2696 };
2697
2698 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
2699 {
2700     if( NULL == pctInfo )
2701         return E_INVALIDARG;
2702
2703     if( SUCCEEDED(loadTypeInfo()) )
2704         *pctInfo = 1;
2705     else
2706         *pctInfo = 0;
2707
2708     return NOERROR;
2709 };
2710
2711 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
2712 {
2713     if( NULL == ppTInfo )
2714         return E_INVALIDARG;
2715
2716     if( SUCCEEDED(loadTypeInfo()) )
2717     {
2718         _p_typeinfo->AddRef();
2719         *ppTInfo = _p_typeinfo;
2720         return NOERROR;
2721     }
2722     *ppTInfo = NULL;
2723     return E_NOTIMPL;
2724 };
2725
2726 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
2727         UINT cNames, LCID lcid, DISPID* rgDispID)
2728 {
2729     if( SUCCEEDED(loadTypeInfo()) )
2730     {
2731         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
2732     }
2733     return E_NOTIMPL;
2734 };
2735
2736 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
2737         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
2738         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
2739 {
2740     if( SUCCEEDED(loadTypeInfo()) )
2741     {
2742         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
2743                 pVarResult, pExcepInfo, puArgErr);
2744     }
2745     return E_NOTIMPL;
2746 };
2747
2748 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
2749 {
2750     if( NULL == autoloop )
2751         return E_POINTER;
2752
2753     *autoloop = _p_instance->getAutoLoop() ? VARIANT_TRUE: VARIANT_FALSE;
2754     return S_OK;
2755 };
2756
2757 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
2758 {
2759     _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
2760     return S_OK;
2761 };
2762
2763 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
2764 {
2765     if( NULL == autoplay )
2766         return E_POINTER;
2767
2768     *autoplay = _p_instance->getAutoPlay() ? VARIANT_TRUE: VARIANT_FALSE;
2769     return S_OK;
2770 };
2771
2772 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
2773 {
2774     _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
2775     return S_OK;
2776 };
2777
2778 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
2779 {
2780     if( NULL == url )
2781         return E_POINTER;
2782
2783     *url = SysAllocStringLen(_p_instance->getBaseURL(),
2784                 SysStringLen(_p_instance->getBaseURL()));
2785     return NOERROR;
2786 };
2787
2788 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
2789 {
2790     _p_instance->setBaseURL(mrl);
2791
2792     return S_OK;
2793 };
2794
2795 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
2796 {
2797     if( NULL == mrl )
2798         return E_POINTER;
2799
2800     *mrl = SysAllocStringLen(_p_instance->getMRL(),
2801                 SysStringLen(_p_instance->getMRL()));
2802     return NOERROR;
2803 };
2804
2805 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
2806 {
2807     _p_instance->setMRL(mrl);
2808
2809     return S_OK;
2810 };
2811
2812
2813 STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
2814 {
2815     if( NULL == visible )
2816         return E_POINTER;
2817
2818     /*
2819      * Note to developers
2820      *
2821      * Returning the _b_toolbar is closer to the method specification.
2822      * But returning True when toolbar is not implemented so not displayed
2823      * could be bad for ActiveX users which rely on this value to show their
2824      * own toolbar if not provided by the ActiveX.
2825      *
2826      * This is the reason why FALSE is returned, until toolbar get implemented.
2827      */
2828
2829     /* DISABLED for now */
2830     //  *visible = _p_instance->getShowToolbar() ? VARIANT_TRUE: VARIANT_FALSE;
2831
2832     *visible = VARIANT_FALSE;
2833
2834     return S_OK;
2835 };
2836
2837 STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
2838 {
2839     _p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
2840     return S_OK;
2841 };
2842
2843
2844 STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
2845 {
2846     if( NULL == seconds )
2847         return E_POINTER;
2848
2849     *seconds = _p_instance->getStartTime();
2850
2851     return S_OK;
2852 };
2853
2854 STDMETHODIMP VLCControl2::put_StartTime(long seconds)
2855 {
2856     _p_instance->setStartTime(seconds);
2857
2858     return NOERROR;
2859 };
2860
2861 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
2862 {
2863     if( NULL == version )
2864         return E_POINTER;
2865
2866     const char *versionStr = libvlc_get_version();
2867     if( NULL != versionStr )
2868     {
2869         *version = BSTRFromCStr(CP_UTF8, versionStr);
2870
2871         return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
2872     }
2873     *version = NULL;
2874     return E_FAIL;
2875 };
2876
2877 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
2878 {
2879     if( NULL == isVisible )
2880         return E_POINTER;
2881
2882     *isVisible = _p_instance->getVisible() ? VARIANT_TRUE : VARIANT_FALSE;
2883
2884     return NOERROR;
2885 };
2886
2887 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
2888 {
2889     _p_instance->setVisible(isVisible != VARIANT_FALSE);
2890
2891     return NOERROR;
2892 };
2893
2894 STDMETHODIMP VLCControl2::get_Volume(long *volume)
2895 {
2896     if( NULL == volume )
2897         return E_POINTER;
2898
2899     *volume  = _p_instance->getVolume();
2900     return NOERROR;
2901 };
2902
2903 STDMETHODIMP VLCControl2::put_Volume(long volume)
2904 {
2905     _p_instance->setVolume(volume);
2906     return NOERROR;
2907 };
2908
2909 STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
2910 {
2911     if( NULL == backcolor )
2912         return E_POINTER;
2913
2914     *backcolor  = _p_instance->getBackColor();
2915     return NOERROR;
2916 };
2917
2918 STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
2919 {
2920     _p_instance->setBackColor(backcolor);
2921     return NOERROR;
2922 };
2923
2924 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
2925 {
2926     if( NULL == obj )
2927         return E_POINTER;
2928
2929     *obj = _p_vlcaudio;
2930     if( NULL != _p_vlcaudio )
2931     {
2932         _p_vlcaudio->AddRef();
2933         return NOERROR;
2934     }
2935     return E_OUTOFMEMORY;
2936 };
2937
2938 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
2939 {
2940     if( NULL == obj )
2941         return E_POINTER;
2942
2943     *obj = _p_vlcinput;
2944     if( NULL != _p_vlcinput )
2945     {
2946         _p_vlcinput->AddRef();
2947         return NOERROR;
2948     }
2949     return E_OUTOFMEMORY;
2950 };
2951
2952 STDMETHODIMP VLCControl2::get_log(IVLCLog** obj)
2953 {
2954     if( NULL == obj )
2955         return E_POINTER;
2956
2957     *obj = _p_vlclog;
2958     if( NULL != _p_vlclog )
2959     {
2960         _p_vlclog->AddRef();
2961         return NOERROR;
2962     }
2963     return E_OUTOFMEMORY;
2964 };
2965
2966 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
2967 {
2968     if( NULL == obj )
2969         return E_POINTER;
2970
2971     *obj = _p_vlcplaylist;
2972     if( NULL != _p_vlcplaylist )
2973     {
2974         _p_vlcplaylist->AddRef();
2975         return NOERROR;
2976     }
2977     return E_OUTOFMEMORY;
2978 };
2979
2980 STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
2981 {
2982     if( NULL == obj )
2983         return E_POINTER;
2984
2985     *obj = _p_vlcsubtitle;
2986     if( NULL != _p_vlcsubtitle )
2987     {
2988         _p_vlcsubtitle->AddRef();
2989         return NOERROR;
2990     }
2991     return E_OUTOFMEMORY;
2992 };
2993
2994 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
2995 {
2996     if( NULL == obj )
2997         return E_POINTER;
2998
2999     *obj = _p_vlcvideo;
3000     if( NULL != _p_vlcvideo )
3001     {
3002         _p_vlcvideo->AddRef();
3003         return NOERROR;
3004     }
3005     return E_OUTOFMEMORY;
3006 };