#ifndef CODE_XCOLORS_CXX
#define CODE_XCOLORS_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: Xcolors.cxx,v 1.2 1999/12/27 01:24:54 schmitzj Exp $)
 * 
 * Copyright (C) 1998 Jürgen Schmitz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *-----------------------------------------------------------------------
 */

#include "types.h"
#include <Xclasses/Xdisplay.h>
#include <Xclasses/Xcolors.h>
#include "include/Xcolors_p.h"
#include <string.h>

static int forceSW=0;
static int xcol_used=0;
static int ownCM=0;
Colormap cmap=0;
Xcolors *baseXcolors=NULL;
static Visual *vis=NULL;
static struct ColorPens pens;
static struct ColorAlloced *cols=NULL;
static unsigned long colnum=0;
static unsigned long colmem=0;

#define COLBLOCK	10

static long getclosecolor(class Xdisplay *d,int r,int g,int b)
{
	if (vis)
	{
		if (vis->
#if defined(__cplusplus) || defined(c_plusplus)
				c_class        	
#else
				class
#endif
			!=DirectColor)
		{
			XColor *cols;
			int ncols;
			int rdif=0xffff,gdif=0xffff,bdif=0xffff,idif=-1;

			ncols=vis->map_entries;
			if (cols=new XColor[ncols])
			{
				for(int i=0;i<ncols;i++)
					cols[i].pixel=i;
				XQueryColors(d->display(), cmap, cols, ncols);

				for(int i=0;i<ncols;i++)
				{
					if (abs(cols[i].red-r)<=rdif
					  &&abs(cols[i].green-g)<=gdif
					  &&abs(cols[i].blue-b)<=bdif)
					{
						idif=i;
						rdif=abs(cols[i].red-r);
						gdif=abs(cols[i].green-g);
						bdif=abs(cols[i].blue-b);
					}
				}
				r=0;
				XColor c;
				if (idif>=0)
				{
					c=cols[idif];
					r=XAllocColor(d->display(),cmap,&c);
				}
				delete cols;
				if (r) return c.pixel;
			}
		}
	}
	return -1;
}
static long getcolor(class Xdisplay *d,int r,int g,int b)
{
	XColor c;
	int ret=0;

	c.flags	=DoRed|DoGreen|DoBlue;
	c.red	=r;
	c.green	=g;
	c.blue	=b;

	if (XAllocColor(d->display(),cmap,&c)) return c.pixel;

	char buf[40];
//	sprintf(buf,"Can't get color #%02x%02x%02x",r>>8,g>>8,b>>8);
//	warn_printf(buf,d);

	if ((ret=getclosecolor(d,r,g,b))>=0) return ret;
	sprintf(buf,"Can't get close color #%02x%02x%02x",r>>8,g>>8,b>>8);
	warn_printf(buf,d);

	return -1;
}
static long AllocColor(class Xdisplay *d,unsigned short r,unsigned short g,unsigned short b)
{
	if (cmap)
	{
		long c;
		for(int i=1;i<=colnum;i++)
		{
			if (cols[i-1].red==r && cols[i-1].green==g && cols[i-1].blue==b)
			{
				cols[i-1].count++;
				return cols[i-1].color;
			}
		}
		
		c=getcolor(d,r,g,b);
		if (c<0)
		{
			if (r!=0 || g!=0 || b!=0)
				return AllocColor(d,0,0,0);
			else
				return 0;
		}
		if (!cols)
		{
			if (cols=new ColorAlloced[COLBLOCK])
			{
				colmem=COLBLOCK;
				colnum++;
				cols[0].red=r;
				cols[0].green=g;
				cols[0].blue=b;
				cols[0].count=1;
				cols[0].color=c;
				return c;
			}
		}
		if (colnum+1>COLBLOCK)
		{
			struct ColorAlloced *c1;
			int i;
			if (c1=new ColorAlloced[colmem+COLBLOCK])
			{
				for (i=0;i<colnum;i++) c1[i]=cols[i];
				colmem+=COLBLOCK;
				delete [] cols;
				cols=c1;
			}
			else
			{
				return c;
			}
		}
		cols[colnum].red=r;
		cols[colnum].green=g;
		cols[colnum].blue=b;
		cols[colnum].count=1;
		cols[colnum].color=c;
		colnum++;
		return c;
	}
	if (cmap && (r!=0 || g!=0 || b!=0))
		return AllocColor(d,0,0,0);
	else
		return 0;
}
static void FreeColor(class Xdisplay *d,unsigned long c)
{
	for(int i=1;i<=colnum;i++)
	{
		if (cols[i-1].color==c)
		{
			cols[i-1].count--;
			if (cmap && cols[i-1].count==0)
			{
				if (cols[i-1].color>=0) XFreeColors(d->display(),cmap,(unsigned long*)&cols[i-1].color,1,0);
				for(int j=i-1;j<colnum-1;j++)
				{
					cols[j]=cols[j+1];
				}		
				colnum--;
			}
			break;
		}
	}
}
static void FreeColors(class Xdisplay *d)
{
	for(int i=1;i<=colnum;i++)
	{
		if (cmap && cols[i-1].color>=0)
		{
			XFreeColors(d->display(),cmap,(unsigned long*)&cols[i-1].color,1,0);
			XSync(d->display(),0);
		}
	}
	delete [] cols;
	cols=NULL;
	colnum=0;
	colmem=0;
}

pXcolors::pXcolors(void)
{
	pens.base_red  =0xA0A0;
	pens.base_green=0xA0A0;
	pens.base_blue =0xA0A0;
	colnum=0; colmem=0;
	cols=NULL;
	ppens=NULL;
}
pXcolors::~pXcolors(void)
{
	if (ppens) delete ppens;
	ppens=NULL;
}
Xcolors::Xcolors(void) : Xdisplay()
{
	while (!(p=new pXcolors))
	{
		outOfMemory("Xcolors");
	}
	p->o=this;
	if (!baseXcolors) baseXcolors=this;
	Name("Xcolors");
	xcol_used++;
}
Xcolors::~Xcolors(void)
{
	xcol_used--;
	Close();
	if (p) delete p;			
}
unsigned short pXcolors::mixr(int r)
{
	r+=(ppens?ppens->base_red:pens.base_red);
	if (r<0) r=0;
	if (r>0xffff) r=0xffff;
	return (unsigned short)r;
}
unsigned short pXcolors::mixg(int g)
{
	g+=(ppens?ppens->base_green:pens.base_green);
	if (g<0) g=0;
	if (g>0xffff) g=0xffff;
	return (unsigned short)g;
}
unsigned short pXcolors::mixb(int b)
{
	b+=(ppens?ppens->base_blue:pens.base_blue);
	if (b<0) b=0;
	if (b>0xffff) b=0xffff;
	return (unsigned short)b;
}

// unsigned long pXcolors::getcolor(int r,int g,int b)
// {
// 	XColor c;
// 
// 	c.flags	=DoRed|DoGreen|DoBlue;
// 	c.red	=r;
// 	c.green	=g;
// 	c.blue	=b;
// 	
// 	if (XAllocColor(o->display(),cmap,&c)) return c.pixel;
// 	
// 	return pens.Xblack;
// }
void Xcolors::SetBase(int r,int g,int b)
{
	pens.base_red=r;
	pens.base_green=g;
	pens.base_blue=b;
}
void Xcolors::SetBase(char *colname)
{
	XColor c;
	Colormap cmap;
	
	c.flags=DoRed|DoGreen|DoBlue;
	
	cmap=DefaultColormap(display(),screen());
	if (XParseColor(display(),cmap,colname,&c))
	{
		pens.base_red=c.red;
		pens.base_green=c.green;
		pens.base_blue=c.blue;
	}	
}
//#define COLTEST(com)	if ((com)==0) { farbeSW(this); break; }
#define COLTEST(com)	com
static void farbeSW(class Xdisplay *d)
{
	pens.cclass=0;
	pens.Xbackground		=::AllocColor(d,0xffff,0xffff,0xffff); //pens.Xwhite;
	pens.Xdarkbackground	=::AllocColor(d,0xffff,0xffff,0xffff); //pens.Xwhite;
	pens.Xshinebackground	=::AllocColor(d,0xffff,0xffff,0xffff); //pens.Xwhite;
	pens.Xmarkbackground	=::AllocColor(d,0xffff,0xffff,0xffff); //pens.Xwhite;
	pens.Xselected			=::AllocColor(d,0,0,0); //pens.Xblack;
	pens.Xactive			=::AllocColor(d,0,0,0); //pens.Xblack;
	pens.Xshine				=::AllocColor(d,0,0,0); //pens.Xblack;
	pens.Xshadow			=::AllocColor(d,0,0,0); //pens.Xblack;
	pens.Xshine2			=::AllocColor(d,0,0,0); //pens.Xblack;
	pens.Xshadow2			=::AllocColor(d,0,0,0); //pens.Xblack;
	pens.Xtext				=::AllocColor(d,0,0,0); //pens.Xblack;
	pens.Xhitext			=::AllocColor(d,0,0,0); //pens.Xblack;
	pens.Xselectedtext		=::AllocColor(d,0xffff,0xffff,0xffff); //pens.Xwhite;
}
int Xcolors::Init(void)
{
	if (!cmap)
	{
//	    pens.Xwhite=WhitePixel(display(),screen()); 
//    	pens.Xblack=BlackPixel(display(),screen()); 
    	
		if (cmap=DefaultColormap(display(),screen()))
		{
			if (ownCM)
			{
				Colormap ocmap;
				if (ocmap=XCopyColormapAndFree(display(),cmap))
					cmap=ocmap;
				else
					ownCM=0;
			}
			int v;

			pens.Xwhite=::AllocColor(this,0xffff,0xffff,0xffff);
			pens.Xblack=::AllocColor(this,0,0,0);

			pens.depth=DefaultDepth(display(),screen());					
        	vis=DefaultVisual(display(),screen());
        	v=vis->
#if defined(__cplusplus) || defined(c_plusplus)
                        c_class        	
#else
                        class
#endif
							;
			if (forceSW) v=0;

			switch(v)
			{
				case PseudoColor:
				case DirectColor:
				case TrueColor:
					// "bunte" Farben anfordern
					pens.cclass=1; 
					
					COLTEST(pens.Xbackground	=::AllocColor(this,p->mixr(0),p->mixg(0),p->mixb(0)));
					COLTEST(pens.Xdarkbackground=::AllocColor(this,p->mixr(-0x2222),p->mixg(-0x2222),p->mixb(-0x2222)));
					COLTEST(pens.Xmarkbackground=::AllocColor(this,p->mixr(0x3333),p->mixg(-0x2222),p->mixb(-0x2222)));
					COLTEST(pens.Xshinebackground=::AllocColor(this,p->mixr(+0x2222),p->mixg(+0x2222),p->mixb(+0x2222)));
					COLTEST(pens.Xselected		=::AllocColor(this,p->mixr(-0x1111),p->mixg(-0x1111),p->mixb(-0x1111)));
					COLTEST(pens.Xactive		=::AllocColor(this,p->mixr(0x4444),p->mixg(0x4444),p->mixb(0)));
					COLTEST(pens.Xshine			=::AllocColor(this,p->mixr(0x6666),p->mixg(0x6666),p->mixb(0x6666)));
					COLTEST(pens.Xshadow		=::AllocColor(this,p->mixr(-0x6666),p->mixg(-0x6666),p->mixb(-0x6666)));
					COLTEST(pens.Xshine2		=::AllocColor(this,p->mixr(0x3333),p->mixg(0x3333),p->mixb(0x3333)));
					COLTEST(pens.Xshadow2		=::AllocColor(this,p->mixr(-0x3333),p->mixg(-0x3333),p->mixb(-0x3333)));
					pens.Xtext			=::AllocColor(this,0,0,0);
					pens.Xhitext		=::AllocColor(this,0xffff,0xffff,0xffff);
					pens.Xselectedtext	=::AllocColor(this,0,0,0);
					
					break;
				case StaticColor:	// VGA16
					// "wenige" Farben anfordern
					pens.cclass=1; 
					
					COLTEST(pens.Xbackground	=::AllocColor(this,p->mixr(0),p->mixg(0),p->mixb(0)));
					COLTEST(pens.Xdarkbackground=::AllocColor(this,p->mixr(-0x6666),p->mixg(-0x6666),p->mixb(-0x6666)));
					COLTEST(pens.Xmarkbackground=::AllocColor(this,p->mixr(+0x5555),p->mixg(0x5555),p->mixb(0)));
					COLTEST(pens.Xshinebackground=::AllocColor(this,p->mixr(+0x3333),p->mixg(+0x3333),p->mixb(+0x3333)));
					COLTEST(pens.Xselected		=::AllocColor(this,p->mixr(-0x5555),p->mixg(-0x5555),p->mixb(-0x5555)));
					COLTEST(pens.Xactive		=::AllocColor(this,p->mixr(0x5555),p->mixg(0x5555),p->mixb(0)));
					COLTEST(pens.Xshine			=::AllocColor(this,p->mixr(0x6666),p->mixg(0x6666),p->mixb(0x6666)));
					COLTEST(pens.Xshadow		=::AllocColor(this,p->mixr(-0x6666),p->mixg(-0x6666),p->mixb(-0x6666)));
					COLTEST(pens.Xshine2		=::AllocColor(this,p->mixr(0x6666),p->mixg(0x6666),p->mixb(0x6666)));
					COLTEST(pens.Xshadow2		=::AllocColor(this,p->mixr(-0x6666),p->mixg(-0x6666),p->mixb(-0x6666)));
					pens.Xtext			=::AllocColor(this,0,0,0);
					pens.Xhitext		=::AllocColor(this,0xffff,0xffff,0xffff);
					pens.Xselectedtext	=::AllocColor(this,0xffff,0xffff,0xffff);
					
					break;
//				case GrayScale:
					// Grautoene anfordern
//					pens.cclass=2;
					
//					pens.Xbackground	=getcolor(r,g,b);
//					pens.Xdarkbackground=getcolor(r,g,b);					
//					pens.Xselected		=getcolor(r,g,b);
//					pens.Xactive		=getcolor(r,g,b);
//					pens.Xshine			=getcolor(r,g,b);
//					pens.Xshadow		=getcolor(r,g,b);
//					pens.Xtext			=getcolor(r,g,b);
//					pens.Xhitext		=getcolor(r,g,b);
//					pens.Xselectedtext	=getcolor(r,g,b);
										
//					break;
				default:
					// alles mit schwarz/weiss fuellen
					farbeSW(this);
					break;
			}
		}   				 	
		init_x_session(this);
	}
	return 1;
} 
int Xcolors::Init(char *dsp)
{
	if (Xdisplay::Init(dsp))
	{
		return Init();
	}
	return 0;
}

extern int NOKEY,BLACKBORDER;
int Xcolors::Init(int &argc,char *argv[])
{
	return Init(argc,argv,NULL);
}
int Xcolors::Init(int &argc,char *argv[],char *basecolor)
{
	if (Xdisplay::Init(argc,argv))
	{
		if (basecolor)
		{
			SetBase(basecolor);
		}
		int i=1;
		while (i<argc)
		{
			if (!strcasecmp(argv[i],"-blackwhite"))
			{
				forceSW=1;
				remarg(argc,argv,i);
				argc--;
			}
			else if (!strcasecmp(argv[i],"-basecolor"))
			{
				if (i+1<argc)
				{
					SetBase(argv[i+1]);
					remarg(argc,argv,i+1);
					argc--;
				}
				remarg(argc,argv,i);
				argc--;
			}
			else if (!strcasecmp(argv[i],"-privatecolor"))
			{
				ownCM=1;
				remarg(argc,argv,i);
				argc--;
			}
			else
			{
				i++;
			}
		}
		return Init();
	}
	return 0;
}
void Xcolors::Close(void)
{
// Farben freigeben
	if (xcol_used==0)
	{
		free_x_session(this);
	}
	if (p->cols)
	{
		for(int i=0;i<p->colnum;i++)
		{
			::FreeColor(this,p->cols[i]);	
		}
		delete [] p->cols;
		p->cols=NULL;
		p->colnum=0;
		p->colmem=0;
	}
	if (xcol_used==0)
	{
		FreeColors(this);
		if (ownCM) XFreeColormap(display(),cmap);
		cmap=0;
	}
	Xdisplay::Close();
}
Colormap Xcolors::Cmap(void)
{
	return cmap;
}
int Xcolors::ColMode(void)
{
	return pens.cclass;
}
unsigned long Xcolors::AllocColor(unsigned short r,unsigned short g,unsigned short b)
{
	if (cmap)
	{
		unsigned long c;
		
		c=::AllocColor(this,r,g,b);
		if (!p->cols)
		{
			if (p->cols=new unsigned long[COLBLOCK])
			{
				p->colmem=COLBLOCK;
				p->colnum++;
				p->cols[0]=c;
				return c;
			}
		}
		if (p->colnum+1>COLBLOCK)
		{
			unsigned long *c1;
			int i;
			if (c1=new unsigned long[p->colmem+COLBLOCK])
			{
				for (i=0;i<p->colnum;i++) c1[i]=p->cols[i];
				p->colmem+=COLBLOCK;
				delete p->cols;
				p->cols=c1;
			}
			else
			{
				return c;
			}
		}
		p->cols[p->colnum++]=c;
		return c;
	}	
	return pens.Xblack;
}
unsigned long Xcolors::AllocColor(char *n)
{
	unsigned long r=pens.Xblack;
	if (cmap)
	{
		XColor xc;
		char *name=strdup(n);

		xc.flags=DoRed|DoGreen|DoBlue;
		if (name[0]=='+' || name[0]=='-')
		{
			int blue =strtol(&name[7],NULL,16)<<8;
			if (name[6]=='-') blue=-blue;
			name[6]=0;
			int green=strtol(&name[4],NULL,16)<<8;
			if (name[3]=='-') green=-green;
			name[3]=0;
			int red  =strtol(&name[1],NULL,16)<<8;
			if (name[0]=='-') red=-red;
			r=AllocColor(p->mixr(red),p->mixg(green),p->mixb(blue));
		}
		else if (XParseColor(display(),cmap,name,&xc))
		{
			r=AllocColor(xc.red,xc.green,xc.blue);
		}
		free(name);
	}
	return r;
}
void Xcolors::FreeColor(unsigned long c)
{
	if (cmap)
	{
		int i,j;
		
		::FreeColor(this,c);		
		j=0; i=0;
		for(;i<p->colnum;)
		{
			p->cols[j]=p->cols[i];
			if (c && p->cols[i]!=c) j++; else c=0; 
			i++;
		}		
		if (!c) p->colnum--;
	}
}

void pXcolors::set_col(unsigned long c,char *colname)
{
	if (cmap)
		*((unsigned long*)((char*)ppens+c))=o->AllocColor(colname);
}

ColorPens *pXcolors::genPens(void)
{
	if (!ppens)
	{
		Xclasses *c1,*c2;
		char *col;
		ppens=new ColorPens;

		if (col=o->GetResource("basecolor"))
		{
			XColor c;
			Colormap cmap;
	
			c.flags=DoRed|DoGreen|DoBlue;
	
			cmap=DefaultColormap(o->display(),o->screen());
			if (col[0]=='+' || col[0]=='-')
			{
				c1=o;
				do
				{
					c2=c1;
					c1=c1->ParentClass();
				}
				while (c1 && c1!=c2 && !c1->IsClassType("Xcolors"));
				if (c1 && c1==c2)
				{
					fatal_printf("Looping object tree!\n",c1);
				}
				if (c1 && c1!=c2)
					*ppens=*(((Xcolors*)c1)->p->genPens());
				else
					*ppens=pens;

				int blue =strtol(&col[7],NULL,16)<<8;
				if (col[6]=='-') blue=-blue;
				col[6]=0;
				int green=strtol(&col[4],NULL,16)<<8;
				if (col[3]=='-') green=-green;
				col[3]=0;
				int red  =strtol(&col[1],NULL,16)<<8;
				if (col[0]=='-') red=-red;
				ppens->base_red  =mixr(red);
				ppens->base_green=mixg(green);
				ppens->base_blue =mixb(blue);
			}
			else if (XParseColor(o->display(),cmap,col,&c))
			{
				ppens->base_red  =c.red;
				ppens->base_green=c.green;
				ppens->base_blue =c.blue;
			}
			else
			{
				ppens->base_red  =0xA0A0;
				ppens->base_green=0xA0A0;
				ppens->base_blue =0xA0A0;
			}
			ppens->Xwhite=o->AllocColor(0xffff,0xffff,0xffff);
			ppens->Xblack=o->AllocColor(0,0,0);

			ppens->Xbackground	 =o->AllocColor(mixr(0),mixg(0),mixb(0));
			ppens->Xdarkbackground=o->AllocColor(mixr(-0x2222),mixg(-0x2222),mixb(-0x2222));
			ppens->Xmarkbackground=o->AllocColor(mixr(0x3333),mixg(-0x2222),mixb(-0x2222));
			ppens->Xshinebackground=o->AllocColor(mixr(+0x2222),mixg(+0x2222),mixb(+0x2222));
			ppens->Xselected	=o->AllocColor(mixr(-0x1111),mixg(-0x1111),mixb(-0x1111));
			ppens->Xactive		=o->AllocColor(mixr(0x4444),mixg(0x4444),mixb(0));
			ppens->Xshine		=o->AllocColor(mixr(0x6666),mixg(0x6666),mixb(0x6666));
			ppens->Xshadow		=o->AllocColor(mixr(-0x6666),mixg(-0x6666),mixb(-0x6666));
			ppens->Xshine2		=o->AllocColor(mixr(0x3333),mixg(0x3333),mixb(0x3333));
			ppens->Xshadow2		=o->AllocColor(mixr(-0x3333),mixg(-0x3333),mixb(-0x3333));
			ppens->Xtext		=o->AllocColor(0,0,0);
			ppens->Xhitext		=o->AllocColor(0xffff,0xffff,0xffff);
			ppens->Xselectedtext=o->AllocColor(0,0,0);
		}
		else
		{
			c1=o;
			do
			{
				c2=c1;
				c1=c1->ParentClass();
			}
			while (c1 && c1!=c2 && !c1->IsClassType("Xcolors"));
			if (c1 && c1==c2)
			{
				fatal_printf("Looping object tree!\n",c1);
			}
			if (c1 && c1!=c2)
				*ppens=*(((Xcolors*)c1)->p->genPens());
			else
				*ppens=pens;
		}
		if (col=o->GetResource("col_background"))
		{
			set_col(offsetof(ColorPens,Xbackground),col);
		}
		if (col=o->GetResource("col_darkbackground"))
		{
			set_col(offsetof(ColorPens,Xdarkbackground),col);
		}
		if (col=o->GetResource("col_markbackground"))
		{
			set_col(offsetof(ColorPens,Xmarkbackground),col);
		}
		if (col=o->GetResource("col_shinebackground"))
		{
			set_col(offsetof(ColorPens,Xshinebackground),col);
		}
		if (col=o->GetResource("col_selected"))
		{
			set_col(offsetof(ColorPens,Xselected),col);
		}
		if (col=o->GetResource("col_active"))
		{
			set_col(offsetof(ColorPens,Xactive),col);
		}
		if (col=o->GetResource("col_shine"))
		{
			set_col(offsetof(ColorPens,Xshine),col);
		}
		if (col=o->GetResource("col_shine2"))
		{
			set_col(offsetof(ColorPens,Xshine2),col);
		}
		if (col=o->GetResource("col_shadow"))
		{
			set_col(offsetof(ColorPens,Xshadow),col);
		}
		if (col=o->GetResource("col_shadow2"))
		{
			set_col(offsetof(ColorPens,Xshadow2),col);
		}
		if (col=o->GetResource("col_text"))
		{
			set_col(offsetof(ColorPens,Xtext),col);
		}
		if (col=o->GetResource("col_hitext"))
		{
			set_col(offsetof(ColorPens,Xhitext),col);
		}
		if (col=o->GetResource("col_selectedtext"))
		{
			set_col(offsetof(ColorPens,Xselectedtext),col);
		}
		if (col=o->GetResource("col_black"))
		{
			set_col(offsetof(ColorPens,Xblack),col);
		}
		if (col=o->GetResource("col_white"))
		{
			set_col(offsetof(ColorPens,Xwhite),col);
		}
	}
	return ppens;
}
unsigned long pXcolors::get_col(unsigned long offset)
{
	if (!ppens)
		genPens();
	return *((unsigned long*)((char*)ppens+offset));
}

unsigned long Xcolors::col_background(void) 	{ return p->get_col(offsetof(ColorPens,Xbackground)); };
unsigned long Xcolors::col_darkbackground(void)	{ return p->get_col(offsetof(ColorPens,Xdarkbackground)); };
unsigned long Xcolors::col_markbackground(void)	{ return p->get_col(offsetof(ColorPens,Xmarkbackground)); };
unsigned long Xcolors::col_shinebackground(void){ return p->get_col(offsetof(ColorPens,Xshinebackground)); };
unsigned long Xcolors::col_selected(void)		{ return p->get_col(offsetof(ColorPens,Xselected)); };
unsigned long Xcolors::col_active(void)			{ return p->get_col(offsetof(ColorPens,Xactive)); };
unsigned long Xcolors::col_shine(void)			{ return p->get_col(offsetof(ColorPens,Xshine)); };
unsigned long Xcolors::col_shadow(void)			{ return p->get_col(offsetof(ColorPens,Xshadow)); };
unsigned long Xcolors::col_shine2(void)			{ return p->get_col(offsetof(ColorPens,Xshine2)); };
unsigned long Xcolors::col_shadow2(void)		{ return p->get_col(offsetof(ColorPens,Xshadow2)); };
unsigned long Xcolors::col_text(void)			{ return p->get_col(offsetof(ColorPens,Xtext)); };
unsigned long Xcolors::col_hitext(void)			{ return p->get_col(offsetof(ColorPens,Xhitext)); };
unsigned long Xcolors::col_selectedtext(void)	{ return p->get_col(offsetof(ColorPens,Xselectedtext)); };
unsigned long Xcolors::col_white(void)			{ return p->get_col(offsetof(ColorPens,Xwhite)); };
unsigned long Xcolors::col_black(void)			{ return p->get_col(offsetof(ColorPens,Xblack)); };

#endif
