#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
#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. */
+ (void) SwitchToThread ();
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 */
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.
+ /* 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 */
+ 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)
{
+ /* Not an XEmacs frame */
TranslateMessage (&msg);
}
else if (msg.message == WM_PAINT)
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;
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);
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
* 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 mswindows_frame* msframe;
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:
if (mswindows_debug_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 ();
}
}
if (should_set_keymap)
- // && (message != WM_SYSKEYUP
+ // && (message_ != WM_SYSKEYUP
// || NILP (Vmenu_accelerator_enabled)))
SetKeyboardState (keymap);
if (mswindows_debug_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 ();
}
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
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;
/* 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,
+ mswindows_enqueue_mouse_button_event (hwnd, message_,
MAKEPOINTS (lParam), GetMessageTime());
break;
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. */
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"))
{
}
#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);
}