Commit 5bf4823d authored by Rafaël Carré's avatar Rafaël Carré

Remove activex project

It is now available at git://git.videolan.org/activex-vlc.git
Fetch, configure, and build it when making windows packages

Modify npapi-vlc dependencies, and move install of the dll in
package-win-common rule

Pass $(SHELL) to npapi & activex ./configure to be sure they pick
/bin/bash and not /bin/sh (which might be incompatible with libtool)
parent e6552497
......@@ -9,8 +9,7 @@
# - libs/* are needed by modules
BASE_SUBDIRS = po compat src bin modules share doc test
EXTRA_SUBDIRS = m4 \
libs/loader libs/srtp libs/unzip \
projects/activex
libs/loader libs/srtp libs/unzip
DIST_SUBDIRS = $(BASE_SUBDIRS) $(EXTRA_SUBDIRS)
SUBDIRS = po compat src
......@@ -29,9 +28,6 @@ if BUILD_VLC
SUBDIRS += bin
endif
SUBDIRS += modules share doc test
if BUILD_ACTIVEX
SUBDIRS += projects/activex
endif
EXTRA_DIST = \
HACKING \
......@@ -697,10 +693,11 @@ win32_xpi_destdir=$(win32_destdir)/vlc-plugin
if HAVE_WIN32
include extras/package/npapi.am
include extras/package/activex.am
endif
#Win-common is for win32 and wince
package-win-common: install
package-win-common: install build-npapi build-activex
# Check that tmp isn't in the way
@if test -e "$(win32_destdir)"; then \
echo "Error: please remove $(win32_destdir), it is in the way"; \
......@@ -796,8 +793,11 @@ if BUILD_OSDMENU
rm -f -- "$$file.tmp"; \
done
endif
if BUILD_ACTIVEX
cp $(top_srcdir)/projects/activex/axvlc.dll.manifest $(win32_destdir)
if !HAVE_WIN64
cp "$(top_builddir)/activex-vlc/src/axvlc.dll.manifest" "$(win32_destdir)/"
cp "$(top_builddir)/activex-vlc/installed/lib/axvlc.dll" "$(win32_destdir)/"
cp "$(top_builddir)/npapi-vlc/src/npvlc.dll.manifest" "$(win32_destdir)/"
cp "$(top_builddir)/npapi-vlc/installed/lib/npvlc.dll" "$(win32_destdir)/"
endif
# SDK
......@@ -806,10 +806,10 @@ endif
cp -r $(destdir)/lib/pkgconfig "$(win32_destdir)/sdk/lib"
for file in libvlc.dll.a libvlc.la libvlccore.dll.a libvlccore.la; do \
cp -r $(destdir)/lib/$$file "$(win32_destdir)/sdk/lib"; done
if BUILD_ACTIVEX
if !HAVE_WIN64
mkdir -p "$(win32_destdir)/sdk/activex"
cp $(srcdir)/projects/activex/README.TXT $(win32_destdir)/sdk/activex/
cp $(srcdir)/projects/activex/test.html $(win32_destdir)/sdk/activex/
cp $(top_builddir)/activex-vlc/README $(win32_destdir)/sdk/activex/README.TXT
cp $(top_builddir)/activex-vlc/src/test.html $(win32_destdir)/sdk/activex/
endif
find $(win32_destdir) -type f \( -name "*xml" -or -name "*html" -or -name '*js' -or -name '*css' -or -name '*hosts' -or -iname '*txt' -or -name '*.cfg' -or -name '*.lua' \) -exec $(U2D) {} \;
......@@ -829,36 +829,32 @@ package-win-base: package-win-common
fi ; \
done
package-win32-webplugin-common: package-win-base build-npapi
package-win32-webplugin-common: package-win-base
mkdir -p "$(win32_xpi_destdir)/plugins"
find $(destdir) -maxdepth 4 -name "*$(LIBEXT)" -exec cp {} "$(win32_xpi_destdir)/" \;
if !HAVE_WIN64
cp $(top_srcdir)/npapi-vlc/src/npvlc.dll.manifest "$(win32_xpi_destdir)/plugins"
cp $(top_builddir)/npapi-vlc/src/npvlc.dll.manifest "$(win32_xpi_destdir)/plugins"
endif
cp "$(top_srcdir)/extras/package/win32/libvlc.dll.manifest" "$(win32_xpi_destdir)/plugins"
cp -r $(win32_destdir)/plugins/ "$(win32_xpi_destdir)/plugins"
rm -rf "$(win32_xpi_destdir)/plugins/plugins/*qt*"
rm -rf "$(win32_xpi_destdir)/plugins/plugins/*skins*"
package-win32-xpi: package-win32-webplugin-common build-npapi
package-win32-xpi: package-win32-webplugin-common
if !HAVE_WIN64
cp $(top_builddir)/npapi-vlc/src/install.rdf "$(win32_xpi_destdir)"
cd $(win32_xpi_destdir) && zip -r "../vlc-$(VERSION).xpi" install.rdf plugins
endif
package-win32-crx: package-win32-webplugin-common build-npapi
package-win32-crx: package-win32-webplugin-common
if !HAVE_WIN64
cp $(top_builddir)/npapi-vlc/src/manifest.json "$(win32_xpi_destdir)"
crxmake --pack-extension "$(win32_xpi_destdir)" \
--extension-output "$(win32_destdir)/vlc-$(VERSION).crx" --ignore-file install.rdf
endif
package-win32-base-exe: package-win-base build-npapi
package-win32-base-exe: package-win-base
# Script installer
if !HAVE_WIN64
cp "$(top_builddir)/npapi-vlc/installed/lib/npvlc.dll" "$(win32_destdir)/"
cp "$(top_builddir)/npapi-vlc/src/npvlc.dll.manifest" "$(win32_destdir)/"
endif
cp "$(top_builddir)/extras/package/win32/vlc.win32.nsi" "$(win32_destdir)/"
cp "$(top_builddir)/extras/package/win32/spad.nsi" "$(win32_destdir)/"
mkdir "$(win32_destdir)/languages"
......
......@@ -313,7 +313,7 @@ case "${host_os}" in
# add ws2_32 for closesocket, select, recv
VLC_ADD_LIBS([libvlccore],[-lws2_32 -lnetapi32 -lwinmm])
VLC_ADD_LDFLAGS([vlc],[-mwindows])
VLC_ADD_LIBS([activex win32text],[-lgdi32])
VLC_ADD_LIBS([win32text],[-lgdi32])
VLC_ADD_LIBS([cdda vcdx sdl_image aout_sdl vout_sdl],[-lwinmm])
VLC_ADD_LIBS([access_http access_mms access_udp access_tcp access_ftp access_rtmp access_output_udp access_output_shout access_output_rtmp sap oldhttp stream_out_standard stream_out_rtp stream_out_raop vod_rtsp access_realrtsp rtp oldrc netsync gnutls growl_udp flac ts audioscrobbler lua remoteosd zvbi audiobargraph_a netsync],[-lws2_32])
VLC_ADD_LIBS([filesystem], [-lshlwapi])
......@@ -4242,57 +4242,6 @@ AC_ARG_ENABLE(vlc,
[ --enable-vlc build the VLC media player (default enabled)])
AM_CONDITIONAL(BUILD_VLC, [test "${enable_vlc}" != "no"])
dnl
dnl Microsoft ActiveX support
dnl
activex=false
AC_ARG_ENABLE(activex,
AS_HELP_STRING([--enable-activex],[build a vlc-based ActiveX control
(default enabled on Win32)]))
AC_ARG_WITH(wine-sdk-path,
[ --with-wine-sdk-path=PATH path to wine sdk])
if test "${enable_activex}" != "no"
then
if test "${SYS}" = "mingw32"
then
AC_CHECK_PROGS(MIDL, [midl], no)
if test "${with_wine_sdk_path}" != ""
then
WINE_SDK_PATH=${with_wine_sdk_path}
AC_PATH_PROG(WIDL, widl, no, [$WINE_SDK_PATH/bin:$WINE_SDK_PATH/tools/widl])
else
WIDL=no
fi
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS(ole2.h,
[AC_CHECK_HEADERS(olectl.h,
[ VLC_ADD_CPPFLAGS([activex],[-DUNICODE -D_UNICODE -D_MIDL_USE_GUIDDEF_])
VLC_ADD_CXXFLAGS([activex],[-fno-exceptions])
VLC_ADD_LIBS([activex],[-lole32 -loleaut32 -luuid -lshlwapi])
AC_CHECK_HEADERS(objsafe.h,
VLC_ADD_CXXFLAGS([activex],[-DHAVE_OBJSAFE_HEADER]),,
[
#if HAVE_OLE2_H
# include <ole2.h>
#endif
]
)
activex=:
PLUGINS_BINDINGS="${PLUGINS_BINDINGS} activex"
],
[ AC_MSG_ERROR([required OLE headers are missing from your system]) ]
)],
[ AC_MSG_ERROR([required OLE headers are missing from your system]) ]
)
AC_LANG_POP(C++)
fi
fi
AC_ARG_VAR(MIDL, [Microsoft IDL compiler (Win32 platform only)])
AM_CONDITIONAL(HAS_MIDL_COMPILER, test "${MIDL}" != "no")
AC_ARG_VAR(WIDL, [Wine IDL compiler (requires Wine SDK)])
AM_CONDITIONAL(HAS_WIDL_COMPILER, test "${WIDL}" != "no")
AM_CONDITIONAL(BUILD_ACTIVEX,${activex})
dnl
dnl Plugin and builtin checks
......@@ -4394,7 +4343,6 @@ VLC_OUTPUT_VLC_CONFIG_IN
AC_CONFIG_FILES([
Makefile
projects/activex/Makefile
doc/Makefile
libs/loader/Makefile
libs/srtp/Makefile
......@@ -4490,12 +4438,6 @@ AM_COND_IF([HAVE_WIN32], [
extras/package/win32/spad.nsi
extras/package/win32/vlc.win32.nsi
])
AM_COND_IF([BUILD_ACTIVEX], [
AC_CONFIG_FILES([
projects/activex/axvlc.inf
projects/activex/axvlc_rc.rc
])
])
])
AM_COND_IF([HAVE_DARWIN], [
......
#! /usr/bin/make -f
if HAVE_WIN64
build-activex:
touch $@
else
build-activex: stamp-activex-build
endif
stamp-activex-fetch:
rm -Rf activex-vlc
git clone git://git.videolan.org/activex-vlc.git activex-vlc
touch $@
stamp-activex-autogen: stamp-activex-fetch
# extras/package/activex.am
cd activex-vlc && \
$(SHELL) ./autogen.sh
touch $@
stamp-activex-configure: stamp-activex-autogen
cd activex-vlc && \
$(SHELL) ./configure \
--prefix=/ \
--host=$(host_alias) --build=$(build_alias) \
CPP="$(CPP)" CPPFLAGS="$(CPPFLAGS)" \
CC="$(CC)" CFLAGS="$(CFLAGS)" \
CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS)" \
LD="$(LD)" LDFLAGS="$(LDFLAGS)" \
SHELL="$(SHELL)" \
PKG_CONFIG_LIBDIR="../$(srcdir)/extras/contrib/lib/pkgconfig:../src"
touch $@
stamp-activex-build: stamp-activex-configure
cd activex-vlc && \
$(MAKE) $(MAKEFLAGS) all && \
$(MAKE) $(MAKEFLAGS) DESTDIR="$(abs_builddir)/activex-vlc/installed" install
touch $@
......@@ -28,6 +28,7 @@ stamp-npapi-configure: stamp-npapi-autogen
CC="$(CC)" CFLAGS="$(CFLAGS)" \
CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS)" \
LD="$(LD)" LDFLAGS="$(LDFLAGS)" \
SHELL="$(SHELL)" \
PKG_CONFIG_LIBDIR="../$(srcdir)/extras/contrib/lib/pkgconfig:../src"
touch $@
......
......@@ -25,7 +25,6 @@
--enable-portaudio \
--enable-sdl \
--enable-qt4 \
--enable-activex \
--enable-sse --enable-mmx \
--enable-libcddb \
--enable-zvbi --disable-telx \
......
......@@ -14,5 +14,5 @@ CC=amd64-mingw32msvc-gcc CXX=amd64-mingw32msvc-g++ \
CONFIGURE="${root}configure" \
CONFIGOPTS="--host=amd64-mingw32msvc --build=i386-linux
--enable-dirac --enable-mkv --enable-taglib --enable-debug --enable-projectm
--disable-qt4 --disable-skins2 --disable-activex" \
--disable-qt4 --disable-skins2" \
sh ${root}extras/package/win32/configure-common.sh
......@@ -20,7 +20,7 @@
!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_DIR_REGKEY}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "Language"
@BUILD_ACTIVEX_TRUE@ !define INSTALL_ACTIVEX
@HAVE_WIN64_FALSE@ !define INSTALL_ACTIVEX
@HAVE_WIN64_FALSE@ !define INSTALL_MOZILLA
@FILE_LIBVLCCORE_DLL@
......@@ -756,7 +756,9 @@ SectionEnd
!ifdef INSTALL_MOZILLA
!insertmacro MUI_DESCRIPTION_TEXT ${SEC03} $Desc_Section03
!endif
@BUILD_ACTIVEX_TRUE@ !insertmacro MUI_DESCRIPTION_TEXT ${SEC04} $Desc_Section04
!ifdef INSTALL_ACTIVEX
!insertmacro MUI_DESCRIPTION_TEXT ${SEC04} $Desc_Section04
!endif
!insertmacro MUI_DESCRIPTION_TEXT ${SEC05} $Desc_Section05
!insertmacro MUI_DESCRIPTION_TEXT ${SEC06} $Desc_Section06
!insertmacro MUI_DESCRIPTION_TEXT ${SEC07} $Desc_Section07
......
###############################################################################
# Building the Activex plugin
###############################################################################
MOSTLYCLEANFILES =
EXTRA_DIST = $(SOURCES_activex) $(DIST_rsrc) $(DIST_misc)
BUILT_SOURCES = $(BUILT_SOURCES_activex)
SOURCES_activex = \
main.cpp \
utils.cpp \
utils.h \
olecontrol.cpp \
olecontrol.h \
oleinplaceactiveobject.cpp \
oleinplaceactiveobject.h \
oleinplaceobject.cpp \
oleinplaceobject.h \
oleobject.cpp \
oleobject.h \
persistpropbag.cpp \
persistpropbag.h \
persiststorage.cpp \
persiststorage.h \
persiststreaminit.cpp \
persiststreaminit.h \
position.h \
provideclassinfo.cpp \
provideclassinfo.h \
connectioncontainer.cpp \
connectioncontainer.h \
objectsafety.cpp \
objectsafety.h \
dataobject.cpp \
dataobject.h \
viewobject.cpp \
viewobject.h \
supporterrorinfo.cpp \
supporterrorinfo.h \
vlccontrol.cpp \
vlccontrol.h \
vlccontrol2.cpp \
vlccontrol2.h \
plugin.cpp \
plugin.h \
axvlc_idl.c \
axvlc_idl.h \
guiddef.h \
$(NULL)
DIST_rsrc = \
axvlc_rc.rc.in \
$(NULL)
DIST_misc = \
README.TXT \
axvlc.inf.in \
axvlc.def \
axvlc.dll.manifest \
axvlc.idl \
axvlc.tlb \
inplace.bmp \
vlc16x16.bmp \
test.html \
$(NULL)
if BUILD_ACTIVEX
lib_LTLIBRARIES = axvlc.la
LIBRARIES_libvlc = $(top_builddir)/src/libvlc.la \
$(top_builddir)/src/libvlccore.la
axvlc_la_SOURCES = $(SOURCES_activex)
axvlc_la_CFLAGS = `$(VLC_CONFIG) --cflags activex`
axvlc_la_CXXFLAGS = `$(VLC_CONFIG) --cxxflags activex`
axvlc_la_DEPENDENCIES = axvlc.def $(DATA_axvlc_rc) $(LIBRARIES_libvlc)
axvlc_la_LDFLAGS = -Wl,$(srcdir)/axvlc.def -Wl,$(DATA_axvlc_rc) \
-no-undefined -avoid-version -module \
`$(VLC_CONFIG) --ldflags activex libvlc`
axvlc_la_LIBADD = $(LIBRARIES_libvlc) \
`$(VLC_CONFIG) -libs activex`
DATA_axvlc_rc = $(noinst_axvlc_rc_DATA)
noinst_axvlc_rc_DATA = axvlc_rc.$(OBJEXT)
noinst_axvlc_rcdir =
axvlc_rc.$(OBJEXT): axvlc_rc.rc inplace.bmp axvlc.tlb
$(WINDRES) --include-dir $(srcdir) -i $< -o $@
DATA_axvlc_tlb = $(axvlc_tlb_DATA)
noinst_axvlc_tlb_DATA = axvlc.tlb
noinst_axvlc_tlbdir = $(libdir)
if HAS_MIDL_COMPILER
axvlc.tlb axvlc_idl.c axvlc_idl.h: axvlc.idl
$(MIDL) -Oicf -error all -env win32 -tlb axvlc.tlb -iid axvlc_idl.c -h axvlc_idl.h axvlc.idl
clean-tlb:
rm -f axvlc.tlb axvlc_idl.c axvlc_idl.h
else
if HAS_WIDL_COMPILER
axvlc.tlb axvlc_idl.c axvlc_idl.h: axvlc.idl
$(WIDL) -I$(WINE_SDK_PATH)/include -tuh -T axvlc.tlb -U axvlc_idl.c -H axvlc_idl.h axvlc.idl
clean-tlb:
rm -f axvlc.tlb axvlc_idl.c axvlc_idl.h
else
clean-tlb:
endif
endif
else
clean-tlb:
endif
###############################################################################
# Clean rules
###############################################################################
clean-local: clean-tlb
###############################################################################
# Force rules
###############################################################################
== ACTIVEX Control for VLC ==
The VLC ActiveX Control has been primary designed to work with Internet
Explorer. However it may also work with Visual Basic and/or .NET. Please
note, that this code does not rely upon Microsoft MFC/ATL code, hence
good compatibility is not guaranteed.
I. Compiling
The ActiveX Control should compile without any glitches as long as you
have the latest version of mingw gcc and headers.
In order to script the ActiveX Control on Internet Explorer, a type
library is required. This type library is usually generated from an IDL
file using Microsoft MIDL compiler. Therefore, for convenience I have
checked in the output of the MIDL compiler in the repository so that you
will only need the MIDL compiler if you change axvlc.idl. the generated
files are as follow:
axvlc_idl.c
axvlc_idl.h
axvlc.tlb
To use the MIDL compiler on cygwin, you will need to set some
environment variables before configuring vlc. If you have a copy of
'Microsoft Visual C++ 6.0' installed, the following settings are
correct:
export PATH=$PATH:"/cygdrive/c/Program Files/Microsoft Visual Studio/COMMON/MSDev98/Bin":"/cygdrive/c/Program Files/Microsoft Visual Studio/VC98/Bin"
export INCLUDE='C:\Program Files\Microsoft Visual Studio\VC98\Include'
export MIDL="midl"
If you are cross-compiling on Linux, you can use 'widl' which is part of
the WINE project (http://www.winehq.com). At leat wine-dev-0.9.57 works,
the comand line to compile IDL should looks like the following :
widl -I/usr/include/wine/windows/ \
-h -H axvlc_idl.h -t -T axvlc.tlb -u -U axvlc_idl.c axvlc.idl
NOTE: widl breaks compatibility with Visual Basic. If that is important
to you then you must use midl.
II. Debugging
The ActiveX control is compiled with verbose output by default, but you
will need to launch Internet Explorer from a Cygwin shell to see the
output. Alternatively, the plugin will also use the VLC preferences, so
if you enable the file logging interface through the player and save the
preferences, the control will automatically log its verbose output into
the designated file.
Debugging the ActiveX control DLL with GNU GDB can be difficult.
Fortunately the ActiveX control can also be compiled as an executable
rather than a DLL. In ActiveX terms, this is called a local server. The
advantage of a local server is that it will never crash its client,
i.e. Internet Explorer, even if the local server crashes. The build
system does not currently allow to create an executable version of the
ActiveX control, you will need to manually define the BUILD_LOCALSERVER
pre-processor variable and modify the Makefile to exclude the '-shared'
option at the linking stage. Once this is done, launch axvlc.exe to have
a working Activex control. Please note, that executable version of the
ActiveX control will override any settings required for the DLL version,
which will no longer work until you (re)register it as shown in the
following section
III. Local Install
The VLC NSIS installer will install the ActiveX Control without
requiring any further manual intervention, but for people who like to
live on the edge, here are the steps you need to perform once you have
built the ActiveX Control.
The ActiveX control DLL file may be copied anywhere on the target
machine, but before you can use the control, you will need to register
it with Windows by using the REGSVR32 command, as per following example:
REGSVR32 C:\WINDOWS\AXVLC.DLL
If the control needs to use external VLC plugins (i.e other than the
built-in ones), make sure that the plugin path is set in the registry as
per following example:
[HKEY_LOCAL_MACHINE\Software\VideoLAN\VLC]
InstallDir="C:\Program Files\VideoLAN\VLC"
The InstallDir must be the parent directory of the 'plugins' directory.
WARNING: Both control and plugins must come from the same source build
tree. Otherwise, at best, the control will not play any content,
at worse it may crash Internet Explorer while attempting to load
incompatible plugins.
IV. Internet Install
The activex control may be installed from a remote through Internet
Installer if it is packaged up in a CAB file. The following link
explains how to achieve this
http://msdn.microsoft.com/workshop/components/activex/packaging.asp
For convenience, I have provided a sample axvlc.INF file, which assumes
that the VLC NSIS Installer has been packaged up a CAB file called
AXVLC.CAB.
The ActiveX Control DLL file can also be distributed by itself if it has
been compiled with built-in VLC plugins; check developer information for
more information on built-in plugins.
V. Controlling the plugin
1) Properties
The following public properties can be used to control the plugin
from HTML, the property panel of Visual Basic and most ActiveX aware
applications.
+==========+=========+===================================+===============+
| Name: | Type: | Description: | Alias: |
+==========+=========+===================================+===============+
| autoplay | boolean | play when control is activated | autostart |
+----------+---------+-----------------------------------+---------------+
| autoloop | boolean | loop the playlist | loop |
+----------+---------+-----------------------------------+---------------+
| mrl | string | initial MRL in playlist | src, filename |
+----------+---------+-----------------------------------+---------------+
| mute | boolean | mute audio volume | |
+----------+---------+-----------------------------------+---------------+
| visible | boolean | show/hide control viewport | showdisplay |
+----------+---------+-----------------------------------+---------------+
| volume | integer | set/get audio volume | |
+----------+---------+-----------------------------------+---------------+
| toolbar | boolean | set/get visibility of the toolbar | |
+----------+---------+-----------------------------------+---------------+
The alias column shows an alternative <PARAM name> for the property in
internet explorer, which is useful to maintain compatibility with HTML
pages already leveraging Windows Media Player
2) Programming APIs
The MRL, Autoplay and Autoloop properties are only used to configure the
initial state of the ActiveX control,i.e before its activation; they are
ignored afterward. Therefore, if some runtime control is required, the
following APIs should be used within your programming environment:
Variables:
+==========+=========+=========+=======================================+
| Name: | Type: | Access: | Description: |
+==========+=========+=========+=======================================+
| Playing | boolean | RO | Returns whether some MRL is playing |
+----------+---------+---------+---------------------------------------+
| Time | integer | RW | Time elapsed in seconds playing |
| | | | current MRL |
| | | | NOTE: live feeds returns 0 |
+----------+---------+---------+---------------------------------------+
| Position | real | RW | Playback position within current MRL |
| | | | in a scale from 0.0 to 1.0 |
| | | | NOTE: live feeds returns 0.0 |
+----------+---------+---------+---------------------------------------+
| Length | integer | RO | Total length in seconds of current MRL|
| | | | NOTE: live feeds returns 0 |
+----------+---------+---------+---------------------------------------+
| Volume | integer | RW | Current volume from 0 to 100 |
+----------+---------+---------+---------------------------------------+
| Visible | boolean | RW | Indicates whether control is visible |
+----------+---------+---------+---------------------------------------+
Methods:
*** current interface (0.8.6+) ***
UUID : 9BE31822-FDAD-461B-AD51-BE1D1C159921
defined in axvlc.idl as "coclass VLCPlugin2", "interface IVLCControl2"
This interface organizes an API with several objects (like .audio.mute).
It is currently documented on videolan wiki (the url may change) at
http://wiki.videolan.org/Documentation:Play_HowTo/Advanced_Use_of_VLC
*** old interface (deprecated) ***
UUID : E23FE9C6-778E-49D4-B537-38FCDE4887D8
defined in axvlc.idl as "coclass VLCPlugin", "interface IVLCControl"
play()
Play current item the playlist
pause()
Pause current item in the playlist
stop()
Stop playing current item in playlist
shuttle(Seconds as integer)
Advance/backtrack playback by specified amount (which is negative for
backtracking). This is also called relative seeking.
This method does not work for live streams.
fullscreen()
Switch between normal and full screen video
playFaster()
Increase play back speed by 2X, 4X, 8X
playSlower()
Decrease play back speed by 2X, 4X, 8X
toggleMute()
mute/unmute sound output
addTarget(MRL As String, Options as array of strings,
Mode as enumeration, Position as integer)
Add an MRL into the default playlist, you can also specify a list
of playlist options to attach to this MRL or Null for no options.
Mode indicates the action taken by the playlist on MRL and is one
the following:
VLCPlayListInsert = 1 (Insert MRL into playlist at Position)
VLCPlayListInsertAndGo = 9 (Insert MRL into playlist at Position and play it immediately)
VLCPlayListReplace = 2 (Replace MRL in playlist at Position)
VLCPlayListReplaceAndGo = 10 (Replace MRL in playlist at Position and play it immediately)
VLCPlayListAppend = 4 (Append MRL in playlist after Position)
VLCPlayListAppendAndGo = 12 (Append MRL in playlist after Position and play it immediately)
VLCPlayListCheckInsert = 16 (Verify if MRL is in playlist)
Position can take the value of -666 as wildcard for the last element
in the playlist.
setVariable(Name as string, Value as object);
Set a value into a VLC variables
getVariable(Name as string) as object
Retrieve the value of a VLC variable.
Regards,
Damien Fouilleul <Damien dot Fouilleul at laposte dot net>
LIBRARY AXVLC.DLL
EXPORTS
DllMain = DllMain@12
DllCanUnloadNow = DllCanUnloadNow@0
DllGetClassObject = DllGetClassObject@12
DllRegisterServer = DllRegisterServer@0
DllUnregisterServer = DllUnregisterServer@0
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="x86"
name="axvlc.dll"
type="win32"
/>
<description>VLC ActiveX plugin</description>
</assembly>
/*****************************************************************************
* axvlc.idl: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2006 the VideoLAN team
* Copyright (C) 2010 M2X BV
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
* Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
// comments terminated by [t] are by tonsofpcs, regarding the string
// review. April 02, 2006. [t]
// Possibly change all instances of "the current playlist" to "the
// playlist" and "current playlist" to "the playlist" [t]
import "ocidl.idl";
[
uuid(DF2BBE39-40A8-433b-A279-073F48DA94B6),
version(1.0),
helpstring("VideoLAN VLC ActiveX Plugin")
]
library AXVLC
{
// Forward declare all types defined in this typelib
interface IVLCControl;
interface IVLCAudio;
interface IVLCInput;
interface IVLCLogo;
interface IVLCDeinterlace;
interface IVLCMarquee;
interface IVLCPlaylist;
interface IVLCSubtitle;
interface IVLCVideo;
interface IVLCControl2;
dispinterface DVLCEvents;
importlib("stdole2.tlb");
typedef [public] enum VLCPlaylistMode
{
VLCPlayListInsert = 1,
VLCPlayListInsertAndGo = 9,
VLCPlayListReplace = 2,
VLCPlayListReplaceAndGo = 10,
VLCPlayListAppend = 4,
VLCPlayListAppendAndGo = 12,
VLCPlayListCheckInsert = 16
} eVLCPlaylistMode;
// playlist target position
const int VLCPlayListEnd = -666;
// DISPID definitions
const int DISPID_BackColor = -501;
const int DISPID_Visible = 100;
const int DISPID_Playing = 101;
const int DISPID_Position = 102;
const int DISPID_Time = 103;
const int DISPID_Length = 104;
const int DISPID_Volume = 105;
const int DISPID_MRL = 106;
const int DISPID_AutoPlay = 107;
const int DISPID_AutoLoop = 108;
const int DISPID_StartTime = 109;
const int DISPID_BaseURL = 110;
const int DISPID_Toolbar = 111;
[
odl,
uuid(C2FA41D0-B113-476e-AC8C-9BD14999C1C1),
helpstring("VLC Control (deprecated)"),
dual,
oleautomation
]
interface IVLCControl : IDispatch
{
[id(DISPID_Visible), propget, bindable, helpstring("Returns/sets a value that determines whether viewing area is visible or hidden.")]
HRESULT Visible([out, retval] VARIANT_BOOL* visible);
[id(DISPID_Visible), propput, bindable, helpstring("Returns/sets a value that determines whether viewing area is visible or hidden.")]
HRESULT Visible([in] VARIANT_BOOL visible);
[helpstring("Play current target in playlist.")]
HRESULT play();
[helpstring("Pause playback.")]
HRESULT pause();
[helpstring("Stop playback.")]
HRESULT stop();
[id(DISPID_Playing), hidden, propget, helpstring("Returns a value that determines whether VLC is currently playing.")]
HRESULT Playing([out, retval] VARIANT_BOOL* isPlaying);
[id(DISPID_Position), propget, helpstring("Returns/sets playback position within the current item. Position is a relative value ranging from 0.0 to 1.0.")]
HRESULT Position([out, retval] float* position);
[id(DISPID_Position), propput, helpstring("Returns/sets playback position within the current item. Position is a relative value ranging from 0.0 to 1.0.")]
HRESULT Position([in] float position);
[id(DISPID_Time), propget, helpstring("Returns/sets playback time relative to the start of the current item.")]
HRESULT Time([out, retval] int* seconds);
[id(DISPID_Time), propput, helpstring("Returns/sets playback time relative to the start of the current item.")]
HRESULT Time([in] int seconds);
[helpstring("Advance or backtrack playback time, relative to current time.")] //possibly find a better word to replace 'backtrack' [t]
HRESULT shuttle([in] int seconds);
[helpstring("Switch video between normal and fullscreen view modes.")]
HRESULT fullscreen();
[id(DISPID_Length), propget, hidden, helpstring("Returns the total length, in seconds, of the current item, may be unknown.")]
HRESULT Length([out, retval] int* seconds);
[helpstring("Increases playback speed. Possible speeds are: 1x, 2x, 4x, 8x.")]
HRESULT playFaster();
[helpstring("Decreases playback speed. Possible speeds are: 1x, 2x, 4x, 8x.")]
HRESULT playSlower();
[id(DISPID_Volume), propget, helpstring("Returns/sets playback volume, ranges from 0 to 200%.")] //possibly remove % from 'ranges', change to 'values', and specify that 200 is equivilant to 200% (remember, 200% == 2.0, but this gets an int not a float) [t]
HRESULT Volume([out, retval] int* volume);
[id(DISPID_Volume), propput, helpstring("Returns/sets playback volume, ranges from 0 to 200%.")]
HRESULT Volume([in] int volume);
[helpstring("Mute/unmute playback audio.")]
HRESULT toggleMute();
[helpstring("Sets the value of a VLC variable.")]
HRESULT setVariable([in] BSTR name, [in] VARIANT value);
[helpstring("Returns the value of a VLC variable.")]
HRESULT getVariable([in] BSTR name, [out, retval] VARIANT *value);
/*
** use VARIANT rather than a SAFEARRAY as argument type
** for compatibility with some scripting language (JScript)
*/
[helpstring("Add an item to the playlist.")]
HRESULT addTarget([in] BSTR uri, [in] VARIANT options, [in] enum VLCPlaylistMode mode, [in] int position);
[propget, helpstring("Returns index of current item in playlist.")]
HRESULT PlaylistIndex([out, retval] int* index);
[propget, helpstring("Returns number of items in playlist.")]
HRESULT PlaylistCount([out, retval] int* index);
[helpstring("Advance to next item in playlist.")]
HRESULT playlistNext();
[helpstring("Advance to previous item in playlist.")]
HRESULT playlistPrev();
[helpstring("Remove all items from playlist.")]
HRESULT playlistClear();
[propget, hidden, helpstring("Returns VLC Version.")]
HRESULT VersionInfo([out, retval] BSTR* version);
[id(DISPID_MRL), propget, helpstring("Returns/sets the first MRL in playlist, used for AutoPlay")]
HRESULT MRL([out, retval] BSTR* mrl);
[id(DISPID_MRL), propput, helpstring("Returns/sets the first MRL in playlist, used for AutoPlay")]
HRESULT MRL([in] BSTR mrl);
[id(DISPID_AutoPlay), propget, helpstring("Returns/sets a value that determines whether the playlist is played on startup")]
HRESULT AutoPlay([out, retval] VARIANT_BOOL* autoplay);
[id(DISPID_AutoPlay), propput, helpstring("Returns/Sets a value that determines whether the playlist is played on startup")]
HRESULT AutoPlay([in] VARIANT_BOOL autoplay);
[id(DISPID_AutoLoop), propget, helpstring("Returns/sets a value that determines whether the playlist is looped")]
HRESULT AutoLoop([out, retval] VARIANT_BOOL* autoloop);
[id(DISPID_AutoLoop), propput, helpstring("Returns/sets a value that determines whether the playlist is looped")]
HRESULT AutoLoop([in] VARIANT_BOOL autoloop);
};
const int DISPID_PlayEvent = 100;
const int DISPID_PauseEvent = 101;
const int DISPID_StopEvent = 102;
/* async events from libvlc */
const int DISPID_MediaPlayerNothingSpecialEvent = 200;
const int DISPID_MediaPlayerOpeningEvent = 201;
const int DISPID_MediaPlayerBufferingEvent = 202;
const int DISPID_MediaPlayerPlayingEvent = 203;
const int DISPID_MediaPlayerPausedEvent = 204;
const int DISPID_MediaPlayerForwardEvent = 205;
const int DISPID_MediaPlayerBackwardEvent = 206;
const int DISPID_MediaPlayerEncounteredErrorEvent = 207;
const int DISPID_MediaPlayerEndReachedEvent = 208;
const int DISPID_MediaPlayerStoppedEvent = 209;
const int DISPID_MediaPlayerTimeChangedEvent = 210;
const int DISPID_MediaPlayerPositionChangedEvent = 211;
const int DISPID_MediaPlayerSeekableChangedEvent = 212;
const int DISPID_MediaPlayerPausableChangedEvent = 213;
[
uuid(DF48072F-5EF8-434e-9B40-E2F3AE759B5F),
helpstring("Event interface for VLC control"),
]
dispinterface DVLCEvents
{
properties:
methods:
[id(DISPID_PlayEvent), helpstring("Playing")]
void play();
[id(DISPID_PauseEvent), helpstring("Paused")]
void pause();
[id(DISPID_StopEvent), helpstring("Stopped")]
void stop();
/* asyn events from libvlc */
[id(DISPID_MediaPlayerNothingSpecialEvent), helpstring("Idle state")]
void MediaPlayerNothingSpecial();
[id(DISPID_MediaPlayerOpeningEvent), helpstring("Opening media")]
void MediaPlayerOpening();
[id(DISPID_MediaPlayerBufferingEvent), helpstring("Buffering media")]
void MediaPlayerBuffering([in] long cache);
[id(DISPID_MediaPlayerPlayingEvent), helpstring("Media is playing")]
void MediaPlayerPlaying();
[id(DISPID_MediaPlayerPausedEvent), helpstring("Media is paused")]
void MediaPlayerPaused();
[id(DISPID_MediaPlayerForwardEvent), helpstring("Forward playback")]
void MediaPlayerForward();
[id(DISPID_MediaPlayerBackwardEvent), helpstring("Backward playback")]
void MediaPlayerBackward();
[id(DISPID_MediaPlayerEncounteredErrorEvent), helpstring("An error has been encountered")]
void MediaPlayerEncounteredError();
[id(DISPID_MediaPlayerEndReachedEvent), helpstring("End of playback reached")]
void MediaPlayerEndReached();
[id(DISPID_MediaPlayerStoppedEvent), helpstring("Playback stopped")]
void MediaPlayerStopped();
[id(DISPID_MediaPlayerTimeChangedEvent), helpstring("Time changed")]
void MediaPlayerTimeChanged([in] long time);
[id(DISPID_MediaPlayerPositionChangedEvent), helpstring("Position changed")]
void MediaPlayerPositionChanged([in] long position);
[id(DISPID_MediaPlayerSeekableChangedEvent), helpstring("Seek changed")]
void MediaPlayerSeekableChanged([in] VARIANT_BOOL seekable);
[id(DISPID_MediaPlayerPausableChangedEvent), helpstring("Pause setting changed")]
void MediaPlayerPausableChanged([in] VARIANT_BOOL pausable);
};
[
odl,
uuid(9E0BD17B-2D3C-4656-B94D-03084F3FD9D4),
helpstring("VLC Audio APIs"),
dual,
oleautomation
]
interface IVLCAudio : IDispatch
{
[propget, helpstring("Returns/sets the audio mute state.")]
HRESULT mute([out, retval] VARIANT_BOOL* muted);
[propput, helpstring("Returns/sets the audio mute state.")]
HRESULT mute([in] VARIANT_BOOL muted);
[propget, helpstring("Returns/sets audio volume as a percent value.")]
HRESULT volume([out, retval] long* volume);
[propput, helpstring("Returns/sets audio volume as a percent value.")]
HRESULT volume([in] long volume);
[helpstring("Mute/unmute audio playback.")]
HRESULT toggleMute();
[propget, helpstring("Returns/sets audio track used/to use.")]
HRESULT track([out, retval] long* track);
[propput, helpstring("Returns/sets audio track used/to use.")]
HRESULT track([in] long track);
[propget, helpstring("Returns the number of audio tracks available.")]
HRESULT count([out, retval] long* trackNumber);
[helpstring("Returns audio track name.")]
HRESULT description([in] long trackID, [out, retval] BSTR* name);
[propget, helpstring("Returns audio channel [1-5] indicating; stereo, reverse stereo, left, right, dolby.")]
HRESULT channel([out, retval] long* channel);
[propput, helpstring("Sets audio channel to [1-5] indicating; stereo, reverse stereo, left, right, dolby.")]
HRESULT channel([in] long channel);
};
[
odl,
uuid(49E0DBD1-9440-466C-9C97-95C67190C603),
helpstring("VLC Input APIs"),
dual,
oleautomation
]
interface IVLCInput : IDispatch
{
[propget, helpstring("Returns the clip length, in milliseconds.")]
HRESULT length([out, retval] double* length);
[propget, helpstring("Returns/sets playback position in current clip. Position is ranging from 0.0 to 1.0.")]
HRESULT position([out, retval] double* position);
[propput, helpstring("Returns/sets playback position in the current clip. Position ranging from 0.0 to 1.0.")]
HRESULT position([in] double position);
[propget, helpstring("Returns/sets playback time in current clip, in milliseconds.")]
HRESULT time([out, retval] double* time);
[propput, helpstring("Returns/sets playback time in the current clip, in milliseconds.")]
HRESULT time([in] double time);
[propget, helpstring("Returns current playback state.")]
HRESULT state([out, retval] long* state);
[propget, helpstring("Returns/sets current playback rate, normal rate is 1.0 ")]
HRESULT rate([out, retval] double* rate);
[propput, helpstring("Returns/sets current playback rate, normal rate is 1.0.")]
HRESULT rate([in] double rate);
[propget, helpstring("Returns current playback frames per seconds if available.")]
HRESULT fps([out, retval] double* fps);
[propget, helpstring("Returns whether current playback displays video.")]
HRESULT hasVout([out, retval] VARIANT_BOOL* hasVout);
};
[
odl,
uuid(FD37FE32-82BC-4A25-B056-315F4DBB194D),
helpstring("VLC Playlist Items collection"),
dual,
oleautomation
]
interface IVLCPlaylistItems : IDispatch
{
[propget, helpstring("Returns number of items in playlist.")]
HRESULT count([out, retval] long* count);
[helpstring("Remove all items from playlist.")]
HRESULT clear();
[helpstring("remove item from playlist.")]
HRESULT remove([in] long itemId);
};
[
odl,
uuid(54613049-40BF-4035-9E70-0A9312C0188D),
helpstring("VLC Playlist APIs"),
dual,
oleautomation
]
interface IVLCPlaylist : IDispatch
{
[hidden, propget, helpstring("Returns number of items in playlist. (deprecated)")]
HRESULT itemCount([out, retval] long* count);
[propget, helpstring("Returns whether playback displays video.")]
HRESULT isPlaying([out, retval] VARIANT_BOOL* playing);
[helpstring("Add a playlist item.")]
HRESULT add([in] BSTR uri, [in, optional] VARIANT name, [in, optional] VARIANT options, [out, retval] long* itemId);
[helpstring("Play/Resume the playlist.")]
HRESULT play();
[helpstring("Play item in playlist.")]
HRESULT playItem([in] long itemId);
[helpstring("Play/Pause current clip.")]
HRESULT togglePause();
[helpstring("Stop current clip.")]
HRESULT stop();
[helpstring("Advance to next item in playlist.")]
HRESULT next();
[helpstring("Advance to previous item in playlist.")]
HRESULT prev();
[hidden, helpstring("Remove all items from playlist. (deprecated)")]
HRESULT clear();
[hidden, helpstring("Remove item from playlist. (deprecated)")]
HRESULT removeItem([in] long item);
[propget, helpstring("Returns the playlist items collection object.")]
HRESULT items([out, retval] IVLCPlaylistItems** obj);
};
[
odl,
uuid(465E787A-0556-452F-9477-954E4A940003),
helpstring("VLC Subtitle APIs"),
dual,
oleautomation
]
interface IVLCSubtitle : IDispatch
{
[propget, helpstring("Returns video subtitle used.")]
HRESULT track([out, retval] long* spu);
[propput, helpstring("Sets video subtitle to use.")]
HRESULT track([in] long spu);
[propget, helpstring("Returns the number of video subtitles available.")]
HRESULT count([out, retval] long* spuNumber);
[helpstring("Returns video subtitle name.")]
HRESULT description([in] long nameID, [out, retval] BSTR* name);
};
[
odl,
uuid(8D076AD6-9B6F-4150-A0FD-5D7E8C8CB02C),
helpstring("VLC Marquee Filter"),
dual,
oleautomation
]
interface IVLCMarquee : IDispatch
{
[helpstring("enable Marquee Filter.")]
HRESULT enable();
[helpstring("disable Marquee Filter.")]
HRESULT disable();
[propget, helpstring("Retrieve marquee text.")]
HRESULT text([out, retval] BSTR* val);
[propput, helpstring("Change marquee text.")]
HRESULT text([in] BSTR val);
[propget, helpstring("Retrieve text color.")]
HRESULT color([out, retval] LONG* val);
[propput, helpstring("Change text color.")]
HRESULT color([in] LONG val);
[propget, helpstring("Retrieve text opacity.")]
HRESULT opacity([out, retval] LONG* val);
[propput, helpstring("Set text opacity (0=transparent, 255=opaque).")]
HRESULT opacity([in] LONG val);
[propget, helpstring("Retrieve text position.")]
HRESULT position([out, retval] BSTR* val);
[propput, helpstring("Text positioning relative to: center, left, right, top, bottom, top-left, top-right, bottom-left, bottom-right.")]
HRESULT position([in] BSTR val);
[propget, helpstring("Retrieve text refresh time.")]
HRESULT refresh([out, retval] LONG* val);
[propput, helpstring("Set text refresh time.")]
HRESULT refresh([in] LONG val);
[propget, helpstring("Retrieve text size.")]
HRESULT size([out, retval] LONG* val);
[propput, helpstring("Set text size.")]
HRESULT size([in] LONG val);
[propget, helpstring("Retrieve timeout.")]
HRESULT timeout([out, retval] LONG* val);
[propput, helpstring("Change timeout.")]
HRESULT timeout([in] LONG val);
[propget, helpstring("Retrieve text abcissa.")]
HRESULT x([out, retval] LONG* val);
[propput, helpstring("Change text abcissa.")]
HRESULT x([in] LONG val);
[propget, helpstring("Retrieve text ordinate.")]
HRESULT y([out, retval] LONG* val);
[propput, helpstring("Change text ordinate.")]
HRESULT y([in] LONG val);
};
[
odl,
uuid(8a4a20c2-93f3-44e8-8644-beb2e3487e84),
helpstring("VLC Logo Filter"),
dual,
oleautomation
]
interface IVLCLogo : IDispatch
{
[helpstring("Enable the logo filter.")]
HRESULT enable();
[helpstring("Disable the logo filter.")]
HRESULT disable();
[helpstring("specify input file[[,delay],alpha].")]
HRESULT file([in] BSTR fname);
[propget, helpstring("")]
HRESULT delay([out, retval] long* val);
[propput, helpstring("Set delay-to-next-picture in miliseconds.")]
HRESULT delay([in] long val);
[propget, helpstring("")]
HRESULT repeat([out, retval] long* val);
[propput, helpstring("Repeat: -1 continuous (default), 0 no repeat, ....")]
HRESULT repeat([in] long val);
[propget, helpstring("Returns the `global' alpha value.")]
HRESULT opacity([out, retval] long* val);
[propput, helpstring("Alpha value: 0 opaque to 255 fully transparent")]
HRESULT opacity([in] long val);
[propget, helpstring("Retrieve picture position.")]
HRESULT position([out, retval] BSTR* val);
[propput, helpstring("Picture positioning relative to: center, left, right, top, bottom, top-left, top-right, bottom-left, bottom-right.")]
HRESULT position([in] BSTR val);
[propget, helpstring("Picture x offset.")]
HRESULT x([out, retval] long* val);
[propput, helpstring("Picture x offset.")]
HRESULT x([in] long val);
[propget, helpstring("Picture y offset.")]
HRESULT y([out, retval] long* val);
[propput, helpstring("Picture y offset.")]
HRESULT y([in] long val);
};
[
odl,
uuid(bc97469f-cb11-4037-8dce-5fc9f5f85307),
helpstring("VLC Deinterlace Filter"),
dual,
oleautomation
]
interface IVLCDeinterlace : IDispatch
{
[helpstring("Enable deinterlace filter and set method.")]
HRESULT enable([in] BSTR mode);
[helpstring("Disable deinterlace filter.")]
HRESULT disable();
};
[
odl,
uuid(0AAEDF0B-D333-4B27-A0C6-BBF31413A42E),
helpstring("VLC Video APIs"),
dual,
oleautomation
]
interface IVLCVideo : IDispatch
{
[propget, helpstring("Returns/sets the fullscreen state.")]
HRESULT fullscreen([out, retval] VARIANT_BOOL* fullscreen);
[propput, helpstring("Returns/sets the fullscreen state.")]
HRESULT fullscreen([in] VARIANT_BOOL fullscreen);
[propget, helpstring("Returns video original width.")]
HRESULT width([out, retval] long* width);
[propget, helpstring("Returns video original height.")]
HRESULT height([out, retval] long* height);
[propget, helpstring("Returns video aspect ratio.")]
HRESULT aspectRatio([out, retval] BSTR* aspect);
[propput, helpstring("Sets video aspect ratio.")]
HRESULT aspectRatio([in] BSTR aspect);
[propget, helpstring("Returns video subtitle used.")]
HRESULT subtitle([out, retval] long* spu);
[propput, helpstring("Sets video subtitle to use.")]
HRESULT subtitle([in] long spu);
[propget, helpstring("Returns crop filter geometry.")]
HRESULT crop([out, retval] BSTR* geometry);
[propput, helpstring("Sets crop filter geometry.")]
HRESULT crop([in] BSTR geometry);
[propget, helpstring("Returns teletext page used.")]
HRESULT teletext([out, retval] long* page);
[propput, helpstring("Sets teletext page to use.")]
HRESULT teletext([in] long page);
[helpstring("toggle fullscreen/windowed state.")]
HRESULT toggleFullscreen();
[helpstring("take video snapshot and save it into picture object.")]
HRESULT takeSnapshot([out, retval] IPictureDisp** picture);
[helpstring("toggle teletext transparent state.")]
HRESULT toggleTeletext();
[propget, helpstring("Returns the marquee object.")]
HRESULT marquee([out, retval] IVLCMarquee** obj);
[propget, helpstring("Returns the logo object.")]
HRESULT logo([out, retval] IVLCLogo** obj);
[propget, helpstring("Returns the logo object.")]
HRESULT deinterlace([out, retval] IVLCDeinterlace** obj);
};
[
odl,
uuid(2D719729-5333-406C-BF12-8DE787FD65E3),
helpstring("VLC Control"),
dual,
oleautomation
]
interface IVLCControl2 : IDispatch
{
[id(DISPID_AutoLoop), propget, helpstring("Returns/sets a value that determines whether the playlist is looped")]
HRESULT AutoLoop([out, retval] VARIANT_BOOL* autoloop);
[id(DISPID_AutoLoop), propput, helpstring("Returns/sets a value that determines whether the playlist is looped")]
HRESULT AutoLoop([in] VARIANT_BOOL autoloop);
[id(DISPID_AutoPlay), propget, helpstring("Returns/sets a value that determines whether the playlist is played on startup")]
HRESULT AutoPlay([out, retval] VARIANT_BOOL* autoplay);
[id(DISPID_AutoPlay), propput, helpstring("Returns/Sets a value that determines whether the playlist is played on startup")]
HRESULT AutoPlay([in] VARIANT_BOOL autoplay);
[id(DISPID_BaseURL), propget, helpstring("Returns/sets the base URL for relative paths")]
HRESULT BaseURL([out, retval] BSTR* url);
[id(DISPID_BaseURL), propput, helpstring("Returns/sets the base URL for relative paths")]
HRESULT BaseURL([in] BSTR url);
[id(DISPID_StartTime), propget, helpstring("Returns/sets playback start time of URL.")]
HRESULT StartTime([out, retval] long* seconds);
[id(DISPID_StartTime), propput, helpstring("Returns/sets playback start time of URL.")]
HRESULT StartTime([in] long seconds);
[id(DISPID_MRL), propget, helpstring("Returns/sets the default MRL in playlist")]
HRESULT MRL([out, retval] BSTR* mrl);
[id(DISPID_MRL), propput, helpstring("Returns/sets the default MRL in playlist")]
HRESULT MRL([in] BSTR mrl);
[propget, helpstring("Returns VLC Version.")]
HRESULT VersionInfo([out, retval] BSTR* version);
[id(DISPID_Visible), propget, helpstring("Returns/sets a value that determines whether viewing area is visible or hidden.")]
HRESULT Visible([out, retval] VARIANT_BOOL* visible);
[id(DISPID_Visible), propput, helpstring("Returns/sets a value that determines whether viewing area is visible or hidden.")]
HRESULT Visible([in] VARIANT_BOOL visible);
[id(DISPID_Volume), propget, helpstring("Returns/sets default audio volume.")]
HRESULT Volume([out, retval] long* volume);
[id(DISPID_Volume), propput, helpstring("Returns/sets default audio volume.")]
HRESULT Volume([in] long volume);
[id(DISPID_BackColor), propget, helpstring("Returns/sets background color.")]
HRESULT BackColor([out, retval] OLE_COLOR* backcolor);
[id(DISPID_BackColor), propput, helpstring("Returns/sets background color.")]
HRESULT BackColor([in] OLE_COLOR backcolor);
/*
* caution: vlcobject.toolbar:bool does not yet exists in Firefox
* plugin. Official usage is through "toolbar" property for now,
* which is compatibile with Firefox.
*/
[id(DISPID_Toolbar), propget, helpstring("Returns/sets visibility of the toolbar")]
HRESULT Toolbar([out, retval] VARIANT_BOOL* visible);
[id(DISPID_Toolbar), propput, helpstring("Returns/sets visibility of the toolbar")]
HRESULT Toolbar([in] VARIANT_BOOL visible);
[propget, helpstring("Returns the audio object.")]
HRESULT audio([out, retval] IVLCAudio** obj);
[propget, helpstring("Returns the audio object.")]
HRESULT input([out, retval] IVLCInput** obj);
[propget, helpstring("Returns the playlist object.")]
HRESULT playlist([out, retval] IVLCPlaylist** obj);
[propget, helpstring("Returns the audio object.")]
HRESULT subtitle([out, retval] IVLCSubtitle** obj);
[propget, helpstring("Returns the audio object.")]
HRESULT video([out, retval] IVLCVideo** obj);
};
[
uuid(E23FE9C6-778E-49D4-B537-38FCDE4887D8),
helpstring("VLC control (deprecated)"),
control
]
coclass VLCPlugin
{
[default] interface IVLCControl;
interface IVLCControl2;
[default, source] dispinterface DVLCEvents;
};
[
uuid(9BE31822-FDAD-461B-AD51-BE1D1C159921),
helpstring("VLC control"),
control
]
coclass VLCPlugin2
{
[default] interface IVLCControl2;
interface IVLCControl;
[default, source] dispinterface DVLCEvents;
};
};
; Version number and signature of INF file.
;
[version]
signature="$CHICAGO$"
AdvancedINF=2.0
[Add.Code]
axvlc.dll=axvlc.dll
vlc-@VERSION@-win32.exe=vlc-@VERSION@-win32.exe
[axvlc.dll]
FileVersion=@VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_REVISION@,0
clsid={9BE31822-FDAD-461B-AD51-BE1D1C159921}
RegisterServer=no
Hook=runinstaller
[vlc-@VERSION@-win32.exe]
FileVersion=@VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_REVISION@,0
file-win32-x86=http://downloads.videolan.org/pub/videolan/vlc/@VERSION@/win32/vlc-@VERSION@-win32.exe
[runinstaller]
run=%EXTRACT_DIR%\vlc-@VERSION@-win32.exe
/*** Autogenerated by WIDL 1.1.38 from axvlc.idl - Do not edit ***/
#include <rpc.h>
#include <rpcndr.h>
#include <initguid.h>
#ifdef __cplusplus
extern "C" {
#endif
DEFINE_GUID(LIBID_AXVLC, 0xdf2bbe39, 0x40a8, 0x433b, 0xa2,0x79, 0x07,0x3f,0x48,0xda,0x94,0xb6);
DEFINE_GUID(IID_IVLCControl, 0xc2fa41d0, 0xb113, 0x476e, 0xac,0x8c, 0x9b,0xd1,0x49,0x99,0xc1,0xc1);
DEFINE_GUID(DIID_DVLCEvents, 0xdf48072f, 0x5ef8, 0x434e, 0x9b,0x40, 0xe2,0xf3,0xae,0x75,0x9b,0x5f);
DEFINE_GUID(IID_IVLCAudio, 0x9e0bd17b, 0x2d3c, 0x4656, 0xb9,0x4d, 0x03,0x08,0x4f,0x3f,0xd9,0xd4);
DEFINE_GUID(IID_IVLCInput, 0x49e0dbd1, 0x9440, 0x466c, 0x9c,0x97, 0x95,0xc6,0x71,0x90,0xc6,0x03);
DEFINE_GUID(IID_IVLCPlaylistItems, 0xfd37fe32, 0x82bc, 0x4a25, 0xb0,0x56, 0x31,0x5f,0x4d,0xbb,0x19,0x4d);
DEFINE_GUID(IID_IVLCPlaylist, 0x54613049, 0x40bf, 0x4035, 0x9e,0x70, 0x0a,0x93,0x12,0xc0,0x18,0x8d);
DEFINE_GUID(IID_IVLCSubtitle, 0x465e787a, 0x0556, 0x452f, 0x94,0x77, 0x95,0x4e,0x4a,0x94,0x00,0x03);
DEFINE_GUID(IID_IVLCMarquee, 0x8d076ad6, 0x9b6f, 0x4150, 0xa0,0xfd, 0x5d,0x7e,0x8c,0x8c,0xb0,0x2c);
DEFINE_GUID(IID_IVLCLogo, 0x8a4a20c2, 0x93f3, 0x44e8, 0x86,0x44, 0xbe,0xb2,0xe3,0x48,0x7e,0x84);
DEFINE_GUID(IID_IVLCDeinterlace, 0xbc97469f, 0xcb11, 0x4037, 0x8d,0xce, 0x5f,0xc9,0xf5,0xf8,0x53,0x07);
DEFINE_GUID(IID_IVLCVideo, 0x0aaedf0b, 0xd333, 0x4b27, 0xa0,0xc6, 0xbb,0xf3,0x14,0x13,0xa4,0x2e);
DEFINE_GUID(IID_IVLCControl2, 0x2d719729, 0x5333, 0x406c, 0xbf,0x12, 0x8d,0xe7,0x87,0xfd,0x65,0xe3);
DEFINE_GUID(CLSID_VLCPlugin, 0xe23fe9c6, 0x778e, 0x49d4, 0xb5,0x37, 0x38,0xfc,0xde,0x48,0x87,0xd8);
DEFINE_GUID(CLSID_VLCPlugin2, 0x9be31822, 0xfdad, 0x461b, 0xad,0x51, 0xbe,0x1d,0x1c,0x15,0x99,0x21);
#ifdef __cplusplus
}
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
#define VERSION_NUMBER @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_REVISION@,@VERSION_EXTRA_RC@
1 BITMAP "vlc16x16.bmp"
1 VERSIONINFO
FILETYPE 1
FILEOS 4
PRODUCTVERSION VERSION_NUMBER
FILEVERSION VERSION_NUMBER
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", "VideoLAN"
VALUE "FileVersion", "@VERSION@"
VALUE "FileDescription", "VLC media player (Activex Plugin)"
VALUE "LegalCopyright", "(c) @COPYRIGHT_YEARS@ VideoLAN and Authors"
VALUE "OLESelfRegister", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
2 BITMAP DISCARDABLE "inplace.bmp"
1 TYPELIB "axvlc.tlb"
/*****************************************************************************
* connectioncontainer.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
* Copyright (C) 2010 M2X BV
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "connectioncontainer.h"
#include "utils.h"
#include <assert.h>
#include <rpc.h>
#include <rpcndr.h>
using namespace std;
////////////////////////////////////////////////////////////////////////////////////////////////
DEFINE_GUID(IID_IGlobalInterfaceTable, 0x00000146, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
DEFINE_GUID(CLSID_StdGlobalInterfaceTable, 0x00000323, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
const GUID IID_IGlobalInterfaceTable = { 0x00000146, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
const CLSID CLSID_StdGlobalInterfaceTable = { 0x00000323, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
////////////////////////////////////////////////////////////////////////////////////////////////
/* this function object is used to return the value from a map pair */
struct VLCEnumConnectionsDereference
{
CONNECTDATA operator()(const map<DWORD,LPUNKNOWN>::iterator& i)
{
CONNECTDATA cd;
i->second->AddRef();
cd.dwCookie = i->first;
cd.pUnk = i->second;
return cd;
};
};
class VLCEnumConnections : public VLCEnumIterator<IID_IEnumConnections,
IEnumConnections,
CONNECTDATA,
map<DWORD,LPUNKNOWN>::iterator,
VLCEnumConnectionsDereference>
{
public:
VLCEnumConnections(map<DWORD,LPUNKNOWN> &m) :
VLCEnumIterator<IID_IEnumConnections,
IEnumConnections,
CONNECTDATA,
map<DWORD,LPUNKNOWN>::iterator,
VLCEnumConnectionsDereference> (m.begin(), m.end())
{};
};
////////////////////////////////////////////////////////////////////////////////////////////////
/* this function object is used to retain the dereferenced iterator value */
struct VLCEnumConnectionPointsDereference
{
LPCONNECTIONPOINT operator()(const vector<LPCONNECTIONPOINT>::iterator& i)
{
LPCONNECTIONPOINT cp = *i;
cp->AddRef();
return cp;
}
};
class VLCEnumConnectionPoints: public VLCEnumIterator<IID_IEnumConnectionPoints,
IEnumConnectionPoints,
LPCONNECTIONPOINT,
vector<LPCONNECTIONPOINT>::iterator,
VLCEnumConnectionPointsDereference>
{
public:
VLCEnumConnectionPoints(vector<LPCONNECTIONPOINT>& v) :
VLCEnumIterator<IID_IEnumConnectionPoints,
IEnumConnectionPoints,
LPCONNECTIONPOINT,
vector<LPCONNECTIONPOINT>::iterator,
VLCEnumConnectionPointsDereference> (v.begin(), v.end())
{};
};
////////////////////////////////////////////////////////////////////////////////////////////////
// Condition variable emulation
////////////////////////////////////////////////////////////////////////////////////////////////
static void ConditionInit(HANDLE *handle)
{
*handle = CreateEvent(NULL, TRUE, FALSE, NULL);
assert(*handle != NULL);
}
static void ConditionDestroy(HANDLE *handle)
{
CloseHandle(*handle);
}
static void ConditionWait(HANDLE *handle, CRITICAL_SECTION *lock)
{
DWORD dwWaitResult;
do {
LeaveCriticalSection(lock);
dwWaitResult = WaitForSingleObjectEx(*handle, INFINITE, TRUE);
EnterCriticalSection(lock);
} while(dwWaitResult == WAIT_IO_COMPLETION);
assert(dwWaitResult != WAIT_ABANDONED); /* another thread failed to cleanup! */
assert(dwWaitResult != WAIT_FAILED);
ResetEvent(*handle);
}
static void ConditionSignal(HANDLE *handle)
{
SetEvent(*handle);
}
////////////////////////////////////////////////////////////////////////////////////////////////
// Event handling thread
//
// It bridges the gap between libvlc thread context and ActiveX/COM thread context.
////////////////////////////////////////////////////////////////////////////////////////////////
DWORD WINAPI ThreadProcEventHandler(LPVOID lpParam)
{
CoInitialize(NULL);
VLCConnectionPointContainer *pCPC = (VLCConnectionPointContainer *)lpParam;
while(pCPC->isRunning)
{
EnterCriticalSection(&(pCPC->csEvents));
ConditionWait(&(pCPC->sEvents), &(pCPC->csEvents));
if (!pCPC->isRunning)
{
LeaveCriticalSection(&(pCPC->csEvents));
break;
}
while(!pCPC->_q_events.empty())
{
VLCDispatchEvent *ev = pCPC->_q_events.front();
pCPC->_q_events.pop();
pCPC->_p_events->fireEvent(ev->_dispId, &ev->_dispParams);
delete ev;
if (!pCPC->isRunning)
{
LeaveCriticalSection(&(pCPC->csEvents));
goto out;
}
}
LeaveCriticalSection(&(pCPC->csEvents));
}
out:
CoUninitialize();
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////
// VLCConnectionPoint
////////////////////////////////////////////////////////////////////////////////////////////////
VLCConnectionPoint::VLCConnectionPoint(IConnectionPointContainer *p_cpc, REFIID iid) :
_iid(iid), _p_cpc(p_cpc)
{
// Get the Global Interface Table per-process singleton:
CoCreateInstance(CLSID_StdGlobalInterfaceTable, 0,
CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable,
reinterpret_cast<void**>(&m_pGIT));
};
VLCConnectionPoint::~VLCConnectionPoint()
{
// Revoke interfaces from the GIT:
map<DWORD,LPUNKNOWN>::iterator end = _connections.end();
map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin();
while( iter != end )
{
m_pGIT->RevokeInterfaceFromGlobal((DWORD)iter->second);
++iter;
}
m_pGIT->Release();
};
STDMETHODIMP VLCConnectionPoint::GetConnectionInterface(IID *iid)
{
if( NULL == iid )
return E_POINTER;
*iid = _iid;
return S_OK;
};
STDMETHODIMP VLCConnectionPoint::GetConnectionPointContainer(LPCONNECTIONPOINTCONTAINER *ppCPC)
{
if( NULL == ppCPC )
return E_POINTER;
_p_cpc->AddRef();
*ppCPC = _p_cpc;
return S_OK;
};
STDMETHODIMP VLCConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)
{
static DWORD dwCookieCounter = 0;
HRESULT hr;
if( (NULL == pUnk) || (NULL == pdwCookie) )
return E_POINTER;
hr = pUnk->QueryInterface(_iid, (LPVOID *)&pUnk);
if( SUCCEEDED(hr) )
{
DWORD dwGITCookie;
hr = m_pGIT->RegisterInterfaceInGlobal( pUnk, _iid, &dwGITCookie );
if( SUCCEEDED(hr) )
{
*pdwCookie = ++dwCookieCounter;
_connections[*pdwCookie] = (LPUNKNOWN) dwGITCookie;
}
pUnk->Release();
}
return hr;
};
STDMETHODIMP VLCConnectionPoint::Unadvise(DWORD pdwCookie)
{
map<DWORD,LPUNKNOWN>::iterator pcd = _connections.find((DWORD)pdwCookie);
if( pcd != _connections.end() )
{
m_pGIT->RevokeInterfaceFromGlobal((DWORD)pcd->second);
_connections.erase(pdwCookie);
return S_OK;
}
return CONNECT_E_NOCONNECTION;
};
STDMETHODIMP VLCConnectionPoint::EnumConnections(IEnumConnections **ppEnum)
{
if( NULL == ppEnum )
return E_POINTER;
*ppEnum = dynamic_cast<LPENUMCONNECTIONS>(new VLCEnumConnections(_connections));
return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
};
void VLCConnectionPoint::fireEvent(DISPID dispId, DISPPARAMS *pDispParams)
{
map<DWORD,LPUNKNOWN>::iterator end = _connections.end();
map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin();
HRESULT hr = S_OK;
while( iter != end )
{
DWORD dwCookie = (DWORD)iter->second;
LPUNKNOWN pUnk;
hr = m_pGIT->GetInterfaceFromGlobal( dwCookie, _iid,
reinterpret_cast<void **>(&pUnk) );
if( SUCCEEDED(hr) )
{
IDispatch *pDisp;
hr = pUnk->QueryInterface(_iid, (LPVOID *)&pDisp);
if( SUCCEEDED(hr) )
{
pDisp->Invoke(dispId, IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD, pDispParams, NULL, NULL, NULL);
pDisp->Release();
}
pUnk->Release();
}
++iter;
}
};
void VLCConnectionPoint::firePropChangedEvent(DISPID dispId)
{
map<DWORD,LPUNKNOWN>::iterator end = _connections.end();
map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin();
while( iter != end )
{
LPUNKNOWN pUnk;
HRESULT hr;
hr = m_pGIT->GetInterfaceFromGlobal( (DWORD)iter->second, IID_IUnknown,
reinterpret_cast<void **>(&pUnk) );
if( SUCCEEDED(hr) )
{
IPropertyNotifySink *pPropSink;
hr = pUnk->QueryInterface( IID_IPropertyNotifySink, (LPVOID *)&pPropSink );
if( SUCCEEDED(hr) )
{
pPropSink->OnChanged(dispId);
pPropSink->Release();
}
pUnk->Release();
}
++iter;
}
};
////////////////////////////////////////////////////////////////////////////////////////////////
VLCDispatchEvent::~VLCDispatchEvent()
{
//clear event arguments
if( NULL != _dispParams.rgvarg )
{
for(unsigned int c = 0; c < _dispParams.cArgs; ++c)
VariantClear(_dispParams.rgvarg + c);
CoTaskMemFree(_dispParams.rgvarg);
}
if( NULL != _dispParams.rgdispidNamedArgs )
CoTaskMemFree(_dispParams.rgdispidNamedArgs);
};
////////////////////////////////////////////////////////////////////////////////////////////////
// VLCConnectionPointContainer
////////////////////////////////////////////////////////////////////////////////////////////////
VLCConnectionPointContainer::VLCConnectionPointContainer(VLCPlugin *p_instance) :
_p_instance(p_instance), freeze(FALSE), isRunning(TRUE)
{
_p_events = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),
_p_instance->getDispEventID());
_v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_events));
_p_props = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),
IID_IPropertyNotifySink);
_v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_props));
// init protection
InitializeCriticalSection(&csEvents);
ConditionInit(&sEvents);
// create thread
hThread = CreateThread(NULL, NULL, ThreadProcEventHandler,
dynamic_cast<LPVOID>(this), NULL, NULL);
};
VLCConnectionPointContainer::~VLCConnectionPointContainer()
{
EnterCriticalSection(&csEvents);
isRunning = FALSE;
freeze = TRUE;
ConditionSignal(&sEvents);
LeaveCriticalSection(&csEvents);
do {
/* nothing wait for thread to finish */;
} while(WaitForSingleObjectEx (hThread, INFINITE, TRUE) == WAIT_IO_COMPLETION);
CloseHandle(hThread);
ConditionDestroy(&sEvents);
DeleteCriticalSection(&csEvents);
_v_cps.clear();
while(!_q_events.empty()) {
_q_events.pop();
};
delete _p_props;
delete _p_events;
};
STDMETHODIMP VLCConnectionPointContainer::EnumConnectionPoints(LPENUMCONNECTIONPOINTS *ppEnum)
{
if( NULL == ppEnum )
return E_POINTER;
*ppEnum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(_v_cps));
return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
};
STDMETHODIMP VLCConnectionPointContainer::FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP)
{
if( NULL == ppCP )
return E_POINTER;
*ppCP = NULL;
if( IID_IPropertyNotifySink == riid )
{
_p_props->AddRef();
*ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_props);
}
else if( _p_instance->getDispEventID() == riid )
{
_p_events->AddRef();
*ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_events);
}
else
return CONNECT_E_NOCONNECTION;
return NOERROR;
};
void VLCConnectionPointContainer::freezeEvents(BOOL bFreeze)
{
EnterCriticalSection(&csEvents);
freeze = bFreeze;
LeaveCriticalSection(&csEvents);
};
void VLCConnectionPointContainer::fireEvent(DISPID dispId, DISPPARAMS* pDispParams)
{
EnterCriticalSection(&csEvents);
// queue event for later use when container is ready
_q_events.push(new VLCDispatchEvent(dispId, *pDispParams));
if( _q_events.size() > 1024 )
{
// too many events in queue, get rid of older one
delete _q_events.front();
_q_events.pop();
}
ConditionSignal(&sEvents);
LeaveCriticalSection(&csEvents);
};
void VLCConnectionPointContainer::firePropChangedEvent(DISPID dispId)
{
if( ! freeze )
_p_props->firePropChangedEvent(dispId);
};
/*****************************************************************************
* connectioncontainer.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
* Copyright (C) 2010 M2X BV
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __CONNECTIONCONTAINER_H__
#define __CONNECTIONCONTAINER_H__
#include <ocidl.h>
#include <vector>
#include <queue>
#include <map>
#include <cguid.h>
class VLCConnectionPoint : public IConnectionPoint
{
public:
VLCConnectionPoint(IConnectionPointContainer *p_cpc, REFIID iid);
virtual ~VLCConnectionPoint();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IConnectionPoint == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
// must be a standalone object
return E_NOINTERFACE;
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_cpc->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_cpc->Release(); };
// IConnectionPoint methods
STDMETHODIMP GetConnectionInterface(IID *);
STDMETHODIMP GetConnectionPointContainer(LPCONNECTIONPOINTCONTAINER *);
STDMETHODIMP Advise(IUnknown *, DWORD *);
STDMETHODIMP Unadvise(DWORD);
STDMETHODIMP EnumConnections(LPENUMCONNECTIONS *);
void fireEvent(DISPID dispIdMember, DISPPARAMS* pDispParams);
void firePropChangedEvent(DISPID dispId);
private:
REFIID _iid;
IGlobalInterfaceTable *m_pGIT;
IConnectionPointContainer *_p_cpc;
std::map<DWORD, LPUNKNOWN> _connections;
};
//////////////////////////////////////////////////////////////////////////
class VLCDispatchEvent {
public:
VLCDispatchEvent(DISPID dispId, DISPPARAMS dispParams) :
_dispId(dispId), _dispParams(dispParams) {};
VLCDispatchEvent(const VLCDispatchEvent&);
~VLCDispatchEvent();
DISPID _dispId;
DISPPARAMS _dispParams;
};
class VLCConnectionPointContainer : public IConnectionPointContainer
{
public:
VLCConnectionPointContainer(VLCPlugin *p_instance);
virtual ~VLCConnectionPointContainer();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv)
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IConnectionPointContainer == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IConnectionPointContainer methods
STDMETHODIMP EnumConnectionPoints(LPENUMCONNECTIONPOINTS *);
STDMETHODIMP FindConnectionPoint(REFIID, LPCONNECTIONPOINT *);
void freezeEvents(BOOL);
void fireEvent(DISPID, DISPPARAMS*);
void firePropChangedEvent(DISPID dispId);
public:
CRITICAL_SECTION csEvents;
HANDLE sEvents;
VLCPlugin *_p_instance;
BOOL isRunning;
BOOL freeze;
VLCConnectionPoint *_p_events;
VLCConnectionPoint *_p_props;
std::vector<LPCONNECTIONPOINT> _v_cps;
std::queue<class VLCDispatchEvent *> _q_events;
private:
HANDLE hThread;
};
#endif
/*****************************************************************************
* viewobject.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 VideoLAN
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "dataobject.h"
#include "utils.h"
using namespace std;
//////////////////////////////////////////////////////////////////////////////
static const FORMATETC _metaFileFormatEtc =
{
CF_METAFILEPICT,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_MFPICT,
};
static const FORMATETC _enhMetaFileFormatEtc =
{
CF_ENHMETAFILE,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_ENHMF,
};
class VLCEnumFORMATETC : public VLCEnumIterator<IID_IEnumFORMATETC,
IEnumFORMATETC,
FORMATETC,
vector<FORMATETC>::iterator>
{
public:
VLCEnumFORMATETC(vector<FORMATETC> v) :
VLCEnumIterator<IID_IEnumFORMATETC,
IEnumFORMATETC,
FORMATETC,
vector<FORMATETC>::iterator>(v.begin(), v.end())
{};
};
//////////////////////////////////////////////////////////////////////////////
VLCDataObject::VLCDataObject(VLCPlugin *p_instance) : _p_instance(p_instance)
{
_v_formatEtc.push_back(_enhMetaFileFormatEtc);
_v_formatEtc.push_back(_metaFileFormatEtc);
CreateDataAdviseHolder(&_p_adviseHolder);
};
VLCDataObject::~VLCDataObject()
{
_p_adviseHolder->Release();
};
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP VLCDataObject::DAdvise(LPFORMATETC pFormatEtc, DWORD padvf,
LPADVISESINK pAdviseSink, LPDWORD pdwConnection)
{
return _p_adviseHolder->Advise(this,
pFormatEtc, padvf,pAdviseSink, pdwConnection);
};
STDMETHODIMP VLCDataObject::DUnadvise(DWORD dwConnection)
{
return _p_adviseHolder->Unadvise(dwConnection);
};
STDMETHODIMP VLCDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
{
return _p_adviseHolder->EnumAdvise(ppenumAdvise);
};
STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection,
IEnumFORMATETC **ppEnum)
{
if( NULL == ppEnum )
return E_POINTER;
*ppEnum = new VLCEnumFORMATETC(_v_formatEtc);
return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
};
STDMETHODIMP VLCDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatEtcIn,
LPFORMATETC pFormatEtcOut)
{
HRESULT result = QueryGetData(pFormatEtcIn);
if( FAILED(result) )
return result;
if( NULL == pFormatEtcOut )
return E_POINTER;
*pFormatEtcOut = *pFormatEtcIn;
pFormatEtcOut->ptd = NULL;
return DATA_S_SAMEFORMATETC;
};
STDMETHODIMP VLCDataObject::GetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
{
if( NULL == pMedium )
return E_POINTER;
HRESULT result = QueryGetData(pFormatEtc);
if( SUCCEEDED(result) )
{
switch( pFormatEtc->cfFormat )
{
case CF_METAFILEPICT:
pMedium->tymed = TYMED_MFPICT;
pMedium->hMetaFilePict = NULL;
pMedium->pUnkForRelease = NULL;
result = getMetaFileData(pFormatEtc, pMedium);
break;
case CF_ENHMETAFILE:
pMedium->tymed = TYMED_ENHMF;
pMedium->hEnhMetaFile = NULL;
pMedium->pUnkForRelease = NULL;
result = getEnhMetaFileData(pFormatEtc, pMedium);
break;
default:
result = DV_E_FORMATETC;
}
}
return result;
};
STDMETHODIMP VLCDataObject::GetDataHere(LPFORMATETC pFormatEtc,
LPSTGMEDIUM pMedium)
{
if( NULL == pMedium )
return E_POINTER;
return E_NOTIMPL;
}
//////////////////////////////////////////////////////////////////////////////
HRESULT VLCDataObject::getMetaFileData(LPFORMATETC pFormatEtc,
LPSTGMEDIUM pMedium)
{
HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
if( NULL == hicTargetDev )
return E_FAIL;
HDC hdcMeta = CreateMetaFile(NULL);
if( NULL != hdcMeta )
{
LPMETAFILEPICT pMetaFilePict =
(LPMETAFILEPICT)CoTaskMemAlloc(sizeof(METAFILEPICT));
if( NULL != pMetaFilePict )
{
SIZEL size = _p_instance->getExtent();
RECTL wBounds = { 0L, 0L, size.cx, size.cy };
pMetaFilePict->mm = MM_ANISOTROPIC;
pMetaFilePict->xExt = size.cx;
pMetaFilePict->yExt = size.cy;
DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
SetMapMode(hdcMeta, MM_ANISOTROPIC);
SetWindowExtEx(hdcMeta, size.cx, size.cy, NULL);
RECTL bounds = { 0L, 0L, size.cx, size.cy };
_p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta,
&bounds, &wBounds);
pMetaFilePict->hMF = CloseMetaFile(hdcMeta);
if( NULL != pMetaFilePict->hMF )
pMedium->hMetaFilePict = pMetaFilePict;
else
CoTaskMemFree(pMetaFilePict);
}
}
DeleteDC(hicTargetDev);
return (NULL != pMedium->hMetaFilePict) ? S_OK : E_FAIL;
};
HRESULT VLCDataObject::getEnhMetaFileData(LPFORMATETC pFormatEtc,
LPSTGMEDIUM pMedium)
{
HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
if( NULL == hicTargetDev )
return E_FAIL;
SIZEL size = _p_instance->getExtent();
HDC hdcMeta = CreateEnhMetaFile(hicTargetDev, NULL, NULL, NULL);
if( NULL != hdcMeta )
{
RECTL wBounds = { 0L, 0L, size.cx, size.cy };
DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
RECTL bounds = { 0L, 0L, size.cx, size.cy };
_p_instance->onDraw(pFormatEtc->ptd, hicTargetDev,
hdcMeta, &bounds, &wBounds);
pMedium->hEnhMetaFile = CloseEnhMetaFile(hdcMeta);
}
DeleteDC(hicTargetDev);
return (NULL != pMedium->hEnhMetaFile) ? S_OK : E_FAIL;
};
STDMETHODIMP VLCDataObject::QueryGetData(LPFORMATETC pFormatEtc)
{
if( NULL == pFormatEtc )
return E_POINTER;
const FORMATETC *formatEtc;
switch( pFormatEtc->cfFormat )
{
case CF_METAFILEPICT:
formatEtc = &_metaFileFormatEtc;
break;
case CF_ENHMETAFILE:
formatEtc = &_enhMetaFileFormatEtc;
break;
default:
return DV_E_FORMATETC;
}
if( pFormatEtc->dwAspect != formatEtc->dwAspect )
return DV_E_DVASPECT;
if( pFormatEtc->lindex != formatEtc->lindex )
return DV_E_LINDEX;
if( pFormatEtc->tymed != formatEtc->tymed )
return DV_E_TYMED;
return S_OK;
};
STDMETHODIMP VLCDataObject::SetData(LPFORMATETC pFormatEtc,
LPSTGMEDIUM pMedium, BOOL fRelease)
{
return E_NOTIMPL;
};
/*void VLCDataObject::onDataChange(void)
{
_p_adviseHolder->SendOnDataChange(this, 0, 0);
};*/
void VLCDataObject::onClose(void)
{
_p_adviseHolder->SendOnDataChange(this, 0, ADVF_DATAONSTOP);
if( S_OK == OleIsCurrentClipboard(dynamic_cast<LPDATAOBJECT>(this)) )
OleFlushClipboard();
};
/*****************************************************************************
* persiststorage.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 VideoLAN
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __DATAOBJECT_H__
#define __DATAOBJECT_H__
#include <objidl.h>
#include <vector>
class VLCDataObject : public IDataObject
{
public:
VLCDataObject(VLCPlugin *p_instance);
virtual ~VLCDataObject();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv)
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IDataObject == riid) ) {
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IDataObject methods
STDMETHODIMP DAdvise(LPFORMATETC,DWORD,LPADVISESINK,LPDWORD);
STDMETHODIMP DUnadvise(DWORD);
STDMETHODIMP EnumDAdvise(IEnumSTATDATA**);
STDMETHODIMP EnumFormatEtc(DWORD, IEnumFORMATETC**);
STDMETHODIMP GetCanonicalFormatEtc(LPFORMATETC,LPFORMATETC);
STDMETHODIMP GetData(LPFORMATETC,LPSTGMEDIUM);
STDMETHODIMP GetDataHere(LPFORMATETC,LPSTGMEDIUM);
STDMETHODIMP QueryGetData(LPFORMATETC);
STDMETHODIMP SetData(LPFORMATETC,LPSTGMEDIUM,BOOL);
void onClose(void);
private:
HRESULT getMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
HRESULT getEnhMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
VLCPlugin *_p_instance;
std::vector<FORMATETC> _v_formatEtc;
IDataAdviseHolder *_p_adviseHolder;
};
#endif
/*****************************************************************************
* guiddef.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2006 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __GUIDDEF_H__
#define __GUIDDEF_H__
/*
** Widl generated code requires guiddef.h,
** which is not available under MinGW
*/
#undef GUID_EXT
#define GUID_EXT
#include <initguid.h>
#endif
/*****************************************************************************
* main.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "utils.h"
#include <stdio.h>
#include <comcat.h>
#include <windows.h>
#include <shlwapi.h>
#include <tchar.h>
#include <guiddef.h>
using namespace std;
#define COMPANY_STR "VideoLAN"
#define PROGRAM_STR "VLCPlugin"
#define DESCRIPTION "VLC ActiveX Plugin and IE Web Plugin"
#define THREADING_MODEL "Apartment"
#define MISC_STATUS "131473"
#define PROGID_STR COMPANY_STR"."PROGRAM_STR
#define GUID_STRLEN 39
/*
** MingW headers & libs do not declare those
*/
static DEFINE_GUID(_CATID_InternetAware, \
0x0DE86A58, 0x2BAA, 0x11CF, 0xA2, 0x29, 0x00,0xAA,0x00,0x3D,0x73,0x52);
static DEFINE_GUID(_CATID_SafeForInitializing, \
0x7DD95802, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
static DEFINE_GUID(_CATID_SafeForScripting, \
0x7DD95801, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
static LONG i_class_ref= 0;
static HINSTANCE h_instance= 0;
HMODULE DllGetModule()
{
return h_instance;
};
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
*ppv = NULL;
if( (CLSID_VLCPlugin == rclsid) || (CLSID_VLCPlugin2 == rclsid) )
{
VLCPluginClass *plugin =
new VLCPluginClass(&i_class_ref, h_instance, rclsid);
hr = plugin->QueryInterface(riid, ppv);
plugin->Release();
}
return hr;
};
STDAPI DllCanUnloadNow(VOID)
{
return (0 == i_class_ref) ? S_OK: S_FALSE;
};
static inline HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)
{
HKEY childKey;
if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )
{
return childKey;
}
return NULL;
};
static inline HKEY keySet(HKEY hKey, LPCTSTR valueName,
const void *s, size_t len, DWORD dwType = REG_SZ)
{
if( NULL != hKey )
{
RegSetValueEx(hKey, valueName, 0, dwType, (const BYTE*)s, len);
}
return hKey;
};
static inline HKEY keySetDef(HKEY hKey,
const void *s, size_t len, DWORD dwType = REG_SZ)
{
return keySet(hKey, NULL, s, len, dwType);
};
static inline HKEY keySetDef(HKEY hKey, LPCTSTR s)
{
return keySetDef(hKey, s, sizeof(TCHAR)*(_tcslen(s)+1), REG_SZ);
};
static inline HKEY keyClose(HKEY hKey)
{
if( NULL != hKey )
{
RegCloseKey(hKey);
}
return NULL;
};
static void UnregisterProgID(REFCLSID rclsid, unsigned int version)
{
OLECHAR szCLSID[GUID_STRLEN];
StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);
TCHAR progId[sizeof(PROGID_STR)+16];
_stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);
SHDeleteKey(HKEY_CLASSES_ROOT, progId);
HKEY hClsIDKey;
if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_WRITE, &hClsIDKey) )
{
SHDeleteKey(hClsIDKey, szCLSID);
RegCloseKey(hClsIDKey);
}
};
STDAPI DllUnregisterServer(VOID)
{
// unregister type lib from the registry
UnRegisterTypeLib(LIBID_AXVLC, 1, 0, LOCALE_NEUTRAL, SYS_WIN32);
// remove component categories we supports
ICatRegister *pcr;
if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
CATID implCategories[] = {
CATID_Control,
CATID_PersistsToPropertyBag,
_CATID_InternetAware,
_CATID_SafeForInitializing,
_CATID_SafeForScripting,
};
pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin,
sizeof(implCategories)/sizeof(CATID), implCategories);
pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin2,
sizeof(implCategories)/sizeof(CATID), implCategories);
pcr->Release();
}
SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
UnregisterProgID(CLSID_VLCPlugin, 2);
UnregisterProgID(CLSID_VLCPlugin2, 1);
return S_OK;
};
static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int version, BOOL isDefault, LPCTSTR path, size_t pathLen)
{
TCHAR progId[sizeof(PROGID_STR)+16];
_stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);
TCHAR description[sizeof(DESCRIPTION)+16];
_stprintf(description, TEXT("%s v%u"), TEXT(DESCRIPTION), version);
HKEY hClassKey;
{
OLECHAR szCLSID[GUID_STRLEN];
StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);
HKEY hProgKey = keyCreate(HKEY_CLASSES_ROOT, progId);
if( NULL != hProgKey )
{
// default key value
keySetDef(hProgKey, description);
keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
szCLSID, sizeof(szCLSID)));
//hSubKey = keyClose(keyCreate(hBaseKey, "Insertable"));
RegCloseKey(hProgKey);
}
if( isDefault )
{
hProgKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
if( NULL != hProgKey )
{
// default key value
keySetDef(hProgKey, description);
keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
szCLSID, sizeof(szCLSID)));
keyClose(keySetDef(keyCreate(hProgKey, TEXT("CurVer")),
progId));
}
}
hClassKey = keyCreate(hParent, szCLSID);
}
if( NULL != hClassKey )
{
// default key value
keySetDef(hClassKey, description);
// Control key value
keyClose(keyCreate(hClassKey, TEXT("Control")));
// Insertable key value
//keyClose(keyCreate(hClassKey, TEXT("Insertable")));
// ToolboxBitmap32 key value
{
TCHAR iconPath[pathLen+3];
memcpy(iconPath, path, sizeof(TCHAR)*pathLen);
_tcscpy(iconPath+pathLen, TEXT(",1"));
keyClose(keySetDef(keyCreate(hClassKey,
TEXT("ToolboxBitmap32")),
iconPath, sizeof(iconPath)));
}
#ifdef BUILD_LOCALSERVER
// LocalServer32 key value
keyClose(keySetDef(keyCreate(hClassKey,
TEXT("LocalServer32"), path, sizeof(TCHAR)*(pathLen+1))));
#else
// InprocServer32 key value
{
HKEY hSubKey = keySetDef(keyCreate(hClassKey,
TEXT("InprocServer32")),
path, sizeof(TCHAR)*(pathLen+1));
keySet(hSubKey,
TEXT("ThreadingModel"),
TEXT(THREADING_MODEL), sizeof(TEXT(THREADING_MODEL)));
keyClose(hSubKey);
}
#endif
// MiscStatus key value
keyClose(keySetDef(keyCreate(hClassKey,TEXT("MiscStatus\\1")),
TEXT(MISC_STATUS), sizeof(TEXT(MISC_STATUS))));
// Programmable key value
keyClose(keyCreate(hClassKey, TEXT("Programmable")));
// ProgID key value
keyClose(keySetDef(keyCreate(hClassKey,TEXT("ProgID")),progId));
// VersionIndependentProgID key value
keyClose(keySetDef(keyCreate(hClassKey,
TEXT("VersionIndependentProgID")),
TEXT(PROGID_STR), sizeof(TEXT(PROGID_STR))));
// Version key value
keyClose(keySetDef(keyCreate(hClassKey,TEXT("Version")),TEXT("1.0")));
// TypeLib key value
OLECHAR szLIBID[GUID_STRLEN];
StringFromGUID2(LIBID_AXVLC, szLIBID, GUID_STRLEN);
keyClose(keySetDef(keyCreate(hClassKey,TEXT("TypeLib")),
szLIBID, sizeof(szLIBID)));
RegCloseKey(hClassKey);
}
return S_OK;
}
STDAPI DllRegisterServer(VOID)
{
DllUnregisterServer();
TCHAR DllPath[MAX_PATH];
DWORD DllPathLen=GetModuleFileName(h_instance, DllPath, MAX_PATH) ;
if( 0 == DllPathLen )
return E_UNEXPECTED;
DllPath[MAX_PATH-1] = '\0';
HKEY hBaseKey;
if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"),
0, KEY_CREATE_SUB_KEY, &hBaseKey) )
return SELFREG_E_CLASS;
RegisterClassID(hBaseKey, CLSID_VLCPlugin, 1, FALSE, DllPath, DllPathLen);
RegisterClassID(hBaseKey, CLSID_VLCPlugin2, 2, TRUE, DllPath, DllPathLen);
RegCloseKey(hBaseKey);
// indicate which component categories we support
ICatRegister *pcr;
if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
CATID implCategories[] = {
CATID_Control,
CATID_PersistsToPropertyBag,
_CATID_InternetAware,
_CATID_SafeForInitializing,
_CATID_SafeForScripting,
};
pcr->RegisterClassImplCategories(CLSID_VLCPlugin,
sizeof(implCategories)/sizeof(CATID), implCategories);
pcr->RegisterClassImplCategories(CLSID_VLCPlugin2,
sizeof(implCategories)/sizeof(CATID), implCategories);
pcr->Release();
}
#ifdef BUILD_LOCALSERVER
// replace .exe by .tlb
_tcscpy(DllPath+DllPathLen-4, TEXT(".tlb"));
#endif
// register type lib into the registry
ITypeLib *typeLib;
HRESULT result = LoadTypeLibEx(DllPath, REGKIND_REGISTER, &typeLib);
if( SUCCEEDED(result) )
typeLib->Release();
return result;
};
#ifdef BUILD_LOCALSERVER
/*
** easier to debug an application than a DLL on cygwin GDB :)
*/
#include <iostream>
STDAPI_(int) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
{
MSG msg;
if( FAILED(OleInitialize(NULL)) )
{
cerr << "cannot initialize OLE" << endl;
return 1;
}
h_instance = hInst;
if( FAILED(DllRegisterServer()) )
{
cerr << "cannot register Local Server" << endl;
return 1;
}
IUnknown *classProc = NULL;
if( FAILED(DllGetClassObject(CLSID_VLCPlugin, IID_IUnknown,
(LPVOID *)&classProc)) )
return 0;
DWORD dwRegisterClassObject;
DWORD dwRegisterClassObject2;
if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin, classProc,
CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegisterClassObject)) )
return 0;
DWORD dwRegisterActiveObject;
if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin,
ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )
return 0;
if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin2,
ACTIVEOBJECT_WEAK, &dwRegisterActiveObject2)) )
return 0;
classProc->Release();
/*
* Polling messages from event queue
*/
while( S_FALSE == DllCanUnloadNow() )
{
while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
{
if( msg.message == WM_QUIT )
break; // break out PeekMessage loop
/*if(TranslateAccelerator(ghwndApp, ghAccel, &msg))
continue;*/
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT)
break; // break out main loop
WaitMessage();
}
if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject, NULL)) )
CoRevokeClassObject(dwRegisterClassObject);
if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject2, NULL)) )
CoRevokeClassObject(dwRegisterClassObject2);
// Reached on WM_QUIT message
OleUninitialize();
return ((int) msg.wParam);
};
#else
STDAPI_(BOOL) DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved )
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
h_instance = (HINSTANCE)hModule;
break;
default:
break;
}
return TRUE;
};
#endif
/*****************************************************************************
* objectsafety.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005-2010 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "objectsafety.h"
#include "axvlc_idl.h"
#if 0
const GUID IID_IObjectSafety =
{0xCB5BDC81,0x93C1,0x11cf,{0x8F,0x20,0x00,0x80,0x5F,0x2C,0xD0,0x64}};
#endif
using namespace std;
STDMETHODIMP VLCObjectSafety::GetInterfaceSafetyOptions(
REFIID riid,
DWORD *pdwSupportedOptions,
DWORD *pdwEnabledOptions
)
{
if( (NULL == pdwSupportedOptions) || (NULL == pdwEnabledOptions) )
return E_POINTER;
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACESAFE_FOR_UNTRUSTED_CALLER;
if( (IID_IDispatch == riid)
|| (IID_IVLCControl == riid)
|| (IID_IVLCControl2 == riid) )
{
*pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
return NOERROR;
}
else if( (IID_IPersist == riid)
|| (IID_IPersistStreamInit == riid)
|| (IID_IPersistStorage == riid)
|| (IID_IPersistPropertyBag == riid) )
{
*pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
return NOERROR;
}
*pdwEnabledOptions = 0;
return E_NOINTERFACE;
};
STDMETHODIMP VLCObjectSafety::SetInterfaceSafetyOptions(
REFIID riid,
DWORD dwOptionSetMask,
DWORD dwEnabledOptions
)
{
if( (IID_IDispatch == riid)
|| (IID_IVLCControl == riid)
|| (IID_IVLCControl2 == riid) )
{
if( (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwOptionSetMask)
&& (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwEnabledOptions) )
{
return NOERROR;
}
return E_FAIL;
}
else if( (IID_IPersist == riid)
|| (IID_IPersistStreamInit == riid)
|| (IID_IPersistStorage == riid)
|| (IID_IPersistPropertyBag == riid) )
{
if( (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwOptionSetMask)
&& (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwEnabledOptions) )
{
return NOERROR;
}
return E_FAIL;
}
return E_FAIL;
};
/*****************************************************************************
* objectsafety.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __OBJECTSAFETY_H__
#define __OBJECTSAFETY_H__
#if HAVE_OBJSAFE_HEADER
/*
** at last, a version of mingw that supports this header
*/
#include <objsafe.h>
#else
/*
** mingw does not yet support objsafe.h, redefine what we need here
*/
// {CB5BDC81-93C1-11cf-8F20-00805F2CD064}
extern "C" const IID IID_IObjectSafety;
#define INTERFACESAFE_FOR_UNTRUSTED_CALLER 1L
#define INTERFACESAFE_FOR_UNTRUSTED_DATA 2L
struct IObjectSafety : public IUnknown
{
virtual STDMETHODIMP GetInterfaceSafetyOptions(
REFIID riid,
DWORD __RPC_FAR *pdwSupportedOptions,
DWORD __RPC_FAR *pdwEnabledOptions
) = 0;
virtual STDMETHODIMP SetInterfaceSafetyOptions(
REFIID riid,
DWORD dwSupportedOptions,
DWORD dwOptionSetMask
) = 0;
};
#endif
class VLCObjectSafety : public IObjectSafety
{
public:
VLCObjectSafety(VLCPlugin *p_instance) : _p_instance(p_instance) {};
virtual ~VLCObjectSafety() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv)
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IObjectSafety == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IUnknown methods
STDMETHODIMP GetInterfaceSafetyOptions(
REFIID riid,
DWORD *pdwSupportedOptions,
DWORD *pdwEnabledOptions
);
STDMETHODIMP SetInterfaceSafetyOptions(
REFIID riid,
DWORD dwOptionSetMask,
DWORD dwEnabledOptions
);
private:
VLCPlugin *_p_instance;
};
#endif
/*****************************************************************************
* olecontrol.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "olecontrol.h"
using namespace std;
STDMETHODIMP VLCOleControl::GetControlInfo(CONTROLINFO *pCI)
{
if( NULL == pCI )
return E_POINTER;
pCI->cb = sizeof(CONTROLINFO);
pCI->hAccel = NULL;
pCI->cAccel = 0;
pCI->dwFlags = 0;
return S_OK;
};
STDMETHODIMP VLCOleControl::OnMnemonic(LPMSG pMsg)
{
return S_OK;
};
STDMETHODIMP VLCOleControl::OnAmbientPropertyChange(DISPID dispID)
{
HRESULT hr;
LPOLEOBJECT oleObj;
hr = QueryInterface(IID_IOleObject, (LPVOID *)&oleObj);
if( SUCCEEDED(hr) )
{
LPOLECLIENTSITE clientSite;
hr = oleObj->GetClientSite(&clientSite);
if( SUCCEEDED(hr) && (NULL != clientSite) )
{
_p_instance->onAmbientChanged(clientSite, dispID);
clientSite->Release();
}
oleObj->Release();
}
return S_OK;
};
STDMETHODIMP VLCOleControl::FreezeEvents(BOOL bFreeze)
{
_p_instance->freezeEvents(bFreeze);
return S_OK;
};
/*****************************************************************************
* olecontrol.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __OLECONTROL_H__
#define __OLECONTROL_H__
#include <olectl.h>
class VLCOleControl : public IOleControl
{
public:
VLCOleControl(VLCPlugin *p_instance) : _p_instance(p_instance) {};
virtual ~VLCOleControl() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IOleControl == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleControl methods
STDMETHODIMP GetControlInfo(CONTROLINFO *pCI);
STDMETHODIMP OnMnemonic(LPMSG pMsg);
STDMETHODIMP OnAmbientPropertyChange(DISPID dispID);
STDMETHODIMP FreezeEvents(BOOL bFreeze);
private:
VLCPlugin *_p_instance;
};
#endif
/*****************************************************************************
* oleinplaceactiveobject.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "oleinplaceactiveobject.h"
using namespace std;
STDMETHODIMP VLCOleInPlaceActiveObject::GetWindow(HWND *pHwnd)
{
if( NULL == pHwnd )
return E_POINTER;
*pHwnd = NULL;
if( _p_instance->isInPlaceActive() )
{
if( NULL != (*pHwnd = _p_instance->getInPlaceWindow()) )
return S_OK;
}
return E_FAIL;
};
STDMETHODIMP VLCOleInPlaceActiveObject::EnableModeless(BOOL fEnable)
{
return S_OK;
};
STDMETHODIMP VLCOleInPlaceActiveObject::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
};
STDMETHODIMP VLCOleInPlaceActiveObject::TranslateAccelerator(LPMSG lpmsg)
{
HRESULT hr = S_FALSE;
LPOLEOBJECT oleObj;
if( SUCCEEDED(QueryInterface(IID_IOleObject, (LPVOID *)&oleObj)) )
{
LPOLECLIENTSITE clientSite;
if( SUCCEEDED(oleObj->GetClientSite(&clientSite)) && (NULL != clientSite) )
{
IOleControlSite *controlSite;
if( SUCCEEDED(clientSite->QueryInterface(IID_IOleControlSite, (LPVOID *)&controlSite)) )
{
hr = controlSite->TranslateAccelerator(lpmsg,
((GetKeyState(VK_SHIFT) >> 15) & 1) |
((GetKeyState(VK_CONTROL) >> 14) & 2) |
((GetKeyState(VK_MENU) >> 13) & 4) );
controlSite->Release();
}
clientSite->Release();
}
oleObj->Release();
}
return hr;
};
STDMETHODIMP VLCOleInPlaceActiveObject::OnFrameWindowActivate(BOOL fActivate)
{
return S_OK;
};
STDMETHODIMP VLCOleInPlaceActiveObject::OnDocWindowActivate(BOOL fActivate)
{
return S_OK;
};
STDMETHODIMP VLCOleInPlaceActiveObject::ResizeBorder(LPCRECT prcBorder, LPOLEINPLACEUIWINDOW pUIWindow, BOOL fFrameWindow)
{
return S_OK;
};
/*****************************************************************************
* oleinplaceactiveobject.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __OLEINPLACEACTIVEOBJECT_H__
#define __OLEINPLACEACTIVEOBJECT_H__
#include "oleidl.h"
class VLCOleInPlaceActiveObject : public IOleInPlaceActiveObject
{
public:
VLCOleInPlaceActiveObject(VLCPlugin *p_instance) : _p_instance(p_instance) {};
virtual ~VLCOleInPlaceActiveObject() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IOleWindow == riid)
|| (IID_IOleInPlaceActiveObject == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleWindow methods
STDMETHODIMP GetWindow(HWND *);
STDMETHODIMP ContextSensitiveHelp(BOOL);
// IOleInPlaceActiveObject methods
STDMETHODIMP EnableModeless(BOOL);
STDMETHODIMP TranslateAccelerator(LPMSG);
STDMETHODIMP OnFrameWindowActivate(BOOL);
STDMETHODIMP OnDocWindowActivate(BOOL);
STDMETHODIMP ResizeBorder(LPCRECT, LPOLEINPLACEUIWINDOW, BOOL);
private:
VLCPlugin *_p_instance;
};
#endif
/*****************************************************************************
* oleinplaceobject.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "oleinplaceobject.h"
#include <docobj.h>
using namespace std;
STDMETHODIMP VLCOleInPlaceObject::GetWindow(HWND *pHwnd)
{
if( NULL == pHwnd )
return E_POINTER;
*pHwnd = NULL;
if( _p_instance->isInPlaceActive() )
{
if( NULL != (*pHwnd = _p_instance->getInPlaceWindow()) )
return S_OK;
}
return E_FAIL;
};
STDMETHODIMP VLCOleInPlaceObject::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
};
STDMETHODIMP VLCOleInPlaceObject::InPlaceDeactivate(void)
{
if( _p_instance->isInPlaceActive() )
{
UIDeactivate();
_p_instance->onInPlaceDeactivate();
LPOLEOBJECT p_oleObject;
if( SUCCEEDED(QueryInterface(IID_IOleObject, (void**)&p_oleObject)) )
{
LPOLECLIENTSITE p_clientSite;
if( SUCCEEDED(p_oleObject->GetClientSite(&p_clientSite)) )
{
LPOLEINPLACESITE p_inPlaceSite;
if( SUCCEEDED(p_clientSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
{
p_inPlaceSite->OnInPlaceDeactivate();
p_inPlaceSite->Release();
}
p_clientSite->Release();
}
p_oleObject->Release();
}
return S_OK;
}
return E_UNEXPECTED;
};
STDMETHODIMP VLCOleInPlaceObject::UIDeactivate(void)
{
if( _p_instance->isInPlaceActive() )
{
if( _p_instance->hasFocus() )
_p_instance->setFocus(FALSE);
LPOLEOBJECT p_oleObject;
if( SUCCEEDED(QueryInterface(IID_IOleObject, (void**)&p_oleObject)) )
{
LPOLECLIENTSITE p_clientSite;
if( SUCCEEDED(p_oleObject->GetClientSite(&p_clientSite)) )
{
LPOLEINPLACESITE p_inPlaceSite;
if( SUCCEEDED(p_clientSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
{
LPOLEINPLACEFRAME p_inPlaceFrame;
LPOLEINPLACEUIWINDOW p_inPlaceUIWindow;
OLEINPLACEFRAMEINFO oleFrameInfo;
RECT posRect, clipRect;
oleFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
if( SUCCEEDED(p_inPlaceSite->GetWindowContext(&p_inPlaceFrame, &p_inPlaceUIWindow, &posRect, &clipRect, &oleFrameInfo)) )
{
if( p_inPlaceFrame )
{
p_inPlaceFrame->SetActiveObject(NULL, NULL);
p_inPlaceFrame->Release();
}
if( p_inPlaceUIWindow )
{
p_inPlaceUIWindow->SetActiveObject(NULL, NULL);
p_inPlaceUIWindow->Release();
}
}
p_inPlaceSite->OnUIDeactivate(FALSE);
p_inPlaceSite->Release();
}
p_clientSite->Release();
}
p_oleObject->Release();
}
return S_OK;
}
return E_UNEXPECTED;
};
STDMETHODIMP VLCOleInPlaceObject::SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
{
if( _p_instance->isInPlaceActive() )
{
_p_instance->onPositionChange(lprcPosRect, lprcClipRect);
return S_OK;
}
return E_UNEXPECTED;
};
STDMETHODIMP VLCOleInPlaceObject::ReactivateAndUndo(void)
{
return INPLACE_E_NOTUNDOABLE;
};
/*****************************************************************************
* oleinplaceobject.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __OLEINPLACEOBJECT_H__
#define __OLEINPLACEOBJECT_H__
class VLCOleInPlaceObject : public IOleInPlaceObject
{
public:
VLCOleInPlaceObject(VLCPlugin *p_instance) : _p_instance(p_instance) {};
virtual ~VLCOleInPlaceObject() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IOleWindow == riid)
|| (IID_IOleInPlaceObject == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleWindow methods
STDMETHODIMP GetWindow(HWND *);
STDMETHODIMP ContextSensitiveHelp(BOOL);
// IOleInPlaceObject methods
STDMETHODIMP InPlaceDeactivate(void);
STDMETHODIMP UIDeactivate(void);
STDMETHODIMP SetObjectRects(LPCRECT, LPCRECT);
STDMETHODIMP ReactivateAndUndo(void);
private:
VLCPlugin *_p_instance;
};
#endif
/*****************************************************************************
* oleobject.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "oleobject.h"
#include "utils.h"
#include <docobj.h>
using namespace std;
VLCOleObject::VLCOleObject(VLCPlugin *p_instance) :
_p_clientsite(NULL), _p_instance(p_instance)
{
CreateOleAdviseHolder(&_p_advise_holder);
};
VLCOleObject::~VLCOleObject()
{
SetClientSite(NULL);
Close(OLECLOSE_NOSAVE);
_p_advise_holder->Release();
};
STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection)
{
return _p_advise_holder->Advise(pAdvSink, dwConnection);
};
STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption)
{
if( _p_instance->isRunning() )
{
_p_advise_holder->SendOnClose();
return _p_instance->onClose(dwSaveOption);
}
return S_OK;
};
STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActiveSite,
LONG lIndex, HWND hwndParent, LPCRECT lprcPosRect)
{
switch( iVerb )
{
case OLEIVERB_PRIMARY:
case OLEIVERB_SHOW:
case OLEIVERB_OPEN:
// force control to be visible when activating in place
_p_instance->setVisible(TRUE);
return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, TRUE);
case OLEIVERB_INPLACEACTIVATE:
return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, FALSE);
case OLEIVERB_HIDE:
_p_instance->setVisible(FALSE);
return S_OK;
case OLEIVERB_UIACTIVATE:
// UI activate only if visible
if( _p_instance->isVisible() )
return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, TRUE);
return OLEOBJ_S_CANNOT_DOVERB_NOW;
case OLEIVERB_DISCARDUNDOSTATE:
return S_OK;
default:
if( iVerb > 0 ) {
_p_instance->setVisible(TRUE);
doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, TRUE);
return OLEOBJ_S_INVALIDVERB;
}
return E_NOTIMPL;
}
};
HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect, BOOL uiActivate)
{
RECT posRect;
RECT clipRect;
LPCRECT lprcClipRect = lprcPosRect;
if( pActiveSite )
{
LPOLEINPLACESITE p_inPlaceSite;
IOleInPlaceSiteEx *p_inPlaceSiteEx;
LPOLEINPLACEFRAME p_inPlaceFrame;
LPOLEINPLACEUIWINDOW p_inPlaceUIWindow;
if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSiteEx, reinterpret_cast<void**>(&p_inPlaceSiteEx))) )
{
p_inPlaceSite = p_inPlaceSiteEx;
p_inPlaceSite->AddRef();
}
else if FAILED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, reinterpret_cast<void**>(&p_inPlaceSite)) )
{
p_inPlaceSite = p_inPlaceSiteEx = NULL;
}
if( p_inPlaceSite )
{
OLEINPLACEFRAMEINFO oleFrameInfo;
oleFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
if( SUCCEEDED(p_inPlaceSite->GetWindowContext(&p_inPlaceFrame, &p_inPlaceUIWindow, &posRect, &clipRect, &oleFrameInfo)) )
{
lprcPosRect = &posRect;
lprcClipRect = &clipRect;
}
if( (NULL == hwndParent) && FAILED(p_inPlaceSite->GetWindow(&hwndParent)) )
{
p_inPlaceSite->Release();
if( p_inPlaceSiteEx )
p_inPlaceSiteEx->Release();
if( p_inPlaceFrame )
p_inPlaceFrame->Release();
if( p_inPlaceUIWindow )
p_inPlaceUIWindow->Release();
return OLEOBJ_S_INVALIDHWND;
}
}
else if( NULL == hwndParent )
{
return OLEOBJ_S_INVALIDHWND;
}
else if( NULL == lprcPosRect )
{
SetRect(&posRect, 0, 0, 0, 0);
lprcPosRect = &posRect;
lprcClipRect = &posRect;
}
// check if not already activated
if( ! _p_instance->isInPlaceActive() )
{
if( ((NULL == p_inPlaceSite) || (S_OK == p_inPlaceSite->CanInPlaceActivate()))
&& SUCCEEDED(_p_instance->onActivateInPlace(lpMsg, hwndParent, lprcPosRect, lprcClipRect)) )
{
if( p_inPlaceSiteEx )
{
BOOL needsRedraw;
p_inPlaceSiteEx->OnInPlaceActivateEx(&needsRedraw, 0);
}
else if( p_inPlaceSite )
p_inPlaceSite->OnInPlaceActivate();
}
else
{
if( p_inPlaceSite )
{
p_inPlaceSite->Release();
if( p_inPlaceSiteEx )
p_inPlaceSiteEx->Release();
if( p_inPlaceFrame )
p_inPlaceFrame->Release();
if( p_inPlaceUIWindow )
p_inPlaceUIWindow->Release();
}
return OLEOBJ_S_CANNOT_DOVERB_NOW;
}
}
if( p_inPlaceSite )
p_inPlaceSite->OnPosRectChange(lprcPosRect);
if( uiActivate )
{
if( (NULL == p_inPlaceSiteEx) || (S_OK == p_inPlaceSiteEx->RequestUIActivate()) )
{
if( p_inPlaceSite)
{
p_inPlaceSite->OnUIActivate();
LPOLEINPLACEACTIVEOBJECT p_inPlaceActiveObject;
if( SUCCEEDED(QueryInterface(IID_IOleInPlaceActiveObject, reinterpret_cast<void**>(&p_inPlaceActiveObject))) )
{
if( p_inPlaceFrame )
p_inPlaceFrame->SetActiveObject(p_inPlaceActiveObject, NULL);
if( p_inPlaceUIWindow )
p_inPlaceUIWindow->SetActiveObject(p_inPlaceActiveObject, NULL);
p_inPlaceActiveObject->Release();
}
if( p_inPlaceFrame )
p_inPlaceFrame->RequestBorderSpace(NULL);
pActiveSite->ShowObject();
}
_p_instance->setFocus(TRUE);
}
}
if( p_inPlaceSite )
{
p_inPlaceSite->Release();
if( p_inPlaceSiteEx )
p_inPlaceSiteEx->Release();
if( p_inPlaceFrame )
p_inPlaceFrame->Release();
if( p_inPlaceUIWindow )
p_inPlaceUIWindow->Release();
}
return S_OK;
}
return OLEOBJ_S_CANNOT_DOVERB_NOW;
};
STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise)
{
return _p_advise_holder->EnumAdvise(ppEnumAdvise);
};
STDMETHODIMP VLCOleObject::EnumVerbs(IEnumOleVerb **ppEnumOleVerb)
{
return OleRegEnumVerbs(_p_instance->getClassID(),
ppEnumOleVerb);
};
STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)
{
if( NULL == ppClientSite )
return E_POINTER;
if( NULL != _p_clientsite )
_p_clientsite->AddRef();
*ppClientSite = _p_clientsite;
return S_OK;
};
STDMETHODIMP VLCOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject)
{
return _p_instance->pUnkOuter->QueryInterface(IID_IDataObject, (void **)ppDataObject);
};
STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
{
if( NULL == pSizel )
return E_POINTER;
if( dwDrawAspect & DVASPECT_CONTENT )
{
*pSizel = _p_instance->getExtent();
return S_OK;
}
pSizel->cx= 0L;
pSizel->cy= 0L;
return E_NOTIMPL;
};
STDMETHODIMP VLCOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
{
if( NULL == pdwStatus )
return E_POINTER;
switch( dwAspect )
{
case DVASPECT_CONTENT:
*pdwStatus = OLEMISC_RECOMPOSEONRESIZE
| OLEMISC_CANTLINKINSIDE
| OLEMISC_INSIDEOUT
| OLEMISC_ACTIVATEWHENVISIBLE
| OLEMISC_SETCLIENTSITEFIRST;
break;
default:
*pdwStatus = 0;
}
return S_OK;
};
STDMETHODIMP VLCOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER *ppMoniker)
{
if( NULL != _p_clientsite )
return _p_clientsite->GetMoniker(dwAssign,dwWhichMoniker, ppMoniker);
return E_UNEXPECTED;
};
STDMETHODIMP VLCOleObject::GetUserClassID(LPCLSID pClsid)
{
if( NULL == pClsid )
return E_POINTER;
*pClsid = _p_instance->getClassID();
return S_OK;
};
STDMETHODIMP VLCOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
{
return OleRegGetUserType(_p_instance->getClassID(),
dwFormOfType, pszUserType);
};
STDMETHODIMP VLCOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved)
{
return E_NOTIMPL;
};
STDMETHODIMP VLCOleObject::IsUpToDate(void)
{
return S_OK;
};
STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)
{
if( NULL != _p_clientsite )
_p_clientsite->Release();
_p_clientsite = pClientSite;
if( NULL != pClientSite )
{
pClientSite->AddRef();
_p_instance->onAmbientChanged(pClientSite, DISPID_UNKNOWN);
}
return S_OK;
};
STDMETHODIMP VLCOleObject::SetColorScheme(LOGPALETTE *pLogpal)
{
return E_NOTIMPL;
};
STDMETHODIMP VLCOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
{
if( NULL == pSizel )
return E_POINTER;
if( dwDrawAspect & DVASPECT_CONTENT )
{
_p_instance->setExtent(*pSizel);
if( _p_instance->isInPlaceActive() )
{
LPOLEINPLACESITE p_inPlaceSite;
if( SUCCEEDED(_p_clientsite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
{
HWND hwnd;
if( SUCCEEDED(p_inPlaceSite->GetWindow(&hwnd)) )
{
// use HIMETRIC to pixel transform
RECT posRect = _p_instance->getPosRect();
HDC hDC = GetDC(hwnd);
posRect.right = (pSizel->cx*GetDeviceCaps(hDC, LOGPIXELSX)/2540L)+posRect.left;
posRect.bottom = (pSizel->cy*GetDeviceCaps(hDC, LOGPIXELSY)/2540L)+posRect.top;
DeleteDC(hDC);
p_inPlaceSite->OnPosRectChange(&posRect);
}
p_inPlaceSite->Release();
}
}
return S_OK;
}
return E_NOTIMPL;
};
STDMETHODIMP VLCOleObject::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
{
return S_OK;
};
STDMETHODIMP VLCOleObject::SetMoniker(DWORD dwWhichMoniker, LPMONIKER pMoniker)
{
return _p_advise_holder->SendOnRename(pMoniker);
};
STDMETHODIMP VLCOleObject::Unadvise(DWORD dwConnection)
{
return _p_advise_holder->Unadvise(dwConnection);
};
STDMETHODIMP VLCOleObject::Update(void)
{
return S_OK;
};
/*****************************************************************************
* oleobject.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __OLEOBJECT_H__
#define __OLEOBJECT_H__
class VLCOleObject : public IOleObject
{
public:
VLCOleObject(VLCPlugin *p_instance);
virtual ~VLCOleObject();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IOleObject == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleObject methods
STDMETHODIMP Advise(IAdviseSink *, LPDWORD);
STDMETHODIMP Close(DWORD);
STDMETHODIMP DoVerb(LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND, LPCRECT);
STDMETHODIMP EnumAdvise(IEnumSTATDATA **);
STDMETHODIMP EnumVerbs(IEnumOleVerb **);
STDMETHODIMP GetClientSite(LPOLECLIENTSITE *);
STDMETHODIMP GetClipboardData(DWORD, LPDATAOBJECT *);
STDMETHODIMP GetExtent(DWORD, SIZEL *);
STDMETHODIMP GetMiscStatus(DWORD, DWORD *);
STDMETHODIMP GetMoniker(DWORD, DWORD, LPMONIKER *);
STDMETHODIMP GetUserClassID(CLSID *);
STDMETHODIMP GetUserType(DWORD, LPOLESTR *);
STDMETHODIMP InitFromData(IDataObject *, BOOL, DWORD);
STDMETHODIMP IsUpToDate(void);
STDMETHODIMP SetClientSite(LPOLECLIENTSITE);
STDMETHODIMP SetColorScheme(LOGPALETTE *);
STDMETHODIMP SetExtent(DWORD, SIZEL *);
STDMETHODIMP SetHostNames(LPCOLESTR, LPCOLESTR) ;
STDMETHODIMP SetMoniker(DWORD, LPMONIKER);
STDMETHODIMP Unadvise(DWORD);
STDMETHODIMP Update(void);
private:
HRESULT doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect, BOOL uiActivate);
IOleAdviseHolder *_p_advise_holder;
IOleClientSite *_p_clientsite;
VLCPlugin *_p_instance;
};
#endif
/*****************************************************************************
* persistpropbag.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "persistpropbag.h"
#include "utils.h"
#include "oleobject.h"
using namespace std;
STDMETHODIMP VLCPersistPropertyBag::GetClassID(LPCLSID pClsID)
{
if( NULL == pClsID )
return E_POINTER;
*pClsID = _p_instance->getClassID();
return S_OK;
};
STDMETHODIMP VLCPersistPropertyBag::InitNew(void)
{
return _p_instance->onInit();
};
STDMETHODIMP VLCPersistPropertyBag::Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog)
{
HRESULT hr = _p_instance->onInit();
if( FAILED(hr) )
return hr;
if( NULL == pPropBag )
return E_INVALIDARG;
VARIANT value;
V_VT(&value) = VT_BSTR;
if( S_OK == pPropBag->Read(OLESTR("mrl"), &value, pErrorLog) )
{
_p_instance->setMRL(V_BSTR(&value));
VariantClear(&value);
}
else
{
/*
** try alternative syntax
*/
V_VT(&value) = VT_BSTR;
if( S_OK == pPropBag->Read(OLESTR("src"), &value, pErrorLog) )
{
_p_instance->setMRL(V_BSTR(&value));
VariantClear(&value);
}
else
{
V_VT(&value) = VT_BSTR;
if( S_OK == pPropBag->Read(OLESTR("filename"), &value, pErrorLog) )
{
_p_instance->setMRL(V_BSTR(&value));
VariantClear(&value);
}
}
}
V_VT(&value) = VT_BOOL;
if( S_OK == pPropBag->Read(OLESTR("autoplay"), &value, pErrorLog) )
{
_p_instance->setAutoPlay(V_BOOL(&value) != VARIANT_FALSE);
VariantClear(&value);
}
else
{
/*
** try alternative syntax
*/
V_VT(&value) = VT_BOOL;
if( S_OK == pPropBag->Read(OLESTR("autostart"), &value, pErrorLog) )
{
_p_instance->setAutoPlay(V_BOOL(&value) != VARIANT_FALSE);
VariantClear(&value);
}
}
V_VT(&value) = VT_BOOL;
if( S_OK == pPropBag->Read(OLESTR("toolbar"), &value, pErrorLog) )
{
_p_instance->setShowToolbar(V_BOOL(&value) != VARIANT_FALSE);
VariantClear(&value);
}
SIZEL size = _p_instance->getExtent();
V_VT(&value) = VT_I4;
if( S_OK == pPropBag->Read(OLESTR("extentwidth"), &value, pErrorLog) )
{
size.cx = V_I4(&value);
VariantClear(&value);
}
V_VT(&value) = VT_I4;
if( S_OK == pPropBag->Read(OLESTR("extentheight"), &value, pErrorLog) )
{
size.cy = V_I4(&value);
VariantClear(&value);
}
_p_instance->setExtent(size);
V_VT(&value) = VT_BOOL;
if( S_OK == pPropBag->Read(OLESTR("autoloop"), &value, pErrorLog) )
{
_p_instance->setAutoLoop(V_BOOL(&value) != VARIANT_FALSE);
VariantClear(&value);
}
else
{
/*
** try alternative syntax
*/
V_VT(&value) = VT_BOOL;
if( S_OK == pPropBag->Read(OLESTR("loop"), &value, pErrorLog) )
{
_p_instance->setAutoLoop(V_BOOL(&value) != VARIANT_FALSE);
VariantClear(&value);
}
}
V_VT(&value) = VT_BOOL;
if( S_OK == pPropBag->Read(OLESTR("mute"), &value, pErrorLog) )
{
_p_instance->setMute(V_BOOL(&value) != VARIANT_FALSE);
VariantClear(&value);
}
V_VT(&value) = VT_BOOL;
if( S_OK == pPropBag->Read(OLESTR("visible"), &value, pErrorLog) )
{
_p_instance->setVisible(V_BOOL(&value) != VARIANT_FALSE);
VariantClear(&value);
}
else
{
/*
** try alternative syntax
*/
V_VT(&value) = VT_BOOL;
if( S_OK == pPropBag->Read(OLESTR("showdisplay"), &value, pErrorLog) )
{
_p_instance->setVisible(V_BOOL(&value) != VARIANT_FALSE);
VariantClear(&value);
}
}
V_VT(&value) = VT_I4;
if( S_OK == pPropBag->Read(OLESTR("volume"), &value, pErrorLog) )
{
_p_instance->setVolume(V_I4(&value));
VariantClear(&value);
}
V_VT(&value) = VT_I4;
if( S_OK == pPropBag->Read(OLESTR("starttime"), &value, pErrorLog) )
{
_p_instance->setStartTime(V_I4(&value));
VariantClear(&value);
}
V_VT(&value) = VT_BSTR;
if( S_OK == pPropBag->Read(OLESTR("baseurl"), &value, pErrorLog) )
{
_p_instance->setBaseURL(V_BSTR(&value));
VariantClear(&value);
}
V_VT(&value) = VT_I4;
if( S_OK == pPropBag->Read(OLESTR("backcolor"), &value, pErrorLog) )
{
_p_instance->setBackColor(V_I4(&value));
VariantClear(&value);
}
else
{
/*
** try alternative syntax
*/
V_VT(&value) = VT_BSTR;
if( S_OK == pPropBag->Read(OLESTR("bgcolor"), &value, pErrorLog) )
{
long backcolor;
if( swscanf(V_BSTR(&value), L"#%lX", &backcolor) )
{
_p_instance->setBackColor(backcolor);
}
VariantClear(&value);
}
}
return _p_instance->onLoad();
};
STDMETHODIMP VLCPersistPropertyBag::Save(LPPROPERTYBAG pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
{
if( NULL == pPropBag )
return E_INVALIDARG;
VARIANT value;
VariantInit(&value);
V_VT(&value) = VT_BOOL;
V_BOOL(&value) = _p_instance->getAutoLoop()? VARIANT_TRUE : VARIANT_FALSE;
pPropBag->Write(OLESTR("AutoLoop"), &value);
VariantClear(&value);
V_VT(&value) = VT_BOOL;
V_BOOL(&value) = _p_instance->getAutoPlay()? VARIANT_TRUE : VARIANT_FALSE;
pPropBag->Write(OLESTR("AutoPlay"), &value);
VariantClear(&value);
V_VT(&value) = VT_BOOL;
V_BOOL(&value) = _p_instance->getShowToolbar()? VARIANT_TRUE : VARIANT_FALSE;
pPropBag->Write(OLESTR("Toolbar"), &value);
VariantClear(&value);
SIZEL size = _p_instance->getExtent();
V_VT(&value) = VT_I4;
V_I4(&value) = size.cx;
pPropBag->Write(OLESTR("ExtentWidth"), &value);
V_I4(&value) = size.cy;
pPropBag->Write(OLESTR("ExtentHeight"), &value);
V_VT(&value) = VT_BSTR;
V_BSTR(&value) = SysAllocStringLen(_p_instance->getMRL(),
SysStringLen(_p_instance->getMRL()));
pPropBag->Write(OLESTR("MRL"), &value);
VariantClear(&value);
V_VT(&value) = VT_BOOL;
V_BOOL(&value) = _p_instance->getVisible()? VARIANT_TRUE : VARIANT_FALSE;
pPropBag->Write(OLESTR("Visible"), &value);
VariantClear(&value);
V_VT(&value) = VT_I4;
V_I4(&value) = _p_instance->getVolume();
pPropBag->Write(OLESTR("Volume"), &value);
VariantClear(&value);
V_VT(&value) = VT_I4;
V_I4(&value) = _p_instance->getStartTime();
pPropBag->Write(OLESTR("StartTime"), &value);
VariantClear(&value);
V_VT(&value) = VT_BSTR;
V_BSTR(&value) = SysAllocStringLen(_p_instance->getBaseURL(),
SysStringLen(_p_instance->getBaseURL()));
pPropBag->Write(OLESTR("BaseURL"), &value);
VariantClear(&value);
V_VT(&value) = VT_I4;
V_I4(&value) = _p_instance->getBackColor();
pPropBag->Write(OLESTR("BackColor"), &value);
VariantClear(&value);
if( fClearDirty )
_p_instance->setDirty(FALSE);
return S_OK;
};
/*****************************************************************************
* persistpropbag.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __PERSISTPROPBAG_H__
#define __PERSISTPROPBAG_H__
#include <stdio.h>
#include <ocidl.h>
class VLCPersistPropertyBag : public IPersistPropertyBag
{
public:
VLCPersistPropertyBag(VLCPlugin *p_instance) : _p_instance(p_instance) {};
virtual ~VLCPersistPropertyBag() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IPersist == riid)
|| (IID_IPersistPropertyBag == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IPersist methods
STDMETHODIMP GetClassID(LPCLSID);
// IPersistPropertyBag methods
STDMETHODIMP InitNew(void);
STDMETHODIMP Load(LPPROPERTYBAG, LPERRORLOG);
STDMETHODIMP Save(LPPROPERTYBAG, BOOL, BOOL);
private:
VLCPlugin *_p_instance;
};
#endif
/*****************************************************************************
* persiststorage.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "persiststorage.h"
using namespace std;
STDMETHODIMP VLCPersistStorage::GetClassID(LPCLSID pClsID)
{
if( NULL == pClsID )
return E_POINTER;
*pClsID = _p_instance->getClassID();
return S_OK;
};
STDMETHODIMP VLCPersistStorage::IsDirty(void)
{
return _p_instance->isDirty() ? S_OK : S_FALSE;
};
STDMETHODIMP VLCPersistStorage::InitNew(LPSTORAGE pStg)
{
return _p_instance->onInit();
};
STDMETHODIMP VLCPersistStorage::Load(LPSTORAGE pStg)
{
if( NULL == pStg )
return E_INVALIDARG;
LPSTREAM pStm = NULL;
HRESULT result = pStg->OpenStream(L"VideoLAN ActiveX Plugin Data", NULL,
STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &pStm);
if( FAILED(result) )
return result;
LPPERSISTSTREAMINIT pPersistStreamInit;
if( SUCCEEDED(QueryInterface(IID_IPersistStreamInit, (void **)&pPersistStreamInit)) )
{
result = pPersistStreamInit->Load(pStm);
pPersistStreamInit->Release();
}
pStm->Release();
return result;
};
STDMETHODIMP VLCPersistStorage::Save(LPSTORAGE pStg, BOOL fSameAsLoad)
{
if( NULL == pStg )
return E_INVALIDARG;
if( fSameAsLoad && (S_FALSE == IsDirty()) )
return S_OK;
LPSTREAM pStm = NULL;
HRESULT result = pStg->CreateStream(L"VideoLAN ActiveX Plugin Data",
STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &pStm);
if( FAILED(result) )
return result;
LPPERSISTSTREAMINIT pPersistStreamInit;
if( SUCCEEDED(QueryInterface(IID_IPersistStreamInit, (void **)&pPersistStreamInit)) )
{
result = pPersistStreamInit->Save(pStm, fSameAsLoad);
pPersistStreamInit->Release();
}
pStm->Release();
return result;
};
STDMETHODIMP VLCPersistStorage::SaveCompleted(IStorage *pStg)
{
return S_OK;
};
STDMETHODIMP VLCPersistStorage::HandsOffStorage(void)
{
return S_OK;
};
/*****************************************************************************
* persiststorage.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __PERSISTSTORAGE_H__
#define __PERSISTSTORAGE_H__
#include <ocidl.h>
class VLCPersistStorage : public IPersistStorage
{
public:
VLCPersistStorage(VLCPlugin *p_instance) : _p_instance(p_instance) {};
virtual ~VLCPersistStorage() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IPersist == riid)
|| (IID_IPersistStorage == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IPersist methods
STDMETHODIMP GetClassID(LPCLSID);
// IPersistStorage methods
STDMETHODIMP IsDirty(void);
STDMETHODIMP InitNew(IStorage *);
STDMETHODIMP Load(IStorage *);
STDMETHODIMP Save(IStorage *, BOOL);
STDMETHODIMP SaveCompleted(IStorage *);
STDMETHODIMP HandsOffStorage(void);
private:
VLCPlugin *_p_instance;
};
#endif
/*****************************************************************************
* persiststreaminit.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "persiststreaminit.h"
#include "utils.h"
#include <map>
#include <malloc.h>
#include <wchar.h>
using namespace std;
class AxVLCVariant
{
public:
AxVLCVariant(void)
{
VariantInit(&_v);
};
~AxVLCVariant(void)
{
VariantClear(&_v);
}
AxVLCVariant(VARIANTARG &v)
{
VariantInit(&_v);
VariantCopy(&_v, &v);
};
AxVLCVariant(VARIANTARG *v)
{
VariantInit(&_v);
VariantCopy(&_v, v);
};
AxVLCVariant(const AxVLCVariant &vv)
{
VariantInit(&_v);
VariantCopy(&_v, const_cast<VARIANTARG *>(&(vv._v)));
};
AxVLCVariant(int i)
{
V_VT(&_v) = VT_I4;
V_I4(&_v) = i;
};
AxVLCVariant(BSTR bstr)
{
VARIANT arg;
V_VT(&arg) = VT_BSTR;
V_BSTR(&arg) = bstr;
VariantInit(&_v);
VariantCopy(&_v, &arg);
};
inline const VARIANTARG *variantArg(void) const {
return &_v;
}
inline void swap(AxVLCVariant &v1, AxVLCVariant &v2)
{
VARIANTARG tmp = v1._v;
v1._v = v2._v;
v2._v = tmp;
};
private:
VARIANTARG _v;
};
class AxVLCWSTR
{
public:
AxVLCWSTR(void) : _data(NULL) {};
virtual ~AxVLCWSTR()
{
if( NULL != _data )
{
ULONG refcount = InterlockedDecrement(&(_data->refcount));
if( 0 == refcount )
CoTaskMemFree(_data);
}
};
AxVLCWSTR(LPCWSTR s)
{
if( NULL != s )
{
size_t len = wcslen(s);
if( len > 0 )
{
size_t size = len*sizeof(WCHAR);
_data = (struct data *)CoTaskMemAlloc(sizeof(struct data)+size);
if( NULL != _data )
{
_data->len = len;
_data->refcount = 1;
memcpy(_data->wstr, s, size);
_data->wstr[len]=L'\0';
return;
}
}
}
_data = NULL;
};
AxVLCWSTR(const AxVLCWSTR &s)
{
_data = s._data;
if( NULL != _data )
InterlockedIncrement(&(_data->refcount));
};
inline bool operator<(const AxVLCWSTR &s) const
{
return compareNoCase(s.wstr()) < 0;
};
inline bool operator<(LPCWSTR s) const
{
return compareNoCase(s) < 0;
};
inline bool operator==(const AxVLCWSTR &s) const
{
return size() == s.size() ?
(compareNoCase(s.wstr()) == 0) : false;
};
inline bool operator==(LPCWSTR s) const
{
return compareNoCase(s) == 0;
};
LPCWSTR wstr(void) const
{
return (NULL != _data) ? _data->wstr : NULL;
};
size_t size(void) const
{
return (NULL != _data) ? _data->len : 0;
};
private:
inline int compareNoCase(LPCWSTR s) const
{
if( NULL == _data )
{
return (NULL == s) ? 0 : -1;
}
if( NULL == s )
return 1;
return _wcsicmp(_data->wstr, s);
};
struct data {
size_t len;
LONG refcount;
wchar_t wstr[1];
} *_data;
};
typedef pair<class AxVLCWSTR, class AxVLCVariant> AxVLCPropertyPair;
typedef map<class AxVLCWSTR, class AxVLCVariant> AxVLCPropertyMap;
///////////////////////////
class VLCPropertyBag : public IPropertyBag
{
public:
VLCPropertyBag(void) : _i_ref(1) {};
virtual ~VLCPropertyBag() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IPropertyBag == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
// standalone object
return E_NOINTERFACE;
};
STDMETHODIMP_(ULONG) AddRef(void)
{ return InterlockedIncrement(&_i_ref); };
STDMETHODIMP_(ULONG) Release(void)
{
ULONG refcount = InterlockedDecrement(&_i_ref);
if( 0 == refcount )
{
delete this;
return 0;
}
return refcount;
};
// IPropertyBag methods
STDMETHODIMP Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog)
{
if( (NULL == pszPropName) || (NULL == pVar) )
return E_POINTER;
AxVLCPropertyMap::const_iterator notfound = _pm.end();
AxVLCPropertyMap::const_iterator iter = _pm.find(pszPropName);
if( notfound != iter )
{
VARTYPE vtype = V_VT(pVar);
VARIANTARG v;
VariantInit(&v);
VariantCopy(&v, const_cast<VARIANTARG*>((*iter).second.variantArg()));
if( (V_VT(&v) != vtype) && FAILED(VariantChangeType(&v, &v, 0, vtype)) )
{
VariantClear(&v);
return E_FAIL;
}
*pVar = v;
return S_OK;
}
else
return E_INVALIDARG;
};
STDMETHODIMP Write(LPCOLESTR pszPropName, VARIANT *pVar)
{
if( (NULL == pszPropName) || (NULL == pVar) )
return E_POINTER;
AxVLCPropertyPair val(pszPropName, pVar);
pair<AxVLCPropertyMap::iterator, bool> p = _pm.insert(val);
if( false == p.second )
// replace existing key value
(*p.first).second = val.second;
return S_OK;
};
// custom methods
HRESULT Load(LPSTREAM pStm)
{
if( NULL == pStm )
return E_INVALIDARG;
HRESULT result;
AxVLCPropertyPair *val;
result = ReadProperty(pStm, &val);
if( SUCCEEDED(result) )
{
if( (val->first == L"(Count)") && (VT_I4 == V_VT(val->second.variantArg())) )
{
size_t count = V_I4(val->second.variantArg());
delete val;
while( count-- )
{
result = ReadProperty(pStm, &val);
if( FAILED(result) )
return result;
pair<AxVLCPropertyMap::iterator, bool> p = _pm.insert(*val);
if( false == p.second )
// replace existing key value
(*p.first).second = val->second;
delete val;
}
}
}
return result;
};
HRESULT Save(LPSTREAM pStm)
{
if( NULL == pStm )
return E_INVALIDARG;
HRESULT result;
AxVLCPropertyPair header(L"(Count)", _pm.size());
result = WriteProperty(pStm, header);
if( SUCCEEDED(result) )
{
AxVLCPropertyMap::const_iterator iter = _pm.begin();
AxVLCPropertyMap::const_iterator end = _pm.end();
while( iter != end )
{
result = WriteProperty(pStm, *(iter++));
if( FAILED(result) )
return result;
}
}
return result;
};
BOOL IsEmpty()
{
return _pm.size() == 0;
}
private:
HRESULT WriteProperty(LPSTREAM pStm, const AxVLCPropertyPair &prop)
{
HRESULT result;
const AxVLCWSTR propName = prop.first;
ULONG len = propName.size();
if( 0 == len )
return E_INVALIDARG;
result = pStm->Write(&len, sizeof(len), NULL);
if( FAILED(result) )
return result;
result = pStm->Write(propName.wstr(), len*sizeof(WCHAR), NULL);
if( FAILED(result) )
return result;
const VARIANTARG *propValue = prop.second.variantArg();
VARTYPE vtype = V_VT(propValue);
switch( vtype )
{
case VT_BOOL:
result = pStm->Write(&vtype, sizeof(vtype), NULL);
if( FAILED(result) )
return result;
result = pStm->Write(&V_BOOL(propValue), sizeof(V_BOOL(propValue)), NULL);
if( FAILED(result) )
return result;
break;
case VT_I4:
result = pStm->Write(&vtype, sizeof(vtype), NULL);
if( FAILED(result) )
return result;
result = pStm->Write(&V_I4(propValue), sizeof(V_I4(propValue)), NULL);
if( FAILED(result) )
return result;
break;
case VT_BSTR:
result = pStm->Write(&vtype, sizeof(vtype), NULL);
if( FAILED(result) )
return result;
len = SysStringLen(V_BSTR(propValue));
result = pStm->Write(&len, sizeof(len), NULL);
if( FAILED(result) )
return result;
if( len > 0 )
{
result = pStm->Write(V_BSTR(propValue), len*sizeof(OLECHAR), NULL);
if( FAILED(result) )
return result;
}
break;
default:
vtype = VT_EMPTY;
result = pStm->Write(&vtype, sizeof(vtype), NULL);
if( FAILED(result) )
return result;
}
return result;
};
HRESULT ReadProperty(LPSTREAM pStm, AxVLCPropertyPair **prop)
{
HRESULT result;
ULONG len;
result = pStm->Read(&len, sizeof(len), NULL);
if( FAILED(result) )
return result;
if( 0 == len )
return E_INVALIDARG;
WCHAR propName[len + 1];
result = pStm->Read(propName, len*sizeof(WCHAR), NULL);
if( FAILED(result) )
return result;
propName[len] = L'\0';
VARIANTARG propValue;
VARTYPE vtype;
result = pStm->Read(&vtype, sizeof(vtype), NULL);
if( FAILED(result) )
return result;
switch( vtype )
{
case VT_BOOL:
V_VT(&propValue) = vtype;
result = pStm->Read(&V_BOOL(&propValue), sizeof(V_BOOL(&propValue)), NULL);
if( FAILED(result) )
return result;
break;
case VT_I4:
V_VT(&propValue) = vtype;
result = pStm->Read(&V_I4(&propValue), sizeof(V_I4(&propValue)), NULL);
if( FAILED(result) )
return result;
break;
case VT_BSTR:
V_VT(&propValue) = vtype;
result = pStm->Read(&len, sizeof(len), NULL);
if( FAILED(result) )
return result;
V_BSTR(&propValue) = NULL;
if( len > 0 )
{
V_BSTR(&propValue) = SysAllocStringLen(NULL, len);
if( NULL == V_BSTR(&propValue) )
return E_OUTOFMEMORY;
result = pStm->Read(V_BSTR(&propValue), len*sizeof(OLECHAR), NULL);
if( FAILED(result) )
{
SysFreeString(V_BSTR(&propValue));
return result;
}
}
break;
default:
VariantInit(&propValue);
}
*prop = new AxVLCPropertyPair(propName, propValue);
return S_OK;
};
AxVLCPropertyMap _pm;
LONG _i_ref;
};
///////////////////////////
VLCPersistStreamInit::VLCPersistStreamInit(VLCPlugin *p_instance) : _p_instance(p_instance)
{
_p_props = new VLCPropertyBag();
};
VLCPersistStreamInit::~VLCPersistStreamInit()
{
_p_props->Release();
};
STDMETHODIMP VLCPersistStreamInit::GetClassID(LPCLSID pClsID)
{
if( NULL == pClsID )
return E_POINTER;
*pClsID = _p_instance->getClassID();
return S_OK;
};
STDMETHODIMP VLCPersistStreamInit::InitNew(void)
{
return _p_instance->onInit();
};
STDMETHODIMP VLCPersistStreamInit::Load(LPSTREAM pStm)
{
HRESULT result = _p_props->Load(pStm);
if( FAILED(result) )
return result;
LPPERSISTPROPERTYBAG pPersistPropBag;
if( FAILED(QueryInterface(IID_IPersistPropertyBag, (void**)&pPersistPropBag)) )
return E_FAIL;
result = pPersistPropBag->Load(_p_props, NULL);
pPersistPropBag->Release();
return result;
};
STDMETHODIMP VLCPersistStreamInit::Save(LPSTREAM pStm, BOOL fClearDirty)
{
if( NULL == pStm )
return E_INVALIDARG;
LPPERSISTPROPERTYBAG pPersistPropBag;
if( FAILED(QueryInterface(IID_IPersistPropertyBag, (void**)&pPersistPropBag)) )
return E_FAIL;
HRESULT result = pPersistPropBag->Save(_p_props, fClearDirty, _p_props->IsEmpty());
pPersistPropBag->Release();
if( FAILED(result) )
return result;
return _p_props->Save(pStm);
};
STDMETHODIMP VLCPersistStreamInit::IsDirty(void)
{
return _p_instance->isDirty() ? S_OK : S_FALSE;
};
STDMETHODIMP VLCPersistStreamInit::GetSizeMax(ULARGE_INTEGER *pcbSize)
{
pcbSize->HighPart = 0UL;
pcbSize->LowPart = 16384UL; // just a guess
return S_OK;
};
/*****************************************************************************
* persiststreaminit.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __PERSISTSTREAMINIT_H__
#define __PERSISTSTREAMINIT_H__
#include <ocidl.h>
class VLCPersistStreamInit : public IPersistStreamInit
{
public:
VLCPersistStreamInit(VLCPlugin *p_instance);
virtual ~VLCPersistStreamInit();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IPersist == riid)
|| (IID_IPersistStreamInit == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IPersist methods
STDMETHODIMP GetClassID(LPCLSID);
// IPersistStreamInit methods
STDMETHODIMP IsDirty(void);
STDMETHODIMP InitNew(void);
STDMETHODIMP Load(LPSTREAM);
STDMETHODIMP Save(LPSTREAM, BOOL);
STDMETHODIMP GetSizeMax(ULARGE_INTEGER *);
private:
VLCPlugin *_p_instance;
class VLCPropertyBag *_p_props;
};
#endif
/*****************************************************************************
* plugin.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2006-2010 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "oleobject.h"
#include "olecontrol.h"
#include "oleinplaceobject.h"
#include "oleinplaceactiveobject.h"
#include "persistpropbag.h"
#include "persiststreaminit.h"
#include "persiststorage.h"
#include "provideclassinfo.h"
#include "connectioncontainer.h"
#include "objectsafety.h"
#include "vlccontrol.h"
#include "vlccontrol2.h"
#include "viewobject.h"
#include "dataobject.h"
#include "supporterrorinfo.h"
#include "utils.h"
#include <stdio.h>
#include <string.h>
#include <winreg.h>
#include <winuser.h>
#include <servprov.h>
#include <shlwapi.h>
#include <wininet.h>
#include <assert.h>
using namespace std;
////////////////////////////////////////////////////////////////////////
//class factory
static LRESULT CALLBACK VLCInPlaceClassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
VLCPlugin *p_instance = reinterpret_cast<VLCPlugin *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
switch( uMsg )
{
case WM_ERASEBKGND:
return 1L;
case WM_PAINT:
PAINTSTRUCT ps;
RECT pr;
if( GetUpdateRect(hWnd, &pr, FALSE) )
{
RECT bounds;
GetClientRect(hWnd, &bounds);
BeginPaint(hWnd, &ps);
p_instance->onPaint(ps.hdc, bounds, pr);
EndPaint(hWnd, &ps);
}
return 0L;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
};
VLCPluginClass::VLCPluginClass(LONG *p_class_ref, HINSTANCE hInstance, REFCLSID rclsid) :
_p_class_ref(p_class_ref),
_hinstance(hInstance),
_classid(rclsid),
_inplace_picture(NULL)
{
WNDCLASS wClass;
if( ! GetClassInfo(hInstance, getInPlaceWndClassName(), &wClass) )
{
wClass.style = CS_NOCLOSE|CS_DBLCLKS;
wClass.lpfnWndProc = VLCInPlaceClassWndProc;
wClass.cbClsExtra = 0;
wClass.cbWndExtra = 0;
wClass.hInstance = hInstance;
wClass.hIcon = NULL;
wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wClass.hbrBackground = NULL;
wClass.lpszMenuName = NULL;
wClass.lpszClassName = getInPlaceWndClassName();
_inplace_wndclass_atom = RegisterClass(&wClass);
}
else
{
_inplace_wndclass_atom = 0;
}
HBITMAP hbitmap = (HBITMAP)LoadImage(getHInstance(), MAKEINTRESOURCE(2), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
if( NULL != hbitmap )
{
PICTDESC pictDesc;
pictDesc.cbSizeofstruct = sizeof(PICTDESC);
pictDesc.picType = PICTYPE_BITMAP;
pictDesc.bmp.hbitmap = hbitmap;
pictDesc.bmp.hpal = NULL;
if( FAILED(OleCreatePictureIndirect(&pictDesc, IID_IPicture, TRUE, reinterpret_cast<LPVOID*>(&_inplace_picture))) )
_inplace_picture = NULL;
}
AddRef();
};
VLCPluginClass::~VLCPluginClass()
{
if( 0 != _inplace_wndclass_atom )
UnregisterClass(MAKEINTATOM(_inplace_wndclass_atom), _hinstance);
if( NULL != _inplace_picture )
_inplace_picture->Release();
};
STDMETHODIMP VLCPluginClass::QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_INVALIDARG;
if( (IID_IUnknown == riid)
|| (IID_IClassFactory == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
*ppv = NULL;
return E_NOINTERFACE;
};
STDMETHODIMP_(ULONG) VLCPluginClass::AddRef(void)
{
return InterlockedIncrement(_p_class_ref);
};
STDMETHODIMP_(ULONG) VLCPluginClass::Release(void)
{
ULONG refcount = InterlockedDecrement(_p_class_ref);
if( 0 == refcount )
{
delete this;
return 0;
}
return refcount;
};
STDMETHODIMP VLCPluginClass::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
*ppv = NULL;
if( (NULL != pUnkOuter) && (IID_IUnknown != riid) ) {
return CLASS_E_NOAGGREGATION;
}
VLCPlugin *plugin = new VLCPlugin(this, pUnkOuter);
if( NULL != plugin )
{
HRESULT hr = plugin->QueryInterface(riid, ppv);
// the following will destroy the object if QueryInterface() failed
plugin->Release();
return hr;
}
return E_OUTOFMEMORY;
};
STDMETHODIMP VLCPluginClass::LockServer(BOOL fLock)
{
if( fLock )
AddRef();
else
Release();
return S_OK;
};
////////////////////////////////////////////////////////////////////////
VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) :
_inplacewnd(NULL),
_p_class(p_class),
_i_ref(1UL),
_p_libvlc(NULL),
_p_mlist(NULL),
_p_mplayer(NULL),
_i_midx(-1),
_i_codepage(CP_ACP),
_b_usermode(TRUE)
{
/*
** bump refcount to avoid recursive release from
** following interfaces when releasing this interface
*/
AddRef();
p_class->AddRef();
vlcOleControl = new VLCOleControl(this);
vlcOleInPlaceObject = new VLCOleInPlaceObject(this);
vlcOleInPlaceActiveObject = new VLCOleInPlaceActiveObject(this);
vlcPersistStorage = new VLCPersistStorage(this);
vlcPersistStreamInit = new VLCPersistStreamInit(this);
vlcPersistPropertyBag = new VLCPersistPropertyBag(this);
vlcProvideClassInfo = new VLCProvideClassInfo(this);
vlcConnectionPointContainer = new VLCConnectionPointContainer(this);
vlcObjectSafety = new VLCObjectSafety(this);
vlcControl = new VLCControl(this);
vlcControl2 = new VLCControl2(this);
vlcViewObject = new VLCViewObject(this);
vlcDataObject = new VLCDataObject(this);
vlcOleObject = new VLCOleObject(this);
vlcSupportErrorInfo = new VLCSupportErrorInfo(this);
// configure controlling IUnknown interface for implemented interfaces
this->pUnkOuter = (NULL != pUnkOuter) ? pUnkOuter : dynamic_cast<LPUNKNOWN>(this);
// default picure
_p_pict = p_class->getInPlacePict();
// make sure that persistable properties are initialized
onInit();
};
VLCPlugin::~VLCPlugin()
{
delete vlcSupportErrorInfo;
delete vlcOleObject;
delete vlcDataObject;
delete vlcViewObject;
delete vlcControl2;
delete vlcControl;
delete vlcConnectionPointContainer;
delete vlcProvideClassInfo;
delete vlcPersistPropertyBag;
delete vlcPersistStreamInit;
delete vlcPersistStorage;
delete vlcOleInPlaceActiveObject;
delete vlcOleInPlaceObject;
delete vlcObjectSafety;
delete vlcOleControl;
if( _p_pict )
_p_pict->Release();
SysFreeString(_bstr_mrl);
SysFreeString(_bstr_baseurl);
if( _p_mplayer )
{
if( isPlaying() )
playlist_stop();
player_unregister_events();
libvlc_media_player_release(_p_mplayer);
_p_mplayer=NULL;
}
if( _p_mlist ) { libvlc_media_list_release(_p_mlist); _p_mlist=NULL; }
if( _p_libvlc ) { libvlc_release(_p_libvlc); _p_libvlc=NULL; }
_p_class->Release();
Release();
};
STDMETHODIMP VLCPlugin::QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_INVALIDARG;
if( IID_IUnknown == riid )
*ppv = reinterpret_cast<LPVOID>(this);
else if( IID_IOleObject == riid )
*ppv = reinterpret_cast<LPVOID>(vlcOleObject);
else if( IID_IOleControl == riid )
*ppv = reinterpret_cast<LPVOID>(vlcOleControl);
else if( IID_IOleWindow == riid )
*ppv = reinterpret_cast<LPVOID>(vlcOleInPlaceObject);
else if( IID_IOleInPlaceObject == riid )
*ppv = reinterpret_cast<LPVOID>(vlcOleInPlaceObject);
else if( IID_IOleInPlaceActiveObject == riid )
*ppv = reinterpret_cast<LPVOID>(vlcOleInPlaceActiveObject);
else if( IID_IPersist == riid )
*ppv = reinterpret_cast<LPVOID>(vlcPersistStreamInit);
else if( IID_IPersistStreamInit == riid )
*ppv = reinterpret_cast<LPVOID>(vlcPersistStreamInit);
else if( IID_IPersistStorage == riid )
*ppv = reinterpret_cast<LPVOID>(vlcPersistStorage);
else if( IID_IPersistPropertyBag == riid )
*ppv = reinterpret_cast<LPVOID>(vlcPersistPropertyBag);
else if( IID_IProvideClassInfo == riid )
*ppv = reinterpret_cast<LPVOID>(vlcProvideClassInfo);
else if( IID_IProvideClassInfo2 == riid )
*ppv = reinterpret_cast<LPVOID>(vlcProvideClassInfo);
else if( IID_IConnectionPointContainer == riid )
*ppv = reinterpret_cast<LPVOID>(vlcConnectionPointContainer);
else if( IID_IObjectSafety == riid )
*ppv = reinterpret_cast<LPVOID>(vlcObjectSafety);
else if( IID_IDispatch == riid )
*ppv = (CLSID_VLCPlugin2 == getClassID()) ?
reinterpret_cast<LPVOID>(vlcControl2) :
reinterpret_cast<LPVOID>(vlcControl);
else if( IID_IVLCControl == riid )
*ppv = reinterpret_cast<LPVOID>(vlcControl);
else if( IID_IVLCControl2 == riid )
*ppv = reinterpret_cast<LPVOID>(vlcControl2);
else if( IID_IViewObject == riid )
*ppv = reinterpret_cast<LPVOID>(vlcViewObject);
else if( IID_IViewObject2 == riid )
*ppv = reinterpret_cast<LPVOID>(vlcViewObject);
else if( IID_IDataObject == riid )
*ppv = reinterpret_cast<LPVOID>(vlcDataObject);
else if( IID_ISupportErrorInfo == riid )
*ppv = reinterpret_cast<LPVOID>(vlcSupportErrorInfo);
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
};
STDMETHODIMP_(ULONG) VLCPlugin::AddRef(void)
{
return InterlockedIncrement((LONG *)&_i_ref);
};
STDMETHODIMP_(ULONG) VLCPlugin::Release(void)
{
if( ! InterlockedDecrement((LONG *)&_i_ref) )
{
delete this;
return 0;
}
return _i_ref;
};
//////////////////////////////////////
HRESULT VLCPlugin::onInit(void)
{
if( NULL == _p_libvlc )
{
// initialize persistable properties
_b_autoplay = TRUE;
_b_autoloop = FALSE;
_b_toolbar = FALSE;
_bstr_baseurl = NULL;
_bstr_mrl = NULL;
_b_visible = TRUE;
_b_mute = FALSE;
_i_volume = 50;
_i_time = 0;
_i_backcolor = 0;
// set default/preferred size (320x240) pixels in HIMETRIC
HDC hDC = CreateDevDC(NULL);
_extent.cx = 320;
_extent.cy = 240;
HimetricFromDP(hDC, (LPPOINT)&_extent, 1);
DeleteDC(hDC);
return S_OK;
}
return CO_E_ALREADYINITIALIZED;
};
HRESULT VLCPlugin::onLoad(void)
{
if( SysStringLen(_bstr_baseurl) == 0 )
{
/*
** try to retreive the base URL using the client site moniker, which for Internet Explorer
** is the URL of the page the plugin is embedded into.
*/
LPOLECLIENTSITE pClientSite;
if( SUCCEEDED(vlcOleObject->GetClientSite(&pClientSite)) && (NULL != pClientSite) )
{
IBindCtx *pBC = 0;
if( SUCCEEDED(CreateBindCtx(0, &pBC)) )
{
LPMONIKER pContMoniker = NULL;
if( SUCCEEDED(pClientSite->GetMoniker(OLEGETMONIKER_ONLYIFTHERE,
OLEWHICHMK_CONTAINER, &pContMoniker)) )
{
LPOLESTR base_url;
if( SUCCEEDED(pContMoniker->GetDisplayName(pBC, NULL, &base_url)) )
{
/*
** check that the moniker name is a URL
*/
if( UrlIsW(base_url, URLIS_URL) )
{
/* copy base URL */
_bstr_baseurl = SysAllocString(base_url);
}
CoTaskMemFree(base_url);
}
}
}
}
}
setDirty(FALSE);
return S_OK;
};
void VLCPlugin::initVLC()
{
extern HMODULE DllGetModule();
/*
** default initialization options
*/
const char *ppsz_argv[32] = { };
int ppsz_argc = 0;
char p_progpath[MAX_PATH];
{
TCHAR w_progpath[MAX_PATH];
DWORD len = GetModuleFileName(DllGetModule(), w_progpath, MAX_PATH);
w_progpath[MAX_PATH-1] = '\0';
if( len > 0 )
{
len = WideCharToMultiByte(CP_UTF8, 0, w_progpath, len, p_progpath,
sizeof(p_progpath)-1, NULL, NULL);
if( len > 0 )
{
p_progpath[len] = '\0';
ppsz_argv[0] = p_progpath;
}
}
}
ppsz_argv[ppsz_argc++] = "-vv";
HKEY h_key;
char p_pluginpath[MAX_PATH];
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("Software\\VideoLAN\\VLC"),
0, KEY_READ, &h_key ) == ERROR_SUCCESS )
{
DWORD i_type, i_data = MAX_PATH;
TCHAR w_pluginpath[MAX_PATH];
if( RegQueryValueEx( h_key, TEXT("InstallDir"), 0, &i_type,
(LPBYTE)w_pluginpath, &i_data ) == ERROR_SUCCESS )
{
w_pluginpath[MAX_PATH-1] = '\0';
if( i_type == REG_SZ )
{
if( WideCharToMultiByte(CP_UTF8, 0, w_pluginpath, -1, p_pluginpath,
sizeof(p_pluginpath)-sizeof("\\plugins")+1, NULL, NULL) )
{
strcat( p_pluginpath, "\\plugins" );
ppsz_argv[ppsz_argc++] = "--plugin-path";
ppsz_argv[ppsz_argc++] = p_pluginpath;
}
}
}
RegCloseKey( h_key );
}
// make sure plugin isn't affected with VLC single instance mode
ppsz_argv[ppsz_argc++] = "--no-one-instance";
/* common settings */
ppsz_argv[ppsz_argc++] = "-vv";
ppsz_argv[ppsz_argc++] = "--no-stats";
ppsz_argv[ppsz_argc++] = "--no-media-library";
ppsz_argv[ppsz_argc++] = "--intf=dummy";
ppsz_argv[ppsz_argc++] = "--no-video-title-show";
// loop mode is a configuration option only
if( _b_autoloop )
ppsz_argv[ppsz_argc++] = "--loop";
_p_libvlc = libvlc_new(ppsz_argc, ppsz_argv);
if( !_p_libvlc )
return;
_p_mlist = libvlc_media_list_new(_p_libvlc);
// initial playlist item
if( SysStringLen(_bstr_mrl) > 0 )
{
char *psz_mrl = NULL;
if( SysStringLen(_bstr_baseurl) > 0 )
{
/*
** if the MRL a relative URL, we should end up with an absolute URL
*/
LPWSTR abs_url = CombineURL(_bstr_baseurl, _bstr_mrl);
if( NULL != abs_url )
{
psz_mrl = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
CoTaskMemFree(abs_url);
}
else
{
psz_mrl = CStrFromBSTR(CP_UTF8, _bstr_mrl);
}
}
else
{
/*
** baseURL is empty, assume MRL is absolute
*/
psz_mrl = CStrFromBSTR(CP_UTF8, _bstr_mrl);
}
if( NULL != psz_mrl )
{
const char *options[1];
int i_options = 0;
char timeBuffer[32];
if( _i_time )
{
snprintf(timeBuffer, sizeof(timeBuffer), ":start-time=%d", _i_time);
options[i_options++] = timeBuffer;
}
// add default target to playlist
playlist_add_extended_untrusted(psz_mrl, i_options, options);
CoTaskMemFree(psz_mrl);
}
}
};
void VLCPlugin::setErrorInfo(REFIID riid, const char *description)
{
vlcSupportErrorInfo->setErrorInfo( getClassID() == CLSID_VLCPlugin2 ?
OLESTR("VideoLAN.VLCPlugin.2") : OLESTR("VideoLAN.VLCPlugin.1"),
riid, description );
};
HRESULT VLCPlugin::onAmbientChanged(LPUNKNOWN pContainer, DISPID dispID)
{
VARIANT v;
switch( dispID )
{
case DISPID_AMBIENT_BACKCOLOR:
VariantInit(&v);
V_VT(&v) = VT_I4;
if( SUCCEEDED(GetObjectProperty(pContainer, dispID, v)) )
{
setBackColor(V_I4(&v));
}
break;
case DISPID_AMBIENT_DISPLAYNAME:
break;
case DISPID_AMBIENT_FONT:
break;
case DISPID_AMBIENT_FORECOLOR:
break;
case DISPID_AMBIENT_LOCALEID:
break;
case DISPID_AMBIENT_MESSAGEREFLECT:
break;
case DISPID_AMBIENT_SCALEUNITS:
break;
case DISPID_AMBIENT_TEXTALIGN:
break;
case DISPID_AMBIENT_USERMODE:
VariantInit(&v);
V_VT(&v) = VT_BOOL;
if( SUCCEEDED(GetObjectProperty(pContainer, dispID, v)) )
{
setUserMode(V_BOOL(&v) != VARIANT_FALSE);
}
break;
case DISPID_AMBIENT_UIDEAD:
break;
case DISPID_AMBIENT_SHOWGRABHANDLES:
break;
case DISPID_AMBIENT_SHOWHATCHING:
break;
case DISPID_AMBIENT_DISPLAYASDEFAULT:
break;
case DISPID_AMBIENT_SUPPORTSMNEMONICS:
break;
case DISPID_AMBIENT_AUTOCLIP:
break;
case DISPID_AMBIENT_APPEARANCE:
break;
case DISPID_AMBIENT_CODEPAGE:
VariantInit(&v);
V_VT(&v) = VT_I4;
if( SUCCEEDED(GetObjectProperty(pContainer, dispID, v)) )
{
setCodePage(V_I4(&v));
}
break;
case DISPID_AMBIENT_PALETTE:
break;
case DISPID_AMBIENT_CHARSET:
break;
case DISPID_AMBIENT_RIGHTTOLEFT:
break;
case DISPID_AMBIENT_TOPTOBOTTOM:
break;
case DISPID_UNKNOWN:
/*
** multiple property change, look up the ones we are interested in
*/
VariantInit(&v);
V_VT(&v) = VT_BOOL;
if( SUCCEEDED(GetObjectProperty(pContainer, DISPID_AMBIENT_USERMODE, v)) )
{
setUserMode(V_BOOL(&v) != VARIANT_FALSE);
}
VariantInit(&v);
V_VT(&v) = VT_I4;
if( SUCCEEDED(GetObjectProperty(pContainer, DISPID_AMBIENT_CODEPAGE, v)) )
{
setCodePage(V_I4(&v));
}
break;
}
return S_OK;
};
HRESULT VLCPlugin::onClose(DWORD dwSaveOption)
{
if( isInPlaceActive() )
{
onInPlaceDeactivate();
}
if( isRunning() )
{
libvlc_instance_t* p_libvlc = _p_libvlc;
_p_libvlc = NULL;
vlcDataObject->onClose();
if( p_libvlc )
libvlc_release(p_libvlc);
}
return S_OK;
};
BOOL VLCPlugin::isInPlaceActive(void)
{
return (NULL != _inplacewnd);
};
HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprcPosRect, LPCRECT lprcClipRect)
{
RECT clipRect = *lprcClipRect;
/*
** record keeping of control geometry within container
*/
_posRect = *lprcPosRect;
/*
** Create a window for in place activated control.
** the window geometry matches the control viewport
** within container so that embedded video is always
** properly displayed.
*/
_inplacewnd = CreateWindow(_p_class->getInPlaceWndClassName(),
TEXT("VLC Plugin In-Place Window"),
WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
lprcPosRect->left,
lprcPosRect->top,
lprcPosRect->right-lprcPosRect->left,
lprcPosRect->bottom-lprcPosRect->top,
hwndParent,
0,
_p_class->getHInstance(),
NULL
);
if( NULL == _inplacewnd )
return E_FAIL;
SetWindowLongPtr(_inplacewnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
/* change cliprect coordinates system relative to window bounding rect */
OffsetRect(&clipRect, -lprcPosRect->left, -lprcPosRect->top);
HRGN clipRgn = CreateRectRgnIndirect(&clipRect);
SetWindowRgn(_inplacewnd, clipRgn, TRUE);
if( _b_usermode )
{
/* will run vlc if not done already */
libvlc_instance_t* p_libvlc;
HRESULT result = getVLC(&p_libvlc);
if( FAILED(result) )
return result;
if( _b_autoplay && playlist_select(0) )
{
libvlc_media_player_play(_p_mplayer);
fireOnPlayEvent();
}
}
if( isVisible() )
ShowWindow(_inplacewnd, SW_SHOW);
return S_OK;
};
HRESULT VLCPlugin::onInPlaceDeactivate(void)
{
if( isPlaying() )
{
playlist_stop();
fireOnStopEvent();
}
DestroyWindow(_inplacewnd);
_inplacewnd = NULL;
return S_OK;
};
void VLCPlugin::setVisible(BOOL fVisible)
{
if( fVisible != _b_visible )
{
_b_visible = fVisible;
if( isInPlaceActive() )
{
ShowWindow(_inplacewnd, fVisible ? SW_SHOW : SW_HIDE);
if( fVisible )
InvalidateRect(_inplacewnd, NULL, TRUE);
}
setDirty(TRUE);
firePropChangedEvent(DISPID_Visible);
}
};
void VLCPlugin::setVolume(int volume)
{
if( volume < 0 )
volume = 0;
else if( volume > 200 )
volume = 200;
if( volume != _i_volume )
{
_i_volume = volume;
if( isRunning() )
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
libvlc_audio_set_volume(p_md, _i_volume);
}
setDirty(TRUE);
}
};
void VLCPlugin::setBackColor(OLE_COLOR backcolor)
{
if( _i_backcolor != backcolor )
{
_i_backcolor = backcolor;
if( isInPlaceActive() )
{
}
setDirty(TRUE);
}
};
void VLCPlugin::setTime(int seconds)
{
if( seconds < 0 )
seconds = 0;
if( seconds != _i_time )
{
setStartTime(_i_time);
if( NULL != _p_mplayer )
{
libvlc_media_player_set_time(_p_mplayer, _i_time);
}
}
};
void VLCPlugin::setFocus(BOOL fFocus)
{
if( fFocus )
SetActiveWindow(_inplacewnd);
};
BOOL VLCPlugin::hasFocus(void)
{
return GetActiveWindow() == _inplacewnd;
};
void VLCPlugin::onDraw(DVTARGETDEVICE * ptd, HDC hicTargetDev,
HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds)
{
if( isVisible() )
{
long width = lprcBounds->right-lprcBounds->left;
long height = lprcBounds->bottom-lprcBounds->top;
RECT bounds = { lprcBounds->left, lprcBounds->top, lprcBounds->right, lprcBounds->bottom };
if( isUserMode() )
{
/* VLC is in user mode, just draw background color */
COLORREF colorref = RGB(0, 0, 0);
OleTranslateColor(_i_backcolor, (HPALETTE)GetStockObject(DEFAULT_PALETTE), &colorref);
if( colorref != RGB(0, 0, 0) )
{
/* custom background */
HBRUSH colorbrush = CreateSolidBrush(colorref);
FillRect(hdcDraw, &bounds, colorbrush);
DeleteObject((HANDLE)colorbrush);
}
else
{
/* black background */
FillRect(hdcDraw, &bounds, (HBRUSH)GetStockObject(BLACK_BRUSH));
}
}
else
{
/* VLC is in design mode, draw the VLC logo */
FillRect(hdcDraw, &bounds, (HBRUSH)GetStockObject(WHITE_BRUSH));
LPPICTURE pict = getPicture();
if( NULL != pict )
{
OLE_XSIZE_HIMETRIC picWidth;
OLE_YSIZE_HIMETRIC picHeight;
pict->get_Width(&picWidth);
pict->get_Height(&picHeight);
SIZEL picSize = { picWidth, picHeight };
if( NULL != hicTargetDev )
{
DPFromHimetric(hicTargetDev, (LPPOINT)&picSize, 1);
}
else if( NULL != (hicTargetDev = CreateDevDC(ptd)) )
{
DPFromHimetric(hicTargetDev, (LPPOINT)&picSize, 1);
DeleteDC(hicTargetDev);
}
if( picSize.cx > width-4 )
picSize.cx = width-4;
if( picSize.cy > height-4 )
picSize.cy = height-4;
LONG dstX = lprcBounds->left+(width-picSize.cx)/2;
LONG dstY = lprcBounds->top+(height-picSize.cy)/2;
if( NULL != lprcWBounds )
{
RECT wBounds = { lprcWBounds->left, lprcWBounds->top, lprcWBounds->right, lprcWBounds->bottom };
pict->Render(hdcDraw, dstX, dstY, picSize.cx, picSize.cy,
0L, picHeight, picWidth, -picHeight, &wBounds);
}
else
pict->Render(hdcDraw, dstX, dstY, picSize.cx, picSize.cy,
0L, picHeight, picWidth, -picHeight, NULL);
pict->Release();
}
SelectObject(hdcDraw, GetStockObject(BLACK_BRUSH));
MoveToEx(hdcDraw, bounds.left, bounds.top, NULL);
LineTo(hdcDraw, bounds.left+width-1, bounds.top);
LineTo(hdcDraw, bounds.left+width-1, bounds.top+height-1);
LineTo(hdcDraw, bounds.left, bounds.top+height-1);
LineTo(hdcDraw, bounds.left, bounds.top);
}
}
};
void VLCPlugin::onPaint(HDC hdc, const RECT &bounds, const RECT &clipRect)
{
if( isVisible() )
{
/* if VLC is in design mode, draw control logo */
HDC hdcDraw = CreateCompatibleDC(hdc);
if( NULL != hdcDraw )
{
SIZEL size = getExtent();
DPFromHimetric(hdc, (LPPOINT)&size, 1);
RECTL posRect = { 0, 0, size.cx, size.cy };
int width = bounds.right-bounds.left;
int height = bounds.bottom-bounds.top;
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, width, height);
if( NULL != hBitmap )
{
HBITMAP oldBmp = (HBITMAP)SelectObject(hdcDraw, hBitmap);
if( (size.cx != width) || (size.cy != height) )
{
// needs to scale canvas
SetMapMode(hdcDraw, MM_ANISOTROPIC);
SetWindowExtEx(hdcDraw, size.cx, size.cy, NULL);
SetViewportExtEx(hdcDraw, width, height, NULL);
}
onDraw(NULL, hdc, hdcDraw, &posRect, NULL);
SetMapMode(hdcDraw, MM_TEXT);
BitBlt(hdc, bounds.left, bounds.top,
width, height,
hdcDraw, 0, 0,
SRCCOPY);
SelectObject(hdcDraw, oldBmp);
DeleteObject(hBitmap);
}
DeleteDC(hdcDraw);
}
}
};
void VLCPlugin::onPositionChange(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
{
RECT clipRect = *lprcClipRect;
//RedrawWindow(GetParent(_inplacewnd), &_posRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
/*
** record keeping of control geometry within container
*/
_posRect = *lprcPosRect;
/*
** change in-place window geometry to match clipping region
*/
SetWindowPos(_inplacewnd, NULL,
lprcPosRect->left,
lprcPosRect->top,
lprcPosRect->right-lprcPosRect->left,
lprcPosRect->bottom-lprcPosRect->top,
SWP_NOACTIVATE|
SWP_NOCOPYBITS|
SWP_NOZORDER|
SWP_NOOWNERZORDER );
/* change cliprect coordinates system relative to window bounding rect */
OffsetRect(&clipRect, -lprcPosRect->left, -lprcPosRect->top);
HRGN clipRgn = CreateRectRgnIndirect(&clipRect);
SetWindowRgn(_inplacewnd, clipRgn, FALSE);
//RedrawWindow(_videownd, &posRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
};
void VLCPlugin::freezeEvents(BOOL freeze)
{
vlcConnectionPointContainer->freezeEvents(freeze);
};
void VLCPlugin::firePropChangedEvent(DISPID dispid)
{
vlcConnectionPointContainer->firePropChangedEvent(dispid);
};
void VLCPlugin::fireOnPlayEvent(void)
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_PlayEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnPauseEvent(void)
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_PauseEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnStopEvent(void)
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_StopEvent, &dispparamsNoArgs);
};
/*
* Async events
*/
void VLCPlugin::fireOnMediaPlayerNothingSpecialEvent()
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerNothingSpecialEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnMediaPlayerOpeningEvent()
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerOpeningEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnMediaPlayerBufferingEvent(long cache)
{
DISPPARAMS params;
params.cArgs = 1;
params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
params.rgvarg[0].vt = VT_I4;
params.rgvarg[0].lVal = cache;
params.rgdispidNamedArgs = NULL;
params.cNamedArgs = 0;
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerBufferingEvent, &params);
};
void VLCPlugin::fireOnMediaPlayerPlayingEvent()
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPlayingEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnMediaPlayerPausedEvent()
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPausedEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnMediaPlayerEncounteredErrorEvent()
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerEncounteredErrorEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnMediaPlayerEndReachedEvent()
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerEndReachedEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnMediaPlayerStoppedEvent()
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerStoppedEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnMediaPlayerForwardEvent()
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerForwardEvent, &dispparamsNoArgs);
};
void VLCPlugin::fireOnMediaPlayerBackwardEvent()
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerBackwardEvent, &dispparamsNoArgs);
};
static void handle_input_state_event(const libvlc_event_t* event, void *param)
{
VLCPlugin *plugin = (VLCPlugin*)param;
switch( event->type )
{
case libvlc_MediaPlayerNothingSpecial:
plugin->fireOnMediaPlayerNothingSpecialEvent();
break;
case libvlc_MediaPlayerOpening:
plugin->fireOnMediaPlayerOpeningEvent();
break;
case libvlc_MediaPlayerBuffering:
plugin->fireOnMediaPlayerBufferingEvent(event->u.media_player_buffering.new_cache);
break;
case libvlc_MediaPlayerPlaying:
plugin->fireOnMediaPlayerPlayingEvent();
break;
case libvlc_MediaPlayerPaused:
plugin->fireOnMediaPlayerPausedEvent();
break;
case libvlc_MediaPlayerStopped:
plugin->fireOnMediaPlayerStoppedEvent();
break;
case libvlc_MediaPlayerForward:
plugin->fireOnMediaPlayerForwardEvent();
break;
case libvlc_MediaPlayerBackward:
plugin->fireOnMediaPlayerBackwardEvent();
break;
case libvlc_MediaPlayerEndReached:
plugin->fireOnMediaPlayerEndReachedEvent();
break;
case libvlc_MediaPlayerEncounteredError:
plugin->fireOnMediaPlayerEncounteredErrorEvent();
break;
}
}
void VLCPlugin::fireOnMediaPlayerTimeChangedEvent(long time)
{
DISPPARAMS params;
params.cArgs = 1;
params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
params.rgvarg[0].vt = VT_I4;
params.rgvarg[0].lVal = time;
params.rgdispidNamedArgs = NULL;
params.cNamedArgs = 0;
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerTimeChangedEvent, &params);
};
static void handle_time_changed_event(const libvlc_event_t* event, void *param)
{
VLCPlugin *plugin = (VLCPlugin*)param;
plugin->fireOnMediaPlayerTimeChangedEvent(event->u.media_player_time_changed.new_time);
}
void VLCPlugin::fireOnMediaPlayerPositionChangedEvent(long position)
{
DISPPARAMS params;
params.cArgs = 1;
params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
params.rgvarg[0].vt = VT_I4;
params.rgvarg[0].lVal = position;
params.rgdispidNamedArgs = NULL;
params.cNamedArgs = 0;
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPositionChangedEvent, &params);
};
static void handle_position_changed_event(const libvlc_event_t* event, void *param)
{
VLCPlugin *plugin = (VLCPlugin*)param;
plugin->fireOnMediaPlayerPositionChangedEvent(event->u.media_player_position_changed.new_position);
}
#define B(val) ((val) ? 0xFFFF : 0x0000)
void VLCPlugin::fireOnMediaPlayerSeekableChangedEvent(VARIANT_BOOL seekable)
{
DISPPARAMS params;
params.cArgs = 1;
params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
params.rgvarg[0].vt = VT_BOOL;
params.rgvarg[0].boolVal = seekable;
params.rgdispidNamedArgs = NULL;
params.cNamedArgs = 0;
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerSeekableChangedEvent, &params);
};
static void handle_seekable_changed_event(const libvlc_event_t* event, void *param)
{
VLCPlugin *plugin = (VLCPlugin*)param;
plugin->fireOnMediaPlayerSeekableChangedEvent(B(event->u.media_player_seekable_changed.new_seekable));
}
void VLCPlugin::fireOnMediaPlayerPausableChangedEvent(VARIANT_BOOL pausable)
{
DISPPARAMS params;
params.cArgs = 1;
params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
params.rgvarg[0].vt = VT_BOOL;
params.rgvarg[0].boolVal = pausable;
params.rgdispidNamedArgs = NULL;
params.cNamedArgs = 0;
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPausableChangedEvent, &params);
};
static void handle_pausable_changed_event(const libvlc_event_t* event, void *param)
{
VLCPlugin *plugin = (VLCPlugin*)param;
plugin->fireOnMediaPlayerPausableChangedEvent(B(event->u.media_player_pausable_changed.new_pausable));
}
#undef B
/* */
bool VLCPlugin::playlist_select( int idx )
{
libvlc_media_t *p_m = NULL;
assert(_p_mlist);
libvlc_media_list_lock(_p_mlist);
int count = libvlc_media_list_count(_p_mlist);
if( (idx < 0) || (idx >= count) )
goto bad_unlock;
_i_midx = idx;
p_m = libvlc_media_list_item_at_index(_p_mlist,_i_midx);
libvlc_media_list_unlock(_p_mlist);
if( !p_m )
return false;
if( _p_mplayer )
{
if( isPlaying() )
playlist_stop();
player_unregister_events();
libvlc_media_player_release( _p_mplayer );
_p_mplayer = NULL;
}
_p_mplayer = libvlc_media_player_new_from_media(p_m);
if( _p_mplayer )
{
// initial volume setting
libvlc_audio_set_volume(_p_mplayer, _i_volume);
if( _b_mute )
libvlc_audio_set_mute(_p_mplayer, TRUE);
set_player_window();
player_register_events();
}
libvlc_media_release(p_m);
return _p_mplayer ? true : false;
bad_unlock:
libvlc_media_list_unlock(_p_mlist);
return false;
}
void VLCPlugin::set_player_window()
{
// XXX FIXME no idea if this is correct or not
libvlc_media_player_set_hwnd(_p_mplayer,getInPlaceWindow());
}
void VLCPlugin::player_register_events()
{
libvlc_event_manager_t *eventManager = NULL;
assert(_p_mplayer);
eventManager = libvlc_media_player_event_manager(_p_mplayer);
if(eventManager) {
libvlc_event_attach(eventManager, libvlc_MediaPlayerNothingSpecial,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerOpening,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerBuffering,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerPlaying,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerPaused,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerStopped,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerForward,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerBackward,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerEncounteredError,
handle_input_state_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerTimeChanged,
handle_time_changed_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerPositionChanged,
handle_position_changed_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerSeekableChanged,
handle_seekable_changed_event, this);
libvlc_event_attach(eventManager, libvlc_MediaPlayerPausableChanged,
handle_pausable_changed_event, this);
}
}
void VLCPlugin::player_unregister_events()
{
libvlc_event_manager_t *eventManager = NULL;
assert(_p_mplayer);
eventManager = libvlc_media_player_event_manager(_p_mplayer);
if(eventManager) {
libvlc_event_detach(eventManager, libvlc_MediaPlayerNothingSpecial,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerOpening,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerBuffering,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerPlaying,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerPaused,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerStopped,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerForward,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerBackward,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerEndReached,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerEncounteredError,
handle_input_state_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerTimeChanged,
handle_time_changed_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerPositionChanged,
handle_position_changed_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerSeekableChanged,
handle_seekable_changed_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerPausableChanged,
handle_pausable_changed_event, this);
}
}
int VLCPlugin::playlist_add_extended_untrusted(const char *mrl, int optc, const char **optv)
{
int item = -1;
libvlc_media_t *p_m = libvlc_media_new_location(_p_libvlc,mrl);
if( !p_m )
return -1;
for( int i = 0; i < optc; ++i )
libvlc_media_add_option_flag(p_m, optv[i], libvlc_media_option_unique);
libvlc_media_list_lock(_p_mlist);
if( libvlc_media_list_add_media(_p_mlist,p_m) == 0 )
item = libvlc_media_list_count(_p_mlist)-1;
libvlc_media_list_unlock(_p_mlist);
libvlc_media_release(p_m);
return item;
}
/*****************************************************************************
* plugin.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005-2010 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __PLUGIN_H__
#define __PLUGIN_H__
#include <ole2.h>
#include <olectl.h>
#include <vlc/vlc.h>
extern "C" const GUID CLSID_VLCPlugin;
extern "C" const GUID CLSID_VLCPlugin2;
extern "C" const GUID LIBID_AXVLC;
extern "C" const GUID DIID_DVLCEvents;
class VLCPluginClass : public IClassFactory
{
public:
VLCPluginClass(LONG *p_class_ref, HINSTANCE hInstance, REFCLSID rclsid);
/* IUnknown methods */
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
/* IClassFactory methods */
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **ppv);
STDMETHODIMP LockServer(BOOL fLock);
REFCLSID getClassID(void) { return (REFCLSID)_classid; };
LPCTSTR getInPlaceWndClassName(void) const { return TEXT("VLC Plugin In-Place"); };
HINSTANCE getHInstance(void) const { return _hinstance; };
LPPICTURE getInPlacePict(void) const
{ if( NULL != _inplace_picture) _inplace_picture->AddRef(); return _inplace_picture; };
protected:
virtual ~VLCPluginClass();
private:
LPLONG _p_class_ref;
HINSTANCE _hinstance;
CLSID _classid;
ATOM _inplace_wndclass_atom;
LPPICTURE _inplace_picture;
};
class VLCPlugin : public IUnknown
{
public:
VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter);
/* IUnknown methods */
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
/* custom methods */
HRESULT getTypeLib(LCID lcid, ITypeLib **pTL) { return LoadRegTypeLib(LIBID_AXVLC, 1, 0, lcid, pTL); };
REFCLSID getClassID(void) { return _p_class->getClassID(); };
REFIID getDispEventID(void) { return (REFIID)DIID_DVLCEvents; };
/*
** persistant properties
*/
void setMRL(BSTR mrl)
{
SysFreeString(_bstr_mrl);
_bstr_mrl = SysAllocStringLen(mrl, SysStringLen(mrl));
setDirty(TRUE);
};
const BSTR getMRL(void) { return _bstr_mrl; };
inline void setAutoPlay(BOOL autoplay)
{
_b_autoplay = autoplay;
setDirty(TRUE);
};
inline BOOL getAutoPlay(void) { return _b_autoplay; };
inline void setAutoLoop(BOOL autoloop)
{
_b_autoloop = autoloop;
setDirty(TRUE);
};
inline BOOL getAutoLoop(void) { return _b_autoloop;};
inline void setShowToolbar(BOOL showtoolbar)
{
_b_toolbar = showtoolbar;
setDirty(TRUE);
};
inline BOOL getShowToolbar(void) { return _b_toolbar;};
void setVolume(int volume);
int getVolume(void) { return _i_volume; };
void setBackColor(OLE_COLOR backcolor);
OLE_COLOR getBackColor(void) { return _i_backcolor; };
void setVisible(BOOL fVisible);
BOOL getVisible(void) { return _b_visible; };
BOOL isVisible(void) { return _b_visible || (! _b_usermode); };
inline void setStartTime(int time)
{
_i_time = time;
setDirty(TRUE);
};
inline int getStartTime(void) { return _i_time; };
void setTime(int time);
int getTime(void) { return _i_time; };
void setBaseURL(BSTR url)
{
SysFreeString(_bstr_baseurl);
_bstr_baseurl = SysAllocStringLen(url, SysStringLen(url));
setDirty(TRUE);
};
const BSTR getBaseURL(void) { return _bstr_baseurl; };
// control size in HIMETRIC
inline void setExtent(const SIZEL& extent)
{
_extent = extent;
setDirty(TRUE);
};
const SIZEL& getExtent(void) { return _extent; };
// transient properties
inline void setMute(BOOL mute) { _b_mute = mute; };
inline void setPicture(LPPICTURE pict)
{
if( NULL != _p_pict )
_p_pict->Release();
if( NULL != pict )
pict->AddRef();
_p_pict = pict;
};
inline LPPICTURE getPicture(void)
{
if( NULL != _p_pict )
_p_pict->AddRef();
return _p_pict;
};
BOOL hasFocus(void);
void setFocus(BOOL fFocus);
inline UINT getCodePage(void) { return _i_codepage; };
inline void setCodePage(UINT cp)
{
// accept new codepage only if it works on this system
size_t mblen = WideCharToMultiByte(cp,
0, L"test", -1, NULL, 0, NULL, NULL);
if( mblen > 0 )
_i_codepage = cp;
};
inline BOOL isUserMode(void) { return _b_usermode; };
inline void setUserMode(BOOL um) { _b_usermode = um; };
inline BOOL isDirty(void) { return _b_dirty; };
inline void setDirty(BOOL dirty) { _b_dirty = dirty; };
inline BOOL isRunning(void) { return NULL != _p_libvlc; };
HRESULT getVLC(libvlc_instance_t** pp_libvlc)
{
if( !isRunning() )
initVLC();
*pp_libvlc = _p_libvlc;
return _p_libvlc ? S_OK : E_FAIL;
}
HRESULT getMD(libvlc_media_player_t **pp_md)
{
*pp_md = _p_mplayer;
return _p_mplayer ? S_OK : E_FAIL;
}
void setErrorInfo(REFIID riid, const char *description);
// control geometry within container
RECT getPosRect(void) { return _posRect; };
inline HWND getInPlaceWindow(void) const { return _inplacewnd; };
BOOL isInPlaceActive(void);
/*
** container events
*/
HRESULT onInit(void);
HRESULT onLoad(void);
HRESULT onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprcPosRect, LPCRECT lprcClipRect);
HRESULT onInPlaceDeactivate(void);
HRESULT onAmbientChanged(LPUNKNOWN pContainer, DISPID dispID);
HRESULT onClose(DWORD dwSaveOption);
void onPositionChange(LPCRECT lprcPosRect, LPCRECT lprcClipRect);
void onDraw(DVTARGETDEVICE * ptd, HDC hicTargetDev,
HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds);
void onPaint(HDC hdc, const RECT &bounds, const RECT &pr);
/*
** control events
*/
void freezeEvents(BOOL freeze);
void firePropChangedEvent(DISPID dispid);
void fireOnPlayEvent(void);
void fireOnPauseEvent(void);
void fireOnStopEvent(void);
// async events;
void fireOnMediaPlayerNothingSpecialEvent();
void fireOnMediaPlayerOpeningEvent();
void fireOnMediaPlayerBufferingEvent(long cache);
void fireOnMediaPlayerPlayingEvent();
void fireOnMediaPlayerPausedEvent();
void fireOnMediaPlayerForwardEvent();
void fireOnMediaPlayerBackwardEvent();
void fireOnMediaPlayerEncounteredErrorEvent();
void fireOnMediaPlayerEndReachedEvent();
void fireOnMediaPlayerStoppedEvent();
void fireOnMediaPlayerTimeChangedEvent(long time);
void fireOnMediaPlayerPositionChangedEvent(long position);
void fireOnMediaPlayerSeekableChangedEvent(VARIANT_BOOL seekable);
void fireOnMediaPlayerPausableChangedEvent(VARIANT_BOOL pausable);
// controlling IUnknown interface
LPUNKNOWN pUnkOuter;
/*
** libvlc interface
*/
bool isPlaying()
{
return _p_mplayer && libvlc_media_player_is_playing(_p_mplayer);
}
int playlist_get_current_index() { return _i_midx; }
int playlist_add_extended_untrusted(const char *, int, const char **);
void playlist_delete_item(int idx)
{
if( _p_mlist )
{
libvlc_media_list_lock(_p_mlist);
libvlc_media_list_remove_index(_p_mlist,idx);
libvlc_media_list_unlock(_p_mlist);
}
}
void playlist_clear()
{
if( !_p_libvlc )
return;
if( _p_mlist )
libvlc_media_list_release(_p_mlist);
_p_mlist = libvlc_media_list_new(_p_libvlc);
}
int playlist_count()
{
int r = 0;
if( !_p_mlist )
return 0;
libvlc_media_list_lock(_p_mlist);
r = libvlc_media_list_count(_p_mlist);
libvlc_media_list_unlock(_p_mlist);
return r;
}
void playlist_pause()
{
if( isPlaying() )
libvlc_media_player_pause(_p_mplayer);
}
void playlist_play()
{
if( _p_mplayer || playlist_select(0) )
libvlc_media_player_play(_p_mplayer);
}
void playlist_play_item(int idx)
{
if( playlist_select(idx) )
libvlc_media_player_play(_p_mplayer);
}
void playlist_stop()
{
if( _p_mplayer )
libvlc_media_player_stop(_p_mplayer);
}
void playlist_next()
{
if( playlist_select( _i_midx+1 ) )
libvlc_media_player_play(_p_mplayer);
}
void playlist_prev()
{
if( playlist_select( _i_midx-1 ) )
libvlc_media_player_play(_p_mplayer);
}
protected:
virtual ~VLCPlugin();
private:
void initVLC();
bool playlist_select(int i);
void set_player_window();
void player_register_events();
void player_unregister_events();
//implemented interfaces
class VLCOleObject *vlcOleObject;
class VLCOleControl *vlcOleControl;
class VLCOleInPlaceObject *vlcOleInPlaceObject;
class VLCOleInPlaceActiveObject *vlcOleInPlaceActiveObject;
class VLCPersistStreamInit *vlcPersistStreamInit;
class VLCPersistStorage *vlcPersistStorage;
class VLCPersistPropertyBag *vlcPersistPropertyBag;
class VLCProvideClassInfo *vlcProvideClassInfo;
class VLCConnectionPointContainer *vlcConnectionPointContainer;
class VLCObjectSafety *vlcObjectSafety;
class VLCControl *vlcControl;
class VLCControl2 *vlcControl2;
class VLCViewObject *vlcViewObject;
class VLCDataObject *vlcDataObject;
class VLCSupportErrorInfo *vlcSupportErrorInfo;
// in place activated window (Plugin window)
HWND _inplacewnd;
VLCPluginClass* _p_class;
ULONG _i_ref;
libvlc_instance_t *_p_libvlc;
libvlc_media_list_t *_p_mlist;
libvlc_media_player_t *_p_mplayer;
int _i_midx;
UINT _i_codepage;
BOOL _b_usermode;
RECT _posRect;
LPPICTURE _p_pict;
// persistable properties
BSTR _bstr_baseurl;
BSTR _bstr_mrl;
BOOL _b_autoplay;
BOOL _b_autoloop;
BOOL _b_toolbar;
BOOL _b_visible;
BOOL _b_mute;
int _i_volume;
int _i_time;
SIZEL _extent;
OLE_COLOR _i_backcolor;
// indicates whether properties needs persisting
BOOL _b_dirty;
};
#endif
/*****************************************************************************
* position.h: Support routines for logo and marquee plugin objects
*****************************************************************************
* Copyright (C) 2010 M2X BV
*
* Authors: JP Dinger <jpd (at) videolan (dot) org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef POSITION_H
#define POSITION_H
struct posidx_s { const char *n; size_t i; };
static const posidx_s posidx[] = {
{ "center", 0 },
{ "left", 1 },
{ "right", 2 },
{ "top", 4 },
{ "bottom", 8 },
{ "top-left", 5 },
{ "top-right", 6 },
{ "bottom-left", 9 },
{ "bottom-right", 10 },
};
enum { num_posidx = sizeof(posidx)/sizeof(*posidx) };
static inline const char *position_bynumber( size_t i )
{
for( const posidx_s *h=posidx; h<posidx+num_posidx; ++h )
if( h->i == i )
return h->n;
return "undefined";
}
static inline bool position_byname( const char *n, size_t &i )
{
for( const posidx_s *h=posidx; h<posidx+num_posidx; ++h )
if( !strcasecmp( n, h->n ) )
{ i=h->i; return true; }
return false;
}
#endif
/*****************************************************************************
* provideclassinfo.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "provideclassinfo.h"
using namespace std;
STDMETHODIMP VLCProvideClassInfo::GetClassInfo(ITypeInfo **ppTI)
{
ITypeLib *p_typelib;
if( NULL == ppTI )
return E_POINTER;
HRESULT hr = _p_instance->getTypeLib(LOCALE_NEUTRAL, &p_typelib);
if( SUCCEEDED(hr) )
{
hr = p_typelib->GetTypeInfoOfGuid(_p_instance->getClassID(), ppTI);
if( FAILED(hr) )
{
*ppTI = NULL;
}
p_typelib->Release();
}
return hr;
};
STDMETHODIMP VLCProvideClassInfo::GetGUID(DWORD dwGuidKind, GUID *pGUID)
{
if( GUIDKIND_DEFAULT_SOURCE_DISP_IID != dwGuidKind )
return E_INVALIDARG;
if( NULL == pGUID )
return E_POINTER;
*pGUID = _p_instance->getDispEventID();
return S_OK;
};
/*****************************************************************************
* provideclassinfo.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __PROVIDECLASSINFO_H__
#define __PROVIDECLASSINFO_H__
#include <ocidl.h>
class VLCProvideClassInfo : public IProvideClassInfo2
{
public:
VLCProvideClassInfo(VLCPlugin *p_instance) : _p_instance(p_instance) {};
virtual ~VLCProvideClassInfo() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IProvideClassInfo == riid)
|| (IID_IProvideClassInfo2 == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IProvideClassInfo methods
STDMETHODIMP GetClassInfo(ITypeInfo **);
// IProvideClassInfo2 methods
STDMETHODIMP GetGUID(DWORD, GUID *);
private:
VLCPlugin *_p_instance;
};
#endif
/*****************************************************************************
* supporterrorinfo.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005-2010 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "supporterrorinfo.h"
#include "utils.h"
#include "axvlc_idl.h"
using namespace std;
STDMETHODIMP VLCSupportErrorInfo::InterfaceSupportsErrorInfo(REFIID riid)
{
if( (riid == IID_IVLCAudio)
|| (riid == IID_IVLCInput)
|| (riid == IID_IVLCMarquee)
|| (riid == IID_IVLCLogo)
|| (riid == IID_IVLCPlaylist)
|| (riid == IID_IVLCPlaylistItems)
|| (riid == IID_IVLCSubtitle)
|| (riid == IID_IVLCVideo)
|| (riid == IID_IVLCControl2) )
{
return S_OK;
}
return S_FALSE;
};
void VLCSupportErrorInfo::setErrorInfo(LPCOLESTR progid, REFIID riid, const char *description)
{
BSTR bstrDescription = BSTRFromCStr(CP_UTF8, description);
if( NULL != bstrDescription )
{
ICreateErrorInfo* pcerrinfo;
HRESULT hr = CreateErrorInfo(&pcerrinfo);
if( SUCCEEDED(hr) )
{
IErrorInfo* perrinfo;
pcerrinfo->SetSource((LPOLESTR)progid);
pcerrinfo->SetGUID(riid);
pcerrinfo->SetDescription((LPOLESTR)bstrDescription);
hr = pcerrinfo->QueryInterface(IID_IErrorInfo, (LPVOID*) &perrinfo);
if( SUCCEEDED(hr) )
{
::SetErrorInfo(0, perrinfo);
perrinfo->Release();
}
pcerrinfo->Release();
}
SysFreeString(bstrDescription);
}
};
/*****************************************************************************
* supporterrorinfo.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2006 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __SUPPORTERRORINFO_H__
#define __SUPPORTERRORINFO_H__
#include <oaidl.h>
class VLCSupportErrorInfo : public ISupportErrorInfo
{
public:
VLCSupportErrorInfo(VLCPlugin *p_instance) :
_p_instance(p_instance)
{};
virtual ~VLCSupportErrorInfo()
{};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_ISupportErrorInfo == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// ISupportErrorInfo methods
STDMETHODIMP InterfaceSupportsErrorInfo(REFIID riid);
// VLCSupportErrorInfo methods
void setErrorInfo(LPCOLESTR progid, REFIID riid, const char *description);
private:
VLCPlugin *_p_instance;
};
#endif
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<TITLE>VLC Plugin test page</TITLE>
<STYLE>
.inputTrackerInput {
height:20;
width:30;
font-family : Arial, Helvetica, sans-serif;
font-size : 12px;
}
</STYLE>
<SCRIPT type="text/javascript" src="blueshoes-4.5/javascript/lib/LibCrossBrowser.js"></SCRIPT>
<SCRIPT type="text/javascript" src="blueshoes-4.5/javascript/lib/EventHandler.js"></SCRIPT>
<SCRIPT type="text/javascript" src="blueshoes-4.5/javascript/core/form/Bs_FormUtil.lib.js"></SCRIPT>
<SCRIPT type="text/javascript" src="blueshoes-4.5/javascript/components/slider/Bs_Slider.class.js"></SCRIPT>
<SCRIPT language="JavaScript"><!--
function init()
{
inputTracker = new Bs_Slider();
if (inputTracker)
{
inputTracker.attachOnChange(onInputTrackerChange);
inputTracker.attachOnSlideStart(onInputTrackerScrollStart);
inputTracker.attachOnSlideEnd(onInputTrackerScrollEnd);
inputTracker.width = 530;
inputTracker.height = 15;
inputTracker.minVal = 0;
inputTracker.maxVal = 1.0;
inputTracker.valueDefault = 0;
inputTracker.valueInterval = 1/530;
inputTracker.setDisabled(true);
inputTracker.imgDir = 'blueshoes-4.5/javascript/components/slider/img/';
inputTracker.setBackgroundImage('aluminumalloyvolcanic/horizontal_background.gif', 'repeat');
inputTracker.setArrowIconLeft('aluminumalloyvolcanic/horizontal_backgroundLeft.gif', 2, 19);
inputTracker.setArrowIconRight('aluminumalloyvolcanic/horizontal_backgroundRight.gif', 2, 19);
inputTracker.setSliderIcon('aluminumalloyvolcanic/horizontal_knob.gif', 15, 19);
inputTracker.useInputField = 0;
inputTracker.draw('inputTrackerDiv');
}
if( navigator.appName.indexOf("Microsoft Internet")==-1 )
{
onVLCPluginReady()
}
else if( document.readyState == 'complete' )
{
onVLCPluginReady();
}
else
{
/* Explorer loads plugins asynchronously */
document.onreadystatechange=function()
{
if( document.readyState == 'complete' )
{
onVLCPluginReady();
}
}
}
}
function getVLC(name)
{
if (window.document[name])
{
return window.document[name];
}
if (navigator.appName.indexOf("Microsoft Internet")==-1)
{
if (document.embeds && document.embeds[name])
return document.embeds[name];
}
else // if (navigator.appName.indexOf("Microsoft Internet")!=-1)
{
return document.getElementById(name);
}
}
function registerVLCEvent(event, handler)
{
var vlc = getVLC("vlc");
if (vlc) {
if (vlc.attachEvent) {
// Microsoft
vlc.attachEvent (event, handler);
} else if (vlc.addEventListener) {
// Mozilla: DOM level 2
vlc.addEventListener (event, handler, true);
} else {
// DOM level 0
eval("vlc.on" + event + " = handler");
}
}
}
function unregisterVLCEvent(event, handler)
{
var vlc = getVLC("vlc");
if (vlc) {
if (vlc.detachEvent) {
// Microsoft
vlc.detachEvent (event, handler);
} else if (vlc.removeEventListener) {
// Mozilla: DOM level 2
vlc.removeEventListener (event, handler, true);
} else {
// DOM level 0
eval("vlc.on" + event + " = null");
}
}
}
// JS VLC API callbacks
function handleMediaPlayerMediaChanged()
{
document.getElementById("info").innerHTML = "Media Changed";
}
function handle_MediaPlayerNothingSpecial()
{
document.getElementById("state").innerHTML = "Idle...";
}
function handle_MediaPlayerOpening()
{
onOpen();
}
function handle_MediaPlayerBuffering(val)
{
document.getElementById("info").innerHTML = val + "%";
}
function handle_MediaPlayerPlaying()
{
onPlay();
}
function handle_MediaPlayerPaused()
{
onPause();
}
function handle_MediaPlayerStopped()
{
onStop();
}
function handle_MediaPlayerForward()
{
document.getElementById("state").innerHTML = "Forward...";
}
function handle_MediaPlayerBackward()
{
document.getElementById("state").innerHTML = "Backward...";
}
function handle_MediaPlayerEndReached()
{
onEnd();
}
function handle_MediaPlayerEncounteredError()
{
onError();
}
function handle_MediaPlayerTimeChanged(time)
{
var vlc = getVLC("vlc");
var info = document.getElementById("info");
if( vlc )
{
var mediaLen = vlc.input.length;
if( mediaLen > 0 )
{
// seekable media
info.innerHTML = formatTime(time)+"/"+formatTime(mediaLen);
}
}
}
function handle_MediaPlayerPositionChanged(val)
{
// set javascript slider to correct position
}
function handle_MediaPlayerSeekableChanged(val)
{
setSeekable(val);
}
function handle_MediaPlayerPausableChanged(val)
{
setPauseable(val);
}
function handle_MediaPlayerTitleChanged(val)
{
//setTitle(val);
document.getElementById("info").innerHTML = "Title: " + val;
}
function handle_MediaPlayerLengthChanged(val)
{
//setMediaLength(val);
}
// VLC Plugin
function onVLCPluginReady()
{
registerVLCEvent("MediaPlayerMediaChanged", handleMediaPlayerMediaChanged);
registerVLCEvent("MediaPlayerNothingSpecial", handle_MediaPlayerNothingSpecial);
registerVLCEvent("MediaPlayerOpening", handle_MediaPlayerOpening);
registerVLCEvent("MediaPlayerBuffering", handle_MediaPlayerBuffering);
registerVLCEvent("MediaPlayerPlaying", handle_MediaPlayerPlaying);
registerVLCEvent("MediaPlayerPaused", handle_MediaPlayerPaused);
registerVLCEvent("MediaPlayerStopped", handle_MediaPlayerStopped);
registerVLCEvent("MediaPlayerForward", handle_MediaPlayerForward);
registerVLCEvent("MediaPlayerBackward", handle_MediaPlayerBackward);
registerVLCEvent("MediaPlayerEndReached", handle_MediaPlayerEndReached);
registerVLCEvent("MediaPlayerEncounteredError", handle_MediaPlayerEncounteredError);
registerVLCEvent("MediaPlayerTimeChanged", handle_MediaPlayerTimeChanged);
registerVLCEvent("MediaPlayerPositionChanged", handle_MediaPlayerPositionChanged);
registerVLCEvent("MediaPlayerSeekableChanged", handle_MediaPlayerSeekableChanged);
registerVLCEvent("MediaPlayerPausableChanged", handle_MediaPlayerPausableChanged);
registerVLCEvent("MediaPlayerTitleChanged", handle_MediaPlayerTitleChanged);
registerVLCEvent("MediaPlayerLengthChanged", handle_MediaPlayerLengthChanged);
}
function close()
{
unregisterVLCEvent('MediaPlayerMouseGrab', handleMouseGrab);
unregisterVLCEvent('MediaPlayerMouseRelease', handleMouseRelease);
unregisterVLCEvent('MediaPlayerMouseClick', handleMouseClick);
unregisterVLCEvent("MediaPlayerMediaChanged", handleMediaPlayerMediaChanged);
unregisterVLCEvent("MediaPlayerNothingSpecial", handle_MediaPlayerNothingSpecial);
unregisterVLCEvent("MediaPlayerOpening", handle_MediaPlayerOpening);
unregisterVLCEvent("MediaPlayerBuffering", handle_MediaPlayerBuffering);
unregisterVLCEvent("MediaPlayerPlaying", handle_MediaPlayerPlaying);
unregisterVLCEvent("MediaPlayerPaused", handle_MediaPlayerPaused);
unregisterVLCEvent("MediaPlayerStopped", handle_MediaPlayerStopped);
unregisterVLCEvent("MediaPlayerForward", handle_MediaPlayerForward);
unregisterVLCEvent("MediaPlayerBackward", handle_MediaPlayerBackward);
unregisterVLCEvent("MediaPlayerEndReached", handle_MediaPlayerEndReached);
unregisterVLCEvent("MediaPlayerEncounteredError", handle_MediaPlayerEncounteredError);
unregisterVLCEvent("MediaPlayerTimeChanged", handle_MediaPlayerTimeChanged);
unregisterVLCEvent("MediaPlayerPositionChanged", handle_MediaPlayerPositionChanged);
unregisterVLCEvent("MediaPlayerSeekableChanged", handle_MediaPlayerSeekableChanged);
unregisterVLCEvent("MediaPlayerPausableChanged", handle_MediaPlayerPausableChanged);
unregisterVLCEvent("MediaPlayerTitleChanged", handle_MediaPlayerTitleChanged);
unregisterVLCEvent("MediaPlayerLengthChanged", handle_MediaPlayerLengthChanged);
}
//--></SCRIPT>
<BODY onLoad="init();" onClose="close();>
<TABLE>
<TR><TD colspan="2">
MRL:
<INPUT size="90" id="targetTextField" value="">
<INPUT type=submit value="Go" onClick="doGo(document.getElementById('targetTextField').value);">
<INPUT type=submit value="Add" onClick="doAdd(document.getElementById('targetTextField').value);">
</TD></TR>
<TR><TD align="center" colspan="2">
<!--
Insert VideoLAN.VLCPlugin.2
-->
<OBJECT classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921"
width="640"
height="480"
id="vlc"
events="True">
<param name="MRL" value="" />
<param name="ShowDisplay" value="True" />
<param name="AutoLoop" value="False" />
<param name="AutoPlay" value="False" />
<param name="Volume" value="50" />
<param name="toolbar" value="true" />
<param name="StartTime" value="0" />
<EMBED pluginspage="http://www.videolan.org"
type="application/x-vlc-plugin"
version="VideoLAN.VLCPlugin.2"
width="640"
height="480"
toolbar="true"
text="Waiting for video"
name="vlc">
</EMBED>
</OBJECT>
</TD></TR>
<TR><TD colspan="2">
<TABLE><TR>
<TD valign="top" width="550">
<!--
Insert Slider widget
-->
<DIV id="inputTrackerDiv"</DIV>
</TD><TD width="15%">
<DIV id="info" style="text-align:center">-:--:--/-:--:--</DIV>
<DIV id="state" style="text-align:center">Stopped...</DIV>
</TD></TR></TABLE>
</TD></TR>
<TR><TD>
<INPUT type=button id="PlayOrPause" value=" Play " onClick='doPlayOrPause();'>
<INPUT type=button value="Stop" onClick='doStop();'>
&nbsp;
<INPUT type=button value=" << " onClick='doPlaySlower();'>
<INPUT type=button value="Reverse" onClick='doReverse();'>
<INPUT type=button value=" >> " onClick='doPlayFaster();'>
&nbsp;
<INPUT type=button value="Fullscreen" onClick='getVLC("vlc").video.toggleFullscreen();'>
<INPUT type=button value="Version" onClick='alert("vlc " + getVLC("vlc").VersionInfo);'>
<INPUT type=button value=" State " onClick='alert("state: " + getVLC("vlc").input.state);'>
</TD><TD align="right">
<SPAN style="text-align:center">Volume:</SPAN>
<INPUT type=button value=" - " onClick='updateVolume(-10)'>
<SPAN id="volumeTextField" style="text-align:center">--</SPAN>
<INPUT type=button value=" + " onClick='updateVolume(+10)'>
<INPUT type=button value="Mute" onClick='getVLC("vlc").audio.toggleMute();'>
</TD>
</TR>
<TR><TD>Playlist:
<INPUT type=button value="Prev" onClick='getVLC("vlc").playlist.prev();'>
<INPUT type=button value="Next" onClick='getVLC("vlc").playlist.next();'>
<INPUT type=button value="Clear All" onClick='doPlaylistClearAll();'>
Aspect Ratio:
<SELECT readonly onChange='doAspectRatio(this.value)'>
<OPTION value="default">Default</OPTION>
<OPTION value="1:1">1:1</OPTION>
<OPTION value="4:3">4:3</OPTION>
<OPTION value="16:9">16:9</OPTION>
<OPTION value="221:100">221:100</OPTION>
<OPTION value="5:4">5:4</OPTION>
</SELECT>
</TD><TD align="right">
<INPUT type=button id="itemCount" value=" Items 0 " onClick='doItemCount();'>
<INPUT size=4 value="" id="removeid"><INPUT type=submit value="Delete" onClick="doRemoveItem(document.getElementById('removeid').value);">
</TD>
</TR>
<TR><TD>Audio Channel:
<SELECT readonly onClick='doAudioChannel(this.value);'>
<OPTION value=1>Stereo</OPTION>
<OPTION value=2>Reverse Stereo</OPTION>
<OPTION value=3>Left</OPTION>
<OPTION value=4>Right</OPTION>
<OPTION value=5>Dolby</OPTION>
</SELECT>
</TD>
<TD>
<INPUT type=button value="current channel" onClick='alert(getVLC("vlc").audio.channel);'>
</TD>
</TR>
<TR><TD> Audio Track:
<INPUT type=button value=" + " onClick='doAudioTrack(1);'>
<SPAN id="trackTextField" style="text-align:center">--</SPAN>
<INPUT type=button value=" - " onClick='doAudioTrack(-1);'>
<INPUT type=button value="current track" onClick='alert(getVLC("vlc").audio.description(vlc.audio.track));'>
<INPUT type=button value="number of track" onClick='alert(getVLC("vlc").audio.count);'>
</TD>
<TD>
<INPUT type=button value="set slider" onClick='doSetSlider();'>
<INPUT type=button value="get position" onClick='doGetPosition();'>
</TD>
</TR>
<TR>
<TD>Video Subtitle:
<INPUT type=button value=" + " onClick='doSubtitle(1);'>
<SPAN id="spuTextField" style="text-align:center">--</SPAN>
<INPUT type=button value=" - " onClick='doSubtitle(-1);'>
<INPUT type=button value="current subtitle" onClick='alert(getVLC("vlc").subtitle.description(vlc.subtitle.track));'>
<INPUT type=button value="number of subtitle" onClick='alert(getVLC("vlc").subtitle.count);'>
</TD>
</TR>
<TR>
<TD>Deinterlacing:
<INPUT type=button value="BLEND" onClick='getVLC("vlc").video.deinterlace.enable("blend");'>
<INPUT type=button value=" X " onClick='getVLC("vlc").video.deinterlace.enable("x");'>
<INPUT type=button value="Disable" onClick='getVLC("vlc").video.deinterlace.disable();'>
</TD>
</TR>
<TR>
<TD>Marquee video filter:
<INPUT type=button value="Enable" onClick='getVLC("vlc").video.marquee.enable();'>
<INPUT type=button value="Disable" onClick='getVLC("vlc").video.marquee.disable();'>
<INPUT size=4 value="" id="marqueeIntValue">
<SELECT readonly onClick="doMarqueeOption(this.value,document.getElementById('marqueeIntValue').value);">
<OPTION value=1>Color</OPTION>
<OPTION value=2>Opacity</OPTION>
<OPTION value=3>Position</OPTION>
<OPTION value=4>Refresh</OPTION>
<OPTION value=5>Size</OPTION>
<OPTION value=6>Text</OPTION>
<OPTION value=7>Timeout</OPTION>
<OPTION value=8>X</OPTION>
<OPTION value=9>Y</OPTION>
</SELECT>
</TD>
</TR>
<TR>
<TD>Logo video filter:
<INPUT type=button value="Enable" onClick='getVLC("vlc").video.logo.enable();'>
<INPUT type=button value="Disable" onClick='getVLC("vlc").video.logo.disable();'>
<INPUT size=4 value="" id="logoIntValue">
<SELECT readonly onClick="doLogoOption(this.value,document.getElementById('logoIntValue').value);">
<OPTION value=1>File</OPTION>
<OPTION value=2>Position</OPTION>
<OPTION value=3>Opacity</OPTION>
<OPTION value=4>Repeat</OPTION>
<OPTION value=5>Delay</OPTION>
<OPTION value=6>X</OPTION>
<OPTION value=7>Y</OPTION>
</SELECT>
</TD>
</TR>
<TR>
<TD>
<INPUT type=button id="telx" value="Teletext off" onClick='doToggleTeletext();'>
Teletext page:
<INPUT size=4 value="100" id="telxPage" onClick='doTelxPage(document.getElementById("telxPage").value);'>
</TD>
</TR>
</TABLE>
<SCRIPT language="javascript">
<!--
var rate = 0;
var prevState = 0;
var monitorTimerId = 0;
var inputTracker;
var inputTrackerScrolling = false;
var inputTrackerIgnoreChange = false;
var telxState = false;
var canPause = true;
var canSeek = true;
function setPauseable(val)
{
canPause = val;
}
function setSeekable(val)
{
canSeek = val;
}
function doSetSlider()
{
var vlc = getVLC("vlc");
// set slider to new position
if( vlc )
vlc.input.time = (vlc.input.length/2);
}
function doGetPosition()
{
var vlc = getVLC("vlc");
// set slider to new position
if (vlc)
alert( "position is " + vlc.input.time);
}
function doReverse(rate)
{
var vlc = getVLC("vlc");
if( vlc )
vlc.input.rate = -1.0 * vlc.input.rate;
}
function doAudioChannel(value)
{
var vlc = getVLC("vlc");
if( vlc )
vlc.audio.channel = parseInt(value);
}
function doAudioTrack(value)
{
var vlc = getVLC("vlc");
if( vlc )
{
vlc.audio.track = vlc.audio.track + value;
document.getElementById("trackTextField").innerHTML = vlc.audio.track;
}
}
function doAspectRatio(value)
{
var vlc = getVLC("vlc");
if( vlc )
vlc.video.aspectRatio = value;
}
function doSubtitle(value)
{
var vlc = getVLC("vlc");
if( vlc )
{
vlc.subtitle.track = vlc.subtitle.track + value;
document.getElementById("spuTextField").innerHTML = vlc.subtitle.track;
}
}
function doTelxPage(value)
{
var vlc = getVLC("vlc");
if( vlc )
vlc.video.teletext = parseInt(value);
}
function doToggleTeletext()
{
var vlc = getVLC("vlc");
if( vlc )
{
vlc.video.toggleTeletext();
if (telxState)
{
document.getElementById("telx").innerHTML = "Teletext on";
telxState = true;
}
else
{
document.getElementById("telx").innerHTML = "Teletext off";
telxState = false;
}
}
}
function doItemCount()
{
var vlc = getVLC("vlc");
if( vlc )
{
var count = vlc.playlist.items.count;
document.getElementById("itemCount").value = " Items " + count + " ";
}
}
function doRemoveItem(item)
{
var vlc = getVLC("vlc");
if( vlc )
vlc.playlist.items.remove(item);
}
function doPlaylistClearAll()
{
var vlc = getVLC("vlc");
if( vlc )
{
vlc.playlist.items.clear();
while( vlc.playlist.items.count > 0)
{
// wait till playlist empties.
}
doItemCount();
}
}
function updateVolume(deltaVol)
{
var vlc = getVLC("vlc");
if( vlc )
{
vlc.audio.volume += deltaVol;
document.getElementById("volumeTextField").innerHTML = vlc.audio.volume+"%";
}
}
function formatTime(timeVal)
{
if( typeof timeVal != 'number' )
return "-:--:--";
var timeHour = Math.round(timeVal / 1000);
var timeSec = timeHour % 60;
if( timeSec < 10 )
timeSec = '0'+timeSec;
timeHour = (timeHour - timeSec)/60;
var timeMin = timeHour % 60;
if( timeMin < 10 )
timeMin = '0'+timeMin;
timeHour = (timeHour - timeMin)/60;
if( timeHour > 0 )
return timeHour+":"+timeMin+":"+timeSec;
else
return timeMin+":"+timeSec;
}
function doState()
{
var vlc = getVLC("vlc");
var newState = 0;
if( vlc )
newState = vlc.input.state;
if( newState == 0 )
{
// current media has stopped
onEnd();
}
else if( newState == 1 )
{
// current media is openning/connecting
onOpen();
}
else if( newState == 2 )
{
// current media is buffering data
onBuffer();
}
else if( newState == 3 )
{
// current media is now playing
onPlay();
}
else if( newState == 4 )
{
// current media is now paused
onPause();
}
else if( newState == 5 )
{
// current media has stopped
onStop();
}
else if( newState == 6 )
{
// current media has ended
onEnd();
}
else if( newState == 7 )
{
// current media encountered error
onError();
}
}
function monitor()
{
var vlc = getVLC("vlc");
var newState = 0;
if( vlc )
{
newState = vlc.input.state;
}
if( prevState != newState )
{
if( newState == 0 )
{
// current media has stopped
onEnd();
}
else if( newState == 1 )
{
// current media is openning/connecting
onOpen();
}
else if( newState == 2 )
{
// current media is buffering data
onBuffer();
}
else if( newState == 3 )
{
// current media is now playing
onPlay();
}
else if( newState == 4 )
{
// current media is now paused
onPause();
}
else if( newState == 5 )
{
// current media has stopped
onStop();
}
else if( newState == 6 )
{
// current media has ended
onEnd();
}
else if( newState == 7 )
{
// current media encountered error
onError();
}
prevState = newState;
}
else if( newState == 3 )
{
// current media is playing
onPlaying();
}
if( monitorTimerId == 0 )
{
monitorTimerId = setInterval("monitor()", 1000);
}
};
/* actions */
function doGo(targetURL)
{
var vlc = getVLC("vlc");
if( vlc )
{
vlc.playlist.items.clear();
while( vlc.playlist.items.count > 0 )
{
// clear() may return before the playlist has actually been cleared
// just wait for it to finish its job
}
var options = [":rtsp-tcp"];
var itemId = vlc.playlist.add(targetURL,"",options);
options = [];
if( itemId != -1 )
{
// play MRL
vlc.playlist.playItem(itemId);
if( monitorTimerId == 0 )
{
monitor();
}
}
else
{
alert("cannot play at the moment !");
}
doItemCount();
}
}
function doAdd(targetURL)
{
var vlc = getVLC("vlc");
var options = [":vout-filter=deinterlace", ":deinterlace-mode=linear"];
if( vlc )
{
vlc.playlist.add(targetURL, "", options);
options = [];
doItemCount();
}
}
function doPlayOrPause()
{
var vlc = getVLC("vlc");
if( vlc )
{
if( vlc.playlist.isPlaying && canPause )
{
vlc.playlist.togglePause();
//monitor();
}
else if( vlc.playlist.items.count > 0 )
{
vlc.playlist.play();
//monitor();
}
else
{
alert('nothing to play !');
}
}
}
function doStop()
{
var vlc = getVLC("vlc");
if( vlc )
vlc.playlist.stop();
if( monitorTimerId != 0 )
{
clearInterval(monitorTimerId);
monitorTimerId = 0;
}
onStop();
}
function doPlaySlower()
{
var vlc = getVLC("vlc");
if( vlc )
vlc.input.rate = vlc.input.rate / 2;
}
function doPlayFaster()
{
var vlc = getVLC("vlc");
if( vlc )
vlc.input.rate = vlc.input.rate * 2;
}
function doMarqueeOption(option, value)
{
var vlc = getVLC("vlc");
val = parseInt(value);
if( vlc )
{
if (option == 1)
vlc.video.marquee.color = val;
if (option == 2)
vlc.video.marquee.opacity = val;
if (option == 3)
vlc.video.marquee.position = value;
if (option == 4)
vlc.video.marquee.refresh = val;
if (option == 5)
vlc.video.marquee.size = val;
if (option == 6)
vlc.video.marquee.text = value;
if (option == 7)
vlc.video.marquee.timeout = val;
if (option == 8)
vlc.video.marquee.x = val;
if (option == 9)
vlc.video.marquee.y = val;
}
}
function doLogoOption(option, value)
{
var vlc = getVLC("vlc");
if( vlc )
{
if (option == 1)
vlc.video.logo.file(value);
if (option == 2)
vlc.video.logo.position = value;
val = parseInt(value);
if (option == 3)
vlc.video.logo.opacity = val;
if (option == 4)
vlc.video.logo.repeat = val;
if (option == 5)
vlc.video.logo.delay = val;
if (option == 6)
vlc.video.logo.x = val;
if (option == 7)
vlc.video.logo.y = val;
}
}
/* events */
function onOpen()
{
document.getElementById("state").innerHTML = "Opening...";
document.getElementById("PlayOrPause").value = "Pause";
}
function onBuffer()
{
document.getElementById("state").innerHTML = "Buffering...";
document.getElementById("PlayOrPause").value = "Pause";
}
function onPlay()
{
document.getElementById("state").innerHTML = "Playing...";
document.getElementById("PlayOrPause").value = "Pause";
onPlaying();
}
function onEnd()
{
document.getElementById("state").innerHTML = "End...";
}
var liveFeedText = ["Live", "((Live))", "(( Live ))", "(( Live ))"];
var liveFeedRoll = 0;
function onPlaying()
{
if( !inputTrackerScrolling )
{
var vlc = getVLC("vlc");
var info = document.getElementById("info");
if( vlc )
{
var mediaLen = vlc.input.length;
inputTrackerIgnoreChange = true;
if( mediaLen > 0 )
{
// seekable media
if( inputTracker )
{
if( inputTracker.maxVal == 1.0 )
{
inputTracker.setDisabled(false);
inputTracker.maxVal = 1.0;
}
inputTracker.setValue(vlc.input.position);
}
info.innerHTML = formatTime(vlc.input.time)+"/"+formatTime(mediaLen);
}
else
{
// non-seekable "live" media
if( inputTracker )
{
if( inputTracker.maxVal != 0.0 )
{
inputTracker.maxVal = 0.0;
inputTracker.setValue(0.0);
inputTracker.setDisabled(true);
}
}
liveFeedRoll = liveFeedRoll & 3;
info.innerHTML = liveFeedText[liveFeedRoll++];
}
inputTrackerIgnoreChange = false;
}
}
}
function onPause()
{
document.getElementById("state").innerHTML = "Paused...";
document.getElementById("PlayOrPause").value = " Play ";
}
function onStop()
{
var vlc = getVLC("vlc");
if( inputTracker )
{
if( !inputTracker.disabled )
{
inputTracker.setValue(inputTracker.minVal);
inputTracker.setDisabled(true);
}
}
document.getElementById("info").innerHTML = "-:--:--/-:--:--";
document.getElementById("state").innerHTML = "Stopped...";
document.getElementById("PlayOrPause").value = " Play ";
}
function onError()
{
var vlc = getVLC("vlc");
document.getElementById("state").innerHTML = "Error...";
}
function onInputTrackerScrollStart()
{
inputTrackerScrolling = true;
}
function onInputTrackerScrollEnd(inputTracker, value, pos)
{
inputTrackerScrolling = false;
}
function onInputTrackerChange(inputTracker, value, pos)
{
if( !inputTrackerIgnoreChange )
{
var vlc = getVLC("vlc");
if( vlc )
{
if( (vlc.input.state == 3) && (vlc.input.position != value) )
{
var info = document.getElementById("info");
vlc.input.position = value;
info.innerHTML = formatTime(vlc.input.time)+"/"+formatTime(vlc.input.length);
}
}
}
}
//-->
</SCRIPT>
</BODY>
</HTML>
/*****************************************************************************
* utils.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "utils.h"
#include <wchar.h>
#include <wctype.h>
/*
** conversion facilities
*/
using namespace std;
char *CStrFromWSTR(UINT codePage, LPCWSTR wstr, UINT len)
{
if( len > 0 )
{
size_t mblen = WideCharToMultiByte(codePage,
0, wstr, len, NULL, 0, NULL, NULL);
if( mblen > 0 )
{
char *buffer = (char *)CoTaskMemAlloc(mblen+1);
ZeroMemory(buffer, mblen+1);
if( WideCharToMultiByte(codePage, 0, wstr, len, buffer, mblen, NULL, NULL) )
{
buffer[mblen] = '\0';
return buffer;
}
}
}
return NULL;
};
char *CStrFromBSTR(UINT codePage, BSTR bstr)
{
return CStrFromWSTR(codePage, bstr, SysStringLen(bstr));
};
BSTR BSTRFromCStr(UINT codePage, LPCSTR s)
{
int wideLen = MultiByteToWideChar(codePage, 0, s, -1, NULL, 0);
if( wideLen > 0 )
{
WCHAR* wideStr = (WCHAR*)CoTaskMemAlloc(wideLen*sizeof(WCHAR));
if( NULL != wideStr )
{
BSTR bstr;
ZeroMemory(wideStr, wideLen*sizeof(WCHAR));
MultiByteToWideChar(codePage, 0, s, -1, wideStr, wideLen);
bstr = SysAllocStringLen(wideStr, wideLen-1);
CoTaskMemFree(wideStr);
return bstr;
}
}
return NULL;
};
/*
** properties
*/
HRESULT GetObjectProperty(LPUNKNOWN object, DISPID dispID, VARIANT& v)
{
IDispatch *pDisp;
HRESULT hr = object->QueryInterface(IID_IDispatch, (LPVOID *)&pDisp);
if( SUCCEEDED(hr) )
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
VARIANT vres;
VariantInit(&vres);
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET, &dispparamsNoArgs, &vres, NULL, NULL);
if( SUCCEEDED(hr) )
{
if( V_VT(&v) != V_VT(&vres) )
{
hr = VariantChangeType(&v, &vres, 0, V_VT(&v));
VariantClear(&vres);
}
else
{
v = vres;
}
}
pDisp->Release();
}
return hr;
};
HDC CreateDevDC(DVTARGETDEVICE *ptd)
{
HDC hdc;
if( NULL == ptd )
{
hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
}
else
{
LPDEVNAMES lpDevNames = (LPDEVNAMES) ptd; // offset for size field
LPDEVMODE lpDevMode = NULL;
if (ptd->tdExtDevmodeOffset != 0)
lpDevMode = (LPDEVMODE) ((LPTSTR)ptd + ptd->tdExtDevmodeOffset);
hdc = CreateDC( (LPTSTR) lpDevNames + ptd->tdDriverNameOffset,
(LPTSTR) lpDevNames + ptd->tdDeviceNameOffset,
(LPTSTR) lpDevNames + ptd->tdPortNameOffset,
lpDevMode );
}
return hdc;
};
#define HIMETRIC_PER_INCH 2540
void DPFromHimetric(HDC hdc, LPPOINT pt, int count)
{
LONG lpX = GetDeviceCaps(hdc, LOGPIXELSX);
LONG lpY = GetDeviceCaps(hdc, LOGPIXELSY);
while( count-- )
{
pt->x = pt->x*lpX/HIMETRIC_PER_INCH;
pt->y = pt->y*lpY/HIMETRIC_PER_INCH;
++pt;
}
};
void HimetricFromDP(HDC hdc, LPPOINT pt, int count)
{
LONG lpX = GetDeviceCaps(hdc, LOGPIXELSX);
LONG lpY = GetDeviceCaps(hdc, LOGPIXELSY);
while( count-- )
{
pt->x = pt->x*HIMETRIC_PER_INCH/lpX;
pt->y = pt->y*HIMETRIC_PER_INCH/lpY;
++pt;
}
};
LPWSTR CombineURL(LPCWSTR baseUrl, LPCWSTR url)
{
if( NULL != url )
{
// check whether URL is already absolute
const wchar_t *end=wcschr(url, L':');
if( (NULL != end) && (end != url) )
{
// validate protocol header
const wchar_t *start = url;
wchar_t c = *start;
if( iswalpha(c) )
{
++start;
while( start != end )
{
c = *start;
if( ! (iswalnum(c)
|| (L'-' == c)
|| (L'+' == c)
|| (L'.' == c)
|| (L'/' == c)) ) /* VLC uses / to allow user to specify a demuxer */
// not valid protocol header, assume relative URL
goto relativeurl;
++start;
}
/* we have a protocol header, therefore URL is absolute */
UINT len = wcslen(url);
wchar_t *href = (LPWSTR)CoTaskMemAlloc((len+1)*sizeof(wchar_t));
if( href )
{
memcpy(href, url, len*sizeof(wchar_t));
href[len] = L'\0';
}
return href;
}
}
relativeurl:
if( baseUrl )
{
size_t baseLen = wcslen(baseUrl);
wchar_t *href = (LPWSTR)CoTaskMemAlloc((baseLen+wcslen(url)+1)*sizeof(wchar_t));
if( href )
{
/* prepend base URL */
wcscpy(href, baseUrl);
/*
** relative url could be empty,
** in which case return base URL
*/
if( L'\0' == *url )
return href;
/*
** locate pathname part of base URL
*/
/* skip over protocol part */
wchar_t *pathstart = wcschr(href, L':');
wchar_t *pathend;
if( pathstart )
{
if( L'/' == *(++pathstart) )
{
if( L'/' == *(++pathstart) )
{
++pathstart;
}
}
/* skip over host part */
pathstart = wcschr(pathstart, L'/');
pathend = href+baseLen;
if( ! pathstart )
{
// no path, add a / past end of url (over '\0')
pathstart = pathend;
*pathstart = L'/';
}
}
else
{
/* baseURL is just a UNIX file path */
if( L'/' != *href )
{
/* baseURL is not an absolute path */
return NULL;
}
pathstart = href;
pathend = href+baseLen;
}
/* relative URL made of an absolute path ? */
if( L'/' == *url )
{
/* replace path completely */
wcscpy(pathstart, url);
return href;
}
/* find last path component and replace it */
while( L'/' != *pathend )
--pathend;
/*
** if relative url path starts with one or more './' or '../',
** factor them out of href so that we return a
** normalized URL
*/
while( pathend > pathstart )
{
const wchar_t *p = url;
if( L'.' != *p )
break;
++p;
if( L'\0' == *p )
{
/* relative url is just '.' */
url = p;
break;
}
if( L'/' == *p )
{
/* relative url starts with './' */
url = ++p;
continue;
}
if( L'.' != *p )
break;
++p;
if( L'\0' == *p )
{
/* relative url is '..' */
}
else
{
if( L'/' != *p )
break;
/* relative url starts with '../' */
++p;
}
url = p;
do
{
--pathend;
}
while( L'/' != *pathend );
}
/* skip over '/' separator */
++pathend;
/* concatenate remaining base URL and relative URL */
wcscpy(pathend, url);
}
return href;
}
}
return NULL;
}
/*****************************************************************************
* utils.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __UTILS_H__
#define __UTILS_H__
#include <ole2.h>
#include <vector>
// utilities
extern char *CStrFromWSTR(UINT codePage, LPCWSTR wstr, UINT len);
extern char *CStrFromBSTR(UINT codePage, BSTR bstr);
extern BSTR BSTRFromCStr(UINT codePage, LPCSTR s);
// properties
extern HRESULT GetObjectProperty(LPUNKNOWN object, DISPID dispID, VARIANT& v);
// properties
extern HDC CreateDevDC(DVTARGETDEVICE *ptd);
extern void DPFromHimetric(HDC hdc, LPPOINT pt, int count);
extern void HimetricFromDP(HDC hdc, LPPOINT pt, int count);
// URL
extern LPWSTR CombineURL(LPCWSTR baseUrl, LPCWSTR url);
/**************************************************************************************************/
/* this function object is used to dereference the iterator into a value */
template <typename T, class Iterator>
struct VLCDereference
{
T operator()(const Iterator& i) const
{
return *i;
};
};
template<REFIID EnumeratorIID, class Enumerator, typename T, class Iterator, typename Dereference = VLCDereference<T, Iterator> >
class VLCEnumIterator : public Enumerator
{
public:
VLCEnumIterator(const Iterator& from, const Iterator& to) :
_refcount(1),
_begin(from),
_curr(from),
_end(to)
{};
VLCEnumIterator(const VLCEnumIterator& e) :
Enumerator(),
_refcount(e._refcount),
_begin(e._begin),
_curr(e._curr),
_end(e._end)
{};
virtual ~VLCEnumIterator()
{};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (EnumeratorIID == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
// standalone object
return E_NOINTERFACE;
};
STDMETHODIMP_(ULONG) AddRef(void)
{
return InterlockedIncrement(&_refcount);
};
STDMETHODIMP_(ULONG) Release(void)
{
ULONG refcount = InterlockedDecrement(&_refcount);
if( 0 == refcount )
{
delete this;
return 0;
}
return refcount;
};
// IEnumXXXX methods
STDMETHODIMP Next(ULONG celt, T *rgelt, ULONG *pceltFetched)
{
if( NULL == rgelt )
return E_POINTER;
if( (celt > 1) && (NULL == pceltFetched) )
return E_INVALIDARG;
ULONG c = 0;
while( (c < celt) && (_curr != _end) )
{
rgelt[c] = dereference(_curr);
++_curr;
++c;
}
if( NULL != pceltFetched )
*pceltFetched = c;
return (c == celt) ? S_OK : S_FALSE;
};
STDMETHODIMP Skip(ULONG celt)
{
ULONG c = 0;
while( (c < celt) && (_curr != _end) )
{
++_curr;
++c;
}
return (c == celt) ? S_OK : S_FALSE;
};
STDMETHODIMP Reset(void)
{
_curr = _begin;
return S_OK;
};
STDMETHODIMP Clone(Enumerator **ppEnum)
{
if( NULL == ppEnum )
return E_POINTER;
*ppEnum = dynamic_cast<Enumerator *>(new VLCEnumIterator(*this));
return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
};
private:
LONG _refcount;
Iterator _begin, _curr, _end;
Dereference dereference;
};
#endif
/*****************************************************************************
* viewobject.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "viewobject.h"
#include "utils.h"
using namespace std;
STDMETHODIMP VLCViewObject::Draw(DWORD dwAspect, LONG lindex, PVOID pvAspect,
DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprcBounds,
LPCRECTL lprcWBounds, BOOL(CALLBACK *pfnContinue)(DWORD), DWORD dwContinue)
{
if( dwAspect & DVASPECT_CONTENT )
{
if( NULL == lprcBounds )
return E_INVALIDARG;
BOOL releaseDC = FALSE;
SIZEL size = _p_instance->getExtent();
if( NULL == ptd )
{
hicTargetDev = CreateDevDC(NULL);
releaseDC = TRUE;
}
DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
RECTL bounds = { 0L, 0L, size.cx, size.cy };
int sdc = SaveDC(hdcDraw);
SetMapMode(hdcDraw, MM_ANISOTROPIC);
SetWindowOrgEx(hdcDraw, 0, 0, NULL);
SetWindowExtEx(hdcDraw, size.cx, size.cy, NULL);
OffsetViewportOrgEx(hdcDraw, lprcBounds->left, lprcBounds->top, NULL);
SetViewportExtEx(hdcDraw, lprcBounds->right-lprcBounds->left,
lprcBounds->bottom-lprcBounds->top, NULL);
_p_instance->onDraw(ptd, hicTargetDev, hdcDraw, &bounds, lprcWBounds);
RestoreDC(hdcDraw, sdc);
if( releaseDC )
DeleteDC(hicTargetDev);
return S_OK;
}
return E_NOTIMPL;
};
STDMETHODIMP VLCViewObject::Freeze(DWORD dwAspect, LONG lindex,
PVOID pvAspect, LPDWORD pdwFreeze)
{
return E_NOTIMPL;
};
STDMETHODIMP VLCViewObject::GetAdvise(LPDWORD pdwAspect, LPDWORD padvf,
LPADVISESINK *ppAdviseSink)
{
if( NULL != pdwAspect )
*pdwAspect = _dwAspect;
if( NULL != padvf )
*padvf = _advf;
if( NULL != ppAdviseSink )
{
*ppAdviseSink = _pAdvSink;
if( NULL != _pAdvSink )
_pAdvSink->AddRef();
}
return S_OK;
};
STDMETHODIMP VLCViewObject::GetColorSet(DWORD dwAspect, LONG lindex,
PVOID pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LPLOGPALETTE *ppColorSet)
{
return S_FALSE;
};
STDMETHODIMP VLCViewObject::SetAdvise(DWORD dwAspect, DWORD advf,
LPADVISESINK pAdvSink)
{
if( NULL != pAdvSink )
pAdvSink->AddRef();
if( NULL != _pAdvSink )
_pAdvSink->Release();
_dwAspect = dwAspect;
_advf = advf;
_pAdvSink = pAdvSink;
if( (dwAspect & DVASPECT_CONTENT) && (advf & ADVF_PRIMEFIRST) && (NULL != _pAdvSink) )
{
_pAdvSink->OnViewChange(DVASPECT_CONTENT, -1);
}
return S_OK;
};
STDMETHODIMP VLCViewObject::Unfreeze(DWORD dwFreeze)
{
return E_NOTIMPL;
};
STDMETHODIMP VLCViewObject::GetExtent(DWORD dwAspect, LONG lindex,
DVTARGETDEVICE *ptd, LPSIZEL lpSizel)
{
if( dwAspect & DVASPECT_CONTENT )
{
*lpSizel = _p_instance->getExtent();
return S_OK;
}
lpSizel->cx= 0L;
lpSizel->cy= 0L;
return E_NOTIMPL;
};
/*****************************************************************************
* persiststorage.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __VIEWOBJECT_H__
#define __VIEWOBJECT_H__
#include <oleidl.h>
class VLCViewObject : public IViewObject2
{
public:
VLCViewObject(VLCPlugin *p_instance) : _p_instance(p_instance),
_dwAspect(0), _advf(0), _pAdvSink(NULL) {};
virtual ~VLCViewObject() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IViewObject == riid)
|| (IID_IViewObject2 == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IViewObject methods
STDMETHODIMP Draw(DWORD,LONG,PVOID,DVTARGETDEVICE*,HDC,HDC,LPCRECTL,LPCRECTL,BOOL(CALLBACK *)(DWORD),DWORD);
STDMETHODIMP Freeze(DWORD,LONG,PVOID,LPDWORD);
STDMETHODIMP GetAdvise(LPDWORD,LPDWORD,LPADVISESINK *);
STDMETHODIMP GetColorSet(DWORD,LONG,PVOID,DVTARGETDEVICE *,HDC,LPLOGPALETTE *);
STDMETHODIMP SetAdvise(DWORD,DWORD,LPADVISESINK);
STDMETHODIMP Unfreeze(DWORD);
// IViewObject2 methods
STDMETHODIMP GetExtent(DWORD,LONG,DVTARGETDEVICE *,LPSIZEL);
private:
VLCPlugin *_p_instance;
// Advise Sink support
DWORD _dwAspect;
DWORD _advf;
LPADVISESINK _pAdvSink;
};
#endif
/*****************************************************************************
* vlccontrol.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005-2010 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
#include "vlccontrol.h"
#include "utils.h"
using namespace std;
VLCControl::~VLCControl()
{
if( _p_typeinfo )
_p_typeinfo->Release();
};
HRESULT VLCControl::getTypeInfo(void)
{
HRESULT hr = NOERROR;
if( NULL == _p_typeinfo )
{
ITypeLib *p_typelib;
hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
if( SUCCEEDED(hr) )
{
hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl, &_p_typeinfo);
if( FAILED(hr) )
{
_p_typeinfo = NULL;
}
p_typelib->Release();
}
}
return hr;
};
STDMETHODIMP VLCControl::GetTypeInfoCount(UINT* pctInfo)
{
if( NULL == pctInfo )
return E_INVALIDARG;
if( SUCCEEDED(getTypeInfo()) )
*pctInfo = 1;
else
*pctInfo = 0;
return NOERROR;
};
STDMETHODIMP VLCControl::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
{
if( NULL == ppTInfo )
return E_INVALIDARG;
if( SUCCEEDED(getTypeInfo()) )
{
_p_typeinfo->AddRef();
*ppTInfo = _p_typeinfo;
return NOERROR;
}
*ppTInfo = NULL;
return E_NOTIMPL;
};
STDMETHODIMP VLCControl::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
UINT cNames, LCID lcid, DISPID* rgDispID)
{
if( SUCCEEDED(getTypeInfo()) )
{
return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
}
return E_NOTIMPL;
};
STDMETHODIMP VLCControl::Invoke(DISPID dispIdMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
if( SUCCEEDED(getTypeInfo()) )
{
return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
pVarResult, pExcepInfo, puArgErr);
}
return E_NOTIMPL;
};
STDMETHODIMP VLCControl::get_Visible(VARIANT_BOOL *isVisible)
{
if( NULL == isVisible )
return E_POINTER;
*isVisible = _p_instance->getVisible() ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
};
STDMETHODIMP VLCControl::put_Visible(VARIANT_BOOL isVisible)
{
_p_instance->setVisible(isVisible != VARIANT_FALSE);
return S_OK;
};
STDMETHODIMP VLCControl::play(void)
{
_p_instance->playlist_play();
_p_instance->fireOnPlayEvent();
return S_OK;
};
STDMETHODIMP VLCControl::pause(void)
{
libvlc_media_player_t* p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
libvlc_media_player_pause(p_md);
_p_instance->fireOnPauseEvent();
}
return result;
};
STDMETHODIMP VLCControl::stop(void)
{
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
libvlc_media_player_stop(p_md);
_p_instance->fireOnStopEvent();
}
return result;
};
STDMETHODIMP VLCControl::get_Playing(VARIANT_BOOL *isPlaying)
{
if( NULL == isPlaying )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
*isPlaying = libvlc_media_player_is_playing(p_md) ?
VARIANT_TRUE : VARIANT_FALSE;
} else *isPlaying = VARIANT_FALSE;
return result;
};
STDMETHODIMP VLCControl::get_Position(float *position)
{
if( NULL == position )
return E_POINTER;
*position = 0.0f;
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
*position = libvlc_media_player_get_position(p_md);
}
return result;
};
STDMETHODIMP VLCControl::put_Position(float position)
{
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
libvlc_media_player_set_position(p_md, position);
}
return result;
};
STDMETHODIMP VLCControl::get_Time(int *seconds)
{
if( NULL == seconds )
return E_POINTER;
*seconds = 0;
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
*seconds = libvlc_media_player_get_time(p_md);
}
return result;
};
STDMETHODIMP VLCControl::put_Time(int seconds)
{
/* setTime function of the plugin sets the time. */
_p_instance->setTime(seconds);
return S_OK;
};
STDMETHODIMP VLCControl::shuttle(int seconds)
{
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
if( seconds < 0 ) seconds = 0;
libvlc_media_player_set_time(p_md, (int64_t)seconds);
}
return result;
};
STDMETHODIMP VLCControl::fullscreen(void)
{
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
if( libvlc_media_player_is_playing(p_md) )
{
libvlc_toggle_fullscreen(p_md);
}
}
return result;
};
STDMETHODIMP VLCControl::get_Length(int *seconds)
{
if( NULL == seconds )
return E_POINTER;
*seconds = 0;
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
*seconds = (double)libvlc_media_player_get_length(p_md);
}
return result;
};
STDMETHODIMP VLCControl::playFaster(void)
{
int32_t rate = 2;
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
libvlc_media_player_set_rate(p_md, rate);
}
return result;
};
STDMETHODIMP VLCControl::playSlower(void)
{
float rate = 0.5;
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
{
libvlc_media_player_set_rate(p_md, rate);
}
return result;
};
STDMETHODIMP VLCControl::get_Volume(int *volume)
{
if( NULL == volume )
return E_POINTER;
*volume = _p_instance->getVolume();
return S_OK;
};
STDMETHODIMP VLCControl::put_Volume(int volume)
{
_p_instance->setVolume(volume);
return S_OK;
};
STDMETHODIMP VLCControl::toggleMute(void)
{
libvlc_media_player_t *p_md;
HRESULT result = _p_instance->getMD(&p_md);
if( SUCCEEDED(result) )
libvlc_audio_toggle_mute(p_md);
return result;
};
STDMETHODIMP VLCControl::setVariable(BSTR name, VARIANT value)
{
libvlc_instance_t* p_libvlc;
HRESULT result = _p_instance->getVLC(&p_libvlc);
if( SUCCEEDED(result) )
{
_p_instance->setErrorInfo(IID_IVLCControl,
"setVariable() is an unsafe interface to use. "
"It has been removed because of security implications." );
}
return E_FAIL;
};
STDMETHODIMP VLCControl::getVariable(BSTR name, VARIANT *value)
{
libvlc_instance_t* p_libvlc;
HRESULT result = _p_instance->getVLC(&p_libvlc);
if( SUCCEEDED(result) )
{
_p_instance->setErrorInfo(IID_IVLCControl,
"getVariable() is an unsafe interface to use. "
"It has been removed because of security implications." );
}
return E_FAIL;
};
void VLCControl::FreeTargetOptions(char **cOptions, int cOptionCount)
{
// clean up
if( NULL != cOptions )
{
for( int pos=0; pos<cOptionCount; ++pos )
{
char *cOption = cOptions[pos];
if( NULL != cOption )
CoTaskMemFree(cOption);
else
break;
}
CoTaskMemFree(cOptions);
}
};
static HRESULT parseStringOptions(int codePage, BSTR bstr, char*** cOptions, int *cOptionCount)
{
HRESULT hr = E_INVALIDARG;
if( SysStringLen(bstr) > 0 )
{
hr = E_OUTOFMEMORY;
char *s = CStrFromBSTR(codePage, bstr);
char *val = s;
if( val )
{
long capacity = 16;
char **options = (char **)CoTaskMemAlloc(capacity*sizeof(char *));
if( options )
{
int nOptions = 0;
char *end = val + strlen(val);
while( val < end )
{
// skip leading blanks
while( (val < end)
&& ((*val == ' ' ) || (*val == '\t')) )
++val;
char *start = val;
// skip till we get a blank character
while( (val < end)
&& (*val != ' ' )
&& (*val != '\t') )
{
char c = *(val++);
if( ('\'' == c) || ('"' == c) )
{
// skip till end of string
while( (val < end) && (*(val++) != c ) );
}
}
if( val > start )
{
if( nOptions == capacity )
{
capacity += 16;
char **moreOptions = (char **)CoTaskMemRealloc(options, capacity*sizeof(char*));
if( ! moreOptions )
{
/* failed to allocate more memory */
CoTaskMemFree(s);
/* return what we got so far */
*cOptionCount = nOptions;
*cOptions = options;
return NOERROR;
}
options = moreOptions;
}
*(val++) = '\0';
options[nOptions] = (char *)CoTaskMemAlloc(val-start);
if( options[nOptions] )
{
memcpy(options[nOptions], start, val-start);
++nOptions;
}
else
{
/* failed to allocate memory */
CoTaskMemFree(s);
/* return what we got so far */
*cOptionCount = nOptions;
*cOptions = options;
return NOERROR;
}
}
else
// must be end of string
break;
}
*cOptionCount = nOptions;
*cOptions = options;
hr = NOERROR;
}
CoTaskMemFree(s);
}
}
return hr;
}
HRESULT VLCControl::CreateTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount)
{
HRESULT hr = E_INVALIDARG;
if( VT_ERROR == V_VT(options) )
{
if( DISP_E_PARAMNOTFOUND == V_ERROR(options) )
{
// optional parameter not set
*cOptions = NULL;
*cOptionCount = 0;
return NOERROR;
}
}
else if( (VT_EMPTY == V_VT(options)) || (VT_NULL == V_VT(options)) )
{
// null parameter
*cOptions = NULL;
*cOptionCount = 0;
return NOERROR;
}
else if( VT_DISPATCH == V_VT(options) )
{
// if object is a collection, retrieve enumerator
VARIANT colEnum;
V_VT(&colEnum) = VT_UNKNOWN;
hr = GetObjectProperty(V_DISPATCH(options), DISPID_NEWENUM, colEnum);
if( SUCCEEDED(hr) )
{
IEnumVARIANT *enumVar;
hr = V_UNKNOWN(&colEnum)->QueryInterface(IID_IEnumVARIANT, (LPVOID *)&enumVar);
if( SUCCEEDED(hr) )
{
long pos = 0;
long capacity = 16;
VARIANT option;
*cOptions = (char **)CoTaskMemAlloc(capacity*sizeof(char *));
if( NULL != *cOptions )
{
ZeroMemory(*cOptions, sizeof(char *)*capacity);
while( SUCCEEDED(hr) && (S_OK == enumVar->Next(1, &option, NULL)) )
{
if( VT_BSTR == V_VT(&option) )
{
char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
(*cOptions)[pos] = cOption;
if( NULL != cOption )
{
++pos;
if( pos == capacity )
{
char **moreOptions = (char **)CoTaskMemRealloc(*cOptions, (capacity+16)*sizeof(char *));
if( NULL != moreOptions )
{
ZeroMemory(moreOptions+capacity, sizeof(char *)*16);
capacity += 16;
*cOptions = moreOptions;
}
else
hr = E_OUTOFMEMORY;
}
}
else
hr = ( SysStringLen(V_BSTR(&option)) > 0 ) ?
E_OUTOFMEMORY : E_INVALIDARG;
}
else
hr = E_INVALIDARG;
VariantClear(&option);
}
*cOptionCount = pos;
if( FAILED(hr) )
{
// free already processed elements
FreeTargetOptions(*cOptions, *cOptionCount);
}
}
else
hr = E_OUTOFMEMORY;
enumVar->Release();
}
}
else
{
// coerce object into a string and parse it
VARIANT v_name;
VariantInit(&v_name);
hr = VariantChangeType(&v_name, options, 0, VT_BSTR);
if( SUCCEEDED(hr) )
{
hr = parseStringOptions(codePage, V_BSTR(&v_name), cOptions, cOptionCount);
VariantClear(&v_name);
}
}
}
else if( V_ISARRAY(options) )
{
// array parameter
SAFEARRAY *array = V_ISBYREF(options) ? *V_ARRAYREF(options) : V_ARRAY(options);
if( SafeArrayGetDim(array) != 1 )
return E_INVALIDARG;
long lBound = 0;
long uBound = 0;
SafeArrayGetLBound(array, 1, &lBound);
SafeArrayGetUBound(array, 1, &uBound);
// have we got any options
if( uBound >= lBound )
{
VARTYPE vType;
hr = SafeArrayGetVartype(array, &vType);
if( FAILED(hr) )
return hr;
long pos;
// marshall options into an array of C strings
if( VT_VARIANT == vType )
{
*cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound+1));
if( NULL == *cOptions )
return E_OUTOFMEMORY;
ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound+1));
for(pos=lBound; (pos<=uBound) && SUCCEEDED(hr); ++pos )
{
VARIANT option;
hr = SafeArrayGetElement(array, &pos, &option);
if( SUCCEEDED(hr) )
{
if( VT_BSTR == V_VT(&option) )
{
char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
(*cOptions)[pos-lBound] = cOption;
if( NULL == cOption )
hr = ( SysStringLen(V_BSTR(&option)) > 0 ) ?
E_OUTOFMEMORY : E_INVALIDARG;
}
else
hr = E_INVALIDARG;
VariantClear(&option);
}
}
}
else if( VT_BSTR == vType )
{
*cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound+1));
if( NULL == *cOptions )
return E_OUTOFMEMORY;
ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound+1));
for(pos=lBound; (pos<=uBound) && SUCCEEDED(hr); ++pos )
{
BSTR option;
hr = SafeArrayGetElement(array, &pos, &option);
if( SUCCEEDED(hr) )
{
char *cOption = CStrFromBSTR(codePage, option);
(*cOptions)[pos-lBound] = cOption;
if( NULL == cOption )
hr = ( SysStringLen(option) > 0 ) ?
E_OUTOFMEMORY : E_INVALIDARG;
SysFreeString(option);
}
}
}
else
{
// unsupported type
return E_INVALIDARG;
}
*cOptionCount = pos-lBound;
if( FAILED(hr) )
{
// free already processed elements
FreeTargetOptions(*cOptions, *cOptionCount);
}
}
else
{
// empty array
*cOptions = NULL;
*cOptionCount = 0;
return NOERROR;
}
}
else if( VT_UNKNOWN == V_VT(options) )
{
// coerce object into a string and parse it
VARIANT v_name;
VariantInit(&v_name);
hr = VariantChangeType(&v_name, options, 0, VT_BSTR);
if( SUCCEEDED(hr) )
{
hr = parseStringOptions(codePage, V_BSTR(&v_name), cOptions, cOptionCount);
VariantClear(&v_name);
}
}
else if( VT_BSTR == V_VT(options) )
{
hr = parseStringOptions(codePage, V_BSTR(options), cOptions, cOptionCount);
}
return hr;
};
/*
** use VARIANT rather than a SAFEARRAY as argument type
** for compatibility with some scripting language (JScript)
*/
STDMETHODIMP VLCControl::addTarget(BSTR uri, VARIANT options, enum VLCPlaylistMode mode, int position)
{
if( 0 == SysStringLen(uri) )
return E_INVALIDARG;
libvlc_instance_t *p_libvlc;
HRESULT hr = _p_instance->getVLC(&p_libvlc);
if( SUCCEEDED(hr) )
{
char *cUri = CStrFromBSTR(CP_UTF8, uri);
if( NULL == cUri )
return E_OUTOFMEMORY;
int cOptionsCount;
char **cOptions;
if( FAILED(CreateTargetOptions(CP_UTF8, &options, &cOptions, &cOptionsCount)) )
return E_INVALIDARG;
position = _p_instance->playlist_add_extended_untrusted(cUri,
cOptionsCount, const_cast<const char**>(cOptions));
FreeTargetOptions(cOptions, cOptionsCount);
CoTaskMemFree(cUri);
if( position >= 0 )
{
if( mode & VLCPlayListAppendAndGo )
_p_instance->fireOnPlayEvent();
}
else
{
if( mode & VLCPlayListAppendAndGo )
_p_instance->fireOnStopEvent();
}
}
return hr;
};
STDMETHODIMP VLCControl::get_PlaylistIndex(int *index)
{
if( NULL == index )
return E_POINTER;
*index = 0;
libvlc_instance_t *p_libvlc;
HRESULT result = _p_instance->getVLC(&p_libvlc);
if( SUCCEEDED(result) )
{
*index = _p_instance->playlist_get_current_index();
}
return result;
};
STDMETHODIMP VLCControl::get_PlaylistCount(int *count)
{
if( NULL == count )
return E_POINTER;
*count = _p_instance->playlist_count();
return S_OK;
};
STDMETHODIMP VLCControl::playlistNext(void)
{
libvlc_instance_t* p_libvlc;
HRESULT result = _p_instance->getVLC(&p_libvlc);
if( SUCCEEDED(result) )
{
_p_instance->playlist_next();
}
return result;
};
STDMETHODIMP VLCControl::playlistPrev(void)
{
libvlc_instance_t* p_libvlc;
HRESULT result = _p_instance->getVLC(&p_libvlc);
if( SUCCEEDED(result) )
{
_p_instance->playlist_prev();
}
return result;
};
STDMETHODIMP VLCControl::playlistClear(void)
{
libvlc_instance_t* p_libvlc;
HRESULT result = _p_instance->getVLC(&p_libvlc);
if( SUCCEEDED(result) )
{
_p_instance->playlist_clear();
}
return result;
};
STDMETHODIMP VLCControl::get_VersionInfo(BSTR *version)
{
if( NULL == version )
return E_POINTER;
const char *versionStr = libvlc_get_version();
if( NULL != versionStr )
{
*version = BSTRFromCStr(CP_UTF8, versionStr);
return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
}
*version = NULL;
return E_FAIL;
};
STDMETHODIMP VLCControl::get_MRL(BSTR *mrl)
{
if( NULL == mrl )
return E_POINTER;
*mrl = SysAllocStringLen(_p_instance->getMRL(),
SysStringLen(_p_instance->getMRL()));
return S_OK;
};
STDMETHODIMP VLCControl::put_MRL(BSTR mrl)
{
_p_instance->setMRL(mrl);
return S_OK;
};
STDMETHODIMP VLCControl::get_AutoPlay(VARIANT_BOOL *autoplay)
{
if( NULL == autoplay )
return E_POINTER;
*autoplay = _p_instance->getAutoPlay() ? VARIANT_TRUE: VARIANT_FALSE;
return S_OK;
};
STDMETHODIMP VLCControl::put_AutoPlay(VARIANT_BOOL autoplay)
{
_p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
return S_OK;
};
STDMETHODIMP VLCControl::get_AutoLoop(VARIANT_BOOL *autoloop)
{
if( NULL == autoloop )
return E_POINTER;
*autoloop = _p_instance->getAutoLoop() ? VARIANT_TRUE: VARIANT_FALSE;
return S_OK;
};
STDMETHODIMP VLCControl::put_AutoLoop(VARIANT_BOOL autoloop)
{
_p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
return S_OK;
};
/*****************************************************************************
* vlccontrol.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005-2010 the VideoLAN team
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef _VLCCONTROL_H_
#define _VLCCONTROL_H_
#include "axvlc_idl.h"
class VLCControl : public IVLCControl
{
public:
VLCControl(VLCPlugin *p_instance):
_p_instance(p_instance), _p_typeinfo(NULL) { }
virtual ~VLCControl();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IDispatch == riid)
|| (IID_IVLCControl == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG) AddRef(void)
{ return _p_instance->pUnkOuter->AddRef(); }
STDMETHODIMP_(ULONG) Release(void)
{ return _p_instance->pUnkOuter->Release(); }
// IDispatch methods
STDMETHODIMP GetTypeInfoCount(UINT*);
STDMETHODIMP GetTypeInfo(UINT, LCID, LPTYPEINFO*);
STDMETHODIMP GetIDsOfNames(REFIID,LPOLESTR*,UINT,LCID,DISPID*);
STDMETHODIMP Invoke(DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
// IVLCControl methods
STDMETHODIMP play(void);
STDMETHODIMP get_Visible(VARIANT_BOOL *visible);
STDMETHODIMP put_Visible(VARIANT_BOOL visible);
STDMETHODIMP pause(void);
STDMETHODIMP stop(void);
STDMETHODIMP get_Playing(VARIANT_BOOL *isPlaying);
STDMETHODIMP get_Position(float *position);
STDMETHODIMP put_Position(float position);
STDMETHODIMP get_Time(int *seconds);
STDMETHODIMP put_Time(int seconds);
STDMETHODIMP shuttle(int seconds);
STDMETHODIMP fullscreen();
STDMETHODIMP get_Length(int *seconds);
STDMETHODIMP playFaster(void);
STDMETHODIMP playSlower(void);
STDMETHODIMP get_Volume(int *volume);
STDMETHODIMP put_Volume(int volume);
STDMETHODIMP toggleMute(void);
STDMETHODIMP setVariable( BSTR name, VARIANT value);
STDMETHODIMP getVariable( BSTR name, VARIANT *value);
STDMETHODIMP addTarget( BSTR uri, VARIANT options, enum VLCPlaylistMode mode, int position);
STDMETHODIMP get_PlaylistIndex(int *index);
STDMETHODIMP get_PlaylistCount(int *count);
STDMETHODIMP playlistNext(void);
STDMETHODIMP playlistPrev(void);
STDMETHODIMP playlistClear(void);
STDMETHODIMP get_VersionInfo(BSTR *version);
STDMETHODIMP get_MRL(BSTR *mrl);
STDMETHODIMP put_MRL(BSTR mrl);
STDMETHODIMP get_AutoLoop(VARIANT_BOOL *autoloop);
STDMETHODIMP put_AutoLoop(VARIANT_BOOL autoloop);
STDMETHODIMP get_AutoPlay(VARIANT_BOOL *autoplay);
STDMETHODIMP put_AutoPlay(VARIANT_BOOL autoplay);
static HRESULT CreateTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount);
static void FreeTargetOptions(char **cOptions, int cOptionCount);
private:
HRESULT getTypeInfo();
VLCPlugin *_p_instance;
ITypeInfo *_p_typeinfo;
};
#endif
/*****************************************************************************
* vlccontrol2.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2006 the VideoLAN team
* Copyright (C) 2010 M2X BV
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
* Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <stdio.h>
#include <shlwapi.h>
#include <wininet.h>
#include <tchar.h>
#include "utils.h"
#include "plugin.h"
#include "vlccontrol2.h"
#include "vlccontrol.h"
#include "position.h"
// ---------
HRESULT VLCInterfaceBase::loadTypeInfo(REFIID riid)
{
// if( _ti ) return NOERROR; // unnecessairy
ITypeLib *p_typelib;
HRESULT hr = _plug->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
if( SUCCEEDED(hr) )
{
hr = p_typelib->GetTypeInfoOfGuid(riid, &_ti);
if( FAILED(hr) ) _ti = NULL;
p_typelib->Release();
}
return hr;
}
#define BIND_INTERFACE( class ) \
template<> REFIID VLCInterface<class, I##class>::_riid = IID_I##class;
BIND_INTERFACE( VLCAudio )
BIND_INTERFACE( VLCInput )
BIND_INTERFACE( VLCMarquee )
BIND_INTERFACE( VLCLogo )
BIND_INTERFACE( VLCDeinterlace )
BIND_INTERFACE( VLCPlaylistItems )
BIND_INTERFACE( VLCPlaylist )
BIND_INTERFACE( VLCVideo )
BIND_INTERFACE( VLCSubtitle )
#undef BIND_INTERFACE
template<class I> static inline
HRESULT object_get(I **dst, I *src)
{
if( NULL == dst )
return E_POINTER;
*dst = src;
if( NULL != src )
{
src->AddRef();
return NOERROR;
}
return E_OUTOFMEMORY;
}
static inline
VARIANT_BOOL varbool(bool b) { return b ? VARIANT_TRUE : VARIANT_FALSE; }
// ---------
STDMETHODIMP VLCAudio::get_mute(VARIANT_BOOL* mute)
{
if( NULL == mute )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
*mute = varbool( libvlc_audio_get_mute(p_md) );
return hr;
};
STDMETHODIMP VLCAudio::put_mute(VARIANT_BOOL mute)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
libvlc_audio_set_mute(p_md, VARIANT_FALSE != mute);
return hr;
};
STDMETHODIMP VLCAudio::get_volume(long* volume)
{
if( NULL == volume )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
*volume = libvlc_audio_get_volume(p_md);
return hr;
};
STDMETHODIMP VLCAudio::put_volume(long volume)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_audio_set_volume(p_md, volume);
}
return hr;
};
STDMETHODIMP VLCAudio::get_track(long* track)
{
if( NULL == track )
return E_POINTER;
libvlc_media_player_t* p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*track = libvlc_audio_get_track(p_md);
}
return hr;
};
STDMETHODIMP VLCAudio::put_track(long track)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_audio_set_track(p_md, track);
}
return hr;
};
STDMETHODIMP VLCAudio::get_count(long* trackNumber)
{
if( NULL == trackNumber )
return E_POINTER;
libvlc_media_player_t* p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
// get the number of audio track available and return it
*trackNumber = libvlc_audio_get_track_count(p_md);
}
return hr;
};
STDMETHODIMP VLCAudio::description(long trackID, BSTR* name)
{
if( NULL == name )
return E_POINTER;
libvlc_media_player_t* p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
int i, i_limit;
const char *psz_name;
libvlc_track_description_t *p_trackDesc;
// get tracks description
p_trackDesc = libvlc_audio_get_track_description(p_md);
if( !p_trackDesc )
return E_FAIL;
//get the number of available track
i_limit = libvlc_audio_get_track_count(p_md);
if( i_limit < 0 )
return E_FAIL;
// check if the number given is a good one
if ( ( trackID > ( i_limit -1 ) ) || ( trackID < 0 ) )
return E_FAIL;
// get the good trackDesc
for( i = 0 ; i < trackID ; i++ )
{
p_trackDesc = p_trackDesc->p_next;
}
// get the track name
psz_name = p_trackDesc->psz_name;
// return it
if( psz_name != NULL )
{
*name = BSTRFromCStr(CP_UTF8, psz_name);
return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
}
*name = NULL;
return E_FAIL;
}
return hr;
};
STDMETHODIMP VLCAudio::get_channel(long *channel)
{
if( NULL == channel )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*channel = libvlc_audio_get_channel(p_md);
}
return hr;
};
STDMETHODIMP VLCAudio::put_channel(long channel)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_audio_set_channel(p_md, channel);
}
return hr;
};
STDMETHODIMP VLCAudio::toggleMute()
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
libvlc_audio_toggle_mute(p_md);
return hr;
};
/****************************************************************************/
STDMETHODIMP VLCDeinterlace::disable()
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_video_set_deinterlace(p_md, "");
}
return hr;
}
STDMETHODIMP VLCDeinterlace::enable(BSTR mode)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
char *psz_mode = CStrFromBSTR(CP_UTF8, mode);
libvlc_video_set_deinterlace(p_md, psz_mode);
CoTaskMemFree(psz_mode);
}
return hr;
}
/****************************************************************************/
STDMETHODIMP VLCInput::get_length(double* length)
{
if( NULL == length )
return E_POINTER;
*length = 0;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*length = (double)libvlc_media_player_get_length(p_md);
}
return hr;
};
STDMETHODIMP VLCInput::get_position(double* position)
{
if( NULL == position )
return E_POINTER;
*position = 0.0f;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*position = libvlc_media_player_get_position(p_md);
}
return hr;
};
STDMETHODIMP VLCInput::put_position(double position)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_media_player_set_position(p_md, position);
}
return hr;
};
STDMETHODIMP VLCInput::get_time(double* time)
{
if( NULL == time )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*time = (double)libvlc_media_player_get_time(p_md);
}
return hr;
};
STDMETHODIMP VLCInput::put_time(double time)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_media_player_set_time(p_md, (int64_t)time);
}
return hr;
};
STDMETHODIMP VLCInput::get_state(long* state)
{
if( NULL == state )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*state = libvlc_media_player_get_state(p_md);
}
return hr;
};
STDMETHODIMP VLCInput::get_rate(double* rate)
{
if( NULL == rate )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*rate = libvlc_media_player_get_rate(p_md);
}
return hr;
};
STDMETHODIMP VLCInput::put_rate(double rate)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_media_player_set_rate(p_md, rate);
}
return hr;
};
STDMETHODIMP VLCInput::get_fps(double* fps)
{
if( NULL == fps )
return E_POINTER;
*fps = 0.0;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*fps = libvlc_media_player_get_fps(p_md);
}
return hr;
};
STDMETHODIMP VLCInput::get_hasVout(VARIANT_BOOL* hasVout)
{
if( NULL == hasVout )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*hasVout = varbool( libvlc_media_player_has_vout(p_md) );
}
return hr;
};
/****************************************************************************/
HRESULT VLCMarquee::do_put_int(unsigned idx, LONG val)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_video_set_marquee_int(p_md, idx, val);
}
return hr;
}
HRESULT VLCMarquee::do_get_int(unsigned idx, LONG *val)
{
if( NULL == val )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*val = libvlc_video_get_marquee_int(p_md, idx);
}
return hr;
}
STDMETHODIMP VLCMarquee::get_position(BSTR* val)
{
if( NULL == val )
return E_POINTER;
LONG i;
HRESULT hr = do_get_int(libvlc_marquee_Position, &i);
if(SUCCEEDED(hr))
*val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
return hr;
}
STDMETHODIMP VLCMarquee::put_position(BSTR val)
{
char *n = CStrFromBSTR(CP_UTF8, val);
if( !n ) return E_OUTOFMEMORY;
size_t i;
HRESULT hr;
if( position_byname( n, i ) )
hr = do_put_int(libvlc_marquee_Position,i);
else
hr = E_INVALIDARG;
CoTaskMemFree(n);
return hr;
}
STDMETHODIMP VLCMarquee::get_text(BSTR *val)
{
char *psz;
if( NULL == val )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
psz = libvlc_video_get_marquee_string(p_md, libvlc_marquee_Text);
if( psz )
*val = BSTRFromCStr(CP_UTF8, psz);
}
return hr;
}
STDMETHODIMP VLCMarquee::put_text(BSTR val)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
char *psz_text = CStrFromBSTR(CP_UTF8, val);
libvlc_video_set_marquee_string(p_md, libvlc_marquee_Text, psz_text);
CoTaskMemFree(psz_text);
}
return hr;
}
/****************************************************************************/
STDMETHODIMP VLCPlaylistItems::get_count(long* count)
{
if( NULL == count )
return E_POINTER;
*count = Instance()->playlist_count();
return S_OK;
};
STDMETHODIMP VLCPlaylistItems::clear()
{
Instance()->playlist_clear();
return S_OK;
};
STDMETHODIMP VLCPlaylistItems::remove(long item)
{
libvlc_instance_t* p_libvlc;
HRESULT hr = getVLC(&p_libvlc);
if( SUCCEEDED(hr) )
{
Instance()->playlist_delete_item(item);
}
return hr;
};
/****************************************************************************/
STDMETHODIMP VLCPlaylist::get_itemCount(long* count)
{
if( NULL == count )
return E_POINTER;
*count = 0;
*count = Instance()->playlist_count();
return S_OK;
};
STDMETHODIMP VLCPlaylist::get_isPlaying(VARIANT_BOOL* isPlaying)
{
if( NULL == isPlaying )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*isPlaying = varbool( libvlc_media_player_is_playing(p_md) );
}
return hr;
};
STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* item)
{
if( NULL == item )
return E_POINTER;
if( 0 == SysStringLen(uri) )
return E_INVALIDARG;
libvlc_instance_t* p_libvlc;
HRESULT hr = getVLC(&p_libvlc);
if( SUCCEEDED(hr) )
{
char *psz_uri = NULL;
if( SysStringLen(Instance()->getBaseURL()) > 0 )
{
/*
** if the MRL a relative URL, we should end up with an absolute URL
*/
LPWSTR abs_url = CombineURL(Instance()->getBaseURL(), uri);
if( NULL != abs_url )
{
psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
CoTaskMemFree(abs_url);
}
else
{
psz_uri = CStrFromBSTR(CP_UTF8, uri);
}
}
else
{
/*
** baseURL is empty, assume MRL is absolute
*/
psz_uri = CStrFromBSTR(CP_UTF8, uri);
}
if( NULL == psz_uri )
{
return E_OUTOFMEMORY;
}
int i_options;
char **ppsz_options;
hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
if( FAILED(hr) )
{
CoTaskMemFree(psz_uri);
return hr;
}
char *psz_name = NULL;
VARIANT v_name;
VariantInit(&v_name);
if( SUCCEEDED(VariantChangeType(&v_name, &name, 0, VT_BSTR)) )
{
if( SysStringLen(V_BSTR(&v_name)) > 0 )
psz_name = CStrFromBSTR(CP_UTF8, V_BSTR(&v_name));
VariantClear(&v_name);
}
*item = Instance()->playlist_add_extended_untrusted(psz_uri,
i_options, const_cast<const char **>(ppsz_options));
VLCControl::FreeTargetOptions(ppsz_options, i_options);
CoTaskMemFree(psz_uri);
if( psz_name ) /* XXX Do we even need to check? */
CoTaskMemFree(psz_name);
}
return hr;
};
STDMETHODIMP VLCPlaylist::play()
{
Instance()->playlist_play();
return S_OK;
};
STDMETHODIMP VLCPlaylist::playItem(long item)
{
Instance()->playlist_play_item(item);
return S_OK;
};
STDMETHODIMP VLCPlaylist::togglePause()
{
libvlc_media_player_t* p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_media_player_pause(p_md);
}
return hr;
};
STDMETHODIMP VLCPlaylist::stop()
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_media_player_stop(p_md);
}
return hr;
};
STDMETHODIMP VLCPlaylist::next()
{
Instance()->playlist_next();
return S_OK;
};
STDMETHODIMP VLCPlaylist::prev()
{
Instance()->playlist_prev();
return S_OK;
};
STDMETHODIMP VLCPlaylist::clear()
{
Instance()->playlist_clear();
return S_OK;
};
STDMETHODIMP VLCPlaylist::removeItem(long item)
{
libvlc_instance_t* p_libvlc;
HRESULT hr = getVLC(&p_libvlc);
if( SUCCEEDED(hr) )
{
Instance()->playlist_delete_item(item);
}
return hr;
};
STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
{
if( NULL == obj )
return E_POINTER;
*obj = _p_vlcplaylistitems;
if( NULL != _p_vlcplaylistitems )
{
_p_vlcplaylistitems->AddRef();
return NOERROR;
}
return E_OUTOFMEMORY;
};
/****************************************************************************/
STDMETHODIMP VLCSubtitle::get_track(long* spu)
{
if( NULL == spu )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*spu = libvlc_video_get_spu(p_md);
}
return hr;
};
STDMETHODIMP VLCSubtitle::put_track(long spu)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_video_set_spu(p_md, spu);
}
return hr;
};
STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
{
if( NULL == spuNumber )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
// get the number of video subtitle available and return it
*spuNumber = libvlc_video_get_spu_count(p_md);
}
return hr;
};
STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
{
if( NULL == name )
return E_POINTER;
libvlc_media_player_t* p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
int i, i_limit;
const char *psz_name;
libvlc_track_description_t *p_spuDesc;
// get subtitles description
p_spuDesc = libvlc_video_get_spu_description(p_md);
if( !p_spuDesc )
return E_FAIL;
// get the number of available subtitle
i_limit = libvlc_video_get_spu_count(p_md);
if( i_limit < 0 )
return E_FAIL;
// check if the number given is a good one
if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
return E_FAIL;
// get the good spuDesc
for( i = 0 ; i < nameID ; i++ )
{
p_spuDesc = p_spuDesc->p_next;
}
// get the subtitle name
psz_name = p_spuDesc->psz_name;
// return it
if( psz_name != NULL )
{
*name = BSTRFromCStr(CP_UTF8, psz_name);
return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
}
*name = NULL;
return E_FAIL;
}
return hr;
};
/****************************************************************************/
STDMETHODIMP VLCVideo::get_fullscreen(VARIANT_BOOL* fullscreen)
{
if( NULL == fullscreen )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*fullscreen = varbool( libvlc_get_fullscreen(p_md) );
}
return hr;
};
STDMETHODIMP VLCVideo::put_fullscreen(VARIANT_BOOL fullscreen)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_set_fullscreen(p_md, VARIANT_FALSE != fullscreen);
}
return hr;
};
STDMETHODIMP VLCVideo::get_width(long* width)
{
if( NULL == width )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*width = libvlc_video_get_width(p_md);
}
return hr;
};
STDMETHODIMP VLCVideo::get_height(long* height)
{
if( NULL == height )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*height = libvlc_video_get_height(p_md);
}
return hr;
};
STDMETHODIMP VLCVideo::get_aspectRatio(BSTR* aspect)
{
if( NULL == aspect )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
char *psz_aspect = libvlc_video_get_aspect_ratio(p_md);
if( !psz_aspect )
{
*aspect = BSTRFromCStr(CP_UTF8, psz_aspect);
if( NULL == *aspect )
hr = E_OUTOFMEMORY;
} else if( NULL == psz_aspect)
hr = E_OUTOFMEMORY;
free( psz_aspect );
}
return hr;
};
STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
{
if( NULL == aspect )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
if( !psz_aspect )
{
return E_OUTOFMEMORY;
}
libvlc_video_set_aspect_ratio(p_md, psz_aspect);
CoTaskMemFree(psz_aspect);
}
return hr;
};
STDMETHODIMP VLCVideo::get_subtitle(long* spu)
{
if( NULL == spu )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*spu = libvlc_video_get_spu(p_md);
}
return hr;
};
STDMETHODIMP VLCVideo::put_subtitle(long spu)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_video_set_spu(p_md, spu);
}
return hr;
};
STDMETHODIMP VLCVideo::get_crop(BSTR* geometry)
{
if( NULL == geometry )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
char *psz_geometry = libvlc_video_get_crop_geometry(p_md);
if( !psz_geometry )
{
*geometry = BSTRFromCStr(CP_UTF8, psz_geometry);
if( !geometry )
hr = E_OUTOFMEMORY;
} else if( !psz_geometry )
hr = E_OUTOFMEMORY;
free( psz_geometry );
}
return hr;
};
STDMETHODIMP VLCVideo::put_crop(BSTR geometry)
{
if( NULL == geometry )
return E_POINTER;
if( 0 == SysStringLen(geometry) )
return E_INVALIDARG;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
char *psz_geometry = CStrFromBSTR(CP_UTF8, geometry);
if( !psz_geometry )
{
return E_OUTOFMEMORY;
}
libvlc_video_set_crop_geometry(p_md, psz_geometry);
CoTaskMemFree(psz_geometry);
}
return hr;
};
STDMETHODIMP VLCVideo::get_teletext(long* page)
{
if( NULL == page )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*page = libvlc_video_get_teletext(p_md);
}
return hr;
};
STDMETHODIMP VLCVideo::put_teletext(long page)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_video_set_teletext(p_md, page);
}
return hr;
};
STDMETHODIMP VLCVideo::takeSnapshot(LPPICTUREDISP* picture)
{
if( NULL == picture )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
static int uniqueId = 0;
TCHAR path[MAX_PATH+1];
int pathlen = GetTempPath(MAX_PATH-24, path);
if( (0 == pathlen) || (pathlen > (MAX_PATH-24)) )
return E_FAIL;
/* check temp directory path by openning it */
{
HANDLE dirHandle = CreateFile(path, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if( INVALID_HANDLE_VALUE == dirHandle )
{
Instance()->setErrorInfo(IID_IVLCVideo,
"Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
return E_FAIL;
}
else
{
BY_HANDLE_FILE_INFORMATION bhfi;
BOOL res = GetFileInformationByHandle(dirHandle, &bhfi);
CloseHandle(dirHandle);
if( !res || !(bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
Instance()->setErrorInfo(IID_IVLCVideo,
"Invalid temporary directory for snapshot images, check values of TMP, TEMP envars.");
return E_FAIL;
}
}
}
TCHAR filepath[MAX_PATH+1];
_stprintf(filepath, TEXT("%sAXVLC%lXS%lX.bmp"),
path, GetCurrentProcessId(), ++uniqueId);
#ifdef _UNICODE
/* reuse path storage for UTF8 string */
char *psz_filepath = (char *)path;
WCHAR* wpath = filepath;
#else
char *psz_filepath = path;
/* first convert to unicode using current code page */
WCHAR wpath[MAX_PATH+1];
if( 0 == MultiByteToWideChar(CP_ACP, 0, filepath, -1,
wpath, sizeof(wpath)/sizeof(WCHAR)) )
return E_FAIL;
#endif
/* convert to UTF8 */
pathlen = WideCharToMultiByte(CP_UTF8, 0, wpath, -1,
psz_filepath, sizeof(path), NULL, NULL);
// fail if path is 0 or too short (i.e pathlen is the same as
// storage size)
if( (0 == pathlen) || (sizeof(path) == pathlen) )
return E_FAIL;
/* take snapshot into file */
if( libvlc_video_take_snapshot(p_md, 0, psz_filepath, 0, 0) == 0 )
{
/* open snapshot file */
HANDLE snapPic = LoadImage(NULL, filepath, IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION|LR_LOADFROMFILE);
if( snapPic )
{
PICTDESC snapDesc;
snapDesc.cbSizeofstruct = sizeof(PICTDESC);
snapDesc.picType = PICTYPE_BITMAP;
snapDesc.bmp.hbitmap = (HBITMAP)snapPic;
snapDesc.bmp.hpal = NULL;
hr = OleCreatePictureIndirect(&snapDesc, IID_IPictureDisp,
TRUE, (LPVOID*)picture);
if( FAILED(hr) )
{
*picture = NULL;
DeleteObject(snapPic);
}
}
DeleteFile(filepath);
}
}
return hr;
};
STDMETHODIMP VLCVideo::toggleFullscreen()
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_toggle_fullscreen(p_md);
}
return hr;
};
STDMETHODIMP VLCVideo::toggleTeletext()
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_toggle_teletext(p_md);
}
return hr;
};
STDMETHODIMP VLCVideo::get_marquee(IVLCMarquee** obj)
{
return object_get(obj,_p_vlcmarquee);
}
STDMETHODIMP VLCVideo::get_logo(IVLCLogo** obj)
{
return object_get(obj,_p_vlclogo);
}
STDMETHODIMP VLCVideo::get_deinterlace(IVLCDeinterlace** obj)
{
return object_get(obj,_p_vlcdeint);
}
/****************************************************************************/
HRESULT VLCLogo::do_put_int(unsigned idx, LONG val)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_video_set_logo_int(p_md, idx, val);
}
return hr;
}
HRESULT VLCLogo::do_get_int(unsigned idx, LONG *val)
{
if( NULL == val )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
if( SUCCEEDED(hr) )
{
*val = libvlc_video_get_logo_int(p_md, idx);
}
return hr;
}
STDMETHODIMP VLCLogo::file(BSTR fname)
{
libvlc_media_player_t *p_md;
HRESULT hr = getMD(&p_md);
char *n = CStrFromBSTR(CP_UTF8, fname);
if( !n ) hr = E_OUTOFMEMORY;
if( SUCCEEDED(hr) )
{
libvlc_video_set_logo_string(p_md, libvlc_logo_file, n);
}
CoTaskMemFree(n);
return hr;
}
STDMETHODIMP VLCLogo::get_position(BSTR* val)
{
if( NULL == val )
return E_POINTER;
LONG i;
HRESULT hr = do_get_int(libvlc_logo_position, &i);
if(SUCCEEDED(hr))
*val = BSTRFromCStr(CP_UTF8, position_bynumber(i));
return hr;
}
STDMETHODIMP VLCLogo::put_position(BSTR val)
{
char *n = CStrFromBSTR(CP_UTF8, val);
if( !n ) return E_OUTOFMEMORY;
size_t i;
HRESULT hr;
if( position_byname( n, i ) )
hr = do_put_int(libvlc_logo_position,i);
else
hr = E_INVALIDARG;
CoTaskMemFree(n);
return hr;
}
/****************************************************************************/
VLCControl2::VLCControl2(VLCPlugin *p_instance) :
_p_instance(p_instance),
_p_typeinfo(NULL),
_p_vlcaudio(new VLCAudio(p_instance)),
_p_vlcinput(new VLCInput(p_instance)),
_p_vlcplaylist(new VLCPlaylist(p_instance)),
_p_vlcsubtitle(new VLCSubtitle(p_instance)),
_p_vlcvideo(new VLCVideo(p_instance))
{
}
VLCControl2::~VLCControl2()
{
delete _p_vlcvideo;
delete _p_vlcsubtitle;
delete _p_vlcplaylist;
delete _p_vlcinput;
delete _p_vlcaudio;
if( _p_typeinfo )
_p_typeinfo->Release();
};
HRESULT VLCControl2::loadTypeInfo(void)
{
HRESULT hr = NOERROR;
if( NULL == _p_typeinfo )
{
ITypeLib *p_typelib;
hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
if( SUCCEEDED(hr) )
{
hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl2, &_p_typeinfo);
if( FAILED(hr) )
{
_p_typeinfo = NULL;
}
p_typelib->Release();
}
}
return hr;
};
STDMETHODIMP VLCControl2::GetTypeInfoCount(UINT* pctInfo)
{
if( NULL == pctInfo )
return E_INVALIDARG;
if( SUCCEEDED(loadTypeInfo()) )
*pctInfo = 1;
else
*pctInfo = 0;
return NOERROR;
};
STDMETHODIMP VLCControl2::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
{
if( NULL == ppTInfo )
return E_INVALIDARG;
if( SUCCEEDED(loadTypeInfo()) )
{
_p_typeinfo->AddRef();
*ppTInfo = _p_typeinfo;
return NOERROR;
}
*ppTInfo = NULL;
return E_NOTIMPL;
};
STDMETHODIMP VLCControl2::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
UINT cNames, LCID lcid, DISPID* rgDispID)
{
if( SUCCEEDED(loadTypeInfo()) )
{
return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
}
return E_NOTIMPL;
};
STDMETHODIMP VLCControl2::Invoke(DISPID dispIdMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
if( SUCCEEDED(loadTypeInfo()) )
{
return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
pVarResult, pExcepInfo, puArgErr);
}
return E_NOTIMPL;
};
STDMETHODIMP VLCControl2::get_AutoLoop(VARIANT_BOOL *autoloop)
{
if( NULL == autoloop )
return E_POINTER;
*autoloop = varbool( _p_instance->getAutoLoop() );
return S_OK;
};
STDMETHODIMP VLCControl2::put_AutoLoop(VARIANT_BOOL autoloop)
{
_p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE);
return S_OK;
};
STDMETHODIMP VLCControl2::get_AutoPlay(VARIANT_BOOL *autoplay)
{
if( NULL == autoplay )
return E_POINTER;
*autoplay = varbool( _p_instance->getAutoPlay() );
return S_OK;
};
STDMETHODIMP VLCControl2::put_AutoPlay(VARIANT_BOOL autoplay)
{
_p_instance->setAutoPlay((VARIANT_FALSE != autoplay) ? TRUE: FALSE);
return S_OK;
};
STDMETHODIMP VLCControl2::get_BaseURL(BSTR *url)
{
if( NULL == url )
return E_POINTER;
*url = SysAllocStringLen(_p_instance->getBaseURL(),
SysStringLen(_p_instance->getBaseURL()));
return NOERROR;
};
STDMETHODIMP VLCControl2::put_BaseURL(BSTR mrl)
{
_p_instance->setBaseURL(mrl);
return S_OK;
};
STDMETHODIMP VLCControl2::get_MRL(BSTR *mrl)
{
if( NULL == mrl )
return E_POINTER;
*mrl = SysAllocStringLen(_p_instance->getMRL(),
SysStringLen(_p_instance->getMRL()));
return NOERROR;
};
STDMETHODIMP VLCControl2::put_MRL(BSTR mrl)
{
_p_instance->setMRL(mrl);
return S_OK;
};
STDMETHODIMP VLCControl2::get_Toolbar(VARIANT_BOOL *visible)
{
if( NULL == visible )
return E_POINTER;
/*
* Note to developers
*
* Returning the _b_toolbar is closer to the method specification.
* But returning True when toolbar is not implemented so not displayed
* could be bad for ActiveX users which rely on this value to show their
* own toolbar if not provided by the ActiveX.
*
* This is the reason why FALSE is returned, until toolbar get implemented.
*/
/* DISABLED for now */
// *visible = varbool( _p_instance->getShowToolbar() );
*visible = VARIANT_FALSE;
return S_OK;
};
STDMETHODIMP VLCControl2::put_Toolbar(VARIANT_BOOL visible)
{
_p_instance->setShowToolbar((VARIANT_FALSE != visible) ? TRUE: FALSE);
return S_OK;
};
STDMETHODIMP VLCControl2::get_StartTime(long *seconds)
{
if( NULL == seconds )
return E_POINTER;
*seconds = _p_instance->getStartTime();
return S_OK;
};
STDMETHODIMP VLCControl2::put_StartTime(long seconds)
{
_p_instance->setStartTime(seconds);
return S_OK;
};
STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
{
if( NULL == version )
return E_POINTER;
const char *versionStr = libvlc_get_version();
if( NULL != versionStr )
{
*version = BSTRFromCStr(CP_UTF8, versionStr);
return (NULL == *version) ? E_OUTOFMEMORY : NOERROR;
}
*version = NULL;
return E_FAIL;
};
STDMETHODIMP VLCControl2::get_Visible(VARIANT_BOOL *isVisible)
{
if( NULL == isVisible )
return E_POINTER;
*isVisible = varbool( _p_instance->getVisible() );
return S_OK;
};
STDMETHODIMP VLCControl2::put_Visible(VARIANT_BOOL isVisible)
{
_p_instance->setVisible(isVisible != VARIANT_FALSE);
return S_OK;
};
STDMETHODIMP VLCControl2::get_Volume(long *volume)
{
if( NULL == volume )
return E_POINTER;
*volume = _p_instance->getVolume();
return S_OK;
};
STDMETHODIMP VLCControl2::put_Volume(long volume)
{
_p_instance->setVolume(volume);
return S_OK;
};
STDMETHODIMP VLCControl2::get_BackColor(OLE_COLOR *backcolor)
{
if( NULL == backcolor )
return E_POINTER;
*backcolor = _p_instance->getBackColor();
return S_OK;
};
STDMETHODIMP VLCControl2::put_BackColor(OLE_COLOR backcolor)
{
_p_instance->setBackColor(backcolor);
return S_OK;
};
STDMETHODIMP VLCControl2::get_audio(IVLCAudio** obj)
{
return object_get(obj,_p_vlcaudio);
}
STDMETHODIMP VLCControl2::get_input(IVLCInput** obj)
{
return object_get(obj,_p_vlcinput);
}
STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
{
return object_get(obj,_p_vlcplaylist);
}
STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
{
return object_get(obj,_p_vlcsubtitle);
}
STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
{
return object_get(obj,_p_vlcvideo);
}
/*****************************************************************************
* vlccontrol.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2006 the VideoLAN team
* Copyright (C) 2010 M2X BV
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
* Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef _VLCCONTROL2_H_
#define _VLCCONTROL2_H_
#include "axvlc_idl.h"
#include <vlc/libvlc.h>
#include <ole2.h>
class VLCInterfaceBase {
public:
VLCInterfaceBase(VLCPlugin *p): _plug(p), _ti(NULL) { }
virtual ~VLCInterfaceBase() { if( _ti ) _ti->Release(); }
VLCPlugin *Instance() const { return _plug; }
HRESULT getVLC(libvlc_instance_t **pp) const { return _plug->getVLC(pp); }
HRESULT getMD(libvlc_media_player_t **pp) const { return _plug->getMD(pp); }
protected:
HRESULT loadTypeInfo(REFIID riid);
ITypeInfo *TypeInfo() const { return _ti; }
STDMETHODIMP_(ULONG) AddRef(void) { return _plug->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _plug->pUnkOuter->Release(); };
private:
VLCPlugin *_plug;
ITypeInfo *_ti;
};
template<class T,class I>
class VLCInterface: public I, private VLCInterfaceBase
{
private:
typedef VLCInterfaceBase Base;
T *This() { return static_cast< T *>(this); }
const T *This() const { return static_cast<const T *>(this); }
HRESULT loadTypeInfo()
{
return TypeInfo() ? NOERROR : Base::loadTypeInfo(_riid);
}
public:
VLCInterface(VLCPlugin *p): Base(p) { }
VLCPlugin *Instance() const { return Base::Instance(); }
HRESULT getVLC(libvlc_instance_t **pp) const { return Base::getVLC(pp); }
HRESULT getMD(libvlc_media_player_t **pp) const { return Base::getMD(pp); }
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv ) return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IDispatch == riid)
|| (_riid == riid) )
{
This()->AddRef();
*ppv = reinterpret_cast<LPVOID>(This());
return NOERROR;
}
// behaves as a standalone object
return E_NOINTERFACE;
}
STDMETHODIMP GetTypeInfoCount(UINT* pctInfo)
{
if( NULL == pctInfo )
return E_INVALIDARG;
*pctInfo = SUCCEEDED(loadTypeInfo()) ? 1 : 0;
return NOERROR;
}
STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
{
if( NULL == ppTInfo )
return E_INVALIDARG;
if( SUCCEEDED(loadTypeInfo()) )
{
(*ppTInfo = TypeInfo())->AddRef();
return NOERROR;
}
*ppTInfo = NULL;
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
UINT cNames, LCID lcid, DISPID* rgDispID)
{
return FAILED(loadTypeInfo()) ? E_NOTIMPL :
DispGetIDsOfNames(TypeInfo(), rgszNames, cNames, rgDispID);
}
STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
return FAILED(loadTypeInfo()) ? E_NOTIMPL :
DispInvoke(This(), TypeInfo(), dispIdMember, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
}
STDMETHODIMP_(ULONG) AddRef(void) { return Base::AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return Base::Release(); };
private:
static REFIID _riid;
};
class VLCAudio : public VLCInterface<VLCAudio,IVLCAudio>
{
public:
VLCAudio(VLCPlugin *p): VLCInterface<VLCAudio,IVLCAudio>(p) { }
// IVLCAudio methods
STDMETHODIMP get_mute(VARIANT_BOOL*);
STDMETHODIMP put_mute(VARIANT_BOOL);
STDMETHODIMP get_volume(long*);
STDMETHODIMP put_volume(long);
STDMETHODIMP get_track(long*);
STDMETHODIMP put_track(long);
STDMETHODIMP get_count(long*);
STDMETHODIMP get_channel(long*);
STDMETHODIMP put_channel(long);
STDMETHODIMP toggleMute();
STDMETHODIMP description(long, BSTR*);
};
class VLCInput: public VLCInterface<VLCInput,IVLCInput>
{
public:
VLCInput(VLCPlugin *p): VLCInterface<VLCInput,IVLCInput>(p) { }
// IVLCInput methods
STDMETHODIMP get_length(double*);
STDMETHODIMP get_position(double*);
STDMETHODIMP put_position(double);
STDMETHODIMP get_time(double*);
STDMETHODIMP put_time(double);
STDMETHODIMP get_state(long*);
STDMETHODIMP get_rate(double*);
STDMETHODIMP put_rate(double);
STDMETHODIMP get_fps(double*);
STDMETHODIMP get_hasVout(VARIANT_BOOL*);
};
class VLCMarquee: public VLCInterface<VLCMarquee,IVLCMarquee>
{
public:
VLCMarquee(VLCPlugin *p): VLCInterface<VLCMarquee,IVLCMarquee>(p) { }
// IVLCMarquee methods
STDMETHODIMP enable() { return do_put_int(libvlc_marquee_Enable, true); }
STDMETHODIMP disable() { return do_put_int(libvlc_marquee_Enable, false); }
STDMETHODIMP get_text(BSTR *);
STDMETHODIMP put_text(BSTR);
STDMETHODIMP get_position(BSTR *);
STDMETHODIMP put_position(BSTR);
#define PROP_INT( a, b ) \
STDMETHODIMP get_##a(LONG *val) { return do_get_int(b,val); } \
STDMETHODIMP put_##a(LONG val) { return do_put_int(b,val); }
PROP_INT( color, libvlc_marquee_Color )
PROP_INT( opacity, libvlc_marquee_Opacity )
PROP_INT( refresh, libvlc_marquee_Refresh )
PROP_INT( size, libvlc_marquee_Size )
PROP_INT( timeout, libvlc_marquee_Timeout )
PROP_INT( x, libvlc_marquee_X )
PROP_INT( y, libvlc_marquee_Y )
#undef PROP_INT
private:
HRESULT do_put_int(unsigned idx, LONG val);
HRESULT do_get_int(unsigned idx, LONG *val);
};
class VLCLogo: public VLCInterface<VLCLogo,IVLCLogo>
{
public:
VLCLogo(VLCPlugin *p): VLCInterface<VLCLogo,IVLCLogo>(p) { }
STDMETHODIMP enable() { return do_put_int(libvlc_logo_enable, true); }
STDMETHODIMP disable() { return do_put_int(libvlc_logo_enable, false); }
STDMETHODIMP file(BSTR fname);
#define PROP_INT( a ) \
STDMETHODIMP get_##a(LONG *val) \
{ return do_get_int(libvlc_logo_##a,val); } \
STDMETHODIMP put_##a(LONG val) \
{ return do_put_int(libvlc_logo_##a,val); }
PROP_INT( delay )
PROP_INT( repeat )
PROP_INT( opacity )
PROP_INT( x )
PROP_INT( y )
#undef PROP_INT
STDMETHODIMP get_position(BSTR* val);
STDMETHODIMP put_position(BSTR val);
private:
HRESULT do_put_int(unsigned idx, LONG val);
HRESULT do_get_int(unsigned idx, LONG *val);
};
class VLCDeinterlace: public VLCInterface<VLCDeinterlace,IVLCDeinterlace>
{
public:
VLCDeinterlace(VLCPlugin *p):
VLCInterface<VLCDeinterlace,IVLCDeinterlace>(p) { }
STDMETHODIMP enable(BSTR val);
STDMETHODIMP disable();
};
class VLCPlaylistItems: public VLCInterface<VLCPlaylistItems,IVLCPlaylistItems>
{
public:
VLCPlaylistItems(VLCPlugin *p):
VLCInterface<VLCPlaylistItems,IVLCPlaylistItems>(p) { }
// IVLCPlaylistItems methods
STDMETHODIMP get_count(long*);
STDMETHODIMP clear();
STDMETHODIMP remove(long);
};
class VLCPlaylist: public VLCInterface<VLCPlaylist,IVLCPlaylist>
{
public:
VLCPlaylist(VLCPlugin *p):
VLCInterface<VLCPlaylist,IVLCPlaylist>(p),
_p_vlcplaylistitems(new VLCPlaylistItems(p)) { }
virtual ~VLCPlaylist() { delete _p_vlcplaylistitems; }
// IVLCPlaylist methods
STDMETHODIMP get_itemCount(long*);
STDMETHODIMP get_isPlaying(VARIANT_BOOL*);
STDMETHODIMP add(BSTR, VARIANT, VARIANT, long*);
STDMETHODIMP play();
STDMETHODIMP playItem(long);
STDMETHODIMP togglePause();
STDMETHODIMP stop();
STDMETHODIMP next();
STDMETHODIMP prev();
STDMETHODIMP clear();
STDMETHODIMP removeItem(long);
STDMETHODIMP get_items(IVLCPlaylistItems**);
private:
VLCPlaylistItems* _p_vlcplaylistitems;
};
class VLCSubtitle: public VLCInterface<VLCSubtitle,IVLCSubtitle>
{
public:
VLCSubtitle(VLCPlugin *p): VLCInterface<VLCSubtitle,IVLCSubtitle>(p) { }
// IVLCSubtitle methods
STDMETHODIMP get_track(long*);
STDMETHODIMP put_track(long);
STDMETHODIMP get_count(long*);
STDMETHODIMP description(long, BSTR*);
};
class VLCVideo: public VLCInterface<VLCVideo,IVLCVideo>
{
public:
VLCVideo(VLCPlugin *p): VLCInterface<VLCVideo,IVLCVideo>(p),
_p_vlcmarquee(new VLCMarquee(p)), _p_vlclogo(new VLCLogo(p)),
_p_vlcdeint(new VLCDeinterlace(p)) { }
virtual ~VLCVideo() {
delete _p_vlcmarquee;
delete _p_vlclogo;
delete _p_vlcdeint;
}
// IVLCVideo methods
STDMETHODIMP get_fullscreen(VARIANT_BOOL*);
STDMETHODIMP put_fullscreen(VARIANT_BOOL);
STDMETHODIMP get_width(long*);
STDMETHODIMP get_height(long*);
STDMETHODIMP get_aspectRatio(BSTR*);
STDMETHODIMP put_aspectRatio(BSTR);
STDMETHODIMP get_subtitle(long*);
STDMETHODIMP put_subtitle(long);
STDMETHODIMP get_crop(BSTR*);
STDMETHODIMP put_crop(BSTR);
STDMETHODIMP get_teletext(long*);
STDMETHODIMP put_teletext(long);
STDMETHODIMP get_marquee(IVLCMarquee**);
STDMETHODIMP get_logo(IVLCLogo**);
STDMETHODIMP get_deinterlace(IVLCDeinterlace**);
STDMETHODIMP takeSnapshot(LPPICTUREDISP*);
STDMETHODIMP toggleFullscreen();
STDMETHODIMP toggleTeletext();
private:
IVLCMarquee *_p_vlcmarquee;
IVLCLogo *_p_vlclogo;
IVLCDeinterlace *_p_vlcdeint;
};
class VLCControl2 : public IVLCControl2
{
public:
VLCControl2(VLCPlugin *p_instance);
virtual ~VLCControl2();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IDispatch == riid)
|| (IID_IVLCControl2 == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IDispatch methods
STDMETHODIMP GetTypeInfoCount(UINT*);
STDMETHODIMP GetTypeInfo(UINT, LCID, LPTYPEINFO*);
STDMETHODIMP GetIDsOfNames(REFIID,LPOLESTR*,UINT,LCID,DISPID*);
STDMETHODIMP Invoke(DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
// IVLCControl2 methods
STDMETHODIMP get_AutoLoop(VARIANT_BOOL *autoloop);
STDMETHODIMP put_AutoLoop(VARIANT_BOOL autoloop);
STDMETHODIMP get_AutoPlay(VARIANT_BOOL *autoplay);
STDMETHODIMP put_AutoPlay(VARIANT_BOOL autoplay);
STDMETHODIMP get_BaseURL(BSTR *url);
STDMETHODIMP put_BaseURL(BSTR url);
STDMETHODIMP get_MRL(BSTR *mrl);
STDMETHODIMP put_MRL(BSTR mrl);
STDMETHODIMP get_Toolbar(VARIANT_BOOL *visible);
STDMETHODIMP put_Toolbar(VARIANT_BOOL visible);
STDMETHODIMP get_StartTime(long *seconds);
STDMETHODIMP put_StartTime(long seconds);
STDMETHODIMP get_VersionInfo(BSTR *version);
STDMETHODIMP get_Visible(VARIANT_BOOL *visible);
STDMETHODIMP put_Visible(VARIANT_BOOL visible);
STDMETHODIMP get_Volume(long *volume);
STDMETHODIMP put_Volume(long volume);
STDMETHODIMP get_BackColor(OLE_COLOR *backcolor);
STDMETHODIMP put_BackColor(OLE_COLOR backcolor);
STDMETHODIMP get_audio(IVLCAudio**);
STDMETHODIMP get_input(IVLCInput**);
STDMETHODIMP get_playlist(IVLCPlaylist**);
STDMETHODIMP get_subtitle(IVLCSubtitle**);
STDMETHODIMP get_video(IVLCVideo**);
protected:
HRESULT loadTypeInfo();
private:
VLCPlugin *_p_instance;
ITypeInfo *_p_typeinfo;
IVLCAudio *_p_vlcaudio;
IVLCInput *_p_vlcinput;
IVLCPlaylist *_p_vlcplaylist;
IVLCSubtitle *_p_vlcsubtitle;
IVLCVideo *_p_vlcvideo;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment