msdos.c (dos_rawgetc): Use gen_help_event, instead of doing the same in-line.
[bpt/emacs.git] / src / msdos.c
index b387717..0f9a2ff 100644 (file)
@@ -1,6 +1,6 @@
 /* MS-DOS specific C utilities.          -*- coding: raw-text -*-
    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
-                 2003, 2004, 2005, 2006, 2007, 2008
+                 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -26,19 +26,17 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <config.h>
 
 #ifdef MSDOS
+#include <setjmp.h>
 #include "lisp.h"
 #include <stdio.h>
-#include <stdlib.h>
 #include <time.h>
 #include <sys/param.h>
 #include <sys/time.h>
 #include <dos.h>
 #include <errno.h>
-#include <string.h>     /* for bzero and string functions */
 #include <sys/stat.h>    /* for _fixpath */
 #include <unistd.h>     /* for chdir, dup, dup2, etc. */
 #include <dir.h>        /* for getdisk */
-#if __DJGPP__ >= 2
 #pragma pack(0)                 /* dir.h does a pack(4), which isn't GCC's default */
 #include <fcntl.h>
 #include <io.h>                 /* for setmode */
@@ -46,10 +44,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <sys/farptr.h>         /* for _farsetsel, _farnspokeb */
 #include <libc/dosio.h>  /* for _USE_LFN */
 #include <conio.h>      /* for cputs */
-#endif
 
 #include "msdos.h"
 #include "systime.h"
+#include "frame.h"
 #include "termhooks.h"
 #include "termchar.h"
 #include "dispextern.h"
@@ -58,7 +56,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "character.h"
 #include "coding.h"
 #include "disptab.h"
-#include "frame.h"
 #include "window.h"
 #include "buffer.h"
 #include "commands.h"
@@ -69,8 +66,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <pc.h>
 #include <ctype.h>
 /* #include <process.h> */
-/* Damn that local process.h!  Instead we can define P_WAIT ourselves.  */
+/* Damn that local process.h!  Instead we can define P_WAIT and
+   spawnve ourselves.  */
 #define P_WAIT 1
+extern int spawnve (int, const char *, char *const [], char *const []);
 
 #ifndef _USE_LFN
 #define _USE_LFN 0
@@ -80,8 +79,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define _dos_ds _go32_info_block.selector_for_linear_memory
 #endif
 
-#if __DJGPP__ > 1
-
 #include <signal.h>
 #include "syssignal.h"
 
@@ -103,10 +100,9 @@ int _crt0_startup_flags = (_CRT0_FLAG_UNIX_SBRK | _CRT0_FLAG_FILL_SBRK_MEMORY);
 #endif /* GNU_MALLOC */
 
 #endif /* not SYSTEM_MALLOC */
-#endif /* __DJGPP__ > 1 */
 
 static unsigned long
-event_timestamp ()
+event_timestamp (void)
 {
   struct time t;
   unsigned long s;
@@ -142,14 +138,16 @@ static int mouse_button_translate[NUM_MOUSE_BUTTONS];
 static int mouse_button_count;
 
 void
-mouse_on ()
+mouse_on (void)
 {
   union REGS regs;
 
   if (have_mouse > 0 && !mouse_visible)
     {
-      if (termscript)
-       fprintf (termscript, "<M_ON>");
+      struct tty_display_info *tty = CURTTY ();
+
+      if (tty->termscript)
+       fprintf (tty->termscript, "<M_ON>");
       regs.x.ax = 0x0001;
       int86 (0x33, &regs, &regs);
       mouse_visible = 1;
@@ -157,14 +155,16 @@ mouse_on ()
 }
 
 void
-mouse_off ()
+mouse_off (void)
 {
   union REGS regs;
 
   if (have_mouse > 0 && mouse_visible)
     {
-      if (termscript)
-       fprintf (termscript, "<M_OFF>");
+      struct tty_display_info *tty = CURTTY ();
+
+      if (tty->termscript)
+       fprintf (tty->termscript, "<M_OFF>");
       regs.x.ax = 0x0002;
       int86 (0x33, &regs, &regs);
       mouse_visible = 0;
@@ -195,8 +195,7 @@ DEFUN ("msdos-set-mouse-buttons", Fmsdos_set_mouse_buttons, Smsdos_set_mouse_but
 This is useful with mice that report the number of buttons inconsistently,
 e.g., if the number of buttons is reported as 3, but Emacs only sees 2 of
 them.  This happens with wheeled mice on Windows 9X, for example.  */)
-     (nbuttons)
-     Lisp_Object nbuttons;
+  (Lisp_Object nbuttons)
 {
   int n;
 
@@ -222,13 +221,13 @@ mouse_get_xy (int *x, int *y)
 }
 
 void
-mouse_moveto (x, y)
-     int x, y;
+mouse_moveto (int x, int y)
 {
   union REGS regs;
+  struct tty_display_info *tty = CURTTY ();
 
-  if (termscript)
-    fprintf (termscript, "<M_XY=%dx%d>", x, y);
+  if (tty->termscript)
+    fprintf (tty->termscript, "<M_XY=%dx%d>", x, y);
   regs.x.ax = 0x0004;
   mouse_last_x = regs.x.cx = x * 8;
   mouse_last_y = regs.x.dx = y * 8;
@@ -236,8 +235,7 @@ mouse_moveto (x, y)
 }
 
 static int
-mouse_pressed (b, xp, yp)
-     int b, *xp, *yp;
+mouse_pressed (int b, int *xp, int *yp)
 {
   union REGS regs;
 
@@ -252,8 +250,7 @@ mouse_pressed (b, xp, yp)
 }
 
 static int
-mouse_released (b, xp, yp)
-     int b, *xp, *yp;
+mouse_released (int b, int *xp, int *yp)
 {
   union REGS regs;
 
@@ -268,8 +265,7 @@ mouse_released (b, xp, yp)
 }
 
 static int
-mouse_button_depressed (b, xp, yp)
-     int b, *xp, *yp;
+mouse_button_depressed (int b, int *xp, int *yp)
 {
   union REGS regs;
 
@@ -287,12 +283,9 @@ mouse_button_depressed (b, xp, yp)
 }
 
 void
-mouse_get_pos (f, insist, bar_window, part, x, y, time)
-     FRAME_PTR *f;
-     int insist;
-     Lisp_Object *bar_window, *x, *y;
-     enum scroll_bar_part *part;
-     unsigned long *time;
+mouse_get_pos (FRAME_PTR *f, int insist, Lisp_Object *bar_window,
+              enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
+              unsigned long *time)
 {
   int ix, iy;
   Lisp_Object frame, tail;
@@ -310,7 +303,7 @@ mouse_get_pos (f, insist, bar_window, part, x, y, time)
 }
 
 static void
-mouse_check_moved ()
+mouse_check_moved (void)
 {
   int x, y;
 
@@ -337,12 +330,13 @@ mouse_clear_clicks (void)
 }
 
 void
-mouse_init ()
+mouse_init (void)
 {
   union REGS regs;
+  struct tty_display_info *tty = CURTTY ();
 
-  if (termscript)
-    fprintf (termscript, "<M_INIT>");
+  if (tty->termscript)
+    fprintf (tty->termscript, "<M_INIT>");
 
   regs.x.ax = 0x0021;
   int86 (0x33, &regs, &regs);
@@ -400,7 +394,7 @@ static int term_setup_done;
 static unsigned short outside_cursor;
 
 /* Similar to the_only_frame.  */
-struct x_output the_only_x_display;
+struct tty_display_info the_only_display_info;
 
 /* Support for DOS/V (allows Japanese characters to be displayed on
    standard, non-Japanese, ATs).  Only supported for DJGPP v2 and later.  */
@@ -420,7 +414,6 @@ extern Lisp_Object Qbar, Qhbar;
    colors for newly-created frames.  */
 static int initial_screen_colors[2];
 
-#if __DJGPP__ > 1
 /* Update the screen from a part of relocated DOS/V screen buffer which
    begins at OFFSET and includes COUNT characters.  */
 static void
@@ -437,79 +430,20 @@ dosv_refresh_virtual_screen (int offset, int count)
   regs.x.cx = count;
   __dpmi_int (0x10, &regs);
 }
-#endif
 
 static void
-dos_direct_output (y, x, buf, len)
-     int x, y;
-     char *buf;
-     int len;
+dos_direct_output (int y, int x, char *buf, int len)
 {
   int t0 = 2 * (x + y * screen_size_X);
   int t = t0 + (int) ScreenPrimary;
   int l0 = len;
 
-#if (__DJGPP__ < 2)
-  while (--len >= 0) {
-    dosmemput (buf++, 1, t);
-    t += 2;
-  }
-#else
   /* This is faster.  */
   for (_farsetsel (_dos_ds); --len >= 0; t += 2, buf++)
     _farnspokeb (t, *buf);
 
   if (screen_virtual_segment)
     dosv_refresh_virtual_screen (t0, l0);
-#endif
-}
-#endif
-
-/* Flash the screen as a substitute for BEEPs.  */
-
-#if (__DJGPP__ < 2)
-static void
-do_visible_bell (xorattr)
-     unsigned char xorattr;
-{
-  asm volatile
-    ("  movb   $1,%%dl                         \n\
-visible_bell_0:                                        \n\
-       movl   _ScreenPrimary,%%eax             \n\
-       call   dosmemsetup                      \n\
-       movl   %%eax,%%ebx                      \n\
-       movl   %1,%%ecx                         \n\
-       movb   %0,%%al                          \n\
-       incl   %%ebx                            \n\
-visible_bell_1:                                        \n\
-       xorb   %%al,%%gs:(%%ebx)                \n\
-       addl   $2,%%ebx                         \n\
-       decl   %%ecx                            \n\
-       jne    visible_bell_1                   \n\
-       decb   %%dl                             \n\
-       jne    visible_bell_3                   \n\
-visible_bell_2:                                        \n\
-       movzwl %%ax,%%eax                       \n\
-        movzwl %%ax,%%eax                      \n\
-       movzwl %%ax,%%eax                       \n\
-       movzwl %%ax,%%eax                       \n\
-       decw   %%cx                             \n\
-       jne    visible_bell_2                   \n\
-       jmp    visible_bell_0                   \n\
-visible_bell_3:"
-     : /* no output */
-     : "m" (xorattr), "g" (screen_size)
-     : "%eax", "%ebx", /* "%gs",*/ "%ecx", "%edx");
-}
-
-static void
-ScreenVisualBell (void)
-{
-  /* This creates an xor-mask that will swap the default fore- and
-     background colors.  */
-  do_visible_bell (((FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ())
-                    ^ FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()))
-                   * 0x11) & 0x7f);
 }
 #endif
 
@@ -565,8 +499,7 @@ vga_installed (void)
    ROWS x COLS frame.  */
 
 void
-dos_set_window_size (rows, cols)
-     int *rows, *cols;
+dos_set_window_size (int *rows, int *cols)
 {
   char video_name[30];
   union REGS regs;
@@ -583,8 +516,7 @@ dos_set_window_size (rows, cols)
   /* If the user specified a special video mode for these dimensions,
      use that mode.  */
   sprintf (video_name, "screen-dimensions-%dx%d", *rows, *cols);
-  video_mode = XSYMBOL (Fintern_soft (build_string (video_name),
-                                     Qnil))-> value;
+  video_mode = Fsymbol_value (Fintern_soft (build_string (video_name), Qnil));
 
   if (INTEGERP (video_mode)
       && (video_mode_value = XINT (video_mode)) > 0)
@@ -604,9 +536,6 @@ dos_set_window_size (rows, cols)
 
   /* Find one of the dimensions supported by standard EGA/VGA
      which gives us at least the required dimensions.  */
-
-#if __DJGPP__ > 1
-
   else
     {
       static struct {
@@ -635,41 +564,6 @@ dos_set_window_size (rows, cols)
        }
     }
 
-#else /* not __DJGPP__ > 1 */
-
-  else if (*rows <= 25)
-    {
-      if (current_rows != 25 || current_cols != 80)
-       {
-         regs.x.ax = 3;
-         int86 (0x10, &regs, &regs);
-         regs.x.ax = 0x1101;
-         regs.h.bl = 0;
-         int86 (0x10, &regs, &regs);
-         regs.x.ax = 0x1200;
-         regs.h.bl = 32;
-         int86 (0x10, &regs, &regs);
-         regs.x.ax = 3;
-         int86 (0x10, &regs, &regs);
-       }
-    }
-  else if (*rows <= 50)
-    if (have_vga && (current_rows != 50 || current_cols != 80)
-       || *rows <= 43 && (current_rows != 43 || current_cols != 80))
-      {
-       regs.x.ax = 3;
-       int86 (0x10, &regs, &regs);
-       regs.x.ax = 0x1112;
-       regs.h.bl = 0;
-       int86 (0x10, &regs, &regs);
-       regs.x.ax = 0x1200;
-       regs.h.bl = 32;
-       int86 (0x10, &regs, &regs);
-       regs.x.ax = 0x0100;
-       regs.x.cx = 7;
-       int86 (0x10, &regs, &regs);
-      }
-#endif /* not __DJGPP__ > 1 */
 
   if (have_mouse)
     {
@@ -686,22 +580,20 @@ dos_set_window_size (rows, cols)
   screen_size_Y = *rows;
   screen_size = *cols * *rows;
 
-#if __DJGPP__ > 1
   /* If the dimensions changed, the mouse highlight info is invalid.  */
   if (current_rows != *rows || current_cols != *cols)
     {
       struct frame *f = SELECTED_FRAME();
-      struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-      Lisp_Object window = dpyinfo->mouse_face_window;
+      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+      Lisp_Object window = hlinfo->mouse_face_window;
 
       if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
        {
-         dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
-         dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
-         dpyinfo->mouse_face_window = Qnil;
+         hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
+         hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
+         hlinfo->mouse_face_window = Qnil;
        }
     }
-#endif
 
   /* Enable bright background colors.  */
   bright_bg ();
@@ -716,7 +608,7 @@ dos_set_window_size (rows, cols)
    the mouse cursor may need to be refreshed.  */
 
 static void
-mouse_off_maybe ()
+mouse_off_maybe (void)
 {
   int x, y;
 
@@ -740,10 +632,10 @@ mouse_off_maybe ()
 static void
 msdos_set_cursor_shape (struct frame *f, int start_line, int width)
 {
-#if __DJGPP__ > 1
   unsigned desired_cursor;
   __dpmi_regs regs;
   int max_line, top_line, bot_line;
+  struct tty_display_info *tty = FRAME_TTY (f);
 
   /* Avoid the costly BIOS call if F isn't the currently selected
      frame.  Allow for NULL as unconditionally meaning the selected
@@ -751,8 +643,8 @@ msdos_set_cursor_shape (struct frame *f, int start_line, int width)
   if (f && f != SELECTED_FRAME())
     return;
 
-  if (termscript)
-    fprintf (termscript, "\nCURSOR SHAPE=(%d,%d)", start_line, width);
+  if (tty->termscript)
+    fprintf (tty->termscript, "\nCURSOR SHAPE=(%d,%d)", start_line, width);
 
   /* The character cell size in scan lines is stored at 40:85 in the
      BIOS data area.  */
@@ -816,7 +708,6 @@ msdos_set_cursor_shape (struct frame *f, int start_line, int width)
   regs.h.ah = 1;
   regs.x.cx = desired_cursor;
   __dpmi_int (0x10, &regs);
-#endif /* __DJGPP__ > 1 */
 }
 
 static void
@@ -862,7 +753,7 @@ IT_set_cursor_type (struct frame *f, Lisp_Object cursor_type)
 }
 
 static void
-IT_ring_bell (void)
+IT_ring_bell (struct frame *f)
 {
   if (visible_bell)
     {
@@ -890,6 +781,7 @@ IT_set_face (int face)
   struct face *fp  = FACE_FROM_ID (sf, face);
   struct face *dfp = FACE_FROM_ID (sf, DEFAULT_FACE_ID);
   unsigned long fg, bg, dflt_fg, dflt_bg;
+  struct tty_display_info *tty = FRAME_TTY (sf);
 
   if (!fp)
     {
@@ -934,8 +826,8 @@ IT_set_face (int face)
       fg = bg;
       bg = tem2;
     }
-  if (termscript)
-    fprintf (termscript, "<FACE %d: %d/%d[FG:%d/BG:%d]>", face,
+  if (tty->termscript)
+    fprintf (tty->termscript, "<FACE %d: %lu/%lu[FG:%lu/BG:%lu]>", face,
             fp->foreground, fp->background, fg, bg);
   if (fg >= 0 && fg < 16)
     {
@@ -949,48 +841,34 @@ IT_set_face (int face)
     }
 }
 
-Lisp_Object Vdos_unsupported_char_glyph;
+/* According to RBIL (INTERRUP.A, V-1000), 160 is the maximum possible
+   width of a DOS display in any known text mode.  We multiply by 2 to
+   accomodate the screen attribute byte.  */
+#define MAX_SCREEN_BUF 160*2
 
+Lisp_Object Vdos_unsupported_char_glyph;
+extern unsigned char *encode_terminal_code (struct glyph *, int,
+                                           struct coding_system *);
 static void
-IT_write_glyphs (struct glyph *str, int str_len)
+IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
 {
-  unsigned char *screen_buf, *screen_bp, *screen_buf_end, *bp;
-  int unsupported_face = 0;
-  unsigned unsupported_char = '\177';
+  unsigned char screen_buf[MAX_SCREEN_BUF], *screen_bp, *bp;
   int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
   register int sl = str_len;
-  register int tlen = GLYPH_TABLE_LENGTH;
-  register Lisp_Object *tbase = GLYPH_TABLE_BASE;
+  struct tty_display_info *tty = FRAME_TTY (f);
+  struct frame *sf;
+  unsigned char *conversion_buffer;
 
   /* If terminal_coding does any conversion, use it, otherwise use
      safe_terminal_coding.  We can't use CODING_REQUIRE_ENCODING here
      because it always returns 1 if terminal_coding.src_multibyte is 1.  */
-  struct coding_system *coding =
-    (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
-     ? &terminal_coding
-     : &safe_terminal_coding);
-  struct frame *sf;
-
-  /* Do we need to consider conversion of unibyte characters to
-     multibyte?  */
-  int convert_unibyte_characters
-    = (NILP (current_buffer->enable_multibyte_characters)
-       && unibyte_display_via_language_environment);
+  struct coding_system *coding = FRAME_TERMINAL_CODING (f);
 
-  unsigned char conversion_buffer[256];
-  int conversion_buffer_size = sizeof conversion_buffer;
+  if (!(coding->common_flags & CODING_REQUIRE_ENCODING_MASK))
+    coding = &safe_terminal_coding;
 
   if (str_len <= 0) return;
 
-  /* Set up the unsupported character glyph */
-  if (!NILP (Vdos_unsupported_char_glyph))
-    {
-      unsupported_char = GLYPH_CHAR (XINT (Vdos_unsupported_char_glyph));
-      unsupported_face = GLYPH_FACE (XINT (Vdos_unsupported_char_glyph));
-    }
-
-  screen_buf = screen_bp = alloca (str_len * 2);
-  screen_buf_end = screen_buf + str_len * 2;
   sf = SELECTED_FRAME();
 
   /* Since faces get cached and uncached behind our back, we can't
@@ -1002,191 +880,56 @@ IT_write_glyphs (struct glyph *str, int str_len)
 
   /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
      the tail.  */
-  terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
-  while (sl)
+  coding->mode &= ~CODING_MODE_LAST_BLOCK;
+  screen_bp = &screen_buf[0];
+  while (sl > 0)
     {
-      int cf, chlen, enclen;
-      unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *buf;
-      unsigned ch;
-
-      /* Glyphs with GLYPH_MASK_PADDING bit set are actually there
-        only for the redisplay code to know how many columns does
-         this character occupy on the screen.  Skip padding glyphs.  */
-      if (CHAR_GLYPH_PADDING_P (*str))
-       {
-         str++;
-         sl--;
-       }
-      else
-       {
-         GLYPH g;
-         int glyph_not_in_table = 0;
-
-         SET_GLYPH_FROM_CHAR_GLYPH (g, *str);
-
-         if (GLYPH_INVALID_P (g) || GLYPH_SIMPLE_P (tbase, tlen, g))
-           {
-             /* This glyph doesn't have an entry in Vglyph_table.  */
-             ch = str->u.ch;
-             glyph_not_in_table = 1;
-           }
-         else
-           {
-             /* This glyph has an entry in Vglyph_table, so process
-                any aliases before testing for simpleness.  */
-             GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
-             ch = GLYPH_CHAR (g);
-           }
-
-         /* Convert the character code to multibyte, if they
-            requested display via language environment.  We only want
-            to convert unibyte characters to multibyte in unibyte
-            buffers!  Otherwise, the 8-bit value in CH came from the
-            display table set up to display foreign characters.  */
-         if (SINGLE_BYTE_CHAR_P (ch) && convert_unibyte_characters
-             && (ch >= 0240
-                 || (ch >= 0200 && !NILP (Vnonascii_translation_table))))
-           ch = unibyte_char_to_multibyte (ch);
-
-         /* Invalid characters are displayed with a special glyph.  */
-         if (! CHAR_VALID_P (ch, 0))
-           {
-             ch = !NILP (Vdos_unsupported_char_glyph)
-               ? XINT (Vdos_unsupported_char_glyph)
-               : '\177';
-             SET_GLYPH_CHAR (g, ch);
-           }
-
-         /* If the face of this glyph is different from the current
-            screen face, update the screen attribute byte.  */
-         cf = str->face_id;
-         if (cf != screen_face)
-           IT_set_face (cf);   /* handles invalid faces gracefully */
-
-         if (glyph_not_in_table || GLYPH_SIMPLE_P (tbase, tlen, g))
-           {
-             /* We generate the multi-byte form of CH in WORKBUF.  */
-             chlen = CHAR_STRING (ch, workbuf);
-             buf = workbuf;
-           }
-         else
-           {
-             /* We have a string in Vglyph_table.  */
-             chlen = GLYPH_LENGTH (tbase, g);
-             buf = GLYPH_STRING (tbase, g);
-           }
-
-         /* If the character is not multibyte, don't bother converting it.  */
-         if (chlen == 1)
-           {
-             *conversion_buffer = (unsigned char)ch;
-             chlen = 0;
-             enclen = 1;
-           }
-         else
-           {
-             coding->src_multibyte = 1;
-             encode_coding (coding, buf, conversion_buffer, chlen,
-                            conversion_buffer_size);
-             chlen -= coding->consumed;
-             enclen = coding->produced;
-
-             /* Replace glyph codes that cannot be converted by
-                terminal_coding with Vdos_unsupported_char_glyph.  */
-             if (*conversion_buffer == '?')
-               {
-                 unsigned char *cbp = conversion_buffer;
+      int cf;
+      int n;
+
+      /* If the face of this glyph is different from the current
+        screen face, update the screen attribute byte.  */
+      cf = str->face_id;
+      if (cf != screen_face)
+       IT_set_face (cf);       /* handles invalid faces gracefully */
+
+      /* Identify a run of glyphs with the same face.  */
+      for (n = 1; n < sl; ++n)
+       if (str[n].face_id != cf)
+         break;
 
-                 while (cbp < conversion_buffer + enclen && *cbp == '?')
-                   *cbp++ = unsupported_char;
-                 if (unsupported_face != screen_face)
-                   IT_set_face (unsupported_face);
-               }
-           }
+      if (n >= sl)
+       /* This is the last glyph.  */
+       coding->mode |= CODING_MODE_LAST_BLOCK;
 
-         if (enclen + chlen > screen_buf_end - screen_bp)
-           {
-             /* The allocated buffer for screen writes is too small.
-                Flush it and loop again without incrementing STR, so
-                that the next loop will begin with the same glyph.  */
-             int nbytes = screen_bp - screen_buf;
-
-             mouse_off_maybe ();
-             dosmemput (screen_buf, nbytes, (int)ScreenPrimary + offset);
-             if (screen_virtual_segment)
-               dosv_refresh_virtual_screen (offset, nbytes / 2);
-             new_pos_X += nbytes / 2;
-             offset += nbytes;
-
-             /* Prepare to reuse the same buffer again.  */
-             screen_bp = screen_buf;
-           }
-         else
+      conversion_buffer = encode_terminal_code (str, n, coding);
+      if (coding->produced > 0)
+       {
+         /* Copy the encoded bytes to the screen buffer.  */
+         for (bp = conversion_buffer; coding->produced--; bp++)
            {
-             /* There's enough place in the allocated buffer to add
-                the encoding of this glyph.  */
-
-             /* First, copy the encoded bytes.  */
-             for (bp = conversion_buffer; enclen--; bp++)
+             /* Paranoia: discard bytes that would overrun the end of
+                the screen buffer.  */
+             if (screen_bp - screen_buf <= MAX_SCREEN_BUF - 2)
                {
                  *screen_bp++ = (unsigned char)*bp;
                  *screen_bp++ = ScreenAttrib;
-                 if (termscript)
-                   fputc (*bp, termscript);
                }
-
-             /* Now copy the bytes not consumed by the encoding.  */
-             if (chlen > 0)
-               {
-                 buf += coding->consumed;
-                 while (chlen--)
-                   {
-                     if (termscript)
-                       fputc (*buf, termscript);
-                     *screen_bp++ = (unsigned char)*buf++;
-                     *screen_bp++ = ScreenAttrib;
-                   }
-               }
-
-             /* Update STR and its remaining length.  */
-             str++;
-             sl--;
+             if (tty->termscript)
+               fputc (*bp, tty->termscript);
            }
        }
+      /* Update STR and its remaining length.  */
+      str += n;
+      sl -= n;
     }
 
-  /* Dump whatever is left in the screen buffer.  */
+  /* Dump whatever we have in the screen buffer.  */
   mouse_off_maybe ();
   dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset);
   if (screen_virtual_segment)
     dosv_refresh_virtual_screen (offset, (screen_bp - screen_buf) / 2);
   new_pos_X += (screen_bp - screen_buf) / 2;
-
-  /* We may have to output some codes to terminate the writing.  */
-  if (CODING_REQUIRE_FLUSHING (coding))
-    {
-      coding->mode |= CODING_MODE_LAST_BLOCK;
-      encode_coding (coding, "", conversion_buffer, 0, conversion_buffer_size);
-      if (coding->produced > 0)
-       {
-         screen_buf = alloca (coding->produced * 2);
-         for (screen_bp = screen_buf, bp = conversion_buffer;
-              coding->produced--; bp++)
-           {
-             *screen_bp++ = (unsigned char)*bp;
-             *screen_bp++ = ScreenAttrib;
-             if (termscript)
-               fputc (*bp, termscript);
-           }
-         offset += screen_bp - screen_buf;
-         mouse_off_maybe ();
-         dosmemput (screen_buf, screen_bp - screen_buf,
-                    (int)ScreenPrimary + offset);
-         if (screen_virtual_segment)
-           dosv_refresh_virtual_screen (offset, (screen_bp - screen_buf) / 2);
-         new_pos_X += (screen_bp - screen_buf) / 2;
-       }
-    }
 }
 
 /************************************************************************
@@ -1198,570 +941,97 @@ static Lisp_Object last_mouse_window;
 
 static int mouse_preempted = 0;        /* non-zero when XMenu gobbles mouse events */
 
-/* Set the mouse pointer shape according to whether it is in the
-   area where the mouse highlight is in effect.  */
-static void
-IT_set_mouse_pointer (int mode)
+int
+popup_activated (void)
 {
-  /* A no-op for now.  DOS text-mode mouse pointer doesn't offer too
-     many possibilities to change its shape, and the available
-     functionality pretty much sucks (e.g., almost every reasonable
-     shape will conceal the character it is on).  Since the color of
-     the pointer changes in the highlighted area, it is not clear to
-     me whether anything else is required, anyway.  */
+  return mouse_preempted;
 }
 
-/* Display the active region described by mouse_face_*
-   in its mouse-face if HL > 0, in its normal face if HL = 0.  */
-static void
-show_mouse_face (struct display_info *dpyinfo, int hl)
+/* Draw TEXT_AREA glyphs between START and END of glyph row ROW on
+   window W.  X is relative to TEXT_AREA in W.  HL is a face override
+   for drawing the glyphs.  */
+void
+tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
+                             int start_hpos, int end_hpos,
+                             enum draw_glyphs_face hl)
 {
-  struct window *w = XWINDOW (dpyinfo->mouse_face_window);
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  int i;
-  struct face *fp;
-
-
-  /* If window is in the process of being destroyed, don't bother
-     doing anything.  */
-  if (w->current_matrix == NULL)
-    goto set_cursor_shape;
-
-  /* Recognize when we are called to operate on rows that don't exist
-     anymore.  This can happen when a window is split.  */
-  if (dpyinfo->mouse_face_end_row >= w->current_matrix->nrows)
-    goto set_cursor_shape;
-
-  /* There's no sense to do anything if the mouse face isn't realized.  */
-  if (hl > 0)
-    {
-      if (dpyinfo->mouse_face_hidden)
-       goto set_cursor_shape;
-
-      fp = FACE_FROM_ID (SELECTED_FRAME(), dpyinfo->mouse_face_face_id);
-      if (!fp)
-       goto set_cursor_shape;
-    }
-
-  /* Note that mouse_face_beg_row etc. are window relative.  */
-  for (i = dpyinfo->mouse_face_beg_row;
-       i <= dpyinfo->mouse_face_end_row;
-       i++)
-    {
-      int start_hpos, end_hpos;
-      struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
-
-      /* Don't do anything if row doesn't have valid contents.  */
-      if (!row->enabled_p)
-       continue;
-
-      /* For all but the first row, the highlight starts at column 0.  */
-      if (i == dpyinfo->mouse_face_beg_row)
-       start_hpos = dpyinfo->mouse_face_beg_col;
-      else
-       start_hpos = 0;
-
-      if (i == dpyinfo->mouse_face_end_row)
-       end_hpos = dpyinfo->mouse_face_end_col;
-      else
-       end_hpos = row->used[TEXT_AREA];
-
-      if (end_hpos <= start_hpos)
-       continue;
-      /* Record that some glyphs of this row are displayed in
-         mouse-face.  */
-      row->mouse_face_p = hl > 0;
-      if (hl > 0)
-       {
-         int vpos = row->y + WINDOW_TOP_EDGE_Y (w);
-         int kstart = start_hpos + WINDOW_LEFT_EDGE_X (w);
-         int nglyphs = end_hpos - start_hpos;
-         int offset = ScreenPrimary + 2*(vpos*screen_size_X + kstart) + 1;
-         int start_offset = offset;
-
-         if (termscript)
-           fprintf (termscript, "\n<MH+ %d-%d:%d>",
-                    kstart, kstart + nglyphs - 1, vpos);
-
-         mouse_off ();
-         IT_set_face (dpyinfo->mouse_face_face_id);
-         /* Since we are going to change only the _colors_ of the
-            displayed text, there's no need to go through all the
-            pain of generating and encoding the text from the glyphs.
-            Instead, we simply poke the attribute byte of each
-            affected position in video memory with the colors
-            computed by IT_set_face!  */
-         _farsetsel (_dos_ds);
-         while (nglyphs--)
-           {
-             _farnspokeb (offset, ScreenAttrib);
-             offset += 2;
-           }
-         if (screen_virtual_segment)
-           dosv_refresh_virtual_screen (start_offset, end_hpos - start_hpos);
-         mouse_on ();
-       }
-      else
-       {
-         /* We are removing a previously-drawn mouse highlight.  The
-            safest way to do so is to redraw the glyphs anew, since
-            all kinds of faces and display tables could have changed
-            behind our back.  */
-         int nglyphs = end_hpos - start_hpos;
-         int save_x = new_pos_X, save_y = new_pos_Y;
-
-         if (end_hpos >= row->used[TEXT_AREA])
-           nglyphs = row->used[TEXT_AREA] - start_hpos;
-
-         /* IT_write_glyphs writes at cursor position, so we need to
-            temporarily move cursor coordinates to the beginning of
-            the highlight region.  */
-         new_pos_X = start_hpos + WINDOW_LEFT_EDGE_X (w);
-         new_pos_Y = row->y + WINDOW_TOP_EDGE_Y (w);
-
-         if (termscript)
-           fprintf (termscript, "<MH- %d-%d:%d>",
-                    new_pos_X, new_pos_X + nglyphs - 1, new_pos_Y);
-         IT_write_glyphs (row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
-         if (termscript)
-           fputs ("\n", termscript);
-         new_pos_X = save_x;
-         new_pos_Y = save_y;
-       }
-    }
-
- set_cursor_shape:
-  /* Change the mouse pointer shape.  */
-  IT_set_mouse_pointer (hl);
-}
+  struct tty_display_info *tty = FRAME_TTY (f);
+  Mouse_HLInfo *hlinfo = &tty->mouse_highlight;
 
-/* Clear out the mouse-highlighted active region.
-   Redraw it un-highlighted first.  */
-static void
-clear_mouse_face (struct display_info *dpyinfo)
-{
-  if (!dpyinfo->mouse_face_hidden && ! NILP (dpyinfo->mouse_face_window))
-    show_mouse_face (dpyinfo, 0);
-
-  dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
-  dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
-  dpyinfo->mouse_face_window = Qnil;
-}
-
-/* Find the glyph matrix position of buffer position POS in window W.
-   *HPOS and *VPOS are set to the positions found.  W's current glyphs
-   must be up to date.  If POS is above window start return (0, 0).
-   If POS is after end of W, return end of last line in W.  */
-static int
-fast_find_position (struct window *w, int pos, int *hpos, int *vpos)
-{
-  int i, lastcol, line_start_position, maybe_next_line_p = 0;
-  int yb = window_text_bottom_y (w);
-  struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row;
-
-  while (row->y < yb)
+  if (hl == DRAW_MOUSE_FACE)
     {
-      if (row->used[TEXT_AREA])
-       line_start_position = row->glyphs[TEXT_AREA]->charpos;
-      else
-       line_start_position = 0;
+      int vpos = row->y + WINDOW_TOP_EDGE_Y (w);
+      int kstart = start_hpos + WINDOW_LEFT_EDGE_X (w);
+      int nglyphs = end_hpos - start_hpos;
+      int offset = ScreenPrimary + 2*(vpos*screen_size_X + kstart) + 1;
+      int start_offset = offset;
 
-      if (line_start_position > pos)
-       break;
-      /* If the position sought is the end of the buffer,
-        don't include the blank lines at the bottom of the window.  */
-      else if (line_start_position == pos
-              && pos == BUF_ZV (XBUFFER (w->buffer)))
-       {
-         maybe_next_line_p = 1;
-         break;
-       }
-      else if (line_start_position > 0)
-       best_row = row;
+      if (tty->termscript)
+       fprintf (tty->termscript, "\n<MH+ %d-%d:%d>",
+                kstart, kstart + nglyphs - 1, vpos);
 
-      /* Don't overstep the last matrix row, lest we get into the
-        never-never land... */
-      if (row->y + 1 >= yb)
-       break;
-
-      ++row;
-    }
-
-  /* Find the right column within BEST_ROW.  */
-  lastcol = 0;
-  row = best_row;
-  for (i = 0; i < row->used[TEXT_AREA]; i++)
-    {
-      struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
-      int charpos;
-
-      charpos = glyph->charpos;
-      if (charpos == pos)
+      mouse_off ();
+      IT_set_face (hlinfo->mouse_face_face_id);
+      /* Since we are going to change only the _colors_ of already
+        displayed text, there's no need to go through all the pain of
+        generating and encoding the text from the glyphs.  Instead,
+        we simply poke the attribute byte of each affected position
+        in video memory with the colors computed by IT_set_face!  */
+      _farsetsel (_dos_ds);
+      while (nglyphs--)
        {
-         *hpos = i;
-         *vpos = row->y;
-         return 1;
+         _farnspokeb (offset, ScreenAttrib);
+         offset += 2;
        }
-      else if (charpos > pos)
-       break;
-      else if (charpos > 0)
-       lastcol = i;
+      if (screen_virtual_segment)
+       dosv_refresh_virtual_screen (start_offset, end_hpos - start_hpos);
+      mouse_on ();
     }
-
-  /* If we're looking for the end of the buffer,
-     and we didn't find it in the line we scanned,
-     use the start of the following line.  */
-  if (maybe_next_line_p)
+  else if (hl == DRAW_NORMAL_TEXT)
     {
-      ++row;
-      lastcol = 0;
+      /* We are removing a previously-drawn mouse highlight.  The
+        safest way to do so is to redraw the glyphs anew, since all
+        kinds of faces and display tables could have changed behind
+        our back.  */
+      int nglyphs = end_hpos - start_hpos;
+      int save_x = new_pos_X, save_y = new_pos_Y;
+
+      if (end_hpos >= row->used[TEXT_AREA])
+       nglyphs = row->used[TEXT_AREA] - start_hpos;
+
+      /* IT_write_glyphs writes at cursor position, so we need to
+        temporarily move cursor coordinates to the beginning of
+        the highlight region.  */
+      new_pos_X = start_hpos + WINDOW_LEFT_EDGE_X (w);
+      new_pos_Y = row->y + WINDOW_TOP_EDGE_Y (w);
+
+      if (tty->termscript)
+       fprintf (tty->termscript, "<MH- %d-%d:%d>",
+                new_pos_X, new_pos_X + nglyphs - 1, new_pos_Y);
+      IT_write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
+      if (tty->termscript)
+       fputs ("\n", tty->termscript);
+      new_pos_X = save_x;
+      new_pos_Y = save_y;
     }
-
-  *vpos = row->y;
-  *hpos = lastcol + 1;
-  return 0;
 }
 
-/* Take proper action when mouse has moved to the mode or top line of
-   window W, x-position X.  MODE_LINE_P non-zero means mouse is on the
-   mode line.  X is relative to the start of the text display area of
-   W, so the width of fringes and scroll bars must be subtracted
-   to get a position relative to the start of the mode line.  */
 static void
-IT_note_mode_line_highlight (struct window *w, int x, int mode_line_p)
-{
-  struct frame *f = XFRAME (w->frame);
-  struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  struct glyph_row *row;
-
-  if (mode_line_p)
-    row = MATRIX_MODE_LINE_ROW (w->current_matrix);
-  else
-    row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
-
-  if (row->enabled_p)
-    {
-      extern Lisp_Object Qhelp_echo;
-      struct glyph *glyph, *end;
-      Lisp_Object help, map;
-
-      /* Find the glyph under X.  */
-      glyph = (row->glyphs[TEXT_AREA]
-              + x
-              /* in case someone implements scroll bars some day... */
-              - WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w));
-      end = glyph + row->used[TEXT_AREA];
-      if (glyph < end
-         && STRINGP (glyph->object)
-         && STRING_INTERVALS (glyph->object)
-         && glyph->charpos >= 0
-         && glyph->charpos < SCHARS (glyph->object))
-       {
-         /* If we're on a string with `help-echo' text property,
-            arrange for the help to be displayed.  This is done by
-            setting the global variable help_echo to the help string.  */
-         help = Fget_text_property (make_number (glyph->charpos),
-                                    Qhelp_echo, glyph->object);
-         if (!NILP (help))
-           {
-             help_echo_string = help;
-             XSETWINDOW (help_echo_window, w);
-             help_echo_object = glyph->object;
-             help_echo_pos = glyph->charpos;
-           }
-       }
-    }
-}
-
-/* Take proper action when the mouse has moved to position X, Y on
-   frame F as regards highlighting characters that have mouse-face
-   properties.  Also de-highlighting chars where the mouse was before.
-   X and Y can be negative or out of range.  */
-static void
-IT_note_mouse_highlight (struct frame *f, int x, int y)
-{
-  struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  enum window_part part = ON_NOTHING;
-  Lisp_Object window;
-  struct window *w;
-
-  /* When a menu is active, don't highlight because this looks odd.  */
-  if (mouse_preempted)
-    return;
-
-  if (NILP (Vmouse_highlight)
-      || !f->glyphs_initialized_p)
-    return;
-
-  dpyinfo->mouse_face_mouse_x = x;
-  dpyinfo->mouse_face_mouse_y = y;
-  dpyinfo->mouse_face_mouse_frame = f;
-
-  if (dpyinfo->mouse_face_defer)
-    return;
-
-  if (gc_in_progress)
-    {
-      dpyinfo->mouse_face_deferred_gc = 1;
-      return;
-    }
-
-  /* Which window is that in?  */
-  window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
-
-  /* If we were displaying active text in another window, clear that.  */
-  if (! EQ (window, dpyinfo->mouse_face_window))
-    clear_mouse_face (dpyinfo);
-
-  /* Not on a window -> return.  */
-  if (!WINDOWP (window))
-    return;
-
-  /* Convert to window-relative coordinates.  */
-  w = XWINDOW (window);
-
-  if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
-    {
-      /* Mouse is on the mode or top line.  */
-      IT_note_mode_line_highlight (w, x, part == ON_MODE_LINE);
-      return;
-    }
-
-  IT_set_mouse_pointer (0);
-
-  /* Are we in a window whose display is up to date?
-     And verify the buffer's text has not changed.  */
-  if (part == ON_TEXT
-      && EQ (w->window_end_valid, w->buffer)
-      && XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))
-      && (XFASTINT (w->last_overlay_modified)
-         == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
-    {
-      int pos, i, nrows = w->current_matrix->nrows;
-      struct glyph_row *row;
-      struct glyph *glyph;
-
-      /* Find the glyph under X/Y.  */
-      glyph = NULL;
-      if (y >= 0 && y < nrows)
-       {
-         row = MATRIX_ROW (w->current_matrix, y);
-         /* Give up if some row before the one we are looking for is
-            not enabled.  */
-         for (i = 0; i <= y; i++)
-           if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
-             break;
-         if (i > y  /* all rows upto and including the one at Y are enabled */
-             && row->displays_text_p
-             && x <  window_box_width (w, TEXT_AREA))
-           {
-             glyph = row->glyphs[TEXT_AREA];
-             if (x >= row->used[TEXT_AREA])
-               glyph = NULL;
-             else
-               {
-                 glyph += x;
-                 if (!BUFFERP (glyph->object))
-                   glyph = NULL;
-               }
-           }
-       }
-
-      /* Clear mouse face if X/Y not over text.  */
-      if (glyph == NULL)
-       {
-         clear_mouse_face (dpyinfo);
-         return;
-       }
-
-      if (!BUFFERP (glyph->object))
-       abort ();
-      pos = glyph->charpos;
-
-      /* Check for mouse-face and help-echo.  */
-      {
-       extern Lisp_Object Qmouse_face;
-       Lisp_Object mouse_face, overlay, position, *overlay_vec;
-       int noverlays, obegv, ozv;
-       struct buffer *obuf;
-
-       /* If we get an out-of-range value, return now; avoid an error.  */
-       if (pos > BUF_Z (XBUFFER (w->buffer)))
-         return;
-
-       /* Make the window's buffer temporarily current for
-          overlays_at and compute_char_face.  */
-       obuf = current_buffer;
-       current_buffer = XBUFFER (w->buffer);
-       obegv = BEGV;
-       ozv = ZV;
-       BEGV = BEG;
-       ZV = Z;
-
-       /* Is this char mouse-active or does it have help-echo?  */
-       XSETINT (position, pos);
-
-       /* Put all the overlays we want in a vector in overlay_vec. */
-       GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
-       /* Sort overlays into increasing priority order.  */
-       noverlays = sort_overlays (overlay_vec, noverlays, w);
-
-       /* Check mouse-face highlighting.  */
-       if (! (EQ (window, dpyinfo->mouse_face_window)
-              && y >= dpyinfo->mouse_face_beg_row
-              && y <= dpyinfo->mouse_face_end_row
-              && (y > dpyinfo->mouse_face_beg_row
-                  || x >= dpyinfo->mouse_face_beg_col)
-              && (y < dpyinfo->mouse_face_end_row
-                  || x < dpyinfo->mouse_face_end_col
-                  || dpyinfo->mouse_face_past_end)))
-         {
-           /* Clear the display of the old active region, if any.  */
-           clear_mouse_face (dpyinfo);
-
-           /* Find highest priority overlay that has a mouse-face prop.  */
-           overlay = Qnil;
-           for (i = noverlays - 1; i >= 0; --i)
-             {
-               mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
-               if (!NILP (mouse_face))
-                 {
-                   overlay = overlay_vec[i];
-                   break;
-                 }
-             }
-
-           /* If no overlay applies, get a text property.  */
-           if (NILP (overlay))
-             mouse_face = Fget_text_property (position, Qmouse_face,
-                                              w->buffer);
-
-           /* Handle the overlay case.  */
-           if (! NILP (overlay))
-             {
-               /* Find the range of text around this char that
-                  should be active.  */
-               Lisp_Object before, after;
-               EMACS_INT ignore;
-
-               before = Foverlay_start (overlay);
-               after = Foverlay_end (overlay);
-               /* Record this as the current active region.  */
-               fast_find_position (w, XFASTINT (before),
-                                   &dpyinfo->mouse_face_beg_col,
-                                   &dpyinfo->mouse_face_beg_row);
-               dpyinfo->mouse_face_past_end
-                 = !fast_find_position (w, XFASTINT (after),
-                                        &dpyinfo->mouse_face_end_col,
-                                        &dpyinfo->mouse_face_end_row);
-               dpyinfo->mouse_face_window = window;
-               dpyinfo->mouse_face_face_id
-                 = face_at_buffer_position (w, pos, 0, 0,
-                                            &ignore, pos + 1,
-                                            !dpyinfo->mouse_face_hidden);
-
-               /* Display it as active.  */
-               show_mouse_face (dpyinfo, 1);
-             }
-           /* Handle the text property case.  */
-           else if (! NILP (mouse_face))
-             {
-               /* Find the range of text around this char that
-                  should be active.  */
-               Lisp_Object before, after, beginning, end;
-               EMACS_INT ignore;
-
-               beginning = Fmarker_position (w->start);
-               XSETINT (end, (BUF_Z (XBUFFER (w->buffer))
-                              - XFASTINT (w->window_end_pos)));
-               before
-                 = Fprevious_single_property_change (make_number (pos + 1),
-                                                     Qmouse_face,
-                                                     w->buffer, beginning);
-               after
-                 = Fnext_single_property_change (position, Qmouse_face,
-                                                 w->buffer, end);
-               /* Record this as the current active region.  */
-               fast_find_position (w, XFASTINT (before),
-                                   &dpyinfo->mouse_face_beg_col,
-                                   &dpyinfo->mouse_face_beg_row);
-               dpyinfo->mouse_face_past_end
-                 = !fast_find_position (w, XFASTINT (after),
-                                        &dpyinfo->mouse_face_end_col,
-                                        &dpyinfo->mouse_face_end_row);
-               dpyinfo->mouse_face_window = window;
-               dpyinfo->mouse_face_face_id
-                 = face_at_buffer_position (w, pos, 0, 0,
-                                            &ignore, pos + 1,
-                                            !dpyinfo->mouse_face_hidden);
-
-               /* Display it as active.  */
-               show_mouse_face (dpyinfo, 1);
-             }
-         }
-
-       /* Look for a `help-echo' property.  */
-       {
-         Lisp_Object help;
-         extern Lisp_Object Qhelp_echo;
-
-         /* Check overlays first.  */
-         help = Qnil;
-         for (i = noverlays - 1; i >= 0 && NILP (help); --i)
-           {
-             overlay = overlay_vec[i];
-             help = Foverlay_get (overlay, Qhelp_echo);
-           }
-
-         if (!NILP (help))
-           {
-             help_echo_string = help;
-             help_echo_window = window;
-             help_echo_object = overlay;
-             help_echo_pos = pos;
-           }
-         /* Try text properties.  */
-         else if (NILP (help)
-                  && ((STRINGP (glyph->object)
-                       && glyph->charpos >= 0
-                       && glyph->charpos < SCHARS (glyph->object))
-                      || (BUFFERP (glyph->object)
-                          && glyph->charpos >= BEGV
-                          && glyph->charpos < ZV)))
-           {
-             help = Fget_text_property (make_number (glyph->charpos),
-                                        Qhelp_echo, glyph->object);
-             if (!NILP (help))
-               {
-                 help_echo_string = help;
-                 help_echo_window = window;
-                 help_echo_object = glyph->object;
-                 help_echo_pos = glyph->charpos;
-               }
-           }
-       }
-
-       BEGV = obegv;
-       ZV = ozv;
-       current_buffer = obuf;
-      }
-    }
-}
-
-static void
-IT_clear_end_of_line (int first_unused)
+IT_clear_end_of_line (struct frame *f, int first_unused)
 {
   char *spaces, *sp;
   int i, j, offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
   extern int fatal_error_in_progress;
+  struct tty_display_info *tty = FRAME_TTY (f);
 
   if (new_pos_X >= first_unused || fatal_error_in_progress)
     return;
 
   IT_set_face (0);
   i = (j = first_unused - new_pos_X) * 2;
-  if (termscript)
-    fprintf (termscript, "<CLR:EOL[%d..%d)>", new_pos_X, first_unused);
+  if (tty->termscript)
+    fprintf (tty->termscript, "<CLR:EOL[%d..%d)>", new_pos_X, first_unused);
   spaces = sp = alloca (i);
 
   while (--j >= 0)
@@ -1781,10 +1051,12 @@ IT_clear_end_of_line (int first_unused)
 }
 
 static void
-IT_clear_screen (void)
+IT_clear_screen (struct frame *f)
 {
-  if (termscript)
-    fprintf (termscript, "<CLR:SCR>");
+  struct tty_display_info *tty = FRAME_TTY (f);
+
+  if (tty->termscript)
+    fprintf (tty->termscript, "<CLR:SCR>");
   /* We are sometimes called (from clear_garbaged_frames) when a new
      frame is being created, but its faces are not yet realized.  In
      such a case we cannot call IT_set_face, since it will fail to find
@@ -1803,23 +1075,27 @@ IT_clear_screen (void)
 }
 
 static void
-IT_clear_to_end (void)
+IT_clear_to_end (struct frame *f)
 {
-  if (termscript)
-    fprintf (termscript, "<CLR:EOS>");
+  struct tty_display_info *tty = FRAME_TTY (f);
+
+  if (tty->termscript)
+    fprintf (tty->termscript, "<CLR:EOS>");
 
   while (new_pos_Y < screen_size_Y) {
     new_pos_X = 0;
-    IT_clear_end_of_line (screen_size_X);
+    IT_clear_end_of_line (f, screen_size_X);
     new_pos_Y++;
   }
 }
 
 static void
-IT_cursor_to (int y, int x)
+IT_cursor_to (struct frame *f, int y, int x)
 {
-  if (termscript)
-    fprintf (termscript, "\n<XY=%dx%d>", x, y);
+  struct tty_display_info *tty = FRAME_TTY (f);
+
+  if (tty->termscript)
+    fprintf (tty->termscript, "\n<XY=%dx%d>", x, y);
   new_pos_X = x;
   new_pos_Y = y;
 }
@@ -1829,17 +1105,23 @@ static int cursor_cleared;
 static void
 IT_display_cursor (int on)
 {
-  if (termscript)
-    fprintf (termscript, "\nCURSOR %s", on ? "ON" : "OFF");
+  struct tty_display_info *tty = CURTTY ();
+
   if (on && cursor_cleared)
     {
       ScreenSetCursor (current_pos_Y, current_pos_X);
       cursor_cleared = 0;
+      if (tty->termscript)
+       fprintf (tty->termscript, "\nCURSOR ON (%dx%d)",
+                current_pos_Y, current_pos_X);
     }
   else if (!on && !cursor_cleared)
     {
       ScreenSetCursor (-1, -1);
       cursor_cleared = 1;
+      if (tty->termscript)
+       fprintf (tty->termscript, "\nCURSOR OFF (%dx%d)",
+                current_pos_Y, current_pos_X);
     }
 }
 
@@ -1868,6 +1150,7 @@ IT_cmgoto (FRAME_PTR f)
   /* Only set the cursor to where it should be if the display is
      already in sync with the window contents.  */
   int update_cursor_pos = 1; /* MODIFF == unchanged_modified; */
+  struct tty_display_info *tty = FRAME_TTY (f);
 
   /* FIXME: This needs to be rewritten for the new redisplay, or
      removed.  */
@@ -1917,8 +1200,8 @@ IT_cmgoto (FRAME_PTR f)
       && (current_pos_X != new_pos_X || current_pos_Y != new_pos_Y))
     {
       ScreenSetCursor (current_pos_Y = new_pos_Y, current_pos_X = new_pos_X);
-      if (termscript)
-       fprintf (termscript, "\n<CURSOR:%dx%d>", current_pos_X, current_pos_Y);
+      if (tty->termscript)
+       fprintf (tty->termscript, "\n<CURSOR:%dx%d>", current_pos_X, current_pos_Y);
     }
 
   /* Maybe cursor is invisible, so make it visible.  */
@@ -1933,36 +1216,40 @@ IT_cmgoto (FRAME_PTR f)
 static void
 IT_update_begin (struct frame *f)
 {
-  struct display_info *display_info = FRAME_X_DISPLAY_INFO (f);
-  struct frame *mouse_face_frame = display_info->mouse_face_mouse_frame;
+  struct tty_display_info *display_info = FRAME_X_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = &display_info->mouse_highlight;
+  struct frame *mouse_face_frame = hlinfo->mouse_face_mouse_frame;
+
+  if (display_info->termscript)
+    fprintf (display_info->termscript, "\n\n<UPDATE_BEGIN");
 
   BLOCK_INPUT;
 
   if (f && f == mouse_face_frame)
     {
       /* Don't do highlighting for mouse motion during the update.  */
-      display_info->mouse_face_defer = 1;
+      hlinfo->mouse_face_defer = 1;
 
       /* If F needs to be redrawn, simply forget about any prior mouse
         highlighting.  */
       if (FRAME_GARBAGED_P (f))
-       display_info->mouse_face_window = Qnil;
+       hlinfo->mouse_face_window = Qnil;
 
       /* Can we tell that this update does not affect the window
         where the mouse highlight is?  If so, no need to turn off.
         Likewise, don't do anything if none of the enabled rows
         contains glyphs highlighted in mouse face.  */
-      if (!NILP (display_info->mouse_face_window)
-         && WINDOWP (display_info->mouse_face_window))
+      if (!NILP (hlinfo->mouse_face_window)
+         && WINDOWP (hlinfo->mouse_face_window))
        {
-         struct window *w = XWINDOW (display_info->mouse_face_window);
+         struct window *w = XWINDOW (hlinfo->mouse_face_window);
          int i;
 
          /* If the mouse highlight is in the window that was deleted
             (e.g., if it was popped by completion), clear highlight
             unconditionally.  */
          if (NILP (w->buffer))
-           display_info->mouse_face_window = Qnil;
+           hlinfo->mouse_face_window = Qnil;
          else
            {
              for (i = 0; i < w->desired_matrix->nrows; ++i)
@@ -1972,18 +1259,18 @@ IT_update_begin (struct frame *f)
            }
 
          if (NILP (w->buffer) || i < w->desired_matrix->nrows)
-           clear_mouse_face (display_info);
+           clear_mouse_face (hlinfo);
        }
     }
   else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame))
     {
       /* If the frame with mouse highlight was deleted, invalidate the
         highlight info.  */
-      display_info->mouse_face_beg_row = display_info->mouse_face_beg_col = -1;
-      display_info->mouse_face_end_row = display_info->mouse_face_end_col = -1;
-      display_info->mouse_face_window = Qnil;
-      display_info->mouse_face_deferred_gc = 0;
-      display_info->mouse_face_mouse_frame = NULL;
+      hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
+      hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
+      hlinfo->mouse_face_window = Qnil;
+      hlinfo->mouse_face_deferred_gc = 0;
+      hlinfo->mouse_face_mouse_frame = NULL;
     }
 
   UNBLOCK_INPUT;
@@ -1992,25 +1279,29 @@ IT_update_begin (struct frame *f)
 static void
 IT_update_end (struct frame *f)
 {
-  FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
+  struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+  if (dpyinfo->termscript)
+    fprintf (dpyinfo->termscript, "\n<UPDATE_END\n");
+  dpyinfo->mouse_highlight.mouse_face_defer = 0;
 }
 
 static void
 IT_frame_up_to_date (struct frame *f)
 {
-  struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   Lisp_Object new_cursor, frame_desired_cursor;
   struct window *sw;
 
-  if (dpyinfo->mouse_face_deferred_gc
-      || (f && f == dpyinfo->mouse_face_mouse_frame))
+  if (hlinfo->mouse_face_deferred_gc
+      || (f && f == hlinfo->mouse_face_mouse_frame))
     {
       BLOCK_INPUT;
-      if (dpyinfo->mouse_face_mouse_frame)
-       IT_note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
-                                dpyinfo->mouse_face_mouse_x,
-                                dpyinfo->mouse_face_mouse_y);
-      dpyinfo->mouse_face_deferred_gc = 0;
+      if (hlinfo->mouse_face_mouse_frame)
+       note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
+                             hlinfo->mouse_face_mouse_x,
+                             hlinfo->mouse_face_mouse_y);
+      hlinfo->mouse_face_deferred_gc = 0;
       UNBLOCK_INPUT;
     }
 
@@ -2081,9 +1372,7 @@ IT_copy_glyphs (int xfrom, int xto, size_t len, int ypos)
 
 /* Insert and delete glyphs.  */
 static void
-IT_insert_glyphs (start, len)
-     register struct glyph *start;
-     register int len;
+IT_insert_glyphs (struct frame *f, struct glyph *start, int len)
 {
   int shift_by_width = screen_size_X - (new_pos_X + len);
 
@@ -2092,22 +1381,21 @@ IT_insert_glyphs (start, len)
   IT_copy_glyphs (new_pos_X, new_pos_X + len, shift_by_width, new_pos_Y);
 
   /* Now write the glyphs to be inserted.  */
-  IT_write_glyphs (start, len);
+  IT_write_glyphs (f, start, len);
 }
 
 static void
-IT_delete_glyphs (n)
-     register int n;
+IT_delete_glyphs (struct frame *f, int n)
 {
   abort ();
 }
 
 /* set-window-configuration on window.c needs this.  */
 void
-x_set_menu_bar_lines (f, value, oldval)
-     struct frame *f;
-     Lisp_Object value, oldval;
+x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
 {
+  extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
+
   set_menu_bar_lines (f, value, oldval);
 }
 
@@ -2122,10 +1410,19 @@ extern Lisp_Object Qtitle;
    resumed, and whenever the screen is redrawn!  */
 
 static void
-IT_set_terminal_modes (void)
+IT_set_terminal_modes (struct terminal *term)
 {
-  if (termscript)
-    fprintf (termscript, "\n<SET_TERM>");
+  struct tty_display_info *tty;
+
+  /* If called with initial terminal, it's too early to do anything
+     useful.  */
+  if (term->type == output_initial)
+    return;
+
+  tty = term->display_info.tty;
+
+  if (tty->termscript)
+    fprintf (tty->termscript, "\n<SET_TERM>");
 
   screen_size_X = ScreenCols ();
   screen_size_Y = ScreenRows ();
@@ -2142,7 +1439,6 @@ IT_set_terminal_modes (void)
   startup_screen_size_Y = screen_size_Y;
   startup_screen_attrib = ScreenAttrib;
 
-#if __DJGPP__ > 1
   /* Is DOS/V (or any other RSIS software which relocates
      the screen) installed?  */
   {
@@ -2166,22 +1462,17 @@ IT_set_terminal_modes (void)
           already point to the relocated buffer address returned by
           the Int 10h/AX=FEh call above.  DJGPP v2.02 and later sets
           ScreenPrimary to that address at startup under DOS/V.  */
-       if (regs.x.es != (ScreenPrimary >> 4) & 0xffff)
+       if (regs.x.es != ((ScreenPrimary >> 4) & 0xffff))
          screen_old_address = ScreenPrimary;
        screen_virtual_segment = regs.x.es;
        screen_virtual_offset  = regs.x.di;
        ScreenPrimary = (screen_virtual_segment << 4) + screen_virtual_offset;
       }
   }
-#endif /* __DJGPP__ > 1 */
 
   ScreenGetCursor (&startup_pos_Y, &startup_pos_X);
   ScreenRetrieve (startup_screen_buffer = xmalloc (screen_size * 2));
 
-  if (termscript)
-    fprintf (termscript, "<SCREEN SAVED (dimensions=%dx%d)>\n",
-            screen_size_X, screen_size_Y);
-
   bright_bg ();
 }
 
@@ -2189,7 +1480,7 @@ IT_set_terminal_modes (void)
    suspended or killed.  */
 
 static void
-IT_reset_terminal_modes (void)
+IT_reset_terminal_modes (struct terminal *term)
 {
   int display_row_start = (int) ScreenPrimary;
   int saved_row_len     = startup_screen_size_X * 2;
@@ -2197,9 +1488,10 @@ IT_reset_terminal_modes (void)
   int to_next_row       = update_row_len;
   unsigned char *saved_row = startup_screen_buffer;
   int cursor_pos_X = ScreenCols () - 1, cursor_pos_Y = ScreenRows () - 1;
+  struct tty_display_info *tty = term->display_info.tty;
 
-  if (termscript)
-    fprintf (termscript, "\n<RESET_TERM>");
+  if (tty->termscript)
+    fprintf (tty->termscript, "\n<RESET_TERM>");
 
   if (!term_setup_done)
     return;
@@ -2238,8 +1530,8 @@ IT_reset_terminal_modes (void)
       if (current_rows > startup_screen_size_Y)
        current_rows = startup_screen_size_Y;
 
-      if (termscript)
-       fprintf (termscript, "<SCREEN RESTORED (dimensions=%dx%d)>\n",
+      if (tty->termscript)
+       fprintf (tty->termscript, "<SCREEN RESTORED (dimensions=%dx%d)>\n",
                 update_row_len / 2, current_rows);
 
       while (current_rows--)
@@ -2259,12 +1551,13 @@ IT_reset_terminal_modes (void)
 
   ScreenSetCursor (cursor_pos_Y, cursor_pos_X);
   xfree (startup_screen_buffer);
+  startup_screen_buffer = NULL;
 
   term_setup_done = 0;
 }
 
 static void
-IT_set_terminal_window (int foo)
+IT_set_terminal_window (struct frame *f, int foo)
 {
 }
 
@@ -2273,34 +1566,25 @@ IT_set_terminal_window (int foo)
 DEFUN ("msdos-remember-default-colors", Fmsdos_remember_default_colors,
        Smsdos_remember_default_colors, 1, 1, 0,
        doc: /* Remember the screen colors of the current frame.  */)
-     (frame)
-     Lisp_Object frame;
+  (Lisp_Object frame)
 {
   struct frame *f;
 
   CHECK_FRAME (frame);
-  f= XFRAME (frame);
+  f = XFRAME (frame);
 
   /* This function is called after applying default-frame-alist to the
      initial frame.  At that time, if reverse-colors option was
      specified in default-frame-alist, it was already applied, and
-     frame colors are reversed.  We need to account for that.  */
-  if (EQ (Fcdr (Fassq (Qreverse, f->param_alist)), Qt))
-    {
-      initial_screen_colors[0] = FRAME_BACKGROUND_PIXEL (f);
-      initial_screen_colors[1] = FRAME_FOREGROUND_PIXEL (f);
-    }
-  else
-    {
-      initial_screen_colors[0] = FRAME_FOREGROUND_PIXEL (f);
-      initial_screen_colors[1] = FRAME_BACKGROUND_PIXEL (f);
-    }
+     frame colors are reversed.  */
+  initial_screen_colors[0] = FRAME_FOREGROUND_PIXEL (f);
+  initial_screen_colors[1] = FRAME_BACKGROUND_PIXEL (f);
+
+  return Qnil;
 }
 
 void
-IT_set_frame_parameters (f, alist)
-     struct frame *f;
-     Lisp_Object alist;
+IT_set_frame_parameters (struct frame *f, Lisp_Object alist)
 {
   Lisp_Object tail;
   int i, j, length = XINT (Flength (alist));
@@ -2310,31 +1594,22 @@ IT_set_frame_parameters (f, alist)
     = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
   /* Do we have to reverse the foreground and background colors?  */
   int reverse = EQ (Fcdr (Fassq (Qreverse, f->param_alist)), Qt);
-  int need_to_reverse, was_reverse = reverse;
   int redraw = 0, fg_set = 0, bg_set = 0;
   unsigned long orig_fg, orig_bg;
-  Lisp_Object frame_bg, frame_fg;
-  extern Lisp_Object Qdefault, QCforeground, QCbackground;
+  struct tty_display_info *tty = FRAME_TTY (f);
 
   /* If we are creating a new frame, begin with the original screen colors
      used for the initial frame.  */
-  if (EQ (alist, Vdefault_frame_alist)
+  if (!f->default_face_done_p
       && initial_screen_colors[0] != -1 && initial_screen_colors[1] != -1)
     {
       FRAME_FOREGROUND_PIXEL (f) = initial_screen_colors[0];
       FRAME_BACKGROUND_PIXEL (f) = initial_screen_colors[1];
+      init_frame_faces (f);
+      f->default_face_done_p = 1;
     }
-  orig_fg = FRAME_FOREGROUND_PIXEL (f);
-  orig_bg = FRAME_BACKGROUND_PIXEL (f);
-  frame_fg = Fcdr (Fassq (Qforeground_color, f->param_alist));
-  frame_bg = Fcdr (Fassq (Qbackground_color, f->param_alist));
-  /* frame_fg and frame_bg could be nil if, for example,
-     f->param_alist is nil, e.g. if we are called from
-     Fmake_terminal_frame.  */
-  if (NILP (frame_fg))
-    frame_fg = build_string (unspecified_fg);
-  if (NILP (frame_bg))
-    frame_bg = build_string (unspecified_bg);
+  orig_fg = reverse ? FRAME_BACKGROUND_PIXEL (f) : FRAME_FOREGROUND_PIXEL (f);
+  orig_bg = reverse ? FRAME_FOREGROUND_PIXEL (f) : FRAME_BACKGROUND_PIXEL (f);
 
   /* Extract parm names and values into those vectors.  */
   i = 0;
@@ -2362,119 +1637,120 @@ IT_set_frame_parameters (f, alist)
        reverse = EQ (val, Qt);
     }
 
-  need_to_reverse = reverse && !was_reverse;
-  if (termscript && need_to_reverse)
-    fprintf (termscript, "<INVERSE-VIDEO>\n");
+  if (tty->termscript && reverse)
+    fprintf (tty->termscript, "<INVERSE-VIDEO>\n");
 
   /* Now process the alist elements in reverse of specified order.  */
   for (i--; i >= 0; i--)
     {
-      Lisp_Object prop, val, frame;
+      Lisp_Object prop, val;
 
       prop = parms[i];
       val  = values[i];
 
       if (EQ (prop, Qforeground_color))
        {
-         unsigned long new_color = load_color (f, NULL, val, need_to_reverse
+         unsigned long new_color = load_color (f, NULL, val, reverse
                                                ? LFACE_BACKGROUND_INDEX
                                                : LFACE_FOREGROUND_INDEX);
          if (new_color !=  FACE_TTY_DEFAULT_COLOR
              && new_color != FACE_TTY_DEFAULT_FG_COLOR
              && new_color != FACE_TTY_DEFAULT_BG_COLOR)
            {
-             FRAME_FOREGROUND_PIXEL (f) = new_color;
-             /* Make sure the foreground of the default face for this
-                frame is changed as well.  */
-             XSETFRAME (frame, f);
-             if (need_to_reverse)
+             if (!reverse)
                {
-                 Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
-                                                    val, frame);
-                 prop = Qbackground_color;
-                 bg_set = 1;
+                 FRAME_FOREGROUND_PIXEL (f) = new_color;
+                 /* Make sure the foreground of the default face for
+                    this frame is changed as well.  */
+                 update_face_from_frame_parameter (f, Qforeground_color, val);
+                 fg_set = 1;
+                 if (tty->termscript)
+                   fprintf (tty->termscript, "<FGCOLOR %lu>\n", new_color);
                }
              else
                {
-                 Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
-                                                    val, frame);
-                 fg_set = 1;
+                 FRAME_BACKGROUND_PIXEL (f) = new_color;
+                 update_face_from_frame_parameter (f, Qbackground_color, val);
+                 bg_set = 1;
+                 if (tty->termscript)
+                   fprintf (tty->termscript, "<BGCOLOR %lu>\n", new_color);
                }
              redraw = 1;
-             if (termscript)
-               fprintf (termscript, "<FGCOLOR %lu>\n", new_color);
            }
        }
       else if (EQ (prop, Qbackground_color))
        {
-         unsigned long new_color = load_color (f, NULL, val, need_to_reverse
+         unsigned long new_color = load_color (f, NULL, val, reverse
                                                ? LFACE_FOREGROUND_INDEX
                                                : LFACE_BACKGROUND_INDEX);
          if (new_color != FACE_TTY_DEFAULT_COLOR
              && new_color != FACE_TTY_DEFAULT_FG_COLOR
              && new_color != FACE_TTY_DEFAULT_BG_COLOR)
            {
-             FRAME_BACKGROUND_PIXEL (f) = new_color;
-             /* Make sure the background of the default face for this
-                frame is changed as well.  */
-             XSETFRAME (frame, f);
-             if (need_to_reverse)
+             if (!reverse)
                {
-                 Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
-                                                    val, frame);
-                 prop = Qforeground_color;
-                 fg_set = 1;
+                 FRAME_BACKGROUND_PIXEL (f) = new_color;
+                 /* Make sure the background of the default face for
+                    this frame is changed as well.  */
+                 bg_set = 1;
+                 update_face_from_frame_parameter (f, Qbackground_color, val);
+                 if (tty->termscript)
+                   fprintf (tty->termscript, "<BGCOLOR %lu>\n", new_color);
                }
              else
                {
-                 Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
-                                                    val, frame);
-                 bg_set = 1;
+                 FRAME_FOREGROUND_PIXEL (f) = new_color;
+                 fg_set = 1;
+                 update_face_from_frame_parameter (f, Qforeground_color, val);
+                 if (tty->termscript)
+                   fprintf (tty->termscript, "<FGCOLOR %lu>\n", new_color);
                }
              redraw = 1;
-             if (termscript)
-               fprintf (termscript, "<BGCOLOR %lu>\n", new_color);
            }
        }
       else if (EQ (prop, Qtitle))
        {
          x_set_title (f, val);
-         if (termscript)
-           fprintf (termscript, "<TITLE: %s>\n", SDATA (val));
+         if (tty->termscript)
+           fprintf (tty->termscript, "<TITLE: %s>\n", SDATA (val));
        }
       else if (EQ (prop, Qcursor_type))
        {
          IT_set_cursor_type (f, val);
-         if (termscript)
-           fprintf (termscript, "<CTYPE: %s>\n",
-                    EQ (val, Qbar) || EQ (val, Qhbar)
-                    || CONSP (val) && (EQ (XCAR (val), Qbar)
-                                       || EQ (XCAR (val), Qhbar))
+         if (tty->termscript)
+           fprintf (tty->termscript, "<CTYPE: %s>\n",
+                    EQ (val, Qbar)
+                    || EQ (val, Qhbar)
+                    || (CONSP (val) && (EQ (XCAR (val), Qbar)
+                                        || EQ (XCAR (val), Qhbar)))
                     ? "bar" : "box");
        }
+      else if (EQ (prop, Qtty_type))
+       {
+         internal_terminal_init ();
+         if (tty->termscript)
+           fprintf (tty->termscript, "<TERM_INIT done, TTY_TYPE: %.*s>\n",
+                    SBYTES (val), SDATA (val));
+       }
       store_frame_param (f, prop, val);
     }
 
   /* If they specified "reverse", but not the colors, we need to swap
      the current frame colors.  */
-  if (need_to_reverse)
+  if (reverse)
     {
-      Lisp_Object frame;
-
       if (!fg_set)
        {
-         XSETFRAME (frame, f);
-         Finternal_set_lisp_face_attribute (Qdefault, QCforeground,
-                                            tty_color_name (f, orig_bg),
-                                            frame);
+         FRAME_FOREGROUND_PIXEL (f) = orig_bg;
+         update_face_from_frame_parameter (f, Qforeground_color,
+                                           tty_color_name (f, orig_bg));
          redraw = 1;
        }
       if (!bg_set)
        {
-         XSETFRAME (frame, f);
-         Finternal_set_lisp_face_attribute (Qdefault, QCbackground,
-                                            tty_color_name (f, orig_fg),
-                                            frame);
+         FRAME_BACKGROUND_PIXEL (f) = orig_fg;
+         update_face_from_frame_parameter (f, Qbackground_color,
+                                           tty_color_name (f, orig_fg));
          redraw = 1;
        }
     }
@@ -2495,22 +1771,25 @@ extern void init_frame_faces (FRAME_PTR);
 /* Do we need the internal terminal?  */
 
 void
-internal_terminal_init ()
+internal_terminal_init (void)
 {
+  static int init_needed = 1;
   char *term = getenv ("TERM"), *colors;
   struct frame *sf = SELECTED_FRAME();
+  struct tty_display_info *tty;
 
 #ifdef HAVE_X_WINDOWS
   if (!inhibit_window_system)
     return;
 #endif
 
+  /* If this is the initial terminal, we are done here.  */
+  if (sf->output_method == output_initial)
+    return;
+
   internal_terminal
     = (!noninteractive) && term && !strcmp (term, "internal");
 
-  if (getenv ("EMACSTEST"))
-    termscript = fopen (getenv ("EMACSTEST"), "wt");
-
 #ifndef HAVE_X_WINDOWS
   if (!internal_terminal || inhibit_window_system)
     {
@@ -2518,77 +1797,118 @@ internal_terminal_init ()
       return;
     }
 
-  Vwindow_system = intern ("pc");
-  Vwindow_system_version = make_number (1);
+  tty = FRAME_TTY (sf);
+  current_kboard->Vwindow_system = Qpc;
   sf->output_method = output_msdos_raw;
+  if (init_needed)
+    {
+      if (!tty->termscript && getenv ("EMACSTEST"))
+       tty->termscript = fopen (getenv ("EMACSTEST"), "wt");
+      if (tty->termscript)
+       {
+         time_t now = time (NULL);
+         struct tm *tnow = localtime (&now);
+         char tbuf[100];
 
-  /* If Emacs was dumped on DOS/V machine, forget the stale VRAM address.  */
-  screen_old_address = 0;
+         strftime (tbuf, sizeof (tbuf) - 1, "%a %b %e %Y %H:%M:%S %Z", tnow);
+         fprintf (tty->termscript, "\nEmacs session started at %s\n", tbuf);
+         fprintf (tty->termscript,   "=====================\n\n");
+       }
 
-  /* Forget the stale screen colors as well.  */
-  initial_screen_colors[0] = initial_screen_colors[1] = -1;
+      Vinitial_window_system = Qpc;
+      Vwindow_system_version = make_number (23); /* RE Emacs version */
+      tty->terminal->type = output_msdos_raw;
 
-  bzero (&the_only_x_display, sizeof the_only_x_display);
-  FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = 7; /* White */
-  FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ()) = 0; /* Black */
-  bright_bg ();
-  colors = getenv ("EMACSCOLORS");
-  if (colors && strlen (colors) >= 2)
-    {
-      /* The colors use 4 bits each (we enable bright background).  */
-      if (isdigit (colors[0]))
-        colors[0] -= '0';
-      else if (isxdigit (colors[0]))
-        colors[0] -= (isupper (colors[0]) ? 'A' : 'a') - 10;
-      if (colors[0] >= 0 && colors[0] < 16)
-        FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ()) = colors[0];
-      if (isdigit (colors[1]))
-        colors[1] -= '0';
-      else if (isxdigit (colors[1]))
-        colors[1] -= (isupper (colors[1]) ? 'A' : 'a') - 10;
-      if (colors[1] >= 0 && colors[1] < 16)
-        FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1];
+      /* If Emacs was dumped on DOS/V machine, forget the stale VRAM
+        address.  */
+      screen_old_address = 0;
+
+      /* Forget the stale screen colors as well.  */
+      initial_screen_colors[0] = initial_screen_colors[1] = -1;
+
+      FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = 7; /* White */
+      FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ()) = 0; /* Black */
+      bright_bg ();
+      colors = getenv ("EMACSCOLORS");
+      if (colors && strlen (colors) >= 2)
+       {
+         /* The colors use 4 bits each (we enable bright background).  */
+         if (isdigit (colors[0]))
+           colors[0] -= '0';
+         else if (isxdigit (colors[0]))
+           colors[0] -= (isupper (colors[0]) ? 'A' : 'a') - 10;
+         if (colors[0] >= 0 && colors[0] < 16)
+           FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ()) = colors[0];
+         if (isdigit (colors[1]))
+           colors[1] -= '0';
+         else if (isxdigit (colors[1]))
+           colors[1] -= (isupper (colors[1]) ? 'A' : 'a') - 10;
+         if (colors[1] >= 0 && colors[1] < 16)
+           FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1];
+       }
+      the_only_display_info.mouse_highlight.mouse_face_mouse_frame = NULL;
+      the_only_display_info.mouse_highlight.mouse_face_deferred_gc = 0;
+      the_only_display_info.mouse_highlight.mouse_face_beg_row =
+       the_only_display_info.mouse_highlight.mouse_face_beg_col = -1;
+      the_only_display_info.mouse_highlight.mouse_face_end_row =
+       the_only_display_info.mouse_highlight.mouse_face_end_col = -1;
+      the_only_display_info.mouse_highlight.mouse_face_face_id = DEFAULT_FACE_ID;
+      the_only_display_info.mouse_highlight.mouse_face_window = Qnil;
+      the_only_display_info.mouse_highlight.mouse_face_mouse_x =
+       the_only_display_info.mouse_highlight.mouse_face_mouse_y = 0;
+      the_only_display_info.mouse_highlight.mouse_face_defer = 0;
+      the_only_display_info.mouse_highlight.mouse_face_hidden = 0;
+
+      if (have_mouse)  /* detected in dos_ttraw, which see */
+       {
+         have_mouse = 1;       /* enable mouse */
+         mouse_visible = 0;
+         mouse_setup_buttons (mouse_button_count);
+         tty->terminal->mouse_position_hook = &mouse_get_pos;
+         mouse_init ();
+       }
+
+      if (tty->termscript && screen_size)
+       fprintf (tty->termscript, "<SCREEN SAVED (dimensions=%dx%d)>\n",
+                screen_size_X, screen_size_Y);
+
+      init_frame_faces (sf);
+      init_needed = 0;
     }
-  the_only_x_display.font = (XFontStruct *)1;   /* must *not* be zero */
-  the_only_x_display.display_info.mouse_face_mouse_frame = NULL;
-  the_only_x_display.display_info.mouse_face_deferred_gc = 0;
-  the_only_x_display.display_info.mouse_face_beg_row =
-    the_only_x_display.display_info.mouse_face_beg_col = -1;
-  the_only_x_display.display_info.mouse_face_end_row =
-    the_only_x_display.display_info.mouse_face_end_col = -1;
-  the_only_x_display.display_info.mouse_face_face_id = DEFAULT_FACE_ID;
-  the_only_x_display.display_info.mouse_face_window = Qnil;
-  the_only_x_display.display_info.mouse_face_mouse_x =
-    the_only_x_display.display_info.mouse_face_mouse_y = 0;
-  the_only_x_display.display_info.mouse_face_defer = 0;
-  the_only_x_display.display_info.mouse_face_hidden = 0;
-
-  init_frame_faces (sf);
-
-  ring_bell_hook = IT_ring_bell;
-  insert_glyphs_hook = IT_insert_glyphs;
-  delete_glyphs_hook = IT_delete_glyphs;
-  write_glyphs_hook = IT_write_glyphs;
-  cursor_to_hook = raw_cursor_to_hook = IT_cursor_to;
-  clear_to_end_hook = IT_clear_to_end;
-  clear_end_of_line_hook = IT_clear_end_of_line;
-  clear_frame_hook = IT_clear_screen;
-  update_begin_hook = IT_update_begin;
-  update_end_hook = IT_update_end;
-  frame_up_to_date_hook = IT_frame_up_to_date;
-
-  /* These hooks are called by term.c without being checked.  */
-  set_terminal_modes_hook = IT_set_terminal_modes;
-  reset_terminal_modes_hook = IT_reset_terminal_modes;
-  set_terminal_window_hook = IT_set_terminal_window;
-  TTY_CHAR_INS_DEL_OK (CURTTY ()) = 0;
 #endif
 }
 
-dos_get_saved_screen (screen, rows, cols)
-     char **screen;
-     int *rows;
-     int *cols;
+void
+initialize_msdos_display (struct terminal *term)
+{
+  term->rif = 0;               /* we don't support window-based display */
+  term->cursor_to_hook = term->raw_cursor_to_hook = IT_cursor_to;
+  term->clear_to_end_hook = IT_clear_to_end;
+  term->clear_frame_hook = IT_clear_screen;
+  term->clear_end_of_line_hook = IT_clear_end_of_line;
+  term->ins_del_lines_hook = 0;
+  term->insert_glyphs_hook = IT_insert_glyphs;
+  term->write_glyphs_hook = IT_write_glyphs;
+  term->delete_glyphs_hook = IT_delete_glyphs;
+  term->ring_bell_hook = IT_ring_bell;
+  term->reset_terminal_modes_hook = IT_reset_terminal_modes;
+  term->set_terminal_modes_hook = IT_set_terminal_modes;
+  term->set_terminal_window_hook = IT_set_terminal_window;
+  term->update_begin_hook = IT_update_begin;
+  term->update_end_hook = IT_update_end;
+  term->frame_up_to_date_hook = IT_frame_up_to_date;
+  term->mouse_position_hook = 0; /* set later by dos_ttraw */
+  term->frame_rehighlight_hook = 0;
+  term->frame_raise_lower_hook = 0;
+  term->set_vertical_scroll_bar_hook = 0;
+  term->condemn_scroll_bars_hook = 0;
+  term->redeem_scroll_bar_hook = 0;
+  term->judge_scroll_bars_hook = 0;
+  term->read_socket_hook = &tty_read_avail_input; /* from keyboard.c */
+}
+
+int
+dos_get_saved_screen (char **screen, int *rows, int *cols)
 {
 #ifndef HAVE_X_WINDOWS
   *screen = startup_screen_buffer;
@@ -2735,11 +2055,11 @@ static struct keyboard_layout_list
   struct dos_keyboard_map *keyboard_map;
 } keyboard_layout_list[] =
 {
-  1, &us_keyboard,
-  33, &fr_keyboard,
-  39, &it_keyboard,
-  45, &dk_keyboard,
-  81, &jp_keyboard
+  { 1, &us_keyboard },
+  { 33, &fr_keyboard },
+  { 39, &it_keyboard },
+  { 45, &dk_keyboard },
+  { 81, &jp_keyboard }
 };
 
 static struct dos_keyboard_map *keyboard;
@@ -2747,9 +2067,7 @@ static int keyboard_map_all;
 static int international_keyboard;
 
 int
-dos_set_keyboard (code, always)
-     int code;
-     int always;
+dos_set_keyboard (int code, int always)
 {
   int i;
   _go32_dpmi_registers regs;
@@ -2786,17 +2104,17 @@ static struct
   unsigned char keypad_code;   /* keypad code  */
   unsigned char editkey_code;  /* edit key     */
 } keypad_translate_map[] = {
-  '0',  '0',  0xb0, /* kp-0 */         0x63, /* insert */
-  '1',  '1',  0xb1, /* kp-1 */         0x57, /* end */
-  '2',  '2',  0xb2, /* kp-2 */         0x54, /* down */
-  '3',  '3',  0xb3, /* kp-3 */         0x56, /* next */
-  '4',  '4',  0xb4, /* kp-4 */         0x51, /* left */
-  '5',  '5',  0xb5, /* kp-5 */         0xb5, /* kp-5 */
-  '6',  '6',  0xb6, /* kp-6 */         0x53, /* right */
-  '7',  '7',  0xb7, /* kp-7 */         0x50, /* home */
-  '8',  '8',  0xb8, /* kp-8 */         0x52, /* up */
-  '9',  '9',  0xb9, /* kp-9 */         0x55, /* prior */
-  '.',  '-',  0xae, /* kp-decimal */   0xff  /* delete */
+  { '0',  '0',  0xb0, /* kp-0 */               0x63 /* insert */ },
+  { '1',  '1',  0xb1, /* kp-1 */               0x57 /* end */    },
+  { '2',  '2',  0xb2, /* kp-2 */               0x54 /* down */   },
+  { '3',  '3',  0xb3, /* kp-3 */               0x56 /* next */   },
+  { '4',  '4',  0xb4, /* kp-4 */               0x51 /* left */   },
+  { '5',  '5',  0xb5, /* kp-5 */               0xb5 /* kp-5 */   },
+  { '6',  '6',  0xb6, /* kp-6 */               0x53 /* right */  },
+  { '7',  '7',  0xb7, /* kp-7 */               0x50 /* home */   },
+  { '8',  '8',  0xb8, /* kp-8 */               0x52 /* up */     },
+  { '9',  '9',  0xb9, /* kp-9 */               0x55 /* prior */  },
+  { '.',  '-',  0xae, /* kp-decimal */         0xff  /* delete */}
 };
 
 static struct
@@ -2804,11 +2122,11 @@ static struct
   unsigned char char_code;     /* normal code  */
   unsigned char keypad_code;   /* keypad code  */
 } grey_key_translate_map[] = {
-  '/',  0xaf, /* kp-decimal */
-  '*',  0xaa, /* kp-multiply */
-  '-',  0xad, /* kp-subtract */
-  '+',  0xab, /* kp-add */
-  '\r', 0x8d  /* kp-enter */
+  { '/',  0xaf /* kp-decimal */  },
+  { '*',  0xaa /* kp-multiply */ },
+  { '-',  0xad /* kp-subtract */ },
+  { '+',  0xab /* kp-add */      },
+  { '\r', 0x8d  /* kp-enter */   }
 };
 
 static unsigned short
@@ -3016,8 +2334,7 @@ ibmpc_translate_map[] =
 #define HYPER_P                0x8000  /* pseudo */
 
 static int
-dos_get_modifiers (keymask)
-     int *keymask;
+dos_get_modifiers (int *keymask)
 {
   union REGS regs;
   int mask, modifiers = 0;
@@ -3099,13 +2416,13 @@ dos_get_modifiers (keymask)
 #define NUM_RECENT_DOSKEYS (100)
 int recent_doskeys_index;      /* Index for storing next element into recent_doskeys */
 int total_doskeys;             /* Total number of elements stored into recent_doskeys */
-Lisp_Object recent_doskeys; /* A vector, holding the last 100 keystrokes */
+Lisp_Object recent_doskeys;    /* A vector, holding the last 100 keystrokes */
 
 DEFUN ("recent-doskeys", Frecent_doskeys, Srecent_doskeys, 0, 0, 0,
        doc: /* Return vector of last 100 keyboard input values seen in dos_rawgetc.
 Each input key receives two values in this vector: first the ASCII code,
 and then the scan code.  */)
-     ()
+  (void)
 {
   Lisp_Object val, *keys = XVECTOR (recent_doskeys)->contents;
 
@@ -3114,23 +2431,21 @@ and then the scan code.  */)
   else
     {
       val = Fvector (NUM_RECENT_DOSKEYS, keys);
-      bcopy (keys + recent_doskeys_index,
-            XVECTOR (val)->contents,
-            (NUM_RECENT_DOSKEYS - recent_doskeys_index) * sizeof (Lisp_Object));
-      bcopy (keys,
-            XVECTOR (val)->contents + NUM_RECENT_DOSKEYS - recent_doskeys_index,
-            recent_doskeys_index * sizeof (Lisp_Object));
+      memcpy (XVECTOR (val)->contents, keys + recent_doskeys_index,
+             (NUM_RECENT_DOSKEYS - recent_doskeys_index) * sizeof (Lisp_Object));
+      memcpy (XVECTOR (val)->contents + NUM_RECENT_DOSKEYS - recent_doskeys_index,
+             keys, recent_doskeys_index * sizeof (Lisp_Object));
       return val;
     }
 }
 
 /* Get a char from keyboard.  Function keys are put into the event queue.  */
 static int
-dos_rawgetc ()
+dos_rawgetc (void)
 {
   struct input_event event;
   union REGS regs;
-  struct display_info *dpyinfo = FRAME_X_DISPLAY_INFO (SELECTED_FRAME());
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (SELECTED_FRAME());
   EVENT_INIT (event);
 
 #ifndef HAVE_X_WINDOWS
@@ -3337,14 +2652,13 @@ dos_rawgetc ()
          break;
        }
 
-    make_event:
       if (code == 0)
        continue;
 
-      if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+      if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
        {
-         clear_mouse_face (dpyinfo);
-         dpyinfo->mouse_face_hidden = 1;
+         clear_mouse_face (hlinfo);
+         hlinfo->mouse_face_hidden = 1;
        }
 
       if (code >= 0x100)
@@ -3372,10 +2686,10 @@ dos_rawgetc ()
          might need to update mouse highlight.  */
       if (mouse_last_x != mouse_prev_x || mouse_last_y != mouse_prev_y)
        {
-         if (dpyinfo->mouse_face_hidden)
+         if (hlinfo->mouse_face_hidden)
            {
-             dpyinfo->mouse_face_hidden = 0;
-             clear_mouse_face (dpyinfo);
+             hlinfo->mouse_face_hidden = 0;
+             clear_mouse_face (hlinfo);
            }
 
          /* Generate SELECT_WINDOW_EVENTs when needed.  */
@@ -3384,7 +2698,7 @@ dos_rawgetc ()
              mouse_window = window_from_coordinates (SELECTED_FRAME(),
                                                      mouse_last_x,
                                                      mouse_last_y,
-                                                     0, 0, 0, 0);
+                                                     0, 0);
              /* A window will be selected only when it is not
                 selected now, and the last mouse movement event was
                 not in it.  A minibuffer window will be selected iff
@@ -3407,22 +2721,12 @@ dos_rawgetc ()
          previous_help_echo_string = help_echo_string;
          help_echo_string = help_echo_object = help_echo_window = Qnil;
          help_echo_pos = -1;
-         IT_note_mouse_highlight (SELECTED_FRAME(),
-                                  mouse_last_x, mouse_last_y);
+         note_mouse_highlight (SELECTED_FRAME(), mouse_last_x, mouse_last_y);
          /* If the contents of the global variable help_echo has
             changed, generate a HELP_EVENT.  */
          if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
-           {
-             event.kind = HELP_EVENT;
-             event.frame_or_window = selected_frame;
-             event.arg = help_echo_object;
-             event.x = WINDOWP (help_echo_window)
-               ? help_echo_window : selected_frame;
-             event.y = help_echo_string;
-             event.timestamp = event_timestamp ();
-             event.code = help_echo_pos;
-             kbd_buffer_store_event (&event);
-           }
+           gen_help_event (help_echo_string, selected_frame, help_echo_window,
+                           help_echo_object, help_echo_pos);
        }
 
       for (but = 0; but < NUM_MOUSE_BUTTONS; but++)
@@ -3445,14 +2749,14 @@ dos_rawgetc ()
                    /* If only one button is pressed, wait 100 msec and
                       check again.  This way, Speedy Gonzales isn't
                       punished, while the slow get their chance.  */
-                   if (press && mouse_pressed (1-but, &x2, &y2)
-                       || !press && mouse_released (1-but, &x2, &y2))
+                   if ((press && mouse_pressed (1-but, &x2, &y2))
+                       || (!press && mouse_released (1-but, &x2, &y2)))
                      button_num = 2;
                    else
                      {
                        delay (100);
-                       if (press && mouse_pressed (1-but, &x2, &y2)
-                           || !press && mouse_released (1-but, &x2, &y2))
+                       if ((press && mouse_pressed (1-but, &x2, &y2))
+                           || (!press && mouse_released (1-but, &x2, &y2)))
                          button_num = 2;
                      }
                  }
@@ -3477,8 +2781,8 @@ dos_rawgetc ()
 static int prev_get_char = -1;
 
 /* Return 1 if a key is ready to be read without suspending execution.  */
-
-dos_keysns ()
+int
+dos_keysns (void)
 {
   if (prev_get_char != -1)
     return 1;
@@ -3487,8 +2791,8 @@ dos_keysns ()
 }
 
 /* Read a key.  Return -1 if no key is ready.  */
-
-dos_keyread ()
+int
+dos_keyread (void)
 {
   if (prev_get_char != -1)
     {
@@ -3517,7 +2821,7 @@ static char *menu_help_message, *prev_menu_help_message;
 static int menu_help_paneno, menu_help_itemno;
 
 static XMenu *
-IT_menu_create ()
+IT_menu_create (void)
 {
   XMenu *menu;
 
@@ -3597,18 +2901,29 @@ IT_menu_calc_size (XMenu *menu, int *width, int *height)
 
 /* Display MENU at (X,Y) using FACES.  */
 
+#define BUILD_CHAR_GLYPH(GLYPH, CODE, FACE_ID, PADDING_P)  \
+  do                                                      \
+    {                                                     \
+      (GLYPH).type = CHAR_GLYPH;                          \
+      SET_CHAR_GLYPH ((GLYPH), CODE, FACE_ID, PADDING_P);  \
+      (GLYPH).charpos = -1;                               \
+    }                                                     \
+  while (0)
+
 static void
 IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
 {
   int i, j, face, width,  mx, my, enabled, mousehere, row, col;
   struct glyph *text, *p;
-  char *q;
+  const unsigned char *q;
   struct frame *sf = SELECTED_FRAME();
 
   menu_help_message = NULL;
 
   width = menu->width;
-  text = (struct glyph *) xmalloc ((width + 2) * sizeof (struct glyph));
+  /* We multiply width by 2 to account for possible control characters.
+     FIXME: cater to non-ASCII characters in menus.  */
+  text = (struct glyph *) xmalloc ((width * 2 + 2) * sizeof (struct glyph));
   ScreenGetCursor (&row, &col);
   mouse_get_xy (&mx, &my);
   IT_update_begin (sf);
@@ -3616,10 +2931,10 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
     {
       int max_width = width + 2;
 
-      IT_cursor_to (y + i, x);
+      IT_cursor_to (sf, y + i, x);
       enabled
        = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]);
-      mousehere = (y + i == my && x <= mx && mx < x + width + 2);
+      mousehere = (y + i == my && x <= mx && mx < x + max_width);
       face = faces[enabled + mousehere * 2];
       /* The following if clause means that we display the menu help
         strings even if the menu item is currently disabled.  */
@@ -3630,21 +2945,23 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
          menu_help_itemno = i;
        }
       p = text;
-      SET_CHAR_GLYPH (*p, ' ', face, 0);
+      BUILD_CHAR_GLYPH (*p, ' ', face, 0);
       p++;
       for (j = 0, q = menu->text[i]; *q; j++)
        {
-         if (*q > 26)
+         unsigned c = STRING_CHAR_ADVANCE (q);
+
+         if (c > 26)
            {
-             SET_CHAR_GLYPH (*p, *q++, face, 0);
+             BUILD_CHAR_GLYPH (*p, c, face, 0);
              p++;
            }
          else  /* make '^x' */
            {
-             SET_CHAR_GLYPH (*p, '^', face, 0);
+             BUILD_CHAR_GLYPH (*p, '^', face, 0);
              p++;
              j++;
-             SET_CHAR_GLYPH (*p, *q++ + 64, face, 0);
+             BUILD_CHAR_GLYPH (*p, c + 64, face, 0);
              p++;
            }
        }
@@ -3655,14 +2972,16 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
          text[max_width - 1].u.ch = '$'; /* indicate it's truncated */
        }
       for (; j < max_width - 2; j++, p++)
-       SET_CHAR_GLYPH (*p, ' ', face, 0);
+       BUILD_CHAR_GLYPH (*p, ' ', face, 0);
 
-      SET_CHAR_GLYPH (*p, menu->submenu[i] ? 16 : ' ', face, 0);
+      /* 16 is the character code of a character that on DOS terminal
+        produces a nice-looking right-pointing arrow glyph.  */
+      BUILD_CHAR_GLYPH (*p, menu->submenu[i] ? 16 : ' ', face, 0);
       p++;
-      IT_write_glyphs (text, max_width);
+      IT_write_glyphs (sf, text, max_width);
     }
   IT_update_end (sf);
-  IT_cursor_to (row, col);
+  IT_cursor_to (sf, row, col);
   xfree (text);
 }
 \f
@@ -3671,7 +2990,7 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
 /* Report availability of menus.  */
 
 int
-have_menus_p () {  return 1; }
+have_menus_p (void) {  return 1; }
 
 /* Create a brand new menu structure.  */
 
@@ -3873,10 +3192,12 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
                if (0 <= dy && dy < state[i].menu->count)
                  {
                    if (!state[i].menu->submenu[dy])
-                     if (state[i].menu->panenumber[dy])
-                       result = XM_SUCCESS;
-                     else
-                       result = XM_IA_SELECT;
+                     {
+                       if (state[i].menu->panenumber[dy])
+                         result = XM_SUCCESS;
+                       else
+                         result = XM_IA_SELECT;
+                     }
                    *pane = state[i].pane - 1;
                    *selidx = dy;
                    /* We hit some part of a menu, so drop extra menus that
@@ -4029,8 +3350,7 @@ void msdos_downcase_filename (unsigned char *);
 /* Destructively turn backslashes into slashes.  */
 
 void
-dostounix_filename (p)
-     register char *p;
+dostounix_filename (char *p)
 {
   msdos_downcase_filename (p);
 
@@ -4045,8 +3365,7 @@ dostounix_filename (p)
 /* Destructively turn slashes into backslashes.  */
 
 void
-unixtodos_filename (p)
-     register char *p;
+unixtodos_filename (char *p)
 {
   if (p[1] == ':' && *p >= 'A' && *p <= 'Z')
     {
@@ -4065,9 +3384,7 @@ unixtodos_filename (p)
 /* Get the default directory for a given drive.  0=def, 1=A, 2=B, ...  */
 
 int
-getdefdir (drive, dst)
-     int drive;
-     char *dst;
+getdefdir (int drive, char *dst)
 {
   char in_path[4], *p = in_path, e = errno;
 
@@ -4106,9 +3423,7 @@ emacs_root_dir (void)
 /* Remove all CR's that are followed by a LF.  */
 
 int
-crlf_to_lf (n, buf)
-     register int n;
-     register unsigned char *buf;
+crlf_to_lf (int n, unsigned char *buf)
 {
   unsigned char *np = buf, *startp = buf, *endp = buf + n;
 
@@ -4129,199 +3444,10 @@ crlf_to_lf (n, buf)
   return np - startp;
 }
 
-#if defined(__DJGPP__) && __DJGPP__ == 2 && __DJGPP_MINOR__ == 0
-
-/* In DJGPP v2.0, library `write' can call `malloc', which might
-   cause relocation of the buffer whose address we get in ADDR.
-   Here is a version of `write' that avoids calling `malloc',
-   to serve us until such time as the library is fixed.
-   Actually, what we define here is called `__write', because
-   `write' is a stub that just jmp's to `__write' (to be
-   POSIXLY-correct with respect to the global name-space).  */
-
-#include <io.h>                      /* for _write */
-#include <libc/dosio.h>       /* for __file_handle_modes[] */
-
-static char xbuf[64 * 1024];  /* DOS cannot write more in one chunk */
-
-#define XBUF_END (xbuf + sizeof (xbuf) - 1)
-
-int
-__write (int handle, const void *buffer, size_t count)
-{
-  if (count == 0)
-    return 0;
-
-  if(__file_handle_modes[handle] & O_BINARY)
-    return _write (handle, buffer, count);
-  else
-    {
-      char *xbp = xbuf;
-      const char *bp = buffer;
-      int total_written = 0;
-      int nmoved = 0, ncr = 0;
-
-      while (count)
-       {
-         /* The next test makes sure there's space for at least 2 more
-            characters in xbuf[], so both CR and LF can be put there.  */
-         if (xbp < XBUF_END)
-           {
-             if (*bp == '\n')
-               {
-                 ncr++;
-                 *xbp++ = '\r';
-               }
-             *xbp++ = *bp++;
-             nmoved++;
-             count--;
-           }
-         if (xbp >= XBUF_END || !count)
-           {
-             size_t to_write = nmoved + ncr;
-             int written = _write (handle, xbuf, to_write);
-
-             if (written == -1)
-               return -1;
-             else
-               total_written += nmoved;  /* CRs aren't counted in ret value */
-
-             /* If some, but not all were written (disk full?), return
-                an estimate of the total written bytes not counting CRs.  */
-             if (written < to_write)
-               return total_written - (to_write - written) * nmoved/to_write;
-
-             nmoved = 0;
-             ncr = 0;
-             xbp = xbuf;
-           }
-       }
-      return total_written;
-    }
-}
-
-/* A low-level file-renaming function which works around Windows 95 bug.
-   This is pulled directly out of DJGPP v2.01 library sources, and only
-   used when you compile with DJGPP v2.0.  */
-
-#include <io.h>
-
-int _rename(const char *old, const char *new)
-{
-  __dpmi_regs r;
-  int olen    = strlen(old) + 1;
-  int i;
-  int use_lfn = _USE_LFN;
-  char tempfile[FILENAME_MAX];
-  const char *orig = old;
-  int lfn_fd = -1;
-
-  r.x.dx = __tb_offset;
-  r.x.di = __tb_offset + olen;
-  r.x.ds = r.x.es = __tb_segment;
-
-  if (use_lfn)
-    {
-      /* Windows 95 bug: for some filenames, when you rename
-        file -> file~ (as in Emacs, to leave a backup), the
-        short 8+3 alias doesn't change, which effectively
-        makes OLD and NEW the same file.  We must rename
-        through a temporary file to work around this.  */
-
-      char *pbase = 0, *p;
-      static char try_char[] = "abcdefghijklmnopqrstuvwxyz012345789";
-      int idx = sizeof(try_char) - 1;
-
-      /* Generate a temporary name.  Can't use `tmpnam', since $TMPDIR
-        might point to another drive, which will fail the DOS call.  */
-      strcpy(tempfile, old);
-      for (p = tempfile; *p; p++) /* ensure temporary is on the same drive */
-       if (*p == '/' || *p == '\\' || *p == ':')
-         pbase = p;
-      if (pbase)
-       pbase++;
-      else
-       pbase = tempfile;
-      strcpy(pbase, "X$$djren$$.$$temp$$");
-
-      do
-       {
-         if (idx <= 0)
-           return -1;
-         *pbase = try_char[--idx];
-       } while (_chmod(tempfile, 0) != -1);
-
-      r.x.ax = 0x7156;
-      _put_path2(tempfile, olen);
-      _put_path(old);
-      __dpmi_int(0x21, &r);
-      if (r.x.flags & 1)
-       {
-         errno = __doserr_to_errno(r.x.ax);
-         return -1;
-       }
-
-      /* Now create a file with the original name.  This will
-        ensure that NEW will always have a 8+3 alias
-        different from that of OLD.  (Seems to be required
-        when NameNumericTail in the Registry is set to 0.)  */
-      lfn_fd = _creat(old, 0);
-
-      olen = strlen(tempfile) + 1;
-      old  = tempfile;
-      r.x.di = __tb_offset + olen;
-    }
-
-  for (i=0; i<2; i++)
-    {
-      if(use_lfn)
-       r.x.ax = 0x7156;
-      else
-       r.h.ah = 0x56;
-      _put_path2(new, olen);
-      _put_path(old);
-      __dpmi_int(0x21, &r);
-      if(r.x.flags & 1)
-       {
-         if (r.x.ax == 5 && i == 0) /* access denied */
-           remove(new);                 /* and try again */
-         else
-           {
-             errno = __doserr_to_errno(r.x.ax);
-
-             /* Restore to original name if we renamed it to temporary.  */
-             if (use_lfn)
-               {
-                 if (lfn_fd != -1)
-                   {
-                     _close (lfn_fd);
-                     remove (orig);
-                   }
-                 _put_path2(orig, olen);
-                 _put_path(tempfile);
-                 r.x.ax = 0x7156;
-                 __dpmi_int(0x21, &r);
-               }
-             return -1;
-           }
-       }
-      else
-       break;
-    }
-
-  /* Success.  Delete the file possibly created to work
-     around the Windows 95 bug.  */
-  if (lfn_fd != -1)
-    return (_close (lfn_fd) == 0) ? remove (orig) : -1;
-  return 0;
-}
-
-#endif /* __DJGPP__ == 2 && __DJGPP_MINOR__ == 0 */
-
 DEFUN ("msdos-long-file-names", Fmsdos_long_file_names, Smsdos_long_file_names,
        0, 0, 0,
-       doc: /* Return non-nil if long file names are supported on MSDOS.  */)
-     ()
+       doc: /* Return non-nil if long file names are supported on MS-DOS.  */)
+  (void)
 {
   return (_USE_LFN ? Qt : Qnil);
 }
@@ -4329,8 +3455,7 @@ DEFUN ("msdos-long-file-names", Fmsdos_long_file_names, Smsdos_long_file_names,
 /* Convert alphabetic characters in a filename to lower-case.  */
 
 void
-msdos_downcase_filename (p)
-     register unsigned char *p;
+msdos_downcase_filename (unsigned char *p)
 {
   /* Always lower-case drive letters a-z, even if the filesystem
      preserves case in filenames.
@@ -4356,8 +3481,7 @@ DEFUN ("msdos-downcase-filename", Fmsdos_downcase_filename, Smsdos_downcase_file
 When long filenames are supported, doesn't change FILENAME.
 If FILENAME is not a string, returns nil.
 The argument object is never altered--the value is a copy.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   Lisp_Object tem;
 
@@ -4374,8 +3498,7 @@ The argument object is never altered--the value is a copy.  */)
 static char emacsroot[MAXPATHLEN];
 
 char *
-rootrelativepath (rel)
-     char *rel;
+rootrelativepath (char *rel)
 {
   static char result[MAXPATHLEN + 10];
 
@@ -4390,10 +3513,7 @@ rootrelativepath (rel)
    break if one or more of these are missing.  */
 
 void
-init_environment (argc, argv, skip_args)
-     int argc;
-     char **argv;
-     int skip_args;
+init_environment (int argc, char **argv, int skip_args)
 {
   char *s, *t, *root;
   int len, i;
@@ -4563,53 +3683,22 @@ init_environment (argc, argv, skip_args)
 static int break_stat;  /* BREAK check mode status.    */
 static int stdin_stat;  /* stdin IOCTL status.         */
 
-#if __DJGPP__ < 2
-
-/* These must be global.  */
-static _go32_dpmi_seginfo ctrl_break_vector;
-static _go32_dpmi_registers ctrl_break_regs;
-static int ctrlbreakinstalled = 0;
-
-/* Interrupt level detection of Ctrl-Break.  Don't do anything fancy here!  */
-
-void
-ctrl_break_func (regs)
-     _go32_dpmi_registers *regs;
-{
-  Vquit_flag = Qt;
-}
-
-void
-install_ctrl_break_check ()
-{
-  if (!ctrlbreakinstalled)
-    {
-      /* Don't press Ctrl-Break if you don't have either DPMI or Emacs
-        was compiler with Djgpp 1.11 maintenance level 5 or later!  */
-      ctrlbreakinstalled = 1;
-      ctrl_break_vector.pm_offset = (int) ctrl_break_func;
-      _go32_dpmi_allocate_real_mode_callback_iret (&ctrl_break_vector,
-                                                  &ctrl_break_regs);
-      _go32_dpmi_set_real_mode_interrupt_vector (0x1b, &ctrl_break_vector);
-    }
-}
-
-#endif /* __DJGPP__ < 2 */
-
 /* Turn off Dos' Ctrl-C checking and inhibit interpretation of
    control chars by DOS.   Determine the keyboard type.  */
 
 int
-dos_ttraw ()
+dos_ttraw (struct tty_display_info *tty)
 {
   union REGS inregs, outregs;
   static int first_time = 1;
 
+  /* If we are called for the initial terminal, it's too early to do
+     anything, and termscript isn't set up.  */
+  if (tty->terminal->type == output_initial)
+    return 2;
+
   break_stat = getcbrk ();
   setcbrk (0);
-#if __DJGPP__ < 2
-  install_ctrl_break_check ();
-#endif
 
   if (first_time)
     {
@@ -4619,7 +3708,7 @@ dos_ttraw ()
 
       have_mouse = 0;
 
-      if (internal_terminal
+      if (1
 #ifdef HAVE_X_WINDOWS
          && inhibit_window_system
 #endif
@@ -4637,67 +3726,34 @@ dos_ttraw ()
              int86 (0x33, &inregs, &outregs);
              have_mouse = (outregs.x.ax & 0xffff) == 0xffff;
            }
-
          if (have_mouse)
-           {
-             have_mouse = 1;   /* enable mouse */
-             mouse_visible = 0;
-             mouse_setup_buttons (outregs.x.bx);
-             mouse_position_hook = &mouse_get_pos;
-             mouse_init ();
-           }
+           mouse_button_count = outregs.x.bx;
 
 #ifndef HAVE_X_WINDOWS
-#if __DJGPP__ >= 2
          /* Save the cursor shape used outside Emacs.  */
          outside_cursor = _farpeekw (_dos_ds, 0x460);
-#endif
 #endif
        }
 
       first_time = 0;
 
-#if __DJGPP__ >= 2
-
       stdin_stat = setmode (fileno (stdin), O_BINARY);
       return (stdin_stat != -1);
     }
   else
     return (setmode (fileno (stdin), O_BINARY) != -1);
-
-#else /* __DJGPP__ < 2 */
-
-    }
-
-  /* I think it is wrong to overwrite `stdin_stat' every time
-     but the first one this function is called, but I don't
-     want to change the way it used to work in v1.x.--EZ  */
-
-  inregs.x.ax = 0x4400;                /* Get IOCTL status. */
-  inregs.x.bx = 0x00;          /* 0 = stdin. */
-  intdos (&inregs, &outregs);
-  stdin_stat = outregs.h.dl;
-
-  inregs.x.dx = stdin_stat | 0x0020; /* raw mode */
-  inregs.x.ax = 0x4401;                /* Set IOCTL status */
-  intdos (&inregs, &outregs);
-  return !outregs.x.cflag;
-
-#endif /* __DJGPP__ < 2 */
 }
 
 /*  Restore status of standard input and Ctrl-C checking.  */
 
 int
-dos_ttcooked ()
+dos_ttcooked (void)
 {
   union REGS inregs, outregs;
 
   setcbrk (break_stat);
   mouse_off ();
 
-#if __DJGPP__ >= 2
-
 #ifndef HAVE_X_WINDOWS
   /* Restore the cursor shape we found on startup.  */
   if (outside_cursor)
@@ -4709,16 +3765,6 @@ dos_ttcooked ()
 #endif
 
   return (setmode (fileno (stdin), stdin_stat) != -1);
-
-#else  /* not __DJGPP__ >= 2 */
-
-  inregs.x.ax = 0x4401;        /* Set IOCTL status.    */
-  inregs.x.bx = 0x00;  /* 0 = stdin.           */
-  inregs.x.dx = stdin_stat;
-  intdos (&inregs, &outregs);
-  return !outregs.x.cflag;
-
-#endif /* not __DJGPP__ >= 2 */
 }
 
 \f
@@ -4727,11 +3773,8 @@ dos_ttcooked ()
    file TEMPOUT and stderr to TEMPERR.  */
 
 int
-run_msdos_command (argv, working_dir, tempin, tempout, temperr, envv)
-     unsigned char **argv;
-     const char *working_dir;
-     int tempin, tempout, temperr;
-     char **envv;
+run_msdos_command (unsigned char **argv, const char *working_dir,
+                  int tempin, int tempout, int temperr, char **envv)
 {
   char *saveargv1, *saveargv2, *lowcase_argv0, *pa, *pl;
   char oldwd[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS.  */
@@ -4791,14 +3834,13 @@ run_msdos_command (argv, working_dir, tempin, tempout, temperr, envv)
   if (have_mouse > 0)
     mouse_get_xy (&x, &y);
 
-  dos_ttcooked ();     /* do it here while 0 = stdin */
+  if (!noninteractive)
+    dos_ttcooked ();   /* do it here while 0 = stdin */
 
   dup2 (tempin, 0);
   dup2 (tempout, 1);
   dup2 (temperr, 2);
 
-#if __DJGPP__ > 1
-
   if (msshell && !argv[3])
     {
       /* MS-DOS native shells are too restrictive.  For starters, they
@@ -4839,10 +3881,7 @@ run_msdos_command (argv, working_dir, tempin, tempout, temperr, envv)
        result = 0;     /* emulate Unixy shell behavior with empty cmd line */
     }
   else
-
-#endif /* __DJGPP__ > 1 */
-
-  result = spawnve (P_WAIT, argv[0], argv, envv);
+    result = spawnve (P_WAIT, argv[0], (char **)argv, envv);
 
   dup2 (inbak, 0);
   dup2 (outbak, 1);
@@ -4851,7 +3890,8 @@ run_msdos_command (argv, working_dir, tempin, tempout, temperr, envv)
   emacs_close (outbak);
   emacs_close (errbak);
 
-  dos_ttraw ();
+  if (!noninteractive)
+    dos_ttraw (CURTTY ());
   if (have_mouse > 0)
     {
       mouse_init ();
@@ -4861,7 +3901,8 @@ run_msdos_command (argv, working_dir, tempin, tempout, temperr, envv)
   /* Some programs might change the meaning of the highest bit of the
      text attribute byte, so we get blinking characters instead of the
      bright background colors.  Restore that.  */
-  bright_bg ();
+  if (!noninteractive)
+    bright_bg ();
 
  done:
   chdir (oldwd);
@@ -4874,100 +3915,20 @@ run_msdos_command (argv, working_dir, tempin, tempout, temperr, envv)
 }
 
 void
-croak (badfunc)
-     char *badfunc;
+croak (char *badfunc)
 {
   fprintf (stderr, "%s not yet implemented\r\n", badfunc);
   reset_all_sys_modes ();
   exit (1);
 }
 \f
-#if __DJGPP__ < 2
-
-/* ------------------------- Compatibility functions -------------------
- *     gethostname
- *     gettimeofday
- */
-
-/* Hostnames for a pc are not really funny,
-   but they are used in change log so we emulate the best we can.  */
-
-gethostname (p, size)
-     char *p;
-     int size;
-{
-  char *q = egetenv ("HOSTNAME");
-
-  if (!q) q = "pc";
-  strcpy (p, q);
-  return 0;
-}
-
-/* When time zones are set from Ms-Dos too many C-libraries are playing
-   tricks with time values.  We solve this by defining our own version
-   of `gettimeofday' bypassing GO32.  Our version needs to be initialized
-   once and after each call to `tzset' with TZ changed.  That is
-   accomplished by aliasing tzset to init_gettimeofday. */
-
-static struct tm time_rec;
-
-int
-gettimeofday (struct timeval *tp, struct timezone *tzp)
-{
-  if (tp)
-    {
-      struct time t;
-      struct tm tm;
-
-      gettime (&t);
-      if (t.ti_hour < time_rec.tm_hour) /* midnight wrap */
-       {
-         struct date d;
-         getdate (&d);
-         time_rec.tm_year = d.da_year - 1900;
-         time_rec.tm_mon = d.da_mon - 1;
-         time_rec.tm_mday = d.da_day;
-       }
-
-      time_rec.tm_hour = t.ti_hour;
-      time_rec.tm_min = t.ti_min;
-      time_rec.tm_sec = t.ti_sec;
-
-      tm = time_rec;
-      tm.tm_gmtoff = dos_timezone_offset;
-
-      tp->tv_sec = mktime (&tm);       /* may modify tm */
-      tp->tv_usec = t.ti_hund * (1000000 / 100);
-    }
-  /* Ignore tzp; it's obsolescent.  */
-  return 0;
-}
-
-#endif /* __DJGPP__ < 2 */
-
 /*
- * A list of unimplemented functions that we silently ignore.
+ * A few unimplemented functions that we silently ignore.
  */
-
-#if __DJGPP__ < 2
-unsigned alarm (s) unsigned s; {}
-fork () { return 0; }
-int kill (x, y) int x, y; { return -1; }
-nice (p) int p; {}
-void volatile pause () {}
-sigsetmask (x) int x; { return 0; }
-sigblock (mask) int mask; { return 0; }
-#endif
-
-void request_sigio (void) {}
-setpgrp () {return 0; }
-setpriority (x,y,z) int x,y,z; { return 0; }
-void unrequest_sigio (void) {}
-
-#if __DJGPP__ > 1
-#if __DJGPP_MINOR__ < 2
-
-#ifdef POSIX_SIGNALS
+int setpgrp (void) {return 0; }
+int setpriority (int x, int y, int z) { return 0; }
+\f
+#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2
 
 /* Augment DJGPP library POSIX signal functions.  This is needed
    as of DJGPP v2.01, but might be in the library in later releases. */
@@ -4981,7 +3942,7 @@ static int sigprocmask_count = -1;
 static sigset_t current_mask;
 
 /* Which signals are pending (initially none).  */
-static sigset_t pending_signals;
+static sigset_t msdos_pending_signals;
 
 /* Previous handlers to restore when the blocked signals are unblocked.  */
 typedef void (*sighandler_t)(int);
@@ -4990,17 +3951,13 @@ static sighandler_t prev_handlers[320];
 /* A signal handler which just records that a signal occurred
    (it will be raised later, if and when the signal is unblocked).  */
 static void
-sig_suspender (signo)
-     int signo;
+sig_suspender (int signo)
 {
-  sigaddset (&pending_signals, signo);
+  sigaddset (&msdos_pending_signals, signo);
 }
 
 int
-sigprocmask (how, new_set, old_set)
-     int how;
-     const sigset_t *new_set;
-     sigset_t *old_set;
+sigprocmask (int how, const sigset_t *new_set, sigset_t *old_set)
 {
   int signo;
   sigset_t new_mask;
@@ -5009,7 +3966,7 @@ sigprocmask (how, new_set, old_set)
   if (sigprocmask_count != __bss_count)
     {
       sigprocmask_count = __bss_count;
-      sigemptyset (&pending_signals);
+      sigemptyset (&msdos_pending_signals);
       sigemptyset (&current_mask);
       for (signo = 0; signo < 320; signo++)
        prev_handlers[signo] = SIG_ERR;
@@ -5055,9 +4012,9 @@ sigprocmask (how, new_set, old_set)
              signal (signo, prev_handlers[signo]);
              prev_handlers[signo] = SIG_ERR;
            }
-         if (sigismember (&pending_signals, signo))
+         if (sigismember (&msdos_pending_signals, signo))
            {
-             sigdelset (&pending_signals, signo);
+             sigdelset (&msdos_pending_signals, signo);
              raise (signo);
            }
        }
@@ -5066,14 +4023,7 @@ sigprocmask (how, new_set, old_set)
   return 0;
 }
 
-#else /* not POSIX_SIGNALS */
-
-sigsetmask (x) int x; { return 0; }
-sigblock (mask) int mask; { return 0; }
-
-#endif /* not POSIX_SIGNALS */
 #endif /* not __DJGPP_MINOR__ < 2 */
-#endif /* __DJGPP__ > 1 */
 
 #ifndef HAVE_SELECT
 #include "sysselect.h"
@@ -5109,10 +4059,8 @@ dos_yield_time_slice (void)
 /* We don't have to call timer_check here
    because wait_reading_process_output takes care of that.  */
 int
-sys_select (nfds, rfds, wfds, efds, timeout)
-     int nfds;
-     SELECT_TYPE *rfds, *wfds, *efds;
-     EMACS_TIME *timeout;
+sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
+           EMACS_TIME *timeout)
 {
   int check_input;
   struct time t;
@@ -5182,11 +4130,10 @@ sys_select (nfds, rfds, wfds, efds, timeout)
 
 #ifdef chdir
 #undef chdir
-extern int chdir ();
+extern int chdir (const char *);
 
 int
-sys_chdir (path)
-     const char* path;
+sys_chdir (const char *path)
 {
   int len = strlen (path);
   char *tmp = (char *)path;
@@ -5215,7 +4162,7 @@ sys_chdir (path)
 extern void tzset (void);
 
 void
-init_gettimeofday ()
+init_gettimeofday (void)
 {
   time_t ltm, gtm;
   struct tm *lstm;
@@ -5233,9 +4180,7 @@ init_gettimeofday ()
 #ifdef abort
 #undef abort
 void
-dos_abort (file, line)
-     char *file;
-     int  line;
+dos_abort (char *file, int line)
 {
   char buffer1[200], buffer2[400];
   int i, j;
@@ -5251,12 +4196,11 @@ dos_abort (file, line)
 }
 #else
 void
-abort ()
+abort (void)
 {
   dos_ttcooked ();
   ScreenSetCursor (10, 0);
   cputs ("\r\n\nEmacs aborted!\r\n");
-#if __DJGPP__ > 1
 #if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2
   if (screen_virtual_segment)
     dosv_refresh_virtual_screen (2 * 10 * screen_size_X, 4 * screen_size_X);
@@ -5266,19 +4210,12 @@ abort ()
 #else  /* __DJGPP_MINOR__ >= 2 */
   raise (SIGABRT);
 #endif /* __DJGPP_MINOR__ >= 2 */
-#endif
   exit (2);
 }
 #endif
 
-/* The following variables are required so that cus-start.el won't
-   complain about unbound variables.  */
-#ifndef subprocesses
-/* Nonzero means delete a process right away if it exits (process.c).  */
-static int delete_exited_processes;
-#endif
-
-syms_of_msdos ()
+void
+syms_of_msdos (void)
 {
   recent_doskeys = Fmake_vector (make_number (NUM_RECENT_DOSKEYS), Qnil);
   staticpro (&recent_doskeys);
@@ -5286,20 +4223,14 @@ syms_of_msdos ()
 #ifndef HAVE_X_WINDOWS
 
   /* The following two are from xfns.c:  */
-  Qreverse = intern ("reverse");
+  Qreverse = intern_c_string ("reverse");
   staticpro (&Qreverse);
 
   DEFVAR_LISP ("dos-unsupported-char-glyph", &Vdos_unsupported_char_glyph,
               doc: /* *Glyph to display instead of chars not supported by current codepage.
-This variable is used only by MSDOS terminals.  */);
+This variable is used only by MS-DOS terminals.  */);
   Vdos_unsupported_char_glyph = make_number ('\177');
 
-#endif
-#ifndef subprocesses
-  DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
-              doc: /* *Non-nil means delete processes immediately when they exit.
-A value of nil means don't delete them until `list-processes' is run.  */);
-  delete_exited_processes = 0;
 #endif
 
   defsubr (&Srecent_doskeys);