.. _program_listing_file_include_input_linux_RT_RTEvent.cpp: Program Listing for File RTEvent.cpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/input/linux/RT/RTEvent.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "RTEvent.hpp" #include "RTSocket.hpp" #include 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 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; }