Commit 27e0b63d authored by Vincent Seguin's avatar Vincent Seguin

Nettoyage.

parent 6dcda4bb
......@@ -119,10 +119,15 @@
/* Base delay in micro second for interface sleeps */
#define INTF_IDLE_SLEEP 100000
/* Factor for changing gamma, and minimum and maximum values */
#define INTF_GAMMA_FACTOR .1
/* Step for changing gamma, and minimum and maximum values */
#define INTF_GAMMA_STEP .1
#define INTF_GAMMA_MAX 3
/* Factor for changing aspect ratio, and minimum and maximum values */
#define INTF_RATIO_FACTOR 1.1
#define INTF_RATIO_MIN .1
#define INTF_RATIO_MAX 10
/*
* X11 settings
*/
......
......@@ -47,4 +47,5 @@ void intf_Run ( intf_thread_t * p_intf );
void intf_Destroy ( intf_thread_t * p_intf );
int intf_SelectInput ( intf_thread_t * p_intf, p_input_cfg_t p_cfg );
int intf_ProcessKey ( intf_thread_t * p_intf, int i_key );
......@@ -87,6 +87,7 @@ typedef struct vout_thread_s
vlc_thread_t thread_id; /* id for pthread functions */
vlc_mutex_t picture_lock; /* picture heap lock */
vlc_mutex_t subtitle_lock; /* subtitle heap lock */
vlc_mutex_t change_lock; /* thread change lock */
int * pi_status; /* temporary status flag */
p_vout_sys_t p_sys; /* system output method */
......@@ -105,15 +106,15 @@ typedef struct vout_thread_s
#ifdef STATS
/* Statistics - these numbers are not supposed to be accurate, but are a
* good indication of the thread status */
mtime_t loop_time; /* last picture loop time */
count_t c_fps_samples; /* picture counts */
mtime_t render_time; /* last picture render time */
count_t c_fps_samples; /* picture counts */
mtime_t fps_sample[ VOUT_FPS_SAMPLES ]; /* FPS samples dates */
#endif
/* Running properties */
u16 i_changes; /* changes made to the thread */
mtime_t last_picture_date; /* last picture display date */
mtime_t last_idle_date; /* last idle screen displaydate */
mtime_t last_display_date; /* last screen display date */
/* Videos heap and translation tables */
picture_t p_picture[VOUT_MAX_PICTURES]; /* pictures */
......@@ -133,16 +134,13 @@ typedef struct vout_thread_s
#define VOUT_DEPTH_CHANGE 0x0008 /* depth changed */
#define VOUT_RATIO_CHANGE 0x0010 /* display ratio changed */
#define VOUT_GAMMA_CHANGE 0x0020 /* gamma changed */
#define VOUT_NODISPLAY_CHANGE 0xffdc /* changes which forbiden the display */
/*******************************************************************************
* Prototypes
*******************************************************************************/
vout_thread_t * vout_CreateThread (
#ifdef VIDEO_X11
char *psz_display, Window root_window,
#endif
int i_width, int i_height, int *pi_status
);
vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window,
int i_width, int i_height, int *pi_status );
void vout_DestroyThread ( vout_thread_t *p_vout, int *pi_status );
picture_t * vout_CreatePicture ( vout_thread_t *p_vout, int i_type,
int i_width, int i_height );
......
......@@ -6,11 +6,7 @@
/*******************************************************************************
* Prototypes
*******************************************************************************/
int vout_SysCreate ( p_vout_thread_t p_vout
#ifdef VIDEO_X11
, char *psz_display, Window root_window
#endif
);
int vout_SysCreate ( p_vout_thread_t p_vout, char *psz_display, int i_root_window );
int vout_SysInit ( p_vout_thread_t p_vout );
void vout_SysEnd ( p_vout_thread_t p_vout );
void vout_SysDestroy ( p_vout_thread_t p_vout );
......
......@@ -26,6 +26,8 @@
#include "intf_cmd.h"
#include "intf_console.h"
#include "main.h"
#include "video.h"
#include "video_output.h"
#include "intf_sys.h"
......@@ -96,6 +98,19 @@ void intf_Run( intf_thread_t *p_intf )
/* Manage specific interface */
intf_SysManage( p_intf );
/* Check attached threads status */
if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_error )
{
//?? add aout error detection
p_intf->b_die = 1;
}
if( (p_intf->p_input != NULL) && p_intf->p_input->b_error )
{
input_DestroyThread( p_intf->p_input /*, NULL */ );
p_intf->p_input = NULL;
intf_DbgMsg("Input thread destroyed\n");
}
/* Sleep to avoid using all CPU - since some interfaces needs to access
* keyboard events, a 100ms delay is a good compromise */
msleep( INTF_IDLE_SLEEP );
......@@ -143,4 +158,124 @@ int intf_SelectInput( intf_thread_t * p_intf, input_cfg_t *p_cfg )
return( (p_cfg != NULL) && (p_intf->p_input == NULL) );
}
/*******************************************************************************
* intf_ProcessKey: process standard keys
*******************************************************************************
* This function will process standard keys and return non 0 if the key was
* unknown.
*******************************************************************************/
int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
{
switch( i_key )
{
case 'Q': /* quit order */
case 'q':
case 27:
p_intf->b_die = 1;
break;
case '0': /* source change */
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
// ??
break;
case '+': /* volume + */
// ??
break;
case '-': /* volume - */
// ??
break;
case 'M': /* toggle mute */
case 'm':
// ??
break;
case 'g': /* gamma - */
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma > -INTF_GAMMA_MAX) )
{
vlc_mutex_lock( &p_intf->p_vout->change_lock );
p_intf->p_vout->f_gamma -= INTF_GAMMA_STEP;
p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
}
break;
case 'G': /* gamma + */
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma < INTF_GAMMA_MAX) )
{
vlc_mutex_lock( &p_intf->p_vout->change_lock );
p_intf->p_vout->f_gamma += INTF_GAMMA_STEP;
p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
}
break;
case 'c': /* toggle grayscale */
if( p_intf->p_vout != NULL )
{
vlc_mutex_lock( &p_intf->p_vout->change_lock );
p_intf->p_vout->b_grayscale = !p_intf->p_vout->b_grayscale;
p_intf->p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE;
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
}
break;
case 'x': /* horizontal aspect ratio - */
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_x_ratio > INTF_RATIO_MIN) )
{
vlc_mutex_lock( &p_intf->p_vout->change_lock );
p_intf->p_vout->f_x_ratio /= INTF_RATIO_FACTOR;
p_intf->p_vout->i_changes |= VOUT_RATIO_CHANGE;
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
}
break;
case 'X': /* horizontal aspect ratio + */
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_x_ratio < INTF_RATIO_MAX) )
{
vlc_mutex_lock( &p_intf->p_vout->change_lock );
p_intf->p_vout->f_x_ratio *= INTF_RATIO_FACTOR;
p_intf->p_vout->i_changes |= VOUT_RATIO_CHANGE;
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
}
break;
case 'y': /* vertical aspect ratio - */
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_y_ratio > INTF_RATIO_MIN) )
{
vlc_mutex_lock( &p_intf->p_vout->change_lock );
p_intf->p_vout->f_y_ratio /= INTF_RATIO_FACTOR;
p_intf->p_vout->i_changes |= VOUT_RATIO_CHANGE;
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
}
break;
case 'Y': /* horizontal aspect ratio + */
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_y_ratio < INTF_RATIO_MAX) )
{
vlc_mutex_lock( &p_intf->p_vout->change_lock );
p_intf->p_vout->f_y_ratio *= INTF_RATIO_FACTOR;
p_intf->p_vout->i_changes |= VOUT_RATIO_CHANGE;
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
}
break;
case 'f': /* toggle fullscreen */
//??
break;
case ' ': /* toggle info */
if( p_intf->p_vout != NULL )
{
vlc_mutex_lock( &p_intf->p_vout->change_lock );
p_intf->p_vout->b_info = !p_intf->p_vout->b_info;
p_intf->p_vout->i_changes |= VOUT_INFO_CHANGE;
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
}
break;
default: /* unknown key */
return( 1 );
}
return( 0 );
}
......@@ -380,7 +380,8 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
*******************************************************************************/
static void Usage( void )
{
intf_Msg(COPYRIGHT_MESSAGE);
intf_Msg(COPYRIGHT_MESSAGE "\n");
/* Usage */
intf_Msg("usage: vlc [options...] [parameters]\n" \
" parameters can be passed using environment variables\n" \
......@@ -425,12 +426,11 @@ static void Usage( void )
/* Interfaces keys */
intf_Msg("Interface keys: most interface accept the following commands:\n" \
" [esc], q quit\n" \
" +, - change volume\n" \
" m mute\n" \
" f fullscreen\n" \
" +, -, m change volume, mute\n" \
" g, G, c change gamma, toggle grayscale\n" \
" x, X, y, Y, f change aspect ratio, toggle fullscreen\n" \
" 0 - 9 select channel\n" \
" [space] toggle info printing\n" \
" g, G change gamma\n" \
);
}
......
......@@ -15,10 +15,6 @@
#include <stdio.h>
#include <string.h>
#ifdef VIDEO_X11
#include <X11/Xlib.h> /* for video_sys.h in X11 mode */
#endif
#include "common.h"
#include "config.h"
#include "mtime.h"
......@@ -37,10 +33,11 @@ static int InitThread ( vout_thread_t *p_vout );
static void RunThread ( vout_thread_t *p_vout );
static void ErrorThread ( vout_thread_t *p_vout );
static void EndThread ( vout_thread_t *p_vout );
static void RenderPicture ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderPictureInfo ( vout_thread_t *p_vout, picture_t *p_pic );
static int RenderIdle ( vout_thread_t *p_vout );
static int RenderInfo ( vout_thread_t *p_vout );
static void RenderBlank ( vout_thread_t *p_vout );
static int RenderPicture ( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank );
static int RenderPictureInfo ( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank );
static int RenderIdle ( vout_thread_t *p_vout, boolean_t b_blank );
static int RenderInfo ( vout_thread_t *p_vout, boolean_t b_balnk );
static int Manage ( vout_thread_t *p_vout );
/*******************************************************************************
......@@ -51,12 +48,8 @@ static int Manage ( vout_thread_t *p_vout );
* If pi_status is NULL, then the function will block until the thread is ready.
* If not, it will be updated using one of the THREAD_* constants.
*******************************************************************************/
vout_thread_t * vout_CreateThread (
#ifdef VIDEO_X11
char *psz_display, Window root_window,
#endif
int i_width, int i_height, int *pi_status
)
vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window,
int i_width, int i_height, int *pi_status )
{
vout_thread_t * p_vout; /* thread descriptor */
int i_status; /* thread status */
......@@ -100,11 +93,7 @@ vout_thread_t * vout_CreateThread (
/* Create and initialize system-dependant method - this function issues its
* own error messages */
if( vout_SysCreate( p_vout
#if defined(VIDEO_X11)
, psz_display, root_window
#endif
) )
if( vout_SysCreate( p_vout, psz_display, i_root_window ) )
{
free( p_vout );
return( NULL );
......@@ -116,15 +105,21 @@ vout_thread_t * vout_CreateThread (
#ifdef STATS
/* Initialize statistics fields */
p_vout->loop_time = 0;
p_vout->render_time = 0;
p_vout->c_fps_samples = 0;
#endif
/* Initialize running properties */
p_vout->i_changes = 0;
p_vout->last_picture_date = 0;
p_vout->last_display_date = 0;
/* Create thread and set locks */
vlc_mutex_init( &p_vout->picture_lock );
vlc_mutex_init( &p_vout->subtitle_lock );
if( vlc_thread_create( &p_vout->thread_id, "video output",
(void *) RunThread, (void *) p_vout) )
vlc_mutex_init( &p_vout->change_lock );
vlc_mutex_lock( &p_vout->change_lock );
if( vlc_thread_create( &p_vout->thread_id, "video output", (void *) RunThread, (void *) p_vout) )
{
intf_ErrMsg("error: %s\n", strerror(ENOMEM));
vout_SysDestroy( p_vout );
......@@ -615,7 +610,6 @@ static void RunThread( vout_thread_t *p_vout)
p_pic = NULL;
}
}
/*
* Perform rendering, sleep and display rendered picture
......@@ -625,13 +619,12 @@ static void RunThread( vout_thread_t *p_vout)
/* A picture is ready to be displayed : render it */
if( p_vout->b_active )
{
RenderPicture( p_vout, p_pic );
b_display = RenderPicture( p_vout, p_pic, 1 );
if( p_vout->b_info )
{
RenderPictureInfo( p_vout, p_pic );
RenderInfo( p_vout );
b_display |= RenderPictureInfo( p_vout, p_pic, b_display );
b_display |= RenderInfo( p_vout, b_display );
}
b_display = 1;
}
else
{
......@@ -646,17 +639,26 @@ static void RunThread( vout_thread_t *p_vout)
else
{
/* No picture. However, an idle screen may be ready to display */
b_display = p_vout->b_active && ( RenderIdle( p_vout ) |
( p_vout->b_info && RenderInfo( p_vout ) ));
if( p_vout->b_active )
{
b_display = RenderIdle( p_vout, 1 );
if( p_vout->b_info )
{
b_display |= RenderInfo( p_vout, b_display );
}
}
else
{
b_display = 0;
}
}
/* Give back change lock */
vlc_mutex_unlock( &p_vout->change_lock );
/* Sleep a while or until a given date */
if( p_pic )
{
#ifdef STATS
/* Computes loop time */
p_vout->loop_time = mdate() - current_date;
#endif
mwait( pic_date );
}
else
......@@ -664,8 +666,10 @@ static void RunThread( vout_thread_t *p_vout)
msleep( VOUT_IDLE_SLEEP );
}
/* On awakening, send immediately picture to display */
if( b_display && p_vout->b_active )
/* On awakening, take back lock and send immediately picture to display */
vlc_mutex_lock( &p_vout->change_lock );
if( b_display && p_vout->b_active &&
!(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) )
{
vout_SysDisplay( p_vout );
}
......@@ -748,6 +752,48 @@ static void EndThread( vout_thread_t *p_vout )
*pi_status = THREAD_OVER;
}
/*******************************************************************************
* RenderBlank: render a blank screen
*******************************************************************************
* This function is called by all other rendering functions when they arrive on
* a non blanked screen.
*******************************************************************************/
static void RenderBlank( vout_thread_t *p_vout )
{
int i_index; /* current 32 bits sample */
int i_width; /* number of 32 bits samples */
u32 *p_pic; /* pointer to 32 bits samples */
/* Initialize variables */
p_pic = vout_SysGetPicture( p_vout );
i_width = p_vout->i_bytes_per_line * p_vout->i_height / 128;
/* Clear beginning of screen by 128 bytes blocks */
for( i_index = 0; i_index < i_width; i_index++ )
{
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
*p_pic++ = 0; *p_pic++ = 0;
}
/* Clear last pixels */
//??
}
/*******************************************************************************
* RenderPicture: render a picture
*******************************************************************************
......@@ -756,8 +802,17 @@ static void EndThread( vout_thread_t *p_vout )
* rendered picture has been determined as existant, and will only be destroyed
* by the vout thread later.
*******************************************************************************/
static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
static int RenderPicture( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank )
{
/* Mark last picture date */
p_vout->last_picture_date = p_pic->date;
/* Blank screen if required */
if( b_blank )
{
RenderBlank( p_vout );
}
/*
* Prepare scaling
*/
......@@ -769,7 +824,6 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
* XImages */
/* p_vout->i_new_width = p_pic->i_width;
p_vout->i_new_height = p_pic->i_height;*/
return;
#else
/* Other drivers: the video output thread can't change its size, so
* we need to change the aspect ratio */
......@@ -815,6 +869,8 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
* Terminate scaling
*/
//??
return( 1 );
}
......@@ -822,16 +878,12 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
/*******************************************************************************
* RenderPictureInfo: print additionnal informations on a picture
*******************************************************************************
* This function will add informations such as fps and buffer size on a picture
* This function will print informations such as fps and other picture
* dependant informations.
*******************************************************************************/
static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
static int RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank )
{
char psz_buffer[256]; /* string buffer */
#ifdef DEBUG
int i_ready_pic = 0; /* ready pictures */
int i_reserved_pic = 0; /* reserved pictures */
int i_picture; /* picture index */
#endif
#ifdef STATS
/*
......@@ -846,37 +898,32 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
}
/*
* Print statistics in upper left corner
* Print frames count and loop time in upper left corner
*/
sprintf( psz_buffer, "gamma=%.2f %ld frames",
p_vout->f_gamma, p_vout->c_fps_samples );
sprintf( psz_buffer, "%ld frames render time: %lu us",
p_vout->c_fps_samples, (long unsigned) p_vout->render_time );
vout_SysPrint( p_vout, 0, 0, -1, -1, psz_buffer );
#endif
#ifdef DEBUG
/*
* Print heap state in lower left corner
/*
* Print picture information in lower right corner
*/
for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ )
{
switch( p_vout->p_picture[i_picture].i_status )
{
case RESERVED_PICTURE:
i_reserved_pic++;
break;
case READY_PICTURE:
i_ready_pic++;
break;
}
}
sprintf( psz_buffer, "video heap: %d/%d/%d", i_reserved_pic, i_ready_pic,
VOUT_MAX_PICTURES );
vout_SysPrint( p_vout, 0, p_vout->i_height, -1, 1, psz_buffer );
#endif
#ifdef DEBUG_VIDEO
//??
sprintf( psz_buffer, "%s picture (mc=%d) %dx%d (%dx%d%+d%+d ar=%s)",
(p_pic->i_type == YUV_420_PICTURE) ? "4:2:0" :
((p_pic->i_type == YUV_422_PICTURE) ? "4:2:2" :
((p_pic->i_type == YUV_444_PICTURE) ? "4:4:4" : "?")),
p_pic->i_matrix_coefficients, p_pic->i_width, p_pic->i_height,
p_pic->i_display_width, p_pic->i_display_height,
p_pic->i_display_horizontal_offset, p_pic->i_display_vertical_offset,
(p_pic->i_aspect_ratio == AR_SQUARE_PICTURE) ? "square" :
((p_pic->i_aspect_ratio == AR_3_4_PICTURE) ? "4:3" :
((p_pic->i_aspect_ratio == AR_16_9_PICTURE) ? "16:9" :
((p_pic->i_aspect_ratio == AR_221_1_PICTURE) ? "2.21:1" : "?" ))));
vout_SysPrint( p_vout, p_vout->i_width, p_vout->i_height, 1, 1, psz_buffer );
#endif
return( 0 );
}
/*******************************************************************************
......@@ -884,31 +931,80 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
*******************************************************************************
* This function will clear the display or print a logo.
*******************************************************************************/
static int RenderIdle( vout_thread_t *p_vout )
static int RenderIdle( vout_thread_t *p_vout, boolean_t b_blank )
{
//??
/* Blank screen if required */
if( (mdate() - p_vout->last_picture_date > VOUT_IDLE_DELAY) &&
(p_vout->last_picture_date > p_vout->last_display_date) &&
b_blank )
{
RenderBlank( p_vout );
p_vout->last_display_date = mdate();
vout_SysPrint( p_vout, p_vout->i_width / 2, p_vout->i_height / 2, 0, 0,
"no stream" );
return( 1 );
}
return( 0 );
}
/*******************************************************************************
* RenderInfo: render additionnal informations
*******************************************************************************
* ??
* This function render informations which do not depend of the current picture
* rendered.
*******************************************************************************/
static int RenderInfo( vout_thread_t *p_vout )
static int RenderInfo( vout_thread_t *p_vout, boolean_t b_blank )
{
//??
char psz_buffer[256]; /* string buffer */
#ifdef DEBUG
int i_ready_pic = 0; /* ready pictures */
int i_reserved_pic = 0; /* reserved pictures */
int i_picture; /* picture index */
#endif
#ifdef DEBUG
/*
* Print thread state in lower left corner
*/
for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ )
{
switch( p_vout->p_picture[i_picture].i_status )
{
case RESERVED_PICTURE:
i_reserved_pic++;
break;
case READY_PICTURE:
i_ready_pic++;
break;
}
}
sprintf( psz_buffer, "%s %dx%d:%d %.2f:%.2f g%+.2f pic: %d/%d/%d",
p_vout->b_grayscale ? "gray" : "rgb",
p_vout->i_width, p_vout->i_height,
p_vout->i_screen_depth, p_vout->f_x_ratio, p_vout->f_y_ratio, p_vout->f_gamma,
i_reserved_pic, i_ready_pic,
VOUT_MAX_PICTURES );
vout_SysPrint( p_vout, 0, p_vout->i_height, -1, 1, psz_buffer );
#endif
return( 0 );
}
/*******************************************************************************
* Manage: manage thread
*******************************************************************************
* ??
* This function will handle changes in thread configuration.
*******************************************************************************/
static int Manage( vout_thread_t *p_vout )
{
//??
/* On gamma or grayscale change, rebuild tables */
if( p_vout->i_changes & (VOUT_GAMMA_CHANGE | VOUT_GRAYSCALE_CHANGE) )
{
vout_ResetTables( p_vout );
}
/* Clear changes flags which does not need management or have been handled */
p_vout->i_changes &= ~(VOUT_INFO_CHANGE | VOUT_GAMMA_CHANGE | VOUT_GRAYSCALE_CHANGE);
/* Detect unauthorized changes */
if( p_vout->i_changes )
......
......@@ -82,7 +82,7 @@ static void X11DestroyShmImage ( vout_thread_t *p_vout, XImage *p_ximage,
* vout properties to choose the window size, and change them according to the
* actual properties of the display.
*******************************************************************************/
int vout_SysCreate( vout_thread_t *p_vout, char *psz_display, Window root_window )
int vout_SysCreate( vout_thread_t *p_vout, char *psz_display, int i_root_window )
{
/* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
......@@ -96,7 +96,7 @@ int vout_SysCreate( vout_thread_t *p_vout, char *psz_display, Window root_window
* Since XLib is usually not thread-safe, we can't use the same display
* pointer than the interface or another thread. However, the root window
* id is still valid. */
if( X11OpenDisplay( p_vout, psz_display, root_window ) )
if( X11OpenDisplay( p_vout, psz_display, i_root_window ) )
{
intf_ErrMsg("error: can't initialize X11 display\n" );
free( p_vout->p_sys );
......@@ -259,7 +259,7 @@ void vout_SysDisplay( vout_thread_t *p_vout )
p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->height);
/* Send the order to the X server */
XFlush(p_vout->p_sys->p_display); /* ?? not needed ? */
XFlush(p_vout->p_sys->p_display);
}
/* Swap buffers */
......@@ -291,17 +291,19 @@ void vout_SysPrint( vout_thread_t *p_vout, int i_x, int i_y, int i_halign,
int i_byte; /* byte offset in character line */
int i_height; /* character height */
int i_char_bytes_per_line; /* total bytes per line */
int i_text_width; /* total text width */
byte_t * pi_pic; /* picture data */
byte_t * pi_char; /* character data */
/* Update upper left coordinates according to alignment */
i_text_width = p_vout->p_sys->i_char_interspacing * strlen( psz_text );
switch( i_halign )
{
case 0: /* centered */
i_x -= p_vout->p_sys->i_char_interspacing * strlen( psz_text ) / 2;
i_x -= i_text_width / 2;
break;
case 1: /* right aligned */
i_x -= p_vout->p_sys->i_char_interspacing * strlen( psz_text );
i_x -= i_text_width;
break;
}
switch( i_valign )
......@@ -318,11 +320,20 @@ void vout_SysPrint( vout_thread_t *p_vout, int i_x, int i_y, int i_halign,
i_height = p_vout->p_sys->i_char_height;
i_char_bytes_per_line = p_vout->p_sys->i_char_bytes_per_line;
/* Check that the text is in the screen vertically and horizontally */
if( (i_y < 0) || (i_y + i_height > p_vout->i_height) || (i_x < 0) ||
(i_x + i_text_width > p_vout->i_width) )
{
intf_DbgMsg("text '%s' would print outside the screen\n", psz_text);
return;
}
/* Print text */
for( ; *psz_text != '\0'; psz_text++ )
{
/* Check that the character is valid and in the screen horizontally */
if( (*psz_text >= VOUT_MIN_CHAR) && (*psz_text < VOUT_MAX_CHAR) )
{
{
/* Select character */
pi_char = p_vout->p_sys->pi_font + (*psz_text - VOUT_MIN_CHAR) *
i_height * i_char_bytes_per_line;
......