Initial revision
[wmaker-crm.git] / WINGs / wcolor.c
bloba00d1eb878d593eeaf0909ebb1cdd8f7b0550627
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;
34 XGCValues gcv;
36 rcolor.red = red>>8;
37 rcolor.green = green>>8;
38 rcolor.blue = blue>>8;
40 if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor))
41 return NULL;
43 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
44 return NULL;
46 color = wmalloc(sizeof(WMColor));
48 color->screen = scr;
49 color->refCount = 1;
50 color->color = xcolor;
51 color->flags.exact = 1;
53 gcv.foreground = color->color.pixel;
54 gcv.graphics_exposures = False;
55 color->gc = XCreateGC(scr->display, scr->rcontext->drawable,
56 GCForeground|GCGraphicsExposures, &gcv);
58 return color;
63 static WMColor*
64 createRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
65 unsigned short blue)
67 WMColor *color;
68 XGCValues gcv;
69 XColor xcolor;
71 xcolor.red = red;
72 xcolor.green = green;
73 xcolor.blue = blue;
74 xcolor.flags = DoRed|DoGreen|DoBlue;
75 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
76 return NULL;
78 color = wmalloc(sizeof(WMColor));
80 color->screen = scr;
81 color->refCount = 1;
82 color->color = xcolor;
83 color->flags.exact = 1;
85 gcv.foreground = color->color.pixel;
86 gcv.graphics_exposures = False;
87 color->gc = XCreateGC(scr->display, scr->rcontext->drawable,
88 GCForeground|GCGraphicsExposures, &gcv);
90 return color;
95 WMColor*
96 WMCreateRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
97 unsigned short blue, Bool exact)
99 WMColor *color = NULL;
101 if (!exact || !(color=createRGBColor(scr, red, green, blue))) {
102 color = findCloseColor(scr, red, green, blue);
104 if (!color)
105 color = WMBlackColor(scr);
107 return color;
111 WMColor*
112 WMCreateNamedColor(WMScreen *scr, char *name, Bool exact)
114 WMColor *color;
115 XColor xcolor;
117 if (!XParseColor(scr->display, scr->colormap, name, &xcolor))
118 return NULL;
121 if (!exact || !(color=createRGBColor(scr, xcolor.red, xcolor.green,
122 xcolor.blue))) {
123 color = findCloseColor(scr, xcolor.red, xcolor.green, xcolor.blue);
125 return color;
130 WMColor*
131 WMRetainColor(WMColor *color)
133 assert(color!=NULL);
135 color->refCount++;
137 return color;
141 void
142 WMReleaseColor(WMColor *color)
144 color->refCount--;
146 if (color->refCount < 1) {
147 XFreeColors(color->screen->display, color->screen->colormap,
148 &(color->color.pixel), 1, 0);
149 XFreeGC(color->screen->display, color->gc);
150 free(color);
155 void
156 WMPaintColorSwatch(WMColor *color, Drawable d, int x, int y,
157 unsigned int width, unsigned int height)
159 XFillRectangle(color->screen->display, d, color->gc, x, y, width, height);
163 WMPixel
164 WMColorPixel(WMColor *color)
166 return color->color.pixel;
171 WMColorGC(WMColor *color)
173 return color->gc;
177 void
178 WMSetColorInGC(WMColor *color, GC gc)
180 XSetForeground(color->screen->display, gc, color->color.pixel);
185 /* "system" colors */
186 WMColor*
187 WMWhiteColor(WMScreen *scr)
189 if (!scr->white) {
190 scr->white = WMCreateRGBColor(scr, 0xffff, 0xffff, 0xffff, True);
191 if (!scr->white->flags.exact)
192 wwarning("could not allocate %s color", "white");
194 return WMRetainColor(scr->white);
199 WMColor*
200 WMBlackColor(WMScreen *scr)
202 if (!scr->black) {
203 scr->black = WMCreateRGBColor(scr, 0, 0, 0, True);
204 if (!scr->black->flags.exact)
205 wwarning("could not allocate %s color", "black");
207 return WMRetainColor(scr->black);
212 WMColor*
213 WMGrayColor(WMScreen *scr)
215 if (!scr->gray) {
216 WMColor *color;
218 if (scr->depth == 1) {
219 Pixmap stipple;
220 WMColor *white = WMWhiteColor(scr);
221 WMColor *black = WMBlackColor(scr);
222 XGCValues gcv;
224 stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
225 LIGHT_STIPPLE_BITS, LIGHT_STIPPLE_WIDTH,
226 LIGHT_STIPPLE_HEIGHT);
228 color = createRGBColor(scr, 0xffff, 0xffff, 0xffff);
229 XFreeGC(scr->display, color->gc);
231 gcv.foreground = white->color.pixel;
232 gcv.background = black->color.pixel;
233 gcv.fill_style = FillStippled;
234 gcv.stipple = stipple;
235 color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
236 |GCBackground|GCStipple|GCFillStyle
237 |GCGraphicsExposures, &gcv);
239 XFreePixmap(scr->display, stipple);
240 WMReleaseColor(white);
241 WMReleaseColor(black);
242 } else {
243 color = WMCreateRGBColor(scr, 0xaeba, 0xaaaa, 0xaeba, True);
244 if (!color->flags.exact)
245 wwarning("could not allocate %s color", "gray");
247 scr->gray = color;
249 return WMRetainColor(scr->gray);
254 WMColor*
255 WMDarkGrayColor(WMScreen *scr)
257 if (!scr->darkGray) {
258 WMColor *color;
260 if (scr->depth == 1) {
261 Pixmap stipple;
262 WMColor *white = WMWhiteColor(scr);
263 WMColor *black = WMBlackColor(scr);
264 XGCValues gcv;
266 stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
267 DARK_STIPPLE_BITS, DARK_STIPPLE_WIDTH,
268 DARK_STIPPLE_HEIGHT);
270 color = createRGBColor(scr, 0, 0, 0);
271 XFreeGC(scr->display, color->gc);
273 gcv.foreground = white->color.pixel;
274 gcv.background = black->color.pixel;
275 gcv.fill_style = FillStippled;
276 gcv.stipple = stipple;
277 color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
278 |GCBackground|GCStipple|GCFillStyle
279 |GCGraphicsExposures, &gcv);
281 XFreePixmap(scr->display, stipple);
282 WMReleaseColor(white);
283 WMReleaseColor(black);
284 } else {
285 color = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True);
286 if (!color->flags.exact)
287 wwarning("could not allocate %s color", "dark gray");
289 scr->darkGray = color;
291 return WMRetainColor(scr->darkGray);
295 unsigned short
296 WMRedComponentOfColor(WMColor *color)
298 return color->color.red;
302 unsigned short
303 WMGreenComponentOfColor(WMColor *color)
305 return color->color.green;
309 unsigned short
310 WMBlueComponentOfColor(WMColor *color)
312 return color->color.blue;
316 char*
317 WMGetColorRGBDescription(WMColor *color)
319 char *str = wmalloc(32);
321 sprintf(str, "rgb:%4x/%4x/%4x", color->color.red, color->color.green,
322 color->color.blue);
324 return str;