Yet another try to get 0.51.2-pre2 in cvs
[wmaker-crm.git] / WINGs / wcolor.c
blob6ae38abd80cd6304e7d4a107614847ae248bc4f8
2 #include "WINGsP.h"
4 #include <wraster.h>
6 #define LIGHT_STIPPLE_WIDTH 4
7 #define LIGHT_STIPPLE_HEIGHT 4
8 static unsigned char LIGHT_STIPPLE_BITS[] = {
9 0x05, 0x0a, 0x05, 0x0a};
11 #define DARK_STIPPLE_WIDTH 4
12 #define DARK_STIPPLE_HEIGHT 4
13 static unsigned char DARK_STIPPLE_BITS[] = {
14 0x0a, 0x04, 0x0a, 0x01};
17 static WMColor *createRGBColor(WMScreen *scr, unsigned short red,
18 unsigned short green, unsigned short blue);
21 * TODO: make the color creation code return the same WMColor for the
22 * same colors.
23 * make findCloseColor() find the closest color in the RContext pallette
24 * or in the other colors allocated by WINGs.
27 static WMColor*
28 findCloseColor(WMScreen *scr, unsigned short red, unsigned short green,
29 unsigned short blue)
31 WMColor *color;
32 XColor xcolor;
33 RColor rcolor;
35 rcolor.red = red>>8;
36 rcolor.green = green>>8;
37 rcolor.blue = blue>>8;
39 if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor))
40 return NULL;
42 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
43 return NULL;
45 color = wmalloc(sizeof(WMColor));
47 color->screen = scr;
48 color->refCount = 1;
49 color->color = xcolor;
50 color->flags.exact = 1;
51 color->gc = NULL;
53 return color;
58 static WMColor*
59 createRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
60 unsigned short blue)
62 WMColor *color;
63 XColor xcolor;
65 xcolor.red = red;
66 xcolor.green = green;
67 xcolor.blue = blue;
68 xcolor.flags = DoRed|DoGreen|DoBlue;
69 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
70 return NULL;
72 color = wmalloc(sizeof(WMColor));
74 color->screen = scr;
75 color->refCount = 1;
76 color->color = xcolor;
77 color->flags.exact = 1;
78 color->gc = NULL;
80 return color;
85 WMColor*
86 WMCreateRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
87 unsigned short blue, Bool exact)
89 WMColor *color = NULL;
91 if (!exact || !(color=createRGBColor(scr, red, green, blue))) {
92 color = findCloseColor(scr, red, green, blue);
94 if (!color)
95 color = WMBlackColor(scr);
97 return color;
101 WMColor*
102 WMCreateNamedColor(WMScreen *scr, char *name, Bool exact)
104 WMColor *color;
105 XColor xcolor;
107 if (!XParseColor(scr->display, scr->colormap, name, &xcolor))
108 return NULL;
110 if (scr->visual->class == TrueColor)
111 exact = True;
113 if (!exact || !(color=createRGBColor(scr, xcolor.red, xcolor.green,
114 xcolor.blue))) {
115 color = findCloseColor(scr, xcolor.red, xcolor.green, xcolor.blue);
117 return color;
122 WMColor*
123 WMRetainColor(WMColor *color)
125 assert(color!=NULL);
127 color->refCount++;
129 return color;
133 void
134 WMReleaseColor(WMColor *color)
136 color->refCount--;
138 if (color->refCount < 1) {
139 XFreeColors(color->screen->display, color->screen->colormap,
140 &(color->color.pixel), 1, 0);
141 if (color->gc)
142 XFreeGC(color->screen->display, color->gc);
143 free(color);
148 void
149 WMPaintColorSwatch(WMColor *color, Drawable d, int x, int y,
150 unsigned int width, unsigned int height)
152 XFillRectangle(color->screen->display, d, WMColorGC(color),
153 x, y, width, height);
157 WMPixel
158 WMColorPixel(WMColor *color)
160 return color->color.pixel;
165 WMColorGC(WMColor *color)
167 if (!color->gc) {
168 XGCValues gcv;
169 WMScreen *scr = color->screen;
171 gcv.foreground = color->color.pixel;
172 gcv.graphics_exposures = False;
173 color->gc = XCreateGC(scr->display, scr->rcontext->drawable,
174 GCForeground|GCGraphicsExposures, &gcv);
177 return color->gc;
181 void
182 WMSetColorInGC(WMColor *color, GC gc)
184 XSetForeground(color->screen->display, gc, color->color.pixel);
189 /* "system" colors */
190 WMColor*
191 WMWhiteColor(WMScreen *scr)
193 if (!scr->white) {
194 scr->white = WMCreateRGBColor(scr, 0xffff, 0xffff, 0xffff, True);
195 if (!scr->white->flags.exact)
196 wwarning("could not allocate %s color", "white");
198 return WMRetainColor(scr->white);
203 WMColor*
204 WMBlackColor(WMScreen *scr)
206 if (!scr->black) {
207 scr->black = WMCreateRGBColor(scr, 0, 0, 0, True);
208 if (!scr->black->flags.exact)
209 wwarning("could not allocate %s color", "black");
211 return WMRetainColor(scr->black);
216 WMColor*
217 WMGrayColor(WMScreen *scr)
219 if (!scr->gray) {
220 WMColor *color;
222 if (scr->depth == 1) {
223 Pixmap stipple;
224 WMColor *white = WMWhiteColor(scr);
225 WMColor *black = WMBlackColor(scr);
226 XGCValues gcv;
228 stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
229 LIGHT_STIPPLE_BITS, LIGHT_STIPPLE_WIDTH,
230 LIGHT_STIPPLE_HEIGHT);
232 color = createRGBColor(scr, 0xffff, 0xffff, 0xffff);
234 gcv.foreground = white->color.pixel;
235 gcv.background = black->color.pixel;
236 gcv.fill_style = FillStippled;
237 gcv.stipple = stipple;
238 color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
239 |GCBackground|GCStipple|GCFillStyle
240 |GCGraphicsExposures, &gcv);
242 XFreePixmap(scr->display, stipple);
243 WMReleaseColor(white);
244 WMReleaseColor(black);
245 } else {
246 color = WMCreateRGBColor(scr, 0xaeba, 0xaaaa, 0xaeba, True);
247 if (!color->flags.exact)
248 wwarning("could not allocate %s color", "gray");
250 scr->gray = color;
252 return WMRetainColor(scr->gray);
257 WMColor*
258 WMDarkGrayColor(WMScreen *scr)
260 if (!scr->darkGray) {
261 WMColor *color;
263 if (scr->depth == 1) {
264 Pixmap stipple;
265 WMColor *white = WMWhiteColor(scr);
266 WMColor *black = WMBlackColor(scr);
267 XGCValues gcv;
269 stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
270 DARK_STIPPLE_BITS, DARK_STIPPLE_WIDTH,
271 DARK_STIPPLE_HEIGHT);
273 color = createRGBColor(scr, 0, 0, 0);
275 gcv.foreground = white->color.pixel;
276 gcv.background = black->color.pixel;
277 gcv.fill_style = FillStippled;
278 gcv.stipple = stipple;
279 color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
280 |GCBackground|GCStipple|GCFillStyle
281 |GCGraphicsExposures, &gcv);
283 XFreePixmap(scr->display, stipple);
284 WMReleaseColor(white);
285 WMReleaseColor(black);
286 } else {
287 color = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True);
288 if (!color->flags.exact)
289 wwarning("could not allocate %s color", "dark gray");
291 scr->darkGray = color;
293 return WMRetainColor(scr->darkGray);
297 unsigned short
298 WMRedComponentOfColor(WMColor *color)
300 return color->color.red;
304 unsigned short
305 WMGreenComponentOfColor(WMColor *color)
307 return color->color.green;
311 unsigned short
312 WMBlueComponentOfColor(WMColor *color)
314 return color->color.blue;
318 char*
319 WMGetColorRGBDescription(WMColor *color)
321 char *str = wmalloc(32);
323 sprintf(str, "rgb:%4x/%4x/%4x", color->color.red, color->color.green,
324 color->color.blue);
326 return str;