summaryrefslogtreecommitdiff
path: root/otk/rendercolor.cc
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-01-20 07:07:13 +0000
committerDana Jansens <danakj@orodu.net>2003-01-20 07:07:13 +0000
commit0348a2f3abd2334f5f5812c5fb45c1b4fffb46a5 (patch)
treef19e07f899a3e390dbc8f2484d6b1426defcbb47 /otk/rendercolor.cc
parentcfd8f9a65848c5e7b0514999581512069a4f98f6 (diff)
add rendercolor class, with a cache of gcs for the colors
Diffstat (limited to 'otk/rendercolor.cc')
-rw-r--r--otk/rendercolor.cc83
1 files changed, 83 insertions, 0 deletions
diff --git a/otk/rendercolor.cc b/otk/rendercolor.cc
new file mode 100644
index 00000000..99dd3341
--- /dev/null
+++ b/otk/rendercolor.cc
@@ -0,0 +1,83 @@
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif // HAVE_CONFIG_H
+
+#include "rendercolor.hh"
+#include "display.hh"
+#include "screeninfo.hh"
+
+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),
+ _gc(0)
+{
+ 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;
+ ++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; xcol.red |= xcol.red << 8;
+ xcol.green = _green; xcol.green |= xcol.green << 8;
+ xcol.blue = _blue; xcol.blue |= xcol.blue << 8;
+ xcol.pixel = 0;
+
+ if (! XAllocColor(**display, info->colormap(), &xcol)) {
+ fprintf(stderr, "RenderColor: color alloc error: rgb:%x/%x/%x\n",
+ _red, _green, _blue);
+ xcol.pixel = 0;
+ }
+
+ gcv.foreground = xcol.pixel;
+ _gc = XCreateGC(**display, info->rootWindow(), GCForeground, &gcv);
+ assert(_gc);
+
+ // insert into the cache
+ _cache[_screen][color] = new CacheItem(_gc);
+ }
+}
+
+RenderColor::~RenderColor()
+{
+ unsigned long color = _blue | _green << 8 | _red << 16;
+
+ CacheItem *item = _cache[_screen][color];
+ assert(item); // it better be in the cache ...
+
+ if (--item->count <= 0) {
+ // remove from the cache
+ XFreeGC(**display, _gc);
+ _cache[_screen][color] = 0;
+ delete item;
+ }
+}
+
+}