Merge HAL changes 34743, 34812, 34839, 34917, 35515, 35771, 35902, 35904,
[reactos.git] / reactos / subsystems / win32 / 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 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * PURPOSE: GDI EngCopyBits Function
23 * FILE: subsys/win32k/eng/copybits.c
24 * PROGRAMER: Jason Filby
25 * REVISION HISTORY:
26 * 8/18/1999: Created
27 */
28
29 #include <w32k.h>
30
31 #define NDEBUG
32 #include <debug.h>
33
34 /*
35 * @implemented
36 */
37 BOOL APIENTRY
38 EngCopyBits(SURFOBJ *psoDest,
39 SURFOBJ *psoSource,
40 CLIPOBJ *Clip,
41 XLATEOBJ *ColorTranslation,
42 RECTL *DestRect,
43 POINTL *SourcePoint)
44 {
45 BOOLEAN ret;
46 BYTE clippingType;
47 RECT_ENUM RectEnum;
48 BOOL EnumMore;
49 BLTINFO BltInfo;
50 SURFACE *psurfDest;
51 SURFACE *psurfSource;
52
53 ASSERT(psoDest != NULL && psoSource != NULL && DestRect != NULL && SourcePoint != NULL);
54
55 psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
56 SURFACE_LockBitmapBits(psurfSource);
57
58 psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
59 if (psoDest != psoSource)
60 {
61 SURFACE_LockBitmapBits(psurfDest);
62 }
63
64 // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
65 // mark the copy block function to be DrvCopyBits instead of the
66 // GDI's copy bit function so as to remove clipping from the
67 // driver's responsibility
68
69 // If one of the surfaces isn't managed by the GDI
70 if((psoDest->iType!=STYPE_BITMAP) || (psoSource->iType!=STYPE_BITMAP))
71 {
72 // Destination surface is device managed
73 if(psoDest->iType!=STYPE_BITMAP)
74 {
75 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */
76 if (psurfDest->flHooks & HOOK_COPYBITS)
77 {
78 ret = GDIDEVFUNCS(psoDest).CopyBits(
79 psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
80
81 if (psoDest != psoSource)
82 {
83 SURFACE_UnlockBitmapBits(psurfDest);
84 }
85 SURFACE_UnlockBitmapBits(psurfSource);
86
87 return ret;
88 }
89 }
90
91 // Source surface is device managed
92 if(psoSource->iType!=STYPE_BITMAP)
93 {
94 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */
95 if (psurfSource->flHooks & HOOK_COPYBITS)
96 {
97 ret = GDIDEVFUNCS(psoSource).CopyBits(
98 psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
99
100 if (psoDest != psoSource)
101 {
102 SURFACE_UnlockBitmapBits(psurfDest);
103 }
104 SURFACE_UnlockBitmapBits(psurfSource);
105
106 return ret;
107 }
108 }
109
110 // If CopyBits wasn't hooked, BitBlt must be
111 ret = IntEngBitBlt(psoDest, psoSource,
112 NULL, Clip, ColorTranslation, DestRect, SourcePoint,
113 NULL, NULL, NULL, ROP3_TO_ROP4(SRCCOPY));
114
115 if (psoDest != psoSource)
116 {
117 SURFACE_UnlockBitmapBits(psurfDest);
118 }
119 SURFACE_UnlockBitmapBits(psurfSource);
120
121 return ret;
122 }
123
124 // Determine clipping type
125 if (Clip == (CLIPOBJ *) NULL)
126 {
127 clippingType = DC_TRIVIAL;
128 } else {
129 clippingType = Clip->iDComplexity;
130 }
131
132 BltInfo.DestSurface = psoDest;
133 BltInfo.SourceSurface = psoSource;
134 BltInfo.PatternSurface = NULL;
135 BltInfo.XlateSourceToDest = ColorTranslation;
136 BltInfo.Rop4 = SRCCOPY;
137
138 switch(clippingType)
139 {
140 case DC_TRIVIAL:
141 BltInfo.DestRect = *DestRect;
142 BltInfo.SourcePoint = *SourcePoint;
143
144 DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
145
146 MouseSafetyOnDrawEnd(psoDest);
147 if (psoDest != psoSource)
148 {
149 SURFACE_UnlockBitmapBits(psurfDest);
150 }
151 SURFACE_UnlockBitmapBits(psurfSource);
152
153 return(TRUE);
154
155 case DC_RECT:
156 // Clip the blt to the clip rectangle
157 RECTL_bIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds);
158
159 BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left;
160 BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top;
161
162 DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
163
164 if (psoDest != psoSource)
165 {
166 SURFACE_UnlockBitmapBits(psurfDest);
167 }
168 SURFACE_UnlockBitmapBits(psurfSource);
169
170 return(TRUE);
171
172 case DC_COMPLEX:
173
174 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, 0);
175
176 do {
177 EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
178
179 if (RectEnum.c > 0)
180 {
181 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
182 RECTL* prcl = &RectEnum.arcl[0];
183
184 do {
185 RECTL_bIntersectRect(&BltInfo.DestRect, prcl, DestRect);
186
187 BltInfo.SourcePoint.x = SourcePoint->x + prcl->left - DestRect->left;
188 BltInfo.SourcePoint.y = SourcePoint->y + prcl->top - DestRect->top;
189
190 if(!DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo))
191 return FALSE;
192
193 prcl++;
194
195 } while (prcl < prclEnd);
196 }
197
198 } while(EnumMore);
199
200 if (psoDest != psoSource)
201 {
202 SURFACE_UnlockBitmapBits(psurfDest);
203 }
204 SURFACE_UnlockBitmapBits(psurfSource);
205
206 return(TRUE);
207 }
208
209 if (psoDest != psoSource)
210 {
211 SURFACE_UnlockBitmapBits(psurfDest);
212 }
213 SURFACE_UnlockBitmapBits(psurfSource);
214
215 return FALSE;
216 }
217
218 BOOL APIENTRY
219 IntEngCopyBits(
220 SURFOBJ *psoDest,
221 SURFOBJ *psoSource,
222 CLIPOBJ *pco,
223 XLATEOBJ *pxlo,
224 RECTL *prclDest,
225 POINTL *ptlSource)
226 {
227 BOOL bResult;
228
229 MouseSafetyOnDrawStart(psoSource, ptlSource->x, ptlSource->y,
230 (ptlSource->x + abs(prclDest->right - prclDest->left)),
231 (ptlSource->y + abs(prclDest->bottom - prclDest->top)));
232
233 MouseSafetyOnDrawStart(psoDest, prclDest->left, prclDest->top, prclDest->right, prclDest->bottom);
234
235 bResult = EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
236
237 MouseSafetyOnDrawEnd(psoDest);
238 MouseSafetyOnDrawEnd(psoSource);
239
240 return bResult;
241 }
242
243
244 /* EOF */