mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
user32: Move the common parts of ScrollDC into user32 and the null driver.
This commit is contained in:
parent
a35db4e7e3
commit
04ad06353d
@ -341,10 +341,13 @@ static void CDECL nulldrv_ReleaseDC( HWND hwnd, HDC hdc )
|
||||
{
|
||||
}
|
||||
|
||||
static BOOL CDECL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
|
||||
HRGN hrgn, LPRECT update )
|
||||
static BOOL CDECL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
|
||||
{
|
||||
return FALSE;
|
||||
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 )
|
||||
@ -679,10 +682,9 @@ static void CDECL loaderdrv_ReleaseDC( HWND hwnd, HDC hdc )
|
||||
load_driver()->pReleaseDC( hwnd, hdc );
|
||||
}
|
||||
|
||||
static BOOL CDECL loaderdrv_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
|
||||
HRGN hrgn, LPRECT update )
|
||||
static BOOL CDECL loaderdrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
|
||||
{
|
||||
return load_driver()->pScrollDC( hdc, dx, dy, scroll, clip, hrgn, update );
|
||||
return load_driver()->pScrollDC( hdc, dx, dy, update );
|
||||
}
|
||||
|
||||
static void CDECL loaderdrv_SetCapture( HWND hwnd, UINT flags )
|
||||
|
@ -1587,11 +1587,109 @@ BOOL WINAPI ScrollWindow( HWND hwnd, INT dx, INT dy,
|
||||
* wrong) hrgnUpdate is returned in device coordinates with rcUpdate in
|
||||
* logical coordinates.
|
||||
*/
|
||||
BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll,
|
||||
const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate )
|
||||
BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
|
||||
HRGN ret_update_rgn, LPRECT update_rect )
|
||||
|
||||
{
|
||||
return USER_Driver->pScrollDC( hdc, dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate );
|
||||
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;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -100,7 +100,7 @@ typedef struct tagUSER_DRIVER {
|
||||
void (CDECL *pGetDC)(HDC,HWND,HWND,const RECT *,const RECT *,DWORD);
|
||||
DWORD (CDECL *pMsgWaitForMultipleObjectsEx)(DWORD,const HANDLE*,DWORD,DWORD,DWORD);
|
||||
void (CDECL *pReleaseDC)(HWND,HDC);
|
||||
BOOL (CDECL *pScrollDC)(HDC, INT, INT, const RECT *, const RECT *, HRGN, LPRECT);
|
||||
BOOL (CDECL *pScrollDC)(HDC,INT,INT,HRGN);
|
||||
void (CDECL *pSetCapture)(HWND,UINT);
|
||||
void (CDECL *pSetFocus)(HWND);
|
||||
void (CDECL *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
|
||||
|
@ -14,7 +14,6 @@ C_SRCS = \
|
||||
macdrv_main.c \
|
||||
mouse.c \
|
||||
opengl.c \
|
||||
scroll.c \
|
||||
surface.c \
|
||||
systray.c \
|
||||
window.c
|
||||
|
@ -1,188 +0,0 @@
|
||||
/*
|
||||
* MACDRV window/DC scrolling
|
||||
*
|
||||
* Copyright 1993 David W. Metcalfe
|
||||
* Copyright 1995, 1996 Alex Korobka
|
||||
* Copyright 2001 Alexandre Julliard
|
||||
* Copyright 2011, 2013 Ken Thomases for CodeWeavers Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "macdrv.h"
|
||||
#include "winuser.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(scroll);
|
||||
|
||||
|
||||
static void dump_region(const char *p, HRGN hrgn)
|
||||
{
|
||||
DWORD i, size;
|
||||
RGNDATA *data = NULL;
|
||||
RECT *rect;
|
||||
|
||||
if (!hrgn)
|
||||
{
|
||||
TRACE("%s null region\n", p);
|
||||
return;
|
||||
}
|
||||
if (!(size = GetRegionData(hrgn, 0, NULL)))
|
||||
return;
|
||||
if (!(data = HeapAlloc(GetProcessHeap(), 0, size))) return;
|
||||
GetRegionData(hrgn, size, data);
|
||||
TRACE("%s %d rects:", p, data->rdh.nCount);
|
||||
for (i = 0, rect = (RECT *)data->Buffer; i<20 && i < data->rdh.nCount; i++, rect++)
|
||||
TRACE(" %s", wine_dbgstr_rect(rect));
|
||||
TRACE("\n");
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* ScrollDC (MACDRV.@)
|
||||
*/
|
||||
BOOL CDECL macdrv_ScrollDC(HDC hdc, INT dx, INT dy, const RECT *lprcScroll,
|
||||
const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate)
|
||||
{
|
||||
RECT rcSrc, rcClip, offset;
|
||||
INT dxdev, dydev, res;
|
||||
HRGN DstRgn, clipRgn, visrgn;
|
||||
|
||||
TRACE("dx,dy %d,%d rcScroll %s rcClip %s hrgnUpdate %p lprcUpdate %p\n",
|
||||
dx, dy, wine_dbgstr_rect(lprcScroll), wine_dbgstr_rect(lprcClip),
|
||||
hrgnUpdate, lprcUpdate);
|
||||
|
||||
/* get the visible region */
|
||||
visrgn = CreateRectRgn(0, 0, 0, 0);
|
||||
GetRandomRgn(hdc, visrgn, SYSRGN);
|
||||
if (!(GetVersion() & 0x80000000))
|
||||
{
|
||||
/* Window NT/2k/XP */
|
||||
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 = NULL;
|
||||
}
|
||||
else
|
||||
CombineRgn(visrgn, visrgn, clipRgn, RGN_AND);
|
||||
|
||||
/* only those pixels in the scroll rectangle that remain in the clipping
|
||||
* rect are scrolled. */
|
||||
if (lprcClip)
|
||||
rcClip = *lprcClip;
|
||||
else
|
||||
GetClipBox(hdc, &rcClip);
|
||||
rcSrc = rcClip;
|
||||
OffsetRect(&rcClip, -dx, -dy);
|
||||
IntersectRect(&rcSrc, &rcSrc, &rcClip);
|
||||
|
||||
/* if an scroll rectangle is specified, only the pixels within that
|
||||
* rectangle are scrolled */
|
||||
if (lprcScroll)
|
||||
IntersectRect(&rcSrc, &rcSrc, lprcScroll);
|
||||
|
||||
/* now convert to device coordinates */
|
||||
LPtoDP(hdc, (LPPOINT)&rcSrc, 2);
|
||||
TRACE("source rect: %s\n", wine_dbgstr_rect(&rcSrc));
|
||||
|
||||
/* 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(&rcSrc);
|
||||
res = CombineRgn(DstRgn, DstRgn, visrgn, RGN_AND);
|
||||
|
||||
/* and translate, giving the destination region */
|
||||
OffsetRgn(DstRgn, dxdev, dydev);
|
||||
if (TRACE_ON(scroll)) dump_region("Destination scroll region: ", DstRgn);
|
||||
|
||||
/* if there are any, do it */
|
||||
if (res > NULLREGION)
|
||||
{
|
||||
RECT rect ;
|
||||
/* clip to the destination region, so we can BitBlt with a simple
|
||||
* bounding rectangle */
|
||||
if (clipRgn)
|
||||
ExtSelectClipRgn(hdc, DstRgn, RGN_AND);
|
||||
else
|
||||
SelectClipRgn(hdc, DstRgn);
|
||||
GetRgnBox(DstRgn, &rect);
|
||||
DPtoLP(hdc, (LPPOINT)&rect, 2);
|
||||
TRACE("destination rect: %s\n", wine_dbgstr_rect(&rect));
|
||||
|
||||
BitBlt(hdc, rect.left, rect.top,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
hdc, rect.left - dx, rect.top - dy, SRCCOPY);
|
||||
}
|
||||
|
||||
/* compute the update areas. This is the combined clip rectangle
|
||||
* minus the scrolled region, and intersected with the visible
|
||||
* region. */
|
||||
if (hrgnUpdate || lprcUpdate)
|
||||
{
|
||||
HRGN hrgn = hrgnUpdate;
|
||||
|
||||
/* Intersect clip and scroll rectangles, allowing NULL values */
|
||||
if (lprcScroll)
|
||||
if (lprcClip)
|
||||
IntersectRect(&rcClip, lprcClip, lprcScroll);
|
||||
else
|
||||
rcClip = *lprcScroll;
|
||||
else
|
||||
if (lprcClip)
|
||||
rcClip = *lprcClip;
|
||||
else
|
||||
GetClipBox(hdc, &rcClip);
|
||||
|
||||
/* Convert the combined clip rectangle to device coordinates */
|
||||
LPtoDP(hdc, (LPPOINT)&rcClip, 2);
|
||||
if (hrgn)
|
||||
SetRectRgn(hrgn, rcClip.left, rcClip.top, rcClip.right, rcClip.bottom);
|
||||
else
|
||||
hrgn = CreateRectRgnIndirect(&rcClip);
|
||||
CombineRgn(hrgn, hrgn, visrgn, RGN_AND);
|
||||
CombineRgn(hrgn, hrgn, DstRgn, RGN_DIFF);
|
||||
if (TRACE_ON(scroll)) dump_region("Update region: ", hrgn);
|
||||
if (lprcUpdate)
|
||||
{
|
||||
GetRgnBox(hrgn, lprcUpdate);
|
||||
/* Put the lprcUpdate in logical coordinates */
|
||||
DPtoLP(hdc, (LPPOINT)lprcUpdate, 2);
|
||||
TRACE("returning lprcUpdate %s\n", wine_dbgstr_rect(lprcUpdate));
|
||||
}
|
||||
if (!hrgnUpdate)
|
||||
DeleteObject(hrgn);
|
||||
}
|
||||
|
||||
/* restore original clipping region */
|
||||
SelectClipRgn(hdc, clipRgn);
|
||||
DeleteObject(visrgn);
|
||||
DeleteObject(DstRgn);
|
||||
if (clipRgn) DeleteObject(clipRgn);
|
||||
return TRUE;
|
||||
}
|
@ -28,7 +28,6 @@
|
||||
@ cdecl IsClipboardFormatAvailable(long) macdrv_IsClipboardFormatAvailable
|
||||
@ cdecl MapVirtualKeyEx(long long long) macdrv_MapVirtualKeyEx
|
||||
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) macdrv_MsgWaitForMultipleObjectsEx
|
||||
@ cdecl ScrollDC(long long long ptr ptr long ptr) macdrv_ScrollDC
|
||||
@ cdecl SetClipboardData(long long long) macdrv_SetClipboardData
|
||||
@ cdecl SetCursor(long) macdrv_SetCursor
|
||||
@ cdecl SetCursorPos(long long) macdrv_SetCursorPos
|
||||
|
@ -18,7 +18,6 @@ C_SRCS = \
|
||||
opengl.c \
|
||||
palette.c \
|
||||
pen.c \
|
||||
scroll.c \
|
||||
settings.c \
|
||||
systray.c \
|
||||
window.c \
|
||||
|
@ -1,192 +0,0 @@
|
||||
/*
|
||||
* Scroll windows and DCs
|
||||
*
|
||||
* Copyright 1993 David W. Metcalfe
|
||||
* Copyright 1995, 1996 Alex Korobka
|
||||
* Copyright 2001 Alexandre Julliard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
|
||||
#include "x11drv.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(scroll);
|
||||
|
||||
static void dump_region( const char *p, HRGN hrgn)
|
||||
{
|
||||
DWORD i, size;
|
||||
RGNDATA *data = NULL;
|
||||
RECT *rect;
|
||||
|
||||
if (!hrgn) {
|
||||
TRACE( "%s null region\n", p );
|
||||
return;
|
||||
}
|
||||
if (!(size = GetRegionData( hrgn, 0, NULL ))) {
|
||||
return;
|
||||
}
|
||||
if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
|
||||
GetRegionData( hrgn, size, data );
|
||||
TRACE("%s %d rects:", p, data->rdh.nCount );
|
||||
for (i = 0, rect = (RECT *)data->Buffer; i<20 && i < data->rdh.nCount; i++, rect++)
|
||||
TRACE( " %s", wine_dbgstr_rect( rect));
|
||||
TRACE("\n");
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* ScrollDC (X11DRV.@)
|
||||
*/
|
||||
BOOL CDECL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll,
|
||||
const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate )
|
||||
{
|
||||
RECT rcSrc, rcClip, offset;
|
||||
INT dxdev, dydev, res;
|
||||
HRGN DstRgn, clipRgn, visrgn;
|
||||
INT code = X11DRV_START_EXPOSURES;
|
||||
|
||||
TRACE("dx,dy %d,%d rcScroll %s rcClip %s hrgnUpdate %p lprcUpdate %p\n",
|
||||
dx, dy, wine_dbgstr_rect(lprcScroll), wine_dbgstr_rect(lprcClip),
|
||||
hrgnUpdate, lprcUpdate);
|
||||
/* enable X-exposure events */
|
||||
if (hrgnUpdate || lprcUpdate)
|
||||
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL );
|
||||
/* get the visible region */
|
||||
visrgn=CreateRectRgn( 0, 0, 0, 0);
|
||||
GetRandomRgn( hdc, visrgn, SYSRGN);
|
||||
if( !(GetVersion() & 0x80000000)) {
|
||||
/* Window NT/2k/XP */
|
||||
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=NULL;
|
||||
} else
|
||||
CombineRgn( visrgn, visrgn, clipRgn, RGN_AND);
|
||||
/* only those pixels in the scroll rectangle that remain in the clipping
|
||||
* rect are scrolled. */
|
||||
if( lprcClip)
|
||||
rcClip = *lprcClip;
|
||||
else
|
||||
GetClipBox( hdc, &rcClip);
|
||||
rcSrc = rcClip;
|
||||
OffsetRect( &rcClip, -dx, -dy);
|
||||
IntersectRect( &rcSrc, &rcSrc, &rcClip);
|
||||
/* if an scroll rectangle is specified, only the pixels within that
|
||||
* rectangle are scrolled */
|
||||
if( lprcScroll)
|
||||
IntersectRect( &rcSrc, &rcSrc, lprcScroll);
|
||||
/* now convert to device coordinates */
|
||||
LPtoDP(hdc, (LPPOINT)&rcSrc, 2);
|
||||
TRACE("source rect: %s\n", wine_dbgstr_rect(&rcSrc));
|
||||
/* 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( &rcSrc);
|
||||
res = CombineRgn( DstRgn, DstRgn, visrgn, RGN_AND);
|
||||
/* and translate, giving the destination region */
|
||||
OffsetRgn( DstRgn, dxdev, dydev);
|
||||
if( TRACE_ON( scroll)) dump_region( "Destination scroll region: ", DstRgn);
|
||||
/* if there are any, do it */
|
||||
if( res > NULLREGION) {
|
||||
RECT rect ;
|
||||
/* clip to the destination region, so we can BitBlt with a simple
|
||||
* bounding rectangle */
|
||||
if( clipRgn)
|
||||
ExtSelectClipRgn( hdc, DstRgn, RGN_AND);
|
||||
else
|
||||
SelectClipRgn( hdc, DstRgn);
|
||||
GetRgnBox( DstRgn, &rect);
|
||||
DPtoLP(hdc, (LPPOINT)&rect, 2);
|
||||
TRACE("destination rect: %s\n", wine_dbgstr_rect(&rect));
|
||||
|
||||
BitBlt( hdc, rect.left, rect.top,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
hdc, rect.left - dx, rect.top - dy, SRCCOPY);
|
||||
}
|
||||
/* compute the update areas. This is the combined clip rectangle
|
||||
* minus the scrolled region, and intersected with the visible
|
||||
* region. */
|
||||
if (hrgnUpdate || lprcUpdate)
|
||||
{
|
||||
HRGN hrgn = hrgnUpdate;
|
||||
HRGN ExpRgn = 0;
|
||||
|
||||
/* collect all the exposures */
|
||||
code = X11DRV_END_EXPOSURES;
|
||||
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code,
|
||||
sizeof(ExpRgn), (LPSTR)&ExpRgn );
|
||||
/* Intersect clip and scroll rectangles, allowing NULL values */
|
||||
if( lprcScroll)
|
||||
if( lprcClip)
|
||||
IntersectRect( &rcClip, lprcClip, lprcScroll);
|
||||
else
|
||||
rcClip = *lprcScroll;
|
||||
else
|
||||
if( lprcClip)
|
||||
rcClip = *lprcClip;
|
||||
else
|
||||
GetClipBox( hdc, &rcClip);
|
||||
/* Convert the combined clip rectangle to device coordinates */
|
||||
LPtoDP(hdc, (LPPOINT)&rcClip, 2);
|
||||
if( hrgn )
|
||||
SetRectRgn( hrgn, rcClip.left, rcClip.top, rcClip.right,
|
||||
rcClip.bottom);
|
||||
else
|
||||
hrgn = CreateRectRgnIndirect( &rcClip);
|
||||
CombineRgn( hrgn, hrgn, visrgn, RGN_AND);
|
||||
CombineRgn( hrgn, hrgn, DstRgn, RGN_DIFF);
|
||||
/* add the exposures to this */
|
||||
if( ExpRgn) {
|
||||
if( TRACE_ON( scroll)) dump_region( "Expose region: ", ExpRgn);
|
||||
CombineRgn( hrgn, hrgn, ExpRgn, RGN_OR);
|
||||
DeleteObject( ExpRgn);
|
||||
}
|
||||
if( TRACE_ON( scroll)) dump_region( "Update region: ", hrgn);
|
||||
if( lprcUpdate) {
|
||||
GetRgnBox( hrgn, lprcUpdate );
|
||||
/* Put the lprcUpdate in logical coordinates */
|
||||
DPtoLP( hdc, (LPPOINT)lprcUpdate, 2 );
|
||||
TRACE("returning lprcUpdate %s\n", wine_dbgstr_rect(lprcUpdate));
|
||||
}
|
||||
if( !hrgnUpdate)
|
||||
DeleteObject( hrgn);
|
||||
}
|
||||
/* restore original clipping region */
|
||||
SelectClipRgn( hdc, clipRgn);
|
||||
DeleteObject( visrgn);
|
||||
DeleteObject( DstRgn);
|
||||
if( clipRgn) DeleteObject( clipRgn);
|
||||
return TRUE;
|
||||
}
|
@ -2018,6 +2018,41 @@ void CDECL X11DRV_ReleaseDC( HWND hwnd, HDC hdc )
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* ScrollDC (X11DRV.@)
|
||||
*/
|
||||
BOOL CDECL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
|
||||
{
|
||||
RECT rect;
|
||||
BOOL ret;
|
||||
HRGN expose_rgn = 0;
|
||||
|
||||
GetClipBox( hdc, &rect );
|
||||
|
||||
if (update)
|
||||
{
|
||||
INT code = X11DRV_START_EXPOSURES;
|
||||
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL );
|
||||
|
||||
ret = BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
hdc, rect.left - dx, rect.top - dy, SRCCOPY );
|
||||
|
||||
code = X11DRV_END_EXPOSURES;
|
||||
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code,
|
||||
sizeof(expose_rgn), (LPSTR)&expose_rgn );
|
||||
if (expose_rgn)
|
||||
{
|
||||
CombineRgn( update, update, expose_rgn, RGN_OR );
|
||||
DeleteObject( expose_rgn );
|
||||
}
|
||||
}
|
||||
else ret = BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
hdc, rect.left - dx, rect.top - dy, SRCCOPY );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetCapture (X11DRV.@)
|
||||
*/
|
||||
|
@ -36,7 +36,7 @@
|
||||
@ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable
|
||||
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
|
||||
@ cdecl ReleaseDC(long long) X11DRV_ReleaseDC
|
||||
@ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC
|
||||
@ cdecl ScrollDC(long long long) X11DRV_ScrollDC
|
||||
@ cdecl SetClipboardData(long long long) X11DRV_SetClipboardData
|
||||
@ cdecl SetCapture(long long) X11DRV_SetCapture
|
||||
@ cdecl SetFocus(long) X11DRV_SetFocus
|
||||
|
Loading…
Reference in New Issue
Block a user