From e809e384a956f950906160ef86abfb01b1638075 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Tue, 6 May 2025 01:36:18 -0400 Subject: initial commit --- .gitignore | 13 ++++++ Makefile | 10 +++++ README | 3 ++ marsond.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README create mode 100644 marsond.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e9e276 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +marsond +*.old +*.b0rk +*.o +1 +2 +3 +4 +1.* +2.* +3.* +4.* +.*.swp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..70985f9 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +# Makefile for marsond. Should be fine with any make (GNU, BSD, etc). + +CC=gcc +# CC=clang works, too + +COPT=-O2 +CWARN=-Wall +CFLAGS=-std=c99 $(COPT) $(CWARN) + +all: marsond diff --git a/README b/README new file mode 100644 index 0000000..f133158 --- /dev/null +++ b/README @@ -0,0 +1,3 @@ +Marson MT-601 USBLinux Daemon +============================= + 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 +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 +*/ -- cgit v1.2.3