changed indentation to use spaces only
[wmaker-crm.git] / WINGs / wcolor.c
blobbca13a7a888b6d16417eb84d064756b1fa2343cb
2 #include "WINGsP.h"
4 #include "wconfig.h"
6 #include <wraster.h>
8 #define LIGHT_STIPPLE_WIDTH 4
9 #define LIGHT_STIPPLE_HEIGHT 4
10 static unsigned char LIGHT_STIPPLE_BITS[] = {
11 0x05, 0x0a, 0x05, 0x0a};
13 #define DARK_STIPPLE_WIDTH 4
14 #define DARK_STIPPLE_HEIGHT 4
15 static unsigned char DARK_STIPPLE_BITS[] = {
16 0x0a, 0x04, 0x0a, 0x01};
19 static WMColor *createRGBAColor(WMScreen *scr, unsigned short red,
20 unsigned short green, unsigned short blue,
21 unsigned short alpha);
24 * TODO: make the color creation code return the same WMColor for the
25 * same colors.
26 * make findCloseColor() find the closest color in the RContext pallette
27 * or in the other colors allocated by WINGs.
30 static WMColor*
31 findCloseColor(WMScreen *scr, unsigned short red, unsigned short green,
32 unsigned short blue, unsigned short alpha)
34 WMColor *color;
35 XColor xcolor;
36 RColor rcolor;
38 rcolor.red = red>>8;
39 rcolor.green = green>>8;
40 rcolor.blue = blue>>8;
41 rcolor.alpha = alpha>>8;
43 if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor))
44 return NULL;
46 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
47 return NULL;
49 color = wmalloc(sizeof(WMColor));
51 color->screen = scr;
52 color->refCount = 1;
53 color->color = xcolor;
54 color->alpha = alpha;
55 color->flags.exact = 1;
56 color->gc = NULL;
58 return color;
63 static WMColor*
64 createRGBAColor(WMScreen *scr, unsigned short red, unsigned short green,
65 unsigned short blue, unsigned short alpha)
67 WMColor *color;
68 XColor xcolor;
70 xcolor.red = red;
71 xcolor.green = green;
72 xcolor.blue = blue;
73 xcolor.flags = DoRed|DoGreen|DoBlue;
74 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
75 return NULL;
77 color = wmalloc(sizeof(WMColor));
79 color->screen = scr;
80 color->refCount = 1;
81 color->color = xcolor;
82 color->alpha = alpha;
83 color->flags.exact = 1;
84 color->gc = NULL;
86 return color;
90 WMColor*
91 WMCreateRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
92 unsigned short blue, Bool exact)
94 WMColor *color = NULL;
96 if (!exact || !(color=createRGBAColor(scr, red, green, blue, 0xffff))) {
97 color = findCloseColor(scr, red, green, blue, 0xffff);
99 if (!color)
100 color = WMBlackColor(scr);
102 return color;
106 WMColor*
107 WMCreateRGBAColor(WMScreen *scr, unsigned short red, unsigned short green,
108 unsigned short blue, unsigned short alpha, Bool exact)
110 WMColor *color = NULL;
112 if (!exact || !(color=createRGBAColor(scr, red, green, blue, alpha))) {
113 color = findCloseColor(scr, red, green, blue, alpha);
115 if (!color)
116 color = WMBlackColor(scr);
118 return color;
122 WMColor*
123 WMCreateNamedColor(WMScreen *scr, char *name, Bool exact)
125 WMColor *color;
126 XColor xcolor;
128 if (!XParseColor(scr->display, scr->colormap, name, &xcolor))
129 return NULL;
131 if (scr->visual->class == TrueColor)
132 exact = True;
134 if (!exact || !(color=createRGBAColor(scr, xcolor.red, xcolor.green,
135 xcolor.blue, 0xffff))) {
136 color = findCloseColor(scr, xcolor.red, xcolor.green, xcolor.blue, 0xffff);
138 return color;
143 WMColor*
144 WMRetainColor(WMColor *color)
146 assert(color!=NULL);
148 color->refCount++;
150 return color;
154 void
155 WMReleaseColor(WMColor *color)
157 color->refCount--;
159 if (color->refCount < 1) {
160 XFreeColors(color->screen->display, color->screen->colormap,
161 &(color->color.pixel), 1, 0);
162 if (color->gc)
163 XFreeGC(color->screen->display, color->gc);
164 wfree(color);
169 void
170 WMSetColorAlpha(WMColor *color, unsigned short alpha)
172 color->alpha = alpha;
176 void
177 WMPaintColorSwatch(WMColor *color, Drawable d, int x, int y,
178 unsigned int width, unsigned int height)
180 XFillRectangle(color->screen->display, d, WMColorGC(color),
181 x, y, width, height);
185 WMPixel
186 WMColorPixel(WMColor *color)
188 return color->color.pixel;
193 WMColorGC(WMColor *color)
195 if (!color->gc) {
196 XGCValues gcv;
197 WMScreen *scr = color->screen;
199 gcv.foreground = color->color.pixel;
200 gcv.graphics_exposures = False;
201 color->gc = XCreateGC(scr->display, scr->rcontext->drawable,
202 GCForeground|GCGraphicsExposures, &gcv);
205 return color->gc;
209 void
210 WMSetColorInGC(WMColor *color, GC gc)
212 XSetForeground(color->screen->display, gc, color->color.pixel);
217 /* "system" colors */
218 WMColor*
219 WMWhiteColor(WMScreen *scr)
221 if (!scr->white) {
222 scr->white = WMCreateRGBColor(scr, 0xffff, 0xffff, 0xffff, True);
223 if (!scr->white->flags.exact)
224 wwarning(_("could not allocate %s color"), _("white"));
226 return WMRetainColor(scr->white);
230 WMColor*
231 WMBlackColor(WMScreen *scr)
233 if (!scr->black) {
234 scr->black = WMCreateRGBColor(scr, 0, 0, 0, True);
235 if (!scr->black->flags.exact)
236 wwarning(_("could not allocate %s color"), _("black"));
238 return WMRetainColor(scr->black);
243 WMColor*
244 WMGrayColor(WMScreen *scr)
246 if (!scr->gray) {
247 WMColor *color;
249 if (scr->depth == 1) {
250 Pixmap stipple;
251 WMColor *white = WMWhiteColor(scr);
252 WMColor *black = WMBlackColor(scr);
253 XGCValues gcv;
255 stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
256 LIGHT_STIPPLE_BITS, LIGHT_STIPPLE_WIDTH,
257 LIGHT_STIPPLE_HEIGHT);
259 color = createRGBAColor(scr, 0xffff, 0xffff, 0xffff, 0xffff);
261 gcv.foreground = white->color.pixel;
262 gcv.background = black->color.pixel;
263 gcv.fill_style = FillStippled;
264 gcv.stipple = stipple;
265 color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
266 |GCBackground|GCStipple|GCFillStyle
267 |GCGraphicsExposures, &gcv);
269 XFreePixmap(scr->display, stipple);
270 WMReleaseColor(white);
271 WMReleaseColor(black);
272 } else {
273 color = WMCreateRGBColor(scr, 0xaeba, 0xaaaa, 0xaeba, True);
274 if (!color->flags.exact)
275 wwarning(_("could not allocate %s color"), _("gray"));
277 scr->gray = color;
279 return WMRetainColor(scr->gray);
284 WMColor*
285 WMDarkGrayColor(WMScreen *scr)
287 if (!scr->darkGray) {
288 WMColor *color;
290 if (scr->depth == 1) {
291 Pixmap stipple;
292 WMColor *white = WMWhiteColor(scr);
293 WMColor *black = WMBlackColor(scr);
294 XGCValues gcv;
296 stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
297 DARK_STIPPLE_BITS, DARK_STIPPLE_WIDTH,
298 DARK_STIPPLE_HEIGHT);
300 color = createRGBAColor(scr, 0, 0, 0, 0xffff);
302 gcv.foreground = white->color.pixel;
303 gcv.background = black->color.pixel;
304 gcv.fill_style = FillStippled;
305 gcv.stipple = stipple;
306 color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
307 |GCBackground|GCStipple|GCFillStyle
308 |GCGraphicsExposures, &gcv);
310 XFreePixmap(scr->display, stipple);
311 WMReleaseColor(white);
312 WMReleaseColor(black);
313 } else {
314 color = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True);
315 if (!color->flags.exact)
316 wwarning(_("could not allocate %s color"), _("dark gray"));
318 scr->darkGray = color;
320 return WMRetainColor(scr->darkGray);
324 unsigned short
325 WMRedComponentOfColor(WMColor *color)
327 return color->color.red;
331 unsigned short
332 WMGreenComponentOfColor(WMColor *color)
334 return color->color.green;
338 unsigned short
339 WMBlueComponentOfColor(WMColor *color)
341 return color->color.blue;
345 unsigned short
346 WMGetColorAlpha(WMColor *color)
348 return color->alpha;
352 char*
353 WMGetColorRGBDescription(WMColor *color)
355 char *str = wmalloc(32);
357 sprintf(str, "#%02x%02x%02x", color->color.red>>8, color->color.green>>8,
358 color->color.blue>>8);
360 return str;