[WIN32K]
[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 <win32k.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 psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
57
58 // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
59 // mark the copy block function to be DrvCopyBits instead of the
60 // GDI's copy bit function so as to remove clipping from the
61 // driver's responsibility
62
63 // If one of the surfaces isn't managed by the GDI
64 if ((psoDest->iType!=STYPE_BITMAP) || (psoSource->iType!=STYPE_BITMAP))
65 {
66 // Destination surface is device managed
67 if (psoDest->iType!=STYPE_BITMAP)
68 {
69 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */
70 if (psurfDest->flags & HOOK_COPYBITS)
71 {
72 ret = GDIDEVFUNCS(psoDest).CopyBits(
73 psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
74
75 goto cleanup;
76 }
77 }
78
79 // Source surface is device managed
80 if (psoSource->iType!=STYPE_BITMAP)
81 {
82 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */
83 if (psurfSource->flags & HOOK_COPYBITS)
84 {
85 ret = GDIDEVFUNCS(psoSource).CopyBits(
86 psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
87
88 goto cleanup;
89 }
90 }
91
92 // If CopyBits wasn't hooked, BitBlt must be
93 ret = IntEngBitBlt(psoDest, psoSource,
94 NULL, Clip, ColorTranslation, DestRect, SourcePoint,
95 NULL, NULL, NULL, ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
96
97 goto cleanup;
98 }
99
100 // Determine clipping type
101 if (!Clip)
102 {
103 clippingType = DC_TRIVIAL;
104 }
105 else
106 {
107 clippingType = Clip->iDComplexity;
108 }
109
110 BltInfo.DestSurface = psoDest;
111 BltInfo.SourceSurface = psoSource;
112 BltInfo.PatternSurface = NULL;
113 BltInfo.XlateSourceToDest = ColorTranslation;
114 BltInfo.Rop4 = ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY);
115
116 switch (clippingType)
117 {
118 case DC_TRIVIAL:
119 BltInfo.DestRect = *DestRect;
120 BltInfo.SourcePoint = *SourcePoint;
121
122 ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
123 break;
124
125 case DC_RECT:
126 // Clip the blt to the clip rectangle
127 RECTL_bIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds);
128
129 BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left;
130 BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top;
131
132 ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
133 break;
134
135 case DC_COMPLEX:
136
137 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, 0);
138
139 do
140 {
141 EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
142
143 if (RectEnum.c > 0)
144 {
145 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
146 RECTL* prcl = &RectEnum.arcl[0];
147
148 do
149 {
150 RECTL_bIntersectRect(&BltInfo.DestRect, prcl, DestRect);
151
152 BltInfo.SourcePoint.x = SourcePoint->x + prcl->left - DestRect->left;
153 BltInfo.SourcePoint.y = SourcePoint->y + prcl->top - DestRect->top;
154
155 if (!DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo))
156 {
157 ret = FALSE;
158 goto cleanup;
159 }
160
161 prcl++;
162
163 } while (prcl < prclEnd);
164 }
165
166 } while (EnumMore);
167 ret = TRUE;
168 break;
169
170 default:
171 ASSERT(FALSE);
172 ret = FALSE;
173 break;
174 }
175
176 cleanup:
177 return ret;
178 }
179
180 BOOL APIENTRY
181 IntEngCopyBits(
182 SURFOBJ *psoDest,
183 SURFOBJ *psoSource,
184 CLIPOBJ *pco,
185 XLATEOBJ *pxlo,
186 RECTL *prclDest,
187 POINTL *ptlSource)
188 {
189 return EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
190 }
191
192
193 /* EOF */