1 /**
2 * Kbd-fade fades keyboard led backlighting
3 * Copyright (C) 2019 Aaron Ball <nullspoon@oper.io>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21
22 #define COLORFILE "/sys/class/leds/system76::kbd_backlight/color_left"
23 #define COLORMAX 255
24 #define COLORSTEP 5
25
26
27 void writecolor(int r, int g, int b) {
28 FILE* fd;
29 fd = fopen(COLORFILE, "w");
30 fprintf(fd, "%02X%02X%02X\n", r, g, b);
31 fclose(fd);
32 }
33
34
35 /**
36 * load_current_state:
37 * Loads the current color state from the keyboard's sys file at
38 * /sys/class/leds/*kbd_backlight/..
39 *
40 * @r Pointer to red int buffer
41 * @g Pointer to green int buffer
42 * @b Pointer to blue int buffer
43 */
44 int load_current_state(int* r, int* g, int* b) {
45 char chan[3];
46 FILE* fd;
47
48 chan[3] = '\0';
49 fd = fopen(COLORFILE, "r");
50 if(!fd) {
51 *r = 0;
52 *g = 0;
53 *b = 0;
54 return 2;
55 }
56
57 chan[0] = fgetc(fd);
58 chan[1] = fgetc(fd);
59 *r = atoi(chan);
60
61 chan[0] = fgetc(fd);
62 chan[1] = fgetc(fd);
63 *g = atoi(chan);
64
65 chan[0] = fgetc(fd);
66 chan[1] = fgetc(fd);
67 *b = atoi(chan);
68
69 fclose(fd);
70 return 0;
71 }
72
73
74 /**
75 * channel_fade:
76 * Fades one color channel into another in one step.
77 *
78 * @a Pointer to A color channel buffer
79 * @b Pointer to B color channel buffer
80 */
81 void channel_fade(int* a, int* b) {
82 // Increase channel B with A maxed
83 if(*a <= COLORMAX) {
84 if(COLORMAX - *a >= COLORSTEP)
85 *a = *a + COLORSTEP;
86 else
87 *a = COLORMAX;
88 }
89
90 if(*b > 0) {
91 if(*b >= COLORSTEP)
92 *b = *b - COLORSTEP;
93 else
94 *b = 0;
95 }
96 }
97
98
99 /**
100 * rgb_fade:
101 * Infinite loop tha handles color fading
102 *
103 * @r Initialization value for red channel
104 * @b Initialization value for blue channel
105 * @g Initialization value for green channel
106 * @wait Wait time in milliseconds between steps
107 */
108 void rgb_fade(int r, int g, int b, int wait) {
109 int i = 0;
110 int highest = 0;
111 int colors[3] = {r, g, b};
112 int size = 3;
113
114 while(1) {
115 while(colors[i % size] < COLORMAX) {
116 channel_fade(&colors[i % size], &colors[(i + 1) % size]);
117 writecolor(colors[0], colors[1], colors[2]);
118 //printf("%02X %02X %02X\n", colors[0], colors[1], colors[2]);
119 usleep(wait * 1000);
120 }
121 i++;
122 }
123 }
124
125
126 int main(int argc, char* argv[]) {
127 int wait = 1000;
128 int r = 0;
129 int g = 0;
130 int b = 0;
131
132 //Set wait time between steps if specified
133 if(argc == 2)
134 wait = atoi(argv[1]);
135
136 load_current_state(&r, &g, &b);
137 rgb_fade(r, g, b, wait);
138 }
|