Fix cursor rendering for multi-head.

Before putting anything on the screen, check if the GC was made for the
ScreenRec we want to render to. If not, toss the GC and create a new one. This
is not the best solution but it does the job for now. Same thing for ARGB
cursors except that it's even uglier.

Also remember the screen the cursor was rendered to and check for the right
screen in the BlockHandler, SourceValidate and a few others. Only remove or
restore the cursor if we are rendering to the same screen, otherwise we get
artefacts that are both funky and really annoying.
This commit is contained in:
Peter Hutterer 2007-04-26 22:18:35 +09:30
parent 82f97e1c0c
commit cfc01115af
3 changed files with 87 additions and 8 deletions

View File

@ -488,6 +488,15 @@ miDCPutUpCursor (pDev, pScreen, pCursor, x, y, source, mask)
#ifdef ARGB_CURSOR
if (pPriv->pPicture)
{
/* see comment in miDCPutUpCursor */
if (pBuffer->pRootPicture &&
pBuffer->pRootPicture->pDrawable &&
pBuffer->pRootPicture->pDrawable->pScreen != pScreen)
{
tossPict(pBuffer->pRootPicture);
pBuffer->pRootPicture = NULL;
}
if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin))
return FALSE;
CompositePicture (PictOpOver,
@ -502,6 +511,25 @@ miDCPutUpCursor (pDev, pScreen, pCursor, x, y, source, mask)
else
#endif
{
/**
* XXX: Before MPX, the sourceGC and maskGC were attached to the
* screen, and would switch as the screen switches. With mpx we have
* the GC's attached to the device now, so each time we switch screen
* we need to make sure the GC's are allocated on the new screen.
* This is ... not optimal. (whot)
*/
if (pBuffer->pSourceGC && pScreen != pBuffer->pSourceGC->pScreen)
{
tossGC(pBuffer->pSourceGC);
pBuffer->pSourceGC = NULL;
}
if (pBuffer->pMaskGC && pScreen != pBuffer->pMaskGC->pScreen)
{
tossGC(pBuffer->pMaskGC);
pBuffer->pMaskGC = NULL;
}
if (!EnsureGC(pBuffer->pSourceGC, pWin))
return FALSE;
if (!EnsureGC(pBuffer->pMaskGC, pWin))
@ -544,6 +572,12 @@ miDCSaveUnderCursor (pDev, pScreen, x, y, w, h)
if (!pSave)
return FALSE;
}
/* see comment in miDCPutUpCursor */
if (pBuffer->pSaveGC && pBuffer->pSaveGC->pScreen != pScreen)
{
tossGC(pBuffer->pSaveGC);
pBuffer->pSaveGC = NULL;
}
if (!EnsureGC(pBuffer->pSaveGC, pWin))
return FALSE;
pGC = pBuffer->pSaveGC;
@ -573,6 +607,12 @@ miDCRestoreUnderCursor (pDev, pScreen, x, y, w, h)
pWin = WindowTable[pScreen->myNum];
if (!pSave)
return FALSE;
/* see comment in miDCPutUpCursor */
if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
{
tossGC(pBuffer->pRestoreGC);
pBuffer->pRestoreGC = NULL;
}
if (!EnsureGC(pBuffer->pRestoreGC, pWin))
return FALSE;
pGC = pBuffer->pRestoreGC;
@ -606,6 +646,12 @@ miDCChangeSave (pDev, pScreen, x, y, w, h, dx, dy)
*/
if (!pSave)
return FALSE;
/* see comment in miDCPutUpCursor */
if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
{
tossGC(pBuffer->pRestoreGC);
pBuffer->pRestoreGC = NULL;
}
if (!EnsureGC(pBuffer->pRestoreGC, pWin))
return FALSE;
pGC = pBuffer->pRestoreGC;
@ -646,6 +692,12 @@ miDCChangeSave (pDev, pScreen, x, y, w, h, dx, dy)
(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
0, sourcey, -dx, copyh, x + dx, desty);
}
/* see comment in miDCPutUpCursor */
if (pBuffer->pSaveGC && pBuffer->pSaveGC->pScreen != pScreen)
{
tossGC(pBuffer->pSaveGC);
pBuffer->pSaveGC = NULL;
}
if (!EnsureGC(pBuffer->pSaveGC, pWin))
return FALSE;
pGC = pBuffer->pSaveGC;
@ -788,6 +840,15 @@ miDCMoveCursor (pDev, pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
#ifdef ARGB_CURSOR
if (pPriv->pPicture)
{
/* see comment in miDCPutUpCursor */
if (pBuffer->pTempPicture &&
pBuffer->pTempPicture->pDrawable &&
pBuffer->pTempPicture->pDrawable->pScreen != pScreen)
{
tossPict(pBuffer->pTempPicture);
pBuffer->pTempPicture = NULL;
}
if (!EnsurePicture(pBuffer->pTempPicture, &pTemp->drawable, pWin))
return FALSE;
CompositePicture (PictOpOver,
@ -822,6 +883,12 @@ miDCMoveCursor (pDev, pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
source, mask);
}
/* see comment in miDCPutUpCursor */
if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
{
tossGC(pBuffer->pRestoreGC);
pBuffer->pRestoreGC = NULL;
}
/*
* copy the temporary pixmap onto the screen
*/

View File

@ -79,6 +79,7 @@ static int miSpriteDevPrivatesIndex;
(miCursorInfoPtr) dev->devPrivates[miSpriteDevPrivatesIndex].ptr : \
(miCursorInfoPtr) inputInfo.pointer->devPrivates[miSpriteDevPrivatesIndex].ptr)
/*
* screen wrappers
*/
@ -175,6 +176,7 @@ miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
pCursorInfo = MISPRITE(pDev);
if (pCursorInfo->isUp &&
pCursorInfo->pScreen == pScreen &&
RECT_IN_REGION (pScreen, pRegion, &pCursorInfo->saved)
!= rgnOUT)
{
@ -277,7 +279,6 @@ miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
damageRegister = 0;
miSpriteDevPrivatesIndex = AllocateDevicePrivateIndex();
return TRUE;
}
@ -340,6 +341,7 @@ miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
pCursorInfo = MISPRITE(pDev);
if (pDrawable->type == DRAWABLE_WINDOW &&
pCursorInfo->isUp &&
pCursorInfo->pScreen == pScreen &&
ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y,
sx, sy, w, h))
{
@ -379,7 +381,9 @@ miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
{
pCursorInfo = MISPRITE(pDev);
if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp)
if (pDrawable->type == DRAWABLE_WINDOW &&
pCursorInfo->isUp &&
pCursorInfo->pScreen == pScreen)
{
DDXPointPtr pts;
int *widths;
@ -431,6 +435,7 @@ miSpriteSourceValidate (pDrawable, x, y, width, height)
{
pCursorInfo = MISPRITE(pDev);
if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp &&
pCursorInfo->pScreen == pScreen &&
ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y,
x, y, width, height))
{
@ -466,7 +471,7 @@ miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
/*
* Damage will take care of destination check
*/
if (pCursorInfo->isUp &&
if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
RECT_IN_REGION (pScreen, prgnSrc, &pCursorInfo->saved) != rgnOUT)
{
SPRITE_DEBUG (("CopyWindow remove\n"));
@ -504,7 +509,9 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
if (DevHasCursor(pDev))
{
pCursorInfo = MISPRITE(pDev);
if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
if (!pCursorInfo->isUp
&& pCursorInfo->pScreen == pScreen
&& pCursorInfo->shouldBeUp)
{
SPRITE_DEBUG (("BlockHandler restore\n"));
miSpriteSaveUnderCursor (pDev, pScreen);
@ -516,7 +523,9 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
if (DevHasCursor(pDev))
{
pCursorInfo = MISPRITE(pDev);
if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
if (!pCursorInfo->isUp &&
pCursorInfo->pScreen == pScreen &&
pCursorInfo->shouldBeUp)
{
SPRITE_DEBUG (("BlockHandler restore\n"));
miSpriteRestoreCursor (pDev, pScreen);
@ -552,7 +561,7 @@ miSpriteInstallColormap (pMap)
{
pCursorInfo = MISPRITE(pDev);
pCursorInfo->checkPixels = TRUE;
if (pCursorInfo->isUp)
if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
miSpriteRemoveCursor(pDev, pScreen);
}
}
@ -639,7 +648,7 @@ miSpriteStoreColors (pMap, ndef, pdef)
{
pCursorInfo = MISPRITE(pDev);
pCursorInfo->checkPixels = TRUE;
if (pCursorInfo->isUp)
if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
miSpriteRemoveCursor (pDev, pScreen);
}
}
@ -711,7 +720,7 @@ miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
if(DevHasCursor(pDev))
{
pCursorInfo = MISPRITE(pDev);
if (pCursorInfo->isUp)
if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
{
cursorBox = pCursorInfo->saved;
@ -930,6 +939,7 @@ miSpriteDeviceCursorInitialize(pDev, pScreen)
pCursorInfo->pCacheWin = NullWindow;
pCursorInfo->isInCacheWin = FALSE;
pCursorInfo->checkPixels = TRUE;
pCursorInfo->pScreen = FALSE;
ret = (*pScreenPriv->funcs->DeviceCursorInitialize)(pDev, pScreen);
if (!ret)
@ -1075,6 +1085,7 @@ miSpriteRestoreCursor (pDev, pScreen)
pScreenPriv->colors[MASK_COLOR].pixel))
{
miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv);
pCursorInfo->pScreen = pScreen;
}
miSpriteEnableDamage(pScreen, pScreenPriv);
DamageDrawInternal (pScreen, FALSE);

View File

@ -53,6 +53,7 @@ typedef struct {
WindowPtr pCacheWin; /* window the cursor last seen in */
Bool isInCacheWin;
Bool checkPixels; /* check colormap collision */
ScreenPtr pScreen;
} miCursorInfoRec, *miCursorInfoPtr;
/*