win32u: Move NtUserScrollDC 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:
Jacek Caban 2021-11-17 12:49:37 +01:00 committed by Alexandre Julliard
parent d60708a17f
commit 5204622efa
11 changed files with 133 additions and 131 deletions

View file

@ -154,15 +154,6 @@ static void CDECL nulldrv_ReleaseDC( HWND hwnd, HDC hdc )
{ {
} }
static BOOL CDECL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
{
RECT rect;
GetClipBox( hdc, &rect );
return BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
hdc, rect.left - dx, rect.top - dy, SRCCOPY );
}
static void CDECL nulldrv_SetCapture( HWND hwnd, UINT flags ) static void CDECL nulldrv_SetCapture( HWND hwnd, UINT flags )
{ {
} }
@ -365,7 +356,7 @@ static struct user_driver_funcs lazy_load_driver =
loaderdrv_GetDC, loaderdrv_GetDC,
nulldrv_MsgWaitForMultipleObjectsEx, nulldrv_MsgWaitForMultipleObjectsEx,
nulldrv_ReleaseDC, nulldrv_ReleaseDC,
nulldrv_ScrollDC, NULL,
nulldrv_SetCapture, nulldrv_SetCapture,
nulldrv_SetFocus, nulldrv_SetFocus,
loaderdrv_SetLayeredWindowAttributes, loaderdrv_SetLayeredWindowAttributes,

View file

@ -1506,7 +1506,7 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC
hDC = GetDCEx( hwnd, 0, dcxflags); hDC = GetDCEx( hwnd, 0, dcxflags);
if (hDC) if (hDC)
{ {
ScrollDC( hDC, dx, dy, &rc, &cliprc, hrgnUpdate, rcUpdate ); NtUserScrollDC( hDC, dx, dy, &rc, &cliprc, hrgnUpdate, rcUpdate );
ReleaseDC( hwnd, hDC ); ReleaseDC( hwnd, hDC );
@ -1632,119 +1632,6 @@ BOOL WINAPI ScrollWindow( HWND hwnd, INT dx, INT dy,
SW_INVALIDATE | SW_ERASE | (rect ? 0 : SW_SCROLLCHILDREN), FALSE ) != ERROR; SW_INVALIDATE | SW_ERASE | (rect ? 0 : SW_SCROLLCHILDREN), FALSE ) != ERROR;
} }
/*************************************************************************
* ScrollDC (USER32.@)
*
* dx, dy, lprcScroll and lprcClip are all in logical coordinates (msdn is
* wrong) hrgnUpdate is returned in device coordinates with rcUpdate in
* logical coordinates.
*/
BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
HRGN ret_update_rgn, LPRECT update_rect )
{
HRGN update_rgn = ret_update_rgn;
RECT src_rect, clip_rect, offset;
INT dxdev, dydev;
HRGN dstrgn, cliprgn, visrgn;
BOOL ret;
TRACE( "dx,dy %d,%d scroll %s clip %s update %p rect %p\n",
dx, dy, wine_dbgstr_rect(scroll), wine_dbgstr_rect(clip), ret_update_rgn, update_rect );
/* get the visible region */
visrgn = CreateRectRgn( 0, 0, 0, 0 );
GetRandomRgn( hdc, visrgn, SYSRGN );
if (!(GetVersion() & 0x80000000))
{
POINT org;
GetDCOrgEx( hdc, &org );
OffsetRgn( visrgn, -org.x, -org.y );
}
/* intersect with the clipping region if the DC has one */
cliprgn = CreateRectRgn( 0, 0, 0, 0);
if (GetClipRgn( hdc, cliprgn ) != 1)
{
DeleteObject( cliprgn );
cliprgn = 0;
}
else CombineRgn( visrgn, visrgn, cliprgn, RGN_AND );
/* only those pixels in the scroll rectangle that remain in the clipping
* rect are scrolled. */
if (clip)
clip_rect = *clip;
else
GetClipBox( hdc, &clip_rect );
src_rect = clip_rect;
OffsetRect( &clip_rect, -dx, -dy );
IntersectRect( &src_rect, &src_rect, &clip_rect );
/* if an scroll rectangle is specified, only the pixels within that
* rectangle are scrolled */
if (scroll) IntersectRect( &src_rect, &src_rect, scroll );
/* now convert to device coordinates */
LPtoDP( hdc, (LPPOINT)&src_rect, 2 );
TRACE( "source rect: %s\n", wine_dbgstr_rect(&src_rect) );
/* also dx and dy */
SetRect( &offset, 0, 0, dx, dy );
LPtoDP( hdc, (LPPOINT)&offset, 2 );
dxdev = offset.right - offset.left;
dydev = offset.bottom - offset.top;
/* now intersect with the visible region to get the pixels that will actually scroll */
dstrgn = CreateRectRgnIndirect( &src_rect );
CombineRgn( dstrgn, dstrgn, visrgn, RGN_AND );
OffsetRgn( dstrgn, dxdev, dydev );
ExtSelectClipRgn( hdc, dstrgn, RGN_AND );
/* compute the update areas. This is the combined clip rectangle
* minus the scrolled region, and intersected with the visible region. */
if (ret_update_rgn || update_rect)
{
/* intersect clip and scroll rectangles, allowing NULL values */
if (scroll)
{
if (clip)
IntersectRect( &clip_rect, clip, scroll );
else
clip_rect = *scroll;
}
else if (clip)
clip_rect = *clip;
else
GetClipBox( hdc, &clip_rect );
/* Convert the combined clip rectangle to device coordinates */
LPtoDP( hdc, (LPPOINT)&clip_rect, 2 );
if (update_rgn)
SetRectRgn( update_rgn, clip_rect.left, clip_rect.top, clip_rect.right, clip_rect.bottom );
else
update_rgn = CreateRectRgnIndirect( &clip_rect );
CombineRgn( update_rgn, update_rgn, visrgn, RGN_AND );
CombineRgn( update_rgn, update_rgn, dstrgn, RGN_DIFF );
}
ret = USER_Driver->pScrollDC( hdc, dx, dy, update_rgn );
if (ret && update_rect)
{
GetRgnBox( update_rgn, update_rect );
DPtoLP( hdc, (LPPOINT)update_rect, 2 );
TRACE( "returning update_rect %s\n", wine_dbgstr_rect(update_rect) );
}
if (!ret_update_rgn) DeleteObject( update_rgn );
SelectClipRgn( hdc, cliprgn );
if (cliprgn) DeleteObject( cliprgn );
DeleteObject( visrgn );
DeleteObject( dstrgn );
return ret;
}
/************************************************************************ /************************************************************************
* PrintWindow (USER32.@) * PrintWindow (USER32.@)
* *

View file

@ -627,7 +627,7 @@
@ stdcall ReuseDDElParam(long long long long long) @ stdcall ReuseDDElParam(long long long long long)
@ stdcall ScreenToClient(long ptr) @ stdcall ScreenToClient(long ptr)
@ stdcall ScrollChildren(long long long long) @ stdcall ScrollChildren(long long long long)
@ stdcall ScrollDC(long long long ptr ptr long ptr) @ stdcall ScrollDC(long long long ptr ptr long ptr) NtUserScrollDC
@ stdcall ScrollWindow(long long long ptr ptr) @ stdcall ScrollWindow(long long long ptr ptr)
@ stdcall ScrollWindowEx(long long long ptr ptr long ptr long) @ stdcall ScrollWindowEx(long long long ptr ptr long ptr long)
@ stdcall SendDlgItemMessageA(long long long long long) @ stdcall SendDlgItemMessageA(long long long long long)

View file

@ -1054,6 +1054,7 @@ static const struct user_driver_funcs lazy_load_driver =
.pUnregisterHotKey = loaderdrv_UnregisterHotKey, .pUnregisterHotKey = loaderdrv_UnregisterHotKey,
.pVkKeyScanEx = loaderdrv_VkKeyScanEx, .pVkKeyScanEx = loaderdrv_VkKeyScanEx,
.pUpdateClipboard = loaderdrv_UpdateClipboard, .pUpdateClipboard = loaderdrv_UpdateClipboard,
.pScrollDC = nulldrv_ScrollDC,
}; };
const struct user_driver_funcs *user_driver = &lazy_load_driver; const struct user_driver_funcs *user_driver = &lazy_load_driver;

View file

@ -277,11 +277,6 @@ static inline INT INTERNAL_YWSTODS(DC *dc, INT height)
return pt[1].y - pt[0].y; return pt[1].y - pt[0].y;
} }
static inline BOOL is_win9x(void)
{
return NtCurrentTeb()->Peb->OSPlatformId == VER_PLATFORM_WIN32s;
}
static inline WCHAR *strdupW( const WCHAR *p ) static inline WCHAR *strdupW( const WCHAR *p )
{ {
WCHAR *ret; WCHAR *ret;

View file

@ -1175,6 +1175,7 @@ static struct unix_funcs unix_funcs =
NtUserGetUpdatedClipboardFormats, NtUserGetUpdatedClipboardFormats,
NtUserIsClipboardFormatAvailable, NtUserIsClipboardFormatAvailable,
NtUserMapVirtualKeyEx, NtUserMapVirtualKeyEx,
NtUserScrollDC,
NtUserToUnicodeEx, NtUserToUnicodeEx,
NtUserUnregisterHotKey, NtUserUnregisterHotKey,
NtUserVkKeyScanEx, NtUserVkKeyScanEx,

View file

@ -905,3 +905,115 @@ BOOL WINAPI NtGdiDrawStream( HDC hdc, ULONG in, void *pvin )
FIXME("stub: %p, %d, %p\n", hdc, in, pvin); FIXME("stub: %p, %d, %p\n", hdc, in, pvin);
return FALSE; return FALSE;
} }
/*************************************************************************
* NtUserScrollDC (win32u.@)
*/
BOOL WINAPI NtUserScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
HRGN ret_update_rgn, RECT *update_rect )
{
HRGN update_rgn = ret_update_rgn;
RECT src_rect, clip_rect, offset;
INT dxdev, dydev;
HRGN dstrgn, cliprgn, visrgn;
POINT org;
DC *dc;
BOOL ret;
TRACE( "dx,dy %d,%d scroll %s clip %s update %p rect %p\n",
dx, dy, wine_dbgstr_rect(scroll), wine_dbgstr_rect(clip), ret_update_rgn, update_rect );
if (!(dc = get_dc_ptr( hdc ))) return FALSE;
org.x = dc->attr->vis_rect.left;
org.y = dc->attr->vis_rect.top;
release_dc_ptr( dc );
/* get the visible region */
visrgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
NtGdiGetRandomRgn( hdc, visrgn, SYSRGN );
if (!is_win9x()) NtGdiOffsetRgn( visrgn, -org.x, -org.y );
/* intersect with the clipping region if the DC has one */
cliprgn = NtGdiCreateRectRgn( 0, 0, 0, 0);
if (NtGdiGetRandomRgn( hdc, cliprgn, NTGDI_RGN_MIRROR_RTL | 1 ) != 1)
{
NtGdiDeleteObjectApp( cliprgn );
cliprgn = 0;
}
else NtGdiCombineRgn( visrgn, visrgn, cliprgn, RGN_AND );
/* only those pixels in the scroll rectangle that remain in the clipping
* rect are scrolled. */
if (clip)
clip_rect = *clip;
else
NtGdiGetAppClipBox( hdc, &clip_rect );
src_rect = clip_rect;
offset_rect( &clip_rect, -dx, -dy );
intersect_rect( &src_rect, &src_rect, &clip_rect );
/* if an scroll rectangle is specified, only the pixels within that
* rectangle are scrolled */
if (scroll) intersect_rect( &src_rect, &src_rect, scroll );
/* now convert to device coordinates */
NtGdiTransformPoints( hdc, (POINT *)&src_rect, (POINT *)&src_rect, 2, NtGdiLPtoDP );
TRACE( "source rect: %s\n", wine_dbgstr_rect(&src_rect) );
/* also dx and dy */
SetRect( &offset, 0, 0, dx, dy );
NtGdiTransformPoints( hdc, (POINT *)&offset, (POINT *)&offset, 2, NtGdiLPtoDP );
dxdev = offset.right - offset.left;
dydev = offset.bottom - offset.top;
/* now intersect with the visible region to get the pixels that will actually scroll */
dstrgn = NtGdiCreateRectRgn( src_rect.left, src_rect.top, src_rect.right, src_rect.bottom );
NtGdiCombineRgn( dstrgn, dstrgn, visrgn, RGN_AND );
NtGdiOffsetRgn( dstrgn, dxdev, dydev );
NtGdiExtSelectClipRgn( hdc, dstrgn, RGN_AND );
/* compute the update areas. This is the combined clip rectangle
* minus the scrolled region, and intersected with the visible region. */
if (ret_update_rgn || update_rect)
{
/* intersect clip and scroll rectangles, allowing NULL values */
if (scroll)
{
if (clip)
intersect_rect( &clip_rect, clip, scroll );
else
clip_rect = *scroll;
}
else if (clip)
clip_rect = *clip;
else
NtGdiGetAppClipBox( hdc, &clip_rect );
/* Convert the combined clip rectangle to device coordinates */
NtGdiTransformPoints( hdc, (POINT *)&clip_rect, (POINT *)&clip_rect, 2, NtGdiLPtoDP );
if (update_rgn)
NtGdiSetRectRgn( update_rgn, clip_rect.left, clip_rect.top,
clip_rect.right, clip_rect.bottom );
else
update_rgn = NtGdiCreateRectRgn( clip_rect.left, clip_rect.top,
clip_rect.right, clip_rect.bottom );
NtGdiCombineRgn( update_rgn, update_rgn, visrgn, RGN_AND );
NtGdiCombineRgn( update_rgn, update_rgn, dstrgn, RGN_DIFF );
}
ret = user_driver->pScrollDC( hdc, dx, dy, update_rgn );
if (ret && update_rect)
{
NtGdiGetRgnBox( update_rgn, update_rect );
NtGdiTransformPoints( hdc, (POINT *)&update_rect, (POINT *)&update_rect, 2, NtGdiDPtoLP );
TRACE( "returning update_rect %s\n", wine_dbgstr_rect(update_rect) );
}
if (!ret_update_rgn) NtGdiDeleteObjectApp( update_rgn );
NtGdiExtSelectClipRgn( hdc, cliprgn, RGN_COPY );
if (cliprgn) NtGdiDeleteObjectApp( cliprgn );
NtGdiDeleteObjectApp( visrgn );
NtGdiDeleteObjectApp( dstrgn );
return ret;
}

View file

@ -1155,7 +1155,7 @@
@ stub NtUserResolveDesktopForWOW @ stub NtUserResolveDesktopForWOW
@ stub NtUserRestoreWindowDpiChanges @ stub NtUserRestoreWindowDpiChanges
@ stub NtUserSBGetParms @ stub NtUserSBGetParms
@ stub NtUserScrollDC @ stdcall NtUserScrollDC(long long long ptr ptr long ptr)
@ stub NtUserScrollWindowEx @ stub NtUserScrollWindowEx
@ stub NtUserSelectPalette @ stub NtUserSelectPalette
@ stub NtUserSendEventMessage @ stub NtUserSendEventMessage

View file

@ -202,6 +202,8 @@ struct unix_funcs
BOOL (WINAPI *pNtUserGetUpdatedClipboardFormats)( UINT *formats, UINT size, UINT *out_size ); BOOL (WINAPI *pNtUserGetUpdatedClipboardFormats)( UINT *formats, UINT size, UINT *out_size );
BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format ); BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format );
UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout ); UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout );
BOOL (WINAPI *pNtUserScrollDC)( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
HRGN ret_update_rgn, RECT *update_rect );
INT (WINAPI *pNtUserToUnicodeEx)( UINT virt, UINT scan, const BYTE *state, INT (WINAPI *pNtUserToUnicodeEx)( UINT virt, UINT scan, const BYTE *state,
WCHAR *str, int size, UINT flags, HKL layout ); WCHAR *str, int size, UINT flags, HKL layout );
BOOL (WINAPI *pNtUserUnregisterHotKey)( HWND hwnd, INT id ); BOOL (WINAPI *pNtUserUnregisterHotKey)( HWND hwnd, INT id );
@ -407,4 +409,9 @@ DWORD win32u_mbtowc( CPTABLEINFO *info, WCHAR *dst, DWORD dstlen, const char *sr
DWORD win32u_wctomb( CPTABLEINFO *info, char *dst, DWORD dstlen, const WCHAR *src, DWORD win32u_wctomb( CPTABLEINFO *info, char *dst, DWORD dstlen, const WCHAR *src,
DWORD srclen ) DECLSPEC_HIDDEN; DWORD srclen ) DECLSPEC_HIDDEN;
static inline BOOL is_win9x(void)
{
return NtCurrentTeb()->Peb->OSPlatformId == VER_PLATFORM_WIN32s;
}
#endif /* __WINE_WIN32U_PRIVATE */ #endif /* __WINE_WIN32U_PRIVATE */

View file

@ -636,6 +636,12 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout )
return unix_funcs->pNtUserMapVirtualKeyEx( code, type, layout ); return unix_funcs->pNtUserMapVirtualKeyEx( code, type, layout );
} }
BOOL WINAPI NtUserScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
HRGN ret_update_rgn, RECT *update_rect )
{
return unix_funcs->pNtUserScrollDC( hdc, dx, dy, scroll, clip, ret_update_rgn, update_rect );
}
INT WINAPI NtUserToUnicodeEx( UINT virt, UINT scan, const BYTE *state, INT WINAPI NtUserToUnicodeEx( UINT virt, UINT scan, const BYTE *state,
WCHAR *str, int size, UINT flags, HKL layout ) WCHAR *str, int size, UINT flags, HKL layout )
{ {

View file

@ -92,6 +92,8 @@ HDESK WINAPI NtUserOpenDesktop( OBJECT_ATTRIBUTES *attr, DWORD flags, ACCESS_M
HDESK WINAPI NtUserOpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access ); HDESK WINAPI NtUserOpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access );
BOOL WINAPI NtUserRemoveClipboardFormatListener( HWND hwnd ); BOOL WINAPI NtUserRemoveClipboardFormatListener( HWND hwnd );
HANDLE WINAPI NtUserRemoveProp( HWND hwnd, const WCHAR *str ); HANDLE WINAPI NtUserRemoveProp( HWND hwnd, const WCHAR *str );
BOOL WINAPI NtUserScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
HRGN ret_update_rgn, RECT *update_rect );
BOOL WINAPI NtUserSetKeyboardState( BYTE *state ); BOOL WINAPI NtUserSetKeyboardState( BYTE *state );
BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle ); BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle );
BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle ); BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle );