From cf94c763b15d7fc98d5e3f16ddbfcd8b79b99536 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Fri, 24 Jul 2015 11:27:07 +0200 Subject: Interim protocol support... --- rcm-server-evdev.c | 32 ++++++++++++++++++++++++++++++++ rcm-server-evdev.h | 2 ++ rcm-server-main.c | 50 ++++++++++++++++++++++++++++++-------------------- shared.c | 2 +- shared.h | 2 +- utils.h | 2 ++ 6 files changed, 68 insertions(+), 22 deletions(-) diff --git a/rcm-server-evdev.c b/rcm-server-evdev.c index 9423806..bc8361e 100644 --- a/rcm-server-evdev.c +++ b/rcm-server-evdev.c @@ -33,6 +33,38 @@ struct rc_keymap_entry { }; #define RKE_SIZE (sizeof(struct rc_scancode)) +const char * +evdev_guess_protocol(struct device *device, uint64_t scancode, uint32_t keycode) +{ + struct rc_keymap_entry rke; + unsigned i; + + if (!device || device->evdev_fd < 0) + return NULL; + + for (i = 0; ; i++) { + memset(&rke, 0, sizeof(rke)); + rke.len = RKE_SIZE; + rke.index = i; + rke.flags = INPUT_KEYMAP_BY_INDEX; + if (ioctl(device->evdev_fd, EVIOCGKEYCODE_V2, &rke)) + break; + + if (rke.u.rc.scancode != scancode) + continue; + + if (rke.keycode != keycode) + continue; + + if (rke.u.rc.protocol > ARRAY_SIZE(rc_protocols)) + return NULL; + + return rc_protocols[rke.u.rc.protocol]; + } + + return NULL; +} + static int evdev_clear_keymap(struct device *device) { diff --git a/rcm-server-evdev.h b/rcm-server-evdev.h index 7cdf6c1..73b2b25 100644 --- a/rcm-server-evdev.h +++ b/rcm-server-evdev.h @@ -1,6 +1,8 @@ #ifndef foorcmserverevdevhfoo #define foorcmserverevdevhfoo +const char *evdev_guess_protocol(struct device *device, uint64_t scancode, uint32_t keycode); + int evdev_setup(struct device *device); #endif diff --git a/rcm-server-main.c b/rcm-server-main.c index 8dc5a6b..990a964 100644 --- a/rcm-server-main.c +++ b/rcm-server-main.c @@ -726,11 +726,10 @@ evdev_read(sd_event_source *s, int fd, uint32_t revents, void *userdata) { struct device *device = userdata; struct input_event ev; - static const char *keycode_str = NULL; - static uint32_t keycode = KEY_RESERVED; + static struct linux_input_keycode *keycode = NULL; + static bool pressed = false; static uint32_t scancode; static bool scancode_recv = false; - static bool pressed = false; unsigned i; if (fd != device->evdev_fd) @@ -751,7 +750,7 @@ evdev_read(sd_event_source *s, int fd, uint32_t revents, void *userdata) while (read(fd, &ev, sizeof(ev)) == sizeof(ev)) { switch (ev.type) { case EV_KEY: - if (keycode != KEY_RESERVED) + if (keycode) printf("Reading from evdev - multiple keycodes?\n"); for (i = 0; linux_input_keycodes[i].name; i++) { @@ -764,9 +763,9 @@ evdev_read(sd_event_source *s, int fd, uint32_t revents, void *userdata) break; } - keycode_str = linux_input_keycodes[i].name; - keycode = ev.code; - pressed = ev.value ? true : false; + keycode = &linux_input_keycodes[i]; + if (ev.value) + pressed = true; break; case EV_MSC: @@ -779,35 +778,46 @@ evdev_read(sd_event_source *s, int fd, uint32_t revents, void *userdata) break; case EV_SYN: - if (keycode != KEY_RESERVED || scancode_recv) { - printf("evdev event -"); - if (keycode != KEY_RESERVED) - printf(" keycode %s (%u) %s", - keycode_str, keycode, - pressed ? "pressed" : "released"); + if (keycode || scancode_recv) { + const char *protocol; + + /* FIXME: protocol reporting needs kernel support */ if (scancode_recv) + protocol = evdev_guess_protocol(device, scancode, lik ? lik->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"); - /* FIXME: protocol needs kernel support */ - if (pressed && scancode_recv) + if (scancode_recv) sd_bus_emit_signal(device->mgr->bus, device->path, "org.gnome.RemoteControlManager.Device", "KeyPressed", - "sts", "nec", scancode, keycode_str); - else if (!pressed && keycode != KEY_RESERVED) + "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_str); + "s", keycode->name); } - keycode = KEY_RESERVED; - keycode_str = NULL; scancode_recv = false; pressed = false; + keycode = NULL; break; default: diff --git a/shared.c b/shared.c index a1ce931..b07d8c0 100644 --- a/shared.c +++ b/shared.c @@ -3,7 +3,7 @@ #include "shared.h" -const char *rc_protocols[] = { +const char *rc_protocols[20] = { "Unknown", "Other", "RC5", diff --git a/shared.h b/shared.h index dda43ff..7dfcfca 100644 --- a/shared.h +++ b/shared.h @@ -9,7 +9,7 @@ #define REMOTE_LAYOUT_MAX_WIDTH 1000 #define REMOTE_LAYOUT_MAX_HEIGHT 1000 -extern const char *rc_protocols[]; +extern const char *rc_protocols[20]; struct linux_input_keycode { const char *name; diff --git a/utils.h b/utils.h index fd9db77..250dbdc 100644 --- a/utils.h +++ b/utils.h @@ -44,6 +44,8 @@ static inline bool list_empty(struct list_head *list) return list->next == list; } +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member) ({ \ -- cgit v1.2.3