changeset 111413:d53ee71e7e89

Unify mouse-highlight code for all GUI and TTY sessions. term.c: Remove static mouse_face_* variables. All users changed. (term_show_mouse_face, term_clear_mouse_face) (fast_find_position, term_mouse_highlight): Functions deleted. (tty_draw_row_with_mouse_face): New function. (term_mouse_movement): Call note_mouse_highlight instead of term_mouse_highlight. nsterm.m (ns_update_window_begin, ns_update_window_end) (ns_update_end, x_destroy_window, ns_frame_up_to_date) (ns_dumpglyphs_box_or_relief, ns_maybe_dumpglyphs_background) (ns_dumpglyphs_image, ns_dumpglyphs_stretch) (ns_initialize_display_info, keyDown, mouseMoved, mouseExited): Replace Display_Info with Mouse_HLInfo everywhere where mouse_face_* members were accessed for mouse highlight purposes. xterm.c (x_update_window_begin, x_update_window_end) (x_update_end, XTframe_up_to_date, x_set_mouse_face_gc) (handle_one_xevent, x_free_frame_resources, x_term_init): Replace Display_Info with Mouse_HLInfo everywhere where mouse_face_* members were accessed for mouse highlight purposes. w32term.c (x_update_window_begin, x_update_window_end) (x_update_end, w32_read_socket, x_free_frame_resources) (w32_initialize_display_info): Replace Display_Info with Mouse_HLInfo everywhere where mouse_face_* members were accessed for mouse highlight purposes. xdisp.c (show_mouse_face, note_mode_line_or_margin_highlight) (note_mouse_highlight) [HAVE_WINDOW_SYSTEM]: Don't run GUI code unless the frame is on a window-system. (get_tool_bar_item, handle_tool_bar_click) (note_tool_bar_highlight, draw_glyphs, erase_phys_cursor) (show_mouse_face, clear_mouse_face, coords_in_mouse_face_p) (note_mode_line_or_margin_highlight, note_mouse_highlight) (x_clear_window_mouse_face, cancel_mouse_face, expose_frame): Replace Display_Info with Mouse_HLInfo everywhere where mouse_face_* members were accessed for mouse highlight purposes. (coords_in_mouse_face_p): Move prototype out of the HAVE_WINDOW_SYSTEM conditional. (x_y_to_hpos_vpos, frame_to_window_pixel_xy): Move out of the HAVE_WINDOW_SYSTEM block. (try_window_id) [HAVE_GPM || MSDOS]: Call x_clear_window_mouse_face. (draw_row_with_mouse_face): Implementation for HAVE_WINDOW_SYSTEM systems. Call tty_draw_row_with_mouse_face for TTY systems. (show_mouse_face): Call draw_row_with_mouse_face, instead of calling draw_glyphs directly. (show_mouse_face, clear_mouse_face, coords_in_mouse_face_p) (cursor_in_mouse_face_p, rows_from_pos_range) (mouse_face_from_buffer_pos, mouse_face_from_string_pos) (note_mode_line_or_margin_highlight, note_mouse_highlight) (x_clear_window_mouse_face, cancel_mouse_face): Move out of the HAVE_WINDOW_SYSTEM block. Ifdef away window-system specific fragments. (note_mouse_highlight): Call popup_activated for MSDOS as well. Clear mouse highlight if pointer is over glyphs whose OBJECT is an integer. (mouse_face_from_buffer_pos): Add parentheses around && within ||. (x_consider_frame_title, tool_bar_lines_needed): Move prototypes to HAVE_WINDOW_SYSTEM-only part. (get_window_cursor_type): Move inside a HAVE_WINDOW_SYSTEM-only part. Remove "#ifdef HAVE_WINDOW_SYSTEM" from body of function. (null_glyph_slice): Move declaration into HAVE_WINDOW_SYSTEM-only part. dispnew.c (mirror_make_current): Set Y coordinate of the mode-line and header-line rows. (init_display): Setup initial frame's output_data for text terminal frames. xmenu.c (popup_activated): Don't define on MSDOS, which now has its own definition on msdos.c. msdos.c (show_mouse_face, clear_mouse_face) (fast_find_position, IT_note_mode_line_highlight) (IT_note_mouse_highlight): Functions deleted. (IT_frame_up_to_date, dos_rawgetc): Call note_mouse_highlight instead of IT_note_mouse_highlight. (draw_row_with_mouse_face, popup_activated): New functions. (dos_set_window_size, draw_row_with_mouse_face, IT_update_begin) (IT_update_end, IT_frame_up_to_date, internal_terminal_init) (dos_rawgetc): Replace Display_Info with Mouse_HLInfo everywhere where mouse_face_* members were accessed for mouse highlight purposes. msdos.h (initialize_msdos_display): Add prototype. frame.h (MOUSE_HL_INFO): New macro. lisp.h (Mouse_HLInfo): New data type. xterm.h (struct x_display_info): w32term.h (struct w32_display_info): nsterm.h (struct ns_display_info): termchar.h (struct tty_display_info): Use it instead of mouse_face_* members. dispextern.h (show_mouse_face, clear_mouse_face): Update type of 1st argument. (frame_to_window_pixel_xy, note_mouse_highlight) (x_clear_window_mouse_face, cancel_mouse_face, clear_mouse_face) (show_mouse_face, cursor_in_mouse_face_p): Move prototypes out of HAVE_WINDOW_SYSTEM conditional. (draw_row_with_mouse_face): Declare prototype. (tty_draw_row_with_mouse_face): Declare prototype.
author Eli Zaretskii <eliz@gnu.org>
date Sat, 06 Nov 2010 10:28:31 +0200
parents cc7702f421a0 (current diff) 9a687477468c (diff)
children d291fc8615a3
files src/ChangeLog src/dispextern.h src/nsterm.m src/term.c src/w32term.c src/xdisp.c src/xterm.c
diffstat 17 files changed, 860 insertions(+), 1558 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/ChangeLog	Sat Nov 06 10:28:31 2010 +0200
@@ -1,3 +1,114 @@
+2010-11-05  Eli Zaretskii  <eliz@gnu.org>
+
+	Unify mouse-highlight code for all GUI and TTY sessions.
+
+	* term.c: Remove static mouse_face_* variables.  All users
+	changed.
+	(term_show_mouse_face, term_clear_mouse_face)
+	(fast_find_position, term_mouse_highlight): Functions deleted.
+	(tty_draw_row_with_mouse_face): New function.
+	(term_mouse_movement): Call note_mouse_highlight instead of
+	term_mouse_highlight.
+
+	* nsterm.m (ns_update_window_begin, ns_update_window_end)
+	(ns_update_end, x_destroy_window, ns_frame_up_to_date)
+	(ns_dumpglyphs_box_or_relief, ns_maybe_dumpglyphs_background)
+	(ns_dumpglyphs_image, ns_dumpglyphs_stretch)
+	(ns_initialize_display_info, keyDown, mouseMoved, mouseExited):
+	Replace Display_Info with Mouse_HLInfo everywhere where
+	mouse_face_* members were accessed for mouse highlight purposes.
+
+	* xterm.c (x_update_window_begin, x_update_window_end)
+	(x_update_end, XTframe_up_to_date, x_set_mouse_face_gc)
+	(handle_one_xevent, x_free_frame_resources, x_term_init): Replace
+	Display_Info with Mouse_HLInfo everywhere where mouse_face_*
+	members were accessed for mouse highlight purposes.
+
+	* w32term.c (x_update_window_begin, x_update_window_end)
+	(x_update_end, w32_read_socket, x_free_frame_resources)
+	(w32_initialize_display_info): Replace Display_Info with
+	Mouse_HLInfo everywhere where mouse_face_* members were accessed
+	for mouse highlight purposes.
+
+	* xdisp.c (show_mouse_face, note_mode_line_or_margin_highlight)
+	(note_mouse_highlight) [HAVE_WINDOW_SYSTEM]: Don't run GUI code
+	unless the frame is on a window-system.
+	(get_tool_bar_item, handle_tool_bar_click)
+	(note_tool_bar_highlight, draw_glyphs, erase_phys_cursor)
+	(show_mouse_face, clear_mouse_face, coords_in_mouse_face_p)
+	(note_mode_line_or_margin_highlight, note_mouse_highlight)
+	(x_clear_window_mouse_face, cancel_mouse_face, expose_frame):
+	Replace Display_Info with Mouse_HLInfo everywhere where
+	mouse_face_* members were accessed for mouse highlight purposes.
+	(coords_in_mouse_face_p): Move prototype out of the
+	HAVE_WINDOW_SYSTEM conditional.
+	(x_y_to_hpos_vpos, frame_to_window_pixel_xy): Move out of the
+	HAVE_WINDOW_SYSTEM block.
+	(try_window_id) [HAVE_GPM || MSDOS]: Call
+	x_clear_window_mouse_face.
+	(draw_row_with_mouse_face): Implementation for HAVE_WINDOW_SYSTEM
+	systems.  Call tty_draw_row_with_mouse_face for TTY systems.
+	(show_mouse_face): Call draw_row_with_mouse_face, instead of
+	calling draw_glyphs directly.
+	(show_mouse_face, clear_mouse_face, coords_in_mouse_face_p)
+	(cursor_in_mouse_face_p, rows_from_pos_range)
+	(mouse_face_from_buffer_pos, mouse_face_from_string_pos)
+	(note_mode_line_or_margin_highlight, note_mouse_highlight)
+	(x_clear_window_mouse_face, cancel_mouse_face): Move out of the
+	HAVE_WINDOW_SYSTEM block.  Ifdef away window-system specific
+	fragments.
+	(note_mouse_highlight): Call popup_activated for MSDOS as well.
+	Clear mouse highlight if pointer is over glyphs whose OBJECT is an
+	integer.
+	(mouse_face_from_buffer_pos): Add parentheses around && within ||.
+	(x_consider_frame_title, tool_bar_lines_needed): Move
+	prototypes to HAVE_WINDOW_SYSTEM-only part.
+	(get_window_cursor_type): Move inside a HAVE_WINDOW_SYSTEM-only
+	part.  Remove "#ifdef HAVE_WINDOW_SYSTEM" from body of function.
+	(null_glyph_slice): Move declaration into HAVE_WINDOW_SYSTEM-only
+	part.
+
+	* dispnew.c (mirror_make_current): Set Y coordinate of the
+	mode-line and header-line rows.
+	(init_display): Setup initial frame's output_data for text
+	terminal frames.
+
+	* xmenu.c (popup_activated): Don't define on MSDOS, which now has
+	its own definition on msdos.c.
+
+	* msdos.c (show_mouse_face, clear_mouse_face)
+	(fast_find_position, IT_note_mode_line_highlight)
+	(IT_note_mouse_highlight): Functions deleted.
+	(IT_frame_up_to_date, dos_rawgetc): Call note_mouse_highlight
+	instead of IT_note_mouse_highlight.
+	(draw_row_with_mouse_face, popup_activated): New functions.
+	(dos_set_window_size, draw_row_with_mouse_face, IT_update_begin)
+	(IT_update_end, IT_frame_up_to_date, internal_terminal_init)
+	(dos_rawgetc): Replace Display_Info with Mouse_HLInfo everywhere
+	where mouse_face_* members were accessed for mouse highlight
+	purposes.
+
+	* msdos.h (initialize_msdos_display): Add prototype.
+
+	* frame.h (MOUSE_HL_INFO): New macro.
+
+	* lisp.h (Mouse_HLInfo): New data type.
+
+	* xterm.h (struct x_display_info):
+	* w32term.h (struct w32_display_info):
+	* nsterm.h (struct ns_display_info):
+	* termchar.h (struct tty_display_info): Use it instead of
+	mouse_face_* members.
+
+	* dispextern.h (show_mouse_face, clear_mouse_face): Update type of
+	1st argument.
+	(frame_to_window_pixel_xy, note_mouse_highlight)
+	(x_clear_window_mouse_face, cancel_mouse_face, clear_mouse_face)
+	(show_mouse_face, cursor_in_mouse_face_p): Move prototypes out of
+	HAVE_WINDOW_SYSTEM conditional.
+	(draw_row_with_mouse_face): Declare prototype.
+	(tty_draw_row_with_mouse_face): Declare prototype.
+
 2010-11-05  Eli Zaretskii  <eliz@gnu.org>
 
 	* term.c (append_glyphless_glyph, produce_glyphless_glyph): Remove
--- a/src/dispextern.h	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/dispextern.h	Sat Nov 06 10:28:31 2010 +0200
@@ -69,6 +69,11 @@
 typedef XImagePtr XImagePtr_or_DC;
 #endif
 
+#ifndef HAVE_WINDOW_SYSTEM
+typedef int Cursor;
+#define No_Cursor (0)
+#endif
+
 #ifndef NativeRectangle
 #define NativeRectangle int
 #endif
@@ -3060,28 +3065,31 @@
 extern void x_clear_cursor (struct window *);
 extern void x_draw_vertical_border (struct window *w);
 
-extern void frame_to_window_pixel_xy (struct window *, int *, int *);
 extern int get_glyph_string_clip_rects (struct glyph_string *,
                                         NativeRectangle *, int);
 extern void get_glyph_string_clip_rect (struct glyph_string *,
                                         NativeRectangle *nr);
 extern Lisp_Object find_hot_spot (Lisp_Object, int, int);
-extern void note_mouse_highlight (struct frame *, int, int);
-extern void x_clear_window_mouse_face (struct window *);
-extern void cancel_mouse_face (struct frame *);
 
 extern void handle_tool_bar_click (struct frame *,
                                    int, int, int, unsigned int);
 
-/* msdos.c defines its own versions of these functions. */
-extern int clear_mouse_face (Display_Info *);
-extern void show_mouse_face (Display_Info *, enum draw_glyphs_face);
-extern int cursor_in_mouse_face_p (struct window *w);
-
 extern void expose_frame (struct frame *, int, int, int, int);
 extern int x_intersect_rectangles (XRectangle *, XRectangle *,
                                    XRectangle *);
-#endif
+#endif	/* HAVE_WINDOW_SYSTEM */
+
+extern void frame_to_window_pixel_xy (struct window *, int *, int *);
+extern void note_mouse_highlight (struct frame *, int, int);
+extern void x_clear_window_mouse_face (struct window *);
+extern void cancel_mouse_face (struct frame *);
+extern int clear_mouse_face (Mouse_HLInfo *);
+extern void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
+extern int cursor_in_mouse_face_p (struct window *w);
+extern void draw_row_with_mouse_face (struct window *, int, struct glyph_row *,
+				      int, int, enum draw_glyphs_face);
+extern void tty_draw_row_with_mouse_face (struct window *, struct glyph_row *,
+					  int, int, enum draw_glyphs_face);
 
 /* Flags passed to try_window.  */
 #define TRY_WINDOW_CHECK_MARGINS	(1 << 0)
--- a/src/dispnew.c	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/dispnew.c	Sat Nov 06 10:28:31 2010 +0200
@@ -2893,6 +2893,14 @@
 	      else
 		swap_glyph_pointers (desired_row, current_row);
 	      current_row->enabled_p = 1;
+
+	      /* Set the Y coordinate of the mode/header line's row.
+		 It is needed in draw_row_with_mouse_face to find the
+		 screen coordinates.  (Window-based redisplay sets
+		 this in update_window, but no one seems to do that
+		 for frame-based redisplay.)  */
+	      if (current_row->mode_line_p)
+		current_row->y = row;
 	    }
 	}
 
@@ -6416,6 +6424,12 @@
     f->terminal = t;
 
     t->reference_count++;
+#ifdef MSDOS
+    f->output_data.tty->display_info = &the_only_display_info;
+#else
+    if (f->output_method == output_termcap)
+      create_tty_output (f);
+#endif
     t->display_info.tty->top_frame = selected_frame;
     change_frame_size (XFRAME (selected_frame),
                        FrameRows (t->display_info.tty),
--- a/src/frame.h	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/frame.h	Sat Nov 06 10:28:31 2010 +0200
@@ -544,6 +544,20 @@
 #define FRAME_WINDOW_P(f) (0)
 #endif
 
+/* Return a pointer to the structure holding information about the
+   region of text, if any, that is currently shown in mouse-face on
+   frame F.  We need to define two versions because a TTY-only build
+   does not have FRAME_X_DISPLAY_INFO.  */
+#ifdef HAVE_WINDOW_SYSTEM
+# define MOUSE_HL_INFO(F)					\
+   (FRAME_WINDOW_P(F)						\
+    ? &(FRAME_X_DISPLAY_INFO(F)->mouse_highlight)		\
+    : &(((F)->output_data.tty->display_info)->mouse_highlight))
+#else
+# define MOUSE_HL_INFO(F)					\
+    (&(((F)->output_data.tty->display_info)->mouse_highlight))
+#endif
+
 /* Nonzero if frame F is still alive (not deleted).  */
 #define FRAME_LIVE_P(f) ((f)->terminal != 0)
 
--- a/src/lisp.h	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/lisp.h	Sat Nov 06 10:28:31 2010 +0200
@@ -1563,6 +1563,41 @@
 /* The ID of the mode line highlighting face.  */
 #define GLYPH_MODE_LINE_FACE 1
 
+/* Structure to hold mouse highlight data.  This is here because other
+   header files need it for defining struct x_output etc.  */
+typedef struct {
+  /* These variables describe the range of text currently shown in its
+     mouse-face, together with the window they apply to.  As long as
+     the mouse stays within this range, we need not redraw anything on
+     its account.  Rows and columns are glyph matrix positions in
+     MOUSE_FACE_WINDOW.  */
+  int mouse_face_beg_row, mouse_face_beg_col;
+  int mouse_face_beg_x, mouse_face_beg_y;
+  int mouse_face_end_row, mouse_face_end_col;
+  int mouse_face_end_x, mouse_face_end_y;
+  int mouse_face_past_end;
+  Lisp_Object mouse_face_window;
+  int mouse_face_face_id;
+  Lisp_Object mouse_face_overlay;
+
+  /* 1 if a mouse motion event came and we didn't handle it right away because
+     gc was in progress.  */
+  int mouse_face_deferred_gc;
+
+  /* FRAME and X, Y position of mouse when last checked for
+     highlighting.  X and Y can be negative or out of range for the frame.  */
+  struct frame *mouse_face_mouse_frame;
+  int mouse_face_mouse_x, mouse_face_mouse_y;
+
+  /* Nonzero means defer mouse-motion highlighting.  */
+  int mouse_face_defer;
+
+  /* Nonzero means that the mouse highlight should not be shown.  */
+  int mouse_face_hidden;
+
+  int mouse_face_image_state;
+} Mouse_HLInfo;
+
 /* Data type checking */
 
 #define NILP(x)  EQ (x, Qnil)
--- a/src/msdos.c	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/msdos.c	Sat Nov 06 10:28:31 2010 +0200
@@ -584,14 +584,14 @@
   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;
 	}
     }
 
@@ -941,551 +941,79 @@
 
 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)
-{
-  /* 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.  */
-}
-
-/* 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)
+int
+popup_activated (void)
 {
-  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);
-
-
-  /* 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++)
-    {
-      struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
-      int charpos;
-
-      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 (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))
-	{
-	  /* 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;
-	    }
-	}
-    }
+  return mouse_preempted;
 }
 
-/* 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)
+/* 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 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)
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct tty_display_info *tty = FRAME_TTY (f);
+  Mouse_HLInfo *hlinfo = &tty->mouse_highlight;
+
+  if (hl == DRAW_MOUSE_FACE)
     {
-      /* Mouse is on the mode or top line.  */
-      IT_note_mode_line_highlight (w, x, part == ON_MODE_LINE);
-      return;
-    }
-
-  IT_set_mouse_pointer (0);
-
-  /* Are we in a window whose display is up to date?
-     And verify the buffer's text has not changed.  */
-  if (part == ON_TEXT
-      && EQ (w->window_end_valid, w->buffer)
-      && XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))
-      && (XFASTINT (w->last_overlay_modified)
-	  == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
-    {
-      int pos, i, nrows = w->current_matrix->nrows;
-      struct glyph_row *row;
-      struct glyph *glyph;
-
-      /* Find the glyph under X/Y.  */
-      glyph = NULL;
-      if (y >= 0 && y < nrows)
+      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 (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--)
 	{
-	  row = MATRIX_ROW (w->current_matrix, y);
-	  /* Give up if some row before the one we are looking for is
-	     not enabled.  */
-	  for (i = 0; i <= y; i++)
-	    if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
-	      break;
-	  if (i > y  /* all rows upto and including the one at Y are enabled */
-	      && row->displays_text_p
-	      && x <  window_box_width (w, TEXT_AREA))
-	    {
-	      glyph = row->glyphs[TEXT_AREA];
-	      if (x >= row->used[TEXT_AREA])
-		glyph = NULL;
-	      else
-		{
-		  glyph += x;
-		  if (!BUFFERP (glyph->object))
-		    glyph = NULL;
-		}
-	    }
-	}
-
-      /* Clear mouse face if X/Y not over text.  */
-      if (glyph == NULL)
-	{
-	  clear_mouse_face (dpyinfo);
-	  return;
+	  _farnspokeb (offset, ScreenAttrib);
+	  offset += 2;
 	}
-
-      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 (screen_virtual_segment)
+	dosv_refresh_virtual_screen (start_offset, end_hpos - start_hpos);
+      mouse_on ();
+    }
+  else if (hl == DRAW_NORMAL_TEXT)
+    {
+      /* 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;
     }
 }
 
@@ -1689,7 +1217,8 @@
 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");
@@ -1699,28 +1228,28 @@
   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)
@@ -1730,18 +1259,18 @@
 	    }
 
 	  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;
@@ -1754,25 +1283,25 @@
 
   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;
     }
 
@@ -2317,18 +1846,18 @@
 	  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 */
 	{
@@ -2916,7 +2445,7 @@
 {
   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
@@ -3126,10 +2655,10 @@
       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)
@@ -3157,10 +2686,10 @@
          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.  */
@@ -3192,8 +2721,7 @@
 	  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))
--- a/src/msdos.h	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/msdos.h	Sat Nov 06 10:28:31 2010 +0200
@@ -34,6 +34,7 @@
 char *rootrelativepath (char *);
 void init_environment (int, char **, int);
 void internal_terminal_init (void);
+void initialize_msdos_display (struct terminal *);
 
 extern int have_mouse;
 void mouse_init (void);
--- a/src/nsterm.h	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/nsterm.h	Sat Nov 06 10:28:31 2010 +0200
@@ -492,21 +492,9 @@
   /* The cursor to use for vertical scroll bars. */
   Cursor vertical_scroll_bar_cursor;
 
-  /* most mouse face stuff moved in here as of 21+ (and reasonably so) */
-  int mouse_face_beg_row, mouse_face_beg_col;
-  int mouse_face_end_row, mouse_face_end_col;
-  int mouse_face_beg_x, mouse_face_beg_y;
-  int mouse_face_end_x, mouse_face_end_y;
-  int mouse_face_past_end;
-  Lisp_Object mouse_face_window;
-  int mouse_face_face_id;
-  int mouse_face_deferred_gc;
-  Lisp_Object mouse_face_overlay;
-  FRAME_PTR mouse_face_mouse_frame;
-  int mouse_face_mouse_x, mouse_face_mouse_y;
-  int mouse_face_defer;
-  int mouse_face_hidden;
-  int mouse_face_image_state;
+  /* Information about the range of text currently shown in
+     mouse-face.  */
+  Mouse_HLInfo mouse_highlight;
 
   struct frame *x_highlight_frame;
   struct frame *x_focus_frame;
--- a/src/nsterm.m	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/nsterm.m	Sat Nov 06 10:28:31 2010 +0200
@@ -553,7 +553,7 @@
    -------------------------------------------------------------------------- */
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   NSTRACE (ns_update_window_begin);
 
   updated_window = w;
@@ -561,15 +561,15 @@
 
   BLOCK_INPUT;
 
-  if (f == dpyinfo->mouse_face_mouse_frame)
+  if (f == hlinfo->mouse_face_mouse_frame)
     {
       /* Don't do highlighting for mouse motion during the update.  */
-      dpyinfo->mouse_face_defer = 1;
+      hlinfo->mouse_face_defer = 1;
 
         /* If the frame needs to be redrawn,
            simply forget about any prior mouse highlighting.  */
       if (FRAME_GARBAGED_P (f))
-        dpyinfo->mouse_face_window = Qnil;
+        hlinfo->mouse_face_window = Qnil;
 
       /* (further code for mouse faces ifdef'd out in other terms elided) */
     }
@@ -586,7 +586,7 @@
    external (RIF) call; for one window called before update_end
    -------------------------------------------------------------------------- */
 {
-  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (XFRAME (w->frame));
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
 
   /* note: this fn is nearly identical in all terms */
   if (!w->pseudo_window_p)
@@ -608,9 +608,9 @@
      frame_up_to_date to redisplay the mouse highlight.  */
   if (mouse_face_overwritten_p)
     {
-      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;
     }
 
   updated_window = NULL;
@@ -627,8 +627,8 @@
 {
   NSView *view = FRAME_NS_VIEW (f);
 
-/*   if (f == FRAME_NS_DISPLAY_INFO (f)->mouse_face_mouse_frame) */
-    FRAME_NS_DISPLAY_INFO (f)->mouse_face_defer = 0;
+/*   if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
+    MOUSE_HL_INFO (f)->mouse_face_defer = 0;
 
   BLOCK_INPUT;
 
@@ -1032,6 +1032,7 @@
 {
   NSView *view = FRAME_NS_VIEW (f);
   struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   NSTRACE (x_destroy_window);
   check_ns ();
 
@@ -1048,13 +1049,13 @@
     dpyinfo->x_focus_frame = 0;
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
-  if (f == dpyinfo->mouse_face_mouse_frame)
+  if (f == hlinfo->mouse_face_mouse_frame)
     {
-      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_deferred_gc = 0;
-      dpyinfo->mouse_face_mouse_frame = 0;
+      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 = 0;
     }
 
   xfree (f->output_data.ns);
@@ -1772,18 +1773,18 @@
 
   if (FRAME_NS_P (f))
     {
-      struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
-      if ((dpyinfo->mouse_face_deferred_gc||f ==dpyinfo->mouse_face_mouse_frame)
-      /*&& dpyinfo->mouse_face_mouse_frame*/)
+      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+      if ((hlinfo->mouse_face_deferred_gc || f ==hlinfo->mouse_face_mouse_frame)
+      /*&& hlinfo->mouse_face_mouse_frame*/)
         {
           BLOCK_INPUT;
-         ns_update_begin(f);
-          if (dpyinfo->mouse_face_mouse_frame)
-            note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
-                                  dpyinfo->mouse_face_mouse_x,
-                                  dpyinfo->mouse_face_mouse_y);
-          dpyinfo->mouse_face_deferred_gc = 0;
-         ns_update_end(f);
+	  ns_update_begin(f);
+          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;
+	  ns_update_end(f);
           UNBLOCK_INPUT;
         }
     }
@@ -2595,8 +2596,7 @@
 
   if (s->hl == DRAW_MOUSE_FACE)
     {
-      face = FACE_FROM_ID
-        (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id);
+      face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
       if (!face)
         face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
     }
@@ -2663,8 +2663,8 @@
           struct face *face;
           if (s->hl == DRAW_MOUSE_FACE)
             {
-              face = FACE_FROM_ID
-                (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id);
+              face = FACE_FROM_ID (s->f,
+				   MOUSE_HL_INFO (s->f)->mouse_face_face_id);
               if (!face)
                 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
             }
@@ -2749,8 +2749,7 @@
      with its background color), we must clear just the image area. */
   if (s->hl == DRAW_MOUSE_FACE)
     {
-      face = FACE_FROM_ID
-       (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id);
+      face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
       if (!face)
        face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
     }
@@ -2873,8 +2872,7 @@
 
       if (s->hl == DRAW_MOUSE_FACE)
        {
-         face = FACE_FROM_ID
-           (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id);
+         face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
          if (!face)
            face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
        }
@@ -3545,6 +3543,7 @@
 {
     NSScreen *screen = [NSScreen mainScreen];
     NSWindowDepth depth = [screen depth];
+    Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 
     dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */
     dpyinfo->resy = 72.27;
@@ -3559,16 +3558,16 @@
     dpyinfo->color_table->colors = NULL;
     dpyinfo->root_window = 42; /* a placeholder.. */
 
-    dpyinfo->mouse_face_mouse_frame = NULL;
-    dpyinfo->mouse_face_deferred_gc = 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_face_id = DEFAULT_FACE_ID;
-    dpyinfo->mouse_face_window = dpyinfo->mouse_face_overlay = Qnil;
-    dpyinfo->mouse_face_hidden = 0;
-
-    dpyinfo->mouse_face_mouse_x = dpyinfo->mouse_face_mouse_y = 0;
-    dpyinfo->mouse_face_defer = 0;
+    hlinfo->mouse_face_mouse_frame = NULL;
+    hlinfo->mouse_face_deferred_gc = 0;
+    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_face_id = DEFAULT_FACE_ID;
+    hlinfo->mouse_face_window = hlinfo->mouse_face_overlay = Qnil;
+    hlinfo->mouse_face_hidden = 0;
+
+    hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0;
+    hlinfo->mouse_face_defer = 0;
 
     dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame = NULL;
 
@@ -4351,7 +4350,7 @@
 
 - (void)keyDown: (NSEvent *)theEvent
 {
-  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe);
   int code;
   unsigned fnKeysym = 0;
   int flags;
@@ -4389,10 +4388,10 @@
 
   [NSCursor setHiddenUntilMouseMoves: YES];
 
-  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 (!processingCompose)
@@ -4829,7 +4828,7 @@
 /* Tell emacs the mouse has moved. */
 - (void)mouseMoved: (NSEvent *)e
 {
-  struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe);
   Lisp_Object frame;
 
 //  NSTRACE (mouseMoved);
@@ -4839,10 +4838,10 @@
     = [self convertPoint: [e locationInWindow] fromView: nil];
 
   /* update any mouse face */
-  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);
     }
 
   /* tooltip handling */
@@ -5308,20 +5307,19 @@
 {
   NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
   NSRect r;
-  struct ns_display_info *dpyinfo
-    = emacsframe ? FRAME_NS_DISPLAY_INFO (emacsframe) : NULL;
+  Mouse_HLInfo *hlinfo = emacsframe ? MOUSE_HL_INFO (emacsframe) : NULL;
 
   NSTRACE (mouseExited);
 
-  if (!dpyinfo)
+  if (!hlinfo)
     return;
 
   last_mouse_movement_time = EV_TIMESTAMP (theEvent);
 
-  if (emacsframe == dpyinfo->mouse_face_mouse_frame)
+  if (emacsframe == hlinfo->mouse_face_mouse_frame)
     {
-      clear_mouse_face (dpyinfo);
-      dpyinfo->mouse_face_mouse_frame = 0;
+      clear_mouse_face (hlinfo);
+      hlinfo->mouse_face_mouse_frame = 0;
     }
 }
 
--- a/src/term.c	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/term.c	Sat Nov 06 10:28:31 2010 +0200
@@ -184,24 +184,10 @@
 #ifdef HAVE_GPM
 #include <sys/fcntl.h>
 
-static void term_clear_mouse_face (void);
-static void term_mouse_highlight (struct frame *f, int x, int y);
-
 /* The device for which we have enabled gpm support (or NULL).  */
 struct tty_display_info *gpm_tty = NULL;
 
-/* These variables describe the range of text currently shown in its
-   mouse-face, together with the window they apply to.  As long as
-   the mouse stays within this range, we need not redraw anything on
-   its account.  Rows and columns are glyph matrix positions in
-   MOUSE_FACE_WINDOW.  */
-static int mouse_face_beg_row, mouse_face_beg_col;
-static int mouse_face_end_row, mouse_face_end_col;
-static int mouse_face_past_end;
-static Lisp_Object mouse_face_window;
-static int mouse_face_face_id;
-
-static int pos_x, pos_y;
+/* Last recorded mouse coordinates.  */
 static int last_mouse_x, last_mouse_y;
 #endif /* HAVE_GPM */
 
@@ -2686,416 +2672,36 @@
   last_mouse_y = y;  */
 }
 
-static void
-term_show_mouse_face (enum draw_glyphs_face draw)
-{
-  struct window *w = XWINDOW (mouse_face_window);
-  int save_x, save_y;
-  int i;
-
-  struct frame *f = XFRAME (w->frame);
-  struct tty_display_info *tty = FRAME_TTY (f);
-
-  if (/* If window is in the process of being destroyed, don't bother
-	 to do anything.  */
-      w->current_matrix != NULL
-      /* Recognize when we are called to operate on rows that don't exist
-	 anymore.  This can happen when a window is split.  */
-      && mouse_face_end_row < w->current_matrix->nrows)
-    {
-      /* write_glyphs writes at cursor position, so we need to
-	 temporarily move cursor coordinates to the beginning of
-	 the highlight region.  */
-
-      /* Save current cursor co-ordinates */
-      save_y = curY (tty);
-      save_x = curX (tty);
-
-      /* Note that mouse_face_beg_row etc. are window relative.  */
-      for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
-	{
-	  int start_hpos, end_hpos, nglyphs;
-	  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 == mouse_face_beg_row)
-	    start_hpos = mouse_face_beg_col;
-	  else
-	    start_hpos = 0;
-
-	  if (i == mouse_face_end_row)
-	    end_hpos = mouse_face_end_col;
-	  else
-	    {
-	      end_hpos = row->used[TEXT_AREA];
-	      if (draw == DRAW_NORMAL_TEXT)
-		row->fill_line_p = 1; /* Clear to end of line */
-	    }
-
-	  if (end_hpos <= start_hpos)
-	    continue;
-	  /* Record that some glyphs of this row are displayed in
-	     mouse-face.  */
-	  row->mouse_face_p = draw > 0;
-
-	  nglyphs = end_hpos - start_hpos;
-
-	  if (end_hpos >= row->used[TEXT_AREA])
-	    nglyphs = row->used[TEXT_AREA] - start_hpos;
-
-	  pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
-	  pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos
-	    + WINDOW_LEFT_EDGE_X (w);
-
-	  cursor_to (f, pos_y, pos_x);
-
-	  if (draw == DRAW_MOUSE_FACE)
-	    {
-	      tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
-				      nglyphs, mouse_face_face_id);
-	    }
-	  else /* draw == DRAW_NORMAL_TEXT */
-	    write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
-	}
-      cursor_to (f, save_y, save_x);
-    }
-}
-
-static void
-term_clear_mouse_face (void)
-{
-  if (!NILP (mouse_face_window))
-    term_show_mouse_face (DRAW_NORMAL_TEXT);
-
-  mouse_face_beg_row = mouse_face_beg_col = -1;
-  mouse_face_end_row = mouse_face_end_col = -1;
-  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.
-   - taken from msdos.c */
-static int
-fast_find_position (struct window *w, EMACS_INT pos, int *hpos, int *vpos)
-{
-  int i, lastcol, maybe_next_line_p = 0;
-  EMACS_INT line_start_position;
-  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++)
-    {
-      struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
-      EMACS_INT charpos;
-
-      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;
-}
-
-static void
-term_mouse_highlight (struct frame *f, int x, int y)
+/* Implementation of draw_row_with_mouse_face for TTY/GPM.  */
+void
+tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
+			      int start_hpos, int end_hpos,
+			      enum draw_glyphs_face draw)
 {
-  enum window_part part;
-  Lisp_Object window;
-  struct window *w;
-  struct buffer *b;
-
-  if (NILP (Vmouse_highlight)
-      || !f->glyphs_initialized_p)
-    return;
-
-  /* Which window is that in?  */
-  window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
-
-  /* Not on a window -> return.  */
-  if (!WINDOWP (window))
-    return;
-
-  if (!EQ (window, mouse_face_window))
-    term_clear_mouse_face ();
-
-  w = XWINDOW (window);
-
-  /* Are we in a window whose display is up to date?
-     And verify the buffer's text has not changed.  */
-  b = XBUFFER (w->buffer);
-  if (part == ON_TEXT
-      && EQ (w->window_end_valid, w->buffer)
-      && XFASTINT (w->last_modified) == BUF_MODIFF (b)
-      && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
-    {
-      int i, nrows = w->current_matrix->nrows;
-      EMACS_INT pos;
-      struct glyph_row *row;
-      struct glyph *glyph;
-
-      /* Find the glyph under X/Y.  */
-      glyph = NULL;
-      if (y >= 0 && y < nrows)
-	{
-	  row = MATRIX_ROW (w->current_matrix, y);
-	  /* Give up if some row before the one we are looking for is
-	     not enabled.  */
-	  for (i = 0; i <= y; i++)
-	    if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
-	      break;
-	  if (i > y  /* all rows upto and including the one at Y are enabled */
-	      && row->displays_text_p
-	      && x <  window_box_width (w, TEXT_AREA))
-	    {
-	      glyph = row->glyphs[TEXT_AREA];
-	      if (x >= row->used[TEXT_AREA])
-		glyph = NULL;
-	      else
-		{
-		  glyph += x;
-		  if (!BUFFERP (glyph->object))
-		    glyph = NULL;
-		}
-	    }
-	}
-
-      /* Clear mouse face if X/Y not over text.  */
-      if (glyph == NULL)
-	{
-	  term_clear_mouse_face ();
-	  return;
-	}
-
-      if (!BUFFERP (glyph->object))
-	abort ();
-      pos = glyph->charpos;
-
-      /* Check for mouse-face.  */
-      {
-	Lisp_Object mouse_face, overlay, position, *overlay_vec;
-	int noverlays;
-	EMACS_INT obegv, ozv;
-	struct buffer *obuf;
-
-	/* If we get an out-of-range value, return now; avoid an error.  */
-	if (pos > BUF_Z (b))
-	  return;
-
-	/* Make the window's buffer temporarily current for
-	   overlays_at and compute_char_face.  */
-	obuf = current_buffer;
-	current_buffer = b;
-	obegv = BEGV;
-	ozv = ZV;
-	BEGV = BEG;
-	ZV = Z;
-
-	/* Is this char mouse-active?  */
-	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, mouse_face_window)
-	      && y >= mouse_face_beg_row
-	      && y <= mouse_face_end_row
-	      && (y > mouse_face_beg_row
-		  || x >= mouse_face_beg_col)
-	      && (y < mouse_face_end_row
-		  || x < mouse_face_end_col
-		  || mouse_face_past_end)))
-	  {
-	    /* Clear the display of the old active region, if any.  */
-	    term_clear_mouse_face ();
-
-	    /* Find the highest priority overlay that has a mouse-face
-	       property.  */
-	    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),
-				    &mouse_face_beg_col,
-				    &mouse_face_beg_row);
-
-		mouse_face_past_end
-		  = !fast_find_position (w, XFASTINT (after),
-					 &mouse_face_end_col,
-					 &mouse_face_end_row);
-		mouse_face_window = window;
-
-		mouse_face_face_id
-		  = face_at_buffer_position (w, pos, 0, 0,
-					     &ignore, pos + 1, 1, -1);
-
-		/* Display it as active.  */
-		term_show_mouse_face (DRAW_MOUSE_FACE);
-	      }
-	    /* 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 (b) - 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),
-				    &mouse_face_beg_col,
-				    &mouse_face_beg_row);
-		mouse_face_past_end
-		  = !fast_find_position (w, XFASTINT (after),
-					 &mouse_face_end_col,
-					 &mouse_face_end_row);
-		mouse_face_window = window;
-
-		mouse_face_face_id
-		  = face_at_buffer_position (w, pos, 0, 0,
-					     &ignore, pos + 1, 1, -1);
-
-		/* Display it as active.  */
-		term_show_mouse_face (DRAW_MOUSE_FACE);
-	      }
-	  }
-
-	/* 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;
-      }
-    }
+  int nglyphs = end_hpos - start_hpos;
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct tty_display_info *tty = FRAME_TTY (f);
+  int face_id = tty->mouse_highlight.mouse_face_face_id;
+  int save_x, save_y, pos_x, pos_y;
+
+  if (end_hpos >= row->used[TEXT_AREA])
+    nglyphs = row->used[TEXT_AREA] - start_hpos;
+
+  pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
+  pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
+
+  /* Save current cursor co-ordinates.  */
+  save_y = curY (tty);
+  save_x = curX (tty);
+  cursor_to (f, pos_y, pos_x);
+
+  if (draw == DRAW_MOUSE_FACE)
+    tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
+				nglyphs, face_id);
+  else if (draw == DRAW_NORMAL_TEXT)
+    write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
+
+  cursor_to (f, save_y, save_x);
 }
 
 static int
@@ -3105,7 +2711,7 @@
   if (event->x != last_mouse_x || event->y != last_mouse_y)
     {
       frame->mouse_moved = 1;
-      term_mouse_highlight (frame, event->x, event->y);
+      note_mouse_highlight (frame, event->x, event->y);
       /* Remember which glyph we're now on.  */
       last_mouse_x = event->x;
       last_mouse_y = event->y;
@@ -3576,7 +3182,7 @@
 
 #ifdef HAVE_GPM
   terminal->mouse_position_hook = term_mouse_position;
-  mouse_face_window = Qnil;
+  tty->mouse_highlight.mouse_face_window = Qnil;
 #endif
 
   
@@ -4211,8 +3817,6 @@
 #ifdef HAVE_GPM
   defsubr (&Sgpm_mouse_start);
   defsubr (&Sgpm_mouse_stop);
-
-  staticpro (&mouse_face_window);
 #endif /* HAVE_GPM */
 
 #ifndef DOS_NT
--- a/src/termchar.h	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/termchar.h	Sat Nov 06 10:28:31 2010 +0200
@@ -34,18 +34,18 @@
 struct tty_display_info
 {
   struct tty_display_info *next; /* Chain of all tty devices. */
-  
+
   char *name;                   /* The name of the device file or 0 if
                                    stdin/stdout. */
   char *type;                   /* The type of the tty. */
-  
+
   /* Input/output */
-  
+
   FILE *input;                  /* The stream to be used for terminal input.
                                    NULL if the terminal is suspended. */
   FILE *output;                 /* The stream to be used for terminal output.
                                    NULL if the terminal is suspended. */
-  
+
   FILE *termscript;             /* If nonzero, send all terminal output
                                    characters to this stream also.  */
 
@@ -65,38 +65,14 @@
   /* Redisplay. */
 
   Lisp_Object top_frame;        /* The topmost frame on this tty. */
-  
+
   /* The previous frame we displayed on this tty.  */
   struct frame *previous_frame;
   int previous_color_mode;
 
-#ifdef MSDOS
-  /* These variables describe the range of text currently shown in its
-     mouse-face, together with the window they apply to.  As long as
-     the mouse stays within this range, we need not redraw anything on
-     its account.  Rows and columns are glyph matrix positions in
-     MOUSE_FACE_WINDOW.  */
-  int mouse_face_beg_row, mouse_face_beg_col;
-  int mouse_face_end_row, mouse_face_end_col;
-  int mouse_face_past_end;
-  Lisp_Object mouse_face_window;
-  int mouse_face_face_id;
-
-  /* 1 if a mouse motion event came and we didn't handle it right away because
-     gc was in progress.  */
-  int mouse_face_deferred_gc;
-
-  /* FRAME and X, Y position of mouse when last checked for
-     highlighting.  X and Y can be negative or out of range for the frame.  */
-  struct frame *mouse_face_mouse_frame;
-  int mouse_face_mouse_x, mouse_face_mouse_y;
-
-  /* Nonzero means defer mouse-motion highlighting.  */
-  int mouse_face_defer;
-
-  /* Nonzero means that the mouse highlight should not be shown.  */
-  int mouse_face_hidden;
-#endif	/* !MSDOS */
+  /* Information about the range of text currently shown in
+     mouse-face.  */
+  Mouse_HLInfo mouse_highlight;
 
   /* Buffer used internally by termcap (see tgetent in the Termcap
      manual).  Only init_tty and delete_tty should change this.  */
@@ -190,12 +166,12 @@
   int RPov;                     /* # chars to start a TS_repeat */
 
   int delete_in_insert_mode;    /* delete mode == insert mode */
-  
+
   int se_is_so;                 /* 1 if same string both enters and leaves
                                    standout mode */
-  
+
   int costs_set;                /* Nonzero if costs have been calculated. */
-  
+
   int insert_mode;              /* Nonzero when in insert mode.  */
   int standout_mode;            /* Nonzero when in standout mode.  */
 
@@ -214,7 +190,7 @@
    lines from those operations.  */
 
   int specified_window;
-  
+
   /* Flag used in tty_show/hide_cursor.  */
 
   int cursor_hidden;
--- a/src/w32term.c	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/w32term.c	Sat Nov 06 10:28:31 2010 +0200
@@ -505,7 +505,7 @@
 x_update_window_begin (struct window *w)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
 
   /* Hide the system caret during an update.  */
   if (w32_use_visible_system_caret && w32_system_caret_hwnd)
@@ -518,15 +518,15 @@
 
   BLOCK_INPUT;
 
-  if (f == display_info->mouse_face_mouse_frame)
+  if (f == hlinfo->mouse_face_mouse_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;
 
 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
 	 their mouse_face_p flag set, which means that they are always
@@ -540,8 +540,8 @@
 	 Likewise, don't do anything if the frame is garbaged;
 	 in that case, the frame's current matrix that we would use
 	 is all wrong, and we will redisplay that line anyway.  */
-      if (!NILP (display_info->mouse_face_window)
-	  && w == XWINDOW (display_info->mouse_face_window))
+      if (!NILP (hlinfo->mouse_face_window)
+	  && w == XWINDOW (hlinfo->mouse_face_window))
 	{
 	  int i;
 
@@ -550,7 +550,7 @@
 	      break;
 
 	  if (i < w->desired_matrix->nrows)
-	    clear_mouse_face (display_info);
+	    clear_mouse_face (hlinfo);
 	}
 #endif /* 0 */
     }
@@ -601,7 +601,7 @@
 x_update_window_end (struct window *w, int cursor_on_p,
 		     int mouse_face_overwritten_p)
 {
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
 
   if (!w->pseudo_window_p)
     {
@@ -622,9 +622,9 @@
      XTframe_up_to_date to redisplay the mouse highlight.  */
   if (mouse_face_overwritten_p)
     {
-      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;
     }
 
   /* Unhide the caret.  This won't actually show the cursor, unless it
@@ -649,7 +649,7 @@
     return;
 
   /* Mouse highlight may be displayed again.  */
-  FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
+  MOUSE_HL_INFO (f)->mouse_face_defer = 0;
 }
 
 
@@ -662,17 +662,17 @@
 {
   if (FRAME_W32_P (f))
     {
-      struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-
-      if (dpyinfo->mouse_face_deferred_gc
-	  || f == dpyinfo->mouse_face_mouse_frame)
+      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+      if (hlinfo->mouse_face_deferred_gc
+	  || f == hlinfo->mouse_face_mouse_frame)
 	{
 	  BLOCK_INPUT;
-	  if (dpyinfo->mouse_face_mouse_frame)
-	    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;
 	}
     }
@@ -999,7 +999,7 @@
   struct face *face;
 
   /* What face has to be used last for the mouse face?  */
-  face_id = FRAME_W32_DISPLAY_INFO (s->f)->mouse_face_face_id;
+  face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
   face = FACE_FROM_ID (s->f, face_id);
   if (face == NULL)
     face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
@@ -4060,6 +4060,7 @@
   W32Msg msg;
   struct frame *f;
   struct w32_display_info *dpyinfo = &one_w32_display_info;
+  Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 
   if (interrupt_input_blocked)
     {
@@ -4160,11 +4161,11 @@
 
 	  if (f && !f->iconified)
 	    {
-	      if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
-		  && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+	      if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+		  && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
 		{
-		  clear_mouse_face (dpyinfo);
-		  dpyinfo->mouse_face_hidden = 1;
+		  clear_mouse_face (hlinfo);
+		  hlinfo->mouse_face_hidden = 1;
 		}
 
 	      if (temp_index == sizeof temp_buffer / sizeof (short))
@@ -4185,11 +4186,11 @@
 
 	  if (f && !f->iconified)
 	    {
-	      if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
-		  && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+	      if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+		  && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
 		{
-		  clear_mouse_face (dpyinfo);
-		  dpyinfo->mouse_face_hidden = 1;
+		  clear_mouse_face (hlinfo);
+		  hlinfo->mouse_face_hidden = 1;
 		}
 
 	      if (temp_index == sizeof temp_buffer / sizeof (short))
@@ -4263,11 +4264,11 @@
 
 	  if (f && !f->iconified)
 	    {
-	      if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
-		  && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+	      if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+		  && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
 		{
-		  clear_mouse_face (dpyinfo);
-		  dpyinfo->mouse_face_hidden = 1;
+		  clear_mouse_face (hlinfo);
+		  hlinfo->mouse_face_hidden = 1;
 		}
 
 	      if (temp_index == sizeof temp_buffer / sizeof (short))
@@ -4301,10 +4302,10 @@
 	  else
 	    f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
 
-	  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);
 	    }
 
 	  if (f)
@@ -4345,7 +4346,7 @@
             {
               /* If we move outside the frame, then we're
                  certainly no longer on any text in the frame.  */
-              clear_mouse_face (dpyinfo);
+              clear_mouse_face (hlinfo);
             }
 
           /* If the contents of the global variable help_echo_string
@@ -4634,12 +4635,12 @@
 	  f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
 	  if (f)
 	    {
-	      if (f == dpyinfo->mouse_face_mouse_frame)
+	      if (f == hlinfo->mouse_face_mouse_frame)
 		{
 		  /* If we move outside the frame, then we're
 		     certainly no longer on any text in the frame.  */
-		  clear_mouse_face (dpyinfo);
-		  dpyinfo->mouse_face_mouse_frame = 0;
+		  clear_mouse_face (hlinfo);
+		  hlinfo->mouse_face_mouse_frame = 0;
 		}
 
 	      /* Generate a nil HELP_EVENT to cancel a help-echo.
@@ -4669,12 +4670,12 @@
               if (f == dpyinfo->w32_focus_frame)
                 x_new_focus_frame (dpyinfo, 0);
 
-              if (f == dpyinfo->mouse_face_mouse_frame)
+              if (f == hlinfo->mouse_face_mouse_frame)
                 {
                   /* If we move outside the frame, then we're
                      certainly no longer on any text in the frame.  */
-                  clear_mouse_face (dpyinfo);
-                  dpyinfo->mouse_face_mouse_frame = 0;
+                  clear_mouse_face (hlinfo);
+                  hlinfo->mouse_face_mouse_frame = 0;
                 }
 
               /* Generate a nil HELP_EVENT to cancel a help-echo.
@@ -5822,6 +5823,7 @@
 x_free_frame_resources (struct frame *f)
 {
   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
 
   BLOCK_INPUT;
 
@@ -5860,15 +5862,15 @@
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
 
-  if (f == dpyinfo->mouse_face_mouse_frame)
+  if (f == hlinfo->mouse_face_mouse_frame)
     {
-      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_deferred_gc = 0;
-      dpyinfo->mouse_face_mouse_frame = 0;
+      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 = 0;
     }
 
   UNBLOCK_INPUT;
@@ -5934,6 +5936,7 @@
 w32_initialize_display_info (Lisp_Object display_name)
 {
   struct w32_display_info *dpyinfo = &one_w32_display_info;
+  Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 
   memset (dpyinfo, 0, sizeof (*dpyinfo));
 
@@ -5959,12 +5962,12 @@
   dpyinfo->smallest_font_height = 1;
   dpyinfo->smallest_char_width = 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_face_id = DEFAULT_FACE_ID;
-  dpyinfo->mouse_face_window = Qnil;
-  dpyinfo->mouse_face_overlay = Qnil;
-  dpyinfo->mouse_face_hidden = 0;
+  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_face_id = DEFAULT_FACE_ID;
+  hlinfo->mouse_face_window = Qnil;
+  hlinfo->mouse_face_overlay = Qnil;
+  hlinfo->mouse_face_hidden = 0;
 
   dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
   /* TODO: dpyinfo->gray */
--- a/src/w32term.h	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/w32term.h	Sat Nov 06 10:28:31 2010 +0200
@@ -143,36 +143,9 @@
   /* Reusable Graphics Context for drawing a cursor in a non-default face. */
   XGCValues *scratch_cursor_gc;
 
-  /* These variables describe the range of text currently shown in its
-     mouse-face, together with the window they apply to. As long as
-     the mouse stays within this range, we need not redraw anything on
-     its account.  Rows and columns are glyph matrix positions in
-     MOUSE_FACE_WINDOW.  */
-  int mouse_face_beg_row, mouse_face_beg_col;
-  int mouse_face_beg_x, mouse_face_beg_y;
-  int mouse_face_end_row, mouse_face_end_col;
-  int mouse_face_end_x, mouse_face_end_y;
-  int mouse_face_past_end;
-  Lisp_Object mouse_face_window;
-  int mouse_face_face_id;
-  Lisp_Object mouse_face_overlay;
-
-  /* 1 if a mouse motion event came and we didn't handle it right away because
-     gc was in progress.  */
-  int mouse_face_deferred_gc;
-
-  /* FRAME and X, Y position of mouse when last checked for
-     highlighting.  X and Y can be negative or out of range for the frame.  */
-  struct frame *mouse_face_mouse_frame;
-  int mouse_face_mouse_x, mouse_face_mouse_y;
-
-  /* Nonzero means defer mouse-motion highlighting.  */
-  int mouse_face_defer;
-
-  /* Nonzero means that the mouse highlight should not be shown.  */
-  int mouse_face_hidden;
-
-  int mouse_face_image_state;
+  /* Information about the range of text currently shown in
+     mouse-face.  */
+  Mouse_HLInfo mouse_highlight;
 
   char *w32_id_name;
 
--- a/src/xdisp.c	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/xdisp.c	Sat Nov 06 10:28:31 2010 +0200
@@ -888,6 +888,9 @@
 #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 +916,6 @@
 
 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.  */
@@ -975,10 +974,8 @@
 					  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 +1088,8 @@
 
 #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 +1099,13 @@
                                        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);
+
+
 
 /***********************************************************************
 		      Window display dimensions
@@ -1797,8 +1797,6 @@
 }
 
 
-#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 +1879,6 @@
   return glyph;
 }
 
-
 /* EXPORT:
    Convert frame-relative x/y to coordinates relative to window W.
    Takes pseudo-windows into account.  */
@@ -1904,6 +1901,8 @@
     }
 }
 
+#ifdef HAVE_WINDOW_SYSTEM
+
 /* EXPORT:
    Return in RECTS[] at most N clipping rectangles for glyph string S.
    Return the number of stored rectangles.  */
@@ -10818,7 +10817,7 @@
 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 +10832,14 @@
     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 +10856,7 @@
 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 +10875,8 @@
   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 +10886,8 @@
       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 +10917,7 @@
   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 +10931,7 @@
      values when mouse moves outside of the frame.  */
   if (x <= 0 || y <= 0)
     {
-      clear_mouse_face (dpyinfo);
+      clear_mouse_face (hlinfo);
       return;
     }
 
@@ -10939,14 +10939,14 @@
   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 +10956,7 @@
       && 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 +10970,22 @@
 	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:
@@ -15985,6 +15985,9 @@
 		     + (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 +21445,7 @@
   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 +21455,16 @@
 	{
 	  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];
 	    }
 	}
@@ -23400,6 +23403,8 @@
 }
 
 
+#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 +23450,7 @@
 
   /* 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 +23491,6 @@
   /* 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 +23518,6 @@
 	      cursor_type = HOLLOW_BOX_CURSOR;
 	    }
       }
-#endif
       return cursor_type;
     }
 
@@ -23559,8 +23559,6 @@
 }
 
 
-#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 +23724,7 @@
 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 +23780,7 @@
 
   /* 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 +23972,50 @@
     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)
-{
-  struct window *w = XWINDOW (dpyinfo->mouse_face_window);
+show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
+{
+  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 +24030,13 @@
 		 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 +24046,8 @@
 	    }
 	  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 +24058,9 @@
 	  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 +24069,7 @@
 		}
 	    }
 	  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 +24079,19 @@
 
 	  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 +24099,22 @@
 				  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 +24123,20 @@
    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))
-    {
-      show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
+  if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
+    {
+      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 +24145,43 @@
 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 (dpyinfo->mouse_face_beg_col <= hpos && hpos < dpyinfo->mouse_face_end_col)
+      if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
+	{
+	  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 (dpyinfo->mouse_face_end_col < hpos && hpos <= dpyinfo->mouse_face_beg_col)
+       if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
+	{
+	  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 +24322,7 @@
     }
 }
 
-/* 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 +24333,7 @@
 
 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 +24378,7 @@
   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 +24407,10 @@
       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 +24458,19 @@
 					    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 +24508,13 @@
 	      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 +24522,8 @@
       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 +24572,13 @@
 	  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 +24586,8 @@
       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 +24622,27 @@
 	  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];
-    }
-
-  dpyinfo->mouse_face_window = window;
-  dpyinfo->mouse_face_face_id
+      hlinfo->mouse_face_end_x = x;
+      hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
+    }
+
+  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 +24731,11 @@
 
 /* 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 +24760,10 @@
 	    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 +24778,12 @@
 	    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 +24817,8 @@
   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 +24830,11 @@
 	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,10 +24847,12 @@
 	    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.  */
 
@@ -24996,6 +25024,8 @@
     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 +25038,13 @@
 {
   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;
+  Cursor cursor;
+#else
+  Cursor cursor = No_Cursor;
+#endif
   Lisp_Object pointer = Qnil;
   int dx, dy, width, height;
   EMACS_INT charpos;
@@ -25061,6 +25096,7 @@
 
   help = Qnil;
 
+#ifdef HAVE_WINDOW_SYSTEM
   if (IMAGEP (object))
     {
       Lisp_Object image_map, hotspot;
@@ -25097,6 +25133,7 @@
       if (NILP (pointer))
 	pointer = Fplist_get (XCDR (object), QCpointer);
     }
+#endif	/* HAVE_WINDOW_SYSTEM */
 
   if (STRINGP (string))
     {
@@ -25116,19 +25153,27 @@
 	    }
 	}
 
-      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;
-	}
+#ifdef HAVE_WINDOW_SYSTEM
+      if (FRAME_WINDOW_P (f))
+	{
+	  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 +25253,63 @@
 
 	  /* 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;
-	    }
-
-	  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_col = hpos + gseq_length;
+	      hlinfo->mouse_face_beg_x   = 0;
+	    }
+
+	  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);
-    }
-  define_frame_cursor1 (f, cursor, pointer);
+	clear_mouse_face (hlinfo);
+    }
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
+    define_frame_cursor1 (f, cursor, pointer);
+#endif
 }
 
 
@@ -25274,7 +25322,7 @@
 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 +25331,7 @@
   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,16 +25341,16 @@
       || f->pointer_invisible)
     return;
 
-  dpyinfo->mouse_face_mouse_x = x;
-  dpyinfo->mouse_face_mouse_y = y;
-  dpyinfo->mouse_face_mouse_frame = f;
-
-  if (dpyinfo->mouse_face_defer)
+  hlinfo->mouse_face_mouse_x = x;
+  hlinfo->mouse_face_mouse_y = y;
+  hlinfo->mouse_face_mouse_frame = f;
+
+  if (hlinfo->mouse_face_defer)
     return;
 
   if (gc_in_progress)
     {
-      dpyinfo->mouse_face_deferred_gc = 1;
+      hlinfo->mouse_face_deferred_gc = 1;
       return;
     }
 
@@ -25311,10 +25359,10 @@
 
   /* 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 +25375,7 @@
   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 +25383,7 @@
       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 +25393,7 @@
       return;
     }
 
+#ifdef HAVE_WINDOW_SYSTEM
   if (part == ON_VERTICAL_BORDER)
     {
       cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
@@ -25353,6 +25404,7 @@
     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 +25428,7 @@
       /* 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 +25470,18 @@
 		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 +25491,17 @@
 	      && 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 +25547,8 @@
 	     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 +25561,12 @@
 
 	  /* 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 +25590,14 @@
 		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 +25672,7 @@
 		      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 +25751,9 @@
 	  }
       }
 
+#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 +25792,7 @@
 					      Qpointer, object);
 	    }
 	}
+#endif	/* HAVE_WINDOW_SYSTEM */
 
       BEGV = obegv;
       ZV = ozv;
@@ -25737,7 +25801,14 @@
 
  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 +25820,13 @@
 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,19 +25839,17 @@
 cancel_mouse_face (struct frame *f)
 {
   Lisp_Object window;
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-
-  window = dpyinfo->mouse_face_window;
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+  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;
-    }
-}
-
-
-#endif /* HAVE_WINDOW_SYSTEM */
+      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;
+    }
+}
+
 
 
 /***********************************************************************
@@ -26238,12 +26307,12 @@
      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)
-	{
-	  int x = dpyinfo->mouse_face_mouse_x;
-	  int y = dpyinfo->mouse_face_mouse_y;
-	  clear_mouse_face (dpyinfo);
+      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+      if (f == hlinfo->mouse_face_mouse_frame)
+	{
+	  int x = hlinfo->mouse_face_mouse_x;
+	  int y = hlinfo->mouse_face_mouse_y;
+	  clear_mouse_face (hlinfo);
 	  note_mouse_highlight (f, x, y);
 	}
     }
--- a/src/xmenu.c	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/xmenu.c	Sat Nov 06 10:28:31 2010 +0200
@@ -2533,13 +2533,16 @@
 
 #endif /* HAVE_MENUS */
 
-/* Detect if a dialog or menu has been posted.  */
+#ifndef MSDOS
+/* Detect if a dialog or menu has been posted.  MSDOS has its own
+   implementation on msdos.c.  */
 
 int
 popup_activated (void)
 {
   return popup_activated_flag;
 }
+#endif	/* not MSDOS */
 
 /* The following is used by delayed window autoselection.  */
 
--- a/src/xterm.c	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/xterm.c	Sat Nov 06 10:28:31 2010 +0200
@@ -548,22 +548,22 @@
 x_update_window_begin (struct window *w)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  struct x_display_info *display_info = FRAME_X_DISPLAY_INFO (f);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
 
   updated_window = w;
   set_output_cursor (&w->cursor);
 
   BLOCK_INPUT;
 
-  if (f == display_info->mouse_face_mouse_frame)
+  if (f == hlinfo->mouse_face_mouse_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;
     }
 
   UNBLOCK_INPUT;
@@ -603,7 +603,7 @@
 static void
 x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritten_p)
 {
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
 
   if (!w->pseudo_window_p)
     {
@@ -624,9 +624,9 @@
      XTframe_up_to_date to redisplay the mouse highlight.  */
   if (mouse_face_overwritten_p)
     {
-      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;
     }
 
   updated_window = NULL;
@@ -640,7 +640,7 @@
 x_update_end (struct frame *f)
 {
   /* Mouse highlight may be displayed again.  */
-  FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
+  MOUSE_HL_INFO (f)->mouse_face_defer = 0;
 
 #ifndef XFlush
   BLOCK_INPUT;
@@ -659,17 +659,17 @@
 {
   if (FRAME_X_P (f))
     {
-      struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-
-      if (dpyinfo->mouse_face_deferred_gc
-	  || f == dpyinfo->mouse_face_mouse_frame)
+      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+      if (hlinfo->mouse_face_deferred_gc
+	  || f == hlinfo->mouse_face_mouse_frame)
 	{
 	  BLOCK_INPUT;
-	  if (dpyinfo->mouse_face_mouse_frame)
-	    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;
 	}
     }
@@ -970,7 +970,7 @@
   struct face *face;
 
   /* What face has to be used last for the mouse face?  */
-  face_id = FRAME_X_DISPLAY_INFO (s->f)->mouse_face_face_id;
+  face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
   face = FACE_FROM_ID (s->f, face_id);
   if (face == NULL)
     face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
@@ -5788,6 +5788,7 @@
   struct frame *f = NULL;
   struct coding_system coding;
   XEvent event = *eventp;
+  Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 
   *finish = X_EVENT_NORMAL;
 
@@ -6237,12 +6238,12 @@
 
       /* If mouse-highlight is an integer, input clears out
 	 mouse highlighting.  */
-      if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+      if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
 	  && (f == 0
-	      || !EQ (f->tool_bar_window, dpyinfo->mouse_face_window)))
+	      || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)))
         {
-          clear_mouse_face (dpyinfo);
-          dpyinfo->mouse_face_hidden = 1;
+          clear_mouse_face (hlinfo);
+          hlinfo->mouse_face_hidden = 1;
         }
 
 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
@@ -6599,12 +6600,12 @@
       f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
       if (f)
         {
-          if (f == dpyinfo->mouse_face_mouse_frame)
+          if (f == hlinfo->mouse_face_mouse_frame)
             {
               /* If we move outside the frame, then we're
                  certainly no longer on any text in the frame.  */
-              clear_mouse_face (dpyinfo);
-              dpyinfo->mouse_face_mouse_frame = 0;
+              clear_mouse_face (hlinfo);
+              hlinfo->mouse_face_mouse_frame = 0;
             }
 
           /* Generate a nil HELP_EVENT to cancel a help-echo.
@@ -6637,10 +6638,10 @@
         else
           f = x_window_to_frame (dpyinfo, event.xmotion.window);
 
-        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);
           }
 
 #ifdef USE_GTK
@@ -6695,7 +6696,7 @@
 
             /* If we move outside the frame, then we're
                certainly no longer on any text in the frame.  */
-            clear_mouse_face (dpyinfo);
+            clear_mouse_face (hlinfo);
           }
 
         /* If the contents of the global variable help_echo_string
@@ -9385,6 +9386,7 @@
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Lisp_Object bar;
   struct scroll_bar *b;
+  Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 
   BLOCK_INPUT;
 
@@ -9478,15 +9480,15 @@
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
 
-  if (f == dpyinfo->mouse_face_mouse_frame)
-    {
-      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_deferred_gc = 0;
-      dpyinfo->mouse_face_mouse_frame = 0;
+  if (f == hlinfo->mouse_face_mouse_frame)
+    {
+      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 = 0;
     }
 
   UNBLOCK_INPUT;
@@ -9863,6 +9865,7 @@
   struct terminal *terminal;
   struct x_display_info *dpyinfo;
   XrmDatabase xrdb;
+  Mouse_HLInfo *hlinfo;
 
   BLOCK_INPUT;
 
@@ -9993,6 +9996,7 @@
 
   dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info));
   memset (dpyinfo, 0, sizeof *dpyinfo);
+  hlinfo = &dpyinfo->mouse_highlight;
 
   terminal = x_create_terminal (dpyinfo);
 
@@ -10115,16 +10119,16 @@
   dpyinfo->bitmaps_size = 0;
   dpyinfo->bitmaps_last = 0;
   dpyinfo->scratch_cursor_gc = 0;
-  dpyinfo->mouse_face_mouse_frame = 0;
-  dpyinfo->mouse_face_deferred_gc = 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_face_id = DEFAULT_FACE_ID;
-  dpyinfo->mouse_face_window = Qnil;
-  dpyinfo->mouse_face_overlay = Qnil;
-  dpyinfo->mouse_face_mouse_x = dpyinfo->mouse_face_mouse_y = 0;
-  dpyinfo->mouse_face_defer = 0;
-  dpyinfo->mouse_face_hidden = 0;
+  hlinfo->mouse_face_mouse_frame = 0;
+  hlinfo->mouse_face_deferred_gc = 0;
+  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_face_id = DEFAULT_FACE_ID;
+  hlinfo->mouse_face_window = Qnil;
+  hlinfo->mouse_face_overlay = Qnil;
+  hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0;
+  hlinfo->mouse_face_defer = 0;
+  hlinfo->mouse_face_hidden = 0;
   dpyinfo->x_focus_frame = 0;
   dpyinfo->x_focus_event_frame = 0;
   dpyinfo->x_highlight_frame = 0;
--- a/src/xterm.h	Fri Nov 05 15:30:18 2010 -0400
+++ b/src/xterm.h	Sat Nov 06 10:28:31 2010 +0200
@@ -190,36 +190,9 @@
   /* Reusable Graphics Context for drawing a cursor in a non-default face. */
   GC scratch_cursor_gc;
 
-  /* These variables describe the range of text currently shown in its
-     mouse-face, together with the window they apply to.  As long as
-     the mouse stays within this range, we need not redraw anything on
-     its account.  Rows and columns are glyph matrix positions in
-     MOUSE_FACE_WINDOW.  */
-  int mouse_face_beg_row, mouse_face_beg_col;
-  int mouse_face_beg_x, mouse_face_beg_y;
-  int mouse_face_end_row, mouse_face_end_col;
-  int mouse_face_end_x, mouse_face_end_y;
-  int mouse_face_past_end;
-  Lisp_Object mouse_face_window;
-  int mouse_face_face_id;
-  Lisp_Object mouse_face_overlay;
-
-  /* 1 if a mouse motion event came and we didn't handle it right away because
-     gc was in progress.  */
-  int mouse_face_deferred_gc;
-
-  /* FRAME and X, Y position of mouse when last checked for
-     highlighting.  X and Y can be negative or out of range for the frame.  */
-  struct frame *mouse_face_mouse_frame;
-  int mouse_face_mouse_x, mouse_face_mouse_y;
-
-  /* Nonzero means defer mouse-motion highlighting.  */
-  int mouse_face_defer;
-
-  /* Nonzero means that the mouse highlight should not be shown.  */
-  int mouse_face_hidden;
-
-  int mouse_face_image_state;
+  /* Information about the range of text currently shown in
+     mouse-face.  */
+  Mouse_HLInfo mouse_highlight;
 
   char *x_id_name;