[qt5-qtbase] support the old versions of libxcb and libxkbcommon in F19 and F20

Kevin Kofler kkofler at fedoraproject.org
Wed Jul 2 00:39:47 UTC 2014


commit c7f997cf4d8348ed63713370389e19a241ba7628
Author: Kevin Kofler <Kevin at tigcc.ticalc.org>
Date:   Wed Jul 2 02:39:46 2014 +0200

    support the old versions of libxcb and libxkbcommon in F19 and F20
    
    * Mon Jun 30 2014 Kevin Kofler <Kevin at tigcc.ticalc.org> 5.3.1-4
    - support the old versions of libxcb and libxkbcommon in F19 and F20
    - don't use the bundled libxkbcommon
    
    As per https://fedoraproject.org/wiki/Packaging:No_Bundled_Libraries
    (all prior 5.3.x builds are NOT shippable). Also fixes QT_NO_XKB getting
    set in those broken builds.

 qt5-qtbase.spec                                    |   28 ++-
 qtbase-opensource-src-5.3.0-no_xkbcommon-x11.patch |   16 --
 qtbase-opensource-src-5.3.0-old-xcb.patch          |  257 ++++++++++++++++++++
 3 files changed, 272 insertions(+), 29 deletions(-)
---
diff --git a/qt5-qtbase.spec b/qt5-qtbase.spec
index ee0da07..3d231d6 100644
--- a/qt5-qtbase.spec
+++ b/qt5-qtbase.spec
@@ -22,7 +22,7 @@
 Summary: Qt5 - QtBase components
 Name:    qt5-qtbase
 Version: 5.3.1
-Release: 3%{?dist}
+Release: 4%{?dist}
 
 # See LGPL_EXCEPTIONS.txt, LICENSE.GPL3, respectively, for exception details
 License: LGPLv2 with exceptions or GPLv3 with exceptions
@@ -45,8 +45,8 @@ Source5: qconfig-multilib.h
 # QT_XCB_FORCE_SOFTWARE_OPENGL for them
 Source6: 10-qt5-check-opengl2.sh
 
-# drop configure check for xkbcommon-x11
-Patch1: qtbase-opensource-src-5.3.0-no_xkbcommon-x11.patch
+# support the old versions of libxcb and libxkbcommon in F19 and F20
+Patch1: qtbase-opensource-src-5.3.0-old-xcb.patch
 
 # support multilib optflags
 Patch2: qtbase-multilib_optflags.patch
@@ -113,15 +113,13 @@ BuildRequires: pkgconfig(openssl)
 BuildRequires: pkgconfig(libpulse) pkgconfig(libpulse-mainloop-glib)
 %if 0%{?fedora} > 20
 BuildRequires: pkgconfig(xcb-xkb) >= 1.10
-%global xkbcommon -system-xkbcommon
 BuildRequires: pkgconfig(xkbcommon) >= 0.4.1
 BuildRequires: pkgconfig(xkbcommon-x11) >= 0.4.1
-## if no xcb-xkb > 1.10 or xkbcommon-x11
-## ie, to allow libxkbcommon backport for f19/f20
-#global no_xkbcommon_x11 1
 %else
-Provides: bundled(libxkbcommon) = 0.4.1
-%global xkbcommon -qt-xkbcommon
+# apply our patch to support the old versions of xcb and xkbcommon
+%global old_xcb 1
+BuildRequires: pkgconfig(xcb-xkb)
+BuildRequires: pkgconfig(xkbcommon)
 %endif
 BuildRequires: pkgconfig(xkeyboard-config)
 %if 0%{?fedora} || 0%{?rhel} > 6
@@ -262,8 +260,8 @@ Qt5 libraries used for drawing widgets and OpenGL items.
 %prep
 %setup -q -n qtbase-opensource-src-%{version}%{?pre:-%{pre}}
 
-%if 0%{?no_xkbcommon_x11}
-%patch1 -p1 -b .no_xkbcommon-x11
+%if 0%{?old_xcb}
+%patch1 -p1 -b .old_xcb
 %endif
 %patch2 -p1 -b .multilib_optflags
 # drop backup file(s), else they get installed too, http://bugzilla.redhat.com/639463
@@ -297,7 +295,7 @@ sed -i -e 's|^\(QMAKE_STRIP.*=\).*$|\1|g' mkspecs/common/linux.conf
 # move some bundled libs to ensure they're not accidentally used
 pushd src/3rdparty
 mkdir UNUSED
-mv freetype libjpeg libpng zlib xcb UNUSED/
+mv freetype libjpeg libpng zlib xcb xkbcommon UNUSED/
 %if "%{?sqlite}" == "-system-sqlite"
 mv sqlite UNUSED/
 %endif
@@ -353,7 +351,7 @@ popd
   %{?pcre} \
   %{?sqlite} \
   %{?tds} \
-  %{?xkbcommon} \
+  -system-xkbcommon \
   -system-zlib
 
 make %{?_smp_mflags}
@@ -702,6 +700,10 @@ popd
 
 
 %changelog
+* Mon Jun 30 2014 Kevin Kofler <Kevin at tigcc.ticalc.org> 5.3.1-4
+- support the old versions of libxcb and libxkbcommon in F19 and F20
+- don't use the bundled libxkbcommon
+
 * Mon Jun 30 2014 Rex Dieter <rdieter at fedoraproject.org> 5.3.1-3
 - -devel: Requires: pkgconfig(egl)
 
diff --git a/qtbase-opensource-src-5.3.0-old-xcb.patch b/qtbase-opensource-src-5.3.0-old-xcb.patch
new file mode 100644
index 0000000..00ef724
--- /dev/null
+++ b/qtbase-opensource-src-5.3.0-old-xcb.patch
@@ -0,0 +1,257 @@
+diff -ur qtbase-opensource-src-5.3.0/configure qtbase-opensource-src-5.3.0-old-xcb/configure
+--- qtbase-opensource-src-5.3.0/configure	2014-05-15 19:12:04.000000000 +0200
++++ qtbase-opensource-src-5.3.0-old-xcb/configure	2014-06-01 23:45:21.000000000 +0200
+@@ -4946,10 +4946,8 @@
+                 QMAKE_LIBS_XCB="`$PKG_CONFIG --libs $XCB_PACKAGES 2>/dev/null`"
+             fi
+ 
+-            # libxcb version 1.10 was the first version that enables xcb-xkb by default,
+-            # therefore the minimal xcb-xkb version we support is 1.10
+             CFG_XKB=no
+-            if $PKG_CONFIG --exists "xcb-xkb >= 1.10" 2>/dev/null; then
++            if $PKG_CONFIG --exists "xcb-xkb" 2>/dev/null; then
+                 QMAKE_CFLAGS_XKB="`$PKG_CONFIG --cflags xcb xcb-xkb 2>/dev/null`"
+                 QMAKE_LIBS_XKB="`$PKG_CONFIG --libs xcb xcb-xkb 2>/dev/null`"
+                 if compileTest qpa/xcb-xkb "xcb-xkb" $QMAKE_CFLAGS_XKB $QMAKE_LIBS_XKB; then
+@@ -5051,14 +5049,14 @@
+ fi
+ 
+ # Detect libxkbcommon
+-MIN_REQ_XKBCOMMON="0.4.1"
++MIN_REQ_XKBCOMMON="0.3.0"
+ ORIG_CFG_XKBCOMMON="$CFG_XKBCOMMON"
+ # currently only xcb platform plugin supports building xkbcommon
+ if [ "$CFG_XCB" != "no" ]; then
+     if [ "$CFG_XKBCOMMON" = "auto" ] || [ "$CFG_XKBCOMMON" = "system" ]; then
+-        if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xkbcommon xkbcommon-x11 >= $MIN_REQ_XKBCOMMON" 2>/dev/null; then
+-            QMAKE_CFLAGS_XKBCOMMON="`$PKG_CONFIG --cflags xkbcommon xkbcommon-x11 2>/dev/null`"
+-            QMAKE_LIBS_XKBCOMMON="`$PKG_CONFIG --libs xkbcommon xkbcommon-x11 2>/dev/null`"
++        if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xkbcommon >= $MIN_REQ_XKBCOMMON" 2>/dev/null; then
++            QMAKE_CFLAGS_XKBCOMMON="`$PKG_CONFIG --cflags xkbcommon 2>/dev/null`"
++            QMAKE_LIBS_XKBCOMMON="`$PKG_CONFIG --libs xkbcommon 2>/dev/null`"
+ 
+             QMakeVar set QMAKE_CFLAGS_XKBCOMMON "$QMAKE_CFLAGS_XKBCOMMON"
+             QMakeVar set QMAKE_LIBS_XKBCOMMON "$QMAKE_LIBS_XKBCOMMON"
+@@ -6552,7 +6550,7 @@
+     echo
+ fi
+ if [ "$ORIG_CFG_XKBCOMMON" != qt ] && [ "$CFG_XKBCOMMON" = qt ]; then
+-    echo "NOTE: libxkbcommon and libxkbcommon-x11 $MIN_REQ_XKBCOMMON or higher not found on the system, will use "
++    echo "NOTE: libxkbcommon $MIN_REQ_XKBCOMMON or higher not found on the system, will use "
+     echo "the bundled version from 3rd party directory."
+ fi
+ if [ "$CFG_XKBCOMMON" = "qt" ] && [ "$CFG_XKB_CONFIG_ROOT" = "not found" ]; then
+diff -ur qtbase-opensource-src-5.3.0/src/plugins/platforms/xcb/qxcbconnection.cpp qtbase-opensource-src-5.3.0-old-xcb/src/plugins/platforms/xcb/qxcbconnection.cpp
+--- qtbase-opensource-src-5.3.0/src/plugins/platforms/xcb/qxcbconnection.cpp	2014-05-15 19:12:17.000000000 +0200
++++ qtbase-opensource-src-5.3.0-old-xcb/src/plugins/platforms/xcb/qxcbconnection.cpp	2014-06-02 00:17:14.000000000 +0200
+@@ -1698,7 +1698,7 @@
+     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);
++    xkb_query_cookie = xcb_xkb_use_extension(c, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
+     xkb_query = xcb_xkb_use_extension_reply(c, xkb_query_cookie, 0);
+ 
+     if (!xkb_query) {
+diff -ur qtbase-opensource-src-5.3.0/src/plugins/platforms/xcb/qxcbkeyboard.cpp qtbase-opensource-src-5.3.0-old-xcb/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+--- qtbase-opensource-src-5.3.0/src/plugins/platforms/xcb/qxcbkeyboard.cpp	2014-05-15 19:12:17.000000000 +0200
++++ qtbase-opensource-src-5.3.0-old-xcb/src/plugins/platforms/xcb/qxcbkeyboard.cpp	2014-06-30 19:08:22.000000000 +0200
+@@ -697,50 +697,65 @@
+         // log only critical errors, we do our own error logging from printKeymapError()
+         xkb_context_set_log_level(xkb_context, (xkb_log_level)XKB_LOG_LEVEL_CRITICAL);
+     }
+-    // update xkb keymap object
+-    xkb_keymap_unref(xkb_keymap);
+-    xkb_keymap = 0;
+ 
+-    struct xkb_state *new_state = 0;
+-#ifndef QT_NO_XKB
+-    if (connection()->hasXKB()) {
+-        xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, xcb_connection(), core_device_id, (xkb_keymap_compile_flags)0);
+-        if (xkb_keymap) {
+-            // Create a new keyboard state object for a keymap
+-            new_state = xkb_x11_state_new_from_device(xkb_keymap, xcb_connection(), core_device_id);
+-        }
+-    }
+-#endif
++    readXKBConfig();
++    // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names
++    if (xkb_keymap)
++        xkb_keymap_unref(xkb_keymap);
++
++    xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0);
+     if (!xkb_keymap) {
+-        // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names
+-        readXKBConfig();
++        // last fallback is to used hard-coded keymap name, see DEFAULT_XKB_* in xkbcommon.pri
++        qWarning() << "Qt: Could not determine keyboard configuration data"
++                      " from X server, will use hard-coded keymap configuration.";
++        clearXKBConfig();
+         xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0);
+-        if (!xkb_keymap) {
+-            // last fallback is to used hard-coded keymap name, see DEFAULT_XKB_* in xkbcommon.pri
+-            qWarning() << "Qt: Could not determine keyboard configuration data"
+-                          " from X server, will use hard-coded keymap configuration.";
+-            clearXKBConfig();
+-            xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0);
+-        }
+-        if (xkb_keymap) {
+-            new_state = xkb_state_new(xkb_keymap);
+-        } else {
+-            printKeymapError("Failed to compile a keymap!");
+-            m_config = false;
+-            return;
+-        }
+-
+     }
++    if (!xkb_keymap) {
++        printKeymapError("Qt: Failed to compile a keymap!");
++        m_config = false;
++        return;
++    }
++
++    struct xkb_state *new_state = xkb_state_new(xkb_keymap);
+     if (!new_state) {
+         qWarning("Qt: Failed to create xkb state!");
+         m_config = false;
+         return;
+     }
+-    // update xkb state object
+-    xkb_state_unref(xkb_state);
+-    xkb_state = new_state;
+-    if (!connection()->hasXKB())
+-        updateXKBMods();
++
++    if (xkb_state) {
++        xkb_state_unref(xkb_state);
++        xkb_state = new_state;
++    } else {
++        xkb_state = new_state;
++#ifndef QT_NO_XKB
++        if (connection()->hasXKB()) {
++            // get initial state from the X server (and keep it up-to-date at all times)
++            xcb_xkb_get_state_cookie_t state;
++            xcb_xkb_get_state_reply_t *init_state;
++
++            xcb_connection_t *c = xcb_connection();
++            state = xcb_xkb_get_state(c, XCB_XKB_ID_USE_CORE_KBD);
++            init_state = xcb_xkb_get_state_reply(c, state, 0);
++            if (!init_state) {
++                qWarning("Qt: couldn't retrieve an initial keyboard state");
++                return;
++            }
++            /* The xkb keyboard state is comprised of the state of all keyboard modifiers,
++               the keyboard group, and the state of the pointer buttons */
++            xkb_state_update_mask(xkb_state,
++                                  init_state->baseMods,
++                                  init_state->latchedMods,
++                                  init_state->lockedMods,
++                                  init_state->baseGroup,
++                                  init_state->latchedGroup,
++                                  init_state->lockedGroup);
++            free(init_state);
++        } else
++#endif
++            updateXKBMods();
++    }
+ }
+ 
+ #ifndef QT_NO_XKB
+@@ -856,7 +871,7 @@
+         return QList<int>();
+ 
+     QList<int> result;
+-    int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, event->nativeScanCode()));
++    int baseQtKey = keysymToQtKey(sym, modifiers, keysymToUnicode(sym));
+     result += (baseQtKey + modifiers); // The base key is _always_ valid, of course
+ 
+     xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(xkb_keymap, "Shift");
+@@ -903,7 +918,7 @@
+                 continue;
+ 
+             Qt::KeyboardModifiers mods = modifiers & ~neededMods;
+-            qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, event->nativeScanCode()));
++            qtKey = keysymToQtKey(sym, mods, keysymToUnicode(sym));
+ 
+             if (qtKey == baseQtKey)
+                 continue;
+@@ -986,11 +1001,23 @@
+     if (connection->hasXKB()) {
+         updateVModMapping();
+         updateVModToRModMapping();
+-        core_device_id = xkb_x11_get_core_keyboard_device_id(xcb_connection());
+-        if (core_device_id == -1) {
++
++        // get the core keyboard id
++        xcb_xkb_get_device_info_cookie_t device_id_cookie;
++        xcb_xkb_get_device_info_reply_t *device_id;
++
++        device_id_cookie = xcb_xkb_get_device_info(xcb_connection(),
++                                            XCB_XKB_ID_USE_CORE_KBD,
++                                            0, 0, 0, 0, 0, 0);
++
++        device_id = xcb_xkb_get_device_info_reply(xcb_connection(), device_id_cookie, 0);
++        if (!device_id) {
+             qWarning("Qt: couldn't get core keyboard device info");
+             return;
+         }
++
++        core_device_id = device_id->deviceID;
++        free(device_id);
+     } else {
+ #endif
+         m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
+@@ -1320,7 +1347,7 @@
+ 
+     Qt::KeyboardModifiers modifiers = translateModifiers(state);
+ 
+-    QString string = lookupString(xkb_state, code);
++    QString string = keysymToUnicode(sym);
+     int count = string.size();
+     string.truncate(count);
+ 
+@@ -1383,12 +1410,18 @@
+     }
+ }
+ 
+-QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
++QString QXcbKeyboard::keysymToUnicode(xcb_keysym_t sym) const
+ {
+     QByteArray chars;
+-    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());
++    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);
++
+     return QString::fromUtf8(chars);
+ }
+ 
+diff -ur qtbase-opensource-src-5.3.0/src/plugins/platforms/xcb/qxcbkeyboard.h qtbase-opensource-src-5.3.0-old-xcb/src/plugins/platforms/xcb/qxcbkeyboard.h
+--- qtbase-opensource-src-5.3.0/src/plugins/platforms/xcb/qxcbkeyboard.h	2014-05-15 19:12:17.000000000 +0200
++++ qtbase-opensource-src-5.3.0-old-xcb/src/plugins/platforms/xcb/qxcbkeyboard.h	2014-06-30 19:06:35.000000000 +0200
+@@ -47,9 +47,6 @@
+ #include <xcb/xcb_keysyms.h>
+ 
+ #include <xkbcommon/xkbcommon.h>
+-#ifndef QT_NO_XKB
+-#include <xkbcommon/xkbcommon-x11.h>
+-#endif
+ 
+ #include <QEvent>
+ 
+@@ -86,7 +83,7 @@
+     void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
+ 
+     void resolveMaskConflicts();
+-    QString lookupString(struct xkb_state *state, xcb_keycode_t code) const;
++    QString keysymToUnicode(xcb_keysym_t sym) const;
+     int keysymToQtKey(xcb_keysym_t keysym) const;
+     int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const;
+     void printKeymapError(const char *error) const;


More information about the scm-commits mailing list