#include "sysdep.h"
#include "objects-msw.h"
-#include "events-mod.h"
#ifdef HAVE_MSG_SELECT
#include "sysfile.h"
#include "console-tty.h"
/* 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
/* 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 debug_mswindows_events;
+Fixnum debug_mswindows_events;
#endif
/* This is the event signaled by the event pump.
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);
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);
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;
}
* 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
/* 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. */
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;
memcpy (keymap_sticky, keymap_orig, 256);
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,
|| 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
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 */
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;
{
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
}