forked from MonitorControl/MonitorControl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInternalDisplay.swift
More file actions
85 lines (76 loc) · 4.17 KB
/
InternalDisplay.swift
File metadata and controls
85 lines (76 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//
// InternalDisplay.swift
// MonitorControl
//
// Created by Joni Van Roost on 24/01/2020.
// Copyright © 2020 Guillaume Broder. All rights reserved.
//
// Most of the code in this file was sourced from:
// https://github.com/fnesveda/ExternalDisplayBrightness
// all credit goes to @fnesveda
import Foundation
class InternalDisplay: Display {
// the queue for dispatching display operations, so they're not performed directly and concurrently
private var displayQueue: DispatchQueue
override init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?) {
self.displayQueue = DispatchQueue(label: String("displayQueue-\(identifier)"))
super.init(identifier, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber)
}
func calcNewBrightness(isUp: Bool, isSmallIncrement: Bool) -> Float {
var step: Float = (isUp ? 1 : -1) / 16.0
let delta = step / 4
if isSmallIncrement {
step = delta
}
return min(max(0, ceil((self.getBrightness() + delta) / step) * step), 1)
}
public func getBrightness() -> Float {
self.displayQueue.sync {
Float(type(of: self).CoreDisplayGetUserBrightness?(self.identifier) ?? 0.5)
}
}
override func stepBrightness(isUp: Bool, isSmallIncrement: Bool) {
let value = self.calcNewBrightness(isUp: isUp, isSmallIncrement: isSmallIncrement)
self.displayQueue.sync {
type(of: self).CoreDisplaySetUserBrightness?(self.identifier, Double(value))
type(of: self).DisplayServicesBrightnessChanged?(self.identifier, Double(value))
self.showOsd(command: .brightness, value: Int(value * 64), maxValue: 64)
}
}
// notifies the system that the brightness of a specified display has changed (to update System Preferences etc.)
// unfortunately Apple doesn't provide a public API for this, so we have to manually extract the function from the DisplayServices framework
private static var DisplayServicesBrightnessChanged: ((CGDirectDisplayID, Double) -> Void)? {
let displayServicesPath = CFURLCreateWithString(kCFAllocatorDefault, "/System/Library/PrivateFrameworks/DisplayServices.framework" as CFString, nil)
if let displayServicesBundle = CFBundleCreate(kCFAllocatorDefault, displayServicesPath) {
if let funcPointer = CFBundleGetFunctionPointerForName(displayServicesBundle, "DisplayServicesBrightnessChanged" as CFString) {
typealias DSBCFunctionType = @convention(c) (UInt32, Double) -> Void
return unsafeBitCast(funcPointer, to: DSBCFunctionType.self)
}
}
return nil
}
// reads the brightness of a display through the CoreDisplay framework
// unfortunately Apple doesn't provide a public API for this, so we have to manually extract the function from the CoreDisplay framework
private static var CoreDisplayGetUserBrightness: ((CGDirectDisplayID) -> Double)? {
let coreDisplayPath = CFURLCreateWithString(kCFAllocatorDefault, "/System/Library/Frameworks/CoreDisplay.framework" as CFString, nil)
if let coreDisplayBundle = CFBundleCreate(kCFAllocatorDefault, coreDisplayPath) {
if let funcPointer = CFBundleGetFunctionPointerForName(coreDisplayBundle, "CoreDisplay_Display_GetUserBrightness" as CFString) {
typealias CDGUBFunctionType = @convention(c) (UInt32) -> Double
return unsafeBitCast(funcPointer, to: CDGUBFunctionType.self)
}
}
return nil
}
// sets the brightness of a display through the CoreDisplay framework
// unfortunately Apple doesn't provide a public API for this, so we have to manually extract the function from the CoreDisplay framework
private static var CoreDisplaySetUserBrightness: ((CGDirectDisplayID, Double) -> Void)? {
let coreDisplayPath = CFURLCreateWithString(kCFAllocatorDefault, "/System/Library/Frameworks/CoreDisplay.framework" as CFString, nil)
if let coreDisplayBundle = CFBundleCreate(kCFAllocatorDefault, coreDisplayPath) {
if let funcPointer = CFBundleGetFunctionPointerForName(coreDisplayBundle, "CoreDisplay_Display_SetUserBrightness" as CFString) {
typealias CDSUBFunctionType = @convention(c) (UInt32, Double) -> Void
return unsafeBitCast(funcPointer, to: CDSUBFunctionType.self)
}
}
return nil
}
}