forked from pool/xorg-x11-server
Stefan Dirsch
3da29b8c96
U_0002-animcur-Return-the-next-interval-directly-from-the-t.patch, U_0003-animcur-Run-the-timer-from-the-device-not-the-screen.patch, U_0004-animcur-Fix-transitions-between-animated-cursors.patch * There is a bug in version 1.19 of the X.org X server that can cause an infinite recursion in the animated cursor code, which has been fixed by these patches (boo#1080312) - supersedes u_cursors-animation.patch (boo#1020061) OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=690
189 lines
7.0 KiB
Diff
189 lines
7.0 KiB
Diff
From 693f0e21d55d6e9fe792d91e76e4168aa813db71 Mon Sep 17 00:00:00 2001
|
|
From: Adam Jackson <ajax@redhat.com>
|
|
Date: Thu, 26 Oct 2017 15:24:39 -0400
|
|
Subject: [PATCH] animcur: Run the timer from the device, not the screen
|
|
|
|
This is very slightly more efficient since the callback now doesn't need
|
|
to walk every input device, instead we know exactly which device's
|
|
cursor is being updated. AnimCurTimerNotify() gets outdented nicely as a
|
|
result. A more important side effect is that we can stop using the
|
|
TimerAbsolute mode and just pass in the relative delay.
|
|
|
|
In AnimCurSetCursorPosition, we no longer need to rearm the timer with
|
|
the new screen; it is enough to update the device's state. In
|
|
AnimCurDisplayCursor we need to notice when we're switching from
|
|
animated cursor to regular and cancel the existing timer.
|
|
|
|
Reviewed-by: Robert Morell <rmorell@nvidia.com>
|
|
Tested-by: Robert Morell <rmorell@nvidia.com>
|
|
Signed-off-by: Adam Jackson <ajax@redhat.com>
|
|
(cherry picked from commit 094a63d56fbfb9e23210cc9ac538fb198af37cee)
|
|
---
|
|
render/animcur.c | 87 +++++++++++++++++++-------------------------------------
|
|
1 file changed, 29 insertions(+), 58 deletions(-)
|
|
|
|
diff --git a/render/animcur.c b/render/animcur.c
|
|
index 26a6026ae..9393b4018 100644
|
|
--- a/render/animcur.c
|
|
+++ b/render/animcur.c
|
|
@@ -55,6 +55,7 @@ typedef struct _AnimCurElt {
|
|
typedef struct _AnimCur {
|
|
int nelt; /* number of elements in the elts array */
|
|
AnimCurElt *elts; /* actually allocated right after the structure */
|
|
+ OsTimerPtr timer;
|
|
} AnimCurRec, *AnimCurPtr;
|
|
|
|
typedef struct _AnimScrPriv {
|
|
@@ -65,8 +66,6 @@ typedef struct _AnimScrPriv {
|
|
RealizeCursorProcPtr RealizeCursor;
|
|
UnrealizeCursorProcPtr UnrealizeCursor;
|
|
RecolorCursorProcPtr RecolorCursor;
|
|
- OsTimerPtr timer;
|
|
- Bool timer_set;
|
|
} AnimCurScreenRec, *AnimCurScreenPtr;
|
|
|
|
static unsigned char empty[4];
|
|
@@ -130,49 +129,27 @@ AnimCurCursorLimits(DeviceIntPtr pDev,
|
|
static CARD32
|
|
AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg)
|
|
{
|
|
- ScreenPtr pScreen = arg;
|
|
+ DeviceIntPtr dev = arg;
|
|
+ ScreenPtr pScreen = dev->spriteInfo->anim.pScreen;
|
|
AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
|
|
- DeviceIntPtr dev;
|
|
- Bool activeDevice = FALSE;
|
|
- CARD32 soonest = ~0; /* earliest time to wakeup again */
|
|
-
|
|
- for (dev = inputInfo.devices; dev; dev = dev->next) {
|
|
- if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
|
|
- if (!activeDevice)
|
|
- activeDevice = TRUE;
|
|
-
|
|
- if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) {
|
|
- AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor);
|
|
- int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt;
|
|
- DisplayCursorProcPtr DisplayCursor;
|
|
-
|
|
- /*
|
|
- * Not a simple Unwrap/Wrap as this
|
|
- * isn't called along the DisplayCursor
|
|
- * wrapper chain.
|
|
- */
|
|
- DisplayCursor = pScreen->DisplayCursor;
|
|
- pScreen->DisplayCursor = as->DisplayCursor;
|
|
- (void) (*pScreen->DisplayCursor) (dev,
|
|
- pScreen,
|
|
- ac->elts[elt].pCursor);
|
|
- as->DisplayCursor = pScreen->DisplayCursor;
|
|
- pScreen->DisplayCursor = DisplayCursor;
|
|
-
|
|
- dev->spriteInfo->anim.elt = elt;
|
|
- dev->spriteInfo->anim.time = now + ac->elts[elt].delay;
|
|
- }
|
|
|
|
- if (soonest > dev->spriteInfo->anim.time)
|
|
- soonest = dev->spriteInfo->anim.time;
|
|
- }
|
|
- }
|
|
+ AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor);
|
|
+ int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt;
|
|
+ DisplayCursorProcPtr DisplayCursor = pScreen->DisplayCursor;
|
|
|
|
- if (activeDevice)
|
|
- return soonest - now;
|
|
+ /*
|
|
+ * Not a simple Unwrap/Wrap as this isn't called along the DisplayCursor
|
|
+ * wrapper chain.
|
|
+ */
|
|
+ pScreen->DisplayCursor = as->DisplayCursor;
|
|
+ (void) (*pScreen->DisplayCursor) (dev, pScreen, ac->elts[elt].pCursor);
|
|
+ as->DisplayCursor = pScreen->DisplayCursor;
|
|
+ pScreen->DisplayCursor = DisplayCursor;
|
|
|
|
- as->timer_set = FALSE;
|
|
- return 0;
|
|
+ dev->spriteInfo->anim.elt = elt;
|
|
+ dev->spriteInfo->anim.time = now + ac->elts[elt].delay;
|
|
+
|
|
+ return ac->elts[elt].delay;
|
|
}
|
|
|
|
static Bool
|
|
@@ -198,17 +175,19 @@ AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
|
|
pDev->spriteInfo->anim.pCursor = pCursor;
|
|
pDev->spriteInfo->anim.pScreen = pScreen;
|
|
|
|
- if (!as->timer_set) {
|
|
- TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
|
|
- AnimCurTimerNotify, pScreen);
|
|
- as->timer_set = TRUE;
|
|
- }
|
|
+ ac->timer = TimerSet(ac->timer, 0, ac->elts[0].delay,
|
|
+ AnimCurTimerNotify, pDev);
|
|
}
|
|
}
|
|
else
|
|
ret = TRUE;
|
|
}
|
|
else {
|
|
+ CursorPtr old = pDev->spriteInfo->anim.pCursor;
|
|
+
|
|
+ if (old && IsAnimCur(old))
|
|
+ TimerCancel(GetAnimCur(old)->timer);
|
|
+
|
|
pDev->spriteInfo->anim.pCursor = 0;
|
|
pDev->spriteInfo->anim.pScreen = 0;
|
|
ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
|
|
@@ -227,12 +206,6 @@ AnimCurSetCursorPosition(DeviceIntPtr pDev,
|
|
Unwrap(as, pScreen, SetCursorPosition);
|
|
if (pDev->spriteInfo->anim.pCursor) {
|
|
pDev->spriteInfo->anim.pScreen = pScreen;
|
|
-
|
|
- if (!as->timer_set) {
|
|
- TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
|
|
- AnimCurTimerNotify, pScreen);
|
|
- as->timer_set = TRUE;
|
|
- }
|
|
}
|
|
ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
|
|
Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
|
|
@@ -307,11 +280,6 @@ AnimCurInit(ScreenPtr pScreen)
|
|
return FALSE;
|
|
|
|
as = GetAnimCurScreen(pScreen);
|
|
- as->timer = TimerSet(NULL, TimerAbsolute, 0, AnimCurTimerNotify, pScreen);
|
|
- if (!as->timer) {
|
|
- return FALSE;
|
|
- }
|
|
- as->timer_set = FALSE;
|
|
|
|
Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
|
|
|
|
@@ -359,10 +327,14 @@ AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
|
|
|
|
pCursor->id = cid;
|
|
|
|
+ ac = GetAnimCur(pCursor);
|
|
+ ac->timer = TimerSet(NULL, 0, 0, AnimCurTimerNotify, NULL);
|
|
+
|
|
/* security creation/labeling check */
|
|
rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCursor,
|
|
RT_NONE, NULL, DixCreateAccess);
|
|
if (rc != Success) {
|
|
+ TimerFree(ac->timer);
|
|
dixFiniPrivates(pCursor, PRIVATE_CURSOR);
|
|
free(pCursor);
|
|
return rc;
|
|
@@ -372,7 +344,6 @@ AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
|
|
* Fill in the AnimCurRec
|
|
*/
|
|
animCursorBits.refcnt++;
|
|
- ac = GetAnimCur(pCursor);
|
|
ac->nelt = ncursor;
|
|
ac->elts = (AnimCurElt *) (ac + 1);
|
|
|
|
--
|
|
2.13.6
|
|
|