Fix xcb plugin compilation for -qconfig large
[profile/ivi/qtbase.git] / src / plugins / platforms / xcb / qxcbconnection.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
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 <QHash>
48 #include <QList>
49 #include <QMutex>
50 #include <QObject>
51 #include <QThread>
52 #include <QVector>
53 #include <QVarLengthArray>
54
55 #ifdef XCB_USE_XINPUT2_MAEMO
56 struct XInput2Data;
57 #endif
58
59 //#define Q_XCB_DEBUG
60
61 QT_BEGIN_NAMESPACE
62
63 class QXcbScreen;
64 class QXcbWindow;
65 class QXcbDrag;
66 class QXcbKeyboard;
67 class QXcbClipboard;
68 class QXcbWMSupport;
69 class QXcbNativeInterface;
70
71 typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
72
73 namespace QXcbAtom {
74     enum Atom {
75         // window-manager <-> client protocols
76         WM_PROTOCOLS,
77         WM_DELETE_WINDOW,
78         WM_TAKE_FOCUS,
79         _NET_WM_PING,
80         _NET_WM_CONTEXT_HELP,
81         _NET_WM_SYNC_REQUEST,
82         _NET_WM_SYNC_REQUEST_COUNTER,
83
84         // ICCCM window state
85         WM_STATE,
86         WM_CHANGE_STATE,
87
88         // Session management
89         WM_CLIENT_LEADER,
90         WM_WINDOW_ROLE,
91         SM_CLIENT_ID,
92
93         // Clipboard
94         CLIPBOARD,
95         INCR,
96         TARGETS,
97         MULTIPLE,
98         TIMESTAMP,
99         SAVE_TARGETS,
100         CLIP_TEMPORARY,
101         _QT_SELECTION,
102         _QT_CLIPBOARD_SENTINEL,
103         _QT_SELECTION_SENTINEL,
104         CLIPBOARD_MANAGER,
105
106         RESOURCE_MANAGER,
107
108         _XSETROOT_ID,
109
110         _QT_SCROLL_DONE,
111         _QT_INPUT_ENCODING,
112
113         // Qt/XCB specific
114         _QT_CLOSE_CONNECTION,
115
116         _MOTIF_WM_HINTS,
117
118         DTWM_IS_RUNNING,
119         ENLIGHTENMENT_DESKTOP,
120         _DT_SAVE_MODE,
121         _SGI_DESKS_MANAGER,
122
123         // EWMH (aka NETWM)
124         _NET_SUPPORTED,
125         _NET_VIRTUAL_ROOTS,
126         _NET_WORKAREA,
127
128         _NET_MOVERESIZE_WINDOW,
129         _NET_WM_MOVERESIZE,
130
131         _NET_WM_NAME,
132         _NET_WM_ICON_NAME,
133         _NET_WM_ICON,
134
135         _NET_WM_PID,
136
137         _NET_WM_WINDOW_OPACITY,
138
139         _NET_WM_STATE,
140         _NET_WM_STATE_ABOVE,
141         _NET_WM_STATE_BELOW,
142         _NET_WM_STATE_FULLSCREEN,
143         _NET_WM_STATE_MAXIMIZED_HORZ,
144         _NET_WM_STATE_MAXIMIZED_VERT,
145         _NET_WM_STATE_MODAL,
146         _NET_WM_STATE_STAYS_ON_TOP,
147         _NET_WM_STATE_DEMANDS_ATTENTION,
148
149         _NET_WM_USER_TIME,
150         _NET_WM_USER_TIME_WINDOW,
151         _NET_WM_FULL_PLACEMENT,
152
153         _NET_WM_WINDOW_TYPE,
154         _NET_WM_WINDOW_TYPE_DESKTOP,
155         _NET_WM_WINDOW_TYPE_DOCK,
156         _NET_WM_WINDOW_TYPE_TOOLBAR,
157         _NET_WM_WINDOW_TYPE_MENU,
158         _NET_WM_WINDOW_TYPE_UTILITY,
159         _NET_WM_WINDOW_TYPE_SPLASH,
160         _NET_WM_WINDOW_TYPE_DIALOG,
161         _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
162         _NET_WM_WINDOW_TYPE_POPUP_MENU,
163         _NET_WM_WINDOW_TYPE_TOOLTIP,
164         _NET_WM_WINDOW_TYPE_NOTIFICATION,
165         _NET_WM_WINDOW_TYPE_COMBO,
166         _NET_WM_WINDOW_TYPE_DND,
167         _NET_WM_WINDOW_TYPE_NORMAL,
168         _KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
169
170         _KDE_NET_WM_FRAME_STRUT,
171
172         _NET_STARTUP_INFO,
173         _NET_STARTUP_INFO_BEGIN,
174
175         _NET_SUPPORTING_WM_CHECK,
176
177         _NET_WM_CM_S0,
178
179         _NET_SYSTEM_TRAY_VISUAL,
180
181         _NET_ACTIVE_WINDOW,
182
183         // Property formats
184         TEXT,
185         UTF8_STRING,
186
187         // Xdnd
188         XdndEnter,
189         XdndPosition,
190         XdndStatus,
191         XdndLeave,
192         XdndDrop,
193         XdndFinished,
194         XdndTypelist,
195         XdndActionList,
196
197         XdndSelection,
198
199         XdndAware,
200         XdndProxy,
201
202         XdndActionCopy,
203         XdndActionLink,
204         XdndActionMove,
205         XdndActionPrivate,
206
207         // Motif DND
208         _MOTIF_DRAG_AND_DROP_MESSAGE,
209         _MOTIF_DRAG_INITIATOR_INFO,
210         _MOTIF_DRAG_RECEIVER_INFO,
211         _MOTIF_DRAG_WINDOW,
212         _MOTIF_DRAG_TARGETS,
213
214         XmTRANSFER_SUCCESS,
215         XmTRANSFER_FAILURE,
216
217         // Xkb
218         _XKB_RULES_NAMES,
219
220         // XEMBED
221         _XEMBED,
222         _XEMBED_INFO,
223
224         XWacomStylus,
225         XWacomCursor,
226         XWacomEraser,
227
228         XTabletStylus,
229         XTabletEraser,
230
231         // XInput2
232         ButtonLeft,
233         ButtonMiddle,
234         ButtonRight,
235         ButtonWheelUp,
236         ButtonWheelDown,
237         ButtonHorizWheelLeft,
238         ButtonHorizWheelRight,
239         AbsMTPositionX,
240         AbsMTPositionY,
241         AbsMTTouchMajor,
242         AbsMTTouchMinor,
243         AbsMTPressure,
244         AbsMTTrackingID,
245         MaxContacts,
246
247 #if XCB_USE_MAEMO_WINDOW_PROPERTIES
248         MeegoTouchOrientationAngle,
249 #endif
250
251         NPredefinedAtoms,
252
253         _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
254         NAtoms
255     };
256 }
257
258 typedef QVarLengthArray<xcb_generic_event_t *, 64> QXcbEventArray;
259
260 class QXcbConnection;
261 class QXcbEventReader : public QThread
262 {
263     Q_OBJECT
264 public:
265     QXcbEventReader(QXcbConnection *connection)
266         : m_connection(connection)
267     {
268     }
269
270 #ifdef XCB_POLL_FOR_QUEUED_EVENT
271     void run();
272 #endif
273
274     QXcbEventArray *lock();
275     void unlock();
276
277 signals:
278     void eventPending();
279
280 private:
281     void addEvent(xcb_generic_event_t *event);
282
283     QMutex m_mutex;
284     QXcbEventArray m_events;
285     QXcbConnection *m_connection;
286 };
287
288 class QAbstractEventDispatcher;
289 class QXcbConnection : public QObject
290 {
291     Q_OBJECT
292 public:
293     QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName = 0);
294     ~QXcbConnection();
295
296     QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
297
298     const QList<QXcbScreen *> &screens() const { return m_screens; }
299     int primaryScreen() const { return m_primaryScreen; }
300
301     xcb_atom_t atom(QXcbAtom::Atom atom);
302     xcb_atom_t internAtom(const char *name);
303     QByteArray atomName(xcb_atom_t atom);
304
305     const char *displayName() const { return m_displayName.constData(); }
306
307     xcb_connection_t *xcb_connection() const { return m_connection; }
308     const xcb_setup_t *setup() const { return m_setup; }
309     const xcb_format_t *formatForDepth(uint8_t depth) const;
310
311     QXcbKeyboard *keyboard() const { return m_keyboard; }
312
313 #ifndef QT_NO_CLIPBOARD
314     QXcbClipboard *clipboard() const { return m_clipboard; }
315 #endif
316 #ifndef QT_NO_DRAGANDDROP
317     QXcbDrag *drag() const { return m_drag; }
318 #endif
319
320     QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); }
321
322 #ifdef XCB_USE_XLIB
323     void *xlib_display() const { return m_xlib_display; }
324 #endif
325
326 #ifdef XCB_USE_DRI2
327     bool hasSupportForDri2() const;
328     QByteArray dri2DeviceName() const { return m_dri2_device_name; }
329 #endif
330 #ifdef XCB_USE_EGL
331     bool hasEgl() const;
332 #endif
333 #if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
334     void *egl_display() const { return m_egl_display; }
335 #endif
336 #ifdef XCB_USE_XINPUT2_MAEMO
337     bool isUsingXInput2();
338 #endif
339
340     void sync();
341     void flush() { xcb_flush(m_connection); }
342
343     void handleXcbError(xcb_generic_error_t *error);
344     void handleXcbEvent(xcb_generic_event_t *event);
345
346     void addWindow(xcb_window_t id, QXcbWindow *window);
347     void removeWindow(xcb_window_t id);
348     QXcbWindow *platformWindowFromId(xcb_window_t id);
349
350     xcb_generic_event_t *checkEvent(int type);
351     template<typename T>
352     inline xcb_generic_event_t *checkEvent(T &checker);
353
354     typedef bool (*PeekFunc)(xcb_generic_event_t *);
355     void addPeekFunc(PeekFunc f);
356
357     inline xcb_timestamp_t time() const { return m_time; }
358     inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; }
359
360     bool hasXFixes() const { return xfixes_first_event > 0; }
361     bool hasXShape() const { return has_shape_extension; }
362     bool hasXRandr() const { return has_randr_extension; }
363     bool hasInputShape() const { return has_input_shape; }
364
365 private slots:
366     void processXcbEvents();
367
368 private:
369     void initializeAllAtoms();
370     void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
371     void initializeXFixes();
372     void initializeXRender();
373     void initializeXRandr();
374     void initializeXShape();
375 #ifdef XCB_USE_DRI2
376     void initializeDri2();
377 #endif
378 #ifdef XCB_USE_XINPUT2_MAEMO
379     void initializeXInput2();
380     void finalizeXInput2();
381     void handleGenericEvent(xcb_ge_event_t *event);
382 #endif
383     void handleClientMessageEvent(const xcb_client_message_event_t *event);
384
385     xcb_connection_t *m_connection;
386     const xcb_setup_t *m_setup;
387
388     QList<QXcbScreen *> m_screens;
389     int m_primaryScreen;
390
391     xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
392
393     xcb_timestamp_t m_time;
394
395     QByteArray m_displayName;
396
397     xcb_window_t m_connectionEventListener;
398
399     QXcbKeyboard *m_keyboard;
400 #ifndef QT_NO_CLIPBOARD
401     QXcbClipboard *m_clipboard;
402 #endif
403 #ifndef QT_NO_DRAGANDDROP
404     QXcbDrag *m_drag;
405 #endif
406     QScopedPointer<QXcbWMSupport> m_wmSupport;
407     QXcbNativeInterface *m_nativeInterface;
408
409 #if defined(XCB_USE_XLIB)
410     void *m_xlib_display;
411 #endif
412     QXcbEventReader *m_reader;
413 #ifdef XCB_USE_XINPUT2_MAEMO
414     XInput2Data *m_xinputData;
415 #endif
416 #ifdef XCB_USE_DRI2
417     uint32_t m_dri2_major;
418     uint32_t m_dri2_minor;
419     bool m_dri2_support_probed;
420     bool m_has_support_for_dri2;
421     QByteArray m_dri2_device_name;
422 #endif
423 #if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
424     void *m_egl_display;
425     bool m_has_egl;
426 #endif
427 #ifdef Q_XCB_DEBUG
428     struct CallInfo {
429         int sequence;
430         QByteArray file;
431         int line;
432     };
433     QVector<CallInfo> m_callLog;
434     QMutex m_callLogMutex;
435     void log(const char *file, int line, int sequence);
436     template <typename cookie_t>
437     friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line);
438 #endif
439
440     WindowMapper m_mapper;
441
442     QVector<PeekFunc> m_peekFuncs;
443
444     uint32_t xfixes_first_event;
445     uint32_t xrandr_first_event;
446
447     bool has_shape_extension;
448     bool has_randr_extension;
449     bool has_input_shape;
450 };
451
452 #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
453
454 template<typename T>
455 xcb_generic_event_t *QXcbConnection::checkEvent(T &checker)
456 {
457     QXcbEventArray *eventqueue = m_reader->lock();
458
459     for (int i = 0; i < eventqueue->size(); ++i) {
460         xcb_generic_event_t *event = eventqueue->at(i);
461         if (checker.checkEvent(event)) {
462             (*eventqueue)[i] = 0;
463             m_reader->unlock();
464             return event;
465         }
466     }
467     m_reader->unlock();
468     return 0;
469 }
470
471
472 #ifdef Q_XCB_DEBUG
473 template <typename cookie_t>
474 cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line)
475 {
476     connection->log(file, line, cookie.sequence);
477     return cookie;
478 }
479 #define Q_XCB_CALL(x) q_xcb_call_template(x, connection(), __FILE__, __LINE__)
480 #define Q_XCB_CALL2(x, connection) q_xcb_call_template(x, connection, __FILE__, __LINE__)
481 #define Q_XCB_NOOP(c) q_xcb_call_template(xcb_no_operation(c->xcb_connection()), c, __FILE__, __LINE__);
482 #else
483 #define Q_XCB_CALL(x) x
484 #define Q_XCB_CALL2(x, connection) x
485 #define Q_XCB_NOOP(c)
486 #endif
487
488
489 #if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
490 #define EGL_DISPLAY_FROM_XCB(object) ((EGLDisplay)(object->connection()->egl_display()))
491 #endif //endifXCB_USE_DRI2
492
493 QT_END_NAMESPACE
494
495 #endif