···11-.Dd $Mdocdate: December 8 2015$
11+.Dd $Mdocdate: July 25 2016$
22.Dt XDIMMER 1
33.Os
44.Sh NAME
55.Nm xdimmer
66-.Nd dim the screen when idle
66+.Nd dim the screen (and possibly the keyboard) backlight when idle
77.Sh SYNOPSIS
88.Nm
99.Op Fl d
1010+.Op Fl k
1011.Op Fl p Ar percent
1112.Op Fl s Ar steps
1213.Op Fl t Ar timeout
···1516waits
1617.Ar timeout
1718number of seconds and if no keyboard or mouse input is detected, the screen
1818-is dimmed to
1919+backlight is dimmed to
1920.Ar percent
2021in
2122.Ar steps
2223steps.
2323-Once keyboard or mouse input is detected, the screen is restored to its
2424-previous brightness value.
2424+Once keyboard or mouse input is detected, the screen backlight is restored
2525+to its previous brightness value.
2626+.Pp
2727+On OpenBSD, if the
2828+.Ar -k
2929+option is used, the keyboard backlight is also dimmed and restored via the
3030+.Xr wscons 4
3131+interface.
2532.Sh OPTIONS
2633.Bl -tag -width Ds
2734.It Fl d
2835Print debugging messages to stdout.
3636+.It Fl k
3737+Affect the keyboard backlight as well as the screen backlight.
3838+Currently only supported on OpenBSD.
2939.It Fl p Ar percent
3030-Absolute brightness value to which the screen is dimmed.
4040+Absolute brightness value to which the backlight is dimmed.
3141The default is
3242.Dv 10
3343percent.
3444.It Fl t Ar steps
3535-Number of steps to take while decrementing screen brightness.
4545+Number of steps to take while decrementing backlight.
3646The default is
3747.Dv 20
3848steps.
3949.It Fl t Ar timeout
4040-Number of seconds to wait without receiving input before dimming screen.
5050+Number of seconds to wait without receiving input before dimming.
4151The default is
4252.Dv 120
4353seconds.
+85-16
xdimmer.c
···6363void dim(void);
6464void brighten(void);
6565void bail(int);
6666-void stepper(int, double, int);
6666+void stepper(int, double, double, int);
6767double backlight_op(int, double);
6868+double kbd_backlight_op(int, double);
6869void usage(void);
69707071extern char *__progname;
···7475static int dimmed = 0;
7576static int debug = 0;
7677static int exiting = 0;
7878+static int dimkbd = 0;
7979+static double kbd_backlight = -1;
77807881static int dim_timeout = DEFAULT_DIM_TIMEOUT;
7982static int dim_pct = DEFAULT_DIM_PERCENTAGE;
8083static int dim_steps = DIM_STEPS;
81848282-static int wsconsfd = 0;
8585+static int wsconsdfd = 0;
8686+static int wsconskfd = 0;
83878488static Display *dpy;
8589···8892{
8993 int ch;
90949191- while ((ch = getopt(argc, argv, "dp:s:t:")) != -1) {
9595+ while ((ch = getopt(argc, argv, "dkp:s:t:")) != -1) {
9296 const char *errstr;
93979498 switch (ch) {
9599 case 'd':
96100 debug = 1;
97101 break;
102102+ case 'k':
103103+#ifndef __OpenBSD__
104104+ errx(1, "keyboard backlight not supported on this "
105105+ "platform");
106106+#endif
107107+ dimkbd = 1;
108108+ break;
98109 case 'p':
99110 dim_pct = strtonum(optarg, 1, 100, &errstr);
100111 if (errstr)
···124135 if (backlight_a == None) {
125136#ifdef __OpenBSD__
126137 /* see if wscons display.brightness is available */
127127- if (!(wsconsfd = open("/dev/ttyC0", O_WRONLY)) ||
138138+ if (!(wsconsdfd = open("/dev/ttyC0", O_WRONLY)) ||
128139 backlight_op(OP_GET, 0) < 0)
129140#endif
130141 errx(1, "no backlight control");
131131- } else {
142142+ }
132143#ifdef __OpenBSD__
144144+ else if (!dimkbd) {
133145 /*
134146 * unfortunately we can't pledge() with wscons interface,
135147 * because the ws*io* ioctls aren't whitelisted
136148 */
137149 if (pledge("stdio", NULL) == -1)
138150 err(1, "pledge");
151151+ }
152152+153153+ if (dimkbd)
154154+ if (!(wsconskfd = open("/dev/wskbd0", O_WRONLY)) ||
155155+ kbd_backlight_op(OP_GET, 0) < 0)
156156+ errx(1, "no keyboard backlight control");
139157#endif
158158+159159+ if (debug) {
160160+ printf("dimming screen to %d%% in %d secs\n", dim_pct,
161161+ dim_timeout);
162162+163163+ if (dimkbd)
164164+ printf("dimming keyboard backlight in %d secs\n",
165165+ dim_timeout);
140166 }
141141-142142- if (debug)
143143- printf("dimming to %d%% in %d secs\n", dim_pct, dim_timeout);
144167145168 signal(SIGINT, bail);
146169 signal(SIGTERM, bail);
···268291dim(void)
269292{
270293 backlight = backlight_op(OP_GET, 0);
294294+ if (dimkbd)
295295+ kbd_backlight = backlight_op(OP_GET, 0);
271296272297 if (backlight > dim_pct) {
273298 if (debug)
274299 printf("dimming to %d\n", dim_pct);
275300276276- stepper(OP_SET, dim_pct, dim_steps);
301301+ stepper(OP_SET, dim_pct, 0, dim_steps);
277302 dimmed = 1;
278303 }
279304 else if (debug)
···288313 if (debug)
289314 printf("brightening back to %f\n", backlight);
290315291291- stepper(OP_SET, backlight, BRIGHTEN_STEPS);
316316+ stepper(OP_SET, backlight, kbd_backlight, BRIGHTEN_STEPS);
292317 }
293318 else if (debug)
294319 printf("no previous backlight setting, not brightening\n");
···297322}
298323299324void
300300-stepper(int op, double new_backlight, int steps)
325325+stepper(int op, double new_backlight, double new_kbd_backlight, int steps)
301326{
302327 double tbacklight = backlight_op(OP_GET, 0);
303303- int step_inc = 0, j;
328328+ double tkbdbacklight;
329329+ int step_inc = 0, kbd_step_inc = 0, j;
304330305331 if ((int)new_backlight == (int)tbacklight)
306332 steps = 0;
307333 else
308334 step_inc = (new_backlight - tbacklight) / steps;
309335336336+ if (dimkbd) {
337337+ tkbdbacklight = kbd_backlight_op(OP_GET, 0);
338338+339339+ if ((int)new_kbd_backlight != (int)tkbdbacklight)
340340+ kbd_step_inc = (new_kbd_backlight - tkbdbacklight) /
341341+ steps;
342342+ }
343343+310344 if (debug)
311345 printf("stepping from %0.2f to %0.2f in increments of %d "
312346 "(%d step%s)... ",
···316350 for (j = 1; j <= steps; j++) {
317351 tbacklight += step_inc;
318352319319- if (j == steps)
353353+ if (dimkbd)
354354+ tkbdbacklight += kbd_step_inc;
355355+356356+ if (j == steps) {
320357 tbacklight = new_backlight;
321358359359+ if (dimkbd)
360360+ tkbdbacklight = new_kbd_backlight;
361361+ }
362362+322363 if (debug)
323364 printf(" %0.2f", tbacklight);
324365325366 backlight_op(OP_SET, tbacklight);
367367+368368+ if (dimkbd)
369369+ kbd_backlight_op(OP_SET, tkbdbacklight);
326370327371 if (j < steps && step_inc < 0)
328372 usleep(15000);
···352396 struct wsdisplay_param param;
353397354398 param.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
355355- if (ioctl(wsconsfd, WSDISPLAYIO_GETPARAM, ¶m) < 0)
399399+ if (ioctl(wsconsdfd, WSDISPLAYIO_GETPARAM, ¶m) < 0)
356400 errx(1, "ioctl");
357401358402 if (op == OP_SET) {
···364408 else if (param.curval < param.min)
365409 param.curval = param.min;
366410367367- if (ioctl(wsconsfd, WSDISPLAYIO_SETPARAM, ¶m) < 0)
411411+ if (ioctl(wsconsdfd, WSDISPLAYIO_SETPARAM, ¶m) < 0)
368412 errx(1, "ioctl");
369413 }
370414···438482 return cur_backlight;
439483}
440484485485+double
486486+kbd_backlight_op(int op, double new_backlight)
487487+{
488488+ struct wskbd_backlight param;
489489+490490+ if (ioctl(wsconskfd, WSKBDIO_GETBACKLIGHT, ¶m) < 0)
491491+ errx(1, "ioctl");
492492+493493+ if (op == OP_SET) {
494494+ param.curval = (double)(param.max - param.min) *
495495+ (new_backlight / 100.0);
496496+497497+ if (param.curval > param.max)
498498+ param.curval = param.max;
499499+ else if (param.curval < param.min)
500500+ param.curval = param.min;
501501+502502+ if (ioctl(wsconsdfd, WSKBDIO_SETBACKLIGHT, ¶m) < 0)
503503+ errx(1, "ioctl");
504504+ }
505505+506506+ return ((double)param.curval /
507507+ (double)(param.max - param.min)) * 100;
508508+}
509509+441510void
442511usage(void)
443512{
444444- fprintf(stderr, "usage: %s [-d] [-p dim pct] [-s dim steps] "
513513+ fprintf(stderr, "usage: %s [-d] [-k] [-p dim pct] [-s dim steps] "
445514 "[-t timeout secs]\n", __progname);
446515 exit(1);
447516}