ASSERT parameter assumptions in EngCopyBits()
[reactos.git] / reactos / subsys / win32k / eng / copybits.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: copybits.c,v 1.27 2004/12/14 04:22:00 royce Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: GDI EngCopyBits Function
24 * FILE: subsys/win32k/eng/copybits.c
25 * PROGRAMER: Jason Filby
26 * REVISION HISTORY:
27 * 8/18/1999: Created
28 */
29 #include <w32k.h>
30
31 /*
32 * @implemented
33 */
34 BOOL STDCALL
35 EngCopyBits(SURFOBJ *Dest,
36 SURFOBJ *Source,
37 CLIPOBJ *Clip,
38 XLATEOBJ *ColorTranslation,
39 RECTL *DestRect,
40 POINTL *SourcePoint)
41 {
42 BOOLEAN ret;
43 BYTE clippingType;
44 RECT_ENUM RectEnum;
45 BOOL EnumMore;
46 BLTINFO BltInfo;
47
48 ASSERT(Dest != NULL && Source != NULL && DestRect != NULL && SourcePoint != NULL);
49
50 MouseSafetyOnDrawStart(Source, SourcePoint->x, SourcePoint->y,
51 (SourcePoint->x + abs(DestRect->right - DestRect->left)),
52 (SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
53 MouseSafetyOnDrawStart(Dest, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
54
55 // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
56 // mark the copy block function to be DrvCopyBits instead of the
57 // GDI's copy bit function so as to remove clipping from the
58 // driver's responsibility
59
60 // If one of the surfaces isn't managed by the GDI
61 if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
62 {
63 // Destination surface is device managed
64 if(Dest->iType!=STYPE_BITMAP)
65 {
66 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */
67 /* FIXME: Remove typecast. */
68 if (((BITMAPOBJ*)Dest)->flHooks & HOOK_COPYBITS)
69 {
70 ret = GDIDEVFUNCS(Dest).CopyBits(
71 Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
72
73 MouseSafetyOnDrawEnd(Dest);
74 MouseSafetyOnDrawEnd(Source);
75
76 return ret;
77 }
78 }
79
80 // Source surface is device managed
81 if(Source->iType!=STYPE_BITMAP)
82 {
83 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */
84 /* FIXME: Remove typecast. */
85 if (((BITMAPOBJ*)Source)->flHooks & HOOK_COPYBITS)
86 {
87 ret = GDIDEVFUNCS(Source).CopyBits(
88 Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
89
90 MouseSafetyOnDrawEnd(Dest);
91 MouseSafetyOnDrawEnd(Source);
92
93 return ret;
94 }
95 }
96
97 // If CopyBits wasn't hooked, BitBlt must be
98 /* FIXME: Remove the typecast! */
99 ret = IntEngBitBlt((BITMAPOBJ*)Dest, (BITMAPOBJ*)Source,
100 NULL, Clip, ColorTranslation, DestRect, SourcePoint,
101 NULL, NULL, NULL, 0);
102
103 MouseSafetyOnDrawEnd(Dest);
104 MouseSafetyOnDrawEnd(Source);
105
106 return ret;
107 }
108
109 // Determine clipping type
110 if (Clip == (CLIPOBJ *) NULL)
111 {
112 clippingType = DC_TRIVIAL;
113 } else {
114 clippingType = Clip->iDComplexity;
115 }
116
117 BltInfo.DestSurface = Dest;
118 BltInfo.SourceSurface = Source;
119 BltInfo.PatternSurface = NULL;
120 BltInfo.XlateSourceToDest = ColorTranslation;
121 BltInfo.XlatePatternToDest = NULL;
122 BltInfo.Rop4 = SRCCOPY;
123
124 switch(clippingType)
125 {
126 case DC_TRIVIAL:
127 BltInfo.DestRect = *DestRect;
128 BltInfo.SourcePoint = *SourcePoint;
129
130 DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
131
132 MouseSafetyOnDrawEnd(Dest);
133 MouseSafetyOnDrawEnd(Source);
134
135 return(TRUE);
136
137 case DC_RECT:
138 // Clip the blt to the clip rectangle
139 EngIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds);
140
141 BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left;
142 BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top;
143
144 DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
145
146 MouseSafetyOnDrawEnd(Dest);
147 MouseSafetyOnDrawEnd(Source);
148
149 return(TRUE);
150
151 case DC_COMPLEX:
152
153 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, 0);
154
155 do {
156 EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
157
158 if (RectEnum.c > 0)
159 {
160 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
161 RECTL* prcl = &RectEnum.arcl[0];
162
163 do {
164 EngIntersectRect(&BltInfo.DestRect, prcl, DestRect);
165
166 BltInfo.SourcePoint.x = SourcePoint->x + prcl->left - DestRect->left;
167 BltInfo.SourcePoint.y = SourcePoint->y + prcl->top - DestRect->top;
168
169 if(!DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo))
170 return FALSE;
171
172 prcl++;
173
174 } while (prcl < prclEnd);
175 }
176
177 } while(EnumMore);
178
179 MouseSafetyOnDrawEnd(Dest);
180 MouseSafetyOnDrawEnd(Source);
181
182 return(TRUE);
183 }
184
185 MouseSafetyOnDrawEnd(Dest);
186 MouseSafetyOnDrawEnd(Source);
187
188 return FALSE;
189 }
190
191 /* EOF */