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