[PATCH 6/9] evdev: organize main event processing loop
Tiago Vignatti
tiago.vignatti at intel.com
Mon Oct 24 07:42:19 PDT 2011
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++)
+ evdev_process_event(device, &ev[i]);
+ }
- device->abs_queued = 0;
return 1;
}
--
1.7.5.4
More information about the wayland-devel
mailing list