msdos.c (dos_rawgetc): Use gen_help_event, instead of doing the same in-line.
[bpt/emacs.git] / src / msdos.c
index 086cad2..0f9a2ff 100644 (file)
@@ -29,13 +29,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #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 memset and string functions */
 #include <sys/stat.h>    /* for _fixpath */
 #include <unistd.h>     /* for chdir, dup, dup2, etc. */
 #include <dir.h>        /* for getdisk */
@@ -586,14 +584,14 @@ dos_set_window_size (int *rows, int *cols)
   if (current_rows != *rows || current_cols != *cols)
     {
       struct frame *f = SELECTED_FRAME();
-      struct tty_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;
        }
     }
 
@@ -943,551 +941,79 @@ 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 tty_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;
   struct tty_display_info *tty = FRAME_TTY (f);
+  Mouse_HLInfo *hlinfo = &tty->mouse_highlight;
 
-
-  /* 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 (tty->termscript)
-           fprintf (tty->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 (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;
-       }
-    }
-
- set_cursor_shape:
-  /* Change the mouse pointer shape.  */
-  IT_set_mouse_pointer (hl);
-}
-
-/* Clear out the mouse-highlighted active region.
-   Redraw it un-highlighted first.  */
-static void
-clear_mouse_face (struct tty_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 (row->used[TEXT_AREA])
-       line_start_position = row->glyphs[TEXT_AREA]->charpos;
-      else
-       line_start_position = 0;
-
-      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;
-
-      /* 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++)
+  if (hl == DRAW_MOUSE_FACE)
     {
-      struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
-      int charpos;
+      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;
 
-      charpos = glyph->charpos;
-      if (charpos == pos)
-       {
-         *hpos = i;
-         *vpos = row->y;
-         return 1;
-       }
-      else if (charpos > pos)
-       break;
-      else if (charpos > 0)
-       lastcol = i;
-    }
-
-  /* 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)
-    {
-      ++row;
-      lastcol = 0;
-    }
-
-  *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 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 (tty->termscript)
+       fprintf (tty->termscript, "\n<MH+ %d-%d:%d>",
+                kstart, kstart + nglyphs - 1, vpos);
 
-  if (row->enabled_p)
-    {
-      struct glyph *glyph, *end;
-      Lisp_Object help;
-
-      /* 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))
+      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--)
        {
-         /* 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;
-           }
+         _farnspokeb (offset, ScreenAttrib);
+         offset += 2;
        }
+      if (screen_virtual_segment)
+       dosv_refresh_virtual_screen (start_offset, end_hpos - start_hpos);
+      mouse_on ();
     }
-}
-
-/* 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 tty_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))))
+  else if (hl == DRAW_NORMAL_TEXT)
     {
-      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;
-               }
-           }
-       }
+      /* 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);
 
-      /* 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.  */
-      {
-       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,
-                                            -1);
-
-               /* 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,
-                                            -1);
-
-               /* Display it as active.  */
-               show_mouse_face (dpyinfo, 1);
-             }
-         }
-
-       /* Look for a `help-echo' property.  */
-       {
-         Lisp_Object help;
-
-         /* 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;
-      }
+      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;
     }
 }
 
@@ -1691,7 +1217,8 @@ static void
 IT_update_begin (struct frame *f)
 {
   struct tty_display_info *display_info = FRAME_X_DISPLAY_INFO (f);
-  struct frame *mouse_face_frame = display_info->mouse_face_mouse_frame;
+  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");
@@ -1701,28 +1228,28 @@ IT_update_begin (struct frame *f)
   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)
@@ -1732,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;
@@ -1756,25 +1283,25 @@ IT_update_end (struct frame *f)
 
   if (dpyinfo->termscript)
     fprintf (dpyinfo->termscript, "\n<UPDATE_END\n");
-  dpyinfo->mouse_face_defer = 0;
+  dpyinfo->mouse_highlight.mouse_face_defer = 0;
 }
 
 static void
 IT_frame_up_to_date (struct frame *f)
 {
-  struct tty_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;
     }
 
@@ -2319,18 +1846,18 @@ internal_terminal_init (void)
          if (colors[1] >= 0 && colors[1] < 16)
            FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1];
        }
-      the_only_display_info.mouse_face_mouse_frame = NULL;
-      the_only_display_info.mouse_face_deferred_gc = 0;
-      the_only_display_info.mouse_face_beg_row =
-       the_only_display_info.mouse_face_beg_col = -1;
-      the_only_display_info.mouse_face_end_row =
-       the_only_display_info.mouse_face_end_col = -1;
-      the_only_display_info.mouse_face_face_id = DEFAULT_FACE_ID;
-      the_only_display_info.mouse_face_window = Qnil;
-      the_only_display_info.mouse_face_mouse_x =
-       the_only_display_info.mouse_face_mouse_y = 0;
-      the_only_display_info.mouse_face_defer = 0;
-      the_only_display_info.mouse_face_hidden = 0;
+      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 */
        {
@@ -2918,7 +2445,7 @@ dos_rawgetc (void)
 {
   struct input_event event;
   union REGS regs;
-  struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (SELECTED_FRAME());
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (SELECTED_FRAME());
   EVENT_INIT (event);
 
 #ifndef HAVE_X_WINDOWS
@@ -3128,10 +2655,10 @@ dos_rawgetc (void)
       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)
@@ -3159,10 +2686,10 @@ dos_rawgetc (void)
          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.  */
@@ -3171,7 +2698,7 @@ dos_rawgetc (void)
              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
@@ -3194,22 +2721,12 @@ dos_rawgetc (void)
          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++)
@@ -4706,7 +4223,7 @@ syms_of_msdos (void)
 #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,