diff options
author | B. Watson <urchlay@slackware.uk> | 2025-05-06 04:10:06 -0400 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2025-05-06 04:10:06 -0400 |
commit | 67ebbac0be7ad917e794ca5ea0496d0a1ead83b8 (patch) | |
tree | d169b8481afe91a394023c294741a21e57cb033f | |
parent | c4eda00ddbc16723f3e1d1e943edaaa2c6c2c748 (diff) | |
download | marsond-67ebbac0be7ad917e794ca5ea0496d0a1ead83b8.tar.gz |
much work (options, rc script, make install, etc etc).
-rw-r--r-- | Makefile | 46 | ||||
-rw-r--r-- | marsond.1 | 93 | ||||
-rw-r--r-- | marsond.c | 126 | ||||
-rw-r--r-- | marsond.rst | 90 | ||||
-rw-r--r-- | mkusage.pl | 18 | ||||
-rw-r--r-- | rc.marsond | 36 | ||||
-rw-r--r-- | usage.c | 7 |
7 files changed, 395 insertions, 21 deletions
@@ -1,5 +1,6 @@ # Makefile for marsond. Should be fine with any make (GNU, BSD, etc). +### Compiler and options. CC=gcc # CC=clang works, too @@ -7,4 +8,49 @@ COPT=-O2 CWARN=-Wall CFLAGS=-std=c99 $(COPT) $(CWARN) +### Install paths. Not compiled into the binary. +PREFIX=/usr +SBINDIR=$(PREFIX)/sbin +MANDIR=$(PREFIX)/man +MAN8DIR=$(PREFIX)/man8 + +INSTALL=install +INSTALL_MAN=$(INSTALL) +INSTALL_BIN=$(INSTALL) -s -m0755 +INSTALL_RC=$(INSTALL) -m0755 +GZIP=gzip -9 + +# Leave blank to skip installing the Slackware-style rc.marsond SysV +# init script. Most distros no longer use rc scripts. Mine does, +# and doesn't have systemd, so I didn't try to write a systemd service +# file for this. +# For Slackware, this should be: +# RCDIR=/etc/rc.d +RCDIR= + +### No user-serviceable parts below (I hope). all: marsond + +marsond: marsond.c usage.c + +usage.c: mkusage.pl marsond.rst + perl mkusage.pl marsond.rst > usage.c + +marsond.1: marsond.rst + rst2man marsond.rst > marsond.1 + +clean: + rm -f marsond core *.o + +realclean: clean + rm -f marsond.1 usage.c + +install: all + mkdir -p $(DESTDIR)/$(SBINDIR) $(DESTDIR)/$(MAN8DIR) + $(INSTALL_BIN) marsond $(DESTDIR)/$(SBINDIR) + $(INSTALL_MAN) marsond.1 $(DESTDIR)/$(MAN8DIR) + $(GZIP) $(DESTDIR)/$(MAN8DIR)/marsond.1 || true + [ "$(RCDIR)" != "" ] && \ + mkdir -p $(DESTDIR)/$(RCDIR) && \ + $(INSTALL_RC) rc.marsond $(DESTDIR)$(RCDIR) + diff --git a/marsond.1 b/marsond.1 new file mode 100644 index 0000000..6bb016b --- /dev/null +++ b/marsond.1 @@ -0,0 +1,93 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "MARSOND" 1 "2025-05-06" "0.1" "SlackBuilds.org" +.SH NAME +marsond \- Fix Enter key on Marson/USBLinux/MT606-1 adaptors +.SH SYNOPSIS +.sp +marsond [\fB\-d\fP \fIdelay\-ms*\fP] [\fB\-k\fP \fIkeyboard\-device\fP] [\fB\-v\fP] | [\fB\-\-help\fP] | [\fB\-\-version\fP] | [\fB\-V\fP] +.SH DESCRIPTION +.SH OPTIONS +.INDENT 0.0 +.TP +.BI \-d \ delay\-ms +Amount of time in milliseconds to delay the Enter key release events. +Default: 30. +.TP +.BI \-k \ keyboard\-device +Input device for the keyboard adaptor. Default: +/dev/input/by\-id/usb\-Marson_Marson_Keyboard_and_Mouse_Link_Ver:ps2120L\-event\-kbd +.TP +.B \-v +Verbose debugging mode. Prints copious trace information to \fBstderr\fP, and +does not run in the background. +.TP +.B \-H\fP,\fB \-\-help +Shows built\-in usage message and exits. +.TP +.B \-V\fP,\fB \-\-version +Shows version number and exits. +.UNINDENT +.\" other sections we might want, uncomment as needed. +. +.\" FILES +. +.\" ===== +. +.\" ENVIRONMENT +. +.\" =========== +. +.\" EXIT STATUS +. +.\" =========== +. +.\" BUGS +. +.\" ==== +. +.\" EXAMPLES +. +.\" ======== +. +.SH COPYRIGHT +.sp +See the file /usr/doc/PRGNAM\-0.1/COPYING for license information. +.SH AUTHORS +.sp +PRGNAM was written by WHOEVER. +.sp +This man page written for the SlackBuilds.org project +by B. Watson, and is licensed under the WTFPL. +.SH SEE ALSO +.sp +The PRGNAM homepage: \fI\%http://www.PRGNAM.org/\fP +.\" Generated by docutils manpage writer. +. @@ -1,3 +1,5 @@ +#define _DEFAULT_SOURCE /* for getopt() and optarg */ + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -9,19 +11,17 @@ #include <linux/input.h> #include <linux/uinput.h> -#define DELAY_MS 30 +#define VERSION "0.0.1" -#define DEFAULT_KBD "/dev/input/by-id/usb-Marson_Marson_Keyboard_and_Mouse_Link_Ver:ps2120L-event-kbd" +#define DEFAULT_DELAY_MS 30 -/* eventually, this will take options to set the device and - delay for the Enter key, and will have an rc script to - start it...? */ +#define DEFAULT_KBD "/dev/input/by-id/usb-Marson_Marson_Keyboard_and_Mouse_Link_Ver:ps2120L-event-kbd" const char *self; -int debugging = 1; - -const char *keyboard_dev; +int debugging = 0; /* -v */ +const char *keyboard_dev = DEFAULT_KBD; /* -k */ +int delay_ms = DEFAULT_DELAY_MS; /* -d */ /* variadic macros are apparently C99 and not just a GNU extension */ void logmsg(const char *prefix, const char *fmt, ...) { @@ -34,8 +34,8 @@ void logmsg(const char *prefix, const char *fmt, ...) { } #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 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) { @@ -45,17 +45,93 @@ void set_self(const char *argv0) { if(p) self = p + 1; } +void print_help(void) { + /* helptext comes from usage.c, which gets generated by mkusage.pl, + from the content in the the .rst file. */ + extern const char *helptext[]; + + const char **helpline; + + puts("marsond " VERSION ", by B. Watson <urchlay@slackware.uk>, WTFPL"); + puts("Usage:"); + + for(helpline = helptext; *helpline; helpline++) + puts(*helpline); +} + +void version(void) { + puts(VERSION); +} + +void parse_args(int argc, char **argv) { + int opt; + + opterr = 0; + + if(argc >= 2) { + if(strcmp(argv[1], "--help") == 0) { + print_help(); + exit(0); + } else if(strcmp(argv[1], "--version") == 0) { + version(); + exit(0); + } + } + + while( (opt = getopt(argc, argv, "d:hk:vV")) != -1) { + switch(opt) { + case 'v': debugging++; break; + case 'd': delay_ms = atoi(optarg); break; + case 'k': keyboard_dev = optarg; break; + case 'h': print_help(); exit(0); break; + case 'V': version(); exit(0); break; + case '?': die("invalid option (try --help)"); break; + default: print_help(); exit(1); break; + } + } + + if(delay_ms < 1) die("invalid -d argument"); +} + +void daemonize(void) { + int pid; + + pid = fork(); + if(pid < 0) { + die("fork() failed"); + } else if(pid) { + /* parent */ + exit(0); + } + + /* we are the child here */ + setsid(); + + pid = fork(); + if(pid < 0) { + die("fork() failed"); + } else if(pid) { + /* 2nd generation parent */ + info("forked to background, PID %d\n", pid); + exit(0); + } + + /* we are the grandchild here */ + chdir("/"); + close(0); + close(1); + close(2); +} + 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; + parse_args(argc, argv); if((outfd = open("/dev/uinput", O_WRONLY | O_NONBLOCK)) >= 0) { debug("opened /dev/uinput"); @@ -88,12 +164,13 @@ int main(int argc, char **argv) { die("UI_SET_EVBIT failed: %s", strerror(errno)); } } + debug("UI_SET_KEYBIT OK"); 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.bustype = BUS_USB; + dev.id.vendor = 0x69; + dev.id.product = 0x666; dev.id.version = 1; if(write(outfd, &dev, sizeof(dev)) >= 0) { @@ -108,25 +185,32 @@ int main(int argc, char **argv) { die("UI_DEV_CREATE failed: %s", strerror(errno)); } + if(!debugging) daemonize(); + + /* note: don't call die() unless debugging is true, since daemonize() + closes our stderr (there's nowhere for the error message to print). */ + while(1) { if(read(infd, &ev, sizeof(ev)) < 0) { - die("read from %s failed: %s", keyboard_dev, strerror(errno)); + if(debugging) + 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); + 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)); + if(debugging) + die("write to /dev/uinput failed: %s", strerror(errno)); } } - exit(0); + exit(1); } /* diff --git a/marsond.rst b/marsond.rst new file mode 100644 index 0000000..4dfee82 --- /dev/null +++ b/marsond.rst @@ -0,0 +1,90 @@ + +.. |version| replace:: 0.1 +.. |date| date:: + +======= +marsond +======= + +------------------------------------------------- +Fix Enter key on Marson/USBLinux/MT606-1 adaptors +------------------------------------------------- + +:Manual section: 1 +:Manual group: SlackBuilds.org +:Date: |date| +:Version: |version| + +SYNOPSIS +======== + +marsond [**-d** *delay-ms**] [**-k** *keyboard-device*] [**-v**] | [**--help**] | [**--version**] | [**-V**] + +DESCRIPTION +=========== + +OPTIONS +======= + +-d delay-ms + Amount of time in milliseconds to delay the Enter key release events. + Default: 30. + + .. delay time for Enter key relase (default 30). + +-k keyboard-device + Input device for the keyboard adaptor. Default: + /dev/input/by-id/usb-Marson_Marson_Keyboard_and_Mouse_Link_Ver:ps2120L-event-kbd + +.. keyboard device (usually under /dev/input/by-id/). + +-v + Verbose debugging mode. Prints copious trace information to **stderr**, and + does not run in the background. + +.. verbose debugging, foreground operation. + +-h, --help + Shows built-in usage message and exits. + +.. this help text. + +-V, --version + Shows version number and exits. + +.. show version number. + +.. other sections we might want, uncomment as needed. + +.. FILES +.. ===== + +.. ENVIRONMENT +.. =========== + +.. EXIT STATUS +.. =========== + +.. BUGS +.. ==== + +.. EXAMPLES +.. ======== + +COPYRIGHT +========= + +See the file /usr/doc/PRGNAM-|version|/COPYING for license information. + +AUTHORS +======= + +PRGNAM was written by WHOEVER. + +This man page written for the SlackBuilds.org project +by B. Watson, and is licensed under the WTFPL. + +SEE ALSO +======== + +The PRGNAM homepage: http://www.PRGNAM.org/ diff --git a/mkusage.pl b/mkusage.pl new file mode 100644 index 0000000..fab9626 --- /dev/null +++ b/mkusage.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl -w + +print "const char *helptext[] = {\n"; + +while(<>) { + chomp; + next if /^---/; + if(/^-[-a-zA-Z\d]/) { + $opt = $_; + next; + } + if($opt && (/^\.\. (.*)$/)) { + print "\t\" $opt: $1\",\n"; + undef $opt; + } +} + +print "\t(const char*)0\n};\n"; diff --git a/rc.marsond b/rc.marsond new file mode 100644 index 0000000..3de1c23 --- /dev/null +++ b/rc.marsond @@ -0,0 +1,36 @@ +#!/bin/sh + +# Start/stop/restart marsond, Slackware-style. + +# To start marsond at boot, make sure this script is executable: + +# chmod 755 /etc/rc.d/rc.marsond +# ...and then add this to /etc/rc.d/rc.local: + +# [ -x /etc/rc.d/rc.marsond ] && /etc/rc.d/rc.marsond + +# There's no need to add anything to rc.local_shutdown, as the +# daemon will always exit cleanly. + +# If you need to set the keyboard's input device name and/or the +# delay time for Enter key releases, uncomment and modify the +# next line: + +#MARSOND_OPTS="-d 30 -k /dev/input/by-id/your-device-name-goes-here" + +# By default, marsond drops privilege to nobody:nogroup after +# initialization. You can use a different user and group by +# uncommenting and modifying these: + +#MARSON_USER=nobody +#MARSON_GROUP=nogroup + +PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin +export PATH + +case "$1" in + start) /usr/sbin/marsond $MARSOND_OPTS ;; + stop) /sbin/killall marsond ;; + restart) "$0" stop ; sleep 2; "$0" start ;; + *) echo "usage $0 start|stop|restart" ;; +esac @@ -0,0 +1,7 @@ +const char *helptext[] = { + " -k keyboard-device: keyboard device (usually under /dev/input/by-id/).", + " -v: verbose debugging, foreground operation.", + " -h, --help: this help text.", + " -V, --version: show version number.", + (const char*)0 +}; |