Put size check before data dereference
[vlc/asuraparaju-public.git] / projects / activex / vlccontrol2.cpp
blob2940e4e4e97b6d033041eebab01d8e19bc3c31d4
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 *****************************************************************************/
25 #include <stdio.h>
26 #include <shlwapi.h>
27 #include <wininet.h>
28 #include <tchar.h>
30 #include "utils.h"
31 #include "plugin.h"
32 #include "vlccontrol2.h"
33 #include "vlccontrol.h"
35 #include "position.h"
37 // ---------
39 HRESULT VLCInterfaceBase::loadTypeInfo(REFIID riid)
41 // if( _ti ) return NOERROR; // unnecessairy
43 ITypeLib *p_typelib;
44 HRESULT hr = _plug->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
45 if( SUCCEEDED(hr) )
47 hr = p_typelib->GetTypeInfoOfGuid(riid, &_ti);
48 if( FAILED(hr) ) _ti = NULL;
49 p_typelib->Release();
51 return hr;
54 #define BIND_INTERFACE( class ) \
55 template<> REFIID VLCInterface<class, I##class>::_riid = IID_I##class;
57 BIND_INTERFACE( VLCAudio )
58 BIND_INTERFACE( VLCInput )
59 BIND_INTERFACE( VLCMarquee )
60 BIND_INTERFACE( VLCLogo )
61 BIND_INTERFACE( VLCDeinterlace )
62 BIND_INTERFACE( VLCPlaylistItems )
63 BIND_INTERFACE( VLCPlaylist )
64 BIND_INTERFACE( VLCVideo )
65 BIND_INTERFACE( VLCSubtitle )
67 #undef BIND_INTERFACE
69 template<class I> static inline
70 HRESULT object_get(I **dst, I *src)
72 if( NULL == dst )
73 return E_POINTER;
75 *dst = src;
76 if( NULL != src )
78 src->AddRef();
79 return NOERROR;
81 return E_OUTOFMEMORY;
84 static inline
85 VARIANT_BOOL varbool(bool b) { return b ? VARIANT_TRUE : VARIANT_FALSE; }
87 // ---------
89 STDMETHODIMP VLCAudio::get_mute(VARIANT_BOOL* mute)
91 if( NULL == mute )
92 return E_POINTER;
94 libvlc_media_player_t *p_md;
95 HRESULT hr = getMD(&p_md);
96 if( SUCCEEDED(hr) )
97 *mute = varbool( libvlc_audio_get_mute(p_md) );
98 return hr;
101 STDMETHODIMP VLCAudio::put_mute(VARIANT_BOOL mute)
103 libvlc_media_player_t *p_md;
104 HRESULT hr = getMD(&p_md);
105 if( SUCCEEDED(hr) )
106 libvlc_audio_set_mute(p_md, VARIANT_FALSE != mute);
107 return hr;
110 STDMETHODIMP VLCAudio::get_volume(long* volume)
112 if( NULL == volume )
113 return E_POINTER;
115 libvlc_media_player_t *p_md;
116 HRESULT hr = getMD(&p_md);
117 if( SUCCEEDED(hr) )
118 *volume = libvlc_audio_get_volume(p_md);
119 return hr;
122 STDMETHODIMP VLCAudio::put_volume(long volume)
124 libvlc_media_player_t *p_md;
125 HRESULT hr = getMD(&p_md);
126 if( SUCCEEDED(hr) )
128 libvlc_audio_set_volume(p_md, volume);
130 return hr;
133 STDMETHODIMP VLCAudio::get_track(long* track)
135 if( NULL == track )
136 return E_POINTER;
138 libvlc_media_player_t* p_md;
139 HRESULT hr = getMD(&p_md);
140 if( SUCCEEDED(hr) )
142 *track = libvlc_audio_get_track(p_md);
144 return hr;
147 STDMETHODIMP VLCAudio::put_track(long track)
149 libvlc_media_player_t *p_md;
150 HRESULT hr = getMD(&p_md);
151 if( SUCCEEDED(hr) )
153 libvlc_audio_set_track(p_md, track);
155 return hr;
158 STDMETHODIMP VLCAudio::get_count(long* trackNumber)
160 if( NULL == trackNumber )
161 return E_POINTER;
163 libvlc_media_player_t* p_md;
164 HRESULT hr = getMD(&p_md);
165 if( SUCCEEDED(hr) )
167 // get the number of audio track available and return it
168 *trackNumber = libvlc_audio_get_track_count(p_md);
170 return hr;
174 STDMETHODIMP VLCAudio::description(long trackID, BSTR* name)
176 if( NULL == name )
177 return E_POINTER;
179 libvlc_media_player_t* p_md;
181 HRESULT hr = getMD(&p_md);
182 if( SUCCEEDED(hr) )
184 int i, i_limit;
185 const char *psz_name;
186 libvlc_track_description_t *p_trackDesc;
188 // get tracks description
189 p_trackDesc = libvlc_audio_get_track_description(p_md);
190 if( !p_trackDesc )
191 return E_FAIL;
193 //get the number of available track
194 i_limit = libvlc_audio_get_track_count(p_md);
195 if( i_limit < 0 )
196 return E_FAIL;
198 // check if the number given is a good one
199 if ( ( trackID > ( i_limit -1 ) ) || ( trackID < 0 ) )
200 return E_FAIL;
202 // get the good trackDesc
203 for( i = 0 ; i < trackID ; i++ )
205 p_trackDesc = p_trackDesc->p_next;
207 // get the track name
208 psz_name = p_trackDesc->psz_name;
210 // return it
211 if( psz_name != NULL )
213 *name = BSTRFromCStr(CP_UTF8, psz_name);
214 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
216 *name = NULL;
217 return E_FAIL;
219 return hr;
222 STDMETHODIMP VLCAudio::get_channel(long *channel)
224 if( NULL == channel )
225 return E_POINTER;
227 libvlc_media_player_t *p_md;
228 HRESULT hr = getMD(&p_md);
229 if( SUCCEEDED(hr) )
231 *channel = libvlc_audio_get_channel(p_md);
233 return hr;
236 STDMETHODIMP VLCAudio::put_channel(long channel)
238 libvlc_media_player_t *p_md;
239 HRESULT hr = getMD(&p_md);
240 if( SUCCEEDED(hr) )
242 libvlc_audio_set_channel(p_md, channel);
244 return hr;
247 STDMETHODIMP VLCAudio::toggleMute()
249 libvlc_media_player_t *p_md;
250 HRESULT hr = getMD(&p_md);
251 if( SUCCEEDED(hr) )
252 libvlc_audio_toggle_mute(p_md);
253 return hr;
256 /****************************************************************************/
258 STDMETHODIMP VLCDeinterlace::disable()
260 libvlc_media_player_t *p_md;
261 HRESULT hr = getMD(&p_md);
262 if( SUCCEEDED(hr) )
264 libvlc_video_set_deinterlace(p_md, "");
266 return hr;
269 STDMETHODIMP VLCDeinterlace::enable(BSTR mode)
271 libvlc_media_player_t *p_md;
272 HRESULT hr = getMD(&p_md);
273 if( SUCCEEDED(hr) )
275 char *psz_mode = CStrFromBSTR(CP_UTF8, mode);
276 libvlc_video_set_deinterlace(p_md, psz_mode);
277 CoTaskMemFree(psz_mode);
279 return hr;
282 /****************************************************************************/
284 STDMETHODIMP VLCInput::get_length(double* length)
286 if( NULL == length )
287 return E_POINTER;
288 *length = 0;
290 libvlc_media_player_t *p_md;
291 HRESULT hr = getMD(&p_md);
292 if( SUCCEEDED(hr) )
294 *length = (double)libvlc_media_player_get_length(p_md);
296 return hr;
299 STDMETHODIMP VLCInput::get_position(double* position)
301 if( NULL == position )
302 return E_POINTER;
304 *position = 0.0f;
305 libvlc_media_player_t *p_md;
306 HRESULT hr = getMD(&p_md);
307 if( SUCCEEDED(hr) )
309 *position = libvlc_media_player_get_position(p_md);
311 return hr;
314 STDMETHODIMP VLCInput::put_position(double position)
316 libvlc_media_player_t *p_md;
317 HRESULT hr = getMD(&p_md);
318 if( SUCCEEDED(hr) )
320 libvlc_media_player_set_position(p_md, position);
322 return hr;
325 STDMETHODIMP VLCInput::get_time(double* time)
327 if( NULL == time )
328 return E_POINTER;
330 libvlc_media_player_t *p_md;
331 HRESULT hr = getMD(&p_md);
332 if( SUCCEEDED(hr) )
334 *time = (double)libvlc_media_player_get_time(p_md);
336 return hr;
339 STDMETHODIMP VLCInput::put_time(double time)
341 libvlc_media_player_t *p_md;
342 HRESULT hr = getMD(&p_md);
343 if( SUCCEEDED(hr) )
345 libvlc_media_player_set_time(p_md, (int64_t)time);
347 return hr;
350 STDMETHODIMP VLCInput::get_state(long* state)
352 if( NULL == state )
353 return E_POINTER;
355 libvlc_media_player_t *p_md;
356 HRESULT hr = getMD(&p_md);
357 if( SUCCEEDED(hr) )
359 *state = libvlc_media_player_get_state(p_md);
361 return hr;
364 STDMETHODIMP VLCInput::get_rate(double* rate)
366 if( NULL == rate )
367 return E_POINTER;
369 libvlc_media_player_t *p_md;
370 HRESULT hr = getMD(&p_md);
371 if( SUCCEEDED(hr) )
373 *rate = libvlc_media_player_get_rate(p_md);
375 return hr;
378 STDMETHODIMP VLCInput::put_rate(double rate)
380 libvlc_media_player_t *p_md;
381 HRESULT hr = getMD(&p_md);
382 if( SUCCEEDED(hr) )
384 libvlc_media_player_set_rate(p_md, rate);
386 return hr;
389 STDMETHODIMP VLCInput::get_fps(double* fps)
391 if( NULL == fps )
392 return E_POINTER;
394 *fps = 0.0;
395 libvlc_media_player_t *p_md;
396 HRESULT hr = getMD(&p_md);
397 if( SUCCEEDED(hr) )
399 *fps = libvlc_media_player_get_fps(p_md);
401 return hr;
404 STDMETHODIMP VLCInput::get_hasVout(VARIANT_BOOL* hasVout)
406 if( NULL == hasVout )
407 return E_POINTER;
409 libvlc_media_player_t *p_md;
410 HRESULT hr = getMD(&p_md);
411 if( SUCCEEDED(hr) )
413 *hasVout = varbool( libvlc_media_player_has_vout(p_md) );
415 return hr;
418 /****************************************************************************/
420 HRESULT VLCMarquee::do_put_int(unsigned idx, LONG val)
422 libvlc_media_player_t *p_md;
423 HRESULT hr = getMD(&p_md);
424 if( SUCCEEDED(hr) )
426 libvlc_video_set_marquee_int(p_md, idx, val);
428 return hr;
431 HRESULT VLCMarquee::do_get_int(unsigned idx, LONG *val)
433 if( NULL == val )
434 return E_POINTER;
436 libvlc_media_player_t *p_md;
437 HRESULT hr = getMD(&p_md);
438 if( SUCCEEDED(hr) )
440 *val = libvlc_video_get_marquee_int(p_md, idx);
442 return hr;
445 STDMETHODIMP VLCMarquee::get_position(BSTR* val)
447 if( NULL == val )
448 return E_POINTER;
450 LONG i;
451 HRESULT hr = do_get_int(libvlc_marquee_Position, &i);
452 if(SUCCEEDED(hr))
453 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
455 return hr;
458 STDMETHODIMP VLCMarquee::put_position(BSTR val)
460 char *n = CStrFromBSTR(CP_UTF8, val);
461 if( !n ) return E_OUTOFMEMORY;
463 size_t i;
464 HRESULT hr;
465 if( position_byname( n, i ) )
466 hr = do_put_int(libvlc_marquee_Position,i);
467 else
468 hr = E_INVALIDARG;
470 CoTaskMemFree(n);
471 return hr;
474 STDMETHODIMP VLCMarquee::get_text(BSTR *val)
476 char *psz;
477 if( NULL == val )
478 return E_POINTER;
480 libvlc_media_player_t *p_md;
481 HRESULT hr = getMD(&p_md);
482 if( SUCCEEDED(hr) )
484 psz = libvlc_video_get_marquee_string(p_md, libvlc_marquee_Text);
485 if( psz )
486 *val = BSTRFromCStr(CP_UTF8, psz);
488 return hr;
491 STDMETHODIMP VLCMarquee::put_text(BSTR val)
493 libvlc_media_player_t *p_md;
494 HRESULT hr = getMD(&p_md);
495 if( SUCCEEDED(hr) )
497 char *psz_text = CStrFromBSTR(CP_UTF8, val);
498 libvlc_video_set_marquee_string(p_md, libvlc_marquee_Text, psz_text);
499 CoTaskMemFree(psz_text);
501 return hr;
504 /****************************************************************************/
506 STDMETHODIMP VLCPlaylistItems::get_count(long* count)
508 if( NULL == count )
509 return E_POINTER;
511 *count = Instance()->playlist_count();
512 return S_OK;
515 STDMETHODIMP VLCPlaylistItems::clear()
517 Instance()->playlist_clear();
518 return S_OK;
521 STDMETHODIMP VLCPlaylistItems::remove(long item)
523 libvlc_instance_t* p_libvlc;
524 HRESULT hr = getVLC(&p_libvlc);
525 if( SUCCEEDED(hr) )
527 Instance()->playlist_delete_item(item);
529 return hr;
532 /****************************************************************************/
534 STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
536 if( NULL == count )
537 return E_POINTER;
539 *count = 0;
540 *count = Instance()->playlist_count();
541 return S_OK;
544 STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
546 if( NULL == isPlaying )
547 return E_POINTER;
549 libvlc_media_player_t *p_md;
550 HRESULT hr = getMD(&p_md);
551 if( SUCCEEDED(hr) )
553 *isPlaying = varbool( libvlc_media_player_is_playing(p_md) );
555 return hr;
558 STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
560 if( NULL == item )
561 return E_POINTER;
563 if( 0 == SysStringLen(uri) )
564 return E_INVALIDARG;
566 libvlc_instance_t* p_libvlc;
567 HRESULT hr = getVLC(&p_libvlc);
568 if( SUCCEEDED(hr) )
570 char *psz_uri = NULL;
571 if( SysStringLen(Instance()->getBaseURL()) > 0 )
574 ** if the MRL a relative URL, we should end up with an absolute URL
576 LPWSTR abs_url = CombineURL(Instance()->getBaseURL(), uri);
577 if( NULL != abs_url )
579 psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
580 CoTaskMemFree(abs_url);
582 else
584 psz_uri = CStrFromBSTR(CP_UTF8, uri);
587 else
590 ** baseURL is empty, assume MRL is absolute
592 psz_uri = CStrFromBSTR(CP_UTF8, uri);
595 if( NULL == psz_uri )
597 return E_OUTOFMEMORY;
600 int i_options;
601 char **ppsz_options;
603 hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
604 if( FAILED(hr) )
606 CoTaskMemFree(psz_uri);
607 return hr;
610 char *psz_name = NULL;
611 VARIANT v_name;
612 VariantInit(&v_name);
613 if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
615 if( SysStringLen(V_BSTR(&v_name)) > 0 )
616 psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
618 VariantClear(&v_name);
621 *item = Instance()->playlist_add_extended_untrusted(psz_uri,
622 i_options, const_cast<const char **>(ppsz_options));
624 VLCControl::FreeTargetOptions(ppsz_options, i_options);
625 CoTaskMemFree(psz_uri);
626 if( psz_name ) /* XXX Do we even need to check? */
627 CoTaskMemFree(psz_name);
629 return hr;
632 STDMETHODIMP VLCPlaylist::play()
634 Instance()->playlist_play();
635 return S_OK;
638 STDMETHODIMP VLCPlaylist::playItem(long item)
640 Instance()->playlist_play_item(item);
641 return S_OK;
644 STDMETHODIMP VLCPlaylist::togglePause()
646 libvlc_media_player_t* p_md;
647 HRESULT hr = getMD(&p_md);
648 if( SUCCEEDED(hr) )
650 libvlc_media_player_pause(p_md);
652 return hr;
655 STDMETHODIMP VLCPlaylist::stop()
657 libvlc_media_player_t *p_md;
658 HRESULT hr = getMD(&p_md);
659 if( SUCCEEDED(hr) )
661 libvlc_media_player_stop(p_md);
663 return hr;
666 STDMETHODIMP VLCPlaylist::next()
668 Instance()->playlist_next();
669 return S_OK;
672 STDMETHODIMP VLCPlaylist::prev()
674 Instance()->playlist_prev();
675 return S_OK;
678 STDMETHODIMP VLCPlaylist::clear()
680 Instance()->playlist_clear();
681 return S_OK;
684 STDMETHODIMP VLCPlaylist::removeItem(long item)
686 libvlc_instance_t* p_libvlc;
687 HRESULT hr = getVLC(&p_libvlc);
688 if( SUCCEEDED(hr) )
690 Instance()->playlist_delete_item(item);
692 return hr;
695 STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
697 if( NULL == obj )
698 return E_POINTER;
700 *obj = _p_vlcplaylistitems;
701 if( NULL != _p_vlcplaylistitems )
703 _p_vlcplaylistitems->AddRef();
704 return NOERROR;
706 return E_OUTOFMEMORY;
709 /****************************************************************************/
711 STDMETHODIMP VLCSubtitle::get_track(long* spu)
713 if( NULL == spu )
714 return E_POINTER;
716 libvlc_media_player_t *p_md;
717 HRESULT hr = getMD(&p_md);
718 if( SUCCEEDED(hr) )
720 *spu = libvlc_video_get_spu(p_md);
722 return hr;
725 STDMETHODIMP VLCSubtitle::put_track(long spu)
727 libvlc_media_player_t *p_md;
728 HRESULT hr = getMD(&p_md);
729 if( SUCCEEDED(hr) )
731 libvlc_video_set_spu(p_md, spu);
733 return hr;
736 STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
738 if( NULL == spuNumber )
739 return E_POINTER;
741 libvlc_media_player_t *p_md;
742 HRESULT hr = getMD(&p_md);
743 if( SUCCEEDED(hr) )
745 // get the number of video subtitle available and return it
746 *spuNumber = libvlc_video_get_spu_count(p_md);
748 return hr;
752 STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
754 if( NULL == name )
755 return E_POINTER;
757 libvlc_media_player_t* p_md;
759 HRESULT hr = getMD(&p_md);
760 if( SUCCEEDED(hr) )
762 int i, i_limit;
763 const char *psz_name;
764 libvlc_track_description_t *p_spuDesc;
766 // get subtitles description
767 p_spuDesc = libvlc_video_get_spu_description(p_md);
768 if( !p_spuDesc )
769 return E_FAIL;
771 // get the number of available subtitle
772 i_limit = libvlc_video_get_spu_count(p_md);
773 if( i_limit < 0 )
774 return E_FAIL;
776 // check if the number given is a good one
777 if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
778 return E_FAIL;
780 // get the good spuDesc
781 for( i = 0 ; i < nameID ; i++ )
783 p_spuDesc = p_spuDesc->p_next;
785 // get the subtitle name
786 psz_name = p_spuDesc->psz_name;
788 // return it
789 if( psz_name != NULL )
791 *name = BSTRFromCStr(CP_UTF8, psz_name);
792 return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
794 *name = NULL;
795 return E_FAIL;
797 return hr;
800 /****************************************************************************/
802 STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
804 if( NULL == fullscreen )
805 return E_POINTER;
807 libvlc_media_player_t *p_md;
808 HRESULT hr = getMD(&p_md);
809 if( SUCCEEDED(hr) )
811 *fullscreen = varbool( libvlc_get_fullscreen(p_md) );
813 return hr;
816 STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
818 libvlc_media_player_t *p_md;
819 HRESULT hr = getMD(&p_md);
820 if( SUCCEEDED(hr) )
822 libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen);
824 return hr;
827 STDMETHODIMP VLCVideo::get_width(long* width)
829 if( NULL == width )
830 return E_POINTER;
832 libvlc_media_player_t *p_md;
833 HRESULT hr = getMD(&p_md);
834 if( SUCCEEDED(hr) )
836 *width = libvlc_video_get_width(p_md);
838 return hr;
841 STDMETHODIMP VLCVideo::get_height(long* height)
843 if( NULL == height )
844 return E_POINTER;
846 libvlc_media_player_t *p_md;
847 HRESULT hr = getMD(&p_md);
848 if( SUCCEEDED(hr) )
850 *height = libvlc_video_get_height(p_md);
852 return hr;
855 STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
857 if( NULL == aspect )
858 return E_POINTER;
860 libvlc_media_player_t *p_md;
861 HRESULT hr = getMD(&p_md);
862 if( SUCCEEDED(hr) )
864 char *psz_aspect = libvlc_video_get_aspect_ratio(p_md);
866 if( !psz_aspect )
868 *aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
869 if( NULL == *aspect )
870 hr = E_OUTOFMEMORY;
871 } else if( NULL == psz_aspect)
872 hr = E_OUTOFMEMORY;
873 free( psz_aspect );
875 return hr;
878 STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
880 if( NULL == aspect )
881 return E_POINTER;
883 libvlc_media_player_t *p_md;
884 HRESULT hr = getMD(&p_md);
885 if( SUCCEEDED(hr) )
887 char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
888 if( !psz_aspect )
890 return E_OUTOFMEMORY;
893 libvlc_video_set_aspect_ratio(p_md, psz_aspect);
895 CoTaskMemFree(psz_aspect);
897 return hr;
900 STDMETHODIMP VLCVideo::get_subtitle(long* spu)
902 if( NULL == spu )
903 return E_POINTER;
905 libvlc_media_player_t *p_md;
906 HRESULT hr = getMD(&p_md);
907 if( SUCCEEDED(hr) )
909 *spu = libvlc_video_get_spu(p_md);
911 return hr;
914 STDMETHODIMP VLCVideo::put_subtitle(long spu)
916 libvlc_media_player_t *p_md;
917 HRESULT hr = getMD(&p_md);
918 if( SUCCEEDED(hr) )
920 libvlc_video_set_spu(p_md, spu);
922 return hr;
925 STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
927 if( NULL == geometry )
928 return E_POINTER;
930 libvlc_media_player_t *p_md;
931 HRESULT hr = getMD(&p_md);
932 if( SUCCEEDED(hr) )
934 char *psz_geometry = libvlc_video_get_crop_geometry(p_md);
935 if( !psz_geometry )
937 *geometry = BSTRFromCStr(CP_UTF8, psz_geometry);
938 if( !geometry )
939 hr = E_OUTOFMEMORY;
940 } else if( !psz_geometry )
941 hr = E_OUTOFMEMORY;
942 free( psz_geometry );
944 return hr;
947 STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
949 if( NULL == geometry )
950 return E_POINTER;
952 if( 0 == SysStringLen(geometry) )
953 return E_INVALIDARG;
955 libvlc_media_player_t *p_md;
956 HRESULT hr = getMD(&p_md);
957 if( SUCCEEDED(hr) )
959 char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
960 if( !psz_geometry )
962 return E_OUTOFMEMORY;
965 libvlc_video_set_crop_geometry(p_md, psz_geometry);
967 CoTaskMemFree(psz_geometry);
969 return hr;
972 STDMETHODIMP VLCVideo::get_teletext(long* page)
974 if( NULL == page )
975 return E_POINTER;
977 libvlc_media_player_t *p_md;
978 HRESULT hr = getMD(&p_md);
979 if( SUCCEEDED(hr) )
981 *page = libvlc_video_get_teletext(p_md);
984 return hr;
987 STDMETHODIMP VLCVideo::put_teletext(long page)
989 libvlc_media_player_t *p_md;
990 HRESULT hr = getMD(&p_md);
992 if( SUCCEEDED(hr) )
994 libvlc_video_set_teletext(p_md, page);
996 return hr;
999 STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
1001 if( NULL == picture )
1002 return E_POINTER;
1004 libvlc_media_player_t *p_md;
1005 HRESULT hr = getMD(&p_md);
1006 if( SUCCEEDED(hr) )
1008 static int uniqueId = 0;
1009 TCHAR path[MAX_PATH+1];
1011 int pathlen = GetTempPath(MAX_PATH-24, path);
1012 if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
1013 return E_FAIL;
1015 /* check temp directory path by openning it */
1017 HANDLE dirHandle = CreateFile(path, GENERIC_READ,
1018 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1019 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1020 if( INVALID_HANDLE_VALUE == dirHandle )
1022 Instance()->setErrorInfo(IID_IVLCVideo,
1023 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1024 return E_FAIL;
1026 else
1028 BY_HANDLE_FILE_INFORMATION bhfi;
1029 BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
1030 CloseHandle(dirHandle);
1031 if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
1033 Instance()->setErrorInfo(IID_IVLCVideo,
1034 "Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
1035 return E_FAIL;
1040 TCHAR filepath[MAX_PATH+1];
1042 _stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
1043 path, GetCurrentProcessId(), ++uniqueId);
1045 #ifdef _UNICODE
1046 /* reuse path storage for UTF8 string */
1047 char *psz_filepath = (char *)path;
1048 WCHAR* wpath = filepath;
1049 #else
1050 char *psz_filepath = path;
1051 /* first convert to unicode using current code page */
1052 WCHAR wpath[MAX_PATH+1];
1053 if( 0 == MultiByteToWideChar(CP_ACP, 0, filepath, -1,
1054 wpath, sizeof(wpath)/sizeof(WCHAR)) )
1055 return E_FAIL;
1056 #endif
1057 /* convert to UTF8 */
1058 pathlen = WideCharToMultiByte(CP_UTF8, 0, wpath, -1,
1059 psz_filepath, sizeof(path), NULL, NULL);
1060 // fail if path is 0 or too short (i.e pathlen is the same as
1061 // storage size)
1063 if( (0 == pathlen) || (sizeof(path) == pathlen) )
1064 return E_FAIL;
1066 /* take snapshot into file */
1067 if( libvlc_video_take_snapshot(p_md, 0, psz_filepath, 0, 0) == 0 )
1069 /* open snapshot file */
1070 HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP, 0, 0,
1071 LR_CREATEDIBSECTION|LR_LOADFROMFILE);
1072 if( snapPic )
1074 PICTDESC snapDesc;
1076 snapDesc.cbSizeofstruct = sizeof(PICTDESC);
1077 snapDesc.picType = PICTYPE_BITMAP;
1078 snapDesc.bmp.hbitmap = (HBITMAP)snapPic;
1079 snapDesc.bmp.hpal = NULL;
1081 hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp,
1082 TRUE, (LPVOID*)picture);
1083 if( FAILED(hr) )
1085 *picture = NULL;
1086 DeleteObject(snapPic);
1089 DeleteFile(filepath);
1092 return hr;
1095 STDMETHODIMP VLCVideo::toggleFullscreen()
1097 libvlc_media_player_t *p_md;
1098 HRESULT hr = getMD(&p_md);
1099 if( SUCCEEDED(hr) )
1101 libvlc_toggle_fullscreen(p_md);
1103 return hr;
1106 STDMETHODIMP VLCVideo::toggleTeletext()
1108 libvlc_media_player_t *p_md;
1109 HRESULT hr = getMD(&p_md);
1110 if( SUCCEEDED(hr) )
1112 libvlc_toggle_teletext(p_md);
1114 return hr;
1117 STDMETHODIMP VLCVideo::get_marquee(IVLCMarquee** obj)
1119 return object_get(obj,_p_vlcmarquee);
1122 STDMETHODIMP VLCVideo::get_logo(IVLCLogo** obj)
1124 return object_get(obj,_p_vlclogo);
1127 STDMETHODIMP VLCVideo::get_deinterlace(IVLCDeinterlace** obj)
1129 return object_get(obj,_p_vlcdeint);
1132 /****************************************************************************/
1134 HRESULT VLCLogo::do_put_int(unsigned idx, LONG val)
1136 libvlc_media_player_t *p_md;
1137 HRESULT hr = getMD(&p_md);
1138 if( SUCCEEDED(hr) )
1140 libvlc_video_set_logo_int(p_md, idx, val);
1142 return hr;
1145 HRESULT VLCLogo::do_get_int(unsigned idx, LONG *val)
1147 if( NULL == val )
1148 return E_POINTER;
1150 libvlc_media_player_t *p_md;
1151 HRESULT hr = getMD(&p_md);
1152 if( SUCCEEDED(hr) )
1154 *val = libvlc_video_get_logo_int(p_md, idx);
1156 return hr;
1159 STDMETHODIMP VLCLogo::file(BSTR fname)
1161 libvlc_media_player_t *p_md;
1162 HRESULT hr = getMD(&p_md);
1164 char *n = CStrFromBSTR(CP_UTF8, fname);
1165 if( !n ) hr = E_OUTOFMEMORY;
1167 if( SUCCEEDED(hr) )
1169 libvlc_video_set_logo_string(p_md, libvlc_logo_file, n);
1172 CoTaskMemFree(n);
1173 return hr;
1176 STDMETHODIMP VLCLogo::get_position(BSTR* val)
1178 if( NULL == val )
1179 return E_POINTER;
1181 LONG i;
1182 HRESULT hr = do_get_int(libvlc_logo_position, &i);
1184 if(SUCCEEDED(hr))
1185 *val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
1187 return hr;
1190 STDMETHODIMP VLCLogo::put_position(BSTR val)
1192 char *n = CStrFromBSTR(CP_UTF8, val);
1193 if( !n ) return E_OUTOFMEMORY;
1195 size_t i;
1196 HRESULT hr;
1197 if( position_byname( n, i ) )
1198 hr = do_put_int(libvlc_logo_position,i);
1199 else
1200 hr = E_INVALIDARG;
1202 CoTaskMemFree(n);
1203 return hr;
1206 /****************************************************************************/
1208 VLCControl2::VLCControl2(VLCPlugin *p_instance) :
1209 _p_instance(p_instance),
1210 _p_typeinfo(NULL),
1211 _p_vlcaudio(new VLCAudio(p_instance)),
1212 _p_vlcinput(new VLCInput(p_instance)),
1213 _p_vlcplaylist(new VLCPlaylist(p_instance)),
1214 _p_vlcsubtitle(new VLCSubtitle(p_instance)),
1215 _p_vlcvideo(new VLCVideo(p_instance))
1219 VLCControl2::~VLCControl2()
1221 delete _p_vlcvideo;
1222 delete _p_vlcsubtitle;
1223 delete _p_vlcplaylist;
1224 delete _p_vlcinput;
1225 delete _p_vlcaudio;
1226 if( _p_typeinfo )
1227 _p_typeinfo->Release();
1230 HRESULT VLCControl2::loadTypeInfo(void)
1232 HRESULT hr = NOERROR;
1233 if( NULL == _p_typeinfo )
1235 ITypeLib *p_typelib;
1237 hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
1238 if( SUCCEEDED(hr) )
1240 hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
1241 if( FAILED(hr) )
1243 _p_typeinfo = NULL;
1245 p_typelib->Release();
1248 return hr;
1251 STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
1253 if( NULL == pctInfo )
1254 return E_INVALIDARG;
1256 if( SUCCEEDED(loadTypeInfo()) )
1257 *pctInfo = 1;
1258 else
1259 *pctInfo = 0;
1261 return NOERROR;
1264 STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
1266 if( NULL == ppTInfo )
1267 return E_INVALIDARG;
1269 if( SUCCEEDED(loadTypeInfo()) )
1271 _p_typeinfo->AddRef();
1272 *ppTInfo = _p_typeinfo;
1273 return NOERROR;
1275 *ppTInfo = NULL;
1276 return E_NOTIMPL;
1279 STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
1280 UINT cNames, LCID lcid, DISPID* rgDispID)
1282 if( SUCCEEDED(loadTypeInfo()) )
1284 return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
1286 return E_NOTIMPL;
1289 STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
1290 LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
1291 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1293 if( SUCCEEDED(loadTypeInfo()) )
1295 return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
1296 pVarResult, pExcepInfo, puArgErr);
1298 return E_NOTIMPL;
1301 STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
1303 if( NULL == autoloop )
1304 return E_POINTER;
1306 *autoloop = varbool( _p_instance->getAutoLoop() );
1307 return S_OK;
1310 STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
1312 _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
1313 return S_OK;
1316 STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
1318 if( NULL == autoplay )
1319 return E_POINTER;
1321 *autoplay = varbool( _p_instance->getAutoPlay() );
1322 return S_OK;
1325 STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
1327 _p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
1328 return S_OK;
1331 STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
1333 if( NULL == url )
1334 return E_POINTER;
1336 *url = SysAllocStringLen(_p_instance->getBaseURL(),
1337 SysStringLen(_p_instance->getBaseURL()));
1338 return NOERROR;
1341 STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
1343 _p_instance->setBaseURL(mrl);
1345 return S_OK;
1348 STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
1350 if( NULL == mrl )
1351 return E_POINTER;
1353 *mrl = SysAllocStringLen(_p_instance->getMRL(),
1354 SysStringLen(_p_instance->getMRL()));
1355 return NOERROR;
1358 STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
1360 _p_instance->setMRL(mrl);
1362 return S_OK;
1366 STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
1368 if( NULL == visible )
1369 return E_POINTER;
1372 * Note to developers
1374 * Returning the _b_toolbar is closer to the method specification.
1375 * But returning True when toolbar is not implemented so not displayed
1376 * could be bad for ActiveX users which rely on this value to show their
1377 * own toolbar if not provided by the ActiveX.
1379 * This is the reason why FALSE is returned, until toolbar get implemented.
1382 /* DISABLED for now */
1383 // *visible = varbool( _p_instance->getShowToolbar() );
1385 *visible = VARIANT_FALSE;
1387 return S_OK;
1390 STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
1392 _p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
1393 return S_OK;
1397 STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
1399 if( NULL == seconds )
1400 return E_POINTER;
1402 *seconds = _p_instance->getStartTime();
1403 return S_OK;
1406 STDMETHODIMP VLCControl2::put_StartTime(long seconds)
1408 _p_instance->setStartTime(seconds);
1409 return S_OK;
1412 STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
1414 if( NULL == version )
1415 return E_POINTER;
1417 const char *versionStr = libvlc_get_version();
1418 if( NULL != versionStr )
1420 *version = BSTRFromCStr(CP_UTF8, versionStr);
1422 return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
1424 *version = NULL;
1425 return E_FAIL;
1428 STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
1430 if( NULL == isVisible )
1431 return E_POINTER;
1433 *isVisible = varbool( _p_instance->getVisible() );
1435 return S_OK;
1438 STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
1440 _p_instance->setVisible(isVisible != VARIANT_FALSE);
1441 return S_OK;
1444 STDMETHODIMP VLCControl2::get_Volume(long *volume)
1446 if( NULL == volume )
1447 return E_POINTER;
1449 *volume = _p_instance->getVolume();
1450 return S_OK;
1453 STDMETHODIMP VLCControl2::put_Volume(long volume)
1455 _p_instance->setVolume(volume);
1456 return S_OK;
1459 STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
1461 if( NULL == backcolor )
1462 return E_POINTER;
1464 *backcolor = _p_instance->getBackColor();
1465 return S_OK;
1468 STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
1470 _p_instance->setBackColor(backcolor);
1471 return S_OK;
1474 STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
1476 return object_get(obj,_p_vlcaudio);
1479 STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
1481 return object_get(obj,_p_vlcinput);
1484 STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
1486 return object_get(obj,_p_vlcplaylist);
1489 STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
1491 return object_get(obj,_p_vlcsubtitle);
1494 STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
1496 return object_get(obj,_p_vlcvideo);