diff options
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r-- | src/plugins/platforms/xcb/qglxintegration.cpp | 38 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qglxintegration.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 77 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 20 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 132 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbdrag.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.cpp | 96 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbsessionmanager.cpp | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 7 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/xcb-plugin.pro | 2 |
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 ®ion) @@ -314,10 +311,11 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion ®ion, 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) { |