]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(w32-charset-info-alist): Map vietnamese to windows-1258.
[gnu-emacs] / src / xterm.c
index 65a6232425887bcd6c6b93b295670524fe4500b3..5dda7ed2c5d3fe0121328a5b2cbe228c7ef8e45b 100644 (file)
@@ -1,6 +1,7 @@
 /* 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, 2006, 2007 Free Software Foundation, Inc.
+                 2002, 2003, 2004, 2005, 2006, 2007, 2008
+                 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -54,7 +55,6 @@ Boston, MA 02110-1301, USA.  */
 #include <sys/ioctl.h>
 #endif /* ! defined (BSD_SYSTEM) */
 
-#include "systty.h"
 #include "systime.h"
 
 #ifndef INCLUDED_FCNTL
@@ -77,7 +77,7 @@ Boston, MA 02110-1301, USA.  */
 #include "termhooks.h"
 #include "termopts.h"
 #include "termchar.h"
-#include "gnu.h"
+#include "emacs-icon.h"
 #include "disptab.h"
 #include "buffer.h"
 #include "window.h"
@@ -160,8 +160,6 @@ extern void _XEditResCheckMessages ();
 #endif
 #endif
 
-#define abs(x) ((x) < 0 ? -(x) : (x))
-
 /* Default to using XIM if available.  */
 #ifdef USE_XIM
 int use_xim = 1;
@@ -327,6 +325,10 @@ static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
 static Lisp_Object Qvendor_specific_keysyms;
 static Lisp_Object Qlatin_1;
 
+/* Used in x_flush.  */
+
+extern Lisp_Object Vinhibit_redisplay;
+
 extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
 extern int x_bitmap_mask P_ ((FRAME_PTR, int));
 
@@ -336,13 +338,15 @@ static const XColor *x_color_cells P_ ((Display *, int *));
 static void x_update_window_end P_ ((struct window *, int, int));
 
 static int x_io_error_quitter P_ ((Display *));
+static struct terminal *x_create_terminal P_ ((struct x_display_info *));
+void x_delete_terminal P_ ((struct terminal *));
 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_ ((void));
-static void XTreset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+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 *));
 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
@@ -382,12 +386,18 @@ static void
 x_flush (f)
      struct frame *f;
 {
+  /* Don't call XFlush when it is not safe to redisplay; the X
+     connection may be broken.  */
+  if (!NILP (Vinhibit_redisplay))
+    return;
+
   BLOCK_INPUT;
   if (f == NULL)
     {
       Lisp_Object rest, frame;
       FOR_EACH_FRAME (rest, frame)
-       x_flush (XFRAME (frame));
+        if (FRAME_X_P (XFRAME (frame)))
+          x_flush (XFRAME (frame));
     }
   else if (FRAME_X_P (f))
     XFlush (FRAME_X_DISPLAY (f));
@@ -848,7 +858,7 @@ x_draw_fringe_bitmap (w, row, p)
    rarely happens).  */
 
 static void
-XTset_terminal_modes ()
+XTset_terminal_modes (struct terminal *terminal)
 {
 }
 
@@ -856,7 +866,7 @@ XTset_terminal_modes ()
    the X-windows go away, and suspending requires no action.  */
 
 static void
-XTreset_terminal_modes ()
+XTreset_terminal_modes (struct terminal *terminal)
 {
 }
 
@@ -1088,6 +1098,11 @@ x_set_cursor_gc (s)
        }
 
       IF_DEBUG (x_check_font (s->f, s->font));
+#ifdef USE_FONT_BACKEND
+      if (enable_font_backend)
+       xgcv.font = FRAME_X_DISPLAY_INFO (s->f)->font->fid;
+      else
+#endif
       xgcv.font = s->font->fid;
       xgcv.graphics_exposures = False;
       mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
@@ -1144,6 +1159,11 @@ x_set_mouse_face_gc (s)
       xgcv.background = s->face->background;
       xgcv.foreground = s->face->foreground;
       IF_DEBUG (x_check_font (s->f, s->font));
+#ifdef USE_FONT_BACKEND
+      if (enable_font_backend)
+       xgcv.font = FRAME_X_DISPLAY_INFO (s->f)->font->fid;
+      else
+#endif
       xgcv.font = s->font->fid;
       xgcv.graphics_exposures = False;
       mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
@@ -1228,13 +1248,18 @@ static INLINE void
 x_set_glyph_string_clipping (s)
      struct glyph_string *s;
 {
-  XRectangle r;
-  get_glyph_string_clip_rect (s, &r);
-  XSetClipRectangles (s->display, s->gc, 0, 0, &r, 1, Unsorted);
 #ifdef USE_FONT_BACKEND
-  s->clip_x = r.x, s->clip_y = r.y;
-  s->clip_width = r.width, s->clip_height = r.height;
-#endif /* USE_FONT_BACKEND */
+  XRectangle *r = s->clip;
+#else
+  XRectangle r[2];
+#endif
+  int n = get_glyph_string_clip_rects (s, r, 2);
+
+  if (n > 0)
+    XSetClipRectangles (s->display, s->gc, 0, 0, r, n, Unsorted);
+#ifdef USE_FONT_BACKEND
+  s->num_clips = n;
+#endif
 }
 
 
@@ -1251,10 +1276,12 @@ x_set_glyph_string_clipping_exactly (src, dst)
 #ifdef USE_FONT_BACKEND
   if (enable_font_backend)
     {
-      r.x = dst->clip_x = src->x;
-      r.width = dst->clip_width = src->width;
-      r.y = dst->clip_y = src->y;
-      r.height = dst->clip_height = src->height;
+      r.x = src->x;
+      r.width = src->width;
+      r.y = src->y;
+      r.height = src->height;
+      dst->clip[0] = r;
+      dst->num_clips = 1;
     }
   else
     {
@@ -1385,7 +1412,7 @@ x_draw_glyph_string_foreground (s)
      of S to the right of that box line.  */
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + abs (s->face->box_line_width);
+    x = s->x + eabs (s->face->box_line_width);
   else
     x = s->x;
 
@@ -1487,7 +1514,7 @@ x_draw_composite_glyph_string_foreground (s)
      of S to the right of that box line.  */
   if (s->face && s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + abs (s->face->box_line_width);
+    x = s->x + eabs (s->face->box_line_width);
   else
     x = s->x;
 
@@ -1526,7 +1553,7 @@ x_draw_composite_glyph_string_foreground (s)
 
              if (! VECTORP (adjustment))
                {
-                 width += XINT (LGLYPH_WIDTH (g));
+                 width += LGLYPH_WIDTH (g);
                  continue;
                }
              if (from < i)
@@ -1539,7 +1566,7 @@ x_draw_composite_glyph_string_foreground (s)
              wadjust = XINT (AREF (adjustment, 2));
 
              font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
-             x += XINT (LGLYPH_WIDTH (g)) + wadjust;
+             x += wadjust;
              from = i + 1;
              width = 0;
            }
@@ -1614,7 +1641,8 @@ x_frame_of_widget (widget)
   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
     if (FRAMEP (XCAR (tail))
        && (f = XFRAME (XCAR (tail)),
-           (f->output_data.nothing != 1
+           (FRAME_X_P (f)
+             && f->output_data.nothing != 1
             && FRAME_X_DISPLAY_INFO (f) == dpyinfo))
        && f->output_data.x->widget == widget)
       return f;
@@ -2340,7 +2368,7 @@ x_draw_glyph_string_box (s)
                ? s->first_glyph
                : s->first_glyph + s->nchars - 1);
 
-  width = abs (s->face->box_line_width);
+  width = eabs (s->face->box_line_width);
   raised_p = s->face->box == FACE_RAISED_BOX;
   left_x = s->x;
   right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
@@ -2386,7 +2414,7 @@ x_draw_image_foreground (s)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += abs (s->face->box_line_width);
+    x += eabs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -2479,7 +2507,7 @@ x_draw_image_relief (s)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += abs (s->face->box_line_width);
+    x += eabs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -2496,7 +2524,7 @@ x_draw_image_relief (s)
     }
   else
     {
-      thick = abs (s->img->relief);
+      thick = eabs (s->img->relief);
       raised_p = s->img->relief > 0;
     }
 
@@ -2531,7 +2559,7 @@ x_draw_image_foreground_1 (s, pixmap)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += abs (s->face->box_line_width);
+    x += eabs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -2631,7 +2659,7 @@ static void
 x_draw_image_glyph_string (s)
      struct glyph_string *s;
 {
-  int box_line_hwidth = abs (s->face->box_line_width);
+  int box_line_hwidth = eabs (s->face->box_line_width);
   int box_line_vwidth = max (s->face->box_line_width, 0);
   int height;
   Pixmap pixmap = None;
@@ -2737,7 +2765,6 @@ x_draw_stretch_glyph_string (s)
      struct glyph_string *s;
 {
   xassert (s->first_glyph->type == STRETCH_GLYPH);
-  s->stippled_p = s->face->stipple != 0;
 
   if (s->hl == DRAW_CURSOR
       && !x_stretch_cursor_p)
@@ -2839,7 +2866,7 @@ x_draw_glyph_string (s)
            x_set_glyph_string_clipping (next);
            x_draw_glyph_string_background (next, 1);
 #ifdef USE_FONT_BACKEND
-           next->clip_width = 0;
+           next->num_clips = 0;
 #endif /* USE_FONT_BACKEND */
          }
     }
@@ -3028,7 +3055,7 @@ x_draw_glyph_string (s)
                XSetClipMask (prev->display, prev->gc, None);
                prev->hl = save;
 #ifdef USE_FONT_BACKEND
-               prev->clip_width = 0;
+               prev->num_clips = 0;
 #endif /* USE_FONT_BACKEND */
              }
        }
@@ -3055,7 +3082,7 @@ x_draw_glyph_string (s)
                XSetClipMask (next->display, next->gc, None);
                next->hl = save;
 #ifdef USE_FONT_BACKEND
-               next->clip_width = 0;
+               next->num_clips = 0;
 #endif /* USE_FONT_BACKEND */
              }
        }
@@ -3064,7 +3091,7 @@ x_draw_glyph_string (s)
   /* Reset clipping.  */
   XSetClipMask (s->display, s->gc, None);
 #ifdef USE_FONT_BACKEND
-  s->clip_width = 0;
+  s->num_clips = 0;
 #endif /* USE_FONT_BACKEND */
 }
 
@@ -3085,7 +3112,8 @@ x_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
    for X frames.  */
 
 static void
-x_delete_glyphs (n)
+x_delete_glyphs (f, n)
+     struct frame *f;
      register int n;
 {
   abort ();
@@ -3108,19 +3136,11 @@ x_clear_area (dpy, window, x, y, width, height, exposures)
 }
 
 
-/* Clear entire frame.  If updating_frame is non-null, clear that
-   frame.  Otherwise clear the selected frame.  */
+/* Clear an entire frame.  */
 
 static void
-x_clear_frame ()
+x_clear_frame (struct frame *f)
 {
-  struct frame *f;
-
-  if (updating_frame)
-    f = updating_frame;
-  else
-    f = SELECTED_FRAME ();
-
   /* Clearing the frame will erase any cursor, so mark them all as no
      longer visible.  */
   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
@@ -3199,8 +3219,8 @@ XTflash (f)
       XGCValues values;
 
       values.function = GXxor;
-      values.foreground = (f->output_data.x->foreground_pixel
-                          ^ f->output_data.x->background_pixel);
+      values.foreground = (FRAME_FOREGROUND_PIXEL (f)
+                          ^ FRAME_BACKGROUND_PIXEL (f));
 
       gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                      GCFunction | GCForeground, &values);
@@ -3366,7 +3386,8 @@ XTset_terminal_window (n)
    lines or deleting -N lines at vertical position VPOS.  */
 
 static void
-x_ins_del_lines (vpos, n)
+x_ins_del_lines (f, vpos, n)
+     struct frame *f;
      int vpos, n;
 {
   abort ();
@@ -3599,6 +3620,15 @@ x_detect_focus_change (dpyinfo, event, bufp)
                        FOCUS_IMPLICIT : FOCUS_EXPLICIT),
                       dpyinfo, frame, bufp);
       break;
+
+    case ClientMessage:
+      if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
+       {
+         enum xembed_message msg = event->xclient.data.l[1];
+         x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
+                          FOCUS_EXPLICIT, dpyinfo, frame, bufp);
+       }
+      break;
     }
 }
 
@@ -3677,12 +3707,7 @@ x_find_modifier_meanings (dpyinfo)
   dpyinfo->super_mod_mask = 0;
   dpyinfo->hyper_mod_mask = 0;
 
-#ifdef HAVE_X11R4
   XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
-#else
-  min_code = dpyinfo->display->min_keycode;
-  max_code = dpyinfo->display->max_keycode;
-#endif
 
   syms = XGetKeyboardMapping (dpyinfo->display,
                              min_code, max_code - min_code + 1,
@@ -4003,7 +4028,8 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
 
       /* Clear the mouse-moved flag for every frame on this display.  */
       FOR_EACH_FRAME (tail, frame)
-       if (FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
+       if (FRAME_X_P (XFRAME (frame))
+            && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
          XFRAME (frame)->mouse_moved = 0;
 
       last_mouse_scroll_bar = Qnil;
@@ -4190,6 +4216,9 @@ x_window_to_scroll_bar (display, window_id)
       if (! FRAMEP (frame))
        abort ();
 
+      if (! FRAME_X_P (XFRAME (frame)))
+        continue;
+      
       /* Scan this frame's scroll bar list for a scroll bar with the
          right window ID.  */
       condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
@@ -4200,7 +4229,7 @@ x_window_to_scroll_bar (display, window_id)
                               condemned = Qnil,
                               ! NILP (bar));
           bar = XSCROLL_BAR (bar)->next)
-       if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)) == window_id &&
+       if (XSCROLL_BAR (bar)->x_window == window_id &&
             FRAME_X_DISPLAY (XFRAME (frame)) == display)
          return XSCROLL_BAR (bar);
     }
@@ -4222,11 +4251,14 @@ x_window_to_menu_bar (window)
 
   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
     {
-      Lisp_Object frame = XCAR (tail);
-      Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
+      if (FRAME_X_P (XFRAME (XCAR (tail))))
+        {
+          Lisp_Object frame = XCAR (tail);
+          Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
 
-      if (menu_bar && xlwmenu_window_p (menu_bar, window))
-       return menu_bar;
+          if (menu_bar && xlwmenu_window_p (menu_bar, window))
+            return menu_bar;
+        }
     }
 
   return NULL;
@@ -4513,9 +4545,8 @@ xm_scroll_callback (widget, client_data, call_data)
     }
 }
 
+#elif defined USE_GTK
 
-#else /* !USE_MOTIF, i.e. Xaw or GTK */
-#ifdef USE_GTK
 /* Scroll bar callback for GTK scroll bars.  WIDGET is the scroll
    bar widget.  DATA is a pointer to the scroll_bar structure. */
 
@@ -4586,7 +4617,7 @@ xg_scroll_callback (widget, data)
     }
 }
 
-#else /* not USE_GTK */
+#else /* not USE_GTK and not USE_MOTIF */
 
 /* Xaw scroll bar callback.  Invoked when the thumb is dragged.
    WIDGET is the scroll bar widget.  CLIENT_DATA is a pointer to the
@@ -4612,7 +4643,7 @@ xaw_jump_callback (widget, client_data, call_data)
   whole = 10000000;
   portion = shown < 1 ? top * whole : 0;
 
-  if (shown < 1 && (abs (top + shown - 1) < 1.0/height))
+  if (shown < 1 && (eabs (top + shown - 1) < 1.0/height))
     /* Some derivatives of Xaw refuse to shrink the thumb when you reach
        the bottom, so we force the scrolling whenever we see that we're
        too close to the bottom (in x_set_toolkit_scroll_bar_thumb
@@ -4653,12 +4684,12 @@ xaw_scroll_callback (widget, client_data, call_data)
   XtVaGetValues (widget, XtNheight, &height, NULL);
   UNBLOCK_INPUT;
 
-  if (abs (position) >= height)
+  if (eabs (position) >= height)
     part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
 
   /* If Xaw3d was compiled with ARROW_SCROLLBAR,
      it maps line-movement to call_data = max(5, height/20).  */
-  else if (xaw3d_arrow_scroll && abs (position) <= max (5, height / 20))
+  else if (xaw3d_arrow_scroll && eabs (position) <= max (5, height / 20))
     part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow;
   else
     part = scroll_bar_move_ratio;
@@ -4669,8 +4700,7 @@ xaw_scroll_callback (widget, client_data, call_data)
   x_send_scroll_bar_event (bar->window, part, position, height);
 }
 
-#endif /* not USE_GTK */
-#endif /* not USE_MOTIF */
+#endif /* not USE_GTK and not USE_MOTIF */
 
 #define SCROLL_BAR_NAME "verticalScrollBar"
 
@@ -4876,7 +4906,7 @@ x_create_toolkit_scroll_bar (f, bar)
   /* Remember X window and widget in the scroll bar vector.  */
   SET_SCROLL_BAR_X_WIDGET (bar, widget);
   xwindow = XtWindow (widget);
-  SET_SCROLL_BAR_X_WINDOW (bar, xwindow);
+  bar->x_window = xwindow;
 
   UNBLOCK_INPUT;
 }
@@ -5020,7 +5050,7 @@ x_scroll_bar_create (w, top, left, width, height)
 {
   struct frame *f = XFRAME (w->frame);
   struct scroll_bar *bar
-    = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
+    = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, x_window, PVEC_OTHER);
 
   BLOCK_INPUT;
 
@@ -5034,7 +5064,7 @@ x_scroll_bar_create (w, top, left, width, height)
 
     a.background_pixel = f->output_data.x->scroll_bar_background_pixel;
     if (a.background_pixel == -1)
-      a.background_pixel = f->output_data.x->background_pixel;
+      a.background_pixel = FRAME_BACKGROUND_PIXEL (f);
 
     a.event_mask = (ButtonPressMask | ButtonReleaseMask
                    | ButtonMotionMask | PointerMotionHintMask
@@ -5064,21 +5094,19 @@ x_scroll_bar_create (w, top, left, width, height)
                            CopyFromParent,
                             /* Attributes.  */
                            mask, &a);
-    SET_SCROLL_BAR_X_WINDOW (bar, window);
+    bar->x_window = window;
   }
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 
   XSETWINDOW (bar->window, w);
-  XSETINT (bar->top, top);
-  XSETINT (bar->left, left);
-  XSETINT (bar->width, width);
-  XSETINT (bar->height, height);
-  XSETINT (bar->start, 0);
-  XSETINT (bar->end, 0);
+  bar->top = top;
+  bar->left = left;
+  bar->width = width;
+  bar->height = height;
+  bar->start = 0;
+  bar->end = 0;
   bar->dragging = Qnil;
-#ifdef USE_TOOLKIT_SCROLL_BARS
-  bar->fringe_extended_p = Qnil;
-#endif
+  bar->fringe_extended_p = 0;
 
   /* Add bar to its frame's list of scroll bars.  */
   bar->next = FRAME_SCROLL_BARS (f);
@@ -5092,12 +5120,12 @@ x_scroll_bar_create (w, top, left, width, height)
   {
 #ifdef USE_GTK
     xg_update_scrollbar_pos (f,
-                             SCROLL_BAR_X_WINDOW (bar),
+                             bar->x_window,
                              top,
                              left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
                              width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
                              max (height, 1));
-    xg_show_scroll_bar (SCROLL_BAR_X_WINDOW (bar));
+    xg_show_scroll_bar (bar->x_window);
 #else /* not USE_GTK */
     Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
     XtConfigureWidget (scroll_bar,
@@ -5109,7 +5137,7 @@ x_scroll_bar_create (w, top, left, width, height)
 #endif /* not USE_GTK */
     }
 #else /* not USE_TOOLKIT_SCROLL_BARS */
-  XMapRaised (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
+  XMapRaised (FRAME_X_DISPLAY (f), bar->x_window);
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 
   UNBLOCK_INPUT;
@@ -5117,6 +5145,8 @@ x_scroll_bar_create (w, top, left, width, height)
 }
 
 
+#ifndef USE_TOOLKIT_SCROLL_BARS
+
 /* Draw BAR's handle in the proper position.
 
    If the handle is already drawn from START to END, don't bother
@@ -5130,8 +5160,6 @@ x_scroll_bar_create (w, top, left, width, height)
    the bar's top is as far down as it goes; otherwise, there's no way
    to move to the very end of the buffer.  */
 
-#ifndef USE_TOOLKIT_SCROLL_BARS
-
 static void
 x_scroll_bar_set_handle (bar, start, end, rebuild)
      struct scroll_bar *bar;
@@ -5139,22 +5167,22 @@ x_scroll_bar_set_handle (bar, start, end, rebuild)
      int rebuild;
 {
   int dragging = ! NILP (bar->dragging);
-  Window w = SCROLL_BAR_X_WINDOW (bar);
+  Window w = bar->x_window;
   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   GC gc = f->output_data.x->normal_gc;
 
   /* If the display is already accurate, do nothing.  */
   if (! rebuild
-      && start == XINT (bar->start)
-      && end == XINT (bar->end))
+      && start == bar->start
+      && end == bar->end)
     return;
 
   BLOCK_INPUT;
 
   {
-    int inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, XINT (bar->width));
-    int inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, XINT (bar->height));
-    int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
+    int inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, bar->width);
+    int inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, bar->height);
+    int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 
     /* Make sure the values are reasonable, and try to preserve
        the distance between start and end.  */
@@ -5174,8 +5202,8 @@ x_scroll_bar_set_handle (bar, start, end, rebuild)
     }
 
     /* Store the adjusted setting in the scroll bar.  */
-    XSETINT (bar->start, start);
-    XSETINT (bar->end, end);
+    bar->start = start;
+    bar->end = end;
 
     /* Clip the end position, just for display.  */
     if (end > top_range)
@@ -5211,7 +5239,7 @@ x_scroll_bar_set_handle (bar, start, end, rebuild)
     /* Restore the foreground color of the GC if we changed it above.  */
     if (f->output_data.x->scroll_bar_foreground_pixel != -1)
       XSetForeground (FRAME_X_DISPLAY (f), gc,
-                     f->output_data.x->foreground_pixel);
+                     FRAME_FOREGROUND_PIXEL (f));
 
     /* Draw the empty space below the handle.  Note that we can't
        clear zero-height areas; that means "clear to end of window." */
@@ -5242,12 +5270,12 @@ x_scroll_bar_remove (bar)
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
 #ifdef USE_GTK
-  xg_remove_scroll_bar (f, SCROLL_BAR_X_WINDOW (bar));
+  xg_remove_scroll_bar (f, bar->x_window);
 #else /* not USE_GTK */
   XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
 #endif /* not USE_GTK */
 #else
-  XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
+  XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window);
 #endif
 
   /* Disassociate this scroll bar from its window.  */
@@ -5345,19 +5373,19 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
       BLOCK_INPUT;
 
-      if (sb_left != XINT (bar->left))
+      if (sb_left != bar->left)
        mask |= CWX;
-      if (top != XINT (bar->top))
+      if (top != bar->top)
        mask |= CWY;
-      if (sb_width != XINT (bar->width))
+      if (sb_width != bar->width)
        mask |= CWWidth;
-      if (height != XINT (bar->height))
+      if (height != bar->height)
        mask |= CWHeight;
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
 
       /* Move/size the scroll bar widget.  */
-      if (mask || !NILP (bar->fringe_extended_p) != fringe_extended_p)
+      if (mask || bar->fringe_extended_p != fringe_extended_p)
        {
          /* Since toolkit scroll bars are smaller than the space reserved
             for them on the frame, we have to clear "under" them.  */
@@ -5372,7 +5400,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
            }
 #ifdef USE_GTK
           xg_update_scrollbar_pos (f,
-                                   SCROLL_BAR_X_WINDOW (bar),
+                                   bar->x_window,
                                    top,
                                    sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
                                    sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM *2,
@@ -5428,23 +5456,23 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
          wc.y = top;
          wc.width = sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2;
          wc.height = height;
-         XConfigureWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar),
+         XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
                            mask, &wc);
        }
 
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 
       /* Remember new settings.  */
-      XSETINT (bar->left, sb_left);
-      XSETINT (bar->top, top);
-      XSETINT (bar->width, sb_width);
-      XSETINT (bar->height, height);
+      bar->left = sb_left;
+      bar->top = top;
+      bar->width = sb_width;
+      bar->height = height;
 
       UNBLOCK_INPUT;
     }
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
-  bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
+  bar->fringe_extended_p = fringe_extended_p;
 
   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
@@ -5588,14 +5616,14 @@ x_scroll_bar_expose (bar, event)
      struct scroll_bar *bar;
      XEvent *event;
 {
-  Window w = SCROLL_BAR_X_WINDOW (bar);
+  Window w = bar->x_window;
   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   GC gc = f->output_data.x->normal_gc;
   int width_trim = VERTICAL_SCROLL_BAR_WIDTH_TRIM;
 
   BLOCK_INPUT;
 
-  x_scroll_bar_set_handle (bar, XINT (bar->start), XINT (bar->end), 1);
+  x_scroll_bar_set_handle (bar, bar->start, bar->end, 1);
 
   /* Switch to scroll bar foreground color.  */
   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
@@ -5607,13 +5635,13 @@ x_scroll_bar_expose (bar, event)
 
                  /* x, y, width, height */
                  0, 0,
-                 XINT (bar->width) - 1 - width_trim - width_trim,
-                 XINT (bar->height) - 1);
+                 bar->width - 1 - width_trim - width_trim,
+                 bar->height - 1);
 
    /* Restore the foreground color of the GC if we changed it above.  */
    if (f->output_data.x->scroll_bar_foreground_pixel != -1)
      XSetForeground (FRAME_X_DISPLAY (f), gc,
-                   f->output_data.x->foreground_pixel);
+                    FRAME_FOREGROUND_PIXEL (f));
 
    UNBLOCK_INPUT;
 
@@ -5652,18 +5680,18 @@ x_scroll_bar_handle_click (bar, event, emacs_event)
 #if 0
     FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
     int internal_height
-      = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, XINT (bar->height));
+      = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, bar->height);
 #endif
     int top_range
-      = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
+      = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
     int y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER;
 
     if (y < 0) y = 0;
     if (y > top_range) y = top_range;
 
-    if (y < XINT (bar->start))
+    if (y < bar->start)
       emacs_event->part = scroll_bar_above_handle;
-    else if (y < XINT (bar->end) + VERTICAL_SCROLL_BAR_MIN_HANDLE)
+    else if (y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE)
       emacs_event->part = scroll_bar_handle;
     else
       emacs_event->part = scroll_bar_below_handle;
@@ -5676,7 +5704,7 @@ x_scroll_bar_handle_click (bar, event, emacs_event)
        holding it.  */
     if (event->type == ButtonPress
        && emacs_event->part == scroll_bar_handle)
-      XSETINT (bar->dragging, y - XINT (bar->start));
+      XSETINT (bar->dragging, y - bar->start);
 #endif
 
 #ifndef USE_TOOLKIT_SCROLL_BARS
@@ -5685,7 +5713,7 @@ x_scroll_bar_handle_click (bar, event, emacs_event)
        && ! NILP (bar->dragging))
       {
        int new_start = y - XINT (bar->dragging);
-       int new_end = new_start + (XINT (bar->end) - XINT (bar->start));
+       int new_end = new_start + bar->end - bar->start;
 
        x_scroll_bar_set_handle (bar, new_start, new_end, 0);
        bar->dragging = Qnil;
@@ -5733,9 +5761,9 @@ x_scroll_bar_note_movement (bar, event)
       /* Where should the handle be now?  */
       int new_start = event->xmotion.y - XINT (bar->dragging);
 
-      if (new_start != XINT (bar->start))
+      if (new_start != bar->start)
        {
-         int new_end = new_start + (XINT (bar->end) - XINT (bar->start));
+         int new_end = new_start + bar->end - bar->start;
 
          x_scroll_bar_set_handle (bar, new_start, new_end, 0);
        }
@@ -5756,7 +5784,7 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
      unsigned long *time;
 {
   struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
-  Window w = SCROLL_BAR_X_WINDOW (bar);
+  Window w = bar->x_window;
   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   int win_x, win_y;
   Window dummy_window;
@@ -5783,10 +5811,10 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
     {
 #if 0
       int inside_height
-       = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, XINT (bar->height));
+       = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, bar->height);
 #endif
       int top_range
-       = VERTICAL_SCROLL_BAR_TOP_RANGE     (f, XINT (bar->height));
+       = VERTICAL_SCROLL_BAR_TOP_RANGE     (f, bar->height);
 
       win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
 
@@ -5803,9 +5831,9 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
 
       if (! NILP (bar->dragging))
        *part = scroll_bar_handle;
-      else if (win_y < XINT (bar->start))
+      else if (win_y < bar->start)
        *part = scroll_bar_above_handle;
-      else if (win_y < XINT (bar->end) + VERTICAL_SCROLL_BAR_MIN_HANDLE)
+      else if (win_y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE)
        *part = scroll_bar_handle;
       else
        *part = scroll_bar_below_handle;
@@ -5842,7 +5870,7 @@ x_scroll_bar_clear (f)
     for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
         bar = XSCROLL_BAR (bar)->next)
       XClearArea (FRAME_X_DISPLAY (f),
-                 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)),
+                 XSCROLL_BAR (bar)->x_window,
                  0, 0, 0, 0, True);
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 }
@@ -6013,7 +6041,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;
 
@@ -6192,6 +6220,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
           }
 #endif /* USE_TOOLKIT_SCROLL_BARS */
 
+       /* XEmbed messages from the embedder (if any).  */
+        if (event.xclient.message_type
+           == dpyinfo->Xatom_XEMBED)
+          {
+           enum xembed_message msg = event.xclient.data.l[1];
+           if (msg == XEMBED_FOCUS_IN || msg == XEMBED_FOCUS_OUT)
+             x_detect_focus_change (dpyinfo, &event, &inev.ie);
+
+           *finish = X_EVENT_GOTO_OUT;
+            goto done;
+          }
+
        f = x_any_window_to_frame (dpyinfo, event.xclient.window);
        if (!f)
          goto OTHER;
@@ -6589,19 +6629,19 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
           bzero (&compose_status, sizeof (compose_status));
           orig_keysym = keysym;
 
-         /* Common for all keysym input events.  */
-         XSETFRAME (inev.ie.frame_or_window, f);
-         inev.ie.modifiers
-           = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
-         inev.ie.timestamp = event.xkey.time;
-
-         /* First deal with keysyms which have defined
-            translations to characters.  */
-         if (keysym >= 32 && keysym < 128)
-           /* Avoid explicitly decoding each ASCII character.  */
-           {
-             inev.ie.kind = ASCII_KEYSTROKE_EVENT;
-             inev.ie.code = keysym;
+         /* Common for all keysym input events.  */
+         XSETFRAME (inev.ie.frame_or_window, f);
+         inev.ie.modifiers
+           = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
+         inev.ie.timestamp = event.xkey.time;
+
+         /* First deal with keysyms which have defined
+            translations to characters.  */
+         if (keysym >= 32 && keysym < 128)
+           /* Avoid explicitly decoding each ASCII character.  */
+           {
+             inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+             inev.ie.code = keysym;
              goto done_keysym;
            }
 
@@ -6619,18 +6659,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
          /* Now non-ASCII.  */
          if (HASH_TABLE_P (Vx_keysym_table)
              && (NATNUMP (c = Fgethash (make_number (keysym),
-                                        Vx_keysym_table,
-                                        Qnil))))
-           {
-             inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
-                             ? ASCII_KEYSTROKE_EVENT
-                             : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
-             inev.ie.code = XFASTINT (c);
-             goto done_keysym;
-           }
-
-         /* Random non-modifier sorts of keysyms.  */
-         if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
+                                        Vx_keysym_table,
+                                        Qnil))))
+           {
+             inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
+                              ? ASCII_KEYSTROKE_EVENT
+                              : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+             inev.ie.code = XFASTINT (c);
+             goto done_keysym;
+           }
+         /* Random non-modifier sorts of keysyms.  */
+         if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
                         || keysym == XK_Delete
 #ifdef XK_ISO_Left_Tab
                         || (keysym >= XK_ISO_Left_Tab
@@ -6691,14 +6731,6 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                         || (orig_keysym & (1 << 28))
                         || (keysym != NoSymbol && nbytes == 0))
                        && ! (IsModifierKey (orig_keysym)
-#ifndef HAVE_X11R5
-#ifdef XK_Mode_switch
-                             || ((unsigned)(orig_keysym) == XK_Mode_switch)
-#endif
-#ifdef XK_Num_Lock
-                             || ((unsigned)(orig_keysym) == XK_Num_Lock)
-#endif
-#endif /* not HAVE_X11R5 */
                              /* The symbols from XK_ISO_Lock
                                 to XK_ISO_Last_Group_Lock
                                 don't have real modifiers but
@@ -6769,15 +6801,13 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                  c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
                                              nbytes - i, len);
                inev.ie.kind = (SINGLE_BYTE_CHAR_P (c)
-                             ? ASCII_KEYSTROKE_EVENT
-                             : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+                               ? ASCII_KEYSTROKE_EVENT
+                               : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
                inev.ie.code = c;
                kbd_buffer_store_event_hold (&inev.ie, hold_quit);
              }
 
-           /* Previous code updated count by nchars rather than nbytes,
-              but that seems bogus to me.  ++kfs  */
-           count += nbytes;
+           count += nchars;
 
            inev.ie.kind = NO_EVENT;  /* Already stored above.  */
 
@@ -6839,7 +6869,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
       /* 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);
+        note_mouse_movement (last_mouse_glyph_frame, &event.xmotion);
 #endif
       goto OTHER;
 
@@ -6872,7 +6902,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
 #ifdef USE_GTK
       /* See comment in EnterNotify above */
       else if (last_mouse_glyph_frame)
-        note_mouse_movement (last_mouse_glyph_frame, &event);
+        note_mouse_movement (last_mouse_glyph_frame, &event.xmotion);
 #endif
       goto OTHER;
 
@@ -6915,7 +6945,13 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                    will be selected only when it is active.  */
                 if (WINDOWP (window)
                     && !EQ (window, last_window)
-                    && !EQ (window, selected_window))
+                   && !EQ (window, selected_window)
+                   /* For click-to-focus window managers
+                      create event iff we don't leave the
+                      selected frame.  */
+                   && (focus_follows_mouse
+                       || (EQ (XWINDOW (window)->frame,
+                               XWINDOW (selected_window)->frame))))
                   {
                     inev.ie.kind = SELECT_WINDOW_EVENT;
                     inev.ie.frame_or_window = window;
@@ -6952,13 +6988,20 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
 
     case ConfigureNotify:
       f = x_top_window_to_frame (dpyinfo, event.xconfigure.window);
+#ifdef USE_GTK
+      if (!f
+          && (f = x_any_window_to_frame (dpyinfo, event.xconfigure.window))
+          && event.xconfigure.window == FRAME_X_WINDOW (f))
+        {
+          xg_frame_resized (f, event.xconfigure.width,
+                            event.xconfigure.height);
+          f = 0;
+        }
+#endif  
       if (f)
         {
 #ifndef USE_X_TOOLKIT
-#ifdef USE_GTK
-          xg_resize_widgets (f, event.xconfigure.width,
-                             event.xconfigure.height);
-#else /* not USE_GTK */
+#ifndef USE_GTK
           /* If there is a pending resize for fullscreen, don't
              do this one, the right one will come later.
              The toolkit version doesn't seem to need this, but we
@@ -6988,11 +7031,11 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
               SET_FRAME_GARBAGED (f);
               cancel_mouse_face (f);
             }
-#endif /* not USE_GTK */
-#endif
 
           FRAME_PIXEL_WIDTH (f) = event.xconfigure.width;
           FRAME_PIXEL_HEIGHT (f) = event.xconfigure.height;
+#endif /* not USE_GTK */
+#endif
 
 #ifdef USE_GTK
           /* GTK creates windows but doesn't map them.
@@ -7055,12 +7098,10 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
 
                 if (tool_bar_p && event.xbutton.button < 4)
                   {
-                    if (event.xbutton.type == ButtonPress)
-                      handle_tool_bar_click (f, x, y, 1, 0);
-                    else
-                      handle_tool_bar_click (f, x, y, 0,
-                                             x_x_to_emacs_modifiers (dpyinfo,
-                                                                    event.xbutton.state));
+                   handle_tool_bar_click (f, x, y,
+                                          event.xbutton.type == ButtonPress,
+                                          x_x_to_emacs_modifiers (dpyinfo,
+                                                                  event.xbutton.state));
                   }
               }
 
@@ -7083,6 +7124,9 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                   else
                     construct_mouse_click (&inev.ie, &event.xbutton, f);
                 }
+            if (FRAME_X_EMBEDDED_P (f))
+              xembed_send_message (f, event.xbutton.time,
+                                   XEMBED_REQUEST_FOCUS, 0, 0, 0);
           }
         else
           {
@@ -7270,20 +7314,24 @@ x_dispatch_event (event, display)
    We return as soon as there are no more events to be read.
 
    We return the number of characters stored into the buffer,
-   thus pretending to be `read'.
+   thus pretending to be `read' (except the characters we store
+   in the keyboard buffer can be multibyte, so are not necessarily
+   C chars).
 
    EXPECTED is nonzero if the caller knows input is available.  */
 
 static int
-XTread_socket (sd, expected, hold_quit)
-     register int sd;
+XTread_socket (terminal, expected, hold_quit)
+     struct terminal *terminal;
      int expected;
      struct input_event *hold_quit;
 {
   int count = 0;
   XEvent event;
   int event_found = 0;
+#if 0
   struct x_display_info *dpyinfo;
+#endif
 
   if (interrupt_input_blocked)
     {
@@ -7299,6 +7347,31 @@ XTread_socket (sd, expected, hold_quit)
 
   ++handling_signal;
 
+#ifdef HAVE_X_SM
+  /* Only check session manager input for the primary display. */
+  if (terminal->id == 1 && x_session_have_connection ())
+    {
+      struct input_event inev;
+      BLOCK_INPUT;
+      /* We don't need to EVENT_INIT (inev) here, as
+         x_session_check_input copies an entire input_event.  */
+      if (x_session_check_input (&inev))
+        {
+          kbd_buffer_store_event_hold (&inev, hold_quit);
+          count++;
+        }
+      UNBLOCK_INPUT;
+    }
+#endif
+
+  /* For debugging, this gives a way to fake an I/O error.  */
+  if (terminal->display_info.x == XTread_socket_fake_io_error)
+    {
+      XTread_socket_fake_io_error = 0;
+      x_io_error_quitter (terminal->display_info.x->display);
+    }
+  
+#if 0 /* This loop is a noop now.  */
   /* Find the display we are supposed to read input for.
      It's the one communicating on descriptor SD.  */
   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
@@ -7329,52 +7402,31 @@ XTread_socket (sd, expected, hold_quit)
 #endif /* HAVE_SELECT */
 #endif /* SIGIO */
 #endif
-
-      /* For debugging, this gives a way to fake an I/O error.  */
-      if (dpyinfo == XTread_socket_fake_io_error)
-       {
-         XTread_socket_fake_io_error = 0;
-         x_io_error_quitter (dpyinfo->display);
-       }
-
-#ifdef HAVE_X_SM
-      {
-       struct input_event inev;
-       BLOCK_INPUT;
-       /* We don't need to EVENT_INIT (inev) here, as
-          x_session_check_input copies an entire input_event.  */
-       if (x_session_check_input (&inev))
-         {
-           kbd_buffer_store_event_hold (&inev, hold_quit);
-           count++;
-         }
-       UNBLOCK_INPUT;
-      }
+    }
 #endif
 
 #ifndef USE_GTK
-      while (XPending (dpyinfo->display))
-       {
-          int finish;
+  while (XPending (terminal->display_info.x->display))
+    {
+      int finish;
 
-         XNextEvent (dpyinfo->display, &event);
+      XNextEvent (terminal->display_info.x->display, &event);
 
 #ifdef HAVE_X_I18N
-          /* Filter events for the current X input method.  */
-          if (x_filter_event (dpyinfo, &event))
-            break;
+      /* Filter events for the current X input method.  */
+      if (x_filter_event (terminal->display_info.x, &event))
+        break;
 #endif
-         event_found = 1;
+      event_found = 1;
 
-          count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
+      count += handle_one_xevent (terminal->display_info.x,
+                                  &event, &finish, hold_quit);
 
-          if (finish == X_EVENT_GOTO_OUT)
-            goto out;
-        }
-#endif /* not USE_GTK */
+      if (finish == X_EVENT_GOTO_OUT)
+        goto out;
     }
 
-#ifdef USE_GTK
+#else /* USE_GTK */
 
   /* For GTK we must use the GTK event loop.  But XEvents gets passed
      to our filter function above, and then to the big event switch.
@@ -7685,8 +7737,7 @@ x_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, activ
     }
 
 #ifndef XFlush
-  if (updating_frame != f)
-    XFlush (FRAME_X_DISPLAY (f));
+  XFlush (FRAME_X_DISPLAY (f));
 #endif
 }
 
@@ -7779,7 +7830,6 @@ x_text_icon (f, icon_name)
   if (FRAME_X_WINDOW (f) == 0)
     return 1;
 
-#ifdef HAVE_X11R4
   {
     XTextProperty text;
     text.value = (unsigned char *) icon_name;
@@ -7788,9 +7838,6 @@ x_text_icon (f, icon_name)
     text.nitems = strlen (icon_name);
     XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
   }
-#else /* not HAVE_X11R4 */
-  XSetIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), icon_name);
-#endif /* not HAVE_X11R4 */
 
   if (f->output_data.x->icon_bitmap > 0)
     x_destroy_bitmap (f, f->output_data.x->icon_bitmap);
@@ -7924,6 +7971,8 @@ x_clear_errors (dpy)
   x_error_message->string[0] = 0;
 }
 
+#if 0 /* See comment in unwind_to_catch why calling this is a bad
+       * idea.  --lorentey   */
 /* Close off all unclosed x_catch_errors calls.  */
 
 void
@@ -7932,6 +7981,7 @@ x_fully_uncatch_errors ()
   while (x_error_message)
     x_uncatch_errors ();
 }
+#endif
 
 /* Nonzero if x_catch_errors has been done and not yet canceled.  */
 
@@ -7997,6 +8047,7 @@ x_connection_closed (dpy, error_message)
 {
   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
   Lisp_Object frame, tail;
+  int index = SPECPDL_INDEX ();
 
   error_msg = (char *) alloca (strlen (error_message) + 1);
   strcpy (error_msg, error_message);
@@ -8008,42 +8059,17 @@ x_connection_closed (dpy, error_message)
      the original message here.  */
   x_catch_errors (dpy);
 
-  /* We have to close the display to inform Xt that it doesn't
-     exist anymore.  If we don't, Xt will continue to wait for
-     events from the display.  As a consequence, a sequence of
+  /* Inhibit redisplay while frames are being deleted. */
+  specbind (Qinhibit_redisplay, Qt);
 
-     M-x make-frame-on-display RET :1 RET
-     ...kill the new frame, so that we get an IO error...
-     M-x make-frame-on-display RET :1 RET
-
-     will indefinitely wait in Xt for events for display `:1', opened
-     in the first class to make-frame-on-display.
-
-     Closing the display is reported to lead to a bus error on
-     OpenWindows in certain situations.  I suspect that is a bug
-     in OpenWindows.  I don't know how to cicumvent it here.  */
-
-#ifdef USE_X_TOOLKIT
-  /* If DPYINFO is null, this means we didn't open the display
-     in the first place, so don't try to close it.  */
   if (dpyinfo)
     {
-      extern void (*fatal_error_signal_hook) P_ ((void));
-      fatal_error_signal_hook = x_fatal_error_signal;
-      XtCloseDisplay (dpy);
-      fatal_error_signal_hook = NULL;
+      /* Protect display from being closed when we delete the last
+         frame on it. */
+      dpyinfo->reference_count++;
+      dpyinfo->terminal->reference_count++;
     }
-#endif
-
-#ifdef USE_GTK
-  if (dpyinfo)
-    xg_display_close (dpyinfo->display);
-#endif
-
-  /* Indicate that this display is dead.  */
-  if (dpyinfo)
-    dpyinfo->display = 0;
-
+  
   /* First delete frames whose mini-buffers are on frames
      that are on the dead display.  */
   FOR_EACH_FRAME (tail, frame)
@@ -8055,7 +8081,7 @@ x_connection_closed (dpy, error_message)
          && FRAME_X_P (XFRAME (minibuf_frame))
          && ! EQ (frame, minibuf_frame)
          && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
-       Fdelete_frame (frame, Qt);
+       Fdelete_frame (frame, Qnoelisp);
     }
 
   /* Now delete all remaining frames on the dead display.
@@ -8068,15 +8094,68 @@ x_connection_closed (dpy, error_message)
        /* Set this to t so that Fdelete_frame won't get confused
           trying to find a replacement.  */
        FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt;
-       Fdelete_frame (frame, Qt);
+       Fdelete_frame (frame, Qnoelisp);
       }
 
+  /* We have to close the display to inform Xt that it doesn't
+     exist anymore.  If we don't, Xt will continue to wait for
+     events from the display.  As a consequence, a sequence of
+
+     M-x make-frame-on-display RET :1 RET
+     ...kill the new frame, so that we get an IO error...
+     M-x make-frame-on-display RET :1 RET
+
+     will indefinitely wait in Xt for events for display `:1', opened
+     in the first call to make-frame-on-display.
+
+     Closing the display is reported to lead to a bus error on
+     OpenWindows in certain situations.  I suspect that is a bug
+     in OpenWindows.  I don't know how to circumvent it here.  */
+
   if (dpyinfo)
-    x_delete_display (dpyinfo);
+    {
+#ifdef USE_X_TOOLKIT
+      /* If DPYINFO is null, this means we didn't open the display
+        in the first place, so don't try to close it.  */
+      {
+       extern void (*fatal_error_signal_hook) P_ ((void));
+       fatal_error_signal_hook = x_fatal_error_signal;
+       XtCloseDisplay (dpy);
+       fatal_error_signal_hook = NULL;
+      }
+#endif
+
+#ifdef USE_GTK
+      /* Due to bugs in some Gtk+ versions, just exit here if this
+         is the last display/terminal. */
+      if (terminal_list->next_terminal == NULL)
+        {
+          fprintf (stderr, "%s\n", error_msg);
+          shut_down_emacs (0, 0, Qnil);
+          exit (70);
+        }
+      xg_display_close (dpyinfo->display);
+#endif
+
+      /* Indicate that this display is dead.  */
+      dpyinfo->display = 0;
+
+      dpyinfo->reference_count--;
+      dpyinfo->terminal->reference_count--;
+      if (dpyinfo->reference_count != 0)
+        /* We have just closed all frames on this display. */
+        abort ();
+
+      {
+       Lisp_Object tmp;
+       XSETTERMINAL (tmp, dpyinfo->terminal);
+       Fdelete_terminal (tmp, Qnoelisp);
+      }
+    }
 
   x_uncatch_errors ();
 
-  if (x_display_list == 0)
+  if (terminal_list == 0)
     {
       fprintf (stderr, "%s\n", error_msg);
       shut_down_emacs (0, 0, Qnil);
@@ -8090,7 +8169,11 @@ x_connection_closed (dpy, error_message)
   sigunblock (sigmask (SIGALRM));
   TOTALLY_UNBLOCK_INPUT;
 
+  unbind_to (index, Qnil);
   clear_waiting_for_input ();
+  /* Here, we absolutely have to use a non-local exit (e.g. signal, throw,
+     longjmp), because returning from this function would get us back into
+     Xlib's code which will directly call `exit'.  */
   error ("%s", error_msg);
 }
 
@@ -8221,12 +8304,17 @@ x_new_font (f, fontname)
   /* Now make the frame display the given font.  */
   if (FRAME_X_WINDOW (f) != 0)
     {
-      XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
-               FRAME_FONT (f)->fid);
-      XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc,
-               FRAME_FONT (f)->fid);
-      XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc,
-               FRAME_FONT (f)->fid);
+      Font fid;
+
+#ifdef USE_FONT_BACKEND
+      if (enable_font_backend)
+       fid = FRAME_X_DISPLAY_INFO (f)->font->fid;
+      else
+#endif
+      fid = FRAME_FONT (f)->fid;
+      XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc, fid);
+      XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc, fid);
+      XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, fid);
 
       /* Don't change the size of a tip frame; there's no point in
         doing it because it's done in Fx_show_tip, and it leads to
@@ -8379,7 +8467,7 @@ xim_destroy_callback (xim, client_data, call_data)
   FOR_EACH_FRAME (tail, frame)
     {
       struct frame *f = XFRAME (frame);
-      if (FRAME_X_DISPLAY_INFO (f) == dpyinfo)
+      if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
        {
          FRAME_XIC (f) = NULL;
           xic_free_xfontset (f);
@@ -8478,7 +8566,8 @@ xim_instantiate_callback (display, client_data, call_data)
        {
          struct frame *f = XFRAME (frame);
 
-         if (FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo)
+         if (FRAME_X_P (f)
+              && FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo)
            if (FRAME_XIC (f) == NULL)
              {
                create_frame_xic (f);
@@ -8631,7 +8720,7 @@ x_set_offset (f, xoff, yoff, change_gravity)
 {
   int modified_top, modified_left;
 
-  if (change_gravity != 0)
+  if (change_gravity > 0)
     {
       FRAME_X_OUTPUT (f)->left_before_move = f->left_pos;
       FRAME_X_OUTPUT (f)->top_before_move = f->top_pos;
@@ -8693,7 +8782,7 @@ x_set_offset (f, xoff, yoff, change_gravity)
    on the root window for frame F contains ATOMNAME.
    This is how a WM check shall be done according to the Window Manager
    Specification/Extended Window Manager Hints at
-   http://freedesktop.org/wiki/Standards_2fwm_2dspec.  */
+   http://freedesktop.org/wiki/Specifications/wm-spec.  */
 
 static int
 wm_supports (f, atomname)
@@ -8993,7 +9082,8 @@ x_sync_with_move (f, left, top, fuzzy)
           /* The left fuzz-factor is 10 pixels.  The top fuzz-factor is 40
              pixels.  */
 
-          if (abs (current_left - left) <= 10 && abs (current_top - top) <= 40)
+          if (eabs (current_left - left) <= 10
+             && eabs (current_top - top) <= 40)
             return;
   }
       else if (current_left == left && current_top == top)
@@ -9225,7 +9315,7 @@ x_ewmh_activate_frame (f)
      FRAME_PTR f;
 {
   /* See Window Manager Specification/Extended Window Manager Hints at
-     http://freedesktop.org/wiki/Standards_2fwm_2dspec  */
+     http://freedesktop.org/wiki/Specifications/wm-spec  */
 
   const char *atom = "_NET_ACTIVE_WINDOW";
   if (f->async_visible && wm_supports (f, atom))
@@ -9252,6 +9342,51 @@ XTframe_raise_lower (f, raise_flag)
     x_lower_frame (f);
 }
 \f
+/* XEmbed implementation.  */
+
+void
+xembed_set_info (f, flags)
+     struct frame *f;
+     enum xembed_info flags;
+{
+  Atom atom;
+  unsigned long data[2];
+
+  atom = XInternAtom (FRAME_X_DISPLAY (f), "_XEMBED_INFO", False);
+
+  data[0] = XEMBED_VERSION;
+  data[1] = flags;
+
+  XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), atom, atom,
+                  32, PropModeReplace, (unsigned char *) data, 2);
+}
+
+void
+xembed_send_message (f, time, message, detail, data1, data2)
+     struct frame *f;
+     Time time;
+     enum xembed_message message;
+     long detail;
+     long data1;
+     long data2;
+{
+  XEvent event;
+
+  event.xclient.type = ClientMessage;
+  event.xclient.window = FRAME_X_OUTPUT (f)->parent_desc;
+  event.xclient.message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_XEMBED;
+  event.xclient.format = 32;
+  event.xclient.data.l[0] = time;
+  event.xclient.data.l[1] = message;
+  event.xclient.data.l[2] = detail;
+  event.xclient.data.l[3] = data1;
+  event.xclient.data.l[4] = data2;
+
+  XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_OUTPUT (f)->parent_desc,
+             False, NoEventMask, &event);
+  XSync (FRAME_X_DISPLAY (f), False);
+}
+\f
 /* Change of visibility.  */
 
 /* This tries to wait until the frame is really visible.
@@ -9284,6 +9419,7 @@ x_make_frame_visible (f)
         if we get to x_make_frame_visible a second time
         before the window gets really visible.  */
       if (! FRAME_ICONIFIED_P (f)
+         && ! FRAME_X_EMBEDDED_P (f)
          && ! f->output_data.x->asked_for_visible)
        x_set_offset (f, f->left_pos, f->top_pos, 0);
 
@@ -9292,14 +9428,22 @@ x_make_frame_visible (f)
       if (! EQ (Vx_no_window_manager, Qt))
        x_wm_set_window_state (f, NormalState);
 #ifdef USE_X_TOOLKIT
-      /* This was XtPopup, but that did nothing for an iconified frame.  */
-      XtMapWidget (f->output_data.x->widget);
+      if (FRAME_X_EMBEDDED_P (f))
+       xembed_set_info (f, XEMBED_MAPPED);
+      else
+       {
+         /* This was XtPopup, but that did nothing for an iconified frame.  */
+         XtMapWidget (f->output_data.x->widget);
+       }
 #else /* not USE_X_TOOLKIT */
 #ifdef USE_GTK
       gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
       gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
 #else
-      XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+      if (FRAME_X_EMBEDDED_P (f))
+       xembed_set_info (f, XEMBED_MAPPED);
+      else
+       XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 #endif /* not USE_GTK */
 #endif /* not USE_X_TOOLKIT */
 #if 0 /* This seems to bring back scroll bars in the wrong places
@@ -9340,7 +9484,9 @@ x_make_frame_visible (f)
        because the window manager may choose the position
        and we don't want to override it.  */
 
-    if (! FRAME_VISIBLE_P (f) && ! FRAME_ICONIFIED_P (f)
+    if (! FRAME_VISIBLE_P (f)
+       && ! FRAME_ICONIFIED_P (f)
+       && ! FRAME_X_EMBEDDED_P (f)
        && f->win_gravity == NorthWestGravity
        && previously_visible)
       {
@@ -9451,9 +9597,12 @@ x_make_frame_invisible (f)
   if (FRAME_GTK_OUTER_WIDGET (f))
     gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
   else
+#else
+  if (FRAME_X_EMBEDDED_P (f))
+    xembed_set_info (f, 0);
+  else
 #endif
   {
-#ifdef HAVE_X11R4
 
   if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window,
                         DefaultScreen (FRAME_X_DISPLAY (f))))
@@ -9461,31 +9610,6 @@ x_make_frame_invisible (f)
       UNBLOCK_INPUT_RESIGNAL;
       error ("Can't notify window manager of window withdrawal");
     }
-#else /* ! defined (HAVE_X11R4) */
-
-  /*  Tell the window manager what we're going to do.  */
-  if (! EQ (Vx_no_window_manager, Qt))
-    {
-      XEvent unmap;
-
-      unmap.xunmap.type = UnmapNotify;
-      unmap.xunmap.window = window;
-      unmap.xunmap.event = DefaultRootWindow (FRAME_X_DISPLAY (f));
-      unmap.xunmap.from_configure = False;
-      if (! XSendEvent (FRAME_X_DISPLAY (f),
-                       DefaultRootWindow (FRAME_X_DISPLAY (f)),
-                       False,
-                       SubstructureRedirectMaskSubstructureNotifyMask,
-                       &unmap))
-       {
-         UNBLOCK_INPUT_RESIGNAL;
-         error ("Can't notify window manager of withdrawal");
-       }
-    }
-
-  /* Unmap the window ourselves.  Cheeky!  */
-  XUnmapWindow (FRAME_X_DISPLAY (f), window);
-#endif /* ! defined (HAVE_X11R4) */
   }
 
   /* We can't distinguish this from iconification
@@ -9581,7 +9705,9 @@ x_iconify_frame (f)
 
   /* Make sure the X server knows where the window should be positioned,
      in case the user deiconifies with the window manager.  */
-  if (! FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f))
+  if (! FRAME_VISIBLE_P (f)
+      && ! FRAME_ICONIFIED_P (f)
+      && ! FRAME_X_EMBEDDED_P (f))
     x_set_offset (f, f->left_pos, f->top_pos, 0);
 
   /* Since we don't know which revision of X we're running, we'll use both
@@ -9702,8 +9828,8 @@ x_free_frame_resources (f)
        XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 #endif /* !USE_X_TOOLKIT */
 
-      unload_color (f, f->output_data.x->foreground_pixel);
-      unload_color (f, f->output_data.x->background_pixel);
+      unload_color (f, FRAME_FOREGROUND_PIXEL (f));
+      unload_color (f, FRAME_BACKGROUND_PIXEL (f));
       unload_color (f, f->output_data.x->cursor_pixel);
       unload_color (f, f->output_data.x->cursor_foreground_pixel);
       unload_color (f, f->output_data.x->border_pixel);
@@ -9851,16 +9977,11 @@ x_wm_set_size_hint (f, flags, user_position)
        them; otherwise, we set the min_width and min_height members
        to the size for a zero x zero frame.  */
 
-#ifdef HAVE_X11R4
     size_hints.flags |= PBaseSize;
     size_hints.base_width = base_width;
     size_hints.base_height = base_height;
     size_hints.min_width  = base_width + min_cols * size_hints.width_inc;
     size_hints.min_height = base_height + min_rows * size_hints.height_inc;
-#else
-    size_hints.min_width = base_width;
-    size_hints.min_height = base_height;
-#endif
   }
 
   /* If we don't need the old flags, we don't need the old hint at all.  */
@@ -9876,12 +9997,8 @@ x_wm_set_size_hint (f, flags, user_position)
     long supplied_return;
     int value;
 
-#ifdef HAVE_X11R4
     value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints,
                               &supplied_return);
-#else
-    value = XGetNormalHints (FRAME_X_DISPLAY (f), window, &hints);
-#endif
 
 #ifdef USE_X_TOOLKIT
     size_hints.base_height = hints.base_height;
@@ -9922,11 +10039,7 @@ x_wm_set_size_hint (f, flags, user_position)
     }
 #endif /* PWinGravity */
 
-#ifdef HAVE_X11R4
   XSetWMNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
-#else
-  XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
-#endif
 }
 #endif /* not USE_GTK */
 
@@ -10356,6 +10469,11 @@ x_check_font (f, font)
 
   xassert (font != NULL);
 
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    /* Fixme: Perhaps we should check all cached fonts.  */
+    return;
+#endif
   for (i = 0; i < dpyinfo->n_fonts; i++)
     if (dpyinfo->font_table[i].name
        && font == dpyinfo->font_table[i].font)
@@ -11001,9 +11119,12 @@ get_bits_and_offset (mask, bits, offset)
   *bits = nr;
 }
 
+/* Return 1 if display DISPLAY is available for use, 0 otherwise.
+   But don't permanently open it, just test its availability.  */
+
 int
 x_display_ok (display)
-    const char * display;
+    const char *display;
 {
     int dpy_ok = 1;
     Display *dpy;
@@ -11016,6 +11137,10 @@ x_display_ok (display)
     return dpy_ok;
 }
 
+/* Open a connection to X display DISPLAY_NAME, and return
+   the structure that describes the open display.
+   If we cannot contact the display, return null.  */
+
 struct x_display_info *
 x_term_init (display_name, xrm_option, resource_name)
      Lisp_Object display_name;
@@ -11024,6 +11149,7 @@ x_term_init (display_name, xrm_option, resource_name)
 {
   int connection;
   Display *dpy;
+  struct terminal *terminal;
   struct x_display_info *dpyinfo;
   XrmDatabase xrdb;
 
@@ -11035,6 +11161,9 @@ x_term_init (display_name, xrm_option, resource_name)
       ++x_initialized;
     }
 
+  if (! x_display_ok (SDATA (display_name)))
+    error ("Display %s can't be opened", SDATA (display_name));
+
 #ifdef USE_GTK
   {
 #define NUM_ARGV 10
@@ -11043,14 +11172,21 @@ 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)
+#endif
           error ("Sorry, this version of GTK can only handle one display");
-     }
+      }
     else
       {
         for (argc = 0; argc < NUM_ARGV; ++argc)
@@ -11068,9 +11204,7 @@ x_term_init (display_name, xrm_option, resource_name)
         argv[argc++] = "--name";
         argv[argc++] = resource_name;
 
-#ifdef HAVE_X11R5
         XSetLocaleModifiers ("");
-#endif
 
         gtk_init (&argc, &argv2);
 
@@ -11135,9 +11269,7 @@ x_term_init (display_name, xrm_option, resource_name)
   }
 
 #else /* not USE_X_TOOLKIT */
-#ifdef HAVE_X11R5
   XSetLocaleModifiers ("");
-#endif
   dpy = XOpenDisplay (SDATA (display_name));
 #endif /* not USE_X_TOOLKIT */
 #endif /* not USE_GTK*/
@@ -11154,6 +11286,8 @@ x_term_init (display_name, xrm_option, resource_name)
   dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info));
   bzero (dpyinfo, sizeof *dpyinfo);
 
+  terminal = x_create_terminal (dpyinfo);
+
 #ifdef MULTI_KBOARD
   {
     struct x_display_info *share;
@@ -11165,30 +11299,31 @@ x_term_init (display_name, xrm_option, resource_name)
                         SDATA (display_name)))
        break;
     if (share)
-      dpyinfo->kboard = share->kboard;
+      terminal->kboard = share->terminal->kboard;
     else
       {
-       dpyinfo->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
-       init_kboard (dpyinfo->kboard);
+       terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+       init_kboard (terminal->kboard);
+       terminal->kboard->Vwindow_system = intern ("x");
        if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound))
          {
            char *vendor = ServerVendor (dpy);
            UNBLOCK_INPUT;
-           dpyinfo->kboard->Vsystem_key_alist
+           terminal->kboard->Vsystem_key_alist
              = call1 (Qvendor_specific_keysyms,
                       vendor ? build_string (vendor) : empty_unibyte_string);
            BLOCK_INPUT;
          }
 
-       dpyinfo->kboard->next_kboard = all_kboards;
-       all_kboards = dpyinfo->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 = dpyinfo->kboard;
+         current_kboard = terminal->kboard;
       }
-    dpyinfo->kboard->reference_count++;
+    terminal->kboard->reference_count++;
   }
 #endif
 
@@ -11203,6 +11338,11 @@ x_term_init (display_name, xrm_option, resource_name)
 
   dpyinfo->display = dpy;
 
+  /* 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);
 #endif /* ! 0 */
@@ -11251,6 +11391,13 @@ x_term_init (display_name, xrm_option, resource_name)
   dpyinfo->font_table = NULL;
   dpyinfo->n_fonts = 0;
   dpyinfo->font_table_size = 0;
+#ifdef USE_FONT_BACKEND
+  dpyinfo->font = XLoadQueryFont (dpyinfo->display, "fixed");
+  if (! dpyinfo->font)
+    dpyinfo->font = XLoadQueryFont (dpyinfo->display, "*");
+  if (! dpyinfo->font)
+    abort ();
+#endif /* USE_FONT_BACKEND */
   dpyinfo->bitmaps = 0;
   dpyinfo->bitmaps_size = 0;
   dpyinfo->bitmaps_last = 0;
@@ -11268,7 +11415,7 @@ x_term_init (display_name, xrm_option, resource_name)
   dpyinfo->x_focus_frame = 0;
   dpyinfo->x_focus_event_frame = 0;
   dpyinfo->x_highlight_frame = 0;
-  dpyinfo->image_cache = make_image_cache ();
+  dpyinfo->terminal->image_cache = make_image_cache ();
   dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
 
   /* See if we can construct pixel values from RGB values.  */
@@ -11312,8 +11459,8 @@ x_term_init (display_name, xrm_option, resource_name)
     /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
     dpyinfo->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
     pixels = DisplayWidth (dpyinfo->display, screen_number);
-    /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
     mm = DisplayWidthMM (dpyinfo->display, screen_number);
+    /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
     dpyinfo->resx = (mm < 1) ? 100 : pixels * 25.4 / mm;
   }
 
@@ -11378,6 +11525,9 @@ x_term_init (display_name, xrm_option, resource_name)
   dpyinfo->Xatom_Scrollbar = XInternAtom (dpyinfo->display, "SCROLLBAR",
                                          False);
 
+  dpyinfo->Xatom_XEMBED = XInternAtom (dpyinfo->display, "_XEMBED",
+                                      False);
+
   dpyinfo->cut_buffers_initialized = 0;
 
   dpyinfo->x_dnd_atoms_size = 8;
@@ -11423,16 +11573,9 @@ x_term_init (display_name, xrm_option, resource_name)
     add_keyboard_wait_descriptor (connection);
 #endif
 
-#ifndef F_SETOWN_BUG
 #ifdef F_SETOWN
-#ifdef F_SETOWN_SOCK_NEG
-  /* stdin is a socket here */
-  fcntl (connection, F_SETOWN, -getpid ());
-#else /* ! defined (F_SETOWN_SOCK_NEG) */
   fcntl (connection, F_SETOWN, getpid ());
-#endif /* ! defined (F_SETOWN_SOCK_NEG) */
 #endif /* ! defined (F_SETOWN) */
-#endif /* F_SETOWN_BUG */
 
 #ifdef SIGIO
   if (interrupt_input)
@@ -11440,9 +11583,6 @@ x_term_init (display_name, xrm_option, resource_name)
 #endif /* ! defined (SIGIO) */
 
 #ifdef USE_LUCID
-#ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer.  */
-  /* Make sure that we have a valid font for dialog boxes
-     so that Xt does not crash.  */
   {
     Display *dpy = dpyinfo->display;
     XrmValue d, fr, to;
@@ -11461,7 +11601,6 @@ x_term_init (display_name, xrm_option, resource_name)
       XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
     x_uncatch_errors ();
   }
-#endif
 #endif
 
   /* See if we should run in synchronous mode.  This is useful
@@ -11486,20 +11625,22 @@ x_term_init (display_name, xrm_option, resource_name)
                                    Qnil, Qnil);
 #ifdef USE_XIM
     if (STRINGP (value)
-       && (!strcmp (XSTRING (value)->data, "false")
-           || !strcmp (XSTRING (value)->data, "off")))
+       && (!strcmp (SDATA (value), "false")
+           || !strcmp (SDATA (value), "off")))
       use_xim = 0;
 #else
     if (STRINGP (value)
-       && (!strcmp (XSTRING (value)->data, "true")
-           || !strcmp (XSTRING (value)->data, "on")))
+       && (!strcmp (SDATA (value), "true")
+           || !strcmp (SDATA (value), "on")))
       use_xim = 1;
 #endif
   }
 
 #ifdef HAVE_X_SM
-  /* Only do this for the first display.  */
-  if (!x_session_initialized++)
+  /* 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 (terminal->id == 1)
     x_session_initialize (dpyinfo);
 #endif
 
@@ -11508,7 +11649,7 @@ x_term_init (display_name, xrm_option, resource_name)
   return dpyinfo;
 }
 \f
-/* Get rid of display DPYINFO, assuming all frames are already gone,
+/* Get rid of display DPYINFO, deleting all frames on it,
    and without sending any more commands to the X server.  */
 
 void
@@ -11516,6 +11657,21 @@ x_delete_display (dpyinfo)
      struct x_display_info *dpyinfo;
 {
   int i;
+  struct terminal *t;
+
+  /* Close all frames and 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)
+      {
+#ifdef HAVE_X_SM
+        /* Close X session management when we close its display.  */
+        if (t->id == 1 && x_session_have_connection ())
+          x_session_close();
+#endif
+        delete_terminal (t);
+        break;
+      }
 
   delete_keyboard_wait_descriptor (dpyinfo->connection);
 
@@ -11559,15 +11715,15 @@ x_delete_display (dpyinfo)
   XrmDestroyDatabase (dpyinfo->xrdb);
 #endif
 #endif
-#ifdef MULTI_KBOARD
-  if (--dpyinfo->kboard->reference_count == 0)
-    delete_kboard (dpyinfo->kboard);
-#endif
 #ifdef HAVE_X_I18N
   if (dpyinfo->xim)
     xim_close_dpy (dpyinfo);
 #endif
 
+#ifdef USE_FONT_BACKEND
+  if (! enable_font_backend)
+    {
+#endif
   /* Free the font names in the font table.  */
   for (i = 0; i < dpyinfo->n_fonts; i++)
     if (dpyinfo->font_table[i].name)
@@ -11583,6 +11739,10 @@ x_delete_display (dpyinfo)
        xfree (dpyinfo->font_table->font_encoder);
       xfree (dpyinfo->font_table);
     }
+#ifdef USE_FONT_BACKEND
+    }
+#endif
+
   if (dpyinfo->x_id_name)
     xfree (dpyinfo->x_id_name);
   if (dpyinfo->color_cells)
@@ -11644,71 +11804,141 @@ x_activate_timeout_atimer ()
 extern frame_parm_handler x_frame_parm_handlers[];
 
 static struct redisplay_interface x_redisplay_interface =
-{
-  x_frame_parm_handlers,
-  x_produce_glyphs,
-  x_write_glyphs,
-  x_insert_glyphs,
-  x_clear_end_of_line,
-  x_scroll_run,
-  x_after_update_window_line,
-  x_update_window_begin,
-  x_update_window_end,
-  x_cursor_to,
-  x_flush,
+  {
+    x_frame_parm_handlers,
+    x_produce_glyphs,
+    x_write_glyphs,
+    x_insert_glyphs,
+    x_clear_end_of_line,
+    x_scroll_run,
+    x_after_update_window_line,
+    x_update_window_begin,
+    x_update_window_end,
+    x_cursor_to,
+    x_flush,
 #ifdef XFlush
-  x_flush,
+    x_flush,
 #else
-  0,  /* flush_display_optional */
-#endif
-  x_clear_window_mouse_face,
-  x_get_glyph_overhangs,
-  x_fix_overlapping_area,
-  x_draw_fringe_bitmap,
-  0, /* define_fringe_bitmap */
-  0, /* destroy_fringe_bitmap */
-  x_per_char_metric,
-  x_encode_char,
-  x_compute_glyph_string_overhangs,
-  x_draw_glyph_string,
-  x_define_frame_cursor,
-  x_clear_frame_area,
-  x_draw_window_cursor,
-  x_draw_vertical_window_border,
-  x_shift_glyphs_for_insert
-};
+    0,  /* flush_display_optional */
+#endif
+    x_clear_window_mouse_face,
+    x_get_glyph_overhangs,
+    x_fix_overlapping_area,
+    x_draw_fringe_bitmap,
+    0, /* define_fringe_bitmap */
+    0, /* destroy_fringe_bitmap */
+    x_per_char_metric,
+    x_encode_char,
+    x_compute_glyph_string_overhangs,
+    x_draw_glyph_string,
+    x_define_frame_cursor,
+    x_clear_frame_area,
+    x_draw_window_cursor,
+    x_draw_vertical_window_border,
+    x_shift_glyphs_for_insert
+  };
+
+
+/* This function is called when the last frame on a display is deleted. */
+void
+x_delete_terminal (struct terminal *terminal)
+{
+  struct x_display_info *dpyinfo = terminal->display_info.x;
+  int i;
+
+  /* Protect against recursive calls.  Fdelete_frame in
+     delete_terminal calls us back when it deletes our last frame.  */
+  if (!terminal->name)
+    return;
+
+  BLOCK_INPUT;
+  /* If called from x_connection_closed, the display may already be closed
+     and dpyinfo->display was set to 0 to indicate that.  */
+  if (dpyinfo->display)
+    {
+#ifdef USE_FONT_BACKEND
+      if (enable_font_backend)
+       XFreeFont (dpyinfo->display, dpyinfo->font);
+      else
+#endif
+       /* Free the fonts in the font table.  */
+       for (i = 0; i < dpyinfo->n_fonts; i++)
+         if (dpyinfo->font_table[i].name)
+           {
+             XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
+           }
+
+      x_destroy_all_bitmaps (dpyinfo);
+      XSetCloseDownMode (dpyinfo->display, DestroyAll);
+
+#ifdef USE_GTK
+      xg_display_close (dpyinfo->display);
+#else
+#ifdef USE_X_TOOLKIT
+      XtCloseDisplay (dpyinfo->display);
+#else
+      XCloseDisplay (dpyinfo->display);
+#endif
+#endif /* ! USE_GTK */
+    }
+
+  x_delete_display (dpyinfo);
+  UNBLOCK_INPUT;
+}
+
+/* Create a struct terminal, initialize it with the X11 specific
+   functions and make DISPLAY->TERMINAL point to it.  */
+
+static struct terminal *
+x_create_terminal (struct x_display_info *dpyinfo)
+{
+  struct terminal *terminal;
+  
+  terminal = create_terminal ();
+
+  terminal->type = output_x_window;
+  terminal->display_info.x = dpyinfo;
+  dpyinfo->terminal = terminal;
+
+  /* kboard is initialized in x_term_init. */
+  
+  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->fullscreen_hook = XTfullscreen_hook;
+  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;
+  
+  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 terminal;
+}
 
 void
 x_initialize ()
 {
-  rif = &x_redisplay_interface;
-
-  clear_frame_hook = x_clear_frame;
-  ins_del_lines_hook = x_ins_del_lines;
-  delete_glyphs_hook = x_delete_glyphs;
-  ring_bell_hook = XTring_bell;
-  reset_terminal_modes_hook = XTreset_terminal_modes;
-  set_terminal_modes_hook = XTset_terminal_modes;
-  update_begin_hook = x_update_begin;
-  update_end_hook = x_update_end;
-  set_terminal_window_hook = XTset_terminal_window;
-  read_socket_hook = XTread_socket;
-  frame_up_to_date_hook = XTframe_up_to_date;
-  mouse_position_hook = XTmouse_position;
-  frame_rehighlight_hook = XTframe_rehighlight;
-  frame_raise_lower_hook = XTframe_raise_lower;
-  set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
-  condemn_scroll_bars_hook = XTcondemn_scroll_bars;
-  redeem_scroll_bar_hook = XTredeem_scroll_bar;
-  judge_scroll_bars_hook = XTjudge_scroll_bars;
-  fullscreen_hook = XTfullscreen_hook;
-
-  scroll_region_ok = 1;                /* we'll scroll partial frames */
-  char_ins_del_ok = 1;
-  line_ins_del_ok = 1;         /* we'll just blt 'em */
-  fast_clear_end_of_line = 1;  /* X does this well */
-  memory_below_frame = 0;      /* we don't remember what scrolls
-                                  off the bottom */
   baud_rate = 19200;
 
   x_noop_count = 0;
@@ -11724,7 +11954,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 ();
@@ -11755,9 +11985,11 @@ x_initialize ()
   XSetIOErrorHandler (x_io_error_quitter);
 
   /* Disable Window Change signals;  they are handled by X events.  */
+#if 0              /* Don't.  We may want to open tty frames later. */
 #ifdef SIGWINCH
   signal (SIGWINCH, SIG_DFL);
 #endif /* SIGWINCH */
+#endif
 
   signal (SIGPIPE, x_connection_signal);
 }