Author: fireball Date: Thu Aug 6 22:28:46 2009 New Revision: 42436
URL: http://svn.reactos.org/svn/reactos?rev=42436&view=rev Log: - Translate coordinates (logical to device) for blitting operations in usermode. - Implement ScrollDC (almost fully based on winex11's implementation). Work in progress.
Modified: branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
Modified: branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c [iso-8859-1] Thu Aug 6 22:28:46 2009 @@ -44,6 +44,30 @@ INT width, INT height, NTDRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, DWORD rop ) { + POINT pts[2]; + + /* map source coordinates */ + if (physDevSrc) + { + pts[0].x = xSrc; + pts[0].y = ySrc; + pts[1].x = xSrc + width; + pts[1].y = ySrc + height; + + LPtoDP(physDevSrc->hUserDC, pts, 2); + width = pts[1].x - pts[0].x; + height = pts[1].y - pts[0].y; + xSrc = pts[0].x; + ySrc = pts[0].y; + } + + /* map dest coordinates */ + pts[0].x = xDst; + pts[0].y = yDst; + LPtoDP(physDevDst->hUserDC, pts, 1); + xDst = pts[0].x; + yDst = pts[0].y; + return RosGdiBitBlt(physDevDst->hKernelDC, xDst, yDst, width, height, physDevSrc->hKernelDC, xSrc, ySrc, rop); } @@ -357,6 +381,20 @@
BOOL CDECL RosDrv_PatBlt( NTDRV_PDEVICE *physDev, INT left, INT top, INT width, INT height, DWORD rop ) { + POINT pts[2]; + + /* Map coordinates */ + pts[0].x = left; + pts[0].y = top; + pts[1].x = left + width; + pts[1].y = top + height; + + LPtoDP(physDev->hUserDC, pts, 2); + width = pts[1].x - pts[0].x; + height = pts[1].y - pts[0].y; + left = pts[0].x; + top = pts[0].y; + return RosGdiPatBlt(physDev->hKernelDC, left, top, width, height, rop); }
@@ -667,6 +705,34 @@ NTDRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop ) { + POINT pts[2]; + + /* map source coordinates */ + if (physDevSrc) + { + pts[0].x = xSrc; + pts[0].y = ySrc; + pts[1].x = xSrc + widthSrc; + pts[1].y = ySrc + heightSrc; + + LPtoDP(physDevSrc->hUserDC, pts, 2); + widthSrc = pts[1].x - pts[0].x; + heightSrc = pts[1].y - pts[0].y; + xSrc = pts[0].x; + ySrc = pts[0].y; + } + + /* map dest coordinates */ + pts[0].x = xDst; + pts[0].y = yDst; + pts[1].x = xDst + widthDst; + pts[1].y = yDst + heightDst; + LPtoDP(physDevDst->hUserDC, pts, 2); + widthDst = pts[1].x - pts[0].x; + heightDst = pts[1].y - pts[0].y; + xDst = pts[0].x; + yDst = pts[0].y; + return RosGdiStretchBlt(physDevDst->hKernelDC, xDst, yDst, widthDst, heightDst, physDevSrc->hKernelDC, xSrc, ySrc, widthSrc, heightSrc, rop); }
Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Thu Aug 6 22:28:46 2009 @@ -559,11 +559,142 @@ ExtEscape( hdc, NTDRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL ); }
-BOOL CDECL RosDrv_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip, - HRGN hrgn, LPRECT update ) -{ - UNIMPLEMENTED; - return FALSE; +/* + * Scroll windows and DCs + * + * Copyright 1993 David W. Metcalfe + * Copyright 1995, 1996 Alex Korobka + * Copyright 2001 Alexandre Julliard + */ +BOOL CDECL RosDrv_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; }
void CDECL RosDrv_SetCapture( HWND hwnd, UINT flags )