podprobe: emit boot-STABLE panel identities + ready-to-paste monitor🆔 lines

Adds a section resolving each screen's panel identity via the SAME Win32 API the
game uses (EnumDisplayDevices on the display's MONITOR child) rather than the
WmiMonitorID query above -- if probe and engine read different sources the
printed fragments could fail to match what the engine tests.  Verified on the
dev box: probe and engine emit byte-identical identities.

Answers the open [T3] multi-panel question WITHOUT deploying a build (pure OS
data).  When one EDID code appears on SEVERAL panels (identical MFD models) it
detects the collision and emits the per-connector UID form instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SgmXGNMXavXiafKXf9MDC
This commit is contained in:
Joe DiPrima
2026-08-08 15:58:12 -05:00
co-authored by Claude Opus 5
parent ec080cd61d
commit 990ad52563
+88
View File
@@ -82,6 +82,94 @@ try {
} catch { W " (EDID query failed -- normal over some remote sessions: $_)" }
W ""
# ---------------------------------------------------------------------------
# BOOT-STABLE panel identity. Windows renumbers \\.\DISPLAYn and reorders the
# enumeration when a panel is power-cycled or re-cabled, so binding the pod by
# index or device name is fragile (Nick, 2026-08-07: "the order changed ... even
# if the visual desktop tool looks the same"). Bind by the panel's own EDID
# identity instead: glass_layout.cfg accepts `monitor:id:<fragment>`.
#
# This deliberately calls the SAME Win32 API the game does (EnumDisplayDevices
# on the display's MONITOR child) rather than the WmiMonitorID above -- if the
# probe and the engine read different sources, the fragments printed here might
# not be what the engine actually matches against.
# ---------------------------------------------------------------------------
W "---- BOOT-STABLE panel identity (paste these into glass_layout.cfg) ----"
try {
if (-not ("BTDisp" -as [type])) {
Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;
public class BTDisp {
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct DISPLAY_DEVICE {
public int cb;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string DeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string DeviceString;
public int StateFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string DeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string DeviceKey;
}
[DllImport("user32.dll", CharSet=CharSet.Ansi)]
public static extern bool EnumDisplayDevicesA(string dev, uint num, ref DISPLAY_DEVICE dd, uint flags);
public static string MonitorId(string display) {
DISPLAY_DEVICE dd = new DISPLAY_DEVICE();
dd.cb = Marshal.SizeOf(typeof(DISPLAY_DEVICE));
// 0x1 = EDD_GET_DEVICE_INTERFACE_NAME (richer path, includes connector UID)
if (!EnumDisplayDevicesA(display, 0, ref dd, 0x1)) {
dd = new DISPLAY_DEVICE();
dd.cb = Marshal.SizeOf(typeof(DISPLAY_DEVICE));
if (!EnumDisplayDevicesA(display, 0, ref dd, 0)) return "";
}
return dd.DeviceID;
}
}
'@
}
$codes = @{}
$rows = @()
foreach ($s in [System.Windows.Forms.Screen]::AllScreens) {
$sid = [BTDisp]::MonitorId($s.DeviceName)
# EDID PnP code = 3 letters + 4 hex digits (AUO10ED, DEL4231)
$code = ""
if ($sid -match '[\\#\?]([A-Za-z]{3}[0-9A-Fa-f]{4})[\\#\?]') { $code = $Matches[1] }
elseif ($sid -match '([A-Za-z]{3}[0-9A-Fa-f]{4})') { $code = $Matches[1] }
$rows += [pscustomobject]@{ Dev=$s.DeviceName; Prim=$s.Primary; Sid=$sid; Code=$code
X=$s.Bounds.X; Y=$s.Bounds.Y; W=$s.Bounds.Width; H=$s.Bounds.Height }
if ($code -ne "") { $codes[$code] = 1 + $(if ($codes.ContainsKey($code)) { $codes[$code] } else { 0 }) }
}
foreach ($r in $rows) {
W (" {0}{1} {2},{3} {4}x{5}" -f $r.Dev, $(if ($r.Prim) { " *PRIMARY*" } else { "" }), $r.X, $r.Y, $r.W, $r.H)
W (" stable-id : {0}" -f $(if ($r.Sid) { $r.Sid } else { "(unavailable)" }))
if ($r.Code -ne "" -and $codes[$r.Code] -gt 1) {
# Same model on more than one output: the EDID code alone is ambiguous.
# The connector UID in the tail is what separates them.
$uid = ""
if ($r.Sid -match '(UID[0-9]+)') { $uid = $Matches[1] }
if ($uid -ne "") {
W (" cfg form : monitor:id:{0} <-- code '{1}' is on {2} panels, so use the UID" -f $uid, $r.Code, $codes[$r.Code])
} else {
W (" cfg form : (AMBIGUOUS -- '{0}' appears on {1} panels and no UID found;" -f $r.Code, $codes[$r.Code])
W " use a longer unique substring of stable-id above)"
}
} elseif ($r.Code -ne "") {
W (" cfg form : monitor:id:{0}" -f $r.Code)
} else {
W " cfg form : (no EDID code parsed -- use a substring of stable-id)"
}
}
$dupes = ($codes.GetEnumerator() | Where-Object { $_.Value -gt 1 } | Measure-Object).Count
if ($dupes -gt 0) {
W ""
W (" NOTE: {0} EDID code(s) appear on more than one panel (identical models)." -f $dupes)
W " Those lines use the connector UID instead, which is per-output."
}
W ""
W " Run this again AFTER a reboot or a panel power-cycle: the device names"
W " and ordering above may move, but stable-id / cfg form must NOT."
} catch { W " (stable-identity probe failed: $_)" }
W ""
W "---- SERIAL PORTS (the RIO board lives on one of these) ----"
try {
$sp = Get-CimInstance Win32_SerialPort