[DDK]: Merge 46183 from header-branch.
[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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 BOOL 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 goto cleanup;
82 }
83 }
84
85 // Source surface is device managed
86 if (psoSource->iType!=STYPE_BITMAP)
87 {
88 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */
89 if (psurfSource->flHooks & HOOK_COPYBITS)
90 {
91 ret = GDIDEVFUNCS(psoSource).CopyBits(
92 psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
93
94 goto cleanup;
95 }
96 }
97
98 // If CopyBits wasn't hooked, BitBlt must be
99 ret = IntEngBitBlt(psoDest, psoSource,
100 NULL, Clip, ColorTranslation, DestRect, SourcePoint,
101 NULL, NULL, NULL, ROP3_TO_ROP4(SRCCOPY));
102
103 goto cleanup;
104 }
105
106 // Determine clipping type
107 if (!Clip)
108 {
109 clippingType = DC_TRIVIAL;
110 }
111 else
112 {
113 clippingType = Clip->iDComplexity;
114 }
115
116 BltInfo.DestSurface = psoDest;
117 BltInfo.SourceSurface = psoSource;
118 BltInfo.PatternSurface = NULL;
119 BltInfo.XlateSourceToDest = ColorTranslation;
120 BltInfo.Rop4 = SRCCOPY;
121
122 switch (clippingType)
123 {
124 case DC_TRIVIAL:
125 BltInfo.DestRect = *DestRect;
126 BltInfo.SourcePoint = *SourcePoint;
127
128 ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
129 break;
130
131 case DC_RECT:
132 // Clip the blt to the clip rectangle
133 RECTL_bIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds);
134
135 BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left;
136 BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top;
137
138 ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
139 break;
140
141 case DC_COMPLEX:
142
143 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, 0);
144
145 do
146 {
147 EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
148
149 if (RectEnum.c > 0)
150 {
151 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
152 RECTL* prcl = &RectEnum.arcl[0];
153
154 do
155 {
156 RECTL_bIntersectRect(&BltInfo.DestRect, prcl, DestRect);
157
158 BltInfo.SourcePoint.x = SourcePoint->x + prcl->left - DestRect->left;
159 BltInfo.SourcePoint.y = SourcePoint->y + prcl->top - DestRect->top;
160
161 if (!DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo))
162 {
163 ret = FALSE;
164 goto cleanup;
165 }
166
167 prcl++;
168
169 } while (prcl < prclEnd);
170 }
171
172 } while (EnumMore);
173 ret = TRUE;
174 break;
175
176 default:
177 ASSERT(FALSE);
178 ret = FALSE;
179 break;
180 }
181
182 cleanup:
183 if (psoDest != psoSource)
184 {
185 SURFACE_UnlockBitmapBits(psurfDest);
186 }
187 SURFACE_UnlockBitmapBits(psurfSource);
188
189 return ret;
190 }
191
192 BOOL APIENTRY
193 IntEngCopyBits(
194 SURFOBJ *psoDest,
195 SURFOBJ *psoSource,
196 CLIPOBJ *pco,
197 XLATEOBJ *pxlo,
198 RECTL *prclDest,
199 POINTL *ptlSource)
200 {
201 BOOL bResult;
202
203 MouseSafetyOnDrawStart(psoSource, ptlSource->x, ptlSource->y,
204 (ptlSource->x + abs(prclDest->right - prclDest->left)),
205 (ptlSource->y + abs(prclDest->bottom - prclDest->top)));
206
207 MouseSafetyOnDrawStart(psoDest, prclDest->left, prclDest->top, prclDest->right, prclDest->bottom);
208
209 bResult = EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
210
211 MouseSafetyOnDrawEnd(psoDest);
212 MouseSafetyOnDrawEnd(psoSource);
213
214 return bResult;
215 }
216
217
218 /* EOF */