summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2007-01-29 16:10:03 +1030
committerPeter Hutterer <whot@hyena.localdomain>2007-01-29 16:10:03 +1030
commitf3418b52dcf2ab4982504856ab9fae3e726ee6d2 (patch)
tree9430f58bb65e09b1d0f9172090e583359a1c3a4f
parent15a81b6325d359990017b8e9f17ce18a7eff1354 (diff)
mi: Fix cursor rendering issues.
-rw-r--r--mi/misprite.c85
-rw-r--r--mi/mispritest.h38
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);
@@ -524,6 +526,18 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
{
SPRITE_DEBUG (("BlockHandler restore\n"));
+ miSpriteSaveUnderCursor (pDev, pScreen);
+ }
+ }
+ }
+ 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"));
miSpriteRestoreCursor (pDev, pScreen);
}
}
@@ -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
*/