*** empty log message ***
[bpt/emacs.git] / src / w32term.c
index ba2b14d..b336fc9 100644 (file)
@@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA.  */
 #include <setjmp.h>
 #include <sys/stat.h>
 
+#include "keyboard.h"
 #include "frame.h"
 #include "dispextern.h"
 #include "fontset.h"
@@ -51,7 +52,6 @@ Boston, MA 02111-1307, USA.  */
 #include "disptab.h"
 #include "buffer.h"
 #include "window.h"
-#include "keyboard.h"
 #include "intervals.h"
 #include "composite.h"
 #include "coding.h"
@@ -84,7 +84,8 @@ enum w32_char_font_type
   UNKNOWN_FONT,
   ANSI_FONT,
   UNICODE_FONT,
-  BDF_FONT
+  BDF_1D_FONT,
+  BDF_2D_FONT
 };
 
 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
@@ -161,6 +162,7 @@ int x_toolkit_scroll_bars_p;
    (The display is done in read_char.)  */
    
 static Lisp_Object help_echo;
+static Lisp_Object help_echo_window;
 static Lisp_Object help_echo_object;
 static int help_echo_pos;
 
@@ -314,7 +316,9 @@ extern Lisp_Object Vcommand_line_args, Vsystem_name;
 
 extern Lisp_Object Qface, Qmouse_face;
 
+#ifndef USE_CRT_DLL
 extern int errno;
+#endif
 
 /* A mask of extra modifier bits to put into every keyboard char.  */
 
@@ -333,7 +337,7 @@ enum draw_glyphs_face
   DRAW_IMAGE_SUNKEN
 };
 
-static void x_update_window_end P_ ((struct window *, int));
+static void x_update_window_end P_ ((struct window *, int, int));
 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
 void w32_delete_display P_ ((struct w32_display_info *));
 static int fast_find_position P_ ((struct window *, int, int *, int *,
@@ -383,7 +387,6 @@ static void w32_frame_rehighlight P_ ((struct frame *));
 static void x_frame_rehighlight P_ ((struct w32_display_info *));
 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
-static int w32_intersect_rectangles P_ ((RECT *, RECT *, RECT *));
 static void expose_frame P_ ((struct frame *, int, int, int, int));
 static void expose_window_tree P_ ((struct window *, RECT *));
 static void expose_window P_ ((struct window *, RECT *));
@@ -470,13 +473,6 @@ void XGetGCValues (void* ignore, XGCValues *gc,
   XChangeGC (ignore, xgcv, mask, gc);
 }
 
-void XTextExtents16 (XFontStruct *font, wchar_t *text, int nchars,
-                     int *direction,int *font_ascent,
-                     int *font_descent, XCharStruct *cs)
-{
-  /* NTEMACS_TODO: Use GetTextMetrics to do this and inline it below. */
-}
-
 static void
 w32_set_clip_rectangle (HDC hdc, RECT *rect)
 {
@@ -1130,12 +1126,48 @@ static void x_produce_image_glyph P_ ((struct it *it));
  ((ch) & 0x00ff)
 
 
-/* NTEMACS_TODO: Add support for bdf fonts back in. */
-
 /* Get metrics of character CHAR2B in FONT.  Value is always non-null.
    If CHAR2B is not contained in FONT, the font's default character
    metric is returned. */
 
+static XCharStruct *
+w32_bdf_per_char_metric (font, char2b, dim)
+     XFontStruct *font;
+     wchar_t *char2b;
+     int dim;
+{
+  glyph_metric * bdf_metric;
+  char buf[2];
+  XCharStruct * pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct));
+
+  if (dim == 1)
+    buf[0] = (char)char2b;
+  else
+    {
+      buf[0] = BYTE1 (*char2b);
+      buf[1] = BYTE2 (*char2b);
+    }
+
+  bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
+
+  if (bdf_metric)
+    {
+      pcm->width = bdf_metric->dwidth;
+      pcm->lbearing = bdf_metric->bbox;
+      pcm->rbearing = bdf_metric->dwidth
+                    - (bdf_metric->bbox + bdf_metric->bbw);
+      pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
+      pcm->descent = bdf_metric->bboy;
+    }
+  else
+    {
+      xfree (pcm);
+      return NULL;
+    }
+  return pcm;
+}
+
+
 static XCharStruct *
 w32_per_char_metric (hdc, font, char2b, font_type)
      HDC hdc;
@@ -1143,60 +1175,83 @@ w32_per_char_metric (hdc, font, char2b, font_type)
      wchar_t *char2b;
      enum w32_char_font_type font_type;
 {
+  /* NTEMACS_TODO: Use GetGlyphOutline where possible (no Unicode
+     version on W9x) */
+
   /* The result metric information.  */
   XCharStruct *pcm;
-  ABC char_widths;
-  SIZE sz;
   BOOL retval;
 
   xassert (font && char2b);
+  xassert (font_type != UNKNOWN_FONT);
 
-  if (font_type == UNKNOWN_FONT)
-    {
-      if (font->bdf)
-        font_type = BDF_FONT;
-      else if (!w32_enable_unicode_output)
-        font_type = ANSI_FONT;
-      else
-        font_type = UNICODE_FONT;  /* NTEMACS_TODO: Need encoding? */
-    }
+  if (font_type == BDF_1D_FONT)
+    return w32_bdf_per_char_metric (font, char2b, 1);
+  else if (font_type == BDF_2D_FONT)
+    return w32_bdf_per_char_metric (font, char2b, 2);
 
   pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct));
 
   if (font->hfont)
     SelectObject (hdc, font->hfont);
 
-  if (font_type == UNICODE_FONT)
-    retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
-  else if (font_type == ANSI_FONT)
-    retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
-
-  if (retval)
+  if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
     {
-      pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
-      pcm->lbearing = char_widths.abcA;
-      pcm->rbearing = pcm->width - char_widths.abcC;
+      ABC char_widths;
+
+      if (font_type == UNICODE_FONT)
+       retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
+      else if (font_type == ANSI_FONT)
+       retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
+
+      if (retval)
+       {
+         pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
+         pcm->lbearing = char_widths.abcA;
+         pcm->rbearing = pcm->width - char_widths.abcC;
+       }
+      else
+       {
+         /* Windows 9x does not implement GetCharABCWidthsW, so if that
+            failed, try GetTextExtentPoint32W, which is implemented and
+            at least gives us some of the info we are after (total
+            character width). */
+         SIZE sz;
+
+         if (font_type == UNICODE_FONT)
+           retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
+
+         if (retval)
+           {
+             pcm->width = sz.cx;
+             pcm->rbearing = sz.cx;
+             pcm->lbearing = 0;
+           }
+         else
+           {
+             xfree (pcm);
+             return NULL;
+           }
+       }
     }
   else
     {
-      /* Windows 9x does not implement GetCharABCWidthsW, so if that
-         failed, try GetTextExtentPoint32W, which is implemented and
-         at least gives us some of the info we are after (total
-         character width). */
-      if (font_type == UNICODE_FONT)
-          retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
+      /* Do our best to deduce the desired metrics data for non-Truetype
+         fonts (generally, raster fonts).  */
+      INT char_width;
 
+      retval = GetCharWidth (hdc, *char2b, *char2b, &char_width);
       if (retval)
-        {
-          pcm->width = sz.cx;
-          pcm->rbearing = sz.cx;
-          pcm->lbearing = 0;
-        }
+       {
+         pcm->width = char_width;
+         pcm->rbearing = char_width;
+         pcm->lbearing = 0;
+       }
       else
-        {
-          xfree (pcm);
-          return NULL;
-        }
+       {
+         xfree (pcm);
+         return NULL;
+       }
     }
 
   pcm->ascent = FONT_BASE (font);
@@ -1205,7 +1260,7 @@ w32_per_char_metric (hdc, font, char2b, font_type)
   if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
     {
       xfree (pcm);
-      pcm = NULL;
+      return NULL;
     }
 
   return pcm;
@@ -1235,7 +1290,7 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
 
   XFontStruct *font = font_info->font;
 
-  xassert(two_byte_p);
+  xassert (two_byte_p);
 
   *two_byte_p = w32_font_is_double_byte (font);
 
@@ -1310,8 +1365,10 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
     }
   if (!font)
     return UNKNOWN_FONT;
+  else if (font->bdf && CHARSET_DIMENSION (charset) == 1)
+    return BDF_1D_FONT;
   else if (font->bdf)
-    return BDF_FONT;
+    return BDF_2D_FONT;
   else if (unicode_p)
     return UNICODE_FONT;
   else
@@ -1897,7 +1954,7 @@ x_produce_glyphs (it)
          it->nglyphs = 1;
 
           pcm = w32_per_char_metric (hdc, font, &char2b,
-                                     font->bdf ? BDF_FONT : ANSI_FONT);
+                                     font->bdf ? BDF_1D_FONT : ANSI_FONT);
          it->ascent = FONT_BASE (font) + boff;
          it->descent = FONT_DESCENT (font) - boff;
 
@@ -1910,9 +1967,9 @@ x_produce_glyphs (it)
           else
             {
               it->glyph_not_available_p = 1;
-              it->phys_ascent = FONT_BASE(font) + boff;
-              it->phys_descent = FONT_DESCENT(font) - boff;
-              it->pixel_width = FONT_WIDTH(font);
+              it->phys_ascent = FONT_BASE (font) + boff;
+              it->phys_descent = FONT_DESCENT (font) - boff;
+              it->pixel_width = FONT_WIDTH (font);
             }
           
          /* If this is a space inside a region of text with
@@ -1989,6 +2046,12 @@ x_produce_glyphs (it)
          int x = it->current_x + it->continuation_lines_width;
          int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
       
+         /* If the distance from the current position to the next tab
+            stop is less than a canonical character width, use the
+            tab stop after that.  */
+         if (next_tab_x - x < CANON_X_UNIT (it->f))
+           next_tab_x += tab_width;
+
          it->pixel_width = next_tab_x - x;
          it->nglyphs = 1;
          it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
@@ -2009,8 +2072,16 @@ x_produce_glyphs (it)
              default font and calculate the width of the character
              from the charset width; this is what old redisplay code
              did.  */
-          pcm = w32_per_char_metric (hdc, font, &char2b,
-                                     font->bdf ? BDF_FONT : UNICODE_FONT);
+          enum w32_char_font_type type;
+
+          if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
+            type = BDF_1D_FONT;
+          else if (font->bdf)
+            type = BDF_2D_FONT;
+          else
+            type = UNICODE_FONT;
+
+          pcm = w32_per_char_metric (hdc, font, &char2b, type);
 
          if (font_not_found_p || !pcm)
            {
@@ -2244,7 +2315,7 @@ struct glyph_string
 
 /* Encapsulate the different ways of displaying text under W32.  */
 
-void W32_TEXTOUT(s, x, y,chars,nchars)
+void W32_TEXTOUT (s, x, y,chars,nchars)
      struct glyph_string * s;
      int x, y;
      wchar_t * chars;
@@ -2648,16 +2719,9 @@ static INLINE void
 x_compute_glyph_string_overhangs (s)
      struct glyph_string *s;
 {
-  if (s->cmp == NULL
-      && s->first_glyph->type == CHAR_GLYPH)
-    {
-      XCharStruct cs;
-      int direction, font_ascent, font_descent;
-      XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
-                     &font_ascent, &font_descent, &cs);
-      s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
-      s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
-    }
+  /* NTEMACS_TODO: Windows does not appear to have a method for
+     getting this info without getting the ABC widths for each
+     individual character and working it out manually. */
 }
 
 
@@ -2916,6 +2980,7 @@ x_draw_glyph_string_background (s, force_p)
         if (FONT_HEIGHT (s->font) < s->height - 2 * s->face->box_line_width
               || s->font_not_found_p
               || s->extends_to_end_of_line_p
+               || s->font->bdf
               || force_p)
        {
          x_clear_glyph_string_rect (s, s->x, s->y + s->face->box_line_width,
@@ -3366,7 +3431,7 @@ x_draw_image_foreground (s)
          image_rect.y = y;
          image_rect.width = s->img->width;
          image_rect.height = s->img->height;
-         if (w32_intersect_rectangles (&clip_rect, &image_rect, &r))
+         if (IntersectRect (&r, &clip_rect, &image_rect))
            XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
                       r.x - x, r.y - y, r.width, r.height, r.x, r.y);
        }
@@ -3377,6 +3442,7 @@ x_draw_image_foreground (s)
           HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
           HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
           HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
+          x_set_glyph_string_clipping (s);
 
           SetTextColor (s->hdc, s->gc->foreground);
           SetBkColor (s->hdc, s->gc->background);
@@ -3401,6 +3467,7 @@ x_draw_image_foreground (s)
          if (s->hl == DRAW_CURSOR)
             w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width - 1,
                                 s->img->height - 1);
+          w32_set_clip_rectangle (s->hdc, NULL);
        }
     }
   else
@@ -3662,10 +3729,6 @@ x_draw_image_glyph_string (s)
        }
       else
 #endif
-       /* Implementation idea: Is it possible to construct a mask?
-          We could look at the color at the margins of the image, and
-          say that this color is probably the background color of the
-          image.  */
        x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
       
       s->background_filled_p = 1;
@@ -4366,8 +4429,10 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
   HDC hdc = get_frame_dc (XFRAME (WINDOW_FRAME (w)));
 
   /* Let's rather be paranoid than getting a SEGV.  */
-  start = max (0, start);
   end = min (end, row->used[area]);
+  start = max (0, start);
+  start = min (end, start);
+
   if (real_start)
     *real_start = start;
   if (real_end)
@@ -4421,7 +4486,7 @@ x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
   /* If there are any glyphs with lbearing < 0 or rbearing > width in
      the row, redraw some glyphs in front or following the glyph
      strings built above.  */
-  if (!overlaps_p && row->contains_overlapping_glyphs_p)
+  if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
     {
       int dummy_x = 0;
       struct glyph_string *h, *t;
@@ -4968,7 +5033,7 @@ expose_frame (f, x, y, w, h)
       window_rect.right = window_x + window_width;
       window_rect.bottom = window_y + window_height;
 
-      if (w32_intersect_rectangles (&r, &window_rect, &intersection_rect))
+      if (IntersectRect (&intersection_rect, &r, &window_rect))
        expose_window (w, &intersection_rect);
     }
 }
@@ -5010,7 +5075,7 @@ expose_window_tree (w, r)
          window_rect.bottom = window_rect.top
            + window_height + CURRENT_MODE_LINE_HEIGHT (w);
 
-         if (w32_intersect_rectangles (r, &window_rect, &intersection_rect))
+         if (IntersectRect (&intersection_rect, r, &window_rect))
            expose_window (w, &intersection_rect);
        }
 
@@ -5128,7 +5193,7 @@ x_phys_cursor_in_rect_p (w, r)
       cr.top = w->phys_cursor.y;
       cr.right = cr.left + cursor_glyph->pixel_width;
       cr.bottom = cr.top + w->phys_cursor_height;
-      return w32_intersect_rectangles (&cr, r, &result);
+      return IntersectRect (&result, &cr, r);
     }
   else
     return 0;
@@ -5213,60 +5278,6 @@ expose_window (w, r)
     }
 }
 
-
-/* Determine the intersection of two rectangles R1 and R2.  Return
-   the intersection in *RESULT.  Value is non-zero if RESULT is not
-   empty.  */
-
-static int
-w32_intersect_rectangles (r1, r2, result)
-     RECT *r1, *r2, *result;
-{
-  RECT *left, *right;
-  RECT *upper, *lower;
-  int intersection_p = 0;
-  
-  /* Rerrange so that R1 is the left-most rectangle.  */
-  if (r1->left < r2->left)
-    left = r1, right = r2;
-  else
-    left = r2, right = r1;
-
-  /* X0 of the intersection is right.x0, if this is inside R1,
-     otherwise there is no intersection.  */
-  if (right->left <= left->right)
-    {
-      result->left = right->left;
-      
-      /* The right end of the intersection is the minimum of the
-        the right ends of left and right.  */
-      result->right = min (left->right, right->right);
-
-      /* Same game for Y.  */
-      if (r1->top < r2->top)
-       upper = r1, lower = r2;
-      else
-       upper = r2, lower = r1;
-
-      /* The upper end of the intersection is lower.y0, if this is inside
-        of upper.  Otherwise, there is no intersection.  */
-      if (lower->top <= upper->bottom)
-       {
-         result->top = lower->top;
-         
-         /* The lower end of the intersection is the minimum of the lower
-            ends of upper and lower.  */
-         result->bottom = min (lower->bottom, upper->bottom);
-         intersection_p = 1;
-       }
-    }
-
-  return intersection_p;
-}
-
-
-
-
 \f
 static void
 frame_highlight (f)
@@ -5379,7 +5390,7 @@ x_get_keysym_name (keysym)
   static char value[100];
 
   BLOCK_INPUT;
-  GetKeyNameText(keysym, value, 100);
+  GetKeyNameText (keysym, value, 100);
   UNBLOCK_INPUT;
 
   return value;
@@ -5413,7 +5424,7 @@ pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
   /* 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 (FRAME_FONT(f)) - 1;
+    pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1;
   if (pix_y < 0)
     pix_y -= (f)->output_data.w32->line_height - 1;
 
@@ -5424,7 +5435,7 @@ pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
     {
       bounds->left = CHAR_TO_PIXEL_COL (f, pix_x);
       bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y);
-      bounds->right  = bounds->left + FONT_WIDTH  (FRAME_FONT(f)) - 1;
+      bounds->right  = bounds->left + FONT_WIDTH  (FRAME_FONT (f)) - 1;
       bounds->bottom = bounds->top + f->output_data.w32->line_height - 1;
     }
 
@@ -5593,7 +5604,7 @@ construct_mouse_wheel (result, msg, f)
   result->modifiers = msg->dwModifiers;
   p.x = LOWORD (msg->msg.lParam);
   p.y = HIWORD (msg->msg.lParam);
-  ScreenToClient(msg->msg.hwnd, &p);
+  ScreenToClient (msg->msg.hwnd, &p);
   XSETINT (result->x, p.x);
   XSETINT (result->y, p.y);
   XSETFRAME (result->frame_or_window, f);
@@ -5867,6 +5878,7 @@ note_mode_line_highlight (w, x, mode_line_p)
          if (!NILP (help))
             {
               help_echo = help;
+              XSETWINDOW (help_echo_window, w);
               help_echo_object = glyph->object;
               help_echo_pos = glyph->charpos;
             }
@@ -6020,6 +6032,7 @@ note_mouse_highlight (f, x, y)
            noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
          }
 
+       /* Sort overlays into increasing priority order.  */
         noverlays = sort_overlays (overlay_vec, noverlays, w);
 
        /* Check mouse-face highlighting.  */
@@ -6037,7 +6050,7 @@ note_mouse_highlight (f, x, y)
 
             /* Find the highest priority overlay that has a mouse-face prop.  */
             overlay = Qnil;
-            for (i = 0; i < noverlays; i++)
+            for (i = noverlays - 1; i >= 0; --i)
               {
                 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
                 if (!NILP (mouse_face))
@@ -6123,17 +6136,21 @@ note_mouse_highlight (f, x, y)
 
         /* Look for a `help-echo' property.  */
         {
-          Lisp_Object help;
+          Lisp_Object help, overlay;
 
          /* Check overlays first.  */
          help = Qnil;
-         for (i = 0; i < noverlays && NILP (help); ++i)
-           help = Foverlay_get (overlay_vec[i], Qhelp_echo); 
+         for (i = noverlays - 1; i >= 0 && NILP (help); --i)
+            {
+              overlay = overlay_vec[i];
+              help = Foverlay_get (overlay, Qhelp_echo); 
+            }
 
           if (!NILP (help))
             {
               help_echo = help;
-              help_echo_object = w->buffer;
+              help_echo_window = window;
+              help_echo_object = overlay;
               help_echo_pos = pos;
             }
           else
@@ -6151,6 +6168,7 @@ note_mouse_highlight (f, x, y)
               if (!NILP (help))
                 {
                   help_echo = help;
+                  help_echo_window = window;
                   help_echo_object = glyph->object;
                   help_echo_pos = glyph->charpos;
                 }
@@ -6385,7 +6403,7 @@ note_tool_bar_highlight (f, x, y)
   
   /* 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_object = help_echo_window = Qnil;
   help_echo_pos = -1;
   help_echo = (XVECTOR (f->current_tool_bar_items)
               ->contents[prop_idx + TOOL_BAR_ITEM_HELP]);
@@ -6623,9 +6641,11 @@ x_clear_mouse_face (w)
     = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
   Lisp_Object window;
 
+  BLOCK_INPUT;
   XSETWINDOW (window, w);
   if (EQ (window, dpyinfo->mouse_face_window))
     clear_mouse_face (dpyinfo);
+  UNBLOCK_INPUT;
 }
 
 
@@ -6713,13 +6733,15 @@ w32_mouse_position (fp, insist, bar_window, part, x, y, time)
        else
          {
            /* Is window under mouse one of our frames?  */
-           f1 = x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp), WindowFromPoint(pt));
+           f1 = x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
+                                    WindowFromPoint (pt));
          }
 
        /* If not, is it one of our scroll bars?  */
        if (! f1)
          {
-           struct scroll_bar *bar = x_window_to_scroll_bar (WindowFromPoint(pt));
+           struct scroll_bar *bar
+              = x_window_to_scroll_bar (WindowFromPoint (pt));
 
            if (bar)
              {
@@ -7451,8 +7473,8 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
       break;
   }
 
-  XSETINT(*x, pos);
-  XSETINT(*y, top_range);
+  XSETINT (*x, pos);
+  XSETINT (*y, top_range);
 
   f->mouse_moved = 0;
   last_mouse_scroll_bar = Qnil;
@@ -7615,7 +7637,7 @@ w32_read_socket (sd, bufp, numchars, expected)
                        count++;
                        numchars--;
                      }
-                   else if (! NILP(Vframe_list)
+                   else if (! NILP (Vframe_list)
                             && ! NILP (XCDR (Vframe_list)))
                      /* Force a redisplay sooner or later to update the
                         frame titles in case this is the second frame.  */
@@ -7701,7 +7723,8 @@ w32_read_socket (sd, bufp, numchars, expected)
 
        case WM_MOUSEMOVE:
           previous_help_echo = help_echo;
-          help_echo = Qnil;
+          help_echo = help_echo_object = help_echo_window = Qnil;
+          help_echo_pos = -1;
 
          if (dpyinfo->grabbed && last_mouse_frame
              && FRAME_LIVE_P (last_mouse_frame))
@@ -7732,8 +7755,9 @@ w32_read_socket (sd, bufp, numchars, expected)
                 frame = Qnil;
 
               any_help_event_p = 1;
-              n = gen_help_event (bufp, help_echo, frame,
-                                  help_echo_object, help_echo_pos);
+              n = gen_help_event (bufp, numchars, help_echo, frame,
+                                 help_echo_window, help_echo_object,
+                                 help_echo_pos);
               bufp += n, count += n, numchars -= n;
             }
           break;
@@ -7984,7 +8008,7 @@ w32_read_socket (sd, bufp, numchars, expected)
              int width;
              int height;
              
-             GetClientRect(msg.msg.hwnd, &rect);
+             GetClientRect (msg.msg.hwnd, &rect);
              
              height = rect.bottom - rect.top;
              width = rect.right - rect.left;
@@ -8059,7 +8083,8 @@ w32_read_socket (sd, bufp, numchars, expected)
                   int n;
 
                   XSETFRAME (frame, f);
-                  n = gen_help_event (bufp, Qnil, frame, Qnil, 0);
+                  n = gen_help_event (bufp, numchars, Qnil, frame,
+                                     Qnil, Qnil, 0);
                   bufp += n, count += n, numchars -=n;
                 }
             }
@@ -8364,18 +8389,31 @@ x_draw_bar_cursor (w, row, width)
       if (cursor_glyph == NULL)
        return;
 
-      x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+      /* If on an image, draw like a normal cursor.  That's usually better
+         visible than drawing a bar, esp. if the image is large so that
+         the bar might not be in the window.  */
+      if (cursor_glyph->type == IMAGE_GLYPH)
+        {
+          struct glyph_row *row;
+          row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
+          x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
+        }
+      else
+        {
 
-      if (width < 0)
-        width = f->output_data.w32->cursor_width;
+          x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 
-      hdc = get_frame_dc (f);
-      w32_fill_area (f, hdc, f->output_data.w32->cursor_pixel,
-                     x,
-                     WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-                     min (cursor_glyph->pixel_width, width),
-                     row->height);
-      release_frame_dc (f, hdc);
+          if (width < 0)
+            width = f->output_data.w32->cursor_width;
+
+          hdc = get_frame_dc (f);
+          w32_fill_area (f, hdc, f->output_data.w32->cursor_pixel,
+                         x,
+                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
+                         min (cursor_glyph->pixel_width, width),
+                         row->height);
+          release_frame_dc (f, hdc);
+        }
     }
 }
 
@@ -8587,7 +8625,9 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
         {
          extern int cursor_in_non_selected_windows;
 
-          if (MINI_WINDOW_P (w) || !cursor_in_non_selected_windows)
+          if (MINI_WINDOW_P (w) 
+              || !cursor_in_non_selected_windows
+              || NILP (XBUFFER (w->buffer)->cursor_type))
             new_cursor_type = NO_CURSOR;
           else
             new_cursor_type = HOLLOW_BOX_CURSOR;
@@ -8902,17 +8942,12 @@ x_font_min_bounds (font, w, h)
      XFontStruct *font;
      int *w, *h;
 {
+  /*
+   * NTEMACS_TODO: Windows does not appear to offer min bound, only
+   * average and maximum width, and maximum height.
+   */
   *h = FONT_HEIGHT (font);
   *w = FONT_WIDTH (font);
-#if 0 /* NTEMACS_TODO: min/max bounds of Windows fonts */
-  *w = font->min_bounds.width;
-
-  /* Try to handle the case where FONT->min_bounds has invalid
-     contents.  Since the only font known to have invalid min_bounds
-     is fixed-width, use max_bounds if min_bounds seems to be invalid.  */
-  if (*w <= 0)
-    *w = font->max_bounds.width;
-#endif
 }
 
 
@@ -9002,7 +9037,7 @@ x_calc_absolute_position (f)
                              - 2 * f->output_data.w32->border_width - pt.x
                              - PIXEL_WIDTH (f)
                              + f->output_data.w32->left_pos);
-  /* NTEMACS_TODO: Subtract menubar height?  */
+
   if (flags & YNegative)
     f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
                             - 2 * f->output_data.w32->border_width - pt.y
@@ -9671,7 +9706,7 @@ x_delete_display (dpyinfo)
     {
       struct w32_palette_entry * pentry = plist;
       plist = plist->next;
-      xfree(pentry);
+      xfree (pentry);
     }
     dpyinfo->color_list = NULL;
     if (dpyinfo->palette)
@@ -9799,8 +9834,8 @@ w32_initialize ()
 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
 
     /* New proportional scroll bar functions. */
-    LOAD_PROC( SetScrollInfo );
-    LOAD_PROC( GetScrollInfo );
+    LOAD_PROC (SetScrollInfo);
+    LOAD_PROC (GetScrollInfo);
 
 #undef LOAD_PROC
 
@@ -9877,8 +9912,11 @@ affect on NT machines.");
   staticpro (&help_echo);
   help_echo_object = Qnil;
   staticpro (&help_echo_object);
+  help_echo_window = Qnil;
+  staticpro (&help_echo_window);
   previous_help_echo = Qnil;
   staticpro (&previous_help_echo);
+  help_echo_pos = -1;
 
   DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
     "*Non-nil means draw block cursor as wide as the glyph under it.\n\