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