f2dc2c669d61a2a95245d732e045cb80e27dc703
[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 #include <QtGui/qwindowsysteminterface.h>
55
56 #ifndef QT_NO_TABLETEVENT
57 #include <QTabletEvent>
58 #endif
59
60 #ifdef XCB_USE_XINPUT2_MAEMO
61 struct XInput2MaemoData;
62 #elif XCB_USE_XINPUT2
63 #ifdef XI_TouchBeginMask
64 #define XCB_USE_XINPUT22    // XI 2.2 adds multi-point touch support
65 #endif
66 struct XInput2DeviceData;
67 #endif
68
69 //#define Q_XCB_DEBUG
70
71 QT_BEGIN_NAMESPACE
72
73 class QXcbScreen;
74 class QXcbWindow;
75 class QXcbDrag;
76 class QXcbKeyboard;
77 class QXcbClipboard;
78 class QXcbWMSupport;
79 class QXcbNativeInterface;
80
81 typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
82
83 namespace QXcbAtom {
84     enum Atom {
85         // window-manager <-> client protocols
86         WM_PROTOCOLS,
87         WM_DELETE_WINDOW,
88         WM_TAKE_FOCUS,
89         _NET_WM_PING,
90         _NET_WM_CONTEXT_HELP,
91         _NET_WM_SYNC_REQUEST,
92         _NET_WM_SYNC_REQUEST_COUNTER,
93
94         // ICCCM window state
95         WM_STATE,
96         WM_CHANGE_STATE,
97
98         // Session management
99         WM_CLIENT_LEADER,
100         WM_WINDOW_ROLE,
101         SM_CLIENT_ID,
102
103         // Clipboard
104         CLIPBOARD,
105         INCR,
106         TARGETS,
107         MULTIPLE,
108         TIMESTAMP,
109         SAVE_TARGETS,
110         CLIP_TEMPORARY,
111         _QT_SELECTION,
112         _QT_CLIPBOARD_SENTINEL,
113         _QT_SELECTION_SENTINEL,
114         CLIPBOARD_MANAGER,
115
116         RESOURCE_MANAGER,
117
118         _XSETROOT_ID,
119
120         _QT_SCROLL_DONE,
121         _QT_INPUT_ENCODING,
122
123         // Qt/XCB specific
124         _QT_CLOSE_CONNECTION,
125
126         _MOTIF_WM_HINTS,
127
128         DTWM_IS_RUNNING,
129         ENLIGHTENMENT_DESKTOP,
130         _DT_SAVE_MODE,
131         _SGI_DESKS_MANAGER,
132
133         // EWMH (aka NETWM)
134         _NET_SUPPORTED,
135         _NET_VIRTUAL_ROOTS,
136         _NET_WORKAREA,
137
138         _NET_MOVERESIZE_WINDOW,
139         _NET_WM_MOVERESIZE,
140
141         _NET_WM_NAME,
142         _NET_WM_ICON_NAME,
143         _NET_WM_ICON,
144
145         _NET_WM_PID,
146
147         _NET_WM_WINDOW_OPACITY,
148
149         _NET_WM_STATE,
150         _NET_WM_STATE_ABOVE,
151         _NET_WM_STATE_BELOW,
152         _NET_WM_STATE_FULLSCREEN,
153         _NET_WM_STATE_MAXIMIZED_HORZ,
154         _NET_WM_STATE_MAXIMIZED_VERT,
155         _NET_WM_STATE_MODAL,
156         _NET_WM_STATE_STAYS_ON_TOP,
157         _NET_WM_STATE_DEMANDS_ATTENTION,
158
159         _NET_WM_USER_TIME,
160         _NET_WM_USER_TIME_WINDOW,
161         _NET_WM_FULL_PLACEMENT,
162
163         _NET_WM_WINDOW_TYPE,
164         _NET_WM_WINDOW_TYPE_DESKTOP,
165         _NET_WM_WINDOW_TYPE_DOCK,
166         _NET_WM_WINDOW_TYPE_TOOLBAR,
167         _NET_WM_WINDOW_TYPE_MENU,
168         _NET_WM_WINDOW_TYPE_UTILITY,
169         _NET_WM_WINDOW_TYPE_SPLASH,
170         _NET_WM_WINDOW_TYPE_DIALOG,
171         _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
172         _NET_WM_WINDOW_TYPE_POPUP_MENU,
173         _NET_WM_WINDOW_TYPE_TOOLTIP,
174         _NET_WM_WINDOW_TYPE_NOTIFICATION,
175         _NET_WM_WINDOW_TYPE_COMBO,
176         _NET_WM_WINDOW_TYPE_DND,
177         _NET_WM_WINDOW_TYPE_NORMAL,
178         _KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
179
180         _KDE_NET_WM_FRAME_STRUT,
181
182         _NET_STARTUP_INFO,
183         _NET_STARTUP_INFO_BEGIN,
184
185         _NET_SUPPORTING_WM_CHECK,
186
187         _NET_WM_CM_S0,
188
189         _NET_SYSTEM_TRAY_VISUAL,
190
191         _NET_ACTIVE_WINDOW,
192
193         // Property formats
194         TEXT,
195         UTF8_STRING,
196         CARDINAL,
197
198         // Xdnd
199         XdndEnter,
200         XdndPosition,
201         XdndStatus,
202         XdndLeave,
203         XdndDrop,
204         XdndFinished,
205         XdndTypelist,
206         XdndActionList,
207
208         XdndSelection,
209
210         XdndAware,
211         XdndProxy,
212
213         XdndActionCopy,
214         XdndActionLink,
215         XdndActionMove,
216         XdndActionPrivate,
217
218         // Motif DND
219         _MOTIF_DRAG_AND_DROP_MESSAGE,
220         _MOTIF_DRAG_INITIATOR_INFO,
221         _MOTIF_DRAG_RECEIVER_INFO,
222         _MOTIF_DRAG_WINDOW,
223         _MOTIF_DRAG_TARGETS,
224
225         XmTRANSFER_SUCCESS,
226         XmTRANSFER_FAILURE,
227
228         // Xkb
229         _XKB_RULES_NAMES,
230
231         // XEMBED
232         _XEMBED,
233         _XEMBED_INFO,
234
235         // XInput2
236         ButtonLeft,
237         ButtonMiddle,
238         ButtonRight,
239         ButtonWheelUp,
240         ButtonWheelDown,
241         ButtonHorizWheelLeft,
242         ButtonHorizWheelRight,
243         AbsMTPositionX,
244         AbsMTPositionY,
245         AbsMTTouchMajor,
246         AbsMTTouchMinor,
247         AbsMTPressure,
248         AbsMTTrackingID,
249         MaxContacts,
250         // XInput2 tablet
251         AbsX,
252         AbsY,
253         AbsPressure,
254         AbsTiltX,
255         AbsTiltY,
256         AbsWheel,
257         AbsDistance,
258         WacomSerialIDs,
259         INTEGER,
260
261 #if XCB_USE_MAEMO_WINDOW_PROPERTIES
262         MeegoTouchOrientationAngle,
263 #endif
264
265         NPredefinedAtoms,
266
267         _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
268         NAtoms
269     };
270 }
271
272 typedef QVarLengthArray<xcb_generic_event_t *, 64> QXcbEventArray;
273
274 class QXcbConnection;
275 class QXcbEventReader : public QThread
276 {
277     Q_OBJECT
278 public:
279     QXcbEventReader(QXcbConnection *connection)
280         : m_connection(connection)
281     {
282     }
283
284 #ifdef XCB_POLL_FOR_QUEUED_EVENT
285     void run();
286 #endif
287
288     QXcbEventArray *lock();
289     void unlock();
290
291 signals:
292     void eventPending();
293
294 private:
295     void addEvent(xcb_generic_event_t *event);
296
297     QMutex m_mutex;
298     QXcbEventArray m_events;
299     QXcbConnection *m_connection;
300 };
301
302 class QAbstractEventDispatcher;
303 class QXcbConnection : public QObject
304 {
305     Q_OBJECT
306 public:
307     QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName = 0);
308     ~QXcbConnection();
309
310     QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
311
312     const QList<QXcbScreen *> &screens() const { return m_screens; }
313     int primaryScreen() const { return m_primaryScreen; }
314
315     xcb_atom_t atom(QXcbAtom::Atom atom);
316     xcb_atom_t internAtom(const char *name);
317     QByteArray atomName(xcb_atom_t atom);
318
319     const char *displayName() const { return m_displayName.constData(); }
320
321     xcb_connection_t *xcb_connection() const { return m_connection; }
322     const xcb_setup_t *setup() const { return m_setup; }
323     const xcb_format_t *formatForDepth(uint8_t depth) const;
324
325     QXcbKeyboard *keyboard() const { return m_keyboard; }
326
327 #ifndef QT_NO_CLIPBOARD
328     QXcbClipboard *clipboard() const { return m_clipboard; }
329 #endif
330 #ifndef QT_NO_DRAGANDDROP
331     QXcbDrag *drag() const { return m_drag; }
332 #endif
333
334     QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); }
335
336 #ifdef XCB_USE_XLIB
337     void *xlib_display() const { return m_xlib_display; }
338 #endif
339
340 #ifdef XCB_USE_DRI2
341     bool hasSupportForDri2() const;
342     QByteArray dri2DeviceName() const { return m_dri2_device_name; }
343 #endif
344 #ifdef XCB_USE_EGL
345     bool hasEgl() const;
346 #endif
347 #if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
348     void *egl_display() const { return m_egl_display; }
349 #endif
350 #ifdef XCB_USE_XINPUT2_MAEMO
351     bool isUsingXInput2Maemo();
352 #elif defined(XCB_USE_XINPUT2)
353     void xi2Select(xcb_window_t window);
354 #endif
355
356     void sync();
357     void flush() { xcb_flush(m_connection); }
358
359     void handleXcbError(xcb_generic_error_t *error);
360     void handleXcbEvent(xcb_generic_event_t *event);
361
362     void addWindow(xcb_window_t id, QXcbWindow *window);
363     void removeWindow(xcb_window_t id);
364     QXcbWindow *platformWindowFromId(xcb_window_t id);
365
366     xcb_generic_event_t *checkEvent(int type);
367     template<typename T>
368     inline xcb_generic_event_t *checkEvent(T &checker);
369
370     typedef bool (*PeekFunc)(xcb_generic_event_t *);
371     void addPeekFunc(PeekFunc f);
372
373     inline xcb_timestamp_t time() const { return m_time; }
374     inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; }
375
376     bool hasXFixes() const { return xfixes_first_event > 0; }
377     bool hasXShape() const { return has_shape_extension; }
378     bool hasXRandr() const { return has_randr_extension; }
379     bool hasInputShape() const { return has_input_shape; }
380
381 private slots:
382     void processXcbEvents();
383
384 private:
385     void initializeAllAtoms();
386     void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
387     void initializeXFixes();
388     void initializeXRender();
389     void initializeXRandr();
390     void initializeXShape();
391 #ifdef XCB_USE_DRI2
392     void initializeDri2();
393 #endif
394 #ifdef XCB_USE_XINPUT2_MAEMO
395     void initializeXInput2Maemo();
396     void finalizeXInput2Maemo();
397     void handleGenericEventMaemo(xcb_ge_event_t *event);
398 #endif
399     void handleClientMessageEvent(const xcb_client_message_event_t *event);
400
401     bool m_xi2Enabled;
402     int m_xi2Minor;
403 #ifdef XCB_USE_XINPUT2
404     void initializeXInput2();
405     void finalizeXInput2();
406     XInput2DeviceData *deviceForId(int id);
407     void xi2HandleEvent(xcb_ge_event_t *event);
408     int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
409 #ifndef QT_NO_TABLETEVENT
410     struct TabletData {
411         TabletData() : deviceId(0), down(false), serialId(0), inProximity(false) { }
412         int deviceId;
413         QTabletEvent::PointerType pointerType;
414         bool down;
415         qint64 serialId;
416         bool inProximity;
417         struct ValuatorClassInfo {
418             ValuatorClassInfo() : minVal(0), maxVal(0) { }
419             double minVal;
420             double maxVal;
421             int number;
422         };
423         QHash<int, ValuatorClassInfo> valuatorInfo;
424     };
425     void xi2QueryTabletData(void *dev, TabletData *tabletData); // use no XI stuff in headers
426     void xi2SetupTabletDevices();
427     bool xi2HandleTabletEvent(void *event, TabletData *tabletData);
428     void xi2ReportTabletEvent(const TabletData &tabletData, void *event);
429     QVector<TabletData> m_tabletData;
430 #endif
431 #endif // XCB_USE_XINPUT2
432
433 #if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
434     static int xi2CountBits(unsigned char *ptr, int len);
435     static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value);
436     static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode);
437 #endif
438
439     xcb_connection_t *m_connection;
440     const xcb_setup_t *m_setup;
441
442     QList<QXcbScreen *> m_screens;
443     int m_primaryScreen;
444
445     xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
446
447     xcb_timestamp_t m_time;
448
449     QByteArray m_displayName;
450
451     xcb_window_t m_connectionEventListener;
452
453     QXcbKeyboard *m_keyboard;
454 #ifndef QT_NO_CLIPBOARD
455     QXcbClipboard *m_clipboard;
456 #endif
457 #ifndef QT_NO_DRAGANDDROP
458     QXcbDrag *m_drag;
459 #endif
460     QScopedPointer<QXcbWMSupport> m_wmSupport;
461     QXcbNativeInterface *m_nativeInterface;
462
463 #if defined(XCB_USE_XLIB)
464     void *m_xlib_display;
465 #endif
466     QXcbEventReader *m_reader;
467 #ifdef XCB_USE_XINPUT2_MAEMO
468     XInput2MaemoData *m_xinputData;
469 #elif defined(XCB_USE_XINPUT2)
470     QHash<int, QWindowSystemInterface::TouchPoint> m_touchPoints;
471     QHash<int, XInput2DeviceData*> m_touchDevices;
472 #endif
473 #ifdef XCB_USE_DRI2
474     uint32_t m_dri2_major;
475     uint32_t m_dri2_minor;
476     bool m_dri2_support_probed;
477     bool m_has_support_for_dri2;
478     QByteArray m_dri2_device_name;
479 #endif
480 #if defined(XCB_USE_EGL) || defined(XCB_USE_DRI2)
481     void *m_egl_display;
482     bool m_has_egl;
483 #endif
484 #ifdef Q_XCB_DEBUG
485     struct CallInfo {
486         int sequence;
487         QByteArray file;
488         int line;
489     };
490     QVector<CallInfo> m_callLog;
491     QMutex m_callLogMutex;
492     void log(const char *file, int line, int sequence);
493     template <typename cookie_t>
494     friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line);
495 #endif
496
497     WindowMapper m_mapper;
498
499     QVector<PeekFunc> m_peekFuncs;
500
501     uint32_t xfixes_first_event;
502     uint32_t xrandr_first_event;
503
504     bool has_shape_extension;
505     bool has_randr_extension;
506     bool has_input_shape;
507 };
508
509 #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
510
511 template<typename T>
512 xcb_generic_event_t *QXcbConnection::checkEvent(T &checker)
513 {
514     QXcbEventArray *eventqueue = m_reader->lock();
515
516     for (int i = 0; i < eventqueue->size(); ++i) {
517         xcb_generic_event_t *event = eventqueue->at(i);
518         if (checker.checkEvent(event)) {
519             (*eventqueue)[i] = 0;
520             m_reader->unlock();
521             return event;
522         }
523     }
524     m_reader->unlock();
525     return 0;
526 }
527
528
529 #ifdef Q_XCB_DEBUG
530 template <typename cookie_t>
531 cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line)
532 {
533     connection->log(file, line, cookie.sequence);
534     return cookie;
535 }
536 #define Q_XCB_CALL(x) q_xcb_call_template(x, connection(), __FILE__, __LINE__)
537 #define Q_XCB_CALL2(x, connection) q_xcb_call_template(x, connection, __FILE__, __LINE__)
538 #define Q_XCB_NOOP(c) q_xcb_call_template(xcb_no_operation(c->xcb_connection()), c, __FILE__, __LINE__);
539 #else
540 #define Q_XCB_CALL(x) x
541 #define Q_XCB_CALL2(x, connection) x
542 #define Q_XCB_NOOP(c)
543 #endif
544
545
546 #if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
547 #define EGL_DISPLAY_FROM_XCB(object) ((EGLDisplay)(object->connection()->egl_display()))
548 #endif //endifXCB_USE_DRI2
549
550 QT_END_NAMESPACE
551
552 #endif