-
Notifications
You must be signed in to change notification settings - Fork 1
/
brightness.c
176 lines (149 loc) · 5.2 KB
/
brightness.c
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/* brightness.c - set brightness of display and keyboard backlights in OSX
*
* Can be used to set the brightness of the backlights well below the minimum
* level permitted by the normal function keys. This is especially useful for
* e.g. setting the keybaord backlight at night (0.01 is a suggested value).
*
*
* Building:
* gcc -o brightness brightness.c -framework IOKit \
-framework ApplicationServices -framework CoreFoundation
*
* Note: works on 64-bit machines only, due to use of IOConnectCallScalarMethod
*
* Inspired by:
* https://github.com/stevedekorte/io/blob/master/addons/AppleExtras
* http://www.osxbook.com/book/bonus/chapter10/light/
*
*/
#include <stdio.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <ApplicationServices/ApplicationServices.h>
#include <IOKit/IOKitLib.h>
#define PROGNAME "brightness"
static io_connect_t dataPort = 0;
enum {
kGetSensorReadingID = 0, // getSensorReading(int *, int *)
kGetLEDBrightnessID = 1, // getLEDBrightness(int, int *)
kSetLEDBrightnessID = 2, // setLEDBrightness(int, int, int *)
kSetLEDFadeID = 3, // setLEDFade(int, int, int, int *)
};
void usage(void) {
fprintf(stderr, "usage: %s <brightness>\n" " where 0.0 <= brightness <= 1.0\n", PROGNAME);
exit(1);
}
io_connect_t getDataPort(void) {
kern_return_t kr;
io_service_t serviceObject;
if (dataPort) return dataPort;
// Look up a registered IOService object whose class is AppleLMUController
serviceObject = IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching("AppleLMUController"));
if (!serviceObject) {
printf("getDataPort() error: failed to find ambient light sensor\n");
return 0;
}
// Create a connection to the IOService object
kr = IOServiceOpen(serviceObject, mach_task_self(), 0, &dataPort);
IOObjectRelease(serviceObject);
if (kr != KERN_SUCCESS) {
printf("getDataPort() error: failed to open IoService object\n");
return 0;
}
return dataPort;
}
void setKeyboardBrightness(float in) {
// static io_connect_t dp = 0; // shared?
kern_return_t kr;
uint64_t inputCount = 2;
uint64_t inputValues[2];
uint64_t in_unknown = 0;
uint64_t in_brightness = in * 0xfff;
inputValues[0] = in_unknown;
inputValues[1] = in_brightness;
uint32_t outputCount = 1;
uint64_t outputValues[1];
uint32_t out_brightness;
kr = IOConnectCallScalarMethod(getDataPort(), kSetLEDBrightnessID,
inputValues, inputCount, outputValues, &outputCount);
out_brightness = outputValues[0];
if (kr != KERN_SUCCESS) {
printf("setKeyboardBrightness() error\n");
return;
} else {
printf("keyboard brightness is %f\n", in);
}
}
/**
* Workaround for deprecation of CGDisplayIOServicePort. Return io_service_t
* for a given display id, or NULL on failure.
*/
static io_service_t IOServicePortForCGDisplayID(CGDirectDisplayID displayID)
{
io_iterator_t iter;
io_service_t serv, servicePort = 0;
CFMutableDictionaryRef matching = IOServiceMatching("IODisplayConnect");
kern_return_t err = IOServiceGetMatchingServices(kIOMasterPortDefault,
matching, &iter);
if (err) {
return 0;
}
while ((serv = IOIteratorNext(iter)) != 0) {
CFDictionaryRef info;
CFIndex vendorID, productID;
CFNumberRef vendorIDRef, productIDRef;
Boolean success;
info = IODisplayCreateInfoDictionary(serv, kIODisplayOnlyPreferredName);
vendorIDRef = CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
productIDRef = CFDictionaryGetValue(info, CFSTR(kDisplayProductID));
success = CFNumberGetValue(vendorIDRef, kCFNumberCFIndexType, &vendorID);
success &= CFNumberGetValue(productIDRef, kCFNumberCFIndexType, &productID);
if (!success) {
CFRelease(info);
continue;
}
if (CGDisplayVendorNumber(displayID) != vendorID ||
CGDisplayModelNumber(displayID) != productID) {
CFRelease(info);
continue;
}
servicePort = serv;
CFRelease(info);
break;
}
IOObjectRelease(iter);
return servicePort;
}
int main(int argc, char **argv) {
CGDisplayErr dErr;
io_service_t service;
CGDirectDisplayID targetDisplay;
CFStringRef key = CFSTR(kIODisplayBrightnessKey);
float brightness = HUGE_VALF;
switch (argc) {
case 1:
break;
case 2:
brightness = strtof(argv[1], NULL);
break;
default:
usage();
break;
}
targetDisplay = CGMainDisplayID();
service = IOServicePortForCGDisplayID(targetDisplay);
if (brightness != HUGE_VALF) {
// set the display brightness, if requested
dErr = IODisplaySetFloatParameter(service, kNilOptions, key, brightness);
//set keyboard brightness
setKeyboardBrightness(brightness);
}
// now get the brightness
dErr = IODisplayGetFloatParameter(service, kNilOptions, key, &brightness);
if (dErr != kIOReturnSuccess) {
fprintf(stderr, "operation failed\n");
} else {
printf("brightness of main display is %f\n", brightness);
}
exit(dErr);
}