1 /*****************************************************************************
2 * vlccontrol2.cpp: ActiveX control for VLC
3 *****************************************************************************
4 * Copyright (C) 2006 the VideoLAN team
5 * Copyright (C) 2010 M2X BV
7 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8 * Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
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.
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.
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 *****************************************************************************/
32 #include "vlccontrol2.h"
33 #include "vlccontrol.h"
39 HRESULT VLCInterfaceBase::report_exception(REFIID riid, libvlc_exception_t *ex)
41 _plug->setErrorInfo(riid,libvlc_errmsg());
42 libvlc_exception_clear(ex);
46 HRESULT VLCInterfaceBase::loadTypeInfo(REFIID riid)
48 // if( _ti ) return NOERROR; // unnecessairy
51 HRESULT hr = _plug->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
54 hr = p_typelib->GetTypeInfoOfGuid(riid, &_ti);
55 if( FAILED(hr) ) _ti = NULL;
61 #define BIND_INTERFACE( class ) \
62 template<> REFIID VLCInterface<class, I##class>::_riid = IID_I##class;
64 BIND_INTERFACE( VLCAudio )
65 BIND_INTERFACE( VLCInput )
66 BIND_INTERFACE( VLCMarquee )
67 BIND_INTERFACE( VLCLogo )
68 BIND_INTERFACE( VLCDeinterlace )
69 BIND_INTERFACE( VLCPlaylistItems )
70 BIND_INTERFACE( VLCPlaylist )
71 BIND_INTERFACE( VLCVideo )
72 BIND_INTERFACE( VLCSubtitle )
76 template<class I> static inline
77 HRESULT object_get(I **dst, I *src)
92 VARIANT_BOOL varbool(bool b) { return b ? VARIANT_TRUE : VARIANT_FALSE; }
96 STDMETHODIMP VLCAudio::get_mute(VARIANT_BOOL* mute)
101 libvlc_instance_t* p_libvlc;
102 HRESULT hr = getVLC(&p_libvlc);
104 *mute = varbool( libvlc_audio_get_mute(p_libvlc) );
108 STDMETHODIMP VLCAudio::put_mute(VARIANT_BOOL mute)
110 libvlc_instance_t* p_libvlc;
111 HRESULT hr = getVLC(&p_libvlc);
113 libvlc_audio_set_mute(p_libvlc, VARIANT_FALSE != mute);
117 STDMETHODIMP VLCAudio::get_volume(long* volume)
122 libvlc_instance_t* p_libvlc;
123 HRESULT hr = getVLC(&p_libvlc);
125 *volume = libvlc_audio_get_volume(p_libvlc);
129 STDMETHODIMP VLCAudio::put_volume(long volume)
131 libvlc_instance_t* p_libvlc;
132 HRESULT hr = getVLC(&p_libvlc);
135 libvlc_exception_t ex;
136 libvlc_exception_init(&ex);
138 libvlc_audio_set_volume(p_libvlc, volume, &ex);
139 hr = exception_bridge(&ex);
144 STDMETHODIMP VLCAudio::get_track(long* track)
149 libvlc_media_player_t* p_md;
150 HRESULT hr = getMD(&p_md);
153 libvlc_exception_t ex;
154 libvlc_exception_init(&ex);
156 *track = libvlc_audio_get_track(p_md, &ex);
157 hr = exception_bridge(&ex);
162 STDMETHODIMP VLCAudio::put_track(long track)
164 libvlc_media_player_t *p_md;
165 HRESULT hr = getMD(&p_md);
168 libvlc_exception_t ex;
169 libvlc_exception_init(&ex);
171 libvlc_audio_set_track(p_md, track, &ex);
172 hr = exception_bridge(&ex);
177 STDMETHODIMP VLCAudio::get_count(long* trackNumber)
179 if( NULL == trackNumber )
182 libvlc_media_player_t* p_md;
183 HRESULT hr = getMD(&p_md);
186 libvlc_exception_t ex;
187 libvlc_exception_init(&ex);
188 // get the number of audio track available and return it
189 *trackNumber = libvlc_audio_get_track_count(p_md, &ex);
190 hr = exception_bridge(&ex);
196 STDMETHODIMP VLCAudio::description(long trackID, BSTR* name)
201 libvlc_media_player_t* p_md;
202 libvlc_exception_t ex;
203 libvlc_exception_init(&ex);
205 HRESULT hr = getMD(&p_md);
209 const char *psz_name;
210 libvlc_track_description_t *p_trackDesc;
212 // get tracks description
213 p_trackDesc = libvlc_audio_get_track_description(p_md, &ex);
214 hr = exception_bridge(&ex);
218 //get the number of available track
219 i_limit = libvlc_audio_get_track_count(p_md, &ex);
220 hr = exception_bridge(&ex);
224 // check if the number given is a good one
225 if ( ( trackID > ( i_limit -1 ) ) || ( trackID < 0 ) )
228 // get the good trackDesc
229 for( i = 0 ; i < trackID ; i++ )
231 p_trackDesc = p_trackDesc->p_next;
233 // get the track name
234 psz_name = p_trackDesc->psz_name;
237 if( psz_name != NULL )
239 *name = BSTRFromCStr(CP_UTF8, psz_name);
240 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
248 STDMETHODIMP VLCAudio::get_channel(long *channel)
250 if( NULL == channel )
253 libvlc_instance_t* p_libvlc;
254 HRESULT hr = getVLC(&p_libvlc);
257 libvlc_exception_t ex;
258 libvlc_exception_init(&ex);
260 *channel = libvlc_audio_get_channel(p_libvlc, &ex);
261 hr = exception_bridge(&ex);
266 STDMETHODIMP VLCAudio::put_channel(long channel)
268 libvlc_instance_t* p_libvlc;
269 HRESULT hr = getVLC(&p_libvlc);
272 libvlc_exception_t ex;
273 libvlc_exception_init(&ex);
275 libvlc_audio_set_channel(p_libvlc, channel, &ex);
276 hr = exception_bridge(&ex);
281 STDMETHODIMP VLCAudio::toggleMute()
283 libvlc_instance_t* p_libvlc;
284 HRESULT hr = getVLC(&p_libvlc);
286 libvlc_audio_toggle_mute(p_libvlc);
290 /****************************************************************************/
292 STDMETHODIMP VLCDeinterlace::disable()
294 libvlc_media_player_t *p_md;
295 HRESULT hr = getMD(&p_md);
298 libvlc_exception_t ex;
299 libvlc_exception_init(&ex);
301 libvlc_video_set_deinterlace(p_md, 0, "", &ex);
302 hr = exception_bridge(&ex);
307 STDMETHODIMP VLCDeinterlace::enable(BSTR mode)
309 libvlc_media_player_t *p_md;
310 HRESULT hr = getMD(&p_md);
313 libvlc_exception_t ex;
314 libvlc_exception_init(&ex);
315 char *psz_mode = CStrFromBSTR(CP_UTF8, mode);
316 libvlc_video_set_deinterlace(p_md, 1, psz_mode, &ex);
317 CoTaskMemFree(psz_mode);
318 hr = exception_bridge(&ex);
323 /****************************************************************************/
325 STDMETHODIMP VLCInput::get_length(double* length)
331 libvlc_media_player_t *p_md;
332 HRESULT hr = getMD(&p_md);
335 libvlc_exception_t ex;
336 libvlc_exception_init(&ex);
338 *length = (double)libvlc_media_player_get_length(p_md, &ex);
339 hr = exception_bridge(&ex);
344 STDMETHODIMP VLCInput::get_position(double* position)
346 if( NULL == position )
350 libvlc_media_player_t *p_md;
351 HRESULT hr = getMD(&p_md);
354 libvlc_exception_t ex;
355 libvlc_exception_init(&ex);
357 *position = libvlc_media_player_get_position(p_md, &ex);
358 hr = exception_bridge(&ex);
363 STDMETHODIMP VLCInput::put_position(double position)
365 libvlc_media_player_t *p_md;
366 HRESULT hr = getMD(&p_md);
369 libvlc_exception_t ex;
370 libvlc_exception_init(&ex);
372 libvlc_media_player_set_position(p_md, position, &ex);
373 hr = exception_bridge(&ex);
378 STDMETHODIMP VLCInput::get_time(double* time)
383 libvlc_media_player_t *p_md;
384 HRESULT hr = getMD(&p_md);
387 libvlc_exception_t ex;
388 libvlc_exception_init(&ex);
390 *time = (double)libvlc_media_player_get_time(p_md, &ex);
391 hr = exception_bridge(&ex);
396 STDMETHODIMP VLCInput::put_time(double time)
398 libvlc_media_player_t *p_md;
399 HRESULT hr = getMD(&p_md);
402 libvlc_exception_t ex;
403 libvlc_exception_init(&ex);
405 libvlc_media_player_set_time(p_md, (int64_t)time, &ex);
406 hr = exception_bridge(&ex);
411 STDMETHODIMP VLCInput::get_state(long* state)
416 libvlc_media_player_t *p_md;
417 HRESULT hr = getMD(&p_md);
420 libvlc_exception_t ex;
421 libvlc_exception_init(&ex);
423 *state = libvlc_media_player_get_state(p_md);
424 if( libvlc_exception_raised(&ex) )
426 // don't fail, just return the idle state
428 libvlc_exception_clear(&ex);
434 STDMETHODIMP VLCInput::get_rate(double* rate)
439 libvlc_media_player_t *p_md;
440 HRESULT hr = getMD(&p_md);
443 libvlc_exception_t ex;
444 libvlc_exception_init(&ex);
446 *rate = libvlc_media_player_get_rate(p_md, &ex);
447 hr = exception_bridge(&ex);
452 STDMETHODIMP VLCInput::put_rate(double rate)
454 libvlc_media_player_t *p_md;
455 HRESULT hr = getMD(&p_md);
458 libvlc_exception_t ex;
459 libvlc_exception_init(&ex);
461 libvlc_media_player_set_rate(p_md, rate, &ex);
462 hr = exception_bridge(&ex);
467 STDMETHODIMP VLCInput::get_fps(double* fps)
473 libvlc_media_player_t *p_md;
474 HRESULT hr = getMD(&p_md);
477 libvlc_exception_t ex;
478 libvlc_exception_init(&ex);
480 *fps = libvlc_media_player_get_fps(p_md, &ex);
481 hr = exception_bridge(&ex);
486 STDMETHODIMP VLCInput::get_hasVout(VARIANT_BOOL* hasVout)
488 if( NULL == hasVout )
491 libvlc_media_player_t *p_md;
492 HRESULT hr = getMD(&p_md);
495 libvlc_exception_t ex;
496 libvlc_exception_init(&ex);
498 *hasVout = varbool( libvlc_media_player_has_vout(p_md, &ex) );
499 hr = exception_bridge(&ex);
504 /****************************************************************************/
506 HRESULT VLCMarquee::do_put_int(unsigned idx, LONG val)
508 libvlc_media_player_t *p_md;
509 HRESULT hr = getMD(&p_md);
512 libvlc_exception_t ex;
513 libvlc_exception_init(&ex);
514 libvlc_video_set_marquee_int(p_md, idx, val, &ex);
515 hr = exception_bridge(&ex);
520 HRESULT VLCMarquee::do_get_int(unsigned idx, LONG *val)
525 libvlc_media_player_t *p_md;
526 HRESULT hr = getMD(&p_md);
529 libvlc_exception_t ex;
530 libvlc_exception_init(&ex);
531 *val = libvlc_video_get_marquee_int(p_md, idx, &ex);
532 hr = exception_bridge(&ex);
537 STDMETHODIMP VLCMarquee::get_position(BSTR* val)
543 HRESULT hr = do_get_int(libvlc_marquee_Position, &i);
546 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
551 STDMETHODIMP VLCMarquee::put_position(BSTR val)
553 char *n = CStrFromBSTR(CP_UTF8, val);
554 if( !n ) return E_OUTOFMEMORY;
558 if( position_byname( n, i ) )
559 hr = do_put_int(libvlc_marquee_Position,i);
567 STDMETHODIMP VLCMarquee::get_text(BSTR *val)
573 libvlc_media_player_t *p_md;
574 HRESULT hr = getMD(&p_md);
577 libvlc_exception_t ex;
578 libvlc_exception_init(&ex);
580 psz = libvlc_video_get_marquee_string(p_md, libvlc_marquee_Text, &ex);
582 hr = exception_bridge(&ex);
584 *val = BSTRFromCStr(CP_UTF8, psz);
589 STDMETHODIMP VLCMarquee::put_text(BSTR val)
591 libvlc_media_player_t *p_md;
592 HRESULT hr = getMD(&p_md);
595 libvlc_exception_t ex;
596 libvlc_exception_init(&ex);
598 char *psz_text = CStrFromBSTR(CP_UTF8, val);
599 libvlc_video_set_marquee_string(p_md, libvlc_marquee_Text,
601 hr = exception_bridge(&ex);
602 CoTaskMemFree(psz_text);
607 /****************************************************************************/
609 STDMETHODIMP VLCPlaylistItems::get_count(long* count)
614 libvlc_exception_t ex;
615 libvlc_exception_init(&ex);
617 *count = Instance()->playlist_count(&ex);
618 return exception_bridge(&ex);
621 STDMETHODIMP VLCPlaylistItems::clear()
623 libvlc_exception_t ex;
624 libvlc_exception_init(&ex);
626 Instance()->playlist_clear(&ex);
627 return exception_bridge(&ex);
630 STDMETHODIMP VLCPlaylistItems::remove(long item)
632 libvlc_instance_t* p_libvlc;
633 HRESULT hr = getVLC(&p_libvlc);
636 libvlc_exception_t ex;
637 libvlc_exception_init(&ex);
639 Instance()->playlist_delete_item(item, &ex);
640 hr = exception_bridge(&ex);
645 /****************************************************************************/
647 STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
653 libvlc_exception_t ex;
654 libvlc_exception_init(&ex);
656 *count = Instance()->playlist_count(&ex);
657 return exception_bridge(&ex);
660 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
662 if( NULL == isPlaying )
665 libvlc_media_player_t *p_md;
666 HRESULT hr = getMD(&p_md);
669 libvlc_exception_t ex;
670 libvlc_exception_init(&ex);
672 *isPlaying = varbool( libvlc_media_player_is_playing(p_md) );
673 libvlc_exception_clear(&ex);
678 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
683 if( 0 == SysStringLen(uri) )
686 libvlc_instance_t* p_libvlc;
687 HRESULT hr = getVLC(&p_libvlc);
690 libvlc_exception_t ex;
691 libvlc_exception_init(&ex);
693 char *psz_uri = NULL;
694 if( SysStringLen(Instance()->getBaseURL()) > 0 )
697 ** if the MRL a relative URL, we should end up with an absolute URL
699 LPWSTR abs_url = CombineURL(Instance()->getBaseURL(), uri);
700 if( NULL != abs_url )
702 psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
703 CoTaskMemFree(abs_url);
707 psz_uri = CStrFromBSTR(CP_UTF8, uri);
713 ** baseURL is empty, assume MRL is absolute
715 psz_uri = CStrFromBSTR(CP_UTF8, uri);
718 if( NULL == psz_uri )
720 return E_OUTOFMEMORY;
726 hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
729 CoTaskMemFree(psz_uri);
733 char *psz_name = NULL;
735 VariantInit(&v_name);
736 if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
738 if( SysStringLen(V_BSTR(&v_name)) > 0 )
739 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
741 VariantClear(&v_name);
744 *item = Instance()->playlist_add_extended_untrusted(psz_uri,
745 i_options, const_cast<const char **>(ppsz_options), &ex);
747 VLCControl::FreeTargetOptions(ppsz_options, i_options);
748 CoTaskMemFree(psz_uri);
749 if( psz_name ) /* XXX Do we even need to check? */
750 CoTaskMemFree(psz_name);
751 hr = exception_bridge(&ex);
756 STDMETHODIMP VLCPlaylist::play()
758 libvlc_exception_t ex;
759 libvlc_exception_init(&ex);
761 Instance()->playlist_play(&ex);
762 return exception_bridge(&ex);
765 STDMETHODIMP VLCPlaylist::playItem(long item)
767 libvlc_exception_t ex;
768 libvlc_exception_init(&ex);
770 Instance()->playlist_play_item(item,&ex);
771 return exception_bridge(&ex);;
774 STDMETHODIMP VLCPlaylist::togglePause()
776 libvlc_media_player_t* p_md;
777 HRESULT hr = getMD(&p_md);
780 libvlc_exception_t ex;
781 libvlc_exception_init(&ex);
783 libvlc_media_player_pause(p_md, &ex);
784 hr = exception_bridge(&ex);;
789 STDMETHODIMP VLCPlaylist::stop()
791 libvlc_media_player_t *p_md;
792 HRESULT hr = getMD(&p_md);
795 libvlc_exception_t ex;
796 libvlc_exception_init(&ex);
798 libvlc_media_player_stop(p_md);
799 hr = exception_bridge(&ex);;
804 STDMETHODIMP VLCPlaylist::next()
806 libvlc_exception_t ex;
807 libvlc_exception_init(&ex);
809 Instance()->playlist_next(&ex);
810 return exception_bridge(&ex);;
813 STDMETHODIMP VLCPlaylist::prev()
815 libvlc_exception_t ex;
816 libvlc_exception_init(&ex);
818 Instance()->playlist_prev(&ex);
819 return exception_bridge(&ex);;
822 STDMETHODIMP VLCPlaylist::clear()
824 libvlc_exception_t ex;
825 libvlc_exception_init(&ex);
827 Instance()->playlist_clear(&ex);
828 return exception_bridge(&ex);;
831 STDMETHODIMP VLCPlaylist::removeItem(long item)
833 libvlc_instance_t* p_libvlc;
834 HRESULT hr = getVLC(&p_libvlc);
837 libvlc_exception_t ex;
838 libvlc_exception_init(&ex);
840 Instance()->playlist_delete_item(item, &ex);
841 hr = exception_bridge(&ex);;
846 STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
851 *obj = _p_vlcplaylistitems;
852 if( NULL != _p_vlcplaylistitems )
854 _p_vlcplaylistitems->AddRef();
857 return E_OUTOFMEMORY;
860 /****************************************************************************/
862 STDMETHODIMP VLCSubtitle::get_track(long* spu)
867 libvlc_media_player_t *p_md;
868 HRESULT hr = getMD(&p_md);
871 libvlc_exception_t ex;
872 libvlc_exception_init(&ex);
874 *spu = libvlc_video_get_spu(p_md, &ex);
875 hr = exception_bridge(&ex);
880 STDMETHODIMP VLCSubtitle::put_track(long spu)
882 libvlc_media_player_t *p_md;
883 HRESULT hr = getMD(&p_md);
886 libvlc_exception_t ex;
887 libvlc_exception_init(&ex);
889 libvlc_video_set_spu(p_md, spu, &ex);
890 hr = exception_bridge(&ex);
895 STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
897 if( NULL == spuNumber )
900 libvlc_media_player_t *p_md;
901 HRESULT hr = getMD(&p_md);
904 libvlc_exception_t ex;
905 libvlc_exception_init(&ex);
906 // get the number of video subtitle available and return it
907 *spuNumber = libvlc_video_get_spu_count(p_md, &ex);
908 hr = exception_bridge(&ex);
914 STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
919 libvlc_media_player_t* p_md;
920 libvlc_exception_t ex;
921 libvlc_exception_init(&ex);
923 HRESULT hr = getMD(&p_md);
927 const char *psz_name;
928 libvlc_track_description_t *p_spuDesc;
930 // get subtitles description
931 p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
932 hr = exception_bridge(&ex);
936 // get the number of available subtitle
937 i_limit = libvlc_video_get_spu_count(p_md, &ex);
938 hr = exception_bridge(&ex);
942 // check if the number given is a good one
943 if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
946 // get the good spuDesc
947 for( i = 0 ; i < nameID ; i++ )
949 p_spuDesc = p_spuDesc->p_next;
951 // get the subtitle name
952 psz_name = p_spuDesc->psz_name;
955 if( psz_name != NULL )
957 *name = BSTRFromCStr(CP_UTF8, psz_name);
958 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
966 /****************************************************************************/
968 STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
970 if( NULL == fullscreen )
973 libvlc_media_player_t *p_md;
974 HRESULT hr = getMD(&p_md);
977 libvlc_exception_t ex;
978 libvlc_exception_init(&ex);
980 *fullscreen = varbool( libvlc_get_fullscreen(p_md, &ex) );
981 hr = exception_bridge(&ex);
986 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
988 libvlc_media_player_t *p_md;
989 HRESULT hr = getMD(&p_md);
992 libvlc_exception_t ex;
993 libvlc_exception_init(&ex);
995 libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen, &ex);
996 hr = exception_bridge(&ex);
1001 STDMETHODIMP VLCVideo::get_width(long* width)
1006 libvlc_media_player_t *p_md;
1007 HRESULT hr = getMD(&p_md);
1010 libvlc_exception_t ex;
1011 libvlc_exception_init(&ex);
1013 *width = libvlc_video_get_width(p_md, &ex);
1014 hr = exception_bridge(&ex);
1019 STDMETHODIMP VLCVideo::get_height(long* height)
1021 if( NULL == height )
1024 libvlc_media_player_t *p_md;
1025 HRESULT hr = getMD(&p_md);
1028 libvlc_exception_t ex;
1029 libvlc_exception_init(&ex);
1031 *height = libvlc_video_get_height(p_md, &ex);
1032 hr = exception_bridge(&ex);
1037 STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
1039 if( NULL == aspect )
1042 libvlc_media_player_t *p_md;
1043 HRESULT hr = getMD(&p_md);
1046 libvlc_exception_t ex;
1047 libvlc_exception_init(&ex);
1049 char *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1051 hr = exception_bridge(&ex);
1052 if( SUCCEEDED(hr) && NULL != psz_aspect )
1054 *aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
1055 if( NULL == *aspect )
1057 } else if( NULL == psz_aspect) hr = E_OUTOFMEMORY; // strdup("") failed
1063 STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
1065 if( NULL == aspect )
1068 libvlc_media_player_t *p_md;
1069 HRESULT hr = getMD(&p_md);
1072 libvlc_exception_t ex;
1073 libvlc_exception_init(&ex);
1075 char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
1076 if( NULL == psz_aspect )
1078 return E_OUTOFMEMORY;
1081 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
1083 CoTaskMemFree(psz_aspect);
1084 hr = exception_bridge(&ex);
1089 STDMETHODIMP VLCVideo::get_subtitle(long* spu)
1094 libvlc_media_player_t *p_md;
1095 HRESULT hr = getMD(&p_md);
1098 libvlc_exception_t ex;
1099 libvlc_exception_init(&ex);
1101 *spu = libvlc_video_get_spu(p_md, &ex);
1102 hr = exception_bridge(&ex);
1107 STDMETHODIMP VLCVideo::put_subtitle(long spu)
1109 libvlc_media_player_t *p_md;
1110 HRESULT hr = getMD(&p_md);
1113 libvlc_exception_t ex;
1114 libvlc_exception_init(&ex);
1116 libvlc_video_set_spu(p_md, spu, &ex);
1117 hr = exception_bridge(&ex);
1122 STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
1124 if( NULL == geometry )
1127 libvlc_media_player_t *p_md;
1128 HRESULT hr = getMD(&p_md);
1131 libvlc_exception_t ex;
1132 libvlc_exception_init(&ex);
1134 char *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1136 hr = exception_bridge(&ex);
1137 if( SUCCEEDED(&ex) && NULL != psz_geometry )
1139 *geometry = BSTRFromCStr(CP_UTF8, psz_geometry);
1140 if( NULL == geometry ) hr = E_OUTOFMEMORY;
1141 } else if( NULL == psz_geometry ) hr = E_OUTOFMEMORY;
1142 free( psz_geometry );
1147 STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
1149 if( NULL == geometry )
1152 if( 0 == SysStringLen(geometry) )
1153 return E_INVALIDARG;
1155 libvlc_media_player_t *p_md;
1156 HRESULT hr = getMD(&p_md);
1159 libvlc_exception_t ex;
1160 libvlc_exception_init(&ex);
1162 char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
1163 if( NULL == psz_geometry )
1165 return E_OUTOFMEMORY;
1168 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
1170 CoTaskMemFree(psz_geometry);
1171 hr = exception_bridge(&ex);
1176 STDMETHODIMP VLCVideo::get_teletext(long* page)
1181 libvlc_media_player_t *p_md;
1182 HRESULT hr = getMD(&p_md);
1186 libvlc_exception_t ex;
1187 libvlc_exception_init(&ex);
1189 *page = libvlc_video_get_teletext(p_md);
1190 hr = exception_bridge(&ex);
1196 STDMETHODIMP VLCVideo::put_teletext(long page)
1199 libvlc_media_player_t *p_md;
1200 HRESULT hr = getMD(&p_md);
1204 libvlc_exception_t ex;
1205 libvlc_exception_init(&ex);
1207 libvlc_video_set_teletext(p_md, page);
1208 hr = exception_bridge(&ex);
1214 STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
1216 if( NULL == picture )
1219 libvlc_media_player_t *p_md;
1220 HRESULT hr = getMD(&p_md);
1223 libvlc_exception_t ex;
1224 libvlc_exception_init(&ex);
1226 static int uniqueId = 0;
1227 TCHAR path[MAX_PATH+1];
1229 int pathlen = GetTempPath(MAX_PATH-24, path);
1230 if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
1233 /* check temp directory path by openning it */
1235 HANDLE dirHandle = CreateFile(path, GENERIC_READ,
1236 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1237 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1238 if( INVALID_HANDLE_VALUE == dirHandle )
1240 Instance()->setErrorInfo(IID_IVLCVideo,
1241 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1246 BY_HANDLE_FILE_INFORMATION bhfi;
1247 BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
1248 CloseHandle(dirHandle);
1249 if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
1251 Instance()->setErrorInfo(IID_IVLCVideo,
1252 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1258 TCHAR filepath[MAX_PATH+1];
1260 _stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
1261 path, GetCurrentProcessId(), ++uniqueId);
1264 /* reuse path storage for UTF8 string */
1265 char *psz_filepath = (char *)path;
1266 WCHAR* wpath = filepath;
1268 char *psz_filepath = path;
1269 /* first convert to unicode using current code page */
1270 WCHAR wpath[MAX_PATH+1];
1271 if( 0 == MultiByteToWideChar(CP_ACP, 0, filepath, -1,
1272 wpath, sizeof(wpath)/sizeof(WCHAR)) )
1275 /* convert to UTF8 */
1276 pathlen = WideCharToMultiByte(CP_UTF8, 0, wpath, -1,
1277 psz_filepath, sizeof(path), NULL, NULL);
1278 // fail if path is 0 or too short (i.e pathlen is the same as
1281 if( (0 == pathlen) || (sizeof(path) == pathlen) )
1284 /* take snapshot into file */
1285 libvlc_video_take_snapshot(p_md, psz_filepath, 0, 0, &ex);
1286 hr = exception_bridge(&ex);
1289 /* open snapshot file */
1290 HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP, 0, 0,
1291 LR_CREATEDIBSECTION|LR_LOADFROMFILE);
1296 snapDesc.cbSizeofstruct = sizeof(PICTDESC);
1297 snapDesc.picType = PICTYPE_BITMAP;
1298 snapDesc.bmp.hbitmap = (HBITMAP)snapPic;
1299 snapDesc.bmp.hpal = NULL;
1301 hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp,
1302 TRUE, (LPVOID*)picture);
1306 DeleteObject(snapPic);
1309 DeleteFile(filepath);
1315 STDMETHODIMP VLCVideo::toggleFullscreen()
1317 libvlc_media_player_t *p_md;
1318 HRESULT hr = getMD(&p_md);
1321 libvlc_exception_t ex;
1322 libvlc_exception_init(&ex);
1324 libvlc_toggle_fullscreen(p_md, &ex);
1325 hr = exception_bridge(&ex);
1330 STDMETHODIMP VLCVideo::toggleTeletext()
1332 libvlc_media_player_t *p_md;
1333 HRESULT hr = getMD(&p_md);
1336 libvlc_exception_t ex;
1337 libvlc_exception_init(&ex);
1339 libvlc_toggle_teletext(p_md, &ex);
1340 hr = exception_bridge(&ex);
1345 STDMETHODIMP VLCVideo::get_marquee(IVLCMarquee** obj)
1347 return object_get(obj,_p_vlcmarquee);
1350 STDMETHODIMP VLCVideo::get_logo(IVLCLogo** obj)
1352 return object_get(obj,_p_vlclogo);
1355 STDMETHODIMP VLCVideo::get_deinterlace(IVLCDeinterlace** obj)
1357 return object_get(obj,_p_vlcdeint);
1361 /****************************************************************************/
1363 HRESULT VLCLogo::do_put_int(unsigned idx, LONG val)
1365 libvlc_media_player_t *p_md;
1366 HRESULT hr = getMD(&p_md);
1369 libvlc_exception_t ex;
1370 libvlc_exception_init(&ex);
1371 libvlc_video_set_logo_int(p_md, idx, val, &ex);
1372 hr = exception_bridge(&ex);
1377 HRESULT VLCLogo::do_get_int(unsigned idx, LONG *val)
1382 libvlc_media_player_t *p_md;
1383 HRESULT hr = getMD(&p_md);
1386 libvlc_exception_t ex;
1387 libvlc_exception_init(&ex);
1388 *val = libvlc_video_get_logo_int(p_md, idx, &ex);
1389 hr = exception_bridge(&ex);
1394 STDMETHODIMP VLCLogo::file(BSTR fname)
1396 libvlc_media_player_t *p_md;
1397 HRESULT hr = getMD(&p_md);
1399 char *n = CStrFromBSTR(CP_UTF8, fname);
1400 if( !n ) hr = E_OUTOFMEMORY;
1404 libvlc_exception_t ex;
1405 libvlc_exception_init(&ex);
1406 libvlc_video_set_logo_string(p_md, libvlc_logo_file, n, &ex);
1407 hr = exception_bridge(&ex);
1414 STDMETHODIMP VLCLogo::get_position(BSTR* val)
1420 HRESULT hr = do_get_int(libvlc_logo_position, &i);
1423 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
1428 STDMETHODIMP VLCLogo::put_position(BSTR val)
1430 char *n = CStrFromBSTR(CP_UTF8, val);
1431 if( !n ) return E_OUTOFMEMORY;
1435 if( position_byname( n, i ) )
1436 hr = do_put_int(libvlc_logo_position,i);
1444 /****************************************************************************/
1446 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
1447 _p_instance(p_instance),
1449 _p_vlcaudio(new VLCAudio(p_instance)),
1450 _p_vlcinput(new VLCInput(p_instance)),
1451 _p_vlcplaylist(new VLCPlaylist(p_instance)),
1452 _p_vlcsubtitle(new VLCSubtitle(p_instance)),
1453 _p_vlcvideo(new VLCVideo(p_instance))
1457 VLCControl2::~VLCControl2()
1460 delete _p_vlcsubtitle;
1461 delete _p_vlcplaylist;
1465 _p_typeinfo->Release();
1468 HRESULT VLCControl2::loadTypeInfo(void)
1470 HRESULT hr = NOERROR;
1471 if( NULL == _p_typeinfo )
1473 ITypeLib *p_typelib;
1475 hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1478 hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
1483 p_typelib->Release();
1489 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
1491 if( NULL == pctInfo )
1492 return E_INVALIDARG;
1494 if( SUCCEEDED(loadTypeInfo()) )
1502 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1504 if( NULL == ppTInfo )
1505 return E_INVALIDARG;
1507 if( SUCCEEDED(loadTypeInfo()) )
1509 _p_typeinfo->AddRef();
1510 *ppTInfo = _p_typeinfo;
1517 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1518 UINT cNames, LCID lcid, DISPID* rgDispID)
1520 if( SUCCEEDED(loadTypeInfo()) )
1522 return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1527 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
1528 LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1529 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1531 if( SUCCEEDED(loadTypeInfo()) )
1533 return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1534 pVarResult, pExcepInfo, puArgErr);
1539 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
1541 if( NULL == autoloop )
1544 *autoloop = varbool( _p_instance->getAutoLoop() );
1548 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
1550 _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
1554 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
1556 if( NULL == autoplay )
1559 *autoplay = varbool( _p_instance->getAutoPlay() );
1563 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
1565 _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
1569 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
1574 *url = SysAllocStringLen(_p_instance->getBaseURL(),
1575 SysStringLen(_p_instance->getBaseURL()));
1579 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
1581 _p_instance->setBaseURL(mrl);
1586 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
1591 *mrl = SysAllocStringLen(_p_instance->getMRL(),
1592 SysStringLen(_p_instance->getMRL()));
1596 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
1598 _p_instance->setMRL(mrl);
1604 STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
1606 if( NULL == visible )
1610 * Note to developers
1612 * Returning the _b_toolbar is closer to the method specification.
1613 * But returning True when toolbar is not implemented so not displayed
1614 * could be bad for ActiveX users which rely on this value to show their
1615 * own toolbar if not provided by the ActiveX.
1617 * This is the reason why FALSE is returned, until toolbar get implemented.
1620 /* DISABLED for now */
1621 // *visible = varbool( _p_instance->getShowToolbar() );
1623 *visible = VARIANT_FALSE;
1628 STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
1630 _p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
1635 STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
1637 if( NULL == seconds )
1640 *seconds = _p_instance->getStartTime();
1645 STDMETHODIMP VLCControl2::put_StartTime(long seconds)
1647 _p_instance->setStartTime(seconds);
1652 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
1654 if( NULL == version )
1657 const char *versionStr = libvlc_get_version();
1658 if( NULL != versionStr )
1660 *version = BSTRFromCStr(CP_UTF8, versionStr);
1662 return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
1668 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
1670 if( NULL == isVisible )
1673 *isVisible = varbool( _p_instance->getVisible() );
1678 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
1680 _p_instance->setVisible(isVisible != VARIANT_FALSE);
1685 STDMETHODIMP VLCControl2::get_Volume(long *volume)
1687 if( NULL == volume )
1690 *volume = _p_instance->getVolume();
1694 STDMETHODIMP VLCControl2::put_Volume(long volume)
1696 _p_instance->setVolume(volume);
1700 STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
1702 if( NULL == backcolor )
1705 *backcolor = _p_instance->getBackColor();
1709 STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
1711 _p_instance->setBackColor(backcolor);
1715 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
1717 return object_get(obj,_p_vlcaudio);
1720 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
1722 return object_get(obj,_p_vlcinput);
1725 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
1727 return object_get(obj,_p_vlcplaylist);
1730 STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
1732 return object_get(obj,_p_vlcsubtitle);
1735 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
1737 return object_get(obj,_p_vlcvideo);