chore: Implement display initialization
This commit is contained in:
parent
5adf93a9d3
commit
0fd3b21d6d
12 changed files with 501 additions and 20 deletions
74
libunreal/linux/__init__.py
Normal file
74
libunreal/linux/__init__.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
import subprocess
|
||||
import os
|
||||
|
||||
from libunreal.supported_devices import supported_devices
|
||||
from libunreal.edid import EvdiDisplaySpec
|
||||
import pyedid
|
||||
|
||||
def fetch_xr_glass_edid(allow_unsupported_devices) -> EvdiDisplaySpec:
|
||||
# Scan for all VGA devices and their IDs
|
||||
pci_device_comand = subprocess.run(["lspci"], capture_output=True)
|
||||
|
||||
if pci_device_comand.returncode != 0:
|
||||
raise OSError("Failed to scan PCI devices")
|
||||
|
||||
pci_devices: list[str] = pci_device_comand.stdout.decode("utf-8").split("\n")
|
||||
pci_devices = pci_devices[:-1]
|
||||
|
||||
vga_devices: list[str] = []
|
||||
|
||||
for pci_device in pci_devices:
|
||||
if "VGA compatible controller:" in pci_device:
|
||||
vga_devices.append(pci_device[:pci_device.index(" ")])
|
||||
|
||||
# Attempt to find any XR glasses
|
||||
for vga_device in vga_devices:
|
||||
card_devices = list(os.listdir(f"/sys/devices/pci0000:00/0000:{vga_device}/drm/"))
|
||||
|
||||
for card_device in card_devices:
|
||||
if "card" not in card_device:
|
||||
continue
|
||||
|
||||
monitors = list(os.listdir(f"/sys/devices/pci0000:00/0000:{vga_device}/drm/{card_device}/"))
|
||||
|
||||
for monitor in monitors:
|
||||
if card_device not in monitor:
|
||||
continue
|
||||
|
||||
with open(f"/sys/devices/pci0000:00/0000:{vga_device}/drm/{card_device}/{monitor}/edid", "rb") as edid:
|
||||
raw_edid_file = edid.read()
|
||||
|
||||
if len(raw_edid_file) == 0:
|
||||
continue
|
||||
|
||||
edid = pyedid.parse_edid(raw_edid_file)
|
||||
|
||||
for manufacturer, manufacturer_supported_devices in supported_devices.items():
|
||||
if edid.manufacturer_pnp_id == manufacturer and (edid.name in manufacturer_supported_devices or allow_unsupported_devices):
|
||||
max_width = 0
|
||||
max_height = 0
|
||||
max_refresh = 0
|
||||
|
||||
for resolution in edid.resolutions:
|
||||
if resolution[0] > max_width and resolution[1] > max_height:
|
||||
max_width = resolution[0]
|
||||
max_height = resolution[1]
|
||||
|
||||
max_refresh = max(max_refresh, int(resolution[2]))
|
||||
|
||||
if max_width == 0 or max_height == 0:
|
||||
if "max_width" not in manufacturer_supported_devices[edid.name] or "max_height" not in manufacturer_supported_devices[edid.name]:
|
||||
raise ValueError("Couldn't determine maximum width and height, and the maximum width and height isn't defined in the device quirks section")
|
||||
|
||||
max_width = int(manufacturer_supported_devices[edid.name]["max_width"])
|
||||
max_height = int(manufacturer_supported_devices[edid.name]["max_height"])
|
||||
|
||||
if max_refresh == 0:
|
||||
if "max_refresh" not in manufacturer_supported_devices[edid.name]:
|
||||
raise ValueError("Couldn't determine maximum refresh rate, and the maximum refresh rate isn't defined in the device quirks section")
|
||||
|
||||
max_refresh = int(manufacturer_supported_devices[edid.name]["max_refresh"])
|
||||
|
||||
return EvdiDisplaySpec(raw_edid_file, max_width, max_height, max_refresh)
|
||||
|
||||
raise ValueError("Could not find supported device. Check if the device is plugged in. If it is plugged in and working correctly, check the README or open an issue.")
|
Loading…
Add table
Add a link
Reference in a new issue