-// -*- mode: C; indent-tabs-mode: nil; -*-
+// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
#include "../config.h"
#include "color.h"
static Bool cleancache = False;
static PyObject *colorcache = NULL;
-static void otkcolor_dealloc(OtkColor* self)
-{
- // when this is called, the color has already been cleaned out of the cache
- PyObject_Del((PyObject*)self);
-}
-
-static int otkcolor_compare(OtkColor *c1, OtkColor *c2)
-{
- long result;
- unsigned long p1, p2;
-
- p1 = c1->red << 16 | c1->green << 8 | c1->blue;
- p2 = c2->red << 16 | c2->green << 8 | c2->blue;
-
- if (p1 < p2)
- result = -1;
- else if (p1 > p2)
- result = 1;
- else
- result = 0;
- return result;
-}
-
-static PyObject *otkcolor_repr(OtkColor *self)
-{
- return PyString_FromFormat("rgb:%x/%x/%x", self->red, self->green,
- self->blue);
-}
-
-static long otkcolor_hash(OtkColor *self)
-{
- return self->screen << 24 | self->red << 16 | self->green << 8 | self->blue;
-}
-
-static PyTypeObject OtkColor_Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "Color",
- sizeof(OtkColor),
- 0,
- (destructor)otkcolor_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- (cmpfunc)otkcolor_compare, /*tp_compare*/
- (reprfunc)otkcolor_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)otkcolor_hash, /*tp_hash */
-};
-
-
static void parseColorName(OtkColor *self, const char *name) {
XColor xcol;
}
}
-#include <stdio.h>
static void doCacheCleanup() {
unsigned long *pixels;
int i, ppos;
// ### TODO - support multiple displays!
if (!PyDict_Size(colorcache)) return; // nothing to do
- printf("Cleaning Cache...\n");
-
pixels = malloc(sizeof(unsigned long) * PyDict_Size(colorcache));
for (i = 0; i < ScreenCount(OBDisplay->display); i++) {
- printf("Screen %d\n", i);
count = 0;
ppos = 0;
// get the screen from the hash
if (color->screen != i) continue; // wrong screen
- printf("has %d refs\n", color->ob_refcnt);
-
// does someone other than the cache have a reference? (the cache gets 2)
if (color->ob_refcnt > 2)
continue;
- printf("ppos: %d\n", ppos);
- printf("Cleaning pixel: %lx Count: %d\n", color->pixel, count+1);
-
pixels[count++] = color->pixel;
- printf("pixref references before: %d\n", color->ob_refcnt);
PyDict_DelItem(colorcache, key);
- printf("pixref references after: %d\n", color->ob_refcnt);
--ppos; // back up one in the iteration
}
XFreeColors(OBDisplay->display,
OtkDisplay_ScreenInfo(OBDisplay, i)->colormap,
pixels, count, 0);
- printf("Done Cleaning Cache. Cleaned %d pixels\n", count);
}
free(pixels);
static void allocate(OtkColor *self) {
XColor xcol;
- assert(!self->allocated);
-
- printf("allocating! %d\n", cleancache);
-
// allocate color from rgb values
xcol.red = self->red | self->red << 8;
xcol.green = self->green | self->green << 8;
}
self->pixel = xcol.pixel;
- self->allocated = True;
if (cleancache)
doCacheCleanup();
if (!colorcache) colorcache = PyDict_New();
- self->allocated = False;
self->red = r;
self->green = g;
self->blue = b;
- self->pixel = 0;
self->screen = screen;
// does this color already exist in the cache?
// add it to the cache
PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self);
+ allocate(self);
return (PyObject*)self;
}
if (!colorcache) colorcache = PyDict_New();
- self->allocated = False;
self->red = -1;
self->green = -1;
self->blue = -1;
- self->pixel = 0;
self->screen = screen;
parseColorName(self, name);
// add it to the cache
PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self);
+ allocate(self);
return (PyObject*)self;
}
-unsigned long OtkColor_Pixel(OtkColor *self)
+void OtkColor_CleanupColorCache()
{
- if (!self->allocated)
- allocate(self);
- return self->pixel;
+ cleancache = True;
}
-void OtkColor_CleanupColorCache()
+
+
+static void otkcolor_dealloc(OtkColor* self)
{
- cleancache = True;
+ // when this is called, the color has already been cleaned out of the cache
+ PyObject_Del((PyObject*)self);
+}
+
+static int otkcolor_compare(OtkColor *c1, OtkColor *c2)
+{
+ long result;
+ unsigned long p1, p2;
+
+ p1 = c1->red << 16 | c1->green << 8 | c1->blue;
+ p2 = c2->red << 16 | c2->green << 8 | c2->blue;
+
+ if (p1 < p2)
+ result = -1;
+ else if (p1 > p2)
+ result = 1;
+ else
+ result = 0;
+ return result;
}
+
+static PyObject *otkcolor_repr(OtkColor *self)
+{
+ return PyString_FromFormat("rgb:%x/%x/%x", self->red, self->green,
+ self->blue);
+}
+
+static long otkcolor_hash(OtkColor *self)
+{
+ return self->screen << 24 | self->red << 16 | self->green << 8 | self->blue;
+}
+
+PyTypeObject OtkColor_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "OtkColor",
+ sizeof(OtkColor),
+ 0,
+ (destructor)otkcolor_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ (cmpfunc)otkcolor_compare, /*tp_compare*/
+ (reprfunc)otkcolor_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)otkcolor_hash, /*tp_hash */
+};