test: dtbitmap.c Source File

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