Make "xfree (NULL)" a no-op; remove useless if-before-xfree.
[bpt/emacs.git] / src / w32fns.c
index 8af99a2..e83acf0 100644 (file)
@@ -1,13 +1,14 @@
 /* Graphical user interface functions for the Microsoft W32 API.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-                 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+                 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,9 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Added by Kevin Gallo */
 
@@ -27,24 +26,26 @@ Boston, MA 02110-1301, USA.  */
 #include <stdio.h>
 #include <limits.h>
 #include <errno.h>
+#include <math.h>
 
 #include "lisp.h"
-#include "charset.h"
-#include "dispextern.h"
 #include "w32term.h"
-#include "keyboard.h"
 #include "frame.h"
 #include "window.h"
 #include "buffer.h"
-#include "fontset.h"
 #include "intervals.h"
+#include "dispextern.h"
+#include "keyboard.h"
 #include "blockinput.h"
 #include "epaths.h"
-#include "w32heap.h"
-#include "termhooks.h"
+#include "character.h"
+#include "charset.h"
 #include "coding.h"
 #include "ccl.h"
+#include "fontset.h"
 #include "systime.h"
+#include "termhooks.h"
+#include "w32heap.h"
 
 #include "bitmaps/gray.xbm"
 
@@ -56,8 +57,12 @@ Boston, MA 02110-1301, USA.  */
 #include <objbase.h>
 
 #include <dlgs.h>
+#include <imm.h>
 #define FILE_NAME_TEXT_FIELD edt1
 
+#include "font.h"
+#include "w32font.h"
+
 void syms_of_w32fns ();
 void globals_of_w32fns ();
 
@@ -66,20 +71,14 @@ extern double atof ();
 extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));
 extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));
 extern void w32_free_menu_strings P_ ((HWND));
+#if OLD_FONT
 extern XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, int));
+#endif
 
 extern int quit_char;
 
 extern char *lispy_function_keys[];
 
-/* The gray bitmap `bitmaps/gray'.  This is done because w32term.c uses
-   it, and including `bitmaps/gray' more than once is a problem when
-   config.h defines `static' as an empty replacement string.  */
-
-int gray_bitmap_width = gray_width;
-int gray_bitmap_height = gray_height;
-unsigned char *gray_bitmap_bits = gray_bits;
-
 /* The colormap for converting color names to RGB values */
 Lisp_Object Vw32_color_map;
 
@@ -142,7 +141,10 @@ int w32_mouse_button_tolerance;
 int w32_mouse_move_interval;
 
 /* Flag to indicate if XBUTTON events should be passed on to Windows.  */
-int w32_pass_extra_mouse_buttons_to_system;
+static int w32_pass_extra_mouse_buttons_to_system;
+
+/* Flag to indicate if media keys should be passed on to Windows.  */
+static int w32_pass_multimedia_buttons_to_system;
 
 /* Non nil if no window manager is in use.  */
 Lisp_Object Vx_no_window_manager;
@@ -151,6 +153,11 @@ Lisp_Object Vx_no_window_manager;
 
 int display_hourglass_p;
 
+/* If non-zero, a w32 timer that, when it expires, displays an
+   hourglass cursor on all frames.  */
+static unsigned hourglass_timer = 0;
+static HWND hourglass_hwnd = NULL;
+
 /* The background and shape of the mouse pointer, and shape when not
    over text or in the modeline.  */
 
@@ -181,14 +188,14 @@ Lisp_Object Vx_pixel_size_width_font_regexp;
 Lisp_Object Vw32_bdf_filename_alist;
 
 /* A flag to control whether fonts are matched strictly or not.  */
-int w32_strict_fontnames;
+static int w32_strict_fontnames;
 
 /* A flag to control whether we should only repaint if GetUpdateRect
    indicates there is an update region.  */
-int w32_strict_painting;
+static int w32_strict_painting;
 
 /* Associative list linking character set strings to Windows codepages. */
-Lisp_Object Vw32_charset_info_alist;
+static Lisp_Object Vw32_charset_info_alist;
 
 /* VIETNAMESE_CHARSET is not defined in some versions of MSVC.  */
 #ifndef VIETNAMESE_CHARSET
@@ -258,13 +265,42 @@ static unsigned mouse_move_timer = 0;
 /* Window that is tracking the mouse.  */
 static HWND track_mouse_window;
 
+/* Multi-monitor API definitions that are not pulled from the headers
+   since we are compiling for NT 4.  */
+#ifndef MONITOR_DEFAULT_TO_NEAREST
+#define MONITOR_DEFAULT_TO_NEAREST 2
+#endif
+/* MinGW headers define MONITORINFO unconditionally, but MSVC ones don't.
+   To avoid a compile error on one or the other, redefine with a new name.  */
+struct MONITOR_INFO
+{
+    DWORD   cbSize;
+    RECT    rcMonitor;
+    RECT    rcWork;
+    DWORD   dwFlags;
+};
+
 typedef BOOL (WINAPI * TrackMouseEvent_Proc)
   (IN OUT LPTRACKMOUSEEVENT lpEventTrack);
+typedef LONG (WINAPI * ImmGetCompositionString_Proc)
+  (IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen);
+typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window);
+typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
+typedef BOOL (WINAPI * GetMonitorInfo_Proc)
+  (IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
 
 TrackMouseEvent_Proc track_mouse_event_fn = NULL;
 ClipboardSequence_Proc clipboard_sequence_fn = NULL;
+ImmGetCompositionString_Proc get_composition_string_fn = NULL;
+ImmGetContext_Proc get_ime_context_fn = NULL;
+MonitorFromPoint_Proc monitor_from_point_fn = NULL;
+GetMonitorInfo_Proc get_monitor_info_fn = NULL;
+
 extern AppendMenuW_Proc unicode_append_menu;
 
+/* Flag to selectively ignore WM_IME_CHAR messages.  */
+static int ignore_ime_char = 0;
+
 /* W95 mousewheel handler */
 unsigned int msh_mousewheel = 0;
 
@@ -272,6 +308,7 @@ unsigned int msh_mousewheel = 0;
 #define MOUSE_BUTTON_ID        1
 #define MOUSE_MOVE_ID  2
 #define MENU_FREE_ID 3
+#define HOURGLASS_ID 4
 /* The delay (milliseconds) before a menu is freed after WM_EXITMENULOOP
    is received.  */
 #define MENU_FREE_DELAY 1000
@@ -303,6 +340,15 @@ static HWND w32_visible_system_caret_hwnd;
 extern HMENU current_popup_menu;
 static int menubar_in_use = 0;
 
+/* From w32uniscribe.c  */
+extern void syms_of_w32uniscribe ();
+extern int uniscribe_available;
+
+/* Function prototypes for hourglass support.  */
+static void show_hourglass P_ ((struct frame *));
+static void hide_hourglass P_ ((void));
+
+
 \f
 /* Error if we are not connected to MS-Windows.  */
 void
@@ -383,16 +429,14 @@ x_window_to_frame (dpyinfo, wdesc)
   Lisp_Object tail, frame;
   struct frame *f;
 
-  for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
+  for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
     {
       frame = XCAR (tail);
-      if (!GC_FRAMEP (frame))
+      if (!FRAMEP (frame))
         continue;
       f = XFRAME (frame);
       if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
        continue;
-      if (f->output_data.w32->hourglass_window == wdesc)
-        return f;
 
       if (FRAME_W32_WINDOW (f) == wdesc)
         return f;
@@ -458,8 +502,8 @@ x_real_positions (f, xptr, yptr)
 
 DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
        Sw32_define_rgb_color, 4, 4, 0,
-       doc: /* Convert RGB numbers to a windows color reference and associate with NAME.
-This adds or updates a named color to w32-color-map, making it
+       doc: /* Convert RGB numbers to a Windows color reference and associate with NAME.
+This adds or updates a named color to `w32-color-map', making it
 available for use.  The original entry's RGB ref is returned, or nil
 if the entry is new.  */)
     (red, green, blue, name)
@@ -474,7 +518,7 @@ if the entry is new.  */)
   CHECK_NUMBER (blue);
   CHECK_STRING (name);
 
-  XSETINT (rgb, RGB(XUINT (red), XUINT (green), XUINT (blue)));
+  XSETINT (rgb, RGB (XUINT (red), XUINT (green), XUINT (blue)));
 
   BLOCK_INPUT;
 
@@ -499,7 +543,7 @@ if the entry is new.  */)
 DEFUN ("w32-load-color-file", Fw32_load_color_file,
        Sw32_load_color_file, 1, 1, 0,
        doc: /* Create an alist of color entries from an external file.
-Assign this value to w32-color-map to replace the existing color map.
+Assign this value to `w32-color-map' to replace the existing color map.
 
 The file should define one named RGB color per line like so:
   R G B   name
@@ -817,7 +861,7 @@ DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map,
   return (cmap);
 }
 
-Lisp_Object
+static Lisp_Object
 w32_to_x_color (rgb)
      Lisp_Object rgb;
 {
@@ -845,11 +889,11 @@ w32_color_map_lookup (colorname)
 
   BLOCK_INPUT;
 
-  for (tail = Vw32_color_map; !NILP (tail); tail = Fcdr (tail))
+  for (tail = Vw32_color_map; CONSP (tail); tail = XCDR (tail))
     {
       register Lisp_Object elt, tem;
 
-      elt = Fcar (tail);
+      elt = XCAR (tail);
       if (!CONSP (elt)) continue;
 
       tem = Fcar (elt);
@@ -934,7 +978,7 @@ x_to_w32_color (colorname)
       int size;
       color = colorname + 1;
 
-      size = strlen(color);
+      size = strlen (color);
       if (size == 3 || size == 6 || size == 9 || size == 12)
        {
          UINT colorval;
@@ -952,11 +996,11 @@ x_to_w32_color (colorname)
              /* The check for 'x' in the following conditional takes into
                 account the fact that strtol allows a "0x" in front of
                 our numbers, and we don't.  */
-             if (!isxdigit(color[0]) || color[1] == 'x')
+             if (!isxdigit (color[0]) || color[1] == 'x')
                break;
              t = color[size];
              color[size] = '\0';
-             value = strtoul(color, &end, 16);
+             value = strtoul (color, &end, 16);
              color[size] = t;
              if (errno == ERANGE || end - color != size)
                break;
@@ -986,7 +1030,7 @@ x_to_w32_color (colorname)
            }
        }
     }
-  else if (strnicmp(colorname, "rgb:", 4) == 0)
+  else if (strnicmp (colorname, "rgb:", 4) == 0)
     {
       char *color;
       UINT colorval;
@@ -1003,9 +1047,9 @@ x_to_w32_color (colorname)
          /* The check for 'x' in the following conditional takes into
             account the fact that strtol allows a "0x" in front of
             our numbers, and we don't.  */
-         if (!isxdigit(color[0]) || color[1] == 'x')
+         if (!isxdigit (color[0]) || color[1] == 'x')
            break;
-         value = strtoul(color, &end, 16);
+         value = strtoul (color, &end, 16);
          if (errno == ERANGE)
            break;
          switch (end - color)
@@ -1041,7 +1085,7 @@ x_to_w32_color (colorname)
          color = end + 1;
        }
     }
-  else if (strnicmp(colorname, "rgbi:", 5) == 0)
+  else if (strnicmp (colorname, "rgbi:", 5) == 0)
     {
       /* This is an RGB Intensity specification.  */
       char *color;
@@ -1057,7 +1101,7 @@ x_to_w32_color (colorname)
          double value;
          UINT val;
 
-         value = strtod(color, &end);
+         value = strtod (color, &end);
          if (errno == ERANGE)
            break;
          if (value < 0.0 || value > 1.0)
@@ -1555,7 +1599,6 @@ x_set_mouse_color (f, arg, oldval)
 #endif /* TODO */
 }
 
-/* Defined in w32term.c. */
 void
 x_set_cursor_color (f, arg, oldval)
      struct frame *f;
@@ -1907,7 +1950,7 @@ x_set_name (f, name, explicit)
        name = ENCODE_SYSTEM (name);
 
       BLOCK_INPUT;
-      SetWindowText(FRAME_W32_WINDOW (f), SDATA (name));
+      SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
       UNBLOCK_INPUT;
     }
 }
@@ -1959,7 +2002,7 @@ x_set_title (f, name, old_name)
        name = ENCODE_SYSTEM (name);
 
       BLOCK_INPUT;
-      SetWindowText(FRAME_W32_WINDOW (f), SDATA (name));
+      SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
       UNBLOCK_INPUT;
     }
 }
@@ -2006,7 +2049,7 @@ Cursor
 w32_load_cursor (LPCTSTR name)
 {
   /* Try first to load cursor from application resource.  */
-  Cursor cursor = LoadImage ((HINSTANCE) GetModuleHandle(NULL),
+  Cursor cursor = LoadImage ((HINSTANCE) GetModuleHandle (NULL),
                             name, IMAGE_CURSOR, 0, 0,
                             LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
   if (!cursor)
@@ -2020,7 +2063,7 @@ w32_load_cursor (LPCTSTR name)
 
 extern LRESULT CALLBACK w32_wnd_proc ();
 
-BOOL
+static BOOL
 w32_init_class (hinst)
      HINSTANCE hinst;
 {
@@ -2040,24 +2083,24 @@ w32_init_class (hinst)
   return (RegisterClass (&wc));
 }
 
-HWND
+static HWND
 w32_createscrollbar (f, bar)
      struct frame *f;
      struct scroll_bar * bar;
 {
   return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,
                        /* Position and size of scroll bar.  */
-                       XINT(bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
-                        XINT(bar->top),
-                       XINT(bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
-                        XINT(bar->height),
+                       XINT (bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+                        XINT (bar->top),
+                       XINT (bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
+                        XINT (bar->height),
                        FRAME_W32_WINDOW (f),
                        NULL,
                        hinst,
                        NULL));
 }
 
-void
+static void
 w32_createwindow (f)
      struct frame *f;
 {
@@ -2127,7 +2170,7 @@ w32_createwindow (f)
     }
 }
 
-void
+static void
 my_post_msg (wmsg, hwnd, msg, wParam, lParam)
      W32Msg * wmsg;
      HWND hwnd;
@@ -2359,7 +2402,7 @@ w32_key_to_modifier (int key)
   return 0;
 }
 
-unsigned int
+static unsigned int
 w32_get_modifiers ()
 {
   return ((modifier_set (VK_SHIFT)   ? shift_modifier : 0) |
@@ -2430,12 +2473,12 @@ map_keypad_keys (unsigned int virt_key, unsigned int extended)
 }
 
 /* List of special key combinations which w32 would normally capture,
-   but emacs should grab instead.  Not directly visible to lisp, to
+   but Emacs should grab instead.  Not directly visible to lisp, to
    simplify synchronization.  Each item is an integer encoding a virtual
    key code and modifier combination to capture.  */
-Lisp_Object w32_grabbed_keys;
+static Lisp_Object w32_grabbed_keys;
 
-#define HOTKEY(vk,mods)       make_number (((vk) & 255) | ((mods) << 8))
+#define HOTKEY(vk, mods)      make_number (((vk) & 255) | ((mods) << 8))
 #define HOTKEY_ID(k)          (XFASTINT (k) & 0xbfff)
 #define HOTKEY_VK_CODE(k)     (XFASTINT (k) & 255)
 #define HOTKEY_MODIFIERS(k)   (XFASTINT (k) >> 8)
@@ -2454,8 +2497,8 @@ register_hot_keys (hwnd)
 {
   Lisp_Object keylist;
 
-  /* Use GC_CONSP, since we are called asynchronously.  */
-  for (keylist = w32_grabbed_keys; GC_CONSP (keylist); keylist = XCDR (keylist))
+  /* Use CONSP, since we are called asynchronously.  */
+  for (keylist = w32_grabbed_keys; CONSP (keylist); keylist = XCDR (keylist))
     {
       Lisp_Object key = XCAR (keylist);
 
@@ -2474,8 +2517,7 @@ unregister_hot_keys (hwnd)
 {
   Lisp_Object keylist;
 
-  /* Use GC_CONSP, since we are called asynchronously.  */
-  for (keylist = w32_grabbed_keys; GC_CONSP (keylist); keylist = XCDR (keylist))
+  for (keylist = w32_grabbed_keys; CONSP (keylist); keylist = XCDR (keylist))
     {
       Lisp_Object key = XCAR (keylist);
 
@@ -2582,8 +2624,12 @@ w32_msg_pump (deferred_msg * msg_buf)
                  abort ();
              }
              break;
+#ifdef MSG_DEBUG
+              /* Broadcast messages make it here, so you need to be looking
+                 for something in particular for this to be useful.  */
            default:
              DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message));
+#endif
            }
        }
       else
@@ -2662,7 +2708,7 @@ complete_deferred_msg (HWND hwnd, UINT msg, LRESULT result)
   deferred_msg * msg_buf = find_deferred_msg (hwnd, msg);
 
   if (msg_buf == NULL)
-    /* Message may have been cancelled, so don't abort().  */
+    /* Message may have been cancelled, so don't abort.  */
     return;
 
   msg_buf->result = result;
@@ -2672,7 +2718,7 @@ complete_deferred_msg (HWND hwnd, UINT msg, LRESULT result)
   PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
 }
 
-void
+static void
 cancel_all_deferred_msgs ()
 {
   deferred_msg * item;
@@ -2710,7 +2756,7 @@ w32_msg_worker (void *arg)
   dummy_buf.w32msg.msg.hwnd = NULL;
   dummy_buf.w32msg.msg.message = WM_NULL;
 
-  /* This is the inital message loop which should only exit when the
+  /* This is the initial message loop which should only exit when the
      application quits.  */
   w32_msg_pump (&dummy_buf);
 
@@ -2750,7 +2796,7 @@ post_character_message (hwnd, msg, wParam, lParam, modifiers)
 
   /* Detect quit_char and set quit-flag directly.  Note that we
      still need to post a message to ensure the main thread will be
-     woken up if blocked in sys_select(), but we do NOT want to post
+     woken up if blocked in sys_select, but we do NOT want to post
      the quit_char message itself (because it will usually be as if
      the user had typed quit_char twice).  Instead, we post a dummy
      message that has no particular effect. */
@@ -2905,7 +2951,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
 
        /* If GetUpdateRect returns 0 (meaning there is no update
            region), assume the whole window needs to be repainted.  */
-       GetClientRect(hwnd, &wmsg.rect);
+       GetClientRect (hwnd, &wmsg.rect);
        my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
         return 0;
       }
@@ -2962,7 +3008,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
             they don't produce WM_CHAR messages).  This ensures that
             indicator lights are toggled promptly on Windows 9x, for
             example.  */
-         if (lispy_function_keys[wParam] != 0)
+         if (wParam < 256 && lispy_function_keys[wParam])
            {
              windows_translate = 1;
              goto translate;
@@ -3084,7 +3130,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
          break;
        default:
          /* If not defined as a function key, change it to a WM_CHAR message. */
-         if (lispy_function_keys[wParam] == 0)
+         if (wParam > 255 || !lispy_function_keys[wParam])
            {
              DWORD modifiers = construct_console_modifiers ();
 
@@ -3135,7 +3181,8 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
                        {
                          /* Forward asciified character sequence.  */
                          post_character_message
-                           (hwnd, WM_CHAR, key.uChar.AsciiChar, lParam,
+                           (hwnd, WM_CHAR,
+                             (unsigned char) key.uChar.AsciiChar, lParam,
                             w32_get_key_modifiers (wParam, lParam));
                          w32_kbd_patch_key (&key);
                        }
@@ -3154,7 +3201,6 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
       if (windows_translate)
        {
          MSG windows_msg = { hwnd, msg, wParam, lParam, 0, {0,0} };
-
          windows_msg.time = GetMessageTime ();
          TranslateMessage (&windows_msg);
          goto dflt;
@@ -3168,6 +3214,64 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
                              w32_get_key_modifiers (wParam, lParam));
       break;
 
+    case WM_UNICHAR:
+      /* WM_UNICHAR looks promising from the docs, but the exact
+         circumstances in which TranslateMessage sends it is one of those
+         Microsoft secret API things that EU and US courts are supposed
+         to have put a stop to already. Spy++ shows it being sent to Notepad
+         and other MS apps, but never to Emacs.
+
+         Some third party IMEs send it in accordance with the official
+         documentation though, so handle it here.
+
+         UNICODE_NOCHAR is used to test for support for this message.
+         TRUE indicates that the message is supported.  */
+      if (wParam == UNICODE_NOCHAR)
+        return TRUE;
+
+      {
+        W32Msg wmsg;
+        wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
+        signal_user_input ();
+        my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+      }
+      break;
+
+    case WM_IME_CHAR:
+      /* If we can't get the IME result as unicode, use default processing,
+         which will at least allow characters decodable in the system locale
+         get through.  */
+      if (!get_composition_string_fn)
+        goto dflt;
+
+      else if (!ignore_ime_char)
+        {
+          wchar_t * buffer;
+          int size, i;
+          W32Msg wmsg;
+          HIMC context = get_ime_context_fn (hwnd);
+          wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
+          /* Get buffer size.  */
+          size = get_composition_string_fn (context, GCS_RESULTSTR, buffer, 0);
+          buffer = alloca(size);
+          size = get_composition_string_fn (context, GCS_RESULTSTR,
+                                            buffer, size);
+          signal_user_input ();
+          for (i = 0; i < size / sizeof (wchar_t); i++)
+            {
+              my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer[i],
+                           lParam);
+            }
+          /* We output the whole string above, so ignore following ones
+             until we are notified of the end of composition.  */
+          ignore_ime_char = 1;
+        }
+      break;
+
+    case WM_IME_ENDCOMPOSITION:
+      ignore_ime_char = 0;
+      goto dflt;
+
       /* Simulate middle mouse button events when left and right buttons
         are used together, but only if user has two button mouse. */
     case WM_LBUTTONDOWN:
@@ -3382,6 +3486,10 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
       signal_user_input ();
       return 0;
 
+    case WM_APPCOMMAND:
+      if (w32_pass_multimedia_buttons_to_system)
+        goto dflt;
+      /* Otherwise, pass to lisp, the same way we do with mousehwheel.  */
     case WM_MOUSEHWHEEL:
       wmsg.dwModifiers = w32_get_modifiers ();
       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
@@ -3429,6 +3537,12 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
               menubar_in_use = 0;
            }
        }
+      else if (wParam == hourglass_timer)
+       {
+         KillTimer (hwnd, hourglass_timer);
+         hourglass_timer = 0;
+         show_hourglass (x_window_to_frame (dpyinfo, hwnd));
+       }
       return 0;
 
     case WM_NCACTIVATE:
@@ -3494,6 +3608,11 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
       */
       if (f && menubar_in_use && current_popup_menu == NULL)
        menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
+
+      /* If hourglass cursor should be displayed, display it now.  */
+      if (f && f->output_data.w32->hourglass_p)
+       SetCursor (f->output_data.w32->hourglass_cursor);
+
       goto dflt;
 
     case WM_MENUSELECT:
@@ -3695,7 +3814,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
            DWORD scrollbar_extra;
            RECT wr;
 
-           wp.length = sizeof(wp);
+           wp.length = sizeof (wp);
            GetWindowRect (hwnd, &wr);
 
            enter_crit ();
@@ -3762,15 +3881,27 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
 
     case WM_SETCURSOR:
       if (LOWORD (lParam) == HTCLIENT)
-       return 0;
-
+       {
+         f = x_window_to_frame (dpyinfo, hwnd);
+         if (f->output_data.w32->hourglass_p && !menubar_in_use
+             && !current_popup_menu)
+           SetCursor (f->output_data.w32->hourglass_cursor);
+         else
+           SetCursor (f->output_data.w32->current_cursor);
+         return 0;
+       }
       goto dflt;
 
     case WM_EMACS_SETCURSOR:
       {
        Cursor cursor = (Cursor) wParam;
-       if (cursor)
-         SetCursor (cursor);
+       f = x_window_to_frame (dpyinfo, hwnd);
+       if (f && cursor)
+         {
+           f->output_data.w32->current_cursor = cursor;
+           if (!f->output_data.w32->hourglass_p)
+             SetCursor (cursor);
+         }
        return 0;
       }
 
@@ -4136,11 +4267,41 @@ unwind_create_frame (frame)
   return Qnil;
 }
 
+static void
+x_default_font_parameter (f, parms)
+     struct frame *f;
+     Lisp_Object parms;
+{
+  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+  Lisp_Object font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font",
+                                RES_TYPE_STRING);
+
+  if (!STRINGP (font))
+    {
+      int i;
+      static char *names[]
+        = { "Courier New-10",
+            "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
+            "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
+            "Fixedsys",
+            NULL };
+
+      for (i = 0; names[i]; i++)
+        {
+          font = font_open_by_name (f, names[i]);
+          if (! NILP (font))
+            break;
+        }
+      if (NILP (font))
+        error ("No suitable font was found");
+    }
+  x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
+}
 
 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
        1, 1, 0,
        doc: /* Make a new window, which is called a \"frame\" in Emacs terms.
-Returns an Emacs frame object.
+Return an Emacs frame object.
 PARAMETERS is an alist of frame parameters.
 If the parameters specify that the frame should not have a minibuffer,
 and do not specify a specific minibuffer window to use,
@@ -4166,6 +4327,10 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
   check_w32 ();
 
+  /* Make copy of frame parameters because the original is in pure
+     storage now. */
+  parameters = Fcopy_alist (parameters);
+
   /* Use this general default value to start with
      until we know if this frame has a specified name.  */
   Vx_resource_name = Vinvocation_name;
@@ -4271,39 +4436,18 @@ This function is an internal primitive--use `make-frame' instead.  */)
       specbind (Qx_resource_name, name);
     }
 
-  /* Extract the window parameters from the supplied values
-     that are needed to determine window geometry.  */
-  {
-    Lisp_Object font;
-
-    font = w32_get_arg (parameters, Qfont, "font", "Font", RES_TYPE_STRING);
-
-    BLOCK_INPUT;
-    /* First, try whatever font the caller has specified.  */
-    if (STRINGP (font))
-      {
-        tem = Fquery_fontset (font, Qnil);
-        if (STRINGP (tem))
-          font = x_new_fontset (f, SDATA (tem));
-        else
-          font = x_new_font (f, SDATA (font));
-      }
-    /* Try out a font which we hope has bold and italic variations.  */
-    if (!STRINGP (font))
-      font = x_new_font (f, "-*-Courier New-normal-r-*-*-*-100-*-*-c-*-iso8859-1");
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1");
-    /* If those didn't work, look for something which will at least work.  */
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1");
-    UNBLOCK_INPUT;
-    if (! STRINGP (font))
-      font = build_string ("Fixedsys");
+  f->resx = dpyinfo->resx;
+  f->resy = dpyinfo->resy;
 
-    x_default_parameter (f, parameters, Qfont, font,
-                        "font", "Font", RES_TYPE_STRING);
-  }
+  if (uniscribe_available)
+    register_font_driver (&uniscribe_font_driver, f);
+  register_font_driver (&w32font_driver, f);
 
+  x_default_parameter (f, parameters, Qfont_backend, Qnil,
+                      "fontBackend", "FontBackend", RES_TYPE_STRING);
+  /* Extract the window parameters from the supplied values
+     that are needed to determine window geometry.  */
+  x_default_font_parameter (f, parameters);
   x_default_parameter (f, parameters, Qborder_width, make_number (2),
                       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
   /* This defaults to 2 in order to match xterm.  We recognize either
@@ -4376,6 +4520,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
   f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
 
+  f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
+
   window_prompting = x_figure_window_size (f, parameters, 1);
 
   tem = w32_get_arg (parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
@@ -4450,12 +4596,10 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
   /* All remaining specified parameters, which have not been "used"
      by x_get_arg and friends, now go in the misc. alist of the frame.  */
-  for (tem = parameters; !NILP (tem); tem = XCDR (tem))
+  for (tem = parameters; CONSP (tem); tem = XCDR (tem))
     if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
       f->param_alist = Fcons (XCAR (tem), f->param_alist);
 
-  store_frame_param (f, Qwindow_system, Qw32);
-  
   UNGCPRO;
 
   /* Make sure windows on this frame appear in calls to next-window
@@ -4491,12 +4635,15 @@ DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
 }
 
 \f
+#if OLD_FONT
+
 /* Return the charset portion of a font name.  */
-char * xlfd_charset_of_font (char * fontname)
+char *
+xlfd_charset_of_font (char * fontname)
 {
   char *charset, *encoding;
 
-  encoding = strrchr(fontname, '-');
+  encoding = strrchr (fontname, '-');
   if (!encoding || encoding == fontname)
     return NULL;
 
@@ -4504,7 +4651,7 @@ char * xlfd_charset_of_font (char * fontname)
     if (*charset == '-')
       break;
 
-  if (charset == fontname || strcmp(charset, "-*-*") == 0)
+  if (charset == fontname || strcmp (charset, "-*-*") == 0)
     return NULL;
 
   return charset + 1;
@@ -4518,7 +4665,7 @@ static BOOL w32_to_x_font (LOGFONT * lplf, char * lpxstr, int len,
 static BOOL x_to_w32_font (char *lpxstr, LOGFONT *lplogfont);
 
 static struct font_info *
-w32_load_system_font (f,fontname,size)
+w32_load_system_font (f, fontname, size)
      struct frame *f;
      char * fontname;
      int size;
@@ -4621,7 +4768,7 @@ w32_load_system_font (f,fontname,size)
                GetFontLanguageInfo, we check the properties of the
                codepage directly, since that is ultimately what we are
                working from anyway.  */
-           /* font->double_byte_p = GetFontLanguageInfo(hdc) & GCP_DBCS; */
+           /* font->double_byte_p = GetFontLanguageInfo (hdc) & GCP_DBCS; */
            CPINFO cpi = {0};
            GetCPInfo (codepage, &cpi);
            font->double_byte_p = cpi.MaxCharSize > 1;
@@ -4680,10 +4827,10 @@ w32_load_system_font (f,fontname,size)
     fontp->name = (char *) xmalloc (strlen (fontname) + 1);
     bcopy (fontname, fontp->name, strlen (fontname) + 1);
 
-    if (lf.lfPitchAndFamily == FIXED_PITCH)
+    if ((lf.lfPitchAndFamily & 0x03) == FIXED_PITCH)
       {
        /* Fixed width font.  */
-       fontp->average_width = fontp->space_width = FONT_WIDTH (font);
+       fontp->average_width = fontp->space_width = FONT_AVG_WIDTH (font);
       }
     else
       {
@@ -4693,11 +4840,12 @@ w32_load_system_font (f,fontname,size)
        if (pcm)
          fontp->space_width = pcm->width;
        else
-         fontp->space_width = FONT_WIDTH (font);
+         fontp->space_width = FONT_AVG_WIDTH (font);
 
        fontp->average_width = font->tm.tmAveCharWidth;
       }
 
+    fontp->charset = -1;
     charset = xlfd_charset_of_font (fontname);
 
   /* Cache the W32 codepage for a font.  This makes w32_encode_char
@@ -4724,7 +4872,7 @@ w32_load_system_font (f,fontname,size)
        (0:0x20..0x7F, 1:0xA0..0xFF,
        (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
        2:0xA020..0xFF7F).  For the moment, we don't know which charset
-       uses this font.  So, we set information in fontp->encoding[1]
+       uses this font.  So, we set information in fontp->encoding_type
        which is never used by any charset.  If mapping can't be
        decided, set FONT_ENCODING_NOT_DECIDED.  */
 
@@ -4732,9 +4880,9 @@ w32_load_system_font (f,fontname,size)
        type FONT_ENCODING_NOT_DECIDED.  */
     encoding = strrchr (fontp->name, '-');
     if (encoding && strnicmp (encoding+1, "sjis", 4) == 0)
-      fontp->encoding[1] = 4;
+      fontp->encoding_type = 4;
     else
-      fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED;
+      fontp->encoding_type = FONT_ENCODING_NOT_DECIDED;
 
     /* The following three values are set to 0 under W32, which is
        what they get set to if XGetFontProperty fails under X.  */
@@ -4757,10 +4905,10 @@ w32_load_system_font (f,fontname,size)
    pointer to the structure font_info while allocating it dynamically.
    If loading fails, return NULL. */
 struct font_info *
-w32_load_font (f,fontname,size)
-struct frame *f;
-char * fontname;
-int size;
+w32_load_font (f, fontname, size)
+     struct frame *f;
+     char * fontname;
+     int size;
 {
   Lisp_Object bdf_fonts;
   struct font_info *retval = NULL;
@@ -4778,7 +4926,7 @@ int size;
       bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist);
       bdf_file = SDATA (XCDR (bdf_pair));
 
-      // If the font is already loaded, do not load it again.
+      /* If the font is already loaded, do not load it again.  */
       for (i = 0; i < dpyinfo->n_fonts; i++)
        {
          if ((dpyinfo->font_table[i].name
@@ -4796,7 +4944,7 @@ int size;
   if (retval)
     return retval;
 
-  return w32_load_system_font(f, fontname, size);
+  return w32_load_system_font (f, fontname, size);
 }
 
 
@@ -4807,13 +4955,14 @@ w32_unload_font (dpyinfo, font)
 {
   if (font)
     {
-      if (font->per_char) xfree (font->per_char);
+      xfree (font->per_char);
       if (font->bdf) w32_free_bdf_font (font->bdf);
 
-      if (font->hfont) DeleteObject(font->hfont);
+      if (font->hfont) DeleteObject (font->hfont);
       xfree (font);
     }
 }
+#endif /* OLD_FONT */
 
 /* The font conversion stuff between x and w32 */
 
@@ -4844,16 +4993,16 @@ x_to_w32_weight (lpw)
 {
   if (!lpw) return (FW_DONTCARE);
 
-  if (stricmp (lpw,"heavy") == 0)             return FW_HEAVY;
-  else if (stricmp (lpw,"extrabold") == 0)    return FW_EXTRABOLD;
-  else if (stricmp (lpw,"bold") == 0)         return FW_BOLD;
-  else if (stricmp (lpw,"demibold") == 0)     return FW_SEMIBOLD;
-  else if (stricmp (lpw,"semibold") == 0)     return FW_SEMIBOLD;
-  else if (stricmp (lpw,"medium") == 0)       return FW_MEDIUM;
-  else if (stricmp (lpw,"normal") == 0)       return FW_NORMAL;
-  else if (stricmp (lpw,"light") == 0)        return FW_LIGHT;
-  else if (stricmp (lpw,"extralight") == 0)   return FW_EXTRALIGHT;
-  else if (stricmp (lpw,"thin") == 0)         return FW_THIN;
+  if (xstrcasecmp (lpw, "heavy") == 0)             return FW_HEAVY;
+  else if (xstrcasecmp (lpw, "extrabold") == 0)    return FW_EXTRABOLD;
+  else if (xstrcasecmp (lpw, "bold") == 0)         return FW_BOLD;
+  else if (xstrcasecmp (lpw, "demibold") == 0)     return FW_SEMIBOLD;
+  else if (xstrcasecmp (lpw, "semibold") == 0)     return FW_SEMIBOLD;
+  else if (xstrcasecmp (lpw, "medium") == 0)       return FW_MEDIUM;
+  else if (xstrcasecmp (lpw, "normal") == 0)       return FW_NORMAL;
+  else if (xstrcasecmp (lpw, "light") == 0)        return FW_LIGHT;
+  else if (xstrcasecmp (lpw, "extralight") == 0)   return FW_EXTRALIGHT;
+  else if (xstrcasecmp (lpw, "thin") == 0)         return FW_THIN;
   else
     return FW_DONTCARE;
 }
@@ -4876,7 +5025,7 @@ w32_to_x_weight (fnweight)
     return "*";
 }
 
-static LONG
+LONG
 x_to_w32_charset (lpcs)
     char * lpcs;
 {
@@ -4888,23 +5037,27 @@ x_to_w32_charset (lpcs)
   if (strncmp (lpcs, "*-#", 3) == 0)
     return atoi (lpcs + 3);
 
+  /* All Windows fonts qualify as unicode.  */
+  if (!strncmp (lpcs, "iso10646", 8))
+    return DEFAULT_CHARSET;
+
   /* Handle wildcards by ignoring them; eg. treat "big5*-*" as "big5".  */
   charset = alloca (len + 1);
   strcpy (charset, lpcs);
   lpcs = strchr (charset, '*');
   if (lpcs)
-    *lpcs = 0;
+    *lpcs = '\0';
 
   /* Look through w32-charset-info-alist for the character set.
      Format of each entry is
        (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
   */
-  this_entry = Fassoc (build_string(charset), Vw32_charset_info_alist);
+  this_entry = Fassoc (build_string (charset), Vw32_charset_info_alist);
 
-  if (NILP(this_entry))
+  if (NILP (this_entry))
     {
       /* At startup, we want iso8859-1 fonts to come up properly. */
-      if (stricmp(charset, "iso8859-1") == 0)
+      if (xstrcasecmp (charset, "iso8859-1") == 0)
         return ANSI_CHARSET;
       else
         return DEFAULT_CHARSET;
@@ -4960,19 +5113,34 @@ x_to_w32_charset (lpcs)
 }
 
 
-static char *
-w32_to_x_charset (fncharset)
+char *
+w32_to_x_charset (fncharset, matching)
     int fncharset;
+    char *matching;
 {
   static char buf[32];
   Lisp_Object charset_type;
+  int match_len = 0;
+
+  if (matching)
+    {
+      /* If fully specified, accept it as it is.  Otherwise use a
+        substring match. */
+      char *wildcard = strchr (matching, '*');
+      if (wildcard)
+       *wildcard = '\0';
+      else if (strchr (matching, '-'))
+       return matching;
+
+      match_len = strlen (matching);
+    }
 
   switch (fncharset)
     {
     case ANSI_CHARSET:
       /* Handle startup case of w32-charset-info-alist not
          being set up yet. */
-      if (NILP(Vw32_charset_info_alist))
+      if (NILP (Vw32_charset_info_alist))
         return "iso8859-1";
       charset_type = Qw32_charset_ansi;
       break;
@@ -5050,6 +5218,7 @@ w32_to_x_charset (fncharset)
   {
     Lisp_Object rest;
     char * best_match = NULL;
+    int matching_found = 0;
 
     /* Look through w32-charset-info-alist for the character set.
        Prefer ISO codepages, and prefer lower numbers in the ISO
@@ -5085,12 +5254,34 @@ w32_to_x_charset (fncharset)
             /* If we don't have a match already, then this is the
                best.  */
             if (!best_match)
-              best_match = x_charset;
-            /* If this is an ISO codepage, and the best so far isn't,
-               then this is better.  */
-            else if (strnicmp (best_match, "iso", 3) != 0
-                     && strnicmp (x_charset, "iso", 3) == 0)
-              best_match = x_charset;
+             {
+               best_match = x_charset;
+               if (matching && !strnicmp (x_charset, matching, match_len))
+                 matching_found = 1;
+             }
+           /* If we already found a match for MATCHING, then
+              only consider other matches.  */
+           else if (matching_found
+                    && strnicmp (x_charset, matching, match_len))
+             continue;
+           /* If this matches what we want, and the best so far doesn't,
+              then this is better.  */
+           else if (!matching_found && matching
+                    && !strnicmp (x_charset, matching, match_len))
+             {
+               best_match = x_charset;
+               matching_found = 1;
+             }
+           /* If this is fully specified, and the best so far isn't,
+              then this is better.  */
+           else if ((!strchr (best_match, '-') && strchr (x_charset, '-'))
+           /* If this is an ISO codepage, and the best so far isn't,
+              then this is better, but only if it fully specifies the
+              encoding.  */
+               || (strnicmp (best_match, "iso", 3) != 0
+                   && strnicmp (x_charset, "iso", 3) == 0
+                   && strchr (x_charset, '-')))
+               best_match = x_charset;
             /* If both are ISO8859 codepages, choose the one with the
                lowest number in the encoding field.  */
             else if (strnicmp (best_match, "iso8859-", 8) == 0
@@ -5111,7 +5302,18 @@ w32_to_x_charset (fncharset)
         return buf;
       }
 
-    strncpy(buf, best_match, 31);
+    strncpy (buf, best_match, 31);
+    /* If the charset is not fully specified, put -0 on the end.  */
+    if (!strchr (best_match, '-'))
+      {
+       int pos = strlen (best_match);
+       /* Charset specifiers shouldn't be very long.  If it is a made
+          up one, truncating it should not do any harm since it isn't
+          recognized anyway.  */
+       if (pos > 29)
+         pos = 29;
+       strcpy (buf + pos, "-0");
+      }
     buf[31] = '\0';
     return buf;
   }
@@ -5132,7 +5334,7 @@ w32_to_all_x_charsets (fncharset)
     case ANSI_CHARSET:
       /* Handle startup case of w32-charset-info-alist not
          being set up yet. */
-      if (NILP(Vw32_charset_info_alist))
+      if (NILP (Vw32_charset_info_alist))
         return Fcons (build_string ("iso8859-1"), Qnil);
 
       charset_type = Qw32_charset_ansi;
@@ -5211,7 +5413,8 @@ w32_to_all_x_charsets (fncharset)
   {
     Lisp_Object rest;
     /* Look through w32-charset-info-alist for the character set.
-       Only return charsets for codepages which are installed.
+       Only return fully specified charsets for codepages which are
+       installed.
 
        Format of each entry in Vw32_charset_info_alist is
          (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
@@ -5234,6 +5437,9 @@ w32_to_all_x_charsets (fncharset)
         w32_charset = XCAR (XCDR (this_entry));
         codepage = XCDR (XCDR (this_entry));
 
+       if (!strchr (SDATA (x_charset), '-'))
+         continue;
+
         /* Look for Same charset and a valid codepage (or non-int
            which means ignore).  */
         if (EQ (w32_charset, charset_type)
@@ -5255,6 +5461,8 @@ w32_to_all_x_charsets (fncharset)
   }
 }
 
+#if OLD_FONT
+
 /* Get the Windows codepage corresponding to the specified font.  The
    charset info in the font name is used to look up
    w32-charset-to-codepage-alist.  */
@@ -5264,9 +5472,6 @@ w32_codepage_for_font (char *fontname)
   Lisp_Object codepage, entry;
   char *charset_str, *charset, *end;
 
-  if (NILP (Vw32_charset_info_alist))
-    return CP_DEFAULT;
-
   /* Extract charset part of font string.  */
   charset = xlfd_charset_of_font (fontname);
 
@@ -5292,6 +5497,12 @@ w32_codepage_for_font (char *fontname)
         *end = '\0';
       }
 
+  if (!strcmp (charset, "iso10646"))
+    return CP_UNICODE;
+
+  if (NILP (Vw32_charset_info_alist))
+    return CP_DEFAULT;
+
   entry = Fassoc (build_string(charset), Vw32_charset_info_alist);
   if (NILP (entry))
     return CP_UNKNOWN;
@@ -5307,7 +5518,7 @@ w32_codepage_for_font (char *fontname)
   else
     return CP_UNKNOWN;
 }
-
+#endif /* OLD_FONT */
 
 static BOOL
 w32_to_x_font (lplogfont, lpxstr, len, specific_charset)
@@ -5324,7 +5535,6 @@ w32_to_x_font (lplogfont, lpxstr, len, specific_charset)
   char *fontname_dash;
   int display_resy = (int) one_w32_display_info.resy;
   int display_resx = (int) one_w32_display_info.resx;
-  int bufsz;
   struct coding_system coding;
 
   if (!lpxstr) abort ();
@@ -5346,12 +5556,14 @@ w32_to_x_font (lplogfont, lpxstr, len, specific_charset)
   coding.mode |= CODING_MODE_LAST_BLOCK;
   /* We explicitely disable composition handling because selection
      data should not contain any composition sequence.  */
-  coding.composing = COMPOSITION_DISABLED;
-  bufsz = decoding_buffer_size (&coding, LF_FACESIZE);
+  coding.common_flags &= ~CODING_ANNOTATION_MASK;
+
+  coding.dst_bytes = LF_FACESIZE * 2;
+  coding.destination = (unsigned char *) xmalloc (coding.dst_bytes + 1);
+  decode_coding_c_string (&coding, lplogfont->lfFaceName,
+                         strlen(lplogfont->lfFaceName), Qnil);
+  fontname = coding.destination;
 
-  fontname = alloca(sizeof(*fontname) * bufsz);
-  decode_coding (&coding, lplogfont->lfFaceName, fontname,
-                 strlen(lplogfont->lfFaceName), bufsz - 1);
   *(fontname + coding.produced) = '\0';
 
   /* Replace dashes with underscores so the dashes are not
@@ -5372,7 +5584,7 @@ w32_to_x_font (lplogfont, lpxstr, len, specific_charset)
       strcpy (height_dpi, "*");
     }
 
-#if 0 /* Never put the width in the xfld. It fails on fonts with
+#if 0 /* Never put the width in the xlfd. It fails on fonts with
         double-width characters.  */
   if (lplogfont->lfWidth)
     sprintf (width_pixels, "%u", lplogfont->lfWidth * 10);
@@ -5395,8 +5607,7 @@ w32_to_x_font (lplogfont, lpxstr, len, specific_charset)
             ((lplogfont->lfPitchAndFamily & 0x3) == VARIABLE_PITCH)
              ? 'p' : 'c',                            /* spacing */
             width_pixels,                           /* avg width */
-            specific_charset ? specific_charset
-             : w32_to_x_charset (lplogfont->lfCharSet)
+             w32_to_x_charset (lplogfont->lfCharSet, specific_charset)
              /* charset registry and encoding */
             );
 
@@ -5474,26 +5685,24 @@ x_to_w32_font (lpxstr, lplogfont)
 
       if (fields > 0 && name[0] != '*')
         {
-         int bufsize;
-         unsigned char *buf;
-
+         Lisp_Object string = build_string (name);
           setup_coding_system
             (Fcheck_coding_system (Vlocale_coding_system), &coding);
-         coding.src_multibyte = 1;
-         coding.dst_multibyte = 0;
-         /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
-            encode_coding_iso2022 trying to dereference a null pointer.  */
-         coding.composing = COMPOSITION_DISABLED;
-         if (coding.type == coding_type_iso2022)
-           coding.flags |= CODING_FLAG_ISO_SAFE;
-         bufsize = encoding_buffer_size (&coding, strlen (name));
-         buf = (unsigned char *) alloca (bufsize);
-          coding.mode |= CODING_MODE_LAST_BLOCK;
-          encode_coding (&coding, name, buf, strlen (name), bufsize);
+          coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
+         /* Disable composition/charset annotation.   */
+         coding.common_flags &= ~CODING_ANNOTATION_MASK;
+         coding.dst_bytes = SCHARS (string) * 2;
+
+         coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
+          encode_coding_object (&coding, string, 0, 0,
+                               SCHARS (string), SBYTES (string), Qnil);
          if (coding.produced >= LF_FACESIZE)
            coding.produced = LF_FACESIZE - 1;
-         buf[coding.produced] = 0;
-         strcpy (lplogfont->lfFaceName, buf);
+
+         coding.destination[coding.produced] = '\0';
+
+         strcpy (lplogfont->lfFaceName, coding.destination);
+         xfree (coding.destination);
        }
       else
         {
@@ -5525,8 +5734,12 @@ x_to_w32_font (lpxstr, lplogfont)
        lplogfont->lfHeight = atoi (height) * dpi / 720;
 
       if (fields > 0)
-      lplogfont->lfPitchAndFamily =
-       (fields > 0 && pitch == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
+        {
+          if (pitch == 'p')
+            lplogfont->lfPitchAndFamily = VARIABLE_PITCH | FF_DONTCARE;
+          else if (pitch == 'c')
+            lplogfont->lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
+        }
 
       fields--;
 
@@ -5562,7 +5775,7 @@ x_to_w32_font (lpxstr, lplogfont)
 
       if (fields > 0)
         {
-         strncpy (lplogfont->lfFaceName,name, LF_FACESIZE);
+         strncpy (lplogfont->lfFaceName, name, LF_FACESIZE);
          lplogfont->lfFaceName[LF_FACESIZE-1] = 0;
        }
       else
@@ -5591,6 +5804,8 @@ x_to_w32_font (lpxstr, lplogfont)
   return (TRUE);
 }
 
+#if OLD_FONT
+
 /* Strip the pixel height and point height from the given xlfd, and
    return the pixel height. If no pixel height is specified, calculate
    one from the point height, or if that isn't defined either, return
@@ -5761,7 +5976,7 @@ w32_font_match (fontname, pattern)
   }
 
   return (fast_string_match_ignore_case (build_string (regex),
-                                         build_string(font_name_copy)) >= 0);
+                                         build_string (font_name_copy)) >= 0);
 }
 
 /* Callback functions, and a structure holding info they need, for
@@ -5871,14 +6086,23 @@ enum_font_cb2 (lplf, lptm, FontType, lpef)
        if (charset
            && strncmp (charset, "*-*", 3) != 0
            && lpef->logfont.lfCharSet == DEFAULT_CHARSET
-           && strcmp (charset, w32_to_x_charset (DEFAULT_CHARSET)) != 0)
+           && strcmp (charset, w32_to_x_charset (DEFAULT_CHARSET, NULL)) != 0)
          return 1;
+
+        /* Reject raster fonts if we are looking for a unicode font.  */
+        if (charset
+            && FontType == RASTER_FONTTYPE
+            && strncmp (charset, "iso10646", 8) == 0)
+          return 1;
       }
 
     if (charset)
       charset_list = Fcons (build_string (charset), Qnil);
     else
-      charset_list = w32_to_all_x_charsets (lplf->elfLogFont.lfCharSet);
+      /* Always prefer unicode.  */
+      charset_list
+       = Fcons (build_string ("iso10646-1"),
+                w32_to_all_x_charsets (lplf->elfLogFont.lfCharSet));
 
     /* Loop through the charsets.  */
     for ( ; CONSP (charset_list); charset_list = Fcdr (charset_list))
@@ -5886,14 +6110,21 @@ enum_font_cb2 (lplf, lptm, FontType, lpef)
        Lisp_Object this_charset = Fcar (charset_list);
        charset = SDATA (this_charset);
 
+       /* Don't list  raster fonts as unicode.  */
+       if (charset
+           && FontType == RASTER_FONTTYPE
+           && strncmp (charset, "iso10646", 8) == 0)
+         continue;
+
+       enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
+                                    charset, width);
+
        /* List bold and italic variations if w32-enable-synthesized-fonts
           is non-nil and this is a plain font.  */
        if (w32_enable_synthesized_fonts
            && lplf->elfLogFont.lfWeight == FW_NORMAL
            && lplf->elfLogFont.lfItalic == FALSE)
          {
-           enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
-                                        charset, width);
            /* bold.  */
            lplf->elfLogFont.lfWeight = FW_BOLD;
            enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
@@ -5907,9 +6138,6 @@ enum_font_cb2 (lplf, lptm, FontType, lpef)
            enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
                                         charset, width);
          }
-       else
-         enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
-                                      charset, width);
       }
   }
 
@@ -5996,7 +6224,8 @@ enum_fontex_cb1 (lplf, lptm, font_type, lpef)
 /* Interface to fontset handler. (adapted from mw32font.c in Meadow
    and xterm.c in Emacs 20.3) */
 
-static Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern, int max_names)
+static Lisp_Object
+w32_list_bdf_fonts (Lisp_Object pattern, int max_names)
 {
   char *fontname, *ptnstr;
   Lisp_Object list, tem, newlist = Qnil;
@@ -6067,7 +6296,7 @@ w32_list_fonts (f, pattern, size, maxnames)
       codepage = w32_codepage_for_font (SDATA (tpat));
       if (codepage != CP_8BIT && codepage != CP_UNICODE
           && codepage != CP_DEFAULT && codepage != CP_UNKNOWN
-         && !IsValidCodePage(codepage))
+         && !IsValidCodePage (codepage))
         continue;
 
       /* See if we cached the result for this particular query.
@@ -6173,12 +6402,12 @@ w32_list_fonts (f, pattern, size, maxnames)
               hdc = GetDC (dpyinfo->root_window);
               oldobj = SelectObject (hdc, thisinfo.hfont);
               if (GetTextMetrics (hdc, &thisinfo.tm))
-                XSETCDR (tem, make_number (FONT_WIDTH (&thisinfo)));
+                XSETCDR (tem, make_number (FONT_AVG_WIDTH (&thisinfo)));
               else
                 XSETCDR (tem, make_number (0));
               SelectObject (hdc, oldobj);
               ReleaseDC (dpyinfo->root_window, hdc);
-              DeleteObject(thisinfo.hfont);
+              DeleteObject (thisinfo.hfont);
               UNBLOCK_INPUT;
             }
           found_size = XINT (XCDR (tem));
@@ -6227,7 +6456,7 @@ w32_list_fonts (f, pattern, size, maxnames)
     Lisp_Object combined[2];
     combined[0] = w32_list_bdf_fonts (pattern, maxnames - n_fonts);
     combined[1] = newlist;
-    newlist = Fnconc(2, combined);
+    newlist = Fnconc (2, combined);
   }
 
   return newlist;
@@ -6254,7 +6483,7 @@ w32_query_font (struct frame *f, char *fontname)
 
   for (i = 0; i < one_w32_display_info.n_fonts ;i++, pfi++)
     {
-      if (stricmp(pfi->name, fontname) == 0) return pfi;
+      if (xstrcasecmp (pfi->name, fontname) == 0) return pfi;
     }
 
   return NULL;
@@ -6290,10 +6519,14 @@ w32_find_ccl_program (fontp)
     }
 }
 
+#endif /* OLD_FONT */
+
 /* directory-files from dired.c.  */
-Lisp_Object Fdirectory_files P_((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
+Lisp_Object Fdirectory_files P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
 
 \f
+#if OLD_FONT
+
 /* Find BDF files in a specified directory.  (use GCPRO when calling,
    as this calls lisp to get a directory listing).  */
 static Lisp_Object
@@ -6302,13 +6535,13 @@ w32_find_bdf_fonts_in_dir (Lisp_Object directory)
   Lisp_Object filelist, list = Qnil;
   char fontname[100];
 
-  if (!STRINGP(directory))
+  if (!STRINGP (directory))
     return Qnil;
 
   filelist = Fdirectory_files (directory, Qt,
                               build_string (".*\\.[bB][dD][fF]"), Qt);
 
-  for ( ; CONSP(filelist); filelist = XCDR (filelist))
+  for ( ; CONSP (filelist); filelist = XCDR (filelist))
     {
       Lisp_Object filename = XCAR (filelist);
       if (w32_BDF_to_x_font (SDATA (filename), fontname, 100))
@@ -6338,12 +6571,13 @@ in the list.  DIRECTORY may be a list of directories.  */)
       pair[0] = list;
       pair[1] = Qnil;
       GCPRO2 (directory, list);
-      pair[1] = w32_find_bdf_fonts_in_dir( XCAR (directory) );
-      list = Fnconc( 2, pair );
+      pair[1] = w32_find_bdf_fonts_in_dir ( XCAR (directory) );
+      list = Fnconc ( 2, pair );
       UNGCPRO;
     }
   return list;
 }
+#endif /* OLD_FONT */
 
 \f
 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
@@ -6416,7 +6650,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
 DEFUN ("x-display-pixel-width", Fx_display_pixel_width,
        Sx_display_pixel_width, 0, 1, 0,
-       doc: /* Returns the width in pixels of DISPLAY.
+       doc: /* Return the width in pixels of DISPLAY.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6430,7 +6664,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
        Sx_display_pixel_height, 0, 1, 0,
-       doc: /* Returns the height in pixels of DISPLAY.
+       doc: /* Return the height in pixels of DISPLAY.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6444,7 +6678,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
        0, 1, 0,
-       doc: /* Returns the number of bitplanes of DISPLAY.
+       doc: /* Return the number of bitplanes of DISPLAY.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6458,7 +6692,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
        0, 1, 0,
-       doc: /* Returns the number of color cells of DISPLAY.
+       doc: /* Return the number of color cells of DISPLAY.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6478,7 +6712,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
   /* We force 24+ bit depths to 24-bit, both to prevent an overflow
      and because probably is more meaningful on Windows anyway */
   if (cap < 0)
-    cap = 1 << min(dpyinfo->n_planes * dpyinfo->n_cbits, 24);
+    cap = 1 << min (dpyinfo->n_planes * dpyinfo->n_cbits, 24);
 
   ReleaseDC (dpyinfo->root_window, hdc);
 
@@ -6488,7 +6722,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
        Sx_server_max_request_size,
        0, 1, 0,
-       doc: /* Returns the maximum request size of the server of DISPLAY.
+       doc: /* Return the maximum request size of the server of DISPLAY.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6501,7 +6735,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 }
 
 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
-       doc: /* Returns the "vendor ID" string of the W32 system (Microsoft).
+       doc: /* Return the "vendor ID" string of the W32 system (Microsoft).
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6512,10 +6746,10 @@ If omitted or nil, that stands for the selected frame's display.  */)
 }
 
 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
-       doc: /* Returns the version numbers of the server of DISPLAY.
+       doc: /* Return the version numbers of the server of DISPLAY.
 The value is a list of three integers: the major and minor
-version numbers of the X Protocol in use, and the distributor-specific release
-number.  See also the function `x-server-vendor'.
+version numbers of the X Protocol in use, and the distributor-specific
+release number.  See also the function `x-server-vendor'.
 
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
@@ -6529,7 +6763,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 }
 
 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
-       doc: /* Returns the number of screens on the server of DISPLAY.
+       doc: /* Return the number of screens on the server of DISPLAY.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6541,7 +6775,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
 DEFUN ("x-display-mm-height", Fx_display_mm_height,
        Sx_display_mm_height, 0, 1, 0,
-       doc: /* Returns the height in millimeters of DISPLAY.
+       doc: /* Return the height in millimeters of DISPLAY.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6562,7 +6796,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 }
 
 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
-       doc: /* Returns the width in millimeters of DISPLAY.
+       doc: /* Return the width in millimeters of DISPLAY.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6585,7 +6819,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
 DEFUN ("x-display-backing-store", Fx_display_backing_store,
        Sx_display_backing_store, 0, 1, 0,
-       doc: /* Returns an indication of whether DISPLAY does backing store.
+       doc: /* Return an indication of whether DISPLAY does backing store.
 The value may be `always', `when-mapped', or `not-useful'.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
@@ -6598,7 +6832,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
 DEFUN ("x-display-visual-class", Fx_display_visual_class,
        Sx_display_visual_class, 0, 1, 0,
-       doc: /* Returns the visual class of DISPLAY.
+       doc: /* Return the visual class of DISPLAY.
 The value is one of the symbols `static-gray', `gray-scale',
 `static-color', `pseudo-color', `true-color', or `direct-color'.
 
@@ -6625,7 +6859,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 
 DEFUN ("x-display-save-under", Fx_display_save_under,
        Sx_display_save_under, 0, 1, 0,
-       doc: /* Returns t if DISPLAY supports the save-under feature.
+       doc: /* Return t if DISPLAY supports the save-under feature.
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6741,7 +6975,7 @@ terminate Emacs if we can't open the connection.  */)
     Lisp_Object color_file;
     struct gcpro gcpro1;
 
-    color_file = build_string("~/rgb.txt");
+    color_file = build_string ("~/rgb.txt");
 
     GCPRO1 (color_file);
 
@@ -6814,6 +7048,7 @@ If DISPLAY is nil, that stands for the selected frame's display.  */)
     error ("Display still has frames on it");
 
   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)
@@ -6823,6 +7058,7 @@ If DISPLAY is nil, that stands for the selected frame's display.  */)
         xfree (dpyinfo->font_table[i].name);
         w32_unload_font (dpyinfo, dpyinfo->font_table[i].font);
       }
+#endif
   x_destroy_all_bitmaps (dpyinfo);
 
   x_delete_display (dpyinfo);
@@ -6838,7 +7074,7 @@ DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
   Lisp_Object tail, result;
 
   result = Qnil;
-  for (tail = w32_display_name_list; ! NILP (tail); tail = XCDR (tail))
+  for (tail = w32_display_name_list; CONSP (tail); tail = XCDR (tail))
     result = Fcons (XCAR (XCAR (tail)), result);
 
   return result;
@@ -6988,11 +7224,6 @@ value.  */)
                                Busy cursor
  ***********************************************************************/
 
-/* If non-null, an asynchronous timer that, when it expires, displays
-   an hourglass cursor on all frames.  */
-
-static struct atimer *hourglass_atimer;
-
 /* Non-zero means an hourglass cursor is currently shown.  */
 
 static int hourglass_shown_p;
@@ -7006,20 +7237,26 @@ static Lisp_Object Vhourglass_delay;
 
 #define DEFAULT_HOURGLASS_DELAY 1
 
-/* Function prototypes.  */
-
-static void show_hourglass P_ ((struct atimer *));
-static void hide_hourglass P_ ((void));
+/* Return non-zero if houglass timer has been started or hourglass is shown.  */
 
+int
+hourglass_started ()
+{
+  return hourglass_shown_p || hourglass_timer;
+}
 
 /* Cancel a currently active hourglass timer, and start a new one.  */
 
 void
 start_hourglass ()
 {
-#if 0 /* TODO: cursor shape changes.  */
-  EMACS_TIME delay;
-  int secs, usecs = 0;
+  DWORD delay;
+  int secs, msecs = 0;
+  struct frame * f = SELECTED_FRAME ();
+
+  /* No cursors on non GUI frames.  */
+  if (!FRAME_W32_P (f))
+    return;
 
   cancel_hourglass ();
 
@@ -7032,15 +7269,14 @@ start_hourglass ()
       Lisp_Object tem;
       tem = Ftruncate (Vhourglass_delay, Qnil);
       secs = XFASTINT (tem);
-      usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
+      msecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000;
     }
   else
     secs = DEFAULT_HOURGLASS_DELAY;
 
-  EMACS_SET_SECS_USECS (delay, secs, usecs);
-  hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
-                                  show_hourglass, NULL);
-#endif
+  delay = secs * 1000 + msecs;
+  hourglass_hwnd = FRAME_W32_WINDOW (f);
+  hourglass_timer = SetTimer (hourglass_hwnd, HOURGLASS_ID, delay, NULL);
 }
 
 
@@ -7050,10 +7286,10 @@ start_hourglass ()
 void
 cancel_hourglass ()
 {
-  if (hourglass_atimer)
+  if (hourglass_timer)
     {
-      cancel_atimer (hourglass_atimer);
-      hourglass_atimer = NULL;
+      KillTimer (hourglass_hwnd, hourglass_timer);
+      hourglass_timer = 0;
     }
 
   if (hourglass_shown_p)
@@ -7061,62 +7297,22 @@ cancel_hourglass ()
 }
 
 
-/* Timer function of hourglass_atimer.  TIMER is equal to
-   hourglass_atimer.
+/* Timer function of hourglass_timer.
 
-   Display an hourglass cursor on all frames by mapping the frames'
-   hourglass_window.  Set the hourglass_p flag in the frames'
-   output_data.x structure to indicate that an hourglass cursor is
-   shown on the frames.  */
+   Display an hourglass cursor.  Set the hourglass_p flag in display info
+   to indicate that an hourglass cursor is shown.  */
 
 static void
-show_hourglass (timer)
-     struct atimer *timer;
+show_hourglass (f)
+     struct frame *f;
 {
-#if 0  /* TODO: cursor shape changes.  */
-  /* The timer implementation will cancel this timer automatically
-     after this function has run.  Set hourglass_atimer to null
-     so that we know the timer doesn't have to be canceled.  */
-  hourglass_atimer = NULL;
-
   if (!hourglass_shown_p)
     {
-      Lisp_Object rest, frame;
-
-      BLOCK_INPUT;
-
-      FOR_EACH_FRAME (rest, frame)
-       if (FRAME_W32_P (XFRAME (frame)))
-         {
-           struct frame *f = XFRAME (frame);
-
-           f->output_data.w32->hourglass_p = 1;
-
-           if (!f->output_data.w32->hourglass_window)
-             {
-               unsigned long mask = CWCursor;
-               XSetWindowAttributes attrs;
-
-               attrs.cursor = f->output_data.w32->hourglass_cursor;
-
-               f->output_data.w32->hourglass_window
-                 = XCreateWindow (FRAME_X_DISPLAY (f),
-                                  FRAME_OUTER_WINDOW (f),
-                                  0, 0, 32000, 32000, 0, 0,
-                                  InputOnly,
-                                  CopyFromParent,
-                                  mask, &attrs);
-             }
-
-           XMapRaised (FRAME_X_DISPLAY (f),
-                       f->output_data.w32->hourglass_window);
-           XFlush (FRAME_X_DISPLAY (f));
-         }
-
+      f->output_data.w32->hourglass_p = 1;
+      if (!menubar_in_use && !current_popup_menu)
+       SetCursor (f->output_data.w32->hourglass_cursor);
       hourglass_shown_p = 1;
-      UNBLOCK_INPUT;
     }
-#endif
 }
 
 
@@ -7125,33 +7321,15 @@ show_hourglass (timer)
 static void
 hide_hourglass ()
 {
-#if 0 /* TODO: cursor shape changes.  */
   if (hourglass_shown_p)
     {
-      Lisp_Object rest, frame;
-
-      BLOCK_INPUT;
-      FOR_EACH_FRAME (rest, frame)
-       {
-         struct frame *f = XFRAME (frame);
-
-         if (FRAME_W32_P (f)
-             /* Watch out for newly created frames.  */
-             && f->output_data.x->hourglass_window)
-           {
-             XUnmapWindow (FRAME_X_DISPLAY (f),
-                           f->output_data.x->hourglass_window);
-             /* Sync here because XTread_socket looks at the
-                hourglass_p flag that is reset to zero below.  */
-             XSync (FRAME_X_DISPLAY (f), False);
-             f->output_data.x->hourglass_p = 0;
-           }
-       }
+      struct frame *f = x_window_to_frame (&one_w32_display_info,
+                                          hourglass_hwnd);
 
+      f->output_data.w32->hourglass_p = 0;
+      SetCursor (f->output_data.w32->current_cursor);
       hourglass_shown_p = 0;
-      UNBLOCK_INPUT;
     }
-#endif
 }
 
 
@@ -7284,7 +7462,7 @@ x_create_tip_frame (dpyinfo, parms, text)
   f->icon_name = Qnil;
 
 #if 0 /* GLYPH_DEBUG TODO: image support.  */
-  image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
+  image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
   dpyinfo_refcount = dpyinfo->reference_count;
 #endif /* GLYPH_DEBUG */
 #ifdef MULTI_KBOARD
@@ -7308,39 +7486,19 @@ x_create_tip_frame (dpyinfo, parms, text)
       specbind (Qx_resource_name, name);
     }
 
-  /* Extract the window parameters from the supplied values
-     that are needed to determine window geometry.  */
-  {
-    Lisp_Object font;
+  f->resx = dpyinfo->resx;
+  f->resy = dpyinfo->resy;
 
-    font = w32_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
+  /* Perhaps, we must allow frame parameter, say `font-backend',
+     to specify which font backends to use.  */
+  register_font_driver (&w32font_driver, f);
 
-    BLOCK_INPUT;
-    /* First, try whatever font the caller has specified.  */
-    if (STRINGP (font))
-      {
-       tem = Fquery_fontset (font, Qnil);
-       if (STRINGP (tem))
-         font = x_new_fontset (f, SDATA (tem));
-       else
-         font = x_new_font (f, SDATA (font));
-      }
-
-    /* Try out a font which we hope has bold and italic variations.  */
-    if (!STRINGP (font))
-      font = x_new_font (f, "-*-Courier New-normal-r-*-*-*-100-*-*-c-*-iso8859-1");
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1");
-    /* If those didn't work, look for something which will at least work.  */
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1");
-    UNBLOCK_INPUT;
-    if (! STRINGP (font))
-      font = build_string ("Fixedsys");
+  x_default_parameter (f, parms, Qfont_backend, Qnil,
+                      "fontBackend", "FontBackend", RES_TYPE_STRING);
 
-    x_default_parameter (f, parms, Qfont, font,
-                        "font", "Font", RES_TYPE_STRING);
-  }
+  /* Extract the window parameters from the supplied values
+     that are needed to determine window geometry.  */
+  x_default_font_parameter (f, parms);
 
   x_default_parameter (f, parms, Qborder_width, make_number (2),
                       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
@@ -7438,8 +7596,6 @@ x_create_tip_frame (dpyinfo, parms, text)
                                              Qnil));
   }
 
-  Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qw32), Qnil));
-
   f->no_split = 1;
 
   UNGCPRO;
@@ -7479,6 +7635,7 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
      int *root_x, *root_y;
 {
   Lisp_Object left, top;
+  int min_x, min_y, max_x, max_y;
 
   /* User-specified position?  */
   left = Fcdr (Fassq (Qleft, parms));
@@ -7490,40 +7647,68 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
     {
       POINT pt;
 
+      /* Default min and max values.  */
+      min_x = 0;
+      min_y = 0;
+      max_x = FRAME_W32_DISPLAY_INFO (f)->width;
+      max_y = FRAME_W32_DISPLAY_INFO (f)->height;
+
       BLOCK_INPUT;
       GetCursorPos (&pt);
       *root_x = pt.x;
       *root_y = pt.y;
       UNBLOCK_INPUT;
+
+      /* If multiple monitor support is available, constrain the tip onto
+        the current monitor. This improves the above by allowing negative
+        co-ordinates if monitor positions are such that they are valid, and
+        snaps a tooltip onto a single monitor if we are close to the edge
+        where it would otherwise flow onto the other monitor (or into
+        nothingness if there is a gap in the overlap).  */
+      if (monitor_from_point_fn && get_monitor_info_fn)
+       {
+         struct MONITOR_INFO info;
+         HMONITOR monitor
+           = monitor_from_point_fn (pt, MONITOR_DEFAULT_TO_NEAREST);
+         info.cbSize = sizeof (info);
+
+         if (get_monitor_info_fn (monitor, &info))
+           {
+             min_x = info.rcWork.left;
+             min_y = info.rcWork.top;
+             max_x = info.rcWork.right;
+             max_y = info.rcWork.bottom;
+           }
+       }
     }
 
   if (INTEGERP (top))
     *root_y = XINT (top);
-  else if (*root_y + XINT (dy) <= 0)
-    *root_y = 0; /* Can happen for negative dy */
-  else if (*root_y + XINT (dy) + height <= FRAME_W32_DISPLAY_INFO (f)->height)
+  else if (*root_y + XINT (dy) <= min_y)
+    *root_y = min_y; /* Can happen for negative dy */
+  else if (*root_y + XINT (dy) + height <= max_y)
     /* It fits below the pointer */
       *root_y += XINT (dy);
-  else if (height + XINT (dy) <= *root_y)
+  else if (height + XINT (dy) + min_y <= *root_y)
     /* It fits above the pointer.  */
     *root_y -= height + XINT (dy);
   else
     /* Put it on the top.  */
-    *root_y = 0;
+    *root_y = min_y;
 
   if (INTEGERP (left))
     *root_x = XINT (left);
-  else if (*root_x + XINT (dx) <= 0)
+  else if (*root_x + XINT (dx) <= min_x)
     *root_x = 0; /* Can happen for negative dx */
-  else if (*root_x + XINT (dx) + width <= FRAME_W32_DISPLAY_INFO (f)->width)
+  else if (*root_x + XINT (dx) + width <= max_x)
     /* It fits to the right of the pointer.  */
     *root_x += XINT (dx);
-  else if (width + XINT (dx) <= *root_x)
+  else if (width + XINT (dx) + min_x <= *root_x)
     /* It fits to the left of the pointer.  */
     *root_x -= width + XINT (dx);
   else
     /* Put it left justified on the screen -- it ought to fit that way.  */
-    *root_x = 0;
+    *root_x = min_x;
 }
 
 
@@ -7981,7 +8166,7 @@ If ONLY-DIR-P is non-nil, the user can only select directories.  */)
            *last = '\0';
          }
 
-       file = DECODE_FILE(build_string (filename));
+       file = DECODE_FILE (build_string (filename));
       }
     /* User cancelled the dialog without making a selection.  */
     else if (!CommDlgExtendedError ())
@@ -8012,7 +8197,7 @@ If ONLY-DIR-P is non-nil, the user can only select directories.  */)
 
 DEFUN ("w32-select-font", Fw32_select_font, Sw32_select_font, 0, 2, 0,
        doc: /* Select a font for the named FRAME using the W32 font dialog.
-Returns an X-style font string corresponding to the selection.
+Return an X-style font string corresponding to the selection.
 
 If FRAME is omitted or nil, it defaults to the selected frame.
 If INCLUDE-PROPORTIONAL is non-nil, include proportional fonts
@@ -8045,7 +8230,7 @@ in the font selection dialog. */)
   /* Initialize as much of the font details as we can from the current
      default font.  */
   hdc = GetDC (FRAME_W32_WINDOW (f));
-  oldobj = SelectObject (hdc, FRAME_FONT (f)->hfont);
+  oldobj = SelectObject (hdc, FONT_COMPAT (FRAME_FONT (f))->hfont);
   GetTextFace (hdc, LF_FACESIZE, lf.lfFaceName);
   if (GetTextMetrics (hdc, &tm))
     {
@@ -8116,13 +8301,13 @@ DOCUMENT is typically the name of a document file or a URL, but can
 also be a program executable to run, or a directory to open in the
 Windows Explorer.
 
-If DOCUMENT is a program executable, the optional arg PARAMETERS can
-be a string containing command line parameters that will be passed to
-the program; otherwise, PARAMETERS should be nil or unspecified.
+If DOCUMENT is a program executable, the optional third arg PARAMETERS
+can be a string containing command line parameters that will be passed
+to the program; otherwise, PARAMETERS should be nil or unspecified.
 
-Second optional argument SHOW-FLAG can be used to control how the
+Optional fourth argument SHOW-FLAG can be used to control how the
 application will be displayed when it is invoked.  If SHOW-FLAG is nil
-or unspceified, the application is displayed normally, otherwise it is
+or unspecified, the application is displayed normally, otherwise it is
 an integer representing a ShowWindow flag:
 
   0 - start hidden
@@ -8136,9 +8321,12 @@ an integer representing a ShowWindow flag:
 
   CHECK_STRING (document);
 
-  /* Encode filename and current directory.  */
+  /* Encode filename, current directory and parameters.  */
   current_dir = ENCODE_FILE (current_buffer->directory);
   document = ENCODE_FILE (document);
+  if (STRINGP (parameters))
+    parameters = ENCODE_SYSTEM (parameters);
+
   if ((int) ShellExecute (NULL,
                          (STRINGP (operation) ?
                           SDATA (operation) : NULL),
@@ -8162,7 +8350,7 @@ lookup_vk_code (char *key)
   int i;
 
   for (i = 0; i < 256; i++)
-    if (lispy_function_keys[i] != 0
+    if (lispy_function_keys[i]
        && strcmp (lispy_function_keys[i], key) == 0)
       return i;
 
@@ -8259,7 +8447,7 @@ The return value is the hotkey-id if registered, otherwise nil.  */)
 {
   key = w32_parse_hot_key (key);
 
-  if (NILP (Fmemq (key, w32_grabbed_keys)))
+  if (!NILP (key) && NILP (Fmemq (key, w32_grabbed_keys)))
     {
       /* Reuse an empty slot if possible.  */
       Lisp_Object item = Fmemq (Qnil, w32_grabbed_keys);
@@ -8307,7 +8495,6 @@ DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key,
 #else
       if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
                             (WPARAM) XINT (XCAR (item)), (LPARAM) item))
-
 #endif
        {
          MSG msg;
@@ -8323,7 +8510,7 @@ DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys,
        doc: /* Return list of registered hot-key IDs.  */)
   ()
 {
-  return Fcopy_sequence (w32_grabbed_keys);
+  return Fdelq (Qnil, Fcopy_sequence (w32_grabbed_keys));
 }
 
 DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key,
@@ -8341,7 +8528,7 @@ usage: (w32-reconstruct-hot-key ID)  */)
   vk_code = HOTKEY_VK_CODE (hotkeyid);
   w32_modifiers = HOTKEY_MODIFIERS (hotkeyid);
 
-  if (lispy_function_keys[vk_code])
+  if (vk_code < 256 && lispy_function_keys[vk_code])
     key = intern (lispy_function_keys[vk_code]);
   else
     key = make_number (vk_code);
@@ -8419,6 +8606,115 @@ Lisp_Object class, name;
   return Qt;
 }
 
+DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0,
+       doc: /* Get power status information from Windows system.
+
+The following %-sequences are provided:
+%L AC line status (verbose)
+%B Battery status (verbose)
+%b Battery status, empty means high, `-' means low,
+   `!' means critical, and `+' means charging
+%p Battery load percentage
+%s Remaining time (to charge or discharge) in seconds
+%m Remaining time (to charge or discharge) in minutes
+%h Remaining time (to charge or discharge) in hours
+%t Remaining time (to charge or discharge) in the form `h:min'  */)
+  ()
+{
+  Lisp_Object status = Qnil;
+
+  SYSTEM_POWER_STATUS system_status;
+  if (GetSystemPowerStatus (&system_status))
+    {
+      Lisp_Object line_status, battery_status, battery_status_symbol;
+      Lisp_Object load_percentage, seconds, minutes, hours, remain;
+      Lisp_Object sequences[8];
+
+      long seconds_left = (long) system_status.BatteryLifeTime;
+
+      if (system_status.ACLineStatus == 0)
+       line_status = build_string ("off-line");
+      else if (system_status.ACLineStatus == 1)
+       line_status = build_string ("on-line");
+      else
+       line_status = build_string ("N/A");
+
+      if (system_status.BatteryFlag & 128)
+       {
+         battery_status = build_string ("N/A");
+         battery_status_symbol = build_string ("");
+       }
+      else if (system_status.BatteryFlag & 8)
+       {
+         battery_status = build_string ("charging");
+         battery_status_symbol = build_string ("+");
+         if (system_status.BatteryFullLifeTime != -1L)
+           seconds_left = system_status.BatteryFullLifeTime - seconds_left;
+       }
+      else if (system_status.BatteryFlag & 4)
+       {
+         battery_status = build_string ("critical");
+         battery_status_symbol = build_string ("!");
+       }
+      else if (system_status.BatteryFlag & 2)
+       {
+         battery_status = build_string ("low");
+         battery_status_symbol = build_string ("-");
+       }
+      else if (system_status.BatteryFlag & 1)
+       {
+         battery_status = build_string ("high");
+         battery_status_symbol = build_string ("");
+       }
+      else
+       {
+         battery_status = build_string ("medium");
+         battery_status_symbol = build_string ("");
+       }
+
+      if (system_status.BatteryLifePercent > 100)
+       load_percentage = build_string ("N/A");
+      else
+       {
+         char buffer[16];
+         _snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
+         load_percentage = build_string (buffer);
+       }
+
+      if (seconds_left < 0)
+       seconds = minutes = hours = remain = build_string ("N/A");
+      else
+       {
+         long m;
+         float h;
+         char buffer[16];
+         _snprintf (buffer, 16, "%ld", seconds_left);
+         seconds = build_string (buffer);
+
+         m = seconds_left / 60;
+         _snprintf (buffer, 16, "%ld", m);
+         minutes = build_string (buffer);
+
+         h = seconds_left / 3600.0;
+         _snprintf (buffer, 16, "%3.1f", h);
+         hours = build_string (buffer);
+
+         _snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60);
+         remain = build_string (buffer);
+       }
+      sequences[0] = Fcons (make_number ('L'), line_status);
+      sequences[1] = Fcons (make_number ('B'), battery_status);
+      sequences[2] = Fcons (make_number ('b'), battery_status_symbol);
+      sequences[3] = Fcons (make_number ('p'), load_percentage);
+      sequences[4] = Fcons (make_number ('s'), seconds);
+      sequences[5] = Fcons (make_number ('m'), minutes);
+      sequences[6] = Fcons (make_number ('h'), hours);
+      sequences[7] = Fcons (make_number ('t'), remain);
+
+      status = Flist (8, sequences);
+    }
+  return status;
+}
 
 \f
 DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0,
@@ -8486,10 +8782,10 @@ If the underlying system call fails, value is nil.  */)
        LARGE_INTEGER freebytes;
        LARGE_INTEGER totalbytes;
 
-       if (pfn_GetDiskFreeSpaceEx(rootname,
-                                  (ULARGE_INTEGER *)&availbytes,
-                                  (ULARGE_INTEGER *)&totalbytes,
-                                  (ULARGE_INTEGER *)&freebytes))
+       if (pfn_GetDiskFreeSpaceEx (rootname,
+                                   (ULARGE_INTEGER *)&availbytes,
+                                   (ULARGE_INTEGER *)&totalbytes,
+                                   (ULARGE_INTEGER *)&freebytes))
          value = list3 (make_float ((double) totalbytes.QuadPart),
                         make_float ((double) freebytes.QuadPart),
                         make_float ((double) availbytes.QuadPart));
@@ -8501,11 +8797,11 @@ If the underlying system call fails, value is nil.  */)
        DWORD free_clusters;
        DWORD total_clusters;
 
-       if (GetDiskFreeSpace(rootname,
-                            &sectors_per_cluster,
-                            &bytes_per_sector,
-                            &free_clusters,
-                            &total_clusters))
+       if (GetDiskFreeSpace (rootname,
+                             &sectors_per_cluster,
+                             &bytes_per_sector,
+                             &free_clusters,
+                             &total_clusters))
          value = list3 (make_float ((double) total_clusters
                                     * sectors_per_cluster * bytes_per_sector),
                         make_float ((double) free_clusters
@@ -8551,12 +8847,12 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
       ClosePrinter (hPrn);
       return Qnil;
     }
-  /* Call GetPrinter() again with big enouth memory block */
+  /* Call GetPrinter again with big enouth memory block */
   err = GetPrinter (hPrn, 2, (LPBYTE)ppi2, dwNeeded, &dwReturned);
   ClosePrinter (hPrn);
   if (!err)
     {
-      xfree(ppi2);
+      xfree (ppi2);
       return Qnil;
     }
 
@@ -8566,23 +8862,23 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
         {
          /* a remote printer */
          if (*ppi2->pServerName == '\\')
-           _snprintf(pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
-                     ppi2->pShareName);
+           _snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
+                      ppi2->pShareName);
          else
-           _snprintf(pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
-                     ppi2->pShareName);
+           _snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
+                      ppi2->pShareName);
          pname_buf[sizeof (pname_buf) - 1] = '\0';
        }
       else
         {
          /* a local printer */
-         strncpy(pname_buf, ppi2->pPortName, sizeof (pname_buf));
+         strncpy (pname_buf, ppi2->pPortName, sizeof (pname_buf));
          pname_buf[sizeof (pname_buf) - 1] = '\0';
          /* `pPortName' can include several ports, delimited by ','.
           * we only use the first one. */
-         strtok(pname_buf, ",");
+         strtok (pname_buf, ",");
        }
-      xfree(ppi2);
+      xfree (ppi2);
     }
 
   return build_string (pname_buf);
@@ -8626,6 +8922,8 @@ frame_parm_handler w32_frame_parm_handlers[] =
   x_set_fringe_width,
   0, /* x_set_wait_for_wm, */
   x_set_fullscreen,
+  x_set_font_backend,
+  0 /* x_set_alpha, */
 };
 
 void
@@ -8638,29 +8936,17 @@ syms_of_w32fns ()
 
   w32_visible_system_caret_hwnd = NULL;
 
-  Qnone = intern ("none");
-  staticpro (&Qnone);
-  Qsuppress_icon = intern ("suppress-icon");
-  staticpro (&Qsuppress_icon);
-  Qundefined_color = intern ("undefined-color");
-  staticpro (&Qundefined_color);
-  Qcancel_timer = intern ("cancel-timer");
-  staticpro (&Qcancel_timer);
-
-  Qhyper = intern ("hyper");
-  staticpro (&Qhyper);
-  Qsuper = intern ("super");
-  staticpro (&Qsuper);
-  Qmeta = intern ("meta");
-  staticpro (&Qmeta);
-  Qalt = intern ("alt");
-  staticpro (&Qalt);
-  Qctrl = intern ("ctrl");
-  staticpro (&Qctrl);
-  Qcontrol = intern ("control");
-  staticpro (&Qcontrol);
-  Qshift = intern ("shift");
-  staticpro (&Qshift);
+  DEFSYM (Qnone, "none");
+  DEFSYM (Qsuppress_icon, "suppress-icon");
+  DEFSYM (Qundefined_color, "undefined-color");
+  DEFSYM (Qcancel_timer, "cancel-timer");
+  DEFSYM (Qhyper, "hyper");
+  DEFSYM (Qsuper, "super");
+  DEFSYM (Qmeta, "meta");
+  DEFSYM (Qalt, "alt");
+  DEFSYM (Qctrl, "ctrl");
+  DEFSYM (Qcontrol, "control");
+  DEFSYM (Qshift, "shift");
   /* This is the end of symbol initialization.  */
 
   /* Text property `display' should be nonsticky by default.  */
@@ -8817,6 +9103,29 @@ If this variable is non-nil, Emacs will pass them on, allowing the
 system to handle them.  */);
   w32_pass_extra_mouse_buttons_to_system = 0;
 
+  DEFVAR_BOOL ("w32-pass-multimedia-buttons-to-system",
+               &w32_pass_multimedia_buttons_to_system,
+               doc: /* If non-nil, media buttons are passed to Windows.
+Some modern keyboards contain buttons for controlling media players, web
+browsers and other applications.  Generally these buttons are handled on a
+system wide basis, but by setting this to nil they are made available
+to Emacs for binding.  Depending on your keyboard, additional keys that
+may be available are:
+
+browser-back, browser-forward, browser-refresh, browser-stop,
+browser-search, browser-favorites, browser-home,
+mail, mail-reply, mail-forward, mail-send,
+app-1, app-2,
+help, find, new, open, close, save, print, undo, redo, copy, cut, paste,
+spell-check, correction-list, toggle-dictate-command,
+media-next, media-previous, media-stop, media-play-pause, media-select,
+media-play, media-pause, media-record, media-fast-forward, media-rewind,
+media-channel-up, media-channel-down,
+volume-mute, volume-up, volume-down,
+mic-volume-mute, mic-volume-down, mic-volume-up, mic-toggle,
+bass-down, bass-boost, bass-up, treble-down, treble-up  */);
+  w32_pass_multimedia_buttons_to_system = 1;
+
   DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
               doc: /* The shape of the pointer when over text.
 Changing the value does not affect existing frames
@@ -8843,14 +9152,14 @@ Value must be an integer or float.  */);
   Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
 
   DEFVAR_LISP ("x-sensitive-text-pointer-shape",
-             &Vx_sensitive_text_pointer_shape,
+              &Vx_sensitive_text_pointer_shape,
               doc: /* The shape of the pointer when over mouse-sensitive text.
 This variable takes effect when you create a new frame
 or when you set the mouse color.  */);
   Vx_sensitive_text_pointer_shape = Qnil;
 
   DEFVAR_LISP ("x-window-horizontal-drag-cursor",
-             &Vx_window_horizontal_drag_shape,
+              &Vx_window_horizontal_drag_shape,
               doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
 This variable takes effect when you create a new frame
 or when you set the mouse color.  */);
@@ -8927,24 +9236,16 @@ CODEPAGE should be an integer specifying the codepage that should be used
 to display the character set, t to do no translation and output as Unicode,
 or nil to do no translation and output as 8 bit (or multibyte on far-east
 versions of Windows) characters.  */);
-    Vw32_charset_info_alist = Qnil;
-
-  staticpro (&Qw32_charset_ansi);
-  Qw32_charset_ansi = intern ("w32-charset-ansi");
-  staticpro (&Qw32_charset_symbol);
-  Qw32_charset_default = intern ("w32-charset-default");
-  staticpro (&Qw32_charset_default);
-  Qw32_charset_symbol = intern ("w32-charset-symbol");
-  staticpro (&Qw32_charset_shiftjis);
-  Qw32_charset_shiftjis = intern ("w32-charset-shiftjis");
-  staticpro (&Qw32_charset_hangeul);
-  Qw32_charset_hangeul = intern ("w32-charset-hangeul");
-  staticpro (&Qw32_charset_chinesebig5);
-  Qw32_charset_chinesebig5 = intern ("w32-charset-chinesebig5");
-  staticpro (&Qw32_charset_gb2312);
-  Qw32_charset_gb2312 = intern ("w32-charset-gb2312");
-  staticpro (&Qw32_charset_oem);
-  Qw32_charset_oem = intern ("w32-charset-oem");
+  Vw32_charset_info_alist = Qnil;
+
+  DEFSYM (Qw32_charset_ansi, "w32-charset-ansi");
+  DEFSYM (Qw32_charset_symbol, "w32-charset-symbol");
+  DEFSYM (Qw32_charset_default, "w32-charset-default");
+  DEFSYM (Qw32_charset_shiftjis, "w32-charset-shiftjis");
+  DEFSYM (Qw32_charset_hangeul, "w32-charset-hangeul");
+  DEFSYM (Qw32_charset_chinesebig5, "w32-charset-chinesebig5");
+  DEFSYM (Qw32_charset_gb2312, "w32-charset-gb2312");
+  DEFSYM (Qw32_charset_oem, "w32-charset-oem");
 
 #ifdef JOHAB_CHARSET
   {
@@ -8952,28 +9253,17 @@ versions of Windows) characters.  */);
     DEFVAR_BOOL ("w32-extra-charsets-defined", &w32_extra_charsets_defined,
                 doc: /* Internal variable.  */);
 
-    staticpro (&Qw32_charset_johab);
-    Qw32_charset_johab = intern ("w32-charset-johab");
-    staticpro (&Qw32_charset_easteurope);
-    Qw32_charset_easteurope = intern ("w32-charset-easteurope");
-    staticpro (&Qw32_charset_turkish);
-    Qw32_charset_turkish = intern ("w32-charset-turkish");
-    staticpro (&Qw32_charset_baltic);
-    Qw32_charset_baltic = intern ("w32-charset-baltic");
-    staticpro (&Qw32_charset_russian);
-    Qw32_charset_russian = intern ("w32-charset-russian");
-    staticpro (&Qw32_charset_arabic);
-    Qw32_charset_arabic = intern ("w32-charset-arabic");
-    staticpro (&Qw32_charset_greek);
-    Qw32_charset_greek = intern ("w32-charset-greek");
-    staticpro (&Qw32_charset_hebrew);
-    Qw32_charset_hebrew = intern ("w32-charset-hebrew");
-    staticpro (&Qw32_charset_vietnamese);
-    Qw32_charset_vietnamese = intern ("w32-charset-vietnamese");
-    staticpro (&Qw32_charset_thai);
-    Qw32_charset_thai = intern ("w32-charset-thai");
-    staticpro (&Qw32_charset_mac);
-    Qw32_charset_mac = intern ("w32-charset-mac");
+    DEFSYM (Qw32_charset_johab, "w32-charset-johab");
+    DEFSYM (Qw32_charset_easteurope, "w32-charset-easteurope");
+    DEFSYM (Qw32_charset_turkish, "w32-charset-turkish");
+    DEFSYM (Qw32_charset_baltic, "w32-charset-baltic");
+    DEFSYM (Qw32_charset_russian, "w32-charset-russian");
+    DEFSYM (Qw32_charset_arabic, "w32-charset-arabic");
+    DEFSYM (Qw32_charset_greek, "w32-charset-greek");
+    DEFSYM (Qw32_charset_hebrew, "w32-charset-hebrew");
+    DEFSYM (Qw32_charset_vietnamese, "w32-charset-vietnamese");
+    DEFSYM (Qw32_charset_thai, "w32-charset-thai");
+    DEFSYM (Qw32_charset_mac, "w32-charset-mac");
   }
 #endif
 
@@ -8983,9 +9273,7 @@ versions of Windows) characters.  */);
     DEFVAR_BOOL ("w32-unicode-charset-defined",
                  &w32_unicode_charset_defined,
                 doc: /* Internal variable.  */);
-
-    staticpro (&Qw32_charset_unicode);
-    Qw32_charset_unicode = intern ("w32-charset-unicode");
+    DEFSYM (Qw32_charset_unicode, "w32-charset-unicode");
   }
 #endif
 
@@ -9032,11 +9320,15 @@ versions of Windows) characters.  */);
   defsubr (&Sw32_reconstruct_hot_key);
   defsubr (&Sw32_toggle_lock_key);
   defsubr (&Sw32_window_exists_p);
+#if OLD_FONT
   defsubr (&Sw32_find_bdf_fonts);
+#endif
+  defsubr (&Sw32_battery_status);
 
   defsubr (&Sfile_system_info);
   defsubr (&Sdefault_printer_name);
 
+#if OLD_FONT
   /* Setting callback functions for fontset handler.  */
   get_font_info_func = w32_get_font_info;
 
@@ -9049,10 +9341,13 @@ versions of Windows) characters.  */);
   find_ccl_program_func = w32_find_ccl_program;
   query_font_func = w32_query_font;
   set_frame_fontset_func = x_set_font;
+  get_font_repertory_func = x_get_font_repertory;
+#endif
   check_window_system_func = check_w32;
 
 
-  hourglass_atimer = NULL;
+  hourglass_timer = 0;
+  hourglass_hwnd = NULL;
   hourglass_shown_p = 0;
   defsubr (&Sx_show_tip);
   defsubr (&Sx_hide_tip);
@@ -9076,7 +9371,8 @@ versions of Windows) characters.  */);
        variable initialized is 0 and directly from main when initialized
        is non zero.
  */
-void globals_of_w32fns ()
+void
+globals_of_w32fns ()
 {
   HMODULE user32_lib = GetModuleHandle ("user32.dll");
   /*
@@ -9089,6 +9385,18 @@ void globals_of_w32fns ()
   clipboard_sequence_fn = (ClipboardSequence_Proc)
     GetProcAddress (user32_lib, "GetClipboardSequenceNumber");
 
+  monitor_from_point_fn = (MonitorFromPoint_Proc)
+    GetProcAddress (user32_lib, "MonitorFromPoint");
+  get_monitor_info_fn = (GetMonitorInfo_Proc)
+    GetProcAddress (user32_lib, "GetMonitorInfoA");
+
+  {
+    HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
+    get_composition_string_fn = (ImmGetCompositionString_Proc)
+      GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
+    get_ime_context_fn = (ImmGetContext_Proc)
+      GetProcAddress (imm32_lib, "ImmGetContext");
+  }
   DEFVAR_INT ("w32-ansi-code-page",
              &w32_ansi_code_page,
              doc: /* The ANSI code page used by the system.  */);
@@ -9096,14 +9404,14 @@ void globals_of_w32fns ()
 
   /* MessageBox does not work without this when linked to comctl32.dll 6.0.  */
   InitCommonControls ();
+
+  syms_of_w32uniscribe ();
 }
 
 #undef abort
 
-void w32_abort (void) NO_RETURN;
-
 void
-w32_abort()
+w32_abort ()
 {
   int button;
   button = MessageBox (NULL,
@@ -9131,7 +9439,7 @@ w32_abort()
 
 /* For convenience when debugging.  */
 int
-w32_last_error()
+w32_last_error ()
 {
   return GetLastError ();
 }