Support for opening X frames from a tty session.
[bpt/emacs.git] / src / dispnew.c
index 3cf15de..81a0f1f 100644 (file)
@@ -29,10 +29,8 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #include "lisp.h"
-#include "systty.h"             /* For emacs_tty in termchar.h */
 #include "termchar.h"
 #include "termopts.h"
-#include "termhooks.h"
 /* cm.h must come after dispextern.h on Windows.  */
 #include "dispextern.h"
 #include "cm.h"
@@ -40,6 +38,7 @@ Boston, MA 02111-1307, USA.  */
 #include "charset.h"
 #include "keyboard.h"
 #include "frame.h"
+#include "termhooks.h"
 #include "window.h"
 #include "commands.h"
 #include "disptab.h"
@@ -215,9 +214,9 @@ int inverse_video;
 EMACS_INT baud_rate;
 
 /* Either nil or a symbol naming the window system under which Emacs
-   is running.  */
+   creates the first frame.  */
 
-Lisp_Object Vwindow_system;
+Lisp_Object Vinitial_window_system;
 
 /* Version number of X windows: 10, 11 or nil.  */
 
@@ -297,11 +296,6 @@ int glyph_pool_count;
 
 static struct frame *frame_matrix_frame;
 
-/* Current interface for window-based redisplay.  Set from init_xterm.
-   A null value means we are not using window-based redisplay.  */
-
-struct redisplay_interface *rif;
-
 /* Non-zero means that fonts have been loaded since the last glyph
    matrix adjustments.  Redisplay must stop, and glyph matrices must
    be adjusted when this flag becomes non-zero during display.  The
@@ -1390,7 +1384,7 @@ line_hash_code (row)
        {
          int c = glyph->u.ch;
          int face_id = glyph->face_id;
-         if (TTY_MUST_WRITE_SPACES (CURTTY ()))
+         if (FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
            c -= SPACEGLYPH;
          hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
          hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
@@ -1422,7 +1416,7 @@ line_draw_cost (matrix, vpos)
   int glyph_table_len = GLYPH_TABLE_LENGTH;
 
   /* Ignore trailing and leading spaces if we can.  */
-  if (!TTY_MUST_WRITE_SPACES (CURTTY ()))
+  if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
     {
       /* Skip from the end over trailing spaces.  */
       while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1)))
@@ -3312,12 +3306,15 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
     return Qnil;
 
   update_begin (f);
+#ifdef MSDOS
   if (FRAME_MSDOS_P (f))
-    set_terminal_modes ();
+    set_terminal_modes (FRAME_DISPLAY (f));
+#endif
   clear_frame ();
   clear_current_matrices (f);
   update_end (f);
-  fflush (TTY_OUTPUT (FRAME_TTY (f)));
+  if (FRAME_TERMCAP_P (f))
+    fflush (TTY_OUTPUT (FRAME_TTY (f)));
   windows_or_buffers_changed++;
   /* Mark all windows as inaccurate, so that every window will have
      its redisplay done.  */
@@ -3457,7 +3454,7 @@ direct_output_for_insert (g)
 
   /* If we can't insert glyphs, we can use this method only
      at the end of a line.  */
-  if (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f)))
+  if (!FRAME_CHAR_INS_DEL_OK (f))
     if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n')
       return 0;
 
@@ -3607,17 +3604,17 @@ direct_output_for_insert (g)
   updated_row = glyph_row;
   updated_area = TEXT_AREA;
   update_begin (f);
-  if (rif)
+  if (FRAME_RIF (f))
     {
-      rif->update_window_begin_hook (w);
+      FRAME_RIF (f)->update_window_begin_hook (w);
 
       if (glyphs == end - n
          /* In front of a space added by append_space.  */
          || (glyphs == end - n - 1
              && (end - n)->charpos <= 0))
-       rif->write_glyphs (glyphs, n);
+       FRAME_RIF (f)->write_glyphs (glyphs, n);
       else
-       rif->insert_glyphs (glyphs, n);
+       FRAME_RIF (f)->insert_glyphs (glyphs, n);
     }
   else
     {
@@ -3637,8 +3634,8 @@ direct_output_for_insert (g)
      a frame matrix is used, cursor_to expects frame coordinates,
      and the X and Y parameters are not used.  */
   if (window_redisplay_p)
-    rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
-                   w->cursor.y, w->cursor.x);
+    FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
+                              w->cursor.y, w->cursor.x);
   else
     {
       int x, y;
@@ -3650,11 +3647,12 @@ direct_output_for_insert (g)
       cursor_to (y, x);
     }
 
-  if (rif)
-    rif->update_window_end_hook (w, 1, 0);
+  if (FRAME_RIF (f))
+    FRAME_RIF (f)->update_window_end_hook (w, 1, 0);
   update_end (f);
   updated_row = NULL;
-  fflush (TTY_OUTPUT (CURTTY ()));
+  if (FRAME_TERMCAP_P (f))
+    fflush (TTY_OUTPUT (FRAME_TTY (f)));
 
   TRACE ((stderr, "direct output for insert\n"));
   mark_window_display_accurate (it.window, 1);
@@ -3732,8 +3730,8 @@ direct_output_forward_char (n)
           && w->cursor.hpos < w->desired_matrix->matrix_w);
 
   if (FRAME_WINDOW_P (f))
-    rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
-                   w->cursor.y, w->cursor.x);
+    FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
+                              w->cursor.y, w->cursor.x);
   else
     {
       int x, y;
@@ -3745,7 +3743,8 @@ direct_output_forward_char (n)
       cursor_to (y, x);
     }
 
-  fflush (TTY_OUTPUT (CURTTY ()));
+  if (FRAME_TERMCAP_P (f))
+    fflush (TTY_OUTPUT (FRAME_TTY (f)));
   redisplay_performed_directly_p = 1;
   return 1;
 }
@@ -3819,7 +3818,7 @@ update_frame (f, force_p, inhibit_hairy_id_p)
 
 #if 0 /* This flush is a performance bottleneck under X,
         and it doesn't seem to be necessary anyway.  */
-      rif->flush_display (f);
+      FRAME_RIF (f)->flush_display (f);
 #endif
     }
   else
@@ -3836,9 +3835,12 @@ update_frame (f, force_p, inhibit_hairy_id_p)
       paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
       update_end (f);
 
-      if (TTY_TERMSCRIPT (FRAME_TTY (f)))
-       fflush (TTY_TERMSCRIPT (FRAME_TTY (f)));
-      fflush (TTY_OUTPUT (FRAME_TTY (f)));
+      if (FRAME_TERMCAP_P (f))
+        {
+          if (TTY_TERMSCRIPT (FRAME_TTY (f)))
+            fflush (TTY_TERMSCRIPT (FRAME_TTY (f)));
+          fflush (TTY_OUTPUT (FRAME_TTY (f)));
+        }
 
       /* Check window matrices for lost pointers.  */
 #if GLYPH_DEBUG
@@ -3921,7 +3923,8 @@ redraw_overlapped_rows (w, yb)
      int yb;
 {
   int i;
-
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  
   /* If rows overlapping others have been changed, the rows being
      overlapped have to be redrawn.  This won't draw lines that have
      already been drawn in update_window_line because overlapped_p in
@@ -3944,10 +3947,12 @@ redraw_overlapped_rows (w, yb)
            {
              updated_row = row;
              updated_area = area;
-             rif->cursor_to (i, 0, row->y, area == TEXT_AREA ? row->x : 0);
+             FRAME_RIF (f)->cursor_to (i, 0, row->y,
+                                        area == TEXT_AREA ? row->x : 0);
              if (row->used[area])
-               rif->write_glyphs (row->glyphs[area], row->used[area]);
-             rif->clear_end_of_line (-1);
+               FRAME_RIF (f)->write_glyphs (row->glyphs[area],
+                                             row->used[area]);
+             FRAME_RIF (f)->clear_end_of_line (-1);
            }
 
          row->overlapped_p = 0;
@@ -3969,7 +3974,8 @@ redraw_overlapping_rows (w, yb)
 {
   int i, bottom_y;
   struct glyph_row *row;
-
+  struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
+  
   for (i = 0; i < w->current_matrix->nrows; ++i)
     {
       row = w->current_matrix->rows + i;
@@ -4049,6 +4055,7 @@ update_window (w, force_p)
 #if GLYPH_DEBUG
   struct frame *f = XFRAME (WINDOW_FRAME (w));
 #endif
+  struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
 
   /* Check that W's frame doesn't have glyph matrices.  */
   xassert (FRAME_WINDOW_P (f));
@@ -4216,6 +4223,7 @@ update_marginal_area (w, area, vpos)
      int area, vpos;
 {
   struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+  struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
 
   /* Let functions in xterm.c know what area subsequent X positions
      will be relative to.  */
@@ -4241,6 +4249,7 @@ update_text_area (w, vpos)
 {
   struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
   struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+  struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
   int changed_p = 0;
 
   /* Let functions in xterm.c know what area subsequent X positions
@@ -4462,6 +4471,7 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
 {
   struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
   struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+  struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
   int changed_p = 0;
 
   /* Set the row being updated.  This is important to let xterm.c
@@ -4532,6 +4542,7 @@ set_window_cursor_after_update (w)
      struct window *w;
 {
   struct frame *f = XFRAME (w->frame);
+  struct redisplay_interface *rif = FRAME_RIF (f);
   int cx, cy, vpos, hpos;
 
   /* Not intended for frame matrix updates.  */
@@ -4755,6 +4766,7 @@ scrolling_window (w, header_line_p)
   int i, j, first_old, first_new, last_old, last_new;
   int nruns, nbytes, n, run_idx;
   struct row_entry *entry;
+  struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
 
   /* Skip over rows equal at the start.  */
   for (i = header_line_p ? 1 : 0; i < current_matrix->nrows - 1; ++i)
@@ -5070,7 +5082,7 @@ update_frame_1 (f, force_p, inhibit_id_p)
     }
 
   /* If we cannot insert/delete lines, it's no use trying it.  */
-  if (!TTY_LINE_INS_DEL_OK (FRAME_TTY (f)))
+  if (!FRAME_LINE_INS_DEL_OK (f))
     inhibit_id_p = 1;
 
   /* See if any of the desired lines are enabled; don't compute for
@@ -5288,7 +5300,7 @@ scrolling (frame)
     }
 
   /* If changed lines are few, don't allow preemption, don't scroll.  */
-  if ((!TTY_SCROLL_REGION_OK (FRAME_TTY (frame))
+  if ((!FRAME_SCROLL_REGION_OK (frame)
        && changed_lines < baud_rate / 2400)
       || unchanged_at_bottom == FRAME_LINES (frame))
     return 1;
@@ -5296,14 +5308,14 @@ scrolling (frame)
   window_size = (FRAME_LINES (frame) - unchanged_at_top
                 - unchanged_at_bottom);
 
-  if (TTY_SCROLL_REGION_OK (FRAME_TTY (frame)))
+  if (FRAME_SCROLL_REGION_OK (frame))
     free_at_end_vpos -= unchanged_at_bottom;
-  else if (TTY_MEMORY_BELOW_FRAME (FRAME_TTY (frame)))
+  else if (FRAME_MEMORY_BELOW_FRAME (frame))
     free_at_end_vpos = -1;
 
   /* If large window, fast terminal and few lines in common between
      current frame and desired frame, don't bother with i/d calc.  */
-  if (!TTY_SCROLL_REGION_OK (FRAME_TTY (frame))
+  if (!FRAME_SCROLL_REGION_OK (frame)
       && window_size >= 18 && baud_rate > 2400
       && (window_size >=
          10 * scrolling_max_lines_saved (unchanged_at_top,
@@ -5384,7 +5396,7 @@ update_frame_line (f, vpos)
   struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
   struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
   int must_write_whole_line_p;
-  int write_spaces_p = TTY_MUST_WRITE_SPACES (FRAME_TTY (f));
+  int write_spaces_p = FRAME_MUST_WRITE_SPACES (f);
   int colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
                          != FACE_TTY_DEFAULT_BG_COLOR);
 
@@ -5463,7 +5475,7 @@ update_frame_line (f, vpos)
       nlen--;
 
   /* If there's no i/d char, quickly do the best we can without it.  */
-  if (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f)))
+  if (!FRAME_CHAR_INS_DEL_OK (f))
     {
       int i, j;
 
@@ -5566,7 +5578,7 @@ update_frame_line (f, vpos)
 
   tem = (nlen - nsp) - (olen - osp);
   if (endmatch && tem
-      && (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f))
+      && (!FRAME_CHAR_INS_DEL_OK (f)
           || endmatch <= char_ins_del_cost (f)[tem]))
     endmatch = 0;
 
@@ -5576,7 +5588,7 @@ update_frame_line (f, vpos)
      Is it worth it?  */
 
   if (nsp != osp
-      && (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f))
+      && (!FRAME_CHAR_INS_DEL_OK (f)
          || begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]))
     {
       begmatch = 0;
@@ -5685,21 +5697,24 @@ update_frame_line (f, vpos)
  ***********************************************************************/
 
 /* Determine what's under window-relative pixel position (*X, *Y).
-   Return in *OBJECT the object (string or buffer) that's there.
-   Return in *POS the position in that object. Adjust *X and *Y
-   to character positions.  */
+   Return the object (string or buffer) that's there.
+   Return in *POS the position in that object.
+   Adjust *X and *Y to character positions.  */
 
-void
-buffer_posn_from_coords (w, x, y, dx, dy, object, pos)
+Lisp_Object
+buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
      struct window *w;
      int *x, *y;
-     int *dx, *dy;
-     Lisp_Object *object;
      struct display_pos *pos;
+     Lisp_Object *object;
+     int *dx, *dy;
+     int *width, *height;
 {
   struct it it;
   struct buffer *old_current_buffer = current_buffer;
   struct text_pos startp;
+  Lisp_Object string;
+  struct glyph_row *row;
   int x0, x1;
 
   current_buffer = XBUFFER (w->buffer);
@@ -5717,7 +5732,10 @@ buffer_posn_from_coords (w, x, y, dx, dy, object, pos)
   *dx = x0 + it.first_visible_x - it.current_x;
   *dy = *y - it.current_y;
 
-  *object =  w->buffer;
+  string =  w->buffer;
+  if (STRINGP (it.string))
+    string = it.string;
+  *pos = it.current;
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (it.what == IT_IMAGE)
@@ -5725,25 +5743,33 @@ buffer_posn_from_coords (w, x, y, dx, dy, object, pos)
       struct image *img;
       if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL
          && !NILP (img->spec))
-       {
-         struct glyph_row *row = MATRIX_ROW (w->current_matrix, it.vpos);
-         struct glyph *glyph;
+       *object = img->spec;
+    }
+#endif
 
-         if (it.hpos < row->used[TEXT_AREA]
-             && (glyph = row->glyphs[TEXT_AREA] + it.hpos,
-                 glyph->type == IMAGE_GLYPH))
-           {
-             *dy -= row->ascent - glyph->ascent;
-             *object = img->spec;
-           }
+  row = MATRIX_ROW (w->current_matrix, it.vpos);
+  if (row->enabled_p)
+    {
+      if (it.hpos < row->used[TEXT_AREA])
+       {
+         struct glyph *glyph = row->glyphs[TEXT_AREA] + it.hpos;
+         *width = glyph->pixel_width;
+         *height = glyph->ascent + glyph->descent;
+#ifdef HAVE_WINDOW_SYSTEM
+         if (glyph->type == IMAGE_GLYPH)
+           *dy -= row->ascent - glyph->ascent;
+#endif
+       }
+      else
+       {
+         *width = 0;
+         *height = row->height;
        }
     }
   else
-#endif
-    if (STRINGP (it.string))
-      *object = it.string;
-
-  *pos = it.current;
+    {
+      *width = *height = 0;
+    }
 
   /* Add extra (default width) columns if clicked after EOL. */
   x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
@@ -5752,21 +5778,24 @@ buffer_posn_from_coords (w, x, y, dx, dy, object, pos)
 
   *x = it.hpos;
   *y = it.vpos;
+
+  return string;
 }
 
 
 /* Value is the string under window-relative coordinates X/Y in the
-   mode or header line of window W, or nil if none.  MODE_LINE_P non-zero
-   means look at the mode line.  *CHARPOS is set to the position in
-   the string returned.  */
+   mode line or header line (PART says which) of window W, or nil if none.
+   *CHARPOS is set to the position in the string returned.  */
 
 Lisp_Object
-mode_line_string (w, x, y, dx, dy, part, charpos)
+mode_line_string (w, part, x, y, charpos, object, dx, dy, width, height)
      struct window *w;
-     int *x, *y;
-     int *dx, *dy;
      enum window_part part;
+     int *x, *y;
      int *charpos;
+     Lisp_Object *object;
+     int *dx, *dy;
+     int *width, *height;
 {
   struct glyph_row *row;
   struct glyph *glyph, *end;
@@ -5793,22 +5822,36 @@ mode_line_string (w, x, y, dx, dy, part, charpos)
        {
          string = glyph->object;
          *charpos = glyph->charpos;
+         *width = glyph->pixel_width;
+         *height = glyph->ascent + glyph->descent;
+#ifdef HAVE_WINDOW_SYSTEM
+         if (glyph->type == IMAGE_GLYPH)
+           {
+             struct image *img;
+             img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
+             if (img != NULL)
+               *object = img->spec;
+             y0 -= row->ascent - glyph->ascent;
+           }
+#endif
        }
       else
-       /* Add extra (default width) columns if clicked after EOL. */
-       *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+       {
+         /* Add extra (default width) columns if clicked after EOL. */
+         *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+         *width = 0;
+         *height = row->height;
+       }
     }
   else
     {
       *x = 0;
       x0 = 0;
+      *width = *height = 0;
     }
 
-  if (dx)
-    {
-      *dx = x0;
-      *dy = y0;
-    }
+  *dx = x0;
+  *dy = y0;
 
   return string;
 }
@@ -5819,12 +5862,14 @@ mode_line_string (w, x, y, dx, dy, part, charpos)
    the string returned.  */
 
 Lisp_Object
-marginal_area_string (w, x, y, dx, dy, part, charpos)
+marginal_area_string (w, part, x, y, charpos, object, dx, dy, width, height)
      struct window *w;
-     int *x, *y;
-     int *dx, *dy;
      enum window_part part;
+     int *x, *y;
      int *charpos;
+     Lisp_Object *object;
+     int *dx, *dy;
+     int *width, *height;
 {
   struct glyph_row *row = w->current_matrix->rows;
   struct glyph *glyph, *end;
@@ -5869,32 +5914,36 @@ marginal_area_string (w, x, y, dx, dy, part, charpos)
        {
          string = glyph->object;
          *charpos = glyph->charpos;
+         *width = glyph->pixel_width;
+         *height = glyph->ascent + glyph->descent;
 #ifdef HAVE_WINDOW_SYSTEM
          if (glyph->type == IMAGE_GLYPH)
            {
              struct image *img;
              img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
              if (img != NULL)
-               string = img->spec;
+               *object = img->spec;
              y0 -= row->ascent - glyph->ascent;
            }
 #endif
        }
       else
-       /* Add extra (default width) columns if clicked after EOL. */
-       *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+       {
+         /* Add extra (default width) columns if clicked after EOL. */
+         *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+         *width = 0;
+         *height = row->height;
+       }
     }
   else
     {
       x0 = 0;
       *x = 0;
+      *width = *height = 0;
     }
 
-  if (dx)
-    {
-      *dx = x0;
-      *dy = y0;
-    }
+  *dx = x0;
+  *dy = y0;
 
   return string;
 }
@@ -5916,8 +5965,8 @@ window_change_signal (signalnum) /* If we don't have an argument, */
 #endif
   int old_errno = errno;
 
-  struct tty_output *tty;
-  
+  struct tty_display_info *tty;
+
   /* The frame size change obviously applies to a single
      termcap-controlled terminal, but we can't decide which.
      Therefore, we resize the frames corresponding to each tty.
@@ -5926,22 +5975,18 @@ window_change_signal (signalnum) /* If we don't have an argument, */
 
     if (! tty->term_initted)
       continue;
-    
-    get_tty_size (tty, &width, &height);
+
+    get_tty_size (fileno (TTY_INPUT (tty)), &width, &height);
     
     {
       Lisp_Object tail, frame;
       
       FOR_EACH_FRAME (tail, frame)
-        {
-          if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
-            {
-              /* Record the new sizes, but don't reallocate the data structures
-                 now.  Let that be done later outside of the signal handler.  */
-              change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
-              break;
-            }
-        }
+        if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
+          /* Record the new sizes, but don't reallocate the data
+             structures now.  Let that be done later outside of the
+             signal handler.  */
+          change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
     }
   }
   
@@ -6167,6 +6212,9 @@ Control characters in STRING will have terminal-dependent effects.  */)
 {
   /* ??? Perhaps we should do something special for multibyte strings here.  */
   CHECK_STRING (string);
+  if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
+    error ("Current frame is not on a tty device");
+  
   if (TTY_TERMSCRIPT (CURTTY ()))
     {
       fwrite (SDATA (string), 1, SBYTES (string),
@@ -6193,7 +6241,8 @@ terminate any keyboard macro currently executing.  */)
        putchar (07);
       else
        ring_bell ();
-      fflush (TTY_OUTPUT (CURTTY ()));
+      if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
+        fflush (TTY_OUTPUT (CURTTY ()));
     }
   else
     bitch_at_user ();
@@ -6210,7 +6259,8 @@ bitch_at_user ()
     error ("Keyboard macro terminated by a command ringing the bell");
   else
     ring_bell ();
-  fflush (TTY_OUTPUT (CURTTY ()));
+  if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
+    fflush (TTY_OUTPUT (CURTTY ()));
 }
 
 
@@ -6519,7 +6569,7 @@ init_display ()
 
   /* Now is the time to initialize this; it's used by init_sys_modes
      during startup.  */
-  Vwindow_system = Qnil;
+  Vinitial_window_system = Qnil;
 
   /* If the user wants to use a window system, we shouldn't bother
      initializing the terminal.  This is especially important when the
@@ -6548,7 +6598,7 @@ init_display ()
 #endif
      )
     {
-      Vwindow_system = intern ("x");
+      Vinitial_window_system = intern ("x");
 #ifdef HAVE_X11
       Vwindow_system_version = make_number (11);
 #else
@@ -6568,7 +6618,7 @@ init_display ()
 #ifdef HAVE_NTGUI
   if (!inhibit_window_system)
     {
-      Vwindow_system = intern ("w32");
+      Vinitial_window_system = intern ("w32");
       Vwindow_system_version = make_number (1);
       adjust_frame_glyphs_initially ();
       return;
@@ -6578,7 +6628,7 @@ init_display ()
 #ifdef MAC_OS
   if (!inhibit_window_system)
     {
-      Vwindow_system = intern ("mac");
+      Vinitial_window_system = intern ("mac");
       Vwindow_system_version = make_number (1);
       adjust_frame_glyphs_initially ();
       return;
@@ -6625,10 +6675,26 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
 #endif /* VMS */
 
   {
-    struct tty_output *tty;
-    
-    tty = term_init (selected_frame, 0, terminal_type);
-    change_frame_size (XFRAME (selected_frame), FrameRows (tty), FrameCols (tty), 0, 0, 0);
+    struct display *d;
+    struct frame *f = XFRAME (selected_frame);
+
+    /* Open a display on the controlling tty. */
+    d = term_init (0, terminal_type, 1); /* Errors are fatal. */
+
+    /* Convert the initial frame to use the new display. */
+    if (! f->output_method == output_initial)
+      abort ();
+    f->output_method = d->type;
+    f->display = d;
+
+    d->reference_count++;
+    d->display_info.tty->top_frame = selected_frame;
+    change_frame_size (XFRAME (selected_frame), FrameRows (d->display_info.tty), FrameCols (d->display_info.tty), 0, 0, 1);
+
+    /* Delete the initial display. */
+    if (--initial_display->reference_count == 0
+        && initial_display->delete_display_hook)
+      (*initial_display->delete_display_hook) (initial_display);
   }
   
   {
@@ -6664,7 +6730,7 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
         and internal_terminal_init.  */
       && (strcmp (terminal_type, "internal") != 0 || inhibit_window_system)
 #endif
-      && NILP (Vwindow_system))
+      && NILP (Vinitial_window_system))
     {
       /* For the initial frame, we don't have any way of knowing what
         are the foreground and background colors of the terminal.  */
@@ -6776,8 +6842,8 @@ A non-nil value is useful if the terminal can automatically preserve
 Emacs's frame display when you reenter Emacs.
 It is up to you to set this variable if your terminal can do that.  */);
 
-  DEFVAR_LISP ("window-system", &Vwindow_system,
-              doc: /* Name of window system that Emacs is displaying through.
+  DEFVAR_LISP ("initial-window-system", &Vinitial_window_system,
+              doc: /* Name of the window system that Emacs uses for the first frame.
 The value is a symbol--for instance, `x' for X windows.
 The value is nil if Emacs is using a text-only terminal.  */);
 
@@ -6813,7 +6879,7 @@ See `buffer-display-table' for more information.  */);
   if (noninteractive)
 #endif
     {
-      Vwindow_system = Qnil;
+      Vinitial_window_system = Qnil;
       Vwindow_system_version = Qnil;
     }
 }