+\f
+/* Return the parent map of the keymap MAP, or nil if it has none.
+ We assume that MAP is a valid keymap. */
+
+DEFUN ("keymap-parent", Fkeymap_parent, Skeymap_parent, 1, 1, 0,
+ "Return the parent keymap of KEYMAP.")
+ (keymap)
+ Lisp_Object keymap;
+{
+ Lisp_Object list;
+
+ keymap = get_keymap_1 (keymap, 1, 1);
+
+ /* Skip past the initial element `keymap'. */
+ list = XCONS (keymap)->cdr;
+ for (; CONSP (list); list = XCONS (list)->cdr)
+ {
+ /* See if there is another `keymap'. */
+ if (EQ (Qkeymap, XCONS (list)->car))
+ return list;
+ }
+
+ return Qnil;
+}
+
+/* Set the parent keymap of MAP to PARENT. */
+
+DEFUN ("set-keymap-parent", Fset_keymap_parent, Sset_keymap_parent, 2, 2, 0,
+ "Modify KEYMAP to set its parent map to PARENT.\n\
+PARENT should be nil or another keymap.")
+ (keymap, parent)
+ Lisp_Object keymap, parent;
+{
+ Lisp_Object list, prev;
+ int i;
+
+ keymap = get_keymap_1 (keymap, 1, 1);
+ if (!NILP (parent))
+ parent = get_keymap_1 (parent, 1, 1);
+
+ /* Skip past the initial element `keymap'. */
+ prev = keymap;
+ while (1)
+ {
+ list = XCONS (prev)->cdr;
+ /* If there is a parent keymap here, replace it.
+ If we came to the end, add the parent in PREV. */
+ if (! CONSP (list) || EQ (Qkeymap, XCONS (list)->car))
+ {
+ /* If we already have the right parent, return now
+ so that we avoid the loops below. */
+ if (EQ (XCONS (prev)->cdr, parent))
+ return parent;
+
+ XCONS (prev)->cdr = parent;
+ break;
+ }
+ prev = list;
+ }
+
+ /* Scan through for submaps, and set their parents too. */
+
+ for (list = XCONS (keymap)->cdr; CONSP (list); list = XCONS (list)->cdr)
+ {
+ /* Stop the scan when we come to the parent. */
+ if (EQ (XCONS (list)->car, Qkeymap))
+ break;
+
+ /* If this element holds a prefix map, deal with it. */
+ if (CONSP (XCONS (list)->car)
+ && CONSP (XCONS (XCONS (list)->car)->cdr))
+ fix_submap_inheritance (keymap, XCONS (XCONS (list)->car)->car,
+ XCONS (XCONS (list)->car)->cdr);
+
+ if (VECTORP (XCONS (list)->car))
+ for (i = 0; i < XVECTOR (XCONS (list)->car)->size; i++)
+ if (CONSP (XVECTOR (XCONS (list)->car)->contents[i]))
+ fix_submap_inheritance (keymap, make_number (i),
+ XVECTOR (XCONS (list)->car)->contents[i]);
+ }
+
+ return parent;
+}
+
+/* EVENT is defined in MAP as a prefix, and SUBMAP is its definition.
+ if EVENT is also a prefix in MAP's parent,
+ make sure that SUBMAP inherits that definition as its own parent. */
+
+fix_submap_inheritance (map, event, submap)
+ Lisp_Object map, event, submap;
+{
+ Lisp_Object map_parent, parent_entry;