xcb: Wrap xcb callings in macros

... to improve readability and reliability.

This change introduces macros Q_XCB_REPLY and Q_XCB_REPLY_UNCHECKED
that allow to replace couples of xcb cookie/reply callings by
a single "calling" of a macro. The macros wrap the reply in
std::unique_ptr thus preventing the need to free it manually.

The following C++11 features are used:
  - variadic macros
  - std::unique_ptr
  - auto type deduction

Change-Id: Icf9b93353404a39bf5f4a4562b9234db18cac696
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
This commit is contained in:
Alexander Volkov 2017-02-22 02:18:27 +03:00
parent 2a3297c726
commit 89870a35bd
14 changed files with 276 additions and 578 deletions

View File

@ -111,18 +111,13 @@ bool QXcbGlxIntegration::initialize(QXcbConnection *connection)
m_glx_first_event = reply->first_event; m_glx_first_event = reply->first_event;
xcb_generic_error_t *error = 0; auto xglx_query = Q_XCB_REPLY(xcb_glx_query_version, m_connection->xcb_connection(),
xcb_glx_query_version_cookie_t xglx_query_cookie = xcb_glx_query_version(m_connection->xcb_connection(),
XCB_GLX_MAJOR_VERSION, XCB_GLX_MAJOR_VERSION,
XCB_GLX_MINOR_VERSION); XCB_GLX_MINOR_VERSION);
xcb_glx_query_version_reply_t *xglx_query = xcb_glx_query_version_reply(m_connection->xcb_connection(), if (!xglx_query) {
xglx_query_cookie, &error);
if (!xglx_query || error) {
qCWarning(lcQpaGl) << "QXcbConnection: Failed to initialize GLX"; qCWarning(lcQpaGl) << "QXcbConnection: Failed to initialize GLX";
free(error);
return false; return false;
} }
free(xglx_query);
#endif #endif
m_native_interface_handler.reset(new QXcbGlxNativeInterfaceHandler(connection->nativeInterface())); m_native_interface_handler.reset(new QXcbGlxNativeInterfaceHandler(connection->nativeInterface()));

View File

@ -305,8 +305,7 @@ QXcbClipboard::~QXcbClipboard()
m_timestamp[QClipboard::Selection] != XCB_CURRENT_TIME) { m_timestamp[QClipboard::Selection] != XCB_CURRENT_TIME) {
// First we check if there is a clipboard manager. // First we check if there is a clipboard manager.
xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER)); auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER));
xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0);
if (reply && reply->owner != XCB_NONE) { if (reply && reply->owner != XCB_NONE) {
// we delete the property so the manager saves all TARGETS. // we delete the property so the manager saves all TARGETS.
xcb_delete_property(xcb_connection(), m_owner, atom(QXcbAtom::_QT_SELECTION)); xcb_delete_property(xcb_connection(), m_owner, atom(QXcbAtom::_QT_SELECTION));
@ -320,7 +319,6 @@ QXcbClipboard::~QXcbClipboard()
"clipboard manager in a reasonable time"); "clipboard manager in a reasonable time");
} }
} }
free(reply);
} }
if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection]) if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
@ -759,17 +757,14 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property,
format = &dummy_format; format = &dummy_format;
// Don't read anything, just get the size of the property data // Don't read anything, just get the size of the property data
xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 0);
xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
if (!reply || reply->type == XCB_NONE) { if (!reply || reply->type == XCB_NONE) {
free(reply);
buffer->resize(0); buffer->resize(0);
return false; return false;
} }
*type = reply->type; *type = reply->type;
*format = reply->format; *format = reply->format;
bytes_left = reply->bytes_after; bytes_left = reply->bytes_after;
free(reply);
int offset = 0, buffer_offset = 0; int offset = 0, buffer_offset = 0;
@ -784,17 +779,15 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property,
while (bytes_left) { while (bytes_left) {
// more to read... // more to read...
xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4)); reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4);
reply = xcb_get_property_reply(xcb_connection(), cookie, 0); if (!reply || reply->type == XCB_NONE)
if (!reply || reply->type == XCB_NONE) {
free(reply);
break; break;
}
*type = reply->type; *type = reply->type;
*format = reply->format; *format = reply->format;
bytes_left = reply->bytes_after; bytes_left = reply->bytes_after;
char *data = (char *)xcb_get_property_value(reply); char *data = (char *)xcb_get_property_value(reply.get());
int length = xcb_get_property_value_length(reply); int length = xcb_get_property_value_length(reply.get());
// Here we check if we get a buffer overflow and tries to // Here we check if we get a buffer overflow and tries to
// recover -- this shouldn't normally happen, but it doesn't // recover -- this shouldn't normally happen, but it doesn't
@ -814,7 +807,6 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property,
// offset is specified in 32-bit multiples // offset is specified in 32-bit multiples
offset += length / 4; offset += length / 4;
} }
free(reply);
} }
} }
@ -891,14 +883,10 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int
return e; return e;
if (checkManager) { if (checkManager) {
xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER)); auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER));
xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0); if (!reply || reply->owner == XCB_NONE)
if (!reply || reply->owner == XCB_NONE) {
free(reply);
return 0; return 0;
} }
free(reply);
}
// process other clipboard events, since someone is probably requesting data from us // process other clipboard events, since someone is probably requesting data from us
ClipboardEvent clipboard(connection()); ClipboardEvent clipboard(connection());

View File

@ -243,11 +243,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
} else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) { } else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) {
// New XRandR output is available and it's enabled // New XRandR output is available and it's enabled
if (output.crtc != XCB_NONE && output.mode != XCB_NONE) { if (output.crtc != XCB_NONE && output.mode != XCB_NONE) {
xcb_randr_get_output_info_cookie_t outputInfoCookie = auto outputInfo = Q_XCB_REPLY(xcb_randr_get_output_info, xcb_connection(),
xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); output.output, output.config_timestamp);
QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo(
xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL));
// Find a fake screen // Find a fake screen
const auto scrs = virtualDesktop->screens(); const auto scrs = virtualDesktop->screens();
for (QPlatformScreen *scr : scrs) { for (QPlatformScreen *scr : scrs) {
@ -261,12 +258,12 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
if (screen) { if (screen) {
QString nameWas = screen->name(); QString nameWas = screen->name();
// Transform the fake screen into a physical screen // Transform the fake screen into a physical screen
screen->setOutput(output.output, outputInfo.data()); screen->setOutput(output.output, outputInfo.get());
updateScreen(screen, output); updateScreen(screen, output);
qCDebug(lcQpaScreen) << "output" << screen->name() qCDebug(lcQpaScreen) << "output" << screen->name()
<< "is connected and enabled; was fake:" << nameWas; << "is connected and enabled; was fake:" << nameWas;
} else { } else {
screen = createScreen(virtualDesktop, output, outputInfo.data()); screen = createScreen(virtualDesktop, output, outputInfo.get());
qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled";
} }
QHighDpiScaling::updateHighDpiScaling(); QHighDpiScaling::updateHighDpiScaling();
@ -274,10 +271,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
} else if (screen) { } else if (screen) {
if (output.crtc == XCB_NONE && output.mode == XCB_NONE) { if (output.crtc == XCB_NONE && output.mode == XCB_NONE) {
// Screen has been disabled // Screen has been disabled
xcb_randr_get_output_info_cookie_t outputInfoCookie = auto outputInfo = Q_XCB_REPLY(xcb_randr_get_output_info, xcb_connection(),
xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); output.output, output.config_timestamp);
QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo(
xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL));
if (outputInfo->crtc == XCB_NONE) { if (outputInfo->crtc == XCB_NONE) {
qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled"; qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled";
destroyScreen(screen); destroyScreen(screen);
@ -299,16 +294,10 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output) bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output)
{ {
xcb_generic_error_t *error = 0; auto primary = Q_XCB_REPLY(xcb_randr_get_output_primary, xcb_connection(), rootWindow);
xcb_randr_get_output_primary_cookie_t primaryCookie = if (!primary)
xcb_randr_get_output_primary(xcb_connection(), rootWindow);
QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary (
xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error));
if (!primary || error) {
qWarning("failed to get the primary output of the screen"); qWarning("failed to get the primary output of the screen");
free(error);
error = NULL;
}
const bool isPrimary = primary ? (primary->output == output) : false; const bool isPrimary = primary ? (primary->output == output) : false;
return isPrimary; return isPrimary;
@ -404,72 +393,59 @@ void QXcbConnection::initializeScreens()
m_virtualDesktops.append(virtualDesktop); m_virtualDesktops.append(virtualDesktop);
QList<QPlatformScreen *> siblings; QList<QPlatformScreen *> siblings;
if (has_randr_extension) { if (has_randr_extension) {
xcb_generic_error_t *error = NULL;
// RRGetScreenResourcesCurrent is fast but it may return nothing if the // RRGetScreenResourcesCurrent is fast but it may return nothing if the
// configuration is not initialized wrt to the hardware. We should call // configuration is not initialized wrt to the hardware. We should call
// RRGetScreenResources in this case. // RRGetScreenResources in this case.
QScopedPointer<xcb_randr_get_screen_resources_reply_t, QScopedPointerPodDeleter> resources; auto resources_current = Q_XCB_REPLY(xcb_randr_get_screen_resources_current,
xcb_randr_get_screen_resources_current_cookie_t resourcesCookie = xcb_connection(), xcbScreen->root);
xcb_randr_get_screen_resources_current(xcb_connection(), xcbScreen->root); if (!resources_current) {
QScopedPointer<xcb_randr_get_screen_resources_current_reply_t, QScopedPointerPodDeleter> resources_current(
xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, &error));
if (!resources_current || error) {
qWarning("failed to get the current screen resources"); qWarning("failed to get the current screen resources");
free(error);
} else { } else {
xcb_timestamp_t timestamp = 0; xcb_timestamp_t timestamp = 0;
xcb_randr_output_t *outputs = Q_NULLPTR; xcb_randr_output_t *outputs = Q_NULLPTR;
int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data()); int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.get());
if (outputCount) { if (outputCount) {
timestamp = resources_current->config_timestamp; timestamp = resources_current->config_timestamp;
outputs = xcb_randr_get_screen_resources_current_outputs(resources_current.data()); outputs = xcb_randr_get_screen_resources_current_outputs(resources_current.get());
} else { } else {
xcb_randr_get_screen_resources_cookie_t resourcesCookie = auto resources = Q_XCB_REPLY(xcb_randr_get_screen_resources,
xcb_randr_get_screen_resources(xcb_connection(), xcbScreen->root); xcb_connection(), xcbScreen->root);
resources.reset(xcb_randr_get_screen_resources_reply(xcb_connection(), resourcesCookie, &error)); if (!resources) {
if (!resources || error) {
qWarning("failed to get the screen resources"); qWarning("failed to get the screen resources");
free(error);
} else { } else {
timestamp = resources->config_timestamp; timestamp = resources->config_timestamp;
outputCount = xcb_randr_get_screen_resources_outputs_length(resources.data()); outputCount = xcb_randr_get_screen_resources_outputs_length(resources.get());
outputs = xcb_randr_get_screen_resources_outputs(resources.data()); outputs = xcb_randr_get_screen_resources_outputs(resources.get());
} }
} }
if (outputCount) { if (outputCount) {
xcb_randr_get_output_primary_cookie_t primaryCookie = auto primary = Q_XCB_REPLY(xcb_randr_get_output_primary, xcb_connection(), xcbScreen->root);
xcb_randr_get_output_primary(xcb_connection(), xcbScreen->root); if (!primary) {
QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary(
xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error));
if (!primary || error) {
qWarning("failed to get the primary output of the screen"); qWarning("failed to get the primary output of the screen");
free(error);
} else { } else {
for (int i = 0; i < outputCount; i++) { for (int i = 0; i < outputCount; i++) {
QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> output( auto output = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_output_info,
xcb_randr_get_output_info_reply(xcb_connection(), xcb_connection(), outputs[i], timestamp);
xcb_randr_get_output_info_unchecked(xcb_connection(), outputs[i], timestamp), NULL));
// Invalid, disconnected or disabled output // Invalid, disconnected or disabled output
if (output == NULL) if (!output)
continue; continue;
if (output->connection != XCB_RANDR_CONNECTION_CONNECTED) { if (output->connection != XCB_RANDR_CONNECTION_CONNECTED) {
qCDebug(lcQpaScreen, "Output %s is not connected", qPrintable( qCDebug(lcQpaScreen, "Output %s is not connected", qPrintable(
QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.get()),
xcb_randr_get_output_info_name_length(output.data())))); xcb_randr_get_output_info_name_length(output.get()))));
continue; continue;
} }
if (output->crtc == XCB_NONE) { if (output->crtc == XCB_NONE) {
qCDebug(lcQpaScreen, "Output %s is not enabled", qPrintable( qCDebug(lcQpaScreen, "Output %s is not enabled", qPrintable(
QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.get()),
xcb_randr_get_output_info_name_length(output.data())))); xcb_randr_get_output_info_name_length(output.get()))));
continue; continue;
} }
QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputs[i], output.data()); QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputs[i], output.get());
siblings << screen; siblings << screen;
m_screens << screen; m_screens << screen;
@ -492,12 +468,9 @@ void QXcbConnection::initializeScreens()
} }
} else if (has_xinerama_extension) { } else if (has_xinerama_extension) {
// Xinerama is available // Xinerama is available
xcb_xinerama_query_screens_cookie_t cookie = xcb_xinerama_query_screens(m_connection); auto screens = Q_XCB_REPLY(xcb_xinerama_query_screens, m_connection);
xcb_xinerama_query_screens_reply_t *screens = xcb_xinerama_query_screens_reply(m_connection,
cookie,
Q_NULLPTR);
if (screens) { if (screens) {
xcb_xinerama_screen_info_iterator_t it = xcb_xinerama_query_screens_screen_info_iterator(screens); xcb_xinerama_screen_info_iterator_t it = xcb_xinerama_query_screens_screen_info_iterator(screens.get());
while (it.rem) { while (it.rem) {
xcb_xinerama_screen_info_t *screen_info = it.data; xcb_xinerama_screen_info_t *screen_info = it.data;
QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, QXcbScreen *screen = new QXcbScreen(this, virtualDesktop,
@ -507,7 +480,6 @@ void QXcbConnection::initializeScreens()
m_screens << screen; m_screens << screen;
xcb_xinerama_screen_info_next(&it); xcb_xinerama_screen_info_next(&it);
} }
free(screens);
} }
} }
if (siblings.isEmpty()) { if (siblings.isEmpty()) {
@ -1461,13 +1433,7 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const
{ {
xcb_connection_t *c = xcb_connection(); return Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom)->owner;
xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(c, atom);
xcb_get_selection_owner_reply_t *reply;
reply = xcb_get_selection_owner_reply(c, cookie, 0);
xcb_window_t win = reply->owner;
free(reply);
return win;
} }
xcb_window_t QXcbConnection::getQtSelectionOwner() xcb_window_t QXcbConnection::getQtSelectionOwner()
@ -1993,11 +1959,7 @@ xcb_atom_t QXcbConnection::internAtom(const char *name)
if (!name || *name == 0) if (!name || *name == 0)
return XCB_NONE; return XCB_NONE;
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcb_connection(), false, strlen(name), name); return Q_XCB_REPLY(xcb_intern_atom, xcb_connection(), false, strlen(name), name)->atom;
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookie, 0);
int atom = reply->atom;
free(reply);
return atom;
} }
QByteArray QXcbConnection::atomName(xcb_atom_t atom) QByteArray QXcbConnection::atomName(xcb_atom_t atom)
@ -2005,18 +1967,12 @@ QByteArray QXcbConnection::atomName(xcb_atom_t atom)
if (!atom) if (!atom)
return QByteArray(); return QByteArray();
xcb_generic_error_t *error = 0; auto reply = Q_XCB_REPLY(xcb_get_atom_name, xcb_connection(), atom);
xcb_get_atom_name_cookie_t cookie = Q_XCB_CALL(xcb_get_atom_name(xcb_connection(), atom)); if (!reply)
xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(xcb_connection(), cookie, &error);
if (error) {
qWarning() << "QXcbConnection::atomName: bad Atom" << atom; qWarning() << "QXcbConnection::atomName: bad Atom" << atom;
free(error); else
} return QByteArray(xcb_get_atom_name_name(reply.get()), xcb_get_atom_name_name_length(reply.get()));
if (reply) {
QByteArray result(xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply));
free(reply);
return result;
}
return QByteArray(); return QByteArray();
} }
@ -2044,23 +2000,18 @@ void QXcbConnection::sync()
void QXcbConnection::initializeXFixes() void QXcbConnection::initializeXFixes()
{ {
xcb_generic_error_t *error = 0;
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xfixes_id); const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xfixes_id);
if (!reply || !reply->present) if (!reply || !reply->present)
return; return;
xfixes_first_event = reply->first_event; xfixes_first_event = reply->first_event;
xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection, auto xfixes_query = Q_XCB_REPLY(xcb_xfixes_query_version, m_connection,
XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MAJOR_VERSION,
XCB_XFIXES_MINOR_VERSION); XCB_XFIXES_MINOR_VERSION);
xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection, if (!xfixes_query || xfixes_query->major_version < 2) {
xfixes_query_cookie, &error);
if (!xfixes_query || error || xfixes_query->major_version < 2) {
qWarning("QXcbConnection: Failed to initialize XFixes"); qWarning("QXcbConnection: Failed to initialize XFixes");
free(error);
xfixes_first_event = 0; xfixes_first_event = 0;
} }
free(xfixes_query);
} }
void QXcbConnection::initializeXRender() void QXcbConnection::initializeXRender()
@ -2070,17 +2021,11 @@ void QXcbConnection::initializeXRender()
if (!reply || !reply->present) if (!reply || !reply->present)
return; return;
xcb_generic_error_t *error = 0; auto xrender_query = Q_XCB_REPLY(xcb_render_query_version, m_connection,
xcb_render_query_version_cookie_t xrender_query_cookie = xcb_render_query_version(m_connection,
XCB_RENDER_MAJOR_VERSION, XCB_RENDER_MAJOR_VERSION,
XCB_RENDER_MINOR_VERSION); XCB_RENDER_MINOR_VERSION);
xcb_render_query_version_reply_t *xrender_query = xcb_render_query_version_reply(m_connection, if (!xrender_query || (xrender_query->major_version == 0 && xrender_query->minor_version < 5))
xrender_query_cookie, &error);
if (!xrender_query || error || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) {
qWarning("QXcbConnection: Failed to initialize XRender"); qWarning("QXcbConnection: Failed to initialize XRender");
free(error);
}
free(xrender_query);
#endif #endif
} }
@ -2092,21 +2037,16 @@ void QXcbConnection::initializeXRandr()
xrandr_first_event = reply->first_event; xrandr_first_event = reply->first_event;
xcb_generic_error_t *error = 0; auto xrandr_query = Q_XCB_REPLY(xcb_randr_query_version, m_connection,
xcb_randr_query_version_cookie_t xrandr_query_cookie = xcb_randr_query_version(m_connection,
XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MAJOR_VERSION,
XCB_RANDR_MINOR_VERSION); XCB_RANDR_MINOR_VERSION);
has_randr_extension = true; has_randr_extension = true;
xcb_randr_query_version_reply_t *xrandr_query = xcb_randr_query_version_reply(m_connection, if (!xrandr_query || (xrandr_query->major_version < 1 || (xrandr_query->major_version == 1 && xrandr_query->minor_version < 2))) {
xrandr_query_cookie, &error);
if (!xrandr_query || error || (xrandr_query->major_version < 1 || (xrandr_query->major_version == 1 && xrandr_query->minor_version < 2))) {
qWarning("QXcbConnection: Failed to initialize XRandr"); qWarning("QXcbConnection: Failed to initialize XRandr");
free(error);
has_randr_extension = false; has_randr_extension = false;
} }
free(xrandr_query);
xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(m_setup); xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(m_setup);
for (; rootIter.rem; xcb_screen_next(&rootIter)) { for (; rootIter.rem; xcb_screen_next(&rootIter)) {
@ -2126,14 +2066,8 @@ void QXcbConnection::initializeXinerama()
if (!reply || !reply->present) if (!reply || !reply->present)
return; return;
xcb_generic_error_t *error = Q_NULLPTR; auto xinerama_is_active = Q_XCB_REPLY(xcb_xinerama_is_active, m_connection);
xcb_xinerama_is_active_cookie_t xinerama_query_cookie = xcb_xinerama_is_active(m_connection); has_xinerama_extension = xinerama_is_active && xinerama_is_active->state;
xcb_xinerama_is_active_reply_t *xinerama_is_active = xcb_xinerama_is_active_reply(m_connection,
xinerama_query_cookie,
&error);
has_xinerama_extension = xinerama_is_active && !error && xinerama_is_active->state;
free(error);
free(xinerama_is_active);
} }
void QXcbConnection::initializeXShape() void QXcbConnection::initializeXShape()
@ -2143,16 +2077,13 @@ void QXcbConnection::initializeXShape()
return; return;
has_shape_extension = true; has_shape_extension = true;
xcb_shape_query_version_cookie_t cookie = xcb_shape_query_version(m_connection); auto shape_query = Q_XCB_REPLY(xcb_shape_query_version, m_connection);
xcb_shape_query_version_reply_t *shape_query = xcb_shape_query_version_reply(m_connection,
cookie, NULL);
if (!shape_query) { if (!shape_query) {
qWarning("QXcbConnection: Failed to initialize SHAPE extension"); qWarning("QXcbConnection: Failed to initialize SHAPE extension");
} else if (shape_query->major_version > 1 || (shape_query->major_version == 1 && shape_query->minor_version >= 1)) { } 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 // The input shape is the only thing added in SHAPE 1.1
has_input_shape = true; has_input_shape = true;
} }
free(shape_query);
} }
void QXcbConnection::initializeXKB() void QXcbConnection::initializeXKB()
@ -2167,11 +2098,10 @@ void QXcbConnection::initializeXKB()
xkb_first_event = reply->first_event; xkb_first_event = reply->first_event;
xcb_connection_t *c = connection()->xcb_connection(); xcb_connection_t *c = connection()->xcb_connection();
xcb_xkb_use_extension_cookie_t xkb_query_cookie;
xcb_xkb_use_extension_reply_t *xkb_query;
xkb_query_cookie = xcb_xkb_use_extension(c, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION); auto xkb_query = Q_XCB_REPLY(xcb_xkb_use_extension, c,
xkb_query = xcb_xkb_use_extension_reply(c, xkb_query_cookie, 0); XKB_X11_MIN_MAJOR_XKB_VERSION,
XKB_X11_MIN_MINOR_XKB_VERSION);
if (!xkb_query) { if (!xkb_query) {
qWarning("Qt: Failed to initialize XKB extension"); qWarning("Qt: Failed to initialize XKB extension");
@ -2180,12 +2110,10 @@ void QXcbConnection::initializeXKB()
qWarning("Qt: Unsupported XKB version (We want %d %d, but X server has %d %d)", qWarning("Qt: Unsupported XKB version (We want %d %d, but X server has %d %d)",
XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION,
xkb_query->serverMajor, xkb_query->serverMinor); xkb_query->serverMajor, xkb_query->serverMinor);
free(xkb_query);
return; return;
} }
has_xkb = true; has_xkb = true;
free(xkb_query);
const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES | const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES |
XCB_XKB_MAP_PART_KEY_SYMS | XCB_XKB_MAP_PART_KEY_SYMS |

View File

@ -56,6 +56,8 @@
#include <QtCore/QLoggingCategory> #include <QtCore/QLoggingCategory>
#include <QtCore/private/qglobal_p.h> #include <QtCore/private/qglobal_p.h>
#include <memory>
// This is needed to make Qt compile together with XKB. xkb.h is using a variable // This is needed to make Qt compile together with XKB. xkb.h is using a variable
// which is called 'explicit', this is a reserved keyword in c++ // which is called 'explicit', this is a reserved keyword in c++
#if QT_CONFIG(xkb) #if QT_CONFIG(xkb)
@ -731,6 +733,20 @@ private:
QXcbConnection *m_connection; QXcbConnection *m_connection;
}; };
#define Q_XCB_REPLY_CONNECTION_ARG(connection, ...) connection
#define Q_XCB_REPLY(call, ...) \
std::unique_ptr<call##_reply_t, decltype(std::free) *>( \
call##_reply(Q_XCB_REPLY_CONNECTION_ARG(__VA_ARGS__), call(__VA_ARGS__), nullptr), \
std::free \
)
#define Q_XCB_REPLY_UNCHECKED(call, ...) \
std::unique_ptr<call##_reply_t, decltype(std::free) *>( \
call##_reply(Q_XCB_REPLY_CONNECTION_ARG(__VA_ARGS__), call##_unchecked(__VA_ARGS__), nullptr), \
std::free \
)
#ifdef Q_XCB_DEBUG #ifdef Q_XCB_DEBUG
template <typename cookie_t> template <typename cookie_t>
cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file,

View File

@ -629,10 +629,9 @@ void QXcbCursor::queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDes
*pos = QPoint(); *pos = QPoint();
xcb_window_t root = c->primaryVirtualDesktop()->root(); xcb_window_t root = c->primaryVirtualDesktop()->root();
xcb_query_pointer_cookie_t cookie = xcb_query_pointer(c->xcb_connection(), root);
xcb_generic_error_t *err = 0; auto reply = Q_XCB_REPLY(xcb_query_pointer, c->xcb_connection(), root);
xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(c->xcb_connection(), cookie, &err); if (reply) {
if (!err && reply) {
if (virtualDesktop) { if (virtualDesktop) {
const auto virtualDesktops = c->virtualDesktops(); const auto virtualDesktops = c->virtualDesktops();
for (QXcbVirtualDesktop *vd : virtualDesktops) { for (QXcbVirtualDesktop *vd : virtualDesktops) {
@ -646,11 +645,8 @@ void QXcbCursor::queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDes
*pos = QPoint(reply->root_x, reply->root_y); *pos = QPoint(reply->root_x, reply->root_y);
if (keybMask) if (keybMask)
*keybMask = reply->mask; *keybMask = reply->mask;
free(reply);
return; return;
} }
free(err);
free(reply);
} }
QPoint QXcbCursor::pos() const QPoint QXcbCursor::pos() const

View File

@ -94,32 +94,27 @@ static xcb_window_t xdndProxy(QXcbConnection *c, xcb_window_t w)
{ {
xcb_window_t proxy = XCB_NONE; xcb_window_t proxy = XCB_NONE;
xcb_get_property_cookie_t cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, w, c->atom(QXcbAtom::XdndProxy), auto reply = Q_XCB_REPLY(xcb_get_property, c->xcb_connection(),
XCB_ATOM_WINDOW, 0, 1), c); false, w, c->atom(QXcbAtom::XdndProxy), XCB_ATOM_WINDOW, 0, 1);
xcb_get_property_reply_t *reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0);
if (reply && reply->type == XCB_ATOM_WINDOW) if (reply && reply->type == XCB_ATOM_WINDOW)
proxy = *((xcb_window_t *)xcb_get_property_value(reply)); proxy = *((xcb_window_t *)xcb_get_property_value(reply.get()));
free(reply);
if (proxy == XCB_NONE) if (proxy == XCB_NONE)
return proxy; return proxy;
// exists and is real? // exists and is real?
cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, proxy, c->atom(QXcbAtom::XdndProxy), reply = Q_XCB_REPLY(xcb_get_property, c->xcb_connection(),
XCB_ATOM_WINDOW, 0, 1), c); false, proxy, c->atom(QXcbAtom::XdndProxy), XCB_ATOM_WINDOW, 0, 1);
reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0);
if (reply && reply->type == XCB_ATOM_WINDOW) { if (reply && reply->type == XCB_ATOM_WINDOW) {
xcb_window_t p = *((xcb_window_t *)xcb_get_property_value(reply)); xcb_window_t p = *((xcb_window_t *)xcb_get_property_value(reply.get()));
if (proxy != p) if (proxy != p)
proxy = 0; proxy = 0;
} else { } else {
proxy = 0; proxy = 0;
} }
free(reply);
return proxy; return proxy;
} }
@ -228,28 +223,19 @@ void QXcbDrag::endDrag()
initiatorWindow.clear(); initiatorWindow.clear();
} }
static xcb_translate_coordinates_reply_t *
translateCoordinates(QXcbConnection *c, xcb_window_t from, xcb_window_t to, int x, int y)
{
xcb_translate_coordinates_cookie_t cookie =
xcb_translate_coordinates(c->xcb_connection(), from, to, x, y);
return xcb_translate_coordinates_reply(c->xcb_connection(), cookie, 0);
}
static static
bool windowInteractsWithPosition(xcb_connection_t *connection, const QPoint & pos, xcb_window_t w, xcb_shape_sk_t shapeType) bool windowInteractsWithPosition(xcb_connection_t *connection, const QPoint & pos, xcb_window_t w, xcb_shape_sk_t shapeType)
{ {
bool interacts = false; bool interacts = false;
xcb_shape_get_rectangles_reply_t *reply = xcb_shape_get_rectangles_reply(connection, xcb_shape_get_rectangles(connection, w, shapeType), NULL); auto reply = Q_XCB_REPLY(xcb_shape_get_rectangles, connection, w, shapeType);
if (reply) { if (reply) {
xcb_rectangle_t *rectangles = xcb_shape_get_rectangles_rectangles(reply); xcb_rectangle_t *rectangles = xcb_shape_get_rectangles_rectangles(reply.get());
if (rectangles) { if (rectangles) {
const int nRectangles = xcb_shape_get_rectangles_rectangles_length(reply); const int nRectangles = xcb_shape_get_rectangles_rectangles_length(reply.get());
for (int i = 0; !interacts && i < nRectangles; ++i) { for (int i = 0; !interacts && i < nRectangles; ++i) {
interacts = QRect(rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height).contains(pos); interacts = QRect(rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height).contains(pos);
} }
} }
free(reply);
} }
return interacts; return interacts;
@ -261,33 +247,25 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
return 0; return 0;
if (md) { if (md) {
xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(xcb_connection(), w); auto reply = Q_XCB_REPLY(xcb_get_window_attributes, xcb_connection(), w);
xcb_get_window_attributes_reply_t *reply = xcb_get_window_attributes_reply(xcb_connection(), cookie, 0);
if (!reply) if (!reply)
return 0; return 0;
if (reply->map_state != XCB_MAP_STATE_VIEWABLE) if (reply->map_state != XCB_MAP_STATE_VIEWABLE)
return 0; return 0;
free(reply); auto greply = Q_XCB_REPLY(xcb_get_geometry, xcb_connection(), w);
xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(xcb_connection(), w);
xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(xcb_connection(), gcookie, 0);
if (!greply) if (!greply)
return 0; return 0;
QRect windowRect(greply->x, greply->y, greply->width, greply->height); QRect windowRect(greply->x, greply->y, greply->width, greply->height);
free(greply);
if (windowRect.contains(pos)) { if (windowRect.contains(pos)) {
bool windowContainsMouse = !ignoreNonXdndAwareWindows; bool windowContainsMouse = !ignoreNonXdndAwareWindows;
{ {
xcb_get_property_cookie_t cookie = auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
Q_XCB_CALL(xcb_get_property(xcb_connection(), false, w, connection()->atom(QXcbAtom::XdndAware), false, w, connection()->atom(QXcbAtom::XdndAware),
XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); XCB_GET_PROPERTY_TYPE_ANY, 0, 0);
xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
bool isAware = reply && reply->type != XCB_NONE; bool isAware = reply && reply->type != XCB_NONE;
free(reply);
if (isAware) { if (isAware) {
const QPoint relPos = pos - windowRect.topLeft(); const QPoint relPos = pos - windowRect.topLeft();
// When ShapeInput and ShapeBounding are not set they return a single rectangle with the geometry of the window, this is why we // When ShapeInput and ShapeBounding are not set they return a single rectangle with the geometry of the window, this is why we
@ -303,19 +281,16 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
} }
} }
xcb_query_tree_cookie_t cookie = xcb_query_tree (xcb_connection(), w); auto reply = Q_XCB_REPLY(xcb_query_tree, xcb_connection(), w);
xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, 0);
if (!reply) if (!reply)
return 0; return 0;
int nc = xcb_query_tree_children_length(reply); int nc = xcb_query_tree_children_length(reply.get());
xcb_window_t *c = xcb_query_tree_children(reply); xcb_window_t *c = xcb_query_tree_children(reply.get());
xcb_window_t r = 0; xcb_window_t r = 0;
for (uint i = nc; !r && i--;) for (uint i = nc; !r && i--;)
r = findRealWindow(pos - windowRect.topLeft(), c[i], md-1, ignoreNonXdndAwareWindows); r = findRealWindow(pos - windowRect.topLeft(), c[i], md-1, ignoreNonXdndAwareWindows);
free(reply);
if (r) if (r)
return r; return r;
@ -356,15 +331,14 @@ void QXcbDrag::move(const QPoint &globalPos)
} }
xcb_window_t rootwin = current_virtual_desktop->root(); xcb_window_t rootwin = current_virtual_desktop->root();
xcb_translate_coordinates_reply_t *translate = auto translate = Q_XCB_REPLY(xcb_translate_coordinates, connection()->xcb_connection(),
::translateCoordinates(connection(), rootwin, rootwin, globalPos.x(), globalPos.y()); rootwin, rootwin, globalPos.x(), globalPos.y());
if (!translate) if (!translate)
return; return;
xcb_window_t target = translate->child; xcb_window_t target = translate->child;
int lx = translate->dst_x; int lx = translate->dst_x;
int ly = translate->dst_y; int ly = translate->dst_y;
free (translate);
if (target && target != rootwin) { if (target && target != rootwin) {
xcb_window_t src = rootwin; xcb_window_t src = rootwin;
@ -372,7 +346,8 @@ void QXcbDrag::move(const QPoint &globalPos)
DNDDEBUG << "checking target for XdndAware" << target << lx << ly; DNDDEBUG << "checking target for XdndAware" << target << lx << ly;
// translate coordinates // translate coordinates
translate = ::translateCoordinates(connection(), src, target, lx, ly); auto translate = Q_XCB_REPLY(xcb_translate_coordinates, connection()->xcb_connection(),
src, target, lx, ly);
if (!translate) { if (!translate) {
target = 0; target = 0;
break; break;
@ -381,14 +356,11 @@ void QXcbDrag::move(const QPoint &globalPos)
ly = translate->dst_y; ly = translate->dst_y;
src = target; src = target;
xcb_window_t child = translate->child; xcb_window_t child = translate->child;
free(translate);
// check if it has XdndAware // check if it has XdndAware
xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, target, auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, target,
atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0);
xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
bool aware = reply && reply->type != XCB_NONE; bool aware = reply && reply->type != XCB_NONE;
free(reply);
if (aware) { if (aware) {
DNDDEBUG << "Found XdndAware on " << target; DNDDEBUG << "Found XdndAware on " << target;
break; break;
@ -422,16 +394,14 @@ void QXcbDrag::move(const QPoint &globalPos)
int target_version = 1; int target_version = 1;
if (proxy_target) { if (proxy_target) {
xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, proxy_target, auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
false, proxy_target,
atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 1); atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 1);
xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
if (!reply || reply->type == XCB_NONE) if (!reply || reply->type == XCB_NONE)
target = 0; target = 0;
target_version = *(uint32_t *)xcb_get_property_value(reply); target_version = *(uint32_t *)xcb_get_property_value(reply.get());
target_version = qMin(xdnd_version, target_version ? target_version : 1); target_version = qMin(xdnd_version, target_version ? target_version : 1);
free(reply);
} }
if (target != current_target) { if (target != current_target) {
@ -714,21 +684,19 @@ void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_eve
if (event->data.data32[1] & 1) { if (event->data.data32[1] & 1) {
// get the types from XdndTypeList // get the types from XdndTypeList
xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, xdnd_dragsource, auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, xdnd_dragsource,
atom(QXcbAtom::XdndTypelist), XCB_ATOM_ATOM, atom(QXcbAtom::XdndTypelist), XCB_ATOM_ATOM,
0, xdnd_max_type); 0, xdnd_max_type);
xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
if (reply && reply->type != XCB_NONE && reply->format == 32) { if (reply && reply->type != XCB_NONE && reply->format == 32) {
int length = xcb_get_property_value_length(reply) / 4; int length = xcb_get_property_value_length(reply.get()) / 4;
if (length > xdnd_max_type) if (length > xdnd_max_type)
length = xdnd_max_type; length = xdnd_max_type;
xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply); xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply.get());
xdnd_types.reserve(length); xdnd_types.reserve(length);
for (int i = 0; i < length; ++i) for (int i = 0; i < length; ++i)
xdnd_types.append(atoms[i]); xdnd_types.append(atoms[i]);
} }
free(reply);
} else { } else {
// get the types from the message // get the types from the message
for(int i = 2; i < 5; i++) { for(int i = 2; i < 5; i++) {
@ -1132,28 +1100,20 @@ static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window)
xcb_window_t target = 0; xcb_window_t target = 0;
forever { forever {
// check if window has XdndAware // check if window has XdndAware
xcb_get_property_cookie_t gpCookie = Q_XCB_CALL( auto gpReply = Q_XCB_REPLY(xcb_get_property, c->xcb_connection(), false, window,
xcb_get_property(c->xcb_connection(), false, window, c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0);
c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
xcb_get_property_reply_t *gpReply = xcb_get_property_reply(
c->xcb_connection(), gpCookie, 0);
bool aware = gpReply && gpReply->type != XCB_NONE; bool aware = gpReply && gpReply->type != XCB_NONE;
free(gpReply);
if (aware) { if (aware) {
target = window; target = window;
break; break;
} }
// try window's parent // try window's parent
xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL( auto qtReply = Q_XCB_REPLY_UNCHECKED(xcb_query_tree, c->xcb_connection(), window);
xcb_query_tree_unchecked(c->xcb_connection(), window));
xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply(
c->xcb_connection(), qtCookie, NULL);
if (!qtReply) if (!qtReply)
break; break;
xcb_window_t root = qtReply->root; xcb_window_t root = qtReply->root;
xcb_window_t parent = qtReply->parent; xcb_window_t parent = qtReply->parent;
free(qtReply);
if (window == root) if (window == root)
break; break;
window = parent; window = parent;

View File

@ -91,19 +91,14 @@ QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap
{ {
xcb_connection_t *conn = connection->xcb_connection(); xcb_connection_t *conn = connection->xcb_connection();
xcb_get_image_cookie_t get_image_cookie = auto image_reply = Q_XCB_REPLY_UNCHECKED(xcb_get_image, conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap,
xcb_get_image_unchecked(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap,
0, 0, width, height, 0xffffffff); 0, 0, width, height, 0xffffffff);
xcb_get_image_reply_t *image_reply =
xcb_get_image_reply(conn, get_image_cookie, NULL);
if (!image_reply) { if (!image_reply) {
return QPixmap(); return QPixmap();
} }
uint8_t *data = xcb_get_image_data(image_reply); uint8_t *data = xcb_get_image_data(image_reply.get());
uint32_t length = xcb_get_image_data_length(image_reply); uint32_t length = xcb_get_image_data_length(image_reply.get());
QPixmap result; QPixmap result;
@ -165,7 +160,6 @@ QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap
result = QPixmap::fromImage(image.copy()); result = QPixmap::fromImage(image.copy());
} }
free(image_reply);
return result; return result;
} }
@ -203,22 +197,15 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
xcb_connection_t *conn = screen->xcb_connection(); xcb_connection_t *conn = screen->xcb_connection();
const int w = image.width(); const int w = image.width();
const int h = image.height(); const int h = image.height();
xcb_generic_error_t *error = 0; auto formats = Q_XCB_REPLY(xcb_render_query_pict_formats, conn);
xcb_render_query_pict_formats_cookie_t formatsCookie = xcb_render_query_pict_formats(conn); if (!formats) {
xcb_render_query_pict_formats_reply_t *formatsReply = xcb_render_query_pict_formats_reply(conn,
formatsCookie,
&error);
if (!formatsReply || error) {
qWarning("qt_xcb_createCursorXRender: query_pict_formats failed"); qWarning("qt_xcb_createCursorXRender: query_pict_formats failed");
free(formatsReply);
free(error);
return XCB_NONE; return XCB_NONE;
} }
xcb_render_pictforminfo_t *fmt = xcb_render_util_find_standard_format(formatsReply, xcb_render_pictforminfo_t *fmt = xcb_render_util_find_standard_format(formats.get(),
XCB_PICT_STANDARD_ARGB_32); XCB_PICT_STANDARD_ARGB_32);
if (!fmt) { if (!fmt) {
qWarning("qt_xcb_createCursorXRender: Failed to find format PICT_STANDARD_ARGB_32"); qWarning("qt_xcb_createCursorXRender: Failed to find format PICT_STANDARD_ARGB_32");
free(formatsReply);
return XCB_NONE; return XCB_NONE;
} }
@ -230,14 +217,12 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
0, 0, 0); 0, 0, 0);
if (!xi) { if (!xi) {
qWarning("qt_xcb_createCursorXRender: xcb_image_create failed"); qWarning("qt_xcb_createCursorXRender: xcb_image_create failed");
free(formatsReply);
return XCB_NONE; return XCB_NONE;
} }
xi->data = (uint8_t *) malloc(xi->stride * h); xi->data = (uint8_t *) malloc(xi->stride * h);
if (!xi->data) { if (!xi->data) {
qWarning("qt_xcb_createCursorXRender: Failed to malloc() image data"); qWarning("qt_xcb_createCursorXRender: Failed to malloc() image data");
xcb_image_destroy(xi); xcb_image_destroy(xi);
free(formatsReply);
return XCB_NONE; return XCB_NONE;
} }
memcpy(xi->data, img.constBits(), img.byteCount()); memcpy(xi->data, img.constBits(), img.byteCount());
@ -260,7 +245,6 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
xcb_image_destroy(xi); xcb_image_destroy(xi);
xcb_render_free_picture(conn, pic); xcb_render_free_picture(conn, pic);
xcb_free_pixmap(conn, pix); xcb_free_pixmap(conn, pix);
free(formatsReply);
return cursor; return cursor;
#else #else

View File

@ -612,23 +612,18 @@ Qt::KeyboardModifiers QXcbKeyboard::translateModifiers(int s) const
void QXcbKeyboard::readXKBConfig() void QXcbKeyboard::readXKBConfig()
{ {
clearXKBConfig(); clearXKBConfig();
xcb_generic_error_t *error;
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *config_reply;
xcb_connection_t *c = xcb_connection(); xcb_connection_t *c = xcb_connection();
xcb_window_t rootWindow = connection()->rootWindow(); xcb_window_t rootWindow = connection()->rootWindow();
cookie = xcb_get_property(c, 0, rootWindow, auto config_reply = Q_XCB_REPLY(xcb_get_property, c, 0, rootWindow,
atom(QXcbAtom::_XKB_RULES_NAMES), XCB_ATOM_STRING, 0, 1024); atom(QXcbAtom::_XKB_RULES_NAMES), XCB_ATOM_STRING, 0, 1024);
config_reply = xcb_get_property_reply(c, cookie, &error);
if (!config_reply) { if (!config_reply) {
qWarning("Qt: Couldn't interpret the _XKB_RULES_NAMES property"); qWarning("Qt: Couldn't interpret the _XKB_RULES_NAMES property");
return; return;
} }
char *xkb_config = (char *)xcb_get_property_value(config_reply); char *xkb_config = (char *)xcb_get_property_value(config_reply.get());
int length = xcb_get_property_value_length(config_reply); int length = xcb_get_property_value_length(config_reply.get());
// on old X servers xkb_config can be 0 even if config_reply indicates a succesfull read // on old X servers xkb_config can be 0 even if config_reply indicates a succesfull read
if (!xkb_config || length == 0) if (!xkb_config || length == 0)
@ -653,8 +648,6 @@ void QXcbKeyboard::readXKBConfig()
xkb_names.layout = qstrdup(names[2]); xkb_names.layout = qstrdup(names[2]);
xkb_names.variant = qstrdup(names[3]); xkb_names.variant = qstrdup(names[3]);
xkb_names.options = qstrdup(names[4]); xkb_names.options = qstrdup(names[4]);
free(config_reply);
} }
void QXcbKeyboard::clearXKBConfig() void QXcbKeyboard::clearXKBConfig()
@ -1172,23 +1165,19 @@ QXcbKeyboard::~QXcbKeyboard()
void QXcbKeyboard::updateVModMapping() void QXcbKeyboard::updateVModMapping()
{ {
#if QT_CONFIG(xkb) #if QT_CONFIG(xkb)
xcb_xkb_get_names_cookie_t names_cookie;
xcb_xkb_get_names_reply_t *name_reply;
xcb_xkb_get_names_value_list_t names_list; xcb_xkb_get_names_value_list_t names_list;
memset(&vmod_masks, 0, sizeof(vmod_masks)); memset(&vmod_masks, 0, sizeof(vmod_masks));
names_cookie = xcb_xkb_get_names(xcb_connection(), auto name_reply = Q_XCB_REPLY(xcb_xkb_get_names, xcb_connection(),
XCB_XKB_ID_USE_CORE_KBD, XCB_XKB_ID_USE_CORE_KBD,
XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES); XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES);
name_reply = xcb_xkb_get_names_reply(xcb_connection(), names_cookie, 0);
if (!name_reply) { if (!name_reply) {
qWarning("Qt: failed to retrieve the virtual modifier names from XKB"); qWarning("Qt: failed to retrieve the virtual modifier names from XKB");
return; return;
} }
const void *buffer = xcb_xkb_get_names_value_list(name_reply); const void *buffer = xcb_xkb_get_names_value_list(name_reply.get());
xcb_xkb_get_names_value_list_unpack(buffer, xcb_xkb_get_names_value_list_unpack(buffer,
name_reply->nTypes, name_reply->nTypes,
name_reply->indicators, name_reply->indicators,
@ -1233,32 +1222,27 @@ void QXcbKeyboard::updateVModMapping()
else if (qstrcmp(vmod_name, "Hyper") == 0) else if (qstrcmp(vmod_name, "Hyper") == 0)
vmod_masks.hyper = bit; vmod_masks.hyper = bit;
} }
free(name_reply);
#endif #endif
} }
void QXcbKeyboard::updateVModToRModMapping() void QXcbKeyboard::updateVModToRModMapping()
{ {
#if QT_CONFIG(xkb) #if QT_CONFIG(xkb)
xcb_xkb_get_map_cookie_t map_cookie;
xcb_xkb_get_map_reply_t *map_reply;
xcb_xkb_get_map_map_t map; xcb_xkb_get_map_map_t map;
memset(&rmod_masks, 0, sizeof(rmod_masks)); memset(&rmod_masks, 0, sizeof(rmod_masks));
map_cookie = xcb_xkb_get_map(xcb_connection(), auto map_reply = Q_XCB_REPLY(xcb_xkb_get_map,
xcb_connection(),
XCB_XKB_ID_USE_CORE_KBD, XCB_XKB_ID_USE_CORE_KBD,
XCB_XKB_MAP_PART_VIRTUAL_MODS, XCB_XKB_MAP_PART_VIRTUAL_MODS,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
map_reply = xcb_xkb_get_map_reply(xcb_connection(), map_cookie, 0);
if (!map_reply) { if (!map_reply) {
qWarning("Qt: failed to retrieve the virtual modifier map from XKB"); qWarning("Qt: failed to retrieve the virtual modifier map from XKB");
return; return;
} }
const void *buffer = xcb_xkb_get_map_map(map_reply); const void *buffer = xcb_xkb_get_map_map(map_reply.get());
xcb_xkb_get_map_map_unpack(buffer, xcb_xkb_get_map_map_unpack(buffer,
map_reply->nTypes, map_reply->nTypes,
map_reply->nKeySyms, map_reply->nKeySyms,
@ -1301,7 +1285,6 @@ void QXcbKeyboard::updateVModToRModMapping()
rmod_masks.hyper = modmap; rmod_masks.hyper = modmap;
} }
free(map_reply);
resolveMaskConflicts(); resolveMaskConflicts();
#endif #endif
} }
@ -1315,14 +1298,10 @@ void QXcbKeyboard::updateModifiers()
// process for all modifiers whenever any part of the modifier mapping is changed. // process for all modifiers whenever any part of the modifier mapping is changed.
memset(&rmod_masks, 0, sizeof(rmod_masks)); memset(&rmod_masks, 0, sizeof(rmod_masks));
xcb_generic_error_t *error = 0;
xcb_connection_t *conn = xcb_connection(); xcb_connection_t *conn = xcb_connection();
xcb_get_modifier_mapping_cookie_t modMapCookie = xcb_get_modifier_mapping(conn); auto modMapReply = Q_XCB_REPLY(xcb_get_modifier_mapping, conn);
xcb_get_modifier_mapping_reply_t *modMapReply = if (!modMapReply) {
xcb_get_modifier_mapping_reply(conn, modMapCookie, &error);
if (error) {
qWarning("Qt: failed to get modifier mapping"); qWarning("Qt: failed to get modifier mapping");
free(error);
return; return;
} }
@ -1338,7 +1317,7 @@ void QXcbKeyboard::updateModifiers()
for (size_t i = 0; i < numSymbols; ++i) for (size_t i = 0; i < numSymbols; ++i)
modKeyCodes[i] = xcb_key_symbols_get_keycode(m_key_symbols, symbols[i]); modKeyCodes[i] = xcb_key_symbols_get_keycode(m_key_symbols, symbols[i]);
xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply); xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply.get());
const int w = modMapReply->keycodes_per_modifier; const int w = modMapReply->keycodes_per_modifier;
for (size_t i = 0; i < numSymbols; ++i) { for (size_t i = 0; i < numSymbols; ++i) {
for (int bit = 0; bit < 8; ++bit) { for (int bit = 0; bit < 8; ++bit) {
@ -1366,7 +1345,6 @@ void QXcbKeyboard::updateModifiers()
for (size_t i = 0; i < numSymbols; ++i) for (size_t i = 0; i < numSymbols; ++i)
free(modKeyCodes[i]); free(modKeyCodes[i]);
free(modMapReply);
resolveMaskConflicts(); resolveMaskConflicts();
} }

View File

@ -121,28 +121,19 @@ xcb_window_t QXcbNativeInterface::locateSystemTray(xcb_connection_t *conn, const
{ {
if (m_sysTraySelectionAtom == XCB_ATOM_NONE) { if (m_sysTraySelectionAtom == XCB_ATOM_NONE) {
const QByteArray net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen->screenNumber()).toLatin1(); const QByteArray net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen->screenNumber()).toLatin1();
xcb_intern_atom_cookie_t intern_c = auto intern_r = Q_XCB_REPLY_UNCHECKED(xcb_intern_atom, conn,
xcb_intern_atom_unchecked(conn, true, net_sys_tray.length(), net_sys_tray); true, net_sys_tray.length(), net_sys_tray);
xcb_intern_atom_reply_t *intern_r = xcb_intern_atom_reply(conn, intern_c, 0);
if (!intern_r) if (!intern_r)
return XCB_WINDOW_NONE; return XCB_WINDOW_NONE;
m_sysTraySelectionAtom = intern_r->atom; m_sysTraySelectionAtom = intern_r->atom;
free(intern_r);
} }
xcb_get_selection_owner_cookie_t sel_owner_c = xcb_get_selection_owner_unchecked(conn, m_sysTraySelectionAtom); auto sel_owner_r = Q_XCB_REPLY_UNCHECKED(xcb_get_selection_owner, conn, m_sysTraySelectionAtom);
xcb_get_selection_owner_reply_t *sel_owner_r = xcb_get_selection_owner_reply(conn, sel_owner_c, 0);
if (!sel_owner_r) if (!sel_owner_r)
return XCB_WINDOW_NONE; return XCB_WINDOW_NONE;
xcb_window_t selection_window = sel_owner_r->owner; return sel_owner_r->owner;
free(sel_owner_r);
return selection_window;
} }
bool QXcbNativeInterface::systrayVisualHasAlphaChannel() bool QXcbNativeInterface::systrayVisualHasAlphaChannel()
@ -457,21 +448,13 @@ void *QXcbNativeInterface::atspiBus()
QXcbConnection *defaultConnection = integration->defaultConnection(); QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection) { if (defaultConnection) {
xcb_atom_t atspiBusAtom = defaultConnection->internAtom("AT_SPI_BUS"); xcb_atom_t atspiBusAtom = defaultConnection->internAtom("AT_SPI_BUS");
xcb_get_property_cookie_t cookie = Q_XCB_CALL2(xcb_get_property( auto reply = Q_XCB_REPLY(xcb_get_property, defaultConnection->xcb_connection(),
defaultConnection->xcb_connection(),
false, defaultConnection->rootWindow(), false, defaultConnection->rootWindow(),
atspiBusAtom, XCB_ATOM_STRING, 0, 128), atspiBusAtom, XCB_ATOM_STRING, 0, 128);
defaultConnection);
xcb_get_property_reply_t *reply = Q_XCB_CALL2(xcb_get_property_reply(
defaultConnection->xcb_connection(),
cookie, 0),
defaultConnection);
Q_ASSERT(!reply->bytes_after); Q_ASSERT(!reply->bytes_after);
char *data = (char *)xcb_get_property_value(reply); char *data = (char *)xcb_get_property_value(reply.get());
int length = xcb_get_property_value_length(reply); int length = xcb_get_property_value_length(reply.get());
QByteArray *busAddress = new QByteArray(data, length); return new QByteArray(data, length);
free(reply);
return busAddress;
} }
return 0; return 0;
} }

View File

@ -130,11 +130,9 @@ void QXcbVirtualDesktop::subscribeToXFixesSelectionNotify()
QRect QXcbVirtualDesktop::getWorkArea() const QRect QXcbVirtualDesktop::getWorkArea() const
{ {
QRect r; QRect r;
xcb_get_property_reply_t * workArea = auto workArea = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), false, screen()->root,
xcb_get_property_reply(xcb_connection(),
xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
atom(QXcbAtom::_NET_WORKAREA), atom(QXcbAtom::_NET_WORKAREA),
XCB_ATOM_CARDINAL, 0, 1024), NULL); XCB_ATOM_CARDINAL, 0, 1024);
if (workArea && workArea->type == XCB_ATOM_CARDINAL && workArea->format == 32 && workArea->value_len >= 4) { if (workArea && workArea->type == XCB_ATOM_CARDINAL && workArea->format == 32 && workArea->value_len >= 4) {
// If workArea->value_len > 4, the remaining ones seem to be for WM's virtual desktops // If workArea->value_len > 4, the remaining ones seem to be for WM's virtual desktops
// (don't mess with QXcbVirtualDesktop which represents an X screen). // (don't mess with QXcbVirtualDesktop which represents an X screen).
@ -142,12 +140,11 @@ QRect QXcbVirtualDesktop::getWorkArea() const
// "docked" panel (with _NET_WM_STRUT_PARTIAL atom set) on just one desktop. // "docked" panel (with _NET_WM_STRUT_PARTIAL atom set) on just one desktop.
// But for now just assume the first 4 values give us the geometry of the // But for now just assume the first 4 values give us the geometry of the
// "work area", AKA "available geometry" // "work area", AKA "available geometry"
uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea); uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea.get());
r = QRect(geom[0], geom[1], geom[2], geom[3]); r = QRect(geom[0], geom[1], geom[2], geom[3]);
} else { } else {
r = QRect(QPoint(), size()); r = QRect(QPoint(), size());
} }
free(workArea);
return r; return r;
} }
@ -181,14 +178,11 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
{ {
if (connection->hasXRandr()) { if (connection->hasXRandr()) {
xcb_randr_select_input(xcb_connection(), screen()->root, true); xcb_randr_select_input(xcb_connection(), screen()->root, true);
xcb_randr_get_crtc_info_cookie_t crtcCookie = auto crtc = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_crtc_info, xcb_connection(),
xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, output ? output->timestamp : 0); m_crtc, output ? output->timestamp : 0);
xcb_randr_get_crtc_info_reply_t *crtc =
xcb_randr_get_crtc_info_reply(xcb_connection(), crtcCookie, NULL);
if (crtc) { if (crtc) {
updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation); updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation);
updateRefreshRate(crtc->mode); updateRefreshRate(crtc->mode);
free(crtc);
} }
} else if (xineramaScreenInfo) { } else if (xineramaScreenInfo) {
m_geometry = QRect(xineramaScreenInfo->x_org, xineramaScreenInfo->y_org, m_geometry = QRect(xineramaScreenInfo->x_org, xineramaScreenInfo->y_org,
@ -210,10 +204,9 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
readXResources(); readXResources();
QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> rootAttribs( auto rootAttribs = Q_XCB_REPLY_UNCHECKED(xcb_get_window_attributes, xcb_connection(),
xcb_get_window_attributes_reply(xcb_connection(), screen()->root);
xcb_get_window_attributes_unchecked(xcb_connection(), screen()->root), NULL)); const quint32 existingEventMask = !rootAttribs ? 0 : rootAttribs->your_event_mask;
const quint32 existingEventMask = rootAttribs.isNull() ? 0 : rootAttribs->your_event_mask;
const quint32 mask = XCB_CW_EVENT_MASK; const quint32 mask = XCB_CW_EVENT_MASK;
const quint32 values[] = { const quint32 values[] = {
@ -227,29 +220,24 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
xcb_change_window_attributes(xcb_connection(), screen()->root, mask, values); xcb_change_window_attributes(xcb_connection(), screen()->root, mask, values);
xcb_get_property_reply_t *reply = auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
xcb_get_property_reply(xcb_connection(), false, screen()->root,
xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK), atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK),
XCB_ATOM_WINDOW, 0, 1024), NULL); XCB_ATOM_WINDOW, 0, 1024);
if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) { if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) {
xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply)); xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply.get()));
if (windowManager != XCB_WINDOW_NONE) { if (windowManager != XCB_WINDOW_NONE) {
xcb_get_property_reply_t *windowManagerReply = auto windowManagerReply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
xcb_get_property_reply(xcb_connection(), false, windowManager,
xcb_get_property_unchecked(xcb_connection(), false, windowManager,
atom(QXcbAtom::_NET_WM_NAME), atom(QXcbAtom::_NET_WM_NAME),
atom(QXcbAtom::UTF8_STRING), 0, 1024), NULL); atom(QXcbAtom::UTF8_STRING), 0, 1024);
if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) { if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) {
m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply), xcb_get_property_value_length(windowManagerReply)); m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply.get()),
} xcb_get_property_value_length(windowManagerReply.get()));
}
free(windowManagerReply);
} }
} }
free(reply);
const xcb_query_extension_reply_t *sync_reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id); const xcb_query_extension_reply_t *sync_reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id);
if (!sync_reply || !sync_reply->present) if (!sync_reply || !sync_reply->present)
@ -311,12 +299,7 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
xcb_window_t child = root; xcb_window_t child = root;
do { do {
xcb_translate_coordinates_cookie_t translate_cookie = auto translate_reply = Q_XCB_REPLY_UNCHECKED(xcb_translate_coordinates, xcb_connection(), parent, child, x, y);
xcb_translate_coordinates_unchecked(xcb_connection(), parent, child, x, y);
xcb_translate_coordinates_reply_t *translate_reply =
xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, NULL);
if (!translate_reply) { if (!translate_reply) {
return 0; return 0;
} }
@ -326,8 +309,6 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
x = translate_reply->dst_x; x = translate_reply->dst_x;
y = translate_reply->dst_y; y = translate_reply->dst_y;
free(translate_reply);
if (!child || child == root) if (!child || child == root)
return 0; return 0;
@ -581,14 +562,10 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
if (!connection()->hasXRandr()) if (!connection()->hasXRandr())
return; return;
xcb_randr_get_crtc_info_cookie_t crtcCookie = auto crtc = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_crtc_info, xcb_connection(),
xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, timestamp); m_crtc, timestamp);
xcb_randr_get_crtc_info_reply_t *crtc = if (crtc)
xcb_randr_get_crtc_info_reply(xcb_connection(), crtcCookie, NULL);
if (crtc) {
updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation); updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation);
free(crtc);
}
} }
void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation) void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation)
@ -645,13 +622,11 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode)
// we can safely use get_screen_resources_current here, because in order to // we can safely use get_screen_resources_current here, because in order to
// get here, we must have called get_screen_resources before // get here, we must have called get_screen_resources before
xcb_randr_get_screen_resources_current_cookie_t resourcesCookie = auto resources = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_screen_resources_current,
xcb_randr_get_screen_resources_current_unchecked(xcb_connection(), screen()->root); xcb_connection(), screen()->root);
xcb_randr_get_screen_resources_current_reply_t *resources =
xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, NULL);
if (resources) { if (resources) {
xcb_randr_mode_info_iterator_t modesIter = xcb_randr_mode_info_iterator_t modesIter =
xcb_randr_get_screen_resources_current_modes_iterator(resources); xcb_randr_get_screen_resources_current_modes_iterator(resources.get());
for (; modesIter.rem; xcb_randr_mode_info_next(&modesIter)) { for (; modesIter.rem; xcb_randr_mode_info_next(&modesIter)) {
xcb_randr_mode_info_t *modeInfo = modesIter.data; xcb_randr_mode_info_t *modeInfo = modesIter.data;
if (modeInfo->id == mode) { if (modeInfo->id == mode) {
@ -662,29 +637,19 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode)
} }
} }
free(resources);
QWindowSystemInterface::handleScreenRefreshRateChange(QPlatformScreen::screen(), m_refreshRate); QWindowSystemInterface::handleScreenRefreshRateChange(QPlatformScreen::screen(), m_refreshRate);
} }
} }
static xcb_get_geometry_reply_t *getGeometryUnchecked(xcb_connection_t *connection, xcb_window_t window)
{
const xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry_unchecked(connection, window);
return xcb_get_geometry_reply(connection, geometry_cookie, NULL);
}
static inline bool translate(xcb_connection_t *connection, xcb_window_t child, xcb_window_t parent, static inline bool translate(xcb_connection_t *connection, xcb_window_t child, xcb_window_t parent,
int *x, int *y) int *x, int *y)
{ {
const xcb_translate_coordinates_cookie_t translate_cookie = auto translate_reply = Q_XCB_REPLY_UNCHECKED(xcb_translate_coordinates,
xcb_translate_coordinates_unchecked(connection, child, parent, *x, *y); connection, child, parent, *x, *y);
xcb_translate_coordinates_reply_t *translate_reply =
xcb_translate_coordinates_reply(connection, translate_cookie, NULL);
if (!translate_reply) if (!translate_reply)
return false; return false;
*x = translate_reply->dst_x; *x = translate_reply->dst_x;
*y = translate_reply->dst_y; *y = translate_reply->dst_y;
free(translate_reply);
return true; return true;
} }
@ -698,22 +663,20 @@ QPixmap QXcbScreen::grabWindow(WId window, int xIn, int yIn, int width, int heig
QXcbScreen *screen = const_cast<QXcbScreen *>(this); QXcbScreen *screen = const_cast<QXcbScreen *>(this);
xcb_window_t root = screen->root(); xcb_window_t root = screen->root();
xcb_get_geometry_reply_t *rootReply = getGeometryUnchecked(xcb_connection(), root); auto rootReply = Q_XCB_REPLY_UNCHECKED(xcb_get_geometry, xcb_connection(), root);
if (!rootReply) if (!rootReply)
return QPixmap(); return QPixmap();
const quint8 rootDepth = rootReply->depth; const quint8 rootDepth = rootReply->depth;
free(rootReply);
QSize windowSize; QSize windowSize;
quint8 effectiveDepth = 0; quint8 effectiveDepth = 0;
if (window) { if (window) {
xcb_get_geometry_reply_t *windowReply = getGeometryUnchecked(xcb_connection(), window); auto windowReply = Q_XCB_REPLY_UNCHECKED(xcb_get_geometry, xcb_connection(), window);
if (!windowReply) if (!windowReply)
return QPixmap(); return QPixmap();
windowSize = QSize(windowReply->width, windowReply->height); windowSize = QSize(windowReply->width, windowReply->height);
effectiveDepth = windowReply->depth; effectiveDepth = windowReply->depth;
free(windowReply);
if (effectiveDepth == rootDepth) { if (effectiveDepth == rootDepth) {
// if the depth of the specified window and the root window are the // if the depth of the specified window and the root window are the
// same, grab pixels from the root window (so that we get the any // same, grab pixels from the root window (so that we get the any
@ -738,14 +701,12 @@ QPixmap QXcbScreen::grabWindow(WId window, int xIn, int yIn, int width, int heig
if (height < 0) if (height < 0)
height = windowSize.height() - yIn; height = windowSize.height() - yIn;
xcb_get_window_attributes_reply_t *attributes_reply = auto attributes_reply = Q_XCB_REPLY_UNCHECKED(xcb_get_window_attributes, xcb_connection(), window);
xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes_unchecked(xcb_connection(), window), NULL);
if (!attributes_reply) if (!attributes_reply)
return QPixmap(); return QPixmap();
const xcb_visualtype_t *visual = screen->visualForId(attributes_reply->visual); const xcb_visualtype_t *visual = screen->visualForId(attributes_reply->visual);
free(attributes_reply);
xcb_pixmap_t pixmap = xcb_generate_id(xcb_connection()); xcb_pixmap_t pixmap = xcb_generate_id(xcb_connection());
xcb_create_pixmap(xcb_connection(), effectiveDepth, pixmap, window, width, height); xcb_create_pixmap(xcb_connection(), effectiveDepth, pixmap, window, width, height);
@ -819,21 +780,17 @@ void QXcbScreen::readXResources()
int offset = 0; int offset = 0;
QByteArray resources; QByteArray resources;
while(1) { while(1) {
xcb_get_property_reply_t *reply = auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
xcb_get_property_reply(xcb_connection(), false, screen()->root,
xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
XCB_ATOM_RESOURCE_MANAGER, XCB_ATOM_RESOURCE_MANAGER,
XCB_ATOM_STRING, offset/4, 8192), NULL); XCB_ATOM_STRING, offset/4, 8192);
bool more = false; bool more = false;
if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) { if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) {
resources += QByteArray((const char *)xcb_get_property_value(reply), xcb_get_property_value_length(reply)); resources += QByteArray((const char *)xcb_get_property_value(reply.get()), xcb_get_property_value_length(reply.get()));
offset += xcb_get_property_value_length(reply); offset += xcb_get_property_value_length(reply.get());
more = reply->bytes_after != 0; more = reply->bytes_after != 0;
} }
if (reply)
free(reply);
if (!more) if (!more)
break; break;
} }

View File

@ -85,13 +85,10 @@ QXcbSystemTrayTracker::QXcbSystemTrayTracker(QXcbConnection *connection,
xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection) xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection)
{ {
xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(connection->xcb_connection(), selection); auto reply = Q_XCB_REPLY(xcb_get_selection_owner, connection->xcb_connection(), selection);
xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(connection->xcb_connection(), cookie, 0);
if (!reply) if (!reply)
return 0; return 0;
const xcb_window_t result = reply->owner; return reply->owner;
free(reply);
return result;
} }
// API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Request a window // API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Request a window
@ -130,23 +127,16 @@ xcb_window_t QXcbSystemTrayTracker::trayWindow()
// does not work for the QWindow parented on the tray. // does not work for the QWindow parented on the tray.
QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window) const QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window) const
{ {
xcb_connection_t *conn = m_connection->xcb_connection(); xcb_connection_t *conn = m_connection->xcb_connection();
xcb_get_geometry_reply_t *geomReply = auto geomReply = Q_XCB_REPLY(xcb_get_geometry, conn, window);
xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), 0);
if (!geomReply) if (!geomReply)
return QRect(); return QRect();
xcb_translate_coordinates_reply_t *translateReply = auto translateReply = Q_XCB_REPLY(xcb_translate_coordinates, conn, window, m_connection->rootWindow(), 0, 0);
xcb_translate_coordinates_reply(conn, xcb_translate_coordinates(conn, window, m_connection->rootWindow(), 0, 0), 0); if (!translateReply)
if (!translateReply) {
free(geomReply);
return QRect(); return QRect();
}
const QRect result(QPoint(translateReply->dst_x, translateReply->dst_y), QSize(geomReply->width, geomReply->height)); return QRect(QPoint(translateReply->dst_x, translateReply->dst_y), QSize(geomReply->width, geomReply->height));
free(translateReply);
return result;
} }
inline void QXcbSystemTrayTracker::emitSystemTrayWindowChanged() inline void QXcbSystemTrayTracker::emitSystemTrayWindowChanged()
@ -180,24 +170,18 @@ bool QXcbSystemTrayTracker::visualHasAlphaChannel()
xcb_atom_t tray_atom = m_connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL); xcb_atom_t tray_atom = m_connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL);
// Get the xcb property for the _NET_SYSTEM_TRAY_VISUAL atom // Get the xcb property for the _NET_SYSTEM_TRAY_VISUAL atom
xcb_get_property_cookie_t systray_atom_cookie; auto systray_atom_reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, m_connection->xcb_connection(),
xcb_get_property_reply_t *systray_atom_reply; false, m_trayWindow,
systray_atom_cookie = xcb_get_property_unchecked(m_connection->xcb_connection(), false, m_trayWindow,
tray_atom, XCB_ATOM_VISUALID, 0, 1); tray_atom, XCB_ATOM_VISUALID, 0, 1);
systray_atom_reply = xcb_get_property_reply(m_connection->xcb_connection(), systray_atom_cookie, 0);
if (!systray_atom_reply) if (!systray_atom_reply)
return false; return false;
xcb_visualid_t systrayVisualId = XCB_NONE; xcb_visualid_t systrayVisualId = XCB_NONE;
if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply) > 0) { if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply.get()) > 0) {
xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply); xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply.get());
systrayVisualId = vids[0]; systrayVisualId = vids[0];
} }
free(systray_atom_reply);
if (systrayVisualId != XCB_NONE) { if (systrayVisualId != XCB_NONE) {
quint8 depth = m_connection->primaryScreen()->depthOfVisual(systrayVisualId); quint8 depth = m_connection->primaryScreen()->depthOfVisual(systrayVisualId);
return depth == 32; return depth == 32;

View File

@ -673,12 +673,10 @@ QMargins QXcbWindow::frameMargins() const
{ {
if (m_dirtyFrameMargins) { if (m_dirtyFrameMargins) {
if (connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_FRAME_EXTENTS))) { if (connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_FRAME_EXTENTS))) {
xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, m_window, auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, m_window,
atom(QXcbAtom::_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4); atom(QXcbAtom::_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4);
QScopedPointer<xcb_get_property_reply_t, QScopedPointerPodDeleter> reply(
xcb_get_property_reply(xcb_connection(), cookie, NULL));
if (reply && reply->type == XCB_ATOM_CARDINAL && reply->format == 32 && reply->value_len == 4) { if (reply && reply->type == XCB_ATOM_CARDINAL && reply->format == 32 && reply->value_len == 4) {
quint32 *data = (quint32 *)xcb_get_property_value(reply.data()); quint32 *data = (quint32 *)xcb_get_property_value(reply.get());
// _NET_FRAME_EXTENTS format is left, right, top, bottom // _NET_FRAME_EXTENTS format is left, right, top, bottom
m_frameMargins = QMargins(data[0], data[2], data[1], data[3]); m_frameMargins = QMargins(data[0], data[2], data[1], data[3]);
m_dirtyFrameMargins = false; m_dirtyFrameMargins = false;
@ -697,9 +695,7 @@ QMargins QXcbWindow::frameMargins() const
connection()->wmSupport()->virtualRoots(); connection()->wmSupport()->virtualRoots();
while (!foundRoot) { while (!foundRoot) {
xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked(xcb_connection(), parent); auto reply = Q_XCB_REPLY_UNCHECKED(xcb_query_tree, xcb_connection(), parent);
xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, NULL);
if (reply) { if (reply) {
if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1 || reply->parent == XCB_WINDOW_NONE) { if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1 || reply->parent == XCB_WINDOW_NONE) {
foundRoot = true; foundRoot = true;
@ -707,8 +703,6 @@ QMargins QXcbWindow::frameMargins() const
window = parent; window = parent;
parent = reply->parent; parent = reply->parent;
} }
free(reply);
} else { } else {
m_dirtyFrameMargins = false; m_dirtyFrameMargins = false;
m_frameMargins = QMargins(); m_frameMargins = QMargins();
@ -718,23 +712,12 @@ QMargins QXcbWindow::frameMargins() const
QPoint offset; QPoint offset;
xcb_translate_coordinates_reply_t *reply = auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(), window, parent, 0, 0);
xcb_translate_coordinates_reply(
xcb_connection(),
xcb_translate_coordinates(xcb_connection(), window, parent, 0, 0),
NULL);
if (reply) { if (reply) {
offset = QPoint(reply->dst_x, reply->dst_y); offset = QPoint(reply->dst_x, reply->dst_y);
free(reply);
} }
xcb_get_geometry_reply_t *geom = auto geom = Q_XCB_REPLY(xcb_get_geometry, xcb_connection(), parent);
xcb_get_geometry_reply(
xcb_connection(),
xcb_get_geometry(xcb_connection(), parent),
NULL);
if (geom) { if (geom) {
// -- // --
// add the border_width for the window managers frame... some window managers // add the border_width for the window managers frame... some window managers
@ -751,8 +734,6 @@ QMargins QXcbWindow::frameMargins() const
int bottom = geom->height + geom->border_width - geometry().height() - offset.y(); int bottom = geom->height + geom->border_width - geometry().height() - offset.y();
m_frameMargins = QMargins(left, top, right, bottom); m_frameMargins = QMargins(left, top, right, bottom);
free(geom);
} }
m_dirtyFrameMargins = false; m_dirtyFrameMargins = false;
@ -779,6 +760,7 @@ static inline bool testShowWithoutActivating(const QWindow *window)
void QXcbWindow::show() void QXcbWindow::show()
{ {
if (window()->isTopLevel()) { if (window()->isTopLevel()) {
xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window);
xcb_wm_hints_t hints; xcb_wm_hints_t hints;
@ -1006,15 +988,11 @@ static QtMotifWmHints getMotifWmHints(QXcbConnection *c, xcb_window_t window)
{ {
QtMotifWmHints hints; QtMotifWmHints hints;
xcb_get_property_cookie_t get_cookie = auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, c->xcb_connection(), 0, window,
xcb_get_property_unchecked(c->xcb_connection(), 0, window, c->atom(QXcbAtom::_MOTIF_WM_HINTS), c->atom(QXcbAtom::_MOTIF_WM_HINTS), c->atom(QXcbAtom::_MOTIF_WM_HINTS), 0, 20);
c->atom(QXcbAtom::_MOTIF_WM_HINTS), 0, 20);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(c->xcb_connection(), get_cookie, NULL);
if (reply && reply->format == 32 && reply->type == c->atom(QXcbAtom::_MOTIF_WM_HINTS)) { if (reply && reply->format == 32 && reply->type == c->atom(QXcbAtom::_MOTIF_WM_HINTS)) {
hints = *((QtMotifWmHints *)xcb_get_property_value(reply)); hints = *((QtMotifWmHints *)xcb_get_property_value(reply.get()));
} else { } else {
hints.flags = 0L; hints.flags = 0L;
hints.functions = MWM_FUNC_ALL; hints.functions = MWM_FUNC_ALL;
@ -1023,8 +1001,6 @@ static QtMotifWmHints getMotifWmHints(QXcbConnection *c, xcb_window_t window)
hints.status = 0L; hints.status = 0L;
} }
free(reply);
return hints; return hints;
} }
@ -1048,15 +1024,12 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
{ {
NetWmStates result(0); NetWmStates result(0);
xcb_get_property_cookie_t get_cookie = auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
XCB_ATOM_ATOM, 0, 1024); XCB_ATOM_ATOM, 0, 1024);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) { if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) {
const xcb_atom_t *states = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply)); const xcb_atom_t *states = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get()));
const xcb_atom_t *statesEnd = states + reply->length; const xcb_atom_t *statesEnd = states + reply->length;
if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_ABOVE))) if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_ABOVE)))
result |= NetWmStateAbove; result |= NetWmStateAbove;
@ -1074,7 +1047,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
result |= NetWmStateStaysOnTop; result |= NetWmStateStaysOnTop;
if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION))) if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)))
result |= NetWmStateDemandsAttention; result |= NetWmStateDemandsAttention;
free(reply);
} else { } else {
#ifdef NET_WM_STATE_DEBUG #ifdef NET_WM_STATE_DEBUG
printf("getting net wm state (%x), empty\n", m_window); printf("getting net wm state (%x), empty\n", m_window);
@ -1088,21 +1060,15 @@ void QXcbWindow::setNetWmStates(NetWmStates states)
{ {
QVector<xcb_atom_t> atoms; QVector<xcb_atom_t> atoms;
xcb_get_property_cookie_t get_cookie = auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
XCB_ATOM_ATOM, 0, 1024); XCB_ATOM_ATOM, 0, 1024);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) { if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) {
const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply)); const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get()));
atoms.resize(reply->value_len); atoms.resize(reply->value_len);
memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t)); memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t));
} }
free(reply);
if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE))) if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE)); atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE));
if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW))) if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW)))
@ -1743,15 +1709,11 @@ QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const
{ {
QXcbWindowFunctions::WmWindowTypes result(0); QXcbWindowFunctions::WmWindowTypes result(0);
xcb_get_property_cookie_t get_cookie = auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_WINDOW_TYPE), 0, m_window, atom(QXcbAtom::_NET_WM_WINDOW_TYPE),
XCB_ATOM_ATOM, 0, 1024); XCB_ATOM_ATOM, 0, 1024);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) { if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) {
const xcb_atom_t *types = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply)); const xcb_atom_t *types = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get()));
const xcb_atom_t *types_end = types + reply->length; const xcb_atom_t *types_end = types + reply->length;
for (; types != types_end; types++) { for (; types != types_end; types++) {
QXcbAtom::Atom type = connection()->qatom(*types); QXcbAtom::Atom type = connection()->qatom(*types);
@ -1805,7 +1767,6 @@ QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const
break; break;
} }
} }
free(reply);
} }
return result; return result;
} }
@ -2091,13 +2052,11 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
QPoint pos(event->x, event->y); QPoint pos(event->x, event->y);
if (!parent() && !fromSendEvent) { if (!parent() && !fromSendEvent) {
// Do not trust the position, query it instead. // Do not trust the position, query it instead.
xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(), auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
xcbScreen()->root(), 0, 0); xcb_window(), xcbScreen()->root(), 0, 0);
xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) { if (reply) {
pos.setX(reply->dst_x); pos.setX(reply->dst_x);
pos.setY(reply->dst_y); pos.setY(reply->dst_y);
free(reply);
} }
} }
@ -2152,15 +2111,12 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
return pos; return pos;
QPoint ret; QPoint ret;
xcb_translate_coordinates_cookie_t cookie = auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
xcb_translate_coordinates(xcb_connection(), xcb_window(), xcbScreen()->root(), xcb_window(), xcbScreen()->root(),
pos.x(), pos.y()); pos.x(), pos.y());
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) { if (reply) {
ret.setX(reply->dst_x); ret.setX(reply->dst_x);
ret.setY(reply->dst_y); ret.setY(reply->dst_y);
free(reply);
} }
return ret; return ret;
@ -2172,15 +2128,12 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const
return pos; return pos;
QPoint ret; QPoint ret;
xcb_translate_coordinates_cookie_t cookie = auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
xcb_translate_coordinates(xcb_connection(), xcbScreen()->root(), xcb_window(), xcbScreen()->root(), xcb_window(),
pos.x(), pos.y()); pos.x(), pos.y());
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) { if (reply) {
ret.setX(reply->dst_x); ret.setX(reply->dst_x);
ret.setY(reply->dst_y); ret.setY(reply->dst_y);
free(reply);
} }
return ret; return ret;
@ -2533,15 +2486,11 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
Qt::WindowState newState = Qt::WindowNoState; Qt::WindowState newState = Qt::WindowNoState;
if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'. if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
const xcb_get_property_cookie_t get_cookie = auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::WM_STATE), 0, m_window, atom(QXcbAtom::WM_STATE),
XCB_ATOM_ANY, 0, 1024); XCB_ATOM_ANY, 0, 1024);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) { if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
const quint32 *data = (const quint32 *)xcb_get_property_value(reply); const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get());
if (reply->length != 0) { if (reply->length != 0) {
if (data[0] == XCB_WM_STATE_ICONIC if (data[0] == XCB_WM_STATE_ICONIC
|| (data[0] == XCB_WM_STATE_WITHDRAWN || (data[0] == XCB_WM_STATE_WITHDRAWN
@ -2550,7 +2499,6 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
} }
} }
} }
free(reply);
} else { // _NET_WM_STATE can't change minimized state } else { // _NET_WM_STATE can't change minimized state
if (m_lastWindowStateEvent == Qt::WindowMinimized) if (m_lastWindowStateEvent == Qt::WindowMinimized)
newState = Qt::WindowMinimized; newState = Qt::WindowMinimized;
@ -2627,13 +2575,11 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab)
xcb_ungrab_keyboard(xcb_connection(), XCB_TIME_CURRENT_TIME); xcb_ungrab_keyboard(xcb_connection(), XCB_TIME_CURRENT_TIME);
return true; return true;
} }
xcb_grab_keyboard_cookie_t cookie = xcb_grab_keyboard(xcb_connection(), false,
auto reply = Q_XCB_REPLY(xcb_grab_keyboard, xcb_connection(), false,
m_window, XCB_TIME_CURRENT_TIME, m_window, XCB_TIME_CURRENT_TIME,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
xcb_grab_keyboard_reply_t *reply = xcb_grab_keyboard_reply(xcb_connection(), cookie, NULL); return reply && reply->status == XCB_GRAB_STATUS_SUCCESS;
bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS);
free(reply);
return result;
} }
bool QXcbWindow::setMouseGrabEnabled(bool grab) bool QXcbWindow::setMouseGrabEnabled(bool grab)
@ -2655,16 +2601,16 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME); xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME);
return true; return true;
} }
xcb_grab_pointer_cookie_t cookie = xcb_grab_pointer(xcb_connection(), false, m_window,
auto reply = Q_XCB_REPLY(xcb_grab_pointer, xcb_connection(),
false, m_window,
(XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE (XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE
| XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW
| XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_POINTER_MOTION), | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_POINTER_MOTION),
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
XCB_WINDOW_NONE, XCB_CURSOR_NONE, XCB_WINDOW_NONE, XCB_CURSOR_NONE,
XCB_TIME_CURRENT_TIME); XCB_TIME_CURRENT_TIME);
xcb_grab_pointer_reply_t *reply = xcb_grab_pointer_reply(xcb_connection(), cookie, NULL); bool result = reply && reply->status == XCB_GRAB_STATUS_SUCCESS;
bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS);
free(reply);
if (result) if (result)
connection()->setMouseGrabber(this); connection()->setMouseGrabber(this);
return result; return result;

View File

@ -66,16 +66,15 @@ void QXcbWMSupport::updateNetWMAtoms()
int offset = 0; int offset = 0;
int remaining = 0; int remaining = 0;
do { do {
xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_SUPPORTED), XCB_ATOM_ATOM, offset, 1024); auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, root, atom(QXcbAtom::_NET_SUPPORTED), XCB_ATOM_ATOM, offset, 1024);
xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, NULL);
if (!reply) if (!reply)
break; break;
remaining = 0; remaining = 0;
if (reply->type == XCB_ATOM_ATOM && reply->format == 32) { if (reply->type == XCB_ATOM_ATOM && reply->format == 32) {
int len = xcb_get_property_value_length(reply)/sizeof(xcb_atom_t); int len = xcb_get_property_value_length(reply.get())/sizeof(xcb_atom_t);
xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply); xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply.get());
int s = net_wm_atoms.size(); int s = net_wm_atoms.size();
net_wm_atoms.resize(s + len); net_wm_atoms.resize(s + len);
memcpy(net_wm_atoms.data() + s, atoms, len*sizeof(xcb_atom_t)); memcpy(net_wm_atoms.data() + s, atoms, len*sizeof(xcb_atom_t));
@ -83,8 +82,6 @@ void QXcbWMSupport::updateNetWMAtoms()
remaining = reply->bytes_after; remaining = reply->bytes_after;
offset += len; offset += len;
} }
free(reply);
} while (remaining > 0); } while (remaining > 0);
} }
@ -100,16 +97,16 @@ void QXcbWMSupport::updateVirtualRoots()
int offset = 0; int offset = 0;
int remaining = 0; int remaining = 0;
do { do {
xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_VIRTUAL_ROOTS), XCB_ATOM_WINDOW, offset, 1024); auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, NULL); false, root, atom(QXcbAtom::_NET_VIRTUAL_ROOTS), XCB_ATOM_WINDOW, offset, 1024);
if (!reply) if (!reply)
break; break;
remaining = 0; remaining = 0;
if (reply->type == XCB_ATOM_WINDOW && reply->format == 32) { if (reply->type == XCB_ATOM_WINDOW && reply->format == 32) {
int len = xcb_get_property_value_length(reply)/sizeof(xcb_window_t); int len = xcb_get_property_value_length(reply.get())/sizeof(xcb_window_t);
xcb_window_t *roots = (xcb_window_t *)xcb_get_property_value(reply); xcb_window_t *roots = (xcb_window_t *)xcb_get_property_value(reply.get());
int s = net_virtual_roots.size(); int s = net_virtual_roots.size();
net_virtual_roots.resize(s + len); net_virtual_roots.resize(s + len);
memcpy(net_virtual_roots.data() + s, roots, len*sizeof(xcb_window_t)); memcpy(net_virtual_roots.data() + s, roots, len*sizeof(xcb_window_t));
@ -118,7 +115,6 @@ void QXcbWMSupport::updateVirtualRoots()
offset += len; offset += len;
} }
free(reply);
} while (remaining > 0); } while (remaining > 0);
#ifdef Q_XCB_DEBUG #ifdef Q_XCB_DEBUG

View File

@ -106,26 +106,23 @@ public:
QByteArray settings; QByteArray settings;
xcb_atom_t _xsettings_atom = screen->connection()->atom(QXcbAtom::_XSETTINGS_SETTINGS); xcb_atom_t _xsettings_atom = screen->connection()->atom(QXcbAtom::_XSETTINGS_SETTINGS);
while (1) { while (1) {
xcb_get_property_cookie_t get_prop_cookie = auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property,
xcb_get_property_unchecked(screen->xcb_connection(), screen->xcb_connection(),
false, false,
x_settings_window, x_settings_window,
_xsettings_atom, _xsettings_atom,
_xsettings_atom, _xsettings_atom,
offset/4, offset/4,
8192); 8192);
xcb_get_property_reply_t *reply = xcb_get_property_reply(screen->xcb_connection(), get_prop_cookie, NULL);
bool more = false; bool more = false;
if (!reply) if (!reply)
return settings; return settings;
const auto property_value_length = xcb_get_property_value_length(reply); const auto property_value_length = xcb_get_property_value_length(reply.get());
settings.append(static_cast<const char *>(xcb_get_property_value(reply)), property_value_length); settings.append(static_cast<const char *>(xcb_get_property_value(reply.get())), property_value_length);
offset += property_value_length; offset += property_value_length;
more = reply->bytes_after != 0; more = reply->bytes_after != 0;
free(reply);
if (!more) if (!more)
break; break;
} }
@ -228,34 +225,24 @@ QXcbXSettings::QXcbXSettings(QXcbVirtualDesktop *screen)
{ {
QByteArray settings_atom_for_screen("_XSETTINGS_S"); QByteArray settings_atom_for_screen("_XSETTINGS_S");
settings_atom_for_screen.append(QByteArray::number(screen->number())); settings_atom_for_screen.append(QByteArray::number(screen->number()));
xcb_intern_atom_cookie_t atom_cookie = xcb_intern_atom(screen->xcb_connection(), auto atom_reply = Q_XCB_REPLY(xcb_intern_atom,
screen->xcb_connection(),
true, true,
settings_atom_for_screen.length(), settings_atom_for_screen.length(),
settings_atom_for_screen.constData()); settings_atom_for_screen.constData());
xcb_generic_error_t *error = 0; if (!atom_reply)
xcb_intern_atom_reply_t *atom_reply = xcb_intern_atom_reply(screen->xcb_connection(),atom_cookie,&error);
if (error) {
free(error);
return; return;
}
xcb_atom_t selection_owner_atom = atom_reply->atom; xcb_atom_t selection_owner_atom = atom_reply->atom;
free(atom_reply);
xcb_get_selection_owner_cookie_t selection_cookie = auto selection_result = Q_XCB_REPLY(xcb_get_selection_owner,
xcb_get_selection_owner(screen->xcb_connection(), selection_owner_atom); screen->xcb_connection(), selection_owner_atom);
if (!selection_result)
xcb_get_selection_owner_reply_t *selection_result =
xcb_get_selection_owner_reply(screen->xcb_connection(), selection_cookie, &error);
if (error) {
free(error);
return; return;
}
d_ptr->x_settings_window = selection_result->owner; d_ptr->x_settings_window = selection_result->owner;
free(selection_result); if (!d_ptr->x_settings_window)
if (!d_ptr->x_settings_window) {
return; return;
}
const uint32_t event = XCB_CW_EVENT_MASK; const uint32_t event = XCB_CW_EVENT_MASK;
const uint32_t event_mask[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY|XCB_EVENT_MASK_PROPERTY_CHANGE }; const uint32_t event_mask[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY|XCB_EVENT_MASK_PROPERTY_CHANGE };