Initial support for backlight control on sleep, needs more work.
This commit is contained in:
1 parent
6847713826
commit
c771e2d2e6
1 file changed
+120
-12
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user