From 54ce7436b2579bb20728eab7c8d460b531c378af Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 2 Oct 2007 10:49:46 +0930 Subject: [PATCH] xfree86: update all pointers when calling xf86SwitchMode Center the frame around the first pointer found and then update all pointers on the same screen to move to the edges (if necessary). Note: xf86WarpCursor needs to be modified, is using deprecated miPointerWarpCursor and will kill the server when called with inputInfo.pointer. --- hw/xfree86/common/xf86Cursor.c | 53 ++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/common/xf86Cursor.c b/hw/xfree86/common/xf86Cursor.c index 38bd38c62..d6fa60461 100644 --- a/hw/xfree86/common/xf86Cursor.c +++ b/hw/xfree86/common/xf86Cursor.c @@ -206,6 +206,7 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode) ScreenPtr pCursorScreen; Bool Switched; int px, py; + DeviceIntPtr dev, it; if (!pScr->vtSema || !mode || !pScr->SwitchMode) return FALSE; @@ -221,9 +222,20 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode) if (mode->HDisplay > pScr->virtualX || mode->VDisplay > pScr->virtualY) return FALSE; - pCursorScreen = miPointerGetScreen(inputInfo.pointer); + /* Let's take an educated guess for which pointer to take here. And about as + educated as it gets is to take the first pointer we find. + */ + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner) + break; + } + if (!dev) + dev = inputInfo.pointer; + + pCursorScreen = miPointerGetScreen(dev); if (pScreen == pCursorScreen) - miPointerGetPosition(inputInfo.pointer, &px, &py); + miPointerGetPosition(dev, &px, &py); xf86EnterServerState(SETUP); Switched = (*pScr->SwitchMode)(pScr->scrnIndex, mode, 0); @@ -232,6 +244,7 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode) /* * Adjust frame for new display size. + * Frame is centered around cursor position if cursor is on same screen. */ if (pScreen == pCursorScreen) pScr->frameX0 = px - (mode->HDisplay / 2) + 1; @@ -266,8 +279,42 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode) if (pScr->AdjustFrame) (*pScr->AdjustFrame)(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0); + /* The original code centered the frame around the cursor if possible. + * Since this is hard to achieve with multiple cursors, we do the following: + * - center around the first pointer + * - move all other pointers to the nearest edge on the screen (or leave + * them unmodified if they are within the boundaries). + */ if (pScreen == pCursorScreen) - xf86WarpCursor(inputInfo.pointer, pScreen, px, py); + { + xf86WarpCursor(dev, pScreen, px, py); + } + + for (it = inputInfo.devices; it; it = it->next) + { + if (it == dev) + continue; + + if (IsPointerDevice(it) && it->spriteInfo->spriteOwner) + { + pCursorScreen = miPointerGetScreen(it); + if (pScreen == pCursorScreen) + { + miPointerGetPosition(it, &px, &py); + if (px < pScr->frameX0) + px = pScr->frameX0; + else if (px > pScr->frameX1) + px = pScr->frameX1; + + if(py < pScr->frameY0) + py = pScr->frameY0; + else if(py > pScr->frameY1) + py = pScr->frameY1; + + xf86WarpCursor(it, pScreen, px, py); + } + } + } return Switched; }