* xmga.c : X11 MGA plugin for vlc
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: xmga.c,v 1.2 2002/01/10 04:11:25 sam Exp $
+ * $Id: xmga.c,v 1.3 2002/01/13 15:07:55 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
int i_height_backup;
int i_xpos_backup;
int i_ypos_backup;
+ int i_width_backup_2;
+ int i_height_backup_2;
+ int i_xpos_backup_2;
+ int i_ypos_backup_2;
/* Screen saver properties */
int i_ss_timeout; /* timeout */
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" );
/* Save current window coordinates so they can be restored when
- * we exit from fullscreen mode */
+ * we exit from fullscreen mode. This is the tricky part because
+ * this heavily depends on the behaviour of the window manager.
+ * When you use XMoveWindow some window managers will adjust the top
+ * of the window to the coordinates you gave, but others will instead
+ * adjust the top of the client area to the coordinates
+ * (don't forget windows have decorations). */
+
+ /* First, get the position and size of the client area */
+ XGetGeometry( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ &dummy1,
+ &dummy2,
+ &dummy3,
+ &p_vout->p_sys->i_width_backup_2,
+ &p_vout->p_sys->i_height_backup_2,
+ &dummy2, &dummy3 );
+ XTranslateCoordinates( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ DefaultRootWindow( p_vout->p_sys->p_display ),
+ 0,
+ 0,
+ &p_vout->p_sys->i_xpos_backup_2,
+ &p_vout->p_sys->i_ypos_backup_2,
+ &dummy1 );
- /* find the real parent, which means the which is a direct child of
- * the root window */
+ /* Then try to get the position and size of the whole window */
+
+ /* find the real parent of our window (created by the window manager),
+ * the one 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 ) )
{
&p_vout->p_sys->i_ypos_backup,
&dummy1 );
- mwmhints.flags = MWM_HINTS_DECORATIONS;
- mwmhints.decorations = 0;
-
+ /* fullscreen window size and position */
i_xpos = 0;
i_ypos = 0;
i_width = DisplayWidth( p_vout->p_sys->p_display,
{
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;
* 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 );
-#if 0 /* brute force way to remove decorations */
- XSetWindowAttributes attributes;
- attributes.override_redirect = True;
+
+#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,
/* 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 );
+
XMoveResizeWindow( p_vout->p_sys->p_display,
p_vout->p_sys->window,
i_xpos,
i_ypos,
i_width,
i_height );
- XSync( p_vout->p_sys->p_display, False );
+
+ /* 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 ) );
+
+
+ /* We need to check that the window was really restored where we wanted */
+ if( !p_vout->b_fullscreen )
+ {
+ Window dummy1;
+ unsigned int dummy2, dummy3, dummy4, dummy5;
+
+ /* Check the position */
+ XTranslateCoordinates( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ DefaultRootWindow( p_vout->p_sys->p_display ),
+ 0,
+ 0,
+ &dummy2,
+ &dummy3,
+ &dummy1 );
+ if( dummy2 != p_vout->p_sys->i_xpos_backup_2 ||
+ dummy3 != p_vout->p_sys->i_ypos_backup_2 )
+ {
+ /* Ok it didn't work... second try */
+
+ XMoveWindow( p_vout->p_sys->p_display,
+ 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 ) );
+ }
+
+ /* Check the size */
+ XGetGeometry( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ &dummy1,
+ &dummy2,
+ &dummy3,
+ &dummy4,
+ &dummy5,
+ &dummy2, &dummy3 );
+
+ if( dummy4 != p_vout->p_sys->i_width_backup_2 ||
+ dummy5 != p_vout->p_sys->i_height_backup_2 )
+ {
+ /* Ok it didn't work... third try */
+
+ XResizeWindow( p_vout->p_sys->p_display,
+ 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 ) );
+ }
+ }
+
+#ifdef ALTERNATE_FULLSCREEN
+ XSetInputFocus(p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ RevertToParent,
+ CurrentTime);
+#endif
+
+ /* signal that the size needs to be updated */
+ p_vout->p_sys->i_width = i_width;
+ p_vout->p_sys->i_height = i_height;
+ p_vout->i_changes |= VOUT_SIZE_CHANGE;
+
}
/*****************************************************************************
* xcommon.c: Functions common to the X11 and XVideo plugins
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: xcommon.c,v 1.11 2002/01/12 01:25:57 sam Exp $
+ * $Id: xcommon.c,v 1.12 2002/01/13 15:07:55 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* David Kennedy <dkennedy@tinytoad.com>
+ * Gildas Bazin <gbazin@netcourrier.com>
*
* 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
int i_height_backup;
int i_xpos_backup;
int i_ypos_backup;
+ int i_width_backup_2;
+ int i_height_backup_2;
+ int i_xpos_backup_2;
+ int i_ypos_backup_2;
/* Screen saver properties */
int i_ss_timeout; /* timeout */
#else
/*
* Size change
+ *
+ * (Needs to be placed after VOUT_FULLSREEN_CHANGE because we can activate
+ * the size flag inside the fullscreen routine)
*/
if( p_vout->i_changes & VOUT_SIZE_CHANGE )
{
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;
{
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 */
+ * we exit from fullscreen mode. This is the tricky part because
+ * this heavily depends on the behaviour of the window manager.
+ * When you use XMoveWindow some window managers will adjust the top
+ * of the window to the coordinates you gave, but others will instead
+ * adjust the top of the client area to the coordinates
+ * (don't forget windows have decorations). */
+
+ /* First, get the position and size of the client area */
+ XGetGeometry( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ &dummy1,
+ &dummy2,
+ &dummy3,
+ &p_vout->p_sys->i_width_backup_2,
+ &p_vout->p_sys->i_height_backup_2,
+ &dummy2, &dummy3 );
+ XTranslateCoordinates( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ DefaultRootWindow( p_vout->p_sys->p_display ),
+ 0,
+ 0,
+ &p_vout->p_sys->i_xpos_backup_2,
+ &p_vout->p_sys->i_ypos_backup_2,
+ &dummy1 );
- /* find the real parent, which means the which is a direct child of
- * the root window */
+ /* Then try to get the position and size of the whole window */
+
+ /* find the real parent of our window (created by the window manager),
+ * the one 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 ) )
{
&p_vout->p_sys->i_ypos_backup,
&dummy1 );
- mwmhints.flags = MWM_HINTS_DECORATIONS;
- mwmhints.decorations = 0;
-
+ /* fullscreen window size and position */
i_xpos = 0;
i_ypos = 0;
i_width = DisplayWidth( p_vout->p_sys->p_display,
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;
* 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 );
-#if 0 /* brute force way to remove decorations */
- XSetWindowAttributes attributes;
- attributes.override_redirect = True;
+
+#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,
/* 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 );
+
XMoveResizeWindow( p_vout->p_sys->p_display,
p_vout->p_sys->window,
i_xpos,
i_width,
i_height );
- /* Do NOT use XFlush here ! */
- XSync( p_vout->p_sys->p_display, False );
+ /* 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 ) );
+
+
+ /* We need to check that the window was really restored where we wanted */
+ if( !p_vout->b_fullscreen )
+ {
+ Window dummy1;
+ unsigned int dummy2, dummy3, dummy4, dummy5;
+
+ /* Check the position */
+ XTranslateCoordinates( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ DefaultRootWindow( p_vout->p_sys->p_display ),
+ 0,
+ 0,
+ &dummy2,
+ &dummy3,
+ &dummy1 );
+ if( dummy2 != p_vout->p_sys->i_xpos_backup_2 ||
+ dummy3 != p_vout->p_sys->i_ypos_backup_2 )
+ {
+ /* Ok it didn't work... second try */
+
+ XMoveWindow( p_vout->p_sys->p_display,
+ 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 ) );
+ }
+
+ /* Check the size */
+ XGetGeometry( p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ &dummy1,
+ &dummy2,
+ &dummy3,
+ &dummy4,
+ &dummy5,
+ &dummy2, &dummy3 );
+
+ if( dummy4 != p_vout->p_sys->i_width_backup_2 ||
+ dummy5 != p_vout->p_sys->i_height_backup_2 )
+ {
+ /* Ok it didn't work... third try */
+
+ XResizeWindow( p_vout->p_sys->p_display,
+ 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 ) );
+ }
+ }
+
+#ifdef ALTERNATE_FULLSCREEN
+ XSetInputFocus(p_vout->p_sys->p_display,
+ p_vout->p_sys->window,
+ RevertToParent,
+ CurrentTime);
+#endif
+
+ /* signal that the size needs to be updated */
+ p_vout->p_sys->i_width = i_width;
+ p_vout->p_sys->i_height = i_height;
+ p_vout->i_changes |= VOUT_SIZE_CHANGE;
+
}
/*****************************************************************************
* thread, and destroy a previously oppened video output thread.
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: video_output.c,v 1.156 2002/01/12 01:25:57 sam Exp $
+ * $Id: video_output.c,v 1.157 2002/01/13 15:07:55 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
p_vout->b_info = 0;
p_vout->b_interface = 0;
p_vout->b_scale = 1;
- p_vout->b_fullscreen = main_GetIntVariable( VOUT_FULLSCREEN_VAR,
- VOUT_FULLSCREEN_DEFAULT );
+ p_vout->b_fullscreen = 0;
p_vout->render_time = 10;
+ /* user requested fullscreen? */
+ if( main_GetIntVariable( VOUT_FULLSCREEN_VAR, VOUT_FULLSCREEN_DEFAULT ) )
+ p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+
/* Create thread and set locks */
vlc_mutex_init( &p_vout->picture_lock );
vlc_mutex_init( &p_vout->subpicture_lock );