# PXE menu theme — research for next-release follow-up Status: queued. v0.4.63 keeps the ASCII-banner fallback + `console --picture` compositor wired; this note captures the design for the menu-theming work that lands once iPXE rebuilt with `IMAGE_PNG` is published. ## How iVentoy actually does it iVentoy is closed-source for its menu, but the supporting bits are public at https://github.com/ventoy/PXE — a vanilla iPXE snapshot (`iPXE/ipxe-bd13697`) used to produce the loader binaries iVentoy serves over TFTP (`pxeboot.efi`, `iventoy_loader_16000`, `iventoy_loader_16000_uefi`). The graphical menu itself is rendered by iPXE's framebuffer console with a baked-in PNG background via `console --picture` — same primitive OpenPXE already uses in `crates/http-api/src/ipxe_script.rs`. Evidence: - The iPXE build in `ventoy/PXE` is configured with `CONSOLE_FRAMEBUFFER` + `IMAGE_PNG` + `CONSOLE_CMD` (the three flags `console --picture` needs). - iVentoy issue #11 confirms "iventoy using default 1024x768"; users report 800x600 / 1024x768 / 1280x720 / 1280x1024 / 1920x1080 as selectable resolutions from the iVentoy web UI **Configuration tab**, not via EDID auto-detect. iPXE has no EDID parsing; the daemon writes a resolution-tagged script per boot and serves the matching PNG. - iVentoy docs explicitly state both Free and Pro editions **do not support** modifying the boot background/title — it's baked into the shipped PNG assets. - Chrome is iPXE's native `menu` / `item` / `choose` widgets (single highlight bar, no borders) painted on top of the PNG, with margins set via `console --left/--right/--top/--bottom` to keep the text off the logo. Not GRUB, not syslinux — UEFI iVentoy uses iPXE's `snponly.efi` / `pxeboot.efi`, and `--picture` does work under UEFI GOP despite older folklore. Do not conflate this with Ventoy-USB, which is a separate codebase and uses GRUB2 themes (`theme.txt`, `background_ventoy.png`, `select_c.png`). ## Rust ingredients to replicate / surpass Most of these already exist in the workspace. 1. **Compositor (extend, don't replace)** — extend `crates/iso-store/src/pxe_logo.rs` to emit per-resolution PNGs (1024x768, 1280x1024, 1920x1080 as the v1 set). `image` + `imageproc` crates handle scaling; `ab_glyph` / `fontdue` for raster text (subtitle, hostname, version). One source SVG/logo, three to five rendered PNGs cached on disk. 2. **Script generator** — `ipxe_script.rs` already emits `console --picture … || console`. Add a `?res=` query param (or per-MAC client hint persisted in `hosts.json`) and serve the matching PNG plus matching `console --x --y` line. Keep the text-console fallback already in place. 3. **Resolution selection** — iPXE exposes `${vesa-x}` / `${vesa-y}` on BIOS; UEFI side we can probe firmware vars at chain-time. The simpler v1 is a "low-res / hi-res" toggle in Settings plus a per-host override — mirrors iVentoy's UX, no kernel helper needed. True EDID parsing is overkill for the first cut. 4. **Chrome upgrades over iVentoy** — iPXE menus are limited (single highlight, no borders). To look distinctly cooler without leaving iPXE: paint border / title / footer **into the PNG**, leave a window in the middle, then `console --left/--right/--top/--bottom` to inset the iPXE menu exactly into that window. ASCII box-drawing inside the menu remains fragile (iPXE mangles non-ASCII on some builds — already noted in `ipxe_script.rs`). ## Recommended architecture for the next OpenPXE release - Build a `pxe_theme` module beside `pxe_logo.rs`: takes operator logo + theme tokens (accent colour, title, footer) and renders a layered PNG (background gradient → framing chrome → logo → title bar → footer with `${hostname}` / `${version}` / `${ip}`) at the three target resolutions. Cache by hash of inputs. - Serve at `/branding/pxe-menu-{w}x{h}.png`. Default 1024x768; expose a Settings dropdown. - In `ipxe_script.rs`, emit `console --picture …/pxe-menu-1024x768.png --left 80 --right 80 --top 180 --bottom 60 || console`, then the existing `menu` / `item` / `choose` block — text now lands inside the framed window. - Compile iPXE with `CONSOLE_FRAMEBUFFER`, `IMAGE_PNG`, `CONSOLE_CMD`, `CONSOLE_VESAFB` (BIOS) and `CONSOLE_EFIFB` (UEFI). The v0.4.61 image attempted this in-Docker via QEMU emulation and hit `cc1` segfaults. The follow-up will use a Gitea Actions runner pinned to native `linux/amd64` (an Unraid host already exists for this). - Stretch goal: a second "theme pack" that ships a layered PNG with subtle scanlines / grid — iPXE can't animate, but a well-designed static composite beats iVentoy's plain centered logo handily. ## Source URLs - https://github.com/ventoy/PXE - https://github.com/ventoy/PXE/tree/master/iPXE - https://github.com/ventoy/PXE/issues/11 — 1024x768 default - https://github.com/ventoy/PXE/issues/59 — iVentoy iPXE EFI loader - https://ipxe.org/cmd/console — `--picture` and compile flags - https://github.com/ipxe/ipxe/discussions/945 — background image how-to - https://github.com/ipxe/ipxe/discussions/802 — `CONSOLE_FRAMEBUFFER` requirement - https://github.com/ipxe/ipxe/discussions/1006 — picture resolution behaviour - https://www.iventoy.com/en/doc_edition.html — background / title not user-customisable - https://kingtam.win/archives/iventoy.html — third-party iPXE-based iVentoy alternative