diff options
-rw-r--r-- | dix/events.c | 107 | ||||
-rw-r--r-- | hw/kdrive/src/kinput.c | 27 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Xinput.c | 75 | ||||
-rw-r--r-- | include/input.h | 8 |
4 files changed, 118 insertions, 99 deletions
diff --git a/dix/events.c b/dix/events.c index f0b9e165d..5706aac36 100644 --- a/dix/events.c +++ b/dix/events.c @@ -4658,22 +4658,39 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) } } +/* Maximum number of valuators, divided by six, rounded up. */ +#define MAX_VALUATOR_EVENTS 6 + +/** + * Returns the maximum number of events GetKeyboardEvents, + * GetKeyboardValuatorEvents, and GetPointerEvents will ever return. + * + * Should be used in DIX as: + * xEvent *events = xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + */ +int +GetMaximumEventsNum() { + /* Two base events -- core and device, plus valuator events. Multiply + * by two if we're doing key repeats. */ + return 2 * (2 + MAX_VALUATOR_EVENTS); +} + /** * Convenience wrapper around GetKeyboardValuatorEvents, that takes no * valuators. */ int -GetKeyboardEvents(xEvent **xE, DeviceIntPtr pDev, int type, int key_code) { - return GetKeyboardValuatorEvents(xE, pDev, type, key_code, 0, NULL); +GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) { + return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, NULL); } /** * Returns a set of keyboard events for KeyPress/KeyRelease, optionally * also with valuator events. Handles Xi and XKB. * - * xE will be set to an array of events, which must be freed by the user; - * the return value is the number of events in xE, which is not - * NULL-terminated. + * 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. * * If pDev is set to send core events, then the keymap on the core * keyboard will be pivoted to that of the new keyboard and the appropriate @@ -4683,18 +4700,21 @@ GetKeyboardEvents(xEvent **xE, DeviceIntPtr pDev, int type, int key_code) { * key press will trigger a matching KeyRelease, as well as the * KeyPresses. */ -int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type, +int GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code, int num_valuators, int *valuators) { int numEvents = 0, numRepeatEvents = 0, ms = 0, first_valuator = 0, i = 0; deviceKeyButtonPointer *kbp = NULL; deviceValuator *xv = NULL; - xEvent *ev = NULL, *repeatEvents = NULL; + xEvent *repeatEvents = NULL; KeyClassPtr ckeyc; #ifdef XKB xkbMapNotify mn; #endif + if (!events) + return 0; + if (type != KeyPress && type != KeyRelease) return 0; @@ -4707,8 +4727,11 @@ int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type, else numEvents = 1; - if (num_valuators) - numEvents += (num_valuators % 6) + 1; + if (num_valuators) { + if ((num_valuators / 6) + 1 > MAX_VALUATOR_EVENTS) + num_valuators = MAX_VALUATOR_EVENTS; + numEvents += (num_valuators / 6) + 1; + } /* Handle core repeating, via press/release/press/release. * FIXME: In theory, if you're repeating with two keyboards, @@ -4724,26 +4747,15 @@ int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type, !(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] & (1 << (key_code & 7)))) return 0; - numEvents += GetKeyboardValuatorEvents(&repeatEvents, pDev, + numEvents += GetKeyboardValuatorEvents(events, pDev, KeyRelease, key_code, num_valuators, valuators); + events += numEvents; } - ev = (xEvent *)xcalloc(sizeof(xEvent), numEvents); - if (!ev) - return 0; - - if (repeatEvents) { - for (i = 0; i < numRepeatEvents; i++) { - ev = repeatEvents++; - ev++; - } - } - - *xE = ev; ms = GetTimeInMillis(); - kbp = (deviceKeyButtonPointer *) ev; + kbp = (deviceKeyButtonPointer *) events; kbp->time = ms; kbp->deviceid = pDev->id; if (type == KeyPress) @@ -4754,7 +4766,7 @@ int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type, if (num_valuators) { kbp->deviceid |= MORE_EVENTS; while (first_valuator < num_valuators) { - xv = (deviceValuator *) ++ev; + xv = (deviceValuator *) ++events; xv->type = DeviceValuator; xv->first_valuator = first_valuator; xv->num_valuators = num_valuators; @@ -4781,10 +4793,10 @@ int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type, } if (pDev->coreEvents) { - ev++; - ev->u.keyButtonPointer.time = ms; - ev->u.u.type = type; - ev->u.u.detail = key_code; + events++; + events->u.keyButtonPointer.time = ms; + events->u.u.type = type; + events->u.u.detail = key_code; if (inputInfo.keyboard->devPrivates[CoreDevicePrivatesIndex].ptr != pDev) { @@ -4796,8 +4808,6 @@ int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type, memcpy(ckeyc->modifierKeyMap, pDev->key->modifierKeyMap, (8 * pDev->key->maxKeysPerModifier)); ckeyc->maxKeysPerModifier = pDev->key->maxKeysPerModifier; - ckeyc->curKeySyms.map = NULL; - ckeyc->curKeySyms.mapWidth = 0; ckeyc->curKeySyms.minKeyCode = pDev->key->curKeySyms.minKeyCode; ckeyc->curKeySyms.maxKeyCode = pDev->key->curKeySyms.maxKeyCode; SetKeySymsMap(&ckeyc->curKeySyms, &pDev->key->curKeySyms); @@ -4911,13 +4921,14 @@ acceleratePointer(DeviceIntPtr pDev, int num_valuators, int *valuators) * Generate a series of xEvents (returned in xE) representing pointer * motion, or button presses. Xi and XKB-aware. * - * xE is not NULL-terminated; the return value is the number of events. - * The user is responsible for freeing these 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. */ int -GetPointerEvents(xEvent **xE, DeviceIntPtr pDev, int type, int buttons, +GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, int flags, int num_valuators, int *valuators) { - int numEvents, ms, first_valuator = 0; + int numEvents = 0, ms = 0, first_valuator = 0; deviceKeyButtonPointer *kbp = NULL; deviceValuator *xv = NULL; AxisInfoPtr axes = NULL; @@ -4942,20 +4953,18 @@ GetPointerEvents(xEvent **xE, DeviceIntPtr pDev, int type, int buttons, numEvents = 1; if (type == MotionNotify) { - if (num_valuators > 2) + if (num_valuators > 2) { + if (((num_valuators / 6) + 1) > MAX_VALUATOR_EVENTS) + num_valuators = MAX_VALUATOR_EVENTS; numEvents += (num_valuators / 6) + 1; + } else if (num_valuators < 2) return 0; } - ev = (xEvent *)xcalloc(sizeof(xEvent), numEvents); - if (!ev) - return 0; - - *xE = ev; ms = GetTimeInMillis(); - kbp = (deviceKeyButtonPointer *) ev; + kbp = (deviceKeyButtonPointer *) events; kbp->time = ms; kbp->deviceid = pDev->id; @@ -5053,7 +5062,7 @@ GetPointerEvents(xEvent **xE, DeviceIntPtr pDev, int type, int buttons, flags & POINTER_ABSOLUTE)) { kbp->deviceid |= MORE_EVENTS; while (first_valuator < num_valuators) { - xv = (deviceValuator *) ++ev; + xv = (deviceValuator *) ++events; xv->type = DeviceValuator; xv->first_valuator = first_valuator; xv->num_valuators = num_valuators; @@ -5086,11 +5095,11 @@ GetPointerEvents(xEvent **xE, DeviceIntPtr pDev, int type, int buttons, } if (pDev->coreEvents) { - ev++; - ev->u.u.type = type; - ev->u.keyButtonPointer.time = ms; - ev->u.keyButtonPointer.rootX = kbp->root_x; - ev->u.keyButtonPointer.rootY = kbp->root_y; + events++; + events->u.u.type = type; + events->u.keyButtonPointer.time = ms; + events->u.keyButtonPointer.rootX = kbp->root_x; + events->u.keyButtonPointer.rootY = kbp->root_y; cp->valuator->lastx = kbp->root_x; cp->valuator->lasty = kbp->root_y; #ifdef DEBUG @@ -5101,10 +5110,10 @@ GetPointerEvents(xEvent **xE, DeviceIntPtr pDev, int type, int buttons, ErrorF("GPE: core detail is %d\n", buttons); #endif /* Core buttons remapping shouldn't be transitive. */ - ev->u.u.detail = pDev->button->map[buttons]; + events->u.u.detail = pDev->button->map[buttons]; } else { - ev->u.u.detail = 0; + events->u.u.detail = 0; } if (inputInfo.pointer->devPrivates[CoreDevicePrivatesIndex].ptr != diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 1718fdad1..fc4592a64 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -69,6 +69,8 @@ static struct KdConfigDevice *kdConfigPointers = NULL; static KdKeyboardDriver *kdKeyboardDrivers = NULL; static KdPointerDriver *kdPointerDrivers = NULL; +static xEvent *kdEvents = NULL; + static Bool kdInputEnabled; static Bool kdOffScreen; static unsigned long kdOffScreenTime; @@ -1271,6 +1273,11 @@ KdInitInput (void) ErrorF("Failed to add keyboard!\n"); } + if (!kdEvents) + kdEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + if (!kdEvents) + FatalError("Couldn't allocate event buffer\n"); + mieqInit(); } @@ -1849,7 +1856,6 @@ KdHandleKeyboardEvent (KdKeyboardInfo *ki, int type, int key) void KdReleaseAllKeys (void) { - xEvent *xE; int key, nEvents, i; KdKeyboardInfo *ki; @@ -1860,9 +1866,9 @@ KdReleaseAllKeys (void) key++) { if (IsKeyDown(ki, key)) { KdHandleKeyboardEvent(ki, KeyRelease, key); - nEvents = GetKeyboardEvents(&xE, ki->dixdev, KeyRelease, key); + nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key); for (i = 0; i < nEvents; i++) - KdQueueEvent (xE++); + KdQueueEvent (kdEvents + i); } } } @@ -1897,7 +1903,6 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, KeyClassPtr keyc = NULL; KeybdCtrl *ctrl = NULL; int type, nEvents, i; - xEvent *xE = NULL; #ifdef DEBUG ErrorF("enqueuing kb event (scancode %d, %s)\n", scan_code, is_up ? "up" : "down"); @@ -1939,12 +1944,12 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, KdCheckSpecialKeys(ki, type, key_code); KdHandleKeyboardEvent(ki, type, key_code); - nEvents = GetKeyboardEvents(&xE, ki->dixdev, type, key_code); + nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code); #ifdef DEBUG ErrorF("KdEnqueueKeyboardEvent: got %d events from GKE\n", nEvents); #endif for (i = 0; i < nEvents; i++) - KdQueueEvent(xE++); + KdQueueEvent(kdEvents + i); } else { ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", @@ -2047,8 +2052,7 @@ void _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b, int absrel, Bool force) { - xEvent *xE = NULL; - int n = 0, i = 0; + int nEvents = 0, i = 0; int valuators[3] = { x, y, z }; #ifdef DEBUG @@ -2060,9 +2064,10 @@ _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel)) return; - n = GetPointerEvents(&xE, pi->dixdev, type, b, absrel, 3, valuators); - for (i = 0; i < n; i++) - KdQueueEvent(xE++); + nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, 3, + valuators); + for (i = 0; i < nEvents; i++) + KdQueueEvent(kdEvents + i); } void diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 91db82e73..070645dc6 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -108,6 +108,8 @@ static int debug_level = 0; #define DBG(lvl, f) #endif +static xEvent *xf86Events = NULL; + static Bool xf86SendDragEvents(DeviceIntPtr device) { @@ -639,7 +641,6 @@ xf86PostMotionEvent(DeviceIntPtr device, int i = 0, nevents = 0; Bool drag = xf86SendDragEvents(device); LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate; - xEvent *events = NULL; int *valuators = NULL; int flags = 0; @@ -662,15 +663,16 @@ xf86PostMotionEvent(DeviceIntPtr device, #endif } - nevents = GetPointerEvents(&events, device, MotionNotify, 0, + if (!xf86Events) + xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + if (!xf86Events) + FatalError("Couldn't allocate event store\n"); + + nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, num_valuators, valuators); - for (i = 0; i < nevents; i++) { - if (events->u.keyButtonPointer.time > xf86Info.lastEventTime) - xf86Info.lastEventTime = events->u.keyButtonPointer.time; - mieqEnqueue(events + i); - } - xfree(events); + for (i = 0; i < nevents; i++) + mieqEnqueue(xf86Events + i); #if 0 if (HAS_MOTION_HISTORY(local)) { @@ -791,7 +793,6 @@ xf86PostButtonEvent(DeviceIntPtr device, va_list var; int *valuators = NULL; int i = 0, nevents = 0; - xEvent *events = NULL; #ifdef DEBUG ErrorF("xf86PostButtonEvent BEGIN 0x%x(%s) button=%d down=%s is_absolute=%s\n", @@ -810,18 +811,19 @@ xf86PostButtonEvent(DeviceIntPtr device, valuators[i] = va_arg(var, int); } - nevents = GetPointerEvents(&events, device, + if (!xf86Events) + xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + if (!xf86Events) + FatalError("Couldn't allocate event store\n"); + + nevents = GetPointerEvents(xf86Events, device, is_down ? ButtonPress : ButtonRelease, button, is_absolute ? POINTER_ABSOLUTE : POINTER_RELATIVE, num_valuators, valuators); - for (i = 0; i < nevents; i++) { - if (events->u.keyButtonPointer.time > xf86Info.lastEventTime) - xf86Info.lastEventTime = events->u.keyButtonPointer.time; - mieqEnqueue(events + i); - } - xfree(events); + for (i = 0; i < nevents; i++) + mieqEnqueue(xf86Events + i); } _X_EXPORT void @@ -835,38 +837,39 @@ xf86PostKeyEvent(DeviceIntPtr device, { va_list var; int i = 0, nevents = 0, *valuators = NULL; - xEvent *events = NULL; /* instil confidence in the user */ ErrorF("this function has never been tested properly. if things go quite " "badly south after this message, then xf86PostKeyEvent is " "broken.\n"); + if (!xf86Events) + xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + if (!xf86Events) + FatalError("Couldn't allocate event store\n"); + /* the spec says that dkp/dkr events should only get valuators in * absolute mode. the spec knows all. BOW BEFORE etc. */ if (is_absolute) { - nevents = GetKeyboardValuatorEvents(&events, device, - is_down ? KeyPress : KeyRelease, - key_code, num_valuators, - valuators); valuators = xcalloc(sizeof(int), num_valuators); va_start(var, num_valuators); for (i = 0; i < num_valuators; i++) valuators[i] = va_arg(var, int); va_end(var); + + nevents = GetKeyboardValuatorEvents(xf86Events, device, + is_down ? KeyPress : KeyRelease, + key_code, num_valuators, + valuators); } else { - nevents = GetKeyboardEvents(&events, device, + nevents = GetKeyboardEvents(xf86Events, device, is_down ? KeyPress : KeyRelease, key_code); } - for (i = 0; i < nevents; i++) { - if (events->u.keyButtonPointer.time > xf86Info.lastEventTime) - xf86Info.lastEventTime = events->u.keyButtonPointer.time; - mieqEnqueue(events + i); - } - xfree(events); + for (i = 0; i < nevents; i++) + mieqEnqueue(xf86Events + i); } _X_EXPORT void @@ -874,7 +877,6 @@ xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int key_code, int is_down) { - xEvent *events = NULL; int nevents = 0, i = 0; #ifdef DEBUG @@ -882,15 +884,16 @@ xf86PostKeyboardEvent(DeviceIntPtr device, is_down ? "down" : "up", device->id); #endif - nevents = GetKeyboardEvents(&events, device, + if (!xf86Events) + xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + if (!xf86Events) + FatalError("Couldn't allocate event store\n"); + + nevents = GetKeyboardEvents(xf86Events, device, is_down ? KeyPress : KeyRelease, key_code); - for (i = 0; i < nevents; i++) { - if (events->u.keyButtonPointer.time > xf86Info.lastEventTime) - xf86Info.lastEventTime = events->u.keyButtonPointer.time; - mieqEnqueue(events + i); - } - xfree(events); + for (i = 0; i < nevents; i++) + mieqEnqueue(xf86Events + i); } /* diff --git a/include/input.h b/include/input.h index d1791e7e7..6572db5a3 100644 --- a/include/input.h +++ b/include/input.h @@ -377,8 +377,10 @@ extern void InitInput( int /*argc*/, char ** /*argv*/); +extern int GetMaximumEventsNum(void); + extern int GetPointerEvents( - xEvent **xE, + xEvent *events, DeviceIntPtr pDev, int type, int buttons, @@ -387,13 +389,13 @@ extern int GetPointerEvents( int *valuators); extern int GetKeyboardEvents( - xEvent **xE, + xEvent *events, DeviceIntPtr pDev, int type, int key_code); extern int GetKeyboardValuatorEvents( - xEvent **xE, + xEvent *events, DeviceIntPtr pDev, int type, int key_code, |