5#include "private/qoffsetstringarray_p.h"
10#include <xcb/xfixes.h>
11#include <xcb/render.h>
12#include <xcb/xinput.h>
13#define explicit dont_use_cxx_explicit
17#if QT_CONFIG(xcb_xlib)
20#include <X11/Xlib-xcb.h>
21#include <X11/Xlibint.h>
30#if QT_CONFIG(xcb_xlib)
34 "Unsupported extension used",
36 "Maximum allowed requested length exceeded",
37 "Failed to parse display string",
38 "No such screen on display",
39 "Error during FD passing"
42static int nullErrorHandler(
Display *dpy, XErrorEvent *err)
48 const int buflen = 1024;
51 XGetErrorText(dpy, err->error_code,
buf, buflen);
52 fprintf(stderr,
"X Error: serial %lu error %d %s\n", err->serial, (
int) err->error_code,
buf);
57static int ioErrorHandler(
Display *dpy)
59 xcb_connection_t *conn = XGetXCBConnection(dpy);
60 if (conn !=
nullptr) {
62 int code = xcb_connection_has_error(conn);
63 const char *
str =
"Unknown error";
64 if (code >= 0 && code < xcbConnectionErrors.count())
65 str = xcbConnectionErrors[
code];
67 qWarning(
"The X11 connection broke: %s (code %d)",
str, code);
69 return _XDefaultIOError(dpy);
76#if QT_CONFIG(xcb_xlib)
79 m_primaryScreenNumber = DefaultScreen(dpy);
80 m_xcbConnection = XGetXCBConnection(dpy);
81 XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
82 XSetErrorHandler(nullErrorHandler);
83 XSetIOErrorHandler(ioErrorHandler);
87 m_xcbConnection = xcb_connect(m_displayName.
constData(), &m_primaryScreenNumber);
94 m_setup = xcb_get_setup(m_xcbConnection);
96 m_maximumRequestLength = xcb_get_maximum_request_length(m_xcbConnection);
98 xcb_extension_t *extensions[] = {
99 &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id,
100 &xcb_render_id, &xcb_xkb_id, &xcb_input_id,
nullptr
103 for (xcb_extension_t **ext_it = extensions; *ext_it; ++ext_it)
104 xcb_prefetch_extension_data (m_xcbConnection, *ext_it);
122#if QT_CONFIG(xcb_xlib)
123 XCloseDisplay(
static_cast<Display *
>(m_xlibDisplay));
125 xcb_disconnect(m_xcbConnection);
135 return m_maximumRequestLength * 4 - requestSize;
145 qCDebug(lcQpaXcb) <<
"failed to query intern atom: " <<
name;
159 return QByteArray(xcb_get_atom_name_name(
reply.get()), xcb_get_atom_name_name_length(
reply.get()));
167 return m_maximumRequestLength > m_setup->maximum_request_length;
185 return e->extension == m_xiOpCode;
194 return e->event_type ==
type;
199 return m_hasXFixes && responseType == m_xfixesFirstEvent + eventType;
204 return m_hasXRandr && responseType == m_xrandrFirstEvent + eventType;
209 return m_hasXkb && responseType == m_xkbFirstEvent;
214 const xcb_query_extension_reply_t *
reply = xcb_get_extension_data(m_xcbConnection, &xcb_sync_id);
223 const xcb_query_extension_reply_t *
reply = xcb_get_extension_data(m_xcbConnection, &xcb_shm_id);
225 qCDebug(lcQpaXcb,
"MIT-SHM extension is not present on the X server");
229 auto shmQuery =
Q_XCB_REPLY(xcb_shm_query_version, m_xcbConnection);
231 qCWarning(lcQpaXcb,
"failed to request MIT-SHM version");
236 m_hasShmFd = (shmQuery->major_version == 1 && shmQuery->minor_version >= 2) ||
237 shmQuery->major_version > 1;
239 qCDebug(lcQpaXcb) <<
"Has MIT-SHM :" << m_hasShm;
240 qCDebug(lcQpaXcb) <<
"Has MIT-SHM FD :" << m_hasShmFd;
248 qCDebug(lcQpaXcb,
"failed to create System V shared memory segment (remote "
249 "X11 connection?), disabling SHM");
250 m_hasShm = m_hasShmFd =
false;
258 const xcb_query_extension_reply_t *
reply = xcb_get_extension_data(m_xcbConnection, &xcb_render_id);
260 qCDebug(lcQpaXcb,
"XRender extension not present on the X server");
264 auto xrenderQuery =
Q_XCB_REPLY(xcb_render_query_version, m_xcbConnection,
265 XCB_RENDER_MAJOR_VERSION,
266 XCB_RENDER_MINOR_VERSION);
268 qCWarning(lcQpaXcb,
"xcb_render_query_version failed");
273 m_xrenderVersion.first = xrenderQuery->major_version;
274 m_xrenderVersion.second = xrenderQuery->minor_version;
279 const xcb_query_extension_reply_t *
reply = xcb_get_extension_data(m_xcbConnection, &xcb_xfixes_id);
283 auto xfixesQuery =
Q_XCB_REPLY(xcb_xfixes_query_version, m_xcbConnection,
284 XCB_XFIXES_MAJOR_VERSION,
285 XCB_XFIXES_MINOR_VERSION);
286 if (!xfixesQuery || xfixesQuery->major_version < 2) {
287 qCWarning(lcQpaXcb,
"failed to initialize XFixes");
292 m_xfixesFirstEvent =
reply->first_event;
297 const xcb_query_extension_reply_t *
reply = xcb_get_extension_data(m_xcbConnection, &xcb_randr_id);
301 auto xrandrQuery =
Q_XCB_REPLY(xcb_randr_query_version, m_xcbConnection,
302 XCB_RANDR_MAJOR_VERSION,
303 XCB_RANDR_MINOR_VERSION);
304 if (!xrandrQuery || (xrandrQuery->major_version < 1 ||
305 (xrandrQuery->major_version == 1 && xrandrQuery->minor_version < 2))) {
306 qCWarning(lcQpaXcb,
"failed to initialize XRandr 1.2");
312 m_xrandr1Minor = xrandrQuery->minor_version;
314 m_xrandrFirstEvent =
reply->first_event;
319 const xcb_query_extension_reply_t *
reply = xcb_get_extension_data(m_xcbConnection, &xcb_input_id);
321 qCDebug(lcQpaXcb,
"XInput extension is not present on the X server");
326 auto xinputQuery =
Q_XCB_REPLY(xcb_input_xi_query_version, m_xcbConnection,
327 2, XCB_INPUT_MINOR_VERSION);
328 if (!xinputQuery || xinputQuery->major_version != 2) {
329 qCWarning(lcQpaXcb,
"X server does not support XInput 2");
333 qCDebug(lcQpaXcb,
"Using XInput version %d.%d",
334 xinputQuery->major_version, xinputQuery->minor_version);
337 m_xiOpCode =
reply->major_opcode;
338 m_xinputFirstEvent =
reply->first_event;
339 m_xi2Minor = xinputQuery->minor_version;
344 const xcb_query_extension_reply_t *
reply = xcb_get_extension_data(m_xcbConnection, &xcb_shape_id);
350 auto shapeQuery =
Q_XCB_REPLY(xcb_shape_query_version, m_xcbConnection);
352 qCWarning(lcQpaXcb,
"failed to initialize XShape extension");
356 if (shapeQuery->major_version > 1 || (shapeQuery->major_version == 1 && shapeQuery->minor_version >= 1)) {
358 m_hasInputShape =
true;
364 const xcb_query_extension_reply_t *
reply = xcb_get_extension_data(m_xcbConnection, &xcb_xkb_id);
366 qCWarning(lcQpaXcb,
"XKeyboard extension not present on the X server");
372 auto xkbQuery =
Q_XCB_REPLY(xcb_xkb_use_extension, m_xcbConnection, wantMajor, wantMinor);
374 qCWarning(lcQpaXcb,
"failed to initialize XKeyboard extension");
377 if (!xkbQuery->supported) {
378 qCWarning(lcQpaXcb,
"unsupported XKB version (we want %d.%d, but X server has %d.%d)",
379 wantMajor, wantMinor, xkbQuery->serverMajor, xkbQuery->serverMinor);
384 m_xkbFirstEvent =
reply->first_event;
389#include "moc_qxcbconnection_basic.cpp"
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
bool isEnabled(QtMsgType type) const
Returns true if a message of type msgtype for the category should be shown; false otherwise.
void initialize(xcb_connection_t *connection)
static bool createSystemVShmSegment(xcb_connection_t *c, size_t segmentSize=1, void *shmInfo=nullptr)
size_t maxRequestDataBytes(size_t requestSize) const
bool isXIEvent(xcb_generic_event_t *event) const
bool hasBigRequest() const
QXcbBasicConnection(const char *displayName)
QByteArray atomName(xcb_atom_t atom)
xcb_atom_t internAtom(const char *name)
bool isXRandrType(uint responseType, int eventType) const
bool isXkbType(uint responseType) const
bool isXIType(xcb_generic_event_t *event, uint16_t type) const
xcb_atom_t atom(QXcbAtom::Atom qatom) const
bool isXFixesType(uint responseType, int eventType) const
Combined button and popup list for selecting options.
static QString displayName(CGDirectDisplayID displayID)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr auto qOffsetStringArray(const char(&...strings)[Nx]) noexcept
GLenum GLuint GLenum GLsizei const GLchar * buf
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
#define Q_XCB_REPLY(call,...)