# include "dragdrop.h"
#endif
+#include "buffer.h"
#include "device.h"
#include "events.h"
-#include "frame.h"
-#include "buffer.h"
#include "faces.h"
+#include "frame.h"
#include "lstream.h"
+#include "objects-msw.h"
#include "process.h"
#include "redisplay.h"
#include "select.h"
+#include "sysdep.h"
#include "window.h"
+
+#include "sysfile.h"
#include "sysproc.h"
-#include "syswait.h"
#include "systime.h"
-#include "sysdep.h"
-#include "objects-msw.h"
+#include "syswait.h"
#include "events-mod.h"
+
#ifdef HAVE_MSG_SELECT
-#include "sysfile.h"
#include "console-tty.h"
#elif defined(CYGWIN)
typedef unsigned int SOCKET;
#endif
-#include <io.h>
-#include <errno.h>
#if !(defined(CYGWIN) || defined(MINGW))
# include <shlobj.h> /* For IShellLink */
#ifdef DEBUG_XEMACS
Fixnum debug_mswindows_events;
+
+static void debug_output_mswin_message (HWND hwnd, UINT message_,
+ WPARAM wParam, LPARAM lParam);
#endif
/* This is the event signaled by the event pump.
LPARAM user_data; /* Any user data stored in the stream object */
SOCKET s; /* Socket handle (which is a Win32 handle) */
OVERLAPPED ov; /* Overlapped I/O structure */
- void* buffer; /* Buffer. Allocated for input stream only */
+ void* buffer; /* Buffer. */
unsigned long bufsize; /* Number of bytes last read */
unsigned long bufpos; /* Position in buffer for next fetch */
unsigned int error_p :1; /* I/O Error seen */
if (size == 0)
return 0;
- {
- ResetEvent (str->ov.hEvent);
-
- /* 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
- str->error_p = 1;
- }
+ ResetEvent (str->ov.hEvent);
+
+ /* According to WriteFile docs, we must hold onto the data we pass to it
+ and not make any changes until it finishes -- which may not be until
+ the next time we get here, since we use asynchronous I/O. We have
+ in fact seen data loss as a result of not doing this. */
+ str->buffer = xrealloc (str->buffer, size);
+ memcpy (str->buffer, data, size);
+
+ /* According to MSDN WriteFile docs, the fourth parameter cannot be NULL
+ on Win95 even when doing an overlapped operation, as we are, where
+ the return value through that parameter is not meaningful. */
+ if (WriteFile ((HANDLE)str->s, str->buffer, size, &str->bufsize,
+ &str->ov)
+ || GetLastError() == ERROR_IO_PENDING)
+ str->pending_p = 1;
+ else
+ str->error_p = 1;
return str->error_p ? -1 : size;
}
if (str->pending_p)
WaitForSingleObject (str->ov.hEvent, INFINITE);
- if (lstr->flags & LSTREAM_FL_READ)
- xfree (str->buffer);
+ if (str->buffer)
+ {
+ xfree (str->buffer);
+ str->buffer = 0;
+ }
CloseHandle (str->ov.hEvent);
return 0;
Lstream *lstr = Lstream_new (lstream_winsock, mode);
struct winsock_stream *str = WINSOCK_STREAM_DATA (lstr);
+ xzero (*str);
str->s = s;
- str->blocking_p = 0;
- str->error_p = 0;
- str->eof_p = 0;
- str->pending_p = 0;
str->user_data = param;
- xzero (str->ov);
str->ov.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
if (lstr->flags & LSTREAM_FL_READ)
&mswindows_s_dispatch_event_queue_tail :
&mswindows_u_dispatch_event_queue_tail);
- sevt = XEVENT(event);
+ sevt = XEVENT (event);
if (sevt->event_type == key_press_event
&& (sevt->event.key.modifiers & FAKE_MOD_QUIT))
- {
- sevt->event.key.modifiers &=
- ~(FAKE_MOD_QUIT | FAKE_MOD_QUIT_CRITICAL);
- --mswindows_quit_chars_count;
- }
+ sevt->event.key.modifiers &=
+ ~(FAKE_MOD_QUIT | FAKE_MOD_QUIT_CRITICAL);
return event;
}
return DDE_FNOTPROCESSED;
#ifdef CYGWIN
- filename = alloca (cygwin32_win32_to_posix_path_list_buf_size (cmd) + 5);
+ filename = alloca (cygwin_win32_to_posix_path_list_buf_size (cmd) + 5);
strcpy (filename, "file:");
- cygwin32_win32_to_posix_path_list (cmd, filename+5);
+ cygwin_win32_to_posix_path_list (cmd, filename+5);
#else
dostounix_filename (cmd);
filename = alloca (strlen (cmd)+6);
/* Not perfect but avoids crashes. There is potential for wierd
behavior here. */
if (gc_in_progress)
- goto defproc;
+ {
+ mswindows_output_console_string ("Window procedure called during GC???????\n", 41);
+ /* Yes, this assert always triggers in a --debug XEmacs. But
+ --debug=no is default in the stable branches.
+ #### How about patch in <200106081225.IAA31075@gwyn.tux.org>? */
+ assert (!gc_in_progress);
+ goto defproc;
+ }
+
+#ifdef DEBUG_XEMACS
+ if (debug_mswindows_events)
+ debug_output_mswin_message (hwnd, message_, wParam, lParam);
+#endif /* DEBUG_XEMACS */
assert (!GetWindowLong (hwnd, GWL_USERDATA));
switch (message_)
int should_set_keymap = 0;
#ifdef DEBUG_XEMACS
- 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 ();
- }
+ if (debug_mswindows_events > 2)
+ output_alt_keyboard_state ();
#endif /* DEBUG_XEMACS */
mswindows_handle_sticky_modifiers (wParam, lParam, 0, 1);
int sticky_changed;
#ifdef DEBUG_XEMACS
- 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 ();
- }
+ if (debug_mswindows_events > 2)
+ output_alt_keyboard_state ();
#endif /* DEBUG_XEMACS */
GetKeyboardState (keymap_orig);
int mods_with_quit = mods;
WPARAM ch = tranmsg.wParam;
+#ifdef DEBUG_XEMACS
+ if (debug_mswindows_events)
+ {
+ stderr_out ("-> ");
+ debug_output_mswin_message (tranmsg.hwnd, tranmsg.message,
+ tranmsg.wParam,
+ tranmsg.lParam);
+ }
+#endif /* DEBUG_XEMACS */
+
/* 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 */
mods_with_quit |= FAKE_MOD_QUIT;
if (mods_with_shift & XEMACS_MOD_SHIFT)
mods_with_quit |= FAKE_MOD_QUIT_CRITICAL;
- ++mswindows_quit_chars_count;
+ mswindows_quit_chars_count++;
}
else if (potential_accelerator && !got_accelerator &&
mswindows_char_is_accelerator (frame, ch))
mswindows_handle_paint (XFRAME (mswindows_find_frame (hwnd)));
break;
+ case WM_WINDOWPOSCHANGED:
+ /* This is sent before WM_SIZE; in fact, the processing of this
+ by DefWindowProc() sends WM_SIZE. But WM_SIZE is not sent when
+ a window is hidden (make-frame-invisible), so we need to process
+ this and update the state flags. */
+ {
+ fobj = mswindows_find_frame (hwnd);
+ frame = XFRAME (fobj);
+ if (IsIconic (hwnd))
+ {
+ FRAME_VISIBLE_P (frame) = 0;
+ FRAME_ICONIFIED_P (frame) = 1;
+ }
+ else if (IsWindowVisible (hwnd))
+ {
+ FRAME_VISIBLE_P (frame) = 1;
+ FRAME_ICONIFIED_P (frame) = 0;
+ }
+ else
+ {
+ FRAME_VISIBLE_P (frame) = 0;
+ FRAME_ICONIFIED_P (frame) = 0;
+ }
+
+ return DefWindowProc (hwnd, message_, wParam, lParam);
+ }
+
case WM_SIZE:
/* We only care about this message if our size has really changed */
if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED || wParam==SIZE_MINIMIZED)
if (wParam==SIZE_MINIMIZED)
{
/* Iconified */
- FRAME_VISIBLE_P (frame) = 0;
mswindows_enqueue_magic_event (hwnd, XM_UNMAPFRAME);
}
else
{
if (!msframe->sizing && !FRAME_VISIBLE_P (frame))
mswindows_enqueue_magic_event (hwnd, XM_MAPFRAME);
- FRAME_VISIBLE_P (frame) = 1;
if (!msframe->sizing || mswindows_dynamic_frame_resize)
redisplay ();
if (psl->lpVtbl->QueryInterface (psl, &IID_IPersistFile,
&ppf) == S_OK)
{
- WORD wsz[MAX_PATH];
+ OLECHAR wsz[PATH_MAX];
WIN32_FIND_DATA wfd;
- LPSTR resolved = (char *) xmalloc (MAX_PATH+1);
+ LPSTR resolved = (char *) xmalloc (PATH_MAX+1);
- MultiByteToWideChar (CP_ACP,0, fname, -1, wsz, MAX_PATH);
+ MultiByteToWideChar (CP_ACP,0, fname, -1, wsz, PATH_MAX);
if ((ppf->lpVtbl->Load (ppf, wsz, STGM_READ) == S_OK) &&
- (psl->lpVtbl->GetPath (psl, resolved, MAX_PATH,
+ (psl->lpVtbl->GetPath (psl, resolved, PATH_MAX,
&wfd, 0)==S_OK))
{
xfree (fname);
#endif
#ifdef CYGWIN
- filename = xmalloc (cygwin32_win32_to_posix_path_list_buf_size (fname) + 5);
+ filename = xmalloc (cygwin_win32_to_posix_path_list_buf_size (fname) + 5);
strcpy (filename, "file:");
- cygwin32_win32_to_posix_path_list (fname, filename+5);
+ cygwin_win32_to_posix_path_list (fname, filename+5);
#else
filename = (char *)xmalloc (len+6);
strcat (strcpy (filename, "file:"), fname);
if (mswindows_in_modal_loop)
return;
+ mswindows_quit_chars_count = 0;
/* Drain windows queue. This sets up number of quit characters in
the queue. */
mswindows_drain_windows_queue ();
match_against.event_type = key_press_event;
match_against.event.key.modifiers = FAKE_MOD_QUIT;
- while (mswindows_quit_chars_count-- > 0)
+ while (mswindows_quit_chars_count > 0)
{
emacs_event = mswindows_cancel_dispatch_event (&match_against);
assert (!NILP (emacs_event));
critical_p = 1;
Fdeallocate_event (emacs_event);
+ mswindows_quit_chars_count--;
}
Vquit_flag = critical_p ? Qcritical : Qt;
}
#endif
+#ifdef DEBUG_XEMACS
+
+struct mswin_message_debug
+{
+ int mess;
+ char *string;
+};
+
+#define FROB(val) { val, #val, },
+
+struct mswin_message_debug debug_mswin_messages[] =
+{
+FROB (WM_NULL)
+FROB (WM_CREATE)
+FROB (WM_DESTROY)
+FROB (WM_MOVE)
+FROB (WM_SIZE)
+
+FROB (WM_ACTIVATE)
+
+FROB (WM_SETFOCUS)
+FROB (WM_KILLFOCUS)
+FROB (WM_ENABLE)
+FROB (WM_SETREDRAW)
+FROB (WM_SETTEXT)
+FROB (WM_GETTEXT)
+FROB (WM_GETTEXTLENGTH)
+FROB (WM_PAINT)
+FROB (WM_CLOSE)
+FROB (WM_QUERYENDSESSION)
+FROB (WM_QUIT)
+FROB (WM_QUERYOPEN)
+FROB (WM_ERASEBKGND)
+FROB (WM_SYSCOLORCHANGE)
+FROB (WM_ENDSESSION)
+FROB (WM_SHOWWINDOW)
+FROB (WM_WININICHANGE)
+#if(WINVER >= 0x0400)
+FROB (WM_SETTINGCHANGE)
+#endif /* WINVER >= 0x0400 */
+
+FROB (WM_DEVMODECHANGE)
+FROB (WM_ACTIVATEAPP)
+FROB (WM_FONTCHANGE)
+FROB (WM_TIMECHANGE)
+FROB (WM_CANCELMODE)
+FROB (WM_SETCURSOR)
+FROB (WM_MOUSEACTIVATE)
+FROB (WM_CHILDACTIVATE)
+FROB (WM_QUEUESYNC)
+
+FROB (WM_GETMINMAXINFO)
+
+FROB (WM_PAINTICON)
+FROB (WM_ICONERASEBKGND)
+FROB (WM_NEXTDLGCTL)
+FROB (WM_SPOOLERSTATUS)
+FROB (WM_DRAWITEM)
+FROB (WM_MEASUREITEM)
+FROB (WM_DELETEITEM)
+FROB (WM_VKEYTOITEM)
+FROB (WM_CHARTOITEM)
+FROB (WM_SETFONT)
+FROB (WM_GETFONT)
+FROB (WM_SETHOTKEY)
+FROB (WM_GETHOTKEY)
+FROB (WM_QUERYDRAGICON)
+FROB (WM_COMPAREITEM)
+#if(WINVER >= 0x0500)
+FROB (WM_GETOBJECT)
+#endif /* WINVER >= 0x0500 */
+FROB (WM_COMPACTING)
+FROB (WM_COMMNOTIFY)
+FROB (WM_WINDOWPOSCHANGING)
+FROB (WM_WINDOWPOSCHANGED)
+
+FROB (WM_POWER)
+
+FROB (WM_COPYDATA)
+FROB (WM_CANCELJOURNAL)
+
+#if(WINVER >= 0x0400)
+FROB (WM_NOTIFY)
+FROB (WM_INPUTLANGCHANGEREQUEST)
+FROB (WM_INPUTLANGCHANGE)
+FROB (WM_TCARD)
+FROB (WM_HELP)
+FROB (WM_USERCHANGED)
+FROB (WM_NOTIFYFORMAT)
+
+FROB (WM_CONTEXTMENU)
+FROB (WM_STYLECHANGING)
+FROB (WM_STYLECHANGED)
+FROB (WM_DISPLAYCHANGE)
+FROB (WM_GETICON)
+FROB (WM_SETICON)
+#endif /* WINVER >= 0x0400 */
+
+FROB (WM_NCCREATE)
+FROB (WM_NCDESTROY)
+FROB (WM_NCCALCSIZE)
+FROB (WM_NCHITTEST)
+FROB (WM_NCPAINT)
+FROB (WM_NCACTIVATE)
+FROB (WM_GETDLGCODE)
+FROB (WM_SYNCPAINT)
+FROB (WM_NCMOUSEMOVE)
+FROB (WM_NCLBUTTONDOWN)
+FROB (WM_NCLBUTTONUP)
+FROB (WM_NCLBUTTONDBLCLK)
+FROB (WM_NCRBUTTONDOWN)
+FROB (WM_NCRBUTTONUP)
+FROB (WM_NCRBUTTONDBLCLK)
+FROB (WM_NCMBUTTONDOWN)
+FROB (WM_NCMBUTTONUP)
+FROB (WM_NCMBUTTONDBLCLK)
+
+/* FROB (WM_KEYFIRST) */
+FROB (WM_KEYDOWN)
+FROB (WM_KEYUP)
+FROB (WM_CHAR)
+FROB (WM_DEADCHAR)
+FROB (WM_SYSKEYDOWN)
+FROB (WM_SYSKEYUP)
+FROB (WM_SYSCHAR)
+FROB (WM_SYSDEADCHAR)
+FROB (WM_KEYLAST)
+
+#if(WINVER >= 0x0400) && !defined(CYGWIN)
+FROB (WM_IME_STARTCOMPOSITION)
+FROB (WM_IME_ENDCOMPOSITION)
+FROB (WM_IME_COMPOSITION)
+FROB (WM_IME_KEYLAST)
+#endif /* WINVER >= 0x0400 */
+
+FROB (WM_INITDIALOG)
+FROB (WM_COMMAND)
+FROB (WM_SYSCOMMAND)
+FROB (WM_TIMER)
+FROB (WM_HSCROLL)
+FROB (WM_VSCROLL)
+FROB (WM_INITMENU)
+FROB (WM_INITMENUPOPUP)
+FROB (WM_MENUSELECT)
+FROB (WM_MENUCHAR)
+FROB (WM_ENTERIDLE)
+#if(WINVER >= 0x0500)
+FROB (WM_MENURBUTTONUP)
+FROB (WM_MENUDRAG)
+FROB (WM_MENUGETOBJECT)
+FROB (WM_UNINITMENUPOPUP)
+FROB (WM_MENUCOMMAND)
+#endif /* WINVER >= 0x0500 */
+
+
+FROB (WM_CTLCOLORMSGBOX)
+FROB (WM_CTLCOLOREDIT)
+FROB (WM_CTLCOLORLISTBOX)
+FROB (WM_CTLCOLORBTN)
+FROB (WM_CTLCOLORDLG)
+FROB (WM_CTLCOLORSCROLLBAR)
+FROB (WM_CTLCOLORSTATIC)
+
+
+/* FROB (WM_MOUSEFIRST) */
+FROB (WM_MOUSEMOVE)
+FROB (WM_LBUTTONDOWN)
+FROB (WM_LBUTTONUP)
+FROB (WM_LBUTTONDBLCLK)
+FROB (WM_RBUTTONDOWN)
+FROB (WM_RBUTTONUP)
+FROB (WM_RBUTTONDBLCLK)
+FROB (WM_MBUTTONDOWN)
+FROB (WM_MBUTTONUP)
+FROB (WM_MBUTTONDBLCLK)
+
+#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
+FROB (WM_MOUSEWHEEL)
+FROB (WM_MOUSELAST)
+#else
+FROB (WM_MOUSELAST)
+#endif /* if (_WIN32_WINNT < 0x0400) */
+
+FROB (WM_PARENTNOTIFY)
+FROB (WM_ENTERMENULOOP)
+FROB (WM_EXITMENULOOP)
+
+#if(WINVER >= 0x0400)
+FROB (WM_NEXTMENU)
+
+FROB (WM_SIZING)
+FROB (WM_CAPTURECHANGED)
+FROB (WM_MOVING)
+FROB (WM_POWERBROADCAST)
+
+FROB (WM_DEVICECHANGE)
+
+#endif /* WINVER >= 0x0400 */
+
+FROB (WM_MDICREATE)
+FROB (WM_MDIDESTROY)
+FROB (WM_MDIACTIVATE)
+FROB (WM_MDIRESTORE)
+FROB (WM_MDINEXT)
+FROB (WM_MDIMAXIMIZE)
+FROB (WM_MDITILE)
+FROB (WM_MDICASCADE)
+FROB (WM_MDIICONARRANGE)
+FROB (WM_MDIGETACTIVE)
+
+
+FROB (WM_MDISETMENU)
+FROB (WM_ENTERSIZEMOVE)
+FROB (WM_EXITSIZEMOVE)
+FROB (WM_DROPFILES)
+FROB (WM_MDIREFRESHMENU)
+
+
+#if(WINVER >= 0x0400) && !defined(CYGWIN)
+FROB (WM_IME_SETCONTEXT)
+FROB (WM_IME_NOTIFY)
+FROB (WM_IME_CONTROL)
+FROB (WM_IME_COMPOSITIONFULL)
+FROB (WM_IME_SELECT)
+FROB (WM_IME_CHAR)
+#endif /* WINVER >= 0x0400 */
+#if(WINVER >= 0x0500)
+FROB (WM_IME_REQUEST)
+#endif /* WINVER >= 0x0500 */
+#if(WINVER >= 0x0400) && !defined(CYGWIN)
+FROB (WM_IME_KEYDOWN)
+FROB (WM_IME_KEYUP)
+#endif /* WINVER >= 0x0400 */
+
+
+#if(_WIN32_WINNT >= 0x0400)
+FROB (WM_MOUSEHOVER)
+FROB (WM_MOUSELEAVE)
+#endif /* _WIN32_WINNT >= 0x0400 */
+
+FROB (WM_CUT)
+FROB (WM_COPY)
+FROB (WM_PASTE)
+FROB (WM_CLEAR)
+FROB (WM_UNDO)
+FROB (WM_RENDERFORMAT)
+FROB (WM_RENDERALLFORMATS)
+FROB (WM_DESTROYCLIPBOARD)
+FROB (WM_DRAWCLIPBOARD)
+FROB (WM_PAINTCLIPBOARD)
+FROB (WM_VSCROLLCLIPBOARD)
+FROB (WM_SIZECLIPBOARD)
+FROB (WM_ASKCBFORMATNAME)
+FROB (WM_CHANGECBCHAIN)
+FROB (WM_HSCROLLCLIPBOARD)
+FROB (WM_QUERYNEWPALETTE)
+FROB (WM_PALETTEISCHANGING)
+FROB (WM_PALETTECHANGED)
+FROB (WM_HOTKEY)
+
+#if(WINVER >= 0x0400)
+FROB (WM_PRINT)
+FROB (WM_PRINTCLIENT)
+
+FROB (WM_HANDHELDFIRST)
+FROB (WM_HANDHELDLAST)
+
+FROB (WM_AFXFIRST)
+FROB (WM_AFXLAST)
+#endif /* WINVER >= 0x0400 */
+
+FROB (WM_PENWINFIRST)
+FROB (WM_PENWINLAST)
+};
+
+#undef FROB
+
+static void
+debug_output_mswin_message (HWND hwnd, UINT message_, WPARAM wParam,
+ LPARAM lParam)
+{
+ Lisp_Object frame = mswindows_find_frame (hwnd);
+ int i;
+ char *str = 0;
+ /* struct mswin_message_debug *i_hate_cranking_out_code_like_this; */
+
+ for (i = 0; i < countof (debug_mswin_messages); i++)
+ {
+ if (debug_mswin_messages[i].mess == message_)
+ {
+ str = debug_mswin_messages[i].string;
+ break;
+ }
+ }
+
+ if (str)
+ stderr_out ("%s", str);
+ else
+ stderr_out ("%x", message_);
+
+ if (debug_mswindows_events > 1)
+ {
+ stderr_out (" wparam=%d lparam=%d hwnd=%x frame: ",
+ wParam, (int) lParam, (unsigned int) hwnd);
+ debug_print (frame);
+ }
+ else
+ stderr_out ("\n");
+}
+
+#endif /* DEBUG_XEMACS */
+
/************************************************************************/
/* initialization */
/************************************************************************/
#ifdef DEBUG_XEMACS
DEFVAR_INT ("debug-mswindows-events", &debug_mswindows_events /*
-If non-zero, display debug information about Windows events that XEmacs sees.
+If non-zero, display debug information about Windows messages that XEmacs sees.
Information is displayed in a console window. Currently defined values are:
-1 == non-verbose output
-2 == verbose output
-
-#### Unfortunately, not yet implemented.
+1 == non-verbose output (just the message name)
+2 == verbose output (all parameters)
+3 == even more verbose output (extra debugging info)
*/ );
debug_mswindows_events = 0;
#endif