src/gui/kernel/qkeymapper_x11.cpp
changeset 30 5dc02b23752f
parent 19 fcece45ef507
child 33 3e2da88830cd
--- a/src/gui/kernel/qkeymapper_x11.cpp	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/gui/kernel/qkeymapper_x11.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -80,7 +80,7 @@
       (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF))
 #endif
 
-static void getLocaleAndDirection(QLocale *locale,
+void q_getLocaleAndDirection(QLocale *locale,
                                   Qt::LayoutDirection *direction,
                                   const QByteArray &layoutName,
                                   const QByteArray &variantName)
@@ -248,22 +248,17 @@
 
 
 QKeyMapperPrivate::QKeyMapperPrivate()
-    : keyboardInputDirection(Qt::LeftToRight), useXKB(false)
+    : keyboardInputDirection(Qt::LeftToRight), xkb_currentGroup(0)
 {
     memset(&coreDesc, 0, sizeof(coreDesc));
 
 #ifndef QT_NO_XKB
-    int opcode = -1;
-    int xkbEventBase = -1;
-    int xkbErrorBase = -1;
-    int xkblibMajor = XkbMajorVersion;
-    int xkblibMinor = XkbMinorVersion;
-    if (XkbQueryExtension(X11->display, &opcode, &xkbEventBase, &xkbErrorBase, &xkblibMajor, &xkblibMinor))
-        useXKB = true;
-#endif
-
-#if 0
-    qDebug() << "useXKB =" << useXKB;
+    if (X11->use_xkb) {
+        // get the current group
+        XkbStateRec xkbState;
+        if (XkbGetState(X11->display, XkbUseCoreKbd, &xkbState) == Success)
+            xkb_currentGroup = xkbState.group;
+    }
 #endif
 }
 
@@ -276,7 +271,7 @@
 QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *event)
 {
 #ifndef QT_NO_XKB
-    if (useXKB)
+    if (X11->use_xkb)
         return possibleKeysXKB(event);
 #endif
     return possibleKeysCore(event);
@@ -486,7 +481,7 @@
 void QKeyMapperPrivate::clearMappings()
 {
 #ifndef QT_NO_XKB
-    if (useXKB) {
+    if (X11->use_xkb) {
         // try to determine the layout name and input direction by reading the _XKB_RULES_NAMES property off
         // the root window
         QByteArray layoutName;
@@ -515,15 +510,20 @@
                 p += qstrlen(p) + 1;
             } while (p < end);
 
-            layoutName = QByteArray::fromRawData(names[2], qstrlen(names[2]));
-            variantName = QByteArray::fromRawData(names[3], qstrlen(names[3]));
+            // the layout names and variants are saved in the _XKB_RULES_NAMES property as a comma separated list
+            QList<QByteArray> layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(',');
+            if (uint(xkb_currentGroup) < uint(layoutNames.count()))
+                layoutName = layoutNames.at(xkb_currentGroup);
+            QList<QByteArray> variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(',');
+            if (uint(xkb_currentGroup) < uint(variantNames.count()))
+                variantName = variantNames.at(xkb_currentGroup);
         }
 
         // ### ???
         // if (keyboardLayoutName.isEmpty())
         //     qWarning("Qt: unable to determine keyboard layout, please talk to qt-bugs@trolltech.com"); ?
 
-        getLocaleAndDirection(&keyboardInputLocale,
+        q_getLocaleAndDirection(&keyboardInputLocale,
                               &keyboardInputDirection,
                               layoutName,
                               variantName);
@@ -534,7 +534,6 @@
                  << "direction ="
                  << keyboardInputDirection;
 #endif
-
         if (data)
             XFree(data);
     } else
@@ -574,7 +573,7 @@
 
     // look at the modifier mapping, and get the correct masks for alt, meta, super, hyper, and mode_switch
 #ifndef QT_NO_XKB
-    if (useXKB) {
+    if (X11->use_xkb) {
         XkbDescPtr xkbDesc = XkbGetMap(X11->display, XkbAllClientInfoMask, XkbUseCoreKbd);
         for (int i = xkbDesc->min_key_code; i < xkbDesc->max_key_code; ++i) {
             const uint mask = xkbDesc->map->modmap ? xkbDesc->map->modmap[i] : 0;
@@ -1186,6 +1185,8 @@
     XF86XK_LaunchB,             Qt::Key_LaunchD,
     XF86XK_LaunchC,             Qt::Key_LaunchE,
     XF86XK_LaunchD,             Qt::Key_LaunchF,
+    XF86XK_LaunchE,             Qt::Key_LaunchG,
+    XF86XK_LaunchF,             Qt::Key_LaunchH,
 
     // Qtopia keys
     QTOPIAXK_Select,            Qt::Key_Select,