UTM/Platform/Shared/VMWizardStartView.swift

151 lines
5.0 KiB
Swift

//
// Copyright © 2021 osy. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftUI
#if canImport(Virtualization)
import Virtualization
#endif
struct VMWizardStartView: View {
@ObservedObject var wizardState: VMWizardState
var isVirtualizationSupported: Bool {
#if os(macOS)
VZVirtualMachine.isSupported && !processIsTranslated()
#else
jb_has_hypervisor()
#endif
}
var isEmulationSupported: Bool {
#if WITH_QEMU_TCI
true
#else
Main.jitAvailable
#endif
}
var body: some View {
VMWizardContent("Start") {
Section {
let virtButton = Button {
wizardState.useVirtualization = true
wizardState.next()
} label: {
HStack {
Image(systemName: "hare")
.font(.title)
VStack(alignment: .leading, spacing: 10) {
Text("Virtualize")
.font(.title)
Text("Faster, but can only run the native CPU architecture.")
.font(.caption)
}
Spacer()
}
.padding()
}
.buttonStyle(.inList)
.disabled(!isVirtualizationSupported)
#if os(iOS) || os(visionOS)
if #available(iOS 15, *) {
virtButton
} else {
virtButton
.opacity(isVirtualizationSupported ? 1 : 0.5)
}
#else
virtButton
#endif
Button {
wizardState.useVirtualization = false
wizardState.next()
} label: {
HStack {
Image(systemName: "tortoise")
.font(.title)
VStack(alignment: .leading, spacing: 10) {
Text("Emulate")
.font(.title)
Text("Slower, but can run other CPU architectures.")
.font(.caption)
}
Spacer()
}
.padding()
}
.buttonStyle(.inList)
} header: {
Text("Custom")
} footer: {
if !isEmulationSupported && !isVirtualizationSupported {
Text("Your version of iOS does not support running VMs while unmodified. You must either run UTM while jailbroken or with a remote debugger attached. See https://getutm.app/install/ for more details.")
} else if !isVirtualizationSupported {
Text("Virtualization is not supported on your system.")
} else if !isEmulationSupported {
Text("This build does not emulation.")
}
}
Section {
Button {
NotificationCenter.default.post(name: NSNotification.OpenVirtualMachine, object: nil)
} label: {
Label {
Text("Open…")
} icon: {
Image(systemName: "doc")
}
}
#if os(macOS)
.buttonStyle(.link)
#endif
Link(destination: URL(string: "https://mac.getutm.app/gallery/")!) {
Label {
Text("Download prebuilt from UTM Gallery…")
} icon: {
Image(systemName: "arrow.down.doc")
}
}
} header: {
Text("Existing")
}
}
}
private func processIsTranslated() -> Bool {
let key = "sysctl.proc_translated"
var ret = Int32(0)
var size: Int = 0
sysctlbyname(key, nil, &size, nil, 0)
let result = sysctlbyname(key, &ret, &size, nil, 0)
if result == -1 {
return false
}
return ret != 0
}
}
struct VMWizardStartView_Previews: PreviewProvider {
@StateObject static var wizardState = VMWizardState()
static var previews: some View {
VMWizardStartView(wizardState: wizardState)
}
}