cvsimport
[fvwm.git] / fvwm / colorset.c
blobd706bc8c08ad3f5ce125768f681e494db19a99de
1 /* -*-c-*- */
2 /* Copyright (C) 2002 the late Joey Shutup.
4 * http://www.streetmap.co.uk/streetmap.dll?postcode2map?BS24+9TZ
6 * No guarantees or warranties or anything are provided or implied in any way
7 * whatsoever. Use this program at your own risk. Permission to use this
8 * program for any purpose is given, as long as the copyright is kept intact.
9 */
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* ---------------------------- included header files ---------------------- */
28 #include "config.h"
30 #include <stdio.h>
31 #include <X11/Xatom.h>
33 #include "libs/fvwmlib.h"
34 #include "libs/Parse.h"
35 #include "libs/PictureBase.h"
36 #include "libs/FShape.h"
37 #include "libs/ColorUtils.h"
38 #include "libs/Picture.h"
39 #include "libs/PictureUtils.h"
40 #include "libs/Graphics.h"
41 #include "libs/PictureGraphics.h"
42 #include "libs/FRenderInit.h"
43 #include "libs/Strings.h"
44 #include "libs/Grab.h"
45 #include "colorset.h"
46 #include "externs.h"
47 #include "fvwm.h"
48 #include "cursor.h"
49 #include "functions.h"
50 #include "commands.h"
51 #include "misc.h"
52 #include "screen.h"
53 #include "module_interface.h"
54 #include "execcontext.h"
55 #include "builtins.h"
57 /* ---------------------------- local definitions -------------------------- */
59 /* ---------------------------- local macros ------------------------------- */
61 /* ---------------------------- imports ------------------------------------ */
63 extern int nColorsets; /* in libs/Colorset.c */
65 /* ---------------------------- included code files ------------------------ */
67 /* ---------------------------- local types -------------------------------- */
69 /* When fvwm destroys pixmaps it puts them on a list and only destroys them
70 * after some period of inactivity. This is necessary because changing colorset
71 * options rapidly may result in a module redrawing itself due to the first
72 * change while the second change is happening. If the module renders something
73 * with the colorset affected by the second change there is a chance it may
74 * reference pixmaps that FvwmTheme has destroyed, bad things would happen */
75 struct junklist
77 struct junklist *prev;
78 Pixmap pixmap;
81 struct root_pic
83 Pixmap pixmap;
84 Pixmap old_pixmap;
85 int width;
86 int height;
89 /* ---------------------------- forward declarations ----------------------- */
91 /* ---------------------------- local variables ---------------------------- */
93 static char *black = "black";
94 static char *white = "white";
95 static char *gray = "gray";
97 static struct junklist *junk = NULL;
98 static Bool cleanup_scheduled = False;
99 static struct root_pic root_pic = {None, None, 0, 0};
101 static char *csetopts[] =
103 "Foreground",
104 "Fore",
105 "fg",
107 "Background",
108 "Back",
109 "bg",
111 "Hilight",
112 "Hilite",
113 "hi",
115 "Shadow",
116 "Shade",
117 "sh",
119 "fgsh",
120 "fg_alpha",
121 "fgAlpha",
123 /* these strings are used inside the cases in the switch below! */
124 "Pixmap",
125 "TiledPixmap",
126 "AspectPixmap",
128 /* these strings are used inside the cases in the switch below! */
129 "Shape",
130 "TiledShape",
131 "AspectShape",
133 /* switch off pixmaps and gradients */
134 "Plain",
135 /* switch off shape */
136 "NoShape",
138 /* Make the background transparent, copies the root window background */
139 "Transparent",
140 "RootTransparent",
142 /* tint for the Pixmap or the gradient */
143 "Tint",
144 "PixmapTint", /* ~ Tint */
145 "ImageTint", /* ~ Tint */
146 "TintMask", /* ~ Tint (backward compatibility) */
147 "NoTint", /* ~ Tint without argument */
149 "fgTint",
150 "bgTint",
152 /* Dither the Pixmap or the gradient */
153 "Dither",
154 "NoDither",
156 /* alpha for the Pixmap or the gradient */
157 "Alpha",
158 "PixmapAlpha", /* ~ Alpha */
159 "ImageAlpha", /* ~ Alpha */
161 /* Icon stuff */
162 "DitherIcon",
163 "NoDitherIcon",
164 "IconTint",
165 "NoIconTint",
166 "IconAlpha",
168 NULL
171 /* ---------------------------- exported variables (globals) --------------- */
173 /* ---------------------------- local functions ---------------------------- */
174 static
175 Pixmap get_root_pixmap(Atom prop)
177 Atom type;
178 int format;
179 unsigned long length, after;
180 unsigned char *reteval = NULL;
181 int ret;
182 Pixmap pix = None;
184 ret = XGetWindowProperty(
185 dpy, Scr.Root, prop, 0L, 1L, False, XA_PIXMAP,
186 &type, &format, &length, &after, &reteval);
187 if (
188 ret == Success && type == XA_PIXMAP && format == 32 &&
189 length == 1 && after == 0)
191 pix = (Pixmap)(*(long *)reteval);
193 if (reteval)
195 XFree(reteval);
197 return pix;
200 void update_root_pixmap(Atom prop)
202 static Atom a_rootpix = None;
203 int w = 0;
204 int h = 0;
205 XID dummy;
206 Pixmap pix;
208 if (a_rootpix == None)
210 a_rootpix = XInternAtom(dpy,"_XROOTPMAP_ID", False);
212 XSync(dpy, False);
213 if (prop != 0)
215 pix = get_root_pixmap(prop);
216 if (pix && !XGetGeometry(
217 dpy, pix, &dummy, (int *)&dummy, (int *)&dummy,
218 (unsigned int *)&w, (unsigned int *)&h,
219 (unsigned int *)&dummy, (unsigned int *)&dummy))
221 pix = None;
224 else
226 pix = get_root_pixmap(a_rootpix);
227 if (pix && !XGetGeometry(
228 dpy, pix, &dummy, (int *)&dummy, (int *)&dummy,
229 (unsigned int *)&w, (unsigned int *)&h,
230 (unsigned int *)&dummy, (unsigned int *)&dummy))
232 pix = None;
235 root_pic.pixmap = pix;
236 root_pic.width = w;
237 root_pic.height = h;
238 #if 0
239 fprintf(stderr,"Get New Root Pixmap: 0x%lx %i,%i\n",
240 root_pic.pixmap, w, h);
241 #endif
244 static void add_to_junk(Pixmap pixmap)
246 struct junklist *oldjunk = junk;
248 junk = (struct junklist *)safemalloc(sizeof(struct junklist));
249 junk->prev = oldjunk;
250 junk->pixmap = pixmap;
251 if (!cleanup_scheduled)
253 const exec_context_t *exc;
255 exc = exc_create_null_context();
256 CMD_Schedule(NULL, exc, "3000 CleanupColorsets");
257 exc_destroy_context(exc);
258 cleanup_scheduled = True;
261 return;
264 static char *get_simple_color(
265 char *string, char **color, colorset_t *cs, int supplied_color,
266 int special_flag, char *special_string)
268 char *rest;
270 if (*color)
272 free(*color);
273 *color = NULL;
275 rest = GetNextToken(string, color);
276 if (*color)
278 if (special_string && StrEquals(*color, special_string))
280 free(*color);
281 *color = NULL;
282 cs->color_flags |= special_flag;
283 cs->color_flags &= ~supplied_color;
285 else
287 cs->color_flags |= supplied_color;
288 cs->color_flags &= ~special_flag;
291 else
293 cs->color_flags &= ~(supplied_color | special_flag);
296 return rest;
299 static void SafeDestroyPicture(Display *dpy, FvwmPicture *picture)
301 /* have to subvert destroy picture so that it doesn't free pixmaps,
302 * these are added to the junk list to be cleaned up after a timeout */
303 if (picture->count < 2)
305 if (picture->picture)
307 add_to_junk(picture->picture);
308 picture->picture = None;
310 if (picture->mask)
312 add_to_junk(picture->mask);
313 picture->mask = None;
315 if (picture->alpha)
317 add_to_junk(picture->alpha);
318 picture->alpha = None;
321 /* all that this will now do is free the colors and the name */
322 PDestroyFvwmPicture(dpy, picture);
324 return;
327 static void free_colorset_background(colorset_t *cs, Bool do_free_args)
329 if (cs->picture != NULL)
331 if (cs->picture->picture != cs->pixmap)
333 add_to_junk(cs->pixmap);
335 SafeDestroyPicture(dpy, cs->picture);
336 cs->picture = NULL;
337 cs->pixmap = None;
338 cs->alpha_pixmap = None; /* alaways equal to picture->alpha */
340 if (cs->pixmap && cs->pixmap != ParentRelative &&
341 cs->pixmap != root_pic.pixmap && cs->pixmap != root_pic.old_pixmap)
343 add_to_junk(cs->pixmap);
345 cs->pixmap = None;
346 if (cs->mask)
348 add_to_junk(cs->mask);
349 cs->mask = None;
351 if (cs->alpha_pixmap)
353 add_to_junk(cs->alpha_pixmap);
354 cs->alpha_pixmap = None;
356 if (cs->pixels && cs->nalloc_pixels)
358 PictureFreeColors(
359 dpy, Pcmap, cs->pixels, cs->nalloc_pixels, 0, False);
360 free(cs->pixels);
361 cs->pixels = NULL;
362 cs->nalloc_pixels = 0;
364 if (do_free_args)
366 if (cs->pixmap_args != NULL)
368 free(cs->pixmap_args);
369 cs->pixmap_args = NULL;
371 if (cs->gradient_args != NULL)
373 free(cs->gradient_args);
374 cs->gradient_args = NULL;
376 cs->is_maybe_root_transparent = False;
377 cs->pixmap_type = 0;
381 static void reset_cs_pixmap(colorset_t *cs, GC gc)
383 if (Pdepth == cs->picture->depth)
385 XCopyArea(dpy, cs->picture->picture, cs->pixmap, gc,
386 0, 0, cs->width, cs->height, 0, 0);
388 else
390 XCopyPlane(dpy, cs->picture->picture, cs->pixmap, gc,
391 0, 0, cs->width, cs->height, 0, 0, 1);
394 return;
397 static void parse_pixmap(
398 Window win, GC gc, colorset_t *cs, Bool *pixmap_is_a_bitmap)
400 static char *name = "parse_colorset(pixmap)";
401 FvwmPictureAttributes fpa;
403 /* dither */
404 fpa.mask = 0;
405 if (cs->dither)
407 fpa.mask = FPAM_DITHER;
410 /* read filename */
411 if (!cs->pixmap_args)
413 return;
415 /* load the file */
416 cs->picture = PCacheFvwmPicture(dpy, win, NULL, cs->pixmap_args, fpa);
417 if (cs->picture == NULL)
419 fvwm_msg(ERR, name, "can't load picture %s", cs->pixmap_args);
420 return;
422 if (cs->picture->depth != Pdepth)
424 *pixmap_is_a_bitmap = True;
425 cs->pixmap = None; /* build cs->pixmap later */
427 /* copy the picture pixmap into the public structure */
428 cs->width = cs->picture->width;
429 cs->height = cs->picture->height;
430 cs->alpha_pixmap = cs->picture->alpha;
432 if (!*pixmap_is_a_bitmap)
434 cs->pixmap = XCreatePixmap(dpy, win,
435 cs->width, cs->height,
436 Pdepth);
437 XSetClipMask(dpy, gc, cs->picture->mask);
438 XCopyArea(dpy, cs->picture->picture, cs->pixmap, gc,
439 0, 0, cs->width, cs->height, 0, 0);
440 XSetClipMask(dpy, gc, None);
442 if (cs->pixmap)
444 if (cs->picture->mask != None)
446 /* make an inverted copy of the mask */
447 cs->mask = XCreatePixmap(dpy, win,
448 cs->width, cs->height,
450 if (cs->mask)
452 XCopyArea(dpy, cs->picture->mask, cs->mask,
453 Scr.MonoGC,
454 0, 0, cs->width, cs->height, 0, 0);
455 /* Invert the mask. We use it to draw the
456 * background. */
457 XSetFunction(dpy, Scr.MonoGC, GXinvert);
458 XFillRectangle(dpy, cs->mask, Scr.MonoGC,
459 0, 0, cs->width, cs->height);
460 XSetFunction(dpy, Scr.MonoGC, GXcopy);
466 static void parse_shape(Window win, colorset_t *cs, int i, char *args,
467 int *has_shape_changed)
469 char *token;
470 static char *name = "parse_colorset(shape)";
471 FvwmPicture *picture;
472 FvwmPictureAttributes fpa;
474 if (!FHaveShapeExtension)
476 cs->shape_mask = None;
477 return;
480 /* read filename */
481 token = PeekToken(args, &args);
482 *has_shape_changed = True;
483 if (cs->shape_mask)
485 add_to_junk(cs->shape_mask);
486 cs->shape_mask = None;
489 /* set the flags */
490 if (csetopts[i][0] == 'T')
492 cs->shape_type = SHAPE_TILED;
494 else if (csetopts[i][0] == 'A')
496 cs->shape_type = SHAPE_STRETCH_ASPECT;
498 else
500 cs->shape_type = SHAPE_STRETCH;
502 fpa.mask = FPAM_NO_ALPHA;
504 /* try to load the shape mask */
505 if (!token)
507 return;
510 /* load the shape mask */
511 picture = PCacheFvwmPicture(dpy, win, NULL, token, fpa);
512 if (!picture)
514 fvwm_msg(ERR, name, "can't load picture %s", token);
516 else if (picture->depth != 1 && picture->mask == None)
518 fvwm_msg(ERR, name, "shape pixmap must be of depth 1");
519 SafeDestroyPicture(dpy, picture);
521 else
523 Pixmap mask;
525 /* okay, we have what we want */
526 if (picture->mask != None)
528 mask = picture->mask;
530 else
532 mask = picture->picture;
534 cs->shape_width = picture->width;
535 cs->shape_height = picture->height;
537 if (mask != None)
539 cs->shape_mask = XCreatePixmap(
540 dpy, mask, picture->width, picture->height, 1);
541 if (cs->shape_mask != None)
543 XCopyPlane(dpy, mask, cs->shape_mask,
544 Scr.MonoGC, 0, 0, picture->width,
545 picture->height, 0, 0, 1);
549 if (picture)
551 SafeDestroyPicture(dpy, picture);
552 picture = None;
554 return;
557 static void parse_simple_tint(
558 colorset_t *cs, char *args, char **tint, int supplied_color,
559 int *changed, int *percent, char *cmd)
561 char *rest;
562 static char *name = "parse_colorset (tint)";
564 *changed = False;
565 rest = get_simple_color(args, tint, cs, supplied_color, 0, NULL);
566 if (!(cs->color_flags & supplied_color))
568 /* restore to default */
569 *percent = 0;
570 *changed = True;
571 cs->color_flags &= ~(supplied_color);
573 else if (!GetIntegerArguments(rest, NULL, percent, 1))
575 fvwm_msg(WARN, name,
576 "%s must have two arguments a color and an integer",
577 cmd);
578 return;
580 *changed = True;
581 if (*percent > 100)
583 *percent = 100;
585 else if (*percent < 0)
587 *percent = 0;
591 /* ---------------------------- interface functions ------------------------ */
593 void cleanup_colorsets(void)
595 struct junklist *oldjunk = junk;
597 while (junk)
599 XFreePixmap(dpy, junk->pixmap);
600 oldjunk = junk;
601 junk = junk->prev;
602 free(oldjunk);
604 cleanup_scheduled = False;
607 /* translate a colorset spec into a colorset structure */
608 void parse_colorset(int n, char *line)
610 int i;
611 int w;
612 int h;
613 int tmp;
614 int percent;
615 colorset_t *cs;
616 char *optstring;
617 char *args;
618 char *option;
619 char *tmp_str;
620 char *fg = NULL;
621 char *bg = NULL;
622 char *hi = NULL;
623 char *sh = NULL;
624 char *fgsh = NULL;
625 char *tint = NULL;
626 char *fg_tint = NULL;
627 char *bg_tint = NULL;
628 char *icon_tint = NULL;
629 Bool have_pixels_changed = False;
630 Bool has_icon_pixels_changed = False;
631 Bool has_fg_changed = False;
632 Bool has_bg_changed = False;
633 Bool has_sh_changed = False;
634 Bool has_hi_changed = False;
635 Bool has_fgsh_changed = False;
636 Bool has_fg_alpha_changed = False;
637 Bool has_tint_changed = False;
638 Bool has_fg_tint_changed = False;
639 Bool has_bg_tint_changed = False;
640 Bool has_icon_tint_changed = False;
641 Bool has_pixmap_changed = False;
642 Bool has_shape_changed = False;
643 Bool has_image_alpha_changed = False;
644 Bool pixmap_is_a_bitmap = False;
645 Bool do_reload_pixmap = False;
646 Bool is_server_grabbed = False;
647 XColor color;
648 XGCValues xgcv;
649 static char *name = "parse_colorset";
650 Window win = Scr.NoFocusWin;
651 static GC gc = None;
653 /* initialize statics */
654 if (gc == None)
656 gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv);
659 /* make sure it exists and has sensible contents */
660 alloc_colorset(n);
661 cs = &Colorset[n];
663 /*** Parse the options ***/
664 while (line && *line)
666 /* Read next option specification delimited by a comma or \0.
668 line = GetQuotedString(
669 line, &optstring, ",", NULL, NULL, NULL);
670 if (!optstring)
671 break;
672 args = GetNextToken(optstring, &option);
673 if (!option)
675 free(optstring);
676 break;
679 switch((i = GetTokenIndex(option, csetopts, 0, NULL)))
681 case 0: /* Foreground */
682 case 1: /* Fore */
683 case 2: /* fg */
684 get_simple_color(
685 args, &fg, cs, FG_SUPPLIED, FG_CONTRAST,
686 "contrast");
687 has_fg_changed = True;
688 break;
689 case 3: /* Background */
690 case 4: /* Back */
691 case 5: /* bg */
692 get_simple_color(
693 args, &bg, cs, BG_SUPPLIED, BG_AVERAGE,
694 "average");
695 has_bg_changed = True;
696 break;
697 case 6: /* Hilight */
698 case 7: /* Hilite */
699 case 8: /* hi */
700 get_simple_color(args, &hi, cs, HI_SUPPLIED, 0, NULL);
701 has_hi_changed = True;
702 break;
703 case 9: /* Shadow */
704 case 10: /* Shade */
705 case 11: /* sh */
706 get_simple_color(args, &sh, cs, SH_SUPPLIED, 0, NULL);
707 has_sh_changed = True;
708 break;
709 case 12: /* fgsh */
710 get_simple_color(
711 args, &fgsh, cs, FGSH_SUPPLIED, 0,NULL);
712 has_fgsh_changed = True;
713 break;
714 case 13: /* fg_alpha */
715 case 14: /* fgAlpha */
716 if (GetIntegerArguments(args, NULL, &tmp, 1))
718 if (tmp > 100)
719 tmp = 100;
720 else if (tmp < 0)
721 tmp = 0;
723 else
725 tmp = 100;
727 if (tmp != cs->fg_alpha_percent)
729 cs->fg_alpha_percent = tmp;
730 has_fg_alpha_changed = True;
732 break;
733 case 15: /* TiledPixmap */
734 case 16: /* Pixmap */
735 case 17: /* AspectPixmap */
736 has_pixmap_changed = True;
737 free_colorset_background(cs, True);
738 tmp_str = PeekToken(args, &args);
739 if (tmp_str)
741 CopyString(&cs->pixmap_args, tmp_str);
742 do_reload_pixmap = True;
743 cs->gradient_type = 0;
744 /* set the flags */
745 if (csetopts[i][0] == 'T')
747 cs->pixmap_type = PIXMAP_TILED;
749 else if (csetopts[i][0] == 'A')
751 cs->pixmap_type = PIXMAP_STRETCH_ASPECT;
753 else
755 cs->pixmap_type = PIXMAP_STRETCH;
758 /* the pixmap is build later */
759 break;
760 case 18: /* Shape */
761 case 19: /* TiledShape */
762 case 20: /* AspectShape */
763 parse_shape(win, cs, i, args, &has_shape_changed);
764 break;
765 case 21: /* Plain */
766 has_pixmap_changed = True;
767 free_colorset_background(cs, True);
768 break;
769 case 22: /* NoShape */
770 has_shape_changed = True;
771 if (cs->shape_mask)
773 add_to_junk(cs->shape_mask);
774 cs->shape_mask = None;
776 break;
777 case 23: /* Transparent */
779 /* This is only allowable when the root depth == fvwm
780 * visual depth otherwise bad match errors happen,
781 * it may be even more restrictive but my tests (on
782 * exceed 6.2) show that only == depth is necessary */
784 if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy))))
786 fvwm_msg(
787 ERR, name, "can't do Transparent "
788 "when root_depth!=fvwm_depth");
789 break;
791 has_pixmap_changed = True;
792 free_colorset_background(cs, True);
793 cs->pixmap = ParentRelative;
794 cs->pixmap_type = PIXMAP_STRETCH;
795 break;
796 case 24: /* RootTransparent */
797 if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy))))
799 fvwm_msg(
800 ERR, name, "can't do RootTransparent "
801 "when root_depth!=fvwm_depth");
802 break;
804 free_colorset_background(cs, True);
805 has_pixmap_changed = True;
806 cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE;
807 do_reload_pixmap = True;
808 tmp_str = PeekToken(args, &args);
809 if (StrEquals(tmp_str, "buffer"))
811 cs->allows_buffered_transparency = True;
813 else
815 cs->allows_buffered_transparency = False;
817 cs->is_maybe_root_transparent = True;
818 break;
819 case 25: /* Tint */
820 case 26: /* PixmapTint */
821 case 27: /* ImageTint */
822 case 28: /* TintMask */
823 parse_simple_tint(
824 cs, args, &tint, TINT_SUPPLIED,
825 &has_tint_changed, &percent, "tint");
826 if (has_tint_changed)
828 cs->tint_percent = percent;
830 break;
831 case 29: /* NoTint */
832 has_tint_changed = True;
833 cs->tint_percent = 0;
834 cs->color_flags &= ~TINT_SUPPLIED;
835 break;
836 case 30: /* fgTint */
837 parse_simple_tint(
838 cs, args, &fg_tint, FG_TINT_SUPPLIED,
839 &has_fg_tint_changed, &percent, "fgTint");
840 if (has_fg_tint_changed)
842 cs->fg_tint_percent = percent;
844 break;
845 case 31: /* bgTint */
846 parse_simple_tint(
847 cs, args, &bg_tint, BG_TINT_SUPPLIED,
848 &has_bg_tint_changed, &percent, "bgTint");
849 if (has_bg_tint_changed)
851 cs->bg_tint_percent = percent;
853 break;
854 case 32: /* dither */
855 if (cs->pixmap_args || cs->gradient_args)
857 has_pixmap_changed = True;
858 do_reload_pixmap = True;
860 cs->dither = True;
861 break;
862 case 33: /* nodither */
863 if (cs->pixmap_args || cs->gradient_args)
865 has_pixmap_changed = True;
866 do_reload_pixmap = True;
868 cs->dither = False;
869 break;
870 case 34: /* Alpha */
871 case 35: /* PixmapAlpha */
872 case 36: /* ImageAlpha */
873 if (GetIntegerArguments(args, NULL, &tmp, 1))
875 if (tmp > 100)
876 tmp = 100;
877 else if (tmp < 0)
878 tmp = 0;
880 else
882 tmp = 100;
884 if (tmp != cs->image_alpha_percent)
886 has_image_alpha_changed = True;
887 cs->image_alpha_percent = tmp;
889 break;
890 /* dither icon is not dynamic (yet) maybe a bad opt: default
891 * to False ? */
892 case 37: /* ditherIcon */
893 cs->do_dither_icon = True;
894 break;
895 case 38: /* DoNotDitherIcon */
896 cs->do_dither_icon = False;
897 break;
898 case 39: /* IconTint */
899 parse_simple_tint(
900 cs, args, &icon_tint, ICON_TINT_SUPPLIED,
901 &has_icon_tint_changed, &percent, "IconTint");
902 if (has_icon_tint_changed)
904 cs->icon_tint_percent = percent;
905 has_icon_pixels_changed = True;
907 break;
908 case 40: /* NoIconTint */
909 has_icon_tint_changed = True;
910 if (cs->icon_tint_percent != 0)
912 has_icon_pixels_changed = True;
914 cs->icon_tint_percent = 0;
915 break;
916 case 41: /* IconAlpha */
917 if (GetIntegerArguments(args, NULL, &tmp, 1))
919 if (tmp > 100)
920 tmp = 100;
921 else if (tmp < 0)
922 tmp = 0;
924 else
926 tmp = 100;
928 if (tmp != cs->icon_alpha_percent)
930 has_icon_pixels_changed = True;
931 cs->icon_alpha_percent = tmp;
933 break;
934 default:
935 /* test for ?Gradient */
936 if (option[0] && StrEquals(&option[1], "Gradient"))
938 cs->gradient_type = toupper(option[0]);
939 if (!IsGradientTypeSupported(cs->gradient_type))
940 break;
941 has_pixmap_changed = True;
942 free_colorset_background(cs, True);
943 CopyString(&cs->gradient_args, args);
944 do_reload_pixmap = True;
945 if (cs->gradient_type == V_GRADIENT)
947 cs->pixmap_type = PIXMAP_STRETCH_Y;
949 else if (cs->gradient_type == H_GRADIENT)
950 cs->pixmap_type = PIXMAP_STRETCH_X;
951 else
952 cs->pixmap_type = PIXMAP_STRETCH;
954 else
956 fvwm_msg(
957 WARN, name, "bad colorset pixmap "
958 "specifier %s %s", option, line);
960 break;
961 } /* switch */
963 if (option)
965 free(option);
966 option = NULL;
968 free(optstring);
969 optstring = NULL;
970 } /* while (line && *line) */
973 * ---------- change the "pixmap" tint colour ----------
975 if (has_tint_changed)
977 /* user specified colour */
978 if (tint != NULL)
980 Pixel old_tint = cs->tint;
981 PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True);
982 cs->tint = GetColor(tint);
983 if (old_tint != cs->tint)
985 have_pixels_changed = True;
988 else if (tint == NULL)
990 /* default */
991 Pixel old_tint = cs->tint;
992 PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True);
993 cs->tint = GetColor(black);
994 if (old_tint != cs->tint)
996 have_pixels_changed = True;
1002 * reload the gradient if the tint or the alpha have changed.
1003 * Do this too if we need to recompute the bg average and the
1004 * gradient is tinted (perforemence issue).
1006 if ((has_tint_changed || has_image_alpha_changed ||
1007 (has_bg_changed && (cs->color_flags & BG_AVERAGE) &&
1008 cs->tint_percent > 0)) && cs->gradient_args)
1010 do_reload_pixmap = True;
1014 * reset the pixmap if the tint or the alpha has changed
1016 if (!do_reload_pixmap &&
1017 (has_tint_changed || has_image_alpha_changed ||
1018 (has_bg_changed && cs->alpha_pixmap != None)))
1020 if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE ||
1021 cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN)
1023 do_reload_pixmap = True;
1025 else if (cs->picture != NULL && cs->pixmap)
1027 XSetClipMask(dpy, gc, cs->picture->mask);
1028 reset_cs_pixmap(cs, gc);
1029 XSetClipMask(dpy, gc, None);
1030 has_pixmap_changed = True;
1035 * (re)build the pixmap or the gradient
1037 if (do_reload_pixmap)
1039 free_colorset_background(cs, False);
1040 has_pixmap_changed = True;
1041 if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE ||
1042 cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN)
1044 cs->pixmap_type = 0;
1045 if (root_pic.pixmap)
1047 cs->pixmap = root_pic.pixmap;
1048 cs->width = root_pic.width;
1049 cs->height = root_pic.height;
1050 cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE;
1051 #if 0
1052 fprintf(stderr,"Cset %i LoadRoot 0x%lx\n",
1053 n, cs->pixmap);
1054 #endif
1057 else if (cs->pixmap_args)
1059 parse_pixmap(win, gc, cs, &pixmap_is_a_bitmap);
1061 else if (cs->gradient_args)
1063 cs->pixmap = CreateGradientPixmapFromString(
1064 dpy, win, gc, cs->gradient_type,
1065 cs->gradient_args, &w, &h, &cs->pixels,
1066 &cs->nalloc_pixels, cs->dither);
1067 cs->width = w;
1068 cs->height = h;
1070 has_pixmap_changed = True;
1073 if (cs->picture != NULL && cs->picture->depth != Pdepth)
1075 pixmap_is_a_bitmap = True;
1079 * ---------- change the background colour ----------
1081 if (has_bg_changed ||
1082 (has_pixmap_changed && (cs->color_flags & BG_AVERAGE) &&
1083 cs->pixmap != None &&
1084 cs->pixmap != ParentRelative &&
1085 !pixmap_is_a_bitmap))
1087 Bool do_set_default_background = False;
1088 Pixmap average_pix = None;
1090 if (cs->color_flags & BG_AVERAGE)
1092 if (cs->picture != NULL && cs->picture->picture != None)
1094 average_pix = cs->picture->picture;
1096 else if (cs->pixmap != ParentRelative)
1098 average_pix = cs->pixmap;
1101 if (average_pix == root_pic.pixmap)
1103 int w;
1104 int h;
1105 XID dummy;
1107 MyXGrabServer(dpy);
1108 is_server_grabbed = True;
1109 if (!XGetGeometry(
1110 dpy, average_pix, &dummy,
1111 (int *)&dummy, (int *)&dummy,
1112 (unsigned int *)&w, (unsigned int *)&h,
1113 (unsigned int *)&dummy,
1114 (unsigned int *)&dummy))
1116 average_pix = None;
1118 else
1120 if (w != cs->width || h != cs->height)
1122 average_pix = None;
1125 if (average_pix == None)
1127 MyXUngrabServer(dpy);
1128 is_server_grabbed = False;
1133 /* note: no average for bitmap */
1134 if ((cs->color_flags & BG_AVERAGE) && average_pix)
1136 /* calculate average background color */
1137 XColor *colors;
1138 XImage *image;
1139 XImage *mask_image = None;
1140 unsigned int i, j, k = 0;
1141 unsigned long red = 0, blue = 0, green = 0;
1142 unsigned long tred, tblue, tgreen;
1143 double dred = 0.0, dblue = 0.0, dgreen = 0.0;
1145 has_bg_changed = True;
1146 /* create an array to store all the pixmap colors in */
1147 /* Note: this may allocate a lot of memory:
1148 * cs->width * cs->height * 12 and then the rest of the
1149 * procedure can take a lot of times */
1150 colors = (XColor *)safemalloc(
1151 cs->width * cs->height * sizeof(XColor));
1152 /* get the pixmap and mask into an image */
1153 image = XGetImage(
1154 dpy, average_pix, 0, 0, cs->width, cs->height,
1155 AllPlanes, ZPixmap);
1156 if (cs->mask != None)
1158 mask_image = XGetImage(
1159 dpy, cs->mask, 0, 0, cs->width,
1160 cs->height, AllPlanes, ZPixmap);
1162 if (is_server_grabbed == True)
1164 MyXUngrabServer(dpy);
1166 if (image != None && mask_image != None)
1168 /* only fetch the pixels that are not masked
1169 * out */
1170 for (i = 0; i < cs->width; i++)
1172 for (j = 0; j < cs->height; j++)
1174 if (
1175 cs->mask == None ||
1176 XGetPixel(
1177 mask_image, i,
1178 j) == 0)
1180 colors[k++].pixel =
1181 XGetPixel(
1182 image,
1183 i, j);
1188 if (image != None)
1190 XDestroyImage(image);
1192 if (mask_image != None)
1194 XDestroyImage(mask_image);
1196 if (k == 0)
1198 do_set_default_background = True;
1200 else
1202 /* look them all up, XQueryColors() can't
1203 * handle more than 256 */
1204 for (i = 0; i < k; i += 256)
1206 XQueryColors(
1207 dpy, Pcmap, &colors[i],
1208 min(k - i, 256));
1210 /* calculate average, add overflows in a double
1211 * .red is short, red is long */
1212 for (i = 0; i < k; i++)
1214 tred = red;
1215 red += colors[i].red;
1216 if (red < tred)
1218 dred += (double)tred;
1219 red = colors[i].red;
1221 tgreen = green;
1222 green += colors[i].green;
1223 if (green < tgreen)
1225 dgreen += (double)tgreen;
1226 green = colors[i].green;
1228 tblue = blue;
1229 blue += colors[i].blue;
1230 if (blue < tblue)
1232 dblue += (double)tblue;
1233 blue = colors[i].blue;
1236 dred += red;
1237 dgreen += green;
1238 dblue += blue;
1239 /* get it */
1240 color.red = dred / k;
1241 color.green = dgreen / k;
1242 color.blue = dblue / k;
1244 Pixel old_bg = cs->bg;
1246 PictureFreeColors(
1247 dpy, Pcmap, &cs->bg, 1, 0,
1248 True);
1249 PictureAllocColor(
1250 dpy, Pcmap, &color, True);
1251 cs->bg = color.pixel;
1252 if (old_bg != cs->bg)
1254 have_pixels_changed = True;
1258 free(colors);
1259 } /* average */
1260 else if ((cs->color_flags & BG_SUPPLIED) && bg != NULL)
1262 /* user specified colour */
1263 Pixel old_bg = cs->bg;
1265 PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
1266 cs->bg = GetColor(bg);
1267 if (old_bg != cs->bg)
1269 have_pixels_changed = True;
1271 } /* user specified */
1272 else if (bg == NULL && has_bg_changed)
1274 /* default */
1275 do_set_default_background = True;
1276 } /* default */
1277 if (do_set_default_background)
1279 Pixel old_bg = cs->bg;
1281 PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
1282 cs->bg = GetColor(white);
1283 if (old_bg != cs->bg)
1285 have_pixels_changed = True;
1287 has_bg_changed = True;
1290 if (has_bg_changed)
1292 /* save the bg color for tinting */
1293 cs->bg_saved = cs->bg;
1295 } /* has_bg_changed */
1299 * ---------- setup the bg tint colour ----------
1301 if (has_bg_tint_changed && cs->bg_tint_percent > 0 && bg_tint != NULL)
1303 PictureFreeColors(dpy, Pcmap, &cs->bg_tint, 1, 0, True);
1304 cs->bg_tint = GetColor(bg_tint);
1308 * ---------- tint the bg colour ----------
1310 if (has_bg_tint_changed || (has_bg_changed && cs->bg_tint_percent > 0))
1312 if (cs->bg_tint_percent == 0)
1314 Pixel old_bg = cs->bg;
1316 PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
1317 cs->bg = cs->bg_saved;
1318 if (old_bg != cs->bg)
1320 have_pixels_changed = True;
1321 has_bg_changed = True;
1324 else
1326 Pixel old_bg = cs->bg;
1328 PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
1329 cs->bg = GetTintedPixel(
1330 cs->bg_saved, cs->bg_tint, cs->bg_tint_percent);
1331 if (old_bg != cs->bg)
1333 have_pixels_changed = True;
1334 has_bg_changed = True;
1340 * ---------- setup the fg tint colour ----------
1342 if (has_fg_tint_changed && cs->fg_tint_percent > 0 && fg_tint != NULL)
1344 PictureFreeColors(dpy, Pcmap, &cs->fg_tint, 1, 0, True);
1345 cs->fg_tint = GetColor(fg_tint);
1349 * ---------- change the foreground colour ----------
1351 if (has_fg_changed ||
1352 (has_bg_changed && (cs->color_flags & FG_CONTRAST)))
1354 if (cs->color_flags & FG_CONTRAST)
1356 Pixel old_fg = cs->fg;
1358 /* calculate contrasting foreground color */
1359 color.pixel = cs->bg;
1360 XQueryColor(dpy, Pcmap, &color);
1361 color.red = (color.red > 32767) ? 0 : 65535;
1362 color.green = (color.green > 32767) ? 0 : 65535;
1363 color.blue = (color.blue > 32767) ? 0 : 65535;
1365 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1366 PictureAllocColor(dpy, Pcmap, &color, True);
1367 cs->fg = color.pixel;
1368 if (old_fg != cs->fg)
1370 have_pixels_changed = True;
1371 has_fg_changed = 1;
1373 } /* contrast */
1374 else if ((cs->color_flags & FG_SUPPLIED) && fg != NULL)
1376 /* user specified colour */
1377 Pixel old_fg = cs->fg;
1379 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1380 cs->fg = GetColor(fg);
1381 if (old_fg != cs->fg)
1383 have_pixels_changed = True;
1384 has_fg_changed = 1;
1386 } /* user specified */
1387 else if (fg == NULL)
1389 /* default */
1390 Pixel old_fg = cs->fg;
1392 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1393 cs->fg = GetColor(black);
1394 if (old_fg != cs->fg)
1396 have_pixels_changed = True;
1397 has_fg_changed = 1;
1401 /* save the fg color for tinting */
1402 cs->fg_saved = cs->fg;
1404 } /* has_fg_changed */
1407 * ---------- tint the foreground colour ----------
1409 if (has_fg_tint_changed || (has_fg_changed && cs->fg_tint_percent > 0))
1411 if (cs->fg_tint_percent == 0)
1414 Pixel old_fg = cs->fg;
1416 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1417 cs->fg = cs->fg_saved;
1418 if (old_fg != cs->fg)
1420 have_pixels_changed = True;
1421 has_fg_changed = 1;
1424 else
1426 Pixel old_fg = cs->fg;
1428 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1429 cs->fg = GetTintedPixel(
1430 cs->fg_saved, cs->fg_tint,
1431 cs->fg_tint_percent);
1432 if (old_fg != cs->fg)
1434 have_pixels_changed = True;
1435 has_fg_changed = 1;
1442 * ---------- change the hilight colour ----------
1444 if (has_hi_changed ||
1445 (has_bg_changed && !(cs->color_flags & HI_SUPPLIED)))
1447 has_hi_changed = 1;
1448 if ((cs->color_flags & HI_SUPPLIED) && hi != NULL)
1450 /* user specified colour */
1451 Pixel old_hilite = cs->hilite;
1453 PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True);
1454 cs->hilite = GetColor(hi);
1455 if (old_hilite != cs->hilite)
1457 have_pixels_changed = True;
1459 } /* user specified */
1460 else if (hi == NULL)
1462 Pixel old_hilite = cs->hilite;
1464 PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True);
1465 cs->hilite = GetHilite(cs->bg);
1466 if (old_hilite != cs->hilite)
1468 have_pixels_changed = True;
1471 } /* has_hi_changed */
1474 * ---------- change the shadow colour ----------
1476 if (has_sh_changed ||
1477 (has_bg_changed && !(cs->color_flags & SH_SUPPLIED)))
1479 has_sh_changed = 1;
1480 if ((cs->color_flags & SH_SUPPLIED) && sh != NULL)
1482 /* user specified colour */
1483 Pixel old_shadow = cs->shadow;
1485 PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True);
1486 cs->shadow = GetColor(sh);
1487 if (old_shadow != cs->shadow)
1489 have_pixels_changed = True;
1491 } /* user specified */
1492 else if (sh == NULL)
1494 Pixel old_shadow = cs->shadow;
1496 PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True);
1497 cs->shadow = GetShadow(cs->bg);
1498 if (old_shadow != cs->shadow)
1500 have_pixels_changed = True;
1503 } /* has_sh_changed */
1506 * ---------- change the shadow foreground colour ----------
1508 if (has_fgsh_changed ||
1509 ((has_fg_changed || has_bg_changed) &&
1510 !(cs->color_flags & FGSH_SUPPLIED)))
1512 has_fgsh_changed = 1;
1513 if ((cs->color_flags & FGSH_SUPPLIED) && fgsh != NULL)
1515 /* user specified colour */
1516 Pixel old_fgsh = cs->fgsh;
1518 PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True);
1519 cs->fgsh = GetColor(fgsh);
1520 if (old_fgsh != cs->fgsh)
1522 have_pixels_changed = True;
1524 } /* user specified */
1525 else if (fgsh == NULL)
1527 Pixel old_fgsh = cs->fgsh;
1529 PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True);
1530 cs->fgsh = GetForeShadow(cs->fg, cs->bg);
1531 if (old_fgsh != cs->fgsh)
1533 have_pixels_changed = True;
1536 } /* has_fgsh_changed */
1539 * ------- the pixmap is a bitmap: create here cs->pixmap -------
1541 if (cs->picture != None && pixmap_is_a_bitmap &&
1542 (has_pixmap_changed || has_bg_changed))
1544 cs->pixmap = XCreatePixmap(
1545 dpy, win, cs->width, cs->height, Pdepth);
1546 XSetBackground(dpy, gc, cs->bg);
1547 XSetForeground(dpy, gc, cs->fg);
1548 reset_cs_pixmap(cs, gc);
1552 * ------- change the masked out parts of the background pixmap -------
1554 if (cs->pixmap != None && cs->pixmap != ParentRelative &&
1555 (!CSETS_IS_TRANSPARENT_ROOT(cs)||
1556 cs->allows_buffered_transparency) &&
1557 (cs->mask != None || cs->alpha_pixmap != None ||
1558 cs->image_alpha_percent < 100 || cs->tint_percent > 0) &&
1559 (has_pixmap_changed || has_bg_changed || has_image_alpha_changed
1560 || has_tint_changed))
1562 /* Now that we know the background colour we can update the
1563 * pixmap background. */
1564 FvwmRenderAttributes fra;
1565 Pixmap temp, mask, alpha;
1567 memset(&fra, 0, sizeof(fra));
1568 temp = XCreatePixmap(dpy, win, cs->width, cs->height, Pdepth);
1569 if (cs->picture != NULL)
1571 mask = cs->picture->mask;
1572 alpha = cs->picture->alpha;
1574 else
1576 mask = None;
1577 alpha = None;
1579 XSetForeground(dpy, gc, cs->bg);
1580 XFillRectangle(
1581 dpy, temp, gc, 0, 0, cs->width, cs->height);
1583 fra.mask = FRAM_HAVE_ADDED_ALPHA | FRAM_HAVE_TINT;
1584 fra.added_alpha_percent = cs->image_alpha_percent;
1585 fra.tint = cs->tint;
1586 fra.tint_percent = cs->tint_percent;
1587 PGraphicsRenderPixmaps(
1588 dpy, win, cs->pixmap, mask, alpha, Pdepth, &fra,
1589 temp, gc, Scr.MonoGC, Scr.AlphaGC,
1590 0, 0, cs->width, cs->height,
1591 0, 0, cs->width, cs->height, False);
1592 if (cs->pixmap != root_pic.pixmap)
1594 add_to_junk(cs->pixmap);
1596 cs->pixmap = temp;
1597 has_pixmap_changed = True;
1598 if (CSETS_IS_TRANSPARENT_ROOT(cs))
1600 cs->pixmap_type = PIXMAP_ROOT_PIXMAP_TRAN;
1602 } /* has_pixmap_changed */
1606 * ---------- change the icon tint colour ----------
1608 if (has_icon_tint_changed)
1610 /* user specified colour */
1611 if (icon_tint != NULL)
1613 Pixel old_tint = cs->icon_tint;
1614 PictureFreeColors(
1615 dpy, Pcmap, &cs->icon_tint, 1, 0, True);
1616 cs->icon_tint = GetColor(icon_tint);
1617 if (old_tint != cs->icon_tint)
1619 has_icon_pixels_changed = True;
1622 else
1624 /* default */
1625 Pixel old_tint = cs->icon_tint;
1626 PictureFreeColors(
1627 dpy, Pcmap, &cs->icon_tint, 1, 0, True);
1628 cs->icon_tint = GetColor(black);
1629 if (old_tint != cs->icon_tint)
1631 has_icon_pixels_changed = True;
1637 * ---------- send new colorset to fvwm and clean up ----------
1639 /* make sure the server has this to avoid races */
1640 XSync(dpy, False);
1642 /* inform modules of the change */
1643 if (have_pixels_changed || has_pixmap_changed || has_shape_changed ||
1644 has_fg_alpha_changed || has_icon_pixels_changed)
1646 BroadcastColorset(n);
1649 if (fg)
1651 free(fg);
1653 if (bg)
1655 free(bg);
1657 if (hi)
1659 free(hi);
1661 if (sh)
1663 free(sh);
1665 if (fgsh)
1667 free(fgsh);
1669 if (tint)
1671 free(tint);
1673 if (fg_tint)
1675 free(fg_tint);
1677 if (bg_tint)
1679 free(bg_tint);
1681 if (icon_tint)
1683 free(icon_tint);
1685 return;
1689 * alloc_colorset() grows the size of the Colorset array to include set n
1690 * colorset_t *Colorset will be altered
1691 * returns the address of the member
1693 void alloc_colorset(int n)
1695 /* do nothing if it already exists */
1696 if (n < nColorsets)
1698 return;
1700 else
1702 Colorset = (colorset_t *)saferealloc(
1703 (char *)Colorset, (n + 1) * sizeof(colorset_t));
1704 memset(
1705 &Colorset[nColorsets], 0,
1706 (n + 1 - nColorsets) * sizeof(colorset_t));
1708 if (n == 0)
1710 update_root_pixmap(0);
1713 /* initialize new colorsets to black on gray */
1714 while (nColorsets <= n)
1716 colorset_t *ncs = &Colorset[nColorsets];
1718 if (PictureUseBWOnly())
1720 char g_bits[] = {0x0a, 0x05, 0x0a, 0x05,
1721 0x08, 0x02, 0x08, 0x02,
1722 0x01, 0x02, 0x04, 0x08};
1723 /* monochrome monitors get black on white */
1724 /* with a gray pixmap background */
1725 ncs->fg = GetColor(black);
1726 ncs->bg = GetColor(white);
1727 ncs->hilite = GetColor(white);
1728 ncs->shadow = GetColor(black);
1729 ncs->fgsh = GetColor(white);
1730 ncs->tint = GetColor(black);
1731 ncs->icon_tint = GetColor(black);
1732 ncs->pixmap = XCreatePixmapFromBitmapData(
1733 dpy, Scr.NoFocusWin,
1734 &g_bits[4 * (nColorsets % 3)], 4, 4,
1735 PictureBlackPixel(), PictureWhitePixel(),
1736 Pdepth);
1737 ncs->width = 4;
1738 ncs->height = 4;
1740 else
1742 ncs->fg = GetColor(black);
1743 ncs->bg = GetColor(gray);
1744 ncs->hilite = GetHilite(ncs->bg);
1745 ncs->shadow = GetShadow(ncs->bg);
1746 ncs->fgsh = GetForeShadow(ncs->fg, ncs->bg);
1747 ncs->tint = GetColor(black);
1748 ncs->icon_tint = GetColor(black);
1750 ncs->fg_tint = ncs->bg_tint = GetColor(black);
1751 /* set flags for fg contrast, bg average */
1752 /* in case just a pixmap is given */
1753 ncs->color_flags = FG_CONTRAST | BG_AVERAGE;
1754 ncs->fg_saved = ncs->fg;
1755 ncs->fg_alpha_percent = 100;
1756 ncs->image_alpha_percent = 100;
1757 ncs->icon_alpha_percent = 100;
1758 ncs->tint_percent = 0;
1759 ncs->icon_tint_percent = 0;
1760 ncs->fg_tint_percent = ncs->bg_tint_percent = 0;
1761 ncs->dither = (PictureDitherByDefault())? True:False;
1762 nColorsets++;
1766 void update_root_transparent_colorset(Atom prop)
1768 int i;
1769 colorset_t *cs;
1771 root_pic.old_pixmap = root_pic.pixmap;
1772 update_root_pixmap(prop);
1773 #if 0
1774 if (!root_pic.pixmap)
1776 return;
1778 #endif
1779 for (i=0; i < nColorsets; i++)
1781 Bool root_trans = False;
1782 cs = &Colorset[i];
1783 if (cs->is_maybe_root_transparent &&
1784 cs->allows_buffered_transparency)
1786 parse_colorset(i, "RootTransparent buffer");
1787 root_trans = True;
1789 else if (cs->is_maybe_root_transparent)
1791 parse_colorset(i, "RootTransparent");
1792 root_trans = True;
1794 if (root_trans)
1796 update_fvwm_colorset(i);
1801 /* ---------------------------- builtin commands ---------------------------- */
1803 void CMD_ReadWriteColors(F_CMD_ARGS)
1805 fvwm_msg(WARN, "CMD_ReadWriteColors", "ReadWriteColors is obsolete");
1807 return;
1810 void CMD_Colorset(F_CMD_ARGS)
1812 int n;
1813 char *token;
1815 if (GetIntegerArguments(action, &token, &n, 1) != 1)
1817 return;
1819 if (n < 0)
1821 return;
1823 if (token == NULL)
1825 return;
1827 parse_colorset(n, token);
1828 update_fvwm_colorset(n);
1830 return;
1833 void CMD_CleanupColorsets(F_CMD_ARGS)
1835 cleanup_colorsets();