// WTFPL #include #include #include #include #include #include #include #define MS * 1000 #define SEC * 1000000 #define DEBOUNCE (10 MS) #define THREAD_WAIT (100 MS) #define BACKLIGHT_TIME (10 SEC) #define BACKLIGHT_FADE_FRAMETIME (50 MS) #define BACKLIGHT_FADE_TIME (1000 MS) #define BACKLIGHT_FADE_STEPS (BACKLIGHT_FADE_TIME / BACKLIGHT_FADE_FRAMETIME) #define KEYPRESS_SIZE 72 #define KEYBOARD_FILE "/dev/input/event1" #define BACKLIGHT_FILE "/sys/class/leds/keyboard_light/brightness" //#define BACKLIGHT_FILE stdout #define MAX_BRIGHTNESS 255 static struct timeval* last_press; static uint32_t curr_brightness; static FILE* backlight_fp; void write_to_backlight(int n) { fprintf(backlight_fp, "%d", n); fflush(backlight_fp); curr_brightness = n; } #if 0 void backlight_fade(void) { short brightness_step = MAX_BRIGHTNESS / BACKLIGHT_FADE_STEPS; short* brightness = malloc(sizeof(short)); *brightness = MAX_BRIGHTNESS; fprintf(stderr, "ha, gay\n"); do { fprintf(stderr, "%d %d %d\n", *brightness, brightness_step, 0); write_to_backlight(*brightness); *brightness -= brightness_step; usleep(BACKLIGHT_FADE_FRAMETIME); } while (*brightness >= brightness_step); } #endif void backlight_off(void) { if (curr_brightness == 0) return; write_to_backlight(0); // backlight_fade(); } void backlight_on(void) { curr_brightness = MAX_BRIGHTNESS; write_to_backlight(MAX_BRIGHTNESS); usleep(BACKLIGHT_TIME); } void light_thread(void) { // check last_press vs time, do the thing backlight_fp = fopen(BACKLIGHT_FILE, "w"); // FILE* backlight_fp = BACKLIGHT_FILE; struct timeval now; uint64_t now_usec; uint64_t press_usec; uint64_t diff; while (1) { gettimeofday(&now, NULL); now_usec = now.tv_sec * 1000000L; now_usec += now.tv_usec; press_usec = last_press->tv_sec * 1000000L; press_usec += last_press->tv_usec; diff = now_usec - press_usec; if (diff > BACKLIGHT_TIME) backlight_off(); else backlight_on(); usleep(THREAD_WAIT); fflush(stdout); } } void on_press(void) { gettimeofday(last_press, NULL); } void daemonize(void) { daemon(0, 0); } int main(int argc, const char* argv[]) { FILE* fp = fopen(KEYBOARD_FILE, "r"); fseek(fp, 0, SEEK_END); void* discard = malloc(KEYPRESS_SIZE); // shared mem b/c new proc doesn't share mem space last_press = mmap(NULL, sizeof(last_press), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (fork() == 0) { daemonize(); light_thread(); } else daemonize(); while (1) { fseek(fp, 0, SEEK_END); fread(discard, 1, KEYPRESS_SIZE, fp); on_press(); usleep(DEBOUNCE); } return 0; }