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