OpenCoverage

qevdevtablethandler.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the plugins module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qevdevtablethandler_p.h"-
41-
42#include <QStringList>-
43#include <QSocketNotifier>-
44#include <QGuiApplication>-
45#include <QLoggingCategory>-
46#include <QtCore/private/qcore_unix_p.h>-
47#include <qpa/qwindowsysteminterface.h>-
48#include <linux/input.h>-
49-
50QT_BEGIN_NAMESPACE-
51-
52Q_LOGGING_CATEGORY(qLcEvdevTablet, "qt.qpa.input")
never executed: return category;
0
53-
54class QEvdevTabletData-
55{-
56public:-
57 QEvdevTabletData(QEvdevTabletHandler *q_ptr);-
58-
59 void processInputEvent(input_event *ev);-
60 void report();-
61-
62 QEvdevTabletHandler *q;-
63 int lastEventType;-
64 QString devName;-
65 struct {-
66 int x, y, p, d;-
67 } minValues, maxValues;-
68 struct {-
69 int x, y, p, d;-
70 bool down, lastReportDown;-
71 int tool, lastReportTool;-
72 QPointF lastReportPos;-
73 } state;-
74};-
75-
76QEvdevTabletData::QEvdevTabletData(QEvdevTabletHandler *q_ptr)-
77 : q(q_ptr), lastEventType(0)-
78{-
79 memset(&minValues, 0, sizeof(minValues));-
80 memset(&maxValues, 0, sizeof(maxValues));-
81 memset(&state, 0, sizeof(state));-
82}
never executed: end of block
0
83-
84void QEvdevTabletData::processInputEvent(input_event *ev)-
85{-
86 if (ev->type == EV_ABS) {
ev->type == 0x03Description
TRUEnever evaluated
FALSEnever evaluated
0
87 switch (ev->code) {-
88 case ABS_X:
never executed: case 0x00:
0
89 state.x = ev->value;-
90 break;
never executed: break;
0
91 case ABS_Y:
never executed: case 0x01:
0
92 state.y = ev->value;-
93 break;
never executed: break;
0
94 case ABS_PRESSURE:
never executed: case 0x18:
0
95 state.p = ev->value;-
96 break;
never executed: break;
0
97 case ABS_DISTANCE:
never executed: case 0x19:
0
98 state.d = ev->value;-
99 break;
never executed: break;
0
100 default:
never executed: default:
0
101 break;
never executed: break;
0
102 }-
103 } else if (ev->type == EV_KEY) {
ev->type == 0x01Description
TRUEnever evaluated
FALSEnever evaluated
0
104 // code BTN_TOOL_* value 1 -> proximity enter-
105 // code BTN_TOOL_* value 0 -> proximity leave-
106 // code BTN_TOUCH value 1 -> contact with screen-
107 // code BTN_TOUCH value 0 -> no contact-
108 switch (ev->code) {-
109 case BTN_TOUCH:
never executed: case 0x14a:
0
110 state.down = ev->value != 0;-
111 break;
never executed: break;
0
112 case BTN_TOOL_PEN:
never executed: case 0x140:
0
113 state.tool = ev->value ? QTabletEvent::Pen : 0;
ev->valueDescription
TRUEnever evaluated
FALSEnever evaluated
0
114 break;
never executed: break;
0
115 case BTN_TOOL_RUBBER:
never executed: case 0x141:
0
116 state.tool = ev->value ? QTabletEvent::Eraser : 0;
ev->valueDescription
TRUEnever evaluated
FALSEnever evaluated
0
117 break;
never executed: break;
0
118 default:
never executed: default:
0
119 break;
never executed: break;
0
120 }-
121 } else if (ev->type == EV_SYN && ev->code == SYN_REPORT && lastEventType != ev->type) {
ev->type == 0x00Description
TRUEnever evaluated
FALSEnever evaluated
ev->code == 0Description
TRUEnever evaluated
FALSEnever evaluated
lastEventType != ev->typeDescription
TRUEnever evaluated
FALSEnever evaluated
0
122 report();-
123 }
never executed: end of block
0
124 lastEventType = ev->type;-
125}
never executed: end of block
0
126-
127void QEvdevTabletData::report()-
128{-
129 if (!state.lastReportTool && state.tool)
!state.lastReportToolDescription
TRUEnever evaluated
FALSEnever evaluated
state.toolDescription
TRUEnever evaluated
FALSEnever evaluated
0
130 QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId());
never executed: QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId());
0
131-
132 qreal nx = (state.x - minValues.x) / qreal(maxValues.x - minValues.x);-
133 qreal ny = (state.y - minValues.y) / qreal(maxValues.y - minValues.y);-
134-
135 QRect winRect = QGuiApplication::primaryScreen()->geometry();-
136 QPointF globalPos(nx * winRect.width(), ny * winRect.height());-
137 int pointer = state.tool;-
138 // Prevent sending confusing values of 0 when moving the pen outside the active area.-
139 if (!state.down && state.lastReportDown) {
!state.downDescription
TRUEnever evaluated
FALSEnever evaluated
state.lastReportDownDescription
TRUEnever evaluated
FALSEnever evaluated
0
140 globalPos = state.lastReportPos;-
141 pointer = state.lastReportTool;-
142 }
never executed: end of block
0
143-
144 int pressureRange = maxValues.p - minValues.p;-
145 qreal pressure = pressureRange ? (state.p - minValues.p) / qreal(pressureRange) : qreal(1);
pressureRangeDescription
TRUEnever evaluated
FALSEnever evaluated
0
146-
147 if (state.down || state.lastReportDown) {
state.downDescription
TRUEnever evaluated
FALSEnever evaluated
state.lastReportDownDescription
TRUEnever evaluated
FALSEnever evaluated
0
148 QWindowSystemInterface::handleTabletEvent(0, state.down, QPointF(), globalPos,-
149 QTabletEvent::Stylus, pointer,-
150 pressure, 0, 0, 0, 0, 0, q->deviceId(), qGuiApp->keyboardModifiers());-
151 }
never executed: end of block
0
152-
153 if (state.lastReportTool && !state.tool)
state.lastReportToolDescription
TRUEnever evaluated
FALSEnever evaluated
!state.toolDescription
TRUEnever evaluated
FALSEnever evaluated
0
154 QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId());
never executed: QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId());
0
155-
156 state.lastReportDown = state.down;-
157 state.lastReportTool = state.tool;-
158 state.lastReportPos = globalPos;-
159}
never executed: end of block
0
160-
161-
162QEvdevTabletHandler::QEvdevTabletHandler(const QString &device, const QString &spec, QObject *parent)-
163 : QObject(parent), m_fd(-1), m_device(device), m_notifier(0), d(0)-
164{-
165 Q_UNUSED(spec)-
166-
167 setObjectName(QLatin1String("Evdev Tablet Handler"));-
168-
169 qCDebug(qLcEvdevTablet, "evdevtablet: using %s", qPrintable(device));
never executed: QMessageLogger(__FILE__, 169, __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: using %s", QString(device).toLocal8Bit().constData());
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
170-
171 m_fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);-
172 if (m_fd < 0) {
m_fd < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
173 qErrnoWarning(errno, "evdevtablet: Cannot open input device %s", qPrintable(device));-
174 return;
never executed: return;
0
175 }-
176-
177 bool grabSuccess = !ioctl(m_fd, EVIOCGRAB, (void *) 1);-
178 if (grabSuccess)
grabSuccessDescription
TRUEnever evaluated
FALSEnever evaluated
0
179 ioctl(m_fd, EVIOCGRAB, (void *) 0);
never executed: ioctl(m_fd, (((1U) << (((0 +8)+8)+14)) | ((('E')) << (0 +8)) | (((0x90)) << 0) | ((((sizeof(int)))) << ((0 +8)+8))), (void *) 0);
0
180 else-
181 qWarning("evdevtablet: %s: The device is grabbed by another process. No events will be read.", qPrintable(device));
never executed: QMessageLogger(__FILE__, 181, __PRETTY_FUNCTION__).warning("evdevtablet: %s: The device is grabbed by another process. No events will be read.", QString(device).toLocal8Bit().constData());
0
182-
183 d = new QEvdevTabletData(this);-
184 if (!queryLimits())
!queryLimits()Description
TRUEnever evaluated
FALSEnever evaluated
0
185 qWarning("evdevtablet: %s: Unset or invalid ABS limits. Behavior will be unspecified.", qPrintable(device));
never executed: QMessageLogger(__FILE__, 185, __PRETTY_FUNCTION__).warning("evdevtablet: %s: Unset or invalid ABS limits. Behavior will be unspecified.", QString(device).toLocal8Bit().constData());
0
186-
187 m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);-
188 connect(m_notifier, &QSocketNotifier::activated, this, &QEvdevTabletHandler::readData);-
189}
never executed: end of block
0
190-
191QEvdevTabletHandler::~QEvdevTabletHandler()-
192{-
193 if (m_fd >= 0)
m_fd >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
194 QT_CLOSE(m_fd);
never executed: qt_safe_close(m_fd);
0
195-
196 delete d;-
197}
never executed: end of block
0
198-
199qint64 QEvdevTabletHandler::deviceId() const-
200{-
201 return m_fd;
never executed: return m_fd;
0
202}-
203-
204bool QEvdevTabletHandler::queryLimits()-
205{-
206 bool ok = true;-
207 input_absinfo absInfo;-
208 memset(&absInfo, 0, sizeof(input_absinfo));-
209 ok &= ioctl(m_fd, EVIOCGABS(ABS_X), &absInfo) >= 0;-
210 if (ok) {
okDescription
TRUEnever evaluated
FALSEnever evaluated
0
211 d->minValues.x = absInfo.minimum;-
212 d->maxValues.x = absInfo.maximum;-
213 qCDebug(qLcEvdevTablet, "evdevtablet: %s: min X: %d max X: %d", qPrintable(m_device),
never executed: QMessageLogger( __FILE__ , 214 , __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: %s: min X: %d max X: %d", QString(m_device).toLocal8Bit().constData(), d->minValues.x, d->maxValues.x) ;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
214 d->minValues.x, d->maxValues.x);
never executed: QMessageLogger( __FILE__ , 214 , __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: %s: min X: %d max X: %d", QString(m_device).toLocal8Bit().constData(), d->minValues.x, d->maxValues.x) ;
0
215 }
never executed: end of block
0
216 ok &= ioctl(m_fd, EVIOCGABS(ABS_Y), &absInfo) >= 0;-
217 if (ok) {
okDescription
TRUEnever evaluated
FALSEnever evaluated
0
218 d->minValues.y = absInfo.minimum;-
219 d->maxValues.y = absInfo.maximum;-
220 qCDebug(qLcEvdevTablet, "evdevtablet: %s: min Y: %d max Y: %d", qPrintable(m_device),
never executed: QMessageLogger( __FILE__ , 221 , __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: %s: min Y: %d max Y: %d", QString(m_device).toLocal8Bit().constData(), d->minValues.y, d->maxValues.y) ;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
221 d->minValues.y, d->maxValues.y);
never executed: QMessageLogger( __FILE__ , 221 , __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: %s: min Y: %d max Y: %d", QString(m_device).toLocal8Bit().constData(), d->minValues.y, d->maxValues.y) ;
0
222 }
never executed: end of block
0
223 if (ioctl(m_fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) {
ioctl(m_fd, ((...&absInfo) >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
224 d->minValues.p = absInfo.minimum;-
225 d->maxValues.p = absInfo.maximum;-
226 qCDebug(qLcEvdevTablet, "evdevtablet: %s: min pressure: %d max pressure: %d", qPrintable(m_device),
never executed: QMessageLogger( __FILE__ , 227 , __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: %s: min pressure: %d max pressure: %d", QString(m_device).toLocal8Bit().constData(), d->minValues.p, d->maxValues.p) ;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
227 d->minValues.p, d->maxValues.p);
never executed: QMessageLogger( __FILE__ , 227 , __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: %s: min pressure: %d max pressure: %d", QString(m_device).toLocal8Bit().constData(), d->minValues.p, d->maxValues.p) ;
0
228 }
never executed: end of block
0
229 if (ioctl(m_fd, EVIOCGABS(ABS_DISTANCE), &absInfo) >= 0) {
ioctl(m_fd, ((...&absInfo) >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
230 d->minValues.d = absInfo.minimum;-
231 d->maxValues.d = absInfo.maximum;-
232 qCDebug(qLcEvdevTablet, "evdevtablet: %s: min distance: %d max distance: %d", qPrintable(m_device),
never executed: QMessageLogger( __FILE__ , 233 , __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: %s: min distance: %d max distance: %d", QString(m_device).toLocal8Bit().constData(), d->minValues.d, d->maxValues.d) ;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
233 d->minValues.d, d->maxValues.d);
never executed: QMessageLogger( __FILE__ , 233 , __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: %s: min distance: %d max distance: %d", QString(m_device).toLocal8Bit().constData(), d->minValues.d, d->maxValues.d) ;
0
234 }
never executed: end of block
0
235 char name[128];-
236 if (ioctl(m_fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) {
ioctl(m_fd, ((...)), name) >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
237 d->devName = QString::fromLocal8Bit(name);-
238 qCDebug(qLcEvdevTablet, "evdevtablet: %s: device name: %s", qPrintable(m_device), name);
never executed: QMessageLogger(__FILE__, 238, __PRETTY_FUNCTION__, qLcEvdevTablet().categoryName()).debug("evdevtablet: %s: device name: %s", QString(m_device).toLocal8Bit().constData(), name);
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
239 }
never executed: end of block
0
240 return ok;
never executed: return ok;
0
241}-
242-
243void QEvdevTabletHandler::readData()-
244{-
245 static input_event buffer[32];-
246 int n = 0;-
247 for (; ;) {-
248 int result = QT_READ(m_fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n);-
249 if (!result) {
!resultDescription
TRUEnever evaluated
FALSEnever evaluated
0
250 qWarning("evdevtablet: %s: Got EOF from input device", qPrintable(m_device));-
251 return;
never executed: return;
0
252 } else if (result < 0) {
result < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
253 if (errno != EINTR && errno != EAGAIN) {
(*__errno_location ()) != 4Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) != 11Description
TRUEnever evaluated
FALSEnever evaluated
0
254 qErrnoWarning(errno, "evdevtablet: %s: Could not read from input device", qPrintable(m_device));-
255 if (errno == ENODEV) { // device got disconnected -> stop reading
(*__errno_location ()) == 19Description
TRUEnever evaluated
FALSEnever evaluated
0
256 delete m_notifier;-
257 m_notifier = 0;-
258 QT_CLOSE(m_fd);-
259 m_fd = -1;-
260 }
never executed: end of block
0
261 return;
never executed: return;
0
262 }-
263 } else {
never executed: end of block
0
264 n += result;-
265 if (n % sizeof(input_event) == 0)
n % sizeof(input_event) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
266 break;
never executed: break;
0
267 }
never executed: end of block
0
268 }-
269-
270 n /= sizeof(input_event);-
271-
272 for (int i = 0; i < n; ++i)
i < nDescription
TRUEnever evaluated
FALSEnever evaluated
0
273 d->processInputEvent(&buffer[i]);
never executed: d->processInputEvent(&buffer[i]);
0
274}
never executed: end of block
0
275-
276-
277QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &device, const QString &spec, QObject *parent)-
278 : QDaemonThread(parent), m_device(device), m_spec(spec), m_handler(0)-
279{-
280 start();-
281}
never executed: end of block
0
282-
283QEvdevTabletHandlerThread::~QEvdevTabletHandlerThread()-
284{-
285 quit();-
286 wait();-
287}
never executed: end of block
0
288-
289void QEvdevTabletHandlerThread::run()-
290{-
291 m_handler = new QEvdevTabletHandler(m_device, m_spec);-
292 exec();-
293 delete m_handler;-
294 m_handler = 0;-
295}
never executed: end of block
0
296-
297-
298QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9