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