#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); char name[128] = {0}; err = ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name); assert(err >= 0); unsigned long ev_bits[8] = {0}; err = ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits); assert(err >= 0); if (strncmp(name, "synaptics", 9) == 0 && ev_bits[0] == 0xb) { 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) { assert(out_x && out_y); bool up = false; while (true) { struct pollfd polls[] = {{ .fd = s->fd, .events = POLLIN, }}; int err = poll(polls, 1, 0); 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; } break; case EV_KEY: if (event.code == BTN_TOOL_FINGER && event.value == 0) { // finger up up = true; } break; default: break; } } if (up) { // adjust for landscape *out_x = 1920 - s->last_y; *out_y = s->last_x; } return up; }