diff --git a/Makefile.in b/Makefile.in index 674061d058..caa981ecfe 100644 --- a/Makefile.in +++ b/Makefile.in @@ -185,6 +185,7 @@ INTERFACE = src/interface/main.o \ src/interface/intf_cmd.o \ src/interface/intf_ctrl.o \ src/interface/intf_plst.o \ + src/interface/intf_channels.o \ src/interface/intf_console.o INPUT = src/input/input_ext-dec.o \ @@ -238,8 +239,7 @@ MISC = src/misc/mtime.o \ src/misc/tests.o \ src/misc/rsc_files.o \ src/misc/modules.o \ - src/misc/netutils.o \ - src/misc/plugins.o + src/misc/netutils.o C_OBJ = $(INTERFACE) \ @@ -314,7 +314,6 @@ PLUGIN_GGI = plugins/ggi/ggi.o \ plugins/ggi/vout_ggi.o PLUGIN_SDL = plugins/sdl/sdl.o \ - plugins/sdl/intf_sdl.o \ plugins/sdl/vout_sdl.o \ plugins/sdl/aout_sdl.o @@ -324,10 +323,9 @@ PLUGIN_GLIDE = plugins/glide/glide.o \ PLUGIN_GNOME = plugins/gnome/gnome.o \ plugins/gnome/intf_gnome.o \ - plugins/gnome/intf_gnome_callbacks.o \ - plugins/gnome/intf_gnome_interface.o \ - plugins/gnome/intf_gnome_support.o \ - plugins/gnome/vout_gnome.o + plugins/gnome/gnome_callbacks.o \ + plugins/gnome/gnome_interface.o \ + plugins/gnome/gnome_support.o PLUGIN_MGA = plugins/mga/mga.o \ plugins/mga/intf_mga.o \ diff --git a/configure b/configure index a4cae0cde2..d33058813e 100755 --- a/configure +++ b/configure @@ -22,7 +22,7 @@ ac_help="$ac_help ac_help="$ac_help --disable-optimizations Disable compiler optimizations (default enabled)" ac_help="$ac_help - --disable-dummy dummy audio and video support (default enabled)" + --enable-dummy dummy audio and video support (default disabled)" ac_help="$ac_help --disable-null Null module (default enabled)" ac_help="$ac_help @@ -34,13 +34,13 @@ ac_help="$ac_help ac_help="$ac_help --with-ggi[=name] GGI support (default disabled)" ac_help="$ac_help - --with-sdl[=name] SDL support (default disabled)" + --with-sdl[=name] SDL support (default enabled)" ac_help="$ac_help --with-glide[=name] Glide (3dfx) support (default disabled)" ac_help="$ac_help - --enable-gnome Gnome support (default disabled)" + --disable-gnome Gnome support (default enabled)" ac_help="$ac_help - --disable-x11 X11 support (default enabled)" + --enable-x11 X11 support (default disabled)" ac_help="$ac_help --enable-alsa Alsa sound drivers support (Only for linux) (default disabled)" @@ -3419,10 +3419,9 @@ else # Check whether --enable-dummy or --disable-dummy was given. if test "${enable_dummy+set}" = set; then enableval="$enable_dummy" - : + if test x$enable_dummy = xyes; then PLUGINS=${PLUGINS}"dummy "; fi fi -if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi # Check whether --enable-null or --disable-null was given. if test "${enable_null+set}" = set; then enableval="$enable_null" @@ -3473,6 +3472,11 @@ if test "${with_sdl+set}" = set; then fi fi + if test "x$withval" == "x"; + then + PLUGINS=${PLUGINS}"sdl " + LIB_SDL="-lSDL" + fi # Check whether --with-glide or --without-glide was given. if test "${with_glide+set}" = set; then withval="$with_glide" @@ -3488,32 +3492,33 @@ fi # Check whether --enable-gnome or --disable-gnome was given. if test "${enable_gnome+set}" = set; then enableval="$enable_gnome" - if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi -fi - -# Check whether --enable-x11 or --disable-x11 was given. -if test "${enable_x11+set}" = set; then - enableval="$enable_x11" : fi -if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi +if test x$enable_gnome != xno; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi +# Check whether --enable-x11 or --disable-x11 was given. +if test "${enable_x11+set}" = set; then + enableval="$enable_x11" + if test x$enable_x11 = xyes; then PLUGINS=${PLUGINS}"x11 "; fi +fi + + # Check whether --enable-alsa or --disable-alsa was given. if test "${enable_alsa+set}" = set; then enableval="$enable_alsa" if test x$enable_alsa = xyes; then ac_safe=`echo "sys/asoundlib.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/asoundlib.h""... $ac_c" 1>&6 -echo "configure:3507: checking for sys/asoundlib.h" >&5 +echo "configure:3512: checking for sys/asoundlib.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3517: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3522: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3530,7 +3535,7 @@ fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for main in -lasound""... $ac_c" 1>&6 -echo "configure:3534: checking for main in -lasound" >&5 +echo "configure:3539: checking for main in -lasound" >&5 ac_lib_var=`echo asound'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3538,14 +3543,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lasound $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else diff --git a/configure.in b/configure.in index bee9b459a6..31d46942d7 100644 --- a/configure.in +++ b/configure.in @@ -138,8 +138,8 @@ dnl default case else AC_ARG_ENABLE(dummy, - [ --disable-dummy dummy audio and video support (default enabled)]) -if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi + [ --enable-dummy dummy audio and video support (default disabled)], + [if test x$enable_dummy = xyes; then PLUGINS=${PLUGINS}"dummy "; fi]) AC_ARG_ENABLE(null, [ --disable-null Null module (default enabled)]) if test x$enable_null != xno; then PLUGINS=${PLUGINS}"null "; fi @@ -162,7 +162,7 @@ AC_ARG_WITH(ggi, LIB_GGI="-lggi" fi ]) AC_ARG_WITH(sdl, - [ --with-sdl[=name] SDL support (default disabled)], + [ --with-sdl[=name] SDL support (default enabled)], [ PLUGINS=${PLUGINS}"sdl "; if test "x$withval" != "xyes"; then @@ -170,6 +170,11 @@ AC_ARG_WITH(sdl, else LIB_SDL="-lSDL" fi ]) + if test "x$withval" == "x"; + then + PLUGINS=${PLUGINS}"sdl " + LIB_SDL="-lSDL" + fi AC_ARG_WITH(glide, [ --with-glide[=name] Glide (3dfx) support (default disabled)], [ PLUGINS=${PLUGINS}"glide "; @@ -180,11 +185,12 @@ AC_ARG_WITH(glide, LIB_GLIDE="-lglide2x" fi ]) AC_ARG_ENABLE(gnome, - [ --enable-gnome Gnome support (default disabled)], - [if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi]) + [ --disable-gnome Gnome support (default enabled)]) +if test x$enable_gnome != xno; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi AC_ARG_ENABLE(x11, - [ --disable-x11 X11 support (default enabled)]) -if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi + [ --enable-x11 X11 support (default disabled)], + [if test x$enable_x11 = xyes; then PLUGINS=${PLUGINS}"x11 "; fi]) + AC_ARG_ENABLE(alsa, [ --enable-alsa Alsa sound drivers support (Only for linux) (default disabled)], [if test x$enable_alsa = xyes; then AC_CHECK_HEADER(sys/asoundlib.h, AC_CHECK_LIB(asound, main, have_alsa="true", have_alsa="false"),have_alsa="false") if test $have_alsa = true; then PLUGINS=${PLUGINS}"alsa "; fi; fi]) diff --git a/include/config.h.in b/include/config.h.in index d1da688834..a9bcbf0cba 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -128,6 +128,9 @@ * Interface configuration *****************************************************************************/ +/* Environment variable containing the display method */ +#define INTF_METHOD_VAR "vlc_intf" + /* Environment variable used to store startup script name and default value */ #define INTF_INIT_SCRIPT_VAR "vlcrc" #define INTF_INIT_SCRIPT_DEFAULT ".vlcrc" diff --git a/include/interface.h b/include/interface.h index 2354e6db12..32cc4b1cc6 100644 --- a/include/interface.h +++ b/include/interface.h @@ -43,11 +43,6 @@ * This structe describes all interface-specific data of the main (interface) * thread. *****************************************************************************/ -typedef int ( intf_sys_create_t ) ( p_intf_thread_t p_intf ); -typedef void ( intf_sys_destroy_t ) ( p_intf_thread_t p_intf ); -typedef void ( intf_sys_manage_t ) ( p_intf_thread_t p_intf ); - - typedef struct _keyparam { int key; @@ -72,10 +67,14 @@ typedef struct intf_thread_s p_intf_sys_t p_sys; /* system interface */ p_intf_key p_keys; - /* Plugin */ - intf_sys_create_t * p_sys_create; /* create interface thread */ - intf_sys_manage_t * p_sys_manage; /* main loop */ - intf_sys_destroy_t * p_sys_destroy; /* destroy interface */ + /* Plugin used and shortcuts to access its capabilities */ + struct module_s * p_module; + int ( *pf_open ) ( struct intf_thread_s * ); + void ( *pf_close ) ( struct intf_thread_s * ); + void ( *pf_run ) ( struct intf_thread_s * ); + + /* Interface callback */ + void ( *pf_manage ) ( struct intf_thread_s * ); /* XXX: Channels array - new API */ //p_intf_channel_t * p_channel[INTF_MAX_CHANNELS];/* channel descriptions */ @@ -84,24 +83,24 @@ typedef struct intf_thread_s p_intf_channel_t p_channel; /* description of channels */ /* Main threads - NULL if not active */ - p_vout_thread_t p_vout; p_input_thread_t p_input; /* Specific functions */ keyparm (*p_intf_get_key)(struct intf_thread_s *p_intf, int r_key) ; + + /* XXX: new message passing stuff will go here */ + vlc_mutex_t change_lock; + boolean_t b_menu_change; + boolean_t b_menu; - /* Warning messages level */ - int i_warning_level; } intf_thread_t; /***************************************************************************** * Prototypes *****************************************************************************/ intf_thread_t * intf_Create ( void ); -void intf_Run ( intf_thread_t * p_intf ); void intf_Destroy ( intf_thread_t * p_intf ); -int intf_SelectChannel ( intf_thread_t * p_intf, int i_channel ); int intf_ProcessKey ( intf_thread_t * p_intf, int i_key ); void intf_AssignKey( intf_thread_t *p_intf, int r_key, int f_key, int param); diff --git a/include/main.h b/include/main.h index af1d327052..9e52f66b1e 100644 --- a/include/main.h +++ b/include/main.h @@ -39,7 +39,9 @@ typedef struct char ** ppsz_argv; /* command line arguments */ char ** ppsz_env; /* environment variables */ char * psz_arg0; /* program name (whithout path) */ + int i_cpu_capabilities; /* CPU extensions */ + int i_warning_level; /* warning messages level */ /* Generic settings */ boolean_t b_audio; /* is audio output allowed ? */ @@ -48,13 +50,13 @@ typedef struct boolean_t b_dvd; /* DVD mode ? */ /* Unique threads */ + p_vout_thread_t p_vout; /* video output thread */ p_aout_thread_t p_aout; /* audio output thread */ p_intf_thread_t p_intf; /* main interface thread */ /* Shared data - these structures are accessed directly from p_main by * several modules */ - struct module_bank_s * p_module_bank; /* module bank */ - p_plugin_bank_t p_bank; /* plugin bank */ + struct module_bank_s * p_bank; /* module bank */ p_playlist_t p_playlist; /* playlist */ p_intf_msg_t p_msg; /* messages interface data */ p_input_vlan_t p_vlan; /* vlan library data */ diff --git a/include/modules.h b/include/modules.h index ee7d6024bd..9dfa8c10fd 100644 --- a/include/modules.h +++ b/include/modules.h @@ -65,6 +65,14 @@ typedef struct function_list_s union { + /* Interface plugin */ + struct + { + int ( * pf_open ) ( struct intf_thread_s * ); + void ( * pf_close )( struct intf_thread_s * ); + void ( * pf_run ) ( struct intf_thread_s * ); + } intf; + /* Input plugin */ struct { @@ -98,6 +106,19 @@ typedef struct function_list_s void ( * pf_close ) ( struct aout_thread_s * ); } aout; + /* Video output plugin */ + struct + { + int ( * pf_create ) ( struct vout_thread_s * ); + int ( * pf_init ) ( struct vout_thread_s * ); + void ( * pf_end ) ( struct vout_thread_s * ); + void ( * pf_destroy ) ( struct vout_thread_s * ); + int ( * pf_manage ) ( struct vout_thread_s * ); + void ( * pf_display ) ( struct vout_thread_s * ); + void ( * pf_setpalette ) ( struct vout_thread_s *, u16 *red, + u16 *green, u16 *blue, u16 *transp ); + } vout; + /* Motion compensation plugin */ struct { diff --git a/include/plugins.h b/include/plugins.h deleted file mode 100644 index de1c34a923..0000000000 --- a/include/plugins.h +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************** - * plugins.h : Dynamic plugin management functions - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * - * Authors: - * - * 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. - *****************************************************************************/ - -#ifdef SYS_BEOS -typedef int plugin_id_t; -#define GET_PLUGIN( p_func, plugin_id, psz_name ) \ - get_image_symbol( plugin_id, psz_name, B_SYMBOL_TYPE_TEXT, &p_func ); -#else -typedef void *plugin_id_t; -#define GET_PLUGIN( p_func, plugin_id, psz_name ) \ - p_func = dlsym( plugin_id, psz_name ); -#endif - -typedef struct plugin_info_s -{ - plugin_id_t plugin_id; - - char * psz_filename; - char * psz_name; - char * psz_version; - char * psz_author; - - void * aout_GetPlugin; - void * vout_GetPlugin; - void * intf_GetPlugin; - void * yuv_GetPlugin; - - int i_score; -} plugin_info_t; - -typedef struct plugin_bank_s -{ - int i_plugin_count; - plugin_info_t * p_info[ MAX_PLUGIN_COUNT ]; -} plugin_bank_t; - -plugin_bank_t * bank_Create ( void ); -void bank_Init ( plugin_bank_t * p_bank ); -void bank_Destroy ( plugin_bank_t * p_bank ); - diff --git a/include/video_output.h b/include/video_output.h index 51b1b9c063..a34bd447e2 100644 --- a/include/video_output.h +++ b/include/video_output.h @@ -112,18 +112,6 @@ typedef struct vout_buffer_s * is represented by a video output thread, and described using the following * structure. *****************************************************************************/ -typedef int (vout_sys_create_t) ( p_vout_thread_t p_vout, - char *psz_display, - int i_root_window, void *p_data ); -typedef int (vout_sys_init_t) ( p_vout_thread_t p_vout ); -typedef void (vout_sys_end_t) ( p_vout_thread_t p_vout ); -typedef void (vout_sys_destroy_t) ( p_vout_thread_t p_vout ); -typedef int (vout_sys_manage_t) ( p_vout_thread_t p_vout ); -typedef void (vout_sys_display_t) ( p_vout_thread_t p_vout ); - -typedef void (vout_set_palette_t) ( p_vout_thread_t p_vout, u16 *red, - u16 *green, u16 *blue, u16 *transp ); - typedef struct vout_thread_s { /* Thread properties and lock */ @@ -165,15 +153,16 @@ typedef struct vout_thread_s u32 i_gray_pixel; /* gray */ u32 i_blue_pixel; /* blue */ - /* Plugins */ - vout_sys_create_t * p_sys_create; /* allocate output method */ - vout_sys_init_t * p_sys_init; /* initialize output method */ - vout_sys_end_t * p_sys_end; /* terminate output method */ - vout_sys_destroy_t * p_sys_destroy; /* destroy output method */ - vout_sys_manage_t * p_sys_manage; /* handle events */ - vout_sys_display_t * p_sys_display; /* display rendered image */ - - vout_set_palette_t * p_set_palette; /* set 8bpp palette */ + /* Plugin used and shortcuts to access its capabilities */ + struct module_s * p_module; + int ( *pf_create ) ( struct vout_thread_s * ); + int ( *pf_init ) ( struct vout_thread_s * ); + void ( *pf_end ) ( struct vout_thread_s * ); + void ( *pf_destroy ) ( struct vout_thread_s * ); + int ( *pf_manage ) ( struct vout_thread_s * ); + void ( *pf_display ) ( struct vout_thread_s * ); + void ( *pf_setpalette ) ( struct vout_thread_s *, u16 *red, + u16 *green, u16 *blue, u16 *transp ); /* Pictures and rendering properties */ boolean_t b_grayscale; /* color or grayscale display */ @@ -243,17 +232,16 @@ typedef struct vout_thread_s /***************************************************************************** * Prototypes *****************************************************************************/ -vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, - int i_width, int i_height, int *pi_status, - int i_method, void *p_data ); -void vout_DestroyThread ( vout_thread_t *p_vout, int *pi_status ); -picture_t * vout_CreatePicture ( vout_thread_t *p_vout, int i_type, - int i_width, int i_height ); -void vout_DestroyPicture ( vout_thread_t *p_vout, picture_t *p_pic ); -void vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pic ); -void vout_DatePicture ( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date ); -void vout_LinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ); -void vout_UnlinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ); +vout_thread_t * vout_CreateThread ( int *pi_status ); +void vout_DestroyThread ( vout_thread_t *p_vout, int *pi_status ); +picture_t * vout_CreatePicture ( vout_thread_t *p_vout, int i_type, + int i_width, int i_height ); +void vout_DestroyPicture ( vout_thread_t *p_vout, picture_t *p_pic ); +void vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pic ); +void vout_DatePicture ( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date ); +void vout_LinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ); +void vout_UnlinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ); + subpicture_t * vout_CreateSubPicture ( vout_thread_t *p_vout, int i_type, int i_size ); void vout_DestroySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic ); void vout_DisplaySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic ); diff --git a/plugins/gnome/gnome.c b/plugins/gnome/gnome.c index 02d9384179..533dc3271c 100644 --- a/plugins/gnome/gnome.c +++ b/plugins/gnome/gnome.c @@ -3,8 +3,8 @@ ***************************************************************************** * Copyright (C) 2000 VideoLAN * - * Authors: - * + * Authors: Samuel Hocevar + * * 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 @@ -20,6 +20,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ +#define MODULE_NAME gnome + /***************************************************************************** * Preamble *****************************************************************************/ @@ -27,109 +29,86 @@ #include /* malloc(), free() */ -#include - #include "config.h" #include "common.h" /* boolean_t, byte_t */ #include "threads.h" #include "mtime.h" #include "tests.h" -#include "plugins.h" #include "interface.h" -#include "audio_output.h" #include "video.h" #include "video_output.h" -#include "main.h" +#include "modules.h" +#include "modules_inner.h" /***************************************************************************** - * Exported prototypes + * Building configuration tree *****************************************************************************/ -static void vout_GetPlugin( p_vout_thread_t p_vout ); -static void intf_GetPlugin( p_intf_thread_t p_intf ); - -/* Video output */ -int vout_GnomeCreate ( vout_thread_t *p_vout, char *psz_display, - int i_root_window, void *p_data ); -int vout_GnomeInit ( p_vout_thread_t p_vout ); -void vout_GnomeEnd ( p_vout_thread_t p_vout ); -void vout_GnomeDestroy ( p_vout_thread_t p_vout ); -int vout_GnomeManage ( p_vout_thread_t p_vout ); -void vout_GnomeDisplay ( p_vout_thread_t p_vout ); -void vout_GnomeSetPalette ( p_vout_thread_t p_vout, u16 *red, - u16 *green, u16 *blue, u16 *transp ); - -/* Interface */ -int intf_GnomeCreate ( p_intf_thread_t p_intf ); -void intf_GnomeDestroy ( p_intf_thread_t p_intf ); -void intf_GnomeManage ( p_intf_thread_t p_intf ); +MODULE_CONFIG_START +ADD_WINDOW( "Configuration for Gnome module" ) + ADD_COMMENT( "For now, the Gnome module cannot be configured" ) +MODULE_CONFIG_END /***************************************************************************** - * GetConfig: get the plugin structure and configuration + * Capabilities defined in the other files. + ******************************************************************************/ +extern void intf_getfunctions( function_list_t * p_function_list ); + +/***************************************************************************** + * InitModule: get the module structure and configuration. + ***************************************************************************** + * We have to fill psz_name, psz_longname and psz_version. These variables + * will be strdup()ed later by the main application because the module can + * be unloaded later to save memory, and we want to be able to access this + * data even after the module has been unloaded. *****************************************************************************/ -plugin_info_t * GetConfig( void ) +int InitModule( module_t * p_module ) { - Display *p_display; - plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) ); + p_module->psz_name = MODULE_STRING; + p_module->psz_longname = "Gnome interface module"; + p_module->psz_version = VERSION; - p_info->psz_name = "Gnome"; - p_info->psz_version = VERSION; - p_info->psz_author = "the VideoLAN team "; + p_module->i_capabilities = MODULE_CAPABILITY_NULL + | MODULE_CAPABILITY_INTF; - p_info->aout_GetPlugin = NULL; - p_info->vout_GetPlugin = vout_GetPlugin; - p_info->intf_GetPlugin = intf_GetPlugin; - p_info->yuv_GetPlugin = NULL; - - /* Check that we can open the X display */ - if( (p_display = XOpenDisplay( XDisplayName( - main_GetPszVariable( VOUT_DISPLAY_VAR, NULL ) ) )) - == NULL ) - { - p_info->i_score = 0; - } - else - { - XCloseDisplay( p_display ); - p_info->i_score = 0x200; - } - - if( TestProgram( "gvlc" ) ) - { - p_info->i_score += 0x180; - } - - /* If this plugin was requested, score it higher */ - if( TestMethod( VOUT_METHOD_VAR, "gnome" ) ) - { - p_info->i_score += 0x200; - } - - return( p_info ); + return( 0 ); } /***************************************************************************** - * Following functions are only called through the p_info structure + * ActivateModule: set the module to an usable state. + ***************************************************************************** + * This function fills the capability functions and the configuration + * structure. Once ActivateModule() has been called, the i_usage can + * be set to 0 and calls to NeedModule() be made to increment it. To unload + * the module, one has to wait until i_usage == 0 and call DeactivateModule(). *****************************************************************************/ - -static void vout_GetPlugin( p_vout_thread_t p_vout ) +int ActivateModule( module_t * p_module ) { - p_vout->p_sys_create = vout_GnomeCreate; - p_vout->p_sys_init = vout_GnomeInit; - p_vout->p_sys_end = vout_GnomeEnd; - p_vout->p_sys_destroy = vout_GnomeDestroy; - p_vout->p_sys_manage = vout_GnomeManage; - p_vout->p_sys_display = vout_GnomeDisplay; + p_module->p_functions = malloc( sizeof( module_functions_t ) ); + if( p_module->p_functions == NULL ) + { + return( -1 ); + } - /* optional functions */ - p_vout->p_set_palette = vout_GnomeSetPalette; + intf_getfunctions( &p_module->p_functions->intf ); + + p_module->p_config = p_config; + + return( 0 ); } -static void intf_GetPlugin( p_intf_thread_t p_intf ) +/***************************************************************************** + * DeactivateModule: make sure the module can be unloaded. + ***************************************************************************** + * This function must only be called when i_usage == 0. If it successfully + * returns, i_usage can be set to -1 and the module unloaded. Be careful to + * lock usage_lock during the whole process. + *****************************************************************************/ +int DeactivateModule( module_t * p_module ) { - p_intf->p_sys_create = intf_GnomeCreate; - p_intf->p_sys_destroy = intf_GnomeDestroy; - p_intf->p_sys_manage = intf_GnomeManage; + free( p_module->p_functions ); + + return( 0 ); } diff --git a/plugins/gnome/intf_gnome_callbacks.c b/plugins/gnome/gnome_callbacks.c similarity index 60% rename from plugins/gnome/intf_gnome_callbacks.c rename to plugins/gnome/gnome_callbacks.c index d01088c802..36c299cf79 100644 --- a/plugins/gnome/intf_gnome_callbacks.c +++ b/plugins/gnome/gnome_callbacks.c @@ -3,18 +3,24 @@ #include "config.h" #include "common.h" #include "threads.h" +#include "mtime.h" #include -#include "intf_gnome_thread.h" -#include "intf_gnome_callbacks.h" -#include "intf_gnome_interface.h" -#include "intf_gnome_support.h" +#include "stream_control.h" +#include "input_ext-intf.h" + +#include "interface.h" + +#include "gnome_sys.h" +#include "gnome_callbacks.h" +#include "gnome_interface.h" +#include "gnome_support.h" #define GET_GNOME_STRUCT( item, parent ) \ gtk_object_get_data( \ GTK_OBJECT( lookup_widget(GTK_WIDGET(item), parent) ), \ - "p_gnome" ); + "p_intf" ); void on_modules_activate (GtkMenuItem *menuitem, @@ -28,11 +34,11 @@ void on_exit_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_window" ); - p_gnome->b_die = 1; + p_intf->b_die = 1; } @@ -64,15 +70,15 @@ void on_about_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_window" ); - if( !GTK_IS_WIDGET( p_gnome->p_about ) ) + if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) ) { - p_gnome->p_about = create_intf_about (); + p_intf->p_sys->p_about = create_intf_about (); } - gtk_widget_show( p_gnome->p_about ); + gtk_widget_show( p_intf->p_sys->p_about ); } @@ -80,6 +86,9 @@ void on_stop_clicked (GtkButton *button, gpointer user_data) { + intf_thread_t *p_intf; + + p_intf = GET_GNOME_STRUCT( button, "intf_window" ); } @@ -88,32 +97,32 @@ void on_control_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_window" ); /* lock the change structure */ - vlc_mutex_lock( &p_gnome->change_lock ); + vlc_mutex_lock( &p_intf->p_sys->change_lock ); - if( p_gnome->b_window ) + if( p_intf->p_sys->b_window ) { - gtk_widget_hide( p_gnome->p_window ); - p_gnome->b_window = 0; + gtk_widget_hide( p_intf->p_sys->p_window ); + p_intf->p_sys->b_window = 0; } else { - if( !GTK_IS_WIDGET( p_gnome->p_window ) ) + if( !GTK_IS_WIDGET( p_intf->p_sys->p_window ) ) { - p_gnome->p_window = create_intf_window (); + p_intf->p_sys->p_window = create_intf_window (); } - gtk_widget_show( p_gnome->p_window ); - gtk_object_set_data( GTK_OBJECT(p_gnome->p_window), - "p_gnome", p_gnome ); - p_gnome->b_window = 1; + gtk_widget_show( p_intf->p_sys->p_window ); + gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window), + "p_intf", p_intf ); + p_intf->p_sys->b_window = 1; } /* unlock the change structure */ - vlc_mutex_unlock( &p_gnome->change_lock ); + vlc_mutex_unlock( &p_intf->p_sys->change_lock ); } @@ -121,64 +130,64 @@ void on_playlist_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_window" ); /* lock the change structure */ - vlc_mutex_lock( &p_gnome->change_lock ); + vlc_mutex_lock( &p_intf->p_sys->change_lock ); - if( p_gnome->b_playlist ) + if( p_intf->p_sys->b_playlist ) { - gtk_widget_hide( p_gnome->p_playlist ); - p_gnome->b_playlist = 0; + gtk_widget_hide( p_intf->p_sys->p_playlist ); + p_intf->p_sys->b_playlist = 0; } else { - if( !GTK_IS_WIDGET( p_gnome->p_playlist ) ) + if( !GTK_IS_WIDGET( p_intf->p_sys->p_playlist ) ) { - p_gnome->p_playlist = create_intf_playlist (); + p_intf->p_sys->p_playlist = create_intf_playlist (); } - gtk_widget_show( p_gnome->p_playlist ); - gtk_object_set_data( GTK_OBJECT(p_gnome->p_playlist), - "p_gnome", p_gnome ); - p_gnome->b_playlist = 1; + gtk_widget_show( p_intf->p_sys->p_playlist ); + gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_playlist), + "p_intf", p_intf ); + p_intf->p_sys->b_playlist = 1; } /* unlock the change structure */ - vlc_mutex_unlock( &p_gnome->change_lock ); + vlc_mutex_unlock( &p_intf->p_sys->change_lock ); } void on_popup_control_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" ); /* lock the change structure */ - vlc_mutex_lock( &p_gnome->change_lock ); + vlc_mutex_lock( &p_intf->p_sys->change_lock ); - if( p_gnome->b_window ) + if( p_intf->p_sys->b_window ) { - gtk_widget_hide( p_gnome->p_window ); - p_gnome->b_window = 0; + gtk_widget_hide( p_intf->p_sys->p_window ); + p_intf->p_sys->b_window = 0; } else { - if( !GTK_IS_WIDGET( p_gnome->p_window ) ) + if( !GTK_IS_WIDGET( p_intf->p_sys->p_window ) ) { - p_gnome->p_window = create_intf_window (); + p_intf->p_sys->p_window = create_intf_window (); } - gtk_widget_show( p_gnome->p_window ); - gtk_object_set_data( GTK_OBJECT(p_gnome->p_window), - "p_gnome", p_gnome ); - p_gnome->b_window = 1; + gtk_widget_show( p_intf->p_sys->p_window ); + gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window), + "p_intf", p_intf ); + p_intf->p_sys->b_window = 1; } /* unlock the change structure */ - vlc_mutex_unlock( &p_gnome->change_lock ); + vlc_mutex_unlock( &p_intf->p_sys->change_lock ); } @@ -186,32 +195,32 @@ void on_popup_playlist_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" ); /* lock the change structure */ - vlc_mutex_lock( &p_gnome->change_lock ); + vlc_mutex_lock( &p_intf->p_sys->change_lock ); - if( p_gnome->b_playlist ) + if( p_intf->p_sys->b_playlist ) { - gtk_widget_hide( p_gnome->p_playlist ); - p_gnome->b_playlist = 0; + gtk_widget_hide( p_intf->p_sys->p_playlist ); + p_intf->p_sys->b_playlist = 0; } else { - if( !GTK_IS_WIDGET( p_gnome->p_playlist ) ) + if( !GTK_IS_WIDGET( p_intf->p_sys->p_playlist ) ) { - p_gnome->p_playlist = create_intf_playlist (); + p_intf->p_sys->p_playlist = create_intf_playlist (); } - gtk_widget_show( p_gnome->p_playlist ); - gtk_object_set_data( GTK_OBJECT(p_gnome->p_playlist), - "p_gnome", p_gnome ); - p_gnome->b_playlist = 1; + gtk_widget_show( p_intf->p_sys->p_playlist ); + gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_playlist), + "p_intf", p_intf ); + p_intf->p_sys->b_playlist = 1; } /* unlock the change structure */ - vlc_mutex_unlock( &p_gnome->change_lock ); + vlc_mutex_unlock( &p_intf->p_sys->change_lock ); } @@ -220,11 +229,11 @@ void on_popup_exit_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" ); - p_gnome->b_die = 1; + p_intf->b_die = 1; } @@ -232,15 +241,15 @@ void on_popup_about_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" ); - if( !GTK_IS_WIDGET( p_gnome->p_about ) ) + if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) ) { - p_gnome->p_about = create_intf_about (); + p_intf->p_sys->p_about = create_intf_about (); } - gtk_widget_show( p_gnome->p_about ); + gtk_widget_show( p_intf->p_sys->p_about ); } @@ -248,7 +257,14 @@ void on_intf_window_destroy (GtkObject *object, gpointer user_data) { - fprintf( stderr, "interface window destroyed !\n" ); + intf_thread_t *p_intf; + + p_intf = GET_GNOME_STRUCT( object, "intf_window" ); + + /* FIXME don't destroy the window, just hide it */ + p_intf->p_sys->p_window = NULL; + + p_intf->b_die = 1; } @@ -256,7 +272,7 @@ void on_intf_playlist_destroy (GtkObject *object, gpointer user_data) { - fprintf( stderr, "playlist window destroyed !\n" ); + ; } @@ -377,14 +393,11 @@ void on_popup_play_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" ); - vlc_mutex_lock( &p_gnome->change_lock ); - p_gnome->b_activity_changed = 1; - p_gnome->b_activity = 1; - vlc_mutex_unlock( &p_gnome->change_lock ); + input_Play( p_intf->p_input ); } @@ -400,14 +413,11 @@ void on_play_clicked (GtkButton *button, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( button, "intf_window" ); + p_intf = GET_GNOME_STRUCT( button, "intf_window" ); - vlc_mutex_lock( &p_gnome->change_lock ); - p_gnome->b_activity_changed = 1; - p_gnome->b_activity = 1; - vlc_mutex_unlock( &p_gnome->change_lock ); + input_Play( p_intf->p_input ); } @@ -442,11 +452,11 @@ on_open_clicked (GtkButton *button, } }; - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( button, "intf_window" ); + p_intf = GET_GNOME_STRUCT( button, "intf_window" ); - gnome_app_insert_menus (GNOME_APP (p_gnome->p_window), + gnome_app_insert_menus (GNOME_APP (p_intf->p_sys->p_window), "_View/Channel/None", test_uiinfo); } @@ -456,14 +466,11 @@ void on_pause_clicked (GtkButton *button, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( button, "intf_window" ); + p_intf = GET_GNOME_STRUCT( button, "intf_window" ); - vlc_mutex_lock( &p_gnome->change_lock ); - p_gnome->b_activity_changed = 1; - p_gnome->b_activity = 0; - vlc_mutex_unlock( &p_gnome->change_lock ); + input_Pause( p_intf->p_input ); } @@ -471,14 +478,11 @@ void on_popup_pause_activate (GtkMenuItem *menuitem, gpointer user_data) { - gnome_thread_t *p_gnome; + intf_thread_t *p_intf; - p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" ); + p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" ); - vlc_mutex_lock( &p_gnome->change_lock ); - p_gnome->b_activity_changed = 1; - p_gnome->b_activity = 0; - vlc_mutex_unlock( &p_gnome->change_lock ); + input_Pause( p_intf->p_input ); } diff --git a/plugins/gnome/intf_gnome_callbacks.h b/plugins/gnome/gnome_callbacks.h similarity index 100% rename from plugins/gnome/intf_gnome_callbacks.h rename to plugins/gnome/gnome_callbacks.h diff --git a/plugins/gnome/intf_gnome_interface.c b/plugins/gnome/gnome_interface.c similarity index 99% rename from plugins/gnome/intf_gnome_interface.c rename to plugins/gnome/gnome_interface.c index a9c60d7911..0b3e2db0a6 100644 --- a/plugins/gnome/intf_gnome_interface.c +++ b/plugins/gnome/gnome_interface.c @@ -13,9 +13,9 @@ #include -#include "intf_gnome_callbacks.h" -#include "intf_gnome_interface.h" -#include "intf_gnome_support.h" +#include "gnome_callbacks.h" +#include "gnome_interface.h" +#include "gnome_support.h" static GnomeUIInfo file_menu_menu_uiinfo[] = { diff --git a/plugins/gnome/intf_gnome_interface.h b/plugins/gnome/gnome_interface.h similarity index 100% rename from plugins/gnome/intf_gnome_interface.h rename to plugins/gnome/gnome_interface.h diff --git a/plugins/gnome/intf_gnome_support.c b/plugins/gnome/gnome_support.c similarity index 99% rename from plugins/gnome/intf_gnome_support.c rename to plugins/gnome/gnome_support.c index d13ea74000..f65d7698bf 100644 --- a/plugins/gnome/intf_gnome_support.c +++ b/plugins/gnome/gnome_support.c @@ -13,7 +13,7 @@ #include -#include "intf_gnome_support.h" +#include "gnome_support.h" /* This is an internally used function to create pixmaps. */ static GtkWidget* create_dummy_pixmap (GtkWidget *widget, diff --git a/plugins/gnome/intf_gnome_support.h b/plugins/gnome/gnome_support.h similarity index 100% rename from plugins/gnome/intf_gnome_support.h rename to plugins/gnome/gnome_support.h diff --git a/plugins/gnome/intf_gnome_thread.h b/plugins/gnome/gnome_sys.h similarity index 78% rename from plugins/gnome/intf_gnome_thread.h rename to plugins/gnome/gnome_sys.h index 293cd7ec3d..de74cc1974 100644 --- a/plugins/gnome/intf_gnome_thread.h +++ b/plugins/gnome/gnome_sys.h @@ -1,7 +1,8 @@ /***************************************************************************** - * intf_gnome_thread.h: Gnome thread + * gnome_sys.h: private Gnome interface description ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN + * $Id: gnome_sys.h,v 1.1 2001/02/11 01:15:10 sam Exp $ * * Authors: * @@ -17,18 +18,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Boston, MA 02111-1307, USA. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ /***************************************************************************** * intf_sys_t: description and status of Gnome interface *****************************************************************************/ -typedef struct gnome_thread_s +typedef struct intf_sys_s { - vlc_thread_t thread_id; /* id for thread functions */ - boolean_t b_die; /* `die' flag */ - boolean_t b_error; /* `error' flag */ - /* special actions */ vlc_mutex_t change_lock; /* the change lock */ @@ -43,16 +40,18 @@ typedef struct gnome_thread_s boolean_t b_playlist_changed; /* playlist display toggled ? */ boolean_t b_playlist; /* display playlist ? */ + /* intf_Manage callback timeout */ + int i_timeout; + /* windows and widgets */ GtkWidget * p_window; /* main window */ GtkWidget * p_popup; /* popup menu */ GtkWidget * p_playlist; /* playlist */ GtkWidget * p_about; /* about window */ -} gnome_thread_t; + /* XXX: ugly kludge */ + void ( *pf_gtk_callback ) ( void ); + void ( *pf_gdk_callback ) ( void ); -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -void GnomeThread ( gnome_thread_t *p_gnome ); +} intf_sys_t; diff --git a/plugins/gnome/intf_gnome.c b/plugins/gnome/intf_gnome.c index 0f558ba2da..a4c8bb43d2 100644 --- a/plugins/gnome/intf_gnome.c +++ b/plugins/gnome/intf_gnome.c @@ -2,7 +2,7 @@ * intf_gnome.c: Gnome interface ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: intf_gnome.c,v 1.7 2001/01/15 06:18:22 sam Exp $ + * $Id: intf_gnome.c,v 1.8 2001/02/11 01:15:10 sam Exp $ * * Authors: * @@ -29,46 +29,102 @@ #include /* ENOMEM */ #include /* free() */ #include /* strerror() */ +#include + +#include "glib.h" #include #include #include +#include + #include "config.h" #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" +#include "tests.h" +#include "modules.h" #include "stream_control.h" #include "input_ext-intf.h" -#include "video.h" -#include "video_output.h" - -#include "audio_output.h" /* needed for mute */ - #include "intf_msg.h" #include "interface.h" +#include "gnome_sys.h" +#include "gnome_interface.h" +#include "gnome_support.h" + #include "main.h" -#include +/***************************************************************************** + * Local prototypes. + *****************************************************************************/ +static int intf_Probe ( probedata_t *p_data ); +static int intf_Open ( intf_thread_t *p_intf ); +static void intf_Close ( intf_thread_t *p_intf ); +static void intf_Run ( intf_thread_t *p_intf ); -#include - -#include "intf_gnome_thread.h" -#include "intf_gnome.h" -#include "intf_gnome_interface.h" -#include "intf_gnome_support.h" +static gint GnomeManage ( gpointer p_data ); /***************************************************************************** - * intf_GnomeCreate: initialize and create window + * g_atexit: kludge to avoid the Gnome thread to segfault at exit + ***************************************************************************** + * gtk_init() makes several calls to g_atexit() which calls atexit() to + * register tidying callbacks to be called at program exit. Since the Gnome + * plugin is likely to be unloaded at program exit, we have to export this + * symbol to intercept the g_atexit() calls. Talk about crude hack. *****************************************************************************/ -int intf_GnomeCreate( intf_thread_t *p_intf ) +void g_atexit( GVoidFunc func ) { - char *psz_display; + intf_thread_t *p_intf = p_main->p_intf; + if( p_intf->p_sys->pf_gdk_callback == NULL ) + { + p_intf->p_sys->pf_gdk_callback = func; + } + else if( p_intf->p_sys->pf_gtk_callback == NULL ) + { + p_intf->p_sys->pf_gtk_callback = func; + } + /* else nothing, but we could do something here */ + return; +} + +/***************************************************************************** + * Functions exported as capabilities. They are declared as static so that + * we don't pollute the namespace too much. + *****************************************************************************/ +void intf_getfunctions( function_list_t * p_function_list ) +{ + p_function_list->pf_probe = intf_Probe; + p_function_list->functions.intf.pf_open = intf_Open; + p_function_list->functions.intf.pf_close = intf_Close; + p_function_list->functions.intf.pf_run = intf_Run; +} + +/***************************************************************************** + * intf_Probe: probe the interface and return a score + ***************************************************************************** + * This function tries to initialize Gnome and returns a score to the + * plugin manager so that it can select the best plugin. + *****************************************************************************/ +static int intf_Probe( probedata_t *p_data ) +{ + if( TestMethod( INTF_METHOD_VAR, "gnome" ) ) + { + return( 999 ); + } + + return( 40 ); +} + +/***************************************************************************** + * intf_Open: initialize and create window + *****************************************************************************/ +static int intf_Open( intf_thread_t *p_intf ) +{ /* Allocate instance and initialize some members */ p_intf->p_sys = malloc( sizeof( intf_sys_t ) ); if( p_intf->p_sys == NULL ) @@ -77,593 +133,114 @@ int intf_GnomeCreate( intf_thread_t *p_intf ) return( 1 ); } - p_intf->p_sys->p_gnome = malloc( sizeof( gnome_thread_t ) ); - if( p_intf->p_sys->p_gnome == NULL ) - { - intf_ErrMsg("error: %s", strerror(ENOMEM)); - free( p_intf->p_sys ); - return( 1 ); - } + /* Initialize Gnome thread */ + p_intf->p_sys->b_window = 1; + p_intf->p_sys->b_playlist = 0; - /* Open display, unsing 'vlc_display' or DISPLAY environment variable */ - psz_display = XDisplayName( main_GetPszVariable( VOUT_DISPLAY_VAR, NULL ) ); - p_intf->p_sys->p_display = XOpenDisplay( psz_display ); - if( !p_intf->p_sys->p_display ) /* error */ - { - intf_ErrMsg("error: can't open display %s", psz_display ); - free( p_intf->p_sys->p_gnome ); - free( p_intf->p_sys ); - return( 1 ); - } - p_intf->p_sys->i_screen = DefaultScreen( p_intf->p_sys->p_display ); + p_intf->p_sys->b_popup_changed = 0; + p_intf->p_sys->b_window_changed = 0; + p_intf->p_sys->b_playlist_changed = 0; - /* Spawn base window - this window will include the video output window */ - if( GnomeCreateWindow( p_intf ) ) - { - intf_ErrMsg( "error: can't create output window" ); - XCloseDisplay( p_intf->p_sys->p_display ); - free( p_intf->p_sys->p_gnome ); - free( p_intf->p_sys ); - return( 1 ); - } + p_intf->p_sys->pf_gtk_callback = NULL; + p_intf->p_sys->pf_gdk_callback = NULL; - /* Spawn video output thread */ - if( p_main->b_video ) - { - p_intf->p_vout = vout_CreateThread( psz_display, p_intf->p_sys->window, - p_intf->p_sys->i_width, - p_intf->p_sys->i_height, NULL, 0, - (void *)&p_intf->p_sys->colormap ); - - if( p_intf->p_vout == NULL ) /* error */ - { - intf_ErrMsg("error: can't create video output thread" ); - GnomeDestroyWindow( p_intf ); - XCloseDisplay( p_intf->p_sys->p_display ); - free( p_intf->p_sys->p_gnome ); - free( p_intf->p_sys ); - return( 1 ); - } - } - - /* Spawn Gnome thread */ - p_intf->p_sys->p_gnome->b_die = 0; - p_intf->p_sys->p_gnome->b_error = 0; - - p_intf->p_sys->p_gnome->b_popup_changed = 0; - p_intf->p_sys->p_gnome->b_window_changed = 0; - p_intf->p_sys->p_gnome->b_playlist_changed = 0; - - vlc_thread_create( &p_intf->p_sys->p_gnome->thread_id, "gnome", - (void *)GnomeThread, p_intf->p_sys->p_gnome ); - - /* create basic key bindings */ - intf_AssignNormalKeys( p_intf ); - - - /* Disable screen saver and return */ - p_intf->p_sys->i_ss_count = 1; - GnomeDisableScreenSaver( p_intf ); return( 0 ); } /***************************************************************************** - * intf_GnomeDestroy: destroy interface window + * intf_Close: destroy interface window *****************************************************************************/ -void intf_GnomeDestroy( intf_thread_t *p_intf ) +static void intf_Close( intf_thread_t *p_intf ) { - /* Enable screen saver */ - GnomeEnableScreenSaver( p_intf ); - - /* Close input thread, if any (blocking) */ - if( p_intf->p_input ) - { - input_DestroyThread( p_intf->p_input, NULL ); - } - - /* Close video output thread, if any (blocking) */ - if( p_intf->p_vout ) - { - vout_DestroyThread( p_intf->p_vout, NULL ); - } - - /* Close gnome thread, if any (blocking) */ - if( p_intf->p_sys->p_gnome->thread_id ) - { - p_intf->p_sys->p_gnome->b_die = 1; - intf_DbgMsg( "intf: waiting for Gnome thread to terminate" ); - vlc_thread_join( p_intf->p_sys->p_gnome->thread_id ); - intf_DbgMsg( "intf: Gnome thread terminated" ); - } - - /* Close main window and display */ - GnomeDestroyWindow( p_intf ); - XCloseDisplay( p_intf->p_sys->p_display ); - - /* Destroy structures */ - free( p_intf->p_sys->p_gnome ); + /* Destroy structure */ free( p_intf->p_sys ); } /***************************************************************************** - * intf_GnomeManage: event loop - *****************************************************************************/ -void intf_GnomeManage( intf_thread_t *p_intf ) -{ - /* Manage main window */ - GnomeManageWindow( p_intf ); - - /* Manage messages from the Gnome interface */ - GnomeManageInterface( p_intf ); -} - -/* following functions are local */ - -/***************************************************************************** - * GnomeCreateWindow: open and set-up X11 main window - *****************************************************************************/ -static int GnomeCreateWindow( intf_thread_t *p_intf ) -{ - XSizeHints xsize_hints; - XSetWindowAttributes xwindow_attributes; - XGCValues xgcvalues; - XEvent xevent; - boolean_t b_expose; - boolean_t b_configure_notify; - boolean_t b_map_notify; - - /* Set main window's size */ - p_intf->p_sys->i_width = main_GetIntVariable( VOUT_WIDTH_VAR, - VOUT_WIDTH_DEFAULT ); - p_intf->p_sys->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR, - VOUT_HEIGHT_DEFAULT ); - - /* Prepare window manager hints and properties */ - xsize_hints.base_width = p_intf->p_sys->i_width; - xsize_hints.base_height = p_intf->p_sys->i_height; - xsize_hints.flags = PSize; - p_intf->p_sys->wm_protocols = XInternAtom( p_intf->p_sys->p_display, - "WM_PROTOCOLS", True ); - p_intf->p_sys->wm_delete_window = XInternAtom( p_intf->p_sys->p_display, - "WM_DELETE_WINDOW", True ); - - /* Prepare window attributes */ - xwindow_attributes.backing_store = Always; /* save the hidden part */ - xwindow_attributes.background_pixel = WhitePixel( p_intf->p_sys->p_display, - p_intf->p_sys->i_screen ); - - xwindow_attributes.event_mask = ExposureMask | StructureNotifyMask; - - /* Create the window and set hints - the window must receive ConfigureNotify - * events, and, until it is displayed, Expose and MapNotify events. */ - p_intf->p_sys->window = - XCreateWindow( p_intf->p_sys->p_display, - DefaultRootWindow( p_intf->p_sys->p_display ), - 0, 0, - p_intf->p_sys->i_width, p_intf->p_sys->i_height, 1, - 0, InputOutput, 0, - CWBackingStore | CWBackPixel | CWEventMask, - &xwindow_attributes ); - - /* Set window manager hints and properties: size hints, command, - * window's name, and accepted protocols */ - XSetWMNormalHints( p_intf->p_sys->p_display, p_intf->p_sys->window, - &xsize_hints ); - XSetCommand( p_intf->p_sys->p_display, p_intf->p_sys->window, - p_main->ppsz_argv, p_main->i_argc ); - XStoreName( p_intf->p_sys->p_display, p_intf->p_sys->window, VOUT_TITLE ); - if( (p_intf->p_sys->wm_protocols == None) /* use WM_DELETE_WINDOW */ - || (p_intf->p_sys->wm_delete_window == None) - || !XSetWMProtocols( p_intf->p_sys->p_display, p_intf->p_sys->window, - &p_intf->p_sys->wm_delete_window, 1 ) ) - { - /* WM_DELETE_WINDOW is not supported by window manager */ - intf_Msg("intf error: missing or bad window manager - please exit program kindly."); - } - - /* Creation of a graphic context that doesn't generate a GraphicsExpose - * event when using functions like XCopyArea */ - xgcvalues.graphics_exposures = False; - p_intf->p_sys->gc = XCreateGC( p_intf->p_sys->p_display, p_intf->p_sys->window, - GCGraphicsExposures, &xgcvalues); - - /* Send orders to server, and wait until window is displayed - three - * events must be received: a MapNotify event, an Expose event allowing - * drawing in the window, and a ConfigureNotify to get the window - * dimensions. Once those events have been received, only ConfigureNotify - * events need to be received. */ - b_expose = 0; - b_configure_notify = 0; - b_map_notify = 0; - XMapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window); - do - { - XNextEvent( p_intf->p_sys->p_display, &xevent); - if( (xevent.type == Expose) - && (xevent.xexpose.window == p_intf->p_sys->window) ) - { - b_expose = 1; - } - else if( (xevent.type == MapNotify) - && (xevent.xmap.window == p_intf->p_sys->window) ) - { - b_map_notify = 1; - } - else if( (xevent.type == ConfigureNotify) - && (xevent.xconfigure.window == p_intf->p_sys->window) ) - { - b_configure_notify = 1; - p_intf->p_sys->i_width = xevent.xconfigure.width; - p_intf->p_sys->i_height = xevent.xconfigure.height; - } - } while( !( b_expose && b_configure_notify && b_map_notify ) ); - - XSelectInput( p_intf->p_sys->p_display, p_intf->p_sys->window, - StructureNotifyMask | KeyPressMask | ButtonPressMask ); - - if( XDefaultDepth(p_intf->p_sys->p_display, p_intf->p_sys->i_screen) == 8 ) - { - /* Allocate a new palette */ - p_intf->p_sys->colormap = XCreateColormap( p_intf->p_sys->p_display, - DefaultRootWindow( p_intf->p_sys->p_display ), - DefaultVisual( p_intf->p_sys->p_display, - p_intf->p_sys->i_screen ), - AllocAll ); - - xwindow_attributes.colormap = p_intf->p_sys->colormap; - XChangeWindowAttributes( p_intf->p_sys->p_display, - p_intf->p_sys->window, - CWColormap, &xwindow_attributes ); - } - - /* At this stage, the window is open, displayed, and ready to receive data */ - return( 0 ); -} - -/***************************************************************************** - * GnomeDestroyWindow: destroy X11 main window - *****************************************************************************/ -static void GnomeDestroyWindow( intf_thread_t *p_intf ) -{ - XUnmapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window ); - XFreeGC( p_intf->p_sys->p_display, p_intf->p_sys->gc ); - XDestroyWindow( p_intf->p_sys->p_display, p_intf->p_sys->window ); -} - -/***************************************************************************** - * GnomeManageWindow: manage X11 main window - *****************************************************************************/ -static void GnomeManageWindow( intf_thread_t *p_intf ) -{ - XEvent xevent; /* X11 event */ - boolean_t b_resized; /* window has been resized */ - char i_key; /* ISO Latin-1 key */ - - /* Handle X11 events: ConfigureNotify events are parsed to know if the - * output window's size changed, MapNotify and UnmapNotify to know if the - * window is mapped (and if the display is useful), and ClientMessages - * to intercept window destruction requests */ - b_resized = 0; - while( XCheckWindowEvent( p_intf->p_sys->p_display, p_intf->p_sys->window, - StructureNotifyMask | KeyPressMask | - ButtonPressMask, &xevent ) == True ) - { - /* ConfigureNotify event: prepare */ - if( (xevent.type == ConfigureNotify) - && ((xevent.xconfigure.width != p_intf->p_sys->i_width) - || (xevent.xconfigure.height != p_intf->p_sys->i_height)) ) - { - /* Update dimensions */ - b_resized = 1; - p_intf->p_sys->i_width = xevent.xconfigure.width; - p_intf->p_sys->i_height = xevent.xconfigure.height; - } - /* MapNotify event: change window status and disable screen saver */ - else if( xevent.type == MapNotify) - { - if( (p_intf->p_vout != NULL) && !p_intf->p_vout->b_active ) - { - GnomeDisableScreenSaver( p_intf ); - p_intf->p_vout->b_active = 1; - } - } - /* UnmapNotify event: change window status and enable screen saver */ - else if( xevent.type == UnmapNotify ) - { - if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_active ) - { - GnomeEnableScreenSaver( p_intf ); - p_intf->p_vout->b_active = 0; - } - } - /* Keyboard event */ - else if( xevent.type == KeyPress ) - { - if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) ) - { - if( intf_ProcessKey( p_intf, i_key ) ) - { - intf_DbgMsg( "unhandled key '%c' (%i)", (char) i_key, i_key ); - } - } - } - /* Mouse click */ - else if( xevent.type == ButtonPress ) - { - switch( ((XButtonEvent *)&xevent)->button ) - { - case Button1: - /* in this part we will eventually manage - * clicks for DVD navigation for instance */ - break; - - case Button2: - GnomeTogglePointer( p_intf ); - break; - - case Button3: - /* toggle the menu display */ - vlc_mutex_lock( &p_intf->p_sys->p_gnome->change_lock ); - p_intf->p_sys->p_gnome->b_popup_changed = 1; - vlc_mutex_unlock( &p_intf->p_sys->p_gnome->change_lock ); - break; - } - - } -#ifdef DEBUG - /* Other event */ - else - { - intf_DbgMsg( "%p -> unhandled event type %d received", - p_intf, xevent.type ); - } -#endif - } - - /* ClientMessage event - only WM_PROTOCOLS with WM_DELETE_WINDOW data - * are handled - according to the man pages, the format is always 32 - * in this case */ - while( XCheckTypedEvent( p_intf->p_sys->p_display, - ClientMessage, &xevent ) ) - { - if( (xevent.xclient.message_type == p_intf->p_sys->wm_protocols) - && (xevent.xclient.data.l[0] == p_intf->p_sys->wm_delete_window ) ) - { - p_intf->b_die = 1; - } - else - { - intf_DbgMsg( "%p -> unhandled ClientMessage received", p_intf ); - } - } - - /* - * Handle vout or interface windows resizing - */ - if( p_intf->p_vout != NULL ) - { - if( b_resized ) - { - /* If interface window has been resized, change vout size */ - intf_DbgMsg( "resizing output window" ); - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->i_width = p_intf->p_sys->i_width; - p_intf->p_vout->i_height = p_intf->p_sys->i_height; - p_intf->p_vout->i_changes |= VOUT_SIZE_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); - } - else if( (p_intf->p_vout->i_width != p_intf->p_sys->i_width) || - (p_intf->p_vout->i_height != p_intf->p_sys->i_height) ) - { - /* If video output size has changed, change interface window size */ - intf_DbgMsg( "resizing output window" ); - p_intf->p_sys->i_width = p_intf->p_vout->i_width; - p_intf->p_sys->i_height = p_intf->p_vout->i_height; - XResizeWindow( p_intf->p_sys->p_display, p_intf->p_sys->window, - p_intf->p_sys->i_width, p_intf->p_sys->i_height ); - } - } -} - -/***************************************************************************** - * GnomeEnableScreenSaver: enable screen saver - ***************************************************************************** - * This function enable the screen saver on a display after it had been - * disabled by XDisableScreenSaver. Both functions use a counter mechanism to - * know wether the screen saver can be activated or not: if n successive calls - * are made to XDisableScreenSaver, n successive calls to XEnableScreenSaver - * will be required before the screen saver could effectively be activated. - *****************************************************************************/ -void GnomeEnableScreenSaver( intf_thread_t *p_intf ) -{ - if( p_intf->p_sys->i_ss_count++ == 0 ) - { - intf_DbgMsg( "intf: enabling screen saver" ); - XSetScreenSaver( p_intf->p_sys->p_display, p_intf->p_sys->i_ss_timeout, - p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking, - p_intf->p_sys->i_ss_exposure ); - } -} - -/***************************************************************************** - * GnomeDisableScreenSaver: disable screen saver - ***************************************************************************** - * See XEnableScreenSaver - *****************************************************************************/ -void GnomeDisableScreenSaver( intf_thread_t *p_intf ) -{ - if( --p_intf->p_sys->i_ss_count == 0 ) - { - /* Save screen saver informations */ - XGetScreenSaver( p_intf->p_sys->p_display, &p_intf->p_sys->i_ss_timeout, - &p_intf->p_sys->i_ss_interval, &p_intf->p_sys->i_ss_blanking, - &p_intf->p_sys->i_ss_exposure ); - - /* Disable screen saver */ - intf_DbgMsg("intf: disabling screen saver"); - XSetScreenSaver( p_intf->p_sys->p_display, 0, - p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking, - p_intf->p_sys->i_ss_exposure ); - } -} - -/***************************************************************************** - * GnomeTogglePointer: hide or show the mouse pointer - ***************************************************************************** - * This function hides the X pointer if it is visible by putting it at - * coordinates (32,32) and setting the pointer sprite to a blank one. To - * show it again, we disable the sprite and restore the original coordinates. - *****************************************************************************/ -void GnomeTogglePointer( intf_thread_t *p_intf ) -{ - static Cursor cursor; - static boolean_t b_cursor = 0; - - if( p_intf->p_sys->b_mouse ) - { - p_intf->p_sys->b_mouse = 0; - - if( !b_cursor ) - { - XColor color; - Pixmap blank = XCreatePixmap( p_intf->p_sys->p_display, - DefaultRootWindow(p_intf->p_sys->p_display), - 1, 1, 1 ); - - XParseColor( p_intf->p_sys->p_display, - XCreateColormap( p_intf->p_sys->p_display, - DefaultRootWindow( - p_intf->p_sys->p_display ), - DefaultVisual( - p_intf->p_sys->p_display, - p_intf->p_sys->i_screen ), - AllocNone ), - "black", &color ); - - cursor = XCreatePixmapCursor( p_intf->p_sys->p_display, - blank, blank, &color, &color, 1, 1 ); - - b_cursor = 1; - } - XDefineCursor( p_intf->p_sys->p_display, - p_intf->p_sys->window, cursor ); - } - else - { - p_intf->p_sys->b_mouse = 1; - - XUndefineCursor( p_intf->p_sys->p_display, p_intf->p_sys->window ); - } -} - -/***************************************************************************** - * GnomeManageInterface: manage messages from the Gnome interface - - ***************************************************************************** - * In this function, called approx. 10 times a second, we check what the - * Gnome interface wanted to tell us. - *****************************************************************************/ -static void GnomeManageInterface( intf_thread_t *p_intf ) -{ - gnome_thread_t *p_gnome = p_intf->p_sys->p_gnome; - - /* lock the change structure */ - vlc_mutex_lock( &p_gnome->change_lock ); - - /* you killed my father, prepare to die */ - if( p_gnome->b_die ) - { - p_intf->b_die = 1; - } - - if( p_gnome->b_activity_changed ) - { - vlc_mutex_lock( &p_intf->p_vout->picture_lock ); - p_intf->p_vout->b_active = p_gnome->b_activity; - /* having to access p_main sucks */ - p_main->p_aout->b_active = p_gnome->b_activity; - vlc_mutex_unlock( &p_intf->p_vout->picture_lock ); - - p_gnome->b_activity_changed = 0; - } - - /* unlock the change structure */ - vlc_mutex_unlock( &p_gnome->change_lock ); -} - -/***************************************************************************** - * GnomeManageMain: manage main thread messages - ***************************************************************************** - * In this function, called approx. 10 times a second, we check what the - * main program wanted to tell us. - *****************************************************************************/ -static gint GnomeManageMain( gpointer p_data ) -{ - gnome_thread_t *p_gnome = (void *)p_data; - - /* lock the change structure */ - vlc_mutex_lock( &p_gnome->change_lock ); - - if( p_gnome->b_die ) - { - /* unlock the change structure */ - vlc_mutex_unlock( &p_gnome->change_lock ); - - /* prepare to die, young man */ - gtk_main_quit(); - return( FALSE ); - } - - /* if the "display popup" flag has changed */ - if( p_gnome->b_popup_changed ) - { - gnome_popup_menu_do_popup( p_gnome->p_popup, - NULL, NULL, NULL, NULL ); - p_gnome->b_popup_changed = 0; - } - - /* unlock the change structure */ - vlc_mutex_unlock( &p_gnome->change_lock ); - - return( TRUE ); -} - -/***************************************************************************** - * GnomeThread: special Gnome thread + * intf_Run: Gnome thread ***************************************************************************** * this part of the interface is in a separate thread so that we can call * gtk_main() from within it without annoying the rest of the program. * XXX: the approach may look kludgy, and probably is, but I could not find * a better way to dynamically load a Gnome interface at runtime. *****************************************************************************/ -void GnomeThread( gnome_thread_t *p_gnome ) +static void intf_Run( intf_thread_t *p_intf ) { /* gnome_init needs to know the command line. We don't care, so we * give it an empty one */ char *p_args[] = { }; - /* Sleep to avoid using all CPU - since some interfaces needs to access - * keyboard events, a 100ms delay is a good compromise */ - gtk_timeout_add( INTF_IDLE_SLEEP / 1000, GnomeManageMain, p_gnome ); - - gnome_init( "vlc", VERSION, 1, p_args ); + /* Initialize Gnome */ + gnome_init( p_main->psz_arg0, VERSION, 1, p_args ); /* create some useful widgets that will certainly be used */ - p_gnome->p_window = create_intf_window(); - p_gnome->p_popup = create_intf_popup( ); + p_intf->p_sys->p_window = create_intf_window(); + p_intf->p_sys->p_popup = create_intf_popup( ); /* we don't create these ones yet because we perhaps won't need them */ - p_gnome->p_about = NULL; - p_gnome->p_playlist = NULL; + p_intf->p_sys->p_about = NULL; + p_intf->p_sys->p_playlist = NULL; /* store p_sys to keep an eye on it */ - gtk_object_set_data( GTK_OBJECT(p_gnome->p_window), "p_gnome", p_gnome ); - gtk_object_set_data( GTK_OBJECT(p_gnome->p_popup), "p_gnome", p_gnome ); + gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window), + "p_intf", p_intf ); + + gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_popup), + "p_intf", p_intf ); /* show the control window */ - //gtk_widget_show( p_gnome->p_window ); + gtk_widget_show( p_intf->p_sys->p_window ); + /* Sleep to avoid using all CPU - since some interfaces needs to access + * keyboard events, a 100ms delay is a good compromise */ + p_intf->p_sys->i_timeout = gtk_timeout_add( INTF_IDLE_SLEEP / 1000, + GnomeManage, p_intf ); + /* enter gnome mode */ gtk_main(); + + /* launch stored callbacks */ + if( p_intf->p_sys->pf_gtk_callback != NULL ) + { + p_intf->p_sys->pf_gtk_callback(); + + if( p_intf->p_sys->pf_gdk_callback != NULL ) + { + p_intf->p_sys->pf_gdk_callback(); + } + } +} + +/* following functions are local */ + +/***************************************************************************** + * GnomeManage: manage main thread messages + ***************************************************************************** + * In this function, called approx. 10 times a second, we check what the + * main program wanted to tell us. + *****************************************************************************/ +static gint GnomeManage( gpointer p_data ) +{ + intf_thread_t *p_intf = (void *)p_data; + + /* if the "display popup" flag has changed */ + if( p_intf->b_menu_change ) + { + gnome_popup_menu_do_popup( p_intf->p_sys->p_popup, + NULL, NULL, NULL, NULL ); + p_intf->b_menu_change = 0; + } + + /* Manage core vlc functions through the callback */ + p_intf->pf_manage( p_intf ); + + if( p_intf->b_die ) + { + /* prepare to die, young man */ + gtk_main_quit(); + return( FALSE ); + } + + return( TRUE ); } diff --git a/plugins/gnome/intf_gnome.h b/plugins/gnome/intf_gnome.h deleted file mode 100644 index 198e54e93e..0000000000 --- a/plugins/gnome/intf_gnome.h +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************** - * intf_gnome.h: Gnome interface - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * - * Authors: - * - * 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 - * Boston, MA 02111-1307, USA. - *****************************************************************************/ - -/***************************************************************************** - * intf_sys_t: description and status of Gnome interface - *****************************************************************************/ -typedef struct intf_sys_s -{ - /* X11 generic properties */ - Display * p_display; /* X11 display pointer */ - int i_screen; /* X11 screen */ - Atom wm_protocols; - Atom wm_delete_window; - - /* Main window properties */ - Window window; /* main window */ - GC gc; /* graphic context for main window */ - int i_width; /* width of main window */ - int i_height; /* height of main window */ - Colormap colormap; /* colormap used (8bpp only) */ - - /* Screen saver properties */ - int i_ss_count; /* enabling/disabling count */ - int i_ss_timeout; /* timeout */ - int i_ss_interval; /* interval between changes */ - int i_ss_blanking; /* blanking mode */ - int i_ss_exposure; /* exposure mode */ - - /* Mouse pointer properties */ - boolean_t b_mouse; /* is the mouse pointer displayed ? */ - - /* Gnome part properties */ - gnome_thread_t * p_gnome; - -} intf_sys_t; - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static int GnomeCreateWindow ( intf_thread_t *p_intf ); -static void GnomeDestroyWindow ( intf_thread_t *p_intf ); -static void GnomeManageInterface ( intf_thread_t *p_intf ); -static gint GnomeManageMain ( gpointer p_data ); -static void GnomeManageWindow ( intf_thread_t *p_intf ); -static void GnomeEnableScreenSaver ( intf_thread_t *p_intf ); -static void GnomeDisableScreenSaver ( intf_thread_t *p_intf ); -static void GnomeTogglePointer ( intf_thread_t *p_intf ); - diff --git a/plugins/gnome/vout_gnome.c b/plugins/gnome/vout_gnome.c deleted file mode 100644 index fe4443d9cb..0000000000 --- a/plugins/gnome/vout_gnome.c +++ /dev/null @@ -1,696 +0,0 @@ -/***************************************************************************** - * vout_gnome.c: Gnome video output display method - ***************************************************************************** - * Copyright (C) 1998, 1999, 2000 VideoLAN - * - * Authors: - * - * 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 - *****************************************************************************/ -#include "defs.h" - -#include /* ENOMEM */ -#include /* free() */ -#include /* strerror() */ - -#ifdef SYS_BSD -#include /* typedef ushort */ -#endif - -#include /* shmget(), shmctl() */ -#include -#include -#include - -#include "config.h" -#include "common.h" -#include "threads.h" -#include "mtime.h" -#include "plugins.h" - -#include "video.h" -#include "video_output.h" - -#include "intf_msg.h" - -/***************************************************************************** - * vout_sys_t: video output X11 method descriptor - ***************************************************************************** - * This structure is part of the video output thread descriptor. - * It describes the X11 specific properties of an output thread. X11 video - * output is performed through regular resizable windows. Windows can be - * dynamically resized to adapt to the size of the streams. - *****************************************************************************/ -typedef struct vout_sys_s -{ - /* User settings */ - boolean_t b_shm; /* shared memory extension flag */ - - /* Internal settings and properties */ - Display * p_display; /* display pointer */ - Visual * p_visual; /* visual pointer */ - int i_screen; /* screen number */ - Window root_window; /* root window */ - Window window; /* window instance handler */ - GC gc; /* graphic context instance handler */ - Colormap colormap; /* colormap used (8bpp only) */ - - /* Display buffers and shared memory information */ - XImage * p_ximage[2]; /* XImage pointer */ - XShmSegmentInfo shm_info[2]; /* shared memory zone information */ -} vout_sys_t; - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static int X11OpenDisplay ( vout_thread_t *p_vout, char *psz_display, - Window root_window, void *p_data ); -static void X11CloseDisplay ( vout_thread_t *p_vout ); -static int X11CreateWindow ( vout_thread_t *p_vout ); -static void X11DestroyWindow ( vout_thread_t *p_vout ); -static int X11CreateImage ( vout_thread_t *p_vout, XImage **pp_ximage ); -static void X11DestroyImage ( XImage *p_ximage ); -static int X11CreateShmImage ( vout_thread_t *p_vout, XImage **pp_ximage, - XShmSegmentInfo *p_shm_info ); -static void X11DestroyShmImage ( vout_thread_t *p_vout, XImage *p_ximage, - XShmSegmentInfo *p_shm_info ); - -/***************************************************************************** - * vout_GnomeCreate: allocate X11 video thread output method - ***************************************************************************** - * This function allocate and initialize a X11 vout method. It uses some of the - * vout properties to choose the window size, and change them according to the - * actual properties of the display. - *****************************************************************************/ -int vout_GnomeCreate( vout_thread_t *p_vout, char *psz_display, - int i_root_window, void *p_data ) -{ - /* Allocate structure */ - p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); - if( p_vout->p_sys == NULL ) - { - intf_ErrMsg("error: %s", strerror(ENOMEM) ); - return( 1 ); - } - - /* Open and initialize device. This function issues its own error messages. - * Since XLib is usually not thread-safe, we can't use the same display - * pointer than the interface or another thread. However, the root window - * id is still valid. */ - if( X11OpenDisplay( p_vout, psz_display, i_root_window, p_data ) ) - { - intf_ErrMsg("error: can't initialize X11 display" ); - free( p_vout->p_sys ); - return( 1 ); - } - - return( 0 ); -} - -/***************************************************************************** - * vout_GnomeInit: initialize X11 video thread output method - ***************************************************************************** - * This function create the XImages needed by the output thread. It is called - * at the beginning of the thread, but also each time the window is resized. - *****************************************************************************/ -int vout_GnomeInit( vout_thread_t *p_vout ) -{ - int i_err; - - /* Create XImages using XShm extension - on failure, fall back to regular - * way (and destroy the first image if it was created successfully) */ - if( p_vout->p_sys->b_shm ) - { - /* Create first image */ - i_err = X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[0], - &p_vout->p_sys->shm_info[0] ); - if( !i_err ) /* first image has been created */ - { - /* Create second image */ - if( X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[1], - &p_vout->p_sys->shm_info[1] ) ) - { /* error creating the second image */ - X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0], - &p_vout->p_sys->shm_info[0] ); - i_err = 1; - } - } - if( i_err ) /* an error occured */ - { - intf_Msg("vout: XShm video extension deactivated" ); - p_vout->p_sys->b_shm = 0; - } - } - - /* Create XImages without XShm extension */ - if( !p_vout->p_sys->b_shm ) - { - if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[0] ) ) - { - intf_ErrMsg("error: can't create images"); - p_vout->p_sys->p_ximage[0] = NULL; - p_vout->p_sys->p_ximage[1] = NULL; - return( 1 ); - } - if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[1] ) ) - { - intf_ErrMsg("error: can't create images"); - X11DestroyImage( p_vout->p_sys->p_ximage[0] ); - p_vout->p_sys->p_ximage[0] = NULL; - p_vout->p_sys->p_ximage[1] = NULL; - return( 1 ); - } - } - - /* Set bytes per line and initialize buffers */ - p_vout->i_bytes_per_line = p_vout->p_sys->p_ximage[0]->bytes_per_line; - vout_SetBuffers( p_vout, p_vout->p_sys->p_ximage[ 0 ]->data, - p_vout->p_sys->p_ximage[ 1 ]->data ); - return( 0 ); -} - -/***************************************************************************** - * vout_GnomeEnd: terminate X11 video thread output method - ***************************************************************************** - * Destroy the X11 XImages created by vout_SysInit. It is called at the end of - * the thread, but also each time the window is resized. - *****************************************************************************/ -void vout_GnomeEnd( vout_thread_t *p_vout ) -{ - if( p_vout->p_sys->b_shm ) /* Shm XImages... */ - { - X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0], - &p_vout->p_sys->shm_info[0] ); - X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[1], - &p_vout->p_sys->shm_info[1] ); - } - else /* ...or regular XImages */ - { - X11DestroyImage( p_vout->p_sys->p_ximage[0] ); - X11DestroyImage( p_vout->p_sys->p_ximage[1] ); - } -} - -/***************************************************************************** - * vout_GnomeDestroy: destroy X11 video thread output method - ***************************************************************************** - * Terminate an output method created by vout_CreateOutputMethod - *****************************************************************************/ -void vout_GnomeDestroy( vout_thread_t *p_vout ) -{ - X11CloseDisplay( p_vout ); - free( p_vout->p_sys ); -} - -/***************************************************************************** - * vout_GnomeManage: handle X11 events - ***************************************************************************** - * This function should be called regularly by video output thread. It manages - * X11 events and allows window resizing. It returns a non null value on - * error. - *****************************************************************************/ -int vout_GnomeManage( vout_thread_t *p_vout ) -{ - /* - * Color/Grayscale or gamma change: in 8bpp, just change the colormap - */ - if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE) && (p_vout->i_screen_depth == 8) ) - { - /* FIXME: clear flags ?? */ - } - - /* - * Size change - */ - if( p_vout->i_changes & VOUT_SIZE_CHANGE ) - { - intf_DbgMsg("resizing window"); - p_vout->i_changes &= ~VOUT_SIZE_CHANGE; - - /* Resize window */ - XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window, - p_vout->i_width, p_vout->i_height ); - - /* Destroy XImages to change their size */ - vout_GnomeEnd( p_vout ); - - /* Recreate XImages. If SysInit failed, the thread can't go on. */ - if( vout_GnomeInit( p_vout ) ) - { - intf_ErrMsg("error: can't resize display"); - return( 1 ); - } - - /* Tell the video output thread that it will need to rebuild YUV - * tables. This is needed since convertion buffer size may have changed */ - p_vout->i_changes |= VOUT_YUV_CHANGE; - intf_Msg("vout: video display resized (%dx%d)", p_vout->i_width, p_vout->i_height); - } - - return 0; -} - -/***************************************************************************** - * vout_GnomeDisplay: displays previously rendered output - ***************************************************************************** - * This function send the currently rendered image to X11 server, wait until - * it is displayed and switch the two rendering buffer, preparing next frame. - *****************************************************************************/ -void vout_GnomeDisplay( vout_thread_t *p_vout ) -{ - if( p_vout->p_sys->b_shm) /* XShm is used */ - { - /* Display rendered image using shared memory extension */ - XShmPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc, - p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ], - 0, 0, 0, 0, - p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width, - p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height, True); - - /* Send the order to the X server */ - XFlush(p_vout->p_sys->p_display); - } - else /* regular X11 capabilities are used */ - { - XPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc, - p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ], - 0, 0, 0, 0, - p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width, - p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height); - - /* Send the order to the X server */ - XFlush(p_vout->p_sys->p_display); - } -} - -/***************************************************************************** - * vout_GnomeSetPalette: sets an 8 bpp palette - ***************************************************************************** - * This function sets the palette given as an argument. It does not return - * anything, but could later send information on which colors it was unable - * to set. - *****************************************************************************/ -void vout_GnomeSetPalette( p_vout_thread_t p_vout, - u16 *red, u16 *green, u16 *blue, u16 *transp ) -{ - int i; - XColor color[255]; - - intf_DbgMsg( "Palette change called" ); - - /* allocate palette */ - for( i = 0; i < 255; i++ ) - { - /* kludge: colors are indexed reversely because color 255 seems - * to be reserved for black even if we try to set it to white */ - color[i].pixel = 255-i; - color[i].pad = 0; - color[i].flags = DoRed|DoGreen|DoBlue; - color[i].red = red[255-i]; - color[i].blue = blue[255-i]; - color[i].green = green[255-i]; - } - - XStoreColors( p_vout->p_sys->p_display, p_vout->p_sys->colormap, color, 256 ); -} - -/* following functions are local */ - -/***************************************************************************** - * X11OpenDisplay: open and initialize X11 device - ***************************************************************************** - * Create a window according to video output given size, and set other - * properties according to the display properties. - *****************************************************************************/ -static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root_window, void *p_data ) -{ - XPixmapFormatValues * p_xpixmap_format; /* pixmap formats */ - XVisualInfo * p_xvisual; /* visuals informations */ - XVisualInfo xvisual_template; /* visual template */ - int i_count; /* array size */ - - /* Open display */ - p_vout->p_sys->p_display = XOpenDisplay( psz_display ); - if( p_vout->p_sys->p_display == NULL ) - { - intf_ErrMsg("error: can't open display %s", psz_display ); - return( 1 ); - } - - /* Initialize structure */ - p_vout->p_sys->root_window = root_window; - p_vout->p_sys->b_shm = (XShmQueryExtension(p_vout->p_sys->p_display) == True); - p_vout->p_sys->i_screen = DefaultScreen( p_vout->p_sys->p_display ); - if( !p_vout->p_sys->b_shm ) - { - intf_Msg("vout: XShm video extension is not available"); - } - - /* Get screen depth */ - p_vout->i_screen_depth = XDefaultDepth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen ); - switch( p_vout->i_screen_depth ) - { - case 8: - /* - * Screen depth is 8bpp. Use PseudoColor visual with private colormap. - */ - xvisual_template.screen = p_vout->p_sys->i_screen; - xvisual_template.class = DirectColor; - p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask, - &xvisual_template, &i_count ); - if( p_xvisual == NULL ) - { - intf_ErrMsg("error: no PseudoColor visual available"); - XCloseDisplay( p_vout->p_sys->p_display ); - return( 1 ); - } - p_vout->i_bytes_per_pixel = 1; - - /* put the colormap in place */ - p_vout->p_sys->colormap = *(Colormap *)p_data; - break; - case 15: - case 16: - case 24: - default: - /* - * Screen depth is higher than 8bpp. TrueColor visual is used. - */ - xvisual_template.screen = p_vout->p_sys->i_screen; - xvisual_template.class = TrueColor; - p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask, - &xvisual_template, &i_count ); - if( p_xvisual == NULL ) - { - intf_ErrMsg("error: no TrueColor visual available"); - XCloseDisplay( p_vout->p_sys->p_display ); - return( 1 ); - } - p_vout->i_red_mask = p_xvisual->red_mask; - p_vout->i_green_mask = p_xvisual->green_mask; - p_vout->i_blue_mask = p_xvisual->blue_mask; - - /* There is no difference yet between 3 and 4 Bpp. The only way to find - * the actual number of bytes per pixel is to list supported pixmap - * formats. */ - p_xpixmap_format = XListPixmapFormats( p_vout->p_sys->p_display, &i_count ); - p_vout->i_bytes_per_pixel = 0; - - /* Under XFree 4, XListPixmapFormats returns a list of available - * formats under each screen depth ; so we have to select the one - * for the current display. */ - for( ; i_count--; p_xpixmap_format++ ) - { - if( p_vout->i_screen_depth == p_xpixmap_format->depth ) - { - if( p_xpixmap_format->bits_per_pixel / 8 > p_vout->i_bytes_per_pixel ) - { - p_vout->i_bytes_per_pixel = p_xpixmap_format->bits_per_pixel / 8; - } - } - } - break; - } - p_vout->p_sys->p_visual = p_xvisual->visual; - XFree( p_xvisual ); - - /* Create a window */ - if( X11CreateWindow( p_vout ) ) - { - intf_ErrMsg("error: can't open a window"); - XCloseDisplay( p_vout->p_sys->p_display ); - return( 1 ); - } - return( 0 ); -} - -/***************************************************************************** - * X11CloseDisplay: close X11 device - ***************************************************************************** - * Returns all resources allocated by X11OpenDisplay and restore the original - * state of the display. - *****************************************************************************/ -static void X11CloseDisplay( vout_thread_t *p_vout ) -{ - /* Destroy colormap */ - if( p_vout->i_screen_depth == 8 ) - { - XFreeColormap( p_vout->p_sys->p_display, p_vout->p_sys->colormap ); - } - - /* Destroy window */ - X11DestroyWindow( p_vout ); - - /* FIXME: We should close the display here, but X returns an error. */ - //XCloseDisplay( p_vout->p_sys->p_display ); -} - -/***************************************************************************** - * X11CreateWindow: create X11 vout window - ***************************************************************************** - * The video output window will be created. Normally, this window is wether - * full screen or part of a parent window. Therefore, it does not need a - * title or other hints. Thery are still supplied in case the window would be - * spawned as a standalone one by the interface. - *****************************************************************************/ -static int X11CreateWindow( vout_thread_t *p_vout ) -{ - XSetWindowAttributes xwindow_attributes; /* window attributes */ - XGCValues xgcvalues; /* graphic context configuration */ - XEvent xevent; /* first events */ - boolean_t b_expose; /* 'expose' event received */ - boolean_t b_map_notify; /* 'map_notify' event received */ - - /* Prepare window attributes */ - xwindow_attributes.backing_store = Always; /* save the hidden part */ - - /* Create the window and set hints */ - p_vout->p_sys->window = XCreateSimpleWindow( p_vout->p_sys->p_display, - p_vout->p_sys->root_window, - 0, 0, - p_vout->i_width, p_vout->i_height, - 0, 0, 0); - XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window, - ExposureMask | StructureNotifyMask ); - XChangeWindowAttributes( p_vout->p_sys->p_display, p_vout->p_sys->window, - CWBackingStore, &xwindow_attributes); - - /* Creation of a graphic context that doesn't generate a GraphicsExpose event - when using functions like XCopyArea */ - xgcvalues.graphics_exposures = False; - p_vout->p_sys->gc = XCreateGC( p_vout->p_sys->p_display, p_vout->p_sys->window, - GCGraphicsExposures, &xgcvalues); - - /* Send orders to server, and wait until window is displayed - two events - * must be received: a MapNotify event, an Expose event allowing drawing in the - * window */ - b_expose = 0; - b_map_notify = 0; - XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window); - do - { - XNextEvent( p_vout->p_sys->p_display, &xevent); - if( (xevent.type == Expose) - && (xevent.xexpose.window == p_vout->p_sys->window) ) - { - b_expose = 1; - } - else if( (xevent.type == MapNotify) - && (xevent.xmap.window == p_vout->p_sys->window) ) - { - b_map_notify = 1; - } - } - while( !( b_expose && b_map_notify ) ); - XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window, 0 ); - - /* At this stage, the window is open, displayed, and ready to receive - * data */ - return( 0 ); -} - -/***************************************************************************** - * X11DestroyWindow: destroy X11 window - ***************************************************************************** - * Destroy an X11 window created by vout_CreateWindow - *****************************************************************************/ -static void X11DestroyWindow( vout_thread_t *p_vout ) -{ - XUnmapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window ); - XFreeGC( p_vout->p_sys->p_display, p_vout->p_sys->gc ); - XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->window ); -} - -/***************************************************************************** - * X11CreateImage: create an XImage - ***************************************************************************** - * Create a simple XImage used as a buffer. - *****************************************************************************/ -static int X11CreateImage( vout_thread_t *p_vout, XImage **pp_ximage ) -{ - byte_t * pb_data; /* image data storage zone */ - int i_quantum; /* XImage quantum (see below) */ - - /* Allocate memory for image */ - p_vout->i_bytes_per_line = p_vout->i_width * p_vout->i_bytes_per_pixel; - pb_data = (byte_t *) malloc( p_vout->i_bytes_per_line * p_vout->i_height ); - if( !pb_data ) /* error */ - { - intf_ErrMsg("error: %s", strerror(ENOMEM)); - return( 1 ); - } - - /* Optimize the quantum of a scanline regarding its size - the quantum is - a diviser of the number of bits between the start of two scanlines. */ - if( !(( p_vout->i_bytes_per_line ) % 32) ) - { - i_quantum = 32; - } - else - { - if( !(( p_vout->i_bytes_per_line ) % 16) ) - { - i_quantum = 16; - } - else - { - i_quantum = 8; - } - } - - /* Create XImage */ - *pp_ximage = XCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual, - p_vout->i_screen_depth, ZPixmap, 0, pb_data, - p_vout->i_width, p_vout->i_height, i_quantum, 0); - if(! *pp_ximage ) /* error */ - { - intf_ErrMsg( "error: XCreateImage() failed" ); - free( pb_data ); - return( 1 ); - } - - return 0; -} - -/***************************************************************************** - * X11CreateShmImage: create an XImage using shared memory extension - ***************************************************************************** - * Prepare an XImage for DisplayX11ShmImage function. - * The order of the operations respects the recommandations of the mit-shm - * document by J.Corbet and K.Packard. Most of the parameters were copied from - * there. - *****************************************************************************/ -static int X11CreateShmImage( vout_thread_t *p_vout, XImage **pp_ximage, - XShmSegmentInfo *p_shm_info) -{ - /* Create XImage */ - *pp_ximage = XShmCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual, - p_vout->i_screen_depth, ZPixmap, 0, - p_shm_info, p_vout->i_width, p_vout->i_height ); - if(! *pp_ximage ) /* error */ - { - intf_ErrMsg("error: XShmCreateImage() failed"); - return( 1 ); - } - - /* Allocate shared memory segment - 0777 set the access permission - * rights (like umask), they are not yet supported by X servers */ - p_shm_info->shmid = shmget( IPC_PRIVATE, - (*pp_ximage)->bytes_per_line * (*pp_ximage)->height, - IPC_CREAT | 0777); - if( p_shm_info->shmid < 0) /* error */ - { - intf_ErrMsg("error: can't allocate shared image data (%s)", - strerror(errno)); - XDestroyImage( *pp_ximage ); - return( 1 ); - } - - /* Attach shared memory segment to process (read/write) */ - p_shm_info->shmaddr = (*pp_ximage)->data = shmat(p_shm_info->shmid, 0, 0); - if(! p_shm_info->shmaddr ) - { /* error */ - intf_ErrMsg("error: can't attach shared memory (%s)", - strerror(errno)); - shmctl( p_shm_info->shmid, IPC_RMID, 0 ); /* free shared memory */ - XDestroyImage( *pp_ximage ); - return( 1 ); - } - - /* Mark the shm segment to be removed when there will be no more - * attachements, so it is automatic on process exit or after shmdt */ - shmctl( p_shm_info->shmid, IPC_RMID, 0 ); - - /* Attach shared memory segment to X server (read only) */ - p_shm_info->readOnly = True; - if( XShmAttach( p_vout->p_sys->p_display, p_shm_info ) == False ) /* error */ - { - intf_ErrMsg("error: can't attach shared memory to X11 server"); - shmdt( p_shm_info->shmaddr ); /* detach shared memory from process - * and automatic free */ - XDestroyImage( *pp_ximage ); - return( 1 ); - } - - /* Send image to X server. This instruction is required, since having - * built a Shm XImage and not using it causes an error on XCloseDisplay */ - XFlush( p_vout->p_sys->p_display ); - return( 0 ); -} - -/***************************************************************************** - * X11DestroyImage: destroy an XImage - ***************************************************************************** - * Destroy XImage AND associated data. If pointer is NULL, the image won't be - * destroyed (see vout_ManageOutputMethod()) - *****************************************************************************/ -static void X11DestroyImage( XImage *p_ximage ) -{ - if( p_ximage != NULL ) - { - XDestroyImage( p_ximage ); /* no free() required */ - } -} - -/***************************************************************************** - * X11DestroyShmImage - ***************************************************************************** - * Destroy XImage AND associated data. Detach shared memory segment from - * server and process, then free it. If pointer is NULL, the image won't be - * destroyed (see vout_ManageOutputMethod()) - *****************************************************************************/ -static void X11DestroyShmImage( vout_thread_t *p_vout, XImage *p_ximage, - XShmSegmentInfo *p_shm_info ) -{ - /* If pointer is NULL, do nothing */ - if( p_ximage == NULL ) - { - return; - } - - XShmDetach( p_vout->p_sys->p_display, p_shm_info ); /* detach from server */ - XDestroyImage( p_ximage ); - if( shmdt( p_shm_info->shmaddr ) ) /* detach shared memory from process */ - { /* also automatic freeing... */ - intf_ErrMsg( "error: can't detach shared memory (%s)", - strerror(errno) ); - } -} - - diff --git a/plugins/sdl/intf_sdl.c b/plugins/sdl/intf_sdl.c deleted file mode 100644 index 71c9921335..0000000000 --- a/plugins/sdl/intf_sdl.c +++ /dev/null @@ -1,247 +0,0 @@ -/***************************************************************************** - * intf_sdl.c: SDL interface plugin - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: intf_sdl.c,v 1.32 2001/02/08 13:52:35 massiot Exp $ - * - * Authors: - * - * 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 - *****************************************************************************/ -#include "defs.h" - -#include -#include -#include -#include /* for all the SDL stuff */ - -#include "config.h" -#include "common.h" -#include "threads.h" -#include "mtime.h" -#include "plugins.h" - -#include "stream_control.h" -#include "input_ext-intf.h" - -#include "video.h" -#include "video_output.h" - - -#include "interface.h" -#include "intf_msg.h" -#include "keystrokes.h" - -#include "main.h" - -/* local prototype */ -void intf_SDL_Keymap( intf_thread_t * p_intf ); - -/***************************************************************************** - * intf_SDLCreate: initialize and create SDL interface - *****************************************************************************/ -int intf_SDLCreate( intf_thread_t *p_intf ) -{ - /* Check that b_video is set */ - if( !p_main->b_video ) - { - intf_ErrMsg( "error: SDL interface requires a video output thread" ); - return( 1 ); - } - - /* Spawn video output thread */ - p_intf->p_vout = vout_CreateThread( main_GetPszVariable( VOUT_DISPLAY_VAR, - NULL), 0, - main_GetIntVariable( VOUT_WIDTH_VAR, - VOUT_WIDTH_DEFAULT ), - main_GetIntVariable( VOUT_HEIGHT_VAR, - VOUT_HEIGHT_DEFAULT ), - NULL, 0, NULL ); - - if( p_intf->p_vout == NULL ) /* error */ - { - intf_ErrMsg( "error: can't create video output thread" ); - free( p_intf->p_sys ); - return( 1 ); - } - intf_SDL_Keymap( p_intf ); - return( 0 ); -} - -/***************************************************************************** - * intf_SDLDestroy: destroy interface - *****************************************************************************/ -void intf_SDLDestroy( intf_thread_t *p_intf ) -{ - /* Close input thread, if any (blocking) */ - if( p_intf->p_input ) - { - input_DestroyThread( p_intf->p_input, NULL ); - } - - /* Close video output thread, if any (blocking) */ - if( p_intf->p_vout ) - { - vout_DestroyThread( p_intf->p_vout, NULL ); - } -} - - -/***************************************************************************** - * intf_SDLManage: event loop - *****************************************************************************/ -void intf_SDLManage( intf_thread_t *p_intf ) -{ - SDL_Event event; /* SDL event */ - Uint8 i_key; - int i_rate; - - while ( SDL_PollEvent(&event) ) - { - switch (event.type) - { - case SDL_VIDEORESIZE: /* Resizing of window */ - intf_Msg( "intf: video display resized (%dx%d)", event.resize.w - , event.resize.h ); - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->i_width = event.resize.w; - p_intf->p_vout->i_height = event.resize.h; - p_intf->p_vout->i_changes |= VOUT_SIZE_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); - break; - - case SDL_KEYDOWN: /* if a key is pressed */ - i_key = event.key.keysym.sym; - - switch(i_key) - { - case SDLK_f: /* switch to fullscreen */ - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); - break; - - case SDLK_y: /* switch to hard YUV */ - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->i_changes |= VOUT_YUV_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); - break; - - /* FIXME : this is temporary */ - case SDLK_p: - if( p_intf->p_input->stream.control.i_status == PLAYING_S ) - { - input_Pause( p_intf->p_input ); - } - else - { - input_Play( p_intf->p_input ); - } - break; - - case SDLK_a: - i_rate = p_intf->p_input->stream.control.i_rate/2; - if ( i_rate >= MINIMAL_RATE ) - { - input_Forward( p_intf->p_input, i_rate ); - } - break; - - case SDLK_z: - i_rate = p_intf->p_input->stream.control.i_rate*2; - if ( i_rate <= MAXIMAL_RATE ) - { - /* Compensation of int truncature */ - if ( i_rate > 500 && i_rate < 1000 ) - i_rate = 1000; - input_Forward( p_intf->p_input, i_rate ); - } - break; - - case SDLK_j: - /* Jump forwards */ - input_Seek( p_intf->p_input, - p_intf->p_input->stream.i_tell - + p_intf->p_input->stream.i_size / 20 ); - /* gabuzomeu */ - break; - - case SDLK_b: - /* Jump backwards */ - input_Seek( p_intf->p_input, - p_intf->p_input->stream.i_tell - - p_intf->p_input->stream.i_size / 20 ); - break; - - default: - if( intf_ProcessKey( p_intf, (char )i_key ) ) - { - intf_DbgMsg( "unhandled key '%c' (%i)", (char)i_key, i_key ); - } - break; - } - break; - - case SDL_MOUSEBUTTONDOWN: - if( event.button.button == SDL_BUTTON_MIDDLE ) - { - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->i_changes |= VOUT_CURSOR_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); - } - break; - - case SDL_QUIT: - intf_ProcessKey( p_intf, SDLK_q ); - break; - - default: - break; - } - } -} - -void intf_SDL_Keymap(intf_thread_t * p_intf ) -{ - /* p_intf->p_intf_getKey = intf_getKey; */ - intf_AssignKey(p_intf, SDLK_q, INTF_KEY_QUIT, 0); - intf_AssignKey(p_intf, SDLK_ESCAPE, INTF_KEY_QUIT, 0); - /* intf_AssignKey(p_intf,3,'Q'); */ - intf_AssignKey(p_intf, SDLK_0, INTF_KEY_SET_CHANNEL,0); - intf_AssignKey(p_intf, SDLK_1, INTF_KEY_SET_CHANNEL,1); - intf_AssignKey(p_intf, SDLK_2, INTF_KEY_SET_CHANNEL,2); - intf_AssignKey(p_intf, SDLK_3, INTF_KEY_SET_CHANNEL,3); - intf_AssignKey(p_intf, SDLK_4, INTF_KEY_SET_CHANNEL,4); - intf_AssignKey(p_intf, SDLK_5, INTF_KEY_SET_CHANNEL,5); - intf_AssignKey(p_intf, SDLK_6, INTF_KEY_SET_CHANNEL,6); - intf_AssignKey(p_intf, SDLK_7, INTF_KEY_SET_CHANNEL,7); - intf_AssignKey(p_intf, SDLK_8, INTF_KEY_SET_CHANNEL,8); - intf_AssignKey(p_intf, SDLK_9, INTF_KEY_SET_CHANNEL,9); - intf_AssignKey(p_intf, SDLK_PLUS, INTF_KEY_INC_VOLUME, 0); - intf_AssignKey(p_intf, SDLK_MINUS, INTF_KEY_DEC_VOLUME, 0); - intf_AssignKey(p_intf, SDLK_m, INTF_KEY_TOGGLE_VOLUME, 0); - /* intf_AssignKey(p_intf,'M','M'); */ - intf_AssignKey(p_intf, SDLK_g, INTF_KEY_DEC_GAMMA, 0); - /* intf_AssignKey(p_intf,'G','G'); */ - intf_AssignKey(p_intf, SDLK_c, INTF_KEY_TOGGLE_GRAYSCALE, 0); - intf_AssignKey(p_intf, SDLK_SPACE, INTF_KEY_TOGGLE_INTERFACE, 0); - intf_AssignKey(p_intf, SDLK_i, INTF_KEY_TOGGLE_INFO, 0); - intf_AssignKey(p_intf, SDLK_s, INTF_KEY_TOGGLE_SCALING, 0); - -} diff --git a/plugins/sdl/sdl.c b/plugins/sdl/sdl.c index 54a17dfe46..8a1e4b6c83 100644 --- a/plugins/sdl/sdl.c +++ b/plugins/sdl/sdl.c @@ -36,14 +36,12 @@ #include "threads.h" #include "mtime.h" #include "tests.h" -#include "plugins.h" -#include "interface.h" #include "audio_output.h" + #include "video.h" #include "video_output.h" -/* audio includes */ #include "modules.h" #include "modules_inner.h" @@ -59,6 +57,7 @@ MODULE_CONFIG_END * Capabilities defined in the other files. ******************************************************************************/ extern void aout_getfunctions( function_list_t * p_function_list ); +extern void vout_getfunctions( function_list_t * p_function_list ); /***************************************************************************** * InitModule: get the module structure and configuration. @@ -75,6 +74,7 @@ int InitModule( module_t * p_module ) p_module->psz_version = VERSION; p_module->i_capabilities = MODULE_CAPABILITY_NULL + | MODULE_CAPABILITY_VOUT | MODULE_CAPABILITY_AOUT; return( 0 ); @@ -97,6 +97,7 @@ int ActivateModule( module_t * p_module ) } aout_getfunctions( &p_module->p_functions->aout ); + vout_getfunctions( &p_module->p_functions->vout ); p_module->p_config = p_config; @@ -117,82 +118,3 @@ int DeactivateModule( module_t * p_module ) return( 0 ); } -/* old plugin API */ - -/***************************************************************************** - * Exported prototypes - *****************************************************************************/ -static void vout_GetPlugin( p_vout_thread_t p_vout ); -static void intf_GetPlugin( p_intf_thread_t p_intf ); - -/* Video output */ -int vout_SDLCreate ( vout_thread_t *p_vout, char *psz_display, - int i_root_window, void *p_data ); -int vout_SDLInit ( p_vout_thread_t p_vout ); -void vout_SDLEnd ( p_vout_thread_t p_vout ); -void vout_SDLDestroy ( p_vout_thread_t p_vout ); -int vout_SDLManage ( p_vout_thread_t p_vout ); -void vout_SDLDisplay ( p_vout_thread_t p_vout ); -void vout_SDLSetPalette ( p_vout_thread_t p_vout, - u16 *red, u16 *green, u16 *blue, u16 *transp ); -/* Interface */ -int intf_SDLCreate ( p_intf_thread_t p_intf ); -void intf_SDLDestroy ( p_intf_thread_t p_intf ); -void intf_SDLManage ( p_intf_thread_t p_intf ); - - -/***************************************************************************** - * GetConfig: get the plugin structure and configuration - *****************************************************************************/ -plugin_info_t * GetConfig( void ) -{ - plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) ); - - p_info->psz_name = "SDL (video)"; - p_info->psz_version = VERSION; - p_info->psz_author = "the VideoLAN team "; - - p_info->aout_GetPlugin = NULL; - p_info->vout_GetPlugin = vout_GetPlugin; - p_info->intf_GetPlugin = intf_GetPlugin; - p_info->yuv_GetPlugin = NULL; - - - /* if the SDL libraries are there, assume we can enter the - * initialization part at least, even if we fail afterwards */ - - p_info->i_score = 0x100; - - /* If this plugin was requested, score it higher */ - if( TestMethod( VOUT_METHOD_VAR, "sdl" ) ) - { - p_info->i_score += 0x200; - } - - return( p_info ); -} - -/***************************************************************************** - * Following functions are only called through the p_info structure - *****************************************************************************/ - -static void vout_GetPlugin( p_vout_thread_t p_vout ) -{ - p_vout->p_sys_create = vout_SDLCreate; - p_vout->p_sys_init = vout_SDLInit; - p_vout->p_sys_end = vout_SDLEnd; - p_vout->p_sys_destroy = vout_SDLDestroy; - p_vout->p_sys_manage = vout_SDLManage; - p_vout->p_sys_display = vout_SDLDisplay; - p_vout->p_set_palette = vout_SDLSetPalette; - -} - -static void intf_GetPlugin( p_intf_thread_t p_intf ) -{ - p_intf->p_sys_create = intf_SDLCreate; - p_intf->p_sys_destroy = intf_SDLDestroy; - p_intf->p_sys_manage = intf_SDLManage; -} - - diff --git a/plugins/sdl/vout_sdl.c b/plugins/sdl/vout_sdl.c index 45478cc62d..c4e360d8bf 100644 --- a/plugins/sdl/vout_sdl.c +++ b/plugins/sdl/vout_sdl.c @@ -35,21 +35,40 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" +#include "tests.h" +#include "modules.h" + +/* FIXME: it's up to the _interface_ to do this, not the video output */ +#include "stream_control.h" +#include "input_ext-intf.h" #include "video.h" #include "video_output.h" #include "intf_msg.h" +#include "interface.h" +/* FIXME: get rid of this */ +#include "keystrokes.h" #include "main.h" +/***************************************************************************** + * FIXME: this file is ... * + * * + * XXX XXX XXX XXX XXX XXX XXX XXX * + * XXX XXX XXX XXX XXX XXX XXX * + * XXX XXX XXX XXX XXX XXX * + * XXX XXX XXX XXX XXX XXX XXX * + * XXX XXX XXX XXX XXX XXX * + * XXX XXX XXX XXX XXX XXX XXX * + * * + *****************************************************************************/ + /***************************************************************************** * vout_sys_t: video output SDL method descriptor ***************************************************************************** * This structure is part of the video output thread descriptor. * It describes the SDL specific properties of an output thread. *****************************************************************************/ -/* FIXME: SOME CLUELESS MORON DEFINED THIS STRUCTURE IN INTF_SDL.C AS WELL */ typedef struct vout_sys_s { int i_width; @@ -65,39 +84,73 @@ typedef struct vout_sys_s } vout_sys_t; /***************************************************************************** - * Local prototypes + * Local prototypes. *****************************************************************************/ -static int SDLOpenDisplay ( vout_thread_t *p_vout ); -static void SDLCloseDisplay ( vout_thread_t *p_vout ); -static void SDLToggleFullScreen ( vout_thread_t *p_vout ); -static void SDLTogglePointer ( vout_thread_t *p_vout ); +static int vout_Probe ( probedata_t *p_data ); +static int vout_Create ( struct vout_thread_s * ); +static int vout_Init ( struct vout_thread_s * ); +static void vout_End ( struct vout_thread_s * ); +static void vout_Destroy ( struct vout_thread_s * ); +static int vout_Manage ( struct vout_thread_s * ); +static void vout_Display ( struct vout_thread_s * ); + +static int SDLOpenDisplay ( vout_thread_t *p_vout ); +static void SDLCloseDisplay ( vout_thread_t *p_vout ); + /***************************************************************************** - * vout_SDLCreate: allocate SDL video thread output method + * Functions exported as capabilities. They are declared as static so that + * we don't pollute the namespace too much. + *****************************************************************************/ +void vout_getfunctions( function_list_t * p_function_list ) +{ + p_function_list->pf_probe = vout_Probe; + p_function_list->functions.vout.pf_create = vout_Create; + p_function_list->functions.vout.pf_init = vout_Init; + p_function_list->functions.vout.pf_end = vout_End; + p_function_list->functions.vout.pf_destroy = vout_Destroy; + p_function_list->functions.vout.pf_manage = vout_Manage; + p_function_list->functions.vout.pf_display = vout_Display; + p_function_list->functions.vout.pf_setpalette = NULL; +} + +/***************************************************************************** + * intf_Probe: probe the video driver and return a score + ***************************************************************************** + * This function tries to initialize SDL and returns a score to the + * plugin manager so that it can select the best plugin. + *****************************************************************************/ +static int vout_Probe( probedata_t *p_data ) +{ + if( TestMethod( VOUT_METHOD_VAR, "sdl" ) ) + { + return( 999 ); + } + + return( 40 ); +} + +/***************************************************************************** + * vout_Create: allocate SDL video thread output method ***************************************************************************** * This function allocate and initialize a SDL vout method. It uses some of the * vout properties to choose the correct mode, and change them according to the * mode actually used. *****************************************************************************/ -int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display, - int i_root_window, void *p_data ) +int vout_Create( vout_thread_t *p_vout ) { /* Allocate structure */ p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); if( p_vout->p_sys == NULL ) { - intf_ErrMsg( "error: %s", strerror(ENOMEM) ); + intf_ErrMsg( "vout error: can't create p_sys (%s)", strerror(ENOMEM) ); return( 1 ); } - p_vout->p_sys->p_display = NULL; - p_vout->p_sys->p_overlay = NULL; - /* Initialize library */ if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0 ) { - intf_ErrMsg( "error: can't initialize SDL library: %s", - SDL_GetError() ); + intf_ErrMsg( "vout error: can't initialize SDL (%s)", SDL_GetError() ); free( p_vout->p_sys ); return( 1 ); } @@ -105,8 +158,10 @@ int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display, /* Force the software yuv even if it is not used */ /* If we don't do this, p_vout is not correctly initialized and it's impossible to switch between soft/hard yuv */ + /* FIXME: this is a broken way to do !! fix this !! */ p_vout->b_need_render = 1; + p_vout->p_sys->b_cursor = 1; /* TODO should be done with a main_GetInt.. */ p_vout->p_sys->b_fullscreen = main_GetIntVariable( VOUT_FULLSCREEN_VAR, VOUT_FULLSCREEN_DEFAULT ); p_vout->p_sys->b_overlay = main_GetIntVariable( VOUT_OVERLAY_VAR, @@ -116,70 +171,221 @@ int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display, p_vout->p_sys->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR, VOUT_HEIGHT_DEFAULT ); - p_vout->p_sys->b_cursor = 0 ; // TODO should be done with a main_GetInt.. - + p_vout->p_sys->p_display = NULL; + p_vout->p_sys->p_overlay = NULL; + if( SDLOpenDisplay(p_vout) ) { - intf_ErrMsg( "error: can't initialize SDL library: %s", - SDL_GetError() ); - free( p_vout->p_sys ); - return( 1 ); + intf_ErrMsg( "vout error: can't initialize SDL (%s)", SDL_GetError() ); + free( p_vout->p_sys ); + return( 1 ); } + /* FIXME: get rid of this ASAP, it's FUCKING UGLY */ + { intf_thread_t * p_intf = p_main->p_intf; + /* p_intf->p_intf_getKey = intf_getKey; */ + intf_AssignKey(p_intf, SDLK_q, INTF_KEY_QUIT, 0); + intf_AssignKey(p_intf, SDLK_ESCAPE, INTF_KEY_QUIT, 0); + /* intf_AssignKey(p_intf,3,'Q'); */ + intf_AssignKey(p_intf, SDLK_0, INTF_KEY_SET_CHANNEL,0); + intf_AssignKey(p_intf, SDLK_1, INTF_KEY_SET_CHANNEL,1); + intf_AssignKey(p_intf, SDLK_2, INTF_KEY_SET_CHANNEL,2); + intf_AssignKey(p_intf, SDLK_3, INTF_KEY_SET_CHANNEL,3); + intf_AssignKey(p_intf, SDLK_4, INTF_KEY_SET_CHANNEL,4); + intf_AssignKey(p_intf, SDLK_5, INTF_KEY_SET_CHANNEL,5); + intf_AssignKey(p_intf, SDLK_6, INTF_KEY_SET_CHANNEL,6); + intf_AssignKey(p_intf, SDLK_7, INTF_KEY_SET_CHANNEL,7); + intf_AssignKey(p_intf, SDLK_8, INTF_KEY_SET_CHANNEL,8); + intf_AssignKey(p_intf, SDLK_9, INTF_KEY_SET_CHANNEL,9); + intf_AssignKey(p_intf, SDLK_PLUS, INTF_KEY_INC_VOLUME, 0); + intf_AssignKey(p_intf, SDLK_MINUS, INTF_KEY_DEC_VOLUME, 0); + intf_AssignKey(p_intf, SDLK_m, INTF_KEY_TOGGLE_VOLUME, 0); + /* intf_AssignKey(p_intf,'M','M'); */ + intf_AssignKey(p_intf, SDLK_g, INTF_KEY_DEC_GAMMA, 0); + /* intf_AssignKey(p_intf,'G','G'); */ + intf_AssignKey(p_intf, SDLK_c, INTF_KEY_TOGGLE_GRAYSCALE, 0); + intf_AssignKey(p_intf, SDLK_SPACE, INTF_KEY_TOGGLE_INTERFACE, 0); + intf_AssignKey(p_intf, SDLK_i, INTF_KEY_TOGGLE_INFO, 0); + intf_AssignKey(p_intf, SDLK_s, INTF_KEY_TOGGLE_SCALING, 0); } + return( 0 ); } /***************************************************************************** - * vout_SDLInit: initialize SDL video thread output method + * vout_Init: initialize SDL video thread output method ***************************************************************************** * This function initialize the SDL display device. *****************************************************************************/ -int vout_SDLInit( vout_thread_t *p_vout ) +int vout_Init( vout_thread_t *p_vout ) { return( 0 ); } /***************************************************************************** - * vout_SDLEnd: terminate Sys video thread output method + * vout_End: terminate Sys video thread output method ***************************************************************************** * Terminate an output method created by vout_SDLCreate *****************************************************************************/ -void vout_SDLEnd( vout_thread_t *p_vout ) +void vout_End( vout_thread_t *p_vout ) { SDLCloseDisplay( p_vout ); SDL_Quit(); } /***************************************************************************** - * vout_SDLDestroy: destroy Sys video thread output method + * vout_Destroy: destroy Sys video thread output method ***************************************************************************** * Terminate an output method created by vout_SDLCreate *****************************************************************************/ -void vout_SDLDestroy( vout_thread_t *p_vout ) +void vout_Destroy( vout_thread_t *p_vout ) { free( p_vout->p_sys ); } /***************************************************************************** - * vout_SDLManage: handle Sys events + * vout_Manage: handle Sys events ***************************************************************************** * This function should be called regularly by video output thread. It returns * a non null value if an error occured. *****************************************************************************/ -int vout_SDLManage( vout_thread_t *p_vout ) +int vout_Manage( vout_thread_t *p_vout ) { + SDL_Event event; /* SDL event */ + Uint8 i_key; + int i_rate; + + /* FIXME: do this nicely */ + input_thread_t * p_input = p_main->p_intf->p_input; + + /* Process events */ + while( SDL_PollEvent(&event) ) + { + switch( event.type ) + { + case SDL_VIDEORESIZE: /* Resizing of window */ + p_vout->i_width = event.resize.w; + p_vout->i_height = event.resize.h; + p_vout->i_changes |= VOUT_SIZE_CHANGE; + break; + + case SDL_MOUSEBUTTONDOWN: + switch( event.button.button ) + { + case SDL_BUTTON_MIDDLE: + p_vout->i_changes |= VOUT_CURSOR_CHANGE; + break; + + case SDL_BUTTON_RIGHT: + p_main->p_intf->b_menu_change = 1; + break; + } + break; + + case SDL_QUIT: + intf_ProcessKey( p_main->p_intf, SDLK_q ); + break; + + case SDL_KEYDOWN: /* if a key is pressed */ + i_key = event.key.keysym.sym; + + switch( i_key ) + { + case SDLK_f: /* switch to fullscreen */ + p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE; + break; + + case SDLK_y: /* switch to hard YUV */ + p_vout->i_changes |= VOUT_YUV_CHANGE; + break; + + case SDLK_c: /* toggle grayscale */ + p_vout->b_grayscale = ! p_vout->b_grayscale; + p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE; + break; + + case SDLK_i: /* toggle info */ + p_vout->b_info = ! p_vout->b_info; + p_vout->i_changes |= VOUT_INFO_CHANGE; + break; + + case SDLK_s: /* toggle scaling */ + p_vout->b_scale = ! p_vout->b_scale; + p_vout->i_changes |= VOUT_SCALE_CHANGE; + break; + + case SDLK_SPACE: /* toggle interface */ + p_vout->b_interface = ! p_vout->b_interface; + p_vout->i_changes |= VOUT_INTF_CHANGE; + break; + + /* FIXME : this is temporary */ + case SDLK_p: + if( p_input->stream.control.i_status == PLAYING_S ) + { + input_Pause( p_input ); + } + else + { + input_Play( p_input ); + } + break; + + case SDLK_a: + i_rate = p_input->stream.control.i_rate/2; + if ( i_rate >= MINIMAL_RATE ) + { + input_Forward( p_input, i_rate ); + } + break; + + case SDLK_z: + i_rate = p_input->stream.control.i_rate*2; + if ( i_rate <= MAXIMAL_RATE ) + { + /* Compensation of int truncature */ + if ( i_rate > 500 && i_rate < 1000 ) + i_rate = 1000; + input_Forward( p_input, i_rate ); + } + break; + + case SDLK_j: + /* Jump forwards */ + input_Seek( p_input, p_input->stream.i_tell + + p_input->stream.i_size / 20 ); + /* gabuzomeu */ + break; + + case SDLK_b: + /* Jump backwards */ + input_Seek( p_input, p_input->stream.i_tell + - p_input->stream.i_size / 20 ); + break; + + default: + if( intf_ProcessKey( p_main->p_intf, (char )i_key ) ) + { + intf_DbgMsg( "unhandled key '%c' (%i)", (char)i_key, i_key ); } + break; + } + break; + + default: + break; + } + } /* * Size Change */ - if ( p_vout->i_changes & VOUT_SIZE_CHANGE ) + if( p_vout->i_changes & VOUT_SIZE_CHANGE ) { p_vout->p_sys->i_width = p_vout->i_width; p_vout->p_sys->i_height = p_vout->i_height; /* Need to reopen display */ SDLCloseDisplay( p_vout ); - if ( SDLOpenDisplay( p_vout ) ) + if( SDLOpenDisplay( p_vout ) ) { intf_ErrMsg( "error: can't open DISPLAY default display" ); return( 1 ); @@ -190,52 +396,74 @@ int vout_SDLManage( vout_thread_t *p_vout ) /* * YUV Change */ - if ( p_vout->i_changes & VOUT_YUV_CHANGE ) + if( p_vout->i_changes & VOUT_YUV_CHANGE ) { - p_vout->b_need_render = 1 - p_vout->b_need_render; + p_vout->b_need_render = ! p_vout->b_need_render; /* Need to reopen display */ SDLCloseDisplay( p_vout ); - if ( SDLOpenDisplay( p_vout ) ) + if( SDLOpenDisplay( p_vout ) ) { intf_ErrMsg( "error: can't open DISPLAY default display" ); return( 1 ); } p_vout->i_changes &= ~VOUT_YUV_CHANGE; } - + /* * Fullscreen change */ - if ( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE ) + if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE ) { - p_vout->p_sys->b_fullscreen = 1 - p_vout->p_sys->b_fullscreen; - SDLToggleFullScreen( p_vout ); + p_vout->p_sys->b_fullscreen = ! p_vout->p_sys->b_fullscreen; + + if( p_vout->p_sys->b_fullscreen ) + { + p_vout->p_sys->b_fullscreen = 0; + p_vout->p_sys->b_cursor = 1; + SDL_ShowCursor( 1 ); + } + else + { + p_vout->p_sys->b_fullscreen = 1; + p_vout->p_sys->b_cursor = 0; + SDL_ShowCursor( 0 ); + } + + SDL_WM_ToggleFullScreen(p_vout->p_sys->p_display); + p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE; } - - /* * Pointer change */ - if ( p_vout->i_changes & VOUT_CURSOR_CHANGE ) + if( p_vout->i_changes & VOUT_CURSOR_CHANGE ) { - p_vout->p_sys->b_cursor = 1 - p_vout->p_sys->b_cursor; - SDLTogglePointer( p_vout ); + if( p_vout->p_sys->b_cursor ) + { + SDL_ShowCursor( 0 ); + p_vout->p_sys->b_cursor = 0; + } + else + { + SDL_ShowCursor( 1 ); + p_vout->p_sys->b_cursor = 1; + } + p_vout->i_changes &= ~VOUT_CURSOR_CHANGE; } return( 0 ); } /***************************************************************************** - * vout_SDLSetPalette: sets an 8 bpp palette + * vout_SetPalette: sets an 8 bpp palette ***************************************************************************** * This function sets the palette given as an argument. It does not return * anything, but could later send information on which colors it was unable * to set. *****************************************************************************/ -void vout_SDLSetPalette( p_vout_thread_t p_vout, u16 *red, u16 *green, +void vout_SetPalette( p_vout_thread_t p_vout, u16 *red, u16 *green, u16 *blue, u16 *transp) { /* Create a display surface with a grayscale palette */ @@ -251,25 +479,25 @@ void vout_SDLSetPalette( p_vout_thread_t p_vout, u16 *red, u16 *green, } /* Set palette */ - if( SDL_SetColors(p_vout->p_sys->p_display, colors, 0, 256) == 0 ) + if( SDL_SetColors( p_vout->p_sys->p_display, colors, 0, 256 ) == 0 ) { - intf_ErrMsg( "vout error: failed setting palette\n" ); + intf_ErrMsg( "vout error: failed setting palette" ); } } /***************************************************************************** - * vout_SDLDisplay: displays previously rendered output + * vout_Display: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to the display, wait until * it is displayed and switch the two rendering buffer, preparing next frame. *****************************************************************************/ -void vout_SDLDisplay( vout_thread_t *p_vout ) +void vout_Display( vout_thread_t *p_vout ) { SDL_Rect disp; if((p_vout->p_sys->p_display != NULL) && !p_vout->p_sys->b_reopen_display) { - if(p_vout->b_need_render) + if( p_vout->b_need_render ) { /* Change display frame */ SDL_Flip( p_vout->p_sys->p_display ); @@ -383,8 +611,9 @@ static int SDLOpenDisplay( vout_thread_t *p_vout ) SDL_ShowCursor( 1 ); SDL_WM_SetCaption( VOUT_TITLE , VOUT_TITLE ); - SDL_EventState(SDL_KEYUP , SDL_IGNORE); /* ignore keys up */ + SDL_EventState(SDL_KEYUP , SDL_IGNORE); /* ignore keys up */ SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE); + if( p_vout->b_need_render ) { p_vout->p_sys->p_buffer[ 0 ] = p_vout->p_sys->p_display->pixels; @@ -449,51 +678,13 @@ static void SDLCloseDisplay( vout_thread_t *p_vout ) { if( p_vout->p_sys->p_overlay != NULL ) { - SDL_FreeYUVOverlay(p_vout->p_sys->p_overlay); + SDL_FreeYUVOverlay( p_vout->p_sys->p_overlay ); p_vout->p_sys->p_overlay = NULL; } + SDL_UnlockSurface ( p_vout->p_sys->p_display ); SDL_FreeSurface( p_vout->p_sys->p_display ); p_vout->p_sys->p_display = NULL; } } -/***************************************************************************** - * SDLToggleFullScreen: toggle fullscreen - ***************************************************************************** - * This function toggles the fullscreen state of the surface. - * And - hide the pointer if switching to fullscreen - * - show the pointer if leaving fullscreen state - *****************************************************************************/ -static void SDLToggleFullScreen( vout_thread_t *p_vout ) -{ - SDL_WM_ToggleFullScreen(p_vout->p_sys->p_display); - - if( p_vout->p_sys->b_fullscreen ) - { - p_vout->p_sys->b_cursor=1; - } - else - { - p_vout->p_sys->b_cursor=0; - } - - SDLTogglePointer( p_vout ); -} - -/***************************************************************************** - * SDLTogglePointer: Hide/Show mouse pointer - ***************************************************************************** - * This function hides/shows the mouse pointer inside the main window. - *****************************************************************************/ -static void SDLTogglePointer( vout_thread_t *p_vout ) -{ - if( p_vout->p_sys->b_cursor==1 ) - { - SDL_ShowCursor( 0 ); - } - else - { - SDL_ShowCursor( 1 ); - } -} diff --git a/plugins/yuv/video_yuv.c b/plugins/yuv/video_yuv.c index 37e7d12072..cdf8086b23 100644 --- a/plugins/yuv/video_yuv.c +++ b/plugins/yuv/video_yuv.c @@ -227,7 +227,7 @@ static void SetYUV( vout_thread_t *p_vout ) transp[ i_index ] = 0; } /* the colors have been allocated, we can set the palette */ - p_vout->p_set_palette( p_vout, bright, bright, bright, transp ); + p_vout->pf_setpalette( p_vout, bright, bright, bright, transp ); p_vout->i_white_pixel = 0xff; p_vout->i_black_pixel = 0x00; p_vout->i_gray_pixel = 0x44; @@ -325,7 +325,7 @@ static void SetYUV( vout_thread_t *p_vout ) /* the colors have been allocated, we can set the palette */ /* there will eventually be a way to know which colors * couldn't be allocated and try to find a replacement */ - p_vout->p_set_palette( p_vout, red, green, blue, transp ); + p_vout->pf_setpalette( p_vout, red, green, blue, transp ); p_vout->i_white_pixel = 0xff; p_vout->i_black_pixel = 0x00; diff --git a/plugins/yuv/video_yuvmmx.c b/plugins/yuv/video_yuvmmx.c index f7e72990cb..6beae71449 100644 --- a/plugins/yuv/video_yuvmmx.c +++ b/plugins/yuv/video_yuvmmx.c @@ -190,7 +190,7 @@ static void SetYUV( vout_thread_t *p_vout ) transp[ i_index ] = 0; } /* the colors have been allocated, we can set the palette */ - p_vout->p_set_palette( p_vout, bright, bright, bright, transp ); + p_vout->pf_setpalette( p_vout, bright, bright, bright, transp ); p_vout->i_white_pixel = 0xff; p_vout->i_black_pixel = 0x00; p_vout->i_gray_pixel = 0x44; @@ -263,7 +263,7 @@ static void SetYUV( vout_thread_t *p_vout ) /* the colors have been allocated, we can set the palette */ /* there will eventually be a way to know which colors * couldn't be allocated and try to find a replacement */ - p_vout->p_set_palette( p_vout, red, green, blue, transp ); + p_vout->pf_setpalette( p_vout, red, green, blue, transp ); p_vout->i_white_pixel = 0xff; p_vout->i_black_pixel = 0x00; diff --git a/src/ac3_decoder/ac3_decoder_thread.c b/src/ac3_decoder/ac3_decoder_thread.c index 69b4e95f0a..c5bc8f9d42 100644 --- a/src/ac3_decoder/ac3_decoder_thread.c +++ b/src/ac3_decoder/ac3_decoder_thread.c @@ -2,7 +2,7 @@ * ac3_decoder_thread.c: ac3 decoder thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: ac3_decoder_thread.c,v 1.23 2001/01/05 18:46:44 massiot Exp $ + * $Id: ac3_decoder_thread.c,v 1.24 2001/02/11 01:15:10 sam Exp $ * * Authors: * @@ -44,7 +44,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ diff --git a/src/ac3_decoder/ac3_exponent.c b/src/ac3_decoder/ac3_exponent.c index ed0731816b..82ef2bdf52 100644 --- a/src/ac3_decoder/ac3_exponent.c +++ b/src/ac3_decoder/ac3_exponent.c @@ -27,7 +27,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" diff --git a/src/audio_decoder/audio_decoder.c b/src/audio_decoder/audio_decoder.c index 00fdb08870..e110841f45 100644 --- a/src/audio_decoder/audio_decoder.c +++ b/src/audio_decoder/audio_decoder.c @@ -2,7 +2,7 @@ * audio_decoder.c: MPEG audio decoder thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: audio_decoder.c,v 1.46 2001/01/11 17:44:48 sam Exp $ + * $Id: audio_decoder.c,v 1.47 2001/02/11 01:15:10 sam Exp $ * * Authors: Michel Kaempf * Michel Lespinasse @@ -45,7 +45,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ diff --git a/src/audio_output/audio_output.c b/src/audio_output/audio_output.c index a5d3ce568b..219eeb1259 100644 --- a/src/audio_output/audio_output.c +++ b/src/audio_output/audio_output.c @@ -46,7 +46,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" /* mtime_t, mdate(), msleep() */ -#include "plugins.h" #include "modules.h" #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ @@ -112,7 +111,7 @@ aout_thread_t *aout_CreateThread( int *pi_status ) } /* Choose the best module */ - p_aout->p_module = module_Need( p_main->p_module_bank, + p_aout->p_module = module_Need( p_main->p_bank, MODULE_CAPABILITY_AOUT, NULL ); if( p_aout->p_module == NULL ) @@ -135,7 +134,7 @@ aout_thread_t *aout_CreateThread( int *pi_status ) */ if ( p_aout->pf_open( p_aout ) ) { - module_Unneed( p_main->p_module_bank, p_aout->p_module ); + module_Unneed( p_main->p_bank, p_aout->p_module ); free( p_aout ); return( NULL ); } @@ -146,7 +145,7 @@ aout_thread_t *aout_CreateThread( int *pi_status ) if ( p_aout->pf_setformat( p_aout ) ) { p_aout->pf_close( p_aout ); - module_Unneed( p_main->p_module_bank, p_aout->p_module ); + module_Unneed( p_main->p_bank, p_aout->p_module ); free( p_aout ); return( NULL ); } @@ -160,7 +159,7 @@ aout_thread_t *aout_CreateThread( int *pi_status ) if( aout_SpawnThread( p_aout ) ) { p_aout->pf_close( p_aout ); - module_Unneed( p_main->p_module_bank, p_aout->p_module ); + module_Unneed( p_main->p_bank, p_aout->p_module ); free( p_aout ); return( NULL ); } @@ -338,7 +337,7 @@ void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status ) p_aout->pf_close( p_aout ); /* Release the aout module */ - module_Unneed( p_main->p_module_bank, p_aout->p_module ); + module_Unneed( p_main->p_bank, p_aout->p_module ); /* Free structure */ free( p_aout ); diff --git a/src/input/input.c b/src/input/input.c index 02b8429225..43bff2eed1 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -4,7 +4,7 @@ * decoders. ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: input.c,v 1.78 2001/02/08 13:52:35 massiot Exp $ + * $Id: input.c,v 1.79 2001/02/11 01:15:11 sam Exp $ * * Authors: Christophe Massiot * @@ -115,7 +115,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) /* Initialize default settings for spawned decoders */ p_input->p_default_aout = p_main->p_aout; - p_input->p_default_vout = p_main->p_intf->p_vout; + p_input->p_default_vout = p_main->p_vout; /* Create thread and set locks. */ vlc_mutex_init( &p_input->stream.stream_lock ); @@ -268,7 +268,7 @@ static void InitThread( input_thread_t * p_input ) p_input->c_packets_trashed = 0; #endif - p_input->p_input_module = module_Need( p_main->p_module_bank, + p_input->p_input_module = module_Need( p_main->p_bank, MODULE_CAPABILITY_INPUT, NULL ); if( p_input->p_input_module == NULL ) @@ -297,7 +297,7 @@ static void InitThread( input_thread_t * p_input ) if( p_input->b_error ) { - module_Unneed( p_main->p_module_bank, p_input->p_input_module ); + module_Unneed( p_main->p_bank, p_input->p_input_module ); } else { @@ -352,7 +352,7 @@ static void EndThread( input_thread_t * p_input ) p_input->pf_end( p_input ); /* Release modules */ - module_Unneed( p_main->p_module_bank, p_input->p_input_module ); + module_Unneed( p_main->p_bank, p_input->p_input_module ); /* Destroy Mutex locks */ vlc_mutex_destroy( &p_input->stream.control.control_lock ); diff --git a/src/interface/interface.c b/src/interface/interface.c index a9625d8d86..f7a35bedd6 100644 --- a/src/interface/interface.c +++ b/src/interface/interface.c @@ -36,7 +36,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "modules.h" #include "stream_control.h" @@ -47,8 +46,8 @@ #include "intf_msg.h" #include "interface.h" #include "intf_cmd.h" -#include "intf_console.h" #include "intf_plst.h" +#include "intf_channels.h" #include "keystrokes.h" #include "video.h" @@ -56,33 +55,10 @@ #include "main.h" -/***************************************************************************** - * intf_channel_t: channel description - ***************************************************************************** - * A 'channel' is a descriptor of an input method. It is used to switch easily - * from source to source without having to specify the whole input thread - * configuration. The channels array, stored in the interface thread object, is - * loaded in intf_Create, and unloaded in intf_Destroy. - *****************************************************************************/ -typedef struct intf_channel_s -{ - /* Channel description */ - int i_channel; /* channel number, -1 for end of array */ - char * psz_description; /* channel description (owned) */ - - /* Input configuration */ - int i_input_method; /* input method descriptor */ - char * psz_input_source; /* source string (owned) */ - int i_input_port; /* port */ - int i_input_vlan_id; /* vlan id */ -} intf_channel_t; - /***************************************************************************** * Local prototypes *****************************************************************************/ -static int LoadChannels ( intf_thread_t *p_intf, char *psz_filename ); -static void UnloadChannels ( intf_thread_t *p_intf ); -static int ParseChannel ( intf_channel_t *p_channel, char *psz_str ); +static void intf_Manage( intf_thread_t *p_intf ); /***************************************************************************** * intf_Create: prepare interface before main loop @@ -93,9 +69,6 @@ static int ParseChannel ( intf_channel_t *p_channel, char *psz_str ); intf_thread_t* intf_Create( void ) { intf_thread_t * p_intf; - typedef void ( intf_getplugin_t ) ( intf_thread_t * p_intf ); - int i_index; - int i_best_index = 0, i_best_score = 0; /* Allocate structure */ p_intf = malloc( sizeof( intf_thread_t ) ); @@ -106,84 +79,80 @@ intf_thread_t* intf_Create( void ) return( NULL ); } - /* Get a suitable interface plugin */ - for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ ) - { - /* If there's a plugin in p_info ... */ - if( p_main->p_bank->p_info[ i_index ] != NULL ) - { - /* ... and if this plugin provides the functions we want ... */ - if( p_main->p_bank->p_info[ i_index ]->intf_GetPlugin != NULL ) - { - /* ... and if this plugin has a good score ... */ - if( p_main->p_bank->p_info[ i_index ]->i_score > i_best_score ) - { - /* ... then take it */ - i_best_score = p_main->p_bank->p_info[ i_index ]->i_score; - i_best_index = i_index; - } - } - } - } + /* Choose the best module */ + p_intf->p_module = module_Need( p_main->p_bank, + MODULE_CAPABILITY_INTF, NULL ); - if( i_best_score == 0 ) + if( p_intf->p_module == NULL ) { + intf_ErrMsg( "intf error: no suitable intf module" ); free( p_intf ); - intf_ErrMsg( "intf error: no suitable plugin" ); return( NULL ); } - /* Get the plugin functions */ - ( (intf_getplugin_t *) - p_main->p_bank->p_info[ i_best_index ]->intf_GetPlugin )( p_intf ); +#define f p_intf->p_module->p_functions->intf.functions.intf + p_intf->pf_open = f.pf_open; + p_intf->pf_close = f.pf_close; + p_intf->pf_run = f.pf_run; +#undef f + + /* Initialize callbacks */ + p_intf->pf_manage = intf_Manage; /* Initialize structure */ p_intf->b_die = 0; - p_intf->p_vout = NULL; - p_intf->p_input = NULL; - p_intf->p_keys = NULL; - /* Warning level initialisation */ - p_intf->i_warning_level = main_GetIntVariable( INTF_WARNING_VAR, INTF_WARNING_DEFAULT ); - + p_intf->p_input = NULL; + p_intf->p_keys = NULL; + p_intf->b_menu = 0; + p_intf->b_menu_change = 0; + + if( p_intf->pf_open( p_intf ) ) + { + intf_ErrMsg("intf error: cannot create interface"); + module_Unneed( p_main->p_bank, p_intf->p_module ); + free( p_intf ); + return( NULL ); + } + + /* Initialize mutexes */ + vlc_mutex_init( &p_intf->change_lock ); + /* Load channels - the pointer will be set to NULL on failure. The * return value is ignored since the program can work without * channels */ - LoadChannels( p_intf, main_GetPszVariable( INTF_CHANNELS_VAR, INTF_CHANNELS_DEFAULT )); - - /* Start interfaces */ - p_intf->p_console = intf_ConsoleCreate(); - if( p_intf->p_console == NULL ) - { - intf_ErrMsg( "intf error: cannot create control console" ); - free( p_intf ); - return( NULL ); - } - - if( p_intf->p_sys_create( p_intf ) ) - { - intf_ErrMsg("intf error: cannot create interface"); - intf_ConsoleDestroy( p_intf->p_console ); - free( p_intf ); - return( NULL ); - } + intf_LoadChannels( p_intf, main_GetPszVariable( INTF_CHANNELS_VAR, + INTF_CHANNELS_DEFAULT )); intf_Msg("intf: interface initialized"); return( p_intf ); } /***************************************************************************** - * intf_Run + * intf_Manage: manage interface ***************************************************************************** - * Initialization script and main interface loop. + * This function has to be called regularly by the interface plugin. It + * checks for playlist end, module expiration, message flushing, and a few + * other useful things. *****************************************************************************/ -void intf_Run( intf_thread_t *p_intf ) +static void intf_Manage( intf_thread_t *p_intf ) { - /* Flush messages before spawning input */ + /* Flush waiting messages */ intf_FlushMsg(); - /* Main loop */ - while( !p_intf->b_die ) + /* Manage module bank */ + module_ManageBank( p_main->p_bank ); + + if( ( p_intf->p_input != NULL ) && + ( p_intf->p_input->b_error || p_intf->p_input->b_eof ) ) + { + input_DestroyThread( p_intf->p_input, NULL ); + p_intf->p_input = NULL; + intf_DbgMsg("Input thread destroyed"); + } + + /* If no stream is being played, try to find one */ + if( p_intf->p_input == NULL && !p_intf->b_die ) { /* Select the next playlist item */ intf_PlstNext( p_main->p_playlist ); @@ -192,42 +161,11 @@ void intf_Run( intf_thread_t *p_intf ) { /* FIXME: wait for user to add stuff to playlist ? */ p_intf->b_die = 1; - return; } - - p_intf->p_input = - input_CreateThread( &p_main->p_playlist->current, NULL ); - - /* Main loop */ - while( !p_intf->b_die && (p_intf->p_input != NULL) ) + else { - /* Flush waiting messages */ - intf_FlushMsg(); - - /* Manage specific interface */ - p_intf->p_sys_manage( p_intf ); - - /* Manage module bank */ - module_ManageBank( p_main->p_module_bank ); - - /* Check attached threads status */ - if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_error ) - { - /* FIXME: add aout error detection ?? */ - p_intf->b_die = 1; - } - - if( ( p_intf->p_input != NULL ) && - ( p_intf->p_input->b_error || p_intf->p_input->b_eof ) ) - { - input_DestroyThread( p_intf->p_input, NULL ); - p_intf->p_input = NULL; - intf_DbgMsg("Input thread destroyed"); - } - - /* Sleep to avoid using all CPU - since some interfaces needs - * to access keyboard events, a 100ms delay is a good compromise */ - msleep( INTF_IDLE_SLEEP ); + p_intf->p_input = + input_CreateThread( &p_main->p_playlist->current, NULL ); } } } @@ -241,12 +179,18 @@ void intf_Destroy( intf_thread_t *p_intf ) { p_intf_key p_cur; p_intf_key p_next; - /* Destroy interfaces */ - p_intf->p_sys_destroy( p_intf ); - intf_ConsoleDestroy( p_intf->p_console ); /* Unload channels */ - UnloadChannels( p_intf ); + intf_UnloadChannels( p_intf ); + + /* Destroy interfaces */ + p_intf->pf_close( p_intf ); + + /* Close input thread, if any (blocking) */ + if( p_intf->p_input ) + { + input_DestroyThread( p_intf->p_input, NULL ); + } /* Destroy keymap */ p_cur = p_intf->p_keys; @@ -257,56 +201,15 @@ void intf_Destroy( intf_thread_t *p_intf ) p_cur = p_next; } + /* Unlock module */ + module_Unneed( p_main->p_bank, p_intf->p_module ); + + vlc_mutex_destroy( &p_intf->change_lock ); + /* Free structure */ free( p_intf ); } -/***************************************************************************** - * intf_SelectChannel: change channel - ***************************************************************************** - * Kill existing input, if any, and try to open a new one, using an input - * configuration table. - *****************************************************************************/ -int intf_SelectChannel( intf_thread_t * p_intf, int i_channel ) -{ - /* FIXME */ -#if 0 - intf_channel_t * p_channel; /* channel */ - - /* Look for channel in array */ - if( p_intf->p_channel != NULL ) - { - for( p_channel = p_intf->p_channel; p_channel->i_channel != -1; p_channel++ ) - { - if( p_channel->i_channel == i_channel ) - { - /* - * Change channel - */ - - /* Kill existing input, if any */ - if( p_intf->p_input != NULL ) - { - input_DestroyThread( p_intf->p_input, NULL ); - } - - intf_Msg("Channel %d: %s", i_channel, p_channel->psz_description ); - - /* Open a new input */ - p_intf->p_input = input_CreateThread( p_channel->i_input_method, p_channel->psz_input_source, - p_channel->i_input_port, p_channel->i_input_vlan_id, - p_intf->p_vout, p_main->p_aout, NULL ); - return( p_intf->p_input == NULL ); - } - } - } - - /* Channel does not exist */ - intf_Msg("Channel %d does not exist", i_channel ); -#endif - return( 1 ); -} - /***************************************************************************** * intf_AssignKey: assign standartkeys * ***************************************************************************** @@ -444,57 +347,21 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key ) p_main->p_aout->vol = i_volbackup; break; case INTF_KEY_DEC_GAMMA: /* gamma - */ - if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma > -INTF_GAMMA_LIMIT) ) + if( (p_main->p_vout != NULL) && (p_main->p_vout->f_gamma > -INTF_GAMMA_LIMIT) ) { - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->f_gamma -= INTF_GAMMA_STEP; - p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); + vlc_mutex_lock( &p_main->p_vout->change_lock ); + p_main->p_vout->f_gamma -= INTF_GAMMA_STEP; + p_main->p_vout->i_changes |= VOUT_GAMMA_CHANGE; + vlc_mutex_unlock( &p_main->p_vout->change_lock ); } break; case INTF_KEY_INC_GAMMA: /* gamma + */ - if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma < INTF_GAMMA_LIMIT) ) + if( (p_main->p_vout != NULL) && (p_main->p_vout->f_gamma < INTF_GAMMA_LIMIT) ) { - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->f_gamma += INTF_GAMMA_STEP; - p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); - } - break; - case INTF_KEY_TOGGLE_GRAYSCALE: /* toggle grayscale */ - if( p_intf->p_vout != NULL ) - { - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->b_grayscale = !p_intf->p_vout->b_grayscale; - p_intf->p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); - } - break; - case INTF_KEY_TOGGLE_INTERFACE: /* toggle interface */ - if( p_intf->p_vout != NULL ) - { - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->b_interface = !p_intf->p_vout->b_interface; - p_intf->p_vout->i_changes |= VOUT_INTF_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); - } - break; - case INTF_KEY_TOGGLE_INFO: /* toggle info */ - if( p_intf->p_vout != NULL ) - { - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->b_info = !p_intf->p_vout->b_info; - p_intf->p_vout->i_changes |= VOUT_INFO_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); - } - break; - case INTF_KEY_TOGGLE_SCALING: /* toggle scaling */ - if( p_intf->p_vout != NULL ) - { - vlc_mutex_lock( &p_intf->p_vout->change_lock ); - p_intf->p_vout->b_scale = !p_intf->p_vout->b_scale; - p_intf->p_vout->i_changes |= VOUT_SCALE_CHANGE; - vlc_mutex_unlock( &p_intf->p_vout->change_lock ); + vlc_mutex_lock( &p_main->p_vout->change_lock ); + p_main->p_vout->f_gamma += INTF_GAMMA_STEP; + p_main->p_vout->i_changes |= VOUT_GAMMA_CHANGE; + vlc_mutex_unlock( &p_main->p_vout->change_lock ); } break; default: /* unknown key */ @@ -504,243 +371,3 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key ) return( 0 ); } -/* following functions are local */ - -/***************************************************************************** - * LoadChannels: load channels description from a file - ***************************************************************************** - * This structe describes all interface-specific data of the main (interface) - * thread. - * Each line of the file is a semicolon separated list of the following - * fields : - * integer channel number - * string channel description - * integer input method (see input.h) - * string input source - * integer input port - * integer input vlan id - * The last field must end with a semicolon. - * Comments and empty lines are not explicitely allowed, but lines with parsing - * errors are ignored without warning. - *****************************************************************************/ -static int LoadChannels( intf_thread_t *p_intf, char *psz_filename ) -{ - FILE * p_file; /* file */ - intf_channel_t * p_channel; /* current channel */ - char psz_line[INTF_MAX_CMD_SIZE]; /* line buffer */ - int i_index; /* channel or field index */ - - /* Set default value */ - p_intf->p_channel = NULL; - - /* FIXME: channels are disabled */ - //return( 0 ); - - /* Open file */ - p_file = fopen( psz_filename, "r" ); - if( p_file == NULL ) - { - intf_DbgMsg( "intf warning: cannot open %s (%s)", - psz_filename, strerror(errno) ); - return( 1 ); - } - - /* First pass: count number of lines */ - for( i_index = 0; fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL; i_index++ ) - { - ; - } - - if( i_index != 0 ) - { - /* Allocate array and rewind - some of the lines may be invalid, and the - * array will probably be larger than the actual number of channels, but - * it has no consequence. */ - p_intf->p_channel = malloc( sizeof( intf_channel_t ) * i_index ); - if( p_intf->p_channel == NULL ) - { - intf_ErrMsg( "intf error: cannot create intf_channel_t (%s)", - strerror(ENOMEM) ); - fclose( p_file ); - return( 1 ); - } - p_channel = p_intf->p_channel; - rewind( p_file ); - - /* Second pass: read channels descriptions */ - while( fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL ) - { - if( !ParseChannel( p_channel, psz_line ) ) - { - intf_DbgMsg( "channel [%d] %s : method %d (%s:%d vlan id %d)", - p_channel->i_channel, p_channel->psz_description, - p_channel->i_input_method, - p_channel->psz_input_source, - p_channel->i_input_port, p_channel->i_input_vlan_id ); - p_channel++; - } - } - - /* Add marker at the end of the array */ - p_channel->i_channel = -1; - } - - /* Close file */ - fclose( p_file ); - return( 0 ); -} - -/***************************************************************************** - * UnloadChannels: unload channels description - ***************************************************************************** - * This function free all resources allocated by LoadChannels, if any. - *****************************************************************************/ -static void UnloadChannels( intf_thread_t *p_intf ) -{ - int i_channel; /* channel index */ - - if( p_intf->p_channel != NULL ) - { - /* Free allocated strings */ - for( i_channel = 0; - p_intf->p_channel[ i_channel ].i_channel != -1; - i_channel++ ) - { - if( p_intf->p_channel[ i_channel ].psz_description != NULL ) - { - free( p_intf->p_channel[ i_channel ].psz_description ); - } - if( p_intf->p_channel[ i_channel ].psz_input_source != NULL ) - { - free( p_intf->p_channel[ i_channel ].psz_input_source ); - } - } - - /* Free array */ - free( p_intf->p_channel ); - p_intf->p_channel = NULL; - } -} - - -/***************************************************************************** - * ParseChannel: parse a channel description line - ***************************************************************************** - * See LoadChannels. This function return non 0 on parsing error. - *****************************************************************************/ -static int ParseChannel( intf_channel_t *p_channel, char *psz_str ) -{ - char * psz_index; /* current character */ - char * psz_end; /* end pointer for strtol */ - int i_field; /* field number, -1 on error */ - int i_field_length; /* field length, for text fields */ - - /* Set some default fields */ - p_channel->i_channel = 0; - p_channel->psz_description = NULL; - p_channel->i_input_method = 0; - p_channel->psz_input_source = NULL; - p_channel->i_input_port = 0; - p_channel->i_input_vlan_id = 0; - - /* Parse string */ - i_field = 0; - for( psz_index = psz_str; (i_field != -1) && (*psz_index != '\0'); psz_index++ ) - { - if( *psz_index == ';' ) - { - /* Mark end of field */ - *psz_index = '\0'; - - /* Parse field */ - switch( i_field++ ) - { - case 0: /* channel number */ - p_channel->i_channel = strtol( psz_str, &psz_end, 0); - if( (*psz_str == '\0') || (*psz_end != '\0') ) - { - i_field = -1; - } - break; - case 1: /* channel description */ - i_field_length = strlen( psz_str ); - if( i_field_length != 0 ) - { - p_channel->psz_description = malloc( i_field_length + 1 ); - if( p_channel->psz_description == NULL ) - { - intf_ErrMsg( "intf error: cannot create channel " - "description (%s)", strerror( ENOMEM ) ); - i_field = -1; - } - else - { - strcpy( p_channel->psz_description, psz_str ); - } - } - break; - case 2: /* input method */ - p_channel->i_input_method = strtol( psz_str, &psz_end, 0); - if( (*psz_str == '\0') || (*psz_end != '\0') ) - { - i_field = -1; - } - break; - case 3: /* input source */ - i_field_length = strlen( psz_str ); - if( i_field_length != 0 ) - { - p_channel->psz_input_source = malloc( i_field_length + 1 ); - if( p_channel->psz_input_source == NULL ) - { - intf_ErrMsg( "intf error: cannot create input " - "source (%s)", strerror( ENOMEM ) ); - i_field = -1; - } - else - { - strcpy( p_channel->psz_input_source, psz_str ); - } - } - break; - case 4: /* input port */ - p_channel->i_input_port = strtol( psz_str, &psz_end, 0); - if( (*psz_str == '\0') || (*psz_end != '\0') ) - { - i_field = -1; - } - break; - case 5: /* input vlan id */ - p_channel->i_input_vlan_id = strtol( psz_str, &psz_end, 0); - if( (*psz_str == '\0') || (*psz_end != '\0') ) - { - i_field = -1; - } - break; - /* ... following fields are ignored */ - } - - /* Set new beginning of field */ - psz_str = psz_index + 1; - } - } - - /* At least the first three fields must be parsed sucessfully for function - * success. Other parsing errors are returned using i_field = -1. */ - if( i_field < 3 ) - { - /* Function fails. Free allocated strings */ - if( p_channel->psz_description != NULL ) - { - free( p_channel->psz_description ); - } - if( p_channel->psz_input_source != NULL ) - { - free( p_channel->psz_input_source ); - } - return( 1 ); - } - - /* Return success */ - return( 0 ); -} diff --git a/src/interface/intf_channels.c b/src/interface/intf_channels.c new file mode 100644 index 0000000000..f6ad68111a --- /dev/null +++ b/src/interface/intf_channels.c @@ -0,0 +1,332 @@ +/***************************************************************************** + * intf_channels.c: channel handling functions + ***************************************************************************** + * Copyright (C) 1998, 1999, 2000 VideoLAN + * + * Authors: + * + * 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 + *****************************************************************************/ +#include "defs.h" + +#include /* ENOMEM */ +#include /* free(), strtol() */ +#include /* FILE */ +#include /* strerror() */ + +#include "config.h" +#include "common.h" +#include "threads.h" +#include "mtime.h" + +#include "intf_msg.h" +#include "intf_channels.h" +#include "interface.h" + +#include "main.h" + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ +static int ParseChannel( intf_channel_t *p_channel, char *psz_str ); + +/***************************************************************************** + * intf_LoadChannels: load channels description from a file + ***************************************************************************** + * This structe describes all interface-specific data of the main (interface) + * thread. + * Each line of the file is a semicolon separated list of the following + * fields : + * integer channel number + * string channel description + * integer input method (see input.h) + * string input source + * integer input port + * integer input vlan id + * The last field must end with a semicolon. + * Comments and empty lines are not explicitely allowed, but lines with parsing + * errors are ignored without warning. + *****************************************************************************/ +int intf_LoadChannels( intf_thread_t *p_intf, char *psz_filename ) +{ + FILE * p_file; /* file */ + intf_channel_t * p_channel; /* current channel */ + char psz_line[INTF_MAX_CMD_SIZE]; /* line buffer */ + int i_index; /* channel or field index */ + + /* Set default value */ + p_intf->p_channel = NULL; + + /* Open file */ + p_file = fopen( psz_filename, "r" ); + if( p_file == NULL ) + { + intf_DbgMsg( "intf warning: cannot open %s (%s)", + psz_filename, strerror(errno) ); + return( 1 ); + } + + /* First pass: count number of lines */ + for( i_index = 0; fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL; + i_index++ ) + { + ; + } + + if( i_index != 0 ) + { + /* Allocate array and rewind - some of the lines may be invalid, and the + * array will probably be larger than the actual number of channels, but + * it has no consequence. */ + p_intf->p_channel = malloc( sizeof( intf_channel_t ) * i_index ); + if( p_intf->p_channel == NULL ) + { + intf_ErrMsg( "intf error: cannot create intf_channel_t (%s)", + strerror(ENOMEM) ); + fclose( p_file ); + return( 1 ); + } + p_channel = p_intf->p_channel; + rewind( p_file ); + + /* Second pass: read channels descriptions */ + while( fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL ) + { + if( !ParseChannel( p_channel, psz_line ) ) + { + intf_DbgMsg( "channel [%d] %s : method %d (%s:%d vlan id %d)", + p_channel->i_channel, p_channel->psz_description, + p_channel->i_input_method, + p_channel->psz_input_source, + p_channel->i_input_port, p_channel->i_input_vlan_id ); + p_channel++; + } + } + + /* Add marker at the end of the array */ + p_channel->i_channel = -1; + } + + /* Close file */ + fclose( p_file ); + return( 0 ); +} + +/***************************************************************************** + * intf_UnloadChannels: unload channels description + ***************************************************************************** + * This function free all resources allocated by LoadChannels, if any. + *****************************************************************************/ +void intf_UnloadChannels( intf_thread_t *p_intf ) +{ + int i_channel; /* channel index */ + + if( p_intf->p_channel != NULL ) + { + /* Free allocated strings */ + for( i_channel = 0; + p_intf->p_channel[ i_channel ].i_channel != -1; + i_channel++ ) + { + if( p_intf->p_channel[ i_channel ].psz_description != NULL ) + { + free( p_intf->p_channel[ i_channel ].psz_description ); + } + if( p_intf->p_channel[ i_channel ].psz_input_source != NULL ) + { + free( p_intf->p_channel[ i_channel ].psz_input_source ); + } + } + + /* Free array */ + free( p_intf->p_channel ); + p_intf->p_channel = NULL; + } +} + +/***************************************************************************** + * intf_SelectChannel: change channel + ***************************************************************************** + * Kill existing input, if any, and try to open a new one, using an input + * configuration table. + *****************************************************************************/ +int intf_SelectChannel( intf_thread_t * p_intf, int i_channel ) +{ + /* FIXME */ +#if 0 + intf_channel_t * p_channel; /* channel */ + + /* Look for channel in array */ + if( p_intf->p_channel != NULL ) + { + for( p_channel = p_intf->p_channel; p_channel->i_channel != -1; p_channel++ ) + { + if( p_channel->i_channel == i_channel ) + { + /* + * Change channel + */ + + /* Kill existing input, if any */ + if( p_intf->p_input != NULL ) + { + input_DestroyThread( p_intf->p_input, NULL ); + } + + intf_Msg("Channel %d: %s", i_channel, p_channel->psz_description ); + + /* Open a new input */ + p_intf->p_input = input_CreateThread( p_channel->i_input_method, p_channel->psz_input_source, + p_channel->i_input_port, p_channel->i_input_vlan_id, + p_intf->p_vout, p_main->p_aout, NULL ); + return( p_intf->p_input == NULL ); + } + } + } + + /* Channel does not exist */ + intf_Msg("Channel %d does not exist", i_channel ); +#endif + return( 1 ); +} + +/* Following functions are local */ + +/***************************************************************************** + * ParseChannel: parse a channel description line + ***************************************************************************** + * See intf_LoadChannels. This function return non 0 on parsing error. + *****************************************************************************/ +static int ParseChannel( intf_channel_t *p_channel, char *psz_str ) +{ + char * psz_index; /* current character */ + char * psz_end; /* end pointer for strtol */ + int i_field; /* field number, -1 on error */ + int i_field_length; /* field length, for text fields */ + + /* Set some default fields */ + p_channel->i_channel = 0; + p_channel->psz_description = NULL; + p_channel->i_input_method = 0; + p_channel->psz_input_source = NULL; + p_channel->i_input_port = 0; + p_channel->i_input_vlan_id = 0; + + /* Parse string */ + i_field = 0; + for( psz_index = psz_str; (i_field != -1) && (*psz_index != '\0'); psz_index++ ) + { + if( *psz_index == ';' ) + { + /* Mark end of field */ + *psz_index = '\0'; + + /* Parse field */ + switch( i_field++ ) + { + case 0: /* channel number */ + p_channel->i_channel = strtol( psz_str, &psz_end, 0); + if( (*psz_str == '\0') || (*psz_end != '\0') ) + { + i_field = -1; + } + break; + case 1: /* channel description */ + i_field_length = strlen( psz_str ); + if( i_field_length != 0 ) + { + p_channel->psz_description = malloc( i_field_length + 1 ); + if( p_channel->psz_description == NULL ) + { + intf_ErrMsg( "intf error: cannot create channel " + "description (%s)", strerror( ENOMEM ) ); + i_field = -1; + } + else + { + strcpy( p_channel->psz_description, psz_str ); + } + } + break; + case 2: /* input method */ + p_channel->i_input_method = strtol( psz_str, &psz_end, 0); + if( (*psz_str == '\0') || (*psz_end != '\0') ) + { + i_field = -1; + } + break; + case 3: /* input source */ + i_field_length = strlen( psz_str ); + if( i_field_length != 0 ) + { + p_channel->psz_input_source = malloc( i_field_length + 1 ); + if( p_channel->psz_input_source == NULL ) + { + intf_ErrMsg( "intf error: cannot create input " + "source (%s)", strerror( ENOMEM ) ); + i_field = -1; + } + else + { + strcpy( p_channel->psz_input_source, psz_str ); + } + } + break; + case 4: /* input port */ + p_channel->i_input_port = strtol( psz_str, &psz_end, 0); + if( (*psz_str == '\0') || (*psz_end != '\0') ) + { + i_field = -1; + } + break; + case 5: /* input vlan id */ + p_channel->i_input_vlan_id = strtol( psz_str, &psz_end, 0); + if( (*psz_str == '\0') || (*psz_end != '\0') ) + { + i_field = -1; + } + break; + /* ... following fields are ignored */ + } + + /* Set new beginning of field */ + psz_str = psz_index + 1; + } + } + + /* At least the first three fields must be parsed sucessfully for function + * success. Other parsing errors are returned using i_field = -1. */ + if( i_field < 3 ) + { + /* Function fails. Free allocated strings */ + if( p_channel->psz_description != NULL ) + { + free( p_channel->psz_description ); + } + if( p_channel->psz_input_source != NULL ) + { + free( p_channel->psz_input_source ); + } + return( 1 ); + } + + /* Return success */ + return( 0 ); +} + diff --git a/src/interface/intf_channels.h b/src/interface/intf_channels.h new file mode 100644 index 0000000000..133101b01f --- /dev/null +++ b/src/interface/intf_channels.h @@ -0,0 +1,50 @@ +/***************************************************************************** + * intf_channels.h: Channel handling functions + ***************************************************************************** + * Copyright (C) 1998, 1999, 2000 VideoLAN + * + * Authors: + * + * 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. + *****************************************************************************/ + +/***************************************************************************** + * intf_channel_t: channel description + ***************************************************************************** + * A 'channel' is a descriptor of an input method. It is used to switch easily + * from source to source without having to specify the whole input thread + * configuration. The channels array, stored in the interface thread object, is + * loaded in intf_Create, and unloaded in intf_Destroy. + *****************************************************************************/ +typedef struct intf_channel_s +{ + /* Channel description */ + int i_channel; /* channel number, -1 for end of array */ + char * psz_description; /* channel description (owned) */ + + /* Input configuration */ + int i_input_method; /* input method descriptor */ + char * psz_input_source; /* source string (owned) */ + int i_input_port; /* port */ + int i_input_vlan_id; /* vlan id */ +} intf_channel_t; + +/***************************************************************************** + * Prototypes + *****************************************************************************/ +int intf_LoadChannels ( struct intf_thread_s *, char * ); +void intf_UnloadChannels ( struct intf_thread_s * ); +int intf_SelectChannel ( struct intf_thread_s *, int ); + diff --git a/src/interface/intf_cmd.c b/src/interface/intf_cmd.c index 7f1262d08f..7d1302d6e7 100644 --- a/src/interface/intf_cmd.c +++ b/src/interface/intf_cmd.c @@ -37,7 +37,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "interface.h" #include "intf_msg.h" diff --git a/src/interface/intf_ctrl.c b/src/interface/intf_ctrl.c index 723f88664b..d6e21e9111 100644 --- a/src/interface/intf_ctrl.c +++ b/src/interface/intf_ctrl.c @@ -54,7 +54,6 @@ #include "threads.h" #include "mtime.h" #include "debug.h" -#include "plugins.h" #include "intf_msg.h" #include "stream_control.h" diff --git a/src/interface/intf_msg.c b/src/interface/intf_msg.c index 9a8d709012..64e454b8d1 100644 --- a/src/interface/intf_msg.c +++ b/src/interface/intf_msg.c @@ -39,7 +39,7 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" + #include "intf_msg.h" #include "interface.h" #include "intf_console.h" @@ -224,7 +224,7 @@ void intf_WarnMsg( int i_level, char *psz_format, ... ) { va_list ap; - if( i_level >= p_main->p_intf->i_warning_level ) + if( i_level >= p_main->i_warning_level ) { va_start( ap, psz_format ); QueueMsg( p_main->p_msg, INTF_MSG_WARN, psz_format, ap ); @@ -316,7 +316,7 @@ void intf_WarnMsgImm( int i_level, char *psz_format, ... ) { va_list ap; - if( i_level >= p_main->p_intf->i_warning_level ) + if( i_level >= p_main->i_warning_level ) { va_start( ap, psz_format ); QueueMsg( p_main->p_msg, INTF_MSG_WARN, psz_format, ap ); diff --git a/src/interface/intf_plst.c b/src/interface/intf_plst.c index 36292d1432..69c5c16a66 100644 --- a/src/interface/intf_plst.c +++ b/src/interface/intf_plst.c @@ -85,7 +85,7 @@ void intf_PlstInit ( playlist_t * p_playlist ) /* The playlist is empty */ p_playlist->p_item = NULL; - intf_Msg("intf: playlist initialized"); + intf_WarnMsg( 1, "intf: playlist initialized" ); } /***************************************************************************** @@ -235,7 +235,7 @@ void intf_PlstDestroy( playlist_t * p_playlist ) free( p_playlist ); - intf_Msg("intf: playlist destroyed"); + intf_WarnMsg( 1, "intf: playlist destroyed" ); } /***************************************************************************** diff --git a/src/interface/main.c b/src/interface/main.c index 8a5de7439d..7cba67b8fa 100644 --- a/src/interface/main.c +++ b/src/interface/main.c @@ -44,8 +44,8 @@ #include "threads.h" #include "mtime.h" #include "tests.h" /* TestCPU() */ -#include "plugins.h" #include "modules.h" + #include "stream_control.h" #include "input_ext-intf.h" @@ -55,6 +55,9 @@ #include "audio_output.h" +#include "video.h" +#include "video_output.h" + #ifdef SYS_BEOS #include "beos_specific.h" #endif @@ -167,6 +170,7 @@ main_t *p_main; static void SetDefaultConfiguration ( void ); static int GetConfiguration ( int i_argc, char *ppsz_argv[], char *ppsz_env[] ); +static int GetFilenames ( int i_argc, char *ppsz_argv[] ); static void Usage ( int i_fashion ); static void Version ( void ); @@ -198,15 +202,15 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) #endif p_main->i_cpu_capabilities = CPUCapabilities(); - + /* * Test if our code is likely to run on this CPU */ #if defined( __pentium__ ) || defined( __pentiumpro__ ) if( ! TestCPU( CPU_CAPABILITY_586 ) ) { - fprintf( stderr, "Sorry, this program needs a Pentium CPU.\n" - "Please try a version without Pentium support.\n" ); + fprintf( stderr, "error: this program needs a Pentium CPU,\n" + "please try a version without Pentium support\n" ); return( 1 ); } #endif @@ -214,8 +218,8 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) #ifdef HAVE_MMX if( ! TestCPU( CPU_CAPABILITY_MMX ) ) { - fprintf( stderr, "Sorry, this program needs MMX extensions.\n" - "Please try a version without MMX support.\n" ); + fprintf( stderr, "error: this program needs MMX extensions,\n" + "please try a version without MMX support\n" ); return( 1 ); } #endif @@ -233,6 +237,18 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) intf_MsgImm( COPYRIGHT_MESSAGE ); + /* + * Read configuration + */ + if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) ) /* parse cmd line */ + { + intf_MsgDestroy(); + return( errno ); + } + + p_main->i_warning_level = main_GetIntVariable( INTF_WARNING_VAR, + INTF_WARNING_DEFAULT ); + /* * Initialize playlist and get commandline files */ @@ -246,40 +262,22 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) intf_PlstInit( p_main->p_playlist ); /* - * Read configuration + * Get input filenames given as commandline arguments */ - if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) ) /* parse cmd line */ - { - intf_MsgDestroy(); - return( errno ); - } - - /* - * Initialize plugin bank - */ - p_main->p_bank = bank_Create( ); - if( !p_main->p_bank ) - { - intf_ErrMsg( "plugin error: plugin bank initialization failed" ); - intf_PlstDestroy( p_main->p_playlist ); - intf_MsgDestroy(); - return( errno ); - } - bank_Init( p_main->p_bank ); + GetFilenames( i_argc, ppsz_argv ); /* * Initialize module bank */ - p_main->p_module_bank = module_CreateBank( ); - if( !p_main->p_module_bank ) + p_main->p_bank = module_CreateBank( ); + if( !p_main->p_bank ) { intf_ErrMsg( "module error: module bank initialization failed" ); - bank_Destroy( p_main->p_bank ); intf_PlstDestroy( p_main->p_playlist ); intf_MsgDestroy(); return( errno ); } - module_InitBank( p_main->p_module_bank ); + module_InitBank( p_main->p_bank ); /* * Initialize shared resources and libraries @@ -299,45 +297,76 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) * Run interface */ p_main->p_intf = intf_Create(); - - if( p_main->p_intf != NULL ) + if( !p_main->p_intf ) { - /* - * Set signal handling policy for all threads - */ - InitSignalHandler(); + intf_ErrMsg( "intf error: interface initialization failed" ); + module_DestroyBank( p_main->p_bank ); + intf_PlstDestroy( p_main->p_playlist ); + intf_MsgDestroy(); + return( errno ); + } - /* - * Open audio device and start aout thread - */ - if( p_main->b_audio ) + /* + * Set signal handling policy for all threads + */ + InitSignalHandler(); + + /* + * Open audio device and start aout thread + */ + if( p_main->b_audio ) + { + p_main->p_aout = aout_CreateThread( NULL ); + if( p_main->p_aout == NULL ) { - p_main->p_aout = aout_CreateThread( NULL ); - if( p_main->p_aout == NULL ) - { - /* On error during audio initialization, switch off audio */ - intf_ErrMsg( "aout error: audio initialization failed," - " audio is deactivated" ); - p_main->b_audio = 0; - } + /* On error during audio initialization, switch off audio */ + intf_ErrMsg( "aout error: audio initialization failed," + " audio is deactivated" ); + p_main->b_audio = 0; } + } - /* - * This is the main loop - */ - intf_Run( p_main->p_intf ); - - intf_Destroy( p_main->p_intf ); - - /* - * Close audio device - */ - if( p_main->b_audio ) + /* + * Open video device and start aout thread + */ + if( p_main->b_video ) + { + p_main->p_vout = vout_CreateThread( NULL ); + if( p_main->p_vout == NULL ) { - aout_DestroyThread( p_main->p_aout, NULL ); + /* On error during video initialization, switch off audio */ + intf_ErrMsg( "vout error: video initialization failed," + " video is deactivated" ); + p_main->b_video = 0; } } + /* Flush messages before entering the main loop */ + intf_FlushMsg(); + + /* + * This is the main loop + */ + p_main->p_intf->pf_run( p_main->p_intf ); + + intf_Destroy( p_main->p_intf ); + + /* + * Close video device + */ + if( p_main->b_video ) + { + vout_DestroyThread( p_main->p_vout, NULL ); + } + + /* + * Close audio device + */ + if( p_main->b_audio ) + { + aout_DestroyThread( p_main->p_aout, NULL ); + } + /* * Free shared resources and libraries */ @@ -352,12 +381,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) /* * Free module bank */ - module_DestroyBank( p_main->p_module_bank ); - - /* - * Free plugin bank - */ - bank_Destroy( p_main->p_bank ); + module_DestroyBank( p_main->p_bank ); /* * Free playlist @@ -374,7 +398,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) /* * Terminate messages interface and program */ - intf_Msg( "intf: program terminated." ); + intf_Msg( "intf: program terminated" ); intf_MsgDestroy(); return( 0 ); @@ -493,7 +517,7 @@ static void SetDefaultConfiguration( void ) *****************************************************************************/ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) { - int c, i_opt; + int c; char * p_pointer; /* Set default configuration and copy arguments */ @@ -644,6 +668,17 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) } } #endif + return( 0 ); +} + +/***************************************************************************** + * GetFilenames: parse command line options which are not flags + ***************************************************************************** + * Parse command line for input files. + *****************************************************************************/ +static int GetFilenames( int i_argc, char *ppsz_argv[] ) +{ + int i_opt; /* We assume that the remaining parameters are filenames */ for( i_opt = optind; i_opt < i_argc; i_opt++ ) @@ -798,7 +833,7 @@ static void InitSignalHandler( void ) static void SimpleSignalHandler( int i_signal ) { /* Acknowledge the signal received */ - intf_WarnMsg(0, "intf: ignoring signal %d", i_signal ); + intf_WarnMsg( 0, "intf: ignoring signal %d", i_signal ); } @@ -810,15 +845,15 @@ static void SimpleSignalHandler( int i_signal ) *****************************************************************************/ static void FatalSignalHandler( int i_signal ) { - /* Once a signal has been trapped, the termination sequence will be armed and - * following signals will be ignored to avoid sending messages to an interface - * having been destroyed */ + /* Once a signal has been trapped, the termination sequence will be + * armed and following signals will be ignored to avoid sending messages + * to an interface having been destroyed */ signal( SIGHUP, SIG_IGN ); signal( SIGINT, SIG_IGN ); signal( SIGQUIT, SIG_IGN ); /* Acknowledge the signal received */ - intf_ErrMsgImm("intf error: signal %d received, exiting", i_signal ); + intf_ErrMsgImm( "intf error: signal %d received, exiting", i_signal ); /* Try to terminate everything - this is done by requesting the end of the * interface thread */ diff --git a/src/lpcm_decoder/lpcm_decoder.c b/src/lpcm_decoder/lpcm_decoder.c index dd8cdcb8ca..754d21a9a9 100644 --- a/src/lpcm_decoder/lpcm_decoder.c +++ b/src/lpcm_decoder/lpcm_decoder.c @@ -26,7 +26,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" diff --git a/src/lpcm_decoder/lpcm_decoder_thread.c b/src/lpcm_decoder/lpcm_decoder_thread.c index 8104b50a84..75af82c6e7 100644 --- a/src/lpcm_decoder/lpcm_decoder_thread.c +++ b/src/lpcm_decoder/lpcm_decoder_thread.c @@ -2,7 +2,7 @@ * lpcm_decoder_thread.c: lpcm decoder thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: lpcm_decoder_thread.c,v 1.9 2001/01/05 18:46:44 massiot Exp $ + * $Id: lpcm_decoder_thread.c,v 1.10 2001/02/11 01:15:11 sam Exp $ * * Authors: * @@ -35,7 +35,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ diff --git a/src/misc/modules.c b/src/misc/modules.c index 475ecd3feb..9fe25ed9b8 100644 --- a/src/misc/modules.c +++ b/src/misc/modules.c @@ -95,7 +95,7 @@ void module_InitBank( module_bank_t * p_bank ) p_bank->first = NULL; vlc_mutex_init( &p_bank->lock ); - intf_Msg( "module: module bank initialized" ); + intf_WarnMsg( 1, "module: module bank initialized" ); for( ; *ppsz_path != NULL ; ppsz_path++ ) { @@ -308,7 +308,11 @@ module_t * module_Need( module_bank_t *p_bank, /* We release the global lock */ vlc_mutex_unlock( &p_bank->lock ); - intf_WarnMsg( 1, "module: locking module `%s'", p_bestmodule->psz_name ); + if( p_bestmodule != NULL ) + { + intf_WarnMsg( 1, "module: locking module `%s'", + p_bestmodule->psz_name ); + } /* Don't forget that the module is still locked if bestmodule != NULL */ return( p_bestmodule ); @@ -357,8 +361,8 @@ static int AllocateDynModule( module_bank_t * p_bank, char * psz_filename ) if( module_load( psz_filename, &handle ) ) { /* The dynamic module couldn't be opened */ - intf_ErrMsg( "module warning: cannot open %s (%s)", - psz_filename, module_error() ); + intf_WarnMsgImm( 1, "module warning: cannot open %s (%s)", + psz_filename, module_error() ); return( -1 ); } diff --git a/src/misc/plugins.c b/src/misc/plugins.c deleted file mode 100644 index 8f44a374eb..0000000000 --- a/src/misc/plugins.c +++ /dev/null @@ -1,252 +0,0 @@ -/***************************************************************************** - * plugins.c : Dynamic plugin management functions - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * - * Authors: - * - * 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. - *****************************************************************************/ -#include "defs.h" - -#include "config.h" - -#include /* free(), strtol() */ -#include /* sprintf() */ -#include /* strerror() */ -#include /* ENOMEM */ -#include /* open */ -#include -#include -#include /* close */ - -#if defined(HAVE_DLFCN_H) /* Linux, BSD, Hurd */ -#include /* dlopen(), dlsym(), dlclose() */ - -#elif defined(HAVE_IMAGE_H) /* BeOS */ -#include - -#else -#error no dynamic plugins available on your system ! -#endif - -#ifdef SYS_BEOS -#include "beos_specific.h" -#endif - -#include "common.h" - -#include "intf_msg.h" -#include "plugins.h" - -/* Local prototypes */ -char * TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name ); -int AllocatePlugin ( plugin_id_t plugin_id, plugin_bank_t * p_bank, - char * psz_filename ); - -plugin_bank_t * bank_Create( void ) -{ - plugin_bank_t *p_bank; - int i; - - /* Allocate structure */ - p_bank = malloc( sizeof( plugin_bank_t ) ); - if( !p_bank ) - { - intf_ErrMsg("plugin error: failed to create bank (%s)", strerror( ENOMEM ) ); - return( NULL ); - } - - /* Initialize structure */ - for( i = 0 ; i < MAX_PLUGIN_COUNT ; i++ ) - { - p_bank->p_info[ i ] = NULL; - } - p_bank->i_plugin_count = MAX_PLUGIN_COUNT; - - return( p_bank ); -} - -void bank_Init( plugin_bank_t * p_bank ) -{ - plugin_id_t tmp; - char * psz_filename; - - /* FIXME: we should browse all directories to get plugins */ -#define SEEK_PLUGIN( name ) \ - psz_filename = TestPlugin( &tmp, name ); \ - if( psz_filename ) AllocatePlugin( tmp, p_bank, psz_filename ); - - /* Arch plugins */ - SEEK_PLUGIN( "beos" ); - - /* Low level Video */ - SEEK_PLUGIN( "x11" ); - SEEK_PLUGIN( "fb" ); - SEEK_PLUGIN( "glide" ); - SEEK_PLUGIN( "mga" ); - - /* High level Video */ - SEEK_PLUGIN( "gnome" ); - SEEK_PLUGIN( "ggi" ); - SEEK_PLUGIN( "sdl" ); - - /* Dummy plugin */ - SEEK_PLUGIN( "dummy" ); -#undef SEEK_PLUGIN - - intf_Msg("plugin: plugin bank initialized [OBSOLETE]"); -} - -void bank_Destroy( plugin_bank_t * p_bank ) -{ - int i; - for( i = 0 ; i < p_bank->i_plugin_count ; i++ ) - { - if( p_bank->p_info[ i ] != NULL ) - { - free( p_bank->p_info[ i ]-> psz_filename ); - } - } - - free( p_bank ); -} - -/* - * Following functions are local - */ - -char * TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name ) -{ - int i_count, i_length, i_fd; - char * psz_plugin; - char * psz_plugin_path[ ] = - { - ".", - "lib", /* this one should disappear */ - PLUGIN_PATH, - NULL - }; - - i_length = strlen( psz_name ); - - for ( i_count = 0 ; psz_plugin_path[ i_count ] ; i_count++ ) - { -#ifdef SYS_BEOS - char * psz_program_path; - - psz_program_path = beos_GetProgramPath(); - psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + - strlen(psz_program_path) + i_length + 6 ); - sprintf( psz_plugin, "%s/%s/%s.so", psz_program_path, - psz_plugin_path[i_count], psz_name ); - - *p_plugin_id = load_add_on( psz_plugin ); -#else - psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 5 ); - sprintf( psz_plugin, "%s/%s.so", psz_plugin_path[i_count], psz_name ); - - /* Try to open the plugin before dlopen()ing it. */ - i_fd = open( psz_plugin, O_RDONLY ); - if( i_fd == -1 ) - { - free( psz_plugin ); - continue; - } - close( i_fd ); - - *p_plugin_id = dlopen( psz_plugin, RTLD_NOW ); -#endif - -#ifdef SYS_BEOS - if( *p_plugin_id >= 0 ) -#else - if( *p_plugin_id != NULL ) -#endif - { - /* plugin successfuly dlopened */ - return( psz_plugin ); - } - -#ifndef SYS_BEOS - intf_ErrMsg( "plugin error: cannot open %s (%s)", psz_plugin, dlerror() ); -#endif - - free( psz_plugin ); - } - - return( NULL ); -} - - -int AllocatePlugin( plugin_id_t plugin_id, plugin_bank_t * p_bank, - char * psz_filename ) -{ - typedef plugin_info_t * ( get_config_t ) ( void ); - get_config_t * p_func; - int i; - - for( i = 0 ; i < p_bank->i_plugin_count ; i++ ) - { - if( p_bank->p_info[ i ] == NULL ) - { - break; - } - } - - /* no room to store that plugin, quit */ - if( i == p_bank->i_plugin_count ) - { - intf_ErrMsg( "plugin bank error: reached max plugin count (%i), " - "increase MAX_PLUGIN_COUNT", p_bank->i_plugin_count ); - return( -1 ); - } - - /* system-specific dynamic symbol loading */ - GET_PLUGIN( p_func, plugin_id, "GetConfig" ); - - /* if it failed, just quit */ - if( !p_func ) - { - return( -1 ); - } - - /* run the plugin function to initialize the structure */ - p_bank->p_info[ i ] = p_func( ); - p_bank->p_info[ i ]->plugin_id = plugin_id; - p_bank->p_info[ i ]->psz_filename = strdup( psz_filename ); - - - /* Tell the world we found it */ - intf_Msg( "plugin: #%i, %s %s (score 0x%x)", i, - p_bank->p_info[ i ]->psz_name, - p_bank->p_info[ i ]->psz_version, - p_bank->p_info[ i ]->i_score ); - - /* return nicely */ - return( 0 ); -} - -#if 0 -void TrashPlugin ( plugin_id_t plugin_id ) -{ -#ifdef SYS_BEOS - unload_add_on( plugin_id ); -#else - dlclose( plugin_id ); -#endif -} -#endif - diff --git a/src/spu_decoder/spu_decoder.c b/src/spu_decoder/spu_decoder.c index 692d81301e..b7e7109c1b 100644 --- a/src/spu_decoder/spu_decoder.c +++ b/src/spu_decoder/spu_decoder.c @@ -32,7 +32,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" #include "debug.h" /* ASSERT */ diff --git a/src/video_decoder/video_decoder.c b/src/video_decoder/video_decoder.c index e14c23f2c6..8215925ba3 100644 --- a/src/video_decoder/video_decoder.c +++ b/src/video_decoder/video_decoder.c @@ -2,7 +2,7 @@ * video_decoder.c : video decoder thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video_decoder.c,v 1.45 2001/01/18 05:13:23 sam Exp $ + * $Id: video_decoder.c,v 1.46 2001/02/11 01:15:11 sam Exp $ * * Authors: Christophe Massiot * Gaël Hendryckx @@ -35,7 +35,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 64203da143..2ddf26675f 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -41,7 +41,8 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" +#include "modules.h" + #include "video.h" #include "video_output.h" #include "video_text.h" @@ -49,6 +50,7 @@ #include "video_yuv.h" #include "intf_msg.h" + #include "main.h" /***************************************************************************** @@ -90,15 +92,11 @@ static void SetPalette ( p_vout_thread_t p_vout, u16 *red, * If pi_status is NULL, then the function will block until the thread is ready. * If not, it will be updated using one of the THREAD_* constants. *****************************************************************************/ -vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, - int i_width, int i_height, int *pi_status, - int i_method, void *p_data ) +vout_thread_t * vout_CreateThread ( int *pi_status ) { vout_thread_t * p_vout; /* thread descriptor */ - typedef void ( vout_getplugin_t ) ( vout_thread_t * p_vout ); int i_status; /* thread status */ int i_index; /* index for array initialization */ - int i_best_index = 0, i_best_score = 0; /* Allocate descriptor */ p_vout = (vout_thread_t *) malloc( sizeof(vout_thread_t) ); @@ -109,37 +107,31 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, return( NULL ); } - p_vout->p_set_palette = SetPalette; + /* Choose the best module */ + p_vout->p_module = module_Need( p_main->p_bank, + MODULE_CAPABILITY_VOUT, NULL ); - /* Get a suitable video plugin */ - for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ ) - { - /* If there's a plugin in p_info ... */ - if( p_main->p_bank->p_info[ i_index ] != NULL ) - { - /* ... and if this plugin provides the functions we want ... */ - if( p_main->p_bank->p_info[ i_index ]->vout_GetPlugin != NULL ) - { - /* ... and if this plugin has a good score ... */ - if( p_main->p_bank->p_info[ i_index ]->i_score > i_best_score ) - { - /* ... then take it */ - i_best_score = p_main->p_bank->p_info[ i_index ]->i_score; - i_best_index = i_index; - } - } - } - } - - if( i_best_score == 0 ) + if( p_vout->p_module == NULL ) { + intf_ErrMsg( "vout error: no suitable vout module" ); free( p_vout ); return( NULL ); } - /* Get the plugin functions */ - ( (vout_getplugin_t *) - p_main->p_bank->p_info[ i_best_index ]->vout_GetPlugin )( p_vout ); +#define f p_vout->p_module->p_functions->vout.functions.vout + p_vout->pf_create = f.pf_create; + p_vout->pf_init = f.pf_init; + p_vout->pf_end = f.pf_end; + p_vout->pf_destroy = f.pf_destroy; + p_vout->pf_manage = f.pf_manage; + p_vout->pf_display = f.pf_display; + p_vout->pf_setpalette = f.pf_setpalette; +#undef f + + if( p_vout->pf_setpalette == NULL ) + { + p_vout->pf_setpalette = SetPalette; + } /* Initialize thread properties - thread id and locks will be initialized * later */ @@ -153,16 +145,18 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, * fields will probably be modified by the method, and are only * preferences */ p_vout->i_changes = 0; - p_vout->i_width = i_width; - p_vout->i_height = i_height; - p_vout->i_bytes_per_line = i_width * 2; + p_vout->i_width = main_GetIntVariable( VOUT_WIDTH_VAR, + VOUT_WIDTH_DEFAULT ); + p_vout->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR, + VOUT_HEIGHT_DEFAULT ); + p_vout->i_bytes_per_line = p_vout->i_width * 2; p_vout->i_screen_depth = 15; p_vout->i_bytes_per_pixel = 2; p_vout->f_gamma = VOUT_GAMMA; p_vout->b_need_render = 1; p_vout->b_grayscale = main_GetIntVariable( VOUT_GRAYSCALE_VAR, - VOUT_GRAYSCALE_DEFAULT ); + VOUT_GRAYSCALE_DEFAULT ); p_vout->b_info = 0; p_vout->b_interface = 0; p_vout->b_scale = 1; @@ -199,8 +193,9 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, /* Create and initialize system-dependant method - this function issues its * own error messages */ - if( p_vout->p_sys_create( p_vout, psz_display, i_root_window, p_data ) ) + if( p_vout->pf_create( p_vout ) ) { + module_Unneed( p_main->p_bank, p_vout->p_module ); free( p_vout ); return( NULL ); } @@ -235,7 +230,7 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, if( p_vout->p_default_font == NULL ) { intf_ErrMsg( "vout error: could not load default font" ); - p_vout->p_sys_destroy( p_vout ); + p_vout->pf_destroy( p_vout ); free( p_vout ); return( NULL ); } @@ -248,7 +243,7 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, { intf_ErrMsg( "vout error: could not load large font" ); vout_UnloadFont( p_vout->p_default_font ); - p_vout->p_sys_destroy( p_vout ); + p_vout->pf_destroy( p_vout ); free( p_vout ); return( NULL ); } @@ -264,7 +259,7 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, intf_ErrMsg("vout error: %s", strerror(ENOMEM)); vout_UnloadFont( p_vout->p_default_font ); vout_UnloadFont( p_vout->p_large_font ); - p_vout->p_sys_destroy( p_vout ); + p_vout->pf_destroy( p_vout ); free( p_vout ); return( NULL ); } @@ -930,7 +925,7 @@ static int InitThread( vout_thread_t *p_vout ) #endif /* Initialize output method - this function issues its own error messages */ - if( p_vout->p_sys_init( p_vout ) ) + if( p_vout->pf_init( p_vout ) ) { return( 1 ); } @@ -1191,7 +1186,7 @@ static void RunThread( vout_thread_t *p_vout) #endif if( b_display /* && !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) */ ) { - p_vout->p_sys_display( p_vout ); + p_vout->pf_display( p_vout ); #ifndef SYS_BEOS p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1; #endif @@ -1217,7 +1212,7 @@ static void RunThread( vout_thread_t *p_vout) /* * Check events and manage thread */ - if( p_vout->p_sys_manage( p_vout ) | Manage( p_vout ) ) + if( p_vout->pf_manage( p_vout ) | Manage( p_vout ) ) { /* A fatal error occured, and the thread must terminate immediately, * without displaying anything - setting b_error to 1 cause the @@ -1299,7 +1294,7 @@ static void EndThread( vout_thread_t *p_vout ) /* Destroy translation tables */ vout_EndYUV( p_vout ); - p_vout->p_sys_end( p_vout ); + p_vout->pf_end( p_vout ); /* Release the change lock */ vlc_mutex_unlock( &p_vout->change_lock ); @@ -1321,13 +1316,16 @@ static void DestroyThread( vout_thread_t *p_vout, int i_status ) /* Destroy thread structures allocated by Create and InitThread */ vout_UnloadFont( p_vout->p_default_font ); vout_UnloadFont( p_vout->p_large_font ); - p_vout->p_sys_destroy( p_vout ); + p_vout->pf_destroy( p_vout ); /* Destroy the locks */ vlc_mutex_destroy( &p_vout->picture_lock ); vlc_mutex_destroy( &p_vout->subpicture_lock ); vlc_mutex_destroy( &p_vout->change_lock ); + /* Release the module */ + module_Unneed( p_main->p_bank, p_vout->p_module ); + /* Free structure */ free( p_vout ); *pi_status = i_status; @@ -2076,7 +2074,7 @@ static int Manage( vout_thread_t *p_vout ) /* Detect unauthorized changes */ if( p_vout->i_changes ) { - /* Some changes were not acknowledged by p_vout->p_sys_manage or this + /* Some changes were not acknowledged by p_vout->pf_manage or this * function, it means they should not be authorized */ intf_ErrMsg( "vout error: unauthorized changes in the vout thread" ); return( 1 ); diff --git a/src/video_output/video_spu.c b/src/video_output/video_spu.c index 6a6fd83bac..bc9aa9c9b7 100644 --- a/src/video_output/video_spu.c +++ b/src/video_output/video_spu.c @@ -32,8 +32,8 @@ #include "config.h" #include "common.h" #include "threads.h" -#include "plugins.h" #include "mtime.h" + #include "video.h" #include "video_output.h" #include "video_spu.h" diff --git a/src/video_output/video_yuv.c b/src/video_output/video_yuv.c index 432d89e1c3..0b0a95486d 100644 --- a/src/video_output/video_yuv.c +++ b/src/video_output/video_yuv.c @@ -55,7 +55,7 @@ int vout_InitYUV( vout_thread_t *p_vout ) { /* Choose the best module */ - p_vout->yuv.p_module = module_Need( p_main->p_module_bank, + p_vout->yuv.p_module = module_Need( p_main->p_bank, MODULE_CAPABILITY_YUV, NULL ); if( p_vout->yuv.p_module == NULL ) @@ -93,6 +93,6 @@ int vout_ResetYUV( vout_thread_t *p_vout ) void vout_EndYUV( vout_thread_t *p_vout ) { p_vout->yuv.pf_end( p_vout ); - module_Unneed( p_main->p_module_bank, p_vout->yuv.p_module ); + module_Unneed( p_main->p_bank, p_vout->yuv.p_module ); } diff --git a/src/video_parser/video_fifo.c b/src/video_parser/video_fifo.c index c42aa1647b..1de3967595 100644 --- a/src/video_parser/video_fifo.c +++ b/src/video_parser/video_fifo.c @@ -2,7 +2,7 @@ * video_fifo.c : video FIFO management ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video_fifo.c,v 1.28 2001/01/18 05:13:23 sam Exp $ + * $Id: video_fifo.c,v 1.29 2001/02/11 01:15:12 sam Exp $ * * Authors: Christophe Massiot * @@ -30,7 +30,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" diff --git a/src/video_parser/video_parser.c b/src/video_parser/video_parser.c index 417f48c6ab..60ee502139 100644 --- a/src/video_parser/video_parser.c +++ b/src/video_parser/video_parser.c @@ -2,7 +2,7 @@ * video_parser.c : video parser thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video_parser.c,v 1.72 2001/02/08 17:44:13 massiot Exp $ + * $Id: video_parser.c,v 1.73 2001/02/11 01:15:12 sam Exp $ * * Authors: Christophe Massiot * Samuel Hocevar @@ -40,7 +40,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "modules.h" #include "intf_msg.h" @@ -104,7 +103,7 @@ vlc_thread_t vpar_CreateThread( vdec_config_t * p_config ) /* * Choose the best motion compensation module */ - p_vpar->p_motion_module = module_Need( p_main->p_module_bank, + p_vpar->p_motion_module = module_Need( p_main->p_bank, MODULE_CAPABILITY_MOTION, NULL ); if( p_vpar->p_motion_module == NULL ) @@ -170,13 +169,13 @@ vlc_thread_t vpar_CreateThread( vdec_config_t * p_config ) /* * Choose the best IDCT module */ - p_vpar->p_idct_module = module_Need( p_main->p_module_bank, + p_vpar->p_idct_module = module_Need( p_main->p_bank, MODULE_CAPABILITY_IDCT, NULL ); if( p_vpar->p_idct_module == NULL ) { intf_ErrMsg( "vpar error: no suitable IDCT module" ); - module_Unneed( p_main->p_module_bank, p_vpar->p_motion_module ); + module_Unneed( p_main->p_bank, p_vpar->p_motion_module ); free( p_vpar ); return( 0 ); } @@ -193,8 +192,8 @@ vlc_thread_t vpar_CreateThread( vdec_config_t * p_config ) (vlc_thread_func_t)RunThread, (void *)p_vpar ) ) { intf_ErrMsg("vpar error: can't spawn video parser thread"); - module_Unneed( p_main->p_module_bank, p_vpar->p_idct_module ); - module_Unneed( p_main->p_module_bank, p_vpar->p_motion_module ); + module_Unneed( p_main->p_bank, p_vpar->p_idct_module ); + module_Unneed( p_main->p_bank, p_vpar->p_motion_module ); free( p_vpar ); return( 0 ); } @@ -511,8 +510,8 @@ static void EndThread( vpar_thread_t *p_vpar ) vlc_mutex_destroy( &(p_vpar->synchro.fifo_lock) ); - module_Unneed( p_main->p_module_bank, p_vpar->p_idct_module ); - module_Unneed( p_main->p_module_bank, p_vpar->p_motion_module ); + module_Unneed( p_main->p_bank, p_vpar->p_idct_module ); + module_Unneed( p_main->p_bank, p_vpar->p_motion_module ); free( p_vpar ); diff --git a/src/video_parser/vpar_blocks.c b/src/video_parser/vpar_blocks.c index df772cb603..e4e723bd6f 100644 --- a/src/video_parser/vpar_blocks.c +++ b/src/video_parser/vpar_blocks.c @@ -2,7 +2,7 @@ * vpar_blocks.c : blocks parsing ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_blocks.c,v 1.74 2001/01/26 14:47:16 massiot Exp $ + * $Id: vpar_blocks.c,v 1.75 2001/02/11 01:15:12 sam Exp $ * * Authors: Christophe Massiot * Jean-Marc Dressler @@ -34,7 +34,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" diff --git a/src/video_parser/vpar_headers.c b/src/video_parser/vpar_headers.c index c93da0a4fb..e32a0b7386 100644 --- a/src/video_parser/vpar_headers.c +++ b/src/video_parser/vpar_headers.c @@ -2,7 +2,7 @@ * vpar_headers.c : headers parsing ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_headers.c,v 1.76 2001/02/06 17:17:04 massiot Exp $ + * $Id: vpar_headers.c,v 1.77 2001/02/11 01:15:12 sam Exp $ * * Authors: Christophe Massiot * Stéphane Borel @@ -33,7 +33,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" diff --git a/src/video_parser/vpar_synchro.c b/src/video_parser/vpar_synchro.c index 5e2c8aa1d7..14ddc8db3b 100644 --- a/src/video_parser/vpar_synchro.c +++ b/src/video_parser/vpar_synchro.c @@ -2,7 +2,7 @@ * vpar_synchro.c : frame dropping routines ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_synchro.c,v 1.80 2001/01/24 19:05:55 massiot Exp $ + * $Id: vpar_synchro.c,v 1.81 2001/02/11 01:15:12 sam Exp $ * * Authors: Christophe Massiot * Samuel Hocevar @@ -100,7 +100,6 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h"