root/trunk/LocationDo/brightness.c

Revision 236, 4.2 kB (checked in by nicholas, 2 years ago)

brightness.c: new hot-er, um, brightness

Line 
1 /* gcc -std=c99 -o brightness brightness.c -framework IOKit -framework ApplicationServices */
2
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <IOKit/graphics/IOGraphicsLib.h>
6 #include <ApplicationServices/ApplicationServices.h>
7
8 const int kMaxDisplays = 16;
9 const CFStringRef kDisplayBrightness = CFSTR(kIODisplayBrightnessKey);
10 const char *APP_NAME;
11
12 void errexit(const char *fmt, ...) {
13   va_list ap;
14   va_start(ap, fmt);
15   fprintf(stderr, "%s: ", APP_NAME);
16   vfprintf(stderr, fmt, ap);
17   fprintf(stderr, "\n");
18   exit(1);
19 }
20
21 void usage() {
22   fprintf(stderr, "usage: %s [-m|-d display] [-v] <brightness>\n", APP_NAME);
23   fprintf(stderr, "   or: %s -l [-v]\n", APP_NAME);
24   exit(1);
25 }
26
27 int main(int argc, char * const argv[]) {
28   APP_NAME = argv[0];
29   if (argc == 1)
30     usage();
31
32   int verbose = 0;
33   unsigned long displayToSet = 0;
34   enum { ACTION_LIST, ACTION_SET_ALL, ACTION_SET_ONE } action = ACTION_SET_ALL;
35   extern char *optarg;
36   extern int optind;
37   int ch;
38
39   while ( (ch = getopt(argc, argv, "lmvd:")) != -1) {
40     switch (ch) {
41     case 'l':
42       if (action == ACTION_SET_ONE) usage();
43       action = ACTION_LIST;
44       break;
45     case 'v':
46       verbose = 1;
47       break;
48     case 'm':
49       if (action != ACTION_SET_ALL) usage();
50       action = ACTION_SET_ONE;
51       displayToSet = (unsigned long)CGMainDisplayID();
52       break;
53     case 'd':
54       if (action != ACTION_SET_ALL) usage();
55       action = ACTION_SET_ONE;
56       errno = 0;
57       displayToSet = strtoul(optarg, NULL, 0);
58       if (errno == EINVAL || errno == ERANGE)
59         errexit("display must be an integer index (0) or a hexadecimal ID (0x4270a80)");
60       break;
61     default: usage();
62     }
63   }
64  
65   argc -= optind;
66   argv += optind;
67
68   float brightness;
69   if (action == ACTION_LIST) {
70     if (argc > 0) usage();
71   } else {
72     if (argc != 1) usage();
73
74     errno = 0;
75     brightness = strtof(argv[0], NULL);
76     if (errno == ERANGE)
77       usage();
78     if (brightness < 0 || brightness > 1)
79       errexit("brightness must be between 0 and 1");
80   }
81
82   CGDirectDisplayID display[kMaxDisplays];
83   CGDisplayCount numDisplays;
84   CGDisplayErr err;
85   err = CGGetActiveDisplayList(kMaxDisplays, display, &numDisplays);
86   if (err != CGDisplayNoErr)
87     errexit("cannot get list of displays (error %d)\n", err);
88
89   CFWriteStreamRef stdoutStream = NULL;
90   if (verbose) {
91     CFURLRef devStdout =
92       CFURLCreateWithFileSystemPath(NULL, CFSTR("/dev/stdout"),
93                                     kCFURLPOSIXPathStyle, false);
94     stdoutStream = CFWriteStreamCreateWithFile(NULL, devStdout);
95     if (stdoutStream == NULL)
96       errexit("cannot create CFWriteStream for /dev/stdout");
97     if (!CFWriteStreamOpen(stdoutStream))
98       errexit("cannot open CFWriteStream for /dev/stdout");
99   }                                                               
100
101   for (CGDisplayCount i = 0; i < numDisplays; ++i) {
102     CGDirectDisplayID dspy = display[i];
103     CFDictionaryRef originalMode = CGDisplayCurrentMode(dspy);
104     if (originalMode == NULL)
105       continue;
106
107     if (action == ACTION_LIST) {
108       printf("display %d: ", i);
109       if (CGMainDisplayID() == dspy)
110         printf("main display, ");
111       printf("ID 0x%x\n", (unsigned int)dspy);
112       if (verbose) {
113         CFStringRef error = NULL;
114         CFPropertyListWriteToStream(originalMode, stdoutStream,
115                                     kCFPropertyListXMLFormat_v1_0, &error);
116         if (error != NULL)
117           errexit("failed to write display info (%s)",
118                   CFStringGetCStringPtr(error,
119                                         CFStringGetFastestEncoding(error)));
120       }
121     }
122
123     io_service_t service = CGDisplayIOServicePort(dspy);
124     switch (action) {
125     case ACTION_SET_ONE:
126       if ((CGDirectDisplayID)displayToSet != dspy && displayToSet != i)
127         continue;
128     case ACTION_SET_ALL:
129       err = IODisplaySetFloatParameter(service, kNilOptions, kDisplayBrightness,
130                                        brightness);
131       if (err != kIOReturnSuccess) {
132         fprintf(stderr,
133                 "%s: failed to set brightness of display 0x%x (error %d)",
134                 APP_NAME, (unsigned int)dspy, err);
135         continue;
136       }
137       if (!verbose) continue;
138     case ACTION_LIST:
139       err = IODisplayGetFloatParameter(service, kNilOptions, kDisplayBrightness,
140                                        &brightness);
141       if (err != kIOReturnSuccess) {
142         fprintf(stderr,
143                 "%s: failed to get brightness of display 0x%x (error %d)",
144                 APP_NAME, (unsigned int)dspy, err);
145         continue;
146       }
147       printf("display %d: brightness %f\n", i, brightness);
148     }
149   }
150
151   return 0;
152 }
Note: See TracBrowser for help on using the browser.