Initial support for backlight control on sleep, needs more work.

This commit is contained in:
ikolokolnikov committed 2026-09-25 14:55:12 -07:00
1 parent 6847713826
commit c771e2d2e6
1 file changed
+120 -12
+120 -12
View File
@@ -19,6 +19,7 @@
#include <sys/mman.h> /* mmap */
#include <sys/timerfd.h> /* timerfd_create */
#include <sys/types.h>
#include <dirent.h> /* opendir, closedir, readdir */
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/dpms.h>
#include <X11/keysym.h>
@@ -109,13 +110,13 @@ die(const char *errstr, ...)
exit(1);
}
int round_float_to_int(float real32)
static int round_float_to_int(float real32)
{
int result = (int)roundf(real32);
return result;
}
int str_len(const char *str)
static int str_len(const char *str)
{
int i = 0;
while(*(str++) != '\0') {
@@ -124,6 +125,29 @@ int str_len(const char *str)
return i;
}
static int str_contains(const char *str, const char *value)
{
int strlen, vallen, i, ii, matches;
strlen = str_len(str);
vallen = str_len(value);
matches = 0;
for(i = 0; i <= strlen-vallen && !matches; i++) {
for(ii = 0; ii < vallen; ii++) {
if(str[i+ii] == value[ii]) {
matches = 1;
} else {
matches = 0;
break;
}
}
}
return matches;
}
unsigned long long millis()
{
struct timespec ts;
@@ -603,6 +627,89 @@ static void dpms_enable(Display *dpy, struct dpms_state *state)
}
}
struct keyboard_backlight_state {
int available;
int brightness;
int fd;
};
static struct keyboard_backlight_state get_keyboard_backlight_state()
{
static char bl_entry[1024];
char *leds;
DIR *d;
struct keyboard_backlight_state bl_state;
memset(&bl_state, 0, sizeof(bl_state));
leds = "/sys/class/leds";
d = opendir(leds);
if(d) {
struct dirent *entry;
while((entry = readdir(d)) != 0) {
if(str_contains(entry->d_name, "kbd_backlight")) {
static char read_buf[32];
int fd;
snprintf(bl_entry, 1024,
"%s/%s/brightness", leds, entry->d_name);
fd = open(bl_entry, O_RDWR);
if(fd != -1) {
int read_amnt, s;
char *endptr;
long num;
read_amnt = 0;
do {
s = read(fd, read_buf+read_amnt, 32-read_amnt);
if(s == -1)
break;
read_amnt += s;
} while(s != 0);
if(s != -1) {
read_buf[read_amnt] = '\0';
num = strtol(read_buf, &endptr, 10);
if(!(errno == ERANGE || endptr == read_buf)) {
bl_state.available = 1;
bl_state.fd = fd;
bl_state.brightness = num;
}
}
}
break;
}
}
closedir(d);
}
return bl_state;
}
static void
reset_keyboard_backlight(struct keyboard_backlight_state *bl_state)
{
static char buf[512];
if(bl_state->available) {
snprintf(buf, sizeof(buf), "%d\n", bl_state->brightness);
write(bl_state->fd, buf, str_len(buf));
}
}
static void
set_keyboard_backlight_off(struct keyboard_backlight_state *bl_state)
{
if(bl_state->available) {
char buf[512];
snprintf(buf, sizeof(buf), "%d\n", 0);
write(bl_state->fd, buf, str_len(buf));
}
}
static void update_timerfd(int tfd)
{
time_t now;
@@ -623,7 +730,7 @@ static void update_timerfd(int tfd)
static void
readpw(struct arena *arena,
Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
const char *hash)
const char *hash, struct keyboard_backlight_state *bl_state)
{
XRRScreenChangeNotifyEvent *rre;
char buf[32], passwd[256], *inputhash;
@@ -653,12 +760,6 @@ readpw(struct arena *arena,
dpms_disable(dpy, &dpms_state);
FT_Library main_font_library;
FT_Face main_font_face;
FT_Library secondary_font_library;
FT_Face secondary_font_face;
if(!load_fonts(&fonts))
die("slock: load_fonts\n");
@@ -804,10 +905,13 @@ readpw(struct arena *arena,
}
}
if(dson)
if(dson) {
reset_keyboard_backlight(bl_state);
set_screen_on(dpy);
else
} else {
set_keyboard_backlight_off(bl_state);
set_screen_off(dpy);
}
render_screen(arena,
dpy, locks,
@@ -835,6 +939,7 @@ readpw(struct arena *arena,
if(ret == 0) {
dson = 0;
set_screen_off(dpy);
set_keyboard_backlight_off(bl_state);
} else if(ret > 0 && FD_ISSET(xfd, &fds)) {
} else if(ret > 0 && FD_ISSET(tfd, &fds)) {
}
@@ -1010,6 +1115,9 @@ main(int argc, char **argv) {
if (!DPMSQueryExtension(dpy, &event_base, &error_base))
die("slock: dpms extension is not supported\n");
struct keyboard_backlight_state bl_state =
get_keyboard_backlight_state();
/* drop privileges */
if (setgroups(0, NULL) < 0)
die("slock: setgroups: %s\n", strerror(errno));
@@ -1050,7 +1158,7 @@ main(int argc, char **argv) {
/* everything is now blank. Wait for the correct password */
struct arena arena = arena_init(bf, GB(1));
readpw(&arena, dpy, &rr, locks, nscreens, hash);
readpw(&arena, dpy, &rr, locks, nscreens, hash, &bl_state);
return 0;
}