aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile46
-rw-r--r--marsond.193
-rw-r--r--marsond.c126
-rw-r--r--marsond.rst90
-rw-r--r--mkusage.pl18
-rw-r--r--rc.marsond36
-rw-r--r--usage.c7
7 files changed, 395 insertions, 21 deletions
diff --git a/Makefile b/Makefile
index 70985f9..4ef8ee2 100644
--- a/Makefile
+++ b/Makefile
@@ -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.
+.
diff --git a/marsond.c b/marsond.c
index 228310d..885a3e2 100644
--- a/marsond.c
+++ b/marsond.c
@@ -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
diff --git a/usage.c b/usage.c
new file mode 100644
index 0000000..ac836e8
--- /dev/null
+++ b/usage.c
@@ -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
+};