]> code.delx.au - gnu-emacs/blobdiff - src/w32fns.c
Fix bug #11367 with assertion violation during vertical motion in egg.el.
[gnu-emacs] / src / w32fns.c
index f70f4d6ace5c4629194b4e858f10fd6723dd78f0..510d1e94f166bb83d9e1f6f4dd27966dca23f155 100644 (file)
@@ -1,8 +1,6 @@
 /* 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, 2008, 2009, 2010, 2011
-                 Free Software Foundation, Inc.
+Copyright (C) 1989, 1992-2012  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -62,6 +60,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <dlgs.h>
 #include <imm.h>
 #define FILE_NAME_TEXT_FIELD edt1
+#define FILE_NAME_COMBO_BOX cmb13
+#define FILE_NAME_LIST lst1
 
 #include "font.h"
 #include "w32font.h"
@@ -80,17 +80,11 @@ extern void w32_menu_display_help (HWND, HMENU, UINT, UINT);
 extern void w32_free_menu_strings (HWND);
 extern const char *map_w32_filename (const char *, const char **);
 
-extern int quit_char;
-
-extern const char *const lispy_function_keys[];
-
 /* 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;
 
-#if 0 #endif
-
 #ifndef IDC_HAND
 #define IDC_HAND MAKEINTRESOURCE(32649)
 #endif
@@ -146,8 +140,8 @@ struct MONITOR_INFO
     DWORD   dwFlags;
 };
 
-/* Reportedly, VS 6 does not have this in its headers.  */
-#if defined (_MSC_VER) && _MSC_VER < 1300
+/* Reportedly, MSVC does not have this in its headers.  */
+#ifdef _MSC_VER
 DECLARE_HANDLE(HMONITOR);
 #endif
 
@@ -189,18 +183,10 @@ unsigned int msh_mousewheel = 0;
 #define MENU_FREE_DELAY 1000
 static unsigned menu_free_timer = 0;
 
-extern Lisp_Object Qtooltip;
-
-#ifdef GLYPH_DEBUG
-int image_cache_refcount, dpyinfo_refcount;
+#if GLYPH_DEBUG
+static int image_cache_refcount, dpyinfo_refcount;
 #endif
 
-
-extern HWND w32_system_caret_hwnd;
-
-extern int w32_system_caret_height;
-extern int w32_system_caret_x;
-extern int w32_system_caret_y;
 static HWND w32_visible_system_caret_hwnd;
 
 /* From w32menu.c  */
@@ -649,9 +635,8 @@ colormap_t w32_color_map[] =
   {"LightGreen"                , PALETTERGB (144,238,144)},
 };
 
-DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map,
-       0, 0, 0, doc: /* Return the default color map.  */)
-  (void)
+static Lisp_Object
+w32_default_color_map (void)
 {
   int i;
   colormap_t *pc = w32_color_map;
@@ -672,6 +657,13 @@ DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map,
   return (cmap);
 }
 
+DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map,
+       0, 0, 0, doc: /* Return the default color map.  */)
+  (void)
+{
+  return w32_default_color_map ();
+}
+
 static Lisp_Object
 w32_color_map_lookup (char *colorname)
 {
@@ -697,7 +689,6 @@ w32_color_map_lookup (char *colorname)
       QUIT;
     }
 
-
   UNBLOCK_INPUT;
 
   return ret;
@@ -1509,11 +1500,11 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   BLOCK_INPUT;
 
   result = x_text_icon (f,
-                       (char *) SDATA ((!NILP (f->icon_name)
-                                        ? f->icon_name
-                                        : !NILP (f->title)
-                                        ? f->title
-                                        : f->name)));
+                       SSDATA ((!NILP (f->icon_name)
+                                ? f->icon_name
+                                : !NILP (f->title)
+                                ? f->title
+                                : f->name)));
 
   if (result)
     {
@@ -1541,7 +1532,6 @@ void
 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
 {
   int nlines;
-  int olines = FRAME_MENU_BAR_LINES (f);
 
   /* Right now, menu bars don't work properly in minibuf-only frames;
      most of the commands try to apply themselves to the minibuffer
@@ -1611,7 +1601,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
     }
 
   FRAME_TOOL_BAR_LINES (f) = nlines;
-  change_window_heights (root_window, delta);
+  resize_frame_windows (f, FRAME_LINES (f), 0);
   adjust_glyphs (f);
 
   /* We also have to make sure that the internal border at the top of
@@ -1646,6 +1636,9 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
       if (WINDOWP (f->tool_bar_window))
        clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
     }
+
+  run_window_configuration_change_hook (f);
+
 }
 
 
@@ -2095,7 +2088,7 @@ w32_key_to_modifier (int key)
       key_mapping = Qnil;
     }
 
-  /* NB. This code runs in the input thread, asychronously to the lisp
+  /* NB. This code runs in the input thread, asynchronously to the lisp
      thread, so we must be careful to ensure access to lisp data is
      thread-safe.  The following code is safe because the modifier
      variable values are updated atomically from lisp and symbols are
@@ -2269,7 +2262,7 @@ w32_msg_pump (deferred_msg * msg_buf)
                  some third party shell extensions can cause it to be used in
                  system dialogs, which causes a crash if it is not initialized.
                  This is a known bug in Windows, which was fixed long ago, but
-                 the patch for XP is not publically available until XP SP3,
+                 the patch for XP is not publicly available until XP SP3,
                  and older versions will never be patched.  */
               CoInitialize (NULL);
              w32_createwindow ((struct frame *) msg.wParam);
@@ -2424,7 +2417,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 canceled, so don't abort.  */
     return;
 
   msg_buf->result = result;
@@ -2486,6 +2479,10 @@ signal_user_input (void)
   if (!NILP (Vthrow_on_input))
     {
       Vquit_flag = Vthrow_on_input;
+      /* Doing a QUIT from this thread is a bad idea, since this
+        unwinds the stack of the Lisp thread, and the Windows runtime
+        rightfully barfs.  Disabled.  */
+#if 0
       /* If we're inside a function that wants immediate quits,
         do it now.  */
       if (immediate_quit && NILP (Vinhibit_quit))
@@ -2493,6 +2490,7 @@ signal_user_input (void)
          immediate_quit = 0;
          QUIT;
        }
+#endif
     }
 }
 
@@ -2545,7 +2543,7 @@ post_character_message (HWND hwnd, UINT msg,
            the lisp thread to respond.
 
           Note that we don't want to block the input thread waiting for
-          a reponse from the lisp thread (although that would at least
+          a response from the lisp thread (although that would at least
           solve the deadlock problem above), because we want to be able
           to receive C-g to interrupt the lisp thread.  */
        cancel_all_deferred_msgs ();
@@ -2877,7 +2875,6 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                         base character (ie. translating the base key plus
                         shift modifier).  */
                      int add;
-                     int isdead = 0;
                      KEY_EVENT_RECORD key;
 
                      key.bKeyDown = TRUE;
@@ -2888,7 +2885,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                      key.dwControlKeyState = modifiers;
 
                      add = w32_kbd_patch_key (&key);
-                     /* 0 means an unrecognised keycode, negative means
+                     /* 0 means an unrecognized keycode, negative means
                         dead key.  Ignore both.  */
                      while (--add >= 0)
                        {
@@ -2951,7 +2948,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
       break;
 
     case WM_IME_CHAR:
-      /* If we can't get the IME result as unicode, use default processing,
+      /* 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)
@@ -2965,7 +2962,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
           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);
+          size = get_composition_string_fn (context, GCS_RESULTSTR, NULL, 0);
           buffer = alloca (size);
           size = get_composition_string_fn (context, GCS_RESULTSTR,
                                             buffer, size);
@@ -3286,7 +3283,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
            {
              /* Free memory used by owner-drawn and help-echo strings.  */
              w32_free_menu_strings (hwnd);
-             f->output_data.w32->menubar_active = 0;
+             if (f)
+               f->output_data.w32->menubar_active = 0;
               menubar_in_use = 0;
            }
        }
@@ -3636,10 +3634,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
       if (LOWORD (lParam) == HTCLIENT)
        {
          f = x_window_to_frame (dpyinfo, hwnd);
-         if (f->output_data.w32->hourglass_p && !menubar_in_use
-             && !current_popup_menu)
+         if (f && f->output_data.w32->hourglass_p
+             && !menubar_in_use && !current_popup_menu)
            SetCursor (f->output_data.w32->hourglass_cursor);
-         else
+         else if (f)
            SetCursor (f->output_data.w32->current_cursor);
          return 0;
        }
@@ -3718,7 +3716,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
       if (w32_system_caret_hwnd == NULL)
        {
          /* Use the default caret width, and avoid changing it
-            unneccesarily, as it confuses screen reader software.  */
+            unnecessarily, as it confuses screen reader software.  */
          w32_system_caret_hwnd = hwnd;
          CreateCaret (hwnd, NULL, 0,
                       w32_system_caret_height);
@@ -3756,7 +3754,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
          flags |= TPM_RIGHTBUTTON;
 
        /* Remember we did a SetCapture on the initial mouse down event,
-          so for safety, we make sure the capture is cancelled now.  */
+          so for safety, we make sure the capture is canceled now.  */
        ReleaseCapture ();
        button_state = 0;
 
@@ -3879,7 +3877,7 @@ w32_window (struct frame *f, long window_prompting, int minibuffer_only)
      Elsewhere we specify the window name for the window manager.  */
 
   {
-    char *str = (char *) SDATA (Vx_resource_name);
+    char *str = SSDATA (Vx_resource_name);
     f->namebuf = (char *) xmalloc (strlen (str) + 1);
     strcpy (f->namebuf, str);
   }
@@ -3945,9 +3943,9 @@ x_icon (struct frame *f, Lisp_Object parms)
         ? IconicState
         : NormalState));
 
-  x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
-                                    ? f->icon_name
-                                    : f->name)));
+  x_text_icon (f, SSDATA ((!NILP (f->icon_name)
+                          ? f->icon_name
+                          : f->name)));
 #endif
 
   UNBLOCK_INPUT;
@@ -3984,7 +3982,7 @@ x_make_gc (struct frame *f)
 
 
 /* Handler for signals raised during x_create_frame and
-   x_create_top_frame.  FRAME is the frame which is partially
+   x_create_tip_frame.  FRAME is the frame which is partially
    constructed.  */
 
 static Lisp_Object
@@ -3993,13 +3991,14 @@ unwind_create_frame (Lisp_Object frame)
   struct frame *f = XFRAME (frame);
 
   /* If frame is ``official'', nothing to do.  */
-  if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
+  if (NILP (Fmemq (frame, Vframe_list)))
     {
-#ifdef GLYPH_DEBUG
+#if GLYPH_DEBUG
       struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
 #endif
 
       x_free_frame_resources (f);
+      free_glyphs (f);
 
 #if GLYPH_DEBUG
       /* Check that reference counts are indeed correct.  */
@@ -4141,7 +4140,6 @@ This function is an internal primitive--use `make-frame' instead.  */)
   FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
 
   f->terminal = dpyinfo->terminal;
-  f->terminal->reference_count++;
 
   f->output_method = output_w32;
   f->output_data.w32 =
@@ -4160,7 +4158,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
   /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe.  */
   record_unwind_protect (unwind_create_frame, frame);
 #if GLYPH_DEBUG
-  image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
+  image_cache_refcount =
+    FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
   dpyinfo_refcount = dpyinfo->reference_count;
 #endif /* GLYPH_DEBUG */
 
@@ -4293,6 +4292,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
   x_make_gc (f);
 
   /* Now consider the frame official.  */
+  f->terminal->reference_count++;
   FRAME_W32_DISPLAY_INFO (f)->reference_count++;
   Vframe_list = Fcons (frame, Vframe_list);
 
@@ -4352,9 +4352,9 @@ This function is an internal primitive--use `make-frame' instead.  */)
   /* Initialize `default-minibuffer-frame' in case this is the first
      frame on this terminal.  */
   if (FRAME_HAS_MINIBUF_P (f)
-      && (!FRAMEP (kb->Vdefault_minibuffer_frame)
-          || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
-    kb->Vdefault_minibuffer_frame = frame;
+      && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
+          || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
+    KVAR (kb, Vdefault_minibuffer_frame) = frame;
 
   /* All remaining specified parameters, which have not been "used"
      by x_get_arg and friends, now go in the misc. alist of the frame.  */
@@ -4536,8 +4536,6 @@ DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
   (Lisp_Object display)
 {
-  struct w32_display_info *dpyinfo = check_x_display_info (display);
-
   return make_number (1);
 }
 
@@ -4725,7 +4723,7 @@ x_display_info_for_name (Lisp_Object name)
   validate_x_resource_name ();
 
   dpyinfo = w32_term_init (name, (unsigned char *)0,
-                            (char *) SDATA (Vx_resource_name));
+                          SSDATA (Vx_resource_name));
 
   if (dpyinfo == 0)
     error ("Cannot connect to server %s", SDATA (name));
@@ -4782,13 +4780,13 @@ terminate Emacs if we can't open the connection.
     UNGCPRO;
   }
   if (NILP (Vw32_color_map))
-    Vw32_color_map = Fw32_default_color_map ();
+    Vw32_color_map = w32_default_color_map ();
 
   /* Merge in system logical colors.  */
   add_system_logical_colors_to_map (&Vw32_color_map);
 
   if (! NILP (xrm_string))
-    xrm_option = (unsigned char *) SDATA (xrm_string);
+    xrm_option = SDATA (xrm_string);
   else
     xrm_option = (unsigned char *) 0;
 
@@ -4809,7 +4807,7 @@ terminate Emacs if we can't open the connection.
   /* This is what opens the connection and sets x_current_display.
      This also initializes many symbols, such as those used for input.  */
   dpyinfo = w32_term_init (display, xrm_option,
-                            (char *) SDATA (Vx_resource_name));
+                          SSDATA (Vx_resource_name));
 
   if (dpyinfo == 0)
     {
@@ -4834,7 +4832,6 @@ If DISPLAY is nil, that stands for the selected frame's display.  */)
   (Lisp_Object display)
 {
   struct w32_display_info *dpyinfo = check_x_display_info (display);
-  int i;
 
   if (dpyinfo->reference_count > 0)
     error ("Display still has frames on it");
@@ -4884,6 +4881,8 @@ If TERMINAL is omitted or nil, that stands for the selected frame's display.  */
                            Window properties
  ***********************************************************************/
 
+#if 0 /* TODO : port window properties to W32 */
+
 DEFUN ("x-change-window-property", Fx_change_window_property,
        Sx_change_window_property, 2, 6, 0,
        doc: /* Change window property PROP to VALUE on the X window of FRAME.
@@ -4903,7 +4902,6 @@ If OUTER_P is non-nil, the property is changed for the outer X window of
 FRAME.  Default is to change on the edit X window.  */)
   (Lisp_Object prop, Lisp_Object value, Lisp_Object frame, Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
 {
-#if 0 /* TODO : port window properties to W32 */
   struct frame *f = check_x_frame (frame);
   Atom prop_atom;
 
@@ -4920,8 +4918,6 @@ FRAME.  Default is to change on the edit X window.  */)
   XFlush (FRAME_W32_DISPLAY (f));
   UNBLOCK_INPUT;
 
-#endif /* TODO */
-
   return value;
 }
 
@@ -4932,8 +4928,6 @@ DEFUN ("x-delete-window-property", Fx_delete_window_property,
 FRAME nil or omitted means use the selected frame.  Value is PROP.  */)
   (Lisp_Object prop, Lisp_Object frame)
 {
-#if 0 /* TODO : port window properties to W32 */
-
   struct frame *f = check_x_frame (frame);
   Atom prop_atom;
 
@@ -4945,7 +4939,6 @@ FRAME nil or omitted means use the selected frame.  Value is PROP.  */)
   /* Make sure the property is removed when we return.  */
   XFlush (FRAME_W32_DISPLAY (f));
   UNBLOCK_INPUT;
-#endif  /* TODO */
 
   return prop;
 }
@@ -4963,15 +4956,13 @@ If TYPE is nil or omitted, get the property as a string.
 Otherwise TYPE is the name of the atom that denotes the type expected.
 If SOURCE is non-nil, get the property on that window instead of from
 FRAME.  The number 0 denotes the root window.
-If DELETE_P is non-nil, delete the property after retreiving it.
+If DELETE_P is non-nil, delete the property after retrieving it.
 If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
 
 Value is nil if FRAME hasn't a property with name PROP or if PROP has
 no value of TYPE (always string in the MS Windows case).  */)
   (Lisp_Object prop, Lisp_Object frame)
 {
-#if 0 /* TODO : port window properties to W32 */
-
   struct frame *f = check_x_frame (frame);
   Atom prop_atom;
   int rc;
@@ -5011,10 +5002,10 @@ no value of TYPE (always string in the MS Windows case).  */)
 
   return prop_value;
 
-#endif /* TODO */
   return Qnil;
 }
 
+#endif /* TODO */
 
 \f
 /***********************************************************************
@@ -5025,7 +5016,8 @@ no value of TYPE (always string in the MS Windows case).  */)
    cursor.  Duplicated from xdisp.c, but cannot use the version there
    due to lack of atimers on w32.  */
 #define DEFAULT_HOURGLASS_DELAY 1
-/* Return non-zero if houglass timer has been started or hourglass is shown.  */
+/* Return non-zero if hourglass timer has been started or hourglass is
+   shown.  */
 /* PENDING: if W32 can use atimers (atimer.[hc]) then the common impl in
            xdisp.c could be used. */
 
@@ -5187,7 +5179,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
                    Lisp_Object parms, Lisp_Object text)
 {
   struct frame *f;
-  Lisp_Object frame, tem;
+  Lisp_Object frame;
   Lisp_Object name;
   long window_prompting = 0;
   int width, height;
@@ -5229,7 +5221,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
   Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
   old_buffer = current_buffer;
   set_buffer_internal_1 (XBUFFER (buffer));
-  current_buffer->truncate_lines = Qnil;
+  BVAR (current_buffer, truncate_lines) = Qnil;
   specbind (Qinhibit_read_only, Qt);
   specbind (Qinhibit_modification_hooks, Qt);
   Ferase_buffer ();
@@ -5244,7 +5236,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
      from this point on, x_destroy_window might screw up reference
      counts etc.  */
   f->terminal = dpyinfo->terminal;
-  f->terminal->reference_count++;
   f->output_method = output_w32;
   f->output_data.w32 =
     (struct w32_output *) xmalloc (sizeof (struct w32_output));
@@ -5254,7 +5245,8 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
   f->icon_name = Qnil;
 
 #if GLYPH_DEBUG
-  image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
+  image_cache_refcount =
+    FRAME_IMAGE_CACHE ? FRAME_IMAGE_CACHE (f)->refcount : 0;
   dpyinfo_refcount = dpyinfo->reference_count;
 #endif /* GLYPH_DEBUG */
   FRAME_KBOARD (f) = kb;
@@ -5395,15 +5387,16 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
 
   UNGCPRO;
 
+  /* Now that the frame is official, it counts as a reference to
+     its display.  */
+  FRAME_W32_DISPLAY_INFO (f)->reference_count++;
+  f->terminal->reference_count++;
+
   /* It is now ok to make the frame official even if we get an error
      below.  And the frame needs to be on Vframe_list or making it
      visible won't work.  */
   Vframe_list = Fcons (frame, Vframe_list);
 
-  /* Now that the frame is official, it counts as a reference to
-     its display.  */
-  FRAME_W32_DISPLAY_INFO (f)->reference_count++;
-
   /* Setting attributes of faces of the tooltip frame from resources
      and similar will increment face_change_count, which leads to the
      clearing of all current matrices.  Since this isn't necessary
@@ -5659,7 +5652,7 @@ Text larger than the specified size is clipped.  */)
   /* Display the tooltip text in a temporary buffer.  */
   old_buffer = current_buffer;
   set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
-  current_buffer->truncate_lines = Qnil;
+  BVAR (current_buffer, truncate_lines) = Qnil;
   clear_glyph_matrix (w->desired_matrix);
   clear_glyph_matrix (w->current_matrix);
   SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
@@ -5847,13 +5840,10 @@ Value is t if tooltip was open, nil otherwise.  */)
   UNGCPRO;
   return unbind_to (count, deleted);
 }
-
-
 \f
 /***********************************************************************
                        File selection dialog
  ***********************************************************************/
-extern Lisp_Object Qfile_name_history;
 
 /* Callback for altering the behavior of the Open File dialog.
    Makes the Filename text field contain "Current Directory" and be
@@ -5872,13 +5862,37 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
        {
          HWND dialog = GetParent (hwnd);
          HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD);
+         HWND list = GetDlgItem (dialog, FILE_NAME_LIST);
 
-         /* Directories is in index 2.  */
+         /* At least on Windows 7, the above attempt to get the window handle
+            to the File Name Text Field fails.  The following code does the
+            job though.  Note that this code is based on my examination of the
+            window hierarchy using Microsoft Spy++.  bk */
+         if (edit_control == NULL)
+           {
+             HWND tmp = GetDlgItem (dialog, FILE_NAME_COMBO_BOX);
+             if (tmp)
+               {
+                 tmp = GetWindow (tmp, GW_CHILD);
+                 if (tmp)
+                   edit_control = GetWindow (tmp, GW_CHILD);
+               }
+           }
+
+         /* Directories is in index 2.  */
          if (notify->lpOFN->nFilterIndex == 2)
            {
              CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
                                               "Current Directory");
              EnableWindow (edit_control, FALSE);
+             /* Note that at least on Windows 7, the above call to EnableWindow
+                disables the window that would ordinarily have focus.  If we
+                do not set focus to some other window here, focus will land in
+                no man's land and the user will be unable to tab through the
+                dialog box (pressing tab will only result in a beep).
+                Avoid that problem by setting focus to the list here.  */
+             if (notify->hdr.code == CDN_INITDONE)
+               SetFocus (list);
            }
          else
            {
@@ -5955,6 +5969,13 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
   else
     filename[0] = '\0';
 
+  /* The code in file_dialog_callback that attempts to set the text
+     of the file name edit window when handling the CDN_INITDONE
+     WM_NOTIFY message does not work.  Setting filename to "Current
+     Directory" in the only_dir_p case here does work however.  */
+  if (filename[0] == 0 && ! NILP (only_dir_p))
+    strcpy (filename, "Current Directory");
+
   {
     NEWOPENFILENAME new_file_details;
     BOOL file_opened = FALSE;
@@ -6016,7 +6037,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.  */)
 
        file = DECODE_FILE (build_string (filename));
       }
-    /* User cancelled the dialog without making a selection.  */
+    /* User canceled the dialog without making a selection.  */
     else if (!CommDlgExtendedError ())
       file = Qnil;
     /* An error occurred, fallback on reading from the mini-buffer.  */
@@ -6166,7 +6187,7 @@ an integer representing a ShowWindow flag:
   CHECK_STRING (document);
 
   /* Encode filename, current directory and parameters.  */
-  current_dir = ENCODE_FILE (current_buffer->directory);
+  current_dir = ENCODE_FILE (BVAR (current_buffer, directory));
   document = ENCODE_FILE (document);
   if (STRINGP (parameters))
     parameters = ENCODE_SYSTEM (parameters);
@@ -6190,7 +6211,7 @@ an integer representing a ShowWindow flag:
        code_convert_string_norecord (make_unibyte_string (errstr,
                                                           strlen (errstr)),
                                      Vlocale_coding_system, 0);
-      errstr = (char *)SDATA (decoded);
+      errstr = SSDATA (decoded);
     }
   error ("ShellExecute failed: %s", errstr);
 }
@@ -6694,7 +6715,7 @@ 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 enough memory block.  */
   err = GetPrinter (hPrn, 2, (LPBYTE)ppi2, dwNeeded, &dwReturned);
   ClosePrinter (hPrn);
   if (!err)
@@ -6799,10 +6820,6 @@ syms_of_w32fns (void)
   DEFSYM (Qfont_param, "font-parameter");
   /* This is the end of symbol initialization.  */
 
-  /* Text property `display' should be nonsticky by default.  */
-  Vtext_property_default_nonsticky
-    = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
-
 
   Fput (Qundefined_color, Qerror_conditions,
        pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
@@ -7205,4 +7222,3 @@ w32_last_error (void)
 {
   return GetLastError ();
 }
-