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