X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/cce7d53002e8abc346b67ea4100507b0e7c4d68e..2fa85638a036673b63055a86c6bd5b7b789a9d9d:/src/w32fns.c
diff --git a/src/w32fns.c b/src/w32fns.c
index ec48397657..510d1e94f1 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1,6 +1,6 @@
/* Graphical user interface functions for the Microsoft W32 API.
-Copyright (C) 1989, 1992-2011 Free Software Foundation, Inc.
+Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -60,6 +60,8 @@ along with GNU Emacs. If not, see . */
#include
#include
#define FILE_NAME_TEXT_FIELD edt1
+#define FILE_NAME_COMBO_BOX cmb13
+#define FILE_NAME_LIST lst1
#include "font.h"
#include "w32font.h"
@@ -78,10 +80,6 @@ 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;
@@ -142,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
@@ -185,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 */
@@ -645,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;
@@ -668,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)
{
@@ -693,7 +689,6 @@ w32_color_map_lookup (char *colorname)
QUIT;
}
-
UNBLOCK_INPUT;
return ret;
@@ -1537,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
@@ -1607,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
@@ -1642,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);
+
}
@@ -2091,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
@@ -2265,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);
@@ -2420,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;
@@ -2482,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))
@@ -2489,6 +2490,7 @@ signal_user_input (void)
immediate_quit = 0;
QUIT;
}
+#endif
}
}
@@ -2541,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 ();
@@ -2873,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;
@@ -2884,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)
{
@@ -2947,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)
@@ -2961,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);
@@ -3282,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;
}
}
@@ -3632,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;
}
@@ -3714,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);
@@ -3752,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;
@@ -3980,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
@@ -3989,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. */
@@ -4137,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 =
@@ -4156,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 */
@@ -4289,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);
@@ -4532,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);
}
@@ -4778,7 +4780,7 @@ 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);
@@ -4830,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");
@@ -4880,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.
@@ -4899,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;
@@ -4916,8 +4918,6 @@ FRAME. Default is to change on the edit X window. */)
XFlush (FRAME_W32_DISPLAY (f));
UNBLOCK_INPUT;
-#endif /* TODO */
-
return value;
}
@@ -4928,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;
@@ -4941,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;
}
@@ -4959,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;
@@ -5007,10 +5002,10 @@ no value of TYPE (always string in the MS Windows case). */)
return prop_value;
-#endif /* TODO */
return Qnil;
}
+#endif /* TODO */
/***********************************************************************
@@ -5021,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. */
@@ -5183,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;
@@ -5240,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));
@@ -5250,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;
@@ -5391,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
@@ -5843,13 +5840,10 @@ Value is t if tooltip was open, nil otherwise. */)
UNGCPRO;
return unbind_to (count, deleted);
}
-
-
/***********************************************************************
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
@@ -5868,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
{
@@ -5951,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;
@@ -6012,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. */
@@ -6690,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)
@@ -6795,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)));