+
+ return 0;
+}
+
+static void
+clear_sticky_modifiers (void)
+{
+ need_to_add_mask = 0;
+ last_downkey = 0;
+ down_mask = 0;
+}
+
+#ifdef DEBUG_XEMACS
+
+#if 0
+
+static void
+output_modifier_keyboard_state (void)
+{
+ BYTE keymap[256];
+
+ GetKeyboardState (keymap);
+
+ stderr_out ("GetKeyboardState VK_MENU %d %d VK_LMENU %d %d VK_RMENU %d %d\n",
+ keymap[VK_MENU] & 0x80 ? 1 : 0,
+ keymap[VK_MENU] & 0x1 ? 1 : 0,
+ keymap[VK_LMENU] & 0x80 ? 1 : 0,
+ keymap[VK_LMENU] & 0x1 ? 1 : 0,
+ keymap[VK_RMENU] & 0x80 ? 1 : 0,
+ keymap[VK_RMENU] & 0x1 ? 1 : 0);
+ stderr_out ("GetKeyboardState VK_CONTROL %d %d VK_LCONTROL %d %d VK_RCONTROL %d %d\n",
+ keymap[VK_CONTROL] & 0x80 ? 1 : 0,
+ keymap[VK_CONTROL] & 0x1 ? 1 : 0,
+ keymap[VK_LCONTROL] & 0x80 ? 1 : 0,
+ keymap[VK_LCONTROL] & 0x1 ? 1 : 0,
+ keymap[VK_RCONTROL] & 0x80 ? 1 : 0,
+ keymap[VK_RCONTROL] & 0x1 ? 1 : 0);
+ stderr_out ("GetKeyboardState VK_SHIFT %d %d VK_LSHIFT %d %d VK_RSHIFT %d %d\n",
+ keymap[VK_SHIFT] & 0x80 ? 1 : 0,
+ keymap[VK_SHIFT] & 0x1 ? 1 : 0,
+ keymap[VK_LSHIFT] & 0x80 ? 1 : 0,
+ keymap[VK_LSHIFT] & 0x1 ? 1 : 0,
+ keymap[VK_RSHIFT] & 0x80 ? 1 : 0,
+ 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
+ StickyKeys in the Win2000 accessibility section of the control panel,
+ which is extremely broken for other reasons. */
+
+static void
+output_alt_keyboard_state (void)
+{
+ BYTE keymap[256];
+ SHORT keystate[3];
+ // SHORT asyncstate[3];
+
+ GetKeyboardState (keymap);
+ keystate[0] = GetKeyState (VK_MENU);
+ keystate[1] = GetKeyState (VK_LMENU);
+ keystate[2] = GetKeyState (VK_RMENU);
+ /* Doing this interferes with key processing. */
+/* asyncstate[0] = GetAsyncKeyState (VK_MENU); */
+/* asyncstate[1] = GetAsyncKeyState (VK_LMENU); */
+/* asyncstate[2] = GetAsyncKeyState (VK_RMENU); */
+
+ stderr_out ("GetKeyboardState VK_MENU %d %d VK_LMENU %d %d VK_RMENU %d %d\n",
+ keymap[VK_MENU] & 0x80 ? 1 : 0,
+ keymap[VK_MENU] & 0x1 ? 1 : 0,
+ keymap[VK_LMENU] & 0x80 ? 1 : 0,
+ keymap[VK_LMENU] & 0x1 ? 1 : 0,
+ keymap[VK_RMENU] & 0x80 ? 1 : 0,
+ keymap[VK_RMENU] & 0x1 ? 1 : 0);
+ stderr_out ("GetKeyState VK_MENU %d %d VK_LMENU %d %d VK_RMENU %d %d\n",
+ keystate[0] & 0x8000 ? 1 : 0,
+ keystate[0] & 0x1 ? 1 : 0,
+ keystate[1] & 0x8000 ? 1 : 0,
+ keystate[1] & 0x1 ? 1 : 0,
+ keystate[2] & 0x8000 ? 1 : 0,
+ keystate[2] & 0x1 ? 1 : 0);
+/* stderr_out ("GetAsyncKeyState VK_MENU %d %d VK_LMENU %d %d VK_RMENU %d %d\n", */
+/* asyncstate[0] & 0x8000 ? 1 : 0, */
+/* asyncstate[0] & 0x1 ? 1 : 0, */
+/* asyncstate[1] & 0x8000 ? 1 : 0, */
+/* asyncstate[1] & 0x1 ? 1 : 0, */
+/* asyncstate[2] & 0x8000 ? 1 : 0, */
+/* asyncstate[2] & 0x1 ? 1 : 0); */
+}
+
+#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)
+{
+ /* 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;
+
+ Lisp_Event *event;
+ 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_)
+ {
+ 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, 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);