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( VLCMessage )
67 BIND_INTERFACE( VLCMessages )
68 BIND_INTERFACE( VLCMessageIterator )
69 BIND_INTERFACE( VLCLog )
70 BIND_INTERFACE( VLCMarquee )
71 BIND_INTERFACE( VLCLogo )
72 BIND_INTERFACE( VLCPlaylistItems )
73 BIND_INTERFACE( VLCPlaylist )
74 BIND_INTERFACE( VLCVideo )
75 BIND_INTERFACE( VLCSubtitle )
79 template<class I> static inline
80 HRESULT object_get(I **dst, I *src)
97 STDMETHODIMP VLCAudio::get_mute(VARIANT_BOOL* mute)
102 libvlc_instance_t* p_libvlc;
103 HRESULT hr = getVLC(&p_libvlc);
105 *mute = libvlc_audio_get_mute(p_libvlc) ?
106 VARIANT_TRUE : VARIANT_FALSE;
110 STDMETHODIMP VLCAudio::put_mute(VARIANT_BOOL mute)
112 libvlc_instance_t* p_libvlc;
113 HRESULT hr = getVLC(&p_libvlc);
115 libvlc_audio_set_mute(p_libvlc, VARIANT_FALSE != mute);
119 STDMETHODIMP VLCAudio::get_volume(long* volume)
124 libvlc_instance_t* p_libvlc;
125 HRESULT hr = getVLC(&p_libvlc);
127 *volume = libvlc_audio_get_volume(p_libvlc);
131 STDMETHODIMP VLCAudio::put_volume(long volume)
133 libvlc_instance_t* p_libvlc;
134 HRESULT hr = getVLC(&p_libvlc);
137 libvlc_exception_t ex;
138 libvlc_exception_init(&ex);
140 libvlc_audio_set_volume(p_libvlc, volume, &ex);
141 hr = exception_bridge(&ex);
146 STDMETHODIMP VLCAudio::get_track(long* track)
151 libvlc_media_player_t* p_md;
152 HRESULT hr = getMD(&p_md);
155 libvlc_exception_t ex;
156 libvlc_exception_init(&ex);
158 *track = libvlc_audio_get_track(p_md, &ex);
159 hr = exception_bridge(&ex);
164 STDMETHODIMP VLCAudio::put_track(long track)
166 libvlc_media_player_t *p_md;
167 HRESULT hr = getMD(&p_md);
170 libvlc_exception_t ex;
171 libvlc_exception_init(&ex);
173 libvlc_audio_set_track(p_md, track, &ex);
174 hr = exception_bridge(&ex);
179 STDMETHODIMP VLCAudio::get_count(long* trackNumber)
181 if( NULL == trackNumber )
184 libvlc_media_player_t* p_md;
185 HRESULT hr = getMD(&p_md);
188 libvlc_exception_t ex;
189 libvlc_exception_init(&ex);
190 // get the number of audio track available and return it
191 *trackNumber = libvlc_audio_get_track_count(p_md, &ex);
192 hr = exception_bridge(&ex);
198 STDMETHODIMP VLCAudio::description(long trackID, BSTR* name)
203 libvlc_media_player_t* p_md;
204 libvlc_exception_t ex;
205 libvlc_exception_init(&ex);
207 HRESULT hr = getMD(&p_md);
211 const char *psz_name;
212 libvlc_track_description_t *p_trackDesc;
214 // get tracks description
215 p_trackDesc = libvlc_audio_get_track_description(p_md, &ex);
216 hr = exception_bridge(&ex);
220 //get the number of available track
221 i_limit = libvlc_audio_get_track_count(p_md, &ex);
222 hr = exception_bridge(&ex);
226 // check if the number given is a good one
227 if ( ( trackID > ( i_limit -1 ) ) || ( trackID < 0 ) )
230 // get the good trackDesc
231 for( i = 0 ; i < trackID ; i++ )
233 p_trackDesc = p_trackDesc->p_next;
235 // get the track name
236 psz_name = p_trackDesc->psz_name;
239 if( psz_name != NULL )
241 *name = BSTRFromCStr(CP_UTF8, psz_name);
242 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
250 STDMETHODIMP VLCAudio::get_channel(long *channel)
252 if( NULL == channel )
255 libvlc_instance_t* p_libvlc;
256 HRESULT hr = getVLC(&p_libvlc);
259 libvlc_exception_t ex;
260 libvlc_exception_init(&ex);
262 *channel = libvlc_audio_get_channel(p_libvlc, &ex);
263 hr = exception_bridge(&ex);
268 STDMETHODIMP VLCAudio::put_channel(long channel)
270 libvlc_instance_t* p_libvlc;
271 HRESULT hr = getVLC(&p_libvlc);
274 libvlc_exception_t ex;
275 libvlc_exception_init(&ex);
277 libvlc_audio_set_channel(p_libvlc, channel, &ex);
278 hr = exception_bridge(&ex);
283 STDMETHODIMP VLCAudio::toggleMute()
285 libvlc_instance_t* p_libvlc;
286 HRESULT hr = getVLC(&p_libvlc);
288 libvlc_audio_toggle_mute(p_libvlc);
292 /****************************************************************************/
294 STDMETHODIMP VLCInput::get_length(double* length)
300 libvlc_media_player_t *p_md;
301 HRESULT hr = getMD(&p_md);
304 libvlc_exception_t ex;
305 libvlc_exception_init(&ex);
307 *length = (double)libvlc_media_player_get_length(p_md, &ex);
308 hr = exception_bridge(&ex);
313 STDMETHODIMP VLCInput::get_position(double* position)
315 if( NULL == position )
319 libvlc_media_player_t *p_md;
320 HRESULT hr = getMD(&p_md);
323 libvlc_exception_t ex;
324 libvlc_exception_init(&ex);
326 *position = libvlc_media_player_get_position(p_md, &ex);
327 hr = exception_bridge(&ex);
332 STDMETHODIMP VLCInput::put_position(double position)
334 libvlc_media_player_t *p_md;
335 HRESULT hr = getMD(&p_md);
338 libvlc_exception_t ex;
339 libvlc_exception_init(&ex);
341 libvlc_media_player_set_position(p_md, position, &ex);
342 hr = exception_bridge(&ex);
347 STDMETHODIMP VLCInput::get_time(double* time)
352 libvlc_media_player_t *p_md;
353 HRESULT hr = getMD(&p_md);
356 libvlc_exception_t ex;
357 libvlc_exception_init(&ex);
359 *time = (double)libvlc_media_player_get_time(p_md, &ex);
360 hr = exception_bridge(&ex);
365 STDMETHODIMP VLCInput::put_time(double time)
367 libvlc_media_player_t *p_md;
368 HRESULT hr = getMD(&p_md);
371 libvlc_exception_t ex;
372 libvlc_exception_init(&ex);
374 libvlc_media_player_set_time(p_md, (int64_t)time, &ex);
375 hr = exception_bridge(&ex);
380 STDMETHODIMP VLCInput::get_state(long* state)
385 libvlc_media_player_t *p_md;
386 HRESULT hr = getMD(&p_md);
389 libvlc_exception_t ex;
390 libvlc_exception_init(&ex);
392 *state = libvlc_media_player_get_state(p_md);
393 if( libvlc_exception_raised(&ex) )
395 // don't fail, just return the idle state
397 libvlc_exception_clear(&ex);
403 STDMETHODIMP VLCInput::get_rate(double* rate)
408 libvlc_media_player_t *p_md;
409 HRESULT hr = getMD(&p_md);
412 libvlc_exception_t ex;
413 libvlc_exception_init(&ex);
415 *rate = libvlc_media_player_get_rate(p_md, &ex);
416 hr = exception_bridge(&ex);
421 STDMETHODIMP VLCInput::put_rate(double rate)
423 libvlc_media_player_t *p_md;
424 HRESULT hr = getMD(&p_md);
427 libvlc_exception_t ex;
428 libvlc_exception_init(&ex);
430 libvlc_media_player_set_rate(p_md, rate, &ex);
431 hr = exception_bridge(&ex);
436 STDMETHODIMP VLCInput::get_fps(double* fps)
442 libvlc_media_player_t *p_md;
443 HRESULT hr = getMD(&p_md);
446 libvlc_exception_t ex;
447 libvlc_exception_init(&ex);
449 *fps = libvlc_media_player_get_fps(p_md, &ex);
450 hr = exception_bridge(&ex);
455 STDMETHODIMP VLCInput::get_hasVout(VARIANT_BOOL* hasVout)
457 if( NULL == hasVout )
460 libvlc_media_player_t *p_md;
461 HRESULT hr = getMD(&p_md);
464 libvlc_exception_t ex;
465 libvlc_exception_init(&ex);
467 *hasVout = libvlc_media_player_has_vout(p_md, &ex) ?
468 VARIANT_TRUE : VARIANT_FALSE;
469 hr = exception_bridge(&ex);
474 /****************************************************************************/
478 delete _p_vlcmessages;
480 libvlc_log_close(_p_log);
483 STDMETHODIMP VLCLog::get_messages(IVLCMessages** obj)
488 *obj = _p_vlcmessages;
489 if( NULL != _p_vlcmessages )
491 _p_vlcmessages->AddRef();
494 return E_OUTOFMEMORY;
497 STDMETHODIMP VLCLog::get_verbosity(long* level)
504 libvlc_instance_t* p_libvlc;
505 HRESULT hr = getVLC(&p_libvlc);
507 *level = libvlc_get_log_verbosity(p_libvlc);
512 /* log is not enabled, return -1 */
518 STDMETHODIMP VLCLog::put_verbosity(long verbosity)
520 libvlc_instance_t* p_libvlc;
521 HRESULT hr = getVLC(&p_libvlc);
524 libvlc_exception_t ex;
525 libvlc_exception_init(&ex);
531 _p_log = libvlc_log_open(p_libvlc, &ex);
532 hr = exception_bridge(&ex);
535 libvlc_set_log_verbosity(p_libvlc, (unsigned)verbosity);
539 /* close log when verbosity is set to -1 */
540 libvlc_log_close(_p_log);
543 hr = exception_bridge(&ex);
548 /****************************************************************************/
550 HRESULT VLCMarquee::do_put_int(unsigned idx, LONG val)
552 libvlc_media_player_t *p_md;
553 HRESULT hr = getMD(&p_md);
556 libvlc_exception_t ex;
557 libvlc_exception_init(&ex);
558 libvlc_video_set_marquee_int(p_md, idx, val, &ex);
559 hr = exception_bridge(&ex);
564 HRESULT VLCMarquee::do_get_int(unsigned idx, LONG *val)
569 libvlc_media_player_t *p_md;
570 HRESULT hr = getMD(&p_md);
573 libvlc_exception_t ex;
574 libvlc_exception_init(&ex);
575 *val = libvlc_video_get_marquee_int(p_md, idx, &ex);
576 hr = exception_bridge(&ex);
581 STDMETHODIMP VLCMarquee::get_position(BSTR* val)
587 HRESULT hr = do_get_int(libvlc_marquee_Position, &i);
590 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
595 STDMETHODIMP VLCMarquee::put_position(BSTR val)
597 char *n = CStrFromBSTR(CP_UTF8, val);
598 if( !n ) return E_OUTOFMEMORY;
602 if( position_byname( n, i ) )
603 hr = do_put_int(libvlc_marquee_Position,i);
611 STDMETHODIMP VLCMarquee::get_text(BSTR *val)
617 libvlc_media_player_t *p_md;
618 HRESULT hr = getMD(&p_md);
621 libvlc_exception_t ex;
622 libvlc_exception_init(&ex);
624 psz = libvlc_video_get_marquee_string(p_md, libvlc_marquee_Text, &ex);
626 hr = exception_bridge(&ex);
628 *val = BSTRFromCStr(CP_UTF8, psz);
633 STDMETHODIMP VLCMarquee::put_text(BSTR val)
635 libvlc_media_player_t *p_md;
636 HRESULT hr = getMD(&p_md);
639 libvlc_exception_t ex;
640 libvlc_exception_init(&ex);
642 char *psz_text = CStrFromBSTR(CP_UTF8, val);
643 libvlc_video_set_marquee_string(p_md, libvlc_marquee_Text,
645 hr = exception_bridge(&ex);
646 CoTaskMemFree(psz_text);
651 /****************************************************************************/
653 /* STL forward iterator used by VLCEnumIterator class to implement IEnumVARIANT */
655 class VLCMessageSTLIterator
660 VLCMessageSTLIterator(IVLCMessageIterator* iter) : iter(iter), msg(NULL)
666 VLCMessageSTLIterator(const VLCMessageSTLIterator& other)
676 virtual ~VLCMessageSTLIterator()
685 // we only need prefix ++ operator
686 VLCMessageSTLIterator& operator++()
688 VARIANT_BOOL hasNext = VARIANT_FALSE;
691 iter->get_hasNext(&hasNext);
698 if( VARIANT_TRUE == hasNext ) {
705 VARIANT operator*() const
711 if( SUCCEEDED(msg->QueryInterface(IID_IDispatch,
712 (LPVOID*)&V_DISPATCH(&v))) )
714 V_VT(&v) = VT_DISPATCH;
720 bool operator==(const VLCMessageSTLIterator& other) const
722 return msg == other.msg;
725 bool operator!=(const VLCMessageSTLIterator& other) const
727 return msg != other.msg;
731 IVLCMessageIterator* iter;
735 //////////////////////////////////////////////////////////////////////////////
737 STDMETHODIMP VLCMessages::get__NewEnum(LPUNKNOWN* _NewEnum)
739 if( NULL == _NewEnum )
742 IVLCMessageIterator* iter = NULL;
745 *_NewEnum= new VLCEnumIterator<IID_IEnumVARIANT,
748 VLCMessageSTLIterator>
749 (VLCMessageSTLIterator(iter), VLCMessageSTLIterator(NULL));
751 return *_NewEnum ? S_OK : E_OUTOFMEMORY;
754 STDMETHODIMP VLCMessages::clear()
756 libvlc_log_t *p_log = _p_vlclog->_p_log;
758 libvlc_log_clear(p_log);
762 STDMETHODIMP VLCMessages::get_count(long* count)
767 libvlc_log_t *p_log = _p_vlclog->_p_log;
768 *count = libvlc_log_count(p_log);
772 STDMETHODIMP VLCMessages::iterator(IVLCMessageIterator** iter)
777 *iter = new VLCMessageIterator(Instance(), _p_vlclog);
779 return *iter ? S_OK : E_OUTOFMEMORY;
782 /****************************************************************************/
784 VLCMessageIterator::VLCMessageIterator(VLCPlugin *p, VLCLog* p_vlclog ):
785 VLCInterface<VLCMessageIterator,IVLCMessageIterator>(p),
788 _p_iter(_p_vlclog && _p_vlclog->_p_log ?
789 libvlc_log_get_iterator(_p_vlclog->_p_log, NULL) : NULL)
793 STDMETHODIMP VLCMessageIterator::get_hasNext(VARIANT_BOOL* hasNext)
795 if( NULL == hasNext )
798 *hasNext = (_p_iter && _p_vlclog->_p_log &&
799 libvlc_log_iterator_has_next(_p_iter)) ?
800 VARIANT_TRUE : VARIANT_FALSE;
804 STDMETHODIMP VLCMessageIterator::next(IVLCMessage** message)
808 if( NULL == message )
811 if( _p_iter && _p_vlclog->_p_log )
813 struct libvlc_log_message_t buffer;
815 buffer.sizeof_msg = sizeof(buffer);
817 libvlc_exception_t ex;
818 libvlc_exception_init(&ex);
820 libvlc_log_iterator_next(_p_iter, &buffer, &ex);
821 *message = new VLCMessage(Instance(), buffer);
828 /****************************************************************************/
830 inline const char *msgSeverity(int sev)
845 STDMETHODIMP VLCMessage::get__Value(VARIANT* _Value)
852 snprintf(buffer, sizeof(buffer), "%s %s %s: %s",
853 _msg.psz_type, _msg.psz_name, msgSeverity(_msg.i_severity), _msg.psz_message);
855 V_VT(_Value) = VT_BSTR;
856 V_BSTR(_Value) = BSTRFromCStr(CP_UTF8, buffer);
861 STDMETHODIMP VLCMessage::get_severity(long* level)
866 *level = _msg.i_severity;
871 STDMETHODIMP VLCMessage::get_type(BSTR* type)
876 *type = BSTRFromCStr(CP_UTF8, _msg.psz_type);
881 STDMETHODIMP VLCMessage::get_name(BSTR* name)
886 *name = BSTRFromCStr(CP_UTF8, _msg.psz_name);
891 STDMETHODIMP VLCMessage::get_header(BSTR* header)
896 *header = BSTRFromCStr(CP_UTF8, _msg.psz_header);
901 STDMETHODIMP VLCMessage::get_message(BSTR* message)
903 if( NULL == message )
906 *message = BSTRFromCStr(CP_UTF8, _msg.psz_message);
911 /****************************************************************************/
913 STDMETHODIMP VLCPlaylistItems::get_count(long* count)
918 libvlc_exception_t ex;
919 libvlc_exception_init(&ex);
921 *count = Instance()->playlist_count(&ex);
922 return exception_bridge(&ex);
925 STDMETHODIMP VLCPlaylistItems::clear()
927 libvlc_exception_t ex;
928 libvlc_exception_init(&ex);
930 Instance()->playlist_clear(&ex);
931 return exception_bridge(&ex);
934 STDMETHODIMP VLCPlaylistItems::remove(long item)
936 libvlc_instance_t* p_libvlc;
937 HRESULT hr = getVLC(&p_libvlc);
940 libvlc_exception_t ex;
941 libvlc_exception_init(&ex);
943 Instance()->playlist_delete_item(item, &ex);
944 hr = exception_bridge(&ex);
949 /****************************************************************************/
951 STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
957 libvlc_exception_t ex;
958 libvlc_exception_init(&ex);
960 *count = Instance()->playlist_count(&ex);
961 return exception_bridge(&ex);
964 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
966 if( NULL == isPlaying )
969 libvlc_media_player_t *p_md;
970 HRESULT hr = getMD(&p_md);
973 libvlc_exception_t ex;
974 libvlc_exception_init(&ex);
976 *isPlaying = libvlc_media_player_is_playing(p_md) ?
977 VARIANT_TRUE: VARIANT_FALSE;
978 libvlc_exception_clear(&ex);
983 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
988 if( 0 == SysStringLen(uri) )
991 libvlc_instance_t* p_libvlc;
992 HRESULT hr = getVLC(&p_libvlc);
995 libvlc_exception_t ex;
996 libvlc_exception_init(&ex);
998 char *psz_uri = NULL;
999 if( SysStringLen(Instance()->getBaseURL()) > 0 )
1002 ** if the MRL a relative URL, we should end up with an absolute URL
1004 LPWSTR abs_url = CombineURL(Instance()->getBaseURL(), uri);
1005 if( NULL != abs_url )
1007 psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
1008 CoTaskMemFree(abs_url);
1012 psz_uri = CStrFromBSTR(CP_UTF8, uri);
1018 ** baseURL is empty, assume MRL is absolute
1020 psz_uri = CStrFromBSTR(CP_UTF8, uri);
1023 if( NULL == psz_uri )
1025 return E_OUTOFMEMORY;
1029 char **ppsz_options;
1031 hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
1034 CoTaskMemFree(psz_uri);
1038 char *psz_name = NULL;
1040 VariantInit(&v_name);
1041 if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
1043 if( SysStringLen(V_BSTR(&v_name)) > 0 )
1044 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
1046 VariantClear(&v_name);
1049 *item = Instance()->playlist_add_extended_untrusted(psz_uri,
1050 i_options, const_cast<const char **>(ppsz_options), &ex);
1052 VLCControl::FreeTargetOptions(ppsz_options, i_options);
1053 CoTaskMemFree(psz_uri);
1054 if( psz_name ) /* XXX Do we even need to check? */
1055 CoTaskMemFree(psz_name);
1056 hr = exception_bridge(&ex);
1061 STDMETHODIMP VLCPlaylist::play()
1063 libvlc_exception_t ex;
1064 libvlc_exception_init(&ex);
1066 Instance()->playlist_play(&ex);
1067 return exception_bridge(&ex);
1070 STDMETHODIMP VLCPlaylist::playItem(long item)
1072 libvlc_exception_t ex;
1073 libvlc_exception_init(&ex);
1075 Instance()->playlist_play_item(item,&ex);
1076 return exception_bridge(&ex);;
1079 STDMETHODIMP VLCPlaylist::togglePause()
1081 libvlc_media_player_t* p_md;
1082 HRESULT hr = getMD(&p_md);
1085 libvlc_exception_t ex;
1086 libvlc_exception_init(&ex);
1088 libvlc_media_player_pause(p_md, &ex);
1089 hr = exception_bridge(&ex);;
1094 STDMETHODIMP VLCPlaylist::stop()
1096 libvlc_media_player_t *p_md;
1097 HRESULT hr = getMD(&p_md);
1100 libvlc_exception_t ex;
1101 libvlc_exception_init(&ex);
1103 libvlc_media_player_stop(p_md);
1104 hr = exception_bridge(&ex);;
1109 STDMETHODIMP VLCPlaylist::next()
1111 libvlc_exception_t ex;
1112 libvlc_exception_init(&ex);
1114 Instance()->playlist_next(&ex);
1115 return exception_bridge(&ex);;
1118 STDMETHODIMP VLCPlaylist::prev()
1120 libvlc_exception_t ex;
1121 libvlc_exception_init(&ex);
1123 Instance()->playlist_prev(&ex);
1124 return exception_bridge(&ex);;
1127 STDMETHODIMP VLCPlaylist::clear()
1129 libvlc_exception_t ex;
1130 libvlc_exception_init(&ex);
1132 Instance()->playlist_clear(&ex);
1133 return exception_bridge(&ex);;
1136 STDMETHODIMP VLCPlaylist::removeItem(long item)
1138 libvlc_instance_t* p_libvlc;
1139 HRESULT hr = getVLC(&p_libvlc);
1142 libvlc_exception_t ex;
1143 libvlc_exception_init(&ex);
1145 Instance()->playlist_delete_item(item, &ex);
1146 hr = exception_bridge(&ex);;
1151 STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
1156 *obj = _p_vlcplaylistitems;
1157 if( NULL != _p_vlcplaylistitems )
1159 _p_vlcplaylistitems->AddRef();
1162 return E_OUTOFMEMORY;
1165 /****************************************************************************/
1167 STDMETHODIMP VLCSubtitle::get_track(long* spu)
1172 libvlc_media_player_t *p_md;
1173 HRESULT hr = getMD(&p_md);
1176 libvlc_exception_t ex;
1177 libvlc_exception_init(&ex);
1179 *spu = libvlc_video_get_spu(p_md, &ex);
1180 hr = exception_bridge(&ex);
1185 STDMETHODIMP VLCSubtitle::put_track(long spu)
1187 libvlc_media_player_t *p_md;
1188 HRESULT hr = getMD(&p_md);
1191 libvlc_exception_t ex;
1192 libvlc_exception_init(&ex);
1194 libvlc_video_set_spu(p_md, spu, &ex);
1195 hr = exception_bridge(&ex);
1200 STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
1202 if( NULL == spuNumber )
1205 libvlc_media_player_t *p_md;
1206 HRESULT hr = getMD(&p_md);
1209 libvlc_exception_t ex;
1210 libvlc_exception_init(&ex);
1211 // get the number of video subtitle available and return it
1212 *spuNumber = libvlc_video_get_spu_count(p_md, &ex);
1213 hr = exception_bridge(&ex);
1219 STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
1224 libvlc_media_player_t* p_md;
1225 libvlc_exception_t ex;
1226 libvlc_exception_init(&ex);
1228 HRESULT hr = getMD(&p_md);
1232 const char *psz_name;
1233 libvlc_track_description_t *p_spuDesc;
1235 // get subtitles description
1236 p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
1237 hr = exception_bridge(&ex);
1241 // get the number of available subtitle
1242 i_limit = libvlc_video_get_spu_count(p_md, &ex);
1243 hr = exception_bridge(&ex);
1247 // check if the number given is a good one
1248 if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
1251 // get the good spuDesc
1252 for( i = 0 ; i < nameID ; i++ )
1254 p_spuDesc = p_spuDesc->p_next;
1256 // get the subtitle name
1257 psz_name = p_spuDesc->psz_name;
1260 if( psz_name != NULL )
1262 *name = BSTRFromCStr(CP_UTF8, psz_name);
1263 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
1271 /****************************************************************************/
1273 STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
1275 if( NULL == fullscreen )
1278 libvlc_media_player_t *p_md;
1279 HRESULT hr = getMD(&p_md);
1282 libvlc_exception_t ex;
1283 libvlc_exception_init(&ex);
1285 *fullscreen = libvlc_get_fullscreen(p_md, &ex) ?
1286 VARIANT_TRUE : VARIANT_FALSE;
1287 hr = exception_bridge(&ex);
1292 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
1294 libvlc_media_player_t *p_md;
1295 HRESULT hr = getMD(&p_md);
1298 libvlc_exception_t ex;
1299 libvlc_exception_init(&ex);
1301 libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen, &ex);
1302 hr = exception_bridge(&ex);
1307 STDMETHODIMP VLCVideo::get_width(long* width)
1312 libvlc_media_player_t *p_md;
1313 HRESULT hr = getMD(&p_md);
1316 libvlc_exception_t ex;
1317 libvlc_exception_init(&ex);
1319 *width = libvlc_video_get_width(p_md, &ex);
1320 hr = exception_bridge(&ex);
1325 STDMETHODIMP VLCVideo::get_height(long* height)
1327 if( NULL == height )
1330 libvlc_media_player_t *p_md;
1331 HRESULT hr = getMD(&p_md);
1334 libvlc_exception_t ex;
1335 libvlc_exception_init(&ex);
1337 *height = libvlc_video_get_height(p_md, &ex);
1338 hr = exception_bridge(&ex);
1343 STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
1345 if( NULL == aspect )
1348 libvlc_media_player_t *p_md;
1349 HRESULT hr = getMD(&p_md);
1352 libvlc_exception_t ex;
1353 libvlc_exception_init(&ex);
1355 char *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1357 hr = exception_bridge(&ex);
1358 if( SUCCEEDED(hr) && NULL != psz_aspect )
1360 *aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
1361 if( NULL == *aspect )
1363 } else if( NULL == psz_aspect) hr = E_OUTOFMEMORY; // strdup("") failed
1369 STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
1371 if( NULL == aspect )
1374 libvlc_media_player_t *p_md;
1375 HRESULT hr = getMD(&p_md);
1378 libvlc_exception_t ex;
1379 libvlc_exception_init(&ex);
1381 char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
1382 if( NULL == psz_aspect )
1384 return E_OUTOFMEMORY;
1387 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
1389 CoTaskMemFree(psz_aspect);
1390 hr = exception_bridge(&ex);
1395 STDMETHODIMP VLCVideo::get_subtitle(long* spu)
1400 libvlc_media_player_t *p_md;
1401 HRESULT hr = getMD(&p_md);
1404 libvlc_exception_t ex;
1405 libvlc_exception_init(&ex);
1407 *spu = libvlc_video_get_spu(p_md, &ex);
1408 hr = exception_bridge(&ex);
1413 STDMETHODIMP VLCVideo::put_subtitle(long spu)
1415 libvlc_media_player_t *p_md;
1416 HRESULT hr = getMD(&p_md);
1419 libvlc_exception_t ex;
1420 libvlc_exception_init(&ex);
1422 libvlc_video_set_spu(p_md, spu, &ex);
1423 hr = exception_bridge(&ex);
1428 STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
1430 if( NULL == geometry )
1433 libvlc_media_player_t *p_md;
1434 HRESULT hr = getMD(&p_md);
1437 libvlc_exception_t ex;
1438 libvlc_exception_init(&ex);
1440 char *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1442 hr = exception_bridge(&ex);
1443 if( SUCCEEDED(&ex) && NULL != psz_geometry )
1445 *geometry = BSTRFromCStr(CP_UTF8, psz_geometry);
1446 if( NULL == geometry ) hr = E_OUTOFMEMORY;
1447 } else if( NULL == psz_geometry ) hr = E_OUTOFMEMORY;
1448 free( psz_geometry );
1453 STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
1455 if( NULL == geometry )
1458 if( 0 == SysStringLen(geometry) )
1459 return E_INVALIDARG;
1461 libvlc_media_player_t *p_md;
1462 HRESULT hr = getMD(&p_md);
1465 libvlc_exception_t ex;
1466 libvlc_exception_init(&ex);
1468 char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
1469 if( NULL == psz_geometry )
1471 return E_OUTOFMEMORY;
1474 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
1476 CoTaskMemFree(psz_geometry);
1477 hr = exception_bridge(&ex);
1482 STDMETHODIMP VLCVideo::get_teletext(long* page)
1487 libvlc_media_player_t *p_md;
1488 HRESULT hr = getMD(&p_md);
1492 libvlc_exception_t ex;
1493 libvlc_exception_init(&ex);
1495 *page = libvlc_video_get_teletext(p_md);
1496 hr = exception_bridge(&ex);
1502 STDMETHODIMP VLCVideo::put_teletext(long page)
1505 libvlc_media_player_t *p_md;
1506 HRESULT hr = getMD(&p_md);
1510 libvlc_exception_t ex;
1511 libvlc_exception_init(&ex);
1513 libvlc_video_set_teletext(p_md, page);
1514 hr = exception_bridge(&ex);
1520 STDMETHODIMP VLCVideo::deinterlaceDisable()
1522 libvlc_media_player_t *p_md;
1523 HRESULT hr = getMD(&p_md);
1526 libvlc_exception_t ex;
1527 libvlc_exception_init(&ex);
1529 libvlc_video_set_deinterlace(p_md, 0, "", &ex);
1530 hr = exception_bridge(&ex);
1535 STDMETHODIMP VLCVideo::deinterlaceEnable(BSTR mode)
1537 libvlc_media_player_t *p_md;
1538 HRESULT hr = getMD(&p_md);
1541 libvlc_exception_t ex;
1542 libvlc_exception_init(&ex);
1543 /* get deinterlace mode from the user */
1544 char *psz_mode = CStrFromBSTR(CP_UTF8, mode);
1545 /* enable deinterlace filter if possible */
1546 libvlc_video_set_deinterlace(p_md, 1, psz_mode, &ex);
1547 hr = exception_bridge(&ex);
1548 CoTaskMemFree(psz_mode);
1553 STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
1555 if( NULL == picture )
1558 libvlc_media_player_t *p_md;
1559 HRESULT hr = getMD(&p_md);
1562 libvlc_exception_t ex;
1563 libvlc_exception_init(&ex);
1565 static int uniqueId = 0;
1566 TCHAR path[MAX_PATH+1];
1568 int pathlen = GetTempPath(MAX_PATH-24, path);
1569 if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
1572 /* check temp directory path by openning it */
1574 HANDLE dirHandle = CreateFile(path, GENERIC_READ,
1575 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1576 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1577 if( INVALID_HANDLE_VALUE == dirHandle )
1579 Instance()->setErrorInfo(IID_IVLCVideo,
1580 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1585 BY_HANDLE_FILE_INFORMATION bhfi;
1586 BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
1587 CloseHandle(dirHandle);
1588 if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
1590 Instance()->setErrorInfo(IID_IVLCVideo,
1591 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1597 TCHAR filepath[MAX_PATH+1];
1599 _stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
1600 path, GetCurrentProcessId(), ++uniqueId);
1603 /* reuse path storage for UTF8 string */
1604 char *psz_filepath = (char *)path;
1605 WCHAR* wpath = filepath;
1607 char *psz_filepath = path;
1608 /* first convert to unicode using current code page */
1609 WCHAR wpath[MAX_PATH+1];
1610 if( 0 == MultiByteToWideChar(CP_ACP, 0, filepath, -1,
1611 wpath, sizeof(wpath)/sizeof(WCHAR)) )
1614 /* convert to UTF8 */
1615 pathlen = WideCharToMultiByte(CP_UTF8, 0, wpath, -1,
1616 psz_filepath, sizeof(path), NULL, NULL);
1617 // fail if path is 0 or too short (i.e pathlen is the same as
1620 if( (0 == pathlen) || (sizeof(path) == pathlen) )
1623 /* take snapshot into file */
1624 libvlc_video_take_snapshot(p_md, psz_filepath, 0, 0, &ex);
1625 hr = exception_bridge(&ex);
1628 /* open snapshot file */
1629 HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP, 0, 0,
1630 LR_CREATEDIBSECTION|LR_LOADFROMFILE);
1635 snapDesc.cbSizeofstruct = sizeof(PICTDESC);
1636 snapDesc.picType = PICTYPE_BITMAP;
1637 snapDesc.bmp.hbitmap = (HBITMAP)snapPic;
1638 snapDesc.bmp.hpal = NULL;
1640 hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp,
1641 TRUE, (LPVOID*)picture);
1645 DeleteObject(snapPic);
1648 DeleteFile(filepath);
1654 STDMETHODIMP VLCVideo::toggleFullscreen()
1656 libvlc_media_player_t *p_md;
1657 HRESULT hr = getMD(&p_md);
1660 libvlc_exception_t ex;
1661 libvlc_exception_init(&ex);
1663 libvlc_toggle_fullscreen(p_md, &ex);
1664 hr = exception_bridge(&ex);
1669 STDMETHODIMP VLCVideo::toggleTeletext()
1671 libvlc_media_player_t *p_md;
1672 HRESULT hr = getMD(&p_md);
1675 libvlc_exception_t ex;
1676 libvlc_exception_init(&ex);
1678 libvlc_toggle_teletext(p_md, &ex);
1679 hr = exception_bridge(&ex);
1684 STDMETHODIMP VLCVideo::get_marquee(IVLCMarquee** obj)
1686 return object_get(obj,_p_vlcmarquee);
1689 STDMETHODIMP VLCVideo::get_logo(IVLCLogo** obj)
1691 return object_get(obj,_p_vlclogo);
1695 /****************************************************************************/
1697 HRESULT VLCLogo::do_put_int(unsigned idx, LONG val)
1699 libvlc_media_player_t *p_md;
1700 HRESULT hr = getMD(&p_md);
1703 libvlc_exception_t ex;
1704 libvlc_exception_init(&ex);
1705 libvlc_video_set_logo_int(p_md, idx, val, &ex);
1706 hr = exception_bridge(&ex);
1711 HRESULT VLCLogo::do_get_int(unsigned idx, LONG *val)
1716 libvlc_media_player_t *p_md;
1717 HRESULT hr = getMD(&p_md);
1720 libvlc_exception_t ex;
1721 libvlc_exception_init(&ex);
1722 *val = libvlc_video_get_logo_int(p_md, idx, &ex);
1723 hr = exception_bridge(&ex);
1728 STDMETHODIMP VLCLogo::file(BSTR fname)
1730 libvlc_media_player_t *p_md;
1731 HRESULT hr = getMD(&p_md);
1733 char *n = CStrFromBSTR(CP_UTF8, fname);
1734 if( !n ) hr = E_OUTOFMEMORY;
1738 libvlc_exception_t ex;
1739 libvlc_exception_init(&ex);
1740 libvlc_video_set_logo_string(p_md, libvlc_logo_file, n, &ex);
1741 hr = exception_bridge(&ex);
1748 STDMETHODIMP VLCLogo::get_position(BSTR* val)
1754 HRESULT hr = do_get_int(libvlc_logo_position, &i);
1757 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
1762 STDMETHODIMP VLCLogo::put_position(BSTR val)
1764 char *n = CStrFromBSTR(CP_UTF8, val);
1765 if( !n ) return E_OUTOFMEMORY;
1769 if( position_byname( n, i ) )
1770 hr = do_put_int(libvlc_logo_position,i);
1778 /****************************************************************************/
1780 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
1781 _p_instance(p_instance),
1783 _p_vlcaudio(new VLCAudio(p_instance)),
1784 _p_vlcinput(new VLCInput(p_instance)),
1785 _p_vlclog(new VLCLog(p_instance)),
1786 _p_vlcplaylist(new VLCPlaylist(p_instance)),
1787 _p_vlcsubtitle(new VLCSubtitle(p_instance)),
1788 _p_vlcvideo(new VLCVideo(p_instance))
1792 VLCControl2::~VLCControl2()
1795 delete _p_vlcsubtitle;
1796 delete _p_vlcplaylist;
1801 _p_typeinfo->Release();
1804 HRESULT VLCControl2::loadTypeInfo(void)
1806 HRESULT hr = NOERROR;
1807 if( NULL == _p_typeinfo )
1809 ITypeLib *p_typelib;
1811 hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1814 hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
1819 p_typelib->Release();
1825 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
1827 if( NULL == pctInfo )
1828 return E_INVALIDARG;
1830 if( SUCCEEDED(loadTypeInfo()) )
1838 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1840 if( NULL == ppTInfo )
1841 return E_INVALIDARG;
1843 if( SUCCEEDED(loadTypeInfo()) )
1845 _p_typeinfo->AddRef();
1846 *ppTInfo = _p_typeinfo;
1853 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1854 UINT cNames, LCID lcid, DISPID* rgDispID)
1856 if( SUCCEEDED(loadTypeInfo()) )
1858 return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1863 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
1864 LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1865 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1867 if( SUCCEEDED(loadTypeInfo()) )
1869 return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1870 pVarResult, pExcepInfo, puArgErr);
1875 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
1877 if( NULL == autoloop )
1880 *autoloop = _p_instance->getAutoLoop() ? VARIANT_TRUE: VARIANT_FALSE;
1884 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
1886 _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
1890 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
1892 if( NULL == autoplay )
1895 *autoplay = _p_instance->getAutoPlay() ? VARIANT_TRUE: VARIANT_FALSE;
1899 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
1901 _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
1905 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
1910 *url = SysAllocStringLen(_p_instance->getBaseURL(),
1911 SysStringLen(_p_instance->getBaseURL()));
1915 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
1917 _p_instance->setBaseURL(mrl);
1922 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
1927 *mrl = SysAllocStringLen(_p_instance->getMRL(),
1928 SysStringLen(_p_instance->getMRL()));
1932 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
1934 _p_instance->setMRL(mrl);
1940 STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
1942 if( NULL == visible )
1946 * Note to developers
1948 * Returning the _b_toolbar is closer to the method specification.
1949 * But returning True when toolbar is not implemented so not displayed
1950 * could be bad for ActiveX users which rely on this value to show their
1951 * own toolbar if not provided by the ActiveX.
1953 * This is the reason why FALSE is returned, until toolbar get implemented.
1956 /* DISABLED for now */
1957 // *visible = _p_instance->getShowToolbar() ? VARIANT_TRUE: VARIANT_FALSE;
1959 *visible = VARIANT_FALSE;
1964 STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
1966 _p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
1971 STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
1973 if( NULL == seconds )
1976 *seconds = _p_instance->getStartTime();
1981 STDMETHODIMP VLCControl2::put_StartTime(long seconds)
1983 _p_instance->setStartTime(seconds);
1988 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
1990 if( NULL == version )
1993 const char *versionStr = libvlc_get_version();
1994 if( NULL != versionStr )
1996 *version = BSTRFromCStr(CP_UTF8, versionStr);
1998 return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
2004 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
2006 if( NULL == isVisible )
2009 *isVisible = _p_instance->getVisible() ? VARIANT_TRUE : VARIANT_FALSE;
2014 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
2016 _p_instance->setVisible(isVisible != VARIANT_FALSE);
2021 STDMETHODIMP VLCControl2::get_Volume(long *volume)
2023 if( NULL == volume )
2026 *volume = _p_instance->getVolume();
2030 STDMETHODIMP VLCControl2::put_Volume(long volume)
2032 _p_instance->setVolume(volume);
2036 STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
2038 if( NULL == backcolor )
2041 *backcolor = _p_instance->getBackColor();
2045 STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
2047 _p_instance->setBackColor(backcolor);
2051 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
2053 return object_get(obj,_p_vlcaudio);
2056 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
2058 return object_get(obj,_p_vlcinput);
2061 STDMETHODIMP VLCControl2::get_log(IVLCLog** obj)
2063 return object_get(obj,_p_vlclog);
2066 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
2068 return object_get(obj,_p_vlcplaylist);
2071 STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
2073 return object_get(obj,_p_vlcsubtitle);
2076 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
2078 return object_get(obj,_p_vlcvideo);