]> Dogcows Code - chaz/openbox/blob - otk_c/imagecontrol.c
check for the python cflags and libs
[chaz/openbox] / otk_c / imagecontrol.c
1 // -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #include "../config.h"
4 #include "imagecontrol.h"
5 #include "timer.h"
6 #include "screeninfo.h"
7 #include "display.h"
8
9 typedef struct CachedImage {
10 Pixmap pixmap;
11
12 unsigned int count, width, height;
13 unsigned long pixel1, pixel2, texture;
14 } CachedImage;
15
16 static void timeout(OtkImageControl *self);
17 static void initColors(OtkImageControl *self, Visual *visual);
18
19 PyObject *OtkImageControl_New(int screen)
20 {
21 OtkImageControl *self;
22 int count, i;
23 XPixmapFormatValues *pmv;
24
25 self = PyObject_New(OtkImageControl, &OtkImageControl_Type);
26
27 self->screen = OtkDisplay_ScreenInfo(OBDisplay, screen);
28
29 self->timer = (OtkTimer*)OtkTimer_New((OtkTimeoutHandler)timeout, self);
30 self->timer->timeout = 300000;
31 OtkTimer_Start(self->timer);
32 self->cache_max = 200;
33
34 self->dither = True; // default value
35 self->cpc = 4; // default value
36
37 // get the BPP from the X server
38 self->bpp = 0;
39 if ((pmv = XListPixmapFormats(OBDisplay->display, &count))) {
40 for (i = 0; i < count; i++)
41 if (pmv[i].depth == self->screen->depth) {
42 self->bpp = pmv[i].bits_per_pixel;
43 break;
44 }
45 XFree(pmv);
46 }
47 if (!self->bpp) self->bpp = self->screen->depth;
48 if (self->bpp >= 24) self->dither = False; // don't need dither at >= 24 bpp
49
50 self->grad_xbuffer = self->grad_ybuffer = NULL;
51 self->grad_buffer_width = self->grad_buffer_height = 0;
52 self->sqrt_table = NULL;
53
54 initColors(self, self->screen->visual);
55
56 return (PyObject*)self;
57 }
58
59 static void initColors(OtkImageControl *self, Visual *visual)
60 {
61 // these are not used for !TrueColor
62 self->red_offset = self->green_offset = self->blue_offset = 0;
63 // these are not used for TrueColor
64 self->colors = NULL;
65 self->ncolors = 0;
66
67 // figure out all our color settings based on the visual type
68 switch (visual->class) {
69 case TrueColor: {
70 int i;
71 unsigned long red_mask, green_mask, blue_mask;
72
73 // find the offsets for each color in the visual's masks
74 red_mask = visual->red_mask;
75 green_mask = visual->green_mask;
76 blue_mask = visual->blue_mask;
77
78 while (! (red_mask & 1)) { self->red_offset++; red_mask >>= 1; }
79 while (! (green_mask & 1)) { self->green_offset++; green_mask >>= 1; }
80 while (! (blue_mask & 1)) { self->blue_offset++; blue_mask >>= 1; }
81
82 // use the mask to determine the number of bits for each shade of color
83 // so, best case, red_mask == 0xff (255), and so each bit is a different
84 // shade!
85 self->red_bits = 255 / red_mask;
86 self->green_bits = 255 / green_mask;
87 self->blue_bits = 255 / blue_mask;
88
89 // compute color tables, based on the number of bits for each shade
90 for (i = 0; i < 256; i++) {
91 self->red_color_table[i] = i / self->red_bits;
92 self->green_color_table[i] = i / self->green_bits;
93 self->blue_color_table[i] = i / self->blue_bits;
94 }
95 break;
96 }
97 /*
98 case PseudoColor:
99 case StaticColor: {
100 ncolors = self->cpc * self->cpc * self->cpc; // cpc ^ 3
101
102 if (ncolors > (1 << self->screen->depth)) {
103 self->cpc = (1 << self->screen->depth) / 3;
104 ncolors = self->cpc * self->cpc * self->cpc; // cpc ^ 3
105 }
106
107 if (self->cpc < 2 || self->ncolors > (1 << self->screen->depth)) {
108 fprintf(stderr,
109 "OtkImageControl_New: invalid colormap size %d "
110 "(%d/%d/%d) - reducing",
111 self->ncolors, self->cpc, self->cpc, self->cpc);
112
113 self->cpc = (1 << self->screen->depth) / 3;
114 }
115
116 self->colors = malloc(sizeof(XColor) * self->ncolors);
117 if (! self->colors) {
118 fprintf(stderr, "OtkImageControl_New: error allocating colormap\n");
119 exit(1);
120 }
121
122 int i = 0, ii, p, r, g, b,
123 bits = 255 / (colors_per_channel - 1);
124
125 red_bits = green_bits = blue_bits = bits;
126
127 for (i = 0; i < 256; i++)
128 red_color_table[i] = green_color_table[i] = blue_color_table[i] =
129 i / bits;
130
131 for (r = 0, i = 0; r < colors_per_channel; r++)
132 for (g = 0; g < colors_per_channel; g++)
133 for (b = 0; b < colors_per_channel; b++, i++) {
134 colors[i].red = (r * 0xffff) / (colors_per_channel - 1);
135 colors[i].green = (g * 0xffff) / (colors_per_channel - 1);
136 colors[i].blue = (b * 0xffff) / (colors_per_channel - 1);;
137 colors[i].flags = DoRed|DoGreen|DoBlue;
138 }
139
140 for (i = 0; i < ncolors; i++) {
141 if (! XAllocColor(OBDisplay::display, colormap, &colors[i])) {
142 fprintf(stderr, "couldn't alloc color %i %i %i\n",
143 colors[i].red, colors[i].green, colors[i].blue);
144 colors[i].flags = 0;
145 } else {
146 colors[i].flags = DoRed|DoGreen|DoBlue;
147 }
148 }
149
150 XColor icolors[256];
151 int incolors = (((1 << screen_depth) > 256) ? 256 : (1 << screen_depth));
152
153 for (i = 0; i < incolors; i++)
154 icolors[i].pixel = i;
155
156 XQueryColors(OBDisplay::display, colormap, icolors, incolors);
157 for (i = 0; i < ncolors; i++) {
158 if (! colors[i].flags) {
159 unsigned long chk = 0xffffffff, pixel, close = 0;
160
161 p = 2;
162 while (p--) {
163 for (ii = 0; ii < incolors; ii++) {
164 r = (colors[i].red - icolors[i].red) >> 8;
165 g = (colors[i].green - icolors[i].green) >> 8;
166 b = (colors[i].blue - icolors[i].blue) >> 8;
167 pixel = (r * r) + (g * g) + (b * b);
168
169 if (pixel < chk) {
170 chk = pixel;
171 close = ii;
172 }
173
174 colors[i].red = icolors[close].red;
175 colors[i].green = icolors[close].green;
176 colors[i].blue = icolors[close].blue;
177
178 if (XAllocColor(OBDisplay::display, colormap,
179 &colors[i])) {
180 colors[i].flags = DoRed|DoGreen|DoBlue;
181 break;
182 }
183 }
184 }
185 }
186 }
187
188 break;
189 }
190
191 case GrayScale:
192 case StaticGray: {
193 if (visual->c_class == StaticGray) {
194 ncolors = 1 << screen_depth;
195 } else {
196 ncolors = colors_per_channel * colors_per_channel * colors_per_channel;
197
198 if (ncolors > (1 << screen_depth)) {
199 colors_per_channel = (1 << screen_depth) / 3;
200 ncolors =
201 colors_per_channel * colors_per_channel * colors_per_channel;
202 }
203 }
204
205 if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) {
206 fprintf(stderr,
207 "BImageControl::BImageControl: invalid colormap size %d "
208 "(%d/%d/%d) - reducing",
209 ncolors, colors_per_channel, colors_per_channel,
210 colors_per_channel);
211
212 colors_per_channel = (1 << screen_depth) / 3;
213 }
214
215 colors = new XColor[ncolors];
216 if (! colors) {
217 fprintf(stderr,
218 "BImageControl::BImageControl: error allocating colormap\n");
219 exit(1);
220 }
221
222 int i = 0, ii, p, bits = 255 / (colors_per_channel - 1);
223 red_bits = green_bits = blue_bits = bits;
224
225 for (i = 0; i < 256; i++)
226 red_color_table[i] = green_color_table[i] = blue_color_table[i] =
227 i / bits;
228
229 for (i = 0; i < ncolors; i++) {
230 colors[i].red = (i * 0xffff) / (colors_per_channel - 1);
231 colors[i].green = (i * 0xffff) / (colors_per_channel - 1);
232 colors[i].blue = (i * 0xffff) / (colors_per_channel - 1);;
233 colors[i].flags = DoRed|DoGreen|DoBlue;
234
235 if (! XAllocColor(OBDisplay::display, colormap,
236 &colors[i])) {
237 fprintf(stderr, "couldn't alloc color %i %i %i\n",
238 colors[i].red, colors[i].green, colors[i].blue);
239 colors[i].flags = 0;
240 } else {
241 colors[i].flags = DoRed|DoGreen|DoBlue;
242 }
243 }
244
245 XColor icolors[256];
246 int incolors = (((1 << screen_depth) > 256) ? 256 :
247 (1 << screen_depth));
248
249 for (i = 0; i < incolors; i++)
250 icolors[i].pixel = i;
251
252 XQueryColors(OBDisplay::display, colormap, icolors, incolors);
253 for (i = 0; i < ncolors; i++) {
254 if (! colors[i].flags) {
255 unsigned long chk = 0xffffffff, pixel, close = 0;
256
257 p = 2;
258 while (p--) {
259 for (ii = 0; ii < incolors; ii++) {
260 int r = (colors[i].red - icolors[i].red) >> 8;
261 int g = (colors[i].green - icolors[i].green) >> 8;
262 int b = (colors[i].blue - icolors[i].blue) >> 8;
263 pixel = (r * r) + (g * g) + (b * b);
264
265 if (pixel < chk) {
266 chk = pixel;
267 close = ii;
268 }
269
270 colors[i].red = icolors[close].red;
271 colors[i].green = icolors[close].green;
272 colors[i].blue = icolors[close].blue;
273
274 if (XAllocColor(OBDisplay::display, colormap,
275 &colors[i])) {
276 colors[i].flags = DoRed|DoGreen|DoBlue;
277 break;
278 }
279 }
280 }
281 }
282 }
283
284 break;
285 }
286 */
287 default:
288 fprintf(stderr, "OtkImageControl: unsupported visual class: %d\n",
289 visual->class);
290 exit(1);
291 }
292 }
293
294
295 static void timeout(OtkImageControl *self)
296 {
297 (void)self;
298 }
299
300
301
302 static void otkimagecontrol_dealloc(OtkImageControl* self)
303 {
304 Py_DECREF(self->screen);
305 Py_DECREF(self->timer);
306 PyObject_Del((PyObject*)self);
307 }
308
309 PyTypeObject OtkImageControl_Type = {
310 PyObject_HEAD_INIT(NULL)
311 0,
312 "OtkImageControl",
313 sizeof(OtkImageControl),
314 0,
315 (destructor)otkimagecontrol_dealloc, /*tp_dealloc*/
316 0, /*tp_print*/
317 0, /*tp_getattr*/
318 0, /*tp_setattr*/
319 0, /*tp_compare*/
320 0, /*tp_repr*/
321 0, /*tp_as_number*/
322 0, /*tp_as_sequence*/
323 0, /*tp_as_mapping*/
324 0, /*tp_hash */
325 };
This page took 0.046807 seconds and 4 git commands to generate.