#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
#include "win.h"
static int
winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps);
static void
winStoreColors (ColormapPtr pmap, int ndef, xColorItem *pdefs);
static void
winInstallColormap (ColormapPtr pmap);
static void
winUninstallColormap (ColormapPtr pmap);
static void
winResolveColor (unsigned short *pred,
unsigned short *pgreen,
unsigned short *pblue,
VisualPtr pVisual);
static Bool
winCreateColormap (ColormapPtr pmap);
static void
winDestroyColormap (ColormapPtr pmap);
static Bool
winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap);
static Bool
winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap);
void
winSetColormapFunctions (ScreenPtr pScreen)
{
pScreen->CreateColormap = winCreateColormap;
pScreen->DestroyColormap = winDestroyColormap;
pScreen->InstallColormap = winInstallColormap;
pScreen->UninstallColormap = winUninstallColormap;
pScreen->ListInstalledColormaps = winListInstalledColormaps;
pScreen->StoreColors = winStoreColors;
pScreen->ResolveColor = winResolveColor;
}
static int
winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps)
{
winScreenPriv(pScreen);
*pmaps = pScreenPriv->pcmapInstalled->mid;
return 1;
}
static void
winInstallColormap (ColormapPtr pColormap)
{
ScreenPtr pScreen = pColormap->pScreen;
winScreenPriv(pScreen);
ColormapPtr oldpmap = pScreenPriv->pcmapInstalled;
#if CYGDEBUG
winDebug ("winInstallColormap\n");
#endif
if (pColormap != oldpmap)
{
#if CYGDEBUG
winDebug ("winInstallColormap - Colormap has changed, attempt "
"to install.\n");
#endif
if (oldpmap != (ColormapPtr) None)
{
WalkTree (pColormap->pScreen, TellLostMap, (char *)&oldpmap->mid);
}
pScreenPriv->pcmapInstalled = pColormap;
WalkTree (pColormap->pScreen, TellGainedMap, (char *)&pColormap->mid);
if (!((*pScreenPriv->pwinInstallColormap) (pColormap)))
{
winErrorFVerb (2, "winInstallColormap - Screen specific colormap install "
"procedure failed. Continuing, but colors may be "
"messed up from now on.\n");
}
}
pScreenPriv->pcmapInstalled = pColormap;
}
static void
winUninstallColormap (ColormapPtr pmap)
{
winScreenPriv(pmap->pScreen);
ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
#if CYGDEBUG
winDebug ("winUninstallColormap\n");
#endif
if (pmap != curpmap)
{
return;
}
pScreenPriv->pcmapInstalled = NULL;
if (pmap->mid != pmap->pScreen->defColormap)
{
dixLookupResourceByType((pointer) &curpmap, pmap->pScreen->defColormap,
RT_COLORMAP, NullClient, DixUnknownAccess);
(*pmap->pScreen->InstallColormap) (curpmap);
}
}
static void
winStoreColors (ColormapPtr pmap,
int ndef,
xColorItem *pdefs)
{
ScreenPtr pScreen = pmap->pScreen;
winScreenPriv(pScreen);
winCmapPriv(pmap);
int i;
unsigned short nRed, nGreen, nBlue;
#if CYGDEBUG
if (ndef != 1)
winDebug ("winStoreColors - ndef: %d\n",
ndef);
#endif
for (i = 0; i < ndef; ++i)
{
nRed = pdefs[i].red >> 8;
nGreen = pdefs[i].green >> 8;
nBlue = pdefs[i].blue >> 8;
pCmapPriv->peColors[pdefs[0].pixel + i].peRed = nRed;
pCmapPriv->peColors[pdefs[0].pixel + i].peGreen = nGreen;
pCmapPriv->peColors[pdefs[0].pixel + i].peBlue = nBlue;
pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbRed = nRed;
pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbGreen = nGreen;
pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbBlue = nBlue;
#if CYGDEBUG
winDebug ("winStoreColors - nRed %d nGreen %d nBlue %d\n",
nRed, nGreen, nBlue);
#endif
}
if (!((pScreenPriv->pwinStoreColors) (pmap, ndef, pdefs)))
{
winErrorFVerb (2, "winStoreColors - Engine cpecific color storage procedure "
"failed. Continuing, but colors may be messed up from now "
"on.\n");
}
}
static void
winResolveColor (unsigned short *pred,
unsigned short *pgreen,
unsigned short *pblue,
VisualPtr pVisual)
{
#if CYGDEBUG
winDebug ("winResolveColor ()\n");
#endif
miResolveColor (pred, pgreen, pblue, pVisual);
}
static Bool
winCreateColormap (ColormapPtr pmap)
{
winPrivCmapPtr pCmapPriv = NULL;
ScreenPtr pScreen = pmap->pScreen;
winScreenPriv(pScreen);
#if CYGDEBUG
winDebug ("winCreateColormap\n");
#endif
if (!winAllocateCmapPrivates (pmap))
{
ErrorF ("winCreateColorma - Couldn't allocate cmap privates\n");
return FALSE;
}
pCmapPriv = winGetCmapPriv (pmap);
pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbRed = 255;
pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbGreen = 255;
pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbBlue = 255;
pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peRed = 255;
pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peGreen = 255;
pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peBlue = 255;
if (!((*pScreenPriv->pwinCreateColormap) (pmap)))
{
ErrorF ("winCreateColormap - Engine specific colormap creation "
"procedure failed. Aborting.\n");
return FALSE;
}
return TRUE;
}
static void
winDestroyColormap (ColormapPtr pColormap)
{
winScreenPriv(pColormap->pScreen);
winCmapPriv(pColormap);
if (!((*pScreenPriv->pwinDestroyColormap) (pColormap)))
{
winErrorFVerb (2, "winDestroyColormap - Engine specific colormap destruction "
"procedure failed. Continuing, but it is possible that memory "
"was leaked, or that colors will be messed up from now on.\n");
}
free (pCmapPriv);
winSetCmapPriv (pColormap, NULL);
#if CYGDEBUG
winDebug ("winDestroyColormap - Returning\n");
#endif
}
static Bool
winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap)
{
winScreenPriv(pScreen);
int i;
Pixel pixel;
CARD16 nRed, nGreen, nBlue;
UINT uiColorsRetrieved = 0;
RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
uiColorsRetrieved = GetDIBColorTable (pScreenPriv->hdcScreen,
0,
WIN_NUM_PALETTE_ENTRIES,
rgbColors);
if (uiColorsRetrieved == 0)
{
ErrorF ("winGetPaletteDIB - Could not retrieve screen color table\n");
return FALSE;
}
#if CYGDEBUG
winDebug ("winGetPaletteDIB - Retrieved %d colors from DIB\n",
uiColorsRetrieved);
#endif
if (SetDIBColorTable (pScreenPriv->hdcShadow,
0,
uiColorsRetrieved,
rgbColors) == 0)
{
ErrorF ("winGetPaletteDIB - SetDIBColorTable () failed\n");
return FALSE;
}
for (i = 0; i < uiColorsRetrieved; ++i)
{
pixel = i;
nRed = rgbColors[i].rgbRed << 8;
nGreen = rgbColors[i].rgbGreen << 8;
nBlue = rgbColors[i].rgbBlue << 8;
#if CYGDEBUG
winDebug ("winGetPaletteDIB - Allocating a color: %d; "
"%d %d %d\n",
pixel, nRed, nGreen, nBlue);
#endif
if (AllocColor (pcmap,
&nRed,
&nGreen,
&nBlue,
&pixel,
0) != Success)
{
ErrorF ("winGetPaletteDIB - AllocColor () failed, pixel %d\n",
i);
return FALSE;
}
if (i != pixel
|| nRed != rgbColors[i].rgbRed
|| nGreen != rgbColors[i].rgbGreen
|| nBlue != rgbColors[i].rgbBlue)
{
winDebug ("winGetPaletteDIB - Got: %d; "
"%d %d %d\n",
(int) pixel, nRed, nGreen, nBlue);
}
pcmap->red[i].co.local.red = nRed;
pcmap->red[i].co.local.green = nGreen;
pcmap->red[i].co.local.blue = nBlue;
}
pScreen->whitePixel = uiColorsRetrieved - 1;
pScreen->blackPixel = 0;
return TRUE;
}
static Bool
winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap)
{
int i;
Pixel pixel;
CARD16 nRed, nGreen, nBlue;
UINT uiSystemPaletteEntries;
LPPALETTEENTRY ppeColors = NULL;
HDC hdc = NULL;
hdc = GetDC (NULL);
if (hdc == NULL)
{
ErrorF ("winGetPaletteDD - Couldn't get a DC\n");
return FALSE;
}
uiSystemPaletteEntries = GetSystemPaletteEntries (hdc,
0, 0, NULL);
if (uiSystemPaletteEntries == 0)
{
ErrorF ("winGetPaletteDD - Unable to determine number of "
"system palette entries\n");
return FALSE;
}
#if CYGDEBUG
winDebug ("winGetPaletteDD - uiSystemPaletteEntries %d\n",
uiSystemPaletteEntries);
#endif
ppeColors = malloc (uiSystemPaletteEntries * sizeof (PALETTEENTRY));
if (ppeColors == NULL)
{
ErrorF ("winGetPaletteDD - malloc () for colormap failed\n");
return FALSE;
}
GetSystemPaletteEntries (hdc,
0, uiSystemPaletteEntries, ppeColors);
for (i = 0; i < uiSystemPaletteEntries; ++i)
{
pixel = i;
nRed = ppeColors[i].peRed << 8;
nGreen = ppeColors[i].peGreen << 8;
nBlue = ppeColors[i].peBlue << 8;
#if CYGDEBUG
winDebug ("winGetPaletteDD - Allocating a color: %d; "
"%d %d %d\n",
pixel, nRed, nGreen, nBlue);
#endif
if (AllocColor (pcmap,
&nRed,
&nGreen,
&nBlue,
&pixel,
0) != Success)
{
ErrorF ("winGetPaletteDD - AllocColor () failed, pixel %d\n",
i);
free (ppeColors);
ppeColors = NULL;
return FALSE;
}
pcmap->red[i].co.local.red = nRed;
pcmap->red[i].co.local.green = nGreen;
pcmap->red[i].co.local.blue = nBlue;
}
pScreen->whitePixel = uiSystemPaletteEntries - 1;
pScreen->blackPixel = 0;
free(ppeColors);
ppeColors = NULL;
if (hdc != NULL)
{
ReleaseDC (NULL, hdc);
hdc = NULL;
}
return TRUE;
}
Bool
winCreateDefColormap (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
unsigned short zero = 0, ones = 0xFFFF;
VisualPtr pVisual = pScreenPriv->pRootVisual;
ColormapPtr pcmap = NULL;
Pixel wp, bp;
#if CYGDEBUG
winDebug ("winCreateDefColormap\n");
#endif
if (pScreenInfo->dwBPP > 8)
{
winDebug ("winCreateDefColormap - Deferring to " \
"fbCreateDefColormap ()\n");
return fbCreateDefColormap (pScreen);
}
#if CYGDEBUG
winDebug ("winCreateDefColormap - defColormap: %d\n",
pScreen->defColormap);
#endif
if (CreateColormap (pScreen->defColormap,
pScreen,
pVisual,
&pcmap,
(pVisual->class & DynamicClass) ? AllocNone : AllocAll,
0) != Success)
{
ErrorF ("winCreateDefColormap - CreateColormap failed\n");
return FALSE;
}
if (pcmap == NULL)
{
ErrorF ("winCreateDefColormap - Colormap could not be created\n");
return FALSE;
}
#if CYGDEBUG
winDebug ("winCreateDefColormap - Created a colormap\n");
#endif
if (!(pVisual->class & DynamicClass))
{
if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI)
{
if (!winGetPaletteDIB (pScreen, pcmap))
{
ErrorF ("winCreateDefColormap - Couldn't get DIB colors\n");
return FALSE;
}
}
else
{
if (!winGetPaletteDD (pScreen, pcmap))
{
ErrorF ("winCreateDefColormap - Couldn't get colors "
"for DD\n");
return FALSE;
}
}
}
else
{
wp = pScreen->whitePixel;
bp = pScreen->blackPixel;
if ((AllocColor (pcmap, &ones, &ones, &ones, &wp, 0) !=
Success)
||
(AllocColor (pcmap, &zero, &zero, &zero, &bp, 0) !=
Success))
{
ErrorF ("winCreateDefColormap - Couldn't allocate bp or wp\n");
return FALSE;
}
pScreen->whitePixel = wp;
pScreen->blackPixel = bp;
#if 0
if (pScreenInfo->dwEngine != WIN_SERVER_SHADOW_GDI)
{
int k;
Pixel p;
for (k = 1; k < 10; ++k)
{
p = k;
if (AllocColor (pcmap, &ones, &ones, &ones, &p, 0) != Success)
FatalError ("Foo!\n");
}
for (k = 245; k < 255; ++k)
{
p = k;
if (AllocColor (pcmap, &zero, &zero, &zero, &p, 0) != Success)
FatalError ("Baz!\n");
}
}
#endif
}
(*pScreen->InstallColormap)(pcmap);
#if CYGDEBUG
winDebug ("winCreateDefColormap - Returning\n");
#endif
return TRUE;
}