Howdy,
There is a bug in the way XWin handles Windows screen coordinates when
it's run on a system with legal negative position values. That is, there
is a monitor to the left of the primary monitor, whose screen coords are
(-xxx,0), and the global screen coords are from (-xxx,0) to (+xxx,0). You
can reproduce this on a 2 head system by setting the rightmost head to be
the Control Panel->Display Settings->Settings->Use this device as my
primary monitor, and then running "XWin.exe -multiwindow -multiplemonitors"
The fix is to offset screen coords by SM_XVIRTUALSCREEN/SM_YVIRTUALSCREEN
whenever you are mapping to/from root window coords (window positioning,
mouse movements).
diff -w -patch changes to winmultiwindowwindow.c are:
-8<-------------------------------------------------------------------
*** orig Sun May 11 11:47:45 2003
--- winmultiwindowwindow.c Sun May 11 11:57:24 2003
*************** winPositionWindowMultiWindow (WindowPtr
*** 194,199 ****
--- 194,203 ----
iX = pWin->drawable.x;
iY = pWin->drawable.y;
+ /* Root coord(0,0) is really (-X, -Y) */
+ iX += GetSystemMetrics(SM_XVIRTUALSCREEN);
+ iY += GetSystemMetrics(SM_YVIRTUALSCREEN);
+
/* Get the height and width of the X window */
iWidth = pWin->drawable.width;
iHeight = pWin->drawable.height;
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 778,783 ****
--- 782,791 ----
/* Translate the client area mouse coordinates to screen
coordinates */
ClientToScreen (hwnd, &ptMouse);
+ /* Screen Coords from (-X,-Y) => Root Window (0,0) */
+ ptMouse.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
+ ptMouse.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
+
/* We can't do anything without privates */
if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
break;
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 907,912 ****
--- 915,925 ----
/* Translate the client area mouse coordinates to screen
coordinates */
ClientToScreen (hwnd, &ptMouse);
+ /* Screen Coords from (-X,-Y) => Root Window (0,0) */
+ ptMouse.left -= GetSystemMetrics(SM_XVIRTUALSCREEN);
+ ptMouse.top -= GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+
/* Pass the message to the root window */
SendMessage (hwndScreen, message, wParam, MAKELONG(ptMouse.x,
ptMouse.y));
return 0;
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 1063,1071 ****
SendConfigureNotify (pWin);
/* Tell X that the window is moving */
(s_pScreen->MoveWindow) (pWin,
! (int)(short) LOWORD(lParam) -
wBorderWidth (pWin),
! (int)(short) HIWORD(lParam) -
wBorderWidth (pWin),
pWin->nextSib,
VTMove);
return 0;
--- 1076,1085 ----
SendConfigureNotify (pWin);
/* Tell X that the window is moving */
+ /* Be sure to map from screen (-X,-Y) to (0,0) root coords */
(s_pScreen->MoveWindow) (pWin,
! (int)(short) LOWORD(lParam) -
wBorderWidth (pWin) - GetSystemMetrics(SM_XVIRTUALSCREEN),
! (int)(short) HIWORD(lParam) -
wBorderWidth (pWin) - GetSystemMetrics(SM_YVIRTUALSCREEN),
pWin->nextSib,
VTMove);
return 0;
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 1220,1228 ****
SendConfigureNotify (pWin);
/* Tell the X server that the window is being resized */
(s_pScreen->ResizeWindow) (pWin,
! pWinPriv->iX - wBorderWidth (pWin),
! pWinPriv->iY - wBorderWidth (pWin),
pWinPriv->iWidth,
pWinPriv->iHeight,
pWin->nextSib);
--- 1234,1243 ----
SendConfigureNotify (pWin);
/* Tell the X server that the window is being resized */
+ /* Map from screen (-X,-Y) to (0,0) root coords */
(s_pScreen->ResizeWindow) (pWin,
! pWinPriv->iX - wBorderWidth
(pWin) - GetSystemMetrics(SM_XVIRTUALSCREEN),
! pWinPriv->iY - wBorderWidth
(pWin) - GetSystemMetrics(SM_YVIRTUALSCREEN),
pWinPriv->iWidth,
pWinPriv->iHeight,
pWin->nextSib);
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 1316,1321 ****
--- 1331,1340 ----
/* Get the current position of the mouse cursor */
GetCursorPos (&point);
+ /* Map from screen (-x,-y) to root (0,0) */
+ point.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
+ point.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
+
/* Deliver absolute cursor position to X Server */
miPointerAbsoluteCursor (point.x, point.y,
g_c32LastInputEventTime =
GetTickCount ());
*************** winCreateWindowsWindow (WindowPtr pWin)
*** 1358,1363 ****
--- 1377,1386 ----
iX = pWin->drawable.x;
iY = pWin->drawable.y;
+ /* Map from root coord (0,0) to screen (-X, -Y) */
+ iX += GetSystemMetrics(SM_XVIRTUALSCREEN);
+ iY += GetSystemMetrics(SM_YVIRTUALSCREEN);
+
iWidth = pWin->drawable.width;
iHeight = pWin->drawable.height;
-8<-------------------------------------------------------------------
-Earle F. Philhower, III
earle@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
------------------------------------------------------------------------
*** orig Sun May 11 11:47:45 2003
--- winmultiwindowwindow.c Sun May 11 11:57:24 2003
*************** winPositionWindowMultiWindow (WindowPtr
*** 194,199 ****
--- 194,203 ----
iX = pWin->drawable.x;
iY = pWin->drawable.y;
+ /* Root coord(0,0) is really (-X, -Y) */
+ iX += GetSystemMetrics(SM_XVIRTUALSCREEN);
+ iY += GetSystemMetrics(SM_YVIRTUALSCREEN);
+
/* Get the height and width of the X window */
iWidth = pWin->drawable.width;
iHeight = pWin->drawable.height;
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 778,783 ****
--- 782,791 ----
/* Translate the client area mouse coordinates to screen coordinates */
ClientToScreen (hwnd, &ptMouse);
+ /* Screen Coords from (-X,-Y) => Root Window (0,0) */
+ ptMouse.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
+ ptMouse.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
+
/* We can't do anything without privates */
if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
break;
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 907,912 ****
--- 915,925 ----
/* Translate the client area mouse coordinates to screen coordinates */
ClientToScreen (hwnd, &ptMouse);
+ /* Screen Coords from (-X,-Y) => Root Window (0,0) */
+ ptMouse.left -= GetSystemMetrics(SM_XVIRTUALSCREEN);
+ ptMouse.top -= GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+
/* Pass the message to the root window */
SendMessage (hwndScreen, message, wParam, MAKELONG(ptMouse.x, ptMouse.y));
return 0;
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 1063,1071 ****
SendConfigureNotify (pWin);
/* Tell X that the window is moving */
(s_pScreen->MoveWindow) (pWin,
! (int)(short) LOWORD(lParam) - wBorderWidth (pWin),
! (int)(short) HIWORD(lParam) - wBorderWidth (pWin),
pWin->nextSib,
VTMove);
return 0;
--- 1076,1085 ----
SendConfigureNotify (pWin);
/* Tell X that the window is moving */
+ /* Be sure to map from screen (-X,-Y) to (0,0) root coords */
(s_pScreen->MoveWindow) (pWin,
! (int)(short) LOWORD(lParam) - wBorderWidth (pWin) - GetSystemMetrics(SM_XVIRTUALSCREEN),
! (int)(short) HIWORD(lParam) - wBorderWidth (pWin) - GetSystemMetrics(SM_YVIRTUALSCREEN),
pWin->nextSib,
VTMove);
return 0;
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 1220,1228 ****
SendConfigureNotify (pWin);
/* Tell the X server that the window is being resized */
(s_pScreen->ResizeWindow) (pWin,
! pWinPriv->iX - wBorderWidth (pWin),
! pWinPriv->iY - wBorderWidth (pWin),
pWinPriv->iWidth,
pWinPriv->iHeight,
pWin->nextSib);
--- 1234,1243 ----
SendConfigureNotify (pWin);
/* Tell the X server that the window is being resized */
+ /* Map from screen (-X,-Y) to (0,0) root coords */
(s_pScreen->ResizeWindow) (pWin,
! pWinPriv->iX - wBorderWidth (pWin) - GetSystemMetrics(SM_XVIRTUALSCREEN),
! pWinPriv->iY - wBorderWidth (pWin) - GetSystemMetrics(SM_YVIRTUALSCREEN),
pWinPriv->iWidth,
pWinPriv->iHeight,
pWin->nextSib);
*************** winTopLevelWindowProc (HWND hwnd, UINT m
*** 1316,1321 ****
--- 1331,1340 ----
/* Get the current position of the mouse cursor */
GetCursorPos (&point);
+ /* Map from screen (-x,-y) to root (0,0) */
+ point.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
+ point.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
+
/* Deliver absolute cursor position to X Server */
miPointerAbsoluteCursor (point.x, point.y,
g_c32LastInputEventTime = GetTickCount ());
*************** winCreateWindowsWindow (WindowPtr pWin)
*** 1358,1363 ****
--- 1377,1386 ----
iX = pWin->drawable.x;
iY = pWin->drawable.y;
+ /* Map from root coord (0,0) to screen (-X, -Y) */
+ iX += GetSystemMetrics(SM_XVIRTUALSCREEN);
+ iY += GetSystemMetrics(SM_YVIRTUALSCREEN);
+
iWidth = pWin->drawable.width;
iHeight = pWin->drawable.height;
------------------------------------------------------------------------