diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/adjbacklight.auto-completion | 17 | ||||
-rw-r--r-- | src/adjbacklight.c | 872 |
2 files changed, 0 insertions, 889 deletions
diff --git a/src/adjbacklight.auto-completion b/src/adjbacklight.auto-completion deleted file mode 100644 index a06884f..0000000 --- a/src/adjbacklight.auto-completion +++ /dev/null @@ -1,17 +0,0 @@ -(adjbacklight - (unargumented (options -c --copyright --copying) (complete --copying) - (desc 'Display copyright information')) - - (unargumented (options -w --warranty) (complete --warranty) - (desc 'Display warranty disclaimer')) - - (unargumented (options -a --all) (complete --all) - (desc 'Run for all devices, including ACPI devices')) - - (unargumented (options -g --get) (complete --get) - (desc 'Get average brightness on devices')) - - (argumented (options -s --set) (complete --set) (files 'LEVEL[%]') (files -0) - (desc 'Set brightness on devices')) -) - diff --git a/src/adjbacklight.c b/src/adjbacklight.c deleted file mode 100644 index 455fb70..0000000 --- a/src/adjbacklight.c +++ /dev/null @@ -1,872 +0,0 @@ -/** - * adjbacklight – Convenient method for adjusting the backlight on your portable computer - * - * Copyright © 2012, 2013, 2014, 2015 Mattias Andrée (maandree@member.fsf.org) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -#include <stdlib.h> -#include <stdio.h> -#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> -#include <grp.h> -#include <pwd.h> - - - -#ifndef PATH_MAX -#warning PATH_MAX is not defined -#define PATH_MAX 4096 -#endif - - - -/** - * The years this software has been developed - */ -#define _YEARS_ "2012, 2013, 2014" - - -/** - * Forking method - */ -#ifndef FORK -#define FORK fork -#endif - - -/** - * The directory where the backlight devices are found and configured - */ -#ifndef BACKLIGHT_DIR -#define BACKLIGHT_DIR "/sys/class/backlight" -#endif - - -/** - * Print a line to stdout - * - * @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 - * - * @param cols The number of columns on the terminal - * @param device The device on which to adjust backlight - */ -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); - -/** - * Sets the current backlight setting on a device - * - * @param device The device from which to get backlight - * @param adjustment The adjustment to make - */ -static void setbrightness(const char* device, const char* adjustment); - -/** - * Read a file - * - * @param output Buffer to store the file's content in - * @param file The file to read - * @return Zero on success, non-zero on failure - */ -static int readfile(char* output, const char* file); - -/** - * Write an integer to a file - * - * @param buffer Buffer for temporary data - * @param integer The integer to write - * @param file The file to which to write - * @return Zero on success, non-zero on failure - */ -static int writefile(char* buffer, int integer, const char* file); - -/** - * Print the status - * - * @param min The minimum possible brightness - * @param max The maximum possible brightness - * @param init The brightness used when the program started - * @param cur The current brightness - * @param cols The number of columns on the terminal - */ -static void bars(int min, int max, int init, int cur, int cols); - - - -/** - * A series of spaces used to print the bar - */ -static char* space; - -/** - * A series of vertical lines used to print the bar - */ -static char* line; - - - -/** - * This is the mane entry point of the program - * - * @param argc The number of elements in `argv` - * @parma argv Command line arguments, including the command - * @return Exit value, zero on success - */ -int main(int argc, char** argv) -{ - struct winsize win; - struct termios saved_stty; - struct termios stty; - size_t i, ndevices = 0; - pid_t pid = 0; - char* set = NULL; - int j, get = 0, help = 0, all = 0, cols = 80; - char** devices = alloca((size_t)argc * sizeof(char*)); - - - if (argc > 1) - { - char* arg; - for (i = 1; i < (size_t)argc; i++) - { - #define T(S) (!strcmp(arg, S)) - arg = *(argv + i); - if (T("-h") || T("--help")) - help = 1; - else if (T("-a") || T("--all")) - all = 1; - else if (T("-c") || T("--copyright") || T("--copying")) - { - P("\n"); - P("adjbacklight – Convenient method for adjusting the backlight on your portable computer"); - P(""); - P("Copyright © " _YEARS_ " Mattias Andrée (maandree@member.fsf.org)"); - P(""); - P("This program is free software: you can redistribute it and/or modify"); - P("it under the terms of the GNU General Public License as published by"); - P("the Free Software Foundation, either version 3 of the License, or"); - P("(at your option) any later version."); - P(""); - P("This program is distributed in the hope that it will be useful,"); - P("but WITHOUT ANY WARRANTY; without even the implied warranty of"); - P("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"); - P("GNU General Public License for more details."); - P(""); - P("You should have received a copy of the GNU General Public License"); - P("along with this program. If not, see <http://www.gnu.org/licenses/>."); - P("\n"); - return 0; - } - else if (T("-w") || T("--warranty")) - { - P("\n"); - P("This program is distributed in the hope that it will be useful,"); - P("but WITHOUT ANY WARRANTY; without even the implied warranty of"); - P("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"); - P("GNU General Public License for more details."); - P("\n"); - return 0; - } - else if (T("-s") || T("--set")) - { - char* tmp; - if (i + 1 == (size_t)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 - } - fflush(stderr); - if (help || (((size_t)all + ndevices + (size_t)get == 0) && !set)) - { - P("\n"); - P("adjbacklight - Convenient method for adjusting the backlight on your portable computer"); - P(""); - P("USAGE: adjbacklight (-c | -w | [-g | -s LEVEL | LEVEL] [-a | DEVICE...])"); - P(""); - P("Run with options to adjust the backlight on your monitors."); - P(""); - P(""); - P("OPTIONS:"); - P(""); - P("-c"); - P("--copyright"); - P("--copying Display copyright information"); - P(""); - P("-w"); - P("--warranty Display warranty disclaimer"); - P(""); - P("-a"); - 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-points"); - P("-LEVEL% Decrease brightness on devices by percentage-points"); - P("=LEVEL% Set brightness on devices by percentage-points"); - 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(""); - P("KEYBOARD:"); - P(""); - P("←"); - P("↓ Darken the screen"); - P(""); - P("→"); - P("↑ Brighten the screen"); - P(""); - P("q"); - P("enter"); - P("C-d Continue to next controller, or if at last, quit"); - P(""); - P(""); - P(""); - P("Copyright © " _YEARS_ " Mattias Andrée (maandree@member.fsf.org)"); - P(""); - P("This program is free software: you can redistribute it and/or modify"); - P("it under the terms of the GNU General Public License as published by"); - P("the Free Software Foundation, either version 3 of the License, or"); - P("(at your option) any later version."); - P(""); - return 0; - } - } - - - /* Check permissions */ - if (getuid()) /* Always accept root */ - { - struct group* video_grp = getgrnam("video"); - if (video_grp) /* Accept everypony if the group ‘video’ does not exist */ - { - struct passwd* realuser = getpwuid(getuid()); - char** mems; - char* realname; - int ok; - if (!realuser) - { - P("You do not exist, go away!"); - return 1; - } - mems = video_grp->gr_mem; - realname = realuser->pw_name; - ok = 0; - for (; *mems; mems++) - if (!strcmp(realname, *mems)) - { - ok = 1; - break; - } - endgrent(); - if (!ok) - { - P("Sorry, you need to be in the group 'video'."); - return 1; - } - } - endpwent(); - } - - - if (!get && !set) - { - P("\n"); - P("If the program is abnormally aborted the may be some residual"); - P("effects on the terminal. the following commands should reset it:"); - P(""); - P(" stty icanon echo"); - P(" echo -en '\\e[?25h'"); - P(""); - P("\n\n\n"); - } - - - if (!get && !set) - { - /* 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 &= (tcflag_t)~(ICANON | ECHO); - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty)) - { - perror(*argv); - return 1; - } - } - - - /* Fork to diminish risk of unclean exit */ - if (!get && !set) - { - pid = FORK(); - if (pid == (pid_t)-1) - { - perror(*argv); - pid = 0; - } - } - - if (pid) - waitpid(pid, NULL, 0); - else - { - float brightness = 0; - int nbrightness = 0; - - if (!get && !set) - { - line = malloc((size_t)cols * 3 * sizeof(char)); - space = malloc((size_t)cols * sizeof(char)); - for (i = 0; i < (size_t)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; - } - - if (ndevices) - { - char* device; - for (i = 0; i < ndevices; i++) - { - device = *(devices + i); - for (j = 0; *(device + j); j++) - if (*(device + j) == '/') - { - device += j + 1; - j = -1; - } - if (get) - { - float value = getbrightness(device); - if (value >= 0.f) - { - brightness += value; - nbrightness++; - } - } - else if (set) - setbrightness(device, set); - else - adjust(cols, device); - } - } - else - { - struct dirent* ent; - DIR* dir = opendir(BACKLIGHT_DIR); - if (dir) - { - char* device; - while ((ent = readdir(dir))) - { - device = ent->d_name; - if (all || (strstr(device, "acpi_video") != device)) - if (*device && (*device != '.')) - { - if (get) - { - float value = getbrightness(device); - if (value >= 0.f) - { - brightness += value; - nbrightness++; - } - } - else if (set) - setbrightness(device, set); - else - adjust(cols, device); - } - } - closedir(dir); - } - } - - if (!get && !set) - { - free(line); - free(space); - } - else if (get) - { - if (nbrightness) - { - brightness *= 100.f; - brightness /= (float)nbrightness; - printf("%.2f%%\n", (double)brightness); - fflush(stdout); - } - else - { - printf("%s\n", "100.00%"); - fflush(stdout); - } - } - } - - - if (!get && !set) - { - /* `stty icanon echo` */ - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty)) - { - perror(*argv); - return 1; - } - - /* 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; - - default: - return 0; - } - } - return p <= 2; -} - - -/** - * Interactively adjust the backlight on a device - * - * @param cols The number of columns on the terminal - * @param device The device on which to adjust backlight - */ -static void adjust(int cols, const char* device) -{ - int min, max, cur, step, init, i, d; - size_t lendir; - char* dir = alloca(PATH_MAX * sizeof(char)); - char* buf = alloca(256 * sizeof(char)); - - *dir = 0; - dir = strcat(dir, BACKLIGHT_DIR "/"); - dir = strcat(dir, device); - dir = strcat(dir, "/"); - lendir = strlen(dir); - - /* Get brightness parameters */ - min = 0; - if (readfile(buf, strcat(dir, "max_brightness"))) - return; - max = atoi(unnl(buf)); - *(dir + lendir) = 0; - if (readfile(buf, strcat(dir, "brightness"))) - return; - cur = atoi(unnl(buf)); - - if (max <= min) - return; /* what the buck */ - - step = (max - min) / 200 ?: 1; - init = cur; - - P("\n\n\n\n\n"); - bars(min, max, init, cur, cols); - - while ((d = getchar()) != -1) - switch (d) - { - case 'q': - case '\n': - case 4: - P(""); - return; - - case 'A': - case 'C': - cur += step << 1; - /* fall through */ - case 'B': - case 'D': - cur -= step; - if (cur < min) cur = min; - if (cur > max) cur = max; - if (writefile(buf, cur, dir)) - return; - bars(min, max, init, cur, cols); - } -} - - - -/** - * 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, BACKLIGHT_DIR "/"); - 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); -} - - - -/** - * Sets the current backlight setting on a device - * - * @param device The device from which to get backlight - * @param adjustment The adjustment to make - */ -static void setbrightness(const char* device, const char* adjustment) -{ - int min, max, cur, i, adj; - size_t lendir; - char* dir = alloca(PATH_MAX * sizeof(char)); - char* buf = alloca(256); - int act = 0, integer = 0, decimal = 0, p = 0, d = 0; - - *dir = 0; - dir = strcat(dir, BACKLIGHT_DIR "/"); - dir = strcat(dir, device); - dir = strcat(dir, "/"); - lendir = strlen(dir); - - /* Get brightness parameters */ - min = 0; - if (readfile(buf, strcat(dir, "max_brightness"))) - return; - max = atoi(unnl(buf)); - *(dir + lendir) = 0; - if (readfile(buf, strcat(dir, "brightness"))) - return; - cur = atoi(unnl(buf)); - - if (max <= min) - return; /* what the buck */ - - /* Read -/+/= head */ - if (*adjustment == '-') - act = -1; - else if (*adjustment == '+') - act = 1; - else if (*adjustment != '=') - adjustment--; - adjustment++; - - /* Parse numerical part */ - for (; *adjustment && (*adjustment != '%'); adjustment++) - if (*adjustment == '.') - d = 1; - else if (d) - { - if ((long long)d * 10 > (long long)INT_MAX) - continue; - if ((long long)decimal * 10 + 9 > (long long)INT_MAX) - continue; - d *= 10; - decimal *= 10; - decimal += (*adjustment) - '0'; - } - else - { - integer *= 10; - integer += (*adjustment) - '0'; - } - if (!d) - d = 1; - - /* Count number of p:s */ - while (*adjustment++) - p++; - - /* Calculate value to send */ - if (p == 0) - adj = integer + (int)((double)decimal / (double)d + 0.5d); - else if (p == 1) - adj = (int)(((double)integer + (double)decimal / (double)d) * (double)(max - min) / 100.d); - else - adj = (int)(((double)integer + (double)decimal / (double)d) * (double)cur / 100.d); - adj = (act & 1) * cur + (act | 1) * adj; - if (adj < min) adj = min; - if (adj > max) adj = max; - - /* Send value */ - writefile(buf, adj, dir); -} - - - -/** - * Read a file - * - * @param output Buffer to store the file's content in - * @param file The file to read - * @return Zero on success, non-zero on failure - */ -static int readfile(char* output, const char* file) -{ - #define BLOCK_SIZE 256 /* We will not even encounter that much */ - FILE* f; - size_t got, have = 0; - int ended = 0; - - if ((f = fopen(file, "r")) == NULL) - { - perror(file); - return -1; - } - - while (!ended) - { - got = fread(output + have, 1, BLOCK_SIZE, f); - if (got != BLOCK_SIZE) - { - ended = feof(f); - have += got; - clearerr(f); - fclose(f); - if (!ended) - { - perror(file); - return -1; - } - } - else - have += got; - } - - *(output + have) = 0; - return 0; -} - - - -/** - * Write an integer to a file - * - * @param buffer Buffer for temporary data - * @param integer The integer to write - * @param file The file to which to write - * @return Zero on success, non-zero on failure - */ -static int writefile(char* buffer, int integer, const char* file) -{ - FILE* f; - size_t n = 0; - - buffer += 32; - do - { - *(buffer - n++) = (char)((integer % 10) + '0'); - integer /= 10; - } - while (integer); - buffer -= n - 1; - *(buffer + n++) = '\n'; - - if ((f = fopen(file, "w")) == NULL) - { - perror(file); - return -1; - } - - if (fwrite(buffer, 1, n, f) != n) - { - perror(file); - fclose(f); - return -1; - } - - fflush(f); - fclose(f); - return 0; -} - - - -/** - * Print the status - * - * @param min The minimum possible brightness - * @param max The maximum possible brightness - * @param init The brightness used when the program started - * @param cur The current brightness - * @param cols The number of columns on the terminal - */ -static void bars(int min, int max, int init, int cur, int cols) -{ - int mid = (int)((float)(cur - min) * (float)(cols - 2) / (float)(max - min) + 0.5f); - - printf("\033[1000D\033[6A"); - printf("\033[2K┌%s┐\n", line); - *(space + mid) = 0; - printf("\033[2K│\033[47m%s\033[49m%s│\n", space, space + mid + 1); - *(space + mid) = ' '; - printf("\033[2K└%s┘\n", line); - printf("\033[2KMaximum brightness: %i\n", max); - printf("\033[2KInitial brightness: %i\n", init); - printf("\033[2KCurrent brightness: %i\n", cur); - - fflush(stdout); -} - |