/* 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.
#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"
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
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
#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 */
{"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;
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)
{
QUIT;
}
-
UNBLOCK_INPUT;
return ret;
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)
{
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
}
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
if (WINDOWP (f->tool_bar_window))
clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
}
+
+ run_window_configuration_change_hook (f);
+
}
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
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);
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;
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))
immediate_quit = 0;
QUIT;
}
+#endif
}
}
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 ();
base character (ie. translating the base key plus
shift modifier). */
int add;
- int isdead = 0;
KEY_EVENT_RECORD key;
key.bKeyDown = TRUE;
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)
{
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)
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);
{
/* 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;
}
}
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;
}
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);
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;
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);
}
? 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;
/* 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
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. */
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 =
/* 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 */
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);
/* 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. */
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);
}
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));
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;
/* 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)
{
(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");
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.
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;
XFlush (FRAME_W32_DISPLAY (f));
UNBLOCK_INPUT;
-#endif /* TODO */
-
return value;
}
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;
/* Make sure the property is removed when we return. */
XFlush (FRAME_W32_DISPLAY (f));
UNBLOCK_INPUT;
-#endif /* TODO */
return prop;
}
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;
return prop_value;
-#endif /* TODO */
return Qnil;
}
+#endif /* TODO */
\f
/***********************************************************************
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. */
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;
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 ();
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));
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;
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
/* 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);
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
{
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
{
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;
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. */
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);
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);
}
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)
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)));
{
return GetLastError ();
}
-