1 #include <precomp.h> 2 3 #define NDEBUG 4 #include <debug.h> 5 6 7 8 /* 9 * @implemented 10 */ 11 HPEN 12 APIENTRY 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 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 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 175 CreateHatchBrush(INT fnStyle, 176 COLORREF clrref) 177 { 178 return NtGdiCreateHatchBrushInternal(fnStyle, clrref, FALSE); 179 } 180 181 /* 182 * @implemented 183 */ 184 HBRUSH 185 WINAPI 186 CreatePatternBrush(HBITMAP hbmp) 187 { 188 return NtGdiCreatePatternBrushInternal(hbmp, FALSE, FALSE); 189 } 190 191 /* 192 * @implemented 193 */ 194 HBRUSH 195 WINAPI 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 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 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 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 * @unimplemented 344 */ 345 DWORD 346 WINAPI 347 GetBrushAttributes(HBRUSH hbr) 348 { 349 UNIMPLEMENTED; 350 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 351 return 0; 352 } 353 354 /* 355 * @unimplemented 356 */ 357 HBRUSH 358 WINAPI 359 SetBrushAttributes(HBRUSH hbm, DWORD dwFlags) 360 { 361 UNIMPLEMENTED; 362 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 363 return 0; 364 } 365 366 /* 367 * @unimplemented 368 */ 369 HBRUSH 370 WINAPI 371 ClearBrushAttributes(HBRUSH hbm, DWORD dwFlags) 372 { 373 UNIMPLEMENTED; 374 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 375 return 0; 376 } 377 378 /* 379 * @implemented 380 */ 381 BOOL 382 WINAPI 383 UnrealizeObject(HGDIOBJ hgdiobj) 384 { 385 BOOL retValue = TRUE; 386 /* 387 Win 2k Graphics API, Black Book. by coriolis.com 388 Page 62, Note that Steps 3, 5, and 6 are not required for Windows NT(tm) 389 and Windows 2000(tm). 390 391 Step 5. UnrealizeObject(hTrackBrush); 392 */ 393 /* 394 msdn.microsoft.com, 395 "Windows 2000/XP: If hgdiobj is a brush, UnrealizeObject does nothing, 396 and the function returns TRUE. Use SetBrushOrgEx to set the origin of 397 a brush." 398 */ 399 if (GDI_HANDLE_GET_TYPE(hgdiobj) != GDI_OBJECT_TYPE_BRUSH) 400 { 401 retValue = NtGdiUnrealizeObject(hgdiobj); 402 } 403 404 return retValue; 405 } 406