diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2010-03-30 19:49:41 +0100 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2011-01-19 14:02:26 +0000 |
commit | 33106e1e807a828208b306512e78c5e3e93960d3 (patch) | |
tree | d009e6fbcf73f989481e7c59c3d36c04e6a934c0 | |
parent | bbc511e80b2a9365f6a1528bc1595772f83be654 (diff) |
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>
-rw-r--r-- | hw/xwin/man/XWin.man | 9 | ||||
-rw-r--r-- | hw/xwin/win.h | 2 | ||||
-rw-r--r-- | hw/xwin/winprocarg.c | 4 | ||||
-rw-r--r-- | hw/xwin/winwndproc.c | 126 |
4 files changed, 103 insertions, 38 deletions
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man index 39cdf5ef0..e7933c9c8 100644 --- a/hw/xwin/man/XWin.man +++ b/hw/xwin/man/XWin.man @@ -376,12 +376,9 @@ X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1), XWinrc(__filemansuffix__), s .SH BUGS .I XWin -and this man page still have many limitations. Some of the more obvious -ones are: -.br -- 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 +and this man page still have many limitations. + +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 look also at the output of \fIXWin -help\fP in order to check the options that are operative. diff --git a/hw/xwin/win.h b/hw/xwin/win.h index bbc0f2fbf..2eea345e5 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -400,6 +400,8 @@ typedef struct Bool fUserGaveHeightAndWidth; DWORD dwScreen; + + int iMonitor; DWORD dwUserWidth; DWORD dwUserHeight; DWORD dwWidth; diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c index e4c52ef94..ddfe1f5b7 100644 --- a/hw/xwin/winprocarg.c +++ b/hw/xwin/winprocarg.c @@ -95,6 +95,7 @@ winInitializeScreenDefaults(void) if (monitorResolution == 0) monitorResolution = WIN_DEFAULT_DPI; + defaultScreenInfo.iMonitor = 1; defaultScreenInfo.dwWidth = dwWidth; defaultScreenInfo.dwHeight = dwHeight; defaultScreenInfo.dwUserWidth = dwWidth; @@ -318,6 +319,7 @@ ddxProcessArgument (int argc, char *argv[], int i) iArgsProcessed = 3; g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE; g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; + g_ScreenInfo[nScreenNum].iMonitor = iMonitor; g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth; g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight; 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"); } else if (data.bMonitorSpecifiedExists == TRUE) { + g_ScreenInfo[nScreenNum].iMonitor = iMonitor; g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX; 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); g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; + g_ScreenInfo[nScreenNum].iMonitor = iMonitor; g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX; g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY; } diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c index 04a3a6b86..80f5e1a7b 100644 --- a/hw/xwin/winwndproc.c +++ b/hw/xwin/winwndproc.c @@ -40,6 +40,7 @@ #include "winprefs.h" #include "winconfig.h" #include "winmsg.h" +#include "winmonitors.h" #include "inputstr.h" /* @@ -177,12 +178,9 @@ winWindowProc (HWND hwnd, UINT message, break; } - ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new bpp: %d\n", - wParam); - ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " - "new height: %d\n", - LOWORD (lParam), HIWORD (lParam)); + "new height: %d new bpp: %d\n", + LOWORD (lParam), HIWORD (lParam), wParam); /* * TrueColor --> TrueColor depth changes are disruptive for: @@ -254,41 +252,105 @@ winWindowProc (HWND hwnd, UINT message, * 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 winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated " "primary surface\n"); #endif -#if 0 - /* Multi-Window mode uses RandR for resizes */ - if (s_pScreenInfo->fMultiWindow) + /* + In rootless modes which are monitor or virtual desktop size + use RandR to resize the X screen + */ + if ((!s_pScreenInfo->fUserGaveHeightAndWidth) && + (s_pScreenInfo->iResizeMode == resizeWithRandr) && + (FALSE +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + || s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + || s_pScreenInfo->fMultiWindow +#endif + )) { - RRSetScreenConfig (); + 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); + } } -#endif + 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; |