Program Listing for File RTEvent.cpp
↰ Return to documentation for file (include/input/linux/RT/RTEvent.cpp)
#include "RTEvent.hpp"
#include "RTSocket.hpp"
#include <libevdev/libevdev.h>
int
RTEvent::Add(const fs::path &target)
{
int FD = open(target.c_str(), O_RDONLY | O_NONBLOCK);
if (FD < 0) {
return false;
}
if (libevdev_new_from_fd(FD, &events[FD]) < 0) {
close(FD);
events.erase(FD);
return false;
}
libevdev_set_clock_id(events[FD], CLOCK_MONOTONIC_RAW);
return true;
}
RTEvent::~RTEvent()
{
Reset();
}
void
RTEvent::Reset()
{
for (auto &target : events) {
libevdev_free(target.second);
close(target.first);
}
}
#include <iostream>
void
RTEvent::Trig()
{
int epfd = epoll_create1(EPOLL_CLOEXEC);
for (const auto &dev : events) {
epoll_event ev;
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = dev.first;
epoll_ctl(epfd, EPOLL_CTL_ADD, dev.first, &ev);
}
sched_param sp{};
sp.sched_priority = 70;
if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp) != 0) {
std::cerr << "pthread_setschedparam failed: " << stderr << std::endl;
return;
}
int trigCount = 40;
epoll_event out_events[64];
while (true) {
int n = epoll_wait(epfd, out_events, 64, 500);
std::cout << "trigged" << n << std::endl;
for (int i = 0; i < n; ++i) {
DrainEvents(
epfd, out_events[i].data.fd, events[out_events[i].data.fd]);
}
trigCount--;
if (trigCount < 1) {
return;
}
}
return;
}
void
RTEvent::DrainEvents(const int epFD, int FD, libevdev *evdev)
{
input_event now_ev;
auto flag = LIBEVDEV_READ_FLAG_NORMAL;
bool inSync = false;
int state = 0;
while (true) {
flag = inSync ? LIBEVDEV_READ_FLAG_SYNC : LIBEVDEV_READ_FLAG_NORMAL;
state = libevdev_next_event(evdev, flag, &now_ev);
switch (state) {
case LIBEVDEV_READ_STATUS_SUCCESS:
use_event(now_ev);
continue;
case LIBEVDEV_READ_STATUS_SYNC:
inSync = true;
continue;
case -EAGAIN:
if (inSync) {
inSync = false;
continue;
} else {
return;
}
case -ENOMEM: {
timespec sleepTime{ .tv_nsec = 300000 };
nanosleep(&sleepTime, nullptr);
continue;
}
case -ENODEV:
[[fallthrough]];
default:
epoll_ctl(epFD, EPOLL_CTL_DEL, FD, nullptr);
return;
}
}
}
void
RTEvent::use_event(const input_event &evtrig)
{
if (evtrig.type == EV_KEY && evtrig.code == KEY_A && evtrig.value == 1) {
std::cout << "pressed";
}
return;
}