diff options
| author | Jasper | 2026-04-03 10:25:37 +0200 |
|---|---|---|
| committer | Jasper | 2026-04-03 10:25:37 +0200 |
| commit | 4d34dd39364c8e7ba3fa4fe14dc85630e1d6385c (patch) | |
| tree | 8e3fa48d697fc9e2c9ac598c4ba1c46f4b10f883 | |
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | README | 11 | ||||
| -rwxr-xr-x | build.sh | 3 | ||||
| -rw-r--r-- | kbd.c | 129 |
4 files changed, 144 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89f9ac0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +out/ @@ -0,0 +1,11 @@ +kbd +=== + +Manipulate keyboard backlight. Location of system data for the backlight might +have to be edited according to the device vendor. + +Requires sudo privileges. + +Usage +----- +$ kbd [up|down|off|max] diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..db822d8 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +gcc -Wall -Wextra kbd.c -o out/kbd @@ -0,0 +1,129 @@ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + +#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; +} |
