summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPovilas Kanapickas <povilas@radix.lt>2021-09-28 20:17:00 +0300
committerShawn Rutledge <shawn.rutledge@qt.io>2021-10-16 12:52:29 +0200
commita875503d9e001a05eb3c0998f6c1292f0fefc4e1 (patch)
tree84f2ab2c21f45672257d04541de22ed125ca2d28
parent32edae5e268b968aff82f0713612eff2feffb4e1 (diff)
xcb: Use byte buffer for event masks
This prepares for use of masks larger than 32 bits which happens on XI 2.4. Additionally, since the XI protocol always sends the masks using little-endian, the XI protocol support on big-endian machines was currently broken. Change-Id: Id22131e075059cea783b5be0691a673a457c7364 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp53
1 files changed, 30 insertions, 23 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index c0bd2c6165..4c39c7ee3e 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -55,9 +55,15 @@ using qt_xcb_input_device_event_t = xcb_input_button_press_event_t;
struct qt_xcb_input_event_mask_t {
xcb_input_event_mask_t header;
- uint32_t mask;
+ alignas(4) uint8_t mask[4] = {};
};
+static inline void setXcbMask(uint8_t* mask, int bit)
+{
+ // note that XI protocol always uses little endian for masks over the wire
+ mask[bit >> 3] |= 1 << (bit & 7);
+}
+
void QXcbConnection::xi2SelectStateEvents()
{
// These state events do not depend on a specific X window, but are global
@@ -65,9 +71,9 @@ void QXcbConnection::xi2SelectStateEvents()
qt_xcb_input_event_mask_t xiEventMask;
xiEventMask.header.deviceid = XCB_INPUT_DEVICE_ALL;
xiEventMask.header.mask_len = 1;
- xiEventMask.mask = XCB_INPUT_XI_EVENT_MASK_HIERARCHY;
- xiEventMask.mask |= XCB_INPUT_XI_EVENT_MASK_DEVICE_CHANGED;
- xiEventMask.mask |= XCB_INPUT_XI_EVENT_MASK_PROPERTY;
+ setXcbMask(xiEventMask.mask, XCB_INPUT_HIERARCHY);
+ setXcbMask(xiEventMask.mask, XCB_INPUT_DEVICE_CHANGED);
+ setXcbMask(xiEventMask.mask, XCB_INPUT_PROPERTY);
xcb_input_xi_select_events(xcb_connection(), rootWindow(), 1, &xiEventMask.header);
}
@@ -76,23 +82,23 @@ void QXcbConnection::xi2SelectDeviceEvents(xcb_window_t window)
if (window == rootWindow())
return;
- uint32_t bitMask = XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS;
- bitMask |= XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE;
- bitMask |= XCB_INPUT_XI_EVENT_MASK_MOTION;
+ qt_xcb_input_event_mask_t mask;
+
+ setXcbMask(mask.mask, XCB_INPUT_BUTTON_PRESS);
+ setXcbMask(mask.mask, XCB_INPUT_BUTTON_RELEASE);
+ setXcbMask(mask.mask, XCB_INPUT_MOTION);
// There is a check for enter/leave events in plain xcb enter/leave event handler,
// core enter/leave events will be ignored in this case.
- bitMask |= XCB_INPUT_XI_EVENT_MASK_ENTER;
- bitMask |= XCB_INPUT_XI_EVENT_MASK_LEAVE;
+ setXcbMask(mask.mask, XCB_INPUT_ENTER);
+ setXcbMask(mask.mask, XCB_INPUT_LEAVE);
if (isAtLeastXI22()) {
- bitMask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN;
- bitMask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE;
- bitMask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_END;
+ setXcbMask(mask.mask, XCB_INPUT_TOUCH_BEGIN);
+ setXcbMask(mask.mask, XCB_INPUT_TOUCH_UPDATE);
+ setXcbMask(mask.mask, XCB_INPUT_TOUCH_END);
}
- qt_xcb_input_event_mask_t mask;
mask.header.deviceid = XCB_INPUT_DEVICE_ALL;
mask.header.mask_len = 1;
- mask.mask = bitMask;
xcb_void_cookie_t cookie =
xcb_input_xi_select_events_checked(xcb_connection(), window, 1, &mask.header);
xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie);
@@ -974,22 +980,23 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab)
bool ok = false;
if (grab) { // grab
- uint32_t mask = XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS
- | XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE
- | XCB_INPUT_XI_EVENT_MASK_MOTION
- | XCB_INPUT_XI_EVENT_MASK_ENTER
- | XCB_INPUT_XI_EVENT_MASK_LEAVE;
+ uint8_t mask[8] = {};
+ setXcbMask(mask, XCB_INPUT_BUTTON_PRESS);
+ setXcbMask(mask, XCB_INPUT_BUTTON_RELEASE);
+ setXcbMask(mask, XCB_INPUT_MOTION);
+ setXcbMask(mask, XCB_INPUT_ENTER);
+ setXcbMask(mask, XCB_INPUT_LEAVE);
if (isAtLeastXI22()) {
- mask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN;
- mask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE;
- mask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_END;
+ setXcbMask(mask, XCB_INPUT_TOUCH_BEGIN);
+ setXcbMask(mask, XCB_INPUT_TOUCH_UPDATE);
+ setXcbMask(mask, XCB_INPUT_TOUCH_END);
}
for (int id : qAsConst(m_xiMasterPointerIds)) {
xcb_generic_error_t *error = nullptr;
auto cookie = xcb_input_xi_grab_device(xcb_connection(), w, XCB_CURRENT_TIME, XCB_CURSOR_NONE, id,
XCB_INPUT_GRAB_MODE_22_ASYNC, XCB_INPUT_GRAB_MODE_22_ASYNC,
- false, 1, &mask);
+ false, 1, reinterpret_cast<uint32_t *>(mask));
auto *reply = xcb_input_xi_grab_device_reply(xcb_connection(), cookie, &error);
if (error) {
qCDebug(lcQpaXInput, "failed to grab events for device %d on window %x"