summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp38
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp77
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h20
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp132
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp96
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp7
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro2
11 files changed, 269 insertions, 116 deletions
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index e504d93fba..3f1c53b122 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -167,6 +167,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
, m_shareContext(0)
, m_format(format)
, m_isPBufferCurrent(false)
+ , m_swapInterval(-1)
{
if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType)
m_format.setRenderableType(QSurfaceFormat::OpenGL);
@@ -326,19 +327,50 @@ QGLXContext::~QGLXContext()
bool QGLXContext::makeCurrent(QPlatformSurface *surface)
{
+ bool success = false;
Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ Display *dpy = DISPLAY_FROM_XCB(m_screen);
+ GLXDrawable glxDrawable = 0;
QSurface::SurfaceClass surfaceClass = surface->surface()->surfaceClass();
if (surfaceClass == QSurface::Window) {
m_isPBufferCurrent = false;
QXcbWindow *window = static_cast<QXcbWindow *>(surface);
- return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), window->xcb_window(), m_context);
+ glxDrawable = window->xcb_window();
+ success = glXMakeCurrent(dpy, glxDrawable, m_context);
} else if (surfaceClass == QSurface::Offscreen) {
m_isPBufferCurrent = true;
QGLXPbuffer *pbuffer = static_cast<QGLXPbuffer *>(surface);
- return glXMakeContextCurrent(DISPLAY_FROM_XCB(m_screen), pbuffer->pbuffer(), pbuffer->pbuffer(), m_context);
+ glxDrawable = pbuffer->pbuffer();
+ success = glXMakeContextCurrent(dpy, glxDrawable, glxDrawable, m_context);
+ }
+
+ if (success) {
+ int interval = surface->format().swapInterval();
+ if (interval >= 0 && m_swapInterval != interval) {
+ m_swapInterval = interval;
+ typedef void (*qt_glXSwapIntervalEXT)(Display *, GLXDrawable, int);
+ typedef void (*qt_glXSwapIntervalMESA)(unsigned int);
+ static qt_glXSwapIntervalEXT glXSwapIntervalEXT = 0;
+ static qt_glXSwapIntervalMESA glXSwapIntervalMESA = 0;
+ static bool resolved = false;
+ if (!resolved) {
+ resolved = true;
+ QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(dpy,
+ m_screen->screenNumber())).split(' ');
+ if (glxExt.contains("GLX_EXT_swap_control"))
+ glXSwapIntervalEXT = (qt_glXSwapIntervalEXT) getProcAddress("glXSwapIntervalEXT");
+ if (glxExt.contains("GLX_MESA_swap_control"))
+ glXSwapIntervalMESA = (qt_glXSwapIntervalMESA) getProcAddress("glXSwapIntervalMESA");
+ }
+ if (glXSwapIntervalEXT)
+ glXSwapIntervalEXT(dpy, glxDrawable, interval);
+ else if (glXSwapIntervalMESA)
+ glXSwapIntervalMESA(interval);
+ }
}
- return false;
+
+ return success;
}
void QGLXContext::doneCurrent()
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index dcc7fe8855..00bba94ab3 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -81,7 +81,7 @@ private:
GLXContext m_shareContext;
QSurfaceFormat m_format;
bool m_isPBufferCurrent;
-
+ int m_swapInterval;
static bool m_queriedDummyContext;
static bool m_supportsThreading;
};
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index e93b36cb99..366e043e98 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -232,9 +232,6 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s
Q_XCB_NOOP(connection());
m_dirty = m_dirty | source;
-
- xcb_flush(xcb_connection());
- Q_XCB_NOOP(connection());
}
void QXcbShmImage::preparePaint(const QRegion &region)
@@ -314,10 +311,11 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
Q_XCB_NOOP(connection());
if (m_syncingResize) {
- xcb_flush(xcb_connection());
connection()->sync();
m_syncingResize = false;
platformWindow->updateSyncRequestCounter();
+ } else {
+ xcb_flush(xcb_connection());
}
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 3c4ab8d3e2..0cff92dacc 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -326,23 +326,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeXRandr();
updateScreens();
- m_connectionEventListener = xcb_generate_id(m_connection);
- xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
- m_connectionEventListener, m_screens.at(0)->root(),
- 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
- m_screens.at(0)->screen()->root_visual, 0, 0);
-#ifndef QT_NO_DEBUG
- QByteArray ba("Qt xcb connection listener window");
- Q_XCB_CALL(xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_connectionEventListener,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData()));
-#endif
-
initializeGLX();
initializeXFixes();
initializeXRender();
@@ -379,9 +362,6 @@ QXcbConnection::~QXcbConnection()
#ifndef QT_NO_DRAGANDDROP
delete m_drag;
#endif
- // Delete screens in reverse order to avoid crash in case of multiple screens
- while (!m_screens.isEmpty())
- delete m_screens.takeLast();
#ifdef XCB_USE_XINPUT2_MAEMO
finalizeXInput2Maemo();
@@ -396,6 +376,10 @@ QXcbConnection::~QXcbConnection()
delete m_reader;
+ // Delete screens in reverse order to avoid crash in case of multiple screens
+ while (!m_screens.isEmpty())
+ delete m_screens.takeLast();
+
#ifdef XCB_USE_EGL
if (m_has_egl)
eglTerminate(m_egl_display);
@@ -1081,14 +1065,21 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
xcb_client_message_event_t event;
memset(&event, 0, sizeof(event));
+ const xcb_window_t eventListener = xcb_generate_id(m_connection);
+ Q_XCB_CALL(xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
+ eventListener, m_screens.at(0)->root(),
+ 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
+ m_screens.at(0)->screen()->root_visual, 0, 0));
+
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.sequence = 0;
- event.window = m_connectionEventListener;
+ event.window = eventListener;
event.type = atom(a);
event.data.data32[0] = id;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_connectionEventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_destroy_window(m_connection, eventListener));
xcb_flush(xcb_connection());
}
@@ -1450,6 +1441,10 @@ static const char * xcb_atomnames = {
"Abs Distance\0"
"Wacom Serial IDs\0"
"INTEGER\0"
+ "Rel Horiz Wheel\0"
+ "Rel Vert Wheel\0"
+ "Rel Horiz Scroll\0"
+ "Rel Vert Scroll\0"
#if XCB_USE_MAEMO_WINDOW_PROPERTIES
"_MEEGOTOUCH_ORIENTATION_ANGLE\0"
#endif
@@ -1731,21 +1726,23 @@ bool QXcbConnection::hasEgl() const
#endif // defined(XCB_USE_EGL)
#if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
-// Borrowed from libXi.
-int QXcbConnection::xi2CountBits(unsigned char *ptr, int len)
+static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number)
{
- int bits = 0;
- int i;
- unsigned char x;
-
- for (i = 0; i < len; i++) {
- x = ptr[i];
- while (x > 0) {
- bits += (x & 0x1);
- x >>= 1;
+ int offset = 0;
+ for (int i = 0; i < maskLen; i++) {
+ if (number < 8) {
+ if ((maskPtr[i] & (1 << number)) == 0)
+ return -1;
}
+ for (int j = 0; j < 8; j++) {
+ if (j == number)
+ return offset;
+ if (maskPtr[i] & (1 << j))
+ offset++;
+ }
+ number -= 8;
}
- return bits;
+ return -1;
}
bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value)
@@ -1754,13 +1751,13 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub
unsigned char *buttonsMaskAddr = (unsigned char*)&xideviceevent[1];
unsigned char *valuatorsMaskAddr = buttonsMaskAddr + xideviceevent->buttons_len * 4;
FP3232 *valuatorsValuesAddr = (FP3232*)(valuatorsMaskAddr + xideviceevent->valuators_len * 4);
- int numValuatorValues = xi2CountBits(valuatorsMaskAddr, xideviceevent->valuators_len * 4);
- // This relies on all bit being set until a certain number i.e. it doesn't support only bit 0 and 5 being set in the mask.
- // Just like the original code, works for now.
- if (valuatorNum >= numValuatorValues)
+
+ int valuatorOffset = xi2ValuatorOffset(valuatorsMaskAddr, xideviceevent->valuators_len, valuatorNum);
+ if (valuatorOffset < 0)
return false;
- *value = valuatorsValuesAddr[valuatorNum].integral;
- *value += ((double)valuatorsValuesAddr[valuatorNum].frac / (1 << 16) / (1 << 16));
+
+ *value = valuatorsValuesAddr[valuatorOffset].integral;
+ *value += ((double)valuatorsValuesAddr[valuatorOffset].frac / (1 << 16) / (1 << 16));
return true;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index ba056a8006..71f5ce13fb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -69,9 +69,12 @@
struct XInput2MaemoData;
#elif XCB_USE_XINPUT2
#include <X11/extensions/XI2.h>
+#ifdef XIScrollClass
+#define XCB_USE_XINPUT21 // XI 2.1 adds smooth scrolling support
#ifdef XI_TouchBeginMask
#define XCB_USE_XINPUT22 // XI 2.2 adds multi-point touch support
#endif
+#endif
struct XInput2DeviceData;
#endif
struct xcb_randr_get_output_info_reply_t;
@@ -271,6 +274,10 @@ namespace QXcbAtom {
AbsDistance,
WacomSerialIDs,
INTEGER,
+ RelHorizWheel,
+ RelVertWheel,
+ RelHorizScroll,
+ RelVertScroll,
#if XCB_USE_MAEMO_WINDOW_PROPERTIES
MeegoTouchOrientationAngle,
@@ -499,10 +506,19 @@ private:
void xi2ReportTabletEvent(const TabletData &tabletData, void *event);
QVector<TabletData> m_tabletData;
#endif
+ struct ScrollingDevice {
+ ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0) { }
+ int deviceId;
+ int verticalIndex, horizontalIndex;
+ double verticalIncrement, horizontalIncrement;
+ Qt::Orientations orientations;
+ QPointF lastScrollPosition;
+ };
+ void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
+ QHash<int, ScrollingDevice> m_scrollingDevices;
#endif // XCB_USE_XINPUT2
#if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
- static int xi2CountBits(unsigned char *ptr, int len);
static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value);
static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode);
#endif
@@ -521,8 +537,6 @@ private:
QByteArray m_displayName;
- xcb_window_t m_connectionEventListener;
-
QXcbKeyboard *m_keyboard;
#ifndef QT_NO_CLIPBOARD
QXcbClipboard *m_clipboard;
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index a571f16eb6..d80b49ccbb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qxcbconnection.h"
+#include "qxcbkeyboard.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
#include "qtouchdevice.h"
@@ -75,16 +76,20 @@ void QXcbConnection::initializeXInput2()
#ifndef QT_NO_TABLETEVENT
m_tabletData.clear();
#endif
+ m_scrollingDevices.clear();
Display *xDisplay = static_cast<Display *>(m_xlib_display);
if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
int xiMajor = 2;
m_xi2Minor = 2; // try 2.2 first, needed for TouchBegin/Update/End
if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
- m_xi2Minor = 0; // for tablet support 2.0 is enough
- m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
- } else {
+ m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
+ if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
+ m_xi2Minor = 0; // for tablet support 2.0 is enough
+ m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
+ } else
+ m_xi2Enabled = true;
+ } else
m_xi2Enabled = true;
- }
if (m_xi2Enabled) {
if (Q_UNLIKELY(debug_xinput_devices))
#ifdef XCB_USE_XINPUT22
@@ -103,6 +108,7 @@ void QXcbConnection::initializeXInput2()
#ifndef QT_NO_TABLETEVENT
TabletData tabletData;
#endif
+ ScrollingDevice scrollingDevice;
for (int c = 0; c < devices[i].num_classes; ++c) {
switch (devices[i].classes[c]->type) {
case XIValuatorClass: {
@@ -119,7 +125,29 @@ void QXcbConnection::initializeXInput2()
tabletData.valuatorInfo[valuatorAtom] = info;
}
#endif // QT_NO_TABLETEVENT
- } break;
+ if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
+ scrollingDevice.lastScrollPosition.setX(vci->value);
+ else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
+ scrollingDevice.lastScrollPosition.setY(vci->value);
+ break;
+ }
+#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;
+ scrollingDevice.verticalIncrement = sci->increment;
+ }
+ else if (sci->scroll_type == XIScrollTypeHorizontal) {
+ scrollingDevice.orientations |= Qt::Horizontal;
+ scrollingDevice.horizontalIndex = sci->number;
+ scrollingDevice.horizontalIncrement = sci->increment;
+ }
+ break;
+ }
+#endif
default:
break;
}
@@ -140,6 +168,15 @@ void QXcbConnection::initializeXInput2()
qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
}
#endif // QT_NO_TABLETEVENT
+
+#ifdef XCB_USE_XINPUT21
+ if (scrollingDevice.orientations) {
+ m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice);
+ if (Q_UNLIKELY(debug_xinput_devices))
+ qDebug() << " it's a scrolling device";
+ }
+#endif
+
if (!isTablet) {
XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
if (Q_UNLIKELY(debug_xinput_devices)) {
@@ -181,7 +218,7 @@ void QXcbConnection::xi2Select(xcb_window_t window)
mask.mask_len = sizeof(bitMask);
mask.mask = xiBitMask;
// Enable each touchscreen
- foreach (XInput2DeviceData *dev, m_touchDevices.values()) {
+ foreach (XInput2DeviceData *dev, m_touchDevices) {
mask.deviceid = dev->xiDeviceInfo->deviceid;
Status result = XISelectEvents(xDisplay, window, &mask, 1);
// If we have XInput >= 2.2 and successfully enable a touchscreen, then
@@ -213,6 +250,22 @@ void QXcbConnection::xi2Select(xcb_window_t window)
XISelectEvents(xDisplay, window, xiEventMask.data(), m_tabletData.count());
}
#endif // QT_NO_TABLETEVENT
+
+#ifdef XCB_USE_XINPUT21
+ // Enable each scroll device
+ if (!m_scrollingDevices.isEmpty()) {
+ QVector<XIEventMask> xiEventMask(m_scrollingDevices.size());
+ bitMask = XI_MotionMask;
+ int i=0;
+ Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) {
+ xiEventMask[i].deviceid = scrollingDevice.deviceId;
+ xiEventMask[i].mask_len = sizeof(bitMask);
+ xiEventMask[i].mask = xiBitMask;
+ i++;
+ }
+ XISelectEvents(xDisplay, window, xiEventMask.data(), m_scrollingDevices.size());
+ }
+#endif
}
XInput2DeviceData *QXcbConnection::deviceForId(int id)
@@ -243,7 +296,8 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
type = QTouchDevice::TouchScreen;
break;
}
- } break;
+ break;
+ }
#endif // XCB_USE_XINPUT22
case XIValuatorClass: {
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classinfo);
@@ -260,7 +314,8 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
hasRelativeCoords = true;
dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution);
}
- } break;
+ break;
+ }
}
}
if (type < 0 && caps && hasRelativeCoords) {
@@ -287,12 +342,14 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
return dev;
}
-#ifdef XCB_USE_XINPUT22
+#if defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT)
static qreal fixed1616ToReal(FP1616 val)
{
return (qreal(val >> 16)) + (val & 0xFF) / (qreal)0xFF;
}
+#endif // defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT)
+#if defined(XCB_USE_XINPUT21)
static qreal valuatorNormalized(double value, XIValuatorClassInfo *vci)
{
if (value > vci->max)
@@ -301,7 +358,7 @@ static qreal valuatorNormalized(double value, XIValuatorClassInfo *vci)
value = vci->min;
return (value - vci->min) / (vci->max - vci->min);
}
-#endif // XCB_USE_XINPUT22
+#endif // XCB_USE_XINPUT21
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{
@@ -317,6 +374,12 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
#endif // QT_NO_TABLETEVENT
+#ifdef XCB_USE_XINPUT21
+ QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(xiEvent->deviceid);
+ if (device != m_scrollingDevices.end())
+ xi2HandleScrollEvent(xiEvent, device.value());
+#endif // XCB_USE_XINPUT21
+
#ifdef XCB_USE_XINPUT22
if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) {
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
@@ -461,6 +524,55 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
}
+void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice)
+{
+#ifdef XCB_USE_XINPUT21
+ xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
+
+ if (xiEvent->evtype == XI_Motion) {
+ xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
+ if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
+ QPoint rawDelta;
+ QPoint angleDelta;
+ double value;
+ if (scrollingDevice.orientations & Qt::Vertical) {
+ if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice.verticalIndex, &value)) {
+ double delta = scrollingDevice.lastScrollPosition.y() - value;
+ scrollingDevice.lastScrollPosition.setY(value);
+ angleDelta.setY((delta / scrollingDevice.verticalIncrement) * 120);
+ // We do not set "pixel" delta if it is only measured in ticks.
+ if (scrollingDevice.verticalIncrement > 1)
+ rawDelta.setY(delta);
+ }
+ }
+ if (scrollingDevice.orientations & Qt::Horizontal) {
+ if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice.horizontalIndex, &value)) {
+ double delta = scrollingDevice.lastScrollPosition.x() - value;
+ scrollingDevice.lastScrollPosition.setX(value);
+ angleDelta.setX((delta / scrollingDevice.horizontalIncrement) * 120);
+ // We do not set "pixel" delta if it is only measured in ticks.
+ if (scrollingDevice.horizontalIncrement > 1)
+ rawDelta.setX(delta);
+ }
+ }
+ 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());
+ std::swap(rawDelta.rx(), rawDelta.ry());
+ }
+ QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, rawDelta, angleDelta, modifiers);
+ }
+ }
+ }
+#else
+ Q_UNUSED(event);
+ Q_UNUSED(scrollingDevice);
+#endif // XCB_USE_XINPUT21
+}
+
#ifndef QT_NO_TABLETEVENT
bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
{
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index d18693f6b8..61dfe8ac17 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -593,9 +593,9 @@ static Window findXdndAwareParent(Window window)
unsigned char *data = 0;
if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
- if (data)
+ if (data)
XFree(data);
- if (type) {
+ if (type) {
target = window;
break;
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 2529fb8a83..966090dbd5 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -117,7 +117,7 @@
#define XF86XK_KbdBrightnessUp 0x1008FF05
#define XF86XK_KbdBrightnessDown 0x1008FF06
#define XF86XK_Standby 0x1008FF10
-#define XF86XK_AudioLowerVolume 0x1008FF11
+#define XF86XK_AudioLowerVolume 0x1008FF11
#define XF86XK_AudioMute 0x1008FF12
#define XF86XK_AudioRaiseVolume 0x1008FF13
#define XF86XK_AudioPlay 0x1008FF14
@@ -344,65 +344,65 @@ static const unsigned int KeyTbl[] = {
// International & multi-key character composition
XK_ISO_Level3_Shift, Qt::Key_AltGr,
- XK_Multi_key, Qt::Key_Multi_key,
- XK_Codeinput, Qt::Key_Codeinput,
- XK_SingleCandidate, Qt::Key_SingleCandidate,
- XK_MultipleCandidate, Qt::Key_MultipleCandidate,
- XK_PreviousCandidate, Qt::Key_PreviousCandidate,
+ XK_Multi_key, Qt::Key_Multi_key,
+ XK_Codeinput, Qt::Key_Codeinput,
+ XK_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_MultipleCandidate, Qt::Key_MultipleCandidate,
+ XK_PreviousCandidate, Qt::Key_PreviousCandidate,
// Misc Functions
- XK_Mode_switch, Qt::Key_Mode_switch,
- XK_script_switch, Qt::Key_Mode_switch,
+ XK_Mode_switch, Qt::Key_Mode_switch,
+ XK_script_switch, Qt::Key_Mode_switch,
// Japanese keyboard support
- XK_Kanji, Qt::Key_Kanji,
- XK_Muhenkan, Qt::Key_Muhenkan,
- //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
- XK_Henkan_Mode, Qt::Key_Henkan,
- XK_Henkan, Qt::Key_Henkan,
- XK_Romaji, Qt::Key_Romaji,
- XK_Hiragana, Qt::Key_Hiragana,
- XK_Katakana, Qt::Key_Katakana,
- XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
- XK_Zenkaku, Qt::Key_Zenkaku,
- XK_Hankaku, Qt::Key_Hankaku,
- XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
- XK_Touroku, Qt::Key_Touroku,
- XK_Massyo, Qt::Key_Massyo,
- XK_Kana_Lock, Qt::Key_Kana_Lock,
- XK_Kana_Shift, Qt::Key_Kana_Shift,
- XK_Eisu_Shift, Qt::Key_Eisu_Shift,
- XK_Eisu_toggle, Qt::Key_Eisu_toggle,
- //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
- //XK_Zen_Koho, Qt::Key_Zen_Koho,
- //XK_Mae_Koho, Qt::Key_Mae_Koho,
- XK_Kanji_Bangou, Qt::Key_Codeinput,
- XK_Zen_Koho, Qt::Key_MultipleCandidate,
- XK_Mae_Koho, Qt::Key_PreviousCandidate,
+ XK_Kanji, Qt::Key_Kanji,
+ XK_Muhenkan, Qt::Key_Muhenkan,
+ //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
+ XK_Henkan_Mode, Qt::Key_Henkan,
+ XK_Henkan, Qt::Key_Henkan,
+ XK_Romaji, Qt::Key_Romaji,
+ XK_Hiragana, Qt::Key_Hiragana,
+ XK_Katakana, Qt::Key_Katakana,
+ XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
+ XK_Zenkaku, Qt::Key_Zenkaku,
+ XK_Hankaku, Qt::Key_Hankaku,
+ XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
+ XK_Touroku, Qt::Key_Touroku,
+ XK_Massyo, Qt::Key_Massyo,
+ XK_Kana_Lock, Qt::Key_Kana_Lock,
+ XK_Kana_Shift, Qt::Key_Kana_Shift,
+ XK_Eisu_Shift, Qt::Key_Eisu_Shift,
+ XK_Eisu_toggle, Qt::Key_Eisu_toggle,
+ //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
+ //XK_Zen_Koho, Qt::Key_Zen_Koho,
+ //XK_Mae_Koho, Qt::Key_Mae_Koho,
+ XK_Kanji_Bangou, Qt::Key_Codeinput,
+ XK_Zen_Koho, Qt::Key_MultipleCandidate,
+ XK_Mae_Koho, Qt::Key_PreviousCandidate,
#ifdef XK_KOREAN
// Korean keyboard support
- XK_Hangul, Qt::Key_Hangul,
- XK_Hangul_Start, Qt::Key_Hangul_Start,
- XK_Hangul_End, Qt::Key_Hangul_End,
- XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
- XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
- XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
- //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
- XK_Hangul_Codeinput, Qt::Key_Codeinput,
- XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
- XK_Hangul_Banja, Qt::Key_Hangul_Banja,
- XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
- XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
+ XK_Hangul, Qt::Key_Hangul,
+ XK_Hangul_Start, Qt::Key_Hangul_Start,
+ XK_Hangul_End, Qt::Key_Hangul_End,
+ XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
+ XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
+ XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
+ //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
+ XK_Hangul_Codeinput, Qt::Key_Codeinput,
+ XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
+ XK_Hangul_Banja, Qt::Key_Hangul_Banja,
+ XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
+ XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
//XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
//XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
//XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
- XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
- XK_Hangul_Special, Qt::Key_Hangul_Special,
- //XK_Hangul_switch, Qt::Key_Hangul_switch,
- XK_Hangul_switch, Qt::Key_Mode_switch,
+ XK_Hangul_Special, Qt::Key_Hangul_Special,
+ //XK_Hangul_switch, Qt::Key_Hangul_switch,
+ XK_Hangul_switch, Qt::Key_Mode_switch,
#endif // XK_KOREAN
// dead keys
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index 9d81c8e224..8c10b134bd 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -50,6 +50,7 @@
#include <X11/SM/SMlib.h>
#include <errno.h> // ERANGE
+#include <cerrno> // ERANGE
class QSmSocketReceiver : public QObject
{
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index f46bed77d6..63894373b8 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -297,7 +297,7 @@ void QXcbWindow::create()
#elif defined(XCB_USE_EGL)
EGLDisplay eglDisplay = connection()->egl_display();
EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, m_format, true);
- m_format = q_glFormatFromConfig(eglDisplay, eglConfig);
+ m_format = q_glFormatFromConfig(eglDisplay, eglConfig, m_format);
VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);
@@ -672,8 +672,6 @@ void QXcbWindow::show()
m_screen->windowShown(this);
- xcb_flush(xcb_connection());
-
connection()->sync();
}
@@ -1695,6 +1693,7 @@ 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)
@@ -1703,6 +1702,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
QWindowSystemInterface::handleWheelEvent(window(), event->time,
local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers);
+#endif
return;
}
@@ -1893,7 +1893,6 @@ void QXcbWindow::updateSyncRequestCounter()
{
if (m_usingSyncProtocol && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
- xcb_flush(xcb_connection());
connection()->sync();
m_syncValue.lo = 0;
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index 8968d020c4..67f2d8a911 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -42,7 +42,7 @@ HEADERS = \
qxcbxsettings.h \
qxcbsystemtraytracker.h
-LIBS += -ldl
+LIBS += $$QMAKE_LIBS_DYNLOAD
# needed by GLX, Xcursor ...
contains(QT_CONFIG, xcb-xlib) {