* xcommon.c: Functions common to the X11 and XVideo plugins
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: xcommon.c,v 1.13 2002/01/21 00:52:07 sam Exp $
+ * $Id: xcommon.c,v 1.34 2002/05/20 22:30:19 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
#include <videolan/vlc.h>
#ifdef HAVE_MACHINE_PARAM_H
-/* BSD */
-#include <machine/param.h>
-#include <sys/types.h> /* typedef ushort */
-#include <sys/ipc.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 */
+# include <netinet/in.h> /* BSD: struct in_addr */
+#endif
+
+#ifdef HAVE_SYS_SHM_H
+# include <sys/shm.h> /* shmget(), shmctl() */
#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>
+#ifdef HAVE_SYS_SHM_H
+# include <X11/extensions/XShm.h>
+#endif
+#ifdef DPMSINFO_IN_DPMS_H
+# include <X11/extensions/dpms.h>
+#endif
#ifdef MODULE_NAME_IS_xvideo
# include <X11/extensions/Xv.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-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 FreePicture ( vout_thread_t *, picture_t * );
static IMAGE_TYPE *CreateImage ( Display *, EXTRA_ARGS, int, int );
+#ifdef HAVE_SYS_SHM_H
static IMAGE_TYPE *CreateShmImage ( Display *, EXTRA_ARGS_SHM, int, int );
+#endif
static void ToggleFullScreen ( vout_thread_t * );
static void XVideoReleasePort ( Display *, int );
#endif
+#ifdef MODULE_NAME_IS_x11
+static void SetPalette ( vout_thread_t *, u16 *, u16 *, u16 * );
+#endif
+
/*****************************************************************************
* vout_sys_t: video output method descriptor
*****************************************************************************
Visual * p_visual; /* visual pointer */
int i_screen; /* screen number */
- Window window; /* root window */
GC gc; /* graphic context instance handler */
+ Window window; /* root window */
+ Window video_window; /* sub-window for displaying video */
+#ifdef HAVE_SYS_SHM_H
boolean_t b_shm; /* shared memory extension flag */
+#endif
#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 */
int i_width; /* width of main window */
int i_height; /* height of main window */
+ boolean_t b_altfullscreen; /* which fullscreen method */
/* Backup of window position and size before fullscreen switch */
int i_width_backup;
int i_ss_interval; /* interval between changes */
int i_ss_blanking; /* blanking mode */
int i_ss_exposure; /* exposure mode */
+#ifdef DPMSINFO_IN_DPMS_H
BOOL b_ss_dpms; /* DPMS mode */
+#endif
/* 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 */
+ mtime_t i_time_button_last_pressed; /* to track dbl-clicks */
Pixmap cursor_pixmap;
} vout_sys_t;
{
IMAGE_TYPE * p_image;
+#ifdef HAVE_SYS_SHM_H
XShmSegmentInfo shminfo; /* shared memory zone information */
+#endif
} picture_sys_t;
/*****************************************************************************
* Seeking function TODO: put this in a generic location !
*****************************************************************************/
-static __inline__ void vout_Seek( off_t i_seek )
+static inline void vout_Seek( off_t i_seek )
{
off_t i_tell;
*****************************************************************************/
void _M( 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_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
*****************************************************************************
*****************************************************************************/
static int vout_Create( vout_thread_t *p_vout )
{
- char *psz_display;
+ char * psz_display;
+#ifdef MODULE_NAME_IS_xvideo
+ char * psz_chroma;
+ u32 i_chroma = 0;
+ boolean_t b_chroma = 0;
+#endif
/* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
return( 1 );
}
- /* Open display, unsing 'vlc_display' or DISPLAY environment variable */
- psz_display = XDisplayName( main_GetPszVariable( VOUT_DISPLAY_VAR, NULL ) );
+ /* Open display, unsing the "display" config variable or the DISPLAY
+ * environment variable */
+ psz_display = config_GetPszVariable( MODULE_STRING "-display" );
+
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 );
+ intf_ErrMsg( "vout error: cannot open display %s",
+ XDisplayName( psz_display ) );
free( p_vout->p_sys );
+ if( psz_display ) free( psz_display );
return( 1 );
}
+ if( psz_display ) free( psz_display );
+
p_vout->p_sys->i_screen = DefaultScreen( p_vout->p_sys->p_display );
#ifdef MODULE_NAME_IS_xvideo
+ psz_chroma = config_GetPszVariable( "xvideo-chroma" );
+ if( psz_chroma )
+ {
+ if( strlen( psz_chroma ) >= 4 )
+ {
+ i_chroma = (unsigned char)psz_chroma[0] << 0;
+ i_chroma |= (unsigned char)psz_chroma[1] << 8;
+ i_chroma |= (unsigned char)psz_chroma[2] << 16;
+ i_chroma |= (unsigned char)psz_chroma[3] << 24;
+
+ b_chroma = 1;
+ }
+
+ free( psz_chroma );
+ }
+
+ if( b_chroma )
+ {
+ intf_WarnMsg( 3, "vout info: forcing chroma 0x%.8x (%4.4s)",
+ i_chroma, (char*)&i_chroma );
+ }
+ else
+ {
+ i_chroma = p_vout->render.i_chroma;
+ }
+
/* Check that we have access to an XVideo port providing this chroma */
p_vout->p_sys->i_xvport = XVideoGetPort( p_vout->p_sys->p_display,
- p_vout->render.i_chroma,
+ i_chroma,
&p_vout->output.i_chroma );
if( p_vout->p_sys->i_xvport < 0 )
{
+ /* If a specific chroma format was requested, then we don't try to
+ * be cleverer than the user. He knows pretty well what he wants. */
+ if( b_chroma )
+ {
+ XCloseDisplay( p_vout->p_sys->p_display );
+ free( p_vout->p_sys );
+ return 1;
+ }
+
/* It failed, but it's not completely lost ! We try to open an
* XVideo port for an YUY2 picture. We'll need to do an YUV
* conversion, but at least it has got scaling. */
#endif
/* Create blank cursor (for mouse cursor autohiding) */
+ p_vout->p_sys->i_time_mouse_last_moved = mdate();
p_vout->p_sys->b_mouse_pointer_visible = 1;
CreateCursor( p_vout );
return( 1 );
}
- /* Disable screen saver and return */
+ /* Disable screen saver */
DisableXScreenSaver( p_vout );
+ /* Misc init */
+ p_vout->p_sys->b_altfullscreen = 0;
+ p_vout->p_sys->i_time_button_last_pressed = 0;
+
return( 0 );
}
ToggleCursor( p_vout );
}
-#ifdef MODULE_NAME_IS_xvideo
- XVideoReleasePort( p_vout->p_sys->p_display, p_vout->p_sys->i_xvport );
-#else
-#if 0
+#ifdef MODULE_NAME_IS_x11
/* Destroy colormap */
- if( p_vout->p_sys->i_screen_depth == 8 )
+ if( XDefaultDepth(p_vout->p_sys->p_display, p_vout->p_sys->i_screen) == 8 )
{
XFreeColormap( p_vout->p_sys->p_display, p_vout->p_sys->colormap );
}
-#endif
+#else
+ XVideoReleasePort( p_vout->p_sys->p_display, p_vout->p_sys->i_xvport );
#endif
DestroyCursor( p_vout );
p_vout->output.i_height = p_vout->render.i_height;
p_vout->output.i_aspect = p_vout->render.i_aspect;
+ switch( p_vout->output.i_chroma )
+ {
+ case FOURCC_RV15:
+ p_vout->output.i_rmask = 0x001f;
+ p_vout->output.i_gmask = 0x07e0;
+ p_vout->output.i_bmask = 0xf800;
+ break;
+ case FOURCC_RV16:
+ p_vout->output.i_rmask = 0x001f;
+ p_vout->output.i_gmask = 0x03e0;
+ p_vout->output.i_bmask = 0x7c00;
+ break;
+ }
+
#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;
+ p_vout->output.i_chroma = FOURCC_RGB2; 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;
+ p_vout->output.i_chroma = FOURCC_RV24; break;
case 32:
- p_vout->output.i_chroma = FOURCC_BI_BITFIELDS; break;
+ p_vout->output.i_chroma = FOURCC_RV24; 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;
+ vout_PlacePicture( p_vout, p_vout->p_sys->i_width,
+ p_vout->p_sys->i_height,
+ &i_index, &i_index,
+ &p_vout->output.i_width, &p_vout->output.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;
+ p_vout->output.i_aspect = p_vout->output.i_width
+ * VOUT_ASPECT_FACTOR / p_vout->output.i_height;
#endif
/* Try to initialize up to MAX_DIRECTBUFFERS direct buffers */
/* 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 )
+ if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
{
p_pic = p_vout->p_picture + i_index;
break;
vout_PlacePicture( p_vout, p_vout->p_sys->i_width, p_vout->p_sys->i_height,
&i_x, &i_y, &i_width, &i_height );
+#ifdef HAVE_SYS_SHM_H
if( p_vout->p_sys->b_shm )
{
/* Display rendered image using shared memory extension */
-#ifdef MODULE_NAME_IS_xvideo
+# ifdef MODULE_NAME_IS_xvideo
XvShmPutImage( p_vout->p_sys->p_display, p_vout->p_sys->i_xvport,
- p_vout->p_sys->yuv_window, p_vout->p_sys->gc,
+ p_vout->p_sys->video_window, p_vout->p_sys->gc,
p_pic->p_sys->p_image, 0 /*src_x*/, 0 /*src_y*/,
p_vout->output.i_width, p_vout->output.i_height,
0 /*dest_x*/, 0 /*dest_y*/, i_width, i_height,
False /* Don't put True here or you'll waste your CPU */ );
-#else
- XShmPutImage( p_vout->p_sys->p_display, p_vout->p_sys->window,
+# else
+ XShmPutImage( p_vout->p_sys->p_display, p_vout->p_sys->video_window,
p_vout->p_sys->gc, p_pic->p_sys->p_image,
0 /*src_x*/, 0 /*src_y*/, 0 /*dest_x*/, 0 /*dest_y*/,
p_vout->output.i_width, p_vout->output.i_height,
False /* Don't put True here ! */ );
-#endif
+# endif
}
else
+#endif /* HAVE_SYS_SHM_H */
{
/* Use standard XPutImage -- this is gonna be slow ! */
#ifdef MODULE_NAME_IS_xvideo
XvPutImage( p_vout->p_sys->p_display, p_vout->p_sys->i_xvport,
- p_vout->p_sys->yuv_window, p_vout->p_sys->gc,
+ p_vout->p_sys->video_window, p_vout->p_sys->gc,
p_pic->p_sys->p_image, 0 /*src_x*/, 0 /*src_y*/,
p_vout->output.i_width, p_vout->output.i_height,
0 /*dest_x*/, 0 /*dest_y*/, i_width, i_height );
#else
- XPutImage( p_vout->p_sys->p_display, p_vout->p_sys->window,
+ XPutImage( p_vout->p_sys->p_display, p_vout->p_sys->video_window,
p_vout->p_sys->gc, p_pic->p_sys->p_image,
0 /*src_x*/, 0 /*src_y*/, 0 /*dest_x*/, 0 /*dest_y*/,
p_vout->output.i_width, p_vout->output.i_height );
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;
* 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 |
|| (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;
switch( x_key_symbol )
{
case XK_Escape:
- p_main->p_intf->b_die = 1;
+ if( p_vout->b_fullscreen )
+ {
+ p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+ }
+ else
+ {
+ p_main->p_intf->b_die = 1;
+ }
break;
case XK_Menu:
p_main->p_intf->b_menu_change = 1;
case '9': network_ChannelJoin( 9 ); break;
default:
- intf_DbgMsg( "vout: unhandled key '%c' (%i)",
- (char)i_key, i_key );
break;
}
}
{
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 );
+ * clicks for DVD navigation for instance. */
+
+ /* detect double-clicks */
+ if( ( ((XButtonEvent *)&xevent)->time -
+ p_vout->p_sys->i_time_button_last_pressed ) < 300 )
+ p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+
+ p_vout->p_sys->i_time_button_last_pressed =
+ ((XButtonEvent *)&xevent)->time;
break;
case Button4:
}
}
-#ifdef MODULE_NAME_IS_xvideo
- /* Handle events for YUV video output sub-window */
+ /* Handle events for video output sub-window */
while( XCheckWindowEvent( p_vout->p_sys->p_display,
- p_vout->p_sys->yuv_window,
+ p_vout->p_sys->video_window,
ExposureMask, &xevent ) == True )
{
/* Window exposed (only handled if stream playback is paused) */
if( p_input_bank->pp_input[0] != NULL )
{
if( PAUSE_S ==
- p_input_bank->pp_input[0]->stream.control.i_status )
+ p_input_bank->pp_input[0]->stream.control.i_status )
{
-/* XVideoDisplay( p_vout )*/;
+ /* XVideoDisplay( p_vout )*/;
}
}
}
}
}
-#endif
/* ClientMessage event - only WM_PROTOCOLS with WM_DELETE_WINDOW data
* are handled - according to the man pages, the format is always 32
{
p_main->p_intf->b_die = 1;
}
- else
- {
- intf_DbgMsg( "vout: unhandled ClientMessage received" );
- }
}
/*
}
-#ifdef MODULE_NAME_IS_x11
- /*
- * Handle vout window resizing
- */
-#if 0
- if( b_resized )
- {
- /* If interface window has been resized, change vout size */
- intf_DbgMsg( "vout: resizing output window" );
- p_vout->i_width = p_vout->p_sys->i_width;
- p_vout->i_height = p_vout->p_sys->i_height;
- p_vout->i_changes |= VOUT_SIZE_CHANGE;
- }
- else if( (p_vout->i_width != p_vout->p_sys->i_width) ||
- (p_vout->i_height != p_vout->p_sys->i_height) )
- {
- /* If video output size has changed, change interface window size */
- intf_DbgMsg( "vout: resizing output window" );
- p_vout->p_sys->i_width = p_vout->i_width;
- p_vout->p_sys->i_height = p_vout->i_height;
- XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
- p_vout->p_sys->i_width, p_vout->p_sys->i_height );
- }
- /*
- * Color/Grayscale or gamma change: in 8bpp, just change the colormap
- */
- if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE)
- && (p_vout->i_screen_depth == 8) )
- {
- /* FIXME: clear flags ?? */
- }
-
- /*
- * Size change
- */
- if( p_vout->i_changes & VOUT_SIZE_CHANGE )
- {
- intf_DbgMsg( "vout info: resizing window" );
- p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
-
- /* Resize window */
- XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
- p_vout->i_width, p_vout->i_height );
-
- /* Destroy XImages to change their size */
- vout_End( p_vout );
-
- /* Recreate XImages. If SysInit failed, the thread can't go on. */
- if( vout_Init( p_vout ) )
- {
- intf_ErrMsg( "vout error: cannot resize display" );
- return( 1 );
- }
-
- /* Tell the video output thread that it will need to rebuild YUV
- * tables. This is needed since conversion buffer size may have
- * changed */
- p_vout->i_changes |= VOUT_YUV_CHANGE;
- intf_Msg( "vout: video display resized (%dx%d)",
- p_vout->i_width, p_vout->i_height);
- }
-#endif /* #if 0 */
-#else
/*
* Size change
*
p_vout->p_sys->i_width,
p_vout->p_sys->i_height );
+#ifdef MODULE_NAME_IS_x11
+ /* We need to signal the vout thread about the size change because it
+ * is doing the rescaling */
+ p_vout->i_changes |= VOUT_SIZE_CHANGE;
+#endif
+
vout_PlacePicture( p_vout, p_vout->p_sys->i_width,
p_vout->p_sys->i_height,
&i_x, &i_y, &i_width, &i_height );
- XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
+ XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->video_window,
i_width, i_height );
- XMoveWindow( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
+ XMoveWindow( p_vout->p_sys->p_display, p_vout->p_sys->video_window,
i_x, i_y );
-
}
-#endif
/* 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 );
+ ToggleCursor( p_vout );
}
}
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
+ p_vout->p_sys->i_width = p_vout->i_window_width;
+ p_vout->p_sys->i_height = p_vout->i_window_height;
/* Prepare window manager hints and properties */
xsize_hints.base_width = p_vout->p_sys->i_width;
CWColormap, &xwindow_attributes );
}
-#else
- /* Create YUV output sub-window. */
- p_vout->p_sys->yuv_window = XCreateSimpleWindow( p_vout->p_sys->p_display,
- p_vout->p_sys->window, 0, 0,
- p_vout->p_sys->i_width,
- p_vout->p_sys->i_height,
- 0,
- BlackPixel( p_vout->p_sys->p_display,
- p_vout->p_sys->i_screen ),
- WhitePixel( p_vout->p_sys->p_display,
- p_vout->p_sys->i_screen ) );
+#endif
+ /* Create video output sub-window. */
+ p_vout->p_sys->video_window = XCreateSimpleWindow(
+ p_vout->p_sys->p_display,
+ p_vout->p_sys->window, 0, 0,
+ p_vout->p_sys->i_width,
+ p_vout->p_sys->i_height,
+ 0,
+ BlackPixel( p_vout->p_sys->p_display,
+ p_vout->p_sys->i_screen ),
+ WhitePixel( p_vout->p_sys->p_display,
+ p_vout->p_sys->i_screen ) );
- XSetWindowBackground( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
- BlackPixel(p_vout->p_sys->p_display, p_vout->p_sys->i_screen ) );
+ XSetWindowBackground( p_vout->p_sys->p_display,
+ p_vout->p_sys->video_window,
+ BlackPixel( p_vout->p_sys->p_display,
+ p_vout->p_sys->i_screen ) );
- XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window );
- XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
+ XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->video_window );
+ XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->video_window,
ExposureMask );
-#endif
+
+ /* make sure the video window will be centered in the next vout_Manage() */
+ p_vout->i_changes |= VOUT_SIZE_CHANGE;
+
/* If the cursor was formerly blank than blank it again */
if( !p_vout->p_sys->b_mouse_pointer_visible )
/* Do NOT use XFlush here ! */
XSync( p_vout->p_sys->p_display, False );
-#ifdef MODULE_NAME_IS_xvideo
- XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window );
-#endif
-
+ XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->video_window );
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 );
return -1;
}
+#ifdef HAVE_SYS_SHM_H
if( p_vout->p_sys->b_shm )
{
/* Create image using XShm extension */
p_pic->p_sys->p_image =
CreateShmImage( p_vout->p_sys->p_display,
-#ifdef MODULE_NAME_IS_xvideo
+# ifdef MODULE_NAME_IS_xvideo
p_vout->p_sys->i_xvport,
p_vout->output.i_chroma,
-#else
+# else
p_vout->p_sys->p_visual,
p_vout->p_sys->i_screen_depth,
-#endif
+# endif
&p_pic->p_sys->shminfo,
p_vout->output.i_width, p_vout->output.i_height );
}
else
+#endif /* HAVE_SYS_SHM_H */
{
/* Create image without XShm extension */
p_pic->p_sys->p_image =
p_pic->p->i_pixel_bytes = 2;
p_pic->p->b_margin = 0;
- p_pic->p->i_red_mask = 0x001f;
- p_pic->p->i_green_mask = 0x07e0;
- p_pic->p->i_blue_mask = 0xf800;
-
p_pic->i_planes = 1;
break;
p_pic->p->i_pixel_bytes = 2;
p_pic->p->b_margin = 0;
- p_pic->p->i_red_mask = 0x001f;
- p_pic->p->i_green_mask = 0x03e0;
- p_pic->p->i_blue_mask = 0x7c00;
-
p_pic->i_planes = 1;
break;
#else
+ case FOURCC_RGB2:
+
+ p_pic->p->p_pixels = p_pic->p_sys->p_image->data
+ + p_pic->p_sys->p_image->xoffset;
+ p_pic->p->i_lines = p_pic->p_sys->p_image->height;
+ p_pic->p->i_pitch = p_pic->p_sys->p_image->bytes_per_line;
+ p_pic->p->i_pixel_bytes = p_pic->p_sys->p_image->depth;
+
+ if( p_pic->p->i_pitch == p_pic->p_sys->p_image->width )
+ {
+ p_pic->p->b_margin = 0;
+ }
+ else
+ {
+ p_pic->p->b_margin = 1;
+ p_pic->p->b_hidden = 1;
+ p_pic->p->i_visible_bytes = p_pic->p_sys->p_image->width;
+ }
+
+ p_pic->i_planes = 1;
+
+ break;
+
case FOURCC_RV16:
+ case FOURCC_RV15:
p_pic->p->p_pixels = p_pic->p_sys->p_image->data
+ p_pic->p_sys->p_image->xoffset;
p_pic->p->i_visible_bytes = 2 * p_pic->p_sys->p_image->width;
}
- p_pic->p->i_red_mask = p_pic->p_sys->p_image->red_mask;
- p_pic->p->i_green_mask = p_pic->p_sys->p_image->green_mask;
- p_pic->p->i_blue_mask = p_pic->p_sys->p_image->blue_mask;
-
p_pic->i_planes = 1;
break;
- case FOURCC_BI_BITFIELDS:
+ case FOURCC_RV32:
+ case FOURCC_RV24:
p_pic->p->p_pixels = p_pic->p_sys->p_image->data
+ p_pic->p_sys->p_image->xoffset;
p_pic->p->i_visible_bytes = 4 * p_pic->p_sys->p_image->width;
}
- p_pic->p->i_red_mask = p_pic->p_sys->p_image->red_mask;
- p_pic->p->i_green_mask = p_pic->p_sys->p_image->green_mask;
- p_pic->p->i_blue_mask = p_pic->p_sys->p_image->blue_mask;
-
p_pic->i_planes = 1;
break;
static void FreePicture( vout_thread_t *p_vout, picture_t *p_pic )
{
/* The order of operations is correct */
+#ifdef HAVE_SYS_SHM_H
if( p_vout->p_sys->b_shm )
{
XShmDetach( p_vout->p_sys->p_display, &p_pic->p_sys->shminfo );
}
}
else
+#endif
{
IMAGE_FREE( p_pic->p_sys->p_image );
}
Atom prop;
mwmhints_t mwmhints;
int i_xpos, i_ypos, i_width, i_height;
- XEvent xevent;
-#ifdef ALTERNATE_FULLSCREEN
XSetWindowAttributes attributes;
-#endif
p_vout->b_fullscreen = !p_vout->b_fullscreen;
intf_WarnMsg( 3, "vout: entering fullscreen mode" );
+ /* Only check the fullscreen method when we actually go fullscreen,
+ * because to go back to window mode we need to know in which
+ * fullscreen mode we where */
+ p_vout->p_sys->b_altfullscreen =
+ config_GetIntVariable( MODULE_STRING "-altfullscreen" );
+
/* Save current window coordinates so they can be restored when
* we exit from fullscreen mode. This is the tricky part because
* this heavily depends on the behaviour of the window manager.
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
{
* The other way is to use the motif property "_MOTIF_WM_HINTS" which
* luckily seems to be supported by most window managers.
*/
-#ifndef ALTERNATE_FULLSCREEN
- mwmhints.flags = MWM_HINTS_DECORATIONS;
- mwmhints.decorations = !p_vout->b_fullscreen;
-
- 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 );
-
-#else
- /* brute force way to remove decorations */
- attributes.override_redirect = p_vout->b_fullscreen;
- XChangeWindowAttributes( p_vout->p_sys->p_display,
- p_vout->p_sys->window,
- CWOverrideRedirect,
- &attributes);
-#endif
+ if( !p_vout->p_sys->b_altfullscreen )
+ {
+ mwmhints.flags = MWM_HINTS_DECORATIONS;
+ mwmhints.decorations = !p_vout->b_fullscreen;
+
+ 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 );
+ }
+ else
+ {
+ /* brute force way to remove decorations */
+ attributes.override_redirect = p_vout->b_fullscreen;
+ XChangeWindowAttributes( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ CWOverrideRedirect,
+ &attributes);
+ }
/* 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);
-
- XWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
- StructureNotifyMask, &xevent );
- while( xevent.type != UnmapNotify )
- XWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
- StructureNotifyMask, &xevent );
-
- XMapRaised( p_vout->p_sys->p_display, p_vout->p_sys->window);
-
- while( xevent.type != MapNotify )
- XWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
- StructureNotifyMask, &xevent );
-
+ XReparentWindow( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ DefaultRootWindow( p_vout->p_sys->p_display ),
+ 0, 0 );
+ XSync( p_vout->p_sys->p_display, True );
XMoveResizeWindow( p_vout->p_sys->p_display,
p_vout->p_sys->window,
i_xpos,
i_ypos,
i_width,
i_height );
-
- /* Purge all ConfigureNotify events, this is needed to fix a bug where we
- * would lose the original size of the window */
- while( xevent.type != ConfigureNotify )
- XWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
- StructureNotifyMask, &xevent );
- while( XCheckWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
- StructureNotifyMask, &xevent ) );
-
+ XSync( p_vout->p_sys->p_display, True );
/* We need to check that the window was really restored where we wanted */
if( !p_vout->b_fullscreen )
p_vout->p_sys->window,
p_vout->p_sys->i_xpos_backup_2,
p_vout->p_sys->i_ypos_backup_2 );
-
- /* Purge all ConfigureNotify events, this is needed to fix a bug
- * where we would lose the original size of the window */
- XWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
- StructureNotifyMask, &xevent );
- while( xevent.type != ConfigureNotify )
- XWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
- StructureNotifyMask, &xevent );
- while( XCheckWindowEvent( p_vout->p_sys->p_display,
- p_vout->p_sys->window,
- StructureNotifyMask, &xevent ) );
+
+ XSync( p_vout->p_sys->p_display, True );
}
/* Check the size */
p_vout->p_sys->window,
p_vout->p_sys->i_width_backup_2,
p_vout->p_sys->i_height_backup_2 );
-
- /* Purge all ConfigureNotify events, this is needed to fix a bug
- * where we would lose the original size of the window */
- XWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
- StructureNotifyMask, &xevent );
- while( xevent.type != ConfigureNotify )
- XWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
- StructureNotifyMask, &xevent );
- while( XCheckWindowEvent( p_vout->p_sys->p_display,
- p_vout->p_sys->window,
- StructureNotifyMask, &xevent ) );
+
+ XSync( p_vout->p_sys->p_display, True );
}
}
-#ifdef ALTERNATE_FULLSCREEN
- XSetInputFocus(p_vout->p_sys->p_display,
- p_vout->p_sys->window,
- RevertToParent,
- CurrentTime);
-#endif
+ if( p_vout->p_sys->b_altfullscreen && p_vout->b_fullscreen )
+ XSetInputFocus(p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ RevertToParent,
+ CurrentTime);
/* signal that the size needs to be updated */
p_vout->p_sys->i_width = i_width;
*****************************************************************************/
static void EnableXScreenSaver( vout_thread_t *p_vout )
{
+#ifdef DPMSINFO_IN_DPMS_H
int dummy;
+#endif
- 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 */
+#ifdef DPMSINFO_IN_DPMS_H
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 );
}
}
+#endif
}
/*****************************************************************************
*****************************************************************************/
static void DisableXScreenSaver( vout_thread_t *p_vout )
{
+#ifdef DPMSINFO_IN_DPMS_H
int dummy;
+#endif
/* Save screen saver informations */
XGetScreenSaver( p_vout->p_sys->p_display, &p_vout->p_sys->i_ss_timeout,
&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 */
+#ifdef DPMSINFO_IN_DPMS_H
if( DPMSQueryExtension( p_vout->p_sys->p_display, &dummy, &dummy ) )
{
- CARD16 dummy;
+ CARD16 unused;
/* Save DPMS current state */
- DPMSInfo( p_vout->p_sys->p_display, &dummy,
+ DPMSInfo( p_vout->p_sys->p_display, &unused,
&p_vout->p_sys->b_ss_dpms );
- intf_DbgMsg( "vout: disabling DPMS" );
DPMSDisable( p_vout->p_sys->p_display );
}
+#endif
}
/*****************************************************************************
}
i_selected_port = -1;
- i_requested_adaptor = main_GetIntVariable( VOUT_XVADAPTOR_VAR, -1 );
+ i_requested_adaptor = config_GetIntVariable( "xvideo-adaptor" );
for( i_adaptor = 0; i_adaptor < i_num_adaptors; ++i_adaptor )
{
int i_count; /* array size */
#endif
-#ifdef SYS_DARWIN
+#ifdef HAVE_SYS_SHM_H
+# ifdef SYS_DARWIN
/* FIXME : As of 2001-03-16, XFree4 for MacOS X does not support Xshm. */
p_vout->p_sys->b_shm = 0;
-#else
+# else
p_vout->p_sys->b_shm = ( XShmQueryExtension( p_vout->p_sys->p_display )
== True );
-#endif
+# endif
if( !p_vout->p_sys->b_shm )
+#endif
{
intf_WarnMsg( 1, "vout warning: XShm video extension is unavailable" );
}
return( 1 );
}
p_vout->p_sys->i_bytes_per_pixel = 1;
+ p_vout->output.pf_setpalette = SetPalette;
break;
case 15:
case 16:
intf_ErrMsg( "vout error: no TrueColor visual available" );
return( 1 );
}
- p_vout->p_sys->i_red_mask = p_xvisual->red_mask;
- p_vout->p_sys->i_green_mask = p_xvisual->green_mask;
- p_vout->p_sys->i_blue_mask = p_xvisual->blue_mask;
+
+ p_vout->output.i_rmask = p_xvisual->red_mask;
+ p_vout->output.i_gmask = p_xvisual->green_mask;
+ p_vout->output.i_bmask = p_xvisual->blue_mask;
/* There is no difference yet between 3 and 4 Bpp. The only way
* to find the actual number of bytes per pixel is to list supported
return( 0 );
}
+#ifdef HAVE_SYS_SHM_H
/*****************************************************************************
* CreateShmImage: create an XImage or XvImage using shared memory extension
*****************************************************************************
return( p_image );
}
+#endif
/*****************************************************************************
* CreateImage: create an XImage or XvImage
return p_image;
}
+#ifdef MODULE_NAME_IS_x11
+/*****************************************************************************
+ * SetPalette: sets an 8 bpp palette
+ *****************************************************************************
+ * This function sets the palette given as an argument. It does not return
+ * anything, but could later send information on which colors it was unable
+ * to set.
+ *****************************************************************************/
+static void SetPalette( vout_thread_t *p_vout, u16 *red, u16 *green, u16 *blue )
+{
+ int i;
+ XColor p_colors[255];
+
+ /* allocate palette */
+ for( i = 0; i < 255; i++ )
+ {
+ /* kludge: colors are indexed reversely because color 255 seems
+ * to be reserved for black even if we try to set it to white */
+ p_colors[ i ].pixel = 255 - i;
+ p_colors[ i ].pad = 0;
+ p_colors[ i ].flags = DoRed | DoGreen | DoBlue;
+ p_colors[ i ].red = red[ 255 - i ];
+ p_colors[ i ].blue = blue[ 255 - i ];
+ p_colors[ i ].green = green[ 255 - i ];
+ }
+
+ XStoreColors( p_vout->p_sys->p_display,
+ p_vout->p_sys->colormap, p_colors, 255 );
+}
+#endif