summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbconnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp711
1 files changed, 61 insertions, 650 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index a4294956c1..10d07c37bb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -59,38 +59,24 @@
#include "qxcbbackingstore.h"
#include "qxcbeventqueue.h"
-#include <QSocketNotifier>
#include <QAbstractEventDispatcher>
-#include <QTimer>
#include <QByteArray>
#include <QScopedPointer>
-#include <algorithm>
-
#include <stdio.h>
#include <errno.h>
-#include <xcb/shm.h>
-#include <xcb/sync.h>
+
#include <xcb/xfixes.h>
#include <xcb/xinerama.h>
-
-#if QT_CONFIG(xcb_xlib)
-#define register /* C++17 deprecated register */
-#include <X11/Xlib.h>
-#include <X11/Xlib-xcb.h>
-#include <X11/Xlibint.h>
-#include <X11/Xutil.h>
-#undef register
+#if QT_CONFIG(xkb)
+#define explicit dont_use_cxx_explicit
+#include <xcb/xkb.h>
+#undef explicit
#endif
-
#if QT_CONFIG(xcb_xinput)
#include <xcb/xinput.h>
#endif
-#if QT_CONFIG(xcb_render)
-#include <xcb/render.h>
-#endif
-
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input")
@@ -99,7 +85,6 @@ Q_LOGGING_CATEGORY(lcQpaXInputEvents, "qt.qpa.input.events")
Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen")
Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
Q_LOGGING_CATEGORY(lcQpaEventReader, "qt.qpa.events.reader")
-Q_LOGGING_CATEGORY(lcQpaXcb, "qt.qpa.xcb") // for general (uncategorized) XCB logging
Q_LOGGING_CATEGORY(lcQpaPeeker, "qt.qpa.peeker")
Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard")
Q_LOGGING_CATEGORY(lcQpaXDnd, "qt.qpa.xdnd")
@@ -110,69 +95,19 @@ Q_LOGGING_CATEGORY(lcQpaXDnd, "qt.qpa.xdnd")
#define XCB_GE_GENERIC 35
#endif
-#if QT_CONFIG(xcb_xinput)
-// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
-// - "pad0" became "extension"
-// - "pad1" and "pad" became "pad0"
-// New and old version of this struct share the following fields:
-typedef struct qt_xcb_ge_event_t {
- uint8_t response_type;
- uint8_t extension;
- uint16_t sequence;
- uint32_t length;
- uint16_t event_type;
-} qt_xcb_ge_event_t;
-
-static inline bool isXIEvent(xcb_generic_event_t *event, int opCode)
-{
- qt_xcb_ge_event_t *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
- return e->extension == opCode;
-}
-#endif // QT_CONFIG(xcb_xinput)
-
-#if QT_CONFIG(xcb_xlib)
-static const char * const xcbConnectionErrors[] = {
- "No error", /* Error 0 */
- "I/O error", /* XCB_CONN_ERROR */
- "Unsupported extension used", /* XCB_CONN_CLOSED_EXT_NOTSUPPORTED */
- "Out of memory", /* XCB_CONN_CLOSED_MEM_INSUFFICIENT */
- "Maximum allowed requested length exceeded", /* XCB_CONN_CLOSED_REQ_LEN_EXCEED */
- "Failed to parse display string", /* XCB_CONN_CLOSED_PARSE_ERR */
- "No such screen on display", /* XCB_CONN_CLOSED_INVALID_SCREEN */
- "Error during FD passing" /* XCB_CONN_CLOSED_FDPASSING_FAILED */
-};
-
-static int nullErrorHandler(Display *dpy, XErrorEvent *err)
-{
-#ifndef Q_XCB_DEBUG
- Q_UNUSED(dpy);
- Q_UNUSED(err);
-#else
- const int buflen = 1024;
- char buf[buflen];
-
- XGetErrorText(dpy, err->error_code, buf, buflen);
- fprintf(stderr, "X Error: serial %lu error %d %s\n", err->serial, (int) err->error_code, buf);
-#endif
- return 0;
-}
-
-static int ioErrorHandler(Display *dpy)
+void QXcbConnection::selectXRandrEvents()
{
- xcb_connection_t *conn = XGetXCBConnection(dpy);
- if (conn != NULL) {
- /* Print a message with a textual description of the error */
- int code = xcb_connection_has_error(conn);
- const char *str = "Unknown error";
- int arrayLength = sizeof(xcbConnectionErrors) / sizeof(xcbConnectionErrors[0]);
- if (code >= 0 && code < arrayLength)
- str = xcbConnectionErrors[code];
-
- qWarning("The X11 connection broke: %s (code %d)", str, code);
+ xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(setup());
+ for (; rootIter.rem; xcb_screen_next(&rootIter)) {
+ xcb_randr_select_input(xcb_connection(),
+ rootIter.data->root,
+ XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE |
+ XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE |
+ XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE |
+ XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY
+ );
}
- return _XDefaultIOError(dpy);
}
-#endif
QXcbScreen* QXcbConnection::findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const
{
@@ -314,7 +249,7 @@ void QXcbConnection::updateScreen(QXcbScreen *screen, const xcb_randr_output_cha
if (screen->mode() != outputChange.mode)
screen->updateRefreshRate(outputChange.mode);
// Only screen which belongs to the primary virtual desktop can be a primary screen
- if (screen->screenNumber() == m_primaryScreenNumber) {
+ if (screen->screenNumber() == primaryScreenNumber()) {
if (!screen->isPrimary() && checkOutputIsPrimary(outputChange.window, outputChange.output)) {
screen->setPrimary(true);
@@ -336,7 +271,7 @@ QXcbScreen *QXcbConnection::createScreen(QXcbVirtualDesktop *virtualDesktop,
{
QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputChange.output, outputInfo);
// Only screen which belongs to the primary virtual desktop can be a primary screen
- if (screen->screenNumber() == m_primaryScreenNumber)
+ if (screen->screenNumber() == primaryScreenNumber())
screen->setPrimary(checkOutputIsPrimary(outputChange.window, outputChange.output));
if (screen->isPrimary()) {
@@ -384,7 +319,7 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen)
void QXcbConnection::initializeScreens()
{
- xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
+ xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup());
int xcbScreenNumber = 0; // screen number in the xcb sense
QXcbScreen *primaryScreen = nullptr;
while (it.rem) {
@@ -396,7 +331,7 @@ void QXcbConnection::initializeScreens()
QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber);
m_virtualDesktops.append(virtualDesktop);
QList<QPlatformScreen *> siblings;
- if (has_randr_extension) {
+ if (hasXRender()) {
// RRGetScreenResourcesCurrent is fast but it may return nothing if the
// configuration is not initialized wrt to the hardware. We should call
// RRGetScreenResources in this case.
@@ -457,7 +392,7 @@ void QXcbConnection::initializeScreens()
// the first or an exact match. An exact match isn't
// always available if primary->output is XCB_NONE
// or currently disconnected output.
- if (m_primaryScreenNumber == xcbScreenNumber) {
+ if (primaryScreenNumber() == xcbScreenNumber) {
if (!primaryScreen || (primary && outputs[i] == primary->output)) {
if (primaryScreen)
primaryScreen->setPrimary(false);
@@ -470,9 +405,9 @@ void QXcbConnection::initializeScreens()
}
}
}
- } else if (has_xinerama_extension) {
+ } else if (hasXinerama()) {
// Xinerama is available
- auto screens = Q_XCB_REPLY(xcb_xinerama_query_screens, m_connection);
+ auto screens = Q_XCB_REPLY(xcb_xinerama_query_screens, xcb_connection());
if (screens) {
xcb_xinerama_screen_info_iterator_t it = xcb_xinerama_query_screens_screen_info_iterator(screens.get());
while (it.rem) {
@@ -492,7 +427,7 @@ void QXcbConnection::initializeScreens()
QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, XCB_NONE, nullptr);
qCDebug(lcQpaScreen) << "created fake screen" << screen;
m_screens << screen;
- if (m_primaryScreenNumber == xcbScreenNumber) {
+ if (primaryScreenNumber() == xcbScreenNumber) {
primaryScreen = screen;
primaryScreen->setPrimary(true);
}
@@ -528,72 +463,28 @@ void QXcbConnection::initializeScreens()
}
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
- : m_canGrabServer(canGrabServer)
+ : QXcbBasicConnection(displayName)
+ , m_canGrabServer(canGrabServer)
, m_defaultVisualId(defaultVisualId)
- , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
, m_nativeInterface(nativeInterface)
{
-#if QT_CONFIG(xcb_xlib)
- Display *dpy = XOpenDisplay(m_displayName.constData());
- if (dpy) {
- m_primaryScreenNumber = DefaultScreen(dpy);
- m_connection = XGetXCBConnection(dpy);
- XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
- XSetErrorHandler(nullErrorHandler);
- XSetIOErrorHandler(ioErrorHandler);
- m_xlib_display = dpy;
- }
-#else
- m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber);
-#endif // QT_CONFIG(xcb_xlib)
-
- if (Q_UNLIKELY(!m_connection || xcb_connection_has_error(m_connection))) {
- qCWarning(lcQpaScreen, "QXcbConnection: Could not connect to display %s", m_displayName.constData());
+ if (!isConnected())
return;
- }
m_eventQueue = new QXcbEventQueue(this);
- xcb_extension_t *extensions[] = {
- &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id,
-#if QT_CONFIG(xkb)
- &xcb_xkb_id,
-#endif
-#if QT_CONFIG(xcb_render)
- &xcb_render_id,
-#endif
-#if QT_CONFIG(xcb_xinput)
- &xcb_input_id,
-#endif
- 0
- };
-
- for (xcb_extension_t **ext_it = extensions; *ext_it; ++ext_it)
- xcb_prefetch_extension_data (m_connection, *ext_it);
-
- m_setup = xcb_get_setup(xcb_connection());
-
m_xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toLower();
- initializeAllAtoms();
+ selectXRandrEvents();
- initializeXSync();
- if (!qEnvironmentVariableIsSet("QT_XCB_NO_MITSHM"))
- initializeShm();
- if (!qEnvironmentVariableIsSet("QT_XCB_NO_XRANDR"))
- initializeXRandr();
- if (!has_randr_extension)
- initializeXinerama();
- initializeXFixes();
initializeScreens();
- initializeXRender();
#if QT_CONFIG(xcb_xinput)
- if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2"))
- initializeXInput2();
+ if (hasXInput2()) {
+ xi2SetupDevices();
+ xi2SelectStateEvents();
+ }
#endif
- initializeXShape();
- initializeXKB();
m_wmSupport.reset(new QXcbWMSupport(this));
m_keyboard = new QXcbKeyboard(this);
@@ -632,22 +523,9 @@ QXcbConnection::~QXcbConnection()
delete m_glIntegration;
- if (isConnected()) {
-#if QT_CONFIG(xcb_xlib)
- XCloseDisplay(static_cast<Display *>(m_xlib_display));
-#else
- xcb_disconnect(xcb_connection());
-#endif
- }
-
delete m_keyboard;
}
-bool QXcbConnection::isConnected() const
-{
- return m_connection && !xcb_connection_has_error(m_connection);
-}
-
QXcbScreen *QXcbConnection::primaryScreen() const
{
if (!m_screens.isEmpty()) {
@@ -752,17 +630,17 @@ void QXcbConnection::printXcbEvent(const QLoggingCategory &log, const char *mess
CASE_PRINT_AND_RETURN( XCB_GE_GENERIC );
}
// XFixes
- if (has_xfixes && response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY)
+ if (isXFixesType(response_type, XCB_XFIXES_SELECTION_NOTIFY))
PRINT_AND_RETURN("XCB_XFIXES_SELECTION_NOTIFY");
+
// XRandR
- if (has_randr_extension) {
- if (response_type == xrandr_first_event + XCB_RANDR_NOTIFY)
- PRINT_AND_RETURN("XCB_RANDR_NOTIFY");
- if (response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY)
- PRINT_AND_RETURN("XCB_RANDR_SCREEN_CHANGE_NOTIFY");
- }
+ if (isXRandrType(response_type, XCB_RANDR_NOTIFY))
+ PRINT_AND_RETURN("XCB_RANDR_NOTIFY");
+ if (isXRandrType(response_type, XCB_RANDR_SCREEN_CHANGE_NOTIFY))
+ PRINT_AND_RETURN("XCB_RANDR_SCREEN_CHANGE_NOTIFY");
+
// XKB
- if (response_type == xkb_first_event)
+ if (isXkbType(response_type))
PRINT_AND_RETURN("XCB_XKB_* event");
// UNKNOWN
@@ -1155,7 +1033,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
#if QT_CONFIG(xcb_xinput)
case XCB_GE_GENERIC:
// Here the windowEventListener is invoked from xi2HandleEvent()
- if (hasXInput2() && isXIEvent(event, m_xiOpCode))
+ if (hasXInput2() && isXIEvent(event))
xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
break;
#endif
@@ -1168,7 +1046,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
return;
handled = true;
- if (has_xfixes && response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
+ if (isXFixesType(response_type, XCB_XFIXES_SELECTION_NOTIFY)) {
auto notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event);
setTime(notify_event->timestamp);
#ifndef QT_NO_CLIPBOARD
@@ -1176,14 +1054,14 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
#endif
for (QXcbVirtualDesktop *virtualDesktop : qAsConst(m_virtualDesktops))
virtualDesktop->handleXFixesSelectionNotify(notify_event);
- } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) {
+ } else if (isXRandrType(response_type, XCB_RANDR_NOTIFY)) {
updateScreens(reinterpret_cast<xcb_randr_notify_event_t *>(event));
- } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
+ } else if (isXRandrType(response_type, XCB_RANDR_SCREEN_CHANGE_NOTIFY)) {
auto change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
if (auto virtualDesktop = virtualDesktopForRootWindow(change_event->root))
virtualDesktop->handleScreenChange(change_event);
#if QT_CONFIG(xkb)
- } else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295
+ } else if (isXkbType(response_type)) {
auto xkb_event = reinterpret_cast<_xkb_event *>(event);
if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
switch (xkb_event->any.xkbType) {
@@ -1239,13 +1117,13 @@ void QXcbConnection::setMousePressWindow(QXcbWindow *w)
void QXcbConnection::grabServer()
{
if (m_canGrabServer)
- xcb_grab_server(m_connection);
+ xcb_grab_server(xcb_connection());
}
void QXcbConnection::ungrabServer()
{
if (m_canGrabServer)
- xcb_ungrab_server(m_connection);
+ xcb_ungrab_server(xcb_connection());
}
xcb_timestamp_t QXcbConnection::getTimestamp()
@@ -1360,17 +1238,6 @@ xcb_window_t QXcbConnection::clientLeader()
return m_clientLeader;
}
-#if QT_CONFIG(xcb_xinput)
-static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t type)
-{
- if (!isXIEvent(event, opCode))
- return false;
-
- auto *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
- return e->event_type == type;
-}
-#endif
-
/*! \internal
Compresses events of the same type to avoid swamping the event queue.
@@ -1405,7 +1272,7 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event) const
return false;
// compress XI_Motion
- if (isXIType(event, m_xiOpCode, XCB_INPUT_MOTION)) {
+ if (isXIType(event, XCB_INPUT_MOTION)) {
#if QT_CONFIG(tabletevent)
auto xdev = reinterpret_cast<xcb_input_motion_event_t *>(event);
if (!QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents) &&
@@ -1414,17 +1281,18 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event) const
#endif // QT_CONFIG(tabletevent)
return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch,
[this](xcb_generic_event_t *next, int) {
- return isXIType(next, m_xiOpCode, XCB_INPUT_MOTION);
+ return isXIType(next, XCB_INPUT_MOTION);
});
}
// compress XI_TouchUpdate for the same touch point id
- if (isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) {
+ if (isXIType(event, XCB_INPUT_TOUCH_UPDATE)) {
auto touchUpdateEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(event);
uint32_t id = touchUpdateEvent->detail % INT_MAX;
+
return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch,
[this, &id](xcb_generic_event_t *next, int) {
- if (!isXIType(next, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE))
+ if (!isXIType(next, XCB_INPUT_TOUCH_UPDATE))
return false;
auto touchUpdateNextEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(next);
return id == touchUpdateNextEvent->detail % INT_MAX;
@@ -1465,16 +1333,16 @@ bool QXcbConnection::isUserInputEvent(xcb_generic_event_t *event) const
#if QT_CONFIG(xcb_xinput)
if (connection()->hasXInput2()) {
- isInputEvent = isXIType(event, m_xiOpCode, XCB_INPUT_BUTTON_PRESS) ||
- isXIType(event, m_xiOpCode, XCB_INPUT_BUTTON_RELEASE) ||
- isXIType(event, m_xiOpCode, XCB_INPUT_MOTION) ||
- isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_BEGIN) ||
- isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE) ||
- isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_END) ||
- isXIType(event, m_xiOpCode, XCB_INPUT_ENTER) ||
- isXIType(event, m_xiOpCode, XCB_INPUT_LEAVE) ||
+ isInputEvent = isXIType(event, XCB_INPUT_BUTTON_PRESS) ||
+ isXIType(event, XCB_INPUT_BUTTON_RELEASE) ||
+ isXIType(event, XCB_INPUT_MOTION) ||
+ isXIType(event, XCB_INPUT_TOUCH_BEGIN) ||
+ isXIType(event, XCB_INPUT_TOUCH_UPDATE) ||
+ isXIType(event, XCB_INPUT_TOUCH_END) ||
+ isXIType(event, XCB_INPUT_ENTER) ||
+ isXIType(event, XCB_INPUT_LEAVE) ||
// wacom driver's way of reporting tool proximity
- isXIType(event, m_xiOpCode, XCB_INPUT_PROPERTY);
+ isXIType(event, XCB_INPUT_PROPERTY);
}
if (isInputEvent)
return true;
@@ -1545,265 +1413,10 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags)
xcb_flush(xcb_connection());
}
-static const char * xcb_atomnames = {
- // window-manager <-> client protocols
- "WM_PROTOCOLS\0"
- "WM_DELETE_WINDOW\0"
- "WM_TAKE_FOCUS\0"
- "_NET_WM_PING\0"
- "_NET_WM_CONTEXT_HELP\0"
- "_NET_WM_SYNC_REQUEST\0"
- "_NET_WM_SYNC_REQUEST_COUNTER\0"
- "MANAGER\0"
- "_NET_SYSTEM_TRAY_OPCODE\0"
-
- // ICCCM window state
- "WM_STATE\0"
- "WM_CHANGE_STATE\0"
- "WM_CLASS\0"
- "WM_NAME\0"
-
- // Session management
- "WM_CLIENT_LEADER\0"
- "WM_WINDOW_ROLE\0"
- "SM_CLIENT_ID\0"
- "WM_CLIENT_MACHINE\0"
-
- // Clipboard
- "CLIPBOARD\0"
- "INCR\0"
- "TARGETS\0"
- "MULTIPLE\0"
- "TIMESTAMP\0"
- "SAVE_TARGETS\0"
- "CLIP_TEMPORARY\0"
- "_QT_SELECTION\0"
- "_QT_CLIPBOARD_SENTINEL\0"
- "_QT_SELECTION_SENTINEL\0"
- "CLIPBOARD_MANAGER\0"
-
- "RESOURCE_MANAGER\0"
-
- "_XSETROOT_ID\0"
-
- "_QT_SCROLL_DONE\0"
- "_QT_INPUT_ENCODING\0"
-
- "_QT_CLOSE_CONNECTION\0"
-
- "_MOTIF_WM_HINTS\0"
-
- "DTWM_IS_RUNNING\0"
- "ENLIGHTENMENT_DESKTOP\0"
- "_DT_SAVE_MODE\0"
- "_SGI_DESKS_MANAGER\0"
-
- // EWMH (aka NETWM)
- "_NET_SUPPORTED\0"
- "_NET_VIRTUAL_ROOTS\0"
- "_NET_WORKAREA\0"
-
- "_NET_MOVERESIZE_WINDOW\0"
- "_NET_WM_MOVERESIZE\0"
-
- "_NET_WM_NAME\0"
- "_NET_WM_ICON_NAME\0"
- "_NET_WM_ICON\0"
-
- "_NET_WM_PID\0"
-
- "_NET_WM_WINDOW_OPACITY\0"
-
- "_NET_WM_STATE\0"
- "_NET_WM_STATE_ABOVE\0"
- "_NET_WM_STATE_BELOW\0"
- "_NET_WM_STATE_FULLSCREEN\0"
- "_NET_WM_STATE_MAXIMIZED_HORZ\0"
- "_NET_WM_STATE_MAXIMIZED_VERT\0"
- "_NET_WM_STATE_MODAL\0"
- "_NET_WM_STATE_STAYS_ON_TOP\0"
- "_NET_WM_STATE_DEMANDS_ATTENTION\0"
-
- "_NET_WM_USER_TIME\0"
- "_NET_WM_USER_TIME_WINDOW\0"
- "_NET_WM_FULL_PLACEMENT\0"
-
- "_NET_WM_WINDOW_TYPE\0"
- "_NET_WM_WINDOW_TYPE_DESKTOP\0"
- "_NET_WM_WINDOW_TYPE_DOCK\0"
- "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
- "_NET_WM_WINDOW_TYPE_MENU\0"
- "_NET_WM_WINDOW_TYPE_UTILITY\0"
- "_NET_WM_WINDOW_TYPE_SPLASH\0"
- "_NET_WM_WINDOW_TYPE_DIALOG\0"
- "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0"
- "_NET_WM_WINDOW_TYPE_POPUP_MENU\0"
- "_NET_WM_WINDOW_TYPE_TOOLTIP\0"
- "_NET_WM_WINDOW_TYPE_NOTIFICATION\0"
- "_NET_WM_WINDOW_TYPE_COMBO\0"
- "_NET_WM_WINDOW_TYPE_DND\0"
- "_NET_WM_WINDOW_TYPE_NORMAL\0"
- "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
-
- "_KDE_NET_WM_FRAME_STRUT\0"
- "_NET_FRAME_EXTENTS\0"
-
- "_NET_STARTUP_INFO\0"
- "_NET_STARTUP_INFO_BEGIN\0"
-
- "_NET_SUPPORTING_WM_CHECK\0"
-
- "_NET_WM_CM_S0\0"
-
- "_NET_SYSTEM_TRAY_VISUAL\0"
-
- "_NET_ACTIVE_WINDOW\0"
-
- // Property formats
- "TEXT\0"
- "UTF8_STRING\0"
- "CARDINAL\0"
-
- // xdnd
- "XdndEnter\0"
- "XdndPosition\0"
- "XdndStatus\0"
- "XdndLeave\0"
- "XdndDrop\0"
- "XdndFinished\0"
- "XdndTypeList\0"
- "XdndActionList\0"
-
- "XdndSelection\0"
-
- "XdndAware\0"
- "XdndProxy\0"
-
- "XdndActionCopy\0"
- "XdndActionLink\0"
- "XdndActionMove\0"
- "XdndActionPrivate\0"
-
- // Motif DND
- "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
- "_MOTIF_DRAG_INITIATOR_INFO\0"
- "_MOTIF_DRAG_RECEIVER_INFO\0"
- "_MOTIF_DRAG_WINDOW\0"
- "_MOTIF_DRAG_TARGETS\0"
-
- "XmTRANSFER_SUCCESS\0"
- "XmTRANSFER_FAILURE\0"
-
- // Xkb
- "_XKB_RULES_NAMES\0"
-
- // XEMBED
- "_XEMBED\0"
- "_XEMBED_INFO\0"
-
- // XInput2
- "Button Left\0"
- "Button Middle\0"
- "Button Right\0"
- "Button Wheel Up\0"
- "Button Wheel Down\0"
- "Button Horiz Wheel Left\0"
- "Button Horiz Wheel Right\0"
- "Abs MT Position X\0"
- "Abs MT Position Y\0"
- "Abs MT Touch Major\0"
- "Abs MT Touch Minor\0"
- "Abs MT Orientation\0"
- "Abs MT Pressure\0"
- "Abs MT Tracking ID\0"
- "Max Contacts\0"
- "Rel X\0"
- "Rel Y\0"
- // XInput2 tablet
- "Abs X\0"
- "Abs Y\0"
- "Abs Pressure\0"
- "Abs Tilt X\0"
- "Abs Tilt Y\0"
- "Abs Wheel\0"
- "Abs Distance\0"
- "Wacom Serial IDs\0"
- "INTEGER\0"
- "Rel Horiz Wheel\0"
- "Rel Vert Wheel\0"
- "Rel Horiz Scroll\0"
- "Rel Vert Scroll\0"
- "_XSETTINGS_SETTINGS\0"
- "_COMPIZ_DECOR_PENDING\0"
- "_COMPIZ_DECOR_REQUEST\0"
- "_COMPIZ_DECOR_DELETE_PIXMAP\0"
- "_COMPIZ_TOOLKIT_ACTION\0"
- "_GTK_LOAD_ICONTHEMES\0"
- "AT_SPI_BUS\0"
- "EDID\0"
- "EDID_DATA\0"
- "XFree86_DDC_EDID1_RAWDATA\0"
- // \0\0 terminates loop.
-};
-
-QXcbAtom::Atom QXcbConnection::qatom(xcb_atom_t xatom) const
-{
- return static_cast<QXcbAtom::Atom>(std::find(m_allAtoms, m_allAtoms + QXcbAtom::NAtoms, xatom) - m_allAtoms);
-}
-
-void QXcbConnection::initializeAllAtoms() {
- const char *names[QXcbAtom::NAtoms];
- const char *ptr = xcb_atomnames;
-
- int i = 0;
- while (*ptr) {
- names[i++] = ptr;
- while (*ptr)
- ++ptr;
- ++ptr;
- }
-
- Q_ASSERT(i == QXcbAtom::NAtoms);
-
- xcb_intern_atom_cookie_t cookies[QXcbAtom::NAtoms];
-
- Q_ASSERT(i == QXcbAtom::NAtoms);
- for (i = 0; i < QXcbAtom::NAtoms; ++i)
- cookies[i] = xcb_intern_atom(xcb_connection(), false, strlen(names[i]), names[i]);
-
- for (i = 0; i < QXcbAtom::NAtoms; ++i) {
- xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0);
- m_allAtoms[i] = reply->atom;
- free(reply);
- }
-}
-
-xcb_atom_t QXcbConnection::internAtom(const char *name)
-{
- if (!name || *name == 0)
- return XCB_NONE;
-
- return Q_XCB_REPLY(xcb_intern_atom, xcb_connection(), false, strlen(name), name)->atom;
-}
-
-QByteArray QXcbConnection::atomName(xcb_atom_t atom)
-{
- if (!atom)
- return QByteArray();
-
- auto reply = Q_XCB_REPLY(xcb_get_atom_name, xcb_connection(), atom);
- if (!reply)
- qWarning() << "QXcbConnection::atomName: bad Atom" << atom;
- else
- return QByteArray(xcb_get_atom_name_name(reply.get()), xcb_get_atom_name_name_length(reply.get()));
-
- return QByteArray();
-}
-
const xcb_format_t *QXcbConnection::formatForDepth(uint8_t depth) const
{
xcb_format_iterator_t iterator =
- xcb_setup_pixmap_formats_iterator(m_setup);
+ xcb_setup_pixmap_formats_iterator(setup());
while (iterator.rem) {
xcb_format_t *format = iterator.data;
@@ -1823,208 +1436,6 @@ void QXcbConnection::sync()
free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
}
-void QXcbConnection::initializeShm()
-{
- const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_shm_id);
- if (!reply || !reply->present) {
- qCDebug(lcQpaXcb, "MIT-SHM extension is not present on the X server");
- return;
- }
- has_shm = true;
-
- auto shm_query = Q_XCB_REPLY(xcb_shm_query_version, m_connection);
- if (shm_query) {
- has_shm_fd = (shm_query->major_version == 1 && shm_query->minor_version >= 2) ||
- shm_query->major_version > 1;
- } else {
- qCWarning(lcQpaXcb, "QXcbConnection: Failed to request MIT-SHM version");
- }
-
- qCDebug(lcQpaXcb) << "Has MIT-SHM :" << has_shm;
- qCDebug(lcQpaXcb) << "Has MIT-SHM FD :" << has_shm_fd;
-
- // Temporary disable warnings (unless running in debug mode).
- auto logging = const_cast<QLoggingCategory*>(&lcQpaXcb());
- bool wasEnabled = logging->isEnabled(QtMsgType::QtWarningMsg);
- if (!logging->isEnabled(QtMsgType::QtDebugMsg))
- logging->setEnabled(QtMsgType::QtWarningMsg, false);
- if (!QXcbBackingStore::createSystemVShmSegment(this)) {
- qCDebug(lcQpaXcb, "failed to create System V shared memory segment (remote "
- "X11 connection?), disabling SHM");
- has_shm = has_shm_fd = false;
- }
- if (wasEnabled)
- logging->setEnabled(QtMsgType::QtWarningMsg, true);
-}
-
-void QXcbConnection::initializeXFixes()
-{
- const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xfixes_id);
- if (!reply || !reply->present)
- return;
-
- auto xfixes_query = Q_XCB_REPLY(xcb_xfixes_query_version, m_connection,
- XCB_XFIXES_MAJOR_VERSION,
- XCB_XFIXES_MINOR_VERSION);
- if (!xfixes_query || xfixes_query->major_version < 2) {
- qWarning("QXcbConnection: Failed to initialize XFixes");
- return;
- }
- xfixes_first_event = reply->first_event;
- has_xfixes = true;
-}
-
-void QXcbConnection::initializeXRender()
-{
-#if QT_CONFIG(xcb_render)
- const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_render_id);
- if (!reply || !reply->present) {
- qCDebug(lcQpaXcb, "XRender extension not present on the X server");
- return;
- }
-
- auto xrender_query = Q_XCB_REPLY(xcb_render_query_version, m_connection,
- XCB_RENDER_MAJOR_VERSION,
- XCB_RENDER_MINOR_VERSION);
- if (!xrender_query) {
- qCWarning(lcQpaXcb, "xcb_render_query_version failed");
- return;
- }
-
- has_render_extension = true;
- m_xrenderVersion.first = xrender_query->major_version;
- m_xrenderVersion.second = xrender_query->minor_version;
-#endif
-}
-
-void QXcbConnection::initializeXRandr()
-{
- const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_randr_id);
- if (!reply || !reply->present)
- return;
-
- xrandr_first_event = reply->first_event;
-
- auto xrandr_query = Q_XCB_REPLY(xcb_randr_query_version, m_connection,
- XCB_RANDR_MAJOR_VERSION,
- XCB_RANDR_MINOR_VERSION);
-
- has_randr_extension = true;
-
- if (!xrandr_query || (xrandr_query->major_version < 1 || (xrandr_query->major_version == 1 && xrandr_query->minor_version < 2))) {
- qWarning("QXcbConnection: Failed to initialize XRandr");
- has_randr_extension = false;
- }
-
- xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(m_setup);
- for (; rootIter.rem; xcb_screen_next(&rootIter)) {
- xcb_randr_select_input(xcb_connection(),
- rootIter.data->root,
- XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE |
- XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE |
- XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE |
- XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY
- );
- }
-}
-
-void QXcbConnection::initializeXinerama()
-{
- const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xinerama_id);
- if (!reply || !reply->present)
- return;
-
- auto xinerama_is_active = Q_XCB_REPLY(xcb_xinerama_is_active, m_connection);
- has_xinerama_extension = xinerama_is_active && xinerama_is_active->state;
-}
-
-void QXcbConnection::initializeXShape()
-{
- const xcb_query_extension_reply_t *xshape_reply = xcb_get_extension_data(m_connection, &xcb_shape_id);
- if (!xshape_reply || !xshape_reply->present)
- return;
-
- has_shape_extension = true;
- auto shape_query = Q_XCB_REPLY(xcb_shape_query_version, m_connection);
- if (!shape_query) {
- qWarning("QXcbConnection: Failed to initialize SHAPE extension");
- } else if (shape_query->major_version > 1 || (shape_query->major_version == 1 && shape_query->minor_version >= 1)) {
- // The input shape is the only thing added in SHAPE 1.1
- has_input_shape = true;
- }
-}
-
-void QXcbConnection::initializeXKB()
-{
-#if QT_CONFIG(xkb)
- const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xkb_id);
- if (!reply || !reply->present) {
- qWarning("Qt: XKEYBOARD extension not present on the X server.");
- xkb_first_event = 0;
- return;
- }
- xkb_first_event = reply->first_event;
-
- xcb_connection_t *c = connection()->xcb_connection();
-
- auto xkb_query = Q_XCB_REPLY(xcb_xkb_use_extension, c,
- XKB_X11_MIN_MAJOR_XKB_VERSION,
- XKB_X11_MIN_MINOR_XKB_VERSION);
-
- if (!xkb_query) {
- qWarning("Qt: Failed to initialize XKB extension");
- return;
- } else if (!xkb_query->supported) {
- qWarning("Qt: Unsupported XKB version (We want %d %d, but X server has %d %d)",
- XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION,
- xkb_query->serverMajor, xkb_query->serverMinor);
- return;
- }
-
- has_xkb = true;
-
- const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES |
- XCB_XKB_MAP_PART_KEY_SYMS |
- XCB_XKB_MAP_PART_MODIFIER_MAP |
- XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
- XCB_XKB_MAP_PART_KEY_ACTIONS |
- XCB_XKB_MAP_PART_KEY_BEHAVIORS |
- XCB_XKB_MAP_PART_VIRTUAL_MODS |
- XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
-
- const uint16_t required_events = (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY |
- XCB_XKB_EVENT_TYPE_MAP_NOTIFY |
- XCB_XKB_EVENT_TYPE_STATE_NOTIFY);
-
- // XKB events are reported to all interested clients without regard
- // to the current keyboard input focus or grab state
- xcb_void_cookie_t select = xcb_xkb_select_events_checked(c,
- XCB_XKB_ID_USE_CORE_KBD,
- required_events,
- 0,
- required_events,
- required_map_parts,
- required_map_parts,
- 0);
-
- xcb_generic_error_t *error = xcb_request_check(c, select);
- if (error) {
- free(error);
- qWarning("Qt: failed to select notify events from xcb-xkb");
- return;
- }
-#endif
-}
-
-void QXcbConnection::initializeXSync()
-{
- const xcb_query_extension_reply_t *reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id);
- if (!reply || !reply->present)
- return;
-
- has_sync_extension = true;
-}
-
QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const
{
if (!m_systemTrayTracker) {