WIN32K code cleanup.
[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.14 2003/05/18 17:16:17 ea 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
30 #include <ddk/winddi.h>
31 #include <ddk/ntddmou.h>
32 #include "objects.h"
33 #include "clip.h"
34 #include "../dib/dib.h"
35 #include <include/mouse.h>
36 #include <include/object.h>
37 #include <include/eng.h>
38
39 BOOL STDCALL
40 EngCopyBits(SURFOBJ *Dest,
41 SURFOBJ *Source,
42 CLIPOBJ *Clip,
43 XLATEOBJ *ColorTranslation,
44 RECTL *DestRect,
45 POINTL *SourcePoint)
46 {
47 BOOLEAN ret;
48 SURFGDI *DestGDI, *SourceGDI;
49 BYTE clippingType;
50 RECTL rclTmp;
51 POINTL ptlTmp;
52 RECT_ENUM RectEnum;
53 BOOL EnumMore;
54
55 MouseSafetyOnDrawStart(Source, SourceGDI, SourcePoint->x, SourcePoint->y,
56 (SourcePoint->x + abs(DestRect->right - DestRect->left)),
57 (SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
58 MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
59
60 // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
61 // mark the copy block function to be DrvCopyBits instead of the
62 // GDI's copy bit function so as to remove clipping from the
63 // driver's responsibility
64
65 // If one of the surfaces isn't managed by the GDI
66 if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
67 {
68 // Destination surface is device managed
69 if(Dest->iType!=STYPE_BITMAP)
70 {
71 DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
72
73 if (DestGDI->CopyBits!=NULL)
74 {
75 ret = DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
76
77 MouseSafetyOnDrawEnd(Source, SourceGDI);
78 MouseSafetyOnDrawEnd(Dest, DestGDI);
79
80 return ret;
81 }
82 }
83
84 // Source surface is device managed
85 if(Source->iType!=STYPE_BITMAP)
86 {
87 SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
88
89 if (SourceGDI->CopyBits!=NULL)
90 {
91 ret = SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
92
93 MouseSafetyOnDrawEnd(Source, SourceGDI);
94 MouseSafetyOnDrawEnd(Dest, DestGDI);
95
96 return ret;
97 }
98 }
99
100 // If CopyBits wasn't hooked, BitBlt must be
101 ret = EngBitBlt(Dest, Source,
102 NULL, Clip, ColorTranslation, DestRect, SourcePoint,
103 NULL, NULL, NULL, 0);
104
105 MouseSafetyOnDrawEnd(Source, SourceGDI);
106 MouseSafetyOnDrawEnd(Dest, DestGDI);
107
108 return ret;
109 }
110
111 // Determine clipping type
112 if (Clip == (CLIPOBJ *) NULL)
113 {
114 clippingType = DC_TRIVIAL;
115 } else {
116 clippingType = Clip->iDComplexity;
117 }
118
119 // We only handle XO_TABLE translations at the momement
120 if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
121 (ColorTranslation->flXlate & XO_TABLE))
122 {
123 SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
124 DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
125
126 switch(clippingType)
127 {
128 case DC_TRIVIAL:
129 DestGDI->DIB_BitBlt(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, ColorTranslation);
130
131 MouseSafetyOnDrawEnd(Source, SourceGDI);
132 MouseSafetyOnDrawEnd(Dest, DestGDI);
133
134 return(TRUE);
135
136 case DC_RECT:
137 // Clip the blt to the clip rectangle
138 EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
139
140 ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
141 ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
142
143 DestGDI->DIB_BitBlt(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, ColorTranslation);
144
145 MouseSafetyOnDrawEnd(Source, SourceGDI);
146 MouseSafetyOnDrawEnd(Dest, DestGDI);
147
148 return(TRUE);
149
150 case DC_COMPLEX:
151
152 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
153
154 do {
155 EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
156
157 if (RectEnum.c > 0)
158 {
159 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
160 RECTL* prcl = &RectEnum.arcl[0];
161
162 do {
163 EngIntersectRect(prcl, prcl, DestRect);
164
165 ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
166 ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
167
168 if(!DestGDI->DIB_BitBlt(Dest, Source, DestGDI, SourceGDI,
169 prcl, &ptlTmp, ColorTranslation)) return FALSE;
170
171 prcl++;
172
173 } while (prcl < prclEnd);
174 }
175
176 } while(EnumMore);
177
178 MouseSafetyOnDrawEnd(Source, SourceGDI);
179 MouseSafetyOnDrawEnd(Dest, DestGDI);
180
181 return(TRUE);
182 }
183 }
184
185 MouseSafetyOnDrawEnd(Source, SourceGDI);
186 MouseSafetyOnDrawEnd(Dest, DestGDI);
187
188 return FALSE;
189 }
190 /* EOF */