Moved WIN_FindWinToRepaint functionality to the server.
This commit is contained in:
parent
272023190e
commit
47f9821817
|
@ -1884,17 +1884,11 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
|
|||
/* 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 );
|
||||
}
|
||||
|
|
|
@ -92,7 +92,6 @@ extern void WIN_SetOwner( HWND hwnd, HWND owner );
|
|||
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);
|
||||
|
|
|
@ -891,11 +891,11 @@ DECL_HANDLER(get_message)
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -36,5 +36,6 @@ extern void queue_cleanup_window( struct thread *thread, user_handle_t win );
|
|||
|
||||
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 */
|
||||
|
|
|
@ -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 @@ int is_child_window( user_handle_t parent, user_handle_t child )
|
|||
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 @@ DECL_HANDLER(inc_window_paint_count)
|
|||
{
|
||||
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;
|
||||
|
|
104
windows/win.c
104
windows/win.c
|
@ -564,110 +564,6 @@ void WIN_SetRectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClien
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue