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