Moved WIN_FindWinToRepaint functionality to the server.
diff --git a/dlls/user/message.c b/dlls/user/message.c
index 4a0dab3..e5e38a2 100644
--- a/dlls/user/message.c
+++ b/dlls/user/message.c
@@ -1884,17 +1884,11 @@
/* need to fill the window handle for WM_PAINT message */
if (msg.message == WM_PAINT)
{
- if (!(msg.hwnd = WIN_FindWinToRepaint( hwnd ))) return FALSE;
-
if (IsIconic( msg.hwnd ) && GetClassLongA( msg.hwnd, GCL_HICON ))
{
msg.message = WM_PAINTICON;
msg.wParam = 1;
}
-
- /* check hwnd filter */
- if (hwnd && msg.hwnd != hwnd && !IsChild( hwnd, msg.hwnd )) return FALSE;
-
/* clear internal paint flag */
RedrawWindow( msg.hwnd, NULL, 0, RDW_NOINTERNALPAINT | RDW_NOCHILDREN );
}
diff --git a/include/win.h b/include/win.h
index 6c8d577..d1679a6 100644
--- a/include/win.h
+++ b/include/win.h
@@ -92,7 +92,6 @@
extern LONG WIN_SetStyle( HWND hwnd, LONG style );
extern LONG WIN_SetExStyle( HWND hwnd, LONG style );
extern void WIN_SetRectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClient );
-extern HWND WIN_FindWinToRepaint( HWND hwnd );
extern LRESULT WIN_DestroyWindow( HWND hwnd );
extern void WIN_DestroyThreadWindows( HWND hwnd );
extern BOOL WIN_CreateDesktopWindow(void);
diff --git a/server/queue.c b/server/queue.c
index 76da322..b72f31c 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -891,11 +891,11 @@
}
/* now check for WM_PAINT */
- if ((queue->wake_bits & QS_PAINT) &&
- (WM_PAINT >= req->get_first) && (WM_PAINT <= req->get_last))
+ if (queue->paint_count &&
+ (WM_PAINT >= req->get_first) && (WM_PAINT <= req->get_last) &&
+ (req->win = find_window_to_repaint( get_win, current )))
{
req->type = MSG_POSTED;
- req->win = 0;
req->msg = WM_PAINT;
req->wparam = 0;
req->lparam = 0;
diff --git a/server/user.h b/server/user.h
index 5c6c4ce..884088a 100644
--- a/server/user.h
+++ b/server/user.h
@@ -36,5 +36,6 @@
extern void destroy_thread_windows( struct thread *thread );
extern int is_child_window( user_handle_t parent, user_handle_t child );
+extern user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *thread );
#endif /* __WINE_SERVER_USER_H */
diff --git a/server/window.c b/server/window.c
index 430e7c5..8e8af4b 100644
--- a/server/window.c
+++ b/server/window.c
@@ -6,6 +6,10 @@
#include <assert.h>
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+
#include "object.h"
#include "request.h"
#include "thread.h"
@@ -325,6 +329,47 @@
return 0;
}
+
+/* find a child of the specified window that needs repainting */
+static struct window *find_child_to_repaint( struct window *parent, struct thread *thread )
+{
+ struct window *ptr, *ret = NULL;
+
+ for (ptr = parent->first_child; ptr && !ret; ptr = ptr->next)
+ {
+ if (!(ptr->style & WS_VISIBLE)) continue;
+ if (ptr->paint_count && ptr->thread == thread)
+ ret = ptr;
+ else /* explore its children */
+ ret = find_child_to_repaint( ptr, thread );
+ }
+
+ if (ret && (ret->ex_style & WS_EX_TRANSPARENT))
+ {
+ /* transparent window, check for non-transparent sibling to paint first */
+ for (ptr = ret->next; ptr; ptr = ptr->next)
+ {
+ if (!(ptr->style & WS_VISIBLE)) continue;
+ if (ptr->ex_style & WS_EX_TRANSPARENT) continue;
+ if (ptr->paint_count && ptr->thread == thread) return ptr;
+ }
+ }
+ return ret;
+}
+
+
+/* find a window that needs repainting */
+user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *thread )
+{
+ struct window *win = parent ? get_window( parent ) : top_window;
+
+ if (!win || !(win->style & WS_VISIBLE)) return 0;
+ if (!win->paint_count || win->thread != thread)
+ win = find_child_to_repaint( win, thread );
+ return win ? win->handle : 0;
+}
+
+
/* create a window */
DECL_HANDLER(create_window)
{
@@ -612,7 +657,7 @@
{
struct window *win = get_window( req->handle );
- if (win)
+ if (win && win->thread)
{
int old = win->paint_count;
if ((win->paint_count += req->incr) < 0) win->paint_count = 0;
diff --git a/windows/win.c b/windows/win.c
index e92f0bb..b7d5a9a 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -565,110 +565,6 @@
/***********************************************************************
- * find_child_to_repaint
- *
- * Find a window that needs repaint among the children of the specified window.
- */
-static HWND find_child_to_repaint( HWND parent )
-{
- int i;
- HWND ret = 0;
- HWND *list;
-
- if (!parent) parent = GetDesktopWindow();
- if (!(list = list_window_children( parent, 0, 0 ))) return 0;
-
- for (i = 0; list[i] && !ret; i++)
- {
- WND *win = WIN_GetPtr( list[i] );
- if (!win) continue; /* ignore it */
- if (win == WND_OTHER_PROCESS)
- {
- /* doesn't belong to this process, but check children */
- ret = find_child_to_repaint( list[i] );
- continue;
- }
- if (!(win->dwStyle & WS_VISIBLE))
- {
- WIN_ReleasePtr( win );
- continue;
- }
- if ((win->tid != GetCurrentThreadId()) ||
- (!win->hrgnUpdate && !(win->flags & WIN_INTERNAL_PAINT)))
- {
- /* does not need repaint, check children */
- WIN_ReleasePtr( win );
- ret = find_child_to_repaint( list[i] );
- continue;
- }
-
- /* now we have something */
- ret = list[i];
- if (!(win->dwExStyle & WS_EX_TRANSPARENT))
- {
- /* not transparent, we can repaint it */
- WIN_ReleasePtr( win );
- break;
- }
- WIN_ReleasePtr( win );
-
- /* transparent window, look for non-transparent sibling to paint first */
- for (i++; list[i]; i++)
- {
- if (!(win = WIN_GetPtr( list[i] ))) continue;
- if (win == WND_OTHER_PROCESS) continue;
- if (!(win->dwStyle & WS_VISIBLE))
- {
- WIN_ReleasePtr( win );
- continue;
- }
- if (!(win->dwExStyle & WS_EX_TRANSPARENT) &&
- (win->hrgnUpdate || (win->flags & WIN_INTERNAL_PAINT)))
- {
- ret = list[i];
- WIN_ReleasePtr( win );
- break;
- }
- WIN_ReleasePtr( win );
- }
- }
- HeapFree( GetProcessHeap(), 0, list );
- return ret;
-}
-
-
-/***********************************************************************
- * WIN_FindWinToRepaint
- *
- * Find a window that needs repaint.
- */
-HWND WIN_FindWinToRepaint( HWND hwnd )
-{
- /* Note: the desktop window never gets WM_PAINT messages
- * The real reason why is because Windows DesktopWndProc
- * does ValidateRgn inside WM_ERASEBKGND handler.
- */
- if (hwnd == GetDesktopWindow()) hwnd = 0;
-
- if (hwnd)
- {
- /* check the window itself first */
- WND *win = WIN_FindWndPtr( hwnd );
- if (!win) return 0;
- if ((win->dwStyle & WS_VISIBLE) &&
- (win->hrgnUpdate || (win->flags & WIN_INTERNAL_PAINT)))
- {
- WIN_ReleaseWndPtr( win );
- return hwnd;
- }
- WIN_ReleaseWndPtr( win );
- }
- /* now check its children */
- return find_child_to_repaint( hwnd );
-}
-
-
-/***********************************************************************
* WIN_DestroyWindow
*
* Destroy storage associated to a window. "Internals" p.358