Merge from emacs-23
[bpt/emacs.git] / src / xdisp.c
index ad90d57..1c22064 100644 (file)
@@ -214,11 +214,41 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    leftmost character with special glyphs, which will display as,
    well, empty.  On text terminals, these special glyphs are simply
    blank characters.  On graphics terminals, there's a single stretch
-   glyph with suitably computed width.  Both the blanks and the
+   glyph of a suitably computed width.  Both the blanks and the
    stretch glyph are given the face of the background of the line.
    This way, the terminal-specific back-end can still draw the glyphs
    left to right, even for R2L lines.
 
+   Bidirectional display and character compositions
+
+   Some scripts cannot be displayed by drawing each character
+   individually, because adjacent characters change each other's shape
+   on display.  For example, Arabic and Indic scripts belong to this
+   category.
+
+   Emacs display supports this by providing "character compositions",
+   most of which is implemented in composite.c.  During the buffer
+   scan that delivers characters to PRODUCE_GLYPHS, if the next
+   character to be delivered is a composed character, the iteration
+   calls composition_reseat_it and next_element_from_composition.  If
+   they succeed to compose the character with one or more of the
+   following characters, the whole sequence of characters that where
+   composed is recorded in the `struct composition_it' object that is
+   part of the buffer iterator.  The composed sequence could produce
+   one or more font glyphs (called "grapheme clusters") on the screen.
+   Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
+   in the direction corresponding to the current bidi scan direction
+   (recorded in the scan_dir member of the `struct bidi_it' object
+   that is part of the buffer iterator).  In particular, if the bidi
+   iterator currently scans the buffer backwards, the grapheme
+   clusters are delivered back to front.  This reorders the grapheme
+   clusters as appropriate for the current bidi context.  Note that
+   this means that the grapheme clusters are always stored in the
+   LGSTRING object (see composite.c) in the logical order.
+
+   Moving an iterator in bidirectional text
+   without producing glyphs
+
    Note one important detail mentioned above: that the bidi reordering
    engine, driven by the iterator, produces characters in R2L rows
    starting at the character that will be the rightmost on display.
@@ -888,6 +918,9 @@ static int clear_face_cache_count;
 #ifdef HAVE_WINDOW_SYSTEM
 #define CLEAR_IMAGE_CACHE_COUNT        101
 static int clear_image_cache_count;
+
+/* Null glyph slice */
+static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
 #endif
 
 /* Non-zero while redisplay_internal is in progress.  */
@@ -913,10 +946,6 @@ EMACS_INT help_echo_pos;
 
 Lisp_Object previous_help_echo_string;
 
-/* Null glyph slice */
-
-static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
-
 /* Platform-independent portion of hourglass implementation. */
 
 /* Non-zero means we're allowed to display a hourglass pointer.  */
@@ -942,7 +971,7 @@ Lisp_Object Vglyphless_char_display;
 Lisp_Object Qglyphless_char_display;
 
 /* Method symbols for Vglyphless_char_display.  */
-static Lisp_Object Qhexa_code, Qempty_box, Qthin_space, Qzero_width;
+static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
 
 /* Default pixel width of `thin-space' display method.  */
 #define THIN_SPACE_WIDTH 1
@@ -975,10 +1004,8 @@ static int text_outside_line_unchanged_p (struct window *,
                                          EMACS_INT, EMACS_INT);
 static void store_mode_line_noprop_char (char);
 static int store_mode_line_noprop (const unsigned char *, int, int);
-static void x_consider_frame_title (Lisp_Object);
 static void handle_stop (struct it *);
 static void handle_stop_backwards (struct it *, EMACS_INT);
-static int tool_bar_lines_needed (struct frame *, int *);
 static int single_display_spec_intangible_p (Lisp_Object);
 static void ensure_echo_area_buffers (void);
 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
@@ -1091,6 +1118,8 @@ static int in_ellipses_for_invisible_text_p (struct display_pos *,
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+static void x_consider_frame_title (Lisp_Object);
+static int tool_bar_lines_needed (struct frame *, int *);
 static void update_tool_bar (struct frame *, int);
 static void build_desired_tool_bar_string (struct frame *f);
 static int redisplay_tool_bar (struct frame *);
@@ -1100,12 +1129,13 @@ static void notice_overwritten_cursor (struct window *,
                                        int, int, int, int);
 static void append_stretch_glyph (struct it *, Lisp_Object,
                                   int, int, int);
-static int coords_in_mouse_face_p (struct window *, int, int);
-
 
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
+static int coords_in_mouse_face_p (struct window *, int, int);
+
+
 \f
 /***********************************************************************
                      Window display dimensions
@@ -1514,11 +1544,10 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
 }
 
 
-/* Return the next character from STR which is MAXLEN bytes long.
-   Return in *LEN the length of the character.  This is like
-   STRING_CHAR_AND_LENGTH but never returns an invalid character.  If
-   we find one, we return a `?', but with the length of the invalid
-   character.  */
+/* Return the next character from STR.  Return in *LEN the length of
+   the character.  This is like STRING_CHAR_AND_LENGTH but never
+   returns an invalid character.  If we find one, we return a `?', but
+   with the length of the invalid character.  */
 
 static INLINE int
 string_char_and_length (const unsigned char *str, int *len)
@@ -1547,15 +1576,13 @@ string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT ncha
 
   if (STRING_MULTIBYTE (string))
     {
-      EMACS_INT rest = SBYTES (string) - BYTEPOS (pos);
       const unsigned char *p = SDATA (string) + BYTEPOS (pos);
       int len;
 
       while (nchars--)
        {
          string_char_and_length (p, &len);
-         p += len, rest -= len;
-         xassert (rest >= 0);
+         p += len;
          CHARPOS (pos) += 1;
          BYTEPOS (pos) += len;
        }
@@ -1595,15 +1622,13 @@ c_string_pos (EMACS_INT charpos, const unsigned char *s, int multibyte_p)
 
   if (multibyte_p)
     {
-      EMACS_INT rest = strlen (s);
       int len;
 
       SET_TEXT_POS (pos, 0, 0);
       while (charpos--)
        {
          string_char_and_length (s, &len);
-         s += len, rest -= len;
-         xassert (rest >= 0);
+         s += len;
          CHARPOS (pos) += 1;
          BYTEPOS (pos) += len;
        }
@@ -1797,8 +1822,6 @@ glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
 }
 
 
-#ifdef HAVE_WINDOW_SYSTEM
-
 /* Find the glyph under window-relative coordinates X/Y in window W.
    Consider only glyphs from buffer text, i.e. no glyphs from overlay
    strings.  Return in *HPOS and *VPOS the row and column number of
@@ -1881,7 +1904,6 @@ x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
   return glyph;
 }
 
-
 /* EXPORT:
    Convert frame-relative x/y to coordinates relative to window W.
    Takes pseudo-windows into account.  */
@@ -1904,6 +1926,8 @@ frame_to_window_pixel_xy (struct window *w, int *x, int *y)
     }
 }
 
+#ifdef HAVE_WINDOW_SYSTEM
+
 /* EXPORT:
    Return in RECTS[] at most N clipping rectangles for glyph string S.
    Return the number of stored rectangles.  */
@@ -2189,7 +2213,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
      frame pixel coordinates X/Y on frame F.  */
 
   if (!f->glyphs_initialized_p
-      || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
+      || (window = window_from_coordinates (f, gx, gy, &part, 0),
          NILP (window)))
     {
       width = FRAME_SMALLEST_CHAR_WIDTH (f);
@@ -2201,6 +2225,9 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
   width = WINDOW_FRAME_COLUMN_WIDTH (w);
   height = WINDOW_FRAME_LINE_HEIGHT (w);
 
+  x = window_relative_x_coord (w, part, gx);
+  y = gy - WINDOW_TOP_EDGE_Y (w);
+
   r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
   end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
 
@@ -4791,6 +4818,7 @@ next_overlay_string (struct it *it)
                   && it->stop_charpos <= it->end_charpos));
       it->current.overlay_string_index = -1;
       it->n_overlay_strings = 0;
+      it->overlay_strings_charpos = -1;
 
       /* If we're at the end of the buffer, record that we have
         processed the overlay strings there already, so that
@@ -4803,11 +4831,13 @@ next_overlay_string (struct it *it)
       /* There are more overlay strings to process.  If
         IT->current.overlay_string_index has advanced to a position
         where we must load IT->overlay_strings with more strings, do
-        it.  */
+        it.  We must load at the IT->overlay_strings_charpos where
+        IT->n_overlay_strings was originally computed; when invisible
+        text is present, this might not be IT_CHARPOS (Bug#7016).  */
       int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
 
       if (it->current.overlay_string_index && i == 0)
-       load_overlay_strings (it, 0);
+       load_overlay_strings (it, it->overlay_strings_charpos);
 
       /* Initialize IT to deliver display elements from the overlay
          string.  */
@@ -5019,8 +5049,9 @@ load_overlay_strings (struct it *it, EMACS_INT charpos)
   if (n > 1)
     qsort (entries, n, sizeof *entries, compare_overlay_entries);
 
-  /* Record the total number of strings to process.  */
+  /* Record number of overlay strings, and where we computed it.  */
   it->n_overlay_strings = n;
+  it->overlay_strings_charpos = charpos;
 
   /* IT->current.overlay_string_index is the number of overlay strings
      that have already been consumed by IT.  Copy some of the
@@ -5784,8 +5815,8 @@ lookup_glyphless_char_display (int c, struct it *it)
     it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
   else if (EQ (glyphless_method, Qempty_box))
     it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
-  else if (EQ (glyphless_method, Qhexa_code))
-    it->glyphless_method = GLYPHLESS_DISPLAY_HEXA_CODE;
+  else if (EQ (glyphless_method, Qhex_code))
+    it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
   else if (STRINGP (glyphless_method))
     it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
   else
@@ -9352,6 +9383,8 @@ set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multiby
     Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
 
   current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
+  if (!NILP (current_buffer->bidi_display_reordering))
+    current_buffer->bidi_paragraph_direction = Qleft_to_right;
 
   /* Insert new message at BEG.  */
   TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
@@ -10818,7 +10851,7 @@ static int
 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
                   int *hpos, int *vpos, int *prop_idx)
 {
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   struct window *w = XWINDOW (f->tool_bar_window);
   int area;
 
@@ -10833,14 +10866,14 @@ get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
     return -1;
 
   /* Is mouse on the highlighted item?  */
-  if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
-      && *vpos >= dpyinfo->mouse_face_beg_row
-      && *vpos <= dpyinfo->mouse_face_end_row
-      && (*vpos > dpyinfo->mouse_face_beg_row
-         || *hpos >= dpyinfo->mouse_face_beg_col)
-      && (*vpos < dpyinfo->mouse_face_end_row
-         || *hpos < dpyinfo->mouse_face_end_col
-         || dpyinfo->mouse_face_past_end))
+  if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
+      && *vpos >= hlinfo->mouse_face_beg_row
+      && *vpos <= hlinfo->mouse_face_end_row
+      && (*vpos > hlinfo->mouse_face_beg_row
+         || *hpos >= hlinfo->mouse_face_beg_col)
+      && (*vpos < hlinfo->mouse_face_end_row
+         || *hpos < hlinfo->mouse_face_end_col
+         || hlinfo->mouse_face_past_end))
     return 0;
 
   return 1;
@@ -10857,7 +10890,7 @@ void
 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
                       unsigned int modifiers)
 {
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   struct window *w = XWINDOW (f->tool_bar_window);
   int hpos, vpos, prop_idx;
   struct glyph *glyph;
@@ -10876,8 +10909,8 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
   if (down_p)
     {
       /* Show item in pressed state.  */
-      show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
-      dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
+      show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
+      hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
       last_tool_bar_item = prop_idx;
     }
   else
@@ -10887,8 +10920,8 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
       EVENT_INIT (event);
 
       /* Show item in released state.  */
-      show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
-      dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
+      show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
+      hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
 
       key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
 
@@ -10918,6 +10951,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
   Lisp_Object window = f->tool_bar_window;
   struct window *w = XWINDOW (window);
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   int hpos, vpos;
   struct glyph *glyph;
   struct glyph_row *row;
@@ -10931,7 +10965,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
      values when mouse moves outside of the frame.  */
   if (x <= 0 || y <= 0)
     {
-      clear_mouse_face (dpyinfo);
+      clear_mouse_face (hlinfo);
       return;
     }
 
@@ -10939,14 +10973,14 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
   if (rc < 0)
     {
       /* Not on tool-bar item.  */
-      clear_mouse_face (dpyinfo);
+      clear_mouse_face (hlinfo);
       return;
     }
   else if (rc == 0)
     /* On same tool-bar item as before.  */
     goto set_help_echo;
 
-  clear_mouse_face (dpyinfo);
+  clear_mouse_face (hlinfo);
 
   /* Mouse is down, but on different tool-bar item?  */
   mouse_down_p = (dpyinfo->grabbed
@@ -10956,7 +10990,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
       && last_tool_bar_item != prop_idx)
     return;
 
-  dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
+  hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
   draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
 
   /* If tool-bar item is not enabled, don't highlight it.  */
@@ -10970,22 +11004,22 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
        x += row->glyphs[TEXT_AREA][i].pixel_width;
 
       /* Record this as the current active region.  */
-      dpyinfo->mouse_face_beg_col = hpos;
-      dpyinfo->mouse_face_beg_row = vpos;
-      dpyinfo->mouse_face_beg_x = x;
-      dpyinfo->mouse_face_beg_y = row->y;
-      dpyinfo->mouse_face_past_end = 0;
-
-      dpyinfo->mouse_face_end_col = hpos + 1;
-      dpyinfo->mouse_face_end_row = vpos;
-      dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
-      dpyinfo->mouse_face_end_y = row->y;
-      dpyinfo->mouse_face_window = window;
-      dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
+      hlinfo->mouse_face_beg_col = hpos;
+      hlinfo->mouse_face_beg_row = vpos;
+      hlinfo->mouse_face_beg_x = x;
+      hlinfo->mouse_face_beg_y = row->y;
+      hlinfo->mouse_face_past_end = 0;
+
+      hlinfo->mouse_face_end_col = hpos + 1;
+      hlinfo->mouse_face_end_row = vpos;
+      hlinfo->mouse_face_end_x = x + glyph->pixel_width;
+      hlinfo->mouse_face_end_y = row->y;
+      hlinfo->mouse_face_window = window;
+      hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
 
       /* Display it as active.  */
-      show_mouse_face (dpyinfo, draw);
-      dpyinfo->mouse_face_image_state = draw;
+      show_mouse_face (hlinfo, draw);
+      hlinfo->mouse_face_image_state = draw;
     }
 
  set_help_echo:
@@ -12806,6 +12840,15 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
        && BUFFERP (glyph->object) && glyph->charpos == pt_old)
       && bpos_covered < pt_old)
     {
+      /* An empty line has a single glyph whose OBJECT is zero and
+        whose CHARPOS is the position of a newline on that line.
+        Note that on a TTY, there are more glyphs after that, which
+        were produced by extend_face_to_end_of_line, but their
+        CHARPOS is zero or negative.  */
+      int empty_line_p =
+       (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
+       && INTEGERP (glyph->object) && glyph->charpos > 0;
+
       if (row->ends_in_ellipsis_p && pos_after == last_pos)
        {
          EMACS_INT ellipsis_pos;
@@ -12841,10 +12884,11 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
               || (row->truncated_on_left_p && pt_old < bpos_min)
               || (row->truncated_on_right_p && pt_old > bpos_max)
               /* Zero-width characters produce no glyphs.  */
-              || ((row->reversed_p
-                   ? glyph_after > glyphs_end
-                   : glyph_after < glyphs_end)
-                  && eabs (glyph_after - glyph_before) == 1))
+              || (!string_seen
+                  && !empty_line_p
+                  && (row->reversed_p
+                      ? glyph_after > glyphs_end
+                      : glyph_after < glyphs_end)))
        {
          cursor = glyph_after;
          x = -1;
@@ -12898,8 +12942,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                             cursor on that character's glyph.  */
                          EMACS_INT strpos = glyph->charpos;
 
-                         cursor = glyph;
-                         for (glyph += incr;
+                         if (tem)
+                           cursor = glyph;
+                         for ( ;
                               (row->reversed_p ? glyph > stop : glyph < stop)
                                 && EQ (glyph->object, str);
                               glyph += incr)
@@ -12915,7 +12960,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                                  cursor = glyph;
                                  break;
                                }
-                             if (glyph->charpos < strpos)
+                             if (tem && glyph->charpos < strpos)
                                {
                                  strpos = glyph->charpos;
                                  cursor = glyph;
@@ -12930,10 +12975,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                    }
                  /* This string is not what we want; skip all of the
                     glyphs that came from it.  */
-                 do
-                   glyph += incr;
                  while ((row->reversed_p ? glyph > stop : glyph < stop)
-                        && EQ (glyph->object, str));
+                        && EQ (glyph->object, str))
+                   glyph += incr;
                }
              else
                glyph += incr;
@@ -13381,7 +13425,11 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
 
       /* If cursor ends up on a partially visible line,
         treat that as being off the bottom of the screen.  */
-      if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
+      if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
+         /* It's possible that the cursor is on the first line of the
+            buffer, which is partially obscured due to a vscroll
+            (Bug#7537).  In that case, avoid looping forever . */
+         && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
        {
          clear_glyph_matrix (w->desired_matrix);
          ++extra_scroll_margin_lines;
@@ -15985,6 +16033,9 @@ try_window_id (struct window *w)
                     + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
                     + window_internal_height (w));
 
+#if defined (HAVE_GPM) || defined (MSDOS)
+         x_clear_window_mouse_face (w);
+#endif
          /* Perform the operation on the screen.  */
          if (dvpos > 0)
            {
@@ -21442,7 +21493,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
   if (head && !overlaps && row->contains_overlapping_glyphs_p)
     {
       struct glyph_string *h, *t;
-      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
       int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
       int dummy_x = 0;
 
@@ -21452,16 +21503,16 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
        {
          struct glyph_row *mouse_beg_row, *mouse_end_row;
 
-         mouse_beg_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
-         mouse_end_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
+         mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
+         mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
 
          if (row >= mouse_beg_row && row <= mouse_end_row)
            {
              check_mouse_face = 1;
              mouse_beg_col = (row == mouse_beg_row)
-               ? dpyinfo->mouse_face_beg_col : 0;
+               ? hlinfo->mouse_face_beg_col : 0;
              mouse_end_col = (row == mouse_end_row)
-               ? dpyinfo->mouse_face_end_col
+               ? hlinfo->mouse_face_end_col
                : row->used[TEXT_AREA];
            }
        }
@@ -22259,7 +22310,7 @@ calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
    and only if this is for a character for which no font was found.
 
    If the display method (it->glyphless_method) is
-   GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEXA_CODE, LEN is a
+   GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
    length of the acronym or the hexadecimal string, UPPER_XOFF and
    UPPER_YOFF are pixel offsets for the upper part of the string,
    LOWER_XOFF and LOWER_YOFF are for the lower part.
@@ -22408,7 +22459,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
        }
       else
        {
-         xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEXA_CODE);
+         xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
          sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
          str = buf;
        }
@@ -23400,6 +23451,8 @@ set_frame_cursor_types (struct frame *f, Lisp_Object arg)
 }
 
 
+#ifdef HAVE_WINDOW_SYSTEM
+
 /* Return the cursor we want to be displayed in window W.  Return
    width of bar/hbar cursor through WIDTH arg.  Return with
    ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
@@ -23445,10 +23498,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
 
   /* Detect a nonselected window or nonselected frame.  */
   else if (w != XWINDOW (f->selected_window)
-#ifdef HAVE_WINDOW_SYSTEM
-          || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
-#endif
-          )
+          || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
     {
       *active_cursor = 0;
 
@@ -23489,7 +23539,6 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
   /* Use normal cursor if not blinked off.  */
   if (!w->cursor_off_p)
     {
-#ifdef HAVE_WINDOW_SYSTEM
       if (glyph != NULL && glyph->type == IMAGE_GLYPH)
        {
          if (cursor_type == FILLED_BOX_CURSOR)
@@ -23517,7 +23566,6 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
              cursor_type = HOLLOW_BOX_CURSOR;
            }
       }
-#endif
       return cursor_type;
     }
 
@@ -23559,8 +23607,6 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
 }
 
 
-#ifdef HAVE_WINDOW_SYSTEM
-
 /* Notice when the text cursor of window W has been completely
    overwritten by a drawing operation that outputs glyphs in AREA
    starting at X0 and ending at X1 in the line starting at Y0 and
@@ -23726,7 +23772,7 @@ void
 erase_phys_cursor (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   int hpos = w->phys_cursor.hpos;
   int vpos = w->phys_cursor.vpos;
   int mouse_face_here_p = 0;
@@ -23782,7 +23828,7 @@ erase_phys_cursor (struct window *w)
 
   /* If the cursor is in the mouse face area, redisplay that when
      we clear the cursor.  */
-  if (! NILP (dpyinfo->mouse_face_window)
+  if (! NILP (hlinfo->mouse_face_window)
       && coords_in_mouse_face_p (w, hpos, vpos)
       /* Don't redraw the cursor's spot in mouse face if it is at the
         end of a line (on a newline).  The cursor appears there, but
@@ -23974,30 +24020,50 @@ x_clear_cursor (struct window *w)
     update_window_cursor (w, 0);
 }
 
+#endif /* HAVE_WINDOW_SYSTEM */
+
+/* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
+   and MSDOS.  */
+void
+draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
+                         int start_hpos, int end_hpos,
+                         enum draw_glyphs_face draw)
+{
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (XFRAME (w->frame)))
+    {
+      draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
+      return;
+    }
+#endif
+#if defined (HAVE_GPM) || defined (MSDOS)
+  tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
+#endif
+}
 
 /* EXPORT:
    Display the active region described by mouse_face_* according to DRAW.  */
 
 void
-show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
+show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
 {
-  struct window *w = XWINDOW (dpyinfo->mouse_face_window);
+  struct window *w = XWINDOW (hlinfo->mouse_face_window);
   struct frame *f = XFRAME (WINDOW_FRAME (w));
 
   if (/* If window is in the process of being destroyed, don't bother
         to do anything.  */
       w->current_matrix != NULL
       /* Don't update mouse highlight if hidden */
-      && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
+      && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
       /* Recognize when we are called to operate on rows that don't exist
         anymore.  This can happen when a window is split.  */
-      && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
+      && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
     {
       int phys_cursor_on_p = w->phys_cursor_on_p;
       struct glyph_row *row, *first, *last;
 
-      first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
-      last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
+      first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
+      last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
 
       for (row = first; row <= last && row->enabled_p; ++row)
        {
@@ -24012,13 +24078,13 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
                 highlighted area in R2L rows.  */
              if (!row->reversed_p)
                {
-                 start_hpos = dpyinfo->mouse_face_beg_col;
-                 start_x = dpyinfo->mouse_face_beg_x;
+                 start_hpos = hlinfo->mouse_face_beg_col;
+                 start_x = hlinfo->mouse_face_beg_x;
                }
              else if (row == last)
                {
-                 start_hpos = dpyinfo->mouse_face_end_col;
-                 start_x = dpyinfo->mouse_face_end_x;
+                 start_hpos = hlinfo->mouse_face_end_col;
+                 start_x = hlinfo->mouse_face_end_x;
                }
              else
                {
@@ -24028,8 +24094,8 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
            }
          else if (row->reversed_p && row == last)
            {
-             start_hpos = dpyinfo->mouse_face_end_col;
-             start_x = dpyinfo->mouse_face_end_x;
+             start_hpos = hlinfo->mouse_face_end_col;
+             start_x = hlinfo->mouse_face_end_x;
            }
          else
            {
@@ -24040,9 +24106,9 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
          if (row == last)
            {
              if (!row->reversed_p)
-               end_hpos = dpyinfo->mouse_face_end_col;
+               end_hpos = hlinfo->mouse_face_end_col;
              else if (row == first)
-               end_hpos = dpyinfo->mouse_face_beg_col;
+               end_hpos = hlinfo->mouse_face_beg_col;
              else
                {
                  end_hpos = row->used[TEXT_AREA];
@@ -24051,7 +24117,7 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
                }
            }
          else if (row->reversed_p && row == first)
-           end_hpos = dpyinfo->mouse_face_beg_col;
+           end_hpos = hlinfo->mouse_face_beg_col;
          else
            {
              end_hpos = row->used[TEXT_AREA];
@@ -24061,18 +24127,19 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
 
          if (end_hpos > start_hpos)
            {
-             draw_glyphs (w, start_x, row, TEXT_AREA,
-                          start_hpos, end_hpos,
-                          draw, 0);
+             draw_row_with_mouse_face (w, start_x, row,
+                                       start_hpos, end_hpos, draw);
 
              row->mouse_face_p
                = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
            }
        }
 
+#ifdef HAVE_WINDOW_SYSTEM
       /* When we've written over the cursor, arrange for it to
         be displayed again.  */
-      if (phys_cursor_on_p && !w->phys_cursor_on_p)
+      if (FRAME_WINDOW_P (f)
+         && phys_cursor_on_p && !w->phys_cursor_on_p)
        {
          BLOCK_INPUT;
          display_and_set_cursor (w, 1,
@@ -24080,15 +24147,22 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
                                  w->phys_cursor.x, w->phys_cursor.y);
          UNBLOCK_INPUT;
        }
+#endif /* HAVE_WINDOW_SYSTEM */
     }
 
+#ifdef HAVE_WINDOW_SYSTEM
   /* Change the mouse cursor.  */
-  if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
-    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
-  else if (draw == DRAW_MOUSE_FACE)
-    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
-  else
-    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
+  if (FRAME_WINDOW_P (f))
+    {
+      if (draw == DRAW_NORMAL_TEXT
+         && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
+       FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
+      else if (draw == DRAW_MOUSE_FACE)
+       FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
+      else
+       FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
+    }
+#endif /* HAVE_WINDOW_SYSTEM */
 }
 
 /* EXPORT:
@@ -24097,20 +24171,20 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
    face was actually drawn unhighlighted.  */
 
 int
-clear_mouse_face (Display_Info *dpyinfo)
+clear_mouse_face (Mouse_HLInfo *hlinfo)
 {
   int cleared = 0;
 
-  if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
+  if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
     {
-      show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
+      show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
       cleared = 1;
     }
 
-  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;
-  dpyinfo->mouse_face_overlay = 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;
+  hlinfo->mouse_face_overlay = Qnil;
   return cleared;
 }
 
@@ -24119,43 +24193,43 @@ clear_mouse_face (Display_Info *dpyinfo)
 static int
 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
 {
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
 
   /* Quickly resolve the easy cases.  */
-  if (!(WINDOWP (dpyinfo->mouse_face_window)
-       && XWINDOW (dpyinfo->mouse_face_window) == w))
+  if (!(WINDOWP (hlinfo->mouse_face_window)
+       && XWINDOW (hlinfo->mouse_face_window) == w))
     return 0;
-  if (vpos < dpyinfo->mouse_face_beg_row
-      || vpos > dpyinfo->mouse_face_end_row)
+  if (vpos < hlinfo->mouse_face_beg_row
+      || vpos > hlinfo->mouse_face_end_row)
     return 0;
-  if (vpos > dpyinfo->mouse_face_beg_row
-      && vpos < dpyinfo->mouse_face_end_row)
+  if (vpos > hlinfo->mouse_face_beg_row
+      && vpos < hlinfo->mouse_face_end_row)
     return 1;
 
   if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
     {
-      if (dpyinfo->mouse_face_beg_row == dpyinfo->mouse_face_end_row)
+      if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
        {
-         if (dpyinfo->mouse_face_beg_col <= hpos && hpos < dpyinfo->mouse_face_end_col)
+         if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
            return 1;
        }
-      else if ((vpos == dpyinfo->mouse_face_beg_row
-               && hpos >= dpyinfo->mouse_face_beg_col)
-              || (vpos == dpyinfo->mouse_face_end_row
-                  && hpos < dpyinfo->mouse_face_end_col))
+      else if ((vpos == hlinfo->mouse_face_beg_row
+               && hpos >= hlinfo->mouse_face_beg_col)
+              || (vpos == hlinfo->mouse_face_end_row
+                  && hpos < hlinfo->mouse_face_end_col))
        return 1;
     }
   else
     {
-       if (dpyinfo->mouse_face_beg_row == dpyinfo->mouse_face_end_row)
+       if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
        {
-         if (dpyinfo->mouse_face_end_col < hpos && hpos <= dpyinfo->mouse_face_beg_col)
+         if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
            return 1;
        }
-      else if ((vpos == dpyinfo->mouse_face_beg_row
-               && hpos <= dpyinfo->mouse_face_beg_col)
-              || (vpos == dpyinfo->mouse_face_end_row
-                  && hpos > dpyinfo->mouse_face_end_col))
+      else if ((vpos == hlinfo->mouse_face_beg_row
+               && hpos <= hlinfo->mouse_face_beg_col)
+              || (vpos == hlinfo->mouse_face_end_row
+                  && hpos > hlinfo->mouse_face_end_col))
        return 1;
     }
   return 0;
@@ -24296,7 +24370,7 @@ rows_from_pos_range (struct window *w,
     }
 }
 
-/* This function sets the mouse_face_* elements of DPYINFO, assuming
+/* This function sets the mouse_face_* elements of HLINFO, assuming
    the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
    window WINDOW.  START_CHARPOS and END_CHARPOS are buffer positions
    for the overlay or run of text properties specifying the mouse
@@ -24307,7 +24381,7 @@ rows_from_pos_range (struct window *w,
 
 static void
 mouse_face_from_buffer_pos (Lisp_Object window,
-                           Display_Info *dpyinfo,
+                           Mouse_HLInfo *hlinfo,
                            EMACS_INT mouse_charpos,
                            EMACS_INT start_charpos,
                            EMACS_INT end_charpos,
@@ -24352,7 +24426,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
   if (r2 == NULL)
     {
       r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
-      dpyinfo->mouse_face_past_end = 1;
+      hlinfo->mouse_face_past_end = 1;
     }
   else if (!NILP (after_string))
     {
@@ -24381,10 +24455,10 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       r1 = tem;
     }
 
-  dpyinfo->mouse_face_beg_y = r1->y;
-  dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
-  dpyinfo->mouse_face_end_y = r2->y;
-  dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
+  hlinfo->mouse_face_beg_y = r1->y;
+  hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
+  hlinfo->mouse_face_end_y = r2->y;
+  hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
 
   /* For a bidi-reordered row, the positions of BEFORE_STRING,
      AFTER_STRING, DISPLAY_STRING, START_CHARPOS, and END_CHARPOS
@@ -24432,19 +24506,19 @@ mouse_face_from_buffer_pos (Lisp_Object window,
                                            start_charpos);
              /* If pos == 0, it means before_string came from an
                 overlay, not from a buffer position.  */
-             if (!pos || pos >= start_charpos && pos < end_charpos)
+             if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
          else if (EQ (glyph->object, after_string))
            {
              pos = string_buffer_position (w, after_string, end_charpos);
-             if (!pos || pos >= start_charpos && pos < end_charpos)
+             if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
          x += glyph->pixel_width;
        }
-      dpyinfo->mouse_face_beg_x = x;
-      dpyinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
+      hlinfo->mouse_face_beg_x = x;
+      hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
     }
   else
     {
@@ -24482,13 +24556,13 @@ mouse_face_from_buffer_pos (Lisp_Object window,
              pos = string_buffer_position (w, before_string, start_charpos);
              /* If pos == 0, it means before_string came from an
                 overlay, not from a buffer position.  */
-             if (!pos || pos >= start_charpos && pos < end_charpos)
+             if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
          else if (EQ (glyph->object, after_string))
            {
              pos = string_buffer_position (w, after_string, end_charpos);
-             if (!pos || pos >= start_charpos && pos < end_charpos)
+             if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
        }
@@ -24496,8 +24570,8 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       glyph++; /* first glyph to the right of the highlighted area */
       for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
        x += g->pixel_width;
-      dpyinfo->mouse_face_beg_x = x;
-      dpyinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
+      hlinfo->mouse_face_beg_x = x;
+      hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
     }
 
   /* If the highlight ends in a different row, compute GLYPH and END
@@ -24546,13 +24620,13 @@ mouse_face_from_buffer_pos (Lisp_Object window,
          if (EQ (end->object, before_string))
            {
              pos = string_buffer_position (w, before_string, start_charpos);
-             if (!pos || pos >= start_charpos && pos < end_charpos)
+             if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
          else if (EQ (end->object, after_string))
            {
              pos = string_buffer_position (w, after_string, end_charpos);
-             if (!pos || pos >= start_charpos && pos < end_charpos)
+             if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
        }
@@ -24560,8 +24634,8 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       for (; glyph <= end; ++glyph)
        x += glyph->pixel_width;
 
-      dpyinfo->mouse_face_end_x = x;
-      dpyinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
+      hlinfo->mouse_face_end_x = x;
+      hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
     }
   else
     {
@@ -24596,27 +24670,27 @@ mouse_face_from_buffer_pos (Lisp_Object window,
          if (EQ (end->object, before_string))
            {
              pos = string_buffer_position (w, before_string, start_charpos);
-             if (!pos || pos >= start_charpos && pos < end_charpos)
+             if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
          else if (EQ (end->object, after_string))
            {
              pos = string_buffer_position (w, after_string, end_charpos);
-             if (!pos || pos >= start_charpos && pos < end_charpos)
+             if (!pos || (pos >= start_charpos && pos < end_charpos))
                break;
            }
          x += end->pixel_width;
        }
-      dpyinfo->mouse_face_end_x = x;
-      dpyinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
+      hlinfo->mouse_face_end_x = x;
+      hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
     }
 
-  dpyinfo->mouse_face_window = window;
-  dpyinfo->mouse_face_face_id
+  hlinfo->mouse_face_window = window;
+  hlinfo->mouse_face_face_id
     = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
                               mouse_charpos + 1,
-                              !dpyinfo->mouse_face_hidden, -1);
-  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+                              !hlinfo->mouse_face_hidden, -1);
+  show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
 }
 
 /* The following function is not used anymore (replaced with
@@ -24705,11 +24779,11 @@ fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
 
 /* Find the positions of the first and the last glyphs in window W's
    current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
-   (assumed to be a string), and return in DPYINFO's mouse_face
+   (assumed to be a string), and return in HLINFO's mouse_face_*
    members the pixel and column/row coordinates of those glyphs.  */
 
 static void
-mouse_face_from_string_pos (struct window *w, Display_Info *dpyinfo,
+mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
                            Lisp_Object object,
                            EMACS_INT startpos, EMACS_INT endpos)
 {
@@ -24734,10 +24808,10 @@ mouse_face_from_string_pos (struct window *w, Display_Info *dpyinfo,
            if (EQ (g->object, object)
                && startpos <= g->charpos && g->charpos <= endpos)
              {
-               dpyinfo->mouse_face_beg_row = r - w->current_matrix->rows;
-               dpyinfo->mouse_face_beg_y = r->y;
-               dpyinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
-               dpyinfo->mouse_face_beg_x = gx;
+               hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
+               hlinfo->mouse_face_beg_y = r->y;
+               hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
+               hlinfo->mouse_face_beg_x = gx;
                found = 1;
                break;
              }
@@ -24752,12 +24826,12 @@ mouse_face_from_string_pos (struct window *w, Display_Info *dpyinfo,
            if (EQ ((g-1)->object, object)
                && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
              {
-               dpyinfo->mouse_face_beg_row = r - w->current_matrix->rows;
-               dpyinfo->mouse_face_beg_y = r->y;
-               dpyinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
+               hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
+               hlinfo->mouse_face_beg_y = r->y;
+               hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
                for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
                  gx += g1->pixel_width;
-               dpyinfo->mouse_face_beg_x = gx;
+               hlinfo->mouse_face_beg_x = gx;
                found = 1;
                break;
              }
@@ -24791,8 +24865,8 @@ mouse_face_from_string_pos (struct window *w, Display_Info *dpyinfo,
   r--;
 
   /* Set the end row and its vertical pixel coordinate.  */
-  dpyinfo->mouse_face_end_row = r - w->current_matrix->rows;
-  dpyinfo->mouse_face_end_y = r->y;
+  hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
+  hlinfo->mouse_face_end_y = r->y;
 
   /* Compute and set the end column and the end column's horizontal
      pixel coordinate.  */
@@ -24804,11 +24878,11 @@ mouse_face_from_string_pos (struct window *w, Display_Info *dpyinfo,
        if (EQ ((e-1)->object, object)
            && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
          break;
-      dpyinfo->mouse_face_end_col = e - g;
+      hlinfo->mouse_face_end_col = e - g;
 
       for (gx = r->x; g < e; ++g)
        gx += g->pixel_width;
-      dpyinfo->mouse_face_end_x = gx;
+      hlinfo->mouse_face_end_x = gx;
     }
   else
     {
@@ -24821,11 +24895,13 @@ mouse_face_from_string_pos (struct window *w, Display_Info *dpyinfo,
            break;
          gx += e->pixel_width;
        }
-      dpyinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
-      dpyinfo->mouse_face_end_x = gx;
+      hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
+      hlinfo->mouse_face_end_x = gx;
     }
 }
 
+#ifdef HAVE_WINDOW_SYSTEM
+
 /* See if position X, Y is within a hot-spot of an image.  */
 
 static int
@@ -24996,6 +25072,8 @@ define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
     FRAME_RIF (f)->define_frame_cursor (f, cursor);
 }
 
+#endif /* HAVE_WINDOW_SYSTEM */
+
 /* Take proper action when mouse has moved to the mode or header line
    or marginal area AREA of window W, x-position X and y-position Y.
    X is relative to the start of the text display area of W, so the
@@ -25008,8 +25086,11 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
 {
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+#ifdef HAVE_WINDOW_SYSTEM
+  Display_Info *dpyinfo;
+#endif
+  Cursor cursor = No_Cursor;
   Lisp_Object pointer = Qnil;
   int dx, dy, width, height;
   EMACS_INT charpos;
@@ -25061,6 +25142,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
 
   help = Qnil;
 
+#ifdef HAVE_WINDOW_SYSTEM
   if (IMAGEP (object))
     {
       Lisp_Object image_map, hotspot;
@@ -25097,6 +25179,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
       if (NILP (pointer))
        pointer = Fplist_get (XCDR (object), QCpointer);
     }
+#endif /* HAVE_WINDOW_SYSTEM */
 
   if (STRINGP (string))
     {
@@ -25116,19 +25199,27 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
            }
        }
 
-      if (NILP (pointer))
-       pointer = Fget_text_property (pos, Qpointer, string);
-
-     /* Change the mouse pointer according to what is under X/Y.  */
-      if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
+#ifdef HAVE_WINDOW_SYSTEM
+      if (FRAME_WINDOW_P (f))
        {
-         Lisp_Object map;
-         map = Fget_text_property (pos, Qlocal_map, string);
-         if (!KEYMAPP (map))
-           map = Fget_text_property (pos, Qkeymap, string);
-         if (!KEYMAPP (map))
-           cursor = dpyinfo->vertical_scroll_bar_cursor;
+         dpyinfo = FRAME_X_DISPLAY_INFO (f);
+         cursor  = FRAME_X_OUTPUT (f)->nontext_cursor;
+         if (NILP (pointer))
+           pointer = Fget_text_property (pos, Qpointer, string);
+
+         /* Change the mouse pointer according to what is under X/Y.  */
+         if (NILP (pointer)
+             && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
+           {
+             Lisp_Object map;
+             map = Fget_text_property (pos, Qlocal_map, string);
+             if (!KEYMAPP (map))
+               map = Fget_text_property (pos, Qkeymap, string);
+             if (!KEYMAPP (map))
+               cursor = dpyinfo->vertical_scroll_bar_cursor;
+           }
        }
+#endif
 
      /* Change the mouse face according to what is under X/Y.  */
       mouse_face = Fget_text_property (pos, Qmouse_face, string);
@@ -25208,60 +25299,63 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
 
          /* If GLYPH's position is included in the region that is
             already drawn in mouse face, we have nothing to do.  */
-         if ( EQ (window, dpyinfo->mouse_face_window)
+         if ( EQ (window, hlinfo->mouse_face_window)
               && (!row->reversed_p
-                  ? (dpyinfo->mouse_face_beg_col <= hpos
-                     && hpos < dpyinfo->mouse_face_end_col)
+                  ? (hlinfo->mouse_face_beg_col <= hpos
+                     && hpos < hlinfo->mouse_face_end_col)
                   /* In R2L rows we swap BEG and END, see below.  */
-                  : (dpyinfo->mouse_face_end_col <= hpos
-                     && hpos < dpyinfo->mouse_face_beg_col))
-              && dpyinfo->mouse_face_beg_row == vpos )
+                  : (hlinfo->mouse_face_end_col <= hpos
+                     && hpos < hlinfo->mouse_face_beg_col))
+              && hlinfo->mouse_face_beg_row == vpos )
            return;
 
-         if (clear_mouse_face (dpyinfo))
+         if (clear_mouse_face (hlinfo))
            cursor = No_Cursor;
 
          if (!row->reversed_p)
            {
-             dpyinfo->mouse_face_beg_col = hpos;
-             dpyinfo->mouse_face_beg_x   = original_x_pixel
+             hlinfo->mouse_face_beg_col = hpos;
+             hlinfo->mouse_face_beg_x   = original_x_pixel
                                            - (total_pixel_width + dx);
-             dpyinfo->mouse_face_end_col = hpos + gseq_length;
-             dpyinfo->mouse_face_end_x   = 0;
+             hlinfo->mouse_face_end_col = hpos + gseq_length;
+             hlinfo->mouse_face_end_x   = 0;
            }
          else
            {
              /* In R2L rows, show_mouse_face expects BEG and END
                 coordinates to be swapped.  */
-             dpyinfo->mouse_face_end_col = hpos;
-             dpyinfo->mouse_face_end_x   = original_x_pixel
+             hlinfo->mouse_face_end_col = hpos;
+             hlinfo->mouse_face_end_x   = original_x_pixel
                                            - (total_pixel_width + dx);
-             dpyinfo->mouse_face_beg_col = hpos + gseq_length;
-             dpyinfo->mouse_face_beg_x   = 0;
+             hlinfo->mouse_face_beg_col = hpos + gseq_length;
+             hlinfo->mouse_face_beg_x   = 0;
            }
 
-         dpyinfo->mouse_face_beg_row  = vpos;
-         dpyinfo->mouse_face_end_row  = dpyinfo->mouse_face_beg_row;
-         dpyinfo->mouse_face_beg_y    = 0;
-         dpyinfo->mouse_face_end_y    = 0;
-         dpyinfo->mouse_face_past_end = 0;
-         dpyinfo->mouse_face_window   = window;
-
-         dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
-                                                                charpos,
-                                                                0, 0, 0,
-                                                                &ignore,
-                                                                glyph->face_id,
-                                                                1);
-         show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+         hlinfo->mouse_face_beg_row  = vpos;
+         hlinfo->mouse_face_end_row  = hlinfo->mouse_face_beg_row;
+         hlinfo->mouse_face_beg_y    = 0;
+         hlinfo->mouse_face_end_y    = 0;
+         hlinfo->mouse_face_past_end = 0;
+         hlinfo->mouse_face_window   = window;
+
+         hlinfo->mouse_face_face_id = face_at_string_position (w, string,
+                                                               charpos,
+                                                               0, 0, 0,
+                                                               &ignore,
+                                                               glyph->face_id,
+                                                               1);
+         show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
 
          if (NILP (pointer))
            pointer = Qhand;
        }
       else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
-       clear_mouse_face (dpyinfo);
+       clear_mouse_face (hlinfo);
     }
-  define_frame_cursor1 (f, cursor, pointer);
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
+    define_frame_cursor1 (f, cursor, pointer);
+#endif
 }
 
 
@@ -25274,7 +25368,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
 void
 note_mouse_highlight (struct frame *f, int x, int y)
 {
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   enum window_part part;
   Lisp_Object window;
   struct window *w;
@@ -25283,7 +25377,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
   struct buffer *b;
 
   /* When a menu is active, don't highlight because this looks odd.  */
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
   if (popup_activated ())
     return;
 #endif
@@ -25293,28 +25387,28 @@ note_mouse_highlight (struct frame *f, int x, int y)
       || f->pointer_invisible)
     return;
 
-  dpyinfo->mouse_face_mouse_x = x;
-  dpyinfo->mouse_face_mouse_y = y;
-  dpyinfo->mouse_face_mouse_frame = f;
+  hlinfo->mouse_face_mouse_x = x;
+  hlinfo->mouse_face_mouse_y = y;
+  hlinfo->mouse_face_mouse_frame = f;
 
-  if (dpyinfo->mouse_face_defer)
+  if (hlinfo->mouse_face_defer)
     return;
 
   if (gc_in_progress)
     {
-      dpyinfo->mouse_face_deferred_gc = 1;
+      hlinfo->mouse_face_deferred_gc = 1;
       return;
     }
 
   /* Which window is that in?  */
-  window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
+  window = window_from_coordinates (f, x, y, &part, 1);
 
   /* If we were displaying active text in another window, clear that.
      Also clear if we move out of text area in same window.  */
-  if (! EQ (window, dpyinfo->mouse_face_window)
+  if (! EQ (window, hlinfo->mouse_face_window)
       || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
-         && !NILP (dpyinfo->mouse_face_window)))
-    clear_mouse_face (dpyinfo);
+         && !NILP (hlinfo->mouse_face_window)))
+    clear_mouse_face (hlinfo);
 
   /* Not on a window -> return.  */
   if (!WINDOWP (window))
@@ -25327,6 +25421,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
   w = XWINDOW (window);
   frame_to_window_pixel_xy (w, &x, &y);
 
+#ifdef HAVE_WINDOW_SYSTEM
   /* Handle tool-bar window differently since it doesn't display a
      buffer.  */
   if (EQ (window, f->tool_bar_window))
@@ -25334,6 +25429,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
       note_tool_bar_highlight (f, x, y);
       return;
     }
+#endif
 
   /* Mouse is on the mode, header line or margin?  */
   if (part == ON_MODE_LINE || part == ON_HEADER_LINE
@@ -25343,6 +25439,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
       return;
     }
 
+#ifdef HAVE_WINDOW_SYSTEM
   if (part == ON_VERTICAL_BORDER)
     {
       cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
@@ -25353,6 +25450,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
     cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
   else
     cursor = FRAME_X_OUTPUT (f)->text_cursor;
+#endif
 
   /* Are we in a window whose display is up to date?
      And verify the buffer's text has not changed.  */
@@ -25376,6 +25474,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
       /* Find the glyph under X/Y.  */
       glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
 
+#ifdef HAVE_WINDOW_SYSTEM
       /* Look for :pointer property on image.  */
       if (glyph != NULL && glyph->type == IMAGE_GLYPH)
        {
@@ -25417,11 +25516,18 @@ note_mouse_highlight (struct frame *f, int x, int y)
                pointer = Fplist_get (XCDR (img->spec), QCpointer);
            }
        }
+#endif /* HAVE_WINDOW_SYSTEM */
 
       /* Clear mouse face if X/Y not over text.  */
       if (glyph == NULL
          || area != TEXT_AREA
          || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
+         /* Glyph's OBJECT is an integer for glyphs inserted by the
+            display engine for its internal purposes, like truncation
+            and continuation glyphs and blanks beyond the end of
+            line's text on text terminals.  If we are over such a
+            glyph, we are not over any text.  */
+         || INTEGERP (glyph->object)
          /* R2L rows have a stretch glyph at their front, which
             stands for no text, whereas L2R rows have no glyphs at
             all beyond the end of text.  Treat such stretch glyphs
@@ -25431,15 +25537,17 @@ note_mouse_highlight (struct frame *f, int x, int y)
              && glyph->type == STRETCH_GLYPH
              && glyph->avoid_cursor_p))
        {
-         if (clear_mouse_face (dpyinfo))
+         if (clear_mouse_face (hlinfo))
            cursor = No_Cursor;
-         if (NILP (pointer))
+#ifdef HAVE_WINDOW_SYSTEM
+         if (FRAME_WINDOW_P (f) && NILP (pointer))
            {
              if (area != TEXT_AREA)
                cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
              else
                pointer = Vvoid_text_area_pointer;
            }
+#endif
          goto set_cursor;
        }
 
@@ -25485,8 +25593,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
             the one we are currently highlighting, we have to
             check if we enter the overlapping overlay, and then
             highlight only that.  */
-         || (OVERLAYP (dpyinfo->mouse_face_overlay)
-             && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
+         || (OVERLAYP (hlinfo->mouse_face_overlay)
+             && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
        {
          /* Find the highest priority overlay with a mouse-face.  */
          overlay = Qnil;
@@ -25499,12 +25607,12 @@ note_mouse_highlight (struct frame *f, int x, int y)
 
          /* If we're highlighting the same overlay as before, there's
             no need to do that again.  */
-         if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay))
+         if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
            goto check_help_echo;
-         dpyinfo->mouse_face_overlay = overlay;
+         hlinfo->mouse_face_overlay = overlay;
 
          /* Clear the display of the old active region, if any.  */
-         if (clear_mouse_face (dpyinfo))
+         if (clear_mouse_face (hlinfo))
            cursor = No_Cursor;
 
          /* If no overlay applies, get a text property.  */
@@ -25528,14 +25636,14 @@ note_mouse_highlight (struct frame *f, int x, int y)
                b = make_number (0);
              if (NILP (e))
                e = make_number (SCHARS (object) - 1);
-             mouse_face_from_string_pos (w, dpyinfo, object,
+             mouse_face_from_string_pos (w, hlinfo, object,
                                          XINT (b), XINT (e));
-             dpyinfo->mouse_face_past_end = 0;
-             dpyinfo->mouse_face_window = window;
-             dpyinfo->mouse_face_face_id
+             hlinfo->mouse_face_past_end = 0;
+             hlinfo->mouse_face_window = window;
+             hlinfo->mouse_face_face_id
                = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
                                           glyph->face_id, 1);
-             show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+             show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
              cursor = No_Cursor;
            }
          else
@@ -25610,7 +25718,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
                      if (!STRINGP (after_string))  after_string = Qnil;
                    }
 
-                 mouse_face_from_buffer_pos (window, dpyinfo, pos,
+                 mouse_face_from_buffer_pos (window, hlinfo, pos,
                                              XFASTINT (before),
                                              XFASTINT (after),
                                              before_string, after_string,
@@ -25689,8 +25797,9 @@ note_mouse_highlight (struct frame *f, int x, int y)
          }
       }
 
+#ifdef HAVE_WINDOW_SYSTEM
       /* Look for a `pointer' property.  */
-      if (NILP (pointer))
+      if (FRAME_WINDOW_P (f) && NILP (pointer))
        {
          /* Check overlays first.  */
          for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
@@ -25729,6 +25838,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
                                              Qpointer, object);
            }
        }
+#endif /* HAVE_WINDOW_SYSTEM */
 
       BEGV = obegv;
       ZV = ozv;
@@ -25737,7 +25847,14 @@ note_mouse_highlight (struct frame *f, int x, int y)
 
  set_cursor:
 
-  define_frame_cursor1 (f, cursor, pointer);
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
+    define_frame_cursor1 (f, cursor, pointer);
+#else
+  /* This is here to prevent a compiler error, about "label at end of
+     compound statement".  */
+  return;
+#endif
 }
 
 
@@ -25749,13 +25866,13 @@ note_mouse_highlight (struct frame *f, int x, int y)
 void
 x_clear_window_mouse_face (struct window *w)
 {
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
   Lisp_Object window;
 
   BLOCK_INPUT;
   XSETWINDOW (window, w);
-  if (EQ (window, dpyinfo->mouse_face_window))
-    clear_mouse_face (dpyinfo);
+  if (EQ (window, hlinfo->mouse_face_window))
+    clear_mouse_face (hlinfo);
   UNBLOCK_INPUT;
 }
 
@@ -25768,20 +25885,18 @@ void
 cancel_mouse_face (struct frame *f)
 {
   Lisp_Object window;
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
 
-  window = dpyinfo->mouse_face_window;
+  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 /* HAVE_WINDOW_SYSTEM */
-
 \f
 /***********************************************************************
                           Exposure Events
@@ -26238,12 +26353,12 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
      focus-follows-mouse with delayed raise.  --jason 2001-10-12  */
   if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
     {
-      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-      if (f == dpyinfo->mouse_face_mouse_frame)
+      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+      if (f == hlinfo->mouse_face_mouse_frame)
        {
-         int x = dpyinfo->mouse_face_mouse_x;
-         int y = dpyinfo->mouse_face_mouse_y;
-         clear_mouse_face (dpyinfo);
+         int x = hlinfo->mouse_face_mouse_x;
+         int y = hlinfo->mouse_face_mouse_y;
+         clear_mouse_face (hlinfo);
          note_mouse_highlight (f, x, y);
        }
     }
@@ -26960,7 +27075,7 @@ cursor shapes.  */);
   hourglass_shown_p = 0;
 
   DEFSYM (Qglyphless_char, "glyphless-char");
-  DEFSYM (Qhexa_code, "hexa-code");
+  DEFSYM (Qhex_code, "hex-code");
   DEFSYM (Qempty_box, "empty-box");
   DEFSYM (Qthin_space, "thin-space");
   DEFSYM (Qzero_width, "zero-width");
@@ -26976,13 +27091,13 @@ cursor shapes.  */);
               doc: /* Char-table to control displaying of glyphless characters.
 Each element, if non-nil, is an ASCII acronym string (displayed in a box)
 or one of these symbols:
-  hexa-code: display with hexadecimal character code in a box
-  empty-box: display with an empty box
-  thin-space: display with 1-pixel width space
+  hex-code:   display the hexadecimal code of a character in a box
+  empty-box:  display as an empty box
+  thin-space: display as 1-pixel width space
   zero-width: don't display
 
 It has one extra slot to control the display of a character for which
-no font is found.  The value of the slot is `hexa-code' or `empty-box'.
+no font is found.  The value of the slot is `hex-code' or `empty-box'.
 The default is `empty-box'.  */);
   Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
   Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),