Throughout the file, delete all USE_FONT_BACKEND
[bpt/emacs.git] / src / w32fns.c
index 808376b..980ebf4 100644 (file)
@@ -1,6 +1,7 @@
 /* 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.
 
@@ -58,11 +59,11 @@ Boston, MA 02110-1301, USA.  */
 #include <objbase.h>
 
 #include <dlgs.h>
+#include <imm.h>
 #define FILE_NAME_TEXT_FIELD edt1
 
-#ifdef USE_FONT_BACKEND
 #include "font.h"
-#endif
+#include "w32font.h"
 
 void syms_of_w32fns ();
 void globals_of_w32fns ();
@@ -72,20 +73,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;
 
@@ -148,10 +143,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.  */
-int w32_pass_multimedia_buttons_to_system;
+static int w32_pass_multimedia_buttons_to_system;
 
 /* Non nil if no window manager is in use.  */
 Lisp_Object Vx_no_window_manager;
@@ -160,6 +155,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.  */
 
@@ -190,14 +190,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
@@ -267,13 +267,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;
 
@@ -281,6 +310,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
@@ -312,6 +342,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
@@ -400,8 +439,6 @@ x_window_to_frame (dpyinfo, wdesc)
       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;
@@ -467,8 +504,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)
@@ -483,7 +520,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;
 
@@ -508,7 +545,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
@@ -826,7 +863,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;
 {
@@ -943,7 +980,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;
@@ -961,11 +998,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;
@@ -995,7 +1032,7 @@ x_to_w32_color (colorname)
            }
        }
     }
-  else if (strnicmp(colorname, "rgb:", 4) == 0)
+  else if (strnicmp (colorname, "rgb:", 4) == 0)
     {
       char *color;
       UINT colorval;
@@ -1012,9 +1049,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)
@@ -1050,7 +1087,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;
@@ -1066,7 +1103,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)
@@ -1564,7 +1601,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;
@@ -1916,7 +1952,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;
     }
 }
@@ -1968,7 +2004,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;
     }
 }
@@ -2015,7 +2051,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)
@@ -2029,7 +2065,7 @@ w32_load_cursor (LPCTSTR name)
 
 extern LRESULT CALLBACK w32_wnd_proc ();
 
-BOOL
+static BOOL
 w32_init_class (hinst)
      HINSTANCE hinst;
 {
@@ -2049,24 +2085,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;
 {
@@ -2136,7 +2172,7 @@ w32_createwindow (f)
     }
 }
 
-void
+static void
 my_post_msg (wmsg, hwnd, msg, wParam, lParam)
      W32Msg * wmsg;
      HWND hwnd;
@@ -2368,7 +2404,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) |
@@ -2439,12 +2475,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)
@@ -2590,8 +2626,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
@@ -2670,7 +2710,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;
@@ -2680,7 +2720,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;
@@ -2718,7 +2758,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);
 
@@ -2758,7 +2798,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. */
@@ -2913,7 +2953,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;
       }
@@ -2970,7 +3010,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;
@@ -3092,7 +3132,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 ();
 
@@ -3143,7 +3183,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);
                        }
@@ -3162,7 +3203,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;
@@ -3176,6 +3216,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:
@@ -3441,6 +3539,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:
@@ -3506,6 +3610,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:
@@ -3707,7 +3816,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 ();
@@ -3774,15 +3883,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;
       }
 
@@ -4148,7 +4269,6 @@ unwind_create_frame (frame)
   return Qnil;
 }
 
-#ifdef USE_FONT_BACKEND
 static void
 x_default_font_parameter (f, parms)
      struct frame *f;
@@ -4179,12 +4299,11 @@ x_default_font_parameter (f, parms)
     }
   x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
 }
-#endif
 
 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,
@@ -4210,6 +4329,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;
@@ -4318,56 +4441,15 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->resx = dpyinfo->resx;
   f->resy = dpyinfo->resy;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      /* Perhaps, we must allow frame parameter, say `font-backend',
-        to specify which font backends to use.  */
-      register_font_driver (&w32font_driver, f);
-
-      x_default_parameter (f, parameters, Qfont_backend, Qnil,
-                          "fontBackend", "FontBackend", RES_TYPE_STRING);
-    }
-#endif /* USE_FONT_BACKEND */
+  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.  */
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    x_default_font_parameter (f, parameters);
-  else
-#endif 
-  {
-    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, 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, parameters, Qfont, font,
-                        "font", "Font", RES_TYPE_STRING);
-  }
-
+  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
@@ -4440,6 +4522,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);
@@ -4553,12 +4637,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;
 
@@ -4566,7 +4653,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;
@@ -4580,7 +4667,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;
@@ -4683,7 +4770,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;
@@ -4820,10 +4907,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;
@@ -4841,7 +4928,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
@@ -4859,7 +4946,7 @@ int size;
   if (retval)
     return retval;
 
-  return w32_load_system_font(f, fontname, size);
+  return w32_load_system_font (f, fontname, size);
 }
 
 
@@ -4873,10 +4960,11 @@ w32_unload_font (dpyinfo, font)
       if (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 */
 
@@ -4907,16 +4995,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 (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;
   else
     return FW_DONTCARE;
 }
@@ -4966,12 +5054,12 @@ x_to_w32_charset (lpcs)
      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 (stricmp (charset, "iso8859-1") == 0)
         return ANSI_CHARSET;
       else
         return DEFAULT_CHARSET;
@@ -5054,7 +5142,7 @@ w32_to_x_charset (fncharset, matching)
     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;
@@ -5248,7 +5336,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;
@@ -5375,6 +5463,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.  */
@@ -5430,7 +5520,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)
@@ -5687,7 +5777,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
@@ -5716,6 +5806,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
@@ -5886,7 +5978,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
@@ -5998,6 +6090,12 @@ enum_font_cb2 (lplf, lptm, FontType, lpef)
            && lpef->logfont.lfCharSet == DEFAULT_CHARSET
            && 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)
@@ -6014,6 +6112,12 @@ 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);
 
@@ -6122,7 +6226,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;
@@ -6193,7 +6298,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.
@@ -6304,7 +6409,7 @@ w32_list_fonts (f, pattern, size, maxnames)
                 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));
@@ -6353,7 +6458,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;
@@ -6380,7 +6485,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 (stricmp (pfi->name, fontname) == 0) return pfi;
     }
 
   return NULL;
@@ -6416,10 +6521,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
@@ -6428,13 +6537,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))
@@ -6464,12 +6573,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,
@@ -6542,7 +6652,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.  */)
@@ -6556,7 +6666,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.  */)
@@ -6570,7 +6680,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.  */)
@@ -6584,7 +6694,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.  */)
@@ -6604,7 +6714,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);
 
@@ -6614,7 +6724,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.  */)
@@ -6627,7 +6737,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.  */)
@@ -6638,10 +6748,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).
@@ -6655,7 +6765,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.  */)
@@ -6667,7 +6777,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.  */)
@@ -6688,7 +6798,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.  */)
@@ -6711,7 +6821,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).
@@ -6724,7 +6834,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'.
 
@@ -6751,7 +6861,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.  */)
@@ -6867,7 +6977,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);
 
@@ -6940,6 +7050,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)
@@ -6949,6 +7060,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);
@@ -7114,11 +7226,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;
@@ -7132,20 +7239,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 ();
 
@@ -7158,15 +7271,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);
 }
 
 
@@ -7176,10 +7288,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)
@@ -7187,62 +7299,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
 }
 
 
@@ -7251,33 +7323,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
 }
 
 
@@ -7410,7 +7464,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
@@ -7437,56 +7491,16 @@ x_create_tip_frame (dpyinfo, parms, text)
   f->resx = dpyinfo->resx;
   f->resy = dpyinfo->resy;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      /* Perhaps, we must allow frame parameter, say `font-backend',
-        to specify which font backends to use.  */
-      register_font_driver (&w32font_driver, f);
+  /* Perhaps, we must allow frame parameter, say `font-backend',
+     to specify which font backends to use.  */
+  register_font_driver (&w32font_driver, f);
 
-      x_default_parameter (f, parms, Qfont_backend, Qnil,
-                          "fontBackend", "FontBackend", RES_TYPE_STRING);
-    }
-#endif /* USE_FONT_BACKEND */
+  x_default_parameter (f, parms, Qfont_backend, Qnil,
+                      "fontBackend", "FontBackend", RES_TYPE_STRING);
 
   /* Extract the window parameters from the supplied values
      that are needed to determine window geometry.  */
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    x_default_font_parameter (f, parms);
-  else
-#endif /* USE_FONT_BACKEND */
-  {
-    Lisp_Object font;
-
-    font = w32_get_arg (parms, 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, 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, font,
-                        "font", "Font", RES_TYPE_STRING);
-  }
+  x_default_font_parameter (f, parms);
 
   x_default_parameter (f, parms, Qborder_width, make_number (2),
                       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
@@ -7623,6 +7637,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));
@@ -7634,40 +7649,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;
 }
 
 
@@ -8125,7 +8168,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 ())
@@ -8156,7 +8199,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
@@ -8189,7 +8232,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))
     {
@@ -8260,13 +8303,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
@@ -8280,9 +8323,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),
@@ -8306,7 +8352,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;
 
@@ -8403,7 +8449,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);
@@ -8451,7 +8497,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;
@@ -8467,7 +8512,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,
@@ -8485,7 +8530,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);
@@ -8563,6 +8608,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,
@@ -8630,10 +8784,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));
@@ -8645,11 +8799,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
@@ -8695,12 +8849,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;
     }
 
@@ -8710,23 +8864,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);
@@ -8770,9 +8924,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
   x_set_fringe_width,
   0, /* x_set_wait_for_wm, */
   x_set_fullscreen,
-#ifdef USE_FONT_BACKEND
   x_set_font_backend
-#endif
 };
 
 void
@@ -8956,7 +9108,7 @@ system to handle them.  */);
                &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
+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:
@@ -8972,8 +9124,7 @@ 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
-  */);
+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,
@@ -9002,14 +9153,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.  */);
@@ -9170,11 +9321,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;
 
@@ -9188,10 +9343,12 @@ versions of Windows) characters.  */);
   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);
@@ -9215,7 +9372,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");
   /*
@@ -9228,6 +9386,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.  */);
@@ -9235,12 +9405,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()
+w32_abort ()
 {
   int button;
   button = MessageBox (NULL,
@@ -9268,7 +9440,7 @@ w32_abort()
 
 /* For convenience when debugging.  */
 int
-w32_last_error()
+w32_last_error ()
 {
   return GetLastError ();
 }