1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
// WTFPL
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/param.h>
#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);
}
uint64_t time_since_press(void) {
struct timeval now;
uint64_t now_usec;
uint64_t press_usec;
uint64_t diff;
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;
return diff;
}
void on_press(void) {
gettimeofday(last_press, NULL);
}
int light_thread(void) {
// check last_press vs time, do the thing
backlight_fp = fopen(BACKLIGHT_FILE, "w");
// FILE* backlight_fp = BACKLIGHT_FILE;
while (1) {
if (time_since_press() > BACKLIGHT_TIME) backlight_off();
else backlight_on();
usleep(THREAD_WAIT);
}
return 0;
}
int keypress_thread(void) {
FILE* fp = fopen(KEYBOARD_FILE, "r");
fseek(fp, 0, SEEK_END);
void* discard = malloc(KEYPRESS_SIZE);
while (1) {
fseek(fp, 0, SEEK_END);
fread(discard, 1, KEYPRESS_SIZE, fp);
on_press();
usleep(DEBOUNCE);
}
return 0;
}
void daemonize(void) {
daemon(0, 0);
}
int shared_mem_setup(void) {
last_press = mmap(NULL, sizeof(last_press), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
return 0; // XXX error handling
}
int setup(void) {
daemonize();
shared_mem_setup();
return 0;
}
int main(int argc, const char* argv[]) {
setup();
if (fork() == 0) return light_thread();
else return keypress_thread();
}
|