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