lightweight X11 utility to dim the screen and/or keyboard backlight when idle
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

use a pipe to force an exit

Since the exit handler can't brighten on its own, just write into
the pipe and return. The poll() call is now checking on the pipe
and if it detects a write, brighten back up and exit cleanly.

+36 -20
+36 -20
xdimmer.c
··· 91 91 void als_fetch(void); 92 92 void usage(void); 93 93 int XPeekEventOrTimeout(Display *, XEvent *, unsigned int); 94 + int exitmsg[2]; 94 95 95 96 extern char *__progname; 96 97 ··· 216 217 signal(SIGINT, bail); 217 218 signal(SIGTERM, bail); 218 219 220 + /* setup a pipe to wait for an exit message from bail() */ 221 + pipe(exitmsg); 222 + 219 223 xloop(); 220 224 221 225 return 0; ··· 258 262 XEvent e; 259 263 XSyncAlarmNotifyEvent *alarm_e; 260 264 261 - if (exiting) 262 - break; 263 - 264 265 DPRINTF(("waiting for next event\n")); 265 266 266 267 /* if we're checking an als, only wait 1 second for x event */ ··· 269 270 als_fetch(); 270 271 continue; 271 272 } 273 + 274 + if (exiting) 275 + break; 272 276 273 277 XNextEvent(dpy, &e); 274 278 ··· 684 688 if (exiting) 685 689 exit(0); 686 690 691 + /* 692 + * Doing X ops inside a signal handler causes an infinite loop in 693 + * _XReply/xcb, so we can't properly brighten and exit ourselves. 694 + * write to the pipe setup earlier so our event loop will see it upon 695 + * polling. 696 + */ 687 697 DPRINTF(("got signal %d, trying to exit\n", sig)); 688 - 689 - /* XXX: doing X ops inside a signal handler causes an infinite loop in 690 - * _XReply/xcb, so we can't properly brighten() and exit, so we just 691 - * set a flag and wait for the next time our idle counter stuff happens 692 - * so we can exit there */ 693 - if (dimmed) 694 - exiting = 1; 695 - else 696 - exit(0); 698 + write(exitmsg[1], &exitmsg, 1); 699 + exiting = 1; 697 700 } 698 701 699 702 int 700 703 XPeekEventOrTimeout(Display *dpy, XEvent *e, unsigned int msecs) 701 704 { 702 - struct pollfd pfd[1]; 705 + struct pollfd pfd[2]; 703 706 704 - if (!XPending(dpy)) { 707 + while (!XPending(dpy)) { 705 708 memset(&pfd, 0, sizeof(pfd)); 706 709 pfd[0].fd = ConnectionNumber(dpy); 707 710 pfd[0].events = POLLIN; 711 + pfd[1].fd = exitmsg[0]; 712 + pfd[1].events = POLLIN; 708 713 709 - if (poll(pfd, 1, msecs == 0 ? INFTIM : msecs) == 0) 714 + switch (poll(pfd, 2, msecs == 0 ? INFTIM : msecs)) { 715 + case -1: 716 + /* signal, maybe exit handler, we'll loop again */ 717 + DPRINTF(("poll returned -1 for errno %d\n", errno)); 718 + break; 719 + case 0: 720 + /* timed out */ 710 721 return 0; 711 - 712 - if (pfd[0].revents) { 713 - DPRINTF(("%s: got X event\n", __func__)); 714 - XPeekEvent(dpy, e); 715 - return 1; 722 + default: 723 + if (pfd[1].revents) { 724 + DPRINTF(("%s: got exit message\n", __func__)); 725 + exiting = 1; 726 + return 1; 727 + } else if (pfd[0].revents) { 728 + DPRINTF(("%s: got X event\n", __func__)); 729 + XPeekEvent(dpy, e); 730 + return 1; 731 + } 716 732 } 717 733 } 718 734