Mouse pointer fix:
[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.XlatePatternToDest = NULL;
137 BltInfo.Rop4 = SRCCOPY;
138
139 switch(clippingType)
140 {
141 case DC_TRIVIAL:
142 BltInfo.DestRect = *DestRect;
143 BltInfo.SourcePoint = *SourcePoint;
144
145 DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
146
147 MouseSafetyOnDrawEnd(psoDest);
148 if (psoDest != psoSource)
149 {
150 SURFACE_UnlockBitmapBits(psurfDest);
151 }
152 SURFACE_UnlockBitmapBits(psurfSource);
153
154 return(TRUE);
155
156 case DC_RECT:
157 // Clip the blt to the clip rectangle
158 EngIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds);
159
160 BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left;
161 BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top;
162
163 DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
164
165 if (psoDest != psoSource)
166 {
167 SURFACE_UnlockBitmapBits(psurfDest);
168 }
169 SURFACE_UnlockBitmapBits(psurfSource);
170
171 return(TRUE);
172
173 case DC_COMPLEX:
174
175 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, 0);
176
177 do {
178 EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
179
180 if (RectEnum.c > 0)
181 {
182 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
183 RECTL* prcl = &RectEnum.arcl[0];
184
185 do {
186 EngIntersectRect(&BltInfo.DestRect, prcl, DestRect);
187
188 BltInfo.SourcePoint.x = SourcePoint->x + prcl->left - DestRect->left;
189 BltInfo.SourcePoint.y = SourcePoint->y + prcl->top - DestRect->top;
190
191 if(!DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo))
192 return FALSE;
193
194 prcl++;
195
196 } while (prcl < prclEnd);
197 }
198
199 } while(EnumMore);
200
201 if (psoDest != psoSource)
202 {
203 SURFACE_UnlockBitmapBits(psurfDest);
204 }
205 SURFACE_UnlockBitmapBits(psurfSource);
206
207 return(TRUE);
208 }
209
210 if (psoDest != psoSource)
211 {
212 SURFACE_UnlockBitmapBits(psurfDest);
213 }
214 SURFACE_UnlockBitmapBits(psurfSource);
215
216 return FALSE;
217 }
218
219 BOOL APIENTRY
220 IntEngCopyBits(
221 SURFOBJ *psoDest,
222 SURFOBJ *psoSource,
223 CLIPOBJ *pco,
224 XLATEOBJ *pxlo,
225 RECTL *prclDest,
226 POINTL *ptlSource)
227 {
228 BOOL bResult;
229
230 MouseSafetyOnDrawStart(psoSource, ptlSource->x, ptlSource->y,
231 (ptlSource->x + abs(prclDest->right - prclDest->left)),
232 (ptlSource->y + abs(prclDest->bottom - prclDest->top)));
233
234 MouseSafetyOnDrawStart(psoDest, prclDest->left, prclDest->top, prclDest->right, prclDest->bottom);
235
236 bResult = EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
237
238 MouseSafetyOnDrawEnd(psoDest);
239 MouseSafetyOnDrawEnd(psoSource);
240
241 return bResult;
242 }
243
244
245 /* EOF */