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