diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/adjbacklight.c | 315 |
1 files changed, 255 insertions, 60 deletions
diff --git a/src/adjbacklight.c b/src/adjbacklight.c index 31e4811..4bf50ac 100644 --- a/src/adjbacklight.c +++ b/src/adjbacklight.c @@ -21,10 +21,20 @@ #include <termios.h> #include <sys/ioctl.h> #include <sys/wait.h> +#include <sys/types.h> #include <unistd.h> #include <dirent.h> #include <string.h> #include <limits.h> +#include <alloca.h> + + + + +#ifndef PATH_MAX +#warning PATH_MAX is not defined +#define PATH_MAX 4096 +#endif @@ -43,11 +53,35 @@ /** * Print a line to stdout * - * @param S:char* The string to print + * @param S:const char* The string to print */ #define P(S) printf("%s", S "\n") +/** + * Cut a string of at the first line break + * A help `int` named `i` must be available + * + * @param data:char* The string, it will be modified + * @return :char* The input string, it has been modified + */ +#define unnl(data) \ + ({ \ + for (i = 0; *(data + i); i++) \ + if (*(data + i) == '\n') \ + *(data + i) = 0; \ + data; \ + }) + + + +/** + * Test whether a string numerical and with at most two trailing '%' + * + * @param str The string + * @return Whether the test passed + */ +static int isnumerical(const char* str); /** * Interactively adjust the backlight on a device @@ -58,6 +92,14 @@ static void adjust(int cols, const char* device); /** + * Gets the current backlight setting on a device + * + * @param device The device from which to get backlight + * @return The brightness as a [0; 1] float, negative on error + */ +static float getbrightness(const char* device); + +/** * Read a file * * @param output Buffer to store the file's content in @@ -113,9 +155,10 @@ int main(int argc, char** argv) struct winsize win; struct termios saved_stty; struct termios stty; - pid_t pid; int i, j; - int all = 0, cols = 80, ndevices = 0; + pid_t pid = 0; + char* set = NULL; + int get = 0, all = 0, cols = 80, ndevices = 0; char** devices = alloca(argc * sizeof(char*)); @@ -160,10 +203,36 @@ int main(int argc, char** argv) P("\n"); return 0; } + else if (T("-s") || T("--set")) + { + char* tmp; + if (i + 1 == argc) + fprintf(stderr, "%s: argument for option %s is missing, ignoring option\n", *argv, arg); + else + if (!isnumerical(tmp = *(argv + i++))) + fprintf(stderr, "%s: argument for option %s is malformated, ignoring option\n", *argv, arg); + else + { + set = tmp; + get = 0; + } + } + else if (T("-g") || T("--get")) + { + get = 1; + set = NULL; + } + else if (((*arg == '-') || (*arg == '+') || (*arg == '=')) && isnumerical(arg + 1)) + { + set = arg; + get = 0; + } else { if (*arg && (*arg != '-')) *(devices + ndevices++) = arg; + else + fprintf(stderr, "%s: ignoring unrecognised argument: %s\n", *argv, arg); } #undef T } @@ -172,7 +241,7 @@ int main(int argc, char** argv) P("\n"); P("adjbacklight - Convient method for adjusting the backlight on your portable computer"); P(""); - P("USAGE: adjbacklight [ -c | -w | -a | DEVICE...]"); + P("USAGE: adjbacklight (-c | -w | [-g | -s LEVEL | LEVEL] [-a | DEVICE...])"); P(""); P("Run with options to adjust the backlight on your monitors."); P(""); @@ -187,7 +256,25 @@ int main(int argc, char** argv) P("--warranty Display warranty disclaimer"); P(""); P("-a"); - P("--all Run for all devices, including ACPI devices "); + P("--all Run for all devices, including ACPI devices"); + P(""); + P("-g"); + P("--get Get average brightness on devices"); + P(""); + P("-s"); + P("--set LEVEL[%] Set brightness on devices"); + P(""); + P("+LEVEL Increase brightness on devices by actual value"); + P("-LEVEL Decrease brightness on devices by actual value"); + P("=LEVEL Set brightness on devices by actual value"); + P(""); + P("+LEVEL% Increase brightness on devices by percentage"); + P("-LEVEL% Decrease brightness on devices by percentage"); + P("=LEVEL% Set brightness on devices by percentage"); + P(""); + P("+LEVEL%% Increase brightness on devices by relative percentage"); + P("-LEVEL%% Decrease brightness on devices by relative percentage"); + P("=LEVEL%% Set brightness on devices by relative percentage"); P(""); P(""); P("KEYBOARD:"); @@ -226,54 +313,66 @@ int main(int argc, char** argv) P("\n\n\n"); - /* Get the size of the terminal */ - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == -1) - perror(*argv); - else - cols = win.ws_col; - - /* Hide cursor */ - printf("%s", "\033[?25l"); - fflush(stdout); - - /* stty -icanon -echo */ - if (tcgetattr(STDIN_FILENO, &stty)) - { - perror(*argv); - return 1; - } - saved_stty = stty; - stty.c_lflag &= ~(ICANON | ECHO); - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty)) + if (!get && !set) { - perror(*argv); - return 1; + /* Get the size of the terminal */ + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == -1) + perror(*argv); + else + cols = win.ws_col; + + /* Hide cursor */ + printf("%s", "\033[?25l"); + fflush(stdout); + + /* stty -icanon -echo */ + if (tcgetattr(STDIN_FILENO, &stty)) + { + perror(*argv); + return 1; + } + saved_stty = stty; + stty.c_lflag &= ~(ICANON | ECHO); + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty)) + { + perror(*argv); + return 1; + } } /* Fork to diminish risk of unclean exit */ - pid = FORK(); - if (pid == (pid_t)-1) + if (!get && !set) { - perror(*argv); - pid = 0; + pid = FORK(); + if (pid == (pid_t)-1) + { + perror(*argv); + pid = 0; + } } if (pid) waitpid(pid, NULL, 0); else { - line = malloc(cols * 3 * sizeof(char)); - space = malloc(cols * sizeof(char)); - for (i = 0; i < cols; i++) + float brightness = 0; + int nbrightness = 0; + + if (!get && !set) { - *(line + i * 3 + 0) = 0xE2; - *(line + i * 3 + 1) = 0x94; - *(line + i * 3 + 2) = 0x80; - *(space + i) = ' '; + line = malloc(cols * 3 * sizeof(char)); + space = malloc(cols * sizeof(char)); + for (i = 0; i < cols; i++) + { + *(line + i * 3 + 0) = (char)(0xE2); + *(line + i * 3 + 1) = (char)(0x94); + *(line + i * 3 + 2) = (char)(0x80); + *(space + i) = ' '; + } + *(space + cols - 1) = 0; + *(line + (cols - 2) * 3) = 0; } - *(space + cols - 1) = 0; - *(line + (cols - 2) * 3) = 0; if (ndevices) { @@ -287,7 +386,17 @@ int main(int argc, char** argv) device += j + 1; j = -1; } - adjust(cols, device); + if (get) + { + float value = getbrightness(device); + if (value >= 0.f) + { + brightness += value; + nbrightness++; + } + } + else + adjust(cols, device); } } else @@ -303,32 +412,89 @@ int main(int argc, char** argv) device = ent->d_name; if (all || (strstr(device, forbidden) != forbidden)) if (*device && (*device != '.')) - adjust(cols, device); + { + if (get) + { + float value = getbrightness(device); + if (value >= 0.f) + { + brightness += value; + nbrightness++; + } + } + else + adjust(cols, device); + } } closedir(dir); } } - free(line); - free(space); + if (!get && !set) + { + free(line); + free(space); + } + else if (get) + { + brightness *= 100.f; + brightness /= nbrightness; + printf("%.2f%%\n", brightness); + fflush(stdout); + } } - /* `stty icanon echo` */ - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty)) + if (!get && !set) { - perror(*argv); - return 1; + /* `stty icanon echo` */ + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty)) + { + perror(*argv); + return 1; + } + + /* Show cursor */ + printf("%s", "\033[?25h"); + fflush(stdout); } - /* Show cursor */ - printf("%s", "\033[?25h"); - fflush(stdout); - return 0; } +/** + * Test whether a string numerical and with at most two trailing '%' + * + * @param str The string + * @return Whether the test passed + */ +static int isnumerical(const char* str) +{ + int p = 0, d = 0; + if ((*str == 0) || (*str == '%')) + return 0; + for (; *str; str++) + { + switch (*str) + { + case '.': + if (d++) + return 0; + /* fall through */ + case '0' ... '9': + if (p) + return 0; + break; + + case '%': + p++; + break; + } + } + return p <= 2; +} + /** * Interactively adjust the backlight on a device @@ -338,18 +504,10 @@ int main(int argc, char** argv) */ static void adjust(int cols, const char* device) { - #define unnl(data) \ - ({ \ - for (i = 0; *(data + i); i++) \ - if (*(data + i) == '\n') \ - *(data + i) = 0; \ - data; \ - }) - int min, max, cur, step, init, i, d; size_t lendir; char* dir = alloca(PATH_MAX * sizeof(char)); - char* buf = alloca(256); + char* buf = alloca(256 * sizeof(char)); *dir = 0; dir = strcat(dir, "/sys/class/backlight/"); @@ -403,6 +561,43 @@ static void adjust(int cols, const char* device) /** + * Gets the current backlight setting on a device + * + * @param device The device from which to get backlight + * @return The brightness as a [0; 1] float, negative on error + */ +static float getbrightness(const char* device) +{ + int min, max, cur, i; + size_t lendir; + char* dir = alloca(PATH_MAX * sizeof(char)); + char* buf = alloca(256); + + *dir = 0; + dir = strcat(dir, "/sys/class/backlight/"); + dir = strcat(dir, device); + dir = strcat(dir, "/"); + lendir = strlen(dir); + + /* Get brightness parameters */ + min = 0; + if (readfile(buf, strcat(dir, "max_brightness"))) + return -1.f; + max = atoi(unnl(buf)); + *(dir + lendir) = 0; + if (readfile(buf, strcat(dir, "brightness"))) + return -1.f; + cur = atoi(unnl(buf)); + + if (max <= min) + return -1.f; /* what the buck */ + + return (float)cur / (float)(max - min); +} + + + +/** * Read a file * * @param output Buffer to store the file's content in |