diff --git a/Xext/xtest.c b/Xext/xtest.c index 18e1ef7ae..daa6430f1 100644 --- a/Xext/xtest.c +++ b/Xext/xtest.c @@ -52,6 +52,7 @@ #include "mipointer.h" #include "xserver-properties.h" #include "exevents.h" +#include "eventstr.h" #include "inpututils.h" #include "modinit.h" @@ -61,7 +62,7 @@ extern int DeviceValuator; /* XTest events are sent during request processing and may be interruped by * a SIGIO. We need a separate event list to avoid events overwriting each * other's memory */ -static EventListPtr xtest_evlist; +static InternalEvent* xtest_evlist; /** * xtestpointer @@ -428,7 +429,7 @@ ProcXTestFakeInput(ClientPtr client) } for (i = 0; i < nevents; i++) - mieqProcessDeviceEvent(dev, (InternalEvent*)(xtest_evlist+i)->event, NULL); + mieqProcessDeviceEvent(dev, &xtest_evlist[i], NULL); if (need_ptr_update) miPointerUpdateSprite(dev); diff --git a/Xi/exevents.c b/Xi/exevents.c index 76d5c3759..c6f9d467f 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -77,6 +77,7 @@ SOFTWARE. #include "xiquerydevice.h" /* For List*Info */ #include "eventconvert.h" #include "eventstr.h" +#include "inpututils.h" #include #include "xkbsrv.h" @@ -920,7 +921,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) DeviceIntPtr mouse = NULL, kbd = NULL; DeviceEvent *event = &ev->device_event; - CHECKEVENT(ev); + verify_internal_event(ev); if (ev->any.type == ET_RawKeyPress || ev->any.type == ET_RawKeyRelease || @@ -1188,6 +1189,108 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, first += ev->num_valuators; } +static void +DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) +{ + int evcount = 1; + deviceStateNotify *ev, *sev; + deviceKeyStateNotify *kev; + deviceButtonStateNotify *bev; + + KeyClassPtr k; + ButtonClassPtr b; + ValuatorClassPtr v; + int nval = 0, nkeys = 0, nbuttons = 0, first = 0; + + if (!(wOtherInputMasks(win)) || + !(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask)) + return; + + if ((b = dev->button) != NULL) { + nbuttons = b->numButtons; + if (nbuttons > 32) + evcount++; + } + if ((k = dev->key) != NULL) { + nkeys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code; + if (nkeys > 32) + evcount++; + if (nbuttons > 0) { + evcount++; + } + } + if ((v = dev->valuator) != NULL) { + nval = v->numAxes; + + if (nval > 3) + evcount++; + if (nval > 6) { + if (!(k && b)) + evcount++; + if (nval > 9) + evcount += ((nval - 7) / 3); + } + } + + sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); + FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); + + if (b != NULL) { + FixDeviceStateNotify(dev, ev++, NULL, b, v, first); + first += 3; + nval -= 3; + if (nbuttons > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + bev = (deviceButtonStateNotify *) ev++; + bev->type = DeviceButtonStateNotify; + bev->deviceid = dev->id; + memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + if (k != NULL) { + FixDeviceStateNotify(dev, ev++, k, NULL, v, first); + first += 3; + nval -= 3; + if (nkeys > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + kev = (deviceKeyStateNotify *) ev++; + kev->type = DeviceKeyStateNotify; + kev->deviceid = dev->id; + memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + while (nval > 0) { + FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); + first += 3; + nval -= 3; + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, + DeviceStateNotifyMask, NullGrab); + free(sev); +} + void DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) @@ -1254,104 +1357,8 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, DeviceFocusChangeMask, NullGrab); - if ((event.type == DeviceFocusIn) && - (wOtherInputMasks(pWin)) && - (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) - { - int evcount = 1; - deviceStateNotify *ev, *sev; - deviceKeyStateNotify *kev; - deviceButtonStateNotify *bev; - - KeyClassPtr k; - ButtonClassPtr b; - ValuatorClassPtr v; - int nval = 0, nkeys = 0, nbuttons = 0, first = 0; - - if ((b = dev->button) != NULL) { - nbuttons = b->numButtons; - if (nbuttons > 32) - evcount++; - } - if ((k = dev->key) != NULL) { - nkeys = k->xkbInfo->desc->max_key_code - - k->xkbInfo->desc->min_key_code; - if (nkeys > 32) - evcount++; - if (nbuttons > 0) { - evcount++; - } - } - if ((v = dev->valuator) != NULL) { - nval = v->numAxes; - - if (nval > 3) - evcount++; - if (nval > 6) { - if (!(k && b)) - evcount++; - if (nval > 9) - evcount += ((nval - 7) / 3); - } - } - - sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); - FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); - - if (b != NULL) { - FixDeviceStateNotify(dev, ev++, NULL, b, v, first); - first += 3; - nval -= 3; - if (nbuttons > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - bev = (deviceButtonStateNotify *) ev++; - bev->type = DeviceButtonStateNotify; - bev->deviceid = dev->id; - memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - if (k != NULL) { - FixDeviceStateNotify(dev, ev++, k, NULL, v, first); - first += 3; - nval -= 3; - if (nkeys > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - kev = (deviceKeyStateNotify *) ev++; - kev->type = DeviceKeyStateNotify; - kev->deviceid = dev->id; - memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - while (nval > 0) { - FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); - first += 3; - nval -= 3; - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, - DeviceStateNotifyMask, NullGrab); - free(sev); - } + if (event.type == DeviceFocusIn) + DeliverStateNotifyEvent(dev, pWin); } int diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c index 0736a5a36..96ead6fcd 100644 --- a/Xi/xichangehierarchy.c +++ b/Xi/xichangehierarchy.c @@ -355,6 +355,7 @@ detach_slave(ClientPtr client, xXIDetachSlaveInfo *c, int flags[MAXDEVICES]) goto unwind; } + ReleaseButtonsAndKeys(dev); AttachDevice(client, dev, NULL); flags[dev->id] |= XISlaveDetached; @@ -406,6 +407,7 @@ attach_slave(ClientPtr client, xXIAttachSlaveInfo *c, goto unwind; } + ReleaseButtonsAndKeys(dev); AttachDevice(client, dev, newmaster); flags[dev->id] |= XISlaveAttached; diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c index ae63297da..f647f9872 100644 --- a/Xi/xiqueryversion.c +++ b/Xi/xiqueryversion.c @@ -58,7 +58,6 @@ ProcXIQueryVersion(ClientPtr client) xXIQueryVersionReply rep; XIClientPtr pXIClient; int major, minor; - unsigned int sversion, cversion; REQUEST(xXIQueryVersionReq); REQUEST_SIZE_MATCH(xXIQueryVersionReq); @@ -72,10 +71,8 @@ ProcXIQueryVersion(ClientPtr client) pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); - sversion = XIVersion.major_version * 1000 + XIVersion.minor_version; - cversion = stuff->major_version * 1000 + stuff->minor_version; - - if (sversion > cversion) + if (version_compare(XIVersion.major_version, XIVersion.minor_version, + stuff->major_version, stuff->minor_version) > 0) { major = stuff->major_version; minor = stuff->minor_version; diff --git a/dix/devices.c b/dix/devices.c index 3f46ad6fb..9a4498b9f 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -2365,10 +2365,10 @@ RecalculateMasterButtons(DeviceIntPtr slave) * Generate release events for all keys/button currently down on this * device. */ -static void +void ReleaseButtonsAndKeys(DeviceIntPtr dev) { - EventListPtr eventlist = InitEventList(GetMaximumEventsNum()); + InternalEvent* eventlist = InitEventList(GetMaximumEventsNum()); ButtonClassPtr b = dev->button; KeyClassPtr k = dev->key; int i, j, nevents; @@ -2383,7 +2383,7 @@ ReleaseButtonsAndKeys(DeviceIntPtr dev) { nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL); for (j = 0; j < nevents; j++) - mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL); + mieqProcessDeviceEvent(dev, &eventlist[j], NULL); } } @@ -2394,7 +2394,7 @@ ReleaseButtonsAndKeys(DeviceIntPtr dev) { nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i, NULL); for (j = 0; j < nevents; j++) - mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL); + mieqProcessDeviceEvent(dev, &eventlist[j], NULL); } } @@ -2434,8 +2434,6 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) free(dev->spriteInfo->sprite); } - ReleaseButtonsAndKeys(dev); - oldmaster = GetMaster(dev, MASTER_ATTACHED); dev->master = master; diff --git a/dix/eventconvert.c b/dix/eventconvert.c index 14731f4f6..024f2e833 100644 --- a/dix/eventconvert.c +++ b/dix/eventconvert.c @@ -156,7 +156,7 @@ EventToCore(InternalEvent *event, xEvent **core_out, int *count_out) case ET_RawButtonRelease: case ET_RawMotion: ret = BadMatch; - goto out; + break; default: /* XXX: */ ErrorF("[dix] EventToCore: Not implemented yet \n"); diff --git a/dix/events.c b/dix/events.c index d70d62fd8..14f6f909e 100644 --- a/dix/events.c +++ b/dix/events.c @@ -176,12 +176,23 @@ typedef const char *string; #define AllEventMasks (LastEventMask|(LastEventMask-1)) -#define CORE_EVENT(event) \ - (!((event)->u.u.type & EXTENSION_EVENT_BASE) && \ - (event)->u.u.type != GenericEvent) -#define XI2_EVENT(event) \ - (((event)->u.u.type == GenericEvent) && \ - ((xGenericEvent*)(event))->extension == IReqCode) +/* @return the core event type or 0 if the event is not a core event */ +static inline int +core_get_type(const xEvent *event) +{ + int type = event->u.u.type; + + return ((type & EXTENSION_EVENT_BASE) || type == GenericEvent) ? 0 : type; +} + +/* @return the XI2 event type or 0 if the event is not a XI2 event */ +static inline int +xi2_get_type(const xEvent *event) +{ + xGenericEvent* e = (xGenericEvent*)event; + + return (e->type != GenericEvent || e->extension != IReqCode) ? 0 : e->evtype; +} /** * Used to indicate a implicit passive grab created by a ButtonPress event. @@ -345,8 +356,8 @@ extern int DeviceMotionNotify; /** * Event masks for each event type. * - * One set of filters for each device, but only the first layer - * is initialized. The rest is memcpy'd in InitEvents. + * One set of filters for each device, initialized by memcpy of + * default_filter in InitEvents. * * Filters are used whether a given event may be delivered to a client, * usually in the form of if (window-event-mask & filter); then deliver event. @@ -355,7 +366,9 @@ extern int DeviceMotionNotify; * time a button is pressed, the filter is modified to also contain the * matching ButtonXMotion mask. */ -static Mask filters[MAXDEVICES][128] = { +static Mask filters[MAXDEVICES][128]; + +static const Mask default_filter[128] = { NoSuchEvent, /* 0 */ NoSuchEvent, /* 1 */ @@ -392,7 +405,7 @@ static Mask filters[MAXDEVICES][128] = { ColormapChangeMask, /* ColormapNotify */ CantBeFiltered, /* ClientMessage */ CantBeFiltered /* MappingNotify */ -}}; +}; /** * For the given event, return the matching event filter. This filter may then @@ -412,10 +425,12 @@ static Mask filters[MAXDEVICES][128] = { Mask GetEventFilter(DeviceIntPtr dev, xEvent *event) { + int evtype = 0; + if (event->u.u.type != GenericEvent) return filters[dev ? dev->id : 0][event->u.u.type]; - else if (XI2_EVENT(event)) - return (1 << (((xXIDeviceEvent*)event)->evtype % 8)); + else if ((evtype = xi2_get_type(event))) + return (1 << (evtype % 8)); ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type); return 0; } @@ -430,7 +445,7 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev) int filter; int evtype; - if (!inputMasks || !XI2_EVENT(ev)) + if (!inputMasks || xi2_get_type(ev) == 0) return 0; evtype = ((xGenericEvent*)ev)->evtype; @@ -444,14 +459,16 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev) Mask GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other) { + int evtype; + /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */ - if (XI2_EVENT(event)) + if ((evtype = xi2_get_type(event))) { - int byte = ((xGenericEvent*)event)->evtype / 8; + int byte = evtype / 8; return (other->xi2mask[dev->id][byte] | other->xi2mask[XIAllDevices][byte] | (IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0)); - } else if (CORE_EVENT(event)) + } else if (core_get_type(event) != 0) return other->mask[XIAllDevices]; else return other->mask[dev->id]; @@ -1937,6 +1954,159 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, return 1; } +static BOOL +ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win, + xEvent *event, Mask deliveryMask) +{ + GrabRec tempGrab; + OtherInputMasks *inputMasks; + CARD8 type = event->u.u.type; + GrabType grabtype; + + if (type == ButtonPress) + grabtype = GRABTYPE_CORE; + else if (type == DeviceButtonPress) + grabtype = GRABTYPE_XI; + else if ((type = xi2_get_type(event)) == XI_ButtonPress) + grabtype = GRABTYPE_XI2; + else + return FALSE; + + memset(&tempGrab, 0, sizeof(GrabRec)); + tempGrab.next = NULL; + tempGrab.device = dev; + tempGrab.resource = client->clientAsMask; + tempGrab.window = win; + tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE; + tempGrab.eventMask = deliveryMask; + tempGrab.keyboardMode = GrabModeAsync; + tempGrab.pointerMode = GrabModeAsync; + tempGrab.confineTo = NullWindow; + tempGrab.cursor = NullCursor; + tempGrab.type = type; + tempGrab.grabtype = grabtype; + + /* get the XI and XI2 device mask */ + inputMasks = wOtherInputMasks(win); + tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0; + + if (inputMasks) + memcpy(tempGrab.xi2mask, inputMasks->xi2mask, + sizeof(tempGrab.xi2mask)); + + (*dev->deviceGrab.ActivateGrab)(dev, &tempGrab, + currentTime, TRUE | ImplicitGrabMask); + return TRUE; +} + +enum EventDeliveryState { + EVENT_DELIVERED, /**< Event has been delivered to a client */ + EVENT_NOT_DELIVERED, /**< Event was not delivered to any client */ + EVENT_SKIP, /**< Event can be discarded by the caller */ + EVENT_REJECTED, /**< Event was rejected for delivery to the client */ +}; + +/** + * Attempt event delivery to the client owning the window. + */ +static enum EventDeliveryState +DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win, + xEvent *events, int count, Mask filter, + GrabPtr grab) +{ + /* if nobody ever wants to see this event, skip some work */ + if (filter != CantBeFiltered && + !((wOtherEventMasks(win)|win->eventMask) & filter)) + return EVENT_SKIP; + + if (IsInterferingGrab(wClient(win), dev, events)) + return EVENT_SKIP; + + if (!XaceHook(XACE_RECEIVE_ACCESS, wClient(win), win, events, count)) + { + int attempt = TryClientEvents(wClient(win), dev, events, + count, win->eventMask, + filter, grab); + if (attempt > 0) + return EVENT_DELIVERED; + if (attempt < 0) + return EVENT_REJECTED; + } + + return EVENT_NOT_DELIVERED; +} + +/** + * Deliver events to clients registered on the window. + * + * @param client_return On successful delivery, set to the recipient. + * @param mask_return On successful delivery, set to the recipient's event + * mask for this event. + */ +static enum EventDeliveryState +DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events, + int count, Mask filter, GrabPtr grab, + ClientPtr *client_return, Mask *mask_return) +{ + int attempt; + enum EventDeliveryState rc = EVENT_SKIP; + InputClients *other; + + if (core_get_type(events) != 0) + other = (InputClients *)wOtherClients(win); + else if (xi2_get_type(events) != 0) + { + OtherInputMasks *inputMasks = wOtherInputMasks(win); + /* Has any client selected for the event? */ + if (!GetWindowXI2Mask(dev, win, events)) + goto out; + other = inputMasks->inputClients; + } else { + OtherInputMasks *inputMasks = wOtherInputMasks(win); + /* Has any client selected for the event? */ + if (!inputMasks || + !(inputMasks->inputEvents[dev->id] & filter)) + goto out; + + other = inputMasks->inputClients; + } + + rc = EVENT_NOT_DELIVERED; + + for (; other; other = other->next) + { + Mask mask; + ClientPtr client = rClient(other); + + if (IsInterferingGrab(client, dev, events)) + continue; + + mask = GetEventMask(dev, events, other); + + if (XaceHook(XACE_RECEIVE_ACCESS, client, win, + events, count)) + /* do nothing */; + else if ( (attempt = TryClientEvents(client, dev, + events, count, + mask, filter, grab)) ) + { + if (attempt > 0) + { + rc = EVENT_DELIVERED; + *client_return = client; + *mask_return = mask; + /* Success overrides non-success, so if we've been + * successful on one client, return that */ + } else if (rc == EVENT_NOT_DELIVERED) + rc = EVENT_REJECTED; + } + } + +out: + return rc; +} + + /** * Deliver events to a window. At this point, we do not yet know if the event * actually needs to be delivered. May activate a grab if the event is a @@ -1955,152 +2125,84 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, * @param filter Mask based on event type. * @param grab Possible grab on the device that caused the event. * - * @return Number of events delivered to various clients. + * @return a positive number if at least one successful delivery has been + * made, 0 if no events were delivered, or a negative number if the event + * has not been delivered _and_ rejected by at least one client. */ int DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent *pEvents, int count, Mask filter, GrabPtr grab) { int deliveries = 0, nondeliveries = 0; - int attempt; - InputClients *other; ClientPtr client = NullClient; Mask deliveryMask = 0; /* If a grab occurs due to a button press, then this mask is the mask of the grab. */ int type = pEvents->u.u.type; - /* Deliver to window owner */ - if ((filter == CantBeFiltered) || CORE_EVENT(pEvents)) + if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0) { - /* if nobody ever wants to see this event, skip some work */ - if (filter != CantBeFiltered && - !((wOtherEventMasks(pWin)|pWin->eventMask) & filter)) - return 0; + enum EventDeliveryState rc; - if (IsInterferingGrab(wClient(pWin), pDev, pEvents)) + rc = DeliverToWindowOwner(pDev, pWin, pEvents, count, filter, grab); + + switch(rc) + { + case EVENT_SKIP: return 0; - - if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count)) - /* do nothing */; - else if ( (attempt = TryClientEvents(wClient(pWin), pDev, pEvents, - count, pWin->eventMask, - filter, grab)) ) - { - if (attempt > 0) - { - deliveries++; - client = wClient(pWin); - deliveryMask = pWin->eventMask; - } else - nondeliveries--; - } + case EVENT_REJECTED: + nondeliveries--; + break; + case EVENT_DELIVERED: + /* We delivered to the owner, with our event mask */ + deliveries++; + client = wClient(pWin); + deliveryMask = pWin->eventMask; + break; + case EVENT_NOT_DELIVERED: + break; + } } /* CantBeFiltered means only window owner gets the event */ if (filter != CantBeFiltered) { - if (CORE_EVENT(pEvents)) - other = (InputClients *)wOtherClients(pWin); - else if (XI2_EVENT(pEvents)) + enum EventDeliveryState rc; + + rc = DeliverEventToClients(pDev, pWin, pEvents, count, filter, grab, + &client, &deliveryMask); + + switch(rc) { - OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - /* Has any client selected for the event? */ - if (!GetWindowXI2Mask(pDev, pWin, pEvents)) + case EVENT_SKIP: return 0; - other = inputMasks->inputClients; - } else { - OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - /* Has any client selected for the event? */ - if (!inputMasks || - !(inputMasks->inputEvents[pDev->id] & filter)) - return 0; - - other = inputMasks->inputClients; - } - - for (; other; other = other->next) - { - Mask mask; - if (IsInterferingGrab(rClient(other), pDev, pEvents)) - continue; - - mask = GetEventMask(pDev, pEvents, other); - - if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, - pEvents, count)) - /* do nothing */; - else if ( (attempt = TryClientEvents(rClient(other), pDev, - pEvents, count, - mask, filter, grab)) ) - { - if (attempt > 0) - { - deliveries++; - client = rClient(other); - deliveryMask = mask; - } else - nondeliveries--; - } + case EVENT_REJECTED: + nondeliveries--; + break; + case EVENT_DELIVERED: + deliveries++; + break; + case EVENT_NOT_DELIVERED: + break; } } - /* - * Note that since core events are delivered first, an implicit grab may - * be activated on a core grab, stopping the XI events. - */ - if ((type == DeviceButtonPress || type == ButtonPress || - ((XI2_EVENT(pEvents) && ((xGenericEvent*)pEvents)->evtype == XI_ButtonPress))) - && deliveries - && (!grab)) - { - GrabRec tempGrab; - OtherInputMasks *inputMasks; - memset(&tempGrab, 0, sizeof(GrabRec)); - tempGrab.next = NULL; - tempGrab.device = pDev; - tempGrab.resource = client->clientAsMask; - tempGrab.window = pWin; - tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE; - tempGrab.eventMask = deliveryMask; - tempGrab.keyboardMode = GrabModeAsync; - tempGrab.pointerMode = GrabModeAsync; - tempGrab.confineTo = NullWindow; - tempGrab.cursor = NullCursor; - tempGrab.type = type; - if (type == ButtonPress) - tempGrab.grabtype = GRABTYPE_CORE; - else if (type == DeviceButtonPress) - tempGrab.grabtype = GRABTYPE_XI; - else - { - tempGrab.type = ((xGenericEvent*)pEvents)->evtype; - tempGrab.grabtype = GRABTYPE_XI2; - } - - /* get the XI and XI2 device mask */ - inputMasks = wOtherInputMasks(pWin); - tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0; - - if (inputMasks) - memcpy(tempGrab.xi2mask, inputMasks->xi2mask, - sizeof(tempGrab.xi2mask)); - - (*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab, - currentTime, TRUE | ImplicitGrabMask); - } - else if ((type == MotionNotify) && deliveries) - pDev->valuator->motionHintWindow = pWin; - else - { - if ((type == DeviceMotionNotify || type == DeviceButtonPress) && - deliveries) - CheckDeviceGrabAndHintWindow (pWin, type, - (deviceKeyButtonPointer*) pEvents, - grab, client, deliveryMask); - } if (deliveries) + { + /* + * Note that since core events are delivered first, an implicit grab may + * be activated on a core grab, stopping the XI events. + */ + if (!grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask)) + /* grab activated */; + else if ((type == MotionNotify)) + pDev->valuator->motionHintWindow = pWin; + else if (type == DeviceMotionNotify || type == DeviceButtonPress) + CheckDeviceGrabAndHintWindow (pWin, type, + (deviceKeyButtonPointer*) pEvents, + grab, client, deliveryMask); return deliveries; + } return nondeliveries; } @@ -2180,7 +2282,7 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents, static Window FindChildForEvent(SpritePtr pSprite, WindowPtr event) { - WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1]; + WindowPtr w = DeepestSpriteWin(pSprite); Window child = None; /* If the search ends up past the root should the child field be @@ -2224,22 +2326,29 @@ FixUpEventFromWindow( Window child, Bool calcChild) { + int evtype; + if (calcChild) child = FindChildForEvent(pSprite, pWin); - if (XI2_EVENT(xE)) + if ((evtype = xi2_get_type(xE))) { xXIDeviceEvent* event = (xXIDeviceEvent*)xE; - if (event->evtype == XI_RawKeyPress || - event->evtype == XI_RawKeyRelease || - event->evtype == XI_RawButtonPress || - event->evtype == XI_RawButtonRelease || - event->evtype == XI_RawMotion || - event->evtype == XI_DeviceChanged || - event->evtype == XI_HierarchyChanged || - event->evtype == XI_PropertyEvent) - return; + switch (evtype) + { + case XI_RawKeyPress: + case XI_RawKeyRelease: + case XI_RawButtonPress: + case XI_RawButtonRelease: + case XI_RawMotion: + case XI_DeviceChanged: + case XI_HierarchyChanged: + case XI_PropertyEvent: + return; + default: + break; + } event->root = RootWindow(pSprite)->drawable.id; event->event = pWin->drawable.id; @@ -2375,7 +2484,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, xEvent *xE = NULL, *core = NULL; int rc, mask, count = 0; - CHECKEVENT(event); + verify_internal_event(event); while (pWin) { @@ -2623,7 +2732,7 @@ XYToWindow(SpritePtr pSprite, int x, int y) else pWin = pWin->nextSib; } - return pSprite->spriteTrace[pSprite->spriteTraceGood-1]; + return DeepestSpriteWin(pSprite); } /** @@ -2661,7 +2770,8 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) event.deviceid = dev->id; event.sourceid = dev->id; event.detail.button = 0; - rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL); + rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE, + TRUE) != NULL); if (rc) DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); return rc; @@ -2698,7 +2808,8 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) event.deviceid = dev->id; event.sourceid = dev->id; event.detail.button = 0; - rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL); + rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE, + TRUE) != NULL); if (rc) DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab); return rc; @@ -2721,7 +2832,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev) WindowPtr prevSpriteWin, newSpriteWin; SpritePtr pSprite = pDev->spriteInfo->sprite; - CHECKEVENT(ev); + verify_internal_event(ev); prevSpriteWin = pSprite->win; @@ -3385,7 +3496,7 @@ GrabPtr CheckPassiveGrabsOnWindow( WindowPtr pWin, DeviceIntPtr device, - DeviceEvent *event, + InternalEvent *event, BOOL checkCore, BOOL activate) { @@ -3402,9 +3513,22 @@ CheckPassiveGrabsOnWindow( return NULL; /* Fill out the grab details, but leave the type for later before * comparing */ + switch (event->any.type) + { + case ET_KeyPress: + case ET_KeyRelease: + tempGrab.detail.exact = event->device_event.detail.key; + break; + case ET_ButtonPress: + case ET_ButtonRelease: + tempGrab.detail.exact = event->device_event.detail.button; + break; + default: + tempGrab.detail.exact = 0; + break; + } tempGrab.window = pWin; tempGrab.device = device; - tempGrab.detail.exact = event->detail.key; tempGrab.detail.pMask = NULL; tempGrab.modifiersDetail.pMask = NULL; tempGrab.next = NULL; @@ -3412,6 +3536,8 @@ CheckPassiveGrabsOnWindow( { DeviceIntPtr gdev; XkbSrvInfoPtr xkbi = NULL; + xEvent *xE = NULL; + int count, rc; gdev= grab->modifierDevice; if (grab->grabtype == GRABTYPE_CORE) @@ -3437,16 +3563,15 @@ CheckPassiveGrabsOnWindow( tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0; /* Check for XI2 and XI grabs first */ - tempGrab.type = GetXI2Type((InternalEvent*)event); + tempGrab.type = GetXI2Type(event); tempGrab.grabtype = GRABTYPE_XI2; if (GrabMatchesSecond(&tempGrab, grab, FALSE)) match = XI2_MATCH; - tempGrab.detail.exact = event->detail.key; if (!match) { tempGrab.grabtype = GRABTYPE_XI; - if ((tempGrab.type = GetXIType((InternalEvent*)event)) && + if ((tempGrab.type = GetXIType(event)) && (GrabMatchesSecond(&tempGrab, grab, FALSE))) match = XI_MATCH; } @@ -3455,122 +3580,134 @@ CheckPassiveGrabsOnWindow( if (!match && checkCore) { tempGrab.grabtype = GRABTYPE_CORE; - if ((tempGrab.type = GetCoreType((InternalEvent*)event)) && + if ((tempGrab.type = GetCoreType(event)) && (GrabMatchesSecond(&tempGrab, grab, TRUE))) match = CORE_MATCH; } - if (match && (!grab->confineTo || - (grab->confineTo->realized && - BorderSizeNotEmpty(device, grab->confineTo)))) - { - int rc, count = 0; - xEvent *xE = NULL; + if (!match || (grab->confineTo && + (!grab->confineTo->realized || + !BorderSizeNotEmpty(device, grab->confineTo)))) + continue; - event->corestate &= 0x1f00; - event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00); - grabinfo = &device->deviceGrab; - /* In some cases a passive core grab may exist, but the client - * already has a core grab on some other device. In this case we - * must not get the grab, otherwise we may never ungrab the - * device. - */ + grabinfo = &device->deviceGrab; + /* In some cases a passive core grab may exist, but the client + * already has a core grab on some other device. In this case we + * must not get the grab, otherwise we may never ungrab the + * device. + */ - if (grab->grabtype == GRABTYPE_CORE) + if (grab->grabtype == GRABTYPE_CORE) + { + DeviceIntPtr other; + BOOL interfering = FALSE; + + /* A passive grab may have been created for a different device + than it is assigned to at this point in time. + Update the grab's device and modifier device to reflect the + current state. + Since XGrabDeviceButton requires to specify the + modifierDevice explicitly, we don't override this choice. + */ + if (tempGrab.type < GenericEvent) { - DeviceIntPtr other; - BOOL interfering = FALSE; - - /* A passive grab may have been created for a different device - than it is assigned to at this point in time. - Update the grab's device and modifier device to reflect the - current state. - Since XGrabDeviceButton requires to specify the - modifierDevice explicitly, we don't override this choice. - */ - if (tempGrab.type < GenericEvent) - { - grab->device = device; - grab->modifierDevice = GetPairedDevice(device); - } - - for (other = inputInfo.devices; other; other = other->next) - { - GrabPtr othergrab = other->deviceGrab.grab; - if (othergrab && othergrab->grabtype == GRABTYPE_CORE && - SameClient(grab, rClient(othergrab)) && - ((IsPointerDevice(grab->device) && - IsPointerDevice(othergrab->device)) || - (IsKeyboardDevice(grab->device) && - IsKeyboardDevice(othergrab->device)))) - { - interfering = TRUE; - break; - } - } - if (interfering) - continue; + grab->device = device; + grab->modifierDevice = GetPairedDevice(device); } - if (!activate) - return grab; - - if (match & CORE_MATCH) + for (other = inputInfo.devices; other; other = other->next) { - rc = EventToCore((InternalEvent*)event, &xE, &count); - if (rc != Success) + GrabPtr othergrab = other->deviceGrab.grab; + if (othergrab && othergrab->grabtype == GRABTYPE_CORE && + SameClient(grab, rClient(othergrab)) && + ((IsPointerDevice(grab->device) && + IsPointerDevice(othergrab->device)) || + (IsKeyboardDevice(grab->device) && + IsKeyboardDevice(othergrab->device)))) { - if (rc != BadMatch) - ErrorF("[dix] %s: core conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->type, rc); - continue; - } - } else if (match & XI2_MATCH) - { - rc = EventToXI2((InternalEvent*)event, &xE); - if (rc != Success) - { - if (rc != BadMatch) - ErrorF("[dix] %s: XI2 conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->type, rc); - continue; - } - count = 1; - } else - { - rc = EventToXI((InternalEvent*)event, &xE, &count); - if (rc != Success) - { - if (rc != BadMatch) - ErrorF("[dix] %s: XI conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->type, rc); - continue; + interfering = TRUE; + break; } } + if (interfering) + continue; + } - (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); + if (!activate) + { + return grab; + } + else if (!GetXIType(event) && !GetCoreType(event)) + { + ErrorF("Event type %d in CheckPassiveGrabsOnWindow is neither" + " XI 1.x nor core\n", event->any.type); + return NULL; + } - if (xE) + /* The only consumers of corestate are Xi 1.x and core events, which + * are guaranteed to come from DeviceEvents. */ + if (match & (XI_MATCH | CORE_MATCH)) + { + event->device_event.corestate &= 0x1f00; + event->device_event.corestate |= tempGrab.modifiersDetail.exact & + (~0x1f00); + } + + if (match & CORE_MATCH) + { + rc = EventToCore(event, &xE, &count); + if (rc != Success) { - FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE); - - /* XXX: XACE? */ - TryClientEvents(rClient(grab), device, xE, count, - GetEventFilter(device, xE), - GetEventFilter(device, xE), grab); + if (rc != BadMatch) + ErrorF("[dix] %s: core conversion failed in CPGFW " + "(%d, %d).\n", device->name, event->any.type, rc); + continue; } - - if (grabinfo->sync.state == FROZEN_NO_EVENT) - { - if (!grabinfo->sync.event) - grabinfo->sync.event = calloc(1, sizeof(InternalEvent)); - *grabinfo->sync.event = *event; - grabinfo->sync.state = FROZEN_WITH_EVENT; + } else if (match & XI2_MATCH) + { + rc = EventToXI2(event, &xE); + if (rc != Success) + { + if (rc != BadMatch) + ErrorF("[dix] %s: XI2 conversion failed in CPGFW " + "(%d, %d).\n", device->name, event->any.type, rc); + continue; } + count = 1; + } else + { + rc = EventToXI(event, &xE, &count); + if (rc != Success) + { + if (rc != BadMatch) + ErrorF("[dix] %s: XI conversion failed in CPGFW " + "(%d, %d).\n", device->name, event->any.type, rc); + continue; + } + } - free(xE); - return grab; - } + (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); + + if (xE) + { + FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE); + + /* XXX: XACE? */ + TryClientEvents(rClient(grab), device, xE, count, + GetEventFilter(device, xE), + GetEventFilter(device, xE), grab); + } + + if (grabinfo->sync.state == FROZEN_NO_EVENT) + { + if (!grabinfo->sync.event) + grabinfo->sync.event = calloc(1, sizeof(DeviceEvent)); + *grabinfo->sync.event = event->device_event; + grabinfo->sync.state = FROZEN_WITH_EVENT; + } + + free(xE); + return grab; } return NULL; #undef CORE_MATCH @@ -3639,7 +3776,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) for (; i < focus->traceGood; i++) { pWin = focus->trace[i]; - if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE)) + if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event, + sendCore, TRUE)) { ret = TRUE; goto out; @@ -3655,7 +3793,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) for (; i < device->spriteInfo->sprite->spriteTraceGood; i++) { pWin = device->spriteInfo->sprite->spriteTrace[i]; - if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE)) + if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event, + sendCore, TRUE)) { ret = TRUE; goto out; @@ -3766,8 +3905,10 @@ unwind: * grab. If not, TryClientEvents() is used. * * @param deactivateGrab True if the device's grab should be deactivated. + * + * @return The number of events delivered. */ -void +int DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, Bool deactivateGrab) { @@ -3935,6 +4076,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, free(core); free(xi); free(xi2); + + return deliveries; } /* This function is used to set the key pressed or key released state - @@ -4977,12 +5120,9 @@ InitEvents(void) inputInfo.off_devices = (DeviceIntPtr)NULL; inputInfo.keyboard = (DeviceIntPtr)NULL; inputInfo.pointer = (DeviceIntPtr)NULL; - /* The mask for pointer motion events may have changed in the last server - * generation. See comment above definition of filters. */ - filters[0][PointerMotionMask] = MotionNotify; - for (i = 1; i < MAXDEVICES; i++) + for (i = 0; i < MAXDEVICES; i++) { - memcpy(&filters[i], filters[0], sizeof(filters[0])); + memcpy(&filters[i], default_filter, sizeof(default_filter)); } syncEvents.replayDev = (DeviceIntPtr)NULL; @@ -5006,8 +5146,7 @@ InitEvents(void) DontPropagateRefCnts[i] = 0; } - InputEventListLen = GetMaximumEventsNum(); - InputEventList = InitEventList(InputEventListLen); + InputEventList = InitEventList(GetMaximumEventsNum()); if (!InputEventList) FatalError("[dix] Failed to allocate input event list.\n"); } @@ -5015,8 +5154,7 @@ InitEvents(void) void CloseDownEvents(void) { - FreeEventList(InputEventList, InputEventListLen); - InputEventListLen = 0; + FreeEventList(InputEventList, GetMaximumEventsNum()); InputEventList = NULL; } diff --git a/dix/getevents.c b/dix/getevents.c index 4267b61cb..13789f6a2 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -47,6 +47,7 @@ #include "eventstr.h" #include "eventconvert.h" #include "inpututils.h" +#include "mi.h" #include #include "xkbsrv.h" @@ -67,19 +68,12 @@ /* Number of motion history events to store. */ #define MOTION_HISTORY_SIZE 256 -/* InputEventList is the container list for all input events generated by the - * DDX. The DDX is expected to call GetEventList() and then pass the list into - * Get{Pointer|Keyboard}Events. +/** + * InputEventList is the storage for input events generated by + * QueuePointerEvents, QueueKeyboardEvents, and QueueProximityEvents. + * This list is allocated on startup by the DIX. */ -EventListPtr InputEventList = NULL; -int InputEventListLen = 0; - -int -GetEventList(EventListPtr* list) -{ - *list = InputEventList; - return InputEventListLen; -} +InternalEvent* InputEventList = NULL; /** * Pick some arbitrary size for Xi motion history. @@ -223,7 +217,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask) } void -CreateClassesChangedEvent(EventList* event, +CreateClassesChangedEvent(InternalEvent* event, DeviceIntPtr master, DeviceIntPtr slave, int type) @@ -232,7 +226,7 @@ CreateClassesChangedEvent(EventList* event, DeviceChangedEvent *dce; CARD32 ms = GetTimeInMillis(); - dce = (DeviceChangedEvent*)event->event; + dce = &event->changed_event; memset(dce, 0, sizeof(DeviceChangedEvent)); dce->deviceid = slave->id; dce->masterid = master->id; @@ -676,15 +670,15 @@ clipValuators(DeviceIntPtr pDev, ValuatorMask *mask) * is done in the event processing). * Pull in the coordinates from the MD if necessary. * - * @param events Pointer to a pre-allocated event list. + * @param events Pointer to a pre-allocated event array. * @param dev The slave device that generated an event. * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT * @param num_events The current number of events, returns the number of * events if a DCCE was generated. * @return The updated @events pointer. */ -EventListPtr -UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events) +InternalEvent* +UpdateFromMaster(InternalEvent* events, DeviceIntPtr dev, int type, int *num_events) { DeviceIntPtr master; @@ -924,16 +918,49 @@ updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms) } } +static void +queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents) +{ + int i; + for (i = 0; i < nevents; i++) + mieqEnqueue(device, &events[i]); +} + +/** + * Generate internal events representing this keyboard event and enqueue + * them on the event queue. + * + * This function is not reentrant. Disable signals before calling. + * + * FIXME: flags for relative/abs motion? + * + * @param device The device to generate the event for + * @param type Event type, one of KeyPress or KeyRelease + * @param keycode Key code of the pressed/released key + * @param mask Valuator mask for valuators present for this event. + * + */ +void +QueueKeyboardEvents(DeviceIntPtr device, int type, + int keycode, const ValuatorMask *mask) +{ + int nevents; + + nevents = GetKeyboardEvents(InputEventList, device, type, keycode, mask); + queueEventList(device, InputEventList, nevents); +} + /** * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally * also with valuator events. * - * events is not NULL-terminated; the return value is the number of events. - * The DDX is responsible for allocating the event structure in the first - * place via GetMaximumEventsNum(), and for freeing it. + * The DDX is responsible for allocating the event list in the first + * place via InitEventList(), and for freeing it. + * + * @return the number of events written into events. */ int -GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, +GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int key_code, const ValuatorMask *mask_in) { int num_events = 0; CARD32 ms = 0; @@ -966,7 +993,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, ms = GetTimeInMillis(); - raw = (RawDeviceEvent*)events->event; + raw = &events->raw_event; events++; num_events++; @@ -979,7 +1006,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, set_raw_valuators(raw, &mask, raw->valuators.data); - event = (DeviceEvent*) events->event; + event = &events->device_event; init_event(pDev, event, ms); event->detail.key = key_code; @@ -1000,37 +1027,16 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, } /** - * Initialize an event list and fill with 32 byte sized events. + * Initialize an event array large enough for num_events arrays. * This event list is to be passed into GetPointerEvents() and * GetKeyboardEvents(). * * @param num_events Number of elements in list. */ -EventListPtr +InternalEvent* InitEventList(int num_events) { - EventListPtr events; - int i; - - events = (EventListPtr)calloc(num_events, sizeof(EventList)); - if (!events) - return NULL; - - for (i = 0; i < num_events; i++) - { - events[i].evlen = sizeof(InternalEvent); - events[i].event = calloc(1, sizeof(InternalEvent)); - if (!events[i].event) - { - /* rollback */ - while(i--) - free(events[i].event); - free(events); - events = NULL; - break; - } - } - + InternalEvent *events = calloc(num_events, sizeof(InternalEvent)); return events; } @@ -1041,41 +1047,50 @@ InitEventList(int num_events) * @param num_events Number of elements in list. */ void -FreeEventList(EventListPtr list, int num_events) +FreeEventList(InternalEvent *list, int num_events) { - if (!list) - return; - while(num_events--) - free(list[num_events].event); free(list); } static void -transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask) +transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y) { - struct pixman_f_vector p; - - /* p' = M * p in homogeneous coordinates */ - p.v[0] = (valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) : - dev->last.valuators[0]); - p.v[1] = (valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) : - dev->last.valuators[1]); - p.v[2] = 1.0; + struct pixman_f_vector p = {.v = {*x, *y, 1}}; pixman_f_transform_point(&dev->transform, &p); - if (lround(p.v[0]) != dev->last.valuators[0]) - valuator_mask_set(mask, 0, lround(p.v[0])); - if (lround(p.v[1]) != dev->last.valuators[1]) - valuator_mask_set(mask, 1, lround(p.v[1])); + *x = lround(p.v[0]); + *y = lround(p.v[1]); } /** - * Generate a series of InternalEvents (filled into the EventList) - * representing pointer motion, or button presses. + * Generate internal events representing this pointer event and enqueue them + * on the event queue. * - * events is not NULL-terminated; the return value is the number of events. - * The DDX is responsible for allocating the event structure in the first + * This function is not reentrant. Disable signals before calling. + * + * @param device The device to generate the event for + * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify + * @param buttons Button number of the buttons modified. Must be 0 for + * MotionNotify + * @param flags Event modification flags + * @param mask Valuator mask for valuators present for this event. + */ +void +QueuePointerEvents(DeviceIntPtr device, int type, + int buttons, int flags, const ValuatorMask *mask) +{ + int nevents; + + nevents = GetPointerEvents(InputEventList, device, type, buttons, flags, mask); + queueEventList(device, InputEventList, nevents); +} + +/** + * Generate a series of InternalEvents representing pointer motion, or + * button presses. + * + * The DDX is responsible for allocating the events in the first * place via InitEventList() and GetMaximumEventsNum(), and for freeing it. * * In the generated events rootX/Y will be in absolute screen coords and @@ -1085,9 +1100,11 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask) * last.valuators[x] of the master device is in absolute screen coords. * * master->last.valuators[x] for x > 2 is undefined. + * + * @return the number of events written into events. */ int -GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, +GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons, int flags, const ValuatorMask *mask_in) { int num_events = 1; CARD32 ms; @@ -1125,7 +1142,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); - raw = (RawDeviceEvent*)events->event; + raw = &events->raw_event; events++; num_events++; @@ -1158,7 +1175,16 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, } } - transformAbsolute(pDev, &mask); + x = (valuator_mask_isset(&mask, 0) ? valuator_mask_get(&mask, 0) : + pDev->last.valuators[0]); + y = (valuator_mask_isset(&mask, 1) ? valuator_mask_get(&mask, 1) : + pDev->last.valuators[1]); + transformAbsolute(pDev, &mask, &x, &y); + if (valuator_mask_isset(&mask, 0)) + valuator_mask_set(&mask, 0, x); + if (valuator_mask_isset(&mask, 1)) + valuator_mask_set(&mask, 1, y); + moveAbsolute(pDev, &x, &y, &mask); } else { if (flags & POINTER_ACCELERATE) { @@ -1185,7 +1211,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, clipValuators(pDev, &mask); - event = (DeviceEvent*) events->event; + event = &events->device_event; init_event(pDev, event, ms); if (type == MotionNotify) { @@ -1214,17 +1240,39 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, return num_events; } +/** + * Generate internal events representing this proximity event and enqueue + * them on the event queue. + * + * This function is not reentrant. Disable signals before calling. + * + * @param device The device to generate the event for + * @param type Event type, one of ProximityIn or ProximityOut + * @param keycode Key code of the pressed/released key + * @param mask Valuator mask for valuators present for this event. + * + */ +void +QueueProximityEvents(DeviceIntPtr device, int type, + const ValuatorMask *mask) +{ + int nevents; + + nevents = GetProximityEvents(InputEventList, device, type, mask); + queueEventList(device, InputEventList, nevents); +} /** * Generate ProximityIn/ProximityOut InternalEvents, accompanied by * valuators. * - * events is not NULL-terminated; the return value is the number of events. - * The DDX is responsible for allocating the event structure in the first - * place via GetMaximumEventsNum(), and for freeing it. + * The DDX is responsible for allocating the events in the first place via + * InitEventList(), and for freeing it. + * + * @return the number of events written into events. */ int -GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in) +GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in) { int num_events = 1, i; DeviceEvent *event; @@ -1256,7 +1304,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const Valuato events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); - event = (DeviceEvent *) events->event; + event = &events->device_event; init_event(pDev, event, GetTimeInMillis()); event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut; diff --git a/dix/inpututils.c b/dix/inpututils.c index 077ffce01..aeace6ef8 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -36,6 +36,7 @@ #include "xkbsrv.h" #include "xkbstr.h" #include "inpututils.h" +#include "eventstr.h" /* Check if a button map change is okay with the device. * Returns -1 for BadValue, as it collides with MappingBusy. */ @@ -556,3 +557,30 @@ CountBits(const uint8_t *mask, int len) return ret; } + +/** + * Verifies sanity of the event. If the event is not an internal event, + * memdumps the first 32 bytes of event to the log, a backtrace, then kill + * the server. + */ +void verify_internal_event(const InternalEvent *ev) +{ + if (ev && ev->any.header != ET_Internal) + { + int i; + unsigned char *data = (unsigned char*)ev; + + ErrorF("dix: invalid event type %d\n", ev->any.header); + + for (i = 0; i < sizeof(xEvent); i++, data++) + { + ErrorF("%02hx ", *data); + + if ((i % 8) == 7) + ErrorF("\n"); + } + + xorg_backtrace(); + FatalError("Wrong event type %d. Aborting server\n", ev->any.header); + } +} diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c index 15d80f5bb..41bc4bf2d 100644 --- a/hw/dmx/input/dmxevents.c +++ b/hw/dmx/input/dmxevents.c @@ -176,19 +176,15 @@ static void enqueueMotion(DevicePtr pDev, int x, int y) { GETDMXLOCALFROMPDEV; DeviceIntPtr p = dmxLocal->pDevice; - int i, nevents, valuators[3]; - EventListPtr events; + int valuators[3]; int detail = 0; /* XXX should this be mask of pressed buttons? */ ValuatorMask mask; valuators[0] = x; valuators[1] = y; valuator_mask_set_range(&mask, 0, 2, valuators); - GetEventList(&events); - nevents = GetPointerEvents(events, p, MotionNotify, detail, - POINTER_ABSOLUTE | POINTER_SCREEN, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(p, (InternalEvent*)(events + i)->event); + QueuePointerEvents(p, MotionNotify, detail, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); return; } @@ -291,10 +287,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, deviceValuator *xv = (deviceValuator *)xev+1; int thisX = 0; int thisY = 0; - int i; int count; - EventListPtr events; - int nevents; ValuatorMask mask; memset(xE, 0, sizeof(xE)); @@ -348,6 +341,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, } count = 2; } else { + int i; for (i = 0, count = 0; i < axesCount; i += 6) { xev->time = GetTimeInMillis(); xev->type = DeviceMotionNotify; @@ -375,11 +369,8 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal, if (block) dmxSigioBlock(); valuator_mask_set_range(&mask, firstAxis, axesCount, v); - GetEventList(&events); - nevents = GetPointerEvents(events, pDevice, MotionNotify, 0, - POINTER_ABSOLUTE, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event); + QueuePointerEvents(pDevice, MotionNotify, 0, + POINTER_ABSOLUTE, &mask); if (block) dmxSigioUnblock(); @@ -394,8 +385,6 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, XDeviceMotionEvent *me = (XDeviceMotionEvent *)e; DeviceIntPtr pDevice = dmxLocal->pDevice; int valuators[MAX_VALUATORS]; - EventListPtr events; - int nevents, i; ValuatorMask mask; if (!e) @@ -452,12 +441,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators); if (block) dmxSigioBlock(); - GetEventList(&events); - nevents = GetKeyboardEvents(events, pDevice, event, - ke->keycode, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event); - + QueueKeyboardEvents(pDevice, event, ke->keycode, &mask); if (block) dmxSigioUnblock(); break; @@ -467,12 +451,8 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators); if (block) dmxSigioBlock(); - GetEventList(&events); - nevents = GetPointerEvents(events, pDevice, event, ke->keycode, - POINTER_ABSOLUTE, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event); - + QueuePointerEvents(pDevice, event, ke->keycode, + POINTER_ABSOLUTE, &mask); if (block) dmxSigioUnblock(); break; @@ -482,11 +462,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators); if (block) dmxSigioBlock(); - GetEventList(&events); - nevents = GetProximityEvents(events, pDevice, event, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event); - + QueueProximityEvents(pDevice, event, &mask); if (block) dmxSigioUnblock(); break; @@ -667,8 +643,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, GETDMXINPUTFROMPDEV; xEvent xE; DeviceIntPtr p = dmxLocal->pDevice; - int i, nevents, valuators[3]; - EventListPtr events; + int valuators[3]; ValuatorMask mask; DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail); @@ -683,34 +658,25 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym, if (dmxLocal->sendsCore && dmxLocal != dmxLocalCoreKeyboard) xE.u.u.detail = dmxFixup(pDev, detail, keySym); - GetEventList(&events); /*ErrorF("KEY %d sym %d\n", detail, (int) keySym);*/ - nevents = GetKeyboardEvents(events, p, type, detail, NULL); - for (i = 0; i < nevents; i++) - mieqEnqueue(p, (InternalEvent*)(events + i)->event); + QueueKeyboardEvents(p, type, detail, NULL); return; case ButtonPress: case ButtonRelease: detail = dmxGetButtonMapping(dmxLocal, detail); valuator_mask_zero(&mask); - GetEventList(&events); - nevents = GetPointerEvents(events, p, type, detail, - POINTER_ABSOLUTE | POINTER_SCREEN, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(p, (InternalEvent*)(events + i)->event); + QueuePointerEvents(p, type, detail, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); return; case MotionNotify: - GetEventList(&events); valuators[0] = e->xmotion.x; valuators[1] = e->xmotion.y; valuators[2] = e->xmotion.state; /* FIXME: WTF?? */ valuator_mask_set_range(&mask, 0, 3, valuators); - nevents = GetPointerEvents(events, p, type, detail, - POINTER_ABSOLUTE | POINTER_SCREEN, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(p, (InternalEvent*)(events + i)->event); + QueuePointerEvents(p, type, detail, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); return; case EnterNotify: diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index f21475fb6..cdf55d7f9 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -66,8 +66,6 @@ static struct KdConfigDevice *kdConfigPointers = NULL; static KdKeyboardDriver *kdKeyboardDrivers = NULL; static KdPointerDriver *kdPointerDrivers = NULL; -static EventListPtr kdEvents = NULL; - static Bool kdInputEnabled; static Bool kdOffScreen; static unsigned long kdOffScreenTime; @@ -1793,7 +1791,7 @@ void KdReleaseAllKeys (void) { #if 0 - int key, nEvents, i; + int key; KdKeyboardInfo *ki; KdBlockSigio (); @@ -1803,10 +1801,7 @@ KdReleaseAllKeys (void) key++) { if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) { KdHandleKeyboardEvent(ki, KeyRelease, key); - GetEventList(&kdEvents); - nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key, NULL); - for (i = 0; i < nEvents; i++) - KdQueueEvent (ki->dixdev, (kdEvents + i)->event); + QueueGetKeyboardEvents(ki->dixdev, KeyRelease, key, NULL); } } } @@ -1842,7 +1837,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, unsigned char key_code; KeyClassPtr keyc = NULL; KeybdCtrl *ctrl = NULL; - int type, nEvents, i; + int type; if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) return; @@ -1862,11 +1857,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, else type = KeyPress; - GetEventList(&kdEvents); - - nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code, NULL); - for (i = 0; i < nEvents; i++) - KdQueueEvent(ki->dixdev, (InternalEvent *)((kdEvents + i)->event)); + QueueKeyboardEvents(ki->dixdev, type, key_code, NULL); } else { ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", @@ -1965,7 +1956,6 @@ void _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b, int absrel, Bool force) { - int nEvents = 0, i = 0; int valuators[3] = { x, y, z }; ValuatorMask mask; @@ -1975,10 +1965,7 @@ _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, valuator_mask_set_range(&mask, 0, 3, valuators); - GetEventList(&kdEvents); - nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask); - for (i = 0; i < nEvents; i++) - KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event)); + QueuePointerEvents(pi->dixdev, type, b, absrel, &mask); } void diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 3006ad183..c4a4db9be 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -376,7 +376,7 @@ static void xf86ReleaseKeys(DeviceIntPtr pDev) { KeyClassPtr keyc; - int i, j, nevents, sigstate; + int i, sigstate; if (!pDev || !pDev->key) return; @@ -399,9 +399,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev) i++) { if (key_is_down(pDev, i, KEY_POSTED)) { sigstate = xf86BlockSIGIO (); - nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL); - for (j = 0; j < nevents; j++) - mieqEnqueue(pDev, (InternalEvent*)(xf86Events + j)->event); + QueueKeyboardEvents(pDev, KeyRelease, i, NULL); xf86UnblockSIGIO(sigstate); } } diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 0b36163c0..53f763aaf 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -806,8 +806,6 @@ InitInput(int argc, char **argv) mieqInit(); - GetEventList(&xf86Events); - /* Initialize all configured input devices */ for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) { /* Replace obsolete keyboard driver with kbd */ diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 7137a5363..5d91ab367 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -148,9 +148,6 @@ extern _X_EXPORT int xf86SetVerbosity(int verb); extern _X_EXPORT int xf86SetLogVerbosity(int verb); extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only ); -/* xf86Xinput.c */ -extern _X_EXPORT EventList *xf86Events; - #endif /* _NO_XF86_PROTOTYPES */ diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index ef4542c5f..e7e1ce1f0 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -99,8 +99,6 @@ return; \ } -EventListPtr xf86Events = NULL; - static int xf86InputDevicePostInit(DeviceIntPtr dev); @@ -329,8 +327,8 @@ xf86ActivateDevice(InputInfoPtr pInfo) dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL); if (serverGeneration == 1) - xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n", - pInfo->name, pInfo->type_name); + xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s, id %d)\n", + pInfo->name, pInfo->type_name, dev->id); return dev; } @@ -1012,7 +1010,6 @@ xf86PostMotionEventM(DeviceIntPtr device, int is_absolute, const ValuatorMask *mask) { - int i = 0, nevents = 0; int flags = 0; if (valuator_mask_num_valuators(mask) > 0) @@ -1050,11 +1047,7 @@ xf86PostMotionEventM(DeviceIntPtr device, } #endif - nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask); - - for (i = 0; i < nevents; i++) { - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); - } + QueuePointerEvents(device, MotionNotify, 0, flags, mask); } void @@ -1099,13 +1092,7 @@ xf86PostProximityEventM(DeviceIntPtr device, int is_in, const ValuatorMask *mask) { - int i, nevents; - - nevents = GetProximityEvents(xf86Events, device, - is_in ? ProximityIn : ProximityOut, mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); - + QueueProximityEvents(device, is_in ? ProximityIn : ProximityOut, mask); } void @@ -1157,7 +1144,6 @@ xf86PostButtonEventM(DeviceIntPtr device, int is_down, const ValuatorMask *mask) { - int i = 0, nevents = 0; int flags = 0; if (valuator_mask_num_valuators(mask) > 0) @@ -1177,13 +1163,9 @@ xf86PostButtonEventM(DeviceIntPtr device, } #endif - nevents = GetPointerEvents(xf86Events, device, - is_down ? ButtonPress : ButtonRelease, button, - flags, mask); - - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); - + QueuePointerEvents(device, + is_down ? ButtonPress : ButtonRelease, button, + flags, mask); } void @@ -1235,8 +1217,6 @@ xf86PostKeyEventM(DeviceIntPtr device, int is_absolute, const ValuatorMask *mask) { - int i = 0, nevents = 0; - #if XFreeXDGA DeviceIntPtr pointer; @@ -1250,12 +1230,9 @@ xf86PostKeyEventM(DeviceIntPtr device, } #endif - nevents = GetKeyboardEvents(xf86Events, device, - is_down ? KeyPress : KeyRelease, - key_code, mask); - - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); + QueueKeyboardEvents(device, + is_down ? KeyPress : KeyRelease, + key_code, mask); } void diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c index 5c800860a..619427ded 100644 --- a/hw/xnest/Events.c +++ b/hw/xnest/Events.c @@ -43,8 +43,6 @@ is" without express or implied warranty. CARD32 lastEventTime = 0; -extern EventList *xnestEvents; - void ProcessInputEvents(void) { @@ -104,23 +102,17 @@ xnestCollectExposures(void) void xnestQueueKeyEvent(int type, unsigned int keycode) { - int i, n; - - GetEventList(&xnestEvents); lastEventTime = GetTimeInMillis(); - n = GetKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode, NULL); - for (i = 0; i < n; i++) - mieqEnqueue(xnestKeyboardDevice, (InternalEvent*)(xnestEvents + i)->event); + QueueKeyboardEvents(xnestKeyboardDevice, type, keycode, NULL); } void xnestCollectEvents(void) { XEvent X; - int i, n, valuators[2]; + int valuators[2]; ValuatorMask mask; ScreenPtr pScreen; - GetEventList(&xnestEvents); while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) { switch (X.type) { @@ -138,20 +130,16 @@ xnestCollectEvents(void) valuator_mask_set_range(&mask, 0, 0, NULL); xnestUpdateModifierState(X.xkey.state); lastEventTime = GetTimeInMillis(); - n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress, - X.xbutton.button, POINTER_RELATIVE, &mask); - for (i = 0; i < n; i++) - mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event); + QueuePointerEvents(xnestPointerDevice, ButtonPress, + X.xbutton.button, POINTER_RELATIVE, &mask); break; case ButtonRelease: valuator_mask_set_range(&mask, 0, 0, NULL); xnestUpdateModifierState(X.xkey.state); lastEventTime = GetTimeInMillis(); - n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease, - X.xbutton.button, POINTER_RELATIVE, &mask); - for (i = 0; i < n; i++) - mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event); + QueuePointerEvents(xnestPointerDevice, ButtonRelease, + X.xbutton.button, POINTER_RELATIVE, &mask); break; case MotionNotify: @@ -159,10 +147,8 @@ xnestCollectEvents(void) valuators[1] = X.xmotion.y; valuator_mask_set_range(&mask, 0, 2, valuators); lastEventTime = GetTimeInMillis(); - n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify, - 0, POINTER_ABSOLUTE, &mask); - for (i = 0; i < n; i++) - mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event); + QueuePointerEvents(xnestPointerDevice, MotionNotify, + 0, POINTER_ABSOLUTE, &mask); break; case FocusIn: @@ -193,10 +179,8 @@ xnestCollectEvents(void) valuators[1] = X.xcrossing.y; valuator_mask_set_range(&mask, 0, 2, valuators); lastEventTime = GetTimeInMillis(); - n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify, - 0, POINTER_ABSOLUTE, &mask); - for (i = 0; i < n; i++) - mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event); + QueuePointerEvents(xnestPointerDevice, MotionNotify, + 0, POINTER_ABSOLUTE, &mask); xnestDirectInstallColormaps(pScreen); } } diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c index 8a90cc65e..ee74101d2 100644 --- a/hw/xnest/Init.c +++ b/hw/xnest/Init.c @@ -45,8 +45,6 @@ is" without express or implied warranty. Bool xnestDoFullGeneration = True; -EventList *xnestEvents = NULL; - void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[]) { @@ -100,8 +98,6 @@ InitInput(int argc, char *argv[]) if (rc != Success) FatalError("Failed to init Xnest default devices.\n"); - GetEventList(&xnestEvents); - mieqInit(); AddEnabledDevice(XConnectionNumber(xnestDisplay)); diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index f3e12250e..fe744b741 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -88,7 +88,7 @@ static pthread_mutex_t fd_add_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t fd_add_ready_cond = PTHREAD_COND_INITIALIZER; static pthread_t fd_add_tid = NULL; -static EventListPtr darwinEvents = NULL; +static InternalEvent* darwinEvents = NULL; static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER; @@ -433,7 +433,6 @@ static void DarwinPrepareValuators(DeviceIntPtr pDev, int *valuators, ScreenPtr void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y, float pressure, float tilt_x, float tilt_y) { static int darwinFakeMouseButtonDown = 0; - int i, num_events; ScreenPtr screen; int valuators[5]; @@ -486,15 +485,12 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa darwinEvents_lock(); { ValuatorMask mask; valuator_mask_set_range(&mask, 0, (pDev == darwinPointer) ? 2 : 5, valuators); - num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button, - POINTER_ABSOLUTE, &mask); - for(i=0; i 0) DarwinPokeEQ(); + QueuePointerEvents(pDev, ev_type, ev_button, POINTER_ABSOLUTE, &mask); + DarwinPokeEQ(); } darwinEvents_unlock(); } void DarwinSendKeyboardEvents(int ev_type, int keycode) { - int i, num_events; if(!darwinEvents) { DEBUG_LOG("DarwinSendKeyboardEvents called before darwinEvents was initialized\n"); @@ -502,15 +498,13 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) { } darwinEvents_lock(); { - num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL); - for(i=0; i 0) DarwinPokeEQ(); + QueueKeyboardEvents(darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL); + DarwinPokeEQ(); } darwinEvents_unlock(); } void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, float pointer_y, float pressure, float tilt_x, float tilt_y) { - int i, num_events; ScreenPtr screen; int valuators[5]; @@ -531,9 +525,8 @@ void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, darwinEvents_lock(); { ValuatorMask mask; valuator_mask_set_range(&mask, 0, 5, valuators); - num_events = GetProximityEvents(darwinEvents, pDev, ev_type, &mask); - for(i=0; i 0) DarwinPokeEQ(); + QueueProximityEvents(pDev, ev_type, &mask); + DarwinPokeEQ(); } darwinEvents_unlock(); } diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c index 912e2de1c..2fa6b3f6e 100644 --- a/hw/xwin/winkeybd.c +++ b/hw/xwin/winkeybd.c @@ -472,8 +472,7 @@ winKeybdReleaseKeys (void) void winSendKeyEvent (DWORD dwKey, Bool fDown) { - EventListPtr events; - int i, nevents; + InternalEvent* events; /* * When alt-tabing between screens we can get phantom key up messages @@ -484,11 +483,7 @@ winSendKeyEvent (DWORD dwKey, Bool fDown) /* Update the keyState map */ g_winKeyState[dwKey] = fDown; - GetEventList(&events); - nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinKeyboard, (InternalEvent*)events[i].event); + QueueKeyboardEvents(g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL); winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n", dwKey, fDown, nevents); diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c index 080e09626..b1b0657cf 100644 --- a/hw/xwin/winmouse.c +++ b/hw/xwin/winmouse.c @@ -234,20 +234,14 @@ winMouseWheel (ScreenPtr pScreen, int iDeltaZ) void winMouseButtonsSendEvent (int iEventType, int iButton) { - EventListPtr events; - int i, nevents; ValuatorMask mask; if (g_winMouseButtonMap) iButton = g_winMouseButtonMap[iButton]; valuator_mask_zero(&mask); - GetEventList(&events); - nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton, - POINTER_RELATIVE, &mask); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event); + QueuePointerEvents(g_pwinPointer, iEventType, iButton, + POINTER_RELATIVE, &mask); #if CYGDEBUG ErrorF("winMouseButtonsSendEvent: iEventType: %d, iButton: %d, nEvents %d\n", @@ -367,20 +361,15 @@ winMouseButtonsHandle (ScreenPtr pScreen, */ void winEnqueueMotion(int x, int y) { - int i, nevents; int valuators[2]; ValuatorMask mask; - EventListPtr events; miPointerSetPosition(g_pwinPointer, POINTER_RELATIVE, &x, &y); valuators[0] = x; valuators[1] = y; valuator_mask_set_range(&mask, 0, 2, valuators); - GetEventList(&events); - nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0, - POINTER_ABSOLUTE | POINTER_SCREEN, &mask); + QueuePointerEvents(g_pwinPointer, MotionNotify, 0, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event); } diff --git a/include/dix.h b/include/dix.h index c201e3ac1..9a111e8a7 100644 --- a/include/dix.h +++ b/include/dix.h @@ -375,7 +375,7 @@ extern void ReleaseActiveGrabs( extern GrabPtr CheckPassiveGrabsOnWindow( WindowPtr /* pWin */, DeviceIntPtr /* device */, - DeviceEvent * /* event */, + InternalEvent * /* event */, BOOL /* checkCore */, BOOL /* activate */); @@ -415,7 +415,7 @@ extern void DeliverFocusedEvent( InternalEvent* /* event */, WindowPtr /* window */); -extern void DeliverGrabbedEvent( +extern int DeliverGrabbedEvent( InternalEvent* /* event */, DeviceIntPtr /* thisDev */, Bool /* deactivateGrab */); diff --git a/include/eventstr.h b/include/eventstr.h index 673207ce3..049688ca0 100644 --- a/include/eventstr.h +++ b/include/eventstr.h @@ -68,10 +68,6 @@ enum EventType { ET_Internal = 0xFF /* First byte */ }; -#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->any.header != 0xFF) \ - FatalError("Wrong event type %d.\n", \ - ((InternalEvent*)(ev))->any.header); - /** * Used for ALL input device events internal in the server until * copied into the matching protocol event. diff --git a/include/input.h b/include/input.h index 86078daee..4de4ff52c 100644 --- a/include/input.h +++ b/include/input.h @@ -109,19 +109,8 @@ typedef union _GrabMask GrabMask; typedef struct _ValuatorMask ValuatorMask; -typedef struct _EventList { - xEvent* event; - int evlen; /* length of allocated memory for event in bytes. This is not - the actual length of the event. The event's actual length is - 32 for standard events or 32 + - ((xGenericEvent*)event)->length * 4 for GenericEvents. - For events in the EQ, the length is - ((InternalEvent*)event)->u.any.length */ -} EventList, *EventListPtr; - /* The DIX stores incoming input events in this list */ -extern EventListPtr InputEventList; -extern int InputEventListLen; +extern InternalEvent* InputEventList; typedef int (*DeviceProc)( DeviceIntPtr /*device*/, @@ -439,22 +428,28 @@ extern _X_EXPORT void CloseInput(void); extern _X_EXPORT int GetMaximumEventsNum(void); -extern _X_EXPORT int GetEventList(EventListPtr* list); -extern _X_EXPORT EventListPtr InitEventList(int num_events); -extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events); +extern _X_EXPORT InternalEvent *InitEventList(int num_events); +extern _X_EXPORT void FreeEventList(InternalEvent *list, int num_events); -extern void CreateClassesChangedEvent(EventListPtr event, +extern void CreateClassesChangedEvent(InternalEvent *event, DeviceIntPtr master, DeviceIntPtr slave, int type); -extern EventListPtr UpdateFromMaster( - EventListPtr events, +extern InternalEvent * UpdateFromMaster( + InternalEvent *events, DeviceIntPtr pDev, int type, int *num_events); extern _X_EXPORT int GetPointerEvents( - EventListPtr events, + InternalEvent *events, + DeviceIntPtr pDev, + int type, + int buttons, + int flags, + const ValuatorMask *mask); + +extern _X_EXPORT void QueuePointerEvents( DeviceIntPtr pDev, int type, int buttons, @@ -462,14 +457,25 @@ extern _X_EXPORT int GetPointerEvents( const ValuatorMask *mask); extern _X_EXPORT int GetKeyboardEvents( - EventListPtr events, + InternalEvent *events, + DeviceIntPtr pDev, + int type, + int key_code, + const ValuatorMask *mask); + +extern _X_EXPORT void QueueKeyboardEvents( DeviceIntPtr pDev, int type, int key_code, const ValuatorMask *mask); extern int GetProximityEvents( - EventListPtr events, + InternalEvent *events, + DeviceIntPtr pDev, + int type, + const ValuatorMask *mask); + +extern void QueueProximityEvents( DeviceIntPtr pDev, int type, const ValuatorMask *mask); @@ -495,6 +501,8 @@ extern _X_EXPORT int GetMotionHistory( ScreenPtr pScreen, BOOL core); +extern void ReleaseButtonsAndKeys(DeviceIntPtr dev); + extern int AttachDevice(ClientPtr client, DeviceIntPtr slave, DeviceIntPtr master); diff --git a/include/inputstr.h b/include/inputstr.h index bd7c78dec..bc0accc87 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -591,4 +591,14 @@ typedef struct _EventSyncInfo { extern EventSyncInfoRec syncEvents; +/** + * Given a sprite, returns the window at the bottom of the trace (i.e. the + * furthest window from the root). + */ +static inline WindowPtr DeepestSpriteWin(SpritePtr sprite) +{ + assert(sprite->spriteTraceGood > 0); + return sprite->spriteTrace[sprite->spriteTraceGood - 1]; +} + #endif /* INPUTSTRUCT_H */ diff --git a/include/inpututils.h b/include/inpututils.h index b8ca6abfc..92a754327 100644 --- a/include/inpututils.h +++ b/include/inpututils.h @@ -37,4 +37,6 @@ struct _ValuatorMask { int valuators[MAX_VALUATORS]; /* valuator data */ }; +extern void verify_internal_event(const InternalEvent *ev); + #endif diff --git a/include/misc.h b/include/misc.h index 803f5bade..bdcc8cc1e 100644 --- a/include/misc.h +++ b/include/misc.h @@ -223,6 +223,24 @@ pad_to_int32(const int bytes) { extern char** xstrtokenize(const char *str, const char* separators); +/** + * Compare the two version numbers comprising of major.minor. + * + * @return A value less than 0 if a is less than b, 0 if a is equal to b, + * or a value greater than 0 + */ +static inline int +version_compare(uint16_t a_major, uint16_t a_minor, + uint16_t b_major, uint16_t b_minor) +{ + int a, b; + + a = a_major << 16 | a_minor; + b = b_major << 16 | b_minor; + + return (a - b); +} + /* some macros to help swap requests, replies, and events */ #define LengthRestB(stuff) \ diff --git a/mi/mieq.c b/mi/mieq.c index 08a0c8758..236ffcc3b 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -64,7 +64,7 @@ in this Software without prior written authorization from The Open Group. #define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen typedef struct _Event { - EventListPtr events; + InternalEvent* events; ScreenPtr pScreen; DeviceIntPtr pDev; /* device this event _originated_ from */ } EventRec, *EventPtr; @@ -111,7 +111,7 @@ mieqInit(void) for (i = 0; i < QUEUE_SIZE; i++) { if (miEventQueue.events[i].events == NULL) { - EventListPtr evlist = InitEventList(1); + InternalEvent* evlist = InitEventList(1); if (!evlist) FatalError("Could not allocate event queue.\n"); miEventQueue.events[i].events = evlist; @@ -146,7 +146,7 @@ void mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) { unsigned int oldtail = miEventQueue.tail; - EventListPtr evt; + InternalEvent* evt; int isMotion = 0; int evlen; Time time; @@ -156,7 +156,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) pthread_mutex_lock(&miEventQueueMutex); #endif - CHECKEVENT(e); + verify_internal_event(e); /* avoid merging events from different devices */ if (e->any.type == ET_Motion) @@ -188,21 +188,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) evlen = e->any.length; evt = miEventQueue.events[oldtail].events; - if (evt->evlen < evlen) - { - evt->evlen = evlen; - evt->event = realloc(evt->event, evt->evlen); - if (!evt->event) - { - ErrorF("[mi] Running out of memory. Tossing event.\n"); -#ifdef XQUARTZ - pthread_mutex_unlock(&miEventQueueMutex); -#endif - return; - } - } - - memcpy(evt->event, e, evlen); + memcpy(evt, e, evlen); time = e->any.time; /* Make sure that event times don't go backwards - this @@ -211,7 +197,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) miEventQueue.lastEventTime - time < 10000) e->any.time = miEventQueue.lastEventTime; - miEventQueue.lastEventTime = ((InternalEvent*)evt->event)->any.time; + miEventQueue.lastEventTime = evt->any.time; miEventQueue.events[oldtail].pScreen = pDev ? EnqueueScreen(pDev) : NULL; miEventQueue.events[oldtail].pDev = pDev; @@ -292,8 +278,8 @@ static void FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev, InternalEvent* original, InternalEvent *master) { - CHECKEVENT(original); - CHECKEVENT(master); + verify_internal_event(original); + verify_internal_event(master); /* Ensure chained button mappings, i.e. that the detail field is the * value of the mapped button on the SD, not the physical button */ if (original->any.type == ET_ButtonPress || @@ -323,7 +309,7 @@ CopyGetMasterEvent(DeviceIntPtr sdev, int type = original->any.type; int mtype; /* which master type? */ - CHECKEVENT(original); + verify_internal_event(original); /* ET_XQuartz has sdev == NULL */ if (!sdev || IsMaster(sdev) || IsFloating(sdev)) @@ -376,7 +362,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev, DeviceIntPtr master; InternalEvent mevent; /* master event */ - CHECKEVENT(event); + verify_internal_event(event); /* Custom event handler */ handler = miEventQueue.handlers[event->any.type]; @@ -431,10 +417,8 @@ void mieqProcessInputEvents(void) { EventRec *e = NULL; - int evlen; ScreenPtr screen; - static InternalEvent *event = NULL; - static size_t event_size = 0; + static InternalEvent event; DeviceIntPtr dev = NULL, master = NULL; @@ -445,20 +429,7 @@ mieqProcessInputEvents(void) while (miEventQueue.head != miEventQueue.tail) { e = &miEventQueue.events[miEventQueue.head]; - evlen = e->events->evlen; - if(evlen > event_size) - { - event = realloc(event, evlen); - event_size = evlen; - } - - - if (!event) - FatalError("[mi] No memory left for event processing.\n"); - - memcpy(event, e->events->event, evlen); - - + event = *e->events; dev = e->pDev; screen = e->pScreen; @@ -480,10 +451,10 @@ mieqProcessInputEvents(void) DPMSSet(serverClient, DPMSModeOn); #endif - mieqProcessDeviceEvent(dev, event, screen); + mieqProcessDeviceEvent(dev, &event, screen); /* Update the sprite now. Next event may be from different device. */ - if (event->any.type == ET_Motion && master) + if (event.any.type == ET_Motion && master) miPointerUpdateSprite(dev); #ifdef XQUARTZ diff --git a/mi/mipointer.c b/mi/mipointer.c index db243810c..322be9e44 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -63,6 +63,7 @@ in this Software without prior written authorization from The Open Group. # include "dixstruct.h" # include "inputstr.h" # include "inpututils.h" +# include "eventstr.h" DevPrivateKeyRec miPointerScreenKeyRec; @@ -99,7 +100,7 @@ static void miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); static void miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); -static EventList* events; /* for WarpPointer MotionNotifies */ +static InternalEvent* events; /* for WarpPointer MotionNotifies */ Bool miPointerInitialize (ScreenPtr pScreen, @@ -689,7 +690,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) darwinEvents_lock(); #endif for (i = 0; i < nevents; i++) - mieqEnqueue(pDev, (InternalEvent*)events[i].event); + mieqEnqueue(pDev, &events[i]); #ifdef XQUARTZ darwinEvents_unlock(); #endif diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index 213550475..d1c99c288 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -28,8 +28,8 @@ RRClientKnowsRates (ClientPtr pClient) { rrClientPriv(pClient); - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); + return version_compare(pRRClient->major_version, pRRClient->minor_version, + 1, 1) >= 0; } static int @@ -47,8 +47,8 @@ ProcRRQueryVersion (ClientPtr client) rep.length = 0; rep.sequenceNumber = client->sequence; - if ((stuff->majorVersion * 1000 + stuff->minorVersion) < - (SERVER_RANDR_MAJOR_VERSION * 1000 + SERVER_RANDR_MINOR_VERSION)) + if (version_compare(stuff->majorVersion, stuff->minorVersion, + SERVER_RANDR_MAJOR_VERSION, SERVER_RANDR_MINOR_VERSION) < 0) { rep.majorVersion = stuff->majorVersion; rep.minorVersion = stuff->minorVersion; diff --git a/test/Makefile.am b/test/Makefile.am index fe9bc1f2e..b7ee070a1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,7 +1,7 @@ if ENABLE_UNIT_TESTS if HAVE_LD_WRAP SUBDIRS= . xi2 -noinst_PROGRAMS = xkb input xtest list +noinst_PROGRAMS = xkb input xtest list misc check_LTLIBRARIES = libxservertest.la TESTS=$(noinst_PROGRAMS) @@ -18,6 +18,7 @@ xkb_LDADD=$(TEST_LDADD) input_LDADD=$(TEST_LDADD) xtest_LDADD=$(TEST_LDADD) list_LDADD=$(TEST_LDADD) +misc_LDADD=$(TEST_LDADD) libxservertest_la_LIBADD = \ $(XSERVER_LIBS) \ diff --git a/test/misc.c b/test/misc.c new file mode 100644 index 000000000..3d3b1a1e3 --- /dev/null +++ b/test/misc.c @@ -0,0 +1,62 @@ +/** + * Copyright © 2011 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include "misc.h" + +static void dix_version_compare(void) +{ + int rc; + + rc = version_compare(0, 0, 1, 0); + assert(rc < 0); + rc = version_compare(1, 0, 0, 0); + assert(rc > 0); + rc = version_compare(0, 0, 0, 0); + assert(rc == 0); + rc = version_compare(1, 0, 1, 0); + assert(rc == 0); + rc = version_compare(1, 0, 0, 9); + assert(rc > 0); + rc = version_compare(0, 9, 1, 0); + assert(rc < 0); + rc = version_compare(1, 0, 1, 9); + assert(rc < 0); + rc = version_compare(1, 9, 1, 0); + assert(rc > 0); + rc = version_compare(2, 0, 1, 9); + assert(rc > 0); + rc = version_compare(1, 9, 2, 0); + assert(rc < 0); +} + +int main(int argc, char** argv) +{ + dix_version_compare(); + + return 0; +} diff --git a/xfixes/xfixes.c b/xfixes/xfixes.c index e8c7bf161..54f0df341 100644 --- a/xfixes/xfixes.c +++ b/xfixes/xfixes.c @@ -72,17 +72,17 @@ ProcXFixesQueryVersion(ClientPtr client) rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; - if (stuff->majorVersion < SERVER_XFIXES_MAJOR_VERSION) { + + if (version_compare(stuff->majorVersion, stuff->minorVersion, + SERVER_XFIXES_MAJOR_VERSION, SERVER_XFIXES_MAJOR_VERSION) < 0) + { rep.majorVersion = stuff->majorVersion; rep.minorVersion = stuff->minorVersion; } else { rep.majorVersion = SERVER_XFIXES_MAJOR_VERSION; - if (stuff->majorVersion == SERVER_XFIXES_MAJOR_VERSION && - stuff->minorVersion < SERVER_XFIXES_MINOR_VERSION) - rep.minorVersion = stuff->minorVersion; - else - rep.minorVersion = SERVER_XFIXES_MINOR_VERSION; + rep.minorVersion = SERVER_XFIXES_MINOR_VERSION; } + pXFixesClient->major_version = rep.majorVersion; pXFixesClient->minor_version = rep.minorVersion; if (client->swapped) { diff --git a/xkb/xkb.c b/xkb/xkb.c index 4044d333d..86231a895 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -5586,6 +5586,7 @@ ProcXkbGetKbdByName(ClientPtr client) { DeviceIntPtr dev; DeviceIntPtr tmpd; + DeviceIntPtr master; xkbGetKbdByNameReply rep = {0}; xkbGetMapReply mrep = {0}; xkbGetCompatMapReply crep = {0}; @@ -5611,6 +5612,7 @@ ProcXkbGetKbdByName(ClientPtr client) return BadAccess; CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); + master = GetMaster(dev, MASTER_KEYBOARD); xkb = dev->key->xkbInfo->desc; status= Success; @@ -5869,25 +5871,6 @@ ProcXkbGetKbdByName(ClientPtr client) } xkb->ctrls->num_groups= nTG; - for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { - if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { - if (tmpd != dev) - XkbCopyDeviceKeymap(tmpd, dev); - - if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { - old_sli = tmpd->kbdfeed->xkb_sli; - tmpd->kbdfeed->xkb_sli = NULL; - sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); - if (sli) { - sli->explicitState = old_sli->explicitState; - sli->effectiveState = old_sli->effectiveState; - } - tmpd->kbdfeed->xkb_sli = sli; - XkbFreeSrvLedInfo(old_sli); - } - } - } - nkn.deviceID= nkn.oldDeviceID= dev->id; nkn.minKeyCode= new->min_key_code; nkn.maxKeyCode= new->max_key_code; @@ -5900,13 +5883,29 @@ ProcXkbGetKbdByName(ClientPtr client) nkn.changed|= XkbNKN_GeometryMask; XkbSendNewKeyboardNotify(dev,&nkn); - if (!IsMaster(dev)) { - DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD); - if (master && master->lastSlave == dev) { - XkbCopyDeviceKeymap(master, dev); - XkbSendNewKeyboardNotify(dev,&nkn); - } - } + /* Update the map and LED info on the device itself, as well as + * any slaves if it's an MD, or its MD if it's an SD and was the + * last device used on that MD. */ + for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { + if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev && + (tmpd != master || dev != master->lastSlave)) + continue; + + if (tmpd != dev) + XkbCopyDeviceKeymap(tmpd, dev); + + if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { + old_sli = tmpd->kbdfeed->xkb_sli; + tmpd->kbdfeed->xkb_sli = NULL; + sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); + if (sli) { + sli->explicitState = old_sli->explicitState; + sli->effectiveState = old_sli->effectiveState; + } + tmpd->kbdfeed->xkb_sli = sli; + XkbFreeSrvLedInfo(old_sli); + } + } } if ((new!=NULL)&&(new!=xkb)) { XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE); diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index c4336d7b4..4b5405ab0 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -1351,7 +1351,7 @@ static void InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask) { ScreenPtr pScreen; - EventListPtr events; + InternalEvent* events; int nevents, i; DeviceIntPtr ptr, mpointer, lastSlave = NULL; Bool saveWait; @@ -1377,7 +1377,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, Valuat OsReleaseSignals(); for (i = 0; i < nevents; i++) - mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); + mieqProcessDeviceEvent(ptr, &events[i], NULL); FreeEventList(events, GetMaximumEventsNum()); diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c index 7f91e9ae1..dfbf7f2b3 100644 --- a/xkb/xkbEvents.c +++ b/xkb/xkbEvents.c @@ -88,11 +88,15 @@ XkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed, if (!clients[i] || clients[i]->clientState != ClientStateRunning) continue; - /* Ignore clients which will have already received this. - * Inconsistent with themselves, but consistent with previous - * behaviour.*/ - if (xkb_event == XkbMapNotify && (clients[i]->mapNotifyMask & changed)) + /* XKB allows clients to restrict the MappingNotify events sent to + * them. This was broken for three years. Sorry. */ + if (xkb_event == XkbMapNotify && + (clients[i]->xkbClientFlags & _XkbClientInitialized) && + !(clients[i]->mapNotifyMask & changed)) continue; + /* Emulate previous server behaviour: any client which has activated + * XKB will not receive core events emulated from a NewKeyboardNotify + * at all. */ if (xkb_event == XkbNewKeyboardNotify && (clients[i]->xkbClientFlags & _XkbClientInitialized)) continue; @@ -164,9 +168,6 @@ XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN) if (!(clients[i]->newKeyboardNotifyMask & changed)) continue; - if (!XIShouldNotify(clients[i], kbd)) - continue; - pNKN->sequenceNumber = clients[i]->sequence; pNKN->time = time; pNKN->changed = changed; @@ -232,8 +233,7 @@ register CARD16 changed,bState; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->stateNotifyMask&changed) && - XIShouldNotify(interest->client,kbd)) { + (interest->stateNotifyMask&changed)) { pSN->sequenceNumber = interest->client->sequence; pSN->time = time; pSN->changed = changed; @@ -280,9 +280,6 @@ XkbSendMapNotify(DeviceIntPtr kbd, xkbMapNotify *pMN) if (!(clients[i]->mapNotifyMask & changed)) continue; - if (!XIShouldNotify(clients[i], kbd)) - continue; - pMN->time = time; pMN->sequenceNumber = clients[i]->sequence; pMN->changed = changed; @@ -401,8 +398,7 @@ Time time = 0; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->ctrlsNotifyMask&changedControls) && - XIShouldNotify(interest->client, kbd)) { + (interest->ctrlsNotifyMask&changedControls)) { if (!initialized) { pCN->type = XkbEventCode + XkbEventBase; pCN->xkbType = XkbControlsNotify; @@ -450,7 +446,6 @@ CARD32 state,changed; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - XIShouldNotify(interest->client, kbd) && (((xkbType==XkbIndicatorStateNotify)&& (interest->iStateNotifyMask&changed))|| ((xkbType==XkbIndicatorMapNotify)&& @@ -534,8 +529,7 @@ XID winID = 0; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->bellNotifyMask) && - XIShouldNotify(interest->client,kbd)) { + (interest->bellNotifyMask)) { if (!initialized) { time = GetTimeInMillis(); bn.type = XkbEventCode + XkbEventBase; @@ -589,8 +583,7 @@ CARD16 sk_delay,db_delay; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->accessXNotifyMask&(1<detail)) && - XIShouldNotify(interest->client, kbd)) { + (interest->accessXNotifyMask&(1<detail))) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbAccessXNotify; @@ -637,8 +630,7 @@ CARD32 changedIndicators; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->namesNotifyMask&pEv->changed) && - XIShouldNotify(interest->client, kbd)) { + (interest->namesNotifyMask&pEv->changed)) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbNamesNotify; @@ -683,8 +675,7 @@ CARD16 firstSI = 0, nSI = 0, nTotalSI = 0; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->compatNotifyMask) && - XIShouldNotify(interest->client, kbd)) { + (interest->compatNotifyMask)) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbCompatMapNotify; @@ -736,8 +727,7 @@ Time time = 0; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->actionMessageMask) && - XIShouldNotify(interest->client, kbd)) { + (interest->actionMessageMask)) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbActionMessage; @@ -783,8 +773,7 @@ CARD16 reason; if ((!interest->client->clientGone) && (interest->client->requestVector != InitialVector) && (interest->client->xkbClientFlags&_XkbClientInitialized) && - (interest->extDevNotifyMask&reason) && - XIShouldNotify(interest->client, dev)) { + (interest->extDevNotifyMask&reason)) { if (!initialized) { pEv->type = XkbEventCode + XkbEventBase; pEv->xkbType = XkbExtensionDeviceNotify;