/* 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
+ 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"
static unsigned hourglass_timer = 0;
static HWND hourglass_hwnd = NULL;
+#if 0 /* TODO: Mouse cursor customization. */
/* The background and shape of the mouse pointer, and shape when not
over text or in the modeline. */
-
Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape;
/* The shape when over mouse-sensitive text. */
Lisp_Object Vx_sensitive_text_pointer_shape;
+#endif
#ifndef IDC_HAND
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif
/* Color of chars displayed in cursor box. */
-
Lisp_Object Vx_cursor_fore_pixel;
/* Nonzero if using Windows. */
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;
&& mask_color == FRAME_BACKGROUND_PIXEL (f))
f->output_data.w32->mouse_pixel = FRAME_FOREGROUND_PIXEL (f);
-#if 0 /* TODO : cursor changes */
+#if 0 /* TODO : Mouse cursor customization. */
BLOCK_INPUT;
/* It's not okay to crash if the user selects a screwy cursor. */
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:
x_free_frame_resources (f);
+#if GLYPH_DEBUG
/* Check that reference counts are indeed correct. */
xassert (dpyinfo->reference_count == dpyinfo_refcount);
xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
-
+#endif
return Qt;
}
x_default_parameter (f, parameters, Qborder_width, make_number (2),
"borderWidth", "BorderWidth", RES_TYPE_NUMBER);
- /* We recognize either internalBorderWidth or internalBorder
+ /* We recognize either internalBorderWidth or internalBorder
(which is what xterm calls it). */
if (NILP (Fassq (Qinternal_border_width, parameters)))
{
error ("Cannot connect to server %s", SDATA (name));
w32_in_use = 1;
- XSETFASTINT (Vwindow_system_version, 3);
+ XSETFASTINT (Vwindow_system_version, w32_major_version);
return dpyinfo;
}
w32_in_use = 1;
- XSETFASTINT (Vwindow_system_version, 3);
+ XSETFASTINT (Vwindow_system_version, w32_major_version);
return Qnil;
}
{
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)
FRAME_FONTSET (f) = -1;
f->icon_name = Qnil;
-#if 0 /* GLYPH_DEBUG TODO: image support. */
+#if GLYPH_DEBUG
image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
dpyinfo_refcount = dpyinfo->reference_count;
#endif /* GLYPH_DEBUG */
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,
of the tooltip frame appear in pink. Prevent this. */
{
Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
+ Lisp_Object fg = Fframe_parameter (frame, Qforeground_color);
+ Lisp_Object colors = Qnil;
/* Set tip_frame here, so that */
tip_frame = frame;
call2 (Qface_set_after_frame_default, frame, Qnil);
if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
- Qnil));
+ colors = Fcons (Fcons (Qbackground_color, bg), colors);
+ if (!EQ (fg, Fframe_parameter (frame, Qforeground_color)))
+ colors = Fcons (Fcons (Qforeground_color, fg), colors);
+
+ if (!NILP (colors))
+ Fmodify_frame_parameters (frame, colors);
}
f->no_split = 1;
if (FRAMEP (frame))
{
- Fdelete_frame (frame, Qnil);
+ delete_frame (frame, Qnil);
deleted = Qt;
}
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);
if (system_status.BatteryFlag & 128)
{
battery_status = build_string ("N/A");
- battery_status_symbol = build_string ("");
+ battery_status_symbol = empty_unibyte_string;
}
else if (system_status.BatteryFlag & 8)
{
else if (system_status.BatteryFlag & 1)
{
battery_status = build_string ("high");
- battery_status_symbol = build_string ("");
+ battery_status_symbol = empty_unibyte_string;
}
else
{
battery_status = build_string ("medium");
- battery_status_symbol = build_string ("");
+ battery_status_symbol = empty_unibyte_string;
}
if (system_status.BatteryLifePercent > 100)
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,
bass-down, bass-boost, bass-up, treble-down, treble-up */);
w32_pass_multimedia_buttons_to_system = 1;
+#if 0 /* TODO: Mouse cursor customization. */
DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
doc: /* The shape of the pointer when over text.
Changing the value does not affect existing frames
This variable takes effect when you create a new frame
or when you set the mouse color. */);
Vx_window_horizontal_drag_shape = Qnil;
+#endif
DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
doc: /* A string indicating the foreground color of the cursor box. */);
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,