diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2015-05-21 11:27:42 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2015-05-21 11:28:08 +0200 |
commit | 10cf3d2ea4659bf1608984f43d98b0845846188f (patch) | |
tree | d9129463400f7ad7347c9c6176afb4f69d035136 | |
parent | b45f7c813cde7ffa7315833631eef5700ddaa04e (diff) | |
download | input-10cf3d2ea4659bf1608984f43d98b0845846188f.tar.gz |
add emulate-key
-rw-r--r-- | GNUmakefile | 4 | ||||
-rw-r--r-- | emulate-key.c | 123 |
2 files changed, 126 insertions, 1 deletions
diff --git a/GNUmakefile b/GNUmakefile index 73bae9d..7b737bb 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -6,7 +6,8 @@ include mk/Variables.mk CFLAGS += -DVERSION='"$(VERSION)"' # build -TARGETS := lsinput input-events input-kbd input-send input-recv lircd.conf +TARGETS := input-events input-kbd input-send input-recv +TARGETS += lsinput emulate-key lircd.conf HEADERS := EV.h REL.h ABS.h MSC.h LED.h SND.h REP.h KEY.h BTN.h BUS.h SW.h # default target @@ -39,6 +40,7 @@ input-events: input-events.o input.o input-kbd: input-kbd.o input.o input-send: input-send.o input.o tcp.o input-recv: input-recv.o input.o tcp.o +emulate-key: emulate-key.o input.o input.o: input.c $(HEADERS) diff --git a/emulate-key.c b/emulate-key.c new file mode 100644 index 0000000..8affc02 --- /dev/null +++ b/emulate-key.c @@ -0,0 +1,123 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> + +#include <linux/input.h> +#include <linux/uinput.h> + +#include "input.h" + +/* ------------------------------------------------------------------ */ + +static int usage(char *prog, int error) +{ + fprintf(error ? stderr : stdout, + "usage: %s -h this text\n" + "usage: %s -l list keys\n" + "usage: %s [ -v ] <key> send key\n", + prog, prog, prog); + exit(error); +} + +static int send_key(int fd, int key, bool down) +{ + struct input_event ev; + + memset(&ev, 0, sizeof(ev)); + ev.type = EV_KEY; + ev.code = key; + ev.value = down ? 0 : 1; + write(fd, &ev, sizeof(ev)); + + memset(&ev, 0, sizeof(ev)); + ev.type = EV_SYN; + write(fd, &ev, sizeof(ev)); + + return 0; +} + +int main(int argc, char *argv[]) +{ + static struct uinput_user_dev uidev = { + .name = "emulate-key", + }; + int verbose = 0; + int c, key, fd; + char *name; + + for (;;) { + if (-1 == (c = getopt(argc, argv, "hvl"))) + break; + switch (c) { + case 'v': + verbose = 1; + break; + case 'l': + for (key = 0; key < KEY_MAX; key++) { + name = ev_type_name(EV_KEY, key); + if (!name) + continue; + if (strcmp(name, "???") == 0) + continue; + printf("%s%s", key ? ", " : "", name); + } + printf("\n"); + exit(0); + case 'h': + usage(argv[0],0); + default: + usage(argv[0],1); + } + } + + if (optind == argc) { + fprintf(stderr, "%s: no keyname given\n", + argv[0]); + exit(1); + } + for (key = 0; key < KEY_MAX; key++) { + if (strcmp(ev_type_name(EV_KEY, key), argv[optind]) == 0) { + break; + } + } + if (key == KEY_MAX) { + fprintf(stderr, "%s: key '%s' not found\n", + argv[0], argv[optind]); + exit(1); + } + if (verbose) { + printf("Sending '%s' (%d) key (down+up).\n", argv[optind], key); + } + + fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); + if (fd < 0) { + perror("open /dev/uinput"); + exit(1); + } + + ioctl(fd, UI_SET_EVBIT, EV_SYN); + ioctl(fd, UI_SET_EVBIT, EV_KEY); + ioctl(fd, UI_SET_KEYBIT, key); + write(fd, &uidev, sizeof(uidev)); + ioctl(fd, UI_DEV_CREATE); + + usleep(100000); + send_key(fd, key, true); + usleep(100000); + send_key(fd, key, false); + usleep(100000); + + ioctl(fd, UI_DEV_DESTROY); + + return 0; +} + +/* --------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ |