- s/sprintf/snprintf
[wmaker-crm.git] / WINGs / wcolor.c
blob03a5266c67eeaf62c3b5e5f6cbb20e62a5421d82
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 *createRGBColor(WMScreen *scr, unsigned short red,
20 unsigned short green, unsigned short blue);
23 * TODO: make the color creation code return the same WMColor for the
24 * same colors.
25 * make findCloseColor() find the closest color in the RContext pallette
26 * or in the other colors allocated by WINGs.
29 static WMColor*
30 findCloseColor(WMScreen *scr, unsigned short red, unsigned short green,
31 unsigned short blue)
33 WMColor *color;
34 XColor xcolor;
35 RColor rcolor;
37 rcolor.red = red>>8;
38 rcolor.green = green>>8;
39 rcolor.blue = blue>>8;
41 if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor))
42 return NULL;
44 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
45 return NULL;
47 color = wmalloc(sizeof(WMColor));
49 color->screen = scr;
50 color->refCount = 1;
51 color->color = xcolor;
52 color->flags.exact = 1;
53 color->gc = NULL;
55 return color;
60 static WMColor*
61 createRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
62 unsigned short blue)
64 WMColor *color;
65 XColor xcolor;
67 xcolor.red = red;
68 xcolor.green = green;
69 xcolor.blue = blue;
70 xcolor.flags = DoRed|DoGreen|DoBlue;
71 if (!XAllocColor(scr->display, scr->colormap, &xcolor))
72 return NULL;
74 color = wmalloc(sizeof(WMColor));
76 color->screen = scr;
77 color->refCount = 1;
78 color->color = xcolor;
79 color->flags.exact = 1;
80 color->gc = NULL;
82 return color;
87 WMColor*
88 WMCreateRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
89 unsigned short blue, Bool exact)
91 WMColor *color = NULL;
93 if (!exact || !(color=createRGBColor(scr, red, green, blue))) {
94 color = findCloseColor(scr, red, green, blue);
96 if (!color)
97 color = WMBlackColor(scr);
99 return color;
103 WMColor*
104 WMCreateNamedColor(WMScreen *scr, char *name, Bool exact)
106 WMColor *color;
107 XColor xcolor;
109 if (!XParseColor(scr->display, scr->colormap, name, &xcolor))
110 return NULL;
112 if (scr->visual->class == TrueColor)
113 exact = True;
115 if (!exact || !(color=createRGBColor(scr, xcolor.red, xcolor.green,
116 xcolor.blue))) {
117 color = findCloseColor(scr, xcolor.red, xcolor.green, xcolor.blue);
119 return color;
124 WMColor*
125 WMRetainColor(WMColor *color)
127 assert(color!=NULL);
129 color->refCount++;
131 return color;
135 void
136 WMReleaseColor(WMColor *color)
138 color->refCount--;
140 if (color->refCount < 1) {
141 XFreeColors(color->screen->display, color->screen->colormap,
142 &(color->color.pixel), 1, 0);
143 if (color->gc)
144 XFreeGC(color->screen->display, color->gc);
145 wfree(color);
150 void
151 WMPaintColorSwatch(WMColor *color, Drawable d, int x, int y,
152 unsigned int width, unsigned int height)
154 XFillRectangle(color->screen->display, d, WMColorGC(color),
155 x, y, width, height);
159 WMPixel
160 WMColorPixel(WMColor *color)
162 return color->color.pixel;
167 WMColorGC(WMColor *color)
169 if (!color->gc) {
170 XGCValues gcv;
171 WMScreen *scr = color->screen;
173 gcv.foreground = color->color.pixel;
174 gcv.graphics_exposures = False;
175 color->gc = XCreateGC(scr->display, scr->rcontext->drawable,
176 GCForeground|GCGraphicsExposures, &gcv);
179 return color->gc;
183 void
184 WMSetColorInGC(WMColor *color, GC gc)
186 XSetForeground(color->screen->display, gc, color->color.pixel);
191 /* "system" colors */
192 WMColor*
193 WMWhiteColor(WMScreen *scr)
195 if (!scr->white) {
196 scr->white = WMCreateRGBColor(scr, 0xffff, 0xffff, 0xffff, True);
197 if (!scr->white->flags.exact)
198 wwarning(_("could not allocate %s color"), _("white"));
200 return WMRetainColor(scr->white);
205 WMColor*
206 WMBlackColor(WMScreen *scr)
208 if (!scr->black) {
209 scr->black = WMCreateRGBColor(scr, 0, 0, 0, True);
210 if (!scr->black->flags.exact)
211 wwarning(_("could not allocate %s color"), _("black"));
213 return WMRetainColor(scr->black);
218 WMColor*
219 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 = createRGBColor(scr, 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);
259 WMColor*
260 WMDarkGrayColor(WMScreen *scr)
262 if (!scr->darkGray) {
263 WMColor *color;
265 if (scr->depth == 1) {
266 Pixmap stipple;
267 WMColor *white = WMWhiteColor(scr);
268 WMColor *black = WMBlackColor(scr);
269 XGCValues gcv;
271 stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
272 DARK_STIPPLE_BITS, DARK_STIPPLE_WIDTH,
273 DARK_STIPPLE_HEIGHT);
275 color = createRGBColor(scr, 0, 0, 0);
277 gcv.foreground = white->color.pixel;
278 gcv.background = black->color.pixel;
279 gcv.fill_style = FillStippled;
280 gcv.stipple = stipple;
281 color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
282 |GCBackground|GCStipple|GCFillStyle
283 |GCGraphicsExposures, &gcv);
285 XFreePixmap(scr->display, stipple);
286 WMReleaseColor(white);
287 WMReleaseColor(black);
288 } else {
289 color = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True);
290 if (!color->flags.exact)
291 wwarning(_("could not allocate %s color"), _("dark gray"));
293 scr->darkGray = color;
295 return WMRetainColor(scr->darkGray);
299 unsigned short
300 WMRedComponentOfColor(WMColor *color)
302 return color->color.red;
306 unsigned short
307 WMGreenComponentOfColor(WMColor *color)
309 return color->color.green;
313 unsigned short
314 WMBlueComponentOfColor(WMColor *color)
316 return color->color.blue;
320 char*
321 WMGetColorRGBDescription(WMColor *color)
323 char *str = wmalloc(32);
325 sprintf(str, "#%02x%02x%02x", color->color.red>>8, color->color.green>>8,
326 color->color.blue>>8);
328 return str;