Program Listing for File linux_I_WAKER.cpp
↰ Return to documentation for file (include/tests/INPUT_TESTS/linux_I_WAKER.cpp
)
#include "LINUX_INPUT.hpp"
#include <chrono>
#include <fcntl.h>
#include <iostream>
#include <linux/futex.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <unistd.h>
void
futex_wait(int *addr)
{
syscall(SYS_futex, addr, FUTEX_WAIT, 0, NULL, NULL, 0);
}
void
futex_wake(int *addr)
{
syscall(SYS_futex, addr, FUTEX_WAKE, 1, NULL, NULL, 0);
}
int
main(int argc, char *argv[])
{
std::string SHM_FUTEX_NAME = argv[1];
std::string SHM_EVDEV_MIRROR_NAME = argv[2];
std::string SHM_DELAY = "/PDJE_DELAY_CHECK";
int delay_shm_fd = shm_open(SHM_DELAY.c_str(), O_RDWR, 0666);
int futex_shm_fd = shm_open(SHM_FUTEX_NAME.c_str(), O_RDWR, 0666);
int evdev_shm = shm_open(SHM_EVDEV_MIRROR_NAME.c_str(), O_RDWR, 0666);
int *futexVar = (int *)mmap(
NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, futex_shm_fd, 0);
int *tempstopper =
(int *)mmap(NULL, sizeof(int), PROT_READ, MAP_SHARED, evdev_shm, 0);
// int* evdevEventFD = (int*)mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,
// MAP_SHARED, evdev_shm, 0);
int evdevfd;
std::chrono::_V2::system_clock::time_point *delay_checker =
(std::chrono::_V2::system_clock::time_point *)mmap(
NULL,
sizeof(std::chrono::_V2::system_clock::time_point),
PROT_READ | PROT_WRITE,
MAP_SHARED,
delay_shm_fd,
0);
std::string posRoot = "/dev/input/event";
libevdev *dev = nullptr;
for (int i = 14; i > 0; --i) {
std::string pos = posRoot + std::to_string(i);
(evdevfd) = open(pos.c_str(), O_RDONLY); // | O_NONBLOCK);
std::cout << pos << std::endl;
if (libevdev_new_from_fd((evdevfd), &dev) < 0) {
std::cout << "init failed" << std::endl;
close((evdevfd));
continue;
}
if (libevdev_has_event_code(dev, EV_REL, REL_X) > 0) {
break;
} else {
std::cout << "not a mouse" << std::endl;
libevdev_free(dev);
dev = nullptr;
close(evdevfd);
}
}
input_event ev;
while (true) {
(*delay_checker) = std::chrono::high_resolution_clock::now();
futex_wake(futexVar);
if (*tempstopper != 0) {
break;
}
// sleep(1);
int rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_BLOCKING, &ev);
if (rc == LIBEVDEV_READ_STATUS_SUCCESS) {
auto code = ev.code;
auto time = ev.time;
auto type = ev.type;
auto value = ev.value;
std::cout << "evdev IO Result: " << std::endl;
std::cout << "code: " << code << std::endl;
std::cout << "time: " << time.tv_usec << std::endl;
std::cout << "type: " << type << std::endl;
std::cout << "value: " << value << std::endl;
std::cout << "WAKEUP CALL" << std::endl;
} else {
std::cout << "Failed" << std::endl;
}
}
libevdev_free(dev);
close(futex_shm_fd);
close(evdev_shm);
close(evdevfd);
munmap(futexVar, sizeof(int));
munmap(tempstopper, sizeof(int));
// munmap(evdevEventFD, sizeof(int));
munmap(delay_checker, sizeof(std::chrono::_V2::system_clock::time_point));
shm_unlink(SHM_FUTEX_NAME.c_str());
shm_unlink(SHM_EVDEV_MIRROR_NAME.c_str());
shm_unlink(SHM_DELAY.c_str());
return 0;
}