* xcommon.c: Functions common to the X11 and XVideo plugins
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: xcommon.c,v 1.24 2002/03/17 17:00:38 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>
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) */
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;
/*****************************************************************************
* 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;
*****************************************************************************/
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 ) );
/* Open display, unsing the "display" config variable or the DISPLAY
* environment variable */
- psz_display = config_GetPszVariable( "display" );
+ 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 */
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. */
/* 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 );
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;
/* Display rendered image using shared memory extension */
# 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,
+ 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,
/* 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 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
}
-#ifdef MODULE_NAME_IS_x11
- /*
- * Handle vout window resizing
- */
-#if 0
- if( b_resized )
- {
- /* If interface window has been resized, change vout size */
- 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 */
- 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 )
- {
- 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 );
Atom prop;
mwmhints_t mwmhints;
int i_xpos, i_ypos, i_width, i_height;
- XEvent xevent;
XSetWindowAttributes attributes;
p_vout->b_fullscreen = !p_vout->b_fullscreen;
* because to go back to window mode we need to know in which
* fullscreen mode we where */
p_vout->p_sys->b_altfullscreen =
-#ifdef MODULE_NAME_IS_xvideo
- config_GetIntVariable( "xvideo_altfullscreen" );
-#else
- config_GetIntVariable( "x11_altfullscreen" );
-#endif
+ 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
/* 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->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->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 );
}
}
- if( p_vout->p_sys->b_altfullscreen )
+ if( p_vout->p_sys->b_altfullscreen && p_vout->b_fullscreen )
XSetInputFocus(p_vout->p_sys->p_display,
p_vout->p_sys->window,
RevertToParent,
}
i_selected_port = -1;
- i_requested_adaptor = config_GetIntVariable( "xvideo_adaptor" );
+ i_requested_adaptor = config_GetIntVariable( "xvideo-adaptor" );
for( i_adaptor = 0; i_adaptor < i_num_adaptors; ++i_adaptor )
{
p_vout->p_sys->colormap, p_colors, 255 );
}
#endif
-