]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
Merged in changes from CVS trunk.
[gnu-emacs] / src / xterm.c
index 4fc9ed71abd5cc8a3d1d81931f1593e0c49a29fe..51feed59ac4198d88b55a5cb66f42929231c06c4 100644 (file)
@@ -54,7 +54,6 @@ Boston, MA 02111-1307, USA.  */
 #include <sys/ioctl.h>
 #endif /* ! defined (BSD_SYSTEM) */
 
-#include "systty.h"
 #include "systime.h"
 
 #ifndef INCLUDED_FCNTL
@@ -336,14 +335,16 @@ 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 display *x_create_frame_display P_ ((struct x_display_info *));
+void x_delete_frame_display P_ ((struct display *));
 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_ ((void));
-static void XTreset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+static void XTset_terminal_modes P_ ((struct display *));
+static void XTreset_terminal_modes P_ ((struct display *));
+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 *));
@@ -357,7 +358,7 @@ static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
                                   enum text_cursor_kinds));
 
-static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC));
+static void x_clip_to_row P_ ((struct window *, struct glyph_row *, int, GC));
 static void x_flush P_ ((struct frame *f));
 static void x_update_begin P_ ((struct frame *));
 static void x_update_window_begin P_ ((struct window *));
@@ -384,7 +385,8 @@ x_flush (f)
     {
       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));
@@ -471,7 +473,6 @@ x_update_begin (f)
   /* Nothing to do.  */
 }
 
-
 /* Start update of window W.  Set the global variable updated_window
    to the window being updated and set output_cursor to the cursor
    position of W.  */
@@ -571,9 +572,8 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
                                output_cursor.vpos,
                                output_cursor.x, output_cursor.y);
 
-      x_draw_vertical_border (w);
-
-      draw_window_fringes (w);
+      if (draw_window_fringes (w, 1))
+       x_draw_vertical_border (w);
 
       UNBLOCK_INPUT;
     }
@@ -710,12 +710,12 @@ x_draw_fringe_bitmap (w, row, p)
       int oldVH = row->visible_height;
       row->visible_height = p->h;
       row->y -= rowY - p->y;
-      x_clip_to_row (w, row, gc);
+      x_clip_to_row (w, row, -1, gc);
       row->y = oldY;
       row->visible_height = oldVH;
     }
   else
-    x_clip_to_row (w, row, gc);
+    x_clip_to_row (w, row, -1, gc);
 
   if (p->bx >= 0 && !p->overlay_p)
     {
@@ -791,7 +791,7 @@ x_draw_fringe_bitmap (w, row, p)
    rarely happens).  */
 
 static void
-XTset_terminal_modes ()
+XTset_terminal_modes (struct display *display)
 {
 }
 
@@ -799,7 +799,7 @@ XTset_terminal_modes ()
    the X-windows go away, and suspending requires no action.  */
 
 static void
-XTreset_terminal_modes ()
+XTreset_terminal_modes (struct display *display)
 {
 }
 
@@ -1411,7 +1411,8 @@ x_frame_of_widget (widget)
   for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
     if (GC_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;
@@ -2771,7 +2772,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 ();
@@ -2794,19 +2796,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)));
@@ -2824,10 +2818,6 @@ x_clear_frame ()
 
   XFlush (FRAME_X_DISPLAY (f));
 
-#ifdef USE_GTK
-  xg_frame_cleared (f);
-#endif
-
   UNBLOCK_INPUT;
 }
 
@@ -3056,7 +3046,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 ();
@@ -3730,7 +3721,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;
@@ -3929,9 +3921,9 @@ x_window_to_scroll_bar (display, window_id)
 {
   Lisp_Object tail;
 
-#ifdef USE_GTK
+#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
   window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
-#endif /* USE_GTK */
+#endif /* USE_GTK  && USE_TOOLKIT_SCROLL_BARS */
 
   for (tail = Vframe_list;
        XGCTYPE (tail) == Lisp_Cons;
@@ -3944,6 +3936,9 @@ x_window_to_scroll_bar (display, window_id)
       if (! GC_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));
@@ -3978,11 +3973,14 @@ x_window_to_menu_bar (window)
        XGCTYPE (tail) == Lisp_Cons;
        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;
@@ -4288,8 +4286,6 @@ xg_scroll_callback (widget, data)
   int part = -1, whole = 0, portion = 0;
   GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (widget));
 
-  if (xg_ignore_gtk_scrollbar) return;
-
   position = gtk_adjustment_get_value (adj);
 
   p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
@@ -4303,6 +4299,8 @@ xg_scroll_callback (widget, data)
   previous = *p;
   *p = position;
 
+  if (xg_ignore_gtk_scrollbar) return;
+
   diff = (int) (position - previous);
 
   if (diff == (int) adj->step_increment)
@@ -4334,7 +4332,7 @@ xg_scroll_callback (widget, data)
     }
 
   if (part >= 0)
-    {
+    { 
       window_being_scrolled = bar->window;
       last_scroll_bar_part = part;
       x_send_scroll_bar_event (bar->window, part, portion, whole);
@@ -4862,9 +4860,7 @@ x_scroll_bar_create (w, top, left, width, height)
                              top,
                              left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
                              width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
-                             max (height, 1),
-                             left,
-                             width);
+                             max (height, 1));
     xg_show_scroll_bar (SCROLL_BAR_X_WINDOW (bar));
 #else /* not USE_GTK */
     Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
@@ -5108,18 +5104,6 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
 #ifdef USE_TOOLKIT_SCROLL_BARS
 
-#ifdef USE_GTK
-      if (mask)
-        xg_update_scrollbar_pos (f,
-                                 SCROLL_BAR_X_WINDOW (bar),
-                                 top,
-                                 sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                                 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
-                                 max (height, 1),
-                                 left,
-                                 width);
-#else /* not USE_GTK */
-
       /* Move/size the scroll bar widget.  */
       if (mask)
        {
@@ -5128,13 +5112,21 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
          if (width > 0 && height > 0)
            x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                           left, top, width, height, False);
+#ifdef USE_GTK
+          xg_update_scrollbar_pos (f,
+                                   SCROLL_BAR_X_WINDOW (bar),
+                                   top,
+                                   sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+                                   sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM *2,
+                                   max (height, 1));
+#else /* not USE_GTK */
           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
                              sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
                              top,
                              sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
                              max (height, 1), 0);
-       }
 #endif /* not USE_GTK */
+       }
 #else /* not USE_TOOLKIT_SCROLL_BARS */
 
       /* Clear areas not covered by the scroll bar because of
@@ -5585,73 +5577,6 @@ x_scroll_bar_clear (f)
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 }
 
-\f
-/* Define a queue to save up SelectionRequest events for later handling.  */
-
-struct selection_event_queue
-  {
-    XEvent event;
-    struct selection_event_queue *next;
-  };
-
-static struct selection_event_queue *queue;
-
-/* Nonzero means queue up certain events--don't process them yet.  */
-
-static int x_queue_selection_requests;
-
-/* Queue up an X event *EVENT, to be processed later.  */
-
-static void
-x_queue_event (f, event)
-     FRAME_PTR f;
-     XEvent *event;
-{
-  struct selection_event_queue *queue_tmp
-    = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue));
-
-  if (queue_tmp != NULL)
-    {
-      queue_tmp->event = *event;
-      queue_tmp->next = queue;
-      queue = queue_tmp;
-    }
-}
-
-/* Take all the queued events and put them back
-   so that they get processed afresh.  */
-
-static void
-x_unqueue_events (display)
-     Display *display;
-{
-  while (queue != NULL)
-    {
-      struct selection_event_queue *queue_tmp = queue;
-      XPutBackEvent (display, &queue_tmp->event);
-      queue = queue_tmp->next;
-      xfree ((char *)queue_tmp);
-    }
-}
-
-/* Start queuing SelectionRequest events.  */
-
-void
-x_start_queuing_selection_requests (display)
-     Display *display;
-{
-  x_queue_selection_requests++;
-}
-
-/* Stop queuing SelectionRequest events.  */
-
-void
-x_stop_queuing_selection_requests (display)
-     Display *display;
-{
-  x_queue_selection_requests--;
-  x_unqueue_events (display);
-}
 \f
 /* The main X event-reading loop - XTread_socket.  */
 
@@ -6030,11 +5955,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
       if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner))
         goto OTHER;
 #endif /* USE_X_TOOLKIT */
-      if (x_queue_selection_requests)
-        x_queue_event (x_window_to_frame (dpyinfo, event.xselectionrequest.owner),
-                       &event);
-      else
-        {
+      {
           XSelectionRequestEvent *eventp
             = (XSelectionRequestEvent *) &event;
 
@@ -6046,7 +5967,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
           SELECTION_EVENT_PROPERTY (&inev) = eventp->property;
           SELECTION_EVENT_TIME (&inev) = eventp->time;
           inev.frame_or_window = Qnil;
-        }
+      }
       break;
 
     case PropertyNotify:
@@ -6375,37 +6296,37 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
 
           orig_keysym = keysym;
 
-         /* Common for all keysym input events.  */
-         XSETFRAME (inev.frame_or_window, f);
-         inev.modifiers
-           = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
-         inev.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.kind = ASCII_KEYSTROKE_EVENT;
-             inev.code = keysym;
-             goto done_keysym;
-           }
-
-         /* Now non-ASCII.  */
-         if (HASH_TABLE_P (Vx_keysym_table)
-             && (NATNUMP (c = Fgethash (make_number (keysym),
-                                        Vx_keysym_table,
-                                        Qnil))))
-           {
-             inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
-                           ? ASCII_KEYSTROKE_EVENT
-                           : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
-             inev.code = XFASTINT (c);
-             goto done_keysym;
-           }
-
-         /* Random non-modifier sorts of keysyms.  */
-         if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
+         /* Common for all keysym input events.  */
+         XSETFRAME (inev.frame_or_window, f);
+         inev.modifiers
+           = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
+         inev.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.kind = ASCII_KEYSTROKE_EVENT;
+             inev.code = keysym;
+             goto done_keysym;
+           }
+         /* Now non-ASCII.  */
+         if (HASH_TABLE_P (Vx_keysym_table)
+             && (NATNUMP (c = Fgethash (make_number (keysym),
+                                        Vx_keysym_table,
+                                        Qnil))))
+           {
+             inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
+                           ? ASCII_KEYSTROKE_EVENT
+                           : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+             inev.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
@@ -7038,8 +6959,8 @@ x_dispatch_event (event, display)
    EXPECTED is nonzero if the caller knows input is available.  */
 
 static int
-XTread_socket (sd, expected, hold_quit)
-     register int sd;
+XTread_socket (display, expected, hold_quit)
+     struct display *display;
      int expected;
      struct input_event *hold_quit;
 {
@@ -7217,18 +7138,19 @@ XTread_socket (sd, expected, hold_quit)
    mode lines must be clipped to the whole window.  */
 
 static void
-x_clip_to_row (w, row, gc)
+x_clip_to_row (w, row, area, gc)
      struct window *w;
      struct glyph_row *row;
+     int area;
      GC gc;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   XRectangle clip_rect;
-  int window_y, window_width;
+  int window_x, window_y, window_width;
 
-  window_box (w, -1, 0, &window_y, &window_width, 0);
+  window_box (w, area, &window_x, &window_y, &window_width, 0);
 
-  clip_rect.x = WINDOW_TO_FRAME_PIXEL_X (w, 0);
+  clip_rect.x = window_x;
   clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
   clip_rect.y = max (clip_rect.y, window_y);
   clip_rect.width = window_width;
@@ -7294,7 +7216,7 @@ x_draw_hollow_cursor (w, row)
   gc = dpyinfo->scratch_cursor_gc;
 
   /* Set clipping, draw the rectangle, and reset clipping again.  */
-  x_clip_to_row (w, row, gc);
+  x_clip_to_row (w, row, TEXT_AREA, gc);
   XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h);
   XSetClipMask (dpy, gc, None);
 }
@@ -7366,7 +7288,7 @@ x_draw_bar_cursor (w, row, width, kind)
       width = min (cursor_glyph->pixel_width, width);
 
       w->phys_cursor_width = width;
-      x_clip_to_row (w, row, gc);
+      x_clip_to_row (w, row, TEXT_AREA, gc);
 
       if (kind == BAR_CURSOR)
          XFillRectangle (dpy, window, gc,
@@ -7467,8 +7389,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
 }
 
@@ -7626,11 +7547,15 @@ x_catch_errors_unwind (old_val)
 {
   Lisp_Object first = XCAR (old_val);
   Display *dpy = XSAVE_VALUE (first)->pointer;
-
+  
   /* 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)
-    XSync (dpy, False);
+    {
+      BLOCK_INPUT;
+      XSync (dpy, False);
+      UNBLOCK_INPUT;
+    }
 
   x_error_message_string = XCDR (old_val);
   return Qnil;
@@ -7744,6 +7669,7 @@ 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);
   strcpy (error_msg, error_message);
@@ -7791,6 +7717,9 @@ x_connection_closed (dpy, error_message)
   if (dpyinfo)
     dpyinfo->display = 0;
 
+  /* Inhibit redisplay while frames are being deleted. */
+  specbind (Qinhibit_redisplay, Qt);
+
   /* First delete frames whose mini-buffers are on frames
      that are on the dead display.  */
   FOR_EACH_FRAME (tail, frame)
@@ -7823,7 +7752,7 @@ x_connection_closed (dpy, error_message)
 
   x_uncatch_errors (dpy, count);
 
-  if (x_display_list == 0)
+  if (display_list == 0)
     {
       fprintf (stderr, "%s\n", error_msg);
       shut_down_emacs (0, 0, Qnil);
@@ -7837,6 +7766,7 @@ x_connection_closed (dpy, error_message)
   sigunblock (sigmask (SIGALRM));
   TOTALLY_UNBLOCK_INPUT;
 
+  unbind_to (index, Qnil);
   clear_waiting_for_input ();
   error ("%s", error_msg);
 }
@@ -8020,14 +7950,10 @@ 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;
-         if (FRAME_XIC_FONTSET (f))
-           {
-             XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
-             FRAME_XIC_FONTSET (f) = NULL;
-           }
+          xic_free_xfontset (f);
        }
     }
 
@@ -8123,7 +8049,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);
@@ -8228,20 +8155,11 @@ x_calc_absolute_position (f)
   if (! ((flags & XNegative) || (flags & YNegative)))
     return;
 
-  /* Find the offsets of the outside upper-left corner of
-     the inner window, with respect to the outer window.
-     But do this only if we will need the results.  */
-  if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
-    /* This is to get *_pixels_outer_diff.  */
-    x_real_positions (f, &win_x, &win_y);
-
   /* Treat negative positions as relative to the leftmost bottommost
      position that fits on the screen.  */
   if (flags & XNegative)
     f->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
-                   - 2 * FRAME_X_OUTPUT (f)->x_pixels_outer_diff
-                  - FRAME_PIXEL_WIDTH (f)
-                  + f->left_pos);
+                   - FRAME_PIXEL_WIDTH (f) + f->left_pos);
 
   {
     int height = FRAME_PIXEL_HEIGHT (f);
@@ -8263,15 +8181,7 @@ x_calc_absolute_position (f)
 #endif
 
   if (flags & YNegative)
-    f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
-                  - FRAME_X_OUTPUT (f)->y_pixels_outer_diff
-
-                  /* Assume the window manager decorations are the same size on
-                     three sides, i.e. left, right and bottom.  This is to
-                     compensate for the bottom part.  */
-                  - FRAME_X_OUTPUT (f)->x_pixels_outer_diff
-                 - height
-                 + f->top_pos);
+    f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height - height + f->top_pos);
   }
 
   /* The left_pos and top_pos
@@ -8387,7 +8297,9 @@ x_check_expected_move (f)
         FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos;
         FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos;
 
-        x_set_offset (f, expect_left, expect_top, 1);
+        f->left_pos = expect_left;
+        f->top_pos = expect_top;
+        x_set_offset (f, expect_left, expect_top, 0);
       }
     else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
       FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
@@ -10163,6 +10075,7 @@ x_term_init (display_name, xrm_option, resource_name)
 {
   int connection;
   Display *dpy;
+  struct display *display;
   struct x_display_info *dpyinfo;
   XrmDatabase xrdb;
 
@@ -10297,6 +10210,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);
 
+  display = x_create_frame_display (dpyinfo);
+
 #ifdef MULTI_KBOARD
   {
     struct x_display_info *share;
@@ -10346,6 +10261,11 @@ x_term_init (display_name, xrm_option, resource_name)
 
   dpyinfo->display = dpy;
 
+  /* Set the name of the display. */
+  display->name = (char *) xmalloc (SBYTES (display_name) + 1);
+  strncpy (display->name, SDATA (display_name), SBYTES (display_name));
+  display->name[SBYTES (display_name)] = 0;
+  
 #if 0
   XSetAfterFunction (x_current_display, x_trace_wire);
 #endif /* ! 0 */
@@ -10649,7 +10569,18 @@ x_delete_display (dpyinfo)
      struct x_display_info *dpyinfo;
 {
   int i;
-
+  
+  {
+    /* Delete the generic struct display for this X display. */
+    struct display *d;
+    for (d = display_list; d; d = d->next_display)
+      if (d->type == output_x_window && d->display_info.x == dpyinfo)
+        {
+          delete_display (d);
+          break;
+        }
+  }
+    
   delete_keyboard_wait_descriptor (dpyinfo->connection);
 
   /* Discard this display from x_display_name_list and x_display_list.
@@ -10710,10 +10641,11 @@ x_delete_display (dpyinfo)
        xfree (dpyinfo->font_table[i].name);
       }
 
-  if (dpyinfo->font_table->font_encoder)
+  if (dpyinfo->font_table && dpyinfo->font_table->font_encoder)
     xfree (dpyinfo->font_table->font_encoder);
 
-  xfree (dpyinfo->font_table);
+  if (dpyinfo->font_table)
+    xfree (dpyinfo->font_table);
   xfree (dpyinfo->x_id_name);
   xfree (dpyinfo->color_cells);
   xfree (dpyinfo);
@@ -10747,70 +10679,97 @@ x_process_timeouts (timer)
 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,
-#ifndef XFlush
-  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,
 #else
-  0,  /* flush_display_optional */
+    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
-};
+    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_frame_display (struct display *display)
+{
+  /* We don't do anything, the connection to the X server must remain
+     open. */
+}
+
+
+struct display *
+x_create_frame_display (struct x_display_info *dpyinfo)
+{
+  struct display *display;
+  
+  display = create_display ();
+
+  display->type = output_x_window;
+  display->display_info.x = dpyinfo;
+  dpyinfo->frame_display = display;
+  
+  display->clear_frame_hook = x_clear_frame;
+  display->ins_del_lines_hook = x_ins_del_lines;
+  display->delete_glyphs_hook = x_delete_glyphs;
+  display->ring_bell_hook = XTring_bell;
+  display->reset_terminal_modes_hook = XTreset_terminal_modes;
+  display->set_terminal_modes_hook = XTset_terminal_modes;
+  display->update_begin_hook = x_update_begin;
+  display->update_end_hook = x_update_end;
+  display->set_terminal_window_hook = XTset_terminal_window;
+  display->read_socket_hook = XTread_socket;
+  display->frame_up_to_date_hook = XTframe_up_to_date;
+  display->mouse_position_hook = XTmouse_position;
+  display->frame_rehighlight_hook = XTframe_rehighlight;
+  display->frame_raise_lower_hook = XTframe_raise_lower;
+  display->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
+  display->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
+  display->redeem_scroll_bar_hook = XTredeem_scroll_bar;
+  display->judge_scroll_bars_hook = XTjudge_scroll_bars;
+
+  display->delete_frame_hook = x_destroy_window;
+  display->delete_display_hook = x_delete_frame_display;
+  
+  display->rif = &x_redisplay_interface;
+  display->scroll_region_ok = 1; /* We'll scroll partial frames. */
+  display->char_ins_del_ok = 1;
+  display->line_ins_del_ok = 1;        /* We'll just blt 'em. */
+  display->fast_clear_end_of_line = 1; /* X does this well. */
+  display->memory_below_frame = 0; /* We don't remember what scrolls
+                                        off the bottom. */
+
+  return display;
+}
 
 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;
-
-  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;
@@ -10865,9 +10824,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);
 }