53 XGetErrorText(dpy, err->error_code, buf, buflen);
75QXcbBasicConnection::QXcbBasicConnection(
const char *displayName)
76 : m_displayName(displayName ? QByteArray(displayName) : qgetenv(
"DISPLAY"))
78#if QT_CONFIG(xcb_xlib)
79 Display *dpy = XOpenDisplay(m_displayName.constData());
81 m_primaryScreenNumber = DefaultScreen(dpy);
82 m_xcbConnection = XGetXCBConnection(dpy);
83 XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
84 XSetErrorHandler(nullErrorHandler);
85 XSetIOErrorHandler(ioErrorHandler);
89 m_xcbConnection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber);
91 if (Q_UNLIKELY(!isConnected())) {
92 qCWarning(lcQpaXcb,
"could not connect to display %s", m_displayName.constData());
96 m_setup = xcb_get_setup(m_xcbConnection);
97 m_xcbAtom.initialize(m_xcbConnection);
98 m_maximumRequestLength = xcb_get_maximum_request_length(m_xcbConnection);
100 xcb_extension_t *extensions[] = {
101 &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id,
102 &xcb_render_id, &xcb_xkb_id, &xcb_input_id,
nullptr
105 for (xcb_extension_t **ext_it = extensions; *ext_it; ++ext_it)
106 xcb_prefetch_extension_data (m_xcbConnection, *ext_it);
109 if (!qEnvironmentVariableIsSet(
"QT_XCB_NO_MITSHM"))
111 if (!qEnvironmentVariableIsSet(
"QT_XCB_NO_XRANDR"))
115 if (!qEnvironmentVariableIsSet(
"QT_XCB_NO_XI2"))
154QByteArray QXcbBasicConnection::atomName(xcb_atom_t atom)
159 auto reply =
Q_XCB_REPLY(xcb_get_atom_name, m_xcbConnection, atom);
161 return QByteArray(xcb_get_atom_name_name(reply.get()), xcb_get_atom_name_name_length(reply.get()));
163 qCWarning(lcQpaXcb) <<
"atomName: bad atom" << atom;
223void QXcbBasicConnection::initializeShm()
225 const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_shm_id);
226 if (!reply || !reply->present) {
227 qCDebug(lcQpaXcb,
"MIT-SHM extension is not present on the X server");
231 auto shmQuery =
Q_XCB_REPLY(xcb_shm_query_version, m_xcbConnection);
233 qCWarning(lcQpaXcb,
"failed to request MIT-SHM version");
238 m_hasShmFd = (shmQuery->major_version == 1 && shmQuery->minor_version >= 2) ||
239 shmQuery->major_version > 1;
241 qCDebug(lcQpaXcb) <<
"Has MIT-SHM :" << m_hasShm;
242 qCDebug(lcQpaXcb) <<
"Has MIT-SHM FD :" << m_hasShmFd;
245 auto logging =
const_cast<QLoggingCategory*>(&lcQpaXcb());
246 bool wasEnabled = logging->isEnabled(QtMsgType::QtWarningMsg);
247 if (!logging->isEnabled(QtMsgType::QtDebugMsg))
248 logging->setEnabled(QtMsgType::QtWarningMsg,
false);
249 if (!QXcbBackingStore::createSystemVShmSegment(m_xcbConnection)) {
250 qCDebug(lcQpaXcb,
"failed to create System V shared memory segment (remote "
251 "X11 connection?), disabling SHM");
252 m_hasShm = m_hasShmFd =
false;
255 logging->setEnabled(QtMsgType::QtWarningMsg,
true);
258void QXcbBasicConnection::initializeXRender()
260 const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_render_id);
261 if (!reply || !reply->present) {
262 qCDebug(lcQpaXcb,
"XRender extension not present on the X server");
266 auto xrenderQuery =
Q_XCB_REPLY(xcb_render_query_version, m_xcbConnection,
267 XCB_RENDER_MAJOR_VERSION,
268 XCB_RENDER_MINOR_VERSION);
270 qCWarning(lcQpaXcb,
"xcb_render_query_version failed");
275 m_xrenderVersion.first = xrenderQuery->major_version;
276 m_xrenderVersion.second = xrenderQuery->minor_version;
279void QXcbBasicConnection::initializeXFixes()
281 const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_xfixes_id);
282 if (!reply || !reply->present)
285 auto xfixesQuery =
Q_XCB_REPLY(xcb_xfixes_query_version, m_xcbConnection,
286 XCB_XFIXES_MAJOR_VERSION,
287 XCB_XFIXES_MINOR_VERSION);
288 if (!xfixesQuery || xfixesQuery->major_version < 2) {
289 qCWarning(lcQpaXcb,
"failed to initialize XFixes");
294 m_xfixesFirstEvent = reply->first_event;
297void QXcbBasicConnection::initializeXRandr()
299 const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_randr_id);
300 if (!reply || !reply->present)
303 auto xrandrQuery =
Q_XCB_REPLY(xcb_randr_query_version, m_xcbConnection,
304 XCB_RANDR_MAJOR_VERSION,
305 XCB_RANDR_MINOR_VERSION);
306 if (!xrandrQuery || (xrandrQuery->major_version < 1 ||
307 (xrandrQuery->major_version == 1 && xrandrQuery->minor_version < 2))) {
308 qCWarning(lcQpaXcb,
"failed to initialize XRandr 1.2");
314 m_xrandr1Minor = xrandrQuery->minor_version;
316 m_xrandrFirstEvent = reply->first_event;
319void QXcbBasicConnection::initializeXInput2()
321 const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_input_id);
322 if (!reply || !reply->present) {
323 qCDebug(lcQpaXcb,
"XInput extension is not present on the X server");
328 auto xinputQuery =
Q_XCB_REPLY(xcb_input_xi_query_version, m_xcbConnection,
329 2, XCB_INPUT_MINOR_VERSION);
330 if (!xinputQuery || xinputQuery->major_version != 2) {
331 qCWarning(lcQpaXcb,
"X server does not support XInput 2");
335 qCDebug(lcQpaXcb,
"Using XInput version %d.%d",
336 xinputQuery->major_version, xinputQuery->minor_version);
339 m_xiOpCode = reply->major_opcode;
340 m_xinputFirstEvent = reply->first_event;
341 m_xi2Minor = xinputQuery->minor_version;
344void QXcbBasicConnection::initializeXShape()
346 const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_shape_id);
347 if (!reply || !reply->present)
352 auto shapeQuery =
Q_XCB_REPLY(xcb_shape_query_version, m_xcbConnection);
354 qCWarning(lcQpaXcb,
"failed to initialize XShape extension");
358 if (shapeQuery->major_version > 1 || (shapeQuery->major_version == 1 && shapeQuery->minor_version >= 1)) {
360 m_hasInputShape =
true;
364void QXcbBasicConnection::initializeXKB()
366 const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_xkb_id);
367 if (!reply || !reply->present) {
368 qCWarning(lcQpaXcb,
"XKeyboard extension not present on the X server");
374 auto xkbQuery =
Q_XCB_REPLY(xcb_xkb_use_extension, m_xcbConnection, wantMajor, wantMinor);
376 qCWarning(lcQpaXcb,
"failed to initialize XKeyboard extension");
379 if (!xkbQuery->supported) {
380 qCWarning(lcQpaXcb,
"unsupported XKB version (we want %d.%d, but X server has %d.%d)",
381 wantMajor, wantMinor, xkbQuery->serverMajor, xkbQuery->serverMinor);
386 m_xkbFirstEvent = reply->first_event;