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 block Executed 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 block Executed by:
| 135 | ||||||||||||||||||
488 | } executed 135 times by 5 tests: end of block Executed by:
| 135 | ||||||||||||||||||
489 | } executed 135 times by 5 tests: end of block Executed by:
| 135 | ||||||||||||||||||
490 | } executed 135 times by 5 tests: end of block Executed by:
| 135 | ||||||||||||||||||
491 | } | - | ||||||||||||||||||
492 | } executed 135 times by 5 tests: end of block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed by:
| 135 | ||||||||||||||||||
679 | - | |||||||||||||||||||
680 | sync(); | - | ||||||||||||||||||
681 | } executed 135 times by 5 tests: end of block Executed 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 block Executed 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 block never 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 block never 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 block never 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 block Executed 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 block Executed 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 block Executed 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 block executed 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 block never 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 block never 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 block Executed 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 block Executed 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 block never 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 block never 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 |