]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
Merged from emacs@sv.gnu.org
[gnu-emacs] / src / xterm.c
index 42c860b64c99395277a0de0886ce2401028802a0..378373fe79138af4554b8b1088f0cd773c7a900f 100644 (file)
@@ -1,6 +1,6 @@
 /* X Communication module for terminals which understand the X protocol.
    Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-                 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+                 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -325,11 +325,10 @@ static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
 static const XColor *x_color_cells P_ ((Display *, int *));
 static void x_update_window_end P_ ((struct window *, int, int));
 void x_delete_display P_ ((struct x_display_info *));
-static unsigned int x_x_to_emacs_modifiers P_ ((struct x_display_info *,
-                                               unsigned));
+
 static int x_io_error_quitter P_ ((Display *));
-int x_catch_errors P_ ((Display *));
-void x_uncatch_errors P_ ((Display *, int));
+void x_catch_errors P_ ((Display *));
+void x_uncatch_errors P_ ((void));
 void x_lower_frame P_ ((struct frame *));
 void x_scroll_bar_clear P_ ((struct frame *));
 int x_had_errors_p P_ ((Display *));
@@ -338,15 +337,15 @@ void x_raise_frame P_ ((struct frame *));
 void x_set_window_size P_ ((struct frame *, int, int, int));
 void x_wm_set_window_state P_ ((struct frame *, int));
 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
-struct device *x_create_device P_ ((struct x_display_info *));
-void x_delete_device P_ ((struct device *));
+static struct terminal *x_create_terminal P_ ((struct x_display_info *));
+void x_delete_terminal P_ ((struct terminal *));
 void x_initialize P_ ((void));
 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
 static int x_compute_min_glyph_bounds P_ ((struct frame *));
 static void x_update_end P_ ((struct frame *));
 static void XTframe_up_to_date P_ ((struct frame *));
-static void XTset_terminal_modes P_ ((struct device *));
-static void XTreset_terminal_modes P_ ((struct device *));
+static void XTset_terminal_modes P_ ((struct terminal *));
+static void XTreset_terminal_modes P_ ((struct terminal *));
 static void x_clear_frame P_ ((struct frame *));
 static void frame_highlight P_ ((struct frame *));
 static void frame_unhighlight P_ ((struct frame *));
@@ -806,7 +805,7 @@ x_draw_fringe_bitmap (w, row, p)
    rarely happens).  */
 
 static void
-XTset_terminal_modes (struct device *device)
+XTset_terminal_modes (struct terminal *terminal)
 {
 }
 
@@ -814,7 +813,7 @@ XTset_terminal_modes (struct device *device)
    the X-windows go away, and suspending requires no action.  */
 
 static void
-XTreset_terminal_modes (struct device *device)
+XTreset_terminal_modes (struct terminal *terminal)
 {
 }
 
@@ -3470,7 +3469,7 @@ x_find_modifier_meanings (dpyinfo)
 /* Convert between the modifier bits X uses and the modifier bits
    Emacs uses.  */
 
-static unsigned int
+unsigned int
 x_x_to_emacs_modifiers (dpyinfo, state)
      struct x_display_info *dpyinfo;
      unsigned int state;
@@ -3598,6 +3597,9 @@ note_mouse_movement (frame, event)
   last_mouse_motion_event = *event;
   XSETFRAME (last_mouse_motion_frame, frame);
 
+  if (!FRAME_X_OUTPUT (frame))
+    return 0;
+
   if (event->window != FRAME_X_WINDOW (frame))
     {
       frame->mouse_moved = 1;
@@ -3724,7 +3726,6 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
        Window win, child;
        int win_x, win_y;
        int parent_x = 0, parent_y = 0;
-       int count;
 
        win = root;
 
@@ -3732,7 +3733,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
           structure is changing at the same time this function
           is running.  So at least we must not crash from them.  */
 
-       count = x_catch_errors (FRAME_X_DISPLAY (*fp));
+       x_catch_errors (FRAME_X_DISPLAY (*fp));
 
        if (FRAME_X_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
            && FRAME_LIVE_P (last_mouse_frame))
@@ -3801,7 +3802,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
        if (x_had_errors_p (FRAME_X_DISPLAY (*fp)))
          f1 = 0;
 
-       x_uncatch_errors (FRAME_X_DISPLAY (*fp), count);
+       x_uncatch_errors ();
 
        /* If not, is it one of our scroll bars?  */
        if (! f1)
@@ -5673,7 +5674,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
   int count = 0;
   int do_help = 0;
   int nbytes = 0;
-  struct frame *f;
+  struct frame *f = NULL;
   struct coding_system coding;
   XEvent event = *eventp;
 
@@ -5724,7 +5725,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                     Display *d = event.xclient.display;
                     /* Catch and ignore errors, in case window has been
                        iconified by a window manager such as GWM.  */
-                    int count = x_catch_errors (d);
+                    x_catch_errors (d);
                     XSetInputFocus (d, event.xclient.window,
                                     /* The ICCCM says this is
                                        the only valid choice.  */
@@ -5733,7 +5734,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                     /* This is needed to detect the error
                        if there is an error.  */
                     XSync (d, False);
-                    x_uncatch_errors (d, count);
+                    x_uncatch_errors ();
                   }
                 /* Not certain about handling scroll bars here */
 #endif /* 0 */
@@ -6255,23 +6256,40 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
            }
 
          /* Keysyms directly mapped to supported Unicode characters.  */
-         if ((keysym >= 0x01000100 && keysym <= 0x010033ff)
+         if ((keysym >= 0x01000000 && keysym <= 0x010033ff)
              || (keysym >= 0x0100e000 && keysym <= 0x0100ffff))
            {
-             int code, charset_id, c1, c2;
-
-             if (keysym < 0x01002500)
-               charset_id = charset_mule_unicode_0100_24ff,
-                 code = (keysym & 0xFFFF) - 0x100;
-             else if (keysym < 0x0100e000)
-               charset_id = charset_mule_unicode_2500_33ff,
-                 code = (keysym & 0xFFFF) - 0x2500;
+             int code = keysym & 0xFFFF, charset_id, c1, c2;
+
+             if (code < 0x80)
+               {
+                 inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+                 inev.ie.code = code;
+               }
+             else if (code < 0x100)
+               {
+                 if (code < 0xA0)
+                   charset_id = CHARSET_8_BIT_CONTROL;
+                 else
+                   charset_id = charset_latin_iso8859_1;
+                 inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+                 inev.ie.code = MAKE_CHAR (charset_id, code, 0);
+               }
              else
-               charset_id = charset_mule_unicode_e000_ffff,
-                 code = (keysym & 0xFFFF) - 0xe000;
-             c1 = (code / 96) + 32, c2 = (code % 96) + 32;
-             inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
-             inev.ie.code = MAKE_CHAR (charset_id, c1, c2);
+               {
+                 if (code < 0x2500)
+                   charset_id = charset_mule_unicode_0100_24ff,
+                     code -= 0x100;
+                 else if (code < 0xE000)
+                   charset_id = charset_mule_unicode_2500_33ff,
+                     code -= 0x2500;
+                 else
+                   charset_id = charset_mule_unicode_e000_ffff,
+                     code -= 0xE000;
+                 c1 = (code / 96) + 32, c2 = (code % 96) + 32;
+                 inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+                 inev.ie.code = MAKE_CHAR (charset_id, c1, c2);
+               }
              goto done_keysym;
            }
 
@@ -6491,6 +6509,12 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
         so update things that depend on mouse position.  */
       if (f && !f->output_data.x->hourglass_p)
        note_mouse_movement (f, &event.xmotion);
+#ifdef USE_GTK
+      /* We may get an EnterNotify on the buttons in the toolbar.  In that
+         case we moved out of any highlighted area and need to note this.  */
+      if (!f && last_mouse_glyph_frame)
+        note_mouse_movement (last_mouse_glyph_frame, &event);
+#endif
       goto OTHER;
 
     case FocusIn:
@@ -6518,6 +6542,11 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
           if (any_help_event_p)
            do_help = -1;
         }
+#ifdef USE_GTK
+      /* See comment in EnterNotify above */
+      else if (last_mouse_glyph_frame)
+        note_mouse_movement (last_mouse_glyph_frame, &event);
+#endif
       goto OTHER;
 
     case FocusOut:
@@ -6923,8 +6952,8 @@ x_dispatch_event (event, display)
    EXPECTED is nonzero if the caller knows input is available.  */
 
 static int
-XTread_socket (device, expected, hold_quit)
-     struct device *device;
+XTread_socket (terminal, expected, hold_quit)
+     struct terminal *terminal;
      int expected;
      struct input_event *hold_quit;
 {
@@ -6987,7 +7016,7 @@ XTread_socket (device, expected, hold_quit)
 
 #ifdef HAVE_X_SM
       /* Only check session manager input for the primary display. */
-      if (device->id == 1 && x_session_have_connection ())
+      if (terminal->id == 1 && x_session_have_connection ())
         {
           struct input_event inev;
           BLOCK_INPUT;
@@ -7164,7 +7193,7 @@ x_draw_hollow_cursor (w, row)
 
   /* Set clipping, draw the rectangle, and reset clipping again.  */
   x_clip_to_row (w, row, TEXT_AREA, gc);
-  XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h);
+  XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h - 1);
   XSetClipMask (dpy, gc, None);
 }
 
@@ -7453,9 +7482,18 @@ x_text_icon (f, icon_name)
 #define X_ERROR_MESSAGE_SIZE 200
 
 /* If non-nil, this should be a string.
-   It means catch X errors  and store the error message in this string.  */
+   It means catch X errors  and store the error message in this string.
 
-static Lisp_Object x_error_message_string;
+   The reason we use a stack is that x_catch_error/x_uncatch_error can
+   be called from a signal handler.
+*/
+
+struct x_error_message_stack {
+  char string[X_ERROR_MESSAGE_SIZE];
+  Display *dpy;
+  struct x_error_message_stack *prev;
+};
+static struct x_error_message_stack *x_error_message;
 
 /* An X error handler which stores the error message in
    x_error_message_string.  This is called from x_error_handler if
@@ -7467,7 +7505,7 @@ x_error_catcher (display, error)
      XErrorEvent *error;
 {
   XGetErrorText (display, error->error_code,
-                SDATA (x_error_message_string),
+                x_error_message->string,
                 X_ERROR_MESSAGE_SIZE);
 }
 
@@ -7485,47 +7523,41 @@ x_error_catcher (display, error)
    Calling x_uncatch_errors resumes the normal error handling.  */
 
 void x_check_errors ();
-static Lisp_Object x_catch_errors_unwind ();
 
-int
+void
 x_catch_errors (dpy)
      Display *dpy;
 {
-  int count = SPECPDL_INDEX ();
+  struct x_error_message_stack *data = xmalloc (sizeof (*data));
 
   /* Make sure any errors from previous requests have been dealt with.  */
   XSync (dpy, False);
 
-  record_unwind_protect (x_catch_errors_unwind,
-                        Fcons (make_save_value (dpy, 0),
-                               x_error_message_string));
-
-  x_error_message_string = make_uninit_string (X_ERROR_MESSAGE_SIZE);
-  SSET (x_error_message_string, 0, 0);
-
-  return count;
+  data->dpy = dpy;
+  data->string[0] = 0;
+  data->prev = x_error_message;
+  x_error_message = data;
 }
 
-/* Unbind the binding that we made to check for X errors.  */
+/* Undo the last x_catch_errors call.
+   DPY should be the display that was passed to x_catch_errors.  */
 
-static Lisp_Object
-x_catch_errors_unwind (old_val)
-     Lisp_Object old_val;
+void
+x_uncatch_errors ()
 {
-  Lisp_Object first = XCAR (old_val);
-  Display *dpy = XSAVE_VALUE (first)->pointer;
+  struct x_error_message_stack *tmp;
+
+  BLOCK_INPUT;
 
   /* The display may have been closed before this function is called.
      Check if it is still open before calling XSync.  */
-  if (x_display_info_for_display (dpy) != 0)
-    {
-      BLOCK_INPUT;
-      XSync (dpy, False);
-      UNBLOCK_INPUT;
-    }
+  if (x_display_info_for_display (x_error_message->dpy) != 0)
+    XSync (x_error_message->dpy, False);
 
-  x_error_message_string = XCDR (old_val);
-  return Qnil;
+  tmp = x_error_message;
+  x_error_message = x_error_message->prev;
+  xfree (tmp);
+  UNBLOCK_INPUT;
 }
 
 /* If any X protocol errors have arrived since the last call to
@@ -7540,8 +7572,13 @@ x_check_errors (dpy, format)
   /* Make sure to catch any errors incurred so far.  */
   XSync (dpy, False);
 
-  if (SREF (x_error_message_string, 0))
-    error (format, SDATA (x_error_message_string));
+  if (x_error_message->string[0])
+    {
+      char string[X_ERROR_MESSAGE_SIZE];
+      bcopy (x_error_message->string, string, X_ERROR_MESSAGE_SIZE);
+      x_uncatch_errors ();
+      error (format, string);
+    }
 }
 
 /* Nonzero if we had any X protocol errors
@@ -7554,7 +7591,7 @@ x_had_errors_p (dpy)
   /* Make sure to catch any errors incurred so far.  */
   XSync (dpy, False);
 
-  return SREF (x_error_message_string, 0) != 0;
+  return x_error_message->string[0] != 0;
 }
 
 /* Forget about any errors we have had, since we did x_catch_errors on DPY.  */
@@ -7563,20 +7600,24 @@ void
 x_clear_errors (dpy)
      Display *dpy;
 {
-  SSET (x_error_message_string, 0, 0);
+  x_error_message->string[0] = 0;
 }
 
-/* Stop catching X protocol errors and let them make Emacs die.
-   DPY should be the display that was passed to x_catch_errors.
-   COUNT should be the value that was returned by
-   the corresponding call to x_catch_errors.  */
+/* Close off all unclosed x_catch_errors calls.  */
 
 void
-x_uncatch_errors (dpy, count)
-     Display *dpy;
-     int count;
+x_fully_uncatch_errors ()
 {
-  unbind_to (count, Qnil);
+  while (x_error_message)
+    x_uncatch_errors ();
+}
+
+/* Nonzero if x_catch_errors has been done and not yet canceled.  */
+
+int
+x_catching_errors ()
+{
+  return x_error_message != 0;
 }
 
 #if 0
@@ -7635,7 +7676,6 @@ x_connection_closed (dpy, error_message)
 {
   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
   Lisp_Object frame, tail;
-  int count;
   int index = SPECPDL_INDEX ();
 
   error_msg = (char *) alloca (strlen (error_message) + 1);
@@ -7646,7 +7686,7 @@ x_connection_closed (dpy, error_message)
      below.  Otherwise, we might end up with printing ``can't find per
      display information'' in the recursive call instead of printing
      the original message here.  */
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
 
   /* Inhibit redisplay while frames are being deleted. */
   specbind (Qinhibit_redisplay, Qt);
@@ -7656,7 +7696,7 @@ x_connection_closed (dpy, error_message)
       /* Protect display from being closed when we delete the last
          frame on it. */
       dpyinfo->reference_count++;
-      dpyinfo->device->reference_count++;
+      dpyinfo->terminal->reference_count++;
     }
   
   /* First delete frames whose mini-buffers are on frames
@@ -7724,7 +7764,7 @@ x_connection_closed (dpy, error_message)
       dpyinfo->display = 0;
 
       dpyinfo->reference_count--;
-      dpyinfo->device->reference_count--;
+      dpyinfo->terminal->reference_count--;
       if (dpyinfo->reference_count != 0)
         /* We have just closed all frames on this display. */
         abort ();
@@ -7732,9 +7772,9 @@ x_connection_closed (dpy, error_message)
       x_delete_display (dpyinfo);
     }
 
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors ();
 
-  if (device_list == 0)
+  if (terminal_list == 0)
     {
       fprintf (stderr, "%s\n", error_msg);
       shut_down_emacs (0, 0, Qnil);
@@ -7765,7 +7805,7 @@ x_error_handler (display, error)
      Display *display;
      XErrorEvent *error;
 {
-  if (! NILP (x_error_message_string))
+  if (x_error_message)
     x_error_catcher (display, error);
   else
     x_error_quitter (display, error);
@@ -9340,7 +9380,6 @@ x_list_fonts (f, pattern, size, maxnames)
     = f ? FRAME_X_DISPLAY_INFO (f) : x_display_list;
   Display *dpy = dpyinfo->display;
   int try_XLoadQueryFont = 0;
-  int count;
   int allow_auto_scaled_font = 0;
 
   if (size < 0)
@@ -9380,7 +9419,7 @@ x_list_fonts (f, pattern, size, maxnames)
       /* At first, put PATTERN in the cache.  */
 
       BLOCK_INPUT;
-      count = x_catch_errors (dpy);
+      x_catch_errors (dpy);
 
       if (try_XLoadQueryFont)
        {
@@ -9461,7 +9500,7 @@ x_list_fonts (f, pattern, size, maxnames)
            }
        }
 
-      x_uncatch_errors (dpy, count);
+      x_uncatch_errors ();
       UNBLOCK_INPUT;
 
       if (names)
@@ -9552,7 +9591,7 @@ x_list_fonts (f, pattern, size, maxnames)
              XFontStruct *thisinfo;
 
              BLOCK_INPUT;
-             count = x_catch_errors (dpy);
+             x_catch_errors (dpy);
              thisinfo = XLoadQueryFont (dpy,
                                         SDATA (XCAR (tem)));
              if (x_had_errors_p (dpy))
@@ -9562,7 +9601,7 @@ x_list_fonts (f, pattern, size, maxnames)
                  thisinfo = NULL;
                  x_clear_errors (dpy);
                }
-             x_uncatch_errors (dpy, count);
+             x_uncatch_errors ();
              UNBLOCK_INPUT;
 
              if (thisinfo)
@@ -9718,7 +9757,6 @@ x_load_font (f, fontname, size)
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Lisp_Object font_names;
-  int count;
 
   /* Get a list of all the fonts that match this name.  Once we
      have a list of matching fonts, we compare them against the fonts
@@ -9757,7 +9795,7 @@ x_load_font (f, fontname, size)
       fontname = (char *) SDATA (XCAR (font_names));
 
     BLOCK_INPUT;
-    count = x_catch_errors (FRAME_X_DISPLAY (f));
+    x_catch_errors (FRAME_X_DISPLAY (f));
     font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname);
     if (x_had_errors_p (FRAME_X_DISPLAY (f)))
       {
@@ -9766,7 +9804,7 @@ x_load_font (f, fontname, size)
        font = NULL;
        x_clear_errors (FRAME_X_DISPLAY (f));
       }
-    x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+    x_uncatch_errors ();
     UNBLOCK_INPUT;
     if (!font)
       return NULL;
@@ -10121,7 +10159,7 @@ x_term_init (display_name, xrm_option, resource_name)
 {
   int connection;
   Display *dpy;
-  struct device *device;
+  struct terminal *terminal;
   struct x_display_info *dpyinfo;
   XrmDatabase xrdb;
 
@@ -10141,14 +10179,26 @@ x_term_init (display_name, xrm_option, resource_name)
     char **argv2 = argv;
     GdkAtom atom;
 
+#ifndef HAVE_GTK_MULTIDISPLAY
+    if (!EQ (Vinitial_window_system, intern ("x")))
+      error ("Sorry, you cannot connect to X servers with the GTK toolkit");
+#endif
+
     if (x_initialized++ > 1)
       {
+#ifdef HAVE_GTK_MULTIDISPLAY
         /* Opening another display.  If xg_display_open returns less
            than zero, we are probably on GTK 2.0, which can only handle
            one display.  GTK 2.2 or later can handle more than one.  */
         if (xg_display_open (SDATA (display_name), &dpy) < 0)
           error ("Sorry, this version of GTK can only handle one display");
-     }
+#else
+        /* XXX Unfortunately, multiple display support is severely broken
+           in recent GTK versions, so HAVE_GTK_MULTIDISPLAY is
+           unconditionally disabled in configure.in.  */
+        error ("Sorry, multiple display support is broken in current GTK versions");
+#endif
+      }
     else
       {
         for (argc = 0; argc < NUM_ARGV; ++argc)
@@ -10256,7 +10306,7 @@ x_term_init (display_name, xrm_option, resource_name)
   dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info));
   bzero (dpyinfo, sizeof *dpyinfo);
 
-  device = x_create_device (dpyinfo);
+  terminal = x_create_terminal (dpyinfo);
 
 #ifdef MULTI_KBOARD
   {
@@ -10269,30 +10319,30 @@ x_term_init (display_name, xrm_option, resource_name)
                         SDATA (display_name)))
        break;
     if (share)
-      device->kboard = share->device->kboard;
+      terminal->kboard = share->terminal->kboard;
     else
       {
-       device->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
-       init_kboard (device->kboard);
+       terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+       init_kboard (terminal->kboard);
        if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound))
          {
            char *vendor = ServerVendor (dpy);
            UNBLOCK_INPUT;
-           device->kboard->Vsystem_key_alist
+           terminal->kboard->Vsystem_key_alist
              = call1 (Qvendor_specific_keysyms,
                       build_string (vendor ? vendor : ""));
            BLOCK_INPUT;
          }
 
-       device->kboard->next_kboard = all_kboards;
-       all_kboards = device->kboard;
+       terminal->kboard->next_kboard = all_kboards;
+       all_kboards = terminal->kboard;
        /* Don't let the initial kboard remain current longer than necessary.
           That would cause problems if a file loaded on startup tries to
           prompt in the mini-buffer.  */
        if (current_kboard == initial_kboard)
-         current_kboard = device->kboard;
+         current_kboard = terminal->kboard;
       }
-    device->kboard->reference_count++;
+    terminal->kboard->reference_count++;
   }
 #endif
 
@@ -10307,10 +10357,10 @@ x_term_init (display_name, xrm_option, resource_name)
 
   dpyinfo->display = dpy;
 
-  /* Set the name of the device. */
-  device->name = (char *) xmalloc (SBYTES (display_name) + 1);
-  strncpy (device->name, SDATA (display_name), SBYTES (display_name));
-  device->name[SBYTES (display_name)] = 0;
+  /* Set the name of the terminal. */
+  terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+  strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+  terminal->name[SBYTES (display_name)] = 0;
   
 #if 0
   XSetAfterFunction (x_current_display, x_trace_wire);
@@ -10547,7 +10597,6 @@ x_term_init (display_name, xrm_option, resource_name)
     Display *dpy = dpyinfo->display;
     XrmValue d, fr, to;
     Font font;
-    int count;
 
     d.addr = (XPointer)&dpy;
     d.size = sizeof (Display *);
@@ -10555,12 +10604,12 @@ x_term_init (display_name, xrm_option, resource_name)
     fr.size = sizeof (XtDefaultFont);
     to.size = sizeof (Font *);
     to.addr = (XPointer)&font;
-    count = x_catch_errors (dpy);
+    x_catch_errors (dpy);
     if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
       abort ();
     if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
       XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
-    x_uncatch_errors (dpy, count);
+    x_uncatch_errors ();
   }
 #endif
 #endif
@@ -10602,7 +10651,7 @@ x_term_init (display_name, xrm_option, resource_name)
   /* Only do this for the very first display in the Emacs session.
      Ignore X session management when Emacs was first started on a
      tty.  */
-  if (device->id == 1)
+  if (terminal->id == 1)
     x_session_initialize (dpyinfo);
 #endif
 
@@ -10619,17 +10668,17 @@ x_delete_display (dpyinfo)
      struct x_display_info *dpyinfo;
 {
   int i;
-  struct device *d;
+  struct terminal *t;
 
-  /* Delete the generic struct device for this X display. */
-  for (d = device_list; d; d = d->next_device)
-    if (d->type == output_x_window && d->display_info.x == dpyinfo)
+  /* Delete the generic struct terminal for this X display. */
+  for (t = terminal_list; t; t = t->next_terminal)
+    if (t->type == output_x_window && t->display_info.x == dpyinfo)
       {
         /* Close X session management when we close its display. */
-        if (d->id == 1 && x_session_have_connection ())
+        if (t->id == 1 && x_session_have_connection ())
           x_session_close();
 
-        delete_device (d);
+        delete_terminal (t);
         break;
       }
 
@@ -10764,9 +10813,9 @@ static struct redisplay_interface x_redisplay_interface =
 
 /* This function is called when the last frame on a display is deleted. */
 void
-x_delete_device (struct device *device)
+x_delete_terminal (struct terminal *terminal)
 {
-  struct x_display_info *dpyinfo = device->display_info.x;
+  struct x_display_info *dpyinfo = terminal->display_info.x;
   int i;
 
   BLOCK_INPUT;
@@ -10795,50 +10844,50 @@ x_delete_device (struct device *device)
 }
 
 
-struct device *
-x_create_device (struct x_display_info *dpyinfo)
+static struct terminal *
+x_create_terminal (struct x_display_info *dpyinfo)
 {
-  struct device *device;
+  struct terminal *terminal;
   
-  device = create_device ();
+  terminal = create_terminal ();
 
-  device->type = output_x_window;
-  device->display_info.x = dpyinfo;
-  dpyinfo->device = device;
+  terminal->type = output_x_window;
+  terminal->display_info.x = dpyinfo;
+  dpyinfo->terminal = terminal;
 
   /* kboard is initialized in x_term_init. */
   
-  device->clear_frame_hook = x_clear_frame;
-  device->ins_del_lines_hook = x_ins_del_lines;
-  device->delete_glyphs_hook = x_delete_glyphs;
-  device->ring_bell_hook = XTring_bell;
-  device->reset_terminal_modes_hook = XTreset_terminal_modes;
-  device->set_terminal_modes_hook = XTset_terminal_modes;
-  device->update_begin_hook = x_update_begin;
-  device->update_end_hook = x_update_end;
-  device->set_terminal_window_hook = XTset_terminal_window;
-  device->read_socket_hook = XTread_socket;
-  device->frame_up_to_date_hook = XTframe_up_to_date;
-  device->mouse_position_hook = XTmouse_position;
-  device->frame_rehighlight_hook = XTframe_rehighlight;
-  device->frame_raise_lower_hook = XTframe_raise_lower;
-  device->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
-  device->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
-  device->redeem_scroll_bar_hook = XTredeem_scroll_bar;
-  device->judge_scroll_bars_hook = XTjudge_scroll_bars;
-
-  device->delete_frame_hook = x_destroy_window;
-  device->delete_device_hook = x_delete_device;
+  terminal->clear_frame_hook = x_clear_frame;
+  terminal->ins_del_lines_hook = x_ins_del_lines;
+  terminal->delete_glyphs_hook = x_delete_glyphs;
+  terminal->ring_bell_hook = XTring_bell;
+  terminal->reset_terminal_modes_hook = XTreset_terminal_modes;
+  terminal->set_terminal_modes_hook = XTset_terminal_modes;
+  terminal->update_begin_hook = x_update_begin;
+  terminal->update_end_hook = x_update_end;
+  terminal->set_terminal_window_hook = XTset_terminal_window;
+  terminal->read_socket_hook = XTread_socket;
+  terminal->frame_up_to_date_hook = XTframe_up_to_date;
+  terminal->mouse_position_hook = XTmouse_position;
+  terminal->frame_rehighlight_hook = XTframe_rehighlight;
+  terminal->frame_raise_lower_hook = XTframe_raise_lower;
+  terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
+  terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
+  terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
+  terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
+
+  terminal->delete_frame_hook = x_destroy_window;
+  terminal->delete_terminal_hook = x_delete_terminal;
   
-  device->rif = &x_redisplay_interface;
-  device->scroll_region_ok = 1;    /* We'll scroll partial frames. */
-  device->char_ins_del_ok = 1;
-  device->line_ins_del_ok = 1;         /* We'll just blt 'em. */
-  device->fast_clear_end_of_line = 1;  /* X does this well. */
-  device->memory_below_frame = 0;   /* We don't remember what scrolls
+  terminal->rif = &x_redisplay_interface;
+  terminal->scroll_region_ok = 1;    /* We'll scroll partial frames. */
+  terminal->char_ins_del_ok = 1;
+  terminal->line_ins_del_ok = 1;         /* We'll just blt 'em. */
+  terminal->fast_clear_end_of_line = 1;  /* X does this well. */
+  terminal->memory_below_frame = 0;   /* We don't remember what scrolls
                                         off the bottom. */
 
-  return device;
+  return terminal;
 }
 
 void
@@ -10856,7 +10905,7 @@ x_initialize ()
 #endif
 
   /* Try to use interrupt input; if we can't, then start polling.  */
-  Fset_input_mode (Qt, Qnil, Qt, Qnil);
+  Fset_input_interrupt_mode (Qt);
 
 #ifdef USE_X_TOOLKIT
   XtToolkitInitialize ();
@@ -10911,8 +10960,7 @@ x_initialize ()
 void
 syms_of_xterm ()
 {
-  staticpro (&x_error_message_string);
-  x_error_message_string = Qnil;
+  x_error_message = NULL;
 
   staticpro (&x_display_name_list);
   x_display_name_list = Qnil;