summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rcm-server-evdev.c32
-rw-r--r--rcm-server-evdev.h2
-rw-r--r--rcm-server-main.c50
-rw-r--r--shared.c2
-rw-r--r--shared.h2
-rw-r--r--utils.h2
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) ({ \