struct terminal *t = decode_live_terminal (object);
if (t->type != output_w32)
- error ("Terminal %d is not a W32 display", t->id);
+ error ("Terminal %d is not a W32 display", t->id);
return t->display_info.w32;
}
continue;
if (FRAME_W32_WINDOW (f) == wdesc)
- return f;
+ return f;
}
return 0;
}
if (monitor_from_window_fn && get_monitor_info_fn)
{
HMONITOR monitor =
- monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST);
+ monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST);
get_monitor_info_fn (monitor, &mi);
}
else
break;
val = (UINT)(0x100 * value);
/* We used 0x100 instead of 0xFF to give a continuous
- range between 0.0 and 1.0 inclusive. The next statement
- fixes the 1.0 case. */
+ range between 0.0 and 1.0 inclusive. The next statement
+ fixes the 1.0 case. */
if (val == 0x100)
val = 0xFF;
colorval |= (val << pos);
while (list)
{
if (W32_COLOR (list->entry) == color)
- {
+ {
++list->refcount;
return;
}
while (list)
{
if (W32_COLOR (list->entry) == color)
- {
+ {
if (--list->refcount == 0)
{
*prev = list->next;
if (f->gamma)
{
*color = PALETTERGB (
- pow (GetRValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
- pow (GetGValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
- pow (GetBValue (*color) / 255.0, f->gamma) * 255.0 + 0.5);
+ pow (GetRValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
+ pow (GetGValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
+ pow (GetBValue (*color) / 255.0, f->gamma) * 255.0 + 0.5);
}
}
if (!NILP (tem))
{
if (f)
- {
- /* Apply gamma correction. */
- w32_color_ref = XUINT (tem);
- gamma_correct (f, &w32_color_ref);
- XSETINT (tem, w32_color_ref);
- }
+ {
+ /* Apply gamma correction. */
+ w32_color_ref = XUINT (tem);
+ gamma_correct (f, &w32_color_ref);
+ XSETINT (tem, w32_color_ref);
+ }
/* Map this color to the palette if it is enabled. */
if (!NILP (Vw32_enable_palette))
update_face_from_frame_parameter (f, Qforeground_color, arg);
if (FRAME_VISIBLE_P (f))
- redraw_frame (f);
+ redraw_frame (f);
}
}
if (FRAME_W32_WINDOW (f) != 0)
{
SetWindowLong (FRAME_W32_WINDOW (f), WND_BACKGROUND_INDEX,
- FRAME_BACKGROUND_PIXEL (f));
+ FRAME_BACKGROUND_PIXEL (f));
update_face_from_frame_parameter (f, Qbackground_color, arg);
if (FRAME_VISIBLE_P (f))
- redraw_frame (f);
+ redraw_frame (f);
}
}
XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor,
&fore_color, &back_color);
XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor,
- &fore_color, &back_color);
+ &fore_color, &back_color);
XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor,
- &fore_color, &back_color);
+ &fore_color, &back_color);
}
if (FRAME_W32_WINDOW (f) != 0)
if (!NILP (Vx_cursor_fore_pixel))
fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
- WHITE_PIX_DEFAULT (f));
+ WHITE_PIX_DEFAULT (f));
else
fore_pixel = FRAME_BACKGROUND_PIXEL (f);
if (FRAME_W32_WINDOW (f) != 0 && f->border_width > 0)
{
if (FRAME_VISIBLE_P (f))
- redraw_frame (f);
+ redraw_frame (f);
}
}
block_input ();
#ifdef __CYGWIN__
GUI_FN (SetWindowText) (FRAME_W32_WINDOW (f),
- GUI_SDATA (GUI_ENCODE_SYSTEM (name)));
+ GUI_SDATA (GUI_ENCODE_SYSTEM (name)));
#else
/* The frame's title many times shows the name of the file
visited in the selected window's buffer, so it makes sense to
(modifier_set (VK_RWIN) ? w32_key_to_modifier (VK_RWIN) : 0) |
(modifier_set (VK_APPS) ? w32_key_to_modifier (VK_APPS) : 0) |
(modifier_set (VK_SCROLL) ? w32_key_to_modifier (VK_SCROLL) : 0) |
- (modifier_set (VK_MENU) ?
+ (modifier_set (VK_MENU) ?
((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier) : 0));
}
/* Produced by complete_deferred_msg; just ignore. */
break;
case WM_EMACS_CREATEWINDOW:
- /* Initialize COM for this window. Even though we don't use it,
- 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 publicly available until XP SP3,
- and older versions will never be patched. */
- CoInitialize (NULL);
+ /* Initialize COM for this window. Even though we don't use it,
+ 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 publicly available until XP SP3,
+ and older versions will never be patched. */
+ CoInitialize (NULL);
w32_createwindow ((struct frame *) msg.wParam,
(int *) msg.lParam);
if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
if (focus_window != NULL)
UnregisterHotKey (focus_window, RAW_HOTKEY_ID (msg.wParam));
/* Mark item as erased. NB: this code must be
- thread-safe. The next line is okay because the cons
- cell is never made into garbage and is not relocated by
- GC. */
+ thread-safe. The next line is okay because the cons
+ cell is never made into garbage and is not relocated by
+ GC. */
XSETCAR (make_lisp_ptr ((void *)msg.lParam, Lisp_Cons), Qnil);
if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
emacs_abort ();
}
break;
#ifdef MSG_DEBUG
- /* Broadcast messages make it here, so you need to be looking
- for something in particular for this to be useful. */
+ /* Broadcast messages make it here, so you need to be looking
+ for something in particular for this to be useful. */
default:
- DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message));
+ DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message));
#endif
}
}
signal_quit ();
/* As a safety precaution, forcibly complete any deferred
- messages. This is a kludge, but I don't see any particularly
- clean way to handle the situation where a deferred message is
- "dropped" in the lisp thread, and will thus never be
- completed, eg. by the user trying to activate the menubar
- when the lisp thread is busy, and then typing C-g when the
- menubar doesn't open promptly (with the result that the
- menubar never responds at all because the deferred
- WM_INITMENU message is never completed). Another problem
- situation is when the lisp thread calls SendMessage (to send
- a window manager command) when a message has been deferred;
- the lisp thread gets blocked indefinitely waiting for the
- deferred message to be completed, which itself is waiting for
- the lisp thread to respond.
+ messages. This is a kludge, but I don't see any particularly
+ clean way to handle the situation where a deferred message is
+ "dropped" in the lisp thread, and will thus never be
+ completed, eg. by the user trying to activate the menubar
+ when the lisp thread is busy, and then typing C-g when the
+ menubar doesn't open promptly (with the result that the
+ menubar never responds at all because the deferred
+ WM_INITMENU message is never completed). Another problem
+ situation is when the lisp thread calls SendMessage (to send
+ a window manager command) when a message has been deferred;
+ the lisp thread gets blocked indefinitely waiting for the
+ deferred message to be completed, which itself is waiting for
+ the lisp thread to respond.
Note that we don't want to block the input thread waiting for
a response from the lisp thread (although that would at least
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
}
+static int
+get_wm_chars (HWND aWnd, int *buf, int buflen, int ignore_ctrl, int ctrl,
+ int *ctrl_cnt, int *is_dead, int vk, int exp)
+{
+ MSG msg;
+ /* If doubled is at the end, ignore it. */
+ int i = buflen, doubled = 0, code_unit;
+
+ if (ctrl_cnt)
+ *ctrl_cnt = 0;
+ if (is_dead)
+ *is_dead = -1;
+ eassert(w32_unicode_gui);
+ while (buflen
+ /* Should be called only when w32_unicode_gui: */
+ && PeekMessageW(&msg, aWnd, WM_KEYFIRST, WM_KEYLAST,
+ PM_NOREMOVE | PM_NOYIELD)
+ && (msg.message == WM_CHAR || msg.message == WM_SYSCHAR
+ || msg.message == WM_DEADCHAR || msg.message == WM_SYSDEADCHAR
+ || msg.message == WM_UNICHAR))
+ {
+ /* We extract character payload, but in this call we handle only the
+ characters which comes BEFORE the next keyup/keydown message. */
+ int dead;
+
+ GetMessageW(&msg, aWnd, msg.message, msg.message);
+ dead = (msg.message == WM_DEADCHAR || msg.message == WM_SYSDEADCHAR);
+ if (is_dead)
+ *is_dead = (dead ? msg.wParam : -1);
+ if (dead)
+ continue;
+ code_unit = msg.wParam;
+ if (doubled)
+ {
+ /* Had surrogate. */
+ if (msg.message == WM_UNICHAR
+ || code_unit < 0xDC00 || code_unit > 0xDFFF)
+ { /* Mismatched first surrogate.
+ Pass both code units as if they were two characters. */
+ *buf++ = doubled;
+ if (!--buflen)
+ return i; /* Drop the 2nd char if at the end of the buffer. */
+ }
+ else /* see https://en.wikipedia.org/wiki/UTF-16 */
+ code_unit = (doubled << 10) + code_unit - 0x35FDC00;
+ doubled = 0;
+ }
+ else if (code_unit >= 0xD800 && code_unit <= 0xDBFF)
+ {
+ /* Handle mismatched 2nd surrogate the same as a normal character. */
+ doubled = code_unit;
+ continue;
+ }
+
+ /* The only "fake" characters delivered by ToUnicode() or
+ TranslateMessage() are:
+ 0x01 .. 0x1a for Ctrl-letter, Enter, Tab, Ctrl-Break, Esc, Backspace
+ 0x00 and 0x1b .. 0x1f for Control- []\@^_
+ 0x7f for Control-BackSpace
+ 0x20 for Control-Space */
+ if (ignore_ctrl
+ && (code_unit < 0x20 || code_unit == 0x7f
+ || (code_unit == 0x20 && ctrl)))
+ {
+ /* Non-character payload in a WM_CHAR
+ (Ctrl-something pressed, see above). Ignore, and report. */
+ if (ctrl_cnt)
+ *ctrl_cnt++;
+ continue;
+ }
+ /* Traditionally, Emacs would ignore the character payload of VK_NUMPAD*
+ keys, and would treat them later via `function-key-map'. In addition
+ to usual 102-key NUMPAD keys, this map also treats `kp-'-variants of
+ space, tab, enter, separator, equal. TAB and EQUAL, apparently,
+ cannot be generated on Win-GUI branch. ENTER is already handled
+ by the code above. According to `lispy_function_keys', kp_space is
+ generated by not-extended VK_CLEAR. (kp-tab != VK_OEM_NEC_EQUAL!).
+
+ We do similarly for backward-compatibility, but ignore only the
+ characters restorable later by `function-key-map'. */
+ if (code_unit < 0x7f
+ && ((vk >= VK_NUMPAD0 && vk <= VK_DIVIDE)
+ || (exp && ((vk >= VK_PRIOR && vk <= VK_DOWN) ||
+ vk == VK_INSERT || vk == VK_DELETE || vk == VK_CLEAR)))
+ && strchr("0123456789/*-+.,", code_unit))
+ continue;
+ *buf++ = code_unit;
+ buflen--;
+ }
+ return i - buflen;
+}
+
+#ifdef DBG_WM_CHARS
+# define FPRINTF_WM_CHARS(ARG) fprintf ARG
+#else
+# define FPRINTF_WM_CHARS(ARG) 0
+#endif
+
+/* This is a heuristic only. This is supposed to track the state of the
+ finite automaton in the language environment of Windows.
+
+ However, separate windows (if with the same different language
+ environments!) should have different values. Moreover, switching to a
+ non-Emacs window with the same language environment, and using (dead)keys
+ there would change the value stored in the kernel, but not this value. */
+static int after_deadkey = 0;
+
+int
+deliver_wm_chars (int do_translate, HWND hwnd, UINT msg, UINT wParam,
+ UINT lParam, int legacy_alt_meta)
+{
+ /* An "old style" keyboard description may assign up to 125 UTF-16 code
+ points to a keypress.
+ (However, the "old style" TranslateMessage() would deliver at most 16 of
+ them.) Be on a safe side, and prepare to treat many more. */
+ int ctrl_cnt, buf[1024], count, is_dead, after_dead = (after_deadkey != -1);
+
+ /* Since the keypress processing logic of Windows has a lot of state, it
+ is important to call TranslateMessage() for every keyup/keydown, AND
+ do it exactly once. (The actual change of state is done by
+ ToUnicode[Ex](), which is called by TranslateMessage(). So one can
+ call ToUnicode[Ex]() instead.)
+
+ The "usual" message pump calls TranslateMessage() for EVERY event.
+ Emacs calls TranslateMessage() very selectively (is it needed for doing
+ some tricky stuff with Win95??? With newer Windows, selectiveness is,
+ most probably, not needed - and harms a lot).
+
+ So, with the usual message pump, the following call to TranslateMessage()
+ is not needed (and is going to be VERY harmful). With Emacs' message
+ pump, the call is needed. */
+ if (do_translate)
+ {
+ MSG windows_msg = { hwnd, msg, wParam, lParam, 0, {0,0} };
+
+ windows_msg.time = GetMessageTime ();
+ TranslateMessage (&windows_msg);
+ }
+ count = get_wm_chars (hwnd, buf, sizeof(buf)/sizeof(*buf), 1,
+ /* The message may have been synthesized by
+ who knows what; be conservative. */
+ modifier_set (VK_LCONTROL)
+ || modifier_set (VK_RCONTROL)
+ || modifier_set (VK_CONTROL),
+ &ctrl_cnt, &is_dead, wParam,
+ (lParam & 0x1000000L) != 0);
+ if (count)
+ {
+ W32Msg wmsg;
+ DWORD console_modifiers = construct_console_modifiers ();
+ int *b = buf, strip_Alt = 1, strip_ExtraMods = 1, hairy = 0;
+ char *type_CtrlAlt = NULL;
+
+ /* XXXX In fact, there may be another case when we need to do the same:
+ What happens if the string defined in the LIGATURES has length
+ 0? Probably, we will get count==0, but the state of the finite
+ automaton would reset to 0??? */
+ after_deadkey = -1;
+
+ /* wParam is checked when converting CapsLock to Shift; this is a clone
+ of w32_get_key_modifiers (). */
+ wmsg.dwModifiers = w32_kbd_mods_to_emacs (console_modifiers, wParam);
+
+ /* What follows is just heuristics; the correct treatement requires
+ non-destructive ToUnicode():
+ http://search.cpan.org/~ilyaz/UI-KeyboardLayout/lib/UI/KeyboardLayout.pm#Can_an_application_on_Windows_accept_keyboard_events?_Part_IV:_application-specific_modifiers
+
+ What one needs to find is:
+ * which of the present modifiers AFFECT the resulting char(s)
+ (so should be stripped, since their EFFECT is "already
+ taken into account" in the string in buf), and
+ * which modifiers are not affecting buf, so should be reported to
+ the application for further treatment.
+
+ Example: assume that we know:
+ (A) lCtrl+rCtrl+rAlt modifiers with VK_A key produce a Latin "f"
+ ("may be logical" in JCUKEN-flavored Russian keyboard flavors);
+ (B) removing any of lCtrl, rCtrl, rAlt changes the produced char;
+ (C) Win-modifier is not affecting the produced character
+ (this is the common case: happens with all "standard" layouts).
+
+ Suppose the user presses Win+lCtrl+rCtrl+rAlt modifiers with VK_A.
+ What is the intent of the user? We need to guess the intent to decide
+ which event to deliver to the application.
+
+ This looks like a reasonable logic: since Win- modifier doesn't affect
+ the output string, the user was pressing Win for SOME OTHER purpose.
+ So the user wanted to generate Win-SOMETHING event. Now, what is
+ something? If one takes the mantra that "character payload is more
+ important than the combination of keypresses which resulted in this
+ payload", then one should ignore lCtrl+rCtrl+rAlt, ignore VK_A, and
+ assume that the user wanted to generate Win-f.
+
+ Unfortunately, without non-destructive ToUnicode(), checking (B),(C)
+ is out of question. So we use heuristics (hopefully, covering
+ 99.9999% of cases). */
+
+ /* Another thing to watch for is a possibility to use AltGr-* and
+ Ctrl-Alt-* with different semantic.
+
+ Background: the layout defining the KLLF_ALTGR bit are treated
+ specially by the kernel: when VK_RMENU (=rightAlt, =AltGr) is pressed
+ (released), a press (release) of VK_LCONTROL is emulated (unless Ctrl
+ is already down). As a result, any press/release of AltGr is seen
+ by applications as a press/release of lCtrl AND rAlt. This is
+ applicable, in particular, to ToUnicode[Ex](). (Keyrepeat is covered
+ the same way!)
+
+ NOTE: it IS possible to see bare rAlt even with KLLF_ALTGR; but this
+ requires a good finger coordination: doing (physically)
+ Down-lCtrl Down-rAlt Up-lCtrl Down-a
+ (doing quick enough, so that key repeat of rAlt [which would
+ generate new "fake" Down-lCtrl events] does not happens before 'a'
+ is down) results in no "fake" events, so the application will see
+ only rAlt down when 'a' is pressed. (However, fake Up-lCtrl WILL
+ be generated when rAlt goes UP.)
+
+ In fact, note also that KLLF_ALTGR does not prohibit construction of
+ rCtrl-rAlt (just press them in this order!).
+
+ Moreover: "traditional" layouts do not define distinct modifier-masks
+ for VK_LMENU and VK_RMENU (same for VK_L/RCONTROL). Instead, they
+ rely on the KLLF_ALTGR bit to make the behaviour of VK_LMENU and
+ VK_RMENU distinct. As a corollary, for such layouts, the produced
+ character is the same for AltGr-* (=rAlt-*) and Ctrl-Alt-* (in any
+ combination of handedness). For description of masks, see
+
+ http://search.cpan.org/~ilyaz/UI-KeyboardLayout/lib/UI/KeyboardLayout.pm#Keyboard_input_on_Windows,_Part_I:_what_is_the_kernel_doing?
+
+ By default, Emacs was using these coincidences via the following
+ heuristics: it was treating:
+ (*) keypresses with lCtrl-rAlt modifiers as if they are carrying
+ ONLY the character payload (no matter what the actual keyboard
+ was defining: if lCtrl-lAlt-b was delivering U+05df=beta, then
+ Emacs saw [beta]; if lCtrl-lAlt-b was undefined in the layout,
+ the keypress was completely ignored), and
+ (*) keypresses with the other combinations of handedness of Ctrl-Alt
+ modifiers (e.g., lCtrl-lAlt) as if they NEVER carry a character
+ payload (so they were reported "raw": if lCtrl-lAlt-b was
+ delivering beta, then Emacs saw event [C-A-b], and not [beta]).
+ This worked good for "traditional" layouts: users could type both
+ AltGr-x and Ctrl-Alt-x, and one was a character, another a bindable
+ event.
+
+ However, for layouts which deliver different characters for AltGr-x
+ and lCtrl-lAlt-x, this scheme makes the latter character unaccessible
+ in Emacs. While it is easy to access functionality of [C-M-x] in
+ Emacs by other means (for example, by the `controlify' prefix, or
+ using lCtrl-rCtrl-x, or rCtrl-rAlt-x [in this order]), missing
+ characters cannot be reconstructed without a tedious manual work. */
+
+ /* These two cases are often going to be distinguishable, since at most
+ one of these character is defined with KBDCTRL | KBDMENU modifier
+ bitmap. (This heuristic breaks if both lCtrl-lAlt- AND lCtrl-rAlt-
+ are translated to modifier bitmaps distinct from KBDCTRL | KBDMENU,
+ or in the cases when lCtrl-lAlt-* and lCtrl-rAlt-* are generally
+ different, but lCtrl-lAlt-x and lCtrl-rAlt-x happen to deliver the
+ same character.)
+
+ So we have 2 chunks of info:
+ (A) is it lCtrl-rAlt-, or lCtrl-lAlt, or some other combination?
+ (B) is the delivered character defined with KBDCTRL | KBDMENU bits?
+ Basing on (A) and (B), we should decide whether to ignore the
+ delivered character. (Before, Emacs was completely ignoring (B), and
+ was treating the 3-state of (A) as a bit.) This means that we have 6
+ bits of customization.
+
+ Additionally, a presence of two Ctrl down may be AltGr-rCtrl-. */
+
+ /* Strip all non-Shift modifiers if:
+ - more than one UTF-16 code point delivered (can't call VkKeyScanW ())
+ - or the character is a result of combining with a prefix key. */
+ if (!after_dead && count == 1 && *b < 0x10000)
+ {
+ if (console_modifiers & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)
+ && console_modifiers & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+ {
+ type_CtrlAlt = "bB"; /* generic bindable Ctrl-Alt- modifiers */
+ if (console_modifiers & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
+ == (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
+ /* double-Ctrl:
+ e.g. AltGr-rCtrl on some layouts (in this order!) */
+ type_CtrlAlt = "dD";
+ else if (console_modifiers
+ & (LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED)
+ == (LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED))
+ type_CtrlAlt = "lL"; /* Ctrl-Alt- modifiers on the left */
+ else if (!NILP (Vw32_recognize_altgr)
+ && (console_modifiers
+ & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
+ == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
+ type_CtrlAlt = "gG"; /* modifiers as in AltGr */
+ }
+ else if (wmsg.dwModifiers & (alt_modifier | meta_modifier)
+ || (console_modifiers
+ & (RIGHT_WIN_PRESSED | RIGHT_WIN_PRESSED
+ | APPS_PRESSED | SCROLLLOCK_ON)))
+ {
+ /* Pure Alt (or combination of Alt, Win, APPS, scrolllock. */
+ type_CtrlAlt = "aA";
+ }
+ if (type_CtrlAlt)
+ {
+ /* Out of bound bitmap: */
+ SHORT r = VkKeyScanW( *b ), bitmap = 0x1FF;
+
+ FPRINTF_WM_CHARS((stderr, "VkKeyScanW %#06x %#04x\n", (int)r,
+ wParam));
+ if ((r & 0xFF) == wParam)
+ bitmap = r>>8; /* *b is reachable via simple interface */
+ if (*type_CtrlAlt == 'a') /* Simple Alt seen */
+ {
+ if ((bitmap & ~1) == 0) /* 1: KBDSHIFT */
+ {
+ /* In "traditional" layouts, Alt without Ctrl does not
+ change the delivered character. This detects this
+ situation; it is safe to report this as Alt-something
+ - as opposed to delivering the reported character
+ without modifiers. */
+ if (legacy_alt_meta
+ && *b > 0x7f && ('A' <= wParam && wParam <= 'Z'))
+ /* For backward-compatibility with older Emacsen, let
+ this be processed by another branch below (which
+ would convert it to Alt-Latin char via wParam). */
+ return 0;
+ }
+ else
+ hairy = 1;
+ }
+ /* Check whether the delivered character(s) is accessible via
+ KBDCTRL | KBDALT ( | KBDSHIFT ) modifier mask (which is 7). */
+ else if ((bitmap & ~1) != 6)
+ {
+ /* The character is not accessible via plain Ctrl-Alt(-Shift)
+ (which is, probably, same as AltGr) modifiers.
+ Either it was after a prefix key, or is combined with
+ modifier keys which we don't see, or there is an asymmetry
+ between left-hand and right-hand modifiers, or other hairy
+ stuff. */
+ hairy = 1;
+ }
+ /* The best solution is to delegate these tough (but rarely
+ needed) choices to the user. Temporarily (???), it is
+ implemented as C macros.
+
+ Essentially, there are 3 things to do: return 0 (handle to the
+ legacy processing code [ignoring the character payload]; keep
+ some modifiers (so that they will be processed by the binding
+ system [on top of the character payload]; strip modifiers [so
+ that `self-insert' is going to be triggered with the character
+ payload]).
+
+ The default below should cover 99.9999% of cases:
+ (a) strip Alt- in the hairy case only;
+ (stripping = not ignoring)
+ (l) for lAlt-lCtrl, ignore the char in simple cases only;
+ (g) for what looks like AltGr, ignore the modifiers;
+ (d) for what looks like lCtrl-rCtrl-Alt (probably
+ AltGr-rCtrl), ignore the character in simple cases only;
+ (b) for other cases of Ctrl-Alt, ignore the character in
+ simple cases only.
+
+ Essentially, in all hairy cases, and in looks-like-AltGr case,
+ we keep the character, ignoring the modifiers. In all the
+ other cases, we ignore the delivered character. */
+#define S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD "aldb"
+#define S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS ""
+ if (strchr(S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD,
+ type_CtrlAlt[hairy]))
+ return 0;
+ /* If in neither list, report all the modifiers we see COMBINED
+ WITH the reported character. */
+ if (strchr(S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS,
+ type_CtrlAlt[hairy]))
+ strip_ExtraMods = 0;
+ }
+ }
+ if (strip_ExtraMods)
+ wmsg.dwModifiers = wmsg.dwModifiers & shift_modifier;
+
+ signal_user_input ();
+ while (count--)
+ {
+ FPRINTF_WM_CHARS((stderr, "unichar %#06x\n", *b));
+ my_post_msg (&wmsg, hwnd, WM_UNICHAR, *b++, lParam);
+ }
+ if (!ctrl_cnt) /* Process ALSO as ctrl */
+ return 1;
+ else
+ FPRINTF_WM_CHARS((stderr, "extra ctrl char\n"));
+ return -1;
+ }
+ else if (is_dead >= 0)
+ {
+ FPRINTF_WM_CHARS((stderr, "dead %#06x\n", is_dead));
+ after_deadkey = is_dead;
+ return 1;
+ }
+ return 0;
+}
+
/* Main window procedure */
static LRESULT CALLBACK
f = x_window_to_frame (dpyinfo, hwnd);
if (f)
{
- HDC hdc = get_frame_dc (f);
+ HDC hdc = get_frame_dc (f);
GetUpdateRect (hwnd, &wmsg.rect, FALSE);
w32_clear_rect (f, hdc, &wmsg.rect);
- release_frame_dc (f, hdc);
+ release_frame_dc (f, hdc);
#if defined (W32_DEBUG_DISPLAY)
- DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n",
+ DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n",
f,
- wmsg.rect.left, wmsg.rect.top,
+ wmsg.rect.left, wmsg.rect.top,
wmsg.rect.right, wmsg.rect.bottom));
#endif /* W32_DEBUG_DISPLAY */
}
case WM_PALETTECHANGED:
/* ignore our own changes */
if ((HWND)wParam != hwnd)
- {
+ {
f = x_window_to_frame (dpyinfo, hwnd);
if (f)
/* get_frame_dc will realize our palette and force all
return 0;
case WM_PAINT:
{
- PAINTSTRUCT paintStruct;
- RECT update_rect;
+ PAINTSTRUCT paintStruct;
+ RECT update_rect;
memset (&update_rect, 0, sizeof (update_rect));
f = x_window_to_frame (dpyinfo, hwnd);
if (f == 0)
{
- DebPrint (("WM_PAINT received for unknown window %p\n", hwnd));
+ DebPrint (("WM_PAINT received for unknown window %p\n", hwnd));
return 0;
}
- /* MSDN Docs say not to call BeginPaint if GetUpdateRect
- fails. Apparently this can happen under some
- circumstances. */
- if (GetUpdateRect (hwnd, &update_rect, FALSE) || !w32_strict_painting)
- {
- enter_crit ();
- BeginPaint (hwnd, &paintStruct);
+ /* MSDN Docs say not to call BeginPaint if GetUpdateRect
+ fails. Apparently this can happen under some
+ circumstances. */
+ if (GetUpdateRect (hwnd, &update_rect, FALSE) || !w32_strict_painting)
+ {
+ enter_crit ();
+ BeginPaint (hwnd, &paintStruct);
/* The rectangles returned by GetUpdateRect and BeginPaint
do not always match. Play it safe by assuming both areas
UnionRect (&(wmsg.rect), &update_rect, &(paintStruct.rcPaint));
#if defined (W32_DEBUG_DISPLAY)
- DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n",
+ DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n",
f,
wmsg.rect.left, wmsg.rect.top,
wmsg.rect.right, wmsg.rect.bottom));
- DebPrint ((" [update region is %d,%d-%d,%d]\n",
- update_rect.left, update_rect.top,
- update_rect.right, update_rect.bottom));
+ DebPrint ((" [update region is %d,%d-%d,%d]\n",
+ update_rect.left, update_rect.top,
+ update_rect.right, update_rect.bottom));
#endif
- EndPaint (hwnd, &paintStruct);
- leave_crit ();
+ EndPaint (hwnd, &paintStruct);
+ leave_crit ();
/* 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);
+ my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam);
- return 0;
- }
+ return 0;
+ }
/* If GetUpdateRect returns 0 (meaning there is no update
- region), assume the whole window needs to be repainted. */
+ region), assume the whole window needs to be repainted. */
GetClientRect (hwnd, &wmsg.rect);
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
- return 0;
+ return 0;
}
case WM_INPUTLANGCHANGE:
/* Inform lisp thread of keyboard layout changes. */
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+ /* The state of the finite automaton is separate per every input
+ language environment (so it does not change when one switches
+ to a different window with the same environment). Moreover,
+ the experiments show that the state is not remembered when
+ one switches back to the pre-previous environment. */
+ after_deadkey = -1;
+
+ /* XXXX??? What follows is a COMPLETE misunderstanding of Windows! */
+
/* Clear dead keys in the keyboard state; for simplicity only
- preserve modifier key states. */
+ preserve modifier key states. */
{
int i;
BYTE keystate[256];
/* Synchronize modifiers with current keystroke. */
sync_modifiers ();
record_keydown (wParam, lParam);
- wParam = map_keypad_keys (wParam, (lParam & 0x1000000L) != 0);
windows_translate = 0;
if (!NILP (Vw32_rwindow_modifier))
return 0;
break;
- case VK_APPS:
+ case VK_APPS:
if (!NILP (Vw32_apps_modifier))
return 0;
break;
case VK_MENU:
if (NILP (Vw32_pass_alt_to_system))
/* Prevent DefWindowProc from activating the menu bar if an
- Alt key is pressed and released by itself. */
+ Alt key is pressed and released by itself. */
return 0;
windows_translate = 1;
break;
break;
disable_lock_key:
/* Ensure the appropriate lock key state (and indicator light)
- remains in the same state. We do this by faking another
- press of the relevant key. Apparently, this really is the
- only way to toggle the state of the indicator lights. */
+ remains in the same state. We do this by faking another
+ press of the relevant key. Apparently, this really is the
+ only way to toggle the state of the indicator lights. */
dpyinfo->faked_key = wParam;
keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
/* Ensure indicator lights are updated promptly on Windows 9x
- (TranslateMessage apparently does this), after forwarding
- input event. */
+ (TranslateMessage apparently does this), after forwarding
+ input event. */
post_character_message (hwnd, msg, wParam, lParam,
w32_get_key_modifiers (wParam, lParam));
windows_translate = 1;
break;
case VK_CANCEL:
/* Windows maps Ctrl-Pause (aka Ctrl-Break) into VK_CANCEL,
- which is confusing for purposes of key binding; convert
+ which is confusing for purposes of key binding; convert
VK_CANCEL events into VK_PAUSE events. */
wParam = VK_PAUSE;
break;
case VK_PAUSE:
/* Windows maps Ctrl-NumLock into VK_PAUSE, which is confusing
- for purposes of key binding; convert these back into
- VK_NUMLOCK events, at least when we want to see NumLock key
- presses. (Note that there is never any possibility that
- VK_PAUSE with Ctrl really is C-Pause as per above.) */
+ for purposes of key binding; convert these back into
+ VK_NUMLOCK events, at least when we want to see NumLock key
+ presses. (Note that there is never any possibility that
+ VK_PAUSE with Ctrl really is C-Pause as per above.) */
if (NILP (Vw32_enable_num_lock) && modifier_set (VK_CONTROL))
wParam = VK_NUMLOCK;
break;
default:
- /* If not defined as a function key, change it to a WM_CHAR message. */
+ if (w32_unicode_gui)
+ {
+ /* If this event generates characters or deadkeys, do
+ not interpret it as a "raw combination of modifiers
+ and keysym". Hide deadkeys, and use the generated
+ character(s) instead of the keysym. (Backward
+ compatibility: exceptions for numpad keys generating
+ 0-9 . , / * - +, and for extra-Alt combined with a
+ non-Latin char.)
+
+ Try to not report modifiers which have effect on
+ which character or deadkey is generated.
+
+ Example (contrived): if rightAlt-? generates f (on a
+ Cyrillic keyboard layout), and Ctrl, leftAlt do not
+ affect the generated character, one wants to report
+ Ctrl-leftAlt-f if the user presses
+ Ctrl-leftAlt-rightAlt-?. */
+ int res;
+#if 0
+ /* Some of WM_CHAR may be fed to us directly, some are
+ results of TranslateMessage(). Using 0 as the first
+ argument (in a separate call) might help us
+ distinguish these two cases.
+
+ However, the keypress feeders would most probably
+ expect the "standard" message pump, when
+ TranslateMessage() is called on EVERY KeyDown/Keyup
+ event. So they may feed us Down-Ctrl Down-FAKE
+ Char-o and expect us to recognize it as Ctrl-o.
+ Using 0 as the first argument would interfere with
+ this. */
+ deliver_wm_chars (0, hwnd, msg, wParam, lParam, 1);
+#endif
+ /* Processing the generated WM_CHAR messages *WHILE* we
+ handle KEYDOWN/UP event is the best choice, since
+ withoug any fuss, we know all 3 of: scancode, virtual
+ keycode, and expansion. (Additionally, one knows
+ boundaries of expansion of different keypresses.) */
+ res = deliver_wm_chars (1, hwnd, msg, wParam, lParam, 1);
+ windows_translate = -( res != 0 );
+ if (res > 0) /* Bound to character(s) or a deadkey */
+ break;
+ /* deliver_wm_chars may make some branches after this vestigal. */
+ }
+ wParam = map_keypad_keys (wParam, (lParam & 0x1000000L) != 0);
+ /* If not defined as a function key, change it to a WM_CHAR message. */
if (wParam > 255 || !lispy_function_keys[wParam])
{
DWORD modifiers = construct_console_modifiers ();
/* Forward asciified character sequence. */
post_character_message
(hwnd, WM_CHAR,
- (unsigned char) key.uChar.AsciiChar, lParam,
+ (unsigned char) key.uChar.AsciiChar, lParam,
w32_get_key_modifiers (wParam, lParam));
w32_kbd_patch_key (&key, w32_keyboard_codepage);
}
}
}
+ if (windows_translate == -1)
+ break;
translate:
if (windows_translate)
{
case WM_SYSCHAR:
case WM_CHAR:
if (wParam > 255 )
- {
- W32Msg wmsg;
+ {
+ W32Msg wmsg;
- wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
- signal_user_input ();
- my_post_msg (&wmsg, hwnd, WM_UNICHAR, wParam, lParam);
+ wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
+ signal_user_input ();
+ my_post_msg (&wmsg, hwnd, WM_UNICHAR, wParam, lParam);
- }
+ }
else
- post_character_message (hwnd, msg, wParam, lParam,
- w32_get_key_modifiers (wParam, lParam));
+ post_character_message (hwnd, msg, wParam, lParam,
+ w32_get_key_modifiers (wParam, lParam));
break;
case WM_UNICHAR:
/* WM_UNICHAR looks promising from the docs, but the exact
- circumstances in which TranslateMessage sends it is one of those
- Microsoft secret API things that EU and US courts are supposed
- to have put a stop to already. Spy++ shows it being sent to Notepad
- and other MS apps, but never to Emacs.
+ circumstances in which TranslateMessage sends it is one of those
+ Microsoft secret API things that EU and US courts are supposed
+ to have put a stop to already. Spy++ shows it being sent to Notepad
+ and other MS apps, but never to Emacs.
- Some third party IMEs send it in accordance with the official
- documentation though, so handle it here.
+ Some third party IMEs send it in accordance with the official
+ documentation though, so handle it here.
- UNICODE_NOCHAR is used to test for support for this message.
- TRUE indicates that the message is supported. */
+ UNICODE_NOCHAR is used to test for support for this message.
+ TRUE indicates that the message is supported. */
if (wParam == UNICODE_NOCHAR)
- return TRUE;
+ return TRUE;
{
- W32Msg wmsg;
- wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
- signal_user_input ();
- my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+ W32Msg wmsg;
+ wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
+ signal_user_input ();
+ my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
}
break;
case WM_IME_CHAR:
/* 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. */
+ which will at least allow characters decodable in the system locale
+ get through. */
if (!get_composition_string_fn)
- goto dflt;
+ goto dflt;
else if (!ignore_ime_char)
- {
- wchar_t * buffer;
- int size, i;
- W32Msg wmsg;
- 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, NULL, 0);
- buffer = alloca (size);
- size = get_composition_string_fn (context, GCS_RESULTSTR,
- buffer, size);
+ {
+ wchar_t * buffer;
+ int size, i;
+ W32Msg wmsg;
+ 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, NULL, 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);
- }
- /* Ignore the messages for the rest of the
+ signal_user_input ();
+ for (i = 0; i < size / sizeof (wchar_t); i++)
+ {
+ my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer[i],
+ lParam);
+ }
+ /* Ignore the messages for the rest of the
characters in the string that was output above. */
- ignore_ime_char = (size / sizeof (wchar_t)) - 1;
- }
+ ignore_ime_char = (size / sizeof (wchar_t)) - 1;
+ }
else
ignore_ime_char--;
signal_user_input ();
/* Need to return true for XBUTTON messages, false for others,
- to indicate that we processed the message. */
+ to indicate that we processed the message. */
return (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONUP);
case WM_MOUSEMOVE:
case WM_VSCROLL:
if (w32_mouse_move_interval <= 0
|| (msg == WM_MOUSEMOVE && button_state == 0))
- {
+ {
wmsg.dwModifiers = w32_get_modifiers ();
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
return 0;
- }
+ }
/* Hang onto mouse move and scroll messages for a bit, to avoid
sending such events to Emacs faster than it can process them.
case WM_APPCOMMAND:
if (w32_pass_multimedia_buttons_to_system)
- goto dflt;
+ goto dflt;
/* Otherwise, pass to lisp, the same way we do with mousehwheel. */
case WM_MOUSEHWHEEL:
wmsg.dwModifiers = w32_get_modifiers ();
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
signal_user_input ();
/* Non-zero must be returned when WM_MOUSEHWHEEL messages are
- handled, to prevent the system trying to handle it by faking
- scroll bar events. */
+ handled, to prevent the system trying to handle it by faking
+ scroll bar events. */
return 1;
case WM_TIMER:
KillTimer (hwnd, menu_free_timer);
menu_free_timer = 0;
f = x_window_to_frame (dpyinfo, hwnd);
- /* If a popup menu is active, don't wipe its strings. */
+ /* If a popup menu is active, don't wipe its strings. */
if (menubar_in_use
- && current_popup_menu == NULL)
+ && current_popup_menu == NULL)
{
/* Free memory used by owner-drawn and help-echo strings. */
w32_free_menu_strings (hwnd);
if (f)
f->output_data.w32->menubar_active = 0;
- menubar_in_use = 0;
+ menubar_in_use = 0;
}
}
return 0;
if (find_deferred_msg (hwnd, msg) != NULL)
emacs_abort ();
- menubar_in_use = 1;
+ menubar_in_use = 1;
return send_deferred_msg (&msg_buf, hwnd, msg, wParam, lParam);
}
/* If a menu is still active, check again after a short delay,
since Windows often (always?) sends the WM_EXITMENULOOP
before the corresponding WM_COMMAND message.
- Don't do this if a popup menu is active, since it is only
- menubar menus that require cleaning up in this way.
+ Don't do this if a popup menu is active, since it is only
+ menubar menus that require cleaning up in this way.
*/
if (f && menubar_in_use && current_popup_menu == NULL)
menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
menu_font = CreateFontIndirect (&menu_logfont);
old_font = SelectObject (hdc, menu_font);
- pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE);
- if (title)
- {
+ pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE);
+ if (title)
+ {
if (unicode_append_menu)
GetTextExtentPoint32W (hdc, (WCHAR *) title,
wcslen ((WCHAR *) title),
else
GetTextExtentPoint32 (hdc, title, strlen (title), &size);
- pMis->itemWidth = size.cx;
- if (pMis->itemHeight < size.cy)
- pMis->itemHeight = size.cy;
- }
- else
- pMis->itemWidth = 0;
+ pMis->itemWidth = size.cx;
+ if (pMis->itemHeight < size.cy)
+ pMis->itemHeight = size.cy;
+ }
+ else
+ pMis->itemWidth = 0;
SelectObject (hdc, old_font);
DeleteObject (menu_font);
{
/* Draw popup menu title. */
char * title = (char *) pDis->itemData;
- if (title)
- {
- HDC hdc = pDis->hDC;
- HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT);
- LOGFONT menu_logfont;
- HFONT old_font;
-
- GetObject (menu_font, sizeof (menu_logfont), &menu_logfont);
- menu_logfont.lfWeight = FW_BOLD;
- menu_font = CreateFontIndirect (&menu_logfont);
- old_font = SelectObject (hdc, menu_font);
+ if (title)
+ {
+ HDC hdc = pDis->hDC;
+ HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT);
+ LOGFONT menu_logfont;
+ HFONT old_font;
+
+ GetObject (menu_font, sizeof (menu_logfont), &menu_logfont);
+ menu_logfont.lfWeight = FW_BOLD;
+ menu_font = CreateFontIndirect (&menu_logfont);
+ old_font = SelectObject (hdc, menu_font);
/* Always draw title as if not selected. */
if (unicode_append_menu)
ETO_OPAQUE, &pDis->rcItem,
title, strlen (title), NULL);
- SelectObject (hdc, old_font);
- DeleteObject (menu_font);
- }
+ SelectObject (hdc, old_font);
+ DeleteObject (menu_font);
+ }
return TRUE;
}
}
/* Don't restrict the sizing of any kind of frames. If the window
manager doesn't, there's no reason to do it ourselves. */
#if 0
- if (frame_resize_pixelwise || hwnd == tip_window)
+ if (frame_resize_pixelwise || hwnd == tip_window)
#endif
return 0;
#if 0
/* Don't restrict the sizing of fullscreened frames, allowing them to be
- flush with the sides of the screen. */
+ flush with the sides of the screen. */
f = x_window_to_frame (dpyinfo, hwnd);
if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE)
- return 0;
+ return 0;
{
WINDOWPLACEMENT wp;
case WM_EMACS_BRINGTOTOP:
case WM_EMACS_SETFOREGROUND:
{
- HWND foreground_window;
- DWORD foreground_thread, retval;
+ HWND foreground_window;
+ DWORD foreground_thread, retval;
- /* On NT 5.0, and apparently Windows 98, it is necessary to
- attach to the thread that currently has focus in order to
- pull the focus away from it. */
- foreground_window = GetForegroundWindow ();
+ /* On NT 5.0, and apparently Windows 98, it is necessary to
+ attach to the thread that currently has focus in order to
+ pull the focus away from it. */
+ foreground_window = GetForegroundWindow ();
foreground_thread = GetWindowThreadProcessId (foreground_window, NULL);
- if (!foreground_window
- || foreground_thread == GetCurrentThreadId ()
- || !AttachThreadInput (GetCurrentThreadId (),
- foreground_thread, TRUE))
- foreground_thread = 0;
-
- retval = SetForegroundWindow ((HWND) wParam);
- if (msg == WM_EMACS_BRINGTOTOP)
- retval = BringWindowToTop ((HWND) wParam);
-
- /* Detach from the previous foreground thread. */
- if (foreground_thread)
- AttachThreadInput (GetCurrentThreadId (),
- foreground_thread, FALSE);
-
- return retval;
+ if (!foreground_window
+ || foreground_thread == GetCurrentThreadId ()
+ || !AttachThreadInput (GetCurrentThreadId (),
+ foreground_thread, TRUE))
+ foreground_thread = 0;
+
+ retval = SetForegroundWindow ((HWND) wParam);
+ if (msg == WM_EMACS_BRINGTOTOP)
+ retval = BringWindowToTop ((HWND) wParam);
+
+ /* Detach from the previous foreground thread. */
+ if (foreground_thread)
+ AttachThreadInput (GetCurrentThreadId (),
+ foreground_thread, FALSE);
+
+ return retval;
}
case WM_EMACS_SETWINDOWPOS:
button_state = 0;
/* Use menubar_active to indicate that WM_INITMENU is from
- TrackPopupMenu below, and should be ignored. */
+ TrackPopupMenu below, and should be ignored. */
f = x_window_to_frame (dpyinfo, hwnd);
if (f)
f->output_data.w32->menubar_active = 1;
{
int i;
static char *names[]
- = { "Courier New-10",
- "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
- "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
- "Fixedsys",
- NULL };
+ = { "Courier New-10",
+ "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
+ "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
+ "Fixedsys",
+ NULL };
for (i = 0; names[i]; i++)
- {
- font = font_open_by_name (f, build_unibyte_string (names[i]));
- if (! NILP (font))
- break;
- }
+ {
+ font = font_open_by_name (f, build_unibyte_string (names[i]));
+ if (! NILP (font))
+ break;
+ }
if (NILP (font))
- error ("No suitable font was found");
+ error ("No suitable font was found");
}
else if (!NILP (font_param))
{
fset_icon_name
(f, x_get_arg (dpyinfo, parameters, Qicon_name, "iconName", "Title",
- RES_TYPE_STRING));
+ RES_TYPE_STRING));
if (! STRINGP (f->icon_name))
fset_icon_name (f, Qnil);
frame on this terminal. */
if (FRAME_HAS_MINIBUF_P (f)
&& (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
- || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
+ || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
kset_default_minibuffer_frame (kb, frame);
/* All remaining specified parameters, which have not been "used"
\f
/***********************************************************************
- Window properties
+ Window properties
***********************************************************************/
#if 0 /* TODO : port window properties to W32 */
***********************************************************************/
static Lisp_Object x_create_tip_frame (struct w32_display_info *,
- Lisp_Object, Lisp_Object);
+ Lisp_Object, Lisp_Object);
static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
- Lisp_Object, int, int, int *, int *);
+ Lisp_Object, int, int, int *, int *);
/* The frame of a currently visible tooltip. */
"cursorType", "CursorType", RES_TYPE_SYMBOL);
/* Process alpha here (Bug#17344). */
x_default_parameter (f, parms, Qalpha, Qnil,
- "alpha", "Alpha", RES_TYPE_NUMBER);
+ "alpha", "Alpha", RES_TYPE_NUMBER);
/* Dimensions, especially FRAME_LINES (f), must be done via
change_frame_size. Change will not be effected unless different
if (file_opened)
{
- /* Get an Emacs string from the value Windows gave us. */
+ /* Get an Emacs string from the value Windows gave us. */
#ifdef NTGUI_UNICODE
- filename = from_unicode_buffer (filename_buf_w);
+ filename = from_unicode_buffer (filename_buf_w);
#else /* !NTGUI_UNICODE */
if (use_unicode)
filename_from_utf16 (filename_buf_w, fname_ret);
else
filename_from_ansi (filename_buf_a, fname_ret);
dostounix_filename (fname_ret);
- filename = DECODE_FILE (build_unibyte_string (fname_ret));
+ filename = DECODE_FILE (build_unibyte_string (fname_ret));
#endif /* NTGUI_UNICODE */
#ifdef CYGWIN
- filename = Fcygwin_convert_file_name_from_windows (filename, Qt);
+ filename = Fcygwin_convert_file_name_from_windows (filename, Qt);
#endif /* CYGWIN */
- /* Strip the dummy filename off the end of the string if we
- added it to select a directory. */
- if ((use_unicode && file_details_w->nFilterIndex == 2)
+ /* Strip the dummy filename off the end of the string if we
+ added it to select a directory. */
+ if ((use_unicode && file_details_w->nFilterIndex == 2)
#ifndef NTGUI_UNICODE
|| (!use_unicode && file_details_a->nFilterIndex == 2)
#endif
/* An error occurred, fallback on reading from the mini-buffer. */
else
filename = Fcompleting_read (
- orig_prompt,
- intern ("read-file-name-internal"),
- orig_dir,
- mustmatch,
- orig_dir,
- Qfile_name_history,
- default_filename,
- Qnil);
+ orig_prompt,
+ intern ("read-file-name-internal"),
+ orig_dir,
+ mustmatch,
+ orig_dir,
+ Qfile_name_history,
+ default_filename,
+ Qnil);
UNGCPRO;
}
\f
/***********************************************************************
- w32 specialized functions
+ w32 specialized functions
***********************************************************************/
DEFUN ("w32-send-sys-command", Fw32_send_sys_command,
operations:
\"open\" - open DOCUMENT, which could be a file, a directory, or an
- executable program (application). If it is an application,
- that application is launched in the current buffer's default
- directory. Otherwise, the application associated with
- DOCUMENT is launched in the buffer's default directory.
+ executable program (application). If it is an application,
+ that application is launched in the current buffer's default
+ directory. Otherwise, the application associated with
+ DOCUMENT is launched in the buffer's default directory.
\"opennew\" - like \"open\", but instruct the application to open
- DOCUMENT in a new window.
+ DOCUMENT in a new window.
\"openas\" - open the \"Open With\" dialog for DOCUMENT.
\"print\" - print DOCUMENT, which must be a file.
\"printto\" - print DOCUMENT, which must be a file, to a specified printer.
- The printer should be provided in PARAMETERS, see below.
+ The printer should be provided in PARAMETERS, see below.
\"explore\" - start the Windows Explorer on DOCUMENT.
\"edit\" - launch an editor and open DOCUMENT for editing; which
- editor is launched depends on the association for the
- specified DOCUMENT.
+ editor is launched depends on the association for the
+ specified DOCUMENT.
\"find\" - initiate search starting from DOCUMENT, which must specify
- a directory.
+ a directory.
\"delete\" - move DOCUMENT, a file or a directory, to Recycle Bin.
\"copy\" - copy DOCUMENT, which must be a file or a directory, into
- the clipboard.
+ the clipboard.
\"cut\" - move DOCUMENT, a file or a directory, into the clipboard.
\"paste\" - paste the file whose name is in the clipboard into DOCUMENT,
- which must be a directory.
+ which must be a directory.
\"pastelink\"
- - create a shortcut in DOCUMENT (which must be a directory)
- the file or directory whose name is in the clipboard.
+ - create a shortcut in DOCUMENT (which must be a directory)
+ the file or directory whose name is in the clipboard.
\"runas\" - run DOCUMENT, which must be an excutable file, with
- elevated privileges (a.k.a. \"as Administrator\").
+ elevated privileges (a.k.a. \"as Administrator\").
\"properties\"
- - open the property sheet dialog for DOCUMENT.
+ - open the property sheet dialog for DOCUMENT.
nil - invoke the default OPERATION, or \"open\" if default is
- not defined or unavailable.
+ not defined or unavailable.
DOCUMENT is typically the name of a document file or a URL, but can
also be an executable program to run, or a directory to open in the
? Fcons (make_number (0), make_number (0))
: Fcons (make_number (border_width),
make_number (border_height)))),
- Fcons (Qtitle_height,
+ Fcons (Qtitle_height,
((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
? make_number (0)
: make_number (title_height))),
error_no = GetLastError ();
ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- error_no,
- 0, /* choose most suitable language */
- buf, sizeof (buf), NULL);
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ error_no,
+ 0, /* choose most suitable language */
+ buf, sizeof (buf), NULL);
while (ret > 0 && (buf[ret - 1] == '\n' ||
- buf[ret - 1] == '\r' ))
+ buf[ret - 1] == '\r' ))
--ret;
buf[ret] = '\0';
if (!ret)
else
{
isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
- keystate, (LPWORD) ansi_code, 0);
+ keystate, (LPWORD) ansi_code, 0);
}
if (isdead == 0)
w32_pass_extra_mouse_buttons_to_system = 0;
DEFVAR_BOOL ("w32-pass-multimedia-buttons-to-system",
- w32_pass_multimedia_buttons_to_system,
- doc: /* If non-nil, media buttons are passed to Windows.
+ w32_pass_multimedia_buttons_to_system,
+ doc: /* If non-nil, media buttons are passed to Windows.
Some modern keyboards contain buttons for controlling media players, web
browsers and other applications. Generally these buttons are handled on a
system wide basis, but by setting this to nil they are made available
Vx_pixel_size_width_font_regexp = Qnil;
DEFVAR_LISP ("w32-bdf-filename-alist",
- Vw32_bdf_filename_alist,
- doc: /* List of bdf fonts and their corresponding filenames. */);
+ Vw32_bdf_filename_alist,
+ doc: /* List of bdf fonts and their corresponding filenames. */);
Vw32_bdf_filename_alist = Qnil;
DEFVAR_BOOL ("w32-strict-fontnames",
- w32_strict_fontnames,
+ w32_strict_fontnames,
doc: /* Non-nil means only use fonts that are exact matches for those requested.
Default is nil, which allows old fontnames that are not XLFD compliant,
and allows third-party CJK display to work by specifying false charset
w32_strict_fontnames = 0;
DEFVAR_BOOL ("w32-strict-painting",
- w32_strict_painting,
+ w32_strict_painting,
doc: /* Non-nil means use strict rules for repainting frames.
Set this to nil to get the old behavior for repainting; this should
only be necessary if the default setting causes problems. */);