Commit a593fa18 authored by Damien Fouilleul's avatar Damien Fouilleul

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)
parent faef0357
......@@ -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= */
};
/**
......
......@@ -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
......
......@@ -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, &param);
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);
}
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;
}
......@@ -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
###############################################################################
......
/*****************************************************************************
* 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;
}
/*****************************************************************************
* 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);
};
/*****************************************************************************
* 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;
}
/*****************************************************************************
* vlcruntime.h: a VLC plugin for Mozilla
* runtime.h: a VLC plugin for Mozilla
*****************************************************************************
* Copyright (C) 2002-2005 the VideoLAN team
* $Id: vlcruntime.h 14466 2006-02-22 23:34:54Z dionoea $
* $Id: RuntimeNPObject.h 14466 2006-02-22 23:34:54Z dionoea $
*
* Authors: Damien Fouilleul <damien.fouilleul@laposte.net>
*
......@@ -21,36 +21,95 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef __NPORUNTIME_H__
#define __NPORUNTIME_H__
/*
** support framework for runtime script objects
*/
class VlcRuntimeObject : public NPObject
#include <npapi.h>
#include <npruntime.h>
class RuntimeNPObject : public NPObject
{
public:
VlcRuntimeObject(NPP instance, const NPClass *aClass) :
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 ~VlcRuntimeObject() {};
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);
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
template<class T> class RuntimeNPClass : public NPClass
{
public:
VlcRuntimeClass();
virtual ~VlcRuntimeClass();
RuntimeNPClass();
virtual ~RuntimeNPClass();
VlcRuntimeObject *create(NPP instance) const;
/*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;
......@@ -61,106 +120,107 @@ private:
};
template<class T>
static NPObject *vlcRuntimeClassAllocate(NPP instance, NPClass *aClass)
static NPObject *RuntimeNPClassAllocate(NPP instance, NPClass *aClass)
{
const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(aClass);
const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(aClass);
return (NPObject *)vClass->create(instance);
}
template<class T>
static void vlcRuntimeClassDeallocate(NPObject *npobj)
static void RuntimeNPClassDeallocate(NPObject *npobj)
{
VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj);
RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
delete vObj;
}
template<class T>
static void vlcRuntimeClassInvalidate(NPObject *npobj)
static void RuntimeNPClassInvalidate(NPObject *npobj)
{
VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj);
RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
vObj->_instance = NULL;
}
template<class T>
bool vlcRuntimeClassHasMethod(NPObject *npobj, NPIdentifier name)
static bool RuntimeNPClassHasMethod(NPObject *npobj, NPIdentifier name)
{
const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class);
const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
return vClass->indexOfMethod(name) != -1;
}
template<class T>
bool vlcRuntimeClassHasProperty(NPObject *npobj, NPIdentifier name)
static bool RuntimeNPClassHasProperty(NPObject *npobj, NPIdentifier name)
{
const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class);
const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
return vClass->indexOfProperty(name) != -1;
}
template<class T>
bool vlcRuntimeClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
static bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
{
const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class);
const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
int index = vClass->indexOfProperty(name);
if( index != -1 )
{
VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj);
return vObj->getProperty(index, result);
RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
return vObj->returnInvokeResult(vObj->getProperty(index, result));
}
return false;
}
template<class T>
bool vlcRuntimeClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
static bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
{
const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class);
const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
int index = vClass->indexOfProperty(name);
if( index != -1 )
{
VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj);
return vObj->setProperty(index, value);
RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
return vObj->returnInvokeResult(vObj->setProperty(index, value));
}
return false;
}
template<class T>
bool vlcRuntimeClassRemoveProperty(NPObject *npobj, NPIdentifier name)
static bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name)
{
const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class);
const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
int index = vClass->indexOfProperty(name);
if( index != -1 )
{
VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj);
return vObj->removeProperty(index);
RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
return vObj->returnInvokeResult(vObj->removeProperty(index));
}
return false;
}
template<class T>
static bool vlcRuntimeClassInvoke(NPObject *npobj, NPIdentifier name,
static bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name,
const NPVariant *args, uint32_t argCount,
NPVariant *result)
{
const VlcRuntimeClass<T> *vClass = static_cast<VlcRuntimeClass<T> *>(npobj->_class);
const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
int index = vClass->indexOfMethod(name);
if( index != -1 )
{
VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj);
return vObj->invoke(index, args, argCount, result);
RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
return vObj->returnInvokeResult(vObj->invoke(index, args, argCount, result));
}
return false;
}
template<class T>
static bool vlcRuntimeClassInvokeDefault(NPObject *npobj,
static bool RuntimeNPClassInvokeDefault(NPObject *npobj,
const NPVariant *args,
uint32_t argCount,
NPVariant *result)
{
VlcRuntimeObject *vObj = static_cast<VlcRuntimeObject *>(npobj);
return vObj->invokeDefault(args, argCount, result);
RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
return vObj->returnInvokeResult(vObj->invokeDefault(args, argCount, result));
}
template<class T>
VlcRuntimeClass<T>::VlcRuntimeClass()
RuntimeNPClass<T>::RuntimeNPClass()
{
// retreive property identifiers from names
if( T::propertyCount > 0 )
......@@ -182,33 +242,33 @@ VlcRuntimeClass<T>::VlcRuntimeClass()
// 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>;
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>
VlcRuntimeClass<T>::~VlcRuntimeClass()
RuntimeNPClass<T>::~RuntimeNPClass()
{
delete propertyIdentifiers;
delete methodIdentifiers;
}
template<class T>
VlcRuntimeObject *VlcRuntimeClass<T>::create(NPP instance) const
RuntimeNPObject *RuntimeNPClass<T>::create(NPP instance) const
{
return new T(instance, this);
}
template<class T>
int VlcRuntimeClass<T>::indexOfMethod(NPIdentifier name) const
int RuntimeNPClass<T>::indexOfMethod(NPIdentifier name) const
{
if( methodIdentifiers )
{
......@@ -222,7 +282,7 @@ int VlcRuntimeClass<T>::indexOfMethod(NPIdentifier name) const
}
template<class T>
int VlcRuntimeClass<T>::indexOfProperty(NPIdentifier name) const
int RuntimeNPClass<T>::indexOfProperty(NPIdentifier name) const
{
if( propertyIdentifiers )
{
......@@ -235,27 +295,4 @@ int VlcRuntimeClass<T>::indexOfProperty(NPIdentifier name) const
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);
};
#endif
/*****************************************************************************
* 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;
}
/*****************************************************************************
* vlcpeer.h: scriptable peer descriptor
* vlc.h: a VLC plugin for Mozilla
*****************************************************************************
* Copyright (C) 2002-2005 the VideoLAN team
* $Id$
* $Id: vlcruntime.h 14466 2006-02-22 23:34:54Z dionoea $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* 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
......@@ -20,42 +20,29 @@
* 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"
/*
** defined runtime script objects
*/
class VlcPlugin;
#include "nporuntime.h"
class VlcPeer : public VlcIntf, public ClassInfo
class VlcNPObject: public RuntimeNPObject
{
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;
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);
};
#endif
#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);
};
/*****************************************************************************
* 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;
}
......@@ -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 )
{
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 */
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]) )
{
p_peer->Disable();
p_peer->Release();
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
VlcPlugin::~VlcPlugin()
{
delete psz_baseURL;
delete psz_target;
if( libvlc_instance )
libvlc_destroy(libvlc_instance);
}
/*****************************************************************************
* VlcPlugin methods
*****************************************************************************/
void VlcPlugin::SetInstance( NPP instance )
char *VlcPlugin::getAbsoluteURL(const char *url)
{
p_instance = instance;
}
if( NULL != url )
{
// check whether URL is already absolute
const char *end=strchr(url, ':');
if( (NULL != end) && (end != url) )
{
// 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);
}
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);
NPP VlcPlugin::GetInstance()
{
return p_instance;
}
/*
** relative url could be empty,
** in which case return base URL
*/
if( '\0' == *url )
return href;
/*
** locate pathname part of base URL
*/
VlcIntf* VlcPlugin::GetPeer()
{
if( !p_peer )
/* skip over protocol part */
char *pathstart = strchr(href, ':');
char *pathend;
if( '/' == *(++pathstart) )
{
p_peer = new VlcPeer( this );
if( p_peer == NULL )
if( '/' == *(++pathstart) )
{
return NULL;
++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 = '/';
}
NS_ADDREF( p_peer );
/* relative URL made of an absolute path ? */
if( '/' == *url )
{
/* replace path completely */
strcpy(pathstart, url);
return href;
}
NS_ADDREF( p_peer );
return p_peer;
/* 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;
}
#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
/*****************************************************************************
* 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
};
/*******************************************************************************
......
/*****************************************************************************
* 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;
}
......@@ -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;
// plugin has not been initialized yet !
return NPERR_INVALID_INSTANCE_ERROR;
}
break;
case NPPVpluginScriptableIID:
*(nsIID**)value = (nsIID*)NPN_MemAlloc( sizeof(nsIID) );
if( *(nsIID**)value == NULL )
switch( variable )
{
return NPERR_OUT_OF_MEMORY_ERROR;
}
**(nsIID**)value = nsid;
break;
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,7 +167,24 @@ int16 NPP_HandleEvent( NPP instance, void * event )
return true;
case updateEvt:
{
NPWindow *npwindow = p_plugin->window;
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" */
......@@ -218,11 +199,9 @@ int16 NPP_HandleEvent( NPP instance, void * event )
PaintRect( &rect );
ForeColor(whiteColor);
char *text = strdup( WINDOW_TEXT );
MoveTo( (npwindow->width-80)/ 2 , npwindow->height / 2 );
DrawText( text , 0 , strlen(text) );
free(text);
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;
status = p_plugin->init(argc, argn, argv);
if( NPERR_NO_ERROR == status ) {
instance->pdata = reinterpret_cast<void*>(p_plugin);
}
{
#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 );
}
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);
/* 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;
/* change/set parent */
libvlc_video_set_parent(p_vlc, drawable, NULL);
}
#if !USE_LIBVLC
p_plugin->pf_wndproc = (WNDPROC)SetWindowLong( (HWND)window->window,
GWL_WNDPROC, (LONG)Manage );
#endif /* !USE_LIBVLC */
/* remember window details */
p_plugin->setWindow(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 );
/* 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 */
p_plugin->i_width = window->width;
p_plugin->i_height = window->height;
p_plugin->p_npwin = 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 );
if( window && window->window )
{
Window win = (Window) window->window;
Display *p_display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
XResizeWindow( p_display, win, window->width, window->height );
Widget w = XtWindowToWidget( p_display, window );
XtAddEventHandler( w, ExposureMask, FALSE, (XtEventHandler)Redraw, p_plugin );
XtAddEventHandler( w, StructureNotifyMask, FALSE, (XtEventHandler)Resize, p_plugin );
/* remember window */
p_plugin->setWindow(window);
Redraw( w, (XtPointer)p_plugin, NULL );
}
#endif /* XP_UNIX */
if( !p_plugin->b_stream )
{
int i_mode = PLAYLIST_APPEND;
if( p_plugin->psz_target )
{
if( VLC_SUCCESS == libvlc_playlist_add( p_vlc, p_plugin->psz_target, NULL, NULL ) )
{
if( p_plugin->b_autoplay )
{
i_mode |= PLAYLIST_GO;
libvlc_playlist_play(p_vlc, 0, 0, NULL, NULL);
}
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;
}
}
}
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,
......
......@@ -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 )
......
......@@ -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 );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment