c9aa5e2d013d1f707fb7443af7940f88ad1e432e
[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             libvlc_exception_clear(&ex);
124             return E_FAIL;
125         }
126         return NOERROR;
127     }
128     return hr;
129 };
130
131 STDMETHODIMP VLCAudio::put_mute(VARIANT_BOOL mute)
132 {
133     libvlc_instance_t* p_libvlc;
134     HRESULT hr = _p_instance->getVLC(&p_libvlc);
135     if( SUCCEEDED(hr) )
136     {
137         libvlc_exception_t ex;
138         libvlc_exception_init(&ex);
139
140         libvlc_audio_set_mute(p_libvlc, VARIANT_FALSE != mute, &ex);
141         if( libvlc_exception_raised(&ex) )
142         {
143             libvlc_exception_clear(&ex);
144             return E_FAIL;
145         }
146         return NOERROR;
147     }
148     return hr;
149 };
150
151 STDMETHODIMP VLCAudio::get_volume(int* volume)
152 {
153     if( NULL == volume )
154         return E_POINTER;
155
156     libvlc_instance_t* p_libvlc;
157     HRESULT hr = _p_instance->getVLC(&p_libvlc);
158     if( SUCCEEDED(hr) )
159     {
160         libvlc_exception_t ex;
161         libvlc_exception_init(&ex);
162
163         *volume = libvlc_audio_get_volume(p_libvlc, &ex);
164         if( libvlc_exception_raised(&ex) )
165         {
166             libvlc_exception_clear(&ex);
167             return E_FAIL;
168         }
169         return NOERROR;
170     }
171     return hr;
172 };
173
174 STDMETHODIMP VLCAudio::put_volume(int volume)
175 {
176     libvlc_instance_t* p_libvlc;
177     HRESULT hr = _p_instance->getVLC(&p_libvlc);
178     if( SUCCEEDED(hr) )
179     {
180         libvlc_exception_t ex;
181         libvlc_exception_init(&ex);
182
183         libvlc_audio_set_volume(p_libvlc, volume, &ex);
184         if( libvlc_exception_raised(&ex) )
185         {
186             libvlc_exception_clear(&ex);
187             return E_FAIL;
188         }
189         return NOERROR;
190     }
191     return hr;
192 };
193
194 STDMETHODIMP VLCAudio::toggleMute()
195 {
196     libvlc_instance_t* p_libvlc;
197     HRESULT hr = _p_instance->getVLC(&p_libvlc);
198     if( SUCCEEDED(hr) )
199     {
200         libvlc_exception_t ex;
201         libvlc_exception_init(&ex);
202
203         libvlc_audio_toggle_mute(p_libvlc, &ex);
204         if( libvlc_exception_raised(&ex) )
205         {
206             libvlc_exception_clear(&ex);
207             return E_FAIL;
208         }
209         return NOERROR;
210     }
211     return hr;
212 };
213
214 /*******************************************************************************/
215
216 VLCInput::~VLCInput()
217 {
218     if( _p_typeinfo )
219         _p_typeinfo->Release();
220 };
221
222 HRESULT VLCInput::loadTypeInfo(void)
223 {
224     HRESULT hr = NOERROR;
225     if( NULL == _p_typeinfo )
226     {
227         ITypeLib *p_typelib;
228
229         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
230         if( SUCCEEDED(hr) )
231         {
232             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCInput, &_p_typeinfo);
233             if( FAILED(hr) )
234             {
235                 _p_typeinfo = NULL;
236             }
237             p_typelib->Release();
238         }
239     }
240     return hr;
241 };
242
243 STDMETHODIMP VLCInput::GetTypeInfoCount(UINT* pctInfo)
244 {
245     if( NULL == pctInfo )
246         return E_INVALIDARG;
247
248     if( SUCCEEDED(loadTypeInfo()) )
249         *pctInfo = 1;
250     else
251         *pctInfo = 0;
252
253     return NOERROR;
254 };
255
256 STDMETHODIMP VLCInput::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
257 {
258     if( NULL == ppTInfo )
259         return E_INVALIDARG;
260
261     if( SUCCEEDED(loadTypeInfo()) )
262     {
263         _p_typeinfo->AddRef();
264         *ppTInfo = _p_typeinfo;
265         return NOERROR;
266     }
267     *ppTInfo = NULL;
268     return E_NOTIMPL;
269 };
270
271 STDMETHODIMP VLCInput::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, 
272         UINT cNames, LCID lcid, DISPID* rgDispID)
273 {
274     if( SUCCEEDED(loadTypeInfo()) )
275     {
276         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
277     }
278     return E_NOTIMPL;
279 };
280
281 STDMETHODIMP VLCInput::Invoke(DISPID dispIdMember, REFIID riid,
282         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
283         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
284 {
285     if( SUCCEEDED(loadTypeInfo()) )
286     {
287         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
288                 pVarResult, pExcepInfo, puArgErr);
289     }
290     return E_NOTIMPL;
291 };
292
293 STDMETHODIMP VLCInput::get_length(double* length)
294 {
295     if( NULL == length )
296         return E_POINTER;
297
298     libvlc_instance_t* p_libvlc;
299     HRESULT hr = _p_instance->getVLC(&p_libvlc);
300     if( SUCCEEDED(hr) )
301     {
302         libvlc_exception_t ex;
303         libvlc_exception_init(&ex);
304
305         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
306         if( ! libvlc_exception_raised(&ex) )
307         {
308             *length = (double)libvlc_input_get_length(p_input, &ex);
309             libvlc_input_free(p_input);
310             if( ! libvlc_exception_raised(&ex) )
311             {
312                 return NOERROR;
313             }
314         }
315         libvlc_exception_clear(&ex);
316         return E_FAIL;
317     }
318     return hr;
319 };
320
321 STDMETHODIMP VLCInput::get_position(float* position)
322 {
323     if( NULL == position )
324         return E_POINTER;
325
326     libvlc_instance_t* p_libvlc;
327     HRESULT hr = _p_instance->getVLC(&p_libvlc);
328     if( SUCCEEDED(hr) )
329     {
330         libvlc_exception_t ex;
331         libvlc_exception_init(&ex);
332
333         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
334         if( ! libvlc_exception_raised(&ex) )
335         {
336             *position = libvlc_input_get_position(p_input, &ex);
337             libvlc_input_free(p_input);
338             if( ! libvlc_exception_raised(&ex) )
339             {
340                 return NOERROR;
341             }
342         }
343         libvlc_exception_clear(&ex);
344         return E_FAIL;
345     }
346     return hr;
347 };
348
349 STDMETHODIMP VLCInput::put_position(float position)
350 {
351     libvlc_instance_t* p_libvlc;
352     HRESULT hr = _p_instance->getVLC(&p_libvlc);
353     if( SUCCEEDED(hr) )
354     {
355         libvlc_exception_t ex;
356         libvlc_exception_init(&ex);
357
358         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
359         if( ! libvlc_exception_raised(&ex) )
360         {
361             libvlc_input_set_position(p_input, position, &ex);
362             libvlc_input_free(p_input);
363             if( ! libvlc_exception_raised(&ex) )
364             {
365                 return NOERROR;
366             }
367         }
368         libvlc_exception_clear(&ex);
369         return E_FAIL;
370     }
371     return hr;
372 };
373
374 STDMETHODIMP VLCInput::get_time(double* time)
375 {
376     if( NULL == time )
377         return E_POINTER;
378
379     libvlc_instance_t* p_libvlc;
380     HRESULT hr = _p_instance->getVLC(&p_libvlc);
381     if( SUCCEEDED(hr) )
382     {
383         libvlc_exception_t ex;
384         libvlc_exception_init(&ex);
385
386         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
387         if( ! libvlc_exception_raised(&ex) )
388         {
389             *time = (double)libvlc_input_get_time(p_input, &ex);
390             libvlc_input_free(p_input);
391             if( ! libvlc_exception_raised(&ex) )
392             {
393                 return NOERROR;
394             }
395         }
396         libvlc_exception_clear(&ex);
397         return E_FAIL;
398     }
399     return hr;
400 };
401
402 STDMETHODIMP VLCInput::put_time(double time)
403 {
404     libvlc_instance_t* p_libvlc;
405     HRESULT hr = _p_instance->getVLC(&p_libvlc);
406     if( SUCCEEDED(hr) )
407     {
408         libvlc_exception_t ex;
409         libvlc_exception_init(&ex);
410
411         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
412         if( ! libvlc_exception_raised(&ex) )
413         {
414             libvlc_input_set_time(p_input, (vlc_int64_t)time, &ex);
415             libvlc_input_free(p_input);
416             if( ! libvlc_exception_raised(&ex) )
417             {
418                 return NOERROR;
419             }
420         }
421         libvlc_exception_clear(&ex);
422         return E_FAIL;
423     }
424     return hr;
425 };
426
427 STDMETHODIMP VLCInput::get_state(int* state)
428 {
429     if( NULL == state )
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             *state = libvlc_input_get_state(p_input, &ex);
443             libvlc_input_free(p_input);
444             if( ! libvlc_exception_raised(&ex) )
445             {
446                 return NOERROR;
447             }
448         }
449         libvlc_exception_clear(&ex);
450         // don't fail, just return the idle state
451         *state = 0;
452         return NOERROR;
453     }
454     return hr;
455 };
456
457 STDMETHODIMP VLCInput::get_rate(float* rate)
458 {
459     if( NULL == rate )
460         return E_POINTER;
461
462     libvlc_instance_t* p_libvlc;
463     HRESULT hr = _p_instance->getVLC(&p_libvlc);
464     if( SUCCEEDED(hr) )
465     {
466         libvlc_exception_t ex;
467         libvlc_exception_init(&ex);
468
469         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
470         if( ! libvlc_exception_raised(&ex) )
471         {
472             *rate = libvlc_input_get_rate(p_input, &ex);
473             libvlc_input_free(p_input);
474             if( ! libvlc_exception_raised(&ex) )
475             {
476                 return NOERROR;
477             }
478         }
479         libvlc_exception_clear(&ex);
480         return E_FAIL;
481     }
482     return hr;
483 };
484
485 STDMETHODIMP VLCInput::put_rate(float rate)
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             libvlc_input_set_rate(p_input, rate, &ex);
498             libvlc_input_free(p_input);
499             if( ! libvlc_exception_raised(&ex) )
500             {
501                 return NOERROR;
502             }
503         }
504         libvlc_exception_clear(&ex);
505         return E_FAIL;
506     }
507     return hr;
508 };
509
510 STDMETHODIMP VLCInput::get_fps(float* fps)
511 {
512     if( NULL == fps )
513         return E_POINTER;
514
515     libvlc_instance_t* p_libvlc;
516     HRESULT hr = _p_instance->getVLC(&p_libvlc);
517     if( SUCCEEDED(hr) )
518     {
519         libvlc_exception_t ex;
520         libvlc_exception_init(&ex);
521
522         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
523         if( ! libvlc_exception_raised(&ex) )
524         {
525             *fps = libvlc_input_get_fps(p_input, &ex);
526             libvlc_input_free(p_input);
527             if( ! libvlc_exception_raised(&ex) )
528             {
529                 return NOERROR;
530             }
531         }
532         libvlc_exception_clear(&ex);
533         return E_FAIL;
534     }
535     return hr;
536 };
537
538 STDMETHODIMP VLCInput::get_hasVout(VARIANT_BOOL* hasVout)
539 {
540     if( NULL == hasVout )
541         return E_POINTER;
542
543     libvlc_instance_t* p_libvlc;
544     HRESULT hr = _p_instance->getVLC(&p_libvlc);
545     if( SUCCEEDED(hr) )
546     {
547         libvlc_exception_t ex;
548         libvlc_exception_init(&ex);
549
550         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
551         if( ! libvlc_exception_raised(&ex) )
552         {
553             *hasVout = libvlc_input_has_vout(p_input, &ex) ? VARIANT_TRUE : VARIANT_FALSE;
554             libvlc_input_free(p_input);
555             if( ! libvlc_exception_raised(&ex) )
556             {
557                 return NOERROR;
558             }
559         }
560         libvlc_exception_clear(&ex);
561         return E_FAIL;
562     }
563     return hr;
564 };
565
566 /*******************************************************************************/
567
568 VLCPlaylist::~VLCPlaylist()
569 {
570     if( _p_typeinfo )
571         _p_typeinfo->Release();
572 };
573
574 HRESULT VLCPlaylist::loadTypeInfo(void)
575 {
576     HRESULT hr = NOERROR;
577     if( NULL == _p_typeinfo )
578     {
579         ITypeLib *p_typelib;
580
581         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
582         if( SUCCEEDED(hr) )
583         {
584             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCPlaylist, &_p_typeinfo);
585             if( FAILED(hr) )
586             {
587                 _p_typeinfo = NULL;
588             }
589             p_typelib->Release();
590         }
591     }
592     return hr;
593 };
594
595 STDMETHODIMP VLCPlaylist::GetTypeInfoCount(UINT* pctInfo)
596 {
597     if( NULL == pctInfo )
598         return E_INVALIDARG;
599
600     if( SUCCEEDED(loadTypeInfo()) )
601         *pctInfo = 1;
602     else
603         *pctInfo = 0;
604
605     return NOERROR;
606 };
607
608 STDMETHODIMP VLCPlaylist::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
609 {
610     if( NULL == ppTInfo )
611         return E_INVALIDARG;
612
613     if( SUCCEEDED(loadTypeInfo()) )
614     {
615         _p_typeinfo->AddRef();
616         *ppTInfo = _p_typeinfo;
617         return NOERROR;
618     }
619     *ppTInfo = NULL;
620     return E_NOTIMPL;
621 };
622
623 STDMETHODIMP VLCPlaylist::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, 
624         UINT cNames, LCID lcid, DISPID* rgDispID)
625 {
626     if( SUCCEEDED(loadTypeInfo()) )
627     {
628         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
629     }
630     return E_NOTIMPL;
631 };
632
633 STDMETHODIMP VLCPlaylist::Invoke(DISPID dispIdMember, REFIID riid,
634         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
635         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
636 {
637     if( SUCCEEDED(loadTypeInfo()) )
638     {
639         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
640                 pVarResult, pExcepInfo, puArgErr);
641     }
642     return E_NOTIMPL;
643 };
644
645 STDMETHODIMP VLCPlaylist::get_itemCount(int* count)
646 {
647     if( NULL == count )
648         return E_POINTER;
649
650     libvlc_instance_t* p_libvlc;
651     HRESULT hr = _p_instance->getVLC(&p_libvlc);
652     if( SUCCEEDED(hr) )
653     {
654         libvlc_exception_t ex;
655         libvlc_exception_init(&ex);
656
657         *count = libvlc_playlist_items_count(p_libvlc, &ex);
658         if( libvlc_exception_raised(&ex) )
659         {
660             libvlc_exception_clear(&ex);
661             return E_FAIL;
662         }
663         return NOERROR;
664     }
665     return hr;
666 };
667
668 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
669 {
670     if( NULL == isPlaying )
671         return E_POINTER;
672
673     libvlc_instance_t* p_libvlc;
674     HRESULT hr = _p_instance->getVLC(&p_libvlc);
675     if( SUCCEEDED(hr) )
676     {
677         libvlc_exception_t ex;
678         libvlc_exception_init(&ex);
679
680         *isPlaying = libvlc_playlist_isplaying(p_libvlc, &ex) ? VARIANT_TRUE: VARIANT_FALSE;
681         if( libvlc_exception_raised(&ex) )
682         {
683             libvlc_exception_clear(&ex);
684             return E_FAIL;
685         }
686         return NOERROR;
687     }
688     return hr;
689 };
690
691 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, int* item)
692 {
693     if( NULL == item )
694         return E_POINTER;
695
696     if( 0 == SysStringLen(uri) )
697         return E_INVALIDARG;
698
699     libvlc_instance_t* p_libvlc;
700     HRESULT hr = _p_instance->getVLC(&p_libvlc);
701     if( SUCCEEDED(hr) )
702     {
703         libvlc_exception_t ex;
704         libvlc_exception_init(&ex);
705
706         int i_options;
707         char **ppsz_options;
708
709         hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
710         if( FAILED(hr) )
711             return hr;
712
713         char *psz_uri = CStrFromBSTR(CP_UTF8, uri);
714         if( NULL == psz_uri )
715         {
716             VLCControl::FreeTargetOptions(ppsz_options, i_options);
717             return E_OUTOFMEMORY;
718         }
719
720         char *psz_name = NULL;
721         VARIANT v_name;
722         VariantInit(&v_name);
723         if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
724         {
725             if( SysStringLen(V_BSTR(&v_name)) > 0 )
726                 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
727
728             VariantClear(&v_name);
729         }
730
731         *item = libvlc_playlist_add_extended(p_libvlc,
732             psz_uri,
733             psz_name,
734             i_options,
735             const_cast<const char **>(ppsz_options),
736             &ex);
737
738         VLCControl::FreeTargetOptions(ppsz_options, i_options);
739         CoTaskMemFree(psz_uri);
740         if( psz_name )
741             CoTaskMemFree(psz_name);
742         if( libvlc_exception_raised(&ex) )
743         {
744             libvlc_exception_clear(&ex);
745             return E_FAIL;
746         }
747         return NOERROR;
748     }
749     return hr;
750 };
751
752 STDMETHODIMP VLCPlaylist::play()
753 {
754     libvlc_instance_t* p_libvlc;
755     HRESULT hr = _p_instance->getVLC(&p_libvlc);
756     if( SUCCEEDED(hr) )
757     {
758         libvlc_exception_t ex;
759         libvlc_exception_init(&ex);
760
761         libvlc_playlist_play(p_libvlc, -1, 0, NULL, &ex);
762         if( libvlc_exception_raised(&ex) )
763         {
764             libvlc_exception_clear(&ex);
765             return E_FAIL;
766         }
767         return NOERROR;
768     }
769     return hr;
770 };
771
772 STDMETHODIMP VLCPlaylist::playItem(int item)
773 {
774     libvlc_instance_t* p_libvlc;
775     HRESULT hr = _p_instance->getVLC(&p_libvlc);
776     if( SUCCEEDED(hr) )
777     {
778         libvlc_exception_t ex;
779         libvlc_exception_init(&ex);
780
781         libvlc_playlist_play(p_libvlc, item, 0, NULL, &ex);
782         if( libvlc_exception_raised(&ex) )
783         {
784             libvlc_exception_clear(&ex);
785             return E_FAIL;
786         }
787         return NOERROR;
788     }
789     return hr;
790 };
791
792 STDMETHODIMP VLCPlaylist::togglePause()
793 {
794     libvlc_instance_t* p_libvlc;
795     HRESULT hr = _p_instance->getVLC(&p_libvlc);
796     if( SUCCEEDED(hr) )
797     {
798         libvlc_exception_t ex;
799         libvlc_exception_init(&ex);
800
801         libvlc_playlist_pause(p_libvlc, &ex);
802         if( libvlc_exception_raised(&ex) )
803         {
804             libvlc_exception_clear(&ex);
805             return E_FAIL;
806         }
807         return NOERROR;
808     }
809     return hr;
810 };
811
812 STDMETHODIMP VLCPlaylist::stop()
813 {
814     libvlc_instance_t* p_libvlc;
815     HRESULT hr = _p_instance->getVLC(&p_libvlc);
816     if( SUCCEEDED(hr) )
817     {
818         libvlc_exception_t ex;
819         libvlc_exception_init(&ex);
820
821         libvlc_playlist_stop(p_libvlc, &ex);
822         if( libvlc_exception_raised(&ex) )
823         {
824             libvlc_exception_clear(&ex);
825             return E_FAIL;
826         }
827         return NOERROR;
828     }
829     return hr;
830 };
831
832 STDMETHODIMP VLCPlaylist::next()
833 {
834     libvlc_instance_t* p_libvlc;
835     HRESULT hr = _p_instance->getVLC(&p_libvlc);
836     if( SUCCEEDED(hr) )
837     {
838         libvlc_exception_t ex;
839         libvlc_exception_init(&ex);
840
841         libvlc_playlist_next(p_libvlc, &ex);
842         if( libvlc_exception_raised(&ex) )
843         {
844             libvlc_exception_clear(&ex);
845             return E_FAIL;
846         }
847         return NOERROR;
848     }
849     return hr;
850 };
851
852 STDMETHODIMP VLCPlaylist::prev()
853 {
854     libvlc_instance_t* p_libvlc;
855     HRESULT hr = _p_instance->getVLC(&p_libvlc);
856     if( SUCCEEDED(hr) )
857     {
858         libvlc_exception_t ex;
859         libvlc_exception_init(&ex);
860
861         libvlc_playlist_prev(p_libvlc, &ex);
862         if( libvlc_exception_raised(&ex) )
863         {
864             libvlc_exception_clear(&ex);
865             return E_FAIL;
866         }
867         return NOERROR;
868     }
869     return hr;
870 };
871
872 STDMETHODIMP VLCPlaylist::clear()
873 {
874     libvlc_instance_t* p_libvlc;
875     HRESULT hr = _p_instance->getVLC(&p_libvlc);
876     if( SUCCEEDED(hr) )
877     {
878         libvlc_exception_t ex;
879         libvlc_exception_init(&ex);
880
881         libvlc_playlist_clear(p_libvlc, &ex);
882         if( libvlc_exception_raised(&ex) )
883         {
884             libvlc_exception_clear(&ex);
885             return E_FAIL;
886         }
887         return NOERROR;
888     }
889     return hr;
890 };
891
892 STDMETHODIMP VLCPlaylist::removeItem(int item)
893 {
894     libvlc_instance_t* p_libvlc;
895     HRESULT hr = _p_instance->getVLC(&p_libvlc);
896     if( SUCCEEDED(hr) )
897     {
898         libvlc_exception_t ex;
899         libvlc_exception_init(&ex);
900
901         libvlc_playlist_delete_item(p_libvlc, item, &ex);
902         if( libvlc_exception_raised(&ex) )
903         {
904             libvlc_exception_clear(&ex);
905             return E_FAIL;
906         }
907         return NOERROR;
908     }
909     return hr;
910 };
911
912 /*******************************************************************************/
913
914 VLCVideo::~VLCVideo()
915 {
916     if( _p_typeinfo )
917         _p_typeinfo->Release();
918 };
919
920 HRESULT VLCVideo::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_IVLCVideo, &_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 VLCVideo::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 VLCVideo::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 VLCVideo::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 VLCVideo::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 VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
992 {
993     if( NULL == fullscreen )
994         return E_POINTER;
995
996     libvlc_instance_t* p_libvlc;
997     HRESULT hr = _p_instance->getVLC(&p_libvlc);
998     if( SUCCEEDED(hr) )
999     {
1000         libvlc_exception_t ex;
1001         libvlc_exception_init(&ex);
1002
1003         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
1004         if( ! libvlc_exception_raised(&ex) )
1005         {
1006             *fullscreen = libvlc_get_fullscreen(p_input, &ex) ? VARIANT_TRUE : VARIANT_FALSE;
1007             libvlc_input_free(p_input);
1008             if( ! libvlc_exception_raised(&ex) )
1009             {
1010                 return NOERROR;
1011             }
1012         }
1013         libvlc_exception_clear(&ex);
1014         return E_FAIL;
1015     }
1016     return hr;
1017 };
1018
1019 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
1020 {
1021     libvlc_instance_t* p_libvlc;
1022     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1023     if( SUCCEEDED(hr) )
1024     {
1025         libvlc_exception_t ex;
1026         libvlc_exception_init(&ex);
1027
1028         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
1029         if( ! libvlc_exception_raised(&ex) )
1030         {
1031             libvlc_set_fullscreen(p_input, VARIANT_FALSE != fullscreen, &ex);
1032             libvlc_input_free(p_input);
1033             if( ! libvlc_exception_raised(&ex) )
1034             {
1035                 return NOERROR;
1036             }
1037         }
1038         libvlc_exception_clear(&ex);
1039         return E_FAIL;
1040     }
1041     return hr;
1042 };
1043
1044 STDMETHODIMP VLCVideo::get_width(int* width)
1045 {
1046     if( NULL == width )
1047         return E_POINTER;
1048
1049     libvlc_instance_t* p_libvlc;
1050     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1051     if( SUCCEEDED(hr) )
1052     {
1053         libvlc_exception_t ex;
1054         libvlc_exception_init(&ex);
1055
1056         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
1057         if( ! libvlc_exception_raised(&ex) )
1058         {
1059             *width = libvlc_video_get_width(p_input, &ex);
1060             libvlc_input_free(p_input);
1061             if( ! libvlc_exception_raised(&ex) )
1062             {
1063                 return NOERROR;
1064             }
1065         }
1066         libvlc_exception_clear(&ex);
1067         return E_FAIL;
1068     }
1069     return hr;
1070 };
1071
1072 STDMETHODIMP VLCVideo::get_height(int* height)
1073 {
1074     if( NULL == height )
1075         return E_POINTER;
1076
1077     libvlc_instance_t* p_libvlc;
1078     HRESULT hr = _p_instance->getVLC(&p_libvlc);
1079     if( SUCCEEDED(hr) )
1080     {
1081         libvlc_exception_t ex;
1082         libvlc_exception_init(&ex);
1083
1084         libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
1085         if( ! libvlc_exception_raised(&ex) )
1086         {
1087             *height = libvlc_video_get_height(p_input, &ex);
1088             libvlc_input_free(p_input);
1089             if( ! libvlc_exception_raised(&ex) )
1090             {
1091                 return NOERROR;
1092             }
1093         }
1094         libvlc_exception_clear(&ex);
1095         return E_FAIL;
1096     }
1097     return hr;
1098 };
1099
1100 /*******************************************************************************/
1101
1102 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
1103     _p_instance(p_instance),
1104     _p_typeinfo(NULL),
1105     _p_vlcaudio(NULL),
1106     _p_vlcinput(NULL),
1107     _p_vlcplaylist(NULL),
1108     _p_vlcvideo(NULL)
1109 {
1110     _p_vlcaudio     = new VLCAudio(p_instance);
1111     _p_vlcinput     = new VLCInput(p_instance);
1112     _p_vlcplaylist  = new VLCPlaylist(p_instance);
1113     _p_vlcvideo     = new VLCVideo(p_instance);
1114 };
1115
1116 VLCControl2::~VLCControl2()
1117 {
1118     delete _p_vlcvideo;
1119     delete _p_vlcplaylist;
1120     delete _p_vlcinput;
1121     delete _p_vlcaudio;
1122     if( _p_typeinfo )
1123         _p_typeinfo->Release();
1124 };
1125
1126 HRESULT VLCControl2::loadTypeInfo(void)
1127 {
1128     HRESULT hr = NOERROR;
1129     if( NULL == _p_typeinfo )
1130     {
1131         ITypeLib *p_typelib;
1132
1133         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1134         if( SUCCEEDED(hr) )
1135         {
1136             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
1137             if( FAILED(hr) )
1138             {
1139                 _p_typeinfo = NULL;
1140             }
1141             p_typelib->Release();
1142         }
1143     }
1144     return hr;
1145 };
1146
1147 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
1148 {
1149     if( NULL == pctInfo )
1150         return E_INVALIDARG;
1151
1152     if( SUCCEEDED(loadTypeInfo()) )
1153         *pctInfo = 1;
1154     else
1155         *pctInfo = 0;
1156
1157     return NOERROR;
1158 };
1159
1160 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1161 {
1162     if( NULL == ppTInfo )
1163         return E_INVALIDARG;
1164
1165     if( SUCCEEDED(loadTypeInfo()) )
1166     {
1167         _p_typeinfo->AddRef();
1168         *ppTInfo = _p_typeinfo;
1169         return NOERROR;
1170     }
1171     *ppTInfo = NULL;
1172     return E_NOTIMPL;
1173 };
1174
1175 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, 
1176         UINT cNames, LCID lcid, DISPID* rgDispID)
1177 {
1178     if( SUCCEEDED(loadTypeInfo()) )
1179     {
1180         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1181     }
1182     return E_NOTIMPL;
1183 };
1184
1185 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
1186         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1187         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1188 {
1189     if( SUCCEEDED(loadTypeInfo()) )
1190     {
1191         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1192                 pVarResult, pExcepInfo, puArgErr);
1193     }
1194     return E_NOTIMPL;
1195 };
1196
1197 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
1198 {
1199     if( NULL == autoloop )
1200         return E_POINTER;
1201
1202     *autoloop = _p_instance->getAutoLoop() ? VARIANT_TRUE: VARIANT_FALSE;
1203     return S_OK;
1204 };
1205
1206 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
1207 {
1208     _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
1209     return S_OK;
1210 };
1211
1212 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
1213 {
1214     if( NULL == autoplay )
1215         return E_POINTER;
1216
1217     *autoplay = _p_instance->getAutoPlay() ? VARIANT_TRUE: VARIANT_FALSE;
1218     return S_OK;
1219 };
1220
1221 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
1222 {
1223     _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
1224     return S_OK;
1225 };
1226
1227 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
1228 {
1229     if( NULL == url )
1230         return E_POINTER;
1231
1232     *url = SysAllocStringLen(_p_instance->getBaseURL(),
1233                 SysStringLen(_p_instance->getBaseURL()));
1234     return NOERROR;
1235 };
1236
1237 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
1238 {
1239     _p_instance->setBaseURL(mrl);
1240
1241     return S_OK;
1242 };
1243
1244 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
1245 {
1246     if( NULL == mrl )
1247         return E_POINTER;
1248
1249     *mrl = SysAllocStringLen(_p_instance->getMRL(),
1250                 SysStringLen(_p_instance->getMRL()));
1251     return NOERROR;
1252 };
1253
1254 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
1255 {
1256     _p_instance->setMRL(mrl);
1257
1258     return S_OK;
1259 };
1260
1261 STDMETHODIMP VLCControl2::get_StartTime(int *seconds)
1262 {
1263     if( NULL == seconds )
1264         return E_POINTER;
1265
1266     *seconds = _p_instance->getStartTime();
1267
1268     return S_OK;
1269 };
1270      
1271 STDMETHODIMP VLCControl2::put_StartTime(int seconds)
1272 {
1273     _p_instance->setStartTime(seconds);
1274
1275     return NOERROR;
1276 };
1277         
1278 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
1279 {
1280     if( NULL == version )
1281         return E_POINTER;
1282
1283     const char *versionStr = VLC_Version();
1284     if( NULL != versionStr )
1285     {
1286         *version = BSTRFromCStr(_p_instance->getCodePage(), versionStr);
1287         
1288         return NULL == *version ? E_OUTOFMEMORY : NOERROR;
1289     }
1290     *version = NULL;
1291     return E_FAIL;
1292 };
1293  
1294 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
1295 {
1296     if( NULL == isVisible )
1297         return E_POINTER;
1298
1299     *isVisible = _p_instance->getVisible() ? VARIANT_TRUE : VARIANT_FALSE;
1300
1301     return NOERROR;
1302 };
1303         
1304 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
1305 {
1306     _p_instance->setVisible(isVisible != VARIANT_FALSE);
1307
1308     return NOERROR;
1309 };
1310
1311 STDMETHODIMP VLCControl2::get_Volume(int *volume)
1312 {
1313     if( NULL == volume )
1314         return E_POINTER;
1315
1316     *volume  = _p_instance->getVolume();
1317     return NOERROR;
1318 };
1319         
1320 STDMETHODIMP VLCControl2::put_Volume(int volume)
1321 {
1322     _p_instance->setVolume(volume);
1323     return NOERROR;
1324 };
1325
1326 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
1327 {
1328     if( NULL == obj )
1329         return E_POINTER;
1330
1331     *obj = _p_vlcaudio;
1332     if( NULL != _p_vlcaudio )
1333     {
1334         _p_vlcaudio->AddRef();
1335         return NOERROR;
1336     }
1337     return E_OUTOFMEMORY;
1338 };
1339
1340 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
1341 {
1342     if( NULL == obj )
1343         return E_POINTER;
1344
1345     *obj = _p_vlcinput;
1346     if( NULL != _p_vlcinput )
1347     {
1348         _p_vlcinput->AddRef();
1349         return NOERROR;
1350     }
1351     return E_OUTOFMEMORY;
1352 };
1353
1354 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
1355 {
1356     if( NULL == obj )
1357         return E_POINTER;
1358
1359     *obj = _p_vlcplaylist;
1360     if( NULL != _p_vlcplaylist )
1361     {
1362         _p_vlcplaylist->AddRef();
1363         return NOERROR;
1364     }
1365     return E_OUTOFMEMORY;
1366 };
1367
1368 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
1369 {
1370     if( NULL == obj )
1371         return E_POINTER;
1372
1373     *obj = _p_vlcvideo;
1374     if( NULL != _p_vlcvideo )
1375     {
1376         _p_vlcvideo->AddRef();
1377         return NOERROR;
1378     }
1379     return E_OUTOFMEMORY;
1380 };
1381