]> code.delx.au - gnu-emacs/commitdiff
Merged in changes from CVS trunk.
authorKaroly Lorentey <lorentey@elte.hu>
Sun, 10 Oct 2004 16:41:56 +0000 (16:41 +0000)
committerKaroly Lorentey <lorentey@elte.hu>
Sun, 10 Oct 2004 16:41:56 +0000 (16:41 +0000)
Patches applied:

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-604
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-605
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-606
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-607
   Update from CVS

git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-256

1  2 
lisp/subr.el
src/config.in
src/dispextern.h
src/fringe.c
src/macterm.c
src/w32term.c
src/xdisp.c
src/xterm.c

diff --combined lisp/subr.el
index d9262da29635e23e4b8259933e0608ac27cd5f06,2abf953090aa7c90d6a42ee2a336de649121409c..ea971b99c7656f24135a8afb1573616a53923a91
@@@ -1832,18 -1832,6 +1832,18 @@@ See also `with-temp-buffer'.
         (if (window-live-p save-selected-window-window)
           (select-window save-selected-window-window 'norecord)))))
  
 +(defmacro with-selected-frame (frame &rest body)
 +  "Execute the forms in BODY with FRAME as the selected frame.
 +The value returned is the value of the last form in BODY.
 +See also `with-temp-buffer'."
 +  (declare (indent 1) (debug t))
 +  `(let ((save-selected-frame (selected-frame)))
 +     (unwind-protect
 +       (progn (select-frame ,frame)
 +              ,@body)
 +       (if (frame-live-p save-selected-frame)
 +         (select-frame save-selected-frame)))))
 +
  (defmacro with-temp-file (file &rest body)
    "Create a new buffer, evaluate BODY there, and write the buffer to FILE.
  The value returned is the value of the last form in BODY.
@@@ -2664,5 -2652,132 +2664,132 @@@ The properties used on SYMBOL are `comp
    (put symbol 'abortfunc (or abortfunc 'kill-buffer))
    (put symbol 'hookvar (or hookvar 'mail-send-hook)))
  
+ ;; Standardized progress reporting
+ ;; Progress reporter has the following structure:
+ ;;
+ ;;    (NEXT-UPDATE-VALUE . [NEXT-UPDATE-TIME
+ ;;                          MIN-VALUE
+ ;;                          MAX-VALUE
+ ;;                          MESSAGE
+ ;;                          MIN-CHANGE
+ ;;                          MIN-TIME])
+ ;;
+ ;; This weirdeness is for optimization reasons: we want
+ ;; `progress-reporter-update' to be as fast as possible, so
+ ;; `(car reporter)' is better than `(aref reporter 0)'.
+ ;;
+ ;; NEXT-UPDATE-TIME is a float.  While `float-time' loses a couple
+ ;; digits of precision, it doesn't really matter here.  On the other
+ ;; hand, it greatly simplifies the code.
+ (defun make-progress-reporter (message min-value max-value
+                                      &optional current-value
+                                      min-change min-time)
+   "Return an object suitable for reporting operation progress with `progress-reporter-update'.
+ MESSAGE is shown in the echo area.  When at least 1% of operation
+ is complete, the exact percentage will be appended to the
+ MESSAGE.  When you call `progress-reporter-done', word \"done\"
+ is printed after the MESSAGE.  You can change MESSAGE of an
+ existing progress reporter with `progress-reporter-force-update'.
+ MIN-VALUE and MAX-VALUE designate starting (0% complete) and
+ final (100% complete) states of operation.  The latter should be
+ larger; if this is not the case, then simply negate all values.
+ Optional CURRENT-VALUE specifies the progress by the moment you
+ call this function.  You should omit it or set it to nil in most
+ cases since it defaults to MIN-VALUE.
+ Optional MIN-CHANGE determines the minimal change in percents to
+ report (default is 1%.)  Optional MIN-TIME specifies the minimal
+ time before echo area updates (default is 0.2 seconds.)  If
+ `float-time' function is not present, then time is not tracked
+ at all.  If OS is not capable of measuring fractions of seconds,
+ then this parameter is effectively rounded up."
+   (unless min-time
+     (setq min-time 0.2))
+   (let ((reporter
+        (cons min-value ;; Force a call to `message' now
+              (vector (if (and (fboundp 'float-time)
+                               (>= min-time 0.02))
+                          (float-time) nil)
+                      min-value
+                      max-value
+                      message
+                      (if min-change (max (min min-change 50) 1) 1)
+                      min-time))))
+     (progress-reporter-update reporter (or current-value min-value))
+     reporter))
+ (defsubst progress-reporter-update (reporter value)
+   "Report progress of an operation in the echo area.
+ However, if the change since last echo area update is too small
+ or not enough time has passed, then do nothing (see
+ `make-progress-reporter' for details).
+ First parameter, REPORTER, should be the result of a call to
+ `make-progress-reporter'.  Second, VALUE, determines the actual
+ progress of operation; it must be between MIN-VALUE and MAX-VALUE
+ as passed to `make-progress-reporter'.
+ This function is very inexpensive, you may not bother how often
+ you call it."
+   (when (>= value (car reporter))
+     (progress-reporter-do-update reporter value)))
+ (defun progress-reporter-force-update (reporter value &optional new-message)
+   "Report progress of an operation in the echo area unconditionally.
+ First two parameters are the same as for
+ `progress-reporter-update'.  Optional NEW-MESSAGE allows you to
+ change the displayed message."
+   (let ((parameters (cdr reporter)))
+     (when new-message
+       (aset parameters 3 new-message))
+     (when (aref parameters 0)
+       (aset parameters 0 (float-time)))
+     (progress-reporter-do-update reporter value)))
+ (defun progress-reporter-do-update (reporter value)
+   (let* ((parameters   (cdr reporter))
+        (min-value    (aref parameters 1))
+        (max-value    (aref parameters 2))
+        (one-percent  (/ (- max-value min-value) 100.0))
+        (percentage   (truncate (/ (- value min-value) one-percent)))
+        (update-time  (aref parameters 0))
+        (current-time (float-time))
+        (enough-time-passed
+         ;; See if enough time has passed since the last update.
+         (or (not update-time)
+             (when (>= current-time update-time)
+               ;; Calculate time for the next update
+               (aset parameters 0 (+ update-time (aref parameters 5)))))))
+     ;;
+     ;; Calculate NEXT-UPDATE-VALUE.  If we are not going to print
+     ;; message this time because not enough time has passed, then use
+     ;; 1 instead of MIN-CHANGE.  This makes delays between echo area
+     ;; updates closer to MIN-TIME.
+     (setcar reporter
+           (min (+ min-value (* (+ percentage
+                                   (if enough-time-passed
+                                       (aref parameters 4) ;; MIN-CHANGE
+                                     1))
+                                one-percent))
+                max-value))
+     (when (integerp value)
+       (setcar reporter (ceiling (car reporter))))
+     ;;
+     ;; Only print message if enough time has passed
+     (when enough-time-passed
+       (if (> percentage 0)
+         (message "%s%d%%" (aref parameters 3) percentage)
+       (message "%s" (aref parameters 3))))))
+ (defun progress-reporter-done (reporter)
+   "Print reporter's message followed by word \"done\" in echo area."
+   (message "%sdone" (aref (cdr reporter) 3)))
  ;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc
  ;;; subr.el ends here
diff --combined src/config.in
index 6e6d61b4e02601f29c07f7d3e2d20c97605becc0,49095ca4e5afae98101b22d558c7385c475edfbb..f2cf822b6fff53672388884cecc4d4531c01dfb7
@@@ -352,6 -352,9 +352,9 @@@ Boston, MA 02111-1307, USA.  *
  /* Define to 1 if you have the <maillock.h> header file. */
  #undef HAVE_MAILLOCK_H
  
+ /* Define to 1 if you have the <malloc/malloc.h> header file. */
+ #undef HAVE_MALLOC_MALLOC_H
  /* Define to 1 if you have the `mblen' function. */
  #undef HAVE_MBLEN
  
  /* If using the C implementation of alloca, define if you know the
     direction of stack growth for your system; otherwise it will be
     automatically deduced at run-time.
-       STACK_DIRECTION > 0 => grows toward higher addresses
-       STACK_DIRECTION < 0 => grows toward lower addresses
-       STACK_DIRECTION = 0 => direction of growth unknown */
+         STACK_DIRECTION > 0 => grows toward higher addresses
+         STACK_DIRECTION < 0 => grows toward lower addresses
+         STACK_DIRECTION = 0 => direction of growth unknown */
  #undef STACK_DIRECTION
  
  /* Define to 1 if you have the ANSI C header files. */
  #define HAVE_MOUSE
  #endif
  
 +/* Multi-tty support relies on MULTI_KBOARD.  It seems safe to turn it
 +   on unconditionally. */
 +#ifndef MULTI_KBOARD
 +#define MULTI_KBOARD
 +#endif
 +
  /* Define USER_FULL_NAME to return a string
     that is the user's full name.
     It can assume that the variable `pw'
diff --combined src/dispextern.h
index 7bf3149e1b9b638088fec2699c665d3215989ba9,1e9fa483b278ff21ef32e8f31a5bdd194cfbb5c9..ecdb760e3029a371a58ece59962ea71e84d8c740
@@@ -991,6 -991,10 +991,6 @@@ extern int fonts_changed_p
  
  extern struct glyph space_glyph;
  
 -/* Frame being updated by update_window/update_frame.  */
 -
 -extern struct frame *updating_frame;
 -
  /* Window being updated by update_window.  This is non-null as long as
     update_window has not finished, and null otherwise.  It's role is
     analogous to updating_frame.  */
@@@ -1300,7 -1304,7 +1300,7 @@@ struct glyph_strin
        DESCENT = FONT->descent
        HEIGHT = FONT_HEIGHT (FONT)
        F_DESCENT = (FRAME_FONT (F)->descent
 -                   - F->output_data.x->baseline_offset)
 +                   - F->device->output_data.x->baseline_offset)
        F_HEIGHT = FRAME_LINE_HEIGHT (F)
  */
  
@@@ -2078,16 -2082,16 +2078,16 @@@ struct i
  /* Call produce_glyphs or produce_glyphs_hook, if set.  Shortcut to
     avoid the function call overhead.  */
  
 -#define PRODUCE_GLYPHS(IT)                    \
 -     do {                                     \
 -       extern int inhibit_free_realized_faces;        \
 -       if (rif != NULL)                               \
 -       rif->produce_glyphs ((IT));            \
 -       else                                   \
 -       produce_glyphs ((IT));                 \
 -       if ((IT)->glyph_row != NULL)           \
 -       inhibit_free_realized_faces = 1;       \
 -     } while (0)
 +#define PRODUCE_GLYPHS(IT)                              \
 +  do {                                                  \
 +    extern int inhibit_free_realized_faces;             \
 +    if (FRAME_RIF ((IT)->f) != NULL)                    \
 +      FRAME_RIF ((IT)->f)->produce_glyphs ((IT));       \
 +    else                                                \
 +      produce_glyphs ((IT));                            \
 +    if ((IT)->glyph_row != NULL)                        \
 +      inhibit_free_realized_faces = 1;                  \
 +  } while (0)
  
  /* Bit-flags indicating what operation move_it_to should perform.  */
  
@@@ -2261,6 -2265,10 +2261,6 @@@ struct redisplay_interfac
  #endif /* HAVE_WINDOW_SYSTEM */
  };
  
 -/* The current interface for window-based redisplay.  */
 -
 -extern struct redisplay_interface *rif;
 -
  \f
  /***********************************************************************
                                Images
@@@ -2633,7 -2641,7 +2633,7 @@@ extern int x_intersect_rectangles P_ ((
  int lookup_fringe_bitmap (Lisp_Object);
  void draw_fringe_bitmap P_ ((struct window *, struct glyph_row *, int));
  void draw_row_fringe_bitmaps P_ ((struct window *, struct glyph_row *));
void draw_window_fringes P_ ((struct window *));
int draw_window_fringes P_ ((struct window *, int));
  int update_window_fringes P_ ((struct window *, int));
  void compute_fringe_widths P_ ((struct frame *, int));
  
@@@ -2681,11 -2689,11 +2681,11 @@@ int image_ascent P_ ((struct image *, s
  
  /* Defined in sysdep.c */
  
 -void get_frame_size P_ ((int *, int *));
 +void get_tty_size P_ ((int, int *, int *));
  void request_sigio P_ ((void));
  void unrequest_sigio P_ ((void));
 -int tabs_safe_p P_ ((void));
 -void init_baud_rate P_ ((void));
 +int tabs_safe_p P_ ((int));
 +void init_baud_rate P_ ((int));
  void init_sigio P_ ((int));
  
  /* Defined in xfaces.c */
@@@ -2821,8 -2829,8 +2821,8 @@@ void clear_glyph_row P_ ((struct glyph_
  void prepare_desired_row P_ ((struct glyph_row *));
  int line_hash_code P_ ((struct glyph_row *));
  void set_window_update_flags P_ ((struct window *, int));
 -void write_glyphs P_ ((struct glyph *, int));
 -void insert_glyphs P_ ((struct glyph *, int));
 +void write_glyphs P_ ((struct frame *, struct glyph *, int));
 +void insert_glyphs P_ ((struct frame *, struct glyph *, int));
  void redraw_frame P_ ((struct frame *));
  void redraw_garbaged_frames P_ ((void));
  int scroll_cost P_ ((struct frame *, int, int, int));
@@@ -2841,38 -2849,30 +2841,38 @@@ extern Lisp_Object Qredisplay_dont_paus
  
  /* Defined in term.c */
  
 -extern void ring_bell P_ ((void));
 -extern void set_terminal_modes P_ ((void));
 -extern void reset_terminal_modes P_ ((void));
 +extern void ring_bell P_ ((struct frame *));
  extern void update_begin P_ ((struct frame *));
  extern void update_end P_ ((struct frame *));
 -extern void set_terminal_window P_ ((int));
 -extern void set_scroll_region P_ ((int, int));
 -extern void turn_off_insert P_ ((void));
 -extern void turn_off_highlight P_ ((void));
 -extern void background_highlight P_ ((void));
 -extern void clear_frame P_ ((void));
 -extern void clear_end_of_line P_ ((int));
 -extern void clear_end_of_line_raw P_ ((int));
 -extern void delete_glyphs P_ ((int));
 -extern void ins_del_lines P_ ((int, int));
 +extern void set_terminal_window P_ ((struct frame *, int));
 +extern void set_scroll_region P_ ((struct frame *, int, int));
 +extern void turn_off_insert P_ ((struct tty_display_info *));
 +extern void turn_off_highlight P_ ((struct tty_display_info *));
 +extern void background_highlight P_ ((struct tty_display_info *));
 +extern void clear_frame P_ ((struct frame *));
 +extern void clear_end_of_line P_ ((struct frame *, int));
 +extern void clear_end_of_line_raw P_ ((struct frame *, int));
 +extern void tty_clear_end_of_line P_ ((struct frame *, int));
 +extern void delete_glyphs P_ ((struct frame *, int));
 +extern void ins_del_lines P_ ((struct frame *, int, int));
  extern int string_cost P_ ((char *));
  extern int per_line_cost P_ ((char *));
  extern void calculate_costs P_ ((struct frame *));
  extern void set_tty_color_mode P_ ((struct frame *, Lisp_Object));
 -extern void tty_setup_colors P_ ((int));
 -extern void term_init P_ ((char *));
 +extern void tty_setup_colors P_ ((struct tty_display_info *, int));
 +extern struct display *get_display P_ ((Lisp_Object display));
 +extern struct display *get_named_tty_display P_ ((char *));
 +EXFUN (Fdisplay_tty_type, 1);
 +extern struct display *init_initial_display P_ ((void));
 +extern struct display *term_init P_ ((char *, char *, int));
 +extern void delete_tty P_ ((struct display *));
  extern void fatal P_ ((/* char *, ... */));
 -void cursor_to P_ ((int, int));
 -extern int tty_capable_p P_ ((struct frame *, unsigned, unsigned long, unsigned long));
 +extern void cursor_to P_ ((struct frame *, int, int));
 +extern int tty_capable_p P_ ((struct tty_display_info *, unsigned, unsigned long, unsigned long));
 +extern void tty_set_terminal_modes P_ ((struct display *));
 +extern void tty_reset_terminal_modes P_ ((struct display *));
 +extern void create_tty_output P_ ((struct frame *));
 +
  
  /* Defined in scroll.c */
  
diff --combined src/fringe.c
index 03af487c0958bfbd94ccee0732c3dfa80b7b8481,000095f470a5a4e1125adc7d3de473fc0437cdbf..e66fa4adecc11e00b4041d1c599c95d40d9512f0
@@@ -28,7 -28,6 +28,7 @@@ Boston, MA 02111-1307, USA.  *
  #include "dispextern.h"
  #include "buffer.h"
  #include "blockinput.h"
 +#include "termhooks.h"
  
  #ifdef HAVE_WINDOW_SYSTEM
  
@@@ -645,7 -644,7 +645,7 @@@ draw_fringe_bitmap_1 (w, row, left_p, o
        break;
      }
  
 -  rif->draw_fringe_bitmap (w, row, &p);
 +  FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
  }
  
  void
@@@ -723,19 -722,35 +723,35 @@@ draw_row_fringe_bitmaps (w, row
  }
  
  /* Draw the fringes of window W.  Only fringes for rows marked for
-    update in redraw_fringe_bitmaps_p are drawn.  */
+    update in redraw_fringe_bitmaps_p are drawn.
  
- void
- draw_window_fringes (w)
+    Return >0 if left or right fringe was redrawn in any way.
+    If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
+    A return value >0 indicates that the vertical line between windows
+    needs update (as it may be drawn in the fringe).
+ */
+ int
+ draw_window_fringes (w, no_fringe)
       struct window *w;
+      int no_fringe;
  {
    struct glyph_row *row;
    int yb = window_text_bottom_y (w);
    int nrows = w->current_matrix->nrows;
    int y = 0, rn;
+   int updated = 0;
  
    if (w->pseudo_window_p)
-     return;
+     return 0;
+   /* Must draw line if no fringe */
+   if (no_fringe
+       && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
+         || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0))
+     updated++;
  
    for (y = 0, rn = 0, row = w->current_matrix->rows;
         y < yb && rn < nrows;
        continue;
        draw_row_fringe_bitmaps (w, row);
        row->redraw_fringe_bitmaps_p = 0;
+       updated++;
      }
+   return updated;
  }
  
  
@@@ -951,11 -969,7 +970,7 @@@ update_window_fringes (w, force_p
     Typically, we add an equal amount (+/- 1 pixel) to each fringe,
     but a negative width value is taken literally (after negating it).
  
-    We never make the fringes narrower than specified.  It is planned
-    to make fringe bitmaps customizable and expandable, and at that
-    time, the user will typically specify the minimum number of pixels
-    needed for his bitmaps, so we shouldn't select anything less than
-    what is specified.
+    We never make the fringes narrower than specified.
  */
  
  void
@@@ -1053,8 -1067,6 +1068,8 @@@ destroy_fringe_bitmap (n
    fbp = &fringe_bitmaps[n];
    if (*fbp && (*fbp)->dynamic)
      {
 +      /* XXX Is SELECTED_FRAME OK here? */
 +      struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
        if (rif && rif->destroy_fringe_bitmap)
        rif->destroy_fringe_bitmap (n);
        xfree (*fbp);
@@@ -1160,9 -1172,6 +1175,9 @@@ init_fringe_bitmap (which, fb, once_p
  
    if (!once_p)
      {
 +      /* XXX Is SELECTED_FRAME OK here? */
 +      struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
 +
        destroy_fringe_bitmap (which);
  
        if (rif && rif->define_fringe_bitmap)
@@@ -1358,6 -1367,7 +1373,6 @@@ Return nil if POS is not visible in WIN
       Lisp_Object pos, window;
  {
    struct window *w;
 -  struct buffer *old_buffer = NULL;
    struct glyph_row *row;
    int textpos;
  
diff --combined src/macterm.c
index 56c4653bf4320e0491058e6357e945ed6b2be2a0,a5e1de9be0812e4ad81cb81a36295be26b2432c7..b7ebaea09903cfcba7362000533d9d955db8fd9f
@@@ -1291,9 -1291,8 +1291,8 @@@ x_update_window_end (w, cursor_on_p, mo
                                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;
      }
@@@ -5050,7 -5049,7 +5049,7 @@@ mac_get_window_bounds (f, inner, outer
    GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowStructureRgn, outer);
  #else /* not TARGET_API_MAC_CARBON */
    RgnHandle region = NewRgn ();
-     
    GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowContentRgn, region);
    *inner = (*region)->rgnBBox;
    GetWindowRegion (FRAME_MAC_WINDOW (f), kWindowStructureRgn, region);
@@@ -5143,7 -5142,7 +5142,7 @@@ x_set_offset (f, xoff, yoff, change_gra
    {
      Rect inner, outer, screen_rect, dummy;
      RgnHandle region = NewRgn ();
-     
      mac_get_window_bounds (f, &inner, &outer);
      f->x_pixels_diff = inner.left - outer.left;
      f->y_pixels_diff = inner.top - outer.top;
@@@ -8114,7 -8113,7 +8113,7 @@@ XTread_socket (sd, expected, hold_quit
        switch (GetEventClass (eventRef))
          {
          case kEventClassWindow:
-           if (GetEventKind (eventRef) == kEventWindowBoundsChanged) 
+           if (GetEventKind (eventRef) == kEventWindowBoundsChanged)
              {
                WindowPtr window_ptr;
                GetEventParameter(eventRef, kEventParamDirectObject,
  
            if (!is_emacs_window (window_ptr))
              break;
-           
            f = mac_window_to_frame (window_ptr);
  
            if ((er.modifiers & activeFlag) != 0)
@@@ -9159,13 -9158,12 +9158,13 @@@ mac_initialize (
    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 */
 +  TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
 +  TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
 +  TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
 +  TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
 +  TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
 +                                                         scrolls off the
 +                                                         bottom */
    baud_rate = 19200;
  
    x_noop_count = 0;
diff --combined src/w32term.c
index 7e36845eaf3a23cbe6042dd248ed124d47be5bf0,3956fd4b26109098f2569cd835a5f19b59370bfb..3d50e93b761137caa6134ccffe0e6aecc2c55778
@@@ -540,9 -540,8 +540,8 @@@ x_update_window_end (w, cursor_on_p, mo
                                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;
      }
@@@ -6385,13 -6384,12 +6384,13 @@@ w32_initialize (
    redeem_scroll_bar_hook = w32_redeem_scroll_bar;
    judge_scroll_bars_hook = w32_judge_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 */
 +  TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
 +  TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
 +  TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
 +  TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
 +  TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
 +                                                            scrolls off the
 +                                                            bottom */
    baud_rate = 19200;
  
    w32_system_caret_hwnd = NULL;
diff --combined src/xdisp.c
index 0e25b0a3de3e07ac98741dda9a657195a905dc93,b7a24a4364b5076c0ba96bf1dd16940b5ca6cf16..191e0427c66b32912615138e43e79cc8e8ae851f
@@@ -769,6 -769,10 +769,6 @@@ enum move_it_resul
  #define CLEAR_FACE_CACHE_COUNT        500
  static int clear_face_cache_count;
  
 -/* Record the previous terminal frame we displayed.  */
 -
 -static struct frame *previous_terminal_frame;
 -
  /* Non-zero while redisplay_internal is in progress.  */
  
  int redisplaying_p;
@@@ -2059,7 -2063,7 +2059,7 @@@ init_iterator (it, w, charpos, bytepos
    XSETWINDOW (it->window, w);
    it->w = w;
    it->f = XFRAME (w->frame);
 -
 +  
    /* Extra space between lines (on window systems only).  */
    if (base_face_id == DEFAULT_FACE_ID
        && FRAME_WINDOW_P (it->f))
  
    /* If realized faces have been removed, e.g. because of face
       attribute changes of named faces, recompute them.  When running
 -     in batch mode, the face cache of Vterminal_frame is null.  If
 +     in batch mode, the face cache of the initial frame is null.  If
       we happen to get called, make a dummy face cache.  */
 -  if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
 +  if (FRAME_FACE_CACHE (it->f) == NULL)
      init_frame_faces (it->f);
    if (FRAME_FACE_CACHE (it->f)->used == 0)
      recompute_basic_faces (it->f);
@@@ -6663,8 -6667,8 +6663,8 @@@ message2_nolog (m, nbytes, multibyte
        do_pending_window_change (0);
        echo_area_display (1);
        do_pending_window_change (0);
 -      if (frame_up_to_date_hook != 0 && ! gc_in_progress)
 -      (*frame_up_to_date_hook) (f);
 +      if (FRAME_DISPLAY (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
 +      (*FRAME_DISPLAY (f)->frame_up_to_date_hook) (f);
      }
  }
  
@@@ -6749,8 -6753,8 +6749,8 @@@ message3_nolog (m, nbytes, multibyte
        do_pending_window_change (0);
        echo_area_display (1);
        do_pending_window_change (0);
 -      if (frame_up_to_date_hook != 0 && ! gc_in_progress)
 -      (*frame_up_to_date_hook) (f);
 +      if (FRAME_DISPLAY (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
 +      (*FRAME_DISPLAY (f)->frame_up_to_date_hook) (f);
      }
  }
  
@@@ -7773,11 -7777,11 +7773,11 @@@ clear_garbaged_frames (
      {
        Lisp_Object tail, frame;
        int changed_count = 0;
 -
 +      
        FOR_EACH_FRAME (tail, frame)
        {
          struct frame *f = XFRAME (frame);
 -
 +        
          if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
            {
              if (f->resized_p)
              f->resized_p = 0;
            }
        }
 -
 +      
        frame_garbaged = 0;
        if (changed_count)
        ++windows_or_buffers_changed;
@@@ -7824,11 -7828,11 +7824,11 @@@ echo_area_display (update_frame_p
  /* The terminal frame is used as the first Emacs frame on the Mac OS.  */
  #ifndef MAC_OS8
  #ifdef HAVE_WINDOW_SYSTEM
 -  /* When Emacs starts, selected_frame may be a visible terminal
 -     frame, even if we run under a window system.  If we let this
 -     through, a message would be displayed on the terminal.  */
 -  if (EQ (selected_frame, Vterminal_frame)
 -      && !NILP (Vwindow_system))
 +  /* When Emacs starts, selected_frame may be the initial terminal
 +     frame.  If we let this through, a message would be displayed on
 +     the terminal.  */
 +  if (FRAME_TERMCAP_P (XFRAME (selected_frame))
 +      && FRAME_TTY (XFRAME (selected_frame))->type == NULL)
      return 0;
  #endif /* HAVE_WINDOW_SYSTEM */
  #endif
                 Can do with a display update of the echo area,
                 unless we displayed some mode lines.  */
              update_single_window (w, 1);
 -            rif->flush_display (f);
 +            FRAME_RIF (f)->flush_display (f);
            }
          else
            update_frame (f, 1, 1);
@@@ -8340,8 -8344,8 +8340,8 @@@ x_cursor_to (vpos, hpos, y, x
      {
        BLOCK_INPUT;
        display_and_set_cursor (w, 1, hpos, vpos, x, y);
 -      if (rif->flush_display_optional)
 -      rif->flush_display_optional (SELECTED_FRAME ());
 +      if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
 +      FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
        UNBLOCK_INPUT;
      }
  }
@@@ -9762,16 -9766,17 +9762,16 @@@ redisplay_internal (preserve_echo_area
    if (face_change_count)
      ++windows_or_buffers_changed;
  
 -  if (! FRAME_WINDOW_P (sf)
 -      && previous_terminal_frame != sf)
 +  if (FRAME_TERMCAP_P (sf)
 +      && FRAME_TTY (sf)->previous_terminal_frame != sf)
      {
 -      /* Since frames on an ASCII terminal share the same display
 -       area, displaying a different frame means redisplay the whole
 -       thing.  */
 +      /* Since frames on a single ASCII terminal share the same
 +       display area, displaying a different frame means redisplay
 +       the whole thing.  */
        windows_or_buffers_changed++;
        SET_FRAME_GARBAGED (sf);
 -      XSETFRAME (Vterminal_frame, sf);
 +      FRAME_TTY (sf)->previous_terminal_frame = sf;
      }
 -  previous_terminal_frame = sf;
  
    /* Set the visible flags for all frames.  Do this before checking
       for resized or garbaged frames; they want to know if their frames
        }
    }
  
 +  
    /* Notice any pending interrupt request to change frame size.  */
    do_pending_window_change (1);
  
        {
          struct frame *f = XFRAME (frame);
  
 -        if (FRAME_WINDOW_P (f) || f == sf)
 +        if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
            {
              if (! EQ (frame, selected_frame))
                /* Select the frame, for the sake of frame-local
  
              /* Mark all the scroll bars to be removed; we'll redeem
                 the ones we want when we redisplay their windows.  */
 -            if (condemn_scroll_bars_hook)
 -              condemn_scroll_bars_hook (f);
 +            if (FRAME_DISPLAY (f)->condemn_scroll_bars_hook)
 +              FRAME_DISPLAY (f)->condemn_scroll_bars_hook (f);
  
              if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
                redisplay_windows (FRAME_ROOT_WINDOW (f));
  
              /* Any scroll bars which redisplay_windows should have
                 nuked should now go away.  */
 -            if (judge_scroll_bars_hook)
 -              judge_scroll_bars_hook (f);
 +            if (FRAME_DISPLAY (f)->judge_scroll_bars_hook)
 +              FRAME_DISPLAY (f)->judge_scroll_bars_hook (f);
  
              /* If fonts changed, display again.  */
              /* ??? rms: I suspect it is a mistake to jump all the way
            {
              struct frame *f = updated[i];
              mark_window_display_accurate (f->root_window, 1);
 -            if (frame_up_to_date_hook)
 -              frame_up_to_date_hook (f);
 +            if (FRAME_DISPLAY (f)->frame_up_to_date_hook)
 +              FRAME_DISPLAY (f)->frame_up_to_date_hook (f);
            }
        }
      }
          /* Say overlay arrows are up to date.  */
          update_overlay_arrows (1);
  
 -        if (frame_up_to_date_hook != 0)
 -          frame_up_to_date_hook (sf);
 +        if (FRAME_DISPLAY (sf)->frame_up_to_date_hook != 0)
 +          FRAME_DISPLAY (sf)->frame_up_to_date_hook (sf);
        }
  
        update_mode_lines = 0;
@@@ -11516,9 -11520,7 +11516,9 @@@ set_vertical_scroll_bar (w
      start = end = whole = 0;
  
    /* Indicate what this scroll bar ought to be displaying now.  */
 -  set_vertical_scroll_bar_hook (w, end - start, whole, start);
 +  if (FRAME_DISPLAY (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
 +    (*FRAME_DISPLAY (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
 +      (w, end - start, whole, start);
  }
  
  
@@@ -12218,7 -12220,8 +12218,8 @@@ redisplay_window (window, just_this_one
      {
        update_begin (f);
        BLOCK_INPUT;
-       draw_window_fringes (w);
+       if (draw_window_fringes (w, 1))
+       x_draw_vertical_border (w);
        UNBLOCK_INPUT;
        update_end (f);
      }
  
        /* Note that we actually used the scroll bar attached to this
         window, so it shouldn't be deleted at the end of redisplay.  */
 -      redeem_scroll_bar_hook (w);
 +      if (FRAME_DISPLAY (f)->redeem_scroll_bar_hook)
 +        (*FRAME_DISPLAY (f)->redeem_scroll_bar_hook) (w);
      }
  
    /* Restore current_buffer and value of point in it.  */
@@@ -12475,10 -12477,10 +12476,10 @@@ try_window_reusing_current_matrix (w
          if (run.height > 0 && run.current_y != run.desired_y)
            {
              update_begin (f);
 -            rif->update_window_begin_hook (w);
 -            rif->clear_window_mouse_face (w);
 -            rif->scroll_run_hook (w, &run);
 -            rif->update_window_end_hook (w, 0, 0);
 +            FRAME_RIF (f)->update_window_begin_hook (w);
 +            FRAME_RIF (f)->clear_window_mouse_face (w);
 +            FRAME_RIF (f)->scroll_run_hook (w, &run);
 +            FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
              update_end (f);
            }
  
        if (run.height)
        {
          update_begin (f);
 -        rif->update_window_begin_hook (w);
 -        rif->clear_window_mouse_face (w);
 -        rif->scroll_run_hook (w, &run);
 -        rif->update_window_end_hook (w, 0, 0);
 +        FRAME_RIF (f)->update_window_begin_hook (w);
 +        FRAME_RIF (f)->clear_window_mouse_face (w);
 +        FRAME_RIF (f)->scroll_run_hook (w, &run);
 +        FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
          update_end (f);
        }
  
@@@ -13098,7 -13100,7 +13099,7 @@@ try_window_id (w
  
    /* Window must either use window-based redisplay or be full width.  */
    if (!FRAME_WINDOW_P (f)
 -      && (!line_ins_del_ok
 +      && (!FRAME_LINE_INS_DEL_OK (f)
          || !WINDOW_FULL_WIDTH_P (w)))
      GIVE_UP (4);
  
  
        if (FRAME_WINDOW_P (f))
        {
 -        rif->update_window_begin_hook (w);
 -        rif->clear_window_mouse_face (w);
 -        rif->scroll_run_hook (w, &run);
 -        rif->update_window_end_hook (w, 0, 0);
 +        FRAME_RIF (f)->update_window_begin_hook (w);
 +        FRAME_RIF (f)->clear_window_mouse_face (w);
 +        FRAME_RIF (f)->scroll_run_hook (w, &run);
 +        FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
        }
        else
        {
            {
              /* Scroll last_unchanged_at_beg_row to the end of the
                 window down dvpos lines.  */
 -            set_terminal_window (end);
 +            set_terminal_window (f, end);
  
              /* On dumb terminals delete dvpos lines at the end
                 before inserting dvpos empty lines.  */
 -            if (!scroll_region_ok)
 -              ins_del_lines (end - dvpos, -dvpos);
 +            if (!FRAME_SCROLL_REGION_OK (f))
 +              ins_del_lines (f, end - dvpos, -dvpos);
  
              /* Insert dvpos empty lines in front of
                   last_unchanged_at_beg_row.  */
 -            ins_del_lines (from, dvpos);
 +            ins_del_lines (f, from, dvpos);
            }
          else if (dvpos < 0)
            {
              /* Scroll up last_unchanged_at_beg_vpos to the end of
                 the window to last_unchanged_at_beg_vpos - |dvpos|.  */
 -            set_terminal_window (end);
 +            set_terminal_window (f, end);
  
              /* Delete dvpos lines in front of
                 last_unchanged_at_beg_vpos.  ins_del_lines will set
                 the cursor to the given vpos and emit |dvpos| delete
                 line sequences.  */
 -            ins_del_lines (from + dvpos, dvpos);
 +            ins_del_lines (f, from + dvpos, dvpos);
  
              /* On a dumb terminal insert dvpos empty lines at the
                   end.  */
 -            if (!scroll_region_ok)
 -              ins_del_lines (end + dvpos, -dvpos);
 +            if (!FRAME_SCROLL_REGION_OK (f))
 +              ins_del_lines (f, end + dvpos, -dvpos);
            }
  
 -        set_terminal_window (0);
 +        set_terminal_window (f, 0);
        }
  
        update_end (f);
@@@ -16505,8 -16507,8 +16506,8 @@@ decode_mode_spec (w, c, field_width, pr
          {
            /* No need to mention EOL here--the terminal never needs
               to do EOL conversion.  */
 -          p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
 -          p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
 +          p = decode_mode_spec_coding (FRAME_KEYBOARD_CODING (f)->symbol, p, 0);
 +          p = decode_mode_spec_coding (FRAME_TERMINAL_CODING (f)->symbol, p, 0);
          }
        p = decode_mode_spec_coding (b->buffer_file_coding_system,
                                     p, eol_flag);
@@@ -17343,7 -17345,7 +17344,7 @@@ get_glyph_face_and_encoding (f, glyph, 
            = FONT_INFO_FROM_ID (f, face->font_info_id);
          if (font_info)
            glyph->font_type
 -            = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
 +            = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
        }
      }
  
@@@ -17574,7 -17576,7 +17575,7 @@@ x_get_glyph_overhangs (glyph, f, left, 
        font = face->font;
        font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
        if (font  /* ++KFS: Should this be font_info ?  */
 -        && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
 +        && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
        {
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
@@@ -17742,7 -17744,7 +17743,7 @@@ get_char_face_and_encoding (f, c, face_
          struct font_info *font_info
            = FONT_INFO_FROM_ID (f, face->font_info_id);
          if (font_info)
 -          rif->encode_char (c, char2b, font_info, 0);
 +          FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
        }
      }
  
@@@ -17809,8 -17811,8 +17810,8 @@@ compute_overhangs_and_x (s, x, backward
      {
        while (s)
        {
 -        if (rif->compute_glyph_string_overhangs)
 -          rif->compute_glyph_string_overhangs (s);
 +        if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
 +          FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
          x -= s->width;
          s->x = x;
          s = s->prev;
      {
        while (s)
        {
 -        if (rif->compute_glyph_string_overhangs)
 -          rif->compute_glyph_string_overhangs (s);
 +        if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
 +          FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
          s->x = x;
          x += s->width;
          s = s->next;
@@@ -18102,9 -18104,9 +18103,9 @@@ draw_glyphs (w, x, row, area, start, en
        struct glyph_string *h, *t;
  
        /* Compute overhangs for all glyph strings.  */
 -      if (rif->compute_glyph_string_overhangs)
 +      if (FRAME_RIF (f)->compute_glyph_string_overhangs)
        for (s = head; s; s = s->next)
 -        rif->compute_glyph_string_overhangs (s);
 +        FRAME_RIF (f)->compute_glyph_string_overhangs (s);
  
        /* Prepend glyph strings for glyphs in front of the first glyph
         string that are overwritten because of the first glyph
  
    /* Draw all strings.  */
    for (s = head; s; s = s->next)
 -    rif->draw_glyph_string (s);
 +    FRAME_RIF (f)->draw_glyph_string (s);
  
    if (area == TEXT_AREA
        && !row->full_width_p
@@@ -18859,20 -18861,20 +18860,20 @@@ x_produce_glyphs (it
  
          it->nglyphs = 1;
  
 -        pcm = rif->per_char_metric (font, &char2b,
 -                                    FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
 -
 -        if (it->override_ascent >= 0)
 -          {
 -            it->ascent = it->override_ascent;
 -            it->descent = it->override_descent;
 -            boff = it->override_boff;
 -          }
 -        else
 -          {
 -            it->ascent = FONT_BASE (font) + boff;
 -            it->descent = FONT_DESCENT (font) - boff;
 -          }
 +          pcm = FRAME_RIF (it->f)->per_char_metric
 +            (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
 +
 +        if (it->override_ascent >= 0)
 +          {
 +            it->ascent = it->override_ascent;
 +            it->descent = it->override_descent;
 +            boff = it->override_boff;
 +          }
 +        else
 +          {
 +            it->ascent = FONT_BASE (font) + boff;
 +            it->descent = FONT_DESCENT (font) - boff;
 +          }
  
          if (pcm)
            {
             from the charset width; this is what old redisplay code
             did.  */
  
 -        pcm = rif->per_char_metric (font, &char2b,
 -                                    FONT_TYPE_FOR_MULTIBYTE (font, it->c));
 +        pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
 +                                                    FONT_TYPE_FOR_MULTIBYTE (font, it->c));
  
          if (font_not_found_p || !pcm)
            {
  
          /* Initialize the bounding box.  */
          if (font_info
 -            && (pcm = rif->per_char_metric (font, &char2b,
 -                                            FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
 +            && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
 +                                                            FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
            {
              width = pcm->width;
              ascent = pcm->ascent;
                }
  
              if (font_info
 -                && (pcm = rif->per_char_metric (font, &char2b,
 -                                                FONT_TYPE_FOR_MULTIBYTE (font, ch))))
 +                && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
 +                                                                FONT_TYPE_FOR_MULTIBYTE (font, ch))))
                {
                  width = pcm->width;
                  ascent = pcm->ascent;
@@@ -19503,8 -19505,8 +19504,8 @@@ x_insert_glyphs (start, len
    frame_x = window_box_left (w, updated_area) + output_cursor.x;
    frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
  
 -  rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
 -                              line_height, shift_by_width);
 +  FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
 +                                          line_height, shift_by_width);
  
    /* Write the glyphs.  */
    hpos = start - row->glyphs[updated_area];
@@@ -19586,8 -19588,8 +19587,8 @@@ x_clear_end_of_line (to_x
    if (to_x > from_x && to_y > from_y)
      {
        BLOCK_INPUT;
 -      rif->clear_frame_area (f, from_x, from_y,
 -                           to_x - from_x, to_y - from_y);
 +      FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
 +                                       to_x - from_x, to_y - from_y);
        UNBLOCK_INPUT;
      }
  }
@@@ -20049,8 -20051,8 +20050,8 @@@ erase_phys_cursor (w
        x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
        y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
  
 -      rif->clear_frame_area (f, x, y,
 -                           cursor_glyph->pixel_width, cursor_row->visible_height);
 +      FRAME_RIF (f)->clear_frame_area (f, x, y,
 +                                       cursor_glyph->pixel_width, cursor_row->visible_height);
      }
  
    /* Erase the cursor by redrawing the character underneath it.  */
@@@ -20147,9 -20149,9 +20148,9 @@@ display_and_set_cursor (w, on, hpos, vp
        w->phys_cursor.vpos = vpos;
      }
  
 -  rif->draw_window_cursor (w, glyph_row, x, y,
 -                         new_cursor_type, new_cursor_width,
 -                         on, active_cursor);
 +  FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
 +                                     new_cursor_type, new_cursor_width,
 +                                     on, active_cursor);
  }
  
  
@@@ -20294,11 -20296,11 +20295,11 @@@ show_mouse_face (dpyinfo, draw
  
    /* Change the mouse cursor.  */
    if (draw == DRAW_NORMAL_TEXT)
 -    rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
 +    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
    else if (draw == DRAW_MOUSE_FACE)
 -    rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
 +    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
    else
 -    rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
 +    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
  }
  
  /* EXPORT:
@@@ -20712,6 -20714,7 +20713,6 @@@ on_hot_spot_p (hot_spot, x, y
          return inside;
        }
      }
 -  /* If we don't understand the format, pretend we're not in the hot-spot.  */
    return 0;
  }
  
@@@ -20791,7 -20794,7 +20792,7 @@@ define_frame_cursor1 (f, cursor, pointe
      }
  
    if (cursor != No_Cursor)
 -    rif->define_frame_cursor (f, cursor);
 +    FRAME_RIF (f)->define_frame_cursor (f, cursor);
  }
  
  /* Take proper action when mouse has moved to the mode or header line
@@@ -21608,8 -21611,8 +21609,8 @@@ phys_cursor_in_rect_p (w, r
         I assume the effect is the same -- and this is portable.  */
        return x_intersect_rectangles (&cr, r, &result);
      }
 -  else
 -    return 0;
 +  /* If we don't understand the format, pretend we're not in the hot-spot.  */
 +  return 0;
  }
  
  
  x_draw_vertical_border (w)
       struct window *w;
  {
 +  struct frame *f = XFRAME (WINDOW_FRAME (w));
 +  
    /* We could do better, if we knew what type of scroll-bar the adjacent
       windows (on either side) have...  But we don't :-(
       However, I think this works ok.  ++KFS 2003-04-25 */
        window_box_edges (w, -1, &x0, &y0, &x1, &y1);
        y1 -= 1;
  
 -      rif->draw_vertical_window_border (w, x1, y0, y1);
 +      FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
      }
    else if (!WINDOW_LEFTMOST_P (w)
           && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
        window_box_edges (w, -1, &x0, &y0, &x1, &y1);
        y1 -= 1;
  
 -      rif->draw_vertical_window_border (w, x0, y0, y1);
 +      FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
      }
  }
  
diff --combined src/xterm.c
index 69e04de2eb8ecb623ef9977893152d9198397ed3,131753f893cd3eeedac029cadc7b73499d712490..db4914bc1654fe852d7475ab4f39d48bddbcf56b
@@@ -54,6 -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
@@@ -335,16 -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 *));
@@@ -385,8 -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));
@@@ -473,6 -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.  */
@@@ -572,9 -571,8 +572,8 @@@ x_update_window_end (w, cursor_on_p, mo
                                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;
      }
@@@ -792,7 -790,7 +791,7 @@@ x_draw_fringe_bitmap (w, row, p
     rarely happens).  */
  
  static void
 -XTset_terminal_modes ()
 +XTset_terminal_modes (struct display *display)
  {
  }
  
     the X-windows go away, and suspending requires no action.  */
  
  static void
 -XTreset_terminal_modes ()
 +XTreset_terminal_modes (struct display *display)
  {
  }
  
@@@ -1412,8 -1410,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;
@@@ -2773,8 -2770,7 +2772,8 @@@ x_shift_glyphs_for_insert (f, x, y, wid
     for X frames.  */
  
  static void
 -x_delete_glyphs (n)
 +x_delete_glyphs (f, n)
 +     struct frame *f;
       register int n;
  {
    abort ();
@@@ -2801,8 -2797,15 +2800,8 @@@ x_clear_area (dpy, window, x, y, width
     frame.  Otherwise clear the selected 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)));
@@@ -3052,8 -3055,7 +3051,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 ();
@@@ -3727,8 -3729,7 +3726,8 @@@ XTmouse_position (fp, insist, bar_windo
  
        /* 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;
@@@ -3942,9 -3943,6 +3941,9 @@@ x_window_to_scroll_bar (display, window
        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));
@@@ -3979,14 -3977,11 +3978,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;
@@@ -6379,37 -6374,37 +6378,37 @@@ handle_one_xevent (dpyinfo, eventp, fin
  
            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
@@@ -7042,8 -7037,8 +7041,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;
  {
@@@ -7630,7 -7625,7 +7629,7 @@@ 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)
@@@ -7748,7 -7743,6 +7747,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);
    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)
  
    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);
    sigunblock (sigmask (SIGALRM));
    TOTALLY_UNBLOCK_INPUT;
  
 +  unbind_to (index, Qnil);
    clear_waiting_for_input ();
    error ("%s", error_msg);
  }
@@@ -8029,7 -8019,7 +8028,7 @@@ xim_destroy_callback (xim, client_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))
@@@ -8132,8 -8122,7 +8131,8 @@@ xim_instantiate_callback (display, clie
        {
          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);
@@@ -10173,7 -10162,6 +10172,7 @@@ x_term_init (display_name, xrm_option, 
  {
    int connection;
    Display *dpy;
 +  struct display *display;
    struct x_display_info *dpyinfo;
    XrmDatabase xrdb;
  
    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;
  
    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 */
@@@ -10667,18 -10648,7 +10666,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.
        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);
@@@ -10777,97 -10746,70 +10776,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,
 +  {
 +    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_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;
    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);
  }