Commit a4c5031a authored by Cheng Sun's avatar Cheng Sun Committed by Jean-Baptiste Kempf

Moved most platform-specific stuff out of vlcplugin.cpp.

VlcPluginBase is a new abstract class from which platform-specific child
classes will inherit.
Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent e8156c27
/*****************************************************************************
* vlcplugin.h: a VLC plugin for Mozilla
*****************************************************************************
* Copyright (C) 2002-2009 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Damien Fouilleul <damienf@videolan.org>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*******************************************************************************
* Instance state information about the plugin.
******************************************************************************/
#ifndef __VLCPLUGIN_H__
#define __VLCPLUGIN_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <vlc/vlc.h>
// Setup XP_MACOSX, XP_UNIX, XP_WIN
#if defined(_WIN32)
#define XP_WIN 1
#elif defined(__APPLE__)
#define XP_MACOSX 1
#else
#define XP_UNIX 1
#define MOZ_X11 1
#endif
#if !defined(XP_MACOSX) && !defined(XP_UNIX) && !defined(XP_WIN)
#define XP_UNIX 1
#elif defined(XP_MACOSX)
#undef XP_UNIX
#endif
#ifdef XP_WIN
/* Windows stuff */
# include <windows.h>
# include <winbase.h>
#endif
#ifdef XP_MACOSX
/* Mac OS X stuff */
# include <Quickdraw.h>
#endif
#ifdef XP_UNIX
# include <pthread.h>
/* X11 stuff */
# include <X11/Xlib.h>
# include <X11/Intrinsic.h>
# include <X11/StringDefs.h>
# include <X11/X.h>
# ifndef __APPLE__
# include <X11/xpm.h>
# endif
#endif
#ifndef __MAX
# define __MAX(a, b) ( ((a) > (b)) ? (a) : (b) )
#endif
#ifndef __MIN
# define __MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
//on windows, to avoid including <npapi.h>
//from Microsoft SDK (rather then from Mozilla SDK),
//#include it indirectly via <npfunctions.h>
#include <npfunctions.h>
#include <vector>
#include <assert.h>
#include "control/nporuntime.h"
#if (((NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR) < 20)
typedef uint16 NPuint16_t;
typedef int16 NPint16_t;
typedef int32 NPint32_t;
#else
typedef uint16_t NPuint16_t;
typedef int16_t NPint16_t;
typedef int32_t NPint32_t;
#endif
#include "vlcplugin_base.h"
typedef struct {
#if defined(XP_UNIX)
pthread_mutex_t mutex;
# if defined(USE_GTK)
# include "vlcplugin_gtk.h"
typedef VlcPluginGtk VlcPlugin;
# else
# include "vlcplugin_xlib.h"
typedef VlcPluginXlib VlcPlugin;
# endif
#elif defined(XP_WIN)
CRITICAL_SECTION cs;
#else
#warning "locking not implemented in this platform"
# include "vlcplugin_win.h"
typedef VlcPluginWin VlcPlugin;
#elif defined(XP_MAC)
# include "vlcplugin_mac.h"
typedef VlcPluginMac VlcPlugin;
#endif
} plugin_lock_t;
typedef enum vlc_toolbar_clicked_e {
clicked_Unknown = 0,
clicked_Play,
clicked_Pause,
clicked_Stop,
clicked_timeline,
clicked_Time,
clicked_Fullscreen,
clicked_Mute,
clicked_Unmute
} vlc_toolbar_clicked_t;
typedef struct {
const char *name; /* event name */
const libvlc_event_type_t libvlc_type; /* libvlc event type */
libvlc_callback_t libvlc_callback; /* libvlc callback function */
} vlcplugin_event_t;
class EventObj
{
private:
class Listener
{
public:
Listener(vlcplugin_event_t *event, NPObject *p_object, bool b_bubble):
_event(event), _listener(p_object), _bubble(b_bubble)
{
assert(event);
assert(p_object);
}
Listener(): _event(NULL), _listener(NULL), _bubble(false) { }
~Listener()
{
}
const libvlc_event_type_t event_type() const { return _event->libvlc_type; }
NPObject *listener() const { return _listener; }
bool bubble() const { return _bubble; }
private:
vlcplugin_event_t *_event;
NPObject *_listener;
bool _bubble;
};
class VLCEvent
{
public:
VLCEvent(libvlc_event_type_t libvlc_event_type, NPVariant *npparams, uint32_t npcount):
_libvlc_event_type(libvlc_event_type), _npparams(npparams), _npcount(npcount)
{
}
VLCEvent(): _libvlc_event_type(0), _npparams(NULL), _npcount(0) { }
~VLCEvent()
{
}
const libvlc_event_type_t event_type() { return _libvlc_event_type; }
NPVariant *params() const { return _npparams; }
const uint32_t count() { return _npcount; }
private:
libvlc_event_type_t _libvlc_event_type;
NPVariant *_npparams;
uint32_t _npcount;
};
libvlc_event_manager_t *_em; /* libvlc media_player event manager */
public:
EventObj(): _em(NULL) { /* deferred to init() */ }
bool init();
~EventObj();
void deliver(NPP browser);
void callback(const libvlc_event_t *event, NPVariant *npparams, uint32_t count);
bool insert(const NPString &name, NPObject *listener, bool bubble);
bool remove(const NPString &name, NPObject *listener, bool bubble);
void unhook_manager(void *);
void hook_manager(libvlc_event_manager_t *, void *);
private:
vlcplugin_event_t *find_event(const char *s) const;
const char *find_name(const libvlc_event_t *event);
typedef std::vector<Listener> lr_l;
typedef std::vector<VLCEvent> ev_l;
lr_l _llist; /* list of registered listeners with 'addEventListener' method */
ev_l _elist; /* scheduled events list for delivery to browser */
plugin_lock_t lock;
};
#ifdef XP_WIN
HMODULE DllGetModule();
#include "../common/win32_fullscreen.h"
#endif
class VlcPlugin
{
public:
VlcPlugin( NPP, NPuint16_t );
virtual ~VlcPlugin();
NPError init(int argc, char* const argn[], char* const argv[]);
libvlc_instance_t* getVLC()
{ return libvlc_instance; };
libvlc_media_player_t* getMD()
{
if( !libvlc_media_player )
{
libvlc_printerr("no mediaplayer");
}
return libvlc_media_player;
}
NPP getBrowser()
{ return p_browser; };
char* getAbsoluteURL(const char *url);
NPWindow& getWindow()
{ return npwindow; };
void setWindow(const NPWindow &window);
NPClass* getScriptClass()
{ return p_scriptClass; };
#if defined(XP_WIN)
WNDPROC getWindowProc()
{ return pf_wndproc; };
void setWindowProc(WNDPROC wndproc)
{ pf_wndproc = wndproc; };
#endif
#if defined(XP_UNIX)
int setSize(unsigned width, unsigned height);
Window getVideoWindow()
{ return npvideo; };
void setVideoWindow(Window window)
{ npvideo = window; };
Window getControlWindow()
{ return npcontrol; };
void setControlWindow(Window window)
{ npcontrol = window; };
void showToolbar();
void hideToolbar();
void redrawToolbar();
void getToolbarSize(unsigned int *width, unsigned int *height)
{ *width = i_tb_width; *height = i_tb_height; };
int setToolbarSize(unsigned int width, unsigned int height)
{ i_tb_width = width; i_tb_height = height; return 1; };
vlc_toolbar_clicked_t getToolbarButtonClicked( int i_xpos, int i_ypos );
#endif
NPuint16_t i_npmode; /* either NP_EMBED or NP_FULL */
/* plugin properties */
int b_stream;
int b_autoplay;
int b_toolbar;
char * psz_text;
char * psz_target;
void playlist_play()
{
if( playlist_isplaying() )
playlist_stop();
if( libvlc_media_player||playlist_select(0) )
libvlc_media_player_play(libvlc_media_player);
}
void playlist_play_item(int idx)
{
if( playlist_select(idx) )
libvlc_media_player_play(libvlc_media_player);
}
void playlist_stop()
{
if( libvlc_media_player )
libvlc_media_player_stop(libvlc_media_player);
}
void playlist_next()
{
if( playlist_select(playlist_index+1) )
libvlc_media_player_play(libvlc_media_player);
}
void playlist_prev()
{
if( playlist_select(playlist_index-1) )
libvlc_media_player_play(libvlc_media_player);
}
void playlist_pause()
{
if( libvlc_media_player )
libvlc_media_player_pause(libvlc_media_player);
}
int playlist_isplaying()
{
int is_playing = 0;
if( libvlc_media_player )
is_playing = libvlc_media_player_is_playing(
libvlc_media_player );
return is_playing;
}
int playlist_add( const char * );
int playlist_add_extended_untrusted( const char *, const char *, int,
const char ** );
int playlist_delete_item( int );
void playlist_clear();
int playlist_count();
void toggle_fullscreen();
void set_fullscreen( int );
int get_fullscreen();
bool player_has_vout();
static bool canUseEventListener();
EventObj events;
static void event_callback(const libvlc_event_t *, NPVariant *, uint32_t, void *);
private:
bool playlist_select(int);
void set_player_window();
/* VLC reference */
int playlist_index;
libvlc_instance_t *libvlc_instance;
libvlc_media_list_t *libvlc_media_list;
libvlc_media_player_t *libvlc_media_player;
NPClass *p_scriptClass;
/* browser reference */
NPP p_browser;
char* psz_baseURL;
/* display settings */
NPWindow npwindow;
#if defined(XP_WIN)
WNDPROC pf_wndproc;
VLCWindowsManager _WindowsManager;
#endif
#if defined(XP_UNIX)
unsigned int i_width, i_height;
unsigned int i_tb_width, i_tb_height;
Window npvideo, npcontrol;
XImage *p_btnPlay;
XImage *p_btnPause;
XImage *p_btnStop;
XImage *p_timeline;
XImage *p_btnTime;
XImage *p_btnFullscreen;
XImage *p_btnMute;
XImage *p_btnUnmute;
int i_last_position;
#endif
static void eventAsync(void *);
};
/*******************************************************************************
* Plugin properties.
******************************************************************************/
#define PLUGIN_NAME "VLC Web Plugin"
#define PLUGIN_DESCRIPTION \
"Version %s, copyright 1996-2011 VideoLAN and Authors" \
"<br /><a href=\"http://www.videolan.org/vlc/\">http://www.videolan.org/vlc/</a>"
#endif
#endif /* __VLCPLUGIN_H__ */
......@@ -34,7 +34,7 @@
#include "control/npolibvlc.h"
#include <ctype.h>
#include <cctype>
#if defined(XP_UNIX)
# include <pthread.h>
......@@ -45,51 +45,10 @@
#warning "locking not implemented for this platform"
#endif
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#if defined(XP_UNIX)
#include "../share/pixmaps/x11/fullscreen.xpm"
#include "../share/pixmaps/x11/pause.xpm"
#include "../share/pixmaps/x11/play.xpm"
#include "../share/pixmaps/x11/stop.xpm"
#include "../share/pixmaps/x11/time_icon.xpm"
#include "../share/pixmaps/x11/time_line.xpm"
#include "../share/pixmaps/x11/volume_max.xpm"
#include "../share/pixmaps/x11/volume_mute.xpm"
//#include "../share/pixmaps/x11/skip_next.xpm"
//#include "../share/pixmaps/x11/skip_previous.xpm"
//#include "../share/pixmaps/x11/volume_knob.xpm"
//#include "../share/pixmaps/x11/volume_slider_bar.xpm"
#endif
#ifdef XP_WIN
#include "../common/win32_fullscreen.h"
static HMODULE hDllModule= 0;
HMODULE DllGetModule()
{
return hDllModule;
};
extern "C"
BOOL WINAPI DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved )
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
hDllModule = (HMODULE)hModule;
break;
default:
break;
}
return TRUE;
};
#endif
#include <cstdio>
#include <cassert>
#include <cstdlib>
#include <cstring>
/*****************************************************************************
* utilitiy functions
......@@ -174,7 +133,7 @@ static vlcplugin_event_t vlcevents[] = {
static void handle_input_event(const libvlc_event_t* event, void *param)
{
VlcPlugin *plugin = (VlcPlugin*)param;
VlcPluginBase *plugin = (VlcPluginBase*)param;
switch( event->type )
{
case libvlc_MediaPlayerNothingSpecial:
......@@ -186,7 +145,7 @@ static void handle_input_event(const libvlc_event_t* event, void *param)
case libvlc_MediaPlayerBackward:
case libvlc_MediaPlayerEndReached:
case libvlc_MediaPlayerEncounteredError:
plugin->event_callback(event, NULL, 0, param);
plugin->event_callback(event, NULL, 0);
break;
default: /* ignore all other libvlc_event_type_t */
break;
......@@ -198,7 +157,7 @@ static void handle_changed_event(const libvlc_event_t* event, void *param)
uint32_t npcount = 1;
NPVariant *npparam = (NPVariant *) NPN_MemAlloc( sizeof(NPVariant) * npcount );
VlcPlugin *plugin = (VlcPlugin*)param;
VlcPluginBase *plugin = (VlcPluginBase*)param;
switch( event->type )
{
#ifdef LIBVLC120
......@@ -228,7 +187,7 @@ static void handle_changed_event(const libvlc_event_t* event, void *param)
NPN_MemFree( npparam );
return;
}
plugin->event_callback(event, npparam, npcount, param);
plugin->event_callback(event, npparam, npcount);
}
bool EventObj::init()
......@@ -380,9 +339,9 @@ void EventObj::unhook_manager( void *userdata )
}
/*****************************************************************************
* VlcPlugin constructor and destructor
* VlcPluginBase constructor and destructor
*****************************************************************************/
VlcPlugin::VlcPlugin( NPP instance, NPuint16_t mode ) :
VlcPluginBase::VlcPluginBase( NPP instance, NPuint16_t mode ) :
i_npmode(mode),
b_stream(0),
b_autoplay(1),
......@@ -396,31 +355,8 @@ VlcPlugin::VlcPlugin( NPP instance, NPuint16_t mode ) :
p_scriptClass(NULL),
p_browser(instance),
psz_baseURL(NULL)
#if defined(XP_WIN)
,pf_wndproc(NULL)
,_WindowsManager(DllGetModule())
#endif
#if defined(XP_UNIX)
,i_width((unsigned)-1)
,i_height((unsigned)-1)
,i_tb_width(0)
,i_tb_height(0)
,i_last_position(0)
,p_btnPlay(NULL)
,p_btnPause(NULL)
,p_btnStop(NULL)
,p_btnMute(NULL)
,p_btnUnmute(NULL)
,p_btnFullscreen(NULL)
,p_btnTime(NULL)
,p_timeline(NULL)
#endif
{
memset(&npwindow, 0, sizeof(NPWindow));
#if defined(XP_UNIX)
memset(&npvideo, 0, sizeof(Window));
memset(&npcontrol, 0, sizeof(Window));
#endif
}
static bool boolValue(const char *value) {
......@@ -429,19 +365,19 @@ static bool boolValue(const char *value) {
!strcasecmp(value, "yes") );
}
void VlcPlugin::eventAsync(void *param)
void VlcPluginBase::eventAsync(void *param)
{
VlcPlugin *plugin = (VlcPlugin*)param;
VlcPluginBase *plugin = (VlcPluginBase*)param;
plugin->events.deliver(plugin->getBrowser());
plugin->update_controls();
}
void VlcPlugin::event_callback(const libvlc_event_t* event,
NPVariant *npparams, uint32_t npcount, void *userdata)
void VlcPluginBase::event_callback(const libvlc_event_t* event,
NPVariant *npparams, uint32_t npcount)
{
VlcPlugin *plugin = (VlcPlugin*)userdata;
#if defined(XP_UNIX)
plugin->events.callback(event, npparams, npcount);
NPN_PluginThreadAsyncCall(plugin->getBrowser(), eventAsync, plugin);
#ifdef XP_UNIX
events.callback(event, npparams, npcount);
NPN_PluginThreadAsyncCall(getBrowser(), eventAsync, this);
#else
#ifdef _MSC_VER
#pragma message("NPN_PluginThreadAsyncCall not implemented yet.")
......@@ -452,7 +388,7 @@ void VlcPlugin::event_callback(const libvlc_event_t* event,
#endif
}
NPError VlcPlugin::init(int argc, char* const argn[], char* const argv[])
NPError VlcPluginBase::init(int argc, char* const argn[], char* const argv[])
{
/* prepare VLC command line */
const char *ppsz_argv[32];
......@@ -558,11 +494,7 @@ NPError VlcPlugin::init(int argc, char* const argn[], char* const argv[])
}
else if( !strcmp( argn[i], "toolbar" ) )
{
/* FIXME: Remove this when toolbar functionality has been implemented on
* MacOS X and Win32 for Firefox/Mozilla/Safari. */
#ifdef XP_UNIX
b_toolbar = boolValue(argv[i]);
#endif
}
}
......@@ -625,12 +557,8 @@ NPError VlcPlugin::init(int argc, char* const argn[], char* const argv[])
return NPERR_NO_ERROR;
}
VlcPlugin::~VlcPlugin()
VlcPluginBase::~VlcPluginBase()
{
#ifdef XP_WIN
_WindowsManager.DestroyWindows();
#endif
free(psz_baseURL);
free(psz_target);
free(psz_text);
......@@ -648,32 +576,15 @@ VlcPlugin::~VlcPlugin()
libvlc_release( libvlc_instance );
}
void VlcPlugin::setWindow(const NPWindow &window)
void VlcPluginBase::setWindow(const NPWindow &window)
{
npwindow = window;
#ifdef XP_WIN
_WindowsManager.CreateWindows((HWND)(getWindow().window));
#endif
};
/*****************************************************************************
* VlcPlugin playlist replacement methods
* VlcPluginBase playlist replacement methods
*****************************************************************************/
void VlcPlugin::set_player_window()
{
#ifdef XP_UNIX
libvlc_media_player_set_xwindow(libvlc_media_player,
(uint32_t)getVideoWindow());
#endif
#ifdef XP_MACOSX
// XXX FIXME insert appropriate call here
#endif
#ifdef XP_WIN
_WindowsManager.LibVlcAttach(libvlc_media_player);
#endif
}
int VlcPlugin::playlist_add( const char *mrl )
int VlcPluginBase::playlist_add( const char *mrl )
{
int item = -1;
libvlc_media_t *p_m = libvlc_media_new_location(libvlc_instance,mrl);
......@@ -690,7 +601,7 @@ int VlcPlugin::playlist_add( const char *mrl )
return item;
}
int VlcPlugin::playlist_add_extended_untrusted( const char *mrl, const char *name,
int VlcPluginBase::playlist_add_extended_untrusted( const char *mrl, const char *name,
int optc, const char **optv )
{
libvlc_media_t *p_m;
......@@ -714,7 +625,7 @@ int VlcPlugin::playlist_add_extended_untrusted( const char *mrl, const char *nam
return item;
}
bool VlcPlugin::playlist_select( int idx )
bool VlcPluginBase::playlist_select( int idx )
{
libvlc_media_t *p_m = NULL;
......@@ -761,7 +672,7 @@ bad_unlock:
return false;
}
int VlcPlugin::playlist_delete_item( int idx )
int VlcPluginBase::playlist_delete_item( int idx )
{
if( !libvlc_media_list )
return -1;
......@@ -771,14 +682,14 @@ int VlcPlugin::playlist_delete_item( int idx )
return ret;
}
void VlcPlugin::playlist_clear()
void VlcPluginBase::playlist_clear()
{
if( libvlc_media_list )
libvlc_media_list_release(libvlc_media_list);
libvlc_media_list = libvlc_media_list_new(getVLC());
}
int VlcPlugin::playlist_count()
int VlcPluginBase::playlist_count()
{
int items_count = 0;
if( !libvlc_media_list )
......@@ -789,52 +700,8 @@ int VlcPlugin::playlist_count()
return items_count;
}
void VlcPlugin::toggle_fullscreen()
{
#ifdef XP_WIN
if(!get_fullscreen()){//now in windowed mode
set_fullscreen(true);
}
else if(get_fullscreen()){//now in fullscreen mode
set_fullscreen(false);
}
else {
//and what it meen?
}
#else
if( playlist_isplaying() )
libvlc_toggle_fullscreen(libvlc_media_player);
#endif
}
void VlcPlugin::set_fullscreen( int yes )
{
#ifdef XP_WIN
if(yes){
_WindowsManager.StartFullScreen();
}
else{
_WindowsManager.EndFullScreen();
}
#else
if( playlist_isplaying() )
libvlc_set_fullscreen(libvlc_media_player,yes);
#endif
}
int VlcPlugin::get_fullscreen()
{
#ifdef XP_WIN
return _WindowsManager.IsFullScreen();
#else
int r = 0;
if( playlist_isplaying() )
r = libvlc_get_fullscreen(libvlc_media_player);
return r;
#endif
}
bool VlcPlugin::player_has_vout()
bool VlcPluginBase::player_has_vout()
{
bool r = false;
if( playlist_isplaying() )
......@@ -843,10 +710,10 @@ bool VlcPlugin::player_has_vout()
}
/*****************************************************************************
* VlcPlugin methods
* VlcPluginBase methods
*****************************************************************************/
char *VlcPlugin::getAbsoluteURL(const char *url)
char *VlcPluginBase::getAbsoluteURL(const char *url)
{
if( NULL != url )
{
......@@ -1000,330 +867,78 @@ relativeurl:
return NULL;
}
#if defined(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;
}
#define BTN_SPACE ((unsigned int)4)
void VlcPlugin::showToolbar()
void VlcPluginBase::control_handler(vlc_toolbar_clicked_t clicked)
{
const NPWindow& window = getWindow();
Window control = getControlWindow();