source: trunk/LocationDo/brightness.c @ 396

Last change on this file since 396 was 236, checked in by Nicholas Riley, 14 years ago

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

File size: 4.2 KB
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
8const int kMaxDisplays = 16;
9const CFStringRef kDisplayBrightness = CFSTR(kIODisplayBrightnessKey);
10const char *APP_NAME;
11
12void 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
21void 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
27int 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 repository browser.