Introduce QInputDevice hierarchy; replace QTouchDevice

We have seen during the Qt 5 series that QMouseEvent::source() does
not provide enough information: if it is synthesized, it could have
come from any device for which mouse events are synthesized, not only
from a touchscreen. By providing in every QInputEvent as complete
information about the actual source device as possible, we will enable
very fine-tuned behavior in the object that handles each event.

Further, we would like to support multiple keyboards, pointing devices,
and named groups of devices that are known as "seats" in Wayland.

In Qt 5, QPA plugins registered each touchscreen as it was discovered.
Now we extend this pattern to all input devices.  This new requirement
can be implemented gradually; for now, if a QTWSI input event is
received wtihout a device pointer, a default "core" device will be
created on-the-fly, and a warning emitted.

In Qt 5, QTouchEvent::TouchPoint::id() was forced to be unique even when
multiple devices were in use simultaneously. Now that each event
identifies the device it came from, this hack is no longer needed.

A stub of the new QPointerEvent is added; it will be developed further
in subsequent patches.

[ChangeLog][QtGui][QInputEvent] Every QInputEvent now carries a pointer
to an instance of QInputDevice, or the subclass QPointingDevice in case
of mouse, touch and tablet events. Each platform plugin is expected to
create the device instances, register them, and provide valid pointers
with all input events. If this is not done, warnings are emitted and
default devices are created as necessary. When the device has accurate
information, it provides the opportunity to fine-tune behavior depending
on device type and capabilities: for example if a QMouseEvent is
synthesized from a touchscreen, the recipient can see which touchscreen
it came from. Each device also has a seatName to distinguish users on
multi-user windowing systems. Touchpoint IDs are no longer unique on
their own, but the combination of ID and device is.

Fixes: QTBUG-46412
Fixes: QTBUG-72167
Task-number: QTBUG-69433
Task-number: QTBUG-52430
Change-Id: I933fb2b86182efa722037b7a33e404c5daf5292a
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Shawn Rutledge 2019-05-31 08:38:16 +02:00
parent 0a2e3ce85c
commit 6589f2ed0c
78 changed files with 2065 additions and 1270 deletions

View File

@ -208,7 +208,7 @@ bool ScribbleArea::event(QEvent *event)
QSizeF diams = touchPoint.ellipseDiameters();
if (diams.isEmpty()) {
qreal diameter = MaximumDiameter;
if (touch->device()->capabilities() & QTouchDevice::Pressure)
if (touch->pointingDevice()->capabilities().testFlag(QPointingDevice::Capability::Pressure))
diameter = MinimumDiameter + (MaximumDiameter - MinimumDiameter) * touchPoint.pressure();
diams = QSizeF(diameter, diameter);
}

View File

@ -106,7 +106,7 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
break;
case QEvent::TabletMove:
#ifndef Q_OS_IOS
if (event->deviceType() == QTabletEvent::RotationStylus)
if (event->pointingDevice() && event->pointingDevice()->capabilities().testFlag(QPointingDevice::Capability::Rotation))
updateCursor(event);
#endif
if (m_deviceDown) {
@ -163,7 +163,7 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
switch (event->deviceType()) {
//! [6]
case QTabletEvent::Airbrush:
case QInputDevice::DeviceType::Airbrush:
{
painter.setPen(Qt::NoPen);
QRadialGradient grad(lastPoint.pos, m_pen.widthF() * 10.0);
@ -177,29 +177,9 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
update(QRect(event->position().toPoint() - QPoint(radius, radius), QSize(radius * 2, radius * 2)));
}
break;
case QTabletEvent::RotationStylus:
{
m_brush.setStyle(Qt::SolidPattern);
painter.setPen(Qt::NoPen);
painter.setBrush(m_brush);
QPolygonF poly;
qreal halfWidth = pressureToWidth(lastPoint.pressure);
QPointF brushAdjust(qSin(qDegreesToRadians(-lastPoint.rotation)) * halfWidth,
qCos(qDegreesToRadians(-lastPoint.rotation)) * halfWidth);
poly << lastPoint.pos + brushAdjust;
poly << lastPoint.pos - brushAdjust;
halfWidth = m_pen.widthF();
brushAdjust = QPointF(qSin(qDegreesToRadians(-event->rotation())) * halfWidth,
qCos(qDegreesToRadians(-event->rotation())) * halfWidth);
poly << event->position() - brushAdjust;
poly << event->position() + brushAdjust;
painter.drawConvexPolygon(poly);
update(poly.boundingRect().toRect());
}
break;
//! [6]
case QTabletEvent::Puck:
case QTabletEvent::FourDMouse:
case QInputDevice::DeviceType::Puck:
case QInputDevice::DeviceType::Mouse:
{
const QString error(tr("This input device is not supported by the example."));
#if QT_CONFIG(statustip)
@ -221,11 +201,30 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
#endif
}
Q_FALLTHROUGH();
case QTabletEvent::Stylus:
painter.setPen(m_pen);
painter.drawLine(lastPoint.pos, event->position());
update(QRect(lastPoint.pos.toPoint(), event->position().toPoint()).normalized()
.adjusted(-maxPenRadius, -maxPenRadius, maxPenRadius, maxPenRadius));
case QInputDevice::DeviceType::Stylus:
if (event->pointingDevice()->capabilities().testFlag(QPointingDevice::Capability::Rotation)) {
m_brush.setStyle(Qt::SolidPattern);
painter.setPen(Qt::NoPen);
painter.setBrush(m_brush);
QPolygonF poly;
qreal halfWidth = pressureToWidth(lastPoint.pressure);
QPointF brushAdjust(qSin(qDegreesToRadians(-lastPoint.rotation)) * halfWidth,
qCos(qDegreesToRadians(-lastPoint.rotation)) * halfWidth);
poly << lastPoint.pos + brushAdjust;
poly << lastPoint.pos - brushAdjust;
halfWidth = m_pen.widthF();
brushAdjust = QPointF(qSin(qDegreesToRadians(-event->rotation())) * halfWidth,
qCos(qDegreesToRadians(-event->rotation())) * halfWidth);
poly << event->position() - brushAdjust;
poly << event->position() + brushAdjust;
painter.drawConvexPolygon(poly);
update(poly.boundingRect().toRect());
} else {
painter.setPen(m_pen);
painter.drawLine(lastPoint.pos, event->position());
update(QRect(lastPoint.pos.toPoint(), event->position().toPoint()).normalized()
.adjusted(-maxPenRadius, -maxPenRadius, maxPenRadius, maxPenRadius));
}
break;
}
}
@ -251,7 +250,7 @@ void TabletCanvas::updateBrush(const QTabletEvent *event)
m_color.setAlphaF(event->pressure());
break;
case TangentialPressureValuator:
if (event->deviceType() == QTabletEvent::Airbrush)
if (event->deviceType() == QInputDevice::DeviceType::Airbrush)
m_color.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0));
else
m_color.setAlpha(255);
@ -293,7 +292,7 @@ void TabletCanvas::updateBrush(const QTabletEvent *event)
}
//! [10] //! [11]
if (event->pointerType() == QTabletEvent::Eraser) {
if (event->pointerType() == QPointingDevice::PointerType::Eraser) {
m_brush.setColor(Qt::white);
m_pen.setColor(Qt::white);
m_pen.setWidthF(event->pressure() * 10 + 1);
@ -309,34 +308,35 @@ void TabletCanvas::updateCursor(const QTabletEvent *event)
{
QCursor cursor;
if (event->type() != QEvent::TabletLeaveProximity) {
if (event->pointerType() == QTabletEvent::Eraser) {
if (event->pointerType() == QPointingDevice::PointerType::Eraser) {
cursor = QCursor(QPixmap(":/images/cursor-eraser.png"), 3, 28);
} else {
switch (event->deviceType()) {
case QTabletEvent::Stylus:
cursor = QCursor(QPixmap(":/images/cursor-pencil.png"), 0, 0);
case QInputDevice::DeviceType::Stylus:
if (event->pointingDevice()->capabilities().testFlag(QPointingDevice::Capability::Rotation)) {
QImage origImg(QLatin1String(":/images/cursor-felt-marker.png"));
QImage img(32, 32, QImage::Format_ARGB32);
QColor solid = m_color;
solid.setAlpha(255);
img.fill(solid);
QPainter painter(&img);
QTransform transform = painter.transform();
transform.translate(16, 16);
transform.rotate(event->rotation());
painter.setTransform(transform);
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
painter.drawImage(-24, -24, origImg);
painter.setCompositionMode(QPainter::CompositionMode_HardLight);
painter.drawImage(-24, -24, origImg);
painter.end();
cursor = QCursor(QPixmap::fromImage(img), 16, 16);
} else {
cursor = QCursor(QPixmap(":/images/cursor-pencil.png"), 0, 0);
}
break;
case QTabletEvent::Airbrush:
case QInputDevice::DeviceType::Airbrush:
cursor = QCursor(QPixmap(":/images/cursor-airbrush.png"), 3, 4);
break;
case QTabletEvent::RotationStylus: {
QImage origImg(QLatin1String(":/images/cursor-felt-marker.png"));
QImage img(32, 32, QImage::Format_ARGB32);
QColor solid = m_color;
solid.setAlpha(255);
img.fill(solid);
QPainter painter(&img);
QTransform transform = painter.transform();
transform.translate(16, 16);
transform.rotate(event->rotation());
painter.setTransform(transform);
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
painter.drawImage(-24, -24, origImg);
painter.setCompositionMode(QPainter::CompositionMode_HardLight);
painter.drawImage(-24, -24, origImg);
painter.end();
cursor = QCursor(QPixmap::fromImage(img), 16, 16);
} break;
default:
break;
}

View File

@ -132,7 +132,8 @@ qt_add_module(Gui
kernel/qsurfaceformat.cpp kernel/qsurfaceformat.h
kernel/qtestsupport_gui.cpp kernel/qtestsupport_gui.h
kernel/qtguiglobal.h kernel/qtguiglobal_p.h
kernel/qtouchdevice.cpp kernel/qtouchdevice.h kernel/qtouchdevice_p.h
kernel/qinputdevice.cpp kernel/qinputdevice.h kernel/qinputdevice_p.h
kernel/qpointingdevice.cpp kernel/qpointingdevice.h kernel/qpointingdevice_p.h
kernel/qwindow.cpp kernel/qwindow.h kernel/qwindow_p.h
kernel/qwindowdefs.h
kernel/qwindowsysteminterface.cpp kernel/qwindowsysteminterface.h kernel/qwindowsysteminterface_p.h

View File

@ -45,6 +45,8 @@ HEADERS += \
kernel/qcursor_p.h \
kernel/qevent.h \
kernel/qevent_p.h \
kernel/qinputdevice.h \
kernel/qinputdevice_p.h \
kernel/qinputmethod.h \
kernel/qinputmethod_p.h \
kernel/qinternalmimedata_p.h \
@ -56,8 +58,8 @@ HEADERS += \
kernel/qscreen.h \
kernel/qscreen_p.h \
kernel/qstylehints.h \
kernel/qtouchdevice.h \
kernel/qtouchdevice_p.h \
kernel/qpointingdevice.h \
kernel/qpointingdevice_p.h \
kernel/qplatformsharedgraphicscache.h \
kernel/qplatformdialoghelper.h \
kernel/qplatformservices.h \
@ -103,6 +105,7 @@ SOURCES += \
kernel/qclipboard.cpp \
kernel/qcursor.cpp \
kernel/qevent.cpp \
kernel/qinputdevice.cpp \
kernel/qinputmethod.cpp \
kernel/qinternalmimedata.cpp \
kernel/qkeymapper.cpp \
@ -110,7 +113,7 @@ SOURCES += \
kernel/qguivariant.cpp \
kernel/qscreen.cpp \
kernel/qstylehints.cpp \
kernel/qtouchdevice.cpp \
kernel/qpointingdevice.cpp \
kernel/qplatformsharedgraphicscache.cpp \
kernel/qplatformdialoghelper.cpp \
kernel/qplatformservices.cpp \

View File

@ -40,7 +40,8 @@
#include "qevent.h"
#include "qcursor.h"
#include "private/qguiapplication_p.h"
#include "qtouchdevice.h"
#include "private/qinputdevice_p.h"
#include "private/qpointingdevice_p.h"
#include "qpa/qplatformintegration.h"
#include "private/qevent_p.h"
#include "qfile.h"
@ -152,8 +153,8 @@ QEnterEvent::~QEnterEvent()
/*!
\internal
*/
QInputEvent::QInputEvent(Type type, Qt::KeyboardModifiers modifiers)
: QEvent(type), modState(modifiers), ts(0)
QInputEvent::QInputEvent(Type type, const QInputDevice *dev, Qt::KeyboardModifiers modifiers)
: QEvent(type), m_dev(dev), modState(modifiers), ts(0)
{}
/*!
@ -163,6 +164,38 @@ QInputEvent::~QInputEvent()
{
}
QPointerEvent::QPointerEvent(QEvent::Type type, const QPointingDevice *dev, Qt::KeyboardModifiers modifiers)
: QInputEvent(type, dev, modifiers)
{
}
const QPointingDevice *QPointerEvent::pointingDevice() const
{
return static_cast<const QPointingDevice *>(m_dev);
}
/*!
\fn QInputDevice *QInputEvent::device() const
\since 6.0
Returns the source device that generated the original event.
In case of a synthesized event, for example a mouse event that was
generated from a touch event, \c device() continues to return the touchscreen
device, so that you can tell that it did not come from an actual mouse.
Thus \c {mouseEvent.source()->type() != QInputDevice::DeviceType::Mouse}
is one possible replacement for the Qt 5 expression
\c {mouseEvent.source() == Qt::MouseEventSynthesizedByQt}.
*/
/*!
\fn QInputDevice::DeviceType QInputEvent::deviceType() const
Returns the type of device that generated the event.
*/
/*!
\fn Qt::KeyboardModifiers QInputEvent::modifiers() const
@ -194,6 +227,12 @@ QInputEvent::~QInputEvent()
Sets the timestamp for this event.
*/
/*!
\fn QPointingDevice::PointerType QPointerEvent::pointerType() const
Returns the type of point that generated the event.
*/
/*!
\class QMouseEvent
\ingroup events
@ -265,7 +304,8 @@ QInputEvent::~QInputEvent()
*/
QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, Qt::MouseButton button,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
: QInputEvent(type, modifiers), l(localPos), w(localPos), b(button), mouseState(buttons), caps(0)
: QPointerEvent(type, QPointingDevice::primaryPointingDevice(), modifiers),
l(localPos), w(localPos), b(button), mouseState(buttons), caps(0)
{
#ifndef QT_NO_CURSOR
g = QCursor::pos();
@ -319,7 +359,8 @@ QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, const QPointF &glob
QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, const QPointF &scenePos, const QPointF &globalPos,
Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers)
: QInputEvent(type, modifiers), l(localPos), w(scenePos), g(globalPos), b(button), mouseState(buttons), caps(0)
: QPointerEvent(type, QPointingDevice::primaryPointingDevice(), modifiers),
l(localPos), w(scenePos), g(globalPos), b(button), mouseState(buttons), caps(0)
{}
/*!
@ -644,7 +685,7 @@ Qt::MouseEventFlags QMouseEvent::flags() const
of the event.
*/
QHoverEvent::QHoverEvent(Type type, const QPointF &pos, const QPointF &oldPos, Qt::KeyboardModifiers modifiers)
: QInputEvent(type, modifiers), p(pos), op(oldPos)
: QInputEvent(type, QPointingDevice::primaryPointingDevice(), modifiers), p(pos), op(oldPos)
{
}
@ -776,7 +817,8 @@ QHoverEvent::~QHoverEvent()
QWheelEvent::QWheelEvent(QPointF pos, QPointF globalPos, QPoint pixelDelta, QPoint angleDelta,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase,
bool inverted, Qt::MouseEventSource source)
: QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta), angleD(angleDelta),
: QPointerEvent(Wheel, QPointingDevice::primaryPointingDevice(), modifiers),
p(pos), g(globalPos), pixelD(pixelDelta), angleD(angleDelta),
mouseState(buttons), src(source), ph(phase), invertedScrolling(inverted)
{
}
@ -928,7 +970,7 @@ QWheelEvent::~QWheelEvent()
*/
QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, const QString& text,
bool autorep, ushort count)
: QInputEvent(type, modifiers), txt(text), k(key),
: QInputEvent(type, QInputDevice::primaryKeyboard(), modifiers), txt(text), k(key),
nScanCode(0), nVirtualKey(0), nModifiers(0),
c(count), autor(autorep)
{
@ -957,7 +999,7 @@ QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, const
QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
const QString &text, bool autorep, ushort count)
: QInputEvent(type, modifiers), txt(text), k(key),
: QInputEvent(type, QInputDevice::primaryKeyboard(), modifiers), txt(text), k(key),
nScanCode(nativeScanCode), nVirtualKey(nativeVirtualKey), nModifiers(nativeModifiers),
c(count), autor(autorep)
{
@ -1566,7 +1608,7 @@ QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos, const QPo
*/
QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos, const QPoint &globalPos,
Qt::KeyboardModifiers modifiers)
: QInputEvent(ContextMenu, modifiers), p(pos), gp(globalPos), reas(reason)
: QInputEvent(ContextMenu, QPointingDevice::primaryPointingDevice(), modifiers), p(pos), gp(globalPos), reas(reason)
{}
@ -1589,7 +1631,7 @@ QContextMenuEvent::~QContextMenuEvent()
position explicitly.
*/
QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos)
: QInputEvent(ContextMenu), p(pos), reas(reason)
: QInputEvent(ContextMenu, QInputDevice::primaryKeyboard()), p(pos), reas(reason)
{
#ifndef QT_NO_CURSOR
gp = QCursor::pos();
@ -2112,91 +2154,84 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const
*/
/*!
\enum QTabletEvent::TabletDevice
Construct a tablet event of the given \a type.
This enum defines what type of device is generating the event.
The \a pos parameter indicates where the event occurred in the widget;
\a globalPos is the corresponding position in absolute coordinates.
\value NoDevice No device, or an unknown device.
\value Puck A Puck (a device that is similar to a flat mouse with
a transparent circle with cross-hairs).
\value Stylus A Stylus.
\value Airbrush An airbrush
\value FourDMouse A 4D Mouse.
\value RotationStylus A special stylus that also knows about rotation
(a 6D stylus). \since 4.1
*/
\a pressure gives the pressure exerted on the \a device.
/*!
\enum QTabletEvent::PointerType
\a deviceType, of type \l QInputDevice::DeviceType,
indicates the type of stylus or other tool the event comes from.
This enum defines what type of point is generating the event.
\a pointerType should be one of QPointingDevice::PointerType::Pen or
QPointingDevice::PointerType::Eraser, depending on which end of the
stylus the event comes from; or QPointingDevice::PointerType::Cursor
if \a deviceType is QInputDevice::DeviceType::Puck.
\value UnknownPointer An unknown device.
\value Pen Tip end of a stylus-like device (the narrow end of the pen).
\value Cursor Any puck-like device.
\value Eraser Eraser end of a stylus-like device (the broad end of the pen).
\a xTilt and \a yTilt give the device's degree of tilt from the
x and y axes respectively.
\sa pointerType()
*/
\a keyState specifies which keyboard modifiers are pressed (e.g.,
\uicontrol{Ctrl}).
/*!
Construct a tablet event of the given \a type.
The \a uniqueID parameter gives the serial number of the current tool.
The \a pos parameter indicates where the event occurred in the
widget; \a globalPos is the corresponding position in absolute
coordinates.
The \a z parameter gives the Z coordinate of the device on the tablet;
this is usually given by a wheel on a 4D mouse. If the device does not
support a Z-axis (i.e. \l QPointingDevice::capabilities() does not include
\c ZPosition), pass \c 0 here.
\a pressure contains the pressure exerted on the \a device.
The \a tangentialPressure parameter gives the tangential pressure
thumbwheel value from an airbrush. If the device does not support
tangential pressure (i.e. \l QPointingDevice::capabilities() does not
include \c TangentialPressure), pass \c 0 here.
\a pointerType describes the type of pen that is being used.
\a rotation gives the device's rotation in degrees.
4D mice, the Wacom Art Pen, and the Apple Pencil support rotation.
If the device does not support rotation (i.e. \l QPointingDevice::capabilities()
does not include \c Rotation), pass \c 0 here.
\a xTilt and \a yTilt contain the device's degree of tilt from the
x and y axes respectively.
The \a button that caused the event is given as a value from the
\l Qt::MouseButton enum. If the event \a type is not \l TabletPress or
\l TabletRelease, the appropriate button for this event is \l Qt::NoButton.
\a keyState specifies which keyboard modifiers are pressed (e.g.,
\uicontrol{Ctrl}).
\a buttons is the state of all buttons at the time of the event.
The \a uniqueID parameter contains the unique ID for the current device.
The \a z parameter contains the coordinate of the device on the tablet, this
is usually given by a wheel on 4D mouse. If the device does not support a
Z-axis, pass zero here.
The \a tangentialPressure parameter contins the tangential pressure of an air
brush. If the device does not support tangential pressure, pass 0 here.
\a rotation contains the device's rotation in degrees.
4D mice, the Wacom Art Pen, and the Apple Pencil support rotation.
If the device does not support rotation, pass 0 here.
The \a button that caused the event is given as a value from the
\l Qt::MouseButton enum. If the event \a type is not \l TabletPress or
\l TabletRelease, the appropriate button for this event is \l Qt::NoButton.
\a buttons is the state of all buttons at the time of the event.
\sa pos(), globalPos(), device(), pressure(), xTilt(), yTilt(), uniqueId(), rotation(),
\sa pos(), globalPos(), device(), pressure(), xTilt(), yTilt(), uniqueId(), rotation(),
tangentialPressure(), z()
*/
QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalPos,
int device, int pointerType,
int deviceType, int pointerType, // TODO use the enums rather than int
qreal pressure, int xTilt, int yTilt, qreal tangentialPressure,
qreal rotation, int z, Qt::KeyboardModifiers keyState, qint64 uniqueID,
Qt::MouseButton button, Qt::MouseButtons buttons)
: QInputEvent(type, keyState),
: QTabletEvent(type,
QPointingDevice::tabletDevice(QInputDevice::DeviceType(deviceType),
QPointingDevice::PointerType(pointerType),
QPointingDeviceUniqueId::fromNumericId(uniqueID)),
pos, globalPos, pressure, xTilt, yTilt, tangentialPressure,
rotation, z, keyState, button, buttons)
{
Q_ASSERT(m_dev);
}
QTabletEvent::QTabletEvent(Type type, const QPointingDevice *dev, const QPointF &pos, const QPointF &globalPos,
qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
Qt::KeyboardModifiers keyState,
Qt::MouseButton button, Qt::MouseButtons buttons)
: QPointerEvent(type, dev, keyState),
mPos(pos),
mGPos(globalPos),
mDev(device),
mPointerType(pointerType),
mXT(xTilt),
mYT(yTilt),
mZ(z),
mPress(pressure),
mTangential(tangentialPressure),
mRot(rotation),
mUnique(uniqueID),
mExtra(new QTabletEventPrivate(button, buttons))
mButton(button),
mButtons(buttons)
{
}
@ -2205,10 +2240,11 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP
*/
QTabletEvent::~QTabletEvent()
{
delete static_cast<QTabletEventPrivate *>(mExtra);
}
/*!
\fn Qt::MouseButton QTabletEvent::button() const
Returns the button that caused the event.
Note that the returned value is always Qt::NoButton for \l TabletMove,
@ -2216,12 +2252,10 @@ QTabletEvent::~QTabletEvent()
\sa buttons(), Qt::MouseButton
*/
Qt::MouseButton QTabletEvent::button() const
{
return static_cast<QTabletEventPrivate *>(mExtra)->b;
}
/*!
\fn Qt::MouseButtons QTabletEvent::buttons() const
Returns the button state when the event was generated. The button state is
a combination of buttons from the \l Qt::MouseButton enum using the OR
operator. For \l TabletMove events, this is all buttons that are pressed
@ -2231,24 +2265,6 @@ Qt::MouseButton QTabletEvent::button() const
\sa button(), Qt::MouseButton
*/
Qt::MouseButtons QTabletEvent::buttons() const
{
return static_cast<QTabletEventPrivate *>(mExtra)->buttonState;
}
/*!
\fn TabletDevices QTabletEvent::deviceType() const
Returns the type of device that generated the event.
\sa TabletDevice
*/
/*!
\fn PointerType QTabletEvent::pointerType() const
Returns the type of point that generated the event.
*/
/*!
\fn qreal QTabletEvent::tangentialPressure() const
@ -2479,11 +2495,12 @@ Qt::MouseButtons QTabletEvent::buttons() const
\a realValue is the \macos event parameter, \a sequenceId and \a intValue are the Windows event parameters.
\since 5.10
*/
QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QTouchDevice *device, const QPointF &localPos, const QPointF &scenePos,
const QPointF &globalPos, qreal realValue, ulong sequenceId, quint64 intValue)
: QInputEvent(QEvent::NativeGesture), mGestureType(type),
QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QPointingDevice *device,
const QPointF &localPos, const QPointF &scenePos, const QPointF &globalPos,
qreal realValue, ulong sequenceId, quint64 intValue)
: QPointerEvent(QEvent::NativeGesture, device), mGestureType(type),
mLocalPos(localPos), mScenePos(scenePos), mGlobalPos(globalPos), mRealValue(realValue),
mSequenceId(sequenceId), mIntValue(intValue), mDevice(device)
mSequenceId(sequenceId), mIntValue(intValue)
{
}
@ -2491,7 +2508,7 @@ QNativeGestureEvent::~QNativeGestureEvent()
= default;
/*!
\fn const QTouchDevice *QNativeGestureEvent::device() const
\fn const QPointingDevice *QNativeGestureEvent::device() const
\since 5.10
Returns the device.
@ -3617,9 +3634,9 @@ static void formatTabletEvent(QDebug d, const QTabletEvent *e)
QtDebugUtils::formatQFlags(d, e->buttons());
if (type == QEvent::TabletPress || type == QEvent::TabletMove)
d << ", pressure=" << e->pressure();
if (e->deviceType() == QTabletEvent::RotationStylus || e->deviceType() == QTabletEvent::FourDMouse)
if (e->device()->hasCapability(QInputDevice::Capability::Rotation))
d << ", rotation=" << e->rotation();
if (e->deviceType() == QTabletEvent::Airbrush)
if (e->deviceType() == QInputDevice::DeviceType::Airbrush)
d << ", tangentialPressure=" << e->tangentialPressure();
}
@ -4065,14 +4082,13 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent()
the event.
*/
QTouchEvent::QTouchEvent(QEvent::Type eventType,
QTouchDevice *device,
const QPointingDevice *device,
Qt::KeyboardModifiers modifiers,
Qt::TouchPointStates touchPointStates,
const QList<QTouchEvent::TouchPoint> &touchPoints)
: QInputEvent(eventType, modifiers),
: QPointerEvent(eventType, device, modifiers),
_window(nullptr),
_target(nullptr),
_device(device),
_touchPointStates(touchPointStates),
_touchPoints(touchPoints)
{ }
@ -4113,7 +4129,7 @@ QTouchEvent::~QTouchEvent()
Returns the list of touch points contained in the touch event.
*/
/*! \fn QTouchDevice* QTouchEvent::device() const
/*! \fn QPointingDevice* QTouchEvent::device() const
Returns the touch device from which this touch event originates.
*/
@ -4132,13 +4148,6 @@ QTouchEvent::~QTouchEvent()
Sets the target within the window (typically a widget) for this event.
*/
/*! \fn void QTouchEvent::setTouchPointStates(Qt::TouchPointStates touchPointStates)
\internal
Sets a bitwise OR of all the touch point states for this event.
*/
/*! \fn void QTouchEvent::setTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints)
\internal
@ -4146,13 +4155,6 @@ QTouchEvent::~QTouchEvent()
Sets the list of touch points for this event.
*/
/*! \fn void QTouchEvent::setDevice(QTouchDevice *adevice)
\internal
Sets the device to \a adevice.
*/
/*! \class QTouchEvent::TouchPoint
\brief The TouchPoint class provides information about a touch point in a QTouchEvent.
\since 4.6
@ -4461,9 +4463,9 @@ QSizeF QTouchEvent::TouchPoint::ellipseDiameters() const
Returns a velocity vector for this touch point.
The vector is in the screen's coordinate system, using pixels per seconds for the magnitude.
\note The returned vector is only valid if the touch device's capabilities include QTouchDevice::Velocity.
\note The returned vector is only valid if the touch device's capabilities include QPointingDevice::Velocity.
\sa QTouchDevice::capabilities(), device()
\sa QPointingDevice::capabilities(), device()
*/
QVector2D QTouchEvent::TouchPoint::velocity() const
{
@ -4485,14 +4487,14 @@ QTouchEvent::TouchPoint::InfoFlags QTouchEvent::TouchPoint::flags() const
Returns the raw, unfiltered positions for the touch point. The positions are in native screen coordinates.
To get local coordinates you can use mapFromGlobal() of the QWindow returned by QTouchEvent::window().
\note Returns an empty vector if the touch device's capabilities do not include QTouchDevice::RawPositions.
\note Returns an empty vector if the touch device's capabilities do not include QPointingDevice::RawPositions.
\note Native screen coordinates refer to the native orientation of the screen which, in case of
mobile devices, is typically portrait. This means that on systems capable of screen orientation
changes the positions in this list will not reflect the current orientation (unlike pos(),
screenPos(), etc.) and will always be reported in the native orientation.
\sa QTouchDevice::capabilities(), device(), window()
\sa QPointingDevice::capabilities(), device(), window()
*/
QVector<QPointF> QTouchEvent::TouchPoint::rawScreenPositions() const
{

View File

@ -49,6 +49,7 @@
#include <QtCore/qvariant.h>
#include <QtCore/qvector.h>
#include <QtCore/qurl.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/qregion.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qwindowdefs.h>
@ -61,8 +62,9 @@ QT_BEGIN_NAMESPACE
class QFile;
class QAction;
class QInputDevice;
class QPointingDevice;
class QScreen;
class QTouchDevice;
#if QT_CONFIG(gestures)
class QGesture;
#endif
@ -70,17 +72,30 @@ class QGesture;
class Q_GUI_EXPORT QInputEvent : public QEvent
{
public:
explicit QInputEvent(Type type, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
explicit QInputEvent(Type type, const QInputDevice *m_dev, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
~QInputEvent();
const QInputDevice *device() const { return m_dev; }
QInputDevice::DeviceType deviceType() const { return m_dev ? m_dev->type() : QInputDevice::DeviceType::Unknown; }
inline Qt::KeyboardModifiers modifiers() const { return modState; }
inline void setModifiers(Qt::KeyboardModifiers amodifiers) { modState = amodifiers; }
inline ulong timestamp() const { return ts; }
inline void setTimestamp(ulong atimestamp) { ts = atimestamp; }
protected:
const QInputDevice *m_dev = nullptr;
Qt::KeyboardModifiers modState;
ulong ts;
};
class Q_GUI_EXPORT QPointerEvent : public QInputEvent
{
public:
explicit QPointerEvent(Type type, const QPointingDevice *dev, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
const QPointingDevice *pointingDevice() const;
QPointingDevice::PointerType pointerType() const {
return pointingDevice() ? pointingDevice()->pointerType() : QPointingDevice::PointerType::Unknown;
}
};
class Q_GUI_EXPORT QEnterEvent : public QEvent
{
public:
@ -118,7 +133,7 @@ protected:
QPointF l, s, g;
};
class Q_GUI_EXPORT QMouseEvent : public QInputEvent
class Q_GUI_EXPORT QMouseEvent : public QPointerEvent
{
public:
QMouseEvent(Type type, const QPointF &localPos, Qt::MouseButton button,
@ -207,7 +222,7 @@ protected:
};
#if QT_CONFIG(wheelevent)
class Q_GUI_EXPORT QWheelEvent : public QInputEvent
class Q_GUI_EXPORT QWheelEvent : public QPointerEvent
{
public:
enum { DefaultDeltasPerStep = 120 };
@ -247,20 +262,20 @@ protected:
#endif
#if QT_CONFIG(tabletevent)
class Q_GUI_EXPORT QTabletEvent : public QInputEvent
class Q_GUI_EXPORT QTabletEvent : public QPointerEvent
{
Q_GADGET
public:
enum TabletDevice { NoDevice, Puck, Stylus, Airbrush, FourDMouse, RotationStylus };
Q_ENUM(TabletDevice)
enum PointerType { UnknownPointer, Pen, Cursor, Eraser };
Q_ENUM(PointerType)
QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos,
int device, int pointerType, qreal pressure, int xTilt, int yTilt,
int deviceType, int pointerType, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
Qt::KeyboardModifiers keyState, qint64 uniqueID,
Qt::MouseButton button, Qt::MouseButtons buttons);
QTabletEvent(Type t, const QPointingDevice *dev, const QPointF &pos, const QPointF &globalPos,
qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
Qt::KeyboardModifiers keyState,
Qt::MouseButton button, Qt::MouseButtons buttons);
~QTabletEvent();
#if QT_DEPRECATED_SINCE(6, 0)
@ -288,35 +303,31 @@ public:
#endif
inline QPointF position() const { return mPos; }
inline QPointF globalPosition() const { return mGPos; }
inline TabletDevice deviceType() const { return TabletDevice(mDev); }
inline PointerType pointerType() const { return PointerType(mPointerType); }
inline qint64 uniqueId() const { return mUnique; }
inline qint64 uniqueId() const { return pointingDevice() ? pointingDevice()->uniqueId().numericId() : -1; }
inline qreal pressure() const { return mPress; }
inline int z() const { return mZ; }
inline qreal tangentialPressure() const { return mTangential; }
inline qreal rotation() const { return mRot; }
inline int xTilt() const { return mXT; }
inline int yTilt() const { return mYT; }
Qt::MouseButton button() const;
Qt::MouseButtons buttons() const;
inline Qt::MouseButton button() const { return mButton; }
inline Qt::MouseButtons buttons() const { return mButtons; }
protected:
QPointF mPos, mGPos;
int mDev, mPointerType, mXT, mYT, mZ;
int mXT, mYT, mZ;
qreal mPress, mTangential, mRot;
qint64 mUnique;
// QTabletEventPrivate for extra storage.
// ### Qt 6: QPointingEvent will have Buttons, QTabletEvent will inherit
void *mExtra;
// TODO refactor to parent class along with QMouseEvent's button storage
Qt::MouseButton mButton;
Qt::MouseButtons mButtons;
};
#endif // QT_CONFIG(tabletevent)
#if QT_CONFIG(gestures)
class Q_GUI_EXPORT QNativeGestureEvent : public QInputEvent
class Q_GUI_EXPORT QNativeGestureEvent : public QPointerEvent
{
public:
QNativeGestureEvent(Qt::NativeGestureType type, const QTouchDevice *dev, const QPointF &localPos, const QPointF &scenePos,
QNativeGestureEvent(Qt::NativeGestureType type, const QPointingDevice *dev, const QPointF &localPos, const QPointF &scenePos,
const QPointF &globalPos, qreal value, ulong sequenceId, quint64 intArgument);
~QNativeGestureEvent();
Qt::NativeGestureType gestureType() const { return mGestureType; }
@ -341,8 +352,6 @@ public:
QPointF scenePosition() const { return mScenePos; }
QPointF globalPosition() const { return mGlobalPos; }
const QTouchDevice *device() const { return mDevice; }
protected:
Qt::NativeGestureType mGestureType;
QPointF mLocalPos;
@ -351,7 +360,6 @@ protected:
qreal mRealValue;
ulong mSequenceId;
quint64 mIntValue;
const QTouchDevice *mDevice;
};
#endif // QT_CONFIG(gestures)
@ -817,38 +825,8 @@ inline bool operator==(QKeyEvent *e, QKeySequence::StandardKey key){return (e ?
inline bool operator==(QKeySequence::StandardKey key, QKeyEvent *e){return (e ? e->matches(key) : false);}
#endif // QT_CONFIG(shortcut)
class Q_GUI_EXPORT QPointingDeviceUniqueId
{
Q_GADGET
Q_PROPERTY(qint64 numericId READ numericId CONSTANT)
public:
Q_ALWAYS_INLINE
Q_DECL_CONSTEXPR QPointingDeviceUniqueId() noexcept : m_numericId(-1) {}
// compiler-generated copy/move ctor/assignment operators are ok!
// compiler-generated dtor is ok!
static QPointingDeviceUniqueId fromNumericId(qint64 id);
Q_ALWAYS_INLINE Q_DECL_CONSTEXPR bool isValid() const noexcept { return m_numericId != -1; }
qint64 numericId() const noexcept;
private:
// TODO: for TUIO 2, or any other type of complex token ID, an internal
// array (or hash) can be added to hold additional properties.
// In this case, m_numericId will then turn into an index into that array (or hash).
qint64 m_numericId;
};
Q_DECLARE_TYPEINFO(QPointingDeviceUniqueId, Q_MOVABLE_TYPE);
Q_GUI_EXPORT bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) noexcept;
inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) noexcept
{ return !operator==(lhs, rhs); }
Q_GUI_EXPORT size_t qHash(QPointingDeviceUniqueId key, size_t seed = 0) noexcept;
class QTouchEventTouchPointPrivate;
class Q_GUI_EXPORT QTouchEvent : public QInputEvent
class Q_GUI_EXPORT QTouchEvent : public QPointerEvent
{
public:
class Q_GUI_EXPORT TouchPoint
@ -963,7 +941,7 @@ public:
};
explicit QTouchEvent(QEvent::Type eventType,
QTouchDevice *device = nullptr,
const QPointingDevice *source = nullptr,
Qt::KeyboardModifiers modifiers = Qt::NoModifier,
Qt::TouchPointStates touchPointStates = Qt::TouchPointStates(),
const QList<QTouchEvent::TouchPoint> &touchPoints = QList<QTouchEvent::TouchPoint>());
@ -973,21 +951,17 @@ public:
inline QObject *target() const { return _target; }
inline Qt::TouchPointStates touchPointStates() const { return _touchPointStates; }
inline const QList<QTouchEvent::TouchPoint> &touchPoints() const { return _touchPoints; }
inline QTouchDevice *device() const { return _device; }
// ### Qt 6: move private, rename appropriately, only friends can call them; or just let friends modify variables directly
#if QT_DEPRECATED_SINCE(6, 0)
inline void setWindow(QWindow *awindow) { _window = awindow; }
inline void setTarget(QObject *atarget) { _target = atarget; }
inline void setTouchPointStates(Qt::TouchPointStates aTouchPointStates) { _touchPointStates = aTouchPointStates; }
inline void setTouchPoints(const QList<QTouchEvent::TouchPoint> &atouchPoints) { _touchPoints = atouchPoints; }
inline void setDevice(QTouchDevice *adevice) { _device = adevice; }
#endif // QT_DEPRECATED_SINCE(6, 0)
protected:
QWindow *_window;
QObject *_target;
QTouchDevice *_device;
Qt::TouchPointStates _touchPointStates;
QList<QTouchEvent::TouchPoint> _touchPoints;

View File

@ -43,7 +43,7 @@
#include <QtGui/private/qtguiglobal_p.h>
#include <QtCore/qurl.h>
#include <QtGui/qevent.h>
#include <QtGui/private/qpointingdevice_p.h>
QT_BEGIN_NAMESPACE
@ -96,20 +96,6 @@ public:
QVector<QPointF> rawScreenPositions;
};
#if QT_CONFIG(tabletevent)
class QTabletEventPrivate
{
public:
inline QTabletEventPrivate(Qt::MouseButton button, Qt::MouseButtons buttons)
: b(button),
buttonState(buttons)
{ }
Qt::MouseButton b;
Qt::MouseButtons buttonState;
};
#endif // QT_CONFIG(tabletevent)
QT_END_NAMESPACE
#endif // QEVENT_P_H

View File

@ -44,7 +44,7 @@
#include <qpa/qplatformintegrationfactory_p.h>
#include "private/qevent_p.h"
#include "qfont.h"
#include "qtouchdevice.h"
#include "qpointingdevice.h"
#include <qpa/qplatformfontdatabase.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformnativeinterface.h>
@ -86,7 +86,7 @@
#include "private/qopenglcontext_p.h"
#include "private/qinputdevicemanager_p.h"
#include "private/qinputmethod_p.h"
#include "private/qtouchdevice_p.h"
#include "private/qpointingdevice_p.h"
#include <qpa/qplatformthemefactory_p.h>
@ -200,7 +200,7 @@ static Qt::LayoutDirection layout_direction = Qt::LayoutDirectionAuto;
static bool force_reverse = false;
QGuiApplicationPrivate *QGuiApplicationPrivate::self = nullptr;
QTouchDevice *QGuiApplicationPrivate::m_fakeTouchDevice = nullptr;
QPointingDevice *QGuiApplicationPrivate::m_fakeTouchDevice = nullptr;
int QGuiApplicationPrivate::m_fakeMouseSourcePointId = 0;
#ifndef QT_NO_CLIPBOARD
@ -2234,8 +2234,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
&& !e->nonClientArea
&& qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) {
if (!m_fakeTouchDevice) {
m_fakeTouchDevice = new QTouchDevice;
QWindowSystemInterface::registerTouchDevice(m_fakeTouchDevice);
m_fakeTouchDevice = new QPointingDevice;
QWindowSystemInterface::registerInputDevice(m_fakeTouchDevice);
}
QList<QWindowSystemInterface::TouchPoint> points;
QWindowSystemInterface::TouchPoint point;
@ -2259,7 +2259,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
QEvent::Type type;
QList<QTouchEvent::TouchPoint> touchPoints =
QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, QTouchDevicePrivate::get(m_fakeTouchDevice)->id, &type);
QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, &type);
QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers);
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
@ -2832,7 +2832,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
ActiveTouchPointsValue &touchInfo = d->activeTouchPoints[touchInfoKey];
switch (touchPoint.state()) {
case Qt::TouchPointPressed:
if (e->device->type() == QTouchDevice::TouchPad) {
if (e->device->type() == QInputDevice::DeviceType::TouchPad) {
// on touch-pads, send all touch points to the same widget
w = d->activeTouchPoints.isEmpty()
? QPointer<QWindow>()
@ -2997,7 +2997,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
if (!e->synthetic() && !touchEvent.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) {
// exclude devices which generate their own mouse events
if (!(touchEvent.device()->capabilities() & QTouchDevice::MouseEmulation)) {
if (!(touchEvent.device()->capabilities().testFlag(QInputDevice::Capability::MouseEmulation))) {
if (eventType == QEvent::TouchEnd)
self->synthesizedMousePoints.clear();
@ -4271,7 +4271,7 @@ Qt::MouseEventSource QGuiApplicationPrivate::mouseEventSource(const QMouseEvent
void QGuiApplicationPrivate::setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source)
{
// Mouse event synthesization status is encoded in the caps field because
// QTouchDevice::CapabilityFlag uses only 6 bits from it.
// QPointingDevice::Capability uses only 6 bits from it.
int value = source;
Q_ASSERT(value <= MouseSourceMaskSrc);
event->caps &= ~MouseSourceMaskDst;

View File

@ -285,8 +285,8 @@ public:
#endif
struct ActiveTouchPointsKey {
ActiveTouchPointsKey(QTouchDevice *dev, int id) : device(dev), touchPointId(id) { }
QTouchDevice *device;
ActiveTouchPointsKey(const QPointingDevice *dev, int id) : device(dev), touchPointId(id) { }
const QPointingDevice *device;
int touchPointId;
};
struct ActiveTouchPointsValue {
@ -357,7 +357,7 @@ private:
friend class QDragManager;
static QGuiApplicationPrivate *self;
static QTouchDevice *m_fakeTouchDevice;
static QPointingDevice *m_fakeTouchDevice;
static int m_fakeMouseSourcePointId;
QSharedPointer<QColorTrcLut> m_a8ColorProfile;
QSharedPointer<QColorTrcLut> m_a32ColorProfile;

View File

@ -0,0 +1,293 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qinputdevice.h"
#include "qinputdevice_p.h"
#include <QCoreApplication>
#include <QDebug>
#include <QMutex>
#include <QScreen>
QT_BEGIN_NAMESPACE
/*!
\class QInputDevice
\brief The QInputDevice class describes a device from which a QInputEvent originates.
\since 6.0
\inmodule QtGui
Each QInputEvent contains a QInputDevice pointer to allow accessing
device-specific properties like type, capabilities and seat. It is the
responsibility of the platform or generic plug-ins to discover, create and
register an instance of this class corresponding to each available input
device, via QWindowSystemInterface::registerInputDevice(), before
generating any input event referring to that device.
Applications do not need to instantiate this class, but can read the
instances pointed to by QInputEvent::device() and QInputDevice::devices().
*/
/*!
Creates a new invalid input device instance.
*/
QInputDevice::QInputDevice()
: QObject(*(new QInputDevicePrivate(QString(), -1, QInputDevice::DeviceType::Unknown)), nullptr)
{
}
QInputDevice::~QInputDevice()
{
QInputDevicePrivate::unregisterDevice(this);
}
/*!
Creates a new input device instance. The given \a name is normally a
manufacturer-assigned model name if available, or something else
identifiable; \a id is a platform-specific number that will be unique per
device (for example the xinput ID on X11); \a type identifies what kind of
device. On window systems that are capable of handling input from multiple
users or sets of input devices at the same time (such as Wayland or X11),
\a seatName identifies the name of the set of devices that will be used
together. If the device is a child or slave device (for example one of
several mice that can take turns moving the "core pointer"), the master
device should be given as the \a parent.
The platform plugin creates, registers and continues to own each device
instance; usually \a parent should be given for memory management purposes
even if there is no master for a particular device.
By default, capabilities() are \c None.
*/
QInputDevice::QInputDevice(const QString &name, qint64 id, QInputDevice::DeviceType type,
const QString &seatName, QObject *parent)
: QObject(*new QInputDevicePrivate(name, id, type, QInputDevice::Capability::None, seatName), parent)
{
}
/*!
\internal
*/
QInputDevice::QInputDevice(QInputDevicePrivate &d, QObject *parent)
: QObject(d, parent)
{
}
/*!
Returns the device name.
This string may be empty. It is however useful on systems that have
multiple input devices: it can be used to differentiate from which device a
QPointerEvent originates.
*/
QString QInputDevice::name() const
{
Q_D(const QInputDevice);
return d->name;
}
/*!
Returns the device type.
*/
QInputDevice::DeviceType QInputDevice::type() const
{
Q_D(const QInputDevice);
return d->deviceType;
}
/*!
Returns the device capabilities.
*/
QInputDevice::Capabilities QInputDevice::capabilities() const
{
Q_D(const QInputDevice);
return QInputDevice::Capabilities(d->capabilities);
}
/*!
Returns whether the device capabilities include the given \a capability.
*/
bool QInputDevice::hasCapability(QInputDevice::Capability capability) const
{
return capabilities().testFlag(capability);
}
/*!
Returns the platform ID (for example xinput ID on the X11 platform).
All platforms are expected to provide a unique ID for each device.
*/
qint64 QInputDevice::id() const
{
Q_D(const QInputDevice);
return d->id;
}
/*!
Returns the seat with which the device is associated, if known; otherwise empty.
Devices that are intended to be used together by one user may be configured
to have the same seat name. That is only possible on Wayland and X11
platforms so far.
*/
QString QInputDevice::seatName() const
{
Q_D(const QInputDevice);
return d->seatName;
}
typedef QVector<const QInputDevice *> InputDevicesVector;
Q_GLOBAL_STATIC(InputDevicesVector, deviceList)
static QBasicMutex devicesMutex;
/*!
Returns a list of all registered input devices (keyboards and pointing devices).
\note The returned list cannot be used to add new devices. To add a simulated
touch screen for an autotest, QTest::createTouchDevice() can be used.
Platform plugins should call \l QWindowSystemInterface::registerInputDevice()
to add devices as they are discovered.
*/
QVector<const QInputDevice *> QInputDevice::devices()
{
QMutexLocker lock(&devicesMutex);
return *deviceList();
}
/*!
Returns the core or master keyboard on the given seat \a seatName.
*/
const QInputDevice *QInputDevice::primaryKeyboard(const QString& seatName)
{
QMutexLocker locker(&devicesMutex);
InputDevicesVector v = *deviceList();
locker.unlock();
const QInputDevice *ret = nullptr;
for (const QInputDevice *d : v) {
if (d->type() == DeviceType::Keyboard && d->seatName() == seatName) {
// the master keyboard's parent is not another input device
if (!d->parent() || !qobject_cast<const QInputDevice *>(d->parent()))
return d;
if (!ret)
ret = d;
}
}
if (!ret) {
qWarning() << "no keyboards registered for seat" << seatName
<< "The platform plugin should have provided one via "
"QWindowSystemInterface::registerInputDevice(). Creating a default one for now.";
ret = new QInputDevice(QLatin1String("core keyboard"), 0, DeviceType::Keyboard, seatName);
QInputDevicePrivate::registerDevice(ret);
return ret;
}
qWarning() << "core keyboard ambiguous for seat" << seatName;
return ret;
}
/*!
\internal
Checks whether a matching device is already registered
(via operator==, not pointer equality).
*/
bool QInputDevicePrivate::isRegistered(const QInputDevice *dev)
{
if (!dev)
return false;
QMutexLocker locker(&devicesMutex);
InputDevicesVector v = *deviceList();
for (const QInputDevice *d : v)
if (d && *d == *dev)
return true;
return false;
}
/*!
\internal
Find the device with the given \a id, which must be unique.
\note Use QPointingDevice::tabletDevice() if the device is a tablet
or a tablet stylus; in that case, \a id is not unique.
*/
const QInputDevice *QInputDevicePrivate::fromId(qint64 id)
{
QMutexLocker locker(&devicesMutex);
for (const QInputDevice *dev : *deviceList())
if (const_cast<QInputDevicePrivate *>(QInputDevicePrivate::get(dev))->id == id)
return dev;
return nullptr;
}
void QInputDevicePrivate::registerDevice(const QInputDevice *dev)
{
QMutexLocker lock(&devicesMutex);
deviceList()->append(dev);
}
/*!
\internal
*/
void QInputDevicePrivate::unregisterDevice(const QInputDevice *dev)
{
QMutexLocker lock(&devicesMutex);
deviceList()->removeOne(dev);
}
bool QInputDevice::operator==(const QInputDevice &other) const
{
return id() == other.id();
}
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QInputDevice *device)
{
QDebugStateSaver saver(debug);
debug.nospace();
debug.noquote();
debug << "QInputDevice(";
if (device) {
debug << '"' << device->name() << "\", type=" << device->type()
<< Qt::hex << ", ID=" << device->id() << ", seat='" << device->seatName() << "'";
} else {
debug << '0';
}
debug << ')';
return debug;
}
#endif // !QT_NO_DEBUG_STREAM
QT_END_NAMESPACE

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@ -37,65 +37,94 @@
**
****************************************************************************/
#ifndef QTOUCHDEVICE_H
#define QTOUCHDEVICE_H
#ifndef QINPUTDEVICE_H
#define QINPUTDEVICE_H
#include <QtGui/qtguiglobal.h>
#include <QtCore/qobject.h>
#include <QtGui/qscreen.h>
QT_BEGIN_NAMESPACE
class QDebug;
class QTouchDevicePrivate;
class QInputDevicePrivate;
class Q_GUI_EXPORT QTouchDevice
class Q_GUI_EXPORT QInputDevice : public QObject
{
Q_GADGET
public:
enum DeviceType {
TouchScreen,
TouchPad
};
Q_ENUM(DeviceType)
Q_OBJECT
Q_DECLARE_PRIVATE(QInputDevice)
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(DeviceType type READ type CONSTANT)
Q_PROPERTY(Capabilities capabilities READ capabilities CONSTANT)
Q_PROPERTY(qint64 id READ id CONSTANT)
Q_PROPERTY(QString seatName READ seatName CONSTANT)
enum CapabilityFlag {
public:
enum class DeviceType : qint16 {
Unknown = 0x0000,
Mouse = 0x0001,
TouchScreen = 0x0002,
TouchPad = 0x0004,
Puck = 0x0008,
Stylus = 0x0010,
Airbrush = 0x0020,
Keyboard = 0x1000,
AllDevices = 0x7FFF
};
Q_DECLARE_FLAGS(DeviceTypes, DeviceType)
Q_FLAG(DeviceTypes)
enum class Capability : qint32 {
None = 0,
Position = 0x0001,
Area = 0x0002,
Pressure = 0x0004,
Velocity = 0x0008,
RawPositions = 0x0010,
NormalizedPosition = 0x0020,
MouseEmulation = 0x0040
MouseEmulation = 0x0040,
Scroll = 0x0100,
Hover = 0x0200,
Rotation = 0x0400,
XTilt = 0x0800,
YTilt = 0x1000,
TangentialPressure = 0x2000,
ZPosition = 0x4000,
All = 0x7FFFFFFF
};
Q_FLAG(CapabilityFlag)
Q_DECLARE_FLAGS(Capabilities, CapabilityFlag)
Q_DECLARE_FLAGS(Capabilities, Capability)
Q_FLAG(Capabilities)
QTouchDevice();
~QTouchDevice();
static QList<const QTouchDevice *> devices();
QInputDevice();
~QInputDevice();
QInputDevice(const QString &name, qint64 id, DeviceType type,
const QString &seatName = QString(), QObject *parent = nullptr);
QString name() const;
DeviceType type() const;
Capabilities capabilities() const;
int maximumTouchPoints() const;
bool hasCapability(Capability cap) const;
qint64 id() const;
QString seatName() const;
void setName(const QString &name);
void setType(DeviceType devType);
void setCapabilities(Capabilities caps);
void setMaximumTouchPoints(int max);
static QVector<const QInputDevice *> devices();
static const QInputDevice *primaryKeyboard(const QString& seatName = QString());
private:
QTouchDevicePrivate *d;
friend class QTouchDevicePrivate;
bool operator==(const QInputDevice &other) const;
protected:
QInputDevice(QInputDevicePrivate &d, QObject *parent = nullptr);
Q_DISABLE_COPY_MOVE(QInputDevice)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QTouchDevice::Capabilities)
Q_DECLARE_OPERATORS_FOR_FLAGS(QInputDevice::DeviceTypes)
Q_DECLARE_OPERATORS_FOR_FLAGS(QInputDevice::Capabilities)
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug, const QTouchDevice *);
Q_GUI_EXPORT QDebug operator<<(QDebug, const QInputDevice *);
#endif
QT_END_NAMESPACE
#endif // QTOUCHDEVICE_H
#endif // QINPUTDEVICE_H

View File

@ -0,0 +1,103 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QINPUTDEVICE_P_H
#define QINPUTDEVICE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtGui/private/qtguiglobal_p.h>
#include <QtGui/qinputdevice.h>
#include "private/qobject_p.h"
QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QInputDevicePrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QInputDevice)
public:
QInputDevicePrivate(const QString &name, qint64 id, QInputDevice::DeviceType type,
QInputDevice::Capabilities caps = QInputDevice::Capability::None,
const QString &seatName = QString())
: name(name), seatName(seatName), id(id), capabilities(caps), deviceType(type)
{
// if the platform doesn't provide device IDs, make one up,
// but try to avoid clashing with OS-provided 32-bit IDs
static qint64 nextId = qint64(1) << 33;
if (!id)
id = nextId++;
}
QString name;
QString seatName;
QString busId;
void *extra = nullptr; // The QPA plugin can store arbitrary device-specific data here
void *qqExtra = nullptr; // Qt Quick can store arbitrary device-specific data here
qint64 id = 0;
qint32 capabilities = static_cast<qint32>(QInputDevice::Capability::None);
QInputDevice::DeviceType deviceType = QInputDevice::DeviceType::Unknown;
static void registerDevice(const QInputDevice *dev);
static void unregisterDevice(const QInputDevice *dev);
static bool isRegistered(const QInputDevice *dev);
static const QInputDevice *fromId(qint64 id); // window system ID (e.g. xinput id), not QPointingDeviceUniqueId
inline static QInputDevicePrivate *get(QInputDevice *q)
{
return static_cast<QInputDevicePrivate *>(QObjectPrivate::get(q));
}
inline static const QInputDevicePrivate *get(const QInputDevice *q)
{
return static_cast<const QInputDevicePrivate *>(QObjectPrivate::get(q));
}
};
QT_END_NAMESPACE
#endif // QINPUTDEVICE_P_H

View File

@ -0,0 +1,425 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qpointingdevice.h"
#include "qpointingdevice_p.h"
#include <QList>
#include <QLoggingCategory>
#include <QMutex>
#include <QCoreApplication>
#include <private/qdebug_p.h>
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaInputDevices)
/*!
\class QPointingDevice
\brief The QPointingDevice class describes a device from which mouse, touch or tablet events originate.
\since 6.0
\ingroup events
\inmodule QtGui
Each QPointerEvent contains a QPointingDevice pointer to allow accessing
device-specific properties like type and capabilities. It is the
responsibility of the platform or generic plug-ins to register the
available pointing devices via QWindowSystemInterface before generating any
pointer events. Applications do not need to instantiate this class, they
should just access the global instances pointed to by QPointerEvent::device().
*/
/*! \enum QInputDevice::DeviceType
This enum represents the type of device that generated a QPointerEvent.
\value Unknown
The device cannot be identified.
\value Mouse
A mouse.
\value TouchScreen
In this type of device, the touch surface and display are integrated.
This means the surface and display typically have the same size, such
that there is a direct relationship between the touch points' physical
positions and the coordinate reported by QTouchEvent::TouchPoint. As a
result, Qt allows the user to interact directly with multiple QWidgets,
QGraphicsItems, or Qt Quick Items at the same time.
\value TouchPad
In this type of device, the touch surface is separate from the display.
There is not a direct relationship between the physical touch location
and the on-screen coordinates. Instead, they are calculated relative to
the current mouse position, and the user must use the touch-pad to move
this reference point. Unlike touch-screens, Qt allows users to only
interact with a single QWidget or QGraphicsItem at a time.
\value Stylus
A pen-like device used on a graphics tablet such as a Wacom tablet,
or on a touchscreen that provides a separate stylus sensing capability.
\value Airbrush
A stylus with a thumbwheel to adjust
\l {QTabletEvent::tangentialPressure}{tangentialPressure}.
\value Puck
A device that is similar to a flat mouse with a transparent circle with
cross-hairs.
\value AllDevices
Any of the above (used as a default filter value).
*/
/*! \enum QPointingDevice::PointerType
This enum represents what is interacting with the pointing device.
There is some redundancy between this property and \l {QInputDevice::DeviceType}.
For example, if a touchscreen is used, then the \c DeviceType is
\c TouchScreen and \c PointerType is \c Finger (always). But on a graphics
tablet, it's often possible for both ends of the stylus to be used, and
programs need to distinguish them. Therefore the concept is extended so
that every QPointerEvent has a PointerType, and it can simplify some event
handling code to ignore the DeviceType and react differently depending on
the PointerType alone.
Valid values are:
\value Unknown
The pointer type is unknown.
\value Generic
A mouse or something acting like a mouse (the core pointer on X11).
\value Finger
The user's finger.
\value Pen
The drawing end of a stylus.
\value Eraser
The other end of the stylus (if it has a virtual eraser on the other end).
\value Cursor
A transparent circle with cross-hairs as found on a \l {DeviceType.Puck}{Puck} device.
\value AllPointerTypes
Any of the above (used as a default filter value).
*/
/*! \enum QPointingDevice::Capability
This enum is used with QPointingDevice::capabilities() to indicate what kind of information the
touch device or its driver can provide.
\value Position
Indicates that position information is available, meaning that the
pos() family of functions in the touch points return valid points.
\value Area
Indicates that touch area information is available, meaning that the
rect() family of functions in the touch points return valid rectangles.
\value Pressure
Indicates that pressure information is available, meaning that
QPointerEvent::EventPoint::pressure() returns a valid value.
\value Velocity
Indicates that velocity information is available, meaning that
QPointerEvent::EventPoint::velocity() returns a valid vector.
\value RawPositions
Indicates that the list returned by
QPointerEvent::EventPoint::rawScreenPositions() may contain one or more
positions for each touch point. This is relevant when the touch input
gets filtered or corrected on the driver level.
\value NormalizedPosition
Indicates that the normalized position is available, meaning that
QPointerEvent::EventPoint::normalizedPos() returns a valid value.
\value MouseEmulation
Indicates that the device synthesizes mouse events.
*/
/*!
Creates a new invalid pointing device instance.
*/
QPointingDevice::QPointingDevice()
: QInputDevice(*(new QPointingDevicePrivate(QLatin1String("unknown"), -1,
DeviceType::Unknown, PointerType::Unknown,
Capability::None, 0, 0)))
{
}
QPointingDevice::~QPointingDevice()
{
}
/*!
Creates a new pointing device instance with the given
\a deviceType, \a pointerType, \a capabilities, \a maxPoints,
\a buttonCount, \a name, \a id and \a seatId.
*/
QPointingDevice::QPointingDevice(const QString &name, qint64 id, QInputDevice::DeviceType deviceType,
QPointingDevice::PointerType pointerType, Capabilities capabilities, int maxPoints, int buttonCount,
const QString &seatName, QPointingDeviceUniqueId uniqueId, QObject *parent)
: QInputDevice(*(new QPointingDevicePrivate(name, id, deviceType, pointerType, capabilities, maxPoints, buttonCount, seatName, uniqueId)), parent)
{
}
/*!
\internal
*/
QPointingDevice::QPointingDevice(QPointingDevicePrivate &d, QObject *parent)
: QInputDevice(d, parent)
{
}
/*!
\internal
\deprecated Please use the constructor rather than setters.
Sets the device type \a devType and infers the pointer type.
*/
void QPointingDevice::setType(DeviceType devType)
{
Q_D(QPointingDevice);
d->deviceType = devType;
if (d->pointerType == PointerType::Unknown)
switch (devType) {
case DeviceType::Mouse:
d->pointerType = PointerType::Generic;
break;
case DeviceType::TouchScreen:
case DeviceType::TouchPad:
d->pointerType = PointerType::Finger;
break;
case DeviceType::Puck:
d->pointerType = PointerType::Cursor;
break;
case DeviceType::Stylus:
case DeviceType::Airbrush:
d->pointerType = PointerType::Pen;
break;
default:
break;
}
}
/*!
\internal
\deprecated Please use the constructor rather than setters.
*/
void QPointingDevice::setCapabilities(QInputDevice::Capabilities caps)
{
Q_D(QPointingDevice);
d->capabilities = caps;
}
/*!
\internal
\deprecated Please use the constructor rather than setters.
*/
void QPointingDevice::setMaximumTouchPoints(int c)
{
Q_D(QPointingDevice);
d->maximumTouchPoints = c;
}
/*!
Returns the pointer type.
*/
QPointingDevice::PointerType QPointingDevice::pointerType() const
{
Q_D(const QPointingDevice);
return d->pointerType;
}
/*!
Returns the maximum number of simultaneous touch points (fingers) that
can be detected.
*/
int QPointingDevice::maximumPoints() const
{
Q_D(const QPointingDevice);
return d->maximumTouchPoints;
}
/*!
Returns the maximum number of on-device buttons that can be detected.
*/
int QPointingDevice::buttonCount() const
{
Q_D(const QPointingDevice);
return d->buttonCount;
}
/*!
Returns a unique ID (of dubious utility) for the device.
You probably should rather be concerned with QPointerEventPoint::uniqueId().
*/
QPointingDeviceUniqueId QPointingDevice::uniqueId() const
{
Q_D(const QPointingDevice);
return d->uniqueId;
}
/*!
Returns the primary pointing device (the core pointer, traditionally
assumed to be a mouse) on the given seat \a seatName.
If multiple pointing devices are registered, this function prefers a
mouse, touchpad, or touchscreen (in that order) that matches the given
\a seatName and that does not have another device as its parent.
Usually only one master or core device does not have a parent device.
*/
const QPointingDevice *QPointingDevice::primaryPointingDevice(const QString& seatName)
{
const auto v = devices();
const QPointingDevice *mouse = nullptr;
const QPointingDevice *touchpad = nullptr;
const QPointingDevice *touchscreen = nullptr;
for (const QInputDevice *dev : v) {
if (dev->seatName() != seatName)
continue;
if (dev->type() == QInputDevice::DeviceType::Mouse) {
if (!mouse)
mouse = static_cast<const QPointingDevice *>(dev);
// the core pointer is likely a mouse, and its parent is not another input device
if (!mouse->parent() || !qobject_cast<const QInputDevice *>(mouse->parent()))
return mouse;
} else if (dev->type() == QInputDevice::DeviceType::TouchPad) {
if (!touchpad || !dev->parent() || dev->parent()->metaObject() != dev->metaObject())
touchpad = static_cast<const QPointingDevice *>(dev);
} else if (dev->type() == QInputDevice::DeviceType::TouchScreen) {
if (!touchscreen || !dev->parent() || dev->parent()->metaObject() != dev->metaObject())
touchscreen = static_cast<const QPointingDevice *>(dev);
}
}
if (!mouse && !touchpad && !touchscreen) {
qWarning() << "no pointing devices registered for seat" << seatName
<< "The platform plugin should have provided one via "
"QWindowSystemInterface::registerInputDevice(). Creating a default mouse for now.";
mouse = new QPointingDevice(QLatin1String("core pointer"), 1, DeviceType::Mouse,
PointerType::Generic, Capability::Position, 1, 3, seatName);
QInputDevicePrivate::registerDevice(mouse);
return mouse;
}
if (v.length() > 1)
qCWarning(lcQpaInputDevices) << "core pointer ambiguous for seat" << seatName;
if (mouse)
return mouse;
if (touchpad)
return touchpad;
return touchscreen;
}
/*!
Finds the device instance belonging to the drawing or eraser end of a particular stylus,
identified by its \a deviceType, \a pointerType and \a uniqueId. The given \a busId
may be used to update the stored USB ID, if it was not known before.
*/
const QPointingDevice *QPointingDevice::tabletDevice(QInputDevice::DeviceType deviceType,
QPointingDevice::PointerType pointerType,
QPointingDeviceUniqueId uniqueId, quint32 busId)
{
const QVector<const QInputDevice *> devices = QInputDevice::devices();
for (const QInputDevice *dev : devices) {
if (dev->type() < DeviceType::Puck || dev->type() > DeviceType::Airbrush)
continue;
const QPointingDevice *pdev = static_cast<const QPointingDevice *>(dev);
const auto devPriv = QPointingDevicePrivate::get(pdev);
bool uniqueIdDiscovered = (devPriv->uniqueId.numericId() == 0 && uniqueId.numericId() != 0);
if (devPriv->deviceType == deviceType && devPriv->pointerType == pointerType &&
(devPriv->uniqueId == uniqueId || uniqueIdDiscovered)) {
if (uniqueIdDiscovered) {
const_cast<QPointingDevicePrivate *>(devPriv)->uniqueId = uniqueId;
qCDebug(lcQpaInputDevices) << "discovered unique ID of tablet tool" << pdev;
}
if (devPriv->busId.isEmpty() && busId) {
const_cast<QPointingDevicePrivate *>(devPriv)->busId = QString::number(busId, 16);
qCDebug(lcQpaInputDevices) << "discovered USB ID" << devPriv->busId << "of" << pdev;
}
return pdev;
}
}
qWarning() << "failed to find registered tablet device" << deviceType << pointerType << Qt::hex << uniqueId.numericId()
<< "The platform plugin should have provided one via "
"QWindowSystemInterface::registerInputDevice(). Creating a default one for now.";
QPointingDevice *dev = new QPointingDevice(QLatin1String("fake tablet"), 2, deviceType, pointerType,
QInputDevice::Capability::Position | QInputDevice::Capability::Pressure,
1, 1, QString(), uniqueId);
QInputDevicePrivate::registerDevice(dev);
return dev;
}
bool QPointingDevice::operator==(const QPointingDevice &other) const
{
// Wacom tablets generate separate instances for each end of each stylus;
// QInputDevice::operator==() says they are all the same, but we use
// the stylus unique serial number and pointerType to distinguish them
return QInputDevice::operator==(other) &&
pointerType() == other.pointerType() &&
uniqueId() == other.uniqueId();
}
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QPointingDevice *device)
{
QDebugStateSaver saver(debug);
debug.nospace();
debug.noquote();
debug << "QPointingDevice(";
if (device) {
debug << '"' << device->name() << "\", type=";
QtDebugUtils::formatQEnum(debug, device->type());
debug << "id=" << Qt::hex << device->id() << Qt::dec << "seat=" << device->seatName();
debug << ", pointerType=";
QtDebugUtils::formatQEnum(debug, device->pointerType());
debug << ", capabilities=";
QtDebugUtils::formatQFlags(debug, device->capabilities());
debug << ", maximumTouchPoints=" << device->maximumPoints();
if (device->uniqueId().numericId())
debug << ", uniqueId=" << Qt::hex << device->uniqueId().numericId() << Qt::dec;
} else {
debug << '0';
}
debug << ')';
return debug;
}
#endif // !QT_NO_DEBUG_STREAM
QT_END_NAMESPACE

View File

@ -0,0 +1,149 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPOINTINGDEVICE_H
#define QPOINTINGDEVICE_H
#include <QtGui/qtguiglobal.h>
#include <QtCore/qobject.h>
#include <QtGui/qinputdevice.h>
QT_BEGIN_NAMESPACE
class QDebug;
class QPointingDevicePrivate;
class QScreen;
class Q_GUI_EXPORT QPointingDeviceUniqueId
{
Q_GADGET
Q_PROPERTY(qint64 numericId READ numericId CONSTANT)
public:
Q_ALWAYS_INLINE
Q_DECL_CONSTEXPR QPointingDeviceUniqueId() noexcept : m_numericId(-1) {}
// compiler-generated copy/move ctor/assignment operators are ok!
// compiler-generated dtor is ok!
static QPointingDeviceUniqueId fromNumericId(qint64 id);
Q_ALWAYS_INLINE Q_DECL_CONSTEXPR bool isValid() const noexcept { return m_numericId != -1; }
qint64 numericId() const noexcept;
private:
// TODO: for TUIO 2, or any other type of complex token ID, an internal
// array (or hash) can be added to hold additional properties.
// In this case, m_numericId will then turn into an index into that array (or hash).
qint64 m_numericId;
};
Q_DECLARE_TYPEINFO(QPointingDeviceUniqueId, Q_MOVABLE_TYPE);
Q_GUI_EXPORT bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) noexcept;
inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) noexcept
{ return !operator==(lhs, rhs); }
Q_GUI_EXPORT size_t qHash(QPointingDeviceUniqueId key, size_t seed = 0) noexcept;
class Q_GUI_EXPORT QPointingDevice : public QInputDevice
{
Q_OBJECT
Q_DECLARE_PRIVATE(QPointingDevice)
Q_PROPERTY(PointerType pointerType READ pointerType)
Q_PROPERTY(int maximumPoints READ maximumPoints)
Q_PROPERTY(int buttonCount READ buttonCount)
Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId)
public:
enum class PointerType : qint16 {
Unknown = 0,
Generic = 0x0001, // mouse or similar
Finger = 0x0002, // touchscreen or pad
Pen = 0x0004, // stylus on a tablet
Eraser = 0x0008, // eraser end of a stylus
Cursor = 0x0010, // digitizer with crosshairs
AllPointerTypes = 0x7FFF
};
Q_DECLARE_FLAGS(PointerTypes, PointerType)
Q_FLAG(PointerTypes)
QPointingDevice();
~QPointingDevice();
QPointingDevice(const QString &name, qint64 id, QInputDevice::DeviceType devType,
PointerType pType, Capabilities caps, int maxPoints, int buttonCount,
const QString &seatName = QString(),
QPointingDeviceUniqueId uniqueId = QPointingDeviceUniqueId(),
QObject *parent = nullptr);
#if QT_DEPRECATED_SINCE(6, 0)
QT_DEPRECATED_VERSION_X_6_0("Use the constructor")
void setType(DeviceType devType);
QT_DEPRECATED_VERSION_X_6_0("Use the constructor")
void setCapabilities(QInputDevice::Capabilities caps);
QT_DEPRECATED_VERSION_X_6_0("Use the constructor")
void setMaximumTouchPoints(int c);
#endif
PointerType pointerType() const;
int maximumPoints() const;
int buttonCount() const;
QPointingDeviceUniqueId uniqueId() const;
static const QPointingDevice *primaryPointingDevice(const QString& seatName = QString());
static const QPointingDevice *tabletDevice(QInputDevice::DeviceType deviceType,
QPointingDevice::PointerType pointerType,
QPointingDeviceUniqueId uniqueId, quint32 usbId = 0);
bool operator==(const QPointingDevice &other) const;
protected:
QPointingDevice(QPointingDevicePrivate &d, QObject *parent = nullptr);
Q_DISABLE_COPY_MOVE(QPointingDevice)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QPointingDevice::PointerTypes)
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug, const QPointingDevice *);
#endif
//typedef QPointingDevice QTouchDevice; // Qt 5 source compatibility if we need it? or could be "using"
QT_END_NAMESPACE
#endif // QPOINTINGDEVICE_H

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@ -37,8 +37,8 @@
**
****************************************************************************/
#ifndef QTOUCHDEVICE_P_H
#define QTOUCHDEVICE_P_H
#ifndef QPOINTINGDEVICE_P_H
#define QPOINTINGDEVICE_P_H
//
// W A R N I N G
@ -52,36 +52,45 @@
//
#include <QtGui/private/qtguiglobal_p.h>
#include <QtGui/qtouchdevice.h>
#include <QtGui/private/qinputdevice_p.h>
#include <QtGui/qpointingdevice.h>
QT_BEGIN_NAMESPACE
class QTouchDevicePrivate
class Q_GUI_EXPORT QPointingDevicePrivate : public QInputDevicePrivate
{
public:
QTouchDevicePrivate()
: type(QTouchDevice::TouchScreen),
caps(QTouchDevice::Position),
maxTouchPoints(1)
QPointingDevicePrivate(const QString &name, qint64 id, QInputDevice::DeviceType type,
QPointingDevice::PointerType pType, QPointingDevice::Capabilities caps,
int maxPoints, int buttonCount,
const QString &seatName = QString(),
QPointingDeviceUniqueId uniqueId = QPointingDeviceUniqueId())
: QInputDevicePrivate(name, id, type, caps, seatName),
uniqueId(uniqueId),
maximumTouchPoints(qint8(maxPoints)), buttonCount(qint8(buttonCount)),
pointerType(pType)
{
static quint8 nextId = 2; // device 0 is not used, device 1 is for mouse device
id = nextId++;
}
QTouchDevice::DeviceType type;
QTouchDevice::Capabilities caps;
QString name;
int maxTouchPoints;
quint8 id;
void * extra = nullptr; // QPA plugins can store platform-specific stuff here
QPointingDeviceUniqueId uniqueId;
quint32 toolId = 0; // only for Wacom tablets
qint8 maximumTouchPoints = 0;
qint8 buttonCount = 0;
QPointingDevice::PointerType pointerType = QPointingDevice::PointerType::Unknown;
bool toolProximity = false; // only for Wacom tablets
static void registerDevice(const QTouchDevice *dev);
static void unregisterDevice(const QTouchDevice *dev);
static bool isRegistered(const QTouchDevice *dev);
static const QTouchDevice *deviceById(quint8 id);
static QTouchDevicePrivate *get(QTouchDevice *q) { return q->d; }
inline static QPointingDevicePrivate *get(QPointingDevice *q)
{
return static_cast<QPointingDevicePrivate *>(QObjectPrivate::get(q));
}
inline static const QPointingDevicePrivate *get(const QPointingDevice *q)
{
return static_cast<const QPointingDevicePrivate *>(QObjectPrivate::get(q));
}
};
QT_END_NAMESPACE
#endif // QTOUCHDEVICE_P_H
#endif // QPOINTINGDEVICE_P_H

View File

@ -1,292 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qtouchdevice.h"
#include "qtouchdevice_p.h"
#include <QList>
#include <QMutex>
#include <QCoreApplication>
#include <private/qdebug_p.h>
#include <private/qlocking_p.h>
QT_BEGIN_NAMESPACE
/*!
\class QTouchDevice
\brief The QTouchDevice class describes the device from which touch events originate.
\since 5.0
\ingroup touch
\inmodule QtGui
Each QTouchEvent contains a QTouchDevice pointer to allow accessing
device-specific properties like type and capabilities. It is the
responsibility of the platform or generic plug-ins to register the
available touch devices via QWindowSystemInterface before generating any
touch events. Applications do not need to instantiate this class, they
should just access the global instances pointed to by QTouchEvent::device().
*/
/*! \enum QTouchDevice::DeviceType
This enum represents the type of device that generated a QTouchEvent.
\value TouchScreen In this type of device, the touch surface and display are integrated. This
means the surface and display typically have the same size, such that there
is a direct relationship between the touch points' physical positions and the
coordinate reported by QTouchEvent::TouchPoint. As a result, Qt allows the
user to interact directly with multiple QWidgets and QGraphicsItems at the
same time.
\value TouchPad In this type of device, the touch surface is separate from the display. There
is not a direct relationship between the physical touch location and the
on-screen coordinates. Instead, they are calculated relative to the current
mouse position, and the user must use the touch-pad to move this reference
point. Unlike touch-screens, Qt allows users to only interact with a single
QWidget or QGraphicsItem at a time.
*/
/*! \enum QTouchDevice::CapabilityFlag
This enum is used with QTouchDevice::capabilities() to indicate what kind of information the
touch device or its driver can provide.
\value Position Indicates that position information is available, meaning
that the pos() family of functions in the touch points return valid points.
\value Area Indicates that touch area information is available, meaning that the rect() family
of functions in the touch points return valid rectangles.
\value Pressure Indicates that pressure information is available, meaning that pressure()
returns a valid value.
\value Velocity Indicates that velocity information is available, meaning that velocity()
returns a valid vector.
\value RawPositions Indicates that the list returned by QTouchEvent::TouchPoint::rawScreenPositions()
may contain one or more positions for each touch point. This is relevant when
the touch input gets filtered or corrected on driver level.
\value NormalizedPosition Indicates that the normalized position is available, meaning that normalizedPos()
returns a valid value.
\value MouseEmulation Indicates that the device synthesizes mouse events.
This enum value has been introduced in Qt 5.5.
*/
/*!
Creates a new touch device instance.
By default the name is empty, the only capability is Position and type is TouchScreen.
*/
QTouchDevice::QTouchDevice()
: d(new QTouchDevicePrivate)
{
}
/*!
Destroys a touch device instance.
*/
QTouchDevice::~QTouchDevice()
{
delete d;
}
/*!
Returns the touch device type.
*/
QTouchDevice::DeviceType QTouchDevice::type() const
{
return d->type;
}
/*!
Returns the touch device capabilities.
*/
QTouchDevice::Capabilities QTouchDevice::capabilities() const
{
return d->caps;
}
/*!
Returns the maximum number of simultaneous touch points (fingers) that
can be detected.
\since 5.2
*/
int QTouchDevice::maximumTouchPoints() const
{
return d->maxTouchPoints;
}
/*!
Returns the touch device name.
This string may often be empty. It is however useful for systems that have
more than one touch input device because there it can be used to
differentiate between the devices (i.e. to tell from which device a
QTouchEvent originates from).
*/
QString QTouchDevice::name() const
{
return d->name;
}
/*!
Sets the device type \a devType.
*/
void QTouchDevice::setType(DeviceType devType)
{
d->type = devType;
}
/*!
Sets the capabilities \a caps supported by the device and its driver.
*/
void QTouchDevice::setCapabilities(Capabilities caps)
{
d->caps = caps;
}
/*!
Sets the maximum number of simultaneous touchpoints \a max
supported by the device and its driver.
*/
void QTouchDevice::setMaximumTouchPoints(int max)
{
d->maxTouchPoints = max;
}
/*!
Sets the \a name (a unique identifier) for the device. In most systems it is
enough to leave this unset and keep the default empty name. This identifier
becomes important when having multiple touch devices and a need to
differentiate between them.
*/
void QTouchDevice::setName(const QString &name)
{
d->name = name;
}
static QBasicMutex devicesMutex;
struct TouchDevices {
TouchDevices();
QList<const QTouchDevice *> list;
};
Q_GLOBAL_STATIC(TouchDevices, deviceList)
TouchDevices::TouchDevices()
{
qAddPostRoutine([]{
const auto locker = qt_scoped_lock(devicesMutex);
qDeleteAll(qExchange(deviceList->list, {}));
});
}
/*!
Returns a list of all registered devices.
\note The returned list cannot be used to add new devices. To add a simulated
touch screen for an autotest, QTest::createTouchDevice() can be used.
To add real touch screens to QPA plugins, the private
\c QWindowSystemInterface::registerTouchDevice() function can be used.
*/
QList<const QTouchDevice *> QTouchDevice::devices()
{
const auto locker = qt_scoped_lock(devicesMutex);
return deviceList->list;
}
/*!
\internal
*/
bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
{
const auto locker = qt_scoped_lock(devicesMutex);
return deviceList->list.contains(dev);
}
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
{
const auto locker = qt_scoped_lock(devicesMutex);
for (const QTouchDevice *dev : qAsConst(deviceList->list))
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
return dev;
return nullptr;
}
/*!
\internal
*/
void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
{
const auto locker = qt_scoped_lock(devicesMutex);
deviceList->list.append(dev);
}
/*!
\internal
*/
void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
{
const auto locker = qt_scoped_lock(devicesMutex);
deviceList->list.removeOne(dev);
}
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QTouchDevice *device)
{
QDebugStateSaver saver(debug);
debug.nospace();
debug.noquote();
debug << "QTouchDevice(";
if (device) {
debug << '"' << device->name() << "\", type=";
QtDebugUtils::formatQEnum(debug, device->type());
debug << ", capabilities=";
QtDebugUtils::formatQFlags(debug, device->capabilities());
debug << ", maximumTouchPoints=" << device->maximumTouchPoints();
} else {
debug << '0';
}
debug << ')';
return debug;
}
#endif // !QT_NO_DEBUG_STREAM
QT_END_NAMESPACE

View File

@ -41,7 +41,7 @@
#include "qwindowsysteminterface_p.h"
#include "private/qguiapplication_p.h"
#include "private/qevent_p.h"
#include "private/qtouchdevice_p.h"
#include "private/qpointingdevice_p.h"
#include <QAbstractEventDispatcher>
#include <qpa/qplatformintegration.h>
#include <qdebug.h>
@ -56,6 +56,7 @@
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaInputDevices, "qt.qpa.input.devices")
QElapsedTimer QWindowSystemInterfacePrivate::eventTime;
bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false;
@ -575,60 +576,31 @@ bool QWindowSystemInterface::handleWheelEvent(QWindow *window, ulong timestamp,
return acceptVert || acceptHorz;
}
void QWindowSystemInterface::registerTouchDevice(const QTouchDevice *device)
{
QTouchDevicePrivate::registerDevice(device);
}
void QWindowSystemInterface::unregisterTouchDevice(const QTouchDevice *device)
{
QTouchDevicePrivate::unregisterDevice(device);
}
bool QWindowSystemInterface::isTouchDeviceRegistered(const QTouchDevice *device)
{
return QTouchDevicePrivate::isRegistered(device);
}
static int g_nextPointId = 1;
// map from device-independent point id (arbitrary) to "Qt point" ids
static QBasicMutex pointIdMapMutex;
typedef QMap<quint64, int> PointIdMap;
Q_GLOBAL_STATIC(PointIdMap, g_pointIdMap)
/*!
\internal
This function maps potentially arbitrary point ids \a pointId in the 32 bit
value space to start from 1 and increase incrementally for each touch point
held down. If all touch points are released it will reset the id back to 1
for the following touch point.
Register a new input \a device.
We can then assume that the touch points ids will never become too large,
and it will then put the device identifier \a deviceId in the upper 8 bits.
This leaves us with max 255 devices, and 16.7M taps without full release
before we run out of value space.
It is expected that every platform plugin will discover available input
devices at startup, and whenever a new device is plugged in, if possible.
If that's not possible, then it at least must call this function before
sending an event whose QInputEvent::source() is this device.
When a device is unplugged, the platform plugin should destroy the
corresponding QInputDevice instance. There is no unregisterInputDevice()
function, because it's enough for the destructor to call
QInputDevicePrivate::unregisterDevice(); while other parts of Qt can
connect to the QObject::destroyed() signal to be notified when a device is
unplugged or otherwise destroyed.
*/
static int acquireCombinedPointId(quint8 deviceId, int pointId)
void QWindowSystemInterface::registerInputDevice(const QInputDevice *device)
{
const auto locker = qt_scoped_lock(pointIdMapMutex);
quint64 combinedId64 = (quint64(deviceId) << 32) + pointId;
auto it = g_pointIdMap->constFind(combinedId64);
int uid;
if (it == g_pointIdMap->constEnd()) {
uid = g_nextPointId++;
g_pointIdMap->insert(combinedId64, uid);
} else {
uid = *it;
}
return (deviceId << 24) + uid;
qCDebug(lcQpaInputDevices) << "register" << device;
QInputDevicePrivate::registerDevice(device);
}
QList<QTouchEvent::TouchPoint>
QWindowSystemInterfacePrivate::fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
const QWindow *window, quint8 deviceId,
QEvent::Type *type)
const QWindow *window, QEvent::Type *type)
{
QList<QTouchEvent::TouchPoint> touchPoints;
Qt::TouchPointStates states;
@ -638,7 +610,7 @@ QList<QTouchEvent::TouchPoint>
QList<QWindowSystemInterface::TouchPoint>::const_iterator point = points.constBegin();
QList<QWindowSystemInterface::TouchPoint>::const_iterator end = points.constEnd();
while (point != end) {
p.setId(acquireCombinedPointId(deviceId, point->id));
p.setId(point->id);
if (point->uniqueId >= 0)
p.setUniqueId(point->uniqueId);
p.setPressure(point->pressure);
@ -649,7 +621,7 @@ QList<QTouchEvent::TouchPoint>
p.setScreenPos(QHighDpi::fromNativePixels(point->area.center(), window));
p.setEllipseDiameters(QHighDpi::fromNativePixels(point->area.size(), window));
// The local pos and rect are not set, they will be calculated
// The local pos is not set: it will be calculated
// when the event gets processed by QGuiApplication.
p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition, window));
@ -670,33 +642,9 @@ QList<QTouchEvent::TouchPoint>
*type = QEvent::TouchEnd;
}
if (states == Qt::TouchPointReleased) {
const auto locker = qt_scoped_lock(pointIdMapMutex);
// All points on deviceId have been released.
// Remove all points associated with that device from g_pointIdMap.
// (On other devices, some touchpoints might still be pressed.
// But this function is only called with points from one device at a time.)
for (auto it = g_pointIdMap->begin(); it != g_pointIdMap->end();) {
if (it.key() >> 32 == quint64(deviceId))
it = g_pointIdMap->erase(it);
else
++it;
}
if (g_pointIdMap->isEmpty())
g_nextPointId = 1;
}
return touchPoints;
}
void QWindowSystemInterfacePrivate::clearPointIdMap()
{
const auto locker = qt_scoped_lock(pointIdMapMutex);
g_pointIdMap->clear();
g_nextPointId = 1;
}
QList<QWindowSystemInterface::TouchPoint>
QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
const QWindow *window)
@ -721,39 +669,38 @@ QList<QWindowSystemInterface::TouchPoint>
return newList;
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, QTouchDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, const QPointingDevice *device,
const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
return handleTouchEvent<Delivery>(window, time, device, points, mods);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, ulong timestamp, QTouchDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, ulong timestamp, const QPointingDevice *device,
const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
{
if (!points.size()) // Touch events must have at least one point
return false;
if (!QTouchDevicePrivate::isRegistered(device)) // Disallow passing bogus, non-registered devices.
if (!QPointingDevicePrivate::isRegistered(device)) // Disallow passing bogus, non-registered devices.
return false;
QEvent::Type type;
QList<QTouchEvent::TouchPoint> touchPoints =
QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, QTouchDevicePrivate::get(device)->id, &type);
QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, &type);
QWindowSystemInterfacePrivate::TouchEvent *e =
new QWindowSystemInterfacePrivate::TouchEvent(window, timestamp, type, device, touchPoints, mods);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, QTouchDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, const QPointingDevice *device,
Qt::KeyboardModifiers mods)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
return handleTouchCancelEvent<Delivery>(window, time, device, mods);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, ulong timestamp, QTouchDevice *device,
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, ulong timestamp, const QPointingDevice *device,
Qt::KeyboardModifiers mods)
{
QWindowSystemInterfacePrivate::TouchEvent *e =
@ -967,7 +914,7 @@ void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int poi
}
#ifndef QT_NO_GESTURES
bool QWindowSystemInterface::handleGestureEvent(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
bool QWindowSystemInterface::handleGestureEvent(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
QPointF &local, QPointF &global)
{
QWindowSystemInterfacePrivate::GestureEvent *e =
@ -975,7 +922,7 @@ bool QWindowSystemInterface::handleGestureEvent(QWindow *window, QTouchDevice *d
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
bool QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
bool QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
qreal value, QPointF &local, QPointF &global)
{
QWindowSystemInterfacePrivate::GestureEvent *e =
@ -984,7 +931,7 @@ bool QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, QT
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
bool QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
bool QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
ulong sequenceId, quint64 value, QPointF &local, QPointF &global)
{
QWindowSystemInterfacePrivate::GestureEvent *e =
@ -1217,16 +1164,19 @@ Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int
namespace QTest
{
Q_GUI_EXPORT QTouchDevice * createTouchDevice(QTouchDevice::DeviceType devType = QTouchDevice::TouchScreen)
Q_GUI_EXPORT QPointingDevice * createTouchDevice(QInputDevice::DeviceType devType = QInputDevice::DeviceType::TouchScreen,
QInputDevice::Capabilities caps = QInputDevice::Capability::Position)
{
QTouchDevice *ret = new QTouchDevice();
ret->setType(devType);
QWindowSystemInterface::registerTouchDevice(ret);
static qint64 nextId = 0x100000000;
QPointingDevice *ret = new QPointingDevice(QLatin1String("test touch device"), nextId++,
devType, QPointingDevice::PointerType::Finger,
caps, 8, 0);
QWindowSystemInterface::registerInputDevice(ret);
return ret;
}
}
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *window, QTouchDevice *device,
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *window, const QPointingDevice *device,
const QList<QTouchEvent::TouchPoint> &points,
Qt::KeyboardModifiers mods = Qt::NoModifier)
{

View File

@ -64,7 +64,7 @@
QT_BEGIN_NAMESPACE
class QMimeData;
class QTouchDevice;
class QPointingDevice;
class QPlatformDragQtResponse;
class QPlatformDropQtResponse;
@ -148,20 +148,18 @@ public:
QVector<QPointF> rawPositions; // in screen coordinates
};
static void registerTouchDevice(const QTouchDevice *device);
static void unregisterTouchDevice(const QTouchDevice *device);
static bool isTouchDeviceRegistered(const QTouchDevice *device);
static void registerInputDevice(const QInputDevice *device);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static bool handleTouchEvent(QWindow *window, QTouchDevice *device,
static bool handleTouchEvent(QWindow *window, const QPointingDevice *device,
const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static bool handleTouchEvent(QWindow *window, ulong timestamp, QTouchDevice *device,
static bool handleTouchEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static bool handleTouchCancelEvent(QWindow *window, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
static bool handleTouchCancelEvent(QWindow *window, const QPointingDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static bool handleTouchCancelEvent(QWindow *window, ulong timestamp, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
static bool handleTouchCancelEvent(QWindow *window, ulong timestamp, const QPointingDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
// rect is relative to parent
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
@ -241,11 +239,11 @@ public:
static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid);
#ifndef QT_NO_GESTURES
static bool handleGestureEvent(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
static bool handleGestureEvent(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
QPointF &local, QPointF &global);
static bool handleGestureEventWithRealValue(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
static bool handleGestureEventWithRealValue(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
qreal value, QPointF &local, QPointF &global);
static bool handleGestureEventWithSequenceIdAndValue(QWindow *window, QTouchDevice *device, ulong timestamp,Qt::NativeGestureType type,
static bool handleGestureEventWithSequenceIdAndValue(QWindow *window, const QPointingDevice *device, ulong timestamp,Qt::NativeGestureType type,
ulong sequenceId, quint64 value, QPointF &local, QPointF &global);
#endif // QT_NO_GESTURES

View File

@ -297,10 +297,10 @@ public:
class TouchEvent : public InputEvent {
public:
TouchEvent(QWindow *w, ulong time, QEvent::Type t, QTouchDevice *dev,
TouchEvent(QWindow *w, ulong time, QEvent::Type t, const QPointingDevice *dev,
const QList<QTouchEvent::TouchPoint> &p, Qt::KeyboardModifiers mods)
:InputEvent(w, time, Touch, mods), device(dev), points(p), touchType(t) { }
QTouchDevice *device;
const QPointingDevice *device;
QList<QTouchEvent::TouchPoint> points;
QEvent::Type touchType;
};
@ -440,7 +440,7 @@ public:
#ifndef QT_NO_GESTURES
class GestureEvent : public InputEvent {
public:
GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, QTouchDevice *dev, QPointF pos, QPointF globalPos)
GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, const QPointingDevice *dev, QPointF pos, QPointF globalPos)
: InputEvent(window, time, Gesture, Qt::NoModifier), type(type), pos(pos), globalPos(globalPos),
realValue(0), sequenceId(0), intValue(0), device(dev) { }
Qt::NativeGestureType type;
@ -451,7 +451,7 @@ public:
// Windows
ulong sequenceId;
quint64 intValue;
QTouchDevice *device;
const QPointingDevice *device;
};
#endif
@ -533,11 +533,10 @@ public:
static QList<QTouchEvent::TouchPoint>
fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
const QWindow *window, quint8 deviceId, QEvent::Type *type = nullptr);
const QWindow *window, QEvent::Type *type = nullptr);
static QList<QWindowSystemInterface::TouchPoint>
toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
const QWindow *window);
static void clearPointIdMap();
static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler);
static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler);

View File

@ -42,6 +42,7 @@
#include <QStringList>
#include <QSocketNotifier>
#include <QGuiApplication>
#include <QPointingDevice>
#include <QLoggingCategory>
#include <QtCore/private/qcore_unix_p.h>
#include <qpa/qwindowsysteminterface.h>
@ -114,10 +115,10 @@ void QEvdevTabletData::processInputEvent(input_event *ev)
state.down = ev->value != 0;
break;
case BTN_TOOL_PEN:
state.tool = ev->value ? QTabletEvent::Pen : 0;
state.tool = ev->value ? int(QPointingDevice::PointerType::Pen) : 0;
break;
case BTN_TOOL_RUBBER:
state.tool = ev->value ? QTabletEvent::Eraser : 0;
state.tool = ev->value ? int(QPointingDevice::PointerType::Eraser) : 0;
break;
default:
break;
@ -131,7 +132,7 @@ void QEvdevTabletData::processInputEvent(input_event *ev)
void QEvdevTabletData::report()
{
if (!state.lastReportTool && state.tool)
QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId());
QWindowSystemInterface::handleTabletEnterProximityEvent(int(QInputDevice::DeviceType::Stylus), state.tool, q->deviceId());
qreal nx = (state.x - minValues.x) / qreal(maxValues.x - minValues.x);
qreal ny = (state.y - minValues.y) / qreal(maxValues.y - minValues.y);
@ -150,14 +151,14 @@ void QEvdevTabletData::report()
if (state.down || state.lastReportDown) {
QWindowSystemInterface::handleTabletEvent(0, QPointF(), globalPos,
QTabletEvent::Stylus, pointer,
int(QInputDevice::DeviceType::Stylus), pointer,
state.down ? Qt::LeftButton : Qt::NoButton,
pressure, 0, 0, 0, 0, 0, q->deviceId(),
qGuiApp->keyboardModifiers());
}
if (state.lastReportTool && !state.tool)
QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId());
QWindowSystemInterface::handleTabletLeaveProximityEvent(int(QInputDevice::DeviceType::Stylus), state.tool, q->deviceId());
state.lastReportDown = state.down;
state.lastReportTool = state.tool;

View File

@ -44,9 +44,9 @@
#include <QHash>
#include <QSocketNotifier>
#include <QGuiApplication>
#include <QTouchDevice>
#include <QLoggingCategory>
#include <QtCore/private/qcore_unix_p.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/private/qguiapplication_p.h>
@ -358,7 +358,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const
qUtf16Printable(d->deviceNode), qUtf16Printable(d->m_screenName));
}
registerTouchDevice();
registerPointingDevice();
}
QEvdevTouchScreenHandler::~QEvdevTouchScreenHandler()
@ -375,7 +375,7 @@ QEvdevTouchScreenHandler::~QEvdevTouchScreenHandler()
delete d;
unregisterTouchDevice();
unregisterPointingDevice();
}
bool QEvdevTouchScreenHandler::isFiltered() const
@ -383,7 +383,7 @@ bool QEvdevTouchScreenHandler::isFiltered() const
return d && d->m_filtered;
}
QTouchDevice *QEvdevTouchScreenHandler::touchDevice() const
QPointingDevice *QEvdevTouchScreenHandler::touchDevice() const
{
return m_device;
}
@ -444,40 +444,33 @@ err:
QT_CLOSE(m_fd);
m_fd = -1;
unregisterTouchDevice();
unregisterPointingDevice();
}
return;
}
}
}
void QEvdevTouchScreenHandler::registerTouchDevice()
void QEvdevTouchScreenHandler::registerPointingDevice()
{
if (m_device)
return;
m_device = new QTouchDevice;
m_device->setName(d->hw_name);
m_device->setType(QTouchDevice::TouchScreen);
m_device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area);
static int id = 1;
QPointingDevice::Capabilities caps = QPointingDevice::Capability::Position | QPointingDevice::Capability::Area;
if (d->hw_pressure_max > d->hw_pressure_min)
m_device->setCapabilities(m_device->capabilities() | QTouchDevice::Pressure);
caps.setFlag(QPointingDevice::Capability::Pressure);
QWindowSystemInterface::registerTouchDevice(m_device);
// TODO get evdev ID instead of an incremeting number; set USB ID too
m_device = new QPointingDevice(d->hw_name, id++,
QInputDevice::DeviceType::TouchScreen, QPointingDevice::PointerType::Finger,
caps, 16, 0);
QWindowSystemInterface::registerInputDevice(m_device);
}
void QEvdevTouchScreenHandler::unregisterTouchDevice()
void QEvdevTouchScreenHandler::unregisterPointingDevice()
{
if (!m_device)
return;
// At app exit the cleanup may have already been done, avoid
// double delete by checking the list first.
if (QWindowSystemInterface::isTouchDeviceRegistered(m_device)) {
QWindowSystemInterface::unregisterTouchDevice(m_device);
delete m_device;
}
delete m_device;
m_device = nullptr;
}
@ -833,7 +826,7 @@ void QEvdevTouchScreenHandlerThread::run()
m_handler = nullptr;
}
bool QEvdevTouchScreenHandlerThread::isTouchDeviceRegistered() const
bool QEvdevTouchScreenHandlerThread::isPointingDeviceRegistered() const
{
return m_touchDeviceRegistered;
}

View File

@ -52,6 +52,7 @@
// We mean it.
//
//#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qtguiglobal_p.h>
#include <QObject>
#include <QString>
@ -69,6 +70,7 @@ QT_BEGIN_NAMESPACE
class QSocketNotifier;
class QEvdevTouchScreenData;
class QPointingDevice;
class QEvdevTouchScreenHandler : public QObject
{
@ -78,7 +80,7 @@ public:
explicit QEvdevTouchScreenHandler(const QString &device, const QString &spec = QString(), QObject *parent = nullptr);
~QEvdevTouchScreenHandler();
QTouchDevice *touchDevice() const;
QPointingDevice *touchDevice() const;
bool isFiltered() const;
@ -91,13 +93,13 @@ private:
friend class QEvdevTouchScreenData;
friend class QEvdevTouchScreenHandlerThread;
void registerTouchDevice();
void unregisterTouchDevice();
void registerPointingDevice();
void unregisterPointingDevice();
QSocketNotifier *m_notify;
int m_fd;
QEvdevTouchScreenData *d;
QTouchDevice *m_device;
QPointingDevice *m_device;
#if QT_CONFIG(mtdev)
mtdev *m_mtdev;
#endif
@ -111,7 +113,7 @@ public:
~QEvdevTouchScreenHandlerThread();
void run() override;
bool isTouchDeviceRegistered() const;
bool isPointingDeviceRegistered() const;
bool eventFilter(QObject *object, QEvent *event) override;

View File

@ -117,7 +117,7 @@ void QEvdevTouchManager::updateInputDeviceCount()
{
int registeredTouchDevices = 0;
for (const auto &device : m_activeDevices) {
if (device.handler->isTouchDeviceRegistered())
if (device.handler->isPointingDeviceRegistered())
++registeredTouchDevices;
}

View File

@ -41,9 +41,11 @@
#include "qtouchoutputmapping_p.h"
#include <libinput.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QPointingDevice>
#include <QtGui/QScreen>
#include <QtGui/QTouchDevice>
#include <QtGui/QPointingDevice>
#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/private/qpointingdevice_p.h>
QT_BEGIN_NAMESPACE
@ -107,18 +109,18 @@ void QLibInputTouch::registerDevice(libinput_device *dev)
qPrintable(devNode), qPrintable(m_devState[dev].m_screenName));
}
QTouchDevice *&td = m_devState[dev].m_touchDevice;
td = new QTouchDevice;
td->setName(devName);
td->setType(QTouchDevice::TouchScreen);
td->setCapabilities(QTouchDevice::Position | QTouchDevice::Area);
QWindowSystemInterface::registerTouchDevice(td);
QPointingDevice *&td = m_devState[dev].m_touchDevice;
td = new QPointingDevice(devName, udev_device_get_devnum(udev_device),
QInputDevice::DeviceType::TouchScreen, QPointingDevice::PointerType::Finger,
QPointingDevice::Capability::Position | QPointingDevice::Capability::Area, 16, 0);
QPointingDevicePrivate::get(td)->busId = QString::fromLocal8Bit(udev_device_get_syspath(udev_device)); // TODO is that the best to choose?
QWindowSystemInterface::registerInputDevice(td);
}
void QLibInputTouch::unregisterDevice(libinput_device *dev)
{
Q_UNUSED(dev);
// There is no way to remove a QTouchDevice.
// There is no way to remove a QPointingDevice.
}
void QLibInputTouch::processTouchDown(libinput_event_touch *e)

View File

@ -78,7 +78,7 @@ private:
DeviceState() : m_touchDevice(nullptr), m_screenName() { }
QWindowSystemInterface::TouchPoint *point(int32_t slot);
QList<QWindowSystemInterface::TouchPoint> m_points;
QTouchDevice *m_touchDevice;
QPointingDevice *m_touchDevice;
QString m_screenName;
};

View File

@ -47,7 +47,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <QTouchDevice>
#include <QPointingDevice>
#include <QWindow>
#include <QGuiApplication>
@ -68,7 +68,6 @@ Q_LOGGING_CATEGORY(lcTuioSet, "qt.qpa.tuio.set")
static bool forceDelivery = qEnvironmentVariableIsSet("QT_TUIOTOUCH_DELIVER_WITHOUT_FOCUS");
QTuioHandler::QTuioHandler(const QString &specification)
: m_device(new QTouchDevice) // not leaked, QTouchDevice cleans up registered devices itself
{
QStringList args = specification.split(':');
int portNumber = 3333;
@ -111,13 +110,17 @@ QTuioHandler::QTuioHandler(const QString &specification)
if (inverty)
m_transform *= QTransform::fromTranslate(0.5, 0.5).scale(1.0, -1.0).translate(-0.5, -0.5);
m_device->setName("TUIO"); // TODO: multiple based on SOURCE?
m_device->setType(QTouchDevice::TouchScreen);
m_device->setCapabilities(QTouchDevice::Position |
QTouchDevice::Area |
QTouchDevice::Velocity |
QTouchDevice::NormalizedPosition);
QWindowSystemInterface::registerTouchDevice(m_device);
// not leaked, QPointingDevice cleans up registered devices itself
// TODO register each device based on SOURCE, not just an all-purpose generic touchscreen
// TODO define seats when multiple connections occur
m_device = new QPointingDevice(QLatin1String("TUIO"), 1, QInputDevice::DeviceType::TouchScreen,
QPointingDevice::PointerType::Finger,
QInputDevice::Capability::Position |
QInputDevice::Capability::Area |
QInputDevice::Capability::Velocity |
QInputDevice::Capability::NormalizedPosition,
16, 0);
QWindowSystemInterface::registerInputDevice(m_device);
if (!m_socket.bind(QHostAddress::Any, portNumber)) {
qCWarning(lcTuioHandler) << "Failed to bind TUIO socket: " << m_socket.errorString();

View File

@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
class QTouchDevice;
class QPointingDevice;
class QOscMessage;
class QTuioCursor;
class QTuioToken;
@ -80,7 +80,7 @@ private:
QWindowSystemInterface::TouchPoint cursorToTouchPoint(const QTuioCursor &tc, QWindow *win);
QWindowSystemInterface::TouchPoint tokenToTouchPoint(const QTuioToken &tc, QWindow *win);
QTouchDevice *m_device;
QPointingDevice *m_device = nullptr;
QUdpSocket m_socket;
QMap<int, QTuioCursor> m_activeCursors;
QVector<QTuioCursor> m_deadCursors;

View File

@ -45,7 +45,6 @@
#include "qandroidplatformintegration.h"
#include <qpa/qwindowsysteminterface.h>
#include <QTouchDevice>
#include <QTouchEvent>
#include <QPointer>
@ -276,15 +275,15 @@ namespace QtAndroidInput
if (!platformIntegration)
return;
QTouchDevice *touchDevice = platformIntegration->touchDevice();
QPointingDevice *touchDevice = platformIntegration->touchDevice();
if (touchDevice == 0) {
touchDevice = new QTouchDevice;
touchDevice->setType(QTouchDevice::TouchScreen);
touchDevice->setCapabilities(QTouchDevice::Position
| QTouchDevice::Area
| QTouchDevice::Pressure
| QTouchDevice::NormalizedPosition);
QWindowSystemInterface::registerTouchDevice(touchDevice);
touchDevice = new QPointingDevice; // TODO fill out the constructor args
touchDevice->setType(QInputDevice::DeviceType::TouchScreen);
touchDevice->setCapabilities(QPointingDevice::Capability::Position
| QPointingDevice::Capability::Area
| QPointingDevice::Capability::Pressure
| QPointingDevice::Capability::NormalizedPosition);
QWindowSystemInterface::registerInputDevice(touchDevice);
platformIntegration->setTouchDevice(touchDevice);
}
@ -344,7 +343,7 @@ namespace QtAndroidInput
#endif
QWindowSystemInterface::handleTabletEvent(tlw, ulong(time),
localPos, globalPosF, QTabletEvent::Stylus, pointerType,
localPos, globalPosF, int(QInputDevice::DeviceType::Stylus), pointerType,
buttons, pressure, 0, 0, 0., 0., 0, deviceId, Qt::NoModifier);
#endif // QT_CONFIG(tabletevent)
}

View File

@ -48,7 +48,6 @@
#endif
#include <QOffscreenSurface>
#include <QThread>
#include <QTouchDevice>
#include <QtEglSupport/private/qeglpbuffer_p.h>
#include <qpa/qwindowsysteminterface.h>
@ -208,12 +207,12 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
if (touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_FINGER")
|| touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_STYLUS"))
{
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
m_touchDevice->setCapabilities(QTouchDevice::Position
| QTouchDevice::Area
| QTouchDevice::Pressure
| QTouchDevice::NormalizedPosition);
m_touchDevice = new QPointingDevice;
m_touchDevice->setType(QInputDevice::DeviceType::TouchScreen);
m_touchDevice->setCapabilities(QPointingDevice::Capability::Position
| QPointingDevice::Capability::Area
| QPointingDevice::Capability::Pressure
| QPointingDevice::Capability::NormalizedPosition);
QJNIObjectPrivate pm = javaActivity.callObjectMethod("getPackageManager", "()Landroid/content/pm/PackageManager;");
Q_ASSERT(pm.isValid());
@ -227,7 +226,7 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH", "Ljava/lang/String;").object())) {
m_touchDevice->setMaximumTouchPoints(2);
}
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
QWindowSystemInterface::registerInputDevice(m_touchDevice);
}
auto contentResolver = javaActivity.callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;");

View File

@ -128,8 +128,8 @@ public:
static void setScreenOrientation(Qt::ScreenOrientation currentOrientation,
Qt::ScreenOrientation nativeOrientation);
QTouchDevice *touchDevice() const { return m_touchDevice; }
void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; }
QPointingDevice *touchDevice() const { return m_touchDevice; }
void setTouchDevice(QPointingDevice *touchDevice) { m_touchDevice = touchDevice; }
void flushPendingUpdates();
@ -139,7 +139,7 @@ public:
private:
EGLDisplay m_eglDisplay;
QTouchDevice *m_touchDevice;
QPointingDevice *m_touchDevice;
QAndroidPlatformScreen *m_primaryScreen;

View File

@ -42,14 +42,14 @@
#include "qmultitouch_mac_p.h"
#include "qcocoahelpers.h"
#include "qcocoascreen.h"
#include <private/qtouchdevice_p.h>
#include <private/qpointingdevice_p.h>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcInputDevices, "qt.qpa.input.devices")
QHash<qint64, QCocoaTouch*> QCocoaTouch::_currentTouches;
QHash<quint64, QTouchDevice*> QCocoaTouch::_touchDevices;
QHash<quint64, QPointingDevice*> QCocoaTouch::_touchDevices;
QPointF QCocoaTouch::_screenReferencePos;
QPointF QCocoaTouch::_trackpadReferencePos;
int QCocoaTouch::_idAssignmentCount = 0;
@ -219,17 +219,18 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch)
return touchPoints.values();
}
QTouchDevice *QCocoaTouch::getTouchDevice(QTouchDevice::DeviceType type, quint64 id)
QPointingDevice *QCocoaTouch::getTouchDevice(QInputDevice::DeviceType type, quint64 id)
{
QTouchDevice *ret = _touchDevices.value(id);
QPointingDevice *ret = _touchDevices.value(id);
if (!ret) {
ret = new QTouchDevice;
ret->setType(type);
ret->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation);
QWindowSystemInterface::registerTouchDevice(ret);
ret = new QPointingDevice(type == QInputDevice::DeviceType::TouchScreen ? QLatin1String("touchscreen") : QLatin1String("trackpad"),
id, type, QPointingDevice::PointerType::Finger,
QInputDevice::Capability::Position |
QInputDevice::Capability::NormalizedPosition |
QInputDevice::Capability::MouseEmulation,
10, 0);
QWindowSystemInterface::registerInputDevice(ret);
_touchDevices.insert(id, ret);
qCDebug(lcInputDevices) << "touch device" << id << "of type" << type
<< "registered as Qt device" << QTouchDevicePrivate::get(ret)->id;
}
return ret;
}

View File

@ -55,7 +55,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <qhash.h>
#include <QtCore>
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtCore/private/qcore_mac_p.h>
@ -69,10 +69,10 @@ class QCocoaTouch
public:
static QList<QWindowSystemInterface::TouchPoint> getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch);
static void setMouseInDraggingState(bool inDraggingState);
static QTouchDevice *getTouchDevice(QTouchDevice::DeviceType type, quint64 id);
static QPointingDevice *getTouchDevice(QInputDevice::DeviceType type, quint64 id);
private:
static QHash<quint64, QTouchDevice*> _touchDevices;
static QHash<quint64, QPointingDevice*> _touchDevices;
static QHash<qint64, QCocoaTouch*> _currentTouches;
static QPointF _screenReferencePos;
static QPointF _trackpadReferencePos;

View File

@ -75,7 +75,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF windowPoint;
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::ZoomNativeGesture,
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::ZoomNativeGesture,
[event magnification], windowPoint, screenPoint);
}
@ -90,7 +90,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF windowPoint;
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::SmartZoomNativeGesture,
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::SmartZoomNativeGesture,
zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
zoomIn = !zoomIn;
}
@ -107,7 +107,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF windowPoint;
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::RotateNativeGesture,
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::RotateNativeGesture,
-[event rotation], windowPoint, screenPoint);
}
@ -132,7 +132,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
else if ([event deltaY] == -1)
angle = 270.0f;
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::SwipeNativeGesture,
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::SwipeNativeGesture,
angle, windowPoint, screenPoint);
}
@ -146,7 +146,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
qCDebug(lcQpaGestures) << "beginGestureWithEvent @" << windowPoint << "from device" << Qt::hex << [event deviceID];
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::BeginNativeGesture,
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::BeginNativeGesture,
windowPoint, screenPoint);
}
@ -160,7 +160,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF windowPoint;
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::EndNativeGesture,
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::EndNativeGesture,
windowPoint, screenPoint);
}

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -41,12 +41,14 @@
#ifndef QT_NO_TABLETEVENT
#include "qpointingdevice.h"
Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
struct QCocoaTabletDeviceData
{
QTabletEvent::TabletDevice device;
QTabletEvent::PointerType pointerType;
QInputDevice::DeviceType device;
QPointingDevice::PointerType pointerType;
uint capabilityMask;
qint64 uid;
};
@ -116,7 +118,7 @@ Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash)
static_cast<uint>(buttons), pressure, xTilt, yTilt, rotation);
QWindowSystemInterface::handleTabletEvent(m_platformWindow->window(), timestamp, windowPoint, screenPoint,
deviceData.device, deviceData.pointerType, buttons, pressure, xTilt, yTilt,
int(deviceData.device), int(deviceData.pointerType), buttons, pressure, xTilt, yTilt,
tangentialPressure, rotation, z, deviceData.uid,
keyboardModifiers);
return true;
@ -130,7 +132,7 @@ Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash)
[self handleTabletEvent: theEvent];
}
static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
static QInputDevice::DeviceType wacomTabletDevice(NSEvent *theEvent)
{
qint64 uid = [theEvent uniqueID];
uint bits = [theEvent vendorPointingDeviceType];
@ -141,30 +143,30 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
bits = uid >> 32;
}
QTabletEvent::TabletDevice device;
QInputDevice::DeviceType device;
// Defined in the "EN0056-NxtGenImpGuideX"
// on Wacom's Developer Website (www.wacomeng.com)
if (((bits & 0x0006) == 0x0002) && ((bits & 0x0F06) != 0x0902)) {
device = QTabletEvent::Stylus;
device = QInputDevice::DeviceType::Stylus;
} else {
switch (bits & 0x0F06) {
case 0x0802:
device = QTabletEvent::Stylus;
device = QInputDevice::DeviceType::Stylus;
break;
case 0x0902:
device = QTabletEvent::Airbrush;
device = QInputDevice::DeviceType::Airbrush;
break;
case 0x0004:
device = QTabletEvent::FourDMouse;
device = QInputDevice::DeviceType::Mouse; // TODO set capabilities
break;
case 0x0006:
device = QTabletEvent::Puck;
device = QInputDevice::DeviceType::Puck;
break;
case 0x0804:
device = QTabletEvent::RotationStylus;
device = QInputDevice::DeviceType::Stylus; // TODO set capability rotation
break;
default:
device = QTabletEvent::NoDevice;
device = QInputDevice::DeviceType::Unknown;
}
}
return device;
@ -184,16 +186,16 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
switch ([theEvent pointingDeviceType]) {
case NSPointingDeviceTypeUnknown:
default:
deviceData.pointerType = QTabletEvent::UnknownPointer;
deviceData.pointerType = QPointingDevice::PointerType::Unknown;
break;
case NSPointingDeviceTypePen:
deviceData.pointerType = QTabletEvent::Pen;
deviceData.pointerType = QPointingDevice::PointerType::Pen;
break;
case NSPointingDeviceTypeCursor:
deviceData.pointerType = QTabletEvent::Cursor;
deviceData.pointerType = QPointingDevice::PointerType::Cursor;
break;
case NSPointingDeviceTypeEraser:
deviceData.pointerType = QTabletEvent::Eraser;
deviceData.pointerType = QPointingDevice::PointerType::Eraser;
break;
}
@ -213,9 +215,9 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
deviceId, deviceData.device, deviceData.pointerType, deviceData.uid);
if (entering) {
QWindowSystemInterface::handleTabletEnterProximityEvent(timestamp, deviceData.device, deviceData.pointerType, deviceData.uid);
QWindowSystemInterface::handleTabletEnterProximityEvent(timestamp, int(deviceData.device), int(deviceData.pointerType), deviceData.uid);
} else {
QWindowSystemInterface::handleTabletLeaveProximityEvent(timestamp, deviceData.device, deviceData.pointerType, deviceData.uid);
QWindowSystemInterface::handleTabletLeaveProximityEvent(timestamp, int(deviceData.device), int(deviceData.pointerType), deviceData.uid);
}
}
@end

View File

@ -61,7 +61,7 @@ Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch")
const NSTimeInterval timestamp = [event timestamp];
const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
qCDebug(lcQpaTouch) << "touchesBeganWithEvent" << points << "from device" << Qt::hex << [event deviceID];
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), points);
}
- (void)touchesMovedWithEvent:(NSEvent *)event
@ -72,7 +72,7 @@ Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch")
const NSTimeInterval timestamp = [event timestamp];
const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
qCDebug(lcQpaTouch) << "touchesMovedWithEvent" << points << "from device" << Qt::hex << [event deviceID];
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), points);
}
- (void)touchesEndedWithEvent:(NSEvent *)event
@ -83,7 +83,7 @@ Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch")
const NSTimeInterval timestamp = [event timestamp];
const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
qCDebug(lcQpaTouch) << "touchesEndedWithEvent" << points << "from device" << Qt::hex << [event deviceID];
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), points);
}
- (void)touchesCancelledWithEvent:(NSEvent *)event
@ -94,7 +94,7 @@ Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch")
const NSTimeInterval timestamp = [event timestamp];
const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
qCDebug(lcQpaTouch) << "touchesCancelledWithEvent" << points << "from device" << Qt::hex << [event deviceID];
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), points);
}
@end

View File

@ -87,7 +87,7 @@ public:
QAbstractEventDispatcher *createEventDispatcher() const override;
QPlatformNativeInterface *nativeInterface() const override;
QTouchDevice *touchDevice();
QPointingDevice *touchDevice();
#ifndef QT_NO_ACCESSIBILITY
QPlatformAccessibility *accessibility() const override;
#endif
@ -110,7 +110,7 @@ private:
QPlatformClipboard *m_clipboard;
#endif
QPlatformInputContext *m_inputContext;
QTouchDevice *m_touchDevice;
QPointingDevice *m_touchDevice;
QIOSServices *m_platformServices;
mutable QPlatformAccessibility *m_accessibility;
QFactoryLoader *m_optionalPlugins;

View File

@ -53,7 +53,7 @@
#include "qiosservices.h"
#include "qiosoptionalplugininterface.h"
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qoffscreensurface.h>
@ -117,13 +117,13 @@ void QIOSIntegration::initialize()
// Depends on a primary screen being present
m_inputContext = new QIOSInputContext;
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition;
m_touchDevice = new QPointingDevice;
m_touchDevice->setType(QInputDevice::DeviceType::TouchScreen);
QPointingDevice::Capabilities touchCapabilities = QPointingDevice::Capability::Position | QPointingDevice::Capability::NormalizedPosition;
if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
touchCapabilities |= QTouchDevice::Pressure;
touchCapabilities |= QPointingDevice::Capability::Pressure;
m_touchDevice->setCapabilities(touchCapabilities);
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
QWindowSystemInterface::registerInputDevice(m_touchDevice);
#if QT_CONFIG(tabletevent)
QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
#endif
@ -280,7 +280,7 @@ QPlatformTheme *QIOSIntegration::createPlatformTheme(const QString &name) const
return QPlatformIntegration::createPlatformTheme(name);
}
QTouchDevice *QIOSIntegration::touchDevice()
QPointingDevice *QIOSIntegration::touchDevice()
{
return m_touchDevice;
}

View File

@ -49,7 +49,7 @@
#include <QtCore/private/qcore_mac_p.h>
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qwindow_p.h>
#include <private/qcoregraphics_p.h>
#include <qpa/qwindowsysteminterface.h>

View File

@ -49,7 +49,7 @@
#include "qiosmenu.h"
#endif
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qwindow_p.h>
#include <qpa/qwindowsysteminterface_p.h>
@ -351,13 +351,11 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
{
[super traitCollectionDidChange: previousTraitCollection];
QTouchDevice *touchDevice = QIOSIntegration::instance()->touchDevice();
QTouchDevice::Capabilities touchCapabilities = touchDevice->capabilities();
QPointingDevice *touchDevice = QIOSIntegration::instance()->touchDevice();
QPointingDevice::Capabilities touchCapabilities = touchDevice->capabilities();
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
touchCapabilities |= QTouchDevice::Pressure;
else
touchCapabilities &= ~QTouchDevice::Pressure;
touchCapabilities.setFlag(QPointingDevice::Capability::Pressure,
(self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable));
touchDevice->setCapabilities(touchCapabilities);
}
@ -372,7 +370,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
- (void)handleTouches:(NSSet *)touches withEvent:(UIEvent *)event withState:(Qt::TouchPointState)state withTimestamp:(ulong)timeStamp
{
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
bool supportsPressure = QIOSIntegration::instance()->touchDevice()->capabilities() & QTouchDevice::Pressure;
bool supportsPressure = QIOSIntegration::instance()->touchDevice()->capabilities() & QPointingDevice::Capability::Pressure;
#if QT_CONFIG(tabletevent)
if (m_activePencilTouch && [touches containsObject:m_activePencilTouch]) {
@ -396,7 +394,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
<< "xTilt" << qBound(-60.0, altitudeAngle * azimuth.dx, 60.0) << "yTilt" << qBound(-60.0, altitudeAngle * azimuth.dy, 60.0);
QWindowSystemInterface::handleTabletEvent(self.platformWindow->window(), timeStamp, localViewPosition, globalScreenPosition,
// device, pointerType, buttons
QTabletEvent::RotationStylus, QTabletEvent::Pen, state == Qt::TouchPointReleased ? Qt::NoButton : Qt::LeftButton,
int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Pen), state == Qt::TouchPointReleased ? Qt::NoButton : Qt::LeftButton,
// pressure, xTilt, yTilt
pressure, qBound(-60.0, altitudeAngle * azimuth.dx, 60.0), qBound(-60.0, altitudeAngle * azimuth.dy, 60.0),
// tangentialPressure, rotation, z, uid, modifiers
@ -422,7 +420,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
touchPoint.area = QRectF(globalScreenPosition, QSize(0, 0));
// FIXME: Do we really need to support QTouchDevice::NormalizedPosition?
// FIXME: Do we really need to support QPointingDevice::Capability::NormalizedPosition?
QSize screenSize = self.platformWindow->screen()->geometry().size();
touchPoint.normalPosition = QPointF(globalScreenPosition.x() / screenSize.width(),
globalScreenPosition.y() / screenSize.height());
@ -434,7 +432,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
// sending a touch press event to Qt, just to have a valid pressure.
touchPoint.pressure = uiTouch.force / uiTouch.maximumPossibleForce;
} else {
// We don't claim that our touch device supports QTouchDevice::Pressure,
// We don't claim that our touch device supports QPointingDevice::Capability::Pressure,
// but fill in a meaningful value in case clients use it anyway.
touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0;
}

View File

@ -49,7 +49,6 @@
#include <QDebug>
#include <QGuiApplication>
#include <QTouchDevice>
#include <errno.h>
#include <sys/keycodes.h>
@ -146,10 +145,10 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration)
, m_focusLostTimer(-1)
{
// Create a touch device
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition);
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
m_touchDevice = new QPointingDevice;
m_touchDevice->setType(QInputDevice::DeviceType::TouchScreen);
m_touchDevice->setCapabilities(QPointingDevice::Capability::Position | QPointingDevice::Capability::Area | QPointingDevice::Capability::Pressure | QPointingDevice::Capability::NormalizedPosition);
QWindowSystemInterface::registerInputDevice(m_touchDevice);
// initialize array of touch points
for (int i = 0; i < MaximumTouchPoints; i++) {

View File

@ -97,7 +97,7 @@ private:
QPoint m_lastLocalMousePoint;
Qt::MouseButtons m_lastButtonState;
screen_window_t m_lastMouseWindow;
QTouchDevice *m_touchDevice;
QPointingDevice *m_touchDevice;
QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints];
QList<QQnxScreenEventFilter*> m_eventFilters;
QQnxScreenEventThread *m_eventThread;

View File

@ -329,10 +329,10 @@ QWasmEventTranslator::QWasmEventTranslator(QWasmScreen *screen)
, pressedButtons(Qt::NoButton)
, resizeMode(QWasmWindow::ResizeNone)
{
touchDevice = new QTouchDevice;
touchDevice->setType(QTouchDevice::TouchScreen);
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition);
QWindowSystemInterface::registerTouchDevice(touchDevice);
touchDevice = new QPointingDevice;
touchDevice->setType(QInputDevice::DeviceType::TouchScreen);
touchDevice->setCapabilities(QPointingDevice::Capability::Position | QPointingDevice::Capability::Area | QPointingDevice::Capability::NormalizedPosition);
QWindowSystemInterface::registerInputDevice(touchDevice);
initEventHandlers();
}

View File

@ -35,7 +35,7 @@
#include <QtCore/qpoint.h>
#include <emscripten/html5.h>
#include "qwasmwindow.h"
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QHash>
QT_BEGIN_NAMESPACE
@ -88,7 +88,7 @@ private:
QWasmWindow::ResizeMode resizeMode;
QPoint resizePoint;
QRect resizeStartRect;
QTouchDevice *touchDevice;
QPointingDevice *touchDevice;
quint64 getTimestamp();
Qt::Key m_emDeadKey = Qt::Key_unknown;

View File

@ -70,7 +70,7 @@
#include <qpa/qplatformnativeinterface.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtCore/qset.h>
#include <QtCore/qhash.h>
@ -348,15 +348,15 @@ bool QWindowsContext::initTouch(unsigned integrationOptions)
if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
return true;
QTouchDevice *touchDevice = (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) ?
QPointingDevice *touchDevice = (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) ?
d->m_pointerHandler.ensureTouchDevice() : d->m_mouseHandler.ensureTouchDevice();
if (!touchDevice)
return false;
if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch))
touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
touchDevice->setCapabilities(touchDevice->capabilities() | QInputDevice::Capability::MouseEmulation);
QWindowSystemInterface::registerTouchDevice(touchDevice);
QWindowSystemInterface::registerInputDevice(touchDevice);
d->m_systemInfo |= QWindowsContext::SI_SupportsTouch;
@ -1631,7 +1631,7 @@ void QWindowsContext::setAsyncExpose(bool value)
d->m_asyncExpose = value;
}
QTouchDevice *QWindowsContext::touchDevice() const
QPointingDevice *QWindowsContext::touchDevice() const
{
return (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) ?
d->m_pointerHandler.touchDevice() : d->m_mouseHandler.touchDevice();

View File

@ -80,7 +80,7 @@ struct QWindowCreationContext;
struct QWindowsContextPrivate;
class QPoint;
class QKeyEvent;
class QTouchDevice;
class QPointingDevice;
struct QWindowsUser32DLL
{
@ -265,7 +265,7 @@ public:
static DWORD readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue);
QTouchDevice *touchDevice() const;
QPointingDevice *touchDevice() const;
static bool filterNativeEvent(MSG *msg, LRESULT *result);
static bool filterNativeEvent(QWindow *window, MSG *msg, LRESULT *result);

View File

@ -73,7 +73,7 @@
#if QT_CONFIG(sessionmanager)
# include "qwindowssessionmanager.h"
#endif
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/qpa/qplatforminputcontextfactory_p.h>

View File

@ -47,7 +47,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qscreen.h>
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/qwindow.h>
#include <QtGui/qcursor.h>
@ -117,7 +117,7 @@ static inline void compressMouseMove(MSG *msg)
}
}
static inline QTouchDevice *createTouchDevice()
static inline QPointingDevice *createTouchDevice()
{
const int digitizers = GetSystemMetrics(SM_DIGITIZER);
if (!(digitizers & (NID_INTEGRATED_TOUCH | NID_EXTERNAL_TOUCH)))
@ -127,12 +127,12 @@ static inline QTouchDevice *createTouchDevice()
qCDebug(lcQpaEvents) << "Digitizers:" << Qt::hex << Qt::showbase << (digitizers & ~NID_READY)
<< "Ready:" << (digitizers & NID_READY) << Qt::dec << Qt::noshowbase
<< "Tablet PC:" << tabletPc << "Max touch points:" << maxTouchPoints;
auto *result = new QTouchDevice;
auto *result = new QPointingDevice;
result->setType(digitizers & NID_INTEGRATED_TOUCH
? QTouchDevice::TouchScreen : QTouchDevice::TouchPad);
QTouchDevice::Capabilities capabilities = QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition;
if (result->type() == QTouchDevice::TouchPad)
capabilities |= QTouchDevice::MouseEmulation;
? QInputDevice::DeviceType::TouchScreen : QInputDevice::DeviceType::TouchPad);
QPointingDevice::Capabilities capabilities = QPointingDevice::Capability::Position | QPointingDevice::Capability::Area | QPointingDevice::Capability::NormalizedPosition;
if (result->type() == QInputDevice::DeviceType::TouchPad)
capabilities.setFlag(QInputDevice::Capability::MouseEmulation);
result->setCapabilities(capabilities);
result->setMaximumTouchPoints(maxTouchPoints);
return result;
@ -149,7 +149,7 @@ static inline QTouchDevice *createTouchDevice()
QWindowsMouseHandler::QWindowsMouseHandler() = default;
QTouchDevice *QWindowsMouseHandler::ensureTouchDevice()
QPointingDevice *QWindowsMouseHandler::ensureTouchDevice()
{
if (!m_touchDevice)
m_touchDevice = createTouchDevice();

View File

@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
class QWindow;
class QTouchDevice;
class QPointingDevice;
class QWindowsMouseHandler
{
@ -58,8 +58,8 @@ class QWindowsMouseHandler
public:
QWindowsMouseHandler();
QTouchDevice *touchDevice() const { return m_touchDevice; }
QTouchDevice *ensureTouchDevice();
QPointingDevice *touchDevice() const { return m_touchDevice; }
QPointingDevice *ensureTouchDevice();
bool translateMouseEvent(QWindow *widget, HWND hwnd,
QtWindows::WindowsEventType t, MSG msg,
@ -90,7 +90,7 @@ private:
QPointer<QWindow> m_trackedWindow;
QHash<DWORD, int> m_touchInputIDToTouchPointID;
QHash<int, QPointF> m_lastTouchPositions;
QTouchDevice *m_touchDevice = nullptr;
QPointingDevice *m_touchDevice = nullptr;
bool m_leftButtonDown = false;
QWindow *m_previousCaptureWindow = nullptr;
QEvent::Type m_lastEventType = QEvent::None;

View File

@ -53,7 +53,7 @@
#include <QtGui/qguiapplication.h>
#include <QtGui/qscreen.h>
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/qwindow.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtCore/qvarlengtharray.h>
@ -75,6 +75,13 @@ enum {
QT_PT_TOUCHPAD = 5, // MinGW is missing PT_TOUCHPAD
};
qint64 QWindowsPointerHandler::m_nextInputDeviceId = 1;
QWindowsPointerHandler::~QWindowsPointerHandler()
{
delete m_touchDevice;
}
bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
{
*result = 0;
@ -310,31 +317,30 @@ static bool isValidWheelReceiver(QWindow *candidate)
return false;
}
static QTouchDevice *createTouchDevice()
QPointingDevice *QWindowsPointerHandler::ensureTouchDevice()
{
const int digitizers = GetSystemMetrics(SM_DIGITIZER);
if (!(digitizers & (NID_INTEGRATED_TOUCH | NID_EXTERNAL_TOUCH)))
return nullptr;
const int tabletPc = GetSystemMetrics(SM_TABLETPC);
const int maxTouchPoints = GetSystemMetrics(SM_MAXIMUMTOUCHES);
qCDebug(lcQpaEvents) << "Digitizers:" << Qt::hex << Qt::showbase << (digitizers & ~NID_READY)
<< "Ready:" << (digitizers & NID_READY) << Qt::dec << Qt::noshowbase
<< "Tablet PC:" << tabletPc << "Max touch points:" << maxTouchPoints;
auto *result = new QTouchDevice;
result->setType(digitizers & NID_INTEGRATED_TOUCH
? QTouchDevice::TouchScreen : QTouchDevice::TouchPad);
QTouchDevice::Capabilities capabilities = QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition;
if (result->type() == QTouchDevice::TouchPad)
capabilities |= QTouchDevice::MouseEmulation;
result->setCapabilities(capabilities);
result->setMaximumTouchPoints(maxTouchPoints);
return result;
}
QTouchDevice *QWindowsPointerHandler::ensureTouchDevice()
{
if (!m_touchDevice)
m_touchDevice = createTouchDevice();
if (!m_touchDevice) {
const int digitizers = GetSystemMetrics(SM_DIGITIZER);
if (!(digitizers & (NID_INTEGRATED_TOUCH | NID_EXTERNAL_TOUCH)))
return nullptr;
const int tabletPc = GetSystemMetrics(SM_TABLETPC);
const int maxTouchPoints = GetSystemMetrics(SM_MAXIMUMTOUCHES);
const bool touchScreen = digitizers & NID_INTEGRATED_TOUCH;
QPointingDevice::Capabilities capabilities = QPointingDevice::Capability::Position;
if (!touchScreen) {
capabilities.setFlag(QInputDevice::Capability::MouseEmulation);
capabilities.setFlag(QInputDevice::Capability::Scroll);
}
qCDebug(lcQpaEvents) << "Digitizers:" << Qt::hex << Qt::showbase << (digitizers & ~NID_READY)
<< "Ready:" << (digitizers & NID_READY) << Qt::dec << Qt::noshowbase
<< "Tablet PC:" << tabletPc << "Max touch points:" << maxTouchPoints << "Capabilities:" << capabilities;
// TODO: use system-provided name and device ID rather than empty-string and m_nextInputDeviceId
m_touchDevice = new QPointingDevice(QString(), m_nextInputDeviceId++,
(touchScreen ? QInputDevice::DeviceType::TouchScreen : QInputDevice::DeviceType::TouchPad),
QPointingDevice::PointerType::Finger, capabilities, maxTouchPoints,
// TODO: precise button count (detect whether the touchpad can emulate 3 or more buttons)
(touchScreen ? 1 : 3));
}
return m_touchDevice;
}
@ -577,8 +583,8 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
<< " message=" << Qt::hex << msg.message
<< " flags=" << Qt::hex << penInfo->pointerInfo.pointerFlags;
const QTabletEvent::TabletDevice device = QTabletEvent::Stylus;
QTabletEvent::PointerType type;
const QInputDevice::DeviceType device = QInputDevice::DeviceType::Stylus;
QPointingDevice::PointerType type;
// Since it may be the middle button, so if the checks fail then it should
// be set to Middle if it was used.
Qt::MouseButtons mouseButtons = queryMouseButtons();
@ -588,16 +594,16 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
mouseButtons = Qt::LeftButton;
if (penInfo->penFlags & (PEN_FLAG_ERASER | PEN_FLAG_INVERTED)) {
type = QTabletEvent::Eraser;
type = QPointingDevice::PointerType::Eraser;
} else {
type = QTabletEvent::Pen;
type = QPointingDevice::PointerType::Pen;
if (pointerInContact && penInfo->penFlags & PEN_FLAG_BARREL)
mouseButtons = Qt::RightButton; // Either left or right, not both
}
switch (msg.message) {
case WM_POINTERENTER: {
QWindowSystemInterface::handleTabletEnterProximityEvent(device, type, sourceDevice);
QWindowSystemInterface::handleTabletEnterProximityEvent(int(device), int(type), sourceDevice);
m_windowUnderPointer = window;
// The local coordinates may fall outside the window.
// Wait until the next update to send the enter event.
@ -610,7 +616,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
m_windowUnderPointer = nullptr;
m_currentWindow = nullptr;
}
QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, sourceDevice);
QWindowSystemInterface::handleTabletLeaveProximityEvent(int(device), int(type), sourceDevice);
break;
case WM_POINTERDOWN:
case WM_POINTERUP:
@ -635,7 +641,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
}
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, int(device), int(type), mouseButtons,
pressure, xTilt, yTilt, tangentialPressure, rotation, z,
sourceDevice, keyModifiers);
return false; // Allow mouse messages to be generated.

View File

@ -51,17 +51,18 @@
QT_BEGIN_NAMESPACE
class QWindow;
class QTouchDevice;
class QPointingDevice;
class QWindowsPointerHandler
{
Q_DISABLE_COPY_MOVE(QWindowsPointerHandler)
public:
QWindowsPointerHandler() = default;
~QWindowsPointerHandler();
bool translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result);
bool translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result);
QTouchDevice *touchDevice() const { return m_touchDevice; }
QTouchDevice *ensureTouchDevice();
QPointingDevice *touchDevice() const { return m_touchDevice; }
QPointingDevice *ensureTouchDevice();
QWindow *windowUnderMouse() const { return m_windowUnderPointer.data(); }
void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; }
void clearEvents();
@ -73,7 +74,7 @@ private:
void handleCaptureRelease(QWindow *window, QWindow *currentWindowUnderPointer, HWND hwnd, QEvent::Type eventType, Qt::MouseButtons mouseButtons);
void handleEnterLeave(QWindow *window, QWindow *currentWindowUnderPointer, QPoint globalPos);
QTouchDevice *m_touchDevice = nullptr;
QPointingDevice *m_touchDevice = nullptr;
QHash<int, QPointF> m_lastTouchPositions;
QHash<DWORD, int> m_touchInputIDToTouchPointID;
QPointer<QWindow> m_windowUnderPointer;
@ -83,6 +84,7 @@ private:
QEvent::Type m_lastEventType = QEvent::None;
Qt::MouseButton m_lastEventButton = Qt::NoButton;
DWORD m_pointerType = 0;
static qint64 m_nextInputDeviceId; // workaround until we know how to get system device IDs
};
QT_END_NAMESPACE

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -326,42 +326,42 @@ static inline int indexOfDevice(const QVector<QWindowsTabletDeviceData> &devices
return -1;
}
static inline QTabletEvent::TabletDevice deviceType(const UINT cursorType)
static inline QInputDevice::DeviceType deviceType(const UINT cursorType)
{
if (((cursorType & 0x0006) == 0x0002) && ((cursorType & CursorTypeBitMask) != 0x0902))
return QTabletEvent::Stylus;
return QInputDevice::DeviceType::Stylus;
if (cursorType == 0x4020) // Surface Pro 2 tablet device
return QTabletEvent::Stylus;
return QInputDevice::DeviceType::Stylus;
switch (cursorType & CursorTypeBitMask) {
case 0x0802:
return QTabletEvent::Stylus;
return QInputDevice::DeviceType::Stylus;
case 0x0902:
return QTabletEvent::Airbrush;
return QInputDevice::DeviceType::Airbrush;
case 0x0004:
return QTabletEvent::FourDMouse;
return QInputDevice::DeviceType::Mouse;
case 0x0006:
return QTabletEvent::Puck;
return QInputDevice::DeviceType::Puck;
case 0x0804:
return QTabletEvent::RotationStylus;
return QInputDevice::DeviceType::Stylus;
default:
break;
}
return QTabletEvent::NoDevice;
return QInputDevice::DeviceType::Unknown;
}
static inline QTabletEvent::PointerType pointerType(unsigned currentCursor)
static inline QPointingDevice::PointerType pointerType(unsigned currentCursor)
{
switch (currentCursor % 3) { // %3 for dual track
case 0:
return QTabletEvent::Cursor;
return QPointingDevice::PointerType::Cursor;
case 1:
return QTabletEvent::Pen;
return QPointingDevice::PointerType::Pen;
case 2:
return QTabletEvent::Eraser;
return QPointingDevice::PointerType::Eraser;
default:
break;
}
return QTabletEvent::UnknownPointer;
return QPointingDevice::PointerType::Unknown;
}
QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(qint64 uniqueId, UINT cursorType) const
@ -389,6 +389,7 @@ QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(qint64 uniqueId, UINT
result.maxY = int(defaultLc.lcInExtY) - int(defaultLc.lcInOrgY);
result.maxZ = int(defaultLc.lcInExtZ) - int(defaultLc.lcInOrgZ);
result.currentDevice = deviceType(cursorType);
result.zCapability = (cursorType == 0x0004);
return result;
}
@ -404,12 +405,12 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
m_state = PenUp;
if (totalPacks > 0) {
QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime,
m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
int(m_devices.at(m_currentDevice).currentDevice),
int(m_devices.at(m_currentDevice).currentPointerType),
m_devices.at(m_currentDevice).uniqueId);
} else {
QWindowSystemInterface::handleTabletLeaveProximityEvent(m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
QWindowSystemInterface::handleTabletLeaveProximityEvent(int(m_devices.at(m_currentDevice).currentDevice),
int(m_devices.at(m_currentDevice).currentPointerType),
m_devices.at(m_currentDevice).uniqueId);
}
@ -458,9 +459,11 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
m_state = PenProximity;
qCDebug(lcQpaTablet) << "enter proximity for device #"
<< m_currentDevice << m_devices.at(m_currentDevice);
// TODO use the version taking a QPointingDevice, and own those instances; replace QWindowsTabletDeviceData
// TODO QWindowSystemInterface::registerInputDevice() as early as possible, and before sending any events from it
QWindowSystemInterface::handleTabletEnterProximityEvent(proximityBuffer[0].pkTime,
m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
int(m_devices.at(m_currentDevice).currentDevice),
int(m_devices.at(m_currentDevice).currentPointerType),
m_devices.at(m_currentDevice).uniqueId);
return true;
}
@ -518,8 +521,8 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
if (!packetCount || m_currentDevice < 0)
return false;
const int currentDevice = m_devices.at(m_currentDevice).currentDevice;
const int currentPointer = m_devices.at(m_currentDevice).currentPointerType;
const auto currentDevice = m_devices.at(m_currentDevice).currentDevice;
const auto currentPointer = m_devices.at(m_currentDevice).currentPointerType;
const qint64 uniqueId = m_devices.at(m_currentDevice).uniqueId;
// The tablet can be used in 2 different modes (reflected in enum Mode),
@ -549,7 +552,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
for (int i = 0; i < packetCount ; ++i) {
const PACKET &packet = localPacketBuf[i];
const int z = currentDevice == QTabletEvent::FourDMouse ? int(packet.pkZ) : 0;
const int z = m_devices.at(m_currentDevice).zCapability ? int(packet.pkZ) : 0;
QPointF globalPosF =
m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
@ -578,10 +581,10 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
Q_ASSERT(platformWindow);
const QPoint localPos = platformWindow->mapFromGlobal(globalPos);
const qreal pressureNew = packet.pkButtons && (currentPointer == QTabletEvent::Pen || currentPointer == QTabletEvent::Eraser) ?
const qreal pressureNew = packet.pkButtons && (currentPointer == QPointingDevice::PointerType::Pen || currentPointer == QPointingDevice::PointerType::Eraser) ?
m_devices.at(m_currentDevice).scalePressure(packet.pkNormalPressure) :
qreal(0);
const qreal tangentialPressure = currentDevice == QTabletEvent::Airbrush ?
const qreal tangentialPressure = currentDevice == QInputDevice::DeviceType::Airbrush ?
m_devices.at(m_currentDevice).scaleTangentialPressure(packet.pkTangentPressure) :
qreal(0);
@ -621,7 +624,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
convertTabletButtons(packet.pkButtons, m_devices.at(m_currentDevice));
QWindowSystemInterface::handleTabletEvent(target, packet.pkTime, QPointF(localPos), globalPosF,
currentDevice, currentPointer,
int(currentDevice), int(currentPointer),
buttons,
pressureNew, tiltX, tiltY,
tangentialPressure, rotation, z,

View File

@ -42,6 +42,7 @@
#include "qtwindowsglobal.h"
#include <QtGui/qtguiglobal.h>
#include <QtGui/qpointingdevice.h>
#include <QtCore/qvector.h>
#include <QtCore/qpoint.h>
@ -99,8 +100,9 @@ struct QWindowsTabletDeviceData
int minZ = 0;
int maxZ = 0;
qint64 uniqueId = 0;
int currentDevice = 0;
int currentPointerType = 0;
QInputDevice::DeviceType currentDevice = QInputDevice::DeviceType::Unknown;
QPointingDevice::PointerType currentPointerType = QPointingDevice::PointerType::Unknown;
bool zCapability = false;
QHash<quint8, quint8> buttonsMap;
};

View File

@ -44,6 +44,7 @@
#include <xcb/randr.h>
#include <QtCore/QTimer>
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qtguiglobal_p.h>
#include "qxcbexport.h"
#include <QHash>
@ -263,10 +264,11 @@ private:
inline bool timeGreaterThan(xcb_timestamp_t a, xcb_timestamp_t b) const
{ return static_cast<int32_t>(a - b) > 0 || b == XCB_CURRENT_TIME; }
void xi2SetupDevice(void *info, bool removeExisting = true);
void xi2SetupSlavePointerDevice(void *info, bool removeExisting = true, QPointingDevice *master = nullptr);
void xi2SetupDevices();
// TODO get rid of this: store a smaller struct in QPointingDevicePrivate::extra
struct TouchDeviceData {
QTouchDevice *qtTouchDevice = nullptr;
QPointingDevice *qtTouchDevice = nullptr;
QHash<int, QWindowSystemInterface::TouchPoint> touchPoints;
QHash<int, QPointF> pointPressedPosition; // in screen coordinates where each point was pressed
struct ValuatorClassInfo {
@ -290,10 +292,12 @@ private:
void xi2HandleDeviceChangedEvent(void *event);
void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow);
#if QT_CONFIG(tabletevent)
// TODO get rid of this: store a smaller struct in QPointingDevicePrivate::extra
struct TabletData {
int deviceId = 0;
QTabletEvent::PointerType pointerType = QTabletEvent::UnknownPointer;
QTabletEvent::TabletDevice tool = QTabletEvent::Stylus;
QString name;
QPointingDevice::PointerType pointerType = QPointingDevice::PointerType::Unknown;
QInputDevice::DeviceType tool = QInputDevice::DeviceType::Stylus;
Qt::MouseButtons buttons;
qint64 serialId = 0;
bool inProximity = false;
@ -312,6 +316,7 @@ private:
QVector<TabletData> m_tabletData;
TabletData *tabletDataForDevice(int id);
#endif // QT_CONFIG(tabletevent)
// TODO get rid of this: store a smaller struct in QPointingDevicePrivate::extra
struct ScrollingDevice {
int deviceId = 0;
int verticalIndex = 0;

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -41,8 +41,9 @@
#include "qxcbkeyboard.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
#include "qtouchdevice.h"
#include "QtCore/qmetaobject.h"
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qpointingdevice_p.h>
#include <qpa/qwindowsysteminterface_p.h>
#include <QDebug>
#include <cmath>
@ -107,7 +108,129 @@ static inline qreal fixed3232ToReal(xcb_input_fp3232_t val)
return qreal(val.integral) + qreal(val.frac) / (1ULL << 32);
}
void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
#if QT_CONFIG(tabletevent)
/*!
\internal
Find the existing QPointingDevice instance representing a particular tablet or stylus;
or create and register a new instance if it was not found.
An instance can be uniquely identified by its \a devType, \a pointerType and \a uniqueId.
The rest of the arguments are necessary to create a new instance.
If the instance represents a stylus, the instance representing the tablet
itself must be given as \a master. Otherwise, \a master must be the xinput
master device (core pointer) to which the tablet belongs. It should not be
null, because \a master is also the QObject::parent() for memory management.
Proximity events have incomplete information. So as a side effect, if an
existing instance is found, it is updated with the given \a usbId and
\a toolId, and the seat ID of \a master, in case those values were only
now discovered, or the seat assignment changed (?).
*/
static const QPointingDevice *tabletToolInstance(QPointingDevice *master, const QString &tabletName,
qint64 id, quint32 usbId, quint32 toolId, qint64 uniqueId,
QPointingDevice::PointerType pointerTypeOverride = QPointingDevice::PointerType::Unknown,
QPointingDevice::Capabilities capsOverride = QInputDevice::Capability::None)
{
QInputDevice::DeviceType devType = QInputDevice::DeviceType::Stylus;
QPointingDevice::PointerType pointerType = QPointingDevice::PointerType::Pen;
QPointingDevice::Capabilities caps = QInputDevice::Capability::Position |
QInputDevice::Capability::Pressure |
QInputDevice::Capability::MouseEmulation |
QInputDevice::Capability::Hover |
capsOverride;
int buttonCount = 3; // the tip, plus two barrel buttons
// keep in sync with wacom_intuos_inout() in Linux kernel driver wacom_wac.c
// TODO yeah really, there are many more now so this needs updating
switch (toolId) {
case 0xd12:
case 0x912:
case 0x112:
case 0x913: /* Intuos3 Airbrush */
case 0x902: /* Intuos4/5 13HD/24HD Airbrush */
case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */
devType = QInputDevice::DeviceType::Airbrush;
caps.setFlag(QInputDevice::Capability::XTilt);
caps.setFlag(QInputDevice::Capability::YTilt);
caps.setFlag(QInputDevice::Capability::TangentialPressure);
buttonCount = 2;
break;
case 0x91b: /* Intuos3 Airbrush Eraser */
case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
devType = QInputDevice::DeviceType::Airbrush;
pointerType = QPointingDevice::PointerType::Eraser;
caps.setFlag(QInputDevice::Capability::XTilt);
caps.setFlag(QInputDevice::Capability::YTilt);
caps.setFlag(QInputDevice::Capability::TangentialPressure);
buttonCount = 2;
break;
case 0x007: /* Mouse 4D and 2D */
case 0x09c:
case 0x094:
// TODO set something to indicate a multi-dimensional capability:
// Capability::3D or 4D or QPointingDevice::setMaximumDimensions()?
devType = QInputDevice::DeviceType::Mouse;
buttonCount = 5; // TODO only if it's a 4D Mouse
break;
case 0x017: /* Intuos3 2D Mouse */
case 0x806: /* Intuos4 Mouse */
devType = QInputDevice::DeviceType::Mouse;
break;
case 0x096: /* Lens cursor */
case 0x097: /* Intuos3 Lens cursor */
case 0x006: /* Intuos4 Lens cursor */
devType = QInputDevice::DeviceType::Puck;
break;
case 0x885: /* Intuos3 Art Pen (Marker Pen) */
case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */
caps.setFlag(QInputDevice::Capability::XTilt);
caps.setFlag(QInputDevice::Capability::YTilt);
caps.setFlag(QInputDevice::Capability::Rotation);
buttonCount = 1;
break;
case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */
pointerType = QPointingDevice::PointerType::Eraser;
caps.setFlag(QInputDevice::Capability::XTilt);
caps.setFlag(QInputDevice::Capability::YTilt);
caps.setFlag(QInputDevice::Capability::Rotation);
buttonCount = 1;
break;
case 0:
pointerType = QPointingDevice::PointerType::Unknown;
break;
}
if (pointerTypeOverride != QPointingDevice::PointerType::Unknown)
pointerType = pointerTypeOverride;
const QPointingDevice *ret = QPointingDevice::tabletDevice(devType, pointerType, QPointingDeviceUniqueId::fromNumericId(uniqueId));
if (!ret) {
ret = new QPointingDevice(tabletName, id, devType, pointerType, caps, 1, buttonCount,
master ? master->seatName() : QString(),
QPointingDeviceUniqueId::fromNumericId(uniqueId), master);
QWindowSystemInterface::registerInputDevice(ret);
}
QPointingDevicePrivate *devPriv = QPointingDevicePrivate::get(const_cast<QPointingDevice *>(ret));
devPriv->busId = QString::number(usbId, 16);
devPriv->toolId = toolId;
if (master)
devPriv->seatName = master->seatName();
return ret;
}
static const char *toolName(QInputDevice::DeviceType tool) {
static const QMetaObject *metaObject = qt_getEnumMetaObject(tool);
static const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(tool)));
return me.valueToKey(int(tool));
}
static const char *pointerTypeName(QPointingDevice::PointerType ptype) {
static const QMetaObject *metaObject = qt_getEnumMetaObject(ptype);
static const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(ptype)));
return me.valueToKey(int(ptype));
}
#endif
void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting, QPointingDevice *master)
{
auto *deviceInfo = reinterpret_cast<xcb_input_xi_device_info_t *>(info);
if (removeExisting) {
@ -128,6 +251,7 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
TabletData tabletData;
#endif
ScrollingDevice scrollingDevice;
int buttonCount = 32;
auto classes_it = xcb_input_xi_device_info_classes_iterator(deviceInfo);
for (; classes_it.rem; xcb_input_device_class_next(&classes_it)) {
xcb_input_device_class_t *classinfo = classes_it.data;
@ -183,6 +307,7 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
if ((!label6 || qatom(label6) == QXcbAtom::ButtonHorizWheelLeft) && (!label7 || qatom(label7) == QXcbAtom::ButtonHorizWheelRight))
scrollingDevice.legacyOrientations |= Qt::Horizontal;
}
buttonCount = bci->num_buttons;
qCDebug(lcQpaXInputDevices, " has %d buttons", bci->num_buttons);
break;
}
@ -207,42 +332,43 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
// But we need to be careful not to take the touch and tablet-button devices as tablets.
QByteArray name = QByteArray(xcb_input_xi_device_info_name(deviceInfo),
xcb_input_xi_device_info_name_length(deviceInfo)).toLower();
xcb_input_xi_device_info_name_length(deviceInfo));
QByteArray nameLower = name.toLower();
QString dbgType = QLatin1String("UNKNOWN");
if (name.contains("eraser")) {
if (nameLower.contains("eraser")) {
isTablet = true;
tabletData.pointerType = QTabletEvent::Eraser;
tabletData.pointerType = QPointingDevice::PointerType::Eraser;
dbgType = QLatin1String("eraser");
} else if (name.contains("cursor") && !(name.contains("cursor controls") && name.contains("trackball"))) {
} else if (nameLower.contains("cursor") && !(nameLower.contains("cursor controls") && nameLower.contains("trackball"))) {
isTablet = true;
tabletData.pointerType = QTabletEvent::Cursor;
tabletData.pointerType = QPointingDevice::PointerType::Cursor;
dbgType = QLatin1String("cursor");
} else if (name.contains("wacom") && name.contains("finger touch")) {
} else if (nameLower.contains("wacom") && nameLower.contains("finger touch")) {
isTablet = false;
} else if ((name.contains("pen") || name.contains("stylus")) && isTablet) {
tabletData.pointerType = QTabletEvent::Pen;
} else if ((nameLower.contains("pen") || nameLower.contains("stylus")) && isTablet) {
tabletData.pointerType = QPointingDevice::PointerType::Pen;
dbgType = QLatin1String("pen");
} else if (name.contains("wacom") && isTablet && !name.contains("touch")) {
} else if (nameLower.contains("wacom") && isTablet && !nameLower.contains("touch")) {
// combined device (evdev) rather than separate pen/eraser (wacom driver)
tabletData.pointerType = QTabletEvent::Pen;
tabletData.pointerType = QPointingDevice::PointerType::Pen;
dbgType = QLatin1String("pen");
} else if (name.contains("aiptek") /* && device == QXcbAtom::KEYBOARD */) {
} else if (nameLower.contains("aiptek") /* && device == QXcbAtom::KEYBOARD */) {
// some "Genius" tablets
isTablet = true;
tabletData.pointerType = QTabletEvent::Pen;
tabletData.pointerType = QPointingDevice::PointerType::Pen;
dbgType = QLatin1String("pen");
} else if (name.contains("waltop") && name.contains("tablet")) {
} else if (nameLower.contains("waltop") && nameLower.contains("tablet")) {
// other "Genius" tablets
// WALTOP International Corp. Slim Tablet
isTablet = true;
tabletData.pointerType = QTabletEvent::Pen;
tabletData.pointerType = QPointingDevice::PointerType::Pen;
dbgType = QLatin1String("pen");
} else if (name.contains("uc-logic") && isTablet) {
tabletData.pointerType = QTabletEvent::Pen;
} else if (nameLower.contains("uc-logic") && isTablet) {
tabletData.pointerType = QPointingDevice::PointerType::Pen;
dbgType = QLatin1String("pen");
} else if (name.contains("ugee")) {
} else if (nameLower.contains("ugee")) {
isTablet = true;
tabletData.pointerType = QTabletEvent::Pen;
tabletData.pointerType = QPointingDevice::PointerType::Pen;
dbgType = QLatin1String("pen");
} else {
isTablet = false;
@ -250,8 +376,20 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
if (isTablet) {
tabletData.deviceId = deviceInfo->deviceid;
tabletData.name = QLatin1String(name);
m_tabletData.append(tabletData);
qCDebug(lcQpaXInputDevices) << " it's a tablet with pointer type" << dbgType;
QPointingDevice::Capabilities capsOverride = QInputDevice::Capability::None;
if (tabletData.valuatorInfo.contains(QXcbAtom::AbsTiltX))
capsOverride.setFlag(QInputDevice::Capability::XTilt);
if (tabletData.valuatorInfo.contains(QXcbAtom::AbsTiltY))
capsOverride.setFlag(QInputDevice::Capability::YTilt);
// TODO can we get USB ID?
Q_ASSERT(deviceInfo->deviceid == tabletData.deviceId);
const QPointingDevice *dev = tabletToolInstance(master,
tabletData.name, deviceInfo->deviceid, 0, 0, tabletData.serialId,
tabletData.pointerType, capsOverride);
Q_ASSERT(dev);
}
#endif // QT_CONFIG(tabletevent)
@ -266,18 +404,28 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
if (!isTablet) {
TouchDeviceData *dev = populateTouchDevices(deviceInfo);
if (dev && lcQpaXInputDevices().isDebugEnabled()) {
if (dev->qtTouchDevice->type() == QTouchDevice::TouchScreen)
if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchScreen)
qCDebug(lcQpaXInputDevices, " it's a touchscreen with type %d capabilities 0x%X max touch points %d",
dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
dev->qtTouchDevice->maximumTouchPoints());
else if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
int(dev->qtTouchDevice->type()), qint32(dev->qtTouchDevice->capabilities()),
dev->qtTouchDevice->maximumPoints());
else if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchPad)
qCDebug(lcQpaXInputDevices, " it's a touchpad with type %d capabilities 0x%X max touch points %d size %f x %f",
dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
dev->qtTouchDevice->maximumTouchPoints(),
int(dev->qtTouchDevice->type()), qint32(dev->qtTouchDevice->capabilities()),
dev->qtTouchDevice->maximumPoints(),
dev->size.width(), dev->size.height());
}
}
if (!QInputDevicePrivate::fromId(deviceInfo->deviceid)) {
qCDebug(lcQpaXInputDevices) << " it's a mouse";
QInputDevice::Capabilities caps = QInputDevice::Capability::Position | QInputDevice::Capability::Hover;
if (scrollingDevice.orientations || scrollingDevice.legacyOrientations)
caps.setFlag(QInputDevice::Capability::Scroll);
QWindowSystemInterface::registerInputDevice(new QPointingDevice(
QString::fromUtf8(xcb_input_xi_device_info_name(deviceInfo)), deviceInfo->deviceid,
QInputDevice::DeviceType::Mouse, QPointingDevice::PointerType::Generic,
caps, 1, buttonCount, (master ? master->seatName() : QString()), QPointingDeviceUniqueId(), master));
}
}
void QXcbConnection::xi2SetupDevices()
@ -295,16 +443,56 @@ void QXcbConnection::xi2SetupDevices()
return;
}
// XInput doesn't provide a way to identify "seats"; but each device has an attachment to another device.
// So we make up a seatId: master-keyboard-id << 16 | master-pointer-id.
auto it = xcb_input_xi_query_device_infos_iterator(reply.get());
for (; it.rem; xcb_input_xi_device_info_next(&it)) {
xcb_input_xi_device_info_t *deviceInfo = it.data;
if (deviceInfo->type == XCB_INPUT_DEVICE_TYPE_MASTER_POINTER) {
switch (deviceInfo->type) {
case XCB_INPUT_DEVICE_TYPE_MASTER_KEYBOARD: {
auto dev = new QInputDevice(QString::fromUtf8(xcb_input_xi_device_info_name(deviceInfo)),
deviceInfo->deviceid, QInputDevice::DeviceType::Keyboard,
QString::number(deviceInfo->attachment << 16 | deviceInfo->deviceid, 16), this);
QWindowSystemInterface::registerInputDevice(dev);
} break;
case XCB_INPUT_DEVICE_TYPE_MASTER_POINTER: {
m_xiMasterPointerIds.append(deviceInfo->deviceid);
auto dev = new QPointingDevice(QString::fromUtf8(xcb_input_xi_device_info_name(deviceInfo)), deviceInfo->deviceid,
QInputDevice::DeviceType::Mouse, QPointingDevice::PointerType::Generic,
QInputDevice::Capability::Position | QInputDevice::Capability::Scroll | QInputDevice::Capability::Hover,
1, 32, QString::number(deviceInfo->attachment << 16 | deviceInfo->deviceid, 16), QPointingDeviceUniqueId(), this);
QWindowSystemInterface::registerInputDevice(dev);
continue;
} break;
default:
break;
}
}
it = xcb_input_xi_query_device_infos_iterator(reply.get());
for (; it.rem; xcb_input_xi_device_info_next(&it)) {
xcb_input_xi_device_info_t *deviceInfo = it.data;
switch (deviceInfo->type) {
case XCB_INPUT_DEVICE_TYPE_MASTER_KEYBOARD:
case XCB_INPUT_DEVICE_TYPE_MASTER_POINTER:
// already registered
break;
case XCB_INPUT_DEVICE_TYPE_SLAVE_POINTER: {
QInputDevice *master = const_cast<QInputDevice *>(QInputDevicePrivate::fromId(deviceInfo->attachment));
Q_ASSERT(master);
xi2SetupSlavePointerDevice(deviceInfo, false, qobject_cast<QPointingDevice *>(master));
} break;
case XCB_INPUT_DEVICE_TYPE_SLAVE_KEYBOARD: {
QInputDevice *master = const_cast<QInputDevice *>(QInputDevicePrivate::fromId(deviceInfo->attachment));
Q_ASSERT(master);
QWindowSystemInterface::registerInputDevice(new QInputDevice(
QString::fromUtf8(xcb_input_xi_device_info_name(deviceInfo)), deviceInfo->deviceid,
QInputDevice::DeviceType::Keyboard, master->seatName(), master));
} break;
case XCB_INPUT_DEVICE_TYPE_FLOATING_SLAVE:
break;
}
// only slave pointer devices are relevant here
if (deviceInfo->type == XCB_INPUT_DEVICE_TYPE_SLAVE_POINTER)
xi2SetupDevice(deviceInfo, false);
}
if (m_xiMasterPointerIds.size() > 1)
@ -423,14 +611,14 @@ QXcbConnection::TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info)
{
auto *deviceinfo = reinterpret_cast<xcb_input_xi_device_info_t *>(info);
QTouchDevice::Capabilities caps;
int type = -1;
auto *deviceInfo = reinterpret_cast<xcb_input_xi_device_info_t *>(info);
QPointingDevice::Capabilities caps;
QInputDevice::DeviceType type = QInputDevice::DeviceType::Unknown;
int maxTouchPoints = 1;
bool isTouchDevice = false;
bool hasRelativeCoords = false;
TouchDeviceData dev;
auto classes_it = xcb_input_xi_device_info_classes_iterator(deviceinfo);
auto classes_it = xcb_input_xi_device_info_classes_iterator(deviceInfo);
for (; classes_it.rem; xcb_input_device_class_next(&classes_it)) {
xcb_input_device_class_t *classinfo = classes_it.data;
switch (classinfo->type) {
@ -440,10 +628,10 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
qCDebug(lcQpaXInputDevices, " has touch class with mode %d", tci->mode);
switch (tci->mode) {
case XCB_INPUT_TOUCH_MODE_DEPENDENT:
type = QTouchDevice::TouchPad;
type = QInputDevice::DeviceType::TouchPad;
break;
case XCB_INPUT_TOUCH_MODE_DIRECT:
type = QTouchDevice::TouchScreen;
type = QInputDevice::DeviceType::TouchScreen;
break;
}
break;
@ -463,13 +651,13 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
// for now just prevent a division by zero
const int vciResolution = vci->resolution ? vci->resolution : 1;
if (valuatorAtom == QXcbAtom::AbsMTPositionX)
caps |= QTouchDevice::Position | QTouchDevice::NormalizedPosition;
caps |= QInputDevice::Capability::Position | QInputDevice::Capability::NormalizedPosition;
else if (valuatorAtom == QXcbAtom::AbsMTTouchMajor)
caps |= QTouchDevice::Area;
caps |= QInputDevice::Capability::Area;
else if (valuatorAtom == QXcbAtom::AbsMTOrientation)
dev.providesTouchOrientation = true;
else if (valuatorAtom == QXcbAtom::AbsMTPressure || valuatorAtom == QXcbAtom::AbsPressure)
caps |= QTouchDevice::Pressure;
caps |= QInputDevice::Capability::Pressure;
else if (valuatorAtom == QXcbAtom::RelX) {
hasRelativeCoords = true;
dev.size.setWidth((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
@ -477,10 +665,10 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
hasRelativeCoords = true;
dev.size.setHeight((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
} else if (valuatorAtom == QXcbAtom::AbsX) {
caps |= QTouchDevice::Position;
caps |= QInputDevice::Capability::Position;
dev.size.setWidth((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
} else if (valuatorAtom == QXcbAtom::AbsY) {
caps |= QTouchDevice::Position;
caps |= QInputDevice::Capability::Position;
dev.size.setHeight((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
}
break;
@ -489,29 +677,30 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
break;
}
}
if (type < 0 && caps && hasRelativeCoords) {
type = QTouchDevice::TouchPad;
if (type == QInputDevice::DeviceType::Unknown && caps && hasRelativeCoords) {
type = QInputDevice::DeviceType::TouchPad;
if (dev.size.width() < 10 || dev.size.height() < 10 ||
dev.size.width() > 10000 || dev.size.height() > 10000)
dev.size = QSizeF(130, 110);
}
if (!isAtLeastXI22() || type == QTouchDevice::TouchPad)
caps |= QTouchDevice::MouseEmulation;
if (!isAtLeastXI22() || type == QInputDevice::DeviceType::TouchPad)
caps |= QInputDevice::Capability::MouseEmulation;
if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) {
dev.qtTouchDevice = new QTouchDevice;
dev.qtTouchDevice->setName(QString::fromUtf8(xcb_input_xi_device_info_name(deviceinfo),
xcb_input_xi_device_info_name_length(deviceinfo)));
dev.qtTouchDevice->setType((QTouchDevice::DeviceType)type);
dev.qtTouchDevice->setCapabilities(caps);
dev.qtTouchDevice->setMaximumTouchPoints(maxTouchPoints);
if (type == QInputDevice::DeviceType::TouchScreen || type == QInputDevice::DeviceType::TouchPad) {
QInputDevice *master = const_cast<QInputDevice *>(QInputDevicePrivate::fromId(deviceInfo->attachment));
Q_ASSERT(master);
dev.qtTouchDevice = new QPointingDevice(QString::fromUtf8(xcb_input_xi_device_info_name(deviceInfo),
xcb_input_xi_device_info_name_length(deviceInfo)),
deviceInfo->deviceid,
type, QPointingDevice::PointerType::Finger, caps, maxTouchPoints, 0,
master->seatName(), QPointingDeviceUniqueId(), master);
if (caps != 0)
QWindowSystemInterface::registerTouchDevice(dev.qtTouchDevice);
m_touchDevices[deviceinfo->deviceid] = dev;
QWindowSystemInterface::registerInputDevice(dev.qtTouchDevice);
m_touchDevices[deviceInfo->deviceid] = dev;
isTouchDevice = true;
}
return isTouchDevice ? &m_touchDevices[deviceinfo->deviceid] : nullptr;
return isTouchDevice ? &m_touchDevices[deviceInfo->deviceid] : nullptr;
}
static inline qreal fixed1616ToReal(xcb_input_fp1616_t val)
@ -564,6 +753,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
#if QT_CONFIG(tabletevent)
if (!xiEnterEvent) {
// TODO we need the UID here; tabletDataForDevice doesn't have enough to go on (?)
QXcbConnection::TabletData *tablet = tabletDataForDevice(sourceDeviceId);
if (tablet && xi2HandleTabletEvent(event, tablet))
return;
@ -616,7 +806,7 @@ bool QXcbConnection::xi2MouseEventsDisabled() const
bool QXcbConnection::isTouchScreen(int id)
{
auto device = touchDeviceForId(id);
return device && device->qtTouchDevice->type() == QTouchDevice::TouchScreen;
return device && device->qtTouchDevice->type() == QInputDevice::DeviceType::TouchScreen;
}
void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow)
@ -728,7 +918,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
}
break;
case XCB_INPUT_TOUCH_UPDATE:
if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
qreal dx = (nx - dev->firstPressedNormalPosition.x()) *
dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
qreal dy = (ny - dev->firstPressedNormalPosition.y()) *
@ -738,11 +928,11 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
touchPoint.state = Qt::TouchPointMoved;
} else if (touchPoint.area.center() != QPoint(x, y)) {
touchPoint.state = Qt::TouchPointMoved;
if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchPad)
dev->pointPressedPosition[touchPoint.id] = QPointF(x, y);
}
if (dev->qtTouchDevice->type() == QTouchDevice::TouchScreen &&
if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchScreen &&
xiDeviceEvent->event == m_startSystemMoveResizeInfo.window &&
xiDeviceEvent->sourceid == m_startSystemMoveResizeInfo.deviceid &&
xiDeviceEvent->detail == m_startSystemMoveResizeInfo.pointid) {
@ -758,7 +948,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
break;
case XCB_INPUT_TOUCH_END:
touchPoint.state = Qt::TouchPointReleased;
if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
qreal dx = (nx - dev->firstPressedNormalPosition.x()) *
dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
qreal dy = (ny - dev->firstPressedNormalPosition.y()) *
@ -790,7 +980,7 @@ bool QXcbConnection::startSystemMoveResizeForTouch(xcb_window_t window, int edge
QHash<int, TouchDeviceData>::const_iterator devIt = m_touchDevices.constBegin();
for (; devIt != m_touchDevices.constEnd(); ++devIt) {
TouchDeviceData deviceData = devIt.value();
if (deviceData.qtTouchDevice->type() == QTouchDevice::TouchScreen) {
if (deviceData.qtTouchDevice->type() == QInputDevice::DeviceType::TouchScreen) {
auto pointIt = deviceData.touchPoints.constBegin();
for (; pointIt != deviceData.touchPoints.constEnd(); ++pointIt) {
Qt::TouchPointState state = pointIt.value().state;
@ -893,7 +1083,7 @@ void QXcbConnection::xi2HandleDeviceChangedEvent(void *event)
if (!reply || reply->num_infos <= 0)
return;
auto it = xcb_input_xi_query_device_infos_iterator(reply.get());
xi2SetupDevice(it.data);
xi2SetupSlavePointerDevice(it.data);
break;
}
case XCB_INPUT_CHANGE_REASON_SLAVE_SWITCH: {
@ -1081,51 +1271,6 @@ Qt::MouseButton QXcbConnection::xiToQtMouseButton(uint32_t b)
}
#if QT_CONFIG(tabletevent)
static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) {
// keep in sync with wacom_intuos_inout() in Linux kernel driver wacom_wac.c
switch (toolId) {
case 0xd12:
case 0x912:
case 0x112:
case 0x913: /* Intuos3 Airbrush */
case 0x91b: /* Intuos3 Airbrush Eraser */
case 0x902: /* Intuos4/5 13HD/24HD Airbrush */
case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */
case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
return QTabletEvent::Airbrush;
case 0x007: /* Mouse 4D and 2D */
case 0x09c:
case 0x094:
return QTabletEvent::FourDMouse;
case 0x017: /* Intuos3 2D Mouse */
case 0x806: /* Intuos4 Mouse */
case 0x096: /* Lens cursor */
case 0x097: /* Intuos3 Lens cursor */
case 0x006: /* Intuos4 Lens cursor */
return QTabletEvent::Puck;
case 0x885: /* Intuos3 Art Pen (Marker Pen) */
case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */
case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */
return QTabletEvent::RotationStylus;
case 0:
return QTabletEvent::NoDevice;
}
return QTabletEvent::Stylus; // Safe default assumption if nonzero
}
static const char *toolName(QTabletEvent::TabletDevice tool) {
static const QMetaObject *metaObject = qt_getEnumMetaObject(tool);
static const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(tool)));
return me.valueToKey(tool);
}
static const char *pointerTypeName(QTabletEvent::PointerType ptype) {
static const QMetaObject *metaObject = qt_getEnumMetaObject(ptype);
static const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(ptype)));
return me.valueToKey(ptype);
}
bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletData)
{
bool handled = true;
@ -1175,27 +1320,35 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
// The property change event informs us which tool is in proximity or which one left proximity.
if (tool) {
const QPointingDevice *dev = tabletToolInstance(nullptr, tabletData->name,
tabletData->deviceId, ptr[_WACSER_USB_ID], tool,
qint64(ptr[_WACSER_TOOL_SERIAL])); // TODO look up the master
tabletData->inProximity = true;
tabletData->tool = toolIdToTabletDevice(tool);
tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_TOOL_SERIAL]);
tabletData->tool = dev->type();
tabletData->serialId = qint64(ptr[_WACSER_TOOL_SERIAL]);
QWindowSystemInterface::handleTabletEnterProximityEvent(ev->time,
tabletData->tool, tabletData->pointerType, tabletData->serialId);
int(tabletData->tool), int(tabletData->pointerType), tabletData->serialId);
} else {
tabletData->inProximity = false;
tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_ID]);
tool = ptr[_WACSER_LAST_TOOL_ID];
// Workaround for http://sourceforge.net/p/linuxwacom/bugs/246/
// e.g. on Thinkpad Helix, tool ID will be 0 and serial will be 1
if (!tabletData->tool)
tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_SERIAL]);
tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_LAST_TOOL_SERIAL]);
if (!tool)
tool = ptr[_WACSER_LAST_TOOL_SERIAL];
const QInputDevice *dev = QInputDevicePrivate::fromId(tabletData->deviceId);
Q_ASSERT(dev);
tabletData->tool = dev->type();
tabletData->inProximity = false;
tabletData->serialId = qint64(ptr[_WACSER_LAST_TOOL_SERIAL]);
// TODO why doesn't it just take QPointingDevice*
QWindowSystemInterface::handleTabletLeaveProximityEvent(ev->time,
tabletData->tool, tabletData->pointerType, tabletData->serialId);
int(tabletData->tool), int(tabletData->pointerType), tabletData->serialId);
}
// TODO maybe have a hash of tabletData->deviceId to device data so we can
// look up the tablet name here, and distinguish multiple tablets
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x %s",
tabletData->deviceId, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID],
qCDebug(lcQpaXInputDevices, "XI2 proximity change on tablet %d %s (USB %x): last tool: %x id %x current tool: %x id %x %s",
tabletData->deviceId, qPrintable(tabletData->name), ptr[_WACSER_USB_ID],
ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID],
ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], toolName(tabletData->tool));
}
}
@ -1216,6 +1369,7 @@ inline qreal scaleOneValuator(qreal normValue, qreal screenMin, qreal screenSize
return screenMin + normValue * screenSize;
}
// TODO QPointingDevice not TabletData
void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletData)
{
auto *ev = reinterpret_cast<const qt_xcb_input_device_event_t *>(event);
@ -1274,10 +1428,10 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
break;
case QXcbAtom::AbsWheel:
switch (tabletData->tool) {
case QTabletEvent::Airbrush:
case QInputDevice::DeviceType::Airbrush:
tangentialPressure = normalizedValue * 2.0 - 1.0; // Convert 0..1 range to -1..+1 range
break;
case QTabletEvent::RotationStylus:
case QInputDevice::DeviceType::Stylus:
rotation = normalizedValue * 360.0 - 180.0; // Convert 0..1 range to -180..+180 degrees
break;
default: // Other types of styli do not use this valuator
@ -1290,15 +1444,15 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
}
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 event on tablet %d with tool %s type %s seq %d detail %d time %d "
qCDebug(lcQpaXInputEvents, "XI2 event on tablet %d with tool %s %llx type %s seq %d detail %d time %d "
"pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf modifiers 0x%x",
tabletData->deviceId, toolName(tabletData->tool), pointerTypeName(tabletData->pointerType),
tabletData->deviceId, toolName(tabletData->tool), tabletData->serialId, pointerTypeName(tabletData->pointerType),
ev->sequence, ev->detail, ev->time,
local.x(), local.y(), global.x(), global.y(),
(int)tabletData->buttons, pressure, xTilt, yTilt, rotation, (int)modifiers);
QWindowSystemInterface::handleTabletEvent(window, ev->time, local, global,
tabletData->tool, tabletData->pointerType,
int(tabletData->tool), int(tabletData->pointerType),
tabletData->buttons, pressure,
xTilt, yTilt, tangentialPressure,
rotation, 0, tabletData->serialId, modifiers);

View File

@ -1248,14 +1248,14 @@
*/
/*!
\fn QTouchDevice *QTest::createTouchDevice(QTouchDevice::DeviceType devType = QTouchDevice::TouchScreen)
\fn QPointingDevice *QTest::createTouchDevice(QInputDevice::DeviceType devType = QInputDevice::DeviceType::TouchScreen)
\since 5.8
Creates a dummy touch device of type \a devType for simulation of touch events.
The touch device will be registered with the QPA window system interface,
and deleted automatically when the QCoreApplication is deleted. So you
should typically use createTouchDevice() to initialize a QTouchDevice
should typically use createTouchDevice() to initialize a QPointingDevice
member variable in your test case class, and use the same instance for all tests.
\sa QTest::QTouchEventSequence
@ -1380,7 +1380,7 @@
*/
/*!
\fn QTouchEventSequence QTest::touchEvent(QWindow *window, QTouchDevice *device, bool autoCommit)
\fn QTouchEventSequence QTest::touchEvent(QWindow *window, QPointingDevice *device, bool autoCommit)
\since 5.0
Creates and returns a QTouchEventSequence for the \a device to
@ -1397,7 +1397,7 @@
*/
/*!
\fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchDevice *device, bool autoCommit)
\fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QPointingDevice *device, bool autoCommit)
Creates and returns a QTouchEventSequence for the \a device to
simulate events for \a widget.

View File

@ -51,22 +51,25 @@
#include <QtTest/qtestspontaneevent.h>
#include <QtCore/qmap.h>
#include <QtGui/qevent.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/qwindow.h>
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#ifdef QT_WIDGETS_LIB
#include <QtWidgets/qwidget.h>
#endif
QT_BEGIN_NAMESPACE
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device,
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, const QPointingDevice *device,
const QList<QTouchEvent::TouchPoint> &points,
Qt::KeyboardModifiers mods = Qt::NoModifier);
namespace QTest
{
Q_GUI_EXPORT QTouchDevice * createTouchDevice(QTouchDevice::DeviceType devType = QTouchDevice::TouchScreen);
Q_GUI_EXPORT QPointingDevice * createTouchDevice(QInputDevice::DeviceType devType = QInputDevice::DeviceType::TouchScreen,
QInputDevice::Capabilities caps = QInputDevice::Capability::Position);
class QTouchEventSequence
{
@ -151,12 +154,12 @@ namespace QTest
private:
#ifdef QT_WIDGETS_LIB
QTouchEventSequence(QWidget *widget, QTouchDevice *aDevice, bool autoCommit)
QTouchEventSequence(QWidget *widget, QPointingDevice *aDevice, bool autoCommit)
: targetWidget(widget), targetWindow(nullptr), device(aDevice), commitWhenDestroyed(autoCommit)
{
}
#endif
QTouchEventSequence(QWindow *window, QTouchDevice *aDevice, bool autoCommit)
QTouchEventSequence(QWindow *window, QPointingDevice *aDevice, bool autoCommit)
:
#ifdef QT_WIDGETS_LIB
targetWidget(nullptr),
@ -204,18 +207,18 @@ private:
QWidget *targetWidget;
#endif
QWindow *targetWindow;
QTouchDevice *device;
QPointingDevice *device;
bool commitWhenDestroyed;
#if defined(QT_WIDGETS_LIB) || defined(Q_CLANG_QDOC)
friend QTouchEventSequence touchEvent(QWidget *widget, QTouchDevice *device, bool autoCommit);
friend QTouchEventSequence touchEvent(QWidget *widget, QPointingDevice *device, bool autoCommit);
#endif
friend QTouchEventSequence touchEvent(QWindow *window, QTouchDevice *device, bool autoCommit);
friend QTouchEventSequence touchEvent(QWindow *window, QPointingDevice *device, bool autoCommit);
};
#if defined(QT_WIDGETS_LIB) || defined(Q_CLANG_QDOC)
inline
QTouchEventSequence touchEvent(QWidget *widget,
QTouchDevice *device,
QPointingDevice *device,
bool autoCommit = true)
{
return QTouchEventSequence(widget, device, autoCommit);
@ -223,7 +226,7 @@ private:
#endif
inline
QTouchEventSequence touchEvent(QWindow *window,
QTouchDevice *device,
QPointingDevice *device,
bool autoCommit = true)
{
return QTouchEventSequence(window, device, autoCommit);

View File

@ -235,7 +235,7 @@
#include <QtGui/qpainterpath.h>
#include <QtGui/qpixmapcache.h>
#include <QtGui/qpolygon.h>
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtWidgets/qstyleoption.h>
#if QT_CONFIG(tooltip)
#include <QtWidgets/qtooltip.h>
@ -5859,7 +5859,7 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
// update state
QGraphicsItem *item = nullptr;
if (touchPoint.state() == Qt::TouchPointPressed) {
if (sceneTouchEvent->device()->type() == QTouchDevice::TouchPad) {
if (sceneTouchEvent->pointingDevice()->type() == QInputDevice::DeviceType::TouchPad) {
// on touch-pad devices, send all touch points to the same item
item = itemForTouchPointId.isEmpty()
? 0
@ -5874,7 +5874,7 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.constFirst();
}
if (sceneTouchEvent->device()->type() == QTouchDevice::TouchScreen) {
if (sceneTouchEvent->pointingDevice()->type() == QInputDevice::DeviceType::TouchScreen) {
// on touch-screens, combine this touch point with the closest one we find
int closestTouchPointId = findClosestTouchPointId(touchPoint.scenePosition());
QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPointId);
@ -5938,13 +5938,11 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
break;
}
QTouchEvent touchEvent(eventType);
QTouchEvent touchEvent(eventType, sceneTouchEvent->pointingDevice(), sceneTouchEvent->modifiers(), it.value().first, it.value().second);
// TODO more constructor args and fewer setters?
touchEvent.setWindow(sceneTouchEvent->window());
touchEvent.setTarget(sceneTouchEvent->target());
touchEvent.setDevice(sceneTouchEvent->device());
touchEvent.setModifiers(sceneTouchEvent->modifiers());
touchEvent.setTouchPointStates(it.value().first);
touchEvent.setTouchPoints(it.value().second);
touchEvent.setTimestamp(sceneTouchEvent->timestamp());
switch (touchEvent.type()) {

View File

@ -79,7 +79,7 @@
#include <QtGui/qstylehints.h>
#include <QtGui/qinputmethod.h>
#include <QtGui/private/qwindow_p.h>
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <qpa/qplatformtheme.h>
#if QT_CONFIG(whatsthis)
#include <QtWidgets/QWhatsThis>
@ -3120,11 +3120,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QPointF relpos = tablet->position();
bool eventAccepted = tablet->isAccepted();
while (w) {
QTabletEvent te(tablet->type(), relpos, tablet->globalPosition(),
tablet->deviceType(), tablet->pointerType(),
QTabletEvent te(tablet->type(), tablet->pointingDevice(), relpos, tablet->globalPosition(),
tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
tablet->tangentialPressure(), tablet->rotation(), tablet->z(),
tablet->modifiers(), tablet->uniqueId(), tablet->button(), tablet->buttons());
tablet->modifiers(), tablet->button(), tablet->buttons());
te.spont = e->spontaneous();
te.setAccepted(false);
res = d->notify_helper(w, w == receiver ? tablet : &te);
@ -3975,7 +3974,7 @@ void QApplicationPrivate::cleanupMultitouch_sys()
{
}
QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QTouchEvent::TouchPoint &touchPoint)
QWidget *QApplicationPrivate::findClosestTouchPointTarget(const QPointingDevice *device, const QTouchEvent::TouchPoint &touchPoint)
{
const QPointF screenPos = touchPoint.globalPosition();
int closestTouchPointId = -1;
@ -4007,12 +4006,13 @@ void QApplicationPrivate::activateImplicitTouchGrab(QWidget *widget, QTouchEvent
for (int i = 0, tc = touchEvent->touchPoints().count(); i < tc; ++i) {
const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
activeTouchPoints[QGuiApplicationPrivate::ActiveTouchPointsKey(touchEvent->device(), touchPoint.id())].target = widget;
activeTouchPoints[QGuiApplicationPrivate::ActiveTouchPointsKey(
touchEvent->pointingDevice(), touchPoint.id())].target = widget;
}
}
bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
QTouchDevice *device,
const QPointingDevice *device,
const QList<QTouchEvent::TouchPoint> &touchPoints,
ulong timestamp)
{
@ -4032,7 +4032,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
ActiveTouchPointsKey touchInfoKey(device, touchPoint.id());
ActiveTouchPointsValue &touchInfo = d->activeTouchPoints[touchInfoKey];
if (touchPoint.state() == Qt::TouchPointPressed) {
if (device->type() == QTouchDevice::TouchPad) {
if (device->type() == QInputDevice::DeviceType::TouchPad) {
// on touch-pads, send all touch points to the same widget
target = d->activeTouchPoints.isEmpty()
? QPointer<QObject>()
@ -4050,7 +4050,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
target = window;
}
if (device->type() == QTouchDevice::TouchScreen) {
if (device->type() == QInputDevice::DeviceType::TouchScreen) {
QWidget *closestWidget = d->findClosestTouchPointTarget(device, touchPoint);
QWidget *widget = static_cast<QWidget *>(target.data());
if (closestWidget
@ -4073,7 +4073,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
// Single-touch events are normally not sent unless WA_TouchPadAcceptSingleTouchEvents is set.
// In Qt 4 this check was in OS X-only code. That behavior is preserved here by the #ifdef.
if (touchPoints.count() == 1
&& device->type() == QTouchDevice::TouchPad
&& device->type() == QInputDevice::DeviceType::TouchPad
&& !targetWidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents))
continue;
#endif
@ -4153,7 +4153,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
return accepted;
}
void QApplicationPrivate::translateTouchCancel(QTouchDevice *device, ulong timestamp)
void QApplicationPrivate::translateTouchCancel(const QPointingDevice *device, ulong timestamp)
{
QTouchEvent touchEvent(QEvent::TouchCancel, device, QGuiApplication::keyboardModifiers());
touchEvent.setTimestamp(timestamp);

View File

@ -81,7 +81,7 @@ class QGraphicsScene;
class QObject;
class QWidget;
class QSocketNotifier;
class QTouchDevice;
class QPointingDevice;
#ifndef QT_NO_GESTURES
class QGestureManager;
#endif
@ -247,15 +247,15 @@ public:
void initializeMultitouch_sys();
void cleanupMultitouch();
void cleanupMultitouch_sys();
QWidget *findClosestTouchPointTarget(QTouchDevice *device, const QTouchEvent::TouchPoint &touchPoint);
QWidget *findClosestTouchPointTarget(const QPointingDevice *device, const QTouchEvent::TouchPoint &touchPoint);
void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint);
void removeTouchPoint(int touchPointId);
void activateImplicitTouchGrab(QWidget *widget, QTouchEvent *touchBeginEvent);
static bool translateRawTouchEvent(QWidget *widget,
QTouchDevice *device,
const QPointingDevice *device,
const QList<QTouchEvent::TouchPoint> &touchPoints,
ulong timestamp);
static void translateTouchCancel(QTouchDevice *device, ulong timestamp);
static void translateTouchCancel(const QPointingDevice *device, ulong timestamp);
QPixmap applyQIconStyleHelper(QIcon::Mode mode, const QPixmap& base) const override;
private:

View File

@ -692,14 +692,14 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
void QWidgetWindow::handleTouchEvent(QTouchEvent *event)
{
if (event->type() == QEvent::TouchCancel) {
QApplicationPrivate::translateTouchCancel(event->device(), event->timestamp());
QApplicationPrivate::translateTouchCancel(event->pointingDevice(), event->timestamp());
event->accept();
} else if (QApplicationPrivate::inPopupMode()) {
// Ignore touch events for popups. This will cause QGuiApplication to synthesise mouse
// events instead, which QWidgetWindow::handleMouseEvent will forward correctly:
event->ignore();
} else {
event->setAccepted(QApplicationPrivate::translateRawTouchEvent(m_widget, event->device(), event->touchPoints(), event->timestamp()));
event->setAccepted(QApplicationPrivate::translateRawTouchEvent(m_widget, event->pointingDevice(), event->touchPoints(), event->timestamp()));
}
}
@ -1071,9 +1071,9 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
if (widget) {
QPointF delta = event->globalPosition() - event->globalPosition().toPoint();
QPointF mapped = widget->mapFromGlobal(event->globalPosition().toPoint()) + delta;
QTabletEvent ev(event->type(), mapped, event->globalPosition(), event->deviceType(), event->pointerType(),
QTabletEvent ev(event->type(), event->pointingDevice(), mapped, event->globalPosition(),
event->pressure(), event->xTilt(), event->yTilt(), event->tangentialPressure(),
event->rotation(), event->z(), event->modifiers(), event->uniqueId(), event->button(), event->buttons());
event->rotation(), event->z(), event->modifiers(), event->button(), event->buttons());
ev.setTimestamp(event->timestamp());
ev.setAccepted(false);
QGuiApplication::forwardEvent(widget, &ev, event);

View File

@ -48,7 +48,7 @@
#include "qgraphicsview.h"
#endif
#include "qscroller.h"
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include "private/qapplication_p.h"
#include "private/qevent_p.h"
#include "private/qflickgesture_p.h"
@ -547,7 +547,7 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
if (!inputType)
inputType = QScroller::InputMove;
if (te->device()->type() == QTouchDevice::TouchPad) {
if (te->pointingDevice()->type() == QInputDevice::DeviceType::TouchPad) {
if (te->touchPoints().count() != 2) // 2 fingers on pad
return Ignore;

View File

@ -30,7 +30,7 @@
#include <QtCore/qpropertyanimation.h>
#include <QtCore/qvariantanimation.h>
#include <private/qabstractanimation_p.h>
#include <QtGui/qtouchdevice.h>
#include <QtGui/qpointingdevice.h>
#include <QtWidgets/qwidget.h>
Q_DECLARE_METATYPE(QAbstractAnimation::State)

View File

@ -493,12 +493,12 @@ void tst_QGuiApplication::keyboardModifiers()
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
// touch events
QList<const QTouchDevice *> touchDevices = QTouchDevice::devices();
if (!touchDevices.isEmpty()) {
QTouchDevice *touchDevice = const_cast<QTouchDevice *>(touchDevices.first());
QTest::touchEvent(window.data(), touchDevice).press(1, center).release(1, center);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
}
QPointingDevice touchDevice(QLatin1String("test touchscreen"), 0,
QInputDevice::DeviceType::TouchScreen, QPointingDevice::PointerType::Finger,
QPointingDevice::Capability::Position, 10, 0);
QWindowSystemInterface::registerInputDevice(&touchDevice);
QTest::touchEvent(window.data(), &touchDevice).press(1, center).release(1, center);
QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
window->close();
}

View File

@ -36,7 +36,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qwindowsysteminterface_p.h>
#include <private/qhighdpiscaling_p.h>
#include <private/qtouchdevice_p.h>
#include <private/qpointingdevice_p.h>
class tst_QTouchEventWidget : public QWidget
{
@ -46,7 +46,7 @@ public:
bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd;
bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd;
ulong timestamp;
QTouchDevice *deviceFromEvent;
const QPointingDevice *deviceFromEvent;
explicit tst_QTouchEventWidget(QWidget *parent = nullptr) : QWidget(parent)
{
@ -73,7 +73,7 @@ public:
seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd;
touchBeginPoints = static_cast<QTouchEvent *>(event)->touchPoints();
timestamp = static_cast<QTouchEvent *>(event)->timestamp();
deviceFromEvent = static_cast<QTouchEvent *>(event)->device();
deviceFromEvent = static_cast<QTouchEvent *>(event)->pointingDevice();
event->setAccepted(acceptTouchBegin);
if (deleteInTouchBegin)
delete this;
@ -84,7 +84,7 @@ public:
seenTouchUpdate = seenTouchBegin && !seenTouchEnd;
touchUpdatePoints = static_cast<QTouchEvent *>(event)->touchPoints();
timestamp = static_cast<QTouchEvent *>(event)->timestamp();
deviceFromEvent = static_cast<QTouchEvent *>(event)->device();
deviceFromEvent = static_cast<QTouchEvent *>(event)->pointingDevice();
event->setAccepted(acceptTouchUpdate);
if (deleteInTouchUpdate)
delete this;
@ -95,7 +95,7 @@ public:
seenTouchEnd = seenTouchBegin && !seenTouchEnd;
touchEndPoints = static_cast<QTouchEvent *>(event)->touchPoints();
timestamp = static_cast<QTouchEvent *>(event)->timestamp();
deviceFromEvent = static_cast<QTouchEvent *>(event)->device();
deviceFromEvent = static_cast<QTouchEvent *>(event)->pointingDevice();
event->setAccepted(acceptTouchEnd);
if (deleteInTouchEnd)
delete this;
@ -213,22 +213,21 @@ private slots:
void testMultiDevice();
private:
QTouchDevice *touchScreenDevice;
QTouchDevice *secondaryTouchScreenDevice;
QTouchDevice *touchPadDevice;
QPointingDevice *touchScreenDevice;
QPointingDevice *secondaryTouchScreenDevice;
QPointingDevice *touchPadDevice;
};
tst_QTouchEvent::tst_QTouchEvent()
: touchScreenDevice(QTest::createTouchDevice())
, secondaryTouchScreenDevice(QTest::createTouchDevice())
, touchPadDevice(QTest::createTouchDevice(QTouchDevice::TouchPad))
, touchPadDevice(QTest::createTouchDevice(QInputDevice::DeviceType::TouchPad))
{
}
void tst_QTouchEvent::cleanup()
{
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
QWindowSystemInterfacePrivate::clearPointIdMap();
}
void tst_QTouchEvent::qPointerUniqueId()
@ -641,8 +640,7 @@ void tst_QTouchEvent::basicRawEventTranslation()
QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
QCOMPARE(touchWidget.timestamp, timestamp);
QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first();
const int touchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1;
QCOMPARE(touchBeginPoint.id(), touchPointId);
QCOMPARE(touchBeginPoint.id(), 0);
QCOMPARE(touchBeginPoint.state(), rawTouchPoint.state());
QCOMPARE(touchBeginPoint.position(), pos);
QCOMPARE(touchBeginPoint.pressPosition(), pos);
@ -678,7 +676,7 @@ void tst_QTouchEvent::basicRawEventTranslation()
QVERIFY(!touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchUpdatePoints.count(), 1);
QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first();
QCOMPARE(touchUpdatePoint.id(), touchPointId);
QCOMPARE(touchUpdatePoint.id(), 0);
QCOMPARE(touchUpdatePoint.state(), rawTouchPoint.state());
QCOMPARE(touchUpdatePoint.position(), pos + delta);
QCOMPARE(touchUpdatePoint.pressPosition(), pos);
@ -711,7 +709,7 @@ void tst_QTouchEvent::basicRawEventTranslation()
QVERIFY(touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchEndPoints.count(), 1);
QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first();
QCOMPARE(touchEndPoint.id(), touchPointId);
QCOMPARE(touchEndPoint.id(), 0);
QCOMPARE(touchEndPoint.state(), rawTouchPoint.state());
QCOMPARE(touchEndPoint.position(), pos + delta + delta);
QCOMPARE(touchEndPoint.pressPosition(), pos);
@ -785,7 +783,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen()
QVERIFY(!rightWidget.seenTouchEnd);
QCOMPARE(leftWidget.touchBeginPoints.count(), 1);
QCOMPARE(rightWidget.touchBeginPoints.count(), 1);
const int touchPointId0 = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1;
const int touchPointId0 = 0;
const int touchPointId1 = touchPointId0 + 1;
{
QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchBeginPoints.first();
@ -980,7 +978,7 @@ void tst_QTouchEvent::touchOnMultipleTouchscreens()
QRectF screenGeometry = touchWidget.screen()->geometry();
QVector<QTouchEvent::TouchPoint> rawTouchPoints(3);
rawTouchPoints[0].setId(0);
rawTouchPoints[0].setId(1);
rawTouchPoints[1].setId(10);
rawTouchPoints[2].setId(11);
@ -1000,9 +998,7 @@ void tst_QTouchEvent::touchOnMultipleTouchscreens()
QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
QCOMPARE(touchWidget.timestamp, timestamp);
QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first();
const int touchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1;
const int secTouchPointId = (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2;
QCOMPARE(touchBeginPoint.id(), touchPointId);
QCOMPARE(touchBeginPoint.id(), 1);
QCOMPARE(touchBeginPoint.state(), rawTouchPoints[0].state());
QCOMPARE(touchBeginPoint.position(), pos);
@ -1020,7 +1016,7 @@ void tst_QTouchEvent::touchOnMultipleTouchscreens()
QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
QCOMPARE(touchWidget.timestamp, timestamp);
touchBeginPoint = touchWidget.touchBeginPoints[0];
QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2);
QCOMPARE(touchBeginPoint.id(), 10);
QCOMPARE(touchBeginPoint.state(), rawTouchPoints[1].state());
QCOMPARE(touchBeginPoint.position(), pos);
@ -1038,7 +1034,7 @@ void tst_QTouchEvent::touchOnMultipleTouchscreens()
QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
QCOMPARE(touchWidget.timestamp, timestamp);
touchBeginPoint = touchWidget.touchBeginPoints[0];
QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 3);
QCOMPARE(touchBeginPoint.id(), 11);
QCOMPARE(touchBeginPoint.state(), rawTouchPoints[2].state());
QCOMPARE(touchBeginPoint.position(), pos);
@ -1055,7 +1051,7 @@ void tst_QTouchEvent::touchOnMultipleTouchscreens()
QVERIFY(!touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchUpdatePoints.count(), 1);
QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first();
QCOMPARE(touchUpdatePoint.id(), touchPointId);
QCOMPARE(touchUpdatePoint.id(), 1);
QCOMPARE(touchUpdatePoint.state(), rawTouchPoints[0].state());
QCOMPARE(touchUpdatePoint.position(), pos + delta);
@ -1072,7 +1068,7 @@ void tst_QTouchEvent::touchOnMultipleTouchscreens()
QVERIFY(touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchEndPoints.count(), 1);
QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first();
QCOMPARE(touchEndPoint.id(), touchPointId);
QCOMPARE(touchEndPoint.id(), 1);
QCOMPARE(touchEndPoint.state(), rawTouchPoints[0].state());
QCOMPARE(touchEndPoint.position(), pos + delta + delta);
@ -1096,8 +1092,8 @@ void tst_QTouchEvent::touchOnMultipleTouchscreens()
QVERIFY(touchWidget.seenTouchUpdate);
QVERIFY(!touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
QCOMPARE(touchWidget.touchUpdatePoints[0].id(), secTouchPointId);
QCOMPARE(touchWidget.touchUpdatePoints[1].id(), secTouchPointId + 1);
QCOMPARE(touchWidget.touchUpdatePoints[0].id(), 10);
QCOMPARE(touchWidget.touchUpdatePoints[1].id(), 11);
// releasing the last point on the secondary touchscreen translates to TouchEnd
touchWidget.seenTouchEnd = false;
@ -1111,7 +1107,7 @@ void tst_QTouchEvent::touchOnMultipleTouchscreens()
QVERIFY(touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchEndPoints.count(), 1);
touchEndPoint = touchWidget.touchEndPoints.first();
QCOMPARE(touchEndPoint.id(), secTouchPointId + 1);
QCOMPARE(touchEndPoint.id(), 11);
QCOMPARE(touchEndPoint.state(), rawTouchPoints[2].state());
}
@ -1394,11 +1390,9 @@ void tst_QTouchEvent::basicRawEventTranslationOfIds()
QVERIFY(!touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchBeginPoints.count(), 2);
const int initialTouchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1;
for (int i = 0; i < touchWidget.touchBeginPoints.count(); ++i) {
QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.at(i);
QCOMPARE(touchBeginPoint.id(), initialTouchPointId + i);
QCOMPARE(touchBeginPoint.id(), i);
QCOMPARE(touchBeginPoint.state(), rawTouchPoints[i].state());
}
@ -1417,8 +1411,8 @@ void tst_QTouchEvent::basicRawEventTranslationOfIds()
QVERIFY(touchWidget.seenTouchUpdate);
QVERIFY(!touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
QCOMPARE(touchWidget.touchUpdatePoints.at(0).id(), initialTouchPointId);
QCOMPARE(touchWidget.touchUpdatePoints.at(1).id(), initialTouchPointId + 1);
QCOMPARE(touchWidget.touchUpdatePoints.at(0).id(), 0);
QCOMPARE(touchWidget.touchUpdatePoints.at(1).id(), 1);
// release last point
p0.setState(Qt::TouchPointStationary);
@ -1432,8 +1426,8 @@ void tst_QTouchEvent::basicRawEventTranslationOfIds()
QVERIFY(touchWidget.seenTouchUpdate);
QVERIFY(!touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
QCOMPARE(touchWidget.touchUpdatePoints[0].id(), initialTouchPointId);
QCOMPARE(touchWidget.touchUpdatePoints[1].id(), initialTouchPointId + 1);
QCOMPARE(touchWidget.touchUpdatePoints[0].id(), 0);
QCOMPARE(touchWidget.touchUpdatePoints[1].id(), 1);
// Press last point again, id should increase
p1.setState(Qt::TouchPointPressed);
@ -1446,8 +1440,8 @@ void tst_QTouchEvent::basicRawEventTranslationOfIds()
QVERIFY(touchWidget.seenTouchUpdate);
QVERIFY(!touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
QCOMPARE(touchWidget.touchUpdatePoints[0].id(), initialTouchPointId);
QCOMPARE(touchWidget.touchUpdatePoints[1].id(), initialTouchPointId + 2);
QCOMPARE(touchWidget.touchUpdatePoints[0].id(), 0);
QCOMPARE(touchWidget.touchUpdatePoints[1].id(), 42);
// release everything
p0.setState(Qt::TouchPointReleased);
@ -1460,8 +1454,8 @@ void tst_QTouchEvent::basicRawEventTranslationOfIds()
QVERIFY(touchWidget.seenTouchUpdate);
QVERIFY(touchWidget.seenTouchEnd);
QCOMPARE(touchWidget.touchUpdatePoints.count(), 2);
QCOMPARE(touchWidget.touchUpdatePoints[0].id(), initialTouchPointId);
QCOMPARE(touchWidget.touchUpdatePoints[1].id(), initialTouchPointId + 2);
QCOMPARE(touchWidget.touchUpdatePoints[0].id(), 0);
QCOMPARE(touchWidget.touchUpdatePoints[1].id(), 42);
}
void tst_QTouchEvent::deleteInEventHandler()
@ -1782,7 +1776,7 @@ public:
QList<QTouchEvent::TouchPoint> points;
QEvent::Type lastSeenType;
};
QMap<QTouchDevice *, TouchInfo> d;
QMap<const QPointingDevice *, TouchInfo> d;
};
bool WindowTouchEventFilter::eventFilter(QObject *, QEvent *event)
@ -1791,7 +1785,7 @@ bool WindowTouchEventFilter::eventFilter(QObject *, QEvent *event)
|| event->type() == QEvent::TouchUpdate
|| event->type() == QEvent::TouchEnd) {
QTouchEvent *te = static_cast<QTouchEvent *>(event);
TouchInfo &td = d[te->device()];
TouchInfo &td = d[te->pointingDevice()];
if (event->type() == QEvent::TouchBegin)
td.points.clear();
td.points.append(te->touchPoints());
@ -1813,7 +1807,7 @@ void tst_QTouchEvent::testQGuiAppDelivery()
QList<QWindowSystemInterface::TouchPoint> points;
// Pass empty list, should be ignored.
QWindowSystemInterface::handleTouchEvent(&w, 0, points);
QWindowSystemInterface::handleTouchEvent(&w, nullptr, points);
QCoreApplication::processEvents();
QCOMPARE(filter.d.isEmpty(), true);
@ -1823,8 +1817,8 @@ void tst_QTouchEvent::testQGuiAppDelivery()
tp.area = QRectF(120, 120, 20, 20);
points.append(tp);
// Pass 0 as device, should be ignored.
QWindowSystemInterface::handleTouchEvent(&w, 0, points);
// Null device: should be ignored.
QWindowSystemInterface::handleTouchEvent(&w, nullptr, points);
QCoreApplication::processEvents();
QCOMPARE(filter.d.isEmpty(), true);
@ -1855,7 +1849,7 @@ void tst_QTouchEvent::testQGuiAppDelivery()
void tst_QTouchEvent::testMultiDevice()
{
QTouchDevice *deviceTwo = QTest::createTouchDevice();
QPointingDevice *deviceTwo = QTest::createTouchDevice();
QWindow w;
w.setGeometry(100, 100, 100, 100);

View File

@ -110,7 +110,10 @@ private slots:
private:
QPoint m_availableTopLeft;
QSize m_testWindowSize;
QTouchDevice *touchDevice = QTest::createTouchDevice();
QPointingDevice *touchDevice = QTest::createTouchDevice();
QPointingDevice *touchDeviceWithMouseEmulation =
QTest::createTouchDevice(QInputDevice::DeviceType::TouchScreen,
QInputDevice::Capability::Position | QInputDevice::Capability::MouseEmulation);
};
void tst_QWindow::initTestCase()
@ -1180,11 +1183,9 @@ void tst_QWindow::touchToMouseTranslationForDevices()
window.resetCounters();
touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
QTest::touchEvent(&window, touchDevice).press(0, touchPoint, &window);
QTest::touchEvent(&window, touchDevice).release(0, touchPoint, &window);
QTest::touchEvent(&window, touchDeviceWithMouseEmulation).press(0, touchPoint, &window);
QTest::touchEvent(&window, touchDeviceWithMouseEmulation).release(0, touchPoint, &window);
QCoreApplication::processEvents();
touchDevice->setCapabilities(touchDevice->capabilities() & ~QTouchDevice::MouseEmulation);
QCOMPARE(window.mousePressedCount, 0);
QCOMPARE(window.mouseReleasedCount, 0);
@ -1704,7 +1705,8 @@ public:
QEvent::Type eventType = QEvent::None;
QPointF eventGlobal, eventLocal;
int eventDevice = -1;
QInputDevice::DeviceType eventDevice = QInputDevice::DeviceType::Unknown;
QPointingDevice::PointerType eventPointerType = QPointingDevice::PointerType::Unknown;
bool eventFilter(QObject *obj, QEvent *ev) override
{
@ -1713,6 +1715,7 @@ public:
eventType = ev->type();
QTabletEvent *te = static_cast<QTabletEvent *>(ev);
eventDevice = te->deviceType();
eventPointerType = te->pointerType();
}
return QWindow::eventFilter(obj, ev);
}
@ -1741,16 +1744,17 @@ void tst_QWindow::tabletEvents()
QCoreApplication::processEvents();
QTRY_COMPARE(window.eventType, QEvent::TabletRelease);
QWindowSystemInterface::handleTabletEnterProximityEvent(1, 2, 3);
QWindowSystemInterface::handleTabletEnterProximityEvent(int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Eraser), 3);
QCoreApplication::processEvents();
QTRY_COMPARE(window.eventType, QEvent::TabletEnterProximity);
QTRY_COMPARE(window.eventDevice, 1);
QCOMPARE(window.eventDevice, QInputDevice::DeviceType::Stylus);
QCOMPARE(window.eventPointerType, QPointingDevice::PointerType::Eraser);
QWindowSystemInterface::handleTabletLeaveProximityEvent(1, 2, 3);
QWindowSystemInterface::handleTabletLeaveProximityEvent(int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Eraser), 3);
QCoreApplication::processEvents();
QTRY_COMPARE(window.eventType, QEvent::TabletLeaveProximity);
QTRY_COMPARE(window.eventDevice, 1);
QCOMPARE(window.eventDevice, QInputDevice::DeviceType::Stylus);
QCOMPARE(window.eventPointerType, QPointingDevice::PointerType::Eraser);
#endif
}

View File

@ -31,7 +31,7 @@
#include <QtTest/qtesttouch.h>
#include <qevent.h>
#include <qtouchdevice.h>
#include <qpointingdevice.h>
#include <qwidget.h>
#include <qlayout.h>
#include <qgesture.h>
@ -1821,7 +1821,7 @@ void tst_Gestures::deleteMacPanGestureRecognizerTargetWidget()
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
QTouchDevice *device = QTest::createTouchDevice();
QPointingDevice *device = QTest::createTouchDevice();
// QMacOSPenGestureRecognizer will start a timer on a touch press event
QTest::touchEvent(&window, device).press(1, QPoint(100, 100), &window);
delete view;
@ -2327,7 +2327,7 @@ void tst_Gestures::bug_13501_gesture_not_accepted()
w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w));
//QTest::mousePress(&ignoreEvent, Qt::LeftButton);
QTouchDevice *device = QTest::createTouchDevice();
QPointingDevice *device = QTest::createTouchDevice();
QTest::touchEvent(&w, device).press(0, QPoint(10, 10), &w);
}

View File

@ -490,7 +490,7 @@ private slots:
private:
GraphicsItems paintedItems;
QTouchDevice *m_touchDevice = nullptr;
QPointingDevice *m_touchDevice = nullptr;
};
void tst_QGraphicsItem::initMain()

View File

@ -3871,7 +3871,7 @@ void tst_QGraphicsProxyWidget::forwardTouchEvent()
EventSpy eventSpy(widget);
QTouchDevice *device = QTest::createTouchDevice();
QPointingDevice *device = QTest::createTouchDevice();
QCOMPARE(eventSpy.counts[QEvent::TouchBegin], 0);
QCOMPARE(eventSpy.counts[QEvent::TouchUpdate], 0);

View File

@ -4849,8 +4849,8 @@ void tst_QGraphicsScene::focusOnTouch()
scene.setFocusOnTouch(false);
QTouchDevice device;
device.setType(QTouchDevice::TouchPad);
QPointingDevice device;
device.setType(QInputDevice::DeviceType::TouchPad);
QList<QTouchEvent::TouchPoint> touchPoints;
QTouchEvent::TouchPoint point;
point.setScenePos(QPointF(10, 10));

View File

@ -1910,7 +1910,7 @@ void tst_QApplication::touchEventPropagation()
release.setState(Qt::TouchPointReleased);
releasedTouchPoints << release;
QTouchDevice *device = QTest::createTouchDevice();
QPointingDevice *device = QTest::createTouchDevice();
{
// touch event behavior on a window

View File

@ -32,7 +32,7 @@
#include <QtWidgets/QWidget>
#include <QtWidgets/QGestureEvent>
#include <QtGui/QScreen>
#include <QtGui/QTouchDevice>
#include <QtGui/QPointingDevice>
#include <QtCore/QVector>
#include <QtCore/QString>
#include <QtCore/QHash>
@ -57,7 +57,7 @@ private Q_SLOTS:
private:
const int m_fingerDistance;
QTouchDevice *m_touchDevice;
QPointingDevice *m_touchDevice;
};
tst_QGestureRecognizer::tst_QGestureRecognizer()

View File

@ -428,7 +428,7 @@ private:
QPoint m_availableTopLeft;
QPoint m_safeCursorPos;
const bool m_windowsAnimationsEnabled;
QTouchDevice *m_touchScreen;
QPointingDevice *m_touchScreen;
const int m_fuzz;
};
@ -11447,7 +11447,7 @@ void tst_QWidget::tabletTracking()
qint64 uid = 1234UL;
QWindowSystemInterface::handleTabletEvent(window, ulong(QDateTime::currentMSecsSinceEpoch()), deviceLocal, deviceGlobal,
QTabletEvent::Stylus, QTabletEvent::Pen, Qt::NoButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Pen), Qt::NoButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
QCoreApplication::processEvents();
QTRY_COMPARE(widget.moveEventCount, 1);
QCOMPARE(widget.uid, uid);
@ -11456,7 +11456,7 @@ void tst_QWidget::tabletTracking()
deviceLocal += QPoint(10, 10);
deviceGlobal += QPoint(10, 10);
QWindowSystemInterface::handleTabletEvent(window, ulong(QDateTime::currentMSecsSinceEpoch()), deviceLocal, deviceGlobal,
QTabletEvent::Stylus, QTabletEvent::Pen, Qt::NoButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Pen), Qt::NoButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
QCoreApplication::processEvents();
QTRY_COMPARE(widget.moveEventCount, 2);
@ -11465,7 +11465,7 @@ void tst_QWidget::tabletTracking()
QTRY_COMPARE(widget.trackingChangeEventCount, 2);
QWindowSystemInterface::handleTabletEvent(window, ulong(QDateTime::currentMSecsSinceEpoch()), deviceLocal, deviceGlobal,
QTabletEvent::Stylus, QTabletEvent::Pen, Qt::LeftButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Pen), Qt::LeftButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
QCoreApplication::processEvents();
QTRY_COMPARE(widget.pressEventCount, 1);
@ -11473,12 +11473,12 @@ void tst_QWidget::tabletTracking()
deviceLocal += QPoint(10, 10);
deviceGlobal += QPoint(10, 10);
QWindowSystemInterface::handleTabletEvent(window, ulong(QDateTime::currentMSecsSinceEpoch()), deviceLocal, deviceGlobal,
QTabletEvent::Stylus, QTabletEvent::Pen, Qt::LeftButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Pen), Qt::LeftButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
QCoreApplication::processEvents();
QTRY_COMPARE(widget.moveEventCount, 3);
QWindowSystemInterface::handleTabletEvent(window, ulong(QDateTime::currentMSecsSinceEpoch()), deviceLocal, deviceGlobal,
QTabletEvent::Stylus, QTabletEvent::Pen, Qt::NoButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Pen), Qt::NoButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
QCoreApplication::processEvents();
QTRY_COMPARE(widget.releaseEventCount, 1);
@ -11486,7 +11486,7 @@ void tst_QWidget::tabletTracking()
deviceLocal += QPoint(10, 10);
deviceGlobal += QPoint(10, 10);
QWindowSystemInterface::handleTabletEvent(window, ulong(QDateTime::currentMSecsSinceEpoch()), deviceLocal, deviceGlobal,
QTabletEvent::Stylus, QTabletEvent::Pen, Qt::NoButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Pen), Qt::NoButton, 0, 0, 0, 0, 0, 0, uid, Qt::NoModifier);
QCoreApplication::processEvents();
QTRY_COMPARE(widget.moveEventCount, 3);
}

View File

@ -128,7 +128,7 @@ private slots:
void multipleWindows();
private:
QTouchDevice *m_touchScreen = QTest::createTouchDevice();
QPointingDevice *m_touchScreen = QTest::createTouchDevice();
};
/*! \internal

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite module of the Qt Toolkit.
@ -58,8 +58,13 @@ bool TabletWidget::eventFilter(QObject *, QEvent *ev)
mPos = event->pos();
mGPos = event->globalPos();
mHiResGlobalPos = event->posF();
mDev = event->deviceType();
mPointerType = event->pointerType();
if (event->pointingDevice()) {
mDev = event->pointingDevice()->type();
mPointerType = event->pointingDevice()->pointerType();
mCaps = event->pointingDevice()->capabilities();
} else {
qWarning() << "missing device in tablet event";
}
mUnique = event->uniqueId();
mXT = event->xTilt();
mYT = event->yTilt();
@ -132,46 +137,9 @@ void TabletWidget::paintEvent(QPaintEvent *)
eventInfo << QString("High res global position: %1 %2").arg(QString::number(mHiResGlobalPos.x()), QString::number(mHiResGlobalPos.y()));
QString pointerType("Pointer type: ");
switch (mPointerType) {
case QTabletEvent::UnknownPointer:
pointerType += "QTabletEvent::UnknownPointer";
break;
case QTabletEvent::Pen:
pointerType += "QTabletEvent::Pen";
break;
case QTabletEvent::Cursor:
pointerType += "QTabletEvent::Cursor";
break;
case QTabletEvent::Eraser:
pointerType += "QTabletEvent::Eraser";
break;
}
eventInfo << pointerType;
QString deviceString = "Device type: ";
switch (mDev) {
case QTabletEvent::NoDevice:
deviceString += "QTabletEvent::NoDevice";
break;
case QTabletEvent::Puck:
deviceString += "QTabletEvent::Puck";
break;
case QTabletEvent::Stylus:
deviceString += "QTabletEvent::Stylus";
break;
case QTabletEvent::Airbrush:
deviceString += "QTabletEvent::Airbrush";
break;
case QTabletEvent::FourDMouse:
deviceString += "QTabletEvent::FourDMouse";
break;
case QTabletEvent::RotationStylus:
deviceString += "QTabletEvent::RotationStylus";
break;
}
eventInfo << deviceString;
eventInfo << QString("Device type: %1").arg(deviceTypeToString(mDev));
eventInfo << QString("Pointer type: %1").arg(pointerTypeToString(mPointerType));
eventInfo << QString("Capabilities: %1").arg(pointerCapabilitiesToString(mCaps));
eventInfo << QString("Button: %1 (0x%2)").arg(buttonToString(mButton)).arg(mButton, 0, 16);
eventInfo << QString("Buttons currently pressed: %1 (0x%2)").arg(buttonsToString(mButtons)).arg(mButtons, 0, 16);
eventInfo << QString("Keyboard modifiers: %1 (0x%2)").arg(modifiersToString(mModifiers)).arg(mModifiers, 0, 16);
@ -182,7 +150,7 @@ void TabletWidget::paintEvent(QPaintEvent *)
eventInfo << QString("yTilt: %1").arg(QString::number(mYT));
eventInfo << QString("z: %1").arg(QString::number(mZ));
eventInfo << QString("Unique Id: %1").arg(QString::number(mUnique));
eventInfo << QString("Unique Id: %1").arg(QString::number(mUnique, 16));
eventInfo << QString("Total wheel events: %1").arg(QString::number(mWheelEventCount));
}
@ -191,10 +159,28 @@ void TabletWidget::paintEvent(QPaintEvent *)
painter.drawText(rect(), text);
}
const char *TabletWidget::deviceTypeToString(QInputDevice::DeviceType t)
{
static int enumIdx = QInputDevice::staticMetaObject.indexOfEnumerator("DeviceType");
return QPointingDevice::staticMetaObject.enumerator(enumIdx).valueToKey(int(t));
}
const char *TabletWidget::pointerTypeToString(QPointingDevice::PointerType t)
{
static int enumIdx = QPointingDevice::staticMetaObject.indexOfEnumerator("PointerType");
return QPointingDevice::staticMetaObject.enumerator(enumIdx).valueToKey(int(t));
}
QString TabletWidget::pointerCapabilitiesToString(QPointingDevice::Capabilities c)
{
static int enumIdx = QPointingDevice::staticMetaObject.indexOfEnumerator("Capabilities");
return QString::fromLatin1(QPointingDevice::staticMetaObject.enumerator(enumIdx).valueToKeys(c));
}
const char *TabletWidget::buttonToString(Qt::MouseButton b)
{
static int enumIdx = QObject::staticQtMetaObject.indexOfEnumerator("MouseButtons");
return QObject::staticQtMetaObject.enumerator(enumIdx).valueToKey(b);
static int enumIdx = QObject::staticMetaObject.indexOfEnumerator("MouseButtons");
return QObject::staticMetaObject.enumerator(enumIdx).valueToKey(b);
}
QString TabletWidget::buttonsToString(Qt::MouseButtons bs)

View File

@ -31,6 +31,7 @@
#include <QWidget>
#include <QTabletEvent>
#include <QPointingDevice>
#include <QShortcut>
// a widget showing the information of the last tablet event
@ -42,12 +43,18 @@ protected:
bool eventFilter(QObject *obj, QEvent *ev);
void tabletEvent(QTabletEvent *event);
void paintEvent(QPaintEvent *event);
const char *deviceTypeToString(QInputDevice::DeviceType t);
const char *pointerTypeToString(QPointingDevice::PointerType t);
QString pointerCapabilitiesToString(QPointingDevice::Capabilities c);
const char *buttonToString(Qt::MouseButton b);
QString buttonsToString(Qt::MouseButtons bs);
QString modifiersToString(Qt::KeyboardModifiers m);
private:
void resetAttributes() {
mType = mDev = mPointerType = mXT = mYT = mZ = 0;
mDev = QInputDevice::DeviceType::Unknown;
mPointerType = QPointingDevice::PointerType::Unknown;
mCaps = {};
mType = mXT = mYT = mZ = 0;
mPress = mTangential = mRot = 0.0;
mPos = mGPos = QPoint();
mHiResGlobalPos = QPointF();
@ -56,7 +63,10 @@ private:
int mType;
QPoint mPos, mGPos;
QPointF mHiResGlobalPos;
int mDev, mPointerType, mXT, mYT, mZ;
QInputDevice::DeviceType mDev;
QPointingDevice::PointerType mPointerType;
QPointingDevice::Capabilities mCaps;
int mXT, mYT, mZ;
Qt::MouseButton mButton;
Qt::MouseButtons mButtons;
Qt::KeyboardModifiers mModifiers;

View File

@ -48,14 +48,14 @@ enum TabletPointType {
struct TabletPoint
{
TabletPoint(const QPointF &p = QPointF(), TabletPointType t = TabletMove,
Qt::MouseButton b = Qt::LeftButton, QTabletEvent::PointerType pt = QTabletEvent::UnknownPointer, qreal prs = 0, qreal rotation = 0) :
TabletPoint(const QPointF &p = QPointF(), TabletPointType t = TabletMove, Qt::MouseButton b = Qt::LeftButton,
QPointingDevice::PointerType pt = QPointingDevice::PointerType::Unknown, qreal prs = 0, qreal rotation = 0) :
pos(p), type(t), button(b), ptype(pt), pressure(prs), angle(rotation) {}
QPointF pos;
TabletPointType type;
Qt::MouseButton button;
QTabletEvent::PointerType ptype;
QPointingDevice::PointerType ptype;
qreal pressure;
qreal angle;
};
@ -167,7 +167,7 @@ void EventReportWidget::paintEvent(QPaintEvent *)
break;
case TabletMove:
if (t.pressure > 0.0) {
p.setPen(t.ptype == QTabletEvent::Eraser ? Qt::red : Qt::black);
p.setPen(t.ptype == QPointingDevice::PointerType::Eraser ? Qt::red : Qt::black);
if (t.angle != 0.0) {
p.save();
p.translate(t.pos);
@ -205,7 +205,7 @@ void EventReportWidget::tabletEvent(QTabletEvent *event)
{
QWidget::tabletEvent(event);
bool isMove = false;
m_tabletPos = event->posF();
m_tabletPos = event->position();
switch (event->type()) {
case QEvent::TabletMove:
m_points.push_back(TabletPoint(m_tabletPos, TabletMove, m_lastButton, event->pointerType(), event->pressure(), event->rotation()));
@ -229,7 +229,7 @@ void EventReportWidget::tabletEvent(QTabletEvent *event)
if (!(isMove && m_lastIsTabletMove)) {
QDebug d = qDebug();
d << event << " global position = " << event->globalPos()
d << event << " global position = " << event->globalPosition()
<< " cursor at " << QCursor::pos();
if (event->button() != Qt::NoButton)
d << " changed button " << event->button();
@ -245,7 +245,7 @@ bool EventReportWidget::event(QEvent *event)
event->accept();
m_touchPoints.clear();
for (const QTouchEvent::TouchPoint &p : static_cast<const QTouchEvent *>(event)->touchPoints())
m_touchPoints.append(p.pos());
m_touchPoints.append(p.position());
update();
break;
case QEvent::TouchEnd:

View File

@ -536,7 +536,7 @@ void MainWindow::dumpTouchDevices()
{
QString message;
QDebug debug(&message);
const QList<const QTouchDevice *> devices = QTouchDevice::devices();
const QList<const QPointingDevice *> devices = QPointingDevice::devices();
debug << devices.size() << "Device(s):\n";
for (int i = 0; i < devices.size(); ++i)
debug << "Device #" << i << devices.at(i) << '\n';

View File

@ -106,26 +106,26 @@ int main(int argc, char **argv)
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(new QLabel("The blue ellipses should indicate touch point contact patches"));
qDebug() << "Touch devices:";
for (const QTouchDevice *device : QTouchDevice::devices()) {
for (const QPointingDevice *device : QPointingDevice::devices()) {
QString result;
QTextStream str(&result);
str << (device->type() == QTouchDevice::TouchScreen ? "TouchScreen" : "TouchPad")
str << (device->type() == QInputDevice::DeviceType::TouchScreen ? "TouchScreen" : "TouchPad")
<< " \"" << device->name() << "\", max " << device->maximumTouchPoints()
<< " touch points, capabilities:";
const QTouchDevice::Capabilities capabilities = device->capabilities();
if (capabilities & QTouchDevice::Position)
const QPointingDevice::Capabilities capabilities = device->capabilities();
if (capabilities & QPointingDevice::Capability::Position)
str << " Position";
if (capabilities & QTouchDevice::Area)
if (capabilities & QPointingDevice::Capability::Area)
str << " Area";
if (capabilities & QTouchDevice::Pressure)
if (capabilities & QPointingDevice::Capability::Pressure)
str << " Pressure";
if (capabilities & QTouchDevice::Velocity)
if (capabilities & QPointingDevice::Velocity)
str << " Velocity";
if (capabilities & QTouchDevice::RawPositions)
if (capabilities & QPointingDevice::RawPositions)
str << " RawPositions";
if (capabilities & QTouchDevice::NormalizedPosition)
if (capabilities & QPointingDevice::Capability::NormalizedPosition)
str << " NormalizedPosition";
if (capabilities & QTouchDevice::MouseEmulation)
if (capabilities & QInputDevice::DeviceType::MouseEmulation)
str << " MouseEmulation";
vbox->addWidget(new QLabel(result));
qDebug() << " " << result;