Enable mouse handling on VxWorks

Provide implementation of QEvdevMouseHandler for VxWorks OS.

This is a preparatory change before actually using this handler, as Qt
is not supporting evdev on VxWorks yet.

Task-number: QTBUG-115777
Change-Id: Ie92418c903a54ea1d6683e08762d4cc88c4956ac
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 2003532cd84141434f698d723458f0672766fc0c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Michał Łoś 2024-04-10 16:50:31 +02:00 committed by Qt Cherry-pick Bot
parent d92264a089
commit a7fc60015d
3 changed files with 171 additions and 1 deletions

View File

@ -33,7 +33,7 @@ qt_internal_extend_target(InputSupportPrivate CONDITION QT_FEATURE_evdev
evdevkeyboard/qevdevkeyboard_defaultmap_p.h
evdevkeyboard/qevdevkeyboardhandler.cpp evdevkeyboard/qevdevkeyboardhandler_p.h
evdevkeyboard/qevdevkeyboardmanager.cpp evdevkeyboard/qevdevkeyboardmanager_p.h
evdevmouse/qevdevmousehandler.cpp evdevmouse/qevdevmousehandler_p.h
evdevmouse/qevdevmousehandler_p.h
evdevmouse/qevdevmousemanager.cpp evdevmouse/qevdevmousemanager_p.h
evdevtouch/qevdevtouchhandler.cpp evdevtouch/qevdevtouchhandler_p.h
evdevtouch/qevdevtouchfilter_p.h
@ -63,6 +63,16 @@ qt_internal_extend_target(InputSupportPrivate CONDITION QT_FEATURE_evdev AND QT_
PkgConfig::Mtdev
)
qt_internal_extend_target(InputSupportPrivate CONDITION QT_FEATURE_evdev AND NOT VXWORKS
SOURCES
evdevmouse/qevdevmousehandler.cpp
)
qt_internal_extend_target(InputSupportPrivate CONDITION QT_FEATURE_evdev AND VXWORKS
SOURCES
evdevmouse/qevdevmousehandler_vxworks.cpp
)
qt_internal_extend_target(InputSupportPrivate CONDITION QT_FEATURE_tslib
SOURCES
tslib/qtslib.cpp tslib/qtslib_p.h

View File

@ -45,7 +45,9 @@ private:
QEvdevMouseHandler(const QString &device, int fd, bool abs, bool compression, int jitterLimit);
void sendMouseEvent();
#ifndef Q_OS_VXWORKS
bool getHardwareMaximum();
#endif
void detectHiResWheelSupport();
QString m_device;

View File

@ -0,0 +1,158 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qevdevmousehandler_p.h"
#include <QGuiApplication>
#include <QLoggingCategory>
#include <QPoint>
#include <QScreen>
#include <QSocketNotifier>
#include <QStringList>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
#include <qpa/qwindowsysteminterface.h>
#include <qplatformdefs.h>
#include <errno.h>
#include <evdevLib.h>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcEvdevMouse, "qt.qpa.input")
std::unique_ptr<QEvdevMouseHandler> QEvdevMouseHandler::create(const QString &device, const QString &specification)
{
qCDebug(qLcEvdevMouse) << "create mouse handler for" << device << specification;
bool compression = false;
int jitterLimit = 0;
bool abs = false;
QStringList args = specification.split(QLatin1Char(':'));
for (const auto& arg : args) {
if (arg == QLatin1String("abs"))
abs = true;
}
int fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NONBLOCK, 0);
if (fd >= 0) {
return std::unique_ptr<QEvdevMouseHandler>(new QEvdevMouseHandler(device, fd, abs, compression, jitterLimit));
} else {
qCWarning(qLcEvdevMouse) << "Cannot open mouse input device" << qPrintable(device) << ":" << strerror(errno);
return nullptr;
}
}
QEvdevMouseHandler::QEvdevMouseHandler(const QString &device, int fd, bool abs, bool, int jitterLimit)
: m_device(device), m_fd(fd), m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0),
m_abs(abs), m_buttons(0), m_button(Qt::NoButton), m_eventType(QEvent::None), m_prevInvalid(true)
{
Q_UNUSED(jitterLimit)
setObjectName(QLatin1String("Evdev Mouse Handler"));
QSocketNotifier *notifier;
notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect(notifier, &QSocketNotifier::activated,
this, &QEvdevMouseHandler::readMouseData);
}
QEvdevMouseHandler::~QEvdevMouseHandler()
{
if (m_fd >= 0)
qt_safe_close(m_fd);
}
void QEvdevMouseHandler::sendMouseEvent()
{
int x = m_x - m_prevx;
int y = m_y - m_prevy;
if (m_prevInvalid) {
x = 0;
y = 0;
m_prevInvalid = false;
}
emit handleMouseEvent(x, y, m_abs, m_buttons, m_button, m_eventType);
m_prevx = m_x;
m_prevy = m_y;
}
void QEvdevMouseHandler::readMouseData()
{
bool posChanged = false;
bool btnChanged = false;
Q_FOREVER {
EV_DEV_EVENT ev;
size_t n = read(m_fd, (char *)(&ev), sizeof(EV_DEV_EVENT));
if (n < sizeof(EV_DEV_EVENT)) {
sendMouseEvent();
return;
}
switch (ev.type) {
case EV_DEV_KEY: {
Qt::MouseButton buttons = Qt::NoButton;
switch (ev.code) {
case EV_DEV_PTR_BTN_LEFT:
buttons = Qt::LeftButton;
break;
case EV_DEV_PTR_BTN_RIGHT:
buttons = Qt::RightButton;
break;
case EV_DEV_PTR_BTN_MIDDLE:
buttons = Qt::MiddleButton;
break;
}
if (ev.value)
m_buttons |= buttons;
else
m_buttons &= ~buttons;
m_button = buttons;
m_eventType = ev.value != 0 ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
btnChanged = true;
break;
}
case EV_DEV_REL:
switch (ev.code) {
case EV_DEV_PTR_REL_X:
m_x += ev.value;
m_eventType = QEvent::MouseMove;
posChanged = true;
break;
case EV_DEV_PTR_REL_Y:
m_y += ev.value;
m_eventType = QEvent::MouseMove;
posChanged = true;
break;
}
break;
case EV_DEV_ABS:
switch (ev.code) {
case EV_DEV_PTR_ABS_X:
m_x = ev.value;
m_eventType = QEvent::MouseMove;
posChanged = true;
break;
case EV_DEV_PTR_ABS_Y:
m_y = ev.value;
m_eventType = QEvent::MouseMove;
posChanged = true;
break;
}
break;
}
if (btnChanged) {
btnChanged = false;
posChanged = false;
sendMouseEvent();
} else if (posChanged) {
posChanged = false;
sendMouseEvent();
}
}
}
QT_END_NAMESPACE