Adjust Mac OS X display brightness from the Terminal
by Matt Danger on December 17, 2008
One of the classrooms I maintain is comprised of 2.4Ghz iMacs (MB323LL/A) that are dual booted with Windows XP and Mac OS X. Sometimes when the workstations are restarted from XP to OS X the display brightness gets changed to its dim power saver setting. This requires the user manually increase the display brightness by pressing the F2 key, which is inconvenient. I haven’t been able to determine the cause of this issue so I wanted to create a login hook to increases the brightness as a temporary fix.
OS X doesn’t ship with a command line utility that let’s you change display brightness. Fortunately, Nicholas Riley has written a utility that uses OS X frameworks to accomplish this quickly and easily. Here’s the code:
#include <stdio.h> #include <unistd.h> #include <IOKit/graphics/IOGraphicsLib.h> #include <ApplicationServices/ApplicationServices.h> const int kMaxDisplays = 16; const CFStringRef kDisplayBrightness = CFSTR(kIODisplayBrightnessKey); const char *APP_NAME; void errexit(const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s: ", APP_NAME); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); exit(1); } void usage() { fprintf(stderr, "usage: %s [-m|-d display] [-v] <brightness>\n", APP_NAME); fprintf(stderr, " or: %s -l [-v]\n", APP_NAME); exit(1); } int main(int argc, char * const argv[]) { APP_NAME = argv[0]; if (argc == 1) usage(); int verbose = 0; unsigned long displayToSet = 0; enum { ACTION_LIST, ACTION_SET_ALL, ACTION_SET_ONE } action = ACTION_SET_ALL; extern char *optarg; extern int optind; int ch; while ( (ch = getopt(argc, argv, "lmvd:")) != -1) { switch (ch) { case 'l': if (action == ACTION_SET_ONE) usage(); action = ACTION_LIST; break; case 'v': verbose = 1; break; case 'm': if (action != ACTION_SET_ALL) usage(); action = ACTION_SET_ONE; displayToSet = (unsigned long)CGMainDisplayID(); break; case 'd': if (action != ACTION_SET_ALL) usage(); action = ACTION_SET_ONE; errno = 0; displayToSet = strtoul(optarg, NULL, 0); if (errno == EINVAL || errno == ERANGE) errexit("display must be an integer index (0) or a hexadecimal ID (0x4270a80)"); break; default: usage(); } } argc -= optind; argv += optind; float brightness; if (action == ACTION_LIST) { if (argc > 0) usage(); } else { if (argc != 1) usage(); errno = 0; brightness = strtof(argv[0], NULL); if (errno == ERANGE) usage(); if (brightness < 0 || brightness > 1) errexit("brightness must be between 0 and 1"); } CGDirectDisplayID display[kMaxDisplays]; CGDisplayCount numDisplays; CGDisplayErr err; err = CGGetActiveDisplayList(kMaxDisplays, display, &numDisplays); if (err != CGDisplayNoErr) errexit("cannot get list of displays (error %d)\n", err); CFWriteStreamRef stdoutStream = NULL; if (verbose) { CFURLRef devStdout = CFURLCreateWithFileSystemPath(NULL, CFSTR("/dev/stdout"), kCFURLPOSIXPathStyle, false); stdoutStream = CFWriteStreamCreateWithFile(NULL, devStdout); if (stdoutStream == NULL) errexit("cannot create CFWriteStream for /dev/stdout"); if (!CFWriteStreamOpen(stdoutStream)) errexit("cannot open CFWriteStream for /dev/stdout"); } for (CGDisplayCount i = 0; i < numDisplays; ++i) { CGDirectDisplayID dspy = display[i]; CFDictionaryRef originalMode = CGDisplayCurrentMode(dspy); if (originalMode == NULL) continue; if (action == ACTION_LIST) { printf("display %d: ", i); if (CGMainDisplayID() == dspy) printf("main display, "); printf("ID 0x%x\n", (unsigned int)dspy); if (verbose) { CFStringRef error = NULL; CFPropertyListWriteToStream(originalMode, stdoutStream, kCFPropertyListXMLFormat_v1_0, &error); if (error != NULL) errexit("failed to write display info (%s)", CFStringGetCStringPtr(error, CFStringGetFastestEncoding(error))); } } io_service_t service = CGDisplayIOServicePort(dspy); switch (action) { case ACTION_SET_ONE: if ((CGDirectDisplayID)displayToSet != dspy && displayToSet != i) continue; case ACTION_SET_ALL: err = IODisplaySetFloatParameter(service, kNilOptions, kDisplayBrightness, brightness); if (err != kIOReturnSuccess) { fprintf(stderr, "%s: failed to set brightness of display 0x%x (error %d)", APP_NAME, (unsigned int)dspy, err); continue; } if (!verbose) continue; case ACTION_LIST: err = IODisplayGetFloatParameter(service, kNilOptions, kDisplayBrightness, &brightness); if (err != kIOReturnSuccess) { fprintf(stderr, "%s: failed to get brightness of display 0x%x (error %d)", APP_NAME, (unsigned int)dspy, err); continue; } printf("display %d: brightness %f\n", i, brightness); } } return 0; }
You can compile your own utility by saving this code to a file named brightness.c and doing:
gcc -std=c99 -o brightness brightness.c -framework IOKit -framework ApplicationServices
You can also download the precompiled binary.
You can create a login hook to automatically increase the brightness by chmoding the downloaded ‘brightness’ file to 755 and running the following command as root in Terminal:
defaults write com.apple.loginwindow LoginHook "/path/to/brightness 1"
January 29th, 2009 on 5:35 am
[...] I think* it may have something to do with Workgroup Manager, but here’s a little trick from Matt Danger that might solve the problem. I’m going to try it later this [...]
August 17th, 2009 on 3:07 pm
[...] a C program to adjust the screen’s brightness written by Nicholas Riley, also available from this blog post by Matt (Danger) West. Get it. The rest is obvious. For instance, here’s a Python script, which should have [...]
September 14th, 2009 on 9:47 am
[...] This blog post discusses has a small commandline tool (written by Nicholas Riley) to set the brightness from Terminal. Just download the binary [4KB] and install it. You can then set the brightness by typing brightness 0 (to set it to minimum, use 1 for maximum, or any value between). [...]
September 14th, 2009 on 10:39 am
[...] This blog post discusses has a small commandline tool (written by Nicholas Riley) to set the brightness from Terminal. Just download the binary [4KB] and install it. You can then set the brightness by typing brightness 0 (to set it to minimum, use 1 for maximum, or any value between). [...]
September 14th, 2009 on 10:46 am
[...] This blog post discusses has a small commandline tool (written by Nicholas Riley) to set the brightness from Terminal. Just download the binary [4KB] and install it. You can then set the brightness by typing brightness 0 (to set it to minimum, use 1 for maximum, or any value between). Note: The binary is Intel-Only (32-Bit), but the source code is available on the above linked page too, so you could easily compile a PowerPC or 64Bit Intel Binary on your own. … [...]
September 14th, 2009 on 2:28 pm
[...] This blog post discusses has a small commandline tool (written by Nicholas Riley) to set the brightness from Terminal. Just download the binary [4KB] and install it. You can then set the brightness by typing brightness 0 (to set it to minimum, use 1 for maximum, or any value between). [...]
September 28th, 2009 on 6:37 pm
[...] screen brightness from the command line. It’s precompiled but the source code is available here if you are interested to see it. Once you have the precompiled binary in your path, just type [...]
April 18th, 2010 on 4:17 pm
[...] This handy utility will allow you to adjust the display (screen) brightness from the command line. [...]