From f3418b52dcf2ab4982504856ab9fae3e726ee6d2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 29 Jan 2007 16:10:03 +1030 Subject: mi: Fix cursor rendering issues. --- mi/misprite.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++----------- mi/mispritest.h | 38 +++++++++++--------------- 2 files changed, 85 insertions(+), 38 deletions(-) diff --git a/mi/misprite.c b/mi/misprite.c index 70dda1c3c..8639c5629 100644 --- a/mi/misprite.c +++ b/mi/misprite.c @@ -137,6 +137,8 @@ _X_EXPORT miPointerSpriteFuncRec miSpritePointerFuncs = { static void miSpriteRemoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen); +static void miSpriteSaveUnderCursor(DeviceIntPtr pDev, + ScreenPtr pScreen); static void miSpriteRestoreCursor(DeviceIntPtr pDev, ScreenPtr pScreen); @@ -516,6 +518,18 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask) 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) { if (DevHasCursor(pDev)) @@ -891,14 +905,15 @@ miSpriteSetCursor (pDev, pScreen, pCursor, x, y) else #endif { - SPRITE_DEBUG (("SetCursor remove\n")); + SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id)); miSpriteRemoveCursor (pDev, pScreen); } } if (!pPointer->isUp && pPointer->pCursor) { - SPRITE_DEBUG (("SetCursor restore\n")); + SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id)); + miSpriteSaveUnderCursor(pDev, pScreen); miSpriteRestoreCursor (pDev, pScreen); } @@ -944,6 +959,7 @@ miSpriteRemoveCursor (pDev, pScreen) miSpriteIsUpFALSE (pCursorInfo, pScreen, pScreenPriv); pCursorInfo->pCacheWin = NullWindow; + miSpriteDisableDamage(pScreen, pScreenPriv); if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pDev, pScreen, pCursorInfo->saved.x1, @@ -955,16 +971,17 @@ miSpriteRemoveCursor (pDev, pScreen) { miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv); } + miSpriteEnableDamage(pScreen, pScreenPriv); DamageDrawInternal (pScreen, FALSE); } /* - * Called from the block handler, restores the cursor + * Called from the block handler, saves area under cursor * before waiting for something to do. */ -static void -miSpriteRestoreCursor (pDev, pScreen) +static void +miSpriteSaveUnderCursor(pDev, pScreen) DeviceIntPtr pDev; ScreenPtr pScreen; { @@ -985,25 +1002,61 @@ miSpriteRestoreCursor (pDev, pScreen) x = pCursorInfo->x - (int)pCursor->bits->xhot; y = pCursorInfo->y - (int)pCursor->bits->yhot; - if ((*pScreenPriv->funcs->SaveUnderCursor) (pDev, + 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)) + pCursorInfo->saved.y1); + SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); + miSpriteEnableDamage(pScreen, pScreenPriv); + DamageDrawInternal (pScreen, FALSE); +} + + +/* + * Called from the block handler, restores the cursor + * before waiting for something to do. + */ + +static void +miSpriteRestoreCursor (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); + SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); + if (pCursorInfo->checkPixels) + miSpriteFindColors (pCursorInfo, pScreen); + if ((*pScreenPriv->funcs->PutUpCursor) (pDev, pScreen, + pCursor, x, y, + pCursorInfo->colors[SOURCE_COLOR].pixel, + pCursorInfo->colors[MASK_COLOR].pixel)) { - if (pCursorInfo->checkPixels) - 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); - } + miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv); } + miSpriteEnableDamage(pScreen, pScreenPriv); DamageDrawInternal (pScreen, FALSE); } diff --git a/mi/mispritest.h b/mi/mispritest.h index 39875e0cb..8c8cd5314 100644 --- a/mi/mispritest.h +++ b/mi/mispritest.h @@ -95,31 +95,25 @@ typedef struct { #define MASK_COLOR 1 static int damageRegister = 0; -/* - * FIXME: MPX uses a bug at the moment. The semaphore system in place will - * call miSpriteIsUpTRUE multiple times and thus DamageUnregister() will never - * be called in miSpriteIsUpFALSE. - * This gets rid of cursor rendering artefacts but I don't know how this - * 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) { \ - damageRegister--; \ - if (!damageRegister) { \ - DamageUnregister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ - } \ - pDevCursor->isUp = FALSE; \ +#define miSpriteDisableDamage(pScreen, pScreenPriv) \ + if (damageRegister) { \ + DamageUnregister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ + damageRegister = 0; \ } +#define miSpriteEnableDamage(pScreen, pScreenPriv) \ + if (!damageRegister) {\ + damageRegister = 1; \ + DamageRegister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ + } + +#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 */ -- cgit v1.2.3