1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://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 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QXCBCONNECTION_H
43 #define QXCBCONNECTION_H
44
45 #include <xcb/xcb.h>
46
47 #include <QList>
48 #include <QObject>
49 #include <QVector>
50
51 #define Q_XCB_DEBUG
52
53 class QXcbScreen;
54
55 namespace QXcbAtom {
56 enum Atom {
57 // window-manager <-> client protocols
58 WM_PROTOCOLS,
59 WM_DELETE_WINDOW,
60 WM_TAKE_FOCUS,
61 _NET_WM_PING,
62 _NET_WM_CONTEXT_HELP,
63 _NET_WM_SYNC_REQUEST,
64 _NET_WM_SYNC_REQUEST_COUNTER,
65
66 // ICCCM window state
67 WM_STATE,
68 WM_CHANGE_STATE,
69
70 // Session management
71 WM_CLIENT_LEADER,
72 WM_WINDOW_ROLE,
73 SM_CLIENT_ID,
74
75 // Clipboard
76 CLIPBOARD,
77 INCR,
78 TARGETS,
79 MULTIPLE,
80 TIMESTAMP,
81 SAVE_TARGETS,
82 CLIP_TEMPORARY,
83 _QT_SELECTION,
84 _QT_CLIPBOARD_SENTINEL,
85 _QT_SELECTION_SENTINEL,
86 CLIPBOARD_MANAGER,
87
88 RESOURCE_MANAGER,
89
90 _XSETROOT_ID,
91
92 _QT_SCROLL_DONE,
93 _QT_INPUT_ENCODING,
94
95 _MOTIF_WM_HINTS,
96
97 DTWM_IS_RUNNING,
98 ENLIGHTENMENT_DESKTOP,
99 _DT_SAVE_MODE,
100 _SGI_DESKS_MANAGER,
101
102 // EWMH (aka NETWM)
103 _NET_SUPPORTED,
104 _NET_VIRTUAL_ROOTS,
105 _NET_WORKAREA,
106
107 _NET_MOVERESIZE_WINDOW,
108 _NET_WM_MOVERESIZE,
109
110 _NET_WM_NAME,
111 _NET_WM_ICON_NAME,
112 _NET_WM_ICON,
113
114 _NET_WM_PID,
115
116 _NET_WM_WINDOW_OPACITY,
117
118 _NET_WM_STATE,
119 _NET_WM_STATE_ABOVE,
120 _NET_WM_STATE_BELOW,
121 _NET_WM_STATE_FULLSCREEN,
122 _NET_WM_STATE_MAXIMIZED_HORZ,
123 _NET_WM_STATE_MAXIMIZED_VERT,
124 _NET_WM_STATE_MODAL,
125 _NET_WM_STATE_STAYS_ON_TOP,
126 _NET_WM_STATE_DEMANDS_ATTENTION,
127
128 _NET_WM_USER_TIME,
129 _NET_WM_USER_TIME_WINDOW,
130 _NET_WM_FULL_PLACEMENT,
131
132 _NET_WM_WINDOW_TYPE,
133 _NET_WM_WINDOW_TYPE_DESKTOP,
134 _NET_WM_WINDOW_TYPE_DOCK,
135 _NET_WM_WINDOW_TYPE_TOOLBAR,
136 _NET_WM_WINDOW_TYPE_MENU,
137 _NET_WM_WINDOW_TYPE_UTILITY,
138 _NET_WM_WINDOW_TYPE_SPLASH,
139 _NET_WM_WINDOW_TYPE_DIALOG,
140 _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
141 _NET_WM_WINDOW_TYPE_POPUP_MENU,
142 _NET_WM_WINDOW_TYPE_TOOLTIP,
143 _NET_WM_WINDOW_TYPE_NOTIFICATION,
144 _NET_WM_WINDOW_TYPE_COMBO,
145 _NET_WM_WINDOW_TYPE_DND,
146 _NET_WM_WINDOW_TYPE_NORMAL,
147 _KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
148
149 _KDE_NET_WM_FRAME_STRUT,
150
151 _NET_STARTUP_INFO,
152 _NET_STARTUP_INFO_BEGIN,
153
154 _NET_SUPPORTING_WM_CHECK,
155
156 _NET_WM_CM_S0,
157
158 _NET_SYSTEM_TRAY_VISUAL,
159
160 _NET_ACTIVE_WINDOW,
161
162 // Property formats
163 COMPOUND_TEXT,
164 TEXT,
165 UTF8_STRING,
166
167 // Xdnd
168 XdndEnter,
169 XdndPosition,
170 XdndStatus,
171 XdndLeave,
172 XdndDrop,
173 XdndFinished,
174 XdndTypelist,
175 XdndActionList,
176
177 XdndSelection,
178
179 XdndAware,
180 XdndProxy,
181
182 XdndActionCopy,
183 XdndActionLink,
184 XdndActionMove,
185 XdndActionPrivate,
186
187 // Motif DND
188 _MOTIF_DRAG_AND_DROP_MESSAGE,
189 _MOTIF_DRAG_INITIATOR_INFO,
190 _MOTIF_DRAG_RECEIVER_INFO,
191 _MOTIF_DRAG_WINDOW,
192 _MOTIF_DRAG_TARGETS,
193
194 XmTRANSFER_SUCCESS,
195 XmTRANSFER_FAILURE,
196
197 // Xkb
198 _XKB_RULES_NAMES,
199
200 // XEMBED
201 _XEMBED,
202 _XEMBED_INFO,
203
204 XWacomStylus,
205 XWacomCursor,
206 XWacomEraser,
207
208 XTabletStylus,
209 XTabletEraser,
210
211 NPredefinedAtoms,
212
213 _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
214 NAtoms
215 };
216 }
217
218 class QXcbKeyboard;
219
220 class QXcbConnection : public QObject
221 {
222 Q_OBJECT
223 public:
224 QXcbConnection(const char *displayName = 0);
225 ~QXcbConnection();
226
connection()227 QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
228
screens()229 QList<QXcbScreen *> screens() const { return m_screens; }
primaryScreen()230 int primaryScreen() const { return m_primaryScreen; }
231
232 xcb_atom_t atom(QXcbAtom::Atom atom);
233
displayName()234 const char *displayName() const { return m_displayName.constData(); }
235
xcb_connection()236 xcb_connection_t *xcb_connection() const { return m_connection; }
237
keyboard()238 QXcbKeyboard *keyboard() const { return m_keyboard; }
239
240 #ifdef XCB_USE_XLIB
xlib_display()241 void *xlib_display() const { return m_xlib_display; }
242 #endif
243
244 #ifdef XCB_USE_DRI2
245 bool hasSupportForDri2() const;
dri2DeviceName()246 QByteArray dri2DeviceName() const { return m_dri2_device_name; }
247 #endif
248 #ifdef XCB_USE_EGL
249 bool hasEgl() const;
250 #endif
251 #if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
egl_display()252 void *egl_display() const { return m_egl_display; }
253 #endif
254
255 void sync();
256 void handleXcbError(xcb_generic_error_t *error);
257
258 private slots:
259 void processXcbEvents();
260
261 private:
262 void initializeAllAtoms();
263 void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
264 #ifdef XCB_USE_DRI2
265 void initializeDri2();
266 #endif
267
268 xcb_connection_t *m_connection;
269 const xcb_setup_t *m_setup;
270
271 QList<QXcbScreen *> m_screens;
272 int m_primaryScreen;
273
274 xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
275
276 QByteArray m_displayName;
277
278 QXcbKeyboard *m_keyboard;
279
280 #if defined(XCB_USE_XLIB)
281 void *m_xlib_display;
282 #endif
283
284 #ifdef XCB_USE_DRI2
285 uint32_t m_dri2_major;
286 uint32_t m_dri2_minor;
287 bool m_dri2_support_probed;
288 bool m_has_support_for_dri2;
289 QByteArray m_dri2_device_name;
290 #endif
291 #if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
292 void *m_egl_display;
293 bool m_has_egl;
294 #endif
295 #ifdef Q_XCB_DEBUG
296 struct CallInfo {
297 int sequence;
298 QByteArray file;
299 int line;
300 };
301 QVector<CallInfo> m_callLog;
302 void log(const char *file, int line, int sequence);
303 template <typename cookie_t>
304 friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line);
305 #endif
306 };
307
308 #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
309
310 #ifdef Q_XCB_DEBUG
311 template <typename cookie_t>
q_xcb_call_template(const cookie_t & cookie,QXcbConnection * connection,const char * file,int line)312 cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line)
313 {
314 connection->log(file, line, cookie.sequence);
315 return cookie;
316 }
317 #define Q_XCB_CALL(x) q_xcb_call_template(x, connection(), __FILE__, __LINE__)
318 #define Q_XCB_CALL2(x, connection) q_xcb_call_template(x, connection, __FILE__, __LINE__)
319 #define Q_XCB_NOOP(c) q_xcb_call_template(xcb_no_operation(c->xcb_connection()), c, __FILE__, __LINE__);
320 #else
321 #define Q_XCB_CALL(x) x
322 #define Q_XCB_CALL2(x, connection) x
323 #define Q_XCB_NOOP(c)
324 #endif
325
326
327 #if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
328 #define EGL_DISPLAY_FROM_XCB(object) ((EGLDisplay)(object->connection()->egl_display()))
329 #endif //endifXCB_USE_DRI2
330
331 #endif
332