Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dtbitmap.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: dtbitmap.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Desktop Wallpaper Routines. 00007 * 00008 * History: 00009 * 29-Jul-1991 MikeKe From win31 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 /* 00016 * Local Constants. 00017 */ 00018 #define MAXPAL 256 00019 #define MAXSTATIC 20 00020 #define TILE_XMINSIZE 2 00021 #define TILE_YMINSIZE 4 00022 00023 void xxxInvalidateDesktopOnPaletteChange(PWND pwnd); 00024 00025 __inline void 00026 SetBestStretchMode(HDC hdc, UINT bpp, BOOL fHT) 00027 { 00028 GreSetStretchBltMode( 00029 hdc, 00030 ((fHT) ? 00031 HALFTONE : 00032 ((bpp == 1) ? BLACKONWHITE : COLORONCOLOR))); 00033 } 00034 00035 /* 00036 * The version strings are stored in a contiguous-buffer. Each string 00037 * is of equal-size (MAXVERSIONSTRING). 00038 */ 00039 #define MAXTXTBUFFER 80 00040 #define MAXVERSIONBUFFER 300 // Max size of buffer (contains all 3 strings). 00041 #define MAXVERSIONSTRING 100 // Size of each string buffer. 00042 #define OFFSET_BLDSTRING 0 // Offset into verbuffer of build-string. 00043 #define OFFSET_TYPSTRING 100 // Offset into verbuffer of type string. 00044 #define OFFSET_CSDSTRING 200 // Offset into verbuffer of CSD string. 00045 00046 WCHAR wszT[MAXTXTBUFFER]; 00047 WCHAR SafeModeStr[64]; 00048 int SafeModeStrLen; 00049 /* 00050 * Bug 280256 - joejo 00051 * Draw new desktop build information global strings 00052 */ 00053 WCHAR wszProductName[MAXTXTBUFFER]; 00054 WCHAR wszProductBuild[MAXTXTBUFFER]; 00055 00056 00057 /***************************************************************************\ 00058 * GetVersionInfo 00059 * 00060 * Outputs a string on the desktop indicating debug-version. 00061 * 00062 * History: 00063 \***************************************************************************/ 00064 00065 00066 VOID 00067 GetVersionInfo( 00068 BOOL Verbose 00069 ) 00070 { 00071 WCHAR NameBuffer[MAXVERSIONBUFFER]; 00072 WCHAR Title1[128]; 00073 WCHAR Title2[128]; 00074 WCHAR wszPID[MAXVERSIONSTRING]; 00075 WCHAR wszPro[MAXVERSIONSTRING]; 00076 WCHAR wszSrv[MAXVERSIONSTRING]; 00077 WCHAR wszPBuild[MAXVERSIONSTRING]; 00078 WCHAR wszEvaluation[MAXVERSIONSTRING]; 00079 UNICODE_STRING UserBuildString; 00080 UNICODE_STRING UserTypeString; 00081 UNICODE_STRING UserCSDString; 00082 NTSTATUS Status; 00083 00084 00085 RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[] = { 00086 00087 {NULL, 00088 RTL_QUERY_REGISTRY_DIRECT, 00089 L"CurrentBuildNumber", 00090 &UserBuildString, 00091 REG_NONE, 00092 NULL, 00093 0}, 00094 00095 {NULL, 00096 RTL_QUERY_REGISTRY_DIRECT, 00097 L"CurrentType", 00098 &UserTypeString, 00099 REG_NONE, 00100 NULL, 00101 0}, 00102 00103 {NULL, 00104 RTL_QUERY_REGISTRY_DIRECT, 00105 L"CSDVersion", 00106 &UserCSDString, 00107 REG_NONE, 00108 NULL, 00109 0}, 00110 00111 {NULL, 00112 0, 00113 NULL, 00114 NULL, 00115 REG_NONE, 00116 NULL, 00117 0} 00118 }; 00119 00120 UserBuildString.Buffer = &NameBuffer[OFFSET_BLDSTRING]; 00121 UserBuildString.Length = 0; 00122 UserBuildString.MaximumLength = MAXVERSIONSTRING * sizeof(WCHAR); 00123 00124 UserTypeString.Buffer = &NameBuffer[OFFSET_TYPSTRING]; 00125 UserTypeString.Length = 0; 00126 UserTypeString.MaximumLength = MAXVERSIONSTRING * sizeof(WCHAR); 00127 00128 UserCSDString.Buffer = &NameBuffer[OFFSET_CSDSTRING]; 00129 UserCSDString.Length = 0; 00130 UserCSDString.MaximumLength = MAXVERSIONSTRING * sizeof(WCHAR); 00131 00132 Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT, 00133 L"", 00134 BaseServerRegistryConfigurationTable, 00135 NULL, 00136 NULL); 00137 00138 if (!NT_SUCCESS(Status)) { 00139 RIPMSG1(RIP_WARNING, "GetVersionInfo failed with status %x", Status); 00140 return; 00141 } 00142 00143 ServerLoadString( hModuleWin, STR_DTBS_PRODUCTID, wszPID, ARRAY_SIZE(wszPID) ); 00144 ServerLoadString( hModuleWin, STR_DTBS_PRODUCTPRO, wszPro, ARRAY_SIZE(wszPro) ); 00145 ServerLoadString( hModuleWin, STR_DTBS_PRODUCTSRV, wszSrv, ARRAY_SIZE(wszSrv) ); 00146 ServerLoadString( hModuleWin, STR_DTBS_PRODUCTBUILD, wszPBuild, ARRAY_SIZE(wszPBuild) ); 00147 00148 /* 00149 * Write out Debugging Version message. 00150 */ 00151 00152 /* 00153 * Bug 280256 - joejo 00154 * Create new desktop build information strings 00155 */ 00156 swprintf( 00157 wszProductName, 00158 wszPID, 00159 ((USER_SHARED_DATA->NtProductType == NtProductWinNt) ? wszPro : wszSrv) 00160 ); 00161 00162 00163 if (gfUnsignedDrivers) { 00164 /* This takes precedence */ 00165 ServerLoadString( hModuleWin, STR_TESTINGONLY, wszEvaluation, ARRAY_SIZE(wszEvaluation) ); 00166 } else if (USER_SHARED_DATA->SystemExpirationDate.QuadPart) { 00167 ServerLoadString(hModuleWin, STR_DTBS_EVALUATION, wszEvaluation, 00168 ARRAY_SIZE(wszEvaluation)); 00169 } else { 00170 wszEvaluation[0] = '\0'; 00171 } 00172 00173 swprintf( 00174 wszProductBuild, 00175 wszPBuild, 00176 wszEvaluation, 00177 UserBuildString.Buffer 00178 ); 00179 00180 if (Verbose) { 00181 00182 ServerLoadString( hModuleWin, STR_SAFEMODE_TITLE1, Title1, ARRAY_SIZE(Title1) ); 00183 ServerLoadString( hModuleWin, STR_SAFEMODE_TITLE2, Title2, ARRAY_SIZE(Title2) ); 00184 00185 swprintf( 00186 wszT, 00187 UserCSDString.Length == 0 ? Title1 : Title2, 00188 UserBuildString.Buffer, 00189 UserCSDString.Buffer, 00190 USER_SHARED_DATA->NtSystemRoot 00191 ); 00192 00193 } else { 00194 PWSTR s = wcsrchr( UserTypeString.Buffer, L' ' ); 00195 if (s) { 00196 s += 1; 00197 } else { 00198 s = UserTypeString.Buffer; 00199 } 00200 00201 ServerLoadString( hModuleWin, STR_SAFEMODE_TITLE3, Title1, ARRAY_SIZE(Title1) ); 00202 ServerLoadString( hModuleWin, STR_SAFEMODE_TITLE4, Title2, ARRAY_SIZE(Title2) ); 00203 00204 swprintf( 00205 wszT, 00206 UserCSDString.Length == 0 ? Title1 : Title2, 00207 UserBuildString.Buffer, 00208 UserCSDString.Buffer, 00209 s 00210 ); 00211 } 00212 } 00213 00214 /***************************************************************************\ 00215 * GetDefaultWallpaperName 00216 * 00217 * Get initial bitmap name 00218 * 00219 * History: 00220 * 21-Feb-1995 JimA Created. 00221 * 06-Mar-1996 ChrisWil Moved to kernel to facilite ChangeDisplaySettings. 00222 \***************************************************************************/ 00223 VOID GetDefaultWallpaperName( 00224 LPWSTR lpszWallpaper 00225 ) 00226 { 00227 /* 00228 * Set the initial global wallpaper bitmap name for (Default) 00229 * The global name is an at most 8 character name with no 00230 * extension. It is "winnt" for workstation or "lanmannt" 00231 * for server or server upgrade. It is followed by 256 it 00232 * is for 256 color devices. 00233 */ 00234 if (USER_SHARED_DATA->NtProductType == NtProductWinNt) { 00235 wcsncpycch(lpszWallpaper, L"winnt", 8); 00236 } else { 00237 wcsncpycch(lpszWallpaper, L"lanmannt", 8); 00238 } 00239 00240 lpszWallpaper[8] = (WCHAR)0; 00241 00242 if (gpsi->BitsPixel * gpsi->Planes > 4) { 00243 int iStart = wcslen(lpszWallpaper); 00244 iStart = min(iStart, 5); 00245 00246 lpszWallpaper[iStart] = (WCHAR)0; 00247 wcscat(lpszWallpaper, L"256"); 00248 } 00249 00250 return; 00251 } 00252 00253 /***************************************************************************\ 00254 * GetDeskWallpaperName 00255 * 00256 * History: 00257 * 19-Dec-1994 JimA Created. 00258 * 29-Sep-1995 ChrisWil ReWrote to return filename. 00259 \***************************************************************************/ 00260 00261 #define GDWPN_KEYSIZE 40 00262 #define GDWPN_BITSIZE 256 00263 00264 LPWSTR GetDeskWallpaperName(PUNICODE_STRING pProfileUserName, 00265 LPWSTR lpszFile 00266 ) 00267 { 00268 WCHAR wszKey[GDWPN_KEYSIZE]; 00269 WCHAR wszNone[GDWPN_KEYSIZE]; 00270 LPWSTR lpszBitmap = NULL; 00271 00272 /* 00273 * Load the none-string. This will be used for comparisons later. 00274 */ 00275 ServerLoadString(hModuleWin, STR_NONE, wszNone, ARRAY_SIZE(wszNone)); 00276 00277 if ((lpszFile == NULL) || 00278 (lpszFile == SETWALLPAPER_DEFAULT) || 00279 (lpszFile == SETWALLPAPER_METRICS)) { 00280 00281 /* 00282 * Allocate a buffer for the wallpaper. We will assume 00283 * a default-size in this case. 00284 */ 00285 lpszBitmap = UserAllocPool(GDWPN_BITSIZE * sizeof(WCHAR), TAG_SYSTEM); 00286 if (lpszBitmap == NULL) 00287 return NULL; 00288 00289 /* 00290 * Get the "Wallpaper" string from WIN.INI's [Desktop] section. The 00291 * section name is not localized, so hard code it. If the string 00292 * returned is Empty, then set it up for a none-wallpaper. 00293 */ 00294 if (!FastGetProfileStringFromIDW(pProfileUserName, 00295 PMAP_DESKTOP, 00296 STR_DTBITMAP, 00297 wszNone, 00298 lpszBitmap, 00299 GDWPN_BITSIZE 00300 )) { 00301 wcscpy(lpszBitmap, wszNone); 00302 } 00303 00304 } else { 00305 00306 UINT uLen; 00307 00308 uLen = wcslen(lpszFile) + 1; 00309 uLen = max(uLen, GDWPN_BITSIZE); 00310 00311 /* 00312 * Allocate enough space to store the name passed in. Returning 00313 * NULL will allow the wallpaper to redraw. As well, if we're 00314 * out of memory, then no need to load a wallpaper anyway. 00315 */ 00316 lpszBitmap = UserAllocPool(uLen * sizeof(WCHAR), TAG_SYSTEM); 00317 if (lpszBitmap == NULL) 00318 return NULL; 00319 00320 wcscpy(lpszBitmap, lpszFile); 00321 } 00322 00323 /* 00324 * No bitmap if NULL passed in or if (NONE) in win.ini entry. We 00325 * return NULL to force the redraw of the wallpaper in the kernel. 00326 */ 00327 if ((*lpszBitmap == (WCHAR)0) || (_wcsicmp(lpszBitmap, wszNone) == 0)) { 00328 UserFreePool(lpszBitmap); 00329 return NULL; 00330 } 00331 00332 /* 00333 * If bitmap name set to (DEFAULT) then set it to the system bitmap. 00334 */ 00335 ServerLoadString(hModuleWin, STR_DEFAULT, wszKey, ARRAY_SIZE(wszKey)); 00336 00337 if (_wcsicmp(lpszBitmap, wszKey) == 0) { 00338 GetDefaultWallpaperName(lpszBitmap); 00339 } 00340 00341 00342 return lpszBitmap; 00343 } 00344 00345 /***************************************************************************\ 00346 * TestVGAColors 00347 * 00348 * Tests whether the log-palette is just a standard 20 palette. 00349 * 00350 * History: 00351 * 29-Sep-1995 ChrisWil Created. 00352 \***************************************************************************/ 00353 00354 BOOL TestVGAColors( 00355 LPLOGPALETTE ppal) 00356 { 00357 int i; 00358 int n; 00359 int size; 00360 COLORREF clr; 00361 00362 static CONST DWORD StupidColors[] = { 00363 0x00000000, // 0 Sys Black 00364 0x00000080, // 1 Sys Dk Red 00365 0x00008000, // 2 Sys Dk Green 00366 0x00008080, // 3 Sys Dk Yellow 00367 0x00800000, // 4 Sys Dk Blue 00368 0x00800080, // 5 Sys Dk Violet 00369 0x00808000, // 6 Sys Dk Cyan 00370 0x00c0c0c0, // 7 Sys Lt Grey 00371 0x00808080, // 248 Sys Lt Gray 00372 0x000000ff, // 249 Sys Red 00373 0x0000ff00, // 250 Sys Green 00374 0x0000ffff, // 251 Sys Yellow 00375 0x00ff0000, // 252 Sys Blue 00376 0x00ff00ff, // 253 Sys Violet 00377 0x00ffff00, // 254 Sys Cyan 00378 0x00ffffff, // 255 Sys White 00379 00380 0x000000BF, // 1 Sys Dk Red again 00381 0x0000BF00, // 2 Sys Dk Green again 00382 0x0000BFBF, // 3 Sys Dk Yellow again 00383 0x00BF0000, // 4 Sys Dk Blue again 00384 0x00BF00BF, // 5 Sys Dk Violet again 00385 0x00BFBF00, // 6 Sys Dk Cyan again 00386 00387 0x000000C0, // 1 Sys Dk Red again 00388 0x0000C000, // 2 Sys Dk Green again 00389 0x0000C0C0, // 3 Sys Dk Yellow again 00390 0x00C00000, // 4 Sys Dk Blue again 00391 0x00C000C0, // 5 Sys Dk Violet again 00392 0x00C0C000, // 6 Sys Dk Cyan again 00393 }; 00394 00395 size = (sizeof(StupidColors) / sizeof(StupidColors[0])); 00396 00397 for (i = 0; i < (int)ppal->palNumEntries; i++) { 00398 00399 clr = ((LPDWORD)ppal->palPalEntry)[i]; 00400 00401 for (n = 0; n < size; n++) { 00402 00403 if (StupidColors[n] == clr) 00404 break; 00405 } 00406 00407 if (n == size) 00408 return FALSE; 00409 } 00410 00411 return TRUE; 00412 } 00413 00414 /***************************************************************************\ 00415 * DoHTColorAdjustment 00416 * 00417 * The default HT-Gamma adjustment was 2.0 on 3.5 (internal to gdi). For 00418 * 3.51 this value was decreased to 1.0 to accomdate printing. For our 00419 * desktop-wallpaper we are going to darken it slightly to that the image 00420 * doesn't appear to light. For the Shell-Release we will provid a UI to 00421 * allow users to change this for themselves. 00422 * 00423 * 00424 * History: 00425 * 11-May-1995 ChrisWil Created. 00426 \***************************************************************************/ 00427 00428 #define FIXED_GAMMA (WORD)13000 00429 00430 VOID DoHTColorAdjust( 00431 HDC hdc) 00432 { 00433 COLORADJUSTMENT ca; 00434 00435 00436 if (GreGetColorAdjustment(hdc, &ca)) { 00437 00438 ca.caRedGamma = 00439 ca.caGreenGamma = 00440 ca.caBlueGamma = FIXED_GAMMA; 00441 00442 GreSetColorAdjustment(hdc, &ca); 00443 } 00444 00445 return; 00446 } 00447 00448 /***************************************************************************\ 00449 * ConvertToDDB 00450 * 00451 * Converts a DIBSection to a DDB. We do this to speed up drawings so that 00452 * bitmap-colors don't have to go through a palette-translation match. This 00453 * will also stretch/expand the image if the syle is set. 00454 * 00455 * If the new image requires a halftone-palette, the we will create one and 00456 * set it as the new wallpaper-palette. 00457 * 00458 * History: 00459 * 26-Oct-1995 ChrisWil Ported. 00460 * 30-Oct-1995 ChrisWil Added halftoning. Rewote the stretch/expand stuff. 00461 \***************************************************************************/ 00462 00463 HBITMAP ConvertToDDB( 00464 HDC hdc, 00465 HBITMAP hbmOld, 00466 HPALETTE hpal) 00467 { 00468 BITMAP bm; 00469 HBITMAP hbmNew; 00470 00471 /* 00472 * This object must be a REALDIB type bitmap. 00473 */ 00474 GreExtGetObjectW(hbmOld, sizeof(bm), &bm); 00475 00476 /* 00477 * Create the new wallpaper-surface. 00478 */ 00479 if (hbmNew = GreCreateCompatibleBitmap(hdc, bm.bmWidth, bm.bmHeight)) { 00480 00481 HPALETTE hpalDst; 00482 HPALETTE hpalSrc; 00483 HBITMAP hbmDst; 00484 HBITMAP hbmSrc; 00485 UINT bpp; 00486 BOOL fHalftone = FALSE; 00487 00488 /* 00489 * Select in the surfaces. 00490 */ 00491 hbmDst = GreSelectBitmap(ghdcMem2, hbmNew); 00492 hbmSrc = GreSelectBitmap(ghdcMem, hbmOld); 00493 00494 /* 00495 * Determine image bits/pixel. 00496 */ 00497 bpp = (bm.bmPlanes * bm.bmBitsPixel); 00498 00499 /* 00500 * Use the palette if given. If the image is of a greater 00501 * resolution than the device, then we're going to go through 00502 * a halftone-palette to get better colors. 00503 */ 00504 if (hpal) { 00505 00506 hpalDst = _SelectPalette(ghdcMem2, hpal, FALSE); 00507 hpalSrc = _SelectPalette(ghdcMem, hpal, FALSE); 00508 00509 xxxRealizePalette(ghdcMem2); 00510 00511 /* 00512 * Set the halftoning for the destination. This is done 00513 * for images of greater resolution than the device. 00514 */ 00515 if (bpp > gpsi->BitCount) { 00516 fHalftone = TRUE; 00517 DoHTColorAdjust(ghdcMem2); 00518 } 00519 } 00520 00521 /* 00522 * Set the stretchbltmode. This is more necessary when doing 00523 * halftoning. Since otherwise, the colors won't translate 00524 * correctly. 00525 */ 00526 SetBestStretchMode(ghdcMem2, bpp, fHalftone); 00527 00528 /* 00529 * Set the new surface bits. Use StretchBlt() so the SBMode 00530 * will be used in color-translation. 00531 */ 00532 GreStretchBlt(ghdcMem2, 00533 0, 00534 0, 00535 bm.bmWidth, 00536 bm.bmHeight, 00537 ghdcMem, 00538 0, 00539 0, 00540 bm.bmWidth, 00541 bm.bmHeight, 00542 SRCCOPY, 00543 0); 00544 00545 /* 00546 * Restore palettes. 00547 */ 00548 if (hpal) { 00549 _SelectPalette(ghdcMem2, hpalDst, FALSE); 00550 _SelectPalette(ghdcMem, hpalSrc, FALSE); 00551 } 00552 00553 /* 00554 * Restore the surfaces. 00555 */ 00556 GreSelectBitmap(ghdcMem2, hbmDst); 00557 GreSelectBitmap(ghdcMem, hbmSrc); 00558 GreDeleteObject(hbmOld); 00559 00560 GreSetBitmapOwner(hbmNew, OBJECT_OWNER_PUBLIC); 00561 00562 } else { 00563 hbmNew = hbmOld; 00564 } 00565 00566 return hbmNew; 00567 } 00568 00569 /***************************************************************************\ 00570 * CreatePaletteFromBitmap 00571 * 00572 * Take in a REAL dib handle and create a palette from it. This will not 00573 * work for bitmaps created by any other means than CreateDIBSection or 00574 * CreateDIBitmap(CBM_CREATEDIB). This is due to the fact that these are 00575 * the only two formats who have palettes stored with their object. 00576 * 00577 * History: 00578 * 29-Sep-1995 ChrisWil Created. 00579 \***************************************************************************/ 00580 00581 HPALETTE CreatePaletteFromBitmap( 00582 HBITMAP hbm) 00583 { 00584 HPALETTE hpal; 00585 LPLOGPALETTE ppal; 00586 HBITMAP hbmT; 00587 DWORD size; 00588 int i; 00589 00590 /* 00591 * Make room for temp logical palette of max size. 00592 */ 00593 size = sizeof(LOGPALETTE) + (MAXPAL * sizeof(PALETTEENTRY)); 00594 00595 ppal = (LPLOGPALETTE)UserAllocPool(size, TAG_SYSTEM); 00596 if (!ppal) 00597 return NULL; 00598 00599 /* 00600 * Retrieve the palette from the DIB(Section). The method of calling 00601 * GreGetDIBColorTable() can only be done on sections or REAL-Dibs. 00602 */ 00603 hbmT = GreSelectBitmap(ghdcMem, hbm); 00604 ppal->palVersion = 0x300; 00605 ppal->palNumEntries = (WORD)GreGetDIBColorTable(ghdcMem, 00606 0, 00607 MAXPAL, 00608 (LPRGBQUAD)ppal->palPalEntry); 00609 GreSelectBitmap(ghdcMem, hbmT); 00610 00611 /* 00612 * Create a halftone-palette if their are no entries. Otherwise, 00613 * swap the RGB values to be palentry-compatible and create us a 00614 * palette. 00615 */ 00616 if (ppal->palNumEntries == 0) { 00617 hpal = GreCreateHalftonePalette(gpDispInfo->hdcScreen); 00618 } else { 00619 00620 BYTE tmpR; 00621 00622 /* 00623 * Swap red/blue because a RGBQUAD and PALETTEENTRY dont get along. 00624 */ 00625 for (i=0; i < (int)ppal->palNumEntries; i++) { 00626 tmpR = ppal->palPalEntry[i].peRed; 00627 ppal->palPalEntry[i].peRed = ppal->palPalEntry[i].peBlue; 00628 ppal->palPalEntry[i].peBlue = tmpR; 00629 ppal->palPalEntry[i].peFlags = 0; 00630 } 00631 00632 /* 00633 * If the Bitmap only has VGA colors in it we dont want to 00634 * use a palette. It just causes unessesary palette flashes. 00635 */ 00636 hpal = TestVGAColors(ppal) ? NULL : GreCreatePalette(ppal); 00637 } 00638 00639 UserFreePool(ppal); 00640 00641 /* 00642 * Make this palette public. 00643 */ 00644 if (hpal) 00645 GreSetPaletteOwner(hpal, OBJECT_OWNER_PUBLIC); 00646 00647 return hpal; 00648 } 00649 00650 /***************************************************************************\ 00651 * TileWallpaper 00652 * 00653 * History: 00654 * 29-Jul-1991 MikeKe From win31 00655 \***************************************************************************/ 00656 00657 BOOL 00658 TileWallpaper(HDC hdc, LPCRECT lprc, BOOL fOffset) 00659 { 00660 int xO; 00661 int yO; 00662 int x; 00663 int y; 00664 BITMAP bm; 00665 HBITMAP hbmT = NULL; 00666 POINT ptOffset; 00667 00668 if (fOffset) { 00669 ptOffset.x = gsrcWallpaper.x; 00670 ptOffset.y = gsrcWallpaper.y; 00671 } else { 00672 ptOffset.x = 0; 00673 ptOffset.y = 0; 00674 } 00675 00676 /* 00677 * We need to get the dimensions of the bitmap here rather than rely on 00678 * the dimensions in srcWallpaper because this function may 00679 * be called as part of ExpandBitmap, before srcWallpaper is 00680 * set. 00681 */ 00682 if (GreExtGetObjectW(ghbmWallpaper, sizeof(BITMAP), (PBITMAP)&bm)) { 00683 xO = lprc->left - (lprc->left % bm.bmWidth) + (ptOffset.x % bm.bmWidth); 00684 if (xO > lprc->left) { 00685 xO -= bm.bmWidth; 00686 } 00687 00688 yO = lprc->top - (lprc->top % bm.bmHeight) + (ptOffset.y % bm.bmHeight); 00689 if (yO > lprc->top) { 00690 yO -= bm.bmHeight; 00691 } 00692 00693 /* 00694 * Tile the bitmap to the surface. 00695 */ 00696 if (hbmT = GreSelectBitmap(ghdcMem, ghbmWallpaper)) { 00697 for (y = yO; y < lprc->bottom; y += bm.bmHeight) { 00698 for (x = xO; x < lprc->right; x += bm.bmWidth) { 00699 GreBitBlt(hdc, 00700 x, 00701 y, 00702 bm.bmWidth, 00703 bm.bmHeight, 00704 ghdcMem, 00705 0, 00706 0, 00707 SRCCOPY, 00708 0); 00709 } 00710 } 00711 00712 GreSelectBitmap(ghdcMem, hbmT); 00713 } 00714 } 00715 00716 return (hbmT != NULL); 00717 } 00718 00719 /***************************************************************************\ 00720 * GetWallpaperCenterRect 00721 * 00722 * Returns the rect of centered wallpaper on a particular monitor. 00723 * 00724 * History: 00725 * 26-Sep-1996 adams Created. 00726 \***************************************************************************/ 00727 00728 BOOL 00729 GetWallpaperCenterRect(LPRECT lprc, LPPOINT lppt, LPCRECT lprcMonitor) 00730 { 00731 RECT rc; 00732 00733 00734 if (gsrcWallpaper.x != 0 || gsrcWallpaper.y != 0) { 00735 rc.left = lprcMonitor->left + gsrcWallpaper.x; 00736 rc.top = lprcMonitor->top + gsrcWallpaper.y; 00737 } else { 00738 rc.left = (lprcMonitor->left + lprcMonitor->right - gsrcWallpaper.cx) / 2; 00739 rc.top = (lprcMonitor->top + lprcMonitor->bottom - gsrcWallpaper.cy) / 2; 00740 } 00741 00742 rc.right = rc.left + gsrcWallpaper.cx; 00743 rc.bottom = rc.top + gsrcWallpaper.cy; 00744 00745 lppt->x = max(0, lprcMonitor->left - rc.left); 00746 lppt->y = max(0, lprcMonitor->top - rc.top); 00747 00748 return IntersectRect(lprc, &rc, lprcMonitor); 00749 } 00750 00751 00752 00753 /***************************************************************************\ 00754 * CenterWallpaper 00755 * 00756 * 00757 * History: 00758 * 29-Jul-1991 MikeKe From win31 00759 \***************************************************************************/ 00760 00761 BOOL 00762 CenterWallpaper(HDC hdc, LPCRECT lprcMonitor) 00763 { 00764 RECT rc; 00765 HBITMAP hbmT; 00766 BOOL f = TRUE; 00767 HRGN hrgn; 00768 POINT pt; 00769 00770 if (GetWallpaperCenterRect(&rc, &pt, lprcMonitor)) { 00771 /* 00772 * This used to call TileWallpaper, but this really 00773 * slowed up the system for small dimension bitmaps. 00774 * We really only need to blt it once for centered 00775 * bitmaps. 00776 */ 00777 if (hbmT = GreSelectBitmap(ghdcMem, ghbmWallpaper)) { 00778 00779 GreBitBlt(hdc, 00780 rc.left, 00781 rc.top, 00782 rc.right - rc.left, 00783 rc.bottom - rc.top, 00784 ghdcMem, 00785 pt.x, 00786 pt.y, 00787 SRCCOPY, 00788 0); 00789 00790 GreSelectBitmap(ghdcMem, hbmT); 00791 } else { 00792 f = FALSE; 00793 } 00794 } 00795 00796 /* 00797 * Fill the bacground (excluding the bitmap) with the desktop 00798 * brush. Save the DC with the cliprect. 00799 */ 00800 if (hrgn = CreateEmptyRgn()) { 00801 if (GreGetRandomRgn(hdc, hrgn, 1) != -1) { 00802 GreExcludeClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom); 00803 FillRect(hdc, lprcMonitor, SYSHBR(DESKTOP)); 00804 GreExtSelectClipRgn(hdc, hrgn, RGN_COPY); 00805 } else { 00806 f = FALSE; 00807 } 00808 00809 GreDeleteObject(hrgn); 00810 } else { 00811 f = FALSE; 00812 } 00813 00814 return f; 00815 } 00816 00817 /***************************************************************************\ 00818 * xxxDrawWallpaper 00819 * 00820 * Performs the drawing of the wallpaper. This can be either tiled or 00821 * centered. This routine provides the common things like palette-handling. 00822 * If the (fPaint) is false, then we only to palette realization and no 00823 * drawing. 00824 * 00825 * History: 00826 * 01-Oct-1995 ChrisWil Ported. 00827 \***************************************************************************/ 00828 00829 BOOL xxxDrawWallpaper( 00830 PWND pwnd, 00831 HDC hdc, 00832 PMONITOR pMonitorPaint, 00833 LPCRECT lprc) 00834 { 00835 BOOL f; 00836 HPALETTE hpalT; 00837 int i; 00838 00839 CheckLock(pwnd); 00840 CheckLock(pMonitorPaint); 00841 UserAssert(ghbmWallpaper != NULL); 00842 UserAssert(lprc); 00843 00844 /* 00845 * Select in the palette if one exists. As a wallpaper, we should only 00846 * be able to do background-realizations. 00847 */ 00848 if ( ghpalWallpaper && 00849 pMonitorPaint->dwMONFlags & MONF_PALETTEDISPLAY) { 00850 00851 hpalT = _SelectPalette(hdc, ghpalWallpaper, FALSE); 00852 i = xxxRealizePalette(hdc); 00853 } else { 00854 hpalT = NULL; 00855 } 00856 00857 if (gwWPStyle & DTF_TILE) { 00858 f = TileWallpaper(hdc, lprc, pwnd != NULL); 00859 } else { 00860 f = CenterWallpaper(hdc, &pMonitorPaint->rcMonitor); 00861 } 00862 00863 if (hpalT) { 00864 _SelectPalette(hdc, hpalT, FALSE); 00865 } 00866 00867 return f; 00868 } 00869 00870 /***************************************************************************\ 00871 * xxxExpandBitmap 00872 * 00873 * Expand this bitmap to fit the screen. This is used for tiled images 00874 * only. 00875 * 00876 * History: 00877 * 29-Sep-1995 ChrisWil Ported from Chicago. 00878 \***************************************************************************/ 00879 00880 HBITMAP xxxExpandBitmap( 00881 HBITMAP hbm) 00882 { 00883 int nx; 00884 int ny; 00885 BITMAP bm; 00886 HBITMAP hbmNew; 00887 HBITMAP hbmD; 00888 LPRECT lprc; 00889 RECT rc; 00890 PMONITOR pMonitor; 00891 TL tlpMonitor; 00892 00893 00894 /* 00895 * Get the dimensions of the screen and bitmap we'll 00896 * be dealing with. We'll adjust the xScreen/yScreen 00897 * to reflect the new surface size. The default adjustment 00898 * is to stretch the image to fit the screen. 00899 */ 00900 GreExtGetObjectW(hbm, sizeof(bm), (PBITMAP)&bm); 00901 00902 pMonitor = GetPrimaryMonitor(); 00903 lprc = &pMonitor->rcMonitor; 00904 nx = (lprc->right / TILE_XMINSIZE) / bm.bmWidth; 00905 ny = (lprc->bottom / TILE_YMINSIZE) / bm.bmHeight; 00906 00907 if (nx == 0) 00908 nx++; 00909 00910 if (ny == 0) 00911 ny++; 00912 00913 if ((nx + ny) <= 2) 00914 return hbm; 00915 00916 00917 /* 00918 * Create the surface for the new-bitmap. 00919 */ 00920 rc.left = rc.top = 0; 00921 rc.right = nx * bm.bmWidth; 00922 rc.bottom = ny * bm.bmHeight; 00923 hbmD = GreSelectBitmap(ghdcMem, hbm); 00924 hbmNew = GreCreateCompatibleBitmap(ghdcMem, rc.right, rc.bottom); 00925 GreSelectBitmap(ghdcMem, hbmD); 00926 00927 if (hbmNew == NULL) 00928 return hbm; 00929 00930 if (hbmD = GreSelectBitmap(ghdcMem2, hbmNew)) { 00931 /* 00932 * Expand the bitmap to the new surface. 00933 */ 00934 ThreadLockAlways(pMonitor, &tlpMonitor); 00935 xxxDrawWallpaper(NULL, ghdcMem2, pMonitor, &rc); 00936 ThreadUnlock(&tlpMonitor); 00937 GreSelectBitmap(ghdcMem2, hbmD); 00938 } 00939 00940 GreDeleteObject(hbm); 00941 00942 GreSetBitmapOwner(hbmNew, OBJECT_OWNER_PUBLIC); 00943 00944 return hbmNew; 00945 } 00946 00947 /***************************************************************************\ 00948 * xxxLoadDesktopWallpaper 00949 * 00950 * Load the dib (section) from the client-side. We make this callback to 00951 * utilize code in USER32 for loading/creating a dib or section. Since, 00952 * the wallpaper-code can be called from any-process, we can't use DIBSECTIONS 00953 * for a wallpaper. Luckily we can use Real-DIBs for this. That way we 00954 * can extract out a palette from the bitmap. We couldn't do this if the 00955 * bitmap was created "compatible". 00956 * 00957 * History: 00958 * 29-Sep-1995 ChrisWil Created. 00959 \***************************************************************************/ 00960 00961 BOOL xxxLoadDesktopWallpaper( 00962 LPWSTR lpszFile) 00963 { 00964 UINT LR_flags; 00965 int dxDesired; 00966 int dyDesired; 00967 BITMAP bm; 00968 UNICODE_STRING strName; 00969 00970 00971 /* 00972 * If the bitmap is somewhat large (big bpp), then we'll deal 00973 * with it as a real-dib. We'll also do this for 8bpp since it 00974 * can utilize a palette. Chicago uses DIBSECTIONS since it can 00975 * count on the one-process handling the drawing. Since, NT can 00976 * have different processes doing the drawing, we can't use sections. 00977 */ 00978 LR_flags = LR_LOADFROMFILE; 00979 00980 if (gpDispInfo->fAnyPalette || gpsi->BitCount >= 8) { 00981 LR_flags |= LR_CREATEREALDIB; 00982 } 00983 00984 00985 /* 00986 * If we're stretching, then we will ask the loaddib code to do 00987 * it. 00988 */ 00989 if (gwWPStyle & DTF_STRETCH) { 00990 PMONITOR pMonitor; 00991 int dxMonitor, dyMonitor; 00992 00993 dxDesired = INT_MAX; 00994 dyDesired = INT_MAX; 00995 for ( pMonitor = gpDispInfo->pMonitorFirst; 00996 pMonitor; 00997 pMonitor = pMonitor->pMonitorNext) { 00998 00999 if (!(pMonitor->dwMONFlags & MONF_VISIBLE)) 01000 continue; 01001 01002 dxMonitor = pMonitor->rcMonitor.right - pMonitor->rcMonitor.left; 01003 dxDesired = min(dxDesired, dxMonitor); 01004 dyMonitor = pMonitor->rcMonitor.bottom - pMonitor->rcMonitor.top; 01005 dyDesired = min(dyDesired, dyMonitor); 01006 } 01007 } else { 01008 dxDesired = dyDesired = 0; 01009 } 01010 01011 /* 01012 * Make a callback to the client to perform the loading. 01013 * Saves us some code. 01014 */ 01015 RtlInitUnicodeString(&strName, lpszFile); 01016 01017 ghbmWallpaper = xxxClientLoadImage( 01018 &strName, 01019 0, 01020 IMAGE_BITMAP, 01021 dxDesired, 01022 dyDesired, 01023 LR_flags, 01024 TRUE); 01025 01026 if (ghbmWallpaper == NULL) 01027 return FALSE; 01028 01029 /* 01030 * If it's a palette-display, then we will derive the global 01031 * wallpaper palette from the bitmap. 01032 */ 01033 if (gpDispInfo->fAnyPalette) { 01034 ghpalWallpaper = CreatePaletteFromBitmap(ghbmWallpaper); 01035 } 01036 01037 /* 01038 * If the DIB is a higher bitdepth than the display, convert it to 01039 * a DDB, otherwise keep it as DIB. This way it takes the least 01040 * amount of memory and provides a identity-translation blt. 01041 * 01042 */ 01043 GreExtGetObjectW(ghbmWallpaper, sizeof(bm), &bm); 01044 01045 if ( gpDispInfo->cMonitors == 1 && 01046 gpsi->BitCount <= bm.bmPlanes * bm.bmBitsPixel) { 01047 01048 ghbmWallpaper = ConvertToDDB( 01049 gpDispInfo->hdcScreen, 01050 ghbmWallpaper, 01051 ghpalWallpaper); 01052 } 01053 01054 /* 01055 * Expand bitmap if we are going to tile it. Mark the bitmap 01056 * as public, so any process can party with it. This must 01057 * preceed the expand, since it performs a xxxDrawWallpaper 01058 * call that can leave the section. 01059 */ 01060 GreSetBitmapOwner(ghbmWallpaper, OBJECT_OWNER_PUBLIC); 01061 01062 if (gwWPStyle & DTF_TILE) { 01063 ghbmWallpaper = xxxExpandBitmap(ghbmWallpaper); 01064 } 01065 01066 return TRUE; 01067 } 01068 01069 /***************************************************************************\ 01070 * xxxSetDeskWallpaper 01071 * 01072 * Sets the desktop-wallpaper. This deletes the old handles in the process. 01073 * 01074 * History: 01075 * 29-Jul-1991 MikeKe From win31. 01076 * 01-Oct-1995 ChrisWil Rewrote for LoadImage(). 01077 \***************************************************************************/ 01078 01079 BOOL xxxSetDeskWallpaper(PUNICODE_STRING pProfileUserName, 01080 LPWSTR lpszFile) 01081 { 01082 BITMAP bm; 01083 UINT WallpaperStyle2; 01084 PWND pwndShell; 01085 TL tl; 01086 PTHREADINFO ptiCurrent = PtiCurrent(); 01087 PDESKTOP pdesk; 01088 BOOL fRet = FALSE; 01089 HBITMAP hbmOld; 01090 01091 PROFINTINFO apsi[] = { 01092 {PMAP_DESKTOP, (LPWSTR)STR_TILEWALL , 0, &gwWPStyle }, 01093 {PMAP_DESKTOP, (LPWSTR)STR_DTSTYLE , 0, &WallpaperStyle2 }, 01094 {PMAP_DESKTOP, (LPWSTR)STR_DTORIGINX, 0, &gsrcWallpaper.x }, 01095 {PMAP_DESKTOP, (LPWSTR)STR_DTORIGINY, 0, &gsrcWallpaper.y }, 01096 {0, NULL, 0, NULL } 01097 }; 01098 01099 pdesk = ptiCurrent->rpdesk; 01100 hbmOld = ghbmWallpaper; 01101 01102 /* 01103 * Get the shell-window. This could be NULL on system 01104 * initialization. We will use this to do palette realization. 01105 */ 01106 pwndShell = (pdesk ? pdesk->pDeskInfo->spwndShell : NULL); 01107 01108 if ((lpszFile == SETWALLPAPER_METRICS) && !(gwWPStyle & DTF_STRETCH)) { 01109 01110 gsrcWallpaper.x = 0; 01111 gsrcWallpaper.y = 0; 01112 01113 if (ghbmWallpaper) 01114 goto CreateNewWallpaper; 01115 01116 goto Metric_Change; 01117 } 01118 01119 CreateNewWallpaper: 01120 01121 /* 01122 * Delete the old wallpaper and palette if the exist. 01123 */ 01124 if (ghpalWallpaper) { 01125 GreDeleteObject(ghpalWallpaper); 01126 ghpalWallpaper = NULL; 01127 } 01128 01129 if (ghbmWallpaper) { 01130 GreDeleteObject(ghbmWallpaper); 01131 ghbmWallpaper = NULL; 01132 } 01133 01134 /* 01135 * Kill any SPBs no matter what. 01136 * Works if we're switching from/to palettized wallpaper. 01137 * Fixes a lot of problems because palette doesn't change, shell 01138 * paints funny on desktop, etc. 01139 */ 01140 FreeAllSpbs(); 01141 01142 /* 01143 * If this is a metric-change (and stretched), then we need to 01144 * reload it. However, since we are called from the winlogon process 01145 * during a desktop-switch, we would be mapped to the wrong Luid 01146 * when we attempt to grab the name from GetDeskWallpaperName. This 01147 * would use the Luid from the DEFAULT user rather than the current 01148 * logged on user. In order to avoid this, we cache the wallpaer 01149 * name so that on METRIC-CHANGES we use the current-user's wallpaper. 01150 * 01151 * NOTE: we assume that prior to any METRIC change, we have already 01152 * setup the ghbmWallpaper and lpszCached. This is usually done 01153 * either on logon or during user desktop-changes through conrol-Panel. 01154 */ 01155 if (lpszFile == SETWALLPAPER_METRICS) { 01156 01157 UserAssert(gpszWall != NULL); 01158 01159 goto LoadWallpaper; 01160 } 01161 01162 /* 01163 * Free the cached handle. 01164 */ 01165 if (gpszWall) { 01166 UserFreePool(gpszWall); 01167 gpszWall = NULL; 01168 } 01169 01170 /* 01171 * Load the wallpaper-name. If this returns FALSE, then 01172 * the user specified (None). We will return true to force 01173 * the repainting of the desktop. 01174 */ 01175 gpszWall = GetDeskWallpaperName(pProfileUserName,lpszFile); 01176 if (!gpszWall) { 01177 fRet = TRUE; 01178 goto SDW_Exit; 01179 } 01180 01181 /* 01182 * Retrieve the default settings from the registry. 01183 * 01184 * If tile is indicated, then normalize style to not include 01185 * FIT/STRETCH which are center-only styles. Likewise, if 01186 * we are centered, then normalize out the TILE bit. 01187 */ 01188 FastGetProfileIntsW(pProfileUserName, apsi); 01189 01190 gwWPStyle &= DTF_TILE; 01191 if (!(gwWPStyle & DTF_TILE)) { 01192 gwWPStyle = WallpaperStyle2 & DTF_STRETCH; 01193 } 01194 01195 /* 01196 * Load the wallpaper. This makes a callback to the client to 01197 * perform the bitmap-creation. 01198 */ 01199 01200 LoadWallpaper: 01201 01202 if (xxxLoadDesktopWallpaper(gpszWall) == FALSE) { 01203 gwWPStyle = 0; 01204 goto SDW_Exit; 01205 } 01206 01207 /* 01208 * If we have a palette, then we need to do the correct realization and 01209 * notification. 01210 */ 01211 if (ghpalWallpaper != NULL) { 01212 PWND pwndSend; 01213 01214 if (pwndShell) { 01215 pwndSend = pwndShell; 01216 } else { 01217 pwndSend = (pdesk ? pdesk->pDeskInfo->spwnd : NULL); 01218 } 01219 01220 /* 01221 * Update the desktop with the new bitmap. This cleans 01222 * out the system-palette so colors can be realized. 01223 */ 01224 GreRealizeDefaultPalette(gpDispInfo->hdcScreen, TRUE); 01225 01226 /* 01227 * Don't broadcast if system initialization is occuring. Otherwise 01228 * this gives the shell first-crack at realizing its colors 01229 * correctly. 01230 */ 01231 if (pwndSend) { 01232 HWND hwnd = HW(pwndSend); 01233 01234 ThreadLockAlways(pwndSend, &tl); 01235 xxxSendNotifyMessage(pwndSend, WM_PALETTECHANGED, (WPARAM)hwnd, 0); 01236 ThreadUnlock(&tl); 01237 } 01238 } 01239 01240 Metric_Change: 01241 if (fRet = GreExtGetObjectW(ghbmWallpaper, sizeof(bm), (PBITMAP)&bm)) { 01242 gsrcWallpaper.cx = bm.bmWidth; 01243 gsrcWallpaper.cy = bm.bmHeight; 01244 } 01245 // fall-through 01246 01247 SDW_Exit: 01248 01249 /* 01250 * Notify the shell-window that the wallpaper changed. 01251 */ 01252 if ((pwndShell != NULL) && 01253 ((hbmOld && !ghbmWallpaper) || (!hbmOld && ghbmWallpaper))) { 01254 01255 ThreadLockAlways(pwndShell, &tl); 01256 xxxSendNotifyMessage(pwndShell, 01257 WM_SHELLNOTIFY, 01258 SHELLNOTIFY_WALLPAPERCHANGED, 01259 (LPARAM)ghbmWallpaper); 01260 ThreadUnlock(&tl); 01261 } 01262 01263 return fRet; 01264 } 01265 01266 01267 /***************************************************************************\ 01268 * DesktopBuildPaint 01269 * 01270 * Draw the build information onto the desktop 01271 * 01272 * History: 01273 * 2/4/99 joejo - Bug 280256 01274 \***************************************************************************/ 01275 void DesktopBuildPaint( 01276 HDC hdc, 01277 PMONITOR pMonitor) 01278 { 01279 SIZE size; 01280 int imode; 01281 int x; 01282 int y; 01283 COLORREF oldColor; 01284 RECT rcText1 = {0,0,0,0}; 01285 01286 HFONT oldFont = NULL; 01287 01288 PWCHAR pwszT = wszProductName; 01289 01290 /* 01291 * Set up DC 01292 */ 01293 imode = GreSetBkMode(hdc, TRANSPARENT); 01294 01295 if (GreGetBrushColor(SYSHBR(BACKGROUND)) != 0x00ffffff) { 01296 oldColor = GreSetTextColor( hdc, RGB(255,255,255) ); 01297 } else { 01298 oldColor = GreSetTextColor( hdc, RGB(0,0,0) ); 01299 } 01300 01301 01302 /* 01303 * Print Windows 2000 name 01304 */ 01305 if (gpsi && gpsi->hCaptionFont) { 01306 oldFont = GreSelectFont(hdc, gpsi->hCaptionFont); 01307 } 01308 01309 if (gDrawVersionAlways) { 01310 pwszT = (wcslen(wszProductName) > wcslen(USER_SHARED_DATA->NtSystemRoot))?wszProductName:USER_SHARED_DATA->NtSystemRoot; 01311 } 01312 01313 GreGetTextExtentW( 01314 hdc, 01315 pwszT, 01316 wcslen(pwszT), 01317 &size, 01318 GGTE_WIN3_EXTENT); 01319 01320 x = pMonitor->rcWork.right - size.cx - 5; 01321 y = pMonitor->rcWork.bottom - 01322 ((gDrawVersionAlways? 3: 2) * size.cy) - 5; 01323 01324 rcText1.top = y; 01325 rcText1.bottom = rcText1.top + size.cy; 01326 rcText1.left = x; 01327 rcText1.right = rcText1.left + size.cx; 01328 01329 GreSetTextAlign(hdc, TA_RIGHT | TA_BOTTOM); 01330 01331 GreExtTextOutW( 01332 hdc, 01333 rcText1.right, 01334 rcText1.bottom, 01335 0, 01336 &rcText1, 01337 wszProductName, 01338 wcslen(wszProductName), 01339 (LPINT)NULL 01340 ); 01341 01342 01343 /* 01344 * Print Build Number 01345 */ 01346 if (oldFont != NULL && ghMenuFont != NULL ) { 01347 GreSelectFont(hdc, ghMenuFont); 01348 } 01349 01350 rcText1.top = rcText1.bottom + 1; 01351 rcText1.bottom = rcText1.top + size.cy; 01352 01353 GreExtTextOutW( 01354 hdc, 01355 rcText1.right, 01356 rcText1.bottom, 01357 0, 01358 &rcText1, 01359 wszProductBuild, 01360 wcslen(wszProductBuild), 01361 (LPINT)NULL 01362 ); 01363 01364 /* 01365 * If we are in CHK mode, draw the System Dir Path 01366 */ 01367 if (gDrawVersionAlways) { 01368 rcText1.top = rcText1.bottom + 1; 01369 rcText1.bottom = rcText1.top + size.cy; 01370 01371 GreExtTextOutW( 01372 hdc, 01373 rcText1.right, 01374 rcText1.bottom, 01375 0, 01376 &rcText1, 01377 USER_SHARED_DATA->NtSystemRoot, 01378 wcslen(USER_SHARED_DATA->NtSystemRoot), 01379 (LPINT)NULL 01380 ); 01381 } 01382 01383 if (oldFont) { 01384 GreSelectFont(hdc, oldFont); 01385 } 01386 01387 GreSetBkMode(hdc, imode); 01388 GreSetTextColor(hdc, oldColor); 01389 } 01390 01391 /***************************************************************************\ 01392 * xxxDesktopPaintCallback 01393 * 01394 * Draw the wallpaper or fill with the background brush. In debug, 01395 * also draw the build number on the top of each monitor. 01396 * 01397 * History: 01398 * 20-Sep-1996 adams Created. 01399 \***************************************************************************/ 01400 01401 BOOL 01402 xxxDesktopPaintCallback( 01403 PMONITOR pMonitor, 01404 HDC hdc, 01405 LPRECT lprcMonitorClip, 01406 LPARAM dwData) 01407 { 01408 BOOL f; 01409 PWND pwnd; 01410 01411 CheckLock(pMonitor); 01412 01413 pwnd = (PWND)dwData; 01414 01415 01416 if (**((PULONG *)&InitSafeBootMode)) { 01417 FillRect(hdc, lprcMonitorClip, ghbrBlack ); 01418 f = TRUE; 01419 } else { 01420 /* 01421 * if this is the disconnected desktop, skip the bitmap paint 01422 */ 01423 if (!gbDesktopLocked) { 01424 01425 /* 01426 * Paint the desktop with a color or the wallpaper. 01427 */ 01428 if (ghbmWallpaper) { 01429 f = xxxDrawWallpaper( 01430 pwnd, 01431 hdc, 01432 pMonitor, 01433 lprcMonitorClip); 01434 } else { 01435 FillRect(hdc, lprcMonitorClip, SYSHBR(DESKTOP)); 01436 f = TRUE; 01437 } 01438 } 01439 } 01440 01441 if (**((PULONG *)&InitSafeBootMode) 01442 || gDrawVersionAlways 01443 || gdwCanPaintDesktop) { 01444 static BOOL fInit = TRUE; 01445 SIZE size; 01446 int imode; 01447 COLORREF oldColor; 01448 HFONT oldFont = NULL; 01449 01450 01451 /* 01452 * Grab the stuff from the registry 01453 */ 01454 if (fInit) { 01455 if (**((PULONG *)&InitSafeBootMode)) { 01456 ServerLoadString( hModuleWin, STR_SAFEMODE, SafeModeStr, ARRAY_SIZE(SafeModeStr) ); 01457 SafeModeStrLen = wcslen(SafeModeStr); 01458 } 01459 GetVersionInfo(**((PULONG *)&InitSafeBootMode) == 0); 01460 fInit = FALSE; 01461 } 01462 01463 if (**((PULONG *)&InitSafeBootMode)) { 01464 if (gpsi != NULL && gpsi->hCaptionFont != NULL) { 01465 oldFont = GreSelectFont(hdc, gpsi->hCaptionFont); 01466 } 01467 01468 GreGetTextExtentW(hdc, wszT, wcslen(wszT), &size, GGTE_WIN3_EXTENT); 01469 imode = GreSetBkMode(hdc, TRANSPARENT); 01470 01471 oldColor = GreSetTextColor( hdc, RGB(255,255,255) ); 01472 01473 GreExtTextOutW( 01474 hdc, 01475 (pMonitor->rcWork.left + pMonitor->rcWork.right - size.cx) / 2, 01476 pMonitor->rcWork.top, 01477 0, 01478 (LPRECT)NULL, 01479 wszT, 01480 wcslen(wszT), 01481 (LPINT)NULL 01482 ); 01483 01484 GreGetTextExtentW(hdc, SafeModeStr, SafeModeStrLen, &size, GGTE_WIN3_EXTENT); 01485 01486 GreExtTextOutW( 01487 hdc, 01488 pMonitor->rcWork.left, 01489 pMonitor->rcWork.top, 01490 0, 01491 (LPRECT)NULL, 01492 SafeModeStr, 01493 SafeModeStrLen, 01494 (LPINT)NULL 01495 ); 01496 01497 GreExtTextOutW( 01498 hdc, 01499 pMonitor->rcWork.right - size.cx, 01500 pMonitor->rcWork.top, 01501 0, 01502 (LPRECT)NULL, 01503 SafeModeStr, 01504 SafeModeStrLen, 01505 (LPINT)NULL 01506 ); 01507 01508 GreExtTextOutW( 01509 hdc, 01510 pMonitor->rcWork.right - size.cx, 01511 pMonitor->rcWork.bottom - gpsi->tmSysFont.tmHeight, 01512 0, 01513 (LPRECT)NULL, 01514 SafeModeStr, 01515 SafeModeStrLen, 01516 (LPINT)NULL 01517 ); 01518 01519 GreExtTextOutW( 01520 hdc, 01521 pMonitor->rcWork.left, 01522 pMonitor->rcWork.bottom - gpsi->tmSysFont.tmHeight, 01523 0, 01524 (LPRECT)NULL, 01525 SafeModeStr, 01526 SafeModeStrLen, 01527 (LPINT)NULL 01528 ); 01529 01530 GreSetBkMode(hdc, imode); 01531 GreSetTextColor(hdc, oldColor); 01532 01533 if (oldFont) { 01534 GreSelectFont(hdc, oldFont); 01535 } 01536 } else { 01537 DesktopBuildPaint(hdc, pMonitor); 01538 } 01539 } 01540 01541 return f; 01542 } 01543 01544 01545 01546 /***************************************************************************\ 01547 * xxxInvalidateDesktopOnPaletteChange 01548 * 01549 * Invalidates the shell window and uncovered areas of the desktop 01550 * when the palette changes. 01551 * 01552 * History: 01553 * 28-Apr-1997 adams Created. 01554 \***************************************************************************/ 01555 01556 void 01557 xxxInvalidateDesktopOnPaletteChange(PWND pwnd) 01558 { 01559 PDESKTOP pdesk; 01560 PWND pwndShell; 01561 TL tlpwndShell; 01562 RECT rc; 01563 BOOL fRedrawDesktop; 01564 01565 CheckLock(pwnd); 01566 01567 /* 01568 * Invalidate the shell window. 01569 */ 01570 pdesk = PtiCurrent()->rpdesk; 01571 pwndShell = (pdesk) ? pdesk->pDeskInfo->spwndShell : NULL; 01572 if (!pwndShell) { 01573 fRedrawDesktop = TRUE; 01574 rc = gpsi->rcScreen; 01575 } else { 01576 ThreadLockAlways(pwndShell, &tlpwndShell); 01577 xxxRedrawWindow( 01578 pwndShell, 01579 NULL, 01580 NULL, 01581 RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); 01582 01583 /* 01584 * The shell window may not cover all of the desktop. 01585 * Invalidate the part of the desktop wallpaper it 01586 * doesn't sit over. 01587 */ 01588 fRedrawDesktop = SubtractRect(&rc, &pwnd->rcWindow, &pwndShell->rcWindow); 01589 ThreadUnlock(&tlpwndShell); 01590 } 01591 01592 /* 01593 * Invalidate the desktop window. 01594 */ 01595 if (fRedrawDesktop) { 01596 xxxRedrawWindow( 01597 pwnd, 01598 &rc, 01599 NULL, 01600 RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); 01601 } 01602 } 01603 01604 /***************************************************************************\ 01605 * xxxInternalPaintDesktop 01606 * 01607 * If fPaint is TRUE, enumerate the monitors to paint the desktop. 01608 * Otherwise, it selects the bitmap palette into the DC to select 01609 * its colors into the hardware palette. 01610 * 01611 * History: 01612 * 29-Jul-1991 MikeKe From win31 01613 \***************************************************************************/ 01614 01615 BOOL xxxInternalPaintDesktop( 01616 PWND pwnd, 01617 HDC hdc, 01618 BOOL fPaint) 01619 { 01620 BOOL fRet; 01621 01622 CheckLock(pwnd); 01623 01624 if (fPaint) { 01625 RECT rcOrg, rcT; 01626 POINT pt; 01627 01628 /* 01629 * For compatiblity purposes the DC origin of desktop windows 01630 * is set to the primary monitor, i.e. (0,0). Since we may get 01631 * either desktop or non-desktop DCs here, temporarily reset 01632 * the hdc origin to (0,0). 01633 */ 01634 GreGetDCOrgEx(hdc, &pt, &rcOrg); 01635 CopyRect(&rcT, &rcOrg); 01636 OffsetRect(&rcT, -rcT.left, -rcT.top); 01637 GreSetDCOrg(hdc, rcT.left, rcT.top, (PRECTL)&rcT); 01638 01639 fRet = xxxEnumDisplayMonitors( 01640 hdc, 01641 NULL, 01642 (MONITORENUMPROC) xxxDesktopPaintCallback, 01643 (LPARAM)pwnd, 01644 TRUE); 01645 01646 /* 01647 * Reset the DC origin back. 01648 */ 01649 GreSetDCOrg(hdc, rcOrg.left, rcOrg.top, (PRECTL)&rcOrg); 01650 01651 } else if ( ghpalWallpaper && 01652 GetPrimaryMonitor()->dwMONFlags & MONF_PALETTEDISPLAY) { 01653 /* 01654 * Select in the palette if one exists. 01655 */ 01656 HPALETTE hpalT; 01657 int i; 01658 01659 hpalT = _SelectPalette(hdc, ghpalWallpaper, FALSE); 01660 i = xxxRealizePalette(hdc); 01661 _SelectPalette(hdc, hpalT, FALSE); 01662 01663 if (i > 0) { 01664 xxxInvalidateDesktopOnPaletteChange(pwnd); 01665 } 01666 fRet = TRUE; 01667 } 01668 01669 return fRet; 01670 } 01671

Generated on Sat May 15 19:39:47 2004 for test by doxygen 1.3.7