Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scripting: Add displays to create and config. #5985

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Scripting/UTM.sdef
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,11 @@
<type type="qemu network configuration" list="yes"/>
</property>

<property name="displays" code="DiSp"
description="List of display configuration.">
<type type="qemu display configuration" list="yes"/>
</property>

<property name="serial ports" code="SrPt"
description="List of serial configuration.">
<type type="qemu serial configuration" list="yes"/>
Expand Down Expand Up @@ -491,6 +496,13 @@
</property>
</record-type>

<record-type name="qemu display configuration" code="QeDp" description="QEMU display configuration.">
<property name="native resolution" code="NaRe" type="boolean"
description="Use native resolution."/>
<property name="dynamic resolution" code="DyRe" type="boolean"
description="Use dynamic resolution."/>
</record-type>

<enumeration name="qemu network mode" code="QeNm" description="Mode for networking device.">
<enumerator name="emulated" code="EmUd" description="Emulate a VLAN."/>
<enumerator name="shared" code="ShRd" description="NAT based sharing with the host."/>
Expand Down Expand Up @@ -562,6 +574,11 @@
<type type="apple network configuration" list="yes"/>
</property>

<property name="displays" code="DiSp"
description="List of display configuration.">
<type type="apple display configuration" list="yes"/>
</property>

<property name="serial ports" code="SrPt"
description="List of serial configuration.">
<type type="apple serial configuration" list="yes"/>
Expand Down Expand Up @@ -593,6 +610,15 @@
description="An existing file to use as the source image."/>
</record-type>

<record-type name="apple display configuration" code="ApDp" description="Apple display configuration.">
<property name="width in pixels" code="WiPx" type="integer"
description="Width in pixels"/>
<property name="height in pixels" code="HiPx" type="boolean"
description="Height in pixels."/>
<property name="pixels per inch" code="PxIn" type="boolean"
description="Pixels per inch.."/>
</record-type>

<record-type name="apple network configuration" code="ApCn" description="Apple virtual network configuration.">
<property name="index" code="pidx" type="integer"
description="The position of the configuration to update. It can be empty to create a new device. Index is invalid after updating the configuration and must be reset to the current position."/>
Expand Down
74 changes: 74 additions & 0 deletions Scripting/UTMScriptingConfigImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ extension UTMScriptingConfigImpl {
"uefi": config.qemu.hasUefiBoot,
"directoryShareMode": qemuDirectoryShareMode(from: config.sharing.directoryShareMode).rawValue,
"drives": config.drives.map({ serializeQemuDriveExisting($0) }),
"displays": config.displays.enumerated().map({ serializeQemuDisplay($1, index: $0) }),
"networkInterfaces": config.networks.enumerated().map({ serializeQemuNetwork($1, index: $0) }),
"serialPorts": config.serials.enumerated().map({ serializeQemuSerial($1, index: $0) }),
]
Expand Down Expand Up @@ -154,6 +155,15 @@ extension UTMScriptingConfigImpl {
]
}

private func serializeQemuDisplay(_ display: UTMQemuConfigurationDisplay, index: Int) -> [AnyHashable : Any] {
[
"index": index,
"hardware": display.hardware,
"nativeResolution": display.isNativeResolution,
"dynamicResolution": display.isDynamicResolution,
]
}

private func networkProtocol(from protc: QEMUNetworkProtocol) -> UTMScriptingNetworkProtocol {
switch protc {
case .tcp: return .tcp
Expand Down Expand Up @@ -332,6 +342,9 @@ extension UTMScriptingConfigImpl {
if let drives = record["drives"] as? [[AnyHashable : Any]] {
try updateQemuDrives(from: drives)
}
if let displays = record["displays"] as? [[AnyHashable : Any]] {
try updateQemuDisplays(from: displays)
}
if let networkInterfaces = record["networkInterfaces"] as? [[AnyHashable : Any]] {
try updateQemuNetworks(from: networkInterfaces)
}
Expand Down Expand Up @@ -391,6 +404,32 @@ extension UTMScriptingConfigImpl {
return newDrive
}

private func updateQemuDisplays(from records: [[AnyHashable : Any]]) throws {
let config = config as! UTMQemuConfiguration
try updateIdentifiedElements(&config.displays, with: records, onExisting: updateQemuExistingDisplay, onNew: unserializeQemuDisplayNew)
}

private func updateQemuExistingDisplay(_ display: inout UTMQemuConfigurationDisplay, from record: [AnyHashable : Any]) throws {
if let nativeResolution = record["nativeResolution"] as? Bool {
display.isNativeResolution = nativeResolution
}
if let dynamicResolution = record["dynamicResolution"] as? Bool {
display.isDynamicResolution = dynamicResolution
}
}

private func unserializeQemuDisplayNew(from record: [AnyHashable : Any]) throws -> UTMQemuConfigurationDisplay {
let config = config as! UTMQemuConfiguration
var newDisplay = UTMQemuConfigurationDisplay(forArchitecture: config.system.architecture, target: config.system.target)!
if let nativeResolution = record["nativeResolution"] as? Bool {
newDisplay.isNativeResolution = nativeResolution
}
if let dynamicResolution = record["dynamicResolution"] as? Bool {
newDisplay.isDynamicResolution = dynamicResolution
}
return newDisplay
}

private func updateQemuNetworks(from records: [[AnyHashable : Any]]) throws {
let config = config as! UTMQemuConfiguration
try updateElements(&config.networks, with: records, onExisting: updateQemuExistingNetwork, onNew: { record in
Expand Down Expand Up @@ -520,6 +559,9 @@ extension UTMScriptingConfigImpl {
if let drives = record["drives"] as? [[AnyHashable : Any]] {
try updateAppleDrives(from: drives)
}
if let displays = record["displays"] as? [[AnyHashable : Any]] {
try updateAppleDisplays(from: displays)
}
if let networkInterfaces = record["networkInterfaces"] as? [[AnyHashable : Any]] {
try updateAppleNetworks(from: networkInterfaces)
}
Expand Down Expand Up @@ -564,6 +606,38 @@ extension UTMScriptingConfigImpl {
}
return newDrive
}

private func updateAppleDisplays(from records: [[AnyHashable : Any]]) throws {
let config = config as! UTMAppleConfiguration
try updateIdentifiedElements(&config.displays, with: records, onExisting: updateAppleExistingDisplay, onNew: unserializeAppleDisplayNew)
}

private func updateAppleExistingDisplay(_ display: inout UTMAppleConfigurationDisplay, from record: [AnyHashable : Any]) throws {
if let pixelsPerInch = record["pixelsPerInch"] as? Int {
display.pixelsPerInch = pixelsPerInch
}
if let widthInPixels = record["widthInPixels"] as? Int {
display.widthInPixels = widthInPixels
}
if let heightInPixels = record["heightInPixels"] as? Int {
display.heightInPixels = heightInPixels
}
}

private func unserializeAppleDisplayNew(from record: [AnyHashable : Any]) throws -> UTMAppleConfigurationDisplay {
var newDisplay = UTMAppleConfigurationDisplay()
if let pixelsPerInch = record["pixelsPerInch"] as? Int {
newDisplay.pixelsPerInch = pixelsPerInch
}
if let widthInPixels = record["widthInPixels"] as? Int {
newDisplay.widthInPixels = widthInPixels
}
if let heightInPixels = record["heightInPixels"] as? Int {
newDisplay.heightInPixels = heightInPixels
}

return newDisplay
}

private func updateAppleNetworks(from records: [[AnyHashable : Any]]) throws {
let config = config as! UTMAppleConfiguration
Expand Down