#include #include #include #include #include #include #include #include #include #include "touch.h" static int find_dev() { int err; int ret = -1; DIR *dir = opendir("/dev/input"); assert(dir); struct dirent* de = NULL; while ((de = readdir(dir))) { if (strncmp(de->d_name, "event", 5)) continue; int fd = openat(dirfd(dir), de->d_name, O_RDONLY); assert(fd >= 0); unsigned char ev_bits[KEY_MAX / 8 + 1]; err = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(ev_bits)), ev_bits); assert(err >= 0); const int x_key = ABS_MT_POSITION_X / 8; const int y_key = ABS_MT_POSITION_Y / 8; if ((ev_bits[x_key] & (ABS_MT_POSITION_X - x_key)) && (ev_bits[y_key] & (ABS_MT_POSITION_Y - y_key))) { ret = fd; break; } close(fd); } closedir(dir); return ret; } void touch_init(TouchState *s) { s->fd = find_dev(); assert(s->fd >= 0); } int touch_poll(TouchState *s, int* out_x, int* out_y, int timeout) { assert(out_x && out_y); bool up = false; while (true) { struct pollfd polls[] = {{ .fd = s->fd, .events = POLLIN, }}; int err = poll(polls, 1, timeout); if (err < 0) { return -1; } if (!(polls[0].revents & POLLIN)) { break; } struct input_event event; err = read(polls[0].fd, &event, sizeof(event)); if (err < sizeof(event)) { return -1; } switch (event.type) { case EV_ABS: if (event.code == ABS_MT_POSITION_X) { s->last_x = event.value; } else if (event.code == ABS_MT_POSITION_Y) { s->last_y = event.value; } up = true; break; default: break; } } if (up) { // adjust for flippening *out_x = s->last_y; *out_y = 1080 - s->last_x; } return up; } int touch_read(TouchState *s, int* out_x, int* out_y) { assert(out_x && out_y); struct input_event event; int err = read(s->fd, &event, sizeof(event)); if (err < sizeof(event)) { return -1; } bool up = false; switch (event.type) { case EV_ABS: if (event.code == ABS_MT_POSITION_X) { s->last_x = event.value; } else if (event.code == ABS_MT_POSITION_Y) { s->last_y = event.value; } up = true; break; default: break; } if (up) { // adjust for flippening *out_x = s->last_y; *out_y = 1080 - s->last_x; } return up; }