/* Fake key modifier which is attached to a quit char event.
Removed upon dequeueing an event */
-#define FAKE_MOD_QUIT 0x80
+#define FAKE_MOD_QUIT (1 << 20)
+#define FAKE_MOD_QUIT_CRITICAL (1 << 21)
/* Timer ID used for button2 emulation */
#define BUTTON_2_TIMER_ID 1
static Lisp_Object mswindows_find_console (HWND hwnd);
static Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods,
int extendedp);
-static int mswindows_modifier_state (BYTE* keymap, int has_AltGr);
+static int mswindows_modifier_state (BYTE* keymap, DWORD fwKeys,
+ int has_AltGr);
static void mswindows_set_chord_timer (HWND hwnd);
static int mswindows_button2_near_enough (POINTS p1, POINTS p2);
static int mswindows_current_layout_has_AltGr (void);
/* These are Lisp integers; see DEFVARS in this file for description. */
int mswindows_dynamic_frame_resize;
int mswindows_alt_by_itself_activates_menu;
-int mswindows_num_mouse_buttons;
-int mswindows_mouse_button_max_skew_x;
-int mswindows_mouse_button_max_skew_y;
-int mswindows_mouse_button_tolerance;
+Fixnum mswindows_num_mouse_buttons;
+Fixnum mswindows_mouse_button_max_skew_x;
+Fixnum mswindows_mouse_button_max_skew_y;
+Fixnum mswindows_mouse_button_tolerance;
#ifdef DEBUG_XEMACS
-int mswindows_debug_events;
+Fixnum debug_mswindows_events;
#endif
/* This is the event signaled by the event pump.
/* Count of wound timers */
static int mswindows_pending_timers_count;
+
+static DWORD mswindows_last_mouse_button_state;
\f
/************************************************************************/
/* Pipe instream - reads process output */
return s->thread_data->hev_caller;
}
-static ssize_t
-ntpipe_slurp_reader (Lstream *stream, unsigned char *data, size_t size)
+static Lstream_data_count
+ntpipe_slurp_reader (Lstream *stream, unsigned char *data,
+ Lstream_data_count size)
{
/* This function must be called from the main thread only */
struct ntpipe_slurp_stream_shared_data* s =
}
#endif
-static ssize_t
-ntpipe_shove_writer (Lstream *stream, const unsigned char *data, size_t size)
+static Lstream_data_count
+ntpipe_shove_writer (Lstream *stream, const unsigned char *data,
+ Lstream_data_count size)
{
struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream);
SetEvent (s->hev_thread);
/* Give it a chance to run -- this dramatically improves performance
of things like crypt. */
- (void) SwitchToThread ();
+ if (xSwitchToThread) /* not in Win9x or NT 3.51 */
+ (void) xSwitchToThread ();
return size;
}
str->eof_p = 1;
}
-static ssize_t
-winsock_reader (Lstream *stream, unsigned char *data, size_t size)
+static Lstream_data_count
+winsock_reader (Lstream *stream, unsigned char *data, Lstream_data_count size)
{
struct winsock_stream *str = WINSOCK_STREAM_DATA (stream);
return -1;
/* Return as much of buffer as we have */
- size = min (size, (size_t) (str->bufsize - str->bufpos));
+ size = min (size, (Lstream_data_count) (str->bufsize - str->bufpos));
memcpy (data, (void*)((BYTE*)str->buffer + str->bufpos), size);
str->bufpos += size;
return size;
}
-static ssize_t
-winsock_writer (Lstream *stream, const unsigned char *data, size_t size)
+static Lstream_data_count
+winsock_writer (Lstream *stream, const unsigned char *data,
+ Lstream_data_count size)
{
struct winsock_stream *str = WINSOCK_STREAM_DATA (stream);
static void
mswindows_enqueue_mouse_button_event (HWND hwnd, UINT msg, POINTS where,
- DWORD when)
+ int mods, DWORD when)
{
int downp = (msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN ||
msg == WM_RBUTTONDOWN);
((msg==WM_RBUTTONDOWN || msg==WM_RBUTTONUP) ? 3 : 2);
event->event.button.x = where.x;
event->event.button.y = where.y;
- event->event.button.modifiers = mswindows_modifier_state (NULL, 0);
+ event->event.button.modifiers = mswindows_modifier_state (NULL, mods, 0);
if (downp)
{
if (sevt->event_type == key_press_event
&& (sevt->event.key.modifiers & FAKE_MOD_QUIT))
{
- sevt->event.key.modifiers &= ~FAKE_MOD_QUIT;
+ sevt->event.key.modifiers &=
+ ~(FAKE_MOD_QUIT | FAKE_MOD_QUIT_CRITICAL);
--mswindows_quit_chars_count;
}
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
+ char class_name_buf [sizeof (XEMACS_CLASS) + 2] = "";
+
+ /* Don't translate messages destined for a dialog box, this
+ makes keyboard traversal work. I think?? */
+ if (mswindows_is_dialog_msg (&msg))
+ {
+ mswindows_unmodalize_signal_maybe ();
+ continue;
+ }
+
/* We have to translate messages that are not sent to an XEmacs
frame. This is so that key presses work ok in things like
edit fields. However, we *musn't* translate message for XEmacs
/* GetClassName will truncate a longer class name. By adding one
extra character, we are forcing textual comparison to fail
if the name is longer than XEMACS_CLASS */
- char class_name_buf [sizeof (XEMACS_CLASS) + 2] = "";
+
GetClassName (msg.hwnd, class_name_buf, sizeof (class_name_buf) - 1);
if (stricmp (class_name_buf, XEMACS_CLASS) != 0)
{
else if (msg.message == WM_PAINT)
{
struct mswindows_frame* msframe;
-
+
/* hdc will be NULL unless this is a subwindow - in which case we
shouldn't have received a paint message for it here. */
assert (msg.wParam == 0);
* fetching WM_TIMER messages. Instead of trying to fetch a WM_TIMER
* which will never come when there are no pending timers, which leads
* to deadlock, we simply signal an error.
+ *
+ * It might be possible to combine this with mswindows_drain_windows_queue
+ * which fetches events when not in a modal loop. It's not clear
+ * whether the result would be more complex than is justified.
*/
static void
mswindows_need_event_in_modal_loop (int badly_p)
error ("Deadlock due to an attempt to call next-event in a wrong context");
/* Fetch and dispatch any pending timers */
- GetMessage (&msg, NULL, WM_TIMER, WM_TIMER);
- DispatchMessage (&msg);
+ if (GetMessage (&msg, NULL, WM_TIMER, WM_TIMER) > 0)
+ DispatchMessage (&msg);
}
}
{
int active;
- if (mswindows_in_modal_loop)
- {
- mswindows_need_event_in_modal_loop (badly_p);
- return;
- }
-
while (NILP (mswindows_u_dispatch_event_queue)
&& NILP (mswindows_s_dispatch_event_queue))
{
EMACS_SET_SECS_USECS (sometime, 0, 0);
EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block);
pointer_to_this = &select_time_to_block;
+ if (mswindows_in_modal_loop)
+ /* In modal loop with badly_p false, don't care about
+ Windows events. */
+ FD_CLR (windows_fd, &temp_mask);
}
active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this);
{
if (FD_ISSET (windows_fd, &temp_mask))
{
- mswindows_drain_windows_queue ();
+ if (mswindows_in_modal_loop)
+ mswindows_need_event_in_modal_loop (badly_p);
+ else
+ mswindows_drain_windows_queue ();
}
- else
+ else
{
#ifdef HAVE_TTY
/* Look for a TTY event */
struct console *c = tty_find_console_from_fd (i);
Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
Lisp_Event* event = XEVENT (emacs_event);
-
+
assert (c);
if (read_event_from_tty_or_stream_desc (event, c, i))
{
{
Lisp_Process *p =
get_process_from_usid (FD_TO_USID(i));
-
+
mswindows_enqueue_process_event (p);
}
else
}
#else
/* Now try getting a message or process event */
+ DWORD what_events;
+ if (mswindows_in_modal_loop)
+ /* In a modal loop, only look for timer events, and only if
+ we really need one. */
+ {
+ if (badly_p)
+ what_events = QS_TIMER;
+ else
+ what_events = 0;
+ }
+ else
+ /* Look for any event */
+ what_events = QS_ALLINPUT;
+
active = MsgWaitForMultipleObjects (mswindows_waitable_count,
mswindows_waitable_handles,
FALSE, badly_p ? INFINITE : 0,
- QS_ALLINPUT);
+ what_events);
/* This will assert if handle being waited for becomes abandoned.
Not the case currently tho */
else if (active == WAIT_OBJECT_0 + mswindows_waitable_count)
{
/* Got your message, thanks */
- mswindows_drain_windows_queue ();
+ if (mswindows_in_modal_loop)
+ mswindows_need_event_in_modal_loop (badly_p);
+ else
+ mswindows_drain_windows_queue ();
}
else
{
{
/* None. This means that the process handle itself has signaled.
Remove the handle from the wait vector, and make status_notify
- note the exited process */
+ note the exited process. First find the process object if
+ possible. */
+ LIST_LOOP_3 (vaffanculo, Vprocess_list, vproctail)
+ if (get_nt_process_handle (XPROCESS (vaffanculo)) ==
+ mswindows_waitable_handles [ix])
+ break;
mswindows_waitable_handles [ix] =
mswindows_waitable_handles [--mswindows_waitable_count];
kick_status_notify ();
process, and (2) status notifications will happen in
accept-process-output, sleep-for, and sit-for. */
/* #### horrible kludge till my real process fixes go in.
+ #### Replaced with a slightly less horrible kluge that
+ at least finds the right process instead of axing the
+ first one on the list.
*/
- if (!NILP (Vprocess_list))
+ if (!NILP (vproctail))
{
- Lisp_Object vaffanculo = XCAR (Vprocess_list);
mswindows_enqueue_process_event (XPROCESS (vaffanculo));
}
else /* trash me soon. */
}
/*
- * Returns 1 if a key is a real modifier or special key, which
+ * Returns 1 if a key is a real modifier or special key, which
* is better handled by DefWindowProc
*/
static int
/* asyncstate[2] & 0x1 ? 1 : 0); */
}
-#endif /* DEBUG_XEMACS */
+#endif /* DEBUG_XEMACS */
/*
struct frame *frame;
struct mswindows_frame* msframe;
+ /* Not perfect but avoids crashes. There is potential for wierd
+ behavior here. */
+ if (gc_in_progress)
+ goto defproc;
+
assert (!GetWindowLong (hwnd, GWL_USERDATA));
switch (message_)
{
int should_set_keymap = 0;
#ifdef DEBUG_XEMACS
- if (mswindows_debug_events)
+ if (debug_mswindows_events)
{
stderr_out ("%s wparam=%d lparam=%d\n",
message_ == WM_KEYUP ? "WM_KEYUP" : "WM_SYSKEYUP",
wParam, (int)lParam);
output_alt_keyboard_state ();
- }
-#endif /* DEBUG_XEMACS */
+ }
+#endif /* DEBUG_XEMACS */
mswindows_handle_sticky_modifiers (wParam, lParam, 0, 1);
if (wParam == VK_CONTROL)
SetKeyboardState (keymap);
}
-
+
if (key_needs_default_processing_p (wParam))
goto defproc;
else
case WM_SYSKEYDOWN:
/* In some locales the right-hand Alt key is labelled AltGr. This key
- * should produce alternative charcaters when combined with another key.
+ * should produce alternative characters when combined with another key.
* eg on a German keyboard pressing AltGr+q should produce '@'.
* AltGr generates exactly the same keystrokes as LCtrl+RAlt. But if
* TranslateMessage() is called with *any* combination of Ctrl+Alt down,
BYTE keymap_orig[256];
BYTE keymap_sticky[256];
int has_AltGr = mswindows_current_layout_has_AltGr ();
- int mods = 0;
+ int mods = 0, mods_with_shift = 0;
int extendedp = lParam & 0x1000000;
Lisp_Object keysym;
int sticky_changed;
#ifdef DEBUG_XEMACS
- if (mswindows_debug_events)
+ if (debug_mswindows_events)
{
stderr_out ("%s wparam=%d lparam=%d\n",
message_ == WM_KEYDOWN ? "WM_KEYDOWN" : "WM_SYSKEYDOWN",
wParam, (int)lParam);
output_alt_keyboard_state ();
- }
-#endif /* DEBUG_XEMACS */
+ }
+#endif /* DEBUG_XEMACS */
GetKeyboardState (keymap_orig);
frame = XFRAME (mswindows_find_frame (hwnd));
else
memcpy (keymap_sticky, keymap_orig, 256);
- mods = mswindows_modifier_state (keymap_sticky, has_AltGr);
+ mods = mswindows_modifier_state (keymap_sticky, (DWORD) -1, has_AltGr);
+ mods_with_shift = mods;
/* Handle non-printables */
if (!NILP (keysym = mswindows_key_to_emacs_keysym (wParam, mods,
MSG msg, tranmsg;
int potential_accelerator = 0;
int got_accelerator = 0;
-
+
msg.hwnd = hwnd;
msg.message = message_;
msg.wParam = wParam;
|| PeekMessage (&tranmsg, hwnd, WM_SYSCHAR, WM_SYSCHAR,
PM_REMOVE))
{
- int mods1 = mods;
+ int mods_with_quit = mods;
WPARAM ch = tranmsg.wParam;
/* If a quit char with no modifiers other than control and
shift, then mark it with a fake modifier, which is removed
upon dequeueing the event */
- /* #### This might also not withstand localization, if
- quit character is not a latin-1 symbol */
+ /* !!#### Fix this in my mule ws -- replace current_buffer
+ with 0 */
if (((quit_ch < ' ' && (mods & XEMACS_MOD_CONTROL)
- && quit_ch + 'a' - 1 == ch)
+ && DOWNCASE (current_buffer, quit_ch + 'a' - 1) ==
+ DOWNCASE (current_buffer, ch))
|| (quit_ch >= ' ' && !(mods & XEMACS_MOD_CONTROL)
- && quit_ch == ch))
- && ((mods & ~(XEMACS_MOD_CONTROL | XEMACS_MOD_SHIFT))
+ && DOWNCASE (current_buffer, quit_ch) ==
+ DOWNCASE (current_buffer, ch)))
+ && ((mods_with_shift &
+ ~(XEMACS_MOD_CONTROL | XEMACS_MOD_SHIFT))
== 0))
{
- mods1 |= FAKE_MOD_QUIT;
+ mods_with_quit |= FAKE_MOD_QUIT;
+ if (mods_with_shift & XEMACS_MOD_SHIFT)
+ mods_with_quit |= FAKE_MOD_QUIT_CRITICAL;
++mswindows_quit_chars_count;
}
else if (potential_accelerator && !got_accelerator &&
got_accelerator = 1;
break;
}
- mswindows_enqueue_keypress_event (hwnd, make_char (ch), mods1);
+ mswindows_enqueue_keypress_event (hwnd, make_char (ch),
+ mods_with_quit);
} /* while */
/* This generates WM_SYSCHAR messages, which are interpreted
by DefWindowProc as the menu selections. */
if (got_accelerator)
- {
+ {
SetKeyboardState (keymap_sticky);
TranslateMessage (&msg);
SetKeyboardState (keymap_orig);
if one wants to exercise fingers playing chords on the mouse,
he is allowed to do that! */
mswindows_enqueue_mouse_button_event (hwnd, message_,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam &~ MK_MBUTTON,
+ GetMessageTime());
break;
case WM_LBUTTONUP:
msframe->button2_is_down = 0;
msframe->ignore_next_rbutton_up = 1;
mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam
+ &~ (MK_LBUTTON | MK_MBUTTON
+ | MK_RBUTTON),
+ GetMessageTime());
}
else
{
{
msframe->button2_need_rbutton = 0;
mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam &~ MK_LBUTTON,
+ GetMessageTime());
}
mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONUP,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam &~ MK_LBUTTON,
+ GetMessageTime());
}
break;
msframe->button2_is_down = 0;
msframe->ignore_next_lbutton_up = 1;
mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam
+ &~ (MK_LBUTTON | MK_MBUTTON
+ | MK_RBUTTON),
+ GetMessageTime());
}
else
{
{
msframe->button2_need_lbutton = 0;
mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam &~ MK_RBUTTON,
+ GetMessageTime());
}
mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONUP,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam &~ MK_RBUTTON,
+ GetMessageTime());
}
break;
KillTimer (hwnd, BUTTON_2_TIMER_ID);
msframe->button2_need_lbutton = 0;
msframe->button2_need_rbutton = 0;
- if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam)))
+ if (mswindows_button2_near_enough (msframe->last_click_point,
+ MAKEPOINTS (lParam)))
{
mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam
+ &~ (MK_LBUTTON | MK_MBUTTON
+ | MK_RBUTTON),
+ GetMessageTime());
msframe->button2_is_down = 1;
}
else
{
mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
- msframe->last_click_point, msframe->last_click_time);
+ msframe->last_click_point,
+ msframe->last_click_mods
+ &~ MK_RBUTTON,
+ msframe->last_click_time);
mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam &~ MK_LBUTTON,
+ GetMessageTime());
}
}
else
mswindows_set_chord_timer (hwnd);
msframe->button2_need_rbutton = 1;
msframe->last_click_point = MAKEPOINTS (lParam);
+ msframe->last_click_mods = wParam;
}
msframe->last_click_time = GetMessageTime();
break;
KillTimer (hwnd, BUTTON_2_TIMER_ID);
msframe->button2_need_lbutton = 0;
msframe->button2_need_rbutton = 0;
- if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam)))
+ if (mswindows_button2_near_enough (msframe->last_click_point,
+ MAKEPOINTS (lParam)))
{
mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam
+ &~ (MK_LBUTTON | MK_MBUTTON
+ | MK_RBUTTON),
+ GetMessageTime());
msframe->button2_is_down = 1;
}
else
{
mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
- msframe->last_click_point, msframe->last_click_time);
+ msframe->last_click_point,
+ msframe->last_click_mods
+ &~ MK_LBUTTON,
+ msframe->last_click_time);
mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
- MAKEPOINTS (lParam), GetMessageTime());
+ MAKEPOINTS (lParam),
+ wParam &~ MK_RBUTTON,
+ GetMessageTime());
}
}
else
mswindows_set_chord_timer (hwnd);
msframe->button2_need_lbutton = 1;
msframe->last_click_point = MAKEPOINTS (lParam);
+ msframe->last_click_mods = wParam;
}
msframe->last_click_time = GetMessageTime();
break;
{
msframe->button2_need_lbutton = 0;
mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
- msframe->last_click_point, msframe->last_click_time);
+ msframe->last_click_point,
+ msframe->last_click_mods
+ &~ MK_RBUTTON,
+ msframe->last_click_time);
}
else if (msframe->button2_need_rbutton)
{
msframe->button2_need_rbutton = 0;
mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
- msframe->last_click_point, msframe->last_click_time);
+ msframe->last_click_point,
+ msframe->last_click_mods
+ &~ MK_LBUTTON,
+ msframe->last_click_time);
}
}
else
event->event_type = pointer_motion_event;
event->event.motion.x = MAKEPOINTS(lParam).x;
event->event.motion.y = MAKEPOINTS(lParam).y;
- event->event.motion.modifiers = mswindows_modifier_state (NULL, 0);
+ event->event.motion.modifiers =
+ mswindows_modifier_state (NULL, wParam, 0);
mswindows_enqueue_dispatch_event (emacs_event);
}
{
/* I think this is safe since the text will only go away
when the toolbar does...*/
- TO_EXTERNAL_FORMAT (LISP_STRING, btext,
- C_STRING_ALLOCA, tttext->lpszText,
- Qnative);
+ LISP_STRING_TO_EXTERNAL (btext, tttext->lpszText, Qnative);
}
#endif
}
shouldn't have received a paint message for it here. */
assert (wParam == 0);
- /* Can't queue a magic event because windows goes modal and sends paint
+ /* Can't queue a magic event because windows goes modal and sends paint
messages directly to the windows procedure when doing solid drags
and the message queue doesn't get processed. */
mswindows_handle_paint (XFRAME (mswindows_find_frame (hwnd)));
int delta = (short) HIWORD (wParam); /* Wheel rotation amount */
struct gcpro gcpro1, gcpro2;
- if (mswindows_handle_mousewheel_event (mswindows_find_frame (hwnd), keys, delta))
+ if (mswindows_handle_mousewheel_event (mswindows_find_frame (hwnd),
+ keys, delta,
+ MAKEPOINTS (lParam)))
{
GCPRO2 (emacs_event, fobj);
mswindows_pump_outstanding_events (); /* Can GC */
event->channel = mswindows_find_frame(hwnd);
event->timestamp = GetMessageTime();
event->event.misc.button = 1; /* #### Should try harder */
- event->event.misc.modifiers = mswindows_modifier_state (NULL, 0);
+ event->event.misc.modifiers = mswindows_modifier_state (NULL,
+ (DWORD) -1, 0);
event->event.misc.x = point.x;
event->event.misc.y = point.y;
event->event.misc.function = Qdragdrop_drop_dispatch;
if (CoCreateInstance (&CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, &IID_IShellLink, &psl) == S_OK)
- {
+ {
IPersistFile* ppf;
if (psl->lpVtbl->QueryInterface (psl, &IID_IPersistFile,
time when a key typed at autorepeat rate of 30 cps! */
static HKL last_hkl = 0;
static int last_hkl_has_AltGr;
+ HKL current_hkl = (HKL) -1;
- HKL current_hkl = GetKeyboardLayout (0);
+ if (xGetKeyboardLayout) /* not in NT 3.5 */
+ current_hkl = xGetKeyboardLayout (0);
if (current_hkl != last_hkl)
{
TCHAR c;
/* Returns the state of the modifier keys in the format expected by the
* Lisp_Event key_data, button_data and motion_data modifiers member */
static int
-mswindows_modifier_state (BYTE* keymap, int has_AltGr)
+mswindows_modifier_state (BYTE* keymap, DWORD fwKeys, int has_AltGr)
{
int mods = 0;
+ int keys_is_real = 0;
BYTE keymap2[256];
+ if (fwKeys == (DWORD) -1)
+ fwKeys = mswindows_last_mouse_button_state;
+ else
+ {
+ keys_is_real = 1;
+ mswindows_last_mouse_button_state = fwKeys;
+ }
+
if (keymap == NULL)
{
keymap = keymap2;
has_AltGr = mswindows_current_layout_has_AltGr ();
}
+ /* #### should look at fwKeys for MK_CONTROL. I don't understand how
+ AltGr works. */
if (has_AltGr && (keymap [VK_LCONTROL] & 0x80) && (keymap [VK_RMENU] & 0x80))
{
mods |= (keymap [VK_LMENU] & 0x80) ? XEMACS_MOD_META : 0;
mods |= (keymap [VK_CONTROL] & 0x80) ? XEMACS_MOD_CONTROL : 0;
}
- mods |= (keymap [VK_SHIFT] & 0x80) ? XEMACS_MOD_SHIFT : 0;
+ mods |= (keys_is_real ? fwKeys & MK_SHIFT : (keymap [VK_SHIFT] & 0x80))
+ ? XEMACS_MOD_SHIFT : 0;
+ mods |= fwKeys & MK_LBUTTON ? XEMACS_MOD_BUTTON1 : 0;
+ mods |= fwKeys & MK_MBUTTON ? XEMACS_MOD_BUTTON2 : 0;
+ mods |= fwKeys & MK_RBUTTON ? XEMACS_MOD_BUTTON3 : 0;
return mods;
}
* Translate a mswindows virtual key to a keysym.
* Only returns non-Qnil for keys that don't generate WM_CHAR messages
* or whose ASCII codes (like space) xemacs doesn't like.
- * Virtual key values are defined in winresrc.h
*/
Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods,
int extendedp)
{
switch (mswindows_key)
{
+ case VK_CANCEL: return KEYSYM ("pause");
case VK_RETURN: return KEYSYM ("kp-enter");
case VK_PRIOR: return KEYSYM ("prior");
case VK_NEXT: return KEYSYM ("next");
case VK_DOWN: return KEYSYM ("down");
case VK_INSERT: return KEYSYM ("insert");
case VK_DELETE: return QKdelete;
+#if 0 /* FSF Emacs allows these to return configurable syms/mods */
+ case VK_LWIN return KEYSYM ("");
+ case VK_RWIN return KEYSYM ("");
+#endif
+ case VK_APPS: return KEYSYM ("menu");
}
}
else
case '\n': return QKlinefeed;
case VK_CLEAR: return KEYSYM ("clear");
case VK_RETURN: return QKreturn;
+ case VK_PAUSE: return KEYSYM ("pause");
case VK_ESCAPE: return QKescape;
case VK_SPACE: return QKspace;
case VK_PRIOR: return KEYSYM ("kp-prior");
case VK_INSERT: return KEYSYM ("kp-insert");
case VK_DELETE: return KEYSYM ("kp-delete");
case VK_HELP: return KEYSYM ("help");
-#if 0 /* FSF Emacs allows these to return configurable syms/mods */
- case VK_LWIN return KEYSYM ("");
- case VK_RWIN return KEYSYM ("");
-#endif
- case VK_APPS: return KEYSYM ("menu");
case VK_NUMPAD0: return KEYSYM ("kp-0");
case VK_NUMPAD1: return KEYSYM ("kp-1");
case VK_NUMPAD2: return KEYSYM ("kp-2");
if (mswindows_in_modal_loop)
return;
- /* Drain windows queue. This sets up number of quit characters in
- the queue */
+ /* Drain windows queue. This sets up number of quit characters in
+ the queue. */
mswindows_drain_windows_queue ();
if (mswindows_quit_chars_count > 0)
{
emacs_event = mswindows_cancel_dispatch_event (&match_against);
assert (!NILP (emacs_event));
-
- if (XEVENT(emacs_event)->event.key.modifiers & XEMACS_MOD_SHIFT)
+
+ if (XEVENT (emacs_event)->event.key.modifiers &
+ FAKE_MOD_QUIT_CRITICAL)
critical_p = 1;
- Fdeallocate_event(emacs_event);
+ Fdeallocate_event (emacs_event);
}
Vquit_flag = critical_p ? Qcritical : Qt;
: HANDLE_TO_USID (get_ntpipe_input_stream_waitable (XLSTREAM (instream))));
}
+static int
+emacs_mswindows_current_event_timestamp (struct console *c)
+{
+ return GetTickCount ();
+}
+
#ifndef HAVE_X_WINDOWS
/* This is called from GC when a process object is about to be freed.
If we've still got pointers to it in this file, we're gonna lose hard.
mswindows_event_stream->create_stream_pair_cb = emacs_mswindows_create_stream_pair;
mswindows_event_stream->delete_stream_pair_cb = emacs_mswindows_delete_stream_pair;
#endif
+ mswindows_event_stream->current_event_timestamp_cb =
+ emacs_mswindows_current_event_timestamp;
}
void
mswindows_u_dispatch_event_queue = Qnil;
staticpro (&mswindows_u_dispatch_event_queue);
mswindows_u_dispatch_event_queue_tail = Qnil;
- pdump_wire (&mswindows_u_dispatch_event_queue_tail);
+ dump_add_root_object (&mswindows_u_dispatch_event_queue_tail);
mswindows_s_dispatch_event_queue = Qnil;
staticpro (&mswindows_s_dispatch_event_queue);
mswindows_s_dispatch_event_queue_tail = Qnil;
- pdump_wire (&mswindows_s_dispatch_event_queue_tail);
+ dump_add_root_object (&mswindows_s_dispatch_event_queue_tail);
mswindows_error_caught_in_modal_loop = Qnil;
staticpro (&mswindows_error_caught_in_modal_loop);
#ifdef DEBUG_XEMACS
- DEFVAR_INT ("mswindows-debug-events", &mswindows_debug_events /*
+ DEFVAR_INT ("debug-mswindows-events", &debug_mswindows_events /*
If non-zero, display debug information about Windows events that XEmacs sees.
Information is displayed in a console window. Currently defined values are:
#### Unfortunately, not yet implemented.
*/ );
- mswindows_debug_events = 0;
+ debug_mswindows_events = 0;
#endif
DEFVAR_BOOL ("mswindows-alt-by-itself-activates-menu",
{
init_slurp_stream ();
init_shove_stream ();
-#if defined (HAVE_SOCKETS) && !defined(HAVE_MSG_SELECT)
+#if defined (HAVE_SOCKETS) && !defined (HAVE_MSG_SELECT)
init_winsock_stream ();
#endif
}