From c771e2d2e69dcde230eaa4ca4f8dd45de441ebbc Mon Sep 17 00:00:00 2001 From: Igor Kolokolnikov Date: Fri, 25 Sep 2026 14:55:12 -0700 Subject: [PATCH] Initial support for backlight control on sleep, needs more work. --- slock.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 120 insertions(+), 12 deletions(-) diff --git a/slock.c b/slock.c index 51cf84c..8941ba6 100644 --- a/slock.c +++ b/slock.c @@ -19,6 +19,7 @@ #include /* mmap */ #include /* timerfd_create */ #include +#include /* opendir, closedir, readdir */ #include #include #include @@ -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; }