Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qlibinputhandler.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
7#include "qlibinputtouch_p.h"
8
9#include <libudev.h>
10#include <libinput.h>
11#include <QtCore/QLoggingCategory>
12#include <QtCore/QSocketNotifier>
13#include <QtCore/private/qcore_unix_p.h>
14#include <private/qguiapplication_p.h>
15#include <private/qinputdevicemanager_p_p.h>
16
18
19Q_LOGGING_CATEGORY(qLcLibInput, "qt.qpa.input")
20
21static int liOpen(const char *path, int flags, void *user_data)
22{
24 return qt_safe_open(path, flags);
25}
26
27static void liClose(int fd, void *user_data)
28{
31}
32
33static const struct libinput_interface liInterface = {
34 liOpen,
36};
37
38static void liLogHandler(libinput *libinput, libinput_log_priority priority, const char *format, va_list args)
39{
40 Q_UNUSED(libinput);
41 Q_UNUSED(priority);
42
43 char buf[512];
44 int n = vsnprintf(buf, sizeof(buf), format, args);
45 if (n > 0) {
46 if (buf[n - 1] == '\n')
47 buf[n - 1] = '\0';
48 qCDebug(qLcLibInput, "libinput: %s", buf);
49 }
50}
51
53{
55 Q_UNUSED(spec);
56
57 m_udev = udev_new();
58 if (Q_UNLIKELY(!m_udev))
59 qFatal("Failed to get udev context for libinput");
60
61 m_li = libinput_udev_create_context(&liInterface, nullptr, m_udev);
62 if (Q_UNLIKELY(!m_li))
63 qFatal("Failed to get libinput context");
64
65 libinput_log_set_handler(m_li, liLogHandler);
66 if (qLcLibInput().isDebugEnabled())
67 libinput_log_set_priority(m_li, LIBINPUT_LOG_PRIORITY_DEBUG);
68
69 if (Q_UNLIKELY(libinput_udev_assign_seat(m_li, "seat0")))
70 qFatal("Failed to assign seat");
71
72 m_liFd = libinput_get_fd(m_li);
73 m_notifier.reset(new QSocketNotifier(m_liFd, QSocketNotifier::Read));
74
76
77 m_pointer.reset(new QLibInputPointer);
78 m_keyboard.reset(new QLibInputKeyboard);
79 m_touch.reset(new QLibInputTouch);
80
83 m_pointer->setPos(pos);
84 });
85
86 // Process the initial burst of DEVICE_ADDED events.
88}
89
91{
92 if (m_li)
93 libinput_unref(m_li);
94
95 if (m_udev)
96 udev_unref(m_udev);
97}
98
100{
101 if (libinput_dispatch(m_li)) {
102 qWarning("libinput_dispatch failed");
103 return;
104 }
105
106 libinput_event *ev;
107 while ((ev = libinput_get_event(m_li)) != nullptr) {
108 processEvent(ev);
109 libinput_event_destroy(ev);
110 }
111}
112
113void QLibInputHandler::processEvent(libinput_event *ev)
114{
115 libinput_event_type type = libinput_event_get_type(ev);
116 libinput_device *dev = libinput_event_get_device(ev);
117
118 switch (type) {
119 case LIBINPUT_EVENT_DEVICE_ADDED:
120 {
121 // This is not just for hotplugging, it is also called for each input
122 // device libinput reads from on startup. Hence it is suitable for doing
123 // touch device registration.
126 if (libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_TOUCH)) {
127 m_touch->registerDevice(dev);
129 ++count;
130 inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeTouch, count);
131 }
132 if (libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_POINTER)) {
134 ++count;
135 inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypePointer, count);
136 }
137 if (libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
139 ++count;
140 inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeKeyboard, count);
141 }
142 break;
143 }
144 case LIBINPUT_EVENT_DEVICE_REMOVED:
145 {
148 if (libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_TOUCH)) {
149 m_touch->unregisterDevice(dev);
151 --count;
152 inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeTouch, count);
153 }
154 if (libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_POINTER)) {
156 --count;
157 inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypePointer, count);
158 }
159 if (libinput_device_has_capability(dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
161 --count;
162 inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeKeyboard, count);
163 }
164 break;
165 }
166 case LIBINPUT_EVENT_POINTER_BUTTON:
167 m_pointer->processButton(libinput_event_get_pointer_event(ev));
168 break;
169 case LIBINPUT_EVENT_POINTER_MOTION:
170 m_pointer->processMotion(libinput_event_get_pointer_event(ev));
171 break;
172 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
173 m_pointer->processAbsMotion(libinput_event_get_pointer_event(ev));
174 break;
175#if QT_CONFIG(libinput_hires_wheel_support)
176 case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
177#else
178 case LIBINPUT_EVENT_POINTER_AXIS:
179#endif
180 m_pointer->processAxis(libinput_event_get_pointer_event(ev));
181 break;
182 case LIBINPUT_EVENT_KEYBOARD_KEY:
183 m_keyboard->processKey(libinput_event_get_keyboard_event(ev));
184 break;
185 case LIBINPUT_EVENT_TOUCH_DOWN:
186 m_touch->processTouchDown(libinput_event_get_touch_event(ev));
187 break;
188 case LIBINPUT_EVENT_TOUCH_MOTION:
189 m_touch->processTouchMotion(libinput_event_get_touch_event(ev));
190 break;
191 case LIBINPUT_EVENT_TOUCH_UP:
192 m_touch->processTouchUp(libinput_event_get_touch_event(ev));
193 break;
194 case LIBINPUT_EVENT_TOUCH_CANCEL:
195 m_touch->processTouchCancel(libinput_event_get_touch_event(ev));
196 break;
197 case LIBINPUT_EVENT_TOUCH_FRAME:
198 m_touch->processTouchFrame(libinput_event_get_touch_event(ev));
199 break;
200 default:
201 break;
202 }
203}
204
static QInputDeviceManager * inputDeviceManager()
static QInputDeviceManagerPrivate * get(QInputDeviceManager *mgr)
QInputDeviceManager acts as a communication hub between QtGui and the input handlers.
void cursorPositionChangeRequested(const QPoint &pos)
QLibInputHandler(const QString &key, const QString &spec)
void processKey(libinput_event_keyboard *e)
void processAxis(libinput_event_pointer *e)
void setPos(const QPoint &pos)
void processButton(libinput_event_pointer *e)
void processMotion(libinput_event_pointer *e)
void processAbsMotion(libinput_event_pointer *e)
void processTouchDown(libinput_event_touch *e)
void unregisterDevice(libinput_device *dev)
void processTouchMotion(libinput_event_touch *e)
void processTouchCancel(libinput_event_touch *e)
void registerDevice(libinput_device *dev)
void processTouchFrame(libinput_event_touch *e)
void processTouchUp(libinput_event_touch *e)
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
\inmodule QtCore\reentrant
Definition qpoint.h:25
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
\inmodule QtCore
void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent, QPrivateSignal)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
Combined button and popup list for selecting options.
#define Q_UNLIKELY(x)
static int qt_safe_open(const char *pathname, int flags, mode_t mode=0777)
static int qt_safe_close(int fd)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void * user_data
static const struct libinput_interface liInterface
static void liClose(int fd, void *user_data)
static QT_BEGIN_NAMESPACE int liOpen(const char *path, int flags, void *user_data)
static void liLogHandler(libinput *libinput, libinput_log_priority priority, const char *format, va_list args)
#define qWarning
Definition qlogging.h:166
#define qFatal
Definition qlogging.h:168
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLuint64 key
GLenum GLenum GLsizei count
GLenum type
GLenum GLuint GLenum GLsizei const GLchar * buf
GLbitfield flags
GLuint64 GLenum GLint fd
GLfloat n
GLint GLsizei GLsizei GLenum format
GLsizei const GLchar *const * path
#define Q_UNUSED(x)
QNetworkAccessManager manager
QJSValueList args