/** * Kbd-fade fades keyboard led backlighting * Copyright (C) 2019 Aaron Ball * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #define COLORFILE "/sys/class/leds/system76::kbd_backlight/color_left" #define COLORMAX 255 #define COLORSTEP 5 void writecolor(int r, int g, int b) { FILE* fd; fd = fopen(COLORFILE, "w"); fprintf(fd, "%02X%02X%02X\n", r, g, b); fclose(fd); } /** * load_current_state: * Loads the current color state from the keyboard's sys file defined with * COLORFILE * * @r Pointer to red int buffer * @g Pointer to green int buffer * @b Pointer to blue int buffer */ int load_current_state(int* r, int* g, int* b) { char chan[3]; FILE* fd; chan[3] = '\0'; fd = fopen(COLORFILE, "r"); if(!fd) { *r = 0; *g = 0; *b = 0; return 2; } chan[0] = fgetc(fd); chan[1] = fgetc(fd); *r = strtol(chan, NULL, 16); chan[0] = fgetc(fd); chan[1] = fgetc(fd); *g = strtol(chan, NULL, 16); chan[0] = fgetc(fd); chan[1] = fgetc(fd); *b = strtol(chan, NULL, 16); fclose(fd); return 0; } /** * channel_fade: * Fades one color channel into another in one step. * * @a Pointer to A color channel buffer * @b Pointer to B color channel buffer */ void channel_fade(int* a, int* b) { // Increase channel B with A maxed if(*a <= COLORMAX) { if(COLORMAX - *a >= COLORSTEP) *a = *a + COLORSTEP; else *a = COLORMAX; } if(*b > 0) { if(*b >= COLORSTEP) *b = *b - COLORSTEP; else *b = 0; } } /** * rgb_fade: * Infinite loop tha handles color fading * * @r Initialization value for red channel * @b Initialization value for blue channel * @g Initialization value for green channel * @wait Wait time in milliseconds between steps */ void rgb_fade(int r, int g, int b, int wait) { int i = 0; int colors[3] = {r, g, b}; int size = 3; while(1) { while(colors[i % size] < COLORMAX) { channel_fade(&colors[i % size], &colors[(i + 1) % size]); writecolor(colors[0], colors[1], colors[2]); //printf("%02X %02X %02X\n", colors[0], colors[1], colors[2]); usleep(wait * 1000); } i++; } } int main(int argc, char* argv[]) { int wait = 1000; int r = 0; int g = 0; int b = 0; //Set wait time between steps if specified if(argc == 2) wait = atoi(argv[1]); if(wait < 1) { printf("Error setting wait. Defaulting to 1000\n"); wait=1000; } load_current_state(&r, &g, &b); rgb_fade(r, g, b, wait); }