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) - { - RRSetScreenConfig (); - } + /* + 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 + )) + { + 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;