Fix segfault setting MenuFace pixmap style for menus.
[fvwm.git] / fvwm / colorset.c
blobf6b18d128000c36f2b43dfc3edbc618e7ed0cf10
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 else
1190 fvwm_msg(
1191 ERR, "parse_colorset",
1192 "error reading root background");
1194 if (image != None)
1196 XDestroyImage(image);
1198 if (mask_image != None)
1200 XDestroyImage(mask_image);
1202 if (k == 0)
1204 do_set_default_background = True;
1206 else
1208 /* look them all up, XQueryColors() can't
1209 * handle more than 256 */
1210 for (i = 0; i < k; i += 256)
1212 XQueryColors(
1213 dpy, Pcmap, &colors[i],
1214 min(k - i, 256));
1216 /* calculate average, add overflows in a double
1217 * .red is short, red is long */
1218 for (i = 0; i < k; i++)
1220 tred = red;
1221 red += colors[i].red;
1222 if (red < tred)
1224 dred += (double)tred;
1225 red = colors[i].red;
1227 tgreen = green;
1228 green += colors[i].green;
1229 if (green < tgreen)
1231 dgreen += (double)tgreen;
1232 green = colors[i].green;
1234 tblue = blue;
1235 blue += colors[i].blue;
1236 if (blue < tblue)
1238 dblue += (double)tblue;
1239 blue = colors[i].blue;
1242 dred += red;
1243 dgreen += green;
1244 dblue += blue;
1245 /* get it */
1246 color.red = dred / k;
1247 color.green = dgreen / k;
1248 color.blue = dblue / k;
1250 Pixel old_bg = cs->bg;
1252 PictureFreeColors(
1253 dpy, Pcmap, &cs->bg, 1, 0,
1254 True);
1255 PictureAllocColor(
1256 dpy, Pcmap, &color, True);
1257 cs->bg = color.pixel;
1258 if (old_bg != cs->bg)
1260 have_pixels_changed = True;
1264 free(colors);
1265 } /* average */
1266 else if ((cs->color_flags & BG_SUPPLIED) && bg != NULL)
1268 /* user specified colour */
1269 Pixel old_bg = cs->bg;
1271 PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
1272 cs->bg = GetColor(bg);
1273 if (old_bg != cs->bg)
1275 have_pixels_changed = True;
1277 } /* user specified */
1278 else if (bg == NULL && has_bg_changed)
1280 /* default */
1281 do_set_default_background = True;
1282 } /* default */
1283 if (do_set_default_background)
1285 Pixel old_bg = cs->bg;
1287 PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
1288 cs->bg = GetColor(white);
1289 if (old_bg != cs->bg)
1291 have_pixels_changed = True;
1293 has_bg_changed = True;
1296 if (has_bg_changed)
1298 /* save the bg color for tinting */
1299 cs->bg_saved = cs->bg;
1301 } /* has_bg_changed */
1305 * ---------- setup the bg tint colour ----------
1307 if (has_bg_tint_changed && cs->bg_tint_percent > 0 && bg_tint != NULL)
1309 PictureFreeColors(dpy, Pcmap, &cs->bg_tint, 1, 0, True);
1310 cs->bg_tint = GetColor(bg_tint);
1314 * ---------- tint the bg colour ----------
1316 if (has_bg_tint_changed || (has_bg_changed && cs->bg_tint_percent > 0))
1318 if (cs->bg_tint_percent == 0)
1320 Pixel old_bg = cs->bg;
1322 PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
1323 cs->bg = cs->bg_saved;
1324 if (old_bg != cs->bg)
1326 have_pixels_changed = True;
1327 has_bg_changed = True;
1330 else
1332 Pixel old_bg = cs->bg;
1334 PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
1335 cs->bg = GetTintedPixel(
1336 cs->bg_saved, cs->bg_tint, cs->bg_tint_percent);
1337 if (old_bg != cs->bg)
1339 have_pixels_changed = True;
1340 has_bg_changed = True;
1346 * ---------- setup the fg tint colour ----------
1348 if (has_fg_tint_changed && cs->fg_tint_percent > 0 && fg_tint != NULL)
1350 PictureFreeColors(dpy, Pcmap, &cs->fg_tint, 1, 0, True);
1351 cs->fg_tint = GetColor(fg_tint);
1355 * ---------- change the foreground colour ----------
1357 if (has_fg_changed ||
1358 (has_bg_changed && (cs->color_flags & FG_CONTRAST)))
1360 if (cs->color_flags & FG_CONTRAST)
1362 Pixel old_fg = cs->fg;
1364 /* calculate contrasting foreground color */
1365 color.pixel = cs->bg;
1366 XQueryColor(dpy, Pcmap, &color);
1367 color.red = (color.red > 32767) ? 0 : 65535;
1368 color.green = (color.green > 32767) ? 0 : 65535;
1369 color.blue = (color.blue > 32767) ? 0 : 65535;
1371 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1372 PictureAllocColor(dpy, Pcmap, &color, True);
1373 cs->fg = color.pixel;
1374 if (old_fg != cs->fg)
1376 have_pixels_changed = True;
1377 has_fg_changed = 1;
1379 } /* contrast */
1380 else if ((cs->color_flags & FG_SUPPLIED) && fg != NULL)
1382 /* user specified colour */
1383 Pixel old_fg = cs->fg;
1385 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1386 cs->fg = GetColor(fg);
1387 if (old_fg != cs->fg)
1389 have_pixels_changed = True;
1390 has_fg_changed = 1;
1392 } /* user specified */
1393 else if (fg == NULL)
1395 /* default */
1396 Pixel old_fg = cs->fg;
1398 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1399 cs->fg = GetColor(black);
1400 if (old_fg != cs->fg)
1402 have_pixels_changed = True;
1403 has_fg_changed = 1;
1407 /* save the fg color for tinting */
1408 cs->fg_saved = cs->fg;
1410 } /* has_fg_changed */
1413 * ---------- tint the foreground colour ----------
1415 if (has_fg_tint_changed || (has_fg_changed && cs->fg_tint_percent > 0))
1417 if (cs->fg_tint_percent == 0)
1420 Pixel old_fg = cs->fg;
1422 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1423 cs->fg = cs->fg_saved;
1424 if (old_fg != cs->fg)
1426 have_pixels_changed = True;
1427 has_fg_changed = 1;
1430 else
1432 Pixel old_fg = cs->fg;
1434 PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
1435 cs->fg = GetTintedPixel(
1436 cs->fg_saved, cs->fg_tint,
1437 cs->fg_tint_percent);
1438 if (old_fg != cs->fg)
1440 have_pixels_changed = True;
1441 has_fg_changed = 1;
1448 * ---------- change the hilight colour ----------
1450 if (has_hi_changed ||
1451 (has_bg_changed && !(cs->color_flags & HI_SUPPLIED)))
1453 has_hi_changed = 1;
1454 if ((cs->color_flags & HI_SUPPLIED) && hi != NULL)
1456 /* user specified colour */
1457 Pixel old_hilite = cs->hilite;
1459 PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True);
1460 cs->hilite = GetColor(hi);
1461 if (old_hilite != cs->hilite)
1463 have_pixels_changed = True;
1465 } /* user specified */
1466 else if (hi == NULL)
1468 Pixel old_hilite = cs->hilite;
1470 PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True);
1471 cs->hilite = GetHilite(cs->bg);
1472 if (old_hilite != cs->hilite)
1474 have_pixels_changed = True;
1477 } /* has_hi_changed */
1480 * ---------- change the shadow colour ----------
1482 if (has_sh_changed ||
1483 (has_bg_changed && !(cs->color_flags & SH_SUPPLIED)))
1485 has_sh_changed = 1;
1486 if ((cs->color_flags & SH_SUPPLIED) && sh != NULL)
1488 /* user specified colour */
1489 Pixel old_shadow = cs->shadow;
1491 PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True);
1492 cs->shadow = GetColor(sh);
1493 if (old_shadow != cs->shadow)
1495 have_pixels_changed = True;
1497 } /* user specified */
1498 else if (sh == NULL)
1500 Pixel old_shadow = cs->shadow;
1502 PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True);
1503 cs->shadow = GetShadow(cs->bg);
1504 if (old_shadow != cs->shadow)
1506 have_pixels_changed = True;
1509 } /* has_sh_changed */
1512 * ---------- change the shadow foreground colour ----------
1514 if (has_fgsh_changed ||
1515 ((has_fg_changed || has_bg_changed) &&
1516 !(cs->color_flags & FGSH_SUPPLIED)))
1518 has_fgsh_changed = 1;
1519 if ((cs->color_flags & FGSH_SUPPLIED) && fgsh != NULL)
1521 /* user specified colour */
1522 Pixel old_fgsh = cs->fgsh;
1524 PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True);
1525 cs->fgsh = GetColor(fgsh);
1526 if (old_fgsh != cs->fgsh)
1528 have_pixels_changed = True;
1530 } /* user specified */
1531 else if (fgsh == NULL)
1533 Pixel old_fgsh = cs->fgsh;
1535 PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True);
1536 cs->fgsh = GetForeShadow(cs->fg, cs->bg);
1537 if (old_fgsh != cs->fgsh)
1539 have_pixels_changed = True;
1542 } /* has_fgsh_changed */
1545 * ------- the pixmap is a bitmap: create here cs->pixmap -------
1547 if (cs->picture != None && pixmap_is_a_bitmap &&
1548 (has_pixmap_changed || has_bg_changed))
1550 cs->pixmap = XCreatePixmap(
1551 dpy, win, cs->width, cs->height, Pdepth);
1552 XSetBackground(dpy, gc, cs->bg);
1553 XSetForeground(dpy, gc, cs->fg);
1554 reset_cs_pixmap(cs, gc);
1558 * ------- change the masked out parts of the background pixmap -------
1560 if (cs->pixmap != None && cs->pixmap != ParentRelative &&
1561 (!CSETS_IS_TRANSPARENT_ROOT(cs)||
1562 cs->allows_buffered_transparency) &&
1563 (cs->mask != None || cs->alpha_pixmap != None ||
1564 cs->image_alpha_percent < 100 || cs->tint_percent > 0) &&
1565 (has_pixmap_changed || has_bg_changed || has_image_alpha_changed
1566 || has_tint_changed))
1568 /* Now that we know the background colour we can update the
1569 * pixmap background. */
1570 FvwmRenderAttributes fra;
1571 Pixmap temp, mask, alpha;
1573 memset(&fra, 0, sizeof(fra));
1574 temp = XCreatePixmap(dpy, win, cs->width, cs->height, Pdepth);
1575 if (cs->picture != NULL)
1577 mask = cs->picture->mask;
1578 alpha = cs->picture->alpha;
1580 else
1582 mask = None;
1583 alpha = None;
1585 XSetForeground(dpy, gc, cs->bg);
1586 XFillRectangle(
1587 dpy, temp, gc, 0, 0, cs->width, cs->height);
1589 fra.mask = FRAM_HAVE_ADDED_ALPHA | FRAM_HAVE_TINT;
1590 fra.added_alpha_percent = cs->image_alpha_percent;
1591 fra.tint = cs->tint;
1592 fra.tint_percent = cs->tint_percent;
1593 PGraphicsRenderPixmaps(
1594 dpy, win, cs->pixmap, mask, alpha, Pdepth, &fra,
1595 temp, gc, Scr.MonoGC, Scr.AlphaGC,
1596 0, 0, cs->width, cs->height,
1597 0, 0, cs->width, cs->height, False);
1598 if (cs->pixmap != root_pic.pixmap)
1600 add_to_junk(cs->pixmap);
1602 cs->pixmap = temp;
1603 has_pixmap_changed = True;
1604 if (CSETS_IS_TRANSPARENT_ROOT(cs))
1606 cs->pixmap_type = PIXMAP_ROOT_PIXMAP_TRAN;
1608 } /* has_pixmap_changed */
1612 * ---------- change the icon tint colour ----------
1614 if (has_icon_tint_changed)
1616 /* user specified colour */
1617 if (icon_tint != NULL)
1619 Pixel old_tint = cs->icon_tint;
1620 PictureFreeColors(
1621 dpy, Pcmap, &cs->icon_tint, 1, 0, True);
1622 cs->icon_tint = GetColor(icon_tint);
1623 if (old_tint != cs->icon_tint)
1625 has_icon_pixels_changed = True;
1628 else
1630 /* default */
1631 Pixel old_tint = cs->icon_tint;
1632 PictureFreeColors(
1633 dpy, Pcmap, &cs->icon_tint, 1, 0, True);
1634 cs->icon_tint = GetColor(black);
1635 if (old_tint != cs->icon_tint)
1637 has_icon_pixels_changed = True;
1643 * ---------- send new colorset to fvwm and clean up ----------
1645 /* make sure the server has this to avoid races */
1646 XSync(dpy, False);
1648 /* inform modules of the change */
1649 if (have_pixels_changed || has_pixmap_changed || has_shape_changed ||
1650 has_fg_alpha_changed || has_icon_pixels_changed)
1652 BroadcastColorset(n);
1655 if (fg)
1657 free(fg);
1659 if (bg)
1661 free(bg);
1663 if (hi)
1665 free(hi);
1667 if (sh)
1669 free(sh);
1671 if (fgsh)
1673 free(fgsh);
1675 if (tint)
1677 free(tint);
1679 if (fg_tint)
1681 free(fg_tint);
1683 if (bg_tint)
1685 free(bg_tint);
1687 if (icon_tint)
1689 free(icon_tint);
1691 return;
1695 * alloc_colorset() grows the size of the Colorset array to include set n
1696 * colorset_t *Colorset will be altered
1697 * returns the address of the member
1699 void alloc_colorset(int n)
1701 /* do nothing if it already exists */
1702 if (n < nColorsets)
1704 return;
1706 else
1708 Colorset = (colorset_t *)saferealloc(
1709 (char *)Colorset, (n + 1) * sizeof(colorset_t));
1710 memset(
1711 &Colorset[nColorsets], 0,
1712 (n + 1 - nColorsets) * sizeof(colorset_t));
1714 if (n == 0)
1716 update_root_pixmap(0);
1719 /* initialize new colorsets to black on gray */
1720 while (nColorsets <= n)
1722 colorset_t *ncs = &Colorset[nColorsets];
1724 if (PictureUseBWOnly())
1726 char g_bits[] = {0x0a, 0x05, 0x0a, 0x05,
1727 0x08, 0x02, 0x08, 0x02,
1728 0x01, 0x02, 0x04, 0x08};
1729 /* monochrome monitors get black on white */
1730 /* with a gray pixmap background */
1731 ncs->fg = GetColor(black);
1732 ncs->bg = GetColor(white);
1733 ncs->hilite = GetColor(white);
1734 ncs->shadow = GetColor(black);
1735 ncs->fgsh = GetColor(white);
1736 ncs->tint = GetColor(black);
1737 ncs->icon_tint = GetColor(black);
1738 ncs->pixmap = XCreatePixmapFromBitmapData(
1739 dpy, Scr.NoFocusWin,
1740 &g_bits[4 * (nColorsets % 3)], 4, 4,
1741 PictureBlackPixel(), PictureWhitePixel(),
1742 Pdepth);
1743 ncs->width = 4;
1744 ncs->height = 4;
1746 else
1748 ncs->fg = GetColor(black);
1749 ncs->bg = GetColor(gray);
1750 ncs->hilite = GetHilite(ncs->bg);
1751 ncs->shadow = GetShadow(ncs->bg);
1752 ncs->fgsh = GetForeShadow(ncs->fg, ncs->bg);
1753 ncs->tint = GetColor(black);
1754 ncs->icon_tint = GetColor(black);
1756 ncs->fg_tint = ncs->bg_tint = GetColor(black);
1757 /* set flags for fg contrast, bg average */
1758 /* in case just a pixmap is given */
1759 ncs->color_flags = FG_CONTRAST | BG_AVERAGE;
1760 ncs->fg_saved = ncs->fg;
1761 ncs->fg_alpha_percent = 100;
1762 ncs->image_alpha_percent = 100;
1763 ncs->icon_alpha_percent = 100;
1764 ncs->tint_percent = 0;
1765 ncs->icon_tint_percent = 0;
1766 ncs->fg_tint_percent = ncs->bg_tint_percent = 0;
1767 ncs->dither = (PictureDitherByDefault())? True:False;
1768 nColorsets++;
1772 void update_root_transparent_colorset(Atom prop)
1774 int i;
1775 colorset_t *cs;
1777 root_pic.old_pixmap = root_pic.pixmap;
1778 update_root_pixmap(prop);
1779 #if 0
1780 if (!root_pic.pixmap)
1782 return;
1784 #endif
1785 for (i=0; i < nColorsets; i++)
1787 Bool root_trans = False;
1788 cs = &Colorset[i];
1789 if (cs->is_maybe_root_transparent &&
1790 cs->allows_buffered_transparency)
1792 parse_colorset(i, "RootTransparent buffer");
1793 root_trans = True;
1795 else if (cs->is_maybe_root_transparent)
1797 parse_colorset(i, "RootTransparent");
1798 root_trans = True;
1800 if (root_trans)
1802 update_fvwm_colorset(i);
1807 /* ---------------------------- builtin commands ---------------------------- */
1809 void CMD_ReadWriteColors(F_CMD_ARGS)
1811 fvwm_msg(WARN, "CMD_ReadWriteColors", "ReadWriteColors is obsolete");
1813 return;
1816 void CMD_Colorset(F_CMD_ARGS)
1818 int n;
1819 char *token;
1821 if (GetIntegerArguments(action, &token, &n, 1) != 1)
1823 return;
1825 if (n < 0)
1827 return;
1829 if (token == NULL)
1831 return;
1833 parse_colorset(n, token);
1834 update_fvwm_colorset(n);
1836 return;
1839 void CMD_CleanupColorsets(F_CMD_ARGS)
1841 cleanup_colorsets();