Qt 4.8
qxcbconnection.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
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 //don't 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
104 
105 #endif //XCB_USE_XLIB
106  m_setup = xcb_get_setup(xcb_connection());
107 
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 
128  connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
129 
130  sync();
131 }
132 
134 {
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 
147 {
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 
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 
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 
634 {
635  return m_allAtoms[atom];
636 }
637 
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 
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 
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 
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
const unsigned char magic[QSXE_MAGIC_BYTES]
QXcbWindow * platformWindowFromId(xcb_window_t id)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QVector< CallInfo > m_callLog
static mach_timebase_info_data_t info
QPointer< QWidget > widget
#define it(className, varName)
static QAbstractEventDispatcher * instance(QThread *thread=0)
Returns a pointer to the event dispatcher object for the specified thread.
#define error(msg)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
#define SLOT(a)
Definition: qobjectdefs.h:226
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, window, handler)
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms]
void handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event)
xcb_connection_t * xcb_connection() const
void log(const char *file, int line, int sequence)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition: qobject.cpp:1200
void printXcbEvent(const char *message, xcb_generic_event_t *event)
The QSocketNotifier class provides support for monitoring activity on a file descriptor.
static const char * xcb_atomnames
Q_CORE_EXPORT void qDebug(const char *,...)
#define SIGNAL(a)
Definition: qobjectdefs.h:227
NSWindow * window
void handleXcbError(xcb_generic_error_t *error)
int primaryScreen() const
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
#define qApp
static QWidget * find(WId)
Returns a pointer to the widget with window identifer/handle id.
Definition: qwidget.cpp:2517
QByteArray m_displayName
QXcbConnection(const char *displayName=0)
QXcbKeyboard * m_keyboard
unsigned int uint
Definition: qglobal.h:996
const T * ptr(const T &t)
const char * xcb_errors[]
xcb_connection_t * m_connection
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
struct _XDisplay Display
Definition: qwindowdefs.h:115
const char * xcb_protocol_request_codes[]
#define Q_XCB_CALL(x)
const xcb_setup_t * m_setup
xcb_atom_t atom(QXcbAtom::Atom atom)
QList< QXcbScreen * > m_screens
#define qPrintable(string)
Definition: qglobal.h:1750
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
Definition: qalgorithms.h:319
#define O_RDWR
#define HANDLE_KEYBOARD_EVENT(event_t, handler)
The QAbstractEventDispatcher class provides an interface to manage Qt&#39;s event queue.
int open(const char *, int,...)