summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rcm-server-evdev.c137
-rw-r--r--rcm-server-evdev.h4
-rw-r--r--rcm-server-main.c133
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;
}