]> Dogcows Code - chaz/openbox/blob - render/color.c
remove XXX comment, it was right, now its done :>
[chaz/openbox] / render / color.c
1 #include "render.h"
2 #include "color.h"
3 #include "instance.h"
4
5 #include <X11/Xlib.h>
6 #include <X11/Xutil.h>
7 #include <string.h>
8
9 void RrColorAllocateGC(RrColor *in)
10 {
11 XGCValues gcv;
12
13 gcv.foreground = in->pixel;
14 gcv.cap_style = CapProjecting;
15 in->gc = XCreateGC(RrDisplay(in->inst),
16 RrRootWindow(in->inst),
17 GCForeground | GCCapStyle, &gcv);
18 }
19
20 RrColor *RrColorParse(const RrInstance *inst, gchar *colorname)
21 {
22 XColor xcol;
23
24 g_assert(colorname != NULL);
25 /* get rgb values from colorname */
26
27 xcol.red = 0;
28 xcol.green = 0;
29 xcol.blue = 0;
30 xcol.pixel = 0;
31 if (!XParseColor(RrDisplay(inst), RrColormap(inst), colorname, &xcol)) {
32 g_warning("unable to parse color '%s'", colorname);
33 return NULL;
34 }
35 return RrColorNew(inst, xcol.red >> 8, xcol.green >> 8, xcol.blue >> 8);
36 }
37
38 RrColor *RrColorNew(const RrInstance *inst, gint r, gint g, gint b)
39 {
40 /* this should be replaced with something far cooler */
41 RrColor *out = NULL;
42 XColor xcol;
43 gint key;
44
45 key = (r << 24) + (g << 16) + (b << 8);
46 if ((out = g_hash_table_lookup(RrColorHash(inst), &key))) {
47 out->refcount++;
48 } else {
49 xcol.red = (r << 8) | r;
50 xcol.green = (g << 8) | g;
51 xcol.blue = (b << 8) | b;
52 if (XAllocColor(RrDisplay(inst), RrColormap(inst), &xcol)) {
53 out = g_new(RrColor, 1);
54 out->inst = inst;
55 out->r = xcol.red >> 8;
56 out->g = xcol.green >> 8;
57 out->b = xcol.blue >> 8;
58 out->gc = None;
59 out->pixel = xcol.pixel;
60 out->key = key;
61 out->refcount = 1;
62 g_hash_table_replace(RrColorHash(inst), &out->key, out);
63 }
64 }
65 return out;
66 }
67
68 void RrColorFree(RrColor *c)
69 {
70 if (c) {
71 if (--c->refcount < 1) {
72 g_hash_table_remove(RrColorHash(c->inst), &c->key);
73 if (c->pixel) XFreeColors(RrDisplay(c->inst), RrColormap(c->inst),
74 &c->pixel, 1, 0);
75 if (c->gc) XFreeGC(RrDisplay(c->inst), c->gc);
76 g_free(c);
77 }
78 }
79 }
80
81 void RrReduceDepth(const RrInstance *inst, RrPixel32 *data, XImage *im)
82 {
83 int r, g, b;
84 int x,y;
85 RrPixel32 *p32 = (RrPixel32 *) im->data;
86 RrPixel16 *p16 = (RrPixel16 *) im->data;
87 unsigned char *p8 = (unsigned char *)im->data;
88 switch (im->bits_per_pixel) {
89 case 32:
90 if ((RrRedOffset(inst) != RrDefaultRedOffset) ||
91 (RrBlueOffset(inst) != RrDefaultBlueOffset) ||
92 (RrGreenOffset(inst) != RrDefaultGreenOffset)) {
93 for (y = 0; y < im->height; y++) {
94 for (x = 0; x < im->width; x++) {
95 r = (data[x] >> RrDefaultRedOffset) & 0xFF;
96 g = (data[x] >> RrDefaultGreenOffset) & 0xFF;
97 b = (data[x] >> RrDefaultBlueOffset) & 0xFF;
98 p32[x] = (r << RrRedOffset(inst))
99 + (g << RrGreenOffset(inst))
100 + (b << RrBlueOffset(inst));
101 }
102 data += im->width;
103 p32 += im->width;
104 }
105 } else im->data = (char*) data;
106 break;
107 case 16:
108 for (y = 0; y < im->height; y++) {
109 for (x = 0; x < im->width; x++) {
110 r = (data[x] >> RrDefaultRedOffset) & 0xFF;
111 r = r >> RrRedShift(inst);
112 g = (data[x] >> RrDefaultGreenOffset) & 0xFF;
113 g = g >> RrGreenShift(inst);
114 b = (data[x] >> RrDefaultBlueOffset) & 0xFF;
115 b = b >> RrBlueShift(inst);
116 p16[x] = (r << RrRedOffset(inst))
117 + (g << RrGreenOffset(inst))
118 + (b << RrBlueOffset(inst));
119 }
120 data += im->width;
121 p16 += im->bytes_per_line/2;
122 }
123 break;
124 case 8:
125 g_assert(RrVisual(inst)->class != TrueColor);
126 for (y = 0; y < im->height; y++) {
127 for (x = 0; x < im->width; x++) {
128 p8[x] = RrPickColor(inst,
129 data[x] >> RrDefaultRedOffset,
130 data[x] >> RrDefaultGreenOffset,
131 data[x] >> RrDefaultBlueOffset)->pixel;
132 }
133 data += im->width;
134 p8 += im->bytes_per_line;
135 }
136
137 break;
138 default:
139 g_warning("your bit depth is currently unhandled\n");
140 }
141 }
142
143 XColor *RrPickColor(const RrInstance *inst, gint r, gint g, gint b)
144 {
145 r = (r & 0xff) >> (8-RrPseudoBPC(inst));
146 g = (g & 0xff) >> (8-RrPseudoBPC(inst));
147 b = (b & 0xff) >> (8-RrPseudoBPC(inst));
148 return &RrPseudoColors(inst)[(r << (2*RrPseudoBPC(inst))) +
149 (g << (1*RrPseudoBPC(inst))) +
150 b];
151 }
152
153 static void swap_byte_order(XImage *im)
154 {
155 int x, y, di;
156
157 di = 0;
158 for (y = 0; y < im->height; ++y) {
159 for (x = 0; x < im->height; ++x) {
160 char *c = &im->data[di + x * im->bits_per_pixel / 8];
161 char t;
162
163 switch (im->bits_per_pixel) {
164 case 32:
165 t = c[2];
166 c[2] = c[3];
167 c[3] = t;
168 case 16:
169 t = c[0];
170 c[0] = c[1];
171 c[1] = t;
172 case 8:
173 break;
174 default:
175 g_warning("your bit depth is currently unhandled");
176 }
177 }
178 di += im->bytes_per_line;
179 }
180
181 if (im->byte_order == LSBFirst)
182 im->byte_order = MSBFirst;
183 else
184 im->byte_order = LSBFirst;
185 }
186
187 void RrIncreaseDepth(const RrInstance *inst, RrPixel32 *data, XImage *im)
188 {
189 int r, g, b;
190 int x,y;
191 RrPixel32 *p32 = (RrPixel32 *) im->data;
192 RrPixel16 *p16 = (RrPixel16 *) im->data;
193 unsigned char *p8 = (unsigned char *)im->data;
194
195 if (im->byte_order != LSBFirst)
196 swap_byte_order(im);
197
198 switch (im->bits_per_pixel) {
199 case 32:
200 for (y = 0; y < im->height; y++) {
201 for (x = 0; x < im->width; x++) {
202 r = (p32[x] >> RrRedOffset(inst)) & 0xff;
203 g = (p32[x] >> RrGreenOffset(inst)) & 0xff;
204 b = (p32[x] >> RrBlueOffset(inst)) & 0xff;
205 data[x] = (r << RrDefaultRedOffset)
206 + (g << RrDefaultGreenOffset)
207 + (b << RrDefaultBlueOffset)
208 + (0xff << RrDefaultAlphaOffset);
209 }
210 data += im->width;
211 p32 += im->bytes_per_line/4;
212 }
213 break;
214 case 16:
215 for (y = 0; y < im->height; y++) {
216 for (x = 0; x < im->width; x++) {
217 r = (p16[x] & RrRedMask(inst)) >>
218 RrRedOffset(inst) <<
219 RrRedShift(inst);
220 g = (p16[x] & RrGreenMask(inst)) >>
221 RrGreenOffset(inst) <<
222 RrGreenShift(inst);
223 b = (p16[x] & RrBlueMask(inst)) >>
224 RrBlueOffset(inst) <<
225 RrBlueShift(inst);
226 data[x] = (r << RrDefaultRedOffset)
227 + (g << RrDefaultGreenOffset)
228 + (b << RrDefaultBlueOffset)
229 + (0xff << RrDefaultAlphaOffset);
230 }
231 data += im->width;
232 p16 += im->bytes_per_line/2;
233 }
234 break;
235 case 8:
236 g_warning("this image bit depth is currently unhandled");
237 break;
238 case 1:
239 for (y = 0; y < im->height; y++) {
240 for (x = 0; x < im->width; x++) {
241 if (!(((p8[x / 8]) >> (x % 8)) & 0x1))
242 data[x] = 0xff << RrDefaultAlphaOffset; /* black */
243 else
244 data[x] = 0xffffffff; /* white */
245 }
246 data += im->width;
247 p8 += im->bytes_per_line;
248 }
249 break;
250 default:
251 g_warning("this image bit depth is currently unhandled");
252 }
253 }
254
255 int RrColorRed(const RrColor *c)
256 {
257 return c->r;
258 }
259
260 int RrColorGreen(const RrColor *c)
261 {
262 return c->g;
263 }
264
265 int RrColorBlue(const RrColor *c)
266 {
267 return c->b;
268 }
269
270 gulong RrColorPixel(const RrColor *c)
271 {
272 return c->pixel;
273 }
274
275 GC RrColorGC(RrColor *c) /* XXX make this const RrColor* when the GCs are in
276 a cache.. if possible? */
277 {
278 if (!c->gc)
279 RrColorAllocateGC(c);
280 return c->gc;
281 }
This page took 0.055018 seconds and 5 git commands to generate.