xserver: Branch 'input-hotplug' - 2 commits

Daniel Stone daniels at kemper.freedesktop.org
Wed Aug 23 04:39:16 PDT 2006


 .gitignore     |    1 
 dix/devices.c  |   10 -
 dix/events.c   |   10 -
 xkb/xkb.h      |    4 
 xkb/xkbUtils.c |  404 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 411 insertions(+), 18 deletions(-)

New commits:
diff-tree 728fbadd16a748b45c80bc2c65c46f82cf803578 (from 8f8487ff997670a4af0293fed77ff920cfc39fb1)
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Wed Aug 23 14:33:59 2006 +0300

    gitignore: ignore vi swap files

diff --git a/.gitignore b/.gitignore
index 4118cd0..62b5fd6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -267,3 +267,4 @@ mfb/mfbteblack.c
 mfb/mfbtewhite.c
 mfb/mfbtileC.c
 mfb/mfbtileG.c
+.*.swp
diff-tree 8f8487ff997670a4af0293fed77ff920cfc39fb1 (from a56b98bb047003a05e26ca9365c212a2da7ac200)
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Wed Aug 23 14:33:41 2006 +0300

    xkb/gkve: copy XKB map, not pointer-assign
    Write a new function to copy an XKB map (does everything but geometry at
    the moment), and use that instead of nasty pointer assignments.

diff --git a/dix/devices.c b/dix/devices.c
index 773b301..60c2d29 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -260,16 +260,6 @@ CoreKeyboardProc(DeviceIntPtr pDev, int 
         break;
 
     case DEVICE_CLOSE:
-        /* This, uh, probably requires some explanation.
-         * Press a key on another keyboard.
-         * Watch its xkbInfo get pivoted into core's.
-         * Kill the server.
-         * Watch the first device's xkbInfo get freed.
-         * Try to free ours, which points to same.
-         *
-         * ... yeah.
-         */
-        pDev->key->xkbInfo = NULL;
         pDev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
         break;
 
diff --git a/dix/events.c b/dix/events.c
index 47c52d1..808694d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4802,14 +4802,8 @@ int GetKeyboardValuatorEvents(xEvent *ev
                 mn.virtualMods = ~0; /* ??? */
                 mn.changed = XkbAllMapComponentsMask;
                 
-                /* If this is still the map we set at DEVICE_INIT, free it so
-                 * it doesn't just get lost.  (Shameful hack, sorry.) */
-                if (!inputInfo.keyboard->devPrivates[CoreDevicePrivatesIndex].ptr &&
-                    ckeyc->xkbInfo)
-                    XkbFreeInfo(ckeyc->xkbInfo);
-                /* FIXME we really need a map copy here. */
-                ckeyc->xkbInfo = pDev->key->xkbInfo;
-                XkbSendMapNotify(inputInfo.keyboard, &mn);
+                if (!XkbCopyKeymap(pDev->key->xkbInfo, ckeyc->xkbInfo))
+                    FatalError("Couldn't pivot keymap from device to core!\n");
             }
 #endif
             SendMappingNotify(MappingKeyboard, ckeyc->curKeySyms.minKeyCode,
diff --git a/xkb/xkb.h b/xkb/xkb.h
index 156608e..a85df8e 100644
--- a/xkb/xkb.h
+++ b/xkb/xkb.h
@@ -72,3 +72,7 @@ extern Bool XkbDDXCompileKeymapByNames(
     unsigned                need,
     char *                  nameRtrn,
     int                     nameRtrnLen);
+
+extern Bool XkbCopyKeymap(
+    XkbDescPtr              src,
+    XkbDescPtr              dst);
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index ee0abbe..4fa5369 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -969,3 +969,407 @@ XkbConvertCase(register KeySym sym, KeyS
         break;
     }
 }
+
+
+/**
+ * Copy an XKB map from src to dst, reallocating when necessary: if some
+ * map components are present in one, but not in the other, the destination
+ * components will be allocated or freed as necessary.
+ *
+ * Basic map consistency is assumed on both sides, so maps with random
+ * uninitialised data (e.g. names->radio_grous == NULL, names->num_rg == 19)
+ * _will_ cause failures.  You've been warned.
+ *
+ * Returns TRUE on success, or FALSE on failure.  If this function fails,
+ * dst may be in an inconsistent state: all its pointers are guaranteed
+ * to remain valid, but part of the map may be from src and part from dst.
+ */
+Bool
+XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst)
+{
+    int i = 0, j = 0;
+    void *tmp = NULL;
+    XkbKeyTypePtr stype = NULL, dtype = NULL;
+
+    if (!src || !dst)
+        return FALSE;
+
+    /* client map */
+    if (src->map) {
+        if (!dst->map) {
+            tmp = xcalloc(1, sizeof(XkbClientMapRec));
+            if (!tmp)
+                return FALSE;
+            dst->map = tmp;
+        }
+
+        if (src->map->syms) {
+            if (src->map->size_syms != dst->map->size_syms) {
+                if (dst->map->syms)
+                    tmp = xrealloc(dst->map->syms, src->map->size_syms);
+                else
+                    tmp = xalloc(src->map->size_syms);
+                if (!tmp)
+                    return FALSE;
+                dst->map->syms = tmp;
+            }
+            memcpy(dst->map->syms, src->map->syms, src->map->size_syms);
+            memcpy(dst->map->key_sym_map, src->map->key_sym_map,
+                   src->map->size_syms);
+        }
+        else {
+            if (dst->map->syms) {
+                xfree(dst->map->syms);
+                dst->map->syms = NULL;
+            }
+        }
+        dst->map->num_syms = src->map->num_syms;
+        dst->map->size_syms = src->map->size_syms;
+
+        if (src->map->types) {
+            if (src->map->size_types != dst->map->size_types) {
+                XkbKeyTypePtr stype = src->map->types;
+
+                if (dst->map->types)
+                    tmp = xrealloc(dst->map->types, src->map->size_types);
+                else
+                    tmp = xalloc(src->map->size_types);
+                if (!tmp)
+                    return FALSE;
+                dst->map->types = tmp;
+            }
+            memcpy(dst->map->types, src->map->types, src->map->size_types);
+
+            stype = src->map->types;
+            dtype = dst->map->types;
+            for (i = 0; i < dst->map->num_types; i++, dtype++, stype++) {
+                dtype->level_names = xalloc(dtype->num_levels * sizeof(Atom));
+                if (!dtype->level_names)
+                    continue; /* don't return FALSE here, try to whack all the
+                                 pointers we can, so we don't double-free when
+                                 going down. */
+                memcpy(dtype->level_names, stype->level_names,
+                       dtype->num_levels * sizeof(Atom));
+            }
+        }
+        else {
+            if (dst->map->types) {
+                for (i = 0, dtype = dst->map->types; i < dst->map->num_types;
+                     i++, dtype++)
+                    xfree(dtype->level_names);
+                xfree(dst->map->types);
+                dst->map->types = NULL;
+            }
+        }
+        dst->map->size_types = src->map->size_types;
+        dst->map->num_types = src->map->num_types;
+
+        if (src->map->modmap) {
+            if (src->max_key_code != dst->max_key_code) {
+                if (dst->map->modmap)
+                    tmp = xrealloc(dst->map->modmap, src->max_key_code + 1);
+                else
+                    tmp = xalloc(src->max_key_code + 1);
+                if (!tmp)
+                    return FALSE;
+                dst->map->syms = tmp;
+            }
+            memcpy(dst->map->modmap, src->map->modmap, src->max_key_code + 1);
+        }
+        else {
+            if (dst->map->modmap) {
+                xfree(dst->map->modmap);
+                dst->map->modmap = NULL;
+            }
+        }
+    }
+    else {
+        if (dst->map)
+            XkbFreeClientMap(dst, XkbAllClientInfoMask, True);
+    }
+
+    /* server map */
+    if (src->server) {
+        if (!dst->server) {
+            tmp = xcalloc(1, sizeof(XkbServerMapRec));
+            if (!tmp)
+                return FALSE;
+            dst->server = tmp;
+        }
+
+        if (src->server->explicit) {
+            if (src->max_key_code != dst->max_key_code) {
+                if (dst->server->explicit)
+                    tmp = xrealloc(dst->server->explicit, src->max_key_code + 1);
+                else
+                    tmp = xalloc(src->max_key_code + 1);
+                if (!tmp)
+                    return FALSE;
+                dst->server->explicit = tmp;
+            }
+            memcpy(dst->server->explicit, src->server->explicit,
+                   src->max_key_code + 1);
+        }
+        else {
+            if (dst->server->explicit) {
+                xfree(dst->server->explicit);
+                dst->server->explicit = NULL;
+            }
+        }
+
+        if (src->server->acts) {
+            if (src->server->size_acts != dst->server->size_acts) {
+                if (dst->server->acts)
+                    tmp = xrealloc(dst->server->acts, src->server->size_acts);
+                else
+                    tmp = xalloc(src->server->size_acts);
+                if (!tmp)
+                    return FALSE;
+                dst->server->acts = tmp;
+            }
+            memcpy(dst->server->acts, src->server->acts,
+                   src->server->size_acts);
+        }
+        else {
+            if (dst->server->acts) {
+                xfree(dst->server->acts);
+                dst->server->acts = NULL;
+            }
+        }
+       dst->server->size_acts = src->server->size_acts;
+
+        if (src->server->key_acts) {
+            if (src->max_key_code != dst->max_key_code) {
+                if (dst->server->key_acts)
+                    tmp = xrealloc(dst->server->key_acts, src->max_key_code + 1);
+                else
+                    tmp = xalloc(src->max_key_code + 1);
+                if (!tmp)
+                    return FALSE;
+                dst->server->key_acts = tmp;
+            }
+            memcpy(dst->server->key_acts, src->server->key_acts,
+                   src->max_key_code + 1);
+        }
+        else {
+            if (dst->server->key_acts) {
+                xfree(dst->server->key_acts);
+                dst->server->key_acts = NULL;
+            }
+        }
+
+        if (src->server->behaviors) {
+            if (src->max_key_code != dst->max_key_code) {
+                if (dst->server->behaviors)
+                    tmp = xrealloc(dst->server->behaviors,
+                                   (src->max_key_code + 1) *
+                                   sizeof(XkbBehavior));
+                else
+                    tmp = xalloc((src->max_key_code + 1) *
+                                 sizeof(XkbBehavior));
+                if (!tmp)
+                    return FALSE;
+                dst->server->behaviors = tmp;
+            }
+            memcpy(dst->server->behaviors, src->server->behaviors,
+                   (src->max_key_code + 1) * sizeof(XkbBehavior));
+        }
+        else {
+            if (dst->server->behaviors) {
+                xfree(dst->server->behaviors);
+                dst->server->behaviors = NULL;
+            }
+        }
+
+        if (src->server->vmodmap) {
+            if (src->max_key_code != dst->max_key_code) {
+                if (dst->server->vmodmap)
+                    tmp = xrealloc(dst->server->vmodmap,
+                                   src->max_key_code + 1);
+                else
+                    tmp = xalloc(src->max_key_code + 1);
+                if (!tmp)
+                    return FALSE;
+                dst->server->vmodmap = tmp;
+            }
+            memcpy(dst->server->vmodmap, src->server->vmodmap,
+                   src->max_key_code + 1);
+        }
+        else {
+            if (dst->server->vmodmap) {
+                xfree(dst->server->vmodmap);
+                dst->server->vmodmap = NULL;
+            }
+        }
+    }
+    else {
+        if (dst->server)
+            XkbFreeServerMap(dst, XkbAllServerInfoMask, True);
+    }
+
+    /* indicators */
+    if (src->indicators) {
+        if (!dst->indicators) {
+            dst->indicators = xalloc(sizeof(XkbIndicatorRec));
+            if (!dst->indicators)
+                return FALSE;
+        }
+        memcpy(dst->indicators, src->indicators, sizeof(XkbIndicatorRec));
+    }
+    else {
+        if (dst->indicators) {
+            xfree(dst->indicators);
+            dst->indicators = NULL;
+        }
+    }
+
+    /* controls */
+    if (src->ctrls) {
+        if (!dst->ctrls) {
+            dst->ctrls = xalloc(sizeof(XkbControlsRec));
+            if (!dst->ctrls)
+                return FALSE;
+        }
+        memcpy(dst->ctrls, src->ctrls, sizeof(XkbControlsRec));
+    }
+    else {
+        if (dst->ctrls) {
+            xfree(dst->ctrls);
+            dst->ctrls = NULL;
+        }
+    }
+
+    /* names */
+    if (src->names) {
+        if (!dst->names) {
+            dst->names = xcalloc(1, sizeof(XkbNamesRec));
+            if (!dst->names)
+                return FALSE;
+        }
+
+        if (src->names->keys) {
+            if (src->max_key_code != dst->max_key_code) {
+                if (dst->names->keys)
+                    tmp = xrealloc(dst->names->keys, (src->max_key_code + 1) *
+                                   sizeof(XkbKeyNameRec));
+                else
+                    tmp = xalloc((src->max_key_code + 1) *
+                                 sizeof(XkbKeyNameRec));
+                if (!tmp)
+                    return FALSE;
+                dst->names->keys = tmp;
+            }
+            memcpy(dst->names->keys, src->names->keys,
+                   (src->max_key_code + 1) * sizeof(XkbKeyNameRec));
+        }
+        else {
+            if (dst->names->keys) {
+                xfree(dst->names->keys);
+                dst->names->keys = NULL;
+            }
+        }
+
+        if (src->names->num_key_aliases) {
+            if (src->names->num_key_aliases != dst->names->num_key_aliases) {
+                if (dst->names->key_aliases)
+                    tmp = xrealloc(dst->names->key_aliases,
+                                   src->names->num_key_aliases *
+                                     sizeof(XkbKeyAliasRec));
+                else
+                    tmp = xalloc(src->names->num_key_aliases *
+                                 sizeof(XkbKeyAliasRec));
+                if (!tmp)
+                    return FALSE;
+                dst->names->key_aliases = tmp;
+            }
+            memcpy(dst->names->key_aliases, src->names->key_aliases,
+                   src->names->num_key_aliases * sizeof(XkbKeyAliasRec));
+        }
+        else {
+            if (dst->names->key_aliases) {
+                xfree(dst->names->key_aliases);
+                dst->names->key_aliases = NULL;
+            }
+        }
+        dst->names->num_key_aliases = src->names->num_key_aliases;
+
+        if (src->names->num_rg) {
+            if (src->names->num_rg != dst->names->num_rg) {
+                if (dst->names->radio_groups)
+                    tmp = xrealloc(dst->names->radio_groups,
+                                   src->names->num_rg * sizeof(Atom));
+                else
+                    tmp = xalloc(src->names->num_rg * sizeof(Atom));
+                if (!tmp)
+                    return FALSE;
+                dst->names->radio_groups = tmp;
+            }
+            memcpy(dst->names->radio_groups, src->names->radio_groups,
+                   src->names->num_rg * sizeof(Atom));
+        }
+        else {
+            if (dst->names->radio_groups)
+                xfree(dst->names->radio_groups);
+        }
+        dst->names->num_rg = src->names->num_rg;
+    }
+    else {
+        if (dst->names)
+            XkbFreeNames(dst, XkbAllNamesMask, True);
+    }
+
+    /* compat */
+    if (src->compat) {
+        if (src->compat->sym_interpret) {
+            if (src->compat->num_si != dst->compat->num_si) {
+                if (dst->compat->sym_interpret)
+                    tmp = xrealloc(dst->compat->sym_interpret,
+                                   src->compat->num_si *
+                                     sizeof(XkbSymInterpretRec));
+                else
+                    tmp = xalloc(src->compat->num_si *
+                                 sizeof(XkbSymInterpretRec));
+                if (!tmp)
+                    return FALSE;
+                dst->compat->sym_interpret = tmp;
+            }
+            memcpy(dst->compat->sym_interpret, src->compat->sym_interpret,
+                   src->compat->num_si * sizeof(XkbSymInterpretRec));
+        }
+        else {
+            if (dst->compat->sym_interpret) {
+                xfree(dst->compat->sym_interpret);
+                dst->compat->sym_interpret = NULL;
+            }
+        }
+        dst->compat->num_si = src->compat->num_si;
+
+        memcpy(dst->compat->groups, src->compat->groups,
+               XkbNumKbdGroups * sizeof(XkbModsRec));
+    }
+    else {
+        if (dst->compat)
+            XkbFreeCompatMap(dst, XkbAllCompatMask, True);
+    }
+
+    /* geometry */
+    if (src->geom) {
+        /* properties */
+        /* colors */
+        /* shapes */
+        /* sections */
+        /* doodads */
+        /* key aliases */
+        /* font?!? */
+    }
+    else {
+        if (dst->geom) {
+            XkbFreeGeometry(dst->geom, XkbGeomAllMask, True);
+        }
+    }
+
+    dst->min_key_code = src->min_key_code;
+    dst->max_key_code = src->max_key_code;
+
+    return TRUE;
+}



More information about the xorg-commit mailing list