libretro / Lakka-LibreELEC

Lakka is a lightweight Linux distribution that transforms a small computer into a full blown game console.
https://www.lakka.tv
1.7k stars 288 forks source link

GPi Case 2 : RetroArch tries to display on the internal monitor when docked #1983

Open imaspeer opened 3 weeks ago

imaspeer commented 3 weeks ago

Using a Raspberry Pi Compute Module 4 in a RetroFlag GPi Case 2 and the official RPi4-GPICase2 5.0 image in the default configuration :

When the system is connected to its dock, with the dock's HDMI output connected to a monitor, the internal monitor turns off (correctly) and the external monitor only displays the flower screen, in a 640x480 box in the top left.

It is expected RetroArch shows up on the external monitor instead ; or at the very least if it doesn't switch automatically the internal monitor should not be turned off, as this leaves the user without a way to interact with the system.

Setting video_monitor_index="2" in retroarch.cfg fixes it, but that breaks the internal monitor (only shows the flower) when not docked.

This happens regardless of if the system is started while already connected to the dock or if it is hotplugged. (On the plus side, the latter case is technically an improvement over the old switching scripts that didn't support hotplugging at all... But it'd be better if it actually worked :D )

Logs don't seem to have anything interesting, still including them just in case: retroarch -v with the bug retroarch -v with retroarch.cfg workaround applied

imaspeer commented 3 weeks ago

I investigated a bit more and there doesn't seem to be a way to detect whether an external monitor is plugged in or not. In particular /sys/class/drm/card0/card0-HDMI-A-1/status is always connected even while not on the dock, the edid is also always the same regardless of what monitor is connected or if there is one at all.

The dock itself, however, is detectable as a USB hub with id 1a40:0101. One such hub is always present and a second one is added when docked.

I've come up with a workaround that changes the config and restarts RetroArch when the hub is added or removed. Definitely not a great way to do it, but I couldn't find anything better.

.config/set-monitor.sh

#!/bin/sh
if [[ $(lsusb -d 1a40:0101 |wc -l) -gt 1 ]]; then
    echo 'video_monitor_index = "2"' >/tmp/retroarch-monitor.cfg
else
    echo 'video_monitor_index = "0"' >/tmp/retroarch-monitor.cfg
fi

.config/systemd.d/retroarch.service.d/99-set-monitor.conf

[Service]
ExecStartPre=-/storage/.config/set-monitor.sh
ExecStart=
ExecStart=/usr/bin/retroarch --appendconfig=/tmp/retroarch-monitor.cfg

.config/udev/rules.d/99-gpicase2.dock.rules

ACTION=="add", SUBSYSTEM=="usb", ENV{PRODUCT}=="1a40/101/111", ENV{DEVTYPE}=="usb_device", RUN+="/usr/bin/systemctl restart retroarch"
ACTION=="remove", SUBSYSTEM=="usb", ENV{PRODUCT}=="1a40/101/111", ENV{DEVTYPE}=="usb_device", RUN+="/usr/bin/systemctl restart retroarch"