initial
[backlight-adjust.git] / bl.c
blob6af4b54931dafcc392e299f949bc7d8cc3c96550
1 /*
2 * Copyright (c) 2017, S. Gilles <sgilles@math.umd.edu>
4 * Permission to use, copy, modify, and/or distribute this software
5 * for any purpose with or without fee is hereby granted, provided
6 * that the above copyright notice and this permission notice appear
7 * in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
13 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
14 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include <errno.h>
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <termios.h>
24 #include <unistd.h>
26 #define STR2(x) #x
27 #define STR(x) STR2(x)
28 #define L(x) __FILE__ ":" STR(__LINE__) ": " x
30 static int16_t brightness;
32 #define STEP 2
34 #define BAR_WIDTH 72
35 #define BAR_PRE " ┝"
36 #define BAR_POST "┤ "
37 #define FINAL "\033[G"
38 #define BRIGHT_CELL "━"
39 #define DARK_CELL "─"
41 static void output(void)
43 printf("%s%s", "\033[G", BAR_PRE);
45 for (int j = 0; j < BAR_WIDTH; ++j) {
46 if (j * 128 <= brightness * BAR_WIDTH) {
47 printf("%s", BRIGHT_CELL);
48 } else {
49 printf("%s", DARK_CELL);
53 printf("%s%d/128 %s", BAR_POST, (int) brightness, FINAL);
54 fflush(stdout);
57 int main(void)
59 int ret = 0;
60 FILE *sf = 0;
61 struct termios in_t = { 0 };
62 struct termios stored_in_t = { 0 };
63 struct termios stored_out_t = { 0 };
64 int in_fd = fileno(stdin);
65 int out_fd = fileno(stdout);
66 char buf[2];
67 int c;
69 errno = 0;
71 /* Get the /sys entry to manipulate */
72 if (!(sf = fopen(BACKLIGHT_PATH, "w+"))) {
73 ret = errno;
74 perror(L("fopen(\"" BACKLIGHT_PATH "\", \"a+\")"));
75 goto err_pre_tty;
78 /* Read initial backlight value */
79 buf[0] = '\0';
80 brightness = 0;
82 while (!feof(sf) &&
83 !ferror(sf)) {
84 if (fread(buf, 1, 1, sf) > 0) {
85 if (buf[0] <= '9' &&
86 buf[0] >= '0') {
87 brightness = brightness * 10 + (buf[0] - '0');
92 if (brightness < 0 ||
93 brightness > 128) {
94 fprintf(stderr, L("impossible backlight value\n"));
95 goto err_pre_tty;
98 /* Set up the terminal for pretty */
99 if (!isatty(in_fd)) {
100 ret = errno;
101 fprintf(stderr, L("stdin is not a tty\n"));
102 goto err_pre_tty;
105 if (tcgetattr(in_fd, &stored_in_t)) {
106 ret = errno;
107 perror(L("tcgetattr"));
108 goto err_pre_tty;
111 memcpy(&in_t, &stored_in_t, sizeof in_t);
113 if (!isatty(out_fd)) {
114 ret = errno;
115 fprintf(stderr, L("stdout is not a tty\n"));
116 goto err_pre_tty;
119 if (tcgetattr(out_fd, &stored_out_t)) {
120 ret = errno;
121 perror(L("tcgetattr"));
122 goto err_pre_tty;
125 /* cfmakeraw() is nonstandard, and I want ^C anyway. */
126 in_t.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR |
127 ICRNL | IXON);
128 in_t.c_oflag &= ~OPOST;
129 in_t.c_lflag &= ~(ECHO | ECHONL | ICANON);
130 in_t.c_cflag &= ~(CSIZE | PARENB);
131 in_t.c_cflag |= CS8;
133 /* Technically, it is necessary to check these one by one. That's a pain */
134 if (tcsetattr(in_fd, TCSANOW, &in_t)) {
135 ret = errno;
136 perror(L("tcsetattr"));
137 goto err_pre_tty;
140 printf("\033[?25l");
141 output();
143 while ((c = getchar()) != EOF) {
144 switch (c) {
145 case 'q':
146 case 'Q':
147 goto done;
148 break;
149 case 005:
150 case 'j':
151 case 'J':
152 brightness -= (2 * STEP);
153 case 031:
154 case 'k':
155 case 'K':
156 brightness += STEP;
158 if (brightness < 0) {
159 brightness = 0;
160 } else if (brightness > 128) {
161 brightness = 128;
164 fprintf(sf, "%d\n", (int) brightness);
165 fflush(sf);
166 break;
167 default:
168 break;
171 output();
174 done:
175 tcsetattr(in_fd, TCSANOW, &stored_in_t);
176 printf("\033[?25h\n");
177 err_pre_tty:
179 if (sf) {
180 fclose(sf);
183 return ret;