aboutsummaryrefslogtreecommitdiff
path: root/marsond.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-05-06 01:36:18 -0400
committerB. Watson <urchlay@slackware.uk>2025-05-06 01:36:18 -0400
commite809e384a956f950906160ef86abfb01b1638075 (patch)
tree0ba01cfeeed06555be551cb9a18ad8681d224268 /marsond.c
downloadmarsond-e809e384a956f950906160ef86abfb01b1638075.tar.gz
initial commit
Diffstat (limited to 'marsond.c')
-rw-r--r--marsond.c150
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
+*/