]> git.sesse.net Git - vlc/blob - projects/activex/vlccontrol2.cpp
Fix potential segfault.
[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         *count = libvlc_playlist_items_count(p_libvlc, &ex);
1530         if( libvlc_exception_raised(&ex) )
1531         {
1532             _p_instance->setErrorInfo(IID_IVLCPlaylistItems,
1533                          libvlc_exception_get_message(&ex));
1534             libvlc_exception_clear(&ex);
1535             return E_FAIL;
1536         }
1537         return NOERROR;
1538     }
1539     return hr;
1540 };
1541
1542 STDMETHODIMP VLCPlaylistItems::clear()
1543 {
1544     libvlc_instance_t* p_libvlc;
1545     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1546     if( SUCCEEDED(hr) )
1547     {
1548         libvlc_exception_t ex;
1549         libvlc_exception_init(&ex);
1550
1551         libvlc_playlist_clear(p_libvlc, &ex);
1552         if( libvlc_exception_raised(&ex) )
1553         {
1554             _p_instance->setErrorInfo(IID_IVLCPlaylistItems,
1555                          libvlc_exception_get_message(&ex));
1556             libvlc_exception_clear(&ex);
1557             return E_FAIL;
1558         }
1559         return NOERROR;
1560     }
1561     return hr;
1562 };
1563
1564 STDMETHODIMP VLCPlaylistItems::remove(long item)
1565 {
1566     libvlc_instance_t* p_libvlc;
1567     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1568     if( SUCCEEDED(hr) )
1569     {
1570         libvlc_exception_t ex;
1571         libvlc_exception_init(&ex);
1572
1573         libvlc_playlist_delete_item(p_libvlc, item, &ex);
1574         if( libvlc_exception_raised(&ex) )
1575         {
1576             _p_instance->setErrorInfo(IID_IVLCPlaylistItems,
1577                          libvlc_exception_get_message(&ex));
1578             libvlc_exception_clear(&ex);
1579             return E_FAIL;
1580         }
1581         return NOERROR;
1582     }
1583     return hr;
1584 };
1585
1586 /*******************************************************************************/
1587
1588 VLCPlaylist::~VLCPlaylist()
1589 {
1590     delete _p_vlcplaylistitems;
1591     if( _p_typeinfo )
1592         _p_typeinfo->Release();
1593 };
1594
1595 HRESULT VLCPlaylist::loadTypeInfo(void)
1596 {
1597     HRESULT hr = NOERROR;
1598     if( NULL == _p_typeinfo )
1599     {
1600         ITypeLib *p_typelib;
1601
1602         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1603         if( SUCCEEDED(hr) )
1604         {
1605             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCPlaylist, &_p_typeinfo);
1606             if( FAILED(hr) )
1607             {
1608                 _p_typeinfo = NULL;
1609             }
1610             p_typelib->Release();
1611         }
1612     }
1613     return hr;
1614 };
1615
1616 STDMETHODIMP VLCPlaylist::GetTypeInfoCount(UINT* pctInfo)
1617 {
1618     if( NULL == pctInfo )
1619         return E_INVALIDARG;
1620
1621     if( SUCCEEDED(loadTypeInfo()) )
1622         *pctInfo = 1;
1623     else
1624         *pctInfo = 0;
1625
1626     return NOERROR;
1627 };
1628
1629 STDMETHODIMP VLCPlaylist::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1630 {
1631     if( NULL == ppTInfo )
1632         return E_INVALIDARG;
1633
1634     if( SUCCEEDED(loadTypeInfo()) )
1635     {
1636         _p_typeinfo->AddRef();
1637         *ppTInfo = _p_typeinfo;
1638         return NOERROR;
1639     }
1640     *ppTInfo = NULL;
1641     return E_NOTIMPL;
1642 };
1643
1644 STDMETHODIMP VLCPlaylist::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1645         UINT cNames, LCID lcid, DISPID* rgDispID)
1646 {
1647     if( SUCCEEDED(loadTypeInfo()) )
1648     {
1649         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1650     }
1651     return E_NOTIMPL;
1652 };
1653
1654 STDMETHODIMP VLCPlaylist::Invoke(DISPID dispIdMember, REFIID riid,
1655         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1656         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1657 {
1658     if( SUCCEEDED(loadTypeInfo()) )
1659     {
1660         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1661                 pVarResult, pExcepInfo, puArgErr);
1662     }
1663     return E_NOTIMPL;
1664 };
1665
1666 STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
1667 {
1668     if( NULL == count )
1669         return E_POINTER;
1670
1671     *count = 0;
1672     libvlc_instance_t* p_libvlc;
1673     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1674     if( SUCCEEDED(hr) )
1675     {
1676         libvlc_exception_t ex;
1677         libvlc_exception_init(&ex);
1678
1679         *count = libvlc_playlist_items_count(p_libvlc, &ex);
1680         if( libvlc_exception_raised(&ex) )
1681         {
1682             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1683                          libvlc_exception_get_message(&ex));
1684             libvlc_exception_clear(&ex);
1685             return E_FAIL;
1686         }
1687         return NOERROR;
1688     }
1689     return hr;
1690 };
1691
1692 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
1693 {
1694     if( NULL == isPlaying )
1695         return E_POINTER;
1696
1697     libvlc_instance_t* p_libvlc;
1698     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1699     if( SUCCEEDED(hr) )
1700     {
1701         libvlc_exception_t ex;
1702         libvlc_exception_init(&ex);
1703
1704         *isPlaying = libvlc_playlist_isplaying(p_libvlc, &ex) ?
1705                                     VARIANT_TRUE: VARIANT_FALSE;
1706         if( libvlc_exception_raised(&ex) )
1707         {
1708             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1709                          libvlc_exception_get_message(&ex));
1710             libvlc_exception_clear(&ex);
1711             return E_FAIL;
1712         }
1713         return NOERROR;
1714     }
1715     return hr;
1716 };
1717
1718 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
1719 {
1720     if( NULL == item )
1721         return E_POINTER;
1722
1723     if( 0 == SysStringLen(uri) )
1724         return E_INVALIDARG;
1725
1726     libvlc_instance_t* p_libvlc;
1727     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1728     if( SUCCEEDED(hr) )
1729     {
1730         libvlc_exception_t ex;
1731         libvlc_exception_init(&ex);
1732
1733         char *psz_uri = NULL;
1734         if( SysStringLen(_p_instance->getBaseURL()) > 0 )
1735         {
1736             /*
1737             ** if the MRL a relative URL, we should end up with an absolute URL
1738             */
1739             LPWSTR abs_url = CombineURL(_p_instance->getBaseURL(), uri);
1740             if( NULL != abs_url )
1741             {
1742                 psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
1743                 CoTaskMemFree(abs_url);
1744             }
1745             else
1746             {
1747                 psz_uri = CStrFromBSTR(CP_UTF8, uri);
1748             }
1749         }
1750         else
1751         {
1752             /*
1753             ** baseURL is empty, assume MRL is absolute
1754             */
1755             psz_uri = CStrFromBSTR(CP_UTF8, uri);
1756         }
1757
1758         if( NULL == psz_uri )
1759         {
1760             return E_OUTOFMEMORY;
1761         }
1762
1763         int i_options;
1764         char **ppsz_options;
1765
1766         hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
1767         if( FAILED(hr) )
1768         {
1769             CoTaskMemFree(psz_uri);
1770             return hr;
1771         }
1772
1773         char *psz_name = NULL;
1774         VARIANT v_name;
1775         VariantInit(&v_name);
1776         if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
1777         {
1778             if( SysStringLen(V_BSTR(&v_name)) > 0 )
1779                 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
1780
1781             VariantClear(&v_name);
1782         }
1783
1784         *item = libvlc_playlist_add_extended(p_libvlc,
1785                     psz_uri,
1786                     psz_name,
1787                     i_options,
1788                     const_cast<const char **>(ppsz_options),
1789                     &ex);
1790
1791         VLCControl::FreeTargetOptions(ppsz_options, i_options);
1792         CoTaskMemFree(psz_uri);
1793         if( psz_name )
1794             CoTaskMemFree(psz_name);
1795         if( libvlc_exception_raised(&ex) )
1796         {
1797             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1798                 libvlc_exception_get_message(&ex));
1799             libvlc_exception_clear(&ex);
1800             return E_FAIL;
1801         }
1802         return NOERROR;
1803     }
1804     return hr;
1805 };
1806
1807 STDMETHODIMP VLCPlaylist::play()
1808 {
1809     libvlc_instance_t* p_libvlc;
1810     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1811     if( SUCCEEDED(hr) )
1812     {
1813         libvlc_exception_t ex;
1814         libvlc_exception_init(&ex);
1815
1816         libvlc_playlist_play(p_libvlc, -1, 0, NULL, &ex);
1817         if( libvlc_exception_raised(&ex) )
1818         {
1819             libvlc_exception_clear(&ex);
1820             return E_FAIL;
1821         }
1822         return NOERROR;
1823     }
1824     return hr;
1825 };
1826
1827 STDMETHODIMP VLCPlaylist::playItem(long item)
1828 {
1829     libvlc_instance_t* p_libvlc;
1830     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1831     if( SUCCEEDED(hr) )
1832     {
1833         libvlc_exception_t ex;
1834         libvlc_exception_init(&ex);
1835
1836         libvlc_playlist_play(p_libvlc, item, 0, NULL, &ex);
1837         if( libvlc_exception_raised(&ex) )
1838         {
1839             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1840                 libvlc_exception_get_message(&ex));
1841             libvlc_exception_clear(&ex);
1842             return E_FAIL;
1843         }
1844         return NOERROR;
1845     }
1846     return hr;
1847 };
1848
1849 STDMETHODIMP VLCPlaylist::togglePause()
1850 {
1851     libvlc_instance_t* p_libvlc;
1852     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1853     if( SUCCEEDED(hr) )
1854     {
1855         libvlc_exception_t ex;
1856         libvlc_exception_init(&ex);
1857
1858         libvlc_playlist_pause(p_libvlc, &ex);
1859         if( libvlc_exception_raised(&ex) )
1860         {
1861             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1862                 libvlc_exception_get_message(&ex));
1863             libvlc_exception_clear(&ex);
1864             return E_FAIL;
1865         }
1866         return NOERROR;
1867     }
1868     return hr;
1869 };
1870
1871 STDMETHODIMP VLCPlaylist::stop()
1872 {
1873     libvlc_instance_t* p_libvlc;
1874     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1875     if( SUCCEEDED(hr) )
1876     {
1877         libvlc_exception_t ex;
1878         libvlc_exception_init(&ex);
1879
1880         libvlc_playlist_stop(p_libvlc, &ex);
1881         if( libvlc_exception_raised(&ex) )
1882         {
1883             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1884                 libvlc_exception_get_message(&ex));
1885             libvlc_exception_clear(&ex);
1886             return E_FAIL;
1887         }
1888         return NOERROR;
1889     }
1890     return hr;
1891 };
1892
1893 STDMETHODIMP VLCPlaylist::next()
1894 {
1895     libvlc_instance_t* p_libvlc;
1896     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1897     if( SUCCEEDED(hr) )
1898     {
1899         libvlc_exception_t ex;
1900         libvlc_exception_init(&ex);
1901
1902         libvlc_playlist_next(p_libvlc, &ex);
1903         if( libvlc_exception_raised(&ex) )
1904         {
1905             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1906                 libvlc_exception_get_message(&ex));
1907             libvlc_exception_clear(&ex);
1908             return E_FAIL;
1909         }
1910         return NOERROR;
1911     }
1912     return hr;
1913 };
1914
1915 STDMETHODIMP VLCPlaylist::prev()
1916 {
1917     libvlc_instance_t* p_libvlc;
1918     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1919     if( SUCCEEDED(hr) )
1920     {
1921         libvlc_exception_t ex;
1922         libvlc_exception_init(&ex);
1923
1924         libvlc_playlist_prev(p_libvlc, &ex);
1925         if( libvlc_exception_raised(&ex) )
1926         {
1927             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1928                 libvlc_exception_get_message(&ex));
1929             libvlc_exception_clear(&ex);
1930             return E_FAIL;
1931         }
1932         return NOERROR;
1933     }
1934     return hr;
1935 };
1936
1937 STDMETHODIMP VLCPlaylist::clear()
1938 {
1939     libvlc_instance_t* p_libvlc;
1940     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1941     if( SUCCEEDED(hr) )
1942     {
1943         libvlc_exception_t ex;
1944         libvlc_exception_init(&ex);
1945
1946         libvlc_playlist_clear(p_libvlc, &ex);
1947         if( libvlc_exception_raised(&ex) )
1948         {
1949             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1950                 libvlc_exception_get_message(&ex));
1951             libvlc_exception_clear(&ex);
1952             return E_FAIL;
1953         }
1954         return NOERROR;
1955     }
1956     return hr;
1957 };
1958
1959 STDMETHODIMP VLCPlaylist::removeItem(long item)
1960 {
1961     libvlc_instance_t* p_libvlc;
1962     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1963     if( SUCCEEDED(hr) )
1964     {
1965         libvlc_exception_t ex;
1966         libvlc_exception_init(&ex);
1967
1968         libvlc_playlist_delete_item(p_libvlc, item, &ex);
1969         if( libvlc_exception_raised(&ex) )
1970         {
1971             _p_instance->setErrorInfo(IID_IVLCPlaylist,
1972                 libvlc_exception_get_message(&ex));
1973             libvlc_exception_clear(&ex);
1974             return E_FAIL;
1975         }
1976         return NOERROR;
1977     }
1978     return hr;
1979 };
1980
1981 STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
1982 {
1983     if( NULL == obj )
1984         return E_POINTER;
1985
1986     *obj = _p_vlcplaylistitems;
1987     if( NULL != _p_vlcplaylistitems )
1988     {
1989         _p_vlcplaylistitems->AddRef();
1990         return NOERROR;
1991     }
1992     return E_OUTOFMEMORY;
1993 };
1994
1995 /*******************************************************************************/
1996
1997 VLCVideo::~VLCVideo()
1998 {
1999     if( _p_typeinfo )
2000         _p_typeinfo->Release();
2001 };
2002
2003 HRESULT VLCVideo::loadTypeInfo(void)
2004 {
2005     HRESULT hr = NOERROR;
2006     if( NULL == _p_typeinfo )
2007     {
2008         ITypeLib *p_typelib;
2009
2010         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
2011         if( SUCCEEDED(hr) )
2012         {
2013             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCVideo, &_p_typeinfo);
2014             if( FAILED(hr) )
2015             {
2016                 _p_typeinfo = NULL;
2017             }
2018             p_typelib->Release();
2019         }
2020     }
2021     return hr;
2022 };
2023
2024 STDMETHODIMP VLCVideo::GetTypeInfoCount(UINT* pctInfo)
2025 {
2026     if( NULL == pctInfo )
2027         return E_INVALIDARG;
2028
2029     if( SUCCEEDED(loadTypeInfo()) )
2030         *pctInfo = 1;
2031     else
2032         *pctInfo = 0;
2033
2034     return NOERROR;
2035 };
2036
2037 STDMETHODIMP VLCVideo::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
2038 {
2039     if( NULL == ppTInfo )
2040         return E_INVALIDARG;
2041
2042     if( SUCCEEDED(loadTypeInfo()) )
2043     {
2044         _p_typeinfo->AddRef();
2045         *ppTInfo = _p_typeinfo;
2046         return NOERROR;
2047     }
2048     *ppTInfo = NULL;
2049     return E_NOTIMPL;
2050 };
2051
2052 STDMETHODIMP VLCVideo::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
2053         UINT cNames, LCID lcid, DISPID* rgDispID)
2054 {
2055     if( SUCCEEDED(loadTypeInfo()) )
2056     {
2057         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
2058     }
2059     return E_NOTIMPL;
2060 };
2061
2062 STDMETHODIMP VLCVideo::Invoke(DISPID dispIdMember, REFIID riid,
2063         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
2064         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
2065 {
2066     if( SUCCEEDED(loadTypeInfo()) )
2067     {
2068         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
2069                 pVarResult, pExcepInfo, puArgErr);
2070     }
2071     return E_NOTIMPL;
2072 };
2073
2074 STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
2075 {
2076     if( NULL == fullscreen )
2077         return E_POINTER;
2078
2079     libvlc_instance_t* p_libvlc;
2080     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2081     if( SUCCEEDED(hr) )
2082     {
2083         libvlc_exception_t ex;
2084         libvlc_exception_init(&ex);
2085
2086         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2087         if( ! libvlc_exception_raised(&ex) )
2088         {
2089             *fullscreen = libvlc_get_fullscreen(p_md, &ex) ? VARIANT_TRUE : VARIANT_FALSE;
2090             libvlc_media_player_release(p_md);
2091             if( ! libvlc_exception_raised(&ex) )
2092             {
2093                 return NOERROR;
2094             }
2095         }
2096         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2097         libvlc_exception_clear(&ex);
2098         return E_FAIL;
2099     }
2100     return hr;
2101 };
2102
2103 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
2104 {
2105     libvlc_instance_t* p_libvlc;
2106     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2107     if( SUCCEEDED(hr) )
2108     {
2109         libvlc_exception_t ex;
2110         libvlc_exception_init(&ex);
2111
2112         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2113         if( ! libvlc_exception_raised(&ex) )
2114         {
2115             libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen, &ex);
2116             libvlc_media_player_release(p_md);
2117             if( ! libvlc_exception_raised(&ex) )
2118             {
2119                 return NOERROR;
2120             }
2121         }
2122         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2123         libvlc_exception_clear(&ex);
2124         return E_FAIL;
2125     }
2126     return hr;
2127 };
2128
2129 STDMETHODIMP VLCVideo::get_width(long* width)
2130 {
2131     if( NULL == width )
2132         return E_POINTER;
2133
2134     libvlc_instance_t* p_libvlc;
2135     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2136     if( SUCCEEDED(hr) )
2137     {
2138         libvlc_exception_t ex;
2139         libvlc_exception_init(&ex);
2140
2141         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2142         if( ! libvlc_exception_raised(&ex) )
2143         {
2144             *width = libvlc_video_get_width(p_md, &ex);
2145             libvlc_media_player_release(p_md);
2146             if( ! libvlc_exception_raised(&ex) )
2147             {
2148                 return NOERROR;
2149             }
2150         }
2151         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2152         libvlc_exception_clear(&ex);
2153         return E_FAIL;
2154     }
2155     return hr;
2156 };
2157
2158 STDMETHODIMP VLCVideo::get_height(long* height)
2159 {
2160     if( NULL == height )
2161         return E_POINTER;
2162
2163     libvlc_instance_t* p_libvlc;
2164     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2165     if( SUCCEEDED(hr) )
2166     {
2167         libvlc_exception_t ex;
2168         libvlc_exception_init(&ex);
2169
2170         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2171         if( ! libvlc_exception_raised(&ex) )
2172         {
2173             *height = libvlc_video_get_height(p_md, &ex);
2174             libvlc_media_player_release(p_md);
2175             if( ! libvlc_exception_raised(&ex) )
2176             {
2177                 return NOERROR;
2178             }
2179         }
2180         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2181         libvlc_exception_clear(&ex);
2182         return E_FAIL;
2183     }
2184     return hr;
2185 };
2186
2187 STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
2188 {
2189     if( NULL == aspect )
2190         return E_POINTER;
2191
2192     libvlc_instance_t* p_libvlc;
2193     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2194     if( SUCCEEDED(hr) )
2195     {
2196         libvlc_exception_t ex;
2197         libvlc_exception_init(&ex);
2198
2199         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2200         if( ! libvlc_exception_raised(&ex) )
2201         {
2202             char *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
2203
2204             libvlc_media_player_release(p_md);
2205             if( ! libvlc_exception_raised(&ex) )
2206             {
2207                 if( NULL == psz_aspect )
2208                     return E_OUTOFMEMORY;
2209
2210                 *aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
2211                 free( psz_aspect );
2212                 psz_aspect = NULL;
2213                 return (NULL == *aspect) ? E_OUTOFMEMORY : NOERROR;
2214             }
2215             free( psz_aspect );
2216             psz_aspect = NULL;
2217         }
2218         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2219         libvlc_exception_clear(&ex);
2220         return E_FAIL;
2221     }
2222     return hr;
2223 };
2224
2225 STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
2226 {
2227     if( NULL == aspect )
2228         return E_POINTER;
2229
2230     if( 0 == SysStringLen(aspect) )
2231         return E_INVALIDARG;
2232
2233     libvlc_instance_t* p_libvlc;
2234     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2235     if( SUCCEEDED(hr) )
2236     {
2237         libvlc_exception_t ex;
2238         libvlc_exception_init(&ex);
2239
2240         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2241         if( ! libvlc_exception_raised(&ex) )
2242         {
2243             char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
2244             if( NULL == psz_aspect )
2245             {
2246                 return E_OUTOFMEMORY;
2247             }
2248
2249             libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
2250
2251             CoTaskMemFree(psz_aspect);
2252             libvlc_media_player_release(p_md);
2253             if( libvlc_exception_raised(&ex) )
2254             {
2255                 _p_instance->setErrorInfo(IID_IVLCVideo,
2256                     libvlc_exception_get_message(&ex));
2257                 libvlc_exception_clear(&ex);
2258                 return E_FAIL;
2259             }
2260         }
2261         return NOERROR;
2262     }
2263     return hr;
2264 };
2265
2266 STDMETHODIMP VLCVideo::get_subtitle(long* spu)
2267 {
2268     if( NULL == spu )
2269         return E_POINTER;
2270
2271     libvlc_instance_t* p_libvlc;
2272     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2273     if( SUCCEEDED(hr) )
2274     {
2275         libvlc_exception_t ex;
2276         libvlc_exception_init(&ex);
2277
2278         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2279         if( ! libvlc_exception_raised(&ex) )
2280         {
2281             *spu = libvlc_video_get_spu(p_md, &ex);
2282             libvlc_media_player_release(p_md);
2283             if( ! libvlc_exception_raised(&ex) )
2284             {
2285                 return NOERROR;
2286             }
2287         }
2288         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2289         libvlc_exception_clear(&ex);
2290         return E_FAIL;
2291     }
2292     return hr;
2293 };
2294
2295 STDMETHODIMP VLCVideo::put_subtitle(long spu)
2296 {
2297     libvlc_instance_t* p_libvlc;
2298     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2299     if( SUCCEEDED(hr) )
2300     {
2301         libvlc_exception_t ex;
2302         libvlc_exception_init(&ex);
2303
2304         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2305         libvlc_video_set_spu(p_md, spu, &ex);
2306         libvlc_media_player_release(p_md);
2307         if( libvlc_exception_raised(&ex) )
2308         {
2309             _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2310             libvlc_exception_clear(&ex);
2311             return E_FAIL;
2312         }
2313         return NOERROR;
2314     }
2315     return hr;
2316 };
2317
2318 STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
2319 {
2320     if( NULL == geometry )
2321         return E_POINTER;
2322
2323     libvlc_instance_t* p_libvlc;
2324     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2325     if( SUCCEEDED(hr) )
2326     {
2327         libvlc_exception_t ex;
2328         libvlc_exception_init(&ex);
2329
2330         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2331         if( ! libvlc_exception_raised(&ex) )
2332         {
2333             char *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
2334
2335             libvlc_media_player_release(p_md);
2336             if( ! libvlc_exception_raised(&ex) )
2337             {
2338                 if( NULL == psz_geometry )
2339                     return E_OUTOFMEMORY;
2340
2341                 *geometry = BSTRFromCStr(CP_UTF8, psz_geometry);
2342                 free( psz_geometry );
2343                 psz_geometry = NULL;
2344                 return (NULL == geometry) ? E_OUTOFMEMORY : NOERROR;
2345             }
2346             free( psz_geometry );
2347             psz_geometry = NULL;
2348         }
2349         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2350         libvlc_exception_clear(&ex);
2351         return E_FAIL;
2352     }
2353     return hr;
2354 };
2355
2356 STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
2357 {
2358     if( NULL == geometry )
2359         return E_POINTER;
2360
2361     if( 0 == SysStringLen(geometry) )
2362         return E_INVALIDARG;
2363
2364     libvlc_instance_t* p_libvlc;
2365     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2366     if( SUCCEEDED(hr) )
2367     {
2368         libvlc_exception_t ex;
2369         libvlc_exception_init(&ex);
2370
2371         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2372         if( ! libvlc_exception_raised(&ex) )
2373         {
2374             char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
2375             if( NULL == psz_geometry )
2376             {
2377                 return E_OUTOFMEMORY;
2378             }
2379
2380             libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
2381
2382             CoTaskMemFree(psz_geometry);
2383             libvlc_media_player_release(p_md);
2384             if( libvlc_exception_raised(&ex) )
2385             {
2386                 _p_instance->setErrorInfo(IID_IVLCVideo,
2387                     libvlc_exception_get_message(&ex));
2388                 libvlc_exception_clear(&ex);
2389                 return E_FAIL;
2390             }
2391         }
2392         return NOERROR;
2393     }
2394     return hr;
2395 };
2396
2397 STDMETHODIMP VLCVideo::get_teletext(long* page)
2398 {
2399     if( NULL == page )
2400         return E_POINTER;
2401
2402     libvlc_instance_t* p_libvlc;
2403     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2404     if( SUCCEEDED(hr) )
2405     {
2406         libvlc_exception_t ex;
2407         libvlc_exception_init(&ex);
2408
2409         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2410         if( ! libvlc_exception_raised(&ex) )
2411         {
2412             *page = libvlc_video_get_teletext(p_md, &ex);
2413             libvlc_media_player_release(p_md);
2414             if( ! libvlc_exception_raised(&ex) )
2415             {
2416                 return NOERROR;
2417             }
2418         }
2419         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2420         libvlc_exception_clear(&ex);
2421         return E_FAIL;
2422     }
2423     return hr;
2424 };
2425
2426 STDMETHODIMP VLCVideo::put_teletext(long page)
2427 {
2428     libvlc_instance_t* p_libvlc;
2429     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2430     if( SUCCEEDED(hr) )
2431     {
2432         libvlc_exception_t ex;
2433         libvlc_exception_init(&ex);
2434
2435         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2436         libvlc_video_set_teletext(p_md, page, &ex);
2437         libvlc_media_player_release(p_md);
2438         if( libvlc_exception_raised(&ex) )
2439         {
2440             _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2441             libvlc_exception_clear(&ex);
2442             return E_FAIL;
2443         }
2444         return NOERROR;
2445     }
2446     return hr;
2447 };
2448
2449 STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
2450 {
2451     if( NULL == picture )
2452         return E_POINTER;
2453
2454     libvlc_instance_t* p_libvlc;
2455     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2456     if( SUCCEEDED(hr) )
2457     {
2458         libvlc_exception_t ex;
2459         libvlc_exception_init(&ex);
2460
2461         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2462         if( ! libvlc_exception_raised(&ex) )
2463         {
2464             static int uniqueId = 0;
2465             TCHAR path[MAX_PATH+1];
2466
2467             int pathlen = GetTempPath(MAX_PATH-24, path);
2468             if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
2469                 return E_FAIL;
2470
2471             /* check temp directory path by openning it */
2472             {
2473                 HANDLE dirHandle = CreateFile(path,
2474                                               GENERIC_READ,
2475                                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2476                                               NULL,
2477                                               OPEN_EXISTING,
2478                                               FILE_FLAG_BACKUP_SEMANTICS, NULL);
2479                 if( INVALID_HANDLE_VALUE == dirHandle )
2480                 {
2481                     _p_instance->setErrorInfo(IID_IVLCVideo,
2482                             "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
2483                     return E_FAIL;
2484                 }
2485                 else
2486                 {
2487                     BY_HANDLE_FILE_INFORMATION bhfi;
2488                     BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
2489                     CloseHandle(dirHandle);
2490                     if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
2491                     {
2492                         _p_instance->setErrorInfo(IID_IVLCVideo,
2493                                 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
2494                         return E_FAIL;
2495                     }
2496                 }
2497             }
2498
2499             TCHAR filepath[MAX_PATH+1];
2500
2501             _stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
2502                      path, GetCurrentProcessId(), ++uniqueId);
2503
2504 #ifdef _UNICODE
2505             /* reuse path storage for UTF8 string */
2506             char *psz_filepath = (char *)path;
2507             WCHAR* wpath = filepath;
2508 #else
2509             char *psz_filepath = path;
2510             /* first convert to unicode using current code page */
2511             WCHAR wpath[MAX_PATH+1];
2512             if( 0 == MultiByteToWideChar(CP_ACP, 0, filepath, -1, wpath, sizeof(wpath)/sizeof(WCHAR)) )
2513                 return E_FAIL;
2514 #endif
2515             /* convert to UTF8 */
2516             pathlen = WideCharToMultiByte(CP_UTF8, 0, wpath, -1, psz_filepath, sizeof(path), NULL, NULL);
2517             // fail if path is 0 or too short (i.e pathlen is the same as storage size)
2518             if( (0 == pathlen) || (sizeof(path) == pathlen) )
2519                 return E_FAIL;
2520
2521             /* take snapshot into file */
2522             libvlc_video_take_snapshot(p_md, psz_filepath, 0, 0, &ex);
2523             libvlc_media_player_release(p_md);
2524             if( ! libvlc_exception_raised(&ex) )
2525             {
2526                 hr = E_FAIL;
2527                 /* open snapshot file */
2528                 HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP,0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
2529                 if( snapPic )
2530                 {
2531                     PICTDESC snapDesc;
2532
2533                     snapDesc.cbSizeofstruct = sizeof(PICTDESC);
2534                     snapDesc.picType        = PICTYPE_BITMAP;
2535                     snapDesc.bmp.hbitmap    = (HBITMAP)snapPic;
2536                     snapDesc.bmp.hpal       = NULL;
2537
2538                     hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp, TRUE, (LPVOID*)picture);
2539                     if( FAILED(hr) )
2540                     {
2541                         *picture = NULL;
2542                         DeleteObject(snapPic);
2543                     }
2544                 }
2545                 DeleteFile(filepath);
2546                 return hr;
2547             }
2548         }
2549         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2550         libvlc_exception_clear(&ex);
2551         return E_FAIL;
2552     }
2553     return hr;
2554 };
2555
2556 STDMETHODIMP VLCVideo::toggleFullscreen()
2557 {
2558     libvlc_instance_t* p_libvlc;
2559     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2560     if( SUCCEEDED(hr) )
2561     {
2562         libvlc_exception_t ex;
2563         libvlc_exception_init(&ex);
2564
2565         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2566         if( ! libvlc_exception_raised(&ex) )
2567         {
2568             libvlc_toggle_fullscreen(p_md, &ex);
2569             libvlc_media_player_release(p_md);
2570             if( ! libvlc_exception_raised(&ex) )
2571             {
2572                 return NOERROR;
2573             }
2574         }
2575         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2576         libvlc_exception_clear(&ex);
2577         return E_FAIL;
2578     }
2579     return hr;
2580 };
2581
2582 STDMETHODIMP VLCVideo::toggleTeletext()
2583 {
2584     libvlc_instance_t* p_libvlc;
2585     HRESULT hr = _p_instance->getVLC(&p_libvlc);
2586     if( SUCCEEDED(hr) )
2587     {
2588         libvlc_exception_t ex;
2589         libvlc_exception_init(&ex);
2590
2591         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
2592         if( ! libvlc_exception_raised(&ex) )
2593         {
2594             libvlc_toggle_teletext(p_md, &ex);
2595             libvlc_media_player_release(p_md);
2596             if( ! libvlc_exception_raised(&ex) )
2597             {
2598                 return NOERROR;
2599             }
2600         }
2601         _p_instance->setErrorInfo(IID_IVLCVideo, libvlc_exception_get_message(&ex));
2602         libvlc_exception_clear(&ex);
2603         return E_FAIL;
2604     }
2605     return hr;
2606 };
2607
2608 /*******************************************************************************/
2609
2610 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
2611     _p_instance(p_instance),
2612     _p_typeinfo(NULL),
2613     _p_vlcaudio(NULL),
2614     _p_vlcinput(NULL),
2615     _p_vlcplaylist(NULL),
2616     _p_vlcvideo(NULL)
2617 {
2618     _p_vlcaudio     = new VLCAudio(p_instance);
2619     _p_vlcinput     = new VLCInput(p_instance);
2620     _p_vlclog       = new VLCLog(p_instance);
2621     _p_vlcplaylist  = new VLCPlaylist(p_instance);
2622     _p_vlcvideo     = new VLCVideo(p_instance);
2623 };
2624
2625 VLCControl2::~VLCControl2()
2626 {
2627     delete _p_vlcvideo;
2628     delete _p_vlcplaylist;
2629     delete _p_vlclog;
2630     delete _p_vlcinput;
2631     delete _p_vlcaudio;
2632     if( _p_typeinfo )
2633         _p_typeinfo->Release();
2634 };
2635
2636 HRESULT VLCControl2::loadTypeInfo(void)
2637 {
2638     HRESULT hr = NOERROR;
2639     if( NULL == _p_typeinfo )
2640     {
2641         ITypeLib *p_typelib;
2642
2643         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
2644         if( SUCCEEDED(hr) )
2645         {
2646             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
2647             if( FAILED(hr) )
2648             {
2649                 _p_typeinfo = NULL;
2650             }
2651             p_typelib->Release();
2652         }
2653     }
2654     return hr;
2655 };
2656
2657 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
2658 {
2659     if( NULL == pctInfo )
2660         return E_INVALIDARG;
2661
2662     if( SUCCEEDED(loadTypeInfo()) )
2663         *pctInfo = 1;
2664     else
2665         *pctInfo = 0;
2666
2667     return NOERROR;
2668 };
2669
2670 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
2671 {
2672     if( NULL == ppTInfo )
2673         return E_INVALIDARG;
2674
2675     if( SUCCEEDED(loadTypeInfo()) )
2676     {
2677         _p_typeinfo->AddRef();
2678         *ppTInfo = _p_typeinfo;
2679         return NOERROR;
2680     }
2681     *ppTInfo = NULL;
2682     return E_NOTIMPL;
2683 };
2684
2685 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
2686         UINT cNames, LCID lcid, DISPID* rgDispID)
2687 {
2688     if( SUCCEEDED(loadTypeInfo()) )
2689     {
2690         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
2691     }
2692     return E_NOTIMPL;
2693 };
2694
2695 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
2696         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
2697         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
2698 {
2699     if( SUCCEEDED(loadTypeInfo()) )
2700     {
2701         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
2702                 pVarResult, pExcepInfo, puArgErr);
2703     }
2704     return E_NOTIMPL;
2705 };
2706
2707 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
2708 {
2709     if( NULL == autoloop )
2710         return E_POINTER;
2711
2712     *autoloop = _p_instance->getAutoLoop() ? VARIANT_TRUE: VARIANT_FALSE;
2713     return S_OK;
2714 };
2715
2716 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
2717 {
2718     _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
2719     return S_OK;
2720 };
2721
2722 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
2723 {
2724     if( NULL == autoplay )
2725         return E_POINTER;
2726
2727     *autoplay = _p_instance->getAutoPlay() ? VARIANT_TRUE: VARIANT_FALSE;
2728     return S_OK;
2729 };
2730
2731 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
2732 {
2733     _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
2734     return S_OK;
2735 };
2736
2737 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
2738 {
2739     if( NULL == url )
2740         return E_POINTER;
2741
2742     *url = SysAllocStringLen(_p_instance->getBaseURL(),
2743                 SysStringLen(_p_instance->getBaseURL()));
2744     return NOERROR;
2745 };
2746
2747 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
2748 {
2749     _p_instance->setBaseURL(mrl);
2750
2751     return S_OK;
2752 };
2753
2754 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
2755 {
2756     if( NULL == mrl )
2757         return E_POINTER;
2758
2759     *mrl = SysAllocStringLen(_p_instance->getMRL(),
2760                 SysStringLen(_p_instance->getMRL()));
2761     return NOERROR;
2762 };
2763
2764 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
2765 {
2766     _p_instance->setMRL(mrl);
2767
2768     return S_OK;
2769 };
2770
2771
2772 STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
2773 {
2774     if( NULL == visible )
2775         return E_POINTER;
2776
2777     /*
2778      * Note to developpers
2779      *
2780      * Returning the _b_toolbar is closer to the method specification.
2781      * But returning True when toolbar is not implemented so not displayed
2782      * could be bad for ActiveX users which rely on this value to show their
2783      * own toolbar if not provided by the ActiveX.
2784      *
2785      * This is the reason why FALSE is returned, until toolbar get implemented.
2786      */
2787
2788     /* DISABLED for now */
2789     //  *visible = _p_instance->getShowToolbar() ? VARIANT_TRUE: VARIANT_FALSE;
2790
2791     *visible = VARIANT_FALSE;
2792
2793     return S_OK;
2794 };
2795
2796 STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
2797 {
2798     _p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
2799     return S_OK;
2800 };
2801
2802
2803 STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
2804 {
2805     if( NULL == seconds )
2806         return E_POINTER;
2807
2808     *seconds = _p_instance->getStartTime();
2809
2810     return S_OK;
2811 };
2812
2813 STDMETHODIMP VLCControl2::put_StartTime(long seconds)
2814 {
2815     _p_instance->setStartTime(seconds);
2816
2817     return NOERROR;
2818 };
2819
2820 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
2821 {
2822     if( NULL == version )
2823         return E_POINTER;
2824
2825     const char *versionStr = libvlc_get_version();
2826     if( NULL != versionStr )
2827     {
2828         *version = BSTRFromCStr(CP_UTF8, versionStr);
2829
2830         return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
2831     }
2832     *version = NULL;
2833     return E_FAIL;
2834 };
2835
2836 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
2837 {
2838     if( NULL == isVisible )
2839         return E_POINTER;
2840
2841     *isVisible = _p_instance->getVisible() ? VARIANT_TRUE : VARIANT_FALSE;
2842
2843     return NOERROR;
2844 };
2845
2846 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
2847 {
2848     _p_instance->setVisible(isVisible != VARIANT_FALSE);
2849
2850     return NOERROR;
2851 };
2852
2853 STDMETHODIMP VLCControl2::get_Volume(long *volume)
2854 {
2855     if( NULL == volume )
2856         return E_POINTER;
2857
2858     *volume  = _p_instance->getVolume();
2859     return NOERROR;
2860 };
2861
2862 STDMETHODIMP VLCControl2::put_Volume(long volume)
2863 {
2864     _p_instance->setVolume(volume);
2865     return NOERROR;
2866 };
2867
2868 STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
2869 {
2870     if( NULL == backcolor )
2871         return E_POINTER;
2872
2873     *backcolor  = _p_instance->getBackColor();
2874     return NOERROR;
2875 };
2876
2877 STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
2878 {
2879     _p_instance->setBackColor(backcolor);
2880     return NOERROR;
2881 };
2882
2883 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
2884 {
2885     if( NULL == obj )
2886         return E_POINTER;
2887
2888     *obj = _p_vlcaudio;
2889     if( NULL != _p_vlcaudio )
2890     {
2891         _p_vlcaudio->AddRef();
2892         return NOERROR;
2893     }
2894     return E_OUTOFMEMORY;
2895 };
2896
2897 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
2898 {
2899     if( NULL == obj )
2900         return E_POINTER;
2901
2902     *obj = _p_vlcinput;
2903     if( NULL != _p_vlcinput )
2904     {
2905         _p_vlcinput->AddRef();
2906         return NOERROR;
2907     }
2908     return E_OUTOFMEMORY;
2909 };
2910
2911 STDMETHODIMP VLCControl2::get_log(IVLCLog** obj)
2912 {
2913     if( NULL == obj )
2914         return E_POINTER;
2915
2916     *obj = _p_vlclog;
2917     if( NULL != _p_vlclog )
2918     {
2919         _p_vlclog->AddRef();
2920         return NOERROR;
2921     }
2922     return E_OUTOFMEMORY;
2923 };
2924
2925 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
2926 {
2927     if( NULL == obj )
2928         return E_POINTER;
2929
2930     *obj = _p_vlcplaylist;
2931     if( NULL != _p_vlcplaylist )
2932     {
2933         _p_vlcplaylist->AddRef();
2934         return NOERROR;
2935     }
2936     return E_OUTOFMEMORY;
2937 };
2938
2939 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
2940 {
2941     if( NULL == obj )
2942         return E_POINTER;
2943
2944     *obj = _p_vlcvideo;
2945     if( NULL != _p_vlcvideo )
2946     {
2947         _p_vlcvideo->AddRef();
2948         return NOERROR;
2949     }
2950     return E_OUTOFMEMORY;
2951 };