mirror of
https://github.com/videolan/vlc.git
synced 2025-01-24 08:35:46 +08:00
* modules/control/corba/: Olivier Aubert's CORBA plugin. Almost verbatim,
compiles cleanly (to build the medicacontrol.so library you need to cd to that directory and "make medicacontrol.so") but untested. * src/playlist/playlist.c: Mostly harmless fix to playlist.c suggested by Olivier.
This commit is contained in:
parent
76bbfbacd9
commit
34f2374615
34
configure.ac
34
configure.ac
@ -1,5 +1,5 @@
|
||||
dnl Autoconf settings for vlc
|
||||
dnl $Id: configure.ac,v 1.26 2003/07/07 14:56:22 massiot Exp $
|
||||
dnl $Id: configure.ac,v 1.27 2003/07/07 16:59:00 sam Exp $
|
||||
|
||||
AC_INIT(vlc,0.6.0)
|
||||
|
||||
@ -2930,6 +2930,37 @@ then
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl corba (ORBit) plugin
|
||||
dnl
|
||||
AC_ARG_ENABLE(corba,
|
||||
[ --enable-corba corba interface support (default disabled)])
|
||||
if test "${enable_corba}" = "yes"; then
|
||||
ORBIT_PATH="${PATH}"
|
||||
AC_ARG_WITH(orbit-config-path,
|
||||
[ --with-orbit-config-path=PATH orbit-config path (default search in \$PATH)])
|
||||
if test "${with_orbit_config_path}" != "no"; then
|
||||
ORBIT_PATH="${with_orbit_config_path}:${PATH}"
|
||||
fi
|
||||
# look for orbit2-config
|
||||
AC_PATH_PROG(ORBIT_CONFIG, orbit2-config, no, ${ORBIT_PATH})
|
||||
if test "${ORBIT_CONFIG}" != "no"; then
|
||||
AX_ADD_CFLAGS(corba,[`${ORBIT_CONFIG} --cflags server`])
|
||||
AX_ADD_LDFLAGS(corba,[`${ORBIT_CONFIG} --libs server | sed 's,-rdynamic,,'`])
|
||||
# now look for the orbit.h header
|
||||
CPPFLAGS="${CPPFLAGS_save} ${CFLAGS_corba}"
|
||||
ac_cv_corba_headers=yes
|
||||
AC_CHECK_HEADERS(orbit/orbit.h, , [
|
||||
ac_cv_corba_headers=no
|
||||
AC_MSG_ERROR([Could not find corba development headers])
|
||||
])
|
||||
if test "${ac_cv_corba_headers}" = "yes"; then
|
||||
AX_ADD_PLUGINS(corba)
|
||||
fi
|
||||
CPPFLAGS="${CPPFLAGS_save}"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(,[Misc options:])
|
||||
|
||||
dnl
|
||||
@ -3237,6 +3268,7 @@ AC_OUTPUT([
|
||||
modules/codec/mpeg_video/motion/Makefile
|
||||
modules/codec/spudec/Makefile
|
||||
modules/control/Makefile
|
||||
modules/control/corba/Makefile
|
||||
modules/control/lirc/Makefile
|
||||
modules/control/rc/Makefile
|
||||
modules/demux/Makefile
|
||||
|
11
modules/control/corba/.cvsignore
Normal file
11
modules/control/corba/.cvsignore
Normal file
@ -0,0 +1,11 @@
|
||||
.deps
|
||||
.dirstamp
|
||||
*.lo
|
||||
*.la
|
||||
*.dll
|
||||
*.dylib
|
||||
*.sl
|
||||
*.so
|
||||
Makefile.am
|
||||
Makefile.in
|
||||
Makefile
|
25
modules/control/corba/Modules.am
Normal file
25
modules/control/corba/Modules.am
Normal file
@ -0,0 +1,25 @@
|
||||
## corba module declaration
|
||||
|
||||
SOURCES_corba = corba.c
|
||||
|
||||
nodist_SOURCES_corba = \
|
||||
mediacontrol-common.c \
|
||||
mediacontrol-skels.c \
|
||||
mediacontrol.h \
|
||||
$(NULL)
|
||||
|
||||
ORBITIDL = orbit-idl-2
|
||||
|
||||
mediacontrol-common.c mediacontrol-skels.c mediacontrol-stubs.c mediacontrol.h:
|
||||
$(ORBITIDL) --skeleton-impl mediacontrol.idl
|
||||
|
||||
mediacontrol-imodule.c:
|
||||
$(ORBITIDL) --imodule mediacontrol.idl
|
||||
|
||||
mediacontrol.so: mediacontrol-imodule.c
|
||||
gcc -fPIC -o mediacontrol-imodule.o -c mediacontrol-imodule.c `pkg-config --cflags ORBit-2.0`
|
||||
gcc -shared -o $@ mediacontrol-imodule.o `pkg-config --libs ORBit-2.0`
|
||||
|
||||
clean:
|
||||
rm -f mediacontrol-stubs.c mediacontrol-imodule.c mediacontrol-skelimpl.c
|
||||
|
64
modules/control/corba/README
Normal file
64
modules/control/corba/README
Normal file
@ -0,0 +1,64 @@
|
||||
$Id: README,v 1.1 2003/07/07 16:59:00 sam Exp $
|
||||
* Module (server) side
|
||||
** Dependencies
|
||||
|
||||
To compile the CORBA plugin, you need the orbit2 developpement files
|
||||
(for Debian, install the package liborbi2-dev)
|
||||
|
||||
** How to run it ?
|
||||
|
||||
You run the CORBA module with the following command line :
|
||||
|
||||
vlc --intf corba
|
||||
|
||||
The CORBA module is initialized and saves its IOR into the file
|
||||
/tmp/vlc-ior.ref
|
||||
|
||||
|
||||
* Client side
|
||||
|
||||
A sample client application is provided, using python-orbit
|
||||
|
||||
** Dependencies
|
||||
|
||||
The python client uses the pyorbit library developped by James
|
||||
Henstridge <james at daa dot com dot au> (source:
|
||||
http://ftp.gnome.org/pub/GNOME/sources/pyorbit/1.99/pyorbit-1.99.3.tar.gz).
|
||||
|
||||
To interoperate with gtk, the original pyorbit-1.99.3 needs a patch to
|
||||
implement the bindings to OR_work_pending and ORB_perform_work (see
|
||||
pyorbit-1.99.3.patch)
|
||||
|
||||
The gtk simpleplayer example uses the python-glade module by James
|
||||
Henstridge.
|
||||
|
||||
** Typelib information
|
||||
|
||||
To simply access the server, you do not need any reference to the IDL
|
||||
(CORBA2.0 provides introspection facilities). However, if you want to
|
||||
use the structures defined in the IDL (Position, Origin, ...), you
|
||||
need to use the IDL information, and compile a dynamic lib
|
||||
(MediaControl.so) from the IDL.
|
||||
|
||||
To build the library, you can use the Makefile :
|
||||
|
||||
make corba-generate-typelib
|
||||
|
||||
which will generate MediaControl.so
|
||||
|
||||
* Interesting pointers
|
||||
|
||||
- GLib reference manual
|
||||
http://developer.gnome.org/doc/API/glib/
|
||||
|
||||
- IDL quickref :
|
||||
http://www.cs.rpi.edu/~musser/dsc/idl/idl-overview.html
|
||||
|
||||
- Python-Bonobo
|
||||
http://www.pycage.de/howto_bonobo.html
|
||||
|
||||
* How to add the module to the original sources (vlc-0.5.x) :
|
||||
- copy the directory modules/control/corba
|
||||
- add configuration lines relative to corba in configure.ac.in
|
||||
- add a reference to control/corba/Modules.am in
|
||||
modules/Makefile.am
|
34
modules/control/corba/client.py
Normal file
34
modules/control/corba/client.py
Normal file
@ -0,0 +1,34 @@
|
||||
#! /usr/bin/python
|
||||
|
||||
# Simple CLI client for the corba module of vlc. Depends on pyorbit.
|
||||
# Best used with IPython (completion, ...)
|
||||
|
||||
import sys
|
||||
import ORBit, CORBA
|
||||
|
||||
def quit ():
|
||||
try:
|
||||
mc.exit()
|
||||
except:
|
||||
pass
|
||||
|
||||
print "Chargement de l'IDL"
|
||||
ORBit.load_typelib ("./MediaControl.so")
|
||||
import VLC
|
||||
|
||||
if len(sys.argv) < 1:
|
||||
print "Usage: %s" % sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
print "Initialisation de l'ORB"
|
||||
orb = CORBA.ORB_init()
|
||||
|
||||
ior = open("/tmp/vlc-ior.ref").readline()
|
||||
mc = orb.string_to_object(ior)
|
||||
|
||||
print "Objet mc %s" % mc
|
||||
|
||||
pos = mc.get_media_position (0,0)
|
||||
print "pos = mc.get_media_position (0,0)"
|
||||
print pos
|
||||
|
861
modules/control/corba/corba.c
Normal file
861
modules/control/corba/corba.c
Normal file
@ -0,0 +1,861 @@
|
||||
/*****************************************************************************
|
||||
* corba.c : CORBA (ORBit) remote control plugin for vlc
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2001 VideoLAN
|
||||
* $Id: corba.c,v 1.1 2003/07/07 16:59:00 sam Exp $
|
||||
*
|
||||
* Authors: Olivier Aubert <oaubert at lisi dot univ-lyon1 dot fr>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Preamble
|
||||
*****************************************************************************/
|
||||
/* For CORBA */
|
||||
#include "mediacontrol.h"
|
||||
#include "orbit/poa/portableserver-poa-type.h"
|
||||
#define VLC_IOR_FILE "/tmp/vlc-ior.ref"
|
||||
|
||||
#define handle_exception(m) if(ev->_major != CORBA_NO_EXCEPTION) \
|
||||
{ \
|
||||
msg_Err (servant->p_intf, m); \
|
||||
return; \
|
||||
}
|
||||
|
||||
|
||||
#define handle_exception_no_servant(p,m) if(ev->_major != CORBA_NO_EXCEPTION) \
|
||||
{ \
|
||||
msg_Err (p, m); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#include <vlc/vlc.h>
|
||||
#include <vlc/intf.h>
|
||||
#include <vlc/vout.h>
|
||||
#include <vlc/aout.h>
|
||||
|
||||
#include <stdlib.h> /* malloc(), free() */
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h> /* ENOMEM */
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* intf_sys_t: description and status of corba interface
|
||||
*****************************************************************************/
|
||||
struct intf_sys_t
|
||||
{
|
||||
CORBA_ORB orb;
|
||||
VLC_MediaControl mc;
|
||||
PortableServer_POA root_poa;
|
||||
PortableServer_POAManager root_poa_manager;
|
||||
GMainLoop* corbaloop;
|
||||
|
||||
vlc_bool_t b_playing;
|
||||
|
||||
input_thread_t * p_input; /* The input thread */
|
||||
|
||||
msg_subscription_t* p_sub; /* message bank subscription */
|
||||
};
|
||||
|
||||
/* Convert an offset into seconds. Taken from input_ext-intf.c.
|
||||
The 50 hardcoded constant comes from the definition of i_mux_rate :
|
||||
i_mux_rate : the rate we read the stream (in units of 50 bytes/s) ;
|
||||
0 if undef */
|
||||
long long offsetToSeconds (input_thread_t *p_input, off_t l_offset)
|
||||
{
|
||||
long long l_res;
|
||||
|
||||
l_res = -1;
|
||||
if (p_input != NULL && p_input->stream.i_mux_rate != 0)
|
||||
{
|
||||
l_res = (long long) l_offset / 50 / p_input->stream.i_mux_rate;
|
||||
}
|
||||
return l_res;
|
||||
}
|
||||
|
||||
/* Convert an offset into milliseconds */
|
||||
long long offsetToMilliseconds (input_thread_t *p_input, off_t l_offset)
|
||||
{
|
||||
long long l_res;
|
||||
|
||||
l_res = -1;
|
||||
if (p_input != NULL && p_input->stream.i_mux_rate != 0)
|
||||
{
|
||||
l_res = (long long) 1000 * l_offset / 50 / p_input->stream.i_mux_rate;
|
||||
}
|
||||
return l_res;
|
||||
}
|
||||
|
||||
/* Convert seconds to an offset */
|
||||
off_t secondsToOffset (input_thread_t *p_input, long long l_seconds)
|
||||
{
|
||||
off_t l_res;
|
||||
|
||||
l_res = -1;
|
||||
|
||||
if (p_input != NULL)
|
||||
{
|
||||
l_res = (off_t) l_seconds * 50 * p_input->stream.i_mux_rate;
|
||||
}
|
||||
return l_res;
|
||||
}
|
||||
|
||||
|
||||
/* Convert milliseconds to an offset */
|
||||
off_t millisecondsToOffset (input_thread_t *p_input, long long l_milliseconds)
|
||||
{
|
||||
off_t l_res;
|
||||
|
||||
l_res = -1;
|
||||
if (p_input != NULL)
|
||||
{
|
||||
l_res = (off_t) l_milliseconds * 50 * p_input->stream.i_mux_rate / 1000;
|
||||
}
|
||||
return l_res;
|
||||
}
|
||||
|
||||
/* Returns the current offset. */
|
||||
off_t currentOffset (input_thread_t *p_input)
|
||||
{
|
||||
off_t l_offset;
|
||||
|
||||
if( p_input == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* offset contient la valeur en unités arbitraires (cf
|
||||
include/input_ext-intf.h) */
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
|
||||
#define A p_input->stream.p_selected_area
|
||||
l_offset = A->i_tell + A->i_start;
|
||||
#undef A
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
|
||||
return l_offset;
|
||||
}
|
||||
|
||||
/*** App-specific servant structures ***/
|
||||
|
||||
/* We can add attributes to this structure, which is both a pointer on a
|
||||
specific structure, and on a POA_VLC_MediaControl (servant). Cf
|
||||
http://developer.gnome.org/doc/guides/corba/html/corba-poa-example.html */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
POA_VLC_MediaControl servant;
|
||||
PortableServer_POA poa;
|
||||
/* Ajouter ici les attributs utiles */
|
||||
intf_thread_t *p_intf;
|
||||
}
|
||||
impl_POA_VLC_MediaControl;
|
||||
|
||||
/* Beginning of the CORBA code generated in Mediacontrol-skelimpl.c */
|
||||
/* BEGIN INSERT */
|
||||
|
||||
/*** Implementation stub prototypes ***/
|
||||
|
||||
static void impl_VLC_MediaControl__destroy(impl_POA_VLC_MediaControl *
|
||||
servant, CORBA_Environment * ev);
|
||||
|
||||
static VLC_Position
|
||||
impl_VLC_MediaControl_get_media_position(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_PositionOrigin an_origin,
|
||||
const VLC_PositionKey a_key,
|
||||
CORBA_Environment * ev);
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_set_media_position(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position,
|
||||
CORBA_Environment * ev);
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_start(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position,
|
||||
CORBA_Environment * ev);
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_pause(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position,
|
||||
CORBA_Environment * ev);
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_resume(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position,
|
||||
CORBA_Environment * ev);
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_stop(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position,
|
||||
CORBA_Environment * ev);
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_exit(impl_POA_VLC_MediaControl * servant,
|
||||
CORBA_Environment * ev);
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_add_to_playlist(impl_POA_VLC_MediaControl * servant,
|
||||
const CORBA_char * a_file,
|
||||
CORBA_Environment * ev);
|
||||
|
||||
static VLC_PlaylistSeq
|
||||
*impl_VLC_MediaControl_get_playlist(impl_POA_VLC_MediaControl * servant,
|
||||
CORBA_Environment * ev);
|
||||
|
||||
/*** epv structures ***/
|
||||
|
||||
static PortableServer_ServantBase__epv impl_VLC_MediaControl_base_epv = {
|
||||
NULL, /* _private data */
|
||||
NULL, /* finalize routine */
|
||||
NULL, /* default_POA routine */
|
||||
};
|
||||
static POA_VLC_MediaControl__epv impl_VLC_MediaControl_epv = {
|
||||
NULL, /* _private */
|
||||
|
||||
(gpointer) & impl_VLC_MediaControl_get_media_position,
|
||||
|
||||
(gpointer) & impl_VLC_MediaControl_set_media_position,
|
||||
|
||||
(gpointer) & impl_VLC_MediaControl_start,
|
||||
|
||||
(gpointer) & impl_VLC_MediaControl_pause,
|
||||
|
||||
(gpointer) & impl_VLC_MediaControl_resume,
|
||||
|
||||
(gpointer) & impl_VLC_MediaControl_stop,
|
||||
|
||||
(gpointer) & impl_VLC_MediaControl_exit,
|
||||
|
||||
(gpointer) & impl_VLC_MediaControl_add_to_playlist,
|
||||
|
||||
(gpointer) & impl_VLC_MediaControl_get_playlist,
|
||||
|
||||
};
|
||||
|
||||
/*** vepv structures ***/
|
||||
|
||||
static POA_VLC_MediaControl__vepv impl_VLC_MediaControl_vepv = {
|
||||
&impl_VLC_MediaControl_base_epv,
|
||||
&impl_VLC_MediaControl_epv,
|
||||
};
|
||||
|
||||
/*** Stub implementations ***/
|
||||
|
||||
static VLC_MediaControl
|
||||
impl_VLC_MediaControl__create(PortableServer_POA poa, CORBA_Environment * ev)
|
||||
{
|
||||
VLC_MediaControl retval;
|
||||
impl_POA_VLC_MediaControl *newservant;
|
||||
PortableServer_ObjectId *objid;
|
||||
|
||||
newservant = g_new0(impl_POA_VLC_MediaControl, 1);
|
||||
newservant->servant.vepv = &impl_VLC_MediaControl_vepv;
|
||||
newservant->poa = poa;
|
||||
POA_VLC_MediaControl__init((PortableServer_Servant) newservant, ev);
|
||||
objid = PortableServer_POA_activate_object(poa, newservant, ev);
|
||||
CORBA_free(objid);
|
||||
retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl__destroy(impl_POA_VLC_MediaControl * servant,
|
||||
CORBA_Environment * ev)
|
||||
{
|
||||
PortableServer_ObjectId *objid;
|
||||
|
||||
objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
|
||||
PortableServer_POA_deactivate_object(servant->poa, objid, ev);
|
||||
CORBA_free(objid);
|
||||
|
||||
POA_VLC_MediaControl__fini((PortableServer_Servant) servant, ev);
|
||||
g_free(servant);
|
||||
}
|
||||
|
||||
/* END INSERT */
|
||||
/* Beginning of the CORBA functions that we define */
|
||||
|
||||
/* Returns the current position in the stream. The returned value can
|
||||
be relative or absolute (according to PositionOrigin) and the unit
|
||||
is set by PositionKey */
|
||||
static VLC_Position
|
||||
impl_VLC_MediaControl_get_media_position(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_PositionOrigin an_origin,
|
||||
const VLC_PositionKey a_key,
|
||||
CORBA_Environment * ev)
|
||||
{
|
||||
VLC_Position retval;
|
||||
off_t l_offset;
|
||||
VLC_PositionKeyNotSupported *exception;
|
||||
input_thread_t * p_input = servant->p_intf->p_sys->p_input;
|
||||
|
||||
/* msg_Warn (servant->p_intf, "Calling MediaControl::get_media_position"); */
|
||||
|
||||
retval.origin = an_origin;
|
||||
retval.key = a_key;
|
||||
|
||||
if ( an_origin == VLC_RelativePosition
|
||||
|| an_origin == VLC_ModuloPosition )
|
||||
{
|
||||
/* Relative or ModuloPosition make no sense */
|
||||
/* FIXME: should we return 0 or raise an exception ? */
|
||||
retval.value = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ( p_input == NULL )
|
||||
{
|
||||
/* FIXME: should we return 0 or raise an exception ? */
|
||||
retval.value = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* We are asked for an AbsolutePosition. */
|
||||
/* Cf plugins/gtk/gtk_display.c */
|
||||
|
||||
/* The lock is taken by the currentOffset function */
|
||||
l_offset = currentOffset (p_input);
|
||||
|
||||
if (a_key == VLC_ByteCount)
|
||||
{
|
||||
retval.value = l_offset;
|
||||
return retval;
|
||||
}
|
||||
if (a_key == VLC_MediaTime)
|
||||
{
|
||||
retval.value = offsetToSeconds (p_input, l_offset);
|
||||
return retval;
|
||||
}
|
||||
if (a_key == VLC_SampleCount)
|
||||
{
|
||||
/* Raising exceptions in C : cf the good explanations in
|
||||
http://developer.gnome.org/doc/guides/corba/html/corba-module-complete-helloworld.html
|
||||
*/
|
||||
exception = VLC_PositionKeyNotSupported__alloc ();
|
||||
memcpy (&exception->key, &a_key, sizeof (a_key));
|
||||
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
|
||||
ex_VLC_PositionKeyNotSupported,
|
||||
exception);
|
||||
retval.value = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* http://catb.org/~esr/jargon/html/entry/can't-happen.html */
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Sets the media position */
|
||||
static void
|
||||
impl_VLC_MediaControl_set_media_position(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position,
|
||||
CORBA_Environment * ev)
|
||||
{
|
||||
VLC_InvalidPosition *pe_exception;
|
||||
VLC_PositionKeyNotSupported *pe_key_exception;
|
||||
off_t l_offset_destination = 0;
|
||||
int i_whence = 0;
|
||||
input_thread_t * p_input = servant->p_intf->p_sys->p_input;
|
||||
|
||||
msg_Warn (servant->p_intf, "Calling MediaControl::set_media_position");
|
||||
|
||||
if( p_input == NULL )
|
||||
return;
|
||||
|
||||
if ( !p_input->stream.b_seekable )
|
||||
{
|
||||
pe_exception = VLC_InvalidPosition__alloc ();
|
||||
memcpy (&pe_exception->key, &a_position->key, sizeof (&a_position->key));
|
||||
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
|
||||
ex_VLC_InvalidPosition,
|
||||
pe_exception);
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( a_position->key )
|
||||
{
|
||||
case VLC_SampleCount:
|
||||
/* The SampleCount unit is still a bit mysterious... */
|
||||
pe_key_exception = VLC_PositionKeyNotSupported__alloc ();
|
||||
memcpy (&pe_key_exception->key, &a_position->key, sizeof (&a_position->key));
|
||||
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
|
||||
ex_VLC_PositionKeyNotSupported,
|
||||
pe_key_exception);
|
||||
return;
|
||||
break;
|
||||
case VLC_MediaTime:
|
||||
i_whence |= INPUT_SEEK_SECONDS;
|
||||
break;
|
||||
case VLC_ByteCount:
|
||||
i_whence |= INPUT_SEEK_BYTES;
|
||||
break;
|
||||
default:
|
||||
i_whence |= INPUT_SEEK_BYTES;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( a_position->origin)
|
||||
{
|
||||
case VLC_RelativePosition:
|
||||
i_whence |= INPUT_SEEK_CUR;
|
||||
break;
|
||||
case VLC_ModuloPosition:
|
||||
i_whence |= INPUT_SEEK_END;
|
||||
break;
|
||||
case VLC_AbsolutePosition:
|
||||
i_whence |= INPUT_SEEK_SET;
|
||||
break;
|
||||
default:
|
||||
i_whence |= INPUT_SEEK_SET;
|
||||
break;
|
||||
}
|
||||
|
||||
l_offset_destination = a_position->value;
|
||||
|
||||
/* msg_Warn (servant->p_intf, "Offset destination : %d", l_offset_destination); */
|
||||
/* Now we can set the position. The lock is taken in the input_Seek
|
||||
function (cf input_ext-intf.c) */
|
||||
input_Seek (p_input, l_offset_destination, i_whence);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Starts playing a stream */
|
||||
static void
|
||||
impl_VLC_MediaControl_start(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position, CORBA_Environment * ev)
|
||||
{
|
||||
intf_thread_t * p_intf = servant->p_intf;
|
||||
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
|
||||
FIND_ANYWHERE );
|
||||
|
||||
msg_Warn (servant->p_intf, "Calling MediaControl::start");
|
||||
|
||||
if( p_playlist == NULL )
|
||||
{
|
||||
/* FIXME: we should raise an appropriate exception, but we must
|
||||
define it in the IDL first */
|
||||
msg_Err (servant->p_intf, "Error: no playlist available.");
|
||||
return;
|
||||
}
|
||||
|
||||
vlc_mutex_lock( &p_playlist->object_lock );
|
||||
if( p_playlist->i_size )
|
||||
{
|
||||
vlc_mutex_unlock( &p_playlist->object_lock );
|
||||
playlist_Play( p_playlist );
|
||||
vlc_object_release( p_playlist );
|
||||
}
|
||||
else
|
||||
{
|
||||
vlc_mutex_unlock( &p_playlist->object_lock );
|
||||
vlc_object_release( p_playlist );
|
||||
msg_Err (servant->p_intf, "Error: playlist empty.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_pause(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position, CORBA_Environment * ev)
|
||||
{
|
||||
input_thread_t *p_input = servant->p_intf->p_sys->p_input;
|
||||
|
||||
msg_Warn (servant->p_intf, "Calling MediaControl::pause");
|
||||
|
||||
if( p_input != NULL )
|
||||
{
|
||||
input_SetStatus( p_input, INPUT_STATUS_PAUSE );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_resume(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position, CORBA_Environment * ev)
|
||||
{
|
||||
input_thread_t *p_input = servant->p_intf->p_sys->p_input;
|
||||
|
||||
msg_Warn (servant->p_intf, "Calling MediaControl::resume");
|
||||
|
||||
if( p_input != NULL )
|
||||
{
|
||||
input_SetStatus( p_input, INPUT_STATUS_PAUSE );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_stop(impl_POA_VLC_MediaControl * servant,
|
||||
const VLC_Position * a_position, CORBA_Environment * ev)
|
||||
{
|
||||
intf_thread_t * p_intf = servant->p_intf;
|
||||
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
|
||||
FIND_ANYWHERE );
|
||||
|
||||
msg_Warn (servant->p_intf, "Calling MediaControl::stop");
|
||||
|
||||
if( p_playlist != NULL )
|
||||
{
|
||||
playlist_Stop( p_playlist );
|
||||
vlc_object_release( p_playlist );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_exit(impl_POA_VLC_MediaControl * servant,
|
||||
CORBA_Environment * ev)
|
||||
{
|
||||
msg_Warn (servant->p_intf, "Calling MediaControl::exit");
|
||||
|
||||
vlc_mutex_lock( &servant->p_intf->change_lock );
|
||||
servant->p_intf->b_die = TRUE;
|
||||
vlc_mutex_unlock( &servant->p_intf->change_lock );
|
||||
}
|
||||
|
||||
static void
|
||||
impl_VLC_MediaControl_add_to_playlist(impl_POA_VLC_MediaControl * servant,
|
||||
const CORBA_char * psz_file,
|
||||
CORBA_Environment * ev)
|
||||
{
|
||||
intf_thread_t * p_intf = servant->p_intf;
|
||||
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
|
||||
FIND_ANYWHERE );
|
||||
|
||||
msg_Warn (servant->p_intf, "Calling MediaControl::add_to_playlist %s", psz_file);
|
||||
|
||||
if ( p_playlist == NULL )
|
||||
{
|
||||
msg_Err (servant->p_intf, "Error: no playlist defined");
|
||||
/* FIXME: should return an exception */
|
||||
return;
|
||||
}
|
||||
|
||||
playlist_Add (p_playlist, psz_file, PLAYLIST_REPLACE, 0);
|
||||
vlc_object_release( p_playlist );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static VLC_PlaylistSeq *
|
||||
impl_VLC_MediaControl_get_playlist(impl_POA_VLC_MediaControl * servant,
|
||||
CORBA_Environment * ev)
|
||||
{
|
||||
VLC_PlaylistSeq *retval;
|
||||
int i_index;
|
||||
intf_thread_t * p_intf = servant->p_intf;
|
||||
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
|
||||
FIND_ANYWHERE );
|
||||
int i_playlist_size;
|
||||
|
||||
msg_Warn (servant->p_intf, "Calling MediaControl::get_playlist");
|
||||
|
||||
vlc_mutex_lock( &p_playlist->object_lock );
|
||||
i_playlist_size = p_playlist->i_size;
|
||||
|
||||
retval = VLC_PlaylistSeq__alloc ();
|
||||
retval->_buffer = VLC_PlaylistSeq_allocbuf (i_playlist_size);
|
||||
retval->_length = i_playlist_size;
|
||||
|
||||
for (i_index = 0 ; i_index < i_playlist_size ; i_index++)
|
||||
{
|
||||
retval->_buffer[i_index] =
|
||||
CORBA_string_dup (p_playlist->pp_items[i_index]->psz_name);
|
||||
}
|
||||
vlc_mutex_unlock( &p_playlist->object_lock );
|
||||
vlc_object_release( p_playlist );
|
||||
|
||||
CORBA_sequence_set_release (retval, TRUE);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* (Real) end of the CORBA code generated in Mediacontrol-skelimpl.c */
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes.
|
||||
*****************************************************************************/
|
||||
static int Open ( vlc_object_t * );
|
||||
static void Close ( vlc_object_t * );
|
||||
static void Run ( intf_thread_t * );
|
||||
|
||||
/*****************************************************************************
|
||||
* Module descriptor
|
||||
*****************************************************************************/
|
||||
vlc_module_begin();
|
||||
add_category_hint( N_("Corba control"), NULL, VLC_FALSE );
|
||||
set_description( _("corba control module") );
|
||||
set_capability( "interface", 10 );
|
||||
set_callbacks( Open, Close );
|
||||
vlc_module_end();
|
||||
|
||||
/*****************************************************************************
|
||||
* intf_Open: initialize and create stuff
|
||||
*****************************************************************************/
|
||||
static int Open( vlc_object_t *p_this )
|
||||
{
|
||||
intf_thread_t *p_intf = (intf_thread_t *)p_this;
|
||||
|
||||
/* Allocate instance and initialize some members */
|
||||
p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
|
||||
if( p_intf->p_sys == NULL )
|
||||
{
|
||||
msg_Err( p_intf, "out of memory" );
|
||||
return VLC_ENOMEM;
|
||||
}
|
||||
|
||||
/* Initialize the fields of the p_intf struct */
|
||||
p_intf->pf_run = Run;
|
||||
p_intf->p_sys->b_playing = VLC_FALSE;
|
||||
p_intf->p_sys->p_input = NULL;
|
||||
|
||||
p_intf->p_sys->orb = NULL;
|
||||
p_intf->p_sys->mc = NULL;
|
||||
p_intf->p_sys->root_poa = NULL;
|
||||
p_intf->p_sys->root_poa_manager = NULL;
|
||||
p_intf->p_sys->corbaloop = NULL;
|
||||
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* intf_Close: destroy interface
|
||||
*****************************************************************************/
|
||||
static void Close( vlc_object_t *p_this )
|
||||
{
|
||||
intf_thread_t *p_intf = (intf_thread_t *)p_this;
|
||||
CORBA_Environment* ev = NULL;
|
||||
|
||||
ev = CORBA_exception__alloc ();
|
||||
CORBA_ORB_shutdown (p_intf->p_sys->orb, FALSE, ev);
|
||||
handle_exception_no_servant (p_intf, "Erreur dans Close");
|
||||
|
||||
if( p_intf->p_sys->p_input )
|
||||
{
|
||||
vlc_object_release( p_intf->p_sys->p_input );
|
||||
}
|
||||
|
||||
/* Destroy structure */
|
||||
free( p_intf->p_sys );
|
||||
}
|
||||
|
||||
/*
|
||||
Function called regularly to handle various tasks (mainly CORBA calls)
|
||||
*/
|
||||
static gboolean Manage (gpointer p_interface)
|
||||
{
|
||||
intf_thread_t *p_intf = (intf_thread_t*)p_interface;
|
||||
CORBA_boolean b_work_pending;
|
||||
CORBA_Environment* ev;
|
||||
|
||||
ev = CORBA_exception__alloc ();
|
||||
|
||||
/* CORBA */
|
||||
b_work_pending = CORBA_ORB_work_pending (p_intf->p_sys->orb, ev);
|
||||
if(ev->_major != CORBA_NO_EXCEPTION)
|
||||
{
|
||||
msg_Err (p_intf, "Exception dans la vérif d'événements CORBA");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
vlc_mutex_lock( &p_intf->change_lock );
|
||||
|
||||
/* Update the input */
|
||||
if( p_intf->p_sys->p_input == NULL )
|
||||
{
|
||||
p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
|
||||
FIND_ANYWHERE );
|
||||
}
|
||||
else if( p_intf->p_sys->p_input->b_dead )
|
||||
{
|
||||
vlc_object_release( p_intf->p_sys->p_input );
|
||||
p_intf->p_sys->p_input = NULL;
|
||||
}
|
||||
|
||||
if( p_intf->p_sys->p_input )
|
||||
{
|
||||
input_thread_t *p_input = p_intf->p_sys->p_input;
|
||||
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
|
||||
if ( !p_input->b_die )
|
||||
{
|
||||
/* New input or stream map change */
|
||||
if( p_input->stream.b_changed )
|
||||
{
|
||||
/* FIXME: We should notify our client that the input changed */
|
||||
/* E_(GtkModeManage)( p_intf ); */
|
||||
p_intf->p_sys->b_playing = 1;
|
||||
}
|
||||
}
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
}
|
||||
else if( p_intf->p_sys->b_playing && !p_intf->b_die )
|
||||
{
|
||||
/* FIXME: We should notify our client that the input changed */
|
||||
/* E_(GtkModeManage)( p_intf ); */
|
||||
p_intf->p_sys->b_playing = 0;
|
||||
}
|
||||
|
||||
/* CORBA calls handling. Beware: no lock is taken (since p_pinput
|
||||
can be null) */
|
||||
if (b_work_pending)
|
||||
CORBA_ORB_perform_work (p_intf->p_sys->orb, ev);
|
||||
|
||||
if( p_intf->b_die )
|
||||
{
|
||||
vlc_mutex_unlock( &p_intf->change_lock );
|
||||
g_main_loop_quit (p_intf->p_sys->corbaloop);
|
||||
/* Just in case */
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
vlc_mutex_unlock( &p_intf->change_lock );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Run: main loop
|
||||
*****************************************************************************
|
||||
* this part of the interface is in a separate thread so that we can call
|
||||
* g_main_loop_run() from within it without annoying the rest of the program.
|
||||
*****************************************************************************/
|
||||
static void Run ( intf_thread_t *p_intf )
|
||||
{
|
||||
CORBA_Environment* ev = NULL;
|
||||
guint i_event_source;
|
||||
CORBA_char* psz_objref;
|
||||
impl_POA_VLC_MediaControl *servant = NULL;
|
||||
int i_argc = 1;
|
||||
char* ppsz_argv[] = { "mc" };
|
||||
|
||||
msg_Warn (p_intf, "Entering Run");
|
||||
|
||||
ev = CORBA_exception__alloc ();
|
||||
|
||||
/* To be able to use CORBA in a MT app */
|
||||
linc_set_threaded (TRUE);
|
||||
|
||||
p_intf->p_sys->orb = CORBA_ORB_init(&i_argc, ppsz_argv, "orbit-local-orb", ev);
|
||||
|
||||
/* Should be cleaner this way (cf
|
||||
http://www.fifi.org/doc/gnome-dev-doc/html/C/orbitgtk.html) but it
|
||||
functions well enough in the ugly way so that I do not bother
|
||||
cleaning it */
|
||||
/* p_intf->p_sys->orb = gnome_CORBA_init ("VLC", NULL, &argc, &argv, 0, NULL, ev); */
|
||||
|
||||
handle_exception_no_servant (p_intf, "Exception during CORBA_ORB_init");
|
||||
|
||||
p_intf->p_sys->root_poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(p_intf->p_sys->orb, "RootPOA", ev);
|
||||
handle_exception ("Exception during RootPOA initialization");
|
||||
|
||||
p_intf->p_sys->mc = impl_VLC_MediaControl__create(p_intf->p_sys->root_poa, ev);
|
||||
handle_exception ("Exception during MediaControl initialization");
|
||||
|
||||
servant = (impl_POA_VLC_MediaControl*)PortableServer_POA_reference_to_servant(p_intf->p_sys->root_poa, p_intf->p_sys->mc, ev);
|
||||
handle_exception ("Exception during MediaControl access");
|
||||
|
||||
servant->p_intf = p_intf;
|
||||
|
||||
psz_objref = CORBA_ORB_object_to_string(p_intf->p_sys->orb, p_intf->p_sys->mc, ev);
|
||||
handle_exception ("Exception during IOR generation");
|
||||
|
||||
msg_Warn (p_intf, "MediaControl IOR :");
|
||||
msg_Warn (p_intf, psz_objref);
|
||||
|
||||
/* We write the IOR in a file. */
|
||||
{
|
||||
FILE* fp;
|
||||
fp = fopen (VLC_IOR_FILE, "w");
|
||||
if (fp == NULL)
|
||||
{
|
||||
msg_Err (servant->p_intf, "Cannot write the IOR to %s (%d).", VLC_IOR_FILE, errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (fp, "%s", psz_objref);
|
||||
fclose (fp);
|
||||
msg_Warn (servant->p_intf, "IOR written to %s", VLC_IOR_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
msg_Warn (p_intf, "get_the_POAManager (state %s)", p_intf->p_sys->root_poa);
|
||||
p_intf->p_sys->root_poa_manager = PortableServer_POA__get_the_POAManager(p_intf->p_sys->root_poa, ev);
|
||||
handle_exception ("Exception during POAManager resolution");
|
||||
|
||||
msg_Warn (p_intf, "Activating POAManager");
|
||||
PortableServer_POAManager_activate(p_intf->p_sys->root_poa_manager, ev);
|
||||
handle_exception ("Exception during POAManager activation");
|
||||
|
||||
msg_Info(p_intf, "corba remote control interface initialized" );
|
||||
|
||||
/*
|
||||
// Tentative de gestion du nommage...
|
||||
{
|
||||
CosNaming_NamingContext name_service;
|
||||
CosNaming_NameComponent name_component[3] = {{"GNOME", "subcontext"},
|
||||
{"Servers", "subcontext"},
|
||||
{"vlc", "server"} };
|
||||
CosNaming_Name name = {3, 3, name_component, CORBA_FALSE};
|
||||
|
||||
name_service = CORBA_ORB_resolve_initial_references (p_intf->p_sys->orb,
|
||||
"NameService",
|
||||
ev);
|
||||
handle_exception ("Error: could not get name service: %s\n",
|
||||
CORBA_exception_id(ev));
|
||||
msg_Warn (p_intf, "Name service OK");
|
||||
|
||||
CosNaming_NamingContext_bind (name_service, &name, p_intf->p_sys->mc, ev);
|
||||
handle_exception ("Error: could not register object: %s\n",
|
||||
CORBA_exception_id(ev));
|
||||
}
|
||||
*/
|
||||
|
||||
/* The time factor should be 1/1000 but it is a little too
|
||||
slow. Make it 1/10000 */
|
||||
i_event_source = g_timeout_add (INTF_IDLE_SLEEP / 10000,
|
||||
Manage,
|
||||
p_intf);
|
||||
msg_Warn (p_intf, "Entering mainloop");
|
||||
|
||||
p_intf->p_sys->corbaloop = g_main_loop_new (NULL, FALSE);
|
||||
g_main_loop_run (p_intf->p_sys->corbaloop);
|
||||
|
||||
/* Cleaning */
|
||||
g_source_remove( i_event_source );
|
||||
unlink (VLC_IOR_FILE);
|
||||
|
||||
msg_Warn (p_intf, "Normal termination of VLC corba plugin");
|
||||
return;
|
||||
}
|
7
modules/control/corba/launch-vlc-corba
Normal file
7
modules/control/corba/launch-vlc-corba
Normal file
@ -0,0 +1,7 @@
|
||||
#! /bin/sh
|
||||
# Helper prog
|
||||
VLCPATH=/usr/local/src/vlc
|
||||
cd $VLCPATH
|
||||
${VLCPATH}/vlc --intf corba &
|
||||
exit 0
|
||||
|
55
modules/control/corba/mediacontrol.idl
Normal file
55
modules/control/corba/mediacontrol.idl
Normal file
@ -0,0 +1,55 @@
|
||||
/* Cf
|
||||
http://www.cs.rpi.edu/~musser/dsc/idl/idl-overview.html
|
||||
pour une intro à la syntaxe */
|
||||
|
||||
module VLC {
|
||||
enum PositionOrigin {
|
||||
AbsolutePosition, RelativePosition, ModuloPosition
|
||||
};
|
||||
|
||||
enum PositionKey {
|
||||
ByteCount, SampleCount, MediaTime
|
||||
};
|
||||
|
||||
struct Position {
|
||||
PositionOrigin origin;
|
||||
PositionKey key;
|
||||
long value;
|
||||
};
|
||||
|
||||
exception PositionKeyNotSupported { PositionKey key;};
|
||||
exception InvalidPosition { PositionKey key;};
|
||||
|
||||
typedef sequence<string> PlaylistSeq;
|
||||
|
||||
// MediaControl interface is similar to
|
||||
// ControlledStream interface in MSS.
|
||||
// It can be inherited by flow endpoints or
|
||||
// FlowConnection interfaces.
|
||||
interface MediaControl
|
||||
{
|
||||
|
||||
exception PositionKeyNotSupported { PositionKey key;};
|
||||
|
||||
Position get_media_position(
|
||||
in PositionOrigin an_origin,
|
||||
in PositionKey a_key)
|
||||
raises (PositionKeyNotSupported);
|
||||
|
||||
void set_media_position(in Position a_position)
|
||||
raises (PositionKeyNotSupported, InvalidPosition);
|
||||
|
||||
void start(in Position a_position)
|
||||
raises(InvalidPosition);
|
||||
void pause(in Position a_position)
|
||||
raises(InvalidPosition);
|
||||
void resume(in Position a_position)
|
||||
raises(InvalidPosition);
|
||||
void stop(in Position a_position)
|
||||
raises(InvalidPosition);
|
||||
void exit (); // Exits the player (not in the original spec)
|
||||
void add_to_playlist (in string a_file);
|
||||
// Returns the list of files in playlist
|
||||
PlaylistSeq get_playlist ();
|
||||
};
|
||||
};
|
48
modules/control/corba/pyorbit-1.99.3.patch
Normal file
48
modules/control/corba/pyorbit-1.99.3.patch
Normal file
@ -0,0 +1,48 @@
|
||||
--- pyorbit-1.99.3/src/pycorba-orb.c 2002-11-16 07:51:41.000000000 +0100
|
||||
+++ pyorbit-1.99.3-modif/src/pycorba-orb.c 2003-01-22 14:43:30.000000000 +0100
|
||||
@@ -154,6 +154,36 @@
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
+static PyObject *
|
||||
+pycorba_orb_work_pending(PyCORBA_ORB *self)
|
||||
+{
|
||||
+ CORBA_boolean ret;
|
||||
+ CORBA_Environment ev;
|
||||
+ PyObject *py_ret;
|
||||
+
|
||||
+ CORBA_exception_init(&ev);
|
||||
+ ret = CORBA_ORB_work_pending (self->orb, &ev);
|
||||
+
|
||||
+ if (pyorbit_check_ex(&ev))
|
||||
+ return NULL;
|
||||
+ py_ret = ret ? Py_True : Py_False;
|
||||
+ Py_INCREF(py_ret);
|
||||
+ return py_ret;
|
||||
+}
|
||||
+
|
||||
+static PyObject *
|
||||
+pycorba_orb_perform_work (PyCORBA_ORB *self)
|
||||
+{
|
||||
+ CORBA_Environment ev;
|
||||
+
|
||||
+ CORBA_exception_init(&ev);
|
||||
+ CORBA_ORB_perform_work (self->orb, &ev);
|
||||
+ if (pyorbit_check_ex(&ev))
|
||||
+ return NULL;
|
||||
+ Py_INCREF(Py_None);
|
||||
+ return Py_None;
|
||||
+}
|
||||
+
|
||||
static PyMethodDef pycorba_orb_methods[] = {
|
||||
{ "object_to_string", (PyCFunction)pycorba_orb_object_to_string, METH_VARARGS },
|
||||
{ "string_to_object", (PyCFunction)pycorba_orb_string_to_object, METH_VARARGS },
|
||||
@@ -161,6 +191,8 @@
|
||||
{ "resolve_initial_references", (PyCFunction)pycorba_orb_resolve_initial_references, METH_VARARGS },
|
||||
{ "run", (PyCFunction)pycorba_orb_run, METH_NOARGS },
|
||||
{ "shutdown", (PyCFunction)pycorba_orb_shutdown, METH_VARARGS },
|
||||
+ { "work_pending", (PyCFunction)pycorba_orb_work_pending, METH_VARARGS },
|
||||
+ { "perform_work", (PyCFunction)pycorba_orb_perform_work, METH_VARARGS },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
402
modules/control/corba/simpleplayer.glade
Normal file
402
modules/control/corba/simpleplayer.glade
Normal file
@ -0,0 +1,402 @@
|
||||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<glade-interface>
|
||||
|
||||
<widget class="GtkWindow" id="win">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">DVD Annote</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<signal name="delete_event" handler="on_exit" object="win" last_modification_time="Mon, 27 Jan 2003 14:07:29 GMT"/>
|
||||
<signal name="key_press_event" handler="on_win_key_press_event" last_modification_time="Mon, 17 Feb 2003 16:23:35 GMT"/>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuBar" id="menubar">
|
||||
<property name="visible">True</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="menuitem1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use_underline">True</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenu" id="menuitem1_menu">
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="quit1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-quit</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_exit" last_modification_time="Mon, 27 Jan 2003 14:07:57 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="menuitem4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Help</property>
|
||||
<property name="use_underline">True</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenu" id="menuitem4_menu">
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="about1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_About</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_about1_activate" last_modification_time="Mon, 27 Jan 2003 14:07:57 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="b_rewind">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Rewind</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Rewind</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<signal name="clicked" handler="on_b_rewind_clicked" last_modification_time="Mon, 27 Jan 2003 14:19:30 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="b_play">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Play</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Play</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<signal name="clicked" handler="on_b_play_clicked" last_modification_time="Mon, 27 Jan 2003 14:19:50 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="b_pause">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Pause</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Pause</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<signal name="clicked" handler="on_b_pause_clicked" last_modification_time="Mon, 27 Jan 2003 14:19:56 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="b_stop">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Stop</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Stop</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<signal name="clicked" handler="on_b_stop_clicked" last_modification_time="Mon, 27 Jan 2003 14:20:03 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="b_forward">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Forward</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Forward</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<signal name="clicked" handler="on_b_forward_clicked" last_modification_time="Mon, 27 Jan 2003 14:20:10 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="b_addfile">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Add file</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Add file...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<signal name="clicked" handler="on_b_addfile_clicked" last_modification_time="Mon, 27 Jan 2003 14:20:15 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="b_selectdvd">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Select DVD</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Play DVD</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<signal name="clicked" handler="on_b_selectdvd_clicked" last_modification_time="Mon, 27 Jan 2003 14:20:15 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="b_exit">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Exit</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-quit</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<signal name="clicked" handler="on_b_exit_clicked" last_modification_time="Mon, 27 Jan 2003 14:20:26 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkFrame" id="Information">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="label_yalign">0.5</property>
|
||||
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTable" id="table1">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">1</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="row_spacing">0</property>
|
||||
<property name="column_spacing">10</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Position</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">10</property>
|
||||
<property name="ypad">2</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="position_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">N/C</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Information</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTextView" id="logmessages">
|
||||
<property name="height_request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="justification">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap_mode">GTK_WRAP_CHAR</property>
|
||||
<property name="cursor_visible">False</property>
|
||||
<property name="pixels_above_lines">0</property>
|
||||
<property name="pixels_below_lines">0</property>
|
||||
<property name="pixels_inside_wrap">0</property>
|
||||
<property name="left_margin">0</property>
|
||||
<property name="right_margin">0</property>
|
||||
<property name="indent">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
<signal name="insert_at_cursor" handler="on_logmessages_insert_at_cursor" last_modification_time="Mon, 27 Jan 2003 14:09:43 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkWindow" id="about">
|
||||
<property name="title" translatable="yes">About</property>
|
||||
<property name="type">GTK_WINDOW_POPUP</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="label_yalign">0.5</property>
|
||||
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<property name="width_request">280</property>
|
||||
<property name="height_request">64</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">DVD Annotation
|
||||
|
||||
En cours de developpement...</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="button1">
|
||||
<property name="border_width">1</property>
|
||||
<property name="width_request">54</property>
|
||||
<property name="height_request">34</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Close about box</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<signal name="clicked" handler="about_hide" object="about" last_modification_time="Wed, 29 Jan 2003 12:52:15 GMT"/>
|
||||
<accelerator key="Escape" modifiers="0" signal="clicked"/>
|
||||
<accelerator key="Return" modifiers="0" signal="clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
298
modules/control/corba/simpleplayer.py
Normal file
298
modules/control/corba/simpleplayer.py
Normal file
@ -0,0 +1,298 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, time
|
||||
|
||||
# For gtk/glade
|
||||
import pygtk
|
||||
pygtk.require ('2.0')
|
||||
import gtk
|
||||
import gtk.glade
|
||||
|
||||
# For CORBA
|
||||
import ORBit, CORBA
|
||||
# FIXME: How do we make this portable to windows ?
|
||||
ORBit.load_typelib ("./MediaControl.so")
|
||||
import VLC
|
||||
|
||||
class Connect:
|
||||
"""Abstract class defining helper functions to interconnect
|
||||
glade XML files and methods of a python class."""
|
||||
def create_dictionary (self):
|
||||
"""Create a (name, function) dictionnary for the current class"""
|
||||
dict = {}
|
||||
self.create_dictionary_for_class (self.__class__, dict)
|
||||
return dict
|
||||
|
||||
def create_dictionary_for_class (self, a_class, dict):
|
||||
"""Create a (name, function) dictionnary for the specified class"""
|
||||
bases = a_class.__bases__
|
||||
for iteration in bases:
|
||||
self.create_dictionary_for_class (iteration, dict)
|
||||
for iteration in dir(a_class):
|
||||
dict[iteration] = getattr(self, iteration)
|
||||
|
||||
def connect (self):
|
||||
"""Connects the class methods with the UI"""
|
||||
self.gui.signal_autoconnect(self.create_dictionary ())
|
||||
|
||||
def gtk_widget_hide (self, widget):
|
||||
widget.hide ()
|
||||
return gtk.TRUE
|
||||
|
||||
def on_exit(self, source=None, event=None):
|
||||
"""Generic exit callback"""
|
||||
gtk.main_quit()
|
||||
|
||||
class DVDControl (Connect):
|
||||
def __init__ (self, gladefile):
|
||||
"""Initializes the GUI and other attributes"""
|
||||
# Glade init.
|
||||
self.gui = gtk.glade.XML(gladefile)
|
||||
self.connect ()
|
||||
# Frequently used GUI widgets
|
||||
self.gui.logmessages = self.gui.get_widget("logmessages")
|
||||
self.gui.position_label = self.gui.get_widget("position_label")
|
||||
self.gui.fs = gtk.FileSelection ("Select a file")
|
||||
self.gui.fs.ok_button.connect_after ("clicked", lambda win: self.gui.fs.hide ())
|
||||
self.gui.fs.cancel_button.connect ("clicked", lambda win: self.gui.fs.destroy ())
|
||||
|
||||
# CORBA init.
|
||||
self.mc = None
|
||||
self.currentpos = None
|
||||
self.status = None
|
||||
# FIXME: portability
|
||||
self.iorfile = "/tmp/vlc-ior.ref"
|
||||
|
||||
# Various
|
||||
# Default FF/RW time : 5 seconds
|
||||
self.default_time_increment = 5
|
||||
|
||||
def update_title (self, title):
|
||||
# Update the title of the main window
|
||||
self.gui.get_widget ("win").set_title (title)
|
||||
|
||||
def launch_player (self):
|
||||
"""Launch the VLC corba plugin"""
|
||||
#print "Launching vlc server..."
|
||||
# FIXME: spawn is portable, but how can we make sure that
|
||||
# launch-vlc-corba launches the application in the background ?
|
||||
# FIXME: portability
|
||||
import distutils.spawn
|
||||
distutils.spawn.spawn (["launch-vlc-corba"], True, True)
|
||||
# Wait a little for the server to initialize. We could instead test
|
||||
# on the existence and validity of self.iorfile
|
||||
time.sleep (2)
|
||||
return
|
||||
|
||||
def main (self):
|
||||
"""Mainloop : CORBA initalization and Gtk mainloop setup"""
|
||||
self.orb = CORBA.ORB_init(sys.argv)
|
||||
|
||||
errormessage = """Unable to get a MediaControl object
|
||||
Please try to run the following command:
|
||||
vlc --intf corba"""
|
||||
|
||||
try:
|
||||
ior = open(self.iorfile).readline()
|
||||
except:
|
||||
# The iorfile does not existe : the player is maybe not active
|
||||
self.launch_player ()
|
||||
try:
|
||||
ior = open(self.iorfile).readline()
|
||||
except:
|
||||
print errormessage
|
||||
sys.exit(1)
|
||||
|
||||
self.mc = self.orb.string_to_object(ior)
|
||||
|
||||
if self.mc._non_existent ():
|
||||
# The remote object is not available. Let's run the
|
||||
# VLC server
|
||||
self.launch_player ()
|
||||
try:
|
||||
ior = open(self.iorfile).readline()
|
||||
except:
|
||||
print errormessage
|
||||
sys.exit(1)
|
||||
self.mc = self.orb.string_to_object(ior)
|
||||
if self.mc._non_existent ():
|
||||
print errormessage
|
||||
sys.exit(1)
|
||||
|
||||
self.currentpos = VLC.Position ()
|
||||
self.currentpos.value = 0
|
||||
self.currentpos.key = VLC.MediaTime
|
||||
self.currentpos.origin = VLC.RelativePosition
|
||||
|
||||
gtk.timeout_add (20, self.update_display, self.orb)
|
||||
gtk.main ()
|
||||
|
||||
def log (self, msg):
|
||||
"""Adds a new log message to the logmessage window"""
|
||||
buf = self.gui.logmessages.get_buffer ()
|
||||
mes = str(msg) + "\n"
|
||||
buf.insert_at_cursor (mes, len(mes))
|
||||
|
||||
endmark = buf.create_mark ("end",
|
||||
buf.get_end_iter (),
|
||||
gtk.TRUE)
|
||||
self.gui.logmessages.scroll_mark_onscreen (endmark)
|
||||
return
|
||||
|
||||
def on_exit (self, source=None, event=None):
|
||||
"""General exit callback"""
|
||||
self.status = "Stop"
|
||||
# Terminate the VLC server
|
||||
try:
|
||||
self.mc.exit()
|
||||
except:
|
||||
pass
|
||||
gtk.main_quit ()
|
||||
|
||||
def file_selector (self, callback=None, label="Select a file",
|
||||
default=""):
|
||||
"""Display the file selector"""
|
||||
self.gui.fs.set_property ("title", label)
|
||||
self.gui.fs.set_property ("filename", default)
|
||||
self.gui.fs.set_property ("select-multiple", False)
|
||||
self.gui.fs.set_property ("show-fileops", False)
|
||||
|
||||
if callback:
|
||||
# Disconnecting the old callback
|
||||
try:
|
||||
self.gui.fs.ok_button.disconnect (self.gui.fs.connect_id)
|
||||
except:
|
||||
pass
|
||||
# Connecting the new one
|
||||
self.gui.fs.connect_id = self.gui.fs.ok_button.connect ("clicked", callback, self.gui.fs)
|
||||
self.gui.fs.show ()
|
||||
return gtk.TRUE
|
||||
|
||||
def file_selected_cb (self, button, fs):
|
||||
"""Open and play the selected movie file"""
|
||||
file = self.gui.fs.get_property ("filename")
|
||||
self.mc.add_to_playlist (file)
|
||||
self.status = "Play"
|
||||
return gtk.TRUE
|
||||
|
||||
def move_position (self, value):
|
||||
"""Helper function : fast forward or rewind by value seconds"""
|
||||
print "Moving by %d seconds" % value
|
||||
pos = VLC.Position ()
|
||||
pos.value = value
|
||||
pos.key = VLC.MediaTime
|
||||
pos.origin = VLC.RelativePosition
|
||||
self.mc.set_media_position (pos)
|
||||
return
|
||||
|
||||
def update_display (self, orb):
|
||||
"""Update the interface"""
|
||||
if self.status == "Play":
|
||||
pos = self.mc.get_media_position (VLC.AbsolutePosition,
|
||||
VLC.ByteCount)
|
||||
self.gui.position_label.set_text (str(pos.value))
|
||||
elif self.status == "Stop":
|
||||
self.gui.position_label.set_text ("N/C")
|
||||
return gtk.TRUE
|
||||
|
||||
# Callbacks function. Skeletons can be generated by glade2py
|
||||
def on_win_key_press_event (self, win=None, event=None):
|
||||
# Navigation keys
|
||||
if event.keyval == gtk.keysyms.Tab:
|
||||
self.on_b_pause_clicked (win, event)
|
||||
return gtk.TRUE
|
||||
elif event.keyval == gtk.keysyms.Right:
|
||||
self.on_b_forward_clicked (win, event)
|
||||
return gtk.TRUE
|
||||
elif event.keyval == gtk.keysyms.Left:
|
||||
self.on_b_rewind_clicked (win, event)
|
||||
return gtk.TRUE
|
||||
elif event.keyval == gtk.keysyms.Home:
|
||||
pos = VLC.Position ()
|
||||
pos.value = 0
|
||||
pos.key = VLC.MediaTime
|
||||
pos.origin = VLC.AbsolutePosition
|
||||
self.mc.set_media_position (pos)
|
||||
return gtk.TRUE
|
||||
elif event.keyval == gtk.keysyms.End:
|
||||
pos = VLC.Position ()
|
||||
pos.value = -self.default_time_increment
|
||||
pos.key = VLC.MediaTime
|
||||
pos.origin = VLC.ModuloPosition
|
||||
self.mc.set_media_position (pos)
|
||||
return gtk.TRUE
|
||||
elif event.keyval == gtk.keysyms.Page_Down:
|
||||
# FIXME: Next chapter
|
||||
return gtk.TRUE
|
||||
elif event.keyval == gtk.keysyms.Page_Up:
|
||||
# FIXME: Previous chapter
|
||||
return gtk.TRUE
|
||||
return gtk.TRUE
|
||||
|
||||
def on_quit1_activate (self, button=None, data=None):
|
||||
"""Gtk callback to quit"""
|
||||
self.on_exit (button, data)
|
||||
return gtk.TRUE
|
||||
|
||||
def on_about1_activate (self, button=None, data=None):
|
||||
self.gui.get_widget("about").show ()
|
||||
return gtk.TRUE
|
||||
|
||||
def about_hide (self, button=None, data=None):
|
||||
self.gui.get_widget("about").hide ()
|
||||
return gtk.TRUE
|
||||
|
||||
def on_b_rewind_clicked (self, button=None, data=None):
|
||||
if self.status == "Play":
|
||||
self.move_position (-self.default_time_increment)
|
||||
return gtk.TRUE
|
||||
|
||||
def on_b_play_clicked (self, button=None, data=None):
|
||||
if self.status != "Play":
|
||||
self.mc.start (self.currentpos)
|
||||
self.status = "Play"
|
||||
return gtk.TRUE
|
||||
|
||||
def on_b_pause_clicked (self, button=None, data=None):
|
||||
if self.status == "Play":
|
||||
self.mc.pause (self.currentpos)
|
||||
self.status = "Pause"
|
||||
elif self.status == "Pause":
|
||||
self.mc.pause (self.currentpos)
|
||||
self.status = "Play"
|
||||
return gtk.TRUE
|
||||
|
||||
def on_b_stop_clicked (self, button=None, data=None):
|
||||
self.mc.stop (self.currentpos)
|
||||
self.status = "Stop"
|
||||
return gtk.TRUE
|
||||
|
||||
def on_b_forward_clicked (self, button=None, data=None):
|
||||
if self.status == "Play":
|
||||
self.move_position (self.default_time_increment)
|
||||
return gtk.TRUE
|
||||
|
||||
def on_b_addfile_clicked (self, button=None, data=None):
|
||||
self.file_selector (callback=self.file_selected_cb,
|
||||
label="Play a movie file")
|
||||
return gtk.TRUE
|
||||
|
||||
def on_b_selectdvd_clicked (self, button=None, data=None):
|
||||
"""Play a DVD"""
|
||||
self.mc.add_to_playlist ("dvd:///dev/dvd at 1,1")
|
||||
self.mc.start (self.currentpos)
|
||||
self.status = "Play"
|
||||
return gtk.TRUE
|
||||
|
||||
def on_b_exit_clicked (self, button=None, data=None):
|
||||
self.on_exit (button, data)
|
||||
return gtk.TRUE
|
||||
|
||||
def on_logmessages_insert_at_cursor (self, button=None, data=None):
|
||||
print "on_logmessages_insert_at_cursor activated (%s, %s, %s)" % (self, button, data)
|
||||
# FIXME: faire défiler la scrollmark (cf gtkshell)
|
||||
return gtk.TRUE
|
||||
|
||||
if __name__ == '__main__':
|
||||
v = DVDControl ("simpleplayer.glade")
|
||||
v.main ()
|
@ -2,7 +2,7 @@
|
||||
* playlist.c : Playlist management functions
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999-2001 VideoLAN
|
||||
* $Id: playlist.c,v 1.40 2003/06/27 13:38:54 sam Exp $
|
||||
* $Id: playlist.c,v 1.41 2003/07/07 16:59:00 sam Exp $
|
||||
*
|
||||
* Authors: Samuel Hocevar <sam@zoy.org>
|
||||
*
|
||||
@ -412,6 +412,7 @@ void playlist_Command( playlist_t * p_playlist, int i_command, int i_arg )
|
||||
p_playlist->i_status = PLAYLIST_RUNNING;
|
||||
if( p_playlist->p_input )
|
||||
{
|
||||
PlayItem( p_playlist );
|
||||
input_SetStatus( p_playlist->p_input, INPUT_STATUS_PLAY );
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user