diff src/keymap.c @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents 7e54bd776075
children 54cc21c15cbb
line wrap: on
line diff
--- a/src/keymap.c	Mon Aug 13 09:00:04 2007 +0200
+++ b/src/keymap.c	Mon Aug 13 09:02:59 2007 +0200
@@ -21,8 +21,9 @@
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-/* Synched up with: Not synched with FSF.  Substantially different
-   from FSF. */
+/* Synched up with: Mule 2.0.  Not synched with FSF.  Substantially
+   different from FSF. */
+
 
 #include <config.h>
 #include "lisp.h"
@@ -46,12 +47,12 @@
 		   Keymaps can thus be arranged in a hierarchy.
 
    table	   A hash table, hashing keysyms to their bindings.
-		   As in the rest of emacs, a keysym is either a symbol or
-		   an integer, which is an ASCII code (of one of the printing
-		   ASCII characters: not 003 meaning C-c, for instance).
-		   It can also be an integer representing a modifier
-		   combination; this will be greater than or equal to
-		   (1 << 16).
+   		   It will be one of the following:
+
+		   -- a symbol, e.g. 'home
+		   -- a character, representing something printable
+		      (not ?\C-c meaning C-c, for instance)
+		   -- an integer representing a modifier combination
 
    inverse_table   A hash table, hashing bindings to the list of keysyms
 		   in this keymap which are bound to them.  This is to make
@@ -83,29 +84,29 @@
    keymap hierarchy as well. (This lets us use EQable objects as hash keys.)
    Each combination of modifiers (e.g. control-hyper) gets its own submap
    off of the main map.  The hash key for a modifier combination is
-   a large integer, computed by MAKE_MODIFIER_HASH_KEY().
+   an integer, computed by MAKE_MODIFIER_HASH_KEY().
    
    If the key `C-a' was bound to some command, the hierarchy would look like
 
-      keymap-1: associates the integer (MOD_CONTROL << 16) with keymap-2
+      keymap-1: associates the integer MOD_CONTROL with keymap-2
       keymap-2: associates "a" with the command
 
    Similarly, if the key `C-H-a' was bound to some command, the hierarchy
    would look like
 
-      keymap-1: associates the integer ((MOD_CONTROL | MOD_HYPER) << 16)
+      keymap-1: associates the integer (MOD_CONTROL | MOD_HYPER)
                 with keymap-2
       keymap-2: associates "a" with the command
 
    Note that a special exception is made for the meta modifier, in order
    to deal with ESC/meta lossage.  Any key combination containing the
    meta modifier is first indexed off of the main map into the meta
-   submap (with hash key (MOD_META << 16)) and then indexed off of the
+   submap (with hash key MOD_META) and then indexed off of the
    meta submap with the meta modifier removed from the key combination.
    For example, when associating a command with C-M-H-a, we'd have
 
-      keymap-1: associates the integer (MOD_META << 16) with keymap-2
-      keymap-2: associates the integer ((MOD_CONTROL | MOD_HYPER) << 16)
+      keymap-1: associates the integer MOD_META with keymap-2
+      keymap-2: associates the integer (MOD_CONTROL | MOD_HYPER)
                 with keymap-3
       keymap-3: associates "a" with the command
 
@@ -119,7 +120,7 @@
    Note that this new model of keymaps takes much of the magic away from
    the Escape key: the value of the variable `esc-map' is no longer indexed
    in the `global-map' under the ESC key.  It's indexed under the integer
-   (MOD_META << 16).  This is not user-visible, however; none of the "bucky"
+   MOD_META.  This is not user-visible, however; none of the "bucky"
    maps are.
 
    There is a hack in Flookup_key() that makes (lookup-key global-map "\^[")
@@ -177,10 +178,8 @@
 #define KEYMAPP(x) RECORDP (x, keymap)
 #define CHECK_KEYMAP(x) CHECK_RECORD (x, keymap)
 
-/* Hash key is shifted so it can't conflict with eight-bit
-   string-char constituents */
-#define MAKE_MODIFIER_HASH_KEY(modifier) (make_int ((modifier) << 16))
-#define MODIFIER_HASH_KEY_BITS(x) ((INTP((x))) ? (XINT ((x)) >> 16) : 0)
+#define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier)
+#define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0)
 
 
 
@@ -228,9 +227,6 @@
 Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up, Qbutton4up,
   Qbutton5up, Qbutton6up, Qbutton7up;
 Lisp_Object Qmenu_selection;
-/* Emacs compatibility */
-Lisp_Object Qdown_mouse_1, Qdown_mouse_2, Qdown_mouse_3;
-Lisp_Object Qmouse_1, Qmouse_2, Qmouse_3;
 
 /* Kludge kludge kludge */
 Lisp_Object QLFD, QTAB, QRET, QESC, QDEL, QSPC, QBS;
@@ -439,7 +435,7 @@
   Lisp_Object keysym = key->keysym;
   unsigned int modifiers = key->modifiers;
 
-  if (prettify && INTP (keysym))
+  if (prettify && CHARP (keysym))
     {
       /* This is a little slow, but (control a) is prettier than (control 65).
 	 It's now ok to do this for digit-chars too, since we've fixed the
@@ -1238,29 +1234,39 @@
 /*                        Defining keys in keymaps                      */
 /************************************************************************/
 
+/* Given a keysym (should be a symbol, int, char), make sure it's valid
+   and perform any necessary canonicalization. */
+
 static void
-define_key_check_keysym (Lisp_Object spec,
-                         Lisp_Object *keysym, unsigned int modifiers)
+define_key_check_and_coerce_keysym (Lisp_Object spec,
+				    Lisp_Object *keysym,
+				    unsigned int modifiers)
 {
   /* Now, check and massage the trailing keysym specifier. */
   if (SYMBOLP (*keysym))
     {
-      if (string_length (XSYMBOL (*keysym)->name) == 1)
+      if (string_char_length (XSYMBOL (*keysym)->name) == 1)
 	{
-	  *keysym = make_int (string_char (XSYMBOL (*keysym)->name, 0));
+	  Lisp_Object ream_gcc_up_the_ass =
+	    make_char (string_char (XSYMBOL (*keysym)->name, 0));
+	  *keysym = ream_gcc_up_the_ass;
 	  goto fixnum_keysym;
 	}
     }
-  else if (INTP (*keysym))
+  else if (CHAR_OR_CHAR_INTP (*keysym))
     {
+      CHECK_CHAR_COERCE_INT (*keysym);
     fixnum_keysym:
-      if (XINT (*keysym) < ' ' || XINT (*keysym) > 255)
-	signal_simple_error ("keysym must be in the range 32 - 255",
-			     *keysym);
+      if (XCHAR (*keysym) < ' '
+	  /* || (XCHAR (*keysym) >= 128 && XCHAR (*keysym) < 160) */)
+	/* yuck!  Can't make the above restriction; too many compatibility
+	   problems ... */
+	signal_simple_error ("keysym char must be printable", *keysym);
       /* #### This bites!  I want to be able to write (control shift a) */
       if (modifiers & MOD_SHIFT)
-	signal_simple_error ("the `shift' modifier may not be applied to ASCII keysyms",
-			     spec);
+	signal_simple_error
+	  ("the `shift' modifier may not be applied to ASCII keysyms",
+	   spec);
     }
   else
     {
@@ -1268,49 +1274,83 @@
 			   *keysym);
     }
 
-  /* Code semi-snarfed from v20. */
   if (SYMBOLP (*keysym))
     {
       char *name = (char *)
 	string_data (XSYMBOL (*keysym)->name);
 
-      if (!strncmp(name, "kp_", 3)) {
-	/* Likewise, the obsolete keysym binding of kp_.* should not lose. */
-	char temp[50];
-
-	strncpy(temp, name, sizeof (temp));
-	temp[sizeof (temp) - 1] = '\0';
-	temp[2] = '-';
-	*keysym = Fintern_soft(make_string((Bufbyte *)temp,
-					   strlen(temp)),
-			       Qnil);
-      }
-      /* Emacs compatibility */
-      else if (EQ(*keysym, Qdown_mouse_1))
-	*keysym = Qbutton1;
-      else if (EQ(*keysym, Qdown_mouse_2))
-	*keysym = Qbutton2;
-      else if (EQ(*keysym, Qdown_mouse_3))
-	*keysym = Qbutton3;
-      else if (EQ(*keysym, Qmouse_1))
-	*keysym = Qbutton1up;
-      else if (EQ(*keysym, Qmouse_2))
-	*keysym = Qbutton2up;
-      else if (EQ(*keysym, Qmouse_3))
-	*keysym = Qbutton3up;
+      /* FSFmacs uses symbols with the printed representation of keysyms in
+	 their names, like 'M-x, and we use the syntax '(meta x).  So, to avoid
+	 confusion, notice the M-x syntax and signal an error - because
+	 otherwise it would be interpreted as a regular keysym, and would even
+	 show up in the list-buffers output, causing confusion to the naive.
+
+	 We can get away with this because none of the X keysym names contain
+	 a hyphen (some contain underscore, however).
+
+	 It might be useful to reject keysyms which are not x-valid-keysym-
+	 name-p, but that would interfere with various tricks we do to
+	 sanitize the Sun keyboards, and would make it trickier to
+	 conditionalize a .emacs file for multiple X servers.
+	 */
+      if (((int) strlen (name) >= 2 && name[1] == '-')
+#if 1
+          ||
+	  /* Ok, this is a bit more dubious - prevent people from doing things
+	     like (global-set-key 'RET 'something) because that will have the
+	     same problem as above.  (Gag!)  Maybe we should just silently
+	     accept these as aliases for the "real" names?
+	     */
+	  (string_length (XSYMBOL (*keysym)->name) < 4 &&
+	   (!strcmp (name, "LFD") ||
+	    !strcmp (name, "TAB") ||
+	    !strcmp (name, "RET") ||
+	    !strcmp (name, "ESC") ||
+	    !strcmp (name, "DEL") ||
+	    !strcmp (name, "SPC") ||
+	    !strcmp (name, "BS")))
+#endif /* unused */
+          )
+	signal_simple_error
+          ("Invalid (FSF Emacs) key format (see doc of define-key)",
+	   *keysym);
+
+      /* #### Ok, this is a bit more dubious - make people not lose if they
+	 do things like (global-set-key 'RET 'something) because that would
+	 otherwise have the same problem as above.  (Gag!)  We silently
+	 accept these as aliases for the "real" names.
+	 */
+      else if (EQ (*keysym, QLFD))
+	*keysym = QKlinefeed;
+      else if (EQ (*keysym, QTAB))
+	*keysym = QKtab;
+      else if (EQ (*keysym, QRET))
+	*keysym = QKreturn;
+      else if (EQ (*keysym, QESC))
+	*keysym = QKescape;
+      else if (EQ (*keysym, QDEL))
+	*keysym = QKdelete;
+      else if (EQ (*keysym, QBS))
+	*keysym = QKbackspace;
     }
 }
 
+
 /* Given any kind of key-specifier, return a keysym and modifier mask.
+   Proper canonicalization is performed:
+
+   -- integers are converted into the equivalent characters.
+   -- one-character strings are converted into the equivalent characters.
  */
+
 static void
 define_key_parser (Lisp_Object spec, struct key_data *returned_value)
 {
-  if (INTP (spec))
+  if (CHAR_OR_CHAR_INTP (spec))
     {
       struct Lisp_Event event;
       event.event_type = empty_event;
-      character_to_event (XINT (spec), &event,
+      character_to_event (XCHAR_OR_CHAR_INT (spec), &event,
 			  XCONSOLE (Vselected_console), 0);
       returned_value->keysym = event.event.key.keysym;
       returned_value->modifiers = event.event.key.modifiers;
@@ -1363,7 +1403,7 @@
       /* Be nice, allow = to mean (=) */
       if (bucky_sym_to_bucky_bit (spec) != 0)
         signal_simple_error ("Key is a modifier name", spec);
-      define_key_check_keysym (spec, &spec, 0);
+      define_key_check_and_coerce_keysym (spec, &spec, 0);
       returned_value->keysym = spec;
       returned_value->modifiers = 0;
     }
@@ -1398,7 +1438,7 @@
       if (!NILP (rest))
         signal_simple_error ("dotted list", spec);
 
-      define_key_check_keysym (spec, &keysym, modifiers);
+      define_key_check_and_coerce_keysym (spec, &keysym, modifiers);
       returned_value->keysym = keysym;
       returned_value->modifiers = modifiers;
     }
@@ -1407,81 +1447,6 @@
       signal_simple_error ("unknown key-sequence specifier",
 			   spec);
     }
-
-  /* Convert single-character symbols into ints, since that's the
-     way the events arrive from the keyboard... */
-  if (SYMBOLP (returned_value->keysym) &&
-      string_length (XSYMBOL (returned_value->keysym)->name) == 1)
-    {
-      returned_value->keysym =
-	make_int (string_char (XSYMBOL (returned_value->keysym)->name, 0));
-
-      /* Detect bogus (user-provided) keysyms like '\?C-a;
-         We can't do that for '\?M-a because that interferes with
-         legitimate 8-bit input. */
-      if (XINT (returned_value->keysym) < ' ' ||
-	  XINT (returned_value->keysym) > 255)
-	signal_simple_error ("keysym must be in the range 32 - 255",
-			     returned_value->keysym);
-    }
-
-  if (SYMBOLP (returned_value->keysym))
-    {
-      char *name = (char *) string_data (XSYMBOL (returned_value->keysym)->name);
-
-      /* FSFmacs uses symbols with the printed representation of keysyms in
-	 their names, like 'M-x, and we use the syntax '(meta x).  So, to avoid
-	 confusion, notice the M-x syntax and signal an error - because
-	 otherwise it would be interpreted as a regular keysym, and would even
-	 show up in the list-buffers output, causing confusion to the naive.
-
-	 We can get away with this because none of the X keysym names contain
-	 a hyphen (some contain underscore, however).
-
-	 It might be useful to reject keysyms which are not x-valid-keysym-
-	 name-p, but that would interfere with various tricks we do to
-	 sanitize the Sun keyboards, and would make it trickier to
-	 conditionalize a .emacs file for multiple X servers.
-	 */
-      if (((unsigned int) strlen (name) >= 2 && name[1] == '-')
-#if 1
-          ||
-	  /* Ok, this is a bit more dubious - prevent people from doing things
-	     like (global-set-key 'RET 'something) because that will have the
-	     same problem as above.  (Gag!)  Maybe we should just silently
-	     accept these as aliases for the "real" names?
-	     */
-	  (string_length (XSYMBOL (returned_value->keysym)->name) < 4 &&
-	   (!strcmp (name, "LFD") ||
-	    !strcmp (name, "TAB") ||
-	    !strcmp (name, "RET") ||
-	    !strcmp (name, "ESC") ||
-	    !strcmp (name, "DEL") ||
-	    !strcmp (name, "SPC") ||
-	    !strcmp (name, "BS")))
-#endif /* unused */
-          )
-	signal_simple_error ("invalid keysym (see doc of define-key)",
-			     returned_value->keysym);
-
-      /* #### Ok, this is a bit more dubious - make people not lose if they
-	 do things like (global-set-key 'RET 'something) because that would
-	 otherwise have the same problem as above.  (Gag!)  We silently
-	 accept these as aliases for the "real" names.
-	 */
-      else if (EQ (returned_value->keysym, QLFD))
-	returned_value->keysym = QKlinefeed;
-      else if (EQ (returned_value->keysym, QTAB))
-	returned_value->keysym = QKtab;
-      else if (EQ (returned_value->keysym, QRET))
-	returned_value->keysym = QKreturn;
-      else if (EQ (returned_value->keysym, QESC))
-	returned_value->keysym = QKescape;
-      else if (EQ (returned_value->keysym, QDEL))
-	returned_value->keysym = QKdelete;
-      else if (EQ (returned_value->keysym, QBS))
-	returned_value->keysym = QKbackspace;
-    }
 }
 
 /* Used by character-to-event */
@@ -1539,14 +1504,15 @@
   struct gcpro gcpro1;
 
   if (event->event_type != key_press_event || NILP (key_specifier) ||
-      (INTP (key_specifier) && XINT (key_specifier) < 0))
+      (INTP (key_specifier) && !CHAR_INTP (key_specifier)))
     return 0;
 
   /* if the specifier is an integer such as 27, then it should match
      both of the events 'escape' and 'control ['.  Calling
      Fcharacter_to_event() will only match 'escape'. */
-  if (INTP (key_specifier))
-    return XINT (key_specifier) == event_to_character (event, 0, 0, 0);
+  if (CHAR_OR_CHAR_INTP (key_specifier))
+    return (XCHAR_OR_CHAR_INT (key_specifier)
+	    == event_to_character (event, 0, 0, 0));
 
   /* Otherwise, we cannot call event_to_character() because we may
      be dealing with non-ASCII keystrokes.  In any case, if I ask
@@ -1677,7 +1643,7 @@
   struct key_data meta_key;
 
   if (NILP (Vmeta_prefix_char) ||
-      (INTP (Vmeta_prefix_char) && XINT (Vmeta_prefix_char) < 0))
+      (INTP (Vmeta_prefix_char) && !CHAR_INTP (Vmeta_prefix_char)))
     return;
 
   define_key_parser (Vmeta_prefix_char, &meta_key);
@@ -1700,17 +1666,15 @@
     abort ();
   if (EQ (keys, new_keys))
     sprintf (buf, GETTEXT ("can't bind %s: %s has a non-keymap binding"),
-	     (char *) string_data (XSTRING (Fkey_description (keys))),
-	     (char *) string_data (XSTRING
-				   (Fsingle_key_description 
-				    (Vmeta_prefix_char))));
+	     (char *) XSTRING_DATA (Fkey_description (keys)),
+	     (char *) XSTRING_DATA (Fsingle_key_description
+				    (Vmeta_prefix_char)));
   else
     sprintf (buf, GETTEXT ("can't bind %s: %s %s has a non-keymap binding"),
-	     (char *) string_data (XSTRING (Fkey_description (keys))),
-	     (char *) string_data (XSTRING (Fkey_description (new_keys))),
-	     (char *) string_data (XSTRING
-				   (Fsingle_key_description
-				    (Vmeta_prefix_char))));
+	     (char *) XSTRING_DATA (Fkey_description (keys)),
+	     (char *) XSTRING_DATA (Fkey_description (new_keys)),
+	     (char *) XSTRING_DATA (Fsingle_key_description
+				    (Vmeta_prefix_char)));
   signal_simple_error (buf, mpc_binding);
 }
 
@@ -1827,8 +1791,8 @@
   if (VECTORP (keys))
     size = vector_length (XVECTOR (keys));
   else if (STRINGP (keys))
-    size = string_length (XSTRING (keys));
-  else if (INTP (keys) || SYMBOLP (keys) || CONSP (keys))
+    size = string_char_length (XSTRING (keys));
+  else if (CHAR_OR_CHAR_INTP (keys) || SYMBOLP (keys) || CONSP (keys))
     {
       if (!CONSP (keys)) keys = list1 (keys);
       size = 1;
@@ -1867,12 +1831,7 @@
       if (STRINGP (keys))
 	c = make_char (string_char (XSTRING (keys), idx));
       else
-	{
-	  c = vector_data (XVECTOR (keys)) [idx];
-	  if (INTP (c) &&
-	      (XINT (c) < ' ' || XINT (c) > 127))
-	    args_out_of_range_3 (c, make_int (32), make_int (127));
-	}
+	c = vector_data (XVECTOR (keys)) [idx];
 
       define_key_parser (c, &raw_key1);
 
@@ -2110,7 +2069,7 @@
   if (nkeys == 0)
     return Qnil;
 
-  if (nkeys < (countof (kkk)))
+  if (nkeys > (countof (kkk)))
     raw_keys = kkk;
   else
     raw_keys = (struct key_data *) alloca (sizeof (struct key_data) * nkeys);
@@ -2189,7 +2148,7 @@
                           vector_data (XVECTOR (keys)),
                           !NILP (accept_default));
     }
-  else if (SYMBOLP (keys) || INTP (keys) || CONSP (keys))
+  else if (SYMBOLP (keys) || CHAR_OR_CHAR_INTP (keys) || CONSP (keys))
     {
       return lookup_keys (keymap, 1, &keys,
 			  !NILP (accept_default));
@@ -2381,11 +2340,8 @@
 
 	      if (!EQ (buffer, Vmouse_grabbed_buffer)) /* already pushed */
 		{
-		  Lisp_Object map = XBUFFER (buffer)->keymap;
-
 		  get_relevant_minor_maps (buffer, &closure);
-		  if (!NILP(map))
-		    relevant_map_push (map, &closure);
+		  relevant_map_push (XBUFFER (buffer)->keymap, &closure);
 		}
 	    }
 	}
@@ -2624,8 +2580,6 @@
   assert (EVENTP (event0));
 
   nmaps = get_relevant_keymaps (event0, countof (maps), maps);
-  if (nmaps > countof (maps))
-    nmaps = countof (maps);
   return (process_event_binding_result
 	  (lookup_events (event0, nmaps, maps, accept_default)));
 }
@@ -2814,14 +2768,22 @@
   if (! bit1 && SYMBOLP (obj1))
     {
       Lisp_Object code = Fget (obj1, Vcharacter_set_property, Qnil);
-      if (INTP (code))
-	obj1 = code, sym1_p = 1;
+      if (CHAR_OR_CHAR_INTP (code))
+	{
+	  obj1 = code;
+	  CHECK_CHAR_COERCE_INT (obj1);
+	  sym1_p = 1;
+	}
     }
   if (! bit2 && SYMBOLP (obj2))
     {
       Lisp_Object code = Fget (obj2, Vcharacter_set_property, Qnil);
-      if (INTP (code))
-	obj2 = code, sym2_p = 1;
+      if (CHAR_OR_CHAR_INTP (code))
+	{
+	  obj2 = code;
+	  CHECK_CHAR_COERCE_INT (obj2);
+	  sym2_p = 1;
+	}
     }
 
   /* all symbols (non-ASCIIs) come after characters (ASCIIs) */
@@ -2962,7 +2924,7 @@
 Otherwise, they will be passed in hash (that is, random) order, which is
 faster.
 */
-       (function, keymap, sort_first))
+     (function, keymap, sort_first))
 {
   /* This function can GC */
   struct gcpro gcpro1, gcpro2;
@@ -3144,7 +3106,8 @@
 */
        (keys))
 {
-  if (INTP (keys) || CONSP (keys) || SYMBOLP (keys) || EVENTP (keys))
+  if (CHAR_OR_CHAR_INTP (keys) || CONSP (keys) || SYMBOLP (keys)
+      || EVENTP (keys))
     {
       return Fsingle_key_description (keys);
     }
@@ -3187,7 +3150,7 @@
   if (SYMBOLP (key))
     key = Fcons (key, Qnil); /* sleaze sleaze */
 
-  if (EVENTP (key) || CHARP (key))
+  if (EVENTP (key) || CHAR_OR_CHAR_INTP (key))
     {
       char buf [255];
       if (!EVENTP (key))
@@ -3220,8 +3183,12 @@
 	  else if (EQ (keysym, Qhyper)) strcpy (bufp, "H-"), bufp += 2;
 	  else if (EQ (keysym, Qalt))	strcpy (bufp, "A-"), bufp += 2;
 	  else if (EQ (keysym, Qshift)) strcpy (bufp, "Sh-"), bufp += 3;
-	  else if (INTP (keysym))
-	    *bufp = XINT (keysym), bufp++, *bufp = 0;
+	  else if (CHAR_OR_CHAR_INTP (keysym))
+	    {
+	      bufp += set_charptr_emchar ((Bufbyte *) bufp,
+					  XCHAR_OR_CHAR_INT (keysym));
+	      *bufp = 0;
+	    }
 	  else
 	    {
 	      CHECK_SYMBOL (keysym);
@@ -3261,10 +3228,10 @@
   unsigned int c;
   Lisp_Object ctl_arrow = current_buffer->ctl_arrow;
   int ctl_p = !NILP (ctl_arrow);
-  int printable_min = (INTP (ctl_arrow)
-		       ? XINT (ctl_arrow)
-		       : ((EQ (ctl_arrow, Qt) || EQ (ctl_arrow, Qnil))
-			  ? 256 : 160));
+  Emchar printable_min = (CHAR_OR_CHAR_INTP (ctl_arrow)
+			  ? XCHAR_OR_CHAR_INT (ctl_arrow)
+			  : ((EQ (ctl_arrow, Qt) || NILP (ctl_arrow))
+			     ? 256 : 160));
 
   if (EVENTP (chr))
     {
@@ -3298,6 +3265,18 @@
   else if (c >= 0200 || c < 040)
     {
       *p++ = '\\';
+#ifdef MULE
+      /* !!#### This syntax is not readable.  It will
+	 be interpreted as a 3-digit octal number rather
+	 than a 7-digit octal number. */
+      if (c >= 0400)
+	{
+	  *p++ = '0' + ((c & 07000000) >> 18);
+	  *p++ = '0' + ((c & 0700000) >> 15);
+	  *p++ = '0' + ((c & 070000) >> 12);
+	  *p++ = '0' + ((c & 07000) >> 9);
+	}
+#endif
       *p++ = '0' + ((c & 0700) >> 6);
       *p++ = '0' + ((c & 0070) >> 3);
       *p++ = '0' + ((c & 0007));
@@ -3990,13 +3969,21 @@
   if (SYMBOLP (s1))
     {
       Lisp_Object code = Fget (s1, Vcharacter_set_property, Qnil);
-      if (INTP (code)) s1 = code;
+      if (CHAR_OR_CHAR_INTP (code))
+	{
+	  s1 = code;
+	  CHECK_CHAR_COERCE_INT (s1);
+	}
       else return 0;
     }
   if (SYMBOLP (s2))
     {
       Lisp_Object code = Fget (s2, Vcharacter_set_property, Qnil);
-      if (INTP (code)) s2 = code;
+      if (CHAR_OR_CHAR_INTP (code))
+	{
+	  s2 = code;
+	  CHECK_CHAR_COERCE_INT (s2);
+	}
       else return 0;
     }
 
@@ -4201,12 +4188,6 @@
   defsymbol (&Qbutton5up, "button5up");
   defsymbol (&Qbutton6up, "button6up");
   defsymbol (&Qbutton7up, "button7up");
-  defsymbol (&Qmouse_1, "mouse-1");
-  defsymbol (&Qmouse_2, "mouse-2");
-  defsymbol (&Qmouse_3, "mouse-3");
-  defsymbol (&Qdown_mouse_1, "down-mouse-1");
-  defsymbol (&Qdown_mouse_2, "down-mouse-2");
-  defsymbol (&Qdown_mouse_3, "down-mouse-3");
   defsymbol (&Qmenu_selection, "menu-selection");
   defsymbol (&QLFD, "LFD");
   defsymbol (&QTAB, "TAB");