4aeac925e9086b13d8cf9e89cea6ec253e197599
[vlc.git] / 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_errmsg());
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);
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             *level = libvlc_get_log_verbosity(p_libvlc);
729         return hr;
730     }
731     else
732     {
733         /* log is not enabled, return -1 */
734         *level = -1;
735         return NOERROR;
736     }
737 };
738
739 STDMETHODIMP VLCLog::put_verbosity(long verbosity)
740 {
741     libvlc_instance_t* p_libvlc;
742     HRESULT hr = _p_instance->getVLC(&p_libvlc);
743     if( SUCCEEDED(hr) )
744     {
745         libvlc_exception_t ex;
746         libvlc_exception_init(&ex);
747
748         if( verbosity >= 0 )
749         {
750             if( ! _p_log )
751             {
752                 _p_log = libvlc_log_open(p_libvlc, &ex);
753                 hr = exception_bridge(&ex);
754             }
755             if( SUCCEEDED(hr) )
756                 libvlc_set_log_verbosity(p_libvlc, (unsigned)verbosity);
757         }
758         else if( _p_log )
759         {
760             /* close log  when verbosity is set to -1 */
761             libvlc_log_close(_p_log);
762             _p_log = NULL;
763         }
764         hr = exception_bridge(&ex);
765     }
766     return hr;
767 };
768
769 /*******************************************************************************/
770
771 VLCMarquee::~VLCMarquee()
772 {
773     if( _p_typeinfo )
774         _p_typeinfo->Release();
775 };
776
777 HRESULT VLCMarquee::loadTypeInfo(void)
778 {
779     HRESULT hr = NOERROR;
780     if( NULL == _p_typeinfo )
781     {
782         ITypeLib *p_typelib;
783
784         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
785         if( SUCCEEDED(hr) )
786         {
787             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCMarquee, &_p_typeinfo);
788             if( FAILED(hr) )
789             {
790                 _p_typeinfo = NULL;
791             }
792             p_typelib->Release();
793         }
794     }
795     return hr;
796 };
797
798 STDMETHODIMP VLCMarquee::GetTypeInfoCount(UINT* pctInfo)
799 {
800     if( NULL == pctInfo )
801         return E_INVALIDARG;
802
803     if( SUCCEEDED(loadTypeInfo()) )
804         *pctInfo = 1;
805     else
806         *pctInfo = 0;
807
808     return NOERROR;
809 };
810
811 STDMETHODIMP VLCMarquee::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
812 {
813     if( NULL == ppTInfo )
814         return E_INVALIDARG;
815
816     if( SUCCEEDED(loadTypeInfo()) )
817     {
818         _p_typeinfo->AddRef();
819         *ppTInfo = _p_typeinfo;
820         return NOERROR;
821     }
822     *ppTInfo = NULL;
823     return E_NOTIMPL;
824 };
825
826 STDMETHODIMP VLCMarquee::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
827         UINT cNames, LCID lcid, DISPID* rgDispID)
828 {
829     if( SUCCEEDED(loadTypeInfo()) )
830     {
831         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
832     }
833     return E_NOTIMPL;
834 };
835
836 STDMETHODIMP VLCMarquee::Invoke(DISPID dispIdMember, REFIID riid,
837         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
838         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
839 {
840     if( SUCCEEDED(loadTypeInfo()) )
841     {
842         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
843                 pVarResult, pExcepInfo, puArgErr);
844     }
845     return E_NOTIMPL;
846 };
847
848 STDMETHODIMP VLCMarquee::enable()
849 {
850     libvlc_media_player_t *p_md;
851     HRESULT hr = _p_instance->getMD(&p_md);
852     if( SUCCEEDED(hr) )
853     {
854         libvlc_exception_t ex;
855         libvlc_exception_init(&ex);
856
857         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Enabled, true, &ex);
858         hr = exception_bridge(&ex);
859     }
860     return hr;
861 };
862
863 STDMETHODIMP VLCMarquee::disable()
864 {
865     libvlc_media_player_t *p_md;
866     HRESULT hr = _p_instance->getMD(&p_md);
867     if( SUCCEEDED(hr) )
868     {
869         libvlc_exception_t ex;
870         libvlc_exception_init(&ex);
871
872         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Enabled, false, &ex);
873         hr = exception_bridge(&ex);
874     }
875     return hr;
876 };
877
878 STDMETHODIMP VLCMarquee::color(long val)
879 {
880     libvlc_media_player_t *p_md;
881     HRESULT hr = _p_instance->getMD(&p_md);
882     if( SUCCEEDED(hr) )
883     {
884         libvlc_exception_t ex;
885         libvlc_exception_init(&ex);
886
887         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Color, val, &ex);
888         hr = exception_bridge(&ex);
889     }
890     return hr;
891 };
892
893 STDMETHODIMP VLCMarquee::opacity(long val)
894 {
895     libvlc_media_player_t *p_md;
896     HRESULT hr = _p_instance->getMD(&p_md);
897     if( SUCCEEDED(hr) )
898     {
899         libvlc_exception_t ex;
900         libvlc_exception_init(&ex);
901
902         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Opacity, val, &ex);
903         hr = exception_bridge(&ex);
904     }
905     return hr;
906 };
907
908 STDMETHODIMP VLCMarquee::position(long val)
909 {
910     libvlc_media_player_t *p_md;
911     HRESULT hr = _p_instance->getMD(&p_md);
912     if( SUCCEEDED(hr) )
913     {
914         libvlc_exception_t ex;
915         libvlc_exception_init(&ex);
916
917         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Position, val, &ex);
918         hr = exception_bridge(&ex);
919     }
920     return hr;
921 };
922
923 STDMETHODIMP VLCMarquee::refresh(long val)
924 {
925     libvlc_media_player_t *p_md;
926     HRESULT hr = _p_instance->getMD(&p_md);
927     if( SUCCEEDED(hr) )
928     {
929         libvlc_exception_t ex;
930         libvlc_exception_init(&ex);
931
932         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Refresh, val, &ex);
933         hr = exception_bridge(&ex);
934     }
935     return hr;
936 };
937
938 STDMETHODIMP VLCMarquee::size(long val)
939 {
940     libvlc_media_player_t *p_md;
941     HRESULT hr = _p_instance->getMD(&p_md);
942     if( SUCCEEDED(hr) )
943     {
944         libvlc_exception_t ex;
945         libvlc_exception_init(&ex);
946
947         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Size, val, &ex);
948         hr = exception_bridge(&ex);
949     }
950     return hr;
951 };
952
953 STDMETHODIMP VLCMarquee::text(BSTR text)
954 {
955     libvlc_media_player_t *p_md;
956     HRESULT hr = _p_instance->getMD(&p_md);
957     if( SUCCEEDED(hr) )
958     {
959         libvlc_exception_t ex;
960         libvlc_exception_init(&ex);
961
962         char *psz_text = CStrFromBSTR(CP_UTF8, text);
963         libvlc_video_set_marquee_option_as_string(p_md, libvlc_marquee_Text, psz_text, &ex);
964         hr = exception_bridge(&ex);
965         CoTaskMemFree(psz_text);
966     }
967     return hr;
968 };
969
970 STDMETHODIMP VLCMarquee::timeout(long val)
971 {
972     libvlc_media_player_t *p_md;
973     HRESULT hr = _p_instance->getMD(&p_md);
974     if( SUCCEEDED(hr) )
975     {
976         libvlc_exception_t ex;
977         libvlc_exception_init(&ex);
978
979         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Timeout, val, &ex);
980         hr = exception_bridge(&ex);
981     }
982     return hr;
983 };
984
985 STDMETHODIMP VLCMarquee::x(long val)
986 {
987     libvlc_media_player_t *p_md;
988     HRESULT hr = _p_instance->getMD(&p_md);
989     if( SUCCEEDED(hr) )
990     {
991         libvlc_exception_t ex;
992         libvlc_exception_init(&ex);
993
994         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_X, val, &ex);
995         hr = exception_bridge(&ex);
996     }
997     return hr;
998 };
999
1000 STDMETHODIMP VLCMarquee::y(long val)
1001 {
1002     libvlc_media_player_t *p_md;
1003     HRESULT hr = _p_instance->getMD(&p_md);
1004     if( SUCCEEDED(hr) )
1005     {
1006         libvlc_exception_t ex;
1007         libvlc_exception_init(&ex);
1008
1009         libvlc_video_set_marquee_option_as_int(p_md, libvlc_marquee_Y, val, &ex);
1010         hr = exception_bridge(&ex);
1011     }
1012     return hr;
1013 };
1014
1015 /*******************************************************************************/
1016
1017 /* STL forward iterator used by VLCEnumIterator class to implement IEnumVARIANT */
1018
1019 class VLCMessageSTLIterator
1020 {
1021
1022 public:
1023
1024     VLCMessageSTLIterator(IVLCMessageIterator* iter) : iter(iter), msg(NULL)
1025     {
1026         // get first message
1027         operator++();
1028     };
1029
1030     VLCMessageSTLIterator(const VLCMessageSTLIterator& other)
1031     {
1032         iter = other.iter;
1033         if( iter )
1034             iter->AddRef();
1035         msg = other.msg;
1036         if( msg )
1037             msg->AddRef();
1038     };
1039
1040     virtual ~VLCMessageSTLIterator()
1041     {
1042         if( msg )
1043             msg->Release();
1044
1045         if( iter )
1046             iter->Release();
1047     };
1048
1049     // we only need prefix ++ operator
1050     VLCMessageSTLIterator& operator++()
1051     {
1052         VARIANT_BOOL hasNext = VARIANT_FALSE;
1053         if( iter )
1054         {
1055             iter->get_hasNext(&hasNext);
1056
1057             if( msg )
1058             {
1059                 msg->Release();
1060                 msg = NULL;
1061             }
1062             if( VARIANT_TRUE == hasNext ) {
1063                 iter->next(&msg);
1064             }
1065         }
1066         return *this;
1067     };
1068
1069     VARIANT operator*() const
1070     {
1071         VARIANT v;
1072         VariantInit(&v);
1073         if( msg )
1074         {
1075             if( SUCCEEDED(msg->QueryInterface(IID_IDispatch,
1076                           (LPVOID*)&V_DISPATCH(&v))) )
1077             {
1078                 V_VT(&v) = VT_DISPATCH;
1079             }
1080         }
1081         return v;
1082     };
1083
1084     bool operator==(const VLCMessageSTLIterator& other) const
1085     {
1086         return msg == other.msg;
1087     };
1088
1089     bool operator!=(const VLCMessageSTLIterator& other) const
1090     {
1091         return msg != other.msg;
1092     };
1093
1094 private:
1095     IVLCMessageIterator* iter;
1096     IVLCMessage*         msg;
1097 };
1098
1099 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1100
1101 VLCMessages::~VLCMessages()
1102 {
1103     if( _p_typeinfo )
1104         _p_typeinfo->Release();
1105 };
1106
1107 HRESULT VLCMessages::loadTypeInfo(void)
1108 {
1109     HRESULT hr = NOERROR;
1110     if( NULL == _p_typeinfo )
1111     {
1112         ITypeLib *p_typelib;
1113
1114         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1115         if( SUCCEEDED(hr) )
1116         {
1117             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCMessages, &_p_typeinfo);
1118             if( FAILED(hr) )
1119             {
1120                 _p_typeinfo = NULL;
1121             }
1122             p_typelib->Release();
1123         }
1124     }
1125     return hr;
1126 };
1127
1128 STDMETHODIMP VLCMessages::GetTypeInfoCount(UINT* pctInfo)
1129 {
1130     if( NULL == pctInfo )
1131         return E_INVALIDARG;
1132
1133     if( SUCCEEDED(loadTypeInfo()) )
1134         *pctInfo = 1;
1135     else
1136         *pctInfo = 0;
1137
1138     return NOERROR;
1139 };
1140
1141 STDMETHODIMP VLCMessages::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1142 {
1143     if( NULL == ppTInfo )
1144         return E_INVALIDARG;
1145
1146     if( SUCCEEDED(loadTypeInfo()) )
1147     {
1148         _p_typeinfo->AddRef();
1149         *ppTInfo = _p_typeinfo;
1150         return NOERROR;
1151     }
1152     *ppTInfo = NULL;
1153     return E_NOTIMPL;
1154 };
1155
1156 STDMETHODIMP VLCMessages::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1157         UINT cNames, LCID lcid, DISPID* rgDispID)
1158 {
1159     if( SUCCEEDED(loadTypeInfo()) )
1160     {
1161         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1162     }
1163     return E_NOTIMPL;
1164 };
1165
1166 STDMETHODIMP VLCMessages::Invoke(DISPID dispIdMember, REFIID riid,
1167         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1168         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1169 {
1170     if( SUCCEEDED(loadTypeInfo()) )
1171     {
1172         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1173                 pVarResult, pExcepInfo, puArgErr);
1174     }
1175     return E_NOTIMPL;
1176 };
1177
1178 STDMETHODIMP VLCMessages::get__NewEnum(LPUNKNOWN* _NewEnum)
1179 {
1180     if( NULL == _NewEnum )
1181         return E_POINTER;
1182
1183     IVLCMessageIterator* iter = NULL;
1184     iterator(&iter);
1185
1186     *_NewEnum= new VLCEnumIterator<IID_IEnumVARIANT,
1187                        IEnumVARIANT,
1188                        VARIANT,
1189                        VLCMessageSTLIterator>
1190                        (VLCMessageSTLIterator(iter), VLCMessageSTLIterator(NULL));
1191
1192     return *_NewEnum ? S_OK : E_OUTOFMEMORY;
1193 };
1194
1195 STDMETHODIMP VLCMessages::clear()
1196 {
1197     libvlc_log_t *p_log = _p_vlclog->_p_log;
1198     if( p_log )
1199         libvlc_log_clear(p_log);
1200     return NOERROR;
1201 };
1202
1203 STDMETHODIMP VLCMessages::get_count(long* count)
1204 {
1205     if( NULL == count )
1206         return E_POINTER;
1207
1208     libvlc_log_t *p_log = _p_vlclog->_p_log;
1209     *count = libvlc_log_count(p_log);
1210     return S_OK;
1211 };
1212
1213 STDMETHODIMP VLCMessages::iterator(IVLCMessageIterator** iter)
1214 {
1215     if( NULL == iter )
1216         return E_POINTER;
1217
1218     *iter = new VLCMessageIterator(_p_instance, _p_vlclog);
1219
1220     return *iter ? S_OK : E_OUTOFMEMORY;
1221 };
1222
1223 /*******************************************************************************/
1224
1225 VLCMessageIterator::VLCMessageIterator(VLCPlugin *p_instance, VLCLog* p_vlclog ) :
1226     _p_instance(p_instance),
1227     _p_typeinfo(NULL),
1228     _refcount(1),
1229     _p_vlclog(p_vlclog)
1230 {
1231     if( p_vlclog->_p_log )
1232     {
1233         _p_iter = libvlc_log_get_iterator(p_vlclog->_p_log, NULL);
1234     }
1235     else
1236         _p_iter = NULL;
1237 };
1238
1239 VLCMessageIterator::~VLCMessageIterator()
1240 {
1241     if( _p_iter )
1242         libvlc_log_iterator_free(_p_iter);
1243
1244     if( _p_typeinfo )
1245         _p_typeinfo->Release();
1246 };
1247
1248 HRESULT VLCMessageIterator::loadTypeInfo(void)
1249 {
1250     HRESULT hr = NOERROR;
1251     if( NULL == _p_typeinfo )
1252     {
1253         ITypeLib *p_typelib;
1254
1255         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1256         if( SUCCEEDED(hr) )
1257         {
1258             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCMessageIterator, &_p_typeinfo);
1259             if( FAILED(hr) )
1260             {
1261                 _p_typeinfo = NULL;
1262             }
1263             p_typelib->Release();
1264         }
1265     }
1266     return hr;
1267 };
1268
1269 STDMETHODIMP VLCMessageIterator::GetTypeInfoCount(UINT* pctInfo)
1270 {
1271     if( NULL == pctInfo )
1272         return E_INVALIDARG;
1273
1274     if( SUCCEEDED(loadTypeInfo()) )
1275         *pctInfo = 1;
1276     else
1277         *pctInfo = 0;
1278
1279     return NOERROR;
1280 };
1281
1282 STDMETHODIMP VLCMessageIterator::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1283 {
1284     if( NULL == ppTInfo )
1285         return E_INVALIDARG;
1286
1287     if( SUCCEEDED(loadTypeInfo()) )
1288     {
1289         _p_typeinfo->AddRef();
1290         *ppTInfo = _p_typeinfo;
1291         return NOERROR;
1292     }
1293     *ppTInfo = NULL;
1294     return E_NOTIMPL;
1295 };
1296
1297 STDMETHODIMP VLCMessageIterator::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1298         UINT cNames, LCID lcid, DISPID* rgDispID)
1299 {
1300     if( SUCCEEDED(loadTypeInfo()) )
1301     {
1302         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1303     }
1304     return E_NOTIMPL;
1305 };
1306
1307 STDMETHODIMP VLCMessageIterator::Invoke(DISPID dispIdMember, REFIID riid,
1308         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1309         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1310 {
1311     if( SUCCEEDED(loadTypeInfo()) )
1312     {
1313         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1314                 pVarResult, pExcepInfo, puArgErr);
1315     }
1316     return E_NOTIMPL;
1317 };
1318
1319 STDMETHODIMP VLCMessageIterator::get_hasNext(VARIANT_BOOL* hasNext)
1320 {
1321     if( NULL == hasNext )
1322         return E_POINTER;
1323
1324     if( _p_iter &&  _p_vlclog->_p_log )
1325     {
1326         *hasNext = libvlc_log_iterator_has_next(_p_iter) ?
1327                    VARIANT_TRUE : VARIANT_FALSE;
1328     }
1329     else
1330     {
1331         *hasNext = VARIANT_FALSE;
1332     }
1333     return S_OK;
1334 };
1335
1336 STDMETHODIMP VLCMessageIterator::next(IVLCMessage** message)
1337 {
1338     HRESULT hr = S_OK;
1339
1340     if( NULL == message )
1341         return E_POINTER;
1342
1343     if( _p_iter &&  _p_vlclog->_p_log )
1344     {
1345         struct libvlc_log_message_t buffer;
1346
1347         buffer.sizeof_msg = sizeof(buffer);
1348
1349         libvlc_exception_t ex;
1350         libvlc_exception_init(&ex);
1351
1352         libvlc_log_iterator_next(_p_iter, &buffer, &ex);
1353         *message = new VLCMessage(_p_instance, buffer);
1354         if( !message )
1355             hr = E_OUTOFMEMORY;
1356     }
1357     return hr;
1358 };
1359
1360 /*******************************************************************************/
1361
1362 VLCMessage::~VLCMessage()
1363 {
1364     if( _p_typeinfo )
1365         _p_typeinfo->Release();
1366 };
1367
1368 HRESULT VLCMessage::loadTypeInfo(void)
1369 {
1370     HRESULT hr = NOERROR;
1371     if( NULL == _p_typeinfo )
1372     {
1373         ITypeLib *p_typelib;
1374
1375         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1376         if( SUCCEEDED(hr) )
1377         {
1378             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCMessage, &_p_typeinfo);
1379             if( FAILED(hr) )
1380             {
1381                 _p_typeinfo = NULL;
1382             }
1383             p_typelib->Release();
1384         }
1385     }
1386     return hr;
1387 };
1388
1389 STDMETHODIMP VLCMessage::GetTypeInfoCount(UINT* pctInfo)
1390 {
1391     if( NULL == pctInfo )
1392         return E_INVALIDARG;
1393
1394     if( SUCCEEDED(loadTypeInfo()) )
1395         *pctInfo = 1;
1396     else
1397         *pctInfo = 0;
1398
1399     return NOERROR;
1400 };
1401
1402 STDMETHODIMP VLCMessage::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1403 {
1404     if( NULL == ppTInfo )
1405         return E_INVALIDARG;
1406
1407     if( SUCCEEDED(loadTypeInfo()) )
1408     {
1409         _p_typeinfo->AddRef();
1410         *ppTInfo = _p_typeinfo;
1411         return NOERROR;
1412     }
1413     *ppTInfo = NULL;
1414     return E_NOTIMPL;
1415 };
1416
1417 STDMETHODIMP VLCMessage::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1418         UINT cNames, LCID lcid, DISPID* rgDispID)
1419 {
1420     if( SUCCEEDED(loadTypeInfo()) )
1421     {
1422         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1423     }
1424     return E_NOTIMPL;
1425 };
1426
1427 STDMETHODIMP VLCMessage::Invoke(DISPID dispIdMember, REFIID riid,
1428         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1429         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1430 {
1431     if( SUCCEEDED(loadTypeInfo()) )
1432     {
1433         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1434                 pVarResult, pExcepInfo, puArgErr);
1435     }
1436     return E_NOTIMPL;
1437 };
1438
1439 inline const char *msgSeverity(int sev)
1440 {
1441     switch( sev )
1442     {
1443         case 0:
1444             return "info";
1445         case 1:
1446             return "error";
1447         case 2:
1448             return "warning";
1449         default:
1450             return "debug";
1451     }
1452 };
1453
1454 STDMETHODIMP VLCMessage::get__Value(VARIANT* _Value)
1455 {
1456     if( NULL == _Value )
1457         return E_POINTER;
1458
1459     char buffer[256];
1460
1461     snprintf(buffer, sizeof(buffer), "%s %s %s: %s",
1462         _msg.psz_type, _msg.psz_name, msgSeverity(_msg.i_severity), _msg.psz_message);
1463
1464     V_VT(_Value) = VT_BSTR;
1465     V_BSTR(_Value) = BSTRFromCStr(CP_UTF8, buffer);
1466
1467     return S_OK;
1468 };
1469
1470 STDMETHODIMP VLCMessage::get_severity(long* level)
1471 {
1472     if( NULL == level )
1473         return E_POINTER;
1474
1475     *level = _msg.i_severity;
1476
1477     return S_OK;
1478 };
1479
1480 STDMETHODIMP VLCMessage::get_type(BSTR* type)
1481 {
1482     if( NULL == type )
1483         return E_POINTER;
1484
1485     *type = BSTRFromCStr(CP_UTF8, _msg.psz_type);
1486
1487     return NOERROR;
1488 };
1489
1490 STDMETHODIMP VLCMessage::get_name(BSTR* name)
1491 {
1492     if( NULL == name )
1493         return E_POINTER;
1494
1495     *name = BSTRFromCStr(CP_UTF8, _msg.psz_name);
1496
1497     return NOERROR;
1498 };
1499
1500 STDMETHODIMP VLCMessage::get_header(BSTR* header)
1501 {
1502     if( NULL == header )
1503         return E_POINTER;
1504
1505     *header = BSTRFromCStr(CP_UTF8, _msg.psz_header);
1506
1507     return NOERROR;
1508 };
1509
1510 STDMETHODIMP VLCMessage::get_message(BSTR* message)
1511 {
1512     if( NULL == message )
1513         return E_POINTER;
1514
1515     *message = BSTRFromCStr(CP_UTF8, _msg.psz_message);
1516
1517     return NOERROR;
1518 };
1519
1520 /*******************************************************************************/
1521
1522 VLCPlaylistItems::~VLCPlaylistItems()
1523 {
1524     if( _p_typeinfo )
1525         _p_typeinfo->Release();
1526 };
1527
1528 HRESULT VLCPlaylistItems::loadTypeInfo(void)
1529 {
1530     HRESULT hr = NOERROR;
1531     if( NULL == _p_typeinfo )
1532     {
1533         ITypeLib *p_typelib;
1534
1535         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1536         if( SUCCEEDED(hr) )
1537         {
1538             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCPlaylistItems, &_p_typeinfo);
1539             if( FAILED(hr) )
1540             {
1541                 _p_typeinfo = NULL;
1542             }
1543             p_typelib->Release();
1544         }
1545     }
1546     return hr;
1547 };
1548
1549 STDMETHODIMP VLCPlaylistItems::GetTypeInfoCount(UINT* pctInfo)
1550 {
1551     if( NULL == pctInfo )
1552         return E_INVALIDARG;
1553
1554     if( SUCCEEDED(loadTypeInfo()) )
1555         *pctInfo = 1;
1556     else
1557         *pctInfo = 0;
1558
1559     return NOERROR;
1560 };
1561
1562 STDMETHODIMP VLCPlaylistItems::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1563 {
1564     if( NULL == ppTInfo )
1565         return E_INVALIDARG;
1566
1567     if( SUCCEEDED(loadTypeInfo()) )
1568     {
1569         _p_typeinfo->AddRef();
1570         *ppTInfo = _p_typeinfo;
1571         return NOERROR;
1572     }
1573     *ppTInfo = NULL;
1574     return E_NOTIMPL;
1575 };
1576
1577 STDMETHODIMP VLCPlaylistItems::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1578         UINT cNames, LCID lcid, DISPID* rgDispID)
1579 {
1580     if( SUCCEEDED(loadTypeInfo()) )
1581     {
1582         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1583     }
1584     return E_NOTIMPL;
1585 };
1586
1587 STDMETHODIMP VLCPlaylistItems::Invoke(DISPID dispIdMember, REFIID riid,
1588         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1589         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1590 {
1591     if( SUCCEEDED(loadTypeInfo()) )
1592     {
1593         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1594                 pVarResult, pExcepInfo, puArgErr);
1595     }
1596     return E_NOTIMPL;
1597 };
1598
1599 STDMETHODIMP VLCPlaylistItems::get_count(long* count)
1600 {
1601     if( NULL == count )
1602         return E_POINTER;
1603
1604     libvlc_exception_t ex;
1605     libvlc_exception_init(&ex);
1606
1607     *count = _p_instance->playlist_count(&ex);
1608     return exception_bridge(&ex);
1609 };
1610
1611 STDMETHODIMP VLCPlaylistItems::clear()
1612 {
1613     libvlc_exception_t ex;
1614     libvlc_exception_init(&ex);
1615
1616     _p_instance->playlist_clear(&ex);
1617     return exception_bridge(&ex);
1618 };
1619
1620 STDMETHODIMP VLCPlaylistItems::remove(long item)
1621 {
1622     libvlc_instance_t* p_libvlc;
1623     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1624     if( SUCCEEDED(hr) )
1625     {
1626         libvlc_exception_t ex;
1627         libvlc_exception_init(&ex);
1628
1629         _p_instance->playlist_delete_item(item, &ex);
1630         hr = exception_bridge(&ex);
1631     }
1632     return hr;
1633 };
1634
1635 /*******************************************************************************/
1636
1637 VLCPlaylist::~VLCPlaylist()
1638 {
1639     delete _p_vlcplaylistitems;
1640     if( _p_typeinfo )
1641         _p_typeinfo->Release();
1642 };
1643
1644 HRESULT VLCPlaylist::loadTypeInfo(void)
1645 {
1646     HRESULT hr = NOERROR;
1647     if( NULL == _p_typeinfo )
1648     {
1649         ITypeLib *p_typelib;
1650
1651         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1652         if( SUCCEEDED(hr) )
1653         {
1654             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCPlaylist, &_p_typeinfo);
1655             if( FAILED(hr) )
1656             {
1657                 _p_typeinfo = NULL;
1658             }
1659             p_typelib->Release();
1660         }
1661     }
1662     return hr;
1663 };
1664
1665 STDMETHODIMP VLCPlaylist::GetTypeInfoCount(UINT* pctInfo)
1666 {
1667     if( NULL == pctInfo )
1668         return E_INVALIDARG;
1669
1670     if( SUCCEEDED(loadTypeInfo()) )
1671         *pctInfo = 1;
1672     else
1673         *pctInfo = 0;
1674
1675     return NOERROR;
1676 };
1677
1678 STDMETHODIMP VLCPlaylist::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1679 {
1680     if( NULL == ppTInfo )
1681         return E_INVALIDARG;
1682
1683     if( SUCCEEDED(loadTypeInfo()) )
1684     {
1685         _p_typeinfo->AddRef();
1686         *ppTInfo = _p_typeinfo;
1687         return NOERROR;
1688     }
1689     *ppTInfo = NULL;
1690     return E_NOTIMPL;
1691 };
1692
1693 STDMETHODIMP VLCPlaylist::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1694         UINT cNames, LCID lcid, DISPID* rgDispID)
1695 {
1696     if( SUCCEEDED(loadTypeInfo()) )
1697     {
1698         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1699     }
1700     return E_NOTIMPL;
1701 };
1702
1703 STDMETHODIMP VLCPlaylist::Invoke(DISPID dispIdMember, REFIID riid,
1704         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1705         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1706 {
1707     if( SUCCEEDED(loadTypeInfo()) )
1708     {
1709         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1710                 pVarResult, pExcepInfo, puArgErr);
1711     }
1712     return E_NOTIMPL;
1713 };
1714
1715 STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
1716 {
1717     if( NULL == count )
1718         return E_POINTER;
1719
1720     *count = 0;
1721     libvlc_exception_t ex;
1722     libvlc_exception_init(&ex);
1723
1724     *count = _p_instance->playlist_count(&ex);
1725     return exception_bridge(&ex);
1726 };
1727
1728 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
1729 {
1730     if( NULL == isPlaying )
1731         return E_POINTER;
1732
1733     libvlc_media_player_t *p_md;
1734     HRESULT hr = _p_instance->getMD(&p_md);
1735     if( SUCCEEDED(hr) )
1736     {
1737         libvlc_exception_t ex;
1738         libvlc_exception_init(&ex);
1739
1740         *isPlaying = libvlc_media_player_is_playing(p_md, &ex) ?
1741                      VARIANT_TRUE: VARIANT_FALSE;
1742         libvlc_exception_clear(&ex);
1743     }
1744     return hr;
1745 };
1746
1747 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
1748 {
1749     if( NULL == item )
1750         return E_POINTER;
1751
1752     if( 0 == SysStringLen(uri) )
1753         return E_INVALIDARG;
1754
1755     libvlc_instance_t* p_libvlc;
1756     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1757     if( SUCCEEDED(hr) )
1758     {
1759         libvlc_exception_t ex;
1760         libvlc_exception_init(&ex);
1761
1762         char *psz_uri = NULL;
1763         if( SysStringLen(_p_instance->getBaseURL()) > 0 )
1764         {
1765             /*
1766             ** if the MRL a relative URL, we should end up with an absolute URL
1767             */
1768             LPWSTR abs_url = CombineURL(_p_instance->getBaseURL(), uri);
1769             if( NULL != abs_url )
1770             {
1771                 psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
1772                 CoTaskMemFree(abs_url);
1773             }
1774             else
1775             {
1776                 psz_uri = CStrFromBSTR(CP_UTF8, uri);
1777             }
1778         }
1779         else
1780         {
1781             /*
1782             ** baseURL is empty, assume MRL is absolute
1783             */
1784             psz_uri = CStrFromBSTR(CP_UTF8, uri);
1785         }
1786
1787         if( NULL == psz_uri )
1788         {
1789             return E_OUTOFMEMORY;
1790         }
1791
1792         int i_options;
1793         char **ppsz_options;
1794
1795         hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
1796         if( FAILED(hr) )
1797         {
1798             CoTaskMemFree(psz_uri);
1799             return hr;
1800         }
1801
1802         char *psz_name = NULL;
1803         VARIANT v_name;
1804         VariantInit(&v_name);
1805         if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
1806         {
1807             if( SysStringLen(V_BSTR(&v_name)) > 0 )
1808                 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
1809
1810             VariantClear(&v_name);
1811         }
1812
1813         *item = _p_instance->playlist_add_extended_untrusted(psz_uri,
1814                     i_options, const_cast<const char **>(ppsz_options), &ex);
1815
1816         VLCControl::FreeTargetOptions(ppsz_options, i_options);
1817         CoTaskMemFree(psz_uri);
1818         if( psz_name ) /* XXX Do we even need to check? */
1819             CoTaskMemFree(psz_name);
1820         hr = exception_bridge(&ex);
1821     }
1822     return hr;
1823 };
1824
1825 STDMETHODIMP VLCPlaylist::play()
1826 {
1827     libvlc_exception_t ex;
1828     libvlc_exception_init(&ex);
1829
1830     _p_instance->playlist_play(&ex);
1831     return exception_bridge(&ex);
1832 };
1833
1834 STDMETHODIMP VLCPlaylist::playItem(long item)
1835 {
1836     libvlc_exception_t ex;
1837     libvlc_exception_init(&ex);
1838
1839     _p_instance->playlist_play_item(item,&ex);
1840     return exception_bridge(&ex);;
1841 };
1842
1843 STDMETHODIMP VLCPlaylist::togglePause()
1844 {
1845     libvlc_media_player_t* p_md;
1846     HRESULT hr = _p_instance->getMD(&p_md);
1847     if( SUCCEEDED(hr) )
1848     {
1849         libvlc_exception_t ex;
1850         libvlc_exception_init(&ex);
1851
1852         libvlc_media_player_pause(p_md, &ex);
1853         hr = exception_bridge(&ex);;
1854     }
1855     return hr;
1856 };
1857
1858 STDMETHODIMP VLCPlaylist::stop()
1859 {
1860     libvlc_media_player_t *p_md;
1861     HRESULT hr = _p_instance->getMD(&p_md);
1862     if( SUCCEEDED(hr) )
1863     {
1864         libvlc_exception_t ex;
1865         libvlc_exception_init(&ex);
1866
1867         libvlc_media_player_stop(p_md, &ex);
1868         hr = exception_bridge(&ex);;
1869     }
1870     return hr;
1871 };
1872
1873 STDMETHODIMP VLCPlaylist::next()
1874 {
1875     libvlc_exception_t ex;
1876     libvlc_exception_init(&ex);
1877
1878     _p_instance->playlist_next(&ex);
1879     return exception_bridge(&ex);;
1880 };
1881
1882 STDMETHODIMP VLCPlaylist::prev()
1883 {
1884     libvlc_exception_t ex;
1885     libvlc_exception_init(&ex);
1886
1887     _p_instance->playlist_prev(&ex);
1888     return exception_bridge(&ex);;
1889 };
1890
1891 STDMETHODIMP VLCPlaylist::clear()
1892 {
1893     libvlc_exception_t ex;
1894     libvlc_exception_init(&ex);
1895
1896     _p_instance->playlist_clear(&ex);
1897     return exception_bridge(&ex);;
1898 };
1899
1900 STDMETHODIMP VLCPlaylist::removeItem(long item)
1901 {
1902     libvlc_instance_t* p_libvlc;
1903     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1904     if( SUCCEEDED(hr) )
1905     {
1906         libvlc_exception_t ex;
1907         libvlc_exception_init(&ex);
1908
1909         _p_instance->playlist_delete_item(item, &ex);
1910         hr = exception_bridge(&ex);;
1911     }
1912     return hr;
1913 };
1914
1915 STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
1916 {
1917     if( NULL == obj )
1918         return E_POINTER;
1919
1920     *obj = _p_vlcplaylistitems;
1921     if( NULL != _p_vlcplaylistitems )
1922     {
1923         _p_vlcplaylistitems->AddRef();
1924         return NOERROR;
1925     }
1926     return E_OUTOFMEMORY;
1927 };
1928
1929 /*******************************************************************************/
1930
1931 VLCSubtitle::~VLCSubtitle()
1932 {
1933     if( _p_typeinfo )
1934         _p_typeinfo->Release();
1935 };
1936
1937 HRESULT VLCSubtitle::loadTypeInfo(void)
1938 {
1939     HRESULT hr = NOERROR;
1940     if( NULL == _p_typeinfo )
1941     {
1942         ITypeLib *p_typelib;
1943
1944         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1945         if( SUCCEEDED(hr) )
1946         {
1947             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCSubtitle, &_p_typeinfo);
1948             if( FAILED(hr) )
1949             {
1950                 _p_typeinfo = NULL;
1951             }
1952             p_typelib->Release();
1953         }
1954     }
1955     return hr;
1956 };
1957
1958 STDMETHODIMP VLCSubtitle::GetTypeInfoCount(UINT* pctInfo)
1959 {
1960     if( NULL == pctInfo )
1961         return E_INVALIDARG;
1962
1963     if( SUCCEEDED(loadTypeInfo()) )
1964         *pctInfo = 1;
1965     else
1966         *pctInfo = 0;
1967
1968     return NOERROR;
1969 };
1970
1971 STDMETHODIMP VLCSubtitle::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1972 {
1973     if( NULL == ppTInfo )
1974         return E_INVALIDARG;
1975
1976     if( SUCCEEDED(loadTypeInfo()) )
1977     {
1978         _p_typeinfo->AddRef();
1979         *ppTInfo = _p_typeinfo;
1980         return NOERROR;
1981     }
1982     *ppTInfo = NULL;
1983     return E_NOTIMPL;
1984 };
1985
1986 STDMETHODIMP VLCSubtitle::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1987         UINT cNames, LCID lcid, DISPID* rgDispID)
1988 {
1989     if( SUCCEEDED(loadTypeInfo()) )
1990     {
1991         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1992     }
1993     return E_NOTIMPL;
1994 };
1995
1996 STDMETHODIMP VLCSubtitle::Invoke(DISPID dispIdMember, REFIID riid,
1997         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1998         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1999 {
2000     if( SUCCEEDED(loadTypeInfo()) )
2001     {
2002         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
2003                 pVarResult, pExcepInfo, puArgErr);
2004     }
2005     return E_NOTIMPL;
2006 };
2007
2008 STDMETHODIMP VLCSubtitle::get_track(long* spu)
2009 {
2010     if( NULL == spu )
2011         return E_POINTER;
2012
2013     libvlc_media_player_t *p_md;
2014     HRESULT hr = _p_instance->getMD(&p_md);
2015     if( SUCCEEDED(hr) )
2016     {
2017         libvlc_exception_t ex;
2018         libvlc_exception_init(&ex);
2019
2020         *spu = libvlc_video_get_spu(p_md, &ex);
2021         hr = exception_bridge(&ex);
2022     }
2023     return hr;
2024 };
2025
2026 STDMETHODIMP VLCSubtitle::put_track(long spu)
2027 {
2028     libvlc_media_player_t *p_md;
2029     HRESULT hr = _p_instance->getMD(&p_md);
2030     if( SUCCEEDED(hr) )
2031     {
2032         libvlc_exception_t ex;
2033         libvlc_exception_init(&ex);
2034
2035         libvlc_video_set_spu(p_md, spu, &ex);
2036         hr = exception_bridge(&ex);
2037     }
2038     return hr;
2039 };
2040
2041 STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
2042 {
2043     if( NULL == spuNumber )
2044         return E_POINTER;
2045
2046     libvlc_media_player_t *p_md;
2047     HRESULT hr = _p_instance->getMD(&p_md);
2048     if( SUCCEEDED(hr) )
2049     {
2050         libvlc_exception_t ex;
2051         libvlc_exception_init(&ex);
2052         // get the number of video subtitle available and return it
2053         *spuNumber = libvlc_video_get_spu_count(p_md, &ex);
2054         hr = exception_bridge(&ex);
2055     }
2056     return hr;
2057 };
2058
2059
2060 STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
2061 {
2062     if( NULL == name )
2063        return E_POINTER;
2064
2065     libvlc_media_player_t* p_md;
2066     libvlc_exception_t ex;
2067     libvlc_exception_init(&ex);
2068
2069     HRESULT hr = _p_instance->getMD(&p_md);
2070     if( SUCCEEDED(hr) )
2071     {
2072         int i, i_limit;
2073         const char *psz_name;
2074         libvlc_track_description_t *p_spuDesc;
2075
2076         // get subtitles description
2077         p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
2078         hr = exception_bridge(&ex);
2079         if( FAILED(hr) )
2080             return hr;
2081
2082         // get the number of available subtitle
2083         i_limit = libvlc_video_get_spu_count(p_md, &ex);
2084         hr = exception_bridge(&ex);
2085         if( FAILED(hr) )
2086             return hr;
2087
2088         // check if the number given is a good one
2089         if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
2090             return E_FAIL;
2091
2092         // get the good spuDesc
2093         for( i = 0 ; i < nameID ; i++ )
2094         {
2095             p_spuDesc = p_spuDesc->p_next;
2096         }
2097         // get the subtitle name
2098         psz_name = p_spuDesc->psz_name;
2099
2100         // return it
2101         if( psz_name != NULL )
2102         {
2103             *name = BSTRFromCStr(CP_UTF8, psz_name);
2104             return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
2105         }
2106         *name = NULL;
2107         return E_FAIL;
2108     }
2109     return hr;
2110 };
2111
2112 /*******************************************************************************/
2113
2114 VLCVideo::~VLCVideo()
2115 {
2116     delete _p_vlcmarquee;
2117     if( _p_typeinfo )
2118         _p_typeinfo->Release();
2119 };
2120
2121 HRESULT VLCVideo::loadTypeInfo(void)
2122 {
2123     HRESULT hr = NOERROR;
2124     if( NULL == _p_typeinfo )
2125     {
2126         ITypeLib *p_typelib;
2127
2128         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
2129         if( SUCCEEDED(hr) )
2130         {
2131             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCVideo, &_p_typeinfo);
2132             if( FAILED(hr) )
2133             {
2134                 _p_typeinfo = NULL;
2135             }
2136             p_typelib->Release();
2137         }
2138     }
2139     return hr;
2140 };
2141
2142 STDMETHODIMP VLCVideo::GetTypeInfoCount(UINT* pctInfo)
2143 {
2144     if( NULL == pctInfo )
2145         return E_INVALIDARG;
2146
2147     if( SUCCEEDED(loadTypeInfo()) )
2148         *pctInfo = 1;
2149     else
2150         *pctInfo = 0;
2151
2152     return NOERROR;
2153 };
2154
2155 STDMETHODIMP VLCVideo::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
2156 {
2157     if( NULL == ppTInfo )
2158         return E_INVALIDARG;
2159
2160     if( SUCCEEDED(loadTypeInfo()) )
2161     {
2162         _p_typeinfo->AddRef();
2163         *ppTInfo = _p_typeinfo;
2164         return NOERROR;
2165     }
2166     *ppTInfo = NULL;
2167     return E_NOTIMPL;
2168 };
2169
2170 STDMETHODIMP VLCVideo::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
2171         UINT cNames, LCID lcid, DISPID* rgDispID)
2172 {
2173     if( SUCCEEDED(loadTypeInfo()) )
2174     {
2175         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
2176     }
2177     return E_NOTIMPL;
2178 };
2179
2180 STDMETHODIMP VLCVideo::Invoke(DISPID dispIdMember, REFIID riid,
2181         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
2182         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
2183 {
2184     if( SUCCEEDED(loadTypeInfo()) )
2185     {
2186         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
2187                 pVarResult, pExcepInfo, puArgErr);
2188     }
2189     return E_NOTIMPL;
2190 };
2191
2192 STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
2193 {
2194     if( NULL == fullscreen )
2195         return E_POINTER;
2196
2197     libvlc_media_player_t *p_md;
2198     HRESULT hr = _p_instance->getMD(&p_md);
2199     if( SUCCEEDED(hr) )
2200     {
2201         libvlc_exception_t ex;
2202         libvlc_exception_init(&ex);
2203
2204         *fullscreen = libvlc_get_fullscreen(p_md, &ex) ?
2205                       VARIANT_TRUE : VARIANT_FALSE;
2206         hr = exception_bridge(&ex);
2207     }
2208     return hr;
2209 };
2210
2211 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
2212 {
2213     libvlc_media_player_t *p_md;
2214     HRESULT hr = _p_instance->getMD(&p_md);
2215     if( SUCCEEDED(hr) )
2216     {
2217         libvlc_exception_t ex;
2218         libvlc_exception_init(&ex);
2219
2220         libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen, &ex);
2221         hr = exception_bridge(&ex);
2222     }
2223     return hr;
2224 };
2225
2226 STDMETHODIMP VLCVideo::get_width(long* width)
2227 {
2228     if( NULL == width )
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         *width = libvlc_video_get_width(p_md, &ex);
2239         hr = exception_bridge(&ex);
2240     }
2241     return hr;
2242 };
2243
2244 STDMETHODIMP VLCVideo::get_height(long* height)
2245 {
2246     if( NULL == height )
2247         return E_POINTER;
2248
2249     libvlc_media_player_t *p_md;
2250     HRESULT hr = _p_instance->getMD(&p_md);
2251     if( SUCCEEDED(hr) )
2252     {
2253         libvlc_exception_t ex;
2254         libvlc_exception_init(&ex);
2255
2256         *height = libvlc_video_get_height(p_md, &ex);
2257         hr = exception_bridge(&ex);
2258     }
2259     return hr;
2260 };
2261
2262 STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
2263 {
2264     if( NULL == aspect )
2265         return E_POINTER;
2266
2267     libvlc_media_player_t *p_md;
2268     HRESULT hr = _p_instance->getMD(&p_md);
2269     if( SUCCEEDED(hr) )
2270     {
2271         libvlc_exception_t ex;
2272         libvlc_exception_init(&ex);
2273
2274         char *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
2275
2276         hr = exception_bridge(&ex);
2277         if( SUCCEEDED(hr) && NULL != psz_aspect )
2278         {
2279             *aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
2280             if( NULL == *aspect )
2281                 hr = E_OUTOFMEMORY;
2282         } else if( NULL == psz_aspect) hr = E_OUTOFMEMORY; // strdup("") failed
2283         free( psz_aspect );
2284     }
2285     return hr;
2286 };
2287
2288 STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
2289 {
2290     if( NULL == aspect )
2291         return E_POINTER;
2292
2293     libvlc_media_player_t *p_md;
2294     HRESULT hr = _p_instance->getMD(&p_md);
2295     if( SUCCEEDED(hr) )
2296     {
2297         libvlc_exception_t ex;
2298         libvlc_exception_init(&ex);
2299
2300         char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
2301         if( NULL == psz_aspect )
2302         {
2303             return E_OUTOFMEMORY;
2304         }
2305
2306         libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
2307
2308         CoTaskMemFree(psz_aspect);
2309         hr = exception_bridge(&ex);
2310     }
2311     return hr;
2312 };
2313
2314 STDMETHODIMP VLCVideo::get_subtitle(long* spu)
2315 {
2316     if( NULL == spu )
2317         return E_POINTER;
2318
2319     libvlc_media_player_t *p_md;
2320     HRESULT hr = _p_instance->getMD(&p_md);
2321     if( SUCCEEDED(hr) )
2322     {
2323         libvlc_exception_t ex;
2324         libvlc_exception_init(&ex);
2325
2326         *spu = libvlc_video_get_spu(p_md, &ex);
2327         hr = exception_bridge(&ex);
2328     }
2329     return hr;
2330 };
2331
2332 STDMETHODIMP VLCVideo::put_subtitle(long spu)
2333 {
2334     libvlc_media_player_t *p_md;
2335     HRESULT hr = _p_instance->getMD(&p_md);
2336     if( SUCCEEDED(hr) )
2337     {
2338         libvlc_exception_t ex;
2339         libvlc_exception_init(&ex);
2340
2341         libvlc_video_set_spu(p_md, spu, &ex);
2342         hr = exception_bridge(&ex);
2343     }
2344     return hr;
2345 };
2346
2347 STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
2348 {
2349     if( NULL == geometry )
2350         return E_POINTER;
2351
2352     libvlc_media_player_t *p_md;
2353     HRESULT hr = _p_instance->getMD(&p_md);
2354     if( SUCCEEDED(hr) )
2355     {
2356         libvlc_exception_t ex;
2357         libvlc_exception_init(&ex);
2358
2359         char *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
2360
2361         hr = exception_bridge(&ex);
2362         if( SUCCEEDED(&ex) && NULL != psz_geometry )
2363         {
2364             *geometry = BSTRFromCStr(CP_UTF8, psz_geometry);
2365             if( NULL == geometry ) hr = E_OUTOFMEMORY;
2366         } else if( NULL == psz_geometry ) hr = E_OUTOFMEMORY;
2367         free( psz_geometry );
2368     }
2369     return hr;
2370 };
2371
2372 STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
2373 {
2374     if( NULL == geometry )
2375         return E_POINTER;
2376
2377     if( 0 == SysStringLen(geometry) )
2378         return E_INVALIDARG;
2379
2380     libvlc_media_player_t *p_md;
2381     HRESULT hr = _p_instance->getMD(&p_md);
2382     if( SUCCEEDED(hr) )
2383     {
2384         libvlc_exception_t ex;
2385         libvlc_exception_init(&ex);
2386
2387         char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
2388         if( NULL == psz_geometry )
2389         {
2390             return E_OUTOFMEMORY;
2391         }
2392
2393         libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
2394
2395         CoTaskMemFree(psz_geometry);
2396         hr = exception_bridge(&ex);
2397     }
2398     return hr;
2399 };
2400
2401 STDMETHODIMP VLCVideo::get_teletext(long* page)
2402 {
2403     if( NULL == page )
2404         return E_POINTER;
2405
2406     libvlc_media_player_t *p_md;
2407     HRESULT hr = _p_instance->getMD(&p_md);
2408     if( SUCCEEDED(hr) )
2409     {
2410         libvlc_exception_t ex;
2411         libvlc_exception_init(&ex);
2412
2413         *page = libvlc_video_get_teletext(p_md, &ex);
2414         hr = exception_bridge(&ex);
2415     }
2416     return hr;
2417 };
2418
2419 STDMETHODIMP VLCVideo::put_teletext(long page)
2420 {
2421     libvlc_media_player_t *p_md;
2422     HRESULT hr = _p_instance->getMD(&p_md);
2423     if( SUCCEEDED(hr) )
2424     {
2425         libvlc_exception_t ex;
2426         libvlc_exception_init(&ex);
2427
2428         libvlc_video_set_teletext(p_md, page, &ex);
2429         hr = exception_bridge(&ex);
2430     }
2431     return hr;
2432 };
2433
2434 STDMETHODIMP VLCVideo::deinterlaceDisable()
2435 {
2436     libvlc_media_player_t *p_md;
2437     HRESULT hr = _p_instance->getMD(&p_md);
2438     if( SUCCEEDED(hr) )
2439     {
2440         libvlc_exception_t ex;
2441         libvlc_exception_init(&ex);
2442
2443         libvlc_video_set_deinterlace(p_md, 0, "", &ex);
2444         hr = exception_bridge(&ex);
2445     }
2446     return hr;
2447 };
2448
2449 STDMETHODIMP VLCVideo::deinterlaceEnable(BSTR mode)
2450 {
2451     libvlc_media_player_t *p_md;
2452     HRESULT hr = _p_instance->getMD(&p_md);
2453     if( SUCCEEDED(hr) )
2454     {
2455         libvlc_exception_t ex;
2456         libvlc_exception_init(&ex);
2457         /* get deinterlace mode from the user */
2458         char *psz_mode = CStrFromBSTR(CP_UTF8, mode);
2459         /* enable deinterlace filter if possible */
2460         libvlc_video_set_deinterlace(p_md, 1, psz_mode, &ex);
2461         hr = exception_bridge(&ex);
2462         CoTaskMemFree(psz_mode);
2463     }
2464     return hr;
2465 };
2466
2467 STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
2468 {
2469     if( NULL == picture )
2470         return E_POINTER;
2471
2472     libvlc_media_player_t *p_md;
2473     HRESULT hr = _p_instance->getMD(&p_md);
2474     if( SUCCEEDED(hr) )
2475     {
2476         libvlc_exception_t ex;
2477         libvlc_exception_init(&ex);
2478
2479         static int uniqueId = 0;
2480         TCHAR path[MAX_PATH+1];
2481
2482         int pathlen = GetTempPath(MAX_PATH-24, path);
2483         if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
2484             return E_FAIL;
2485
2486         /* check temp directory path by openning it */
2487         {
2488             HANDLE dirHandle = CreateFile(path, GENERIC_READ,
2489                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2490                        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
2491             if( INVALID_HANDLE_VALUE == dirHandle )
2492             {
2493                 _p_instance->setErrorInfo(IID_IVLCVideo,
2494                         "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
2495                 return E_FAIL;
2496             }
2497             else
2498             {
2499                 BY_HANDLE_FILE_INFORMATION bhfi;
2500                 BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
2501                 CloseHandle(dirHandle);
2502                 if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
2503                 {
2504                     _p_instance->setErrorInfo(IID_IVLCVideo,
2505                             "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
2506                     return E_FAIL;
2507                 }
2508             }
2509         }
2510
2511         TCHAR filepath[MAX_PATH+1];
2512
2513         _stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
2514                  path, GetCurrentProcessId(), ++uniqueId);
2515
2516 #ifdef _UNICODE
2517         /* reuse path storage for UTF8 string */
2518         char *psz_filepath = (char *)path;
2519         WCHAR* wpath = filepath;
2520 #else
2521         char *psz_filepath = path;
2522         /* first convert to unicode using current code page */
2523         WCHAR wpath[MAX_PATH+1];
2524         if( 0 == MultiByteToWideChar(CP_ACP, 0, filepath, -1,
2525                                      wpath, sizeof(wpath)/sizeof(WCHAR)) )
2526             return E_FAIL;
2527 #endif
2528         /* convert to UTF8 */
2529         pathlen = WideCharToMultiByte(CP_UTF8, 0, wpath, -1,
2530                                       psz_filepath, sizeof(path), NULL, NULL);
2531         // fail if path is 0 or too short (i.e pathlen is the same as
2532         // storage size)
2533
2534         if( (0 == pathlen) || (sizeof(path) == pathlen) )
2535             return E_FAIL;
2536
2537         /* take snapshot into file */
2538         libvlc_video_take_snapshot(p_md, psz_filepath, 0, 0, &ex);
2539         hr = exception_bridge(&ex);
2540         if( SUCCEEDED(hr) )
2541         {
2542             /* open snapshot file */
2543             HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP, 0, 0,
2544                                        LR_CREATEDIBSECTION|LR_LOADFROMFILE);
2545             if( snapPic )
2546             {
2547                 PICTDESC snapDesc;
2548
2549                 snapDesc.cbSizeofstruct = sizeof(PICTDESC);
2550                 snapDesc.picType        = PICTYPE_BITMAP;
2551                 snapDesc.bmp.hbitmap    = (HBITMAP)snapPic;
2552                 snapDesc.bmp.hpal       = NULL;
2553
2554                 hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp,
2555                                               TRUE, (LPVOID*)picture);
2556                 if( FAILED(hr) )
2557                 {
2558                     *picture = NULL;
2559                     DeleteObject(snapPic);
2560                 }
2561             }
2562             DeleteFile(filepath);
2563         }
2564     }
2565     return hr;
2566 };
2567
2568 STDMETHODIMP VLCVideo::toggleFullscreen()
2569 {
2570     libvlc_media_player_t *p_md;
2571     HRESULT hr = _p_instance->getMD(&p_md);
2572     if( SUCCEEDED(hr) )
2573     {
2574         libvlc_exception_t ex;
2575         libvlc_exception_init(&ex);
2576
2577         libvlc_toggle_fullscreen(p_md, &ex);
2578         hr = exception_bridge(&ex);
2579     }
2580     return hr;
2581 };
2582
2583 STDMETHODIMP VLCVideo::toggleTeletext()
2584 {
2585     libvlc_media_player_t *p_md;
2586     HRESULT hr = _p_instance->getMD(&p_md);
2587     if( SUCCEEDED(hr) )
2588     {
2589         libvlc_exception_t ex;
2590         libvlc_exception_init(&ex);
2591
2592         libvlc_toggle_teletext(p_md, &ex);
2593         hr = exception_bridge(&ex);
2594     }
2595     return hr;
2596 };
2597
2598 STDMETHODIMP VLCVideo::get_marquee(IVLCMarquee** obj)
2599 {
2600     if( NULL == obj )
2601         return E_POINTER;
2602
2603     *obj = _p_vlcmarquee;
2604     if( NULL != _p_vlcmarquee )
2605     {
2606         _p_vlcmarquee->AddRef();
2607         return NOERROR;
2608     }
2609     return E_OUTOFMEMORY;
2610 };
2611
2612 /*******************************************************************************/
2613
2614 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
2615     _p_instance(p_instance),
2616     _p_typeinfo(NULL),
2617     _p_vlcaudio(NULL),
2618     _p_vlcinput(NULL),
2619     _p_vlcplaylist(NULL),
2620     _p_vlcsubtitle(NULL),
2621     _p_vlcvideo(NULL)
2622 {
2623     _p_vlcaudio     = new VLCAudio(p_instance);
2624     _p_vlcinput     = new VLCInput(p_instance);
2625     _p_vlclog       = new VLCLog(p_instance);
2626     _p_vlcplaylist  = new VLCPlaylist(p_instance);
2627     _p_vlcsubtitle  = new VLCSubtitle(p_instance);
2628     _p_vlcvideo     = new VLCVideo(p_instance);
2629 };
2630
2631 VLCControl2::~VLCControl2()
2632 {
2633     delete _p_vlcvideo;
2634     delete _p_vlcsubtitle;
2635     delete _p_vlcplaylist;
2636     delete _p_vlclog;
2637     delete _p_vlcinput;
2638     delete _p_vlcaudio;
2639     if( _p_typeinfo )
2640         _p_typeinfo->Release();
2641 };
2642
2643 HRESULT VLCControl2::loadTypeInfo(void)
2644 {
2645     HRESULT hr = NOERROR;
2646     if( NULL == _p_typeinfo )
2647     {
2648         ITypeLib *p_typelib;
2649
2650         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
2651         if( SUCCEEDED(hr) )
2652         {
2653             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
2654             if( FAILED(hr) )
2655             {
2656                 _p_typeinfo = NULL;
2657             }
2658             p_typelib->Release();
2659         }
2660     }
2661     return hr;
2662 };
2663
2664 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
2665 {
2666     if( NULL == pctInfo )
2667         return E_INVALIDARG;
2668
2669     if( SUCCEEDED(loadTypeInfo()) )
2670         *pctInfo = 1;
2671     else
2672         *pctInfo = 0;
2673
2674     return NOERROR;
2675 };
2676
2677 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
2678 {
2679     if( NULL == ppTInfo )
2680         return E_INVALIDARG;
2681
2682     if( SUCCEEDED(loadTypeInfo()) )
2683     {
2684         _p_typeinfo->AddRef();
2685         *ppTInfo = _p_typeinfo;
2686         return NOERROR;
2687     }
2688     *ppTInfo = NULL;
2689     return E_NOTIMPL;
2690 };
2691
2692 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
2693         UINT cNames, LCID lcid, DISPID* rgDispID)
2694 {
2695     if( SUCCEEDED(loadTypeInfo()) )
2696     {
2697         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
2698     }
2699     return E_NOTIMPL;
2700 };
2701
2702 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
2703         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
2704         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
2705 {
2706     if( SUCCEEDED(loadTypeInfo()) )
2707     {
2708         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
2709                 pVarResult, pExcepInfo, puArgErr);
2710     }
2711     return E_NOTIMPL;
2712 };
2713
2714 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
2715 {
2716     if( NULL == autoloop )
2717         return E_POINTER;
2718
2719     *autoloop = _p_instance->getAutoLoop() ? VARIANT_TRUE: VARIANT_FALSE;
2720     return S_OK;
2721 };
2722
2723 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
2724 {
2725     _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
2726     return S_OK;
2727 };
2728
2729 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
2730 {
2731     if( NULL == autoplay )
2732         return E_POINTER;
2733
2734     *autoplay = _p_instance->getAutoPlay() ? VARIANT_TRUE: VARIANT_FALSE;
2735     return S_OK;
2736 };
2737
2738 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
2739 {
2740     _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
2741     return S_OK;
2742 };
2743
2744 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
2745 {
2746     if( NULL == url )
2747         return E_POINTER;
2748
2749     *url = SysAllocStringLen(_p_instance->getBaseURL(),
2750                 SysStringLen(_p_instance->getBaseURL()));
2751     return NOERROR;
2752 };
2753
2754 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
2755 {
2756     _p_instance->setBaseURL(mrl);
2757
2758     return S_OK;
2759 };
2760
2761 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
2762 {
2763     if( NULL == mrl )
2764         return E_POINTER;
2765
2766     *mrl = SysAllocStringLen(_p_instance->getMRL(),
2767                 SysStringLen(_p_instance->getMRL()));
2768     return NOERROR;
2769 };
2770
2771 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
2772 {
2773     _p_instance->setMRL(mrl);
2774
2775     return S_OK;
2776 };
2777
2778
2779 STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
2780 {
2781     if( NULL == visible )
2782         return E_POINTER;
2783
2784     /*
2785      * Note to developers
2786      *
2787      * Returning the _b_toolbar is closer to the method specification.
2788      * But returning True when toolbar is not implemented so not displayed
2789      * could be bad for ActiveX users which rely on this value to show their
2790      * own toolbar if not provided by the ActiveX.
2791      *
2792      * This is the reason why FALSE is returned, until toolbar get implemented.
2793      */
2794
2795     /* DISABLED for now */
2796     //  *visible = _p_instance->getShowToolbar() ? VARIANT_TRUE: VARIANT_FALSE;
2797
2798     *visible = VARIANT_FALSE;
2799
2800     return S_OK;
2801 };
2802
2803 STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
2804 {
2805     _p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
2806     return S_OK;
2807 };
2808
2809
2810 STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
2811 {
2812     if( NULL == seconds )
2813         return E_POINTER;
2814
2815     *seconds = _p_instance->getStartTime();
2816
2817     return S_OK;
2818 };
2819
2820 STDMETHODIMP VLCControl2::put_StartTime(long seconds)
2821 {
2822     _p_instance->setStartTime(seconds);
2823
2824     return NOERROR;
2825 };
2826
2827 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
2828 {
2829     if( NULL == version )
2830         return E_POINTER;
2831
2832     const char *versionStr = libvlc_get_version();
2833     if( NULL != versionStr )
2834     {
2835         *version = BSTRFromCStr(CP_UTF8, versionStr);
2836
2837         return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
2838     }
2839     *version = NULL;
2840     return E_FAIL;
2841 };
2842
2843 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
2844 {
2845     if( NULL == isVisible )
2846         return E_POINTER;
2847
2848     *isVisible = _p_instance->getVisible() ? VARIANT_TRUE : VARIANT_FALSE;
2849
2850     return NOERROR;
2851 };
2852
2853 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
2854 {
2855     _p_instance->setVisible(isVisible != VARIANT_FALSE);
2856
2857     return NOERROR;
2858 };
2859
2860 STDMETHODIMP VLCControl2::get_Volume(long *volume)
2861 {
2862     if( NULL == volume )
2863         return E_POINTER;
2864
2865     *volume  = _p_instance->getVolume();
2866     return NOERROR;
2867 };
2868
2869 STDMETHODIMP VLCControl2::put_Volume(long volume)
2870 {
2871     _p_instance->setVolume(volume);
2872     return NOERROR;
2873 };
2874
2875 STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
2876 {
2877     if( NULL == backcolor )
2878         return E_POINTER;
2879
2880     *backcolor  = _p_instance->getBackColor();
2881     return NOERROR;
2882 };
2883
2884 STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
2885 {
2886     _p_instance->setBackColor(backcolor);
2887     return NOERROR;
2888 };
2889
2890 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
2891 {
2892     if( NULL == obj )
2893         return E_POINTER;
2894
2895     *obj = _p_vlcaudio;
2896     if( NULL != _p_vlcaudio )
2897     {
2898         _p_vlcaudio->AddRef();
2899         return NOERROR;
2900     }
2901     return E_OUTOFMEMORY;
2902 };
2903
2904 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
2905 {
2906     if( NULL == obj )
2907         return E_POINTER;
2908
2909     *obj = _p_vlcinput;
2910     if( NULL != _p_vlcinput )
2911     {
2912         _p_vlcinput->AddRef();
2913         return NOERROR;
2914     }
2915     return E_OUTOFMEMORY;
2916 };
2917
2918 STDMETHODIMP VLCControl2::get_log(IVLCLog** obj)
2919 {
2920     if( NULL == obj )
2921         return E_POINTER;
2922
2923     *obj = _p_vlclog;
2924     if( NULL != _p_vlclog )
2925     {
2926         _p_vlclog->AddRef();
2927         return NOERROR;
2928     }
2929     return E_OUTOFMEMORY;
2930 };
2931
2932 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
2933 {
2934     if( NULL == obj )
2935         return E_POINTER;
2936
2937     *obj = _p_vlcplaylist;
2938     if( NULL != _p_vlcplaylist )
2939     {
2940         _p_vlcplaylist->AddRef();
2941         return NOERROR;
2942     }
2943     return E_OUTOFMEMORY;
2944 };
2945
2946 STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
2947 {
2948     if( NULL == obj )
2949         return E_POINTER;
2950
2951     *obj = _p_vlcsubtitle;
2952     if( NULL != _p_vlcsubtitle )
2953     {
2954         _p_vlcsubtitle->AddRef();
2955         return NOERROR;
2956     }
2957     return E_OUTOFMEMORY;
2958 };
2959
2960 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
2961 {
2962     if( NULL == obj )
2963         return E_POINTER;
2964
2965     *obj = _p_vlcvideo;
2966     if( NULL != _p_vlcvideo )
2967     {
2968         _p_vlcvideo->AddRef();
2969         return NOERROR;
2970     }
2971     return E_OUTOFMEMORY;
2972 };