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