Move shutdown screen to wrapper, reuse stock firmware goodbye.png

The in-app shutdown visual didn't work because SDL cleanup wiped the
framebuffer. Instead of hacking around that, move the shutdown display
to the device wrapper where it belongs. The wrapper now decodes the
stock firmware's goodbye.png with Python3+PIL and writes raw BGRA
pixels directly to /dev/fb0 before calling poweroff.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michael Smith
2026-02-13 21:07:03 +01:00
parent 3728e9499c
commit 06daec791e
4 changed files with 86 additions and 31 deletions

View File

@@ -5,7 +5,8 @@
# Launched by dmenu_ln instead of sdlamp2 directly. Handles device-specific
# concerns that don't belong in the player binary:
# 1. Monitor power button and trigger clean shutdown
# 2. Launch sdlamp2 as the main process
# 2. Display the stock firmware's shutdown screen (goodbye.png → /dev/fb0)
# 3. 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
@@ -24,13 +25,21 @@ AUDIO_DIR="/mnt/sdcard/Music"
POWER_EVENT_DEV="/dev/input/event0"
monitor_power_button() {
# evtest writes one line per event; filter for KEY_POWER press (value 1)
POWER_TIMER_PID=""
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
# Power button pressed — start 3-second hold timer
( trap 'exit 0' TERM; sleep 3; touch /tmp/.sdlamp2_shutdown; kill -TERM "$SDLAMP2_PID" 2>/dev/null ) &
POWER_TIMER_PID=$!
;;
*"code 116"*"value 0"*)
# Power button released — cancel timer if still running
if [ -n "$POWER_TIMER_PID" ]; then
kill "$POWER_TIMER_PID" 2>/dev/null
wait "$POWER_TIMER_PID" 2>/dev/null
POWER_TIMER_PID=""
fi
;;
esac
done
@@ -52,4 +61,23 @@ SDLAMP2_EXIT=$?
# Kill the power button monitor if it's still running
kill "$MONITOR_PID" 2>/dev/null
# If this was a shutdown, call poweroff and block so the loadapp.sh restart
# loop doesn't relaunch dmenu_ln (which would take over the framebuffer and
# overwrite sdlamp2's shutdown screen).
if [ -f /tmp/.sdlamp2_shutdown ]; then
rm -f /tmp/.sdlamp2_shutdown
# Display the stock firmware's shutdown screen via framebuffer.
# goodbye.png is 640x480 RGB — exactly matches the display.
# /dev/fb0 is 32bpp BGRA, so we swap R/B channels and write raw pixels.
python3 -c "
from PIL import Image
img = Image.open('/mnt/vendor/res1/shutdown/goodbye.png').convert('RGBA')
r, g, b, a = img.split()
with open('/dev/fb0', 'wb') as f:
f.write(Image.merge('RGBA', (b, g, r, a)).tobytes())
" 2>/dev/null
poweroff
sleep 30
fi
exit "$SDLAMP2_EXIT"