initiated commitment
This commit is contained in:
commit
3299a68059
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
**/*.o
|
||||
sbl*
|
||||
tests/**
|
||||
!**/*.c
|
||||
!**/*.1
|
||||
|
25
LICENSE
Normal file
25
LICENSE
Normal file
@ -0,0 +1,25 @@
|
||||
GLWT(Good Luck With That) Public License
|
||||
Copyright (c) Everyone, except Author
|
||||
|
||||
Everyone is permitted to copy, distribute, modify, merge, sell, publish,
|
||||
sublicense or whatever they want with this software but at their OWN RISK.
|
||||
|
||||
Preamble
|
||||
|
||||
The author has absolutely no clue what the code in this project does.
|
||||
It might just work or not, there is no third option.
|
||||
|
||||
|
||||
GOOD LUCK WITH THAT PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION
|
||||
|
||||
0. You just DO WHATEVER YOU WANT TO as long as you NEVER LEAVE A
|
||||
TRACE TO TRACK THE AUTHOR of the original product to blame for or hold
|
||||
responsible.
|
||||
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Good luck and Godspeed.
|
27
README.md
Normal file
27
README.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Simple backlight
|
||||
Simple utility to change the backlight
|
||||
|
||||
## Features
|
||||
- Set the monitor to change
|
||||
- Save and restore backlight
|
||||
- Written in C99, that is a pro i guess...
|
||||
|
||||
## Getting
|
||||
Clone this repository, then use `make` to compile, `make install` and `make
|
||||
uninstall` to install and uninstall, finally `make clean` to remove all the
|
||||
compiled junk from the folder.
|
||||
|
||||
## Usage
|
||||
Here are some examples:
|
||||
|
||||
```sh
|
||||
# Increase brightness by 10% and save the changed brightness to $HOME/.savefile
|
||||
$ sbl -c $HOME/.savefile -S -i 10
|
||||
# Set the brightness to 30%
|
||||
$ sbl -s 30
|
||||
# Restore the saved backlight value from example 1
|
||||
$ sbl -c $HOME/.savefile -r
|
||||
# Forgot what does what?
|
||||
$ sbl -h
|
||||
```
|
||||
Read the man page for detailed instructions
|
25
makefile
Normal file
25
makefile
Normal file
@ -0,0 +1,25 @@
|
||||
CC ?= gcc
|
||||
CFLAGS = -Wall -pedantic --std=c99 -O2
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
sbl: sbl.c
|
||||
|
||||
dbg:
|
||||
gcc -O0 -g sbl.c -o sbl-dbg
|
||||
|
||||
install: sbl
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
cp -f sbl ${DESTDIR}${PREFIX}/bin/sbl
|
||||
chown root:root ${DESTDIR}${PREFIX}/bin/sbl
|
||||
chmod 4755 ${DESTDIR}${PREFIX}/bin/sbl
|
||||
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||
cp -f sbl.1 ${DESTDIR}${MANPREFIX}/man1/sbl.1
|
||||
chmod 644 ${DESTDIR}${MANPREFIX}/man1/sbl.1
|
||||
|
||||
uninstall:
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/sbl\
|
||||
${DESTDIR}${MANPREFIX}/man1/sbl.1
|
||||
|
||||
clean:
|
||||
rm -f sbl sbl-dbg
|
361
sbl.c
Normal file
361
sbl.c
Normal file
@ -0,0 +1,361 @@
|
||||
#define _DEFAULT_SOURCE
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <wordexp.h>
|
||||
#include <limits.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BACKLIGHT_ROOT_PATH "/sys/class/backlight/"
|
||||
#define BL_MIN 5
|
||||
|
||||
#define const_arr_size(val) ((int)(sizeof(val)/sizeof(val[0])))
|
||||
|
||||
const char *savefile_paths[] = {
|
||||
NULL, /* reserved for external savefile path */
|
||||
"/etc/sbl/savefile"
|
||||
};
|
||||
|
||||
enum action {
|
||||
DISPLAY, INCREASE, DECREASE, SET, RESTORE
|
||||
};
|
||||
|
||||
static uid_t ruid;
|
||||
int device_index = 0;
|
||||
|
||||
static void die (const char *, ...);
|
||||
static void usage (void);
|
||||
static void list_cards (void);
|
||||
static void set_brightness (float);
|
||||
static void change_permissions (const char *);
|
||||
static void restore_permissions (void);
|
||||
static int save_value (float);
|
||||
static int get_max_brightness (void);
|
||||
static float get_saved_value (void);
|
||||
static float get_current_brightness (void);
|
||||
static const char * backlight_path (int);
|
||||
static const char * get_savefile (void);
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int opc = 0, store = 0;
|
||||
enum action act = DISPLAY;
|
||||
float value = BL_MIN;
|
||||
char *extfile = NULL;
|
||||
/* Parse command line arguments */
|
||||
while ((opc = getopt(argc, argv, "c:hI:li:d:s:Sr")) != -1) {
|
||||
switch (opc) {
|
||||
case 'l':
|
||||
list_cards();
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
break;
|
||||
case 'c':
|
||||
extfile = malloc(strlen(optarg) + 1);
|
||||
if (!extfile)
|
||||
die("malloc in main():");
|
||||
strcpy(extfile, optarg);
|
||||
savefile_paths[0] = extfile;
|
||||
break;
|
||||
case 'I':
|
||||
device_index = atoi(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
act = INCREASE;
|
||||
value = atof(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
act = DECREASE;
|
||||
value = atof(optarg);
|
||||
break;
|
||||
case 's':
|
||||
act = SET;
|
||||
value = atof(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
act = RESTORE;
|
||||
break;
|
||||
case 'S':
|
||||
store = 1;
|
||||
break;
|
||||
default:
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ruid = getuid ();
|
||||
|
||||
switch (act) {
|
||||
case DISPLAY:
|
||||
printf("%.2f\n", get_current_brightness());
|
||||
break;
|
||||
case SET:
|
||||
set_brightness(value);
|
||||
break;
|
||||
case INCREASE:
|
||||
value += get_current_brightness();
|
||||
set_brightness(value);
|
||||
break;
|
||||
case DECREASE:
|
||||
value = get_current_brightness() - value;
|
||||
set_brightness(value);
|
||||
break;
|
||||
case RESTORE:
|
||||
set_brightness(get_saved_value());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (store)
|
||||
save_value(get_current_brightness());
|
||||
|
||||
if (extfile)
|
||||
free(extfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int save_value (float value)
|
||||
{
|
||||
FILE *fd;
|
||||
fd = fopen(get_savefile(), "w");
|
||||
if (!fd)
|
||||
die("could not open savefile");
|
||||
fprintf(fd, "%f\n", value);
|
||||
fclose(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
float get_saved_value (void)
|
||||
{
|
||||
FILE *fd;
|
||||
float rtf = -1;
|
||||
fd = fopen(get_savefile(), "r");
|
||||
if (!fd)
|
||||
die("could not open savefile");
|
||||
fscanf(fd, "%f", &rtf);
|
||||
fclose(fd);
|
||||
return rtf;
|
||||
}
|
||||
|
||||
float get_current_brightness (void)
|
||||
{
|
||||
FILE *fd;
|
||||
char buf[PATH_MAX] = {0};
|
||||
int cb = -1;
|
||||
const char *path = backlight_path(device_index);
|
||||
if (!path)
|
||||
die("invalid device index");
|
||||
strcpy(buf, path);
|
||||
strcat(buf, "/brightness");
|
||||
fd = fopen(buf, "r");
|
||||
if (!fd)
|
||||
die("could not open %s", buf);
|
||||
fscanf(fd, "%d", &cb);
|
||||
fclose(fd);
|
||||
|
||||
return ((float)cb / (float)get_max_brightness()) * 100.0;;
|
||||
}
|
||||
|
||||
int get_max_brightness (void)
|
||||
{
|
||||
FILE *fd;
|
||||
char buf[PATH_MAX] = {0};
|
||||
int rti = -1;
|
||||
const char *path = backlight_path(device_index);
|
||||
if (!path)
|
||||
die("invalid device index");
|
||||
strcpy(buf, path);
|
||||
strcat(buf, "/max_brightness");
|
||||
fd = fopen(buf, "r");
|
||||
if (!fd)
|
||||
die("could not open %s", buf);
|
||||
fscanf(fd, "%d", &rti);
|
||||
fclose(fd);
|
||||
|
||||
return rti;
|
||||
}
|
||||
|
||||
/* Return the correct savefile path, creating it if it does not exist */
|
||||
const char * get_savefile (void)
|
||||
{
|
||||
static char buf[PATH_MAX];
|
||||
wordexp_t result = {0};
|
||||
FILE *fd;
|
||||
|
||||
for (int i = 0; i < const_arr_size(savefile_paths); i++) {
|
||||
if (!savefile_paths[i])
|
||||
continue;
|
||||
switch (wordexp(savefile_paths[i], &result, 0)) {
|
||||
case 0:
|
||||
break;
|
||||
case WRDE_NOSPACE:
|
||||
wordfree (&result);
|
||||
die("Not enough space");
|
||||
default:
|
||||
die("Path not valid");
|
||||
}
|
||||
|
||||
strcpy(buf, result.we_wordv[0]);
|
||||
if ((fd = fopen(result.we_wordv[0], "r")))
|
||||
break;
|
||||
}
|
||||
/* Create a savefile */
|
||||
if (!fd) {
|
||||
wordfree(&result);
|
||||
for (int i = 0; i < const_arr_size(savefile_paths); i++) {
|
||||
if (!savefile_paths[i])
|
||||
continue;
|
||||
switch (wordexp(savefile_paths[i], &result, 0)) {
|
||||
case 0:
|
||||
break;
|
||||
case WRDE_NOSPACE:
|
||||
wordfree (&result);
|
||||
die("Not enough space");
|
||||
default:
|
||||
die("Path not valid");
|
||||
}
|
||||
|
||||
strcpy(buf, result.we_wordv[0]);
|
||||
if ((fd = fopen(result.we_wordv[0], "w")))
|
||||
break;
|
||||
}
|
||||
}
|
||||
wordfree(&result);
|
||||
if (!fd)
|
||||
die("could not open or create a savefile");
|
||||
fclose(fd);
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char * backlight_path (int index)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *de;
|
||||
static char buf[PATH_MAX];
|
||||
|
||||
memset(buf, 0, PATH_MAX);
|
||||
if (index < 0)
|
||||
die("%d is not a valid index", index);
|
||||
if (!(dp = opendir(BACKLIGHT_ROOT_PATH)))
|
||||
die("error opening " BACKLIGHT_ROOT_PATH);
|
||||
|
||||
errno = 0;
|
||||
while ((de = readdir(dp))) {
|
||||
if (!(de->d_type & DT_LNK))
|
||||
continue;
|
||||
if (index) {
|
||||
index--;
|
||||
continue;
|
||||
} else {
|
||||
strcpy(buf, BACKLIGHT_ROOT_PATH);
|
||||
strcat(buf, de->d_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
if (errno)
|
||||
die("error reading " BACKLIGHT_ROOT_PATH);
|
||||
// FIXME: actually check return value of this
|
||||
if (!buf[0])
|
||||
return NULL;
|
||||
return buf;
|
||||
|
||||
}
|
||||
|
||||
void list_cards (void)
|
||||
{
|
||||
int i = 0;
|
||||
const char *s;
|
||||
for (; (s = backlight_path(i)); i++)
|
||||
printf("%d: %s\n", i, s);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void set_brightness (float value)
|
||||
{
|
||||
int set;
|
||||
char buf[PATH_MAX] = {0};
|
||||
const char *path = backlight_path(device_index);
|
||||
FILE *fd;
|
||||
if (value > 100)
|
||||
value = 100;
|
||||
if (value < BL_MIN)
|
||||
value = BL_MIN;
|
||||
set = (value/100.0) * get_max_brightness();
|
||||
if (set < 0)
|
||||
return;
|
||||
if (!path)
|
||||
die("invalid device index");
|
||||
strcpy(buf, path);
|
||||
strcat(buf, "/brightness");
|
||||
change_permissions(buf);
|
||||
fd = fopen(buf, "w");
|
||||
if (!fd)
|
||||
die("could not open %s", buf);
|
||||
fprintf(fd, "%d", set);
|
||||
fclose(fd);
|
||||
restore_permissions();
|
||||
}
|
||||
|
||||
/* Change the process permissions matching the ones pointed by path */
|
||||
void change_permissions (const char *path)
|
||||
{
|
||||
int status;
|
||||
struct stat st;
|
||||
|
||||
stat(path, &st);
|
||||
status = seteuid(st.st_uid);
|
||||
if (status < 0)
|
||||
die("could not setuid");
|
||||
}
|
||||
|
||||
static void restore_permissions (void)
|
||||
{
|
||||
int status;
|
||||
status = seteuid(ruid);
|
||||
if (status < 0)
|
||||
die("could not setuid");
|
||||
}
|
||||
|
||||
void die(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
vfprintf(stderr, fmt, ap);
|
||||
|
||||
if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
|
||||
fputc(' ', stderr);
|
||||
perror(NULL);
|
||||
} else {
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
exit(errno ? errno : 1);
|
||||
}
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
puts("Usage: sbl [-hlrS] [-c savefile] [-I index] [-i/d/s percent]\n"
|
||||
"-h print this message\n"
|
||||
"-l list devices by index\n"
|
||||
"-r restore saved value\n"
|
||||
"-S save value\n"
|
||||
"-c savefile specify savefile\n"
|
||||
"-I index specify device by index\n"
|
||||
"-i percent increase backlight by percent\n"
|
||||
"-d percent decrease backlight by percent\n"
|
||||
"-s percent set backlight to percent\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
Loading…
Reference in New Issue
Block a user