diff options
Diffstat (limited to 'xorg-server/dix')
-rw-r--r-- | xorg-server/dix/devices.c | 33 | ||||
-rw-r--r-- | xorg-server/dix/events.c | 173 | ||||
-rw-r--r-- | xorg-server/dix/getevents.c | 27 | ||||
-rw-r--r-- | xorg-server/dix/grabs.c | 2 | ||||
-rw-r--r-- | xorg-server/dix/inpututils.c | 155 |
5 files changed, 286 insertions, 104 deletions
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c index 0ccf25277..ab8a648a9 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -2406,7 +2406,6 @@ int AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) { ScreenPtr screen; - DeviceIntPtr oldmaster; if (!dev || IsMaster(dev)) return BadDevice; @@ -2425,7 +2424,6 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) free(dev->spriteInfo->sprite); } - oldmaster = GetMaster(dev, MASTER_ATTACHED); dev->master = master; /* If device is set to floating, we need to create a sprite for it, @@ -2484,16 +2482,22 @@ GetPairedDevice(DeviceIntPtr dev) /** - * Returns the right master for the type of event needed. If the event is a - * keyboard event. - * This function may be called with a master device as argument. If so, the - * returned master is either the device itself or the paired master device. - * If dev is a floating slave device, NULL is returned. + * Returns the requested master for this device. + * The return values are: + * - MASTER_ATTACHED: the master for this device or NULL for a floating + * slave. + * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a + * floating slave + * - MASTER_POINTER: the master keyboard for this device or NULL for a + * floating slave + * - POINTER_OR_FLOAT: the master pointer for this device or the device for + * a floating slave + * - KEYBOARD_OR_FLOAT: the master keyboard for this device or the device for + * a floating slave * - * @type ::MASTER_KEYBOARD or ::MASTER_POINTER or ::MASTER_ATTACHED - * @return The requested master device. In the case of MASTER_ATTACHED, this - * is the directly attached master to this device, regardless of the type. - * Otherwise, it is either the master keyboard or pointer for this device. + * @param which ::MASTER_KEYBOARD or ::MASTER_POINTER, ::MASTER_ATTACHED, + * ::POINTER_OR_FLOAT or ::KEYBOARD_OR_FLOAT. + * @return The requested master device */ DeviceIntPtr GetMaster(DeviceIntPtr dev, int which) @@ -2502,12 +2506,15 @@ GetMaster(DeviceIntPtr dev, int which) if (IsMaster(dev)) master = dev; - else + else { master = dev->master; + if (!master && (which == POINTER_OR_FLOAT || which == KEYBOARD_OR_FLOAT)) + return dev; + } if (master && which != MASTER_ATTACHED) { - if (which == MASTER_KEYBOARD) + if (which == MASTER_KEYBOARD || which == KEYBOARD_OR_FLOAT) { if (master->type != MASTER_KEYBOARD) master = GetPairedDevice(master); diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index 8a4c6b9ac..fbe4fc953 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -408,6 +408,24 @@ static const Mask default_filter[128] = CantBeFiltered /* MappingNotify */ }; +static inline Mask +GetEventFilterMask(DeviceIntPtr dev, int evtype) +{ + return filters[dev ? dev->id : 0][evtype]; +} + +static inline Mask +GetXI2EventFilterMask(int evtype) +{ + return (1 << (evtype % 8)); +} + +static inline int +GetXI2EventFilterOffset(int evtype) +{ + return (evtype / 8); +} + /** * For the given event, return the matching event filter. This filter may then * be AND'ed with the selected event mask. @@ -429,14 +447,28 @@ GetEventFilter(DeviceIntPtr dev, xEvent *event) int evtype = 0; if (event->u.u.type != GenericEvent) - return filters[dev ? dev->id : 0][event->u.u.type]; + return GetEventFilterMask(dev, event->u.u.type); else if ((evtype = xi2_get_type(event))) - return (1 << (evtype % 8)); + return GetXI2EventFilterMask(evtype); ErrorF("[dix] Unknown event type %d. No filter\n", event->u.u.type); return 0; } /** + * Return the single byte of the device's XI2 mask that contains the mask + * for the event_type. + */ +static int +GetXI2MaskByte(unsigned char xi2mask[][XI2MASKSIZE], DeviceIntPtr dev, int event_type) +{ + int byte = GetXI2EventFilterOffset(event_type); + return xi2mask[dev->id][byte] | + xi2mask[XIAllDevices][byte] | + (IsMaster(dev) ? xi2mask[XIAllMasterDevices][byte] : 0); +} + + +/** * Return the windows complete XI2 mask for the given XI2 event type. */ Mask @@ -452,9 +484,7 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev) evtype = ((xGenericEvent*)ev)->evtype; filter = GetEventFilter(dev, ev); - return ((inputMasks->xi2mask[dev->id][evtype/8] & filter) || - inputMasks->xi2mask[XIAllDevices][evtype/8] || - (inputMasks->xi2mask[XIAllMasterDevices][evtype/8] && IsMaster(dev))); + return (GetXI2MaskByte(inputMasks->xi2mask, dev, evtype) & filter); } Mask @@ -465,10 +495,7 @@ GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other) /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */ if ((evtype = xi2_get_type(event))) { - int byte = evtype / 8; - return (other->xi2mask[dev->id][byte] | - other->xi2mask[XIAllDevices][byte] | - (IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0)); + return GetXI2MaskByte(other->xi2mask, dev, evtype); } else if (core_get_type(event) != 0) return other->mask[XIAllDevices]; else @@ -680,9 +707,7 @@ ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py) BoxRec box; int x = *px, y = *py; int incx = 1, incy = 1; - SpritePtr pSprite; - pSprite = pDev->spriteInfo->sprite; if (RegionContainsPoint(shape, x, y, &box)) return; box = *RegionExtents(shape); @@ -2478,44 +2503,45 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win) int filter = 0; int type; OtherInputMasks *inputMasks = wOtherInputMasks(win); - xEvent ev; - - /* XXX: this makes me gag */ - type = GetXI2Type(event); - ev.u.u.type = GenericEvent; /* GetEventFilter only cares about type and evtype*/ - ((xGenericEvent*)&ev)->extension = IReqCode; - ((xGenericEvent*)&ev)->evtype = type; - filter = GetEventFilter(dev, &ev); - if (type && inputMasks && - ((inputMasks->xi2mask[XIAllDevices][type/8] & filter) || - ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && IsMaster(dev)) || - (inputMasks->xi2mask[dev->id][type/8] & filter))) - rc |= EVENT_XI2_MASK; - - type = GetXIType(event); - ev.u.u.type = type; - filter = GetEventFilter(dev, &ev); - - /* Check for XI mask */ - if (type && inputMasks && - (inputMasks->deliverableEvents[dev->id] & filter) && - (inputMasks->inputEvents[dev->id] & filter)) - rc |= EVENT_XI1_MASK; - - /* Check for XI DontPropagate mask */ - if (type && inputMasks && - (inputMasks->dontPropagateMask[dev->id] & filter)) - rc |= EVENT_DONT_PROPAGATE_MASK; - - /* Check for core mask */ - type = GetCoreType(event); - if (type && (win->deliverableEvents & filter) && - ((wOtherEventMasks(win) | win->eventMask) & filter)) - rc |= EVENT_CORE_MASK; - - /* Check for core DontPropagate mask */ - if (type && (filter & wDontPropagateMask(win))) - rc |= EVENT_DONT_PROPAGATE_MASK; + + if ((type = GetXI2Type(event)) != 0) + { + filter = GetXI2EventFilterMask(type); + + if (inputMasks && + (GetXI2MaskByte(inputMasks->xi2mask, dev, type) & filter)) + rc |= EVENT_XI2_MASK; + } + + if ((type = GetXIType(event)) != 0) + { + filter = GetEventFilterMask(dev, type); + + /* Check for XI mask */ + if (inputMasks && + (inputMasks->deliverableEvents[dev->id] & filter) && + (inputMasks->inputEvents[dev->id] & filter)) + rc |= EVENT_XI1_MASK; + + /* Check for XI DontPropagate mask */ + if (inputMasks && (inputMasks->dontPropagateMask[dev->id] & filter)) + rc |= EVENT_DONT_PROPAGATE_MASK; + + } + + if ((type = GetCoreType(event)) != 0) + { + filter = GetEventFilterMask(dev, type); + + /* Check for core mask */ + if ((win->deliverableEvents & filter) && + ((wOtherEventMasks(win) | win->eventMask) & filter)) + rc |= EVENT_CORE_MASK; + + /* Check for core DontPropagate mask */ + if (filter & wDontPropagateMask(win)) + rc |= EVENT_DONT_PROPAGATE_MASK; + } return rc; } @@ -3351,16 +3377,21 @@ XineramaWarpPointer(ClientPtr client) { WindowPtr dest = NULL; int x, y, rc; - SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; + DeviceIntPtr dev; + SpritePtr pSprite; REQUEST(xWarpPointerReq); - if (stuff->dstWid != None) { rc = dixLookupWindow(&dest, stuff->dstWid, client, DixReadAccess); if (rc != Success) return rc; } + + /* Post through the XTest device */ + dev = PickPointer(client); + dev = GetXTestDevice(dev); + pSprite = dev->spriteInfo->sprite; x = pSprite->hotPhys.x; y = pSprite->hotPhys.y; @@ -3410,9 +3441,9 @@ XineramaWarpPointer(ClientPtr client) else if (y >= pSprite->physLimits.y2) y = pSprite->physLimits.y2 - 1; if (pSprite->hotShape) - ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y); + ConfineToShape(dev, pSprite->hotShape, &x, &y); - XineramaSetCursorPosition(PickPointer(client), x, y, TRUE); + XineramaSetCursorPosition(dev, x, y, TRUE); return Success; } @@ -3430,7 +3461,7 @@ ProcWarpPointer(ClientPtr client) WindowPtr dest = NULL; int x, y, rc; ScreenPtr newScreen; - DeviceIntPtr dev, tmp; + DeviceIntPtr dev, tmp, xtest_dev = NULL; SpritePtr pSprite; REQUEST(xWarpPointerReq); @@ -3443,11 +3474,13 @@ ProcWarpPointer(ClientPtr client) rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess); if (rc != Success) return rc; + if (IsXTestDevice(tmp, dev)) + xtest_dev = tmp; } } - if (dev->lastSlave) - dev = dev->lastSlave; + /* Use the XTest device to actually move the pointer */ + dev = xtest_dev; pSprite = dev->spriteInfo->sprite; #ifdef PANORAMIX @@ -3678,7 +3711,7 @@ CheckPassiveGrabsOnWindow( if (tempGrab.type < GenericEvent) { grab->device = device; - grab->modifierDevice = GetPairedDevice(device); + grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD); } for (other = inputInfo.devices; other; other = other->next) @@ -4063,9 +4096,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, if (rc == Success) { int evtype = xi2_get_type(xi2); - mask = grab->xi2mask[XIAllDevices][evtype/8] | - grab->xi2mask[XIAllMasterDevices][evtype/8] | - grab->xi2mask[thisDev->id][evtype/8]; + mask = GetXI2MaskByte(grab->xi2mask, thisDev, evtype); /* try XI2 event */ FixUpEventFromWindow(pSprite, xi2, grab->window, None, TRUE); /* XXX: XACE */ @@ -4544,9 +4575,7 @@ DeviceEnterLeaveEvent( if (grab) { Mask mask; - mask = grab->xi2mask[XIAllDevices][type/8] | - grab->xi2mask[XIAllMasterDevices][type/8] | - grab->xi2mask[mouse->id][type/8]; + mask = GetXI2MaskByte(grab->xi2mask, mouse, type); TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask, filter, grab); } else { @@ -4765,7 +4794,6 @@ ProcGrabPointer(ClientPtr client) WindowPtr confineTo; CursorPtr oldCursor; REQUEST(xGrabPointerReq); - TimeStamp time; int rc; REQUEST_SIZE_MATCH(xGrabPointerReq); @@ -4811,7 +4839,6 @@ ProcGrabPointer(ClientPtr client) if (oldCursor && rep.status == GrabSuccess) FreeCursor (oldCursor, (Cursor)0); - time = ClientTimeToServerTime(stuff->time); rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; @@ -5224,6 +5251,8 @@ CloseDownEvents(void) InputEventList = NULL; } +#define SEND_EVENT_BIT 0x80 + /** * Server-side protocol handling for SendEvent request. * @@ -5241,6 +5270,16 @@ ProcSendEvent(ClientPtr client) REQUEST_SIZE_MATCH(xSendEventReq); + /* libXext and other extension libraries may set the bit indicating + * that this event came from a SendEvent request so remove it + * since otherwise the event type may fail the range checks + * and cause an invalid BadValue error to be returned. + * + * This is safe to do since we later add the SendEvent bit (0x80) + * back in once we send the event to the client */ + + stuff->event.u.u.type &= ~(SEND_EVENT_BIT); + /* The client's event type must be a core event type or one defined by an extension. */ @@ -5298,7 +5337,7 @@ ProcSendEvent(ClientPtr client) client->errorValue = stuff->propagate; return BadValue; } - stuff->event.u.u.type |= 0x80; + stuff->event.u.u.type |= SEND_EVENT_BIT; if (stuff->propagate) { for (;pWin; pWin = pWin->parent) @@ -5360,7 +5399,7 @@ ProcUngrabKey(ClientPtr client) tempGrab.window = pWin; tempGrab.modifiersDetail.exact = stuff->modifiers; tempGrab.modifiersDetail.pMask = NULL; - tempGrab.modifierDevice = GetPairedDevice(keybd); + tempGrab.modifierDevice = keybd; tempGrab.type = KeyPress; tempGrab.grabtype = GRABTYPE_CORE; tempGrab.detail.exact = stuff->key; diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c index a12462a4a..be2840c47 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -154,17 +154,6 @@ key_autorepeats(DeviceIntPtr pDev, int key_code) } static void -init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms) -{ - memset(event, 0, sizeof(DeviceEvent)); - event->header = ET_Internal; - event->length = sizeof(DeviceEvent); - event->time = ms; - event->deviceid = dev->id; - event->sourceid = dev->id; -} - -static void init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail) { memset(event, 0, sizeof(RawDeviceEvent)); @@ -414,7 +403,6 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, Time current; /* The size of a single motion event. */ int size; - int dflt; AxisInfo from, *to; /* for scaling */ INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */ INT16 *corebuf; @@ -502,13 +490,6 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, else if (j == 1 && (from.max_value < from.min_value)) from.max_value = pScreen->height; - if (j == 0 && (to->max_value < to->min_value)) - dflt = pScreen->width; - else if (j == 1 && (to->max_value < to->min_value)) - dflt = pScreen->height; - else - dflt = 0; - /* scale from stored range into current range */ coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0); memcpy(ocbuf, &coord, sizeof(INT32)); @@ -1014,7 +995,7 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type, set_raw_valuators(raw, &mask, raw->valuators.data); event = &events->device_event; - init_event(pDev, event, ms); + init_device_event(event, pDev, ms); event->detail.key = key_code; if (type == KeyPress) { @@ -1236,7 +1217,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons clipValuators(pDev, &mask); event = &events->device_event; - init_event(pDev, event, ms); + init_device_event(event, pDev, ms); if (type == MotionNotify) { event->type = ET_Motion; @@ -1329,7 +1310,7 @@ GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type, const Val events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); event = &events->device_event; - init_event(pDev, event, GetTimeInMillis()); + init_device_event(event, pDev, GetTimeInMillis()); event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut; clipValuators(pDev, &mask); @@ -1365,7 +1346,7 @@ PostSyntheticMotion(DeviceIntPtr pDev, #endif memset(&ev, 0, sizeof(DeviceEvent)); - init_event(pDev, &ev, time); + init_device_event(&ev, pDev, time); ev.root_x = x; ev.root_y = y; ev.type = ET_Motion; diff --git a/xorg-server/dix/grabs.c b/xorg-server/dix/grabs.c index 85ca9eee0..c28356d9b 100644 --- a/xorg-server/dix/grabs.c +++ b/xorg-server/dix/grabs.c @@ -479,7 +479,7 @@ AddPassiveGrabToList(ClientPtr client, GrabPtr pGrab) for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next) { - if (GrabMatchesSecond(pGrab, grab, FALSE)) + if (GrabMatchesSecond(pGrab, grab, (pGrab->grabtype == GRABTYPE_CORE))) { if (CLIENT_BITS(pGrab->resource) != CLIENT_BITS(grab->resource)) { diff --git a/xorg-server/dix/inpututils.c b/xorg-server/dix/inpututils.c index 49e175822..7aeb1e516 100644 --- a/xorg-server/dix/inpututils.c +++ b/xorg-server/dix/inpututils.c @@ -584,3 +584,158 @@ void verify_internal_event(const InternalEvent *ev) FatalError("Wrong event type %d. Aborting server\n", ev->any.header); } } + +/** + * Initializes the given event to zero (or default values), for the given + * device. + */ +void init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms) +{ + memset(event, 0, sizeof(DeviceEvent)); + event->header = ET_Internal; + event->length = sizeof(DeviceEvent); + event->time = ms; + event->deviceid = dev->id; + event->sourceid = dev->id; +} + +/** + * Delete the element with the key from the list, freeing all memory + * associated with the element.. + */ +static void +input_option_free(InputOption *o) +{ + free(o->key); + free(o->value); + free(o); +} + +/* + * Create a new InputOption with the key/value pair provided. + * If a list is provided, the new options is added to the list and the list + * is returned. + * + * If a new option is added to a list that already contains that option, the + * previous option is overwritten. + * + * @param list The list to add to. + * @param key Option key, will be copied. + * @param value Option value, will be copied. + * + * @return If list is not NULL, the list with the new option added. If list + * is NULL, a new option list with one element. On failure, NULL is + * returned. + */ +InputOption* +input_option_new(InputOption* list, const char *key, const char *value) +{ + InputOption *opt = NULL; + + if (!key) + return NULL; + + if (list) + { + nt_list_for_each_entry(opt, list, next) + { + if (strcmp(input_option_get_key(opt), key) == 0) + { + input_option_set_value(opt, value); + return list; + } + } + } + + opt = calloc(1, sizeof(InputOption)); + if (!opt) + return NULL; + + nt_list_init(opt, next); + input_option_set_key(opt, key); + input_option_set_value(opt, value); + + if (list) + { + nt_list_append(opt, list, InputOption, next); + return list; + } else + return opt; +} + +InputOption* +input_option_free_element(InputOption *list, const char *key) +{ + InputOption *element; + + nt_list_for_each_entry(element, list, next) { + if (strcmp(input_option_get_key(element), key) == 0) { + nt_list_del(element, list, InputOption, next); + input_option_free(element); + break; + } + } + return list; +} + +/** + * Free the list pointed at by opt. + */ +void +input_option_free_list(InputOption **opt) +{ + InputOption *element, *tmp; + + nt_list_for_each_entry_safe(element, tmp, *opt, next) { + nt_list_del(element, *opt, InputOption, next); + input_option_free(element); + } + *opt = NULL; +} + + +/** + * Find the InputOption with the given option name. + * + * @return The InputOption or NULL if not present. + */ +InputOption* +input_option_find(InputOption *list, const char *key) +{ + InputOption *element; + + nt_list_for_each_entry(element, list, next) { + if (strcmp(input_option_get_key(element), key) == 0) + return element; + } + + return NULL; +} + +const char* +input_option_get_key(const InputOption *opt) +{ + return opt->key; +} + +const char* +input_option_get_value(const InputOption *opt) +{ + return opt->value; +} + +void +input_option_set_key(InputOption *opt, const char *key) +{ + free(opt->key); + if (key) + opt->key = strdup(key); +} + +void +input_option_set_value(InputOption *opt, const char *value) +{ + free(opt->value); + if (value) + opt->value = strdup(value); +} |