Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wcolor.c
blob8c74f7cd2a1acdc042cee1f9273f02bb7927974a
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 char LIGHT_STIPPLE_BITS[] = {
11 0x05, 0x0a, 0x05, 0x0a
12 };
14 #define DARK_STIPPLE_WIDTH 4
15 #define DARK_STIPPLE_HEIGHT 4
16 static char DARK_STIPPLE_BITS[] = {
17 0x0a, 0x04, 0x0a, 0x01
18 };
20 static WMColor *createRGBAColor(WMScreen * scr, unsigned short red,
21 unsigned short green, unsigned short blue, unsigned short alpha);
23 /*
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.
28 */
30 static WMColor *findCloseColor(WMScreen * scr, unsigned short red, unsigned short green,
31 unsigned short blue, unsigned short alpha)
32 {
33 WMColor *color;
34 XColor xcolor;
35 RColor rcolor;
37 rcolor.red = red >> 8;
38 rcolor.green = green >> 8;
39 rcolor.blue = blue >> 8;
40 rcolor.alpha = alpha >> 8;
42 if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor))
43 return NULL;
45 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
46 return NULL;
48 color = wmalloc(sizeof(WMColor));
50 color->screen = scr;
51 color->refCount = 1;
52 color->color = xcolor;
53 color->alpha = alpha;
54 color->flags.exact = 1;
55 color->gc = NULL;
57 return color;
58 }
60 static WMColor *createRGBAColor(WMScreen * scr, unsigned short red, unsigned short green,
61 unsigned short blue, unsigned short alpha)
62 {
63 WMColor *color;
64 XColor xcolor;
66 xcolor.red = red;
67 xcolor.green = green;
68 xcolor.blue = blue;
69 xcolor.flags = DoRed | DoGreen | DoBlue;
70 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
71 return NULL;
73 color = wmalloc(sizeof(WMColor));
75 color->screen = scr;
76 color->refCount = 1;
77 color->color = xcolor;
78 color->alpha = alpha;
79 color->flags.exact = 1;
80 color->gc = NULL;
82 return color;
83 }
85 WMColor *WMCreateRGBColor(WMScreen * scr, unsigned short red, unsigned short green,
86 unsigned short blue, Bool exact)
87 {
88 WMColor *color = NULL;
90 if (!exact || !(color = createRGBAColor(scr, red, green, blue, 0xffff))) {
91 color = findCloseColor(scr, red, green, blue, 0xffff);
92 }
93 if (!color)
94 color = WMBlackColor(scr);
96 return color;
97 }
99 RColor WMGetRColorFromColor(WMColor * color)
101 RColor rcolor;
103 rcolor.red = color->color.red >> 8;
104 rcolor.green = color->color.green >> 8;
105 rcolor.blue = color->color.blue >> 8;
106 rcolor.alpha = color->alpha >> 8;
108 return rcolor;
111 WMColor *WMCreateRGBAColor(WMScreen * scr, unsigned short red, unsigned short green,
112 unsigned short blue, unsigned short alpha, Bool exact)
114 WMColor *color = NULL;
116 if (!exact || !(color = createRGBAColor(scr, red, green, blue, alpha))) {
117 color = findCloseColor(scr, red, green, blue, alpha);
119 if (!color)
120 color = WMBlackColor(scr);
122 return color;
125 WMColor *WMCreateNamedColor(WMScreen * scr, char *name, Bool exact)
127 WMColor *color;
128 XColor xcolor;
130 if (!XParseColor(scr->display, scr->colormap, name, &xcolor))
131 return NULL;
133 if (scr->visual->class == TrueColor)
134 exact = True;
136 if (!exact || !(color = createRGBAColor(scr, xcolor.red, xcolor.green, xcolor.blue, 0xffff))) {
137 color = findCloseColor(scr, xcolor.red, xcolor.green, xcolor.blue, 0xffff);
139 return color;
142 WMColor *WMRetainColor(WMColor * color)
144 assert(color != NULL);
146 color->refCount++;
148 return color;
151 void WMReleaseColor(WMColor * color)
153 color->refCount--;
155 if (color->refCount < 1) {
156 XFreeColors(color->screen->display, color->screen->colormap, &(color->color.pixel), 1, 0);
157 if (color->gc)
158 XFreeGC(color->screen->display, color->gc);
159 wfree(color);
163 void WMSetColorAlpha(WMColor * color, unsigned short alpha)
165 color->alpha = alpha;
168 void WMPaintColorSwatch(WMColor * color, Drawable d, int x, int y, unsigned int width, unsigned int height)
170 XFillRectangle(color->screen->display, d, WMColorGC(color), x, y, width, height);
173 WMPixel WMColorPixel(WMColor * color)
175 return color->color.pixel;
178 GC WMColorGC(WMColor * color)
180 if (!color->gc) {
181 XGCValues gcv;
182 WMScreen *scr = color->screen;
184 gcv.foreground = color->color.pixel;
185 gcv.graphics_exposures = False;
186 color->gc = XCreateGC(scr->display, scr->rcontext->drawable,
187 GCForeground | GCGraphicsExposures, &gcv);
190 return color->gc;
193 void WMSetColorInGC(WMColor * color, GC gc)
195 XSetForeground(color->screen->display, gc, color->color.pixel);
198 /* "system" colors */
199 WMColor *WMWhiteColor(WMScreen * scr)
201 if (!scr->white) {
202 scr->white = WMCreateRGBColor(scr, 0xffff, 0xffff, 0xffff, True);
203 if (!scr->white->flags.exact)
204 wwarning(_("could not allocate %s color"), _("white"));
206 return WMRetainColor(scr->white);
209 WMColor *WMBlackColor(WMScreen * scr)
211 if (!scr->black) {
212 scr->black = WMCreateRGBColor(scr, 0, 0, 0, True);
213 if (!scr->black->flags.exact)
214 wwarning(_("could not allocate %s color"), _("black"));
216 return WMRetainColor(scr->black);
219 WMColor *WMGrayColor(WMScreen * scr)
221 if (!scr->gray) {
222 WMColor *color;
224 if (scr->depth == 1) {
225 Pixmap stipple;
226 WMColor *white = WMWhiteColor(scr);
227 WMColor *black = WMBlackColor(scr);
228 XGCValues gcv;
230 stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
231 LIGHT_STIPPLE_BITS, LIGHT_STIPPLE_WIDTH,
232 LIGHT_STIPPLE_HEIGHT);
234 color = createRGBAColor(scr, 0xffff, 0xffff, 0xffff, 0xffff);
236 gcv.foreground = white->color.pixel;
237 gcv.background = black->color.pixel;
238 gcv.fill_style = FillStippled;
239 gcv.stipple = stipple;
240 color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
241 | GCBackground | GCStipple | GCFillStyle
242 | GCGraphicsExposures, &gcv);
244 XFreePixmap(scr->display, stipple);
245 WMReleaseColor(white);
246 WMReleaseColor(black);
247 } else {
248 color = WMCreateRGBColor(scr, 0xaeba, 0xaaaa, 0xaeba, True);
249 if (!color->flags.exact)
250 wwarning(_("could not allocate %s color"), _("gray"));
252 scr->gray = color;
254 return WMRetainColor(scr->gray);
257 WMColor *WMDarkGrayColor(WMScreen * scr)
259 if (!scr->darkGray) {
260 WMColor *color;
262 if (scr->depth == 1) {
263 Pixmap stipple;
264 WMColor *white = WMWhiteColor(scr);
265 WMColor *black = WMBlackColor(scr);
266 XGCValues gcv;
268 stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
269 DARK_STIPPLE_BITS, DARK_STIPPLE_WIDTH,
270 DARK_STIPPLE_HEIGHT);
272 color = createRGBAColor(scr, 0, 0, 0, 0xffff);
274 gcv.foreground = white->color.pixel;
275 gcv.background = black->color.pixel;
276 gcv.fill_style = FillStippled;
277 gcv.stipple = stipple;
278 color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
279 | GCBackground | GCStipple | GCFillStyle
280 | GCGraphicsExposures, &gcv);
282 XFreePixmap(scr->display, stipple);
283 WMReleaseColor(white);
284 WMReleaseColor(black);
285 } else {
286 color = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True);
287 if (!color->flags.exact)
288 wwarning(_("could not allocate %s color"), _("dark gray"));
290 scr->darkGray = color;
292 return WMRetainColor(scr->darkGray);
295 unsigned short WMRedComponentOfColor(WMColor * color)
297 return color->color.red;
300 unsigned short WMGreenComponentOfColor(WMColor * color)
302 return color->color.green;
305 unsigned short WMBlueComponentOfColor(WMColor * color)
307 return color->color.blue;
310 unsigned short WMGetColorAlpha(WMColor * color)
312 return color->alpha;
315 char *WMGetColorRGBDescription(WMColor * color)
317 char *str = wmalloc(32);
319 sprintf(str, "#%02x%02x%02x", color->color.red >> 8, color->color.green >> 8, color->color.blue >> 8);
321 return str;