xserver: Branch 'master' - 8 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Mar 19 06:45:36 PDT 2014


 Xi/exevents.c    |    2 
 include/input.h  |    6 +
 include/xkbsrv.h |   11 ++
 xkb/ddxLoad.c    |  244 ++++++++++++++++++++++++++++++++++++++++++-------------
 xkb/xkb.c        |   16 ---
 xkb/xkbInit.c    |   42 +++++++--
 xkb/xkbUtils.c   |   37 ++++++--
 7 files changed, 271 insertions(+), 87 deletions(-)

New commits:
commit 4fb31e4824d46edc80bb49b4065152899faa5ac6
Merge: d18d3f6 0e531fb
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Mar 19 06:43:14 2014 -0700

    Merge remote-tracking branch 'whot/for-keith'

commit 0e531fbb97868b9a869044fc5a4f6cb58de6751e
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Wed Mar 12 16:31:25 2014 +1000

    xkb: add XkbLoadKeymapFromString
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Kristian Høgsberg <krh at bitplanet.net>

diff --git a/include/input.h b/include/input.h
index 93c4510..36463f2 100644
--- a/include/input.h
+++ b/include/input.h
@@ -385,6 +385,12 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct(DeviceIntPtr /*device */ ,
                                                KbdCtrlProcPtr /*controlProc */
                                                );
 
+extern _X_EXPORT Bool InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
+							 const char *keymap,
+							 int keymap_length,
+							 BellProcPtr bell_func,
+							 KbdCtrlProcPtr ctrl_func);
+
 extern int ApplyPointerMapping(DeviceIntPtr /* pDev */ ,
                                CARD8 * /* map */ ,
                                int /* len */ ,
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index c1c1561..a80e119 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -876,4 +876,8 @@ extern _X_EXPORT XkbDescPtr XkbCompileKeymap(DeviceIntPtr /* dev */ ,
                                              XkbRMLVOSet *      /* rmlvo */
     );
 
+extern _X_EXPORT XkbDescPtr XkbCompileKeymapFromString(DeviceIntPtr dev,
+						       const char *keymap,
+						       int keymap_length);
+
 #endif                          /* _XKBSRV_H_ */
diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index 76bf09c..1dc0e4e 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -68,6 +68,9 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #define PATHSEPARATOR "/"
 #endif
 
+static unsigned
+LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn);
+
 static void
 OutputDirectory(char *outdir, size_t size)
 {
@@ -255,6 +258,46 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
     return rc;
 }
 
+typedef struct {
+    const char *keymap;
+    size_t len;
+} XkbKeymapString;
+
+static void
+xkb_write_keymap_string_cb(FILE *out, void *userdata)
+{
+    XkbKeymapString *s = userdata;
+    fwrite(s->keymap, s->len, 1, out);
+}
+
+static unsigned int
+XkbDDXLoadKeymapFromString(DeviceIntPtr keybd,
+                          const char *keymap, int keymap_length,
+                          unsigned int want,
+                          unsigned int need,
+                          XkbDescPtr *xkbRtrn)
+{
+    unsigned int have;
+    char *map_name;
+    XkbKeymapString map = {
+        .keymap = keymap,
+        .len = keymap_length
+    };
+
+    *xkbRtrn = NULL;
+
+    map_name = RunXkbComp(xkb_write_keymap_string_cb, &map);
+    if (!map_name) {
+        LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
+        return 0;
+    }
+
+    have = LoadXKM(want, need, map_name, xkbRtrn);
+    free(map_name);
+
+    return have;
+}
+
 static FILE *
 XkbDDXOpenConfigFile(const char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
 {
@@ -486,3 +529,32 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
 
     return KeymapOrDefaults(dev, xkb);
 }
+
+XkbDescPtr
+XkbCompileKeymapFromString(DeviceIntPtr dev,
+                           const char *keymap, int keymap_length)
+{
+    XkbDescPtr xkb;
+    unsigned int need, provided;
+
+    if (!dev || !keymap) {
+        LogMessage(X_ERROR, "XKB: No device or keymap specified\n");
+        return NULL;
+    }
+
+    /* These are the components we really really need */
+    need = XkmSymbolsMask | XkmCompatMapMask | XkmTypesMask |
+           XkmKeyNamesMask | XkmVirtualModsMask;
+
+    provided =
+        XkbDDXLoadKeymapFromString(dev, keymap, keymap_length,
+                                   XkmAllIndicesMask, need, &xkb);
+    if ((need & provided) != need) {
+        if (xkb) {
+            XkbFreeKeyboard(xkb, 0, TRUE);
+            xkb = NULL;
+        }
+    }
+
+    return KeymapOrDefaults(dev, xkb);
+}
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 33420b6..06ec46e 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -505,9 +505,10 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
     return Success;
 }
 
-_X_EXPORT Bool
-InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
-                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+static Bool
+InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+                                 const char *keymap, int keymap_length,
+                                 BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
 {
     int i;
     unsigned int check;
@@ -521,8 +522,9 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     BUG_RETURN_VAL(dev == NULL, FALSE);
     BUG_RETURN_VAL(dev->key != NULL, FALSE);
     BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
+    BUG_RETURN_VAL(rmlvo && keymap, FALSE);
 
-    if (!rmlvo) {
+    if (!rmlvo && !keymap) {
         rmlvo = &rmlvo_dflts;
         XkbGetRulesDflts(rmlvo);
     }
@@ -550,7 +552,7 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     }
     dev->key->xkbInfo = xkbi;
 
-    if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
+    if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
         XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
         xkb_cached_map = NULL;
     }
@@ -558,7 +560,11 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     if (xkb_cached_map)
         LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
     else {
-        xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
+        if (rmlvo)
+            xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
+        else
+            xkb_cached_map = XkbCompileKeymapFromString(dev, keymap, keymap_length);
+
         if (!xkb_cached_map) {
             ErrorF("XKB: Failed to compile keymap\n");
             goto unwind_info;
@@ -627,8 +633,10 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
 
     dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
 
-    XkbSetRulesDflts(rmlvo);
-    XkbSetRulesUsed(rmlvo);
+    if (rmlvo) {
+        XkbSetRulesDflts(rmlvo);
+        XkbSetRulesUsed(rmlvo);
+    }
     XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
 
     return TRUE;
@@ -647,6 +655,24 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     return FALSE;
 }
 
+_X_EXPORT Bool
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+    return InitKeyboardDeviceStructInternal(dev, rmlvo,
+                                            NULL, 0, bell_func, ctrl_func);
+}
+
+_X_EXPORT Bool
+InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
+                                   const char *keymap, int keymap_length,
+                                   BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+    return InitKeyboardDeviceStructInternal(dev, NULL,
+                                            keymap, keymap_length,
+                                            bell_func, ctrl_func);
+}
+
 /***====================================================================***/
 
         /*
commit 8b6c79e19cfabd9f343884ddd91a738720c94583
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Wed Mar 12 17:20:17 2014 +1000

    xkb: add KeymapOrDefault
    
    Helper function to return a default map if the keymap compilation failed.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Kristian Høgsberg <krh at bitplanet.net>

diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index 0361b9b..76bf09c 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -444,6 +444,29 @@ XkbCompileKeymapForDevice(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, int need)
     return xkb;
 }
 
+static XkbDescPtr
+KeymapOrDefaults(DeviceIntPtr dev, XkbDescPtr xkb)
+{
+    XkbRMLVOSet dflts;
+
+    if (xkb)
+        return xkb;
+
+    /* we didn't get what we really needed. And that will likely leave
+     * us with a keyboard that doesn't work. Use the defaults instead */
+    LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
+                        "keymap instead.\n");
+
+    XkbGetRulesDflts(&dflts);
+
+    xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
+
+    XkbFreeRMLVOSet(&dflts, FALSE);
+
+    return xkb;
+}
+
+
 XkbDescPtr
 XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
 {
@@ -461,20 +484,5 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
 
     xkb = XkbCompileKeymapForDevice(dev, rmlvo, need);
 
-    if (!xkb) {
-        XkbRMLVOSet dflts;
-
-        /* we didn't get what we really needed. And that will likely leave
-         * us with a keyboard that doesn't work. Use the defaults instead */
-        LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
-                   "keymap instead.\n");
-
-        XkbGetRulesDflts(&dflts);
-
-        xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
-
-        XkbFreeRMLVOSet(&dflts, FALSE);
-    }
-
-    return xkb;
+    return KeymapOrDefaults(dev, xkb);
 }
commit cb9a1d01468732196fd25c6422991e784639ffce
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Wed Mar 12 17:18:22 2014 +1000

    xkb: factor out xkb loading to LoadXkm
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Kristian Høgsberg <krh at bitplanet.net>

diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index 33247cf..0361b9b 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -291,6 +291,35 @@ XkbDDXOpenConfigFile(const char *mapName, char *fileNameRtrn, int fileNameRtrnLe
     return file;
 }
 
+static unsigned
+LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn)
+{
+    FILE *file;
+    char fileName[PATH_MAX];
+    unsigned missing;
+
+    file = XkbDDXOpenConfigFile(keymap, fileName, PATH_MAX);
+    if (file == NULL) {
+        LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
+                   fileName);
+        return 0;
+    }
+    missing = XkmReadFile(file, need, want, xkbRtrn);
+    if (*xkbRtrn == NULL) {
+        LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
+        fclose(file);
+        (void) unlink(fileName);
+        return 0;
+    }
+    else {
+        DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
+               (*xkbRtrn)->defined);
+    }
+    fclose(file);
+    (void) unlink(fileName);
+    return (need | want) & (~missing);
+}
+
 unsigned
 XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
                         XkbComponentNamesPtr names,
@@ -299,9 +328,6 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
                         XkbDescPtr *xkbRtrn, char *nameRtrn, int nameRtrnLen)
 {
     XkbDescPtr xkb;
-    FILE *file;
-    char fileName[PATH_MAX];
-    unsigned missing;
 
     *xkbRtrn = NULL;
     if ((keybd == NULL) || (keybd->key == NULL) ||
@@ -321,26 +347,8 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
         LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
         return 0;
     }
-    file = XkbDDXOpenConfigFile(nameRtrn, fileName, PATH_MAX);
-    if (file == NULL) {
-        LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
-                   fileName);
-        return 0;
-    }
-    missing = XkmReadFile(file, need, want, xkbRtrn);
-    if (*xkbRtrn == NULL) {
-        LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
-        fclose(file);
-        (void) unlink(fileName);
-        return 0;
-    }
-    else {
-        DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
-               (*xkbRtrn)->defined);
-    }
-    fclose(file);
-    (void) unlink(fileName);
-    return (need | want) & (~missing);
+
+    return LoadXKM(want, need, nameRtrn, xkbRtrn);
 }
 
 Bool
commit 4391cf27f40ec53d41ac7e437cde49848eb32bde
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 12 16:08:15 2014 +1000

    xkb: add a callback to xkbcomp
    
    This provides a callback to write to xkbcomp's buffer once everything is
    prepared.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Kristian Høgsberg <krh at bitplanet.net>

diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index 551f20a..33247cf 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -90,11 +90,17 @@ OutputDirectory(char *outdir, size_t size)
     }
 }
 
-static Bool
-XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
-                           XkbComponentNamesPtr names,
-                           unsigned want,
-                           unsigned need, char *nameRtrn, int nameRtrnLen)
+/**
+ * Callback invoked by XkbRunXkbComp. Write to out to talk to xkbcomp.
+ */
+typedef void (*xkbcomp_buffer_callback)(FILE *out, void *userdata);
+
+/**
+ * Start xkbcomp, let the callback write into xkbcomp's stdin. When done,
+ * return a strdup'd copy of the file name we've written to.
+ */
+static char *
+RunXkbComp(xkbcomp_buffer_callback callback, void *userdata)
 {
     FILE *out;
     char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
@@ -155,7 +161,7 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
     if (!buf) {
         LogMessage(X_ERROR,
                    "XKB: Could not invoke xkbcomp: not enough memory\n");
-        return FALSE;
+        return NULL;
     }
 
 #ifndef WIN32
@@ -165,13 +171,9 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
 #endif
 
     if (out != NULL) {
-#ifdef DEBUG
-        if (xkbDebugFlags) {
-            ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
-            XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
-        }
-#endif
-        XkbWriteXKBKeymapForNames(out, names, xkb, want, need);
+        /* Now write to xkbcomp */
+        (*callback)(out, userdata);
+
 #ifndef WIN32
         if (Pclose(out) == 0)
 #else
@@ -180,14 +182,11 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
         {
             if (xkbDebugFlags)
                 DebugF("[xkb] xkb executes: %s\n", buf);
-            if (nameRtrn) {
-                strlcpy(nameRtrn, keymap, nameRtrnLen);
-            }
             free(buf);
 #ifdef WIN32
             unlink(tmpname);
 #endif
-            return TRUE;
+            return xnfstrdup(keymap);
         }
         else
             LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
@@ -203,10 +202,57 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
         LogMessage(X_ERROR, "Could not open file %s\n", tmpname);
 #endif
     }
-    if (nameRtrn)
-        nameRtrn[0] = '\0';
     free(buf);
-    return FALSE;
+    return NULL;
+}
+
+typedef struct {
+    XkbDescPtr xkb;
+    XkbComponentNamesPtr names;
+    unsigned int want;
+    unsigned int need;
+} XkbKeymapNamesCtx;
+
+static void
+xkb_write_keymap_for_names_cb(FILE *out, void *userdata)
+{
+    XkbKeymapNamesCtx *ctx = userdata;
+#ifdef DEBUG
+    if (xkbDebugFlags) {
+        ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
+        XkbWriteXKBKeymapForNames(stderr, ctx->names, ctx->xkb, ctx->want, ctx->need);
+    }
+#endif
+    XkbWriteXKBKeymapForNames(out, ctx->names, ctx->xkb, ctx->want, ctx->need);
+}
+
+static Bool
+XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
+                           XkbComponentNamesPtr names,
+                           unsigned want,
+                           unsigned need, char *nameRtrn, int nameRtrnLen)
+{
+    char *keymap;
+    Bool rc = FALSE;
+    XkbKeymapNamesCtx ctx = {
+        .xkb = xkb,
+        .names = names,
+        .want = want,
+        .need = need
+    };
+
+    keymap = RunXkbComp(xkb_write_keymap_for_names_cb, &ctx);
+
+    if (keymap) {
+        if(nameRtrn)
+            strlcpy(nameRtrn, keymap, nameRtrnLen);
+
+        free(keymap);
+        rc = TRUE;
+    } else if (nameRtrn)
+        *nameRtrn = '\0';
+
+    return rc;
 }
 
 static FILE *
commit 6ebd838d80074075827dedb75ed4169ea1946be3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 12 17:17:25 2014 +1000

    xkb: constify XkbDDXOpenConfigFile
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Kristian Høgsberg <krh at bitplanet.net>

diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index f458e3b..551f20a 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -210,7 +210,7 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
 }
 
 static FILE *
-XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
+XkbDDXOpenConfigFile(const char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
 {
     char buf[PATH_MAX], xkm_output_dir[PATH_MAX];
     FILE *file;
commit d35a02a767017f13db4bd4742eef49293d5a30ea
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Fri Mar 7 14:32:27 2014 -0800

    xkb: Repurpose XkbCopyDeviceKeymap to apply a given keymap to a device
    
    This will also make it useful for cases when we have a new keymap to
    apply to a device but don't have a source device.
    
    Reviewed-by: Kristian Høgsberg <krh at bitplanet.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index e9f670e..9c207eb 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -230,7 +230,7 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
 
     mk->sourceid = device->id;
 
-    if (!XkbCopyDeviceKeymap(master, device))
+    if (!XkbDeviceApplyKeymap(master, device->key->xkbInfo->desc))
         FatalError("Couldn't pivot keymap from device to core!\n");
 }
 
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 06f1200..c1c1561 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -824,8 +824,8 @@ extern _X_EXPORT void XkbSendNewKeyboardNotify(DeviceIntPtr /* kbd */ ,
 extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ ,
                           XkbDescPtr /* src */ );
 
-extern _X_EXPORT Bool XkbCopyDeviceKeymap(DeviceIntPtr /* dst */ ,
-                                          DeviceIntPtr /* src */ );
+extern _X_EXPORT Bool XkbDeviceApplyKeymap(DeviceIntPtr /* dst */ ,
+                                           XkbDescPtr /* src */ );
 
 extern void XkbFilterEvents(ClientPtr /* pClient */ ,
                             int /* nEvents */ ,
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 920ec72..dc570f0 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5979,7 +5979,7 @@ ProcXkbGetKbdByName(ClientPtr client)
                 continue;
 
             if (tmpd != dev)
-                XkbCopyDeviceKeymap(tmpd, dev);
+                XkbDeviceApplyKeymap(tmpd, xkb);
 
             if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
                 old_sli = tmpd->kbdfeed->xkb_sli;
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index b59d925..6cf6e79 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -1999,28 +1999,28 @@ XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
 }
 
 Bool
-XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
+XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc)
 {
     xkbNewKeyboardNotify nkn;
     Bool ret;
 
-    if (!dst->key || !src->key)
+    if (!dst->key || !desc)
         return FALSE;
 
     memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
     nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
     nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
     nkn.deviceID = dst->id;
-    nkn.oldDeviceID = dst->id;  /* maybe src->id? */
-    nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
-    nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
+    nkn.oldDeviceID = dst->id;
+    nkn.minKeyCode = desc->min_key_code;
+    nkn.maxKeyCode = desc->max_key_code;
     nkn.requestMajor = XkbReqCode;
     nkn.requestMinor = X_kbSetMap;      /* Near enough's good enough. */
     nkn.changed = XkbNKN_KeycodesMask;
-    if (src->key->xkbInfo->desc->geom)
+    if (desc->geom)
         nkn.changed |= XkbNKN_GeometryMask;
 
-    ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
+    ret = XkbCopyKeymap(dst->key->xkbInfo->desc, desc);
     if (ret)
         XkbSendNewKeyboardNotify(dst, &nkn);
 
commit 361f405d3c866bc4d22ef84975fe771691156336
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Fri Mar 7 14:32:28 2014 -0800

    xkb: Factor out a function to copy a keymap's controls onto another
    
    Reviewed-by: Kristian Høgsberg <krh at bitplanet.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index f857b22..06f1200 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -841,6 +841,9 @@ extern void XkbFakeDeviceButton(DeviceIntPtr /* dev */ ,
                                 int /* press */ ,
                                 int /* button */ );
 
+extern _X_EXPORT void XkbCopyControls(XkbDescPtr /* dst */ ,
+                                      XkbDescPtr /* src */ );
+
 #include "xkbfile.h"
 #include "xkbrules.h"
 
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 31bb8d3..920ec72 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5950,25 +5950,13 @@ ProcXkbGetKbdByName(ClientPtr client)
     if (rep.loaded) {
         XkbDescPtr old_xkb;
         xkbNewKeyboardNotify nkn;
-        int i, nG, nTG;
 
         old_xkb = xkb;
         xkb = new;
         dev->key->xkbInfo->desc = xkb;
         new = old_xkb;          /* so it'll get freed automatically */
 
-        *xkb->ctrls = *old_xkb->ctrls;
-        for (nG = nTG = 0, i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
-            nG = XkbKeyNumGroups(xkb, i);
-            if (nG >= XkbNumKbdGroups) {
-                nTG = XkbNumKbdGroups;
-                break;
-            }
-            if (nG > nTG) {
-                nTG = nG;
-            }
-        }
-        xkb->ctrls->num_groups = nTG;
+        XkbCopyControls(xkb, old_xkb);
 
         nkn.deviceID = nkn.oldDeviceID = dev->id;
         nkn.minKeyCode = new->min_key_code;
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 6c6af60..b59d925 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -2090,3 +2090,26 @@ XkbMergeLockedPtrBtns(DeviceIntPtr master)
         xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons;
     }
 }
+
+void
+XkbCopyControls(XkbDescPtr dst, XkbDescPtr src)
+{
+    int i, nG, nTG;
+
+    if (!dst || !src)
+        return;
+
+    *dst->ctrls = *src->ctrls;
+
+    for (nG = nTG = 0, i = dst->min_key_code; i <= dst->max_key_code; i++) {
+        nG = XkbKeyNumGroups(dst, i);
+        if (nG >= XkbNumKbdGroups) {
+            nTG = XkbNumKbdGroups;
+            break;
+        }
+        if (nG > nTG) {
+            nTG = nG;
+        }
+    }
+    dst->ctrls->num_groups = nTG;
+}


More information about the xorg-commit mailing list