// control keyboard backlight on apple M1 // tested on macbook pro 2021 model and m1pro macbook model // works on xorg // to build it libx11-dev and libxext-dev are needed // on alpine linux next line will install then // #sudo apk add libx11-dev libxext-dev // build with next command // gcc -o kbd-bklght kbd-bklght.c -lX11 -lXext -lXss #include #include #include #include #include #include #include #include #include #include #include #include #include #include int GetIdleTime (void); void change (char *what); FILE * cbf; int max = 30; char cb[6]; int cbr; char LOGNAME[] = "kbd-bklght"; void INThandler(){ change("0"); exit(0); } void KILLhandler(){ change("0"); exit(0); } void TERMhandler(){ change("0"); exit(0); } void change (char *what) { cbf = fopen("/sys/class/leds//kbd_backlight/brightness", "w"); if (cbf == NULL) { printf("problem with open\n"); exit(EXIT_FAILURE); } fprintf(cbf, "%s", what); fclose(cbf); } int main(int argc, char **argv) { int option; int limit = 90; char brightness[4] = "30"; int timeout = 5; signal(SIGINT, INThandler); signal(SIGKILL, KILLhandler); signal(SIGTERM, TERMhandler); while ((option = getopt(argc, argv, "b:t:uh")) != -1) { switch (option) { case 'h': puts("help"); puts("-t timeout"); puts("-b brightness"); break; case 'b': sprintf(brightness, "%s", optarg); break; case 't': timeout = atoi(optarg); break; default: /* '?' */ puts("unknown option"); } } pid_t pid, sid; pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0); sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); } if ((chdir("/")) < 0) { exit(EXIT_FAILURE); } close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); while (1) { int idle = GetIdleTime(); if (idle > timeout) { cbf = fopen("/sys/class/leds//kbd_backlight/brightness", "r"); fgets(cb, 3, cbf); fclose(cbf); cbr = atoi(cb); printf("idle: %d\n", idle); change("0"); } else { change(brightness); } usleep(200000); //sleep(1); } exit(EXIT_SUCCESS); } int GetIdleTime () { time_t idle_time; static XScreenSaverInfo *mit_info; Display *display; int screen; mit_info = XScreenSaverAllocInfo(); if((display=XOpenDisplay(NULL)) == NULL) { return(-1); } screen = DefaultScreen(display); XScreenSaverQueryInfo(display, RootWindow(display,screen), mit_info); idle_time = (mit_info->idle) / 1000; XFree(mit_info); XCloseDisplay(display); return idle_time; }