From 51594f0fda8157236bd20dadddf2fa53f7909b9b Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Mon, 14 Jan 2013 00:05:50 +0000 Subject: [PATCH] Add support for keyboard backlight on Apple laptops Use the command line option --apple to turn on the automatic keyboard backlight management. If the light sensor detects a dark environment (sensor value <=3) the keyboard backlight is turned on to maximum brightness and to minimum otherwise. Most of the code is from 'lightum'. Signed-off-by: Carlos R. Mafra --- Makefile | 6 ++-- src/apple.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/apple.h | 3 ++ src/event.c | 49 +++++++++++++++++++++++++----- src/main.c | 5 ++++ src/main.h | 3 ++ 6 files changed, 154 insertions(+), 11 deletions(-) create mode 100644 src/apple.c create mode 100644 src/apple.h diff --git a/Makefile b/Makefile index cd9c5e3..299c750 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,9 @@ INSTALLDIR = /usr/local/bin/ CC = gcc LIBDIR = -L/usr/X11R6/lib -LIBS = -lXpm -lXext -lX11 -lXss -CFLAGS = -Wall -g -OBJS = main.o init.o event.o draw.o battery.o cpu.o autoscript.o pixmap.o +LIBS = `pkg-config --libs dbus-1 --libs dbus-glib-1` -lXpm -lXext -lX11 -lXss +CFLAGS = `pkg-config --cflags dbus-1 --cflags dbus-glib-1` -Wall -g +OBJS = main.o init.o event.o draw.o battery.o cpu.o autoscript.o pixmap.o apple.o EXE = wmlaptop2 diff --git a/src/apple.c b/src/apple.c new file mode 100644 index 0000000..fd3d66d --- /dev/null +++ b/src/apple.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int get_light_sensor_value(void) +{ + + int fd; + size_t i,n=0; + char buf[10]; + char a_light[10]; + const char *light_sensor="/sys/devices/platform/applesmc.768/light"; + ssize_t cnt; + + /* read light sensor value */ + fd = open(light_sensor, O_RDONLY); + if (fd < 0) { + perror(light_sensor); + fprintf(stderr, "Can't open %s\n", light_sensor); + exit(1); + } + cnt = read(fd, buf, sizeof(buf)-1); + buf[cnt] = '\0'; + close(fd); + + /* convert light sensor string value to integer */ + for (i = 0; buf[i] != '\0'; i++) { + if (buf[i] == ',') + break; + if (buf[i] != '(') { + a_light[n] = buf[i]; + n++; + } + } + a_light[n] = '\0'; + + return atoi(a_light); +} + +int set_keyboard_brightness_value(int brightness) +{ + + DBusConnection *connection; + DBusError error; + DBusMessage *message; + DBusMessageIter iter; + DBusBusType type; + + const char *name = NULL; + char arg[] = "org.freedesktop.UPower.KbdBacklight.SetBrightness"; + name = arg; + const char *dest = "org.freedesktop.UPower"; + const char *path = "/org/freedesktop/UPower/KbdBacklight"; + + type = DBUS_BUS_SYSTEM; + + dbus_error_init(&error); + connection = dbus_bus_get(type, &error); + + if (connection == NULL) { + fprintf (stderr, "Failed to open connection to message bus: %s\n", error.message); + dbus_error_free(&error); + return (-1); + } + + char *last_dot; + last_dot = strrchr(name, '.'); + *last_dot = '\0'; + + message = dbus_message_new_method_call(NULL, path, name, last_dot + 1); + dbus_message_set_auto_start(message, TRUE); + + if (message == NULL) { + fprintf (stderr, "Couldn't allocate D-Bus message\n"); + return (-1); + } + + if (dest && !dbus_message_set_destination (message, dest)) { + fprintf (stderr, "Not enough memory\n"); + return (-1); + } + + dbus_message_iter_init_append(message, &iter); + + dbus_int32_t int32; + int32 = brightness; + dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &int32); + + dbus_connection_send(connection, message, NULL); + dbus_connection_flush(connection); + dbus_message_unref(message); + dbus_connection_unref(connection); + return 0; +} diff --git a/src/apple.h b/src/apple.h new file mode 100644 index 0000000..a63d0d0 --- /dev/null +++ b/src/apple.h @@ -0,0 +1,3 @@ +int get_keyboard_brightness_value(void); +int get_light_sensor_value(void); +int set_keyboard_brightness_value(int brightness); diff --git a/src/event.c b/src/event.c index 72337b1..6d587ab 100644 --- a/src/event.c +++ b/src/event.c @@ -15,6 +15,7 @@ */ #include "event.h" +#include "apple.h" void event_handler() { @@ -24,7 +25,7 @@ void event_handler() u_int32 tempUpdate = args_tempUpdate; u_int32 sessionIdle = args_sessionIdle; u_int8 lastPercentage; - int j, once = 0; + int j, lcd_brightness = 100, brightness = 0; /* initial state assumptions: lcd 100%, keyboard 0% */ secondsCounter = time(NULL); update_seconds = time(NULL); @@ -85,17 +86,49 @@ void event_handler() read_power(); } - if (get_session_idle_time(display) >= sessionIdle && !powerState.isCharging) { - if (once == 0) { - system("xbacklight -set 20"); + if (!powerState.isCharging) { + if (get_session_idle_time(display) >= sessionIdle) { printf("Idle more than %d secs\n", sessionIdle); - once = 1; + + if (lcd_brightness != 20) { + system("xbacklight -set 20"); + lcd_brightness = 20; + } + + if (apple == 1 && brightness == 255) { + set_keyboard_brightness_value(0); + brightness = 0; + printf("Turning off keyboard backlight due to inactivity\n"); + } + } else { + /* There's activity. Turn on lights even though on battery */ + if (lcd_brightness != 100) { + system("xbacklight -set 100"); + lcd_brightness = 100; + printf("Restoring backlight\n"); + } + if (apple == 1 && brightness == 0 && get_light_sensor_value() <= 3) { + set_keyboard_brightness_value(255); + brightness = 255; + printf("Turning on keyboard backlight\n"); + } } } else { - if (once == 1) { + /* plugged in, no worries about saving power */ + if (lcd_brightness != 100){ system("xbacklight -set 100"); - printf("Restoring backlight\n"); - once = 0; + lcd_brightness = 100; + printf("Plugged in, maximum brightness!\n"); + } + if (apple == 1 && brightness == 0 && get_light_sensor_value() <= 3) { + set_keyboard_brightness_value(255); + brightness = 255; + printf("Turning on keyboard backlight\n"); + } + if (apple == 1 && brightness == 255 && get_light_sensor_value() > 3) { + set_keyboard_brightness_value(0); + brightness = 0; + printf("Enough light, turning off keyboard backlight\n"); } } diff --git a/src/main.c b/src/main.c index 5b10154..b9485c7 100644 --- a/src/main.c +++ b/src/main.c @@ -42,6 +42,7 @@ struct power_str powerState; bool args_dontBlink100 = ARGSDEF_DONTBLINK100; double powerrate = 1; double cap_total = 0; + int apple = 0; /* X stuff */ struct mouseRegion mouse_region[MAX_MOUSE_REGION]; @@ -172,6 +173,10 @@ void setArgs(int argc, char **argv) args_dontBlink100 = true; continue; } + if(!strcmp(argv[i], "--apple")){ + apple = 1; + continue; + } if(!strncmp(argv[i], "--auto-shutdown=", 16)) { EXIT_IF_ALREADY_SET( args_autoShutdown, AUTOSHUTDOWN_LEAVE, "autoShutDown" ); if(!strcmp( &argv[i][16], "off")) diff --git a/src/main.h b/src/main.h index 9631c2d..f74fe25 100644 --- a/src/main.h +++ b/src/main.h @@ -342,6 +342,9 @@ extern bool args_dontBlink100; #endif extern bool args_beQuiet; +/* use keyboard backlight control on apple laptops */ +extern int apple; + /* macros */ #define EXIT_IF_ALREADY_SET( arg, set, name ) \ \ -- 2.11.4.GIT