151 lines
5.0 KiB
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)
|
|
}
|
|
}
|