CapsLockToggler // Fix a memory-leak issue.

This commit is contained in:
ShikiSuen 2023-11-01 11:58:15 +08:00
parent 3fbb0b418f
commit 6417c0193e
1 changed files with 45 additions and 17 deletions

View File

@ -7,30 +7,58 @@ import CapsLockToggler
public enum CapsLockToggler {
public static func toggle() {
let ioService: io_service_t = IOServiceGetMatchingService(0, IOServiceMatching(kIOHIDSystemClass))
var ioConnect: io_connect_t = 0
IOServiceOpen(ioService, mach_task_self_, UInt32(kIOHIDParamConnectType), &ioConnect)
var state = false
IOHIDGetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), &state)
state.toggle()
IOHIDSetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), state)
IOServiceClose(ioConnect)
try? IOKit.handleHIDSystemService { ioConnect in
var state = false
IOHIDGetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), &state)
state.toggle()
IOHIDSetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), state)
}
}
public static var isOn: Bool {
let ioService: io_service_t = IOServiceGetMatchingService(0, IOServiceMatching(kIOHIDSystemClass))
var ioConnect: io_connect_t = 0
IOServiceOpen(ioService, mach_task_self_, UInt32(kIOHIDParamConnectType), &ioConnect)
var state = false
IOHIDGetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), &state)
try? IOKit.handleHIDSystemService { ioConnect in
IOHIDGetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), &state)
}
return state
}
public static func turnOff() {
let ioService: io_service_t = IOServiceGetMatchingService(0, IOServiceMatching(kIOHIDSystemClass))
var ioConnect: io_connect_t = 0
IOServiceOpen(ioService, mach_task_self_, UInt32(kIOHIDParamConnectType), &ioConnect)
IOHIDSetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), false)
IOServiceClose(ioConnect)
try? IOKit.handleHIDSystemService { ioConnect in
IOHIDSetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), false)
}
}
}
// Refactored by Shiki Suen (MIT License)
public enum IOKit {
public static func handleHIDSystemService(_ taskHandler: @escaping (io_connect_t) -> Void) throws {
let ioService: io_service_t = IOServiceGetMatchingService(0, IOServiceMatching(kIOHIDSystemClass))
var connect: io_connect_t = 0
let x = IOServiceOpen(ioService, mach_task_self_, UInt32(kIOHIDParamConnectType), &connect)
if let errorOne = Mach.KernReturn(rawValue: x), errorOne != .success {
throw errorOne
}
taskHandler(connect)
let y = IOServiceClose(connect)
if let errorTwo = Mach.KernReturn(rawValue: y), errorTwo != .success {
throw errorTwo
}
}
}
// Refactored by Shiki Suen (MIT License)
public enum Mach {
public enum KernReturn: Int32, Error {
case success = 0
case invalidAddress = 1
case protectionFailure = 2
case noSpace = 3
case invalidArgument = 4
case failure = 5
case resourceShortage = 6
case notReceiver = 7
case noAccess = 8
case memoryFailure = 9
}
}