add GPU reader and settings

init GPU popup
This commit is contained in:
Serhiy Mytrovtsiy
2020-08-17 20:37:20 +02:00
parent 0d63ae1061
commit 98fb84163e
11 changed files with 424 additions and 26 deletions

View File

@@ -78,13 +78,18 @@ internal class Settings: NSView, Settings_v {
}
private func addDiskSelector() {
let view: NSView = NSView(frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin*2 + 30, width: self.frame.width, height: 29))
let view: NSView = NSView(frame: NSRect(
x: Constants.Settings.margin,
y: Constants.Settings.margin*2 + 30,
width: self.frame.width - Constants.Settings.margin*2,
height: 30
))
let rowTitle: NSTextField = LabelField(frame: NSRect(x: 0, y: (view.frame.height - 16)/2, width: view.frame.width - 52, height: 17), "Disk to show")
rowTitle.font = NSFont.systemFont(ofSize: 13, weight: .light)
rowTitle.textColor = .textColor
self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 140 - Constants.Settings.margin*2, y: -1, width: 140, height: 30))
self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 140, y: -1, width: 140, height: 30))
self.button!.target = self
self.button?.action = #selector(self.handleSelection)

View File

@@ -6,5 +6,55 @@
<string>GPU</string>
<key>State</key>
<true/>
<key>Widgets</key>
<dict>
<key>mini</key>
<dict>
<key>Default</key>
<true/>
<key>Preview</key>
<dict>
<key>Value</key>
<string>0.32</string>
</dict>
<key>Unsupported colors</key>
<array>
<string>pressure</string>
</array>
<key>Order</key>
<integer>0</integer>
</dict>
<key>line_chart</key>
<dict>
<key>Default</key>
<false/>
<key>Color</key>
<string>systemAccent</string>
<key>Unsupported colors</key>
<array>
<string>pressure</string>
</array>
<key>Order</key>
<integer>1</integer>
</dict>
<key>bar_chart</key>
<dict>
<key>Default</key>
<false/>
<key>Preview</key>
<dict>
<key>Value</key>
<string>0.36,0.28,0.32,0.26</string>
<key>Color</key>
<true/>
</dict>
<key>Unsupported colors</key>
<array>
<string>pressure</string>
</array>
<key>Order</key>
<integer>2</integer>
</dict>
</dict>
</dict>
</plist>

View File

@@ -13,33 +13,103 @@ import Cocoa
import ModuleKit
import StatsKit
public struct GPU_Load {}
public struct GPU_Info {
public let name: String
public let IOclass: String
public var state: Bool = false
public var utilization: Double = 0
public var totalVram: Int = 0
public var freeVram: Int = 0
public var coreClock: Int = 0
public var power: Int = 0
public var temperature: Int = 0
}
public struct GPUs: value_t {
public var list: [GPU_Info] = []
internal func active() -> [GPU_Info] {
return self.list.filter{ $0.state }
}
internal func igpu() -> GPU_Info? {
return self.active().first{ $0.IOclass == "IntelAccelerator" }
}
public var widget_value: Double {
get {
return list[0].utilization
}
}
}
public class GPU: Module {
private let smc: UnsafePointer<SMCService>?
private let store: UnsafePointer<Store>
private var loadReader: LoadReader? = nil
private var infoReader: InfoReader? = nil
private var settingsView: Settings
private var popupView: Popup = Popup()
private var selectedGPU: String = ""
public init(_ store: UnsafePointer<Store>, _ smc: UnsafePointer<SMCService>) {
self.store = store
self.smc = smc
self.settingsView = Settings("GPU", store: store)
super.init(
store: store,
popup: nil,
settings: nil
popup: self.popupView,
settings: self.settingsView
)
guard self.available else { return }
self.loadReader = LoadReader()
self.infoReader = InfoReader()
self.infoReader?.smc = smc
self.selectedGPU = store.pointee.string(key: "\(self.config.name)_gpu", defaultValue: self.selectedGPU)
self.loadReader?.readyCallback = { [unowned self] in
self.infoReader?.readyCallback = { [unowned self] in
self.readyHandler()
}
self.infoReader?.callbackHandler = { [unowned self] value in
self.infoCallback(value)
}
if let reader = self.loadReader {
self.settingsView.selectedGPUHandler = { [unowned self] value in
self.selectedGPU = value
self.infoReader?.read()
}
self.settingsView.setInterval = { [unowned self] value in
self.infoReader?.setInterval(value)
}
if let reader = self.infoReader {
self.addReader(reader)
}
}
private func infoCallback(_ value: GPUs?) {
guard value != nil else {
return
}
self.popupView.infoCallback(value!)
self.settingsView.setList(value!)
let activeGPU = value!.active()
let selectedGPU = activeGPU.first{ $0.name == self.selectedGPU } ?? value!.igpu() ?? value!.list[0]
if let widget = self.widget as? Mini {
widget.setValue(selectedGPU.utilization, sufix: "%")
}
if let widget = self.widget as? LineChart {
widget.setValue(selectedGPU.utilization)
}
if let widget = self.widget as? BarChart {
widget.setValue([selectedGPU.utilization])
}
}
}

32
Modules/GPU/popup.swift Normal file
View File

@@ -0,0 +1,32 @@
//
// popup.swift
// GPU
//
// Created by Serhiy Mytrovtsiy on 17/08/2020.
// Using Swift 5.0.
// Running on macOS 10.15.
//
// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
//
import Cocoa
import StatsKit
import ModuleKit
internal class Popup: NSView {
public init() {
super.init(frame: NSRect(x: 0, y: 0, width: Constants.Popup.width, height: 0))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
internal func infoCallback(_ value: GPUs) {
print(value)
}
}
private class GPUView: NSView {
}

View File

@@ -14,8 +14,94 @@ import StatsKit
import ModuleKit
import os.log
internal class LoadReader: Reader<GPU_Load> {
internal class InfoReader: Reader<GPUs> {
internal var smc: UnsafePointer<SMCService>? = nil
private var gpus: GPUs = GPUs()
public override func read() {
guard let devices = fetchIOService("IOPCIDevice") else {
return
}
let gpus = devices.filter{ $0.object(forKey: "IOName") as? String == "display" }
guard let acceletators = fetchIOService(kIOAcceleratorClassName) else {
return
}
acceletators.forEach { (accelerator: NSDictionary) in
guard let matchedGPU = gpus.first(where: { (gpu: NSDictionary) -> Bool in
guard let deviceID = gpu["device-id"] as? Data, let vendorID = gpu["vendor-id"] as? Data else {
return false
}
let pciMatch = "0x" + Data([deviceID[1], deviceID[0], vendorID[1], vendorID[0]]).map { String(format: "%02hhX", $0) }.joined()
let accMatch = accelerator["IOPCIMatch"] as? String ?? accelerator["IOPCIPrimaryMatch"] as? String ?? ""
return accMatch.range(of: pciMatch) != nil
}) else { return }
guard let agcInfo = accelerator["AGCInfo"] as? [String:Int] else {
return
}
guard let stats = accelerator["PerformanceStatistics"] as? [String:Any] else {
return
}
guard let model = matchedGPU.object(forKey: "model") as? Data else {
return
}
let modelName = String(data: model, encoding: .ascii)!.replacingOccurrences(of: "\0", with: "")
guard let IOClass = accelerator.object(forKey: "IOClass") as? String else {
return
}
if self.gpus.list.first(where: { $0.name == modelName }) == nil {
self.gpus.list.append(GPU_Info(name: modelName, IOclass: IOClass))
}
guard let idx = self.gpus.list.firstIndex(where: { $0.name == modelName }) else {
return
}
let utilization = stats["Device Utilization %"] as? Int ?? 0
let totalVram = accelerator["VRAM,totalMB"] as? Int ?? matchedGPU["VRAM,totalMB"] as? Int ?? 0
let freeVram = stats["vramFreeBytes"] as? Int ?? 0
let coreClock = stats["Core Clock(MHz)"] as? Int ?? 0
var power = stats["Total Power(W)"] as? Int ?? 0
var temperature = stats["Temperature(C)"] as? Int ?? 0
if IOClass == "IntelAccelerator" {
if temperature == 0 {
if let tmp = self.smc?.pointee.getValue("TCGC") {
temperature = Int(tmp)
} else if let tmp = self.smc?.pointee.getValue("TG0D") {
temperature = Int(tmp)
}
}
if power == 0 {
if let pwr = self.smc?.pointee.getValue("PCPG") {
power = Int(pwr)
} else if let pwr = self.smc?.pointee.getValue("PCGC") {
power = Int(pwr)
} else if let pwr = self.smc?.pointee.getValue("PCGM") {
power = Int(pwr)
}
}
}
self.gpus.list[idx].state = agcInfo["poweredOffByAGC"] == 0
self.gpus.list[idx].utilization = utilization == 0 ? 0 : Double(utilization)/100
self.gpus.list[idx].totalVram = totalVram
self.gpus.list[idx].freeVram = freeVram
self.gpus.list[idx].coreClock = coreClock
self.gpus.list[idx].power = power
self.gpus.list[idx].temperature = temperature
}
self.callback(self.gpus)
}
}

126
Modules/GPU/settings.swift Normal file
View File

@@ -0,0 +1,126 @@
//
// settings.swift
// GPU
//
// Created by Serhiy Mytrovtsiy on 17/08/2020.
// Using Swift 5.0.
// Running on macOS 10.15.
//
// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
//
import Cocoa
import StatsKit
import ModuleKit
internal class Settings: NSView, Settings_v {
private var updateIntervalValue: String = "1"
private let listOfUpdateIntervals: [String] = ["1", "2", "3", "5", "10", "15", "30"]
private var selectedGPU: String
private let title: String
private let store: UnsafePointer<Store>
public var selectedGPUHandler: (String) -> Void = {_ in }
public var callback: (() -> Void) = {}
public var setInterval: ((_ value: Double) -> Void) = {_ in }
private var hyperthreadView: NSView? = nil
private var button: NSPopUpButton?
public init(_ title: String, store: UnsafePointer<Store>) {
self.title = title
self.store = store
self.selectedGPU = store.pointee.string(key: "\(self.title)_gpu", defaultValue: "")
self.updateIntervalValue = store.pointee.string(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue)
super.init(frame: CGRect(
x: 0,
y: 0,
width: Constants.Settings.width - (Constants.Settings.margin*2),
height: 0
))
self.wantsLayer = true
self.canDrawConcurrently = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func load(widget: widget_t) {
self.subviews.forEach{ $0.removeFromSuperview() }
let rowHeight: CGFloat = 30
let num: CGFloat = 1
self.addSubview(SelectTitleRow(
frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin + (rowHeight + Constants.Settings.margin) * num, width: self.frame.width - (Constants.Settings.margin*2), height: rowHeight),
title: "Update interval",
action: #selector(changeUpdateInterval),
items: self.listOfUpdateIntervals.map{ "\($0) sec" },
selected: "\(self.updateIntervalValue) sec"
))
self.addGPUSelector()
self.setFrameSize(NSSize(width: self.frame.width, height: (rowHeight*(num+1)) + (Constants.Settings.margin*(2+num))))
}
private func addGPUSelector() {
let view: NSView = NSView(frame: NSRect(
x: Constants.Settings.margin,
y: Constants.Settings.margin,
width: self.frame.width - Constants.Settings.margin*2,
height: 30
))
let rowTitle: NSTextField = LabelField(frame: NSRect(x: 0, y: (view.frame.height - 16)/2, width: view.frame.width - 52, height: 17), "GPU to show")
rowTitle.font = NSFont.systemFont(ofSize: 13, weight: .light)
rowTitle.textColor = .textColor
self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 200, y: -1, width: 200, height: 30))
self.button!.target = self
self.button?.action = #selector(self.handleSelection)
view.addSubview(rowTitle)
view.addSubview(self.button!)
self.addSubview(view)
}
internal func setList(_ list: GPUs) {
let disks = list.active().map{ $0.name }
DispatchQueue.main.async(execute: {
if self.button?.itemTitles.count != disks.count {
self.button?.removeAllItems()
}
if disks != self.button?.itemTitles {
self.button?.addItems(withTitles: disks)
if self.selectedGPU != "" {
self.button?.selectItem(withTitle: self.selectedGPU)
}
}
})
}
@objc private func changeUpdateInterval(_ sender: NSMenuItem) {
let newUpdateInterval = sender.title.replacingOccurrences(of: " sec", with: "")
self.updateIntervalValue = newUpdateInterval
store.pointee.set(key: "\(self.title)_updateInterval", value: self.updateIntervalValue)
if let value = Double(self.updateIntervalValue) {
self.setInterval(value)
}
}
@objc private func handleSelection(_ sender: NSPopUpButton) {
guard let item = sender.selectedItem else { return }
self.selectedGPU = item.title
self.store.pointee.set(key: "\(self.title)_gpu", value: item.title)
self.selectedGPUHandler(item.title)
}
}

View File

@@ -58,13 +58,13 @@ internal class Settings: NSView, Settings_v {
}
private func addNetworkSelector() {
let view: NSView = NSView(frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin, width: self.frame.width, height: 29))
let view: NSView = NSView(frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin, width: self.frame.width, height: 30))
let rowTitle: NSTextField = LabelField(frame: NSRect(x: 0, y: (view.frame.height - 16)/2, width: view.frame.width - 52, height: 17), "Network interface")
rowTitle.font = NSFont.systemFont(ofSize: 13, weight: .light)
rowTitle.textColor = .textColor
self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 200 - Constants.Settings.margin*2, y: -1, width: 200, height: 30))
self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 200 - Constants.Settings.margin*2, y: 0, width: 200, height: 30))
self.button!.target = self
self.button?.action = #selector(self.handleSelection)

View File

@@ -104,7 +104,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "Th3H", name: "Heatpipe 4", group: SensorGroup.Sensor.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TZ0C", name: "Termal zone 1", group: SensorGroup.Sensor.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TZ1C", name: "Termal zone 2", group: SensorGroup.Sensor.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC0E", name: "CPU 1", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC0F", name: "CPU 2", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC0D", name: "CPU die", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
@@ -112,7 +112,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "TC0H", name: "CPU heatsink", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC0P", name: "CPU proximity", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TCAD", name: "CPU package", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC0c", name: "CPU core 1", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC1c", name: "CPU core 2", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC2c", name: "CPU core 3", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
@@ -129,12 +129,12 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "TC13c", name: "CPU core 14", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC14c", name: "CPU core 15", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC15c", name: "CPU core 16", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TCGC", name: "GPU Intel Graphics", group: SensorGroup.GPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TG0D", name: "GPU die", group: SensorGroup.GPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TG0H", name: "GPU heatsink", group: SensorGroup.GPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TG0P", name: "GPU proximity", group: SensorGroup.GPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "Tm0P", name: "Mainboard", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "Tp0P", name: "Powerboard", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TB1T", name: "Battery", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
@@ -144,11 +144,11 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "TI1P", name: "Thunderbold 2", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TI2P", name: "Thunderbold 3", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TI3P", name: "Thunderbold 4", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TN0D", name: "Northbridge die", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TN0H", name: "Northbridge heatsink", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TN0P", name: "Northbridge proximity", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
/// Voltage
Sensor_t(key: "VCAC", name: "CPU IA", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VCSC", name: "CPU System Agent", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
@@ -168,13 +168,13 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "VC13C", name: "CPU Core 14", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VC14C", name: "CPU Core 15", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VC15C", name: "CPU Core 16", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VCTC", name: "GPU Intel Graphics", group: SensorGroup.GPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VG0C", name: "GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VM0R", name: "Memory", group: SensorGroup.System.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "Vb0R", name: "CMOS", group: SensorGroup.System.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VD0R", name: "DC In", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VP0R", name: "12V rail", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "Vp0C", name: "12V vcc", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
@@ -183,7 +183,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "VV1S", name: "5V", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VV9S", name: "12V", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VeES", name: "PCI 12V", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
/// Power
Sensor_t(key: "PC0C", name: "CPU Core", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PCAM", name: "CPU Core (IMON)", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
@@ -193,7 +193,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "PCPR", name: "CPU Package total (SMC)", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PC0R", name: "CPU Computing high side", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PC0G", name: "CPU GFX", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PCPG", name: "GPU Intel Graphics", group: SensorGroup.GPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PG0R", name: "GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PCGC", name: "Intel GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Power.rawValue),
@@ -203,7 +203,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "PPBR", name: "Battery", group: SensorGroup.Sensor.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PDTR", name: "DC In", group: SensorGroup.Sensor.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PSTR", name: "System total", group: SensorGroup.Sensor.rawValue, type: SensorType.Power.rawValue),
/// Frequency
Sensor_t(key: "FRC0", name: "CPU 1", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "FRC1", name: "CPU 2", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
@@ -221,11 +221,11 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "FRC13", name: "CPU 14", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "FRC14", name: "CPU 15", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "FRC15", name: "CPU 16", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "CG0C", name: "GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "CG0S", name: "GPU shader", group: SensorGroup.GPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "CG0M", name: "GPU memory", group: SensorGroup.GPU.rawValue, type: SensorType.Frequency.rawValue),
/// Battery
Sensor_t(key: "B0AV", name: "Voltage", group: SensorGroup.Sensor.rawValue, type: SensorType.Battery.rawValue),
Sensor_t(key: "B0AC", name: "Amperage", group: SensorGroup.Sensor.rawValue, type: SensorType.Battery.rawValue),

View File

@@ -37,6 +37,8 @@
9A3E17E8247AA8E100449CD1 /* Speed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A3E17E7247AA8E100449CD1 /* Speed.swift */; };
9A3E17EA247B07BF00449CD1 /* popup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A3E17E9247B07BF00449CD1 /* popup.swift */; };
9A41530C24ABC3AF00A2BDA7 /* Memory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A41530B24ABC3AF00A2BDA7 /* Memory.swift */; };
9A53EBF924EAFA5200648841 /* settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A53EBF824EAFA5200648841 /* settings.swift */; };
9A53EBFB24EB041E00648841 /* popup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A53EBFA24EB041E00648841 /* popup.swift */; };
9A58DE9E24B363D800716A9F /* popup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58DE9D24B363D800716A9F /* popup.swift */; };
9A58DEA024B363F300716A9F /* settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58DE9F24B363F300716A9F /* settings.swift */; };
9A58DEA424B3647600716A9F /* settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58DEA324B3647600716A9F /* settings.swift */; };
@@ -462,6 +464,8 @@
9A3E17E9247B07BF00449CD1 /* popup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = popup.swift; sourceTree = "<group>"; };
9A41530B24ABC3AF00A2BDA7 /* Memory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Memory.swift; sourceTree = "<group>"; };
9A5349CD23D8832E00C23824 /* Reachability.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Reachability.framework; path = Carthage/Build/Mac/Reachability.framework; sourceTree = "<group>"; };
9A53EBF824EAFA5200648841 /* settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = settings.swift; sourceTree = "<group>"; };
9A53EBFA24EB041E00648841 /* popup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = popup.swift; sourceTree = "<group>"; };
9A58DE9D24B363D800716A9F /* popup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = popup.swift; sourceTree = "<group>"; };
9A58DE9F24B363F300716A9F /* settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = settings.swift; sourceTree = "<group>"; };
9A58DEA324B3647600716A9F /* settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = settings.swift; sourceTree = "<group>"; };
@@ -777,6 +781,8 @@
children = (
9A90E19524EAD35F00471E9A /* main.swift */,
9A90E1A224EAD66600471E9A /* reader.swift */,
9A53EBF824EAFA5200648841 /* settings.swift */,
9A53EBFA24EB041E00648841 /* popup.swift */,
9A90E18C24EAD2BB00471E9A /* Info.plist */,
9A90E19724EAD3B000471E9A /* config.plist */,
);
@@ -1435,6 +1441,8 @@
files = (
9A90E1A324EAD66600471E9A /* reader.swift in Sources */,
9A90E19624EAD35F00471E9A /* main.swift in Sources */,
9A53EBFB24EB041E00648841 /* popup.swift in Sources */,
9A53EBF924EAFA5200648841 /* settings.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -382,4 +382,5 @@ let osDict: [Int: String] = [
13: "High Sierra",
14: "Mojave",
15: "Catalina",
16: "Big Sur",
]

View File

@@ -876,6 +876,26 @@ public func getIOParent(_ obj: io_registry_entry_t) -> io_registry_entry_t? {
return parent
}
public func fetchIOService(_ name: String) -> [NSDictionary]? {
var iterator: io_iterator_t = io_iterator_t()
var obj: io_registry_entry_t = 1
var list: [NSDictionary] = []
let result = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(name), &iterator)
if result == kIOReturnSuccess {
while obj != 0 {
obj = IOIteratorNext(iterator)
if let props = getIOProperties(obj) {
list.append(props)
}
IOObjectRelease(obj)
}
IOObjectRelease(iterator)
}
return list.isEmpty ? nil : list
}
public func getIOProperties(_ entry: io_registry_entry_t) -> NSDictionary? {
var properties: Unmanaged<CFMutableDictionary>? = nil