commit 8082251befdd1798cadc51b0e9e88bdfcc8cbd48 Author: Alessandro Mauri Date: Wed Feb 16 17:01:51 2022 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..423d628 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +btor diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..17d3552 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +.POSIX: + +CC = gcc +CFLAGS = -Wall -Werror -Wextra -pedantic -std=c11 + +btor: btor.c + ${CC} ${LDFLAGS} ${CFLAGS} btor.c -o btor + +clean: + rm -f btor diff --git a/btor.c b/btor.c new file mode 100644 index 0000000..2756f4f --- /dev/null +++ b/btor.c @@ -0,0 +1,99 @@ +#define _POSIX_C_SOURCE 200809l +#define _DEFAULT_SOURCE + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define test_bit(yalv, abs_b) ((((char *)abs_b)[yalv/8] & (1< 0) + +#define EVDEV_ROOT "/dev/input/" + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + DIR *dir = opendir(EVDEV_ROOT); + if (!dir) + err(1, "opendir:"); + struct dirent *dp; + struct stat st = {0}; + int stylus = -1; + + while ((dp = readdir(dir)) != NULL) { + if (fstatat(dirfd(dir), dp->d_name, &st, 0) == -1) + err(1, "fstatat:"); + if ((st.st_mode & S_IFMT) != S_IFCHR) + continue; + + int tmp_fd = openat(dirfd(dir), dp->d_name, O_RDWR | O_NONBLOCK); + if (tmp_fd < 0) + err(1, "openat:"); + union { + char b[EV_MAX]; + char k[KEY_MAX]; + } vec; + if (ioctl(tmp_fd, EVIOCGBIT(0, EV_MAX), vec.b) < 0) + err(1, "ioctl:"); + if (!test_bit(EV_KEY, vec.b)) + continue; + if (ioctl(tmp_fd, EVIOCGBIT(EV_KEY, KEY_MAX), vec.k) < 0) + err(1, "ioctl:"); + + if (test_bit(BTN_STYLUS, vec.k) && test_bit(EV_ABS, vec.k)) { + stylus = tmp_fd; + break; + } + close(tmp_fd); + } + closedir(dir); + if (stylus == -1) + err(1, "no stylus input found"); + + int poll_set = epoll_create(1); + if (poll_set < 0) + err(1, "epoll_create:"); + struct epoll_event poll_ev = { .events = EPOLLIN | EPOLLOUT | EPOLLET }; + if (epoll_ctl(poll_set, EPOLL_CTL_ADD, stylus, &poll_ev) < 0) + err(1, "epoll_ctl:"); + + + unsigned char button_recived = 0; + struct input_event in_ev, out_ev; + while (epoll_wait(poll_set, &poll_ev, 1, -1) != -1) { + switch (poll_ev.events) { + case EPOLLIN: + if (read(stylus, &in_ev, sizeof(struct input_event)) < 0) + err(1, "read:"); + if (in_ev.type != BTN_STYLUS) + break; + out_ev.type = BTN_TOOL_RUBBER; + out_ev.value = in_ev.value; + button_recived = 1; + break; + case EPOLLOUT: + if (!button_recived) + break; + button_recived = 0; + if (write(stylus, &out_ev, sizeof(struct input_event)) < 0) + err(1, "write:"); + break; + default: + break; + } + } + + return 0; +}