Here is the getcolor.c:
#include <X11/Xlib.h>
#include <Imlib2.h>
#include <stdio.h>
int main(int argc, char **argv) {
/**
DELTA : The minimum difference between the dark color and the light color.
If the differences of red, green and blue between dark and light color are ALL less than DELTA,
The light color and dark color are too close. A color correction
algorithm will kick in to seperate them.
The color correction use SH and HI to control the final dark and light
color to make sure they are not too saturated.
SH : the lowest value of RGB
HI : the highest value of RGB
You can change these to meet your taste.
To compile,
gcc `imlib2-config --cflags --libs` -o getcolor getcolor.c
You need imlib2 installed first.
*/
int DELTA=0x20, SH=0x20, HI=0xE0;
Imlib_Image image;
int x;
int y;
int dark, light;
Imlib_Color dark_color, light_color;
Imlib_Color sample_color;
int dr, dg, db;
dark_color.red=SH;
dark_color.green=SH;
dark_color.blue=SH;
dark_color.red=HI;
dark_color.green=HI;
dark_color.blue=HI;
dark = 255*3;
light = 0;
if ( argc != 2 ) {
printf("Usage: getcolor imageFile\n");
return 1;
}
image = imlib_load_image(argv[1]);
if (image) {
imlib_context_set_image(image);
x = imlib_image_get_width()/3;
y = imlib_image_get_height()/3;
imlib_image_query_pixel(x, y, &sample_color);
if (dark > (sample_color.red + sample_color.green +sample_color.blue)) {
dark_color = sample_color;
dark = sample_color.red + sample_color.green +sample_color.blue;
}
if (light < (sample_color.red + sample_color.green +sample_color.blue)) {
light_color = sample_color;
light = sample_color.red + sample_color.green +sample_color.blue;
}
imlib_image_query_pixel(2*x, y, &sample_color);
if (dark > (sample_color.red + sample_color.green +sample_color.blue)) {
dark_color = sample_color;
dark = sample_color.red + sample_color.green +sample_color.blue;
}
if (light < (sample_color.red + sample_color.green +sample_color.blue)) {
light_color = sample_color;
light = sample_color.red + sample_color.green +sample_color.blue;
}
imlib_image_query_pixel(x, 2*y, &sample_color);
if (dark > (sample_color.red + sample_color.green +sample_color.blue)) {
dark_color = sample_color;
dark = sample_color.red + sample_color.green +sample_color.blue;
}
if (light < (sample_color.red + sample_color.green +sample_color.blue)) {
light_color = sample_color;
light = sample_color.red + sample_color.green +sample_color.blue;
}
imlib_image_query_pixel(2*x, 2*y, &sample_color);
if (dark > (sample_color.red + sample_color.green +sample_color.blue)) {
dark_color = sample_color;
dark = sample_color.red + sample_color.green +sample_color.blue;
}
if (light < (sample_color.red + sample_color.green +sample_color.blue)) {
light_color = sample_color;
light = sample_color.red + sample_color.green +sample_color.blue;
}
/*
printf ("DynColorSet rgb:%02X/%02X/%02X rgb:%02X/%02X/%02X\n",
dark_color.red, dark_color.green, dark_color.blue,
light_color.red, light_color.green, light_color.blue);
*/
dr = light_color.red - dark_color.red;
dg = light_color.green - dark_color.green;
db = light_color.blue - dark_color.blue;
if (dr<2*DELTA && dr>-2*DELTA &&
dg<2*DELTA && dg>-2*DELTA &&
db<2*DELTA && db>-2*DELTA ) {
// Too close, should be seperated
if (dr>=0 && dr<2*DELTA) {
light_color.red += DELTA;
dark_color.red -= DELTA;
if (light_color.red > HI) {
dark_color.red -= light_color.red - HI;
light_color.red = HI;
} else if (dark_color.red < SH) {
light_color.red += SH-dark_color.red;
dark_color.red = SH;
}
}
if (dr<0 && dr>-2*DELTA) {
light_color.red -= DELTA;
dark_color.red += DELTA;
if (light_color.red < SH ) {
dark_color.red += SH-light_color.red;
light_color.red = SH;
} else if (dark_color.red > HI) {
light_color.red -= dark_color.red-HI;
dark_color.red = HI;
}
}
if (dg>=0 && dg<2*DELTA) {
light_color.green += DELTA;
dark_color.green -= DELTA;
if (light_color.green > HI) {
dark_color.green -= light_color.green - HI;
light_color.green = HI;
} else if (dark_color.green < SH) {
light_color.green += SH-dark_color.green;
dark_color.green = SH;
}
}
if (dg<0 && dg>-2*DELTA) {
light_color.green -= DELTA;
dark_color.green += DELTA;
if (light_color.green < SH ) {
dark_color.green += SH-light_color.green;
light_color.green = SH;
} else if (dark_color.green > HI) {
light_color.green -= dark_color.green-HI;
dark_color.green = HI;
}
}
if (db>=0 && db<2*DELTA) {
light_color.blue += DELTA;
dark_color.blue -= DELTA;
if (light_color.blue > HI) {
dark_color.blue -= light_color.blue - HI;
light_color.blue = HI;
} else if (dark_color.blue < SH) {
light_color.blue += SH-dark_color.blue;
dark_color.blue = SH;
}
}
if (db<0 && db>-2*DELTA) {
light_color.blue -= DELTA;
dark_color.blue += DELTA;
if (light_color.blue < SH ) {
dark_color.blue += SH-light_color.blue;
light_color.blue = SH;
} else if (dark_color.blue > HI) {
light_color.blue -= dark_color.blue-HI;
dark_color.blue = HI;
}
}
}
printf ("DynColorSet rgb:%02X/%02X/%02X rgb:%02X/%02X/%02X\n",
dark_color.red, dark_color.green, dark_color.blue,
light_color.red, light_color.green, light_color.blue);
imlib_free_image();
return 0;
}
printf ("None\n");
return 1;
}
And DynColorSet
function in config
:
# Colorset
# Color 10 for FvwmBottons
# Color 11 for FvwmIconMan plain, 12 for focus or select and FvwmScript
# Color 13 for FvwmMenu
# Color 16 for focused windows
# Color 17 for unfocused windows
# Color 18 for pager windows.
# Color 19 for pager focused windows
# Color 21 for pager, 22 for pager hilight
DestroyFunc DynColorSet
AddToFunc DynColorSet
+ I CleanupColorsets
+ I Colorset 10 Tint $0 60, bgTint $0 60, RootTransparent
+ I Colorset 11 fg rgb:BF/BF/BF, bg $1, hi $1, sh $1, fgsh rgb:3F/3F/3F, Transparent
+ I Colorset 12 fg white, bg $1, hi $1, sh $1, fgsh rgb:7F/7F/7F, Transparent
+ I Colorset 13 fg white, Translucent $0 80, hi $1, sh $1, fgsh black
+ I Colorset 16 fg white, bg $1, fgsh black
+ I Colorset 17 hi gray30, bg $0, sh black
+ I Colorset 18 DGradient 100 gray80 $0
+ I Colorset 19 DGradient 100 white $1
+ I Colorset 21 fg rgb:BF/BF/BF, fgsh rgb:3F/3F/3F, hi $0, sh $0, bg $0, Tint $0 60, bgTint $0 60, RootTransparent
+ I Colorset 22 fg white, fgsh rgb:7F/7F/7F, hi $1, sh $1, bg $1, Tint $1 50, bgTint $1 60, Transparent
And my own version of wallpaper browse menu (Note: you may have to modify this code to meet your own setup and to use your own image thumbing program. This one use scale, which is another program that utilizes imlib2):
AddToMenu WallpaperMenu "Select Wall Paper" title
+ DynamicPopupAction Function WallpaperFunc
DestroyFunc WallpaperFunc
AddToFunc WallpaperFunc
+ I DestroyMenu recreate WallpaperMenu
+ I AddToMenu WallpaperMenu "Select Wallpaper" Title
+ I PipeRead \
'export bgPath=${HOME}/pictures/wallpapers; export bgtPath=${bgPath}/.bgt; \
if [ ! -e $bgtPath ]; then mkdir -p $bgtPath; fi ;\
for i in ${bgPath}/*.[jp][pn]g; \
do \
export file=`basename $i`; \
if [ ! -e ${bgtPath}/${file}.png ]; then \
${HOME}/.fvwm/thumb/scale 32 $i ${bgtPath}/${file}.png; \
fi; \
echo \
"AddToMenu WallpaperMenu \"%${bgtPath}/${file}.png%${file}\" SetBg $i";\
done;'
DestroyFunc SetBg
AddToFunc SetBg
+ I PipeRead '${HOME}/.fvwm/thumb/getcolor $0'
+ I Exec exec feh --bg-scale $0
Enjoy!