/*
 * Color functions
 *
 * Copyright 1993 Alexandre Julliard
 * Copyright 1996 Alex Korobka
 */

#include "ts_xlib.h"
#include "x11drv.h"

#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "options.h"
#include "gdi.h"
#include "color.h"
#include "debug.h"
#include "xmalloc.h"
#include "monitor.h"

/* Palette indexed mode:

 *	logical palette -> mapping -> pixel
 *				     
 *
 * Windows needs contiguous color space ( from 0 to n ) but 
 * it is possible only with the private colormap. Otherwise we
 * have to map DC palette indices to real pixel values. With 
 * private colormaps it boils down to the identity mapping. The
 * other special case is when we have a fixed color visual with 
 * the screendepth > 8 - we abandon palette mappings altogether 
 * because pixel values can be calculated without X server 
 * assistance.
 *
 * Windows palette manager is described in the
 * http://premium.microsoft.com/msdn/library/techart/f30/f34/f40/d4d/sa942.htm
 */

typedef struct
{ 
    Colormap    colorMap;
    UINT16      size;
    UINT16      flags;
    INT	monoPlane;	 /* bit plane different for white and black pixels */

    INT	(*mapColor)( DC*, COLORREF );
} CSPACE;

static CSPACE cSpace = {0, 0, 0};

static int COLOR_Redshift   = 0; /* to handle abortive COLOR_VIRTUAL visuals */
static int COLOR_Redmax     = 0;
static int COLOR_Greenshift = 0;
static int COLOR_Greenmax   = 0;
static int COLOR_Blueshift  = 0;
static int COLOR_Bluemax    = 0;
static int COLOR_Graymax    = 0;

/* System color space. 
 *
 * First 10 and last 10 colors in COLOR_sysPalette are
 * "guarded". RealizePalette changes only the rest of colorcells. For
 * currently inactive window it changes only DC palette mappings.
 */

#define NB_COLORCUBE_START_INDEX	63

Visual* 		visual = NULL;

static PALETTEENTRY* COLOR_sysPal = NULL;    /* current system palette */
static int COLOR_gapStart = 256;
static int COLOR_gapEnd = -1;
static int COLOR_gapFilled = 0;
static int COLOR_max = 256;

  /* First free dynamic color cell, 0 = full palette, -1 = fixed palette */
static int            COLOR_firstFree = 0; 
static unsigned char  COLOR_freeList[256];

  /* Maps entry in the system palette to X pixel value */
int* COLOR_PaletteToPixel = NULL;

  /* Maps pixel to the entry in the system palette */
int* COLOR_PixelToPalette = NULL;

static const PALETTEENTRY __sysPalTemplate[NB_RESERVED_COLORS] = 
{
    /* first 10 entries in the system palette */
    /* red  green blue  flags */
    { 0x00, 0x00, 0x00, PC_SYS_USED },
    { 0x80, 0x00, 0x00, PC_SYS_USED },
    { 0x00, 0x80, 0x00, PC_SYS_USED },
    { 0x80, 0x80, 0x00, PC_SYS_USED },
    { 0x00, 0x00, 0x80, PC_SYS_USED },
    { 0x80, 0x00, 0x80, PC_SYS_USED },
    { 0x00, 0x80, 0x80, PC_SYS_USED },
    { 0xc0, 0xc0, 0xc0, PC_SYS_USED },
    { 0xc0, 0xdc, 0xc0, PC_SYS_USED },
    { 0xa6, 0xca, 0xf0, PC_SYS_USED },

    /* ... c_min/2 dynamic colorcells */

    /* ... gap (for sparse palettes) */

    /* ... c_min/2 dynamic colorcells */

    { 0xff, 0xfb, 0xf0, PC_SYS_USED },
    { 0xa0, 0xa0, 0xa4, PC_SYS_USED },
    { 0x80, 0x80, 0x80, PC_SYS_USED },
    { 0xff, 0x00, 0x00, PC_SYS_USED },
    { 0x00, 0xff, 0x00, PC_SYS_USED },
    { 0xff, 0xff, 0x00, PC_SYS_USED },
    { 0x00, 0x00, 0xff, PC_SYS_USED },
    { 0xff, 0x00, 0xff, PC_SYS_USED },
    { 0x00, 0xff, 0xff, PC_SYS_USED },
    { 0xff, 0xff, 0xff, PC_SYS_USED }     /* last 10 */
};

   /* Map an EGA index (0..15) to a pixel value in the system color space.  */

int COLOR_mapEGAPixel[16];

/***********************************************************************
 *	Misc auxiliary functions
 */
Colormap X11DRV_COLOR_GetColormap(void)
{
    return cSpace.colorMap;
}

BOOL COLOR_GetMonoPlane(INT* plane)
{
    *plane = cSpace.monoPlane;
    return (cSpace.flags & COLOR_WHITESET) ? TRUE : FALSE;
}

UINT16 COLOR_GetSystemPaletteSize(void)
{
    return (cSpace.flags & COLOR_PRIVATE) ? cSpace.size : 256;
}

UINT16 COLOR_GetSystemPaletteFlags(void)
{
    return cSpace.flags;
}

const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void)
{
    return __sysPalTemplate;
}

COLORREF COLOR_GetSystemPaletteEntry(UINT i)
{
 return *(COLORREF*)(COLOR_sysPal + i) & 0x00ffffff;
}

void COLOR_FormatSystemPalette(void)
{
 /* Build free list so we'd have an easy way to find
  * out if there are any available colorcells. 
  */

  int i, j = COLOR_firstFree = NB_RESERVED_COLORS/2;

  COLOR_sysPal[j].peFlags = 0;
  for( i = NB_RESERVED_COLORS/2 + 1 ; i < 256 - NB_RESERVED_COLORS/2 ; i++ )
    if( i < COLOR_gapStart || i > COLOR_gapEnd )
      {
	COLOR_sysPal[i].peFlags = 0;  /* unused tag */
	COLOR_freeList[j] = i;	  /* next */
        j = i;
      }
  COLOR_freeList[j] = 0;
}

BOOL COLOR_CheckSysColor(COLORREF c)
{
  int i;
  for( i = 0; i < NB_RESERVED_COLORS; i++ )
       if( c == (*(COLORREF*)(__sysPalTemplate + i) & 0x00ffffff) )
	   return 0;
  return 1;
}

/***********************************************************************
 *      Colormap Initialization
 */
static void COLOR_FillDefaultColors(void)
{
 /* initialize unused entries to what Windows uses as a color 
  * cube - based on Greg Kreider's code. 
  */

  int i = 0, idx = 0;
  int red, no_r, inc_r;
  int green, no_g, inc_g; 
  int blue, no_b, inc_b;
  
  if (cSpace.size <= NB_RESERVED_COLORS)
  	return;
  while (i*i*i < (cSpace.size - NB_RESERVED_COLORS)) i++;
  no_r = no_g = no_b = --i;
  if ((no_r * (no_g+1) * no_b) < (cSpace.size - NB_RESERVED_COLORS)) no_g++;
  if ((no_r * no_g * (no_b+1)) < (cSpace.size - NB_RESERVED_COLORS)) no_b++;
  inc_r = (255 - NB_COLORCUBE_START_INDEX)/no_r;
  inc_g = (255 - NB_COLORCUBE_START_INDEX)/no_g;
  inc_b = (255 - NB_COLORCUBE_START_INDEX)/no_b;

  idx = COLOR_firstFree;

  if( idx != -1 )
    for (blue = NB_COLORCUBE_START_INDEX; blue < 256 && idx; blue += inc_b )
     for (green = NB_COLORCUBE_START_INDEX; green < 256 && idx; green += inc_g )
      for (red = NB_COLORCUBE_START_INDEX; red < 256 && idx; red += inc_r )
      {
	 /* weird but true */

	 if( red == NB_COLORCUBE_START_INDEX && green == red && blue == green ) continue;

         COLOR_sysPal[idx].peRed = red;
         COLOR_sysPal[idx].peGreen = green;
         COLOR_sysPal[idx].peBlue = blue;
         
	 /* set X color */

	 if( cSpace.flags & COLOR_VIRTUAL )
	 {
            if (COLOR_Redmax != 255) no_r = (red * COLOR_Redmax) / 255;
            if (COLOR_Greenmax != 255) no_g = (green * COLOR_Greenmax) / 255;
            if (COLOR_Bluemax != 255) no_b = (blue * COLOR_Bluemax) / 255;

            COLOR_PaletteToPixel[idx] = (no_r << COLOR_Redshift) | (no_g << COLOR_Greenshift) | (no_b << COLOR_Blueshift);
	 }
	 else if( !(cSpace.flags & COLOR_FIXED) )
	 {
	   XColor color = { color.pixel = (COLOR_PaletteToPixel)? COLOR_PaletteToPixel[idx] : idx ,
	                    COLOR_sysPal[idx].peRed << 8,
			    COLOR_sysPal[idx].peGreen << 8,
			    COLOR_sysPal[idx].peGreen << 8,
			    (DoRed | DoGreen | DoBlue) };
	   TSXStoreColor(display, cSpace.colorMap, &color);
	 }
	 idx = COLOR_freeList[idx];
      }

  /* try to fill some entries in the "gap" with
   * what's already in the colormap - they will be
   * mappable to but not changeable. */

  if( COLOR_gapStart < COLOR_gapEnd && COLOR_PixelToPalette )
  {
    XColor	xc;
    int		r, g, b, max;

    max = COLOR_max - (256 - (COLOR_gapEnd - COLOR_gapStart));
    for ( i = 0, idx = COLOR_gapStart; i < 256 && idx <= COLOR_gapEnd; i++ )
      if( COLOR_PixelToPalette[i] == 0 )
	{
	  xc.pixel = i;

	  TSXQueryColor(display, cSpace.colorMap, &xc);
	  r = xc.red>>8; g = xc.green>>8; b = xc.blue>>8;

	  if( xc.pixel < 256 && COLOR_CheckSysColor(RGB(r, g, b)) &&
	      TSXAllocColor(display, cSpace.colorMap, &xc) )
	  {
	     COLOR_PixelToPalette[xc.pixel] = idx;
	     COLOR_PaletteToPixel[idx] = xc.pixel;
           *(COLORREF*)(COLOR_sysPal + idx) = RGB(r, g, b);
	     COLOR_sysPal[idx++].peFlags |= PC_SYS_USED;
	     if( --max <= 0 ) break;
	  }
	}
    COLOR_gapFilled = idx - COLOR_gapStart;    
  }
}

/***********************************************************************
 *           COLOR_BuildPrivateMap/COLOR_BuildSharedMap
 *
 * Allocate colorcells and initialize mapping tables.
 */
static BOOL COLOR_BuildPrivateMap(CSPACE* cs)
{
    /* Private colormap - identity mapping */

    XColor color;
    int i; 

    COLOR_sysPal = (PALETTEENTRY*)xmalloc(sizeof(PALETTEENTRY)*cs->size);

    TRACE(palette,"Building private map - %i palette entries\n", cs->size);

      /* Allocate system palette colors */ 

    for( i=0; i < cs->size; i++ )
    {
       if( i < NB_RESERVED_COLORS/2 )
       {
         color.red   = __sysPalTemplate[i].peRed * 65535 / 255;
         color.green = __sysPalTemplate[i].peGreen * 65535 / 255;
         color.blue  = __sysPalTemplate[i].peBlue * 65535 / 255;
	 COLOR_sysPal[i] = __sysPalTemplate[i];
       }
       else if( i >= cs->size - NB_RESERVED_COLORS/2 )
       {
	 int j = NB_RESERVED_COLORS + i - cs->size;
         color.red   = __sysPalTemplate[j].peRed * 65535 / 255;
         color.green = __sysPalTemplate[j].peGreen * 65535 / 255;
         color.blue  = __sysPalTemplate[j].peBlue * 65535 / 255;
	 COLOR_sysPal[i] = __sysPalTemplate[j];
       }

       color.flags = DoRed | DoGreen | DoBlue;
       color.pixel = i;
       TSXStoreColor(display, cs->colorMap, &color);

       /* Set EGA mapping if color is from the first or last eight */

       if (i < 8)
           COLOR_mapEGAPixel[i] = color.pixel;
       else if (i >= cs->size - 8 )
           COLOR_mapEGAPixel[i - (cs->size - 16)] = color.pixel;
    }

    COLOR_PixelToPalette = COLOR_PaletteToPixel = NULL;

    COLOR_gapStart = 256; COLOR_gapEnd = -1;

    COLOR_firstFree = (cs->size > NB_RESERVED_COLORS)?NB_RESERVED_COLORS/2 : -1;

    return FALSE;
}

static BOOL COLOR_BuildSharedMap(CSPACE* cs)
{
   XColor		color;
   unsigned long        sysPixel[NB_RESERVED_COLORS];
   unsigned long*	pixDynMapping = NULL;
   unsigned long	plane_masks[1];
   int			i, j, warn = 0;
   int			diff, r, g, b, max = 256, bp = 0, wp = 1;
   int			step = 1;

   /* read "AllocSystemColors" from wine.conf */

   COLOR_max = PROFILE_GetWineIniInt( "options", "AllocSystemColors", 256);
   if (COLOR_max > 256) COLOR_max = 256;
   else if (COLOR_max < 20) COLOR_max = 20;
   TRACE(palette,"%d colors configured.\n", COLOR_max);
   
   TRACE(palette,"Building shared map - %i palette entries\n", cs->size);

   /* Be nice and allocate system colors as read-only */

   for( i = 0; i < NB_RESERVED_COLORS; i++ )
     { 
        color.red   = __sysPalTemplate[i].peRed * 65535 / 255;
        color.green = __sysPalTemplate[i].peGreen * 65535 / 255;
        color.blue  = __sysPalTemplate[i].peBlue * 65535 / 255;
        color.flags = DoRed | DoGreen | DoBlue;

        if (!TSXAllocColor( display, cSpace.colorMap, &color ))
        { 
	     XColor	best, c;
	     
             if( !warn++ ) 
	     {
		  WARN(palette, "Not enough colors for the full system palette.\n");

	          bp = BlackPixel(display, DefaultScreen(display));
	          wp = WhitePixel(display, DefaultScreen(display));

	          max = (0xffffffff)>>(32 - MONITOR_GetDepth(&MONITOR_PrimaryMonitor));
	          if( max > 256 ) 
	          {
	  	      step = max/256;
		      max = 256;
	          }
	     }

	     /* reinit color (XAllocColor() may change it)
	      * and map to the best shared colorcell */

             color.red   = __sysPalTemplate[i].peRed * 65535 / 255;
             color.green = __sysPalTemplate[i].peGreen * 65535 / 255;
             color.blue  = __sysPalTemplate[i].peBlue * 65535 / 255;

	     best.pixel = best.red = best.green = best.blue = 0;
	     for( c.pixel = 0, diff = 0x7fffffff; c.pixel < max; c.pixel += step )
	     {
		TSXQueryColor(display, cSpace.colorMap, &c);
		r = (c.red - color.red)>>8; 
		g = (c.green - color.green)>>8; 
		b = (c.blue - color.blue)>>8;
		r = r*r + g*g + b*b;
		if( r < diff ) { best = c; diff = r; }
	     }

	     if( TSXAllocColor(display, cSpace.colorMap, &best) )
		 color.pixel = best.pixel;
	     else color.pixel = (i < NB_RESERVED_COLORS/2)? bp : wp;
        }

        sysPixel[i] = color.pixel;

        TRACE(palette,"syscolor(%lx) -> pixel %i\n",
		      *(COLORREF*)(__sysPalTemplate+i), (int)color.pixel);

        /* Set EGA mapping if color in the first or last eight */

        if (i < 8)
            COLOR_mapEGAPixel[i] = color.pixel;
        else if (i >= NB_RESERVED_COLORS - 8 )
            COLOR_mapEGAPixel[i - (NB_RESERVED_COLORS-16)] = color.pixel;
     }

   /* now allocate changeable set */

   if( !(cSpace.flags & COLOR_FIXED) )  
     {
	int c_min = 0, c_max = cs->size, c_val;

	TRACE(palette,"Dynamic colormap... \n");

	/* comment this out if you want to debug palette init */

	TSXGrabServer(display);

	/* let's become the first client that actually follows 
	 * X guidelines and does binary search...
	 */

	pixDynMapping = (unsigned long*)xmalloc(sizeof(long)*cs->size);
        while( c_max - c_min > 0 )
          {
             c_val = (c_max + c_min)/2 + (c_max + c_min)%2;

             if( !TSXAllocColorCells(display, cs->colorMap, False,
                                   plane_masks, 0, pixDynMapping, c_val) )
                 c_max = c_val - 1;
             else
               {
                 TSXFreeColors(display, cs->colorMap, pixDynMapping, c_val, 0);
                 c_min = c_val;
               }
          }

	if( c_min > COLOR_max - NB_RESERVED_COLORS) 
	    c_min = COLOR_max - NB_RESERVED_COLORS;

	c_min = (c_min/2) + (c_min/2);		/* need even set for split palette */

	if( c_min > 0 )
	  if( !TSXAllocColorCells(display, cs->colorMap, False,
                                plane_masks, 0, pixDynMapping, c_min) )
	    {
	      WARN(palette,"Inexplicable failure during colorcell allocation.\n");
	      c_min = 0;
	    }

        cs->size = c_min + NB_RESERVED_COLORS;

	TSXUngrabServer(display);

	TRACE(palette,"adjusted size %i colorcells\n", cs->size);
     }
   else if( cSpace.flags & COLOR_VIRTUAL ) 
	{
          /* virtual colorspace - ToPhysical takes care of 
           * color translations but we have to allocate full palette 
	   * to maintain compatibility
	   */
	  cs->size = 256;
	  TRACE(palette,"Virtual colorspace - screendepth %i\n", MONITOR_GetDepth(&MONITOR_PrimaryMonitor));
	}
   else cs->size = NB_RESERVED_COLORS;	/* system palette only - however we can alloc a bunch
			                 * of colors and map to them */

   TRACE(palette,"Shared system palette uses %i colors.\n", cs->size);

   /* set gap to account for pixel shortage. It has to be right in the center
    * of the system palette because otherwise raster ops get screwed. */

   if( cs->size >= 256 )
     { COLOR_gapStart = 256; COLOR_gapEnd = -1; }
   else
     { COLOR_gapStart = cs->size/2; COLOR_gapEnd = 255 - cs->size/2; }

   COLOR_firstFree = ( cs->size > NB_RESERVED_COLORS && 
		      (cs->flags & COLOR_VIRTUAL || !(cs->flags & COLOR_FIXED)) ) 
		     ? NB_RESERVED_COLORS/2 : -1;

   COLOR_sysPal = (PALETTEENTRY*)xmalloc(sizeof(PALETTEENTRY)*256);

   /* setup system palette entry <-> pixel mappings and fill in 20 fixed entries */

   if( MONITOR_GetDepth(&MONITOR_PrimaryMonitor) <= 8 )
     {
       COLOR_PixelToPalette = (int*)xmalloc(sizeof(int)*256);
       memset( COLOR_PixelToPalette, 0, 256*sizeof(int) );
     }

   /* for hicolor visuals PaletteToPixel mapping is used to skip
    * RGB->pixel calculation in COLOR_ToPhysical(). 
    */

   COLOR_PaletteToPixel = (int*)xmalloc(sizeof(int)*256);

   for( i = j = 0; i < 256; i++ )
   {
      if( i >= COLOR_gapStart && i <= COLOR_gapEnd ) 
      {
         COLOR_PaletteToPixel[i] = 0;
         COLOR_sysPal[i].peFlags = 0;	/* mark as unused */
         continue;
      }

      if( i < NB_RESERVED_COLORS/2 )
      {
        COLOR_PaletteToPixel[i] = sysPixel[i];
        COLOR_sysPal[i] = __sysPalTemplate[i];
      }
      else if( i >= 256 - NB_RESERVED_COLORS/2 )
      {
        COLOR_PaletteToPixel[i] = sysPixel[(i + NB_RESERVED_COLORS) - 256]; 
        COLOR_sysPal[i] = __sysPalTemplate[(i + NB_RESERVED_COLORS) - 256];
      }
      else if( pixDynMapping )
             COLOR_PaletteToPixel[i] = pixDynMapping[j++];
           else
             COLOR_PaletteToPixel[i] = i;

      TRACE(palette,"index %i -> pixel %i\n", i, COLOR_PaletteToPixel[i]);

      if( COLOR_PixelToPalette )
          COLOR_PixelToPalette[COLOR_PaletteToPixel[i]] = i;
   }

   if( pixDynMapping ) free(pixDynMapping);

   return TRUE;
}

/***********************************************************************
 *	     COLOR_Computeshifts
 *
 * Calculate conversion parameters for direct mapped visuals
 */
static void COLOR_Computeshifts(unsigned long maskbits, int *shift, int *max)
{
    int i;

    if (maskbits==0)
    {
        *shift=0;
        *max=0;
        return;
    }

    for(i=0;!(maskbits&1);i++)
        maskbits >>= 1;

    *shift = i;
    *max = maskbits;
}


/***********************************************************************
 *           COLOR_Init
 *
 * Initialize color management.
 */
BOOL COLOR_Init(void)
{
    int	mask, white, black;

    visual = DefaultVisual( display, DefaultScreen(display) );

    TRACE(palette,"initializing palette manager...\n");

    white = WhitePixelOfScreen( X11DRV_GetXScreen() );
    black = BlackPixelOfScreen( X11DRV_GetXScreen() );
    cSpace.monoPlane = 1;
    for( mask = 1; !((white & mask)^(black & mask)); mask <<= 1 )
	 cSpace.monoPlane++;
    cSpace.flags = (white & mask) ? COLOR_WHITESET : 0;
    cSpace.size = visual->map_entries;

    switch(visual->class)
    {
    case DirectColor:
	cSpace.flags |= COLOR_VIRTUAL;
    case GrayScale:
    case PseudoColor:
	if (Options.usePrivateMap)
	{
	    XSetWindowAttributes win_attr;

	    cSpace.colorMap = TSXCreateColormap( display, X11DRV_GetXRootWindow(),
						 visual, AllocAll );
	    if (cSpace.colorMap)
	    {
	        cSpace.flags |= (COLOR_PRIVATE | COLOR_WHITESET);

		cSpace.monoPlane = 1;
		for( white = cSpace.size - 1; !(white & 1); white >>= 1 )
		     cSpace.monoPlane++;

	        if( X11DRV_GetXRootWindow() != DefaultRootWindow(display) )
	        {
		    win_attr.colormap = cSpace.colorMap;
		    TSXChangeWindowAttributes( display, X11DRV_GetXRootWindow(),
					 CWColormap, &win_attr );
		}
		break;
	    }
	}
	cSpace.colorMap = DefaultColormapOfScreen( X11DRV_GetXScreen() );
        break;

    case StaticGray:
	cSpace.colorMap = DefaultColormapOfScreen( X11DRV_GetXScreen() );
	cSpace.flags |= COLOR_FIXED;
        COLOR_Graymax = (1<<MONITOR_GetDepth(&MONITOR_PrimaryMonitor))-1;
        break;

    case TrueColor:
	cSpace.flags |= COLOR_VIRTUAL;
    case StaticColor: {
    	int *depths,nrofdepths;
	/* FIXME: hack to detect XFree32 XF_VGA16 ... We just have
	 * depths 1 and 4
	 */
	depths=TSXListDepths(display,DefaultScreen(display),&nrofdepths);
	if ((nrofdepths==2) && ((depths[0]==4) || depths[1]==4)) {
	    cSpace.monoPlane = 1;
	    for( white = cSpace.size - 1; !(white & 1); white >>= 1 )
	        cSpace.monoPlane++;
    	    cSpace.flags = (white & mask) ? COLOR_WHITESET : 0;
	    cSpace.colorMap = DefaultColormapOfScreen( X11DRV_GetXScreen() );
	    TSXFree(depths);
	    break;
	}
	TSXFree(depths);
        cSpace.colorMap = DefaultColormapOfScreen( X11DRV_GetXScreen() );
        cSpace.flags |= COLOR_FIXED;
        COLOR_Computeshifts(visual->red_mask, &COLOR_Redshift, &COLOR_Redmax);
        COLOR_Computeshifts(visual->green_mask, &COLOR_Greenshift, &COLOR_Greenmax);
        COLOR_Computeshifts(visual->blue_mask, &COLOR_Blueshift, &COLOR_Bluemax);
	break;
    }
    }

    TRACE(palette," visual class %i (%i)\n", 
		    visual->class, cSpace.monoPlane);

    memset(COLOR_freeList, 0, 256*sizeof(unsigned char));

    if (cSpace.flags & COLOR_PRIVATE)
        COLOR_BuildPrivateMap( &cSpace );
    else
        COLOR_BuildSharedMap( &cSpace );

    /* Build free list */

    if( COLOR_firstFree != -1 )
        COLOR_FormatSystemPalette();

    COLOR_FillDefaultColors();

    return TRUE;
}

/***********************************************************************
 *           COLOR_Cleanup
 *
 * Free external colors we grabbed in the FillDefaultPalette()
 */
void COLOR_Cleanup(void)
{
  if( COLOR_gapFilled )
      TSXFreeColors(display, cSpace.colorMap, 
		  (unsigned long*)(COLOR_PaletteToPixel + COLOR_gapStart), 
		  COLOR_gapFilled, 0);
}

/***********************************************************************
 *           COLOR_IsSolid
 *
 * Check whether 'color' can be represented with a solid color.
 */
BOOL COLOR_IsSolid( COLORREF color )
{
    int i;
    const PALETTEENTRY *pEntry = COLOR_sysPal;

    if (color & 0xff000000) return TRUE;		/* indexed color */

    if (!color || (color == 0xffffff)) return TRUE;	/* black or white */

    for (i = 0; i < 256 ; i++, pEntry++)
    {
      if( i < COLOR_gapStart || i > COLOR_gapEnd )
	if ((GetRValue(color) == pEntry->peRed) &&
	    (GetGValue(color) == pEntry->peGreen) &&
	    (GetBValue(color) == pEntry->peBlue)) return TRUE;
    }
    return FALSE;
}


/***********************************************************************
 *	     COLOR_PaletteLookupPixel
 */
int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size,
                              int* mapping, COLORREF col, BOOL skipReserved )
{
    int i, best = 0, diff = 0x7fffffff;
    int r,g,b;

    for( i = 0; i < size && diff ; i++ )
    {
        if( !(palPalEntry[i].peFlags & PC_SYS_USED) ||
            (skipReserved && palPalEntry[i].peFlags  & PC_SYS_RESERVED) )
            continue;

        r = palPalEntry[i].peRed - GetRValue(col);
        g = palPalEntry[i].peGreen - GetGValue(col);
        b = palPalEntry[i].peBlue - GetBValue(col);

        r = r*r + g*g + b*b;

        if( r < diff ) { best = i; diff = r; }
    }
    return (mapping) ? mapping[best] : best;
}

/***********************************************************************
 *           COLOR_LookupSystemPixel
 */
int COLOR_LookupSystemPixel(COLORREF col)
{
 int            i, best = 0, diff = 0x7fffffff;
 int            size = COLOR_GetSystemPaletteSize();
 int            r,g,b;

 for( i = 0; i < size && diff ; i++ )
    {
      if( i == NB_RESERVED_COLORS/2 )
      {
      	int newi = size - NB_RESERVED_COLORS/2;
	if (newi>i) i=newi;
      }

      r = COLOR_sysPal[i].peRed - GetRValue(col);
      g = COLOR_sysPal[i].peGreen - GetGValue(col);
      b = COLOR_sysPal[i].peBlue - GetBValue(col);

      r = r*r + g*g + b*b;

      if( r < diff ) { best = i; diff = r; }
    }
 
 return (COLOR_PaletteToPixel)? COLOR_PaletteToPixel[best] : best;
}

/***********************************************************************
 *	     COLOR_PaletteLookupExactIndex
 */
int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
                                   COLORREF col )
{
    int i;
    BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
    for( i = 0; i < size; i++ )
    {
        if( palPalEntry[i].peFlags & PC_SYS_USED ) 	/* skips gap */
            if( palPalEntry[i].peRed == r &&
                palPalEntry[i].peGreen == g &&
                palPalEntry[i].peBlue == b )
                return i;
    }
    return -1;
}

/***********************************************************************
 *           COLOR_LookupNearestColor
 */
COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
{
  unsigned char		spec_type = color >> 24;
  int			i;

  /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */

  if( spec_type == 2 ) /* PALETTERGB */
    color = *(COLORREF*)
	     (palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));

  else if( spec_type == 1 ) /* PALETTEINDEX */
  {
    if( (i = color & 0x0000ffff) >= size ) 
      {
	WARN(palette, "RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
	color = *(COLORREF*)palPalEntry;
      }
    else color = *(COLORREF*)(palPalEntry + i);
  }

  color &= 0x00ffffff;
  return (0x00ffffff & *(COLORREF*)
         (COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
}

/***********************************************************************
 *           COLOR_ToLogical
 *
 * Return RGB color for given X pixel.
 */
COLORREF COLOR_ToLogical(int pixel)
{
    XColor color;

#if 0
    /* truecolor visual */

    if (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) >= 24) return pixel;
#endif

    /* check for hicolor visuals first */

    if ( cSpace.flags & COLOR_FIXED && !COLOR_Graymax )
    {
         color.red = (pixel >> COLOR_Redshift) & COLOR_Redmax;
         color.green = (pixel >> COLOR_Greenshift) & COLOR_Greenmax;
         color.blue = (pixel >> COLOR_Blueshift) & COLOR_Bluemax;
         return RGB((color.red * 255)/COLOR_Redmax,
                    (color.green * 255)/COLOR_Greenmax,
                    (color.blue * 255)/COLOR_Bluemax);
    }

    /* check if we can bypass X */

    if ((MONITOR_GetDepth(&MONITOR_PrimaryMonitor) <= 8) && (pixel < 256) && 
       !(cSpace.flags & (COLOR_VIRTUAL | COLOR_FIXED)) )
         return  ( *(COLORREF*)(COLOR_sysPal + 
		   ((COLOR_PixelToPalette)?COLOR_PixelToPalette[pixel]:pixel)) ) & 0x00ffffff;

    color.pixel = pixel;
    TSXQueryColor(display, cSpace.colorMap, &color);
    return RGB(color.red >> 8, color.green >> 8, color.blue >> 8);
}


/***********************************************************************
 *           COLOR_ToPhysical
 *
 * Return the physical color closest to 'color'.
 */
int COLOR_ToPhysical( DC *dc, COLORREF color )
{
    WORD 		 index = 0;
    HPALETTE16		 hPal = (dc)? dc->w.hPalette: STOCK_DEFAULT_PALETTE;
    unsigned char	 spec_type = color >> 24;
    PALETTEOBJ* 	 palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );

    if ( cSpace.flags & COLOR_FIXED )
    {
        /* there is no colormap limitation; we are going to have to compute
         * the pixel value from the visual information stored earlier 
	 */

	unsigned 	long red, green, blue;
	unsigned 	idx = 0;

	switch(spec_type)
        {
          case 2: /* PALETTERGB - not sure if we really need to search palette */
	
	    idx = COLOR_PaletteLookupPixel( palPtr->logpalette.palPalEntry,
					    palPtr->logpalette.palNumEntries,
					    NULL, color, FALSE);

            if( palPtr->mapping )
	    {
	        GDI_HEAP_UNLOCK( hPal );
		return palPtr->mapping[idx];
	    }

	    color = *(COLORREF*)(palPtr->logpalette.palPalEntry + idx);
	    break;

          case 1: /* PALETTEINDEX */

            if( (idx = color & 0xffff) >= palPtr->logpalette.palNumEntries)
            {
                WARN(palette, "RGB(%lx) : idx %d is out of bounds, assuming black\n", color, idx);
		GDI_HEAP_UNLOCK( hPal );
                return 0;
            }

            if( palPtr->mapping ) 
	    {
		GDI_HEAP_UNLOCK( hPal );
		return palPtr->mapping[idx];
	    }
	    color = *(COLORREF*)(palPtr->logpalette.palPalEntry + idx);
	    break;

	  default:
	    color &= 0xffffff;
	    /* fall through to RGB */

	  case 0: /* RGB */
	    if( dc && (dc->w.bitsPerPixel == 1) )
	    {
		GDI_HEAP_UNLOCK( hPal );
		return (((color >> 16) & 0xff) +
			((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0;
	    }

	}

        red = GetRValue(color); green = GetGValue(color); blue = GetBValue(color);

	if (COLOR_Graymax)
        {
	    /* grayscale only; return scaled value */
	    GDI_HEAP_UNLOCK( hPal );
            return ( (red * 30 + green * 69 + blue * 11) * COLOR_Graymax) / 25500;
	}
	else
        {
	    /* scale each individually and construct the TrueColor pixel value */
	    if (COLOR_Redmax != 255) red = (red * COLOR_Redmax) / 255;
            if (COLOR_Greenmax != 255) green = (green * COLOR_Greenmax) / 255;
	    if (COLOR_Bluemax != 255) blue = (blue * COLOR_Bluemax) / 255;

	    GDI_HEAP_UNLOCK( hPal );
	    return (red << COLOR_Redshift) | (green << COLOR_Greenshift) | (blue << COLOR_Blueshift);
        }
    }
    else 
    {

	/* palPtr can be NULL when DC is being destroyed */

	if( !palPtr ) return 0;
	else if( !palPtr->mapping ) 
            WARN(palette, "Palette %04x is not realized\n", dc->w.hPalette);

	switch(spec_type)	/* we have to peruse DC and system palette */
    	{
	    default:
		color &= 0xffffff;
		/* fall through to RGB */

       	    case 0:  /* RGB */
		if( dc && (dc->w.bitsPerPixel == 1) )
		{
		    GDI_HEAP_UNLOCK( hPal );
		    return (((color >> 16) & 0xff) +
			    ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0;
		}

	    	index = COLOR_PaletteLookupPixel( COLOR_sysPal, 256, 
						  COLOR_PaletteToPixel, color, FALSE);

		/* TRACE(palette,"RGB(%lx) -> pixel %i\n", color, index);
		 */
	    	break;
       	    case 1:  /* PALETTEINDEX */
		index = color & 0xffff;

	        if( index >= palPtr->logpalette.palNumEntries )
		    WARN(palette, "RGB(%lx) : index %i is out of bounds\n", color, index); 
		else if( palPtr->mapping ) index = palPtr->mapping[index];

		/*  TRACE(palette,"PALETTEINDEX(%04x) -> pixel %i\n", (WORD)color, index);
		 */
		break;
            case 2:  /* PALETTERGB */
		index = COLOR_PaletteLookupPixel( palPtr->logpalette.palPalEntry, 
                                             palPtr->logpalette.palNumEntries,
                                             palPtr->mapping, color, FALSE);
		/* TRACE(palette,"PALETTERGB(%lx) -> pixel %i\n", color, index);
		 */
		break;
	}
    }

    GDI_HEAP_UNLOCK( hPal );
    return index;
}

/***********************************************************************
 *           COLOR_SetMapping
 *
 * Set the color-mapping table for selected palette. 
 * Return number of entries which mapping has changed.
 */
int COLOR_SetMapping( PALETTEOBJ* palPtr, UINT uStart, UINT uNum, BOOL mapOnly )
{
    char flag;
    int  prevMapping = (palPtr->mapping) ? 1 : 0;
    int  index, iRemapped = 0;

    /* reset dynamic system palette entries */

    if( !mapOnly && COLOR_firstFree != -1)
         COLOR_FormatSystemPalette();

    /* initialize palette mapping table */
 
    palPtr->mapping = (int*)xrealloc(palPtr->mapping, sizeof(int)*
                                     palPtr->logpalette.palNumEntries);

    for( uNum += uStart; uStart < uNum; uStart++ )
    {
        index = -1;
        flag = PC_SYS_USED;

        switch( palPtr->logpalette.palPalEntry[uStart].peFlags & 0x07 )
        {
	case PC_EXPLICIT:   /* palette entries are indices into system palette */
            index = *(WORD*)(palPtr->logpalette.palPalEntry + uStart);
            if( index > 255 || (index >= COLOR_gapStart && index <= COLOR_gapEnd) ) 
            {
                WARN(palette,"PC_EXPLICIT: idx %d out of system palette, assuming black.\n", index); 
                index = 0;
            }
            break;

	case PC_RESERVED:   /* forbid future mappings to this entry */
            flag |= PC_SYS_RESERVED;

            /* fall through */
	default:	    /* try to collapse identical colors */
            index = COLOR_PaletteLookupExactIndex(COLOR_sysPal, 256,  
                             *(COLORREF*)(palPtr->logpalette.palPalEntry + uStart));
            /* fall through */
	case PC_NOCOLLAPSE: 
            if( index < 0 )
            {
                if( COLOR_firstFree > 0 && !(cSpace.flags & COLOR_FIXED) )
                {
                    XColor color;
                    index = COLOR_firstFree;  /* ought to be available */
                    COLOR_firstFree = COLOR_freeList[index];

                    color.pixel = (COLOR_PaletteToPixel) ? COLOR_PaletteToPixel[index] : index;
                    color.red = palPtr->logpalette.palPalEntry[uStart].peRed << 8;
                    color.green = palPtr->logpalette.palPalEntry[uStart].peGreen << 8;
                    color.blue = palPtr->logpalette.palPalEntry[uStart].peBlue << 8;
                    color.flags = DoRed | DoGreen | DoBlue;
                    TSXStoreColor(display, cSpace.colorMap, &color);

                    COLOR_sysPal[index] = palPtr->logpalette.palPalEntry[uStart];
                    COLOR_sysPal[index].peFlags = flag;
		    COLOR_freeList[index] = 0;

                    if( COLOR_PaletteToPixel ) index = COLOR_PaletteToPixel[index];
                    break;
                }
                else if ( cSpace.flags & COLOR_VIRTUAL ) 
                {
                    index = COLOR_ToPhysical( NULL, 0x00ffffff &
                             *(COLORREF*)(palPtr->logpalette.palPalEntry + uStart));
                    break;     
                }

                /* we have to map to existing entry in the system palette */

                index = COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, 
                       *(COLORREF*)(palPtr->logpalette.palPalEntry + uStart), TRUE);
            }
	    palPtr->logpalette.palPalEntry[uStart].peFlags |= PC_SYS_USED;

            if( COLOR_PaletteToPixel ) index = COLOR_PaletteToPixel[index];
            break;
        }

        if( !prevMapping || palPtr->mapping[uStart] != index ) iRemapped++;
        palPtr->mapping[uStart] = index;

        TRACE(palette,"entry %i (%lx) -> pixel %i\n", uStart, 
				*(COLORREF*)(palPtr->logpalette.palPalEntry + uStart), index);
	
    }
    return iRemapped;
}

