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( VLCPlaylistItems )
69 BIND_INTERFACE( VLCPlaylist )
70 BIND_INTERFACE( VLCVideo )
71 BIND_INTERFACE( VLCSubtitle )
75 template<class I> static inline
76 HRESULT object_get(I **dst, I *src)
93 STDMETHODIMP VLCAudio::get_mute(VARIANT_BOOL* mute)
98 libvlc_instance_t* p_libvlc;
99 HRESULT hr = getVLC(&p_libvlc);
101 *mute = libvlc_audio_get_mute(p_libvlc) ?
102 VARIANT_TRUE : VARIANT_FALSE;
106 STDMETHODIMP VLCAudio::put_mute(VARIANT_BOOL mute)
108 libvlc_instance_t* p_libvlc;
109 HRESULT hr = getVLC(&p_libvlc);
111 libvlc_audio_set_mute(p_libvlc, VARIANT_FALSE != mute);
115 STDMETHODIMP VLCAudio::get_volume(long* volume)
120 libvlc_instance_t* p_libvlc;
121 HRESULT hr = getVLC(&p_libvlc);
123 *volume = libvlc_audio_get_volume(p_libvlc);
127 STDMETHODIMP VLCAudio::put_volume(long volume)
129 libvlc_instance_t* p_libvlc;
130 HRESULT hr = getVLC(&p_libvlc);
133 libvlc_exception_t ex;
134 libvlc_exception_init(&ex);
136 libvlc_audio_set_volume(p_libvlc, volume, &ex);
137 hr = exception_bridge(&ex);
142 STDMETHODIMP VLCAudio::get_track(long* track)
147 libvlc_media_player_t* p_md;
148 HRESULT hr = getMD(&p_md);
151 libvlc_exception_t ex;
152 libvlc_exception_init(&ex);
154 *track = libvlc_audio_get_track(p_md, &ex);
155 hr = exception_bridge(&ex);
160 STDMETHODIMP VLCAudio::put_track(long track)
162 libvlc_media_player_t *p_md;
163 HRESULT hr = getMD(&p_md);
166 libvlc_exception_t ex;
167 libvlc_exception_init(&ex);
169 libvlc_audio_set_track(p_md, track, &ex);
170 hr = exception_bridge(&ex);
175 STDMETHODIMP VLCAudio::get_count(long* trackNumber)
177 if( NULL == trackNumber )
180 libvlc_media_player_t* p_md;
181 HRESULT hr = getMD(&p_md);
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);
194 STDMETHODIMP VLCAudio::description(long trackID, BSTR* name)
199 libvlc_media_player_t* p_md;
200 libvlc_exception_t ex;
201 libvlc_exception_init(&ex);
203 HRESULT hr = getMD(&p_md);
207 const char *psz_name;
208 libvlc_track_description_t *p_trackDesc;
210 // get tracks description
211 p_trackDesc = libvlc_audio_get_track_description(p_md, &ex);
212 hr = exception_bridge(&ex);
216 //get the number of available track
217 i_limit = libvlc_audio_get_track_count(p_md, &ex);
218 hr = exception_bridge(&ex);
222 // check if the number given is a good one
223 if ( ( trackID > ( i_limit -1 ) ) || ( trackID < 0 ) )
226 // get the good trackDesc
227 for( i = 0 ; i < trackID ; i++ )
229 p_trackDesc = p_trackDesc->p_next;
231 // get the track name
232 psz_name = p_trackDesc->psz_name;
235 if( psz_name != NULL )
237 *name = BSTRFromCStr(CP_UTF8, psz_name);
238 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
246 STDMETHODIMP VLCAudio::get_channel(long *channel)
248 if( NULL == channel )
251 libvlc_instance_t* p_libvlc;
252 HRESULT hr = getVLC(&p_libvlc);
255 libvlc_exception_t ex;
256 libvlc_exception_init(&ex);
258 *channel = libvlc_audio_get_channel(p_libvlc, &ex);
259 hr = exception_bridge(&ex);
264 STDMETHODIMP VLCAudio::put_channel(long channel)
266 libvlc_instance_t* p_libvlc;
267 HRESULT hr = getVLC(&p_libvlc);
270 libvlc_exception_t ex;
271 libvlc_exception_init(&ex);
273 libvlc_audio_set_channel(p_libvlc, channel, &ex);
274 hr = exception_bridge(&ex);
279 STDMETHODIMP VLCAudio::toggleMute()
281 libvlc_instance_t* p_libvlc;
282 HRESULT hr = getVLC(&p_libvlc);
284 libvlc_audio_toggle_mute(p_libvlc);
288 /****************************************************************************/
290 STDMETHODIMP VLCInput::get_length(double* length)
296 libvlc_media_player_t *p_md;
297 HRESULT hr = getMD(&p_md);
300 libvlc_exception_t ex;
301 libvlc_exception_init(&ex);
303 *length = (double)libvlc_media_player_get_length(p_md, &ex);
304 hr = exception_bridge(&ex);
309 STDMETHODIMP VLCInput::get_position(double* position)
311 if( NULL == position )
315 libvlc_media_player_t *p_md;
316 HRESULT hr = getMD(&p_md);
319 libvlc_exception_t ex;
320 libvlc_exception_init(&ex);
322 *position = libvlc_media_player_get_position(p_md, &ex);
323 hr = exception_bridge(&ex);
328 STDMETHODIMP VLCInput::put_position(double position)
330 libvlc_media_player_t *p_md;
331 HRESULT hr = getMD(&p_md);
334 libvlc_exception_t ex;
335 libvlc_exception_init(&ex);
337 libvlc_media_player_set_position(p_md, position, &ex);
338 hr = exception_bridge(&ex);
343 STDMETHODIMP VLCInput::get_time(double* time)
348 libvlc_media_player_t *p_md;
349 HRESULT hr = getMD(&p_md);
352 libvlc_exception_t ex;
353 libvlc_exception_init(&ex);
355 *time = (double)libvlc_media_player_get_time(p_md, &ex);
356 hr = exception_bridge(&ex);
361 STDMETHODIMP VLCInput::put_time(double time)
363 libvlc_media_player_t *p_md;
364 HRESULT hr = getMD(&p_md);
367 libvlc_exception_t ex;
368 libvlc_exception_init(&ex);
370 libvlc_media_player_set_time(p_md, (int64_t)time, &ex);
371 hr = exception_bridge(&ex);
376 STDMETHODIMP VLCInput::get_state(long* state)
381 libvlc_media_player_t *p_md;
382 HRESULT hr = getMD(&p_md);
385 libvlc_exception_t ex;
386 libvlc_exception_init(&ex);
388 *state = libvlc_media_player_get_state(p_md);
389 if( libvlc_exception_raised(&ex) )
391 // don't fail, just return the idle state
393 libvlc_exception_clear(&ex);
399 STDMETHODIMP VLCInput::get_rate(double* rate)
404 libvlc_media_player_t *p_md;
405 HRESULT hr = getMD(&p_md);
408 libvlc_exception_t ex;
409 libvlc_exception_init(&ex);
411 *rate = libvlc_media_player_get_rate(p_md, &ex);
412 hr = exception_bridge(&ex);
417 STDMETHODIMP VLCInput::put_rate(double rate)
419 libvlc_media_player_t *p_md;
420 HRESULT hr = getMD(&p_md);
423 libvlc_exception_t ex;
424 libvlc_exception_init(&ex);
426 libvlc_media_player_set_rate(p_md, rate, &ex);
427 hr = exception_bridge(&ex);
432 STDMETHODIMP VLCInput::get_fps(double* fps)
438 libvlc_media_player_t *p_md;
439 HRESULT hr = getMD(&p_md);
442 libvlc_exception_t ex;
443 libvlc_exception_init(&ex);
445 *fps = libvlc_media_player_get_fps(p_md, &ex);
446 hr = exception_bridge(&ex);
451 STDMETHODIMP VLCInput::get_hasVout(VARIANT_BOOL* hasVout)
453 if( NULL == hasVout )
456 libvlc_media_player_t *p_md;
457 HRESULT hr = getMD(&p_md);
460 libvlc_exception_t ex;
461 libvlc_exception_init(&ex);
463 *hasVout = libvlc_media_player_has_vout(p_md, &ex) ?
464 VARIANT_TRUE : VARIANT_FALSE;
465 hr = exception_bridge(&ex);
470 /****************************************************************************/
472 HRESULT VLCMarquee::do_put_int(unsigned idx, LONG val)
474 libvlc_media_player_t *p_md;
475 HRESULT hr = getMD(&p_md);
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);
486 HRESULT VLCMarquee::do_get_int(unsigned idx, LONG *val)
491 libvlc_media_player_t *p_md;
492 HRESULT hr = getMD(&p_md);
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);
503 STDMETHODIMP VLCMarquee::get_position(BSTR* val)
509 HRESULT hr = do_get_int(libvlc_marquee_Position, &i);
512 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
517 STDMETHODIMP VLCMarquee::put_position(BSTR val)
519 char *n = CStrFromBSTR(CP_UTF8, val);
520 if( !n ) return E_OUTOFMEMORY;
524 if( position_byname( n, i ) )
525 hr = do_put_int(libvlc_marquee_Position,i);
533 STDMETHODIMP VLCMarquee::get_text(BSTR *val)
539 libvlc_media_player_t *p_md;
540 HRESULT hr = getMD(&p_md);
543 libvlc_exception_t ex;
544 libvlc_exception_init(&ex);
546 psz = libvlc_video_get_marquee_string(p_md, libvlc_marquee_Text, &ex);
548 hr = exception_bridge(&ex);
550 *val = BSTRFromCStr(CP_UTF8, psz);
555 STDMETHODIMP VLCMarquee::put_text(BSTR val)
557 libvlc_media_player_t *p_md;
558 HRESULT hr = getMD(&p_md);
561 libvlc_exception_t ex;
562 libvlc_exception_init(&ex);
564 char *psz_text = CStrFromBSTR(CP_UTF8, val);
565 libvlc_video_set_marquee_string(p_md, libvlc_marquee_Text,
567 hr = exception_bridge(&ex);
568 CoTaskMemFree(psz_text);
573 /****************************************************************************/
575 STDMETHODIMP VLCPlaylistItems::get_count(long* count)
580 libvlc_exception_t ex;
581 libvlc_exception_init(&ex);
583 *count = Instance()->playlist_count(&ex);
584 return exception_bridge(&ex);
587 STDMETHODIMP VLCPlaylistItems::clear()
589 libvlc_exception_t ex;
590 libvlc_exception_init(&ex);
592 Instance()->playlist_clear(&ex);
593 return exception_bridge(&ex);
596 STDMETHODIMP VLCPlaylistItems::remove(long item)
598 libvlc_instance_t* p_libvlc;
599 HRESULT hr = getVLC(&p_libvlc);
602 libvlc_exception_t ex;
603 libvlc_exception_init(&ex);
605 Instance()->playlist_delete_item(item, &ex);
606 hr = exception_bridge(&ex);
611 /****************************************************************************/
613 STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
619 libvlc_exception_t ex;
620 libvlc_exception_init(&ex);
622 *count = Instance()->playlist_count(&ex);
623 return exception_bridge(&ex);
626 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
628 if( NULL == isPlaying )
631 libvlc_media_player_t *p_md;
632 HRESULT hr = getMD(&p_md);
635 libvlc_exception_t ex;
636 libvlc_exception_init(&ex);
638 *isPlaying = libvlc_media_player_is_playing(p_md) ?
639 VARIANT_TRUE: VARIANT_FALSE;
640 libvlc_exception_clear(&ex);
645 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
650 if( 0 == SysStringLen(uri) )
653 libvlc_instance_t* p_libvlc;
654 HRESULT hr = getVLC(&p_libvlc);
657 libvlc_exception_t ex;
658 libvlc_exception_init(&ex);
660 char *psz_uri = NULL;
661 if( SysStringLen(Instance()->getBaseURL()) > 0 )
664 ** if the MRL a relative URL, we should end up with an absolute URL
666 LPWSTR abs_url = CombineURL(Instance()->getBaseURL(), uri);
667 if( NULL != abs_url )
669 psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
670 CoTaskMemFree(abs_url);
674 psz_uri = CStrFromBSTR(CP_UTF8, uri);
680 ** baseURL is empty, assume MRL is absolute
682 psz_uri = CStrFromBSTR(CP_UTF8, uri);
685 if( NULL == psz_uri )
687 return E_OUTOFMEMORY;
693 hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
696 CoTaskMemFree(psz_uri);
700 char *psz_name = NULL;
702 VariantInit(&v_name);
703 if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
705 if( SysStringLen(V_BSTR(&v_name)) > 0 )
706 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
708 VariantClear(&v_name);
711 *item = Instance()->playlist_add_extended_untrusted(psz_uri,
712 i_options, const_cast<const char **>(ppsz_options), &ex);
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);
723 STDMETHODIMP VLCPlaylist::play()
725 libvlc_exception_t ex;
726 libvlc_exception_init(&ex);
728 Instance()->playlist_play(&ex);
729 return exception_bridge(&ex);
732 STDMETHODIMP VLCPlaylist::playItem(long item)
734 libvlc_exception_t ex;
735 libvlc_exception_init(&ex);
737 Instance()->playlist_play_item(item,&ex);
738 return exception_bridge(&ex);;
741 STDMETHODIMP VLCPlaylist::togglePause()
743 libvlc_media_player_t* p_md;
744 HRESULT hr = getMD(&p_md);
747 libvlc_exception_t ex;
748 libvlc_exception_init(&ex);
750 libvlc_media_player_pause(p_md, &ex);
751 hr = exception_bridge(&ex);;
756 STDMETHODIMP VLCPlaylist::stop()
758 libvlc_media_player_t *p_md;
759 HRESULT hr = getMD(&p_md);
762 libvlc_exception_t ex;
763 libvlc_exception_init(&ex);
765 libvlc_media_player_stop(p_md);
766 hr = exception_bridge(&ex);;
771 STDMETHODIMP VLCPlaylist::next()
773 libvlc_exception_t ex;
774 libvlc_exception_init(&ex);
776 Instance()->playlist_next(&ex);
777 return exception_bridge(&ex);;
780 STDMETHODIMP VLCPlaylist::prev()
782 libvlc_exception_t ex;
783 libvlc_exception_init(&ex);
785 Instance()->playlist_prev(&ex);
786 return exception_bridge(&ex);;
789 STDMETHODIMP VLCPlaylist::clear()
791 libvlc_exception_t ex;
792 libvlc_exception_init(&ex);
794 Instance()->playlist_clear(&ex);
795 return exception_bridge(&ex);;
798 STDMETHODIMP VLCPlaylist::removeItem(long item)
800 libvlc_instance_t* p_libvlc;
801 HRESULT hr = getVLC(&p_libvlc);
804 libvlc_exception_t ex;
805 libvlc_exception_init(&ex);
807 Instance()->playlist_delete_item(item, &ex);
808 hr = exception_bridge(&ex);;
813 STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
818 *obj = _p_vlcplaylistitems;
819 if( NULL != _p_vlcplaylistitems )
821 _p_vlcplaylistitems->AddRef();
824 return E_OUTOFMEMORY;
827 /****************************************************************************/
829 STDMETHODIMP VLCSubtitle::get_track(long* spu)
834 libvlc_media_player_t *p_md;
835 HRESULT hr = getMD(&p_md);
838 libvlc_exception_t ex;
839 libvlc_exception_init(&ex);
841 *spu = libvlc_video_get_spu(p_md, &ex);
842 hr = exception_bridge(&ex);
847 STDMETHODIMP VLCSubtitle::put_track(long spu)
849 libvlc_media_player_t *p_md;
850 HRESULT hr = getMD(&p_md);
853 libvlc_exception_t ex;
854 libvlc_exception_init(&ex);
856 libvlc_video_set_spu(p_md, spu, &ex);
857 hr = exception_bridge(&ex);
862 STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
864 if( NULL == spuNumber )
867 libvlc_media_player_t *p_md;
868 HRESULT hr = getMD(&p_md);
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);
881 STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
886 libvlc_media_player_t* p_md;
887 libvlc_exception_t ex;
888 libvlc_exception_init(&ex);
890 HRESULT hr = getMD(&p_md);
894 const char *psz_name;
895 libvlc_track_description_t *p_spuDesc;
897 // get subtitles description
898 p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
899 hr = exception_bridge(&ex);
903 // get the number of available subtitle
904 i_limit = libvlc_video_get_spu_count(p_md, &ex);
905 hr = exception_bridge(&ex);
909 // check if the number given is a good one
910 if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
913 // get the good spuDesc
914 for( i = 0 ; i < nameID ; i++ )
916 p_spuDesc = p_spuDesc->p_next;
918 // get the subtitle name
919 psz_name = p_spuDesc->psz_name;
922 if( psz_name != NULL )
924 *name = BSTRFromCStr(CP_UTF8, psz_name);
925 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
933 /****************************************************************************/
935 STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
937 if( NULL == fullscreen )
940 libvlc_media_player_t *p_md;
941 HRESULT hr = getMD(&p_md);
944 libvlc_exception_t ex;
945 libvlc_exception_init(&ex);
947 *fullscreen = libvlc_get_fullscreen(p_md, &ex) ?
948 VARIANT_TRUE : VARIANT_FALSE;
949 hr = exception_bridge(&ex);
954 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
956 libvlc_media_player_t *p_md;
957 HRESULT hr = getMD(&p_md);
960 libvlc_exception_t ex;
961 libvlc_exception_init(&ex);
963 libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen, &ex);
964 hr = exception_bridge(&ex);
969 STDMETHODIMP VLCVideo::get_width(long* width)
974 libvlc_media_player_t *p_md;
975 HRESULT hr = getMD(&p_md);
978 libvlc_exception_t ex;
979 libvlc_exception_init(&ex);
981 *width = libvlc_video_get_width(p_md, &ex);
982 hr = exception_bridge(&ex);
987 STDMETHODIMP VLCVideo::get_height(long* height)
992 libvlc_media_player_t *p_md;
993 HRESULT hr = getMD(&p_md);
996 libvlc_exception_t ex;
997 libvlc_exception_init(&ex);
999 *height = libvlc_video_get_height(p_md, &ex);
1000 hr = exception_bridge(&ex);
1005 STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
1007 if( NULL == aspect )
1010 libvlc_media_player_t *p_md;
1011 HRESULT hr = getMD(&p_md);
1014 libvlc_exception_t ex;
1015 libvlc_exception_init(&ex);
1017 char *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1019 hr = exception_bridge(&ex);
1020 if( SUCCEEDED(hr) && NULL != psz_aspect )
1022 *aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
1023 if( NULL == *aspect )
1025 } else if( NULL == psz_aspect) hr = E_OUTOFMEMORY; // strdup("") failed
1031 STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
1033 if( NULL == aspect )
1036 libvlc_media_player_t *p_md;
1037 HRESULT hr = getMD(&p_md);
1040 libvlc_exception_t ex;
1041 libvlc_exception_init(&ex);
1043 char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
1044 if( NULL == psz_aspect )
1046 return E_OUTOFMEMORY;
1049 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
1051 CoTaskMemFree(psz_aspect);
1052 hr = exception_bridge(&ex);
1057 STDMETHODIMP VLCVideo::get_subtitle(long* spu)
1062 libvlc_media_player_t *p_md;
1063 HRESULT hr = getMD(&p_md);
1066 libvlc_exception_t ex;
1067 libvlc_exception_init(&ex);
1069 *spu = libvlc_video_get_spu(p_md, &ex);
1070 hr = exception_bridge(&ex);
1075 STDMETHODIMP VLCVideo::put_subtitle(long spu)
1077 libvlc_media_player_t *p_md;
1078 HRESULT hr = getMD(&p_md);
1081 libvlc_exception_t ex;
1082 libvlc_exception_init(&ex);
1084 libvlc_video_set_spu(p_md, spu, &ex);
1085 hr = exception_bridge(&ex);
1090 STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
1092 if( NULL == geometry )
1095 libvlc_media_player_t *p_md;
1096 HRESULT hr = getMD(&p_md);
1099 libvlc_exception_t ex;
1100 libvlc_exception_init(&ex);
1102 char *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1104 hr = exception_bridge(&ex);
1105 if( SUCCEEDED(&ex) && NULL != psz_geometry )
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 );
1115 STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
1117 if( NULL == geometry )
1120 if( 0 == SysStringLen(geometry) )
1121 return E_INVALIDARG;
1123 libvlc_media_player_t *p_md;
1124 HRESULT hr = getMD(&p_md);
1127 libvlc_exception_t ex;
1128 libvlc_exception_init(&ex);
1130 char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
1131 if( NULL == psz_geometry )
1133 return E_OUTOFMEMORY;
1136 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
1138 CoTaskMemFree(psz_geometry);
1139 hr = exception_bridge(&ex);
1144 STDMETHODIMP VLCVideo::get_teletext(long* page)
1149 libvlc_media_player_t *p_md;
1150 HRESULT hr = getMD(&p_md);
1154 libvlc_exception_t ex;
1155 libvlc_exception_init(&ex);
1157 *page = libvlc_video_get_teletext(p_md);
1158 hr = exception_bridge(&ex);
1164 STDMETHODIMP VLCVideo::put_teletext(long page)
1167 libvlc_media_player_t *p_md;
1168 HRESULT hr = getMD(&p_md);
1172 libvlc_exception_t ex;
1173 libvlc_exception_init(&ex);
1175 libvlc_video_set_teletext(p_md, page);
1176 hr = exception_bridge(&ex);
1182 STDMETHODIMP VLCVideo::deinterlaceDisable()
1184 libvlc_media_player_t *p_md;
1185 HRESULT hr = getMD(&p_md);
1188 libvlc_exception_t ex;
1189 libvlc_exception_init(&ex);
1191 libvlc_video_set_deinterlace(p_md, 0, "", &ex);
1192 hr = exception_bridge(&ex);
1197 STDMETHODIMP VLCVideo::deinterlaceEnable(BSTR mode)
1199 libvlc_media_player_t *p_md;
1200 HRESULT hr = getMD(&p_md);
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);
1215 STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
1217 if( NULL == picture )
1220 libvlc_media_player_t *p_md;
1221 HRESULT hr = getMD(&p_md);
1224 libvlc_exception_t ex;
1225 libvlc_exception_init(&ex);
1227 static int uniqueId = 0;
1228 TCHAR path[MAX_PATH+1];
1230 int pathlen = GetTempPath(MAX_PATH-24, path);
1231 if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
1234 /* check temp directory path by openning it */
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 )
1241 Instance()->setErrorInfo(IID_IVLCVideo,
1242 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1247 BY_HANDLE_FILE_INFORMATION bhfi;
1248 BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
1249 CloseHandle(dirHandle);
1250 if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
1252 Instance()->setErrorInfo(IID_IVLCVideo,
1253 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1259 TCHAR filepath[MAX_PATH+1];
1261 _stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
1262 path, GetCurrentProcessId(), ++uniqueId);
1265 /* reuse path storage for UTF8 string */
1266 char *psz_filepath = (char *)path;
1267 WCHAR* wpath = filepath;
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)) )
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
1282 if( (0 == pathlen) || (sizeof(path) == pathlen) )
1285 /* take snapshot into file */
1286 libvlc_video_take_snapshot(p_md, psz_filepath, 0, 0, &ex);
1287 hr = exception_bridge(&ex);
1290 /* open snapshot file */
1291 HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP, 0, 0,
1292 LR_CREATEDIBSECTION|LR_LOADFROMFILE);
1297 snapDesc.cbSizeofstruct = sizeof(PICTDESC);
1298 snapDesc.picType = PICTYPE_BITMAP;
1299 snapDesc.bmp.hbitmap = (HBITMAP)snapPic;
1300 snapDesc.bmp.hpal = NULL;
1302 hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp,
1303 TRUE, (LPVOID*)picture);
1307 DeleteObject(snapPic);
1310 DeleteFile(filepath);
1316 STDMETHODIMP VLCVideo::toggleFullscreen()
1318 libvlc_media_player_t *p_md;
1319 HRESULT hr = getMD(&p_md);
1322 libvlc_exception_t ex;
1323 libvlc_exception_init(&ex);
1325 libvlc_toggle_fullscreen(p_md, &ex);
1326 hr = exception_bridge(&ex);
1331 STDMETHODIMP VLCVideo::toggleTeletext()
1333 libvlc_media_player_t *p_md;
1334 HRESULT hr = getMD(&p_md);
1337 libvlc_exception_t ex;
1338 libvlc_exception_init(&ex);
1340 libvlc_toggle_teletext(p_md, &ex);
1341 hr = exception_bridge(&ex);
1346 STDMETHODIMP VLCVideo::get_marquee(IVLCMarquee** obj)
1348 return object_get(obj,_p_vlcmarquee);
1351 STDMETHODIMP VLCVideo::get_logo(IVLCLogo** obj)
1353 return object_get(obj,_p_vlclogo);
1357 /****************************************************************************/
1359 HRESULT VLCLogo::do_put_int(unsigned idx, LONG val)
1361 libvlc_media_player_t *p_md;
1362 HRESULT hr = getMD(&p_md);
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);
1373 HRESULT VLCLogo::do_get_int(unsigned idx, LONG *val)
1378 libvlc_media_player_t *p_md;
1379 HRESULT hr = getMD(&p_md);
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);
1390 STDMETHODIMP VLCLogo::file(BSTR fname)
1392 libvlc_media_player_t *p_md;
1393 HRESULT hr = getMD(&p_md);
1395 char *n = CStrFromBSTR(CP_UTF8, fname);
1396 if( !n ) hr = E_OUTOFMEMORY;
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);
1410 STDMETHODIMP VLCLogo::get_position(BSTR* val)
1416 HRESULT hr = do_get_int(libvlc_logo_position, &i);
1419 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
1424 STDMETHODIMP VLCLogo::put_position(BSTR val)
1426 char *n = CStrFromBSTR(CP_UTF8, val);
1427 if( !n ) return E_OUTOFMEMORY;
1431 if( position_byname( n, i ) )
1432 hr = do_put_int(libvlc_logo_position,i);
1440 /****************************************************************************/
1442 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
1443 _p_instance(p_instance),
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))
1453 VLCControl2::~VLCControl2()
1456 delete _p_vlcsubtitle;
1457 delete _p_vlcplaylist;
1461 _p_typeinfo->Release();
1464 HRESULT VLCControl2::loadTypeInfo(void)
1466 HRESULT hr = NOERROR;
1467 if( NULL == _p_typeinfo )
1469 ITypeLib *p_typelib;
1471 hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1474 hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
1479 p_typelib->Release();
1485 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
1487 if( NULL == pctInfo )
1488 return E_INVALIDARG;
1490 if( SUCCEEDED(loadTypeInfo()) )
1498 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1500 if( NULL == ppTInfo )
1501 return E_INVALIDARG;
1503 if( SUCCEEDED(loadTypeInfo()) )
1505 _p_typeinfo->AddRef();
1506 *ppTInfo = _p_typeinfo;
1513 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1514 UINT cNames, LCID lcid, DISPID* rgDispID)
1516 if( SUCCEEDED(loadTypeInfo()) )
1518 return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1523 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
1524 LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1525 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1527 if( SUCCEEDED(loadTypeInfo()) )
1529 return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1530 pVarResult, pExcepInfo, puArgErr);
1535 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
1537 if( NULL == autoloop )
1540 *autoloop = _p_instance->getAutoLoop() ? VARIANT_TRUE: VARIANT_FALSE;
1544 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
1546 _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
1550 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
1552 if( NULL == autoplay )
1555 *autoplay = _p_instance->getAutoPlay() ? VARIANT_TRUE: VARIANT_FALSE;
1559 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
1561 _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
1565 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
1570 *url = SysAllocStringLen(_p_instance->getBaseURL(),
1571 SysStringLen(_p_instance->getBaseURL()));
1575 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
1577 _p_instance->setBaseURL(mrl);
1582 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
1587 *mrl = SysAllocStringLen(_p_instance->getMRL(),
1588 SysStringLen(_p_instance->getMRL()));
1592 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
1594 _p_instance->setMRL(mrl);
1600 STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
1602 if( NULL == visible )
1606 * Note to developers
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.
1613 * This is the reason why FALSE is returned, until toolbar get implemented.
1616 /* DISABLED for now */
1617 // *visible = _p_instance->getShowToolbar() ? VARIANT_TRUE: VARIANT_FALSE;
1619 *visible = VARIANT_FALSE;
1624 STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
1626 _p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
1631 STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
1633 if( NULL == seconds )
1636 *seconds = _p_instance->getStartTime();
1641 STDMETHODIMP VLCControl2::put_StartTime(long seconds)
1643 _p_instance->setStartTime(seconds);
1648 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
1650 if( NULL == version )
1653 const char *versionStr = libvlc_get_version();
1654 if( NULL != versionStr )
1656 *version = BSTRFromCStr(CP_UTF8, versionStr);
1658 return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
1664 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
1666 if( NULL == isVisible )
1669 *isVisible = _p_instance->getVisible() ? VARIANT_TRUE : VARIANT_FALSE;
1674 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
1676 _p_instance->setVisible(isVisible != VARIANT_FALSE);
1681 STDMETHODIMP VLCControl2::get_Volume(long *volume)
1683 if( NULL == volume )
1686 *volume = _p_instance->getVolume();
1690 STDMETHODIMP VLCControl2::put_Volume(long volume)
1692 _p_instance->setVolume(volume);
1696 STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
1698 if( NULL == backcolor )
1701 *backcolor = _p_instance->getBackColor();
1705 STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
1707 _p_instance->setBackColor(backcolor);
1711 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
1713 return object_get(obj,_p_vlcaudio);
1716 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
1718 return object_get(obj,_p_vlcinput);
1721 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
1723 return object_get(obj,_p_vlcplaylist);
1726 STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
1728 return object_get(obj,_p_vlcsubtitle);
1731 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
1733 return object_get(obj,_p_vlcvideo);