mi: Fix cursor rendering issues.

This commit is contained in:
Peter Hutterer 2007-01-29 16:10:03 +10:30 committed by Peter Hutterer
parent 15a81b6325
commit f3418b52dc
2 changed files with 88 additions and 41 deletions

View File

@ -137,6 +137,8 @@ _X_EXPORT miPointerSpriteFuncRec miSpritePointerFuncs = {
static void miSpriteRemoveCursor(DeviceIntPtr pDev, static void miSpriteRemoveCursor(DeviceIntPtr pDev,
ScreenPtr pScreen); ScreenPtr pScreen);
static void miSpriteSaveUnderCursor(DeviceIntPtr pDev,
ScreenPtr pScreen);
static void miSpriteRestoreCursor(DeviceIntPtr pDev, static void miSpriteRestoreCursor(DeviceIntPtr pDev,
ScreenPtr pScreen); ScreenPtr pScreen);
@ -516,6 +518,18 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
SCREEN_EPILOGUE(pScreen, BlockHandler); SCREEN_EPILOGUE(pScreen, BlockHandler);
for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
{
if (DevHasCursor(pDev))
{
pCursorInfo = &pPriv->pDevCursors[pDev->id];
if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
{
SPRITE_DEBUG (("BlockHandler restore\n"));
miSpriteSaveUnderCursor (pDev, pScreen);
}
}
}
for(pDev = inputInfo.devices; pDev; pDev = pDev->next) for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
{ {
if (DevHasCursor(pDev)) if (DevHasCursor(pDev))
@ -891,14 +905,15 @@ miSpriteSetCursor (pDev, pScreen, pCursor, x, y)
else else
#endif #endif
{ {
SPRITE_DEBUG (("SetCursor remove\n")); SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id));
miSpriteRemoveCursor (pDev, pScreen); miSpriteRemoveCursor (pDev, pScreen);
} }
} }
if (!pPointer->isUp && pPointer->pCursor) if (!pPointer->isUp && pPointer->pCursor)
{ {
SPRITE_DEBUG (("SetCursor restore\n")); SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id));
miSpriteSaveUnderCursor(pDev, pScreen);
miSpriteRestoreCursor (pDev, pScreen); miSpriteRestoreCursor (pDev, pScreen);
} }
@ -944,6 +959,7 @@ miSpriteRemoveCursor (pDev, pScreen)
miSpriteIsUpFALSE (pCursorInfo, pScreen, pScreenPriv); miSpriteIsUpFALSE (pCursorInfo, pScreen, pScreenPriv);
pCursorInfo->pCacheWin = NullWindow; pCursorInfo->pCacheWin = NullWindow;
miSpriteDisableDamage(pScreen, pScreenPriv);
if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pDev, if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pDev,
pScreen, pScreen,
pCursorInfo->saved.x1, pCursorInfo->saved.x1,
@ -955,9 +971,53 @@ miSpriteRemoveCursor (pDev, pScreen)
{ {
miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv); miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv);
} }
miSpriteEnableDamage(pScreen, pScreenPriv);
DamageDrawInternal (pScreen, FALSE); DamageDrawInternal (pScreen, FALSE);
} }
/*
* Called from the block handler, saves area under cursor
* before waiting for something to do.
*/
static void
miSpriteSaveUnderCursor(pDev, pScreen)
DeviceIntPtr pDev;
ScreenPtr pScreen;
{
miSpriteScreenPtr pScreenPriv;
int x, y;
CursorPtr pCursor;
miCursorInfoPtr pCursorInfo;
DamageDrawInternal (pScreen, TRUE);
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
pCursorInfo = pScreenPriv->cp;
if (DevHasCursor(pDev))
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
miSpriteComputeSaved (pDev, pScreen);
pCursor = pCursorInfo->pCursor;
x = pCursorInfo->x - (int)pCursor->bits->xhot;
y = pCursorInfo->y - (int)pCursor->bits->yhot;
miSpriteDisableDamage(pScreen, pScreenPriv);
(*pScreenPriv->funcs->SaveUnderCursor) (pDev,
pScreen,
pCursorInfo->saved.x1,
pCursorInfo->saved.y1,
pCursorInfo->saved.x2 -
pCursorInfo->saved.x1,
pCursorInfo->saved.y2 -
pCursorInfo->saved.y1);
SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id));
miSpriteEnableDamage(pScreen, pScreenPriv);
DamageDrawInternal (pScreen, FALSE);
}
/* /*
* Called from the block handler, restores the cursor * Called from the block handler, restores the cursor
* before waiting for something to do. * before waiting for something to do.
@ -985,25 +1045,18 @@ miSpriteRestoreCursor (pDev, pScreen)
x = pCursorInfo->x - (int)pCursor->bits->xhot; x = pCursorInfo->x - (int)pCursor->bits->xhot;
y = pCursorInfo->y - (int)pCursor->bits->yhot; y = pCursorInfo->y - (int)pCursor->bits->yhot;
if ((*pScreenPriv->funcs->SaveUnderCursor) (pDev, miSpriteDisableDamage(pScreen, pScreenPriv);
pScreen, SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id));
pCursorInfo->saved.x1, if (pCursorInfo->checkPixels)
pCursorInfo->saved.y1, miSpriteFindColors (pCursorInfo, pScreen);
pCursorInfo->saved.x2 - if ((*pScreenPriv->funcs->PutUpCursor) (pDev, pScreen,
pCursorInfo->saved.x1, pCursor, x, y,
pCursorInfo->saved.y2 - pCursorInfo->colors[SOURCE_COLOR].pixel,
pCursorInfo->saved.y1)) pCursorInfo->colors[MASK_COLOR].pixel))
{ {
if (pCursorInfo->checkPixels) miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv);
miSpriteFindColors (pCursorInfo, pScreen);
if ((*pScreenPriv->funcs->PutUpCursor) (pDev, pScreen,
pCursor, x, y,
pCursorInfo->colors[SOURCE_COLOR].pixel,
pCursorInfo->colors[MASK_COLOR].pixel))
{
miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv);
}
} }
miSpriteEnableDamage(pScreen, pScreenPriv);
DamageDrawInternal (pScreen, FALSE); DamageDrawInternal (pScreen, FALSE);
} }

View File

@ -95,30 +95,24 @@ typedef struct {
#define MASK_COLOR 1 #define MASK_COLOR 1
static int damageRegister = 0; static int damageRegister = 0;
/*
* FIXME: MPX uses a bug at the moment. The semaphore system in place will #define miSpriteDisableDamage(pScreen, pScreenPriv) \
* call miSpriteIsUpTRUE multiple times and thus DamageUnregister() will never if (damageRegister) { \
* be called in miSpriteIsUpFALSE. DamageUnregister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \
* This gets rid of cursor rendering artefacts but I don't know how this damageRegister = 0; \
* affects applications.
* Without any semaphore system in place DamageRegister will be called twice
* and segfault.
*/
#define miSpriteIsUpTRUE(pDevCursor, pScreen, pScreenPriv) if (!pDevCursor->isUp) { \
pDevCursor->isUp = TRUE; \
if (!damageRegister ) { \
DamageRegister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \
} \
damageRegister++; \
} }
#define miSpriteIsUpFALSE(pDevCursor, pScreen, pScreenPriv) if (pDevCursor->isUp) { \ #define miSpriteEnableDamage(pScreen, pScreenPriv) \
damageRegister--; \ if (!damageRegister) {\
if (!damageRegister) { \ damageRegister = 1; \
DamageUnregister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ DamageRegister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \
} \ }
pDevCursor->isUp = FALSE; \
} #define miSpriteIsUpTRUE(pDevCursor, pScreen, pScreenPriv) if (!pDevCursor->isUp) \
pDevCursor->isUp = TRUE;
#define miSpriteIsUpFALSE(pDevCursor, pScreen, pScreenPriv) if (pDevCursor->isUp) \
pDevCursor->isUp = FALSE;
/* /*
* Overlap BoxPtr and Box elements * Overlap BoxPtr and Box elements