summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2007-04-26 22:18:35 +0930
committerPeter Hutterer <peter@cs.unisa.edu.au>2007-04-26 22:18:35 +0930
commitcfc01115af4136b2dad8218ba6b389513a356a2e (patch)
tree73a5a4351cbc45ae9658f5f34e9e0b1d8992fffe
parent82f97e1c0cc15b050edc82a8f3b9a423d6cf5fe7 (diff)
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.
-rw-r--r--mi/midispcur.c67
-rw-r--r--mi/misprite.c27
-rw-r--r--mi/mispritest.h1
3 files changed, 87 insertions, 8 deletions
diff --git a/mi/midispcur.c b/mi/midispcur.c
index d4471f9e5..d7a8964dc 100644
--- a/mi/midispcur.c
+++ b/mi/midispcur.c
@@ -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
*/
diff --git a/mi/misprite.c b/mi/misprite.c
index 60774b562..6e4215270 100644
--- a/mi/misprite.c
+++ b/mi/misprite.c
@@ -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);
diff --git a/mi/mispritest.h b/mi/mispritest.h
index f4155b5d5..81efa44e4 100644
--- a/mi/mispritest.h
+++ b/mi/mispritest.h
@@ -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;
/*