Qt 4.8
qxcbwindow.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 "qxcbwindow.h"
43 
44 #include <QtDebug>
45 
46 #include "qxcbconnection.h"
47 #include "qxcbscreen.h"
48 #ifdef XCB_USE_DRI2
49 #include "qdri2context.h"
50 #endif
51 
52 // Fix xcb-icccm 3.8 support
53 #define class class_name
54 #include <xcb/xcb_icccm.h>
55 #undef class
56 
57 #ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS
58 #define xcb_wm_hints_t xcb_icccm_wm_hints_t
59 #define xcb_wm_hints_set_iconic xcb_icccm_wm_hints_set_iconic
60 #define xcb_wm_hints_set_normal xcb_icccm_wm_hints_set_normal
61 #define xcb_set_wm_hints xcb_icccm_set_wm_hints
62 
63 #define xcb_wm_hints_t xcb_icccm_wm_hints_t
64 #define xcb_get_wm_hints_reply xcb_icccm_get_wm_hints_reply
65 #define xcb_get_wm_hints xcb_icccm_get_wm_hints
66 #define xcb_set_wm_hints xcb_icccm_set_wm_hints
67 #define xcb_set_wm_normal_hints xcb_icccm_set_wm_normal_hints
68 #define xcb_size_hints_set_base_size xcb_icccm_size_hints_set_base_size
69 #define xcb_size_hints_set_max_size xcb_icccm_size_hints_set_max_size
70 #define xcb_size_hints_set_min_size xcb_icccm_size_hints_set_min_size
71 #define xcb_size_hints_set_position xcb_icccm_size_hints_set_position
72 #define xcb_size_hints_set_resize_inc xcb_icccm_size_hints_set_resize_inc
73 #define xcb_size_hints_set_size xcb_icccm_size_hints_set_size
74 #define xcb_size_hints_set_win_gravity xcb_icccm_size_hints_set_win_gravity
75 #define xcb_wm_hints_t xcb_icccm_wm_hints_t
76 #define XCB_WM_STATE_ICONIC XCB_ICCCM_WM_STATE_ICONIC
77 #endif
78 
79 #include <private/qapplication_p.h>
80 #include <private/qwindowsurface_p.h>
81 
82 #include <QtGui/QWindowSystemInterface>
83 
84 #include <stdio.h>
85 
86 #ifdef XCB_USE_XLIB
87 #include <X11/Xlib.h>
88 #include <X11/Xutil.h>
89 #endif
90 
91 #if defined(XCB_USE_GLX)
92 #include "qglxintegration.h"
93 #include "qglxconvenience.h"
94 #elif defined(XCB_USE_EGL)
95 #include "../eglconvenience/qeglplatformcontext.h"
96 #include "../eglconvenience/qeglconvenience.h"
97 #include "../eglconvenience/qxlibeglintegration.h"
98 #endif
99 
100 // Returns true if we should set WM_TRANSIENT_FOR on \a w
101 static inline bool isTransient(const QWidget *w)
102 {
103  return ((w->windowType() == Qt::Dialog
104  || w->windowType() == Qt::Sheet
105  || w->windowType() == Qt::Tool
106  || w->windowType() == Qt::SplashScreen
107  || w->windowType() == Qt::ToolTip
108  || w->windowType() == Qt::Drawer
109  || w->windowType() == Qt::Popup)
111 }
112 
114  : QPlatformWindow(tlw)
115  , m_context(0)
116 {
118 
120 
121  const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_EVENT_MASK;
122  const quint32 values[] = {
123  // XCB_CW_BACK_PIXMAP
124  XCB_NONE,
125  // XCB_CW_EVENT_MASK
126  XCB_EVENT_MASK_EXPOSURE
127  | XCB_EVENT_MASK_STRUCTURE_NOTIFY
128  | XCB_EVENT_MASK_KEY_PRESS
129  | XCB_EVENT_MASK_KEY_RELEASE
130  | XCB_EVENT_MASK_BUTTON_PRESS
131  | XCB_EVENT_MASK_BUTTON_RELEASE
132  | XCB_EVENT_MASK_BUTTON_MOTION
133  | XCB_EVENT_MASK_ENTER_WINDOW
134  | XCB_EVENT_MASK_LEAVE_WINDOW
135  | XCB_EVENT_MASK_PROPERTY_CHANGE
136  | XCB_EVENT_MASK_FOCUS_CHANGE
137  };
138 
139 #if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
140  if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
141  && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
142  || tlw->platformWindowFormat().alpha())
143  {
144 #if defined(XCB_USE_GLX)
145  XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat());
146 #elif defined(XCB_USE_EGL)
147  EGLDisplay eglDisplay = connection()->egl_display();
148  EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,tlw->platformWindowFormat(),true);
149  VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);
150 
151  XVisualInfo visualInfoTemplate;
152  memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
153  visualInfoTemplate.visualid = id;
154 
155  XVisualInfo *visualInfo;
156  int matchingCount = 0;
157  visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
158 #endif //XCB_USE_GLX
159  if (visualInfo) {
160  m_depth = visualInfo->depth;
162  Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone);
163 
164  XSetWindowAttributes a;
165  a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
166  a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
167  a.colormap = cmap;
168  m_window = XCreateWindow(DISPLAY_FROM_XCB(this), m_screen->root(), tlw->x(), tlw->y(), tlw->width(), tlw->height(),
169  0, visualInfo->depth, InputOutput, visualInfo->visual,
170  CWBackPixel|CWBorderPixel|CWColormap, &a);
171 
172  printf("created GL window: %d\n", m_window);
173  } else {
174  qFatal("no window!");
175  }
176  } else
177 #endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
178  {
179  m_window = xcb_generate_id(xcb_connection());
180  m_depth = m_screen->screen()->root_depth;
182 
183  Q_XCB_CALL(xcb_create_window(xcb_connection(),
184  XCB_COPY_FROM_PARENT, // depth -- same as root
185  m_window, // window id
186  m_screen->root(), // parent window id
187  tlw->x(),
188  tlw->y(),
189  tlw->width(),
190  tlw->height(),
191  0, // border width
192  XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
193  m_screen->screen()->root_visual, // visual
194  0, // value mask
195  0)); // value list
196 
197  printf("created regular window: %d\n", m_window);
198  }
199 
200  Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
201 
202  xcb_atom_t properties[4];
203  int propertyCount = 0;
204  properties[propertyCount++] = atom(QXcbAtom::WM_DELETE_WINDOW);
205  properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
206  properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
207 
209  properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
210 
212  properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP);
213 
214  Q_XCB_CALL(xcb_change_property(xcb_connection(),
215  XCB_PROP_MODE_REPLACE,
216  m_window,
218  XCB_ATOM_ATOM,
219  32,
220  propertyCount,
221  properties));
222  m_syncValue.hi = 0;
223  m_syncValue.lo = 0;
224 
226  m_syncCounter = xcb_generate_id(xcb_connection());
227  Q_XCB_CALL(xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue));
228 
229  Q_XCB_CALL(xcb_change_property(xcb_connection(),
230  XCB_PROP_MODE_REPLACE,
231  m_window,
233  XCB_ATOM_CARDINAL,
234  32,
235  1,
236  &m_syncCounter));
237  }
238 
239  if (isTransient(tlw) && tlw->parentWidget()) {
240  // ICCCM 4.1.2.6
241  QWidget *p = tlw->parentWidget()->window();
242  xcb_window_t parentWindow = p->winId();
243  Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
244  XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
245  1, &parentWindow));
246 
247  }
248 
249  // set the PID to let the WM kill the application if unresponsive
250  long pid = getpid();
251  Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
252  atom(QXcbAtom::_NET_WM_PID), XCB_ATOM_CARDINAL, 32,
253  1, &pid));
254 }
255 
257 {
258  delete m_context;
260  Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
261  Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
262 }
263 
265 {
267 
268  const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
269  const quint32 values[] = { rect.x(), rect.y(), rect.width(), rect.height() };
270 
271  Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
272 }
273 
274 void QXcbWindow::setVisible(bool visible)
275 {
276  xcb_wm_hints_t hints;
277  if (visible) {
278  if (widget()->isMinimized())
279  xcb_wm_hints_set_iconic(&hints);
280  else
281  xcb_wm_hints_set_normal(&hints);
282  xcb_set_wm_hints(xcb_connection(), m_window, &hints);
283  Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
284  connection()->sync();
285  } else {
286  Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
287 
288  // send synthetic UnmapNotify event according to icccm 4.1.4
289  xcb_unmap_notify_event_t event;
290  event.response_type = XCB_UNMAP_NOTIFY;
291  event.sequence = 0; // does this matter?
292  event.event = m_screen->root();
293  event.window = m_window;
294  event.from_configure = false;
295  Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
296  XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
297 
298  xcb_flush(xcb_connection());
299  }
300 }
301 
302 struct QtMWMHints {
303  quint32 flags, functions, decorations;
306 };
307 
308 enum {
309  MWM_HINTS_FUNCTIONS = (1L << 0),
310 
311  MWM_FUNC_ALL = (1L << 0),
312  MWM_FUNC_RESIZE = (1L << 1),
313  MWM_FUNC_MOVE = (1L << 2),
314  MWM_FUNC_MINIMIZE = (1L << 3),
315  MWM_FUNC_MAXIMIZE = (1L << 4),
316  MWM_FUNC_CLOSE = (1L << 5),
317 
319 
320  MWM_DECOR_ALL = (1L << 0),
321  MWM_DECOR_BORDER = (1L << 1),
322  MWM_DECOR_RESIZEH = (1L << 2),
323  MWM_DECOR_TITLE = (1L << 3),
324  MWM_DECOR_MENU = (1L << 4),
325  MWM_DECOR_MINIMIZE = (1L << 5),
326  MWM_DECOR_MAXIMIZE = (1L << 6),
327 
328  MWM_HINTS_INPUT_MODE = (1L << 2),
329 
333 };
334 
335 Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
336 {
337  Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
338 
339  setNetWmWindowTypes(flags);
340 
341  if (type == Qt::ToolTip)
343  if (type == Qt::Popup)
345 
346  bool topLevel = (flags & Qt::Window);
347  bool popup = (type == Qt::Popup);
348  bool dialog = (type == Qt::Dialog
349  || type == Qt::Sheet);
350  bool desktop = (type == Qt::Desktop);
351  bool tool = (type == Qt::Tool || type == Qt::SplashScreen
352  || type == Qt::ToolTip || type == Qt::Drawer);
353 
354  Q_UNUSED(topLevel);
355  Q_UNUSED(dialog);
356  Q_UNUSED(desktop);
357  Q_UNUSED(tool);
358 
359  bool tooltip = (type == Qt::ToolTip);
360 
361  QtMWMHints mwmhints;
362  mwmhints.flags = 0L;
363  mwmhints.functions = 0L;
364  mwmhints.decorations = 0;
365  mwmhints.input_mode = 0L;
366  mwmhints.status = 0L;
367 
368  if (type != Qt::SplashScreen) {
369  mwmhints.flags |= MWM_HINTS_DECORATIONS;
370 
371  bool customize = flags & Qt::CustomizeWindowHint;
372  if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
373  mwmhints.decorations |= MWM_DECOR_BORDER;
374  mwmhints.decorations |= MWM_DECOR_RESIZEH;
375 
376  if (flags & Qt::WindowTitleHint)
377  mwmhints.decorations |= MWM_DECOR_TITLE;
378 
379  if (flags & Qt::WindowSystemMenuHint)
380  mwmhints.decorations |= MWM_DECOR_MENU;
381 
382  if (flags & Qt::WindowMinimizeButtonHint) {
383  mwmhints.decorations |= MWM_DECOR_MINIMIZE;
384  mwmhints.functions |= MWM_FUNC_MINIMIZE;
385  }
386 
387  if (flags & Qt::WindowMaximizeButtonHint) {
388  mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
389  mwmhints.functions |= MWM_FUNC_MAXIMIZE;
390  }
391 
392  if (flags & Qt::WindowCloseButtonHint)
393  mwmhints.functions |= MWM_FUNC_CLOSE;
394  }
395  } else {
396  // if type == Qt::SplashScreen
397  mwmhints.decorations = MWM_DECOR_ALL;
398  }
399 
400  if (mwmhints.functions != 0) {
401  mwmhints.flags |= MWM_HINTS_FUNCTIONS;
403  } else {
404  mwmhints.functions = MWM_FUNC_ALL;
405  }
406 
407  if (!(flags & Qt::FramelessWindowHint)
408  && flags & Qt::CustomizeWindowHint
409  && flags & Qt::WindowTitleHint
410  && !(flags &
414  {
415  // a special case - only the titlebar without any button
416  mwmhints.flags = MWM_HINTS_FUNCTIONS;
418  mwmhints.decorations = 0;
419  }
420 
421  if (mwmhints.flags != 0l) {
422  Q_XCB_CALL(xcb_change_property(xcb_connection(),
423  XCB_PROP_MODE_REPLACE,
424  m_window,
427  32,
428  5,
429  &mwmhints));
430  } else {
432  }
433 
434  if (popup || tooltip) {
435  const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER;
436  const quint32 values[] = { true, true };
437 
438  Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
439  }
440 
441  return QPlatformWindow::setWindowFlags(flags);
442 }
443 
444 void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
445 {
446  // in order of decreasing priority
447  QVector<uint> windowTypes;
448 
449  Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
450 
451  switch (type) {
452  case Qt::Dialog:
453  case Qt::Sheet:
455  break;
456  case Qt::Tool:
457  case Qt::Drawer:
459  break;
460  case Qt::ToolTip:
462  break;
463  case Qt::SplashScreen:
465  break;
466  default:
467  break;
468  }
469 
470  if (flags & Qt::FramelessWindowHint)
472 
474 
475  Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
476  atom(QXcbAtom::_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32,
477  windowTypes.count(), windowTypes.constData()));
478 }
479 
481 {
482  return m_window;
483 }
484 
486 {
487  QPoint topLeft = geometry().topLeft();
488  Q_XCB_CALL(xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y()));
489 }
490 
492 {
493  QByteArray ba = title.toUtf8();
494  Q_XCB_CALL(xcb_change_property(xcb_connection(),
495  XCB_PROP_MODE_REPLACE,
496  m_window,
499  8,
500  ba.length(),
501  ba.constData()));
502 }
503 
505 {
506  const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
507  const quint32 values[] = { XCB_STACK_MODE_ABOVE };
508  Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
509 }
510 
512 {
513  const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
514  const quint32 values[] = { XCB_STACK_MODE_BELOW };
515  Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
516 }
517 
519 {
520  Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
521  connection()->sync();
522 }
523 
525 {
526  if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
527  printf("no opengl\n");
528  return 0;
529  }
530  if (!m_context) {
531 #if defined(XCB_USE_GLX)
532  QXcbWindow *that = const_cast<QXcbWindow *>(this);
533  that->m_context = new QGLXContext(m_window, m_screen, widget()->platformWindowFormat());
534 #elif defined(XCB_USE_EGL)
535  EGLDisplay display = connection()->egl_display();
536  EGLConfig config = q_configFromQPlatformWindowFormat(display,widget()->platformWindowFormat(),true);
537  QVector<EGLint> eglContextAttrs;
538  eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
539  eglContextAttrs.append(2);
540  eglContextAttrs.append(EGL_NONE);
541 
542  EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)m_window,0);
543  QXcbWindow *that = const_cast<QXcbWindow *>(this);
544  that->m_context = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API, static_cast<QEGLPlatformContext *>(widget()->platformWindowFormat().sharedGLContext()));
545 #elif defined(XCB_USE_DRI2)
546  QXcbWindow *that = const_cast<QXcbWindow *>(this);
547  that->m_context = new QDri2Context(that);
548 #endif
549  }
550  return m_context;
551 }
552 
553 void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
554 {
555  QWindowSurface *surface = widget()->windowSurface();
556  if (surface) {
557  QRect rect(event->x, event->y, event->width, event->height);
558 
559  surface->flush(widget(), rect, QPoint());
560  }
561 }
562 
563 void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *event)
564 {
565  if (event->format == 32 && event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
566  if (event->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) {
568  } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
569  xcb_client_message_event_t reply = *event;
570 
571  reply.response_type = XCB_CLIENT_MESSAGE;
572  reply.window = m_screen->root();
573 
574  xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply);
575  xcb_flush(xcb_connection());
576  } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) {
579  printf("Window manager supports _NET_WM_SYNC_REQUEST, syncing resizes\n");
580  }
581  m_syncValue.lo = event->data.data32[2];
582  m_syncValue.hi = event->data.data32[3];
583  }
584  }
585 }
586 
587 void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
588 {
589  int xpos = geometry().x();
590  int ypos = geometry().y();
591 
592  if ((event->width == geometry().width() && event->height == geometry().height()) || event->x != 0 || event->y != 0) {
593  xpos = event->x;
594  ypos = event->y;
595  }
596 
597  QRect rect(xpos, ypos, event->width, event->height);
598 
599  if (rect == geometry())
600  return;
601 
604 
605 #if XCB_USE_DRI2
606  if (m_context)
607  static_cast<QDri2Context *>(m_context)->resize(rect.size());
608 #endif
609 }
610 
611 static Qt::MouseButtons translateMouseButtons(int s)
612 {
613  Qt::MouseButtons ret = 0;
614  if (s & XCB_BUTTON_MASK_1)
615  ret |= Qt::LeftButton;
616  if (s & XCB_BUTTON_MASK_2)
617  ret |= Qt::MidButton;
618  if (s & XCB_BUTTON_MASK_3)
619  ret |= Qt::RightButton;
620  return ret;
621 }
622 
623 static Qt::MouseButton translateMouseButton(xcb_button_t s)
624 {
625  switch (s) {
626  case 1:
627  return Qt::LeftButton;
628  case 2:
629  return Qt::MidButton;
630  case 3:
631  return Qt::RightButton;
632  default:
633  return Qt::NoButton;
634  }
635 }
636 
637 void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
638 {
639  QPoint local(event->event_x, event->event_y);
640  QPoint global(event->root_x, event->root_y);
641 
642  Qt::KeyboardModifiers modifiers = Qt::NoModifier;
643 
644  if (event->detail >= 4 && event->detail <= 7) {
645  //logic borrowed from qapplication_x11.cpp
646  int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1);
647  bool hor = (((event->detail == 4 || event->detail == 5)
648  && (modifiers & Qt::AltModifier))
649  || (event->detail == 6 || event->detail == 7));
650 
652  local, global, delta, hor ? Qt::Horizontal : Qt::Vertical);
653  return;
654  }
655 
656  handleMouseEvent(event->detail, event->state, event->time, local, global);
657 }
658 
659 void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event)
660 {
661  QPoint local(event->event_x, event->event_y);
662  QPoint global(event->root_x, event->root_y);
663 
664  handleMouseEvent(event->detail, event->state, event->time, local, global);
665 }
666 
667 void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
668 {
669  QPoint local(event->event_x, event->event_y);
670  QPoint global(event->root_x, event->root_y);
671 
672  handleMouseEvent(event->detail, event->state, event->time, local, global);
673 }
674 
675 void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global)
676 {
677  Qt::MouseButtons buttons = translateMouseButtons(state);
678  Qt::MouseButton button = translateMouseButton(detail);
679 
680  buttons ^= button; // X event uses state *before*, Qt uses state *after*
681 
682  QWindowSystemInterface::handleMouseEvent(widget(), time, local, global, buttons);
683 }
684 
685 void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *)
686 {
688 }
689 
690 void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *)
691 {
693 }
694 
695 void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *)
696 {
698 }
699 
700 void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
701 {
703 }
704 
706 {
707  if (m_screen->syncRequestSupported() && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
708  Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
709  xcb_flush(xcb_connection());
710  connection()->sync();
711 
712  m_syncValue.lo = 0;
713  m_syncValue.hi = 0;
714  }
715 }
bool m_hasReceivedSyncRequest
Definition: qxcbwindow.h:111
void handleFocusOutEvent(const xcb_focus_out_event_t *event)
Definition: qxcbwindow.cpp:700
bool syncRequestSupported() const
Definition: qxcbscreen.h:71
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
unsigned long WId
Definition: qwindowdefs.h:119
int type
Definition: qmetatype.cpp:239
ulong decorations
int qint32
Definition: qglobal.h:937
EventRef event
int width
the width of the widget excluding any window frame
Definition: qwidget.h:166
QPlatformGLContext * m_context
Definition: qxcbwindow.h:103
static void handleWheelEvent(QWidget *w, const QPoint &local, const QPoint &global, int d, Qt::Orientation o)
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
virtual void setGeometry(const QRect &rect)
This function is called by Qt whenever a window is moved or the window is resized.
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
#define DISPLAY_FROM_XCB(object)
virtual QRect geometry() const
Returnes the current geometry of a window.
EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat, int surfaceType)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
xcb_connection_t * xcb_connection() const
Definition: qxcbobject.h:56
static Qt::MouseButtons buttons
void handleButtonPressEvent(const xcb_button_press_event_t *event)
Definition: qxcbwindow.cpp:637
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
static QColor cmap[256]
Definition: qgl_mac.mm:760
void setWindowTitle(const QString &title)
Reimplement to set the window title to title.
Definition: qxcbwindow.cpp:491
void setConnection(QXcbConnection *connection)
Definition: qxcbobject.h:52
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
QPlatformGLContext * glContext() const
Reimplement to return the glContext associated with the window.
Definition: qxcbwindow.cpp:524
void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
Definition: qxcbwindow.cpp:587
long ASN1_INTEGER_get ASN1_INTEGER * a
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QPlatformWindow class provides an abstraction for top-level windows.
Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags)
Requests setting the window flags of this surface to type.
Definition: qxcbwindow.cpp:335
WindowType
Definition: qnamespace.h:270
int x
the x coordinate of the widget relative to its parent including any window frame
Definition: qwidget.h:161
NativeWindowType EGLNativeWindowType
Definition: qegl_p.h:116
static Qt::MouseButton translateMouseButton(xcb_button_t s)
Definition: qxcbwindow.cpp:623
void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
Definition: qxcbwindow.cpp:667
QXcbConnection * connection() const
Definition: qxcbobject.h:53
void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global)
Definition: qxcbwindow.cpp:675
void handleFocusInEvent(const xcb_focus_in_event_t *event)
Definition: qxcbwindow.cpp:695
uint m_depth
Definition: qxcbwindow.h:105
xcb_sync_int64_t m_syncValue
Definition: qxcbwindow.h:108
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
static VisualID getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
static void handleWindowActivated(QWidget *w)
static Qt::MouseButtons translateMouseButtons(int s)
Definition: qxcbwindow.cpp:611
virtual void flush(QWidget *widget, const QRegion &region, const QPoint &offset)=0
Flushes the given region from the specified widget onto the screen.
int height
the height of the widget excluding any window frame
Definition: qwidget.h:167
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
QXcbScreen * m_screen
Definition: qxcbwindow.h:100
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
static void handleMouseEvent(QWidget *w, const QPoint &local, const QPoint &global, Qt::MouseButtons b)
tlw == 0 means that ev is in global coords only
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
xcb_window_t root() const
Definition: qxcbscreen.h:68
QWindowSurface * windowSurface() const
Returns the QWindowSurface this widget will be drawn into.
Definition: qwidget.cpp:12819
static QPlatformScreen * platformScreenForWidget(const QWidget *widget)
void handleClientMessageEvent(const xcb_client_message_event_t *event)
Definition: qxcbwindow.cpp:563
void setVisible(bool visible)
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false...
Definition: qxcbwindow.cpp:274
static void handleCloseEvent(QWidget *w)
static bool isTransient(const QWidget *w)
Definition: qxcbwindow.cpp:101
quint16 values[128]
void setGeometry(const QRect &rect)
This function is called by Qt whenever a window is moved or the window is resized.
Definition: qxcbwindow.cpp:264
void setNetWmWindowTypes(Qt::WindowFlags flags)
Definition: qxcbwindow.cpp:444
void handleButtonReleaseEvent(const xcb_button_release_event_t *event)
Definition: qxcbwindow.cpp:659
The QWindowSurface class provides the drawing area for top-level windows.
void handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
Definition: qxcbwindow.cpp:685
int length() const
Same as size().
Definition: qbytearray.h:356
void requestActivateWindow()
Reimplement to let Qt be able to request activation/focus for a window.
Definition: qxcbwindow.cpp:518
void raise()
Reimplement to be able to let Qt rais windows to the top of the desktop.
Definition: qxcbwindow.cpp:504
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
void handleExposeEvent(const xcb_expose_event_t *event)
Definition: qxcbwindow.cpp:553
xcb_sync_counter_t m_syncCounter
Definition: qxcbwindow.h:109
Q_CORE_EXPORT void qFatal(const char *,...)
WId winId() const
Reimplement in subclasses to return a handle to the native window.
Definition: qxcbwindow.cpp:480
The QPlatformGLContext class provides an abstraction for native GL contexts.
void setParent(const QPlatformWindow *window)
This function is called to enable native child widgets in QPA.
Definition: qxcbwindow.cpp:485
ulong functions
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
xcb_window_t window() const
Definition: qxcbwindow.h:77
int y
the y coordinate of the widget relative to its parent and including any window frame ...
Definition: qwidget.h:162
#define Q_XCB_CALL(x)
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
unsigned int quint32
Definition: qglobal.h:938
static void handleGeometryChange(QWidget *w, const QRect &newRect)
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
quint32 functions
Definition: qxcbwindow.cpp:303
QFactoryLoader * l
static const QCssKnownValue properties[NumProperties - 1]
Definition: qcssparser.cpp:67
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
int screenNumber() const
Definition: qxcbscreen.cpp:131
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
XVisualInfo * qglx_findVisualInfo(Display *display, int screen, const QPlatformWindowFormat &format)
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152
Qt::WindowType windowType() const
Returns the window type of this widget.
Definition: qwidget.h:937
WId winId() const
Returns the window system identifier of the widget.
Definition: qwidget.cpp:2557
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
Qt::WindowFlags windowFlags() const
Window flags are a combination of a type (e.
Definition: qwidget.h:939
quint32 status
Definition: qxcbwindow.cpp:305
xcb_atom_t atom(QXcbAtom::Atom atom) const
Definition: qxcbobject.h:55
void lower()
Reimplement to be able to let Qt lower windows to the bottom of the desktop.
Definition: qxcbwindow.cpp:511
static void handleEnterEvent(QWidget *w)
#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
QImage::Format m_format
Definition: qxcbwindow.h:106
qint32 input_mode
Definition: qxcbwindow.cpp:304
static void handleLeaveEvent(QWidget *w)
void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
Definition: qxcbwindow.cpp:690
xcb_window_t m_window
Definition: qxcbwindow.h:102
QWidget * widget() const
Returnes the widget which belongs to the QPlatformWindow.
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
xcb_screen_t * screen() const
Definition: qxcbscreen.h:67
QXcbWindow(QWidget *tlw)
Definition: qxcbwindow.cpp:113
void updateSyncRequestCounter()
Definition: qxcbwindow.cpp:705
MouseButton
Definition: qnamespace.h:150
virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags)
Requests setting the window flags of this surface to type.