Last active
July 25, 2020 04:57
-
-
Save emctague/d8e2f928c135d929b8301a239e007559 to your computer and use it in GitHub Desktop.
brightness.c (like xbacklight, except it actually works for me)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* brightness.c - Because xbacklight doesn't work for me. | |
* Features: Cubic ease-in-out interpolation of brightness over time. | |
* | |
* Currently works with a single target device from /sys/class/backlight. | |
* Previously only worked on intel_backlight, has since been adapted to search | |
* for the proper controller. | |
* | |
* Ethan McTague <[email protected]> - January 28, 2018 | |
* Public domain - free to use/modify without any restrictions. | |
* | |
* gcc brightness.c -o brightness -lm | |
* sudo install -m a=rxs brightness /usr/local/bin | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <math.h> | |
#include <unistd.h> | |
#include <dirent.h> | |
#define TARGET_DIR "/sys/class/backlight/" | |
#define BUF_SIZE 500 | |
// Cubic bezier (ctrl points c1, c2 + anchor points a1, a2 + time u). | |
float | |
cubic_bezier (float u, float c1, float c2, float a1, float a2) | |
{ | |
return pow(u, 3) * (a2 + 3 * (c1 - c2) - a1) + 3 * pow(u, 2) | |
* (a1 - 2 * c1 + c2) + 3 * u * (c1 - a1) + a1; | |
} | |
// Ease-in-out bezier (range: 0 to 1). | |
float | |
ease_in_out (float u) | |
{ | |
return cubic_bezier(u, .42, .58, 0, 1); | |
} | |
// Interpolate linearly between two values. | |
float | |
interpolate (float u, float a, float b) { | |
return a + u * (b - a); | |
} | |
int | |
main (int argc, char* argv[]) | |
{ | |
// Complain if no value provided. | |
if (argc != 2) | |
{ | |
fprintf(stderr, | |
"Usage: %s [+/-][value]\n\n" | |
"Ethan McTague <[email protected]> - January 28, 2018\n" | |
"Public domain - free to use/modify without any restrictions.\n", | |
argv[0]); | |
return 1; | |
} | |
// Read the backlights directory to find the appropriate backlight controller. | |
DIR* dir = opendir(TARGET_DIR); | |
if (dir == NULL) | |
{ | |
fprintf(stderr, "Could not open %s for file listing.\n", TARGET_DIR); | |
return 2; | |
} | |
// Skip over '.' and '..'. | |
readdir(dir); readdir(dir); | |
// Complain if there aren't any backlights to control. | |
struct dirent *ent = readdir(dir); | |
if (ent == NULL || (ent->d_type != DT_DIR && ent->d_type != DT_LNK)) | |
{ | |
fprintf(stderr, "No subdirectories in %s.\n", TARGET_DIR); | |
return 3; | |
} | |
// Write the target paths. | |
char target_out[BUF_SIZE]; | |
char target_max[BUF_SIZE]; | |
snprintf(target_out, BUF_SIZE, TARGET_DIR "%s/brightness", ent->d_name); | |
snprintf(target_max, BUF_SIZE, TARGET_DIR "%s/max_brightness", ent->d_name); | |
closedir(dir); | |
// Get value from first argument. | |
int newval = atoi(argv[1]); | |
// Get original value for smooth and relative. | |
int orig; | |
FILE* cur = fopen(target_out, "r"); | |
if (cur == NULL) | |
{ | |
fprintf(stderr, "Could not open %s for reading.\n", target_out); | |
return 2; | |
} | |
fscanf(cur, "%d", &orig); | |
fclose(cur); | |
// Relative positioning if '+' or '-' prefix is used. | |
if (argv[1][0] == '+' || argv[1][0] == '-') | |
newval = orig + newval; | |
// Read maximum brightness. | |
int max; | |
FILE* maxin = fopen(target_max, "r"); | |
if (maxin == NULL) | |
{ | |
fprintf(stderr, "Could not open %s for reading.\n", target_max); | |
return 3; | |
} | |
fscanf(maxin, "%d", &max); | |
fclose(maxin); | |
// Clamp within valid range (and avoid 0 despite it being valid.) | |
if (newval < 1) newval = 1; | |
if (newval > max) newval = max; | |
// Repeatedly quickly adjust brightness over time for a nice smooth change. | |
for (float n = 0; n < 1; n += 0.01) | |
{ | |
usleep(5000); | |
// Save to output file. | |
FILE* out = fopen(target_out, "w"); | |
if (out == NULL) | |
{ | |
fprintf(stderr, "Could not open %s for writing.\n", target_out); | |
return 4; | |
} | |
float ival = interpolate(ease_in_out(n), (float)orig, (float)newval); | |
fprintf(out, "%d", (int)ival); | |
fclose(out); | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
gcc brightness.c -o brightness -lm | |
sudo install -m a=rxs brightness /usr/local/bin |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment