From b9c1a57e7a98dea63cd362f714411547e728a85a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 6 May 2008 14:51:23 +0930 Subject: [PATCH] xfree86: switch between to SW cursors if more than 1 sprite is available. Switches back to HW cursors when sprites other than the VCP are removed. The current state requires the cursor to change shape once before it updates to SW / HW rendering (whatever is appropriate), e.g. by moving into a different window. Until this is done, the cursor is invisible. --- hw/xfree86/ramdac/xf86Cursor.c | 44 +++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c index 61fb0ed58..4ecb03e7b 100644 --- a/hw/xfree86/ramdac/xf86Cursor.c +++ b/hw/xfree86/ramdac/xf86Cursor.c @@ -20,6 +20,8 @@ extern InputInfo inputInfo; DevPrivateKey xf86CursorScreenKey = &xf86CursorScreenKey; +#define XF86_FORCE_SW_CURSOR (1 << 7) + /* sprite functions */ static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr); @@ -325,25 +327,29 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, PointPriv = (miPointerScreenPtr)dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); - if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || (( -#ifdef ARGB_CURSOR - pCurs->bits->argb && infoPtr->UseHWCursorARGB && - (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || ( - pCurs->bits->argb == 0 && -#endif - (pCurs->bits->height <= infoPtr->MaxHeight) && - (pCurs->bits->width <= infoPtr->MaxWidth) && - (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs)))))) + if (!(ScreenPriv->SWCursor & XF86_FORCE_SW_CURSOR)) { + if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || (( +#ifdef ARGB_CURSOR + pCurs->bits->argb && infoPtr->UseHWCursorARGB && + (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || ( + pCurs->bits->argb == 0 && +#endif + (pCurs->bits->height <= infoPtr->MaxHeight) && + (pCurs->bits->width <= infoPtr->MaxWidth) && + (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs)))))) + { if (ScreenPriv->SWCursor) /* remove the SW cursor */ - (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y); + (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y); xf86SetCursor(pScreen, pCurs, x, y); ScreenPriv->SWCursor = FALSE; ScreenPriv->isUp = TRUE; PointPriv->waitForUpdate = !infoPtr->pScrn->silkenMouse; return; + } + } PointPriv->waitForUpdate = TRUE; @@ -358,10 +364,12 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, } } - ScreenPriv->SWCursor = TRUE; + if (!ScreenPriv->SWCursor) + ScreenPriv->SWCursor = TRUE; if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent) pCurs = NullCursor; + (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, pCurs, x, y); } @@ -436,6 +444,9 @@ xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate( &pScreen->devPrivates, xf86CursorScreenKey); + if (pDev != inputInfo.pointer) + ScreenPriv->SWCursor = TRUE | XF86_FORCE_SW_CURSOR; + /* Init SW cursor */ return (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen); } @@ -446,9 +457,20 @@ xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) static void xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) { + DeviceIntPtr it; xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate( &pScreen->devPrivates, xf86CursorScreenKey); + for (it = inputInfo.devices; it; it = it->next) + { + if (it->isMaster && it != inputInfo.pointer && it != + inputInfo.keyboard) + break; + } + + if (!it) /* no other sprites except VCP. restore HW rendering */ + ScreenPriv->SWCursor = TRUE; + /* Clean up SW cursor */ (*ScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen); }