aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md34
-rw-r--r--kvm-input.rules20
-rwxr-xr-xkvm-plugged-in.sh23
-rwxr-xr-xkvm-udev-trigger.sh26
-rwxr-xr-xkvm-user-daemon.sh48
5 files changed, 151 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8243d3c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,34 @@
+# README for kvm-mapping
+This `kvm-mapping` project is designed to make it easy to run a script in my user session when the kvm output goes to this machine. Specifically, I want keyboard mappings restored for easy switching between layouts 'us,us(dvorak)'.
+
+## Upstream
+This project's upstream is at <https://bgstack15.ddns.net/cgit/kvm-mapping/>
+
+## Alternatives
+None. Original idea and implementation.
+
+## Reason for existence
+Custom solution for myself that might be useful in alternate ways or as an example of the various concepts. Also, putting this in scm acts as a backup.
+
+## Using
+
+* Set up the scripts in `/usr/local/bin`.
+* Set up the udev rule in `/etc/udev/rules.d/`.
+* Modify `kvm-plugged-in.sh` to run whatever you want.
+* Set up your X session to run `kvm-user-daemon.sh` at startup. In ~/.fluxbox/startup this would look like:
+
+ /usr/local/bin/kvm-user-daemon.sh 1>/dev/null 2>&1 &
+
+Logging of the user daemon happens to ~/log/kvm or ~/.log/kvm, whichever exists or you can set `LOGFILE` before running.
+
+## Dependencies
+
+* xinput, setxkbmap, udev, plecho (bgscripts)
+
+## Building
+Not implemented yet; there is nothing to build. Just deploy manually.
+
+## References
+
+1. <https://superuser.com/questions/305723/using-udev-rules-to-run-a-script-on-usb-insertion>
+2. <https://unix.stackexchange.com/questions/71348/why-doesnt-this-udev-rule-trigger-upon-removal-of-the-device>
diff --git a/kvm-input.rules b/kvm-input.rules
new file mode 100644
index 0000000..d1e6ec1
--- /dev/null
+++ b/kvm-input.rules
@@ -0,0 +1,20 @@
+# File: /etc/udev/rules.d/kvm-input.rules
+# Location: vm2
+# Author: bgstack15
+# Startdate: 2023-01-11-4 11:18
+# Title: Udev rule for detecting kvm switched input
+# Project: kvm-mapping
+# Purpose: run script when my USB keyboard is plugged in, i.e., when the kvm is switched to this output
+# History:
+# Usage:
+# After making changes: `sudo udevadm control --reload`
+# Reference:
+# IBM Corp. SK-8815 keyboard that is on my USB kvm
+# lsusb
+# https://superuser.com/questions/305723/using-udev-rules-to-run-a-script-on-usb-insertion
+# Improve:
+# Documentation:
+# This invokes the script three times, so the trigger script must look for DEVTYPE="usb_device" because I couldn't find a way to do that here with an ATTRS
+# Dependencies:
+# /usr/local/bin/kvm-udev-trigger.sh
+ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="04b3", ATTRS{idProduct}=="301b", RUN+="/usr/local/bin/kvm-udev-trigger.sh"
diff --git a/kvm-plugged-in.sh b/kvm-plugged-in.sh
new file mode 100755
index 0000000..ee1958c
--- /dev/null
+++ b/kvm-plugged-in.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# File: /usr/local/bin/kvm-plugged-in.sh
+# Location: vm2
+# Author: bgstack15
+# Startdate: 2023-01-11-4 14:32
+# Title: Script that runs in user context when kvm is plugged in
+# Project: kvm-mapping
+# Purpose: for vm2, run my keyboard input script.
+# History:
+# Usage:
+# called by kvm-user-daemon.sh when the trigger file is made by the udev rule+script
+# Reference:
+# https://unix.stackexchange.com/questions/71348/why-doesnt-this-udev-rule-trigger-upon-removal-of-the-device
+# Improve:
+# Dependencies:
+# xinput and setxkbmap
+# running in user context, with XAUTHORITY and DISPLAY and probably more env vars
+# Documentation:
+# The contents can be whatever you want. On vm2, I want to set my keyboard mappings.
+for word in $( xinput list | sed -r -n -e 's/.*USB.*Keyboard.*id=([0-9]+).*keyboard.*/\1/p;' ) ;
+do
+ setxkbmap -device ${word} -option grp:switch,grp:shifts_toggle -layout 'us,us(dvorak)'
+done
diff --git a/kvm-udev-trigger.sh b/kvm-udev-trigger.sh
new file mode 100755
index 0000000..af7e84b
--- /dev/null
+++ b/kvm-udev-trigger.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+# File: /usr/locla/bin/kvm-udev-trigger.sh
+# Location: vm2
+# Author: bgstack15
+# Startdate: 2023-01-11-4 11:39
+# Title: Reaction script for Udev detecting kvm input
+# Project: kvm-mapping
+# Purpose: When triggered from udev, touch the file that the per-user daemon listens for
+# History:
+# Usage:
+# when run by udev rule, make file that per-user daemons watch for
+# Reference:
+# Improve:
+# Dependencies:
+# /etc/udev/rules.d/kvm-input.rules
+# ~bin/kvm-mapping-daemon.sh running in user session, from ~/.fluxbox/startup probably
+# logger
+# Dependencies:
+KVMFILE=/run/kvm/kvmfile
+KVMDIR="$( dirname "${KVMFILE}" )"
+test "${DEVTYPE}" = "usb_device" && {
+ ! test -d "${KVMDIR}" && mkdir -p "${KVMDIR}"
+ chmod 0777 "${KVMDIR}"
+ echo "kvm input detected!" | logger --priority user.notice
+ touch "${KVMFILE}" ; chmod 0666 "${KVMFILE}"
+}
diff --git a/kvm-user-daemon.sh b/kvm-user-daemon.sh
new file mode 100755
index 0000000..017644e
--- /dev/null
+++ b/kvm-user-daemon.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+# File: /usr/local/bin/kvm-user-daemon.sh
+# Location: vm2
+# Author: bgstack15
+# Startdate: 2023-01-11-4 11:37
+# Title: KVM user daemon
+# Project: kvm-mapping
+# Purpose: daemon that runs inside user session and runs a script when specific USB device is plugged in
+# History:
+# Usage:
+# Run at start of session, such as in ~/.fluxbox/startup
+# Reference:
+# original design (at least my third time) of stdout/stderr timestamps and logging
+# Improve:
+# Dependencies:
+# Documentation:
+test -z "${LOGFILE}" && test -d ~/log && LOGFILE=~/log/kvm
+test -z "${LOGFILE}" && test -d ~/.log && LOGFILE=~/.log/kvm
+test -z "${LOGFILE}" && export LOGFILE=/tmp/kvm-log
+KVMFILE=/run/kvm/kvmfile
+STOPFILE=/tmp/stop-kvm # touch this file to stop the daemons for all users
+# The user should set RUNSCRIPT, which is what should happen when the kvm is switched to this output.
+test -z "${RUNSCRIPT}" && RUNSCRIPT=~/bin/kvm-plugged-in.sh
+! test -x "${RUNSCRIPT}" && RUNSCRIPT=/usr/local/bin/kvm-plugged-in.sh
+# Crazy nesting allows stdout, stderr prepended with timestamps and "STDERR", both to normal streams and to the logfile.
+{
+ {
+ {
+ # Safety valve. When this file exists, the loop stops.
+ while ! test -f "${STOPFILE}" ;
+ do
+ sleep 1
+ test -f "${KVMFILE}" && {
+ #env
+ #echo "sample error" 1>&2
+ echo "kvm input detected, running \"${RUNSCRIPT}\""
+ "${RUNSCRIPT}"
+ # delay a few seconds, because switching inputs fastis unlikely and not recommended, and so that any other user daemons looking for it can find it and also react.
+ { sleep 3 ; rm -f "${KVMFILE}" ; }
+ }
+ done
+ } 2>&3 1>&4
+ } 3>&1 1>&4 | plecho "STDERR:" | tee -a "${LOGFILE}" 1>&2
+} 4>&1 | plecho | tee -a "${LOGFILE}"
+# Delay a few seconds so other daemons can also find it and stop
+sleep 3 ; rm "${STOPFILE}" 1>/dev/null 2>&1
+# exit 0 with this nop
+:
bgstack15