/**Module*Header**\ * Module Name: palette.cxx * Palette processing functions * Adapted from tk.c * Copyright (c) 1996 Microsoft Corporation \**/ #include #include #include #include #include #include "ssintrnl.hxx" #include "palette.hxx" #if(WINVER < 0x0400) // Ordinarily not defined for versions before 4.00. #define COLOR_3DDKSHADOW 21 #define COLOR_3DLIGHT 22 #define COLOR_INFOTEXT 23 #define COLOR_INFOBK 24 #endif #define TKASSERT(x) SS_ASSERT( x, "palette processing failure\n" ) /**/ // Fixed palette support. #define BLACK PALETTERGB(0,0,0) #define WHITE PALETTERGB(255,255,255) #define MAX_STATIC_COLORS (COLOR_INFOBK - COLOR_SCROLLBAR + 1) static int gNumStaticColors = MAX_STATIC_COLORS; // TRUE if static system color settings have been replaced with B&W settings. // TRUE if original static colors saved static BOOL tkStaticColorsSaved = FALSE; // saved system static colors (initialize with default colors) static COLORREF gacrSave[MAX_STATIC_COLORS]; // new B&W system static colors static COLORREF gacrBlackAndWhite[] = { WHITE, // COLOR_SCROLLBAR BLACK, // COLOR_BACKGROUND BLACK, // COLOR_ACTIVECAPTION WHITE, // COLOR_INACTIVECAPTION WHITE, // COLOR_MENU WHITE, // COLOR_WINDOW BLACK, // COLOR_WINDOWFRAME BLACK, // COLOR_MENUTEXT BLACK, // COLOR_WINDOWTEXT WHITE, // COLOR_CAPTIONTEXT WHITE, // COLOR_ACTIVEBORDER WHITE, // COLOR_INACTIVEBORDER WHITE, // COLOR_APPWORKSPACE BLACK, // COLOR_HIGHLIGHT WHITE, // COLOR_HIGHLIGHTTEXT WHITE, // COLOR_BTNFACE BLACK, // COLOR_BTNSHADOW BLACK, // COLOR_GRAYTEXT BLACK, // COLOR_BTNTEXT BLACK, // COLOR_INACTIVECAPTIONTEXT BLACK, // COLOR_BTNHIGHLIGHT BLACK, // COLOR_3DDKSHADOW WHITE, // COLOR_3DLIGHT BLACK, // COLOR_INFOTEXT WHITE // COLOR_INFOBK }; static INT gaiStaticIndex[] = { COLOR_SCROLLBAR , COLOR_BACKGROUND , COLOR_ACTIVECAPTION , COLOR_INACTIVECAPTION , COLOR_MENU , COLOR_WINDOW , COLOR_WINDOWFRAME , COLOR_MENUTEXT , COLOR_WINDOWTEXT , COLOR_CAPTIONTEXT , COLOR_ACTIVEBORDER , COLOR_INACTIVEBORDER , COLOR_APPWORKSPACE , COLOR_HIGHLIGHT , COLOR_HIGHLIGHTTEXT , COLOR_BTNFACE , COLOR_BTNSHADOW , COLOR_GRAYTEXT , COLOR_BTNTEXT , COLOR_INACTIVECAPTIONTEXT, COLOR_BTNHIGHLIGHT , COLOR_3DDKSHADOW , COLOR_3DLIGHT , COLOR_INFOTEXT , COLOR_INFOBK }; #define RESTORE_FROM_REGISTRY 1 #if RESTORE_FROM_REGISTRY // Registry names for the system colors. static CHAR *gaszSysClrNames[] = { "Scrollbar", // COLOR_SCROLLBAR 0 "Background", // COLOR_BACKGROUND 1 (also COLOR_DESKTOP) "ActiveTitle", // COLOR_ACTIVECAPTION 2 "InactiveTitle", // COLOR_INACTIVECAPTION 3 "Menu", // COLOR_MENU 4 "Window", // COLOR_WINDOW 5 "WindowFrame", // COLOR_WINDOWFRAME 6 "MenuText", // COLOR_MENUTEXT 7 "WindowText", // COLOR_WINDOWTEXT 8 "TitleText", // COLOR_CAPTIONTEXT 9 "ActiveBorder", // COLOR_ACTIVEBORDER 10 "InactiveBorder", // COLOR_INACTIVEBORDER 11 "AppWorkspace", // COLOR_APPWORKSPACE 12 "Hilight", // COLOR_HIGHLIGHT 13 "HilightText", // COLOR_HIGHLIGHTTEXT 14 "ButtonFace", // COLOR_BTNFACE 15 (also COLOR_3DFACE) "ButtonShadow", // COLOR_BTNSHADOW 16 (also COLOR_3DSHADOW) "GrayText", // COLOR_GRAYTEXT 17 "ButtonText", // COLOR_BTNTEXT 18 "InactiveTitleText", // COLOR_INACTIVECAPTIONTEXT 19 "ButtonHilight", // COLOR_BTNHIGHLIGHT 20 (also COLOR_3DHILIGHT) "ButtonDkShadow", // COLOR_3DDKSHADOW 21 "ButtonLight", // COLOR_3DLIGHT 22 "InfoText", // COLOR_INFOTEXT 23 "InfoWindow" // COLOR_INFOBK 24 }; static BOOL GetRegistrySysColors(COLORREF *, int); #endif unsigned char ss_ComponentFromIndex(int i, int nbits, int shift ); static int ss_PixelFormatDescriptorFromDc( HDC hdc, PIXELFORMATDESCRIPTOR *Pfd ); /**/ #if RESTORE_FROM_REGISTRY /**Public*Routine**\ * GetRegistrySysColors * Reads the Control Panel's color settings from the registry and stores * those values in pcr. If we fail to get any value, then the corresponding * entry in pcr is not modified. * History: * 12-Apr-1995 -by- Gilman Wong [gilmanw] * Wrote it. \**/ static BOOL GetRegistrySysColors(COLORREF *pcr, int nColors) { BOOL bRet = FALSE; long lRet; HKEY hkSysColors = (HKEY) NULL; int i; DWORD dwDataType; char achColor[64]; DWORD cjColor; TKASSERT(nColors <= gNumStaticColors); // Open the key for the system color settings. lRet = RegOpenKeyExA(HKEY_CURRENT_USER, "Control Panel\\Colors", 0, KEY_QUERY_VALUE, &hkSysColors); if ( lRet != ERROR_SUCCESS ) { goto GetRegistrySysColors_exit; } // Read each system color value. The names are stored in the global // array of char *, gaszSysClrNames. for (i = 0; i < nColors; i++) { cjColor = sizeof(achColor); lRet = RegQueryValueExA(hkSysColors, (LPSTR) gaszSysClrNames[i], (LPDWORD) NULL, &dwDataType, (LPBYTE) achColor, &cjColor); TKASSERT(lRet != ERROR_MORE_DATA); if ( lRet == ERROR_SUCCESS && dwDataType == REG_SZ ) { DWORD r, g, b; sscanf(achColor, "%ld %ld %ld", &r, &g, &b); pcr[i] = RGB(r, g, b); } } bRet = TRUE; GetRegistrySysColors_exit: if (hkSysColors) RegCloseKey(hkSysColors); return bRet; } #endif /**Public*Routine**\ * GrabStaticEntries * Support routine for Realize to manage the static system color * usage. * This function will save the current static system color usage state. * It will fail if: * 1. TK is not in "sys color in use state but system palette is in * SYSPAL_NOSTATIC mode. This means that another app still possesses * the static system colors. If this happens * Side effect: * If system colors are changed, then WM_SYSCOLORCHANGE message is * broadcast to all top level windows. * Returns: * TRUE if successful, FALSE otherwise (see above). * History: * 26-Apr-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**/ BOOL SS_PAL::GrabStaticEntries() { int i; BOOL bRet = FALSE; // Do nothing if sys colors already in use. if ( !bSystemColorsInUse ) { // Take possession only if no other app has the static colors. // How can we tell? If the return from SetSystemPaletteUse is // SYSPAL_STATIC, then no other app has the statics. If it is // SYSPAL_NOSTATIC, someone else has them and we must fail. // SetSystemPaletteUse is properly synchronized internally // so that it is atomic. // Because we are relying on SetSystemPaletteUse to synchronize TK, // it is important to observe the following order for grabbing and // releasing: // Grab call SetSystemPaletteUse and check for SYSPAL_STATIC // save sys color settings // set new sys color settings // Release restore sys color settings // call SetSystemPaletteUse //mf: ! potential pitfall here, if a 'bad' app has not released the static // colors on deactivation. if ( SetSystemPaletteUse( hdc, SYSPAL_NOSTATIC ) == SYSPAL_STATIC ) { // Save current sys color settings. for (i = COLOR_SCROLLBAR; i <= COLOR_BTNHIGHLIGHT; i++) gacrSave[i - COLOR_SCROLLBAR] = GetSysColor(i); bSystemColorsInUse = TRUE; // Set b&w sys color settings. SetSysColors(gNumStaticColors, gaiStaticIndex, gacrBlackAndWhite); // Inform all other top-level windows of the system color change. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); bRet = TRUE; } else { // handle case where can't get sys colors } } else bRet = TRUE; return bRet; } /**Public*Routine**\ * ReleaseStaticEntries * Support routine for Realize to manage the static system color * usage. * This function will reset the current static system color usage state. * It will fail if: * 1. TK is not in a "sys colors in use" state. If we are in this case, * then the static system colors do not need to be released. * Side effect: * If system colors are changed, then WM_SYSCOLORCHANGE message is * broadcast to all top level windows. * Returns: * TRUE if successful, FALSE otherwise (see above). * History: * 21-Jul-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**/ BOOL SS_PAL::ReleaseStaticEntries() { BOOL bRet = FALSE; // Do nothing if sys colors not in use. if ( bSystemColorsInUse ) { #if RESTORE_FROM_REGISTRY // Replace saved system colors with registry values. We do it now // rather than earlier because someone may have changed registry while // TK app was running in the foreground (very unlikely, but it could // happen). // Also, we still try to save current setting in GrabStaticEntries so // that if for some reason we fail to grab one or more of the colors // from the registry, we can still fall back on what we grabbed via // GetSysColors (even though there is a chance its the wrong color). GetRegistrySysColors(gacrSave, gNumStaticColors); #endif // Do this now, since SetSysColors() generates WM_SYSCOLORCHANGE, // which can cause this routine to be re-entered // back to here. bSystemColorsInUse = FALSE; // Return the system palette to SYSPAL_STATIC. SetSystemPaletteUse( hdc, SYSPAL_STATIC ); // Restore the saved system color settings. SetSysColors(gNumStaticColors, gaiStaticIndex, gacrSave); // Inform all other top-level windows of the system color change. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); // Reset the "sys colors in use" state and return success. bSystemColorsInUse = FALSE; bRet = TRUE; } return bRet; } // Gamma correction factor * 10 #define GAMMA_CORRECTION 14 // Maximum color distance with 8-bit components #define MAX_COL_DIST (3*256*256L) // Number of static colors #define STATIC_COLORS 20 // Flags used when matching colors #define EXACT_MATCH 1 #define COLOR_USED 1 // Conversion tables for n bits to eight bits #if GAMMA_CORRECTION == 10 // These tables are corrected for a gamma of 1.0 static unsigned char abThreeToEight[8] = { 0, 0111 >> 1, 0222 >> 1, 0333 >> 1, 0444 >> 1, 0555 >> 1, 0666 >> 1, 0377 }; static unsigned char abTwoToEight[4] = { 0, 0x55, 0xaa, 0xff }; static unsigned char abOneToEight[2] = { 0, 255 }; #else // These tables are corrected for a gamma of 1.4 static unsigned char abThreeToEight[8] = { 0, 63, 104, 139, 171, 200, 229, 255 }; static unsigned char abTwoToEight[4] = { 0, 116, 191, 255 }; static unsigned char abOneToEight[2] = { 0, 255 }; #endif // Table which indicates which colors in a 3-3-2 palette should be // replaced with the system default colors #if GAMMA_CORRECTION == 10 static int aiDefaultOverride[STATIC_COLORS] = { 0, 4, 32, 36, 128, 132, 160, 173, 181, 245, 247, 164, 156, 7, 56, 63, 192, 199, 248, 255 }; #else static int aiDefaultOverride[STATIC_COLORS] = { 0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91, 7, 56, 63, 192, 199, 248, 255 }; #endif unsigned char ss_ComponentFromIndex(int i, int nbits, int shift) { unsigned char val; TKASSERT(nbits >= 1 && nbits <= 3); val = i >> shift; switch (nbits) { case 1: return abOneToEight[val & 1]; case 2: return abTwoToEight[val & 3]; case 3: return abThreeToEight[val & 7]; } return 0; } // System default colors static PALETTEENTRY apeDefaultPalEntry[STATIC_COLORS] = { { 0, 0, 0, 0 }, { 0x80,0, 0, 0 }, { 0, 0x80,0, 0 }, { 0x80,0x80,0, 0 }, { 0, 0, 0x80, 0 }, { 0x80,0, 0x80, 0 }, { 0, 0x80,0x80, 0 }, { 0xC0,0xC0,0xC0, 0 }, { 192, 220, 192, 0 }, { 166, 202, 240, 0 }, { 255, 251, 240, 0 }, { 160, 160, 164, 0 }, { 0x80,0x80,0x80, 0 }, { 0xFF,0, 0, 0 }, { 0, 0xFF,0, 0 }, { 0xFF,0xFF,0, 0 }, { 0, 0, 0xFF, 0 }, { 0xFF,0, 0xFF, 0 }, { 0, 0xFF,0xFF, 0 }, { 0xFF,0xFF,0xFF, 0 } }; /**Public*Routine**\ * UpdateStaticMapping * Computes the best match between the current system static colors * and a 3-3-2 palette * History: * Tue Aug 01 18:18:12 1995 -by- Drew Bliss [drewb] * Created \**/ static void UpdateStaticMapping(PALETTEENTRY *pe332Palette) { HPALETTE hpalStock; int iStatic, i332; int iMinDist, iDist; int iDelta; int iMinEntry; PALETTEENTRY *peStatic, *pe332; hpalStock = (HPALETTE) GetStockObject(DEFAULT_PALETTE); // The system should always have one of these TKASSERT(hpalStock != NULL); // Make sure there's the correct number of entries TKASSERT(GetPaletteEntries(hpalStock, 0, 0, NULL) == STATIC_COLORS); // Get the current static colors GetPaletteEntries(hpalStock, 0, STATIC_COLORS, apeDefaultPalEntry); // Zero the flags in the static colors because they are used later peStatic = apeDefaultPalEntry; for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++) { peStatic->peFlags = 0; peStatic++; } // Zero the flags in the incoming palette because they are used later pe332 = pe332Palette; for (i332 = 0; i332 < 256; i332++) { pe332->peFlags = 0; pe332++; } // Try to match each static color exactly // This saves time by avoiding the least-squares match for each // exact match peStatic = apeDefaultPalEntry; for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++) { pe332 = pe332Palette; for (i332 = 0; i332 < 256; i332++) { if (peStatic->peRed == pe332->peRed && peStatic->peGreen == pe332->peGreen && peStatic->peBlue == pe332->peBlue) { TKASSERT(pe332->peFlags != COLOR_USED); peStatic->peFlags = EXACT_MATCH; pe332->peFlags = COLOR_USED; aiDefaultOverride[iStatic] = i332; break; } pe332++; } peStatic++; } // Match each static color as closely as possible to an entry // in the 332 palette by minimized the square of the distance peStatic = apeDefaultPalEntry; for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++) { // Skip colors already matched exactly if (peStatic->peFlags == EXACT_MATCH) { peStatic++; continue; } iMinDist = MAX_COL_DIST+1; #if DBG iMinEntry = -1; #endif pe332 = pe332Palette; for (i332 = 0; i332 < 256; i332++) { // Skip colors already used if (pe332->peFlags == COLOR_USED) { pe332++; continue; } // Compute Euclidean distance squared iDelta = pe332->peRed-peStatic->peRed; iDist = iDelta*iDelta; iDelta = pe332->peGreen-peStatic->peGreen; iDist += iDelta*iDelta; iDelta = pe332->peBlue-peStatic->peBlue; iDist += iDelta*iDelta; if (iDist < iMinDist) { iMinDist = iDist; iMinEntry = i332; } pe332++; } TKASSERT(iMinEntry != -1); // Remember the best match aiDefaultOverride[iStatic] = iMinEntry; pe332Palette[iMinEntry].peFlags = COLOR_USED; peStatic++; } // Zero the flags in the static colors because they may have been // set. We want them to be zero so the colors can be remapped peStatic = apeDefaultPalEntry; for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++) { peStatic->peFlags = 0; peStatic++; } // Reset the 332 flags because we may have set them pe332 = pe332Palette; for (i332 = 0; i332 < 256; i332++) { pe332->peFlags = PC_NOCOLLAPSE; pe332++; } } /**Public*Routine**\ * FlushPalette * Because of Win 3.1 compatibility, GDI palette mapping always starts * at zero and stops at the first exact match. So if there are duplicates, * the higher colors aren't mapped to--which is often a problem if we * are trying to make to any of the upper 10 static colors. To work around * this, we flush the palette to all black. \**/ void SS_PAL::Flush() { LOGPALETTE *pPal; HPALETTE hpalBlack, hpalOld; int i; if( nEntries == 256 ) { pPal = (LOGPALETTE *) LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, sizeof(LOGPALETTE) + nEntries * sizeof(PALETTEENTRY)); if (pPal) { pPal->palVersion = 0x300; pPal->palNumEntries = (WORD)nEntries; // Mark everything PC_NOCOLLAPSE and PC_RESERVED to force every // thing into the palette. Colors are already black because // we zero initialized during memory allocation. for (i = 0; i < nEntries; i++) { pPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE | PC_RESERVED; } hpalBlack = CreatePalette(pPal); LocalFree(pPal); hpalOld = SelectPalette(hdc, hpalBlack, FALSE); RealizePalette(hdc); SelectPalette(hdc, hpalOld, FALSE); DeleteObject(hpalBlack); } } } /**Public*Routine**\ * Realize * Select the given palette in background or foreground mode (as specified * by the bForceBackground flag), and realize the palette. * If static system color usage is set, the system colors are replaced. * History: * 26-Apr-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**/ //mf: ! this grabbing of colors n stuff should only be done by the top // level window - ? but what if it's not a GL window ? long SS_PAL::Realize( HWND hwndArg, HDC hdcArg, BOOL bForceBackground ) { // cache: hwnd = hwndArg; hdc = hdcArg; if( bTakeOver ) { // Easy case SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); SelectPalette(hdc, hPal, bForceBackground ); RealizePalette(hdc); return 1; } // Else general purpose 'tk' method if( bFlush ) { Flush(); bFlush = FALSE; } return Realize( bForceBackground ); } long SS_PAL::Realize( BOOL bForceBackground ) { long Result = -1; BOOL bHaveSysPal = TRUE; SS_DBGLEVEL2( SS_LEVEL_INFO, "SS_PAL::Realize: %d for %d\n", bForceBackground, hwnd ); // If static system color usage is set, prepare to take over the // system palette. if( bUseStatic ) { // If foreground, take over the static colors. If background, release // the static colors. if ( !bForceBackground ) { // If GrabStaticEntries succeeds, then it is OK to take over the // static colors. If not bHaveSysPal = GrabStaticEntries(); } else { // If we are currently using the system colors (bSystemColorsInUse) // and Realize was called with bForceBackground set, we // are being deactivated and must release the static system colors. ReleaseStaticEntries(); } // Rerealize the palette. // If set to TRUE, bForceBackground will force the palette to be // realized as a background palette, regardless of focus. This // will happen anyway if the TK window does not have the keyboard focus. if ( (bForceBackground || bHaveSysPal) && UnrealizeObject( hPal ) && NULL != SelectPalette( hdc, hPal, bForceBackground ) ) { Result = RealizePalette( hdc ); } //mf: ?? klugey fix for rude apps // If some rude app still has the system colors and we're in the // foreground, make the best of it. if( !bForceBackground && !bHaveSysPal ) { if( UnrealizeObject( hPal ) && NULL != SelectPalette( hdc, hPal, TRUE ) ) { Result = RealizePalette( hdc ); } } } else { if ( NULL != SelectPalette( hdc, hPal, FALSE ) ) { Result = RealizePalette( hdc ); } } return( Result ); } /**Public*Routine**\ * SS_PAL constructor * This creates the palette, but does not select or realize it \**/ SS_PAL::SS_PAL( HDC hdcArg, PIXELFORMATDESCRIPTOR *ppfd, BOOL bTakeOverPalette ) { hwnd = 0; hPal = 0; bUseStatic = FALSE; bSystemColorsInUse = FALSE; pfd = *ppfd; // this is for palette purposes only (other fields may not apply) hdc = hdcArg; bTakeOver = bTakeOverPalette; // mf: for now, when this is set, it means // the screen saver is running in full screen mode - implying that // interaction with other apps not necessary if( bTakeOver ) { //mf: !!! bFlush should be per-window, not per SS_PAL !! //mf: hmmm, not so sure about that... bFlush = FALSE; bUseStatic = TRUE; } else { bFlush = TRUE; bUseStatic = ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE; } if( bUseStatic ) // save current static palette usage so we can restore it uiOldStaticUse = GetSystemPaletteUse( hdc ); paletteManageProc = NullPaletteManageProc; // Now create the palette and return hPal = MakeRGBPalette(); SS_ASSERT( hPal, "SS_PAL constructor failure\n" ); } /**Public*Routine**\ * SS_PAL destructor \**/ SS_PAL::~SS_PAL() { if( bUseStatic ) { if( uiOldStaticUse ) //mf: ! make sure hdc is valid !!! SetSystemPaletteUse(hdc, uiOldStaticUse); PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); } if( hPal ) { SelectPalette( hdc, (HPALETTE) GetStockObject(DEFAULT_PALETTE), TRUE ); DeleteObject( hPal ); } } /**Public*Routine**\ * ReCreateRGBPalette \**/ void SS_PAL::ReCreateRGBPalette() { if( bTakeOver ) return; HPALETTE hPalTmp = hPal; hPal = MakeRGBPalette(); if( hPal ) { DeleteObject( hPalTmp ); bFlush = TRUE; } } /**Public*Routine**\ * MakeRGBPalette * Creates an HPALETTE with values required for a logical rgb palette. * If bUseStatic is TRUE, the static system * colors will be overridden. Otherwise, the PALETTEENTRY array will be * fixed up to contain the default static system colors. \**/ HPALETTE SS_PAL::MakeRGBPalette() { LOGPALETTE *pPal; HPALETTE hpal; int count, i; PIXELFORMATDESCRIPTOR *ppfd = &pfd; count = 1 << ppfd->cColorBits; nEntries = count; pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) + count * sizeof(PALETTEENTRY)); if( !pPal ) return (HPALETTE) 0; pPal->palVersion = 0x300; pPal->palNumEntries = (WORD)count; PALETTEENTRY *pEntry = pPal->palPalEntry; for ( i = 0; i < count ; i++, pEntry++ ) { pEntry->peRed = ss_ComponentFromIndex(i, ppfd->cRedBits, ppfd->cRedShift); pEntry->peGreen = ss_ComponentFromIndex(i, ppfd->cGreenBits, ppfd->cGreenShift); pEntry->peBlue = ss_ComponentFromIndex(i, ppfd->cBlueBits, ppfd->cBlueShift); pEntry->peFlags = PC_NOCOLLAPSE; } if( count == 256 ) { // If app set static system color usage for fixed palette support, // setup to take over the static colors. Otherwise, fixup the // static system colors. if ( bUseStatic ) { // Black and white already exist as the only remaining static // colors. Let those remap. All others should be put into // the palette (i.e., set PC_NOCOLLAPSE). pPal->palPalEntry[0].peFlags = 0; pPal->palPalEntry[255].peFlags = 0; } else { // The defaultOverride array is computed assuming a 332 // palette where red has zero shift, etc. if ( (3 == ppfd->cRedBits) && (0 == ppfd->cRedShift) && (3 == ppfd->cGreenBits) && (3 == ppfd->cGreenShift) && (2 == ppfd->cBlueBits) && (6 == ppfd->cBlueShift) ) { pEntry = pPal->palPalEntry; UpdateStaticMapping( pEntry ); for ( i = 0 ; i < STATIC_COLORS ; i++) { pEntry[aiDefaultOverride[i]] = apeDefaultPalEntry[i]; } } } } hpal = CreatePalette(pPal); LocalFree(pPal); return hpal; }