mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-15 14:02:01 +00:00
win32u: Move NtUserGetUpdateRgn implementation from user32.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
45e0afbca4
commit
d942281a00
|
@ -3943,7 +3943,7 @@ LRESULT WINAPI DECLSPEC_HOTPATCH DispatchMessageA( const MSG* msg )
|
|||
{
|
||||
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
|
||||
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
GetUpdateRgn( msg->hwnd, hrgn, TRUE );
|
||||
NtUserGetUpdateRgn( msg->hwnd, hrgn, TRUE );
|
||||
DeleteObject( hrgn );
|
||||
}
|
||||
return retval;
|
||||
|
@ -4014,7 +4014,7 @@ LRESULT WINAPI DECLSPEC_HOTPATCH DispatchMessageW( const MSG* msg )
|
|||
{
|
||||
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
|
||||
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
GetUpdateRgn( msg->hwnd, hrgn, TRUE );
|
||||
NtUserGetUpdateRgn( msg->hwnd, hrgn, TRUE );
|
||||
DeleteObject( hrgn );
|
||||
}
|
||||
return retval;
|
||||
|
|
|
@ -611,36 +611,6 @@ BOOL WINAPI ValidateRect( HWND hwnd, const RECT *rect )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetUpdateRgn (USER32.@)
|
||||
*/
|
||||
INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
|
||||
{
|
||||
DPI_AWARENESS_CONTEXT context;
|
||||
INT retval = ERROR;
|
||||
UINT flags = UPDATE_NOCHILDREN;
|
||||
HRGN update_rgn;
|
||||
|
||||
context = SetThreadDpiAwarenessContext( GetWindowDpiAwarenessContext( hwnd ));
|
||||
|
||||
if (erase) flags |= UPDATE_NONCLIENT | UPDATE_ERASE;
|
||||
|
||||
if ((update_rgn = send_ncpaint( hwnd, NULL, &flags )))
|
||||
{
|
||||
retval = CombineRgn( hrgn, update_rgn, 0, RGN_COPY );
|
||||
if (send_erase( hwnd, flags, update_rgn, NULL, NULL ))
|
||||
{
|
||||
flags = UPDATE_DELAYED_ERASE;
|
||||
get_update_flags( hwnd, NULL, &flags );
|
||||
}
|
||||
/* map region to client coordinates */
|
||||
map_window_region( 0, hwnd, hrgn );
|
||||
}
|
||||
SetThreadDpiAwarenessContext( context );
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetUpdateRect (USER32.@)
|
||||
*/
|
||||
|
@ -685,7 +655,7 @@ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
|
|||
INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd )
|
||||
{
|
||||
HRGN update_rgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
INT ret = GetUpdateRgn( hwnd, update_rgn, FALSE );
|
||||
INT ret = NtUserGetUpdateRgn( hwnd, update_rgn, FALSE );
|
||||
|
||||
if (ret != ERROR)
|
||||
{
|
||||
|
@ -772,7 +742,7 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC
|
|||
* scrolled as well. Keep a copy in hrgnWinupd
|
||||
* to be added to hrngUpdate at the end. */
|
||||
hrgnTemp = CreateRectRgn( 0, 0, 0, 0 );
|
||||
retVal = GetUpdateRgn( hwnd, hrgnTemp, FALSE );
|
||||
retVal = NtUserGetUpdateRgn( hwnd, hrgnTemp, FALSE );
|
||||
if (retVal != NULLREGION)
|
||||
{
|
||||
HRGN hrgnClip = CreateRectRgnIndirect(&cliprc);
|
||||
|
|
|
@ -393,7 +393,7 @@
|
|||
@ stdcall GetTopWindow(long)
|
||||
@ stdcall GetTouchInputInfo(long long ptr long)
|
||||
@ stdcall GetUpdateRect(long ptr long)
|
||||
@ stdcall GetUpdateRgn(long long long)
|
||||
@ stdcall GetUpdateRgn(long long long) NtUserGetUpdateRgn
|
||||
@ stdcall GetUpdatedClipboardFormats(ptr long ptr) NtUserGetUpdatedClipboardFormats
|
||||
@ stdcall GetUserObjectInformationA (long long ptr long ptr)
|
||||
@ stdcall GetUserObjectInformationW (long long ptr long ptr) NtUserGetObjectInformation
|
||||
|
|
|
@ -45,7 +45,6 @@ extern HWND WIN_IsCurrentThread( HWND hwnd ) DECLSPEC_HIDDEN;
|
|||
extern UINT win_set_flags( HWND hwnd, UINT set_mask, UINT clear_mask ) DECLSPEC_HIDDEN;
|
||||
extern ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits ) DECLSPEC_HIDDEN;
|
||||
extern BOOL WIN_GetRectangles( HWND hwnd, enum coords_relative relative, RECT *rectWindow, RECT *rectClient ) DECLSPEC_HIDDEN;
|
||||
extern void map_window_region( HWND from, HWND to, HRGN hrgn ) DECLSPEC_HIDDEN;
|
||||
extern LRESULT WIN_DestroyWindow( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern void destroy_thread_windows(void) DECLSPEC_HIDDEN;
|
||||
extern HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, BOOL unicode ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -404,43 +404,6 @@ static BOOL WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, BOOL *mirrored, POI
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* map coordinates of a window region */
|
||||
void map_window_region( HWND from, HWND to, HRGN hrgn )
|
||||
{
|
||||
BOOL mirrored;
|
||||
POINT offset;
|
||||
UINT i, size;
|
||||
RGNDATA *data;
|
||||
HRGN new_rgn;
|
||||
RECT *rect;
|
||||
|
||||
if (!WINPOS_GetWinOffset( from, to, &mirrored, &offset )) return;
|
||||
|
||||
if (!mirrored)
|
||||
{
|
||||
OffsetRgn( hrgn, offset.x, offset.y );
|
||||
return;
|
||||
}
|
||||
if (!(size = GetRegionData( hrgn, 0, NULL ))) return;
|
||||
if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
|
||||
GetRegionData( hrgn, size, data );
|
||||
rect = (RECT *)data->Buffer;
|
||||
for (i = 0; i < data->rdh.nCount; i++)
|
||||
{
|
||||
int tmp = -(rect[i].left + offset.x);
|
||||
rect[i].left = -(rect[i].right + offset.x);
|
||||
rect[i].right = tmp;
|
||||
rect[i].top += offset.y;
|
||||
rect[i].bottom += offset.y;
|
||||
}
|
||||
if ((new_rgn = ExtCreateRegion( NULL, data->rdh.dwSize + data->rdh.nRgnSize, data )))
|
||||
{
|
||||
CombineRgn( hrgn, new_rgn, 0, RGN_COPY );
|
||||
DeleteObject( new_rgn );
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* MapWindowPoints (USER32.@)
|
||||
|
|
|
@ -548,7 +548,7 @@ void invalidate_dce( WND *win, const RECT *extra_rect )
|
|||
if (!win->parent) return;
|
||||
|
||||
context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( win->obj.handle ));
|
||||
get_window_rects( win->obj.handle, COORDS_SCREEN, &window_rect, NULL, get_thread_dpi() );
|
||||
get_window_rect( win->obj.handle, &window_rect, get_thread_dpi() );
|
||||
|
||||
TRACE("%p parent %p %s (%s)\n",
|
||||
win->obj.handle, win->parent, wine_dbgstr_rect(&window_rect), wine_dbgstr_rect(extra_rect) );
|
||||
|
@ -576,7 +576,7 @@ void invalidate_dce( WND *win, const RECT *extra_rect )
|
|||
if (win->parent == dce->hwnd || is_child( win->parent, dce->hwnd ))
|
||||
{
|
||||
RECT dce_rect, tmp;
|
||||
get_window_rects( dce->hwnd, COORDS_SCREEN, &dce_rect, NULL, get_thread_dpi() );
|
||||
get_window_rect( dce->hwnd, &dce_rect, get_thread_dpi() );
|
||||
if (intersect_rect( &tmp, &dce_rect, &window_rect ) ||
|
||||
(extra_rect && intersect_rect( &tmp, &dce_rect, extra_rect )))
|
||||
make_dc_dirty( dce );
|
||||
|
@ -1138,3 +1138,32 @@ BOOL WINAPI NtUserRedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT fla
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserGetUpdateRgn (win32u.@)
|
||||
*/
|
||||
INT WINAPI NtUserGetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
|
||||
{
|
||||
DPI_AWARENESS_CONTEXT context;
|
||||
INT retval = ERROR;
|
||||
UINT flags = UPDATE_NOCHILDREN;
|
||||
HRGN update_rgn;
|
||||
|
||||
context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( hwnd ));
|
||||
|
||||
if (erase) flags |= UPDATE_NONCLIENT | UPDATE_ERASE;
|
||||
|
||||
if ((update_rgn = send_ncpaint( hwnd, NULL, &flags )))
|
||||
{
|
||||
retval = NtGdiCombineRgn( hrgn, update_rgn, 0, RGN_COPY );
|
||||
if (send_erase( hwnd, flags, update_rgn, NULL, NULL ))
|
||||
{
|
||||
flags = UPDATE_DELAYED_ERASE;
|
||||
get_update_flags( hwnd, NULL, &flags );
|
||||
}
|
||||
/* map region to client coordinates */
|
||||
map_window_region( 0, hwnd, hrgn );
|
||||
}
|
||||
set_thread_dpi_awareness_context( context );
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -1177,6 +1177,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtUserGetKeyboardLayoutList,
|
||||
NtUserGetPriorityClipboardFormat,
|
||||
NtUserGetQueueStatus,
|
||||
NtUserGetUpdateRgn,
|
||||
NtUserGetUpdatedClipboardFormats,
|
||||
NtUserIsClipboardFormatAvailable,
|
||||
NtUserMapVirtualKeyEx,
|
||||
|
|
|
@ -1003,7 +1003,7 @@
|
|||
@ stub NtUserGetTouchValidationStatus
|
||||
@ stub NtUserGetUniformSpaceMapping
|
||||
@ stub NtUserGetUpdateRect
|
||||
@ stub NtUserGetUpdateRgn
|
||||
@ stdcall NtUserGetUpdateRgn(long long long)
|
||||
@ stdcall NtUserGetUpdatedClipboardFormats(ptr long ptr)
|
||||
@ stub NtUserGetWOWClass
|
||||
@ stub NtUserGetWindowBand
|
||||
|
|
|
@ -218,6 +218,7 @@ struct unix_funcs
|
|||
UINT (WINAPI *pNtUserGetKeyboardLayoutList)( INT size, HKL *layouts );
|
||||
INT (WINAPI *pNtUserGetPriorityClipboardFormat)( UINT *list, INT count );
|
||||
DWORD (WINAPI *pNtUserGetQueueStatus)( UINT flags );
|
||||
INT (WINAPI *pNtUserGetUpdateRgn)( HWND hwnd, HRGN hrgn, BOOL erase );
|
||||
BOOL (WINAPI *pNtUserGetUpdatedClipboardFormats)( UINT *formats, UINT size, UINT *out_size );
|
||||
BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format );
|
||||
UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout );
|
||||
|
@ -346,6 +347,7 @@ extern BOOL get_window_rects( HWND hwnd, enum coords_relative relative, RECT *wi
|
|||
RECT *client_rect, UINT dpi ) DECLSPEC_HIDDEN;
|
||||
extern HWND *list_window_children( HDESK desktop, HWND hwnd, UNICODE_STRING *class,
|
||||
DWORD tid ) DECLSPEC_HIDDEN;
|
||||
extern void map_window_region( HWND from, HWND to, HRGN hrgn ) DECLSPEC_HIDDEN;
|
||||
extern void update_window_state( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* to release pointers retrieved by win_get_ptr */
|
||||
|
|
|
@ -1762,6 +1762,156 @@ INT WINAPI NtUserInternalGetWindowText( HWND hwnd, WCHAR *text, INT count )
|
|||
return lstrlenW(text);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* get_windows_offset
|
||||
*
|
||||
* Calculate the offset between the origin of the two windows. Used
|
||||
* to implement MapWindowPoints.
|
||||
*/
|
||||
static BOOL get_windows_offset( HWND hwnd_from, HWND hwnd_to, BOOL *mirrored, POINT *ret_offset )
|
||||
{
|
||||
WND *win;
|
||||
POINT offset;
|
||||
BOOL mirror_from, mirror_to, ret;
|
||||
HWND hwnd;
|
||||
|
||||
offset.x = offset.y = 0;
|
||||
*mirrored = mirror_from = mirror_to = FALSE;
|
||||
|
||||
/* Translate source window origin to screen coords */
|
||||
if (hwnd_from)
|
||||
{
|
||||
if (!(win = get_win_ptr( hwnd_from )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
if (win == WND_OTHER_PROCESS) goto other_process;
|
||||
if (win != WND_DESKTOP)
|
||||
{
|
||||
if (win->dwExStyle & WS_EX_LAYOUTRTL)
|
||||
{
|
||||
mirror_from = TRUE;
|
||||
offset.x += win->client_rect.right - win->client_rect.left;
|
||||
}
|
||||
while (win->parent)
|
||||
{
|
||||
offset.x += win->client_rect.left;
|
||||
offset.y += win->client_rect.top;
|
||||
hwnd = win->parent;
|
||||
release_win_ptr( win );
|
||||
if (!(win = get_win_ptr( hwnd ))) break;
|
||||
if (win == WND_OTHER_PROCESS) goto other_process;
|
||||
if (win == WND_DESKTOP) break;
|
||||
if (win->flags & WIN_CHILDREN_MOVED)
|
||||
{
|
||||
release_win_ptr( win );
|
||||
goto other_process;
|
||||
}
|
||||
}
|
||||
if (win && win != WND_DESKTOP) release_win_ptr( win );
|
||||
offset = map_dpi_point( offset, get_dpi_for_window( hwnd_from ), get_thread_dpi() );
|
||||
}
|
||||
}
|
||||
|
||||
/* Translate origin to destination window coords */
|
||||
if (hwnd_to)
|
||||
{
|
||||
if (!(win = get_win_ptr( hwnd_to )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
if (win == WND_OTHER_PROCESS) goto other_process;
|
||||
if (win != WND_DESKTOP)
|
||||
{
|
||||
POINT pt = { 0, 0 };
|
||||
if (win->dwExStyle & WS_EX_LAYOUTRTL)
|
||||
{
|
||||
mirror_to = TRUE;
|
||||
pt.x += win->client_rect.right - win->client_rect.left;
|
||||
}
|
||||
while (win->parent)
|
||||
{
|
||||
pt.x += win->client_rect.left;
|
||||
pt.y += win->client_rect.top;
|
||||
hwnd = win->parent;
|
||||
release_win_ptr( win );
|
||||
if (!(win = get_win_ptr( hwnd ))) break;
|
||||
if (win == WND_OTHER_PROCESS) goto other_process;
|
||||
if (win == WND_DESKTOP) break;
|
||||
if (win->flags & WIN_CHILDREN_MOVED)
|
||||
{
|
||||
release_win_ptr( win );
|
||||
goto other_process;
|
||||
}
|
||||
}
|
||||
if (win && win != WND_DESKTOP) release_win_ptr( win );
|
||||
pt = map_dpi_point( pt, get_dpi_for_window( hwnd_to ), get_thread_dpi() );
|
||||
offset.x -= pt.x;
|
||||
offset.y -= pt.y;
|
||||
}
|
||||
}
|
||||
|
||||
*mirrored = mirror_from ^ mirror_to;
|
||||
if (mirror_from) offset.x = -offset.x;
|
||||
*ret_offset = offset;
|
||||
return TRUE;
|
||||
|
||||
other_process: /* one of the parents may belong to another process, do it the hard way */
|
||||
SERVER_START_REQ( get_windows_offset )
|
||||
{
|
||||
req->from = wine_server_user_handle( hwnd_from );
|
||||
req->to = wine_server_user_handle( hwnd_to );
|
||||
req->dpi = get_thread_dpi();
|
||||
if ((ret = !wine_server_call_err( req )))
|
||||
{
|
||||
ret_offset->x = reply->x;
|
||||
ret_offset->y = reply->y;
|
||||
*mirrored = reply->mirror;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* map coordinates of a window region */
|
||||
void map_window_region( HWND from, HWND to, HRGN hrgn )
|
||||
{
|
||||
BOOL mirrored;
|
||||
POINT offset;
|
||||
UINT i, size;
|
||||
RGNDATA *data;
|
||||
HRGN new_rgn;
|
||||
RECT *rect;
|
||||
|
||||
if (!get_windows_offset( from, to, &mirrored, &offset )) return;
|
||||
|
||||
if (!mirrored)
|
||||
{
|
||||
NtGdiOffsetRgn( hrgn, offset.x, offset.y );
|
||||
return;
|
||||
}
|
||||
if (!(size = NtGdiGetRegionData( hrgn, 0, NULL ))) return;
|
||||
if (!(data = malloc( size ))) return;
|
||||
NtGdiGetRegionData( hrgn, size, data );
|
||||
rect = (RECT *)data->Buffer;
|
||||
for (i = 0; i < data->rdh.nCount; i++)
|
||||
{
|
||||
int tmp = -(rect[i].left + offset.x);
|
||||
rect[i].left = -(rect[i].right + offset.x);
|
||||
rect[i].right = tmp;
|
||||
rect[i].top += offset.y;
|
||||
rect[i].bottom += offset.y;
|
||||
}
|
||||
if ((new_rgn = NtGdiExtCreateRegion( NULL, data->rdh.dwSize + data->rdh.nRgnSize, data )))
|
||||
{
|
||||
NtGdiCombineRgn( hrgn, new_rgn, 0, RGN_COPY );
|
||||
NtGdiDeleteObjectApp( new_rgn );
|
||||
}
|
||||
free( data );
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* update_window_state
|
||||
*
|
||||
|
|
|
@ -858,6 +858,12 @@ INT WINAPI NtUserGetKeyNameText( LONG lparam, WCHAR *buffer, INT size )
|
|||
return unix_funcs->pNtUserGetKeyNameText( lparam, buffer, size );
|
||||
}
|
||||
|
||||
INT WINAPI NtUserGetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
|
||||
{
|
||||
if (!unix_funcs) return 0;
|
||||
return unix_funcs->pNtUserGetUpdateRgn( hwnd, hrgn, erase );
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserMoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint )
|
||||
{
|
||||
if (!unix_funcs) return 0;
|
||||
|
|
|
@ -349,6 +349,7 @@ ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process );
|
|||
DWORD WINAPI NtUserGetQueueStatus( UINT flags );
|
||||
ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process );
|
||||
HDESK WINAPI NtUserGetThreadDesktop( DWORD thread );
|
||||
INT WINAPI NtUserGetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase );
|
||||
BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size );
|
||||
int WINAPI NtUserGetWindowRgnEx( HWND hwnd, HRGN hrgn, UINT unk );
|
||||
NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs *client_procsA,
|
||||
|
|
Loading…
Reference in a new issue