Skip to content

Commit 5956ba1

Browse files
authored
remarkable: fix button-listen when resuming from suspend (koreader#1145)
When the home button is used to wake the device from suspend the evdev events have surprising time stamps. There is a pair of press & release events, but the press has a timestamp from when the device went into suspend and the release has a timestamp from after. This means that the wake keypress will launch koreader as button-listen thinks the key was held down for the whole time the device was suspended! Instead, just record CLOCK_BOOTTIME timestamps for the events and use those instead of the event timestamps. CLOCK_BOOTTIME is monotonic but includes time spend in suspend. Also keep track of whether button-listen saw a key press before each key release. Probably not strictly required but seemed sensible to add.
1 parent 11ed619 commit 5956ba1

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

button-listen.c

+15-8
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
#include <stdio.h>
33
#include <time.h>
44
#include <stdlib.h>
5+
#include <stdbool.h>
56

6-
static double timeval_diff(struct timeval const* start, struct timeval const* end)
7+
static double timespec_diff(struct timespec const* start, struct timespec const* end)
78
{
8-
double s = (double)end->tv_sec - (double)start->tv_sec;
9-
double us = (double)end->tv_usec - (double)start->tv_usec;
10-
return s + (us / 1e6);
9+
double s = difftime(end->tv_sec, (double)start->tv_sec);
10+
double ns = (double)end->tv_nsec - (double)start->tv_nsec;
11+
return s + (ns / 1e9);
1112
}
1213

1314
int main(int argc, char** argv)
@@ -19,22 +20,28 @@ int main(int argc, char** argv)
1920
}
2021

2122
struct input_event ev;
22-
struct timeval press_stamp = {0};
23+
struct timespec press_time = {0};
24+
bool pressed = false;
2325
while(1) {
2426
size_t sz = fread(&ev, sizeof(ev), 1, evf);
2527
if(sz == 0) {
2628
return 1;
2729
}
2830
if(ev.type == EV_KEY && ev.code == KEY_HOME) {
29-
if(ev.value == 0) { /* keyrelease */
30-
double t = timeval_diff(&press_stamp, &ev.time);
31+
if(ev.value == 0 && pressed) { /* keyrelease */
32+
struct timespec now;
33+
clock_gettime(CLOCK_BOOTTIME, &now);
34+
double t = timespec_diff(&press_time, &now);
35+
/* Require a press event before processing another release */
36+
pressed = false;
3137
/* hold home (middle) button for 3 seconds to start koreader */
3238
if(t >= 3.0) {
3339
system("systemctl start koreader");
3440
}
3541
}
3642
else if(ev.value == 1) { /* keypress */
37-
press_stamp = ev.time;
43+
clock_gettime(CLOCK_BOOTTIME, &press_time);
44+
pressed = true;
3845
}
3946
}
4047
}

0 commit comments

Comments
 (0)