[PATCH 6/9] evdev: organize main event processing loop
Kristian Høgsberg
krh at bitplanet.net
Mon Oct 24 08:11:42 PDT 2011
2011/10/24 Kristian Høgsberg <krh at bitplanet.net>:
> 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
Oh, and no need for this define.
>> +
>> 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