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 )
82 STDMETHODIMP VLCAudio::get_mute(VARIANT_BOOL* mute)
87 libvlc_instance_t* p_libvlc;
88 HRESULT hr = getVLC(&p_libvlc);
90 *mute = libvlc_audio_get_mute(p_libvlc) ?
91 VARIANT_TRUE : VARIANT_FALSE;
95 STDMETHODIMP VLCAudio::put_mute(VARIANT_BOOL mute)
97 libvlc_instance_t* p_libvlc;
98 HRESULT hr = getVLC(&p_libvlc);
100 libvlc_audio_set_mute(p_libvlc, VARIANT_FALSE != mute);
104 STDMETHODIMP VLCAudio::get_volume(long* volume)
109 libvlc_instance_t* p_libvlc;
110 HRESULT hr = getVLC(&p_libvlc);
112 *volume = libvlc_audio_get_volume(p_libvlc);
116 STDMETHODIMP VLCAudio::put_volume(long volume)
118 libvlc_instance_t* p_libvlc;
119 HRESULT hr = getVLC(&p_libvlc);
122 libvlc_exception_t ex;
123 libvlc_exception_init(&ex);
125 libvlc_audio_set_volume(p_libvlc, volume, &ex);
126 hr = exception_bridge(&ex);
131 STDMETHODIMP VLCAudio::get_track(long* track)
136 libvlc_media_player_t* p_md;
137 HRESULT hr = getMD(&p_md);
140 libvlc_exception_t ex;
141 libvlc_exception_init(&ex);
143 *track = libvlc_audio_get_track(p_md, &ex);
144 hr = exception_bridge(&ex);
149 STDMETHODIMP VLCAudio::put_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 libvlc_audio_set_track(p_md, track, &ex);
159 hr = exception_bridge(&ex);
164 STDMETHODIMP VLCAudio::get_count(long* trackNumber)
166 if( NULL == trackNumber )
169 libvlc_media_player_t* p_md;
170 HRESULT hr = getMD(&p_md);
173 libvlc_exception_t ex;
174 libvlc_exception_init(&ex);
175 // get the number of audio track available and return it
176 *trackNumber = libvlc_audio_get_track_count(p_md, &ex);
177 hr = exception_bridge(&ex);
183 STDMETHODIMP VLCAudio::description(long trackID, BSTR* name)
188 libvlc_media_player_t* p_md;
189 libvlc_exception_t ex;
190 libvlc_exception_init(&ex);
192 HRESULT hr = getMD(&p_md);
196 const char *psz_name;
197 libvlc_track_description_t *p_trackDesc;
199 // get tracks description
200 p_trackDesc = libvlc_audio_get_track_description(p_md, &ex);
201 hr = exception_bridge(&ex);
205 //get the number of available track
206 i_limit = libvlc_audio_get_track_count(p_md, &ex);
207 hr = exception_bridge(&ex);
211 // check if the number given is a good one
212 if ( ( trackID > ( i_limit -1 ) ) || ( trackID < 0 ) )
215 // get the good trackDesc
216 for( i = 0 ; i < trackID ; i++ )
218 p_trackDesc = p_trackDesc->p_next;
220 // get the track name
221 psz_name = p_trackDesc->psz_name;
224 if( psz_name != NULL )
226 *name = BSTRFromCStr(CP_UTF8, psz_name);
227 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
235 STDMETHODIMP VLCAudio::get_channel(long *channel)
237 if( NULL == channel )
240 libvlc_instance_t* p_libvlc;
241 HRESULT hr = getVLC(&p_libvlc);
244 libvlc_exception_t ex;
245 libvlc_exception_init(&ex);
247 *channel = libvlc_audio_get_channel(p_libvlc, &ex);
248 hr = exception_bridge(&ex);
253 STDMETHODIMP VLCAudio::put_channel(long channel)
255 libvlc_instance_t* p_libvlc;
256 HRESULT hr = getVLC(&p_libvlc);
259 libvlc_exception_t ex;
260 libvlc_exception_init(&ex);
262 libvlc_audio_set_channel(p_libvlc, channel, &ex);
263 hr = exception_bridge(&ex);
268 STDMETHODIMP VLCAudio::toggleMute()
270 libvlc_instance_t* p_libvlc;
271 HRESULT hr = getVLC(&p_libvlc);
273 libvlc_audio_toggle_mute(p_libvlc);
277 /****************************************************************************/
279 STDMETHODIMP VLCInput::get_length(double* length)
285 libvlc_media_player_t *p_md;
286 HRESULT hr = getMD(&p_md);
289 libvlc_exception_t ex;
290 libvlc_exception_init(&ex);
292 *length = (double)libvlc_media_player_get_length(p_md, &ex);
293 hr = exception_bridge(&ex);
298 STDMETHODIMP VLCInput::get_position(double* position)
300 if( NULL == position )
304 libvlc_media_player_t *p_md;
305 HRESULT hr = getMD(&p_md);
308 libvlc_exception_t ex;
309 libvlc_exception_init(&ex);
311 *position = libvlc_media_player_get_position(p_md, &ex);
312 hr = exception_bridge(&ex);
317 STDMETHODIMP VLCInput::put_position(double 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 libvlc_media_player_set_position(p_md, position, &ex);
327 hr = exception_bridge(&ex);
332 STDMETHODIMP VLCInput::get_time(double* time)
337 libvlc_media_player_t *p_md;
338 HRESULT hr = getMD(&p_md);
341 libvlc_exception_t ex;
342 libvlc_exception_init(&ex);
344 *time = (double)libvlc_media_player_get_time(p_md, &ex);
345 hr = exception_bridge(&ex);
350 STDMETHODIMP VLCInput::put_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 libvlc_media_player_set_time(p_md, (int64_t)time, &ex);
360 hr = exception_bridge(&ex);
365 STDMETHODIMP VLCInput::get_state(long* state)
370 libvlc_media_player_t *p_md;
371 HRESULT hr = getMD(&p_md);
374 libvlc_exception_t ex;
375 libvlc_exception_init(&ex);
377 *state = libvlc_media_player_get_state(p_md, &ex);
378 if( libvlc_exception_raised(&ex) )
380 // don't fail, just return the idle state
382 libvlc_exception_clear(&ex);
388 STDMETHODIMP VLCInput::get_rate(double* rate)
393 libvlc_media_player_t *p_md;
394 HRESULT hr = getMD(&p_md);
397 libvlc_exception_t ex;
398 libvlc_exception_init(&ex);
400 *rate = libvlc_media_player_get_rate(p_md, &ex);
401 hr = exception_bridge(&ex);
406 STDMETHODIMP VLCInput::put_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 libvlc_media_player_set_rate(p_md, rate, &ex);
416 hr = exception_bridge(&ex);
421 STDMETHODIMP VLCInput::get_fps(double* fps)
427 libvlc_media_player_t *p_md;
428 HRESULT hr = getMD(&p_md);
431 libvlc_exception_t ex;
432 libvlc_exception_init(&ex);
434 *fps = libvlc_media_player_get_fps(p_md, &ex);
435 hr = exception_bridge(&ex);
440 STDMETHODIMP VLCInput::get_hasVout(VARIANT_BOOL* hasVout)
442 if( NULL == hasVout )
445 libvlc_media_player_t *p_md;
446 HRESULT hr = getMD(&p_md);
449 libvlc_exception_t ex;
450 libvlc_exception_init(&ex);
452 *hasVout = libvlc_media_player_has_vout(p_md, &ex) ?
453 VARIANT_TRUE : VARIANT_FALSE;
454 hr = exception_bridge(&ex);
459 /****************************************************************************/
463 delete _p_vlcmessages;
465 libvlc_log_close(_p_log);
468 STDMETHODIMP VLCLog::get_messages(IVLCMessages** obj)
473 *obj = _p_vlcmessages;
474 if( NULL != _p_vlcmessages )
476 _p_vlcmessages->AddRef();
479 return E_OUTOFMEMORY;
482 STDMETHODIMP VLCLog::get_verbosity(long* level)
489 libvlc_instance_t* p_libvlc;
490 HRESULT hr = getVLC(&p_libvlc);
492 *level = libvlc_get_log_verbosity(p_libvlc);
497 /* log is not enabled, return -1 */
503 STDMETHODIMP VLCLog::put_verbosity(long verbosity)
505 libvlc_instance_t* p_libvlc;
506 HRESULT hr = getVLC(&p_libvlc);
509 libvlc_exception_t ex;
510 libvlc_exception_init(&ex);
516 _p_log = libvlc_log_open(p_libvlc, &ex);
517 hr = exception_bridge(&ex);
520 libvlc_set_log_verbosity(p_libvlc, (unsigned)verbosity);
524 /* close log when verbosity is set to -1 */
525 libvlc_log_close(_p_log);
528 hr = exception_bridge(&ex);
533 /****************************************************************************/
535 HRESULT VLCMarquee::do_put_int(unsigned idx, LONG val)
537 libvlc_media_player_t *p_md;
538 HRESULT hr = getMD(&p_md);
541 libvlc_exception_t ex;
542 libvlc_exception_init(&ex);
543 libvlc_video_set_marquee_int(p_md, idx, val, &ex);
544 hr = exception_bridge(&ex);
549 HRESULT VLCMarquee::do_get_int(unsigned idx, LONG *val)
554 libvlc_media_player_t *p_md;
555 HRESULT hr = getMD(&p_md);
558 libvlc_exception_t ex;
559 libvlc_exception_init(&ex);
560 *val = libvlc_video_get_marquee_int(p_md, idx, &ex);
561 hr = exception_bridge(&ex);
566 STDMETHODIMP VLCMarquee::get_position(BSTR* val)
572 HRESULT hr = do_get_int(libvlc_marquee_Position, &i);
575 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
580 STDMETHODIMP VLCMarquee::put_position(BSTR val)
582 char *n = CStrFromBSTR(CP_UTF8, val);
583 if( !n ) return E_OUTOFMEMORY;
587 if( position_byname( n, i ) )
588 hr = do_put_int(libvlc_marquee_Position,i);
596 STDMETHODIMP VLCMarquee::get_text(BSTR *val)
602 libvlc_media_player_t *p_md;
603 HRESULT hr = getMD(&p_md);
606 libvlc_exception_t ex;
607 libvlc_exception_init(&ex);
609 psz = libvlc_video_get_marquee_string(p_md, libvlc_marquee_Text, &ex);
611 hr = exception_bridge(&ex);
613 *val = BSTRFromCStr(CP_UTF8, psz);
618 STDMETHODIMP VLCMarquee::put_text(BSTR val)
620 libvlc_media_player_t *p_md;
621 HRESULT hr = getMD(&p_md);
624 libvlc_exception_t ex;
625 libvlc_exception_init(&ex);
627 char *psz_text = CStrFromBSTR(CP_UTF8, val);
628 libvlc_video_set_marquee_string(p_md, libvlc_marquee_Text,
630 hr = exception_bridge(&ex);
631 CoTaskMemFree(psz_text);
636 /****************************************************************************/
638 /* STL forward iterator used by VLCEnumIterator class to implement IEnumVARIANT */
640 class VLCMessageSTLIterator
645 VLCMessageSTLIterator(IVLCMessageIterator* iter) : iter(iter), msg(NULL)
651 VLCMessageSTLIterator(const VLCMessageSTLIterator& other)
661 virtual ~VLCMessageSTLIterator()
670 // we only need prefix ++ operator
671 VLCMessageSTLIterator& operator++()
673 VARIANT_BOOL hasNext = VARIANT_FALSE;
676 iter->get_hasNext(&hasNext);
683 if( VARIANT_TRUE == hasNext ) {
690 VARIANT operator*() const
696 if( SUCCEEDED(msg->QueryInterface(IID_IDispatch,
697 (LPVOID*)&V_DISPATCH(&v))) )
699 V_VT(&v) = VT_DISPATCH;
705 bool operator==(const VLCMessageSTLIterator& other) const
707 return msg == other.msg;
710 bool operator!=(const VLCMessageSTLIterator& other) const
712 return msg != other.msg;
716 IVLCMessageIterator* iter;
720 //////////////////////////////////////////////////////////////////////////////
722 STDMETHODIMP VLCMessages::get__NewEnum(LPUNKNOWN* _NewEnum)
724 if( NULL == _NewEnum )
727 IVLCMessageIterator* iter = NULL;
730 *_NewEnum= new VLCEnumIterator<IID_IEnumVARIANT,
733 VLCMessageSTLIterator>
734 (VLCMessageSTLIterator(iter), VLCMessageSTLIterator(NULL));
736 return *_NewEnum ? S_OK : E_OUTOFMEMORY;
739 STDMETHODIMP VLCMessages::clear()
741 libvlc_log_t *p_log = _p_vlclog->_p_log;
743 libvlc_log_clear(p_log);
747 STDMETHODIMP VLCMessages::get_count(long* count)
752 libvlc_log_t *p_log = _p_vlclog->_p_log;
753 *count = libvlc_log_count(p_log);
757 STDMETHODIMP VLCMessages::iterator(IVLCMessageIterator** iter)
762 *iter = new VLCMessageIterator(Instance(), _p_vlclog);
764 return *iter ? S_OK : E_OUTOFMEMORY;
767 /****************************************************************************/
769 VLCMessageIterator::VLCMessageIterator(VLCPlugin *p, VLCLog* p_vlclog ):
770 VLCInterface<VLCMessageIterator,IVLCMessageIterator>(p),
773 _p_iter(_p_vlclog && _p_vlclog->_p_log ?
774 libvlc_log_get_iterator(_p_vlclog->_p_log, NULL) : NULL)
778 STDMETHODIMP VLCMessageIterator::get_hasNext(VARIANT_BOOL* hasNext)
780 if( NULL == hasNext )
783 *hasNext = (_p_iter && _p_vlclog->_p_log &&
784 libvlc_log_iterator_has_next(_p_iter)) ?
785 VARIANT_TRUE : VARIANT_FALSE;
789 STDMETHODIMP VLCMessageIterator::next(IVLCMessage** message)
793 if( NULL == message )
796 if( _p_iter && _p_vlclog->_p_log )
798 struct libvlc_log_message_t buffer;
800 buffer.sizeof_msg = sizeof(buffer);
802 libvlc_exception_t ex;
803 libvlc_exception_init(&ex);
805 libvlc_log_iterator_next(_p_iter, &buffer, &ex);
806 *message = new VLCMessage(Instance(), buffer);
813 /****************************************************************************/
815 inline const char *msgSeverity(int sev)
830 STDMETHODIMP VLCMessage::get__Value(VARIANT* _Value)
837 snprintf(buffer, sizeof(buffer), "%s %s %s: %s",
838 _msg.psz_type, _msg.psz_name, msgSeverity(_msg.i_severity), _msg.psz_message);
840 V_VT(_Value) = VT_BSTR;
841 V_BSTR(_Value) = BSTRFromCStr(CP_UTF8, buffer);
846 STDMETHODIMP VLCMessage::get_severity(long* level)
851 *level = _msg.i_severity;
856 STDMETHODIMP VLCMessage::get_type(BSTR* type)
861 *type = BSTRFromCStr(CP_UTF8, _msg.psz_type);
866 STDMETHODIMP VLCMessage::get_name(BSTR* name)
871 *name = BSTRFromCStr(CP_UTF8, _msg.psz_name);
876 STDMETHODIMP VLCMessage::get_header(BSTR* header)
881 *header = BSTRFromCStr(CP_UTF8, _msg.psz_header);
886 STDMETHODIMP VLCMessage::get_message(BSTR* message)
888 if( NULL == message )
891 *message = BSTRFromCStr(CP_UTF8, _msg.psz_message);
896 /****************************************************************************/
898 STDMETHODIMP VLCPlaylistItems::get_count(long* count)
903 libvlc_exception_t ex;
904 libvlc_exception_init(&ex);
906 *count = Instance()->playlist_count(&ex);
907 return exception_bridge(&ex);
910 STDMETHODIMP VLCPlaylistItems::clear()
912 libvlc_exception_t ex;
913 libvlc_exception_init(&ex);
915 Instance()->playlist_clear(&ex);
916 return exception_bridge(&ex);
919 STDMETHODIMP VLCPlaylistItems::remove(long item)
921 libvlc_instance_t* p_libvlc;
922 HRESULT hr = getVLC(&p_libvlc);
925 libvlc_exception_t ex;
926 libvlc_exception_init(&ex);
928 Instance()->playlist_delete_item(item, &ex);
929 hr = exception_bridge(&ex);
934 /****************************************************************************/
936 STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
942 libvlc_exception_t ex;
943 libvlc_exception_init(&ex);
945 *count = Instance()->playlist_count(&ex);
946 return exception_bridge(&ex);
949 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
951 if( NULL == isPlaying )
954 libvlc_media_player_t *p_md;
955 HRESULT hr = getMD(&p_md);
958 libvlc_exception_t ex;
959 libvlc_exception_init(&ex);
961 *isPlaying = libvlc_media_player_is_playing(p_md, &ex) ?
962 VARIANT_TRUE: VARIANT_FALSE;
963 libvlc_exception_clear(&ex);
968 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
973 if( 0 == SysStringLen(uri) )
976 libvlc_instance_t* p_libvlc;
977 HRESULT hr = getVLC(&p_libvlc);
980 libvlc_exception_t ex;
981 libvlc_exception_init(&ex);
983 char *psz_uri = NULL;
984 if( SysStringLen(Instance()->getBaseURL()) > 0 )
987 ** if the MRL a relative URL, we should end up with an absolute URL
989 LPWSTR abs_url = CombineURL(Instance()->getBaseURL(), uri);
990 if( NULL != abs_url )
992 psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
993 CoTaskMemFree(abs_url);
997 psz_uri = CStrFromBSTR(CP_UTF8, uri);
1003 ** baseURL is empty, assume MRL is absolute
1005 psz_uri = CStrFromBSTR(CP_UTF8, uri);
1008 if( NULL == psz_uri )
1010 return E_OUTOFMEMORY;
1014 char **ppsz_options;
1016 hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
1019 CoTaskMemFree(psz_uri);
1023 char *psz_name = NULL;
1025 VariantInit(&v_name);
1026 if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
1028 if( SysStringLen(V_BSTR(&v_name)) > 0 )
1029 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
1031 VariantClear(&v_name);
1034 *item = Instance()->playlist_add_extended_untrusted(psz_uri,
1035 i_options, const_cast<const char **>(ppsz_options), &ex);
1037 VLCControl::FreeTargetOptions(ppsz_options, i_options);
1038 CoTaskMemFree(psz_uri);
1039 if( psz_name ) /* XXX Do we even need to check? */
1040 CoTaskMemFree(psz_name);
1041 hr = exception_bridge(&ex);
1046 STDMETHODIMP VLCPlaylist::play()
1048 libvlc_exception_t ex;
1049 libvlc_exception_init(&ex);
1051 Instance()->playlist_play(&ex);
1052 return exception_bridge(&ex);
1055 STDMETHODIMP VLCPlaylist::playItem(long item)
1057 libvlc_exception_t ex;
1058 libvlc_exception_init(&ex);
1060 Instance()->playlist_play_item(item,&ex);
1061 return exception_bridge(&ex);;
1064 STDMETHODIMP VLCPlaylist::togglePause()
1066 libvlc_media_player_t* p_md;
1067 HRESULT hr = getMD(&p_md);
1070 libvlc_exception_t ex;
1071 libvlc_exception_init(&ex);
1073 libvlc_media_player_pause(p_md, &ex);
1074 hr = exception_bridge(&ex);;
1079 STDMETHODIMP VLCPlaylist::stop()
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_stop(p_md, &ex);
1089 hr = exception_bridge(&ex);;
1094 STDMETHODIMP VLCPlaylist::next()
1096 libvlc_exception_t ex;
1097 libvlc_exception_init(&ex);
1099 Instance()->playlist_next(&ex);
1100 return exception_bridge(&ex);;
1103 STDMETHODIMP VLCPlaylist::prev()
1105 libvlc_exception_t ex;
1106 libvlc_exception_init(&ex);
1108 Instance()->playlist_prev(&ex);
1109 return exception_bridge(&ex);;
1112 STDMETHODIMP VLCPlaylist::clear()
1114 libvlc_exception_t ex;
1115 libvlc_exception_init(&ex);
1117 Instance()->playlist_clear(&ex);
1118 return exception_bridge(&ex);;
1121 STDMETHODIMP VLCPlaylist::removeItem(long item)
1123 libvlc_instance_t* p_libvlc;
1124 HRESULT hr = getVLC(&p_libvlc);
1127 libvlc_exception_t ex;
1128 libvlc_exception_init(&ex);
1130 Instance()->playlist_delete_item(item, &ex);
1131 hr = exception_bridge(&ex);;
1136 STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
1141 *obj = _p_vlcplaylistitems;
1142 if( NULL != _p_vlcplaylistitems )
1144 _p_vlcplaylistitems->AddRef();
1147 return E_OUTOFMEMORY;
1150 /****************************************************************************/
1152 STDMETHODIMP VLCSubtitle::get_track(long* spu)
1157 libvlc_media_player_t *p_md;
1158 HRESULT hr = getMD(&p_md);
1161 libvlc_exception_t ex;
1162 libvlc_exception_init(&ex);
1164 *spu = libvlc_video_get_spu(p_md, &ex);
1165 hr = exception_bridge(&ex);
1170 STDMETHODIMP VLCSubtitle::put_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 libvlc_video_set_spu(p_md, spu, &ex);
1180 hr = exception_bridge(&ex);
1185 STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
1187 if( NULL == spuNumber )
1190 libvlc_media_player_t *p_md;
1191 HRESULT hr = getMD(&p_md);
1194 libvlc_exception_t ex;
1195 libvlc_exception_init(&ex);
1196 // get the number of video subtitle available and return it
1197 *spuNumber = libvlc_video_get_spu_count(p_md, &ex);
1198 hr = exception_bridge(&ex);
1204 STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
1209 libvlc_media_player_t* p_md;
1210 libvlc_exception_t ex;
1211 libvlc_exception_init(&ex);
1213 HRESULT hr = getMD(&p_md);
1217 const char *psz_name;
1218 libvlc_track_description_t *p_spuDesc;
1220 // get subtitles description
1221 p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
1222 hr = exception_bridge(&ex);
1226 // get the number of available subtitle
1227 i_limit = libvlc_video_get_spu_count(p_md, &ex);
1228 hr = exception_bridge(&ex);
1232 // check if the number given is a good one
1233 if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
1236 // get the good spuDesc
1237 for( i = 0 ; i < nameID ; i++ )
1239 p_spuDesc = p_spuDesc->p_next;
1241 // get the subtitle name
1242 psz_name = p_spuDesc->psz_name;
1245 if( psz_name != NULL )
1247 *name = BSTRFromCStr(CP_UTF8, psz_name);
1248 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
1256 /****************************************************************************/
1258 STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
1260 if( NULL == fullscreen )
1263 libvlc_media_player_t *p_md;
1264 HRESULT hr = getMD(&p_md);
1267 libvlc_exception_t ex;
1268 libvlc_exception_init(&ex);
1270 *fullscreen = libvlc_get_fullscreen(p_md, &ex) ?
1271 VARIANT_TRUE : VARIANT_FALSE;
1272 hr = exception_bridge(&ex);
1277 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
1279 libvlc_media_player_t *p_md;
1280 HRESULT hr = getMD(&p_md);
1283 libvlc_exception_t ex;
1284 libvlc_exception_init(&ex);
1286 libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen, &ex);
1287 hr = exception_bridge(&ex);
1292 STDMETHODIMP VLCVideo::get_width(long* width)
1297 libvlc_media_player_t *p_md;
1298 HRESULT hr = getMD(&p_md);
1301 libvlc_exception_t ex;
1302 libvlc_exception_init(&ex);
1304 *width = libvlc_video_get_width(p_md, &ex);
1305 hr = exception_bridge(&ex);
1310 STDMETHODIMP VLCVideo::get_height(long* height)
1312 if( NULL == height )
1315 libvlc_media_player_t *p_md;
1316 HRESULT hr = getMD(&p_md);
1319 libvlc_exception_t ex;
1320 libvlc_exception_init(&ex);
1322 *height = libvlc_video_get_height(p_md, &ex);
1323 hr = exception_bridge(&ex);
1328 STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
1330 if( NULL == aspect )
1333 libvlc_media_player_t *p_md;
1334 HRESULT hr = getMD(&p_md);
1337 libvlc_exception_t ex;
1338 libvlc_exception_init(&ex);
1340 char *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
1342 hr = exception_bridge(&ex);
1343 if( SUCCEEDED(hr) && NULL != psz_aspect )
1345 *aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
1346 if( NULL == *aspect )
1348 } else if( NULL == psz_aspect) hr = E_OUTOFMEMORY; // strdup("") failed
1354 STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
1356 if( NULL == aspect )
1359 libvlc_media_player_t *p_md;
1360 HRESULT hr = getMD(&p_md);
1363 libvlc_exception_t ex;
1364 libvlc_exception_init(&ex);
1366 char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
1367 if( NULL == psz_aspect )
1369 return E_OUTOFMEMORY;
1372 libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
1374 CoTaskMemFree(psz_aspect);
1375 hr = exception_bridge(&ex);
1380 STDMETHODIMP VLCVideo::get_subtitle(long* spu)
1385 libvlc_media_player_t *p_md;
1386 HRESULT hr = getMD(&p_md);
1389 libvlc_exception_t ex;
1390 libvlc_exception_init(&ex);
1392 *spu = libvlc_video_get_spu(p_md, &ex);
1393 hr = exception_bridge(&ex);
1398 STDMETHODIMP VLCVideo::put_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 libvlc_video_set_spu(p_md, spu, &ex);
1408 hr = exception_bridge(&ex);
1413 STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
1415 if( NULL == geometry )
1418 libvlc_media_player_t *p_md;
1419 HRESULT hr = getMD(&p_md);
1422 libvlc_exception_t ex;
1423 libvlc_exception_init(&ex);
1425 char *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
1427 hr = exception_bridge(&ex);
1428 if( SUCCEEDED(&ex) && NULL != psz_geometry )
1430 *geometry = BSTRFromCStr(CP_UTF8, psz_geometry);
1431 if( NULL == geometry ) hr = E_OUTOFMEMORY;
1432 } else if( NULL == psz_geometry ) hr = E_OUTOFMEMORY;
1433 free( psz_geometry );
1438 STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
1440 if( NULL == geometry )
1443 if( 0 == SysStringLen(geometry) )
1444 return E_INVALIDARG;
1446 libvlc_media_player_t *p_md;
1447 HRESULT hr = getMD(&p_md);
1450 libvlc_exception_t ex;
1451 libvlc_exception_init(&ex);
1453 char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
1454 if( NULL == psz_geometry )
1456 return E_OUTOFMEMORY;
1459 libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
1461 CoTaskMemFree(psz_geometry);
1462 hr = exception_bridge(&ex);
1467 STDMETHODIMP VLCVideo::get_teletext(long* page)
1472 libvlc_media_player_t *p_md;
1473 HRESULT hr = getMD(&p_md);
1476 libvlc_exception_t ex;
1477 libvlc_exception_init(&ex);
1479 *page = libvlc_video_get_teletext(p_md, &ex);
1480 hr = exception_bridge(&ex);
1485 STDMETHODIMP VLCVideo::put_teletext(long page)
1487 libvlc_media_player_t *p_md;
1488 HRESULT hr = getMD(&p_md);
1491 libvlc_exception_t ex;
1492 libvlc_exception_init(&ex);
1494 libvlc_video_set_teletext(p_md, page, &ex);
1495 hr = exception_bridge(&ex);
1500 STDMETHODIMP VLCVideo::deinterlaceDisable()
1502 libvlc_media_player_t *p_md;
1503 HRESULT hr = getMD(&p_md);
1506 libvlc_exception_t ex;
1507 libvlc_exception_init(&ex);
1509 libvlc_video_set_deinterlace(p_md, 0, "", &ex);
1510 hr = exception_bridge(&ex);
1515 STDMETHODIMP VLCVideo::deinterlaceEnable(BSTR mode)
1517 libvlc_media_player_t *p_md;
1518 HRESULT hr = getMD(&p_md);
1521 libvlc_exception_t ex;
1522 libvlc_exception_init(&ex);
1523 /* get deinterlace mode from the user */
1524 char *psz_mode = CStrFromBSTR(CP_UTF8, mode);
1525 /* enable deinterlace filter if possible */
1526 libvlc_video_set_deinterlace(p_md, 1, psz_mode, &ex);
1527 hr = exception_bridge(&ex);
1528 CoTaskMemFree(psz_mode);
1533 STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
1535 if( NULL == picture )
1538 libvlc_media_player_t *p_md;
1539 HRESULT hr = getMD(&p_md);
1542 libvlc_exception_t ex;
1543 libvlc_exception_init(&ex);
1545 static int uniqueId = 0;
1546 TCHAR path[MAX_PATH+1];
1548 int pathlen = GetTempPath(MAX_PATH-24, path);
1549 if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
1552 /* check temp directory path by openning it */
1554 HANDLE dirHandle = CreateFile(path, GENERIC_READ,
1555 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1556 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1557 if( INVALID_HANDLE_VALUE == dirHandle )
1559 Instance()->setErrorInfo(IID_IVLCVideo,
1560 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1565 BY_HANDLE_FILE_INFORMATION bhfi;
1566 BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
1567 CloseHandle(dirHandle);
1568 if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
1570 Instance()->setErrorInfo(IID_IVLCVideo,
1571 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1577 TCHAR filepath[MAX_PATH+1];
1579 _stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
1580 path, GetCurrentProcessId(), ++uniqueId);
1583 /* reuse path storage for UTF8 string */
1584 char *psz_filepath = (char *)path;
1585 WCHAR* wpath = filepath;
1587 char *psz_filepath = path;
1588 /* first convert to unicode using current code page */
1589 WCHAR wpath[MAX_PATH+1];
1590 if( 0 == MultiByteToWideChar(CP_ACP, 0, filepath, -1,
1591 wpath, sizeof(wpath)/sizeof(WCHAR)) )
1594 /* convert to UTF8 */
1595 pathlen = WideCharToMultiByte(CP_UTF8, 0, wpath, -1,
1596 psz_filepath, sizeof(path), NULL, NULL);
1597 // fail if path is 0 or too short (i.e pathlen is the same as
1600 if( (0 == pathlen) || (sizeof(path) == pathlen) )
1603 /* take snapshot into file */
1604 libvlc_video_take_snapshot(p_md, psz_filepath, 0, 0, &ex);
1605 hr = exception_bridge(&ex);
1608 /* open snapshot file */
1609 HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP, 0, 0,
1610 LR_CREATEDIBSECTION|LR_LOADFROMFILE);
1615 snapDesc.cbSizeofstruct = sizeof(PICTDESC);
1616 snapDesc.picType = PICTYPE_BITMAP;
1617 snapDesc.bmp.hbitmap = (HBITMAP)snapPic;
1618 snapDesc.bmp.hpal = NULL;
1620 hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp,
1621 TRUE, (LPVOID*)picture);
1625 DeleteObject(snapPic);
1628 DeleteFile(filepath);
1634 STDMETHODIMP VLCVideo::toggleFullscreen()
1636 libvlc_media_player_t *p_md;
1637 HRESULT hr = getMD(&p_md);
1640 libvlc_exception_t ex;
1641 libvlc_exception_init(&ex);
1643 libvlc_toggle_fullscreen(p_md, &ex);
1644 hr = exception_bridge(&ex);
1649 STDMETHODIMP VLCVideo::toggleTeletext()
1651 libvlc_media_player_t *p_md;
1652 HRESULT hr = getMD(&p_md);
1655 libvlc_exception_t ex;
1656 libvlc_exception_init(&ex);
1658 libvlc_toggle_teletext(p_md, &ex);
1659 hr = exception_bridge(&ex);
1664 STDMETHODIMP VLCVideo::get_marquee(IVLCMarquee** obj)
1669 *obj = _p_vlcmarquee;
1670 if( NULL != _p_vlcmarquee )
1672 _p_vlcmarquee->AddRef();
1675 return E_OUTOFMEMORY;
1678 STDMETHODIMP VLCVideo::get_logo(IVLCLogo** obj)
1684 if( NULL != _p_vlclogo )
1686 _p_vlclogo->AddRef();
1689 return E_OUTOFMEMORY;
1693 /****************************************************************************/
1695 HRESULT VLCLogo::do_put_int(unsigned idx, LONG val)
1697 libvlc_media_player_t *p_md;
1698 HRESULT hr = getMD(&p_md);
1701 libvlc_exception_t ex;
1702 libvlc_exception_init(&ex);
1703 libvlc_video_set_logo_int(p_md, idx, val, &ex);
1704 hr = exception_bridge(&ex);
1709 HRESULT VLCLogo::do_get_int(unsigned idx, LONG *val)
1714 libvlc_media_player_t *p_md;
1715 HRESULT hr = getMD(&p_md);
1718 libvlc_exception_t ex;
1719 libvlc_exception_init(&ex);
1720 *val = libvlc_video_get_logo_int(p_md, idx, &ex);
1721 hr = exception_bridge(&ex);
1726 STDMETHODIMP VLCLogo::file(BSTR fname)
1728 libvlc_media_player_t *p_md;
1729 HRESULT hr = getMD(&p_md);
1731 char *n = CStrFromBSTR(CP_UTF8, fname);
1732 if( !n ) hr = E_OUTOFMEMORY;
1736 libvlc_exception_t ex;
1737 libvlc_exception_init(&ex);
1738 libvlc_video_set_logo_string(p_md, libvlc_logo_file, n, &ex);
1739 hr = exception_bridge(&ex);
1746 STDMETHODIMP VLCLogo::get_position(BSTR* val)
1752 HRESULT hr = do_get_int(libvlc_logo_position, &i);
1755 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
1760 STDMETHODIMP VLCLogo::put_position(BSTR val)
1762 char *n = CStrFromBSTR(CP_UTF8, val);
1763 if( !n ) return E_OUTOFMEMORY;
1767 if( position_byname( n, i ) )
1768 hr = do_put_int(libvlc_logo_position,i);
1776 /****************************************************************************/
1778 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
1779 _p_instance(p_instance),
1781 _p_vlcaudio(new VLCAudio(p_instance)),
1782 _p_vlcinput(new VLCInput(p_instance)),
1783 _p_vlclog(new VLCLog(p_instance)),
1784 _p_vlcplaylist(new VLCPlaylist(p_instance)),
1785 _p_vlcsubtitle(new VLCSubtitle(p_instance)),
1786 _p_vlcvideo(new VLCVideo(p_instance))
1790 VLCControl2::~VLCControl2()
1793 delete _p_vlcsubtitle;
1794 delete _p_vlcplaylist;
1799 _p_typeinfo->Release();
1802 HRESULT VLCControl2::loadTypeInfo(void)
1804 HRESULT hr = NOERROR;
1805 if( NULL == _p_typeinfo )
1807 ITypeLib *p_typelib;
1809 hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1812 hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
1817 p_typelib->Release();
1823 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
1825 if( NULL == pctInfo )
1826 return E_INVALIDARG;
1828 if( SUCCEEDED(loadTypeInfo()) )
1836 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1838 if( NULL == ppTInfo )
1839 return E_INVALIDARG;
1841 if( SUCCEEDED(loadTypeInfo()) )
1843 _p_typeinfo->AddRef();
1844 *ppTInfo = _p_typeinfo;
1851 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1852 UINT cNames, LCID lcid, DISPID* rgDispID)
1854 if( SUCCEEDED(loadTypeInfo()) )
1856 return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1861 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
1862 LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1863 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1865 if( SUCCEEDED(loadTypeInfo()) )
1867 return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1868 pVarResult, pExcepInfo, puArgErr);
1873 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
1875 if( NULL == autoloop )
1878 *autoloop = _p_instance->getAutoLoop() ? VARIANT_TRUE: VARIANT_FALSE;
1882 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
1884 _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
1888 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
1890 if( NULL == autoplay )
1893 *autoplay = _p_instance->getAutoPlay() ? VARIANT_TRUE: VARIANT_FALSE;
1897 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
1899 _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
1903 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
1908 *url = SysAllocStringLen(_p_instance->getBaseURL(),
1909 SysStringLen(_p_instance->getBaseURL()));
1913 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
1915 _p_instance->setBaseURL(mrl);
1920 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
1925 *mrl = SysAllocStringLen(_p_instance->getMRL(),
1926 SysStringLen(_p_instance->getMRL()));
1930 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
1932 _p_instance->setMRL(mrl);
1938 STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
1940 if( NULL == visible )
1944 * Note to developers
1946 * Returning the _b_toolbar is closer to the method specification.
1947 * But returning True when toolbar is not implemented so not displayed
1948 * could be bad for ActiveX users which rely on this value to show their
1949 * own toolbar if not provided by the ActiveX.
1951 * This is the reason why FALSE is returned, until toolbar get implemented.
1954 /* DISABLED for now */
1955 // *visible = _p_instance->getShowToolbar() ? VARIANT_TRUE: VARIANT_FALSE;
1957 *visible = VARIANT_FALSE;
1962 STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
1964 _p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
1969 STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
1971 if( NULL == seconds )
1974 *seconds = _p_instance->getStartTime();
1979 STDMETHODIMP VLCControl2::put_StartTime(long seconds)
1981 _p_instance->setStartTime(seconds);
1986 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
1988 if( NULL == version )
1991 const char *versionStr = libvlc_get_version();
1992 if( NULL != versionStr )
1994 *version = BSTRFromCStr(CP_UTF8, versionStr);
1996 return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
2002 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
2004 if( NULL == isVisible )
2007 *isVisible = _p_instance->getVisible() ? VARIANT_TRUE : VARIANT_FALSE;
2012 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
2014 _p_instance->setVisible(isVisible != VARIANT_FALSE);
2019 STDMETHODIMP VLCControl2::get_Volume(long *volume)
2021 if( NULL == volume )
2024 *volume = _p_instance->getVolume();
2028 STDMETHODIMP VLCControl2::put_Volume(long volume)
2030 _p_instance->setVolume(volume);
2034 STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
2036 if( NULL == backcolor )
2039 *backcolor = _p_instance->getBackColor();
2043 STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
2045 _p_instance->setBackColor(backcolor);
2049 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
2055 if( NULL != _p_vlcaudio )
2057 _p_vlcaudio->AddRef();
2060 return E_OUTOFMEMORY;
2063 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
2069 if( NULL != _p_vlcinput )
2071 _p_vlcinput->AddRef();
2074 return E_OUTOFMEMORY;
2077 STDMETHODIMP VLCControl2::get_log(IVLCLog** obj)
2083 if( NULL != _p_vlclog )
2085 _p_vlclog->AddRef();
2088 return E_OUTOFMEMORY;
2091 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
2096 *obj = _p_vlcplaylist;
2097 if( NULL != _p_vlcplaylist )
2099 _p_vlcplaylist->AddRef();
2102 return E_OUTOFMEMORY;
2105 STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
2110 *obj = _p_vlcsubtitle;
2111 if( NULL != _p_vlcsubtitle )
2113 _p_vlcsubtitle->AddRef();
2116 return E_OUTOFMEMORY;
2119 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
2125 if( NULL != _p_vlcvideo )
2127 _p_vlcvideo->AddRef();
2130 return E_OUTOFMEMORY;