mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-25 06:59:46 -05:00
Split out evdev handling to its own file
This commit is contained in:
parent
ed64311b6c
commit
43db4015f9
4 changed files with 228 additions and 194 deletions
|
|
@ -64,199 +64,6 @@ struct drm_output {
|
|||
uint32_t current;
|
||||
};
|
||||
|
||||
struct drm_input {
|
||||
struct wlsc_input_device base;
|
||||
};
|
||||
|
||||
struct evdev_input_device {
|
||||
struct drm_input *master;
|
||||
struct wl_event_source *source;
|
||||
int tool, new_x, new_y;
|
||||
int base_x, base_y;
|
||||
int fd;
|
||||
};
|
||||
|
||||
static void evdev_input_device_data(int fd, uint32_t mask, void *data)
|
||||
{
|
||||
struct drm_compositor *c;
|
||||
struct evdev_input_device *device = data;
|
||||
struct input_event ev[8], *e, *end;
|
||||
int len, value, dx, dy, absolute_event;
|
||||
int x, y;
|
||||
uint32_t time;
|
||||
|
||||
c = (struct drm_compositor *)
|
||||
device->master->base.input_device.compositor;
|
||||
if (!c->vt_active)
|
||||
return;
|
||||
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
absolute_event = 0;
|
||||
x = device->master->base.input_device.x;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
time = e->time.tv_sec * 1000 + e->time.tv_usec / 1000;
|
||||
|
||||
switch (e->type) {
|
||||
case EV_REL:
|
||||
switch (e->code) {
|
||||
case REL_X:
|
||||
dx += value;
|
||||
break;
|
||||
|
||||
case REL_Y:
|
||||
dy += value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EV_ABS:
|
||||
absolute_event = 1;
|
||||
switch (e->code) {
|
||||
case ABS_X:
|
||||
if (device->new_x) {
|
||||
device->base_x = x - value;
|
||||
device->new_x = 0;
|
||||
}
|
||||
x = device->base_x + value;
|
||||
break;
|
||||
case ABS_Y:
|
||||
if (device->new_y) {
|
||||
device->base_y = y - value;
|
||||
device->new_y = 0;
|
||||
}
|
||||
y = device->base_y + value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EV_KEY:
|
||||
if (value == 2)
|
||||
break;
|
||||
|
||||
switch (e->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:
|
||||
if (device->tool == 0 && value) {
|
||||
device->new_x = 1;
|
||||
device->new_y = 1;
|
||||
}
|
||||
device->tool = value ? e->code : 0;
|
||||
break;
|
||||
|
||||
case BTN_LEFT:
|
||||
case BTN_RIGHT:
|
||||
case BTN_MIDDLE:
|
||||
case BTN_SIDE:
|
||||
case BTN_EXTRA:
|
||||
case BTN_FORWARD:
|
||||
case BTN_BACK:
|
||||
case BTN_TASK:
|
||||
notify_button(&device->master->base.input_device,
|
||||
time, e->code, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
notify_key(&device->master->base.input_device,
|
||||
time, e->code, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dx != 0 || dy != 0)
|
||||
notify_motion(&device->master->base.input_device,
|
||||
time, x + dx, y + dy);
|
||||
if (absolute_event && device->tool)
|
||||
notify_motion(&device->master->base.input_device, time, x, y);
|
||||
}
|
||||
|
||||
static struct evdev_input_device *
|
||||
evdev_input_device_create(struct drm_input *master,
|
||||
struct wl_display *display, const char *path)
|
||||
{
|
||||
struct evdev_input_device *device;
|
||||
struct wl_event_loop *loop;
|
||||
|
||||
device = malloc(sizeof *device);
|
||||
if (device == NULL)
|
||||
return NULL;
|
||||
|
||||
device->tool = 1;
|
||||
device->new_x = 1;
|
||||
device->new_y = 1;
|
||||
device->master = master;
|
||||
|
||||
device->fd = open(path, O_RDONLY);
|
||||
if (device->fd < 0) {
|
||||
free(device);
|
||||
fprintf(stderr, "couldn't create pointer for %s: %m\n", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
loop = wl_display_get_event_loop(display);
|
||||
device->source = wl_event_loop_add_fd(loop, device->fd,
|
||||
WL_EVENT_READABLE,
|
||||
evdev_input_device_data, device);
|
||||
if (device->source == NULL) {
|
||||
close(device->fd);
|
||||
free(device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static void
|
||||
drm_input_create(struct drm_compositor *c)
|
||||
{
|
||||
struct drm_input *input;
|
||||
struct udev_enumerate *e;
|
||||
struct udev_list_entry *entry;
|
||||
struct udev_device *device;
|
||||
const char *path;
|
||||
|
||||
input = malloc(sizeof *input);
|
||||
if (input == NULL)
|
||||
return;
|
||||
|
||||
memset(input, 0, sizeof *input);
|
||||
wlsc_input_device_init(&input->base, &c->base);
|
||||
|
||||
e = udev_enumerate_new(c->udev);
|
||||
udev_enumerate_add_match_subsystem(e, "input");
|
||||
udev_enumerate_add_match_property(e, "WAYLAND_SEAT", "1");
|
||||
udev_enumerate_scan_devices(e);
|
||||
udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
|
||||
path = udev_list_entry_get_name(entry);
|
||||
device = udev_device_new_from_syspath(c->udev, path);
|
||||
evdev_input_device_create(input, c->base.wl_display,
|
||||
udev_device_get_devnode(device));
|
||||
}
|
||||
udev_enumerate_unref(e);
|
||||
|
||||
c->base.input_device = &input->base.input_device;
|
||||
}
|
||||
|
||||
static void
|
||||
drm_compositor_present(struct wlsc_compositor *ec)
|
||||
{
|
||||
|
|
@ -683,7 +490,7 @@ drm_compositor_create(struct wl_display *display, int connector)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
drm_input_create(ec);
|
||||
evdev_input_add_devices(&ec->base, ec->udev);
|
||||
|
||||
loop = wl_display_get_event_loop(ec->base.wl_display);
|
||||
ec->drm_source =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue