summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection_xi2.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp84
1 files changed, 41 insertions, 43 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 63a650a514..5b7f45fb6c 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -42,7 +42,7 @@
#include "qxcbscreen.h"
#include "qxcbwindow.h"
#include "qtouchdevice.h"
-#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qwindowsysteminterface_p.h>
#include <QDebug>
#include <cmath>
@@ -119,7 +119,7 @@ void QXcbConnection::xi2SetupDevices()
// Only non-master pointing devices are relevant here.
if (devices[i].use != XISlavePointer)
continue;
- qCDebug(lcQpaXInputDevices) << "input device "<< devices[i].name;
+ qCDebug(lcQpaXInputDevices) << "input device " << devices[i].name << "ID" << devices[i].deviceid;
#ifndef QT_NO_TABLETEVENT
TabletData tabletData;
#endif
@@ -274,7 +274,7 @@ void QXcbConnection::xi2SetupDevices()
void QXcbConnection::finalizeXInput2()
{
- foreach (XInput2TouchDeviceData *dev, m_touchDevices) {
+ for (XInput2TouchDeviceData *dev : qAsConst(m_touchDevices)) {
if (dev->xiDeviceInfo)
XIFreeDeviceInfo(dev->xiDeviceInfo);
delete dev;
@@ -313,12 +313,13 @@ void QXcbConnection::xi2Select(xcb_window_t window)
mask.mask_len = sizeof(bitMask);
mask.mask = xiBitMask;
// When xi2MouseEvents() is true (the default), pointer emulation for touch and tablet
- // events will get disabled. This is preferable for touch, as Qt Quick handles touch events
- // directly while for others QtGui synthesizes mouse events, not so much for tablets. For
- // the latter we will synthesize the events ourselves.
+ // events will get disabled. This is preferable, as Qt Quick handles touch events
+ // directly, while for other applications QtGui synthesizes mouse events.
mask.deviceid = XIAllMasterDevices;
Status result = XISelectEvents(xDisplay, window, &mask, 1);
- if (result != Success)
+ if (result == Success)
+ QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
+ else
qCDebug(lcQpaXInput, "XInput 2.2: failed to select pointer/touch events, window %x, result %d", window, result);
}
@@ -358,7 +359,7 @@ void QXcbConnection::xi2Select(xcb_window_t window)
scrollBitMask = XI_MotionMask;
scrollBitMask |= XI_ButtonReleaseMask;
int i=0;
- Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) {
+ for (const ScrollingDevice& scrollingDevice : qAsConst(m_scrollingDevices)) {
if (tabletDevices.contains(scrollingDevice.deviceId))
continue; // All necessary events are already captured.
xiEventMask[i].deviceid = scrollingDevice.deviceId;
@@ -536,12 +537,9 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
#ifndef QT_NO_TABLETEVENT
if (!xiEnterEvent) {
- for (int i = 0; i < m_tabletData.count(); ++i) {
- if (m_tabletData.at(i).deviceId == sourceDeviceId) {
- if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener))
- return;
- }
- }
+ QXcbConnection::TabletData *tablet = tabletDataForDevice(sourceDeviceId);
+ if (tablet && xi2HandleTabletEvent(xiEvent, tablet))
+ return;
}
#endif // QT_NO_TABLETEVENT
@@ -832,9 +830,8 @@ void QXcbConnection::xi2HandleHierachyEvent(void *event)
return;
xi2SetupDevices();
// Reselect events for all event-listening windows.
- Q_FOREACH (xcb_window_t window, m_mapper.keys()) {
- xi2Select(window);
- }
+ for (auto it = m_mapper.cbegin(), end = m_mapper.cend(); it != end; ++it)
+ xi2Select(it.key());
}
void QXcbConnection::xi2HandleDeviceChangedEvent(void *event)
@@ -1042,36 +1039,36 @@ static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) {
}
#ifndef QT_NO_TABLETEVENT
-bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, QXcbWindowEventListener *eventListener)
+bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletData)
{
bool handled = true;
Display *xDisplay = static_cast<Display *>(m_xlib_display);
- xXIGenericDeviceEvent *xiEvent = static_cast<xXIGenericDeviceEvent *>(event);
- xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(xiEvent);
+ const xXIGenericDeviceEvent *xiEvent = static_cast<const xXIGenericDeviceEvent *>(event);
+ const xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<const xXIDeviceEvent *>(xiEvent);
switch (xiEvent->evtype) {
case XI_ButtonPress: {
Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail);
tabletData->buttons |= b;
- xi2ReportTabletEvent(*tabletData, xiEvent);
+ xi2ReportTabletEvent(xiEvent, tabletData);
break;
}
case XI_ButtonRelease: {
Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail);
tabletData->buttons ^= b;
- xi2ReportTabletEvent(*tabletData, xiEvent);
+ xi2ReportTabletEvent(xiEvent, tabletData);
break;
}
case XI_Motion:
// Report TabletMove only when the stylus is touching the tablet or any button is pressed.
// TODO: report proximity (hover) motion (no suitable Qt event exists yet).
if (tabletData->buttons != Qt::NoButton)
- xi2ReportTabletEvent(*tabletData, xiEvent);
+ xi2ReportTabletEvent(xiEvent, tabletData);
break;
case XI_PropertyEvent: {
// This is the wacom driver's way of reporting tool proximity.
// The evdev driver doesn't do it this way.
- xXIPropertyEvent *ev = reinterpret_cast<xXIPropertyEvent *>(event);
+ const xXIPropertyEvent *ev = reinterpret_cast<const xXIPropertyEvent *>(event);
if (ev->what == XIPropertyModified) {
if (ev->property == atom(QXcbAtom::WacomSerialIDs)) {
enum WacomSerialIndex {
@@ -1132,21 +1129,12 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
break;
}
-#ifdef XCB_USE_XINPUT22
- // Synthesize mouse events since otherwise there are no mouse events from
- // the pen on the XI 2.2+ path.
- if (xi2MouseEvents() && eventListener)
- eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event), Qt::MouseEventSynthesizedByQt);
-#else
- Q_UNUSED(eventListener);
-#endif
-
return handled;
}
-void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event)
+void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletData)
{
- xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event);
+ const xXIDeviceEvent *ev = reinterpret_cast<const xXIDeviceEvent *>(event);
QXcbWindow *xcbWindow = platformWindowFromId(ev->event);
if (!xcbWindow)
return;
@@ -1157,8 +1145,8 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event)
double pressure = 0, rotation = 0, tangentialPressure = 0;
int xTilt = 0, yTilt = 0;
- for (QHash<int, TabletData::ValuatorClassInfo>::iterator it = tabletData.valuatorInfo.begin(),
- ite = tabletData.valuatorInfo.end(); it != ite; ++it) {
+ for (QHash<int, TabletData::ValuatorClassInfo>::iterator it = tabletData->valuatorInfo.begin(),
+ ite = tabletData->valuatorInfo.end(); it != ite; ++it) {
int valuator = it.key();
TabletData::ValuatorClassInfo &classInfo(it.value());
xi2GetValuatorValueIfSet(event, classInfo.number, &classInfo.curVal);
@@ -1174,7 +1162,7 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event)
yTilt = classInfo.curVal;
break;
case QXcbAtom::AbsWheel:
- switch (tabletData.tool) {
+ switch (tabletData->tool) {
case QTabletEvent::Airbrush:
tangentialPressure = normalizedValue * 2.0 - 1.0; // Convert 0..1 range to -1..+1 range
break;
@@ -1193,17 +1181,27 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event)
if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled()))
qCDebug(lcQpaXInput, "XI2 event on tablet %d with tool %d type %d 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",
- tabletData.deviceId, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, ev->time,
+ tabletData->deviceId, tabletData->tool, ev->evtype, ev->sequenceNumber, ev->detail, ev->time,
fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y),
fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y),
- (int)tabletData.buttons, pressure, xTilt, yTilt, rotation);
+ (int)tabletData->buttons, pressure, xTilt, yTilt, rotation);
QWindowSystemInterface::handleTabletEvent(window, ev->time, local, global,
- tabletData.tool, tabletData.pointerType,
- tabletData.buttons, pressure,
+ tabletData->tool, tabletData->pointerType,
+ tabletData->buttons, pressure,
xTilt, yTilt, tangentialPressure,
- rotation, 0, tabletData.serialId);
+ rotation, 0, tabletData->serialId);
}
+
+QXcbConnection::TabletData *QXcbConnection::tabletDataForDevice(int id)
+{
+ for (int i = 0; i < m_tabletData.count(); ++i) {
+ if (m_tabletData.at(i).deviceId == id)
+ return &m_tabletData[i];
+ }
+ return Q_NULLPTR;
+}
+
#endif // QT_NO_TABLETEVENT
#endif // XCB_USE_XINPUT2