This commit was manufactured by cvs2svn to create branch 'XEmacs-21_4'.
[chise/xemacs-chise.git.1] / src / event-msw.c
index c5c3d2f..e18c1e6 100644 (file)
@@ -128,6 +128,7 @@ 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;
@@ -632,8 +633,8 @@ struct winsock_stream
   SOCKET s;                    /* Socket handle (which is a Win32 handle)   */
   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;         /* Position in buffer for next fetch         */
+  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                            */
   unsigned int eof_p :1;       /* EOF Error seen                            */
   unsigned int pending_p :1;   /* There is a pending I/O operation          */
@@ -712,7 +713,7 @@ winsock_reader (Lstream *stream, unsigned char *data, size_t size)
 }
 
 static ssize_t
-winsock_writer (Lstream *stream, CONST unsigned char *data, size_t size)
+winsock_writer (Lstream *stream, const unsigned char *data, size_t size)
 {
   struct winsock_stream *str = WINSOCK_STREAM_DATA (stream);
 
@@ -785,7 +786,7 @@ winsock_was_blocked_p (Lstream *stream)
 }
 
 static Lisp_Object
-make_winsock_stream_1 (SOCKET s, LPARAM param, CONST char *mode)
+make_winsock_stream_1 (SOCKET s, LPARAM param, const char *mode)
 {
   Lisp_Object obj;
   Lstream *lstr = Lstream_new (lstream_winsock, mode);
@@ -1230,18 +1231,14 @@ mswindows_pump_outstanding_events (void)
  * QUITP, and are interesting in keyboard messages only.
  */
 static void
-mswindows_drain_windows_queue (int keyboard_only_till_quit_char_p)
+mswindows_drain_windows_queue ()
 {
   MSG msg;
 
-  /* Minimize the hassle of misordered events by not fetching
-     past quit char if called from QUITP; */
-  while (!(keyboard_only_till_quit_char_p &&
-          mswindows_quit_chars_count > 0) &&
-        PeekMessage (&msg, NULL,
-                     keyboard_only_till_quit_char_p ? WM_KEYFIRST : 0,
-                     keyboard_only_till_quit_char_p ? WM_KEYLAST : 0,
-                     PM_REMOVE))
+  /* should call mswindows_need_event_in_modal_loop() if in modal loop */
+  assert (!mswindows_in_modal_loop);
+
+  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
@@ -1251,6 +1248,19 @@ mswindows_drain_windows_queue (int keyboard_only_till_quit_char_p)
        {
          TranslateMessage (&msg);
        }
+      else if (msg.message == WM_PAINT)
+       {
+         /* 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 */
+         mswindows_enqueue_magic_event (msg.hwnd, WM_PAINT);
+
+         /* Don't dispatch. WM_PAINT is always the last message in the
+            queue so it's OK to just return. */
+         return;
+       }
       DispatchMessage (&msg);
       mswindows_unmodalize_signal_maybe ();
     }
@@ -1314,14 +1324,6 @@ mswindows_need_event (int badly_p)
       return;
     }
 
-#if 0
-  /* Have to drain Windows message queue first, otherwise, we may miss
-     quit char when called from quit_p */
-  /* #### This is, ehm, not quite true -- this function is not
-     called from quit_p. --kkm */
-  mswindows_drain_windows_queue ();
-#endif
-
   while (NILP (mswindows_u_dispatch_event_queue)
         && NILP (mswindows_s_dispatch_event_queue))
     {
@@ -1351,7 +1353,7 @@ mswindows_need_event (int badly_p)
        {
          if (FD_ISSET (windows_fd, &temp_mask))
            {
-             mswindows_drain_windows_queue (0);
+             mswindows_drain_windows_queue ();
            }
 #ifdef HAVE_TTY
          /* Look for a TTY event */
@@ -1432,7 +1434,7 @@ mswindows_need_event (int badly_p)
     else if (active == WAIT_OBJECT_0 + mswindows_waitable_count)
       {
        /* Got your message, thanks */
-       mswindows_drain_windows_queue (0);
+       mswindows_drain_windows_queue ();
       }
     else
       {
@@ -1514,7 +1516,7 @@ mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv,
          { mswindows_dde_service, mswindows_dde_topic_system }, { 0, 0 } };
 
        if (!(hszItem  || DdeCmpStringHandles (hszItem, mswindows_dde_service)) &&
-           !(hszTopic || DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)));
+           !(hszTopic || DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)))
          return (DdeCreateDataHandle (mswindows_dde_mlid, (LPBYTE)pairs,
                                       sizeof (pairs), 0L, 0, uFmt, 0));
       }
@@ -1524,7 +1526,7 @@ mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv,
       if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system))
        {
          DWORD len = DdeGetData (hdata, NULL, 0, 0);
-         char *cmd = alloca (len+1);
+         LPBYTE cmd = (LPBYTE) alloca (len+1);
          char *end;
          char *filename;
          struct gcpro gcpro1, gcpro2;
@@ -1609,6 +1611,41 @@ mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv,
 #endif
 
 /*
+ * Helper to do repainting - repaints can happen both from the windows
+ * procedure and from magic events
+ */
+void
+mswindows_handle_paint (struct frame *frame)
+  {
+    HWND hwnd = FRAME_MSWINDOWS_HANDLE (frame);
+
+    /* According to the docs we need to check GetUpdateRect() before
+       actually doing a WM_PAINT */
+    if (GetUpdateRect (hwnd, NULL, FALSE))
+      {
+       PAINTSTRUCT paintStruct;
+       int x, y, width, height;
+
+       BeginPaint (hwnd, &paintStruct);
+       x = paintStruct.rcPaint.left;
+       y = paintStruct.rcPaint.top;
+       width = paintStruct.rcPaint.right - paintStruct.rcPaint.left;
+       height = paintStruct.rcPaint.bottom - paintStruct.rcPaint.top;
+       /* Normally we want to ignore expose events when child
+          windows are unmapped, however once we are in the guts of
+          WM_PAINT we need to make sure that we don't register
+          unmaps then because they will not actually occur. */
+       if (!check_for_ignored_expose (frame, x, y, width, height))
+         {
+           hold_ignored_expose_registration = 1;
+           mswindows_redraw_exposed_area (frame, x, y, width, height);
+           hold_ignored_expose_registration = 0;
+         }
+       EndPaint (hwnd, &paintStruct);
+      }
+  }
+
+/*
  * Returns 1 if a key is a real modifier or special key, which 
  * is better handled by DefWindowProc
  */
@@ -2021,37 +2058,14 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     break;
 
   case WM_PAINT:
-    {
-      /* According to the docs we need to check GetUpdateRect() before
-         actually doing a WM_PAINT */
-      if (GetUpdateRect (hwnd, NULL, FALSE))
-       {
-         PAINTSTRUCT paintStruct;
-         int x, y, width, height;
-
-         frame = XFRAME (mswindows_find_frame (hwnd));
-
-         BeginPaint (hwnd, &paintStruct);
-         x = paintStruct.rcPaint.left;
-         y = paintStruct.rcPaint.top;
-         width = paintStruct.rcPaint.right - paintStruct.rcPaint.left;
-         height = paintStruct.rcPaint.bottom - paintStruct.rcPaint.top;
-         /* Normally we want to ignore expose events when child
-            windows are unmapped, however once we are in the guts of
-            WM_PAINT we need to make sure that we don't register
-            unmaps then because they will not actually occur. */
-         if (!check_for_ignored_expose (frame, x, y, width, height))
-           {
-             hold_ignored_expose_registration = 1;
-             mswindows_redraw_exposed_area (frame, x, y, width, height);
-             hold_ignored_expose_registration = 0;
-           }
-
-         EndPaint (hwnd, &paintStruct);
-       }
-      else
-       goto defproc;
-    }
+    /* hdc will be NULL unless this is a subwindow - in which case we
+       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 
+       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)));
     break;
 
   case WM_SIZE:
@@ -2346,7 +2360,7 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
       GCPRO3 (emacs_event, l_dndlist, l_item);
 
-      if (!DragQueryPoint ((HANDLE) wParam, &point))
+      if (!DragQueryPoint ((HDROP) wParam, &point))
        point.x = point.y = -1;         /* outside client area */
 
       event->event_type = misc_user_event;
@@ -2358,10 +2372,10 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       event->event.misc.y = point.y;
       event->event.misc.function = Qdragdrop_drop_dispatch;
 
-      filecount = DragQueryFile ((HANDLE) wParam, 0xffffffff, NULL, 0);
+      filecount = DragQueryFile ((HDROP) wParam, 0xffffffff, NULL, 0);
       for (i=0; i<filecount; i++)
        {
-         len = DragQueryFile ((HANDLE) wParam, i, NULL, 0);
+         len = DragQueryFile ((HDROP) wParam, i, NULL, 0);
          /* The URLs that we make here aren't correct according to section
           * 3.10 of rfc1738 because they're missing the //<host>/ part and
           * because they may contain reserved characters. But that's OK. */
@@ -2375,14 +2389,14 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #else
          filename = (char *)xmalloc (len+6);
          strcpy (filename, "file:");
-         DragQueryFile ((HANDLE) wParam, i, filename+5, len+1);
+         DragQueryFile ((HDROP) wParam, i, filename+5, len+1);
          dostounix_filename (filename+5);
 #endif
          l_item = make_string (filename, strlen (filename));
          l_dndlist = Fcons (l_item, l_dndlist);
          xfree (filename);
        }
-      DragFinish ((HANDLE) wParam);
+      DragFinish ((HDROP) wParam);
 
       event->event.misc.object = Fcons (Qdragdrop_URL, l_dndlist);
       mswindows_enqueue_dispatch_event (emacs_event);
@@ -2702,6 +2716,10 @@ emacs_mswindows_handle_magic_event (Lisp_Event *emacs_event)
     case XM_BUMPQUEUE:
       break;
 
+    case WM_PAINT:
+      mswindows_handle_paint (XFRAME (EVENT_CHANNEL (emacs_event)));
+      break;
+
     case WM_SETFOCUS:
     case WM_KILLFOCUS:
       {
@@ -2831,7 +2849,7 @@ emacs_mswindows_quit_p (void)
 
   /* Drain windows queue. This sets up number of quit characters in
      the queue */
-  mswindows_drain_windows_queue (1);
+  mswindows_drain_windows_queue ();
 
   if (mswindows_quit_chars_count > 0)
     {