86eaf5d7d91e490e088530cec81b290fce6888b8
[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     QXcbClipboard *clipboard() const { return m_clipboard; }
314     QXcbDrag *drag() const { return m_drag; }
315
316     QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); }
317
318 #ifdef XCB_USE_XLIB
319     void *xlib_display() const { return m_xlib_display; }
320 #endif
321
322 #ifdef XCB_USE_DRI2
323     bool hasSupportForDri2() const;
324     QByteArray dri2DeviceName() const { return m_dri2_device_name; }
325 #endif
326 #ifdef XCB_USE_EGL
327     bool hasEgl() const;
328 #endif
329 #if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
330     void *egl_display() const { return m_egl_display; }
331 #endif
332 #ifdef XCB_USE_XINPUT2_MAEMO
333     bool isUsingXInput2();
334 #endif
335
336     void sync();
337     void flush() { xcb_flush(m_connection); }
338
339     void handleXcbError(xcb_generic_error_t *error);
340     void handleXcbEvent(xcb_generic_event_t *event);
341
342     void addWindow(xcb_window_t id, QXcbWindow *window);
343     void removeWindow(xcb_window_t id);
344     QXcbWindow *platformWindowFromId(xcb_window_t id);
345
346     xcb_generic_event_t *checkEvent(int type);
347     template<typename T>
348     inline xcb_generic_event_t *checkEvent(T &checker);
349
350     typedef bool (*PeekFunc)(xcb_generic_event_t *);
351     void addPeekFunc(PeekFunc f);
352
353     inline xcb_timestamp_t time() const { return m_time; }
354     inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; }
355
356     bool hasXFixes() const { return xfixes_first_event > 0; }
357     bool hasXShape() const { return has_shape_extension; }
358     bool hasXRandr() const { return has_randr_extension; }
359     bool hasInputShape() const { return has_input_shape; }
360
361 private slots:
362     void processXcbEvents();
363
364 private:
365     void initializeAllAtoms();
366     void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
367     void initializeXFixes();
368     void initializeXRender();
369     void initializeXRandr();
370     void initializeXShape();
371 #ifdef XCB_USE_DRI2
372     void initializeDri2();
373 #endif
374 #ifdef XCB_USE_XINPUT2_MAEMO
375     void initializeXInput2();
376     void finalizeXInput2();
377     void handleGenericEvent(xcb_ge_event_t *event);
378 #endif
379     void handleClientMessageEvent(const xcb_client_message_event_t *event);
380
381     xcb_connection_t *m_connection;
382     const xcb_setup_t *m_setup;
383
384     QList<QXcbScreen *> m_screens;
385     int m_primaryScreen;
386
387     xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
388
389     xcb_timestamp_t m_time;
390
391     QByteArray m_displayName;
392
393     xcb_window_t m_connectionEventListener;
394
395     QXcbKeyboard *m_keyboard;
396     QXcbClipboard *m_clipboard;
397     QXcbDrag *m_drag;
398     QScopedPointer<QXcbWMSupport> m_wmSupport;
399     QXcbNativeInterface *m_nativeInterface;
400
401 #if defined(XCB_USE_XLIB)
402     void *m_xlib_display;
403 #endif
404     QXcbEventReader *m_reader;
405 #ifdef XCB_USE_XINPUT2_MAEMO
406     XInput2Data *m_xinputData;
407 #endif
408 #ifdef XCB_USE_DRI2
409     uint32_t m_dri2_major;
410     uint32_t m_dri2_minor;
411     bool m_dri2_support_probed;
412     bool m_has_support_for_dri2;
413     QByteArray m_dri2_device_name;
414 #endif
415 #if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
416     void *m_egl_display;
417     bool m_has_egl;
418 #endif
419 #ifdef Q_XCB_DEBUG
420     struct CallInfo {
421         int sequence;
422         QByteArray file;
423         int line;
424     };
425     QVector<CallInfo> m_callLog;
426     QMutex m_callLogMutex;
427     void log(const char *file, int line, int sequence);
428     template <typename cookie_t>
429     friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line);
430 #endif
431
432     WindowMapper m_mapper;
433
434     QVector<PeekFunc> m_peekFuncs;
435
436     uint32_t xfixes_first_event;
437     uint32_t xrandr_first_event;
438
439     bool has_shape_extension;
440     bool has_randr_extension;
441     bool has_input_shape;
442 };
443
444 #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
445
446 template<typename T>
447 xcb_generic_event_t *QXcbConnection::checkEvent(T &checker)
448 {
449     QXcbEventArray *eventqueue = m_reader->lock();
450
451     for (int i = 0; i < eventqueue->size(); ++i) {
452         xcb_generic_event_t *event = eventqueue->at(i);
453         if (checker.checkEvent(event)) {
454             (*eventqueue)[i] = 0;
455             m_reader->unlock();
456             return event;
457         }
458     }
459     m_reader->unlock();
460     return 0;
461 }
462
463
464 #ifdef Q_XCB_DEBUG
465 template <typename cookie_t>
466 cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line)
467 {
468     connection->log(file, line, cookie.sequence);
469     return cookie;
470 }
471 #define Q_XCB_CALL(x) q_xcb_call_template(x, connection(), __FILE__, __LINE__)
472 #define Q_XCB_CALL2(x, connection) q_xcb_call_template(x, connection, __FILE__, __LINE__)
473 #define Q_XCB_NOOP(c) q_xcb_call_template(xcb_no_operation(c->xcb_connection()), c, __FILE__, __LINE__);
474 #else
475 #define Q_XCB_CALL(x) x
476 #define Q_XCB_CALL2(x, connection) x
477 #define Q_XCB_NOOP(c)
478 #endif
479
480
481 #if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
482 #define EGL_DISPLAY_FROM_XCB(object) ((EGLDisplay)(object->connection()->egl_display()))
483 #endif //endifXCB_USE_DRI2
484
485 QT_END_NAMESPACE
486
487 #endif