diff options
| -rw-r--r-- | rcm-server-evdev.c | 32 | ||||
| -rw-r--r-- | rcm-server-evdev.h | 2 | ||||
| -rw-r--r-- | rcm-server-main.c | 50 | ||||
| -rw-r--r-- | shared.c | 2 | ||||
| -rw-r--r-- | shared.h | 2 | ||||
| -rw-r--r-- | 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: @@ -3,7 +3,7 @@  #include "shared.h" -const char *rc_protocols[] = { +const char *rc_protocols[20] = {  	"Unknown",  	"Other",  	"RC5", @@ -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; @@ -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) ({				\  | 
