]> Dogcows Code - chaz/openbox/blobdiff - otk_c/imagecontrol.c
otktimer works. imagecontrol is underway!
[chaz/openbox] / otk_c / imagecontrol.c
diff --git a/otk_c/imagecontrol.c b/otk_c/imagecontrol.c
new file mode 100644 (file)
index 0000000..93eddc4
--- /dev/null
@@ -0,0 +1,325 @@
+// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+
+#include "../config.h"
+#include "imagecontrol.h"
+#include "timer.h"
+#include "screeninfo.h"
+#include "display.h"
+
+typedef struct CachedImage {
+  Pixmap pixmap;
+  
+  unsigned int count, width, height;
+  unsigned long pixel1, pixel2, texture;
+} CachedImage;
+
+static void timeout(OtkImageControl *self);
+static void initColors(OtkImageControl *self, Visual *visual);
+
+PyObject *OtkImageControl_New(int screen)
+{
+  OtkImageControl *self;
+  int count, i;
+  XPixmapFormatValues *pmv;
+
+  self = PyObject_New(OtkImageControl, &OtkImageControl_Type);
+
+  self->screen = OtkDisplay_ScreenInfo(OBDisplay, screen);
+
+  self->timer = (OtkTimer*)OtkTimer_New((OtkTimeoutHandler)timeout, self);
+  self->timer->timeout = 300000;
+  OtkTimer_Start(self->timer);
+  self->cache_max = 200;
+  
+  self->dither = True; // default value
+  self->cpc = 4; // default value
+
+  // get the BPP from the X server
+  self->bpp = 0;
+  if ((pmv = XListPixmapFormats(OBDisplay->display, &count))) {
+    for (i = 0; i < count; i++)
+      if (pmv[i].depth == self->screen->depth) {
+       self->bpp = pmv[i].bits_per_pixel;
+       break;
+      }
+    XFree(pmv);
+  }
+  if (!self->bpp) self->bpp = self->screen->depth;
+  if (self->bpp >= 24) self->dither = False; // don't need dither at >= 24 bpp
+
+  self->grad_xbuffer = self->grad_ybuffer = NULL;
+  self->grad_buffer_width = self->grad_buffer_height = 0;
+  self->sqrt_table = NULL;
+
+  initColors(self, self->screen->visual);
+
+  return (PyObject*)self;
+}
+
+static void initColors(OtkImageControl *self, Visual *visual)
+{
+  // these are not used for !TrueColor
+  self->red_offset = self->green_offset = self->blue_offset = 0;
+  // these are not used for TrueColor
+  self->colors = NULL;
+  self->ncolors = 0;
+
+  // figure out all our color settings based on the visual type
+  switch (visual->class) {
+  case TrueColor: {
+    int i;
+    unsigned long red_mask, green_mask, blue_mask;
+
+    // find the offsets for each color in the visual's masks
+    red_mask = visual->red_mask;
+    green_mask = visual->green_mask;
+    blue_mask = visual->blue_mask;
+
+    while (! (red_mask & 1)) { self->red_offset++; red_mask >>= 1; }
+    while (! (green_mask & 1)) { self->green_offset++; green_mask >>= 1; }
+    while (! (blue_mask & 1)) { self->blue_offset++; blue_mask >>= 1; }
+
+    // use the mask to determine the number of bits for each shade of color
+    // so, best case, red_mask == 0xff (255), and so each bit is a different
+    // shade!
+    self->red_bits = 255 / red_mask;
+    self->green_bits = 255 / green_mask;
+    self->blue_bits = 255 / blue_mask;
+
+    // compute color tables, based on the number of bits for each shade
+    for (i = 0; i < 256; i++) {
+      self->red_color_table[i] = i / self->red_bits;
+      self->green_color_table[i] = i / self->green_bits;
+      self->blue_color_table[i] = i / self->blue_bits;
+    }
+    break;
+  }
+/*
+  case PseudoColor:
+  case StaticColor: {
+    ncolors = self->cpc * self->cpc * self->cpc; // cpc ^ 3
+
+    if (ncolors > (1 << self->screen->depth)) {
+      self->cpc = (1 << self->screen->depth) / 3;
+      ncolors = self->cpc * self->cpc * self->cpc; // cpc ^ 3
+    }
+
+    if (self->cpc < 2 || self->ncolors > (1 << self->screen->depth)) {
+      fprintf(stderr,
+             "OtkImageControl_New: invalid colormap size %d "
+              "(%d/%d/%d) - reducing",
+             self->ncolors, self->cpc, self->cpc, self->cpc);
+
+      self->cpc = (1 << self->screen->depth) / 3;
+    }
+
+    self->colors = malloc(sizeof(XColor) * self->ncolors);
+    if (! self->colors) {
+      fprintf(stderr, "OtkImageControl_New: error allocating colormap\n");
+      exit(1);
+    }
+
+    int i = 0, ii, p, r, g, b,
+      bits = 255 / (colors_per_channel - 1);
+
+    red_bits = green_bits = blue_bits = bits;
+
+    for (i = 0; i < 256; i++)
+      red_color_table[i] = green_color_table[i] = blue_color_table[i] =
+       i / bits;
+
+    for (r = 0, i = 0; r < colors_per_channel; r++)
+      for (g = 0; g < colors_per_channel; g++)
+       for (b = 0; b < colors_per_channel; b++, i++) {
+         colors[i].red = (r * 0xffff) / (colors_per_channel - 1);
+         colors[i].green = (g * 0xffff) / (colors_per_channel - 1);
+         colors[i].blue = (b * 0xffff) / (colors_per_channel - 1);;
+         colors[i].flags = DoRed|DoGreen|DoBlue;
+       }
+
+    for (i = 0; i < ncolors; i++) {
+      if (! XAllocColor(OBDisplay::display, colormap, &colors[i])) {
+       fprintf(stderr, "couldn't alloc color %i %i %i\n",
+               colors[i].red, colors[i].green, colors[i].blue);
+       colors[i].flags = 0;
+      } else {
+       colors[i].flags = DoRed|DoGreen|DoBlue;
+      }
+    }
+
+    XColor icolors[256];
+    int incolors = (((1 << screen_depth) > 256) ? 256 : (1 << screen_depth));
+
+    for (i = 0; i < incolors; i++)
+      icolors[i].pixel = i;
+
+    XQueryColors(OBDisplay::display, colormap, icolors, incolors);
+    for (i = 0; i < ncolors; i++) {
+      if (! colors[i].flags) {
+       unsigned long chk = 0xffffffff, pixel, close = 0;
+
+       p = 2;
+       while (p--) {
+         for (ii = 0; ii < incolors; ii++) {
+           r = (colors[i].red - icolors[i].red) >> 8;
+           g = (colors[i].green - icolors[i].green) >> 8;
+           b = (colors[i].blue - icolors[i].blue) >> 8;
+           pixel = (r * r) + (g * g) + (b * b);
+
+           if (pixel < chk) {
+             chk = pixel;
+             close = ii;
+           }
+
+           colors[i].red = icolors[close].red;
+           colors[i].green = icolors[close].green;
+           colors[i].blue = icolors[close].blue;
+
+           if (XAllocColor(OBDisplay::display, colormap,
+                           &colors[i])) {
+             colors[i].flags = DoRed|DoGreen|DoBlue;
+             break;
+           }
+         }
+       }
+      }
+    }
+
+    break;
+  }
+
+  case GrayScale:
+  case StaticGray: {
+    if (visual->c_class == StaticGray) {
+      ncolors = 1 << screen_depth;
+    } else {
+      ncolors = colors_per_channel * colors_per_channel * colors_per_channel;
+
+      if (ncolors > (1 << screen_depth)) {
+       colors_per_channel = (1 << screen_depth) / 3;
+       ncolors =
+         colors_per_channel * colors_per_channel * colors_per_channel;
+      }
+    }
+
+    if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) {
+      fprintf(stderr,
+              "BImageControl::BImageControl: invalid colormap size %d "
+              "(%d/%d/%d) - reducing",
+             ncolors, colors_per_channel, colors_per_channel,
+             colors_per_channel);
+
+      colors_per_channel = (1 << screen_depth) / 3;
+    }
+
+    colors = new XColor[ncolors];
+    if (! colors) {
+      fprintf(stderr,
+              "BImageControl::BImageControl: error allocating colormap\n");
+      exit(1);
+    }
+
+    int i = 0, ii, p, bits = 255 / (colors_per_channel - 1);
+    red_bits = green_bits = blue_bits = bits;
+
+    for (i = 0; i < 256; i++)
+      red_color_table[i] = green_color_table[i] = blue_color_table[i] =
+       i / bits;
+
+    for (i = 0; i < ncolors; i++) {
+      colors[i].red = (i * 0xffff) / (colors_per_channel - 1);
+      colors[i].green = (i * 0xffff) / (colors_per_channel - 1);
+      colors[i].blue = (i * 0xffff) / (colors_per_channel - 1);;
+      colors[i].flags = DoRed|DoGreen|DoBlue;
+
+      if (! XAllocColor(OBDisplay::display, colormap,
+                       &colors[i])) {
+       fprintf(stderr, "couldn't alloc color %i %i %i\n",
+               colors[i].red, colors[i].green, colors[i].blue);
+       colors[i].flags = 0;
+      } else {
+       colors[i].flags = DoRed|DoGreen|DoBlue;
+      }
+    }
+
+    XColor icolors[256];
+    int incolors = (((1 << screen_depth) > 256) ? 256 :
+                   (1 << screen_depth));
+
+    for (i = 0; i < incolors; i++)
+      icolors[i].pixel = i;
+
+    XQueryColors(OBDisplay::display, colormap, icolors, incolors);
+    for (i = 0; i < ncolors; i++) {
+      if (! colors[i].flags) {
+       unsigned long chk = 0xffffffff, pixel, close = 0;
+
+       p = 2;
+       while (p--) {
+         for (ii = 0; ii < incolors; ii++) {
+           int r = (colors[i].red - icolors[i].red) >> 8;
+           int g = (colors[i].green - icolors[i].green) >> 8;
+           int b = (colors[i].blue - icolors[i].blue) >> 8;
+           pixel = (r * r) + (g * g) + (b * b);
+
+           if (pixel < chk) {
+             chk = pixel;
+             close = ii;
+           }
+
+           colors[i].red = icolors[close].red;
+           colors[i].green = icolors[close].green;
+           colors[i].blue = icolors[close].blue;
+
+           if (XAllocColor(OBDisplay::display, colormap,
+                           &colors[i])) {
+             colors[i].flags = DoRed|DoGreen|DoBlue;
+             break;
+           }
+         }
+       }
+      }
+    }
+
+    break;
+  }
+*/
+  default:
+    fprintf(stderr, "OtkImageControl: unsupported visual class: %d\n",
+           visual->class);
+    exit(1);
+  }
+}
+
+
+static void timeout(OtkImageControl *self)
+{
+  (void)self;
+}
+
+
+
+static void otkimagecontrol_dealloc(OtkImageControl* self)
+{
+  Py_DECREF(self->screen);
+  Py_DECREF(self->timer);
+  PyObject_Del((PyObject*)self);
+}
+
+PyTypeObject OtkImageControl_Type = {
+  PyObject_HEAD_INIT(NULL)
+  0,
+  "OtkImageControl",
+  sizeof(OtkImageControl),
+  0,
+  (destructor)otkimagecontrol_dealloc, /*tp_dealloc*/
+  0,                            /*tp_print*/
+  0,                            /*tp_getattr*/
+  0,                            /*tp_setattr*/
+  0,                            /*tp_compare*/
+  0,                            /*tp_repr*/
+  0,                            /*tp_as_number*/
+  0,                            /*tp_as_sequence*/
+  0,                            /*tp_as_mapping*/
+  0,                            /*tp_hash */
+};
This page took 0.031062 seconds and 4 git commands to generate.