| Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /**************************************************************************** | - | ||||||||||||||||||
| 2 | ** | - | ||||||||||||||||||
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||||||||
| 4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||||||||
| 5 | ** | - | ||||||||||||||||||
| 6 | ** This file is part of the plugins of the Qt Toolkit. | - | ||||||||||||||||||
| 7 | ** | - | ||||||||||||||||||
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||||||||||||||
| 9 | ** Commercial License Usage | - | ||||||||||||||||||
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||||||||
| 11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||||||||
| 12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||||||||
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||||||||
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||||||||||||||
| 16 | ** | - | ||||||||||||||||||
| 17 | ** GNU Lesser General Public License Usage | - | ||||||||||||||||||
| 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||||||||
| 19 | ** General Public License version 3 as published by the Free Software | - | ||||||||||||||||||
| 20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||||||||
| 21 | ** packaging of this file. Please review the following information to | - | ||||||||||||||||||
| 22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||||||||
| 23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||||||||
| 24 | ** | - | ||||||||||||||||||
| 25 | ** GNU General Public License Usage | - | ||||||||||||||||||
| 26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||||||||
| 27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||||||||
| 28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||||||||
| 29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||||||||
| 30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||||||||
| 31 | ** included in the packaging of this file. Please review the following | - | ||||||||||||||||||
| 32 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||||||||
| 33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||||||||
| 34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||||||||
| 35 | ** | - | ||||||||||||||||||
| 36 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||
| 37 | ** | - | ||||||||||||||||||
| 38 | ****************************************************************************/ | - | ||||||||||||||||||
| 39 | - | |||||||||||||||||||
| 40 | #include <QtGui/private/qguiapplication_p.h> | - | ||||||||||||||||||
| 41 | #include <QtGui/private/qhighdpiscaling_p.h> | - | ||||||||||||||||||
| 42 | #include <QtCore/QDebug> | - | ||||||||||||||||||
| 43 | - | |||||||||||||||||||
| 44 | #include "qxcbconnection.h" | - | ||||||||||||||||||
| 45 | #include "qxcbkeyboard.h" | - | ||||||||||||||||||
| 46 | #include "qxcbscreen.h" | - | ||||||||||||||||||
| 47 | #include "qxcbwindow.h" | - | ||||||||||||||||||
| 48 | #include "qxcbclipboard.h" | - | ||||||||||||||||||
| 49 | #include "qxcbdrag.h" | - | ||||||||||||||||||
| 50 | #include "qxcbwmsupport.h" | - | ||||||||||||||||||
| 51 | #include "qxcbnativeinterface.h" | - | ||||||||||||||||||
| 52 | #include "qxcbintegration.h" | - | ||||||||||||||||||
| 53 | #include "qxcbsystemtraytracker.h" | - | ||||||||||||||||||
| 54 | #include "qxcbglintegrationfactory.h" | - | ||||||||||||||||||
| 55 | #include "qxcbglintegration.h" | - | ||||||||||||||||||
| 56 | - | |||||||||||||||||||
| 57 | #include <QSocketNotifier> | - | ||||||||||||||||||
| 58 | #include <QAbstractEventDispatcher> | - | ||||||||||||||||||
| 59 | #include <QTimer> | - | ||||||||||||||||||
| 60 | #include <QByteArray> | - | ||||||||||||||||||
| 61 | #include <QScopedPointer> | - | ||||||||||||||||||
| 62 | - | |||||||||||||||||||
| 63 | #include <algorithm> | - | ||||||||||||||||||
| 64 | - | |||||||||||||||||||
| 65 | #include <stdio.h> | - | ||||||||||||||||||
| 66 | #include <errno.h> | - | ||||||||||||||||||
| 67 | #include <xcb/shm.h> | - | ||||||||||||||||||
| 68 | #include <xcb/sync.h> | - | ||||||||||||||||||
| 69 | #include <xcb/xfixes.h> | - | ||||||||||||||||||
| 70 | #include <xcb/xinerama.h> | - | ||||||||||||||||||
| 71 | - | |||||||||||||||||||
| 72 | #ifdef XCB_USE_XLIB | - | ||||||||||||||||||
| 73 | #include <X11/Xlib.h> | - | ||||||||||||||||||
| 74 | #include <X11/Xlib-xcb.h> | - | ||||||||||||||||||
| 75 | #include <X11/Xlibint.h> | - | ||||||||||||||||||
| 76 | #include <X11/Xutil.h> | - | ||||||||||||||||||
| 77 | #endif | - | ||||||||||||||||||
| 78 | - | |||||||||||||||||||
| 79 | #if defined(XCB_USE_XINPUT2) | - | ||||||||||||||||||
| 80 | #include <X11/extensions/XI2proto.h> | - | ||||||||||||||||||
| 81 | #endif | - | ||||||||||||||||||
| 82 | - | |||||||||||||||||||
| 83 | #ifdef XCB_USE_RENDER | - | ||||||||||||||||||
| 84 | #include <xcb/render.h> | - | ||||||||||||||||||
| 85 | #endif | - | ||||||||||||||||||
| 86 | - | |||||||||||||||||||
| 87 | #if defined(Q_CC_GNU) && defined(Q_OF_ELF) | - | ||||||||||||||||||
| 88 | static xcb_generic_event_t *local_xcb_poll_for_queued_event(xcb_connection_t *c) | - | ||||||||||||||||||
| 89 | __attribute__((weakref("xcb_poll_for_queued_event"))); | - | ||||||||||||||||||
| 90 | - | |||||||||||||||||||
| 91 | static inline void checkXcbPollForQueuedEvent() | - | ||||||||||||||||||
| 92 | { } | - | ||||||||||||||||||
| 93 | #else | - | ||||||||||||||||||
| 94 | #include <dlfcn.h> | - | ||||||||||||||||||
| 95 | typedef xcb_generic_event_t * (*XcbPollForQueuedEventFunctionPointer)(xcb_connection_t *c); | - | ||||||||||||||||||
| 96 | static XcbPollForQueuedEventFunctionPointer local_xcb_poll_for_queued_event; | - | ||||||||||||||||||
| 97 | - | |||||||||||||||||||
| 98 | static inline void checkXcbPollForQueuedEvent() | - | ||||||||||||||||||
| 99 | { | - | ||||||||||||||||||
| 100 | #ifdef RTLD_DEFAULT | - | ||||||||||||||||||
| 101 | local_xcb_poll_for_queued_event = (XcbPollForQueuedEventFunctionPointer)dlsym(RTLD_DEFAULT, "xcb_poll_for_queued_event"); | - | ||||||||||||||||||
| 102 | #endif | - | ||||||||||||||||||
| 103 | } | - | ||||||||||||||||||
| 104 | #endif | - | ||||||||||||||||||
| 105 | - | |||||||||||||||||||
| 106 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
| 107 | - | |||||||||||||||||||
| 108 | Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input") | - | ||||||||||||||||||
| 109 | Q_LOGGING_CATEGORY(lcQpaXInputDevices, "qt.qpa.input.devices") | - | ||||||||||||||||||
| 110 | Q_LOGGING_CATEGORY(lcQpaXInputEvents, "qt.qpa.input.events") | - | ||||||||||||||||||
| 111 | Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen") | - | ||||||||||||||||||
| 112 | - | |||||||||||||||||||
| 113 | // this event type was added in libxcb 1.10, | - | ||||||||||||||||||
| 114 | // but we support also older version | - | ||||||||||||||||||
| 115 | #ifndef XCB_GE_GENERIC | - | ||||||||||||||||||
| 116 | #define XCB_GE_GENERIC 35 | - | ||||||||||||||||||
| 117 | #endif | - | ||||||||||||||||||
| 118 | - | |||||||||||||||||||
| 119 | #if defined(XCB_USE_XINPUT2) | - | ||||||||||||||||||
| 120 | // Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed: | - | ||||||||||||||||||
| 121 | // - "pad0" became "extension" | - | ||||||||||||||||||
| 122 | // - "pad1" and "pad" became "pad0" | - | ||||||||||||||||||
| 123 | // New and old version of this struct share the following fields: | - | ||||||||||||||||||
| 124 | typedef struct qt_xcb_ge_event_t { | - | ||||||||||||||||||
| 125 | uint8_t response_type; | - | ||||||||||||||||||
| 126 | uint8_t extension; | - | ||||||||||||||||||
| 127 | uint16_t sequence; | - | ||||||||||||||||||
| 128 | uint32_t length; | - | ||||||||||||||||||
| 129 | uint16_t event_type; | - | ||||||||||||||||||
| 130 | } qt_xcb_ge_event_t; | - | ||||||||||||||||||
| 131 | - | |||||||||||||||||||
| 132 | static inline bool isXIEvent(xcb_generic_event_t *event, int opCode) | - | ||||||||||||||||||
| 133 | { | - | ||||||||||||||||||
| 134 | qt_xcb_ge_event_t *e = (qt_xcb_ge_event_t *)event; | - | ||||||||||||||||||
| 135 | return e->extension == opCode; | - | ||||||||||||||||||
| 136 | } | - | ||||||||||||||||||
| 137 | #endif // XCB_USE_XINPUT2 | - | ||||||||||||||||||
| 138 | - | |||||||||||||||||||
| 139 | #ifdef XCB_USE_XLIB | - | ||||||||||||||||||
| 140 | static const char * const xcbConnectionErrors[] = { | - | ||||||||||||||||||
| 141 | "No error", /* Error 0 */ | - | ||||||||||||||||||
| 142 | "I/O error", /* XCB_CONN_ERROR */ | - | ||||||||||||||||||
| 143 | "Unsupported extension used", /* XCB_CONN_CLOSED_EXT_NOTSUPPORTED */ | - | ||||||||||||||||||
| 144 | "Out of memory", /* XCB_CONN_CLOSED_MEM_INSUFFICIENT */ | - | ||||||||||||||||||
| 145 | "Maximum allowed requested length exceeded", /* XCB_CONN_CLOSED_REQ_LEN_EXCEED */ | - | ||||||||||||||||||
| 146 | "Failed to parse display string", /* XCB_CONN_CLOSED_PARSE_ERR */ | - | ||||||||||||||||||
| 147 | "No such screen on display", /* XCB_CONN_CLOSED_INVALID_SCREEN */ | - | ||||||||||||||||||
| 148 | "Error during FD passing" /* XCB_CONN_CLOSED_FDPASSING_FAILED */ | - | ||||||||||||||||||
| 149 | }; | - | ||||||||||||||||||
| 150 | - | |||||||||||||||||||
| 151 | static int nullErrorHandler(Display *, XErrorEvent *) | - | ||||||||||||||||||
| 152 | { | - | ||||||||||||||||||
| 153 | return 0; | - | ||||||||||||||||||
| 154 | } | - | ||||||||||||||||||
| 155 | - | |||||||||||||||||||
| 156 | static int ioErrorHandler(Display *dpy) | - | ||||||||||||||||||
| 157 | { | - | ||||||||||||||||||
| 158 | xcb_connection_t *conn = XGetXCBConnection(dpy); | - | ||||||||||||||||||
| 159 | if (conn != NULL) { | - | ||||||||||||||||||
| 160 | /* Print a message with a textual description of the error */ | - | ||||||||||||||||||
| 161 | int code = xcb_connection_has_error(conn); | - | ||||||||||||||||||
| 162 | const char *str = "Unknown error"; | - | ||||||||||||||||||
| 163 | int arrayLength = sizeof(xcbConnectionErrors) / sizeof(xcbConnectionErrors[0]); | - | ||||||||||||||||||
| 164 | if (code >= 0 && code < arrayLength) | - | ||||||||||||||||||
| 165 | str = xcbConnectionErrors[code]; | - | ||||||||||||||||||
| 166 | - | |||||||||||||||||||
| 167 | qWarning("The X11 connection broke: %s (code %d)", str, code); | - | ||||||||||||||||||
| 168 | } | - | ||||||||||||||||||
| 169 | return _XDefaultIOError(dpy); | - | ||||||||||||||||||
| 170 | } | - | ||||||||||||||||||
| 171 | #endif | - | ||||||||||||||||||
| 172 | - | |||||||||||||||||||
| 173 | QXcbScreen* QXcbConnection::findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const | - | ||||||||||||||||||
| 174 | { | - | ||||||||||||||||||
| 175 | foreachfor (QXcbScreen *screen ,: m_screens) { | - | ||||||||||||||||||
| 176 | if (screen->root() == rootWindow && screen->crtc() == crtc)
| 0 | ||||||||||||||||||
| 177 | return screen; never executed: return screen; | 0 | ||||||||||||||||||
| 178 | } never executed: end of block | 0 | ||||||||||||||||||
| 179 | - | |||||||||||||||||||
| 180 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
| 181 | } | - | ||||||||||||||||||
| 182 | - | |||||||||||||||||||
| 183 | QXcbScreen* QXcbConnection::findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) const | - | ||||||||||||||||||
| 184 | { | - | ||||||||||||||||||
| 185 | foreachfor (QXcbScreen *screen ,: m_screens) { | - | ||||||||||||||||||
| 186 | if (screen->root() == rootWindow && screen->output() == output)
| 0 | ||||||||||||||||||
| 187 | return screen; never executed: return screen; | 0 | ||||||||||||||||||
| 188 | } never executed: end of block | 0 | ||||||||||||||||||
| 189 | - | |||||||||||||||||||
| 190 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
| 191 | } | - | ||||||||||||||||||
| 192 | - | |||||||||||||||||||
| 193 | QXcbVirtualDesktop* QXcbConnection::virtualDesktopForRootWindow(xcb_window_t rootWindow) const | - | ||||||||||||||||||
| 194 | { | - | ||||||||||||||||||
| 195 | foreachfor (QXcbVirtualDesktop *virtualDesktop ,: m_virtualDesktops) { | - | ||||||||||||||||||
| 196 | if (virtualDesktop->screen()->root == rootWindow)
| 0 | ||||||||||||||||||
| 197 | return virtualDesktop; never executed: return virtualDesktop; | 0 | ||||||||||||||||||
| 198 | } never executed: end of block | 0 | ||||||||||||||||||
| 199 | - | |||||||||||||||||||
| 200 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
| 201 | } | - | ||||||||||||||||||
| 202 | - | |||||||||||||||||||
| 203 | /*! | - | ||||||||||||||||||
| 204 | \brief Synchronizes the screen list, adds new screens, removes deleted ones | - | ||||||||||||||||||
| 205 | */ | - | ||||||||||||||||||
| 206 | void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) | - | ||||||||||||||||||
| 207 | { | - | ||||||||||||||||||
| 208 | if (event->subCode == XCB_RANDR_NOTIFY_CRTC_CHANGE) {
| 0 | ||||||||||||||||||
| 209 | xcb_randr_crtc_change_t crtc = event->u.cc; | - | ||||||||||||||||||
| 210 | QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(crtc.window); | - | ||||||||||||||||||
| 211 | if (!virtualDesktop)
| 0 | ||||||||||||||||||
| 212 | // Not for us | - | ||||||||||||||||||
| 213 | return; never executed: return; | 0 | ||||||||||||||||||
| 214 | - | |||||||||||||||||||
| 215 | QXcbScreen *screen = findScreenForCrtc(crtc.window, crtc.crtc); | - | ||||||||||||||||||
| 216 | qCDebug(lcQpaScreen) << "QXcbConnection: XCB_RANDR_NOTIFY_CRTC_CHANGE:" << crtc.crtc never executed: QMessageLogger(__FILE__, 216, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "QXcbConnection: XCB_RANDR_NOTIFY_CRTC_CHANGE:" << crtc.crtc << "mode" << crtc.mode << "relevant screen" << screen;
| 0 | ||||||||||||||||||
| 217 | << "mode" << crtc.mode << "relevant screen" << screen; never executed: QMessageLogger(__FILE__, 216, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "QXcbConnection: XCB_RANDR_NOTIFY_CRTC_CHANGE:" << crtc.crtc << "mode" << crtc.mode << "relevant screen" << screen; | 0 | ||||||||||||||||||
| 218 | // Only update geometry when there's a valid mode on the CRTC | - | ||||||||||||||||||
| 219 | // CRTC with node mode could mean that output has been disabled, and we'll | - | ||||||||||||||||||
| 220 | // get RRNotifyOutputChange notification for that. | - | ||||||||||||||||||
| 221 | if (screen && crtc.mode) {
| 0 | ||||||||||||||||||
| 222 | if (crtc.rotation == XCB_RANDR_ROTATION_ROTATE_90 ||
| 0 | ||||||||||||||||||
| 223 | crtc.rotation == XCB_RANDR_ROTATION_ROTATE_270)
| 0 | ||||||||||||||||||
| 224 | std::swap(crtc.width, crtc.height); never executed: std::swap(crtc.width, crtc.height); | 0 | ||||||||||||||||||
| 225 | screen->updateGeometry(QRect(crtc.x, crtc.y, crtc.width, crtc.height), crtc.rotation); | - | ||||||||||||||||||
| 226 | if (screen->mode() != crtc.mode)
| 0 | ||||||||||||||||||
| 227 | screen->updateRefreshRate(crtc.mode); never executed: screen->updateRefreshRate(crtc.mode); | 0 | ||||||||||||||||||
| 228 | } never executed: end of block | 0 | ||||||||||||||||||
| 229 | - | |||||||||||||||||||
| 230 | } else if (event->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) { never executed: end of block
| 0 | ||||||||||||||||||
| 231 | xcb_randr_output_change_t output = event->u.oc; | - | ||||||||||||||||||
| 232 | QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(output.window); | - | ||||||||||||||||||
| 233 | if (!virtualDesktop)
| 0 | ||||||||||||||||||
| 234 | // Not for us | - | ||||||||||||||||||
| 235 | return; never executed: return; | 0 | ||||||||||||||||||
| 236 | - | |||||||||||||||||||
| 237 | QXcbScreen *screen = findScreenForOutput(output.window, output.output); | - | ||||||||||||||||||
| 238 | qCDebug(lcQpaScreen) << "QXcbConnection: XCB_RANDR_NOTIFY_OUTPUT_CHANGE:" << output.output; never executed: QMessageLogger(__FILE__, 238, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "QXcbConnection: XCB_RANDR_NOTIFY_OUTPUT_CHANGE:" << output.output;
| 0 | ||||||||||||||||||
| 239 | - | |||||||||||||||||||
| 240 | if (screen && output.connection == XCB_RANDR_CONNECTION_DISCONNECTED) {
| 0 | ||||||||||||||||||
| 241 | qCDebug(lcQpaScreen) << "screen" << screen->name() << "has been disconnected"; never executed: QMessageLogger(__FILE__, 241, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "screen" << screen->name() << "has been disconnected";
| 0 | ||||||||||||||||||
| 242 | destroyScreen(screen); | - | ||||||||||||||||||
| 243 | } else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) { never executed: end of block
| 0 | ||||||||||||||||||
| 244 | // New XRandR output is available and it's enabled | - | ||||||||||||||||||
| 245 | if (output.crtc != XCB_NONE && output.mode != XCB_NONE) {
| 0 | ||||||||||||||||||
| 246 | xcb_randr_get_output_info_cookie_t outputInfoCookie = | - | ||||||||||||||||||
| 247 | xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); | - | ||||||||||||||||||
| 248 | QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo( | - | ||||||||||||||||||
| 249 | xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); | - | ||||||||||||||||||
| 250 | - | |||||||||||||||||||
| 251 | // Find a fake screen | - | ||||||||||||||||||
| 252 | foreachconst auto scrs = virtualDesktop->screens(); | - | ||||||||||||||||||
| 253 | for (QPlatformScreen *scr , virtualDesktop->screens()): scrs) { | - | ||||||||||||||||||
| 254 | QXcbScreen *xcbScreen = (QXcbScreen *)scr; | - | ||||||||||||||||||
| 255 | if (xcbScreen->output() == XCB_NONE) {
| 0 | ||||||||||||||||||
| 256 | screen = xcbScreen; | - | ||||||||||||||||||
| 257 | break; never executed: break; | 0 | ||||||||||||||||||
| 258 | } | - | ||||||||||||||||||
| 259 | } never executed: end of block | 0 | ||||||||||||||||||
| 260 | - | |||||||||||||||||||
| 261 | if (screen) {
| 0 | ||||||||||||||||||
| 262 | QString nameWas = screen->name(); | - | ||||||||||||||||||
| 263 | // Transform the fake screen into a physical screen | - | ||||||||||||||||||
| 264 | screen->setOutput(output.output, outputInfo.data()); | - | ||||||||||||||||||
| 265 | updateScreen(screen, output); | - | ||||||||||||||||||
| 266 | qCDebug(lcQpaScreen) << "output" << screen->name() never executed: QMessageLogger(__FILE__, 266, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "output" << screen->name() << "is connected and enabled; was fake:" << nameWas;
| 0 | ||||||||||||||||||
| 267 | << "is connected and enabled; was fake:" << nameWas; never executed: QMessageLogger(__FILE__, 266, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "output" << screen->name() << "is connected and enabled; was fake:" << nameWas; | 0 | ||||||||||||||||||
| 268 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 269 | screen = createScreen(virtualDesktop, output, outputInfo.data()); | - | ||||||||||||||||||
| 270 | qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; never executed: QMessageLogger(__FILE__, 270, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "output" << screen->name() << "is connected and enabled";
| 0 | ||||||||||||||||||
| 271 | } never executed: end of block | 0 | ||||||||||||||||||
| 272 | QHighDpiScaling::updateHighDpiScaling(); | - | ||||||||||||||||||
| 273 | } never executed: end of block | 0 | ||||||||||||||||||
| 274 | } else if (screen) { never executed: end of block
| 0 | ||||||||||||||||||
| 275 | if (output.crtc == XCB_NONE && output.mode == XCB_NONE) {
| 0 | ||||||||||||||||||
| 276 | // Screen has been disabled | - | ||||||||||||||||||
| 277 | xcb_randr_get_output_info_cookie_t outputInfoCookie = | - | ||||||||||||||||||
| 278 | xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); | - | ||||||||||||||||||
| 279 | QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo( | - | ||||||||||||||||||
| 280 | xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); | - | ||||||||||||||||||
| 281 | if (outputInfo->crtc == XCB_NONE) {
| 0 | ||||||||||||||||||
| 282 | qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled"; never executed: QMessageLogger(__FILE__, 282, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "output" << screen->name() << "has been disabled";
| 0 | ||||||||||||||||||
| 283 | destroyScreen(screen); | - | ||||||||||||||||||
| 284 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 285 | qCDebug(lcQpaScreen) << "output" << screen->name() << "has been temporarily disabled for the mode switch"; never executed: QMessageLogger(__FILE__, 285, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "output" << screen->name() << "has been temporarily disabled for the mode switch";
| 0 | ||||||||||||||||||
| 286 | // Reset crtc to skip RRCrtcChangeNotify events, | - | ||||||||||||||||||
| 287 | // because they may be invalid in the middle of the mode switch | - | ||||||||||||||||||
| 288 | screen->setCrtc(XCB_NONE); | - | ||||||||||||||||||
| 289 | } never executed: end of block | 0 | ||||||||||||||||||
| 290 | } else { | - | ||||||||||||||||||
| 291 | updateScreen(screen, output); | - | ||||||||||||||||||
| 292 | qCDebug(lcQpaScreen) << "output has changed" << screen; never executed: QMessageLogger(__FILE__, 292, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "output has changed" << screen;
| 0 | ||||||||||||||||||
| 293 | } never executed: end of block | 0 | ||||||||||||||||||
| 294 | } | - | ||||||||||||||||||
| 295 | - | |||||||||||||||||||
| 296 | qCDebug(lcQpaScreen) << "primary output is" << qAsConst(m_screens.).first()->name(); never executed: QMessageLogger(__FILE__, 296, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "primary output is" << qAsConst(m_screens).first()->name();
| 0 | ||||||||||||||||||
| 297 | } never executed: end of block | 0 | ||||||||||||||||||
| 298 | } never executed: end of block | 0 | ||||||||||||||||||
| 299 | - | |||||||||||||||||||
| 300 | bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output) | - | ||||||||||||||||||
| 301 | { | - | ||||||||||||||||||
| 302 | xcb_generic_error_t *error = 0; | - | ||||||||||||||||||
| 303 | xcb_randr_get_output_primary_cookie_t primaryCookie = | - | ||||||||||||||||||
| 304 | xcb_randr_get_output_primary(xcb_connection(), rootWindow); | - | ||||||||||||||||||
| 305 | QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary ( | - | ||||||||||||||||||
| 306 | xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error)); | - | ||||||||||||||||||
| 307 | if (!primary || error) { | - | ||||||||||||||||||
| 308 | qWarning("failed to get the primary output of the screen"); | - | ||||||||||||||||||
| 309 | free(error); | - | ||||||||||||||||||
| 310 | error = NULL; | - | ||||||||||||||||||
| 311 | } | - | ||||||||||||||||||
| 312 | const bool isPrimary = primary ? (primary->output == output) : false; | - | ||||||||||||||||||
| 313 | - | |||||||||||||||||||
| 314 | return isPrimary; | - | ||||||||||||||||||
| 315 | } | - | ||||||||||||||||||
| 316 | - | |||||||||||||||||||
| 317 | void QXcbConnection::updateScreen(QXcbScreen *screen, const xcb_randr_output_change_t &outputChange) | - | ||||||||||||||||||
| 318 | { | - | ||||||||||||||||||
| 319 | screen->setCrtc(outputChange.crtc); // Set the new crtc, because it can be invalid | - | ||||||||||||||||||
| 320 | screen->updateGeometry(outputChange.config_timestamp); | - | ||||||||||||||||||
| 321 | if (screen->mode() != outputChange.mode)
| 0 | ||||||||||||||||||
| 322 | screen->updateRefreshRate(outputChange.mode); never executed: screen->updateRefreshRate(outputChange.mode); | 0 | ||||||||||||||||||
| 323 | // Only screen which belongs to the primary virtual desktop can be a primary screen | - | ||||||||||||||||||
| 324 | if (screen->screenNumber() == m_primaryScreenNumber) {
| 0 | ||||||||||||||||||
| 325 | if (!screen->isPrimary() && checkOutputIsPrimary(outputChange.window, outputChange.output)) {
| 0 | ||||||||||||||||||
| 326 | screen->setPrimary(true); | - | ||||||||||||||||||
| 327 | - | |||||||||||||||||||
| 328 | // If the screen became primary, reshuffle the order in QGuiApplicationPrivate | - | ||||||||||||||||||
| 329 | const int idx = m_screens.indexOf(screen); | - | ||||||||||||||||||
| 330 | if (idx > 0) {
| 0 | ||||||||||||||||||
| 331 | qAsConst(m_screens.).first()->setPrimary(false); | - | ||||||||||||||||||
| 332 | m_screens.swap(0, idx); | - | ||||||||||||||||||
| 333 | } never executed: end of block | 0 | ||||||||||||||||||
| 334 | screen->virtualDesktop()->setPrimaryScreen(screen); | - | ||||||||||||||||||
| 335 | QXcbIntegration::instance()->setPrimaryScreen(screen); | - | ||||||||||||||||||
| 336 | } never executed: end of block | 0 | ||||||||||||||||||
| 337 | } never executed: end of block | 0 | ||||||||||||||||||
| 338 | } never executed: end of block | 0 | ||||||||||||||||||
| 339 | - | |||||||||||||||||||
| 340 | QXcbScreen *QXcbConnection::createScreen(QXcbVirtualDesktop *virtualDesktop, | - | ||||||||||||||||||
| 341 | const xcb_randr_output_change_t &outputChange, | - | ||||||||||||||||||
| 342 | xcb_randr_get_output_info_reply_t *outputInfo) | - | ||||||||||||||||||
| 343 | { | - | ||||||||||||||||||
| 344 | QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputChange.output, outputInfo); | - | ||||||||||||||||||
| 345 | // Only screen which belongs to the primary virtual desktop can be a primary screen | - | ||||||||||||||||||
| 346 | if (screen->screenNumber() == m_primaryScreenNumber)
| 0 | ||||||||||||||||||
| 347 | screen->setPrimary(checkOutputIsPrimary(outputChange.window, outputChange.output)); never executed: screen->setPrimary(checkOutputIsPrimary(outputChange.window, outputChange.output)); | 0 | ||||||||||||||||||
| 348 | - | |||||||||||||||||||
| 349 | if (screen->isPrimary()) {
| 0 | ||||||||||||||||||
| 350 | if (!m_screens.isEmpty())
| 0 | ||||||||||||||||||
| 351 | qAsConst(m_screens.).first()->setPrimary(false); never executed: qAsConst(m_screens).first()->setPrimary(false); | 0 | ||||||||||||||||||
| 352 | - | |||||||||||||||||||
| 353 | m_screens.prepend(screen); | - | ||||||||||||||||||
| 354 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 355 | m_screens.append(screen); | - | ||||||||||||||||||
| 356 | } never executed: end of block | 0 | ||||||||||||||||||
| 357 | virtualDesktop->addScreen(screen); | - | ||||||||||||||||||
| 358 | QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary()); | - | ||||||||||||||||||
| 359 | - | |||||||||||||||||||
| 360 | return screen; never executed: return screen; | 0 | ||||||||||||||||||
| 361 | } | - | ||||||||||||||||||
| 362 | - | |||||||||||||||||||
| 363 | void QXcbConnection::destroyScreen(QXcbScreen *screen) | - | ||||||||||||||||||
| 364 | { | - | ||||||||||||||||||
| 365 | QXcbVirtualDesktop *virtualDesktop = screen->virtualDesktop(); | - | ||||||||||||||||||
| 366 | if (virtualDesktop->screens().count() == 1) { | - | ||||||||||||||||||
| 367 | // If there are no other screens on the same virtual desktop, | - | ||||||||||||||||||
| 368 | // then transform the physical screen into a fake screen. | - | ||||||||||||||||||
| 369 | const QString nameWas = screen->name(); | - | ||||||||||||||||||
| 370 | screen->setOutput(XCB_NONE, Q_NULLPTR); | - | ||||||||||||||||||
| 371 | qCDebug(lcQpaScreen) << "transformed" << nameWas << "to fake" << screen; | - | ||||||||||||||||||
| 372 | } else { | - | ||||||||||||||||||
| 373 | // There is more than one screen on the same virtual desktop, remove the screen | - | ||||||||||||||||||
| 374 | m_screens.removeOne(screen); | - | ||||||||||||||||||
| 375 | virtualDesktop->removeScreen(screen); | - | ||||||||||||||||||
| 376 | - | |||||||||||||||||||
| 377 | // When primary screen is removed, set the new primary screen | - | ||||||||||||||||||
| 378 | // which belongs to the primary virtual desktop. | - | ||||||||||||||||||
| 379 | if (screen->isPrimary()) { | - | ||||||||||||||||||
| 380 | QXcbScreen *newPrimary = (QXcbScreen *)virtualDesktop->screens().at(0); | - | ||||||||||||||||||
| 381 | newPrimary->setPrimary(true); | - | ||||||||||||||||||
| 382 | const int idx = m_screens.indexOf(newPrimary); | - | ||||||||||||||||||
| 383 | if (idx > 0) | - | ||||||||||||||||||
| 384 | m_screens.swap(0, idx); | - | ||||||||||||||||||
| 385 | QXcbIntegration::instance()->setPrimaryScreen(newPrimary); | - | ||||||||||||||||||
| 386 | } | - | ||||||||||||||||||
| 387 | - | |||||||||||||||||||
| 388 | QXcbIntegration::instance()->destroyScreen(screen); | - | ||||||||||||||||||
| 389 | } | - | ||||||||||||||||||
| 390 | } | - | ||||||||||||||||||
| 391 | - | |||||||||||||||||||
| 392 | void QXcbConnection::initializeScreens() | - | ||||||||||||||||||
| 393 | { | - | ||||||||||||||||||
| 394 | xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); | - | ||||||||||||||||||
| 395 | int xcbScreenNumber = 0; // screen number in the xcb sense | - | ||||||||||||||||||
| 396 | QXcbScreen *primaryScreen = Q_NULLPTR; | - | ||||||||||||||||||
| 397 | while (it.rem) {
| 135 | ||||||||||||||||||
| 398 | // Each "screen" in xcb terminology is a virtual desktop, | - | ||||||||||||||||||
| 399 | // potentially a collection of separate juxtaposed monitors. | - | ||||||||||||||||||
| 400 | // But we want a separate QScreen for each output (e.g. DVI-I-1, VGA-1, etc.) | - | ||||||||||||||||||
| 401 | // which will become virtual siblings. | - | ||||||||||||||||||
| 402 | xcb_screen_t *xcbScreen = it.data; | - | ||||||||||||||||||
| 403 | QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber); | - | ||||||||||||||||||
| 404 | m_virtualDesktops.append(virtualDesktop); | - | ||||||||||||||||||
| 405 | QList<QPlatformScreen *> siblings; | - | ||||||||||||||||||
| 406 | if (has_randr_extension) {
| 0-135 | ||||||||||||||||||
| 407 | xcb_generic_error_t *error = NULL; | - | ||||||||||||||||||
| 408 | // RRGetScreenResourcesCurrent is fast but it may return nothing if the | - | ||||||||||||||||||
| 409 | // configuration is not initialized wrt to the hardware. We should call | - | ||||||||||||||||||
| 410 | // RRGetScreenResources in this case. | - | ||||||||||||||||||
| 411 | QScopedPointer<xcb_randr_get_screen_resources_reply_t, QScopedPointerPodDeleter> resources; | - | ||||||||||||||||||
| 412 | xcb_randr_get_screen_resources_current_cookie_t resourcesCookie = | - | ||||||||||||||||||
| 413 | xcb_randr_get_screen_resources_current(xcb_connection(), xcbScreen->root); | - | ||||||||||||||||||
| 414 | QScopedPointer<xcb_randr_get_screen_resources_current_reply_t, QScopedPointerPodDeleter> resources_current( | - | ||||||||||||||||||
| 415 | xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, &error)); | - | ||||||||||||||||||
| 416 | if (!resources_current || error) {
| 0-135 | ||||||||||||||||||
| 417 | qWarning("failed to get the current screen resources"); | - | ||||||||||||||||||
| 418 | free(error); | - | ||||||||||||||||||
| 419 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 420 | xcb_timestamp_t timestamp; | - | ||||||||||||||||||
| 421 | xcb_randr_output_t *outputs = Q_NULLPTR; | - | ||||||||||||||||||
| 422 | int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data()); | - | ||||||||||||||||||
| 423 | if (outputCount) {
| 0-135 | ||||||||||||||||||
| 424 | timestamp = resources_current->config_timestamp; | - | ||||||||||||||||||
| 425 | outputs = xcb_randr_get_screen_resources_current_outputs(resources_current.data()); | - | ||||||||||||||||||
| 426 | } else { executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 427 | xcb_randr_get_screen_resources_cookie_t resourcesCookie = | - | ||||||||||||||||||
| 428 | xcb_randr_get_screen_resources(xcb_connection(), xcbScreen->root); | - | ||||||||||||||||||
| 429 | resources.reset(xcb_randr_get_screen_resources_reply(xcb_connection(), resourcesCookie, &error)); | - | ||||||||||||||||||
| 430 | if (!resources || error) {
| 0 | ||||||||||||||||||
| 431 | qWarning("failed to get the screen resources"); | - | ||||||||||||||||||
| 432 | free(error); | - | ||||||||||||||||||
| 433 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 434 | timestamp = resources->config_timestamp; | - | ||||||||||||||||||
| 435 | outputCount = xcb_randr_get_screen_resources_outputs_length(resources.data()); | - | ||||||||||||||||||
| 436 | outputs = xcb_randr_get_screen_resources_outputs(resources.data()); | - | ||||||||||||||||||
| 437 | } never executed: end of block | 0 | ||||||||||||||||||
| 438 | } | - | ||||||||||||||||||
| 439 | - | |||||||||||||||||||
| 440 | if (outputCount) {
| 0-135 | ||||||||||||||||||
| 441 | xcb_randr_get_output_primary_cookie_t primaryCookie = | - | ||||||||||||||||||
| 442 | xcb_randr_get_output_primary(xcb_connection(), xcbScreen->root); | - | ||||||||||||||||||
| 443 | QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary( | - | ||||||||||||||||||
| 444 | xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error)); | - | ||||||||||||||||||
| 445 | if (!primary || error) {
| 0-135 | ||||||||||||||||||
| 446 | qWarning("failed to get the primary output of the screen"); | - | ||||||||||||||||||
| 447 | free(error); | - | ||||||||||||||||||
| 448 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 449 | for (int i = 0; i < outputCount; i++) {
| 135-1080 | ||||||||||||||||||
| 450 | QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> output( | - | ||||||||||||||||||
| 451 | xcb_randr_get_output_info_reply(xcb_connection(), | - | ||||||||||||||||||
| 452 | xcb_randr_get_output_info_unchecked(xcb_connection(), outputs[i], timestamp), NULL)); | - | ||||||||||||||||||
| 453 | - | |||||||||||||||||||
| 454 | // Invalid, disconnected or disabled output | - | ||||||||||||||||||
| 455 | if (output == NULL)
| 0-1080 | ||||||||||||||||||
| 456 | continue; never executed: continue; | 0 | ||||||||||||||||||
| 457 | - | |||||||||||||||||||
| 458 | if (output->connection != XCB_RANDR_CONNECTION_CONNECTED) {
| 135-945 | ||||||||||||||||||
| 459 | qCDebug(lcQpaScreen, "Output %s is not connected", qPrintable( never executed: QMessageLogger( __FILE__ , 461 , __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug("Output %s is not connected", QString(QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), xcb_randr_get_output_info_name_length(output.data()))).toLocal8Bit().constData()) ;
| 0-945 | ||||||||||||||||||
| 460 | QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), never executed: QMessageLogger( __FILE__ , 461 , __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug("Output %s is not connected", QString(QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), xcb_randr_get_output_info_name_length(output.data()))).toLocal8Bit().constData()) ; | 0 | ||||||||||||||||||
| 461 | xcb_randr_get_output_info_name_length(output.data())))); never executed: QMessageLogger( __FILE__ , 461 , __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug("Output %s is not connected", QString(QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), xcb_randr_get_output_info_name_length(output.data()))).toLocal8Bit().constData()) ; | 0 | ||||||||||||||||||
| 462 | continue; executed 945 times by 5 tests: continue;Executed by:
| 945 | ||||||||||||||||||
| 463 | } | - | ||||||||||||||||||
| 464 | - | |||||||||||||||||||
| 465 | if (output->crtc == XCB_NONE) {
| 0-135 | ||||||||||||||||||
| 466 | qCDebug(lcQpaScreen, "Output %s is not enabled", qPrintable( never executed: QMessageLogger( __FILE__ , 468 , __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug("Output %s is not enabled", QString(QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), xcb_randr_get_output_info_name_length(output.data()))).toLocal8Bit().constData()) ;
| 0 | ||||||||||||||||||
| 467 | QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), never executed: QMessageLogger( __FILE__ , 468 , __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug("Output %s is not enabled", QString(QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), xcb_randr_get_output_info_name_length(output.data()))).toLocal8Bit().constData()) ; | 0 | ||||||||||||||||||
| 468 | xcb_randr_get_output_info_name_length(output.data())))); never executed: QMessageLogger( __FILE__ , 468 , __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug("Output %s is not enabled", QString(QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), xcb_randr_get_output_info_name_length(output.data()))).toLocal8Bit().constData()) ; | 0 | ||||||||||||||||||
| 469 | continue; never executed: continue; | 0 | ||||||||||||||||||
| 470 | } | - | ||||||||||||||||||
| 471 | - | |||||||||||||||||||
| 472 | QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputs[i], output.data()); | - | ||||||||||||||||||
| 473 | siblings << screen; | - | ||||||||||||||||||
| 474 | m_screens << screen; | - | ||||||||||||||||||
| 475 | - | |||||||||||||||||||
| 476 | // There can be multiple outputs per screen, use either | - | ||||||||||||||||||
| 477 | // the first or an exact match. An exact match isn't | - | ||||||||||||||||||
| 478 | // always available if primary->output is XCB_NONE | - | ||||||||||||||||||
| 479 | // or currently disconnected output. | - | ||||||||||||||||||
| 480 | if (m_primaryScreenNumber == xcbScreenNumber) {
| 0-135 | ||||||||||||||||||
| 481 | if (!primaryScreen || (primary && outputs[i] == primary->output)) {
| 0-135 | ||||||||||||||||||
| 482 | if (primaryScreen)
| 0-135 | ||||||||||||||||||
| 483 | primaryScreen->setPrimary(false); never executed: primaryScreen->setPrimary(false); | 0 | ||||||||||||||||||
| 484 | primaryScreen = screen; | - | ||||||||||||||||||
| 485 | primaryScreen->setPrimary(true); | - | ||||||||||||||||||
| 486 | siblings.prepend(siblings.takeLast()); | - | ||||||||||||||||||
| 487 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 488 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 489 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 490 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 491 | } | - | ||||||||||||||||||
| 492 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 493 | } else if (has_xinerama_extension) {
| 0 | ||||||||||||||||||
| 494 | // Xinerama is available | - | ||||||||||||||||||
| 495 | xcb_xinerama_query_screens_cookie_t cookie = xcb_xinerama_query_screens(m_connection); | - | ||||||||||||||||||
| 496 | xcb_xinerama_query_screens_reply_t *screens = xcb_xinerama_query_screens_reply(m_connection, | - | ||||||||||||||||||
| 497 | cookie, | - | ||||||||||||||||||
| 498 | Q_NULLPTR); | - | ||||||||||||||||||
| 499 | if (screens) {
| 0 | ||||||||||||||||||
| 500 | xcb_xinerama_screen_info_iterator_t it = xcb_xinerama_query_screens_screen_info_iterator(screens); | - | ||||||||||||||||||
| 501 | while (it.rem) {
| 0 | ||||||||||||||||||
| 502 | xcb_xinerama_screen_info_t *screen_info = it.data; | - | ||||||||||||||||||
| 503 | QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, | - | ||||||||||||||||||
| 504 | XCB_NONE, Q_NULLPTR, | - | ||||||||||||||||||
| 505 | screen_info, it.index); | - | ||||||||||||||||||
| 506 | siblings << screen; | - | ||||||||||||||||||
| 507 | m_screens << screen; | - | ||||||||||||||||||
| 508 | xcb_xinerama_screen_info_next(&it); | - | ||||||||||||||||||
| 509 | } never executed: end of block | 0 | ||||||||||||||||||
| 510 | free(screens); | - | ||||||||||||||||||
| 511 | } never executed: end of block | 0 | ||||||||||||||||||
| 512 | } never executed: end of block | 0 | ||||||||||||||||||
| 513 | if (siblings.isEmpty()) {
| 0-135 | ||||||||||||||||||
| 514 | // If there are no XRandR outputs or XRandR extension is missing, | - | ||||||||||||||||||
| 515 | // then create a fake/legacy screen. | - | ||||||||||||||||||
| 516 | QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, XCB_NONE, Q_NULLPTR); | - | ||||||||||||||||||
| 517 | qCDebug(lcQpaScreen) << "created fake screen" << screen; never executed: QMessageLogger(__FILE__, 517, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "created fake screen" << screen;
| 0 | ||||||||||||||||||
| 518 | m_screens << screen; | - | ||||||||||||||||||
| 519 | if (m_primaryScreenNumber == xcbScreenNumber) {
| 0 | ||||||||||||||||||
| 520 | primaryScreen = screen; | - | ||||||||||||||||||
| 521 | primaryScreen->setPrimary(true); | - | ||||||||||||||||||
| 522 | } never executed: end of block | 0 | ||||||||||||||||||
| 523 | siblings << screen; | - | ||||||||||||||||||
| 524 | } never executed: end of block | 0 | ||||||||||||||||||
| 525 | virtualDesktop->setScreens(siblings); | - | ||||||||||||||||||
| 526 | xcb_screen_next(&it); | - | ||||||||||||||||||
| 527 | ++xcbScreenNumber; | - | ||||||||||||||||||
| 528 | } // for each xcb screen executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 529 | - | |||||||||||||||||||
| 530 | foreachfor (QXcbVirtualDesktop *virtualDesktop ,: qAsConst(m_virtualDesktops))) | - | ||||||||||||||||||
| 531 | virtualDesktop->subscribeToXFixesSelectionNotify(); executed 135 times by 5 tests: virtualDesktop->subscribeToXFixesSelectionNotify();Executed by:
| 135 | ||||||||||||||||||
| 532 | - | |||||||||||||||||||
| 533 | if (m_virtualDesktops.isEmpty()) {
| 0-135 | ||||||||||||||||||
| 534 | qFatal("QXcbConnection: no screens available"); | - | ||||||||||||||||||
| 535 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 536 | // Ensure the primary screen is first on the list | - | ||||||||||||||||||
| 537 | if (primaryScreen) {
| 0-135 | ||||||||||||||||||
| 538 | if (qAsConst(m_screens.).first() != primaryScreen) {
| 0-135 | ||||||||||||||||||
| 539 | m_screens.removeOne(primaryScreen); | - | ||||||||||||||||||
| 540 | m_screens.prepend(primaryScreen); | - | ||||||||||||||||||
| 541 | } never executed: end of block | 0 | ||||||||||||||||||
| 542 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 543 | - | |||||||||||||||||||
| 544 | // Push the screens to QGuiApplication | - | ||||||||||||||||||
| 545 | foreachfor (QXcbScreen *screen ,: qAsConst(m_screens))) { | - | ||||||||||||||||||
| 546 | qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ")"; never executed: QMessageLogger(__FILE__, 546, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "adding" << screen << "(Primary:" << screen->isPrimary() << ")";
| 0-135 | ||||||||||||||||||
| 547 | QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary()); | - | ||||||||||||||||||
| 548 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 549 | - | |||||||||||||||||||
| 550 | qCDebug(lcQpaScreen) << "primary output is" << qAsConst(m_screens.).first()->name(); never executed: QMessageLogger(__FILE__, 550, __PRETTY_FUNCTION__, lcQpaScreen().categoryName()).debug() << "primary output is" << qAsConst(m_screens).first()->name();
| 0-135 | ||||||||||||||||||
| 551 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 552 | } | - | ||||||||||||||||||
| 553 | - | |||||||||||||||||||
| 554 | QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName) | - | ||||||||||||||||||
| 555 | : m_connection(0) | - | ||||||||||||||||||
| 556 | , m_canGrabServer(canGrabServer) | - | ||||||||||||||||||
| 557 | , m_defaultVisualId(defaultVisualId) | - | ||||||||||||||||||
| 558 | , m_primaryScreenNumber(0) | - | ||||||||||||||||||
| 559 | , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) | - | ||||||||||||||||||
| 560 | , m_nativeInterface(nativeInterface) | - | ||||||||||||||||||
| 561 | #ifdef XCB_USE_XLIB | - | ||||||||||||||||||
| 562 | , m_xlib_display(0) | - | ||||||||||||||||||
| 563 | #endif | - | ||||||||||||||||||
| 564 | , xfixes_first_event(0) | - | ||||||||||||||||||
| 565 | , xrandr_first_event(0) | - | ||||||||||||||||||
| 566 | , xkb_first_event(0) | - | ||||||||||||||||||
| 567 | , has_xinerama_extension(false) | - | ||||||||||||||||||
| 568 | , has_shape_extension(false) | - | ||||||||||||||||||
| 569 | , has_randr_extension(false) | - | ||||||||||||||||||
| 570 | , has_input_shape(false) | - | ||||||||||||||||||
| 571 | , has_xkb(false) | - | ||||||||||||||||||
| 572 | , m_buttons(0) | - | ||||||||||||||||||
| 573 | , m_focusWindow(0) | - | ||||||||||||||||||
| 574 | , m_mouseGrabber(0) | - | ||||||||||||||||||
| 575 | , m_mousePressWindow(0) | - | ||||||||||||||||||
| 576 | , m_clientLeader(0) | - | ||||||||||||||||||
| 577 | , m_systemTrayTracker(0) | - | ||||||||||||||||||
| 578 | , m_glIntegration(Q_NULLPTR) | - | ||||||||||||||||||
| 579 | , m_xiGrab(false) | - | ||||||||||||||||||
| 580 | , m_qtSelectionOwner(0) | - | ||||||||||||||||||
| 581 | { | - | ||||||||||||||||||
| 582 | #ifdef XCB_USE_XLIB | - | ||||||||||||||||||
| 583 | Display *dpy = XOpenDisplay(m_displayName.constData()); | - | ||||||||||||||||||
| 584 | if (dpy) {
| 0-135 | ||||||||||||||||||
| 585 | m_primaryScreenNumber = DefaultScreen(dpy); | - | ||||||||||||||||||
| 586 | m_connection = XGetXCBConnection(dpy); | - | ||||||||||||||||||
| 587 | XSetEventQueueOwner(dpy, XCBOwnsEventQueue); | - | ||||||||||||||||||
| 588 | XSetErrorHandler(nullErrorHandler); | - | ||||||||||||||||||
| 589 | XSetIOErrorHandler(ioErrorHandler); | - | ||||||||||||||||||
| 590 | m_xlib_display = dpy; | - | ||||||||||||||||||
| 591 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 592 | #else | - | ||||||||||||||||||
| 593 | m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber); | - | ||||||||||||||||||
| 594 | #endif //XCB_USE_XLIB | - | ||||||||||||||||||
| 595 | - | |||||||||||||||||||
| 596 | if (Q_UNLIKELY(!m_connection || xcb_connection_has_error(m_connection)))))
| 0-135 | ||||||||||||||||||
| 597 | qFatal("QXcbConnection: Could not connect to display %s", m_displayName.constData()); never executed: QMessageLogger(__FILE__, 597, __PRETTY_FUNCTION__).fatal("QXcbConnection: Could not connect to display %s", m_displayName.constData()); | 0 | ||||||||||||||||||
| 598 | - | |||||||||||||||||||
| 599 | - | |||||||||||||||||||
| 600 | m_reader = new QXcbEventReader(this); | - | ||||||||||||||||||
| 601 | m_reader->start(); | - | ||||||||||||||||||
| 602 | - | |||||||||||||||||||
| 603 | xcb_extension_t *extensions[] = { | - | ||||||||||||||||||
| 604 | &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id, | - | ||||||||||||||||||
| 605 | #ifndef QT_NO_XKB | - | ||||||||||||||||||
| 606 | &xcb_xkb_id, | - | ||||||||||||||||||
| 607 | #endif | - | ||||||||||||||||||
| 608 | #ifdef XCB_USE_RENDER | - | ||||||||||||||||||
| 609 | &xcb_render_id, | - | ||||||||||||||||||
| 610 | #endif | - | ||||||||||||||||||
| 611 | 0 | - | ||||||||||||||||||
| 612 | }; | - | ||||||||||||||||||
| 613 | - | |||||||||||||||||||
| 614 | for (xcb_extension_t **ext_it = extensions; *ext_it; ++ext_it)
| 135-945 | ||||||||||||||||||
| 615 | xcb_prefetch_extension_data (m_connection, *ext_it); executed 945 times by 5 tests: xcb_prefetch_extension_data (m_connection, *ext_it);Executed by:
| 945 | ||||||||||||||||||
| 616 | - | |||||||||||||||||||
| 617 | m_setup = xcb_get_setup(xcb_connection()); | - | ||||||||||||||||||
| 618 | - | |||||||||||||||||||
| 619 | initializeAllAtoms(); | - | ||||||||||||||||||
| 620 | - | |||||||||||||||||||
| 621 | m_time = XCB_CURRENT_TIME; | - | ||||||||||||||||||
| 622 | m_netWmUserTime = XCB_CURRENT_TIME; | - | ||||||||||||||||||
| 623 | - | |||||||||||||||||||
| 624 | if (!qEnvironmentVariableIsSet("QT_XCB_NO_XRANDR"))
| 0-135 | ||||||||||||||||||
| 625 | initializeXRandr(); executed 135 times by 5 tests: initializeXRandr();Executed by:
| 135 | ||||||||||||||||||
| 626 | if (!has_randr_extension)
| 0-135 | ||||||||||||||||||
| 627 | initializeXinerama(); never executed: initializeXinerama(); | 0 | ||||||||||||||||||
| 628 | initializeXFixes(); | - | ||||||||||||||||||
| 629 | initializeScreens(); | - | ||||||||||||||||||
| 630 | - | |||||||||||||||||||
| 631 | initializeXRender(); | - | ||||||||||||||||||
| 632 | #if defined(XCB_USE_XINPUT2) | - | ||||||||||||||||||
| 633 | m_xi2Enabled = false; | - | ||||||||||||||||||
| 634 | if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2"))initializeXInput2(); | - | ||||||||||||||||||
| 635 | #endif | - | ||||||||||||||||||
| 636 | initializeXShape(); | - | ||||||||||||||||||
| 637 | initializeXKB(); | - | ||||||||||||||||||
| 638 | - | |||||||||||||||||||
| 639 | m_wmSupport.reset(new QXcbWMSupport(this)); | - | ||||||||||||||||||
| 640 | m_keyboard = new QXcbKeyboard(this); | - | ||||||||||||||||||
| 641 | #ifndef QT_NO_CLIPBOARD | - | ||||||||||||||||||
| 642 | m_clipboard = new QXcbClipboard(this); | - | ||||||||||||||||||
| 643 | #endif | - | ||||||||||||||||||
| 644 | #ifndef QT_NO_DRAGANDDROP | - | ||||||||||||||||||
| 645 | m_drag = new QXcbDrag(this); | - | ||||||||||||||||||
| 646 | #endif | - | ||||||||||||||||||
| 647 | - | |||||||||||||||||||
| 648 | m_startupId = qgetenv("DESKTOP_STARTUP_ID"); | - | ||||||||||||||||||
| 649 | if (!m_startupId.isNull())
| 0-135 | ||||||||||||||||||
| 650 | qunsetenv("DESKTOP_STARTUP_ID"); never executed: qunsetenv("DESKTOP_STARTUP_ID"); | 0 | ||||||||||||||||||
| 651 | - | |||||||||||||||||||
| 652 | - | |||||||||||||||||||
| 653 | QStringList glIntegrationNames; | - | ||||||||||||||||||
| 654 | glIntegrationNames << QStringLiteral("xcb_glx") << QStringLiteral("xcb_egl"); executed 135 times by 5 tests: return qstring_literal_temp;Executed by:
| 135 | ||||||||||||||||||
| 655 | QString glIntegrationName = QString::fromLocal8Bit(qgetenv("QT_XCB_GL_INTEGRATION")); | - | ||||||||||||||||||
| 656 | if (!glIntegrationName.isEmpty()) {
| 0-135 | ||||||||||||||||||
| 657 | qCDebug(QT_XCB_GLINTEGRATIONlcQpaGl) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName; never executed: QMessageLogger(__FILE__, 657, __PRETTY_FUNCTION__, lcQpaGl().categoryName()).debug() << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName;
| 0 | ||||||||||||||||||
| 658 | if (glIntegrationName != QLatin1String("none")) {
| 0 | ||||||||||||||||||
| 659 | glIntegrationNames.removeAll(glIntegrationName); | - | ||||||||||||||||||
| 660 | glIntegrationNames.prepend(glIntegrationName); | - | ||||||||||||||||||
| 661 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 662 | glIntegrationNames.clear(); | - | ||||||||||||||||||
| 663 | } never executed: end of block | 0 | ||||||||||||||||||
| 664 | } | - | ||||||||||||||||||
| 665 | - | |||||||||||||||||||
| 666 | if (!glIntegrationNames.isEmpty()) {
| 0-135 | ||||||||||||||||||
| 667 | qCDebug(QT_XCB_GLINTEGRATIONlcQpaGl) << "Choosing xcb gl-integration based on following priority\n" << glIntegrationNames; never executed: QMessageLogger(__FILE__, 667, __PRETTY_FUNCTION__, lcQpaGl().categoryName()).debug() << "Choosing xcb gl-integration based on following priority\n" << glIntegrationNames;
| 0-135 | ||||||||||||||||||
| 668 | for (int i = 0; i < glIntegrationNames.size() && !m_glIntegration; i++) {
| 0-270 | ||||||||||||||||||
| 669 | m_glIntegration = QXcbGlIntegrationFactory::create(glIntegrationNames.at(i)); | - | ||||||||||||||||||
| 670 | if (m_glIntegration && !m_glIntegration->initialize(this)) {
| 0-135 | ||||||||||||||||||
| 671 | qCDebug(QT_XCB_GLINTEGRATIONlcQpaGl) << "Failed to initialize xcb gl-integration" << glIntegrationNames.at(i); never executed: QMessageLogger(__FILE__, 671, __PRETTY_FUNCTION__, lcQpaGl().categoryName()).debug() << "Failed to initialize xcb gl-integration" << glIntegrationNames.at(i);
| 0 | ||||||||||||||||||
| 672 | delete m_glIntegration; | - | ||||||||||||||||||
| 673 | m_glIntegration = Q_NULLPTR; | - | ||||||||||||||||||
| 674 | } never executed: end of block | 0 | ||||||||||||||||||
| 675 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 676 | if (!m_glIntegration)
| 0-135 | ||||||||||||||||||
| 677 | qCDebug(QT_XCB_GLINTEGRATIONlcQpaGl) << "Failed to create xcb gl-integration"; never executed: QMessageLogger(__FILE__, 677, __PRETTY_FUNCTION__, lcQpaGl().categoryName()).debug() << "Failed to create xcb gl-integration";
| 0 | ||||||||||||||||||
| 678 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 679 | - | |||||||||||||||||||
| 680 | sync(); | - | ||||||||||||||||||
| 681 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 682 | - | |||||||||||||||||||
| 683 | QXcbConnection::~QXcbConnection() | - | ||||||||||||||||||
| 684 | { | - | ||||||||||||||||||
| 685 | #ifndef QT_NO_CLIPBOARD | - | ||||||||||||||||||
| 686 | delete m_clipboard; | - | ||||||||||||||||||
| 687 | #endif | - | ||||||||||||||||||
| 688 | #ifndef QT_NO_DRAGANDDROP | - | ||||||||||||||||||
| 689 | delete m_drag; | - | ||||||||||||||||||
| 690 | #endif | - | ||||||||||||||||||
| 691 | - | |||||||||||||||||||
| 692 | #if defined(XCB_USE_XINPUT2) | - | ||||||||||||||||||
| 693 | finalizeXInput2(); | - | ||||||||||||||||||
| 694 | #endif | - | ||||||||||||||||||
| 695 | - | |||||||||||||||||||
| 696 | if (m_reader->isRunning()) { | - | ||||||||||||||||||
| 697 | sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION); | - | ||||||||||||||||||
| 698 | m_reader->wait(); | - | ||||||||||||||||||
| 699 | } | - | ||||||||||||||||||
| 700 | - | |||||||||||||||||||
| 701 | delete m_reader; | - | ||||||||||||||||||
| 702 | - | |||||||||||||||||||
| 703 | QXcbIntegration *integration = QXcbIntegration::instance(); | - | ||||||||||||||||||
| 704 | // Delete screens in reverse order to avoid crash in case of multiple screens | - | ||||||||||||||||||
| 705 | while (!m_screens.isEmpty()) | - | ||||||||||||||||||
| 706 | integration->destroyScreen(m_screens.takeLast()); | - | ||||||||||||||||||
| 707 | - | |||||||||||||||||||
| 708 | while (!m_virtualDesktops.isEmpty()) | - | ||||||||||||||||||
| 709 | delete m_virtualDesktops.takeLast(); | - | ||||||||||||||||||
| 710 | - | |||||||||||||||||||
| 711 | delete m_glIntegration; | - | ||||||||||||||||||
| 712 | - | |||||||||||||||||||
| 713 | #ifdef XCB_USE_XLIB | - | ||||||||||||||||||
| 714 | XCloseDisplay((Display *)m_xlib_display); | - | ||||||||||||||||||
| 715 | #else | - | ||||||||||||||||||
| 716 | xcb_disconnect(xcb_connection()); | - | ||||||||||||||||||
| 717 | #endif | - | ||||||||||||||||||
| 718 | - | |||||||||||||||||||
| 719 | delete m_keyboard; | - | ||||||||||||||||||
| 720 | } | - | ||||||||||||||||||
| 721 | - | |||||||||||||||||||
| 722 | QXcbScreen *QXcbConnection::primaryScreen() const | - | ||||||||||||||||||
| 723 | { | - | ||||||||||||||||||
| 724 | if (!m_screens.isEmpty()) { | - | ||||||||||||||||||
| 725 | Q_ASSERT(m_screens.first()->screenNumber() == primaryScreenNumber()); | - | ||||||||||||||||||
| 726 | return m_screens.first(); | - | ||||||||||||||||||
| 727 | } | - | ||||||||||||||||||
| 728 | - | |||||||||||||||||||
| 729 | return Q_NULLPTR; | - | ||||||||||||||||||
| 730 | } | - | ||||||||||||||||||
| 731 | - | |||||||||||||||||||
| 732 | void QXcbConnection::addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener) | - | ||||||||||||||||||
| 733 | { | - | ||||||||||||||||||
| 734 | m_mapper.insert(id, eventListener); | - | ||||||||||||||||||
| 735 | } | - | ||||||||||||||||||
| 736 | - | |||||||||||||||||||
| 737 | void QXcbConnection::removeWindowEventListener(xcb_window_t id) | - | ||||||||||||||||||
| 738 | { | - | ||||||||||||||||||
| 739 | m_mapper.remove(id); | - | ||||||||||||||||||
| 740 | } | - | ||||||||||||||||||
| 741 | - | |||||||||||||||||||
| 742 | QXcbWindowEventListener *QXcbConnection::windowEventListenerFromId(xcb_window_t id) | - | ||||||||||||||||||
| 743 | { | - | ||||||||||||||||||
| 744 | return m_mapper.value(id, 0); | - | ||||||||||||||||||
| 745 | } | - | ||||||||||||||||||
| 746 | - | |||||||||||||||||||
| 747 | QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id) | - | ||||||||||||||||||
| 748 | { | - | ||||||||||||||||||
| 749 | QXcbWindowEventListener *listener = m_mapper.value(id, 0); | - | ||||||||||||||||||
| 750 | if (listener) | - | ||||||||||||||||||
| 751 | return listener->toWindow(); | - | ||||||||||||||||||
| 752 | return 0; | - | ||||||||||||||||||
| 753 | } | - | ||||||||||||||||||
| 754 | - | |||||||||||||||||||
| 755 | #define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \ | - | ||||||||||||||||||
| 756 | { \ | - | ||||||||||||||||||
| 757 | event_t *e = (event_t *)event; \ | - | ||||||||||||||||||
| 758 | if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->windowMember)) { \ | - | ||||||||||||||||||
| 759 | handled = eventListener->handleGenericEvent(event, &result); \ | - | ||||||||||||||||||
| 760 | if (!handled) \ | - | ||||||||||||||||||
| 761 | eventListener->handler(e); \ | - | ||||||||||||||||||
| 762 | } \ | - | ||||||||||||||||||
| 763 | } \ | - | ||||||||||||||||||
| 764 | break; | - | ||||||||||||||||||
| 765 | - | |||||||||||||||||||
| 766 | #define HANDLE_KEYBOARD_EVENT(event_t, handler) \ | - | ||||||||||||||||||
| 767 | { \ | - | ||||||||||||||||||
| 768 | event_t *e = (event_t *)event; \ | - | ||||||||||||||||||
| 769 | if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \ | - | ||||||||||||||||||
| 770 | handled = eventListener->handleGenericEvent(event, &result); \ | - | ||||||||||||||||||
| 771 | if (!handled) \ | - | ||||||||||||||||||
| 772 | m_keyboard->handler(e); \ | - | ||||||||||||||||||
| 773 | } \ | - | ||||||||||||||||||
| 774 | } \ | - | ||||||||||||||||||
| 775 | break; | - | ||||||||||||||||||
| 776 | - | |||||||||||||||||||
| 777 | //#define XCB_EVENT_DEBUG | - | ||||||||||||||||||
| 778 | - | |||||||||||||||||||
| 779 | void printXcbEvent(const char *message, xcb_generic_event_t *event) | - | ||||||||||||||||||
| 780 | { | - | ||||||||||||||||||
| 781 | #ifdef XCB_EVENT_DEBUG | - | ||||||||||||||||||
| 782 | #define PRINT_XCB_EVENT(ev) \ | - | ||||||||||||||||||
| 783 | case ev: \ | - | ||||||||||||||||||
| 784 | qDebug("QXcbConnection: %s: %d - %s - sequence: %d", message, int(ev), #ev, event->sequence); \ | - | ||||||||||||||||||
| 785 | break; | - | ||||||||||||||||||
| 786 | - | |||||||||||||||||||
| 787 | switch (event->response_type & ~0x80) { | - | ||||||||||||||||||
| 788 | PRINT_XCB_EVENT(XCB_KEY_PRESS); | - | ||||||||||||||||||
| 789 | PRINT_XCB_EVENT(XCB_KEY_RELEASE); | - | ||||||||||||||||||
| 790 | PRINT_XCB_EVENT(XCB_BUTTON_PRESS); | - | ||||||||||||||||||
| 791 | PRINT_XCB_EVENT(XCB_BUTTON_RELEASE); | - | ||||||||||||||||||
| 792 | PRINT_XCB_EVENT(XCB_MOTION_NOTIFY); | - | ||||||||||||||||||
| 793 | PRINT_XCB_EVENT(XCB_ENTER_NOTIFY); | - | ||||||||||||||||||
| 794 | PRINT_XCB_EVENT(XCB_LEAVE_NOTIFY); | - | ||||||||||||||||||
| 795 | PRINT_XCB_EVENT(XCB_FOCUS_IN); | - | ||||||||||||||||||
| 796 | PRINT_XCB_EVENT(XCB_FOCUS_OUT); | - | ||||||||||||||||||
| 797 | PRINT_XCB_EVENT(XCB_KEYMAP_NOTIFY); | - | ||||||||||||||||||
| 798 | PRINT_XCB_EVENT(XCB_EXPOSE); | - | ||||||||||||||||||
| 799 | PRINT_XCB_EVENT(XCB_GRAPHICS_EXPOSURE); | - | ||||||||||||||||||
| 800 | PRINT_XCB_EVENT(XCB_NO_EXPOSURE); | - | ||||||||||||||||||
| 801 | PRINT_XCB_EVENT(XCB_VISIBILITY_NOTIFY); | - | ||||||||||||||||||
| 802 | PRINT_XCB_EVENT(XCB_CREATE_NOTIFY); | - | ||||||||||||||||||
| 803 | PRINT_XCB_EVENT(XCB_DESTROY_NOTIFY); | - | ||||||||||||||||||
| 804 | PRINT_XCB_EVENT(XCB_UNMAP_NOTIFY); | - | ||||||||||||||||||
| 805 | PRINT_XCB_EVENT(XCB_MAP_NOTIFY); | - | ||||||||||||||||||
| 806 | PRINT_XCB_EVENT(XCB_MAP_REQUEST); | - | ||||||||||||||||||
| 807 | PRINT_XCB_EVENT(XCB_REPARENT_NOTIFY); | - | ||||||||||||||||||
| 808 | PRINT_XCB_EVENT(XCB_CONFIGURE_NOTIFY); | - | ||||||||||||||||||
| 809 | PRINT_XCB_EVENT(XCB_CONFIGURE_REQUEST); | - | ||||||||||||||||||
| 810 | PRINT_XCB_EVENT(XCB_GRAVITY_NOTIFY); | - | ||||||||||||||||||
| 811 | PRINT_XCB_EVENT(XCB_RESIZE_REQUEST); | - | ||||||||||||||||||
| 812 | PRINT_XCB_EVENT(XCB_CIRCULATE_NOTIFY); | - | ||||||||||||||||||
| 813 | PRINT_XCB_EVENT(XCB_CIRCULATE_REQUEST); | - | ||||||||||||||||||
| 814 | PRINT_XCB_EVENT(XCB_PROPERTY_NOTIFY); | - | ||||||||||||||||||
| 815 | PRINT_XCB_EVENT(XCB_SELECTION_CLEAR); | - | ||||||||||||||||||
| 816 | PRINT_XCB_EVENT(XCB_SELECTION_REQUEST); | - | ||||||||||||||||||
| 817 | PRINT_XCB_EVENT(XCB_SELECTION_NOTIFY); | - | ||||||||||||||||||
| 818 | PRINT_XCB_EVENT(XCB_COLORMAP_NOTIFY); | - | ||||||||||||||||||
| 819 | PRINT_XCB_EVENT(XCB_CLIENT_MESSAGE); | - | ||||||||||||||||||
| 820 | PRINT_XCB_EVENT(XCB_MAPPING_NOTIFY); | - | ||||||||||||||||||
| 821 | PRINT_XCB_EVENT(XCB_GE_GENERIC); | - | ||||||||||||||||||
| 822 | default: | - | ||||||||||||||||||
| 823 | qDebug("QXcbConnection: %s: unknown event - response_type: %d - sequence: %d", message, int(event->response_type & ~0x80), int(event->sequence)); | - | ||||||||||||||||||
| 824 | } | - | ||||||||||||||||||
| 825 | #else | - | ||||||||||||||||||
| 826 | Q_UNUSED(message); | - | ||||||||||||||||||
| 827 | Q_UNUSED(event); | - | ||||||||||||||||||
| 828 | #endif | - | ||||||||||||||||||
| 829 | } | - | ||||||||||||||||||
| 830 | - | |||||||||||||||||||
| 831 | const char *xcb_errors[] = | - | ||||||||||||||||||
| 832 | { | - | ||||||||||||||||||
| 833 | "Success", | - | ||||||||||||||||||
| 834 | "BadRequest", | - | ||||||||||||||||||
| 835 | "BadValue", | - | ||||||||||||||||||
| 836 | "BadWindow", | - | ||||||||||||||||||
| 837 | "BadPixmap", | - | ||||||||||||||||||
| 838 | "BadAtom", | - | ||||||||||||||||||
| 839 | "BadCursor", | - | ||||||||||||||||||
| 840 | "BadFont", | - | ||||||||||||||||||
| 841 | "BadMatch", | - | ||||||||||||||||||
| 842 | "BadDrawable", | - | ||||||||||||||||||
| 843 | "BadAccess", | - | ||||||||||||||||||
| 844 | "BadAlloc", | - | ||||||||||||||||||
| 845 | "BadColor", | - | ||||||||||||||||||
| 846 | "BadGC", | - | ||||||||||||||||||
| 847 | "BadIDChoice", | - | ||||||||||||||||||
| 848 | "BadName", | - | ||||||||||||||||||
| 849 | "BadLength", | - | ||||||||||||||||||
| 850 | "BadImplementation", | - | ||||||||||||||||||
| 851 | "Unknown" | - | ||||||||||||||||||
| 852 | }; | - | ||||||||||||||||||
| 853 | - | |||||||||||||||||||
| 854 | const char *xcb_protocol_request_codes[] = | - | ||||||||||||||||||
| 855 | { | - | ||||||||||||||||||
| 856 | "Null", | - | ||||||||||||||||||
| 857 | "CreateWindow", | - | ||||||||||||||||||
| 858 | "ChangeWindowAttributes", | - | ||||||||||||||||||
| 859 | "GetWindowAttributes", | - | ||||||||||||||||||
| 860 | "DestroyWindow", | - | ||||||||||||||||||
| 861 | "DestroySubwindows", | - | ||||||||||||||||||
| 862 | "ChangeSaveSet", | - | ||||||||||||||||||
| 863 | "ReparentWindow", | - | ||||||||||||||||||
| 864 | "MapWindow", | - | ||||||||||||||||||
| 865 | "MapSubwindows", | - | ||||||||||||||||||
| 866 | "UnmapWindow", | - | ||||||||||||||||||
| 867 | "UnmapSubwindows", | - | ||||||||||||||||||
| 868 | "ConfigureWindow", | - | ||||||||||||||||||
| 869 | "CirculateWindow", | - | ||||||||||||||||||
| 870 | "GetGeometry", | - | ||||||||||||||||||
| 871 | "QueryTree", | - | ||||||||||||||||||
| 872 | "InternAtom", | - | ||||||||||||||||||
| 873 | "GetAtomName", | - | ||||||||||||||||||
| 874 | "ChangeProperty", | - | ||||||||||||||||||
| 875 | "DeleteProperty", | - | ||||||||||||||||||
| 876 | "GetProperty", | - | ||||||||||||||||||
| 877 | "ListProperties", | - | ||||||||||||||||||
| 878 | "SetSelectionOwner", | - | ||||||||||||||||||
| 879 | "GetSelectionOwner", | - | ||||||||||||||||||
| 880 | "ConvertSelection", | - | ||||||||||||||||||
| 881 | "SendEvent", | - | ||||||||||||||||||
| 882 | "GrabPointer", | - | ||||||||||||||||||
| 883 | "UngrabPointer", | - | ||||||||||||||||||
| 884 | "GrabButton", | - | ||||||||||||||||||
| 885 | "UngrabButton", | - | ||||||||||||||||||
| 886 | "ChangeActivePointerGrab", | - | ||||||||||||||||||
| 887 | "GrabKeyboard", | - | ||||||||||||||||||
| 888 | "UngrabKeyboard", | - | ||||||||||||||||||
| 889 | "GrabKey", | - | ||||||||||||||||||
| 890 | "UngrabKey", | - | ||||||||||||||||||
| 891 | "AllowEvents", | - | ||||||||||||||||||
| 892 | "GrabServer", | - | ||||||||||||||||||
| 893 | "UngrabServer", | - | ||||||||||||||||||
| 894 | "QueryPointer", | - | ||||||||||||||||||
| 895 | "GetMotionEvents", | - | ||||||||||||||||||
| 896 | "TranslateCoords", | - | ||||||||||||||||||
| 897 | "WarpPointer", | - | ||||||||||||||||||
| 898 | "SetInputFocus", | - | ||||||||||||||||||
| 899 | "GetInputFocus", | - | ||||||||||||||||||
| 900 | "QueryKeymap", | - | ||||||||||||||||||
| 901 | "OpenFont", | - | ||||||||||||||||||
| 902 | "CloseFont", | - | ||||||||||||||||||
| 903 | "QueryFont", | - | ||||||||||||||||||
| 904 | "QueryTextExtents", | - | ||||||||||||||||||
| 905 | "ListFonts", | - | ||||||||||||||||||
| 906 | "ListFontsWithInfo", | - | ||||||||||||||||||
| 907 | "SetFontPath", | - | ||||||||||||||||||
| 908 | "GetFontPath", | - | ||||||||||||||||||
| 909 | "CreatePixmap", | - | ||||||||||||||||||
| 910 | "FreePixmap", | - | ||||||||||||||||||
| 911 | "CreateGC", | - | ||||||||||||||||||
| 912 | "ChangeGC", | - | ||||||||||||||||||
| 913 | "CopyGC", | - | ||||||||||||||||||
| 914 | "SetDashes", | - | ||||||||||||||||||
| 915 | "SetClipRectangles", | - | ||||||||||||||||||
| 916 | "FreeGC", | - | ||||||||||||||||||
| 917 | "ClearArea", | - | ||||||||||||||||||
| 918 | "CopyArea", | - | ||||||||||||||||||
| 919 | "CopyPlane", | - | ||||||||||||||||||
| 920 | "PolyPoint", | - | ||||||||||||||||||
| 921 | "PolyLine", | - | ||||||||||||||||||
| 922 | "PolySegment", | - | ||||||||||||||||||
| 923 | "PolyRectangle", | - | ||||||||||||||||||
| 924 | "PolyArc", | - | ||||||||||||||||||
| 925 | "FillPoly", | - | ||||||||||||||||||
| 926 | "PolyFillRectangle", | - | ||||||||||||||||||
| 927 | "PolyFillArc", | - | ||||||||||||||||||
| 928 | "PutImage", | - | ||||||||||||||||||
| 929 | "GetImage", | - | ||||||||||||||||||
| 930 | "PolyText8", | - | ||||||||||||||||||
| 931 | "PolyText16", | - | ||||||||||||||||||
| 932 | "ImageText8", | - | ||||||||||||||||||
| 933 | "ImageText16", | - | ||||||||||||||||||
| 934 | "CreateColormap", | - | ||||||||||||||||||
| 935 | "FreeColormap", | - | ||||||||||||||||||
| 936 | "CopyColormapAndFree", | - | ||||||||||||||||||
| 937 | "InstallColormap", | - | ||||||||||||||||||
| 938 | "UninstallColormap", | - | ||||||||||||||||||
| 939 | "ListInstalledColormaps", | - | ||||||||||||||||||
| 940 | "AllocColor", | - | ||||||||||||||||||
| 941 | "AllocNamedColor", | - | ||||||||||||||||||
| 942 | "AllocColorCells", | - | ||||||||||||||||||
| 943 | "AllocColorPlanes", | - | ||||||||||||||||||
| 944 | "FreeColors", | - | ||||||||||||||||||
| 945 | "StoreColors", | - | ||||||||||||||||||
| 946 | "StoreNamedColor", | - | ||||||||||||||||||
| 947 | "QueryColors", | - | ||||||||||||||||||
| 948 | "LookupColor", | - | ||||||||||||||||||
| 949 | "CreateCursor", | - | ||||||||||||||||||
| 950 | "CreateGlyphCursor", | - | ||||||||||||||||||
| 951 | "FreeCursor", | - | ||||||||||||||||||
| 952 | "RecolorCursor", | - | ||||||||||||||||||
| 953 | "QueryBestSize", | - | ||||||||||||||||||
| 954 | "QueryExtension", | - | ||||||||||||||||||
| 955 | "ListExtensions", | - | ||||||||||||||||||
| 956 | "ChangeKeyboardMapping", | - | ||||||||||||||||||
| 957 | "GetKeyboardMapping", | - | ||||||||||||||||||
| 958 | "ChangeKeyboardControl", | - | ||||||||||||||||||
| 959 | "GetKeyboardControl", | - | ||||||||||||||||||
| 960 | "Bell", | - | ||||||||||||||||||
| 961 | "ChangePointerControl", | - | ||||||||||||||||||
| 962 | "GetPointerControl", | - | ||||||||||||||||||
| 963 | "SetScreenSaver", | - | ||||||||||||||||||
| 964 | "GetScreenSaver", | - | ||||||||||||||||||
| 965 | "ChangeHosts", | - | ||||||||||||||||||
| 966 | "ListHosts", | - | ||||||||||||||||||
| 967 | "SetAccessControl", | - | ||||||||||||||||||
| 968 | "SetCloseDownMode", | - | ||||||||||||||||||
| 969 | "KillClient", | - | ||||||||||||||||||
| 970 | "RotateProperties", | - | ||||||||||||||||||
| 971 | "ForceScreenSaver", | - | ||||||||||||||||||
| 972 | "SetPointerMapping", | - | ||||||||||||||||||
| 973 | "GetPointerMapping", | - | ||||||||||||||||||
| 974 | "SetModifierMapping", | - | ||||||||||||||||||
| 975 | "GetModifierMapping", | - | ||||||||||||||||||
| 976 | "Unknown" | - | ||||||||||||||||||
| 977 | }; | - | ||||||||||||||||||
| 978 | - | |||||||||||||||||||
| 979 | #ifdef Q_XCB_DEBUG | - | ||||||||||||||||||
| 980 | void QXcbConnection::log(const char *file, int line, int sequence) | - | ||||||||||||||||||
| 981 | { | - | ||||||||||||||||||
| 982 | QMutexLocker locker(&m_callLogMutex); | - | ||||||||||||||||||
| 983 | CallInfo info; | - | ||||||||||||||||||
| 984 | info.sequence = sequence; | - | ||||||||||||||||||
| 985 | info.file = file; | - | ||||||||||||||||||
| 986 | info.line = line; | - | ||||||||||||||||||
| 987 | m_callLog << info; | - | ||||||||||||||||||
| 988 | } | - | ||||||||||||||||||
| 989 | #endif | - | ||||||||||||||||||
| 990 | - | |||||||||||||||||||
| 991 | void QXcbConnection::handleXcbError(xcb_generic_error_t *error) | - | ||||||||||||||||||
| 992 | { | - | ||||||||||||||||||
| 993 | long result = 0; | - | ||||||||||||||||||
| 994 | QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); | - | ||||||||||||||||||
| 995 | if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->genericEventFilterType(), error, &result))
| 0 | ||||||||||||||||||
| 996 | return; never executed: return; | 0 | ||||||||||||||||||
| 997 | - | |||||||||||||||||||
| 998 | uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1); | - | ||||||||||||||||||
| 999 | uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1); | - | ||||||||||||||||||
| 1000 | - | |||||||||||||||||||
| 1001 | qWarning("QXcbConnection: XCB error: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d", | - | ||||||||||||||||||
| 1002 | int(error->error_code), xcb_errors[clamped_error_code], | - | ||||||||||||||||||
| 1003 | int(error->sequence), int(error->resource_id), | - | ||||||||||||||||||
| 1004 | int(error->major_code), xcb_protocol_request_codes[clamped_major_code], | - | ||||||||||||||||||
| 1005 | int(error->minor_code)); | - | ||||||||||||||||||
| 1006 | #ifdef Q_XCB_DEBUG | - | ||||||||||||||||||
| 1007 | QMutexLocker locker(&m_callLogMutex); | - | ||||||||||||||||||
| 1008 | int i = 0; | - | ||||||||||||||||||
| 1009 | for (; i < m_callLog.size(); ++i) { | - | ||||||||||||||||||
| 1010 | if (m_callLog.at(i).sequence == error->sequence) { | - | ||||||||||||||||||
| 1011 | qDebug("Caused by: %s:%d", qPrintable(m_callLog.at(i).file),.constData(), m_callLog.at(i).line); | - | ||||||||||||||||||
| 1012 | break; | - | ||||||||||||||||||
| 1013 | } else if (m_callLog.at(i).sequence > error->sequence) { | - | ||||||||||||||||||
| 1014 | qDebug("Caused some time before: %s:%d", qPrintable(m_callLog.at(i).file),.constData(), | - | ||||||||||||||||||
| 1015 | m_callLog.at(i).line); | - | ||||||||||||||||||
| 1016 | if (i > 0) | - | ||||||||||||||||||
| 1017 | qDebug("and after: %s:%d", qPrintable(m_callLog.at(i-1).file),.constData(), | - | ||||||||||||||||||
| 1018 | m_callLog.at(i-1).line); | - | ||||||||||||||||||
| 1019 | break; | - | ||||||||||||||||||
| 1020 | } | - | ||||||||||||||||||
| 1021 | } | - | ||||||||||||||||||
| 1022 | if (i == m_callLog.size() && !m_callLog.isEmpty()) | - | ||||||||||||||||||
| 1023 | qDebug("Caused some time after: %s:%d", qPrintableqAsConst(m_callLog.).first().file), m_callLog.constData(), | - | ||||||||||||||||||
| 1024 | qAsConst(m_callLog).first().line); | - | ||||||||||||||||||
| 1025 | #endif | - | ||||||||||||||||||
| 1026 | } never executed: end of block | 0 | ||||||||||||||||||
| 1027 | - | |||||||||||||||||||
| 1028 | static Qt::MouseButtons translateMouseButtons(int s) | - | ||||||||||||||||||
| 1029 | { | - | ||||||||||||||||||
| 1030 | Qt::MouseButtons ret = 0; | - | ||||||||||||||||||
| 1031 | if (s & XCB_BUTTON_MASK_1) | - | ||||||||||||||||||
| 1032 | ret |= Qt::LeftButton; | - | ||||||||||||||||||
| 1033 | if (s & XCB_BUTTON_MASK_2) | - | ||||||||||||||||||
| 1034 | ret |= Qt::MidButton; | - | ||||||||||||||||||
| 1035 | if (s & XCB_BUTTON_MASK_3) | - | ||||||||||||||||||
| 1036 | ret |= Qt::RightButton; | - | ||||||||||||||||||
| 1037 | return ret; | - | ||||||||||||||||||
| 1038 | } | - | ||||||||||||||||||
| 1039 | - | |||||||||||||||||||
| 1040 | Qt::MouseButton QXcbConnection::translateMouseButton(xcb_button_t s) | - | ||||||||||||||||||
| 1041 | { | - | ||||||||||||||||||
| 1042 | switch (s) { | - | ||||||||||||||||||
| 1043 | case 1: return Qt::LeftButton; | - | ||||||||||||||||||
| 1044 | case 2: return Qt::MidButton; | - | ||||||||||||||||||
| 1045 | case 3: return Qt::RightButton; | - | ||||||||||||||||||
| 1046 | // Button values 4-7 were already handled as Wheel events, and won't occur here. | - | ||||||||||||||||||
| 1047 | case 8: return Qt::BackButton; // Also known as Qt::ExtraButton1 | - | ||||||||||||||||||
| 1048 | case 9: return Qt::ForwardButton; // Also known as Qt::ExtraButton2 | - | ||||||||||||||||||
| 1049 | case 10: return Qt::ExtraButton3; | - | ||||||||||||||||||
| 1050 | case 11: return Qt::ExtraButton4; | - | ||||||||||||||||||
| 1051 | case 12: return Qt::ExtraButton5; | - | ||||||||||||||||||
| 1052 | case 13: return Qt::ExtraButton6; | - | ||||||||||||||||||
| 1053 | case 14: return Qt::ExtraButton7; | - | ||||||||||||||||||
| 1054 | case 15: return Qt::ExtraButton8; | - | ||||||||||||||||||
| 1055 | case 16: return Qt::ExtraButton9; | - | ||||||||||||||||||
| 1056 | case 17: return Qt::ExtraButton10; | - | ||||||||||||||||||
| 1057 | case 18: return Qt::ExtraButton11; | - | ||||||||||||||||||
| 1058 | case 19: return Qt::ExtraButton12; | - | ||||||||||||||||||
| 1059 | case 20: return Qt::ExtraButton13; | - | ||||||||||||||||||
| 1060 | case 21: return Qt::ExtraButton14; | - | ||||||||||||||||||
| 1061 | case 22: return Qt::ExtraButton15; | - | ||||||||||||||||||
| 1062 | case 23: return Qt::ExtraButton16; | - | ||||||||||||||||||
| 1063 | case 24: return Qt::ExtraButton17; | - | ||||||||||||||||||
| 1064 | case 25: return Qt::ExtraButton18; | - | ||||||||||||||||||
| 1065 | case 26: return Qt::ExtraButton19; | - | ||||||||||||||||||
| 1066 | case 27: return Qt::ExtraButton20; | - | ||||||||||||||||||
| 1067 | case 28: return Qt::ExtraButton21; | - | ||||||||||||||||||
| 1068 | case 29: return Qt::ExtraButton22; | - | ||||||||||||||||||
| 1069 | case 30: return Qt::ExtraButton23; | - | ||||||||||||||||||
| 1070 | case 31: return Qt::ExtraButton24; | - | ||||||||||||||||||
| 1071 | default: return Qt::NoButton; | - | ||||||||||||||||||
| 1072 | } | - | ||||||||||||||||||
| 1073 | } | - | ||||||||||||||||||
| 1074 | - | |||||||||||||||||||
| 1075 | #ifndef QT_NO_XKB | - | ||||||||||||||||||
| 1076 | namespace { | - | ||||||||||||||||||
| 1077 | typedef union { | - | ||||||||||||||||||
| 1078 | /* All XKB events share these fields. */ | - | ||||||||||||||||||
| 1079 | struct { | - | ||||||||||||||||||
| 1080 | uint8_t response_type; | - | ||||||||||||||||||
| 1081 | uint8_t xkbType; | - | ||||||||||||||||||
| 1082 | uint16_t sequence; | - | ||||||||||||||||||
| 1083 | xcb_timestamp_t time; | - | ||||||||||||||||||
| 1084 | uint8_t deviceID; | - | ||||||||||||||||||
| 1085 | } any; | - | ||||||||||||||||||
| 1086 | xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify; | - | ||||||||||||||||||
| 1087 | xcb_xkb_map_notify_event_t map_notify; | - | ||||||||||||||||||
| 1088 | xcb_xkb_state_notify_event_t state_notify; | - | ||||||||||||||||||
| 1089 | } _xkb_event; | - | ||||||||||||||||||
| 1090 | } | - | ||||||||||||||||||
| 1091 | #endif | - | ||||||||||||||||||
| 1092 | - | |||||||||||||||||||
| 1093 | void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) | - | ||||||||||||||||||
| 1094 | { | - | ||||||||||||||||||
| 1095 | #ifdef Q_XCB_DEBUG | - | ||||||||||||||||||
| 1096 | { | - | ||||||||||||||||||
| 1097 | QMutexLocker locker(&m_callLogMutex); | - | ||||||||||||||||||
| 1098 | int i = 0; | - | ||||||||||||||||||
| 1099 | for (; i < m_callLog.size(); ++i) | - | ||||||||||||||||||
| 1100 | if (m_callLog.at(i).sequence >= event->sequence) | - | ||||||||||||||||||
| 1101 | break; | - | ||||||||||||||||||
| 1102 | m_callLog.remove(0, i); | - | ||||||||||||||||||
| 1103 | } | - | ||||||||||||||||||
| 1104 | #endif | - | ||||||||||||||||||
| 1105 | - | |||||||||||||||||||
| 1106 | long result = 0; | - | ||||||||||||||||||
| 1107 | QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); | - | ||||||||||||||||||
| 1108 | bool handled = dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->genericEventFilterType(), event, &result);
| 0-248897 | ||||||||||||||||||
| 1109 | - | |||||||||||||||||||
| 1110 | uint response_type = event->response_type & ~0x80; | - | ||||||||||||||||||
| 1111 | - | |||||||||||||||||||
| 1112 | if (!handled) {
| 0-248907 | ||||||||||||||||||
| 1113 | switch (response_type) { | - | ||||||||||||||||||
| 1114 | case XCB_EXPOSE: executed 2983 times by 108 tests: case 12:Executed by:
| 2983 | ||||||||||||||||||
| 1115 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent); executed 2664 times by 104 tests: eventListener->handleExposeEvent(e);Executed by:
executed 2664 times by 104 tests: end of blockExecuted by:
executed 2983 times by 108 tests: break;Executed by:
| 0-2983 | ||||||||||||||||||
| 1116 | - | |||||||||||||||||||
| 1117 | // press/release/motion is only delivered here when XI 2.2+ is _not_ in use | - | ||||||||||||||||||
| 1118 | case XCB_BUTTON_PRESS: { never executed: case 4: | 0 | ||||||||||||||||||
| 1119 | xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; | - | ||||||||||||||||||
| 1120 | m_keyboard->updateXKBStateFromCore(ev->state); | - | ||||||||||||||||||
| 1121 | // the event explicitly contains the state of the three first buttons, | - | ||||||||||||||||||
| 1122 | // the rest we need to manage ourselves | - | ||||||||||||||||||
| 1123 | m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); | - | ||||||||||||||||||
| 1124 | m_buttons |= translateMouseButton(ev->detail); | - | ||||||||||||||||||
| 1125 | if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
| 0 | ||||||||||||||||||
| 1126 | qCDebug(lcQpaXInputEvents, "legacy mouse press, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttons)); never executed: QMessageLogger(__FILE__, 1126, __PRETTY_FUNCTION__, lcQpaXInputEvents().categoryName()).debug("legacy mouse press, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttons));
| 0 | ||||||||||||||||||
| 1127 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); never executed: eventListener->handleButtonPressEvent(e);never executed: end of blocknever executed: break;
| 0 | ||||||||||||||||||
| 1128 | } | - | ||||||||||||||||||
| 1129 | case XCB_BUTTON_RELEASE: { never executed: case 5: | 0 | ||||||||||||||||||
| 1130 | xcb_button_release_event_t *ev = (xcb_button_release_event_t *)event; | - | ||||||||||||||||||
| 1131 | m_keyboard->updateXKBStateFromCore(ev->state); | - | ||||||||||||||||||
| 1132 | m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); | - | ||||||||||||||||||
| 1133 | m_buttons &= ~translateMouseButton(ev->detail); | - | ||||||||||||||||||
| 1134 | if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
| 0 | ||||||||||||||||||
| 1135 | qCDebug(lcQpaXInputEvents, "legacy mouse release, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttons)); never executed: QMessageLogger(__FILE__, 1135, __PRETTY_FUNCTION__, lcQpaXInputEvents().categoryName()).debug("legacy mouse release, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttons));
| 0 | ||||||||||||||||||
| 1136 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); never executed: eventListener->handleButtonReleaseEvent(e);never executed: end of blocknever executed: break;
| 0 | ||||||||||||||||||
| 1137 | } | - | ||||||||||||||||||
| 1138 | case XCB_MOTION_NOTIFY: { never executed: case 6: | 0 | ||||||||||||||||||
| 1139 | xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event; | - | ||||||||||||||||||
| 1140 | m_keyboard->updateXKBStateFromCore(ev->state); | - | ||||||||||||||||||
| 1141 | m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); | - | ||||||||||||||||||
| 1142 | if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
| 0 | ||||||||||||||||||
| 1143 | qCDebug(lcQpaXInputEvents, "legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y, never executed: QMessageLogger( __FILE__ , 1144 , __PRETTY_FUNCTION__, lcQpaXInputEvents().categoryName()).debug("legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y, ev->detail, static_cast<unsigned int>(m_buttons)) ;
| 0 | ||||||||||||||||||
| 1144 | ev->detail, static_cast<unsigned int>(m_buttons)); never executed: QMessageLogger( __FILE__ , 1144 , __PRETTY_FUNCTION__, lcQpaXInputEvents().categoryName()).debug("legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y, ev->detail, static_cast<unsigned int>(m_buttons)) ; | 0 | ||||||||||||||||||
| 1145 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); never executed: eventListener->handleMotionNotifyEvent(e);never executed: end of blocknever executed: break;
| 0 | ||||||||||||||||||
| 1146 | } | - | ||||||||||||||||||
| 1147 | - | |||||||||||||||||||
| 1148 | case XCB_CONFIGURE_NOTIFY: executed 6597 times by 110 tests: case 22:Executed by:
| 6597 | ||||||||||||||||||
| 1149 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent); executed 5756 times by 109 tests: eventListener->handleConfigureNotifyEvent(e);Executed by:
executed 5756 times by 109 tests: end of blockExecuted by:
executed 6597 times by 110 tests: break;Executed by:
| 0-6597 | ||||||||||||||||||
| 1150 | case XCB_MAP_NOTIFY: executed 2708 times by 108 tests: case 19:Executed by:
| 2708 | ||||||||||||||||||
| 1151 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent); executed 2478 times by 104 tests: eventListener->handleMapNotifyEvent(e);Executed by:
executed 2478 times by 104 tests: end of blockExecuted by:
executed 2708 times by 108 tests: break;Executed by:
| 0-2708 | ||||||||||||||||||
| 1152 | case XCB_UNMAP_NOTIFY: executed 2545 times by 93 tests: case 18:Executed by:
| 2545 | ||||||||||||||||||
| 1153 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent); executed 97 times by 30 tests: eventListener->handleUnmapNotifyEvent(e);Executed by:
executed 97 times by 30 tests: end of blockExecuted by:
executed 2545 times by 93 tests: break;Executed by:
| 0-2545 | ||||||||||||||||||
| 1154 | case XCB_DESTROY_NOTIFY: executed 3713 times by 98 tests: case 17:Executed by:
| 3713 | ||||||||||||||||||
| 1155 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_destroy_notify_event_t, event, handleDestroyNotifyEvent); never executed: eventListener->handleDestroyNotifyEvent(e);never executed: end of blockexecuted 3713 times by 98 tests: break;Executed by:
| 0-3713 | ||||||||||||||||||
| 1156 | case XCB_CLIENT_MESSAGE: executed 12136 times by 111 tests: case 33:Executed by:
| 12136 | ||||||||||||||||||
| 1157 | handleClientMessageEvent((xcb_client_message_event_t *)event); | - | ||||||||||||||||||
| 1158 | break; executed 12136 times by 111 tests: break;Executed by:
| 12136 | ||||||||||||||||||
| 1159 | case XCB_ENTER_NOTIFY: executed 855 times by 70 tests: case 7:Executed by:
| 855 | ||||||||||||||||||
| 1160 | #ifdef XCB_USE_XINPUT22 | - | ||||||||||||||||||
| 1161 | if (isAtLeastXI22() && xi2MouseEvents())
| 0-855 | ||||||||||||||||||
| 1162 | break; executed 855 times by 70 tests: break;Executed by:
| 855 | ||||||||||||||||||
| 1163 | #endif | - | ||||||||||||||||||
| 1164 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent); never executed: eventListener->handleEnterNotifyEvent(e);never executed: end of blocknever executed: break;
| 0 | ||||||||||||||||||
| 1165 | case XCB_LEAVE_NOTIFY: executed 806 times by 58 tests: case 8:Executed by:
| 806 | ||||||||||||||||||
| 1166 | #ifdef XCB_USE_XINPUT22 | - | ||||||||||||||||||
| 1167 | if (isAtLeastXI22() && xi2MouseEvents())
| 0-806 | ||||||||||||||||||
| 1168 | break; executed 806 times by 58 tests: break;Executed by:
| 806 | ||||||||||||||||||
| 1169 | #endif | - | ||||||||||||||||||
| 1170 | m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state); | - | ||||||||||||||||||
| 1171 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent); never executed: eventListener->handleLeaveNotifyEvent(e);never executed: end of blocknever executed: break;
| 0 | ||||||||||||||||||
| 1172 | case XCB_FOCUS_IN: executed 3345 times by 107 tests: case 9:Executed by:
| 3345 | ||||||||||||||||||
| 1173 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent); executed 2580 times by 103 tests: eventListener->handleFocusInEvent(e);Executed by:
executed 2580 times by 103 tests: end of blockExecuted by:
executed 3345 times by 107 tests: break;Executed by:
| 0-3345 | ||||||||||||||||||
| 1174 | case XCB_FOCUS_OUT: executed 2725 times by 91 tests: case 10:Executed by:
| 2725 | ||||||||||||||||||
| 1175 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent); executed 430 times by 49 tests: eventListener->handleFocusOutEvent(e);Executed by:
executed 430 times by 49 tests: end of blockExecuted by:
executed 2725 times by 91 tests: break;Executed by:
| 0-2725 | ||||||||||||||||||
| 1176 | case XCB_KEY_PRESS: never executed: case 2: | 0 | ||||||||||||||||||
| 1177 | { | - | ||||||||||||||||||
| 1178 | xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event; | - | ||||||||||||||||||
| 1179 | m_keyboard->updateXKBStateFromCore(kp->state); | - | ||||||||||||||||||
| 1180 | setTime(kp->time); | - | ||||||||||||||||||
| 1181 | HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent); never executed: m_keyboard->handleKeyPressEvent(e);never executed: end of blocknever executed: break;
| 0 | ||||||||||||||||||
| 1182 | } | - | ||||||||||||||||||
| 1183 | case XCB_KEY_RELEASE: never executed: case 3: | 0 | ||||||||||||||||||
| 1184 | m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state); | - | ||||||||||||||||||
| 1185 | HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent); never executed: m_keyboard->handleKeyReleaseEvent(e);never executed: end of blocknever executed: break;
| 0 | ||||||||||||||||||
| 1186 | case XCB_MAPPING_NOTIFY: never executed: case 34: | 0 | ||||||||||||||||||
| 1187 | m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event); | - | ||||||||||||||||||
| 1188 | break; never executed: break; | 0 | ||||||||||||||||||
| 1189 | case XCB_SELECTION_REQUEST: executed 10 times by 5 tests: case 30:Executed by:
| 10 | ||||||||||||||||||
| 1190 | { | - | ||||||||||||||||||
| 1191 | xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event; | - | ||||||||||||||||||
| 1192 | #ifndef QT_NO_DRAGANDDROP | - | ||||||||||||||||||
| 1193 | if (sr->selection == atom(QXcbAtom::XdndSelection))
| 0-10 | ||||||||||||||||||
| 1194 | m_drag->handleSelectionRequest(sr); never executed: m_drag->handleSelectionRequest(sr); | 0 | ||||||||||||||||||
| 1195 | else | - | ||||||||||||||||||
| 1196 | #endif | - | ||||||||||||||||||
| 1197 | { | - | ||||||||||||||||||
| 1198 | #ifndef QT_NO_CLIPBOARD | - | ||||||||||||||||||
| 1199 | m_clipboard->handleSelectionRequest(sr); | - | ||||||||||||||||||
| 1200 | #endif | - | ||||||||||||||||||
| 1201 | } executed 10 times by 5 tests: end of blockExecuted by:
| 10 | ||||||||||||||||||
| 1202 | break; executed 10 times by 5 tests: break;Executed by:
| 10 | ||||||||||||||||||
| 1203 | } | - | ||||||||||||||||||
| 1204 | case XCB_SELECTION_CLEAR: executed 15 times by 3 tests: case 29:Executed by:
| 15 | ||||||||||||||||||
| 1205 | setTime(((xcb_selection_clear_event_t *)event)->time); | - | ||||||||||||||||||
| 1206 | #ifndef QT_NO_CLIPBOARD | - | ||||||||||||||||||
| 1207 | m_clipboard->handleSelectionClearRequest((xcb_selection_clear_event_t *)event); | - | ||||||||||||||||||
| 1208 | #endif | - | ||||||||||||||||||
| 1209 | handled = true; | - | ||||||||||||||||||
| 1210 | break; executed 15 times by 3 tests: break;Executed by:
| 15 | ||||||||||||||||||
| 1211 | case XCB_SELECTION_NOTIFY: never executed: case 31: | 0 | ||||||||||||||||||
| 1212 | setTime(((xcb_selection_notify_event_t *)event)->time); | - | ||||||||||||||||||
| 1213 | handled = false; | - | ||||||||||||||||||
| 1214 | break; never executed: break; | 0 | ||||||||||||||||||
| 1215 | case XCB_PROPERTY_NOTIFY: executed 205289 times by 113 tests: case 28:Executed by:
| 205289 | ||||||||||||||||||
| 1216 | { | - | ||||||||||||||||||
| 1217 | xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event; | - | ||||||||||||||||||
| 1218 | if (pn->atom == atom(QXcbAtom::_NET_WORKAREA)) {
| 0-205289 | ||||||||||||||||||
| 1219 | QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(pn->window); | - | ||||||||||||||||||
| 1220 | if (virtualDesktop)
| 0 | ||||||||||||||||||
| 1221 | virtualDesktop->updateWorkArea(); never executed: virtualDesktop->updateWorkArea(); | 0 | ||||||||||||||||||
| 1222 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 1223 | HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent); executed 102151 times by 112 tests: eventListener->handlePropertyNotifyEvent(e);Executed by:
executed 102151 times by 112 tests: end of blockExecuted by:
executed 205289 times by 113 tests: break;Executed by:
| 0-205289 | ||||||||||||||||||
| 1224 | } | - | ||||||||||||||||||
| 1225 | break; never executed: break; | 0 | ||||||||||||||||||
| 1226 | } | - | ||||||||||||||||||
| 1227 | #if defined(XCB_USE_XINPUT2) | - | ||||||||||||||||||
| 1228 | case XCB_GE_GENERIC: executed 2185 times by 70 tests: case 35:Executed by:
| 2185 | ||||||||||||||||||
| 1229 | // Here the windowEventListener is invoked from xi2HandleEvent() | - | ||||||||||||||||||
| 1230 | if (m_xi2Enabled && isXIEvent(event, m_xiOpCode))
| 0-2185 | ||||||||||||||||||
| 1231 | xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event)); executed 2185 times by 70 tests: xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));Executed by:
| 2185 | ||||||||||||||||||
| 1232 | break; executed 2185 times by 70 tests: break;Executed by:
| 2185 | ||||||||||||||||||
| 1233 | #endif | - | ||||||||||||||||||
| 1234 | default: executed 2995 times by 109 tests: default:Executed by:
| 2995 | ||||||||||||||||||
| 1235 | handled = false; | - | ||||||||||||||||||
| 1236 | break; executed 2995 times by 109 tests: break;Executed by:
| 2995 | ||||||||||||||||||
| 1237 | } | - | ||||||||||||||||||
| 1238 | } | - | ||||||||||||||||||
| 1239 | - | |||||||||||||||||||
| 1240 | if (!handled) {
| 15-248892 | ||||||||||||||||||
| 1241 | if (response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
| 67-248825 | ||||||||||||||||||
| 1242 | xcb_xfixes_selection_notify_event_t *notify_event = (xcb_xfixes_selection_notify_event_t *)event; | - | ||||||||||||||||||
| 1243 | setTime(notify_event->timestamp); | - | ||||||||||||||||||
| 1244 | #ifndef QT_NO_CLIPBOARD | - | ||||||||||||||||||
| 1245 | m_clipboard->handleXFixesSelectionRequest(notify_event); | - | ||||||||||||||||||
| 1246 | #endif | - | ||||||||||||||||||
| 1247 | foreachfor (QXcbVirtualDesktop *virtualDesktop ,: qAsConst(m_virtualDesktops))) | - | ||||||||||||||||||
| 1248 | virtualDesktop->handleXFixesSelectionNotify(notify_event); executed 67 times by 6 tests: virtualDesktop->handleXFixesSelectionNotify(notify_event);Executed by:
| 67 | ||||||||||||||||||
| 1249 | - | |||||||||||||||||||
| 1250 | handled = true; | - | ||||||||||||||||||
| 1251 | } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) { executed 67 times by 6 tests: end of blockExecuted by:
| 0-248825 | ||||||||||||||||||
| 1252 | updateScreens((xcb_randr_notify_event_t *)event); | - | ||||||||||||||||||
| 1253 | handled = true; | - | ||||||||||||||||||
| 1254 | } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) { never executed: end of block
| 0-248825 | ||||||||||||||||||
| 1255 | xcb_randr_screen_change_notify_event_t *change_event = (xcb_randr_screen_change_notify_event_t *)event; | - | ||||||||||||||||||
| 1256 | foreachfor (QXcbScreen *s ,: qAsConst(m_screens))) { | - | ||||||||||||||||||
| 1257 | if (s->root() == change_event->root )
| 0 | ||||||||||||||||||
| 1258 | s->handleScreenChange(change_event); never executed: s->handleScreenChange(change_event); | 0 | ||||||||||||||||||
| 1259 | } never executed: end of block | 0 | ||||||||||||||||||
| 1260 | handled = true; | - | ||||||||||||||||||
| 1261 | #ifndef QT_NO_XKB | - | ||||||||||||||||||
| 1262 | } else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295 never executed: end of block
| 0-248825 | ||||||||||||||||||
| 1263 | _xkb_event *xkb_event = reinterpret_cast<_xkb_event *>(event); | - | ||||||||||||||||||
| 1264 | if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
| 0 | ||||||||||||||||||
| 1265 | switch (xkb_event->any.xkbType) { | - | ||||||||||||||||||
| 1266 | // XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap | - | ||||||||||||||||||
| 1267 | // updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundent recompilations. | - | ||||||||||||||||||
| 1268 | case XCB_XKB_STATE_NOTIFY: never executed: case 2: | 0 | ||||||||||||||||||
| 1269 | m_keyboard->updateXKBState(&xkb_event->state_notify); | - | ||||||||||||||||||
| 1270 | handled = true; | - | ||||||||||||||||||
| 1271 | break; never executed: break; | 0 | ||||||||||||||||||
| 1272 | case XCB_XKB_MAP_NOTIFY: never executed: case 1: | 0 | ||||||||||||||||||
| 1273 | m_keyboard->handleMappingNotifyEvent(&xkb_event->map_notify); | - | ||||||||||||||||||
| 1274 | handled = true; | - | ||||||||||||||||||
| 1275 | break; never executed: break; | 0 | ||||||||||||||||||
| 1276 | case XCB_XKB_NEW_KEYBOARD_NOTIFY: { never executed: case 0: | 0 | ||||||||||||||||||
| 1277 | xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify; | - | ||||||||||||||||||
| 1278 | if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
| 0 | ||||||||||||||||||
| 1279 | m_keyboard->updateKeymap(); never executed: m_keyboard->updateKeymap(); | 0 | ||||||||||||||||||
| 1280 | break; never executed: break; | 0 | ||||||||||||||||||
| 1281 | } | - | ||||||||||||||||||
| 1282 | default: never executed: default: | 0 | ||||||||||||||||||
| 1283 | break; never executed: break; | 0 | ||||||||||||||||||
| 1284 | } | - | ||||||||||||||||||
| 1285 | } | - | ||||||||||||||||||
| 1286 | #endif | - | ||||||||||||||||||
| 1287 | } never executed: end of block | 0 | ||||||||||||||||||
| 1288 | } executed 248892 times by 117 tests: end of blockExecuted by:
| 248892 | ||||||||||||||||||
| 1289 | - | |||||||||||||||||||
| 1290 | if (!handled && m_glIntegration)
| 0-248825 | ||||||||||||||||||
| 1291 | handled = m_glIntegration->handleXcbEvent(event, response_type); executed 248825 times by 117 tests: handled = m_glIntegration->handleXcbEvent(event, response_type);Executed by:
| 248825 | ||||||||||||||||||
| 1292 | - | |||||||||||||||||||
| 1293 | if (handled)
| 82-248825 | ||||||||||||||||||
| 1294 | printXcbEvent("Handled XCB event", event); executed 82 times by 6 tests: printXcbEvent("Handled XCB event", event);Executed by:
| 82 | ||||||||||||||||||
| 1295 | else | - | ||||||||||||||||||
| 1296 | printXcbEvent("Unhandled XCB event", event); executed 248825 times by 117 tests: printXcbEvent("Unhandled XCB event", event);Executed by:
| 248825 | ||||||||||||||||||
| 1297 | } | - | ||||||||||||||||||
| 1298 | - | |||||||||||||||||||
| 1299 | void QXcbConnection::addPeekFunc(PeekFunc f) | - | ||||||||||||||||||
| 1300 | { | - | ||||||||||||||||||
| 1301 | m_peekFuncs.append(f); | - | ||||||||||||||||||
| 1302 | } | - | ||||||||||||||||||
| 1303 | - | |||||||||||||||||||
| 1304 | QXcbEventReader::QXcbEventReader(QXcbConnection *connection) | - | ||||||||||||||||||
| 1305 | : m_connection(connection) | - | ||||||||||||||||||
| 1306 | { | - | ||||||||||||||||||
| 1307 | checkXcbPollForQueuedEvent(); | - | ||||||||||||||||||
| 1308 | } | - | ||||||||||||||||||
| 1309 | - | |||||||||||||||||||
| 1310 | void QXcbEventReader::start() | - | ||||||||||||||||||
| 1311 | { | - | ||||||||||||||||||
| 1312 | if (local_xcb_poll_for_queued_event) { | - | ||||||||||||||||||
| 1313 | connect(this, SIGNAL(eventPending()), m_connection, SLOT(processXcbEvents()), Qt::QueuedConnection); | - | ||||||||||||||||||
| 1314 | connect(this, SIGNAL(finished()), m_connection, SLOT(processXcbEvents())); | - | ||||||||||||||||||
| 1315 | QThread::start(); | - | ||||||||||||||||||
| 1316 | } else { | - | ||||||||||||||||||
| 1317 | // Must be done after we have an event-dispatcher. By posting a method invocation | - | ||||||||||||||||||
| 1318 | // we are sure that by the time the method is called we have an event-dispatcher. | - | ||||||||||||||||||
| 1319 | QMetaObject::invokeMethod(this, "registerForEvents", Qt::QueuedConnection); | - | ||||||||||||||||||
| 1320 | } | - | ||||||||||||||||||
| 1321 | } | - | ||||||||||||||||||
| 1322 | - | |||||||||||||||||||
| 1323 | void QXcbEventReader::registerForEvents() | - | ||||||||||||||||||
| 1324 | { | - | ||||||||||||||||||
| 1325 | QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(m_connection->xcb_connection()), QSocketNotifier::Read, this); | - | ||||||||||||||||||
| 1326 | connect(notifier, SIGNAL(activated(int)), m_connection, SLOT(processXcbEvents())); | - | ||||||||||||||||||
| 1327 | - | |||||||||||||||||||
| 1328 | QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; | - | ||||||||||||||||||
| 1329 | connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(processXcbEvents())); | - | ||||||||||||||||||
| 1330 | connect(dispatcher, SIGNAL(awake()), m_connection, SLOT(processXcbEvents())); | - | ||||||||||||||||||
| 1331 | } | - | ||||||||||||||||||
| 1332 | - | |||||||||||||||||||
| 1333 | void QXcbEventReader::registerEventDispatcher(QAbstractEventDispatcher *dispatcher) | - | ||||||||||||||||||
| 1334 | { | - | ||||||||||||||||||
| 1335 | // flush the xcb connection before the EventDispatcher is going to block | - | ||||||||||||||||||
| 1336 | // In the non-threaded case processXcbEvents is called before going to block, | - | ||||||||||||||||||
| 1337 | // which flushes the connection. | - | ||||||||||||||||||
| 1338 | if (local_xcb_poll_for_queued_event) | - | ||||||||||||||||||
| 1339 | connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(flush())); | - | ||||||||||||||||||
| 1340 | } | - | ||||||||||||||||||
| 1341 | - | |||||||||||||||||||
| 1342 | void QXcbEventReader::run() | - | ||||||||||||||||||
| 1343 | { | - | ||||||||||||||||||
| 1344 | xcb_generic_event_t *event; | - | ||||||||||||||||||
| 1345 | while (m_connection && (event = xcb_wait_for_event(m_connection->xcb_connection()))) { | - | ||||||||||||||||||
| 1346 | m_mutex.lock(); | - | ||||||||||||||||||
| 1347 | addEvent(event); | - | ||||||||||||||||||
| 1348 | while (m_connection && (event = local_xcb_poll_for_queued_event(m_connection->xcb_connection()))) | - | ||||||||||||||||||
| 1349 | addEvent(event); | - | ||||||||||||||||||
| 1350 | m_mutex.unlock(); | - | ||||||||||||||||||
| 1351 | emit eventPending(); | - | ||||||||||||||||||
| 1352 | } | - | ||||||||||||||||||
| 1353 | - | |||||||||||||||||||
| 1354 | m_mutex.lock(); | - | ||||||||||||||||||
| 1355 | for (int i = 0; i < m_events.size(); ++i) | - | ||||||||||||||||||
| 1356 | free(m_events.at(i)); | - | ||||||||||||||||||
| 1357 | m_events.clear(); | - | ||||||||||||||||||
| 1358 | m_mutex.unlock(); | - | ||||||||||||||||||
| 1359 | } | - | ||||||||||||||||||
| 1360 | - | |||||||||||||||||||
| 1361 | void QXcbEventReader::addEvent(xcb_generic_event_t *event) | - | ||||||||||||||||||
| 1362 | { | - | ||||||||||||||||||
| 1363 | if ((event->response_type & ~0x80) == XCB_CLIENT_MESSAGE | - | ||||||||||||||||||
| 1364 | && ((xcb_client_message_event_t *)event)->type == m_connection->atom(QXcbAtom::_QT_CLOSE_CONNECTION)) | - | ||||||||||||||||||
| 1365 | m_connection = 0; | - | ||||||||||||||||||
| 1366 | m_events << event; | - | ||||||||||||||||||
| 1367 | } | - | ||||||||||||||||||
| 1368 | - | |||||||||||||||||||
| 1369 | QXcbEventArray *QXcbEventReader::lock() | - | ||||||||||||||||||
| 1370 | { | - | ||||||||||||||||||
| 1371 | m_mutex.lock(); | - | ||||||||||||||||||
| 1372 | if (!local_xcb_poll_for_queued_event) { | - | ||||||||||||||||||
| 1373 | while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection->xcb_connection())) | - | ||||||||||||||||||
| 1374 | m_events << event; | - | ||||||||||||||||||
| 1375 | } | - | ||||||||||||||||||
| 1376 | return &m_events; | - | ||||||||||||||||||
| 1377 | } | - | ||||||||||||||||||
| 1378 | - | |||||||||||||||||||
| 1379 | void QXcbEventReader::unlock() | - | ||||||||||||||||||
| 1380 | { | - | ||||||||||||||||||
| 1381 | m_mutex.unlock(); | - | ||||||||||||||||||
| 1382 | } | - | ||||||||||||||||||
| 1383 | - | |||||||||||||||||||
| 1384 | void QXcbConnection::setFocusWindow(QXcbWindow *w) | - | ||||||||||||||||||
| 1385 | { | - | ||||||||||||||||||
| 1386 | m_focusWindow = w; | - | ||||||||||||||||||
| 1387 | } | - | ||||||||||||||||||
| 1388 | void QXcbConnection::setMouseGrabber(QXcbWindow *w) | - | ||||||||||||||||||
| 1389 | { | - | ||||||||||||||||||
| 1390 | m_mouseGrabber = w; | - | ||||||||||||||||||
| 1391 | m_mousePressWindow = Q_NULLPTR; | - | ||||||||||||||||||
| 1392 | } | - | ||||||||||||||||||
| 1393 | void QXcbConnection::setMousePressWindow(QXcbWindow *w) | - | ||||||||||||||||||
| 1394 | { | - | ||||||||||||||||||
| 1395 | m_mousePressWindow = w; | - | ||||||||||||||||||
| 1396 | } | - | ||||||||||||||||||
| 1397 | - | |||||||||||||||||||
| 1398 | void QXcbConnection::grabServer() | - | ||||||||||||||||||
| 1399 | { | - | ||||||||||||||||||
| 1400 | if (m_canGrabServer) | - | ||||||||||||||||||
| 1401 | xcb_grab_server(m_connection); | - | ||||||||||||||||||
| 1402 | } | - | ||||||||||||||||||
| 1403 | - | |||||||||||||||||||
| 1404 | void QXcbConnection::ungrabServer() | - | ||||||||||||||||||
| 1405 | { | - | ||||||||||||||||||
| 1406 | if (m_canGrabServer) | - | ||||||||||||||||||
| 1407 | xcb_ungrab_server(m_connection); | - | ||||||||||||||||||
| 1408 | } | - | ||||||||||||||||||
| 1409 | - | |||||||||||||||||||
| 1410 | void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id) | - | ||||||||||||||||||
| 1411 | { | - | ||||||||||||||||||
| 1412 | xcb_client_message_event_t event; | - | ||||||||||||||||||
| 1413 | memset(&event, 0, sizeof(event)); | - | ||||||||||||||||||
| 1414 | - | |||||||||||||||||||
| 1415 | const xcb_window_t eventListener = xcb_generate_id(m_connection); | - | ||||||||||||||||||
| 1416 | xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); | - | ||||||||||||||||||
| 1417 | xcb_screen_t *screen = it.data; | - | ||||||||||||||||||
| 1418 | Q_XCB_CALL(xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, | - | ||||||||||||||||||
| 1419 | eventListener, screen->root, | - | ||||||||||||||||||
| 1420 | 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY, | - | ||||||||||||||||||
| 1421 | screen->root_visual, 0, 0)); | - | ||||||||||||||||||
| 1422 | - | |||||||||||||||||||
| 1423 | event.response_type = XCB_CLIENT_MESSAGE; | - | ||||||||||||||||||
| 1424 | event.format = 32; | - | ||||||||||||||||||
| 1425 | event.sequence = 0; | - | ||||||||||||||||||
| 1426 | event.window = eventListener; | - | ||||||||||||||||||
| 1427 | event.type = atom(a); | - | ||||||||||||||||||
| 1428 | event.data.data32[0] = id; | - | ||||||||||||||||||
| 1429 | - | |||||||||||||||||||
| 1430 | Q_XCB_CALL(xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event)); | - | ||||||||||||||||||
| 1431 | Q_XCB_CALL(xcb_destroy_window(m_connection, eventListener)); | - | ||||||||||||||||||
| 1432 | xcb_flush(xcb_connection()); | - | ||||||||||||||||||
| 1433 | } | - | ||||||||||||||||||
| 1434 | - | |||||||||||||||||||
| 1435 | namespace | - | ||||||||||||||||||
| 1436 | { | - | ||||||||||||||||||
| 1437 | class PropertyNotifyEvent { | - | ||||||||||||||||||
| 1438 | public: | - | ||||||||||||||||||
| 1439 | PropertyNotifyEvent(xcb_window_t win, xcb_atom_t property) | - | ||||||||||||||||||
| 1440 | : window(win), type(XCB_PROPERTY_NOTIFY), atom(property) {} | - | ||||||||||||||||||
| 1441 | xcb_window_t window; | - | ||||||||||||||||||
| 1442 | int type; | - | ||||||||||||||||||
| 1443 | xcb_atom_t atom; | - | ||||||||||||||||||
| 1444 | bool checkEvent(xcb_generic_event_t *event) const { | - | ||||||||||||||||||
| 1445 | if (!event) | - | ||||||||||||||||||
| 1446 | return false; | - | ||||||||||||||||||
| 1447 | if ((event->response_type & ~0x80) != type) { | - | ||||||||||||||||||
| 1448 | return false; | - | ||||||||||||||||||
| 1449 | } else { | - | ||||||||||||||||||
| 1450 | xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event; | - | ||||||||||||||||||
| 1451 | if ((pn->window == window) && (pn->atom == atom)) | - | ||||||||||||||||||
| 1452 | return true; | - | ||||||||||||||||||
| 1453 | } | - | ||||||||||||||||||
| 1454 | return false; | - | ||||||||||||||||||
| 1455 | } | - | ||||||||||||||||||
| 1456 | }; | - | ||||||||||||||||||
| 1457 | } | - | ||||||||||||||||||
| 1458 | - | |||||||||||||||||||
| 1459 | xcb_timestamp_t QXcbConnection::getTimestamp() | - | ||||||||||||||||||
| 1460 | { | - | ||||||||||||||||||
| 1461 | // send a dummy event to myself to get the timestamp from X server. | - | ||||||||||||||||||
| 1462 | xcb_window_t root_win = rootWindow(); | - | ||||||||||||||||||
| 1463 | xcb_change_property(xcb_connection(), XCB_PROP_MODE_APPEND, root_win, atom(QXcbAtom::CLIP_TEMPORARY), | - | ||||||||||||||||||
| 1464 | XCB_ATOM_INTEGER, 32, 0, NULL); | - | ||||||||||||||||||
| 1465 | - | |||||||||||||||||||
| 1466 | connection()->flush(); | - | ||||||||||||||||||
| 1467 | PropertyNotifyEvent checker(root_win, atom(QXcbAtom::CLIP_TEMPORARY)); | - | ||||||||||||||||||
| 1468 | - | |||||||||||||||||||
| 1469 | xcb_generic_event_t *event = 0; | - | ||||||||||||||||||
| 1470 | // lets keep this inside a loop to avoid a possible race condition, where | - | ||||||||||||||||||
| 1471 | // reader thread has not yet had the time to acquire the mutex in order | - | ||||||||||||||||||
| 1472 | // to add the new set of events to its event queue | - | ||||||||||||||||||
| 1473 | while (!event) { | - | ||||||||||||||||||
| 1474 | connection()->sync(); | - | ||||||||||||||||||
| 1475 | event = checkEvent(checker); | - | ||||||||||||||||||
| 1476 | } | - | ||||||||||||||||||
| 1477 | - | |||||||||||||||||||
| 1478 | xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event; | - | ||||||||||||||||||
| 1479 | xcb_timestamp_t timestamp = pn->time; | - | ||||||||||||||||||
| 1480 | free(event); | - | ||||||||||||||||||
| 1481 | - | |||||||||||||||||||
| 1482 | xcb_delete_property(xcb_connection(), root_win, atom(QXcbAtom::CLIP_TEMPORARY)); | - | ||||||||||||||||||
| 1483 | - | |||||||||||||||||||
| 1484 | return timestamp; | - | ||||||||||||||||||
| 1485 | } | - | ||||||||||||||||||
| 1486 | - | |||||||||||||||||||
| 1487 | xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const | - | ||||||||||||||||||
| 1488 | { | - | ||||||||||||||||||
| 1489 | xcb_connection_t *c = xcb_connection(); | - | ||||||||||||||||||
| 1490 | xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(c, atom); | - | ||||||||||||||||||
| 1491 | xcb_get_selection_owner_reply_t *reply; | - | ||||||||||||||||||
| 1492 | reply = xcb_get_selection_owner_reply(c, cookie, 0); | - | ||||||||||||||||||
| 1493 | xcb_window_t win = reply->owner; | - | ||||||||||||||||||
| 1494 | free(reply); | - | ||||||||||||||||||
| 1495 | return win; | - | ||||||||||||||||||
| 1496 | } | - | ||||||||||||||||||
| 1497 | - | |||||||||||||||||||
| 1498 | xcb_window_t QXcbConnection::getQtSelectionOwner() | - | ||||||||||||||||||
| 1499 | { | - | ||||||||||||||||||
| 1500 | if (!m_qtSelectionOwner) { | - | ||||||||||||||||||
| 1501 | xcb_screen_t *xcbScreen = primaryVirtualDesktop()->screen(); | - | ||||||||||||||||||
| 1502 | int x = 0, y = 0, w = 3, h = 3; | - | ||||||||||||||||||
| 1503 | m_qtSelectionOwner = xcb_generate_id(xcb_connection()); | - | ||||||||||||||||||
| 1504 | Q_XCB_CALL(xcb_create_window(xcb_connection(), | - | ||||||||||||||||||
| 1505 | XCB_COPY_FROM_PARENT, // depth -- same as root | - | ||||||||||||||||||
| 1506 | m_qtSelectionOwner, // window id | - | ||||||||||||||||||
| 1507 | xcbScreen->root, // parent window id | - | ||||||||||||||||||
| 1508 | x, y, w, h, | - | ||||||||||||||||||
| 1509 | 0, // border width | - | ||||||||||||||||||
| 1510 | XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class | - | ||||||||||||||||||
| 1511 | xcbScreen->root_visual, // visual | - | ||||||||||||||||||
| 1512 | 0, // value mask | - | ||||||||||||||||||
| 1513 | 0)); // value list | - | ||||||||||||||||||
| 1514 | } | - | ||||||||||||||||||
| 1515 | return m_qtSelectionOwner; | - | ||||||||||||||||||
| 1516 | } | - | ||||||||||||||||||
| 1517 | - | |||||||||||||||||||
| 1518 | xcb_window_t QXcbConnection::rootWindow() | - | ||||||||||||||||||
| 1519 | { | - | ||||||||||||||||||
| 1520 | QXcbScreen *s = primaryScreen(); | - | ||||||||||||||||||
| 1521 | return s ? s->root() : 0; | - | ||||||||||||||||||
| 1522 | } | - | ||||||||||||||||||
| 1523 | - | |||||||||||||||||||
| 1524 | xcb_window_t QXcbConnection::clientLeader() | - | ||||||||||||||||||
| 1525 | { | - | ||||||||||||||||||
| 1526 | if (m_clientLeader == 0) { | - | ||||||||||||||||||
| 1527 | m_clientLeader = xcb_generate_id(xcb_connection()); | - | ||||||||||||||||||
| 1528 | QXcbScreen *screen = primaryScreen(); | - | ||||||||||||||||||
| 1529 | Q_XCB_CALL(xcb_create_window(xcb_connection(), | - | ||||||||||||||||||
| 1530 | XCB_COPY_FROM_PARENT, | - | ||||||||||||||||||
| 1531 | m_clientLeader, | - | ||||||||||||||||||
| 1532 | screen->root(), | - | ||||||||||||||||||
| 1533 | 0, 0, 1, 1, | - | ||||||||||||||||||
| 1534 | 0, | - | ||||||||||||||||||
| 1535 | XCB_WINDOW_CLASS_INPUT_OUTPUT, | - | ||||||||||||||||||
| 1536 | screen->screen()->root_visual, | - | ||||||||||||||||||
| 1537 | 0, 0)); | - | ||||||||||||||||||
| 1538 | #ifndef QT_NO_DEBUG | - | ||||||||||||||||||
| 1539 | QByteArray ba("Qt client leader window"); | - | ||||||||||||||||||
| 1540 | Q_XCB_CALL(xcb_change_property(xcb_connection(), | - | ||||||||||||||||||
| 1541 | XCB_PROP_MODE_REPLACE, | - | ||||||||||||||||||
| 1542 | m_clientLeader, | - | ||||||||||||||||||
| 1543 | atom(QXcbAtom::_NET_WM_NAME), | - | ||||||||||||||||||
| 1544 | atom(QXcbAtom::UTF8_STRING), | - | ||||||||||||||||||
| 1545 | 8, | - | ||||||||||||||||||
| 1546 | ba.length(), | - | ||||||||||||||||||
| 1547 | ba.constData())); | - | ||||||||||||||||||
| 1548 | #endif | - | ||||||||||||||||||
| 1549 | Q_XCB_CALL(xcb_change_property(xcb_connection(), | - | ||||||||||||||||||
| 1550 | XCB_PROP_MODE_REPLACE, | - | ||||||||||||||||||
| 1551 | m_clientLeader, | - | ||||||||||||||||||
| 1552 | atom(QXcbAtom::WM_CLIENT_LEADER), | - | ||||||||||||||||||
| 1553 | XCB_ATOM_WINDOW, | - | ||||||||||||||||||
| 1554 | 32, | - | ||||||||||||||||||
| 1555 | 1, | - | ||||||||||||||||||
| 1556 | &m_clientLeader)); | - | ||||||||||||||||||
| 1557 | - | |||||||||||||||||||
| 1558 | #if !defined(QT_NO_SESSIONMANAGER) && defined(XCB_USE_SM) | - | ||||||||||||||||||
| 1559 | // If we are session managed, inform the window manager about it | - | ||||||||||||||||||
| 1560 | QByteArray session = qGuiApp->sessionId().toLatin1(); | - | ||||||||||||||||||
| 1561 | if (!session.isEmpty()) { | - | ||||||||||||||||||
| 1562 | Q_XCB_CALL(xcb_change_property(xcb_connection(), | - | ||||||||||||||||||
| 1563 | XCB_PROP_MODE_REPLACE, | - | ||||||||||||||||||
| 1564 | m_clientLeader, | - | ||||||||||||||||||
| 1565 | atom(QXcbAtom::SM_CLIENT_ID), | - | ||||||||||||||||||
| 1566 | XCB_ATOM_STRING, | - | ||||||||||||||||||
| 1567 | 8, | - | ||||||||||||||||||
| 1568 | session.length(), | - | ||||||||||||||||||
| 1569 | session.constData())); | - | ||||||||||||||||||
| 1570 | } | - | ||||||||||||||||||
| 1571 | #endif | - | ||||||||||||||||||
| 1572 | } | - | ||||||||||||||||||
| 1573 | return m_clientLeader; | - | ||||||||||||||||||
| 1574 | } | - | ||||||||||||||||||
| 1575 | - | |||||||||||||||||||
| 1576 | #ifdef XCB_USE_XLIB | - | ||||||||||||||||||
| 1577 | void *QXcbConnection::xlib_display() const | - | ||||||||||||||||||
| 1578 | { | - | ||||||||||||||||||
| 1579 | return m_xlib_display; | - | ||||||||||||||||||
| 1580 | } | - | ||||||||||||||||||
| 1581 | - | |||||||||||||||||||
| 1582 | void *QXcbConnection::createVisualInfoForDefaultVisualId() const | - | ||||||||||||||||||
| 1583 | { | - | ||||||||||||||||||
| 1584 | if (m_defaultVisualId == UINT_MAX) | - | ||||||||||||||||||
| 1585 | return 0; | - | ||||||||||||||||||
| 1586 | XVisualInfo info; | - | ||||||||||||||||||
| 1587 | memset(&info, 0, sizeof info); | - | ||||||||||||||||||
| 1588 | info.visualid = m_defaultVisualId; | - | ||||||||||||||||||
| 1589 | - | |||||||||||||||||||
| 1590 | int count = 0; | - | ||||||||||||||||||
| 1591 | XVisualInfo *retVisual = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &info, &count); | - | ||||||||||||||||||
| 1592 | Q_ASSERT(count < 2); | - | ||||||||||||||||||
| 1593 | return retVisual; | - | ||||||||||||||||||
| 1594 | } | - | ||||||||||||||||||
| 1595 | - | |||||||||||||||||||
| 1596 | #endif | - | ||||||||||||||||||
| 1597 | - | |||||||||||||||||||
| 1598 | #if defined(XCB_USE_XINPUT2) | - | ||||||||||||||||||
| 1599 | // it is safe to cast XI_* events here as long as we are only touching the first 32 bytes, | - | ||||||||||||||||||
| 1600 | // after that position event needs memmove, see xi2PrepareXIGenericDeviceEvent | - | ||||||||||||||||||
| 1601 | static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t type) | - | ||||||||||||||||||
| 1602 | { | - | ||||||||||||||||||
| 1603 | if (!isXIEvent(event, opCode)) | - | ||||||||||||||||||
| 1604 | return false; | - | ||||||||||||||||||
| 1605 | - | |||||||||||||||||||
| 1606 | xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event); | - | ||||||||||||||||||
| 1607 | return xiEvent->evtype == type; | - | ||||||||||||||||||
| 1608 | } | - | ||||||||||||||||||
| 1609 | #endif | - | ||||||||||||||||||
| 1610 | static inline bool isValid(xcb_generic_event_t *event) | - | ||||||||||||||||||
| 1611 | { | - | ||||||||||||||||||
| 1612 | return event && (event->response_type & ~0x80); | - | ||||||||||||||||||
| 1613 | } | - | ||||||||||||||||||
| 1614 | - | |||||||||||||||||||
| 1615 | /*! \internal | - | ||||||||||||||||||
| 1616 | - | |||||||||||||||||||
| 1617 | Compresses events of the same type to avoid swamping the event queue. | - | ||||||||||||||||||
| 1618 | If event compression is not desired there are several options what developers can do: | - | ||||||||||||||||||
| 1619 | - | |||||||||||||||||||
| 1620 | 1) Write responsive applications. We drop events that have been buffered in the event | - | ||||||||||||||||||
| 1621 | queue while waiting on unresponsive GUI thread. | - | ||||||||||||||||||
| 1622 | 2) Use QAbstractNativeEventFilter to get all events from X connection. This is not optimal | - | ||||||||||||||||||
| 1623 | because it requires working with native event types. | - | ||||||||||||||||||
| 1624 | 3) Or add public API to Qt for disabling event compression QTBUG-44964 | - | ||||||||||||||||||
| 1625 | - | |||||||||||||||||||
| 1626 | */ | - | ||||||||||||||||||
| 1627 | bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const | - | ||||||||||||||||||
| 1628 | { | - | ||||||||||||||||||
| 1629 | uint responseType = event->response_type & ~0x80; | - | ||||||||||||||||||
| 1630 | int nextIndex = currentIndex + 1; | - | ||||||||||||||||||
| 1631 | - | |||||||||||||||||||
| 1632 | if (responseType == XCB_MOTION_NOTIFY) { | - | ||||||||||||||||||
| 1633 | // compress XCB_MOTION_NOTIFY notify events | - | ||||||||||||||||||
| 1634 | for (int j = nextIndex; j < eventqueue->size(); ++j) { | - | ||||||||||||||||||
| 1635 | xcb_generic_event_t *next = eventqueue->at(j); | - | ||||||||||||||||||
| 1636 | if (!isValid(next)) | - | ||||||||||||||||||
| 1637 | continue; | - | ||||||||||||||||||
| 1638 | if (next->response_type == XCB_MOTION_NOTIFY) | - | ||||||||||||||||||
| 1639 | return true; | - | ||||||||||||||||||
| 1640 | } | - | ||||||||||||||||||
| 1641 | return false; | - | ||||||||||||||||||
| 1642 | } | - | ||||||||||||||||||
| 1643 | #if defined(XCB_USE_XINPUT2) | - | ||||||||||||||||||
| 1644 | // compress XI_* events | - | ||||||||||||||||||
| 1645 | if (responseType == XCB_GE_GENERIC) { | - | ||||||||||||||||||
| 1646 | if (!m_xi2Enabled) | - | ||||||||||||||||||
| 1647 | return false; | - | ||||||||||||||||||
| 1648 | - | |||||||||||||||||||
| 1649 | // compress XI_Motion, but not from tablet devices | - | ||||||||||||||||||
| 1650 | if (isXIType(event, m_xiOpCode, XI_Motion)) { | - | ||||||||||||||||||
| 1651 | #ifndef QT_NO_TABLETEVENT | - | ||||||||||||||||||
| 1652 | xXIDeviceEvent *xdev = reinterpret_cast<xXIDeviceEvent *>(event); | - | ||||||||||||||||||
| 1653 | if (const_cast<QXcbConnection *>(this)->tabletDataForDevice(xdev->sourceid)) | - | ||||||||||||||||||
| 1654 | return false; | - | ||||||||||||||||||
| 1655 | #endif // QT_NO_TABLETEVENT | - | ||||||||||||||||||
| 1656 | for (int j = nextIndex; j < eventqueue->size(); ++j) { | - | ||||||||||||||||||
| 1657 | xcb_generic_event_t *next = eventqueue->at(j); | - | ||||||||||||||||||
| 1658 | if (!isValid(next)) | - | ||||||||||||||||||
| 1659 | continue; | - | ||||||||||||||||||
| 1660 | if (isXIType(next, m_xiOpCode, XI_Motion)) | - | ||||||||||||||||||
| 1661 | return true; | - | ||||||||||||||||||
| 1662 | } | - | ||||||||||||||||||
| 1663 | return false; | - | ||||||||||||||||||
| 1664 | } | - | ||||||||||||||||||
| 1665 | #ifdef XCB_USE_XINPUT22 | - | ||||||||||||||||||
| 1666 | // compress XI_TouchUpdate for the same touch point id | - | ||||||||||||||||||
| 1667 | if (isXIType(event, m_xiOpCode, XI_TouchUpdate)) { | - | ||||||||||||||||||
| 1668 | xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event); | - | ||||||||||||||||||
| 1669 | uint32_t id = xiDeviceEvent->detail % INT_MAX; | - | ||||||||||||||||||
| 1670 | for (int j = nextIndex; j < eventqueue->size(); ++j) { | - | ||||||||||||||||||
| 1671 | xcb_generic_event_t *next = eventqueue->at(j); | - | ||||||||||||||||||
| 1672 | if (!isValid(next)) | - | ||||||||||||||||||
| 1673 | continue; | - | ||||||||||||||||||
| 1674 | if (isXIType(next, m_xiOpCode, XI_TouchUpdate)) { | - | ||||||||||||||||||
| 1675 | xXIDeviceEvent *xiDeviceNextEvent = reinterpret_cast<xXIDeviceEvent *>(next); | - | ||||||||||||||||||
| 1676 | if (id == xiDeviceNextEvent->detail % INT_MAX) | - | ||||||||||||||||||
| 1677 | return true; | - | ||||||||||||||||||
| 1678 | } | - | ||||||||||||||||||
| 1679 | } | - | ||||||||||||||||||
| 1680 | return false; | - | ||||||||||||||||||
| 1681 | } | - | ||||||||||||||||||
| 1682 | #endif | - | ||||||||||||||||||
| 1683 | return false; | - | ||||||||||||||||||
| 1684 | } | - | ||||||||||||||||||
| 1685 | #endif | - | ||||||||||||||||||
| 1686 | if (responseType == XCB_CONFIGURE_NOTIFY) { | - | ||||||||||||||||||
| 1687 | // compress multiple configure notify events for the same window | - | ||||||||||||||||||
| 1688 | for (int j = nextIndex; j < eventqueue->size(); ++j) { | - | ||||||||||||||||||
| 1689 | xcb_generic_event_t *next = eventqueue->at(j); | - | ||||||||||||||||||
| 1690 | if (isValid(next) && next->response_type == XCB_CONFIGURE_NOTIFY | - | ||||||||||||||||||
| 1691 | && ((xcb_configure_notify_event_t *)next)->event == ((xcb_configure_notify_event_t*)event)->event) | - | ||||||||||||||||||
| 1692 | { | - | ||||||||||||||||||
| 1693 | return true; | - | ||||||||||||||||||
| 1694 | } | - | ||||||||||||||||||
| 1695 | } | - | ||||||||||||||||||
| 1696 | return false; | - | ||||||||||||||||||
| 1697 | } | - | ||||||||||||||||||
| 1698 | - | |||||||||||||||||||
| 1699 | return false; | - | ||||||||||||||||||
| 1700 | } | - | ||||||||||||||||||
| 1701 | - | |||||||||||||||||||
| 1702 | void QXcbConnection::processXcbEvents() | - | ||||||||||||||||||
| 1703 | { | - | ||||||||||||||||||
| 1704 | int connection_error = xcb_connection_has_error(xcb_connection()); | - | ||||||||||||||||||
| 1705 | if (connection_error) {
| 0-115472 | ||||||||||||||||||
| 1706 | qWarning("The X11 connection broke (error %d). Did the X11 server die?", connection_error); | - | ||||||||||||||||||
| 1707 | exit(1); never executed: exit(1); | 0 | ||||||||||||||||||
| 1708 | } | - | ||||||||||||||||||
| 1709 | - | |||||||||||||||||||
| 1710 | QXcbEventArray *eventqueue = m_reader->lock(); | - | ||||||||||||||||||
| 1711 | - | |||||||||||||||||||
| 1712 | for (int i = 0; i < eventqueue->size(); ++i) {
| 115472-250026 | ||||||||||||||||||
| 1713 | xcb_generic_event_t *event = eventqueue->at(i); | - | ||||||||||||||||||
| 1714 | if (!event)
| 227-249799 | ||||||||||||||||||
| 1715 | continue; executed 227 times by 23 tests: continue;Executed by:
| 227 | ||||||||||||||||||
| 1716 | QScopedPointer<xcb_generic_event_t, QScopedPointerPodDeleter> eventGuard(event); | - | ||||||||||||||||||
| 1717 | (*eventqueue)[i] = 0; | - | ||||||||||||||||||
| 1718 | - | |||||||||||||||||||
| 1719 | if (!(event->response_type & ~0x80)) {
| 0-249799 | ||||||||||||||||||
| 1720 | handleXcbError((xcb_generic_error_t *)event); | - | ||||||||||||||||||
| 1721 | continue; never executed: continue; | 0 | ||||||||||||||||||
| 1722 | } | - | ||||||||||||||||||
| 1723 | - | |||||||||||||||||||
| 1724 | if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) &&
| 0-249799 | ||||||||||||||||||
| 1725 | compressEvent(event, i, eventqueue))
| 902-248897 | ||||||||||||||||||
| 1726 | continue; executed 902 times by 83 tests: continue;Executed by:
| 902 | ||||||||||||||||||
| 1727 | - | |||||||||||||||||||
| 1728 | bool accepted = false; | - | ||||||||||||||||||
| 1729 | if (clipboard()->processIncr())
| 0-248897 | ||||||||||||||||||
| 1730 | clipboard()->incrTransactionPeeker(event, accepted); never executed: clipboard()->incrTransactionPeeker(event, accepted); | 0 | ||||||||||||||||||
| 1731 | if (accepted)
| 0-248897 | ||||||||||||||||||
| 1732 | continue; never executed: continue; | 0 | ||||||||||||||||||
| 1733 | - | |||||||||||||||||||
| 1734 | QVector<PeekFunc>::iterator itauto isWaitingFor = m_peekFuncs.begin(); | - | ||||||||||||||||||
| while (it != m_peekFuncs.end())[=](PeekFunc peekFunc) { | ||||||||||||||||||||
| 1735 | // These callbacks return true if the event is what they were | - | ||||||||||||||||||
| 1736 | // waiting for, remove them from the list in that case. | - | ||||||||||||||||||
| 1737 | if ((*it)(return peekFunc(this, event)) executed 121824 times by 85 tests: return peekFunc(this, event);Executed by:
| 121824 | ||||||||||||||||||
| it = executed 121824 times by 85 tests: );return peekFunc(this, event);Executed by:
executed 121824 times by 85 tests: return peekFunc(this, event);Executed by:
| ||||||||||||||||||||
| 1738 | }; | - | ||||||||||||||||||
| 1739 | m_peekFuncs.erase(it); | - | ||||||||||||||||||
| else | ||||||||||||||||||||
| ++it; | ||||||||||||||||||||
| }std::remove_if(m_peekFuncs.begin(), m_peekFuncs.end(), | ||||||||||||||||||||
| 1740 | isWaitingFor), | - | ||||||||||||||||||
| 1741 | m_peekFuncs.end()); | - | ||||||||||||||||||
| 1742 | m_reader->unlock(); | - | ||||||||||||||||||
| 1743 | handleXcbEvent(event); | - | ||||||||||||||||||
| 1744 | m_reader->lock(); | - | ||||||||||||||||||
| 1745 | } executed 248897 times by 113 tests: end of blockExecuted by:
| 248897 | ||||||||||||||||||
| 1746 | - | |||||||||||||||||||
| 1747 | eventqueue->clear(); | - | ||||||||||||||||||
| 1748 | - | |||||||||||||||||||
| 1749 | m_reader->unlock(); | - | ||||||||||||||||||
| 1750 | - | |||||||||||||||||||
| 1751 | // Indicate with a null event that the event the callbacks are waiting for | - | ||||||||||||||||||
| 1752 | // is not in the queue currently. | - | ||||||||||||||||||
| 1753 | Q_FOREACHfor (PeekFunc f ,: qAsConst(m_peekFuncs))) | - | ||||||||||||||||||
| 1754 | f(this, 0); executed 1941 times by 83 tests: f(this, 0);Executed by:
| 1941 | ||||||||||||||||||
| 1755 | m_peekFuncs.clear(); | - | ||||||||||||||||||
| 1756 | - | |||||||||||||||||||
| 1757 | xcb_flush(xcb_connection()); | - | ||||||||||||||||||
| 1758 | } executed 115472 times by 113 tests: end of blockExecuted by:
| 115472 | ||||||||||||||||||
| 1759 | - | |||||||||||||||||||
| 1760 | void QXcbConnection::handleClientMessageEvent(const xcb_client_message_event_t *event) | - | ||||||||||||||||||
| 1761 | { | - | ||||||||||||||||||
| 1762 | if (event->format != 32) | - | ||||||||||||||||||
| 1763 | return; | - | ||||||||||||||||||
| 1764 | - | |||||||||||||||||||
| 1765 | #ifndef QT_NO_DRAGANDDROP | - | ||||||||||||||||||
| 1766 | if (event->type == atom(QXcbAtom::XdndStatus)) { | - | ||||||||||||||||||
| 1767 | drag()->handleStatus(event); | - | ||||||||||||||||||
| 1768 | } else if (event->type == atom(QXcbAtom::XdndFinished)) { | - | ||||||||||||||||||
| 1769 | drag()->handleFinished(event); | - | ||||||||||||||||||
| 1770 | } | - | ||||||||||||||||||
| 1771 | #endif | - | ||||||||||||||||||
| 1772 | if (m_systemTrayTracker && event->type == atom(QXcbAtom::MANAGER)) | - | ||||||||||||||||||
| 1773 | m_systemTrayTracker->notifyManagerClientMessageEvent(event); | - | ||||||||||||||||||
| 1774 | - | |||||||||||||||||||
| 1775 | QXcbWindow *window = platformWindowFromId(event->window); | - | ||||||||||||||||||
| 1776 | if (!window) | - | ||||||||||||||||||
| 1777 | return; | - | ||||||||||||||||||
| 1778 | - | |||||||||||||||||||
| 1779 | window->handleClientMessageEvent(event); | - | ||||||||||||||||||
| 1780 | } | - | ||||||||||||||||||
| 1781 | - | |||||||||||||||||||
| 1782 | xcb_generic_event_t *QXcbConnection::checkEvent(int type) | - | ||||||||||||||||||
| 1783 | { | - | ||||||||||||||||||
| 1784 | QXcbEventArray *eventqueue = m_reader->lock(); | - | ||||||||||||||||||
| 1785 | - | |||||||||||||||||||
| 1786 | for (int i = 0; i < eventqueue->size(); ++i) { | - | ||||||||||||||||||
| 1787 | xcb_generic_event_t *event = eventqueue->at(i); | - | ||||||||||||||||||
| 1788 | if (event && event->response_type == type) { | - | ||||||||||||||||||
| 1789 | (*eventqueue)[i] = 0; | - | ||||||||||||||||||
| 1790 | m_reader->unlock(); | - | ||||||||||||||||||
| 1791 | return event; | - | ||||||||||||||||||
| 1792 | } | - | ||||||||||||||||||
| 1793 | } | - | ||||||||||||||||||
| 1794 | - | |||||||||||||||||||
| 1795 | m_reader->unlock(); | - | ||||||||||||||||||
| 1796 | - | |||||||||||||||||||
| 1797 | return 0; | - | ||||||||||||||||||
| 1798 | } | - | ||||||||||||||||||
| 1799 | - | |||||||||||||||||||
| 1800 | static const char * xcb_atomnames = { | - | ||||||||||||||||||
| 1801 | // window-manager <-> client protocols | - | ||||||||||||||||||
| 1802 | "WM_PROTOCOLS\0" | - | ||||||||||||||||||
| 1803 | "WM_DELETE_WINDOW\0" | - | ||||||||||||||||||
| 1804 | "WM_TAKE_FOCUS\0" | - | ||||||||||||||||||
| 1805 | "_NET_WM_PING\0" | - | ||||||||||||||||||
| 1806 | "_NET_WM_CONTEXT_HELP\0" | - | ||||||||||||||||||
| 1807 | "_NET_WM_SYNC_REQUEST\0" | - | ||||||||||||||||||
| 1808 | "_NET_WM_SYNC_REQUEST_COUNTER\0" | - | ||||||||||||||||||
| 1809 | "MANAGER\0" | - | ||||||||||||||||||
| 1810 | "_NET_SYSTEM_TRAY_OPCODE\0" | - | ||||||||||||||||||
| 1811 | - | |||||||||||||||||||
| 1812 | // ICCCM window state | - | ||||||||||||||||||
| 1813 | "WM_STATE\0" | - | ||||||||||||||||||
| 1814 | "WM_CHANGE_STATE\0" | - | ||||||||||||||||||
| 1815 | "WM_CLASS\0" | - | ||||||||||||||||||
| 1816 | "WM_NAME\0" | - | ||||||||||||||||||
| 1817 | - | |||||||||||||||||||
| 1818 | // Session management | - | ||||||||||||||||||
| 1819 | "WM_CLIENT_LEADER\0" | - | ||||||||||||||||||
| 1820 | "WM_WINDOW_ROLE\0" | - | ||||||||||||||||||
| 1821 | "SM_CLIENT_ID\0" | - | ||||||||||||||||||
| 1822 | - | |||||||||||||||||||
| 1823 | // Clipboard | - | ||||||||||||||||||
| 1824 | "CLIPBOARD\0" | - | ||||||||||||||||||
| 1825 | "INCR\0" | - | ||||||||||||||||||
| 1826 | "TARGETS\0" | - | ||||||||||||||||||
| 1827 | "MULTIPLE\0" | - | ||||||||||||||||||
| 1828 | "TIMESTAMP\0" | - | ||||||||||||||||||
| 1829 | "SAVE_TARGETS\0" | - | ||||||||||||||||||
| 1830 | "CLIP_TEMPORARY\0" | - | ||||||||||||||||||
| 1831 | "_QT_SELECTION\0" | - | ||||||||||||||||||
| 1832 | "_QT_CLIPBOARD_SENTINEL\0" | - | ||||||||||||||||||
| 1833 | "_QT_SELECTION_SENTINEL\0" | - | ||||||||||||||||||
| 1834 | "CLIPBOARD_MANAGER\0" | - | ||||||||||||||||||
| 1835 | - | |||||||||||||||||||
| 1836 | "RESOURCE_MANAGER\0" | - | ||||||||||||||||||
| 1837 | - | |||||||||||||||||||
| 1838 | "_XSETROOT_ID\0" | - | ||||||||||||||||||
| 1839 | - | |||||||||||||||||||
| 1840 | "_QT_SCROLL_DONE\0" | - | ||||||||||||||||||
| 1841 | "_QT_INPUT_ENCODING\0" | - | ||||||||||||||||||
| 1842 | - | |||||||||||||||||||
| 1843 | "_QT_CLOSE_CONNECTION\0" | - | ||||||||||||||||||
| 1844 | - | |||||||||||||||||||
| 1845 | "_MOTIF_WM_HINTS\0" | - | ||||||||||||||||||
| 1846 | - | |||||||||||||||||||
| 1847 | "DTWM_IS_RUNNING\0" | - | ||||||||||||||||||
| 1848 | "ENLIGHTENMENT_DESKTOP\0" | - | ||||||||||||||||||
| 1849 | "_DT_SAVE_MODE\0" | - | ||||||||||||||||||
| 1850 | "_SGI_DESKS_MANAGER\0" | - | ||||||||||||||||||
| 1851 | - | |||||||||||||||||||
| 1852 | // EWMH (aka NETWM) | - | ||||||||||||||||||
| 1853 | "_NET_SUPPORTED\0" | - | ||||||||||||||||||
| 1854 | "_NET_VIRTUAL_ROOTS\0" | - | ||||||||||||||||||
| 1855 | "_NET_WORKAREA\0" | - | ||||||||||||||||||
| 1856 | - | |||||||||||||||||||
| 1857 | "_NET_MOVERESIZE_WINDOW\0" | - | ||||||||||||||||||
| 1858 | "_NET_WM_MOVERESIZE\0" | - | ||||||||||||||||||
| 1859 | - | |||||||||||||||||||
| 1860 | "_NET_WM_NAME\0" | - | ||||||||||||||||||
| 1861 | "_NET_WM_ICON_NAME\0" | - | ||||||||||||||||||
| 1862 | "_NET_WM_ICON\0" | - | ||||||||||||||||||
| 1863 | - | |||||||||||||||||||
| 1864 | "_NET_WM_PID\0" | - | ||||||||||||||||||
| 1865 | - | |||||||||||||||||||
| 1866 | "_NET_WM_WINDOW_OPACITY\0" | - | ||||||||||||||||||
| 1867 | - | |||||||||||||||||||
| 1868 | "_NET_WM_STATE\0" | - | ||||||||||||||||||
| 1869 | "_NET_WM_STATE_ABOVE\0" | - | ||||||||||||||||||
| 1870 | "_NET_WM_STATE_BELOW\0" | - | ||||||||||||||||||
| 1871 | "_NET_WM_STATE_FULLSCREEN\0" | - | ||||||||||||||||||
| 1872 | "_NET_WM_STATE_MAXIMIZED_HORZ\0" | - | ||||||||||||||||||
| 1873 | "_NET_WM_STATE_MAXIMIZED_VERT\0" | - | ||||||||||||||||||
| 1874 | "_NET_WM_STATE_MODAL\0" | - | ||||||||||||||||||
| 1875 | "_NET_WM_STATE_STAYS_ON_TOP\0" | - | ||||||||||||||||||
| 1876 | "_NET_WM_STATE_DEMANDS_ATTENTION\0" | - | ||||||||||||||||||
| 1877 | - | |||||||||||||||||||
| 1878 | "_NET_WM_USER_TIME\0" | - | ||||||||||||||||||
| 1879 | "_NET_WM_USER_TIME_WINDOW\0" | - | ||||||||||||||||||
| 1880 | "_NET_WM_FULL_PLACEMENT\0" | - | ||||||||||||||||||
| 1881 | - | |||||||||||||||||||
| 1882 | "_NET_WM_WINDOW_TYPE\0" | - | ||||||||||||||||||
| 1883 | "_NET_WM_WINDOW_TYPE_DESKTOP\0" | - | ||||||||||||||||||
| 1884 | "_NET_WM_WINDOW_TYPE_DOCK\0" | - | ||||||||||||||||||
| 1885 | "_NET_WM_WINDOW_TYPE_TOOLBAR\0" | - | ||||||||||||||||||
| 1886 | "_NET_WM_WINDOW_TYPE_MENU\0" | - | ||||||||||||||||||
| 1887 | "_NET_WM_WINDOW_TYPE_UTILITY\0" | - | ||||||||||||||||||
| 1888 | "_NET_WM_WINDOW_TYPE_SPLASH\0" | - | ||||||||||||||||||
| 1889 | "_NET_WM_WINDOW_TYPE_DIALOG\0" | - | ||||||||||||||||||
| 1890 | "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0" | - | ||||||||||||||||||
| 1891 | "_NET_WM_WINDOW_TYPE_POPUP_MENU\0" | - | ||||||||||||||||||
| 1892 | "_NET_WM_WINDOW_TYPE_TOOLTIP\0" | - | ||||||||||||||||||
| 1893 | "_NET_WM_WINDOW_TYPE_NOTIFICATION\0" | - | ||||||||||||||||||
| 1894 | "_NET_WM_WINDOW_TYPE_COMBO\0" | - | ||||||||||||||||||
| 1895 | "_NET_WM_WINDOW_TYPE_DND\0" | - | ||||||||||||||||||
| 1896 | "_NET_WM_WINDOW_TYPE_NORMAL\0" | - | ||||||||||||||||||
| 1897 | "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0" | - | ||||||||||||||||||
| 1898 | - | |||||||||||||||||||
| 1899 | "_KDE_NET_WM_FRAME_STRUT\0" | - | ||||||||||||||||||
| 1900 | "_NET_FRAME_EXTENTS\0" | - | ||||||||||||||||||
| 1901 | - | |||||||||||||||||||
| 1902 | "_NET_STARTUP_INFO\0" | - | ||||||||||||||||||
| 1903 | "_NET_STARTUP_INFO_BEGIN\0" | - | ||||||||||||||||||
| 1904 | - | |||||||||||||||||||
| 1905 | "_NET_SUPPORTING_WM_CHECK\0" | - | ||||||||||||||||||
| 1906 | - | |||||||||||||||||||
| 1907 | "_NET_WM_CM_S0\0" | - | ||||||||||||||||||
| 1908 | - | |||||||||||||||||||
| 1909 | "_NET_SYSTEM_TRAY_VISUAL\0" | - | ||||||||||||||||||
| 1910 | - | |||||||||||||||||||
| 1911 | "_NET_ACTIVE_WINDOW\0" | - | ||||||||||||||||||
| 1912 | - | |||||||||||||||||||
| 1913 | // Property formats | - | ||||||||||||||||||
| 1914 | "TEXT\0" | - | ||||||||||||||||||
| 1915 | "UTF8_STRING\0" | - | ||||||||||||||||||
| 1916 | "CARDINAL\0" | - | ||||||||||||||||||
| 1917 | - | |||||||||||||||||||
| 1918 | // xdnd | - | ||||||||||||||||||
| 1919 | "XdndEnter\0" | - | ||||||||||||||||||
| 1920 | "XdndPosition\0" | - | ||||||||||||||||||
| 1921 | "XdndStatus\0" | - | ||||||||||||||||||
| 1922 | "XdndLeave\0" | - | ||||||||||||||||||
| 1923 | "XdndDrop\0" | - | ||||||||||||||||||
| 1924 | "XdndFinished\0" | - | ||||||||||||||||||
| 1925 | "XdndTypeList\0" | - | ||||||||||||||||||
| 1926 | "XdndActionList\0" | - | ||||||||||||||||||
| 1927 | - | |||||||||||||||||||
| 1928 | "XdndSelection\0" | - | ||||||||||||||||||
| 1929 | - | |||||||||||||||||||
| 1930 | "XdndAware\0" | - | ||||||||||||||||||
| 1931 | "XdndProxy\0" | - | ||||||||||||||||||
| 1932 | - | |||||||||||||||||||
| 1933 | "XdndActionCopy\0" | - | ||||||||||||||||||
| 1934 | "XdndActionLink\0" | - | ||||||||||||||||||
| 1935 | "XdndActionMove\0" | - | ||||||||||||||||||
| 1936 | "XdndActionPrivate\0" | - | ||||||||||||||||||
| 1937 | - | |||||||||||||||||||
| 1938 | // Motif DND | - | ||||||||||||||||||
| 1939 | "_MOTIF_DRAG_AND_DROP_MESSAGE\0" | - | ||||||||||||||||||
| 1940 | "_MOTIF_DRAG_INITIATOR_INFO\0" | - | ||||||||||||||||||
| 1941 | "_MOTIF_DRAG_RECEIVER_INFO\0" | - | ||||||||||||||||||
| 1942 | "_MOTIF_DRAG_WINDOW\0" | - | ||||||||||||||||||
| 1943 | "_MOTIF_DRAG_TARGETS\0" | - | ||||||||||||||||||
| 1944 | - | |||||||||||||||||||
| 1945 | "XmTRANSFER_SUCCESS\0" | - | ||||||||||||||||||
| 1946 | "XmTRANSFER_FAILURE\0" | - | ||||||||||||||||||
| 1947 | - | |||||||||||||||||||
| 1948 | // Xkb | - | ||||||||||||||||||
| 1949 | "_XKB_RULES_NAMES\0" | - | ||||||||||||||||||
| 1950 | - | |||||||||||||||||||
| 1951 | // XEMBED | - | ||||||||||||||||||
| 1952 | "_XEMBED\0" | - | ||||||||||||||||||
| 1953 | "_XEMBED_INFO\0" | - | ||||||||||||||||||
| 1954 | - | |||||||||||||||||||
| 1955 | // XInput2 | - | ||||||||||||||||||
| 1956 | "Button Left\0" | - | ||||||||||||||||||
| 1957 | "Button Middle\0" | - | ||||||||||||||||||
| 1958 | "Button Right\0" | - | ||||||||||||||||||
| 1959 | "Button Wheel Up\0" | - | ||||||||||||||||||
| 1960 | "Button Wheel Down\0" | - | ||||||||||||||||||
| 1961 | "Button Horiz Wheel Left\0" | - | ||||||||||||||||||
| 1962 | "Button Horiz Wheel Right\0" | - | ||||||||||||||||||
| 1963 | "Abs MT Position X\0" | - | ||||||||||||||||||
| 1964 | "Abs MT Position Y\0" | - | ||||||||||||||||||
| 1965 | "Abs MT Touch Major\0" | - | ||||||||||||||||||
| 1966 | "Abs MT Touch Minor\0" | - | ||||||||||||||||||
| 1967 | "Abs MT Orientation\0" | - | ||||||||||||||||||
| 1968 | "Abs MT Pressure\0" | - | ||||||||||||||||||
| 1969 | "Abs MT Tracking ID\0" | - | ||||||||||||||||||
| 1970 | "Max Contacts\0" | - | ||||||||||||||||||
| 1971 | "Rel X\0" | - | ||||||||||||||||||
| 1972 | "Rel Y\0" | - | ||||||||||||||||||
| 1973 | // XInput2 tablet | - | ||||||||||||||||||
| 1974 | "Abs X\0" | - | ||||||||||||||||||
| 1975 | "Abs Y\0" | - | ||||||||||||||||||
| 1976 | "Abs Pressure\0" | - | ||||||||||||||||||
| 1977 | "Abs Tilt X\0" | - | ||||||||||||||||||
| 1978 | "Abs Tilt Y\0" | - | ||||||||||||||||||
| 1979 | "Abs Wheel\0" | - | ||||||||||||||||||
| 1980 | "Abs Distance\0" | - | ||||||||||||||||||
| 1981 | "Wacom Serial IDs\0" | - | ||||||||||||||||||
| 1982 | "INTEGER\0" | - | ||||||||||||||||||
| 1983 | "Rel Horiz Wheel\0" | - | ||||||||||||||||||
| 1984 | "Rel Vert Wheel\0" | - | ||||||||||||||||||
| 1985 | "Rel Horiz Scroll\0" | - | ||||||||||||||||||
| 1986 | "Rel Vert Scroll\0" | - | ||||||||||||||||||
| 1987 | "_XSETTINGS_SETTINGS\0" | - | ||||||||||||||||||
| 1988 | "_COMPIZ_DECOR_PENDING\0" | - | ||||||||||||||||||
| 1989 | "_COMPIZ_DECOR_REQUEST\0" | - | ||||||||||||||||||
| 1990 | "_COMPIZ_DECOR_DELETE_PIXMAP\0" | - | ||||||||||||||||||
| 1991 | "_COMPIZ_TOOLKIT_ACTION\0" | - | ||||||||||||||||||
| 1992 | "_GTK_LOAD_ICONTHEMES\0" | - | ||||||||||||||||||
| 1993 | // \0\0 terminates loop. | - | ||||||||||||||||||
| 1994 | }; | - | ||||||||||||||||||
| 1995 | - | |||||||||||||||||||
| 1996 | QXcbAtom::Atom QXcbConnection::qatom(xcb_atom_t xatom) const | - | ||||||||||||||||||
| 1997 | { | - | ||||||||||||||||||
| 1998 | return static_cast<QXcbAtom::Atom>(std::find(m_allAtoms, m_allAtoms + QXcbAtom::NAtoms, xatom) - m_allAtoms); | - | ||||||||||||||||||
| 1999 | } | - | ||||||||||||||||||
| 2000 | - | |||||||||||||||||||
| 2001 | void QXcbConnection::initializeAllAtoms() { | - | ||||||||||||||||||
| 2002 | const char *names[QXcbAtom::NAtoms]; | - | ||||||||||||||||||
| 2003 | const char *ptr = xcb_atomnames; | - | ||||||||||||||||||
| 2004 | - | |||||||||||||||||||
| 2005 | int i = 0; | - | ||||||||||||||||||
| 2006 | while (*ptr) { | - | ||||||||||||||||||
| 2007 | names[i++] = ptr; | - | ||||||||||||||||||
| 2008 | while (*ptr) | - | ||||||||||||||||||
| 2009 | ++ptr; | - | ||||||||||||||||||
| 2010 | ++ptr; | - | ||||||||||||||||||
| 2011 | } | - | ||||||||||||||||||
| 2012 | - | |||||||||||||||||||
| 2013 | Q_ASSERT(i == QXcbAtom::NPredefinedAtoms); | - | ||||||||||||||||||
| 2014 | - | |||||||||||||||||||
| 2015 | QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_"); | - | ||||||||||||||||||
| 2016 | settings_atom_name += m_displayName; | - | ||||||||||||||||||
| 2017 | names[i++] = settings_atom_name; | - | ||||||||||||||||||
| 2018 | - | |||||||||||||||||||
| 2019 | xcb_intern_atom_cookie_t cookies[QXcbAtom::NAtoms]; | - | ||||||||||||||||||
| 2020 | - | |||||||||||||||||||
| 2021 | Q_ASSERT(i == QXcbAtom::NAtoms); | - | ||||||||||||||||||
| 2022 | for (i = 0; i < QXcbAtom::NAtoms; ++i) | - | ||||||||||||||||||
| 2023 | cookies[i] = xcb_intern_atom(xcb_connection(), false, strlen(names[i]), names[i]); | - | ||||||||||||||||||
| 2024 | - | |||||||||||||||||||
| 2025 | for (i = 0; i < QXcbAtom::NAtoms; ++i) { | - | ||||||||||||||||||
| 2026 | xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0); | - | ||||||||||||||||||
| 2027 | m_allAtoms[i] = reply->atom; | - | ||||||||||||||||||
| 2028 | free(reply); | - | ||||||||||||||||||
| 2029 | } | - | ||||||||||||||||||
| 2030 | } | - | ||||||||||||||||||
| 2031 | - | |||||||||||||||||||
| 2032 | xcb_atom_t QXcbConnection::internAtom(const char *name) | - | ||||||||||||||||||
| 2033 | { | - | ||||||||||||||||||
| 2034 | if (!name || *name == 0) | - | ||||||||||||||||||
| 2035 | return XCB_NONE; | - | ||||||||||||||||||
| 2036 | - | |||||||||||||||||||
| 2037 | xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcb_connection(), false, strlen(name), name); | - | ||||||||||||||||||
| 2038 | xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookie, 0); | - | ||||||||||||||||||
| 2039 | int atom = reply->atom; | - | ||||||||||||||||||
| 2040 | free(reply); | - | ||||||||||||||||||
| 2041 | return atom; | - | ||||||||||||||||||
| 2042 | } | - | ||||||||||||||||||
| 2043 | - | |||||||||||||||||||
| 2044 | QByteArray QXcbConnection::atomName(xcb_atom_t atom) | - | ||||||||||||||||||
| 2045 | { | - | ||||||||||||||||||
| 2046 | if (!atom) | - | ||||||||||||||||||
| 2047 | return QByteArray(); | - | ||||||||||||||||||
| 2048 | - | |||||||||||||||||||
| 2049 | xcb_generic_error_t *error = 0; | - | ||||||||||||||||||
| 2050 | xcb_get_atom_name_cookie_t cookie = Q_XCB_CALL(xcb_get_atom_name(xcb_connection(), atom)); | - | ||||||||||||||||||
| 2051 | xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(xcb_connection(), cookie, &error); | - | ||||||||||||||||||
| 2052 | if (error) { | - | ||||||||||||||||||
| 2053 | qWarning() << "QXcbConnection::atomName: bad Atom" << atom; | - | ||||||||||||||||||
| 2054 | free(error); | - | ||||||||||||||||||
| 2055 | } | - | ||||||||||||||||||
| 2056 | if (reply) { | - | ||||||||||||||||||
| 2057 | QByteArray result(xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply)); | - | ||||||||||||||||||
| 2058 | free(reply); | - | ||||||||||||||||||
| 2059 | return result; | - | ||||||||||||||||||
| 2060 | } | - | ||||||||||||||||||
| 2061 | return QByteArray(); | - | ||||||||||||||||||
| 2062 | } | - | ||||||||||||||||||
| 2063 | - | |||||||||||||||||||
| 2064 | const xcb_format_t *QXcbConnection::formatForDepth(uint8_t depth) const | - | ||||||||||||||||||
| 2065 | { | - | ||||||||||||||||||
| 2066 | xcb_format_iterator_t iterator = | - | ||||||||||||||||||
| 2067 | xcb_setup_pixmap_formats_iterator(m_setup); | - | ||||||||||||||||||
| 2068 | - | |||||||||||||||||||
| 2069 | while (iterator.rem) { | - | ||||||||||||||||||
| 2070 | xcb_format_t *format = iterator.data; | - | ||||||||||||||||||
| 2071 | if (format->depth == depth) | - | ||||||||||||||||||
| 2072 | return format; | - | ||||||||||||||||||
| 2073 | xcb_format_next(&iterator); | - | ||||||||||||||||||
| 2074 | } | - | ||||||||||||||||||
| 2075 | - | |||||||||||||||||||
| 2076 | return 0; | - | ||||||||||||||||||
| 2077 | } | - | ||||||||||||||||||
| 2078 | - | |||||||||||||||||||
| 2079 | void QXcbConnection::sync() | - | ||||||||||||||||||
| 2080 | { | - | ||||||||||||||||||
| 2081 | // from xcb_aux_sync | - | ||||||||||||||||||
| 2082 | xcb_get_input_focus_cookie_t cookie = Q_XCB_CALL(xcb_get_input_focus(xcb_connection())); | - | ||||||||||||||||||
| 2083 | free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0)); | - | ||||||||||||||||||
| 2084 | } | - | ||||||||||||||||||
| 2085 | - | |||||||||||||||||||
| 2086 | void QXcbConnection::initializeXFixes() | - | ||||||||||||||||||
| 2087 | { | - | ||||||||||||||||||
| 2088 | xcb_generic_error_t *error = 0; | - | ||||||||||||||||||
| 2089 | const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xfixes_id); | - | ||||||||||||||||||
| 2090 | if (!reply || !reply->present) | - | ||||||||||||||||||
| 2091 | return; | - | ||||||||||||||||||
| 2092 | - | |||||||||||||||||||
| 2093 | xfixes_first_event = reply->first_event; | - | ||||||||||||||||||
| 2094 | xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection, | - | ||||||||||||||||||
| 2095 | XCB_XFIXES_MAJOR_VERSION, | - | ||||||||||||||||||
| 2096 | XCB_XFIXES_MINOR_VERSION); | - | ||||||||||||||||||
| 2097 | xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection, | - | ||||||||||||||||||
| 2098 | xfixes_query_cookie, &error); | - | ||||||||||||||||||
| 2099 | if (!xfixes_query || error || xfixes_query->major_version < 2) { | - | ||||||||||||||||||
| 2100 | qWarning("QXcbConnection: Failed to initialize XFixes"); | - | ||||||||||||||||||
| 2101 | free(error); | - | ||||||||||||||||||
| 2102 | xfixes_first_event = 0; | - | ||||||||||||||||||
| 2103 | } | - | ||||||||||||||||||
| 2104 | free(xfixes_query); | - | ||||||||||||||||||
| 2105 | } | - | ||||||||||||||||||
| 2106 | - | |||||||||||||||||||
| 2107 | void QXcbConnection::initializeXRender() | - | ||||||||||||||||||
| 2108 | { | - | ||||||||||||||||||
| 2109 | #ifdef XCB_USE_RENDER | - | ||||||||||||||||||
| 2110 | const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_render_id); | - | ||||||||||||||||||
| 2111 | if (!reply || !reply->present) | - | ||||||||||||||||||
| 2112 | return; | - | ||||||||||||||||||
| 2113 | - | |||||||||||||||||||
| 2114 | xcb_generic_error_t *error = 0; | - | ||||||||||||||||||
| 2115 | xcb_render_query_version_cookie_t xrender_query_cookie = xcb_render_query_version(m_connection, | - | ||||||||||||||||||
| 2116 | XCB_RENDER_MAJOR_VERSION, | - | ||||||||||||||||||
| 2117 | XCB_RENDER_MINOR_VERSION); | - | ||||||||||||||||||
| 2118 | xcb_render_query_version_reply_t *xrender_query = xcb_render_query_version_reply(m_connection, | - | ||||||||||||||||||
| 2119 | xrender_query_cookie, &error); | - | ||||||||||||||||||
| 2120 | if (!xrender_query || error || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) { | - | ||||||||||||||||||
| 2121 | qWarning("QXcbConnection: Failed to initialize XRender"); | - | ||||||||||||||||||
| 2122 | free(error); | - | ||||||||||||||||||
| 2123 | } | - | ||||||||||||||||||
| 2124 | free(xrender_query); | - | ||||||||||||||||||
| 2125 | #endif | - | ||||||||||||||||||
| 2126 | } | - | ||||||||||||||||||
| 2127 | - | |||||||||||||||||||
| 2128 | void QXcbConnection::initializeXRandr() | - | ||||||||||||||||||
| 2129 | { | - | ||||||||||||||||||
| 2130 | const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_randr_id); | - | ||||||||||||||||||
| 2131 | if (!reply || !reply->present) | - | ||||||||||||||||||
| 2132 | return; | - | ||||||||||||||||||
| 2133 | - | |||||||||||||||||||
| 2134 | xrandr_first_event = reply->first_event; | - | ||||||||||||||||||
| 2135 | - | |||||||||||||||||||
| 2136 | xcb_generic_error_t *error = 0; | - | ||||||||||||||||||
| 2137 | xcb_randr_query_version_cookie_t xrandr_query_cookie = xcb_randr_query_version(m_connection, | - | ||||||||||||||||||
| 2138 | XCB_RANDR_MAJOR_VERSION, | - | ||||||||||||||||||
| 2139 | XCB_RANDR_MINOR_VERSION); | - | ||||||||||||||||||
| 2140 | - | |||||||||||||||||||
| 2141 | has_randr_extension = true; | - | ||||||||||||||||||
| 2142 | - | |||||||||||||||||||
| 2143 | xcb_randr_query_version_reply_t *xrandr_query = xcb_randr_query_version_reply(m_connection, | - | ||||||||||||||||||
| 2144 | xrandr_query_cookie, &error); | - | ||||||||||||||||||
| 2145 | if (!xrandr_query || error || (xrandr_query->major_version < 1 || (xrandr_query->major_version == 1 && xrandr_query->minor_version < 2))) { | - | ||||||||||||||||||
| 2146 | qWarning("QXcbConnection: Failed to initialize XRandr"); | - | ||||||||||||||||||
| 2147 | free(error); | - | ||||||||||||||||||
| 2148 | has_randr_extension = false; | - | ||||||||||||||||||
| 2149 | } | - | ||||||||||||||||||
| 2150 | free(xrandr_query); | - | ||||||||||||||||||
| 2151 | - | |||||||||||||||||||
| 2152 | xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(m_setup); | - | ||||||||||||||||||
| 2153 | for (; rootIter.rem; xcb_screen_next(&rootIter)) { | - | ||||||||||||||||||
| 2154 | xcb_randr_select_input(xcb_connection(), | - | ||||||||||||||||||
| 2155 | rootIter.data->root, | - | ||||||||||||||||||
| 2156 | XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE | | - | ||||||||||||||||||
| 2157 | XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | | - | ||||||||||||||||||
| 2158 | XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | | - | ||||||||||||||||||
| 2159 | XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY | - | ||||||||||||||||||
| 2160 | ); | - | ||||||||||||||||||
| 2161 | } | - | ||||||||||||||||||
| 2162 | } | - | ||||||||||||||||||
| 2163 | - | |||||||||||||||||||
| 2164 | void QXcbConnection::initializeXinerama() | - | ||||||||||||||||||
| 2165 | { | - | ||||||||||||||||||
| 2166 | const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xinerama_id); | - | ||||||||||||||||||
| 2167 | if (!reply || !reply->present) | - | ||||||||||||||||||
| 2168 | return; | - | ||||||||||||||||||
| 2169 | - | |||||||||||||||||||
| 2170 | xcb_generic_error_t *error = Q_NULLPTR; | - | ||||||||||||||||||
| 2171 | xcb_xinerama_is_active_cookie_t xinerama_query_cookie = xcb_xinerama_is_active(m_connection); | - | ||||||||||||||||||
| 2172 | xcb_xinerama_is_active_reply_t *xinerama_is_active = xcb_xinerama_is_active_reply(m_connection, | - | ||||||||||||||||||
| 2173 | xinerama_query_cookie, | - | ||||||||||||||||||
| 2174 | &error); | - | ||||||||||||||||||
| 2175 | has_xinerama_extension = xinerama_is_active && !error && xinerama_is_active->state; | - | ||||||||||||||||||
| 2176 | free(error); | - | ||||||||||||||||||
| 2177 | free(xinerama_is_active); | - | ||||||||||||||||||
| 2178 | } | - | ||||||||||||||||||
| 2179 | - | |||||||||||||||||||
| 2180 | void QXcbConnection::initializeXShape() | - | ||||||||||||||||||
| 2181 | { | - | ||||||||||||||||||
| 2182 | const xcb_query_extension_reply_t *xshape_reply = xcb_get_extension_data(m_connection, &xcb_shape_id); | - | ||||||||||||||||||
| 2183 | if (!xshape_reply || !xshape_reply->present) | - | ||||||||||||||||||
| 2184 | return; | - | ||||||||||||||||||
| 2185 | - | |||||||||||||||||||
| 2186 | has_shape_extension = true; | - | ||||||||||||||||||
| 2187 | xcb_shape_query_version_cookie_t cookie = xcb_shape_query_version(m_connection); | - | ||||||||||||||||||
| 2188 | xcb_shape_query_version_reply_t *shape_query = xcb_shape_query_version_reply(m_connection, | - | ||||||||||||||||||
| 2189 | cookie, NULL); | - | ||||||||||||||||||
| 2190 | if (!shape_query) { | - | ||||||||||||||||||
| 2191 | qWarning("QXcbConnection: Failed to initialize SHAPE extension"); | - | ||||||||||||||||||
| 2192 | } else if (shape_query->major_version > 1 || (shape_query->major_version == 1 && shape_query->minor_version >= 1)) { | - | ||||||||||||||||||
| 2193 | // The input shape is the only thing added in SHAPE 1.1 | - | ||||||||||||||||||
| 2194 | has_input_shape = true; | - | ||||||||||||||||||
| 2195 | } | - | ||||||||||||||||||
| 2196 | free(shape_query); | - | ||||||||||||||||||
| 2197 | } | - | ||||||||||||||||||
| 2198 | - | |||||||||||||||||||
| 2199 | void QXcbConnection::initializeXKB() | - | ||||||||||||||||||
| 2200 | { | - | ||||||||||||||||||
| 2201 | #ifndef QT_NO_XKB | - | ||||||||||||||||||
| 2202 | const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xkb_id); | - | ||||||||||||||||||
| 2203 | if (!reply || !reply->present) {
| 0-135 | ||||||||||||||||||
| 2204 | qWarning() << ("Qt: XKEYBOARD extension not present on the X server.";); | - | ||||||||||||||||||
| 2205 | xkb_first_event = 0; | - | ||||||||||||||||||
| 2206 | return; never executed: return; | 0 | ||||||||||||||||||
| 2207 | } | - | ||||||||||||||||||
| 2208 | xkb_first_event = reply->first_event; | - | ||||||||||||||||||
| 2209 | - | |||||||||||||||||||
| 2210 | xcb_connection_t *c = connection()->xcb_connection(); | - | ||||||||||||||||||
| 2211 | xcb_xkb_use_extension_cookie_t xkb_query_cookie; | - | ||||||||||||||||||
| 2212 | xcb_xkb_use_extension_reply_t *xkb_query; | - | ||||||||||||||||||
| 2213 | - | |||||||||||||||||||
| 2214 | xkb_query_cookie = xcb_xkb_use_extension(c, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION); | - | ||||||||||||||||||
| 2215 | xkb_query = xcb_xkb_use_extension_reply(c, xkb_query_cookie, 0); | - | ||||||||||||||||||
| 2216 | - | |||||||||||||||||||
| 2217 | if (!xkb_query) {
| 0-135 | ||||||||||||||||||
| 2218 | qWarning("Qt: Failed to initialize XKB extension"); | - | ||||||||||||||||||
| 2219 | return; never executed: return; | 0 | ||||||||||||||||||
| 2220 | } else if (!xkb_query->supported) {
| 0-135 | ||||||||||||||||||
| 2221 | qWarning("Qt: Unsupported XKB version (We want %d %d, but X server has %d %d)", | - | ||||||||||||||||||
| 2222 | XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION, | - | ||||||||||||||||||
| 2223 | xkb_query->serverMajor, xkb_query->serverMinor); | - | ||||||||||||||||||
| 2224 | free(xkb_query); | - | ||||||||||||||||||
| 2225 | return; never executed: return; | 0 | ||||||||||||||||||
| 2226 | } | - | ||||||||||||||||||
| 2227 | - | |||||||||||||||||||
| 2228 | has_xkb = true; | - | ||||||||||||||||||
| 2229 | free(xkb_query); | - | ||||||||||||||||||
| 2230 | - | |||||||||||||||||||
| 2231 | const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES | | - | ||||||||||||||||||
| 2232 | XCB_XKB_MAP_PART_KEY_SYMS | | - | ||||||||||||||||||
| 2233 | XCB_XKB_MAP_PART_MODIFIER_MAP | | - | ||||||||||||||||||
| 2234 | XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | | - | ||||||||||||||||||
| 2235 | XCB_XKB_MAP_PART_KEY_ACTIONS | | - | ||||||||||||||||||
| 2236 | XCB_XKB_MAP_PART_KEY_BEHAVIORS | | - | ||||||||||||||||||
| 2237 | XCB_XKB_MAP_PART_VIRTUAL_MODS | | - | ||||||||||||||||||
| 2238 | XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP); | - | ||||||||||||||||||
| 2239 | - | |||||||||||||||||||
| 2240 | const uint16_t required_events = (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | | - | ||||||||||||||||||
| 2241 | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | | - | ||||||||||||||||||
| 2242 | XCB_XKB_EVENT_TYPE_STATE_NOTIFY); | - | ||||||||||||||||||
| 2243 | - | |||||||||||||||||||
| 2244 | // XKB events are reported to all interested clients without regard | - | ||||||||||||||||||
| 2245 | // to the current keyboard input focus or grab state | - | ||||||||||||||||||
| 2246 | xcb_void_cookie_t select = xcb_xkb_select_events_checked(c, | - | ||||||||||||||||||
| 2247 | XCB_XKB_ID_USE_CORE_KBD, | - | ||||||||||||||||||
| 2248 | required_events, | - | ||||||||||||||||||
| 2249 | 0, | - | ||||||||||||||||||
| 2250 | required_events, | - | ||||||||||||||||||
| 2251 | required_map_parts, | - | ||||||||||||||||||
| 2252 | required_map_parts, | - | ||||||||||||||||||
| 2253 | 0); | - | ||||||||||||||||||
| 2254 | - | |||||||||||||||||||
| 2255 | xcb_generic_error_t *error = xcb_request_check(c, select); | - | ||||||||||||||||||
| 2256 | if (error) {
| 0-135 | ||||||||||||||||||
| 2257 | free(error); | - | ||||||||||||||||||
| 2258 | qWarning() << ("Qt: failed to select notify events from xcb-xkb";); | - | ||||||||||||||||||
| 2259 | return; never executed: return; | 0 | ||||||||||||||||||
| 2260 | } | - | ||||||||||||||||||
| 2261 | #endif | - | ||||||||||||||||||
| 2262 | } executed 135 times by 5 tests: end of blockExecuted by:
| 135 | ||||||||||||||||||
| 2263 | - | |||||||||||||||||||
| 2264 | #if defined(XCB_USE_XINPUT22) | - | ||||||||||||||||||
| 2265 | bool QXcbConnection::xi2MouseEvents() const | - | ||||||||||||||||||
| 2266 | { | - | ||||||||||||||||||
| 2267 | static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); | - | ||||||||||||||||||
| 2268 | // FIXME: Don't use XInput2 mouse events when Xinerama extension | - | ||||||||||||||||||
| 2269 | // is enabled, because it causes problems with multi-monitor setup. | - | ||||||||||||||||||
| 2270 | return mouseViaXI2 && !has_xinerama_extension; | - | ||||||||||||||||||
| 2271 | } | - | ||||||||||||||||||
| 2272 | #endif | - | ||||||||||||||||||
| 2273 | - | |||||||||||||||||||
| 2274 | #if defined(XCB_USE_XINPUT2) | - | ||||||||||||||||||
| 2275 | static int xi2ValuatorOffset(const unsigned char *maskPtr, int maskLen, int number) | - | ||||||||||||||||||
| 2276 | { | - | ||||||||||||||||||
| 2277 | int offset = 0; | - | ||||||||||||||||||
| 2278 | for (int i = 0; i < maskLen; i++) {
| 0 | ||||||||||||||||||
| 2279 | if (number < 8) {
| 0 | ||||||||||||||||||
| 2280 | if ((maskPtr[i] & (1 << number)) == 0)
| 0 | ||||||||||||||||||
| 2281 | return -1; never executed: return -1; | 0 | ||||||||||||||||||
| 2282 | } never executed: end of block | 0 | ||||||||||||||||||
| 2283 | for (int j = 0; j < 8; j++) {
| 0 | ||||||||||||||||||
| 2284 | if (j == number)
| 0 | ||||||||||||||||||
| 2285 | return offset; never executed: return offset; | 0 | ||||||||||||||||||
| 2286 | if (maskPtr[i] & (1 << j))
| 0 | ||||||||||||||||||
| 2287 | offset++; never executed: offset++; | 0 | ||||||||||||||||||
| 2288 | } never executed: end of block | 0 | ||||||||||||||||||
| 2289 | number -= 8; | - | ||||||||||||||||||
| 2290 | } never executed: end of block | 0 | ||||||||||||||||||
| 2291 | return -1; never executed: return -1; | 0 | ||||||||||||||||||
| 2292 | } | - | ||||||||||||||||||
| 2293 | - | |||||||||||||||||||
| 2294 | bool QXcbConnection::xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value) | - | ||||||||||||||||||
| 2295 | { | - | ||||||||||||||||||
| 2296 | const xXIDeviceEvent *xideviceevent = static_cast<const xXIDeviceEvent *>(event); | - | ||||||||||||||||||
| 2297 | const unsigned char *buttonsMaskAddr = (const unsigned char*)&xideviceevent[1]; | - | ||||||||||||||||||
| 2298 | const unsigned char *valuatorsMaskAddr = buttonsMaskAddr + xideviceevent->buttons_len * 4; | - | ||||||||||||||||||
| 2299 | FP3232 *valuatorsValuesAddr = (FP3232*)(valuatorsMaskAddr + xideviceevent->valuators_len * 4); | - | ||||||||||||||||||
| 2300 | - | |||||||||||||||||||
| 2301 | int valuatorOffset = xi2ValuatorOffset(valuatorsMaskAddr, xideviceevent->valuators_len, valuatorNum); | - | ||||||||||||||||||
| 2302 | if (valuatorOffset < 0)
| 0 | ||||||||||||||||||
| 2303 | return false; never executed: return false; | 0 | ||||||||||||||||||
| 2304 | - | |||||||||||||||||||
| 2305 | *value = valuatorsValuesAddr[valuatorOffset].integral; | - | ||||||||||||||||||
| 2306 | *value += ((double)valuatorsValuesAddr[valuatorOffset].frac / (1 << 16) / (1 << 16)); | - | ||||||||||||||||||
| 2307 | return true; never executed: return true; | 0 | ||||||||||||||||||
| 2308 | } | - | ||||||||||||||||||
| 2309 | - | |||||||||||||||||||
| 2310 | void QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event) | - | ||||||||||||||||||
| 2311 | { | - | ||||||||||||||||||
| 2312 | // xcb event structs contain stuff that wasn't on the wire, the full_sequence field | - | ||||||||||||||||||
| 2313 | // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes. | - | ||||||||||||||||||
| 2314 | // Move this data back to have the same layout in memory as it was on the wire | - | ||||||||||||||||||
| 2315 | // and allow casting, overwriting the full_sequence field. | - | ||||||||||||||||||
| 2316 | memmove((char*) event + 32, (char*) event + 36, event->length * 4); | - | ||||||||||||||||||
| 2317 | } | - | ||||||||||||||||||
| 2318 | #endif // defined(XCB_USE_XINPUT2) | - | ||||||||||||||||||
| 2319 | - | |||||||||||||||||||
| 2320 | QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const | - | ||||||||||||||||||
| 2321 | { | - | ||||||||||||||||||
| 2322 | if (!m_systemTrayTracker) { | - | ||||||||||||||||||
| 2323 | QXcbConnection *self = const_cast<QXcbConnection *>(this); | - | ||||||||||||||||||
| 2324 | if ((self->m_systemTrayTracker = QXcbSystemTrayTracker::create(self))) { | - | ||||||||||||||||||
| 2325 | connect(m_systemTrayTracker, SIGNAL(systemTrayWindowChanged(QScreen*)), | - | ||||||||||||||||||
| 2326 | QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*))); | - | ||||||||||||||||||
| 2327 | } | - | ||||||||||||||||||
| 2328 | } | - | ||||||||||||||||||
| 2329 | return m_systemTrayTracker; | - | ||||||||||||||||||
| 2330 | } | - | ||||||||||||||||||
| 2331 | - | |||||||||||||||||||
| 2332 | bool QXcbConnection::xEmbedSystemTrayAvailable() | - | ||||||||||||||||||
| 2333 | { | - | ||||||||||||||||||
| 2334 | if (!QGuiApplicationPrivate::platformIntegration()) | - | ||||||||||||||||||
| 2335 | return false; | - | ||||||||||||||||||
| 2336 | QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection(); | - | ||||||||||||||||||
| 2337 | return connection->systemTrayTracker(); | - | ||||||||||||||||||
| 2338 | } | - | ||||||||||||||||||
| 2339 | - | |||||||||||||||||||
| 2340 | bool QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel() | - | ||||||||||||||||||
| 2341 | { | - | ||||||||||||||||||
| 2342 | if (!QGuiApplicationPrivate::platformIntegration()) | - | ||||||||||||||||||
| 2343 | return false; | - | ||||||||||||||||||
| 2344 | QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection(); | - | ||||||||||||||||||
| 2345 | return connection->systemTrayTracker() && connection->systemTrayTracker()->visualHasAlphaChannel(); | - | ||||||||||||||||||
| 2346 | } | - | ||||||||||||||||||
| 2347 | - | |||||||||||||||||||
| 2348 | bool QXcbConnection::event(QEvent *e) | - | ||||||||||||||||||
| 2349 | { | - | ||||||||||||||||||
| 2350 | if (e->type() == QEvent::User + 1) { | - | ||||||||||||||||||
| 2351 | QXcbSyncWindowRequest *ev = static_cast<QXcbSyncWindowRequest *>(e); | - | ||||||||||||||||||
| 2352 | QXcbWindow *w = ev->window(); | - | ||||||||||||||||||
| 2353 | if (w) { | - | ||||||||||||||||||
| 2354 | w->updateSyncRequestCounter(); | - | ||||||||||||||||||
| 2355 | ev->invalidate(); | - | ||||||||||||||||||
| 2356 | } | - | ||||||||||||||||||
| 2357 | return true; | - | ||||||||||||||||||
| 2358 | } | - | ||||||||||||||||||
| 2359 | return QObject::event(e); | - | ||||||||||||||||||
| 2360 | } | - | ||||||||||||||||||
| 2361 | - | |||||||||||||||||||
| 2362 | void QXcbSyncWindowRequest::invalidate() | - | ||||||||||||||||||
| 2363 | { | - | ||||||||||||||||||
| 2364 | if (m_window) { | - | ||||||||||||||||||
| 2365 | m_window->clearSyncWindowRequest(); | - | ||||||||||||||||||
| 2366 | m_window = 0; | - | ||||||||||||||||||
| 2367 | } | - | ||||||||||||||||||
| 2368 | } | - | ||||||||||||||||||
| 2369 | - | |||||||||||||||||||
| 2370 | QXcbConnectionGrabber::QXcbConnectionGrabber(QXcbConnection *connection) | - | ||||||||||||||||||
| 2371 | :m_connection(connection) | - | ||||||||||||||||||
| 2372 | { | - | ||||||||||||||||||
| 2373 | connection->grabServer(); | - | ||||||||||||||||||
| 2374 | } | - | ||||||||||||||||||
| 2375 | - | |||||||||||||||||||
| 2376 | QXcbConnectionGrabber::~QXcbConnectionGrabber() | - | ||||||||||||||||||
| 2377 | { | - | ||||||||||||||||||
| 2378 | if (m_connection) | - | ||||||||||||||||||
| 2379 | m_connection->ungrabServer(); | - | ||||||||||||||||||
| 2380 | } | - | ||||||||||||||||||
| 2381 | - | |||||||||||||||||||
| 2382 | void QXcbConnectionGrabber::release() | - | ||||||||||||||||||
| 2383 | { | - | ||||||||||||||||||
| 2384 | if (m_connection) { | - | ||||||||||||||||||
| 2385 | m_connection->ungrabServer(); | - | ||||||||||||||||||
| 2386 | m_connection = 0; | - | ||||||||||||||||||
| 2387 | } | - | ||||||||||||||||||
| 2388 | } | - | ||||||||||||||||||
| 2389 | - | |||||||||||||||||||
| 2390 | QT_END_NAMESPACE | - | ||||||||||||||||||
| Source code | Switch to Preprocessed file |