Replace bcopy, bzero, bcmp by memcpy, memmove, memset, memcmp
[bpt/emacs.git] / src / w32term.c
index 101b7d5..7ace4b0 100644 (file)
@@ -1,7 +1,7 @@
 /* Implementation of GUI terminal on the Microsoft W32 API.
    Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998,
                  1999, 2000, 2001, 2002, 2003, 2004, 2005,
-                 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -22,6 +22,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <setjmp.h>
 #include "lisp.h"
 #include "blockinput.h"
 #include "w32term.h"
@@ -31,8 +32,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <ctype.h>
 #include <errno.h>
-#include <setjmp.h>
 #include <sys/stat.h>
+#include <imm.h>
 
 #include "charset.h"
 #include "character.h"
@@ -54,7 +55,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "keymap.h"
 
 #include "w32heap.h"
-#include "w32bdf.h"
 #include <shellapi.h>
 
 #include "font.h"
@@ -87,8 +87,7 @@ static int any_help_event_p;
 /* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
 static Lisp_Object last_window;
 
-/* Non-zero means make use of UNDERLINE_POSITION font properties.
-   (Not yet supported, see TODO in x_draw_glyph_string.)  */
+/* Non-zero means make use of UNDERLINE_POSITION font properties.  */
 int x_use_underline_position_properties;
 
 /* Non-zero means to draw the underline at the same place as the descent line.  */
@@ -97,13 +96,11 @@ int x_underline_at_descent_line;
 
 extern unsigned int msh_mousewheel;
 
-extern void free_frame_menubar ();
+extern void free_frame_menubar (struct frame *);
 
 extern int w32_codepage_for_font (char *fontname);
 extern Cursor w32_load_cursor (LPCTSTR name);
 
-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
@@ -131,19 +128,28 @@ typedef struct tagWCRANGE
   USHORT cGlyphs;
 } WCRANGE;
 
-typedef struct tagGLYPHSET 
+typedef struct tagGLYPHSET
 {
   DWORD cbThis;
   DWORD flAccel;
   DWORD cGlyphsSupported;
   DWORD cRanges;
   WCRANGE ranges[1];
-} GLYPHSET;  
+} GLYPHSET;
 
 #endif
 
-/* Dynamic linking to GetFontUnicodeRanges (not available on 95, 98, ME).  */
-DWORD (PASCAL *pfnGetFontUnicodeRanges) (HDC device, GLYPHSET *ranges);
+/* Dynamic linking to SetLayeredWindowAttribute (only since 2000).  */
+BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
+
+#ifndef LWA_ALPHA
+#define LWA_ALPHA 0x02
+#endif
+/* WS_EX_LAYERED is defined unconditionally by MingW, but only for W2K and
+   later targets by MSVC headers.  */
+#ifndef WS_EX_LAYERED
+#define WS_EX_LAYERED 0x80000
+#endif
 
 /* Frame being updated by update_frame.  This is declared in term.c.
    This is set by update_begin and looked at by all the
@@ -162,14 +168,6 @@ int w32_system_caret_x;
 int w32_system_caret_y;
 int w32_use_visible_system_caret;
 
-/* Flag to enable Unicode output in case users wish to use programs
-   like Twinbridge on '95 rather than installed system level support
-   for Far East languages.  */
-int w32_enable_unicode_output;
-
-/* Flag to enable Cleartype hack for font metrics.  */
-static int cleartype_active;
-
 DWORD dwWindowsThreadId = 0;
 HANDLE hWindowsThread = NULL;
 DWORD dwMainThreadId = 0;
@@ -184,7 +182,6 @@ int last_scroll_bar_drag_pos;
 /* Mouse movement. */
 
 /* Where the mouse was last time we reported a mouse event.  */
-
 static RECT last_mouse_glyph;
 static FRAME_PTR last_mouse_glyph_frame;
 static Lisp_Object last_mouse_press_frame;
@@ -219,12 +216,10 @@ static int last_mouse_scroll_bar_pos;
    along with the position query.  So, we just keep track of the time
    of the last movement we received, and return that in hopes that
    it's somewhat accurate.  */
-
 static Time last_mouse_movement_time;
 
 /* Incremented by w32_read_socket whenever it really tries to read
    events.  */
-
 #ifdef __STDC__
 static int volatile input_signal_count;
 #else
@@ -233,53 +228,49 @@ static int input_signal_count;
 
 extern Lisp_Object Vcommand_line_args, Vsystem_name;
 
-#ifndef USE_CRT_DLL
-extern int errno;
-#endif
-
 /* A mask of extra modifier bits to put into every keyboard char.  */
-
 extern EMACS_INT extra_keyboard_modifiers;
 
-static void x_update_window_end P_ ((struct window *, int, int));
-static void w32_handle_tool_bar_click P_ ((struct frame *,
-                                          struct input_event *));
-static void w32_define_cursor P_ ((Window, Cursor));
-
-void x_lower_frame P_ ((struct frame *));
-void x_scroll_bar_clear P_ ((struct frame *));
-void x_wm_set_size_hint P_ ((struct frame *, long, int));
-void x_raise_frame P_ ((struct frame *));
-void x_set_window_size P_ ((struct frame *, int, int, int));
-void x_wm_set_window_state P_ ((struct frame *, int));
-void x_wm_set_icon_pixmap P_ ((struct frame *, int));
-static void w32_initialize P_ ((void));
-static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
-int x_compute_min_glyph_bounds P_ ((struct frame *));
-static void x_update_end P_ ((struct frame *));
-static void w32_frame_up_to_date P_ ((struct frame *));
-static void w32_set_terminal_modes P_ ((struct terminal *));
-static void w32_reset_terminal_modes P_ ((struct terminal *));
-static void x_clear_frame P_ ((struct frame *));
-static void frame_highlight P_ ((struct frame *));
-static void frame_unhighlight P_ ((struct frame *));
-static void x_new_focus_frame P_ ((struct w32_display_info *,
-                                  struct frame *));
-static void x_focus_changed P_ ((int, int, struct w32_display_info *,
-                                 struct frame *, struct input_event *));
-static void w32_detect_focus_change P_ ((struct w32_display_info *,
-                                       W32Msg *, struct input_event *));
-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,
-                                  enum text_cursor_kinds));
-static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, int, HDC));
-static BOOL my_show_window P_ ((struct frame *, HWND, int));
-static void my_set_window_pos P_ ((HWND, HWND, int, int, int, int, UINT));
-static void my_set_focus P_ ((struct frame *, HWND));
-static void my_set_foreground_window P_ ((HWND));
-static void my_destroy_window P_ ((struct frame *, HWND));
+/* Keyboard code page - may be changed by language-change events.  */
+static int keyboard_codepage;
+
+static void x_update_window_end (struct window *, int, int);
+static void w32_handle_tool_bar_click (struct frame *,
+                                       struct input_event *);
+static void w32_define_cursor (Window, Cursor);
+
+void x_lower_frame (struct frame *);
+void x_scroll_bar_clear (struct frame *);
+void x_wm_set_size_hint (struct frame *, long, int);
+void x_raise_frame (struct frame *);
+void x_set_window_size (struct frame *, int, int, int);
+void x_wm_set_window_state (struct frame *, int);
+void x_wm_set_icon_pixmap (struct frame *, int);
+static void w32_initialize (void);
+static void x_update_end (struct frame *);
+static void w32_frame_up_to_date (struct frame *);
+static void w32_set_terminal_modes (struct terminal *);
+static void w32_reset_terminal_modes (struct terminal *);
+static void x_clear_frame (struct frame *);
+static void frame_highlight (struct frame *);
+static void frame_unhighlight (struct frame *);
+static void x_new_focus_frame (struct w32_display_info *,
+                               struct frame *);
+static void x_focus_changed (int, int, struct w32_display_info *,
+                             struct frame *, struct input_event *);
+static void w32_detect_focus_change (struct w32_display_info *,
+                                     W32Msg *, struct input_event *);
+static void w32_frame_rehighlight (struct frame *);
+static void x_frame_rehighlight (struct w32_display_info *);
+static void x_draw_hollow_cursor (struct window *, struct glyph_row *);
+static void x_draw_bar_cursor (struct window *, struct glyph_row *, int,
+                               enum text_cursor_kinds);
+static void w32_clip_to_row (struct window *, struct glyph_row *, int, HDC);
+static BOOL my_show_window (struct frame *, HWND, int);
+static void my_set_window_pos (HWND, HWND, int, int, int, int, UINT);
+static void my_set_focus (struct frame *, HWND);
+static void my_set_foreground_window (HWND);
+static void my_destroy_window (struct frame *, HWND);
 
 static Lisp_Object Qvendor_specific_keysyms;
 
@@ -303,9 +294,7 @@ struct record event_record[100];
 
 int event_record_index;
 
-record_event (locus, type)
-     char *locus;
-     int type;
+record_event (char *locus, int type)
 {
   if (event_record_index == sizeof (event_record) / sizeof (struct record))
     event_record_index = 0;
@@ -319,7 +308,7 @@ record_event (locus, type)
 \f
 
 void
-XChangeGC (void * ignore, XGCValues* gc, unsigned long mask,
+XChangeGC (void *ignore, XGCValues *gc, unsigned long mask,
           XGCValues *xgcv)
 {
   if (mask & GCForeground)
@@ -330,11 +319,11 @@ XChangeGC (void * ignore, XGCValues* gc, unsigned long mask,
     gc->font = xgcv->font;
 }
 
-XGCValues *XCreateGC (void * ignore, Window window, unsigned long mask,
-                      XGCValues *xgcv)
+XGCValues *
+XCreateGC (void *ignore, Window window, unsigned long mask, XGCValues *xgcv)
 {
   XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
-  bzero (gc, sizeof (XGCValues));
+  memset (gc, 0, sizeof (XGCValues));
 
   XChangeGC (ignore, gc, mask, xgcv);
 
@@ -342,8 +331,8 @@ XGCValues *XCreateGC (void * ignore, Window window, unsigned long mask,
 }
 
 void
-XGetGCValues (voidignore, XGCValues *gc,
-                   unsigned long mask, XGCValues *xgcv)
+XGetGCValues (void *ignore, XGCValues *gc,
+             unsigned long mask, XGCValues *xgcv)
 {
   XChangeGC (ignore, xgcv, mask, gc);
 }
@@ -385,11 +374,7 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
 
 /* Draw a filled rectangle at the specified position. */
 void
-w32_fill_rect (f, hdc, pix, lprect)
-     FRAME_PTR f;
-     HDC hdc;
-     COLORREF pix;
-     RECT * lprect;
+w32_fill_rect (FRAME_PTR f, HDC hdc, COLORREF pix, RECT *lprect)
 {
   HBRUSH hb;
 
@@ -399,8 +384,7 @@ w32_fill_rect (f, hdc, pix, lprect)
 }
 
 void
-w32_clear_window (f)
-     FRAME_PTR f;
+w32_clear_window (FRAME_PTR f)
 {
   RECT rect;
   HDC hdc = get_frame_dc (f);
@@ -417,6 +401,72 @@ w32_clear_window (f)
   release_frame_dc (f, hdc);
 }
 
+#define OPAQUE_FRAME 255
+
+void
+x_set_frame_alpha (struct frame *f)
+{
+  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+  double alpha = 1.0;
+  double alpha_min = 1.0;
+  BYTE opac;
+  LONG ex_style;
+  HWND window = FRAME_W32_WINDOW (f);
+
+  /* Older versions of Windows do not support transparency.  */
+  if (!pfnSetLayeredWindowAttributes)
+    return;
+
+  if (dpyinfo->x_highlight_frame == f)
+    alpha = f->alpha[0];
+  else
+    alpha = f->alpha[1];
+
+  if (FLOATP (Vframe_alpha_lower_limit))
+    alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
+  else if (INTEGERP (Vframe_alpha_lower_limit))
+    alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
+
+  if (alpha < 0.0)
+    return;
+  else if (alpha > 1.0)
+    alpha = 1.0;
+  else if (alpha < alpha_min && alpha_min <= 1.0)
+    alpha = alpha_min;
+
+  opac = alpha * OPAQUE_FRAME;
+
+  ex_style = GetWindowLong (window, GWL_EXSTYLE);
+
+  if (opac == OPAQUE_FRAME)
+    ex_style &= ~WS_EX_LAYERED;
+  else
+    ex_style |= WS_EX_LAYERED;
+
+  SetWindowLong (window, GWL_EXSTYLE, ex_style);
+
+  if (opac != OPAQUE_FRAME)
+    pfnSetLayeredWindowAttributes (window, 0, opac, LWA_ALPHA);
+}
+
+int
+x_display_pixel_height (struct w32_display_info *dpyinfo)
+{
+  HDC dc = GetDC (NULL);
+  int pixels = GetDeviceCaps (dc, VERTRES);
+  ReleaseDC (NULL, dc);
+  return pixels;
+}
+
+int
+x_display_pixel_width (struct w32_display_info *dpyinfo)
+{
+  HDC dc = GetDC (NULL);
+  int pixels = GetDeviceCaps (dc, HORZRES);
+  ReleaseDC (NULL, dc);
+  return pixels;
+}
+
 \f
 /***********************************************************************
                    Starting and ending an update
@@ -428,8 +478,7 @@ w32_clear_window (f)
    each window being updated.  */
 
 static void
-x_update_begin (f)
-     struct frame *f;
+x_update_begin (struct frame *f)
 {
   struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
 
@@ -451,8 +500,7 @@ x_update_begin (f)
    position of W.  */
 
 static void
-x_update_window_begin (w)
-     struct window *w;
+x_update_window_begin (struct window *w)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
@@ -511,9 +559,7 @@ x_update_window_begin (w)
 /* Draw a vertical window border from (x,y0) to (x,y1)  */
 
 static void
-w32_draw_vertical_window_border (w, x, y0, y1)
-     struct window *w;
-     int x, y0, y1;
+w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   RECT r;
@@ -550,9 +596,8 @@ w32_draw_vertical_window_border (w, x, y0, y1)
    here. */
 
 static void
-x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
-     struct window *w;
-     int cursor_on_p, mouse_face_overwritten_p;
+x_update_window_end (struct window *w, int cursor_on_p,
+                    int mouse_face_overwritten_p)
 {
   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
 
@@ -596,8 +641,7 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
    update_end.  */
 
 static void
-x_update_end (f)
-     struct frame *f;
+x_update_end (struct frame *f)
 {
   if (! FRAME_W32_P (f))
     return;
@@ -612,8 +656,7 @@ x_update_end (f)
    updated_window is not available here.  */
 
 static void
-w32_frame_up_to_date (f)
-     struct frame *f;
+w32_frame_up_to_date (struct frame *f)
 {
   if (FRAME_W32_P (f))
     {
@@ -642,8 +685,7 @@ w32_frame_up_to_date (f)
    between bitmaps to be drawn between current row and DESIRED_ROW.  */
 
 static void
-x_after_update_window_line (desired_row)
-     struct glyph_row *desired_row;
+x_after_update_window_line (struct glyph_row *desired_row)
 {
   struct window *w = updated_window;
   struct frame *f;
@@ -670,11 +712,6 @@ x_after_update_window_line (desired_row)
     {
       int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
 
-      /* Internal border is drawn below the tool bar.  */
-      if (WINDOWP (f->tool_bar_window)
-         && w == XWINDOW (f->tool_bar_window))
-       y -= width;
-
       BLOCK_INPUT;
       {
        HDC hdc = get_frame_dc (f);
@@ -694,10 +731,8 @@ x_after_update_window_line (desired_row)
    drawn.  */
 
 static void
-w32_draw_fringe_bitmap (w, row, p)
-     struct window *w;
-     struct glyph_row *row;
-     struct draw_fringe_bitmap_params *p;
+w32_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
+                       struct draw_fringe_bitmap_params *p)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   HDC hdc;
@@ -835,10 +870,7 @@ w32_draw_fringe_bitmap (w, row, p)
 }
 
 static void
-w32_define_fringe_bitmap (which, bits, h, wd)
-     int which;
-     unsigned short *bits;
-     int h, wd;
+w32_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
 {
   if (which >= max_fringe_bmp)
     {
@@ -853,8 +885,7 @@ w32_define_fringe_bitmap (which, bits, h, wd)
 }
 
 static void
-w32_destroy_fringe_bitmap (which)
-     int which;
+w32_destroy_fringe_bitmap (int which)
 {
   if (which >= max_fringe_bmp)
     return;
@@ -892,634 +923,39 @@ w32_reset_terminal_modes (struct terminal *term)
 
 /* Function prototypes of this page.  */
 
-#if OLD_FONT
-
-XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, int));
-static int w32_encode_char P_ ((int, wchar_t *, struct font_info *,
-                               struct charset *, int *));
-
-
-/* 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 int
-w32_bdf_per_char_metric (font, char2b, dim, pcm)
-     XFontStruct *font;
-     wchar_t *char2b;
-     int dim;
-     XCharStruct * pcm;
-{
-  glyph_metric * bdf_metric;
-  char buf[2];
-
-  if (dim == 1)
-    buf[0] = (char)(*char2b);
-  else
-    {
-      buf[0] = XCHAR2B_BYTE1 (char2b);
-      buf[1] = XCHAR2B_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;
-
-      return 1;
-    }
-  return 0;
-}
-
-
-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;
-
-  xassert (font && char2b);
-  xassert (font->hfont);
-  xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT);
-
-  old_font = SelectObject (hdc, font->hfont);
-
-  if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
-    {
-      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)
-       {
-#if 0
-         /* Disabled until we can find a way to get the right results
-            on all versions of Windows.  */
-
-         /* Don't trust the ABC widths.  For synthesized fonts they are
-            wrong, and so is the result of GetCharWidth()!  */
-         int real_width;
-         GetCharWidth (hdc, *char2b, *char2b, &real_width);
-#endif
-         if (cleartype_active)
-           {
-             /* Cleartype antialiasing causes characters to overhang
-                by a pixel on each side compared with what GetCharABCWidths
-                reports.  */
-             char_widths.abcA -= 1;
-             char_widths.abcC -= 1;
-             char_widths.abcB += 2;
-           }
-
-         pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
-#if 0
-         /* As far as I can tell, this is the best way to determine what
-            ExtTextOut will do with the broken font.  */
-         if (pcm->width != real_width)
-           pcm->width = (pcm->width + real_width) / 2;
-#endif
-         pcm->lbearing = char_widths.abcA;
-         pcm->rbearing = char_widths.abcA + char_widths.abcB;
-         pcm->ascent = FONT_BASE (font);
-         pcm->descent = FONT_DESCENT (font);
-       }
-    }
-
-  if (!retval)
-    {
-      /* 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);
-      else
-       retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz);
-
-      if (retval)
-       {
-         pcm->width = sz.cx;
-         pcm->rbearing = sz.cx + font->tm.tmOverhang;
-         pcm->lbearing = 0;
-         pcm->ascent = FONT_BASE (font);
-         pcm->descent = FONT_DESCENT (font);
-       }
-    }
-
-
-  if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
-    {
-      retval = FALSE;
-    }
-
-  SelectObject (hdc, old_font);
-  ReleaseDC (NULL, hdc);
-
-  return retval;
-}
-
-
-XCharStruct *
-w32_per_char_metric (font, char2b, font_type)
-     XFontStruct *font;
-     wchar_t *char2b;
-     int /* enum w32_char_font_type */ font_type;
-{
-  /* The result metric information.  */
-  XCharStruct *pcm;
-  BOOL retval;
-
-  xassert (font && char2b);
-
-  /* TODO: This function is currently called through the RIF, and in
-     some cases font_type is UNKNOWN_FONT. We currently allow the
-     cached metrics to be used, which seems to work, but in cases
-     where font_type is UNKNOWN_FONT, we probably haven't encoded
-     char2b appropriately. All callers need checking to see what they
-     are passing.  This is most likely to affect variable width fonts
-     outside the Latin-1 range, particularly in languages like Thai
-     that rely on rbearing and lbearing to provide composition. I
-     don't think that is working currently anyway, but we don't seem
-     to have anyone testing such languages on Windows.  */
-
-  /* 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];
-
-  xassert (font_type != UNKNOWN_FONT);
-
-  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_WIDTH (font);
-          font->max_bounds.lbearing = -font->bdf->llx;
-          font->max_bounds.rbearing = FONT_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);
-    }
-}
-
-/* Determine if a font is double byte. */
-static int
-w32_font_is_double_byte (XFontStruct *font)
-{
-  return font->double_byte_p;
-}
-
-
-static BOOL
-w32_use_unicode_for_codepage (codepage)
-     int codepage;
-{
-  /* If the current codepage is supported, use Unicode for output. */
-  return (w32_enable_unicode_output
-          && codepage != CP_8BIT
-          && (codepage == CP_UNICODE || IsValidCodePage (codepage)));
-}
-
-/* Encode CHAR2B using encoding information from FONT_INFO.  CHAR2B is
-   the two-byte form of C.  Encoding is returned in *CHAR2B.  */
-
-static int /* enum w32_char_font_type */
-w32_encode_char (c, char2b, font_info, charset, two_byte_p)
-     int c;
-     wchar_t *char2b;
-     struct font_info *font_info;
-     struct charset *charset;
-     int * two_byte_p;
-{
-  int codepage;
-  int unicode_p = 0;
-  int internal_two_byte_p = 0;
-
-  XFontStruct *font = font_info->font;
-
-  internal_two_byte_p = w32_font_is_double_byte (font);
-  codepage = font_info->codepage;
-
-  /* If font can output unicode, use the original unicode character.  */
-  if ( font && !font->bdf && w32_use_unicode_for_codepage (codepage)
-       && c >= 0x100)
-    {
-      *char2b = c;
-      unicode_p = 1;
-      internal_two_byte_p = 1;
-    }
-
-  /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
-     This may be either a program in a special encoder language or a
-     fixed encoding.  */
-  else if (font_info->font_encoder)
-    {
-      /* It's a program.  */
-      struct ccl_program *ccl = font_info->font_encoder;
-
-      if (CHARSET_DIMENSION (charset) == 1)
-       {
-         ccl->reg[0] = CHARSET_ID (charset);
-         ccl->reg[1] = XCHAR2B_BYTE2 (char2b);
-         ccl->reg[2] = -1;
-       }
-      else
-       {
-         ccl->reg[0] = CHARSET_ID (charset);
-         ccl->reg[1] = XCHAR2B_BYTE1 (char2b);
-         ccl->reg[2] = XCHAR2B_BYTE2 (char2b);
-       }
-
-      ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
-
-      /* We assume that MSBs are appropriately set/reset by CCL
-        program.  */
-      if (!internal_two_byte_p)        /* 1-byte font */
-       STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
-      else
-       STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
-    }
-  else if (font_info->encoding_type)
-    {
-      /* Fixed encoding scheme.  See fontset.h for the meaning of the
-        encoding numbers.  */
-      unsigned char enc = font_info->encoding_type;
-
-      if ((enc == 1 || enc == 2)
-         && CHARSET_DIMENSION (charset) == 2)
-       STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b) | 0x80, XCHAR2B_BYTE2 (char2b));
-
-      if (enc == 1 || enc == 3          || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
-       STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b) | 0x80);
-      else if (enc == 4)
-        {
-          int code = (int) (*char2b);
-
-         JIS_TO_SJIS (code);
-          STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
-        }
-    }
-
-  if (two_byte_p)
-    *two_byte_p = internal_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_2D_FONT;
-  else if (unicode_p)
-    return UNICODE_FONT;
-  else
-    return ANSI_FONT;
-}
-
-
-/* Return a char-table whose elements are t if the font FONT_INFO
-   contains a glyph for the corresponding character, and nil if not.
-
-   Fixme: For the moment, this function works only for fonts whose
-   glyph encoding is the same as Unicode (e.g. ISO10646-1 fonts).  */
-
-Lisp_Object
-x_get_font_repertory (f, font_info)
-     FRAME_PTR f;
-     struct font_info *font_info;
-{
-  XFontStruct *font = (XFontStruct *) font_info->font;
-  Lisp_Object table;
-  int min_byte1, max_byte1, min_byte2, max_byte2;
-  int c;
-  struct charset *charset = CHARSET_FROM_ID (font_info->charset);
-  int offset = CHARSET_OFFSET (charset);
-
-  table = Fmake_char_table (Qnil, Qnil);
-
-  if (!font->bdf && pfnGetFontUnicodeRanges)
-    {
-      GLYPHSET *glyphset;
-      DWORD glyphset_size;
-      HDC display = get_frame_dc (f);
-      HFONT prev_font;
-      int i;
-
-      prev_font = SelectObject (display, font->hfont);
-
-      /* First call GetFontUnicodeRanges to find out how big a structure
-        we need.  */
-      glyphset_size = pfnGetFontUnicodeRanges (display, NULL);
-      if (glyphset_size)
-       {
-         glyphset = (GLYPHSET *) alloca (glyphset_size);
-         glyphset->cbThis = glyphset_size;
-
-         /* Now call it again to get the ranges.  */
-         glyphset_size = pfnGetFontUnicodeRanges (display, glyphset);
-
-         if (glyphset_size)
-           {
-             /* Store the ranges in TABLE.  */
-             for (i = 0; i < glyphset->cRanges; i++)
-               {
-                 int from = glyphset->ranges[i].wcLow;
-                 int to = from + glyphset->ranges[i].cGlyphs - 1;
-                 char_table_set_range (table, from, to, Qt);
-               }
-           }
-       }
-
-      SelectObject (display, prev_font);
-      release_frame_dc (f, display);
-
-      /* If we got the information we wanted above, then return it.  */
-      if (glyphset_size)
-       return table;
-    }
-
-#if 0 /* TODO: Convert to work on Windows so BDF and older platforms work.  */
-  /* When GetFontUnicodeRanges is not available or does not work,
-     work it out manually.  */
-  min_byte1 = font->min_byte1;
-  max_byte1 = font->max_byte1;
-  min_byte2 = font->min_char_or_byte2;
-  max_byte2 = font->max_char_or_byte2;
-  if (min_byte1 == 0 && max_byte1 == 0)
-    {
-      if (! font->per_char || font->all_chars_exist == True)
-        {
-          if (offset >= 0)
-            char_table_set_range (table, offset + min_byte2,
-                                  offset + max_byte2, Qt);
-          else
-            for (; min_byte2 <= max_byte2; min_byte2++)
-              {
-                c = DECODE_CHAR (charset, min_byte2);
-                CHAR_TABLE_SET (table, c, Qt);
-              }
-        }
-      else
-       {
-         XCharStruct *pcm = font->per_char;
-         int from = -1;
-         int i;
-
-         for (i = min_byte2; i <= max_byte2; i++, pcm++)
-           {
-             if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
-               {
-                 if (from >= 0)
-                   {
-                      if (offset >= 0)
-                        char_table_set_range (table, offset + from,
-                                              offset + i - 1, Qt);
-                      else
-                        for (; from < i; from++)
-                          {
-                            c = DECODE_CHAR (charset, from);
-                            CHAR_TABLE_SET (table, c, Qt);
-                          }
-                     from = -1;
-                   }
-               }
-             else if (from < 0)
-               from = i;
-           }
-         if (from >= 0)
-            {
-              if (offset >= 0)
-                char_table_set_range (table, offset + from, offset + i - 1,
-                                      Qt);
-              else
-                for (; from < i; from++)
-                  {
-                    c = DECODE_CHAR (charset, from);
-                    CHAR_TABLE_SET (table, c, Qt);
-                  }
-            }
-       }
-    }
-  else
-    {
-      if (! font->per_char || font->all_chars_exist == True)
-       {
-         int i, j;
-
-          if (offset >= 0)
-            for (i = min_byte1; i <= max_byte1; i++)
-              char_table_set_range
-                (table, offset + ((i << 8) | min_byte2),
-                 offset + ((i << 8) | max_byte2), Qt);
-          else
-            for (i = min_byte1; i <= max_byte1; i++)
-              for (j = min_byte2; j <= max_byte2; j++)
-                {
-                  unsiged code = (i << 8) | j;
-                  c = DECODE_CHAR (charset, code);
-                  CHAR_TABLE_SET (table, c, Qt);
-                }
-       }
-      else
-       {
-         XCharStruct *pcm = font->per_char;
-         int i;
-
-         for (i = min_byte1; i <= max_byte1; i++)
-           {
-             int from = -1;
-             int j;
-
-             for (j = min_byte2; j <= max_byte2; j++, pcm++)
-               {
-                 if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
-                   {
-                     if (from >= 0)
-                       {
-                          if (offset >= 0)
-                            char_table_set_range
-                              (table, offset + ((i << 8) | from),
-                               offset + ((i << 8) | (j - 1)), Qt);
-                          else
-                            {
-                              for (; from < j; from++)
-                                {
-                                  unsigned code = (i << 8) | from;
-                                  c = ENCODE_CHAR (charset, code);
-                                  CHAR_TABLE_SET (table, c, Qt);
-                                }
-                            }
-                         from = -1;
-                       }
-                   }
-                 else if (from < 0)
-                   from = j;
-               }
-             if (from >= 0)
-                {
-                  if (offset >= 0)
-                    char_table_set_range
-                      (table, offset + ((i << 8) | from),
-                       offset + ((i << 8) | (j - 1)), Qt);
-                  else
-                    {
-                      for (; from < j; from++)
-                        {
-                          unsigned code = (i << 8) | from;
-                          c = DECODE_CHAR (charset, code);
-                          CHAR_TABLE_SET (table, c, Qt);
-                        }
-                    }
-                }
-           }
-       }
-    }
-#endif
-  return table;
-}
-
-\f
-/***********************************************************************
-                           Glyph display
- ***********************************************************************/
-
-
-/* Encapsulate the different ways of displaying text under W32.  */
-
-static void
-w32_text_out (s, x, y,chars,nchars)
-     struct glyph_string * s;
-     int x, y;
-     wchar_t * chars;
-     int nchars;
-{
-  int charset_dim = w32_font_is_double_byte (s->font) ? 2 : 1;
-  if (s->font->bdf)
-    w32_BDF_TextOut (s->font->bdf, s->hdc,
-                     x, y, (char *) chars, charset_dim,
-                     nchars * charset_dim, 0);
-  else if (s->first_glyph->font_type == UNICODE_FONT)
-    ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
-  else
-    ExtTextOutA (s->hdc, x, y, 0, NULL, (char *) chars,
-                nchars * charset_dim, NULL);
-}
-
-#endif /* OLD_FONT */
-
-static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
-static void x_set_glyph_string_gc P_ ((struct glyph_string *));
-static void x_draw_glyph_string_background P_ ((struct glyph_string *,
-                                               int));
-static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
-static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
-static void x_draw_glyph_string_box P_ ((struct glyph_string *));
-static void x_draw_glyph_string  P_ ((struct glyph_string *));
-static void x_set_cursor_gc P_ ((struct glyph_string *));
-static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
-static void x_set_mouse_face_gc P_ ((struct glyph_string *));
+static void x_set_glyph_string_clipping (struct glyph_string *);
+static void x_set_glyph_string_gc (struct glyph_string *);
+static void x_draw_glyph_string_background (struct glyph_string *,
+                                            int);
+static void x_draw_glyph_string_foreground (struct glyph_string *);
+static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
+static void x_draw_glyph_string_box (struct glyph_string *);
+static void x_draw_glyph_string  (struct glyph_string *);
+static void x_set_cursor_gc (struct glyph_string *);
+static void x_set_mode_line_face_gc (struct glyph_string *);
+static void x_set_mouse_face_gc (struct glyph_string *);
 static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
-static void w32_setup_relief_color P_ ((struct frame *, struct relief *,
-                                        double, int, COLORREF));
-static void x_setup_relief_colors P_ ((struct glyph_string *));
-static void x_draw_image_glyph_string P_ ((struct glyph_string *));
-static void x_draw_image_relief P_ ((struct glyph_string *));
-static void x_draw_image_foreground P_ ((struct glyph_string *));
-static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
-static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
-                                          int, int, int));
-static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
-                                     int, int, int, int, int, int,
-                                     RECT *));
-static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
-                                int, int, int, RECT *));
-
-#if GLYPH_DEBUG
-static void x_check_font P_ ((struct frame *, XFontStruct *));
-#endif
+static void w32_setup_relief_color (struct frame *, struct relief *,
+                                    double, int, COLORREF);
+static void x_setup_relief_colors (struct glyph_string *);
+static void x_draw_image_glyph_string (struct glyph_string *);
+static void x_draw_image_relief (struct glyph_string *);
+static void x_draw_image_foreground (struct glyph_string *);
+static void w32_draw_image_foreground_1 (struct glyph_string *, HBITMAP);
+static void x_clear_glyph_string_rect (struct glyph_string *, int,
+                                       int, int, int);
+static void w32_draw_relief_rect (struct frame *, int, int, int, int,
+                                  int, int, int, int, int, int,
+                                  RECT *);
+static void w32_draw_box_rect (struct glyph_string *, int, int, int, int,
+                               int, int, int, RECT *);
 
 
 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
    face.  */
 
 static void
-x_set_cursor_gc (s)
-     struct glyph_string *s;
+x_set_cursor_gc (struct glyph_string *s)
 {
   if (s->font == FRAME_FONT (s->f)
       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
@@ -1570,8 +1006,7 @@ x_set_cursor_gc (s)
 /* Set up S->gc of glyph string S for drawing text in mouse face.  */
 
 static void
-x_set_mouse_face_gc (s)
-     struct glyph_string *s;
+x_set_mouse_face_gc (struct glyph_string *s)
 {
   int face_id;
   struct face *face;
@@ -1624,8 +1059,7 @@ x_set_mouse_face_gc (s)
    matrix was built, so there isn't much to do, here.  */
 
 static INLINE void
-x_set_mode_line_face_gc (s)
-     struct glyph_string *s;
+x_set_mode_line_face_gc (struct glyph_string *s)
 {
   s->gc = s->face->gc;
 }
@@ -1636,8 +1070,7 @@ x_set_mode_line_face_gc (s)
    pattern.  */
 
 static INLINE void
-x_set_glyph_string_gc (s)
-     struct glyph_string *s;
+x_set_glyph_string_gc (struct glyph_string *s)
 {
   PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
 
@@ -1682,8 +1115,7 @@ x_set_glyph_string_gc (s)
    line or menu if we don't have X toolkit support.  */
 
 static INLINE void
-x_set_glyph_string_clipping (s)
-     struct glyph_string *s;
+x_set_glyph_string_clipping (struct glyph_string *s)
 {
   RECT *r = s->clip;
   int n = get_glyph_string_clip_rects (s, r, 2);
@@ -1711,8 +1143,8 @@ x_set_glyph_string_clipping (s)
    the area of SRC.  */
 
 static void
-x_set_glyph_string_clipping_exactly (src, dst)
-     struct glyph_string *src, *dst;
+x_set_glyph_string_clipping_exactly (struct glyph_string *src,
+                                    struct glyph_string *dst)
 {
   RECT r;
 
@@ -1722,17 +1154,6 @@ x_set_glyph_string_clipping_exactly (src, dst)
   r.bottom = r.top + src->height;
   dst->clip[0] = r;
   dst->num_clips = 1;
-#if OLD_FONT
-    {
-  struct glyph_string *clip_head = src->clip_head;
-  struct glyph_string *clip_tail = src->clip_tail;
-
-  /* This foces clipping just this glyph string.  */
-  src->clip_head = src->clip_tail = src;
-  get_glyph_string_clip_rect (src, &r);
-  src->clip_head = clip_head, src->clip_tail = clip_tail;
-    }
-#endif /* OLD_FONT */
   w32_set_clip_rectangle (dst->hdc, &r);
 }
 
@@ -1740,8 +1161,7 @@ x_set_glyph_string_clipping_exactly (src, dst)
    Compute left and right overhang of glyph string S.  */
 
 static void
-w32_compute_glyph_string_overhangs (s)
-     struct glyph_string *s;
+w32_compute_glyph_string_overhangs (struct glyph_string *s)
 {
   if (s->cmp == NULL
       && s->first_glyph->type == CHAR_GLYPH
@@ -1769,9 +1189,8 @@ w32_compute_glyph_string_overhangs (s)
 /* Fill rectangle X, Y, W, H with background color of glyph string S.  */
 
 static INLINE void
-x_clear_glyph_string_rect (s, x, y, w, h)
-     struct glyph_string *s;
-     int x, y, w, h;
+x_clear_glyph_string_rect (struct glyph_string *s,
+                          int x, int y, int w, int h)
 {
   int real_x = x;
   int real_y = y;
@@ -1801,9 +1220,7 @@ x_clear_glyph_string_rect (s, x, y, w, h)
    contains the first component of a composition.  */
 
 static void
-x_draw_glyph_string_background (s, force_p)
-     struct glyph_string *s;
-     int force_p;
+x_draw_glyph_string_background (struct glyph_string *s, int force_p)
 {
   /* Nothing to do if background has already been drawn or if it
      shouldn't be drawn in the first place.  */
@@ -1828,8 +1245,6 @@ x_draw_glyph_string_background (s, force_p)
         if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
               || s->font_not_found_p
               || s->extends_to_end_of_line_p
-              || FONT_COMPAT (s->font)->bdf
-              || cleartype_active
               || force_p)
        {
          x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
@@ -1844,11 +1259,9 @@ x_draw_glyph_string_background (s, force_p)
 /* Draw the foreground of glyph string S.  */
 
 static void
-x_draw_glyph_string_foreground (s)
-     struct glyph_string *s;
+x_draw_glyph_string_foreground (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.  */
@@ -1858,19 +1271,10 @@ x_draw_glyph_string_foreground (s)
   else
     x = s->x;
 
-  if (s->for_overlaps || (s->background_filled_p && s->hl != DRAW_CURSOR)
-      || cleartype_active)
-    SetBkMode (s->hdc, TRANSPARENT);
-  else
-    SetBkMode (s->hdc, OPAQUE);
-
   SetTextColor (s->hdc, s->gc->foreground);
   SetBkColor (s->hdc, s->gc->background);
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
-  if (s->font && FONT_COMPAT (s->font)->hfont)
-    old_font = SelectObject (s->hdc, FONT_COMPAT (s->font)->hfont);
-
   /* Draw characters of S as rectangles if S's font could not be
      loaded. */
   if (s->font_not_found_p)
@@ -1886,12 +1290,15 @@ x_draw_glyph_string_foreground (s)
     }
   else
     {
-      int boff = s->font->baseline_offset;
       struct font *font = s->font;
+      int boff = font->baseline_offset;
       int y;
+      HFONT old_font;
+
+      old_font = SelectObject (s->hdc, FONT_HANDLE (font));
 
-      if (s->font->vertical_centering)
-       boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
+      if (font->vertical_centering)
+       boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
 
       y = s->ybase - boff;
       if (s->for_overlaps
@@ -1901,20 +1308,18 @@ x_draw_glyph_string_foreground (s)
        font->driver->draw (s, 0, s->nchars, x, y, 1);
       if (s->face->overstrike)
        font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
-    }
 
-  if (s->font && FONT_COMPAT (s->font)->hfont)
-    SelectObject (s->hdc, old_font);
+      SelectObject (s->hdc, old_font);
+    }
 }
 
 /* Draw the foreground of composite glyph string S.  */
 
 static void
-x_draw_composite_glyph_string_foreground (s)
-     struct glyph_string *s;
+x_draw_composite_glyph_string_foreground (struct glyph_string *s)
 {
   int i, j, x;
-  HFONT old_font;
+  struct font *font = s->font;
 
   /* If first glyph of S has a left box line, start drawing the text
      of S to the right of that box line.  */
@@ -1924,85 +1329,81 @@ x_draw_composite_glyph_string_foreground (s)
   else
     x = s->x;
 
-  /* S is a glyph string for a composition.  S->gidx is the index of
-     the first character drawn for glyphs of this composition.
-     S->gidx == 0 means we are drawing the very first character of
+  /* S is a glyph string for a composition.  S->cmp_from is the index
+     of the first character drawn for glyphs of this composition.
+     S->cmp_from == 0 means we are drawing the very first character of
      this composition.  */
 
   SetTextColor (s->hdc, s->gc->foreground);
   SetBkColor (s->hdc, s->gc->background);
-  SetBkMode (s->hdc, TRANSPARENT);
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
-  if (s->font && FONT_COMPAT (s->font)->hfont)
-    old_font = SelectObject (s->hdc, FONT_COMPAT (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)
     {
-      if (s->gidx == 0)
+      if (s->cmp_from == 0)
         w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
                             s->height - 1);
     }
+  else if (! s->first_glyph->u.cmp.automatic)
+    {
+      int y = s->ybase;
+      int width = 0;
+      HFONT old_font;
 
+      old_font = SelectObject (s->hdc, FONT_HANDLE (font));
+
+      for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
+       if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
+         {
+           int xx = x + s->cmp->offsets[j * 2];
+           int yy = y - s->cmp->offsets[j * 2 + 1];
+
+           font->driver->draw (s, j, j + 1, xx, yy, 0);
+           if (s->face->overstrike)
+             font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
+         }
+      SelectObject (s->hdc, old_font);
+    }
+  else
     {
-      struct font *font = s->font;
+      Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
+      Lisp_Object glyph;
       int y = s->ybase;
       int width = 0;
+      HFONT old_font;
 
-      if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
-       {
-         Lisp_Object gstring = AREF (XHASH_TABLE (composition_hash_table)
-                                     ->key_and_value,
-                                     s->cmp->hash_index * 2);
-         int from;
+      old_font = SelectObject (s->hdc, FONT_HANDLE (font));
 
-         for (i = from = 0; i < s->nchars; i++)
+      for (i = j = s->cmp_from; i < s->cmp_to; i++)
+       {
+         glyph = LGSTRING_GLYPH (gstring, i);
+         if (NILP (LGLYPH_ADJUSTMENT (glyph)))
+           width += LGLYPH_WIDTH (glyph);
+         else
            {
-             Lisp_Object g = LGSTRING_GLYPH (gstring, i);
-             Lisp_Object adjustment = LGLYPH_ADJUSTMENT (g);
              int xoff, yoff, wadjust;
 
-             if (! VECTORP (adjustment))
-               {
-                 width += LGLYPH_WIDTH (g);
-                 continue;
-               }
-             if (from < i)
+             if (j < i)
                {
-                 font->driver->draw (s, from, i, x, y, 0);
+                 font->driver->draw (s, j, i, x, y, 0);
                  x += width;
                }
-             xoff = XINT (AREF (adjustment, 0));
-             yoff = XINT (AREF (adjustment, 1));
-             wadjust = XINT (AREF (adjustment, 2));
-
+             xoff = LGLYPH_XOFF (glyph);
+             yoff = LGLYPH_YOFF (glyph);
+             wadjust = LGLYPH_WADJUST (glyph);
              font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
              x += wadjust;
-             from = i + 1;
+             j = i + 1;
              width = 0;
            }
-         if (from < i)
-           font->driver->draw (s, from, i, x, y, 0);
        }
-      else
-       {
-         for (i = 0, j = s->gidx; i < s->nchars; i++, j++)
-           if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
-             {
-               int xx = x + s->cmp->offsets[j * 2];
-               int yy = y - s->cmp->offsets[j * 2 + 1];
+      if (j < i)
+       font->driver->draw (s, j, i, x, y, 0);
 
-               font->driver->draw (s, j, j + 1, xx, yy, 0);
-               if (s->face->overstrike)
-                 font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
-             }
-       }
+      SelectObject (s->hdc, old_font);
     }
-
-  if (s->font && FONT_COMPAT (s->font)->hfont)
-    SelectObject (s->hdc, old_font);
 }
 
 
@@ -2028,11 +1429,8 @@ x_draw_composite_glyph_string_foreground (s)
    Value is non-zero if successful.  */
 
 static int
-w32_alloc_lighter_color (f, color, factor, delta)
-     struct frame *f;
-     COLORREF *color;
-     double factor;
-     int delta;
+w32_alloc_lighter_color (struct frame *f, COLORREF *color,
+                        double factor, int delta)
 {
   COLORREF new;
   long bright;
@@ -2087,6 +1485,30 @@ w32_alloc_lighter_color (f, color, factor, delta)
   return 1;
 }
 
+/* On frame F, translate pixel colors to RGB values for the NCOLORS
+   colors in COLORS.  On W32, we no longer try to map colors to
+   a palette.  */
+void
+x_query_colors (struct frame *f, XColor *colors, int ncolors)
+{
+  int i;
+
+  for (i = 0; i < ncolors; i++)
+    {
+      DWORD pixel = colors[i].pixel;
+      /* Convert to a 16 bit value in range 0 - 0xffff. */
+      colors[i].red = GetRValue (pixel) * 257;
+      colors[i].green = GetGValue (pixel) * 257;
+      colors[i].blue = GetBValue (pixel) * 257;
+    }
+}
+
+void
+x_query_color (struct frame *f, XColor *color)
+{
+  x_query_colors (f, color, 1);
+}
+
 
 /* Set up the foreground color for drawing relief lines of glyph
    string S.  RELIEF is a pointer to a struct relief containing the GC
@@ -2096,12 +1518,8 @@ w32_alloc_lighter_color (f, color, factor, delta)
    be allocated, use DEFAULT_PIXEL, instead.  */
 
 static void
-w32_setup_relief_color (f, relief, factor, delta, default_pixel)
-     struct frame *f;
-     struct relief *relief;
-     double factor;
-     int delta;
-     COLORREF default_pixel;
+w32_setup_relief_color (struct frame *f, struct relief *relief, double factor,
+                       int delta, COLORREF default_pixel)
 {
   XGCValues xgcv;
   struct w32_output *di = f->output_data.w32;
@@ -2137,8 +1555,7 @@ w32_setup_relief_color (f, relief, factor, delta, default_pixel)
 /* Set up colors for the relief lines around glyph string S.  */
 
 static void
-x_setup_relief_colors (s)
-     struct glyph_string *s;
+x_setup_relief_colors (struct glyph_string *s)
 {
   struct w32_output *di = s->f->output_data.w32;
   COLORREF color;
@@ -2173,12 +1590,10 @@ x_setup_relief_colors (s)
    when drawing.  */
 
 static void
-w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
-                      raised_p, top_p, bot_p, left_p, right_p, clip_rect)
-     struct frame *f;
-     int left_x, top_y, right_x, bottom_y, width;
-     int top_p, bot_p, left_p, right_p, raised_p;
-     RECT *clip_rect;
+w32_draw_relief_rect (struct frame *f,
+                     int left_x, int top_y, int right_x, int bottom_y, int width,
+                     int raised_p, int top_p, int bot_p, int left_p, int right_p,
+                     RECT *clip_rect)
 {
   int i;
   XGCValues gc;
@@ -2238,11 +1653,9 @@ w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
    rectangle to use when drawing.  */
 
 static void
-w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
-                   left_p, right_p, clip_rect)
-     struct glyph_string *s;
-     int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
-     RECT *clip_rect;
+w32_draw_box_rect (struct glyph_string *s,
+                  int left_x, int top_y, int right_x, int bottom_y, int width,
+                   int left_p, int right_p, RECT *clip_rect)
 {
   w32_set_clip_rectangle (s->hdc, clip_rect);
 
@@ -2275,8 +1688,7 @@ w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
 /* Draw a box around glyph string S.  */
 
 static void
-x_draw_glyph_string_box (s)
-     struct glyph_string *s;
+x_draw_glyph_string_box (struct glyph_string *s)
 {
   int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
   int left_p, right_p;
@@ -2327,8 +1739,7 @@ x_draw_glyph_string_box (s)
 /* Draw foreground of image glyph string S.  */
 
 static void
-x_draw_image_foreground (s)
-     struct glyph_string *s;
+x_draw_image_foreground (struct glyph_string *s)
 {
   int x = s->x;
   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
@@ -2418,8 +1829,7 @@ x_draw_image_foreground (s)
 /* Draw a relief around the image glyph string S.  */
 
 static void
-x_draw_image_relief (s)
-     struct glyph_string *s;
+x_draw_image_relief (struct glyph_string *s)
 {
   int x0, y0, x1, y1, thick, raised_p;
   RECT r;
@@ -2471,9 +1881,7 @@ x_draw_image_relief (s)
 /* Draw the foreground of image glyph string S to PIXMAP.  */
 
 static void
-w32_draw_image_foreground_1 (s, pixmap)
-     struct glyph_string *s;
-     HBITMAP pixmap;
+w32_draw_image_foreground_1 (struct glyph_string *s, HBITMAP pixmap)
 {
   HDC hdc = CreateCompatibleDC (s->hdc);
   HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
@@ -2560,9 +1968,7 @@ w32_draw_image_foreground_1 (s, pixmap)
    give the rectangle to draw.  */
 
 static void
-x_draw_glyph_string_bg_rect (s, x, y, w, h)
-     struct glyph_string *s;
-     int x, y, w, h;
+x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
 {
 #if 0 /* TODO: stipple */
   if (s->stippled_p)
@@ -2593,8 +1999,7 @@ x_draw_glyph_string_bg_rect (s, x, y, w, h)
  */
 
 static void
-x_draw_image_glyph_string (s)
-     struct glyph_string *s;
+x_draw_image_glyph_string (struct glyph_string *s)
 {
   int x, y;
   int box_line_hwidth = eabs (s->face->box_line_width);
@@ -2707,8 +2112,7 @@ x_draw_image_glyph_string (s)
 /* Draw stretch glyph string S.  */
 
 static void
-x_draw_stretch_glyph_string (s)
-     struct glyph_string *s;
+x_draw_stretch_glyph_string (struct glyph_string *s)
 {
   xassert (s->first_glyph->type == STRETCH_GLYPH);
 
@@ -2790,8 +2194,7 @@ x_draw_stretch_glyph_string (s)
 /* Draw glyph string S.  */
 
 static void
-x_draw_glyph_string (s)
-     struct glyph_string *s;
+x_draw_glyph_string (struct glyph_string *s)
 {
   int relief_drawn_p = 0;
 
@@ -2802,13 +2205,17 @@ x_draw_glyph_string (s)
     {
       int width;
       struct glyph_string *next;
-      for (width = 0, next = s->next; next;
+      for (width = 0, next = s->next;
+          next && width < s->right_overhang;
            width += next->width, next = next->next)
         if (next->first_glyph->type != IMAGE_GLYPH)
           {
             x_set_glyph_string_gc (next);
             x_set_glyph_string_clipping (next);
-            x_draw_glyph_string_background (next, 1);
+           if (next->first_glyph->type == STRETCH_GLYPH)
+             x_draw_stretch_glyph_string (next);
+           else
+             x_draw_glyph_string_background (next, 1);
             next->num_clips = 0;
           }
     }
@@ -2830,8 +2237,10 @@ x_draw_glyph_string (s)
       x_set_glyph_string_clipping (s);
       relief_drawn_p = 1;
     }
-  else if ((s->prev && s->prev->hl != s->hl && s->left_overhang)
-          || (s->next && s->next->hl != s->hl && s->right_overhang))
+  else if (!s->clip_head /* draw_glyphs didn't specify a clip mask.  */
+           && !s->clip_tail
+           && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
+               || (s->next && s->next->hl != s->hl && s->right_overhang)))
     /* We must clip just this glyph.  left_overhang part has already
        drawn when s->prev was drawn, and right_overhang part will be
        drawn later when s->next is drawn. */
@@ -2858,7 +2267,8 @@ x_draw_glyph_string (s)
       break;
 
     case COMPOSITE_GLYPH:
-      if (s->for_overlaps || s->gidx > 0)
+      if (s->for_overlaps || (s->cmp_from > 0
+                             && ! s->first_glyph->u.cmp.automatic))
        s->background_filled_p = 1;
       else
        x_draw_glyph_string_background (s, 1);
@@ -2891,7 +2301,7 @@ x_draw_glyph_string (s)
               else
                 thickness = 1;
               if (x_underline_at_descent_line)
-                position = (s->height - thickness) - s->ybase;
+                position = (s->height - thickness) - (s->ybase - s->y);
               else
                 {
                 /* Get the underline position.  This is the recommended
@@ -2908,19 +2318,26 @@ x_draw_glyph_string (s)
                 else if (s->font)
                   position = (s->font->descent + 1) / 2;
                 }
-              s->underline_thickness = thickness;
-              s->underline_position =position;
+             position = max (position, underline_minimum_offset);
             }
+         /* Check the sanity of thickness and position.  We should
+            avoid drawing underline out of the current line area.  */
+         if (s->y + s->height <= s->ybase + position)
+           position = (s->height - 1) - (s->ybase - s->y);
+         if (s->y + s->height < s->ybase + position + thickness)
+           thickness = (s->y + s->height) - (s->ybase + position);
+         s->underline_thickness = thickness;
+         s->underline_position =position;
           y = s->ybase + position;
           if (s->face->underline_defaulted_p)
             {
               w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
-                             y, s->background_width, 1);
+                             y, s->width, 1);
             }
           else
             {
               w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
-                             y, s->background_width, 1);
+                             y, s->width, 1);
             }
         }
       /* Draw overline.  */
@@ -2931,19 +2348,18 @@ x_draw_glyph_string (s)
           if (s->face->overline_color_defaulted_p)
             {
               w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
-                             s->y + dy, s->background_width, h);
+                             s->y + dy, s->width, h);
             }
           else
             {
               w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
-                             s->y + dy, s->background_width, h);
+                             s->y + dy, s->width, h);
             }
         }
 
       /* Draw strike-through.  */
       if (s->face->strike_through_p
-          && (FONT_COMPAT (s->font)->bdf
-             || !FONT_COMPAT (s->font)->tm.tmStruckOut))
+          && !FONT_TEXTMETRIC (s->font).tmStruckOut)
         {
           unsigned long h = 1;
           unsigned long dy = (s->height - h) / 2;
@@ -3024,9 +2440,8 @@ x_draw_glyph_string (s)
 /* Shift display to make room for inserted glyphs.   */
 
 void
-w32_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
-     struct frame *f;
-     int x, y, width, height, shift_by;
+w32_shift_glyphs_for_insert (struct frame *f, int x, int y,
+                            int width, int height, int shift_by)
 {
   HDC hdc;
 
@@ -3042,9 +2457,7 @@ w32_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
    for X frames.  */
 
 static void
-x_delete_glyphs (f, n)
-     struct frame *f;
-     register int n;
+x_delete_glyphs (struct frame *f, register int n)
 {
   if (! FRAME_W32_P (f))
     return;
@@ -3114,8 +2527,7 @@ w32_ring_bell (struct frame *f)
    that is bounded by calls to x_update_begin and x_update_end.  */
 
 static void
-w32_set_terminal_window (n)
-     register int n;
+w32_set_terminal_window (struct frame *f, int n)
 {
   /* This function intentionally left blank.  */
 }
@@ -3129,9 +2541,7 @@ w32_set_terminal_window (n)
    lines or deleting -N lines at vertical position VPOS.  */
 
 static void
-x_ins_del_lines (f, vpos, n)
-     struct frame *f;
-     int vpos, n;
+x_ins_del_lines (struct frame *f, int vpos, int n)
 {
   if (! FRAME_W32_P (f))
     return;
@@ -3143,9 +2553,7 @@ x_ins_del_lines (f, vpos, n)
 /* Scroll part of the display as described by RUN.  */
 
 static void
-x_scroll_run (w, run)
-     struct window *w;
-     struct run *run;
+x_scroll_run (struct window *w, struct run *run)
 {
   struct frame *f = XFRAME (w->frame);
   int x, y, width, height, from_y, to_y, bottom_y;
@@ -3227,17 +2635,17 @@ x_scroll_run (w, run)
  ***********************************************************************/
 
 static void
-frame_highlight (f)
-     struct frame *f;
+frame_highlight (struct frame *f)
 {
   x_update_cursor (f, 1);
+  x_set_frame_alpha (f);
 }
 
 static void
-frame_unhighlight (f)
-     struct frame *f;
+frame_unhighlight (struct frame *f)
 {
   x_update_cursor (f, 1);
+  x_set_frame_alpha (f);
 }
 
 /* The focus has changed.  Update the frames as necessary to reflect
@@ -3247,9 +2655,7 @@ frame_unhighlight (f)
    Lisp code can tell when the switch took place by examining the events.  */
 
 static void
-x_new_focus_frame (dpyinfo, frame)
-     struct w32_display_info *dpyinfo;
-     struct frame *frame;
+x_new_focus_frame (struct w32_display_info *dpyinfo, struct frame *frame)
 {
   struct frame *old_focus = dpyinfo->w32_focus_frame;
 
@@ -3277,12 +2683,8 @@ x_new_focus_frame (dpyinfo, frame)
    a FOCUS_IN_EVENT into *BUFP.  */
 
 static void
-x_focus_changed (type, state, dpyinfo, frame, bufp)
-     int type;
-     int state;
-     struct w32_display_info *dpyinfo;
-     struct frame *frame;
-     struct input_event *bufp;
+x_focus_changed (int type, int state, struct w32_display_info *dpyinfo,
+                struct frame *frame, struct input_event *bufp)
 {
   if (type == WM_SETFOCUS)
     {
@@ -3327,10 +2729,8 @@ x_focus_changed (type, state, dpyinfo, frame, bufp)
    Returns FOCUS_IN_EVENT event in *BUFP. */
 
 static void
-w32_detect_focus_change (dpyinfo, event, bufp)
-     struct w32_display_info *dpyinfo;
-     W32Msg *event;
-     struct input_event *bufp;
+w32_detect_focus_change (struct w32_display_info *dpyinfo, W32Msg *event,
+                        struct input_event *bufp)
 {
   struct frame *frame;
 
@@ -3349,8 +2749,7 @@ w32_detect_focus_change (dpyinfo, event, bufp)
 /* Handle an event saying the mouse has moved out of an Emacs frame.  */
 
 void
-x_mouse_leave (dpyinfo)
-     struct w32_display_info *dpyinfo;
+x_mouse_leave (struct w32_display_info *dpyinfo)
 {
   x_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
 }
@@ -3364,8 +2763,7 @@ x_mouse_leave (dpyinfo)
    the appropriate X display info.  */
 
 static void
-w32_frame_rehighlight (frame)
-     struct frame *frame;
+w32_frame_rehighlight (struct frame *frame)
 {
   if (! FRAME_W32_P (frame))
     return;
@@ -3373,8 +2771,7 @@ w32_frame_rehighlight (frame)
 }
 
 static void
-x_frame_rehighlight (dpyinfo)
-     struct w32_display_info *dpyinfo;
+x_frame_rehighlight (struct w32_display_info *dpyinfo)
 {
   struct frame *old_highlight = dpyinfo->x_highlight_frame;
 
@@ -3407,8 +2804,7 @@ x_frame_rehighlight (dpyinfo)
 /* Convert a keysym to its name.  */
 
 char *
-x_get_keysym_name (keysym)
-    int keysym;
+x_get_keysym_name (int keysym)
 {
   /* Make static so we can always return it */
   static char value[100];
@@ -3420,6 +2816,16 @@ x_get_keysym_name (keysym)
   return value;
 }
 
+static int
+codepage_for_locale (LCID locale)
+{
+  char cp[20];
+
+  if (GetLocaleInfo (locale, LOCALE_IDEFAULTANSICODEPAGE, cp, 20) > 0)
+    return atoi (cp);
+  else
+    return CP_ACP;
+}
 
 \f
 /* Mouse clicks and mouse movement.  Rah.  */
@@ -3428,11 +2834,7 @@ x_get_keysym_name (keysym)
    the state in PUP. XBUTTON provides extra information for extended mouse
    button messages. Returns FALSE if unable to parse the message.  */
 BOOL
-parse_button (message, xbutton, pbutton, pup)
-     int message;
-     int xbutton;
-     int * pbutton;
-     int * pup;
+parse_button (int message, int xbutton, int * pbutton, int * pup)
 {
   int button = 0;
   int up = 0;
@@ -3500,10 +2902,7 @@ parse_button (message, xbutton, pbutton, pup)
    the mouse.  */
 
 static Lisp_Object
-construct_mouse_click (result, msg, f)
-     struct input_event *result;
-     W32Msg *msg;
-     struct frame *f;
+construct_mouse_click (struct input_event *result, W32Msg *msg, struct frame *f)
 {
   int button;
   int up;
@@ -3529,10 +2928,7 @@ construct_mouse_click (result, msg, f)
 }
 
 static Lisp_Object
-construct_mouse_wheel (result, msg, f)
-     struct input_event *result;
-     W32Msg *msg;
-     struct frame *f;
+construct_mouse_wheel (struct input_event *result, W32Msg *msg, struct frame *f)
 {
   POINT p;
   int delta;
@@ -3565,10 +2961,7 @@ construct_mouse_wheel (result, msg, f)
 }
 
 static Lisp_Object
-construct_drag_n_drop (result, msg, f)
-     struct input_event *result;
-     W32Msg *msg;
-     struct frame *f;
+construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f)
 {
   Lisp_Object files;
   Lisp_Object frame;
@@ -3629,9 +3022,7 @@ static MSG last_mouse_motion_event;
 static Lisp_Object last_mouse_motion_frame;
 
 static int
-note_mouse_movement (frame, msg)
-     FRAME_PTR frame;
-     MSG *msg;
+note_mouse_movement (FRAME_PTR frame, MSG *msg)
 {
   int mouse_x = LOWORD (msg->lParam);
   int mouse_y = HIWORD (msg->lParam);
@@ -3679,12 +3070,15 @@ note_mouse_movement (frame, msg)
                              Mouse Face
  ************************************************************************/
 
-static struct scroll_bar *x_window_to_scroll_bar ();
-static void x_scroll_bar_report_motion ();
-static void x_check_fullscreen P_ ((struct frame *));
+static struct scroll_bar *x_window_to_scroll_bar (Window);
+static void x_scroll_bar_report_motion (FRAME_PTR *, Lisp_Object *,
+                                       enum scroll_bar_part *,
+                                       Lisp_Object *, Lisp_Object *,
+                                       unsigned long *);
+static void x_check_fullscreen (struct frame *);
 
 static void
-redo_mouse_highlight ()
+redo_mouse_highlight (void)
 {
   if (!NILP (last_mouse_motion_frame)
       && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
@@ -3694,9 +3088,7 @@ redo_mouse_highlight ()
 }
 
 static void
-w32_define_cursor (window, cursor)
-     Window window;
-     Cursor cursor;
+w32_define_cursor (Window window, Cursor cursor)
 {
   PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
 }
@@ -3721,13 +3113,9 @@ w32_define_cursor (window, cursor)
    movement.  */
 
 static void
-w32_mouse_position (fp, insist, bar_window, part, x, y, time)
-     FRAME_PTR *fp;
-     int insist;
-     Lisp_Object *bar_window;
-     enum scroll_bar_part *part;
-     Lisp_Object *x, *y;
-     unsigned long *time;
+w32_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
+                   enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
+                   unsigned long *time)
 {
   FRAME_PTR f1;
 
@@ -3818,9 +3206,7 @@ w32_mouse_position (fp, insist, bar_window, part, x, y, time)
    or ButtonRelase.  */
 
 static void
-w32_handle_tool_bar_click (f, button_event)
-     struct frame *f;
-     struct input_event *button_event;
+w32_handle_tool_bar_click (struct frame *f, struct input_event *button_event)
 {
   int x = XFASTINT (button_event->x);
   int y = XFASTINT (button_event->y);
@@ -3845,8 +3231,7 @@ w32_handle_tool_bar_click (f, button_event)
    bits.  */
 
 static struct scroll_bar *
-x_window_to_scroll_bar (window_id)
-     Window window_id;
+x_window_to_scroll_bar (Window window_id)
 {
   Lisp_Object tail;
 
@@ -3882,9 +3267,8 @@ x_window_to_scroll_bar (window_id)
    displaying PORTION out of a whole WHOLE, and our position POSITION.  */
 
 static void
-w32_set_scroll_bar_thumb (bar, portion, position, whole)
-     struct scroll_bar *bar;
-     int portion, position, whole;
+w32_set_scroll_bar_thumb (struct scroll_bar *bar,
+                         int portion, int position, int whole)
 {
   Window w = SCROLL_BAR_W32_WINDOW (bar);
   /* We use the whole scroll-bar height in the calculations below, to
@@ -3910,7 +3294,7 @@ w32_set_scroll_bar_thumb (bar, portion, position, whole)
       BLOCK_INPUT;
       si.cbSize = sizeof (si);
       si.fMask = SIF_POS | SIF_PAGE;
-      GetScrollInfo(w, SB_CTL, &si);
+      GetScrollInfo (w, SB_CTL, &si);
       near_bottom_p = si.nPos + si.nPage >= range;
       UNBLOCK_INPUT;
       if (!near_bottom_p)
@@ -3959,9 +3343,7 @@ w32_set_scroll_bar_thumb (bar, portion, position, whole)
  ************************************************************************/
 
 static HWND
-my_create_scrollbar (f, bar)
-     struct frame * f;
-     struct scroll_bar * bar;
+my_create_scrollbar (struct frame * f, struct scroll_bar * bar)
 {
   return (HWND) SendMessage (FRAME_W32_WINDOW (f),
                             WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
@@ -4000,26 +3382,21 @@ my_set_window_pos (HWND hwnd, HWND hwndAfter,
 }
 
 static void
-my_set_focus (f, hwnd)
-     struct frame * f;
-     HWND hwnd;
+my_set_focus (struct frame * f, HWND hwnd)
 {
   SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
               (WPARAM) hwnd, 0);
 }
 
 static void
-my_set_foreground_window (hwnd)
-     HWND hwnd;
+my_set_foreground_window (HWND hwnd)
 {
   SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
 }
 
 
 static void
-my_destroy_window (f, hwnd)
-     struct frame * f;
-     HWND hwnd;
+my_destroy_window (struct frame * f, HWND hwnd)
 {
   SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
               (WPARAM) hwnd, 0);
@@ -4031,9 +3408,7 @@ my_destroy_window (f, hwnd)
    scroll bar. */
 
 static struct scroll_bar *
-x_scroll_bar_create (w, top, left, width, height)
-     struct window *w;
-     int top, left, width, height;
+x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   HWND hwnd;
@@ -4086,8 +3461,7 @@ x_scroll_bar_create (w, top, left, width, height)
    nil. */
 
 static void
-x_scroll_bar_remove (bar)
-     struct scroll_bar *bar;
+x_scroll_bar_remove (struct scroll_bar *bar)
 {
   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 
@@ -4107,9 +3481,8 @@ x_scroll_bar_remove (bar)
    characters, starting at POSITION.  If WINDOW has no scroll bar,
    create one.  */
 static void
-w32_set_vertical_scroll_bar (w, portion, whole, position)
-     struct window *w;
-     int portion, whole, position;
+w32_set_vertical_scroll_bar (struct window *w,
+                            int portion, int whole, int position)
 {
   struct frame *f = XFRAME (w->frame);
   struct scroll_bar *bar;
@@ -4252,8 +3625,7 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
    `*redeem_scroll_bar_hook' is applied to its window before the judgment.  */
 
 static void
-w32_condemn_scroll_bars (frame)
-     FRAME_PTR frame;
+w32_condemn_scroll_bars (FRAME_PTR frame)
 {
   /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS.  */
   while (! NILP (FRAME_SCROLL_BARS (frame)))
@@ -4274,8 +3646,7 @@ w32_condemn_scroll_bars (frame)
    Note that WINDOW isn't necessarily condemned at all.  */
 
 static void
-w32_redeem_scroll_bar (window)
-     struct window *window;
+w32_redeem_scroll_bar (struct window *window)
 {
   struct scroll_bar *bar;
   struct frame *f;
@@ -4320,8 +3691,7 @@ w32_redeem_scroll_bar (window)
    last call to `*condemn_scroll_bars_hook'.  */
 
 static void
-w32_judge_scroll_bars (f)
-     FRAME_PTR f;
+w32_judge_scroll_bars (FRAME_PTR f)
 {
   Lisp_Object bar, next;
 
@@ -4352,10 +3722,8 @@ w32_judge_scroll_bars (f)
    mark bits.  */
 
 static int
-w32_scroll_bar_handle_click (bar, msg, emacs_event)
-     struct scroll_bar *bar;
-     W32Msg *msg;
-     struct input_event *emacs_event;
+w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
+                            struct input_event *emacs_event)
 {
   if (! WINDOWP (bar->window))
     abort ();
@@ -4461,12 +3829,10 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
    on the scroll bar.  */
 
 static void
-x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
-     FRAME_PTR *fp;
-     Lisp_Object *bar_window;
-     enum scroll_bar_part *part;
-     Lisp_Object *x, *y;
-     unsigned long *time;
+x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
+                           enum scroll_bar_part *part,
+                           Lisp_Object *x, Lisp_Object *y,
+                           unsigned long *time)
 {
   struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
   Window w = SCROLL_BAR_W32_WINDOW (bar);
@@ -4522,8 +3888,7 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
    redraw them.  */
 
 void
-x_scroll_bar_clear (f)
-     FRAME_PTR f;
+x_scroll_bar_clear (FRAME_PTR f)
 {
   Lisp_Object bar;
 
@@ -4582,10 +3947,8 @@ static char dbcs_lead = 0;
 */
 
 int
-w32_read_socket (sd, expected, hold_quit)
-     register int sd;
-     int expected;
-     struct input_event *hold_quit;
+w32_read_socket (struct terminal *terminal, int expected,
+                struct input_event *hold_quit)
 {
   int count = 0;
   int check_visibility = 0;
@@ -4617,7 +3980,7 @@ w32_read_socket (sd, expected, hold_quit)
 
       switch (msg.msg.message)
        {
-       case WM_PAINT:
+       case WM_EMACS_PAINT:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
 
          if (f)
@@ -4672,6 +4035,11 @@ w32_read_socket (sd, expected, hold_quit)
          /* Generate a language change event.  */
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
 
+         /* lParam contains the input lang ID.  Use it to update our
+            record of the keyboard codepage.  */
+         keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
+                                                         & 0xffff));
+
          if (f)
            {
              inev.kind = LANGUAGE_CHANGE_EVENT;
@@ -4742,7 +4110,8 @@ w32_read_socket (sd, expected, hold_quit)
                     {
                       dbcs[0] = dbcs_lead;
                       dbcs_lead = 0;
-                      if (!MultiByteToWideChar (CP_ACP, 0, dbcs, 2, &code, 1))
+                      if (!MultiByteToWideChar (keyboard_codepage, 0,
+                                               dbcs, 2, &code, 1))
                         {
                           /* Garbage */
                           DebPrint (("Invalid DBCS sequence: %d %d\n",
@@ -4751,7 +4120,8 @@ w32_read_socket (sd, expected, hold_quit)
                           break;
                         }
                     }
-                  else if (IsDBCSLeadByteEx (CP_ACP, (BYTE) msg.msg.wParam))
+                  else if (IsDBCSLeadByteEx (keyboard_codepage,
+                                            (BYTE) msg.msg.wParam))
                     {
                       dbcs_lead = (char) msg.msg.wParam;
                       inev.kind = NO_EVENT;
@@ -4759,8 +4129,8 @@ w32_read_socket (sd, expected, hold_quit)
                     }
                   else
                     {
-                      if (!MultiByteToWideChar (CP_ACP, 0, &dbcs[1], 1,
-                                                &code, 1))
+                      if (!MultiByteToWideChar (keyboard_codepage, 0,
+                                               &dbcs[1], 1, &code, 1))
                         {
                           /* What to do with garbage? */
                           DebPrint (("Invalid character: %d\n", dbcs[1]));
@@ -4799,13 +4169,13 @@ w32_read_socket (sd, expected, hold_quit)
                temp_index = 0;
              temp_buffer[temp_index++] = msg.msg.wParam;
              inev.kind = MULTIMEDIA_KEY_EVENT;
-             inev.code = GET_APPCOMMAND_LPARAM(msg.msg.lParam);
+             inev.code = GET_APPCOMMAND_LPARAM (msg.msg.lParam);
              inev.modifiers = msg.dwModifiers;
              XSETFRAME (inev.frame_or_window, f);
              inev.timestamp = msg.msg.time;
            }
          break;
-          
+
        case WM_MOUSEMOVE:
          /* Ignore non-movement.  */
          {
@@ -4847,7 +4217,7 @@ w32_read_socket (sd, expected, hold_quit)
                     selected now and last mouse movement event was
                     not in it.  Minibuffer window will be selected
                     only when it is active.  */
-                 if (WINDOWP(window)
+                 if (WINDOWP (window)
                      && !EQ (window, last_window)
                      && !EQ (window, selected_window)
                      /* For click-to-focus window managers
@@ -5252,11 +4622,10 @@ w32_read_socket (sd, expected, hold_quit)
 
          if (f)
            {
-             dpyinfo->width = (short) LOWORD (msg.msg.lParam);
-             dpyinfo->height = (short) HIWORD (msg.msg.lParam);
              dpyinfo->n_cbits = msg.msg.wParam;
-             DebPrint (("display change: %d %d\n", dpyinfo->width,
-                        dpyinfo->height));
+             DebPrint (("display change: %d %d\n",
+                        (short) LOWORD (msg.msg.lParam),
+                        (short) HIWORD (msg.msg.lParam)));
            }
 
          check_visibility = 1;
@@ -5408,11 +4777,7 @@ w32_read_socket (sd, expected, hold_quit)
    mode lines must be clipped to the whole window.  */
 
 static void
-w32_clip_to_row (w, row, area, hdc)
-     struct window *w;
-     struct glyph_row *row;
-     int area;
-     HDC hdc;
+w32_clip_to_row (struct window *w, struct glyph_row *row, int area, HDC hdc)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   RECT clip_rect;
@@ -5433,9 +4798,7 @@ w32_clip_to_row (w, row, area, hdc)
 /* Draw a hollow box cursor on window W in glyph row ROW.  */
 
 static void
-x_draw_hollow_cursor (w, row)
-     struct window *w;
-     struct glyph_row *row;
+x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   HDC hdc;
@@ -5475,16 +4838,11 @@ x_draw_hollow_cursor (w, row)
    --gerd.  */
 
 static void
-x_draw_bar_cursor (w, row, width, kind)
-     struct window *w;
-     struct glyph_row *row;
-     int width;
-     enum text_cursor_kinds kind;
+x_draw_bar_cursor (struct window *w, struct glyph_row *row,
+                  int width, enum text_cursor_kinds kind)
 {
   struct frame *f = XFRAME (w->frame);
   struct glyph *cursor_glyph;
-  int x;
-  HDC hdc;
 
   /* If cursor is out of bounds, don't draw garbage.  This can happen
      in mini-buffer windows when switching between echo area glyphs
@@ -5506,6 +4864,8 @@ x_draw_bar_cursor (w, row, width, kind)
     {
       COLORREF cursor_color = f->output_data.w32->cursor_pixel;
       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
+      int x;
+      HDC hdc;
 
       /* If the glyph's background equals the color we normally draw
         the bar cursor in, the bar cursor in its normal color is
@@ -5517,28 +4877,36 @@ x_draw_bar_cursor (w, row, width, kind)
 
       x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 
-      if (width < 0)
-        width = FRAME_CURSOR_WIDTH (f);
-      width = min (cursor_glyph->pixel_width, width);
-
-      w->phys_cursor_width = width;
-
-
       hdc = get_frame_dc (f);
       w32_clip_to_row (w, row, TEXT_AREA, hdc);
 
       if (kind == BAR_CURSOR)
        {
+         if (width < 0)
+           width = FRAME_CURSOR_WIDTH (f);
+         width = min (cursor_glyph->pixel_width, width);
+
+         w->phys_cursor_width = width;
+
          w32_fill_area (f, hdc, cursor_color, x,
                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
                         width, row->height);
        }
       else
        {
+         int dummy_x, dummy_y, dummy_h;
+
+         if (width < 0)
+           width = row->height;
+
+         width = min (row->height, width);
+
+         get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
+                                   &dummy_y, &dummy_h);
          w32_fill_area (f, hdc, cursor_color, x,
                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
                                                  row->height - width),
-                        cursor_glyph->pixel_width, width);
+                        w->phys_cursor_width, width);
        }
 
       w32_set_clip_rectangle (hdc, NULL);
@@ -5550,9 +4918,7 @@ x_draw_bar_cursor (w, row, width, kind)
 /* RIF: Define cursor CURSOR on frame F.  */
 
 static void
-w32_define_frame_cursor (f, cursor)
-     struct frame *f;
-     Cursor cursor;
+w32_define_frame_cursor (struct frame *f, Cursor cursor)
 {
   w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
 }
@@ -5561,9 +4927,7 @@ w32_define_frame_cursor (f, cursor)
 /* RIF: Clear area on frame F.  */
 
 static void
-w32_clear_frame_area (f, x, y, width, height)
-     struct frame *f;
-     int x, y, width, height;
+w32_clear_frame_area (struct frame *f, int x, int y, int width, int height)
 {
   HDC hdc;
 
@@ -5575,12 +4939,9 @@ w32_clear_frame_area (f, x, y, width, height)
 /* RIF: Draw or clear cursor on window W.  */
 
 static void
-w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, active_p)
-     struct window *w;
-     struct glyph_row *glyph_row;
-     int x, y;
-     int cursor_type, cursor_width;
-     int on_p, active_p;
+w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
+                       int x, int y, int cursor_type, int cursor_width,
+                       int on_p, int active_p)
 {
   if (on_p)
     {
@@ -5618,6 +4979,8 @@ w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
            = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
               + glyph_row->ascent - w->phys_cursor_ascent);
 
+         PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0);
+
          /* If the size of the active cursor changed, destroy the old
             system caret.  */
          if (w32_system_caret_hwnd
@@ -5631,10 +4994,12 @@ w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
        }
 
       if (glyph_row->exact_window_width_line_p
-         && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
+         && (glyph_row->reversed_p
+             ? (w->phys_cursor.hpos < 0)
+             : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
        {
          glyph_row->cursor_in_fringe_p = 1;
-         draw_fringe_bitmap (w, glyph_row, 0);
+         draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
          return;
        }
 
@@ -5671,9 +5036,7 @@ w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
 /* Icons.  */
 
 int
-x_bitmap_icon (f, icon)
-     struct frame *f;
-     Lisp_Object icon;
+x_bitmap_icon (struct frame *f, Lisp_Object icon)
 {
   HANDLE main_icon;
   HANDLE small_icon = NULL;
@@ -5761,114 +5124,8 @@ x_io_error_quitter (display)
 \f
 /* Changing the font of the frame.  */
 
-#if OLD_FONT
-
-/* Give frame F the font named FONTNAME as its default font, and
-   return the full name of that font.  FONTNAME may be a wildcard
-   pattern; in that case, we choose some font that fits the pattern.
-   The return value shows which font we chose.  */
-
 Lisp_Object
-x_new_font (f, fontname)
-     struct frame *f;
-     register char *fontname;
-{
-  struct font_info *fontp
-    = FS_LOAD_FONT (f, fontname);
-
-  if (!fontp)
-    return Qnil;
-
-  if (FRAME_FONT (f) == (XFontStruct *) (fontp->font))
-    /* This font is already set in frame F.  There's nothing more to
-       do.  */
-    return build_string (fontp->full_name);
-
-  FRAME_FONT (f) = (XFontStruct *) (fontp->font);
-  FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
-  FRAME_FONTSET (f) = -1;
-
-  FRAME_COLUMN_WIDTH (f) = fontp->average_width;
-  FRAME_SPACE_WIDTH (f) = fontp->space_width;
-  FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f));
-
-  compute_fringe_widths (f, 1);
-
-  /* Compute the scroll bar width in character columns.  */
-  if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
-    {
-      int wid = FRAME_COLUMN_WIDTH (f);
-      FRAME_CONFIG_SCROLL_BAR_COLS (f)
-       = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid;
-    }
-  else
-    {
-      int wid = FRAME_COLUMN_WIDTH (f);
-      FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
-    }
-
-  /* Now make the frame display the given font.  */
-  if (FRAME_W32_WINDOW (f) != 0)
-    {
-      if (NILP (tip_frame) || XFRAME (tip_frame) != f)
-        x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
-    }
-
-  return build_string (fontp->full_name);
-}
-\f
-/* Give frame F the fontset named FONTSETNAME as its default fontset,
-   and return the full name of that fontset.  FONTSETNAME may be a
-   wildcard pattern; in that case, we choose some fontset that fits
-   the pattern.  FONTSETNAME may be a font name for ASCII characters;
-   in that case, we create a fontset from that font name.
-
-   The return value shows which fontset we chose.
-   If FONTSETNAME specifies the default fontset, return Qt.
-   If an ASCII font in the specified fontset can't be loaded, return
-   Qnil.  */
-
-Lisp_Object
-x_new_fontset (f, fontsetname)
-     struct frame *f;
-     Lisp_Object fontsetname;
-{
-  int fontset = fs_query_fontset (fontsetname, 0);
-  Lisp_Object result;
-
-  if (fontset > 0 && FRAME_FONTSET(f) == fontset)
-    /* This fontset is already set in frame F.  There's nothing more
-       to do.  */
-    return fontset_name (fontset);
-  else if (fontset == 0)
-    /* The default fontset can't be the default font.   */
-    return Qt;
-
-  if (fontset > 0)
-    result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
-  else
-    result = x_new_font (f, SDATA (fontsetname));
-
-  if (!STRINGP (result))
-    /* Can't load ASCII font.  */
-    return Qnil;
-
-  if (fontset < 0)
-    fontset = new_fontset_from_font_name (result);
-
-  /* Since x_new_font doesn't update any fontset information, do it now.  */
-  FRAME_FONTSET(f) = fontset;
-
-  return fontset_name (fontset);
-}
-#endif /* OLD_FONT */
-
-
-Lisp_Object
-x_new_font (f, font_object, fontset)
-     struct frame *f;
-     Lisp_Object font_object;
-     int fontset;
+x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 {
   struct font *font = XFONT_OBJECT (font_object);
 
@@ -5878,9 +5135,7 @@ x_new_font (f, font_object, fontset)
   if (FRAME_FONT (f) == font)
     /* This font is already set in frame F.  There's nothing more to
        do.  */
-    return fontset_name (fontset);
-
-  BLOCK_INPUT;
+    return font_object;
 
   FRAME_FONT (f) = font;
   FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
@@ -5913,15 +5168,9 @@ x_new_font (f, font_object, fontset)
        x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
     }
 
-#ifdef HAVE_X_I18N
-  if (FRAME_XIC (f)
-      && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
-    xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
-#endif
+  /* X version sets font of input methods here also.  */
 
-  UNBLOCK_INPUT;
-
-  return fontset_name (fontset);
+  return font_object;
 }
 
 \f
@@ -5944,8 +5193,7 @@ xim_close_dpy (dpyinfo)
    from its current recorded position values and gravity.  */
 
 void
-x_calc_absolute_position (f)
-     struct frame *f;
+x_calc_absolute_position (struct frame *f)
 {
   int flags = f->size_hint_flags;
 
@@ -5982,13 +5230,13 @@ x_calc_absolute_position (f)
   /* Treat negative positions as relative to the rightmost bottommost
      position that fits on the screen.  */
   if (flags & XNegative)
-    f->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
+    f->left_pos = (x_display_pixel_width (FRAME_W32_DISPLAY_INFO (f))
                   - FRAME_PIXEL_WIDTH (f)
                   + f->left_pos
                   - (left_right_borders_width - 1));
 
   if (flags & YNegative)
-    f->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
+    f->top_pos = (x_display_pixel_height (FRAME_W32_DISPLAY_INFO (f))
                  - FRAME_PIXEL_HEIGHT (f)
                  + f->top_pos
                  - (top_bottom_borders_height - 1));
@@ -6005,10 +5253,8 @@ x_calc_absolute_position (f)
    which means, do adjust for borders but don't change the gravity.  */
 
 void
-x_set_offset (f, xoff, yoff, change_gravity)
-     struct frame *f;
-     register int xoff, yoff;
-     int change_gravity;
+x_set_offset (struct frame *f, register int xoff, register int yoff,
+             int change_gravity)
 {
   int modified_top, modified_left;
 
@@ -6043,8 +5289,7 @@ x_set_offset (f, xoff, yoff, change_gravity)
 /* Check if we need to resize the frame due to a fullscreen request.
    If so needed, resize the frame. */
 static void
-x_check_fullscreen (f)
-     struct frame *f;
+x_check_fullscreen (struct frame *f)
 {
   if (f->want_fullscreen & FULLSCREEN_BOTH)
     {
@@ -6074,10 +5319,7 @@ x_check_fullscreen (f)
    Otherwise we leave the window gravity unchanged.  */
 
 void
-x_set_window_size (f, change_gravity, cols, rows)
-     struct frame *f;
-     int change_gravity;
-     int cols, rows;
+x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
 {
   int pixelwidth, pixelheight;
 
@@ -6102,8 +5344,8 @@ x_set_window_size (f, change_gravity, cols, rows)
     rect.right = pixelwidth;
     rect.bottom = pixelheight;
 
-    AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
-                    FRAME_EXTERNAL_MENU_BAR (f));
+    AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
+                     FRAME_EXTERNAL_MENU_BAR (f));
 
     my_set_window_pos (FRAME_W32_WINDOW (f),
                       NULL,
@@ -6119,7 +5361,7 @@ x_set_window_size (f, change_gravity, cols, rows)
      resize will happen asynchronously. But on Windows, the menu bar
      automatically wraps when the frame is too narrow to contain it,
      and that causes any calculations made here to come out wrong. The
-     end is some nasty buggy behaviour, including the potential loss
+     end is some nasty buggy behavior, including the potential loss
      of the minibuffer.
 
      Disabling this code is either not sufficient to fix the problems
@@ -6169,9 +5411,7 @@ x_set_window_size (f, change_gravity, cols, rows)
 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;
+x_set_mouse_position (struct frame *f, int x, int y)
 {
   int pix_x, pix_y;
 
@@ -6188,9 +5428,7 @@ x_set_mouse_position (f, x, y)
 }
 
 void
-x_set_mouse_pixel_position (f, pix_x, pix_y)
-     struct frame *f;
-     int pix_x, pix_y;
+x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
 {
   RECT rect;
   POINT pt;
@@ -6211,8 +5449,7 @@ x_set_mouse_pixel_position (f, pix_x, pix_y)
 /* focus shifting, raising and lowering.  */
 
 void
-x_focus_on_frame (f)
-     struct frame *f;
+x_focus_on_frame (struct frame *f)
 {
   struct w32_display_info *dpyinfo = &one_w32_display_info;
 
@@ -6229,22 +5466,20 @@ x_focus_on_frame (f)
 }
 
 void
-x_unfocus_frame (f)
-     struct frame *f;
+x_unfocus_frame (struct frame *f)
 {
 }
 
 /* Raise frame F.  */
 void
-x_raise_frame (f)
-     struct frame *f;
+x_raise_frame (struct frame *f)
 {
   BLOCK_INPUT;
 
   /* Strictly speaking, raise-frame should only change the frame's Z
-     order, leaving input focus unchanged.  This is reasonable behaviour
+     order, leaving input focus unchanged.  This is reasonable behavior
      on X where the usual policy is point-to-focus.  However, this
-     behaviour would be very odd on Windows where the usual policy is
+     behavior would be very odd on Windows where the usual policy is
      click-to-focus.
 
      On X, if the mouse happens to be over the raised frame, it gets
@@ -6296,8 +5531,7 @@ x_raise_frame (f)
 
 /* Lower frame F.  */
 void
-x_lower_frame (f)
-     struct frame *f;
+x_lower_frame (struct frame *f)
 {
   BLOCK_INPUT;
   my_set_window_pos (FRAME_W32_WINDOW (f),
@@ -6308,9 +5542,7 @@ x_lower_frame (f)
 }
 
 static void
-w32_frame_raise_lower (f, raise_flag)
-     FRAME_PTR f;
-     int raise_flag;
+w32_frame_raise_lower (FRAME_PTR f, int raise_flag)
 {
   if (! FRAME_W32_P (f))
     return;
@@ -6331,8 +5563,7 @@ w32_frame_raise_lower (f, raise_flag)
    finishes with it.  */
 
 void
-x_make_frame_visible (f)
-     struct frame *f;
+x_make_frame_visible (struct frame *f)
 {
   Lisp_Object type;
 
@@ -6356,8 +5587,8 @@ x_make_frame_visible (f)
 
          /* Adjust vertical window position in order to avoid being
             covered by a task bar placed at the bottom of the desktop. */
-         SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea_rect, 0);
-         GetWindowRect(FRAME_W32_WINDOW(f), &window_rect);
+         SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0);
+         GetWindowRect (FRAME_W32_WINDOW(f), &window_rect);
          if (window_rect.bottom > workarea_rect.bottom
              && window_rect.top > workarea_rect.top)
            f->top_pos = max (window_rect.top
@@ -6369,8 +5600,15 @@ x_make_frame_visible (f)
 
       f->output_data.w32->asked_for_visible = 1;
 
-/*      my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);  */
-      my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
+      /* The first of these seems to give more expected behavior, but
+         was added as a commented out line in Sept 1997, with the
+         second version remaining uncommented. There may have been
+         some problem with it that led to it not being enabled,
+         so the old version remains commented out below in case we
+         decide we need to go back to it [23.0.60 2008-06-09].  */
+      my_show_window (f, FRAME_W32_WINDOW (f),
+                      f->async_iconified ? SW_RESTORE : SW_SHOW);
+      /* my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);  */
     }
 
   /* Synchronize to ensure Emacs knows the frame is visible
@@ -6417,8 +5655,8 @@ x_make_frame_visible (f)
 
 /* Make the frame visible (mapped and not iconified).  */
 
-x_make_frame_invisible (f)
-     struct frame *f;
+void
+x_make_frame_invisible (struct frame *f)
 {
   /* Don't keep the highlight on an invisible frame.  */
   if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
@@ -6444,8 +5682,7 @@ x_make_frame_invisible (f)
 /* Change window state from mapped to iconified. */
 
 void
-x_iconify_frame (f)
-     struct frame *f;
+x_iconify_frame (struct frame *f)
 {
   Lisp_Object type;
 
@@ -6531,8 +5768,7 @@ x_free_frame_resources (f)
 
 /* Destroy the window of frame F.  */
 void
-x_destroy_window (f)
-     struct frame *f;
+x_destroy_window (struct frame *f)
 {
   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
 
@@ -6549,10 +5785,7 @@ x_destroy_window (f)
    If USER_POSITION is nonzero, we set the USPosition
    flag (this is useful when FLAGS is 0).  */
 void
-x_wm_set_size_hint (f, flags, user_position)
-     struct frame *f;
-     long flags;
-     int user_position;
+x_wm_set_size_hint (struct frame *f, long flags, int user_position)
 {
   Window window = FRAME_W32_WINDOW (f);
 
@@ -6568,9 +5801,7 @@ x_wm_set_size_hint (f, flags, user_position)
 
 /* Window manager things */
 void
-x_wm_set_icon_position (f, icon_x, icon_y)
-     struct frame *f;
-     int icon_x, icon_y;
+x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
 {
 #if 0
   Window window = FRAME_W32_WINDOW (f);
@@ -6584,118 +5815,6 @@ x_wm_set_icon_position (f, icon_x, icon_y)
 }
 
 \f
-/***********************************************************************
-                               Fonts
- ***********************************************************************/
-
-#if OLD_FONT
-
-/* The following functions are listed here to help diff stay in step
-   with xterm.c.  See w32fns.c for definitions.
-
-x_get_font_info (f, font_idx)
-x_list_fonts (f, pattern, size, maxnames)
-
- */
-
-#if GLYPH_DEBUG
-
-/* Check that FONT is valid on frame F.  It is if it can be found in F's
-   font table.  */
-
-static void
-x_check_font (f, font)
-     struct frame *f;
-     XFontStruct *font;
-{
-  int i;
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-
-  xassert (font != NULL);
-
-  for (i = 0; i < dpyinfo->n_fonts; i++)
-    if (dpyinfo->font_table[i].name
-       && font == dpyinfo->font_table[i].font)
-      break;
-
-  xassert (i < dpyinfo->n_fonts);
-}
-
-#endif /* GLYPH_DEBUG != 0 */
-
-/* Set *W to the minimum width, *H to the minimum font height of FONT.
-   Note: There are (broken) X fonts out there with invalid XFontStruct
-   min_bounds contents.  For example, handa@etl.go.jp reports that
-   "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
-   have font->min_bounds.width == 0.  */
-
-static INLINE void
-x_font_min_bounds (font, w, h)
-     XFontStruct *font;
-     int *w, *h;
-{
-  /*
-   * TODO: Windows does not appear to offer min bound, only
-   * average and maximum width, and maximum height.
-   */
-  *h = FONT_HEIGHT (font);
-  *w = FONT_AVG_WIDTH (font);
-}
-
-
-/* Compute the smallest character width and smallest font height over
-   all fonts available on frame F.  Set the members smallest_char_width
-   and smallest_font_height in F's x_display_info structure to
-   the values computed.  Value is non-zero if smallest_font_height or
-   smallest_char_width become smaller than they were before.  */
-
-int
-x_compute_min_glyph_bounds (f)
-     struct frame *f;
-{
-  int i;
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-  XFontStruct *font;
-  int old_width = dpyinfo->smallest_char_width;
-  int old_height = dpyinfo->smallest_font_height;
-
-  dpyinfo->smallest_font_height = 100000;
-  dpyinfo->smallest_char_width = 100000;
-
-  for (i = 0; i < dpyinfo->n_fonts; ++i)
-    if (dpyinfo->font_table[i].name)
-      {
-       struct font_info *fontp = dpyinfo->font_table + i;
-       int w, h;
-
-       font = (XFontStruct *) fontp->font;
-       xassert (font != (XFontStruct *) ~0);
-       x_font_min_bounds (font, &w, &h);
-
-       dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
-       dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
-      }
-
-  xassert (dpyinfo->smallest_char_width > 0
-          && dpyinfo->smallest_font_height > 0);
-
-  return (dpyinfo->n_fonts == 1
-         || dpyinfo->smallest_char_width < old_width
-         || dpyinfo->smallest_font_height < old_height);
-}
-
-/* The following functions are listed here to help diff stay in step
-   with xterm.c.  See w32fns.c for definitions.
-
-x_load_font (f, fontname, size)
-x_query_font (f, fontname)
-x_find_ccl_program (fontp)
-
-*/
-
-#endif /* OLD_FONT */
-
-\f
 /***********************************************************************
                            Initialization
  ***********************************************************************/
@@ -6703,12 +5822,11 @@ x_find_ccl_program (fontp)
 static int w32_initialized = 0;
 
 void
-w32_initialize_display_info (display_name)
-     Lisp_Object display_name;
+w32_initialize_display_info (Lisp_Object display_name)
 {
   struct w32_display_info *dpyinfo = &one_w32_display_info;
 
-  bzero (dpyinfo, sizeof (*dpyinfo));
+  memset (dpyinfo, 0, sizeof (*dpyinfo));
 
   /* Put it on w32_display_name_list.  */
   w32_display_name_list = Fcons (Fcons (display_name, Qnil),
@@ -6726,8 +5844,6 @@ w32_initialize_display_info (display_name)
      with values obtained from system metrics.  */
   dpyinfo->resx = 1;
   dpyinfo->resy = 1;
-  dpyinfo->height_in = 1;
-  dpyinfo->width_in = 1;
   dpyinfo->n_planes = 1;
   dpyinfo->n_cbits = 4;
   dpyinfo->n_fonts = 0;
@@ -6759,8 +5875,7 @@ w32_initialize_display_info (display_name)
    but any whitespace following value is not removed.  */
 
 static char *
-w32_make_rdb (xrm_option)
-     char *xrm_option;
+w32_make_rdb (char *xrm_option)
 {
   char *buffer = xmalloc (strlen (xrm_option) + 2);
   char *current = buffer;
@@ -6828,10 +5943,6 @@ static struct redisplay_interface w32_redisplay_interface =
   w32_draw_fringe_bitmap,
   w32_define_fringe_bitmap,
   w32_destroy_fringe_bitmap,
-#if OLD_FONT
-  w32_per_char_metric,
-  w32_encode_char,
-#endif
   w32_compute_glyph_string_overhangs,
   x_draw_glyph_string,
   w32_define_frame_cursor,
@@ -6887,7 +5998,6 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
   terminal->memory_below_frame = 0;   /* We don't remember what scrolls
                                         off the bottom. */
 
-#ifdef MULTI_KBOARD
   /* We don't yet support separate terminals on W32, so don't try to share
      keyboards between virtual terminals that are on the same physical
      terminal like X does.  */
@@ -6902,7 +6012,6 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
   if (current_kboard == initial_kboard)
     current_kboard = terminal->kboard;
   terminal->kboard->reference_count++;
-#endif
 
   return terminal;
 }
@@ -6913,30 +6022,19 @@ x_delete_terminal (struct terminal *terminal)
   struct w32_display_info *dpyinfo = terminal->display_info.w32;
   int i;
 
-  /* Protect against recursive calls.  Fdelete_frame in
+  /* Protect against recursive calls.  delete_frame in
      delete_terminal calls us back when it deletes our last frame.  */
   if (!terminal->name)
     return;
 
   BLOCK_INPUT;
-#if OLD_FONT
-  /* Free the fonts in the font table.  */
-  for (i = 0; i < dpyinfo->n_fonts; i++)
-    if (dpyinfo->font_table[i].name)
-      {
-        DeleteObject (((XFontStruct*)(dpyinfo->font_table[i].font))->hfont);
-      }
-#endif
 
   x_delete_display (dpyinfo);
   UNBLOCK_INPUT;
 }
 
 struct w32_display_info *
-w32_term_init (display_name, xrm_option, resource_name)
-     Lisp_Object display_name;
-     char *xrm_option;
-     char *resource_name;
+w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 {
   struct w32_display_info *dpyinfo;
   struct terminal *terminal;
@@ -6966,20 +6064,15 @@ w32_term_init (display_name, xrm_option, resource_name)
   dpyinfo->next = x_display_list;
   x_display_list = dpyinfo;
 
-  hdc = GetDC (GetDesktopWindow ());
+  hdc = GetDC (NULL);
 
-  dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
-  dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
   dpyinfo->root_window = GetDesktopWindow ();
   dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
   dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
   dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
   dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
   dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
-  dpyinfo->terminal->image_cache = make_image_cache ();
-  dpyinfo->height_in = dpyinfo->height / dpyinfo->resx;
-  dpyinfo->width_in = dpyinfo->width / dpyinfo->resy;
-  ReleaseDC (GetDesktopWindow (), hdc);
+  ReleaseDC (NULL, hdc);
 
   /* initialise palette with white and black */
   {
@@ -7016,8 +6109,7 @@ w32_term_init (display_name, xrm_option, resource_name)
 \f
 /* Get rid of display DPYINFO, assuming all frames are already gone.  */
 void
-x_delete_display (dpyinfo)
-     struct w32_display_info *dpyinfo;
+x_delete_display (struct w32_display_info *dpyinfo)
 {
   /* Discard this display from w32_display_name_list and w32_display_list.
      We can't use Fdelq because that can quit.  */
@@ -7053,11 +6145,8 @@ x_delete_display (dpyinfo)
     }
     dpyinfo->color_list = NULL;
     if (dpyinfo->palette)
-      DeleteObject(dpyinfo->palette);
+      DeleteObject (dpyinfo->palette);
   }
-#if OLD_FONT
-  xfree (dpyinfo->font_table);
-#endif
   xfree (dpyinfo->w32_id_name);
 
   w32_reset_fringes ();
@@ -7068,8 +6157,11 @@ x_delete_display (dpyinfo)
 DWORD WINAPI w32_msg_worker (void * arg);
 
 static void
-w32_initialize ()
+w32_initialize (void)
 {
+  HANDLE shell;
+  HRESULT (WINAPI * set_user_model) (wchar_t * id);
+
   baud_rate = 19200;
 
   w32_system_caret_hwnd = NULL;
@@ -7077,6 +6169,25 @@ w32_initialize ()
   w32_system_caret_x = 0;
   w32_system_caret_y = 0;
 
+  /* On Windows 7 and later, we need to set the user model ID
+     to associate emacsclient launched files with Emacs frames
+     in the UI.  */
+  shell = GetModuleHandle ("shell32.dll");
+  if (shell)
+    {
+      set_user_model
+       = (void *) GetProcAddress (shell,
+                                  "SetCurrentProcessExplicitAppUserModelID");
+
+      /* If the function is defined, then we are running on Windows 7
+        or newer, and the UI uses this to group related windows
+        together.  Since emacs, runemacs, emacsclient are related, we
+        want them grouped even though the executables are different,
+        so we need to set a consistent ID between them.  */
+      if (set_user_model)
+       set_user_model (L"GNU.Emacs");
+    }
+
   /* Initialize w32_use_visible_system_caret based on whether a screen
      reader is in use.  */
   if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
@@ -7090,8 +6201,13 @@ w32_initialize ()
      8 bit character input, standard quit char.  */
   Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
 
-  /* Create the window thread - it will terminate itself or when the app terminates */
+  {
+    DWORD input_locale_id = (DWORD) GetKeyboardLayout (0);
+    keyboard_codepage = codepage_for_locale ((LCID) (input_locale_id & 0xffff));
+  }
 
+  /* Create the window thread - it will terminate itself when the app
+     terminates */
   init_crit ();
 
   dwMainThreadId = GetCurrentThreadId ();
@@ -7099,7 +6215,6 @@ w32_initialize ()
                   GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
 
   /* Wait for thread to start */
-
   {
     MSG msg;
 
@@ -7119,25 +6234,20 @@ w32_initialize ()
      program.  Unfortunately, we have good reasons for doing that, so
      instead we need to send messages to windowsThread to make some API
      calls for us (ones that affect, or depend on, the active/focus
-     window state.  */
+     window state.)  */
 #ifdef ATTACH_THREADS
   AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
 #endif
 
   /* Dynamically link to optional system components.  */
   {
-    UINT smoothing_type;
-    BOOL smoothing_enabled;
-
-    HANDLE gdi_lib = LoadLibrary ("gdi32.dll");
+    HMODULE user_lib = GetModuleHandle ("user32.dll");
 
 #define LOAD_PROC(lib, fn) pfn##fn = (void *) GetProcAddress (lib, #fn)
 
-    LOAD_PROC (gdi_lib, GetFontUnicodeRanges);
-    
-#undef LOAD_PROC
+    LOAD_PROC (user_lib, SetLayeredWindowAttributes);
 
-    FreeLibrary (gdi_lib);
+#undef LOAD_PROC
 
     /* Ensure scrollbar handle is at least 5 pixels.  */
     vertical_scroll_bar_min_handle = 5;
@@ -7146,33 +6256,11 @@ w32_initialize ()
        effectively form the border of the main scroll bar range.  */
     vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
       = GetSystemMetrics (SM_CYVSCROLL);
-
-    /* Constants that are not always defined by the system headers
-       since they only exist on certain versions of Windows.  */
-#ifndef SPI_GETFONTSMOOTHING
-#define SPI_GETFONTSMOOTHING 0x4A
-#endif
-#ifndef SPI_GETFONTSMOOTHINGTYPE
-#define SPI_GETFONTSMOOTHINGTYPE 0x0200A
-#endif
-#ifndef FE_FONTSMOOTHINGCLEARTYPE
-#define FE_FONTSMOOTHINGCLEARTYPE 0x2
-#endif
-
-    /* Determine if Cleartype is in use.  Used to enable a hack in
-       the char metric calculations which adds extra pixels to
-       compensate for the "sub-pixels" that are not counted by the
-       system APIs. */
-    cleartype_active =
-      SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &smoothing_enabled, 0)
-      && smoothing_enabled
-      && SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE, 0, &smoothing_type, 0)
-      && smoothing_type == FE_FONTSMOOTHINGCLEARTYPE;
   }
 }
 
 void
-syms_of_w32term ()
+syms_of_w32term (void)
 {
   staticpro (&w32_display_name_list);
   w32_display_name_list = Qnil;
@@ -7214,15 +6302,6 @@ When nil, the right-alt and left-ctrl key combination is
 interpreted normally.  */);
   Vw32_recognize_altgr = Qt;
 
-  DEFVAR_BOOL ("w32-enable-unicode-output",
-               &w32_enable_unicode_output,
-               doc: /* Enable the use of Unicode for text output if non-nil.
-Unicode output may prevent some third party applications for displaying
-Far-East Languages on Windows 95/98 from working properly.
-NT uses Unicode internally anyway, so this flag will probably have no
-effect on NT machines.  */);
-  w32_enable_unicode_output = 1;
-
   DEFVAR_BOOL ("w32-use-visible-system-caret",
               &w32_use_visible_system_caret,
               doc: /* Flag to make the system caret visible.
@@ -7245,9 +6324,7 @@ the cursor have no effect.  */);
      doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
 A value of nil means ignore them.  If you encounter fonts with bogus
 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
-to 4.1, set this to nil.
-
-NOTE: Not supported on MS-Windows yet.  */);
+to 4.1, set this to nil.  */);
   x_use_underline_position_properties = 0;
 
   DEFVAR_BOOL ("x-underline-at-descent-line",