From 3728e9499cdda46e56d13751d597a9eb958f345c Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 13 Feb 2026 20:07:37 +0100 Subject: [PATCH] Implement power button monitor, document device input devices Co-Authored-By: Claude Opus 4.6 --- docs/rg35xx-plus.md | 13 ++++++++ docs/sdlamp2-fsd.md | 4 +++ tools/rg35xx-wrapper.sh | 70 ++++++++++++++++++----------------------- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/docs/rg35xx-plus.md b/docs/rg35xx-plus.md index 6e90b0a..a0f11af 100644 --- a/docs/rg35xx-plus.md +++ b/docs/rg35xx-plus.md @@ -33,6 +33,19 @@ All required shared libraries are pre-installed. Most are at `/usr/lib/`, some a Shared libraries are already present — no need to bundle or build them. A native aarch64 compile (e.g. inside the arm64 Docker container) produces working binaries. Must link against glibc ≤ 2.35. +## Input Devices + +Three input devices are registered via `/proc/bus/input/devices`: + +| Device | Handlers | Purpose | +|--------|----------|---------| +| `axp2202-pek` | `event0` | Power button (`KEY_POWER`, code 116) | +| `ANBERNIC-keys` | `event1`, `js0` | Gamepad (d-pad, face buttons) | +| `dierct-keys-polled` | `event2` | Shoulder buttons, menu/function keys | + +- **logind**: `HandlePowerKey=ignore` in `/etc/systemd/logind.conf` — systemd does not act on the power button, leaving it free for userspace handling. +- **evtest**: Available at `/usr/bin/evtest` for debugging input events. + ## Partition Layout | Device | Mount point | Filesystem | Contents | diff --git a/docs/sdlamp2-fsd.md b/docs/sdlamp2-fsd.md index d39f915..587ba48 100644 --- a/docs/sdlamp2-fsd.md +++ b/docs/sdlamp2-fsd.md @@ -43,6 +43,10 @@ This document specifies the functional requirements for an SDL2 based media play ## 6. Changelog +### 2026-02-13 — Power button monitor in device wrapper + +- **Power button handling**: The `rg35xx-wrapper.sh` script now monitors `/dev/input/event0` (`axp2202-pek`) for `KEY_POWER` press events via `evtest`. On power button press, sends SIGTERM to sdlamp2 (which saves position and volume), waits 1 second, then calls `poweroff` for a clean shutdown. + ### 2026-02-13 — Clean shutdown on SIGTERM/SIGINT - **Signal handling**: sdlamp2 now catches SIGTERM and SIGINT via a `sig_atomic_t` flag checked in the main loop. On signal, the existing cleanup path runs (save position, save volume, close decoder, SDL_Quit) instead of being killed instantly. This ensures position is saved when the system shuts down or the process is terminated by a wrapper script. diff --git a/tools/rg35xx-wrapper.sh b/tools/rg35xx-wrapper.sh index dacd3d1..8c4d259 100755 --- a/tools/rg35xx-wrapper.sh +++ b/tools/rg35xx-wrapper.sh @@ -4,9 +4,8 @@ # # Launched by dmenu_ln instead of sdlamp2 directly. Handles device-specific # concerns that don't belong in the player binary: -# 1. Start WiFi hotspot (AP mode for SSH access) -# 2. Launch sdlamp2 as the foreground process -# 3. Monitor power button and trigger clean shutdown +# 1. Monitor power button and trigger clean shutdown +# 2. Launch sdlamp2 as the main process # # Install: copy to /mnt/vendor/bin/rg35xx-wrapper.sh # Config: set CMD in dmenu_ln to point here instead of sdlamp2 directly @@ -15,49 +14,42 @@ SDLAMP2="/mnt/vendor/bin/sdlamp2" AUDIO_DIR="/mnt/sdcard/Music" # --- WiFi hotspot --- -# TODO: Investigate how the stock menu starts AP mode. -# Likely candidates: hostapd, nmcli, or a vendor script in /mnt/vendor/ctrl/. -# Run these on the device to find out: -# grep -r 'hostapd\|hotspot\|ap_mode\|wifi' /mnt/vendor/ctrl/ -# systemctl list-units | grep -i net -# nmcli general status && nmcli connection show -# -# Placeholder — uncomment/replace once the mechanism is known: -# nmcli connection up hotspot 2>/dev/null || true +# Deprioritized: connecting the device as a WiFi client to a shared network +# works fine even when sdlamp2 replaces the stock menu. Hotspot/AP mode isn't +# needed — SSH access works over the shared network. # --- Power button monitor --- -# TODO: Investigate power button input device. -# Run on device: -# cat /proc/bus/input/devices (find the power button event device) -# evtest /dev/input/eventN (confirm KEY_POWER event code) -# cat /etc/systemd/logind.conf (check HandlePowerKey setting) -# -# Strategy: read key events from the power button input device in background. -# When KEY_POWER (code 116) is detected, send SIGTERM to sdlamp2 and poweroff. -# -# POWER_EVENT_DEV="/dev/input/eventN" # TBD: set after investigation -# -# monitor_power_button() { -# # evtest writes one line per event; filter for KEY_POWER press (value 1) -# evtest "$POWER_EVENT_DEV" 2>/dev/null | while read -r line; do -# case "$line" in -# *"code 116"*"value 1"*) -# kill -TERM "$SDLAMP2_PID" 2>/dev/null -# sleep 1 -# poweroff -# ;; -# esac -# done -# } -# monitor_power_button & -# MONITOR_PID=$! +# axp2202-pek on /dev/input/event0 sends KEY_POWER (code 116). +# logind has HandlePowerKey=ignore, so we handle it here. +POWER_EVENT_DEV="/dev/input/event0" + +monitor_power_button() { + # evtest writes one line per event; filter for KEY_POWER press (value 1) + evtest "$POWER_EVENT_DEV" 2>/dev/null | while read -r line; do + case "$line" in + *"code 116"*"value 1"*) + kill -TERM "$SDLAMP2_PID" 2>/dev/null + sleep 1 + poweroff + ;; + esac + done +} # --- Launch sdlamp2 --- -"$SDLAMP2" "$AUDIO_DIR" +# Run in background so we can capture PID for the power button monitor. +"$SDLAMP2" "$AUDIO_DIR" & +SDLAMP2_PID=$! + +monitor_power_button & +MONITOR_PID=$! + +# Wait for sdlamp2 to finish (signal or normal exit). +wait "$SDLAMP2_PID" SDLAMP2_EXIT=$? # --- Cleanup --- # Kill the power button monitor if it's still running -# kill "$MONITOR_PID" 2>/dev/null +kill "$MONITOR_PID" 2>/dev/null exit "$SDLAMP2_EXIT"