Module: wine Branch: master Commit: 929052a9c6f8b2758bd86c7d67c4fe67cc537791 URL: https://source.winehq.org/git/wine.git/?a=commit;h=929052a9c6f8b2758bd86c7d6...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Mar 10 14:31:20 2022 +0100
win32u: Move NtUserGetWindowRgnEx 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
---
dlls/user32/winpos.c | 45 ++------------------------------------------- dlls/win32u/syscall.c | 1 + dlls/win32u/win32u.spec | 2 +- dlls/win32u/window.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ dlls/wow64win/syscall.h | 1 + dlls/wow64win/user.c | 9 +++++++++ include/ntuser.h | 1 + 7 files changed, 63 insertions(+), 44 deletions(-)
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index 1387552ca55..c4c61347704 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -97,50 +97,9 @@ BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect ) /*********************************************************************** * GetWindowRgn (USER32.@) */ -int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn ) +int WINAPI GetWindowRgn( HWND hwnd, HRGN hrgn ) { - int nRet = ERROR; - NTSTATUS status; - HRGN win_rgn = 0; - RGNDATA *data; - size_t size = 256; - - do - { - if (!(data = HeapAlloc( GetProcessHeap(), 0, sizeof(*data) + size - 1 ))) - { - SetLastError( ERROR_OUTOFMEMORY ); - return ERROR; - } - SERVER_START_REQ( get_window_region ) - { - req->window = wine_server_user_handle( hwnd ); - wine_server_set_reply( req, data->Buffer, size ); - if (!(status = wine_server_call( req ))) - { - size_t reply_size = wine_server_reply_size( reply ); - if (reply_size) - { - data->rdh.dwSize = sizeof(data->rdh); - data->rdh.iType = RDH_RECTANGLES; - data->rdh.nCount = reply_size / sizeof(RECT); - data->rdh.nRgnSize = reply_size; - win_rgn = ExtCreateRegion( NULL, data->rdh.dwSize + data->rdh.nRgnSize, data ); - } - } - else size = reply->total_size; - } - SERVER_END_REQ; - HeapFree( GetProcessHeap(), 0, data ); - } while (status == STATUS_BUFFER_OVERFLOW); - - if (status) SetLastError( RtlNtStatusToDosError(status) ); - else if (win_rgn) - { - nRet = CombineRgn( hrgn, win_rgn, 0, RGN_COPY ); - DeleteObject( win_rgn ); - } - return nRet; + return NtUserGetWindowRgnEx( hwnd, hrgn, 0 ); }
/*********************************************************************** diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index 0db90cc185d..41f9cfead49 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -139,6 +139,7 @@ static void * const syscalls[] = NtUserGetProp, NtUserGetSystemDpiForProcess, NtUserGetThreadDesktop, + NtUserGetWindowRgnEx, NtUserInitializeClientPfnArrays, NtUserInternalGetWindowText, NtUserNotifyWinEvent, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index fdc4aa153b0..5c493c54629 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1016,7 +1016,7 @@ @ stub NtUserGetWindowMinimizeRect @ stub NtUserGetWindowPlacement @ stub NtUserGetWindowProcessHandle -@ stub NtUserGetWindowRgnEx +@ stdcall -syscall NtUserGetWindowRgnEx(long long long) @ stub NtUserGhostWindowFromHungWindow @ stub NtUserHandleDelegatedInput @ stub NtUserHardErrorControl diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index abfc19de40a..2129afa405e 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1163,6 +1163,54 @@ static BOOL get_window_info( HWND hwnd, WINDOWINFO *info ) return TRUE; }
+/******************************************************************* + * NtUserGetWindowRgnEx (win32u.@) + */ +int WINAPI NtUserGetWindowRgnEx( HWND hwnd, HRGN hrgn, UINT unk ) +{ + NTSTATUS status; + HRGN win_rgn = 0; + RGNDATA *data; + size_t size = 256; + int ret = ERROR; + + do + { + if (!(data = malloc( sizeof(*data) + size - 1 ))) + { + SetLastError( ERROR_OUTOFMEMORY ); + return ERROR; + } + SERVER_START_REQ( get_window_region ) + { + req->window = wine_server_user_handle( hwnd ); + wine_server_set_reply( req, data->Buffer, size ); + if (!(status = wine_server_call( req ))) + { + size_t reply_size = wine_server_reply_size( reply ); + if (reply_size) + { + data->rdh.dwSize = sizeof(data->rdh); + data->rdh.iType = RDH_RECTANGLES; + data->rdh.nCount = reply_size / sizeof(RECT); + data->rdh.nRgnSize = reply_size; + win_rgn = NtGdiExtCreateRegion( NULL, data->rdh.dwSize + data->rdh.nRgnSize, data ); + } + } + else size = reply->total_size; + } + SERVER_END_REQ; + free( data ); + } while (status == STATUS_BUFFER_OVERFLOW); + + if (set_ntstatus( status ) && win_rgn) + { + ret = NtGdiCombineRgn( hrgn, win_rgn, 0, RGN_COPY ); + NtGdiDeleteObjectApp( win_rgn ); + } + return ret; +} + /***************************************************************************** * NtUserGetLayeredWindowAttributes (win32u.@) */ diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 303d719d3a8..82262cd83ab 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -124,6 +124,7 @@ SYSCALL_ENTRY( NtUserGetProp ) \ SYSCALL_ENTRY( NtUserGetSystemDpiForProcess ) \ SYSCALL_ENTRY( NtUserGetThreadDesktop ) \ + SYSCALL_ENTRY( NtUserGetWindowRgnEx ) \ SYSCALL_ENTRY( NtUserInitializeClientPfnArrays ) \ SYSCALL_ENTRY( NtUserInternalGetWindowText ) \ SYSCALL_ENTRY( NtUserNotifyWinEvent ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 18486c92305..4ee05838b47 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -197,6 +197,15 @@ NTSTATUS WINAPI wow64_NtUserGetAncestor( UINT *args ) return HandleToUlong( NtUserGetAncestor( hwnd, type )); }
+NTSTATUS WINAPI wow64_NtUserGetWindowRgnEx( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HRGN hrgn = get_handle( &args ); + UINT unk = get_ulong( &args ); + + return NtUserGetWindowRgnEx( hwnd, hrgn, unk ); +} + NTSTATUS WINAPI wow64_NtUserBuildHwndList( UINT *args ) { HDESK desktop = get_handle( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index 547471daf69..25d58de5992 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -333,6 +333,7 @@ DWORD WINAPI NtUserGetQueueStatus( UINT flags ); ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process ); HDESK WINAPI NtUserGetThreadDesktop( DWORD thread ); 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, const struct user_client_procs *client_procsW, const void *client_workers, HINSTANCE user_module );