Commit 5cc5fdff authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move DWP object implementation from user32.

parent 08b2fbcb
......@@ -63,15 +63,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
#define PLACE_MAX 0x0002
#define PLACE_RECT 0x0004
typedef struct
{
struct user_object obj;
INT actualCount;
INT suggestedCount;
HWND hwndParent;
WINDOWPOS *winPos;
} DWP;
/***********************************************************************
* SwitchToThisWindow (USER32.@)
......@@ -1451,22 +1442,6 @@ LONG WINPOS_HandleWindowPosChanging( HWND hwnd, WINDOWPOS *winpos )
/***********************************************************************
* map_dpi_winpos
*/
static void map_dpi_winpos( WINDOWPOS *winpos )
{
UINT dpi_from = get_thread_dpi();
UINT dpi_to = GetDpiForWindow( winpos->hwnd );
if (!dpi_from) dpi_from = get_win_monitor_dpi( winpos->hwnd );
if (dpi_from == dpi_to) return;
winpos->x = MulDiv( winpos->x, dpi_to, dpi_from );
winpos->y = MulDiv( winpos->y, dpi_to, dpi_from );
winpos->cx = MulDiv( winpos->cx, dpi_to, dpi_from );
winpos->cy = MulDiv( winpos->cy, dpi_to, dpi_from );
}
/***********************************************************************
* SWP_DoWinPosChanging
*/
static BOOL SWP_DoWinPosChanging( WINDOWPOS *pWinpos, RECT *old_window_rect, RECT *old_client_rect,
......@@ -2205,118 +2180,17 @@ done:
*/
HDWP WINAPI BeginDeferWindowPos( INT count )
{
HDWP handle = 0;
DWP *pDWP;
TRACE("%d\n", count);
if (count < 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* Windows allows zero count, in which case it allocates context for 8 moves */
if (count == 0) count = 8;
if (!(pDWP = HeapAlloc( GetProcessHeap(), 0, sizeof(DWP)))) return 0;
pDWP->actualCount = 0;
pDWP->suggestedCount = count;
pDWP->hwndParent = 0;
if (!(pDWP->winPos = HeapAlloc( GetProcessHeap(), 0, count * sizeof(WINDOWPOS) )) ||
!(handle = alloc_user_handle( &pDWP->obj, NTUSER_OBJ_WINPOS )))
{
HeapFree( GetProcessHeap(), 0, pDWP->winPos );
HeapFree( GetProcessHeap(), 0, pDWP );
}
TRACE("returning hdwp %p\n", handle);
return handle;
return UlongToHandle( NtUserCallOneParam( count, NtUserBeginDeferWindowPos ));
}
/***********************************************************************
* DeferWindowPos (USER32.@)
*/
HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
INT x, INT y, INT cx, INT cy,
UINT flags )
HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND after, INT x, INT y,
INT cx, INT cy, UINT flags )
{
DWP *pDWP;
int i;
HDWP retvalue = hdwp;
WINDOWPOS winpos;
TRACE("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
hdwp, hwnd, hwndAfter, x, y, cx, cy, flags);
winpos.hwnd = WIN_GetFullHandle( hwnd );
if (is_desktop_window( winpos.hwnd ) || !IsWindow( winpos.hwnd ))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
winpos.hwndInsertAfter = WIN_GetFullHandle(hwndAfter);
winpos.flags = flags;
winpos.x = x;
winpos.y = y;
winpos.cx = cx;
winpos.cy = cy;
map_dpi_winpos( &winpos );
if (!(pDWP = get_user_handle_ptr( hdwp, NTUSER_OBJ_WINPOS ))) return 0;
if (pDWP == OBJ_OTHER_PROCESS)
{
FIXME( "other process handle %p?\n", hdwp );
return 0;
}
for (i = 0; i < pDWP->actualCount; i++)
{
if (pDWP->winPos[i].hwnd == winpos.hwnd)
{
/* Merge with the other changes */
if (!(flags & SWP_NOZORDER))
{
pDWP->winPos[i].hwndInsertAfter = winpos.hwndInsertAfter;
}
if (!(flags & SWP_NOMOVE))
{
pDWP->winPos[i].x = winpos.x;
pDWP->winPos[i].y = winpos.y;
}
if (!(flags & SWP_NOSIZE))
{
pDWP->winPos[i].cx = winpos.cx;
pDWP->winPos[i].cy = winpos.cy;
}
pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
SWP_NOZORDER | SWP_NOREDRAW |
SWP_NOACTIVATE | SWP_NOCOPYBITS|
SWP_NOOWNERZORDER);
pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
SWP_FRAMECHANGED);
goto END;
}
}
if (pDWP->actualCount >= pDWP->suggestedCount)
{
WINDOWPOS *newpos = HeapReAlloc( GetProcessHeap(), 0, pDWP->winPos,
pDWP->suggestedCount * 2 * sizeof(WINDOWPOS) );
if (!newpos)
{
retvalue = 0;
goto END;
}
pDWP->suggestedCount *= 2;
pDWP->winPos = newpos;
}
pDWP->winPos[pDWP->actualCount++] = winpos;
END:
release_user_handle_ptr( pDWP );
return retvalue;
return NtUserDeferWindowPosAndBand( hdwp, hwnd, after, x, y, cx, cy, flags, 0, 0 );
}
......@@ -2325,33 +2199,7 @@ END:
*/
BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
{
DWP *pDWP;
WINDOWPOS *winpos;
int i;
TRACE("%p\n", hdwp);
if (!(pDWP = free_user_handle( hdwp, NTUSER_OBJ_WINPOS ))) return FALSE;
if (pDWP == OBJ_OTHER_PROCESS)
{
FIXME( "other process handle %p?\n", hdwp );
return FALSE;
}
for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
{
TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
winpos->hwnd, winpos->hwndInsertAfter, winpos->x, winpos->y,
winpos->cx, winpos->cy, winpos->flags);
if (WIN_IsCurrentThread( winpos->hwnd ))
USER_SetWindowPos( winpos, 0, 0 );
else
SendMessageW( winpos->hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)winpos );
}
HeapFree( GetProcessHeap(), 0, pDWP->winPos );
HeapFree( GetProcessHeap(), 0, pDWP );
return TRUE;
return NtUserEndDeferWindowPosEx( hdwp, FALSE );
}
......
......@@ -1160,8 +1160,10 @@ static struct unix_funcs unix_funcs =
NtUserChangeDisplaySettings,
NtUserClipCursor,
NtUserCountClipboardFormats,
NtUserDeferWindowPosAndBand,
NtUserDestroyCursor,
NtUserDrawIconEx,
NtUserEndDeferWindowPosEx,
NtUserEndPaint,
NtUserEnumDisplayDevices,
NtUserEnumDisplayMonitors,
......
......@@ -4602,7 +4602,7 @@ static void thread_detach(void)
}
/***********************************************************************
* NtUserCallOneParam (win32u.@)
* NtUserCallNoParam (win32u.@)
*/
ULONG_PTR WINAPI NtUserCallNoParam( ULONG code )
{
......@@ -4631,6 +4631,8 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
{
switch(code)
{
case NtUserBeginDeferWindowPos:
return HandleToUlong( begin_defer_window_pos( arg ));
case NtUserCreateCursorIcon:
return HandleToUlong( alloc_cursoricon_handle( arg ));
case NtUserGetClipCursor:
......
......@@ -821,7 +821,7 @@
@ stub NtUserDdeInitialize
@ stub NtUserDefSetText
@ stub NtUserDeferWindowDpiChanges
@ stub NtUserDeferWindowPosAndBand
@ stdcall NtUserDeferWindowPosAndBand(long long long long long long long long long long)
@ stub NtUserDelegateCapturePointers
@ stub NtUserDelegateInput
@ stub NtUserDeleteMenu
......@@ -872,7 +872,7 @@
@ stub NtUserEnableWindowGDIScaledDpiMessage
@ stub NtUserEnableWindowGroupPolicy
@ stub NtUserEnableWindowResizeOptimization
@ stub NtUserEndDeferWindowPosEx
@ stdcall NtUserEndDeferWindowPosEx(long long)
@ stub NtUserEndMenu
@ stdcall NtUserEndPaint(long ptr)
@ stdcall NtUserEnumDisplayDevices(ptr long ptr long)
......
......@@ -195,9 +195,13 @@ struct unix_funcs
DWORD flags, void *lparam );
BOOL (WINAPI *pNtUserClipCursor)( const RECT *rect );
INT (WINAPI *pNtUserCountClipboardFormats)(void);
HDWP (WINAPI *pNtUserDeferWindowPosAndBand)( HDWP hdwp, HWND hwnd, HWND after,
INT x, INT y, INT cx, INT cy,
UINT flags, UINT unk1, UINT unk2 );
BOOL (WINAPI *pNtUserDestroyCursor)( HCURSOR cursor, ULONG arg );
BOOL (WINAPI *pNtUserDrawIconEx)( HDC hdc, INT x0, INT y0, HICON icon, INT width,
INT height, UINT istep, HBRUSH hbr, UINT flags );
BOOL (WINAPI *pNtUserEndDeferWindowPosEx)( HDWP hdwp, BOOL async );
BOOL (WINAPI *pNtUserEndPaint)( HWND hwnd, const PAINTSTRUCT *ps );
NTSTATUS (WINAPI *pNtUserEnumDisplayDevices)( UNICODE_STRING *device, DWORD index,
DISPLAY_DEVICEW *info, DWORD flags );
......@@ -334,6 +338,7 @@ extern void erase_now( HWND hwnd, UINT rdw_flags ) DECLSPEC_HIDDEN;
/* window.c */
struct tagWND;
extern HDWP begin_defer_window_pos( INT count ) DECLSPEC_HIDDEN;
extern HWND get_desktop_window(void) DECLSPEC_HIDDEN;
extern HWND get_full_window_handle( HWND hwnd ) DECLSPEC_HIDDEN;
extern HWND get_hwnd_message_parent(void) DECLSPEC_HIDDEN;
......
......@@ -2498,6 +2498,166 @@ BOOL WINAPI NtUserSetWindowPos( HWND hwnd, HWND after, INT x, INT y, INT cx, INT
return send_message( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos );
}
typedef struct
{
struct user_object obj;
INT count;
INT suggested_count;
HWND parent;
WINDOWPOS *winpos;
} DWP;
/* see BeginDeferWindowPos */
HDWP begin_defer_window_pos( INT count )
{
HDWP handle = 0;
DWP *dwp;
TRACE( "%d\n", count );
if (count < 0)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
/* Windows allows zero count, in which case it allocates context for 8 moves */
if (count == 0) count = 8;
if (!(dwp = malloc( sizeof(DWP) ))) return 0;
dwp->count = 0;
dwp->parent = 0;
dwp->suggested_count = count;
if (!(dwp->winpos = malloc( count * sizeof(WINDOWPOS) )) ||
!(handle = alloc_user_handle( &dwp->obj, NTUSER_OBJ_WINPOS )))
{
free( dwp->winpos );
free( dwp );
}
TRACE( "returning %p\n", handle );
return handle;
}
/***********************************************************************
* NtUserDeferWindowPosAndBand (win32u.@)
*/
HDWP WINAPI NtUserDeferWindowPosAndBand( HDWP hdwp, HWND hwnd, HWND after,
INT x, INT y, INT cx, INT cy,
UINT flags, UINT unk1, UINT unk2 )
{
HDWP retvalue = hdwp;
WINDOWPOS winpos;
DWP *dwp;
int i;
TRACE( "hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
hdwp, hwnd, after, x, y, cx, cy, flags );
winpos.hwnd = get_full_window_handle( hwnd );
if (is_desktop_window( winpos.hwnd ) || !is_window( winpos.hwnd ))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
winpos.hwndInsertAfter = get_full_window_handle( after );
winpos.flags = flags;
winpos.x = x;
winpos.y = y;
winpos.cx = cx;
winpos.cy = cy;
map_dpi_winpos( &winpos );
if (!(dwp = get_user_handle_ptr( hdwp, NTUSER_OBJ_WINPOS ))) return 0;
if (dwp == OBJ_OTHER_PROCESS)
{
FIXME( "other process handle %p\n", hdwp );
return 0;
}
for (i = 0; i < dwp->count; i++)
{
if (dwp->winpos[i].hwnd == winpos.hwnd)
{
/* Merge with the other changes */
if (!(flags & SWP_NOZORDER))
{
dwp->winpos[i].hwndInsertAfter = winpos.hwndInsertAfter;
}
if (!(flags & SWP_NOMOVE))
{
dwp->winpos[i].x = winpos.x;
dwp->winpos[i].y = winpos.y;
}
if (!(flags & SWP_NOSIZE))
{
dwp->winpos[i].cx = winpos.cx;
dwp->winpos[i].cy = winpos.cy;
}
dwp->winpos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
SWP_NOZORDER | SWP_NOREDRAW |
SWP_NOACTIVATE | SWP_NOCOPYBITS|
SWP_NOOWNERZORDER);
dwp->winpos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
SWP_FRAMECHANGED);
goto done;
}
}
if (dwp->count >= dwp->suggested_count)
{
WINDOWPOS *newpos = realloc( dwp->winpos, dwp->suggested_count * 2 * sizeof(WINDOWPOS) );
if (!newpos)
{
retvalue = 0;
goto done;
}
dwp->suggested_count *= 2;
dwp->winpos = newpos;
}
dwp->winpos[dwp->count++] = winpos;
done:
release_user_handle_ptr( dwp );
return retvalue;
}
/***********************************************************************
* NtUserEndDeferWindowPosEx (win32u.@)
*/
BOOL WINAPI NtUserEndDeferWindowPosEx( HDWP hdwp, BOOL async )
{
WINDOWPOS *winpos;
DWP *dwp;
int i;
TRACE( "%p\n", hdwp );
if (async) FIXME( "async not supported\n" );
if (!(dwp = free_user_handle( hdwp, NTUSER_OBJ_WINPOS ))) return FALSE;
if (dwp == OBJ_OTHER_PROCESS)
{
FIXME( "other process handle %p\n", hdwp );
return FALSE;
}
for (i = 0, winpos = dwp->winpos; i < dwp->count; i++, winpos++)
{
TRACE( "hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
winpos->hwnd, winpos->hwndInsertAfter, winpos->x, winpos->y,
winpos->cx, winpos->cy, winpos->flags );
if (is_current_thread_window( winpos->hwnd ))
set_window_pos( winpos, 0, 0 );
else
send_message( winpos->hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)winpos );
}
free( dwp->winpos );
free( dwp );
return TRUE;
}
/*******************************************************************
* update_window_state
*
......
......@@ -768,6 +768,15 @@ INT WINAPI NtUserCountClipboardFormats(void)
return unix_funcs->pNtUserCountClipboardFormats();
}
HDWP WINAPI NtUserDeferWindowPosAndBand( HDWP hdwp, HWND hwnd, HWND after,
INT x, INT y, INT cx, INT cy,
UINT flags, UINT unk1, UINT unk2 )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserDeferWindowPosAndBand( hdwp, hwnd, after, x, y, cx, cy,
flags, unk1, unk2 );
}
BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg )
{
if (!unix_funcs) return FALSE;
......@@ -781,6 +790,12 @@ BOOL WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width,
return unix_funcs->pNtUserDrawIconEx( hdc, x0, y0, icon, width, height, istep, hbr, flags );
}
BOOL WINAPI NtUserEndDeferWindowPosEx( HDWP hdwp, BOOL async )
{
if (!unix_funcs) return FALSE;
return unix_funcs->pNtUserEndDeferWindowPosEx( hdwp, async );
}
NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
DISPLAY_DEVICEW *info, DWORD flags )
{
......
......@@ -97,6 +97,7 @@ enum
/* NtUserCallOneParam codes, not compatible with Windows */
enum
{
NtUserBeginDeferWindowPos,
NtUserCreateCursorIcon,
NtUserGetClipCursor,
NtUserGetCursorPos,
......@@ -293,10 +294,13 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *d
ULONG heap_size );
HWINSTA WINAPI NtUserCreateWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK mask, ULONG arg3,
ULONG arg4, ULONG arg5, ULONG arg6, ULONG arg7 );
HDWP WINAPI NtUserDeferWindowPosAndBand( HDWP hdwp, HWND hwnd, HWND after, INT x, INT y,
INT cx, INT cy, UINT flags, UINT unk1, UINT unk2 );
BOOL WINAPI NtUserDestroyAcceleratorTable( HACCEL handle );
BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg );
BOOL WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width,
INT height, UINT istep, HBRUSH hbr, UINT flags );
BOOL WINAPI NtUserEndDeferWindowPosEx( HDWP hdwp, BOOL async );
BOOL WINAPI NtUserEndPaint( HWND hwnd, const PAINTSTRUCT *ps );
NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
DISPLAY_DEVICEW *info, DWORD flags );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment