#include #include #include #include #define BUF_SIZE 100 #define KBD_MAX_PATH "/sys/class/leds/tpacpi::kbd_backlight/max_brightness" #define KBD_BRIGHTNESS_PATH "/sys/class/leds/tpacpi::kbd_backlight/brightness" #define KBD_ERROR_ARGS -1 #define KBD_ERROR_MEM -2 #define KBD_SUCCESS 1 typedef enum direction { BL_DOWN, BL_UP, BL_OFF, BL_MAX } direction_t; int read_int(const char *path, int *value); int write_int(const char *path, int value); int bl_new(int current, int max, direction_t direction); void usage(const char *name); int get_direction(const char *str, direction_t *dir); int main(int argc, char *argv[]) { int bl_max = -1, bl_current = -1, bl; direction_t direction; if (argc < 2) { usage(argv[0]); return -1; } if (get_direction(argv[1], &direction) != KBD_SUCCESS) { fprintf(stderr, "E: Unexpected argument \"%s\"\n", argv[1]); usage(argv[0]); return 1; } if (read_int(KBD_MAX_PATH, &bl_max) != KBD_SUCCESS) { fprintf(stderr, "E: Failed to read maximum brightness from \"%s\"\n", KBD_MAX_PATH); usage(argv[0]); return 1; } if (read_int(KBD_BRIGHTNESS_PATH, &bl_current) != KBD_SUCCESS) { fprintf(stderr, "E: Failed to read current brightness from \"%s\"\n", KBD_BRIGHTNESS_PATH); usage(argv[0]); return 1; } bl = bl_new(bl_current, bl_max, direction); if (write_int(KBD_BRIGHTNESS_PATH, bl) != KBD_SUCCESS) { fprintf(stderr, "E: Failed to writing to \"%s\"\n", KBD_BRIGHTNESS_PATH); usage(argv[0]); return 1; } return 0; } int read_int(const char *path, int *value) { FILE *fp = fopen(path, "r"); int pos; if (fp == NULL) return KBD_ERROR_MEM; char buf[BUF_SIZE]; if (fread(buf, sizeof(char), BUF_SIZE, fp) == 0) return KBD_ERROR_MEM; int status = sscanf(buf, "%d%n", value, &pos); if (status == EOF || pos != 1) { return KBD_ERROR_MEM; } fclose(fp); return KBD_SUCCESS; } int write_int(const char *path, int value) { FILE *fp = fopen(path, "w"); if (fp == NULL) return KBD_ERROR_MEM; int status = fprintf(fp, "%d", value); if (status < 0) return KBD_ERROR_MEM; fclose(fp); return KBD_SUCCESS; } int bl_new(int current, int max, direction_t direction) { switch(direction) { case BL_DOWN: return (current == 0 ? 0 : current - 1); break; case BL_UP: return (current == max ? max : current + 1); break; case BL_OFF: return 0; break; case BL_MAX: return max; break; } return 0; } void usage(const char *name) { fprintf(stderr, "Usage: %s [up|down|off|max]\n", name); } int get_direction(const char *str, direction_t *dir) { if (strcmp(str, "up") == 0) { *dir = BL_UP; } else if (strcmp(str, "down") == 0) { *dir = BL_DOWN; } else if (strcmp(str, "off") == 0) { *dir = BL_OFF; } else if (strcmp(str, "max") == 0) { *dir = BL_MAX; } else { return KBD_ERROR_ARGS; } return KBD_SUCCESS; }