libevdev mouse support
This commit is contained in:
@@ -110,6 +110,13 @@ target_link_libraries(
|
|||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
find_package(X11 REQUIRED)
|
find_package(X11 REQUIRED)
|
||||||
target_link_libraries(ui PRIVATE X11::X11)
|
target_link_libraries(ui PRIVATE X11::X11)
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(LIBEVDEV IMPORTED_TARGET libevdev)
|
||||||
|
if (LIBEVDEV_FOUND)
|
||||||
|
target_compile_definitions(ui PRIVATE EVDEV_INPUT)
|
||||||
|
target_link_libraries(ui PUBLIC PkgConfig::LIBEVDEV)
|
||||||
|
target_sources(ui PRIVATE evdev_mouse.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(ECM NO_MODULE)
|
find_package(ECM NO_MODULE)
|
||||||
if (ECM_FOUND)
|
if (ECM_FOUND)
|
||||||
|
|||||||
102
src/qt/evdev_mouse.cpp
Normal file
102
src/qt/evdev_mouse.cpp
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#include "evdev_mouse.hpp"
|
||||||
|
#include <libevdev/libevdev.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <atomic>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include <86box/86box.h>
|
||||||
|
#include <86box/plat.h>
|
||||||
|
#include <86box/mouse.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::pair<int, libevdev*>> evdev_mice;
|
||||||
|
static std::atomic<bool> stopped = false;
|
||||||
|
static QThread* evdev_thread;
|
||||||
|
|
||||||
|
static std::atomic<int> evdev_mouse_rel_x = 0, evdev_mouse_rel_y = 0;
|
||||||
|
|
||||||
|
void evdev_mouse_poll()
|
||||||
|
{
|
||||||
|
if (!evdev_mice.size() || !mouse_capture)
|
||||||
|
{
|
||||||
|
evdev_mouse_rel_x = 0;
|
||||||
|
evdev_mouse_rel_y = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mouse_x = evdev_mouse_rel_x;
|
||||||
|
mouse_y = evdev_mouse_rel_y;
|
||||||
|
evdev_mouse_rel_x = evdev_mouse_rel_y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void evdev_thread_func()
|
||||||
|
{
|
||||||
|
while (!stopped)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < evdev_mice.size(); i++)
|
||||||
|
{
|
||||||
|
struct input_event ev;
|
||||||
|
int rc = libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev);
|
||||||
|
if (rc == 0 && ev.type == EV_REL && mouse_capture)
|
||||||
|
{
|
||||||
|
if (ev.code == REL_X) evdev_mouse_rel_x += ev.value;
|
||||||
|
if (ev.code == REL_Y) evdev_mouse_rel_y += ev.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < evdev_mice.size(); i++)
|
||||||
|
{
|
||||||
|
libevdev_free(evdev_mice[i].second);
|
||||||
|
close(evdev_mice[i].first);
|
||||||
|
}
|
||||||
|
evdev_mice.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void evdev_stop()
|
||||||
|
{
|
||||||
|
stopped = true;
|
||||||
|
evdev_thread->wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
void evdev_init()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
std::string evdev_device_path = "/dev/input/event" + std::to_string(i);
|
||||||
|
int fd = open(evdev_device_path.c_str(), O_NONBLOCK | O_RDONLY);
|
||||||
|
if (fd != -1)
|
||||||
|
{
|
||||||
|
libevdev* input_struct = nullptr;
|
||||||
|
int rc = libevdev_new_from_fd(fd, &input_struct);
|
||||||
|
if (rc <= -1)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!libevdev_has_event_type(input_struct, EV_REL) || !libevdev_has_event_code(input_struct, EV_KEY, BTN_LEFT))
|
||||||
|
{
|
||||||
|
libevdev_free(input_struct);
|
||||||
|
close(fd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
evdev_mice.push_back(std::make_pair(fd, input_struct));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (errno == ENOENT) break;
|
||||||
|
}
|
||||||
|
if (evdev_mice.size() != 0)
|
||||||
|
{
|
||||||
|
evdev_thread = QThread::create(evdev_thread_func);
|
||||||
|
evdev_thread->start();
|
||||||
|
atexit(evdev_stop);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/qt/evdev_mouse.hpp
Normal file
4
src/qt/evdev_mouse.hpp
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#ifdef EVDEV_INPUT
|
||||||
|
void evdev_init();
|
||||||
|
void evdev_mouse_poll();
|
||||||
|
#endif
|
||||||
@@ -30,12 +30,6 @@ public:
|
|||||||
: QOpenGLWidget(parent), QOpenGLFunctions()
|
: QOpenGLWidget(parent), QOpenGLFunctions()
|
||||||
{
|
{
|
||||||
setMinimumSize(16, 16);
|
setMinimumSize(16, 16);
|
||||||
#ifdef WAYLAND
|
|
||||||
if (QApplication::platformName().contains("wayland")) {
|
|
||||||
wayland = true;
|
|
||||||
wl_init();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
~HardwareRenderer()
|
~HardwareRenderer()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include "qt_softwarerenderer.hpp"
|
#include "qt_softwarerenderer.hpp"
|
||||||
#include "qt_hardwarerenderer.hpp"
|
#include "qt_hardwarerenderer.hpp"
|
||||||
|
|
||||||
|
#include "evdev_mouse.hpp"
|
||||||
|
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@@ -25,6 +27,16 @@ RendererStack::RendererStack(QWidget *parent) :
|
|||||||
imagebufs = QVector<QImage>(2);
|
imagebufs = QVector<QImage>(2);
|
||||||
imagebufs[0] = QImage{QSize(2048 + 64, 2048 + 64), QImage::Format_RGB32};
|
imagebufs[0] = QImage{QSize(2048 + 64, 2048 + 64), QImage::Format_RGB32};
|
||||||
imagebufs[1] = QImage{QSize(2048 + 64, 2048 + 64), QImage::Format_RGB32};
|
imagebufs[1] = QImage{QSize(2048 + 64, 2048 + 64), QImage::Format_RGB32};
|
||||||
|
#ifdef WAYLAND
|
||||||
|
if (QApplication::platformName().contains("wayland")) {
|
||||||
|
wl_init();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef EVDEV_INPUT
|
||||||
|
if (QApplication::platformName() == "xcb" || QApplication::platformName() == "eglfs") {
|
||||||
|
evdev_init();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererStack::~RendererStack()
|
RendererStack::~RendererStack()
|
||||||
@@ -67,6 +79,9 @@ void RendererStack::mousePoll()
|
|||||||
if (QApplication::platformName().contains("wayland"))
|
if (QApplication::platformName().contains("wayland"))
|
||||||
wl_mouse_poll();
|
wl_mouse_poll();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef EVDEV_INPUT
|
||||||
|
evdev_mouse_poll();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user