Skip to content

[H700] Fix screen rotation and enable independent HDMI/internal settings#32

Open
fedekrum wants to merge 1 commit intoknulli-cfw:knulli-mainfrom
fedekrum:h700-rotation-support
Open

[H700] Fix screen rotation and enable independent HDMI/internal settings#32
fedekrum wants to merge 1 commit intoknulli-cfw:knulli-mainfrom
fedekrum:h700-rotation-support

Conversation

@fedekrum
Copy link
Copy Markdown

@fedekrum fedekrum commented Feb 15, 2026

Summary

Enable independent display rotation for HDMI and internal outputs on Allwinner H700 devices (RG40XX-H, RG35XX-H/Plus, etc.), controllable directly from the EmulationStation System Settings menu without editing config files.

Use case: A user wants their HDMI output rotated 90° for a vertical arcade monitor, while keeping the internal screen at 0° (landscape).

Problem

The EmulationStation UI only writes to the global display.rotate key in knulli.conf. However, the emulationstation-standalone launcher already supports per-output rotation keys (display.rotate.hdmi, display.rotate.internal) — it checks display.rotate.{output} first, then falls back to display.rotate.

The issue is that these per-output keys are never populated because:

  1. The ES UI only writes display.rotate (global)
  2. currentOutput was empty, so the launcher could never determine the active output

Solution

Bridge the gap at the shell level with a sync_rotation_per_output() function that transparently manages per-output rotation values:

  • On output change (HDMI plugged/unplugged): restores display.rotate from the saved value for the newly active output
  • On same output (user changed rotation in UI): persists the current display.rotate value to the active output key (display.rotate.hdmi or display.rotate.internal)

This approach requires zero changes to EmulationStation — all logic is contained in the H700 knulli-resolution script.

Changes (minimal, surgical edits)

Change Type Original code modified?
LAST_STATE_FILE variable 1 line added No
sync_rotation_per_output() function New block inserted No (between existing functions)
setOutput: call sync function 1 line added No
currentOutput: return hdmi or internal Fill empty case No (was empty)
supportSystemRotation: return exit 1 1 line in empty case No (was empty)
currentResolution: swap WxH for portrait Modified 2 lines Yes — fbset output captured in variable

Only 2 original lines are modified. Everything else is new code or fills previously empty case blocks.

Configuration

Per-output rotation is managed automatically. Users simply change "SCREEN ROTATION" in ES System Settings as usual. The sync function handles the rest:

# These keys are managed automatically — users do NOT need to edit them
display.rotate=1            # Global (what ES UI reads/writes)
display.rotate.hdmi=1       # Saved HDMI rotation
display.rotate.internal=0   # Saved internal rotation

Technical Details

  • supportSystemRotation returns exit 1 to force software rotation via --screenrotate. Hardware rotation on the H700 (via fb0/rotate) causes image artifacts on HDMI.
  • currentResolution swaps width/height when rotation is 90° or 270° so ES themes render with correct aspect ratio in portrait mode.
  • HDMI state tracking uses /var/run/last_hdmi_state (volatile, cleared on reboot).

Testing

Tested on RG40XX-H running Knulli alpha 20260209:

  • ✅ HDMI output rotated 90° for vertical arcade setup
  • ✅ Internal display unrotated when HDMI disconnected
  • ✅ Rotation values persist independently per output
  • ✅ HDMI hot-plug switching works correctly
  • ✅ Rapid HDMI connect/disconnect does not cause hangs
  • ✅ No regression on standard (non-rotated) usage
  • ✅ Zero impact on devices without HDMI (sync is a no-op)

@fedekrum
Copy link
Copy Markdown
Author

fedekrum commented Feb 15, 2026

🛠️ Manual installation (no compilation needed)

For anyone who wants to test this before it gets merged. Tested on RG40XX-H with Knulli alpha 20260209.

# 1. SSH into the device (default password: linux)
ssh root@<DEVICE_IP>

# 2. Remount filesystem as read-write
mount -o remount,rw /

# 3. Back up the original script
cp /usr/bin/knulli-resolution /usr/bin/knulli-resolution.bak

# 4. Download the patched script directly from this PR
curl -sL https://raw.githubusercontent.com/fedekrum/knulli-linux/h700-rotation-support/board/allwinner/h700/fsoverlay/usr/bin/knulli-resolution \
  -o /usr/bin/knulli-resolution

# 5. Ensure it is executable
chmod 755 /usr/bin/knulli-resolution

# 6. Save overlay so the change persists across reboots
knulli-save-overlay

# 7. Reboot
reboot

How to use

Change SCREEN ROTATION in ES System Settings as usual. The sync function handles per-output values automatically:

  • While on HDMI → rotation saved to display.rotate.hdmi
  • While on internal → rotation saved to display.rotate.internal
  • Plug/unplug HDMI → correct rotation restored automatically

@fedekrum fedekrum changed the title [H700] Implement display rotation and output detection [H700] Implement independent display rotation for HDMI and internal outputs via ES menu Feb 15, 2026
@fedekrum fedekrum changed the title [H700] Implement independent display rotation for HDMI and internal outputs via ES menu [H700] Independent display rotation for HDMI and internal outputs via ES menu Feb 15, 2026
@fedekrum fedekrum changed the title [H700] Independent display rotation for HDMI and internal outputs via ES menu [H700] Per-output rotation sync for independent HDMI/internal display rotation Feb 16, 2026
The emulationstation-standalone launcher already supports per-output
rotation keys (display.rotate.hdmi, display.rotate.internal), but the
EmulationStation UI only writes to the global display.rotate key. This
left per-output keys always empty, making independent HDMI/internal
rotation impossible from the UI.

This patch bridges that gap with a sync function that transparently
manages per-output rotation values at the shell level:

- On output change (HDMI plug/unplug): restores display.rotate from
  the saved value for the newly active output.
- On same output: persists the current display.rotate value to the
  active output key.

Additionally fills three empty case blocks that are prerequisites for
rotation to work on the H700:

- currentOutput: returns hdmi or internal (required by the launcher to
  look up per-output rotation keys)
- currentResolution: swaps WxH when rotation is 90/270 degrees so
  themes render with correct aspect ratio in portrait mode
- supportSystemRotation: returns exit 1 to force software rotation via
  --screenrotate (hardware rotation causes artifacts on H700 HDMI)

Tested on RG40XX-H with Knulli alpha 20260209.
@fedekrum fedekrum force-pushed the h700-rotation-support branch from 386acf9 to a1438c4 Compare February 16, 2026 08:32
@fedekrum fedekrum changed the title [H700] Per-output rotation sync for independent HDMI/internal display rotation [H700] Fix screen rotation and enable independent HDMI/internal rotation Feb 16, 2026
@fedekrum fedekrum changed the title [H700] Fix screen rotation and enable independent HDMI/internal rotation [H700] Fix screen rotation and enable independent HDMI/internal settings Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant