Start using libxkbcommon in the xcb plug-in.
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>
Wed, 1 Jun 2011 09:00:58 +0000 (11:00 +0200)
committerLaszlo Agocs <laszlo.p.agocs@nokia.com>
Wed, 1 Jun 2011 09:01:32 +0000 (11:01 +0200)
configure
src/plugins/platforms/xcb/qxcbkeyboard.cpp
src/plugins/platforms/xcb/qxcbkeyboard.h
src/plugins/platforms/xcb/xcb.pro

index 9a666d9..625c3ff 100755 (executable)
--- a/configure
+++ b/configure
@@ -6291,13 +6291,19 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
         QMAKE_LIBS_WAYLAND=`$PKG_CONFIG --libs wayland-client 2>/dev/null`
         QMAKE_INCDIR_WAYLAND=`$PKG_CONFIG --variable=includedir wayland-client 2>/dev/null`
         QMAKE_LIBDIR_WAYLAND=`$PKG_CONFIG --variable=libdir wayland-client 2>/dev/null`
+    fi
 
-        if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists xkbcommon 2>/dev/null; then
-            QMAKE_CFLAGS_WAYLAND="$QMAKE_CFLAGS_WAYLAND `$PKG_CONFIG --cflags xkbcommon 2>/dev/null`"
-            QMAKE_LIBS_WAYLAND="$QMAKE_LIBS_WAYLAND `$PKG_CONFIG --libs xkbcommon 2>/dev/null`"
-        else
-            QMAKE_DEFINES_WAYLAND=QT_NO_WAYLAND_XKB
-        fi
+    # Detect libxkbcommon
+    if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists 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`"
+        QMAKE_CFLAGS_WAYLAND="$QMAKE_CFLAGS_WAYLAND $QMAKE_CFLAGS_XKBCOMMON"
+        QMAKE_LIBS_WAYLAND="$QMAKE_LIBS_WAYLAND $QMAKE_LIBS_XKBCOMMON"
+        QMAKE_CFLAGS_XCB="$QMAKE_CFLAGS_XCB $QMAKE_CFLAGS_XKBCOMMON"
+        QMAKE_LIBS_XCB="$QMAKE_LIBS_XCB $QMAKE_LIBS_XKBCOMMON"
+    else
+        QMAKE_DEFINES_WAYLAND=QT_NO_WAYLAND_XKB
+        QMAKE_DEFINES_XCB=QT_NO_XCB_XKB
     fi
 
     # QMake variables set here override those in the mkspec. Therefore we only set the variables here if they are not zero.
@@ -6309,6 +6315,12 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
         QMakeVar set QMAKE_DEFINES_WAYLAND " $QMAKE_DEFINES_WAYLAND"
     fi
 
+    if [ -n "$QMAKE_CFLAGS_XCB" ] || [ -n "$QMAKE_LIBS_XCB" ]; then
+        QMakeVar set QMAKE_CFLAGS_XCB "$QMAKE_CFLAGS_XCB"
+        QMakeVar set QMAKE_LIBS_XCB "$QMAKE_LIBS_XCB"
+        QMakeVar set QMAKE_DEFINES_XCB "$QMAKE_DEFINES_XCB"
+    fi
+
     if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/qpa/wayland "Wayland" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_CFLAGS_WAYLAND $QMAKE_LIBS_WAYLAND; then
         QT_CONFIG="$QT_CONFIG wayland"
     fi
index 80f9377..2b9f790 100644 (file)
 
 #include <X11/keysym.h>
 
+#ifndef QT_NO_XCB_XKB
+typedef unsigned char KeyCode;
+#include <X11/extensions/XKBcommon.h>
+#endif
+
 #include <QtGui/QWindowSystemInterface>
 #include <QtCore/QTextCodec>
 
@@ -904,6 +909,7 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
     , m_meta_mask(0)
 {
     m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
+    initXkb();
 }
 
 QXcbKeyboard::~QXcbKeyboard()
@@ -911,6 +917,73 @@ QXcbKeyboard::~QXcbKeyboard()
     xcb_key_symbols_free(m_key_symbols);
 }
 
+void QXcbKeyboard::initXkb()
+{
+#ifndef QT_NO_XCB_XKB
+    struct xkb_rule_names names;
+    names.rules = "evdev";
+    names.model = "pc105";
+    names.layout = "us";
+    names.variant = "";
+    names.options = "";
+    m_xkb = xkb_compile_keymap_from_rules(&names);
+    for (int i = m_xkb->min_key_code; i < m_xkb->max_key_code; ++i) {
+        const uint mask = m_xkb->map->modmap ? m_xkb->map->modmap[i] : 0;
+        if (!mask)
+            continue;
+        for (int j = 0; j < XkbKeyGroupsWidth(m_xkb, i); ++j) {
+            uint32_t keySym = XkbKeySym(m_xkb, i, j);
+            if (keySym)
+                setMask(keySym, mask);
+        }
+    }
+#endif
+}
+
+void QXcbKeyboard::setMask(uint sym, uint mask)
+{
+    if (m_alt_mask == 0
+        && m_meta_mask != mask
+        && m_super_mask != mask
+        && m_hyper_mask != mask
+        && (sym == XK_Alt_L || sym == XK_Alt_R)) {
+        m_alt_mask = mask;
+    }
+    if (m_meta_mask == 0
+        && m_alt_mask != mask
+        && m_super_mask != mask
+        && m_hyper_mask != mask
+        && (sym == XK_Meta_L || sym == XK_Meta_R)) {
+        m_meta_mask = mask;
+    }
+    if (m_super_mask == 0
+        && m_alt_mask != mask
+        && m_meta_mask != mask
+        && m_hyper_mask != mask
+        && (sym == XK_Super_L || sym == XK_Super_R)) {
+        m_super_mask = mask;
+    }
+    if (m_hyper_mask == 0
+        && m_alt_mask != mask
+        && m_meta_mask != mask
+        && m_super_mask != mask
+        && (sym == XK_Hyper_L || sym == XK_Hyper_R)) {
+        m_hyper_mask = mask;
+    }
+    if (m_mode_switch_mask == 0
+        && m_alt_mask != mask
+        && m_meta_mask != mask
+        && m_super_mask != mask
+        && m_hyper_mask != mask
+        && sym == XK_Mode_switch) {
+        m_mode_switch_mask = mask;
+    }
+    if (m_num_lock_mask == 0
+        && sym == XK_Num_Lock) {
+        m_num_lock_mask = mask;
+    }
+}
+
 // #define XCB_KEYBOARD_DEBUG
 
 void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time)
index 98e8c90..dcdbf01 100644 (file)
@@ -70,6 +70,8 @@ private:
     QString translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
                             int &code, Qt::KeyboardModifiers &modifiers,
                             QByteArray &chars, int &count);
+    void initXkb();
+    void setMask(uint sym, uint mask);
 
     uint m_alt_mask;
     uint m_super_mask;
@@ -79,6 +81,9 @@ private:
     uint m_num_lock_mask;
 
     xcb_key_symbols_t *m_key_symbols;
+#ifndef QT_NO_XCB_XKB
+    struct xkb_desc *m_xkb;
+#endif
 };
 
 #endif
index 2091bb0..04db369 100644 (file)
@@ -72,6 +72,10 @@ contains(QT_CONFIG, opengl) {
 
 LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync
 
+DEFINES += $$QMAKE_DEFINES_XCB
+LIBS += $$QMAKE_LIBS_XCB
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
+
 include (../fontdatabases/genericunix/genericunix.pri)
 include (../printersupport/genericunix/genericunix.pri)
 include (../dnd/dnd.pri)