1 /* 2 * ReactOS kernel 3 * Copyright (C) 1998, 1999, 2000, 2001 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 /* 20 * PROJECT: ReactOS user32.dll 21 * FILE: win32ss/user/user32/windows/paint.c 22 * PURPOSE: Input 23 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) 24 * UPDATE HISTORY: 25 * 09-05-2001 CSH Created 26 */ 27 28 /* INCLUDES ******************************************************************/ 29 30 #include <user32.h> 31 32 static HBRUSH FrameBrushes[13]; 33 static HBITMAP hHatch; 34 const DWORD HatchBitmap[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA}; 35 36 BOOL WINAPI MirrorRgn(HWND hwnd, HRGN hrgn); 37 BOOL WINAPI PolyPatBlt(HDC,DWORD,PPATRECT,INT,ULONG); 38 39 /* FUNCTIONS *****************************************************************/ 40 41 INT 42 WINAPI 43 MirrorWindowRect( PWND pWnd, LPRECT lprc) 44 { 45 INT Ret = pWnd->rcWindow.right - pWnd->rcWindow.left - lprc->left; 46 lprc->left = pWnd->rcWindow.right - pWnd->rcWindow.left - lprc->right; 47 lprc->right = Ret; 48 return Ret; 49 } 50 51 VOID 52 CreateFrameBrushes(VOID) 53 { 54 FrameBrushes[0] = CreateSolidBrush(RGB(0,0,0)); 55 FrameBrushes[1] = CreateSolidBrush(RGB(0,0,128)); 56 FrameBrushes[2] = CreateSolidBrush(RGB(10,36,106)); 57 FrameBrushes[3] = CreateSolidBrush(RGB(128,128,128)); 58 FrameBrushes[4] = CreateSolidBrush(RGB(181,181,181)); 59 FrameBrushes[5] = CreateSolidBrush(RGB(212,208,200)); 60 FrameBrushes[6] = CreateSolidBrush(RGB(236,233,216)); 61 FrameBrushes[7] = CreateSolidBrush(RGB(255,255,255)); 62 FrameBrushes[8] = CreateSolidBrush(RGB(49,106,197)); 63 FrameBrushes[9] = CreateSolidBrush(RGB(58,110,165)); 64 FrameBrushes[10] = CreateSolidBrush(RGB(64,64,64)); 65 FrameBrushes[11] = CreateSolidBrush(RGB(255,255,225)); 66 hHatch = CreateBitmap(8, 8, 1, 1, HatchBitmap); 67 FrameBrushes[12] = CreatePatternBrush(hHatch); 68 } 69 70 VOID 71 DeleteFrameBrushes(VOID) 72 { 73 unsigned Brush; 74 75 for (Brush = 0; Brush < sizeof(FrameBrushes) / sizeof(HBRUSH); Brush++) 76 { 77 if (NULL != FrameBrushes[Brush]) 78 { 79 DeleteObject(FrameBrushes[Brush]); 80 FrameBrushes[Brush] = NULL; 81 } 82 } 83 if (NULL != hHatch) 84 { 85 DeleteObject(hHatch); 86 hHatch = NULL; 87 } 88 } 89 90 91 /* 92 * @implemented 93 */ 94 BOOL 95 WINAPI 96 GetUpdateRect( 97 HWND Wnd, 98 LPRECT Rect, 99 BOOL Erase) 100 { 101 PWND pWnd; 102 103 pWnd = ValidateHwnd(Wnd); 104 if (!pWnd) 105 return FALSE; 106 107 if ( pWnd->hrgnUpdate || 108 pWnd->state & (WNDS_SENDERASEBACKGROUND|WNDS_SENDNCPAINT|WNDS_UPDATEDIRTY|WNDS_PAINTNOTPROCESSED)) 109 { 110 return NtUserGetUpdateRect(Wnd, Rect, Erase); 111 } 112 113 if (Rect) 114 { // Did the Rgn update? No! Back set and shutup! 115 Rect->left = Rect->right = Rect->top = Rect->bottom = 0; 116 } 117 return FALSE; // msdn: "If there is no update region, the return value is zero." 118 119 } 120 121 122 /* 123 * @implemented 124 */ 125 int 126 WINAPI 127 GetUpdateRgn( 128 HWND hWnd, 129 HRGN hRgn, 130 BOOL bErase) 131 { 132 PWND pWnd; 133 134 if (!hRgn) 135 { 136 SetLastError(ERROR_INVALID_HANDLE); 137 return ERROR; 138 } 139 140 pWnd = ValidateHwnd(hWnd); 141 if (!pWnd) 142 return ERROR; 143 144 if ( pWnd->hrgnUpdate || 145 pWnd->state & (WNDS_SENDERASEBACKGROUND|WNDS_SENDNCPAINT|WNDS_UPDATEDIRTY|WNDS_PAINTNOTPROCESSED)) 146 { 147 return NtUserGetUpdateRgn(hWnd, hRgn, bErase); 148 } 149 SetRectRgn(hRgn, 0, 0, 0, 0); 150 return NULLREGION; 151 } 152 153 154 /* 155 * @implemented 156 */ 157 BOOL WINAPI 158 ScrollDC( 159 HDC hDC, 160 int dx, 161 int dy, 162 CONST RECT *lprcScroll, 163 CONST RECT *lprcClip, 164 HRGN hrgnUpdate, 165 LPRECT lprcUpdate) 166 { 167 if (hDC == NULL) return FALSE; 168 169 if (dx == 0 && dy == 0) 170 { 171 if (hrgnUpdate) SetRectRgn(hrgnUpdate, 0, 0, 0, 0); 172 if (lprcUpdate) lprcUpdate->left = lprcUpdate->right = 173 lprcUpdate->top = lprcUpdate->bottom = 0; 174 return TRUE; 175 } 176 177 return NtUserScrollDC( hDC, 178 dx, 179 dy, 180 lprcScroll, 181 lprcClip, 182 hrgnUpdate, 183 lprcUpdate); 184 } 185 186 /* 187 * @implemented 188 */ 189 int 190 WINAPI 191 SetWindowRgn( 192 HWND hWnd, 193 HRGN hRgn, 194 BOOL bRedraw) 195 { 196 BOOL Hook; 197 int Ret = 0; 198 199 LoadUserApiHook(); 200 201 Hook = BeginIfHookedUserApiHook(); 202 203 /* Bypass SEH and go direct. */ 204 if (!Hook) 205 { 206 Ret = NtUserSetWindowRgn(hWnd, hRgn, bRedraw); 207 if (Ret) 208 DeleteObject(hRgn); 209 return Ret; 210 } 211 212 _SEH2_TRY 213 { 214 Ret = guah.SetWindowRgn(hWnd, hRgn, bRedraw); 215 } 216 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 217 { 218 } 219 _SEH2_END; 220 221 EndUserApiHook(); 222 223 return Ret; 224 } 225 226 /* 227 * @implemented 228 */ 229 BOOL 230 WINAPI 231 UpdateWindow( 232 HWND hWnd) 233 { 234 PWND pWnd = ValidateHwnd(hWnd); 235 236 if (!pWnd) 237 return FALSE; 238 239 if ( pWnd->hrgnUpdate || 240 pWnd->state & WNDS_INTERNALPAINT || 241 pWnd->spwndChild ) 242 { 243 return NtUserxUpdateWindow(hWnd); 244 } 245 return TRUE; 246 } 247 248 /* 249 * @implemented 250 */ 251 BOOL 252 WINAPI 253 ValidateRgn( 254 HWND hWnd, 255 HRGN hRgn) 256 { 257 return NtUserxValidateRgn(hWnd, hRgn); 258 } 259 260 /* 261 * @implemented 262 */ 263 int 264 WINAPI 265 GetWindowRgn( 266 HWND hWnd, 267 HRGN hRgn) 268 { 269 PWND pWnd; 270 int Ret; 271 272 if (!hRgn) 273 return ERROR; 274 275 pWnd = ValidateHwnd(hWnd); 276 277 if (!pWnd || !pWnd->hrgnClip || pWnd->state2 & WNDS2_MAXIMIZEDMONITORREGION) 278 return ERROR; 279 280 Ret = CombineRgn(hRgn, pWnd->hrgnClip, NULL, RGN_COPY); 281 282 if (!Ret) 283 return ERROR; 284 /* 285 if (hWnd != GetDesktopWindow()) // pWnd->fnid != FNID_DESKTOP) 286 Ret = OffsetRgn(hRgn, -pWnd->rcWindow.left, -pWnd->rcWindow.top); 287 */ 288 if (pWnd->ExStyle & WS_EX_LAYOUTRTL) 289 MirrorRgn(hWnd, hRgn); 290 291 return Ret; 292 } 293 294 /* 295 * @implemented 296 */ 297 int 298 WINAPI 299 GetWindowRgnBox( 300 HWND hWnd, 301 LPRECT lprc) 302 { 303 PWND pWnd; 304 int Ret; 305 306 if (!lprc) 307 return ERROR; 308 309 pWnd = ValidateHwnd(hWnd); 310 311 if (!pWnd || !pWnd->hrgnClip || pWnd->state2 & WNDS2_MAXIMIZEDMONITORREGION) 312 return ERROR; 313 314 Ret = GetRgnBox(pWnd->hrgnClip, lprc); 315 316 if (!Ret) 317 return ERROR; 318 /* 319 if (hWnd != GetDesktopWindow()) // pWnd->fnid != FNID_DESKTOP) 320 OffsetRect(lprc, -pWnd->rcWindow.left, -pWnd->rcWindow.top); 321 */ 322 if (pWnd->ExStyle & WS_EX_LAYOUTRTL) 323 MirrorWindowRect(pWnd, lprc); 324 325 return Ret; 326 } 327 328 329 const BYTE MappingTable[33] = {5,9,2,3,5,7,0,0,0,7,5,5,3,2,7,5,3,3,0,5,7,10,5,0,11,4,1,1,3,8,6,12,7}; 330 /* 331 * @implemented 332 */ 333 BOOL 334 WINAPI 335 DrawFrame( 336 HDC hDc, 337 RECT *r, 338 DWORD width, 339 DWORD type 340 ) 341 { 342 DWORD rop; 343 DWORD brush; 344 HBRUSH hbrFrame; 345 PATRECT p[4]; 346 if (NULL == FrameBrushes[0]) 347 { 348 CreateFrameBrushes(); 349 } 350 if (type & 4) 351 { 352 rop = PATINVERT; 353 } 354 else 355 { 356 rop = PATCOPY; 357 } 358 brush = type / 8; 359 if (brush >= 33) 360 { 361 brush = 32; 362 } 363 brush = MappingTable[brush]; 364 hbrFrame = FrameBrushes[brush]; 365 p[0].hBrush = hbrFrame; 366 p[1].hBrush = hbrFrame; 367 p[2].hBrush = hbrFrame; 368 p[3].hBrush = hbrFrame; 369 p[0].r.left = r->left; 370 p[0].r.top = r->top; 371 p[0].r.right = r->right - r->left; 372 p[0].r.bottom = width; 373 p[1].r.left = r->left; 374 p[1].r.top = r->bottom - width; 375 p[1].r.right = r->right - r->left; 376 p[1].r.bottom = width; 377 p[2].r.left = r->left; 378 p[2].r.top = r->top + width; 379 p[2].r.right = width; 380 p[2].r.bottom = r->bottom - r->top - (width * 2); 381 p[3].r.left = r->right - width; 382 p[3].r.top = r->top + width; 383 p[3].r.right = width; 384 p[3].r.bottom = r->bottom - r->top - (width * 2); 385 return PolyPatBlt(hDc,rop,p,4,0); 386 } 387