[PATCH v2] evdev: Only send the events at synchronization time.
Oliver McFadden
oliver.mcfadden at nokia.com
Mon Jul 27 01:15:18 PDT 2009
On Mon, 2009-07-27 at 05:01 +0200, ext Peter Hutterer wrote:
> On Thu, Jul 23, 2009 at 01:19:49PM +0300, oliver.mcfadden at nokia.com wrote:
> > From: Oliver McFadden <oliver.mcfadden at nokia.com>
> >
> > Instead of just posting the button/key press/release events to the
> > server as soon as they arrive, add them to an internal queue and post
> > them once we receive an EV_SYN synchronization event.
> >
> > The motion events are always sent first, followed by the queued events.
> > There will be one motion event and possibly many queued button/key
> > events posted every EV_SYN event.
> >
> > Note that the size of the event queue (EVDEV_MAXQUEUE) is arbitrary and
> > you may change it. If we receive more events than the queue can handle,
> > those events are dropped and a warning message printed.
> >
> > Tested on my Lenovo T400 using evdev for all input devices; keyboard,
> > touchpad, and trackpoint.
>
> This patch breaks scrolling on my mouse. Please test again, I haven't dug
> into why it happens, I presume some button mapping gone awol.
Hmm, I didn't see this, but I don't use an external mouse very often. I
will try to look into it ASAP.
> Cheers,
> Peter
>
> > ---
> > src/evdev.c | 559 +++++++++++++++++++++++++++++++++++++++--------------------
> > src/evdev.h | 18 ++
> > 2 files changed, 386 insertions(+), 191 deletions(-)
> >
> > diff --git a/src/evdev.c b/src/evdev.c
> > index ecca94a..266209a 100644
> > --- a/src/evdev.c
> > +++ b/src/evdev.c
> > @@ -249,21 +249,12 @@ static int wheel_left_button = 6;
> > static int wheel_right_button = 7;
> >
> > static void
> > -PostButtonClicks(InputInfoPtr pInfo, int button, int count)
> > -{
> > - int i;
> > -
> > - for (i = 0; i < count; i++) {
> > - xf86PostButtonEvent(pInfo->dev, 0, button, 1, 0, 0);
> > - xf86PostButtonEvent(pInfo->dev, 0, button, 0, 0, 0);
> > - }
> > -}
> > -
> > -static void
> > PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
> > {
> > int code = ev->code + MIN_KEYCODE;
> > static char warned[KEY_CNT];
> > + EventQueuePtr pQueue;
> > + EvdevPtr pEvdev = pInfo->private;
> >
> > /* Filter all repeated events from device.
> > We'll do softrepeat in the server, but only since 1.6 */
> > @@ -292,7 +283,47 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
> > return;
> > }
> >
> > - xf86PostKeyboardEvent(pInfo->dev, code, value);
> > + if (pEvdev->num_queue >= EVDEV_MAXQUEUE)
> > + {
> > + xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name);
> > + return;
> > + }
> > +
> > + pQueue = &pEvdev->queue[pEvdev->num_queue];
> > + pQueue->type = EV_QUEUE_KEY;
> > + pQueue->key = code;
> > + pQueue->val = value;
> > + pEvdev->num_queue++;
> > +}
> > +
> > +static void
> > +PostButtonEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
> > +{
> > + EventQueuePtr pQueue;
> > + EvdevPtr pEvdev = pInfo->private;
> > +
> > + if (pEvdev->num_queue >= EVDEV_MAXQUEUE)
> > + {
> > + xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name);
> > + return;
> > + }
> > +
> > + pQueue = &pEvdev->queue[pEvdev->num_queue];
> > + pQueue->type = EV_QUEUE_BTN;
> > + pQueue->key = EvdevUtilButtonEventToButtonNumber(pEvdev, ev->code);
> > + pQueue->val = value;
> > + pEvdev->num_queue++;
> > +}
> > +
> > +static void
> > +PostButtonClicks(InputInfoPtr pInfo, struct input_event *ev, int button, int count)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < count; i++) {
> > + PostButtonEvent(pInfo, ev, 1);
> > + PostButtonEvent(pInfo, ev, 0);
> > + }
> > }
> >
> > /**
> > @@ -349,212 +380,358 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
> > #define ABS_Y_VALUE 0x2
> > #define ABS_VALUE 0x4
> > /**
> > - * Take one input event and process it accordingly.
> > + * Take the valuators and process them accordingly.
> > */
> > static void
> > -EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
> > +EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
> > + int *first_v)
> > +{
> > + int tmp;
> > + EvdevPtr pEvdev = pInfo->private;
> > +
> > + *num_v = *first_v = 0;
> > +
> > + /* convert to relative motion for touchpads */
> > + if (pEvdev->abs && (pEvdev->flags & EVDEV_TOUCHPAD)) {
> > + if (pEvdev->tool) { /* meaning, touch is active */
> > + if (pEvdev->old_vals[0] != -1)
> > + pEvdev->delta[REL_X] = pEvdev->vals[0] - pEvdev->old_vals[0];
> > + if (pEvdev->old_vals[1] != -1)
> > + pEvdev->delta[REL_Y] = pEvdev->vals[1] - pEvdev->old_vals[1];
> > + if (pEvdev->abs & ABS_X_VALUE)
> > + pEvdev->old_vals[0] = pEvdev->vals[0];
> > + if (pEvdev->abs & ABS_Y_VALUE)
> > + pEvdev->old_vals[1] = pEvdev->vals[1];
> > + } else {
> > + pEvdev->old_vals[0] = pEvdev->old_vals[1] = -1;
> > + }
> > + pEvdev->abs = 0;
> > + pEvdev->rel = 1;
> > + }
> > +
> > + if (pEvdev->rel) {
> > + int first = REL_CNT, last = 0;
> > + int i;
> > +
> > + if (pEvdev->swap_axes) {
> > + tmp = pEvdev->delta[REL_X];
> > + pEvdev->delta[REL_X] = pEvdev->delta[REL_Y];
> > + pEvdev->delta[REL_Y] = tmp;
> > + }
> > + if (pEvdev->invert_x)
> > + pEvdev->delta[REL_X] *= -1;
> > + if (pEvdev->invert_y)
> > + pEvdev->delta[REL_Y] *= -1;
> > +
> > + for (i = 0; i < REL_CNT; i++)
> > + {
> > + int map = pEvdev->axis_map[i];
> > + if (pEvdev->delta[i] && map != -1)
> > + {
> > + v[map] = pEvdev->delta[i];
> > + if (map < first)
> > + first = map;
> > + if (map > last)
> > + last = map;
> > + }
> > + }
> > +
> > + *num_v = (last - first + 1);
> > + *first_v = first;
> > + }
> > + /*
> > + * Some devices only generate valid abs coords when BTN_DIGI is
> > + * pressed. On wacom tablets, this means that the pen is in
> > + * proximity of the tablet. After the pen is removed, BTN_DIGI is
> > + * released, and a (0, 0) absolute event is generated. Checking
> > + * pEvdev->digi here, lets us ignore that event. pEvdev is
> > + * initialized to 1 so devices that doesn't use this scheme still
> > + * just works.
> > + */
> > + else if (pEvdev->abs && pEvdev->tool) {
> > + memcpy(v, pEvdev->vals, sizeof(int) * pEvdev->num_vals);
> > + if (pEvdev->flags & EVDEV_CALIBRATED)
> > + {
> > + v[0] = xf86ScaleAxis(v[0],
> > + pEvdev->absinfo[ABS_X].maximum,
> > + pEvdev->absinfo[ABS_X].minimum,
> > + pEvdev->calibration.max_x, pEvdev->calibration.min_x);
> > + v[1] = xf86ScaleAxis(v[1],
> > + pEvdev->absinfo[ABS_Y].maximum,
> > + pEvdev->absinfo[ABS_Y].minimum,
> > + pEvdev->calibration.max_y, pEvdev->calibration.min_y);
> > + }
> > +
> > + if (pEvdev->swap_axes) {
> > + int tmp = v[0];
> > + v[0] = v[1];
> > + v[1] = tmp;
> > + }
> > +
> > + if (pEvdev->invert_x)
> > + v[0] = (pEvdev->absinfo[ABS_X].maximum - v[0] +
> > + pEvdev->absinfo[ABS_X].minimum);
> > + if (pEvdev->invert_y)
> > + v[1] = (pEvdev->absinfo[ABS_Y].maximum - v[1] +
> > + pEvdev->absinfo[ABS_Y].minimum);
> > +
> > + *num_v = pEvdev->num_vals;
> > + *first_v = 0;
> > + }
> > +}
> > +
> > +/**
> > + * Take a button input event and process it accordingly.
> > + */
> > +static void
> > +EvdevProcessButtonEvent(InputInfoPtr pInfo, struct input_event *ev)
> > {
> > - static int delta[REL_CNT];
> > - static int tmp, value;
> > - static unsigned int abs, rel;
> > unsigned int button;
> > + int value;
> > EvdevPtr pEvdev = pInfo->private;
> >
> > + button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev->code);
> > +
> > /* Get the signed value, earlier kernels had this as unsigned */
> > value = ev->value;
> >
> > - switch (ev->type) {
> > - case EV_REL:
> > - /* Ignore EV_REL events if we never set up for them. */
> > - if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS))
> > - break;
> > + /* Handle drag lock */
> > + if (EvdevDragLockFilterEvent(pInfo, button, value))
> > + return;
> >
> > - /* Handle mouse wheel emulation */
> > - if (EvdevWheelEmuFilterMotion(pInfo, ev))
> > - break;
> > + if (EvdevWheelEmuFilterButton(pInfo, button, value))
> > + return;
> >
> > - rel = 1;
> > -
> > - switch (ev->code) {
> > - case REL_WHEEL:
> > - if (value > 0)
> > - PostButtonClicks(pInfo, wheel_up_button, value);
> > - else if (value < 0)
> > - PostButtonClicks(pInfo, wheel_down_button, -value);
> > - break;
> > -
> > - case REL_DIAL:
> > - case REL_HWHEEL:
> > - if (value > 0)
> > - PostButtonClicks(pInfo, wheel_right_button, value);
> > - else if (value < 0)
> > - PostButtonClicks(pInfo, wheel_left_button, -value);
> > - break;
> > -
> > - /* We don't post wheel events as axis motion. */
> > - default:
> > - delta[ev->code] += value;
> > - break;
> > - }
> > + if (EvdevMBEmuFilterEvent(pInfo, button, value))
> > + return;
> > +
> > + if (button)
> > + PostButtonEvent(pInfo, ev, value);
> > + else
> > + PostKbdEvent(pInfo, ev, value);
> > +}
> > +
> > +/**
> > + * Take the relative motion input event and process it accordingly.
> > + */
> > +static void
> > +EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
> > +{
> > + static int value;
> > + EvdevPtr pEvdev = pInfo->private;
> > +
> > + /* Get the signed value, earlier kernels had this as unsigned */
> > + value = ev->value;
> > +
> > + /* Ignore EV_REL events if we never set up for them. */
> > + if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS))
> > + return;
> > +
> > + /* Handle mouse wheel emulation */
> > + if (EvdevWheelEmuFilterMotion(pInfo, ev))
> > + return;
> > +
> > + pEvdev->rel = 1;
> > +
> > + switch (ev->code) {
> > + case REL_WHEEL:
> > + if (value > 0)
> > + PostButtonClicks(pInfo, ev, wheel_up_button, value);
> > + else if (value < 0)
> > + PostButtonClicks(pInfo, ev, wheel_down_button, -value);
> > break;
> >
> > - case EV_ABS:
> > - /* Ignore EV_ABS events if we never set up for them. */
> > - if (!(pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
> > - break;
> > + case REL_DIAL:
> > + case REL_HWHEEL:
> > + if (value > 0)
> > + PostButtonClicks(pInfo, ev, wheel_right_button, value);
> > + else if (value < 0)
> > + PostButtonClicks(pInfo, ev, wheel_left_button, -value);
> > + break;
> >
> > - if (ev->code > ABS_MAX)
> > - break;
> > - pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
> > - if (ev->code == ABS_X)
> > - abs |= ABS_X_VALUE;
> > - else if (ev->code == ABS_Y)
> > - abs |= ABS_Y_VALUE;
> > - else
> > - abs |= ABS_VALUE;
> > + /* We don't post wheel events as axis motion. */
> > + default:
> > + pEvdev->delta[ev->code] += value;
> > break;
> > + }
> > +}
> >
> > - case EV_KEY:
> > - /* don't repeat mouse buttons */
> > - if (ev->code >= BTN_MOUSE && ev->code < KEY_OK)
> > - if (value == 2)
> > - break;
> > -
> > - switch (ev->code) {
> > - case BTN_TOUCH:
> > - case BTN_TOOL_PEN:
> > - case BTN_TOOL_RUBBER:
> > - case BTN_TOOL_BRUSH:
> > - case BTN_TOOL_PENCIL:
> > - case BTN_TOOL_AIRBRUSH:
> > - case BTN_TOOL_FINGER:
> > - case BTN_TOOL_MOUSE:
> > - case BTN_TOOL_LENS:
> > - pEvdev->tool = value ? ev->code : 0;
> > - if (!(pEvdev->flags & EVDEV_TOUCHSCREEN))
> > - break;
> > - /* Treat BTN_TOUCH from devices that only have BTN_TOUCH as
> > - * BTN_LEFT. */
> > - ev->code = BTN_LEFT;
> > - /* Intentional fallthrough! */
> > -
> > - default:
> > - button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev->code);
> > -
> > - /* Handle drag lock */
> > - if (EvdevDragLockFilterEvent(pInfo, button, value))
> > - break;
> > -
> > - if (EvdevWheelEmuFilterButton(pInfo, button, value))
> > - break;
> > -
> > - if (EvdevMBEmuFilterEvent(pInfo, button, value))
> > - break;
> > -
> > - if (button)
> > - xf86PostButtonEvent(pInfo->dev, 0, button, value, 0, 0);
> > - else
> > - PostKbdEvent(pInfo, ev, value);
> > - break;
> > - }
> > +/**
> > + * Take the absolute motion input event and process it accordingly.
> > + */
> > +static void
> > +EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
> > +{
> > + static int value;
> > + EvdevPtr pEvdev = pInfo->private;
> > +
> > + /* Get the signed value, earlier kernels had this as unsigned */
> > + value = ev->value;
> > +
> > + /* Ignore EV_ABS events if we never set up for them. */
> > + if (!(pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
> > + return;
> > +
> > + if (ev->code > ABS_MAX)
> > + return;
> > +
> > + pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
> > + if (ev->code == ABS_X)
> > + pEvdev->abs |= ABS_X_VALUE;
> > + else if (ev->code == ABS_Y)
> > + pEvdev->abs |= ABS_Y_VALUE;
> > + else
> > + pEvdev->abs |= ABS_VALUE;
> > +}
> > +
> > +/**
> > + * Take the key press/release input event and process it accordingly.
> > + */
> > +static void
> > +EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
> > +{
> > + static int value;
> > + EvdevPtr pEvdev = pInfo->private;
> > +
> > + /* Get the signed value, earlier kernels had this as unsigned */
> > + value = ev->value;
> > +
> > + /* don't repeat mouse buttons */
> > + if (ev->code >= BTN_MOUSE && ev->code < KEY_OK)
> > + if (value == 2)
> > + return;
> > +
> > + switch (ev->code) {
> > + case BTN_TOUCH:
> > + case BTN_TOOL_PEN:
> > + case BTN_TOOL_RUBBER:
> > + case BTN_TOOL_BRUSH:
> > + case BTN_TOOL_PENCIL:
> > + case BTN_TOOL_AIRBRUSH:
> > + case BTN_TOOL_FINGER:
> > + case BTN_TOOL_MOUSE:
> > + case BTN_TOOL_LENS:
> > + pEvdev->tool = value ? ev->code : 0;
> > + if (!(pEvdev->flags & EVDEV_TOUCHSCREEN))
> > + break;
> > + /* Treat BTN_TOUCH from devices that only have BTN_TOUCH as
> > + * BTN_LEFT. */
> > + ev->code = BTN_LEFT;
> > + /* Intentional fallthrough! */
> > +
> > + default:
> > + EvdevProcessButtonEvent(pInfo, ev);
> > break;
> > + }
> > +}
> >
> > - case EV_SYN:
> > - /* convert to relative motion for touchpads */
> > - if (abs && (pEvdev->flags & EVDEV_TOUCHPAD)) {
> > - if (pEvdev->tool) { /* meaning, touch is active */
> > - if (pEvdev->old_vals[0] != -1)
> > - delta[REL_X] = pEvdev->vals[0] - pEvdev->old_vals[0];
> > - if (pEvdev->old_vals[1] != -1)
> > - delta[REL_Y] = pEvdev->vals[1] - pEvdev->old_vals[1];
> > - if (abs & ABS_X_VALUE)
> > - pEvdev->old_vals[0] = pEvdev->vals[0];
> > - if (abs & ABS_Y_VALUE)
> > - pEvdev->old_vals[1] = pEvdev->vals[1];
> > - } else {
> > - pEvdev->old_vals[0] = pEvdev->old_vals[1] = -1;
> > - }
> > - abs = 0;
> > - rel = 1;
> > - }
> > +/**
> > + * Post the relative motion events.
> > + */
> > +static void
> > +EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
> > + int v[MAX_VALUATORS])
> > +{
> > + EvdevPtr pEvdev = pInfo->private;
> >
> > - if (rel) {
> > - int post_deltas[REL_CNT] = {0}; /* axis-mapped deltas */
> > - int first = REL_CNT, last = 0;
> > - int i;
> > + if (pEvdev->rel) {
> > + xf86PostMotionEventP(pInfo->dev, FALSE, *first_v, *num_v, v + *first_v);
> > + }
> > +}
> >
> > - if (pEvdev->swap_axes) {
> > - tmp = delta[REL_X];
> > - delta[REL_X] = delta[REL_Y];
> > - delta[REL_Y] = tmp;
> > - }
> > - if (pEvdev->invert_x)
> > - delta[REL_X] *= -1;
> > - if (pEvdev->invert_y)
> > - delta[REL_Y] *= -1;
> > +/**
> > + * Post the absolute motion events.
> > + */
> > +static void
> > +EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
> > + int v[MAX_VALUATORS])
> > +{
> > + EvdevPtr pEvdev = pInfo->private;
> >
> > - for (i = 0; i < REL_CNT; i++)
> > - {
> > - int map = pEvdev->axis_map[i];
> > - if (delta[i] && map != -1)
> > - {
> > - post_deltas[map] = delta[i];
> > - if (map < first)
> > - first = map;
> > - if (map > last)
> > - last = map;
> > - }
> > - }
> > + /*
> > + * Some devices only generate valid abs coords when BTN_DIGI is
> > + * pressed. On wacom tablets, this means that the pen is in
> > + * proximity of the tablet. After the pen is removed, BTN_DIGI is
> > + * released, and a (0, 0) absolute event is generated. Checking
> > + * pEvdev->digi here, lets us ignore that event. pEvdev is
> > + * initialized to 1 so devices that doesn't use this scheme still
> > + * just works.
> > + */
> > + if (pEvdev->abs && pEvdev->tool) {
> > + xf86PostMotionEventP(pInfo->dev, TRUE, *first_v, *num_v, v);
> > + }
> > +}
> >
> > - xf86PostMotionEventP(pInfo->dev, FALSE, first,
> > - (last - first + 1), &post_deltas[first]);
> > - }
> > +/**
> > + * Post the queued key/button events.
> > + */
> > +static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
> > + int v[MAX_VALUATORS])
> > +{
> > + int i;
> > + EvdevPtr pEvdev = pInfo->private;
> >
> > - /*
> > - * Some devices only generate valid abs coords when BTN_DIGI is
> > - * pressed. On wacom tablets, this means that the pen is in
> > - * proximity of the tablet. After the pen is removed, BTN_DIGI is
> > - * released, and a (0, 0) absolute event is generated. Checking
> > - * pEvdev->digi here, lets us ignore that event. pEvdev is
> > - * initialized to 1 so devices that doesn't use this scheme still
> > - * just works.
> > - */
> > - if (abs && pEvdev->tool) {
> > - int v[MAX_VALUATORS];
> > -
> > - memcpy(v, pEvdev->vals, sizeof(int) * pEvdev->num_vals);
> > - if (pEvdev->flags & EVDEV_CALIBRATED)
> > - {
> > - v[0] = xf86ScaleAxis(v[0],
> > - pEvdev->absinfo[ABS_X].maximum,
> > - pEvdev->absinfo[ABS_X].minimum,
> > - pEvdev->calibration.max_x, pEvdev->calibration.min_x);
> > - v[1] = xf86ScaleAxis(v[1],
> > - pEvdev->absinfo[ABS_Y].maximum,
> > - pEvdev->absinfo[ABS_Y].minimum,
> > - pEvdev->calibration.max_y, pEvdev->calibration.min_y);
> > - }
> > + for (i = 0; i < pEvdev->num_queue; i++) {
> > + switch (pEvdev->queue[i].type) {
> > + case EV_QUEUE_KEY:
> > + xf86PostKeyboardEvent(pInfo->dev, pEvdev->queue[i].key,
> > + pEvdev->queue[i].val);
> > + break;
> > + case EV_QUEUE_BTN:
> > + /* FIXME: Add xf86PostButtonEventP to the X server so that we may
> > + * pass the valuators on ButtonPress/Release events, too. Currently
> > + * only MotionNotify events contain the pointer position. */
> > + xf86PostButtonEvent(pInfo->dev, 0, pEvdev->queue[i].key,
> > + pEvdev->queue[i].val, 0, 0);
> > + break;
> > + }
> > + }
> > +}
> >
> > - if (pEvdev->swap_axes) {
> > - int tmp = v[0];
> > - v[0] = v[1];
> > - v[1] = tmp;
> > - }
> > +/**
> > + * Take the synchronization input event and process it accordingly; the motion
> > + * notify events are sent first, then any button/key press/release events.
> > + */
> > +static void
> > +EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
> > +{
> > + int num_v = 0, first_v = 0;
> > + int v[MAX_VALUATORS];
> > + EvdevPtr pEvdev = pInfo->private;
> >
> > - if (pEvdev->invert_x)
> > - v[0] = (pEvdev->absinfo[ABS_X].maximum - v[0] +
> > - pEvdev->absinfo[ABS_X].minimum);
> > - if (pEvdev->invert_y)
> > - v[1] = (pEvdev->absinfo[ABS_Y].maximum - v[1] +
> > - pEvdev->absinfo[ABS_Y].minimum);
> > + EvdevProcessValuators(pInfo, v, &num_v, &first_v);
> >
> > - xf86PostMotionEventP(pInfo->dev, TRUE, 0, pEvdev->num_vals, v);
> > - }
> > + EvdevPostRelativeMotionEvents(pInfo, &num_v, &first_v, v);
> > + EvdevPostAbsoluteMotionEvents(pInfo, &num_v, &first_v, v);
> > + EvdevPostQueuedEvents(pInfo, &num_v, &first_v, v);
> > +
> > + memset(pEvdev->delta, 0, sizeof(pEvdev->delta));
> > + memset(pEvdev->queue, 0, sizeof(pEvdev->queue));
> > + pEvdev->num_queue = 0;
> > + pEvdev->abs = 0;
> > + pEvdev->rel = 0;
> > +}
> >
> > - memset(delta, 0, sizeof(delta));
> > - tmp = 0;
> > - abs = 0;
> > - rel = 0;
> > +/**
> > + * Process the events from the server; nothing is actually posted to the server
> > + * until an EV_SYN event is received.
> > + */
> > +static void
> > +EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
> > +{
> > + switch (ev->type) {
> > + case EV_REL:
> > + EvdevProcessRelativeMotionEvent(pInfo, ev);
> > + break;
> > + case EV_ABS:
> > + EvdevProcessAbsoluteMotionEvent(pInfo, ev);
> > + break;
> > + case EV_KEY:
> > + EvdevProcessKeyEvent(pInfo, ev);
> > + break;
> > + case EV_SYN:
> > + EvdevProcessSyncEvent(pInfo, ev);
> > + break;
> > }
> > }
> >
> > diff --git a/src/evdev.h b/src/evdev.h
> > index 5b95369..23ee003 100644
> > --- a/src/evdev.h
> > +++ b/src/evdev.h
> > @@ -54,6 +54,7 @@
> > #endif
> >
> > #define EVDEV_MAXBUTTONS 32
> > +#define EVDEV_MAXQUEUE 32
> >
> > #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
> > #define HAVE_PROPERTIES 1
> > @@ -87,6 +88,16 @@ typedef struct {
> > int traveled_distance;
> > } WheelAxis, *WheelAxisPtr;
> >
> > +/* Event queue used to defer keyboard/button events until EV_SYN time. */
> > +typedef struct {
> > + enum {
> > + EV_QUEUE_KEY, /* xf86PostKeyboardEvent() */
> > + EV_QUEUE_BTN, /* xf86PostButtonEvent() */
> > + } type;
> > + int key; /* May be either a key code or button number. */
> > + int val; /* State of the key/button; pressed or released. */
> > +} EventQueueRec, *EventQueuePtr;
> > +
> > typedef struct {
> > const char *device;
> > int grabDevice; /* grab the event device? */
> > @@ -103,6 +114,9 @@ typedef struct {
> > BOOL invert_x;
> > BOOL invert_y;
> >
> > + int delta[REL_CNT];
> > + unsigned int abs, rel;
> > +
> > /* XKB stuff has to be per-device rather than per-driver */
> > #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5
> > XkbComponentNamesRec xkbnames;
> > @@ -159,6 +173,10 @@ typedef struct {
> >
> > /* minor/major number */
> > dev_t min_maj;
> > +
> > + /* Event queue used to defer keyboard/button events until EV_SYN time. */
> > + int num_queue;
> > + EventQueueRec queue[EVDEV_MAXQUEUE];
> > } EvdevRec, *EvdevPtr;
> >
> > unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code);
> > --
> > 1.6.1
> >
More information about the xorg-devel
mailing list