diff options
-rw-r--r-- | rcm-server-evdev.c | 137 | ||||
-rw-r--r-- | rcm-server-evdev.h | 4 | ||||
-rw-r--r-- | rcm-server-main.c | 133 |
3 files changed, 139 insertions, 135 deletions
diff --git a/rcm-server-evdev.c b/rcm-server-evdev.c index bc8361e..74cae10 100644 --- a/rcm-server-evdev.c +++ b/rcm-server-evdev.c @@ -6,6 +6,9 @@ #include <systemd/sd-bus.h> #include <errno.h> #include <linux/input.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include "utils.h" #include "shared.h" @@ -33,7 +36,7 @@ struct rc_keymap_entry { }; #define RKE_SIZE (sizeof(struct rc_scancode)) -const char * +static const char * evdev_guess_protocol(struct device *device, uint64_t scancode, uint32_t keycode) { struct rc_keymap_entry rke; @@ -137,15 +140,134 @@ evdev_set_keymap(struct device *device, struct keymap *keymap) return 0; } +static int +evdev_read(sd_event_source *s, int fd, uint32_t revents, void *userdata) +{ + struct device *device = userdata; + struct input_event ev; + static struct linux_input_keycode *keycode = NULL; + static bool pressed = false; + static uint32_t scancode; + static bool scancode_recv = false; + unsigned i; + + if (fd != device->evdev_fd) + fprintf(stderr, "evdev fd mismatch: %i != %i\n", device->evdev_fd, fd); + + if (revents & EPOLLHUP) { + fprintf(stderr, "evdev connection closed!\n"); + close(fd); + device->evdev_fd = -1; + return 0; + } + + if (!(revents & EPOLLIN)) { + fprintf(stderr, "unexpected evdev event: %" PRIu32 "\n", revents); + return 0; + } + + while (read(fd, &ev, sizeof(ev)) == sizeof(ev)) { + switch (ev.type) { + case EV_KEY: + if (keycode) + printf("Reading from evdev - multiple keycodes?\n"); + + for (i = 0; linux_input_keycodes[i].name; i++) { + if (linux_input_keycodes[i].value == ev.code) + break; + } + + if (!linux_input_keycodes[i].name) { + printf("evdev - unknown keycode (%u)\n", ev.code); + break; + } + + keycode = &linux_input_keycodes[i]; + if (ev.value) + pressed = true; + break; + + case EV_MSC: + if (ev.code == MSC_SCAN) { + if (scancode_recv) + printf("Reading from evdev - multiple scancodes?\n"); + scancode_recv = true; + scancode = ev.value; + } + break; + + case EV_SYN: + if (keycode || scancode_recv) { + const char *protocol; + + /* FIXME: protocol reporting needs kernel support */ + if (scancode_recv) + protocol = evdev_guess_protocol(device, scancode, keycode ? keycode->value : KEY_RESERVED); + + printf("evdev -"); + + if (scancode_recv) { + printf(" protocol %s (guessed)", protocol); + printf(" scancode 0x%08x", scancode); + } + + if (keycode) { + printf(" keycode %s (%u)", keycode->name, keycode->value); + printf(" %s", pressed ? "pressed" : "released"); + } + + printf("\n"); + + if (scancode_recv) + sd_bus_emit_signal(device->mgr->bus, + device->path, + "org.gnome.RemoteControlManager.Device", + "KeyPressed", + "sts", protocol, scancode, + keycode ? keycode->name : "KEY_RESERVED"); + + else if (keycode && !pressed) + sd_bus_emit_signal(device->mgr->bus, + device->path, + "org.gnome.RemoteControlManager.Device", + "KeyReleased", + "s", keycode->name); + } + + scancode_recv = false; + pressed = false; + keycode = NULL; + break; + + default: + break; + } + } + + return 0; +} + int -evdev_setup(struct device *device) +evdev_setup(struct manager *mgr, struct device *device, const char *path) { int r; struct keymap *keymap; - if (!device || device->evdev_fd < 0) + if (!device) return -EINVAL; + if (device->evdev_fd >= 0) { + printf("Multiple evdev devices!?\n"); + return 0; + } + + device->evdev_fd = open(path, O_RDONLY | O_NONBLOCK); + if (device->evdev_fd < 0) { + printf("Failed to open evdev device %s: %s\n", + path, strerror(errno)); + return -errno; + } + printf("Performing evdev setup for device %s\n", device->path); r = evdev_clear_keymap(device); if (r < 0) @@ -154,6 +276,15 @@ evdev_setup(struct device *device) list_for_each_entry(keymap, &device->keymaps, list) r = evdev_set_keymap(device, keymap); + if (sd_event_add_io(mgr->event, &device->evdev_ev, + device->evdev_fd, EPOLLIN, evdev_read, device) < 0) { + printf("Failed to add event source for evdev device %s: %s\n", + path, strerror(errno)); + close(device->evdev_fd); + device->evdev_fd = -1; + return -errno; + } + return r; } diff --git a/rcm-server-evdev.h b/rcm-server-evdev.h index 73b2b25..ed0942a 100644 --- a/rcm-server-evdev.h +++ b/rcm-server-evdev.h @@ -1,9 +1,7 @@ #ifndef foorcmserverevdevhfoo #define foorcmserverevdevhfoo -const char *evdev_guess_protocol(struct device *device, uint64_t scancode, uint32_t keycode); - -int evdev_setup(struct device *device); +int evdev_setup(struct manager *mgr, struct device *device, const char *path); #endif diff --git a/rcm-server-main.c b/rcm-server-main.c index f44c0ac..7fc6e85 100644 --- a/rcm-server-main.c +++ b/rcm-server-main.c @@ -675,113 +675,6 @@ remove_device(struct manager *mgr, struct udev_device *udev) } } -static int -evdev_read(sd_event_source *s, int fd, uint32_t revents, void *userdata) -{ - struct device *device = userdata; - struct input_event ev; - static struct linux_input_keycode *keycode = NULL; - static bool pressed = false; - static uint32_t scancode; - static bool scancode_recv = false; - unsigned i; - - if (fd != device->evdev_fd) - fprintf(stderr, "evdev fd mismatch: %i != %i\n", device->evdev_fd, fd); - - if (revents & EPOLLHUP) { - fprintf(stderr, "evdev connection closed!\n"); - close(fd); - device->evdev_fd = -1; - return 0; - } - - if (!(revents & EPOLLIN)) { - fprintf(stderr, "unexpected evdev event: %" PRIu32 "\n", revents); - return 0; - } - - while (read(fd, &ev, sizeof(ev)) == sizeof(ev)) { - switch (ev.type) { - case EV_KEY: - if (keycode) - printf("Reading from evdev - multiple keycodes?\n"); - - for (i = 0; linux_input_keycodes[i].name; i++) { - if (linux_input_keycodes[i].value == ev.code) - break; - } - - if (!linux_input_keycodes[i].name) { - printf("evdev - unknown keycode (%u)\n", ev.code); - break; - } - - keycode = &linux_input_keycodes[i]; - if (ev.value) - pressed = true; - break; - - case EV_MSC: - if (ev.code == MSC_SCAN) { - if (scancode_recv) - printf("Reading from evdev - multiple scancodes?\n"); - scancode_recv = true; - scancode = ev.value; - } - break; - - case EV_SYN: - if (keycode || scancode_recv) { - const char *protocol; - - /* FIXME: protocol reporting needs kernel support */ - if (scancode_recv) - protocol = evdev_guess_protocol(device, scancode, keycode ? keycode->value : KEY_RESERVED); - - printf("evdev -"); - - if (scancode_recv) { - printf(" protocol %s (guessed)", protocol); - printf(" scancode 0x%08x", scancode); - } - - if (keycode) { - printf(" keycode %s (%u)", keycode->name, keycode->value); - printf(" %s", pressed ? "pressed" : "released"); - } - - printf("\n"); - - if (scancode_recv) - sd_bus_emit_signal(device->mgr->bus, - device->path, - "org.gnome.RemoteControlManager.Device", - "KeyPressed", - "sts", protocol, scancode, - keycode ? keycode->name : "KEY_RESERVED"); - - else if (keycode && !pressed) - sd_bus_emit_signal(device->mgr->bus, - device->path, - "org.gnome.RemoteControlManager.Device", - "KeyReleased", - "s", keycode->name); - } - - scancode_recv = false; - pressed = false; - keycode = NULL; - break; - - default: - break; - } - } - - return 0; -} - static void add_device(struct manager *mgr, struct udev_device *udev) { @@ -792,6 +685,7 @@ add_device(struct manager *mgr, struct udev_device *udev) struct udev_enumerate *enumerate; struct udev_list_entry *devices, *dev_list_entry; struct udev_device *evdev; + int r; name = udev_device_get_sysname(udev); if (asprintf(&path, "/org/gnome/RemoteControlManager/%s", name) < 0) { @@ -848,28 +742,9 @@ add_device(struct manager *mgr, struct udev_device *udev) continue; } - if (device->evdev_fd >= 0) { - printf("Multiple evdev devices!?\n"); - udev_device_unref(evdev); - continue; - } - - device->evdev_fd = open(devnode, O_RDONLY | O_NONBLOCK); - if (device->evdev_fd < 0) { - printf("Failed to open evdev device %s: %s\n", - devnode, strerror(errno)); - udev_device_unref(evdev); - continue; - } - - evdev_setup(device); - - if (sd_event_add_io(mgr->event, &device->evdev_ev, - device->evdev_fd, EPOLLIN, evdev_read, device) < 0) { - printf("Failed to add event source for evdev device %s: %s\n", - devnode, strerror(errno)); - close(device->evdev_fd); - device->evdev_fd = -1; + r = evdev_setup(mgr, device, devnode); + if (r < 0) { + printf("Failed to setup evdev: %s\n", devnode); udev_device_unref(evdev); continue; } |