diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c index 1a31cc86990..bb106994632 100644 --- a/dlls/ttydrv/wnd.c +++ b/dlls/ttydrv/wnd.c @@ -18,7 +18,6 @@ DEFAULT_DEBUG_CHANNEL(ttydrv); WND_DRIVER TTYDRV_WND_Driver = { TTYDRV_WND_ForceWindowRaise, - TTYDRV_WND_ScrollWindow, TTYDRV_WND_SetHostAttr }; @@ -98,16 +97,6 @@ void TTYDRV_WND_ForceWindowRaise(WND *wndPtr) FIXME("(%p): stub\n", wndPtr); } -/***************************************************************** - * TTYDRV_WND_ScrollWindow - */ -void TTYDRV_WND_ScrollWindow( WND *wndPtr, HDC hdc, INT dx, INT dy, - const RECT *clipRect, BOOL bUpdate) -{ - FIXME("(%p, %x, %d, %d, %p, %d): stub\n", - wndPtr, hdc, dx, dy, clipRect, bUpdate); -} - /*********************************************************************** * TTYDRV_WND_SetHostAttr */ diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c index cb4f9e8bec2..2690e8daa16 100644 --- a/dlls/user/user_main.c +++ b/dlls/user/user_main.c @@ -88,6 +88,7 @@ static BOOL load_driver(void) GET_USER_FUNC(DestroyWindow); GET_USER_FUNC(GetDC); GET_USER_FUNC(EnableWindow); + GET_USER_FUNC(ScrollWindowEx); GET_USER_FUNC(SetFocus); GET_USER_FUNC(SetParent); GET_USER_FUNC(SetWindowPos); diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c index c5ca2b86ada..4a417a9b3c4 100644 --- a/dlls/x11drv/window.c +++ b/dlls/x11drv/window.c @@ -18,6 +18,7 @@ #include "debugtools.h" #include "x11drv.h" #include "win.h" +#include "dce.h" #include "options.h" DEFAULT_DEBUG_CHANNEL(win); @@ -631,3 +632,154 @@ HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small ) WIN_ReleaseWndPtr( wndPtr ); return old; } + + +/************************************************************************* + * fix_caret + */ +static BOOL fix_caret(HWND hWnd, LPRECT lprc, UINT flags) +{ + HWND hCaret = CARET_GetHwnd(); + + if( hCaret ) + { + RECT rc; + CARET_GetRect( &rc ); + if( hCaret == hWnd || + (flags & SW_SCROLLCHILDREN && IsChild(hWnd, hCaret)) ) + { + POINT pt; + pt.x = rc.left; + pt.y = rc.top; + MapWindowPoints( hCaret, hWnd, (LPPOINT)&rc, 2 ); + if( IntersectRect(lprc, lprc, &rc) ) + { + HideCaret(0); + lprc->left = pt.x; + lprc->top = pt.y; + return TRUE; + } + } + } + return FALSE; +} + + +/************************************************************************* + * ScrollWindowEx (X11DRV.@) + */ +INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy, + const RECT *rect, const RECT *clipRect, + HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags ) +{ + INT retVal = NULLREGION; + BOOL bCaret = FALSE, bOwnRgn = TRUE; + RECT rc, cliprc; + WND* wnd = WIN_FindWndPtr( hwnd ); + + if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE )) + { + retVal = ERROR; + goto END; + } + + GetClientRect(hwnd, &rc); + if (rect) IntersectRect(&rc, &rc, rect); + + if (clipRect) IntersectRect(&cliprc,&rc,clipRect); + else cliprc = rc; + + if (!IsRectEmpty(&cliprc) && (dx || dy)) + { + HDC hDC; + BOOL bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE)); + HRGN hrgnClip = CreateRectRgnIndirect(&cliprc); + HRGN hrgnTemp = CreateRectRgnIndirect(&rc); + RECT caretrc; + + TRACE("%04x, %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d) %04x\n", + (HWND16)hwnd, dx, dy, hrgnUpdate, rcUpdate, + clipRect?clipRect->left:0, clipRect?clipRect->top:0, + clipRect?clipRect->right:0, clipRect?clipRect->bottom:0, + rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags ); + + caretrc = rc; + bCaret = fix_caret(hwnd, &caretrc, flags); + + if( hrgnUpdate ) bOwnRgn = FALSE; + else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ); + + hDC = GetDCEx( hwnd, hrgnClip, DCX_CACHE | DCX_USESTYLE | + DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | + ((flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0) ); + if (hDC) + { + X11DRV_WND_SurfaceCopy(wnd,hDC,dx,dy,&rc,bUpdate); + if( bUpdate ) + { + DC* dc; + + if( (dc = DC_GetDCPtr(hDC)) ) + { + OffsetRgn( hrgnTemp, dc->DCOrgX, dc->DCOrgY ); + CombineRgn( hrgnTemp, hrgnTemp, dc->hVisRgn, + RGN_AND ); + OffsetRgn( hrgnTemp, -dc->DCOrgX, -dc->DCOrgY ); + CombineRgn( hrgnUpdate, hrgnTemp, hrgnClip, + RGN_AND ); + OffsetRgn( hrgnTemp, dx, dy ); + retVal = + CombineRgn( hrgnUpdate, hrgnUpdate, hrgnTemp, + RGN_DIFF ); + + if( rcUpdate ) GetRgnBox( hrgnUpdate, rcUpdate ); + GDI_ReleaseObj( hDC ); + } + } + ReleaseDC(hwnd, hDC); + } + + if( wnd->hrgnUpdate > 1 ) + { + /* Takes into account the fact that some damages may have + occured during the scroll. */ + CombineRgn( hrgnTemp, wnd->hrgnUpdate, 0, RGN_COPY ); + OffsetRgn( hrgnTemp, dx, dy ); + CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND ); + CombineRgn( wnd->hrgnUpdate, wnd->hrgnUpdate, hrgnTemp, RGN_OR ); + } + + if( flags & SW_SCROLLCHILDREN ) + { + RECT r; + WND *w; + for( w =WIN_LockWndPtr(wnd->child); w; WIN_UpdateWndPtr(&w, w->next)) + { + r = w->rectWindow; + if( !rect || IntersectRect(&r, &r, &rc) ) + SetWindowPos(w->hwndSelf, 0, w->rectWindow.left + dx, + w->rectWindow.top + dy, 0,0, SWP_NOZORDER | + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW | + SWP_DEFERERASE ); + } + } + + if( flags & (SW_INVALIDATE | SW_ERASE) ) + RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE | + ((flags & SW_ERASE) ? RDW_ERASENOW : 0) | + ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) ); + + if( bCaret ) + { + SetCaretPos( caretrc.left + dx, caretrc.top + dy ); + ShowCaret(0); + } + + if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate ); + DeleteObject( hrgnClip ); + DeleteObject( hrgnTemp ); + } +END: + WIN_ReleaseWndPtr(wnd); + return retVal; +} diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec index 92e8466f1fb..abfdac3db61 100644 --- a/dlls/x11drv/x11drv.spec +++ b/dlls/x11drv/x11drv.spec @@ -32,6 +32,7 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics @ cdecl DestroyWindow(long) X11DRV_DestroyWindow @ cdecl GetDC(long long long long) X11DRV_GetDC @ cdecl EnableWindow(long long) X11DRV_EnableWindow +@ cdecl ScrollWindowEx(long long long ptr ptr long ptr long) X11DRV_ScrollWindowEx @ cdecl SetFocus(long) X11DRV_SetFocus @ cdecl SetParent(long long) X11DRV_SetParent @ cdecl SetWindowPos(ptr) X11DRV_SetWindowPos diff --git a/include/user.h b/include/user.h index 494f7f34c5f..68379895723 100644 --- a/include/user.h +++ b/include/user.h @@ -75,6 +75,7 @@ typedef struct tagUSER_DRIVER { BOOL (*pDestroyWindow)(HWND); BOOL (*pGetDC)(HWND,HDC,HRGN,DWORD); BOOL (*pEnableWindow)(HWND,BOOL); + INT (*pScrollWindowEx)(HWND,INT,INT,const RECT*,const RECT*,HRGN,LPRECT,UINT); void (*pSetFocus)(HWND); HWND (*pSetParent)(HWND,HWND); BOOL (*pSetWindowPos)(WINDOWPOS *); diff --git a/include/win.h b/include/win.h index 310b4c9e2e6..2ccf79dc9f2 100644 --- a/include/win.h +++ b/include/win.h @@ -71,7 +71,6 @@ typedef struct tagWND typedef struct tagWND_DRIVER { void (*pForceWindowRaise)(WND *); - void (*pSurfaceCopy)(WND *, HDC, INT, INT, const RECT *, BOOL); BOOL (*pSetHostAttr)(WND *, INT haKey, INT value); } WND_DRIVER; diff --git a/windows/scroll.c b/windows/scroll.c index 9afd2f0bc42..dba6111059f 100644 --- a/windows/scroll.c +++ b/windows/scroll.c @@ -17,6 +17,7 @@ #include "gdi.h" #include "dce.h" #include "region.h" +#include "user.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(scroll); @@ -204,34 +205,6 @@ INT16 WINAPI ScrollWindowEx16( HWND16 hwnd, INT16 dx, INT16 dy, return ret; } -/************************************************************************* - * SCROLL_FixCaret - */ -static BOOL SCROLL_FixCaret(HWND hWnd, LPRECT lprc, UINT flags) -{ - HWND hCaret = CARET_GetHwnd(); - - if( hCaret ) - { - RECT rc; - CARET_GetRect( &rc ); - if( hCaret == hWnd || - (flags & SW_SCROLLCHILDREN && IsChild(hWnd, hCaret)) ) - { - POINT pt; - - pt.x = rc.left; pt.y = rc.top; - MapWindowPoints( hCaret, hWnd, (LPPOINT)&rc, 2 ); - if( IntersectRect(lprc, lprc, &rc) ) - { - HideCaret(0); - lprc->left = pt.x; lprc->top = pt.y; - return TRUE; - } - } - } - return FALSE; -} /************************************************************************* * ScrollWindowEx (USER32.@) @@ -243,114 +216,8 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags ) { - INT retVal = NULLREGION; - BOOL bCaret = FALSE, bOwnRgn = TRUE; - RECT rc, cliprc; - WND* wnd = WIN_FindWndPtr( hwnd ); - - if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE )) - { - retVal = ERROR; - goto END; - } - - GetClientRect(hwnd, &rc); - if (rect) IntersectRect(&rc, &rc, rect); - - if (clipRect) IntersectRect(&cliprc,&rc,clipRect); - else cliprc = rc; - - if (!IsRectEmpty(&cliprc) && (dx || dy)) - { - HDC hDC; - BOOL bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE)); - HRGN hrgnClip = CreateRectRgnIndirect(&cliprc); - HRGN hrgnTemp = CreateRectRgnIndirect(&rc); - RECT caretrc; - - TRACE("%04x, %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d) %04x\n", - (HWND16)hwnd, dx, dy, hrgnUpdate, rcUpdate, - clipRect?clipRect->left:0, clipRect?clipRect->top:0, - clipRect?clipRect->right:0, clipRect?clipRect->bottom:0, - rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags ); - - caretrc = rc; - bCaret = SCROLL_FixCaret(hwnd, &caretrc, flags); - - if( hrgnUpdate ) bOwnRgn = FALSE; - else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ); - - hDC = GetDCEx( hwnd, hrgnClip, DCX_CACHE | DCX_USESTYLE | - DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | - ((flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0) ); - if (hDC) - { - wnd->pDriver->pSurfaceCopy(wnd,hDC,dx,dy,&rc,bUpdate); - if( bUpdate ) - { - DC* dc; - - if( (dc = DC_GetDCPtr(hDC)) ) - { - OffsetRgn( hrgnTemp, dc->DCOrgX, dc->DCOrgY ); - CombineRgn( hrgnTemp, hrgnTemp, dc->hVisRgn, - RGN_AND ); - OffsetRgn( hrgnTemp, -dc->DCOrgX, -dc->DCOrgY ); - CombineRgn( hrgnUpdate, hrgnTemp, hrgnClip, - RGN_AND ); - OffsetRgn( hrgnTemp, dx, dy ); - retVal = - CombineRgn( hrgnUpdate, hrgnUpdate, hrgnTemp, - RGN_DIFF ); - - if( rcUpdate ) GetRgnBox( hrgnUpdate, rcUpdate ); - GDI_ReleaseObj( hDC ); - } - } - ReleaseDC(hwnd, hDC); - } - - if( wnd->hrgnUpdate > 1 ) - { - /* Takes into account the fact that some damages may have - occured during the scroll. */ - CombineRgn( hrgnTemp, wnd->hrgnUpdate, 0, RGN_COPY ); - OffsetRgn( hrgnTemp, dx, dy ); - CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND ); - CombineRgn( wnd->hrgnUpdate, wnd->hrgnUpdate, hrgnTemp, RGN_OR ); - } - - if( flags & SW_SCROLLCHILDREN ) - { - RECT r; - WND* w; - for( w =WIN_LockWndPtr(wnd->child); w; WIN_UpdateWndPtr(&w, w->next)) - { - r = w->rectWindow; - if( !rect || IntersectRect(&r, &r, &rc) ) - SetWindowPos(w->hwndSelf, 0, w->rectWindow.left + dx, - w->rectWindow.top + dy, 0,0, SWP_NOZORDER | - SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW | - SWP_DEFERERASE ); - } - } - - if( flags & (SW_INVALIDATE | SW_ERASE) ) - RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE | - ((flags & SW_ERASE) ? RDW_ERASENOW : 0) | - ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) ); - - if( bCaret ) - { - SetCaretPos( caretrc.left + dx, caretrc.top + dy ); - ShowCaret(0); - } - - if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate ); - DeleteObject( hrgnClip ); - DeleteObject( hrgnTemp ); - } -END: - WIN_ReleaseWndPtr(wnd); - return retVal; + if (USER_Driver.pScrollWindowEx) + return USER_Driver.pScrollWindowEx( hwnd, dx, dy, rect, clipRect, + hrgnUpdate, rcUpdate, flags ); + return ERROR; } diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c index facff76b52e..187b9cb49f2 100644 --- a/windows/x11drv/wnd.c +++ b/windows/x11drv/wnd.c @@ -41,7 +41,6 @@ extern Atom wmChangeState; WND_DRIVER X11DRV_WND_Driver = { X11DRV_WND_ForceWindowRaise, - X11DRV_WND_SurfaceCopy, X11DRV_WND_SetHostAttr };