2 Around 12/20/99 we did the 3rd rewrite of the shadow/hilite stuff.
3 (That I know about (dje).
4 The first stuff I saw just applied a percentage.
5 Then we got some code from SCWM.
6 This stuff comes from "Visual.c" which is part of Lesstif.
7 Here's their copyright:
9 * Copyright (C) 1995 Free Software Foundation, Inc.
11 * This file is part of the GNU LessTif Library.
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Library General Public
15 * License as published by the Free Software Foundation; either
16 * version 2 of the License, or (at your option) any later version.
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Library General Public License for more details.
23 * You should have received a copy of the GNU Library General Public
24 * License along with this library; if not, write to the Free
25 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 The routine at the bottom "pixel_to_color_string" was not from Lesstif.
30 Port by Dan Espen, no additional copyright
33 #include "config.h" /* must be first */
36 #include <X11/Xproto.h> /* for X functions in general */
37 #include "fvwmlib.h" /* prototype GetShadow GetHilit */
39 #define PCT_BRIGHTNESS (6 * 0xffff / 100)
41 /* How much lighter/darker to make things in default routine */
43 #define PCT_DARK_BOTTOM 70 /* lighter (less dark, actually) */
44 #define PCT_DARK_TOP 50 /* lighter */
45 #define PCT_LIGHT_BOTTOM 55 /* darker */
46 #define PCT_LIGHT_TOP 80 /* darker */
47 #define PCT_MEDIUM_BOTTOM_BASE 40 /* darker */
48 #define PCT_MEDIUM_BOTTOM_RANGE 25
49 #define PCT_MEDIUM_TOP_BASE 60 /* lighter */
50 #define PCT_MEDIUM_TOP_RANGE -30
52 /* The "brightness" of an RGB color. The "right" way seems to use
53 * empirical values like the default thresholds below, but it boils down
54 * to red is twice as bright as blue and green is thrice blue.
57 #define BRIGHTNESS(r,g,b) (2*(int)(r) + 3*(int)(g) + 1*(int)(b))
59 /* From Xm.h on Solaris */
60 #define XmDEFAULT_DARK_THRESHOLD 15
61 #define XmDEFAULT_LIGHT_THRESHOLD 85
62 extern Colormap Pcmap
;
67 /**** This part is the old fvwm way to calculate colours. Still used for
68 **** 'medium' brigness colours. */
69 #define DARKNESS_FACTOR 0.5
70 #define BRIGHTNESS_FACTOR 1.4
72 #define HALF_SCALE (SCALE / 2)
74 R_MAX_G_MIN
, R_MAX_B_MIN
,
75 G_MAX_B_MIN
, G_MAX_R_MIN
,
76 B_MAX_R_MIN
, B_MAX_G_MIN
79 color_mult (unsigned short *red
,
80 unsigned short *green
,
81 unsigned short *blue
, double k
)
83 if (*red
== *green
&& *red
== *blue
) {
86 temp
= k
* (double) (*red
);
90 *red
= (unsigned short)(temp
);
94 /* Non-zero saturation */
100 MinMaxState min_max_state
;
111 min_max_state
= R_MAX_G_MIN
;
115 min_max_state
= R_MAX_B_MIN
;
121 min_max_state
= B_MAX_G_MIN
;
129 min_max_state
= G_MAX_B_MIN
;
133 min_max_state
= G_MAX_R_MIN
;
139 min_max_state
= B_MAX_R_MIN
;
148 if (l
<= HALF_SCALE
) {
151 s
= 2.0 * SCALE
- (max
+ min
);
164 if (l
<= HALF_SCALE
) {
167 max
= s
* SCALE
+ l
- s
* l
;
172 middle
= min
+ delta
* a
;
174 switch (min_max_state
) {
207 *red
= (unsigned short) r
;
208 *green
= (unsigned short) g
;
209 *blue
= (unsigned short) b
;
212 /**** End of original fvwm code. ****/
214 static XColor
*GetShadowOrHiliteColor(
215 Pixel background
, float light
, float dark
, float factor
)
218 unsigned short red
, green
, blue
;
220 memset(&color
, 0, sizeof(color
));
221 color
.pixel
= background
;
222 XQueryColor(Pdpy
, Pcmap
, &color
);
227 brightness
= BRIGHTNESS(red
, green
, blue
);
228 /* For "dark" backgrounds, make everything a fixed %age lighter */
229 if (brightness
< XmDEFAULT_DARK_THRESHOLD
* PCT_BRIGHTNESS
)
231 color
.red
= 0xffff - ((0xffff - red
) * dark
+ 50) / 100;
232 color
.green
= 0xffff - ((0xffff - green
) * dark
+ 50) / 100;
233 color
.blue
= 0xffff - ((0xffff - blue
) * dark
+ 50) / 100;
235 /* For "light" background, make everything a fixed %age darker */
236 else if (brightness
> XmDEFAULT_LIGHT_THRESHOLD
* PCT_BRIGHTNESS
)
238 color
.red
= (red
* light
+ 50) / 100;
239 color
.green
= (green
* light
+ 50) / 100;
240 color
.blue
= (blue
* light
+ 50) / 100;
242 /* For "medium" background, select is a fixed %age darker;
243 * top (lighter) and bottom (darker) are a variable %age
244 * based on the background's brightness
248 color_mult(&color
.red
, &color
.green
, &color
.blue
, factor
);
254 XColor
*GetShadowColor(Pixel background
)
256 return GetShadowOrHiliteColor(
257 background
, PCT_DARK_BOTTOM
, PCT_DARK_TOP
, DARKNESS_FACTOR
);
260 Pixel
GetShadow(Pixel background
)
264 colorp
= GetShadowColor(background
);
265 XAllocColor (Pdpy
, Pcmap
, colorp
);
266 return colorp
->pixel
;
269 XColor
*GetHiliteColor(Pixel background
)
271 return GetShadowOrHiliteColor(
272 background
, PCT_LIGHT_BOTTOM
, PCT_LIGHT_BOTTOM
, BRIGHTNESS_FACTOR
);
275 Pixel
GetHilite(Pixel background
)
279 colorp
= GetHiliteColor(background
);
280 XAllocColor (Pdpy
, Pcmap
, colorp
);
281 return colorp
->pixel
;
284 /* This function converts the colour stored in a colorcell (pixel) into the
285 * string representation of a colour. The output is printed at the
286 * address 'output'. It is either in rgb format ("rgb:rrrr/gggg/bbbb") if
287 * use_hash is False or in hash notation ("#rrrrggggbbbb") if use_hash is true.
288 * The return value is the number of characters used by the string. The
289 * rgb values of the output are undefined if the colorcell is invalid. The
290 * memory area pointed at by 'output' must be at least 64 bytes (in case of
291 * future extensions and multibyte characters).*/
292 int pixel_to_color_string(
293 Display
*dpy
, Colormap cmap
, Pixel pixel
, char *output
, Bool use_hash
)
303 XQueryColor(dpy
, cmap
, &color
);
306 sprintf(output
, "rgb:%04x/%04x/%04x%n", (int)color
.red
, (int)color
.green
,
307 (int)color
.blue
, &n
);
311 sprintf(output
, "#%04x%04x%04x%n", (int)color
.red
, (int)color
.green
,
312 (int)color
.blue
, &n
);