diff options
54 files changed, 819 insertions, 358 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/devbell.c b/Xi/devbell.c index c75b94dee..202c8de18 100644 --- a/Xi/devbell.c +++ b/Xi/devbell.c @@ -142,7 +142,8 @@ ProcXDeviceBell(ClientPtr client) newpercent = base + newpercent; else newpercent = base - newpercent + stuff->percent; + if (proc == NULL) + return BadValue; (*proc) (newpercent, dev, ctrl, class); - return Success; } diff --git a/Xi/exevents.c b/Xi/exevents.c index f05e03d73..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; } } @@ -1221,25 +1207,36 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource, * touchpoint if it is pending finish. */ static void -ProcessTouchOwnershipEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, - TouchOwnershipEvent *ev) +ProcessTouchOwnershipEvent(TouchOwnershipEvent *ev, + DeviceIntPtr dev) { + TouchPointInfoPtr ti = TouchFindByClientID(dev, ev->touchid); + + if (!ti) { + DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n", + dev->name, ev->type, ev->touchid); + return; + } if (ev->reason == XIRejectTouch) TouchRejected(dev, ti, ev->resource, 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); @@ -1376,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); @@ -1398,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; @@ -1408,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. */ @@ -1416,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); @@ -1436,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; @@ -1446,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) @@ -1536,12 +1535,9 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev) if (!t) return; - if (ev->any.type == ET_TouchOwnership) - touchid = ev->touch_ownership_event.touchid; - else - touchid = ev->device_event.touchid; + 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); } @@ -1608,23 +1604,19 @@ 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; - /* TouchOwnership events are handled separately from the rest, as they - * have more complex semantics. */ - if (ev->any.type == ET_TouchOwnership) - ProcessTouchOwnershipEvent(dev, ti, &ev->touch_ownership_event); - else { - TouchCopyValuatorData(&ev->device_event, ti); - /* 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); - if (ev->any.type == ET_TouchEnd) - TouchEndTouch(dev, ti); - } + TouchCopyValuatorData(&ev->device_event, ti); + /* WARNING: the event type may change to TouchUpdate in + * DeliverTouchEvents if a TouchEnd was delivered to a grabbing + * owner */ + DeliverTouchEvents(dev, ti, ev, ev->device_event.resource); + if (ev->any.type == ET_TouchEnd) + TouchEndTouch(dev, ti); if (emulate_pointer) UpdateDeviceState(dev, &ev->device_event); @@ -1818,10 +1810,14 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) break; case ET_TouchBegin: case ET_TouchUpdate: - case ET_TouchOwnership: case ET_TouchEnd: ProcessTouchEvent(ev, device); break; + case ET_TouchOwnership: + /* TouchOwnership events are handled separately from the rest, as they + * have more complex semantics. */ + ProcessTouchOwnershipEvent(&ev->touch_ownership_event, device); + break; case ET_BarrierHit: case ET_BarrierLeave: ProcessBarrierEvent(ev, device); @@ -1846,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; } @@ -1863,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; @@ -1883,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; } @@ -1916,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; @@ -2847,7 +2858,7 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, (deliveryMask & DeviceButtonGrabMask)) { GrabPtr tempGrab; - tempGrab = AllocGrab(); + tempGrab = AllocGrab(NULL); if (!tempGrab) return; diff --git a/Xi/extinit.c b/Xi/extinit.c index 619d0e468..02fffe574 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -848,24 +848,24 @@ SBarrierEvent(xXIBarrierEvent * from, *to = *from; - swaps(&from->sequenceNumber); - swapl(&from->length); - swaps(&from->evtype); - swapl(&from->time); - swaps(&from->deviceid); - swaps(&from->sourceid); - swapl(&from->event); - swapl(&from->root); - swapl(&from->root_x); - swapl(&from->root_y); - - swapl(&from->dx.integral); - swapl(&from->dx.frac); - swapl(&from->dy.integral); - swapl(&from->dy.frac); - swapl(&from->dtime); - swapl(&from->barrier); - swapl(&from->eventid); + swaps(&to->sequenceNumber); + swapl(&to->length); + swaps(&to->evtype); + swapl(&to->time); + swaps(&to->deviceid); + swaps(&to->sourceid); + swapl(&to->event); + swapl(&to->root); + swapl(&to->root_x); + swapl(&to->root_y); + + swapl(&to->dx.integral); + swapl(&to->dx.frac); + swapl(&to->dy.integral); + swapl(&to->dy.frac); + swapl(&to->dtime); + swapl(&to->barrier); + swapl(&to->eventid); } /** Event swapping function for XI2 events. */ 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/xigrabdev.c b/Xi/xigrabdev.c index 09186e84f..63d95bc1c 100644 --- a/Xi/xigrabdev.c +++ b/Xi/xigrabdev.c @@ -67,6 +67,8 @@ ProcXIGrabDevice(ClientPtr client) uint8_t status; GrabMask mask = { 0 }; int mask_len; + unsigned int keyboard_mode; + unsigned int pointer_mode; REQUEST(xXIGrabDeviceReq); REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq); @@ -78,6 +80,15 @@ ProcXIGrabDevice(ClientPtr client) if (!IsMaster(dev)) stuff->paired_device_mode = GrabModeAsync; + if (IsKeyboardDevice(dev)) { + keyboard_mode = stuff->grab_mode; + pointer_mode = stuff->paired_device_mode; + } + else { + keyboard_mode = stuff->paired_device_mode; + pointer_mode = stuff->grab_mode; + } + if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1], stuff->mask_len * 4) != Success) return BadValue; @@ -91,8 +102,8 @@ ProcXIGrabDevice(ClientPtr client) xi2mask_set_one_mask(mask.xi2mask, dev->id, (unsigned char *) &stuff[1], mask_len); - ret = GrabDevice(client, dev, stuff->grab_mode, - stuff->paired_device_mode, + ret = GrabDevice(client, dev, pointer_mode, + keyboard_mode, stuff->grab_window, stuff->owner_events, stuff->time, 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 406453874..1cd41c97d 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.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2013-04-17" -RELEASE_NAME="Act Normal" +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]) @@ -2236,6 +2236,14 @@ AC_SUBST([prefix]) AC_CONFIG_COMMANDS([sdksyms], [touch hw/xfree86/sdksyms.dep]) +if test "x$CONFIG_HAL" = xno && test "x$CONFIG_UDEV" = xno; then + AC_WARN([ + *********************************************** + Neither HAL nor udev backend will be enabled. + Input device hotplugging will not be available! + ***********************************************]) +fi + AC_OUTPUT([ Makefile glx/Makefile 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 be236dd70..9ef32bb24 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -112,8 +112,8 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform_data) * Transform is the user supplied (affine) transform * InvScale scales coordinates back up into their native range */ - sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value; - sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value; + sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value + 1; + sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1; /* invscale */ pixman_f_transform_init_scale(&scale, sx, sy); @@ -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); @@ -795,6 +794,7 @@ FreeDeviceClass(int type, pointer *class) free((*t)->touches[i].valuators); } + free((*t)->touches); free((*t)); break; } @@ -976,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); @@ -1365,7 +1366,7 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, valc->numMotionEvents = numMotionEvents; valc->motionHintWindow = NullWindow; - if (mode & OutOfProximity) + if ((mode & OutOfProximity) && !dev->proximity) InitProximityClassDeviceStruct(dev); dev->valuator = valc; 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/eventconvert.c b/dix/eventconvert.c index 2c411cf40..f7ecdba77 100644 --- a/dix/eventconvert.c +++ b/dix/eventconvert.c @@ -501,9 +501,7 @@ appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo * info, info->min.frac = 0; info->max.integral = dce->valuators[axisnumber].max; info->max.frac = 0; - /* FIXME: value */ - info->value.integral = 0; - info->value.frac = 0; + info->value = double_to_fp3232(dce->valuators[axisnumber].value); info->resolution = dce->valuators[axisnumber].resolution; info->number = axisnumber; info->mode = dce->valuators[axisnumber].mode; @@ -684,17 +682,18 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi) xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac); xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac); - if (ev->type == ET_TouchUpdate) - xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0; - else - xde->flags = ev->flags; + if (IsTouchEvent((InternalEvent *)ev)) { + if (ev->type == ET_TouchUpdate) + xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0; - if (IsTouchEvent((InternalEvent *) ev) && - ev->flags & TOUCH_POINTER_EMULATED) - xde->flags |= XITouchEmulatingPointer; + if (ev->flags & TOUCH_POINTER_EMULATED) + xde->flags |= XITouchEmulatingPointer; + } else { + xde->flags = ev->flags; - if (ev->key_repeat) - xde->flags |= XIKeyRepeat; + if (ev->key_repeat) + xde->flags |= XIKeyRepeat; + } xde->mods.base_mods = ev->mods.base; xde->mods.latched_mods = ev->mods.latched; 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 a4f192cf0..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]; } } @@ -277,6 +277,7 @@ CreateClassesChangedEvent(InternalEvent *event, dce->valuators[i].mode = slave->valuator->axes[i].mode; dce->valuators[i].name = slave->valuator->axes[i].label; dce->valuators[i].scroll = slave->valuator->axes[i].scroll; + dce->valuators[i].value = slave->valuator->axisVal[i]; } } if (slave->key) { @@ -297,11 +298,11 @@ rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to, if (from && from->min_value < from->max_value) { fmin = from->min_value; - fmax = from->max_value; + fmax = from->max_value + 1; } if (to && to->min_value < to->max_value) { tmin = to->min_value; - tmax = to->max_value; + tmax = to->max_value + 1; } if (fmin == tmin && fmax == tmax) @@ -913,9 +914,9 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask, /* scale x&y to desktop coordinates */ *screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL, - screenInfo.x, screenInfo.width - 1); + screenInfo.x, screenInfo.width); *screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL, - screenInfo.y, screenInfo.height - 1); + screenInfo.y, screenInfo.height); *devx = x; *devy = y; @@ -1355,6 +1356,12 @@ QueuePointerEvents(DeviceIntPtr device, int type, * is the last coordinate on the first screen and must be rescaled for the * event to be m. XI2 clients that do their own coordinate mapping would * otherwise interpret the position of the device elsewere to the cursor. + * However, this scaling leads to losses: + * if we have two ScreenRecs we scale from e.g. [0..44704] (Wacom I4) to + * [0..2048[. that gives us 2047.954 as desktop coord, or the per-screen + * coordinate 1023.954. Scaling that back into the device coordinate range + * gives us 44703. So off by one device unit. It's a bug, but we'll have to + * live with it because with all this scaling, we just cannot win. * * @return the number of events written into events. */ 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 891cc7803..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); } } @@ -620,14 +643,14 @@ TouchConvertToPointerEvent(const InternalEvent *event, BUG_WARN_MSG(!(event->device_event.flags & TOUCH_POINTER_EMULATED), "Non-emulating touch event\n"); - *motion_event = *event; + motion_event->device_event = event->device_event; motion_event->any.type = ET_Motion; motion_event->device_event.detail.button = 0; motion_event->device_event.flags = XIPointerEmulated; if (nevents > 1) { BUG_RETURN_VAL(!button_event, 0); - *button_event = *event; + button_event->device_event = event->device_event; button_event->any.type = ptrtype; button_event->device_event.flags = XIPointerEmulated; /* detail is already correct */ @@ -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 da4646845..41424afdd 100644 --- a/glx/glxdri.c +++ b/glx/glxdri.c @@ -885,7 +885,7 @@ glxDRILeaveVT(ScrnInfoPtr scrn) __GLXDRIscreen *screen = (__GLXDRIscreen *) glxGetScreen(xf86ScrnToScreen(scrn)); - LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n"); + LogMessageVerbSigSafe(X_INFO, -1, "AIGLX: Suspending AIGLX clients for VT switch\n"); glxSuspendClients(); @@ -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/glx/glxdri2.c b/glx/glxdri2.c index b26e501dc..16e7e3dee 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -835,7 +835,7 @@ glxDRILeaveVT(ScrnInfoPtr scrn) __GLXDRIscreen *screen = (__GLXDRIscreen *) glxGetScreen(xf86ScrnToScreen(scrn)); - LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n"); + LogMessageVerbSigSafe(X_INFO, -1, "AIGLX: Suspending AIGLX clients for VT switch\n"); glxSuspendClients(); diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index e6520d035..c9672c04a 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -237,13 +237,11 @@ ephyrMapFramebuffer(KdScreenInfo * screen) KdComputePointerMatrix(&m, ephyrRandr, screen->width, screen->height); KdSetPointerMatrix(&m); - priv->bytes_per_line = - ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2; - buffer_height = ephyrBufferHeight(screen); priv->base = - hostx_screen_init(screen, screen->width, screen->height, buffer_height); + hostx_screen_init(screen, screen->width, screen->height, buffer_height, + &priv->bytes_per_line, &screen->fb.bitsPerPixel); if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All)) { scrpriv->shadow = FALSE; diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 157ac36b2..6bbccd3e8 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -617,7 +617,8 @@ hostx_set_cmap_entry(unsigned char idx, */ void * hostx_screen_init(EphyrScreenInfo screen, - int width, int height, int buffer_height) + int width, int height, int buffer_height, + int *bytes_per_line, int *bits_per_pixel) { int bitmap_pad; Bool shm_success = False; @@ -694,6 +695,9 @@ hostx_screen_init(EphyrScreenInfo screen, malloc(host_screen->ximg->bytes_per_line * buffer_height); } + *bytes_per_line = host_screen->ximg->bytes_per_line; + *bits_per_pixel = host_screen->ximg->bits_per_pixel; + XResizeWindow(HostX.dpy, host_screen->win, width, height); /* Ask the WM to keep our size static */ diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h index 31c4053aa..38b7b3768 100644 --- a/hw/kdrive/ephyr/hostx.h +++ b/hw/kdrive/ephyr/hostx.h @@ -193,7 +193,8 @@ hostx_set_cmap_entry(unsigned char idx, unsigned char r, unsigned char g, unsigned char b); void *hostx_screen_init(EphyrScreenInfo screen, - int width, int height, int buffer_height); + int width, int height, int buffer_height, + int *bytes_per_line, int *bits_per_pixel); void 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/xf86.h b/hw/xfree86/common/xf86.h index 1514c2603..828d95850 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -243,6 +243,7 @@ extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler) (void)); extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new); extern _X_EXPORT void xf86ProcessActionEvent(ActionEvent action, void *arg); extern _X_EXPORT void xf86PrintBacktrace(void); +extern _X_EXPORT Bool xf86VTOwner(void); /* xf86Helper.c */ diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index d92174edf..2a05a0ed5 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -84,6 +84,7 @@ #include "dpmsproc.h" #endif +#include "xf86platformBus.h" /* * This is a toggling variable: * FALSE = No VT switching keys have been pressed last time around @@ -428,7 +429,7 @@ xf86VTSwitch(void) * Since all screens are currently all in the same state it is sufficient * check the first. This might change in future. */ - if (xf86Screens[0]->vtSema) { + if (xf86VTOwner()) { DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n", BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE)); @@ -561,6 +562,11 @@ xf86VTSwitch(void) for (ih = InputHandlers; ih; ih = ih->next) xf86EnableInputHandler(ih); +#ifdef XSERVER_PLATFORM_BUS + /* check for any new output devices */ + xf86platformVTProbe(); +#endif + OsReleaseSIGIO(); } } @@ -769,3 +775,12 @@ DDXRingBell(int volume, int pitch, int duration) { xf86OSRingBell(volume, pitch, duration); } + +Bool +xf86VTOwner(void) +{ + /* at system startup xf86Screens[0] won't be set - but we will own the VT */ + if (xf86NumScreens == 0) + return TRUE; + return xf86Screens[0]->vtSema; +} diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 1695dbf74..91ec4c8bb 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -819,7 +819,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) if (serverGeneration != 1) { xf86Resetting = TRUE; /* All screens are in the same state, so just check the first */ - if (!xf86Screens[0]->vtSema) { + if (!xf86VTOwner()) { #ifdef HAS_USL_VTS ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ); #endif diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index bee407bf9..26c03c6c3 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -870,7 +870,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable) } /* Enable it if it's properly initialised and we're currently in the VT */ - if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema) { + if (enable && dev->inited && dev->startup && xf86VTOwner()) { OsBlockSignals(); EnableDevice(dev, TRUE); if (!dev->enabled) { diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index 58663336a..db831a883 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -113,6 +113,11 @@ xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_ return NULL; } +Bool +xf86_get_platform_device_unowned(int index) +{ + return xf86_platform_devices[index].attribs->unowned; +} /* * xf86IsPrimaryPlatform() -- return TRUE if primary device @@ -449,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); @@ -498,4 +511,18 @@ xf86platformRemoveDevice(int index) out: return; } + +/* called on return from VT switch to find any new devices */ +void xf86platformVTProbe(void) +{ + int i; + + for (i = 0; i < xf86_num_platform_devices; i++) { + if (xf86_platform_devices[i].attribs->unowned == FALSE) + continue; + + xf86_platform_devices[i].attribs->unowned = FALSE; + xf86PlatformReprobeDevice(i, xf86_platform_devices[i].attribs); + } +} #endif diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h index 49afc247b..4e1757854 100644 --- a/hw/xfree86/common/xf86platformBus.h +++ b/hw/xfree86/common/xf86platformBus.h @@ -46,6 +46,8 @@ extern int xf86_remove_platform_device(int dev_index); extern Bool xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str); +extern Bool +xf86_get_platform_device_unowned(int index); extern int xf86platformAddDevice(int index); @@ -59,6 +61,8 @@ xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *bu extern _X_EXPORT int xf86PlatformMatchDriver(char *matches[], int nmatches); + +extern void xf86platformVTProbe(void); #endif #endif diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index f9ae46596..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) @@ -2598,8 +2612,8 @@ xf86SetDesiredModes(ScrnInfoPtr scrn) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcPtr crtc = config->crtc[0]; + int enabled = 0, failed = 0; int c; - int enabled = 0; /* A driver with this hook will take care of this */ if (!crtc->funcs->set_mode_major) { @@ -2659,11 +2673,12 @@ xf86SetDesiredModes(ScrnInfoPtr scrn) if (config->output[o]->crtc == crtc) config->output[o]->crtc = NULL; crtc->enabled = FALSE; + ++failed; } } xf86DisableUnusedFunctions(scrn); - return enabled != 0; + return enabled != 0 || failed == 0; } /** 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/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c index 76f5583dd..d751f591a 100644 --- a/hw/xfree86/os-support/linux/lnx_platform.c +++ b/hw/xfree86/os-support/linux/lnx_platform.c @@ -18,7 +18,7 @@ #include "hotplug.h" static Bool -get_drm_info(struct OdevAttributes *attribs, char *path) +get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) { drmSetVersion sv; char *buf; @@ -37,10 +37,14 @@ get_drm_info(struct OdevAttributes *attribs, char *path) return FALSE; } - xf86_add_platform_device(attribs); + /* for a delayed probe we've already added the device */ + if (delayed_index == -1) { + xf86_add_platform_device(attribs); + delayed_index = xf86_num_platform_devices - 1; + } buf = drmGetBusid(fd); - xf86_add_platform_device_attrib(xf86_num_platform_devices - 1, + xf86_add_platform_device_attrib(delayed_index, ODEV_ATTRIB_BUSID, buf); drmFreeBusid(buf); close(fd); @@ -89,6 +93,23 @@ xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *bu } void +xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs) +{ + Bool ret; + char *dpath; + dpath = xf86_get_platform_attrib(index, ODEV_ATTRIB_PATH); + + ret = get_drm_info(attribs, dpath, index); + if (ret == FALSE) { + xf86_remove_platform_device(index); + return; + } + ret = xf86platformAddDevice(index); + if (ret == -1) + xf86_remove_platform_device(index); +} + +void xf86PlatformDeviceProbe(struct OdevAttributes *attribs) { struct OdevAttribute *attrib; @@ -116,10 +137,17 @@ xf86PlatformDeviceProbe(struct OdevAttributes *attribs) if (i != xf86_num_platform_devices) goto out_free; - LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", - path); + LogMessage(X_INFO, "xfree86: Adding drm device (%s)\n", path); - ret = get_drm_info(attribs, path); + if (!xf86VTOwner()) { + /* if we don't currently own the VT then don't probe the device, + just mark it as unowned for later use */ + attribs->unowned = TRUE; + xf86_add_platform_device(attribs); + return; + } + + ret = get_drm_info(attribs, path, -1); if (ret == FALSE) goto out_free; @@ -138,6 +166,9 @@ void NewGPUDeviceRequest(struct OdevAttributes *attribs) if (old_num == xf86_num_platform_devices) return; + if (xf86_get_platform_device_unowned(xf86_num_platform_devices - 1) == TRUE) + return; + ret = xf86platformAddDevice(xf86_num_platform_devices-1); if (ret == -1) xf86_remove_platform_device(xf86_num_platform_devices-1); @@ -171,7 +202,10 @@ void DeleteGPUDeviceRequest(struct OdevAttributes *attribs) ErrorF("xf86: remove device %d %s\n", index, syspath); - xf86platformRemoveDevice(index); + if (xf86_get_platform_device_unowned(index) == TRUE) + xf86_remove_platform_device(index); + else + xf86platformRemoveDevice(index); out: config_odev_free_attribute_list(attribs); } diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c index 4b75a98ac..68527a577 100644 --- a/hw/xfree86/os-support/solaris/sun_init.c +++ b/hw/xfree86/os-support/solaris/sun_init.c @@ -274,7 +274,7 @@ xf86OpenConsole(void) * this is to make sure we don't continue until the activate * signal is received. */ - if (!xf86Screens[0]->vtSema) + if (!xf86VTOwner()) sleep(5); } #endif /* HAS_USL_VTS */ diff --git a/hw/xfree86/os-support/xf86_OSproc.h b/hw/xfree86/os-support/xf86_OSproc.h index ea2b16e46..6be594651 100644 --- a/hw/xfree86/os-support/xf86_OSproc.h +++ b/hw/xfree86/os-support/xf86_OSproc.h @@ -223,6 +223,9 @@ extern _X_EXPORT void xf86InitVidMem(void); #include "hotplug.h" void xf86PlatformDeviceProbe(struct OdevAttributes *attribs); + +void +xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs); #endif _XFUNCPROTOEND 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/dixstruct.h b/include/dixstruct.h index 678481920..aef822ca2 100644 --- a/include/dixstruct.h +++ b/include/dixstruct.h @@ -96,7 +96,7 @@ typedef struct _Client { unsigned int clientGone:1; unsigned int closeDownMode:2; unsigned int clientState:2; - char smart_priority; + signed char smart_priority; short noClientException; /* this client died or needs to be killed */ int priority; ReplySwapPtr pSwapReplyFunc; diff --git a/include/eventstr.h b/include/eventstr.h index 38fab4f3c..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 */ }; /** @@ -175,6 +176,7 @@ struct _DeviceChangedEvent { struct { uint32_t min; /**< Minimum value */ uint32_t max; /**< Maximum value */ + double value; /**< Current value */; /* FIXME: frac parts of min/max */ uint32_t resolution; /**< Resolution counts/m */ uint8_t mode; /**< Relative or Absolute */ diff --git a/include/hotplug.h b/include/hotplug.h index 2a95b4524..29a22c4da 100644 --- a/include/hotplug.h +++ b/include/hotplug.h @@ -40,6 +40,7 @@ struct OdevAttribute { struct OdevAttributes { struct xorg_list list; + Bool unowned; }; struct OdevAttributes * 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 */ , @@ -1063,6 +1063,7 @@ FreeOsBuffers(OsCommPtr oc) oci->bufptr = oci->buffer; oci->bufcnt = 0; oci->lenLastReq = 0; + oci->ignoreBytes = 0; } } if ((oco = oc->output)) { @@ -253,7 +253,7 @@ void LogClose(enum ExitCode error) { if (logFile) { - ErrorF("Server terminated %s (%d). Closing log file.\n", + ErrorFSigSafe("Server terminated %s (%d). Closing log file.\n", (error == EXIT_NO_ERROR) ? "successfully" : "with error", error); fclose(logFile); logFile = NULL; @@ -282,6 +282,59 @@ LogSetParameter(LogParameter param, int value) } } +enum { + LMOD_LONG = 0x1, + LMOD_LONGLONG = 0x2, + LMOD_SHORT = 0x4, + LMOD_SIZET = 0x8, +}; + +/** + * Parse non-digit length modifiers and set the corresponding flag in + * flags_return. + * + * @return the number of bytes parsed + */ +static int parse_length_modifier(const char *format, size_t len, int *flags_return) +{ + int idx = 0; + int length_modifier = 0; + + while (idx < len) { + switch (format[idx]) { + case 'l': + BUG_RETURN_VAL(length_modifier & LMOD_SHORT, 0); + + if (length_modifier & LMOD_LONG) + length_modifier |= LMOD_LONGLONG; + else + length_modifier |= LMOD_LONG; + break; + case 'h': + BUG_RETURN_VAL(length_modifier & (LMOD_LONG|LMOD_LONGLONG), 0); + length_modifier |= LMOD_SHORT; + /* gcc says 'short int' is promoted to 'int' when + * passed through '...', so ignored during + * processing */ + break; + case 'z': + length_modifier |= LMOD_SIZET; + break; + default: + goto out; + } + idx++; + } + +out: + *flags_return = length_modifier; + return idx; +} + +/** + * Signal-safe snprintf, with some limitations over snprintf. Be careful + * which directives you use. + */ static int pnprintf(char *string, size_t size, const char *f, va_list args) { @@ -296,6 +349,7 @@ pnprintf(char *string, size_t size, const char *f, va_list args) int64_t si; for (; f_idx < f_len && s_idx < size - 1; f_idx++) { + int length_modifier = 0; if (f[f_idx] != '%') { string[s_idx++] = f[f_idx]; continue; @@ -303,10 +357,18 @@ pnprintf(char *string, size_t size, const char *f, va_list args) f_idx++; - /* silently swallow length modifiers */ + /* silently swallow digit length modifiers */ while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.')) f_idx++; + /* non-digit length modifiers */ + if (f_idx < f_len) { + int parsed_bytes = parse_length_modifier(&f[f_idx], f_len - f_idx, &length_modifier); + if (parsed_bytes < 0) + return 0; + f_idx += parsed_bytes; + } + if (f_idx >= f_len) break; @@ -320,7 +382,15 @@ pnprintf(char *string, size_t size, const char *f, va_list args) break; case 'u': - ui = va_arg(args, unsigned); + if (length_modifier & LMOD_LONGLONG) + ui = va_arg(args, unsigned long long); + else if (length_modifier & LMOD_LONG) + ui = va_arg(args, unsigned long); + else if (length_modifier & LMOD_SIZET) + ui = va_arg(args, size_t); + else + ui = va_arg(args, unsigned); + FormatUInt64(ui, number); p_len = strlen_sigsafe(number); @@ -329,7 +399,15 @@ pnprintf(char *string, size_t size, const char *f, va_list args) break; case 'i': case 'd': - si = va_arg(args, int); + if (length_modifier & LMOD_LONGLONG) + si = va_arg(args, long long); + else if (length_modifier & LMOD_LONG) + si = va_arg(args, long); + else if (length_modifier & LMOD_SIZET) + si = va_arg(args, ssize_t); + else + si = va_arg(args, int); + FormatInt64(si, number); p_len = strlen_sigsafe(number); @@ -350,7 +428,15 @@ pnprintf(char *string, size_t size, const char *f, va_list args) break; case 'x': - ui = va_arg(args, unsigned); + if (length_modifier & LMOD_LONGLONG) + ui = va_arg(args, unsigned long long); + else if (length_modifier & LMOD_LONG) + ui = va_arg(args, unsigned long); + else if (length_modifier & LMOD_SIZET) + ui = va_arg(args, size_t); + else + ui = va_arg(args, unsigned); + FormatUInt64Hex(ui, number); p_len = strlen_sigsafe(number); @@ -367,7 +453,18 @@ pnprintf(char *string, size_t size, const char *f, va_list args) string[s_idx++] = number[i]; } break; + case 'c': + { + char c = va_arg(args, int); + if (s_idx < size - 1) + string[s_idx++] = c; + } + break; + case '%': + string[s_idx++] = '%'; + break; default: + BUG_WARN_MSG(f[f_idx], "Unsupported printf directive '%c'\n", f[f_idx]); va_arg(args, char*); string[s_idx++] = '%'; if (s_idx < size - 1) @@ -784,9 +881,9 @@ FatalError(const char *f, ...) static Bool beenhere = FALSE; if (beenhere) - ErrorF("FatalError re-entered, aborting\n"); + ErrorFSigSafe("FatalError re-entered, aborting\n"); else - ErrorF("Fatal server error: "); + ErrorFSigSafe("Fatal server error:\n"); va_start(args, f); @@ -803,10 +900,10 @@ FatalError(const char *f, ...) va_end(apple_args); } #endif - VErrorF(f, args); + VErrorFSigSafe(f, args); va_end(args); if (f[strlen(f) - 1] != '\n') - ErrorF("\n"); + ErrorFSigSafe("\n"); if (!beenhere) OsVendorFatalError(f, args2); va_end(args2); 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/signal-logging.c b/test/signal-logging.c index e0eb81006..f6bc85ce8 100644 --- a/test/signal-logging.c +++ b/test/signal-logging.c @@ -158,6 +158,8 @@ static void logging_format(void) char buf[1024]; int i; unsigned int ui; + long li; + unsigned long lui; FILE *f; char read_buf[2048]; char *logmsg; @@ -194,6 +196,23 @@ static void logging_format(void) read_log_msg(logmsg); assert(strcmp(logmsg, "(EE) %s %d %u %% %p %i\n") == 0); + /* literal % */ + LogMessageVerbSigSafe(X_ERROR, -1, "test %%\n"); + read_log_msg(logmsg); + assert(strcmp(logmsg, "(EE) test %\n") == 0); + + /* character */ + LogMessageVerbSigSafe(X_ERROR, -1, "test %c\n", 'a'); + read_log_msg(logmsg); + assert(strcmp(logmsg, "(EE) test a\n") == 0); + + /* something unsupported % */ + LogMessageVerbSigSafe(X_ERROR, -1, "test %Q\n"); + read_log_msg(logmsg); + assert(strstr(logmsg, "BUG") != NULL); + LogMessageVerbSigSafe(X_ERROR, -1, "\n"); + fseek(f, 0, SEEK_END); + /* string substitution */ LogMessageVerbSigSafe(X_ERROR, -1, "%s\n", "substituted string"); read_log_msg(logmsg); @@ -207,6 +226,14 @@ static void logging_format(void) LogMessageVerbSigSafe(X_ERROR, -1, "\n"); fseek(f, 0, SEEK_END); +#warning Ignore compiler warning below "unknown conversion type character". This is intentional. + /* %hld is bogus */ + LogMessageVerbSigSafe(X_ERROR, -1, "%hld\n", 4); + read_log_msg(logmsg); + assert(strstr(logmsg, "BUG") != NULL); + LogMessageVerbSigSafe(X_ERROR, -1, "\n"); + fseek(f, 0, SEEK_END); + /* number substitution */ ui = 0; do { @@ -215,12 +242,47 @@ static void logging_format(void) LogMessageVerbSigSafe(X_ERROR, -1, "%u\n", ui); read_log_msg(logmsg); assert(strcmp(logmsg, expected) == 0); + + sprintf(expected, "(EE) %x\n", ui); + LogMessageVerbSigSafe(X_ERROR, -1, "%x\n", ui); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + if (ui == 0) ui = 1; else ui <<= 1; } while(ui); + lui = 0; + do { + char expected[30]; + sprintf(expected, "(EE) %lu\n", lui); + LogMessageVerbSigSafe(X_ERROR, -1, "%lu\n", lui); + read_log_msg(logmsg); + + sprintf(expected, "(EE) %lld\n", (unsigned long long)ui); + LogMessageVerbSigSafe(X_ERROR, -1, "%lld\n", (unsigned long long)ui); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + + sprintf(expected, "(EE) %lx\n", lui); + printf("%s\n", expected); + LogMessageVerbSigSafe(X_ERROR, -1, "%lx\n", lui); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + + sprintf(expected, "(EE) %llx\n", (unsigned long long)ui); + LogMessageVerbSigSafe(X_ERROR, -1, "%llx\n", (unsigned long long)ui); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + + if (lui == 0) + lui = 1; + else + lui <<= 1; + } while(lui); + /* signed number substitution */ i = 0; do { @@ -230,7 +292,6 @@ static void logging_format(void) read_log_msg(logmsg); assert(strcmp(logmsg, expected) == 0); - sprintf(expected, "(EE) %d\n", i | INT_MIN); LogMessageVerbSigSafe(X_ERROR, -1, "%d\n", i | INT_MIN); read_log_msg(logmsg); @@ -242,19 +303,35 @@ static void logging_format(void) i <<= 1; } while(i > INT_MIN); - /* hex number substitution */ - ui = 0; + li = 0; do { char expected[30]; - sprintf(expected, "(EE) %x\n", ui); - LogMessageVerbSigSafe(X_ERROR, -1, "%x\n", ui); + sprintf(expected, "(EE) %ld\n", li); + LogMessageVerbSigSafe(X_ERROR, -1, "%ld\n", li); read_log_msg(logmsg); assert(strcmp(logmsg, expected) == 0); - if (ui == 0) - ui = 1; + + sprintf(expected, "(EE) %ld\n", li | LONG_MIN); + LogMessageVerbSigSafe(X_ERROR, -1, "%ld\n", li | LONG_MIN); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + + sprintf(expected, "(EE) %lld\n", (long long)li); + LogMessageVerbSigSafe(X_ERROR, -1, "%lld\n", (long long)li); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + + sprintf(expected, "(EE) %lld\n", (long long)(li | LONG_MIN)); + LogMessageVerbSigSafe(X_ERROR, -1, "%lld\n", (long long)(li | LONG_MIN)); + read_log_msg(logmsg); + assert(strcmp(logmsg, expected) == 0); + + if (li == 0) + li = 1; else - ui <<= 1; - } while(ui); + li <<= 1; + } while(li > LONG_MIN); + /* pointer substitution */ /* we print a null-pointer differently to printf */ 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); } } diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c index 4e8e267da..ed01114b6 100644 --- a/xkb/xkbInit.c +++ b/xkb/xkbInit.c @@ -574,7 +574,8 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes, &check, &cause); - InitFocusClassDeviceStruct(dev); + if (!dev->focus) + InitFocusClassDeviceStruct(dev); xkbi->kbdProc = ctrl_func; dev->kbdfeed->BellProc = bell_func; |