You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
1.9 KiB
99 lines
1.9 KiB
8 years ago
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
9 years ago
|
#include <stdbool.h>
|
||
8 years ago
|
#include <assert.h>
|
||
9 years ago
|
#include <unistd.h>
|
||
|
#include <fcntl.h>
|
||
8 years ago
|
#include <dirent.h>
|
||
9 years ago
|
#include <sys/poll.h>
|
||
|
#include <linux/input.h>
|
||
|
|
||
|
#include "touch.h"
|
||
|
|
||
8 years ago
|
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;
|
||
|
}
|
||
|
|
||
9 years ago
|
void touch_init(TouchState *s) {
|
||
8 years ago
|
s->fd = find_dev();
|
||
9 years ago
|
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;
|
||
|
}
|
||
|
|