Update licenseheader text in source files for qtbase Qt module
[profile/ivi/qtbase.git] / src / plugins / platforms / xcb / qxcbconnection.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the plugins of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qxcbconnection.h"
43 #include "qxcbkeyboard.h"
44 #include "qxcbscreen.h"
45 #include "qxcbwindow.h"
46
47 #include <QtAlgorithms>
48 #include <QSocketNotifier>
49 #include <QtGui/private/qapplication_p.h>
50 #include <QAbstractEventDispatcher>
51
52 #include <QtCore/QDebug>
53
54 #include <stdio.h>
55 #include <errno.h>
56
57 #ifdef XCB_USE_XLIB
58 #include <X11/Xlib.h>
59 #include <X11/Xlib-xcb.h>
60 #endif
61
62 #ifdef XCB_USE_EGL //dont pull in eglext prototypes
63 #include <EGL/egl.h>
64 #endif
65
66 #ifdef XCB_USE_DRI2
67 #include <xcb/dri2.h>
68 #include <xcb/xfixes.h>
69 extern "C" {
70 #include <xf86drm.h>
71 }
72 #define MESA_EGL_NO_X11_HEADERS
73 #define EGL_EGLEXT_PROTOTYPES
74 #include <EGL/egl.h>
75 #include <EGL/eglext.h>
76 #endif
77
78 QXcbConnection::QXcbConnection(const char *displayName)
79     : m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
80 #ifdef XCB_USE_DRI2
81     , m_dri2_major(0)
82     , m_dri2_minor(0)
83     , m_dri2_support_probed(false)
84     , m_has_support_for_dri2(false)
85 #endif
86 {
87     int primaryScreen = 0;
88
89 #ifdef XCB_USE_XLIB
90     Display *dpy = XOpenDisplay(m_displayName.constData());
91     primaryScreen = DefaultScreen(dpy);
92     m_connection = XGetXCBConnection(dpy);
93     XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
94     m_xlib_display = dpy;
95 #ifdef XCB_USE_EGL
96     EGLDisplay eglDisplay = eglGetDisplay(dpy);
97     m_egl_display = eglDisplay;
98     EGLint major, minor;
99     eglBindAPI(EGL_OPENGL_ES_API);
100     m_has_egl = eglInitialize(eglDisplay,&major,&minor);
101 #endif //XCB_USE_EGL
102 #else
103     m_connection = xcb_connect(m_displayName.constData(), &primaryScreen);
104
105 #endif //XCB_USE_XLIB
106     m_setup = xcb_get_setup(xcb_connection());
107
108     initializeAllAtoms();
109
110     xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
111
112     int screenNumber = 0;
113     while (it.rem) {
114         m_screens << new QXcbScreen(this, it.data, screenNumber++);
115         xcb_screen_next(&it);
116     }
117
118     m_keyboard = new QXcbKeyboard(this);
119
120 #ifdef XCB_USE_DRI2
121     initializeDri2();
122 #endif
123
124     QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
125     connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));
126
127     QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance(qApp->thread());
128     connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
129
130     sync();
131 }
132
133 QXcbConnection::~QXcbConnection()
134 {
135     qDeleteAll(m_screens);
136
137 #ifdef XCB_USE_XLIB
138     XCloseDisplay((Display *)m_xlib_display);
139 #else
140     xcb_disconnect(xcb_connection());
141 #endif
142
143     delete m_keyboard;
144 }
145
146 QXcbWindow *platformWindowFromId(xcb_window_t id)
147 {
148     QWidget *widget = QWidget::find(id);
149     if (widget)
150         return static_cast<QXcbWindow *>(widget->platformWindow());
151     return 0;
152 }
153
154 #define HANDLE_PLATFORM_WINDOW_EVENT(event_t, window, handler) \
155 { \
156     event_t *e = (event_t *)event; \
157     if (QXcbWindow *platformWindow = platformWindowFromId(e->window)) { \
158         QObjectPrivate *d = QObjectPrivate::get(platformWindow->widget()); \
159         if (!d->wasDeleted) \
160             platformWindow->handler(e); \
161     } \
162 } \
163 break;
164
165 #define HANDLE_KEYBOARD_EVENT(event_t, handler) \
166 { \
167     event_t *e = (event_t *)event; \
168     if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) \
169         m_keyboard->handler(platformWindow->widget(), e); \
170 } \
171 break;
172
173 //#define XCB_EVENT_DEBUG
174
175 void printXcbEvent(const char *message, xcb_generic_event_t *event)
176 {
177 #ifdef XCB_EVENT_DEBUG
178 #define PRINT_XCB_EVENT(ev) \
179     case ev: \
180         printf("%s: %d - %s - sequence: %d\n", message, int(ev), #ev, event->sequence); \
181         break;
182
183     switch (event->response_type & ~0x80) {
184     PRINT_XCB_EVENT(XCB_KEY_PRESS);
185     PRINT_XCB_EVENT(XCB_KEY_RELEASE);
186     PRINT_XCB_EVENT(XCB_BUTTON_PRESS);
187     PRINT_XCB_EVENT(XCB_BUTTON_RELEASE);
188     PRINT_XCB_EVENT(XCB_MOTION_NOTIFY);
189     PRINT_XCB_EVENT(XCB_ENTER_NOTIFY);
190     PRINT_XCB_EVENT(XCB_LEAVE_NOTIFY);
191     PRINT_XCB_EVENT(XCB_FOCUS_IN);
192     PRINT_XCB_EVENT(XCB_FOCUS_OUT);
193     PRINT_XCB_EVENT(XCB_KEYMAP_NOTIFY);
194     PRINT_XCB_EVENT(XCB_EXPOSE);
195     PRINT_XCB_EVENT(XCB_GRAPHICS_EXPOSURE);
196     PRINT_XCB_EVENT(XCB_VISIBILITY_NOTIFY);
197     PRINT_XCB_EVENT(XCB_CREATE_NOTIFY);
198     PRINT_XCB_EVENT(XCB_DESTROY_NOTIFY);
199     PRINT_XCB_EVENT(XCB_UNMAP_NOTIFY);
200     PRINT_XCB_EVENT(XCB_MAP_NOTIFY);
201     PRINT_XCB_EVENT(XCB_MAP_REQUEST);
202     PRINT_XCB_EVENT(XCB_REPARENT_NOTIFY);
203     PRINT_XCB_EVENT(XCB_CONFIGURE_NOTIFY);
204     PRINT_XCB_EVENT(XCB_CONFIGURE_REQUEST);
205     PRINT_XCB_EVENT(XCB_GRAVITY_NOTIFY);
206     PRINT_XCB_EVENT(XCB_RESIZE_REQUEST);
207     PRINT_XCB_EVENT(XCB_CIRCULATE_NOTIFY);
208     PRINT_XCB_EVENT(XCB_CIRCULATE_REQUEST);
209     PRINT_XCB_EVENT(XCB_PROPERTY_NOTIFY);
210     PRINT_XCB_EVENT(XCB_SELECTION_CLEAR);
211     PRINT_XCB_EVENT(XCB_SELECTION_REQUEST);
212     PRINT_XCB_EVENT(XCB_SELECTION_NOTIFY);
213     PRINT_XCB_EVENT(XCB_COLORMAP_NOTIFY);
214     PRINT_XCB_EVENT(XCB_CLIENT_MESSAGE);
215     PRINT_XCB_EVENT(XCB_MAPPING_NOTIFY);
216     default:
217         printf("%s: unknown event - response_type: %d - sequence: %d\n", message, int(event->response_type & ~0x80), int(event->sequence));
218     }
219 #else
220     Q_UNUSED(message);
221     Q_UNUSED(event);
222 #endif
223 }
224
225 const char *xcb_errors[] =
226 {
227     "Success",
228     "BadRequest",
229     "BadValue",
230     "BadWindow",
231     "BadPixmap",
232     "BadAtom",
233     "BadCursor",
234     "BadFont",
235     "BadMatch",
236     "BadDrawable",
237     "BadAccess",
238     "BadAlloc",
239     "BadColor",
240     "BadGC",
241     "BadIDChoice",
242     "BadName",
243     "BadLength",
244     "BadImplementation",
245     "Unknown"
246 };
247
248 const char *xcb_protocol_request_codes[] =
249 {
250     "Null",
251     "CreateWindow",
252     "ChangeWindowAttributes",
253     "GetWindowAttributes",
254     "DestroyWindow",
255     "DestroySubwindows",
256     "ChangeSaveSet",
257     "ReparentWindow",
258     "MapWindow",
259     "MapSubwindows",
260     "UnmapWindow",
261     "UnmapSubwindows",
262     "ConfigureWindow",
263     "CirculateWindow",
264     "GetGeometry",
265     "QueryTree",
266     "InternAtom",
267     "GetAtomName",
268     "ChangeProperty",
269     "DeleteProperty",
270     "GetProperty",
271     "ListProperties",
272     "SetSelectionOwner",
273     "GetSelectionOwner",
274     "ConvertSelection",
275     "SendEvent",
276     "GrabPointer",
277     "UngrabPointer",
278     "GrabButton",
279     "UngrabButton",
280     "ChangeActivePointerGrab",
281     "GrabKeyboard",
282     "UngrabKeyboard",
283     "GrabKey",
284     "UngrabKey",
285     "AllowEvents",
286     "GrabServer",
287     "UngrabServer",
288     "QueryPointer",
289     "GetMotionEvents",
290     "TranslateCoords",
291     "WarpPointer",
292     "SetInputFocus",
293     "GetInputFocus",
294     "QueryKeymap",
295     "OpenFont",
296     "CloseFont",
297     "QueryFont",
298     "QueryTextExtents",
299     "ListFonts",
300     "ListFontsWithInfo",
301     "SetFontPath",
302     "GetFontPath",
303     "CreatePixmap",
304     "FreePixmap",
305     "CreateGC",
306     "ChangeGC",
307     "CopyGC",
308     "SetDashes",
309     "SetClipRectangles",
310     "FreeGC",
311     "ClearArea",
312     "CopyArea",
313     "CopyPlane",
314     "PolyPoint",
315     "PolyLine",
316     "PolySegment",
317     "PolyRectangle",
318     "PolyArc",
319     "FillPoly",
320     "PolyFillRectangle",
321     "PolyFillArc",
322     "PutImage",
323     "GetImage",
324     "PolyText8",
325     "PolyText16",
326     "ImageText8",
327     "ImageText16",
328     "CreateColormap",
329     "FreeColormap",
330     "CopyColormapAndFree",
331     "InstallColormap",
332     "UninstallColormap",
333     "ListInstalledColormaps",
334     "AllocColor",
335     "AllocNamedColor",
336     "AllocColorCells",
337     "AllocColorPlanes",
338     "FreeColors",
339     "StoreColors",
340     "StoreNamedColor",
341     "QueryColors",
342     "LookupColor",
343     "CreateCursor",
344     "CreateGlyphCursor",
345     "FreeCursor",
346     "RecolorCursor",
347     "QueryBestSize",
348     "QueryExtension",
349     "ListExtensions",
350     "ChangeKeyboardMapping",
351     "GetKeyboardMapping",
352     "ChangeKeyboardControl",
353     "GetKeyboardControl",
354     "Bell",
355     "ChangePointerControl",
356     "GetPointerControl",
357     "SetScreenSaver",
358     "GetScreenSaver",
359     "ChangeHosts",
360     "ListHosts",
361     "SetAccessControl",
362     "SetCloseDownMode",
363     "KillClient",
364     "RotateProperties",
365     "ForceScreenSaver",
366     "SetPointerMapping",
367     "GetPointerMapping",
368     "SetModifierMapping",
369     "GetModifierMapping",
370     "Unknown"
371 };
372
373 #ifdef Q_XCB_DEBUG
374 void QXcbConnection::log(const char *file, int line, int sequence)
375 {
376     CallInfo info;
377     info.sequence = sequence;
378     info.file = file;
379     info.line = line;
380     m_callLog << info;
381 }
382 #endif
383
384 void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
385 {
386     uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
387     uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
388
389     printf("XCB error: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d\n",
390            int(error->error_code), xcb_errors[clamped_error_code],
391            int(error->sequence), int(error->resource_id),
392            int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
393            int(error->minor_code));
394 #ifdef Q_XCB_DEBUG
395     int i = 0;
396     for (; i < m_callLog.size(); ++i) {
397         if (m_callLog.at(i).sequence == error->sequence) {
398             printf("Caused by: %s:%d\n", qPrintable(m_callLog.at(i).file), m_callLog.at(i).line);
399             break;
400         } else if (m_callLog.at(i).sequence > error->sequence) {
401             printf("Caused some time before: %s:%d\n", qPrintable(m_callLog.at(i).file), m_callLog.at(i).line);
402             if (i > 0)
403                 printf("and after: %s:%d\n", qPrintable(m_callLog.at(i-1).file), m_callLog.at(i-1).line);
404             break;
405         }
406     }
407     if (i == m_callLog.size() && !m_callLog.isEmpty())
408         printf("Caused some time after: %s:%d\n", qPrintable(m_callLog.first().file), m_callLog.first().line);
409 #endif
410 }
411
412 void QXcbConnection::processXcbEvents()
413 {
414     while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection())) {
415         bool handled = true;
416
417         uint response_type = event->response_type & ~0x80;
418
419         if (!response_type) {
420             handleXcbError((xcb_generic_error_t *)event);
421             continue;
422         }
423
424 #ifdef Q_XCB_DEBUG
425         {
426             int i = 0;
427             for (; i < m_callLog.size(); ++i)
428                 if (m_callLog.at(i).sequence >= event->sequence)
429                     break;
430             m_callLog.remove(0, i);
431         }
432 #endif
433
434         switch (response_type) {
435         case XCB_EXPOSE:
436             HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
437         case XCB_BUTTON_PRESS:
438             HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
439         case XCB_BUTTON_RELEASE:
440             HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
441         case XCB_MOTION_NOTIFY:
442             HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
443         case XCB_CONFIGURE_NOTIFY:
444             HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
445         case XCB_CLIENT_MESSAGE:
446             HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
447         case XCB_ENTER_NOTIFY:
448             HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
449         case XCB_LEAVE_NOTIFY:
450             HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
451         case XCB_FOCUS_IN:
452             HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
453         case XCB_FOCUS_OUT:
454             HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
455         case XCB_KEY_PRESS:
456             HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
457         case XCB_KEY_RELEASE:
458             HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
459         case XCB_MAPPING_NOTIFY:
460             m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
461             break;
462         default:
463             handled = false;
464             break;
465         }
466         if (handled)
467             printXcbEvent("Handled XCB event", event);
468         else
469             printXcbEvent("Unhandled XCB event", event);
470     }
471
472     xcb_flush(xcb_connection());
473 }
474
475 static const char * xcb_atomnames = {
476     // window-manager <-> client protocols
477     "WM_PROTOCOLS\0"
478     "WM_DELETE_WINDOW\0"
479     "WM_TAKE_FOCUS\0"
480     "_NET_WM_PING\0"
481     "_NET_WM_CONTEXT_HELP\0"
482     "_NET_WM_SYNC_REQUEST\0"
483     "_NET_WM_SYNC_REQUEST_COUNTER\0"
484
485     // ICCCM window state
486     "WM_STATE\0"
487     "WM_CHANGE_STATE\0"
488
489     // Session management
490     "WM_CLIENT_LEADER\0"
491     "WM_WINDOW_ROLE\0"
492     "SM_CLIENT_ID\0"
493
494     // Clipboard
495     "CLIPBOARD\0"
496     "INCR\0"
497     "TARGETS\0"
498     "MULTIPLE\0"
499     "TIMESTAMP\0"
500     "SAVE_TARGETS\0"
501     "CLIP_TEMPORARY\0"
502     "_QT_SELECTION\0"
503     "_QT_CLIPBOARD_SENTINEL\0"
504     "_QT_SELECTION_SENTINEL\0"
505     "CLIPBOARD_MANAGER\0"
506
507     "RESOURCE_MANAGER\0"
508
509     "_XSETROOT_ID\0"
510
511     "_QT_SCROLL_DONE\0"
512     "_QT_INPUT_ENCODING\0"
513
514     "_MOTIF_WM_HINTS\0"
515
516     "DTWM_IS_RUNNING\0"
517     "ENLIGHTENMENT_DESKTOP\0"
518     "_DT_SAVE_MODE\0"
519     "_SGI_DESKS_MANAGER\0"
520
521     // EWMH (aka NETWM)
522     "_NET_SUPPORTED\0"
523     "_NET_VIRTUAL_ROOTS\0"
524     "_NET_WORKAREA\0"
525
526     "_NET_MOVERESIZE_WINDOW\0"
527     "_NET_WM_MOVERESIZE\0"
528
529     "_NET_WM_NAME\0"
530     "_NET_WM_ICON_NAME\0"
531     "_NET_WM_ICON\0"
532
533     "_NET_WM_PID\0"
534
535     "_NET_WM_WINDOW_OPACITY\0"
536
537     "_NET_WM_STATE\0"
538     "_NET_WM_STATE_ABOVE\0"
539     "_NET_WM_STATE_BELOW\0"
540     "_NET_WM_STATE_FULLSCREEN\0"
541     "_NET_WM_STATE_MAXIMIZED_HORZ\0"
542     "_NET_WM_STATE_MAXIMIZED_VERT\0"
543     "_NET_WM_STATE_MODAL\0"
544     "_NET_WM_STATE_STAYS_ON_TOP\0"
545     "_NET_WM_STATE_DEMANDS_ATTENTION\0"
546
547     "_NET_WM_USER_TIME\0"
548     "_NET_WM_USER_TIME_WINDOW\0"
549     "_NET_WM_FULL_PLACEMENT\0"
550
551     "_NET_WM_WINDOW_TYPE\0"
552     "_NET_WM_WINDOW_TYPE_DESKTOP\0"
553     "_NET_WM_WINDOW_TYPE_DOCK\0"
554     "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
555     "_NET_WM_WINDOW_TYPE_MENU\0"
556     "_NET_WM_WINDOW_TYPE_UTILITY\0"
557     "_NET_WM_WINDOW_TYPE_SPLASH\0"
558     "_NET_WM_WINDOW_TYPE_DIALOG\0"
559     "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0"
560     "_NET_WM_WINDOW_TYPE_POPUP_MENU\0"
561     "_NET_WM_WINDOW_TYPE_TOOLTIP\0"
562     "_NET_WM_WINDOW_TYPE_NOTIFICATION\0"
563     "_NET_WM_WINDOW_TYPE_COMBO\0"
564     "_NET_WM_WINDOW_TYPE_DND\0"
565     "_NET_WM_WINDOW_TYPE_NORMAL\0"
566     "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
567
568     "_KDE_NET_WM_FRAME_STRUT\0"
569
570     "_NET_STARTUP_INFO\0"
571     "_NET_STARTUP_INFO_BEGIN\0"
572
573     "_NET_SUPPORTING_WM_CHECK\0"
574
575     "_NET_WM_CM_S0\0"
576
577     "_NET_SYSTEM_TRAY_VISUAL\0"
578
579     "_NET_ACTIVE_WINDOW\0"
580
581     // Property formats
582     "COMPOUND_TEXT\0"
583     "TEXT\0"
584     "UTF8_STRING\0"
585
586     // xdnd
587     "XdndEnter\0"
588     "XdndPosition\0"
589     "XdndStatus\0"
590     "XdndLeave\0"
591     "XdndDrop\0"
592     "XdndFinished\0"
593     "XdndTypeList\0"
594     "XdndActionList\0"
595
596     "XdndSelection\0"
597
598     "XdndAware\0"
599     "XdndProxy\0"
600
601     "XdndActionCopy\0"
602     "XdndActionLink\0"
603     "XdndActionMove\0"
604     "XdndActionPrivate\0"
605
606     // Motif DND
607     "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
608     "_MOTIF_DRAG_INITIATOR_INFO\0"
609     "_MOTIF_DRAG_RECEIVER_INFO\0"
610     "_MOTIF_DRAG_WINDOW\0"
611     "_MOTIF_DRAG_TARGETS\0"
612
613     "XmTRANSFER_SUCCESS\0"
614     "XmTRANSFER_FAILURE\0"
615
616     // Xkb
617     "_XKB_RULES_NAMES\0"
618
619     // XEMBED
620     "_XEMBED\0"
621     "_XEMBED_INFO\0"
622
623     // Wacom old. (before version 0.10)
624     "Wacom Stylus\0"
625     "Wacom Cursor\0"
626     "Wacom Eraser\0"
627
628     // Tablet
629     "STYLUS\0"
630     "ERASER\0"
631 };
632
633 xcb_atom_t QXcbConnection::atom(QXcbAtom::Atom atom)
634 {
635     return m_allAtoms[atom];
636 }
637
638 void QXcbConnection::initializeAllAtoms() {
639     const char *names[QXcbAtom::NAtoms];
640     const char *ptr = xcb_atomnames;
641
642     int i = 0;
643     while (*ptr) {
644         names[i++] = ptr;
645         while (*ptr)
646             ++ptr;
647         ++ptr;
648     }
649
650     Q_ASSERT(i == QXcbAtom::NPredefinedAtoms);
651
652     QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
653     settings_atom_name += m_displayName;
654     names[i++] = settings_atom_name;
655
656     xcb_intern_atom_cookie_t cookies[QXcbAtom::NAtoms];
657
658     Q_ASSERT(i == QXcbAtom::NAtoms);
659     for (i = 0; i < QXcbAtom::NAtoms; ++i)
660         cookies[i] = xcb_intern_atom(xcb_connection(), false, strlen(names[i]), names[i]);
661
662     for (i = 0; i < QXcbAtom::NAtoms; ++i)
663         m_allAtoms[i] = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0)->atom;
664 }
665
666 void QXcbConnection::sync()
667 {
668     // from xcb_aux_sync
669     xcb_get_input_focus_cookie_t cookie = Q_XCB_CALL(xcb_get_input_focus(xcb_connection()));
670     free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
671 }
672
673 #if defined(XCB_USE_EGL)
674 bool QXcbConnection::hasEgl() const
675 {
676     return m_has_egl;
677 }
678 #endif // defined(XCB_USE_EGL)
679
680 #ifdef XCB_USE_DRI2
681 void QXcbConnection::initializeDri2()
682 {
683     xcb_dri2_connect_cookie_t connect_cookie = xcb_dri2_connect_unchecked (m_connection,
684                                                                            m_screens[0]->root(),
685                                                                            XCB_DRI2_DRIVER_TYPE_DRI);
686
687     xcb_dri2_connect_reply_t *connect = xcb_dri2_connect_reply (m_connection,
688                                                                 connect_cookie, NULL);
689
690     if (! connect || connect->driver_name_length + connect->device_name_length == 0) {
691         qDebug() << "Failed to connect to dri2";
692         return;
693     }
694
695     m_dri2_device_name = QByteArray(xcb_dri2_connect_device_name (connect),
696                                                     xcb_dri2_connect_device_name_length (connect));
697     delete connect;
698
699     int fd = open(m_dri2_device_name.constData(), O_RDWR);
700     if (fd < 0) {
701         qDebug() << "InitializeDri2: Could'nt open device << dri2DeviceName";
702         m_dri2_device_name = QByteArray();
703         return;
704     }
705
706     drm_magic_t magic;
707     if (drmGetMagic(fd, &magic)) {
708         qDebug() << "Failed to get drmMagic";
709         return;
710     }
711
712     xcb_dri2_authenticate_cookie_t authenticate_cookie = xcb_dri2_authenticate_unchecked(m_connection,
713                                                                                          m_screens[0]->root(), magic);
714     xcb_dri2_authenticate_reply_t *authenticate = xcb_dri2_authenticate_reply(m_connection,
715                                                                               authenticate_cookie, NULL);
716     if (authenticate == NULL || !authenticate->authenticated) {
717         fprintf(stderr, "DRI2: failed to authenticate\n");
718         free(authenticate);
719         return;
720     }
721
722     delete authenticate;
723
724     EGLDisplay display = eglGetDRMDisplayMESA(fd);
725     if (!display) {
726         fprintf(stderr, "failed to create display\n");
727         return;
728     }
729
730     m_egl_display = display;
731     EGLint major,minor;
732     if (!eglInitialize(display, &major, &minor)) {
733         fprintf(stderr, "failed to initialize display\n");
734         return;
735     }
736 }
737
738 bool QXcbConnection::hasSupportForDri2() const
739 {
740     if (!m_dri2_support_probed) {
741         xcb_generic_error_t *error = 0;
742
743         xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id);
744         xcb_prefetch_extension_data (m_connection, &xcb_dri2_id);
745
746         xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection,
747                                                                                          XCB_XFIXES_MAJOR_VERSION,
748                                                                                          XCB_XFIXES_MINOR_VERSION);
749
750         xcb_dri2_query_version_cookie_t dri2_query_cookie = xcb_dri2_query_version (m_connection,
751                                                                                     XCB_DRI2_MAJOR_VERSION,
752                                                                                     XCB_DRI2_MINOR_VERSION);
753
754         xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection,
755                                                                                          xfixes_query_cookie, &error);
756         if (!xfixes_query || error || xfixes_query->major_version < 2) {
757             delete error;
758             delete xfixes_query;
759             return false;
760         }
761         delete xfixes_query;
762
763         xcb_dri2_query_version_reply_t *dri2_query = xcb_dri2_query_version_reply (m_connection,
764                                                                                    dri2_query_cookie, &error);
765         if (!dri2_query || error) {
766             delete error;
767             delete dri2_query;
768             return false;
769         }
770
771         QXcbConnection *that = const_cast<QXcbConnection *>(this);
772         that->m_dri2_major = dri2_query->major_version;
773         that->m_dri2_minor = dri2_query->minor_version;
774
775         that->m_has_support_for_dri2 = true;
776         that->m_dri2_support_probed = true;
777     }
778     return m_has_support_for_dri2;
779 }
780 #endif //XCB_USE_DRI2