summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2013-09-16 15:02:06 +0100
committerJon TURNEY <jon.turney@dronecode.org.uk>2013-09-16 15:02:06 +0100
commit348c230cb7219c9c813f7ddfa6e9f36d7d7c4062 (patch)
tree599f94c474e239f7046dbf52ee31ca3c210edd94
parent7a15097ca990ea73fb5d79f7133694f73539b747 (diff)
parent9acb64f54ee9dd2fe41afda159b919280850ad8e (diff)
Merge tag 'xorg-server-1.14.3' into cygwin-release-1.14
xorg-server-1.14.3 Conflicts: dix/main.c
-rw-r--r--Xext/saver.c8
-rw-r--r--Xi/exevents.c155
-rw-r--r--Xi/ungrdevb.c2
-rw-r--r--Xi/ungrdevk.c2
-rw-r--r--Xi/xipassivegrab.c2
-rw-r--r--Xi/xiqueryversion.c53
-rw-r--r--configure.ac6
-rw-r--r--dix/cursor.c29
-rw-r--r--dix/devices.c4
-rw-r--r--dix/dispatch.c3
-rw-r--r--dix/dixmain.c3
-rw-r--r--dix/events.c101
-rw-r--r--dix/getevents.c2
-rw-r--r--dix/grabs.c21
-rw-r--r--dix/pixmap.c2
-rw-r--r--dix/touch.c117
-rw-r--r--dix/window.c15
-rw-r--r--fb/fbpixmap.c1
-rw-r--r--glx/glxdri.c2
-rw-r--r--hw/kdrive/src/kinput.c2
-rw-r--r--hw/xfree86/common/xf86platformBus.c8
-rw-r--r--hw/xfree86/modes/xf86Crtc.c34
-rw-r--r--hw/xfree86/modes/xf86Cursors.c4
-rw-r--r--hw/xfree86/ramdac/xf86Cursor.c28
-rw-r--r--include/cursor.h4
-rw-r--r--include/dixgrabs.h2
-rw-r--r--include/eventstr.h1
-rw-r--r--include/input.h2
-rw-r--r--include/inputstr.h4
-rw-r--r--render/animcur.c3
-rw-r--r--test/xi2/protocol-xiqueryversion.c60
-rw-r--r--xfixes/cursor.c6
32 files changed, 430 insertions, 256 deletions
diff --git a/Xext/saver.c b/Xext/saver.c
index 8de043f8e..fe81bc4d7 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -531,15 +531,16 @@ CreateSaverWindow(ScreenPtr pScreen)
mask |= CWBorderPixmap;
}
if (pAttr->pCursor) {
+ CursorPtr cursor;
if (!pWin->optional)
if (!MakeWindowOptional(pWin)) {
FreeResource(pWin->drawable.id, RT_NONE);
return FALSE;
}
- pAttr->pCursor->refcnt++;
+ cursor = RefCursor(pAttr->pCursor);
if (pWin->optional->cursor)
FreeCursor(pWin->optional->cursor, (Cursor) 0);
- pWin->optional->cursor = pAttr->pCursor;
+ pWin->optional->cursor = cursor;
pWin->cursorIsNone = FALSE;
CheckWindowOptionalNeed(pWin);
mask |= CWCursor;
@@ -1065,8 +1066,7 @@ ScreenSaverSetAttributes(ClientPtr client)
client->errorValue = cursorID;
goto PatchUp;
}
- pCursor->refcnt++;
- pAttr->pCursor = pCursor;
+ pAttr->pCursor = RefCursor(pCursor);
pAttr->mask &= ~CWCursor;
}
break;
diff --git a/Xi/exevents.c b/Xi/exevents.c
index d39cf89a7..067e6b3e5 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1036,47 +1036,22 @@ DeliverOneTouchEvent(ClientPtr client, DeviceIntPtr dev, TouchPointInfoPtr ti,
static void
ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
{
- int rc;
ClientPtr client;
XID error;
+ GrabPtr grab = ti->listeners[0].grab;
- rc = dixLookupClient(&client, ti->listeners[0].listener, serverClient,
- DixSendAccess);
- if (rc != Success) {
- ErrorF("[Xi] Failed to lookup early accepting client.\n");
- return;
- }
+ BUG_RETURN(ti->listeners[0].type != LISTENER_GRAB &&
+ ti->listeners[0].type != LISTENER_POINTER_GRAB);
+ BUG_RETURN(!grab);
+
+ client = rClient(grab);
if (TouchAcceptReject(client, dev, XIAcceptTouch, ti->client_id,
- ti->listeners[0].window->drawable.id, &error) !=
- Success)
+ ti->listeners[0].window->drawable.id, &error) != Success)
ErrorF("[Xi] Failed to accept touch grab after early acceptance.\n");
}
/**
- * Generate and deliver a TouchEnd event.
- *
- * @param dev The device to deliver the event for.
- * @param ti The touch point record to deliver the event for.
- * @param flags Internal event flags. The called does not need to provide
- * TOUCH_CLIENT_ID and TOUCH_POINTER_EMULATED, this function will ensure
- * they are set appropriately.
- * @param resource The client resource to deliver to, or 0 for all clients.
- */
-static void
-EmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
-{
- InternalEvent event;
-
- flags |= TOUCH_CLIENT_ID;
- if (ti->emulate_pointer)
- flags |= TOUCH_POINTER_EMULATED;
- TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource);
- GetDixTouchEnd(&event, dev, ti, flags);
- DeliverTouchEvents(dev, ti, &event, resource);
-}
-
-/**
* Find the oldest touch that still has a pointer emulation client.
*
* Pointer emulation can only be performed for the oldest touch. Otherwise, the
@@ -1126,31 +1101,42 @@ static void
TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
TouchOwnershipEvent *ev)
{
+ TouchListener *listener = &ti->listeners[0]; /* new owner */
+ int accepted_early = listener->state == LISTENER_EARLY_ACCEPT;
+
/* Deliver the ownership */
- if (ti->listeners[0].state == LISTENER_AWAITING_OWNER ||
- ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
+ if (listener->state == LISTENER_AWAITING_OWNER || accepted_early)
DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
- ti->listeners[0].listener);
- else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN) {
+ listener->listener);
+ else if (listener->state == LISTENER_AWAITING_BEGIN) {
/* We can't punt to a pointer listener unless all older pointer
* emulated touches have been seen already. */
- if ((ti->listeners[0].type == LISTENER_POINTER_GRAB ||
- ti->listeners[0].type == LISTENER_POINTER_REGULAR) &&
+ if ((listener->type == LISTENER_POINTER_GRAB ||
+ listener->type == LISTENER_POINTER_REGULAR) &&
ti != FindOldestPointerEmulatedTouch(dev))
return;
- TouchEventHistoryReplay(ti, dev, ti->listeners[0].listener);
+ TouchEventHistoryReplay(ti, dev, listener->listener);
}
- /* If we've just removed the last grab and the touch has physically
- * ended, send a TouchEnd event too and finalise the touch. */
- if (ti->num_listeners == 1 && ti->num_grabs == 0 && ti->pending_finish) {
- EmitTouchEnd(dev, ti, 0, 0);
- TouchEndTouch(dev, ti);
- return;
+ /* New owner has Begin/Update but not end. If touch is pending_finish,
+ * emulate the TouchEnd now */
+ if (ti->pending_finish) {
+ TouchEmitTouchEnd(dev, ti, 0, 0);
+
+ /* If the last owner is not a touch grab, finalise the touch, we
+ won't get more correspondence on this.
+ */
+ if (ti->num_listeners == 1 &&
+ (ti->num_grabs == 0 ||
+ listener->grab->grabtype != XI2 ||
+ !xi2mask_isset(listener->grab->xi2mask, dev, XI_TouchBegin))) {
+ TouchEndTouch(dev, ti);
+ return;
+ }
}
- if (ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
+ if (accepted_early)
ActivateEarlyAccept(dev, ti);
}
@@ -1194,7 +1180,7 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
for (i = 0; i < ti->num_listeners; i++) {
if (ti->listeners[i].listener == resource) {
if (ti->listeners[i].state != LISTENER_HAS_END)
- EmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
+ TouchEmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
break;
}
}
@@ -1237,16 +1223,20 @@ ProcessTouchOwnershipEvent(TouchOwnershipEvent *ev,
else if (ev->reason == XIAcceptTouch) {
int i;
- /* Go through the motions of ending the touch if the listener has
+
+ /* For pointer-emulated listeners that ungrabbed the active grab,
+ * the state was forced to LISTENER_HAS_END. Still go
+ * through the motions of ending the touch if the listener has
* already seen the end. This ensures that the touch record is ended in
- * the server. */
+ * the server.
+ */
if (ti->listeners[0].state == LISTENER_HAS_END)
- EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
+ TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
/* The touch owner has accepted the touch. Send TouchEnd events to
* everyone else, and truncate the list of listeners. */
for (i = 1; i < ti->num_listeners; i++)
- EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
+ TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
while (ti->num_listeners > 1)
TouchRemoveListener(ti, ti->listeners[1].listener);
@@ -1383,7 +1373,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
/* We don't deliver pointer events to non-owners */
if (!TouchResourceIsOwner(ti, listener->listener))
- return Success;
+ return !Success;
nevents = TouchConvertToPointerEvent(ev, &motion, &button);
BUG_RETURN_VAL(nevents == 0, BadValue);
@@ -1405,7 +1395,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
/* 'grab' is the passive grab, but if the grab isn't active,
* don't deliver */
if (!dev->deviceGrab.grab)
- return Success;
+ return !Success;
if (grab->ownerEvents) {
WindowPtr focus = NullWindow;
@@ -1415,7 +1405,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
}
if (!deliveries)
- DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
+ deliveries = DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
/* We must accept the touch sequence once a pointer listener has
* received one event past ButtonPress. */
@@ -1423,8 +1413,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
!(ev->device_event.flags & TOUCH_CLIENT_ID))
TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
- if (ev->any.type == ET_TouchEnd &&
- !(ev->device_event.flags & TOUCH_CLIENT_ID) &&
+ if (deliveries && ev->any.type == ET_TouchEnd &&
!dev->button->buttonsDown &&
dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) {
(*dev->deviceGrab.DeactivateGrab) (dev);
@@ -1443,8 +1432,11 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
*/
if (!devgrab && dev->deviceGrab.grab && dev->deviceGrab.implicitGrab) {
TouchListener *l;
+ GrabPtr g;
devgrab = dev->deviceGrab.grab;
+ g = AllocGrab(devgrab);
+ BUG_WARN(!g);
*dev->deviceGrab.sync.event = ev->device_event;
@@ -1453,8 +1445,8 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
* event selection. Thus, we update the last listener in the array.
*/
l = &ti->listeners[ti->num_listeners - 1];
- l->listener = devgrab->resource;
- l->grab = devgrab;
+ l->listener = g->resource;
+ l->grab = g;
//l->resource_type = RT_NONE;
if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
@@ -1545,7 +1537,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
touchid = ev->device_event.touchid;
- if (type == ET_TouchBegin) {
+ if (type == ET_TouchBegin && !(ev->device_event.flags & TOUCH_REPLAYING)) {
ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
emulate_pointer);
}
@@ -1612,7 +1604,9 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
* called after event type mutation. Touch end events are always processed
* in order to end touch records. */
/* FIXME: check this */
- if ((type == ET_TouchBegin && !TouchBuildSprite(dev, ti, ev)) ||
+ if ((type == ET_TouchBegin &&
+ !(ev->device_event.flags & TOUCH_REPLAYING) &&
+ !TouchBuildSprite(dev, ti, ev)) ||
(type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0))
return;
@@ -1620,7 +1614,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
/* WARNING: the event type may change to TouchUpdate in
* DeliverTouchEvents if a TouchEnd was delivered to a grabbing
* owner */
- DeliverTouchEvents(dev, ti, (InternalEvent *) ev, 0);
+ DeliverTouchEvents(dev, ti, ev, ev->device_event.resource);
if (ev->any.type == ET_TouchEnd)
TouchEndTouch(dev, ti);
@@ -1848,6 +1842,14 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
listener->type == LISTENER_POINTER_GRAB) {
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
grab, xi2mask);
+ if (rc == Success) {
+ listener->state = LISTENER_IS_OWNER;
+ /* async grabs cannot replay, so automatically accept this touch */
+ if (dev->deviceGrab.grab &&
+ dev->deviceGrab.fromPassiveGrab &&
+ dev->deviceGrab.grab->pointerMode == GrabModeAsync)
+ ActivateEarlyAccept(dev, ti);
+ }
goto out;
}
@@ -1865,7 +1867,7 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
if (has_ownershipmask)
TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
- if (!has_ownershipmask || listener->type == LISTENER_REGULAR)
+ if (listener->type == LISTENER_REGULAR)
state = LISTENER_HAS_ACCEPTED;
else
state = LISTENER_IS_OWNER;
@@ -1885,16 +1887,23 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
if (listener->type == LISTENER_POINTER_REGULAR ||
listener->type == LISTENER_POINTER_GRAB) {
- rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
- grab, xi2mask);
-
- if (ti->num_listeners > 1) {
- ev->any.type = ET_TouchUpdate;
- ev->device_event.flags |= TOUCH_PENDING_END;
- if (!(ev->device_event.flags & TOUCH_CLIENT_ID))
- ti->pending_finish = TRUE;
+ /* Note: If the active grab was ungrabbed, we already changed the
+ * state to LISTENER_HAS_END but still get here. So we mustn't
+ * actually send the event.
+ * This is part two of the hack in DeactivatePointerGrab
+ */
+ if (listener->state != LISTENER_HAS_END) {
+ rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
+ grab, xi2mask);
+
+ /* Once we send a TouchEnd to a legacy listener, we're already well
+ * past the accepting/rejecting stage (can only happen on
+ * GrabModeSync + replay. This listener now gets the end event,
+ * and we can continue.
+ */
+ if (rc == Success)
+ listener->state = LISTENER_HAS_END;
}
-
goto out;
}
@@ -1918,7 +1927,7 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
if ((ti->num_listeners > 1 ||
- listener->state != LISTENER_HAS_ACCEPTED) &&
+ (ti->num_grabs > 0 && listener->state != LISTENER_HAS_ACCEPTED)) &&
(ev->device_event.flags & (TOUCH_ACCEPT | TOUCH_REJECT)) == 0) {
ev->any.type = ET_TouchUpdate;
ev->device_event.flags |= TOUCH_PENDING_END;
@@ -2849,7 +2858,7 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
(deliveryMask & DeviceButtonGrabMask)) {
GrabPtr tempGrab;
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
if (!tempGrab)
return;
diff --git a/Xi/ungrdevb.c b/Xi/ungrdevb.c
index c4632fadc..b02510ea0 100644
--- a/Xi/ungrdevb.c
+++ b/Xi/ungrdevb.c
@@ -127,7 +127,7 @@ ProcXUngrabDeviceButton(ClientPtr client)
(stuff->modifiers & ~AllModifiersMask))
return BadValue;
- temporaryGrab = AllocGrab();
+ temporaryGrab = AllocGrab(NULL);
if (!temporaryGrab)
return BadAlloc;
diff --git a/Xi/ungrdevk.c b/Xi/ungrdevk.c
index 3273878d3..f98117168 100644
--- a/Xi/ungrdevk.c
+++ b/Xi/ungrdevk.c
@@ -134,7 +134,7 @@ ProcXUngrabDeviceKey(ClientPtr client)
(stuff->modifiers & ~AllModifiersMask))
return BadValue;
- temporaryGrab = AllocGrab();
+ temporaryGrab = AllocGrab(NULL);
if (!temporaryGrab)
return BadAlloc;
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 62a3a469f..eccec0ab8 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -307,7 +307,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
if (!tempGrab)
return BadAlloc;
diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c
index b807a53ce..c705f788f 100644
--- a/Xi/xiqueryversion.c
+++ b/Xi/xiqueryversion.c
@@ -70,25 +70,46 @@ ProcXIQueryVersion(ClientPtr client)
pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
+ if (version_compare(XIVersion.major_version, XIVersion.minor_version,
+ stuff->major_version, stuff->minor_version) > 0) {
+ major = stuff->major_version;
+ minor = stuff->minor_version;
+ } else {
+ major = XIVersion.major_version;
+ minor = XIVersion.minor_version;
+ }
+
if (pXIClient->major_version) {
- if (version_compare(stuff->major_version, stuff->minor_version,
- pXIClient->major_version, pXIClient->minor_version) < 0) {
- client->errorValue = stuff->major_version;
- return BadValue;
+
+ /* Check to see if the client has only ever asked
+ * for version 2.2 or higher
+ */
+ if (version_compare(major, minor, 2, 2) >= 0 &&
+ version_compare(pXIClient->major_version, pXIClient->minor_version, 2, 2) >= 0)
+ {
+
+ /* As of version 2.2, Peter promises to never again break
+ * backward compatibility, so we'll return the requested
+ * version to the client but leave the server internal
+ * version set to the highest requested value
+ */
+ if (version_compare(major, minor,
+ pXIClient->major_version, pXIClient->minor_version) > 0)
+ {
+ pXIClient->major_version = major;
+ pXIClient->minor_version = minor;
+ }
+ } else {
+ if (version_compare(major, minor,
+ pXIClient->major_version, pXIClient->minor_version) < 0) {
+
+ client->errorValue = stuff->major_version;
+ return BadValue;
+ }
+ major = pXIClient->major_version;
+ minor = pXIClient->minor_version;
}
- major = pXIClient->major_version;
- minor = pXIClient->minor_version;
} else {
- if (version_compare(XIVersion.major_version, XIVersion.minor_version,
- stuff->major_version, stuff->minor_version) > 0) {
- major = stuff->major_version;
- minor = stuff->minor_version;
- }
- else {
- major = XIVersion.major_version;
- minor = XIVersion.minor_version;
- }
-
pXIClient->major_version = major;
pXIClient->minor_version = minor;
}
diff --git a/configure.ac b/configure.ac
index e5fa027a6..398981f90 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,9 +26,9 @@ dnl
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.14.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-06-25"
-RELEASE_NAME="Act Abnormal"
+AC_INIT([xorg-server], 1.14.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-09-12"
+RELEASE_NAME="September Rain"
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
diff --git a/dix/cursor.c b/dix/cursor.c
index 1ee127ac5..cd8305c6c 100644
--- a/dix/cursor.c
+++ b/dix/cursor.c
@@ -114,9 +114,13 @@ FreeCursor(pointer value, XID cid)
ScreenPtr pscr;
DeviceIntPtr pDev = NULL; /* unused anyway */
- if (--pCurs->refcnt != 0)
+
+ UnrefCursor(pCurs);
+ if (CursorRefCount(pCurs) != 0)
return Success;
+ BUG_WARN(CursorRefCount(pCurs) < 0);
+
for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
pscr = screenInfo.screens[nscr];
(void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs);
@@ -127,6 +131,29 @@ FreeCursor(pointer value, XID cid)
return Success;
}
+CursorPtr
+RefCursor(CursorPtr cursor)
+{
+ if (cursor)
+ cursor->refcnt++;
+ return cursor;
+}
+
+CursorPtr
+UnrefCursor(CursorPtr cursor)
+{
+ if (cursor)
+ cursor->refcnt--;
+ return cursor;
+}
+
+int
+CursorRefCount(const CursorPtr cursor)
+{
+ return cursor ? cursor->refcnt : 0;
+}
+
+
/*
* We check for empty cursors so that we won't have to display them
*/
diff --git a/dix/devices.c b/dix/devices.c
index a0d545a96..9ef32bb24 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -281,7 +281,6 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
dev->deviceGrab.grabTime = currentTime;
dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
- dev->deviceGrab.activeGrab = AllocGrab();
dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
XkbSetExtension(dev, ProcessKeyboardEvent);
@@ -977,7 +976,8 @@ CloseDevice(DeviceIntPtr dev)
}
}
- FreeGrab(dev->deviceGrab.activeGrab);
+ if (dev->deviceGrab.grab)
+ FreeGrab(dev->deviceGrab.grab);
free(dev->deviceGrab.sync.event);
free(dev->config_info); /* Allocated in xf86ActivateDevice. */
free(dev->last.scroll);
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 2dd1a6764..9003d0c26 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3398,6 +3398,7 @@ CloseDownClient(ClientPtr client)
clientinfo.setup = (xConnSetup *) NULL;
CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
}
+ TouchListenerGone(client->clientAsMask);
FreeClientResources(client);
/* Disable client ID tracking. This must be done after
* ClientStateCallback. */
@@ -3942,7 +3943,6 @@ void
AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new)
{
assert(new->isGPU);
- assert(!new->current_master);
xorg_list_add(&new->output_head, &pScreen->output_slave_list);
new->current_master = pScreen;
}
@@ -3959,7 +3959,6 @@ void
AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new)
{
assert(new->isGPU);
- assert(!new->current_master);
xorg_list_add(&new->offload_head, &pScreen->offload_slave_list);
new->current_master = pScreen;
}
diff --git a/dix/dixmain.c b/dix/dixmain.c
index 7ab43788e..64746b019 100644
--- a/dix/dixmain.c
+++ b/dix/dixmain.c
@@ -207,6 +207,9 @@ dix_main(int argc, char *argv[], char *envp[])
ScreenPtr pScreen = screenInfo.gpuscreens[i];
if (!CreateScratchPixmapsForScreen(pScreen))
FatalError("failed to create scratch pixmaps");
+ if (pScreen->CreateScreenResources &&
+ !(*pScreen->CreateScreenResources) (pScreen))
+ FatalError("failed to create screen resources");
}
for (i = 0; i < screenInfo.numScreens; i++) {
diff --git a/dix/events.c b/dix/events.c
index 2682ecd46..c079f9756 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -931,8 +931,7 @@ ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
(*pScreen->DisplayCursor) (pDev, pScreen, cursor);
FreeCursor(pSprite->current, (Cursor) 0);
- pSprite->current = cursor;
- pSprite->current->refcnt++;
+ pSprite->current = RefCursor(cursor);
}
}
@@ -1424,21 +1423,24 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
for (i = 0; i < mouse->touch->num_touches; i++) {
TouchPointInfoPtr ti = mouse->touch->touches + i;
+ TouchListener *listener = &ti->listeners[0];
GrabPtr grab = mouse->deviceGrab.grab;
if (ti->active &&
- CLIENT_BITS(ti->listeners[0].listener) == grab->resource) {
- ti->listeners[0].listener = grab->resource;
- ti->listeners[0].level = grab->grabtype;
- ti->listeners[0].state = LISTENER_IS_OWNER;
- ti->listeners[0].window = grab->window;
+ CLIENT_BITS(listener->listener) == grab->resource) {
+ listener->listener = grab->resource;
+ listener->level = grab->grabtype;
+ listener->state = LISTENER_IS_OWNER;
+ listener->window = grab->window;
if (grab->grabtype == CORE || grab->grabtype == XI ||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
- ti->listeners[0].type = LISTENER_POINTER_GRAB;
+ listener->type = LISTENER_POINTER_GRAB;
else
- ti->listeners[0].type = LISTENER_GRAB;
- ti->listeners[0].grab = grab;
+ listener->type = LISTENER_GRAB;
+ if (listener->grab)
+ FreeGrab(listener->grab);
+ listener->grab = AllocGrab(grab);
}
}
}
@@ -1463,6 +1465,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
TimeStamp time, Bool autoGrab)
{
GrabInfoPtr grabinfo = &mouse->deviceGrab;
+ GrabPtr oldgrab = grabinfo->grab;
WindowPtr oldWin = (grabinfo->grab) ?
grabinfo->grab->window : mouse->spriteInfo->sprite->win;
Bool isPassive = autoGrab & ~ImplicitGrabMask;
@@ -1485,16 +1488,15 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
grabinfo->grabTime = syncEvents.time;
else
grabinfo->grabTime = time;
- if (grab->cursor)
- grab->cursor->refcnt++;
- CopyGrab(grabinfo->activeGrab, grab);
- grabinfo->grab = grabinfo->activeGrab;
+ grabinfo->grab = AllocGrab(grab);
grabinfo->fromPassiveGrab = isPassive;
grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
PostNewCursor(mouse);
UpdateTouchesForGrab(mouse);
CheckGrabForSyncs(mouse, (Bool) grab->pointerMode,
(Bool) grab->keyboardMode);
+ if (oldgrab)
+ FreeGrab(oldgrab);
}
/**
@@ -1518,13 +1520,20 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) {
TouchPointInfoPtr ti = mouse->touch->touches + i;
if (ti->active && TouchResourceIsOwner(ti, grab_resource)) {
+ int mode = XIRejectTouch;
/* Rejecting will generate a TouchEnd, but we must not
emulate a ButtonRelease here. So pretend the listener
already has the end event */
if (grab->grabtype == CORE || grab->grabtype == XI ||
- !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin))
+ !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin)) {
+ mode = XIAcceptTouch;
+ /* NOTE: we set the state here, but
+ * ProcessTouchOwnershipEvent() will still call
+ * TouchEmitTouchEnd for this listener. The other half of
+ * this hack is in DeliverTouchEndEvent */
ti->listeners[0].state = LISTENER_HAS_END;
- TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
+ }
+ TouchListenerAcceptReject(mouse, ti, 0, mode);
}
}
@@ -1544,13 +1553,13 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
if (grab->confineTo)
ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE);
PostNewCursor(mouse);
- if (grab->cursor)
- FreeCursor(grab->cursor, (Cursor) 0);
if (!wasImplicit && grab->grabtype == XI2)
ReattachToOldMaster(mouse);
ComputeFreezes();
+
+ FreeGrab(grab);
}
/**
@@ -1563,6 +1572,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
Bool passive)
{
GrabInfoPtr grabinfo = &keybd->deviceGrab;
+ GrabPtr oldgrab = grabinfo->grab;
WindowPtr oldWin;
/* slave devices need to float for the duration of the grab. */
@@ -1588,12 +1598,13 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
grabinfo->grabTime = syncEvents.time;
else
grabinfo->grabTime = time;
- CopyGrab(grabinfo->activeGrab, grab);
- grabinfo->grab = grabinfo->activeGrab;
+ grabinfo->grab = AllocGrab(grab);
grabinfo->fromPassiveGrab = passive;
grabinfo->implicitGrab = passive & ImplicitGrabMask;
CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode,
(Bool) grab->pointerMode);
+ if (oldgrab)
+ FreeGrab(oldgrab);
}
/**
@@ -1635,6 +1646,8 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
ReattachToOldMaster(keybd);
ComputeFreezes();
+
+ FreeGrab(grab);
}
void
@@ -1739,6 +1752,16 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
}
break;
}
+
+ /* We've unfrozen the grab. If the grab was a touch grab, we're now the
+ * owner and expected to accept/reject it. Reject == ReplayPointer which
+ * we've handled in ComputeFreezes() (during DeactivateGrab) above,
+ * anything else is accept.
+ */
+ if (newState != NOT_GRABBED /* Replay */ &&
+ IsTouchEvent((InternalEvent*)grabinfo->sync.event)) {
+ TouchAcceptAndEnd(thisDev, grabinfo->sync.event->touchid);
+ }
}
/**
@@ -1971,7 +1994,7 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
else
return FALSE;
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
if (!tempGrab)
return FALSE;
tempGrab->next = NULL;
@@ -3191,11 +3214,10 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
pSprite->pEnqueueScreen = screenInfo.screens[0];
pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
}
- if (pCursor)
- pCursor->refcnt++;
+ pCursor = RefCursor(pCursor);
if (pSprite->current)
FreeCursor(pSprite->current, None);
- pSprite->current = pCursor;
+ pSprite->current = RefCursor(pCursor);
if (pScreen) {
(*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current);
@@ -3274,9 +3296,7 @@ UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen)
pSprite->hotLimits.x2 = pScreen->width;
pSprite->hotLimits.y2 = pScreen->height;
pSprite->win = win;
- pCursor = wCursor(win);
- if (pCursor)
- pCursor->refcnt++;
+ pCursor = RefCursor(wCursor(win));
if (pSprite->current)
FreeCursor(pSprite->current, 0);
pSprite->current = pCursor;
@@ -3878,7 +3898,7 @@ CheckPassiveGrabsOnWindow(WindowPtr pWin,
if (!grab)
return NULL;
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
/* Fill out the grab details, but leave the type for later before
* comparing */
@@ -4836,7 +4856,6 @@ ProcGrabPointer(ClientPtr client)
GrabPtr grab;
GrabMask mask;
WindowPtr confineTo;
- CursorPtr oldCursor;
BYTE status;
REQUEST(xGrabPointerReq);
@@ -4859,15 +4878,10 @@ ProcGrabPointer(ClientPtr client)
return rc;
}
- oldCursor = NullCursor;
grab = device->deviceGrab.grab;
- if (grab) {
- if (grab->confineTo && !confineTo)
- ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE,
- FALSE);
- oldCursor = grab->cursor;
- }
+ if (grab && grab->confineTo && !confineTo)
+ ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE, FALSE);
mask.core = stuff->eventMask;
@@ -4877,9 +4891,6 @@ ProcGrabPointer(ClientPtr client)
if (rc != Success)
return rc;
- if (oldCursor && status == GrabSuccess)
- FreeCursor(oldCursor, (Cursor) 0);
-
rep = (xGrabPointerReply) {
.type = X_Reply,
.status = status,
@@ -4935,9 +4946,7 @@ ProcChangeActivePointerGrab(ClientPtr client)
(CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
return Success;
oldCursor = grab->cursor;
- grab->cursor = newCursor;
- if (newCursor)
- newCursor->refcnt++;
+ grab->cursor = RefCursor(newCursor);
PostNewCursor(device);
if (oldCursor)
FreeCursor(oldCursor, (Cursor) 0);
@@ -5067,7 +5076,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
else {
GrabPtr tempGrab;
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
tempGrab->next = NULL;
tempGrab->window = pWin;
@@ -5082,7 +5091,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
else
xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
tempGrab->device = dev;
- tempGrab->cursor = cursor;
+ tempGrab->cursor = RefCursor(cursor);
tempGrab->confineTo = confineTo;
tempGrab->grabtype = grabtype;
(*grabInfo->ActivateGrab) (dev, tempGrab, time, FALSE);
@@ -5423,7 +5432,7 @@ ProcUngrabKey(ClientPtr client)
client->errorValue = stuff->modifiers;
return BadValue;
}
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
if (!tempGrab)
return BadAlloc;
tempGrab->resource = client->clientAsMask;
@@ -5617,7 +5626,7 @@ ProcUngrabButton(ClientPtr client)
ptr = PickPointer(client);
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
if (!tempGrab)
return BadAlloc;
tempGrab->resource = client->clientAsMask;
diff --git a/dix/getevents.c b/dix/getevents.c
index dfe465254..dd1b2534a 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -239,7 +239,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent *event, ValuatorMask *mask)
SetBit(event->valuators.mode, i);
event->valuators.data[i] = valuator_mask_get_double(mask, i);
}
- else if (valuator_get_mode(dev, i) == Absolute)
+ else
event->valuators.data[i] = dev->valuator->axisVal[i];
}
}
diff --git a/dix/grabs.c b/dix/grabs.c
index 3b02352df..a03897af4 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -189,7 +189,7 @@ UngrabAllDevices(Bool kill_client)
}
GrabPtr
-AllocGrab(void)
+AllocGrab(const GrabPtr src)
{
GrabPtr grab = calloc(1, sizeof(GrabRec));
@@ -201,6 +201,12 @@ AllocGrab(void)
}
}
+ if (src && !CopyGrab(grab, src)) {
+ free(grab->xi2mask);
+ free(grab);
+ grab = NULL;
+ }
+
return grab;
}
@@ -213,7 +219,7 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
{
GrabPtr grab;
- grab = AllocGrab();
+ grab = AllocGrab(NULL);
if (!grab)
return (GrabPtr) NULL;
grab->resource = FakeClientID(client);
@@ -235,13 +241,11 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
grab->detail.exact = keybut;
grab->detail.pMask = NULL;
grab->confineTo = confineTo;
- grab->cursor = cursor;
+ grab->cursor = RefCursor(cursor);
grab->next = NULL;
if (grabtype == XI2)
xi2mask_merge(grab->xi2mask, mask->xi2mask);
- if (cursor)
- cursor->refcnt++;
return grab;
}
@@ -249,8 +253,7 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
void
FreeGrab(GrabPtr pGrab)
{
- if (pGrab->grabtype == XI2 && pGrab->type == XI_TouchBegin)
- TouchListenerGone(pGrab->resource);
+ BUG_RETURN(!pGrab);
free(pGrab->modifiersDetail.pMask);
free(pGrab->detail.pMask);
@@ -269,9 +272,6 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
Mask *details_mask = NULL;
XI2Mask *xi2mask;
- if (src->cursor)
- src->cursor->refcnt++;
-
if (src->modifiersDetail.pMask) {
int len = MasksPerDetailMask * sizeof(Mask);
@@ -309,6 +309,7 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
dst->modifiersDetail.pMask = mdetails_mask;
dst->detail.pMask = details_mask;
dst->xi2mask = xi2mask;
+ dst->cursor = RefCursor(src->cursor);
xi2mask_merge(dst->xi2mask, src->xi2mask);
diff --git a/dix/pixmap.c b/dix/pixmap.c
index 241881262..fe9214739 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -243,6 +243,8 @@ Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region)
}
dst = dirty->slave_dst->master_pixmap;
+ if (!dst)
+ dst = dirty->slave_dst;
RegionTranslate(dirty_region, -dirty->x, -dirty->y);
n = RegionNumRects(dirty_region);
diff --git a/dix/touch.c b/dix/touch.c
index 3027bbbf2..a7ea213ba 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -263,6 +263,7 @@ void
TouchFreeTouchPoint(DeviceIntPtr device, int index)
{
TouchPointInfoPtr ti;
+ int i;
if (!device->touch || index >= device->touch->num_touches)
return;
@@ -271,6 +272,9 @@ TouchFreeTouchPoint(DeviceIntPtr device, int index)
if (ti->active)
TouchEndTouch(device, ti);
+ for (i = 0; i < ti->num_listeners; i++)
+ TouchRemoveListener(ti, ti->listeners[0].listener);
+
valuator_mask_free(&ti->valuators);
free(ti->sprite.spriteTrace);
ti->sprite.spriteTrace = NULL;
@@ -365,6 +369,8 @@ TouchBeginTouch(DeviceIntPtr dev, int sourceid, uint32_t touchid,
void
TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
{
+ int i;
+
if (ti->emulate_pointer) {
GrabPtr grab;
@@ -376,6 +382,9 @@ TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
}
}
+ for (i = 0; i < ti->num_listeners; i++)
+ TouchRemoveListener(ti, ti->listeners[0].listener);
+
ti->active = FALSE;
ti->pending_finish = FALSE;
ti->sprite.spriteTraceGood = 0;
@@ -474,7 +483,21 @@ TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource)
DeviceEvent *ev = &ti->history[i];
ev->flags |= TOUCH_REPLAYING;
- DeliverTouchEvents(dev, ti, (InternalEvent *) ev, resource);
+ ev->resource = resource;
+ /* FIXME:
+ We're replaying ti->history which contains the TouchBegin +
+ all TouchUpdates for ti. This needs to be passed on to the next
+ listener. If that is a touch listener, everything is dandy.
+ If the TouchBegin however triggers a sync passive grab, the
+ TouchUpdate events must be sent to EnqueueEvent so the events end
+ up in syncEvents.pending to be forwarded correctly in a
+ subsequent ComputeFreeze().
+
+ However, if we just send them to EnqueueEvent the sync'ing device
+ prevents handling of touch events for ownership listeners who
+ want the events right here, right now.
+ */
+ dev->public.processInputProc((InternalEvent*)ev, dev);
}
}
@@ -678,15 +701,23 @@ void
TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
enum InputLevel level, enum TouchListenerType type,
enum TouchListenerState state, WindowPtr window,
- GrabPtr grab)
+ const GrabPtr grab)
{
+ GrabPtr g = NULL;
+
+ /* We need a copy of the grab, not the grab itself since that may be
+ * deleted by a UngrabButton request and leaves us with a dangling
+ * pointer */
+ if (grab)
+ g = AllocGrab(grab);
+
ti->listeners[ti->num_listeners].listener = resource;
ti->listeners[ti->num_listeners].resource_type = resource_type;
ti->listeners[ti->num_listeners].level = level;
ti->listeners[ti->num_listeners].state = state;
ti->listeners[ti->num_listeners].type = type;
ti->listeners[ti->num_listeners].window = window;
- ti->listeners[ti->num_listeners].grab = grab;
+ ti->listeners[ti->num_listeners].grab = g;
if (grab)
ti->num_grabs++;
ti->num_listeners++;
@@ -704,21 +735,25 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
int i;
for (i = 0; i < ti->num_listeners; i++) {
- if (ti->listeners[i].listener == resource) {
- int j;
+ int j;
+ TouchListener *listener = &ti->listeners[i];
- if (ti->listeners[i].grab) {
- ti->listeners[i].grab = NULL;
- ti->num_grabs--;
- }
+ if (listener->listener != resource)
+ continue;
- for (j = i; j < ti->num_listeners - 1; j++)
- ti->listeners[j] = ti->listeners[j + 1];
- ti->num_listeners--;
- ti->listeners[ti->num_listeners].listener = 0;
- ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN;
- return TRUE;
+ if (listener->grab) {
+ FreeGrab(listener->grab);
+ listener->grab = NULL;
+ ti->num_grabs--;
}
+
+ for (j = i; j < ti->num_listeners - 1; j++)
+ ti->listeners[j] = ti->listeners[j + 1];
+ ti->num_listeners--;
+ ti->listeners[ti->num_listeners].listener = 0;
+ ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN;
+
+ return TRUE;
}
return FALSE;
}
@@ -860,8 +895,7 @@ TouchAddActiveGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
if (!ti->emulate_pointer &&
grab->grabtype == XI2 &&
- (grab->type != XI_TouchBegin && grab->type != XI_TouchEnd &&
- grab->type != XI_TouchUpdate))
+ !xi2mask_isset(grab->xi2mask, dev, XI_TouchBegin))
return;
TouchAddGrabListener(dev, ti, ev, grab);
@@ -874,7 +908,7 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev)
SpritePtr sprite = &ti->sprite;
WindowPtr win;
- if (dev->deviceGrab.grab)
+ if (dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab)
TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab);
/* We set up an active touch listener for existing touches, but not any
@@ -954,11 +988,11 @@ TouchListenerGone(XID resource)
continue;
for (j = 0; j < ti->num_listeners; j++) {
- if (ti->listeners[j].listener != resource)
+ if (CLIENT_BITS(ti->listeners[j].listener) != resource)
continue;
nev = GetTouchOwnershipEvents(events, dev, ti, XIRejectTouch,
- resource, 0);
+ ti->listeners[j].listener, 0);
for (k = 0; k < nev; k++)
mieqProcessDeviceEvent(dev, events + k, NULL);
@@ -1061,3 +1095,46 @@ TouchEndPhysicallyActiveTouches(DeviceIntPtr dev)
FreeEventList(eventlist, GetMaximumEventsNum());
}
+
+/**
+ * Generate and deliver a TouchEnd event.
+ *
+ * @param dev The device to deliver the event for.
+ * @param ti The touch point record to deliver the event for.
+ * @param flags Internal event flags. The called does not need to provide
+ * TOUCH_CLIENT_ID and TOUCH_POINTER_EMULATED, this function will ensure
+ * they are set appropriately.
+ * @param resource The client resource to deliver to, or 0 for all clients.
+ */
+void
+TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
+{
+ InternalEvent event;
+
+ /* We're not processing a touch end for a frozen device */
+ if (dev->deviceGrab.sync.frozen)
+ return;
+
+ flags |= TOUCH_CLIENT_ID;
+ if (ti->emulate_pointer)
+ flags |= TOUCH_POINTER_EMULATED;
+ TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource);
+ GetDixTouchEnd(&event, dev, ti, flags);
+ DeliverTouchEvents(dev, ti, &event, resource);
+ if (ti->num_grabs == 0)
+ UpdateDeviceState(dev, &event.device_event);
+}
+
+void
+TouchAcceptAndEnd(DeviceIntPtr dev, int touchid)
+{
+ TouchPointInfoPtr ti = TouchFindByClientID(dev, touchid);
+ if (!ti)
+ return;
+
+ TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
+ if (ti->pending_finish)
+ TouchEmitTouchEnd(dev, ti, 0, 0);
+ if (ti->num_listeners <= 1)
+ TouchEndTouch(dev, ti);
+}
diff --git a/dix/window.c b/dix/window.c
index 944e6174b..7738aa145 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -546,8 +546,7 @@ InitRootWindow(WindowPtr pWin)
(*pScreen->PositionWindow) (pWin, 0, 0);
pWin->cursorIsNone = FALSE;
- pWin->optional->cursor = rootCursor;
- rootCursor->refcnt++;
+ pWin->optional->cursor = RefCursor(rootCursor);
if (party_like_its_1989) {
MakeRootTile(pWin);
@@ -1415,8 +1414,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
else if (pWin->parent && pCursor == wCursor(pWin->parent))
checkOptional = TRUE;
pOldCursor = pWin->optional->cursor;
- pWin->optional->cursor = pCursor;
- pCursor->refcnt++;
+ pWin->optional->cursor = RefCursor(pCursor);
pWin->cursorIsNone = FALSE;
/*
* check on any children now matching the new cursor
@@ -3320,8 +3318,7 @@ MakeWindowOptional(WindowPtr pWin)
parentOptional = FindWindowWithOptional(pWin)->optional;
optional->visual = parentOptional->visual;
if (!pWin->cursorIsNone) {
- optional->cursor = parentOptional->cursor;
- optional->cursor->refcnt++;
+ optional->cursor = RefCursor(parentOptional->cursor);
}
else {
optional->cursor = None;
@@ -3409,8 +3406,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor))
pNode->cursor = None;
else {
- pNode->cursor = pCursor;
- pCursor->refcnt++;
+ pNode->cursor = RefCursor(pCursor);
}
pNode = pPrev = NULL;
@@ -3418,8 +3414,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) {
if (pNode->cursor == None) { /* inherited from parent */
- pNode->cursor = pOldCursor;
- pOldCursor->refcnt++;
+ pNode->cursor = RefCursor(pOldCursor);
}
else if (pNode->cursor == pCursor) {
pNode->cursor = None;
diff --git a/fb/fbpixmap.c b/fb/fbpixmap.c
index fbcdca99c..0824b64bb 100644
--- a/fb/fbpixmap.c
+++ b/fb/fbpixmap.c
@@ -67,6 +67,7 @@ fbCreatePixmapBpp(ScreenPtr pScreen, int width, int height, int depth, int bpp,
pPixmap->devKind = paddedWidth;
pPixmap->refcnt = 1;
pPixmap->devPrivate.ptr = (pointer) ((char *) pPixmap + base + adjust);
+ pPixmap->master_pixmap = NULL;
#ifdef FB_DEBUG
pPixmap->devPrivate.ptr =
diff --git a/glx/glxdri.c b/glx/glxdri.c
index 5891a68c5..41424afdd 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -971,6 +971,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
size_t buffer_size;
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ framebuffer.base = NULL;
+
if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
!DRIQueryDirectRenderingCapable(pScreen, &isCapable) || !isCapable) {
LogMessage(X_INFO,
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index b1068bbee..09aae442b 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -221,7 +221,7 @@ KdUnregisterFd(void *closure, int fd, Bool do_close)
if (do_close)
close(kdInputFds[i].fd);
kdNumInputFds--;
- for (j = i; j < kdNumInputFds; j++)
+ for (j = i; j < (kdNumInputFds - 1); j++)
kdInputFds[j] = kdInputFds[j + 1];
break;
}
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 9034dad5e..db831a883 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -454,6 +454,14 @@ xf86platformAddDevice(int index)
CreateScratchPixmapsForScreen(xf86GPUScreens[i]->pScreen);
+ if (xf86GPUScreens[i]->pScreen->CreateScreenResources &&
+ !(*xf86GPUScreens[i]->pScreen->CreateScreenResources) (xf86GPUScreens[i]->pScreen)) {
+ RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
+ xf86DeleteScreen(xf86GPUScreens[i]);
+ xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
+ xf86NumGPUScreens = old_screens;
+ return -1;
+ }
/* attach unbound to 0 protocol screen */
AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 7d55f606e..989595fee 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1908,6 +1908,14 @@ xf86CollectEnabledOutputs(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
Bool any_enabled = FALSE;
int o;
+ /*
+ * Don't bother enabling outputs on GPU screens: a client needs to attach
+ * it to a source provider before setting a mode that scans out a shared
+ * pixmap.
+ */
+ if (scrn->is_gpu)
+ return FALSE;
+
for (o = 0; o < config->num_output; o++)
any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], TRUE);
@@ -2360,11 +2368,11 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
config->debug_modes = xf86ReturnOptValBool(config->options,
OPTION_MODEDEBUG, FALSE);
- if (scrn->display->virtualX)
+ if (scrn->display->virtualX && !scrn->is_gpu)
width = scrn->display->virtualX;
else
width = config->maxWidth;
- if (scrn->display->virtualY)
+ if (scrn->display->virtualY && !scrn->is_gpu)
height = scrn->display->virtualY;
else
height = config->maxHeight;
@@ -2377,9 +2385,11 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
ret = xf86CollectEnabledOutputs(scrn, config, enabled);
if (ret == FALSE && canGrow) {
- xf86DrvMsg(i, X_WARNING,
- "Unable to find connected outputs - setting %dx%d initial framebuffer\n",
- NO_OUTPUT_DEFAULT_WIDTH, NO_OUTPUT_DEFAULT_HEIGHT);
+ if (!scrn->is_gpu)
+ xf86DrvMsg(i, X_WARNING,
+ "Unable to find connected outputs - setting %dx%d "
+ "initial framebuffer\n",
+ NO_OUTPUT_DEFAULT_WIDTH, NO_OUTPUT_DEFAULT_HEIGHT);
have_outputs = FALSE;
}
else {
@@ -2428,8 +2438,10 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
/* XXX override xf86 common frame computation code */
- scrn->display->frameX0 = 0;
- scrn->display->frameY0 = 0;
+ if (!scrn->is_gpu) {
+ scrn->display->frameX0 = 0;
+ scrn->display->frameY0 = 0;
+ }
for (c = 0; c < config->num_crtc; c++) {
xf86CrtcPtr crtc = config->crtc[c];
@@ -2477,7 +2489,7 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
}
}
- if (scrn->display->virtualX == 0) {
+ if (scrn->display->virtualX == 0 || scrn->is_gpu) {
/*
* Expand virtual size to cover the current config and potential mode
* switches, if the driver can't enlarge the screen later.
@@ -2492,8 +2504,10 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
}
}
- scrn->display->virtualX = width;
- scrn->display->virtualY = height;
+ if (!scrn->is_gpu) {
+ scrn->display->virtualX = width;
+ scrn->display->virtualY = height;
+ }
}
if (width > scrn->virtualX)
diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index 634ee3fe0..2b0db3492 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -481,7 +481,7 @@ xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
- ++cursor->refcnt;
+ cursor = RefCursor(cursor);
if (xf86_config->cursor)
FreeCursor(xf86_config->cursor, None);
xf86_config->cursor = cursor;
@@ -500,7 +500,7 @@ xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
- ++cursor->refcnt;
+ cursor = RefCursor(cursor);
if (xf86_config->cursor)
FreeCursor(xf86_config->cursor, None);
xf86_config->cursor = cursor;
diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 8d48a7542..f30bd33c7 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -272,7 +272,7 @@ xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
xf86CursorScreenKey);
- if (pCurs->refcnt <= 1)
+ if (CursorRefCount(pCurs) <= 1)
dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
NULL);
@@ -286,7 +286,7 @@ xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
xf86CursorScreenKey);
- if (pCurs->refcnt <= 1) {
+ if (CursorRefCount(pCurs) <= 1) {
free(dixLookupScreenPrivate
(&pCurs->devPrivates, CursorScreenKey, pScreen));
dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
@@ -323,37 +323,37 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
/* only update for VCP, otherwise we get cursor jumps when removing a
sprite. The second cursor is never HW rendered anyway. */
if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) {
- pCurs->refcnt++;
+ CursorPtr cursor = RefCursor(pCurs);
if (ScreenPriv->CurrentCursor)
FreeCursor(ScreenPriv->CurrentCursor, None);
- ScreenPriv->CurrentCursor = pCurs;
+ ScreenPriv->CurrentCursor = cursor;
ScreenPriv->x = x;
ScreenPriv->y = y;
ScreenPriv->CursorToRestore = NULL;
- ScreenPriv->HotX = pCurs->bits->xhot;
- ScreenPriv->HotY = pCurs->bits->yhot;
+ ScreenPriv->HotX = cursor->bits->xhot;
+ ScreenPriv->HotY = cursor->bits->yhot;
if (!infoPtr->pScrn->vtSema)
- ScreenPriv->SavedCursor = pCurs;
+ ScreenPriv->SavedCursor = cursor;
if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) &&
(ScreenPriv->ForceHWCursorCount ||
((
#ifdef ARGB_CURSOR
- pCurs->bits->argb &&
+ cursor->bits->argb &&
infoPtr->UseHWCursorARGB &&
- (*infoPtr->UseHWCursorARGB)(pScreen, pCurs)) ||
- (pCurs->bits->argb == 0 &&
+ (*infoPtr->UseHWCursorARGB)(pScreen, cursor)) ||
+ (cursor->bits->argb == 0 &&
#endif
- (pCurs->bits->height <= infoPtr->MaxHeight) &&
- (pCurs->bits->width <= infoPtr->MaxWidth) &&
- (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, pCurs)))))) {
+ (cursor->bits->height <= infoPtr->MaxHeight) &&
+ (cursor->bits->width <= infoPtr->MaxWidth) &&
+ (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, cursor)))))) {
if (ScreenPriv->SWCursor) /* remove the SW cursor */
(*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
NullCursor, x, y);
- xf86SetCursor(pScreen, pCurs, x, y);
+ xf86SetCursor(pScreen, cursor, x, y);
ScreenPriv->SWCursor = FALSE;
ScreenPriv->isUp = TRUE;
diff --git a/include/cursor.h b/include/cursor.h
index 082325123..89a650fc5 100644
--- a/include/cursor.h
+++ b/include/cursor.h
@@ -71,6 +71,10 @@ extern _X_EXPORT CursorPtr rootCursor;
extern _X_EXPORT int FreeCursor(pointer /*pCurs */ ,
XID /*cid */ );
+extern _X_EXPORT CursorPtr RefCursor(CursorPtr /* cursor */);
+extern _X_EXPORT CursorPtr UnrefCursor(CursorPtr /* cursor */);
+extern _X_EXPORT int CursorRefCount(const CursorPtr /* cursor */);
+
extern _X_EXPORT int AllocARGBCursor(unsigned char * /*psrcbits */ ,
unsigned char * /*pmaskbits */ ,
CARD32 * /*argb */ ,
diff --git a/include/dixgrabs.h b/include/dixgrabs.h
index eccec77f8..ca3c95be7 100644
--- a/include/dixgrabs.h
+++ b/include/dixgrabs.h
@@ -31,7 +31,7 @@ struct _GrabParameters;
extern void PrintDeviceGrabInfo(DeviceIntPtr dev);
extern void UngrabAllDevices(Bool kill_client);
-extern GrabPtr AllocGrab(void);
+extern GrabPtr AllocGrab(const GrabPtr src);
extern void FreeGrab(GrabPtr grab);
extern Bool CopyGrab(GrabPtr dst, const GrabPtr src);
diff --git a/include/eventstr.h b/include/eventstr.h
index 5c1adc459..3950584d5 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -123,6 +123,7 @@ struct _DeviceEvent {
int corestate; /**< Core key/button state BEFORE the event */
int key_repeat; /**< Internally-generated key repeat event */
uint32_t flags; /**< Flags to be copied into the generated event */
+ uint32_t resource; /**< Touch event resource, only for TOUCH_REPLAYING */
};
/**
diff --git a/include/input.h b/include/input.h
index 5c65597e4..7eed60bcf 100644
--- a/include/input.h
+++ b/include/input.h
@@ -590,6 +590,8 @@ extern int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode,
extern void TouchEndPhysicallyActiveTouches(DeviceIntPtr dev);
extern void TouchDeliverDeviceClassesChangedEvent(TouchPointInfoPtr ti,
Time time, XID resource);
+extern void TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource);
+extern void TouchAcceptAndEnd(DeviceIntPtr dev, int touchid);
/* misc event helpers */
extern Mask GetEventMask(DeviceIntPtr dev, xEvent *ev, InputClientsPtr clients);
diff --git a/include/inputstr.h b/include/inputstr.h
index de96faeda..2da72c1ec 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -195,7 +195,7 @@ typedef struct _GrabRec {
unsigned keyboardMode:1;
unsigned pointerMode:1;
enum InputLevel grabtype;
- CARD8 type; /* event type */
+ CARD8 type; /* event type for passive grabs, 0 for active grabs */
DetailRec modifiersDetail;
DeviceIntPtr modifierDevice;
DetailRec detail; /* key or button */
@@ -485,7 +485,7 @@ typedef struct _GrabInfoRec {
TimeStamp grabTime;
Bool fromPassiveGrab; /* true if from passive grab */
Bool implicitGrab; /* implicit from ButtonPress */
- GrabPtr activeGrab;
+ GrabPtr unused; /* Kept for ABI stability, remove soon */
GrabPtr grab;
CARD8 activatingKey;
void (*ActivateGrab) (DeviceIntPtr /*device */ ,
diff --git a/render/animcur.c b/render/animcur.c
index 9cbba83fa..038c5b9be 100644
--- a/render/animcur.c
+++ b/render/animcur.c
@@ -383,8 +383,7 @@ AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
ac->elts = (AnimCurElt *) (ac + 1);
for (i = 0; i < ncursor; i++) {
- cursors[i]->refcnt++;
- ac->elts[i].pCursor = cursors[i];
+ ac->elts[i].pCursor = RefCursor(cursors[i]);
ac->elts[i].delay = deltas[i];
}
diff --git a/test/xi2/protocol-xiqueryversion.c b/test/xi2/protocol-xiqueryversion.c
index aff023754..ed75c89db 100644
--- a/test/xi2/protocol-xiqueryversion.c
+++ b/test/xi2/protocol-xiqueryversion.c
@@ -44,8 +44,8 @@
#include "extinit.h" /* for XInputExtensionInit */
#include "scrnintstr.h"
#include "xiqueryversion.h"
-
#include "protocol-common.h"
+#include "exglobals.h"
extern XExtensionVersion XIVersion;
@@ -54,8 +54,8 @@ struct test_data {
int minor_client;
int major_server;
int minor_server;
- int major_cached;
- int minor_cached;
+ int major_expected;
+ int minor_expected;
};
static void
@@ -93,13 +93,8 @@ reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *closu
reply_check_defaults(rep, len, XIQueryVersion);
assert(rep->length == 0);
- if (versions->major_cached == -1) {
- versions->major_cached = rep->major_version;
- versions->minor_cached = rep->minor_version;
- }
-
- assert(versions->major_cached == rep->major_version);
- assert(versions->minor_cached == rep->minor_version);
+ assert(versions->major_expected == rep->major_version);
+ assert(versions->minor_expected == rep->minor_version);
}
/**
@@ -199,6 +194,7 @@ test_XIQueryVersion_multiple(void)
{
xXIQueryVersionReq request;
ClientRec client;
+ XIClientPtr pXIClient;
struct test_data versions;
int rc;
@@ -213,28 +209,26 @@ test_XIQueryVersion_multiple(void)
userdata = (void *) &versions;
/* run 1 */
- versions.major_cached = -1;
- versions.minor_cached = -1;
- /* client is lower than server, noncached */
- request.major_version = 2;
- request.minor_version = 1;
+ /* client is lower than server, nonexpected */
+ versions.major_expected = request.major_version = 2;
+ versions.minor_expected = request.minor_version = 1;
rc = ProcXIQueryVersion(&client);
assert(rc == Success);
- /* client is higher than server, cached */
+ /* client is higher than server, no change */
request.major_version = 2;
request.minor_version = 3;
rc = ProcXIQueryVersion(&client);
assert(rc == Success);
- /* client is equal, cached */
+ /* client tries to set higher version, stays same */
request.major_version = 2;
request.minor_version = 2;
rc = ProcXIQueryVersion(&client);
assert(rc == Success);
- /* client is low than cached */
+ /* client tries to set lower version, no change */
request.major_version = 2;
request.minor_version = 0;
rc = ProcXIQueryVersion(&client);
@@ -243,20 +237,24 @@ test_XIQueryVersion_multiple(void)
/* run 2 */
client = init_client(request.length, &request);
XIVersion.major_version = 2;
- XIVersion.minor_version = 2;
- versions.major_cached = -1;
- versions.minor_cached = -1;
+ XIVersion.minor_version = 3;
- request.major_version = 2;
- request.minor_version = 2;
+ versions.major_expected = request.major_version = 2;
+ versions.minor_expected = request.minor_version = 2;
rc = ProcXIQueryVersion(&client);
assert(rc == Success);
+ /* client bumps version from 2.2 to 2.3 */
request.major_version = 2;
- request.minor_version = 3;
+ versions.minor_expected = request.minor_version = 3;
rc = ProcXIQueryVersion(&client);
assert(rc == Success);
+ /* real version is changed, too! */
+ pXIClient = dixLookupPrivate(&client.devPrivates, XIClientPrivateKey);
+ assert(pXIClient->minor_version == 3);
+
+ /* client tries to set lower version, no change */
request.major_version = 2;
request.minor_version = 1;
rc = ProcXIQueryVersion(&client);
@@ -265,20 +263,22 @@ test_XIQueryVersion_multiple(void)
/* run 3 */
client = init_client(request.length, &request);
XIVersion.major_version = 2;
- XIVersion.minor_version = 2;
- versions.major_cached = -1;
- versions.minor_cached = -1;
+ XIVersion.minor_version = 3;
- request.major_version = 2;
- request.minor_version = 3;
+ versions.major_expected = request.major_version = 2;
+ versions.minor_expected = request.minor_version = 3;
rc = ProcXIQueryVersion(&client);
assert(rc == Success);
request.major_version = 2;
- request.minor_version = 2;
+ versions.minor_expected = request.minor_version = 2;
rc = ProcXIQueryVersion(&client);
assert(rc == Success);
+ /* but real client version must not be lowered */
+ pXIClient = dixLookupPrivate(&client.devPrivates, XIClientPrivateKey);
+ assert(pXIClient->minor_version == 3);
+
request.major_version = 2;
request.minor_version = 1;
rc = ProcXIQueryVersion(&client);
diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index 568e717fa..cc6e059b9 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -619,12 +619,12 @@ ReplaceCursorLookup(pointer value, XID id, pointer closure)
}
if (pCursor && pCursor != rcl->pNew) {
if ((*rcl->testCursor) (pCursor, rcl->closure)) {
- rcl->pNew->refcnt++;
+ CursorPtr curs = RefCursor(rcl->pNew);
/* either redirect reference or update resource database */
if (pCursorRef)
- *pCursorRef = rcl->pNew;
+ *pCursorRef = curs;
else
- ChangeResourceValue(id, RT_CURSOR, rcl->pNew);
+ ChangeResourceValue(id, RT_CURSOR, curs);
FreeCursor(pCursor, cursor);
}
}