#ifdef HAVE_MSG_SELECT
#include "sysfile.h"
#include "console-tty.h"
-#elif defined(__CYGWIN32__)
+#elif defined(CYGWIN)
typedef unsigned int SOCKET;
#endif
#include <io.h>
#include <errno.h>
-#if !(defined(__CYGWIN32__) || defined(__MINGW32__))
+#if !(defined(CYGWIN) || defined(MINGW))
# include <shlobj.h> /* For IShellLink */
#endif
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);
int mswindows_mouse_button_tolerance;
#ifdef DEBUG_XEMACS
-int mswindows_debug_events;
+int 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 */
#define NTPIPE_SHOVE_STREAM_DATA(stream) \
LSTREAM_TYPE_DATA (stream, ntpipe_shove)
-#define MAX_SHOVE_BUFFER_SIZE 128
+#define MAX_SHOVE_BUFFER_SIZE 512
struct ntpipe_shove_stream
{
InterlockedIncrement (&s->idle_p);
WaitForSingleObject (s->hev_thread, INFINITE);
- if (s->die_p)
- break;
-
- /* Write passed buffer */
- if (!WriteFile (s->hpipe, s->buffer, s->size, &bytes_written, NULL)
- || bytes_written != s->size)
+ /* Write passed buffer if any */
+ if (s->size > 0)
{
- s->error_p = TRUE;
- InterlockedIncrement (&s->die_p);
+ if (!WriteFile (s->hpipe, s->buffer, s->size, &bytes_written, NULL)
+ || bytes_written != s->size)
+ {
+ s->error_p = TRUE;
+ InterlockedIncrement (&s->die_p);
+ }
+ /* Set size to zero so we won't write it again if the closer sets
+ die_p and kicks us */
+ s->size = 0;
}
if (s->die_p)
return Qnil;
}
+ /* Set the priority of the thread higher so we don't end up waiting
+ on it to send things. */
+ if (!SetThreadPriority (s->hthread, THREAD_PRIORITY_HIGHEST))
+ {
+ CloseHandle (s->hthread);
+ Lstream_delete (lstr);
+ return Qnil;
+ }
+
/* hev_thread is an auto-reset event, initially nonsignaled */
s->hev_thread = CreateEvent (NULL, FALSE, FALSE, NULL);
/* Start output */
InterlockedDecrement (&s->idle_p);
SetEvent (s->hev_thread);
+ /* Give it a chance to run -- this dramatically improves performance
+ of things like crypt. */
+ if (xSwitchToThread) /* not in Win9x or NT 3.51 */
+ (void) xSwitchToThread ();
return size;
}
/* Force thread stop */
InterlockedIncrement (&s->die_p);
- /* Close pipe handle, possibly breaking it */
- CloseHandle (s->hpipe);
-
- /* Thread will end upon unblocking */
+ /* Thread will end upon unblocking. If it's already unblocked this will
+ do nothing, but the thread won't look at die_p until it's written any
+ pending output. */
SetEvent (s->hev_thread);
/* Wait while thread terminates */
WaitForSingleObject (s->hthread, INFINITE);
+
+ /* Close pipe handle, possibly breaking it */
+ CloseHandle (s->hpipe);
+
+ /* Close the thread handle */
CloseHandle (s->hthread);
/* Destroy the event */
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)
{
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.
+ 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
+ frames as this is handled in the wnd proc.
We also have to avoid generating paint magic events for windows
that aren't XEmacs frames */
- if (GetWindowLong (msg.hwnd, GWL_STYLE) & (WS_CHILD|WS_POPUP))
+ /* 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 */
+
+ GetClassName (msg.hwnd, class_name_buf, sizeof (class_name_buf) - 1);
+ if (stricmp (class_name_buf, XEMACS_CLASS) != 0)
{
+ /* Not an XEmacs frame */
TranslateMessage (&msg);
}
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);
/* Queue a magic event for handling when safe */
- msframe = FRAME_MSWINDOWS_DATA (
- XFRAME (mswindows_find_frame (msg.hwnd)));
+ msframe =
+ FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (msg.hwnd)));
if (!msframe->paint_pending)
{
msframe->paint_pending = 1;
{
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
if (*end)
return DDE_FNOTPROCESSED;
-#ifdef __CYGWIN32__
+#ifdef CYGWIN
filename = alloca (cygwin32_win32_to_posix_path_list_buf_size (cmd) + 5);
strcpy (filename, "file:");
cygwin32_win32_to_posix_path_list (cmd, filename+5);
}
/*
- * 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
This means that we need to distinguish between an
auto-repeated key and a key pressed and released a bunch
of times. */
- else if (downp && !keyp ||
+ else if ((downp && !keyp) ||
(downp && keyp && last_downkey &&
(wParam != last_downkey ||
/* the "previous key state" bit indicates autorepeat */
} \
} while (0)
- if (wParam == VK_CONTROL && (lParam & 0x1000000)
+ if ((wParam == VK_CONTROL && (lParam & 0x1000000))
|| wParam == VK_RCONTROL)
FROB (XEMSW_RCONTROL);
- if (wParam == VK_CONTROL && !(lParam & 0x1000000)
+ if ((wParam == VK_CONTROL && !(lParam & 0x1000000))
|| wParam == VK_LCONTROL)
FROB (XEMSW_LCONTROL);
- if (wParam == VK_SHIFT && (lParam & 0x1000000)
+ if ((wParam == VK_SHIFT && (lParam & 0x1000000))
|| wParam == VK_RSHIFT)
FROB (XEMSW_RSHIFT);
- if (wParam == VK_SHIFT && !(lParam & 0x1000000)
+ if ((wParam == VK_SHIFT && !(lParam & 0x1000000))
|| wParam == VK_LSHIFT)
FROB (XEMSW_LSHIFT);
- if (wParam == VK_MENU && (lParam & 0x1000000)
+ if ((wParam == VK_MENU && (lParam & 0x1000000))
|| wParam == VK_RMENU)
FROB (XEMSW_RMENU);
- if (wParam == VK_MENU && !(lParam & 0x1000000)
+ if ((wParam == VK_MENU && !(lParam & 0x1000000))
|| wParam == VK_LMENU)
FROB (XEMSW_LMENU);
}
#ifdef DEBUG_XEMACS
+#if 0
+
static void
output_modifier_keyboard_state (void)
{
keymap[VK_RSHIFT] & 0x1 ? 1 : 0);
}
+#endif
+
/* try to debug the stuck-alt-key problem.
#### this happens only inconsistently, and may only happen when using
/* asyncstate[2] & 0x1 ? 1 : 0); */
}
-#endif /* DEBUG_XEMACS */
+#endif /* DEBUG_XEMACS */
/*
* The windows procedure for the window class XEMACS_CLASS
*/
LRESULT WINAPI
-mswindows_wnd_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+mswindows_wnd_proc (HWND hwnd, UINT message_, WPARAM wParam, LPARAM lParam)
{
/* Note: Remember to initialize emacs_event and event before use.
This code calls code that can GC. You must GCPRO before calling such code. */
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)
+ switch (message_)
{
case WM_DESTROYCLIPBOARD:
/* We own the clipboard and someone else wants it. Delete our
cached copy of the clipboard contents so we'll ask for it from
- Windows again when someone does a paste. */
- handle_selection_clear(QCLIPBOARD);
+ Windows again when someone does a paste, and destroy any memory
+ objects we hold on the clipboard that are not in the list of types
+ that Windows will delete itself. */
+ mswindows_destroy_selection (QCLIPBOARD);
+ handle_selection_clear (QCLIPBOARD);
break;
case WM_ERASEBKGND:
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",
+ 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)
}
if (should_set_keymap)
- // && (message != WM_SYSKEYUP
+ // && (message_ != WM_SYSKEYUP
// || NILP (Vmenu_accelerator_enabled)))
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,
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",
+ 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));
GetKeyboardState (keymap_sticky);
if (keymap_sticky[VK_MENU] & 0x80)
{
- message = WM_SYSKEYDOWN;
+ message_ = WM_SYSKEYDOWN;
/* We have to set the "context bit" so that the
TranslateMessage() call below that generates the
SYSCHAR message does its thing; see the documentation
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);
/* 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.message = message_;
msg.wParam = wParam;
msg.lParam = lParam;
msg.time = GetMessageTime();
}
if (!NILP (Vmenu_accelerator_enabled) &&
- !(mods & XEMACS_MOD_SHIFT) && message == WM_SYSKEYDOWN)
+ !(mods & XEMACS_MOD_SHIFT) && message_ == WM_SYSKEYDOWN)
potential_accelerator = 1;
/* Remove shift modifier from an ascii character */
++mswindows_quit_chars_count;
}
else if (potential_accelerator && !got_accelerator &&
- msw_char_is_accelerator (frame, ch))
+ mswindows_char_is_accelerator (frame, ch))
{
got_accelerator = 1;
break;
/* 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);
/* Real middle mouse button has nothing to do with emulated one:
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());
+ mswindows_enqueue_mouse_button_event (hwnd, message_,
+ 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)));
case WM_DISPLAYCHANGE:
{
struct device *d;
+ DWORD message_tick = GetMessageTime ();
fobj = mswindows_find_frame (hwnd);
frame = XFRAME (fobj);
d = XDEVICE (FRAME_DEVICE (frame));
- DEVICE_MSWINDOWS_HORZRES(d) = LOWORD (lParam);
- DEVICE_MSWINDOWS_VERTRES(d) = HIWORD (lParam);
- DEVICE_MSWINDOWS_BITSPIXEL(d) = wParam;
- break;
+ /* Do this only once per message. XEmacs can receive this message
+ through as many frames as it currently has open. Message time
+ will be the same for all these messages. Despite extreme
+ efficiency, the code below has about one in 4 billion
+ probability that the HDC is not recreated, provided that
+ XEmacs is running sufficiently longer than 52 days. */
+ if (DEVICE_MSWINDOWS_UPDATE_TICK(d) != message_tick)
+ {
+ DEVICE_MSWINDOWS_UPDATE_TICK(d) = message_tick;
+ DeleteDC (DEVICE_MSWINDOWS_HCDC(d));
+ DEVICE_MSWINDOWS_HCDC(d) = CreateCompatibleDC (NULL);
+ }
}
+ break;
/* Misc magic events which only require that the frame be identified */
case WM_SETFOCUS:
case WM_KILLFOCUS:
- mswindows_enqueue_magic_event (hwnd, message);
+ mswindows_enqueue_magic_event (hwnd, message_);
break;
case WM_WINDOWPOSCHANGING:
break;
#endif
- return DefWindowProc (hwnd, message, wParam, lParam);
+ 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. */
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;
DragQueryFile ((HANDLE) wParam, i, fname, len+1);
/* May be a shell link aka "shortcut" - replace fname if so */
-#if !(defined(__CYGWIN32__) || defined(__MINGW32__))
+#if !(defined(CYGWIN) || defined(MINGW))
/* cygwin doesn't define this COM stuff */
if (!stricmp (fname + strlen (fname) - 4, ".LNK"))
{
if (CoCreateInstance (&CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, &IID_IShellLink, &psl) == S_OK)
- {
+ {
IPersistFile* ppf;
if (psl->lpVtbl->QueryInterface (psl, &IID_IPersistFile,
}
#endif
-#ifdef __CYGWIN32__
+#ifdef CYGWIN
filename = xmalloc (cygwin32_win32_to_posix_path_list_buf_size (fname) + 5);
strcpy (filename, "file:");
cygwin32_win32_to_posix_path_list (fname, filename+5);
defproc:
default:
- return DefWindowProc (hwnd, message, wParam, lParam);
+ return DefWindowProc (hwnd, message_, wParam, lParam);
}
return (0);
}
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");
{
emacs_event = mswindows_cancel_dispatch_event (&match_against);
assert (!NILP (emacs_event));
-
+
if (XEVENT(emacs_event)->event.key.modifiers & XEMACS_MOD_SHIFT)
critical_p = 1;
: 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",