Commit c7b1c474 authored by Sam Hocevar's avatar Sam Hocevar

  * ./include/modules_inner.h: replaced _X with __VLC_SYMBOL because _X was
    already a system macro under MacOS X.
  * ./plugins/dummy/dummy.c: fixed vlc:loop, vlc:quit, etc. entries.
  * ./plugins/glide/glide.c: activated double buffering.
  * ./plugins/mga/xmga.c: started writing an xmga plugin; doesn't work yet.
  * ./src/input/input.c: fixed the input memory leak, and the insane thread
    spawning we got with vlc:loop.
  * ./src/misc/intf_eject.c: disc ejection routine courtesy of Julien Blache,
    currently Linux-only.
parent 1ae5bed4
...@@ -38,6 +38,10 @@ E: jobi@via.ecp.fr ...@@ -38,6 +38,10 @@ E: jobi@via.ecp.fr
C: jobi C: jobi
D: VCD input D: VCD input
N: Julien Blache
E: jb@technologeek.org
D: Disc ejection code
N: Emmanuel Blindauer N: Emmanuel Blindauer
E: manu@agat.net E: manu@agat.net
D: aRts audio output D: aRts audio output
......
List of known vlc bugs List of known vlc bugs
$Id: BUGS,v 1.3 2002/01/05 16:09:49 sam Exp $ $Id: BUGS,v 1.4 2002/01/09 02:01:14 sam Exp $
Please try to keep this file up to date. Also, grep for FIXME in the Please try to keep this file up to date. Also, grep for FIXME in the
source files for more and more bugs to fix. source files for more and more bugs to fix.
...@@ -17,10 +17,7 @@ Core: ...@@ -17,10 +17,7 @@ Core:
Input: Input:
* There is a memory leak in the input because the input thread is -
never joined for termination.
* vlc:foo targets don't work anymore.
Audio output: Audio output:
...@@ -37,8 +34,6 @@ Video output: ...@@ -37,8 +34,6 @@ Video output:
* The DirectX video output plugin is broken because of vout4. * The DirectX video output plugin is broken because of vout4.
* The GGI video output plugin is broken because of vout4.
* The BeOS video output plugin is broken because of vout4. * The BeOS video output plugin is broken because of vout4.
* The QNX video output plugin is broken because of vout4. * The QNX video output plugin is broken because of vout4.
...@@ -69,3 +64,8 @@ Gtk interface: ...@@ -69,3 +64,8 @@ Gtk interface:
* Saving preferences does not work at all. * Saving preferences does not work at all.
Misc:
* The Jin-Roh DVD seems to segfault.
...@@ -100,6 +100,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \ ...@@ -100,6 +100,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \
memcpy/memcpymmxext \ memcpy/memcpymmxext \
memcpy/memcpy3dn \ memcpy/memcpy3dn \
mga/mga \ mga/mga \
mga/xmga \
motion/motion \ motion/motion \
motion/motionmmx \ motion/motionmmx \
motion/motionmmxext \ motion/motionmmxext \
...@@ -122,7 +123,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \ ...@@ -122,7 +123,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \
# #
# C Objects # C Objects
# #
INTERFACE := main interface intf_msg intf_playlist INTERFACE := main interface intf_msg intf_playlist intf_eject
INPUT := input input_ext-dec input_ext-intf input_dec input_programs input_clock mpeg_system INPUT := input input_ext-dec input_ext-intf input_dec input_programs input_clock mpeg_system
VIDEO_OUTPUT := video_output video_text vout_pictures vout_subpictures VIDEO_OUTPUT := video_output video_text vout_pictures vout_subpictures
AUDIO_OUTPUT := audio_output aout_ext-dec aout_u8 aout_s8 aout_u16 aout_s16 aout_spdif AUDIO_OUTPUT := audio_output aout_ext-dec aout_u8 aout_s8 aout_u16 aout_s16 aout_spdif
......
...@@ -6439,7 +6439,7 @@ if test "${enable_mga+set}" = set; then ...@@ -6439,7 +6439,7 @@ if test "${enable_mga+set}" = set; then
enableval="$enable_mga" enableval="$enable_mga"
if test x$enable_mga = xyes if test x$enable_mga = xyes
then then
PLUGINS="${PLUGINS} mga" PLUGINS="${PLUGINS} mga xmga"
fi fi
fi fi
......
...@@ -948,7 +948,7 @@ AC_ARG_ENABLE(mga, ...@@ -948,7 +948,7 @@ AC_ARG_ENABLE(mga,
[ --enable-mga Linux kernel Matrox support (default disabled)], [ --enable-mga Linux kernel Matrox support (default disabled)],
[ if test x$enable_mga = xyes [ if test x$enable_mga = xyes
then then
PLUGINS="${PLUGINS} mga" PLUGINS="${PLUGINS} mga xmga"
fi ]) fi ])
dnl dnl
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions * Collection of useful common types and macros definitions
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: common.h,v 1.66 2002/01/07 02:12:29 sam Exp $ * $Id: common.h,v 1.67 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@via.ecp.fr> * Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr> * Vincent Seguin <seguin@via.ecp.fr>
...@@ -468,6 +468,7 @@ typedef struct module_symbols_s ...@@ -468,6 +468,7 @@ typedef struct module_symbols_s
void ( * intf_PlaylistDestroy ) ( struct playlist_s * ); void ( * intf_PlaylistDestroy ) ( struct playlist_s * );
void ( * intf_PlaylistJumpto ) ( struct playlist_s *, int ); void ( * intf_PlaylistJumpto ) ( struct playlist_s *, int );
void ( * intf_UrlDecode ) ( char * ); void ( * intf_UrlDecode ) ( char * );
int ( * intf_Eject ) ( const char * );
void ( * msleep ) ( mtime_t ); void ( * msleep ) ( mtime_t );
mtime_t ( * mdate ) ( void ); mtime_t ( * mdate ) ( void );
...@@ -576,6 +577,7 @@ typedef struct module_symbols_s ...@@ -576,6 +577,7 @@ typedef struct module_symbols_s
struct module_s * ( * module_Need ) ( int, char *, struct probedata_s * ); struct module_s * ( * module_Need ) ( int, char *, struct probedata_s * );
void ( * module_Unneed ) ( struct module_s * ); void ( * module_Unneed ) ( struct module_s * );
} module_symbols_t; } module_symbols_t;
#ifdef PLUGIN #ifdef PLUGIN
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* control the pace of reading. * control the pace of reading.
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.56 2002/01/07 02:12:29 sam Exp $ * $Id: input_ext-intf.h,v 1.57 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -259,7 +259,7 @@ typedef struct input_thread_s ...@@ -259,7 +259,7 @@ typedef struct input_thread_s
boolean_t b_error; boolean_t b_error;
boolean_t b_eof; boolean_t b_eof;
vlc_thread_t thread_id; /* id for thread functions */ vlc_thread_t thread_id; /* id for thread functions */
int * pi_status; /* temporary status flag */ int i_status; /* status flag */
/* Input module */ /* Input module */
struct module_s * p_input_module; struct module_s * p_input_module;
...@@ -343,7 +343,8 @@ void input_EndBank ( void ); ...@@ -343,7 +343,8 @@ void input_EndBank ( void );
struct input_thread_s * input_CreateThread ( struct playlist_item_s *, struct input_thread_s * input_CreateThread ( struct playlist_item_s *,
int *pi_status ); int *pi_status );
void input_DestroyThread ( struct input_thread_s *, int *pi_status ); void input_StopThread ( struct input_thread_s *, int *pi_status );
void input_DestroyThread ( struct input_thread_s * );
void input_SetStatus ( struct input_thread_s *, int ); void input_SetStatus ( struct input_thread_s *, int );
void input_Seek ( struct input_thread_s *, off_t ); void input_Seek ( struct input_thread_s *, off_t );
......
/*****************************************************************************
* intf_eject.h: CD/DVD-ROM ejection handling functions
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: intf_eject.h,v 1.1 2002/01/09 02:01:14 sam Exp $
*
* Author: Julien Blache <jb@technologeek.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef PLUGIN
int intf_Eject( const char * );
#else
# define intf_Eject p_symbols->intf_Eject
#endif
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* modules_inner.h : Macros used from within a module. * modules_inner.h : Macros used from within a module.
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: modules_inner.h,v 1.10 2001/12/30 07:09:54 sam Exp $ * $Id: modules_inner.h,v 1.11 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -56,15 +56,15 @@ ...@@ -56,15 +56,15 @@
/* If the module is built-in, then we need to define foo_InitModule instead /* If the module is built-in, then we need to define foo_InitModule instead
* of InitModule. Same for Activate- and DeactivateModule. */ * of InitModule. Same for Activate- and DeactivateModule. */
#ifdef BUILTIN #ifdef BUILTIN
# define _M( function ) CONCATENATE( function, MODULE_NAME ) # define _M( function ) CONCATENATE( function, MODULE_NAME )
# define _X( function ) CONCATENATE( function, MODULE_NAME ) # define __VLC_SYMBOL( symbol ) CONCATENATE( symbol, MODULE_NAME )
# define DECLARE_SYMBOLS ; # define DECLARE_SYMBOLS ;
# define STORE_SYMBOLS ; # define STORE_SYMBOLS ;
#else #else
# define _M( function ) function # define _M( function ) function
# define _X( function ) CONCATENATE( function, MODULE_SYMBOL ) # define __VLC_SYMBOL( symbol ) CONCATENATE( symbol, MODULE_SYMBOL )
# define DECLARE_SYMBOLS module_symbols_t* p_symbols; # define DECLARE_SYMBOLS module_symbols_t* p_symbols;
# define STORE_SYMBOLS p_symbols = p_module->p_symbols; # define STORE_SYMBOLS p_symbols = p_module->p_symbols;
#endif #endif
#define MODULE_STRING STRINGIFY( MODULE_NAME ) #define MODULE_STRING STRINGIFY( MODULE_NAME )
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
* instance the module name, its shortcuts, its capabilities... * instance the module name, its shortcuts, its capabilities...
*/ */
#define MODULE_INIT_START \ #define MODULE_INIT_START \
int _X( InitModule ) ( module_t *p_module ) \ int __VLC_SYMBOL( InitModule ) ( module_t *p_module ) \
{ \ { \
int i_shortcut = 0; \ int i_shortcut = 0; \
p_module->psz_name = MODULE_STRING; \ p_module->psz_name = MODULE_STRING; \
...@@ -115,7 +115,7 @@ ...@@ -115,7 +115,7 @@
#define MODULE_ACTIVATE_START \ #define MODULE_ACTIVATE_START \
DECLARE_SYMBOLS; \ DECLARE_SYMBOLS; \
\ \
int _X( ActivateModule ) ( module_t *p_module ) \ int __VLC_SYMBOL( ActivateModule ) ( module_t *p_module ) \
{ \ { \
p_module->p_functions = \ p_module->p_functions = \
( module_functions_t * )malloc( sizeof( module_functions_t ) ); \ ( module_functions_t * )malloc( sizeof( module_functions_t ) ); \
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
* here. * here.
*/ */
#define MODULE_DEACTIVATE_START \ #define MODULE_DEACTIVATE_START \
int _X( DeactivateModule )( module_t *p_module ) \ int __VLC_SYMBOL( DeactivateModule )( module_t *p_module ) \
{ \ { \
free( p_module->p_functions ); free( p_module->p_functions );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dummy.c : dummy plugin for vlc * dummy.c : dummy plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: dummy.c,v 1.13 2001/12/30 07:09:55 sam Exp $ * $Id: dummy.c,v 1.14 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -50,10 +50,11 @@ MODULE_INIT_START ...@@ -50,10 +50,11 @@ MODULE_INIT_START
SET_DESCRIPTION( "dummy functions module" ) SET_DESCRIPTION( "dummy functions module" )
/* Capability score set to 0 because we don't want to be spawned /* Capability score set to 0 because we don't want to be spawned
* unless explicitly requested to */ * unless explicitly requested to */
ADD_CAPABILITY( INPUT, 0 )
ADD_CAPABILITY( AOUT, 0 ) ADD_CAPABILITY( AOUT, 0 )
ADD_CAPABILITY( VOUT, 0 ) ADD_CAPABILITY( VOUT, 0 )
ADD_CAPABILITY( INTF, 0 ) ADD_CAPABILITY( INTF, 0 )
/* This one is ok. */
ADD_CAPABILITY( INPUT, 100 )
ADD_SHORTCUT( "dummy" ) ADD_SHORTCUT( "dummy" )
MODULE_INIT_STOP MODULE_INIT_STOP
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_dummy.c: dummy input plugin, to manage "vlc:***" special options * input_dummy.c: dummy input plugin, to manage "vlc:***" special options
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: input_dummy.c,v 1.12 2002/01/04 14:01:34 sam Exp $ * $Id: input_dummy.c,v 1.13 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -89,10 +89,10 @@ static int DummyProbe( probedata_t *p_data ) ...@@ -89,10 +89,10 @@ static int DummyProbe( probedata_t *p_data )
if( ( strlen(psz_name) > 4 ) && !strncasecmp( psz_name, "vlc:", 4 ) ) if( ( strlen(psz_name) > 4 ) && !strncasecmp( psz_name, "vlc:", 4 ) )
{ {
/* If the user specified "vlc:" then it's probably a file */ /* If the user specified "vlc:" then it's probably a file */
return( 100 ); return( 1 );
} }
return( 1 ); return( 0 );
} }
/***************************************************************************** /*****************************************************************************
...@@ -153,7 +153,6 @@ static void DummyOpen( input_thread_t * p_input ) ...@@ -153,7 +153,6 @@ static void DummyOpen( input_thread_t * p_input )
} }
intf_ErrMsg( "input error: unknown command `%s'", psz_name ); intf_ErrMsg( "input error: unknown command `%s'", psz_name );
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* wall.c : Wall video plugin for vlc * wall.c : Wall video plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: wall.c,v 1.9 2002/01/07 17:02:07 sam Exp $ * $Id: wall.c,v 1.10 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -134,8 +134,8 @@ static int vout_Create( vout_thread_t *p_vout ) ...@@ -134,8 +134,8 @@ static int vout_Create( vout_thread_t *p_vout )
return( 1 ); return( 1 );
} }
p_vout->p_sys->i_col = 3; p_vout->p_sys->i_col = 6;
p_vout->p_sys->i_row = 3; p_vout->p_sys->i_row = 6;
p_vout->p_sys->pp_vout = malloc( p_vout->p_sys->i_row * p_vout->p_sys->pp_vout = malloc( p_vout->p_sys->i_row *
p_vout->p_sys->i_col * p_vout->p_sys->i_col *
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* glide.c : 3dfx Glide plugin for vlc * glide.c : 3dfx Glide plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: glide.c,v 1.10 2002/01/07 02:12:29 sam Exp $ * $Id: glide.c,v 1.11 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -60,7 +60,6 @@ static int vout_Manage ( vout_thread_t * ); ...@@ -60,7 +60,6 @@ static int vout_Manage ( vout_thread_t * );
static void vout_Render ( vout_thread_t *, picture_t * ); static void vout_Render ( vout_thread_t *, picture_t * );
static void vout_Display ( vout_thread_t *, picture_t * ); static void vout_Display ( vout_thread_t *, picture_t * );
static int NewPicture ( vout_thread_t *, picture_t * );
static int OpenDisplay ( vout_thread_t * ); static int OpenDisplay ( vout_thread_t * );
static void CloseDisplay ( vout_thread_t * ); static void CloseDisplay ( vout_thread_t * );
...@@ -94,9 +93,8 @@ typedef struct vout_sys_s ...@@ -94,9 +93,8 @@ typedef struct vout_sys_s
{ {
GrLfbInfo_t p_buffer_info; /* back buffer info */ GrLfbInfo_t p_buffer_info; /* back buffer info */
/* Dummy video memory */ u8* pp_buffer[2];
byte_t * p_video; /* base adress */ int i_index;
size_t i_page_size; /* page size */
} vout_sys_t; } vout_sys_t;
...@@ -167,36 +165,49 @@ int vout_Init( vout_thread_t *p_vout ) ...@@ -167,36 +165,49 @@ int vout_Init( vout_thread_t *p_vout )
I_OUTPUTPICTURES = 0; I_OUTPUTPICTURES = 0;
/* Try to initialize up to 1 direct buffers */ p_pic = NULL;
while( I_OUTPUTPICTURES < 1 )
{
p_pic = NULL;
/* Find an empty picture slot */
for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
{
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
{
p_pic = p_vout->p_picture + i_index;
break;
}
}
/* Allocate the picture */ /* Find an empty picture slot */
if( p_pic == NULL || NewPicture( p_vout, p_pic ) ) for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
{
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
{ {
p_pic = p_vout->p_picture + i_index;
break; break;
} }
}
p_pic->i_status = DESTROYED_PICTURE; if( p_pic == NULL )
p_pic->i_type = DIRECT_PICTURE; {
return -1;
}
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; /* We know the chroma, allocate a buffer which will be used
* directly by the decoder */
p_pic->i_planes = 1;
I_OUTPUTPICTURES++; p_pic->p->p_pixels = p_vout->p_sys->pp_buffer[p_vout->p_sys->i_index];
} p_pic->p->i_pixel_bytes = GLIDE_BYTES_PER_PIXEL;
p_pic->p->i_lines = GLIDE_HEIGHT;
return( 0 ); p_pic->p->b_margin = 1;
p_pic->p->b_hidden = 1;
p_pic->p->i_visible_bytes = GLIDE_WIDTH * GLIDE_BYTES_PER_PIXEL;
p_pic->p->i_pitch = p_vout->p_sys->p_buffer_info.strideInBytes;
/*1024 * GLIDE_BYTES_PER_PIXEL*/
p_pic->p->i_red_mask = 0xf800;
p_pic->p->i_green_mask = 0x07e0;
p_pic->p->i_blue_mask = 0x001f;
p_pic->i_status = DESTROYED_PICTURE;
p_pic->i_type = DIRECT_PICTURE;
PP_OUTPUTPICTURE[ 0 ] = p_pic;
I_OUTPUTPICTURES = 1;
return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -286,18 +297,6 @@ static int OpenDisplay( vout_thread_t *p_vout ) ...@@ -286,18 +297,6 @@ static int OpenDisplay( vout_thread_t *p_vout )
GrScreenResolution_t resolution = GR_RESOLUTION_800x600; GrScreenResolution_t resolution = GR_RESOLUTION_800x600;
GrLfbInfo_t p_front_buffer_info; /* front buffer info */ GrLfbInfo_t p_front_buffer_info; /* front buffer info */
p_vout->p_sys->i_page_size = GLIDE_WIDTH * GLIDE_HEIGHT
* GLIDE_BYTES_PER_PIXEL;
/* Map two framebuffers a the very beginning of the fb */
p_vout->p_sys->p_video = malloc( p_vout->p_sys->i_page_size * 2 );
if( (int)p_vout->p_sys->p_video == -1 )
{
intf_ErrMsg( "vout error: can't map video memory (%s)",
strerror(errno) );
return( 1 );
}
grGlideGetVersion( version ); grGlideGetVersion( version );
grGlideInit(); grGlideInit();
...@@ -308,8 +307,8 @@ static int OpenDisplay( vout_thread_t *p_vout ) ...@@ -308,8 +307,8 @@ static int OpenDisplay( vout_thread_t *p_vout )
} }
grSstSelect( 0 ); grSstSelect( 0 );
if( !grSstWinOpen(0, resolution, GR_REFRESH_60Hz, if( !grSstWinOpen( 0, resolution, GR_REFRESH_60Hz,
GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1) ) GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 ) )
{ {
intf_ErrMsg( "vout error: can't open 3dfx screen" ); intf_ErrMsg( "vout error: can't open 3dfx screen" );
return( 1 ); return( 1 );
...@@ -347,10 +346,14 @@ static int OpenDisplay( vout_thread_t *p_vout ) ...@@ -347,10 +346,14 @@ static int OpenDisplay( vout_thread_t *p_vout )
grGlideShutdown(); grGlideShutdown();
return( 1 ); return( 1 );
} }
grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER ); grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
grBufferClear( 0, 0, 0 ); grBufferClear( 0, 0, 0 );
p_vout->p_sys->pp_buffer[0] = p_vout->p_sys->p_buffer_info.lfbPtr;
p_vout->p_sys->pp_buffer[1] = p_front_buffer_info.lfbPtr;
p_vout->p_sys->i_index = 0;
return( 0 ); return( 0 );
} }
...@@ -367,34 +370,5 @@ static void CloseDisplay( vout_thread_t *p_vout ) ...@@ -367,34 +370,5 @@ static void CloseDisplay( vout_thread_t *p_vout )
/* shutdown Glide */ /* shutdown Glide */
grGlideShutdown(); grGlideShutdown();
free( p_vout->p_sys->p_video );
}
/*****************************************************************************
* NewPicture: allocate a picture
*****************************************************************************
* Returns 0 on success, -1 otherwise
*****************************************************************************/
static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
/* We know the chroma, allocate a buffer which will be used
* directly by the decoder */
p_pic->p->p_pixels = p_vout->p_sys->p_video;
p_pic->p->i_pixel_bytes = GLIDE_BYTES_PER_PIXEL;
p_pic->p->i_lines = GLIDE_HEIGHT;
p_pic->p->b_margin = 1;
p_pic->p->b_hidden = 1;
p_pic->p->i_visible_bytes = GLIDE_WIDTH * GLIDE_BYTES_PER_PIXEL;
p_pic->p->i_pitch = p_vout->p_sys->p_buffer_info.strideInBytes;
/*1024 * GLIDE_BYTES_PER_PIXEL*/
p_pic->p->i_red_mask = 0xf800;
p_pic->p->i_green_mask = 0x07e0;
p_pic->p->i_blue_mask = 0x001f;
p_pic->i_planes = 1;
return 0;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gnome.c : Gnome plugin for vlc * gnome.c : Gnome plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000 VideoLAN * Copyright (C) 2000 VideoLAN
* $Id: gnome.c,v 1.6 2002/01/07 02:12:29 sam Exp $ * $Id: gnome.c,v 1.7 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -329,53 +329,56 @@ static gint GnomeManage( gpointer p_data ) ...@@ -329,53 +329,56 @@ static gint GnomeManage( gpointer p_data )
{ {
vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock ); vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
/* New input or stream map change */ if( !p_input_bank->pp_input[0]->b_die )
if( p_input_bank->pp_input[0]->stream.b_changed )
{ {
GtkModeManage( p_intf ); /* New input or stream map change */
GtkSetupMenus( p_intf ); if( p_input_bank->pp_input[0]->stream.b_changed )
p_intf->p_sys->b_playing = 1;
}
/* Manage the slider */
if( p_input_bank->pp_input[0]->stream.b_seekable )
{
float newvalue;
newvalue = p_intf->p_sys->p_adj->value;
#define p_area p_input_bank->pp_input[0]->stream.p_selected_area
/* If the user hasn't touched the slider since the last time,
* then the input can safely change it */
if( newvalue == p_intf->p_sys->f_adj_oldvalue )
{ {
/* Update the value */ GtkModeManage( p_intf );
p_intf->p_sys->p_adj->value = p_intf->p_sys->f_adj_oldvalue = GtkSetupMenus( p_intf );
( 100. * p_area->i_tell ) / p_area->i_size; p_intf->p_sys->b_playing = 1;
gtk_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
"value_changed" );
} }
/* Otherwise, send message to the input if the user has
* finished dragging the slider */ /* Manage the slider */
else if( p_intf->p_sys->b_slider_free ) if( p_input_bank->pp_input[0]->stream.b_seekable )
{ {
off_t i_seek = ( newvalue * p_area->i_size ) / 100; float newvalue;
newvalue = p_intf->p_sys->p_adj->value;
vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock ); #define p_area p_input_bank->pp_input[0]->stream.p_selected_area
input_Seek( p_input_bank->pp_input[0], i_seek ); /* If the user hasn't touched the slider since the last time,
vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock ); * then the input can safely change it */
if( newvalue == p_intf->p_sys->f_adj_oldvalue )
{
/* Update the value */
p_intf->p_sys->p_adj->value = p_intf->p_sys->f_adj_oldvalue =
( 100. * p_area->i_tell ) / p_area->i_size;
/* Update the old value */ gtk_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
p_intf->p_sys->f_adj_oldvalue = newvalue; "value_changed" );
} }
/* Otherwise, send message to the input if the user has
* finished dragging the slider */
else if( p_intf->p_sys->b_slider_free )
{
off_t i_seek = ( newvalue * p_area->i_size ) / 100;
vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
input_Seek( p_input_bank->pp_input[0], i_seek );
vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
/* Update the old value */
p_intf->p_sys->f_adj_oldvalue = newvalue;
}
#undef p_area #undef p_area
} }
if( p_intf->p_sys->i_part != if( p_intf->p_sys->i_part !=
p_input_bank->pp_input[0]->stream.p_selected_area->i_part ) p_input_bank->pp_input[0]->stream.p_selected_area->i_part )
{ {
p_intf->p_sys->b_chapter_update = 1; p_intf->p_sys->b_chapter_update = 1;
GtkSetupMenus( p_intf ); GtkSetupMenus( p_intf );
}
} }
vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock ); vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
......
...@@ -93,7 +93,6 @@ ...@@ -93,7 +93,6 @@
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenubarFileOpenActivate</handler> <handler>GnomeMenubarFileOpenActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Sat, 19 May 2001 16:27:02 GMT</last_modification_time> <last_modification_time>Sat, 19 May 2001 16:27:02 GMT</last_modification_time>
</signal> </signal>
<label>_Open File...</label> <label>_Open File...</label>
...@@ -108,7 +107,6 @@ ...@@ -108,7 +107,6 @@
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenubarDiscOpenActivate</handler> <handler>GnomeMenubarDiscOpenActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Sat, 19 May 2001 16:27:10 GMT</last_modification_time> <last_modification_time>Sat, 19 May 2001 16:27:10 GMT</last_modification_time>
</signal> </signal>
<label>Open _Disc...</label> <label>Open _Disc...</label>
...@@ -122,9 +120,8 @@ ...@@ -122,9 +120,8 @@
<tooltip>Select a Network Stream</tooltip> <tooltip>Select a Network Stream</tooltip>
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenbarNetworkOpenActivate</handler> <handler>GnomeMenubarNetworkOpenActivate</handler>
<data>&quot;intf_window&quot;</data> <last_modification_time>Fri, 21 Dec 2001 13:11:28 GMT</last_modification_time>
<last_modification_time>Sat, 19 May 2001 16:27:39 GMT</last_modification_time>
</signal> </signal>
<label>_Network Stream...</label> <label>_Network Stream...</label>
<right_justify>False</right_justify> <right_justify>False</right_justify>
...@@ -137,13 +134,32 @@ ...@@ -137,13 +134,32 @@
<right_justify>False</right_justify> <right_justify>False</right_justify>
</widget> </widget>
<widget>
<class>GtkPixmapMenuItem</class>
<name>menubar_eject</name>
<tooltip>Eject disc</tooltip>
<signal>
<name>activate</name>
<handler>GnomeMenubarDiscEjectActivate</handler>
<last_modification_time>Fri, 21 Dec 2001 13:11:28 GMT</last_modification_time>
</signal>
<label>_Eject Disc</label>
<right_justify>False</right_justify>
<stock_icon>GNOME_STOCK_MENU_TOP</stock_icon>
</widget>
<widget>
<class>GtkMenuItem</class>
<name>separator15</name>
<right_justify>False</right_justify>
</widget>
<widget> <widget>
<class>GtkPixmapMenuItem</class> <class>GtkPixmapMenuItem</class>
<name>menubar_exit</name> <name>menubar_exit</name>
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenubarExitActivate</handler> <handler>GnomeMenubarExitActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Sat, 19 May 2001 16:27:52 GMT</last_modification_time> <last_modification_time>Sat, 19 May 2001 16:27:52 GMT</last_modification_time>
</signal> </signal>
<stock_item>GNOMEUIINFO_MENU_EXIT_ITEM</stock_item> <stock_item>GNOMEUIINFO_MENU_EXIT_ITEM</stock_item>
...@@ -166,7 +182,6 @@ ...@@ -166,7 +182,6 @@
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenubarWindowToggleActivate</handler> <handler>GnomeMenubarWindowToggleActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Sat, 19 May 2001 16:28:06 GMT</last_modification_time> <last_modification_time>Sat, 19 May 2001 16:28:06 GMT</last_modification_time>
</signal> </signal>
<label>_Hide interface</label> <label>_Hide interface</label>
...@@ -179,7 +194,6 @@ ...@@ -179,7 +194,6 @@
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenubarFullscreenActivate</handler> <handler>GnomeMenubarFullscreenActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Sat, 19 May 2001 16:28:15 GMT</last_modification_time> <last_modification_time>Sat, 19 May 2001 16:28:15 GMT</last_modification_time>
</signal> </signal>
<label>_Fullscreen</label> <label>_Fullscreen</label>
...@@ -232,7 +246,6 @@ ...@@ -232,7 +246,6 @@
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenubarPlaylistActivate</handler> <handler>GnomeMenubarPlaylistActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Sat, 19 May 2001 16:28:41 GMT</last_modification_time> <last_modification_time>Sat, 19 May 2001 16:28:41 GMT</last_modification_time>
</signal> </signal>
<label>_Playlist...</label> <label>_Playlist...</label>
...@@ -248,7 +261,6 @@ ...@@ -248,7 +261,6 @@
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenubarModulesActivate</handler> <handler>GnomeMenubarModulesActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Sat, 19 May 2001 16:28:53 GMT</last_modification_time> <last_modification_time>Sat, 19 May 2001 16:28:53 GMT</last_modification_time>
</signal> </signal>
<label>_Modules...</label> <label>_Modules...</label>
...@@ -297,7 +309,6 @@ ...@@ -297,7 +309,6 @@
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenubarPreferencesActivate</handler> <handler>GnomeMenubarPreferencesActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Sat, 19 May 2001 16:29:03 GMT</last_modification_time> <last_modification_time>Sat, 19 May 2001 16:29:03 GMT</last_modification_time>
</signal> </signal>
<stock_item>GNOMEUIINFO_MENU_PREFERENCES_ITEM</stock_item> <stock_item>GNOMEUIINFO_MENU_PREFERENCES_ITEM</stock_item>
...@@ -320,7 +331,6 @@ ...@@ -320,7 +331,6 @@
<signal> <signal>
<name>activate</name> <name>activate</name>
<handler>GnomeMenubarAboutActivate</handler> <handler>GnomeMenubarAboutActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Sat, 19 May 2001 16:29:19 GMT</last_modification_time> <last_modification_time>Sat, 19 May 2001 16:29:19 GMT</last_modification_time>
</signal> </signal>
<stock_item>GNOMEUIINFO_MENU_ABOUT_ITEM</stock_item> <stock_item>GNOMEUIINFO_MENU_ABOUT_ITEM</stock_item>
...@@ -434,6 +444,21 @@ ...@@ -434,6 +444,21 @@
<stock_pixmap>GNOME_STOCK_PIXMAP_STOP</stock_pixmap> <stock_pixmap>GNOME_STOCK_PIXMAP_STOP</stock_pixmap>
</widget> </widget>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_eject</name>
<tooltip>Eject disc</tooltip>
<signal>
<name>button_press_event</name>
<handler>GtkDiscEject</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Fri, 21 Dec 2001 15:24:18 GMT</last_modification_time>
</signal>
<label>Eject</label>
<stock_pixmap>GNOME_STOCK_PIXMAP_TOP</stock_pixmap>
</widget>
<widget> <widget>
<class>GtkButton</class> <class>GtkButton</class>
<child_name>Toolbar:button</child_name> <child_name>Toolbar:button</child_name>
......
...@@ -30,12 +30,18 @@ GnomeMenubarDiscOpenActivate (GtkMenuItem *menuitem, ...@@ -30,12 +30,18 @@ GnomeMenubarDiscOpenActivate (GtkMenuItem *menuitem,
void void
GnomeMenbarNetworkOpenActivate (GtkMenuItem *menuitem, GnomeMenubarNetworkOpenActivate (GtkMenuItem *menuitem,
gpointer user_data) gpointer user_data)
{ {
GtkNetworkOpenShow( GTK_WIDGET( menuitem ), NULL, "intf_window" ); GtkNetworkOpenShow( GTK_WIDGET( menuitem ), NULL, "intf_window" );
} }
void
GnomeMenubarDiscEjectActivate (GtkMenuItem *menuitem,
gpointer user_data)
{
GtkDiscEject( GTK_WIDGET( menuitem ), NULL, "intf_window" );
}
void void
GnomeMenubarExitActivate (GtkMenuItem *menuitem, GnomeMenubarExitActivate (GtkMenuItem *menuitem,
...@@ -259,6 +265,3 @@ GnomePopupJumpActivate (GtkMenuItem *menuitem, ...@@ -259,6 +265,3 @@ GnomePopupJumpActivate (GtkMenuItem *menuitem,
{ {
GtkJumpShow( GTK_WIDGET( menuitem ), NULL, "intf_popup" ); GtkJumpShow( GTK_WIDGET( menuitem ), NULL, "intf_popup" );
} }
...@@ -11,7 +11,11 @@ GnomeMenubarDiscOpenActivate (GtkMenuItem *menuitem, ...@@ -11,7 +11,11 @@ GnomeMenubarDiscOpenActivate (GtkMenuItem *menuitem,
gpointer user_data); gpointer user_data);
void void
GnomeMenbarNetworkOpenActivate (GtkMenuItem *menuitem, GnomeMenubarNetworkOpenActivate (GtkMenuItem *menuitem,
gpointer user_data);
void
GnomeMenubarDiscEjectActivate (GtkMenuItem *menuitem,
gpointer user_data); gpointer user_data);
void void
...@@ -141,3 +145,4 @@ GtkNetworkOpenBroadcast (GtkToggleButton *togglebutton, ...@@ -141,3 +145,4 @@ GtkNetworkOpenBroadcast (GtkToggleButton *togglebutton,
void void
GtkNetworkOpenChannel (GtkToggleButton *togglebutton, GtkNetworkOpenChannel (GtkToggleButton *togglebutton,
gpointer user_data); gpointer user_data);
...@@ -32,11 +32,19 @@ static GnomeUIInfo menubar_file_menu_uiinfo[] = ...@@ -32,11 +32,19 @@ static GnomeUIInfo menubar_file_menu_uiinfo[] =
{ {
GNOME_APP_UI_ITEM, N_("_Network Stream..."), GNOME_APP_UI_ITEM, N_("_Network Stream..."),
N_("Select a Network Stream"), N_("Select a Network Stream"),
(gpointer) GnomeMenbarNetworkOpenActivate, NULL, NULL, (gpointer) GnomeMenubarNetworkOpenActivate, NULL, NULL,
GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_REFRESH, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_REFRESH,
0, (GdkModifierType) 0, NULL 0, (GdkModifierType) 0, NULL
}, },
GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_SEPARATOR,
{
GNOME_APP_UI_ITEM, N_("_Eject Disc"),
N_("Eject disc"),
(gpointer) GnomeMenubarDiscEjectActivate, NULL, NULL,
GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_TOP,
0, (GdkModifierType) 0, NULL
},
GNOMEUIINFO_SEPARATOR,
GNOMEUIINFO_MENU_EXIT_ITEM (GnomeMenubarExitActivate, NULL), GNOMEUIINFO_MENU_EXIT_ITEM (GnomeMenubarExitActivate, NULL),
GNOMEUIINFO_END GNOMEUIINFO_END
}; };
...@@ -145,6 +153,7 @@ create_intf_window (void) ...@@ -145,6 +153,7 @@ create_intf_window (void)
GtkWidget *toolbar_network; GtkWidget *toolbar_network;
GtkWidget *toolbar_back; GtkWidget *toolbar_back;
GtkWidget *toolbar_stop; GtkWidget *toolbar_stop;
GtkWidget *toolbar_eject;
GtkWidget *toolbar_play; GtkWidget *toolbar_play;
GtkWidget *toolbar_pause; GtkWidget *toolbar_pause;
GtkWidget *toolbar_slow; GtkWidget *toolbar_slow;
...@@ -220,10 +229,20 @@ create_intf_window (void) ...@@ -220,10 +229,20 @@ create_intf_window (void)
(GtkDestroyNotify) gtk_widget_unref); (GtkDestroyNotify) gtk_widget_unref);
gtk_widget_ref (menubar_file_menu_uiinfo[4].widget); gtk_widget_ref (menubar_file_menu_uiinfo[4].widget);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "menubar_exit", gtk_object_set_data_full (GTK_OBJECT (intf_window), "menubar_eject",
menubar_file_menu_uiinfo[4].widget, menubar_file_menu_uiinfo[4].widget,
(GtkDestroyNotify) gtk_widget_unref); (GtkDestroyNotify) gtk_widget_unref);
gtk_widget_ref (menubar_file_menu_uiinfo[5].widget);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "separator15",
menubar_file_menu_uiinfo[5].widget,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_ref (menubar_file_menu_uiinfo[6].widget);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "menubar_exit",
menubar_file_menu_uiinfo[6].widget,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_ref (menubar_uiinfo[1].widget); gtk_widget_ref (menubar_uiinfo[1].widget);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "menubar_view", gtk_object_set_data_full (GTK_OBJECT (intf_window), "menubar_view",
menubar_uiinfo[1].widget, menubar_uiinfo[1].widget,
...@@ -390,6 +409,18 @@ create_intf_window (void) ...@@ -390,6 +409,18 @@ create_intf_window (void)
(GtkDestroyNotify) gtk_widget_unref); (GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_stop); gtk_widget_show (toolbar_stop);
tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_TOP);
toolbar_eject = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Eject"),
_("Eject disc"), NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_widget_ref (toolbar_eject);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "toolbar_eject", toolbar_eject,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_eject);
tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_FORWARD); tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_FORWARD);
toolbar_play = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), toolbar_play = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON, GTK_TOOLBAR_CHILD_BUTTON,
...@@ -682,6 +713,9 @@ create_intf_window (void) ...@@ -682,6 +713,9 @@ create_intf_window (void)
gtk_signal_connect (GTK_OBJECT (toolbar_stop), "button_press_event", gtk_signal_connect (GTK_OBJECT (toolbar_stop), "button_press_event",
GTK_SIGNAL_FUNC (GtkControlStop), GTK_SIGNAL_FUNC (GtkControlStop),
"intf_window"); "intf_window");
gtk_signal_connect (GTK_OBJECT (toolbar_eject), "button_press_event",
GTK_SIGNAL_FUNC (GtkDiscEject),
"intf_window");
gtk_signal_connect (GTK_OBJECT (toolbar_play), "button_press_event", gtk_signal_connect (GTK_OBJECT (toolbar_play), "button_press_event",
GTK_SIGNAL_FUNC (GtkControlPlay), GTK_SIGNAL_FUNC (GtkControlPlay),
"intf_window"); "intf_window");
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gtk.c : Gtk+ plugin for vlc * gtk.c : Gtk+ plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * Copyright (C) 2000-2001 VideoLAN
* $Id: gtk.c,v 1.8 2002/01/07 02:12:29 sam Exp $ * $Id: gtk.c,v 1.9 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -328,61 +328,63 @@ static gint GtkManage( gpointer p_data ) ...@@ -328,61 +328,63 @@ static gint GtkManage( gpointer p_data )
/* update the playlist */ /* update the playlist */
GtkPlayListManage( p_data ); GtkPlayListManage( p_data );
if( p_input_bank->pp_input[0] != NULL && !p_intf->b_die ) if( p_input_bank->pp_input[0] != NULL )
{ {
vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock ); vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
/* New input or stream map change */ if( !p_input_bank->pp_input[0]->b_die )
if( p_input_bank->pp_input[0]->stream.b_changed )
{ {
GtkModeManage( p_intf ); /* New input or stream map change */
GtkSetupMenus( p_intf ); if( p_input_bank->pp_input[0]->stream.b_changed )
p_intf->p_sys->b_playing = 1; {
} GtkModeManage( p_intf );
GtkSetupMenus( p_intf );
p_intf->p_sys->b_playing = 1;
}
/* Manage the slider */ /* Manage the slider */
if( p_input_bank->pp_input[0]->stream.b_seekable ) if( p_input_bank->pp_input[0]->stream.b_seekable )
{ {
float newvalue = p_intf->p_sys->p_adj->value; float newvalue = p_intf->p_sys->p_adj->value;
#define p_area p_input_bank->pp_input[0]->stream.p_selected_area #define p_area p_input_bank->pp_input[0]->stream.p_selected_area
/* If the user hasn't touched the slider since the last time, /* If the user hasn't touched the slider since the last time,
* then the input can safely change it */ * then the input can safely change it */
if( newvalue == p_intf->p_sys->f_adj_oldvalue ) if( newvalue == p_intf->p_sys->f_adj_oldvalue )
{ {
/* Update the value */ /* Update the value */
p_intf->p_sys->p_adj->value = p_intf->p_sys->f_adj_oldvalue = p_intf->p_sys->p_adj->value = p_intf->p_sys->f_adj_oldvalue =
( 100. * p_area->i_tell ) / p_area->i_size; ( 100. * p_area->i_tell ) / p_area->i_size;
gtk_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
"value_changed" );
}
/* Otherwise, send message to the input if the user has
* finished dragging the slider */
else if( p_intf->p_sys->b_slider_free )
{
off_t i_seek = ( newvalue * p_area->i_size ) / 100;
gtk_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ), /* release the lock to be able to seek */
"value_changed" ); vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
input_Seek( p_input_bank->pp_input[0], i_seek );
vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
/* Update the old value */
p_intf->p_sys->f_adj_oldvalue = newvalue;
}
# undef p_area
} }
/* Otherwise, send message to the input if the user has
* finished dragging the slider */
else if( p_intf->p_sys->b_slider_free )
{
off_t i_seek = ( newvalue * p_area->i_size ) / 100;
/* release the lock to be able to seek */
vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
input_Seek( p_input_bank->pp_input[0], i_seek );
vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
/* Update the old value */ if( p_intf->p_sys->i_part !=
p_intf->p_sys->f_adj_oldvalue = newvalue; p_input_bank->pp_input[0]->stream.p_selected_area->i_part )
{
p_intf->p_sys->b_chapter_update = 1;
GtkSetupMenus( p_intf );
} }
#undef p_area
}
if( p_intf->p_sys->i_part !=
p_input_bank->pp_input[0]->stream.p_selected_area->i_part )
{
p_intf->p_sys->b_chapter_update = 1;
GtkSetupMenus( p_intf );
} }
vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock ); vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
} }
else if( p_intf->p_sys->b_playing && !p_intf->b_die ) else if( p_intf->p_sys->b_playing && !p_intf->b_die )
{ {
......
...@@ -140,6 +140,26 @@ ...@@ -140,6 +140,26 @@
<right_justify>False</right_justify> <right_justify>False</right_justify>
</widget> </widget>
<widget>
<class>GtkMenuItem</class>
<name>menubar_eject</name>
<tooltip>Eject disc</tooltip>
<signal>
<name>activate</name>
<handler>GtkEjectDiscActivate</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Fri, 21 Dec 2001 12:51:34 GMT</last_modification_time>
</signal>
<label>_Eject Disc</label>
<right_justify>False</right_justify>
</widget>
<widget>
<class>GtkMenuItem</class>
<name>separator14</name>
<right_justify>False</right_justify>
</widget>
<widget> <widget>
<class>GtkMenuItem</class> <class>GtkMenuItem</class>
<name>menubar_exit</name> <name>menubar_exit</name>
...@@ -441,6 +461,19 @@ ...@@ -441,6 +461,19 @@
<label>Stop</label> <label>Stop</label>
</widget> </widget>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_eject</name>
<signal>
<name>button_press_event</name>
<handler>GtkDiscEject</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Fri, 21 Dec 2001 15:33:26 GMT</last_modification_time>
</signal>
<label>Eject</label>
</widget>
<widget> <widget>
<class>GtkButton</class> <class>GtkButton</class>
<child_name>Toolbar:button</child_name> <child_name>Toolbar:button</child_name>
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
* gtk_callbacks.c : Callbacks for the Gtk+ plugin. * gtk_callbacks.c : Callbacks for the Gtk+ plugin.
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: gtk_callbacks.c,v 1.30 2002/01/07 02:12:29 sam Exp $ * $Id: gtk_callbacks.c,v 1.31 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
* Julien BLACHE <jb@technologeek.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -30,6 +31,8 @@ ...@@ -30,6 +31,8 @@
#include <videolan/vlc.h> #include <videolan/vlc.h>
#include <unistd.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <string.h> #include <string.h>
...@@ -39,6 +42,7 @@ ...@@ -39,6 +42,7 @@
#include "interface.h" #include "interface.h"
#include "intf_playlist.h" #include "intf_playlist.h"
#include "intf_eject.h"
#include "video.h" #include "video.h"
#include "video_output.h" #include "video_output.h"
...@@ -463,3 +467,55 @@ void GtkJumpActivate( GtkMenuItem * menuitem, gpointer user_data ) ...@@ -463,3 +467,55 @@ void GtkJumpActivate( GtkMenuItem * menuitem, gpointer user_data )
GtkJumpShow( GTK_WIDGET( menuitem ), NULL, user_data ); GtkJumpShow( GTK_WIDGET( menuitem ), NULL, user_data );
} }
/****************************************************************************
* Callbacks for disc ejection
****************************************************************************/
gboolean GtkDiscEject ( GtkWidget *widget, GdkEventButton *event,
gpointer user_data )
{
char *psz_device = NULL;
/*
* Get the active input
* Determine whether we can eject a media, ie it's a VCD or DVD
* If it's neither a VCD nor a DVD, then return
*/
/*
* Don't really know if I must lock the stuff here, we're using it read-only
*/
if (p_main->p_playlist->current.psz_name != NULL)
{
if (strncmp(p_main->p_playlist->current.psz_name, "dvd", 3)
|| strncmp(p_main->p_playlist->current.psz_name, "vcd", 3))
{
/* Determine the device name by omitting the first 4 characters */
psz_device = strdup((p_main->p_playlist->current.psz_name + 4));
}
}
if( psz_device == NULL )
{
return TRUE;
}
/* If there's a stream playing, we aren't allowed to eject ! */
if( p_input_bank->pp_input[0] == NULL )
{
intf_WarnMsg( 4, "intf: ejecting %s", psz_device );
intf_Eject( psz_device );
}
free(psz_device);
return TRUE;
}
void GtkEjectDiscActivate ( GtkMenuItem *menuitem, gpointer user_data )
{
fprintf(stderr, "DEBUG: EJECT called from MENU !\n");
GtkDiscEject( GTK_WIDGET( menuitem ), NULL, user_data );
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gtk_callbacks.h : Callbacks for the gtk plugin. * gtk_callbacks.h : Callbacks for the gtk plugin.
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: gtk_callbacks.h,v 1.15 2001/05/30 23:02:03 stef Exp $ * $Id: gtk_callbacks.h,v 1.16 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
...@@ -70,3 +70,12 @@ void GtkNetworkJoin ( GtkEditable *, gpointer ); ...@@ -70,3 +70,12 @@ void GtkNetworkJoin ( GtkEditable *, gpointer );
void GtkChannelGo ( GtkButton *, gpointer ); void GtkChannelGo ( GtkButton *, gpointer );
void GtkNetworkOpenChannel ( GtkToggleButton *, gpointer ); void GtkNetworkOpenChannel ( GtkToggleButton *, gpointer );
void
GtkEjectDiscActivate (GtkMenuItem *menuitem,
gpointer user_data);
gboolean
GtkDiscEject (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gtk_display.c: Gtk+ tools for main interface * gtk_display.c: Gtk+ tools for main interface
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: gtk_display.c,v 1.11 2002/01/07 02:12:29 sam Exp $ * $Id: gtk_display.c,v 1.12 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
...@@ -225,6 +225,7 @@ gint GtkModeManage( intf_thread_t * p_intf ) ...@@ -225,6 +225,7 @@ gint GtkModeManage( intf_thread_t * p_intf )
/* set control items */ /* set control items */
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_back"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_back"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_eject"), !b_control);
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_pause"), b_control ); gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_pause"), b_control );
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_slow"), b_control ); gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_slow"), b_control );
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_fast"), b_control ); gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_fast"), b_control );
......
...@@ -29,6 +29,8 @@ create_intf_window (void) ...@@ -29,6 +29,8 @@ create_intf_window (void)
GtkWidget *menubar_disc; GtkWidget *menubar_disc;
GtkWidget *menubar_network; GtkWidget *menubar_network;
GtkWidget *separator4; GtkWidget *separator4;
GtkWidget *menubar_eject;
GtkWidget *separator14;
GtkWidget *menubar_exit; GtkWidget *menubar_exit;
GtkWidget *menubar_view; GtkWidget *menubar_view;
GtkWidget *menubar_view_menu; GtkWidget *menubar_view_menu;
...@@ -60,6 +62,7 @@ create_intf_window (void) ...@@ -60,6 +62,7 @@ create_intf_window (void)
GtkWidget *toolbar_network; GtkWidget *toolbar_network;
GtkWidget *toolbar_back; GtkWidget *toolbar_back;
GtkWidget *toolbar_stop; GtkWidget *toolbar_stop;
GtkWidget *toolbar_eject;
GtkWidget *toolbar_play; GtkWidget *toolbar_play;
GtkWidget *toolbar_pause; GtkWidget *toolbar_pause;
GtkWidget *toolbar_slow; GtkWidget *toolbar_slow;
...@@ -196,6 +199,26 @@ create_intf_window (void) ...@@ -196,6 +199,26 @@ create_intf_window (void)
gtk_container_add (GTK_CONTAINER (menubar_file_menu), separator4); gtk_container_add (GTK_CONTAINER (menubar_file_menu), separator4);
gtk_widget_set_sensitive (separator4, FALSE); gtk_widget_set_sensitive (separator4, FALSE);
menubar_eject = gtk_menu_item_new_with_label ("");
tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menubar_eject)->child),
_("_Eject Disc"));
gtk_widget_add_accelerator (menubar_eject, "activate_item", menubar_file_menu_accels,
tmp_key, 0, 0);
gtk_widget_ref (menubar_eject);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "menubar_eject", menubar_eject,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (menubar_eject);
gtk_container_add (GTK_CONTAINER (menubar_file_menu), menubar_eject);
gtk_tooltips_set_tip (tooltips, menubar_eject, _("Eject disc"), NULL);
separator14 = gtk_menu_item_new ();
gtk_widget_ref (separator14);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "separator14", separator14,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (separator14);
gtk_container_add (GTK_CONTAINER (menubar_file_menu), separator14);
gtk_widget_set_sensitive (separator14, FALSE);
menubar_exit = gtk_menu_item_new_with_label (""); menubar_exit = gtk_menu_item_new_with_label ("");
tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menubar_exit)->child), tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menubar_exit)->child),
_("E_xit")); _("E_xit"));
...@@ -500,6 +523,17 @@ create_intf_window (void) ...@@ -500,6 +523,17 @@ create_intf_window (void)
(GtkDestroyNotify) gtk_widget_unref); (GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_stop); gtk_widget_show (toolbar_stop);
toolbar_eject = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Eject"),
NULL, NULL,
NULL, NULL, NULL);
gtk_widget_ref (toolbar_eject);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "toolbar_eject", toolbar_eject,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_eject);
toolbar_play = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), toolbar_play = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON, GTK_TOOLBAR_CHILD_BUTTON,
NULL, NULL,
...@@ -776,6 +810,9 @@ create_intf_window (void) ...@@ -776,6 +810,9 @@ create_intf_window (void)
gtk_signal_connect (GTK_OBJECT (menubar_network), "activate", gtk_signal_connect (GTK_OBJECT (menubar_network), "activate",
GTK_SIGNAL_FUNC (GtkNetworkOpenActivate), GTK_SIGNAL_FUNC (GtkNetworkOpenActivate),
"intf_window"); "intf_window");
gtk_signal_connect (GTK_OBJECT (menubar_eject), "activate",
GTK_SIGNAL_FUNC (GtkEjectDiscActivate),
"intf_window");
gtk_signal_connect (GTK_OBJECT (menubar_exit), "activate", gtk_signal_connect (GTK_OBJECT (menubar_exit), "activate",
GTK_SIGNAL_FUNC (GtkExitActivate), GTK_SIGNAL_FUNC (GtkExitActivate),
"intf_window"); "intf_window");
...@@ -812,6 +849,9 @@ create_intf_window (void) ...@@ -812,6 +849,9 @@ create_intf_window (void)
gtk_signal_connect (GTK_OBJECT (toolbar_stop), "button_press_event", gtk_signal_connect (GTK_OBJECT (toolbar_stop), "button_press_event",
GTK_SIGNAL_FUNC (GtkControlStop), GTK_SIGNAL_FUNC (GtkControlStop),
"intf_window"); "intf_window");
gtk_signal_connect (GTK_OBJECT (toolbar_eject), "button_press_event",
GTK_SIGNAL_FUNC (GtkDiscEject),
"intf_window");
gtk_signal_connect (GTK_OBJECT (toolbar_play), "button_press_event", gtk_signal_connect (GTK_OBJECT (toolbar_play), "button_press_event",
GTK_SIGNAL_FUNC (GtkControlPlay), GTK_SIGNAL_FUNC (GtkControlPlay),
"intf_window"); "intf_window");
......
mga_SOURCES = mga.c mga_SOURCES = mga.c
xmga_SOURCES = xmga.c
/*****************************************************************************
* xmga.c : X11 MGA plugin for vlc
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: xmga.c,v 1.1 2002/01/09 02:01:14 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <videolan/vlc.h>
#ifdef HAVE_MACHINE_PARAM_H
/* BSD */
#include <machine/param.h>
#include <sys/types.h> /* typedef ushort */
#include <sys/ipc.h>
#endif
#ifndef WIN32
#include <netinet/in.h> /* BSD: struct in_addr */
#endif
#include <sys/shm.h> /* shmget(), shmctl() */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/dpms.h>
#include "video.h"
#include "video_output.h"
#include "interface.h"
#include "netutils.h" /* network_ChannelJoin */
#include "stream_control.h" /* needed by input_ext-intf.h... */
#include "input_ext-intf.h"
//#include "mga.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static void vout_getfunctions( function_list_t * );
static int vout_Probe ( probedata_t * );
static int vout_Create ( vout_thread_t * );
static void vout_Destroy ( vout_thread_t * );
static void vout_Render ( vout_thread_t *, picture_t * );
static void vout_Display ( vout_thread_t *, picture_t * );
static int vout_Manage ( vout_thread_t * );
static int vout_Init ( vout_thread_t * );
static void vout_End ( vout_thread_t * );
static int CreateWindow ( vout_thread_t * );
static void DestroyWindow ( vout_thread_t * );
static int NewPicture ( vout_thread_t *, picture_t * );
static void FreePicture ( vout_thread_t *, picture_t * );
static void ToggleFullScreen ( vout_thread_t * );
static void EnableXScreenSaver ( vout_thread_t * );
static void DisableXScreenSaver ( vout_thread_t * );
static void CreateCursor ( vout_thread_t * );
static void DestroyCursor ( vout_thread_t * );
static void ToggleCursor ( vout_thread_t * );
/*****************************************************************************
* Building configuration tree
*****************************************************************************/
MODULE_CONFIG_START
MODULE_CONFIG_STOP
MODULE_INIT_START
SET_DESCRIPTION( "X11 MGA module" )
ADD_CAPABILITY( VOUT, 60 )
ADD_SHORTCUT( "xmga" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
vout_getfunctions( &p_module->p_functions->vout );
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
/*****************************************************************************
* vout_sys_t: video output method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the X11 and XVideo specific properties of an output thread.
*****************************************************************************/
typedef struct vout_sys_s
{
/* Internal settings and properties */
Display * p_display; /* display pointer */
Visual * p_visual; /* visual pointer */
int i_screen; /* screen number */
Window window; /* root window */
GC gc; /* graphic context instance handler */
boolean_t b_shm; /* shared memory extension flag */
#ifdef MODULE_NAME_IS_xvideo
Window yuv_window; /* sub-window for displaying yuv video
data */
int i_xvport;
#else
Colormap colormap; /* colormap used (8bpp only) */
int i_screen_depth;
int i_bytes_per_pixel;
int i_bytes_per_line;
int i_red_mask;
int i_green_mask;
int i_blue_mask;
#endif
/* X11 generic properties */
Atom wm_protocols;
Atom wm_delete_window;
int i_width; /* width of main window */
int i_height; /* height of main window */
/* Backup of window position and size before fullscreen switch */
int i_width_backup;
int i_height_backup;
int i_xpos_backup;
int i_ypos_backup;
/* Screen saver properties */
int i_ss_timeout; /* timeout */
int i_ss_interval; /* interval between changes */
int i_ss_blanking; /* blanking mode */
int i_ss_exposure; /* exposure mode */
BOOL b_ss_dpms; /* DPMS mode */
/* Mouse pointer properties */
boolean_t b_mouse_pointer_visible;
mtime_t i_time_mouse_last_moved; /* used to auto-hide pointer*/
Cursor blank_cursor; /* the hidden cursor */
Pixmap cursor_pixmap;
} vout_sys_t;
/*****************************************************************************
* picture_sys_t: direct buffer method descriptor
*****************************************************************************
* This structure is part of the picture descriptor, it describes the
* XVideo specific properties of a direct buffer.
*****************************************************************************/
typedef struct picture_sys_s
{
} picture_sys_t;
/*****************************************************************************
* mwmhints_t: window manager hints
*****************************************************************************
* Fullscreen needs to be able to hide the wm decorations so we provide
* this structure to make it easier.
*****************************************************************************/
#define MWM_HINTS_DECORATIONS (1L << 1)
#define PROP_MWM_HINTS_ELEMENTS 5
typedef struct mwmhints_s
{
u32 flags;
u32 functions;
u32 decorations;
s32 input_mode;
u32 status;
} mwmhints_t;
/*****************************************************************************
* Chroma defines
*****************************************************************************/
#ifdef MODULE_NAME_IS_xvideo
# define MAX_DIRECTBUFFERS 5
#else
# define MAX_DIRECTBUFFERS 2
#endif
/*****************************************************************************
* Seeking function TODO: put this in a generic location !
*****************************************************************************/
static __inline__ void vout_Seek( off_t i_seek )
{
off_t i_tell;
vlc_mutex_lock( &p_input_bank->lock );
if( p_input_bank->pp_input[0] != NULL )
{
#define S p_input_bank->pp_input[0]->stream
i_tell = S.p_selected_area->i_tell + i_seek * (off_t)50 * S.i_mux_rate;
i_tell = ( i_tell <= 0 /*S.p_selected_area->i_start*/ )
? 0 /*S.p_selected_area->i_start*/
: ( i_tell >= S.p_selected_area->i_size )
? S.p_selected_area->i_size
: i_tell;
input_Seek( p_input_bank->pp_input[0], i_tell );
#undef S
}
vlc_mutex_unlock( &p_input_bank->lock );
}
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
static 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_render = vout_Render;
p_function_list->functions.vout.pf_display = vout_Display;
}
/*****************************************************************************
* vout_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 )
{
Display *p_display; /* display pointer */
char *psz_display;
#ifdef MODULE_NAME_IS_xvideo
int i_xvport, i_dummy;
#endif
/* Open display, unsing 'vlc_display' or DISPLAY environment variable */
psz_display = XDisplayName( main_GetPszVariable(VOUT_DISPLAY_VAR, NULL) );
p_display = XOpenDisplay( psz_display );
if( p_display == NULL ) /* error */
{
intf_WarnMsg( 3, "vout: cannot open display %s", psz_display );
return( 0 );
}
#ifdef MODULE_NAME_IS_xvideo
/* Check that there is an available XVideo port for this format */
i_xvport = XVideoGetPort( p_display, p_data->vout.i_chroma, &i_dummy );
if( i_xvport < 0 )
{
/* It failed, but it's not completely lost ! We try to open an
* XVideo port for a YUY2 picture */
i_xvport = XVideoGetPort( p_display, FOURCC_YUY2, &i_dummy );
if( i_xvport < 0 )
{
/* It failed, but it's not completely lost ! We try to open an
* XVideo port for a simple 16bpp RGB picture */
i_xvport = XVideoGetPort( p_display, FOURCC_RV16, &i_dummy );
if( i_xvport < 0 )
{
XCloseDisplay( p_display );
return( 0 );
}
}
}
XVideoReleasePort( p_display, i_xvport );
#endif
/* Clean-up everyting */
XCloseDisplay( p_display );
#ifdef MODULE_NAME_IS_xvideo
return( 150 );
#else
return( 50 );
#endif
}
/*****************************************************************************
* vout_Create: 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.
*****************************************************************************/
static int vout_Create( vout_thread_t *p_vout )
{
char *psz_display;
/* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
{
intf_ErrMsg( "vout error: %s", strerror(ENOMEM) );
return( 1 );
}
/* Open display, unsing 'vlc_display' or DISPLAY environment variable */
psz_display = XDisplayName( main_GetPszVariable( VOUT_DISPLAY_VAR, NULL ) );
p_vout->p_sys->p_display = XOpenDisplay( psz_display );
if( p_vout->p_sys->p_display == NULL ) /* error */
{
intf_ErrMsg( "vout error: cannot open display %s", psz_display );
free( p_vout->p_sys );
return( 1 );
}
p_vout->p_sys->i_screen = DefaultScreen( p_vout->p_sys->p_display );
/* Create blank cursor (for mouse cursor autohiding) */
p_vout->p_sys->b_mouse_pointer_visible = 1;
CreateCursor( p_vout );
/* Spawn base window - this window will include the video output window,
* but also command buttons, subtitles and other indicators */
if( CreateWindow( p_vout ) )
{
intf_ErrMsg( "vout error: cannot create X11 window" );
DestroyCursor( p_vout );
XCloseDisplay( p_vout->p_sys->p_display );
free( p_vout->p_sys );
return( 1 );
}
/* Disable screen saver and return */
DisableXScreenSaver( p_vout );
return( 0 );
}
/*****************************************************************************
* vout_Destroy: destroy X11 video thread output method
*****************************************************************************
* Terminate an output method created by vout_CreateOutputMethod
*****************************************************************************/
static void vout_Destroy( vout_thread_t *p_vout )
{
/* Restore cursor if it was blanked */
if( !p_vout->p_sys->b_mouse_pointer_visible )
{
ToggleCursor( p_vout );
}
DestroyCursor( p_vout );
EnableXScreenSaver( p_vout );
DestroyWindow( p_vout );
XCloseDisplay( p_vout->p_sys->p_display );
/* Destroy structure */
free( p_vout->p_sys );
}
/*****************************************************************************
* vout_Init: 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.
*****************************************************************************/
static int vout_Init( vout_thread_t *p_vout )
{
int i_index;
picture_t *p_pic;
I_OUTPUTPICTURES = 0;
#ifdef MODULE_NAME_IS_xvideo
/* Initialize the output structure; we already found an XVideo port,
* and the corresponding chroma we will be using. Since we can
* arbitrary scale, stick to the coordinates and aspect. */
p_vout->output.i_width = p_vout->render.i_width;
p_vout->output.i_height = p_vout->render.i_height;
p_vout->output.i_aspect = p_vout->render.i_aspect;
#else
/* Initialize the output structure: RGB with square pixels, whatever
* the input format is, since it's the only format we know */
switch( p_vout->p_sys->i_screen_depth )
{
case 8: /* FIXME: set the palette */
p_vout->output.i_chroma = FOURCC_BI_RGB; break;
case 15:
p_vout->output.i_chroma = FOURCC_RV15; break;
case 16:
p_vout->output.i_chroma = FOURCC_RV16; break;
case 24:
p_vout->output.i_chroma = FOURCC_BI_BITFIELDS; break;
case 32:
p_vout->output.i_chroma = FOURCC_BI_BITFIELDS; break;
default:
intf_ErrMsg( "vout error: unknown screen depth" );
return( 0 );
}
p_vout->output.i_width = p_vout->p_sys->i_width;
p_vout->output.i_height = p_vout->p_sys->i_height;
/* Assume we have square pixels */
p_vout->output.i_aspect = p_vout->p_sys->i_width
* VOUT_ASPECT_FACTOR / p_vout->p_sys->i_height;
#endif
/* Try to initialize up to MAX_DIRECTBUFFERS direct buffers */
while( I_OUTPUTPICTURES < MAX_DIRECTBUFFERS )
{
p_pic = NULL;
/* Find an empty picture slot */
for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
{
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
{
p_pic = p_vout->p_picture + i_index;
break;
}
}
/* Allocate the picture */
if( p_pic == NULL || NewPicture( p_vout, p_pic ) )
{
break;
}
p_pic->i_status = DESTROYED_PICTURE;
p_pic->i_type = DIRECT_PICTURE;
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
I_OUTPUTPICTURES++;
}
return( 0 );
}
/*****************************************************************************
* vout_Render: render previously calculated output
*****************************************************************************/
static void vout_Render( vout_thread_t *p_vout, picture_t *p_pic )
{
;
}
/*****************************************************************************
* vout_Display: displays previously rendered output
*****************************************************************************
* This function sends the currently rendered image to X11 server.
* (The Xv extension takes care of "double-buffering".)
*****************************************************************************/
static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
{
int i_width, i_height, i_x, i_y;
vout_PlacePicture( p_vout, p_vout->p_sys->i_width, p_vout->p_sys->i_height,
&i_x, &i_y, &i_width, &i_height );
}
/*****************************************************************************
* vout_Manage: 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.
*****************************************************************************/
static int vout_Manage( vout_thread_t *p_vout )
{
XEvent xevent; /* X11 event */
boolean_t b_resized; /* window has been resized */
char i_key; /* ISO Latin-1 key */
KeySym x_key_symbol;
/* 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_vout->p_sys->p_display, p_vout->p_sys->window,
StructureNotifyMask | KeyPressMask |
ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | Button1MotionMask , &xevent )
== True )
{
/* ConfigureNotify event: prepare */
if( (xevent.type == ConfigureNotify)
&& ((xevent.xconfigure.width != p_vout->p_sys->i_width)
|| (xevent.xconfigure.height != p_vout->p_sys->i_height)) )
{
/* Update dimensions */
b_resized = 1;
p_vout->i_changes |= VOUT_SIZE_CHANGE;
p_vout->p_sys->i_width = xevent.xconfigure.width;
p_vout->p_sys->i_height = xevent.xconfigure.height;
}
/* MapNotify event: change window status and disable screen saver */
else if( xevent.type == MapNotify)
{
if( (p_vout != NULL) && !p_vout->b_active )
{
DisableXScreenSaver( p_vout );
p_vout->b_active = 1;
}
}
/* UnmapNotify event: change window status and enable screen saver */
else if( xevent.type == UnmapNotify )
{
if( (p_vout != NULL) && p_vout->b_active )
{
EnableXScreenSaver( p_vout );
p_vout->b_active = 0;
}
}
/* Keyboard event */
else if( xevent.type == KeyPress )
{
/* We may have keys like F1 trough F12, ESC ... */
x_key_symbol = XKeycodeToKeysym( p_vout->p_sys->p_display,
xevent.xkey.keycode, 0 );
switch( x_key_symbol )
{
case XK_Escape:
p_main->p_intf->b_die = 1;
break;
case XK_Menu:
p_main->p_intf->b_menu_change = 1;
break;
case XK_Left:
vout_Seek( -5 );
break;
case XK_Right:
vout_Seek( 5 );
break;
case XK_Up:
vout_Seek( 60 );
break;
case XK_Down:
vout_Seek( -60 );
break;
case XK_Home:
input_Seek( p_input_bank->pp_input[0],
p_input_bank->pp_input[0]->stream.p_selected_area->i_start );
break;
case XK_End:
input_Seek( p_input_bank->pp_input[0],
p_input_bank->pp_input[0]->stream.p_selected_area->i_size );
break;
case XK_Page_Up:
vout_Seek( 900 );
break;
case XK_Page_Down:
vout_Seek( -900 );
break;
case XK_space:
input_SetStatus( p_input_bank->pp_input[0],
INPUT_STATUS_PAUSE );
break;
default:
/* "Normal Keys"
* The reason why I use this instead of XK_0 is that
* with XLookupString, we don't have to care about
* keymaps. */
if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
{
/* FIXME: handle stuff here */
switch( i_key )
{
case 'q':
case 'Q':
p_main->p_intf->b_die = 1;
break;
case 'f':
case 'F':
p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
break;
case '0': network_ChannelJoin( 0 ); break;
case '1': network_ChannelJoin( 1 ); break;
case '2': network_ChannelJoin( 2 ); break;
case '3': network_ChannelJoin( 3 ); break;
case '4': network_ChannelJoin( 4 ); break;
case '5': network_ChannelJoin( 5 ); break;
case '6': network_ChannelJoin( 6 ); break;
case '7': network_ChannelJoin( 7 ); break;
case '8': network_ChannelJoin( 8 ); break;
case '9': network_ChannelJoin( 9 ); break;
default:
intf_DbgMsg( "vout: unhandled key '%c' (%i)",
(char)i_key, i_key );
break;
}
}
break;
}
}
/* 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. For the
* moment just pause the stream. */
input_SetStatus( p_input_bank->pp_input[0],
INPUT_STATUS_PAUSE );
break;
case Button4:
vout_Seek( 15 );
break;
case Button5:
vout_Seek( -15 );
break;
}
}
/* Mouse release */
else if( xevent.type == ButtonRelease )
{
switch( ((XButtonEvent *)&xevent)->button )
{
case Button3:
/* FIXME: need locking ! */
p_main->p_intf->b_menu_change = 1;
break;
}
}
/* Mouse move */
else if( xevent.type == MotionNotify )
{
p_vout->p_sys->i_time_mouse_last_moved = mdate();
if( ! p_vout->p_sys->b_mouse_pointer_visible )
{
ToggleCursor( p_vout );
}
}
/* Other event */
else
{
intf_WarnMsg( 3, "vout: unhandled event %d received", xevent.type );
}
}
/* 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_vout->p_sys->p_display,
ClientMessage, &xevent ) )
{
if( (xevent.xclient.message_type == p_vout->p_sys->wm_protocols)
&& (xevent.xclient.data.l[0] == p_vout->p_sys->wm_delete_window ) )
{
p_main->p_intf->b_die = 1;
}
else
{
intf_DbgMsg( "vout: unhandled ClientMessage received" );
}
}
/*
* Fullscreen Change
*/
if ( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
{
ToggleFullScreen( p_vout );
p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
}
/*
* Size change
*/
if( p_vout->i_changes & VOUT_SIZE_CHANGE )
{
int i_width, i_height, i_x, i_y;
p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
intf_WarnMsg( 3, "vout: video display resized (%dx%d)",
p_vout->p_sys->i_width,
p_vout->p_sys->i_height );
vout_PlacePicture( p_vout, p_vout->p_sys->i_width,
p_vout->p_sys->i_height,
&i_x, &i_y, &i_width, &i_height );
}
/* Autohide Cursour */
if( mdate() - p_vout->p_sys->i_time_mouse_last_moved > 2000000 )
{
/* Hide the mouse automatically */
if( p_vout->p_sys->b_mouse_pointer_visible )
{
ToggleCursor( p_vout );
}
}
return 0;
}
/*****************************************************************************
* vout_End: terminate X11 video thread output method
*****************************************************************************
* Destroy the X11 XImages created by vout_Init. It is called at the end of
* the thread, but also each time the window is resized.
*****************************************************************************/
static void vout_End( vout_thread_t *p_vout )
{
int i_index;
/* Free the direct buffers we allocated */
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
FreePicture( p_vout, PP_OUTPUTPICTURE[ i_index ] );
}
}
/* following functions are local */
/*****************************************************************************
* CreateWindow: open and set-up X11 main window
*****************************************************************************/
static int CreateWindow( vout_thread_t *p_vout )
{
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 */
if( p_vout->render.i_height * p_vout->render.i_aspect
>= p_vout->render.i_width * VOUT_ASPECT_FACTOR )
{
p_vout->p_sys->i_width = p_vout->render.i_height
* p_vout->render.i_aspect / VOUT_ASPECT_FACTOR;
p_vout->p_sys->i_height = p_vout->render.i_height;
}
else
{
p_vout->p_sys->i_width = p_vout->render.i_width;
p_vout->p_sys->i_height = p_vout->render.i_width
* VOUT_ASPECT_FACTOR / p_vout->render.i_aspect;
}
#if 0
if( p_vout->p_sys->i_width <= 300 && p_vout->p_sys->i_height <= 300 )
{
p_vout->p_sys->i_width <<= 1;
p_vout->p_sys->i_height <<= 1;
}
else if( p_vout->p_sys->i_width <= 400
&& p_vout->p_sys->i_height <= 400 )
{
p_vout->p_sys->i_width += p_vout->p_sys->i_width >> 1;
p_vout->p_sys->i_height += p_vout->p_sys->i_height >> 1;
}
#endif
/* Prepare window manager hints and properties */
xsize_hints.base_width = p_vout->p_sys->i_width;
xsize_hints.base_height = p_vout->p_sys->i_height;
xsize_hints.flags = PSize;
p_vout->p_sys->wm_protocols = XInternAtom( p_vout->p_sys->p_display,
"WM_PROTOCOLS", True );
p_vout->p_sys->wm_delete_window = XInternAtom( p_vout->p_sys->p_display,
"WM_DELETE_WINDOW", True );
/* Prepare window attributes */
xwindow_attributes.backing_store = Always; /* save the hidden part */
xwindow_attributes.background_pixel = BlackPixel(p_vout->p_sys->p_display,
p_vout->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_vout->p_sys->window =
XCreateWindow( p_vout->p_sys->p_display,
DefaultRootWindow( p_vout->p_sys->p_display ),
0, 0,
p_vout->p_sys->i_width,
p_vout->p_sys->i_height,
0,
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_vout->p_sys->p_display, p_vout->p_sys->window,
&xsize_hints );
XSetCommand( p_vout->p_sys->p_display, p_vout->p_sys->window,
p_main->ppsz_argv, p_main->i_argc );
XStoreName( p_vout->p_sys->p_display, p_vout->p_sys->window,
VOUT_TITLE " (XMGA output)"
);
if( (p_vout->p_sys->wm_protocols == None) /* use WM_DELETE_WINDOW */
|| (p_vout->p_sys->wm_delete_window == None)
|| !XSetWMProtocols( p_vout->p_sys->p_display, p_vout->p_sys->window,
&p_vout->p_sys->wm_delete_window, 1 ) )
{
/* WM_DELETE_WINDOW is not supported by window manager */
intf_Msg( "vout error: missing or bad window manager" );
}
/* 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 - 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_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;
}
else if( (xevent.type == ConfigureNotify)
&& (xevent.xconfigure.window == p_vout->p_sys->window) )
{
b_configure_notify = 1;
p_vout->p_sys->i_width = xevent.xconfigure.width;
p_vout->p_sys->i_height = xevent.xconfigure.height;
}
} while( !( b_expose && b_configure_notify && b_map_notify ) );
XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window,
StructureNotifyMask | KeyPressMask |
ButtonPressMask | ButtonReleaseMask |
PointerMotionMask );
/* If the cursor was formerly blank than blank it again */
if( !p_vout->p_sys->b_mouse_pointer_visible )
{
ToggleCursor( p_vout );
ToggleCursor( p_vout );
}
XSync( p_vout->p_sys->p_display, False );
/* At this stage, the window is open, displayed, and ready to
* receive data */
return( 0 );
}
/*****************************************************************************
* DestroyWindow: destroy the window
*****************************************************************************
*
*****************************************************************************/
static void DestroyWindow( vout_thread_t *p_vout )
{
XSync( p_vout->p_sys->p_display, False );
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 );
}
/*****************************************************************************
* NewPicture: allocate a picture
*****************************************************************************
* Returns 0 on success, -1 otherwise
*****************************************************************************/
static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
/* We know the chroma, allocate a buffer which will be used
* directly by the decoder */
p_pic->p_sys = malloc( sizeof( picture_sys_t ) );
if( p_pic->p_sys == NULL )
{
return -1;
}
/* XXX */
switch( p_vout->output.i_chroma )
{
/* XXX ?? */
default:
/* Unknown chroma, tell the guy to get lost */
free( p_pic->p_sys );
intf_ErrMsg( "vout error: never heard of chroma 0x%.8x (%4.4s)",
p_vout->output.i_chroma,
(char*)&p_vout->output.i_chroma );
p_pic->i_planes = 0;
return -1;
}
return 0;
}
/*****************************************************************************
* FreePicture: destroy a picture allocated with NewPicture
*****************************************************************************
* Destroy XImage AND associated data. If using Shm, detach shared memory
* segment from server and process, then free it. The XDestroyImage manpage
* says that both the image structure _and_ the data pointed to by the
* image structure are freed, so no need to free p_image->data.
*****************************************************************************/
static void FreePicture( vout_thread_t *p_vout, picture_t *p_pic )
{
XSync( p_vout->p_sys->p_display, False );
free( p_pic->p_sys );
}
/*****************************************************************************
* ToggleFullScreen: Enable or disable full screen mode
*****************************************************************************
* This function will switch between fullscreen and window mode.
*
*****************************************************************************/
static void ToggleFullScreen ( vout_thread_t *p_vout )
{
Atom prop;
mwmhints_t mwmhints;
int i_xpos, i_ypos, i_width, i_height;
p_vout->b_fullscreen = !p_vout->b_fullscreen;
if( p_vout->b_fullscreen )
{
Window next_parent, parent, *p_dummy, dummy1;
unsigned int dummy2, dummy3;
intf_WarnMsg( 3, "vout: entering fullscreen mode" );
/* Save current window coordinates so they can be restored when
* we exit from fullscreen mode */
/* find the real parent, which means the which is a direct child of
* the root window */
next_parent = parent = p_vout->p_sys->window;
while( next_parent != DefaultRootWindow( p_vout->p_sys->p_display ) )
{
parent = next_parent;
XQueryTree( p_vout->p_sys->p_display,
parent,
&dummy1,
&next_parent,
&p_dummy,
&dummy2 );
XFree((void *)p_dummy);
}
XGetGeometry( p_vout->p_sys->p_display,
p_vout->p_sys->window,
&dummy1,
&dummy2,
&dummy3,
&p_vout->p_sys->i_width_backup,
&p_vout->p_sys->i_height_backup,
&dummy2, &dummy3 );
XTranslateCoordinates( p_vout->p_sys->p_display,
parent,
DefaultRootWindow( p_vout->p_sys->p_display ),
0,
0,
&p_vout->p_sys->i_xpos_backup,
&p_vout->p_sys->i_ypos_backup,
&dummy1 );
mwmhints.flags = MWM_HINTS_DECORATIONS;
mwmhints.decorations = 0;
i_xpos = 0;
i_ypos = 0;
i_width = DisplayWidth( p_vout->p_sys->p_display,
p_vout->p_sys->i_screen );
i_height = DisplayHeight( p_vout->p_sys->p_display,
p_vout->p_sys->i_screen );
#if 0
/* Being a transient window allows us to really be fullscreen (display
* over the taskbar for instance) but then we end-up with the same
* result as with the brute force method */
XSetTransientForHint( p_vout->p_sys->p_display,
p_vout->p_sys->window, None );
#endif
}
else
{
intf_WarnMsg( 3, "vout: leaving fullscreen mode" );
mwmhints.flags = MWM_HINTS_DECORATIONS;
mwmhints.decorations = 1;
i_xpos = p_vout->p_sys->i_xpos_backup;
i_ypos = p_vout->p_sys->i_ypos_backup;
i_width = p_vout->p_sys->i_width_backup;
i_height = p_vout->p_sys->i_height_backup;
}
/* To my knowledge there are two ways to create a borderless window.
* There's the generic way which is to tell x to bypass the window manager,
* but this creates problems with the focus of other applications.
* The other way is to use the motif property "_MOTIF_WM_HINTS" which
* luckily seems to be supported by most window managers.
*/
prop = XInternAtom( p_vout->p_sys->p_display, "_MOTIF_WM_HINTS",
False );
XChangeProperty( p_vout->p_sys->p_display, p_vout->p_sys->window,
prop, prop, 32, PropModeReplace,
(unsigned char *)&mwmhints,
PROP_MWM_HINTS_ELEMENTS );
#if 0 /* brute force way to remove decorations */
XSetWindowAttributes attributes;
attributes.override_redirect = True;
XChangeWindowAttributes( p_vout->p_sys->p_display,
p_vout->p_sys->window,
CWOverrideRedirect,
&attributes);
#endif
/* We need to unmap and remap the window if we want the window
* manager to take our changes into effect */
XUnmapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window);
XMapRaised( p_vout->p_sys->p_display, p_vout->p_sys->window);
XMoveResizeWindow( p_vout->p_sys->p_display,
p_vout->p_sys->window,
i_xpos,
i_ypos,
i_width,
i_height );
XFlush( p_vout->p_sys->p_display );
}
/*****************************************************************************
* EnableXScreenSaver: enable screen saver
*****************************************************************************
* This function enables the screen saver on a display after it has been
* disabled by XDisableScreenSaver.
* FIXME: what happens if multiple vlc sessions are running at the same
* time ???
*****************************************************************************/
static void EnableXScreenSaver( vout_thread_t *p_vout )
{
int dummy;
intf_DbgMsg( "vout: enabling screen saver" );
XSetScreenSaver( p_vout->p_sys->p_display, p_vout->p_sys->i_ss_timeout,
p_vout->p_sys->i_ss_interval,
p_vout->p_sys->i_ss_blanking,
p_vout->p_sys->i_ss_exposure );
/* Restore DPMS settings */
if( DPMSQueryExtension( p_vout->p_sys->p_display, &dummy, &dummy ) )
{
if( p_vout->p_sys->b_ss_dpms )
{
DPMSEnable( p_vout->p_sys->p_display );
}
}
}
/*****************************************************************************
* DisableXScreenSaver: disable screen saver
*****************************************************************************
* See XEnableXScreenSaver
*****************************************************************************/
static void DisableXScreenSaver( vout_thread_t *p_vout )
{
int dummy;
/* Save screen saver informations */
XGetScreenSaver( p_vout->p_sys->p_display, &p_vout->p_sys->i_ss_timeout,
&p_vout->p_sys->i_ss_interval,
&p_vout->p_sys->i_ss_blanking,
&p_vout->p_sys->i_ss_exposure );
/* Disable screen saver */
intf_DbgMsg( "vout: disabling screen saver" );
XSetScreenSaver( p_vout->p_sys->p_display, 0,
p_vout->p_sys->i_ss_interval,
p_vout->p_sys->i_ss_blanking,
p_vout->p_sys->i_ss_exposure );
/* Disable DPMS */
if( DPMSQueryExtension( p_vout->p_sys->p_display, &dummy, &dummy ) )
{
CARD16 dummy;
/* Save DPMS current state */
DPMSInfo( p_vout->p_sys->p_display, &dummy,
&p_vout->p_sys->b_ss_dpms );
intf_DbgMsg( "vout: disabling DPMS" );
DPMSDisable( p_vout->p_sys->p_display );
}
}
/*****************************************************************************
* CreateCursor: create a blank mouse pointer
*****************************************************************************/
static void CreateCursor( vout_thread_t *p_vout )
{
XColor cursor_color;
p_vout->p_sys->cursor_pixmap =
XCreatePixmap( p_vout->p_sys->p_display,
DefaultRootWindow( p_vout->p_sys->p_display ),
1, 1, 1 );
XParseColor( p_vout->p_sys->p_display,
XCreateColormap( p_vout->p_sys->p_display,
DefaultRootWindow(
p_vout->p_sys->p_display ),
DefaultVisual(
p_vout->p_sys->p_display,
p_vout->p_sys->i_screen ),
AllocNone ),
"black", &cursor_color );
p_vout->p_sys->blank_cursor =
XCreatePixmapCursor( p_vout->p_sys->p_display,
p_vout->p_sys->cursor_pixmap,
p_vout->p_sys->cursor_pixmap,
&cursor_color, &cursor_color, 1, 1 );
}
/*****************************************************************************
* DestroyCursor: destroy the blank mouse pointer
*****************************************************************************/
static void DestroyCursor( vout_thread_t *p_vout )
{
XFreePixmap( p_vout->p_sys->p_display, p_vout->p_sys->cursor_pixmap );
}
/*****************************************************************************
* ToggleCursor: hide or show the mouse pointer
*****************************************************************************
* This function hides the X pointer if it is visible by setting the pointer
* sprite to a blank one. To show it again, we disable the sprite.
*****************************************************************************/
static void ToggleCursor( vout_thread_t *p_vout )
{
if( p_vout->p_sys->b_mouse_pointer_visible )
{
XDefineCursor( p_vout->p_sys->p_display,
p_vout->p_sys->window,
p_vout->p_sys->blank_cursor );
p_vout->p_sys->b_mouse_pointer_visible = 0;
}
else
{
XUndefineCursor( p_vout->p_sys->p_display, p_vout->p_sys->window );
p_vout->p_sys->b_mouse_pointer_visible = 1;
}
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* decoders. * decoders.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: input.c,v 1.168 2002/01/07 02:12:29 sam Exp $ * $Id: input.c,v 1.169 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -113,11 +113,15 @@ void input_InitBank ( void ) ...@@ -113,11 +113,15 @@ void input_InitBank ( void )
*****************************************************************************/ *****************************************************************************/
void input_EndBank ( void ) void input_EndBank ( void )
{ {
int i_input;
/* Ask all remaining video outputs to die */ /* Ask all remaining video outputs to die */
while( p_input_bank->i_count ) for( i_input = 0; i_input < p_input_bank->i_count; i_input++ )
{ {
input_StopThread(
p_input_bank->pp_input[ i_input ], NULL );
input_DestroyThread( input_DestroyThread(
p_input_bank->pp_input[ --p_input_bank->i_count ], NULL ); p_input_bank->pp_input[ i_input ] );
} }
vlc_mutex_destroy( &p_input_bank->lock ); vlc_mutex_destroy( &p_input_bank->lock );
...@@ -134,7 +138,6 @@ void input_EndBank ( void ) ...@@ -134,7 +138,6 @@ void input_EndBank ( void )
input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
{ {
input_thread_t * p_input; /* thread descriptor */ input_thread_t * p_input; /* thread descriptor */
int i_status; /* thread status */
/* Allocate descriptor */ /* Allocate descriptor */
p_input = (input_thread_t *)malloc( sizeof(input_thread_t) ); p_input = (input_thread_t *)malloc( sizeof(input_thread_t) );
...@@ -146,16 +149,15 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) ...@@ -146,16 +149,15 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
} }
/* Initialize thread properties */ /* Initialize thread properties */
p_input->b_die = 0; p_input->b_die = 0;
p_input->b_error = 0; p_input->b_error = 0;
p_input->b_eof = 0; p_input->b_eof = 0;
/* Set target */ /* Set target */
p_input->p_source = p_item->psz_name; p_input->p_source = p_item->psz_name;
/* I have never understood that stuff --Meuuh */ /* Set status */
p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status; p_input->i_status = THREAD_CREATE;
*p_input->pi_status = THREAD_CREATE;
/* Initialize stream description */ /* Initialize stream description */
p_input->stream.i_es_number = 0; p_input->stream.i_es_number = 0;
...@@ -196,6 +198,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) ...@@ -196,6 +198,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
return( NULL ); return( NULL );
} }
#if 0
/* If status is NULL, wait until the thread is created */ /* If status is NULL, wait until the thread is created */
if( pi_status == NULL ) if( pi_status == NULL )
{ {
...@@ -204,36 +207,30 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) ...@@ -204,36 +207,30 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
msleep( THREAD_SLEEP ); msleep( THREAD_SLEEP );
} while( (i_status != THREAD_READY) && (i_status != THREAD_ERROR) } while( (i_status != THREAD_READY) && (i_status != THREAD_ERROR)
&& (i_status != THREAD_FATAL) ); && (i_status != THREAD_FATAL) );
if( i_status != THREAD_READY )
{
return( NULL );
}
} }
#endif
return( p_input ); return( p_input );
} }
/***************************************************************************** /*****************************************************************************
* input_DestroyThread: mark an input thread as zombie * input_StopThread: mark an input thread as zombie
***************************************************************************** *****************************************************************************
* This function should not return until the thread is effectively cancelled. * This function should not return until the thread is effectively cancelled.
*****************************************************************************/ *****************************************************************************/
void input_DestroyThread( input_thread_t *p_input, int *pi_status ) void input_StopThread( input_thread_t *p_input, int *pi_status )
{ {
int i_status; /* thread status */ /* Make the thread exit from a possible vlc_cond_wait() */
vlc_mutex_lock( &p_input->stream.stream_lock );
/* Set status */
p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status;
*p_input->pi_status = THREAD_DESTROY;
/* Request thread destruction */ /* Request thread destruction */
p_input->b_die = 1; p_input->b_die = 1;
/* Make the thread exit from a possible vlc_cond_wait() */
vlc_mutex_lock( &p_input->stream.stream_lock );
vlc_cond_signal( &p_input->stream.stream_wait ); vlc_cond_signal( &p_input->stream.stream_wait );
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
/* If status is NULL, wait until thread has been destroyed */ /* If status is NULL, wait until thread has been destroyed */
#if 0
if( pi_status == NULL ) if( pi_status == NULL )
{ {
do do
...@@ -242,6 +239,25 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status ) ...@@ -242,6 +239,25 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
} while ( (i_status != THREAD_OVER) && (i_status != THREAD_ERROR) } while ( (i_status != THREAD_OVER) && (i_status != THREAD_ERROR)
&& (i_status != THREAD_FATAL) ); && (i_status != THREAD_FATAL) );
} }
#endif
}
/*****************************************************************************
* input_DestroyThread: mark an input thread as zombie
*****************************************************************************
* This function should not return until the thread is effectively cancelled.
*****************************************************************************/
void input_DestroyThread( input_thread_t *p_input )
{
/* Join the thread */
vlc_thread_join( p_input->thread_id );
/* Destroy Mutex locks */
vlc_mutex_destroy( &p_input->stream.control.control_lock );
vlc_mutex_destroy( &p_input->stream.stream_lock );
/* Free input structure */
free( p_input );
} }
/***************************************************************************** /*****************************************************************************
...@@ -254,13 +270,15 @@ static void RunThread( input_thread_t *p_input ) ...@@ -254,13 +270,15 @@ static void RunThread( input_thread_t *p_input )
if( InitThread( p_input ) ) if( InitThread( p_input ) )
{ {
/* If we failed, wait before we are killed, and exit */ /* If we failed, wait before we are killed, and exit */
*p_input->pi_status = THREAD_ERROR; p_input->i_status = THREAD_ERROR;
p_input->b_error = 1; p_input->b_error = 1;
ErrorThread( p_input ); ErrorThread( p_input );
DestroyThread( p_input ); DestroyThread( p_input );
return; return;
} }
p_input->i_status = THREAD_READY;
/* initialization is complete */ /* initialization is complete */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_changed = 1; p_input->stream.b_changed = 1;
...@@ -507,8 +525,6 @@ static int InitThread( input_thread_t * p_input ) ...@@ -507,8 +525,6 @@ static int InitThread( input_thread_t * p_input )
return( -1 ); return( -1 );
} }
*p_input->pi_status = THREAD_READY;
return( 0 ); return( 0 );
} }
...@@ -531,11 +547,8 @@ static void ErrorThread( input_thread_t *p_input ) ...@@ -531,11 +547,8 @@ static void ErrorThread( input_thread_t *p_input )
*****************************************************************************/ *****************************************************************************/
static void EndThread( input_thread_t * p_input ) static void EndThread( input_thread_t * p_input )
{ {
int * pi_status; /* thread status */
/* Store status */ /* Store status */
pi_status = p_input->pi_status; p_input->i_status = THREAD_END;
*pi_status = THREAD_END;
if( p_main->b_stats ) if( p_main->b_stats )
{ {
...@@ -605,20 +618,8 @@ static void CloseThread( input_thread_t * p_input ) ...@@ -605,20 +618,8 @@ static void CloseThread( input_thread_t * p_input )
*****************************************************************************/ *****************************************************************************/
static void DestroyThread( input_thread_t * p_input ) static void DestroyThread( input_thread_t * p_input )
{ {
int * pi_status; /* thread status */
/* Store status */
pi_status = p_input->pi_status;
/* Destroy Mutex locks */
vlc_mutex_destroy( &p_input->stream.control.control_lock );
vlc_mutex_destroy( &p_input->stream.stream_lock );
/* Free input structure */
free( p_input );
/* Update status */ /* Update status */
*pi_status = THREAD_OVER; p_input->i_status = THREAD_OVER;
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* interface, such as command line. * interface, such as command line.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: interface.c,v 1.86 2002/01/07 02:12:30 sam Exp $ * $Id: interface.c,v 1.87 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Vincent Seguin <seguin@via.ecp.fr> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* *
...@@ -128,18 +128,33 @@ static void intf_Manage( intf_thread_t *p_intf ) ...@@ -128,18 +128,33 @@ static void intf_Manage( intf_thread_t *p_intf )
vlc_mutex_lock( &p_input_bank->lock ); vlc_mutex_lock( &p_input_bank->lock );
if( p_input_bank->i_count if( p_input_bank->i_count )
&& ( p_input_bank->pp_input[0]->b_error
|| p_input_bank->pp_input[0]->b_eof ) )
{ {
intf_WarnMsg( 3, "intf: input thread destroyed" ); int i_input;
input_DestroyThread( p_input_bank->pp_input[0], NULL ); input_thread_t *p_input;
p_input_bank->pp_input[0] = NULL;
p_input_bank->i_count--; for( i_input = 0; i_input < p_input_bank->i_count; i_input++ )
} {
p_input = p_input_bank->pp_input[i_input];
if( p_input->i_status == THREAD_OVER )
{
/* XXX: completely stupid ! */
input_DestroyThread( p_input );
p_input_bank->pp_input[i_input] = NULL;
p_input_bank->i_count--;
}
else if( ( p_input->i_status == THREAD_READY
|| p_input->i_status == THREAD_ERROR )
&& ( p_input->b_error || p_input->b_eof ) )
{
input_StopThread( p_input, NULL );
}
}
}
/* If no stream is being played, try to find one */ /* If no stream is being played, try to find one */
if( !p_input_bank->i_count && !p_intf->b_die ) else
{ {
// vlc_mutex_lock( &p_main->p_playlist->change_lock ); // vlc_mutex_lock( &p_main->p_playlist->change_lock );
...@@ -155,14 +170,20 @@ static void intf_Manage( intf_thread_t *p_intf ) ...@@ -155,14 +170,20 @@ static void intf_Manage( intf_thread_t *p_intf )
} }
else else
{ {
input_thread_t *p_input;
p_main->p_playlist->b_stopped = 0; p_main->p_playlist->b_stopped = 0;
p_main->p_playlist->i_mode = PLAYLIST_FORWARD + p_main->p_playlist->i_mode = PLAYLIST_FORWARD +
main_GetIntVariable( PLAYLIST_LOOP_VAR, main_GetIntVariable( PLAYLIST_LOOP_VAR,
PLAYLIST_LOOP_DEFAULT ); PLAYLIST_LOOP_DEFAULT );
intf_WarnMsg( 3, "intf: creating new input thread" ); intf_WarnMsg( 3, "intf: creating new input thread" );
p_input_bank->pp_input[0] = p_input = input_CreateThread( &p_main->p_playlist->current,
input_CreateThread( &p_main->p_playlist->current, NULL ); NULL );
p_input_bank->i_count++; if( p_input != NULL )
{
p_input_bank->pp_input[ p_input_bank->i_count ] = p_input;
p_input_bank->i_count++;
}
} }
} }
else else
......
/*****************************************************************************
* intf_eject.c: CD/DVD-ROM ejection handling functions
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: intf_eject.c,v 1.1 2002/01/09 02:01:14 sam Exp $
*
* Author: Julien Blache <jb@technologeek.org> for the Linux part
* with code taken from the Linux "eject" command
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <videolan/vlc.h>
#ifdef SYS_LINUX
/* This code could be extended to support CD/DVD-ROM chargers */
# include <linux/version.h>
/* handy macro found in 2.1 kernels, but not in older ones */
# ifndef KERNEL_VERSION
# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
# endif
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/ioctl.h>
# include <fcntl.h>
# include <sys/ioctl.h>
# include <linux/cdrom.h>
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
# include <linux/ucdrom.h>
# endif
# include <sys/mount.h>
# include <scsi/scsi.h>
# include <scsi/sg.h>
# include <scsi/scsi_ioctl.h>
#endif
static int EjectCdrom( int i_fd );
static int EjectScsi ( int i_fd );
/*
* Eject using CDROMEJECT ioctl. Return 0 if successful
*/
static int EjectCdrom( int i_fd )
{
int i_status;
i_status = ioctl( i_fd, CDROMEJECT );
return i_status;
}
/*
* Eject using SCSI commands. Return 0 if successful
*/
static int EjectScsi( int i_fd )
{
int i_status;
struct sdata
{
int inlen;
int outlen;
char cmd[256];
} scsi_cmd;
scsi_cmd.inlen = 0;
scsi_cmd.outlen = 0;
scsi_cmd.cmd[0] = ALLOW_MEDIUM_REMOVAL;
scsi_cmd.cmd[1] = 0;
scsi_cmd.cmd[2] = 0;
scsi_cmd.cmd[3] = 0;
scsi_cmd.cmd[4] = 0;
scsi_cmd.cmd[5] = 0;
i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd );
if( i_status != 0 )
{
return 1;
}
scsi_cmd.inlen = 0;
scsi_cmd.outlen = 0;
scsi_cmd.cmd[0] = START_STOP;
scsi_cmd.cmd[1] = 0;
scsi_cmd.cmd[2] = 0;
scsi_cmd.cmd[3] = 0;
scsi_cmd.cmd[4] = 1;
scsi_cmd.cmd[5] = 0;
i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd );
if( i_status != 0 )
{
return 1;
}
scsi_cmd.inlen = 0;
scsi_cmd.outlen = 0;
scsi_cmd.cmd[0] = START_STOP;
scsi_cmd.cmd[1] = 0;
scsi_cmd.cmd[2] = 0;
scsi_cmd.cmd[3] = 0;
scsi_cmd.cmd[4] = 2;
scsi_cmd.cmd[5] = 0;
i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd );
if( i_status != 0 )
{
return 1;
}
/* Force kernel to reread partition table when new disc inserted */
i_status = ioctl( i_fd, BLKRRPART );
return i_status;
}
/*
* returns 0 on success
* returns 1 on failure
* returns -1 if not implemented
*
* Modify eject_disc() prototype as needed for portability
*/
int intf_Eject( const char *psz_device )
{
int i_ret;
#ifdef SYS_LINUX
int i_fd = 0;
i_fd = open( psz_device, O_RDONLY | O_NONBLOCK );
if( i_fd == -1 )
{
intf_ErrMsg( "intf error: couldn't open device %s", psz_device );
return 1;
}
if( EjectCdrom(i_fd) == 0 )
{
i_ret = 0;
}
else if( EjectScsi(i_fd) == 0 )
{
i_ret = 0;
}
else
{
intf_ErrMsg( "intf error: couldn't eject %s", psz_device );
i_ret = 1;
}
close( i_fd );
#else
i_ret = -1;
#endif
return i_ret;
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* modules.c : Built-in and plugin modules management functions * modules.c : Built-in and plugin modules management functions
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: modules.c,v 1.46 2001/12/30 07:09:56 sam Exp $ * $Id: modules.c,v 1.47 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* Ethan C. Baldridge <BaldridgeE@cadmus.com> * Ethan C. Baldridge <BaldridgeE@cadmus.com>
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "interface.h" #include "interface.h"
#include "intf_playlist.h" #include "intf_playlist.h"
#include "intf_eject.h"
#include "stream_control.h" #include "stream_control.h"
#include "input_ext-intf.h" #include "input_ext-intf.h"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* modules_plugin.h : Plugin management functions used by the core application. * modules_plugin.h : Plugin management functions used by the core application.
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: modules_plugin.h,v 1.3 2002/01/07 02:12:30 sam Exp $ * $Id: modules_plugin.h,v 1.4 2002/01/09 02:01:14 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -174,6 +174,7 @@ module_error( void ) ...@@ -174,6 +174,7 @@ module_error( void )
(p_symbols)->intf_PlaylistDestroy = intf_PlaylistDestroy; \ (p_symbols)->intf_PlaylistDestroy = intf_PlaylistDestroy; \
(p_symbols)->intf_PlaylistJumpto = intf_PlaylistJumpto; \ (p_symbols)->intf_PlaylistJumpto = intf_PlaylistJumpto; \
(p_symbols)->intf_UrlDecode = intf_UrlDecode; \ (p_symbols)->intf_UrlDecode = intf_UrlDecode; \
(p_symbols)->intf_Eject = intf_Eject; \
(p_symbols)->msleep = msleep; \ (p_symbols)->msleep = msleep; \
(p_symbols)->mdate = mdate; \ (p_symbols)->mdate = mdate; \
(p_symbols)->network_ChannelCreate = network_ChannelCreate; \ (p_symbols)->network_ChannelCreate = network_ChannelCreate; \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment