Cygwin/X: Generate RANDR change on WM_DISPLAYCHANGE for rootless modes

When RANDR resizing is enabled, generate an internal RANDR change when
WM_DISPLAYCHANGE occurs in rootless modes for screens which occupy an
entire monitor or the virtual desktop.

Store the monitor number and use that to handle WM_DISPLAYCHANGE for a
screen specified with '-screen @monitor'

In rooted mode, WM_DISPLAYCHANGE isn't relevant (except where display
depth changes may cause problems). (A maximized screen window will get
WM_SIZE to adjust it to the new monitor size)

In rooted fullscreen mode, WM_DISPLAYCHANGE shouldn't be seen, as we
have the resolution we have selected for the fullscreen session)
(Could client randr requests be handled in fullscreen to cause a change
of the fullscreen resolution? )

Don't bother do a RANDR resize if the dimensions aren't actually changing
when WM_DISPLAYCHANGE is sent (should handle WM_DISPLAYCHANGE to size 0x0
that the intel driver seems to like to send)

Various debug output improvements

Also, remove the note that XWin can't handle display mode changes from
the man page

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
Tested-by: Colin Harrison <colin.harrison@virgin.net>
This commit is contained in:
Jon TURNEY 2010-03-30 19:49:41 +01:00
parent bbc511e80b
commit 33106e1e80
4 changed files with 104 additions and 39 deletions

View File

@ -376,12 +376,9 @@ X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1), XWinrc(__filemansuffix__), s
.SH BUGS .SH BUGS
.I XWin .I XWin
and this man page still have many limitations. Some of the more obvious and this man page still have many limitations.
ones are:
.br The \fIXWin\fP software is continuously developing; it is therefore possible that
- The display mode can not be changed once the X server has started.
.br
- The \fIXWin\fP software is continuously developing; it is therefore possible that
this man page is not up to date. It is always prudent to this man page is not up to date. It is always prudent to
look also at the output of \fIXWin -help\fP in order to look also at the output of \fIXWin -help\fP in order to
check the options that are operative. check the options that are operative.

View File

@ -400,6 +400,8 @@ typedef struct
Bool fUserGaveHeightAndWidth; Bool fUserGaveHeightAndWidth;
DWORD dwScreen; DWORD dwScreen;
int iMonitor;
DWORD dwUserWidth; DWORD dwUserWidth;
DWORD dwUserHeight; DWORD dwUserHeight;
DWORD dwWidth; DWORD dwWidth;

View File

@ -95,6 +95,7 @@ winInitializeScreenDefaults(void)
if (monitorResolution == 0) if (monitorResolution == 0)
monitorResolution = WIN_DEFAULT_DPI; monitorResolution = WIN_DEFAULT_DPI;
defaultScreenInfo.iMonitor = 1;
defaultScreenInfo.dwWidth = dwWidth; defaultScreenInfo.dwWidth = dwWidth;
defaultScreenInfo.dwHeight = dwHeight; defaultScreenInfo.dwHeight = dwHeight;
defaultScreenInfo.dwUserWidth = dwWidth; defaultScreenInfo.dwUserWidth = dwWidth;
@ -318,6 +319,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
iArgsProcessed = 3; iArgsProcessed = 3;
g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE; g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth; g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth;
g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight; g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight;
g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth; g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth;
@ -370,6 +372,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
"Querying monitors is not supported on NT4 and Win95\n"); "Querying monitors is not supported on NT4 and Win95\n");
} else if (data.bMonitorSpecifiedExists == TRUE) } else if (data.bMonitorSpecifiedExists == TRUE)
{ {
g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX; g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX;
g_ScreenInfo[nScreenNum].dwInitialY += data.monitorOffsetY; g_ScreenInfo[nScreenNum].dwInitialY += data.monitorOffsetY;
} }
@ -399,6 +402,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
{ {
winErrorFVerb (2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor); winErrorFVerb (2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor);
g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX; g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX;
g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY; g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY;
} }

View File

@ -40,6 +40,7 @@
#include "winprefs.h" #include "winprefs.h"
#include "winconfig.h" #include "winconfig.h"
#include "winmsg.h" #include "winmsg.h"
#include "winmonitors.h"
#include "inputstr.h" #include "inputstr.h"
/* /*
@ -177,12 +178,9 @@ winWindowProc (HWND hwnd, UINT message,
break; break;
} }
ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new bpp: %d\n",
wParam);
ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d "
"new height: %d\n", "new height: %d new bpp: %d\n",
LOWORD (lParam), HIWORD (lParam)); LOWORD (lParam), HIWORD (lParam), wParam);
/* /*
* TrueColor --> TrueColor depth changes are disruptive for: * TrueColor --> TrueColor depth changes are disruptive for:
@ -254,41 +252,105 @@ winWindowProc (HWND hwnd, UINT message,
* the display dimensions change. * the display dimensions change.
*/ */
{ {
/*
* NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
* and CreatePrimarySurface function pointers to point
* to the no operation function, NoopDDA. This allows us
* to blindly call these functions, even if they are not
* relevant to the current engine (e.g., Shadow GDI).
*/
#if CYGDEBUG
winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n");
#endif
/* Release the old primary surface */
(*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
#if CYGDEBUG
winDebug ("winWindowProc - WM_DISPLAYCHANGE - Released "
"primary surface\n");
#endif
/* Create the new primary surface */
(*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);
#if CYGDEBUG #if CYGDEBUG
winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated " winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated "
"primary surface\n"); "primary surface\n");
#endif #endif
#if 0 /*
/* Multi-Window mode uses RandR for resizes */ In rootless modes which are monitor or virtual desktop size
if (s_pScreenInfo->fMultiWindow) use RandR to resize the X screen
{ */
RRSetScreenConfig (); if ((!s_pScreenInfo->fUserGaveHeightAndWidth) &&
} (s_pScreenInfo->iResizeMode == resizeWithRandr) &&
(FALSE
#ifdef XWIN_MULTIWINDOWEXTWM
|| s_pScreenInfo->fMWExtWM
#endif #endif
|| s_pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOW
|| s_pScreenInfo->fMultiWindow
#endif
))
{
DWORD dwWidth, dwHeight;
if (s_pScreenInfo->fMultipleMonitors)
{
/* resize to new virtual desktop size */
dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
else
{
/* resize to new size of specified monitor */
struct GetMonitorInfoData data;
if (QueryMonitor(s_pScreenInfo->iMonitor, &data))
{
if (data.bMonitorSpecifiedExists == TRUE)
{
dwWidth = data.monitorWidth;
dwHeight = data.monitorHeight;
/*
XXX: monitor may have changed position,
so we might need to update xinerama data
*/
}
else
{
ErrorF ("Monitor number %d no longer exists!\n", s_pScreenInfo->iMonitor);
}
}
}
/*
XXX: probably a small bug here: we don't compute the work area
and allow for task bar
XXX: generally, we don't allow for the task bar being moved after
the server is started
*/
/* Set screen size to match new size, if it is different to current */
if ((s_pScreenInfo->dwWidth != dwWidth) ||
(s_pScreenInfo->dwHeight != dwHeight))
{
winDoRandRScreenSetSize(s_pScreen,
dwWidth,
dwHeight,
(dwWidth * 25.4) / monitorResolution,
(dwHeight * 25.4) / monitorResolution);
}
}
else
{
/*
If we get here, we are either windowed and using the GDI engine
or windowed and non-fullscreen using any engine
*/
/*
* For ddraw engines, we need to (try to) recreate the same-sized primary surface
* when display dimensions change (but not depth, that is disruptive)
*/
/*
* NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
* and CreatePrimarySurface function pointers to point
* to the no operation function, NoopDDA. This allows us
* to blindly call these functions, even if they are not
* relevant to the current engine (e.g., Shadow GDI).
*/
winDebug ("winWindowProc - WM_DISPLAYCHANGE - Releasing and recreating primary surface\n");
/* Release the old primary surface */
(*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
/* Create the new primary surface */
(*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);
}
} }
break; break;