*** empty log message ***
[bpt/emacs.git] / src / w32term.c
index f762256..6116f9a 100644 (file)
@@ -79,14 +79,6 @@ enum bitmap_type
   ZV_LINE_BITMAP
 };
 
-enum w32_char_font_type
-{
-  UNKNOWN_FONT,
-  ANSI_FONT,
-  UNICODE_FONT,
-  BDF_FONT
-};
-
 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
    be Word aligned.  For some reason they are horizontally reflected
    compared to how they appear on X, so changes in xterm.c should be
@@ -188,6 +180,8 @@ extern void w32_menu_display_help (HMENU menu, UINT menu_item, UINT flags);
 
 extern int w32_codepage_for_font (char *fontname);
 
+extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp,
+                                       unsigned char *text, int dim);
 extern Lisp_Object Vwindow_system;
 
 #define x_any_window_to_frame x_window_to_frame
@@ -530,8 +524,15 @@ w32_clear_window (f)
   RECT rect;
   HDC hdc = get_frame_dc (f);
 
-  GetClientRect (FRAME_W32_WINDOW (f), &rect);
-  w32_clear_rect (f, hdc, &rect);
+  /* Under certain conditions, this can be called at startup with
+     a console frame pointer before the GUI frame is created. An HDC
+     of 0 indicates this. */
+  if (hdc)
+    {
+      GetClientRect (FRAME_W32_WINDOW (f), &rect);
+      w32_clear_rect (f, hdc, &rect);
+    }
+
   release_frame_dc (f, hdc);
 }
 
@@ -646,7 +647,7 @@ x_draw_vertical_border (w)
       r.bottom -= 1;
 
       hdc = get_frame_dc (f);
-      w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), r);
+      w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
       release_frame_dc (f, hdc);
     }
 }
@@ -869,15 +870,17 @@ w32_draw_bitmap (w, hdc, row, which)
 
   compat_hdc = CreateCompatibleDC (hdc);
   SaveDC (hdc);
-  fg_brush = CreateSolidBrush (FRAME_FOREGROUND_PIXEL (f));
+  fg_brush = CreateSolidBrush (face->foreground);
   orig_brush = SelectObject (hdc, fg_brush);
   horig_obj = SelectObject (compat_hdc, pixmap);
-  SetTextColor (hdc, FRAME_BACKGROUND_PIXEL (f));
-  SetBkColor (hdc, FRAME_FOREGROUND_PIXEL (f));
+  SetTextColor (hdc, face->foreground);
+  SetBkColor (hdc, face->background);
 #if 0 /* From w32bdf.c (which is from Meadow).  */
+  /* Old versions - in case we find a reason to fall back on them.  */
   BitBlt (hdc, x, y + dy, wd, h, compat_hdc, 0, 0, SRCCOPY);
-#else
   BitBlt (hdc, x, y + dy, wd, h, compat_hdc, 0, 0, 0xB8074A);
+#else
+  BitBlt (hdc, x, y + dy, wd, h, compat_hdc, 0, 0, 0xE20746);
 #endif
   SelectObject (compat_hdc, horig_obj);
   SelectObject (hdc, orig_brush);
@@ -1100,7 +1103,7 @@ static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
                                                        int *));
 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
                                                      int, wchar_t *, int));
-static XCharStruct *w32_per_char_metric P_ ((HDC hdc, XFontStruct *,
+static XCharStruct *w32_per_char_metric P_ ((XFontStruct *,
                                              wchar_t *,
                                              enum w32_char_font_type));
 static enum w32_char_font_type
@@ -1125,85 +1128,206 @@ 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_per_char_metric (hdc, font, char2b, font_type)
-     HDC hdc;
+static int
+w32_bdf_per_char_metric (font, char2b, dim, pcm)
      XFontStruct *font;
      wchar_t *char2b;
-     enum w32_char_font_type font_type;
+     int dim;
+     XCharStruct * pcm;
 {
-  /* The result metric information.  */
-  XCharStruct *pcm;
-  ABC char_widths;
-  SIZE sz;
-  BOOL retval;
+  glyph_metric * bdf_metric;
+  char buf[2];
 
-  xassert (font && char2b);
+  if (dim == 1)
+    buf[0] = (char)(*char2b);
+  else
+    {
+      buf[0] = BYTE1 (*char2b);
+      buf[1] = BYTE2 (*char2b);
+    }
 
-  if (font_type == UNKNOWN_FONT)
+  bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
+
+  if (bdf_metric)
     {
-      if (font->bdf)
-        font_type = BDF_FONT;
-      else if (!w32_enable_unicode_output)
-        font_type = ANSI_FONT;
-      else
-        font_type = UNICODE_FONT;
+      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;
+
+      return 1;
     }
+  return 0;
+}
 
-  pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct));
 
-  if (font->hfont)
-    SelectObject (hdc, font->hfont);
+static int
+w32_native_per_char_metric (font, char2b, font_type, pcm)
+     XFontStruct *font;
+     wchar_t *char2b;
+     enum w32_char_font_type font_type;
+     XCharStruct * pcm;
+{
+  HDC hdc = GetDC (NULL);
+  HFONT old_font;
+  BOOL retval = FALSE;
 
-  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);
+  xassert (font && char2b);
+  xassert (font->hfont);
+  xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT);
 
-  if (retval)
+  old_font = SelectObject (hdc, font->hfont);
+
+  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
+       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;
+         pcm->ascent = FONT_BASE (font);
+         pcm->descent = FONT_DESCENT (font);
+       }
     }
-  else
+
+  if (!retval)
     {
-      /* 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). */
+      /* Either font is not a True-type font, or GetCharABCWidthsW
+        failed (it is not supported on Windows 9x for instance), so we
+        can't determine the full info we would like.  All is not lost
+        though - we can call GetTextExtentPoint32 to get rbearing and
+        deduce width based on the font's per-string overhang.  lbearing
+        is assumed to be zero.  */
+
+      /* TODO: Some Thai characters (and other composites if Windows
+         supports them) do have lbearing, and report their total width
+         as zero. Need some way of handling them when
+         GetCharABCWidthsW fails. */
+      SIZE sz;
+
       if (font_type == UNICODE_FONT)
-          retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
+       retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
+      else
+       retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz);
 
       if (retval)
-        {
-          pcm->width = sz.cx;
-          pcm->rbearing = sz.cx;
-          pcm->lbearing = 0;
-        }
-      else
-        {
-          xfree (pcm);
-          return NULL;
-        }
+       {
+         pcm->width = sz.cx - font->tm.tmOverhang;
+         pcm->rbearing = sz.cx;
+         pcm->lbearing = 0;
+         pcm->ascent = FONT_BASE (font);
+         pcm->descent = FONT_DESCENT (font);
+       }
     }
 
-  pcm->ascent = FONT_BASE (font);
-  pcm->descent = FONT_DESCENT (font);
 
   if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
     {
-      xfree (pcm);
-      pcm = NULL;
+      retval = FALSE;
     }
 
-  return pcm;
+  SelectObject (hdc, old_font);
+  ReleaseDC (NULL, hdc);
+
+  return retval;
+}
+
+
+static XCharStruct *
+w32_per_char_metric (font, char2b, font_type)
+     XFontStruct *font;
+     wchar_t *char2b;
+     enum w32_char_font_type font_type;
+{
+  /* The result metric information.  */
+  XCharStruct *pcm;
+  BOOL retval;
+
+  xassert (font && char2b);
+  xassert (font_type != UNKNOWN_FONT);
+
+  /* Handle the common cases quickly.  */
+  if (!font->bdf && font->per_char == NULL)
+    /* TODO: determine whether char2b exists in font?  */
+    return &font->max_bounds;
+  else if (!font->bdf && *char2b < 128)
+    return &font->per_char[*char2b];
+
+  pcm = &font->scratch;
+
+  if (font_type == BDF_1D_FONT)
+    retval = w32_bdf_per_char_metric (font, char2b, 1, pcm);
+  else if (font_type == BDF_2D_FONT)
+    retval = w32_bdf_per_char_metric (font, char2b, 2, pcm);
+  else
+    retval = w32_native_per_char_metric (font, char2b, font_type, pcm);
+
+  if (retval)
+    return pcm;
+
+  return NULL;
+}
+
+void
+w32_cache_char_metrics (font)
+     XFontStruct *font;
+{
+  wchar_t char2b = L'x';
+
+  /* Cache char metrics for the common cases.  */
+  if (font->bdf)
+    {
+      /* TODO: determine whether font is fixed-pitch.  */
+      if (!w32_bdf_per_char_metric (font, &char2b, 1, &font->max_bounds))
+        {
+          /* Use the font width and height as max bounds, as not all BDF
+             fonts contain the letter 'x'. */
+          font->max_bounds.width = FONT_MAX_WIDTH (font);
+          font->max_bounds.lbearing = -font->bdf->llx;
+          font->max_bounds.rbearing = FONT_MAX_WIDTH (font) - font->bdf->urx;
+          font->max_bounds.ascent = FONT_BASE (font);
+          font->max_bounds.descent = FONT_DESCENT (font);
+        }
+    }
+  else
+    {
+      if (((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0)
+          /* Some fonts (eg DBCS fonts) are marked as fixed width even
+             though they contain characters of different widths. */
+          || (font->tm.tmMaxCharWidth != font->tm.tmAveCharWidth))
+       {
+         /* Font is not fixed pitch, so cache per_char info for the
+             ASCII characters.  It would be much more work, and probably
+             not worth it, to cache other chars, since we may change
+             between using Unicode and ANSI text drawing functions at
+             run-time.  */
+         int i;
+
+         font->per_char = xmalloc (128 * sizeof(XCharStruct));
+         for (i = 0; i < 128; i++)
+           {
+             char2b = i;
+             w32_native_per_char_metric (font, &char2b, ANSI_FONT,
+                                         &font->per_char[i]);
+           }
+       }
+      else
+       w32_native_per_char_metric (font, &char2b, ANSI_FONT,
+                                   &font->max_bounds);
+    }
 }
 
 
@@ -1230,7 +1354,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);
 
@@ -1296,17 +1420,22 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
       temp[0] = BYTE1 (*char2b);
       temp[1] = BYTE2 (*char2b);
       temp[2] = '\0';
-      if (temp[0])
-        MultiByteToWideChar (codepage, 0, temp, 2, char2b, 1);
-      else
-        MultiByteToWideChar (codepage, 0, temp+1, 1, char2b, 1);
+      if (codepage != CP_UNICODE)
+        {
+          if (temp[0])
+            MultiByteToWideChar (codepage, 0, temp, 2, char2b, 1);
+          else
+            MultiByteToWideChar (codepage, 0, temp+1, 1, char2b, 1);
+        }
       unicode_p = 1;
       *two_byte_p = 1;
     }
   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
@@ -1808,9 +1937,10 @@ x_produce_stretch_glyph (it)
 */
 
 #define VCENTER_BASELINE_OFFSET(FONT, F)                       \
- (FONT_DESCENT (FONT)                                          \
-  + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))) / 2       \
-  - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
+  (FONT_DESCENT (FONT)                                         \
+   + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))           \
+      + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2  \
+   - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
 
 /* Produce glyphs/get display metrics for the display element IT is
    loaded with.  See the description of struct display_iterator in
@@ -1831,9 +1961,17 @@ x_produce_glyphs (it)
       int font_not_found_p;
       struct font_info *font_info;
       int boff;                 /* baseline offset */
-      HDC hdc;
-
-      hdc = get_frame_dc (it->f);
+      /* We may change it->multibyte_p upon unibyte<->multibyte
+        conversion.  So, save the current value now and restore it
+        later.
+
+        Note: It seems that we don't have to record multibyte_p in
+        struct glyph because the character code itself tells if or
+        not the character is multibyte.  Thus, in the future, we must
+        consider eliminating the field `multibyte_p' in the struct
+        glyph.
+      */
+      int saved_multibyte_p = it->multibyte_p;
 
       /* Maybe translate single-byte characters to multibyte, or the
          other way.  */
@@ -1846,6 +1984,7 @@ x_produce_glyphs (it)
                   || !NILP (Vnonascii_translation_table)))
             {
               it->char_to_display = unibyte_char_to_multibyte (it->c);
+              it->multibyte_p = 1;
              it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
              face = FACE_FROM_ID (it->f, it->face_id);
            }
@@ -1853,6 +1992,7 @@ x_produce_glyphs (it)
                   && !it->multibyte_p)
            {
              it->char_to_display = multibyte_char_to_unibyte (it->c, Qnil);
+              it->multibyte_p = 0;
              it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
              face = FACE_FROM_ID (it->f, it->face_id);
            }
@@ -1880,9 +2020,6 @@ x_produce_glyphs (it)
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
        }
 
-      if (font->hfont)
-        SelectObject (hdc, font->hfont);
-
       if (it->char_to_display >= ' '
          && (!it->multibyte_p || it->char_to_display < 128))
        {
@@ -1891,8 +2028,8 @@ x_produce_glyphs (it)
 
          it->nglyphs = 1;
 
-          pcm = w32_per_char_metric (hdc, font, &char2b,
-                                     font->bdf ? BDF_FONT : ANSI_FONT);
+          pcm = w32_per_char_metric (font, &char2b,
+                                     font->bdf ? BDF_1D_FONT : ANSI_FONT);
          it->ascent = FONT_BASE (font) + boff;
          it->descent = FONT_DESCENT (font) - boff;
 
@@ -1905,9 +2042,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
@@ -1959,8 +2096,6 @@ x_produce_glyphs (it)
                 glyph row.  This is used to optimize X output code.  */
              if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
                it->glyph_row->contains_overlapping_glyphs_p = 1;
-              if (pcm)
-                xfree (pcm);
            }
        }
       else if (it->char_to_display == '\n')
@@ -1984,6 +2119,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;
@@ -2004,8 +2145,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 (font, &char2b, type);
 
          if (font_not_found_p || !pcm)
            {
@@ -2052,15 +2201,288 @@ x_produce_glyphs (it)
   
          if (it->glyph_row)
            x_append_glyph (it);
-
-          if (pcm)
-            xfree (pcm);
        }
-      release_frame_dc (it->f, hdc);
+      it->multibyte_p = saved_multibyte_p;
     }
   else if (it->what == IT_COMPOSITION)
     {
-      /* NTEMACS_TODO: Composite glyphs.  */
+      /* Note: A composition is represented as one glyph in the
+        glyph matrix.  There are no padding glyphs.  */
+      wchar_t char2b;
+      XFontStruct *font;
+      struct face *face = FACE_FROM_ID (it->f, it->face_id);
+      XCharStruct *pcm;
+      int font_not_found_p;
+      struct font_info *font_info;
+      int boff;                        /* baseline offset */
+      struct composition *cmp = composition_table[it->cmp_id];
+
+      /* Maybe translate single-byte characters to multibyte.  */
+      it->char_to_display = it->c;
+      if (unibyte_display_via_language_environment
+         && SINGLE_BYTE_CHAR_P (it->c)
+         && (it->c >= 0240
+             || (it->c >= 0200
+                 && !NILP (Vnonascii_translation_table))))
+       {
+         it->char_to_display = unibyte_char_to_multibyte (it->c);
+       }
+
+      /* Get face and font to use.  Encode IT->char_to_display.  */
+      it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
+      face = FACE_FROM_ID (it->f, it->face_id);
+      x_get_char_face_and_encoding (it->f, it->char_to_display,
+                                   it->face_id, &char2b, it->multibyte_p);
+      font = face->font;
+
+      /* When no suitable font found, use the default font.  */
+      font_not_found_p = font == NULL;
+      if (font_not_found_p)
+       {
+         font = FRAME_FONT (it->f);
+         boff = it->f->output_data.w32->baseline_offset;
+         font_info = NULL;
+       }
+      else
+       {
+         font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+         boff = font_info->baseline_offset;
+         if (font_info->vertical_centering)
+           boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
+       }
+
+      /* There are no padding glyphs, so there is only one glyph to
+        produce for the composition.  Important is that pixel_width,
+        ascent and descent are the values of what is drawn by
+        draw_glyphs (i.e. the values of the overall glyphs composed).  */
+      it->nglyphs = 1;
+
+      /* If we have not yet calculated pixel size data of glyphs of
+        the composition for the current face font, calculate them
+        now.  Theoretically, we have to check all fonts for the
+        glyphs, but that requires much time and memory space.  So,
+        here we check only the font of the first glyph.  This leads
+        to incorrect display very rarely, and C-l (recenter) can
+        correct the display anyway.  */
+      if (cmp->font != (void *) font)
+       {
+         /* Ascent and descent of the font of the first character of
+            this composition (adjusted by baseline offset).  Ascent
+            and descent of overall glyphs should not be less than
+            them respectively.  */
+         int font_ascent = FONT_BASE (font) + boff;
+         int font_descent = FONT_DESCENT (font) - boff;
+         /* Bounding box of the overall glyphs.  */
+         int leftmost, rightmost, lowest, highest;
+         int i, width, ascent, descent;
+          enum w32_char_font_type font_type;
+
+         cmp->font = (void *) font;
+
+          if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
+            font_type = BDF_1D_FONT;
+          else if (font->bdf)
+            font_type = BDF_2D_FONT;
+          else
+            font_type = UNICODE_FONT;
+
+         /* Initialize the bounding box.  */
+         if (font_info
+              && (pcm = w32_per_char_metric (font, &char2b, font_type)))
+           {
+             width = pcm->width;
+             ascent = pcm->ascent;
+             descent = pcm->descent;
+           }
+         else
+           {
+             width = FONT_WIDTH (font);
+             ascent = FONT_BASE (font);
+             descent = FONT_DESCENT (font);
+           }
+         
+         rightmost = width;
+         lowest = - descent + boff;
+         highest = ascent + boff;
+         leftmost = 0;
+         
+         if (font_info
+             && font_info->default_ascent
+             && CHAR_TABLE_P (Vuse_default_ascent)
+             && !NILP (Faref (Vuse_default_ascent,
+                              make_number (it->char_to_display))))
+           highest = font_info->default_ascent + boff;
+
+         /* Draw the first glyph at the normal position.  It may be
+            shifted to right later if some other glyphs are drawn at
+            the left.  */
+         cmp->offsets[0] = 0;
+         cmp->offsets[1] = boff;
+
+         /* Set cmp->offsets for the remaining glyphs.  */
+         for (i = 1; i < cmp->glyph_len; i++)
+           {
+             int left, right, btm, top;
+             int ch = COMPOSITION_GLYPH (cmp, i);
+             int face_id = FACE_FOR_CHAR (it->f, face, ch);
+
+             face = FACE_FROM_ID (it->f, face_id);
+             x_get_char_face_and_encoding (it->f, ch, face->id, &char2b,
+                                           it->multibyte_p);
+             font = face->font;
+             if (font == NULL)
+               {
+                 font = FRAME_FONT (it->f);
+                 boff = it->f->output_data.w32->baseline_offset;
+                 font_info = NULL;
+               }
+             else
+               {
+                 font_info
+                   = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+                 boff = font_info->baseline_offset;
+                 if (font_info->vertical_centering)
+                   boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
+               }
+
+              if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (ch)) == 1)
+                font_type = BDF_1D_FONT;
+              else if (font->bdf)
+                font_type = BDF_2D_FONT;
+              else
+                font_type = UNICODE_FONT;
+
+             if (font_info
+                  && (pcm = w32_per_char_metric (font, &char2b, font_type)))
+               {
+                 width = pcm->width;
+                 ascent = pcm->ascent;
+                 descent = pcm->descent;
+               }
+             else
+               {
+                 width = FONT_WIDTH (font);
+                 ascent = 1;
+                 descent = 0;
+               }
+
+             if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
+               {
+                 /* Relative composition with or without
+                    alternate chars.  */
+                 left = (leftmost + rightmost - width) / 2;
+                 btm = - descent + boff;
+                 if (font_info && font_info->relative_compose
+                     && (! CHAR_TABLE_P (Vignore_relative_composition)
+                         || NILP (Faref (Vignore_relative_composition,
+                                         make_number (ch)))))
+                   {
+
+                     if (- descent >= font_info->relative_compose)
+                       /* One extra pixel between two glyphs.  */
+                       btm = highest + 1;
+                     else if (ascent <= 0)
+                       /* One extra pixel between two glyphs.  */
+                       btm = lowest - 1 - ascent - descent;
+                   }
+               }
+             else
+               {
+                 /* A composition rule is specified by an integer
+                    value that encodes global and new reference
+                    points (GREF and NREF).  GREF and NREF are
+                    specified by numbers as below:
+
+                       0---1---2 -- ascent
+                       |       |
+                       |       |
+                       |       |
+                       9--10--11 -- center
+                       |       |
+                    ---3---4---5--- baseline
+                       |       |
+                       6---7---8 -- descent
+                 */
+                 int rule = COMPOSITION_RULE (cmp, i);
+                 int gref, nref, grefx, grefy, nrefx, nrefy;
+
+                 COMPOSITION_DECODE_RULE (rule, gref, nref);
+                 grefx = gref % 3, nrefx = nref % 3;
+                 grefy = gref / 3, nrefy = nref / 3;
+
+                 left = (leftmost
+                         + grefx * (rightmost - leftmost) / 2
+                         - nrefx * width / 2);
+                 btm = ((grefy == 0 ? highest
+                         : grefy == 1 ? 0
+                         : grefy == 2 ? lowest
+                         : (highest + lowest) / 2)
+                        - (nrefy == 0 ? ascent + descent
+                           : nrefy == 1 ? descent - boff
+                           : nrefy == 2 ? 0
+                           : (ascent + descent) / 2));
+               }
+
+             cmp->offsets[i * 2] = left;
+             cmp->offsets[i * 2 + 1] = btm + descent;
+
+             /* Update the bounding box of the overall glyphs. */
+             right = left + width;
+             top = btm + descent + ascent;
+             if (left < leftmost)
+               leftmost = left;
+             if (right > rightmost)
+               rightmost = right;
+             if (top > highest)
+               highest = top;
+             if (btm < lowest)
+               lowest = btm;
+           }
+
+         /* If there are glyphs whose x-offsets are negative,
+            shift all glyphs to the right and make all x-offsets
+            non-negative.  */
+         if (leftmost < 0)
+           {
+             for (i = 0; i < cmp->glyph_len; i++)
+               cmp->offsets[i * 2] -= leftmost;
+             rightmost -= leftmost;
+           }
+
+         cmp->pixel_width = rightmost;
+         cmp->ascent = highest;
+         cmp->descent = - lowest;
+         if (cmp->ascent < font_ascent)
+           cmp->ascent = font_ascent;
+         if (cmp->descent < font_descent)
+           cmp->descent = font_descent;
+       }
+
+      it->pixel_width = cmp->pixel_width;
+      it->ascent = it->phys_ascent = cmp->ascent;
+      it->descent = it->phys_descent = cmp->descent;
+
+      if (face->box != FACE_NO_BOX)
+       {
+         int thick = face->box_line_width;
+         it->ascent += thick;
+         it->descent += thick;
+         
+         if (it->start_of_box_run_p)
+           it->pixel_width += thick;
+         if (it->end_of_box_run_p)
+           it->pixel_width += thick;
+       }
+  
+      /* If face has an overline, add the height of the overline
+        (1 pixel) and a 1 pixel margin to the character height.  */
+      if (face->overline_p)
+       it->ascent += 2;
+
+      take_vertical_position_into_account (it);
+  
+      if (it->glyph_row)
+       x_append_composite_glyph (it);
     }
   else if (it->what == IT_IMAGE)
     x_produce_image_glyph (it);
@@ -2089,7 +2511,7 @@ x_estimate_mode_line_height (f, face_id)
      struct frame *f;
      enum face_id face_id;
 {
-  int height = 1;
+  int height = FONT_HEIGHT (FRAME_FONT (f));
 
   /* This function is called so early when Emacs starts that the face
      cache and mode line face are not yet initialized.  */
@@ -2097,7 +2519,12 @@ x_estimate_mode_line_height (f, face_id)
       {
        struct face *face = FACE_FROM_ID (f, face_id);
        if (face)
-         height = FONT_HEIGHT (face->font) + 2 * face->box_line_width;
+          {
+            if (face->font)
+              height = FONT_HEIGHT (face->font);
+            height += 2 * face->box_line_width;
+          }
+        
       }
   
   return height;
@@ -2111,7 +2538,8 @@ w32_use_unicode_for_codepage (codepage)
 {
   /* If the current codepage is supported, use Unicode for output. */
   return (w32_enable_unicode_output
-          && codepage != CP_DEFAULT && IsValidCodePage (codepage));
+          && codepage != CP_8BIT
+          && (codepage == CP_UNICODE || IsValidCodePage (codepage)));
 }
 
 \f
@@ -2239,7 +2667,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;
@@ -2248,7 +2676,8 @@ void W32_TEXTOUT(s, x, y,chars,nchars)
   int charset_dim = w32_font_is_double_byte (s->gc->font) ? 2 : 1;
   if (s->gc->font->bdf)
     w32_BDF_TextOut (s->gc->font->bdf, s->hdc,
-                     x, y, (char *) chars, charset_dim, nchars, 0);
+                     x, y, (char *) chars, charset_dim,
+                     nchars * charset_dim, 0);
   else if (s->first_glyph->w32_font_type == UNICODE_FONT)
     ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
   else
@@ -2643,7 +3072,7 @@ static INLINE void
 x_compute_glyph_string_overhangs (s)
      struct glyph_string *s;
 {
-  /* NTEMACS_TODO: Windows does not appear to have a method for
+  /* 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. */
 }
@@ -2708,14 +3137,13 @@ w32_get_glyph_overhangs (hdc, glyph, f, left, right)
       font = face->font;
 
       if (font
-          && (pcm = w32_per_char_metric (hdc, font, &char2b,
+          && (pcm = w32_per_char_metric (font, &char2b,
                                          glyph->w32_font_type)))
        {
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
          if (pcm->lbearing < 0)
            *left = -pcm->lbearing;
-          xfree (pcm);
        }
     }
 }
@@ -2887,7 +3315,7 @@ x_draw_glyph_string_background (s, force_p)
      shouldn't be drawn in the first place.  */
   if (!s->background_filled_p)
     {
-#if 0 /* NTEMACS_TODO: stipple */
+#if 0 /* TODO: stipple */
       if (s->stippled_p)
        {
          /* Fill background with a stipple pattern.  */
@@ -2904,6 +3332,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,
@@ -2922,6 +3351,7 @@ x_draw_glyph_string_foreground (s)
      struct glyph_string *s;
 {
   int i, x;
+  HFONT old_font;
 
   /* If first glyph of S has a left box line, start drawing the text
      of S to the right of that box line.  */
@@ -2941,7 +3371,7 @@ x_draw_glyph_string_foreground (s)
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
   if (s->font && s->font->hfont)
-    SelectObject (s->hdc, s->font->hfont);
+    old_font = SelectObject (s->hdc, s->font->hfont);
 
   /* Draw characters of S as rectangles if S's font could not be
      loaded. */
@@ -2972,6 +3402,8 @@ x_draw_glyph_string_foreground (s)
       /* Draw text with TextOut and friends. */
       W32_TEXTOUT (s, x, s->ybase - boff, s->char2b, s->nchars);
     }
+  if (s->font && s->font->hfont)
+    SelectObject (s->hdc, old_font);
 }
 
 /* Draw the foreground of composite glyph string S.  */
@@ -2981,6 +3413,7 @@ x_draw_composite_glyph_string_foreground (s)
      struct glyph_string *s;
 {
   int i, x;
+  HFONT old_font;
 
   /* If first glyph of S has a left box line, start drawing the text
      of S to the right of that box line.  */
@@ -3000,6 +3433,9 @@ x_draw_composite_glyph_string_foreground (s)
   SetBkMode (s->hdc, TRANSPARENT);
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
+  if (s->font && s->font->hfont)
+    old_font = SelectObject (s->hdc, s->font->hfont);
+
   /* Draw a rectangle for the composition if the font for the very
      first character of the composition could not be loaded.  */
   if (s->font_not_found_p)
@@ -3011,12 +3447,29 @@ x_draw_composite_glyph_string_foreground (s)
   else
     {
       for (i = 0; i < s->nchars; i++, ++s->gidx)
-       W32_TEXTOUT (s, x + s->cmp->offsets[s->gidx * 2],
-                     s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
-                     s->char2b + i, 1);
+          W32_TEXTOUT (s, x + s->cmp->offsets[s->gidx * 2],
+                       s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
+                       s->char2b + i, 1);
     }
+  if (s->font && s->font->hfont)
+    SelectObject (s->hdc, old_font);
 }
 
+
+/* Brightness beyond which a color won't have its highlight brightness
+   boosted.
+
+   Nominally, highlight colors for `3d' faces are calculated by
+   brightening an object's color by a constant scale factor, but this
+   doesn't yield good results for dark colors, so for colors who's
+   brightness is less than this value (on a scale of 0-255) have to
+   use an additional additive factor.
+
+   The value here is set so that the default menu-bar/mode-line color
+   (grey75) will not have its highlights changed at all.  */
+#define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
+
+
 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
    If this produces the same color as COLOR, try a color where all RGB
@@ -3032,19 +3485,49 @@ w32_alloc_lighter_color (f, color, factor, delta)
      int delta;
 {
   COLORREF new;
+  long bright;
+
+  /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
+  delta /= 256;
 
   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
   xassert (factor >= 0);
   new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
                     min (0xff, factor * GetGValue (*color)),
                     min (0xff, factor * GetBValue (*color)));
+
+  /* Calculate brightness of COLOR.  */
+  bright = (2 * GetRValue (*color) + 3 * GetGValue (*color)
+            + GetBValue (*color)) / 6;
+
+  /* We only boost colors that are darker than
+     HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
+  if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
+    /* Make an additive adjustment to NEW, because it's dark enough so
+       that scaling by FACTOR alone isn't enough.  */
+    {
+      /* How far below the limit this color is (0 - 1, 1 being darker).  */
+      double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
+      /* The additive adjustment.  */
+      int min_delta = delta * dimness * factor / 2;
+      
+      if (factor < 1)
+        new = PALETTERGB (max (0, min (0xff, min_delta - GetRValue (*color))),
+                          max (0, min (0xff, min_delta - GetGValue (*color))),
+                          max (0, min (0xff, min_delta - GetBValue (*color))));
+      else
+        new = PALETTERGB (max (0, min (0xff, min_delta + GetRValue (*color))),
+                          max (0, min (0xff, min_delta + GetGValue (*color))),
+                          max (0, min (0xff, min_delta + GetBValue (*color))));
+    }
+  
   if (new == *color)
     new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
                       max (0, min (0xff, delta + GetGValue (*color))),
                       max (0, min (0xff, delta + GetBValue (*color))));
 
-  /* NTEMACS_TODO: Map to palette and retry with delta if same? */
-  /* NTEMACS_TODO: Free colors (if using palette)? */
+  /* TODO: Map to palette and retry with delta if same? */
+  /* TODO: Free colors (if using palette)? */
 
   if (new == *color)
     return 0;
@@ -3077,7 +3560,7 @@ w32_setup_relief_color (f, relief, factor, delta, default_pixel)
   COLORREF background = di->relief_background;
   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
 
-  /* NTEMACS_TODO: Free colors (if using palette)? */
+  /* TODO: Free colors (if using palette)? */
 
   /* Allocate new color.  */
   xgcv.foreground = default_pixel;
@@ -3090,7 +3573,7 @@ w32_setup_relief_color (f, relief, factor, delta, default_pixel)
   
   if (relief->gc == 0)
     {
-#if 0 /* NTEMACS_TODO: stipple */
+#if 0 /* TODO: stipple */
       xgcv.stipple = dpyinfo->gray;
       mask |= GCStipple;
 #endif
@@ -3147,9 +3630,9 @@ w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
   HDC hdc = get_frame_dc (f);
 
   if (raised_p)
-    gc.foreground = PALETTERGB (255, 255, 255);
+    gc.foreground = f->output_data.w32->white_relief.gc->foreground;
   else
-    gc.foreground = PALETTERGB (0, 0, 0);
+    gc.foreground = f->output_data.w32->black_relief.gc->foreground;
 
   w32_set_clip_rectangle (hdc, clip_rect);
 
@@ -3173,9 +3656,10 @@ w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
   w32_set_clip_rectangle (hdc, NULL);
 
   if (raised_p)
-    gc.foreground = PALETTERGB (0, 0, 0);
+    gc.foreground = f->output_data.w32->black_relief.gc->foreground;
   else
-    gc.foreground = PALETTERGB (255, 255, 255);
+    gc.foreground = f->output_data.w32->white_relief.gc->foreground;
+
 
   w32_set_clip_rectangle (hdc, clip_rect);
   
@@ -3220,24 +3704,24 @@ w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
   
   /* Top.  */
   w32_fill_area (s->f, s->hdc, s->face->box_color,
-                 left_x, top_y, right_x - left_x, width);
+                 left_x, top_y, right_x - left_x + 1, width);
 
   /* Left.  */
   if (left_p)
     {
       w32_fill_area (s->f, s->hdc, s->face->box_color,
-                     left_x, top_y, width, bottom_y - top_y);
+                     left_x, top_y, width, bottom_y - top_y + 1);
     }
   
   /* Bottom.  */
   w32_fill_area (s->f, s->hdc, s->face->box_color,
-                 left_x, bottom_y - width, right_x - left_x, width);
+                 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
   
   /* Right.  */
   if (right_p)
     {
       w32_fill_area (s->f, s->hdc, s->face->box_color,
-                     right_x - width, top_y, width, bottom_y - top_y);
+                     right_x - width + 1, top_y, width, bottom_y - top_y + 1);
     }
 
   w32_set_clip_rectangle (s->hdc, NULL);
@@ -3330,7 +3814,7 @@ x_draw_image_foreground (s)
 
   if (s->img->pixmap)
     {
-#if 0 /* NTEMACS_TODO: image mask */
+#if 0 /* TODO: image mask */
       if (s->img->mask)
        {
          /* We can't set both a clip mask and use XSetClipRectangles
@@ -3390,7 +3874,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);
+          w32_set_clip_rectangle (s->hdc, NULL);
        }
     }
   else
@@ -3482,7 +3966,7 @@ w32_draw_image_foreground_1 (s, pixmap)
 
   if (s->img->pixmap)
     {
-#if 0 /* NTEMACS_TODO: image mask */
+#if 0 /* TODO: image mask */
       if (s->img->mask)
        {
          /* We can't set both a clip mask and use XSetClipRectangles
@@ -3554,7 +4038,7 @@ x_draw_glyph_string_bg_rect (s, x, y, w, h)
      struct glyph_string *s;
      int x, y, w, h;
 {
-#if 0 /* NTEMACS_TODO: stipple */
+#if 0 /* TODO: stipple */
   if (s->stippled_p)
     {
       /* Fill background with a stipple pattern.  */
@@ -3600,7 +4084,7 @@ x_draw_image_glyph_string (s)
   s->stippled_p = s->face->stipple != 0;
   if (height > s->img->height
       || margin
-#if 0 /* NTEMACS_TODO: image mask */
+#if 0 /* TODO: image mask */
       || s->img->mask
 #endif
       || s->img->pixmap == 0
@@ -3612,7 +4096,7 @@ x_draw_image_glyph_string (s)
        x = s->x;
       
       y = s->y + box_line_width;
-#if 0 /* NTEMACS_TODO: image mask */
+#if 0 /* TODO: image mask */
       if (s->img->mask)
        {
          /* Create a pixmap as large as the glyph string Fill it with
@@ -3652,10 +4136,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;
@@ -3730,7 +4210,7 @@ x_draw_stretch_glyph_string (s)
          w32_get_glyph_string_clip_rect (s, &r);
          w32_set_clip_rectangle (hdc, &r);
 
-#if 0 /* NTEMACS_TODO: stipple */
+#if 0 /* TODO: stipple */
          if (s->face->stipple)
            {
              /* Fill background with a stipple pattern.  */
@@ -4356,8 +4836,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)
@@ -4411,7 +4893,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;
@@ -5019,11 +5501,10 @@ expose_area (w, row, r, area)
      RECT *r;
      enum glyph_row_area area;
 {
-  int x;
   struct glyph *first = row->glyphs[area];
   struct glyph *end = row->glyphs[area] + row->used[area];
   struct glyph *last;
-  int first_x;
+  int first_x, start_x, x;
 
   /* Set x to the window-relative start position for drawing glyphs of
      AREA.  The first glyph of the text area can be partially visible.
@@ -5044,6 +5525,18 @@ expose_area (w, row, r, area)
                   NULL, NULL, 0);
   else
     {
+      /* Set START_X to the window-relative start position for drawing glyphs of
+        AREA.  The first glyph of the text area can be partially visible.
+        The first glyphs of other areas cannot.  */
+      if (area == LEFT_MARGIN_AREA)
+       start_x = 0;
+      else if (area == TEXT_AREA)
+       start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
+      else
+       start_x = (window_box_width (w, LEFT_MARGIN_AREA)
+                  + window_box_width (w, TEXT_AREA));
+      x = start_x;
+
       /* Find the first glyph that must be redrawn.  */
       while (first < end
              && x + first->pixel_width < r->left)
@@ -5061,10 +5554,10 @@ expose_area (w, row, r, area)
           x += last->pixel_width;
           ++last;
         }
-      
+
       /* Repaint.  */
       if (last > first)
-        x_draw_glyphs (w, first_x, row, area,
+        x_draw_glyphs (w, first_x - start_x, row, area,
                        first - row->glyphs[area],
                        last - row->glyphs[area],
                        row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
@@ -5315,7 +5808,7 @@ x_get_keysym_name (keysym)
   static char value[100];
 
   BLOCK_INPUT;
-  GetKeyNameText(keysym, value, 100);
+  GetKeyNameText (keysym, value, 100);
   UNBLOCK_INPUT;
 
   return value;
@@ -5349,7 +5842,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;
 
@@ -5360,7 +5853,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;
     }
 
@@ -5529,7 +6022,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);
@@ -5811,12 +6304,12 @@ note_mode_line_highlight (w, x, mode_line_p)
          /* Change the mouse pointer according to what is under X/Y.  */
          map = Fget_text_property (make_number (glyph->charpos),
                                    Qlocal_map, glyph->object);
-         if (!NILP (Fkeymapp (map)))
+         if (KEYMAPP (map))
            cursor = f->output_data.w32->nontext_cursor;
        }
     }
 
-#if 0 /* NTEMACS_TODO: mouse cursor */
+#if 0 /* TODO: mouse cursor */
   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
 #endif
 }
@@ -5887,7 +6380,10 @@ note_mouse_highlight (f, x, y)
       note_mode_line_highlight (w, x, portion == 1);
       return;
     }
-#if 0 /* NTEMACS_TODO: mouse cursor */
+#if 0 /* TODO: mouse cursor */
+  else if (portion == 2)
+    XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                  f->output_data.x->horizontal_drag_cursor);
   else
     XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                   f->output_data.x->text_cursor);
@@ -6136,7 +6632,7 @@ static int last_tool_bar_item;
    Return in *GLYPH a pointer to the glyph of the tool-bar item in
    the current matrix of the tool-bar window of F, or NULL if not
    on a tool-bar item.  Return in *PROP_IDX the index of the tool-bar
-   item in F->current_tool_bar_items.  Value is
+   item in F->tool_bar_items.  Value is
 
    -1  if X/Y is not on a tool-bar item
    0   if X/Y is on the same item that was highlighted before.
@@ -6159,7 +6655,7 @@ x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
     return -1;
 
   /* Get the start of this tool-bar item's properties in
-     f->current_tool_bar_items.  */
+     f->tool_bar_items.  */
   if (!tool_bar_item_info (f, *glyph, prop_idx))
     return -1;
 
@@ -6201,8 +6697,7 @@ w32_handle_tool_bar_click (f, button_event)
     return;
 
   /* If item is disabled, do nothing.  */
-  enabled_p = (XVECTOR (f->current_tool_bar_items)
-              ->contents[prop_idx + TOOL_BAR_ITEM_ENABLED_P]);
+  enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
   if (NILP (enabled_p))
     return;
   
@@ -6222,8 +6717,7 @@ w32_handle_tool_bar_click (f, button_event)
       show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
       dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
 
-      key = (XVECTOR (f->current_tool_bar_items)
-            ->contents[prop_idx + TOOL_BAR_ITEM_KEY]);
+      key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
 
       XSETFRAME (frame, f);
       event.kind = TOOL_BAR_EVENT;
@@ -6295,8 +6789,7 @@ note_tool_bar_highlight (f, x, y)
   draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
   
   /* If tool-bar item is not enabled, don't highlight it.  */
-  enabled_p = (XVECTOR (f->current_tool_bar_items)
-              ->contents[prop_idx + TOOL_BAR_ITEM_ENABLED_P]);
+  enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
   if (!NILP (enabled_p))
     {
       /* Compute the x-position of the glyph.  In front and past the
@@ -6330,11 +6823,9 @@ note_tool_bar_highlight (f, x, y)
      w32_read_socket does the rest.  */
   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]);
+  help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
   if (NILP (help_echo))
-    help_echo = (XVECTOR (f->current_tool_bar_items)
-                ->contents[prop_idx + TOOL_BAR_ITEM_CAPTION]);
+    help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
 }
 
 
@@ -6520,7 +7011,7 @@ show_mouse_face (dpyinfo, draw)
   output_cursor = saved_cursor;
 
  set_x_cursor:
-#if 0 /* NTEMACS_TODO: mouse cursor */
+#if 0 /* TODO: mouse cursor */
   /* Change the mouse cursor.  */
   if (draw == DRAW_NORMAL_TEXT)
     XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
@@ -6566,9 +7057,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;
 }
 
 
@@ -6656,13 +7149,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)
              {
@@ -7394,8 +7889,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;
@@ -7519,7 +8014,7 @@ w32_read_socket (sd, bufp, numchars, expected)
   if (numchars <= 0)
     abort ();                   /* Don't think this happens. */
 
-  /* NTEMACS_TODO: tooltips, tool-bars, ghostscript integration, mouse
+  /* TODO: tooltips, tool-bars, ghostscript integration, mouse
      cursors. */
   while (get_next_msg (&msg, FALSE))
     {
@@ -7558,7 +8053,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.  */
@@ -7929,7 +8424,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;
@@ -7974,7 +8469,7 @@ w32_read_socket (sd, bufp, numchars, expected)
          break;
 
        case WM_KILLFOCUS:
-          /* NTEMACS_TODO: some of this belongs in MOUSE_LEAVE */
+          /* TODO: some of this belongs in MOUSE_LEAVE */
          f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
 
           if (f)
@@ -8546,7 +9041,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;
@@ -8862,7 +9359,7 @@ x_font_min_bounds (font, w, h)
      int *w, *h;
 {
   /*
-   * NTEMACS_TODO: Windows does not appear to offer min bound, only
+   * TODO: Windows does not appear to offer min bound, only
    * average and maximum width, and maximum height.
    */
   *h = FONT_HEIGHT (font);
@@ -9299,7 +9796,7 @@ x_make_frame_visible (f)
         input_signal_count < count && !FRAME_VISIBLE_P (f);)
       {
        /* Force processing of queued events.  */
-        /* NTEMACS_TODO: x_sync equivalent?  */
+        /* TODO: x_sync equivalent?  */
 
        /* Machines that do polling rather than SIGIO have been observed
           to go into a busy-wait here.  So we'll fake an alarm signal
@@ -9498,7 +9995,7 @@ w32_initialize_display_info (display_name)
   dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
   dpyinfo->mouse_face_window = Qnil;
 
-  /* NTEMACS_TODO: dpyinfo->gray */
+  /* TODO: dpyinfo->gray */
 
 }
 
@@ -9625,7 +10122,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)
@@ -9753,8 +10250,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
 
@@ -9775,8 +10272,6 @@ w32_initialize ()
 void
 syms_of_w32term ()
 {
-  Lisp_Object codepage;
-
   staticpro (&w32_display_name_list);
   w32_display_name_list = Qnil;