00001
00002
00003 #ifdef HAVE_CONFIG_H
00004 # include "../config.h"
00005 #endif // HAVE_CONFIG_H
00006
00007 #include "rendercolor.hh"
00008 #include "display.hh"
00009 #include "screeninfo.hh"
00010
00011 extern "C" {
00012 #ifdef HAVE_STDIO_H
00013 # include <stdio.h>
00014 #endif
00015 }
00016
00017 namespace otk {
00018
00019 std::map<unsigned long, RenderColor::CacheItem*> *RenderColor::_cache = 0;
00020
00021 void RenderColor::initialize()
00022 {
00023 _cache = new std::map<unsigned long, CacheItem*>[ScreenCount(**display)];
00024 }
00025
00026 void RenderColor::destroy()
00027 {
00028 delete [] _cache;
00029 }
00030
00031 RenderColor::RenderColor(int screen, unsigned char red,
00032 unsigned char green, unsigned char blue)
00033 : _screen(screen),
00034 _red(red),
00035 _green(green),
00036 _blue(blue),
00037 _gc(0)
00038 {
00039 create();
00040 }
00041
00042 RenderColor::RenderColor(int screen, RGB rgb)
00043 : _screen(screen),
00044 _red(rgb.r),
00045 _green(rgb.g),
00046 _blue(rgb.b),
00047 _gc(0)
00048 {
00049 create();
00050 }
00051
00052 void RenderColor::create()
00053 {
00054 unsigned long color = _blue | _green << 8 | _red << 16;
00055
00056
00057 CacheItem *item = _cache[_screen][color];
00058
00059 if (item) {
00060 _gc = item->gc;
00061 _pixel = item->pixel;
00062 ++item->count;
00063 } else {
00064 XGCValues gcv;
00065
00066
00067 const ScreenInfo *info = display->screenInfo(_screen);
00068
00069 XColor xcol;
00070 xcol.red = _red; xcol.red |= xcol.red << 8;
00071 xcol.green = _green; xcol.green |= xcol.green << 8;
00072 xcol.blue = _blue; xcol.blue |= xcol.blue << 8;
00073 xcol.pixel = 0;
00074
00075 if (! XAllocColor(**display, info->colormap(), &xcol)) {
00076 fprintf(stderr, "RenderColor: color alloc error: rgb:%x/%x/%x\n",
00077 _red, _green, _blue);
00078 xcol.pixel = 0;
00079 }
00080
00081 _pixel = xcol.pixel;
00082 gcv.foreground = _pixel;
00083 gcv.cap_style = CapProjecting;
00084 _gc = XCreateGC(**display, info->rootWindow(),
00085 GCForeground | GCCapStyle, &gcv);
00086 assert(_gc);
00087
00088
00089 item = new CacheItem(_gc, _pixel);
00090 _cache[_screen][color] = item;
00091 ++item->count;
00092 }
00093 }
00094
00095 RenderColor::~RenderColor()
00096 {
00097 unsigned long color = _blue | _green << 8 | _red << 16;
00098
00099 CacheItem *item = _cache[_screen][color];
00100 assert(item);
00101
00102 if (--item->count <= 0) {
00103
00104 XFreeGC(**display, _gc);
00105 _cache[_screen][color] = 0;
00106 delete item;
00107 }
00108 }
00109
00110 }