1 #include <precomp.h>
2
3 #define NDEBUG
4 #include <debug.h>
5
6
7
8 /*
9 * @implemented
10 */
11 HPEN
12 APIENTRY
ExtCreatePen(DWORD dwPenStyle,DWORD dwWidth,CONST LOGBRUSH * lplb,DWORD dwStyleCount,CONST DWORD * lpStyle)13 ExtCreatePen(DWORD dwPenStyle,
14 DWORD dwWidth,
15 CONST LOGBRUSH *lplb,
16 DWORD dwStyleCount,
17 CONST DWORD *lpStyle)
18 {
19 PVOID lpPackedDIB = NULL;
20 HPEN hPen = NULL;
21 PBITMAPINFO pConvertedInfo = NULL;
22 UINT ConvertedInfoSize = 0, lbStyle;
23 BOOL Hit = FALSE;
24
25 if ((dwPenStyle & PS_STYLE_MASK) == PS_USERSTYLE)
26 {
27 if(!lpStyle)
28 {
29 SetLastError(ERROR_INVALID_PARAMETER);
30 return 0;
31 }
32 } // This is an enhancement and prevents a call to kernel space.
33 else if ((dwPenStyle & PS_STYLE_MASK) == PS_INSIDEFRAME &&
34 (dwPenStyle & PS_TYPE_MASK) != PS_GEOMETRIC)
35 {
36 SetLastError(ERROR_INVALID_PARAMETER);
37 return 0;
38 }
39 else if ((dwPenStyle & PS_STYLE_MASK) == PS_ALTERNATE &&
40 (dwPenStyle & PS_TYPE_MASK) != PS_COSMETIC)
41 {
42 SetLastError(ERROR_INVALID_PARAMETER);
43 return 0;
44 }
45 else
46 {
47 if (dwStyleCount || lpStyle)
48 {
49 SetLastError(ERROR_INVALID_PARAMETER);
50 return 0;
51 }
52 }
53
54 lbStyle = lplb->lbStyle;
55
56 if (lplb->lbStyle > BS_HATCHED)
57 {
58 if (lplb->lbStyle == BS_PATTERN)
59 {
60 pConvertedInfo = (PBITMAPINFO)lplb->lbHatch;
61 if (!pConvertedInfo) return 0;
62 }
63 else
64 {
65 if ((lplb->lbStyle == BS_DIBPATTERN) || (lplb->lbStyle == BS_DIBPATTERNPT))
66 {
67 if (lplb->lbStyle == BS_DIBPATTERN)
68 {
69 lbStyle = BS_DIBPATTERNPT;
70 lpPackedDIB = GlobalLock((HGLOBAL)lplb->lbHatch);
71 if (lpPackedDIB == NULL) return 0;
72 }
73 pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB,
74 lplb->lbColor,
75 &ConvertedInfoSize,
76 TRUE);
77 Hit = TRUE; // We converted DIB.
78 }
79 else
80 pConvertedInfo = (PBITMAPINFO)lpStyle;
81 }
82 }
83 else
84 pConvertedInfo = (PBITMAPINFO)lplb->lbHatch;
85
86
87 hPen = NtGdiExtCreatePen(dwPenStyle,
88 dwWidth,
89 lbStyle,
90 lplb->lbColor,
91 lplb->lbHatch,
92 (ULONG_PTR)pConvertedInfo,
93 dwStyleCount,
94 (PULONG)lpStyle,
95 ConvertedInfoSize,
96 FALSE,
97 NULL);
98
99
100 if (lplb->lbStyle == BS_DIBPATTERN) GlobalUnlock((HGLOBAL)lplb->lbHatch);
101
102 if (Hit)
103 {
104 if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo)
105 RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
106 }
107 return hPen;
108 }
109
110 /*
111 * @implemented
112 */
113 HBRUSH WINAPI
CreateDIBPatternBrush(HGLOBAL hglbDIBPacked,UINT fuColorSpec)114 CreateDIBPatternBrush(
115 HGLOBAL hglbDIBPacked,
116 UINT fuColorSpec)
117 {
118 PVOID lpPackedDIB;
119 HBRUSH hBrush = NULL;
120 PBITMAPINFO pConvertedInfo;
121 UINT ConvertedInfoSize;
122
123 lpPackedDIB = GlobalLock(hglbDIBPacked);
124 if (lpPackedDIB == NULL)
125 return 0;
126
127 pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, fuColorSpec,
128 &ConvertedInfoSize, TRUE);
129 if (pConvertedInfo)
130 {
131 hBrush = NtGdiCreateDIBBrush(pConvertedInfo, fuColorSpec,
132 ConvertedInfoSize, FALSE, FALSE, lpPackedDIB);
133 if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo)
134 RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
135 }
136
137 GlobalUnlock(hglbDIBPacked);
138
139 return hBrush;
140 }
141
142 /*
143 * @implemented
144 */
145 HBRUSH WINAPI
CreateDIBPatternBrushPt(CONST VOID * lpPackedDIB,UINT fuColorSpec)146 CreateDIBPatternBrushPt(
147 CONST VOID *lpPackedDIB,
148 UINT fuColorSpec)
149 {
150 HBRUSH hBrush = NULL;
151 PBITMAPINFO pConvertedInfo;
152 UINT ConvertedInfoSize;
153
154 if (lpPackedDIB == NULL)
155 return 0;
156
157 pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, fuColorSpec,
158 &ConvertedInfoSize, TRUE);
159 if (pConvertedInfo)
160 {
161 hBrush = NtGdiCreateDIBBrush(pConvertedInfo, fuColorSpec,
162 ConvertedInfoSize, FALSE, FALSE, (PVOID)lpPackedDIB);
163 if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo)
164 RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
165 }
166
167 return hBrush;
168 }
169
170 /*
171 * @implemented
172 */
173 HBRUSH
174 WINAPI
CreateHatchBrush(INT fnStyle,COLORREF clrref)175 CreateHatchBrush(INT fnStyle,
176 COLORREF clrref)
177 {
178 return NtGdiCreateHatchBrushInternal(fnStyle, clrref, FALSE);
179 }
180
181 /*
182 * @implemented
183 */
184 HBRUSH
185 WINAPI
CreatePatternBrush(HBITMAP hbmp)186 CreatePatternBrush(HBITMAP hbmp)
187 {
188 return NtGdiCreatePatternBrushInternal(hbmp, FALSE, FALSE);
189 }
190
191 /*
192 * @implemented
193 */
194 HBRUSH
195 WINAPI
CreateSolidBrush(IN COLORREF crColor)196 CreateSolidBrush(IN COLORREF crColor)
197 {
198 /* Call Server-Side API */
199 return NtGdiCreateSolidBrush(crColor, NULL);
200 }
201
202 /*
203 * @implemented
204 */
205 HBRUSH WINAPI
CreateBrushIndirect(CONST LOGBRUSH * LogBrush)206 CreateBrushIndirect(
207 CONST LOGBRUSH *LogBrush)
208 {
209 HBRUSH hBrush;
210
211 switch (LogBrush->lbStyle)
212 {
213 case BS_DIBPATTERN:
214 hBrush = CreateDIBPatternBrush((HGLOBAL)LogBrush->lbHatch,
215 LogBrush->lbColor);
216 break;
217
218 case BS_DIBPATTERNPT:
219 hBrush = CreateDIBPatternBrushPt((PVOID)LogBrush->lbHatch,
220 LogBrush->lbColor);
221 break;
222
223 case BS_PATTERN:
224 hBrush = NtGdiCreatePatternBrushInternal((HBITMAP)LogBrush->lbHatch,
225 FALSE,
226 FALSE);
227 break;
228
229 case BS_PATTERN8X8:
230 hBrush = NtGdiCreatePatternBrushInternal((HBITMAP)LogBrush->lbHatch,
231 FALSE,
232 TRUE);
233 break;
234
235 case BS_SOLID:
236 /* hBrush = hGetPEBHandle(hctBrushHandle, LogBrush->lbColor);
237 if (!hBrush)*/
238 hBrush = NtGdiCreateSolidBrush(LogBrush->lbColor, 0);
239 break;
240
241 case BS_HATCHED:
242 hBrush = NtGdiCreateHatchBrushInternal(LogBrush->lbHatch,
243 LogBrush->lbColor,
244 FALSE);
245 break;
246
247 case BS_NULL:
248 hBrush = NtGdiGetStockObject(NULL_BRUSH);
249 break;
250
251 default:
252 SetLastError(ERROR_INVALID_PARAMETER);
253 hBrush = NULL;
254 break;
255 }
256
257 return hBrush;
258 }
259
260 /*
261 * @implemented
262 *
263 */
264 BOOL
265 WINAPI
GetBrushOrgEx(HDC hdc,LPPOINT pt)266 GetBrushOrgEx(HDC hdc,LPPOINT pt)
267 {
268 PDC_ATTR Dc_Attr;
269
270 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
271 if (pt)
272 {
273 pt->x = Dc_Attr->ptlBrushOrigin.x;
274 pt->y = Dc_Attr->ptlBrushOrigin.y;
275 }
276 return TRUE;
277 }
278
279 /*
280 * @implemented
281 */
282 BOOL
283 WINAPI
SetBrushOrgEx(HDC hdc,int nXOrg,int nYOrg,LPPOINT lppt)284 SetBrushOrgEx(HDC hdc,
285 int nXOrg,
286 int nYOrg,
287 LPPOINT lppt)
288 {
289 PDC_ATTR Dc_Attr;
290 #if 0
291 // Handle something other than a normal dc object.
292 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
293 {
294 PLDC pLDC = GdiGetLDC(hdc);
295 if ( (pLDC == NULL) || (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC))
296 {
297 SetLastError(ERROR_INVALID_HANDLE);
298 return FALSE;
299 }
300 if (pLDC->iType == LDC_EMFLDC)
301 {
302 return EMFDRV_SetBrushOrg(hdc, nXOrg, nYOrg); // ReactOS only.
303 }
304 return FALSE;
305 }
306 #endif
307 if (GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID)&Dc_Attr))
308 {
309 PGDIBSSETBRHORG pgSBO;
310
311 /* Does the caller want the current brush origin to be returned? */
312 if (lppt)
313 {
314 lppt->x = Dc_Attr->ptlBrushOrigin.x;
315 lppt->y = Dc_Attr->ptlBrushOrigin.y;
316 }
317
318 /* Check if we have nothing to do */
319 if ((nXOrg == Dc_Attr->ptlBrushOrigin.x) &&
320 (nYOrg == Dc_Attr->ptlBrushOrigin.y))
321 return TRUE;
322
323 /* Allocate a batch command buffer */
324 pgSBO = GdiAllocBatchCommand(hdc, GdiBCSetBrushOrg);
325 if (pgSBO != NULL)
326 {
327 /* Set current brush origin in the DC attribute */
328 Dc_Attr->ptlBrushOrigin.x = nXOrg;
329 Dc_Attr->ptlBrushOrigin.y = nYOrg;
330
331 /* Setup the GDI batch command */
332 pgSBO->ptlBrushOrigin = Dc_Attr->ptlBrushOrigin;
333
334 return TRUE;
335 }
336 }
337
338 /* Fall back to the slower kernel path */
339 return NtGdiSetBrushOrg(hdc, nXOrg, nYOrg, lppt);
340 }
341
342 /*
343 * @implemented
344 */
345 DWORD
346 WINAPI
GetBrushAttributes(HBRUSH hbr)347 GetBrushAttributes(HBRUSH hbr)
348 {
349 if ( GDI_HANDLE_IS_STOCKOBJ(hbr) )
350 {
351 return SC_BB_STOCKOBJ;
352 }
353 return 0;
354 }
355
356 /*
357 * @implemented
358 */
359 HBRUSH
360 WINAPI
SetBrushAttributes(HBRUSH hbm,DWORD dwFlags)361 SetBrushAttributes(HBRUSH hbm, DWORD dwFlags)
362 {
363 if ( dwFlags & ~SC_BB_STOCKOBJ )
364 {
365 return NULL;
366 }
367 return NtGdiSetBrushAttributes(hbm, dwFlags);
368 }
369
370 /*
371 * @implemented
372 */
373 HBRUSH
374 WINAPI
ClearBrushAttributes(HBRUSH hbm,DWORD dwFlags)375 ClearBrushAttributes(HBRUSH hbm, DWORD dwFlags)
376 {
377 if ( dwFlags & ~SC_BB_STOCKOBJ )
378 {
379 return NULL;
380 }
381 return NtGdiClearBrushAttributes(hbm, dwFlags);
382 }
383
384 /*
385 * @implemented
386 */
387 BOOL
388 WINAPI
UnrealizeObject(HGDIOBJ hgdiobj)389 UnrealizeObject(HGDIOBJ hgdiobj)
390 {
391 BOOL retValue = TRUE;
392 /*
393 Win 2k Graphics API, Black Book. by coriolis.com
394 Page 62, Note that Steps 3, 5, and 6 are not required for Windows NT(tm)
395 and Windows 2000(tm).
396
397 Step 5. UnrealizeObject(hTrackBrush);
398 */
399 /*
400 msdn.microsoft.com,
401 "Windows 2000/XP: If hgdiobj is a brush, UnrealizeObject does nothing,
402 and the function returns TRUE. Use SetBrushOrgEx to set the origin of
403 a brush."
404 */
405 if (GDI_HANDLE_GET_TYPE(hgdiobj) != GDI_OBJECT_TYPE_BRUSH)
406 {
407 retValue = NtGdiUnrealizeObject(hgdiobj);
408 }
409
410 return retValue;
411 }
412