diff options
author | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-04-26 22:18:35 +0930 |
---|---|---|
committer | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-04-26 22:18:35 +0930 |
commit | cfc01115af4136b2dad8218ba6b389513a356a2e (patch) | |
tree | 73a5a4351cbc45ae9658f5f34e9e0b1d8992fffe | |
parent | 82f97e1c0cc15b050edc82a8f3b9a423d6cf5fe7 (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.c | 67 | ||||
-rw-r--r-- | mi/misprite.c | 27 | ||||
-rw-r--r-- | mi/mispritest.h | 1 |
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; /* |