it compiles.. does it work?
This commit is contained in:
parent
607bf10d6d
commit
59b65db2ca
4 changed files with 684 additions and 0 deletions
321
otk_c/color.c
Normal file
321
otk_c/color.c
Normal file
|
@ -0,0 +1,321 @@
|
|||
// -*- mode: C; indent-tabs-mode: nil; -*-
|
||||
|
||||
#include "../config.h"
|
||||
#include "color.h"
|
||||
#include "display.h"
|
||||
#include "screeninfo.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static Bool cleancache = False;
|
||||
static PyObject *colorcache;
|
||||
|
||||
// global color allocator/deallocator
|
||||
typedef struct RGB {
|
||||
PyObject_HEAD
|
||||
int screen;
|
||||
int r, g, b;
|
||||
} RGB;
|
||||
|
||||
static void rgb_dealloc(PyObject* self)
|
||||
{
|
||||
PyObject_Del(self);
|
||||
}
|
||||
|
||||
static int rgb_compare(PyObject *py1, PyObject *py2)
|
||||
{
|
||||
long result;
|
||||
unsigned long p1, p2;
|
||||
RGB *r1, *r2;
|
||||
|
||||
r1 = (RGB*) r1;
|
||||
r2 = (RGB*) r2;
|
||||
p1 = (r1->screen << 24 | r1->r << 16 | r1->g << 8 | r1->b) & 0x00ffffff;
|
||||
p2 = (r2->screen << 24 | r2->r << 16 | r2->g << 8 | r2->b) & 0x00ffffff;
|
||||
|
||||
if (p1 < p2)
|
||||
result = -1;
|
||||
else if (p1 > p2)
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyTypeObject RGB_Type = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
"RGB",
|
||||
sizeof(RGB),
|
||||
0,
|
||||
rgb_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
rgb_compare, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash */
|
||||
};
|
||||
|
||||
static PyObject *RGB_New(int screen, int r, int g, int b) {
|
||||
RGB *self = (RGB*) PyObject_New(RGB, &RGB_Type);
|
||||
self->screen = screen;
|
||||
self->r = r;
|
||||
self->g = g;
|
||||
self->b = b;
|
||||
return (PyObject*)self;
|
||||
}
|
||||
|
||||
typedef struct PixelRef {
|
||||
unsigned long p;
|
||||
unsigned int count;
|
||||
} PixelRef;
|
||||
|
||||
static PixelRef *PixelRef_New(unsigned long p) {
|
||||
PixelRef* self = malloc(sizeof(PixelRef));
|
||||
self->p = p;
|
||||
self->count = 1;
|
||||
return self;
|
||||
}
|
||||
|
||||
static void OtkColor_ParseColorName(OtkColor *self) {
|
||||
XColor xcol;
|
||||
|
||||
if (!self->colorname) {
|
||||
fprintf(stderr, "OtkColor: empty colorname, cannot parse (using black)\n");
|
||||
OtkColor_SetRGB(self, 0, 0, 0);
|
||||
}
|
||||
|
||||
// get rgb values from colorname
|
||||
xcol.red = 0;
|
||||
xcol.green = 0;
|
||||
xcol.blue = 0;
|
||||
xcol.pixel = 0;
|
||||
|
||||
if (!XParseColor(OBDisplay->display, self->colormap,
|
||||
PyString_AsString(self->colorname), &xcol)) {
|
||||
fprintf(stderr, "BColor::allocate: color parse error: \"%s\"\n",
|
||||
PyString_AsString(self->colorname));
|
||||
OtkColor_SetRGB(self, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
OtkColor_SetRGB(self, xcol.red >> 8, xcol.green >> 8, xcol.blue >> 8);
|
||||
}
|
||||
|
||||
static void OtkColor_DoCacheCleanup() {
|
||||
unsigned long *pixels;
|
||||
int i;
|
||||
unsigned int count;
|
||||
PyObject *rgb, *pixref;
|
||||
int ppos;
|
||||
|
||||
// ### TODO - support multiple displays!
|
||||
if (!PyDict_Size(colorcache)) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
pixels = malloc(sizeof(unsigned long) * PyDict_Size(colorcache));
|
||||
|
||||
for (i = 0; i < ScreenCount(OBDisplay->display); i++) {
|
||||
count = 0;
|
||||
ppos = 0;
|
||||
|
||||
while (PyDict_Next(colorcache, &ppos, &rgb, &pixref)) {
|
||||
if (((PixelRef*)pixref)->count != 0 || ((RGB*)rgb)->screen != i)
|
||||
continue;
|
||||
|
||||
pixels[count++] = ((PixelRef*)pixref)->p;
|
||||
PyDict_DelItem(colorcache, rgb);
|
||||
free(pixref); // not really a PyObject, it just pretends
|
||||
--ppos; // back up one in the iteration
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
XFreeColors(OBDisplay->display,
|
||||
OtkDisplay_ScreenInfo(OBDisplay, i)->colormap,
|
||||
pixels, count, 0);
|
||||
}
|
||||
|
||||
free(pixels);
|
||||
cleancache = False;
|
||||
}
|
||||
|
||||
static void OtkColor_Allocate(OtkColor *self) {
|
||||
XColor xcol;
|
||||
PyObject *rgb, *pixref;
|
||||
|
||||
if (!OtkColor_IsValid(self)) {
|
||||
if (!self->colorname) {
|
||||
fprintf(stderr, "BColor: cannot allocate invalid color (using black)\n");
|
||||
OtkColor_SetRGB(self, 0, 0, 0);
|
||||
} else {
|
||||
OtkColor_ParseColorName(self);
|
||||
}
|
||||
}
|
||||
|
||||
// see if we have allocated this color before
|
||||
rgb = RGB_New(self->screen, self->red, self->green, self->blue);
|
||||
pixref = PyDict_GetItem((PyObject*)colorcache, rgb);
|
||||
if (pixref) {
|
||||
// found
|
||||
self->allocated = True;
|
||||
self->pixel = ((PixelRef*)pixref)->p;
|
||||
((PixelRef*)pixref)->count++;
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate color from rgb values
|
||||
xcol.red = self->red | self->red << 8;
|
||||
xcol.green = self->green | self->green << 8;
|
||||
xcol.blue = self->blue | self->blue << 8;
|
||||
xcol.pixel = 0;
|
||||
|
||||
if (!XAllocColor(OBDisplay->display, self->colormap, &xcol)) {
|
||||
fprintf(stderr, "BColor::allocate: color alloc error: rgb:%x/%x/%x\n",
|
||||
self->red, self->green, self->blue);
|
||||
xcol.pixel = 0;
|
||||
}
|
||||
|
||||
self->pixel = xcol.pixel;
|
||||
self->allocated = True;
|
||||
|
||||
PyDict_SetItem(colorcache, rgb, (PyObject*)PixelRef_New(self->pixel));
|
||||
|
||||
if (cleancache)
|
||||
OtkColor_DoCacheCleanup();
|
||||
}
|
||||
|
||||
static void OtkColor_Deallocate(OtkColor *self) {
|
||||
PyObject *rgb, *pixref;
|
||||
|
||||
if (!self->allocated)
|
||||
return;
|
||||
|
||||
rgb = RGB_New(self->screen, self->red, self->green, self->blue);
|
||||
pixref = PyDict_GetItem(colorcache, rgb);
|
||||
if (pixref) {
|
||||
if (((PixelRef*)pixref)->count >= 1)
|
||||
((PixelRef*)pixref)->count--;
|
||||
}
|
||||
|
||||
if (cleancache)
|
||||
OtkColor_DoCacheCleanup();
|
||||
|
||||
self->allocated = False;
|
||||
}
|
||||
|
||||
|
||||
OtkColor *OtkColor_New(int screen)
|
||||
{
|
||||
OtkColor *self = malloc(sizeof(OtkColor));
|
||||
|
||||
self->allocated = False;
|
||||
self->red = -1;
|
||||
self->green = -1;
|
||||
self->blue = -1;
|
||||
self->pixel = 0;
|
||||
self->screen = screen;
|
||||
self->colorname = NULL;
|
||||
self->colormap = OtkDisplay_ScreenInfo(OBDisplay, self->screen)->colormap;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
OtkColor *OtkColor_FromRGB(int r, int g, int b, int screen)
|
||||
{
|
||||
OtkColor *self = malloc(sizeof(OtkColor));
|
||||
|
||||
self->allocated = False;
|
||||
self->red = r;
|
||||
self->green = g;
|
||||
self->blue = b;
|
||||
self->pixel = 0;
|
||||
self->screen = screen;
|
||||
self->colorname = NULL;
|
||||
self->colormap = OtkDisplay_ScreenInfo(OBDisplay, self->screen)->colormap;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
OtkColor *OtkColor_FromName(const char *name, int screen)
|
||||
{
|
||||
OtkColor *self = malloc(sizeof(OtkColor));
|
||||
|
||||
self->allocated = False;
|
||||
self->red = -1;
|
||||
self->green = -1;
|
||||
self->blue = -1;
|
||||
self->pixel = 0;
|
||||
self->screen = screen;
|
||||
self->colorname = PyString_FromString(name);
|
||||
self->colormap = OtkDisplay_ScreenInfo(OBDisplay, self->screen)->colormap;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void OtkColor_Destroy(OtkColor *self)
|
||||
{
|
||||
if (self->colorname)
|
||||
Py_DECREF(self->colorname);
|
||||
free(self);
|
||||
}
|
||||
|
||||
void OtkColor_SetRGB(OtkColor *self, int r, int g, int b)
|
||||
{
|
||||
OtkColor_Deallocate(self);
|
||||
self->red = r;
|
||||
self->green = g;
|
||||
self->blue = b;
|
||||
}
|
||||
|
||||
void OtkColor_SetScreen(OtkColor *self, int screen)
|
||||
{
|
||||
if (screen == self->screen) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
Otk_Deallocate(self);
|
||||
|
||||
self->colormap = OtkDisplay_ScreenInfo(OBDisplay, self->screen)->colormap;
|
||||
|
||||
self->screen = screen;
|
||||
|
||||
if (self->colorname)
|
||||
parseColorName();
|
||||
}
|
||||
|
||||
Bool OtkColor_IsValid(OtkColor *self)
|
||||
{
|
||||
return self->red != -1 && self->blue != -1 && self->green != -1;
|
||||
}
|
||||
|
||||
unsigned long OtkColor_Pixel(OtkColor *self)
|
||||
{
|
||||
if (!self->allocated)
|
||||
OtkColor_Allocate(self);
|
||||
return self->pixel;
|
||||
}
|
||||
|
||||
void OtkColor_InitializeCache()
|
||||
{
|
||||
colorcache = PyDict_New();
|
||||
}
|
||||
|
||||
void OtkColor_DestroyCache()
|
||||
{
|
||||
Py_DECREF(colorcache);
|
||||
colorcache = NULL;
|
||||
}
|
||||
|
||||
void OtkColor_CleanupColorCache()
|
||||
{
|
||||
cleancache = True;
|
||||
}
|
33
otk_c/color.h
Normal file
33
otk_c/color.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||
#ifndef __color_h
|
||||
#define __color_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <Python.h>
|
||||
|
||||
|
||||
typedef struct OtkColor {
|
||||
int red, green, blue;
|
||||
int screen;
|
||||
Bool allocated;
|
||||
unsigned long pixel;
|
||||
PyObject *colorname; // PyStringObject
|
||||
Colormap colormap;
|
||||
} OtkColor;
|
||||
|
||||
OtkColor *OtkColor_New(int screen);
|
||||
OtkColor *OtkColor_FromRGB(int r, int g, int b, int screen);
|
||||
OtkColor *OtkColor_FromName(const char *name, int screen);
|
||||
|
||||
void OtkColor_Destroy(OtkColor *self);
|
||||
|
||||
void OtkColor_SetRGB(OtkColor *self, int r, int g, int b);
|
||||
void OtkColor_SetScreen(OtkColor *self, int screen);
|
||||
Bool OtkColor_IsValid(OtkColor *self);
|
||||
unsigned long OtkColor_Pixel(OtkColor *self);
|
||||
|
||||
void OtkColor_InitializeCache();
|
||||
void OtkColor_DestroyCache();
|
||||
void OtkColor_CleanupColorCache();
|
||||
|
||||
#endif // __color_h
|
232
otk_c/gccache.c
Normal file
232
otk_c/gccache.c
Normal file
|
@ -0,0 +1,232 @@
|
|||
// -*- mode: C; indent-tabs-mode: nil; -*-
|
||||
|
||||
#include "../config.h"
|
||||
#include "gccache.h"
|
||||
#include "screeninfo.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static OtkGCCache *gccache;
|
||||
|
||||
OtkGCCacheContext *OtkGCCacheContext_New()
|
||||
{
|
||||
OtkGCCacheContext *self = malloc(sizeof(OtkGCCacheContext));
|
||||
|
||||
self->gc = 0;
|
||||
self->pixel = 0ul;
|
||||
self->fontid = 0ul;
|
||||
self->function = 0;
|
||||
self->subwindow = 0;
|
||||
self->used = False;
|
||||
self->screen = ~0;
|
||||
self->linewidth = 0;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void OtkGCCacheContext_Destroy(OtkGCCacheContext *self)
|
||||
{
|
||||
if (self->gc)
|
||||
XFreeGC(OBDisplay->display, self->gc);
|
||||
free(self);
|
||||
}
|
||||
|
||||
void OtkGCCacheContext_Set(OtkGCCacheContext *self,
|
||||
OtkColor *color, XFontStruct *font,
|
||||
int function, int subwindow, int linewidth)
|
||||
{
|
||||
XGCValues gcv;
|
||||
unsigned long mask;
|
||||
|
||||
self->pixel = gcv.foreground = OtkColor_Pixel(color);
|
||||
self->function = gcv.function = function;
|
||||
self->subwindow = gcv.subwindow_mode = subwindow;
|
||||
self->linewidth = gcv.line_width = linewidth;
|
||||
gcv.cap_style = CapProjecting;
|
||||
|
||||
mask = GCForeground | GCFunction | GCSubwindowMode | GCLineWidth |
|
||||
GCCapStyle;
|
||||
|
||||
if (font) {
|
||||
self->fontid = gcv.font = font->fid;
|
||||
mask |= GCFont;
|
||||
} else {
|
||||
self->fontid = 0;
|
||||
}
|
||||
|
||||
XChangeGC(OBDisplay->display, self->gc, mask, &gcv);
|
||||
}
|
||||
|
||||
void OtkGCCacheContext_SetFont(OtkGCCacheContext *self,
|
||||
XFontStruct *font)
|
||||
{
|
||||
if (!font) {
|
||||
self->fontid = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
XGCValues gcv;
|
||||
self->fontid = gcv.font = font->fid;
|
||||
XChangeGC(OBDisplay->display, self->gc, GCFont, &gcv);
|
||||
}
|
||||
|
||||
|
||||
OtkGCCacheItem *OtkGCCacheItem_New()
|
||||
{
|
||||
OtkGCCacheItem *self = malloc(sizeof(OtkGCCacheItem));
|
||||
|
||||
self->ctx = 0;
|
||||
self->count = 0;
|
||||
self->hits = 0;
|
||||
self->fault = False;
|
||||
}
|
||||
|
||||
|
||||
void OtkGCCache_Initialize(int screen_count)
|
||||
{
|
||||
int i;
|
||||
|
||||
gccache = malloc(sizeof(OtkGCCache));
|
||||
|
||||
gccache->context_count = 128;
|
||||
gccache->cache_size = 16;
|
||||
gccache->cache_buckets = 8 * screen_count;
|
||||
gccache->cache_total_size = gccache->cache_size * gccache->cache_buckets;
|
||||
|
||||
gccache->contexts = malloc(sizeof(OtkGCCacheContext*) *
|
||||
gccache->context_count);
|
||||
for (i = 0; i < gccache->context_count; ++i)
|
||||
gccache->contexts[i] = OtkGCCacheContext_New();
|
||||
|
||||
gccache->cache = malloc(sizeof(OtkGCCacheItem*) * gccache->cache_total_size);
|
||||
for (i = 0; i < gccache->cache_total_size; ++i)
|
||||
gccache->cache[i] = OtkGCCacheItem_New();
|
||||
}
|
||||
|
||||
|
||||
void OtkGCCache_Destroy()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gccache->context_count; ++i)
|
||||
OtkGCCacheContext_Destroy(gccache->contexts[i]);
|
||||
|
||||
for (i = 0; i < gccache->cache_total_size; ++i)
|
||||
free(gccache->cache[i]);
|
||||
|
||||
free(gccache->contexts);
|
||||
free(gccache->cache);
|
||||
free(gccache);
|
||||
gccache = NULL;
|
||||
}
|
||||
|
||||
OtkGCCacheContext *OtkGCCache_NextContext(int screen)
|
||||
{
|
||||
Window hd = OtkDisplay_ScreenInfo(OBDisplay, screen)->root_window;
|
||||
OtkGCCacheContext *c;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gccache->context_count; ++i) {
|
||||
c = gccache->contexts[i];
|
||||
|
||||
if (! c->gc) {
|
||||
c->gc = XCreateGC(OBDisplay->display, hd, 0, 0);
|
||||
c->used = False;
|
||||
c->screen = screen;
|
||||
}
|
||||
if (! c->used && c->screen == screen)
|
||||
return c;
|
||||
}
|
||||
|
||||
fprintf(stderr, "OtkGCCache: context fault!\n");
|
||||
abort();
|
||||
return NULL; // shut gcc up
|
||||
}
|
||||
|
||||
|
||||
static void OtkGCCache_InternalRelease(OtkGCCacheContext *ctx)
|
||||
{
|
||||
ctx->used = False;
|
||||
}
|
||||
|
||||
OtkGCCacheItem *OtkGCCache_Find(OtkColor *color, XFontStruct *font,
|
||||
int function, int subwindow, int linewidth)
|
||||
{
|
||||
const unsigned long pixel = OtkColor_Pixel(color);
|
||||
const unsigned int screen = color->screen;
|
||||
const int key = color->red ^ color->green ^ color->blue;
|
||||
int k = (key % gccache->cache_size) * gccache->cache_buckets;
|
||||
int i = 0; // loop variable
|
||||
OtkGCCacheItem *c = gccache->cache[k], *prev = 0;
|
||||
|
||||
/*
|
||||
this will either loop cache_buckets times then return/abort or
|
||||
it will stop matching
|
||||
*/
|
||||
while (c->ctx &&
|
||||
(c->ctx->pixel != pixel || c->ctx->function != function ||
|
||||
c->ctx->subwindow != subwindow || c->ctx->screen != screen ||
|
||||
c->ctx->linewidth != linewidth)) {
|
||||
if (i < (gccache->cache_buckets - 1)) {
|
||||
prev = c;
|
||||
c = gccache->cache[++k];
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (c->count == 0 && c->ctx->screen == screen) {
|
||||
// use this cache item
|
||||
OtkGCCacheContext_Set(c->ctx, color, font, function, subwindow,
|
||||
linewidth);
|
||||
c->ctx->used = True;
|
||||
c->count = 1;
|
||||
c->hits = 1;
|
||||
return c;
|
||||
}
|
||||
// cache fault!
|
||||
fprintf(stderr, "OtkGCCache: cache fault, count: %d, screen: %d, item screen: %d\n", c->count, screen, c->ctx->screen);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (c->ctx) {
|
||||
// reuse existing context
|
||||
if (font && font->fid && font->fid != c->ctx->fontid)
|
||||
OtkGCCacheContext_SetFont(c->ctx, font);
|
||||
c->count++;
|
||||
c->hits++;
|
||||
if (prev && c->hits > prev->hits) {
|
||||
gccache->cache[k] = prev;
|
||||
gccache->cache[k-1] = c;
|
||||
}
|
||||
} else {
|
||||
c->ctx = OtkGCCache_NextContext(screen);
|
||||
OtkGCCacheContext_Set(c->ctx, color, font, function, subwindow, linewidth);
|
||||
c->ctx->used = True;
|
||||
c->count = 1;
|
||||
c->hits = 1;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void OtkGCCache_Release(OtkGCCacheItem *item)
|
||||
{
|
||||
item->count--;
|
||||
}
|
||||
|
||||
|
||||
void OtkGCCache_Purge()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gccache->cache_total_size; ++i) {
|
||||
OtkGCCacheItem *d = gccache->cache[i];
|
||||
|
||||
if (d->ctx && d->count == 0) {
|
||||
release(d->ctx);
|
||||
d->ctx = 0;
|
||||
}
|
||||
}
|
||||
}
|
98
otk_c/gccache.h
Normal file
98
otk_c/gccache.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
// -*- mode: C; indent-tabs-mode: nil; -*-
|
||||
#ifndef __gccache_h
|
||||
#define __gccache_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "color.h"
|
||||
|
||||
struct OtkGCCacheItem;
|
||||
|
||||
typedef struct OtkGCCacheContext {
|
||||
GC gc;
|
||||
unsigned long pixel;
|
||||
unsigned long fontid;
|
||||
int function;
|
||||
int subwindow;
|
||||
Bool used;
|
||||
unsigned int screen;
|
||||
int linewidth;
|
||||
} OtkGCCacheContext;
|
||||
|
||||
OtkGCCacheContext *OtkGCCacheContext_New();
|
||||
void OtkGCCacheContext_Destroy(OtkGCCacheContext *self);
|
||||
|
||||
void OtkGCCacheContext_Set(OtkGCCacheContext *self,
|
||||
OtkColor *color, XFontStruct *font,
|
||||
int function, int subwindow, int linewidth);
|
||||
void OtkGCCacheContext_SetFont(OtkGCCacheContext *self,
|
||||
XFontStruct *font);
|
||||
|
||||
|
||||
typedef struct OtkGCCacheItem {
|
||||
OtkGCCacheContext *ctx;
|
||||
unsigned int count;
|
||||
unsigned int hits;
|
||||
Bool fault;
|
||||
} OtkGCCacheItem;
|
||||
|
||||
OtkGCCacheItem *OtkGCCacheItem_New();
|
||||
|
||||
|
||||
typedef struct OtkGCCache {
|
||||
// this is closely modelled after the Qt GC cache, but with some of the
|
||||
// complexity stripped out
|
||||
unsigned int context_count;
|
||||
unsigned int cache_size;
|
||||
unsigned int cache_buckets;
|
||||
unsigned int cache_total_size;
|
||||
OtkGCCacheContext **contexts;
|
||||
OtkGCCacheItem **cache;
|
||||
} OtkGCCache;
|
||||
|
||||
void OtkGCCache_Initialize(int screen_count);
|
||||
void OtkGCCache_Destroy();
|
||||
|
||||
// cleans up the cache
|
||||
void OtkGCCache_Purge();
|
||||
|
||||
OtkGCCacheItem *OtkGCCache_Find(OtkColor *color,
|
||||
XFontStruct *font, int function,
|
||||
int subwindow, int linewidth);
|
||||
void OtkGCCache_Release(OtkGCCacheItem *item);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
class BPen {
|
||||
public:
|
||||
inline BPen(const BColor &_color, const XFontStruct * const _font = 0,
|
||||
int _linewidth = 0, int _function = GXcopy,
|
||||
int _subwindow = ClipByChildren)
|
||||
: color(_color), font(_font), linewidth(_linewidth), function(_function),
|
||||
subwindow(_subwindow), cache(OBDisplay::gcCache()), item(0) { }
|
||||
|
||||
inline ~BPen(void) { if (item) cache->release(item); }
|
||||
|
||||
inline const GC &gc(void) const {
|
||||
if (! item) item = cache->find(color, font, function, subwindow,
|
||||
linewidth);
|
||||
return item->gc();
|
||||
}
|
||||
|
||||
private:
|
||||
const BColor &color;
|
||||
const XFontStruct *font;
|
||||
int linewidth;
|
||||
int function;
|
||||
int subwindow;
|
||||
|
||||
mutable BGCCache *cache;
|
||||
mutable BGCCacheItem *item;
|
||||
};
|
||||
|
||||
}*/
|
||||
|
||||
#endif // __gccache_h
|
Loading…
Reference in a new issue