Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:Update
libqt5-qtbase.16533
0001-xcb-prevent-crash-with-pixmap-cursors-on-X...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-xcb-prevent-crash-with-pixmap-cursors-on-XRender-less-system.patch of Package libqt5-qtbase.16533
From: Max Lin <mlin@suse.com> Date: Tue, 25 Sep 2018 15:50:31 +0800 Subject: [PATCH] xcb: prevent crash with pixmap cursors on XRender-less X servers This is a backport of 6c10c54aa805f79100a29b0648be51d8af41f26a and d5ac11891d8237ca2f02390ffd0ff103578b520e. We were using xcb_render_* APIs without checking if the server even supports this extension. Attempting to use an extension which is not present will always result in a crash. This patch adds the required guards and refactors how we detect presence of XRender extension. Also instead of falling back to some odd-looking bitmapped version just leave the current cursor unchanged. That is how we did it in Qt4 AFAICT. Task-number: QTBUG-66935 --- src/plugins/platforms/xcb/qxcbconnection.cpp | 11 ++++++++--- src/plugins/platforms/xcb/qxcbconnection.h | 10 +++++++++- src/plugins/platforms/xcb/qxcbcursor.cpp | 15 +++++++++++---- 3 files changed, 28 insertions(+), 8 deletions(-) Index: qtbase-opensource-src-5.9.7/src/plugins/platforms/xcb/qxcbconnection.cpp =================================================================== --- qtbase-opensource-src-5.9.7.orig/src/plugins/platforms/xcb/qxcbconnection.cpp +++ qtbase-opensource-src-5.9.7/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -556,6 +556,7 @@ QXcbConnection::QXcbConnection(QXcbNativ , m_defaultVisualId(defaultVisualId) , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) , m_nativeInterface(nativeInterface) + , has_render_extension(false) { #if QT_CONFIG(xcb_xlib) Display *dpy = XOpenDisplay(m_displayName.constData()); @@ -1223,7 +1224,7 @@ void QXcbConnection::handleXcbEvent(xcb_ } if (!handled) { - if (response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) { + if (has_xfixes && response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) { xcb_xfixes_selection_notify_event_t *notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event); setTime(notify_event->timestamp); #ifndef QT_NO_CLIPBOARD @@ -2059,7 +2060,6 @@ void QXcbConnection::initializeXFixes() if (!reply || !reply->present) return; - xfixes_first_event = reply->first_event; xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); @@ -2068,8 +2068,10 @@ void QXcbConnection::initializeXFixes() if (!xfixes_query || error || xfixes_query->major_version < 2) { qWarning("QXcbConnection: Failed to initialize XFixes"); free(error); - xfixes_first_event = 0; + return; } + xfixes_first_event = reply->first_event; + has_xfixes = true; free(xfixes_query); } @@ -2077,8 +2079,10 @@ void QXcbConnection::initializeXRender() { #if QT_CONFIG(xcb_render) const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_render_id); - if (!reply || !reply->present) + if (!reply || !reply->present) { + qDebug("XRender extension not present on the X server"); return; + } xcb_generic_error_t *error = 0; xcb_render_query_version_cookie_t xrender_query_cookie = xcb_render_query_version(m_connection, @@ -2086,10 +2090,14 @@ void QXcbConnection::initializeXRender() XCB_RENDER_MINOR_VERSION); xcb_render_query_version_reply_t *xrender_query = xcb_render_query_version_reply(m_connection, xrender_query_cookie, &error); - if (!xrender_query || error || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) { - qWarning("QXcbConnection: Failed to initialize XRender"); + if (!xrender_query) { + qWarning("xcb_render_query_version failed"); free(error); + return; } + has_render_extension = true; + m_xrenderVersion.first = xrender_query->major_version; + m_xrenderVersion.second = xrender_query->minor_version; free(xrender_query); #endif } Index: qtbase-opensource-src-5.9.7/src/plugins/platforms/xcb/qxcbconnection.h =================================================================== --- qtbase-opensource-src-5.9.7.orig/src/plugins/platforms/xcb/qxcbconnection.h +++ qtbase-opensource-src-5.9.7/src/plugins/platforms/xcb/qxcbconnection.h @@ -464,11 +464,18 @@ public: inline xcb_timestamp_t netWmUserTime() const { return m_netWmUserTime; } inline void setNetWmUserTime(xcb_timestamp_t t) { if (t > m_netWmUserTime) m_netWmUserTime = t; } - bool hasXFixes() const { return xfixes_first_event > 0; } + bool hasXFixes() const { return has_xfixes; } bool hasXShape() const { return has_shape_extension; } bool hasXRandr() const { return has_randr_extension; } bool hasInputShape() const { return has_input_shape; } bool hasXKB() const { return has_xkb; } + bool hasXRender(int major = -1, int minor = -1) const + { + if (has_render_extension && major != -1 && minor != -1) + return m_xrenderVersion >= qMakePair(major, minor); + + return has_render_extension; + } bool supportsThreadedRendering() const { return m_reader->isRunning(); } bool threadedEventHandling() const { return m_reader->isRunning(); } @@ -674,11 +681,15 @@ private: uint32_t xrandr_first_event = 0; uint32_t xkb_first_event = 0; + bool has_xfixes = false; bool has_xinerama_extension = false; bool has_shape_extension = false; bool has_randr_extension = false; bool has_input_shape; bool has_xkb = false; + bool has_render_extension = false; + + QPair<int, int> m_xrenderVersion; Qt::MouseButtons m_buttons = 0; Index: qtbase-opensource-src-5.9.7/src/plugins/platforms/xcb/qxcbcursor.cpp =================================================================== --- qtbase-opensource-src-5.9.7.orig/src/plugins/platforms/xcb/qxcbcursor.cpp +++ qtbase-opensource-src-5.9.7/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -607,12 +607,19 @@ xcb_cursor_t QXcbCursor::createFontCurso xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor) { - xcb_connection_t *conn = xcb_connection(); QPoint spot = cursor->hotSpot(); xcb_cursor_t c = XCB_NONE; - if (cursor->pixmap().depth() > 1) - c = qt_xcb_createCursorXRender(m_screen, cursor->pixmap().toImage(), spot); - if (!c) { + if (cursor->pixmap().depth() > 1) { +#if QT_CONFIG(xcb_render) + if (connection()->hasXRender(0, 5)) + c = qt_xcb_createCursorXRender(m_screen, cursor->pixmap().toImage(), spot); + else + qWarning("xrender >= 0.5 required to create pixmap cursors"); +#else + qWarning("This build of Qt does not support pixmap cursors"); +#endif + } else { + xcb_connection_t *conn = xcb_connection(); xcb_pixmap_t cp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->bitmap()->toImage()); xcb_pixmap_t mp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->mask()->toImage()); c = xcb_generate_id(conn);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor