]> git.sesse.net Git - vlc/blob - projects/activex/vlccontrol2.cpp
Cosmetics: activex plugin: add a helper for bool -> VARIANT_BOOL.
[vlc] / projects / activex / vlccontrol2.cpp
1 /*****************************************************************************
2  * vlccontrol2.cpp: ActiveX control for VLC
3  *****************************************************************************
4  * Copyright (C) 2006 the VideoLAN team
5  * Copyright (C) 2010 M2X BV
6  *
7  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8  *          Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #include <stdio.h>
26 #include <shlwapi.h>
27 #include <wininet.h>
28 #include <tchar.h>
29
30 #include "utils.h"
31 #include "plugin.h"
32 #include "vlccontrol2.h"
33 #include "vlccontrol.h"
34
35 #include "position.h"
36
37 // ---------
38
39 HRESULT VLCInterfaceBase::report_exception(REFIID riid, libvlc_exception_t *ex)
40 {
41     _plug->setErrorInfo(riid,libvlc_errmsg());
42     libvlc_exception_clear(ex);
43     return E_FAIL;
44 }
45
46 HRESULT VLCInterfaceBase::loadTypeInfo(REFIID riid)
47 {
48     // if( _ti ) return NOERROR; // unnecessairy
49
50     ITypeLib *p_typelib;
51     HRESULT hr = _plug->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
52     if( SUCCEEDED(hr) )
53     {
54         hr = p_typelib->GetTypeInfoOfGuid(riid, &_ti);
55         if( FAILED(hr) ) _ti = NULL;
56         p_typelib->Release();
57     }
58     return hr;
59 }
60
61 #define BIND_INTERFACE( class ) \
62     template<> REFIID VLCInterface<class, I##class>::_riid = IID_I##class;
63
64 BIND_INTERFACE( VLCAudio )
65 BIND_INTERFACE( VLCInput )
66 BIND_INTERFACE( VLCMarquee )
67 BIND_INTERFACE( VLCLogo )
68 BIND_INTERFACE( VLCPlaylistItems )
69 BIND_INTERFACE( VLCPlaylist )
70 BIND_INTERFACE( VLCVideo )
71 BIND_INTERFACE( VLCSubtitle )
72
73 #undef  BIND_INTERFACE
74
75 template<class I> static inline
76 HRESULT object_get(I **dst, I *src)
77 {
78     if( NULL == dst )
79         return E_POINTER;
80
81     *dst = src;
82     if( NULL != src )
83     {
84         src->AddRef();
85         return NOERROR;
86     }
87     return E_OUTOFMEMORY;
88 }
89
90 static inline
91 VARIANT_BOOL varbool(bool b) { return b ? VARIANT_TRUE : VARIANT_FALSE; }
92
93 // ---------
94
95 STDMETHODIMP VLCAudio::get_mute(VARIANT_BOOL* mute)
96 {
97     if( NULL == mute )
98         return E_POINTER;
99
100     libvlc_instance_t* p_libvlc;
101     HRESULT hr = getVLC(&p_libvlc);
102     if( SUCCEEDED(hr) )
103         *mute = varbool( libvlc_audio_get_mute(p_libvlc) );
104     return hr;
105 };
106
107 STDMETHODIMP VLCAudio::put_mute(VARIANT_BOOL mute)
108 {
109     libvlc_instance_t* p_libvlc;
110     HRESULT hr = getVLC(&p_libvlc);
111     if( SUCCEEDED(hr) )
112         libvlc_audio_set_mute(p_libvlc, VARIANT_FALSE != mute);
113     return hr;
114 };
115
116 STDMETHODIMP VLCAudio::get_volume(long* volume)
117 {
118     if( NULL == volume )
119         return E_POINTER;
120
121     libvlc_instance_t* p_libvlc;
122     HRESULT hr = getVLC(&p_libvlc);
123     if( SUCCEEDED(hr) )
124         *volume = libvlc_audio_get_volume(p_libvlc);
125     return hr;
126 };
127
128 STDMETHODIMP VLCAudio::put_volume(long volume)
129 {
130     libvlc_instance_t* p_libvlc;
131     HRESULT hr = getVLC(&p_libvlc);
132     if( SUCCEEDED(hr) )
133     {
134         libvlc_exception_t ex;
135         libvlc_exception_init(&ex);
136
137         libvlc_audio_set_volume(p_libvlc, volume, &ex);
138         hr = exception_bridge(&ex);
139     }
140     return hr;
141 };
142
143 STDMETHODIMP VLCAudio::get_track(long* track)
144 {
145     if( NULL == track )
146         return E_POINTER;
147
148     libvlc_media_player_t* p_md;
149     HRESULT hr = getMD(&p_md);
150     if( SUCCEEDED(hr) )
151     {
152         libvlc_exception_t ex;
153         libvlc_exception_init(&ex);
154
155         *track = libvlc_audio_get_track(p_md, &ex);
156         hr = exception_bridge(&ex);
157     }
158     return hr;
159 };
160
161 STDMETHODIMP VLCAudio::put_track(long track)
162 {
163     libvlc_media_player_t *p_md;
164     HRESULT hr = getMD(&p_md);
165     if( SUCCEEDED(hr) )
166     {
167         libvlc_exception_t ex;
168         libvlc_exception_init(&ex);
169
170         libvlc_audio_set_track(p_md, track, &ex);
171         hr = exception_bridge(&ex);
172     }
173     return hr;
174 };
175
176 STDMETHODIMP VLCAudio::get_count(long* trackNumber)
177 {
178     if( NULL == trackNumber )
179         return E_POINTER;
180
181     libvlc_media_player_t* p_md;
182     HRESULT hr = getMD(&p_md);
183     if( SUCCEEDED(hr) )
184     {
185         libvlc_exception_t ex;
186         libvlc_exception_init(&ex);
187         // get the number of audio track available and return it
188         *trackNumber = libvlc_audio_get_track_count(p_md, &ex);
189         hr = exception_bridge(&ex);
190     }
191     return hr;
192 };
193
194
195 STDMETHODIMP VLCAudio::description(long trackID, BSTR* name)
196 {
197     if( NULL == name )
198         return E_POINTER;
199
200     libvlc_media_player_t* p_md;
201     libvlc_exception_t ex;
202     libvlc_exception_init(&ex);
203
204     HRESULT hr = getMD(&p_md);
205     if( SUCCEEDED(hr) )
206     {
207         int i, i_limit;
208         const char *psz_name;
209         libvlc_track_description_t *p_trackDesc;
210
211         // get tracks description
212         p_trackDesc = libvlc_audio_get_track_description(p_md, &ex);
213         hr = exception_bridge(&ex);
214         if( FAILED(hr) )
215             return hr;
216
217         //get the number of available track
218         i_limit = libvlc_audio_get_track_count(p_md, &ex);
219         hr = exception_bridge(&ex);
220         if( FAILED(hr) )
221             return hr;
222
223         // check if the number given is a good one
224         if ( ( trackID > ( i_limit -1 ) ) || ( trackID < 0 ) )
225                 return E_FAIL;
226
227         // get the good trackDesc
228         for( i = 0 ; i < trackID ; i++ )
229         {
230             p_trackDesc = p_trackDesc->p_next;
231         }
232         // get the track name
233         psz_name = p_trackDesc->psz_name;
234
235         // return it
236         if( psz_name != NULL )
237         {
238             *name = BSTRFromCStr(CP_UTF8, psz_name);
239             return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
240         }
241         *name = NULL;
242         return E_FAIL;
243     }
244     return hr;
245 };
246
247 STDMETHODIMP VLCAudio::get_channel(long *channel)
248 {
249     if( NULL == channel )
250         return E_POINTER;
251
252     libvlc_instance_t* p_libvlc;
253     HRESULT hr = getVLC(&p_libvlc);
254     if( SUCCEEDED(hr) )
255     {
256         libvlc_exception_t ex;
257         libvlc_exception_init(&ex);
258
259         *channel = libvlc_audio_get_channel(p_libvlc, &ex);
260         hr = exception_bridge(&ex);
261     }
262     return hr;
263 };
264
265 STDMETHODIMP VLCAudio::put_channel(long channel)
266 {
267     libvlc_instance_t* p_libvlc;
268     HRESULT hr = getVLC(&p_libvlc);
269     if( SUCCEEDED(hr) )
270     {
271         libvlc_exception_t ex;
272         libvlc_exception_init(&ex);
273
274         libvlc_audio_set_channel(p_libvlc, channel, &ex);
275         hr = exception_bridge(&ex);
276     }
277     return hr;
278 };
279
280 STDMETHODIMP VLCAudio::toggleMute()
281 {
282     libvlc_instance_t* p_libvlc;
283     HRESULT hr = getVLC(&p_libvlc);
284     if( SUCCEEDED(hr) )
285         libvlc_audio_toggle_mute(p_libvlc);
286     return hr;
287 };
288
289 /****************************************************************************/
290
291 STDMETHODIMP VLCInput::get_length(double* length)
292 {
293     if( NULL == length )
294         return E_POINTER;
295     *length = 0;
296
297     libvlc_media_player_t *p_md;
298     HRESULT hr = getMD(&p_md);
299     if( SUCCEEDED(hr) )
300     {
301         libvlc_exception_t ex;
302         libvlc_exception_init(&ex);
303
304         *length = (double)libvlc_media_player_get_length(p_md, &ex);
305         hr = exception_bridge(&ex);
306     }
307     return hr;
308 };
309
310 STDMETHODIMP VLCInput::get_position(double* position)
311 {
312     if( NULL == position )
313         return E_POINTER;
314
315     *position = 0.0f;
316     libvlc_media_player_t *p_md;
317     HRESULT hr = getMD(&p_md);
318     if( SUCCEEDED(hr) )
319     {
320         libvlc_exception_t ex;
321         libvlc_exception_init(&ex);
322
323         *position = libvlc_media_player_get_position(p_md, &ex);
324         hr = exception_bridge(&ex);
325     }
326     return hr;
327 };
328
329 STDMETHODIMP VLCInput::put_position(double position)
330 {
331     libvlc_media_player_t *p_md;
332     HRESULT hr = getMD(&p_md);
333     if( SUCCEEDED(hr) )
334     {
335         libvlc_exception_t ex;
336         libvlc_exception_init(&ex);
337
338         libvlc_media_player_set_position(p_md, position, &ex);
339         hr = exception_bridge(&ex);
340     }
341     return hr;
342 };
343
344 STDMETHODIMP VLCInput::get_time(double* time)
345 {
346     if( NULL == time )
347         return E_POINTER;
348
349     libvlc_media_player_t *p_md;
350     HRESULT hr = getMD(&p_md);
351     if( SUCCEEDED(hr) )
352     {
353         libvlc_exception_t ex;
354         libvlc_exception_init(&ex);
355
356         *time = (double)libvlc_media_player_get_time(p_md, &ex);
357         hr = exception_bridge(&ex);
358     }
359     return hr;
360 };
361
362 STDMETHODIMP VLCInput::put_time(double time)
363 {
364     libvlc_media_player_t *p_md;
365     HRESULT hr = getMD(&p_md);
366     if( SUCCEEDED(hr) )
367     {
368         libvlc_exception_t ex;
369         libvlc_exception_init(&ex);
370
371         libvlc_media_player_set_time(p_md, (int64_t)time, &ex);
372         hr = exception_bridge(&ex);
373     }
374     return hr;
375 };
376
377 STDMETHODIMP VLCInput::get_state(long* state)
378 {
379     if( NULL == state )
380         return E_POINTER;
381
382     libvlc_media_player_t *p_md;
383     HRESULT hr = getMD(&p_md);
384     if( SUCCEEDED(hr) )
385     {
386         libvlc_exception_t ex;
387         libvlc_exception_init(&ex);
388
389         *state = libvlc_media_player_get_state(p_md);
390         if( libvlc_exception_raised(&ex) )
391         {
392             // don't fail, just return the idle state
393             *state = 0;
394             libvlc_exception_clear(&ex);
395         }
396     }
397     return hr;
398 };
399
400 STDMETHODIMP VLCInput::get_rate(double* rate)
401 {
402     if( NULL == rate )
403         return E_POINTER;
404
405     libvlc_media_player_t *p_md;
406     HRESULT hr = getMD(&p_md);
407     if( SUCCEEDED(hr) )
408     {
409         libvlc_exception_t ex;
410         libvlc_exception_init(&ex);
411
412         *rate = libvlc_media_player_get_rate(p_md, &ex);
413         hr = exception_bridge(&ex);
414     }
415     return hr;
416 };
417
418 STDMETHODIMP VLCInput::put_rate(double rate)
419 {
420     libvlc_media_player_t *p_md;
421     HRESULT hr = getMD(&p_md);
422     if( SUCCEEDED(hr) )
423     {
424         libvlc_exception_t ex;
425         libvlc_exception_init(&ex);
426
427         libvlc_media_player_set_rate(p_md, rate, &ex);
428         hr = exception_bridge(&ex);
429     }
430     return hr;
431 };
432
433 STDMETHODIMP VLCInput::get_fps(double* fps)
434 {
435     if( NULL == fps )
436         return E_POINTER;
437
438     *fps = 0.0;
439     libvlc_media_player_t *p_md;
440     HRESULT hr = getMD(&p_md);
441     if( SUCCEEDED(hr) )
442     {
443         libvlc_exception_t ex;
444         libvlc_exception_init(&ex);
445
446         *fps = libvlc_media_player_get_fps(p_md, &ex);
447         hr = exception_bridge(&ex);
448     }
449     return hr;
450 };
451
452 STDMETHODIMP VLCInput::get_hasVout(VARIANT_BOOL* hasVout)
453 {
454     if( NULL == hasVout )
455         return E_POINTER;
456
457     libvlc_media_player_t *p_md;
458     HRESULT hr = getMD(&p_md);
459     if( SUCCEEDED(hr) )
460     {
461         libvlc_exception_t ex;
462         libvlc_exception_init(&ex);
463
464         *hasVout = varbool( libvlc_media_player_has_vout(p_md, &ex) );
465         hr = exception_bridge(&ex);
466     }
467     return hr;
468 };
469
470 /****************************************************************************/
471
472 HRESULT VLCMarquee::do_put_int(unsigned idx, LONG val)
473 {
474     libvlc_media_player_t *p_md;
475     HRESULT hr = getMD(&p_md);
476     if( SUCCEEDED(hr) )
477     {
478         libvlc_exception_t ex;
479         libvlc_exception_init(&ex);
480         libvlc_video_set_marquee_int(p_md, idx, val, &ex);
481         hr = exception_bridge(&ex);
482     }
483     return hr;
484 }
485
486 HRESULT VLCMarquee::do_get_int(unsigned idx, LONG *val)
487 {
488     if( NULL == val )
489         return E_POINTER;
490
491     libvlc_media_player_t *p_md;
492     HRESULT hr = getMD(&p_md);
493     if( SUCCEEDED(hr) )
494     {
495         libvlc_exception_t ex;
496         libvlc_exception_init(&ex);
497         *val = libvlc_video_get_marquee_int(p_md, idx, &ex);
498         hr = exception_bridge(&ex);
499     }
500     return hr;
501 }
502
503 STDMETHODIMP VLCMarquee::get_position(BSTR* val)
504 {
505     if( NULL == val )
506         return E_POINTER;
507
508     LONG i;
509     HRESULT hr = do_get_int(libvlc_marquee_Position, &i);
510
511     if(SUCCEEDED(hr))
512         *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
513
514     return hr;
515 }
516
517 STDMETHODIMP VLCMarquee::put_position(BSTR val)
518 {
519     char *n = CStrFromBSTR(CP_UTF8, val);
520     if( !n ) return E_OUTOFMEMORY;
521
522     size_t i;
523     HRESULT hr;
524     if( position_byname( n, i ) )
525         hr = do_put_int(libvlc_marquee_Position,i);
526     else
527         hr = E_INVALIDARG;
528
529     CoTaskMemFree(n);
530     return hr;
531 }
532
533 STDMETHODIMP VLCMarquee::get_text(BSTR *val)
534 {
535     char *psz;
536     if( NULL == val )
537         return E_POINTER;
538
539     libvlc_media_player_t *p_md;
540     HRESULT hr = getMD(&p_md);
541     if( SUCCEEDED(hr) )
542     {
543         libvlc_exception_t ex;
544         libvlc_exception_init(&ex);
545
546         psz = libvlc_video_get_marquee_string(p_md, libvlc_marquee_Text, &ex);
547
548         hr = exception_bridge(&ex);
549         if(SUCCEEDED(hr))
550             *val = BSTRFromCStr(CP_UTF8, psz);
551     }
552     return hr;
553 }
554
555 STDMETHODIMP VLCMarquee::put_text(BSTR val)
556 {
557     libvlc_media_player_t *p_md;
558     HRESULT hr = getMD(&p_md);
559     if( SUCCEEDED(hr) )
560     {
561         libvlc_exception_t ex;
562         libvlc_exception_init(&ex);
563
564         char *psz_text = CStrFromBSTR(CP_UTF8, val);
565         libvlc_video_set_marquee_string(p_md, libvlc_marquee_Text,
566                                         psz_text, &ex);
567         hr = exception_bridge(&ex);
568         CoTaskMemFree(psz_text);
569     }
570     return hr;
571 }
572
573 /****************************************************************************/
574
575 STDMETHODIMP VLCPlaylistItems::get_count(long* count)
576 {
577     if( NULL == count )
578         return E_POINTER;
579
580     libvlc_exception_t ex;
581     libvlc_exception_init(&ex);
582
583     *count = Instance()->playlist_count(&ex);
584     return exception_bridge(&ex);
585 };
586
587 STDMETHODIMP VLCPlaylistItems::clear()
588 {
589     libvlc_exception_t ex;
590     libvlc_exception_init(&ex);
591
592     Instance()->playlist_clear(&ex);
593     return exception_bridge(&ex);
594 };
595
596 STDMETHODIMP VLCPlaylistItems::remove(long item)
597 {
598     libvlc_instance_t* p_libvlc;
599     HRESULT hr = getVLC(&p_libvlc);
600     if( SUCCEEDED(hr) )
601     {
602         libvlc_exception_t ex;
603         libvlc_exception_init(&ex);
604
605         Instance()->playlist_delete_item(item, &ex);
606         hr = exception_bridge(&ex);
607     }
608     return hr;
609 };
610
611 /****************************************************************************/
612
613 STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
614 {
615     if( NULL == count )
616         return E_POINTER;
617
618     *count = 0;
619     libvlc_exception_t ex;
620     libvlc_exception_init(&ex);
621
622     *count = Instance()->playlist_count(&ex);
623     return exception_bridge(&ex);
624 };
625
626 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
627 {
628     if( NULL == isPlaying )
629         return E_POINTER;
630
631     libvlc_media_player_t *p_md;
632     HRESULT hr = getMD(&p_md);
633     if( SUCCEEDED(hr) )
634     {
635         libvlc_exception_t ex;
636         libvlc_exception_init(&ex);
637
638         *isPlaying = varbool( libvlc_media_player_is_playing(p_md) );
639         libvlc_exception_clear(&ex);
640     }
641     return hr;
642 };
643
644 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
645 {
646     if( NULL == item )
647         return E_POINTER;
648
649     if( 0 == SysStringLen(uri) )
650         return E_INVALIDARG;
651
652     libvlc_instance_t* p_libvlc;
653     HRESULT hr = getVLC(&p_libvlc);
654     if( SUCCEEDED(hr) )
655     {
656         libvlc_exception_t ex;
657         libvlc_exception_init(&ex);
658
659         char *psz_uri = NULL;
660         if( SysStringLen(Instance()->getBaseURL()) > 0 )
661         {
662             /*
663             ** if the MRL a relative URL, we should end up with an absolute URL
664             */
665             LPWSTR abs_url = CombineURL(Instance()->getBaseURL(), uri);
666             if( NULL != abs_url )
667             {
668                 psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
669                 CoTaskMemFree(abs_url);
670             }
671             else
672             {
673                 psz_uri = CStrFromBSTR(CP_UTF8, uri);
674             }
675         }
676         else
677         {
678             /*
679             ** baseURL is empty, assume MRL is absolute
680             */
681             psz_uri = CStrFromBSTR(CP_UTF8, uri);
682         }
683
684         if( NULL == psz_uri )
685         {
686             return E_OUTOFMEMORY;
687         }
688
689         int i_options;
690         char **ppsz_options;
691
692         hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
693         if( FAILED(hr) )
694         {
695             CoTaskMemFree(psz_uri);
696             return hr;
697         }
698
699         char *psz_name = NULL;
700         VARIANT v_name;
701         VariantInit(&v_name);
702         if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
703         {
704             if( SysStringLen(V_BSTR(&v_name)) > 0 )
705                 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
706
707             VariantClear(&v_name);
708         }
709
710         *item = Instance()->playlist_add_extended_untrusted(psz_uri,
711                     i_options, const_cast<const char **>(ppsz_options), &ex);
712
713         VLCControl::FreeTargetOptions(ppsz_options, i_options);
714         CoTaskMemFree(psz_uri);
715         if( psz_name ) /* XXX Do we even need to check? */
716             CoTaskMemFree(psz_name);
717         hr = exception_bridge(&ex);
718     }
719     return hr;
720 };
721
722 STDMETHODIMP VLCPlaylist::play()
723 {
724     libvlc_exception_t ex;
725     libvlc_exception_init(&ex);
726
727     Instance()->playlist_play(&ex);
728     return exception_bridge(&ex);
729 };
730
731 STDMETHODIMP VLCPlaylist::playItem(long item)
732 {
733     libvlc_exception_t ex;
734     libvlc_exception_init(&ex);
735
736     Instance()->playlist_play_item(item,&ex);
737     return exception_bridge(&ex);;
738 };
739
740 STDMETHODIMP VLCPlaylist::togglePause()
741 {
742     libvlc_media_player_t* p_md;
743     HRESULT hr = getMD(&p_md);
744     if( SUCCEEDED(hr) )
745     {
746         libvlc_exception_t ex;
747         libvlc_exception_init(&ex);
748
749         libvlc_media_player_pause(p_md, &ex);
750         hr = exception_bridge(&ex);;
751     }
752     return hr;
753 };
754
755 STDMETHODIMP VLCPlaylist::stop()
756 {
757     libvlc_media_player_t *p_md;
758     HRESULT hr = getMD(&p_md);
759     if( SUCCEEDED(hr) )
760     {
761         libvlc_exception_t ex;
762         libvlc_exception_init(&ex);
763
764         libvlc_media_player_stop(p_md);
765         hr = exception_bridge(&ex);;
766     }
767     return hr;
768 };
769
770 STDMETHODIMP VLCPlaylist::next()
771 {
772     libvlc_exception_t ex;
773     libvlc_exception_init(&ex);
774
775     Instance()->playlist_next(&ex);
776     return exception_bridge(&ex);;
777 };
778
779 STDMETHODIMP VLCPlaylist::prev()
780 {
781     libvlc_exception_t ex;
782     libvlc_exception_init(&ex);
783
784     Instance()->playlist_prev(&ex);
785     return exception_bridge(&ex);;
786 };
787
788 STDMETHODIMP VLCPlaylist::clear()
789 {
790     libvlc_exception_t ex;
791     libvlc_exception_init(&ex);
792
793     Instance()->playlist_clear(&ex);
794     return exception_bridge(&ex);;
795 };
796
797 STDMETHODIMP VLCPlaylist::removeItem(long item)
798 {
799     libvlc_instance_t* p_libvlc;
800     HRESULT hr = getVLC(&p_libvlc);
801     if( SUCCEEDED(hr) )
802     {
803         libvlc_exception_t ex;
804         libvlc_exception_init(&ex);
805
806         Instance()->playlist_delete_item(item, &ex);
807         hr = exception_bridge(&ex);;
808     }
809     return hr;
810 };
811
812 STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
813 {
814     if( NULL == obj )
815         return E_POINTER;
816
817     *obj = _p_vlcplaylistitems;
818     if( NULL != _p_vlcplaylistitems )
819     {
820         _p_vlcplaylistitems->AddRef();
821         return NOERROR;
822     }
823     return E_OUTOFMEMORY;
824 };
825
826 /****************************************************************************/
827
828 STDMETHODIMP VLCSubtitle::get_track(long* spu)
829 {
830     if( NULL == spu )
831         return E_POINTER;
832
833     libvlc_media_player_t *p_md;
834     HRESULT hr = getMD(&p_md);
835     if( SUCCEEDED(hr) )
836     {
837         libvlc_exception_t ex;
838         libvlc_exception_init(&ex);
839
840         *spu = libvlc_video_get_spu(p_md, &ex);
841         hr = exception_bridge(&ex);
842     }
843     return hr;
844 };
845
846 STDMETHODIMP VLCSubtitle::put_track(long spu)
847 {
848     libvlc_media_player_t *p_md;
849     HRESULT hr = getMD(&p_md);
850     if( SUCCEEDED(hr) )
851     {
852         libvlc_exception_t ex;
853         libvlc_exception_init(&ex);
854
855         libvlc_video_set_spu(p_md, spu, &ex);
856         hr = exception_bridge(&ex);
857     }
858     return hr;
859 };
860
861 STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
862 {
863     if( NULL == spuNumber )
864         return E_POINTER;
865
866     libvlc_media_player_t *p_md;
867     HRESULT hr = getMD(&p_md);
868     if( SUCCEEDED(hr) )
869     {
870         libvlc_exception_t ex;
871         libvlc_exception_init(&ex);
872         // get the number of video subtitle available and return it
873         *spuNumber = libvlc_video_get_spu_count(p_md, &ex);
874         hr = exception_bridge(&ex);
875     }
876     return hr;
877 };
878
879
880 STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
881 {
882     if( NULL == name )
883        return E_POINTER;
884
885     libvlc_media_player_t* p_md;
886     libvlc_exception_t ex;
887     libvlc_exception_init(&ex);
888
889     HRESULT hr = getMD(&p_md);
890     if( SUCCEEDED(hr) )
891     {
892         int i, i_limit;
893         const char *psz_name;
894         libvlc_track_description_t *p_spuDesc;
895
896         // get subtitles description
897         p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
898         hr = exception_bridge(&ex);
899         if( FAILED(hr) )
900             return hr;
901
902         // get the number of available subtitle
903         i_limit = libvlc_video_get_spu_count(p_md, &ex);
904         hr = exception_bridge(&ex);
905         if( FAILED(hr) )
906             return hr;
907
908         // check if the number given is a good one
909         if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
910             return E_FAIL;
911
912         // get the good spuDesc
913         for( i = 0 ; i < nameID ; i++ )
914         {
915             p_spuDesc = p_spuDesc->p_next;
916         }
917         // get the subtitle name
918         psz_name = p_spuDesc->psz_name;
919
920         // return it
921         if( psz_name != NULL )
922         {
923             *name = BSTRFromCStr(CP_UTF8, psz_name);
924             return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
925         }
926         *name = NULL;
927         return E_FAIL;
928     }
929     return hr;
930 };
931
932 /****************************************************************************/
933
934 STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
935 {
936     if( NULL == fullscreen )
937         return E_POINTER;
938
939     libvlc_media_player_t *p_md;
940     HRESULT hr = getMD(&p_md);
941     if( SUCCEEDED(hr) )
942     {
943         libvlc_exception_t ex;
944         libvlc_exception_init(&ex);
945
946         *fullscreen = varbool( libvlc_get_fullscreen(p_md, &ex) );
947         hr = exception_bridge(&ex);
948     }
949     return hr;
950 };
951
952 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
953 {
954     libvlc_media_player_t *p_md;
955     HRESULT hr = getMD(&p_md);
956     if( SUCCEEDED(hr) )
957     {
958         libvlc_exception_t ex;
959         libvlc_exception_init(&ex);
960
961         libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen, &ex);
962         hr = exception_bridge(&ex);
963     }
964     return hr;
965 };
966
967 STDMETHODIMP VLCVideo::get_width(long* width)
968 {
969     if( NULL == width )
970         return E_POINTER;
971
972     libvlc_media_player_t *p_md;
973     HRESULT hr = getMD(&p_md);
974     if( SUCCEEDED(hr) )
975     {
976         libvlc_exception_t ex;
977         libvlc_exception_init(&ex);
978
979         *width = libvlc_video_get_width(p_md, &ex);
980         hr = exception_bridge(&ex);
981     }
982     return hr;
983 };
984
985 STDMETHODIMP VLCVideo::get_height(long* height)
986 {
987     if( NULL == height )
988         return E_POINTER;
989
990     libvlc_media_player_t *p_md;
991     HRESULT hr = getMD(&p_md);
992     if( SUCCEEDED(hr) )
993     {
994         libvlc_exception_t ex;
995         libvlc_exception_init(&ex);
996
997         *height = libvlc_video_get_height(p_md, &ex);
998         hr = exception_bridge(&ex);
999     }
1000     return hr;
1001 };
1002
1003 STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
1004 {
1005     if( NULL == aspect )
1006         return E_POINTER;
1007
1008     libvlc_media_player_t *p_md;
1009     HRESULT hr = getMD(&p_md);
1010     if( SUCCEEDED(hr) )
1011     {
1012         libvlc_exception_t ex;
1013         libvlc_exception_init(&ex);
1014
1015         char *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1016
1017         hr = exception_bridge(&ex);
1018         if( SUCCEEDED(hr) && NULL != psz_aspect )
1019         {
1020             *aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
1021             if( NULL == *aspect )
1022                 hr = E_OUTOFMEMORY;
1023         } else if( NULL == psz_aspect) hr = E_OUTOFMEMORY; // strdup("") failed
1024         free( psz_aspect );
1025     }
1026     return hr;
1027 };
1028
1029 STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
1030 {
1031     if( NULL == aspect )
1032         return E_POINTER;
1033
1034     libvlc_media_player_t *p_md;
1035     HRESULT hr = getMD(&p_md);
1036     if( SUCCEEDED(hr) )
1037     {
1038         libvlc_exception_t ex;
1039         libvlc_exception_init(&ex);
1040
1041         char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
1042         if( NULL == psz_aspect )
1043         {
1044             return E_OUTOFMEMORY;
1045         }
1046
1047         libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
1048
1049         CoTaskMemFree(psz_aspect);
1050         hr = exception_bridge(&ex);
1051     }
1052     return hr;
1053 };
1054
1055 STDMETHODIMP VLCVideo::get_subtitle(long* spu)
1056 {
1057     if( NULL == spu )
1058         return E_POINTER;
1059
1060     libvlc_media_player_t *p_md;
1061     HRESULT hr = getMD(&p_md);
1062     if( SUCCEEDED(hr) )
1063     {
1064         libvlc_exception_t ex;
1065         libvlc_exception_init(&ex);
1066
1067         *spu = libvlc_video_get_spu(p_md, &ex);
1068         hr = exception_bridge(&ex);
1069     }
1070     return hr;
1071 };
1072
1073 STDMETHODIMP VLCVideo::put_subtitle(long spu)
1074 {
1075     libvlc_media_player_t *p_md;
1076     HRESULT hr = getMD(&p_md);
1077     if( SUCCEEDED(hr) )
1078     {
1079         libvlc_exception_t ex;
1080         libvlc_exception_init(&ex);
1081
1082         libvlc_video_set_spu(p_md, spu, &ex);
1083         hr = exception_bridge(&ex);
1084     }
1085     return hr;
1086 };
1087
1088 STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
1089 {
1090     if( NULL == geometry )
1091         return E_POINTER;
1092
1093     libvlc_media_player_t *p_md;
1094     HRESULT hr = getMD(&p_md);
1095     if( SUCCEEDED(hr) )
1096     {
1097         libvlc_exception_t ex;
1098         libvlc_exception_init(&ex);
1099
1100         char *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1101
1102         hr = exception_bridge(&ex);
1103         if( SUCCEEDED(&ex) && NULL != psz_geometry )
1104         {
1105             *geometry = BSTRFromCStr(CP_UTF8, psz_geometry);
1106             if( NULL == geometry ) hr = E_OUTOFMEMORY;
1107         } else if( NULL == psz_geometry ) hr = E_OUTOFMEMORY;
1108         free( psz_geometry );
1109     }
1110     return hr;
1111 };
1112
1113 STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
1114 {
1115     if( NULL == geometry )
1116         return E_POINTER;
1117
1118     if( 0 == SysStringLen(geometry) )
1119         return E_INVALIDARG;
1120
1121     libvlc_media_player_t *p_md;
1122     HRESULT hr = getMD(&p_md);
1123     if( SUCCEEDED(hr) )
1124     {
1125         libvlc_exception_t ex;
1126         libvlc_exception_init(&ex);
1127
1128         char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
1129         if( NULL == psz_geometry )
1130         {
1131             return E_OUTOFMEMORY;
1132         }
1133
1134         libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
1135
1136         CoTaskMemFree(psz_geometry);
1137         hr = exception_bridge(&ex);
1138     }
1139     return hr;
1140 };
1141
1142 STDMETHODIMP VLCVideo::get_teletext(long* page)
1143 {
1144     if( NULL == page )
1145         return E_POINTER;
1146
1147     libvlc_media_player_t *p_md;
1148     HRESULT hr = getMD(&p_md);
1149 #if 0
1150     if( SUCCEEDED(hr) )
1151     {
1152         libvlc_exception_t ex;
1153         libvlc_exception_init(&ex);
1154
1155         *page = libvlc_video_get_teletext(p_md);
1156         hr = exception_bridge(&ex);
1157     }
1158 #endif
1159     return hr;
1160 };
1161
1162 STDMETHODIMP VLCVideo::put_teletext(long page)
1163 {
1164 #warning Broken
1165     libvlc_media_player_t *p_md;
1166     HRESULT hr = getMD(&p_md);
1167 #if 0
1168     if( SUCCEEDED(hr) )
1169     {
1170         libvlc_exception_t ex;
1171         libvlc_exception_init(&ex);
1172
1173         libvlc_video_set_teletext(p_md, page);
1174         hr = exception_bridge(&ex);
1175     }
1176 #endif
1177     return hr;
1178 };
1179
1180 STDMETHODIMP VLCVideo::deinterlaceDisable()
1181 {
1182     libvlc_media_player_t *p_md;
1183     HRESULT hr = getMD(&p_md);
1184     if( SUCCEEDED(hr) )
1185     {
1186         libvlc_exception_t ex;
1187         libvlc_exception_init(&ex);
1188
1189         libvlc_video_set_deinterlace(p_md, 0, "", &ex);
1190         hr = exception_bridge(&ex);
1191     }
1192     return hr;
1193 };
1194
1195 STDMETHODIMP VLCVideo::deinterlaceEnable(BSTR mode)
1196 {
1197     libvlc_media_player_t *p_md;
1198     HRESULT hr = getMD(&p_md);
1199     if( SUCCEEDED(hr) )
1200     {
1201         libvlc_exception_t ex;
1202         libvlc_exception_init(&ex);
1203         /* get deinterlace mode from the user */
1204         char *psz_mode = CStrFromBSTR(CP_UTF8, mode);
1205         /* enable deinterlace filter if possible */
1206         libvlc_video_set_deinterlace(p_md, 1, psz_mode, &ex);
1207         hr = exception_bridge(&ex);
1208         CoTaskMemFree(psz_mode);
1209     }
1210     return hr;
1211 };
1212
1213 STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
1214 {
1215     if( NULL == picture )
1216         return E_POINTER;
1217
1218     libvlc_media_player_t *p_md;
1219     HRESULT hr = getMD(&p_md);
1220     if( SUCCEEDED(hr) )
1221     {
1222         libvlc_exception_t ex;
1223         libvlc_exception_init(&ex);
1224
1225         static int uniqueId = 0;
1226         TCHAR path[MAX_PATH+1];
1227
1228         int pathlen = GetTempPath(MAX_PATH-24, path);
1229         if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
1230             return E_FAIL;
1231
1232         /* check temp directory path by openning it */
1233         {
1234             HANDLE dirHandle = CreateFile(path, GENERIC_READ,
1235                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1236                        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1237             if( INVALID_HANDLE_VALUE == dirHandle )
1238             {
1239                 Instance()->setErrorInfo(IID_IVLCVideo,
1240                         "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1241                 return E_FAIL;
1242             }
1243             else
1244             {
1245                 BY_HANDLE_FILE_INFORMATION bhfi;
1246                 BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
1247                 CloseHandle(dirHandle);
1248                 if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
1249                 {
1250                     Instance()->setErrorInfo(IID_IVLCVideo,
1251                             "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1252                     return E_FAIL;
1253                 }
1254             }
1255         }
1256
1257         TCHAR filepath[MAX_PATH+1];
1258
1259         _stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
1260                  path, GetCurrentProcessId(), ++uniqueId);
1261
1262 #ifdef _UNICODE
1263         /* reuse path storage for UTF8 string */
1264         char *psz_filepath = (char *)path;
1265         WCHAR* wpath = filepath;
1266 #else
1267         char *psz_filepath = path;
1268         /* first convert to unicode using current code page */
1269         WCHAR wpath[MAX_PATH+1];
1270         if( 0 == MultiByteToWideChar(CP_ACP, 0, filepath, -1,
1271                                      wpath, sizeof(wpath)/sizeof(WCHAR)) )
1272             return E_FAIL;
1273 #endif
1274         /* convert to UTF8 */
1275         pathlen = WideCharToMultiByte(CP_UTF8, 0, wpath, -1,
1276                                       psz_filepath, sizeof(path), NULL, NULL);
1277         // fail if path is 0 or too short (i.e pathlen is the same as
1278         // storage size)
1279
1280         if( (0 == pathlen) || (sizeof(path) == pathlen) )
1281             return E_FAIL;
1282
1283         /* take snapshot into file */
1284         libvlc_video_take_snapshot(p_md, psz_filepath, 0, 0, &ex);
1285         hr = exception_bridge(&ex);
1286         if( SUCCEEDED(hr) )
1287         {
1288             /* open snapshot file */
1289             HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP, 0, 0,
1290                                        LR_CREATEDIBSECTION|LR_LOADFROMFILE);
1291             if( snapPic )
1292             {
1293                 PICTDESC snapDesc;
1294
1295                 snapDesc.cbSizeofstruct = sizeof(PICTDESC);
1296                 snapDesc.picType        = PICTYPE_BITMAP;
1297                 snapDesc.bmp.hbitmap    = (HBITMAP)snapPic;
1298                 snapDesc.bmp.hpal       = NULL;
1299
1300                 hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp,
1301                                               TRUE, (LPVOID*)picture);
1302                 if( FAILED(hr) )
1303                 {
1304                     *picture = NULL;
1305                     DeleteObject(snapPic);
1306                 }
1307             }
1308             DeleteFile(filepath);
1309         }
1310     }
1311     return hr;
1312 };
1313
1314 STDMETHODIMP VLCVideo::toggleFullscreen()
1315 {
1316     libvlc_media_player_t *p_md;
1317     HRESULT hr = getMD(&p_md);
1318     if( SUCCEEDED(hr) )
1319     {
1320         libvlc_exception_t ex;
1321         libvlc_exception_init(&ex);
1322
1323         libvlc_toggle_fullscreen(p_md, &ex);
1324         hr = exception_bridge(&ex);
1325     }
1326     return hr;
1327 };
1328
1329 STDMETHODIMP VLCVideo::toggleTeletext()
1330 {
1331     libvlc_media_player_t *p_md;
1332     HRESULT hr = getMD(&p_md);
1333     if( SUCCEEDED(hr) )
1334     {
1335         libvlc_exception_t ex;
1336         libvlc_exception_init(&ex);
1337
1338         libvlc_toggle_teletext(p_md, &ex);
1339         hr = exception_bridge(&ex);
1340     }
1341     return hr;
1342 };
1343
1344 STDMETHODIMP VLCVideo::get_marquee(IVLCMarquee** obj)
1345 {
1346     return object_get(obj,_p_vlcmarquee);
1347 }
1348
1349 STDMETHODIMP VLCVideo::get_logo(IVLCLogo** obj)
1350 {
1351     return object_get(obj,_p_vlclogo);
1352 }
1353
1354
1355 /****************************************************************************/
1356
1357 HRESULT VLCLogo::do_put_int(unsigned idx, LONG val)
1358 {
1359     libvlc_media_player_t *p_md;
1360     HRESULT hr = getMD(&p_md);
1361     if( SUCCEEDED(hr) )
1362     {
1363         libvlc_exception_t ex;
1364         libvlc_exception_init(&ex);
1365         libvlc_video_set_logo_int(p_md, idx, val, &ex);
1366         hr = exception_bridge(&ex);
1367     }
1368     return hr;
1369 }
1370
1371 HRESULT VLCLogo::do_get_int(unsigned idx, LONG *val)
1372 {
1373     if( NULL == val )
1374         return E_POINTER;
1375
1376     libvlc_media_player_t *p_md;
1377     HRESULT hr = getMD(&p_md);
1378     if( SUCCEEDED(hr) )
1379     {
1380         libvlc_exception_t ex;
1381         libvlc_exception_init(&ex);
1382         *val = libvlc_video_get_logo_int(p_md, idx, &ex);
1383         hr = exception_bridge(&ex);
1384     }
1385     return hr;
1386 }
1387
1388 STDMETHODIMP VLCLogo::file(BSTR fname)
1389 {
1390     libvlc_media_player_t *p_md;
1391     HRESULT hr = getMD(&p_md);
1392
1393     char *n = CStrFromBSTR(CP_UTF8, fname);
1394     if( !n ) hr = E_OUTOFMEMORY;
1395
1396     if( SUCCEEDED(hr) )
1397     {
1398         libvlc_exception_t ex;
1399         libvlc_exception_init(&ex);
1400         libvlc_video_set_logo_string(p_md, libvlc_logo_file, n, &ex);
1401         hr = exception_bridge(&ex);
1402     }
1403
1404     CoTaskMemFree(n);
1405     return hr;
1406 }
1407
1408 STDMETHODIMP VLCLogo::get_position(BSTR* val)
1409 {
1410     if( NULL == val )
1411         return E_POINTER;
1412
1413     LONG i;
1414     HRESULT hr = do_get_int(libvlc_logo_position, &i);
1415
1416     if(SUCCEEDED(hr))
1417         *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
1418
1419     return hr;
1420 }
1421
1422 STDMETHODIMP VLCLogo::put_position(BSTR val)
1423 {
1424     char *n = CStrFromBSTR(CP_UTF8, val);
1425     if( !n ) return E_OUTOFMEMORY;
1426
1427     size_t i;
1428     HRESULT hr;
1429     if( position_byname( n, i ) )
1430         hr = do_put_int(libvlc_logo_position,i);
1431     else
1432         hr = E_INVALIDARG;
1433
1434     CoTaskMemFree(n);
1435     return hr;
1436 }
1437
1438 /****************************************************************************/
1439
1440 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
1441     _p_instance(p_instance),
1442     _p_typeinfo(NULL),
1443     _p_vlcaudio(new VLCAudio(p_instance)),
1444     _p_vlcinput(new VLCInput(p_instance)),
1445     _p_vlcplaylist(new VLCPlaylist(p_instance)),
1446     _p_vlcsubtitle(new VLCSubtitle(p_instance)),
1447     _p_vlcvideo(new VLCVideo(p_instance))
1448 {
1449 }
1450
1451 VLCControl2::~VLCControl2()
1452 {
1453     delete _p_vlcvideo;
1454     delete _p_vlcsubtitle;
1455     delete _p_vlcplaylist;
1456     delete _p_vlcinput;
1457     delete _p_vlcaudio;
1458     if( _p_typeinfo )
1459         _p_typeinfo->Release();
1460 };
1461
1462 HRESULT VLCControl2::loadTypeInfo(void)
1463 {
1464     HRESULT hr = NOERROR;
1465     if( NULL == _p_typeinfo )
1466     {
1467         ITypeLib *p_typelib;
1468
1469         hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1470         if( SUCCEEDED(hr) )
1471         {
1472             hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
1473             if( FAILED(hr) )
1474             {
1475                 _p_typeinfo = NULL;
1476             }
1477             p_typelib->Release();
1478         }
1479     }
1480     return hr;
1481 };
1482
1483 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
1484 {
1485     if( NULL == pctInfo )
1486         return E_INVALIDARG;
1487
1488     if( SUCCEEDED(loadTypeInfo()) )
1489         *pctInfo = 1;
1490     else
1491         *pctInfo = 0;
1492
1493     return NOERROR;
1494 };
1495
1496 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1497 {
1498     if( NULL == ppTInfo )
1499         return E_INVALIDARG;
1500
1501     if( SUCCEEDED(loadTypeInfo()) )
1502     {
1503         _p_typeinfo->AddRef();
1504         *ppTInfo = _p_typeinfo;
1505         return NOERROR;
1506     }
1507     *ppTInfo = NULL;
1508     return E_NOTIMPL;
1509 };
1510
1511 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1512         UINT cNames, LCID lcid, DISPID* rgDispID)
1513 {
1514     if( SUCCEEDED(loadTypeInfo()) )
1515     {
1516         return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1517     }
1518     return E_NOTIMPL;
1519 };
1520
1521 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
1522         LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1523         VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1524 {
1525     if( SUCCEEDED(loadTypeInfo()) )
1526     {
1527         return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1528                 pVarResult, pExcepInfo, puArgErr);
1529     }
1530     return E_NOTIMPL;
1531 };
1532
1533 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
1534 {
1535     if( NULL == autoloop )
1536         return E_POINTER;
1537
1538     *autoloop = varbool( _p_instance->getAutoLoop() );
1539     return S_OK;
1540 };
1541
1542 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
1543 {
1544     _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
1545     return S_OK;
1546 };
1547
1548 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
1549 {
1550     if( NULL == autoplay )
1551         return E_POINTER;
1552
1553     *autoplay = varbool( _p_instance->getAutoPlay() );
1554     return S_OK;
1555 };
1556
1557 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
1558 {
1559     _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
1560     return S_OK;
1561 };
1562
1563 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
1564 {
1565     if( NULL == url )
1566         return E_POINTER;
1567
1568     *url = SysAllocStringLen(_p_instance->getBaseURL(),
1569                 SysStringLen(_p_instance->getBaseURL()));
1570     return NOERROR;
1571 };
1572
1573 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
1574 {
1575     _p_instance->setBaseURL(mrl);
1576
1577     return S_OK;
1578 };
1579
1580 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
1581 {
1582     if( NULL == mrl )
1583         return E_POINTER;
1584
1585     *mrl = SysAllocStringLen(_p_instance->getMRL(),
1586                 SysStringLen(_p_instance->getMRL()));
1587     return NOERROR;
1588 };
1589
1590 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
1591 {
1592     _p_instance->setMRL(mrl);
1593
1594     return S_OK;
1595 };
1596
1597
1598 STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
1599 {
1600     if( NULL == visible )
1601         return E_POINTER;
1602
1603     /*
1604      * Note to developers
1605      *
1606      * Returning the _b_toolbar is closer to the method specification.
1607      * But returning True when toolbar is not implemented so not displayed
1608      * could be bad for ActiveX users which rely on this value to show their
1609      * own toolbar if not provided by the ActiveX.
1610      *
1611      * This is the reason why FALSE is returned, until toolbar get implemented.
1612      */
1613
1614     /* DISABLED for now */
1615     //  *visible = varbool( _p_instance->getShowToolbar() );
1616
1617     *visible = VARIANT_FALSE;
1618
1619     return S_OK;
1620 };
1621
1622 STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
1623 {
1624     _p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
1625     return S_OK;
1626 };
1627
1628
1629 STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
1630 {
1631     if( NULL == seconds )
1632         return E_POINTER;
1633
1634     *seconds = _p_instance->getStartTime();
1635
1636     return S_OK;
1637 };
1638
1639 STDMETHODIMP VLCControl2::put_StartTime(long seconds)
1640 {
1641     _p_instance->setStartTime(seconds);
1642
1643     return NOERROR;
1644 };
1645
1646 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
1647 {
1648     if( NULL == version )
1649         return E_POINTER;
1650
1651     const char *versionStr = libvlc_get_version();
1652     if( NULL != versionStr )
1653     {
1654         *version = BSTRFromCStr(CP_UTF8, versionStr);
1655
1656         return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
1657     }
1658     *version = NULL;
1659     return E_FAIL;
1660 };
1661
1662 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
1663 {
1664     if( NULL == isVisible )
1665         return E_POINTER;
1666
1667     *isVisible = varbool( _p_instance->getVisible() );
1668
1669     return NOERROR;
1670 };
1671
1672 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
1673 {
1674     _p_instance->setVisible(isVisible != VARIANT_FALSE);
1675
1676     return NOERROR;
1677 };
1678
1679 STDMETHODIMP VLCControl2::get_Volume(long *volume)
1680 {
1681     if( NULL == volume )
1682         return E_POINTER;
1683
1684     *volume  = _p_instance->getVolume();
1685     return NOERROR;
1686 };
1687
1688 STDMETHODIMP VLCControl2::put_Volume(long volume)
1689 {
1690     _p_instance->setVolume(volume);
1691     return NOERROR;
1692 };
1693
1694 STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
1695 {
1696     if( NULL == backcolor )
1697         return E_POINTER;
1698
1699     *backcolor  = _p_instance->getBackColor();
1700     return NOERROR;
1701 };
1702
1703 STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
1704 {
1705     _p_instance->setBackColor(backcolor);
1706     return NOERROR;
1707 };
1708
1709 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
1710 {
1711     return object_get(obj,_p_vlcaudio);
1712 }
1713
1714 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
1715 {
1716     return object_get(obj,_p_vlcinput);
1717 }
1718
1719 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
1720 {
1721     return object_get(obj,_p_vlcplaylist);
1722 }
1723
1724 STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
1725 {
1726     return object_get(obj,_p_vlcsubtitle);
1727 }
1728
1729 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
1730 {
1731     return object_get(obj,_p_vlcvideo);
1732 }