/* 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
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <limits.h>
#include <errno.h>
#include <math.h>
+#include <setjmp.h>
#include "lisp.h"
#include "w32term.h"
#include "systime.h"
#include "termhooks.h"
#include "w32heap.h"
+#include "w32.h"
#include "bitmaps/gray.xbm"
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 HWND (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context);
+typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
+ IN COMPOSITIONFORM *form);
typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
typedef BOOL (WINAPI * GetMonitorInfo_Proc)
(IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
ClipboardSequence_Proc clipboard_sequence_fn = NULL;
ImmGetCompositionString_Proc get_composition_string_fn = NULL;
ImmGetContext_Proc get_ime_context_fn = NULL;
+ImmReleaseContext_Proc release_ime_context_fn = NULL;
+ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
MonitorFromPoint_Proc monitor_from_point_fn = NULL;
GetMonitorInfo_Proc get_monitor_info_fn = NULL;
EndPaint (hwnd, &paintStruct);
leave_crit ();
- my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+ /* Change the message type to prevent Windows from
+ combining WM_PAINT messages in the Lisp thread's queue,
+ since Windows assumes that each message queue is
+ dedicated to one frame and does not bother checking
+ that hwnd matches before combining them. */
+ my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam);
return 0;
}
buffer = alloca(size);
size = get_composition_string_fn (context, GCS_RESULTSTR,
buffer, size);
+ release_ime_context_fn (hwnd, context);
+
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;
+ /* Ignore the messages for the rest of the
+ characters in the string that was output above. */
+ ignore_ime_char = (size / sizeof (wchar_t)) - 1;
}
+ else
+ ignore_ime_char--;
+
+ break;
+
+ case WM_IME_STARTCOMPOSITION:
+ if (!set_ime_composition_window_fn)
+ goto dflt;
+ else
+ {
+ COMPOSITIONFORM form;
+ HIMC context;
+ struct window *w;
+
+ if (!context)
+ break;
+
+ f = x_window_to_frame (dpyinfo, hwnd);
+ w = XWINDOW (FRAME_SELECTED_WINDOW (f));
+
+ form.dwStyle = CFS_RECT;
+ form.ptCurrentPos.x = w32_system_caret_x;
+ form.ptCurrentPos.y = w32_system_caret_y;
+
+ form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
+ form.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
+ + WINDOW_HEADER_LINE_HEIGHT (w));
+ form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
+ - WINDOW_RIGHT_MARGIN_WIDTH (w)
+ - WINDOW_RIGHT_FRINGE_WIDTH (w));
+ form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
+ - WINDOW_MODE_LINE_HEIGHT (w));
+
+ context = get_ime_context_fn (hwnd);
+ set_ime_composition_window_fn (context, &form);
+ release_ime_context_fn (hwnd, context);
+ }
break;
case WM_IME_ENDCOMPOSITION:
{
struct frame *f = x_window_to_frame (&one_w32_display_info,
hourglass_hwnd);
+ if (f)
+ f->output_data.w32->hourglass_p = 0;
+ else
+ /* If frame was deleted, restore to selected frame's cursor. */
+ f = SELECTED_FRAME ();
+
+ if (FRAME_W32_P (f))
+ SetCursor (f->output_data.w32->current_cursor);
+ else
+ /* No cursors on non GUI frames - restore to stock arrow cursor. */
+ SetCursor (w32_load_cursor (IDC_ARROW));
- f->output_data.w32->hourglass_p = 0;
- SetCursor (f->output_data.w32->current_cursor);
hourglass_shown_p = 0;
}
}
kb = dpyinfo->terminal->kboard;
+ /* The calls to x_get_arg remove elements from PARMS, so copy it to
+ avoid destructive changes behind our caller's back. */
+ parms = Fcopy_alist (parms);
+
/* Get the name of the frame to use for resource lookup. */
name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
if (!STRINGP (name)
f->resx = dpyinfo->resx;
f->resy = dpyinfo->resy;
- /* Perhaps, we must allow frame parameter, say `font-backend',
- to specify which font backends to use. */
+ if (uniscribe_available)
+ register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f);
x_default_parameter (f, parms, Qfont_backend, Qnil,
if (!NILP (Ffile_directory_p (filename))
&& NILP (Ffile_symlink_p (filename)))
{
- operation = Qdelete_directory;
+ operation = intern ("delete-directory");
filename = Fdirectory_file_name (filename);
}
filename = Fexpand_file_name (filename, Qnil);
Lisp_Object operation, document, parameters, show_flag;
{
Lisp_Object current_dir;
+ char *errstr;
CHECK_STRING (document);
XINT (show_flag) : SW_SHOWDEFAULT))
> 32)
return Qt;
- error ("ShellExecute failed: %s", w32_strerror (0));
+ errstr = w32_strerror (0);
+ /* The error string might be encoded in the locale's encoding. */
+ if (!NILP (Vlocale_coding_system))
+ {
+ Lisp_Object decoded =
+ code_convert_string_norecord (make_unibyte_string (errstr,
+ strlen (errstr)),
+ Vlocale_coding_system, 0);
+ errstr = (char *)SDATA (decoded);
+ }
+ error ("ShellExecute failed: %s", errstr);
}
/* Lookup virtual keycode from string representing the name of a
0, /* x_set_wait_for_wm, */
x_set_fullscreen,
x_set_font_backend,
- x_set_alpha
+ x_set_alpha,
+ 0, /* x_set_sticky */
};
void
Fput (Qundefined_color, Qerror_conditions,
- Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
+ pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
Fput (Qundefined_color, Qerror_message,
- build_string ("Undefined color"));
+ make_pure_c_string ("Undefined color"));
staticpro (&w32_grabbed_keys);
w32_grabbed_keys = Qnil;
The value can be hyper, super, meta, alt, control or shift for the
respective modifier, or nil to handle Scroll Lock as the `scroll' key.
Any other value will cause the Scroll Lock key to be ignored. */);
- Vw32_scroll_lock_modifier = Qt;
+ Vw32_scroll_lock_modifier = Qnil;
DEFVAR_LISP ("w32-lwindow-modifier",
&Vw32_lwindow_modifier,
GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
get_ime_context_fn = (ImmGetContext_Proc)
GetProcAddress (imm32_lib, "ImmGetContext");
+ release_ime_context_fn = (ImmReleaseContext_Proc)
+ GetProcAddress (imm32_lib, "ImmReleaseContext");
+ set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
+ GetProcAddress (imm32_lib, "ImmSetCompositionWindow");
}
DEFVAR_INT ("w32-ansi-code-page",
&w32_ansi_code_page,