changeset 30240:2c2a7ebd2c15

(help_echo_object, help_echo_pos): New variables. (note_mode_line_highlight): Store additional information about the help-echo in help_echo_object and help_echo_pos. Check both `local-map' and `keymap' properties for changing the cursor (note_mouse_highlight): Store additional information about the help-echo in help_echo_object and help_echo_pos. (note_tool_bar_highlight): Set help_echo_object to nil and help_echo_pos to -1. (w32_read_socket): Use gen_help_event instead of filling input_events manually. (syms_of_w32term): Staticpro help_echo_object. (x_update_window_end): Add parameter MOUSE_FACE_OVERWRITTEN_P. If set, arrange for a mouse-highlight redisplay in XTframe_up_to_date. (x_clear_mouse_face): New function. (w32_redisplay_interface): Add pointer to x_clear_mouse_face. (x_update_window_begin): No need to turn off the mouse highlight here. (show_mouse_face): Set the mouse_face_p flag of glyph rows depending on whether they contain glyphs highlighted in mouse-face. (x_fill_stretch_glyph_string): Consume runs of stretch glyphs instead of a single one. (BUILD_STRETCH_GLYPH_STRING): Call x_fill_stretch_glyph_string with new argument list. (x_set_glyph_string_gc): Make sure the face's GC is valid. (x_append_glyph, x_append_composite_glyph) (x_produce_image_glyph, x_append_stretch_glyph): Accomodate to changes in struct glyph starting 1999-12-27. See comments for xterm.c on 2000-07-05.
author Jason Rumney <jasonr@gnu.org>
date Sat, 15 Jul 2000 12:00:51 +0000
parents 6a55bd8a85f8
children 6d37357647d2
files src/w32term.c
diffstat 1 files changed, 240 insertions(+), 145 deletions(-) [+]
line wrap: on
line diff
--- a/src/w32term.c	Sat Jul 15 11:56:03 2000 +0000
+++ b/src/w32term.c	Sat Jul 15 12:00:51 2000 +0000
@@ -161,6 +161,8 @@
    (The display is done in read_char.)  */
    
 static Lisp_Object help_echo;
+static Lisp_Object help_echo_object;
+static int help_echo_pos;
 
 /* Temporary variable for w32_read_socket.  */
 
@@ -593,6 +595,13 @@
       if (FRAME_GARBAGED_P (f))
 	display_info->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
+	 unequal to rows in a desired matrix which never have that
+	 flag set.  So, rows containing mouse-face glyphs are never
+	 scrolled, and we don't have to switch the mouse highlight off
+	 here to prevent it from being scrolled.  */
+      
       /* 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 the frame is garbaged;
@@ -610,6 +619,7 @@
 	  if (i < w->desired_matrix->nrows)
 	    clear_mouse_face (display_info);
 	}
+#endif /* 0 */
     }
 
   UNBLOCK_INPUT;
@@ -647,20 +657,40 @@
 }
 
    
-/* End update of window W (which is equal to updated_window).  Draw
-   vertical borders between horizontally adjacent windows, and display
-   W's cursor if CURSOR_ON_P is non-zero.  W may be a menu bar
-   pseudo-window in case we don't have X toolkit support.  Such
-   windows don't have a cursor, so don't display it here.  */
+/* End update of window W (which is equal to updated_window).
+
+   Draw vertical borders between horizontally adjacent windows, and
+   display W's cursor if CURSOR_ON_P is non-zero.
+
+   MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
+   glyphs in mouse-face were overwritten.  In that case we have to
+   make sure that the mouse-highlight is properly redrawn.
+
+   W may be a menu bar pseudo-window in case we don't have X toolkit
+   support. Such windows don't have a cursor, so don't display it
+   here. */
 
 static void
-x_update_window_end (w, cursor_on_p)
+x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
      struct window *w;
-     int cursor_on_p;
+     int cursor_on_p, mouse_face_overwritten_p;
 {
   if (!w->pseudo_window_p)
     {
+      struct w32_display_info *dpyinfo
+        = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
+
       BLOCK_INPUT;
+
+      /* If a row with mouse-face was overwritten, arrange for
+	 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;
+	}
+
       if (cursor_on_p)
 	x_display_and_set_cursor (w, 1, output_cursor.hpos,
 				  output_cursor.vpos,
@@ -1428,24 +1458,21 @@
   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
-      /* Play it safe.  If sub-structures of the glyph are not all the
-	 same size, it otherwise be that some bits stay set.  This
-	 would prevent a comparison with GLYPH_EQUAL_P.  */
-      glyph->u.val = 0;
-      
-      glyph->type = CHAR_GLYPH;
-      glyph->pixel_width = it->pixel_width;
-      glyph->u.ch = it->char_to_display;
-      glyph->face_id = it->face_id;
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
+      glyph->pixel_width = it->pixel_width;
+      glyph->voffset = it->voffset;
+      glyph->type = CHAR_GLYPH;
+      glyph->multibyte_p = it->multibyte_p;
       glyph->left_box_line_p = it->start_of_box_run_p;
       glyph->right_box_line_p = it->end_of_box_run_p;
-      glyph->voffset = it->voffset;
-      glyph->multibyte_p = it->multibyte_p;
       glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
 				      || it->phys_descent > it->descent);
+      glyph->padding_p = 0;
       glyph->glyph_not_available_p = it->glyph_not_available_p;
+      glyph->face_id = it->face_id;
+      glyph->u.ch = it->char_to_display;
+      glyph->w32_font_type = UNKNOWN_FONT;
       ++it->glyph_row->used[area];
     }
 }
@@ -1465,23 +1492,21 @@
   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
-      /* Play it safe.  If sub-structures of the glyph are not all the
-	 same size, it otherwise be that some bits stay set.  This
-	 would prevent a comparison with GLYPH_EQUAL_P.  */
-      glyph->u.val = 0;
-      
-      glyph->type = COMPOSITE_GLYPH;
-      glyph->pixel_width = it->pixel_width;
-      glyph->u.cmp_id = it->cmp_id;
-      glyph->face_id = it->face_id;
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
+      glyph->pixel_width = it->pixel_width;
+      glyph->voffset = it->voffset;
+      glyph->type = COMPOSITE_GLYPH;
+      glyph->multibyte_p = it->multibyte_p;
       glyph->left_box_line_p = it->start_of_box_run_p;
       glyph->right_box_line_p = it->end_of_box_run_p;
-      glyph->voffset = it->voffset;
-      glyph->multibyte_p = it->multibyte_p;
       glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
 				      || it->phys_descent > it->descent);
+      glyph->padding_p = 0;
+      glyph->glyph_not_available_p = 0;
+      glyph->face_id = it->face_id;
+      glyph->u.cmp_id = it->cmp_id;
+      glyph->w32_font_type = UNKNOWN_FONT;
       ++it->glyph_row->used[area];
     }
 }
@@ -1556,16 +1581,20 @@
       glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
       if (glyph < it->glyph_row->glyphs[area + 1])
 	{
-	  glyph->type = IMAGE_GLYPH;
-	  glyph->u.img_id = img->id;
-	  glyph->face_id = it->face_id;
-	  glyph->pixel_width = it->pixel_width;
 	  glyph->charpos = CHARPOS (it->position);
 	  glyph->object = it->object;
+	  glyph->pixel_width = it->pixel_width;
+	  glyph->voffset = it->voffset;
+	  glyph->type = IMAGE_GLYPH;
+	  glyph->multibyte_p = it->multibyte_p;
 	  glyph->left_box_line_p = it->start_of_box_run_p;
 	  glyph->right_box_line_p = it->end_of_box_run_p;
-	  glyph->voffset = it->voffset;
-	  glyph->multibyte_p = it->multibyte_p;
+	  glyph->overlaps_vertically_p = 0;
+          glyph->padding_p = 0;
+	  glyph->glyph_not_available_p = 0;
+	  glyph->face_id = it->face_id;
+	  glyph->u.img_id = img->id;
+          glyph->w32_font_type = UNKNOWN_FONT;
 	  ++it->glyph_row->used[area];
 	}
     }
@@ -1592,17 +1621,21 @@
   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
+      glyph->charpos = CHARPOS (it->position);
+      glyph->object = object;
+      glyph->pixel_width = width;
+      glyph->voffset = it->voffset;
       glyph->type = STRETCH_GLYPH;
+      glyph->multibyte_p = it->multibyte_p;
+      glyph->left_box_line_p = it->start_of_box_run_p;
+      glyph->right_box_line_p = it->end_of_box_run_p;
+      glyph->overlaps_vertically_p = 0;
+      glyph->padding_p = 0;
+      glyph->glyph_not_available_p = 0;
+      glyph->face_id = it->face_id;
       glyph->u.stretch.ascent = height * ascent;
       glyph->u.stretch.height = height;
-      glyph->face_id = it->face_id;
-      glyph->pixel_width = width;
-      glyph->charpos = CHARPOS (it->position);
-      glyph->object = object;
-      glyph->left_box_line_p = it->start_of_box_run_p;
-      glyph->right_box_line_p = it->end_of_box_run_p;
-      glyph->voffset = it->voffset;
-      glyph->multibyte_p = it->multibyte_p;
+      glyph->w32_font_type = UNKNOWN_FONT;
       ++it->glyph_row->used[area];
     }
 }
@@ -2474,7 +2507,6 @@
      struct glyph_string *s;
 {     
   s->gc = s->face->gc;
-  xassert (s->gc != 0);
 }
 
 
@@ -2486,6 +2518,8 @@
 x_set_glyph_string_gc (s)
      struct glyph_string *s;
 {
+  PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
+  
   if (s->hl == DRAW_NORMAL_TEXT)
     {
       s->gc = s->face->gc;
@@ -3996,19 +4030,48 @@
 }
 
 
-/* Fill glyph string S from stretch glyph S->first_glyph.  */
-
-static void
-x_fill_stretch_glyph_string (s)
+/* Fill glyph string S from a sequence of stretch glyphs.
+
+   ROW is the glyph row in which the glyphs are found, AREA is the
+   area within the row.  START is the index of the first glyph to
+   consider, END is the index of the last + 1.
+
+   Value is the index of the first glyph not in S.  */
+
+static int
+x_fill_stretch_glyph_string (s, row, area, start, end)
      struct glyph_string *s;
-{
+     struct glyph_row *row;
+     enum glyph_row_area area;
+     int start, end;
+{
+  struct glyph *glyph, *last;
+  int voffset, face_id;
+  
   xassert (s->first_glyph->type == STRETCH_GLYPH);
-  s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+  
+  glyph = s->row->glyphs[s->area] + start;
+  last = s->row->glyphs[s->area] + end;
+  face_id = glyph->face_id;
+  s->face = FACE_FROM_ID (s->f, face_id);
   s->font = s->face->font;
-  s->width = s->first_glyph->pixel_width;
+  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
+  s->width = glyph->pixel_width;
+  voffset = glyph->voffset;
+
+  for (++glyph;
+       (glyph < last
+	&& glyph->type == STRETCH_GLYPH
+	&& glyph->voffset == voffset
+	&& glyph->face_id == face_id);
+       ++glyph)
+    s->width += glyph->pixel_width;
   
   /* Adjust base line for subscript/superscript text.  */
-  s->ybase += s->first_glyph->voffset;
+  s->ybase += voffset;
+
+  xassert (s->face && s->face->gc);
+  return glyph - s->row->glyphs[s->area];
 }
 
 
@@ -4096,9 +4159,8 @@
        {								    \
 	 s = (struct glyph_string *) alloca (sizeof *s);		    \
 	 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL);	    \
-	 x_fill_stretch_glyph_string (s);				    \
+	 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END);	    \
 	 x_append_glyph_string (&HEAD, &TAIL, s);			    \
-	 ++START;							    \
          s->x = (X);							    \
        }								    \
      while (0)
@@ -4137,7 +4199,7 @@
 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P)			   \
      do									   \
        {								   \
-	 int c, charset, face_id;					   \
+	 int c, face_id;					   \
 	 wchar_t *char2b;						   \
 									   \
 	 c = (ROW)->glyphs[AREA][START].u.ch;				   \
@@ -4315,10 +4377,9 @@
      end of the drawing area.  */
   if (row->full_width_p)
     {
-      struct frame *f = XFRAME (WINDOW_FRAME (w));
-
       /* X is relative to the left edge of W, without scroll bars
 	 or flag areas.  */
+      struct frame *f = XFRAME (WINDOW_FRAME (w));
       /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
       int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
 
@@ -5352,7 +5413,7 @@
   /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
      even for negative values.  */
   if (pix_x < 0)
-    pix_x -= FONT_WIDTH ((f)->output_data.w32->font) - 1;
+    pix_x -= FONT_WIDTH (FRAME_FONT(f)) - 1;
   if (pix_y < 0)
     pix_y -= (f)->output_data.w32->line_height - 1;
 
@@ -5363,7 +5424,7 @@
     {
       bounds->left = CHAR_TO_PIXEL_COL (f, pix_x);
       bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y);
-      bounds->right  = bounds->left + FONT_WIDTH  (f->output_data.w32->font) - 1;
+      bounds->right  = bounds->left + FONT_WIDTH  (FRAME_FONT(f)) - 1;
       bounds->bottom = bounds->top + f->output_data.w32->line_height - 1;
     }
 
@@ -5371,8 +5432,8 @@
     {
       if (pix_x < 0)
 	pix_x = 0;
-      else if (pix_x > f->width)
-	pix_x = f->width;
+      else if (pix_x > FRAME_WINDOW_WIDTH (f))
+	pix_x = FRAME_WINDOW_WIDTH (f);
 
       if (pix_y < 0)
 	pix_y = 0;
@@ -5491,7 +5552,7 @@
    If the event is a button press, then note that we have grabbed
    the mouse.  */
 
-static void
+static Lisp_Object
 construct_mouse_click (result, msg, f)
      struct input_event *result;
      W32Msg *msg;
@@ -5512,17 +5573,14 @@
 			  ? up_modifier
 			  : down_modifier));
 
-  {
-    int row, column;
-
-    XSETINT (result->x, LOWORD (msg->msg.lParam));
-    XSETINT (result->y, HIWORD (msg->msg.lParam));
-    XSETFRAME (result->frame_or_window, f);
-    result->arg = Qnil;
-  }
-}
-
-static void
+  XSETINT (result->x, LOWORD (msg->msg.lParam));
+  XSETINT (result->y, HIWORD (msg->msg.lParam));
+  XSETFRAME (result->frame_or_window, f);
+  result->arg = Qnil;
+  return Qnil;
+}
+
+static Lisp_Object
 construct_mouse_wheel (result, msg, f)
      struct input_event *result;
      W32Msg *msg;
@@ -5540,9 +5598,10 @@
   XSETINT (result->y, p.y);
   XSETFRAME (result->frame_or_window, f);
   result->arg = Qnil;
-}
-
-static void
+  return Qnil;
+}
+
+static Lisp_Object
 construct_drag_n_drop (result, msg, f)
      struct input_event *result;
      W32Msg *msg;
@@ -5591,6 +5650,7 @@
   XSETFRAME (frame, f);
   result->frame_or_window = Fcons (frame, files);
   result->arg = Qnil;
+  return Qnil;
 }
 
 
@@ -5659,7 +5719,7 @@
      int *hpos, *vpos, *area;
 {
   struct glyph *glyph, *end;
-  struct glyph_row *row;
+  struct glyph_row *row = NULL;
   int x0, i, left_area_width;
 
   /* Find row containing Y.  Give up if some row is not enabled.  */
@@ -5805,7 +5865,11 @@
 	  help = Fget_text_property (make_number (glyph->charpos),
 				     Qhelp_echo, glyph->object);
 	  if (!NILP (help))
-	    help_echo = help;
+            {
+              help_echo = help;
+              help_echo_object = glyph->object;
+              help_echo_pos = glyph->charpos;
+            }
 
 	  /* Change the mouse pointer according to what is under X/Y.  */
 	  map = Fget_text_property (make_number (glyph->charpos),
@@ -6065,20 +6129,32 @@
 	  help = Qnil;
 	  for (i = 0; i < noverlays && NILP (help); ++i)
 	    help = Foverlay_get (overlay_vec[i], Qhelp_echo); 
-	    
-	  /* Try text properties.  */
-	  if (NILP (help)
-	      && ((STRINGP (glyph->object)
+
+          if (!NILP (help))
+            {
+              help_echo = help;
+              help_echo_object = w->buffer;
+              help_echo_pos = pos;
+            }
+          else
+            {
+              /* Try text properties.  */
+              if ((STRINGP (glyph->object)
 		   && glyph->charpos >= 0
 		   && glyph->charpos < XSTRING (glyph->object)->size)
 		  || (BUFFERP (glyph->object)
 		      && glyph->charpos >= BEGV
-		      && glyph->charpos < ZV)))
-	    help = Fget_text_property (make_number (glyph->charpos),
-				       Qhelp_echo, glyph->object);
+		      && glyph->charpos < ZV))
+                help = Fget_text_property (make_number (glyph->charpos),
+                                           Qhelp_echo, glyph->object);
 	    
-	  if (!NILP (help))
-	    help_echo = help;
+              if (!NILP (help))
+                {
+                  help_echo = help;
+                  help_echo_object = glyph->object;
+                  help_echo_pos = glyph->charpos;
+                }
+            }
         }
         
         BEGV = obegv;
@@ -6309,6 +6385,8 @@
   
   /* Set help_echo to a help string.to display for this tool-bar item.
      w32_read_socket does the rest.  */
+  help_echo_object = Qnil;
+  help_echo_pos = -1;
   help_echo = (XVECTOR (f->current_tool_bar_items)
 	       ->contents[prop_idx + TOOL_BAR_ITEM_HELP]);
   if (NILP (help_echo))
@@ -6483,8 +6561,11 @@
 	}
 
       if (end_hpos > start_hpos)
-	x_draw_glyphs (w, start_x, row, TEXT_AREA,
-		       start_hpos, end_hpos, draw, NULL, NULL, 0);
+        {
+          row->mouse_face_p = draw == DRAW_MOUSE_FACE;
+          x_draw_glyphs (w, start_x, row, TEXT_AREA,
+                         start_hpos, end_hpos, draw, NULL, NULL, 0);
+        }
     }
 
   /* If we turned the cursor off, turn it back on.  */
@@ -6529,6 +6610,25 @@
   dpyinfo->mouse_face_window = Qnil;
 }
 
+
+/* Clear any mouse-face on window W.  This function is part of the
+   redisplay interface, and is called from try_window_id and similar
+   functions to ensure the mouse-highlight is off.  */
+
+static void
+x_clear_mouse_face (w)
+     struct window *w;
+{
+  struct w32_display_info *dpyinfo
+    = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
+  Lisp_Object window;
+
+  XSETWINDOW (window, w);
+  if (EQ (window, dpyinfo->mouse_face_window))
+    clear_mouse_face (dpyinfo);
+}
+
+
 /* Just discard the mouse face information for frame F, if any.
    This is used when the size of F is changed.  */
 
@@ -6687,7 +6787,7 @@
 
 /* Scroll bar support.  */
 
-/* Given an window ID, find the struct scroll_bar which manages it.
+/* Given a window ID, find the struct scroll_bar which manages it.
    This can be called in GC, so we have to make sure to strip off mark
    bits.  */
 
@@ -6831,7 +6931,7 @@
 #endif
 }
 
-BOOL
+void
 my_set_focus (f, hwnd)
      struct frame * f;
      HWND hwnd;
@@ -6840,7 +6940,7 @@
 	       (WPARAM) hwnd, 0);
 }
 
-BOOL
+void
 my_set_foreground_window (hwnd)
      HWND hwnd;
 {
@@ -7624,6 +7724,7 @@
               || !NILP (previous_help_echo))
             {
               Lisp_Object frame;
+              int n;
 
               if (f)
                 XSETFRAME (frame, f);
@@ -7631,10 +7732,9 @@
                 frame = Qnil;
 
               any_help_event_p = 1;
-              bufp->kind = HELP_EVENT;
-              bufp->frame_or_window = frame;
-              bufp->arg = help_echo;
-              ++bufp, ++count, --numchars;
+              n = gen_help_event (bufp, help_echo, frame,
+                                  help_echo_object, help_echo_pos);
+              bufp += n, count += n, numchars -= n;
             }
           break;
 
@@ -7745,14 +7845,7 @@
             UINT menu_item = (UINT) LOWORD (msg.msg.wParam);
             UINT flags = (UINT) HIWORD (msg.msg.wParam);
 
-            /* NTEMACS_TODO: Can't call the below with input blocked,
-               as it may result in hooks being called if the window
-               layout needs to change to display the message, and
-               Feval will abort if input is blocked. But unblocking
-               temporarily is not the best solution. */
-            UNBLOCK_INPUT;
             w32_menu_display_help (menu, menu_item, flags);
-            BLOCK_INPUT;
           }
           break;
 
@@ -7963,11 +8056,11 @@
                  the mouse leaves the frame.  */
               if (any_help_event_p)
                 {
+                  int n;
+
                   XSETFRAME (frame, f);
-                  bufp->kind = HELP_EVENT;
-                  bufp->frame_or_window = frame;
-                  bufp->arg = Qnil;
-                  ++bufp, ++count, --numchars;
+                  n = gen_help_event (bufp, Qnil, frame, Qnil, 0);
+                  bufp += n, count += n, numchars -=n;
                 }
             }
 
@@ -8715,11 +8808,14 @@
   /* Compute the scroll bar width in character columns.  */
   if (f->scroll_bar_pixel_width > 0)
     {
-      int wid = FONT_WIDTH (f->output_data.w32->font);
+      int wid = FONT_WIDTH (FRAME_FONT (f));
       f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
     }
   else
-    f->scroll_bar_cols = 2;
+    {
+      int wid = FONT_WIDTH (FRAME_FONT (f));
+      f->scroll_bar_cols = (14 + wid - 1) / wid;
+    }
 
   /* Now make the frame display the given font.  */
   if (FRAME_W32_WINDOW (f) != 0)
@@ -8730,7 +8826,7 @@
   else
     /* If we are setting a new frame's font for the first time,
        there are no faces yet, so this font's height is the line height.  */
-    f->output_data.w32->line_height = FONT_HEIGHT (f->output_data.w32->font);
+    f->output_data.w32->line_height = FONT_HEIGHT (FRAME_FONT (f));
 
   return build_string (fontp->full_name);
 }
@@ -8948,18 +9044,8 @@
   BLOCK_INPUT;
   x_wm_set_size_hint (f, (long) 0, 0);
 
-  /* It is a mystery why we need to add the border_width here
-     when the frame is already visible, but experiment says we do.  */
   modified_left = f->output_data.w32->left_pos;
   modified_top = f->output_data.w32->top_pos;
-#ifndef HAVE_NTGUI
-  /* Do not add in border widths under W32.  */
-  if (change_gravity != 0)
-    {
-      modified_left += f->output_data.w32->border_width;
-      modified_top += f->output_data.w32->border_width;
-    }
-#endif
 
   my_set_window_pos (FRAME_W32_WINDOW (f),
 		     NULL,
@@ -9021,7 +9107,7 @@
      
      We could just not bother storing any of this information here,
      and let the ConfigureNotify event set everything up, but that
-     might be kind of confusing to the lisp code, since size changes
+     might be kind of confusing to the Lisp code, since size changes
      wouldn't be reported in the frame parameters until some random
      point in the future when the ConfigureNotify event arrives.
 
@@ -9051,6 +9137,27 @@
 
 /* Mouse warping.  */
 
+void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
+
+void
+x_set_mouse_position (f, x, y)
+     struct frame *f;
+     int x, y;
+{
+  int pix_x, pix_y;
+
+  pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH  (f->output_data.w32->font) / 2;
+  pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.w32->line_height / 2;
+
+  if (pix_x < 0) pix_x = 0;
+  if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
+
+  if (pix_y < 0) pix_y = 0;
+  if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
+
+  x_set_mouse_pixel_position (f, pix_x, pix_y);
+}
+
 void
 x_set_mouse_pixel_position (f, pix_x, pix_y)
      struct frame *f;
@@ -9071,27 +9178,10 @@
   UNBLOCK_INPUT;
 }
 
-void
-x_set_mouse_position (f, x, y)
-     struct frame *f;
-     int x, y;
-{
-  int pix_x, pix_y;
-
-  pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH  (f->output_data.w32->font) / 2;
-  pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.w32->line_height / 2;
-
-  if (pix_x < 0) pix_x = 0;
-  if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
-
-  if (pix_y < 0) pix_y = 0;
-  if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
-
-  x_set_mouse_pixel_position (f, pix_x, pix_y);
-}
 
 /* focus shifting, raising and lowering.  */
 
+void
 x_focus_on_frame (f)
      struct frame *f;
 {
@@ -9109,6 +9199,7 @@
   UNBLOCK_INPUT;
 }
 
+void
 x_unfocus_frame (f)
      struct frame *f;
 {
@@ -9188,11 +9279,11 @@
 }
 
 static void
-w32_frame_raise_lower (f, raise)
+w32_frame_raise_lower (f, raise_flag)
      FRAME_PTR f;
-     int raise;
-{
-  if (raise)
+     int raise_flag;
+{
+  if (raise_flag)
     x_raise_frame (f);
   else
     x_lower_frame (f);
@@ -9207,6 +9298,7 @@
    but it will become visible later when the window manager
    finishes with it.  */
 
+void
 x_make_frame_visible (f)
      struct frame *f;
 {
@@ -9617,6 +9709,7 @@
   x_update_window_end,
   w32_cursor_to,
   x_flush,
+  x_clear_mouse_face,
   x_get_glyph_overhangs,
   x_fix_overlapping_area
 };
@@ -9780,10 +9873,12 @@
 affect on NT machines.");
   w32_enable_unicode_output = 1;
 
+  help_echo = Qnil;
   staticpro (&help_echo);
-  help_echo = Qnil;
+  help_echo_object = Qnil;
+  staticpro (&help_echo_object);
+  previous_help_echo = Qnil;
   staticpro (&previous_help_echo);
-  previous_help_echo = Qnil;
 
   DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
     "*Non-nil means draw block cursor as wide as the glyph under it.\n\