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/winen…
==============================================================================
--- 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/winen…
==============================================================================
--- 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 )