13#include <private/qguiapplication_p.h>
16#include <QtCore/QDebug>
18#include <QtGui/qopenglcontext.h>
19#include <QtGui/qscreen.h>
28#include "qxcbvulkanwindow.h"
36 static const QByteArray names[] = {
37 QByteArrayLiteral(
"display"),
38 QByteArrayLiteral(
"connection"), QByteArrayLiteral(
"screen"),
39 QByteArrayLiteral(
"apptime"),
40 QByteArrayLiteral(
"appusertime"), QByteArrayLiteral(
"hintstyle"),
41 QByteArrayLiteral(
"startupid"), QByteArrayLiteral(
"traywindow"),
42 QByteArrayLiteral(
"gettimestamp"), QByteArrayLiteral(
"x11screen"),
43 QByteArrayLiteral(
"rootwindow"),
44 QByteArrayLiteral(
"subpixeltype"), QByteArrayLiteral(
"antialiasingenabled"),
45 QByteArrayLiteral(
"atspibus"),
46 QByteArrayLiteral(
"compositingenabled"),
47 QByteArrayLiteral(
"vksurface"),
48 QByteArrayLiteral(
"generatepeekerid"),
49 QByteArrayLiteral(
"removepeekerid"),
50 QByteArrayLiteral(
"peekeventqueue")
52 const QByteArray *end = names +
sizeof(names) /
sizeof(names[0]);
53 const QByteArray *result =
std::find(names, end, key);
54 return int(result - names);
57QXcbNativeInterface::QXcbNativeInterface()
66 return static_cast<
const QXcbScreen *>(s->handle())->connection()->systemTrayTracker();
69void *QXcbNativeInterface::nativeResourceForIntegration(
const QByteArray &resourceString)
71 QByteArray lowerCaseResource = resourceString.toLower();
72 void *result = handlerNativeResourceForIntegration(lowerCaseResource);
76 switch (resourceType(lowerCaseResource)) {
84 result = rootWindow();
93 result = connection();
102void *QXcbNativeInterface::nativeResourceForContext(
const QByteArray &resourceString, QOpenGLContext *context)
104 QByteArray lowerCaseResource = resourceString.toLower();
105 void *result = handlerNativeResourceForContext(lowerCaseResource, context);
109void *QXcbNativeInterface::nativeResourceForScreen(
const QByteArray &resourceString, QScreen *screen)
112 qWarning(
"nativeResourceForScreen: null screen");
116 QByteArray lowerCaseResource = resourceString.toLower();
117 void *result = handlerNativeResourceForScreen(lowerCaseResource, screen);
121 const QXcbScreen *xcbScreen =
static_cast<QXcbScreen *>(screen->handle());
122 switch (resourceType(lowerCaseResource)) {
124#if QT_CONFIG(xcb_xlib)
125 result = xcbScreen->connection()->xlib_display();
129 result = appTime(xcbScreen);
132 result = appUserTime(xcbScreen);
134 case ScreenHintStyle:
135 result =
reinterpret_cast<
void *>(xcbScreen->hintStyle() + 1);
137 case ScreenSubpixelType:
138 result =
reinterpret_cast<
void *>(xcbScreen->subpixelType() + 1);
140 case ScreenAntialiasingEnabled:
141 result =
reinterpret_cast<
void *>(xcbScreen->antialiasingEnabled() + 1);
144 if (QXcbSystemTrayTracker *s = systemTrayTracker(screen))
145 result = (
void *)quintptr(s->trayWindow());
148 result = getTimestamp(xcbScreen);
151 result =
reinterpret_cast<
void *>(xcbScreen->root());
153 case CompositingEnabled:
154 if (QXcbVirtualDesktop *vd = xcbScreen->virtualDesktop())
155 result = vd->compositingActive() ?
this :
nullptr;
163void *QXcbNativeInterface::nativeResourceForWindow(
const QByteArray &resourceString, QWindow *window)
165 QByteArray lowerCaseResource = resourceString.toLower();
166 void *result = handlerNativeResourceForWindow(lowerCaseResource, window);
170 switch (resourceType(lowerCaseResource)) {
172 result = displayForWindow(window);
175 result = connectionForWindow(window);
178 result = screenForWindow(window);
182 if (window->surfaceType() == QSurface::VulkanSurface && window->handle()) {
184 result =
static_cast<QXcbVulkanWindow *>(window->handle())->surface();
195void *QXcbNativeInterface::nativeResourceForBackingStore(
const QByteArray &resourceString, QBackingStore *backingStore)
197 const QByteArray lowerCaseResource = resourceString.toLower();
198 void *result = handlerNativeResourceForBackingStore(lowerCaseResource,backingStore);
203void *QXcbNativeInterface::nativeResourceForCursor(
const QByteArray &resource,
const QCursor &cursor)
205 if (resource == QByteArrayLiteral(
"xcbcursor")) {
206 if (
const QScreen *primaryScreen = QGuiApplication::primaryScreen()) {
207 if (
const QPlatformCursor *pCursor= primaryScreen->handle()->cursor()) {
208 xcb_cursor_t xcbCursor =
static_cast<
const QXcbCursor *>(pCursor)->xcbCursor(cursor);
209 return reinterpret_cast<
void *>(quintptr(xcbCursor));
217QPlatformNativeInterface::NativeResourceForIntegrationFunction QXcbNativeInterface::nativeResourceFunctionForIntegration(
const QByteArray &resource)
219 const QByteArray lowerCaseResource = resource.toLower();
220 QPlatformNativeInterface::NativeResourceForIntegrationFunction func = handlerNativeResourceFunctionForIntegration(lowerCaseResource);
224 if (lowerCaseResource ==
"setstartupid")
225 return NativeResourceForIntegrationFunction(
reinterpret_cast<
void *>(setStartupId));
226 if (lowerCaseResource ==
"generatepeekerid")
227 return NativeResourceForIntegrationFunction(
reinterpret_cast<
void *>(generatePeekerId));
228 if (lowerCaseResource ==
"removepeekerid")
229 return NativeResourceForIntegrationFunction(
reinterpret_cast<
void *>(removePeekerId));
230 if (lowerCaseResource ==
"peekeventqueue")
231 return NativeResourceForIntegrationFunction(
reinterpret_cast<
void *>(peekEventQueue));
236QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface::nativeResourceFunctionForContext(
const QByteArray &resource)
238 const QByteArray lowerCaseResource = resource.toLower();
239 QPlatformNativeInterface::NativeResourceForContextFunction func = handlerNativeResourceFunctionForContext(lowerCaseResource);
245QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::nativeResourceFunctionForScreen(
const QByteArray &resource)
247 const QByteArray lowerCaseResource = resource.toLower();
248 NativeResourceForScreenFunction func = handlerNativeResourceFunctionForScreen(lowerCaseResource);
252 if (lowerCaseResource ==
"setapptime")
253 return NativeResourceForScreenFunction(
reinterpret_cast<
void *>(setAppTime));
254 else if (lowerCaseResource ==
"setappusertime")
255 return NativeResourceForScreenFunction(
reinterpret_cast<
void *>(setAppUserTime));
259QPlatformNativeInterface::NativeResourceForWindowFunction QXcbNativeInterface::nativeResourceFunctionForWindow(
const QByteArray &resource)
261 const QByteArray lowerCaseResource = resource.toLower();
262 NativeResourceForWindowFunction func = handlerNativeResourceFunctionForWindow(lowerCaseResource);
266QPlatformNativeInterface::NativeResourceForBackingStoreFunction QXcbNativeInterface::nativeResourceFunctionForBackingStore(
const QByteArray &resource)
268 const QByteArray lowerCaseResource = resource.toLower();
269 NativeResourceForBackingStoreFunction func = handlerNativeResourceFunctionForBackingStore(lowerCaseResource);
273QFunctionPointer QXcbNativeInterface::platformFunction(
const QByteArray &function)
const
275 const QByteArray lowerCaseFunction = function.toLower();
276 if (QFunctionPointer func = handlerPlatformFunction(lowerCaseFunction))
282void *QXcbNativeInterface::appTime(
const QXcbScreen *screen)
287 return reinterpret_cast<
void *>(quintptr(screen->connection()->time()));
290void *QXcbNativeInterface::appUserTime(
const QXcbScreen *screen)
295 return reinterpret_cast<
void *>(quintptr(screen->connection()->netWmUserTime()));
298void *QXcbNativeInterface::getTimestamp(
const QXcbScreen *screen)
303 return reinterpret_cast<
void *>(quintptr(screen->connection()->getTimestamp()));
306void *QXcbNativeInterface::startupId()
308 QXcbIntegration* integration = QXcbIntegration::instance();
309 QXcbConnection *connection = integration->connection();
311 return reinterpret_cast<
void *>(
const_cast<
char *>(connection->startupId().constData()));
315void *QXcbNativeInterface::x11Screen()
317 QXcbIntegration *integration = QXcbIntegration::instance();
318 QXcbConnection *connection = integration->connection();
320 return reinterpret_cast<
void *>(connection->primaryScreenNumber());
324void *QXcbNativeInterface::rootWindow()
326 QXcbIntegration *integration = QXcbIntegration::instance();
327 QXcbConnection *connection = integration->connection();
329 return reinterpret_cast<
void *>(connection->rootWindow());
333Display *QXcbNativeInterface::display()
const
335#if QT_CONFIG(xcb_xlib)
336 QXcbIntegration *integration = QXcbIntegration::instance();
337 if (QXcbConnection *connection = integration->connection())
338 return reinterpret_cast<Display *>(connection->xlib_display());
343xcb_connection_t *QXcbNativeInterface::connection()
const
345 QXcbIntegration *integration = QXcbIntegration::instance();
346 return integration->connection()->xcb_connection();
349void *QXcbNativeInterface::atspiBus()
351 QXcbIntegration *integration =
static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
352 QXcbConnection *connection = integration->connection();
354 auto atspiBusAtom = connection->atom(QXcbAtom::AtomAT_SPI_BUS);
355 auto reply =
Q_XCB_REPLY(xcb_get_property, connection->xcb_connection(),
356 false, connection->rootWindow(),
357 atspiBusAtom, XCB_ATOM_STRING, 0, 128);
361 char *data = (
char *)xcb_get_property_value(reply.get());
362 int length = xcb_get_property_value_length(reply.get());
363 return new QByteArray(data, length);
369void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time)
372 static_cast<QXcbScreen *>(screen->handle())->connection()->setTime(time);
376void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time)
379 static_cast<QXcbScreen *>(screen->handle())->connection()->setNetWmUserTime(time);
383qint32 QXcbNativeInterface::generatePeekerId()
385 QXcbIntegration *integration = QXcbIntegration::instance();
386 return integration->connection()->eventQueue()->generatePeekerId();
389bool QXcbNativeInterface::removePeekerId(qint32 peekerId)
391 QXcbIntegration *integration = QXcbIntegration::instance();
392 return integration->connection()->eventQueue()->removePeekerId(peekerId);
395bool QXcbNativeInterface::peekEventQueue(QXcbEventQueue::PeekerCallback peeker,
void *peekerData,
396 QXcbEventQueue::PeekOptions option, qint32 peekerId)
398 QXcbIntegration *integration = QXcbIntegration::instance();
399 return integration->connection()->eventQueue()->peekEventQueue(peeker, peekerData, option, peekerId);
402void QXcbNativeInterface::setStartupId(
const char *data)
404 QByteArray startupId(data);
405 QXcbIntegration *integration = QXcbIntegration::instance();
406 QXcbConnection *connection = integration->connection();
408 connection->setStartupId(startupId);
411QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window)
415 QScreen *qs = window->screen();
416 screen =
static_cast<QXcbScreen *>(qs ? qs->handle() :
nullptr);
418 QScreen *qs = QGuiApplication::primaryScreen();
419 screen =
static_cast<QXcbScreen *>(qs ? qs->handle() :
nullptr);
424void *QXcbNativeInterface::displayForWindow(QWindow *window)
426#if QT_CONFIG(xcb_xlib)
427 QXcbScreen *screen = qPlatformScreenForWindow(window);
428 return screen ? screen->connection()->xlib_display() :
nullptr;
435void *QXcbNativeInterface::connectionForWindow(QWindow *window)
437 QXcbScreen *screen = qPlatformScreenForWindow(window);
438 return screen ? screen->xcb_connection() :
nullptr;
441void *QXcbNativeInterface::screenForWindow(QWindow *window)
443 QXcbScreen *screen = qPlatformScreenForWindow(window);
444 return screen ? screen->screen() :
nullptr;
447void QXcbNativeInterface::addHandler(QXcbNativeInterfaceHandler *handler)
449 m_handlers.removeAll(handler);
450 m_handlers.prepend(handler);
453void QXcbNativeInterface::removeHandler(QXcbNativeInterfaceHandler *handler)
455 m_handlers.removeAll(handler);
458QPlatformNativeInterface::NativeResourceForIntegrationFunction QXcbNativeInterface::handlerNativeResourceFunctionForIntegration(
const QByteArray &resource)
const
460 for (
int i = 0; i < m_handlers.size(); i++) {
461 QXcbNativeInterfaceHandler *handler = m_handlers.at(i);
462 NativeResourceForIntegrationFunction result = handler->nativeResourceFunctionForIntegration(resource);
469QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface::handlerNativeResourceFunctionForContext(
const QByteArray &resource)
const
471 for (
int i = 0; i < m_handlers.size(); i++) {
472 QXcbNativeInterfaceHandler *handler = m_handlers.at(i);
473 NativeResourceForContextFunction result = handler->nativeResourceFunctionForContext(resource);
480QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::handlerNativeResourceFunctionForScreen(
const QByteArray &resource)
const
482 for (
int i = 0; i < m_handlers.size(); i++) {
483 QXcbNativeInterfaceHandler *handler = m_handlers.at(i);
484 NativeResourceForScreenFunction result = handler->nativeResourceFunctionForScreen(resource);
491QPlatformNativeInterface::NativeResourceForWindowFunction QXcbNativeInterface::handlerNativeResourceFunctionForWindow(
const QByteArray &resource)
const
493 for (
int i = 0; i < m_handlers.size(); i++) {
494 QXcbNativeInterfaceHandler *handler = m_handlers.at(i);
495 NativeResourceForWindowFunction result = handler->nativeResourceFunctionForWindow(resource);
502QPlatformNativeInterface::NativeResourceForBackingStoreFunction QXcbNativeInterface::handlerNativeResourceFunctionForBackingStore(
const QByteArray &resource)
const
504 for (
int i = 0; i < m_handlers.size(); i++) {
505 QXcbNativeInterfaceHandler *handler = m_handlers.at(i);
506 NativeResourceForBackingStoreFunction result = handler->nativeResourceFunctionForBackingStore(resource);
513QFunctionPointer QXcbNativeInterface::handlerPlatformFunction(
const QByteArray &function)
const
515 for (
int i = 0; i < m_handlers.size(); i++) {
516 QXcbNativeInterfaceHandler *handler = m_handlers.at(i);
517 QFunctionPointer func = handler->platformFunction(function);
524void *QXcbNativeInterface::handlerNativeResourceForIntegration(
const QByteArray &resource)
const
526 NativeResourceForIntegrationFunction func = handlerNativeResourceFunctionForIntegration(resource);
532void *QXcbNativeInterface::handlerNativeResourceForContext(
const QByteArray &resource, QOpenGLContext *context)
const
534 NativeResourceForContextFunction func = handlerNativeResourceFunctionForContext(resource);
536 return func(context);
540void *QXcbNativeInterface::handlerNativeResourceForScreen(
const QByteArray &resource, QScreen *screen)
const
542 NativeResourceForScreenFunction func = handlerNativeResourceFunctionForScreen(resource);
548void *QXcbNativeInterface::handlerNativeResourceForWindow(
const QByteArray &resource, QWindow *window)
const
550 NativeResourceForWindowFunction func = handlerNativeResourceFunctionForWindow(resource);
556void *QXcbNativeInterface::handlerNativeResourceForBackingStore(
const QByteArray &resource, QBackingStore *backingStore)
const
558 NativeResourceForBackingStoreFunction func = handlerNativeResourceFunctionForBackingStore(resource);
560 return func(backingStore);
565 int level, QTextStream &str)
568 str << QByteArray(2 * level,
' ');
570 xcb_connection_t *conn = connection->xcb_connection();
571 auto geomReply =
Q_XCB_REPLY(xcb_get_geometry, conn, window);
574 const QRect geom(geomReply->x, geomReply->y, geomReply->width, geomReply->height);
575 if (!geom.isValid() || (geom.width() <= 3 && geom.height() <= 3))
578 const int oldFieldWidth = str.fieldWidth();
579 const QChar oldPadChar =str.padChar();
580 str.setFieldWidth(8);
581 str.setPadChar(u'0');
582 str << Qt::hex << window;
583 str.setFieldWidth(oldFieldWidth);
584 str.setPadChar(oldPadChar);
585 str << Qt::dec <<
" \""
586 << QXcbWindow::windowTitle(connection, window) <<
"\" "
587 << geom.width() <<
'x' << geom.height() << Qt::forcesign << geom.x() << geom.y()
588 << Qt::noforcesign <<
'\n';
590 auto reply =
Q_XCB_REPLY(xcb_query_tree, conn, window);
592 const int count = xcb_query_tree_children_length(reply.get());
593 const xcb_window_t *children = xcb_query_tree_children(reply.get());
594 for (
int i = 0; i < count; ++i)
595 dumpNativeWindowsRecursion(connection, children[i], level + 1, str);
599QString QXcbNativeInterface::dumpConnectionNativeWindows(
const QXcbConnection *connection, WId root)
const
602 QTextStream str(&result);
604 dumpNativeWindowsRecursion(connection, xcb_window_t(root), 0, str);
606 for (
const QXcbScreen *screen : connection->screens()) {
607 str <<
"Screen: \"" << screen->name() <<
"\"\n";
608 dumpNativeWindowsRecursion(connection, screen->root(), 0, str);
615QString QXcbNativeInterface::dumpNativeWindows(WId root)
const
617 return dumpConnectionNativeWindows(QXcbIntegration::instance()->connection(), root);
622#include "moc_qxcbnativeinterface.cpp"
#define Q_XCB_REPLY(call,...)
static QXcbSystemTrayTracker * systemTrayTracker(const QScreen *s)
static QT_BEGIN_NAMESPACE int resourceType(const QByteArray &key)
static void dumpNativeWindowsRecursion(const QXcbConnection *connection, xcb_window_t window, int level, QTextStream &str)