This is the mail archive of the cygwin-xfree@cygwin.com mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch for multiple monitors


Nick,

Wow! I like it alot!

I am currently trying to get a build of Kensuke's latest multiwindow patch posted and a patch to xwinclip to handle the -display parameter. Once I get those done I will start merging your patch. Or, I may merge them both at once, but it would probably be wiser to wait so we have two versions to assign bug blame :)

Thanks for the patch,

Harold

Nick Crabtree wrote:

Hi,

I attach a patch for multiple monitors, diffed against
xwin-20021107-0015. I have added a command-line flag -multiplemonitors
which activates the extra code.

This works on my machine in both windowed and rootless modes for engines
1, 2 and 4. It does not work in fullscreen mode because the defaults for
the fullscreen dimensions are calculated before the command line
parameters are parsed (as far as I could figure out).

It should be possible to make this behaviour the default (SM_CXSCREEN ==
SM_CXVIRTUALSCREEN etc. if there is only one monitor), which would
remove many of the if {} else {} blocks, and also might make fullscreen
mode work

My machine is running Windows 2000. Both my graphics cards are set at
1600x1200 32bit colour. It's great - I'm running KDE in rootless mode,
and I get the kicker across the bottom of both monitors, and I can drag
X windows from one monitor to the other ...

Comments?

Nick

diff -uw ./InitOutput.c
../../x-devel/build/opt/programs/Xserver/hw/xwin/InitOutput.c
--- ./InitOutput.c 2002-11-07 05:21:18.000000000 +0000
+++ ../../x-devel/build/opt/programs/Xserver/hw/xwin/InitOutput.c
2003-01-09 16:51:10.000000000 +0000
@@ -114,7 +114,8 @@
/* Zero the memory used for storing the screen info */
ZeroMemory (g_ScreenInfo, MAXSCREENS * sizeof (winScreenInfo));

- /* Get default width and height */
+ /* Get default width and height. These will just be for the primary
+ monitor in the case that we have multiple monitors. */
dwWidth = GetSystemMetrics (SM_CXSCREEN);
dwHeight = GetSystemMetrics (SM_CYSCREEN);

@@ -139,6 +140,7 @@
g_ScreenInfo[i].fFullScreen = FALSE;
g_ScreenInfo[i].fDecoration = TRUE;
g_ScreenInfo[i].fRootless = FALSE;
+ g_ScreenInfo[i].fMultiplemonitors = FALSE;
g_ScreenInfo[i].fLessPointer = FALSE;
g_ScreenInfo[i].fScrollbars = FALSE;
g_ScreenInfo[i].iE3BTimeout = WIN_E3B_OFF;
@@ -303,6 +305,10 @@
ErrorF ("-rootless\n"
"\tEXPERIMENTAL: Run the server in pseudo-rootless mode.\n");

+ ErrorF ("-multiplemonitors\n"
+ "\tEXPERIMENTAL: Use the entire virtual screen if multiple\n"
+ "\tmonitors are present.\n");
+
ErrorF ("-scrollbars\n"
"\tIn windowed mode, allow screens bigger than the Windows
desktop.\n"
"\tMoreover, if the window has decorations, one can now
resize\n"
@@ -653,6 +659,32 @@
}

/*
+ * Look for the '-multiplemonitors' argument
+ */
+ if (strcmp (argv[i], "-multiplemonitors") == 0)
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fMultiplemonitors = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fMultiplemonitors = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
* Look for the '-scrollbars' argument
*/
if (strcmp (argv[i], "-scrollbars") == 0)
diff -uw ./win.h ../../x-devel/build/opt/programs/Xserver/hw/xwin/win.h
--- ./win.h 2002-11-07 05:33:17.000000000 +0000
+++ ../../x-devel/build/opt/programs/Xserver/hw/xwin/win.h
2003-01-09 16:51:38.000000000 +0000
@@ -390,6 +390,7 @@
Bool fFullScreen;
Bool fDecoration;
Bool fRootless;
+ Bool fMultiplemonitors;
Bool fLessPointer;
Bool fScrollbars;
int iE3BTimeout;
diff -uw ./wincreatewnd.c
../../x-devel/build/opt/programs/Xserver/hw/xwin/wincreatewnd.c
--- ./wincreatewnd.c 2002-10-19 04:56:52.000000000 +0100
+++ ../../x-devel/build/opt/programs/Xserver/hw/xwin/wincreatewnd.c
2003-01-10 15:11:26.000000000 +0000
@@ -31,16 +31,17 @@

#include "win.h"
#include "shellapi.h"

/*
* Local function prototypes
*/

static Bool
+winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo);
+static Bool
winAdjustForAutoHide (RECT *prcWorkArea);

-
/*
* Create a full screen window
*/
@@ -155,7 +156,7 @@
RegisterClass (&wc);

/* Get size of work area */
- SystemParametersInfo (SPI_GETWORKAREA, 0, &rcWorkArea, 0);
+ winGetWorkArea (&rcWorkArea, pScreenInfo);

/* Adjust for auto-hide taskbars */
winAdjustForAutoHide (&rcWorkArea);
@@ -206,10 +207,18 @@
* In this case we have to ignore the requested width and
height
* and instead use the largest possible window that we can.
*/
+ if (pScreenInfo->fMultiplemonitors)
+ {
+ iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ }
+ else
+ {
iWidth = GetSystemMetrics (SM_CXSCREEN);
iHeight = GetSystemMetrics (SM_CYSCREEN);
}
}
+ }
else
{
/* By default, we are creating a window that is as large as
possible */
@@ -217,6 +226,12 @@
ErrorF ("winCreateBoundingWindowWindowed - User did not give "
"height and width\n");
#endif
+ /* Defaults are wrong if we have multiple monitors */
+ if (pScreenInfo->fMultiplemonitors)
+ {
+ iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ }
}

/* Clean up the scrollbars flag, if necessary */
@@ -368,6 +383,59 @@


/*
+ * Find the work area of all attached monitors
+ */
+static Bool
+winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo)
+{
+ /* SPI_GETWORKAREA only gets the work area of the primary screen. */
+ SystemParametersInfo (SPI_GETWORKAREA, 0, prcWorkArea, 0);
+ if (pScreenInfo->fMultiplemonitors)
+ {
+ int iPrimaryWidth, iPrimaryHeight, iWidth, iHeight;
+ int iLeft, iTop, iPrimaryNonWorkAreaWidth,
iPrimaryNonWorkAreaHeight;
+ + ErrorF ("winGetWorkArea - Original WorkArea: %d %d %d %d\n",
+ prcWorkArea->top, prcWorkArea->left,
+ prcWorkArea->bottom, prcWorkArea->right);
+ /* Get info on full virtual screen */
+ iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ ErrorF("winGetWorkArea - Virtual screen is %d x %d\n", iWidth,
iHeight);
+ iLeft = GetSystemMetrics (SM_XVIRTUALSCREEN);
+ iTop = GetSystemMetrics (SM_YVIRTUALSCREEN);
+ ErrorF("winGetWorkArea - Virtual screen origin is %d, %d\n",
iLeft, iTop);
+
+ /* Get info on primary screen */
+ iPrimaryWidth = GetSystemMetrics (SM_CXSCREEN);
+ iPrimaryHeight = GetSystemMetrics (SM_CYSCREEN);
+ ErrorF("winGetWorkArea - Primary screen is %d x %d\n",
iPrimaryWidth, iPrimaryHeight);
+
+ /* Work out how much of the primary screen we aren't using */
+ iPrimaryNonWorkAreaWidth = iPrimaryWidth - (prcWorkArea->right -
prcWorkArea->left);
+ iPrimaryNonWorkAreaHeight = iPrimaryHeight - (prcWorkArea->bottom
- prcWorkArea->top);
+
+ /* Update the rectangle to include all monitors */
+ if (iLeft < 0) + {
+ prcWorkArea->left = iLeft;
+ }
+ if (iTop < 0) + {
+ prcWorkArea->top = iTop;
+ }
+ prcWorkArea->right = prcWorkArea->left + iWidth -
iPrimaryNonWorkAreaWidth;
+ prcWorkArea->bottom = prcWorkArea->top + iHeight -
iPrimaryNonWorkAreaHeight;
+
+ ErrorF ("winGetWorkArea - Adjusted WorkArea for multiple
monitors: %d %d %d %d\n",
+ prcWorkArea->top, prcWorkArea->left,
+ prcWorkArea->bottom, prcWorkArea->right);
+ }
+ return TRUE;
+}
+
+
+/*
* Adjust the client area so that any auto-hide toolbars
* will work correctly.
*/
diff -uw ./winscrinit.c
../../x-devel/build/opt/programs/Xserver/hw/xwin/winscrinit.c
--- ./winscrinit.c 2002-11-07 05:21:18.000000000 +0000
+++ ../../x-devel/build/opt/programs/Xserver/hw/xwin/winscrinit.c
2003-01-10 09:27:45.000000000 +0000
@@ -113,6 +113,16 @@
#endif
}

+ /* Check all monitors have the same display depth if we are using
+ multiple monitors */
+ if (pScreenInfo->fMultiplemonitors + && ! GetSystemMetrics (SM_SAMEDISPLAYFORMAT))
+ {
+ ErrorF ("Monitors do not all have same pixel format / display
depth.\n"
+ "Using primary display only.\n");
+ pScreenInfo->fMultiplemonitors = FALSE;
+ }
+ /* Create display window */
if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen))
{
@@ -123,8 +133,28 @@

/* Store the initial height, width, and depth of the display */
hdc = GetDC (pScreenPriv->hwndScreen);
+ /* Are we using multiple monitors? */
+ if (pScreenInfo->fMultiplemonitors)
+ {
+ pScreenPriv->dwLastWindowsWidth = GetSystemMetrics
(SM_CXVIRTUALSCREEN);
+ pScreenPriv->dwLastWindowsHeight = GetSystemMetrics
(SM_CYVIRTUALSCREEN);
+ /* In this case, some of the defaults set in
+ winInitializeDefaultScreens() are not correct ... */
+ if (!pScreenInfo->fUserGaveHeightAndWidth)
+ {
+ pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth /
WIN_DEFAULT_DPI)
+ * 25.4;
+ pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight /
WIN_DEFAULT_DPI)
+ * 25.4;
+ }
+ }
+ else
+ {
pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
+ }
pScreenPriv->dwLastWindowsBitsPixel
= GetDeviceCaps (hdc, BITSPIXEL);
ReleaseDC (pScreenPriv->hwndScreen, hdc);
diff -uw ./winshaddd.c
../../x-devel/build/opt/programs/Xserver/hw/xwin/winshaddd.c
--- ./winshaddd.c 2002-10-19 04:56:53.000000000 +0100
+++ ../../x-devel/build/opt/programs/Xserver/hw/xwin/winshaddd.c
2003-01-10 09:48:28.000000000 +0000
@@ -230,6 +230,7 @@
{
DDSURFACEDESC ddsdCurrent;
DWORD dwRefreshRateCurrent = 0;
+ DWORD dwWidth, dwHeight;
HDC hdc = NULL;

/* Set the cooperative level to full screen */
@@ -289,8 +290,18 @@
}

/* Only change the video mode when different than current mode */
- if (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
- || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
+ if (pScreenInfo->fMultiplemonitors)
+ {
+ dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ }
+ else
+ {
+ dwWidth = GetSystemMetrics (SM_CXSCREEN);
+ dwHeight = GetSystemMetrics (SM_CYSCREEN);
+ }
+ if (pScreenInfo->dwWidth != dwWidth
+ || pScreenInfo->dwHeight != dwHeight
|| pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
|| pScreenInfo->dwRefreshRate != 0)
{
diff -uw ./winshadddnl.c
../../x-devel/build/opt/programs/Xserver/hw/xwin/winshadddnl.c
--- ./winshadddnl.c 2002-10-19 04:56:53.000000000 +0100
+++ ../../x-devel/build/opt/programs/Xserver/hw/xwin/winshadddnl.c
2003-01-10 09:51:55.000000000 +0000
@@ -248,6 +248,7 @@
{
DDSURFACEDESC2 ddsdCurrent;
DWORD dwRefreshRateCurrent = 0;
+ DWORD dwWidth, dwHeight;
HDC hdc = NULL;

/* Set the cooperative level to full screen */
@@ -307,8 +308,18 @@
}

/* Only change the video mode when different than current mode */
- if (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
- || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
+ if (pScreenInfo->fMultiplemonitors)
+ {
+ dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ }
+ else
+ {
+ dwWidth = GetSystemMetrics (SM_CXSCREEN);
+ dwHeight = GetSystemMetrics (SM_CYSCREEN);
+ }
+ if (pScreenInfo->dwWidth != dwWidth
+ || pScreenInfo->dwHeight != dwHeight
|| pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
|| pScreenInfo->dwRefreshRate != 0)
{
diff -uw ./winwndproc.c
../../x-devel/build/opt/programs/Xserver/hw/xwin/winwndproc.c
--- ./winwndproc.c 2002-10-19 04:56:53.000000000 +0100
+++ ../../x-devel/build/opt/programs/Xserver/hw/xwin/winwndproc.c
2003-01-10 09:45:48.000000000 +0000
@@ -137,8 +137,20 @@
* We do this here for future compatibility in case we
* ever allow switching from fullscreen to windowed mode.
*/
- s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics
(SM_CXSCREEN);
- s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics
(SM_CYSCREEN);
+ if (s_pScreenInfo->fMultiplemonitors)
+ {
+ s_pScreenPriv->dwLastWindowsWidth + = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ s_pScreenPriv->dwLastWindowsHeight + = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ }
+ else
+ {
+ s_pScreenPriv->dwLastWindowsWidth
+ = GetSystemMetrics (SM_CXSCREEN);
+ s_pScreenPriv->dwLastWindowsHeight
+ = GetSystemMetrics (SM_CYSCREEN);
+ }
s_pScreenPriv->dwLastWindowsBitsPixel
= GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL);

break;
@@ -280,8 +292,18 @@
}

/* Store the new display dimensions and depth */
+ if (s_pScreenInfo->fMultiplemonitors)
+ {
+ s_pScreenPriv->dwLastWindowsWidth
+ = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ s_pScreenPriv->dwLastWindowsHeight
+ = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ }
+ else
+ {
s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics
(SM_CXSCREEN);
s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics
(SM_CYSCREEN);
+ }
s_pScreenPriv->dwLastWindowsBitsPixel
= GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL);
break;








Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]