1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
15 #include "screeninfo.hh"
19 BColor::ColorCache BColor::colorcache;
20 bool BColor::cleancache = false;
22 BColor::BColor(unsigned int _screen)
23 : allocated(false), r(-1), g(-1), b(-1), p(0), scrn(_screen)
26 BColor::BColor(int _r, int _g, int _b, unsigned int _screen)
27 : allocated(false), r(_r), g(_g), b(_b), p(0), scrn(_screen)
31 BColor::BColor(const std::string &_name, unsigned int _screen)
32 : allocated(false), r(-1), g(-1), b(-1), p(0), scrn(_screen),
38 BColor::~BColor(void) {
43 void BColor::setScreen(unsigned int _screen) {
44 if (_screen == screen()) {
53 if (! colorname.empty()) {
59 unsigned long BColor::pixel(void) const {
62 BColor *that = (BColor *) this;
70 void BColor::parseColorName(void) {
71 if (colorname.empty()) {
72 fprintf(stderr, "BColor: empty colorname, cannot parse (using black)\n");
77 scrn = DefaultScreen(OBDisplay::display);
78 Colormap colormap = OBDisplay::screenInfo(scrn)->colormap();
80 // get rgb values from colorname
87 if (! XParseColor(OBDisplay::display, colormap,
88 colorname.c_str(), &xcol)) {
89 fprintf(stderr, "BColor::allocate: color parse error: \"%s\"\n",
95 setRGB(xcol.red >> 8, xcol.green >> 8, xcol.blue >> 8);
99 void BColor::allocate(void) {
100 if (scrn == ~(0u)) scrn = DefaultScreen(OBDisplay::display);
101 Colormap colormap = OBDisplay::screenInfo(scrn)->colormap();
104 if (colorname.empty()) {
105 fprintf(stderr, "BColor: cannot allocate invalid color (using black)\n");
112 // see if we have allocated this color before
113 RGB rgb(scrn, r, g, b);
114 ColorCache::iterator it = colorcache.find(rgb);
115 if (it != colorcache.end()) {
119 (*it).second.count++;
123 // allocate color from rgb values
125 xcol.red = r | r << 8;
126 xcol.green = g | g << 8;
127 xcol.blue = b | b << 8;
130 if (! XAllocColor(OBDisplay::display, colormap, &xcol)) {
131 fprintf(stderr, "BColor::allocate: color alloc error: rgb:%x/%x/%x\n",
139 colorcache.insert(ColorCacheItem(rgb, PixelRef(p)));
146 void BColor::deallocate(void) {
150 ColorCache::iterator it = colorcache.find(RGB(scrn, r, g, b));
151 if (it != colorcache.end()) {
152 if ((*it).second.count >= 1)
153 (*it).second.count--;
163 BColor &BColor::operator=(const BColor &c) {
166 setRGB(c.r, c.g, c.b);
167 colorname = c.colorname;
173 void BColor::cleanupColorCache(void) {
178 void BColor::doCacheCleanup(void) {
179 // ### TODO - support multiple displays!
180 ColorCache::iterator it = colorcache.begin();
181 if (it == colorcache.end()) {
186 unsigned long *pixels = new unsigned long[ colorcache.size() ];
190 for (i = 0; i < ScreenCount(OBDisplay::display); i++) {
192 it = colorcache.begin();
194 while (it != colorcache.end()) {
195 if ((*it).second.count != 0 || (*it).first.screen != i) {
200 pixels[ count++ ] = (*it).second.p;
201 ColorCache::iterator it2 = it;
203 colorcache.erase(it2);
207 XFreeColors(OBDisplay::display,
208 OBDisplay::screenInfo(i)->colormap(),