diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-04-11 14:36:55 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-04-11 14:36:55 +0200 |
commit | 98d3e40fb7c88b670a93e73dace2d0f05a5f903c (patch) | |
tree | b1292124a86c219fb434db4ec28e8f805ff52287 /src/plugins/platforms/xcb | |
parent | a74e4b85be83e2da47f4a1d8fcf0e78079335b80 (diff) | |
parent | bab494e4d046f5617d19f5fec35eeff94377c51f (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
mkspecs/qnx-armv7le-qcc/qplatformdefs.h
src/printsupport/kernel/qcups.cpp
src/widgets/styles/qstyle.h
tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
Change-Id: Ia41e13051169a6d4a8a1267548e7d47b859bb267
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.cpp | 33 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 28 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.cpp | 50 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.h | 11 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 2 |
5 files changed, 78 insertions, 46 deletions
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 1579797f85..57d6bc580b 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -94,14 +94,23 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI , m_gc_window(0) { Q_XCB_NOOP(connection()); - m_xcb_image = xcb_image_create_native(xcb_connection(), - size.width(), - size.height(), - XCB_IMAGE_FORMAT_Z_PIXMAP, - depth, - 0, - ~0, - 0); + + const xcb_setup_t *setup = xcb_get_setup(xcb_connection()); + xcb_format_t *fmt = xcb_setup_pixmap_formats(setup); + xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup); + for (; fmt != fmtend; ++fmt) + if (fmt->depth == depth) + break; + + Q_ASSERT(fmt != fmtend); + + m_xcb_image = xcb_image_create(size.width(), size.height(), + XCB_IMAGE_FORMAT_Z_PIXMAP, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, 0, + QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST, + XCB_IMAGE_ORDER_MSB_FIRST, + 0, ~0, 0); const int segmentSize = m_xcb_image->stride * m_xcb_image->height; if (!segmentSize) @@ -209,10 +218,13 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s // at least 16384 bytes. That should be enough for quite large images. Q_ASSERT(rows_per_put > 0); + // Convert the image to the native byte order. + xcb_image_t *converted_image = xcb_image_native(xcb_connection(), m_xcb_image, 1); + while (height > 0) { int rows = std::min(height, rows_per_put); - xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, src_x, src_y, width, rows, + xcb_image_t *subimage = xcb_image_subimage(converted_image, src_x, src_y, width, rows, 0, 0, 0); xcb_image_put(xcb_connection(), window, @@ -228,6 +240,9 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s target_y += rows; height -= rows; } + + if (converted_image != m_xcb_image) + xcb_image_destroy(converted_image); } Q_XCB_NOOP(connection()); diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 66b8401ea2..f5f6c712c5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -93,10 +93,37 @@ QT_BEGIN_NAMESPACE #ifdef XCB_USE_XLIB +static const char * const xcbConnectionErrors[] = { + "No error", /* Error 0 */ + "I/O error", /* XCB_CONN_ERROR */ + "Unsupported extension used", /* XCB_CONN_CLOSED_EXT_NOTSUPPORTED */ + "Out of memory", /* XCB_CONN_CLOSED_MEM_INSUFFICIENT */ + "Maximum allowed requested length exceeded", /* XCB_CONN_CLOSED_REQ_LEN_EXCEED */ + "Failed to parse display string", /* XCB_CONN_CLOSED_PARSE_ERR */ + "No such screen on display", /* XCB_CONN_CLOSED_INVALID_SCREEN */ + "Error during FD passing" /* XCB_CONN_CLOSED_FDPASSING_FAILED */ +}; + static int nullErrorHandler(Display *, XErrorEvent *) { return 0; } + +static int ioErrorHandler(Display *dpy) +{ + xcb_connection_t *conn = XGetXCBConnection(dpy); + if (conn != NULL) { + /* Print a message with a textual description of the error */ + int code = xcb_connection_has_error(conn); + const char *str = "Unknown error"; + int arrayLength = sizeof(xcbConnectionErrors) / sizeof(xcbConnectionErrors[0]); + if (code >= 0 && code < arrayLength) + str = xcbConnectionErrors[code]; + + qWarning("The X11 connection broke: %s (code %d)", str, code); + } + return _XDefaultIOError(dpy); +} #endif QXcbScreen* QXcbConnection::findOrCreateScreen(QList<QXcbScreen *>& newScreens, @@ -284,6 +311,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra m_connection = XGetXCBConnection(dpy); XSetEventQueueOwner(dpy, XCBOwnsEventQueue); XSetErrorHandler(nullErrorHandler); + XSetIOErrorHandler(ioErrorHandler); m_xlib_display = dpy; } #else diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 92b24f4722..69601f44d4 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -663,23 +663,17 @@ void QXcbKeyboard::clearXKBConfig() memset(&xkb_names, 0, sizeof(xkb_names)); } -void QXcbKeyboard::printKeymapError(const QString &error) const +void QXcbKeyboard::printKeymapError(const char *error) const { - qWarning() << "Qt: " << error; - // check if XKB config root is a valid path - const QDir xkbRoot = qEnvironmentVariableIsSet("QT_XKB_CONFIG_ROOT") - ? QString::fromLocal8Bit(qgetenv("QT_XKB_CONFIG_ROOT")) - : DFLT_XKB_CONFIG_ROOT; - if (!xkbRoot.exists() || xkbRoot.dirName() != "xkb") { - qWarning() << "Set QT_XKB_CONFIG_ROOT to provide a valid XKB configuration data path, current search paths: " - << xkbRoot.path() << ". Use ':' as separator to provide several search paths."; - return; + qWarning() << error; + if (xkb_context) { + qWarning() << "Current XKB configuration data search paths are: "; + for (unsigned int i = 0; i < xkb_context_num_include_paths(xkb_context); ++i) + qWarning() << xkb_context_include_path_get(xkb_context, i); } - qWarning() << "_XKB_RULES_NAMES property contains:" << "\nrules : " << xkb_names.rules << - "\nmodel : " << xkb_names.model << "\nlayout : " << xkb_names.layout << - "\nvariant : " << xkb_names.variant << "\noptions : " << xkb_names.options << - "\nIf this looks like a valid keyboard layout information then you might need to " - "update XKB configuration data on the system (http://cgit.freedesktop.org/xkeyboard-config/)."; + qWarning() << "Use QT_XKB_CONFIG_ROOT environmental variable to provide an additional search path, " + "add ':' as separator to provide several search paths and/or make sure that XKB configuration data " + "directory contains recent enough contents, to update please see http://cgit.freedesktop.org/xkeyboard-config/ ."; } void QXcbKeyboard::updateKeymap() @@ -696,7 +690,7 @@ void QXcbKeyboard::updateKeymap() xkb_context = xkb_context_new((xkb_context_flags)0); } if (!xkb_context) { - printKeymapError("Failed to create XKB context!"); + printKeymapError("Qt: Failed to create XKB context!"); m_config = false; return; } @@ -731,8 +725,7 @@ void QXcbKeyboard::updateKeymap() if (xkb_keymap) { new_state = xkb_state_new(xkb_keymap); } else { - // failed to compile from RMLVO, give a verbose error message - printKeymapError("Qt: Failed to compile a keymap!"); + printKeymapError("Failed to compile a keymap!"); m_config = false; return; } @@ -863,7 +856,7 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const return QList<int>(); QList<int> result; - int baseQtKey = keysymToQtKey(sym, modifiers, keysymToUnicode(sym)); + int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, event->nativeScanCode())); result += (baseQtKey + modifiers); // The base key is _always_ valid, of course xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(xkb_keymap, "Shift"); @@ -910,7 +903,7 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const continue; Qt::KeyboardModifiers mods = modifiers & ~neededMods; - qtKey = keysymToQtKey(sym, mods, keysymToUnicode(sym)); + qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, event->nativeScanCode())); if (qtKey == baseQtKey) continue; @@ -986,10 +979,10 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection) , xkb_context(0) , xkb_keymap(0) , xkb_state(0) - , core_device_id(0) { memset(&xkb_names, 0, sizeof(xkb_names)); #ifndef QT_NO_XKB + core_device_id = 0; if (connection->hasXKB()) { updateVModMapping(); updateVModToRModMapping(); @@ -1326,7 +1319,8 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod } Qt::KeyboardModifiers modifiers = translateModifiers(state); - QString string = keysymToUnicode(sym); + + QString string = lookupString(xkb_state, code); int count = string.size(); string.truncate(count); @@ -1389,16 +1383,12 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod } } -QString QXcbKeyboard::keysymToUnicode(xcb_keysym_t sym) const +QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const { QByteArray chars; - int bytes; - chars.resize(7); - bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size()); - if (bytes == -1) - qWarning("QXcbKeyboard::handleKeyEvent - buffer too small"); - chars.resize(bytes-1); - + chars.resize(1 + xkb_state_key_get_utf8(state, code, 0, 0)); + // equivalent of XLookupString + xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); return QString::fromUtf8(chars); } diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 36ce1ea2f0..11b7429aca 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -48,10 +48,7 @@ #include <xkbcommon/xkbcommon.h> #ifndef QT_NO_XKB -// note: extern won't be needed from libxkbcommon 0.4.1 and above -extern "C" { #include <xkbcommon/xkbcommon-x11.h> -} #endif #include <QEvent> @@ -79,9 +76,9 @@ public: void updateXKBMods(); quint32 xkbModMask(quint16 state); void updateXKBStateFromCore(quint16 state); +#ifndef QT_NO_XKB // when XKEYBOARD is present on the X server int coreDeviceId() const { return core_device_id; } -#ifndef QT_NO_XKB void updateXKBState(xcb_xkb_state_notify_event_t *state); #endif @@ -89,10 +86,10 @@ protected: void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time); void resolveMaskConflicts(); - QString keysymToUnicode(xcb_keysym_t sym) const; + QString lookupString(struct xkb_state *state, xcb_keycode_t code) const; int keysymToQtKey(xcb_keysym_t keysym) const; int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const; - void printKeymapError(const QString &error) const; + void printKeymapError(const char *error) const; void readXKBConfig(); void clearXKBConfig(); @@ -134,9 +131,11 @@ private: xkb_mod_index_t mod5; }; _xkb_mods xkb_mods; +#ifndef QT_NO_XKB // when XKEYBOARD is present on the X server _mod_masks vmod_masks; int core_device_id; +#endif }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index bed6eb59dc..5a2002f1d4 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1174,7 +1174,7 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp) void QXcbWindow::setTransparentForMouseEvents(bool transparent) { - if (transparent == m_transparent) + if (!connection()->hasXFixes() || transparent == m_transparent) return; xcb_rectangle_t rectangle; |