diff options
author | B. Watson <urchlay@slackware.uk> | 2025-05-06 01:36:18 -0400 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2025-05-06 01:36:18 -0400 |
commit | e809e384a956f950906160ef86abfb01b1638075 (patch) | |
tree | 0ba01cfeeed06555be551cb9a18ad8681d224268 /marsond.c | |
download | marsond-e809e384a956f950906160ef86abfb01b1638075.tar.gz |
initial commit
Diffstat (limited to 'marsond.c')
-rw-r--r-- | marsond.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/marsond.c b/marsond.c new file mode 100644 index 0000000..228310d --- /dev/null +++ b/marsond.c @@ -0,0 +1,150 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <stdarg.h> + +#include <linux/input.h> +#include <linux/uinput.h> + +#define DELAY_MS 30 + +#define DEFAULT_KBD "/dev/input/by-id/usb-Marson_Marson_Keyboard_and_Mouse_Link_Ver:ps2120L-event-kbd" + +/* eventually, this will take options to set the device and + delay for the Enter key, and will have an rc script to + start it...? */ + +const char *self; + +int debugging = 1; + +const char *keyboard_dev; + +/* variadic macros are apparently C99 and not just a GNU extension */ +void logmsg(const char *prefix, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s: %s: ", self, prefix); + vfprintf(stderr, fmt, ap); + va_end(ap); + fputc('\n', stderr); +} + +#define die(fmt, ...) { logmsg("fatal", fmt, ##__VA_ARGS__); exit(1); }; +#define warn(fmt, ...) logmsg("warning", fmt, ##__VA_ARGS__); +#define info(fmt, ...) logmsg("info", fmt, ##__VA_ARGS__); +#define debug(fmt, ...) { if(debugging) logmsg("debug", fmt, ##__VA_ARGS__); }; + +void set_self(const char *argv0) { + char *p; + self = argv0; + p = strrchr(self, '/'); + if(p) self = p + 1; +} + +int main(int argc, char **argv) { + int infd, outfd, i; + struct uinput_user_dev dev; + struct input_event ev; + static struct input_event deferred_ev; + + set_self(argv[0]); + debug("starting up"); + + if(!keyboard_dev) + keyboard_dev = DEFAULT_KBD; + + if((outfd = open("/dev/uinput", O_WRONLY | O_NONBLOCK)) >= 0) { + debug("opened /dev/uinput"); + } else { + die("failed to open /dev/uinput: %s", strerror(errno)); + } + + if((infd = open(keyboard_dev, O_RDONLY)) >= 0) { + debug("opened %s", keyboard_dev); + } else { + die("failed to open %s: %s", keyboard_dev, strerror(errno)); + } + + if(ioctl(infd, EVIOCGRAB, 1) >= 0) { + debug("grabbed %s", keyboard_dev); + } else { + die("failed to grab %s: %s", keyboard_dev, strerror(errno)); + } + + if(ioctl(outfd, UI_SET_EVBIT, EV_KEY) >= 0) { + debug("UI_SET_EVBIT OK"); + } else { + die("UI_SET_EVBIT failed: %s", strerror(errno)); + } + + for(i = 0; i < KEY_MAX; i++) { + if(ioctl(outfd, UI_SET_KEYBIT, i) >= 0) { + /* we don't wanna be *that* verbose */ + } else { + die("UI_SET_EVBIT failed: %s", strerror(errno)); + } + } + + memset(&dev, 0, sizeof(dev)); + snprintf(dev.name, UINPUT_MAX_NAME_SIZE, "marsond virtual keyboard"); + dev.id.bustype == BUS_USB; + dev.id.vendor = 1; + dev.id.product = 1; + dev.id.version = 1; + + if(write(outfd, &dev, sizeof(dev)) >= 0) { + debug("wrote dev structure to /dev/uinput"); + } else { + die("write to /dev/uinput failed: %s", strerror(errno)); + } + + if(ioctl(outfd, UI_DEV_CREATE) >= 0) { + debug("created virtual keyboard device"); + } else { + die("UI_DEV_CREATE failed: %s", strerror(errno)); + } + + while(1) { + if(read(infd, &ev, sizeof(ev)) < 0) { + die("read from %s failed: %s", keyboard_dev, strerror(errno)); + } + + debug("event: type %d, code %d, value %d\n", + ev.type, ev.code, ev.value); + + if(ev.type == EV_KEY && ev.code == KEY_ENTER && ev.value == 0) { + debug("got Enter key release, delaying %d ms", DELAY_MS); + usleep(DELAY_MS * 1000); + } + + if(write(outfd, &ev, sizeof(ev)) < 0) { + die("write to /dev/uinput failed: %s", strerror(errno)); + } + } + + exit(0); +} + +/* +for the A key: + +event: type 4, code 4, value 458756 +event: type 1, code 30, value 1 +event: type 0, code 0, value 0 +event: type 4, code 4, value 458756 +event: type 1, code 30, value 0 +event: type 0, code 0, value 0 + +for Enter: + +event: type 4, code 4, value 458792 +event: type 1, code 28, value 1 +event: type 0, code 0, value 0 +event: type 4, code 4, value 458792 +event: type 1, code 28, value 0 +event: type 0, code 0, value 0 +*/ |