| 1 | /* $Id: dcscroll.cpp,v 1.2 2001-09-05 13:53:50 bird Exp $ */ | 
|---|
| 2 | /* | 
|---|
| 3 | * ScrollDC implementation | 
|---|
| 4 | * | 
|---|
| 5 | * Ported from Wine (windows\scroll.c) | 
|---|
| 6 | * Fixes for clip rectangles & adaption for Odin (SvL) | 
|---|
| 7 | * | 
|---|
| 8 | * Copyright  David W. Metcalfe, 1993 | 
|---|
| 9 | *        Alex Korobka       1995,1996 | 
|---|
| 10 | * | 
|---|
| 11 | * | 
|---|
| 12 | */ | 
|---|
| 13 |  | 
|---|
| 14 | #include <os2win.h> | 
|---|
| 15 |  | 
|---|
| 16 | //****************************************************************************** | 
|---|
| 17 | //TODO: Can be more efficient (update rect/rgn calc.) | 
|---|
| 18 | //****************************************************************************** | 
|---|
| 19 | BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *rc, | 
|---|
| 20 | const RECT *prLClip, HRGN hrgnUpdate, | 
|---|
| 21 | LPRECT rcUpdate ) | 
|---|
| 22 | { | 
|---|
| 23 | RECT rect, rClip, rSrc; | 
|---|
| 24 | POINT src, dest; | 
|---|
| 25 |  | 
|---|
| 26 | dprintf(("USER32: ScrollDC %04x %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d)", | 
|---|
| 27 | hdc, dx, dy, hrgnUpdate, rcUpdate, | 
|---|
| 28 | prLClip ? prLClip->left : 0, prLClip ? prLClip->top : 0, prLClip ? prLClip->right : 0, prLClip ? prLClip->bottom : 0, | 
|---|
| 29 | rc ? rc->left : 0, rc ? rc->top : 0, rc ? rc->right : 0, rc ? rc->bottom : 0 )); | 
|---|
| 30 |  | 
|---|
| 31 | if ( !hdc ) return FALSE; | 
|---|
| 32 |  | 
|---|
| 33 | /* compute device clipping region (in device coordinates) */ | 
|---|
| 34 |  | 
|---|
| 35 | if ( rc ) | 
|---|
| 36 | rect = *rc; | 
|---|
| 37 | else /* maybe we should just return FALSE? */ | 
|---|
| 38 | { | 
|---|
| 39 | DebugInt3(); | 
|---|
| 40 | GetClipBox( hdc, &rect ); | 
|---|
| 41 | } | 
|---|
| 42 |  | 
|---|
| 43 | LPtoDP( hdc, (LPPOINT)&rect, 2 ); | 
|---|
| 44 |  | 
|---|
| 45 | if (prLClip) | 
|---|
| 46 | { | 
|---|
| 47 | rClip = *prLClip; | 
|---|
| 48 | LPtoDP( hdc, (LPPOINT)&rClip, 2 ); | 
|---|
| 49 | IntersectRect( &rClip, &rect, &rClip ); | 
|---|
| 50 | } | 
|---|
| 51 | else | 
|---|
| 52 | rClip = rect; | 
|---|
| 53 |  | 
|---|
| 54 | //limit scrolling to DC's clip rectangle | 
|---|
| 55 | GetClipBox( hdc, &rSrc ); | 
|---|
| 56 | IntersectRect( &rClip, &rSrc, &rClip ); | 
|---|
| 57 | IntersectRect( &rect, &rSrc, &rect ); | 
|---|
| 58 |  | 
|---|
| 59 | POINT ptl[2] = { 0, 0, dx, dy }; | 
|---|
| 60 |  | 
|---|
| 61 | LPtoDP( hdc, ptl, 2); | 
|---|
| 62 |  | 
|---|
| 63 | dx = (int)(ptl[1].x - ptl[0].x); | 
|---|
| 64 | dy = (int)(ptl[1].y - ptl[0].y); | 
|---|
| 65 |  | 
|---|
| 66 | rSrc = rClip; | 
|---|
| 67 | if (prLClip) { | 
|---|
| 68 | OffsetRect( &rSrc, -dx, -dy ); | 
|---|
| 69 | IntersectRect( &rSrc, &rSrc, &rect ); | 
|---|
| 70 | } | 
|---|
| 71 | if (!IsRectEmpty(&rSrc)) | 
|---|
| 72 | { | 
|---|
| 73 | dest.x = (src.x = rSrc.left) + dx; | 
|---|
| 74 | dest.y = (src.y = rSrc.top) + dy; | 
|---|
| 75 |  | 
|---|
| 76 | /* copy bits */ | 
|---|
| 77 |  | 
|---|
| 78 | DPtoLP( hdc, (LPPOINT)&rSrc, 2 ); | 
|---|
| 79 | DPtoLP( hdc, &src, 1 ); | 
|---|
| 80 | DPtoLP( hdc, &dest, 1 ); | 
|---|
| 81 |  | 
|---|
| 82 | if (!BitBlt( hdc, dest.x, dest.y, | 
|---|
| 83 | rSrc.right - rSrc.left, rSrc.bottom - rSrc.top, | 
|---|
| 84 | hdc, src.x, src.y, SRCCOPY)) | 
|---|
| 85 | { | 
|---|
| 86 | return FALSE; | 
|---|
| 87 | } | 
|---|
| 88 | } | 
|---|
| 89 |  | 
|---|
| 90 | /* compute update areas */ | 
|---|
| 91 |  | 
|---|
| 92 | if (hrgnUpdate || rcUpdate) | 
|---|
| 93 | { | 
|---|
| 94 | HRGN hrgn = | 
|---|
| 95 | (hrgnUpdate) ? hrgnUpdate : CreateRectRgn( 0,0,0,0 ); | 
|---|
| 96 | HRGN hrgn2; | 
|---|
| 97 |  | 
|---|
| 98 | hrgn2 = CreateRectRgnIndirect( &rect ); | 
|---|
| 99 | SetRectRgn( hrgn, rClip.left, rClip.top, | 
|---|
| 100 | rClip.right, rClip.bottom ); | 
|---|
| 101 | CombineRgn( hrgn, hrgn, hrgn2, RGN_AND ); | 
|---|
| 102 | OffsetRgn( hrgn2, dx, dy ); | 
|---|
| 103 | CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF ); | 
|---|
| 104 |  | 
|---|
| 105 | if( rcUpdate ) | 
|---|
| 106 | { | 
|---|
| 107 | GetRgnBox( hrgn, rcUpdate ); | 
|---|
| 108 |  | 
|---|
| 109 | /* Put the rcUpdate in logical coordinate */ | 
|---|
| 110 | DPtoLP( hdc, (LPPOINT)rcUpdate, 2 ); | 
|---|
| 111 | } | 
|---|
| 112 | if (!hrgnUpdate) DeleteObject( hrgn ); | 
|---|
| 113 | DeleteObject( hrgn2 ); | 
|---|
| 114 |  | 
|---|
| 115 | } | 
|---|
| 116 |  | 
|---|
| 117 | return TRUE; | 
|---|
| 118 |  | 
|---|
| 119 | } | 
|---|
| 120 | //****************************************************************************** | 
|---|
| 121 | //****************************************************************************** | 
|---|