summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-05-01 13:05:51 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-05-01 13:08:42 +0200
commitccc6efb6e91756451ffd50d51f7f3ae05bc6df0b (patch)
treea65fb418e4e0ce27e6cd73f65500e7cc00bbf106 /src/plugins/platforms/xcb
parentd52b00e1d3cc60c81b54a89d6da488dc4bbce384 (diff)
parent079f2bf5d8a4221b821ec8062affe2efaa9668a0 (diff)
Merge remote-tracking branch 'origin/release' into stable
This merge adds the opengl rename. Change-Id: I84ea0b6abee9780ebb2cf3f64ab9e3fdf2acab3e
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp13
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h10
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp46
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp20
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro1
5 files changed, 77 insertions, 13 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index f5f6c712c5..e3b81c2b40 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -1791,6 +1791,19 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub
return true;
}
+bool QXcbConnection::xi2GetButtonState(void *event, int buttonNum)
+{
+ xXIDeviceEvent *xideviceevent = static_cast<xXIDeviceEvent *>(event);
+ unsigned char *buttonsMaskAddr = (unsigned char*)&xideviceevent[1];
+
+ for (int i = 0; i < (xideviceevent->buttons_len * 4); i++) {
+ if (buttonNum < 8)
+ return (buttonsMaskAddr[i] & (1 << buttonNum));
+ buttonNum -= 8;
+ }
+ return false;
+}
+
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
// - "pad0" became "extension"
// - "pad1" and "pad" became "pad0"
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 13a0280baf..1933b89a19 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -402,6 +402,12 @@ public:
#elif defined(XCB_USE_XINPUT2)
void xi2Select(xcb_window_t window);
#endif
+#ifdef XCB_USE_XINPUT21
+ bool isUsingXInput21() { return m_xi2Enabled && m_xi2Minor >= 1; }
+#else
+ bool isUsingXInput21() { return false; }
+#endif
+
void sync();
void flush() { xcb_flush(m_connection); }
@@ -511,11 +517,12 @@ private:
QVector<TabletData> m_tabletData;
#endif
struct ScrollingDevice {
- ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0) { }
+ ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { }
int deviceId;
int verticalIndex, horizontalIndex;
double verticalIncrement, horizontalIncrement;
Qt::Orientations orientations;
+ Qt::Orientations legacyOrientations;
QPointF lastScrollPosition;
};
void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
@@ -525,6 +532,7 @@ private:
#if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value);
static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode);
+ static bool xi2GetButtonState(void *event, int buttonNum);
#endif
xcb_connection_t *m_connection;
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index d7b3c75aee..831ccba6f6 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -134,7 +134,6 @@ void QXcbConnection::initializeXInput2()
#ifdef XCB_USE_XINPUT21
case XIScrollClass: {
XIScrollClassInfo *sci = reinterpret_cast<XIScrollClassInfo *>(devices[i].classes[c]);
- scrollingDevice.deviceId = devices[i].deviceid;
if (sci->scroll_type == XIScrollTypeVertical) {
scrollingDevice.orientations |= Qt::Vertical;
scrollingDevice.verticalIndex = sci->number;
@@ -147,6 +146,20 @@ void QXcbConnection::initializeXInput2()
}
break;
}
+ case XIButtonClass: {
+ XIButtonClassInfo *bci = reinterpret_cast<XIButtonClassInfo *>(devices[i].classes[c]);
+ for (int i=0; i < bci->num_buttons; ++i) {
+ const int buttonAtom = qatom(bci->labels[i]);
+ if (buttonAtom == QXcbAtom::ButtonWheelUp
+ || buttonAtom == QXcbAtom::ButtonWheelDown) {
+ scrollingDevice.legacyOrientations |= Qt::Vertical;
+ } else if (buttonAtom == QXcbAtom::ButtonHorizWheelLeft
+ || buttonAtom == QXcbAtom::ButtonHorizWheelRight) {
+ scrollingDevice.legacyOrientations |= Qt::Horizontal;
+ }
+ }
+ break;
+ }
#endif
default:
break;
@@ -170,7 +183,10 @@ void QXcbConnection::initializeXInput2()
#endif // QT_NO_TABLETEVENT
#ifdef XCB_USE_XINPUT21
- if (scrollingDevice.orientations) {
+ if (scrollingDevice.orientations || scrollingDevice.legacyOrientations) {
+ scrollingDevice.deviceId = devices[i].deviceid;
+ // Only use legacy wheel button events when we don't have real scroll valuators.
+ scrollingDevice.legacyOrientations &= ~scrollingDevice.orientations;
m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice);
if (Q_UNLIKELY(debug_xinput_devices))
qDebug() << " it's a scrolling device";
@@ -256,6 +272,7 @@ void QXcbConnection::xi2Select(xcb_window_t window)
if (!m_scrollingDevices.isEmpty()) {
QVector<XIEventMask> xiEventMask(m_scrollingDevices.size());
bitMask = XI_MotionMask;
+ bitMask |= XI_ButtonReleaseMask;
int i=0;
Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) {
xiEventMask[i].deviceid = scrollingDevice.deviceId;
@@ -595,6 +612,31 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, rawDelta, angleDelta, modifiers);
}
}
+ } else if (xiEvent->evtype == XI_ButtonRelease) {
+ xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
+ if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
+ QPoint angleDelta;
+ if (scrollingDevice.legacyOrientations & Qt::Vertical) {
+ if (xi2GetButtonState(xiDeviceEvent, 4))
+ angleDelta.setY(120);
+ else if (xi2GetButtonState(xiDeviceEvent, 5))
+ angleDelta.setY(-120);
+ }
+ if (scrollingDevice.legacyOrientations & Qt::Horizontal) {
+ if (xi2GetButtonState(xiDeviceEvent, 6))
+ angleDelta.setX(120);
+ if (xi2GetButtonState(xiDeviceEvent, 7))
+ angleDelta.setX(-120);
+ }
+ if (!angleDelta.isNull()) {
+ QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y));
+ QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y));
+ Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods);
+ if (modifiers & Qt::AltModifier)
+ std::swap(angleDelta.rx(), angleDelta.ry());
+ QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, QPoint(), angleDelta, modifiers);
+ }
+ }
}
#else
Q_UNUSED(event);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index fb9c03b66d..3645b6469a 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1771,16 +1771,16 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
if (isWheel) {
-#ifndef XCB_USE_XINPUT21
- // Logic borrowed from qapplication_x11.cpp
- int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1);
- bool hor = (((event->detail == 4 || event->detail == 5)
- && (modifiers & Qt::AltModifier))
- || (event->detail == 6 || event->detail == 7));
-
- QWindowSystemInterface::handleWheelEvent(window(), event->time,
- local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers);
-#endif
+ if (!connection()->isUsingXInput21()) {
+ // Logic borrowed from qapplication_x11.cpp
+ int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1);
+ bool hor = (((event->detail == 4 || event->detail == 5)
+ && (modifiers & Qt::AltModifier))
+ || (event->detail == 6 || event->detail == 7));
+
+ QWindowSystemInterface::handleWheelEvent(window(), event->time,
+ local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers);
+ }
return;
}
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index 9e4e997f55..a52aaa4a2e 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -2,6 +2,7 @@ TARGET = qxcb
PLUGIN_TYPE = platforms
PLUGIN_CLASS_NAME = QXcbIntegrationPlugin
+!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
load(qt_plugin)
QT += core-private gui-private platformsupport-private