105b261ecSmrg/*
205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
305b261ecSmrg *
405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining
505b261ecSmrg * a copy of this software and associated documentation files (the
605b261ecSmrg *"Software"), to deal in the Software without restriction, including
705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish,
805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to
905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to
1005b261ecSmrg *the following conditions:
1105b261ecSmrg *
1205b261ecSmrg *The above copyright notice and this permission notice shall be
1305b261ecSmrg *included in all copies or substantial portions of the Software.
1405b261ecSmrg *
1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2205b261ecSmrg *
2305b261ecSmrg *Except as contained in this notice, the name of the XFree86 Project
2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use
2505b261ecSmrg *or other dealings in this Software without prior written authorization
2605b261ecSmrg *from the XFree86 Project.
2705b261ecSmrg *
2805b261ecSmrg * Authors:	Dakshinamurthy Karra
2905b261ecSmrg *		Suhaib M Siddiqi
3005b261ecSmrg *		Peter Busch
3105b261ecSmrg *		Harold L Hunt II
3205b261ecSmrg */
3305b261ecSmrg
3405b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H
3505b261ecSmrg#include <xwin-config.h>
3605b261ecSmrg#endif
3705b261ecSmrg#include "win.h"
3805b261ecSmrg
3905b261ecSmrg/*
4005b261ecSmrg * Local prototypes
4105b261ecSmrg */
4205b261ecSmrg
4305b261ecSmrgstatic int
4435c4bbdfSmrg winListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps);
4505b261ecSmrg
4605b261ecSmrgstatic void
4735c4bbdfSmrg winStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs);
4805b261ecSmrg
4905b261ecSmrgstatic void
5035c4bbdfSmrg winInstallColormap(ColormapPtr pmap);
5105b261ecSmrg
5205b261ecSmrgstatic void
5335c4bbdfSmrg winUninstallColormap(ColormapPtr pmap);
5405b261ecSmrg
5505b261ecSmrgstatic void
5635c4bbdfSmrg
5735c4bbdfSmrgwinResolveColor(unsigned short *pred,
5835c4bbdfSmrg                unsigned short *pgreen,
5935c4bbdfSmrg                unsigned short *pblue, VisualPtr pVisual);
6005b261ecSmrg
6105b261ecSmrgstatic Bool
6235c4bbdfSmrg winCreateColormap(ColormapPtr pmap);
6305b261ecSmrg
6405b261ecSmrgstatic void
6535c4bbdfSmrg winDestroyColormap(ColormapPtr pmap);
6605b261ecSmrg
6705b261ecSmrgstatic Bool
6835c4bbdfSmrg winGetPaletteDIB(ScreenPtr pScreen, ColormapPtr pcmap);
6905b261ecSmrg
7005b261ecSmrgstatic Bool
7135c4bbdfSmrg winGetPaletteDD(ScreenPtr pScreen, ColormapPtr pcmap);
7205b261ecSmrg
7305b261ecSmrg/*
7405b261ecSmrg * Set screen functions for colormaps
7505b261ecSmrg */
7605b261ecSmrg
7705b261ecSmrgvoid
7835c4bbdfSmrgwinSetColormapFunctions(ScreenPtr pScreen)
7905b261ecSmrg{
8035c4bbdfSmrg    pScreen->CreateColormap = winCreateColormap;
8135c4bbdfSmrg    pScreen->DestroyColormap = winDestroyColormap;
8235c4bbdfSmrg    pScreen->InstallColormap = winInstallColormap;
8335c4bbdfSmrg    pScreen->UninstallColormap = winUninstallColormap;
8435c4bbdfSmrg    pScreen->ListInstalledColormaps = winListInstalledColormaps;
8535c4bbdfSmrg    pScreen->StoreColors = winStoreColors;
8635c4bbdfSmrg    pScreen->ResolveColor = winResolveColor;
8705b261ecSmrg}
8805b261ecSmrg
8905b261ecSmrg/* See Porting Layer Definition - p. 30 */
9005b261ecSmrg/*
9105b261ecSmrg * Walk the list of installed colormaps, filling the pmaps list
9205b261ecSmrg * with the resource ids of the installed maps, and return
9305b261ecSmrg * a count of the total number of installed maps.
9405b261ecSmrg */
9505b261ecSmrgstatic int
9635c4bbdfSmrgwinListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps)
9705b261ecSmrg{
9835c4bbdfSmrg    winScreenPriv(pScreen);
9935c4bbdfSmrg
10035c4bbdfSmrg    /*
10135c4bbdfSmrg     * There will only be one installed colormap, so we only need
10235c4bbdfSmrg     * to return one id, and the count of installed maps will always
10335c4bbdfSmrg     * be one.
10435c4bbdfSmrg     */
10535c4bbdfSmrg    *pmaps = pScreenPriv->pcmapInstalled->mid;
10635c4bbdfSmrg    return 1;
10705b261ecSmrg}
10805b261ecSmrg
10905b261ecSmrg/* See Porting Layer Definition - p. 30 */
11005b261ecSmrg/* See Programming Windows - p. 663 */
11105b261ecSmrgstatic void
11235c4bbdfSmrgwinInstallColormap(ColormapPtr pColormap)
11305b261ecSmrg{
11435c4bbdfSmrg    ScreenPtr pScreen = pColormap->pScreen;
11535c4bbdfSmrg
11635c4bbdfSmrg    winScreenPriv(pScreen);
11735c4bbdfSmrg    ColormapPtr oldpmap = pScreenPriv->pcmapInstalled;
11805b261ecSmrg
11905b261ecSmrg#if CYGDEBUG
12035c4bbdfSmrg    winDebug("winInstallColormap\n");
12105b261ecSmrg#endif
12235c4bbdfSmrg
12335c4bbdfSmrg    /* Did the colormap actually change? */
12435c4bbdfSmrg    if (pColormap != oldpmap) {
12505b261ecSmrg#if CYGDEBUG
12635c4bbdfSmrg        winDebug("winInstallColormap - Colormap has changed, attempt "
12735c4bbdfSmrg                 "to install.\n");
12805b261ecSmrg#endif
12935c4bbdfSmrg
13035c4bbdfSmrg        /* Was there a previous colormap? */
13135c4bbdfSmrg        if (oldpmap != (ColormapPtr) None) {
13235c4bbdfSmrg            /* There was a previous colormap; tell clients it is gone */
13335c4bbdfSmrg            WalkTree(pColormap->pScreen, TellLostMap, (char *) &oldpmap->mid);
13435c4bbdfSmrg        }
13535c4bbdfSmrg
13635c4bbdfSmrg        /* Install new colormap */
13735c4bbdfSmrg        pScreenPriv->pcmapInstalled = pColormap;
13835c4bbdfSmrg        WalkTree(pColormap->pScreen, TellGainedMap, (char *) &pColormap->mid);
13935c4bbdfSmrg
14035c4bbdfSmrg        /* Call the engine specific colormap install procedure */
14135c4bbdfSmrg        if (!((*pScreenPriv->pwinInstallColormap) (pColormap))) {
14235c4bbdfSmrg            winErrorFVerb(2,
14335c4bbdfSmrg                          "winInstallColormap - Screen specific colormap install "
14435c4bbdfSmrg                          "procedure failed.  Continuing, but colors may be "
14535c4bbdfSmrg                          "messed up from now on.\n");
14635c4bbdfSmrg        }
14705b261ecSmrg    }
14805b261ecSmrg
14935c4bbdfSmrg    /* Save a pointer to the newly installed colormap */
15035c4bbdfSmrg    pScreenPriv->pcmapInstalled = pColormap;
15105b261ecSmrg}
15205b261ecSmrg
15305b261ecSmrg/* See Porting Layer Definition - p. 30 */
15405b261ecSmrgstatic void
15535c4bbdfSmrgwinUninstallColormap(ColormapPtr pmap)
15605b261ecSmrg{
15735c4bbdfSmrg    winScreenPriv(pmap->pScreen);
15835c4bbdfSmrg    ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
15905b261ecSmrg
16005b261ecSmrg#if CYGDEBUG
16135c4bbdfSmrg    winDebug("winUninstallColormap\n");
16205b261ecSmrg#endif
16305b261ecSmrg
16435c4bbdfSmrg    /* Is the colormap currently installed? */
16535c4bbdfSmrg    if (pmap != curpmap) {
16635c4bbdfSmrg        /* Colormap not installed, nothing to do */
16735c4bbdfSmrg        return;
16805b261ecSmrg    }
16935c4bbdfSmrg
17035c4bbdfSmrg    /* Clear the installed colormap flag */
17135c4bbdfSmrg    pScreenPriv->pcmapInstalled = NULL;
17235c4bbdfSmrg
17335c4bbdfSmrg    /*
17435c4bbdfSmrg     * NOTE: The default colormap does not get "uninstalled" before
17535c4bbdfSmrg     * it is destroyed.
17635c4bbdfSmrg     */
17735c4bbdfSmrg
17835c4bbdfSmrg    /* Install the default cmap in place of the cmap to be uninstalled */
17935c4bbdfSmrg    if (pmap->mid != pmap->pScreen->defColormap) {
18035c4bbdfSmrg        dixLookupResourceByType((void *) &curpmap, pmap->pScreen->defColormap,
18135c4bbdfSmrg                                RT_COLORMAP, NullClient, DixUnknownAccess);
18235c4bbdfSmrg        (*pmap->pScreen->InstallColormap) (curpmap);
18305b261ecSmrg    }
18405b261ecSmrg}
18505b261ecSmrg
18605b261ecSmrg/* See Porting Layer Definition - p. 30 */
18705b261ecSmrgstatic void
18835c4bbdfSmrgwinStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs)
18905b261ecSmrg{
19035c4bbdfSmrg    ScreenPtr pScreen = pmap->pScreen;
19135c4bbdfSmrg
19235c4bbdfSmrg    winScreenPriv(pScreen);
19335c4bbdfSmrg    winCmapPriv(pmap);
19435c4bbdfSmrg    int i;
19535c4bbdfSmrg    unsigned short nRed, nGreen, nBlue;
19605b261ecSmrg
19705b261ecSmrg#if CYGDEBUG
19835c4bbdfSmrg    if (ndef != 1)
19935c4bbdfSmrg        winDebug("winStoreColors - ndef: %d\n", ndef);
20005b261ecSmrg#endif
20105b261ecSmrg
20235c4bbdfSmrg    /* Save the new colors in the colormap privates */
20335c4bbdfSmrg    for (i = 0; i < ndef; ++i) {
20435c4bbdfSmrg        /* Adjust the colors from the X color spec to the Windows color spec */
20535c4bbdfSmrg        nRed = pdefs[i].red >> 8;
20635c4bbdfSmrg        nGreen = pdefs[i].green >> 8;
20735c4bbdfSmrg        nBlue = pdefs[i].blue >> 8;
20835c4bbdfSmrg
20935c4bbdfSmrg        /* Copy the colors to a palette entry table */
21035c4bbdfSmrg        pCmapPriv->peColors[pdefs[0].pixel + i].peRed = nRed;
21135c4bbdfSmrg        pCmapPriv->peColors[pdefs[0].pixel + i].peGreen = nGreen;
21235c4bbdfSmrg        pCmapPriv->peColors[pdefs[0].pixel + i].peBlue = nBlue;
21335c4bbdfSmrg
21435c4bbdfSmrg        /* Copy the colors to a RGBQUAD table */
21535c4bbdfSmrg        pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbRed = nRed;
21635c4bbdfSmrg        pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbGreen = nGreen;
21735c4bbdfSmrg        pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbBlue = nBlue;
21805b261ecSmrg
21905b261ecSmrg#if CYGDEBUG
22035c4bbdfSmrg        winDebug("winStoreColors - nRed %d nGreen %d nBlue %d\n",
22135c4bbdfSmrg                 nRed, nGreen, nBlue);
22205b261ecSmrg#endif
22305b261ecSmrg    }
22405b261ecSmrg
22535c4bbdfSmrg    /* Call the engine specific store colors procedure */
22635c4bbdfSmrg    if (!((pScreenPriv->pwinStoreColors) (pmap, ndef, pdefs))) {
22735c4bbdfSmrg        winErrorFVerb(2,
22835c4bbdfSmrg                      "winStoreColors - Engine cpecific color storage procedure "
22935c4bbdfSmrg                      "failed.  Continuing, but colors may be messed up from now "
23035c4bbdfSmrg                      "on.\n");
23105b261ecSmrg    }
23205b261ecSmrg}
23305b261ecSmrg
23405b261ecSmrg/* See Porting Layer Definition - p. 30 */
23505b261ecSmrgstatic void
23635c4bbdfSmrgwinResolveColor(unsigned short *pred,
23735c4bbdfSmrg                unsigned short *pgreen,
23835c4bbdfSmrg                unsigned short *pblue, VisualPtr pVisual)
23905b261ecSmrg{
24005b261ecSmrg#if CYGDEBUG
24135c4bbdfSmrg    winDebug("winResolveColor ()\n");
24205b261ecSmrg#endif
24305b261ecSmrg
24435c4bbdfSmrg    miResolveColor(pred, pgreen, pblue, pVisual);
24505b261ecSmrg}
24605b261ecSmrg
24705b261ecSmrg/* See Porting Layer Definition - p. 29 */
24805b261ecSmrgstatic Bool
24935c4bbdfSmrgwinCreateColormap(ColormapPtr pmap)
25005b261ecSmrg{
25135c4bbdfSmrg    winPrivCmapPtr pCmapPriv = NULL;
25235c4bbdfSmrg    ScreenPtr pScreen = pmap->pScreen;
25335c4bbdfSmrg
25435c4bbdfSmrg    winScreenPriv(pScreen);
25505b261ecSmrg
25605b261ecSmrg#if CYGDEBUG
25735c4bbdfSmrg    winDebug("winCreateColormap\n");
25805b261ecSmrg#endif
25905b261ecSmrg
26035c4bbdfSmrg    /* Allocate colormap privates */
26135c4bbdfSmrg    if (!winAllocateCmapPrivates(pmap)) {
26235c4bbdfSmrg        ErrorF("winCreateColorma - Couldn't allocate cmap privates\n");
26335c4bbdfSmrg        return FALSE;
26405b261ecSmrg    }
26505b261ecSmrg
26635c4bbdfSmrg    /* Get a pointer to the newly allocated privates */
26735c4bbdfSmrg    pCmapPriv = winGetCmapPriv(pmap);
26835c4bbdfSmrg
26935c4bbdfSmrg    /*
27035c4bbdfSmrg     * FIXME: This is some evil hackery to help in handling some X clients
27135c4bbdfSmrg     * that expect the top pixel to be white.  This "help" only lasts until
27235c4bbdfSmrg     * some client overwrites the top colormap entry.
27335c4bbdfSmrg     *
27435c4bbdfSmrg     * We don't want to actually allocate the top entry, as that causes
27535c4bbdfSmrg     * problems with X clients that need 7 planes (128 colors) in the default
27635c4bbdfSmrg     * colormap, such as Magic 7.1.
27735c4bbdfSmrg     */
27835c4bbdfSmrg    pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbRed = 255;
27935c4bbdfSmrg    pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbGreen = 255;
28035c4bbdfSmrg    pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbBlue = 255;
28135c4bbdfSmrg    pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peRed = 255;
28235c4bbdfSmrg    pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peGreen = 255;
28335c4bbdfSmrg    pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peBlue = 255;
28435c4bbdfSmrg
28535c4bbdfSmrg    /* Call the engine specific colormap initialization procedure */
28635c4bbdfSmrg    if (!((*pScreenPriv->pwinCreateColormap) (pmap))) {
28735c4bbdfSmrg        ErrorF("winCreateColormap - Engine specific colormap creation "
28835c4bbdfSmrg               "procedure failed.  Aborting.\n");
28935c4bbdfSmrg        return FALSE;
29005b261ecSmrg    }
29105b261ecSmrg
29235c4bbdfSmrg    return TRUE;
29305b261ecSmrg}
29405b261ecSmrg
29505b261ecSmrg/* See Porting Layer Definition - p. 29, 30 */
29605b261ecSmrgstatic void
29735c4bbdfSmrgwinDestroyColormap(ColormapPtr pColormap)
29805b261ecSmrg{
29935c4bbdfSmrg    winScreenPriv(pColormap->pScreen);
30035c4bbdfSmrg    winCmapPriv(pColormap);
30135c4bbdfSmrg
30235c4bbdfSmrg    /* Call the engine specific colormap destruction procedure */
30335c4bbdfSmrg    if (!((*pScreenPriv->pwinDestroyColormap) (pColormap))) {
30435c4bbdfSmrg        winErrorFVerb(2,
30535c4bbdfSmrg                      "winDestroyColormap - Engine specific colormap destruction "
30635c4bbdfSmrg                      "procedure failed.  Continuing, but it is possible that memory "
30735c4bbdfSmrg                      "was leaked, or that colors will be messed up from now on.\n");
30805b261ecSmrg    }
30905b261ecSmrg
31035c4bbdfSmrg    /* Free the colormap privates */
31135c4bbdfSmrg    free(pCmapPriv);
31235c4bbdfSmrg    winSetCmapPriv(pColormap, NULL);
31305b261ecSmrg
31405b261ecSmrg#if CYGDEBUG
31535c4bbdfSmrg    winDebug("winDestroyColormap - Returning\n");
31605b261ecSmrg#endif
31705b261ecSmrg}
31805b261ecSmrg
31905b261ecSmrg/*
32005b261ecSmrg * Internal function to load the palette used by the Shadow DIB
32105b261ecSmrg */
32205b261ecSmrg
32305b261ecSmrgstatic Bool
32435c4bbdfSmrgwinGetPaletteDIB(ScreenPtr pScreen, ColormapPtr pcmap)
32505b261ecSmrg{
32635c4bbdfSmrg    winScreenPriv(pScreen);
32735c4bbdfSmrg    int i;
32835c4bbdfSmrg    Pixel pixel;                /* Pixel == CARD32 */
32935c4bbdfSmrg    CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */
33035c4bbdfSmrg    UINT uiColorsRetrieved = 0;
33135c4bbdfSmrg    RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
33235c4bbdfSmrg
33335c4bbdfSmrg    /* Get the color table for the screen */
33435c4bbdfSmrg    uiColorsRetrieved = GetDIBColorTable(pScreenPriv->hdcScreen,
33535c4bbdfSmrg                                         0, WIN_NUM_PALETTE_ENTRIES, rgbColors);
33635c4bbdfSmrg    if (uiColorsRetrieved == 0) {
33735c4bbdfSmrg        ErrorF("winGetPaletteDIB - Could not retrieve screen color table\n");
33835c4bbdfSmrg        return FALSE;
33905b261ecSmrg    }
34005b261ecSmrg
34105b261ecSmrg#if CYGDEBUG
34235c4bbdfSmrg    winDebug("winGetPaletteDIB - Retrieved %d colors from DIB\n",
34335c4bbdfSmrg             uiColorsRetrieved);
34405b261ecSmrg#endif
34505b261ecSmrg
34635c4bbdfSmrg    /* Set the DIB color table to the default screen palette */
34735c4bbdfSmrg    if (SetDIBColorTable(pScreenPriv->hdcShadow,
34835c4bbdfSmrg                         0, uiColorsRetrieved, rgbColors) == 0) {
34935c4bbdfSmrg        ErrorF("winGetPaletteDIB - SetDIBColorTable () failed\n");
35035c4bbdfSmrg        return FALSE;
35105b261ecSmrg    }
35205b261ecSmrg
35335c4bbdfSmrg    /* Alloc each color in the DIB color table */
35435c4bbdfSmrg    for (i = 0; i < uiColorsRetrieved; ++i) {
35535c4bbdfSmrg        pixel = i;
35605b261ecSmrg
35735c4bbdfSmrg        /* Extract the color values for current palette entry */
35835c4bbdfSmrg        nRed = rgbColors[i].rgbRed << 8;
35935c4bbdfSmrg        nGreen = rgbColors[i].rgbGreen << 8;
36035c4bbdfSmrg        nBlue = rgbColors[i].rgbBlue << 8;
36105b261ecSmrg
36205b261ecSmrg#if CYGDEBUG
36335c4bbdfSmrg        winDebug("winGetPaletteDIB - Allocating a color: %u; "
36435c4bbdfSmrg                 "%d %d %d\n", (unsigned int)pixel, nRed, nGreen, nBlue);
36505b261ecSmrg#endif
36605b261ecSmrg
36735c4bbdfSmrg        /* Allocate a entry in the X colormap */
36835c4bbdfSmrg        if (AllocColor(pcmap, &nRed, &nGreen, &nBlue, &pixel, 0) != Success) {
36935c4bbdfSmrg            ErrorF("winGetPaletteDIB - AllocColor () failed, pixel %d\n", i);
37035c4bbdfSmrg            return FALSE;
37135c4bbdfSmrg        }
37235c4bbdfSmrg
37335c4bbdfSmrg        if (i != pixel
37435c4bbdfSmrg            || nRed != rgbColors[i].rgbRed
37535c4bbdfSmrg            || nGreen != rgbColors[i].rgbGreen
37635c4bbdfSmrg            || nBlue != rgbColors[i].rgbBlue) {
37735c4bbdfSmrg            winDebug("winGetPaletteDIB - Got: %d; "
37835c4bbdfSmrg                     "%d %d %d\n", (int) pixel, nRed, nGreen, nBlue);
37935c4bbdfSmrg        }
38035c4bbdfSmrg
38135c4bbdfSmrg        /* FIXME: Not sure that this bit is needed at all */
38235c4bbdfSmrg        pcmap->red[i].co.local.red = nRed;
38335c4bbdfSmrg        pcmap->red[i].co.local.green = nGreen;
38435c4bbdfSmrg        pcmap->red[i].co.local.blue = nBlue;
38505b261ecSmrg    }
38605b261ecSmrg
38735c4bbdfSmrg    /* System is using a colormap */
38835c4bbdfSmrg    /* Set the black and white pixel indices */
38935c4bbdfSmrg    pScreen->whitePixel = uiColorsRetrieved - 1;
39035c4bbdfSmrg    pScreen->blackPixel = 0;
39105b261ecSmrg
39235c4bbdfSmrg    return TRUE;
39305b261ecSmrg}
39405b261ecSmrg
39505b261ecSmrg/*
39605b261ecSmrg * Internal function to load the standard system palette being used by DD
39705b261ecSmrg */
39805b261ecSmrg
39905b261ecSmrgstatic Bool
40035c4bbdfSmrgwinGetPaletteDD(ScreenPtr pScreen, ColormapPtr pcmap)
40105b261ecSmrg{
40235c4bbdfSmrg    int i;
40335c4bbdfSmrg    Pixel pixel;                /* Pixel == CARD32 */
40435c4bbdfSmrg    CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */
40535c4bbdfSmrg    UINT uiSystemPaletteEntries;
40635c4bbdfSmrg    LPPALETTEENTRY ppeColors = NULL;
40735c4bbdfSmrg    HDC hdc = NULL;
40835c4bbdfSmrg
40935c4bbdfSmrg    /* Get a DC to obtain the default palette */
41035c4bbdfSmrg    hdc = GetDC(NULL);
41135c4bbdfSmrg    if (hdc == NULL) {
41235c4bbdfSmrg        ErrorF("winGetPaletteDD - Couldn't get a DC\n");
41335c4bbdfSmrg        return FALSE;
41405b261ecSmrg    }
41505b261ecSmrg
41635c4bbdfSmrg    /* Get the number of entries in the system palette */
41735c4bbdfSmrg    uiSystemPaletteEntries = GetSystemPaletteEntries(hdc, 0, 0, NULL);
41835c4bbdfSmrg    if (uiSystemPaletteEntries == 0) {
41935c4bbdfSmrg        ErrorF("winGetPaletteDD - Unable to determine number of "
42035c4bbdfSmrg               "system palette entries\n");
42135c4bbdfSmrg        return FALSE;
42205b261ecSmrg    }
42305b261ecSmrg
42405b261ecSmrg#if CYGDEBUG
42535c4bbdfSmrg    winDebug("winGetPaletteDD - uiSystemPaletteEntries %d\n",
42635c4bbdfSmrg             uiSystemPaletteEntries);
42705b261ecSmrg#endif
42835c4bbdfSmrg
42935c4bbdfSmrg    /* Allocate palette entries structure */
43035c4bbdfSmrg    ppeColors = malloc(uiSystemPaletteEntries * sizeof(PALETTEENTRY));
43135c4bbdfSmrg    if (ppeColors == NULL) {
43235c4bbdfSmrg        ErrorF("winGetPaletteDD - malloc () for colormap failed\n");
43335c4bbdfSmrg        return FALSE;
43405b261ecSmrg    }
43505b261ecSmrg
43635c4bbdfSmrg    /* Get system palette entries */
43735c4bbdfSmrg    GetSystemPaletteEntries(hdc, 0, uiSystemPaletteEntries, ppeColors);
43805b261ecSmrg
43935c4bbdfSmrg    /* Allocate an X colormap entry for every system palette entry */
44035c4bbdfSmrg    for (i = 0; i < uiSystemPaletteEntries; ++i) {
44135c4bbdfSmrg        pixel = i;
44205b261ecSmrg
44335c4bbdfSmrg        /* Extract the color values for current palette entry */
44435c4bbdfSmrg        nRed = ppeColors[i].peRed << 8;
44535c4bbdfSmrg        nGreen = ppeColors[i].peGreen << 8;
44635c4bbdfSmrg        nBlue = ppeColors[i].peBlue << 8;
44705b261ecSmrg#if CYGDEBUG
44835c4bbdfSmrg        winDebug("winGetPaletteDD - Allocating a color: %u; "
44935c4bbdfSmrg                 "%d %d %d\n", (unsigned int)pixel, nRed, nGreen, nBlue);
45005b261ecSmrg#endif
45135c4bbdfSmrg        if (AllocColor(pcmap, &nRed, &nGreen, &nBlue, &pixel, 0) != Success) {
45235c4bbdfSmrg            ErrorF("winGetPaletteDD - AllocColor () failed, pixel %d\n", i);
45335c4bbdfSmrg            free(ppeColors);
45435c4bbdfSmrg            ppeColors = NULL;
45535c4bbdfSmrg            return FALSE;
45635c4bbdfSmrg        }
45735c4bbdfSmrg
45835c4bbdfSmrg        pcmap->red[i].co.local.red = nRed;
45935c4bbdfSmrg        pcmap->red[i].co.local.green = nGreen;
46035c4bbdfSmrg        pcmap->red[i].co.local.blue = nBlue;
46105b261ecSmrg    }
46205b261ecSmrg
46335c4bbdfSmrg    /* System is using a colormap */
46435c4bbdfSmrg    /* Set the black and white pixel indices */
46535c4bbdfSmrg    pScreen->whitePixel = uiSystemPaletteEntries - 1;
46635c4bbdfSmrg    pScreen->blackPixel = 0;
46705b261ecSmrg
46835c4bbdfSmrg    /* Free colormap */
46935c4bbdfSmrg    free(ppeColors);
47035c4bbdfSmrg    ppeColors = NULL;
47105b261ecSmrg
47235c4bbdfSmrg    /* Free the DC */
47335c4bbdfSmrg    if (hdc != NULL) {
47435c4bbdfSmrg        ReleaseDC(NULL, hdc);
47535c4bbdfSmrg        hdc = NULL;
47605b261ecSmrg    }
47705b261ecSmrg
47835c4bbdfSmrg    return TRUE;
47905b261ecSmrg}
48005b261ecSmrg
48105b261ecSmrg/*
48205b261ecSmrg * Install the standard fb colormap, or the GDI colormap,
48305b261ecSmrg * depending on the current screen depth.
48405b261ecSmrg */
48505b261ecSmrg
48605b261ecSmrgBool
48735c4bbdfSmrgwinCreateDefColormap(ScreenPtr pScreen)
48805b261ecSmrg{
48935c4bbdfSmrg    winScreenPriv(pScreen);
49035c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
49135c4bbdfSmrg    unsigned short zero = 0, ones = 0xFFFF;
49235c4bbdfSmrg    VisualPtr pVisual = pScreenPriv->pRootVisual;
49335c4bbdfSmrg    ColormapPtr pcmap = NULL;
49435c4bbdfSmrg    Pixel wp, bp;
49505b261ecSmrg
49605b261ecSmrg#if CYGDEBUG
49735c4bbdfSmrg    winDebug("winCreateDefColormap\n");
49805b261ecSmrg#endif
49905b261ecSmrg
50035c4bbdfSmrg    /* Use standard fb colormaps for non palettized color modes */
50135c4bbdfSmrg    if (pScreenInfo->dwBPP > 8) {
50235c4bbdfSmrg        winDebug("winCreateDefColormap - Deferring to "
50335c4bbdfSmrg                 "fbCreateDefColormap ()\n");
50435c4bbdfSmrg        return fbCreateDefColormap(pScreen);
50505b261ecSmrg    }
50605b261ecSmrg
50735c4bbdfSmrg    /*
50835c4bbdfSmrg     *  AllocAll for non-Dynamic visual classes,
50935c4bbdfSmrg     *  AllocNone for Dynamic visual classes.
51035c4bbdfSmrg     */
51105b261ecSmrg
51235c4bbdfSmrg    /*
51335c4bbdfSmrg     * Dynamic visual classes allow the colors of the color map
51435c4bbdfSmrg     * to be changed by clients.
51535c4bbdfSmrg     */
51605b261ecSmrg
51705b261ecSmrg#if CYGDEBUG
51835c4bbdfSmrg    winDebug("winCreateDefColormap - defColormap: %lu\n", pScreen->defColormap);
51905b261ecSmrg#endif
52005b261ecSmrg
52135c4bbdfSmrg    /* Allocate an X colormap, owned by client 0 */
52235c4bbdfSmrg    if (CreateColormap(pScreen->defColormap,
52335c4bbdfSmrg                       pScreen,
52435c4bbdfSmrg                       pVisual,
52535c4bbdfSmrg                       &pcmap,
52635c4bbdfSmrg                       (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
52735c4bbdfSmrg                       0) != Success) {
52835c4bbdfSmrg        ErrorF("winCreateDefColormap - CreateColormap failed\n");
52935c4bbdfSmrg        return FALSE;
53005b261ecSmrg    }
53135c4bbdfSmrg    if (pcmap == NULL) {
53235c4bbdfSmrg        ErrorF("winCreateDefColormap - Colormap could not be created\n");
53335c4bbdfSmrg        return FALSE;
53405b261ecSmrg    }
53505b261ecSmrg
53605b261ecSmrg#if CYGDEBUG
53735c4bbdfSmrg    winDebug("winCreateDefColormap - Created a colormap\n");
53805b261ecSmrg#endif
53905b261ecSmrg
54035c4bbdfSmrg    /* Branch on the visual class */
54135c4bbdfSmrg    if (!(pVisual->class & DynamicClass)) {
54235c4bbdfSmrg        /* Branch on engine type */
54335c4bbdfSmrg        if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI) {
54435c4bbdfSmrg            /* Load the colors being used by the Shadow DIB */
54535c4bbdfSmrg            if (!winGetPaletteDIB(pScreen, pcmap)) {
54635c4bbdfSmrg                ErrorF("winCreateDefColormap - Couldn't get DIB colors\n");
54735c4bbdfSmrg                return FALSE;
54835c4bbdfSmrg            }
54935c4bbdfSmrg        }
55035c4bbdfSmrg        else {
55135c4bbdfSmrg            /* Load the colors from the default system palette */
55235c4bbdfSmrg            if (!winGetPaletteDD(pScreen, pcmap)) {
55335c4bbdfSmrg                ErrorF("winCreateDefColormap - Couldn't get colors "
55435c4bbdfSmrg                       "for DD\n");
55535c4bbdfSmrg                return FALSE;
55635c4bbdfSmrg            }
55735c4bbdfSmrg        }
55805b261ecSmrg    }
55935c4bbdfSmrg    else {
56035c4bbdfSmrg        wp = pScreen->whitePixel;
56135c4bbdfSmrg        bp = pScreen->blackPixel;
56235c4bbdfSmrg
56335c4bbdfSmrg        /* Allocate a black and white pixel */
56435c4bbdfSmrg        if ((AllocColor(pcmap, &ones, &ones, &ones, &wp, 0) != Success)
56535c4bbdfSmrg            || (AllocColor(pcmap, &zero, &zero, &zero, &bp, 0) != Success)) {
56635c4bbdfSmrg            ErrorF("winCreateDefColormap - Couldn't allocate bp or wp\n");
56735c4bbdfSmrg            return FALSE;
56835c4bbdfSmrg        }
56935c4bbdfSmrg
57035c4bbdfSmrg        pScreen->whitePixel = wp;
57135c4bbdfSmrg        pScreen->blackPixel = bp;
57205b261ecSmrg
57305b261ecSmrg#if 0
57435c4bbdfSmrg        /* Have to reserve first 10 and last ten pixels in DirectDraw windowed */
57535c4bbdfSmrg        if (pScreenInfo->dwEngine != WIN_SERVER_SHADOW_GDI) {
57635c4bbdfSmrg            int k;
57735c4bbdfSmrg            Pixel p;
57835c4bbdfSmrg
57935c4bbdfSmrg            for (k = 1; k < 10; ++k) {
58035c4bbdfSmrg                p = k;
58135c4bbdfSmrg                if (AllocColor(pcmap, &ones, &ones, &ones, &p, 0) != Success)
58235c4bbdfSmrg                    FatalError("Foo!\n");
58335c4bbdfSmrg            }
58435c4bbdfSmrg
58535c4bbdfSmrg            for (k = 245; k < 255; ++k) {
58635c4bbdfSmrg                p = k;
58735c4bbdfSmrg                if (AllocColor(pcmap, &zero, &zero, &zero, &p, 0) != Success)
58835c4bbdfSmrg                    FatalError("Baz!\n");
58935c4bbdfSmrg            }
59035c4bbdfSmrg        }
59105b261ecSmrg#endif
59205b261ecSmrg    }
59305b261ecSmrg
59435c4bbdfSmrg    /* Install the created colormap */
59535c4bbdfSmrg    (*pScreen->InstallColormap) (pcmap);
59605b261ecSmrg
59705b261ecSmrg#if CYGDEBUG
59835c4bbdfSmrg    winDebug("winCreateDefColormap - Returning\n");
59905b261ecSmrg#endif
60005b261ecSmrg
60135c4bbdfSmrg    return TRUE;
60205b261ecSmrg}
603