#include "X.h"
#include "Xproto.h"
#include "scrnintstr.h"
#include "cmapst.h"
#include "resource.h"
#include "i8.h"
#include "afidata.h"

static ColormapPtr InstalledMaps[MAXSCREENS];

int
i8ListInstalledColormaps(pScreen, pmaps)
ScreenPtr	pScreen;
Colormap	*pmaps;
{
#if MAXSCREENS == 1
	*pmaps = InstalledMaps[0]->mid;
#else
	*pmaps = InstalledMaps[pScreen->myNum]->mid;
#endif
	return 1;
}

void
i8InstallColormap(pmap)
    ColormapPtr	pmap;
{
#if MAXSCREENS == 1
#define index 0
#else
    int index = pmap->pScreen->myNum;
#endif
    ColormapPtr oldpmap = InstalledMaps[index];
    struct hldpal_data data;
    struct cm_entry entries[256];	/* should we ALLOCATE_LOCAL this? */

    if(pmap != oldpmap)
    {
	register Entry *pent = pmap->red;
	unsigned char red, green, blue;
	int i;

	if(oldpmap != (ColormapPtr)None)
	    WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
	/* Install pmap */
	data.length = 10;
	data.type = 0;
	data.first = 0;
	data.num = pmap->pVisual->ColormapEntries;
	for (i = 0; i < data.num; i++, pent++) {
	    if (pent->fShared) {
		red = (unsigned char)(pent->co.shco.red->color >> 8);
		green = (unsigned char)(pent->co.shco.green->color >> 8);
		blue = (unsigned char)(pent->co.shco.blue->color >> 8);
	    } else {
		red = (unsigned char)(pent->co.local.red >> 8);
		green = (unsigned char)(pent->co.local.green >> 8);
		blue = (unsigned char)(pent->co.local.blue >> 8);
	    }
	    entries[i].red = red;
	    entries[i].green = green;
	    entries[i].blue = blue;
	}
	data.entries = entries;
	HLDPAL(&data);
	InstalledMaps[index] = pmap;
	i8priv.colormap = pmap;
	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);

    }
#undef index
}

void
i8UninstallColormap(pmap)
    ColormapPtr	pmap;
{
    ColormapPtr defmap = (ColormapPtr)
	    LookupIDByType(pmap->pScreen->defColormap, RT_COLORMAP);

    /* Simple - just install the default colormap.  vgaInstallColormap
     * will uninstall this map. */
    i8InstallColormap(defmap);
}

void
i8ResolveColor(pred, pgreen, pblue, pVisual)
unsigned short	*pred, *pgreen, *pblue;
VisualPtr	pVisual;
{
	/* We get 6 bits for each color.  round to nearest value */
	if (*pred < 0xfc00)
		*pred += 0x0200;
	*pred &= 0xfc00;
	if (*pgreen < 0xfc00)
		*pgreen += 0x0200;
	*pgreen &= 0xfc00;
	if (*pblue < 0xfc00)
		*pblue += 0x0200;
	*pblue &= 0xfc00;
}

Bool
i8CreateColormap(pmap)
ColormapPtr pmap;
{
	/* This code from cfbInitialize332Colormap() cfb/cfbcmap.c */
	int i;

	/* Each color is 6 bits, assume ColormapEntries is 256. */

	for (i = 0; i < pmap->pVisual->ColormapEntries; i++) {
		pmap->red[i].co.local.red = (i & 0x7) << 13;
		pmap->red[i].co.local.green = (i & 0x38) << 10;
		pmap->red[i].co.local.blue = (i & 0xc0) << 8;
	}
	return TRUE;
}

void
i8DestroyColormap(pmap)
ColormapPtr pmap;
{
	/* Don't worry about it.  We didn't allocate any private data
	 * anyway.
	 */
}

void
i8StoreColors(pmap, ndef, pdefs)
ColormapPtr pmap;
int ndef;
xColorItem *pdefs;
{
	int pixel;
	register Entry *pent;
	struct hldpal_data data;
	struct cm_entry entry;

	data.length = 10;
	data.type = 0;
	data.num = 1;
	data.entries = &entry;
	while (ndef-- > 0) {
		pixel = (int)pdefs->pixel;
		/* We have to store red, green, and blue, so ignore
		 * pdefs->flags and get the values out of the colormap
		 * itself.
		 */
		pent = pmap->red + pixel;
		if (pent->fShared) {
		    entry.red = (unsigned char)(pent->co.shco.red->color >> 8);
		    entry.green = (unsigned char)(pent->co.shco.green->color >> 8);
		    entry.blue = (unsigned char)(pent->co.shco.blue->color >> 8);
		} else {
		    entry.red = (unsigned char)(pent->co.local.red >> 8);
		    entry.green = (unsigned char)(pent->co.local.green >> 8);
		    entry.blue = (unsigned char)(pent->co.local.blue >> 8);
		}
		data.first = pixel;
		HLDPAL(&data);
		pdefs++;
	}
}
