diff src/event-Xt.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents 064ab7fed2e0
children 2f8bb876ab1d
line wrap: on
line diff
--- a/src/event-Xt.c	Mon Aug 13 11:12:06 2007 +0200
+++ b/src/event-Xt.c	Mon Aug 13 11:13:30 2007 +0200
@@ -78,6 +78,7 @@
 #include "events-mod.h"
 
 static void enqueue_Xt_dispatch_event (Lisp_Object event);
+static void handle_focus_event_1 (struct frame *f, int in_p);
 
 static struct event_stream *Xt_event_stream;
 
@@ -108,7 +109,7 @@
 /* Mask of bits indicating the descriptors that we wait for input on */
 extern SELECT_TYPE input_wait_mask, process_only_mask, tty_only_mask;
 
-static CONST String x_fallback_resources[] =
+static const String x_fallback_resources[] =
 {
   /* This file is automatically generated from the app-defaults file
      in ../etc/Emacs.ad.  These resources are consulted only if no
@@ -120,7 +121,7 @@
 
 static Lisp_Object x_keysym_to_emacs_keysym (KeySym keysym, int simple_p);
 void emacs_Xt_mapping_action (Widget w, XEvent *event);
-void debug_process_finalization (struct Lisp_Process *p);
+void debug_process_finalization (Lisp_Process *p);
 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event,
 			     Boolean *continue_to_dispatch);
 
@@ -174,6 +175,204 @@
    use a pop-up-window instead.)
  */
 
+/* For every key on the keyboard that has a known character correspondence,
+   we define the ascii-character property of the keysym, and make the
+   default binding for the key be self-insert-command.
+
+   The following magic is basically intimate knowledge of X11/keysymdef.h.
+   The keysym mappings defined by X11 are based on the iso8859 standards,
+   except for Cyrillic and Greek.
+
+   In a non-Mule world, a user can still have a multi-lingual editor, by doing
+   (set-face-font "...-iso8859-2" (current-buffer))
+   for all their Latin-2 buffers, etc.  */
+
+static Lisp_Object
+x_keysym_to_character (KeySym keysym)
+{
+#ifdef MULE
+  Lisp_Object charset = Qzero;
+#define USE_CHARSET(var,cs) \
+  ((var) = CHARSET_BY_LEADING_BYTE (LEADING_BYTE_##cs))
+#else
+#define USE_CHARSET(var,lb)
+#endif /* MULE */
+  int code = 0;
+
+  if ((keysym & 0xff) < 0xa0)
+    return Qnil;
+
+  switch (keysym >> 8)
+    {
+    case 0: /* ASCII + Latin1 */
+      USE_CHARSET (charset, LATIN_ISO8859_1);
+      code = keysym & 0x7f;
+      break;
+    case 1: /* Latin2 */
+      USE_CHARSET (charset, LATIN_ISO8859_2);
+      code = keysym & 0x7f;
+      break;
+    case 2: /* Latin3 */
+      USE_CHARSET (charset, LATIN_ISO8859_3);
+      code = keysym & 0x7f;
+      break;
+    case 3: /* Latin4 */
+      USE_CHARSET (charset, LATIN_ISO8859_4);
+      code = keysym & 0x7f;
+      break;
+    case 4: /* Katakana */
+      USE_CHARSET (charset, KATAKANA_JISX0201);
+      if ((keysym & 0xff) > 0xa0)
+	code = keysym & 0x7f;
+      break;
+    case 5: /* Arabic */
+      USE_CHARSET (charset, ARABIC_ISO8859_6);
+      code = keysym & 0x7f;
+      break;
+    case 6: /* Cyrillic */
+      {
+	static unsigned char const cyrillic[] = /* 0x20 - 0x7f */
+	{0x00, 0x72, 0x73, 0x71, 0x74, 0x75, 0x76, 0x77,
+	 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x00, 0x7e, 0x7f,
+	 0x70, 0x22, 0x23, 0x21, 0x24, 0x25, 0x26, 0x27,
+	 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x00, 0x2e, 0x2f,
+	 0x6e, 0x50, 0x51, 0x66, 0x54, 0x55, 0x64, 0x53,
+	 0x65, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
+	 0x5f, 0x6f, 0x60, 0x61, 0x62, 0x63, 0x56, 0x52,
+	 0x6c, 0x6b, 0x57, 0x68, 0x6d, 0x69, 0x67, 0x6a,
+	 0x4e, 0x30, 0x31, 0x46, 0x34, 0x35, 0x44, 0x33,
+	 0x45, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
+	 0x3f, 0x4f, 0x40, 0x41, 0x42, 0x43, 0x36, 0x32,
+	 0x4c, 0x4b, 0x37, 0x48, 0x4d, 0x49, 0x47, 0x4a};
+	USE_CHARSET (charset, CYRILLIC_ISO8859_5);
+	code = cyrillic[(keysym & 0x7f) - 0x20];
+	break;
+      }
+    case 7: /* Greek */
+      {
+	static unsigned char const greek[] = /* 0x20 - 0x7f */
+	{0x00, 0x36, 0x38, 0x39, 0x3a, 0x5a, 0x00, 0x3c,
+	 0x3e, 0x5b, 0x00, 0x3f, 0x00, 0x00, 0x35, 0x2f,
+	 0x00, 0x5c, 0x5d, 0x5e, 0x5f, 0x7a, 0x40, 0x7c,
+	 0x7d, 0x7b, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+	 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+	 0x50, 0x51, 0x53, 0x00, 0x54, 0x55, 0x56, 0x57,
+	 0x58, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+	 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+	 0x70, 0x71, 0x73, 0x72, 0x74, 0x75, 0x76, 0x77,
+	 0x78, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+	USE_CHARSET (charset, GREEK_ISO8859_7);
+	code = greek[(keysym & 0x7f) - 0x20];
+	break;
+      }
+    case 8: /* Technical */
+      break;
+    case 9: /* Special */
+      break;
+    case 10: /* Publishing */
+      break;
+    case 11: /* APL */
+      break;
+    case 12: /* Hebrew */
+      USE_CHARSET (charset, HEBREW_ISO8859_8);
+      code = keysym & 0x7f;
+      break;
+    case 13: /* Thai */
+      /* #### This needs to deal with character composition. */
+      USE_CHARSET (charset, THAI_TIS620);
+      code = keysym & 0x7f;
+      break;
+    case 14: /* Korean Hangul */
+      break;
+    case 19: /* Latin 9 - ISO8859-15 - unsupported charset. */
+      break;
+    case 32: /* Currency */
+      break;
+    default:
+      break;
+    }
+
+  if (code == 0)
+    return Qnil;
+
+#ifdef MULE
+  return make_char (MAKE_CHAR (charset, code, 0));
+#else
+  return make_char (code + 0x80);
+#endif
+}
+
+/* #### The way that keysym correspondence to characters should work:
+   - a Lisp_Event should contain a keysym AND a character slot.
+   - keybindings are tried with the keysym.  If no binding can be found,
+   and there is a corresponding character, call self-insert-command.
+
+   #### Nuke x-iso8859-1.el.
+   #### Nuke the Qascii_character property.
+   #### Nuke Vcharacter_set_property.
+*/
+static void
+maybe_define_x_key_as_self_inserting_character (KeySym keysym, Lisp_Object symbol)
+{
+  Lisp_Object character = x_keysym_to_character (keysym);
+
+  if (CHARP (character))
+    {
+      extern Lisp_Object Vcurrent_global_map;
+      extern Lisp_Object Qascii_character;
+      Fput (symbol, Qascii_character, character);
+      if (NILP (Flookup_key (Vcurrent_global_map, symbol, Qnil)))
+	Fdefine_key (Vcurrent_global_map, symbol, Qself_insert_command);
+    }
+}
+
+static void
+x_has_keysym (KeySym keysym, Lisp_Object hash_table, int with_modifiers)
+{
+  KeySym upper_lower[2];
+  int j;
+
+  if (keysym < 0x80) /* Optimize for ASCII keysyms */
+    return;
+
+  /* If you execute:
+     xmodmap -e 'keysym NN = scaron'
+     and then press (Shift scaron), X11 will return the different
+     keysym `Scaron', but  `xmodmap -pke'  might not even mention `Scaron'.
+     So we "register" both `scaron' and `Scaron'. */
+#ifdef HAVE_XCONVERTCASE
+  XConvertCase (keysym, &upper_lower[0], &upper_lower[1]);
+#else
+  upper_lower[0] = upper_lower[1] = keysym;
+#endif
+
+  for (j = 0; j < (upper_lower[0] == upper_lower[1] ? 1 : 2); j++)
+    {
+      char *name;
+      keysym = upper_lower[j];
+
+      name = XKeysymToString (keysym);
+      if (name)
+	{
+	  /* X guarantees NAME to be in the Host Portable Character Encoding */
+	  Lisp_Object sym = x_keysym_to_emacs_keysym (keysym, 0);
+	  Lisp_Object new_value = with_modifiers ? Qt : Qsans_modifiers;
+	  Lisp_Object old_value = Fgethash (sym, hash_table, Qnil);
+
+	  if (! EQ (old_value, new_value)
+	      && ! (EQ (old_value, Qsans_modifiers) &&
+		    EQ (new_value, Qt)))
+	    {
+	      maybe_define_x_key_as_self_inserting_character (keysym, sym);
+	      Fputhash (build_ext_string (name, Qbinary), new_value, hash_table);
+	      Fputhash (sym, new_value, hash_table);
+	    }
+	}
+    }
+}
+
 static void
 x_reset_key_mapping (struct device *d)
 {
@@ -211,34 +410,18 @@
       if (keysym[0] == NoSymbol)
 	continue;
 
-      {
-	char *name = XKeysymToString (keysym[0]);
-	Lisp_Object sym = x_keysym_to_emacs_keysym (keysym[0], 0);
-	if (name)
-	  {
-	    Fputhash (build_string (name), Qsans_modifiers, hash_table);
-	    Fputhash (sym, Qsans_modifiers, hash_table);
-	  }
-      }
+      x_has_keysym (keysym[0], hash_table, 0);
 
       for (j = 1; j < keysyms_per_code; j++)
 	{
 	  if (keysym[j] != keysym[0] &&
 	      keysym[j] != NoSymbol)
-	    {
-	      char *name = XKeysymToString (keysym[j]);
-	      Lisp_Object sym = x_keysym_to_emacs_keysym (keysym[j], 0);
-	      if (name && NILP (Fgethash (sym, hash_table, Qnil)))
-		{
-		  Fputhash (build_string (name), Qt, hash_table);
-		  Fputhash (sym, Qt, hash_table);
-		}
-	    }
+	    x_has_keysym (keysym[j], hash_table, 1);
 	}
     }
 }
 
-static CONST char *
+static const char *
 index_to_name (int indice)
 {
   switch (indice)
@@ -393,7 +576,7 @@
      be totally wrong. */
   if (mode_bit)
     {
-      CONST char *warn = 0;
+      const char *warn = 0;
       if      (mode_bit == meta_bit)  warn = "Meta",  meta_bit  = 0;
       else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0;
       else if (mode_bit == super_bit) warn = "Super", super_bit = 0;
@@ -807,7 +990,8 @@
   len = XmImMbLookupString (XtWindowToWidget (event->display, event->window),
 			    event, bufptr, bufsiz, &keysym, &status);
 #else /* XIM_XLIB */
-  len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
+  if (xic)
+    len = XmbLookupString (xic, event, bufptr, bufsiz, &keysym, &status);
 #endif /* HAVE_XIM */
 
 #ifdef DEBUG_XEMACS
@@ -858,10 +1042,9 @@
 	Lstream *istr;
 	struct gcpro gcpro1, gcpro2;
 
-	fb_instream =
-          make_fixed_buffer_input_stream ((unsigned char *) bufptr, len);
-
-        /* ### Use Fget_coding_system (Vcomposed_input_coding_system) */
+	fb_instream = make_fixed_buffer_input_stream (bufptr, len);
+
+        /* #### Use Fget_coding_system (Vcomposed_input_coding_system) */
 	instream =
 	  make_decoding_input_stream (XLSTREAM (fb_instream),
 				      Fget_coding_system (Qundecided));
@@ -872,7 +1055,7 @@
         while ((ch = Lstream_get_emchar (istr)) != EOF)
           {
             Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
-	    struct Lisp_Event *ev = XEVENT (emacs_event);
+	    Lisp_Event *ev          = XEVENT (emacs_event);
             ev->channel	            = DEVICE_CONSOLE (d);
             ev->event_type	    = key_press_event;
             ev->timestamp	    = event->time;
@@ -919,7 +1102,7 @@
 }
 
 static int
-x_event_to_emacs_event (XEvent *x_event, struct Lisp_Event *emacs_event)
+x_event_to_emacs_event (XEvent *x_event, Lisp_Event *emacs_event)
 {
   Display *display    = x_event->xany.display;
   struct device *d    = get_device_from_display (display);
@@ -1046,6 +1229,7 @@
 	  {
 	    XButtonEvent *ev = &x_event->xbutton;
 	    struct frame *frame = x_window_to_frame (d, ev->window);
+
 	    if (! frame)
 	      return 0;	/* not for us */
 	    XSETFRAME (emacs_event->channel, frame);
@@ -1058,7 +1242,11 @@
 	    emacs_event->event.button.button	= ev->button;
 	    emacs_event->event.button.x		= ev->x;
 	    emacs_event->event.button.y		= ev->y;
-
+	    /* because we don't seem to get a FocusIn event for button clicks
+	       when a widget-glyph is selected we will assume that we want the
+	       focus if a button gets pressed. */
+	    if (x_event->type == ButtonPress)
+	      handle_focus_event_1 (frame, 1);
 	  }
       }
     break;
@@ -1184,7 +1372,7 @@
 					    make_string ((Bufbyte *)"8bit", 4),
 					    make_ext_string ((Extbyte *)data,
 							     strlen((char *)data),
-							     FORMAT_CTEXT) ) );
+							     Qctext) ) );
 		break;
 	      case DndMIME:
 		/* we have to parse this in some way to extract
@@ -1197,7 +1385,7 @@
 		l_type = Qdragdrop_MIME;
 		l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
 						     strlen((char *)data),
-						     FORMAT_BINARY) );
+						     Qbinary) );
 		break;
 	      case DndFile:
 	      case DndDir:
@@ -1218,7 +1406,7 @@
 		   and escaping again will break them (cause % is unsave) */
 		l_dndlist = list1 ( make_ext_string ((Extbyte *)data,
 						     strlen ((char *)data),
-						     FORMAT_FILENAME) );
+						     Qfile_name) );
 		l_type = Qdragdrop_URL;
 		break;
 	      default: /* Unknown, RawData and any other type */
@@ -1226,7 +1414,7 @@
 					    make_string ((Bufbyte *)"8bit", 4),
 					    make_ext_string ((Extbyte *)data,
 							     size,
-							     FORMAT_BINARY) ) );
+							     Qbinary) ) );
 		l_type = Qdragdrop_MIME;
 		break;
 	      }
@@ -1304,6 +1492,9 @@
 static void
 handle_focus_event_1 (struct frame *f, int in_p)
 {
+#if XtSpecificationRelease > 5
+  Widget focus_widget = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f));
+#endif
 #ifdef HAVE_XIM
   XIM_focus_event (f, in_p);
 #endif /* HAVE_XIM */
@@ -1319,7 +1510,26 @@
      Actually, we half handle it: we handle it as far as changing the
      box cursor for redisplay, but we don't call any hooks or do any
      select-frame stuff until after the sit-for.
-   */
+
+     Unfortunately native widgets break the model because they grab
+     the keyboard focus and nothing sets it back again. I cannot find
+     any reasonable way to do this elsewhere so we assert here that
+     the keyboard focus is on the emacs text widget. Menus and dialogs
+     do this in their selection callback, but we don't want that since
+     a button having focus is legitimate. An edit field having focus
+     is mandatory. Weirdly you get a FocusOut event when you click in
+     a widget-glyph but you don't get a correspondng FocusIn when you
+     click in the frame. Why is this?  */
+  if (in_p
+#if XtSpecificationRelease > 5
+      && FRAME_X_TEXT_WIDGET (f) != focus_widget
+#endif
+      )
+    {
+      lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f),
+			     FRAME_X_TEXT_WIDGET (f));
+    }
+  /* do the generic event-stream stuff. */
   {
     Lisp_Object frm;
     Lisp_Object conser;
@@ -1404,7 +1614,7 @@
 
       /* Bleagh!!!!!!  Apparently some window managers (e.g. MWM)
 	 send synthetic MapNotify events when a window is first
-	 created, EVENT IF IT'S CREATED ICONIFIED OR INVISIBLE.
+	 created, EVEN IF IT'S CREATED ICONIFIED OR INVISIBLE.
 	 Or something like that.  We initially tried a different
 	 solution below, but that ran into a different window-
 	 manager bug.
@@ -1512,7 +1722,7 @@
 }
 
 static void
-emacs_Xt_handle_magic_event (struct Lisp_Event *emacs_event)
+emacs_Xt_handle_magic_event (Lisp_Event *emacs_event)
 {
   /* This function can GC */
   XEvent *event = &emacs_event->event.magic.underlying_x_event;
@@ -1540,8 +1750,13 @@
       break;
 
     case Expose:
-      x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
-			     event->xexpose.width, event->xexpose.height);
+      if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y,
+				     event->xexpose.width, event->xexpose.height)
+	  &&
+	  !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y,
+	  event->xexpose.width, event->xexpose.height))
+	x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
+			       event->xexpose.width, event->xexpose.height);
       break;
 
     case GraphicsExpose: /* This occurs when an XCopyArea's source area was
@@ -1579,6 +1794,7 @@
 
     case FocusIn:
     case FocusOut:
+
 #ifdef EXTERNAL_WIDGET
       /* External widget lossage: Ben said:
 	 YUCK.  The only way to make focus changes work properly is to
@@ -1633,14 +1849,14 @@
 /* Xt interval id's might not fit into an int (they're pointers, as it
    happens), so we need to provide a conversion list. */
 
-struct Xt_timeout
+static struct Xt_timeout
 {
   int id;
   XtIntervalId interval_id;
   struct Xt_timeout *next;
 } *pending_timeouts, *completed_timeouts;
 
-struct Xt_timeout_blocktype
+static struct Xt_timeout_blocktype
 {
   Blocktype_declare (struct Xt_timeout);
 } *the_Xt_timeout_blocktype;
@@ -1747,7 +1963,7 @@
 }
 
 static void
-Xt_timeout_to_emacs_event (struct Lisp_Event *emacs_event)
+Xt_timeout_to_emacs_event (Lisp_Event *emacs_event)
 {
   struct Xt_timeout *timeout = completed_timeouts;
   assert (timeout);
@@ -1914,7 +2130,7 @@
 }
 
 static void
-emacs_Xt_select_process (struct Lisp_Process *p)
+emacs_Xt_select_process (Lisp_Process *p)
 {
   Lisp_Object process;
   int infd = event_stream_unixoid_select_process (p);
@@ -1924,7 +2140,7 @@
 }
 
 static void
-emacs_Xt_unselect_process (struct Lisp_Process *p)
+emacs_Xt_unselect_process (Lisp_Process *p)
 {
   int infd = event_stream_unixoid_unselect_process (p);
 
@@ -1953,7 +2169,7 @@
    If we've still got pointers to it in this file, we're gonna lose hard.
  */
 void
-debug_process_finalization (struct Lisp_Process *p)
+debug_process_finalization (Lisp_Process *p)
 {
 #if 0 /* #### */
   int i;
@@ -1973,25 +2189,27 @@
 }
 
 static void
-Xt_process_to_emacs_event (struct Lisp_Event *emacs_event)
+Xt_process_to_emacs_event (Lisp_Event *emacs_event)
 {
   int i;
-  Lisp_Object process;
 
   assert (process_events_occurred > 0);
+
   for (i = 0; i < MAXDESC; i++)
     {
-      process = filedesc_with_input[i];
+      Lisp_Object process = filedesc_with_input[i];
       if (PROCESSP (process))
-	break;
+	{
+	  filedesc_with_input[i] = Qnil;
+	  process_events_occurred--;
+	  /* process events have nil as channel */
+	  emacs_event->event_type = process_event;
+	  emacs_event->timestamp  = 0; /* #### */
+	  emacs_event->event.process.process = process;
+	  return;
+	}
     }
-  assert (i < MAXDESC);
-  filedesc_with_input[i] = Qnil;
-  process_events_occurred--;
-  /* process events have nil as channel */
-  emacs_event->event_type = process_event;
-  emacs_event->timestamp  = 0; /* #### */
-  emacs_event->event.process.process = process;
+  abort ();
 }
 
 static void
@@ -1999,9 +2217,6 @@
 {
   Lisp_Object console;
   int infd;
-#ifdef HAVE_GPM
-  int mousefd;
-#endif
 
   if (CONSOLE_X_P (con))
     return; /* X consoles are automatically selected for when we
@@ -2009,22 +2224,6 @@
   infd = event_stream_unixoid_select_console (con);
   XSETCONSOLE (console, con);
   select_filedesc (infd, console);
-#ifdef HAVE_GPM
-  /* On a stream device (ie: noninteractive), bad things can happen. */
-  if (EQ (CONSOLE_TYPE (con), Qtty)) {
-    mousefd = CONSOLE_TTY_MOUSE_FD (con);
-	/* We check filedesc_to_what_closure[fd] here because if you run
-	** XEmacs from a TTY, it will fire up GPM, select the mouse fd, then
-	** if you run gnuattach to connect to another TTY, it will fire up
-	** GPM again, and try to reselect the mouse fd.  GPM uses the same
-	** fd for every connection apparently, and select_filedesc will
-	** fail its assertion if we try to select it twice.
-	*/
-    if ((mousefd >= 0) && !filedesc_to_what_closure[mousefd]) {
-      select_filedesc (mousefd, console);
-    }
-  }
-#endif
 }
 
 static void
@@ -2032,9 +2231,6 @@
 {
   Lisp_Object console;
   int infd;
-#ifdef HAVE_GPM
-  int mousefd;
-#endif
 
   if (CONSOLE_X_P (con))
     return; /* X consoles are automatically selected for when we
@@ -2042,15 +2238,6 @@
   infd = event_stream_unixoid_unselect_console (con);
   XSETCONSOLE (console, con);
   unselect_filedesc (infd);
-#ifdef HAVE_GPM
-  /* On a stream device (ie: noninteractive), bad things can happen. */
-  if (EQ (CONSOLE_TYPE (con), Qtty)) {
-    mousefd = CONSOLE_TTY_MOUSE_FD (con);
-    if (mousefd >= 0) {
-      unselect_filedesc (mousefd);
-    }
-  }
-#endif
 }
 
 /* read an event from a tty, if one is available.  Returns non-zero
@@ -2062,7 +2249,7 @@
    to be deleted.) */
 
 static int
-Xt_tty_to_emacs_event (struct Lisp_Event *emacs_event)
+Xt_tty_to_emacs_event (Lisp_Event *emacs_event)
 {
   int i;
 
@@ -2108,12 +2295,12 @@
       char *buf = alloca_array (char, XSTRING_LENGTH (f->name) + 4);
       sprintf (buf, " \"%s\"", XSTRING_DATA (f->name));
       write_string_to_stdio_stream (stderr, 0, (Bufbyte *) buf, 0,
-				    strlen (buf), FORMAT_TERMINAL);
+				    strlen (buf), Qterminal);
     }
   stderr_out ("\n");
 }
 
-static CONST char *
+static const char *
 XEvent_mode_to_string (int mode)
 {
   switch (mode)
@@ -2126,7 +2313,7 @@
   }
 }
 
-static CONST char *
+static const char *
 XEvent_detail_to_string (int detail)
 {
   switch (detail)
@@ -2142,7 +2329,7 @@
   }
 }
 
-static CONST char *
+static const char *
 XEvent_visibility_to_string (int state)
 {
   switch (state)
@@ -2347,7 +2534,7 @@
 }
 
 static void
-emacs_Xt_next_event (struct Lisp_Event *emacs_event)
+emacs_Xt_next_event (Lisp_Event *emacs_event)
 {
  we_didnt_get_an_event:
 
@@ -2732,10 +2919,10 @@
    the '#if 0'.  Note, however, that I got "unknown structure"
    errors when I tried this. */
 XtConvertArgRec Const colorConvertArgs[] = {
-  {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
-   sizeof(Screen *)},
-  {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
-   sizeof(Colormap)}
+  { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
+    sizeof (Screen *) },
+  { XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
+    sizeof (Colormap) }
 };
 
 #endif
@@ -2885,18 +3072,12 @@
 {
   defsymbol (&Qkey_mapping, "key-mapping");
   defsymbol (&Qsans_modifiers, "sans-modifiers");
+  defsymbol (&Qself_insert_command, "self-insert-command");
 }
 
 void
-vars_of_event_Xt (void)
+reinit_vars_of_event_Xt (void)
 {
-  dispatch_event_queue = Qnil;
-  staticpro (&dispatch_event_queue);
-  dispatch_event_queue_tail = Qnil;
-
-  /* this function only makes safe calls */
-  init_what_input_once ();
-
   Xt_event_stream = xnew (struct event_stream);
   Xt_event_stream->event_pending_p 	 = emacs_Xt_event_pending_p;
   Xt_event_stream->next_event_cb	 = emacs_Xt_next_event;
@@ -2911,6 +3092,24 @@
   Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair;
   Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair;
 
+  the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
+
+  last_quit_check_signal_tick_count = 0;
+
+  /* this function only makes safe calls */
+  init_what_input_once ();
+}
+
+void
+vars_of_event_Xt (void)
+{
+  reinit_vars_of_event_Xt ();
+
+  dispatch_event_queue = Qnil;
+  staticpro (&dispatch_event_queue);
+  dispatch_event_queue_tail = Qnil;
+  pdump_wire (&dispatch_event_queue_tail);
+
   DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /*
 *Non-nil makes modifier keys sticky.
 This means that you can release the modifier key before pressing down
@@ -2936,10 +3135,6 @@
 */ );
   x_debug_events = 0;
 #endif
-
-  the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
-
-  last_quit_check_signal_tick_count = 0;
 }
 
 /* This mess is a hack that patches the shell widget to treat visual inheritance