Ultimately based on FSF.
Rewritten by Ben Wing.
Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
+ Subprocess and modal loop support by Kirill M. Katsnelson.
*/
#include <config.h>
#include "device.h"
#include "events.h"
#include "frame.h"
+#include "buffer.h"
+#include "faces.h"
#include "lstream.h"
#include "process.h"
#include "redisplay.h"
#include "syswait.h"
#include "systime.h"
#include "sysdep.h"
+#include "objects-msw.h"
#include "events-mod.h"
#ifdef HAVE_MSG_SELECT
#include "sysfile.h"
+#include "console-tty.h"
#elif defined(__CYGWIN32__)
typedef unsigned int SOCKET;
#endif
#include <io.h>
#include <errno.h>
+#if defined (__CYGWIN32__) && !defined (CYGWIN_VERSION_DLL_MAJOR)
+typedef NMHDR *LPNMHDR;
+#endif
+
#ifdef HAVE_MENUBARS
#define ADJR_MENUFLAG TRUE
#else
mswindows_get_toolbar_button_text (struct frame* f, int command_id);
extern Lisp_Object
mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id);
+extern Lisp_Object
+mswindows_handle_gui_wm_command (struct frame* f, HWND ctrl, WORD id);
static Lisp_Object mswindows_find_frame (HWND hwnd);
static Lisp_Object mswindows_find_console (HWND hwnd);
#ifdef HAVE_MSG_SELECT
extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask;
extern SELECT_TYPE process_only_mask, tty_only_mask;
+SELECT_TYPE zero_mask;
extern int signal_event_pipe_initialized;
int windows_fd;
#endif
/* The number of things we can wait on */
#define MAX_WAITABLE (MAXIMUM_WAIT_OBJECTS - 1)
+#ifndef HAVE_MSG_SELECT
/* List of mswindows waitable handles. */
static HANDLE mswindows_waitable_handles[MAX_WAITABLE];
/* Number of wait handles */
static int mswindows_waitable_count=0;
+#endif /* HAVE_MSG_SELECT */
+/* Brush for painting widgets */
+static HBRUSH widget_brush = 0;
+static LONG last_widget_brushed = 0;
/* Count of quit chars currently in the queue */
/* Incremented in WM_[SYS]KEYDOWN handler in the mswindows_wnd_proc()
/* This structure is allocated by the main thread, and is deallocated
in the thread upon exit. There are situations when a thread
remains blocked for a long time, much longer than the lstream
- exists. For exmaple, "start notepad" command is issued from the
+ exists. For example, "start notepad" command is issued from the
shell, then the shell is closed by C-c C-d. Although the shell
process exits, its output pipe will not get closed until the
notepad process exits also, because it inherits the pipe form the
sizeof (struct ntpipe_slurp_stream));
/* This function is thread-safe, and is called from either thread
- context. It serializes freeing shared dtata structure */
+ context. It serializes freeing shared data structure */
static void
slurper_free_shared_data_maybe (struct ntpipe_slurp_stream_shared_data* s)
{
if (s->die_p)
break;
- /* Block until the client finishes with retireving the rest of
+ /* Block until the client finishes with retrieving the rest of
pipe data */
WaitForSingleObject (s->hev_thread, INFINITE);
}
DEFINE_LSTREAM_IMPLEMENTATION ("ntpipe-output", lstream_ntpipe_shove,
sizeof (struct ntpipe_shove_stream));
+#ifndef HAVE_MSG_SELECT
static DWORD WINAPI
shove_thread (LPVOID vparam)
{
struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream);
return s->user_data;
}
+#endif
static int
ntpipe_shove_writer (Lstream *stream, const unsigned char *data, size_t size)
OVERLAPPED ov; /* Overlapped I/O structure */
void* buffer; /* Buffer. Allocated for input stream only */
unsigned int bufsize; /* Number of bytes last read */
- unsigned int bufpos; /* Psition in buffer for next fetch */
+ unsigned int bufpos; /* Position in buffer for next fetch */
unsigned int error_p :1; /* I/O Error seen */
unsigned int eof_p :1; /* EOF Error seen */
unsigned int pending_p :1; /* There is a pending I/O operation */
{
ResetEvent (str->ov.hEvent);
-
- if (WriteFile ((HANDLE)str->s, data, size, NULL, &str->ov)
+
+ /* Docs indicate that 4th parameter to WriteFile can be NULL since this is
+ * an overlapped operation. This fails on Win95 with winsock 1.x so we
+ * supply a spare address which is ignored by Win95 anyway. Sheesh. */
+ if (WriteFile ((HANDLE)str->s, data, size, (LPDWORD)&str->buffer, &str->ov)
|| GetLastError() == ERROR_IO_PENDING)
str->pending_p = 1;
else
{
event->event_type = button_press_event;
SetCapture (hwnd);
+ /* we need this to make sure the main window regains the focus
+ from control subwindows */
+ if (GetFocus() != hwnd)
+ {
+ SetFocus (hwnd);
+ mswindows_enqueue_magic_event (hwnd, WM_SETFOCUS);
+ }
}
else
{
/*
* Remove and return the first emacs event on the dispatch queue that matches
- * the supplied event
- * Timeout event matches if interval_id equals to that of the given event.
+ * the supplied event.
+ * Timeout event matches if interval_id is equal to that of the given event.
* Keypress event matches if logical AND between modifiers bitmask of the
- * event in the queue and that of the given event is non-zero
- * For all other event types, this function asserts.
+ * event in the queue and that of the given event is non-zero.
+ * For all other event types, this function aborts.
*/
Lisp_Object
-mswindows_cancel_dispatch_event (struct Lisp_Event* match)
+mswindows_cancel_dispatch_event (struct Lisp_Event *match)
{
Lisp_Object event;
- Lisp_Object previous_event=Qnil;
+ Lisp_Object previous_event = Qnil;
int user_p = mswindows_user_event_p (match);
Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue :
&mswindows_s_dispatch_event_queue;
EVENT_CHAIN_LOOP (event, *head)
{
- int found = 1;
- if (XEVENT_TYPE (event) != match->event_type)
- found = 0;
- if (found && match->event_type == timeout_event
- && (XEVENT(event)->event.timeout.interval_id !=
- match->event.timeout.interval_id))
- found = 0;
- if (found && match->event_type == key_press_event
- && ((XEVENT(event)->event.key.modifiers &
- match->event.key.modifiers) == 0))
- found = 0;
-
- if (found)
+ struct Lisp_Event *e = XEVENT (event);
+ if ((e->event_type == match->event_type) &&
+ ((e->event_type == timeout_event) ?
+ (e->event.timeout.interval_id == match->event.timeout.interval_id) :
+ /* Must be key_press_event */
+ ((e->event.key.modifiers & match->event.key.modifiers) != 0)))
{
if (NILP (previous_event))
dequeue_event (head, tail);
return Qnil;
}
\f
+#ifndef HAVE_MSG_SELECT
/************************************************************************/
/* Waitable handles manipulation */
/************************************************************************/
mswindows_waitable_handles [ix] =
mswindows_waitable_handles [--mswindows_waitable_count];
}
+#endif /* HAVE_MSG_SELECT */
\f
/************************************************************************/
* neither are waitable handles checked. The function pumps
* thus only dispatch events already queued, as well as those
* resulted in dispatching thereof. This is done by setting
- * module local variable mswidows_in_modal_loop to nonzero.
+ * module local variable mswindows_in_modal_loop to nonzero.
*
* Return value is Qt if no errors was trapped, or Qunbound if
* there was an error.
* If the value of mswindows_error_caught_in_modal_loop is not
* nil already upon entry, the function just returns non-nil.
* This situation means that a new event has been queued while
- * cancleng mode. The event will be dequeued on the next regular
+ * in cancel mode. The event will be dequeued on the next regular
* call of next-event; the pump is off since error is caught.
* The caller must *unconditionally* cancel modal loop if the
* value returned by this function is nil. Otherwise, everything
MSG msg;
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
+ /* we have to translate messages that are not sent to the main
+ window. this is so that key presses work ok in things like
+ edit fields. however, we *musn't* translate message for the
+ main window as this is handled in the wnd proc. */
+ if ( GetWindowLong (msg.hwnd, GWL_STYLE) & WS_CHILD )
+ {
+ TranslateMessage (&msg);
+ }
DispatchMessage (&msg);
mswindows_unmodalize_signal_maybe ();
}
}
/*
- * This is a special flavour of the mswindows_need_event function,
+ * This is a special flavor of the mswindows_need_event function,
* used while in event pump. Actually, there is only kind of events
* allowed while in event pump: a timer. An attempt to fetch any
- * other event leads to a dealock, as there's no source of user input
+ * other event leads to a deadlock, as there's no source of user input
* ('cause event pump mirrors windows modal loop, which is a sole
* owner of thread message queue).
*
EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block);
pointer_to_this = &select_time_to_block;
}
+
active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this);
if (active == 0)
{
+ assert (!badly_p);
return; /* timeout */
}
else if (active > 0)
{
mswindows_drain_windows_queue ();
}
-
+#ifdef HAVE_TTY
+ /* Look for a TTY event */
+ for (i = 0; i < MAXDESC-1; i++)
+ {
+ /* To avoid race conditions (among other things, an infinite
+ loop when called from Fdiscard_input()), we must return
+ user events ahead of process events. */
+ if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &tty_only_mask))
+ {
+ struct console *c = tty_find_console_from_fd (i);
+ Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
+ struct Lisp_Event* event = XEVENT (emacs_event);
+
+ assert (c);
+ if (read_event_from_tty_or_stream_desc (event, c, i))
+ {
+ mswindows_enqueue_dispatch_event (emacs_event);
+ return;
+ }
+ }
+ }
+#endif
/* Look for a process event */
for (i = 0; i < MAXDESC-1; i++)
{
mswindows_enqueue_process_event (p);
}
- else if (FD_ISSET (i, &tty_only_mask))
- {
- /* do we care about tty events? Do we
- ever get tty events? */
- }
else
{
/* We might get here when a fake event came
{
if (errno != EINTR)
{
- /* something bad happended */
+ /* something bad happened */
assert(0);
}
}
else
{
int ix = active - WAIT_OBJECT_0;
- /* First, try to find which process' ouptut has signaled */
+ /* First, try to find which process' output has signaled */
struct Lisp_Process *p =
get_process_from_usid (HANDLE_TO_USID (mswindows_waitable_handles[ix]));
if (p != NULL)
else
{
/* None. This means that the process handle itself has signaled.
- Remove the handle from the wait vector, and make status_ntoify
+ Remove the handle from the wait vector, and make status_notify
note the exited process */
mswindows_waitable_handles [ix] =
mswindows_waitable_handles [--mswindows_waitable_count];
event->timestamp = dwtime;
event->event_type = timeout_event;
event->event.timeout.interval_id = id_timer;
+ event->event.timeout.function = Qnil;
+ event->event.timeout.object = Qnil;
mswindows_enqueue_dispatch_event (emacs_event);
}
LRESULT WINAPI
mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
- /* Note: Remember to initialise emacs_event and event before use.
+ /* Note: Remember to initialize emacs_event and event before use.
This code calls code that can GC. You must GCPRO before calling such code. */
Lisp_Object emacs_event = Qnil;
Lisp_Object fobj = Qnil;
mswindows_enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt));
break;
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ /* See Win95 comment under WM_KEYDOWN */
+ {
+ BYTE keymap[256];
+
+ if (wParam == VK_CONTROL)
+ {
+ GetKeyboardState (keymap);
+ keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] &= ~0x80;
+ SetKeyboardState (keymap);
+ }
+ else if (wParam == VK_MENU)
+ {
+ GetKeyboardState (keymap);
+ keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80;
+ SetKeyboardState (keymap);
+ }
+ };
+ goto defproc;
+
case WM_KEYDOWN:
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.
+ * 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,
+ * it translates as if AltGr were down.
+ * We get round this by removing all modifiers from the keymap before
+ * calling TranslateMessage() unless AltGr is *really* down. */
{
BYTE keymap[256];
int has_AltGr = mswindows_current_layout_has_AltGr ();
GetKeyboardState (keymap);
mods = mswindows_modifier_state (keymap, has_AltGr);
- /* Handle those keys that TranslateMessage won't generate a WM_CHAR for */
+ /* Handle those keys for which TranslateMessage won't generate a WM_CHAR */
if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods)))
mswindows_enqueue_keypress_event (hwnd, keysym, mods);
else
{
int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
BYTE keymap_orig[256];
- MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) };
+ POINT pnt = { LOWORD (GetMessagePos()), HIWORD (GetMessagePos()) };
+ MSG msg;
+
+ msg.hwnd = hwnd;
+ msg.message = message;
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ msg.time = GetMessageTime();
+ msg.pt = pnt;
+
+ /* GetKeyboardState() does not work as documented on Win95. We have
+ * to loosely track Left and Right modifiers on behalf of the OS,
+ * without screwing up Windows NT which tracks them properly. */
+ if (wParam == VK_CONTROL)
+ keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] |= 0x80;
+ else if (wParam == VK_MENU)
+ keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] |= 0x80;
+
memcpy (keymap_orig, keymap, 256);
/* Remove shift modifier from an ascii character */
mods &= ~MOD_SHIFT;
- /* Clear control and alt modifiers out of the keymap */
+ /* Clear control and alt modifiers unless AltGr is pressed */
keymap [VK_RCONTROL] = 0;
keymap [VK_LMENU] = 0;
if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80))
}
SetKeyboardState (keymap);
- /* Have some WM_[SYS]CHARS in the queue */
+ /* Maybe generate some WM_[SYS]CHARs in the queue */
TranslateMessage (&msg);
while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE)
break;
case WM_MOUSEMOVE:
- /* Optimization: don't report mouse movement while size is changind */
+ /* Optimization: don't report mouse movement while size is changing */
msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
if (!msframe->sizing)
{
/* When waiting for the second mouse button to finish
button2 emulation, and have moved too far, just pretend
- as if timer has expired. This impoves drag-select feedback */
+ as if timer has expired. This improves drag-select feedback */
if ((msframe->button2_need_lbutton || msframe->button2_need_rbutton)
&& !mswindows_button2_near_enough (msframe->last_click_point,
MAKEPOINTS (lParam)))
Qcancel_mode_internal, Qnil);
break;
-#ifdef HAVE_TOOLBARS
case WM_NOTIFY:
{
- LPTOOLTIPTEXT tttext = (LPTOOLTIPTEXT)lParam;
- Lisp_Object btext;
- if (tttext->hdr.code == TTN_NEEDTEXT)
+ LPNMHDR nmhdr = (LPNMHDR)lParam;
+
+ if (nmhdr->code == TTN_NEEDTEXT)
{
+#ifdef HAVE_TOOLBARS
+ LPTOOLTIPTEXT tttext = (LPTOOLTIPTEXT)lParam;
+ Lisp_Object btext;
+
/* find out which toolbar */
frame = XFRAME (mswindows_find_frame (hwnd));
btext = mswindows_get_toolbar_button_text ( frame,
- tttext->hdr.idFrom );
+ nmhdr->idFrom );
tttext->lpszText = NULL;
tttext->hinst = NULL;
{
/* I think this is safe since the text will only go away
when the toolbar does...*/
- tttext->lpszText=XSTRING_DATA (btext);
+ GET_C_STRING_EXT_DATA_ALLOCA (btext, FORMAT_OS,
+ tttext->lpszText);
}
-#if 0
- tttext->uFlags |= TTF_DI_SETITEM;
#endif
- }
+ }
+ /* handle tree view callbacks */
+ else if (nmhdr->code == TVN_SELCHANGED)
+ {
+ NM_TREEVIEW* ptree = (NM_TREEVIEW*)lParam;
+ frame = XFRAME (mswindows_find_frame (hwnd));
+ mswindows_handle_gui_wm_command (frame, 0, ptree->itemNew.lParam);
+ }
+ /* handle tab control callbacks */
+ else if (nmhdr->code == TCN_SELCHANGE)
+ {
+ TC_ITEM item;
+ int index = SendMessage (nmhdr->hwndFrom, TCM_GETCURSEL, 0, 0);
+ frame = XFRAME (mswindows_find_frame (hwnd));
+
+ item.mask = TCIF_PARAM;
+ SendMessage (nmhdr->hwndFrom, TCM_GETITEM, (WPARAM)index,
+ (LPARAM)&item);
+
+ mswindows_handle_gui_wm_command (frame, 0, item.lParam);
+ }
}
break;
-#endif
case WM_PAINT:
{
case WM_COMMAND:
{
WORD id = LOWORD (wParam);
+ WORD nid = HIWORD (wParam);
HWND cid = (HWND)lParam;
frame = XFRAME (mswindows_find_frame (hwnd));
if (!NILP (mswindows_handle_toolbar_wm_command (frame, cid, id)))
break;
#endif
-
+ /* widgets in a buffer only eval a callback for suitable events.*/
+ switch (nid)
+ {
+ case BN_CLICKED:
+ case EN_CHANGE:
+ case CBN_EDITCHANGE:
+ case CBN_SELCHANGE:
+ if (!NILP (mswindows_handle_gui_wm_command (frame, cid, id)))
+ return 0;
+ }
+ /* menubars always must come last since the hashtables do not
+ always exist*/
#ifdef HAVE_MENUBARS
if (!NILP (mswindows_handle_wm_command (frame, id)))
break;
#endif
- /* Bite me - a spurious command. This cannot happen. */
- error ("XEMACS BUG: Cannot decode command message");
+ return DefWindowProc (hwnd, message, wParam, lParam);
+ /* Bite me - a spurious command. This used to not be able to
+ happen but with the introduction of widgets its now
+ possible. */
}
break;
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORSTATIC:
+ case WM_CTLCOLORSCROLLBAR:
+ {
+ /* if we get an opportunity to paint a widget then do so if
+ there is an appropriate face */
+ HWND crtlwnd = (HWND)lParam;
+ LONG ii = GetWindowLong (crtlwnd, GWL_USERDATA);
+ if (ii)
+ {
+ Lisp_Object image_instance;
+ VOID_TO_LISP (image_instance, ii);
+ if (IMAGE_INSTANCEP (image_instance)
+ &&
+ IMAGE_INSTANCE_TYPE_P (image_instance, IMAGE_WIDGET)
+ &&
+ !NILP (XIMAGE_INSTANCE_WIDGET_FACE (image_instance)))
+ {
+ /* set colors for the buttons */
+ HDC hdc = (HDC)wParam;
+ if (last_widget_brushed != ii)
+ {
+ if (widget_brush)
+ DeleteObject (widget_brush);
+ widget_brush = CreateSolidBrush
+ (COLOR_INSTANCE_MSWINDOWS_COLOR
+ (XCOLOR_INSTANCE
+ (FACE_BACKGROUND
+ (XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
+ XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance)))));
+ }
+ last_widget_brushed = ii;
+ SetTextColor
+ (hdc,
+ COLOR_INSTANCE_MSWINDOWS_COLOR
+ (XCOLOR_INSTANCE
+ (FACE_FOREGROUND
+ (XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
+ XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance)))));
+ SetBkMode (hdc, OPAQUE);
+ SetBkColor
+ (hdc,
+ COLOR_INSTANCE_MSWINDOWS_COLOR
+ (XCOLOR_INSTANCE
+ (FACE_BACKGROUND
+ (XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
+ XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance)))));
+ return (LRESULT)widget_brush;
+ }
+ }
+ }
+ goto defproc;
+
#ifdef HAVE_DRAGNDROP
case WM_DROPFILES: /* implementation ripped-off from event-Xt.c */
{
mswindows_need_event (1);
- event = mswindows_dequeue_dispatch_event (!NILP(mswindows_u_dispatch_event_queue));
+ event = mswindows_dequeue_dispatch_event ();
XSETEVENT (event2, emacs_event);
Fcopy_event (event, event2);
Fdeallocate_event (event);
}
}
+#ifndef HAVE_MSG_SELECT
static HANDLE
get_process_input_waitable (struct Lisp_Process *process)
{
HANDLE hev = get_process_input_waitable (process);
remove_waitable_handle (hev);
}
+#endif /* HAVE_MSG_SELECT */
static void
emacs_mswindows_select_console (struct console *con)
{
+#ifdef HAVE_MSG_SELECT
+ if (CONSOLE_MSWINDOWS_P (con))
+ return; /* mswindows consoles are automatically selected */
+
+ event_stream_unixoid_select_console (con);
+#endif
}
static void
emacs_mswindows_unselect_console (struct console *con)
{
+#ifdef HAVE_MSG_SELECT
+ if (CONSOLE_MSWINDOWS_P (con))
+ return; /* mswindows consoles are automatically selected */
+
+ event_stream_unixoid_unselect_console (con);
+#endif
}
static void
emacs_mswindows_quit_p (void)
{
+ MSG msg;
+
/* Quit cannot happen in modal loop: all program
input is dedicated to Windows. */
if (mswindows_in_modal_loop)
return;
- /* Drain windows queue. This sets up number of quit
- characters in in the queue */
- mswindows_drain_windows_queue ();
+ /* Drain windows queue. This sets up number of quit characters in the queue
+ * (and also processes wm focus change, move, resize, etc messages).
+ * We don't want to process WM_PAINT messages because this function can be
+ * called from almost anywhere and the windows' states may be changing. */
+ while (PeekMessage (&msg, NULL, 0, WM_PAINT-1, PM_REMOVE) ||
+ PeekMessage (&msg, NULL, WM_PAINT+1, WM_USER-1, PM_REMOVE))
+ DispatchMessage (&msg);
if (mswindows_quit_chars_count > 0)
{
DEFVAR_INT ("mswindows-mouse-button-max-skew-x", &mswindows_mouse_button_max_skew_x /*
*Maximum horizontal distance in pixels between points in which left and
-right button clicks occured for them to be translated into single
+right button clicks occurred for them to be translated into single
middle button event. Clicks must occur in time not longer than defined
by the variable `mswindows-mouse-button-tolerance'.
If negative or zero, currently set system default is used instead.
DEFVAR_INT ("mswindows-mouse-button-max-skew-y", &mswindows_mouse_button_max_skew_y /*
*Maximum vertical distance in pixels between points in which left and
-right button clicks occured for them to be translated into single
+right button clicks occurred for them to be translated into single
middle button event. Clicks must occur in time not longer than defined
by the variable `mswindows-mouse-button-tolerance'.
If negative or zero, currently set system default is used instead.
windows_fd = open("/dev/windows", O_RDONLY | O_NONBLOCK, 0);
assert (windows_fd>=0);
FD_SET (windows_fd, &input_wait_mask);
- /* for some reason I get blocks on the signal event pipe, which is
- bad...
- signal_event_pipe_initialized = 0; */
+ FD_ZERO(&zero_mask);
#endif
event_stream = mswindows_event_stream;