Commit 0cbc9445 authored by Gildas Bazin's avatar Gildas Bazin

* Fixed all the problems related to ToggleFullScreen().
parent 9cec4e85
......@@ -2,7 +2,7 @@
* 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>
......@@ -153,6 +153,10 @@ typedef struct vout_sys_s
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 */
......@@ -974,6 +978,10 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
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;
......@@ -985,10 +993,35 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
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 ) )
{
......@@ -1020,9 +1053,7 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
&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,
......@@ -1042,9 +1073,6 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
{
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;
......@@ -1057,15 +1085,20 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
* 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,
......@@ -1075,14 +1108,117 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
/* 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;
}
/*****************************************************************************
......
......@@ -2,11 +2,12 @@
* 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
......@@ -161,6 +162,10 @@ typedef struct vout_sys_s
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 */
......@@ -898,6 +903,9 @@ static int vout_Manage( vout_thread_t *p_vout )
#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 )
{
......@@ -1448,6 +1456,10 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
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;
......@@ -1455,14 +1467,39 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
{
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 ) )
{
......@@ -1494,9 +1531,7 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
&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,
......@@ -1515,9 +1550,6 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
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;
......@@ -1531,15 +1563,20 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
* 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,
......@@ -1549,7 +1586,19 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
/* 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,
......@@ -1557,8 +1606,97 @@ static void ToggleFullScreen ( vout_thread_t *p_vout )
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;
}
/*****************************************************************************
......
......@@ -5,7 +5,7 @@
* 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>
*
......@@ -172,10 +172,13 @@ vout_thread_t * vout_CreateThread ( int *pi_status,
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 );
......
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