[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

[MD:7058] Patch for new hdc handling.



堀口です. 今までの話を元に整理しなおしてみました. r3987 に対する差
分になっています.

 すみませんが, 問題なく動くかどうか確認していただけないでしょうか.

-- 
ほりぐちきょうたろう

Index: dispnew.c
===================================================================
--- dispnew.c	(revision 3987)
+++ dispnew.c	(working copy)
@@ -3847,6 +3847,7 @@
   struct window *root_window = XWINDOW (f->root_window);
 
 #ifdef MEADOW
+  GET_FRAME_HDC (f);
   W32_BLOCK_INPUT;
 #endif
   if (FRAME_WINDOW_P (f))
@@ -3928,6 +3929,7 @@
     }
 #ifdef MEADOW
   W32_UNBLOCK_INPUT;
+  RELEASE_FRAME_HDC (f);
 #endif
 
   /* Reset flags indicating that a window should be updated.  */
Index: mw32term.c
===================================================================
--- mw32term.c	(revision 3987)
+++ mw32term.c	(working copy)
@@ -193,6 +193,14 @@
    window procedure. */
 HWND mw32_frame_window;
 
+/* Window's DC that is used by main thread. */
+HDC main_thread_hdc = INVALID_HANDLE_VALUE;
+
+/* Nesting level of main_thread_hdc. */
+int main_thread_hdc_nestlevel = 0;
+
+/* hwnd for main_thread_hdc to use on release. */
+HWND main_thread_hdc_hwnd = INVALID_HANDLE_VALUE;
 
 /* The scroll bar in which the last X motion event occurred.
 
@@ -392,8 +400,11 @@
 void
 mw32_destroy_frame_hdc (struct frame *f)
 {
+  if (main_thread_hdc != INVALID_HANDLE_VALUE)
+    ReleaseDC (FRAME_MW32_WINDOW (f), main_thread_hdc);
   if (f->output_data.mw32->hdc != INVALID_HANDLE_VALUE)
     ReleaseDC (FRAME_MW32_WINDOW (f), f->output_data.mw32->hdc);
+  main_thread_hdc = INVALID_HANDLE_VALUE;
   f->output_data.mw32->hdc = INVALID_HANDLE_VALUE;
 }
 
@@ -460,33 +471,32 @@
 void
 mw32_set_caret (struct frame *f, int state)
 {
-  MSG msg;
-  int unblock = FALSE;
-  enum frame_caret_state current_state;
+  int blocked = FALSE;
 
-  current_state  = MW32_FRAME_CARET_STATE (f);
-  if (current_state == NO_CARET
+  if (MW32_FRAME_CARET_STATE (f) == NO_CARET
       && (state == BLOCK_CARET || state == UNBLOCK_CARET)) return;
 
+  if (MW32_FRAME_CARET_BLOCKED (f))
+    {
+      if (state == BLOCK_CARET)
+	return;
+
+      if (state == SHOWN_CARET || state == HIDDEN_CARET)
+	{
+	  MW32_FRAME_CARET_STATE (f) = state;
+	  return;
+	}
+    }
   if (state == BLOCK_CARET || state == HIDDEN_CARET)
     ResetEvent (f->output_data.mw32->setcaret_event);
 
-  if (W32_SELF_INPUT_BLOCKED_P)
-    {
-      W32_UNBLOCK_INPUT;
-      unblock = TRUE;
-    }
-
   SEND_INFORM_MESSAGE (FRAME_MW32_WINDOW (f),
 		       WM_EMACS_SETCARET,
 		       state, 0);
-
+      
   /* Timing is significant when hiding caret */
   if (state == BLOCK_CARET || state == HIDDEN_CARET)
     WaitForSingleObject (f->output_data.mw32->setcaret_event, 10);
-
-  if (unblock)
-    W32_BLOCK_INPUT;
 }
 
 /* Draw a hollow rectangle at the specified position.  */
@@ -525,49 +535,40 @@
 {
   if (FRAME_MW32_P (f))
     {
-      HDC *phdc;
-      int *pcount;
-
-
+      MW32_BLOCK_CARET (f);
       if (MW32_MAIN_THREAD_P ())
 	{
-	  int block = FALSE;
-
-	  if (W32_SELF_INPUT_BLOCKED_P)
+	  if (main_thread_hdc != INVALID_HANDLE_VALUE)
 	    {
-	      W32_UNBLOCK_INPUT;
-	      block = TRUE;
+	      if (main_thread_hdc_nestlevel > GET_FRAME_HDC_LEVEL_LIMIT)
+		abort();
+	      main_thread_hdc_nestlevel++;
+	      return;
 	    }
-
+	  
+	  main_thread_hdc_hwnd = FRAME_MW32_WINDOW (f);
 	  EnterCriticalSection (&(f->output_data.mw32->hdc_critsec));
-	  phdc = &f->output_data.mw32->hdc;
+	  main_thread_hdc = GetDC (main_thread_hdc_hwnd);
 	  LeaveCriticalSection (&(f->output_data.mw32->hdc_critsec));
 
-	  if (block)
-	    W32_BLOCK_INPUT;
-
-	  pcount = &f->output_data.mw32->hdc_refcount;
+	  main_thread_hdc_nestlevel = 1;
+	  mw32_setup_default_hdc (main_thread_hdc);
 	}
       else
 	{
-	  phdc = &f->output_data.mw32->message_thread_hdc;
-	  pcount = &f->output_data.mw32->message_thread_hdc_refcount;
-	}
-	
-
-      if (*phdc != INVALID_HANDLE_VALUE)
-	{
-	  if (*pcount > GET_FRAME_HDC_LEVEL_LIMIT)
-	    abort ();
-	  (*pcount)++;
-	  return;
-	}
+	  if (f->output_data.mw32->hdc != INVALID_HANDLE_VALUE)
+	    {
+	      if (f->output_data.mw32->hdc_nestlevel
+		  > GET_FRAME_HDC_LEVEL_LIMIT)
+		abort ();
+	      f->output_data.mw32->hdc_nestlevel++;
+	      return;
+	    }
 	  
-      *phdc = GetDC (FRAME_MW32_WINDOW (f));
-      *pcount = 1;
-      mw32_setup_default_hdc (*phdc);
-
-      MW32_BLOCK_CARET (f);
+	  f->output_data.mw32->hdc = GetDC (FRAME_MW32_WINDOW (f));
+	  f->output_data.mw32->hdc_nestlevel = 1;
+	  mw32_setup_default_hdc (f->output_data.mw32->hdc);
+	}
     }
 }
 
@@ -632,32 +633,34 @@
     {
       Lisp_Object window;
       HDC *phdc;
+      HWND hwnd;
       int *pcount;
 
       FRAME_MW32_DISPLAY_INFO (f)->mouse_face_defer = 0;
 
       if (MW32_MAIN_THREAD_P ())
 	{
-	  phdc = &f->output_data.mw32->hdc;
-	  pcount = &f->output_data.mw32->hdc_refcount;
+	  phdc = &main_thread_hdc;
+	  pcount = &main_thread_hdc_nestlevel;
+	  hwnd = main_thread_hdc_hwnd;
 	}
       else
 	{
-	  phdc = &f->output_data.mw32->message_thread_hdc;
-	  pcount = &f->output_data.mw32->message_thread_hdc_refcount;
+	  phdc = &(f->output_data.mw32->hdc);
+	  pcount = &(f->output_data.mw32->hdc_nestlevel);
+	  hwnd = FRAME_MW32_WINDOW (f);
 	}
-
-      if (*phdc != INVALID_HANDLE_VALUE)
+	  
+      if (*pcount > 1)
 	{
-	  if (*pcount > 1)
-	    {
-	      (*pcount)--;
-	      return;
-	    }
-
-	  MW32_UNBLOCK_CARET (f);
+	  (*pcount)--;
+	  return;
 	}
 
+      MW32_UNBLOCK_CARET (f);
+      ReleaseDC (hwnd, *phdc);
+      *phdc = INVALID_HANDLE_VALUE;
+
       /* Synchronize selected_window's caret state */
       window = FRAME_SELECTED_WINDOW (f);
       if (WINDOWP (window))
@@ -668,13 +671,6 @@
 	      && ! MW32_FRAME_CARET_SHOWN (f))
 	    mw32_set_caret (f, SHOWN_CARET);
 	}
-
-      if (*phdc == INVALID_HANDLE_VALUE || *pcount > 1)
-	abort();
-      
-      ReleaseDC (FRAME_MW32_WINDOW (f), *phdc);
-      *phdc = INVALID_HANDLE_VALUE;
-      *pcount = 0;
     }
 }
 
@@ -4188,27 +4184,6 @@
 	    Fx_hide_tip ();
 	    break;
 	  }
-	  
-	case WM_EMACS_EXPOSE_FRAME:
-	  {
-	    HDC hdc;
-	    RECT rc;
-	    struct frame *f = (struct frame *)msg.wParam;
-	    
-	    hdc = GET_FRAME_HDC (f);
-	    mw32_setup_default_hdc (hdc);
-	    
-	    GetClientRect (FRAME_MW32_WINDOW (f), &rc);
-	    
-	    W32_BLOCK_INPUT;
-	    expose_frame (f,
-			  rc.left, rc.top,
-			  rc.right - rc.left,
-			  rc.bottom - rc.top);
-	    W32_UNBLOCK_INPUT;
-	    RELEASE_FRAME_HDC (f);
-	  }
-	  break;
 	}
       if (pwait_msg && (pwait_msg->message == msg.message))
 	{
@@ -6534,7 +6509,7 @@
 unwind_get_device_capability (data)
      Lisp_Object data;
 {
-  RELEASE_TEMP_HDC (XFRAME (data));
+  RELEASE_FRAME_HDC (XFRAME (data));
 
   return Qnil;
 }
@@ -6561,7 +6536,7 @@
 
   record_unwind_protect (unwind_get_device_capability, frame);
 
-  hdc = GET_TEMP_HDC (XFRAME (frame));
+  hdc = GET_FRAME_HDC (XFRAME (frame));
   
   if (EQ (item, intern ("width-in-mm")))
     {
Index: mw32term.h
===================================================================
--- mw32term.h	(revision 3987)
+++ mw32term.h	(working copy)
@@ -318,6 +318,15 @@
 /* A flag to control how to display unibyte 8-bit character.  */
 extern int unibyte_display_via_language_environment;
 
+/* Window's DC that is used by main thread. */
+extern HDC main_thread_hdc;
+
+/* Nesting level of main_thread_hdc. */
+extern int main_thread_hdc_nestlevel;
+
+/* hwnd for main_thread_hdc to use on release. */
+extern HWND main_thread_hdc_hwnd;
+
 #define GET_MW32_DISPLAY_INFO(arg) (mw32_display_list)
 
 
@@ -378,15 +387,9 @@
      we have to set it to INVALID_HANDLE_VALUE.  */
   HDC hdc;
 
-  /* Refernce count of hdc. */
-  int hdc_refcount;
+  /* Nesting level of hdc. */
+  int hdc_nestlevel;
 
-  /* Window's DC that is used for message thread. */
-  HDC message_thread_hdc;
-
-  /* Reference count of message_thread_hdc. */
-  int message_thread_hdc_refcount;
-
   /* Critical section to synchronize processces using hdc for this
      frame. */
   CRITICAL_SECTION hdc_critsec;
@@ -524,12 +527,12 @@
 #define FRAME_HDC(f)							\
  (! FRAME_WINDOW_P (f)? INVALID_HANDLE_VALUE:				\
   (MW32_MAIN_THREAD_P() ?						\
-   (((f)->output_data.mw32->hdc != INVALID_HANDLE_VALUE)		\
-    ? (f)->output_data.mw32->hdc					\
+   (main_thread_hdc != INVALID_HANDLE_VALUE				\
+    ? main_thread_hdc							\
     : (abort (), INVALID_HANDLE_VALUE))					\
-   : (((f)->output_data.mw32->message_thread_hdc			\
+   : (((f)->output_data.mw32->hdc					\
        != INVALID_HANDLE_VALUE)						\
-      ? (f)->output_data.mw32->message_thread_hdc			\
+      ? (f)->output_data.mw32->hdc					\
       : (abort(), INVALID_HANDLE_VALUE))))
 
 /* hdc_refcount never exceeds this limit under normal usage */
@@ -537,31 +540,18 @@
 #define GET_FRAME_HDC(f)						\
  (! FRAME_WINDOW_P (f)? INVALID_HANDLE_VALUE:				\
   (MW32_MAIN_THREAD_P()							\
-   ?(((f)->output_data.mw32->hdc != INVALID_HANDLE_VALUE)		\
-     ?(((f)->output_data.mw32->hdc_refcount++>GET_FRAME_HDC_LEVEL_LIMIT) \
+   ?(main_thread_hdc != INVALID_HANDLE_VALUE				\
+     ?((main_thread_hdc_nestlevel++ > GET_FRAME_HDC_LEVEL_LIMIT)	\
        ?(abort(), INVALID_HANDLE_VALUE)					\
-       :(f)->output_data.mw32->hdc)					\
-     :(update_begin_hook (f), (f)->output_data.mw32->hdc))		\
-   :(((f)->output_data.mw32->message_thread_hdc != INVALID_HANDLE_VALUE) \
-     ?(((f)->output_data.mw32->message_thread_hdc_refcount++		\
+       :main_thread_hdc)						\
+     :(update_begin_hook (f), main_thread_hdc))				\
+   :(((f)->output_data.mw32->hdc != INVALID_HANDLE_VALUE)		\
+     ?(((f)->output_data.mw32->hdc_nestlevel++				\
 	> GET_FRAME_HDC_LEVEL_LIMIT)					\
        ?(abort(), INVALID_HANDLE_VALUE)					\
-       :(f)->output_data.mw32->message_thread_hdc)			\
-     :(update_begin_hook (f), (f)->output_data.mw32->message_thread_hdc))))
+       :(f)->output_data.mw32->hdc)					\
+     :(update_begin_hook (f), (f)->output_data.mw32->hdc))))
 
-#define GET_TEMP_HDC(f)							\
- (! FRAME_WINDOW_P (f)? INVALID_HANDLE_VALUE:				\
-  (MW32_MAIN_THREAD_P() ?						\
-   (((f)->output_data.mw32->hdc != INVALID_HANDLE_VALUE)		\
-    ? ((f)->output_data.mw32->hdc_refcount++,(f)->output_data.mw32->hdc) \
-    : ((f)->output_data.mw32->hdc_refcount = 1,				\
-       (f)->output_data.mw32->hdc = GetDC (FRAME_MW32_WINDOW (f)))) 	\
-   : (((f)->output_data.mw32->message_thread_hdc != INVALID_HANDLE_VALUE) \
-      ? ((f)->output_data.mw32->message_thread_hdc_refcount++,		\
-         (f)->output_data.mw32->message_thread_hdc)			\
-      : ((f)->output_data.mw32->message_thread_hdc_refcount = 1,	\
-         (f)->output_data.mw32->message_thread_hdc			\
-	 = GetDC (FRAME_MW32_WINDOW (f))))))
 
 #define RELEASE_FRAME_HDC(f)						\
  if (FRAME_WINDOW_P (f))					       	\
@@ -570,13 +560,13 @@
     HDC *phdc;								\
     if (MW32_MAIN_THREAD_P ())						\
       {									\
-        phdc = &((f)->output_data.mw32->hdc);				\
-        pcount = &((f)->output_data.mw32->hdc_refcount);		\
+        phdc = &main_thread_hdc;					\
+        pcount = &main_thread_hdc_nestlevel;				\
       }									\
     else								\
       {									\
-        phdc = &((f)->output_data.mw32->message_thread_hdc);		\
-        pcount = &((f)->output_data.mw32->message_thread_hdc_refcount);	\
+        phdc = &((f)->output_data.mw32->hdc);				\
+        pcount = &((f)->output_data.mw32->hdc_nestlevel);		\
       }									\
     if (*phdc == INVALID_HANDLE_VALUE)					\
         abort ();							\
@@ -589,36 +579,25 @@
       }									\
   }
 
-#define RELEASE_TEMP_HDC(f)						\
+/* GET/RELEASE_FRAME_HDC is sometimes used asymmetrical becaulse of
+   signalling. This macro does force release of hdc. */
+#define CLEANUP_FRAME_HDC(f)						\
  if (FRAME_WINDOW_P (f))					       	\
   {									\
-    int *pcount;							\
-    HDC *phdc;								\
     if (MW32_MAIN_THREAD_P ())						\
       {									\
-        phdc = &((f)->output_data.mw32->hdc);				\
-        pcount = &((f)->output_data.mw32->hdc_refcount);		\
+	if (main_thread_hdc != INVALID_HANDLE_VALUE)			\
+	  main_thread_hdc_nestlevel = 1;				\
       }									\
     else								\
       {									\
-        phdc = &((f)->output_data.mw32->message_thread_hdc);		\
-        pcount = &((f)->output_data.mw32->message_thread_hdc_refcount);	\
+	if ((f)->output_data.mw32->hdc != INVALID_HANDLE_VALUE)		\
+	  (f)->output_data.mw32->hdc_nestlevel = 1;			\
+	update_end_hook (f);						\
       }									\
-    if (*phdc == INVALID_HANDLE_VALUE)					\
-        abort ();							\
-    else								\
-      {									\
-	if (*pcount > 1)						\
-	  (*pcount)--;							\
-	else								\
-	  {								\
-            ReleaseDC (FRAME_MW32_WINDOW (f), *phdc);			\
-            *phdc = INVALID_HANDLE_VALUE;				\
-            *pcount = 0;						\
-          }								\
-      }									\
   }
 
+
 #define WITH_MESSAGE_THREAD_HDC(f, proc)		\
   {update_begin_hook (f);(proc);update_end_hook (f);}
 
@@ -632,9 +611,10 @@
 
 /* Return the validity of frame's DC. */
 #define FRAME_HDC_VALID_P(f)				\
-  (MW32_MAIN_THREAD_P() ?				\
-   1							\
-   : ((f->output_data.mw32->message_thread_hdc		\
+  (MW32_MAIN_THREAD_P()					\
+   ? (main_thread_hdc != INVALID_HANDLE_VALUE		\
+      ? 1 : 0)						\
+   : ((f->output_data.mw32->hdc				\
        != INVALID_HANDLE_VALUE)				\
       ? 1 : 0))
 
@@ -952,6 +932,8 @@
 #endif
 
 extern int mw32_process_main_thread_message(MSG *pwait_msg);
+extern void (*update_begin_hook) P_ ((struct frame *));
+extern void (*update_end_hook) P_ ((struct frame *));
 
 /* This method does NOT guarantee message reachability
    if its destination is the message thread. */
Index: mw32sync.h
===================================================================
--- mw32sync.h	(revision 3987)
+++ mw32sync.h	(working copy)
@@ -7,20 +7,26 @@
 extern HANDLE next_message_block_event;
 extern HANDLE keyboard_handle;
 extern HANDLE interrupt_handle;
+extern DWORD main_thread_id;
+  //  printf("BLOCK:%s:%d/%d(%s)\n", __FILE__, __LINE__, GetCurrentThreadId(), main_thread_id == GetCurrentThreadId() ? "Main" : "Message");fflush(stdout); \
 
-#define W32_BLOCK_INPUT				\
-do {						\
-  EnterCriticalSection(&critsec_message);	\
-  block_input_ownthread = GetCurrentThreadId ();\
-} while (0);
-#define W32_UNBLOCK_INPUT			\
-do {						\
-  block_input_ownthread = 0;			\
-  LeaveCriticalSection(&critsec_message);	\
-} while (0);
-#define W32_SELF_INPUT_BLOCKED_P \
-(block_input_ownthread == GetCurrentThreadId ())
+#define W32_BLOCK_INPUT
+#define W32_UNBLOCK_INPUT
+#define W32_SELF_INPUT_BLOCKED_P FALSE
 
+// #define W32_BLOCK_INPUT				\
+// do {						\
+//   EnterCriticalSection(&critsec_message);	\
+//   block_input_ownthread = GetCurrentThreadId ();\
+// } while (0);
+// #define W32_UNBLOCK_INPUT			\
+// do {						\
+//   block_input_ownthread = 0;			\
+//   LeaveCriticalSection(&critsec_message);	\
+// } while (0);
+// #define W32_SELF_INPUT_BLOCKED_P \
+// (block_input_ownthread == GetCurrentThreadId ())
+
 #define W32_BLOCK_EVENT EnterCriticalSection(&critsec_access_event)
 #define W32_UNBLOCK_EVENT LeaveCriticalSection(&critsec_access_event)
 
Index: mw32fns.c
===================================================================
--- mw32fns.c	(revision 3987)
+++ mw32fns.c	(working copy)
@@ -1696,7 +1696,7 @@
     {
       hdc1 = GetDC (FRAME_MW32_WINDOW (f));
       mw32_setup_default_hdc (hdc1);
-      f->output_data.mw32->message_thread_hdc = hdc1;
+      f->output_data.mw32->hdc = hdc1;
     }
   else
     hdc1 = INVALID_HANDLE_VALUE;
@@ -1705,7 +1705,7 @@
     {
       hdc2 = GetDC (FRAME_MW32_WINDOW (fold));
       mw32_setup_default_hdc (hdc2);
-      fold->output_data.mw32->message_thread_hdc = hdc2;
+      fold->output_data.mw32->hdc = hdc2;
     }
   else
     hdc2 = INVALID_HANDLE_VALUE;
@@ -1716,12 +1716,12 @@
 
   if (hdc1 != INVALID_HANDLE_VALUE)
     {
-      f->output_data.mw32->message_thread_hdc = INVALID_HANDLE_VALUE;
+      f->output_data.mw32->hdc = INVALID_HANDLE_VALUE;
       ReleaseDC (FRAME_MW32_WINDOW (f), hdc1);
     }
   if (hdc2 != INVALID_HANDLE_VALUE)
     {
-      fold->output_data.mw32->message_thread_hdc = INVALID_HANDLE_VALUE;
+      fold->output_data.mw32->hdc = INVALID_HANDLE_VALUE;
       ReleaseDC (FRAME_MW32_WINDOW (fold), hdc2);
     }
 }
@@ -1938,18 +1938,18 @@
       int orefcount;
       HDC ohdc;
 
-      orefcount = f->output_data.mw32->message_thread_hdc_refcount;
-      ohdc = f->output_data.mw32->message_thread_hdc;
+      orefcount = f->output_data.mw32->hdc_nestlevel;
+      ohdc = f->output_data.mw32->hdc;
 
-      f->output_data.mw32->message_thread_hdc = (HDC) wParam;
-      f->output_data.mw32->message_thread_hdc_refcount = 1;
+      f->output_data.mw32->hdc = (HDC) wParam;
+      f->output_data.mw32->hdc_nestlevel = 1;
 
       GetClientRect (FRAME_MW32_WINDOW (f), &rect);
       mw32_clear_native_frame_area (f, rect.left, rect.top,
 				    rect.right, rect.bottom);
 
-      f->output_data.mw32->message_thread_hdc = ohdc;
-      f->output_data.mw32->message_thread_hdc_refcount = orefcount;
+      f->output_data.mw32->hdc = ohdc;
+      f->output_data.mw32->hdc_nestlevel = orefcount;
 
       return 0;
     }
@@ -1973,7 +1973,7 @@
 
 	  /* Avoid conflicting with drawing in main thread. */
 	  EnterCriticalSection (&(f->output_data.mw32->hdc_critsec));
-	  if (f->output_data.mw32->hdc == INVALID_HANDLE_VALUE)
+	  if (main_thread_hdc == INVALID_HANDLE_VALUE)
 	    {
 	      BeginPaint (FRAME_MW32_WINDOW (f), &ps);
 	      hdc = GET_FRAME_HDC (f);
@@ -2023,6 +2023,7 @@
       {
 	DestroyCaret ();
 	MW32_FRAME_CARET_STATE (f) = NO_CARET;
+	MW32_FRAME_CARET_BLOCKED (f) = FALSE;
       }
 
     if (f == FRAME_MW32_DISPLAY_INFO (f)->mw32_focus_frame)
@@ -2577,6 +2578,9 @@
 
       if (wParam == BLOCK_CARET)
 	{
+	  if (MW32_FRAME_CARET_BLOCKED (f))
+	    goto setcaret_end;
+	    
 	  MW32_FRAME_CARET_BLOCKED (f) = TRUE;
 
 	  if (MW32_FRAME_CARET_SHOWN (f))
@@ -2588,17 +2592,12 @@
 
       if (wParam == UNBLOCK_CARET)
 	{
-	  MW32_FRAME_CARET_BLOCKED (f) = FALSE;
+	  if (!MW32_FRAME_CARET_BLOCKED (f))
+	    goto setcaret_end;
 
-	  if (MW32_FRAME_CARET_SHOWN (f)
-	      || MW32_FRAME_CARET_STATE (f) == TOBESHOWN_CARET)
-	    {
-	      if (ShowCaret (hwnd) == 0)
-		MW32_FRAME_CARET_STATE (f) = TOBESHOWN_CARET;
-	      else
-		MW32_FRAME_CARET_STATE (f) = SHOWN_CARET;
-	    }
-	  goto setcaret_end;
+	  MW32_FRAME_CARET_BLOCKED (f) = FALSE;
+	  wParam = MW32_FRAME_CARET_SHOWN (f) ? SHOWN_CARET : HIDDEN_CARET;
+	  MW32_FRAME_CARET_STATE (f) = HIDDEN_CARET;
 	}
 
       if (wParam == SHOWN_CARET)
@@ -2919,9 +2918,7 @@
   /* all handles must be set to INVALID_HANLE_VALUE.  */
   f->output_data.mw32->menubar_handle = INVALID_HANDLE_VALUE;
   f->output_data.mw32->hdc = INVALID_HANDLE_VALUE;
-  f->output_data.mw32->hdc_refcount = 0;
-  f->output_data.mw32->message_thread_hdc = INVALID_HANDLE_VALUE;
-  f->output_data.mw32->message_thread_hdc_refcount = 0;
+  f->output_data.mw32->hdc_nestlevel = 0;
   f->output_data.mw32->frame_moving_or_sizing = 0;
   f->output_data.mw32->setcaret_event = CreateEvent (NULL, TRUE, FALSE, NULL);
   if (f->output_data.mw32->setcaret_event == NULL)
@@ -3041,7 +3038,7 @@
       specbind (Qx_resource_name, name);
     }
 
-  GET_TEMP_HDC (f);
+  GET_FRAME_HDC (f);
 
   /* Extract the window parameters from the supplied values
      that are needed to determine window geometry.  */
@@ -3249,7 +3246,7 @@
      and similar functions.  */
   Vwindow_list = Qnil;
 
-  RELEASE_TEMP_HDC (f);
+  RELEASE_FRAME_HDC (f);
   return unbind_to (count, frame);
 }
 
@@ -3997,9 +3994,7 @@
   /* all handles must be set to INVALID_HANLE_VALUE.  */
   f->output_data.mw32->menubar_handle = INVALID_HANDLE_VALUE;
   f->output_data.mw32->hdc = INVALID_HANDLE_VALUE;
-  f->output_data.mw32->hdc_refcount = 0;
-  f->output_data.mw32->message_thread_hdc = INVALID_HANDLE_VALUE;
-  f->output_data.mw32->message_thread_hdc_refcount = 0;
+  f->output_data.mw32->hdc_nestlevel = 0;
   InitializeCriticalSection (&(f->output_data.mw32->hdc_critsec));
 
   FRAME_MW32_DISPLAY_INFO (f) = dpyinfo;
Index: mw32font.c
===================================================================
--- mw32font.c	(revision 3987)
+++ mw32font.c	(working copy)
@@ -1466,7 +1466,7 @@
   LOADLFPROC proc;
   MW32LogicalFont *plf = NULL;;
 
-  GET_TEMP_HDC (f);
+  GET_FRAME_HDC (f);
 
   for (i = 0; i < mw32_lf_loader_num; i++)
     {
@@ -1482,7 +1482,7 @@
 	}
     }
 
-  RELEASE_TEMP_HDC (f);
+  RELEASE_FRAME_HDC (f);
   return plf;
 }
 
Index: image.c
===================================================================
--- image.c	(revision 3987)
+++ image.c	(working copy)
@@ -10059,7 +10059,7 @@
   RECT rect;
   unsigned char *bmpdata;
   struct frame *f = SELECTED_FRAME ();
-  HDC hdc = GET_TEMP_HDC (f);
+  HDC hdc = GET_FRAME_HDC (f);
   HDC cdc = CreateCompatibleDC (hdc);
 
   memset (&biheader, 0, sizeof (BITMAPINFOHEADER));
@@ -10089,7 +10089,7 @@
   DeleteObject (hbmp);
   DeleteDC (cdc);
 
-  RELEASE_TEMP_HDC (f);
+  RELEASE_FRAME_HDC (f);
 }
 
 Lisp_Object
Index: xdisp.c
===================================================================
--- xdisp.c	(revision 3987)
+++ xdisp.c	(working copy)
@@ -10954,6 +10954,7 @@
 	      if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
 #ifdef MEADOW
 		{
+		  CLEANUP_FRAME_HDC (f);
 		  GET_FRAME_HDC (f);
 #endif
 		  redisplay_windows (FRAME_ROOT_WINDOW (f));
Index: frame.c
===================================================================
--- frame.c	(revision 3987)
+++ frame.c	(working copy)
@@ -1277,6 +1277,7 @@
   /* during destroying the windows,
      we must block the message loop.  */
   W32_BLOCK_INPUT;
+  GET_FRAME_HDC (f); /* Use only side effect */
 #endif
   /* Free glyphs.
      This function must be called before the window tree of the
@@ -1289,6 +1290,7 @@
   delete_all_subwindows (XWINDOW (f->root_window));
   f->root_window = Qnil;
 #ifdef MEADOW
+  RELEASE_FRAME_HDC (f);
   W32_UNBLOCK_INPUT;
 #endif
 
Index: ChangeLog.Meadow
===================================================================
--- ChangeLog.Meadow	(revision 3987)
+++ ChangeLog.Meadow	(working copy)
@@ -1,3 +1,59 @@
+2005-11-27  Kyotaro HORIGUCHI  <horiguti@xxxxxxxxxxx>
+
+	* dispnew.c (update_frame): Do GET_FRAME_HDC().
+
+	* mw32term.c (main_thread_hdc): New global variable.
+	(main_thread_hdc_nestlevel): New global variable.
+	(main_thread_hdc_hwnd): New global variable.
+	(mw32_destroy_frame_hdc): Release message_thread hdc.
+	(mw32_set_caret): Reduce necessity of calling message thread.
+	(MW32_update_begin): Modified.
+	(MW32_update_end): Modified.
+	(mw32_process_main_thread_message<WM_EMACS_EXPOSE_FRAME>):
+	Removed.
+	(unwind_get_device_capability): Replace macro.
+
+	* mw32term.h (main_thread_hdc): New extern.
+	(main_thread_hdc_nestlevel): New extern.
+	(main_thread_hdc_hwnd): New extern.
+	(struct mw32_output): Member hdc_refcount is renamed to
+	hdc_nestlevel. Removed the member message_thread_hdc,
+	message_thread_hdc_refcount.
+	(FRAME_HDC): Modfied.
+	(GET_FRAME_HDC): Modified because of change of variable name.
+	(GET_TEMP_HDC): Removed.
+	(RELEASE_FRAME_HDC): Modified because of change of variable name.
+	(RELEASE_TEMP_HDC): Removed.
+	(CLEANUP_FRAME_HDC): New macro to do force release of hdc.
+	(update_begin_hook): New extern.
+	(update_end_hook): New extern.
+
+	* mw32sync.h (main_thread_id): New extern.
+	(W32_BLOCK_INPUT): Nop'ed.
+	(W32_UNBLOCK_INPUT): Ditto.
+	(W32_SELF_INPUT_BLOCKED_P): Always returns FALSE.
+
+	* mw32fns.c (mw32m_new_focus_frame): Change variable name.
+	(mw32_WndProc<WM_ERASEBKGND>): Ditto.
+	(mw32_WndProc<WM_PAINT>): Ditto.
+	(mw32_WndProc<WM_KILLFOCUS>): Clear caret block state.
+	(mw32_WndProc<WM_EMACS_SETCARET>): Protect from duplicate
+	blocking. Change unblock process.
+	(x-create-frame): Change variable name. Change the name of macro
+	GET_TEMP_HDC/RELEASE_TEMP_HDC to GET_FRAME_HDC/RELEASE_FRAME_HDC.
+	(mw32_create_tip_frame): Change variable name.
+
+	* mw32font.c (mw32_load_lf): Use GET/RELEAE_FRAME_HDC instead of
+	GET/RELEASE_TEMP_HDC.
+
+	* image.c (get_image_data_from_icon): Use GET/RELEAE_FRAME_HDC
+	instead of GET/RELEASE_TEMP_HDC.
+
+	* xdisp.c (redisplay_internal): Cleanup hdc.
+
+	* frame.c (delete-frame): Use GET/RELEASE_FRAME_HDC to block
+	expose-frame.
+
 2005-11-25  Kyotaro HORIGUCHI  <horiguti@xxxxxxxxxxx>
 
 	* mw32term.c (MW32_update_begin): W32_UNBLOCK_INPUT to avoid