/* translate a colorset spec into a colorset structure */ void parse_colorset(int n, char *line) { int i; int w; int h; int tmp; int percent; colorset_t *cs; char *optstring; char *args; char *option; char *tmp_str; char *fg = NULL; char *bg = NULL; char *hi = NULL; char *sh = NULL; char *fgsh = NULL; char *tint = NULL; char *fg_tint = NULL; char *bg_tint = NULL; char *icon_tint = NULL; Bool have_pixels_changed = False; Bool has_icon_pixels_changed = False; Bool has_fg_changed = False; Bool has_bg_changed = False; Bool has_sh_changed = False; Bool has_hi_changed = False; Bool has_fgsh_changed = False; Bool has_fg_alpha_changed = False; Bool has_tint_changed = False; Bool has_fg_tint_changed = False; Bool has_bg_tint_changed = False; Bool has_icon_tint_changed = False; Bool has_pixmap_changed = False; Bool has_shape_changed = False; Bool has_image_alpha_changed = False; Bool pixmap_is_a_bitmap = False; Bool do_reload_pixmap = False; Bool is_server_grabbed = False; XColor color; XGCValues xgcv; static char *name = "parse_colorset"; Window win = Scr.NoFocusWin; static GC gc = None; /* initialize statics */ if (gc == None) { gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv); } /* make sure it exists and has sensible contents */ alloc_colorset(n); cs = &Colorset[n]; /*** Parse the options ***/ while (line && *line) { /* Read next option specification delimited by a comma or \0. */ line = GetQuotedString( line, &optstring, ",", NULL, NULL, NULL); if (!optstring) break; args = GetNextToken(optstring, &option); if (!option) { free(optstring); break; } switch((i = GetTokenIndex(option, csetopts, 0, NULL))) { case 0: /* Foreground */ case 1: /* Fore */ case 2: /* fg */ get_simple_color( args, &fg, cs, FG_SUPPLIED, FG_CONTRAST, "contrast"); has_fg_changed = True; break; case 3: /* Background */ case 4: /* Back */ case 5: /* bg */ get_simple_color( args, &bg, cs, BG_SUPPLIED, BG_AVERAGE, "average"); has_bg_changed = True; break; case 6: /* Hilight */ case 7: /* Hilite */ case 8: /* hi */ get_simple_color(args, &hi, cs, HI_SUPPLIED, 0, NULL); has_hi_changed = True; break; case 9: /* Shadow */ case 10: /* Shade */ case 11: /* sh */ get_simple_color(args, &sh, cs, SH_SUPPLIED, 0, NULL); has_sh_changed = True; break; case 12: /* fgsh */ get_simple_color( args, &fgsh, cs, FGSH_SUPPLIED, 0,NULL); has_fgsh_changed = True; break; case 13: /* fg_alpha */ case 14: /* fgAlpha */ if (GetIntegerArguments(args, NULL, &tmp, 1)) { if (tmp > 100) tmp = 100; else if (tmp < 0) tmp = 0; } else { tmp = 100; } if (tmp != cs->fg_alpha_percent) { cs->fg_alpha_percent = tmp; has_fg_alpha_changed = True; } break; case 15: /* TiledPixmap */ case 16: /* Pixmap */ case 17: /* AspectPixmap */ has_pixmap_changed = True; free_colorset_background(cs, True); tmp_str = PeekToken(args, &args); if (tmp_str) { CopyString(&cs->pixmap_args, tmp_str); do_reload_pixmap = True; cs->gradient_type = 0; /* set the flags */ if (csetopts[i][0] == 'T') { cs->pixmap_type = PIXMAP_TILED; } else if (csetopts[i][0] == 'A') { cs->pixmap_type = PIXMAP_STRETCH_ASPECT; } else { cs->pixmap_type = PIXMAP_STRETCH; } } /* the pixmap is build later */ break; case 18: /* Shape */ case 19: /* TiledShape */ case 20: /* AspectShape */ parse_shape(win, cs, i, args, &has_shape_changed); break; case 21: /* Plain */ has_pixmap_changed = True; free_colorset_background(cs, True); break; case 22: /* NoShape */ has_shape_changed = True; if (cs->shape_mask) { add_to_junk(cs->shape_mask); cs->shape_mask = None; } break; case 23: /* Transparent */ /* This is only allowable when the root depth == fvwm * visual depth otherwise bad match errors happen, * it may be even more restrictive but my tests (on * exceed 6.2) show that only == depth is necessary */ if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy)))) { fvwm_msg( ERR, name, "can't do Transparent " "when root_depth!=fvwm_depth"); break; } has_pixmap_changed = True; free_colorset_background(cs, True); cs->pixmap = ParentRelative; cs->pixmap_type = PIXMAP_STRETCH; break; case 24: /* RootTransparent */ if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy)))) { fvwm_msg( ERR, name, "can't do RootTransparent " "when root_depth!=fvwm_depth"); break; } free_colorset_background(cs, True); has_pixmap_changed = True; cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE; do_reload_pixmap = True; tmp_str = PeekToken(args, &args); if (StrEquals(tmp_str, "buffer")) { cs->allows_buffered_transparency = True; } else { cs->allows_buffered_transparency = False; } cs->is_maybe_root_transparent = True; break; case 25: /* Tint */ case 26: /* PixmapTint */ case 27: /* ImageTint */ case 28: /* TintMask */ parse_simple_tint( cs, args, &tint, TINT_SUPPLIED, &has_tint_changed, &percent, "tint"); if (has_tint_changed) { cs->tint_percent = percent; } break; case 29: /* NoTint */ has_tint_changed = True; cs->tint_percent = 0; cs->color_flags &= ~TINT_SUPPLIED; break; case 30: /* fgTint */ parse_simple_tint( cs, args, &fg_tint, FG_TINT_SUPPLIED, &has_fg_tint_changed, &percent, "fgTint"); if (has_fg_tint_changed) { cs->fg_tint_percent = percent; } break; case 31: /* bgTint */ parse_simple_tint( cs, args, &bg_tint, BG_TINT_SUPPLIED, &has_bg_tint_changed, &percent, "bgTint"); if (has_bg_tint_changed) { cs->bg_tint_percent = percent; } break; case 32: /* dither */ if (cs->pixmap_args || cs->gradient_args) { has_pixmap_changed = True; do_reload_pixmap = True; } cs->dither = True; break; case 33: /* nodither */ if (cs->pixmap_args || cs->gradient_args) { has_pixmap_changed = True; do_reload_pixmap = True; } cs->dither = False; break; case 34: /* Alpha */ case 35: /* PixmapAlpha */ case 36: /* ImageAlpha */ if (GetIntegerArguments(args, NULL, &tmp, 1)) { if (tmp > 100) tmp = 100; else if (tmp < 0) tmp = 0; } else { tmp = 100; } if (tmp != cs->image_alpha_percent) { has_image_alpha_changed = True; cs->image_alpha_percent = tmp; } break; /* dither icon is not dynamic (yet) maybe a bad opt: default * to False ? */ case 37: /* ditherIcon */ cs->do_dither_icon = True; break; case 38: /* DoNotDitherIcon */ cs->do_dither_icon = False; break; case 39: /* IconTint */ parse_simple_tint( cs, args, &icon_tint, ICON_TINT_SUPPLIED, &has_icon_tint_changed, &percent, "IconTint"); if (has_icon_tint_changed) { cs->icon_tint_percent = percent; has_icon_pixels_changed = True; } break; case 40: /* NoIconTint */ has_icon_tint_changed = True; if (cs->icon_tint_percent != 0) { has_icon_pixels_changed = True; } cs->icon_tint_percent = 0; break; case 41: /* IconAlpha */ if (GetIntegerArguments(args, NULL, &tmp, 1)) { if (tmp > 100) tmp = 100; else if (tmp < 0) tmp = 0; } else { tmp = 100; } if (tmp != cs->icon_alpha_percent) { has_icon_pixels_changed = True; cs->icon_alpha_percent = tmp; } break; default: /* test for ?Gradient */ if (option[0] && StrEquals(&option[1], "Gradient")) { cs->gradient_type = toupper(option[0]); if (!IsGradientTypeSupported(cs->gradient_type)) break; has_pixmap_changed = True; free_colorset_background(cs, True); CopyString(&cs->gradient_args, args); do_reload_pixmap = True; if (cs->gradient_type == V_GRADIENT) { cs->pixmap_type = PIXMAP_STRETCH_Y; } else if (cs->gradient_type == H_GRADIENT) cs->pixmap_type = PIXMAP_STRETCH_X; else cs->pixmap_type = PIXMAP_STRETCH; } else { fvwm_msg( WARN, name, "bad colorset pixmap " "specifier %s %s", option, line); } break; } /* switch */ if (option) { free(option); option = NULL; } free(optstring); optstring = NULL; } /* while (line && *line) */ /* * ---------- change the "pixmap" tint colour ---------- */ if (has_tint_changed) { /* user specified colour */ if (tint != NULL) { Pixel old_tint = cs->tint; PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True); cs->tint = GetColor(tint); if (old_tint != cs->tint) { have_pixels_changed = True; } } else if (tint == NULL) { /* default */ Pixel old_tint = cs->tint; PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True); cs->tint = GetColor(black); if (old_tint != cs->tint) { have_pixels_changed = True; } } } /* * reload the gradient if the tint or the alpha have changed. * Do this too if we need to recompute the bg average and the * gradient is tinted (perforemence issue). */ if ((has_tint_changed || has_image_alpha_changed || (has_bg_changed && (cs->color_flags & BG_AVERAGE) && cs->tint_percent > 0)) && cs->gradient_args) { do_reload_pixmap = True; } /* * reset the pixmap if the tint or the alpha has changed */ if (!do_reload_pixmap && (has_tint_changed || has_image_alpha_changed || (has_bg_changed && cs->alpha_pixmap != None))) { if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE || cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN) { do_reload_pixmap = True; } else if (cs->picture != NULL && cs->pixmap) { XSetClipMask(dpy, gc, cs->picture->mask); reset_cs_pixmap(cs, gc); XSetClipMask(dpy, gc, None); has_pixmap_changed = True; } } /* * (re)build the pixmap or the gradient */ if (do_reload_pixmap) { free_colorset_background(cs, False); has_pixmap_changed = True; if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE || cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN) { cs->pixmap_type = 0; if (root_pic.pixmap) { cs->pixmap = root_pic.pixmap; cs->width = root_pic.width; cs->height = root_pic.height; cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE; #if 0 fprintf(stderr,"Cset %i LoadRoot 0x%lx\n", n, cs->pixmap); #endif } } else if (cs->pixmap_args) { parse_pixmap(win, gc, cs, &pixmap_is_a_bitmap); } else if (cs->gradient_args) { cs->pixmap = CreateGradientPixmapFromString( dpy, win, gc, cs->gradient_type, cs->gradient_args, &w, &h, &cs->pixels, &cs->nalloc_pixels, cs->dither); cs->width = w; cs->height = h; } has_pixmap_changed = True; } if (cs->picture != NULL && cs->picture->depth != Pdepth) { pixmap_is_a_bitmap = True; } /* * ---------- change the background colour ---------- */ if (has_bg_changed || (has_pixmap_changed && (cs->color_flags & BG_AVERAGE) && cs->pixmap != None && cs->pixmap != ParentRelative && !pixmap_is_a_bitmap)) { Bool do_set_default_background = False; Pixmap average_pix = None; if (cs->color_flags & BG_AVERAGE) { if (cs->picture != NULL && cs->picture->picture != None) { average_pix = cs->picture->picture; } else if (cs->pixmap != ParentRelative) { average_pix = cs->pixmap; } if (average_pix == root_pic.pixmap) { int w; int h; XID dummy; MyXGrabServer(dpy); is_server_grabbed = True; if (!XGetGeometry( dpy, average_pix, &dummy, (int *)&dummy, (int *)&dummy, (unsigned int *)&w, (unsigned int *)&h, (unsigned int *)&dummy, (unsigned int *)&dummy)) { average_pix = None; } else { if (w != cs->width || h != cs->height) { average_pix = None; } } if (average_pix == None) { MyXUngrabServer(dpy); is_server_grabbed = False; } } } /* note: no average for bitmap */ if ((cs->color_flags & BG_AVERAGE) && average_pix) { /* calculate average background color */ XColor *colors; XImage *image; XImage *mask_image = None; unsigned int i, j, k = 0; unsigned long red = 0, blue = 0, green = 0; unsigned long tred, tblue, tgreen; double dred = 0.0, dblue = 0.0, dgreen = 0.0; has_bg_changed = True; /* create an array to store all the pixmap colors in */ /* Note: this may allocate a lot of memory: * cs->width * cs->height * 12 and then the rest of the * procedure can take a lot of times */ colors = (XColor *)safemalloc( cs->width * cs->height * sizeof(XColor)); /* get the pixmap and mask into an image */ image = XGetImage( dpy, average_pix, 0, 0, cs->width, cs->height, AllPlanes, ZPixmap); if (cs->mask != None) { mask_image = XGetImage( dpy, cs->mask, 0, 0, cs->width, cs->height, AllPlanes, ZPixmap); } if (is_server_grabbed == True) { MyXUngrabServer(dpy); } if (image != None && mask_image != None) { /* only fetch the pixels that are not masked * out */ for (i = 0; i < cs->width; i++) { for (j = 0; j < cs->height; j++) { if ( cs->mask == None || XGetPixel( mask_image, i, j) == 0) { colors[k++].pixel = XGetPixel( image, i, j); } } } } if (image != None) { XDestroyImage(image); } if (mask_image != None) { XDestroyImage(mask_image); } if (k == 0) { do_set_default_background = True; } else { /* look them all up, XQueryColors() can't * handle more than 256 */ for (i = 0; i < k; i += 256) { XQueryColors( dpy, Pcmap, &colors[i], min(k - i, 256)); } /* calculate average, add overflows in a double * .red is short, red is long */ for (i = 0; i < k; i++) { tred = red; red += colors[i].red; if (red < tred) { dred += (double)tred; red = colors[i].red; } tgreen = green; green += colors[i].green; if (green < tgreen) { dgreen += (double)tgreen; green = colors[i].green; } tblue = blue; blue += colors[i].blue; if (blue < tblue) { dblue += (double)tblue; blue = colors[i].blue; } } dred += red; dgreen += green; dblue += blue; /* get it */ color.red = dred / k; color.green = dgreen / k; color.blue = dblue / k; { Pixel old_bg = cs->bg; PictureFreeColors( dpy, Pcmap, &cs->bg, 1, 0, True); PictureAllocColor( dpy, Pcmap, &color, True); cs->bg = color.pixel; if (old_bg != cs->bg) { have_pixels_changed = True; } } } free(colors); } /* average */ else if ((cs->color_flags & BG_SUPPLIED) && bg != NULL) { /* user specified colour */ Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = GetColor(bg); if (old_bg != cs->bg) { have_pixels_changed = True; } } /* user specified */ else if (bg == NULL && has_bg_changed) { /* default */ do_set_default_background = True; } /* default */ if (do_set_default_background) { Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = GetColor(white); if (old_bg != cs->bg) { have_pixels_changed = True; } has_bg_changed = True; } if (has_bg_changed) { /* save the bg color for tinting */ cs->bg_saved = cs->bg; } } /* has_bg_changed */ /* * ---------- setup the bg tint colour ---------- */ if (has_bg_tint_changed && cs->bg_tint_percent > 0 && bg_tint != NULL) { PictureFreeColors(dpy, Pcmap, &cs->bg_tint, 1, 0, True); cs->bg_tint = GetColor(bg_tint); } /* * ---------- tint the bg colour ---------- */ if (has_bg_tint_changed || (has_bg_changed && cs->bg_tint_percent > 0)) { if (cs->bg_tint_percent == 0) { Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = cs->bg_saved; if (old_bg != cs->bg) { have_pixels_changed = True; has_bg_changed = True; } } else { Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = GetTintedPixel( cs->bg_saved, cs->bg_tint, cs->bg_tint_percent); if (old_bg != cs->bg) { have_pixels_changed = True; has_bg_changed = True; } } } /* * ---------- setup the fg tint colour ---------- */ if (has_fg_tint_changed && cs->fg_tint_percent > 0 && fg_tint != NULL) { PictureFreeColors(dpy, Pcmap, &cs->fg_tint, 1, 0, True); cs->fg_tint = GetColor(fg_tint); } /* * ---------- change the foreground colour ---------- */ if (has_fg_changed || (has_bg_changed && (cs->color_flags & FG_CONTRAST))) { if (cs->color_flags & FG_CONTRAST) { Pixel old_fg = cs->fg; /* calculate contrasting foreground color */ color.pixel = cs->bg; XQueryColor(dpy, Pcmap, &color); color.red = (color.red > 32767) ? 0 : 65535; color.green = (color.green > 32767) ? 0 : 65535; color.blue = (color.blue > 32767) ? 0 : 65535; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); PictureAllocColor(dpy, Pcmap, &color, True); cs->fg = color.pixel; if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } /* contrast */ else if ((cs->color_flags & FG_SUPPLIED) && fg != NULL) { /* user specified colour */ Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = GetColor(fg); if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } /* user specified */ else if (fg == NULL) { /* default */ Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = GetColor(black); if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } /* save the fg color for tinting */ cs->fg_saved = cs->fg; } /* has_fg_changed */ /* * ---------- tint the foreground colour ---------- */ if (has_fg_tint_changed || (has_fg_changed && cs->fg_tint_percent > 0)) { if (cs->fg_tint_percent == 0) { Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = cs->fg_saved; if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } else { Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = GetTintedPixel( cs->fg_saved, cs->fg_tint, cs->fg_tint_percent); if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } } /* * ---------- change the hilight colour ---------- */ if (has_hi_changed || (has_bg_changed && !(cs->color_flags & HI_SUPPLIED))) { has_hi_changed = 1; if ((cs->color_flags & HI_SUPPLIED) && hi != NULL) { /* user specified colour */ Pixel old_hilite = cs->hilite; PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True); cs->hilite = GetColor(hi); if (old_hilite != cs->hilite) { have_pixels_changed = True; } } /* user specified */ else if (hi == NULL) { Pixel old_hilite = cs->hilite; PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True); cs->hilite = GetHilite(cs->bg); if (old_hilite != cs->hilite) { have_pixels_changed = True; } } } /* has_hi_changed */ /* * ---------- change the shadow colour ---------- */ if (has_sh_changed || (has_bg_changed && !(cs->color_flags & SH_SUPPLIED))) { has_sh_changed = 1; if ((cs->color_flags & SH_SUPPLIED) && sh != NULL) { /* user specified colour */ Pixel old_shadow = cs->shadow; PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True); cs->shadow = GetColor(sh); if (old_shadow != cs->shadow) { have_pixels_changed = True; } } /* user specified */ else if (sh == NULL) { Pixel old_shadow = cs->shadow; PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True); cs->shadow = GetShadow(cs->bg); if (old_shadow != cs->shadow) { have_pixels_changed = True; } } } /* has_sh_changed */ /* * ---------- change the shadow foreground colour ---------- */ if (has_fgsh_changed || ((has_fg_changed || has_bg_changed) && !(cs->color_flags & FGSH_SUPPLIED))) { has_fgsh_changed = 1; if ((cs->color_flags & FGSH_SUPPLIED) && fgsh != NULL) { /* user specified colour */ Pixel old_fgsh = cs->fgsh; PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True); cs->fgsh = GetColor(fgsh); if (old_fgsh != cs->fgsh) { have_pixels_changed = True; } } /* user specified */ else if (fgsh == NULL) { Pixel old_fgsh = cs->fgsh; PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True); cs->fgsh = GetForeShadow(cs->fg, cs->bg); if (old_fgsh != cs->fgsh) { have_pixels_changed = True; } } } /* has_fgsh_changed */ /* * ------- the pixmap is a bitmap: create here cs->pixmap ------- */ if (cs->picture != None && pixmap_is_a_bitmap && (has_pixmap_changed || has_bg_changed)) { cs->pixmap = XCreatePixmap( dpy, win, cs->width, cs->height, Pdepth); XSetBackground(dpy, gc, cs->bg); XSetForeground(dpy, gc, cs->fg); reset_cs_pixmap(cs, gc); } /* * ------- change the masked out parts of the background pixmap ------- */ if (cs->pixmap != None && cs->pixmap != ParentRelative && (!CSETS_IS_TRANSPARENT_ROOT(cs)|| cs->allows_buffered_transparency) && (cs->mask != None || cs->alpha_pixmap != None || cs->image_alpha_percent < 100 || cs->tint_percent > 0) && (has_pixmap_changed || has_bg_changed || has_image_alpha_changed || has_tint_changed)) { /* Now that we know the background colour we can update the * pixmap background. */ FvwmRenderAttributes fra; Pixmap temp, mask, alpha; memset(&fra, 0, sizeof(fra)); temp = XCreatePixmap(dpy, win, cs->width, cs->height, Pdepth); if (cs->picture != NULL) { mask = cs->picture->mask; alpha = cs->picture->alpha; } else { mask = None; alpha = None; } XSetForeground(dpy, gc, cs->bg); XFillRectangle( dpy, temp, gc, 0, 0, cs->width, cs->height); fra.mask = FRAM_HAVE_ADDED_ALPHA | FRAM_HAVE_TINT; fra.added_alpha_percent = cs->image_alpha_percent; fra.tint = cs->tint; fra.tint_percent = cs->tint_percent; PGraphicsRenderPixmaps( dpy, win, cs->pixmap, mask, alpha, Pdepth, &fra, temp, gc, Scr.MonoGC, Scr.AlphaGC, 0, 0, cs->width, cs->height, 0, 0, cs->width, cs->height, False); if (cs->pixmap != root_pic.pixmap) { add_to_junk(cs->pixmap); } cs->pixmap = temp; has_pixmap_changed = True; if (CSETS_IS_TRANSPARENT_ROOT(cs)) { cs->pixmap_type = PIXMAP_ROOT_PIXMAP_TRAN; } } /* has_pixmap_changed */ /* * ---------- change the icon tint colour ---------- */ if (has_icon_tint_changed) { /* user specified colour */ if (icon_tint != NULL) { Pixel old_tint = cs->icon_tint; PictureFreeColors( dpy, Pcmap, &cs->icon_tint, 1, 0, True); cs->icon_tint = GetColor(icon_tint); if (old_tint != cs->icon_tint) { has_icon_pixels_changed = True; } } else { /* default */ Pixel old_tint = cs->icon_tint; PictureFreeColors( dpy, Pcmap, &cs->icon_tint, 1, 0, True); cs->icon_tint = GetColor(black); if (old_tint != cs->icon_tint) { has_icon_pixels_changed = True; } } } /* * ---------- send new colorset to fvwm and clean up ---------- */ /* make sure the server has this to avoid races */ XSync(dpy, False); /* inform modules of the change */ if (have_pixels_changed || has_pixmap_changed || has_shape_changed || has_fg_alpha_changed || has_icon_pixels_changed) { BroadcastColorset(n); } if (fg) { free(fg); } if (bg) { free(bg); } if (hi) { free(hi); } if (sh) { free(sh); } if (fgsh) { free(fgsh); } if (tint) { free(tint); } if (fg_tint) { free(fg_tint); } if (bg_tint) { free(bg_tint); } if (icon_tint) { free(icon_tint); } return; }
/* * alloc_colorset() grows the size of the Colorset array to include set n * colorset_t *Colorset will be altered * returns the address of the member */ void alloc_colorset(int n) { /* do nothing if it already exists */ if (n < nColorsets) { return; } else { Colorset = (colorset_t *)saferealloc( (char *)Colorset, (n + 1) * sizeof(colorset_t)); memset( &Colorset[nColorsets], 0, (n + 1 - nColorsets) * sizeof(colorset_t)); } if (n == 0) { update_root_pixmap(0); } /* initialize new colorsets to black on gray */ while (nColorsets <= n) { colorset_t *ncs = &Colorset[nColorsets]; if (PictureUseBWOnly()) { char g_bits[] = {0x0a, 0x05, 0x0a, 0x05, 0x08, 0x02, 0x08, 0x02, 0x01, 0x02, 0x04, 0x08}; /* monochrome monitors get black on white */ /* with a gray pixmap background */ ncs->fg = GetColor(black); ncs->bg = GetColor(white); ncs->hilite = GetColor(white); ncs->shadow = GetColor(black); ncs->fgsh = GetColor(white); ncs->tint = GetColor(black); ncs->icon_tint = GetColor(black); ncs->pixmap = XCreatePixmapFromBitmapData( dpy, Scr.NoFocusWin, &g_bits[4 * (nColorsets % 3)], 4, 4, PictureBlackPixel(), PictureWhitePixel(), Pdepth); ncs->width = 4; ncs->height = 4; } else { ncs->fg = GetColor(black); ncs->bg = GetColor(gray); ncs->hilite = GetHilite(ncs->bg); ncs->shadow = GetShadow(ncs->bg); ncs->fgsh = GetForeShadow(ncs->fg, ncs->bg); ncs->tint = GetColor(black); ncs->icon_tint = GetColor(black); } ncs->fg_tint = ncs->bg_tint = GetColor(black); /* set flags for fg contrast, bg average */ /* in case just a pixmap is given */ ncs->color_flags = FG_CONTRAST | BG_AVERAGE; ncs->fg_saved = ncs->fg; ncs->fg_alpha_percent = 100; ncs->image_alpha_percent = 100; ncs->icon_alpha_percent = 100; ncs->tint_percent = 0; ncs->icon_tint_percent = 0; ncs->fg_tint_percent = ncs->bg_tint_percent = 0; ncs->dither = (PictureDitherByDefault())? True:False; nColorsets++; } }
/****************************************************************************** MakeMeWindow - Create and setup the window we will need ******************************************************************************/ void MakeMeWindow(void) { XSizeHints hints; XGCValues gcval; unsigned long gcmask; unsigned int dummy1, dummy2; int x, y, ret, count; Window dummyroot, dummychild; int i; if ((count = ItemCountD(&windows))==0 && Transient) ShutMeDown(0); AdjustWindow(); hints.width=win_width; hints.height=win_height; hints.win_gravity=NorthWestGravity; hints.flags=PSize|PWinGravity|PResizeInc; hints.width_inc=0; hints.height_inc=0; if (geometry!= NULL) { ret=XParseGeometry(geometry,&x,&y,&dummy1,&dummy2); if (ret&XValue && ret &YValue) { hints.x=x; if (ret&XNegative) hints.x+=XDisplayWidth(dpy,screen)-win_width; hints.y=y; if (ret&YNegative) hints.y+=XDisplayHeight(dpy,screen)-win_height; hints.flags|=USPosition; } if (ret&XNegative) { if (ret&YNegative) hints.win_gravity=SouthEastGravity; else hints.win_gravity=NorthEastGravity; } else { if (ret&YNegative) hints.win_gravity=SouthWestGravity; else hints.win_gravity=NorthWestGravity; } } if (Transient) { XQueryPointer(dpy,Root,&dummyroot,&dummychild,&hints.x,&hints.y,&x,&y,&dummy1); hints.win_gravity=NorthWestGravity; hints.flags |= USPosition; } win_grav=hints.win_gravity; win_x=hints.x; win_y=hints.y; for (i = 0; i != MAX_COLOUR_SETS; i++) if(d_depth < 2) { back[i] = GetColor("white"); fore[i] = GetColor("black"); } else { back[i] = GetColor(BackColor[i] == NULL ? BackColor[0] : BackColor[i]); fore[i] = GetColor(ForeColor[i] == NULL ? ForeColor[0] : ForeColor[i]); } win=XCreateSimpleWindow(dpy,Root,hints.x,hints.y,hints.width,hints.height,1, fore[0],back[0]); wm_del_win=XInternAtom(dpy,"WM_DELETE_WINDOW",False); XSetWMProtocols(dpy,win,&wm_del_win,1); XSetWMNormalHints(dpy,win,&hints); if (!Transient) { XGrabButton(dpy,1,AnyModifier,win,True,GRAB_EVENTS,GrabModeAsync, GrabModeAsync,None,None); XGrabButton(dpy,2,AnyModifier,win,True,GRAB_EVENTS,GrabModeAsync, GrabModeAsync,None,None); XGrabButton(dpy,3,AnyModifier,win,True,GRAB_EVENTS,GrabModeAsync, GrabModeAsync,None,None); SetMwmHints(MWM_DECOR_ALL|MWM_DECOR_RESIZEH|MWM_DECOR_MAXIMIZE|MWM_DECOR_MINIMIZE, MWM_FUNC_ALL|MWM_FUNC_RESIZE|MWM_FUNC_MAXIMIZE|MWM_FUNC_MINIMIZE, MWM_INPUT_MODELESS); } else { SetMwmHints(0,MWM_FUNC_ALL,MWM_INPUT_MODELESS); } for (i = 0; i != MAX_COLOUR_SETS; i++) { gcval.foreground=fore[i]; gcval.background=back[i]; gcval.font=ButtonFont->fid; gcmask=GCForeground|GCBackground|GCFont; graph[i]=XCreateGC(dpy,Root,gcmask,&gcval); if(d_depth < 2) gcval.foreground=GetShadow(fore[i]); else gcval.foreground=GetShadow(back[i]); gcval.background=back[i]; gcmask=GCForeground|GCBackground; shadow[i]=XCreateGC(dpy,Root,gcmask,&gcval); gcval.foreground=GetHilite(back[i]); gcval.background=back[i]; gcmask=GCForeground|GCBackground; hilite[i]=XCreateGC(dpy,Root,gcmask,&gcval); gcval.foreground=back[i]; gcmask=GCForeground; background[i]=XCreateGC(dpy,Root,gcmask,&gcval); } XSelectInput(dpy,win,(ExposureMask | KeyPressMask)); ChangeWindowName(&Module[1]); if (ItemCountD(&windows) > 0) { XMapRaised(dpy,win); WaitForExpose(); WindowIsUp=1; } else WindowIsUp=2; if (Transient) { if ( XGrabPointer(dpy,win,True,GRAB_EVENTS,GrabModeAsync,GrabModeAsync, None,None,CurrentTime)!=GrabSuccess) ShutMeDown(1); XQueryPointer(dpy,Root,&dummyroot,&dummychild,&hints.x,&hints.y,&x,&y,&dummy1); if (!SomeButtonDown(dummy1)) ShutMeDown(0); } }
MyStyle * mystyle_create_from_definition (struct ASHashTable *list, MyStyleDefinition * def) { int i; MyStyle *style; if (def == NULL || def->Name == NULL) return NULL; if ((style = mystyle_find (def->Name)) == NULL) style = mystyle_new_with_name (def->Name); if (def->inherit) { for (i = 0; i < def->inherit_num; ++i) { MyStyle *parent; if (def->inherit[i]) { if ((parent = mystyle_find_or_get_from_file (list, def->inherit[i])) != NULL) mystyle_merge_styles (parent, style, True, False); else show_error ("unknown style to inherit: %s\n", def->inherit[i]); } } } if( def->Font ) { if (get_flags(style->user_flags, F_FONT)) { unload_font (&style->font); clear_flags(style->user_flags, F_FONT); } set_string(&(style->font.name), mystrdup(def->Font)); set_flags(style->user_flags, F_FONT); } if( get_flags(def->set_flags, MYSTYLE_TextStyle ) ) { set_flags( style->user_flags, F_TEXTSTYLE ); style->text_style = def->TextStyle; } if( get_flags(def->set_flags, MYSTYLE_SLICE_SET ) ) { set_flags( style->user_flags, F_SLICE ); style->slice_x_start = def->SliceXStart; style->slice_x_end = def->SliceXEnd; style->slice_y_start = def->SliceYStart; style->slice_y_end = def->SliceYEnd; } if( get_flags(def->set_flags, MYSTYLE_BlurSize ) ) { set_flags( style->user_flags, F_BLUR ); style->blur_x = def->BlurSize.width; style->blur_y = def->BlurSize.height; } if( def->ForeColor ) { if (parse_argb_color (def->ForeColor, &(style->colors.fore)) != def->ForeColor) set_flags(style->user_flags, F_FORECOLOR); else show_error("unable to parse Forecolor \"%s\"", def->ForeColor); } if( def->BackColor ) { if (parse_argb_color (def->BackColor, &(style->colors.back)) != def->BackColor) { style->relief.fore = GetHilite (style->colors.back); style->relief.back = GetShadow (style->colors.back); set_flags(style->user_flags, F_BACKCOLOR); }else show_error("unable to parse BackColor \"%s\"", def->BackColor); } if( def->overlay != NULL ) { MyStyle *o = mystyle_find_or_get_from_file (list, def->overlay ); if ( o != NULL) { style->overlay = o; style->overlay_type = def->overlay_type ; }else show_error ("unknown style to be overlayed with: %s\n", def->overlay ); set_flags(style->user_flags, F_OVERLAY); } if( def->texture_type > 0 && def->texture_type <= TEXTURE_GRADIENT_END ) { int type = def->back_grad_type; ASGradient gradient = {0}; Bool success = False; if( type <= TEXTURE_OLD_GRADIENT_END ) { ARGB32 color1 = ARGB32_White, color2 = ARGB32_Black; parse_argb_color( def->back_grad_colors[0], &color1 ); parse_argb_color( def->back_grad_colors[1], &color2 ); if ((type = mystyle_parse_old_gradient (type, color1, color2, &gradient)) >= 0) { if (style->user_flags & F_BACKGRADIENT) { free (style->gradient.color); free (style->gradient.offset); } style->gradient = gradient; style->gradient.type = mystyle_translate_grad_type (type); LOCAL_DEBUG_OUT( "style %p type = %d", style, style->gradient.type ); success = True ; } else show_error("Error in MyStyle \"%s\": invalid gradient type %d", style->name, type); }else { int i ; gradient.npoints = def->back_grad_npoints; gradient.color = safecalloc(gradient.npoints, sizeof(ARGB32)); gradient.offset = safecalloc(gradient.npoints, sizeof(double)); for( i = 0 ; i < gradient.npoints ; ++i ) { ARGB32 color = ARGB32_White; parse_argb_color (def->back_grad_colors[i], &color ); gradient.color[i] = color ; gradient.offset[i] = def->back_grad_offsets[i] ; } gradient.offset[0] = 0.0; gradient.offset[gradient.npoints - 1] = 1.0; if (style->user_flags & F_BACKGRADIENT) { free (style->gradient.color); free (style->gradient.offset); } style->gradient = gradient; style->gradient.type = mystyle_translate_grad_type (type); success = True ; } if( success ) { style->texture_type = def->texture_type; set_flags( style->user_flags, F_BACKGRADIENT ); }else { if (gradient.color != NULL) free (gradient.color); if (gradient.offset != NULL) free (gradient.offset); show_error("Error in MyStyle \"%s\": bad gradient", style->name); } }else if( def->texture_type > TEXTURE_GRADIENT_END && def->texture_type <= TEXTURE_TEXTURED_END ) { int type = def->texture_type; if ( get_flags(style->user_flags, F_BACKPIXMAP) ) { mystyle_free_back_icon(style); clear_flags (style->user_flags, F_BACKTRANSPIXMAP | F_BACKPIXMAP); } clear_flags (style->inherit_flags, F_BACKTRANSPIXMAP | F_BACKPIXMAP); LOCAL_DEBUG_OUT( "calling mystyle_free_back_icon for style %p", style ); if (type == TEXTURE_TRANSPARENT || type == TEXTURE_TRANSPARENT_TWOWAY) { /* treat second parameter as ARGB tint value : */ if (parse_argb_color (def->back_pixmap, &(style->tint)) == def->back_pixmap) style->tint = TINT_LEAVE_SAME; /* use no tinting by default */ else if (type == TEXTURE_TRANSPARENT) style->tint = (style->tint >> 1) & 0x7F7F7F7F; /* converting old style tint */ /*LOCAL_DEBUG_OUT( "tint is 0x%X (from %s)", style->tint, tmp);*/ set_flags (style->user_flags, F_BACKPIXMAP); style->texture_type = type; } else { /* treat second parameter as an image filename : */ if ( load_icon(&(style->back_icon), def->back_pixmap, get_screen_image_manager(NULL) ))
void CreateWindow(int x,int y, int w, int h) { XGCValues gcv; unsigned long gcm; wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); _XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False); mysizehints.flags = PWinGravity| PResizeInc | PBaseSize | PMaxSize | PMinSize | USSize | USPosition; /* subtract one for the right/bottom border */ mysizehints.width_inc = 1; mysizehints.height_inc = 1; mysizehints.base_height = BAR_WIDTH+PAD_WIDTH3; mysizehints.base_width = BAR_WIDTH+PAD_WIDTH3; Width = w/Reduction_H + BAR_WIDTH + PAD_WIDTH3; Height = h/Reduction_V + BAR_WIDTH + PAD_WIDTH3; target_width = w; target_height = h; mysizehints.width = Width; mysizehints.height = Height; mysizehints.x = x; mysizehints.y = y; mysizehints.max_width = w + BAR_WIDTH + PAD_WIDTH3; mysizehints.max_height = h + BAR_WIDTH + PAD_WIDTH3; mysizehints.win_gravity = NorthWestGravity; if(d_depth < 2) { back_pix = GetColor("black"); fore_pix = GetColor("white"); hilite_pix = fore_pix; shadow_pix = back_pix; } else { back_pix = GetColor(BackColor); hilite_pix = GetHilite(back_pix); shadow_pix = GetShadow(back_pix); } main_win = XCreateSimpleWindow(dpy,Root,mysizehints.x,mysizehints.y, mysizehints.width,mysizehints.height, 0,fore_pix,back_pix); XSetWMProtocols(dpy,main_win,&wm_del_win,1); XSetWMNormalHints(dpy,main_win,&mysizehints); XSelectInput(dpy,main_win,MW_EVENTS); change_window_name(MyName); holder_win = XCreateSimpleWindow(dpy,main_win,PAD_WIDTH3,PAD_WIDTH3, mysizehints.width-BAR_WIDTH -PAD_WIDTH3, mysizehints.height-BAR_WIDTH-PAD_WIDTH3, 0,fore_pix,back_pix); XMapWindow(dpy,holder_win); gcm = GCForeground|GCBackground; gcv.foreground = hilite_pix; gcv.background = hilite_pix; ReliefGC = XCreateGC(dpy, Root, gcm, &gcv); gcm = GCForeground|GCBackground; gcv.foreground = shadow_pix; gcv.background = shadow_pix; ShadowGC = XCreateGC(dpy, Root, gcm, &gcv); _XA_WM_COLORMAP_WINDOWS = XInternAtom (dpy, "WM_COLORMAP_WINDOWS", False); }