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; }