Created
July 16, 2014 14:00
-
-
Save Tasssadar/3e2805d7ca4b7a40b00b to your computer and use it in GitHub Desktop.
Small program for kindle paperwhite 2 which tracks touch events and shows battery percentage on screen when the user double taps on the bottom of the screen.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <linux/input.h> | |
#include <string.h> | |
#include <dirent.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <sys/poll.h> | |
#include <sys/time.h> | |
#include <stdint.h> | |
#define MAX_DEVICES 10 | |
#define MAX_FINGERS 10 | |
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) | |
enum | |
{ | |
TCHNG_POS = 0x01, | |
//TCHNG_PRESSURE = 0x02, // unused | |
TCHNG_ADDED = 0x04, | |
TCHNG_REMOVED = 0x08 | |
}; | |
typedef struct | |
{ | |
int id; | |
int x; | |
int y; | |
int changed; | |
int consumed; | |
struct timeval time; | |
int64_t us_diff; | |
} touch_event; | |
static touch_event mt_events[MAX_FINGERS]; | |
static struct pollfd ev_fds[MAX_DEVICES]; | |
static unsigned ev_count = 0; | |
static int mt_slot = 0; | |
static int ev_init() | |
{ | |
DIR *dir; | |
struct dirent *de; | |
int fd; | |
dir = opendir("/dev/input"); | |
if(!dir) | |
return -1; | |
while((de = readdir(dir))) | |
{ | |
if(strncmp(de->d_name,"event",5)) | |
continue; | |
fd = openat(dirfd(dir), de->d_name, O_RDONLY); | |
if(fd < 0) | |
continue; | |
ev_fds[ev_count].fd = fd; | |
ev_fds[ev_count].events = POLLIN; | |
ev_count++; | |
if(ev_count == MAX_DEVICES) | |
break; | |
} | |
closedir(dir); | |
return 0; | |
} | |
static int ev_get(struct input_event *ev, unsigned dont_wait) | |
{ | |
int r; | |
unsigned n; | |
do | |
{ | |
r = poll(ev_fds, ev_count, dont_wait ? 0 : -1); | |
if(r <= 0) | |
continue; | |
for(n = 0; n < ev_count; n++) | |
{ | |
if(ev_fds[n].revents & POLLIN) | |
{ | |
r = read(ev_fds[n].fd, ev, sizeof(*ev)); | |
if(r == sizeof(*ev)) | |
return 0; | |
} | |
} | |
} | |
while(dont_wait == 0); | |
return -1; | |
} | |
static inline int64_t get_us_diff(struct timeval now, struct timeval prev) | |
{ | |
return ((int64_t)(now.tv_sec - prev.tv_sec))*1000000+ | |
(now.tv_usec - prev.tv_usec); | |
} | |
static void handle_abs_event(struct input_event *ev) | |
{ | |
switch(ev->code) | |
{ | |
case ABS_MT_SLOT: | |
if(ev->value < (int)ARRAY_SIZE(mt_events)) | |
mt_slot = ev->value; | |
break; | |
case ABS_MT_TRACKING_ID: | |
{ | |
if(ev->value != -1) | |
{ | |
mt_events[mt_slot].id = ev->value; | |
mt_events[mt_slot].changed |= TCHNG_ADDED; | |
} | |
else | |
mt_events[mt_slot].changed |= TCHNG_REMOVED; | |
break; | |
} | |
case ABS_MT_POSITION_X: | |
case ABS_MT_POSITION_Y: | |
{ | |
if(ev->code == ABS_MT_POSITION_X) | |
mt_events[mt_slot].x = ev->value; | |
else | |
mt_events[mt_slot].y = ev->value; | |
mt_events[mt_slot].changed |= TCHNG_POS; | |
break; | |
} | |
} | |
} | |
static void handle_touch_event(touch_event *ev) | |
{ | |
static struct timeval last_time = { 0, 0 }; | |
// show battery percentage after double tap on the bottom of the screen | |
if(!(ev->changed & TCHNG_REMOVED) || ev->y < 975) | |
return; | |
if(get_us_diff(ev->time, last_time) < 1500000) | |
{ | |
pid_t pid = fork(); | |
if(pid == 0) | |
{ | |
char buff[32] = { 0 }; | |
strcpy(buff, "Battery: "); | |
FILE *f = fopen("/sys/devices/system/wario_battery/wario_battery0/battery_capacity", "r"); | |
if(f) | |
{ | |
fgets(buff + 9, sizeof(buff) - 9, f); | |
fclose(f); | |
} | |
execl("/usr/sbin/eips", "/usr/sbin/eips", "17", "41", buff, (char*)NULL); | |
exit(0); | |
} | |
} | |
last_time = ev->time; | |
} | |
static void handle_syn_event(struct input_event *ev) | |
{ | |
if(ev->code != SYN_REPORT) | |
return; | |
uint32_t i; | |
touch_event *tev; | |
for(i = 0; i < ARRAY_SIZE(mt_events); ++i) | |
{ | |
tev = &mt_events[i]; | |
tev->us_diff = get_us_diff(ev->time, tev->time); | |
tev->time = ev->time; | |
if(!tev->changed) | |
continue; | |
//printf("event %02d flags 0x%02X, [%d; %d]\n", tev->id, tev->changed, tev->x, tev->y); | |
handle_touch_event(tev); | |
tev->consumed = 0; | |
tev->changed = 0; | |
} | |
} | |
int main(void) | |
{ | |
struct input_event ev; | |
ev_init(); | |
while(1) | |
{ | |
ev_get(&ev, 0); | |
switch(ev.type) | |
{ | |
case EV_ABS: | |
handle_abs_event(&ev); | |
break; | |
case EV_SYN: | |
handle_syn_event(&ev); | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment