#include #include #include #ifndef __color_mapper_h # include "color_mapper.H" #endif ColorMapper::ColorMapper(Display *dpy_in) : dpy(dpy_in) { Screen *screen = DefaultScreenOfDisplay(dpy); mymap=DefaultColormapOfScreen(screen); cells=0; colors=0; if (DefaultVisualOfScreen(screen)->c_class!=PseudoColor) return; cells=CellsOfScreen(screen); colors = new XColor[cells]; setup_usage(); } ColorMapper::~ColorMapper() { free_usage(); if (colors) delete [] colors; } void ColorMapper::free_usage() { int i; for (i=0;i not usefull } } else { colors[i].flags=0; // not allocatable -> not usefull } } } return; } unsigned long ColorMapper::alloc_color(XColor *def) { int i; long min_dist; int min_i; if (!colors) { def->flags=DoRed | DoGreen | DoBlue; if (!XAllocColor(dpy,mymap,def)) { fprintf( stderr, "\n*** failed to allocated color on '%s'\n\n", DisplayString(dpy) ); exit(0); } return def->pixel; } min_i=-1; min_dist=0; for (i=0;ired)/4; long gd = ((long)colors[i].green - (long)def->green)/4; long bd = ((long)colors[i].blue - (long)def->blue)/4; long dist=rd*rd+gd*gd+bd*bd; if (min_i<0 || dist=0 && min_dist<10000) { return colors[min_i].pixel; } // allocate additional entry for that pixel def->flags=DoRed | DoGreen | DoBlue; if (XAllocColor(dpy,mymap,def)) { colors[def->pixel] = *def; return def->pixel; } // allocate the closest entry if (min_i>=0) { return colors[min_i].pixel; } // everything else failed ... fprintf( stderr, "can't handle colormap overflow ...\n" ); exit(0); return 0; } unsigned long ColorMapper::alloc_named_color( const char *name ) { XColor def; if (!XLookupColor(dpy,mymap,name,&def,&def )) { fprintf( stderr, "\n*** failed to query color '%s'\n\n", name ); exit(0); } def.flags = DoRed | DoGreen | DoBlue; return alloc_color(&def); } // ============================================================================ Port::Port(Display *dpy_in) { dpy = dpy_in; mapper = new ColorMapper(dpy); } Port::~Port() { delete mapper; }