Patch by Filip Navara.
[reactos.git] / reactos / subsys / win32k / objects / brush.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: brush.c,v 1.31 2004/01/15 21:03:05 gvg Exp $
20 */
21
22
23 #undef WIN32_LEAN_AND_MEAN
24 #include <windows.h>
25 #include <ddk/ntddk.h>
26 #include <win32k/bitmaps.h>
27 #include <win32k/brush.h>
28 #include <internal/safe.h>
29 //#include <win32k/debug.h>
30 #include <include/object.h>
31 #include <include/inteng.h>
32 #include <include/error.h>
33
34 #define NDEBUG
35 #include <win32k/debug1.h>
36
37 HBRUSH FASTCALL
38 IntGdiCreateBrushIndirect(PLOGBRUSH lb)
39 {
40 PBRUSHOBJ brushPtr;
41 HBRUSH hBrush;
42
43 hBrush = BRUSHOBJ_AllocBrush();
44 if (hBrush == NULL)
45 {
46 return 0;
47 }
48
49 brushPtr = BRUSHOBJ_LockBrush (hBrush);
50 /* FIXME: Occurs! FiN */
51 /* ASSERT( brushPtr ); *///I want to know if this ever occurs
52
53 if( brushPtr ){
54 brushPtr->iSolidColor = lb->lbColor;
55 brushPtr->logbrush.lbStyle = lb->lbStyle;
56 brushPtr->logbrush.lbColor = lb->lbColor;
57 brushPtr->logbrush.lbHatch = lb->lbHatch;
58
59 BRUSHOBJ_UnlockBrush( hBrush );
60 return hBrush;
61 }
62 return NULL;
63 }
64
65 HBRUSH FASTCALL
66 IntGdiCreateDIBPatternBrush(HGLOBAL hDIBPacked,
67 UINT ColorSpec)
68 {
69 return NULL;
70 #if 0
71 LOGBRUSH logbrush;
72 PBITMAPINFO info, newInfo;
73 INT size;
74
75 DPRINT("%04x\n", hbitmap );
76
77 logbrush.lbStyle = BS_DIBPATTERN;
78 logbrush.lbColor = coloruse;
79 logbrush.lbHatch = 0;
80
81 /* Make a copy of the bitmap */
82 if (!(info = (BITMAPINFO *)GlobalLock( hbitmap )))
83 {
84 return 0;
85 }
86
87
88 if (info->bmiHeader.biCompression) size = info->bmiHeader.biSizeImage;
89 else
90 size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
91 size += DIB_BitmapInfoSize(info, coloruse);
92
93 if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
94 {
95 GlobalUnlock16( hbitmap );
96 return 0;
97 }
98 newInfo = (BITMAPINFO *) GlobalLock16((HGLOBAL16)logbrush.lbHatch);
99 memcpy(newInfo, info, size);
100 GlobalUnlock16((HGLOBAL16)logbrush.lbHatch);
101 GlobalUnlock(hbitmap);
102 return IntGdiCreateBrushIndirect(&logbrush);
103 #endif
104 }
105
106 HBRUSH FASTCALL
107 IntGdiCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
108 UINT Usage)
109 {
110 INT size;
111 LOGBRUSH logbrush;
112 PBITMAPINFO info;
113 PBITMAPINFO newInfo;
114
115 info = (BITMAPINFO *) PackedDIB;
116 if (info == NULL)
117 {
118 return 0;
119 }
120 DPRINT ("%p %ldx%ld %dbpp\n",
121 info,
122 info->bmiHeader.biWidth,
123 info->bmiHeader.biHeight,
124 info->bmiHeader.biBitCount);
125
126 logbrush.lbStyle = BS_DIBPATTERN;
127 logbrush.lbColor = Usage;
128 logbrush.lbHatch = 0;
129
130 /* Make a copy of the bitmap */
131
132 if (info->bmiHeader.biCompression)
133 {
134 size = info->bmiHeader.biSizeImage;
135 }
136 else
137 {
138 size = DIB_GetDIBImageBytes (info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
139 }
140 size += DIB_BitmapInfoSize (info, Usage);
141
142 logbrush.lbHatch = (LONG) GDIOBJ_AllocObj(size, GDI_OBJECT_TYPE_DONTCARE, NULL);
143 if (logbrush.lbHatch == 0)
144 {
145 return 0;
146 }
147 newInfo = (PBITMAPINFO) GDIOBJ_LockObj ((HGDIOBJ) logbrush.lbHatch, GDI_OBJECT_TYPE_DONTCARE);
148 ASSERT(newInfo);
149 memcpy(newInfo, info, size);
150 GDIOBJ_UnlockObj((HGDIOBJ) logbrush.lbHatch, GDI_OBJECT_TYPE_DONTCARE);
151
152 return IntGdiCreateBrushIndirect (&logbrush);
153 }
154
155 BOOL FASTCALL
156 IntPatBlt(DC *dc,
157 INT XLeft,
158 INT YLeft,
159 INT Width,
160 INT Height,
161 DWORD ROP,
162 PBRUSHOBJ BrushObj)
163 {
164 RECT DestRect;
165 PSURFOBJ SurfObj;
166 BOOL ret;
167
168 SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
169 if (NULL == SurfObj)
170 {
171 SetLastWin32Error(ERROR_INVALID_HANDLE);
172 return FALSE;
173 }
174
175 assert(BrushObj);
176 if (BrushObj->logbrush.lbStyle != BS_NULL)
177 {
178 if (Width > 0)
179 {
180 DestRect.left = XLeft + dc->w.DCOrgX;
181 DestRect.right = XLeft + Width + dc->w.DCOrgX;
182 }
183 else
184 {
185 DestRect.left = XLeft + Width + 1 + dc->w.DCOrgX;
186 DestRect.right = XLeft + dc->w.DCOrgX + 1;
187 }
188 if (Height > 0)
189 {
190 DestRect.top = YLeft + dc->w.DCOrgY;
191 DestRect.bottom = YLeft + Height + dc->w.DCOrgY;
192 }
193 else
194 {
195 DestRect.top = YLeft + Height + dc->w.DCOrgY + 1;
196 DestRect.bottom = YLeft + dc->w.DCOrgY + 1;
197 }
198 ret = IntEngBitBlt(SurfObj,
199 NULL,
200 NULL,
201 dc->CombinedClip,
202 NULL,
203 &DestRect,
204 NULL,
205 NULL,
206 BrushObj,
207 NULL,
208 ROP);
209 }
210
211 return ret;
212 }
213
214 BOOL FASTCALL
215 IntGdiPolyPatBlt(HDC hDC,
216 DWORD dwRop,
217 PPATRECT pRects,
218 int cRects,
219 ULONG Reserved)
220 {
221 int i;
222 PPATRECT r;
223 PBRUSHOBJ BrushObj;
224 DC *dc;
225
226 dc = DC_LockDc(hDC);
227 if (dc == NULL)
228 {
229 SetLastWin32Error(ERROR_INVALID_HANDLE);
230 return(FALSE);
231 }
232
233 for (r = pRects, i = 0; i < cRects; i++)
234 {
235 BrushObj = BRUSHOBJ_LockBrush(r->hBrush);
236 IntPatBlt(dc,r->r.left,r->r.top,r->r.right,r->r.bottom,dwRop,BrushObj);
237 BRUSHOBJ_UnlockBrush(r->hBrush);
238 r++;
239 }
240 DC_UnlockDc( hDC );
241
242 return(TRUE);
243 }
244
245 /******************************************************************************/
246
247 HBRUSH STDCALL NtGdiCreateBrushIndirect(CONST LOGBRUSH *lb)
248 {
249 LOGBRUSH Safelb;
250 NTSTATUS Status;
251
252 Status = MmCopyFromCaller(&Safelb, lb, sizeof(LOGBRUSH));
253 if(!NT_SUCCESS(Status))
254 {
255 SetLastNtError(Status);
256 return 0;
257 }
258
259 return IntGdiCreateBrushIndirect(&Safelb);
260 }
261
262 HBRUSH STDCALL NtGdiCreateDIBPatternBrush(HGLOBAL hDIBPacked,
263 UINT ColorSpec)
264 {
265 /* IntGdiCreateDIBPatternBrush() */
266 UNIMPLEMENTED;
267 }
268
269 HBRUSH STDCALL NtGdiCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
270 UINT Usage)
271 {
272 /* FIXME - copy PackedDIB memory first! */
273 return IntGdiCreateDIBPatternBrushPt(PackedDIB, Usage);
274 }
275
276 HBRUSH STDCALL NtGdiCreateHatchBrush(INT Style,
277 COLORREF Color)
278 {
279 LOGBRUSH logbrush;
280
281 DPRINT("%d %06lx\n", Style, Color);
282
283 if (Style < 0 || Style >= NB_HATCH_STYLES)
284 {
285 return 0;
286 }
287 logbrush.lbStyle = BS_HATCHED;
288 logbrush.lbColor = Color;
289 logbrush.lbHatch = Style;
290
291 return IntGdiCreateBrushIndirect (&logbrush);
292 }
293
294 HBRUSH STDCALL NtGdiCreatePatternBrush(HBITMAP hBitmap)
295 {
296 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
297
298 DPRINT ("%04x\n", hBitmap);
299 logbrush.lbHatch = (INT) BITMAPOBJ_CopyBitmap (hBitmap);
300 if(!logbrush.lbHatch)
301 {
302 return 0;
303 }
304 else
305 {
306 return IntGdiCreateBrushIndirect( &logbrush );
307 }
308 }
309
310 HBRUSH STDCALL NtGdiCreateSolidBrush(COLORREF Color)
311 {
312 LOGBRUSH logbrush;
313
314 logbrush.lbStyle = BS_SOLID;
315 logbrush.lbColor = Color;
316 logbrush.lbHatch = 0;
317
318 return IntGdiCreateBrushIndirect(&logbrush);
319 }
320
321 BOOL STDCALL NtGdiFixBrushOrgEx(VOID)
322 {
323 return FALSE;
324 }
325
326 BOOL STDCALL NtGdiPolyPatBlt(HDC hDC,
327 DWORD dwRop,
328 PPATRECT pRects,
329 int cRects,
330 ULONG Reserved)
331 {
332 PPATRECT rb;
333 NTSTATUS Status;
334 BOOL Ret;
335
336 if(cRects > 0)
337 {
338 rb = ExAllocatePool(PagedPool, sizeof(PATRECT) * cRects);
339 if(!rb)
340 {
341 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
342 return FALSE;
343 }
344 Status = MmCopyFromCaller(rb, pRects, sizeof(PATRECT) * cRects);
345 if(!NT_SUCCESS(Status))
346 {
347 ExFreePool(rb);
348 SetLastNtError(Status);
349 return FALSE;
350 }
351 }
352
353 Ret = IntGdiPolyPatBlt(hDC, dwRop, pRects, cRects, Reserved);
354
355 if(cRects > 0)
356 ExFreePool(rb);
357 return Ret;
358 }
359
360 BOOL STDCALL NtGdiPatBlt(HDC hDC,
361 INT XLeft,
362 INT YLeft,
363 INT Width,
364 INT Height,
365 DWORD ROP)
366 {
367 PBRUSHOBJ BrushObj;
368 DC *dc = DC_LockDc(hDC);
369 BOOL ret;
370
371 if (NULL == dc)
372 {
373 SetLastWin32Error(ERROR_INVALID_HANDLE);
374 return FALSE;
375 }
376
377 BrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
378 if (NULL == BrushObj)
379 {
380 SetLastWin32Error(ERROR_INVALID_HANDLE);
381 DC_UnlockDc(hDC);
382 return FALSE;
383 }
384
385 ret = IntPatBlt(dc,XLeft,YLeft,Width,Height,ROP,BrushObj);
386
387 BRUSHOBJ_UnlockBrush(dc->w.hBrush);
388 DC_UnlockDc(hDC);
389 return ret;
390 }
391
392 BOOL STDCALL NtGdiSetBrushOrgEx(HDC hDC,
393 INT XOrg,
394 INT YOrg,
395 LPPOINT Point)
396 {
397 UNIMPLEMENTED;
398 }
399 /* EOF */