1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
14 #include "basedisplay.hh"
17 BColor::ColorCache BColor::colorcache;
18 bool BColor::cleancache = false;
20 BColor::BColor(const BaseDisplay * const _display, unsigned int _screen)
21 : allocated(false), r(-1), g(-1), b(-1), p(0), dpy(_display), scrn(_screen)
24 BColor::BColor(int _r, int _g, int _b,
25 const BaseDisplay * const _display, unsigned int _screen)
26 : allocated(false), r(_r), g(_g), b(_b), p(0), dpy(_display), scrn(_screen)
30 BColor::BColor(const std::string &_name,
31 const BaseDisplay * const _display, unsigned int _screen)
32 : allocated(false), r(-1), g(-1), b(-1), p(0), dpy(_display), scrn(_screen),
38 BColor::~BColor(void) {
43 void BColor::setDisplay(const BaseDisplay * const _display,
44 unsigned int _screen) {
45 if (_display == display() && _screen == screen()) {
55 if (! colorname.empty()) {
61 unsigned long BColor::pixel(void) const {
64 BColor *that = (BColor *) this;
72 void BColor::parseColorName(void) {
75 if (colorname.empty()) {
76 fprintf(stderr, "BColor: empty colorname, cannot parse (using black)\n");
81 scrn = DefaultScreen(display()->getXDisplay());
82 Colormap colormap = display()->getScreenInfo(scrn)->getColormap();
84 // get rgb values from colorname
91 if (! XParseColor(display()->getXDisplay(), colormap,
92 colorname.c_str(), &xcol)) {
93 fprintf(stderr, "BColor::allocate: color parse error: \"%s\"\n",
99 setRGB(xcol.red >> 8, xcol.green >> 8, xcol.blue >> 8);
103 void BColor::allocate(void) {
106 if (scrn == ~(0u)) scrn = DefaultScreen(display()->getXDisplay());
107 Colormap colormap = display()->getScreenInfo(scrn)->getColormap();
110 if (colorname.empty()) {
111 fprintf(stderr, "BColor: cannot allocate invalid color (using black)\n");
118 // see if we have allocated this color before
119 RGB rgb(display(), scrn, r, g, b);
120 ColorCache::iterator it = colorcache.find(rgb);
121 if (it != colorcache.end()) {
125 (*it).second.count++;
129 // allocate color from rgb values
131 xcol.red = r | r << 8;
132 xcol.green = g | g << 8;
133 xcol.blue = b | b << 8;
136 if (! XAllocColor(display()->getXDisplay(), colormap, &xcol)) {
137 fprintf(stderr, "BColor::allocate: color alloc error: rgb:%x/%x/%x\n",
145 colorcache.insert(ColorCacheItem(rgb, PixelRef(p)));
152 void BColor::deallocate(void) {
158 ColorCache::iterator it = colorcache.find(RGB(display(), scrn, r, g, b));
159 if (it != colorcache.end()) {
160 if ((*it).second.count >= 1)
161 (*it).second.count--;
171 BColor &BColor::operator=(const BColor &c) {
174 setRGB(c.r, c.g, c.b);
175 colorname = c.colorname;
182 void BColor::cleanupColorCache(void) {
187 void BColor::doCacheCleanup(void) {
188 // ### TODO - support multiple displays!
189 ColorCache::iterator it = colorcache.begin();
190 if (it == colorcache.end()) {
195 const BaseDisplay* const display = (*it).first.display;
196 unsigned long *pixels = new unsigned long[ colorcache.size() ];
197 unsigned int i, count;
199 for (i = 0; i < display->getNumberOfScreens(); i++) {
201 it = colorcache.begin();
203 while (it != colorcache.end()) {
204 if ((*it).second.count != 0 || (*it).first.screen != i) {
209 pixels[ count++ ] = (*it).second.p;
210 ColorCache::iterator it2 = it;
212 colorcache.erase(it2);
216 XFreeColors(display->getXDisplay(),
217 display->getScreenInfo(i)->getColormap(),