UTMQemuConfigurationInput.swift 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. //
  2. // Copyright © 2022 osy. All rights reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. import Foundation
  17. /// Settings for input devices and USB.
  18. struct UTMQemuConfigurationInput: Codable {
  19. /// Level of USB support (disabled/2.0/3.0).
  20. var usbBusSupport: QEMUUSBBus = .usb2_0
  21. /// If enabled, USB forwarding can be used (if supported by the host).
  22. var hasUsbSharing: Bool = false
  23. /// The maximum number of USB devices that can be forwarded concurrently.
  24. var maximumUsbShare: Int = 3
  25. enum CodingKeys: String, CodingKey {
  26. case usbBusSupport = "UsbBusSupport"
  27. case hasUsbSharing = "UsbSharing"
  28. case maximumUsbShare = "MaximumUsbShare"
  29. }
  30. init() {
  31. }
  32. init(from decoder: Decoder) throws {
  33. let values = try decoder.container(keyedBy: CodingKeys.self)
  34. usbBusSupport = try values.decode(QEMUUSBBus.self, forKey: .usbBusSupport)
  35. hasUsbSharing = try values.decode(Bool.self, forKey: .hasUsbSharing)
  36. maximumUsbShare = try values.decode(Int.self, forKey: .maximumUsbShare)
  37. }
  38. func encode(to encoder: Encoder) throws {
  39. var container = encoder.container(keyedBy: CodingKeys.self)
  40. try container.encode(usbBusSupport, forKey: .usbBusSupport)
  41. try container.encode(hasUsbSharing, forKey: .hasUsbSharing)
  42. try container.encode(maximumUsbShare, forKey: .maximumUsbShare)
  43. }
  44. }
  45. // MARK: - Default construction
  46. extension UTMQemuConfigurationInput {
  47. init(forArchitecture architecture: QEMUArchitecture, target: any QEMUTarget) {
  48. self.init()
  49. let rawTarget = target.rawValue
  50. if !architecture.hasUsbSupport || !target.hasUsbSupport {
  51. usbBusSupport = .disabled
  52. } else if rawTarget.hasPrefix("pc") || rawTarget.hasPrefix("q35") {
  53. usbBusSupport = .usb3_0
  54. } else if (architecture == .arm || architecture == .aarch64) && (rawTarget.hasPrefix("virt-") || rawTarget == "virt") {
  55. usbBusSupport = .usb3_0
  56. }
  57. }
  58. }
  59. // MARK: - Conversion of old config format
  60. extension UTMQemuConfigurationInput {
  61. init(migrating oldConfig: UTMLegacyQemuConfiguration) {
  62. self.init()
  63. if oldConfig.inputLegacy {
  64. usbBusSupport = .disabled
  65. } else if oldConfig.usb3Support {
  66. usbBusSupport = .usb3_0
  67. } else {
  68. usbBusSupport = .usb2_0
  69. }
  70. if let sharingNum = oldConfig.usbRedirectionMaximumDevices {
  71. hasUsbSharing = true
  72. maximumUsbShare = sharingNum.intValue
  73. }
  74. }
  75. }