xcb: added env variables to show input devices and events
export QT_XCB_DEBUG_XINPUT_DEVICES=anything to show detected input devices at startup export QT_XCB_DEBUG_XINPUT=anything to log mouse, touch and tablet events Change-Id: Id14844b68ad376740f82a36aab2c59c84d2017ab Task-number: QTBUG-35583 Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
This commit is contained in:
parent
5ee3d1e456
commit
ecf11d62fc
@ -262,6 +262,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
|||||||
, has_input_shape(false)
|
, has_input_shape(false)
|
||||||
, has_touch_without_mouse_emulation(false)
|
, has_touch_without_mouse_emulation(false)
|
||||||
, has_xkb(false)
|
, has_xkb(false)
|
||||||
|
, debug_xinput_devices(false)
|
||||||
|
, debug_xinput(false)
|
||||||
, m_buttons(0)
|
, m_buttons(0)
|
||||||
, m_focusWindow(0)
|
, m_focusWindow(0)
|
||||||
, m_systemTrayTracker(0)
|
, m_systemTrayTracker(0)
|
||||||
@ -749,6 +751,8 @@ void QXcbConnection::handleButtonPress(xcb_generic_event_t *ev)
|
|||||||
// the rest we need to manage ourselves
|
// the rest we need to manage ourselves
|
||||||
m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state);
|
m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state);
|
||||||
m_buttons |= translateMouseButton(event->detail);
|
m_buttons |= translateMouseButton(event->detail);
|
||||||
|
if (Q_UNLIKELY(debug_xinput))
|
||||||
|
qDebug("xcb: pressed mouse button %d, button state %X", event->detail, static_cast<unsigned int>(m_buttons));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev)
|
void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev)
|
||||||
@ -759,6 +763,8 @@ void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev)
|
|||||||
// the rest we need to manage ourselves
|
// the rest we need to manage ourselves
|
||||||
m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state);
|
m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state);
|
||||||
m_buttons &= ~translateMouseButton(event->detail);
|
m_buttons &= ~translateMouseButton(event->detail);
|
||||||
|
if (Q_UNLIKELY(debug_xinput))
|
||||||
|
qDebug("xcb: released mouse button %d, button state %X", event->detail, static_cast<unsigned int>(m_buttons));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_XKB
|
#ifndef QT_NO_XKB
|
||||||
@ -814,6 +820,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
|||||||
handleButtonRelease(event);
|
handleButtonRelease(event);
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
|
||||||
case XCB_MOTION_NOTIFY:
|
case XCB_MOTION_NOTIFY:
|
||||||
|
if (Q_UNLIKELY(debug_xinput)) {
|
||||||
|
xcb_motion_notify_event_t *mev = (xcb_motion_notify_event_t *)event;
|
||||||
|
qDebug("xcb: moved mouse to %4d, %4d; button state %X", mev->event_x, mev->event_y, static_cast<unsigned int>(m_buttons));
|
||||||
|
}
|
||||||
#ifdef QT_NO_XKB
|
#ifdef QT_NO_XKB
|
||||||
m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state);
|
m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state);
|
||||||
#endif
|
#endif
|
||||||
|
@ -574,6 +574,8 @@ private:
|
|||||||
bool has_input_shape;
|
bool has_input_shape;
|
||||||
bool has_touch_without_mouse_emulation;
|
bool has_touch_without_mouse_emulation;
|
||||||
bool has_xkb;
|
bool has_xkb;
|
||||||
|
bool debug_xinput_devices;
|
||||||
|
bool debug_xinput;
|
||||||
|
|
||||||
Qt::MouseButtons m_buttons;
|
Qt::MouseButtons m_buttons;
|
||||||
|
|
||||||
|
@ -44,10 +44,7 @@
|
|||||||
#include "qxcbwindow.h"
|
#include "qxcbwindow.h"
|
||||||
#include "qtouchdevice.h"
|
#include "qtouchdevice.h"
|
||||||
#include <qpa/qwindowsysteminterface.h>
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
//#define XI2_DEBUG
|
|
||||||
#ifdef XI2_DEBUG
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XCB_USE_XINPUT2
|
#ifdef XCB_USE_XINPUT2
|
||||||
|
|
||||||
@ -73,6 +70,8 @@ struct XInput2DeviceData {
|
|||||||
|
|
||||||
void QXcbConnection::initializeXInput2()
|
void QXcbConnection::initializeXInput2()
|
||||||
{
|
{
|
||||||
|
debug_xinput = qEnvironmentVariableIsSet("QT_XCB_DEBUG_XINPUT");
|
||||||
|
debug_xinput_devices = qEnvironmentVariableIsSet("QT_XCB_DEBUG_XINPUT_DEVICES");
|
||||||
#ifndef QT_NO_TABLETEVENT
|
#ifndef QT_NO_TABLETEVENT
|
||||||
m_tabletData.clear();
|
m_tabletData.clear();
|
||||||
#endif
|
#endif
|
||||||
@ -87,8 +86,11 @@ void QXcbConnection::initializeXInput2()
|
|||||||
m_xi2Enabled = true;
|
m_xi2Enabled = true;
|
||||||
}
|
}
|
||||||
if (m_xi2Enabled) {
|
if (m_xi2Enabled) {
|
||||||
#ifdef XI2_DEBUG
|
if (Q_UNLIKELY(debug_xinput_devices))
|
||||||
qDebug("XInput version %d.%d is supported", xiMajor, m_xi2Minor);
|
#ifdef XCB_USE_XINPUT22
|
||||||
|
qDebug("XInput version %d.%d is available and Qt supports 2.2 or greater", xiMajor, m_xi2Minor);
|
||||||
|
#else
|
||||||
|
qDebug("XInput version %d.%d is available and Qt supports 2.0", xiMajor, m_xi2Minor);
|
||||||
#endif
|
#endif
|
||||||
int deviceCount = 0;
|
int deviceCount = 0;
|
||||||
XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
|
XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
|
||||||
@ -96,9 +98,8 @@ void QXcbConnection::initializeXInput2()
|
|||||||
// Only non-master pointing devices are relevant here.
|
// Only non-master pointing devices are relevant here.
|
||||||
if (devices[i].use != XISlavePointer)
|
if (devices[i].use != XISlavePointer)
|
||||||
continue;
|
continue;
|
||||||
#ifdef XI2_DEBUG
|
if (Q_UNLIKELY(debug_xinput_devices))
|
||||||
qDebug() << "input device "<< devices[i].name;
|
qDebug() << "input device "<< devices[i].name;
|
||||||
#endif
|
|
||||||
#ifndef QT_NO_TABLETEVENT
|
#ifndef QT_NO_TABLETEVENT
|
||||||
TabletData tabletData;
|
TabletData tabletData;
|
||||||
#endif
|
#endif
|
||||||
@ -107,9 +108,8 @@ void QXcbConnection::initializeXInput2()
|
|||||||
case XIValuatorClass: {
|
case XIValuatorClass: {
|
||||||
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(devices[i].classes[c]);
|
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(devices[i].classes[c]);
|
||||||
const int valuatorAtom = qatom(vci->label);
|
const int valuatorAtom = qatom(vci->label);
|
||||||
#ifdef XI2_DEBUG
|
if (Q_UNLIKELY(debug_xinput_devices))
|
||||||
qDebug() << " has valuator" << atomName(vci->label) << "recognized?" << (valuatorAtom < QXcbAtom::NAtoms);
|
qDebug() << " has valuator" << atomName(vci->label) << "recognized?" << (valuatorAtom < QXcbAtom::NAtoms);
|
||||||
#endif
|
|
||||||
#ifndef QT_NO_TABLETEVENT
|
#ifndef QT_NO_TABLETEVENT
|
||||||
if (valuatorAtom < QXcbAtom::NAtoms) {
|
if (valuatorAtom < QXcbAtom::NAtoms) {
|
||||||
TabletData::ValuatorClassInfo info;
|
TabletData::ValuatorClassInfo info;
|
||||||
@ -136,26 +136,23 @@ void QXcbConnection::initializeXInput2()
|
|||||||
tabletData.pointerType = QTabletEvent::Eraser;
|
tabletData.pointerType = QTabletEvent::Eraser;
|
||||||
m_tabletData.append(tabletData);
|
m_tabletData.append(tabletData);
|
||||||
isTablet = true;
|
isTablet = true;
|
||||||
#ifdef XI2_DEBUG
|
if (Q_UNLIKELY(debug_xinput_devices))
|
||||||
qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
|
qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif // QT_NO_TABLETEVENT
|
#endif // QT_NO_TABLETEVENT
|
||||||
if (!isTablet) {
|
if (!isTablet) {
|
||||||
XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
|
XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
|
||||||
#ifdef XI2_DEBUG
|
if (Q_UNLIKELY(debug_xinput_devices)) {
|
||||||
if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchScreen)
|
if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchScreen)
|
||||||
qDebug(" it's a touchscreen with type %d capabilities 0x%X max touch points %d",
|
qDebug(" it's a touchscreen with type %d capabilities 0x%X max touch points %d",
|
||||||
dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
|
dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
|
||||||
dev->qtTouchDevice->maximumTouchPoints());
|
dev->qtTouchDevice->maximumTouchPoints());
|
||||||
else if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
|
else if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
|
||||||
qDebug(" it's a touchpad with type %d capabilities 0x%X max touch points %d size %f x %f",
|
qDebug(" 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->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
|
||||||
dev->qtTouchDevice->maximumTouchPoints(),
|
dev->qtTouchDevice->maximumTouchPoints(),
|
||||||
dev->size.width(), dev->size.height());
|
dev->size.width(), dev->size.height());
|
||||||
#else
|
}
|
||||||
Q_UNUSED(dev);
|
|
||||||
#endif // XI2_DEBUG
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XIFreeDeviceInfo(devices);
|
XIFreeDeviceInfo(devices);
|
||||||
@ -236,9 +233,8 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
|
|||||||
case XITouchClass: {
|
case XITouchClass: {
|
||||||
XITouchClassInfo *tci = reinterpret_cast<XITouchClassInfo *>(classinfo);
|
XITouchClassInfo *tci = reinterpret_cast<XITouchClassInfo *>(classinfo);
|
||||||
maxTouchPoints = tci->num_touches;
|
maxTouchPoints = tci->num_touches;
|
||||||
#ifdef XI2_DEBUG
|
if (Q_UNLIKELY(debug_xinput_devices))
|
||||||
qDebug(" has touch class with mode %d", tci->mode);
|
qDebug(" has touch class with mode %d", tci->mode);
|
||||||
#endif
|
|
||||||
switch (tci->mode) {
|
switch (tci->mode) {
|
||||||
case XIModeRelative:
|
case XIModeRelative:
|
||||||
type = QTouchDevice::TouchPad;
|
type = QTouchDevice::TouchPad;
|
||||||
@ -324,13 +320,11 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
|||||||
#ifdef XCB_USE_XINPUT22
|
#ifdef XCB_USE_XINPUT22
|
||||||
if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) {
|
if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) {
|
||||||
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
|
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
|
||||||
#ifdef XI2_DEBUG
|
if (Q_UNLIKELY(debug_xinput))
|
||||||
qDebug("XI2 event type %d seq %d detail %d pos 0x%X,0x%X %f,%f root pos %f,%f",
|
qDebug("XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f",
|
||||||
event->event_type, xiEvent->sequenceNumber, xiDeviceEvent->detail,
|
event->event_type, xiEvent->sequenceNumber, xiDeviceEvent->detail,
|
||||||
xiDeviceEvent->event_x, xiDeviceEvent->event_y,
|
fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y),
|
||||||
fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y),
|
fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y) );
|
||||||
fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
|
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
|
||||||
XInput2DeviceData *dev = deviceForId(xiEvent->deviceid);
|
XInput2DeviceData *dev = deviceForId(xiEvent->deviceid);
|
||||||
@ -356,10 +350,9 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
|||||||
double value;
|
double value;
|
||||||
if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value))
|
if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value))
|
||||||
continue;
|
continue;
|
||||||
#ifdef XI2_DEBUG
|
if (Q_UNLIKELY(debug_xinput))
|
||||||
qDebug(" valuator %20s value %lf from range %lf -> %lf",
|
qDebug(" valuator %20s value %lf from range %lf -> %lf",
|
||||||
atomName(vci->label).constData(), value, vci->min, vci->max );
|
atomName(vci->label).constData(), value, vci->min, vci->max );
|
||||||
#endif
|
|
||||||
if (vci->label == atom(QXcbAtom::RelX)) {
|
if (vci->label == atom(QXcbAtom::RelX)) {
|
||||||
nx = valuatorNormalized(value, vci);
|
nx = valuatorNormalized(value, vci);
|
||||||
} else if (vci->label == atom(QXcbAtom::RelY)) {
|
} else if (vci->label == atom(QXcbAtom::RelY)) {
|
||||||
@ -435,10 +428,9 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
|||||||
touchPoint.area = QRectF(x - w/2, y - h/2, w, h);
|
touchPoint.area = QRectF(x - w/2, y - h/2, w, h);
|
||||||
touchPoint.normalPosition = QPointF(nx, ny);
|
touchPoint.normalPosition = QPointF(nx, ny);
|
||||||
|
|
||||||
#ifdef XI2_DEBUG
|
if (Q_UNLIKELY(debug_xinput))
|
||||||
qDebug() << " tp " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition <<
|
qDebug() << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition <<
|
||||||
" area " << touchPoint.area << " pressure " << touchPoint.pressure;
|
" area " << touchPoint.area << " pressure " << touchPoint.pressure;
|
||||||
#endif
|
|
||||||
QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiEvent->time, dev->qtTouchDevice, m_touchPoints.values());
|
QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiEvent->time, dev->qtTouchDevice, m_touchPoints.values());
|
||||||
if (touchPoint.state == Qt::TouchPointReleased)
|
if (touchPoint.state == Qt::TouchPointReleased)
|
||||||
// If a touchpoint was released, we can forget it, because the ID won't be reused.
|
// If a touchpoint was released, we can forget it, because the ID won't be reused.
|
||||||
@ -560,6 +552,13 @@ void QXcbConnection::xi2ReportTabletEvent(const TabletData &tabletData, void *ev
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Q_UNLIKELY(debug_xinput))
|
||||||
|
qDebug("XI2 tablet event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f pressure %4.2lf tilt %d, %d rotation %6.2lf",
|
||||||
|
ev->type, ev->sequenceNumber, ev->detail,
|
||||||
|
fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y),
|
||||||
|
fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y),
|
||||||
|
pressure, xTilt, yTilt, rotation);
|
||||||
|
|
||||||
QWindowSystemInterface::handleTabletEvent(window, tabletData.down, local, global,
|
QWindowSystemInterface::handleTabletEvent(window, tabletData.down, local, global,
|
||||||
QTabletEvent::Stylus, tabletData.pointerType,
|
QTabletEvent::Stylus, tabletData.pointerType,
|
||||||
pressure, xTilt, yTilt, 0,
|
pressure, xTilt, yTilt, 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user