[PATCH v2] evdev: Only send the events at synchronization time.
Peter Hutterer
peter.hutterer at who-t.net
Sun Jul 26 20:01:17 PDT 2009
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.
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