From a593fa18ef93069b6152cc571561c5ccc053e67b Mon Sep 17 00:00:00 2001 From: Damien Fouilleul <damienf@videolan.org> Date: Sun, 27 Aug 2006 16:18:59 +0000 Subject: [PATCH] all: rewrite of mozilla plugin - added a couple of support APIs in libvlc - retired XPCOM interface, all scripting now goes through NPObject apis - new APIs using libvlc (roughly similar to java bindings) --- include/video_output.h | 3 +- include/vlc/libvlc.h | 49 +- modules/gui/macosx/voutgl.m | 158 +++-- mozilla/Makefile.am | 28 +- mozilla/control/npolibvlc.cpp | 885 ++++++++++++++++++++++++ mozilla/control/npolibvlc.h | 139 ++++ mozilla/control/nporuntime.cpp | 92 +++ mozilla/control/nporuntime.h | 298 ++++++++ mozilla/control/npovlc.cpp | 704 +++++++++++++++++++ mozilla/{vlcpeer.h => control/npovlc.h} | 109 ++- mozilla/vlcintf.idl | 42 -- mozilla/vlcpeer.cpp | 314 --------- mozilla/vlcplugin.cpp | 358 +++++++++- mozilla/vlcplugin.h | 76 +- mozilla/vlcruntime.cpp | 381 ---------- mozilla/vlcruntime.h | 261 ------- mozilla/vlcshell.cpp | 680 ++++++------------ src/control/video.c | 90 +++ src/libvlc.c | 19 +- 19 files changed, 2991 insertions(+), 1695 deletions(-) create mode 100755 mozilla/control/npolibvlc.cpp create mode 100755 mozilla/control/npolibvlc.h create mode 100755 mozilla/control/nporuntime.cpp create mode 100755 mozilla/control/nporuntime.h create mode 100755 mozilla/control/npovlc.cpp rename mozilla/{vlcpeer.h => control/npovlc.h} (52%) mode change 100644 => 100755 delete mode 100644 mozilla/vlcintf.idl delete mode 100644 mozilla/vlcpeer.cpp delete mode 100755 mozilla/vlcruntime.cpp delete mode 100755 mozilla/vlcruntime.h diff --git a/include/video_output.h b/include/video_output.h index cac8d72b5fe2..500adeb23907 100644 --- a/include/video_output.h +++ b/include/video_output.h @@ -275,7 +275,8 @@ enum output_query_e VOUT_REPARENT, VOUT_SNAPSHOT, VOUT_CLOSE, - VOUT_SET_FOCUS /* arg1= vlc_bool_t res= */ + VOUT_SET_FOCUS, /* arg1= vlc_bool_t res= */ + VOUT_SET_VIEWPORT /* arg1= view rect, arg2=clip rect, res= */ }; /** diff --git a/include/vlc/libvlc.h b/include/vlc/libvlc.h index 28f73c17e3ef..0fe28590aa10 100644 --- a/include/vlc/libvlc.h +++ b/include/vlc/libvlc.h @@ -356,7 +356,7 @@ void libvlc_video_resize( libvlc_input_t *, int, int, libvlc_exception_t *); typedef int libvlc_drawable_t; /** - * Get current mute status + * change the video output parent * \param p_instance libvlc instance * \param drawable the new parent window (Drawable on X11, CGrafPort on MacOSX, HWND on Win32) * \param p_exception an initialized exception @@ -364,6 +364,45 @@ typedef int libvlc_drawable_t; */ int libvlc_video_reparent( libvlc_input_t *, libvlc_drawable_t, libvlc_exception_t * ); +/** + * Set the video output parent + * \param p_instance libvlc instance + * \param drawable the new parent window (Drawable on X11, CGrafPort on MacOSX, HWND on Win32) + * \param p_exception an initialized exception + */ +void libvlc_video_set_parent( libvlc_instance_t *, libvlc_drawable_t, libvlc_exception_t * ); + +/** + * Set the video output size + * \param p_instance libvlc instance + * \param width new width for video drawable + * \param height new height for video drawable + * \param p_exception an initialized exception + */ +void libvlc_video_set_size( libvlc_instance_t *, int, int, libvlc_exception_t * ); + +/** +* Downcast to this general type as placeholder for a platform specific one, such as: +* Drawable on X11, +* CGrafPort on MacOSX, +* HWND on win32 +*/ +typedef struct +{ + int top, left; + int bottom, right; +} +libvlc_rectangle_t; + +/** + * Set the video output viewport for a windowless video ouput (MacOS X only) + * \param p_instance libvlc instance + * \param view coordinates within video drawable + * \param clip coordinates within video drawable + * \param p_exception an initialized exception + */ +void libvlc_video_set_viewport( libvlc_instance_t *, const libvlc_rectangle_t *, const libvlc_rectangle_t *, libvlc_exception_t * ); + /** @} */ @@ -380,6 +419,14 @@ int libvlc_video_reparent( libvlc_input_t *, libvlc_drawable_t, libvlc_exception * @{ */ +/** + * Toggle mute status + * \param p_instance libvlc instance + * \param p_exception an initialized exception + * \return void + */ +void libvlc_audio_toggle_mute( libvlc_instance_t *, libvlc_exception_t * ); + /** * Get current mute status * \param p_instance libvlc instance diff --git a/modules/gui/macosx/voutgl.m b/modules/gui/macosx/voutgl.m index f8b9033e00d9..89a27b9fa2b2 100644 --- a/modules/gui/macosx/voutgl.m +++ b/modules/gui/macosx/voutgl.m @@ -86,11 +86,9 @@ static void Unlock ( vout_thread_t * p_vout ); static int aglInit ( vout_thread_t * p_vout ); static void aglEnd ( vout_thread_t * p_vout ); static int aglManage ( vout_thread_t * p_vout ); +static int aglControl( vout_thread_t *, int, va_list ); static void aglSwap ( vout_thread_t * p_vout ); -static int DrawableRedraw( vlc_object_t *p_this, const char *psz_name, - vlc_value_t oval, vlc_value_t nval, void *param); - int E_(OpenVideoGL) ( vlc_object_t * p_this ) { vout_thread_t * p_vout = (vout_thread_t *) p_this; @@ -131,19 +129,11 @@ int E_(OpenVideoGL) ( vlc_object_t * p_this ) AGL_DEPTH_SIZE, 24, AGL_NONE }; - AGLDevice screen; AGLPixelFormat pixFormat; p_vout->p_sys->b_embedded = VLC_TRUE; - screen = GetGWorldDevice((CGrafPtr)value_drawable.i_int); - if( NULL == screen ) - { - msg_Err( p_vout, "can't find screen device for drawable" ); - return VLC_EGENERIC; - } - - pixFormat = aglChoosePixelFormat(&screen, 1, ATTRIBUTES); + pixFormat = aglChoosePixelFormat(NULL, 0, ATTRIBUTES); if( NULL == pixFormat ) { msg_Err( p_vout, "no screen renderer available for required attributes." ); @@ -158,8 +148,8 @@ int E_(OpenVideoGL) ( vlc_object_t * p_this ) return VLC_EGENERIC; } else { - // tell opengl to sync buffer swap with vertical retrace - GLint param = 1; + // tell opengl not to sync buffer swap with vertical retrace + GLint param = 0; aglSetInteger(p_vout->p_sys->agl_ctx, AGL_SWAP_INTERVAL, ¶m); aglEnable(p_vout->p_sys->agl_ctx, AGL_SWAP_INTERVAL); } @@ -167,7 +157,7 @@ int E_(OpenVideoGL) ( vlc_object_t * p_this ) p_vout->pf_init = aglInit; p_vout->pf_end = aglEnd; p_vout->pf_manage = aglManage; - p_vout->pf_control = NULL; + p_vout->pf_control = aglControl; p_vout->pf_swap = aglSwap; p_vout->pf_lock = Lock; p_vout->pf_unlock = Unlock; @@ -207,7 +197,6 @@ void E_(CloseVideoGL) ( vlc_object_t * p_this ) vout_thread_t * p_vout = (vout_thread_t *) p_this; if( p_vout->p_sys->b_embedded ) { - var_DelCallback(p_vout->p_vlc, "drawableredraw", DrawableRedraw, p_vout); aglDestroyContext(p_vout->p_sys->agl_ctx); } else @@ -456,13 +445,38 @@ static void Unlock( vout_thread_t * p_vout ) * embedded AGL context implementation *****************************************************************************/ -static void UpdateEmbeddedGeometry( vout_thread_t *p_vout ); +static void aglSetViewport( vout_thread_t *p_vout, Rect viewBounds, Rect clipBounds ); static void aglReshape( vout_thread_t * p_vout ); static int aglInit( vout_thread_t * p_vout ) { - UpdateEmbeddedGeometry(p_vout); - var_AddCallback(p_vout->p_vlc, "drawableredraw", DrawableRedraw, p_vout); + vlc_value_t val; + + Rect viewBounds; + Rect clipBounds; + + var_Get( p_vout->p_vlc, "drawable", &val ); + p_vout->p_sys->agl_drawable = (AGLDrawable)val.i_int; + aglSetDrawable(p_vout->p_sys->agl_ctx, p_vout->p_sys->agl_drawable); + + var_Get( p_vout->p_vlc, "drawable-view-top", &val ); + viewBounds.top = val.i_int; + var_Get( p_vout->p_vlc, "drawable-view-left", &val ); + viewBounds.left = val.i_int; + var_Get( p_vout->p_vlc, "drawable-view-bottom", &val ); + viewBounds.bottom = val.i_int; + var_Get( p_vout->p_vlc, "drawable-view-right", &val ); + viewBounds.right = val.i_int; + var_Get( p_vout->p_vlc, "drawable-clip-top", &val ); + clipBounds.top = val.i_int; + var_Get( p_vout->p_vlc, "drawable-clip-left", &val ); + clipBounds.left = val.i_int; + var_Get( p_vout->p_vlc, "drawable-clip-bottom", &val ); + clipBounds.bottom = val.i_int; + var_Get( p_vout->p_vlc, "drawable-clip-right", &val ); + clipBounds.right = val.i_int; + + aglSetViewport(p_vout, viewBounds, clipBounds); aglSetCurrentContext(p_vout->p_sys->agl_ctx); return VLC_SUCCESS; @@ -547,84 +561,80 @@ static int aglManage( vout_thread_t * p_vout ) return VLC_SUCCESS; } +static int aglControl( vout_thread_t *p_vout, int i_query, va_list args ) +{ + switch( i_query ) + { + case VOUT_SET_VIEWPORT: + { + Rect viewBounds, clipBounds; + viewBounds.top = va_arg( args, int); + viewBounds.left = va_arg( args, int); + viewBounds.bottom = va_arg( args, int); + viewBounds.right = va_arg( args, int); + clipBounds.top = va_arg( args, int); + clipBounds.left = va_arg( args, int); + clipBounds.bottom = va_arg( args, int); + clipBounds.right = va_arg( args, int); + aglSetViewport(p_vout, viewBounds, clipBounds); + return VLC_SUCCESS; + } + + case VOUT_REPARENT: + { + AGLDrawable drawable = (AGLDrawable)va_arg( args, int); + if( drawable != p_vout->p_sys->agl_drawable ) + { + p_vout->p_sys->agl_drawable = drawable; + aglSetDrawable(p_vout->p_sys->agl_ctx, drawable); + } + return VLC_SUCCESS; + } + + default: + return vout_vaControlDefault( p_vout, i_query, args ); + } +} + static void aglSwap( vout_thread_t * p_vout ) { p_vout->p_sys->b_got_frame = VLC_TRUE; aglSwapBuffers(p_vout->p_sys->agl_ctx); } -static void UpdateEmbeddedGeometry( vout_thread_t *p_vout ) +static void aglSetViewport( vout_thread_t *p_vout, Rect viewBounds, Rect clipBounds ) { - vlc_value_t val; - vlc_value_t valt, vall, valb, valr, valx, valy, valw, valh, - valportx, valporty; - - Rect winBounds; - Rect clientBounds; - - GLint rect[4]; - - var_Get( p_vout->p_vlc, "drawable", &val ); - var_Get( p_vout->p_vlc, "drawablet", &valt ); - var_Get( p_vout->p_vlc, "drawablel", &vall ); - var_Get( p_vout->p_vlc, "drawableb", &valb ); - var_Get( p_vout->p_vlc, "drawabler", &valr ); - var_Get( p_vout->p_vlc, "drawablex", &valx ); - var_Get( p_vout->p_vlc, "drawabley", &valy ); - var_Get( p_vout->p_vlc, "drawablew", &valw ); - var_Get( p_vout->p_vlc, "drawableh", &valh ); - var_Get( p_vout->p_vlc, "drawableportx", &valportx ); - var_Get( p_vout->p_vlc, "drawableporty", &valporty ); - // mozilla plugin provides coordinates based on port bounds // however AGL coordinates are based on window structure region // and are vertically flipped + GLint rect[4]; + CGrafPtr port = (CGrafPtr)p_vout->p_sys->agl_drawable; + Rect winBounds, clientBounds; - GetWindowBounds(GetWindowFromPort((CGrafPtr)val.i_int), + GetWindowBounds(GetWindowFromPort(port), kWindowStructureRgn, &winBounds); - GetWindowBounds(GetWindowFromPort((CGrafPtr)val.i_int), + GetWindowBounds(GetWindowFromPort(port), kWindowContentRgn, &clientBounds); /* update video clipping bounds in drawable */ rect[0] = (clientBounds.left-winBounds.left) - + vall.i_int; // from window left edge + + clipBounds.left; // from window left edge rect[1] = (winBounds.bottom-winBounds.top) - (clientBounds.top-winBounds.top) - - valb.i_int; // from window bottom edge - rect[2] = valr.i_int-vall.i_int; // width - rect[3] = valb.i_int-valt.i_int; // height + - clipBounds.bottom; // from window bottom edge + rect[2] = clipBounds.right-clipBounds.left; // width + rect[3] = clipBounds.bottom-clipBounds.top; // height aglSetInteger(p_vout->p_sys->agl_ctx, AGL_BUFFER_RECT, rect); aglEnable(p_vout->p_sys->agl_ctx, AGL_BUFFER_RECT); /* update video internal bounds in drawable */ - p_vout->p_sys->i_offx = -vall.i_int - valportx.i_int; - p_vout->p_sys->i_offy = valb.i_int + valporty.i_int - valh.i_int; - p_vout->p_sys->i_width = valw.i_int; - p_vout->p_sys->i_height = valh.i_int; + p_vout->p_sys->i_width = viewBounds.right-viewBounds.left; + p_vout->p_sys->i_height = viewBounds.bottom-viewBounds.top; + p_vout->p_sys->i_offx = -clipBounds.left - viewBounds.left; + p_vout->p_sys->i_offy = clipBounds.bottom + viewBounds.top + - p_vout->p_sys->i_height; - if( p_vout->p_sys->agl_drawable == (AGLDrawable)val.i_int ) - { - aglUpdateContext(p_vout->p_sys->agl_ctx); - } - else - { - p_vout->p_sys->agl_drawable = (AGLDrawable)val.i_int; - aglSetDrawable(p_vout->p_sys->agl_ctx, p_vout->p_sys->agl_drawable); - } + aglUpdateContext(p_vout->p_sys->agl_ctx); aglReshape( p_vout ); } -/* If we're embedded, the application is expected to indicate a - * window change (move/resize/etc) via the "drawableredraw" value. - */ - -static int DrawableRedraw( vlc_object_t *p_this, const char *psz_name, - vlc_value_t oval, vlc_value_t nval, void *param) -{ - vout_thread_t *p_vout = (vout_thread_t *)param; - - UpdateEmbeddedGeometry( p_vout ); - - return VLC_SUCCESS; -} - diff --git a/mozilla/Makefile.am b/mozilla/Makefile.am index 0b28ea146ed8..1eb2e4f2f84d 100644 --- a/mozilla/Makefile.am +++ b/mozilla/Makefile.am @@ -4,18 +4,20 @@ noinst_LIBRARIES = $(noinst_LIBRARIES_mozilla) -MOSTLYCLEANFILES = $(npvlc_DATA) $(vlcintf_xpt_DATA) +MOSTLYCLEANFILES = $(npvlc_DATA) CLEANFILES = stamp-pic $(BUILT_SOURCES) -EXTRA_DIST = $(DIST_sources) vlcintf.idl npvlc_rc.rc vlc.r +EXTRA_DIST = $(DIST_sources) npvlc_rc.rc vlc.r SOURCES_mozilla_common = \ vlcshell.cpp \ vlcplugin.cpp \ vlcplugin.h \ - vlcpeer.cpp \ - vlcpeer.h \ - vlcruntime.cpp \ - vlcruntime.h \ + control/npolibvlc.cpp \ + control/npolibvlc.h \ + control/npovlc.cpp \ + control/npovlc.h \ + control/nporuntime.cpp \ + control/nporuntime.h \ support/classinfo.h DIST_sources = $(SOURCES_mozilla_common) \ @@ -141,11 +143,6 @@ endif noinst_LIBRARIES_mozilla = libnpvlc.a -$(SOURCES_mozilla): vlcintf.h - -BUILT_SOURCES = vlcintf.h -vlcintf_xpt_DATA = vlcintf.xpt - if USE_LIBTOOL # FIXME: name is incorrect on Win32 & Darwin npvlc_LTLIBRARIES = libvlcplugin.la @@ -175,15 +172,6 @@ $(npvlc): $(libnpvlc_a_OBJECTS) $(libnpvlc_a_DEPENDENCIES) stamp-pic # Cygwin work-around @if test -f "$@.exe"; then mv -f "$@.exe" "$@"; fi -vlcintf_xptdir = $(libdir)/mozilla/components -vlcintf.xpt: vlcintf.idl - $(XPIDL) $(XPIDL_INCL) \ - -m typelib -o vlcintf $(srcdir)/vlcintf.idl - -vlcintf.h: vlcintf.idl - $(XPIDL) $(XPIDL_INCL) \ - -m header -o vlcintf $(srcdir)/vlcintf.idl - ############################################################################### # Stamp rules ############################################################################### diff --git a/mozilla/control/npolibvlc.cpp b/mozilla/control/npolibvlc.cpp new file mode 100755 index 000000000000..3d712817b843 --- /dev/null +++ b/mozilla/control/npolibvlc.cpp @@ -0,0 +1,885 @@ +/***************************************************************************** + * vlc.cpp: support for NPRuntime API for Netscape Script-able plugins + * FYI: http://www.mozilla.org/projects/plugins/npruntime.html + ***************************************************************************** + * 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 "config.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +/* Mozilla stuff */ +#ifdef HAVE_MOZILLA_CONFIG_H +# include <mozilla-config.h> +#endif + +#include "npolibvlc.h" +#include "vlcplugin.h" + +/* +** implementation of libvlc root object +*/ + +LibvlcRootNPObject::LibvlcRootNPObject(NPP instance, const NPClass *aClass) : + RuntimeNPObject(instance, aClass) +{ + static NPClass *audioClass = new RuntimeNPClass<LibvlcAudioNPObject>(); + static NPClass *inputClass = new RuntimeNPClass<LibvlcInputNPObject>(); + static NPClass *playlistClass = new RuntimeNPClass<LibvlcPlaylistNPObject>(); + static NPClass *videoClass = new RuntimeNPClass<LibvlcVideoNPObject>(); + + audioObj = NPN_CreateObject(instance, audioClass); + inputObj = NPN_CreateObject(instance, inputClass); + playlistObj = NPN_CreateObject(instance, playlistClass); + videoObj = NPN_CreateObject(instance, videoClass); +} + +LibvlcRootNPObject::~LibvlcRootNPObject() +{ + NPN_ReleaseObject(audioObj); + NPN_ReleaseObject(inputObj); + NPN_ReleaseObject(playlistObj); + NPN_ReleaseObject(videoObj); +} + +const NPUTF8 * const LibvlcRootNPObject::propertyNames[] = +{ + "audio", + "input", + "playlist", + "video", +}; + +enum LibvlcRootNPObjectPropertyIds +{ + ID_audio = 0, + ID_input, + ID_playlist, + ID_video, +}; + +const int LibvlcRootNPObject::propertyCount = sizeof(LibvlcRootNPObject::propertyNames)/sizeof(NPUTF8 *); + +RuntimeNPObject::InvokeResult LibvlcRootNPObject::getProperty(int index, NPVariant *result) +{ + switch( index ) + { + case ID_audio: + OBJECT_TO_NPVARIANT(NPN_RetainObject(audioObj), *result); + return INVOKERESULT_NO_ERROR; + case ID_input: + OBJECT_TO_NPVARIANT(NPN_RetainObject(inputObj), *result); + return INVOKERESULT_NO_ERROR; + case ID_playlist: + OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistObj), *result); + return INVOKERESULT_NO_ERROR; + case ID_video: + OBJECT_TO_NPVARIANT(NPN_RetainObject(videoObj), *result); + return INVOKERESULT_NO_ERROR; + } + return INVOKERESULT_GENERIC_ERROR; +} + +const NPUTF8 * const LibvlcRootNPObject::methodNames[] = +{ + /* no methods */ +}; + +const int LibvlcRootNPObject::methodCount = sizeof(LibvlcRootNPObject::methodNames)/sizeof(NPUTF8 *); + +/* +** implementation of libvlc audio object +*/ + +const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] = +{ + "mute", + "volume", +}; + +enum LibvlcAudioNPObjectPropertyIds +{ + ID_mute, + ID_volume, +}; + +const int LibvlcAudioNPObject::propertyCount = sizeof(LibvlcAudioNPObject::propertyNames)/sizeof(NPUTF8 *); + +RuntimeNPObject::InvokeResult LibvlcAudioNPObject::getProperty(int index, NPVariant *result) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + switch( index ) + { + case ID_mute: + { + vlc_bool_t muted = libvlc_audio_get_mute(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + BOOLEAN_TO_NPVARIANT(muted, *result); + return INVOKERESULT_NO_ERROR; + } + case ID_volume: + { + int volume = libvlc_audio_get_volume(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + INT32_TO_NPVARIANT(volume, *result); + return INVOKERESULT_NO_ERROR; + } + } + } + return INVOKERESULT_GENERIC_ERROR; +} + +RuntimeNPObject::InvokeResult LibvlcAudioNPObject::setProperty(int index, const NPVariant *value) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + switch( index ) + { + case ID_mute: + if( NPVARIANT_IS_BOOLEAN(*value) ) + { + libvlc_audio_set_mute(p_plugin->getVLC(), + NPVARIANT_TO_BOOLEAN(*value), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + return INVOKERESULT_NO_ERROR; + } + return INVOKERESULT_INVALID_VALUE; + case ID_volume: + if( isNumberValue(*value) ) + { + libvlc_audio_set_volume(p_plugin->getVLC(), + numberValue(*value), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + return INVOKERESULT_NO_ERROR; + } + return INVOKERESULT_INVALID_VALUE; + } + } + return INVOKERESULT_GENERIC_ERROR; +} + +const NPUTF8 * const LibvlcAudioNPObject::methodNames[] = +{ + "togglemute", +}; + +enum LibvlcAudioNPObjectMethodIds +{ + ID_togglemute, +}; + +const int LibvlcAudioNPObject::methodCount = sizeof(LibvlcAudioNPObject::methodNames)/sizeof(NPUTF8 *); + +RuntimeNPObject::InvokeResult LibvlcAudioNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + switch( index ) + { + case ID_togglemute: + if( argCount == 0 ) + { + libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + default: + return INVOKERESULT_NO_SUCH_METHOD; + } + } + return INVOKERESULT_GENERIC_ERROR; +} + +/* +** implementation of libvlc input object +*/ + +const NPUTF8 * const LibvlcInputNPObject::propertyNames[] = +{ + "length", + "position", + "time", + "fps", + "hasvout", +}; + +enum LibvlcInputNPObjectPropertyIds +{ + ID_length, + ID_position, + ID_time, + ID_fps, + ID_hasvout, +}; + +const int LibvlcInputNPObject::propertyCount = sizeof(LibvlcInputNPObject::propertyNames)/sizeof(NPUTF8 *); + +RuntimeNPObject::InvokeResult LibvlcInputNPObject::getProperty(int index, NPVariant *result) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + + switch( index ) + { + case ID_length: + { + double val = (double)libvlc_input_get_length(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + DOUBLE_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + case ID_position: + { + double val = libvlc_input_get_position(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + DOUBLE_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + case ID_time: + { + double val = (double)libvlc_input_get_time(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + DOUBLE_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + case ID_fps: + { + double val = libvlc_input_get_fps(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + DOUBLE_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + case ID_hasvout: + { + vlc_bool_t val = libvlc_input_has_vout(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + BOOLEAN_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + } + libvlc_input_free(p_input); + } + return INVOKERESULT_GENERIC_ERROR; +} + +RuntimeNPObject::InvokeResult LibvlcInputNPObject::setProperty(int index, const NPVariant *value) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + + switch( index ) + { + case ID_position: + { + if( ! NPVARIANT_IS_DOUBLE(*value) ) + { + libvlc_input_free(p_input); + return INVOKERESULT_INVALID_VALUE; + } + + float val = (float)NPVARIANT_TO_DOUBLE(*value); + libvlc_input_set_position(p_input, val, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + return INVOKERESULT_NO_ERROR; + } + case ID_time: + { + vlc_int64_t val; + if( NPVARIANT_IS_INT32(*value) ) + val = (vlc_int64_t)NPVARIANT_TO_INT32(*value); + else if( NPVARIANT_IS_DOUBLE(*value) ) + val = (vlc_int64_t)NPVARIANT_TO_DOUBLE(*value); + else + { + libvlc_input_free(p_input); + return INVOKERESULT_INVALID_VALUE; + } + + libvlc_input_set_time(p_input, val, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + return INVOKERESULT_NO_ERROR; + } + } + libvlc_input_free(p_input); + } + return INVOKERESULT_GENERIC_ERROR; +} + +const NPUTF8 * const LibvlcInputNPObject::methodNames[] = +{ + /* no methods */ +}; + +const int LibvlcInputNPObject::methodCount = sizeof(LibvlcInputNPObject::methodNames)/sizeof(NPUTF8 *); + +/* +** implementation of libvlc playlist object +*/ + + +const NPUTF8 * const LibvlcPlaylistNPObject::propertyNames[] = +{ + "itemscount", + "isplaying", +}; + +enum LibvlcPlaylistNPObjectPropertyIds +{ + ID_itemscount, + ID_isplaying, +}; + +const int LibvlcPlaylistNPObject::propertyCount = sizeof(LibvlcPlaylistNPObject::propertyNames)/sizeof(NPUTF8 *); + +RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::getProperty(int index, NPVariant *result) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + switch( index ) + { + case ID_itemscount: + { + int val = libvlc_playlist_items_count(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + INT32_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + case ID_isplaying: + { + int val = libvlc_playlist_isplaying(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + BOOLEAN_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + } + } + return INVOKERESULT_GENERIC_ERROR; +} + +const NPUTF8 * const LibvlcPlaylistNPObject::methodNames[] = +{ + "add", + "play", + "togglepause" + "stop", + "next", + "prev", + "clear", + "deleteitem" +}; + +enum LibvlcPlaylistNPObjectMethodIds +{ + ID_add, + ID_play, + ID_togglepause, + ID_stop, + ID_next, + ID_prev, + ID_clear, + ID_deleteitem, +}; + +const int LibvlcPlaylistNPObject::methodCount = sizeof(LibvlcPlaylistNPObject::methodNames)/sizeof(NPUTF8 *); + +RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + switch( index ) + { + case ID_add: + if( (argCount == 1) && NPVARIANT_IS_STRING(args[0]) ) + { + const NPString &name = NPVARIANT_TO_STRING(args[0]); + NPUTF8 *s = new NPUTF8[name.utf8length+1]; + if( s ) + { + strncpy(s, name.utf8characters, name.utf8length); + s[name.utf8length] = '\0'; + + char *url = p_plugin->getAbsoluteURL(s); + delete s; + if( ! url ) + // what happened ? + return INVOKERESULT_GENERIC_ERROR; + + int item = libvlc_playlist_add(p_plugin->getVLC(), url, NULL, &ex); + free(url); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + INT32_TO_NPVARIANT(item, *result); + return INVOKERESULT_NO_ERROR; + } + } + else + return INVOKERESULT_OUT_OF_MEMORY; + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_play: + if( argCount == 0 ) + { + libvlc_playlist_play(p_plugin->getVLC(), -1, 0, NULL, &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_togglepause: + if( argCount == 0 ) + { + libvlc_playlist_pause(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_stop: + if( argCount == 0 ) + { + libvlc_playlist_stop(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_next: + if( argCount == 0 ) + { + libvlc_playlist_next(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_prev: + if( argCount == 0 ) + { + libvlc_playlist_prev(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_clear: + if( argCount == 0 ) + { + libvlc_playlist_clear(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_deleteitem: + if( (argCount == 1) && isNumberValue(args[0]) ) + { + libvlc_playlist_delete_item(p_plugin->getVLC(), numberValue(args[0]), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + default: + return INVOKERESULT_NO_SUCH_METHOD; + } + } + return INVOKERESULT_GENERIC_ERROR; +} + +/* +** implementation of libvlc video object +*/ + +const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] = +{ + "fullscreen", + "height", + "width", +}; + +enum LibvlcVideoNPObjectPropertyIds +{ + ID_fullscreen, + ID_height, + ID_width, +}; + +const int LibvlcVideoNPObject::propertyCount = sizeof(LibvlcVideoNPObject::propertyNames)/sizeof(NPUTF8 *); + +RuntimeNPObject::InvokeResult LibvlcVideoNPObject::getProperty(int index, NPVariant *result) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + + switch( index ) + { + case ID_fullscreen: + { + int val = libvlc_get_fullscreen(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + BOOLEAN_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + case ID_height: + { + int val = libvlc_video_get_height(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + INT32_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + case ID_width: + { + int val = libvlc_video_get_width(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + INT32_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + } + libvlc_input_free(p_input); + } + return INVOKERESULT_GENERIC_ERROR; +} + +RuntimeNPObject::InvokeResult LibvlcVideoNPObject::setProperty(int index, const NPVariant *value) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + + switch( index ) + { + case ID_fullscreen: + { + if( ! NPVARIANT_IS_BOOLEAN(*value) ) + { + libvlc_input_free(p_input); + return INVOKERESULT_INVALID_VALUE; + } + + int val = NPVARIANT_TO_BOOLEAN(*value); + libvlc_set_fullscreen(p_input, val, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + return INVOKERESULT_NO_ERROR; + } + } + libvlc_input_free(p_input); + } + return INVOKERESULT_GENERIC_ERROR; +} + +const NPUTF8 * const LibvlcVideoNPObject::methodNames[] = +{ + "togglefullscreen", +}; + +enum LibvlcVideoNPObjectMethodIds +{ + ID_togglefullscreen, +}; + +const int LibvlcVideoNPObject::methodCount = sizeof(LibvlcVideoNPObject::methodNames)/sizeof(NPUTF8 *); + +RuntimeNPObject::InvokeResult LibvlcVideoNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + + switch( index ) + { + case ID_togglefullscreen: + if( argCount == 0 ) + { + libvlc_toggle_fullscreen(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + else + { + /* cannot get input, probably not playing */ + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + } + return INVOKERESULT_GENERIC_ERROR; + } + return INVOKERESULT_NO_SUCH_METHOD; + default: + return INVOKERESULT_NO_SUCH_METHOD; + } + } + return INVOKERESULT_GENERIC_ERROR; +} + diff --git a/mozilla/control/npolibvlc.h b/mozilla/control/npolibvlc.h new file mode 100755 index 000000000000..e0346fcf39db --- /dev/null +++ b/mozilla/control/npolibvlc.h @@ -0,0 +1,139 @@ +/***************************************************************************** + * vlc.h: a VLC plugin for Mozilla + ***************************************************************************** + * Copyright (C) 2002-2005 the VideoLAN team + * $Id: vlcruntime.h 14466 2006-02-22 23:34:54Z dionoea $ + * + * 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. + *****************************************************************************/ + +/* +** defined runtime script objects +*/ + +#include "nporuntime.h" + +class LibvlcRootNPObject: public RuntimeNPObject +{ +public: + LibvlcRootNPObject(NPP instance, const NPClass *aClass); + virtual ~LibvlcRootNPObject(); + +protected: + friend class RuntimeNPClass<LibvlcRootNPObject>; + + static const int propertyCount; + static const NPUTF8 * const propertyNames[]; + + InvokeResult getProperty(int index, NPVariant *result); + + static const int methodCount; + static const NPUTF8 * const methodNames[]; + + NPObject *audioObj; + NPObject *inputObj; + NPObject *playlistObj; + NPObject *videoObj; +}; + +class LibvlcAudioNPObject: public RuntimeNPObject +{ +public: + LibvlcAudioNPObject(NPP instance, const NPClass *aClass) : + RuntimeNPObject(instance, aClass) {}; + virtual ~LibvlcAudioNPObject() {}; + +protected: + friend class RuntimeNPClass<LibvlcAudioNPObject>; + + static const int propertyCount; + static const NPUTF8 * const propertyNames[]; + + InvokeResult getProperty(int index, NPVariant *result); + InvokeResult setProperty(int index, const NPVariant *value); + + static const int methodCount; + static const NPUTF8 * const methodNames[]; + + InvokeResult invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result); +}; + +class LibvlcInputNPObject: public RuntimeNPObject +{ +public: + LibvlcInputNPObject(NPP instance, const NPClass *aClass) : + RuntimeNPObject(instance, aClass) {}; + + virtual ~LibvlcInputNPObject() {}; + +protected: + friend class RuntimeNPClass<LibvlcInputNPObject>; + + static const int propertyCount; + static const NPUTF8 * const propertyNames[]; + + InvokeResult getProperty(int index, NPVariant *result); + InvokeResult setProperty(int index, const NPVariant *value); + + static const int methodCount; + static const NPUTF8 * const methodNames[]; +}; + +class LibvlcPlaylistNPObject: public RuntimeNPObject +{ +public: + LibvlcPlaylistNPObject(NPP instance, const NPClass *aClass) : + RuntimeNPObject(instance, aClass) {}; + virtual ~LibvlcPlaylistNPObject() {}; + +protected: + friend class RuntimeNPClass<LibvlcPlaylistNPObject>; + + static const int propertyCount; + static const NPUTF8 * const propertyNames[]; + + InvokeResult getProperty(int index, NPVariant *result); + + static const int methodCount; + static const NPUTF8 * const methodNames[]; + + InvokeResult invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result); +}; + +class LibvlcVideoNPObject: public RuntimeNPObject +{ +public: + LibvlcVideoNPObject(NPP instance, const NPClass *aClass) : + RuntimeNPObject(instance, aClass) {}; + virtual ~LibvlcVideoNPObject() {}; + +protected: + friend class RuntimeNPClass<LibvlcVideoNPObject>; + + static const int propertyCount; + static const NPUTF8 * const propertyNames[]; + + InvokeResult getProperty(int index, NPVariant *result); + InvokeResult setProperty(int index, const NPVariant *value); + + static const int methodCount; + static const NPUTF8 * const methodNames[]; + + InvokeResult invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result); + +}; + diff --git a/mozilla/control/nporuntime.cpp b/mozilla/control/nporuntime.cpp new file mode 100755 index 000000000000..831cf10d08b0 --- /dev/null +++ b/mozilla/control/nporuntime.cpp @@ -0,0 +1,92 @@ +/***************************************************************************** + * runtime.cpp: support for NPRuntime API for Netscape Script-able plugins + * FYI: http://www.mozilla.org/projects/plugins/npruntime.html + ***************************************************************************** + * 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 "config.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +/* Mozilla stuff */ +#ifdef HAVE_MOZILLA_CONFIG_H +# include <mozilla-config.h> +#endif + +#include "nporuntime.h" +#include "vlcplugin.h" + +RuntimeNPObject::InvokeResult RuntimeNPObject::getProperty(int index, NPVariant *result) +{ + /* default behaviour */ + return INVOKERESULT_GENERIC_ERROR; +} + +RuntimeNPObject::InvokeResult RuntimeNPObject::setProperty(int index, const NPVariant *value) +{ + /* default behaviour */ + return INVOKERESULT_GENERIC_ERROR; +} + +RuntimeNPObject::InvokeResult RuntimeNPObject::removeProperty(int index) +{ + /* default behaviour */ + return INVOKERESULT_GENERIC_ERROR; +} + +RuntimeNPObject::InvokeResult RuntimeNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result) +{ + /* default beahviour */ + return INVOKERESULT_GENERIC_ERROR; +} + +RuntimeNPObject::InvokeResult RuntimeNPObject::invokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result) +{ + /* return void */ + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; +} + +bool RuntimeNPObject::returnInvokeResult(RuntimeNPObject::InvokeResult result) +{ + switch( result ) + { + case INVOKERESULT_NO_ERROR: + return true; + case INVOKERESULT_GENERIC_ERROR: + break; + case INVOKERESULT_NO_SUCH_METHOD: + NPN_SetException(this, "No such method or arguments mismatch"); + break; + case INVOKERESULT_INVALID_ARGS: + NPN_SetException(this, "Invalid arguments"); + break; + case INVOKERESULT_INVALID_VALUE: + NPN_SetException(this, "Invalid value in assignment"); + break; + case INVOKERESULT_OUT_OF_MEMORY: + NPN_SetException(this, "Out of memory"); + break; + } + return false; +} + diff --git a/mozilla/control/nporuntime.h b/mozilla/control/nporuntime.h new file mode 100755 index 000000000000..1d6237cccc55 --- /dev/null +++ b/mozilla/control/nporuntime.h @@ -0,0 +1,298 @@ +/***************************************************************************** + * runtime.h: a VLC plugin for Mozilla + ***************************************************************************** + * Copyright (C) 2002-2005 the VideoLAN team + * $Id: RuntimeNPObject.h 14466 2006-02-22 23:34:54Z dionoea $ + * + * 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 __NPORUNTIME_H__ +#define __NPORUNTIME_H__ + +/* +** support framework for runtime script objects +*/ + +#include <npapi.h> +#include <npruntime.h> + +class RuntimeNPObject : public NPObject +{ +public: + static bool isNumberValue(const NPVariant &v) + { + return NPVARIANT_IS_INT32(v) + || NPVARIANT_IS_DOUBLE(v); + }; + + static int numberValue(const NPVariant &v) + { + switch( v.type ) { + case NPVariantType_Int32: + return NPVARIANT_TO_INT32(v); + case NPVariantType_Double: + return(int)NPVARIANT_TO_DOUBLE(v); + default: + return 0; + } + }; + + RuntimeNPObject(NPP instance, const NPClass *aClass) : + _instance(instance) + { + _class = const_cast<NPClass *>(aClass); + referenceCount = 1; + }; + virtual ~RuntimeNPObject() {}; + + /* + ** utility functions + */ + +protected: + + enum InvokeResult + { + INVOKERESULT_NO_ERROR = 0, /* returns no error */ + INVOKERESULT_GENERIC_ERROR = 1, /* returns error */ + INVOKERESULT_NO_SUCH_METHOD = 2, /* throws method does not exist */ + INVOKERESULT_INVALID_ARGS = 3, /* throws invalid arguments */ + INVOKERESULT_INVALID_VALUE = 4, /* throws invalid value in assignment */ + INVOKERESULT_OUT_OF_MEMORY = 5, /* throws out of memory */ + }; + + template <class RuntimeNPObject> friend void RuntimeNPClassInvalidate(NPObject *npobj); + template <class RuntimeNPObject> friend bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result); + template <class RuntimeNPObject> friend bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value); + template <class RuntimeNPObject> friend bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name); + template <class RuntimeNPObject> friend bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name, + const NPVariant *args, uint32_t argCount, + NPVariant *result); + template <class RuntimeNPObject> friend bool RuntimeNPClassInvokeDefault(NPObject *npobj, + const NPVariant *args, + uint32_t argCount, + NPVariant *result); + + virtual InvokeResult getProperty(int index, NPVariant *result); + virtual InvokeResult setProperty(int index, const NPVariant *value); + virtual InvokeResult removeProperty(int index); + virtual InvokeResult invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result); + virtual InvokeResult invokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result); + + bool returnInvokeResult(InvokeResult result); + + NPP _instance; +}; + +template<class T> class RuntimeNPClass : public NPClass +{ +public: + RuntimeNPClass(); + virtual ~RuntimeNPClass(); + + /*template <class T> friend NPObject *RuntimeNPClassAllocate(NPP instance, NPClass *aClass); + template <class RuntimeNPObject> friend bool RuntimeNPClassHasMethod(NPObject *npobj, NPIdentifier name); + template <class RuntimeNPObject> friend bool RuntimeNPClassHasProperty(NPObject *npobj, NPIdentifier name);*/ + + RuntimeNPObject *create(NPP instance) const; + + int indexOfMethod(NPIdentifier name) const; + int indexOfProperty(NPIdentifier name) const; + +private: + NPIdentifier *propertyIdentifiers; + NPIdentifier *methodIdentifiers; +}; + +template<class T> +static NPObject *RuntimeNPClassAllocate(NPP instance, NPClass *aClass) +{ + const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(aClass); + return (NPObject *)vClass->create(instance); +} + +template<class T> +static void RuntimeNPClassDeallocate(NPObject *npobj) +{ + RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj); + delete vObj; +} + +template<class T> +static void RuntimeNPClassInvalidate(NPObject *npobj) +{ + RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj); + vObj->_instance = NULL; +} + +template<class T> +static bool RuntimeNPClassHasMethod(NPObject *npobj, NPIdentifier name) +{ + const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class); + return vClass->indexOfMethod(name) != -1; +} + +template<class T> +static bool RuntimeNPClassHasProperty(NPObject *npobj, NPIdentifier name) +{ + const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class); + return vClass->indexOfProperty(name) != -1; +} + +template<class T> +static bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) +{ + const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class); + int index = vClass->indexOfProperty(name); + if( index != -1 ) + { + RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj); + return vObj->returnInvokeResult(vObj->getProperty(index, result)); + } + return false; +} + +template<class T> +static bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) +{ + const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class); + int index = vClass->indexOfProperty(name); + if( index != -1 ) + { + RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj); + return vObj->returnInvokeResult(vObj->setProperty(index, value)); + } + return false; +} + +template<class T> +static bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name) +{ + const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class); + int index = vClass->indexOfProperty(name); + if( index != -1 ) + { + RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj); + return vObj->returnInvokeResult(vObj->removeProperty(index)); + } + return false; +} + +template<class T> +static bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name, + const NPVariant *args, uint32_t argCount, + NPVariant *result) +{ + const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class); + int index = vClass->indexOfMethod(name); + if( index != -1 ) + { + RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj); + return vObj->returnInvokeResult(vObj->invoke(index, args, argCount, result)); + + } + return false; +} + +template<class T> +static bool RuntimeNPClassInvokeDefault(NPObject *npobj, + const NPVariant *args, + uint32_t argCount, + NPVariant *result) +{ + RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj); + return vObj->returnInvokeResult(vObj->invokeDefault(args, argCount, result)); +} + +template<class T> +RuntimeNPClass<T>::RuntimeNPClass() +{ + // retreive property identifiers from names + if( T::propertyCount > 0 ) + { + propertyIdentifiers = new NPIdentifier[T::propertyCount]; + if( propertyIdentifiers ) + NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::propertyNames), + T::propertyCount, propertyIdentifiers); + } + + // retreive method identifiers from names + if( T::methodCount > 0 ) + { + methodIdentifiers = new NPIdentifier[T::methodCount]; + if( methodIdentifiers ) + NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::methodNames), + T::methodCount, methodIdentifiers); + } + + // fill in NPClass structure + structVersion = NP_CLASS_STRUCT_VERSION; + allocate = RuntimeNPClassAllocate<T>; + deallocate = RuntimeNPClassDeallocate<T>; + invalidate = RuntimeNPClassInvalidate<T>; + hasMethod = RuntimeNPClassHasMethod<T>; + invoke = RuntimeNPClassInvoke<T>; + invokeDefault = RuntimeNPClassInvokeDefault<T>; + hasProperty = RuntimeNPClassHasProperty<T>; + getProperty = RuntimeNPClassGetProperty<T>; + setProperty = RuntimeNPClassSetProperty<T>; + removeProperty = RuntimeNPClassRemoveProperty<T>; +} + +template<class T> +RuntimeNPClass<T>::~RuntimeNPClass() +{ + delete propertyIdentifiers; + delete methodIdentifiers; +} + +template<class T> +RuntimeNPObject *RuntimeNPClass<T>::create(NPP instance) const +{ + return new T(instance, this); +} + +template<class T> +int RuntimeNPClass<T>::indexOfMethod(NPIdentifier name) const +{ + if( methodIdentifiers ) + { + for(int c=0; c< T::methodCount; ++c ) + { + if( name == methodIdentifiers[c] ) + return c; + } + } + return -1; +} + +template<class T> +int RuntimeNPClass<T>::indexOfProperty(NPIdentifier name) const +{ + if( propertyIdentifiers ) + { + for(int c=0; c< T::propertyCount; ++c ) + { + if( name == propertyIdentifiers[c] ) + return c; + } + } + return -1; +} + +#endif diff --git a/mozilla/control/npovlc.cpp b/mozilla/control/npovlc.cpp new file mode 100755 index 000000000000..e48000742a9d --- /dev/null +++ b/mozilla/control/npovlc.cpp @@ -0,0 +1,704 @@ +/***************************************************************************** + * vlc.cpp: support for NPRuntime API for Netscape Script-able plugins + * FYI: http://www.mozilla.org/projects/plugins/npruntime.html + ***************************************************************************** + * 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 "config.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include <vlc/vlc.h> + +/* Mozilla stuff */ +#ifdef HAVE_MOZILLA_CONFIG_H +# include <mozilla-config.h> +#endif + +#include "npovlc.h" +#include "vlcplugin.h" + +/* +** implementation of vlc root object +*/ + +const NPUTF8 * const VlcNPObject::propertyNames[] = +{ + /* no properties */ +}; + +const int VlcNPObject::propertyCount = sizeof(VlcNPObject::propertyNames)/sizeof(NPUTF8 *); + +const NPUTF8 * const VlcNPObject::methodNames[] = +{ + "play", + "pause", + "stop", + "fullscreen", + "set_volume", + "get_volume", + "mute", + "get_int_variable", + "set_int_variable", + "get_bool_variable", + "set_bool_variable", + "get_str_variable", + "set_str_variable", + "clear_playlist", + "add_item", + "next", + "previous", + "isplaying", + "get_length", + "get_position", + "get_time", + "seek", +}; + +enum VlcNPObjectMethodIds +{ + ID_play = 0, + ID_pause, + ID_stop, + ID_fullscreen, + ID_set_volume, + ID_get_volume, + ID_mute, + ID_get_int_variable, + ID_set_int_variable, + ID_get_bool_variable, + ID_set_bool_variable, + ID_get_str_variable, + ID_set_str_variable, + ID_clear_playlist, + ID_add_item, + ID_next, + ID_previous, + ID_isplaying, + ID_get_length, + ID_get_position, + ID_get_time, + ID_seek, +}; + +const int VlcNPObject::methodCount = sizeof(VlcNPObject::methodNames)/sizeof(NPUTF8 *); + +RuntimeNPObject::InvokeResult VlcNPObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result) +{ + VlcPlugin *p_plugin = reinterpret_cast<VlcPlugin *>(_instance->pdata); + if( p_plugin ) + { + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + switch( index ) + { + case ID_play: + if( argCount == 0 ) + { + libvlc_playlist_play(p_plugin->getVLC(), -1, 0, NULL, &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_pause: + if( argCount == 0 ) + { + libvlc_playlist_pause(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_stop: + if( argCount == 0 ) + { + libvlc_playlist_stop(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_fullscreen: + if( argCount == 0 ) + { + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( p_input ) + { + libvlc_toggle_fullscreen(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + else + { + /* cannot get input, probably not playing */ + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + } + return INVOKERESULT_GENERIC_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_set_volume: + if( (argCount == 1) && isNumberValue(args[0]) ) + { + libvlc_audio_set_volume(p_plugin->getVLC(), numberValue(args[0]), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_get_volume: + if( argCount == 0 ) + { + int val = libvlc_audio_get_volume(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + INT32_TO_NPVARIANT(val, *result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_mute: + if( argCount == 0 ) + { + libvlc_audio_toggle_mute(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_get_int_variable: + if( (argCount == 1) && NPVARIANT_IS_STRING(args[0]) ) + { + const NPString &name = NPVARIANT_TO_STRING(args[0]); + NPUTF8 *s = new NPUTF8[name.utf8length+1]; + if( s ) + { + int vlc_id = libvlc_get_vlc_id(p_plugin->getVLC()); + vlc_value_t val; + strncpy(s, name.utf8characters, name.utf8length); + s[name.utf8length] = '\0'; + if( VLC_SUCCESS == VLC_VariableGet(vlc_id, s, &val) ) + { + delete s; + INT32_TO_NPVARIANT(val.i_int, *result); + return INVOKERESULT_NO_ERROR; + } + else + { + delete s; + return INVOKERESULT_INVALID_ARGS; + } + } + else + return INVOKERESULT_OUT_OF_MEMORY; + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_set_int_variable: + if( (argCount == 2) + && NPVARIANT_IS_STRING(args[0]) + && isNumberValue(args[1]) ) + { + const NPString &name = NPVARIANT_TO_STRING(args[0]); + NPUTF8 *s = new NPUTF8[name.utf8length+1]; + if( s ) + { + int vlc_id = libvlc_get_vlc_id(p_plugin->getVLC()); + vlc_value_t val; + strncpy(s, name.utf8characters, name.utf8length); + s[name.utf8length] = '\0'; + val.i_int = numberValue(args[1]); + if( VLC_SUCCESS == VLC_VariableSet(vlc_id, s, val) ) + { + delete s; + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + else + { + delete s; + return INVOKERESULT_INVALID_ARGS; + } + } + else + return INVOKERESULT_OUT_OF_MEMORY; + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_get_bool_variable: + if( (argCount == 1) && NPVARIANT_IS_STRING(args[0]) ) + { + const NPString &name = NPVARIANT_TO_STRING(args[0]); + NPUTF8 *s = new NPUTF8[name.utf8length+1]; + if( s ) + { + int vlc_id = libvlc_get_vlc_id(p_plugin->getVLC()); + vlc_value_t val; + strncpy(s, name.utf8characters, name.utf8length); + s[name.utf8length] = '\0'; + if( VLC_SUCCESS == VLC_VariableGet(vlc_id, s, &val) ) + { + delete s; + BOOLEAN_TO_NPVARIANT(val.b_bool, *result); + return INVOKERESULT_NO_ERROR; + } + else + { + delete s; + return INVOKERESULT_INVALID_ARGS; + } + } + else + return INVOKERESULT_OUT_OF_MEMORY; + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_set_bool_variable: + if( (argCount == 2) + && NPVARIANT_IS_STRING(args[0]) + && NPVARIANT_IS_BOOLEAN(args[1]) ) + { + const NPString &name = NPVARIANT_TO_STRING(args[0]); + NPUTF8 *s = new NPUTF8[name.utf8length+1]; + if( s ) + { + int vlc_id = libvlc_get_vlc_id(p_plugin->getVLC()); + vlc_value_t val; + strncpy(s, name.utf8characters, name.utf8length); + s[name.utf8length] = '\0'; + val.b_bool = NPVARIANT_TO_BOOLEAN(args[1]); + if( VLC_SUCCESS == VLC_VariableSet(vlc_id, s, val) ) + { + delete s; + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + else + { + delete s; + return INVOKERESULT_INVALID_ARGS; + } + } + else + return INVOKERESULT_OUT_OF_MEMORY; + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_get_str_variable: + if( (argCount == 1) && NPVARIANT_IS_STRING(args[0]) ) + { + const NPString &name = NPVARIANT_TO_STRING(args[0]); + NPUTF8 *s = new NPUTF8[name.utf8length+1]; + if( s ) + { + int vlc_id = libvlc_get_vlc_id(p_plugin->getVLC()); + vlc_value_t val; + strncpy(s, name.utf8characters, name.utf8length); + s[name.utf8length] = '\0'; + if( VLC_SUCCESS == VLC_VariableGet(vlc_id, s, &val) ) + { + delete s; + if( val.psz_string ) + { + int len = strlen(val.psz_string); + NPUTF8 *retval = (NPUTF8 *)NPN_MemAlloc(len); + if( retval ) + { + memcpy(retval, val.psz_string, len); + STRINGN_TO_NPVARIANT(retval, len, *result); + free(val.psz_string); + return INVOKERESULT_NO_ERROR; + } + else + { + return INVOKERESULT_OUT_OF_MEMORY; + } + } + else + { + /* null string */ + STRINGN_TO_NPVARIANT(NULL, 0, *result); + return INVOKERESULT_NO_ERROR; + } + } + else + { + delete s; + return INVOKERESULT_INVALID_ARGS; + } + } + else + return INVOKERESULT_OUT_OF_MEMORY; + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_set_str_variable: + if( (argCount == 2) + && NPVARIANT_IS_STRING(args[0]) + && NPVARIANT_IS_STRING(args[1]) ) + { + const NPString &name = NPVARIANT_TO_STRING(args[0]); + NPUTF8 *s = new NPUTF8[name.utf8length+1]; + if( s ) + { + int vlc_id = libvlc_get_vlc_id(p_plugin->getVLC()); + vlc_value_t val; + strncpy(s, name.utf8characters, name.utf8length); + s[name.utf8length] = '\0'; + const NPString &v = NPVARIANT_TO_STRING(args[1]); + val.psz_string = new NPUTF8[v.utf8length+1]; + if( val.psz_string ) + { + strncpy(val.psz_string, v.utf8characters, v.utf8length); + val.psz_string[v.utf8length] = '\0'; + if( VLC_SUCCESS == VLC_VariableSet(vlc_id, s, val) ) + { + delete s; + delete val.psz_string; + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + else + { + delete s; + delete val.psz_string; + return INVOKERESULT_INVALID_ARGS; + } + } + else + { + delete s; + return INVOKERESULT_OUT_OF_MEMORY; + } + } + else + return INVOKERESULT_OUT_OF_MEMORY; + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_clear_playlist: + if( argCount == 0 ) + { + libvlc_playlist_clear(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_add_item: + if( (argCount == 1) && NPVARIANT_IS_STRING(args[0]) ) + { + const NPString &name = NPVARIANT_TO_STRING(args[0]); + NPUTF8 *s = new NPUTF8[name.utf8length+1]; + if( s ) + { + strncpy(s, name.utf8characters, name.utf8length); + s[name.utf8length] = '\0'; + + char *url = p_plugin->getAbsoluteURL(s); + delete s; + if( ! url ) + // what happened ? + return INVOKERESULT_GENERIC_ERROR; + + int item = libvlc_playlist_add(p_plugin->getVLC(), url, NULL, &ex); + free(url); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + INT32_TO_NPVARIANT(item, *result); + return INVOKERESULT_NO_ERROR; + } + } + else + return INVOKERESULT_OUT_OF_MEMORY; + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_next: + if( argCount == 0 ) + { + libvlc_playlist_next(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_previous: + if( argCount == 0 ) + { + libvlc_playlist_prev(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_isplaying: + if( argCount == 0 ) + { + int isplaying = libvlc_playlist_isplaying(p_plugin->getVLC(), &ex); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + BOOLEAN_TO_NPVARIANT(isplaying, *result); + return INVOKERESULT_NO_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_get_length: + if( argCount == 0 ) + { + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( p_input ) + { + vlc_int64_t val = libvlc_input_get_length(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + INT32_TO_NPVARIANT((uint32_t)(val/1000LL), *result); + return INVOKERESULT_NO_ERROR; + } + } + else + { + /* cannot get input, probably not playing */ + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + } + return INVOKERESULT_GENERIC_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_get_position: + if( argCount == 0 ) + { + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( p_input ) + { + float val = libvlc_input_get_position(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + DOUBLE_TO_NPVARIANT((double)val, *result); + return INVOKERESULT_NO_ERROR; + } + } + else + { + /* cannot get input, probably not playing */ + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + } + return INVOKERESULT_GENERIC_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_get_time: + if( argCount == 0 ) + { + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( p_input ) + { + vlc_int64_t val = libvlc_input_get_time(p_input, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + else + { + DOUBLE_TO_NPVARIANT((uint32_t)(val/1000LL), *result); + return INVOKERESULT_NO_ERROR; + } + } + else + { + /* cannot get input, probably not playing */ + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + } + return INVOKERESULT_GENERIC_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + case ID_seek: + if( (argCount == 2) + && isNumberValue(args[0]) + && NPVARIANT_IS_BOOLEAN(args[1]) ) + { + libvlc_input_t *p_input = libvlc_playlist_get_input(p_plugin->getVLC(), &ex); + if( p_input ) + { + vlc_int64_t pos = numberValue(args[0])*1000LL; + if( NPVARIANT_TO_BOOLEAN(args[1]) ) + { + /* relative seek */ + vlc_int64_t from = libvlc_input_get_time(p_input, &ex); + if( libvlc_exception_raised(&ex) ) + { + libvlc_input_free(p_input); + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + pos += from; + } + /* jump to time */ + libvlc_input_set_time(p_input, pos, &ex); + libvlc_input_free(p_input); + if( libvlc_exception_raised(&ex) ) + { + libvlc_input_free(p_input); + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + return INVOKERESULT_GENERIC_ERROR; + } + VOID_TO_NPVARIANT(*result); + return INVOKERESULT_NO_ERROR; + } + else + { + /* cannot get input, probably not playing */ + if( libvlc_exception_raised(&ex) ) + { + NPN_SetException(this, libvlc_exception_get_message(&ex)); + libvlc_exception_clear(&ex); + } + return INVOKERESULT_GENERIC_ERROR; + } + } + return INVOKERESULT_NO_SUCH_METHOD; + default: + return INVOKERESULT_NO_SUCH_METHOD; + } + } + return INVOKERESULT_GENERIC_ERROR; +} + diff --git a/mozilla/vlcpeer.h b/mozilla/control/npovlc.h old mode 100644 new mode 100755 similarity index 52% rename from mozilla/vlcpeer.h rename to mozilla/control/npovlc.h index c5ee26a1a9f5..1fee65a3fd49 --- a/mozilla/vlcpeer.h +++ b/mozilla/control/npovlc.h @@ -1,61 +1,48 @@ -/***************************************************************************** - * vlcpeer.h: scriptable peer descriptor - ***************************************************************************** - * Copyright (C) 2002-2005 the VideoLAN team - * $Id$ - * - * Authors: Samuel Hocevar <sam@zoy.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 __VLCPEER_H__ -#define __VLCPEER_H__ - -#include "vlcintf.h" -#include "support/classinfo.h" - -class VlcPlugin; - -class VlcPeer : public VlcIntf, public ClassInfo -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_VLCINTF - - // These flags are used by the DOM and security systems to signal that - // JavaScript callers are allowed to call this object's scriptable methods. - NS_IMETHOD GetFlags(PRUint32 *aFlags) - { - *aFlags = nsIClassInfo::PLUGIN_OBJECT | nsIClassInfo::DOM_OBJECT; - return NS_OK; - } - - NS_IMETHOD GetImplementationLanguage(PRUint32 *aImplementationLanguage) - { - *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; - return NS_OK; - } - - VlcPeer(); - VlcPeer( VlcPlugin * ); - virtual ~VlcPeer(); - - void Disable(); - -private: - VlcPlugin * p_plugin; -}; - -#endif +/***************************************************************************** + * vlc.h: a VLC plugin for Mozilla + ***************************************************************************** + * Copyright (C) 2002-2005 the VideoLAN team + * $Id: vlcruntime.h 14466 2006-02-22 23:34:54Z dionoea $ + * + * 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. + *****************************************************************************/ + +/* +** defined runtime script objects +*/ + +#include "nporuntime.h" + +class VlcNPObject: public RuntimeNPObject +{ +public: + VlcNPObject(NPP instance, const NPClass *aClass) : + RuntimeNPObject(instance, aClass) {}; + virtual ~VlcNPObject() {}; + +protected: + friend class RuntimeNPClass<VlcNPObject>; + + static const int propertyCount; + static const NPUTF8 * const propertyNames[]; + + static const int methodCount; + static const NPUTF8 * const methodNames[]; + + virtual InvokeResult invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result); +}; + diff --git a/mozilla/vlcintf.idl b/mozilla/vlcintf.idl deleted file mode 100644 index 08515f203025..000000000000 --- a/mozilla/vlcintf.idl +++ /dev/null @@ -1,42 +0,0 @@ - -#include "nsISupports.idl" - -[scriptable, uuid(ea92ef52-afe4-4212-bacb-dfe9fca94cd6)] - -interface VlcIntf : nsISupports -{ - /* Basic playback control */ - void play(); - void pause(); - void stop(); - - /* Audio/Video control */ - void fullscreen(); - void set_volume( in PRInt64 i_volume ); - PRInt64 get_volume(); - void mute(); - - /* Get/Set variable */ - void set_int_variable( in string psz_var, in PRInt64 i_value ); - void set_bool_variable( in string psz_var, in PRBool b_value ); - void set_str_variable( in string psz_var, in string psz_value ); - - PRInt64 get_int_variable( in string psz_var ); - PRBool get_bool_variable( in string psz_var ); - string get_str_variable( in string psz_var ); - - /* Playlist management */ - void clear_playlist(); - void add_item( in string psz_name); - void next(); - void previous(); - - /* Status accessors */ - PRBool isplaying(); - PRInt64 get_length(); - PRInt64 get_position(); - PRInt64 get_time(); - - void seek( in PRInt64 i_secs, in PRInt64 b_relative); -}; - diff --git a/mozilla/vlcpeer.cpp b/mozilla/vlcpeer.cpp deleted file mode 100644 index 699f626608d0..000000000000 --- a/mozilla/vlcpeer.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/***************************************************************************** - * vlcpeer.cpp: scriptable peer descriptor - ***************************************************************************** - * Copyright (C) 2002-2005 the VideoLAN team - * $Id$ - * - * Authors: Samuel Hocevar <sam@zoy.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. - *****************************************************************************/ - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include "config.h" - -#include <vlc/vlc.h> - -#ifdef DEBUG -/* We do not want to use nsDebug.h */ -# undef DEBUG -#endif - -#ifdef HAVE_MOZILLA_CONFIG_H -# include <mozilla-config.h> -#endif -#include <nsISupports.h> -#include <nsMemory.h> -#include <npapi.h> - -#if !defined(XP_MACOSX) && !defined(XP_UNIX) && !defined(XP_WIN) -#define XP_UNIX 1 -#elif defined(XP_MACOSX) -#undef XP_UNIX -#endif - -#include "vlcpeer.h" -#include "vlcplugin.h" - -NS_IMPL_ISUPPORTS2( VlcPeer, VlcIntf, nsIClassInfo ) - -/***************************************************************************** - * Scriptable peer constructor and destructor - *****************************************************************************/ -VlcPeer::VlcPeer() -{ - NS_INIT_ISUPPORTS(); -} - -VlcPeer::VlcPeer( VlcPlugin * plugin ) -{ - NS_INIT_ISUPPORTS(); - p_plugin = plugin; -} - -VlcPeer::~VlcPeer() -{ - ; -} - -/***************************************************************************** - * Scriptable peer methods - *****************************************************************************/ -void VlcPeer::Disable() -{ - p_plugin = NULL; -} - -/***************************************************************************** - * Scriptable peer plugin methods - *****************************************************************************/ -NS_IMETHODIMP VlcPeer::Play() -{ - if( p_plugin ) - { - if( !p_plugin->b_stream && p_plugin->psz_target ) - { - VLC_AddTarget( p_plugin->i_vlc, p_plugin->psz_target, 0, 0, - PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END ); - p_plugin->b_stream = 1; - } - - VLC_Play( p_plugin->i_vlc ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Pause() -{ - if( p_plugin ) - { - VLC_Pause( p_plugin->i_vlc ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Stop() -{ - if( p_plugin ) - { - VLC_Stop( p_plugin->i_vlc ); - p_plugin->b_stream = 0; - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Fullscreen() -{ - if( p_plugin ) - { -#ifdef XP_MACOSX -#else - VLC_FullScreen( p_plugin->i_vlc ); -#endif - } - return NS_OK; -} - -/* Set/Get vlc variables */ -NS_IMETHODIMP VlcPeer::Set_int_variable(const char *psz_var, PRInt64 value ) -{ - vlc_value_t val; - val.i_int = value; - if( p_plugin ) - { - VLC_VariableSet( p_plugin->i_vlc, psz_var, val ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Set_str_variable(const char *psz_var, const char *value ) -{ - vlc_value_t val; - val.psz_string = strdup( value ); - if( p_plugin ) - { - VLC_VariableSet( p_plugin->i_vlc, psz_var, val ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Set_bool_variable(const char *psz_var, PRBool value ) -{ - vlc_value_t val; - val.b_bool = value >= 1 ? VLC_TRUE : VLC_FALSE; - if( p_plugin ) - { - VLC_VariableSet( p_plugin->i_vlc, psz_var, val ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Get_int_variable( const char *psz_var, PRInt64 *result ) -{ - vlc_value_t val; - if( p_plugin ) - { - VLC_VariableGet( p_plugin->i_vlc, psz_var, &val ); - *result = (PRInt64)val.i_int; - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Get_bool_variable( const char *psz_var,PRBool *result ) -{ - vlc_value_t val; - if( p_plugin ) - { - VLC_VariableGet( p_plugin->i_vlc, psz_var, &val ); - *result = (PRBool)val.b_bool; - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Get_str_variable( const char *psz_var, char **result ) -{ - vlc_value_t val; - if( p_plugin ) - { - VLC_VariableGet( p_plugin->i_vlc, psz_var, &val ); - if( val.psz_string ) - { - *result = strdup( val.psz_string ); - } - else - { - *result = strdup( "" ); - } - } - return NS_OK; -} - -/* Playlist control */ -NS_IMETHODIMP VlcPeer::Clear_playlist() -{ - if( p_plugin ) - { - VLC_PlaylistClear( p_plugin->i_vlc ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Add_item( const char *psz_item ) -{ - if( p_plugin ) - { - VLC_AddTarget( p_plugin->i_vlc, psz_item, NULL, 0, - PLAYLIST_APPEND, PLAYLIST_END); - } - return NS_OK; -} - - -NS_IMETHODIMP VlcPeer::Isplaying( PRBool *b_playing ) -{ - if( p_plugin->i_vlc ) - { - *b_playing = VLC_IsPlaying( p_plugin->i_vlc ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Get_position( PRInt64 *i_position ) -{ - if( p_plugin->i_vlc ) - { - *i_position = (PRInt64)VLC_PositionGet( p_plugin->i_vlc ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Get_time( PRInt64 *i_time ) -{ - if( p_plugin->i_vlc ) - { - *i_time = VLC_TimeGet( p_plugin->i_vlc ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Get_length( PRInt64 *i_length ) -{ - if( p_plugin->i_vlc ) - { - *i_length = VLC_LengthGet( p_plugin->i_vlc ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Seek( PRInt64 i_secs, PRInt64 b_relative ) -{ - if( p_plugin->i_vlc ) - { - VLC_TimeSet( p_plugin->i_vlc, i_secs, b_relative ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Next() -{ - if( p_plugin->i_vlc ) - { - VLC_PlaylistNext( p_plugin->i_vlc); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Previous() -{ - if( p_plugin->i_vlc ) - { - VLC_PlaylistPrev( p_plugin->i_vlc ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Set_volume( PRInt64 i_volume ) -{ - if( p_plugin->i_vlc ) - { - VLC_VolumeSet( p_plugin->i_vlc, i_volume ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Get_volume( PRInt64 *i_volume ) -{ - if( p_plugin->i_vlc ) - { - *i_volume = VLC_VolumeGet( p_plugin->i_vlc ); - } - return NS_OK; -} - -NS_IMETHODIMP VlcPeer::Mute() -{ - if( p_plugin->i_vlc ) - { - VLC_VolumeMute( p_plugin->i_vlc ); - } - return NS_OK; -} diff --git a/mozilla/vlcplugin.cpp b/mozilla/vlcplugin.cpp index 1c9d2fe305a6..b86828448872 100644 --- a/mozilla/vlcplugin.cpp +++ b/mozilla/vlcplugin.cpp @@ -26,72 +26,360 @@ *****************************************************************************/ #include "config.h" -#include <vlc/vlc.h> - #ifdef HAVE_MOZILLA_CONFIG_H # include <mozilla-config.h> #endif -#include <nsISupports.h> -#include <nsMemory.h> -#include <npapi.h> - -#if !defined(XP_MACOSX) && !defined(XP_UNIX) && !defined(XP_WIN) -#define XP_UNIX 1 -#elif defined(XP_MACOSX) -#undef XP_UNIX -#endif #include "vlcplugin.h" +#include "control/npovlc.h" +#include "control/npolibvlc.h" /***************************************************************************** * VlcPlugin constructor and destructor *****************************************************************************/ -VlcPlugin::VlcPlugin( NPP instance ) +VlcPlugin::VlcPlugin( NPP instance, uint16 mode ) : + i_npmode(mode), + b_stream(0), + b_autoplay(0), + psz_target(NULL), + libvlc_instance(NULL), + scriptClass(NULL), + p_browser(instance), + psz_baseURL(NULL) +#if XP_WIN + ,pf_wndproc(NULL) +#endif +#if XP_UNIX + ,i_width((unsigned)-1) + ,i_height((unsigned)-1) +#endif { - p_instance = instance; - p_peer = NULL; + memset(&npwindow, 0, sizeof(NPWindow)); } +static int boolValue(const char *value) { + return ( !strcmp(value, "1") || + !strcasecmp(value, "true") || + !strcasecmp(value, "yes") ); +} -VlcPlugin::~VlcPlugin() +NPError VlcPlugin::init(int argc, char* const argn[], char* const argv[]) { - if( p_peer ) + /* prepare VLC command line */ + char *ppsz_argv[32] = + { + "vlc", + "-vv", + "--no-stats", + "--intf", "dummy", + }; + int ppsz_argc = 5; + + /* locate VLC module path */ +#ifdef XP_MACOSX + ppsz_argv[ppsz_argc++] = "--plugin-path"; + ppsz_argv[ppsz_argc++] = "/Library/Internet Plug-Ins/VLC Plugin.plugin/" + "Contents/MacOS/modules"; +#elif defined(XP_WIN) + HKEY h_key; + DWORD i_type, i_data = MAX_PATH + 1; + char p_data[MAX_PATH + 1]; + if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\VideoLAN\\VLC", + 0, KEY_READ, &h_key ) == ERROR_SUCCESS ) { - p_peer->Disable(); - p_peer->Release(); + if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type, + (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS ) + { + if( i_type == REG_SZ ) + { + strcat( p_data, "\\vlc" ); + ppsz_argv[0] = p_data; + } + } + RegCloseKey( h_key ); } -} + ppsz_argv[ppsz_argc++] = "--no-one-instance"; +#if 1 + ppsz_argv[0] = "F:\\Cygwin\\home\\Damien\\dev\\videolan\\vlc-trunk\\vlc"; +#endif +#endif /* XP_MACOSX */ -/***************************************************************************** - * VlcPlugin methods - *****************************************************************************/ -void VlcPlugin::SetInstance( NPP instance ) -{ - p_instance = instance; + const char *version = NULL; + + /* parse plugin arguments */ + for( int i = 0; i < argc ; i++ ) + { + fprintf(stderr, "argn=%s, argv=%s\n", argn[i], argv[i]); + + if( !strcmp( argn[i], "target" ) + || !strcmp( argn[i], "mrl") + || !strcmp( argn[i], "filename") + || !strcmp( argn[i], "src") ) + { + psz_target = argv[i]; + } + else if( !strcmp( argn[i], "autoplay") + || !strcmp( argn[i], "autostart") ) + { + b_autoplay = boolValue(argv[i]); + } + else if( !strcmp( argn[i], "fullscreen" ) ) + { + if( boolValue(argv[i]) ) + { + ppsz_argv[ppsz_argc++] = "--fullscreen"; + } + else + { + ppsz_argv[ppsz_argc++] = "--no-fullscreen"; + } + } + else if( !strcmp( argn[i], "mute" ) ) + { + if( boolValue(argv[i]) ) + { + ppsz_argv[ppsz_argc++] = "--volume"; + ppsz_argv[ppsz_argc++] = "0"; + } + } + else if( !strcmp( argn[i], "loop") + || !strcmp( argn[i], "autoloop") ) + { + if( boolValue(argv[i]) ) + { + ppsz_argv[ppsz_argc++] = "--loop"; + } + else { + ppsz_argv[ppsz_argc++] = "--no-loop"; + } + } + else if( !strcmp( argn[i], "version") ) + { + version = argv[i]; + } + } + + libvlc_instance = libvlc_new(ppsz_argc, ppsz_argv, NULL); + if( ! libvlc_instance ) + { + return NPERR_GENERIC_ERROR; + } + + /* + ** fetch plugin base URL, which is the URL of the page containing the plugin + ** this URL is used for making absolute URL from relative URL that may be + ** passed as an MRL argument + */ + NPObject *plugin; + + if( NPERR_NO_ERROR == NPN_GetValue(p_browser, NPNVWindowNPObject, &plugin) ) + { + /* + ** is there a better way to get that info ? + */ + static const char docLocHref[] = "document.location.href"; + NPString script; + NPVariant result; + + script.utf8characters = docLocHref; + script.utf8length = sizeof(docLocHref)-1; + + if( NPN_Evaluate(p_browser, plugin, &script, &result) ) + { + if( NPVARIANT_IS_STRING(result) ) + { + NPString &location = NPVARIANT_TO_STRING(result); + + psz_baseURL = new char[location.utf8length+1]; + if( psz_baseURL ) + { + strncpy(psz_baseURL, location.utf8characters, location.utf8length); + psz_baseURL[location.utf8length] = '\0'; + } + } + NPN_ReleaseVariantValue(&result); + } + NPN_ReleaseObject(plugin); + } + + if( psz_target ) + { + // get absolute URL from src + psz_target = getAbsoluteURL(psz_target); + } + + /* assign plugin script root class */ + if( (NULL != version) && (!strcmp(version, "VideoLAN.VLCPlugin.2")) ) + { + /* new APIs */ + scriptClass = new RuntimeNPClass<LibvlcRootNPObject>(); + } + else + { + /* legacy APIs */ + scriptClass = new RuntimeNPClass<VlcNPObject>(); + } + + return NPERR_NO_ERROR; } +#if 0 +#ifdef XP_WIN +/* This is really ugly but there is a deadlock when stopping a stream + * (in VLC_CleanUp()) because the video output is a child of the drawable but + * is in a different thread. */ +static void HackStopVout( VlcPlugin* p_plugin ) +{ + MSG msg; + HWND hwnd; + vlc_value_t value; + + int i_vlc = libvlc_get_vlc_id(p_plugin->libvlc_instance); + VLC_VariableGet( i_vlc, "drawable", &value ); + + hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 ); + if( !hwnd ) return; + + PostMessage( hwnd, WM_CLOSE, 0, 0 ); + + do + { + while( PeekMessage( &msg, (HWND)value.i_int, 0, 0, PM_REMOVE ) ) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if( FindWindowEx( (HWND)value.i_int, 0, 0, 0 ) ) Sleep( 10 ); + } + while( (hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 )) ); +} +#endif /* XP_WIN */ +#endif -NPP VlcPlugin::GetInstance() +VlcPlugin::~VlcPlugin() { - return p_instance; + delete psz_baseURL; + delete psz_target; + if( libvlc_instance ) + libvlc_destroy(libvlc_instance); } +/***************************************************************************** + * VlcPlugin methods + *****************************************************************************/ -VlcIntf* VlcPlugin::GetPeer() +char *VlcPlugin::getAbsoluteURL(const char *url) { - if( !p_peer ) + if( NULL != url ) { - p_peer = new VlcPeer( this ); - if( p_peer == NULL ) + // check whether URL is already absolute + const char *end=strchr(url, ':'); + if( (NULL != end) && (end != url) ) { - return NULL; + // validate protocol header + const char *start = url; + while( start != end ) { + char c = *start | 0x20; + if( (c < 'a') || (c > 'z') ) + // not valid protocol header, assume relative URL + break; + ++start; + } + /* we have a protocol header, therefore URL is absolute */ + return strdup(url); } - NS_ADDREF( p_peer ); + if( psz_baseURL ) + { + size_t baseLen = strlen(psz_baseURL); + char *href = new char[baseLen+strlen(url)]; + if( href ) + { + /* prepend base URL */ + strcpy(href, psz_baseURL); + + /* + ** relative url could be empty, + ** in which case return base URL + */ + if( '\0' == *url ) + return href; + + /* + ** locate pathname part of base URL + */ + + /* skip over protocol part */ + char *pathstart = strchr(href, ':'); + char *pathend; + if( '/' == *(++pathstart) ) + { + if( '/' == *(++pathstart) ) + { + ++pathstart; + } + } + /* skip over host part */ + pathstart = strchr(pathstart, '/'); + pathend = href+baseLen; + if( ! pathstart ) + { + // no path, add a / past end of url (over '\0') + pathstart = pathend; + *pathstart = '/'; + } + + /* relative URL made of an absolute path ? */ + if( '/' == *url ) + { + /* replace path completely */ + strcpy(pathstart, url); + return href; + } + + /* find last path component and replace it */ + while( '/' != *pathend) --pathend; + + /* + ** if relative url path starts with one or more '../', + ** factor them out of href so that we return a + ** normalized URL + */ + while( pathend != pathstart ) + { + const char *p = url; + if( '.' != *p ) + break; + ++p; + if( '.' != *p ) + break; + ++p; + if( '/' != *p ) + break; + ++p; + url = p; + while( '/' != *pathend ) --pathend; + } + /* concatenate remaining base URL and relative URL */ + strcpy(pathend+1, url); + } + return href; + } } + return NULL; +} - NS_ADDREF( p_peer ); - return p_peer; +#if XP_UNIX +int VlcPlugin::setSize(unsigned width, unsigned height) +{ + int diff = (width != i_width) || (height != i_height); + + i_width = width; + i_height = height; + + /* return size */ + return diff; } +#endif diff --git a/mozilla/vlcplugin.h b/mozilla/vlcplugin.h index 4ff52ef95807..4e8416da9f5e 100644 --- a/mozilla/vlcplugin.h +++ b/mozilla/vlcplugin.h @@ -1,10 +1,11 @@ /***************************************************************************** * vlcplugin.h: a VLC plugin for Mozilla ***************************************************************************** - * Copyright (C) 2002-2005 the VideoLAN team + * Copyright (C) 2002-2006 the VideoLAN team * $Id$ * * Authors: Samuel Hocevar <sam@zoy.org> + Damien Fouilleul <damienf@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 @@ -27,7 +28,9 @@ #ifndef __VLCPLUGIN_H__ #define __VLCPLUGIN_H__ -#include "vlcpeer.h" +#include <vlc/libvlc.h> +#include <npapi.h> +#include "control/nporuntime.h" #if !defined(XP_MACOSX) && !defined(XP_UNIX) && !defined(XP_WIN) #define XP_UNIX 1 @@ -35,6 +38,7 @@ #undef XP_UNIX #endif +#if 0 #ifdef XP_WIN /* Windows stuff */ #endif @@ -50,49 +54,63 @@ # include <X11/Intrinsic.h> # include <X11/StringDefs.h> #endif +#endif class VlcPlugin { public: - VlcPlugin( NPP ); + VlcPlugin( NPP, uint16 ); virtual ~VlcPlugin(); - void SetInstance( NPP ); - NPP GetInstance(); - VlcIntf* GetPeer(); - - /* Window settings */ - NPWindow* p_npwin; - uint16 i_npmode; - uint32 i_width, i_height; - -#ifdef XP_WIN - /* Windows data members */ - HWND p_hwnd; - WNDPROC pf_wndproc; -#endif - -#ifdef XP_UNIX - /* UNIX data members */ - Window window; - Display *p_display; + NPError init(int argc, char* const argn[], char* const argv[]); + libvlc_instance_t* getVLC() + { return libvlc_instance; }; + NPP getBrowser() + { return p_browser; }; + char* getAbsoluteURL(const char *url); + const NPWindow* getWindow() + { return &npwindow; }; + void setWindow(const NPWindow *window) + { npwindow = *window; }; + + NPClass* getScriptClass() + { return scriptClass; }; + +#if XP_WIN + WNDPROC getWindowProc() + { return pf_wndproc; }; + void setWindowProc(WNDPROC wndproc) + { pf_wndproc = wndproc; }; #endif -#ifdef XP_MACOSX - /* MACOS data members */ - NPWindow *window; +#if XP_UNIX + int setSize(unsigned width, unsigned height); #endif + uint16 i_npmode; /* either NP_EMBED or NP_FULL */ - /* vlc data members */ - int i_vlc; + /* plugin properties */ int b_stream; int b_autoplay; char * psz_target; private: - NPP p_instance; - VlcPeer* p_peer; + /* VLC reference */ + libvlc_instance_t *libvlc_instance; + NPClass *scriptClass; + + /* browser reference */ + NPP p_browser; + char* psz_baseURL; + + /* display settings */ + NPWindow npwindow; +#if XP_WIN + WNDPROC pf_wndproc; +#endif +#if XP_UNIX + unsigned int i_width, i_height; +#endif }; /******************************************************************************* diff --git a/mozilla/vlcruntime.cpp b/mozilla/vlcruntime.cpp deleted file mode 100755 index 269d778cd025..000000000000 --- a/mozilla/vlcruntime.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/***************************************************************************** - * vlcruntime.cpp: support for NPRuntime API for Netscape Script-able plugins - * FYI: http://www.mozilla.org/projects/plugins/npruntime.html - ***************************************************************************** - * 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 "config.h" - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -/* vlc stuff */ -#ifdef USE_LIBVLC -# include <vlc/vlc.h> -#endif - -/* Mozilla stuff */ -#ifdef HAVE_MOZILLA_CONFIG_H -# include <mozilla-config.h> -#endif -#include <nsISupports.h> -#include <nsMemory.h> -#include <npapi.h> -#include <npruntime.h> - -#include "vlcplugin.h" -#include "vlcruntime.h" - -/* -** utility functions -*/ - -static PRInt64 NPVariantToPRInt64(const NPVariant &v) -{ - switch( v.type ) { - case NPVariantType_Bool: - return static_cast<PRInt64>(NPVARIANT_TO_BOOLEAN(v)); - case NPVariantType_Int32: - return static_cast<PRInt64>(NPVARIANT_TO_INT32(v)); - case NPVariantType_Double: - return static_cast<PRInt64>(NPVARIANT_TO_DOUBLE(v)); - default: - return 0; - } -} - -/* -** implementation root object -*/ - -const NPUTF8 * const VlcRuntimeRootObject::propertyNames[] = { }; -const NPUTF8 * const VlcRuntimeRootObject::methodNames[] = -{ - "play", - "pause", - "stop", - "fullscreen", - "set_volume", - "get_volume", - "mute", - "get_int_variable", - "set_int_variable", - "get_bool_variable", - "set_bool_variable", - "get_str_variable", - "set_str_variable", - "clear_playlist", - "add_item", - "next", - "previous", - "isplaying", - "get_length", - "get_position", - "get_time", - "seek", -}; - -enum VlcRuntimeRootObjectMethodIds -{ - ID_play = 0, - ID_pause, - ID_stop, - ID_fullscreen, - ID_set_volume, - ID_get_volume, - ID_mute, - ID_get_int_variable, - ID_set_int_variable, - ID_get_bool_variable, - ID_set_bool_variable, - ID_get_str_variable, - ID_set_str_variable, - ID_clear_playlist, - ID_add_item, - ID_next, - ID_previous, - ID_isplaying, - ID_get_length, - ID_get_position, - ID_get_time, - ID_seek, -}; - -const int VlcRuntimeRootObject::propertyCount = sizeof(VlcRuntimeRootObject::propertyNames)/sizeof(NPUTF8 *); -const int VlcRuntimeRootObject::methodCount = sizeof(VlcRuntimeRootObject::methodNames)/sizeof(NPUTF8 *); - -bool VlcRuntimeRootObject::getProperty(int index, NPVariant *result) -{ - return false; -} - -bool VlcRuntimeRootObject::setProperty(int index, const NPVariant *value) -{ - return false; -} - -bool VlcRuntimeRootObject::removeProperty(int index) -{ - return false; -} - -bool VlcRuntimeRootObject::invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result) -{ - VlcPlugin *plugin = (VlcPlugin *)(_instance->pdata); - if( plugin ) - { - VlcIntf *peer = plugin->GetPeer(); - switch( index ) - { - case ID_play: - peer->Play(); - VOID_TO_NPVARIANT(*result); - return true; - case ID_pause: - peer->Pause(); - VOID_TO_NPVARIANT(*result); - return true; - case ID_stop: - peer->Stop(); - VOID_TO_NPVARIANT(*result); - return true; - case ID_fullscreen: - peer->Fullscreen(); - VOID_TO_NPVARIANT(*result); - return true; - case ID_set_volume: - if( argCount == 1 ) - { - peer->Set_volume(NPVariantToPRInt64(args[0])); - VOID_TO_NPVARIANT(*result); - return true; - } - return false; - case ID_get_volume: - { - PRInt64 val; - peer->Get_volume(&val); - INT32_TO_NPVARIANT(val, *result); - return true; - } - case ID_mute: - peer->Mute(); - VOID_TO_NPVARIANT(*result); - return true; - case ID_get_int_variable: - if( (argCount == 1) - && NPVARIANT_IS_STRING(args[0]) ) - { - const NPString &name = NPVARIANT_TO_STRING(args[0]); - NPUTF8 *s = new NPUTF8[name.utf8length+1]; - if( s ) - { - PRInt64 val; - strncpy(s, name.utf8characters, name.utf8length); - s[name.utf8length] = '\0'; - peer->Get_int_variable(s, &val); - INT32_TO_NPVARIANT(val, *result); - delete s; - return true; - } - } - return false; - case ID_set_int_variable: - if( (argCount == 2) - && NPVARIANT_IS_STRING(args[0]) ) - { - const NPString &name = NPVARIANT_TO_STRING(args[0]); - NPUTF8 *s = new NPUTF8[name.utf8length+1]; - if( s ) - { - strncpy(s, name.utf8characters, name.utf8length); - s[name.utf8length] = '\0'; - peer->Set_int_variable(s, NPVariantToPRInt64(args[1])); - delete s; - VOID_TO_NPVARIANT(*result); - return true; - } - } - return false; - case ID_get_bool_variable: - if( (argCount == 1) - && NPVARIANT_IS_STRING(args[0]) ) - { - const NPString &name = NPVARIANT_TO_STRING(args[0]); - NPUTF8 *s = new NPUTF8[name.utf8length+1]; - if( s ) - { - PRBool val; - strncpy(s, name.utf8characters, name.utf8length); - s[name.utf8length] = '\0'; - peer->Get_bool_variable(s, &val); - BOOLEAN_TO_NPVARIANT(val, *result); - delete s; - return true; - } - } - return false; - case ID_set_bool_variable: - if( (argCount == 2) - && NPVARIANT_IS_STRING(args[0]) - && NPVARIANT_IS_BOOLEAN(args[1]) ) - { - const NPString &name = NPVARIANT_TO_STRING(args[0]); - NPUTF8 *s = new NPUTF8[name.utf8length+1]; - if( s ) - { - strncpy(s, name.utf8characters, name.utf8length); - s[name.utf8length] = '\0'; - peer->Set_bool_variable(s, NPVARIANT_TO_BOOLEAN(args[1])); - delete s; - VOID_TO_NPVARIANT(*result); - return true; - } - } - return false; - case ID_get_str_variable: - if( (argCount == 1) - && NPVARIANT_IS_STRING(args[0]) ) - { - const NPString &name = NPVARIANT_TO_STRING(args[0]); - NPUTF8 *s = new NPUTF8[name.utf8length+1]; - if( s ) - { - char *val; - strncpy(s, name.utf8characters, name.utf8length); - s[name.utf8length] = '\0'; - peer->Get_str_variable(s, &val); - delete s; - int len = strlen(val); - NPUTF8 *retval = (NPUTF8 *)NPN_MemAlloc(len); - if( retval ) - { - memcpy(retval, val, len); - STRINGN_TO_NPVARIANT(retval, len, *result); - free(val); - return true; - } - free(val); - } - } - return false; - case ID_set_str_variable: - if( (argCount == 2) - && NPVARIANT_IS_STRING(args[0]) - && NPVARIANT_IS_STRING(args[1]) ) - { - const NPString &name = NPVARIANT_TO_STRING(args[0]); - NPUTF8 *s = new NPUTF8[name.utf8length+1]; - if( s ) - { - strncpy(s, name.utf8characters, name.utf8length); - s[name.utf8length] = '\0'; - const NPString &val = NPVARIANT_TO_STRING(args[1]); - NPUTF8 *v = new NPUTF8[val.utf8length+1]; - if( v ) - { - strncpy(v, val.utf8characters, val.utf8length); - v[val.utf8length] = '\0'; - peer->Set_str_variable(s, v); - delete s; - delete v; - VOID_TO_NPVARIANT(*result); - return true; - } - delete s; - } - } - return false; - case ID_clear_playlist: - peer->Clear_playlist(); - VOID_TO_NPVARIANT(*result); - return true; - case ID_add_item: - if( (argCount == 1) - && NPVARIANT_IS_STRING(args[0]) ) - { - const NPString &name = NPVARIANT_TO_STRING(args[0]); - NPUTF8 *s = new NPUTF8[name.utf8length+1]; - if( s ) - { - strncpy(s, name.utf8characters, name.utf8length); - s[name.utf8length] = '\0'; - peer->Add_item(s); - delete s; - return true; - } - } - return false; - case ID_next: - peer->Next(); - VOID_TO_NPVARIANT(*result); - return true; - case ID_previous: - peer->Previous(); - VOID_TO_NPVARIANT(*result); - return true; - case ID_isplaying: - { - PRBool val; - peer->Isplaying(&val); - BOOLEAN_TO_NPVARIANT(val, *result); - return true; - } - case ID_get_length: - { - PRInt64 val; - peer->Get_length(&val); - DOUBLE_TO_NPVARIANT(val, *result); - return true; - } - case ID_get_position: - { - PRInt64 val; - peer->Get_position(&val); - INT32_TO_NPVARIANT(val, *result); - return true; - } - case ID_get_time: - { - PRInt64 val; - peer->Get_time(&val); - INT32_TO_NPVARIANT(val, *result); - return true; - } - case ID_seek: - if( argCount == 2 ) - { - peer->Seek(NPVariantToPRInt64(args[0]), NPVariantToPRInt64(args[1])); - VOID_TO_NPVARIANT(*result); - return true; - } - return false; - } - NS_RELEASE(peer); - } - return false; -} - -bool VlcRuntimeRootObject::invokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result) -{ - return false; -} - diff --git a/mozilla/vlcruntime.h b/mozilla/vlcruntime.h deleted file mode 100755 index 654d8a950a22..000000000000 --- a/mozilla/vlcruntime.h +++ /dev/null @@ -1,261 +0,0 @@ -/***************************************************************************** - * vlcruntime.h: a VLC plugin for Mozilla - ***************************************************************************** - * Copyright (C) 2002-2005 the VideoLAN team - * $Id: vlcruntime.h 14466 2006-02-22 23:34:54Z dionoea $ - * - * 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. - *****************************************************************************/ - -/* -** support framework for runtime script objects -*/ - -class VlcRuntimeObject : public NPObject -{ -public: - VlcRuntimeObject(NPP instance, const NPClass *aClass) : - _instance(instance) - { - _class = const_cast<NPClass *>(aClass); - referenceCount = 1; - }; - virtual ~VlcRuntimeObject() {}; - - virtual bool getProperty(int index, NPVariant *result) = 0; - virtual bool setProperty(int index, const NPVariant *value) = 0; - virtual bool removeProperty(int index) = 0; - virtual bool invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result) = 0; - virtual bool invokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result) = 0; - NPP _instance; -}; - -template<class T> class VlcRuntimeClass : public NPClass -{ -public: - VlcRuntimeClass(); - virtual ~VlcRuntimeClass(); - - VlcRuntimeObject *create(NPP instance) const; - - int indexOfMethod(NPIdentifier name) const; - int indexOfProperty(NPIdentifier name) const; - -private: - NPIdentifier *propertyIdentifiers; - NPIdentifier *methodIdentifiers; -}; - -template<class T> -static NPObject *vlcRuntimeClassAllocate(NPP instance, NPClass *aClass) -{ - const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(aClass); - return (NPObject *)vClass->create(instance); -} - -template<class T> -static void vlcRuntimeClassDeallocate(NPObject *npobj) -{ - VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj); - delete vObj; -} - -template<class T> -static void vlcRuntimeClassInvalidate(NPObject *npobj) -{ - VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj); - vObj->_instance = NULL; -} - -template<class T> -bool vlcRuntimeClassHasMethod(NPObject *npobj, NPIdentifier name) -{ - const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class); - return vClass->indexOfMethod(name) != -1; -} - -template<class T> -bool vlcRuntimeClassHasProperty(NPObject *npobj, NPIdentifier name) -{ - const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class); - return vClass->indexOfProperty(name) != -1; -} - -template<class T> -bool vlcRuntimeClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) -{ - const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class); - int index = vClass->indexOfProperty(name); - if( index != -1 ) - { - VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj); - return vObj->getProperty(index, result); - } - return false; -} - -template<class T> -bool vlcRuntimeClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) -{ - const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class); - int index = vClass->indexOfProperty(name); - if( index != -1 ) - { - VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj); - return vObj->setProperty(index, value); - } - return false; -} - -template<class T> -bool vlcRuntimeClassRemoveProperty(NPObject *npobj, NPIdentifier name) -{ - const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class); - int index = vClass->indexOfProperty(name); - if( index != -1 ) - { - VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj); - return vObj->removeProperty(index); - } - return false; -} - -template<class T> -static bool vlcRuntimeClassInvoke(NPObject *npobj, NPIdentifier name, - const NPVariant *args, uint32_t argCount, - NPVariant *result) -{ - const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class); - int index = vClass->indexOfMethod(name); - if( index != -1 ) - { - VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj); - return vObj->invoke(index, args, argCount, result); - } - return false; -} - -template<class T> -static bool vlcRuntimeClassInvokeDefault(NPObject *npobj, - const NPVariant *args, - uint32_t argCount, - NPVariant *result) -{ - VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj); - return vObj->invokeDefault(args, argCount, result); -} - -template<class T> -VlcRuntimeClass<T>::VlcRuntimeClass() -{ - // retreive property identifiers from names - if( T::propertyCount > 0 ) - { - propertyIdentifiers = new NPIdentifier[T::propertyCount]; - if( propertyIdentifiers ) - NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::propertyNames), - T::propertyCount, propertyIdentifiers); - } - - // retreive method identifiers from names - if( T::methodCount > 0 ) - { - methodIdentifiers = new NPIdentifier[T::methodCount]; - if( methodIdentifiers ) - NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::methodNames), - T::methodCount, methodIdentifiers); - } - - // fill in NPClass structure - structVersion = NP_CLASS_STRUCT_VERSION; - allocate = vlcRuntimeClassAllocate<T>; - deallocate = vlcRuntimeClassDeallocate<T>; - invalidate = vlcRuntimeClassInvalidate<T>; - hasMethod = vlcRuntimeClassHasMethod<T>; - invoke = vlcRuntimeClassInvoke<T>; - invokeDefault = vlcRuntimeClassInvokeDefault<T>; - hasProperty = vlcRuntimeClassHasProperty<T>; - getProperty = vlcRuntimeClassGetProperty<T>; - setProperty = vlcRuntimeClassSetProperty<T>; - removeProperty = vlcRuntimeClassRemoveProperty<T>; -} - -template<class T> -VlcRuntimeClass<T>::~VlcRuntimeClass() -{ - delete propertyIdentifiers; - delete methodIdentifiers; -} - -template<class T> -VlcRuntimeObject *VlcRuntimeClass<T>::create(NPP instance) const -{ - return new T(instance, this); -} - -template<class T> -int VlcRuntimeClass<T>::indexOfMethod(NPIdentifier name) const -{ - if( methodIdentifiers ) - { - for(int c=0; c< T::methodCount; ++c ) - { - if( name == methodIdentifiers[c] ) - return c; - } - } - return -1; -} - -template<class T> -int VlcRuntimeClass<T>::indexOfProperty(NPIdentifier name) const -{ - if( propertyIdentifiers ) - { - for(int c=0; c< T::propertyCount; ++c ) - { - if( name == propertyIdentifiers[c] ) - return c; - } - } - return -1; -} - -/* -** defined runtime script objects -*/ - -class VlcRuntimeRootObject: public VlcRuntimeObject -{ -public: - VlcRuntimeRootObject(NPP instance, const NPClass *aClass) : - VlcRuntimeObject(instance, aClass) {}; - virtual ~VlcRuntimeRootObject() {}; - - static const int propertyCount; - static const NPUTF8 * const propertyNames[]; - - static const int methodCount; - static const NPUTF8 * const methodNames[]; - - virtual bool getProperty(int index, NPVariant *result); - virtual bool setProperty(int index, const NPVariant *value); - virtual bool removeProperty(int index); - virtual bool invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant *result); - virtual bool invokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result); -}; - diff --git a/mozilla/vlcshell.cpp b/mozilla/vlcshell.cpp index 4a77fd15587b..0629351f5886 100644 --- a/mozilla/vlcshell.cpp +++ b/mozilla/vlcshell.cpp @@ -21,9 +21,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -/* XXX: disable VLC here */ -#define USE_LIBVLC 1 - /***************************************************************************** * Preamble *****************************************************************************/ @@ -33,19 +30,10 @@ #include <string.h> #include <stdlib.h> -/* vlc stuff */ -#ifdef USE_LIBVLC -# include <vlc/vlc.h> -#endif - /* Mozilla stuff */ #ifdef HAVE_MOZILLA_CONFIG_H # include <mozilla-config.h> #endif -#include <nsISupports.h> -#include <nsMemory.h> -#include <npapi.h> -#include <npruntime.h> /* This is from mozilla java, do we really need it? */ #if 0 @@ -53,17 +41,12 @@ #endif #include "vlcplugin.h" -#include "vlcruntime.h" - -#if USE_LIBVLC -# define WINDOW_TEXT "(no picture)" -#else -# define WINDOW_TEXT "(no libvlc)" -#endif /* Enable/disable debugging printf's for X11 resizing */ #undef X11_RESIZE_DEBUG +#define WINDOW_TEXT "(no video)" + /***************************************************************************** * Unix-only declarations ******************************************************************************/ @@ -71,11 +54,9 @@ # define VOUT_PLUGINS "xvideo,x11,dummy" # define AOUT_PLUGINS "esd,arts,alsa,oss,dummy" -static unsigned int i_previous_height = 100000; -static unsigned int i_previous_width = 100000; - static void Redraw( Widget w, XtPointer closure, XEvent *event ); static void Resize( Widget w, XtPointer closure, XEvent *event ); + #endif /***************************************************************************** @@ -84,7 +65,6 @@ static void Resize( Widget w, XtPointer closure, XEvent *event ); #ifdef XP_MACOSX # define VOUT_PLUGINS "opengl,macosx,dummy" # define AOUT_PLUGINS "auhal,macosx,dummy" - #endif /***************************************************************************** @@ -94,9 +74,8 @@ static void Resize( Widget w, XtPointer closure, XEvent *event ); # define VOUT_PLUGINS "directx,wingdi,dummy" # define AOUT_PLUGINS "directx,waveout,dummy" -#if defined(XP_WIN) && !USE_LIBVLC -LRESULT CALLBACK Manage( HWND, UINT, WPARAM, LPARAM ); -#endif +static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ); + #endif /****************************************************************************** @@ -110,9 +89,9 @@ char * NPP_GetMIMEDescription( void ) NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) { - static nsIID nsid = VLCINTF_IID; static char psz_desc[1000]; + /* plugin class variables */ switch( variable ) { case NPPVpluginNameString: @@ -120,17 +99,13 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) return NPERR_NO_ERROR; case NPPVpluginDescriptionString: -#if USE_LIBVLC - snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, VLC_Version() ); -#else /* USE_LIBVLC */ - snprintf( psz_desc, 1000-1, PLUGIN_DESCRIPTION, "(disabled)" ); -#endif /* USE_LIBVLC */ - psz_desc[1000-1] = 0; + snprintf( psz_desc, sizeof(psz_desc)-1, PLUGIN_DESCRIPTION, VLC_Version() ); + psz_desc[sizeof(psz_desc)-1] = 0; *((char **)value) = psz_desc; return NPERR_NO_ERROR; default: - /* go on... */ + /* move on to instance variables ... */ break; } @@ -139,31 +114,21 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) return NPERR_INVALID_INSTANCE_ERROR; } - VlcPlugin* p_plugin = (VlcPlugin*) instance->pdata; + /* plugin instance variables */ - switch( variable ) + VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata); + if( NULL == p_plugin ) { - case NPPVpluginScriptableInstance: - *(nsISupports**)value = p_plugin->GetPeer(); - if( *(nsISupports**)value == NULL ) - { - return NPERR_OUT_OF_MEMORY_ERROR; - } - break; - - case NPPVpluginScriptableIID: - *(nsIID**)value = (nsIID*)NPN_MemAlloc( sizeof(nsIID) ); - if( *(nsIID**)value == NULL ) - { - return NPERR_OUT_OF_MEMORY_ERROR; - } - **(nsIID**)value = nsid; - break; + // plugin has not been initialized yet ! + return NPERR_INVALID_INSTANCE_ERROR; + } + switch( variable ) + { case NPPVpluginScriptableNPObject: - static VlcRuntimeClass<VlcRuntimeRootObject> *rootClass = new VlcRuntimeClass<VlcRuntimeRootObject>; - *(NPObject**)value = NPN_CreateObject(instance, rootClass); - if( *(NPObject**)value == NULL ) + /* create an instance and return it */ + *(NPObject**)value = NPN_CreateObject(instance, p_plugin->getScriptClass()); + if( NULL == *(NPObject**)value ) { return NPERR_OUT_OF_MEMORY_ERROR; } @@ -172,7 +137,6 @@ NPError NPP_GetValue( NPP instance, NPPVariable variable, void *value ) default: return NPERR_GENERIC_ERROR; } - return NPERR_NO_ERROR; } @@ -203,26 +167,41 @@ int16 NPP_HandleEvent( NPP instance, void * event ) return true; case updateEvt: { - NPWindow *npwindow = p_plugin->window; - - /* draw the beautiful "No Picture" */ - - ForeColor(blackColor); - PenMode( patCopy ); - - Rect rect; - rect.left = 0; - rect.top = 0; - rect.right = npwindow->width; - rect.bottom = npwindow->height; - PaintRect( &rect ); - - ForeColor(whiteColor); - char *text = strdup( WINDOW_TEXT ); - MoveTo( (npwindow->width-80)/ 2 , npwindow->height / 2 ); - DrawText( text , 0 , strlen(text) ); - free(text); + int needsDisplay = TRUE; + libvlc_instance_t *p_vlc = p_plugin->getVLC(); + if( p_vlc ) + { + if( libvlc_playlist_isplaying(p_vlc, NULL) ) + { + libvlc_input_t *p_input = libvlc_playlist_get_input(p_vlc, NULL); + if( p_input ) + { + needsDisplay = ! libvlc_input_has_vout(p_input, NULL); + libvlc_input_free(p_input); + } + } + } + if( needsDisplay ) + { + const NPWindow *npwindow = p_plugin->getWindow(); + + /* draw the beautiful "No Picture" */ + + ForeColor(blackColor); + PenMode( patCopy ); + + Rect rect; + rect.left = 0; + rect.top = 0; + rect.right = npwindow->width; + rect.bottom = npwindow->height; + PaintRect( &rect ); + + ForeColor(whiteColor); + MoveTo( (npwindow->width-80)/ 2 , npwindow->height / 2 ); + DrawText( WINDOW_TEXT , 0 , strlen(WINDOW_TEXT) ); + } return true; } case activateEvt: @@ -267,225 +246,28 @@ void NPP_Shutdown( void ) NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved ) { - int i; - -#if USE_LIBVLC - vlc_value_t value; - int i_ret; - -#endif /* USE_LIBVLC */ + NPError status; if( instance == NULL ) { return NPERR_INVALID_INSTANCE_ERROR; } - VlcPlugin * p_plugin = new VlcPlugin( instance ); - - if( p_plugin == NULL ) + VlcPlugin * p_plugin = new VlcPlugin( instance, mode ); + if( NULL == p_plugin ) { return NPERR_OUT_OF_MEMORY_ERROR; } - instance->pdata = p_plugin; - -#ifdef XP_WIN - p_plugin->p_hwnd = NULL; - p_plugin->pf_wndproc = NULL; -#endif /* XP_WIN */ - -#ifdef XP_UNIX - p_plugin->window = 0; - p_plugin->p_display = NULL; -#endif /* XP_UNIX */ - - p_plugin->p_npwin = NULL; - p_plugin->i_npmode = mode; - p_plugin->i_width = 0; - p_plugin->i_height = 0; - -#if USE_LIBVLC - p_plugin->i_vlc = VLC_Create(); - if( p_plugin->i_vlc < 0 ) - { - p_plugin->i_vlc = 0; - delete p_plugin; - p_plugin = NULL; - return NPERR_GENERIC_ERROR; - } - - { -#ifdef XP_MACOSX - char *ppsz_argv[] = - { - "vlc", - "-vvvv", - "--plugin-path", - "/Library/Internet Plug-Ins/VLC Plugin.plugin/" - "Contents/MacOS/modules" - }; - -#elif defined(XP_WIN) - char *ppsz_argv[] = { NULL, "-vv" }; - HKEY h_key; - DWORD i_type, i_data = MAX_PATH + 1; - char p_data[MAX_PATH + 1]; - if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\VideoLAN\\VLC", - 0, KEY_READ, &h_key ) == ERROR_SUCCESS ) - { - if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type, - (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS ) - { - if( i_type == REG_SZ ) - { - strcat( p_data, "\\vlc" ); - ppsz_argv[0] = p_data; - } - } - RegCloseKey( h_key ); - } - - if( !ppsz_argv[0] ) ppsz_argv[0] = "vlc"; - -#else /* XP_MACOSX */ - char *ppsz_argv[] = - { - "vlc" - "-vvvv" - /*, "--plugin-path", ""*/ - }; - -#endif /* XP_MACOSX */ - - /* HACK: special case for loop, to have it set before playlist startup - */ - for( i = 0; i < argc ; i++ ) - { - if( !strcmp( argn[i], "loop" ) ) - { - if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) ) - { - value.b_bool = VLC_TRUE; - VLC_VariableSet( p_plugin->i_vlc, "conf::loop", value ); - } - } - } - - i_ret = VLC_Init( p_plugin->i_vlc, sizeof(ppsz_argv)/sizeof(char*), - ppsz_argv ); - + status = p_plugin->init(argc, argn, argv); + if( NPERR_NO_ERROR == status ) { + instance->pdata = reinterpret_cast<void*>(p_plugin); } - - if( i_ret ) - { - VLC_Destroy( p_plugin->i_vlc ); - p_plugin->i_vlc = 0; + else { delete p_plugin; - p_plugin = NULL; - return NPERR_GENERIC_ERROR; } - - value.psz_string = "dummy"; - VLC_VariableSet( p_plugin->i_vlc, "conf::intf", value ); - value.psz_string = VOUT_PLUGINS; - VLC_VariableSet( p_plugin->i_vlc, "conf::vout", value ); - value.psz_string = AOUT_PLUGINS; - VLC_VariableSet( p_plugin->i_vlc, "conf::aout", value ); - -#else /* USE_LIBVLC */ - p_plugin->i_vlc = 1; - -#endif /* USE_LIBVLC */ - - p_plugin->b_stream = VLC_FALSE; - p_plugin->b_autoplay = VLC_FALSE; - p_plugin->psz_target = NULL; - - for( i = 0; i < argc ; i++ ) - { - if( !strcmp( argn[i], "target" ) ) - { - p_plugin->psz_target = argv[i]; - } - else if( !strcmp( argn[i], "autoplay" ) ) - { - if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) ) - { - p_plugin->b_autoplay = 1; - } - } - else if( !strcmp( argn[i], "autostart" ) ) - { - if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "true" ) ) - { - p_plugin->b_autoplay = 1; - } - } - else if( !strcmp( argn[i], "filename" ) ) - { - p_plugin->psz_target = argv[i]; - } - else if( !strcmp( argn[i], "src" ) ) - { - p_plugin->psz_target = argv[i]; - } - -#if USE_LIBVLC - else if( !strcmp( argn[i], "fullscreen" ) ) - { - if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) ) - { - value.b_bool = VLC_TRUE; - VLC_VariableSet( p_plugin->i_vlc, "conf::fullscreen", value ); - } - } - else if( !strcmp( argn[i], "mute" ) ) - { - if( !strcmp( argv[i], "1" ) || !strcmp( argv[i], "yes" ) ) - { - VLC_VolumeMute( p_plugin->i_vlc ); - } - } -#endif /* USE_LIBVLC */ - } - - if( p_plugin->psz_target ) - { - p_plugin->psz_target = strdup( p_plugin->psz_target ); - } - - return NPERR_NO_ERROR; -} - -#ifdef XP_WIN -/* This is really ugly but there is a deadlock when stopping a stream - * (in VLC_CleanUp()) because the video output is a child of the drawable but - * is in a different thread. */ -static void HackStopVout( VlcPlugin* p_plugin ) -{ - MSG msg; - HWND hwnd; - vlc_value_t value; - - VLC_VariableGet( p_plugin->i_vlc, "drawable", &value ); - - hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 ); - if( !hwnd ) return; - - PostMessage( hwnd, WM_CLOSE, 0, 0 ); - - do - { - while( PeekMessage( &msg, (HWND)value.i_int, 0, 0, PM_REMOVE ) ) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - if( FindWindowEx( (HWND)value.i_int, 0, 0, 0 ) ) Sleep( 10 ); - } - while( (hwnd = FindWindowEx( (HWND)value.i_int, 0, 0, 0 )) ); + return status; } -#endif /* XP_WIN */ NPError NPP_Destroy( NPP instance, NPSavedData** save ) { @@ -494,30 +276,10 @@ NPError NPP_Destroy( NPP instance, NPSavedData** save ) return NPERR_INVALID_INSTANCE_ERROR; } - VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata; - - if( p_plugin != NULL ) - { - if( p_plugin->i_vlc ) - { -#if USE_LIBVLC -# ifdef XP_WIN - HackStopVout( p_plugin ); -# endif /* XP_WIN */ - VLC_CleanUp( p_plugin->i_vlc ); - VLC_Destroy( p_plugin->i_vlc ); -#endif /* USE_LIBVLC */ - p_plugin->i_vlc = 0; - } - - if( p_plugin->psz_target ) - { - free( p_plugin->psz_target ); - p_plugin->psz_target = NULL; - } + VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata); + if( p_plugin ) delete p_plugin; - } instance->pdata = NULL; @@ -526,71 +288,20 @@ NPError NPP_Destroy( NPP instance, NPSavedData** save ) NPError NPP_SetWindow( NPP instance, NPWindow* window ) { - vlc_value_t value; -#ifdef XP_MACOSX - vlc_value_t valuex; - vlc_value_t valuey; - vlc_value_t valuew; - vlc_value_t valueh; - vlc_value_t valuet; - vlc_value_t valuel; - vlc_value_t valueb; - vlc_value_t valuer; - vlc_value_t valueportx; - vlc_value_t valueporty; - vlc_value_t valueredraw; -#endif /* XP_MACOSX */ - - if( instance == NULL ) + if( ! instance ) { return NPERR_INVALID_INSTANCE_ERROR; } - VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata; - - /* Write the window ID for vlc */ -#if USE_LIBVLC - -#ifdef XP_MACOSX - value.i_int = (int)(((NP_Port*) (window->window))->port); - VLC_VariableSet( p_plugin->i_vlc, "drawable", value ); - - valueportx.i_int = ((NP_Port*) (window->window))->portx; - valueporty.i_int = ((NP_Port*) (window->window))->porty; - VLC_VariableSet( p_plugin->i_vlc, "drawableportx", valueportx ); - VLC_VariableSet( p_plugin->i_vlc, "drawableporty", valueporty ); - - valuex.i_int = window->x; - valuey.i_int = window->y; - valuew.i_int = window->width; - valueh.i_int = window->height; - valuet.i_int = window->clipRect.top; - valuel.i_int = window->clipRect.left; - valueb.i_int = window->clipRect.bottom; - valuer.i_int = window->clipRect.right; - - VLC_VariableSet( p_plugin->i_vlc, "drawablet", valuet ); - VLC_VariableSet( p_plugin->i_vlc, "drawablel", valuel ); - VLC_VariableSet( p_plugin->i_vlc, "drawableb", valueb ); - VLC_VariableSet( p_plugin->i_vlc, "drawabler", valuer ); - VLC_VariableSet( p_plugin->i_vlc, "drawablex", valuex ); - VLC_VariableSet( p_plugin->i_vlc, "drawabley", valuey ); - VLC_VariableSet( p_plugin->i_vlc, "drawablew", valuew ); - VLC_VariableSet( p_plugin->i_vlc, "drawableh", valueh ); - - p_plugin->window = window; - - valueredraw.i_int = 1; - VLC_VariableSet( p_plugin->i_vlc, "drawableredraw", valueredraw ); - -#else /* XP_MACOSX */ - /* FIXME: this cast sucks */ - value.i_int = (int) (ptrdiff_t) (void *) window->window; - VLC_VariableSet( p_plugin->i_vlc, "drawable", value ); - -#endif /* XP_MACOSX */ + /* NPP_SetWindow may be called before NPP_New (Opera) */ + VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata); + if( ! p_plugin ) + { + /* we should probably show a splash screen here */ + return NPERR_NO_ERROR; + } -#endif /* USE_LIBVLC */ + libvlc_instance_t *p_vlc = p_plugin->getVLC(); /* * PLUGIN DEVELOPERS: @@ -600,100 +311,128 @@ NPError NPP_SetWindow( NPP instance, NPWindow* window ) * size changes, etc. */ -#ifdef XP_WIN - if( !window || !window->window ) + libvlc_drawable_t drawable; + const NPWindow *curwin = p_plugin->getWindow(); + +#ifdef XP_MACOSX + if( window && window->window ) { - /* Window was destroyed. Invalidate everything. */ - if( p_plugin->p_npwin ) + /* check if plugin has a new parent window */ + drawable = (libvlc_drawable_t)(((NP_Port*) (window->window))->port); + if( !curwin->window || drawable != (libvlc_drawable_t)(((NP_Port*) (curwin->window))->port) ) { -#if !USE_LIBVLC - SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC, - (LONG)p_plugin->pf_wndproc ); -#endif /* !USE_LIBVLC */ - p_plugin->pf_wndproc = NULL; - p_plugin->p_hwnd = NULL; + /* set/change parent window */ + libvlc_video_set_parent(p_vlc, drawable, NULL); } - p_plugin->p_npwin = window; - return NPERR_NO_ERROR; + /* as MacOS X video output is windowless, set viewport */ + libvlc_rectangle_t view, clip; + + /* + ** browser sets port origin to top-left location of plugin relative to GrafPort + ** window origin is set relative to document, which of little use for drawing + */ + view.top = ((NP_Port*) (window->window))->porty; + view.left = ((NP_Port*) (window->window))->portx; + view.bottom = window->height+view.top; + view.right = window->width+view.left; + + /* clipRect coordinates are also relative to GrafPort */ + clip.top = window->clipRect.top; + clip.left = window->clipRect.left; + clip.bottom = window->clipRect.bottom; + clip.right = window->clipRect.right; + + libvlc_video_set_viewport(p_vlc, &view, &clip, NULL); + + /* remember window details */ + p_plugin->setWindow(window); } +#endif /* XP_MACOSX */ - if( p_plugin->p_npwin ) +#ifdef XP_WIN + if( window && window->window ) { - if( p_plugin->p_hwnd == (HWND)window->window ) + /* check if plugin has a new parent window */ + /* FIXME: this cast sucks */ + drawable = (libvlc_drawable_t) (HWND) (window->window); + if( !curwin->window || drawable != (libvlc_drawable_t)(HWND) (curwin->window) ) { - /* Same window, but something may have changed. First we - * update the plugin structure, then we redraw the window */ - p_plugin->i_width = window->width; - p_plugin->i_height = window->height; - p_plugin->p_npwin = window; -#if !USE_LIBVLC - InvalidateRect( p_plugin->p_hwnd, NULL, TRUE ); - UpdateWindow( p_plugin->p_hwnd ); -#endif /* !USE_LIBVLC */ - return NPERR_NO_ERROR; + /* reset previous window settings */ + HWND oldwin = (HWND)p_plugin->getWindow()->window; + WNDPROC oldproc = p_plugin->getWindowProc(); + if( oldproc ) + { + /* reset WNDPROC */ + SetWindowLong( oldwin, GWL_WNDPROC, (LONG)oldproc ); + } + /* install our WNDPROC */ + p_plugin->setWindowProc( (WNDPROC)SetWindowLong( (HWND)drawable, + GWL_WNDPROC, (LONG)Manage ) ); + + /* attach our plugin object */ + SetWindowLongPtr((HWND)drawable, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(p_plugin)); + + /* change window style to our liking */ + LONG style = GetWindowLong((HWND)drawable, GWL_STYLE); + style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS; + SetWindowLong((HWND)drawable, GWL_STYLE, style); + + /* change/set parent */ + libvlc_video_set_parent(p_vlc, drawable, NULL); } - /* Window has changed. Destroy the one we have, and go - * on as if it was a real initialization. */ -#if !USE_LIBVLC - SetWindowLong( p_plugin->p_hwnd, GWL_WNDPROC, - (LONG)p_plugin->pf_wndproc ); -#endif /* !USE_LIBVLC */ - p_plugin->pf_wndproc = NULL; - p_plugin->p_hwnd = NULL; + /* remember window details */ + p_plugin->setWindow(window); + + /* Redraw window */ + InvalidateRect( (HWND)drawable, NULL, TRUE ); + UpdateWindow( (HWND)drawable ); + } + else + { + /* reset WNDPROC */ + HWND oldwin = (HWND)curwin->window; + SetWindowLong( oldwin, GWL_WNDPROC, (LONG)(p_plugin->getWindowProc()) ); + p_plugin->setWindowProc(NULL); + /* change/set parent */ + libvlc_video_set_parent(p_vlc, 0, NULL); } +#endif /* XP_WIN */ + +#ifdef XP_UNIX + if( window && window->window ) + { + Window win = (Window) window->window; + Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display; -#if !USE_LIBVLC - p_plugin->pf_wndproc = (WNDPROC)SetWindowLong( (HWND)window->window, - GWL_WNDPROC, (LONG)Manage ); -#endif /* !USE_LIBVLC */ + XResizeWindow( p_display, win, window->width, window->height ); + Widget w = XtWindowToWidget( p_display, window ); - p_plugin->p_hwnd = (HWND)window->window; - SetProp( p_plugin->p_hwnd, "w00t", (HANDLE)p_plugin ); - InvalidateRect( p_plugin->p_hwnd, NULL, TRUE ); - UpdateWindow( p_plugin->p_hwnd ); -#endif /* XP_WIN */ + XtAddEventHandler( w, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin ); + XtAddEventHandler( w, StructureNotifyMask, FALSE, (XtEventHandler)Resize, p_plugin ); - p_plugin->i_width = window->width; - p_plugin->i_height = window->height; - p_plugin->p_npwin = window; + /* remember window */ + p_plugin->setWindow(window); -#ifdef XP_UNIX - p_plugin->window = (Window) window->window; - p_plugin->p_display = - ((NPSetWindowCallbackStruct *)window->ws_info)->display; - - XResizeWindow( p_plugin->p_display, p_plugin->window, - p_plugin->i_width, p_plugin->i_height ); - Widget w = XtWindowToWidget( p_plugin->p_display, p_plugin->window ); - - XtAddEventHandler( w, ExposureMask, FALSE, - (XtEventHandler)Redraw, p_plugin ); - XtAddEventHandler( w, StructureNotifyMask, FALSE, - (XtEventHandler)Resize, p_plugin ); - Redraw( w, (XtPointer)p_plugin, NULL ); + Redraw( w, (XtPointer)p_plugin, NULL ); + } #endif /* XP_UNIX */ if( !p_plugin->b_stream ) { - int i_mode = PLAYLIST_APPEND; - - if( p_plugin->b_autoplay ) - { - i_mode |= PLAYLIST_GO; - } - if( p_plugin->psz_target ) { -#if USE_LIBVLC - VLC_AddTarget( p_plugin->i_vlc, p_plugin->psz_target, - 0, 0, i_mode, -666 ); -#endif - p_plugin->b_stream = VLC_TRUE; + if( VLC_SUCCESS == libvlc_playlist_add( p_vlc, p_plugin->psz_target, NULL, NULL ) ) + { + if( p_plugin->b_autoplay ) + { + libvlc_playlist_play(p_vlc, 0, 0, NULL, NULL); + } + p_plugin->b_stream = VLC_TRUE; + } } } - return NPERR_NO_ERROR; } @@ -739,7 +478,7 @@ int32 NPP_WriteReady( NPP instance, NPStream *stream ) if (instance != NULL) { - p_plugin = (VlcPlugin*) instance->pdata; + p_plugin = reinterpret_cast<VlcPlugin*>(instance->pdata); /* Muahahahahahahaha */ return STREAMBUFSIZE; /*return SARASS_SIZE;*/ @@ -785,7 +524,7 @@ void NPP_StreamAsFile( NPP instance, NPStream *stream, const char* fname ) /* fprintf(stderr, "NPP_StreamAsFile %s\n", fname); */ -#if USE_LIBVLC +#if 0 VlcPlugin* p_plugin = (VlcPlugin*)instance->pdata; VLC_AddTarget( p_plugin->i_vlc, fname, 0, 0, @@ -875,13 +614,16 @@ void NPP_Print( NPP instance, NPPrint* printInfo ) /****************************************************************************** * Windows-only methods *****************************************************************************/ -#if defined(XP_WIN) && !USE_LIBVLC -LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ) +#if XP_WIN +static LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ) { - VlcPlugin* p_plugin = (VlcPlugin*) GetProp( p_hwnd, "w00t" ); + VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(GetWindowLongPtr(p_hwnd, GWLP_USERDATA)); switch( i_msg ) { + case WM_ERASEBKGND: + return 1L; + case WM_PAINT: { PAINTSTRUCT paintstruct; @@ -891,18 +633,21 @@ LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ) hdc = BeginPaint( p_hwnd, &paintstruct ); GetClientRect( p_hwnd, &rect ); - FillRect( hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH) ); - TextOut( hdc, p_plugin->i_width / 2 - 40, p_plugin->i_height / 2, + + FillRect( hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH) ); + SetTextColor(hdc, RGB(255, 255, 255)); + SetBkColor(hdc, RGB(0, 0, 0)); + TextOut( hdc, (rect.right-rect.left)/ 2 - 40, + (rect.bottom-rect.top)/ 2, WINDOW_TEXT, strlen(WINDOW_TEXT) ); EndPaint( p_hwnd, &paintstruct ); - break; + return 0L; } default: - p_plugin->pf_wndproc( p_hwnd, i_msg, wpar, lpar ); - break; + /* delegate to default handler */ + return p_plugin->getWindowProc()( p_hwnd, i_msg, wpar, lpar ); } - return 0; } #endif /* XP_WIN */ @@ -912,29 +657,37 @@ LRESULT CALLBACK Manage( HWND p_hwnd, UINT i_msg, WPARAM wpar, LPARAM lpar ) #ifdef XP_UNIX static void Redraw( Widget w, XtPointer closure, XEvent *event ) { - VlcPlugin* p_plugin = (VlcPlugin*)closure; + VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure); + const NPWindow *window = p_plugin->getWindow(); GC gc; XGCValues gcv; - gcv.foreground = BlackPixel( p_plugin->p_display, 0 ); - gc = XCreateGC( p_plugin->p_display, p_plugin->window, GCForeground, &gcv ); + Window w = (Window) window->window; + Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display; + + gcv.foreground = BlackPixel( p_display, 0 ); + gc = XCreateGC( p_display, w, GCForeground, &gcv ); - XFillRectangle( p_plugin->p_display, p_plugin->window, gc, - 0, 0, p_plugin->i_width, p_plugin->i_height ); + XFillRectangle( p_display, w, gc, + 0, 0, window->width, window->height ); - gcv.foreground = WhitePixel( p_plugin->p_display, 0 ); - XChangeGC( p_plugin->p_display, gc, GCForeground, &gcv ); + gcv.foreground = WhitePixel( p_display, 0 ); + XChangeGC( p_display, gc, GCForeground, &gcv ); - XDrawString( p_plugin->p_display, p_plugin->window, gc, - p_plugin->i_width / 2 - 40, p_plugin->i_height / 2, + XDrawString( p_display, w, gc, + window->width / 2 - 40, window->height / 2, WINDOW_TEXT, strlen(WINDOW_TEXT) ); - XFreeGC( p_plugin->p_display, gc ); + XFreeGC( p_display, gc ); } static void Resize ( Widget w, XtPointer closure, XEvent *event ) { - VlcPlugin* p_plugin = (VlcPlugin*)closure; + VlcPlugin* p_plugin = reinterpret_cast<VlcPlugin*>(closure); + const NPWindow *window = p_plugin->getWindow(); + Window w = (Window) window->window; + Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display; + int i_ret; Window root_return, parent_return, * children_return; Window base_window; @@ -952,23 +705,20 @@ static void Resize ( Widget w, XtPointer closure, XEvent *event ) } #endif /* X11_RESIZE_DEBUG */ - if( p_plugin->i_height == i_previous_height && - p_plugin->i_width == i_previous_width ) + if( ! p_plugin->setSize(window->width, window->height) ) { + /* size already set */ return; } - i_previous_height = p_plugin->i_height; - i_previous_width = p_plugin->i_width; - i_ret = XResizeWindow( p_plugin->p_display, p_plugin->window, - p_plugin->i_width, p_plugin->i_height ); + i_ret = XResizeWindow( p_display, w, window->i_width, window->i_height ); #ifdef X11_RESIZE_DEBUG fprintf( stderr, "vlcshell::Resize() XResizeWindow(owner) returned %d\n", i_ret ); - XGetWindowAttributes ( p_plugin->p_display, p_plugin->window, &attr ); + XGetWindowAttributes ( p_display, w, &attr ); /* X is asynchronous, so the current size reported here is not necessarily the requested size as the Resize request may not @@ -977,7 +727,7 @@ static void Resize ( Widget w, XtPointer closure, XEvent *event ) attr.width, attr.height ); #endif /* X11_RESIZE_DEBUG */ - XQueryTree( p_plugin->p_display, p_plugin->window, + XQueryTree( p_display, w, &root_return, &parent_return, &children_return, &i_nchildren ); @@ -993,8 +743,8 @@ static void Resize ( Widget w, XtPointer closure, XEvent *event ) base_window ); #endif /* X11_RESIZE_DEBUG */ - i_ret = XResizeWindow( p_plugin->p_display, base_window, - p_plugin->i_width, p_plugin->i_height ); + i_ret = XResizeWindow( p_display, base_window, + window->width, window->height ); #ifdef X11_RESIZE_DEBUG fprintf( stderr, diff --git a/src/control/video.c b/src/control/video.c index 1ec56b07375a..4459c5aaa13d 100644 --- a/src/control/video.c +++ b/src/control/video.c @@ -234,6 +234,96 @@ void libvlc_video_resize( libvlc_input_t *p_input, int width, int height, libvlc vlc_object_release( p_vout ); } +/* global video settings */ + +void libvlc_video_set_parent( libvlc_instance_t *p_instance, libvlc_drawable_t d, + libvlc_exception_t *p_e ) +{ + /* set as default for future vout instances */ + var_SetInteger(p_instance->p_vlc, "drawable", (int)d); + + if( libvlc_playlist_isplaying(p_instance, p_e) ) + { + libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e); + if( p_input ) + { + vout_thread_t *p_vout = GetVout( p_input, p_e ); + if( p_vout ) + { + /* tell running vout to re-parent */ + vout_Control( p_vout , VOUT_REPARENT, d); + vlc_object_release( p_vout ); + } + libvlc_input_free(p_input); + } + } +} + +void libvlc_video_set_size( libvlc_instance_t *p_instance, int width, int height, + libvlc_exception_t *p_e ) +{ + /* set as default for future vout instances */ + config_PutInt(p_instance->p_vlc, "width", width); + config_PutInt(p_instance->p_vlc, "height", height); + + if( libvlc_playlist_isplaying(p_instance, p_e) ) + { + libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e); + if( p_input ) + { + vout_thread_t *p_vout = GetVout( p_input, p_e ); + if( p_vout ) + { + /* tell running vout to re-size */ + vout_Control( p_vout , VOUT_SET_SIZE, width, height); + vlc_object_release( p_vout ); + } + libvlc_input_free(p_input); + } + } +} + +void libvlc_video_set_viewport( libvlc_instance_t *p_instance, + const libvlc_rectangle_t *view, const libvlc_rectangle_t *clip, + libvlc_exception_t *p_e ) +{ + if( NULL == view ) + { + libvlc_exception_raise( p_e, "viewport is NULL" ); + } + + /* if clip is NULL, then use view rectangle as clip */ + if( NULL == clip ) + clip = view; + + /* set as default for future vout instances */ + var_SetInteger( p_instance->p_vlc, "drawable-view-top", view->top ); + var_SetInteger( p_instance->p_vlc, "drawable-view-left", view->left ); + var_SetInteger( p_instance->p_vlc, "drawable-view-bottom", view->bottom ); + var_SetInteger( p_instance->p_vlc, "drawable-view-right", view->right ); + var_SetInteger( p_instance->p_vlc, "drawable-clip-top", clip->top ); + var_SetInteger( p_instance->p_vlc, "drawable-clip-left", clip->left ); + var_SetInteger( p_instance->p_vlc, "drawable-clip-bottom", clip->bottom ); + var_SetInteger( p_instance->p_vlc, "drawable-clip-right", clip->right ); + + if( libvlc_playlist_isplaying(p_instance, p_e) ) + { + libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e); + if( p_input ) + { + vout_thread_t *p_vout = GetVout( p_input, p_e ); + if( p_vout ) + { + /* change viewport for running vout */ + vout_Control( p_vout , VOUT_SET_VIEWPORT, + view->top, view->left, view->bottom, view->right, + clip->top, clip->left, clip->bottom, clip->right ); + vlc_object_release( p_vout ); + } + libvlc_input_free(p_input); + } + } +} int libvlc_video_destroy( libvlc_input_t *p_input, libvlc_exception_t *p_e ) diff --git a/src/libvlc.c b/src/libvlc.c index 30e864cfadb0..a006aae9c3ac 100644 --- a/src/libvlc.c +++ b/src/libvlc.c @@ -833,17 +833,14 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] ) * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin */ var_Create( p_vlc, "drawable", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawableredraw", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawablet", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawablel", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawableb", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawabler", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawablex", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawabley", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawablew", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawableh", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawableportx", VLC_VAR_INTEGER ); - var_Create( p_vlc, "drawableporty", VLC_VAR_INTEGER ); + var_Create( p_vlc, "drawable-view-top", VLC_VAR_INTEGER ); + var_Create( p_vlc, "drawable-view-left", VLC_VAR_INTEGER ); + var_Create( p_vlc, "drawable-view-bottom", VLC_VAR_INTEGER ); + var_Create( p_vlc, "drawable-view-right", VLC_VAR_INTEGER ); + var_Create( p_vlc, "drawable-clip-top", VLC_VAR_INTEGER ); + var_Create( p_vlc, "drawable-clip-left", VLC_VAR_INTEGER ); + var_Create( p_vlc, "drawable-clip-bottom", VLC_VAR_INTEGER ); + var_Create( p_vlc, "drawable-clip-right", VLC_VAR_INTEGER ); /* Create volume callback system. */ var_Create( p_vlc, "volume-change", VLC_VAR_BOOL ); -- GitLab