[PATCH 6/9] evdev: organize main event processing loop
Kristian Høgsberg
krh at bitplanet.net
Mon Oct 24 08:10:18 PDT 2011
On Mon, Oct 24, 2011 at 10:42 AM, Tiago Vignatti
<tiago.vignatti at intel.com> wrote:
> No functional changes on this commit, but the general idea was stolen from X
> input evdev with the intents of copying pretty much the way done there which
> will ease next when implementing a smarter method for computing valuators.
>
> Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
> ---
> compositor/evdev.c | 124 ++++++++++++++++++++++++++++++++++------------------
> 1 files changed, 82 insertions(+), 42 deletions(-)
>
> diff --git a/compositor/evdev.c b/compositor/evdev.c
> index 3661236..72247a6 100644
> --- a/compositor/evdev.c
> +++ b/compositor/evdev.c
> @@ -26,6 +26,7 @@
> #include <linux/input.h>
> #include <unistd.h>
> #include <fcntl.h>
> +#include <errno.h>
>
> #include "compositor.h"
>
> @@ -49,13 +50,18 @@ struct evdev_input_device {
> int is_touchpad, old_x_value, old_y_value, reset_x_value, reset_y_value;
> uint32_t time;
>
> - uint32_t abs_queued;
> + uint32_t abs_queued, rel_queued;
> };
>
> static inline void
> -evdev_process_key(struct evdev_input_device *device,
> - struct input_event *e, int value)
> +evdev_process_key(struct evdev_input_device *device, struct input_event *e)
> {
> + /* Get the signed value, earlier kernels had this as unsigned */
> + int value = e->value;
> +
> + if (value == 2)
> + return;
> +
> switch (e->code) {
> case BTN_TOOL_PEN:
> case BTN_TOOL_RUBBER:
> @@ -98,8 +104,10 @@ evdev_process_key(struct evdev_input_device *device,
>
> static inline void
> evdev_process_absolute_motion(struct evdev_input_device *device,
> - struct input_event *e, int value)
> + struct input_event *e)
> {
> + /* Get the signed value, earlier kernels had this as unsigned */
> + int value = e->value;
> const int screen_width = device->output->current->width;
> const int screen_height = device->output->current->height;
>
> @@ -119,8 +127,11 @@ evdev_process_absolute_motion(struct evdev_input_device *device,
>
> static inline void
> evdev_process_absolute_motion_touchpad(struct evdev_input_device *device,
> - struct input_event *e, int value)
> + struct input_event *e)
> {
> + /* Get the signed value, earlier kernels had this as unsigned */
> + int value = e->value;
> +
> /* FIXME: Make this configurable somehow. */
> const int touchpad_speed = 700;
>
> @@ -147,12 +158,18 @@ evdev_process_absolute_motion_touchpad(struct evdev_input_device *device,
> device->old_y_value = value;
> break;
> }
> +
> + /* we converted to relative motion so treat accordingly */
> + device->rel_queued = 1;
> }
>
> static inline void
> evdev_process_relative_motion(struct evdev_input_device *device,
> - struct input_event *e, int value)
> + struct input_event *e)
> {
> + /* Get the signed value, earlier kernels had this as unsigned */
> + int value = e->value;
> +
> switch (e->code) {
> case REL_X:
> device->dx += value;
> @@ -161,15 +178,58 @@ evdev_process_relative_motion(struct evdev_input_device *device,
> device->dy += value;
> break;
> }
> + device->rel_queued = 1;
> }
>
> +static inline void
> +evdev_notify(struct evdev_input_device *device, struct input_event *e)
> +{
> + if (device->rel_queued)
> + notify_motion(&device->master->base.input_device,
> + device->time, device->x + device->dx,
> + device->y + device->dy);
> +
> + if (device->abs_queued)
> + notify_motion(&device->master->base.input_device,
> + device->time, device->x, device->y);
> +
> +
> + device->rel_queued = 0;
> + device->abs_queued = 0;
> +}
> +
> +static void
> +evdev_process_event(struct evdev_input_device *device, struct input_event *e)
> +{
> + device->time = e->time.tv_sec * 1000 + e->time.tv_usec / 1000;
> +
> + switch (e->type) {
> + case EV_REL:
> + evdev_process_relative_motion(device, e);
> + break;
> + case EV_ABS:
> + if (device->is_touchpad)
> + evdev_process_absolute_motion_touchpad(device, e);
> + else
> + evdev_process_absolute_motion(device, e);
> + break;
> + case EV_KEY:
> + evdev_process_key(device, e);
> + break;
> + }
> +
> + evdev_notify(device, e);
> +}
> +
> +#define NUM_EVENTS 16
> +
> static int
> evdev_input_device_data(int fd, uint32_t mask, void *data)
> {
> struct wlsc_compositor *ec;
> struct evdev_input_device *device = data;
> - struct input_event ev[8], *e, *end;
> - int len, value;
> + struct input_event ev[NUM_EVENTS];
> + int i, len = sizeof(ev);
>
> ec = (struct wlsc_compositor *)
> device->master->base.input_device.compositor;
> @@ -181,45 +241,25 @@ evdev_input_device_data(int fd, uint32_t mask, void *data)
> device->x = device->master->base.input_device.x;
> device->y = device->master->base.input_device.y;
>
> - len = read(fd, &ev, sizeof ev);
> - if (len < 0 || len % sizeof e[0] != 0) {
> - /* FIXME: handle error... reopen device? */;
> - return 1;
> - }
> -
> - e = ev;
> - end = (void *) ev + len;
> - for (e = ev; e < end; e++) {
> - /* Get the signed value, earlier kernels had this as unsigned */
> - value = e->value;
> - device->time = e->time.tv_sec * 1000 + e->time.tv_usec / 1000;
> -
> - switch (e->type) {
> - case EV_REL:
> - evdev_process_relative_motion(device, e, value);
> + while (len == sizeof(ev))
> + {
> + len = read(fd, &ev, sizeof(ev));
> + if (len <= 0) {
> + /* FIXME: handle error... reopen device? */
> + fprintf(stderr, "input read error %s", strerror(errno));
> break;
> - case EV_ABS:
> - if (device->is_touchpad)
> - evdev_process_absolute_motion_touchpad(device,
> - e, value);
> - else
> - evdev_process_absolute_motion(device, e, value);
> + }
> + /* The kernel promises that we always only read a complete
> + * event, so len != sizeof ev is an error. */
> + if (len % sizeof(ev[0])) {
> + fprintf(stderr, "input read error %s", strerror(errno));
> break;
> - case EV_KEY:
> - if (value == 2)
> - break;
> - evdev_process_key(device, e, value);
> }
> - }
>
> - if (device->dx != 0 || device->dy != 0)
> - notify_motion(&device->master->base.input_device,
> - device->time, device->x + device->dx, device->y + device->dy);
> - if (device->abs_queued)
> - notify_motion(&device->master->base.input_device, device->time,
> - device->x, device->y);
> + for (i = 0; i < len/sizeof(ev[0]); i++)
Spaces around /. And use a new 'count' variable to compute the number
elements outside the loop, eg:
count = len / sizeof ev[0];
Kristian
> + evdev_process_event(device, &ev[i]);
> + }
>
> - device->abs_queued = 0;
> return 1;
> }
>
> --
> 1.7.5.4
>
>
More information about the wayland-devel
mailing list