otk/rendercolor.cc (raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- #include "config.h" #include "rendercolor.hh" #include "display.hh" #include "screeninfo.hh" #include "rendercontrol.hh" #include <cstdio> namespace otk { std::map<unsigned long, RenderColor::CacheItem*> *RenderColor::_cache = 0; void RenderColor::initialize() { _cache = new std::map<unsigned long, CacheItem*>[ScreenCount(**display)]; } void RenderColor::destroy() { delete [] _cache; } RenderColor::RenderColor(int screen, unsigned char red, unsigned char green, unsigned char blue) : _screen(screen), _red(red), _green(green), _blue(blue) { create(); } RenderColor::RenderColor(int screen, RGB rgb) : _screen(screen), _red(rgb.r), _green(rgb.g), _blue(rgb.b) { create(); } void RenderColor::create() { unsigned long color = _blue | _green << 8 | _red << 16; // try get a gc from the cache CacheItem *item = _cache[_screen][color]; if (item) { _gc = item->gc; _pixel = item->pixel; ++item->count; } else { XGCValues gcv; // allocate a color and GC from the server const ScreenInfo *info = display->screenInfo(_screen); XColor xcol; // convert from 0-0xff to 0-0xffff xcol.red = (_red << 8) | _red; xcol.green = (_green << 8) | _green; xcol.blue = (_blue << 8) | _blue; display->renderControl(_screen)->allocateColor(&xcol); _pixel = xcol.pixel; gcv.foreground = _pixel; gcv.cap_style = CapProjecting; _gc = XCreateGC(**display, info->rootWindow(), GCForeground | GCCapStyle, &gcv); assert(_gc); // insert into the cache item = new CacheItem(_gc, _pixel); _cache[_screen][color] = item; ++item->count; } } RenderColor::~RenderColor() { unsigned long color = _blue | _green << 8 | _red << 16; CacheItem *item = _cache[_screen][color]; assert(item); // better be... if (--item->count <= 0) { // remove from the cache XFreeGC(**display, _gc); _cache[_screen][color] = 0; delete item; const ScreenInfo *info = display->screenInfo(_screen); XFreeColors(**display, info->colormap(), &_pixel, 1, 0); } } } |