/* Draws text with a texture * * d - target drawable * font - font to draw text * x,y - position of text * gradient - texture pixmap. size must be at least as large as text * text - text to draw * chars - chars in text */ void DrawTexturedText(Display *dpy, Drawable d, XFontStruct *font, int x, int y, Pixmap gradient, char *text, int chars) { Pixmap mask; int w,h; GC gc; XGCValues gcv; /* make the mask pixmap */ w = XTextWidth(font,text,chars); h = font->ascent+font->descent; mask=XCreatePixmap(dpy,main_win,w+1,h+1,1); gcv.foreground = 0; gcv.function = GXcopy; gcv.font = font->fid; gc = fvwmlib_XCreateGC(dpy,mask,GCFunction|GCForeground|GCFont,&gcv); XFillRectangle(dpy,mask,gc,0,0,w,h); XSetForeground(dpy,gc,1); XDrawString(dpy,mask,gc,0,font->ascent,text,chars); XFreeGC(dpy,gc); /* draw the texture */ gcv.function=GXcopy; gc = fvwmlib_XCreateGC(dpy,d,GCFunction,&gcv); XSetClipOrigin(dpy,gc,x,y); XSetClipMask(dpy,gc,mask); XCopyArea(dpy,gradient,d,gc,0,0,w,h,x,y); XFreeGC(dpy,gc); XFreePixmap(dpy,mask); }
static void __initialize_window(Display *dpy) { XGCValues xgcv; unsigned long valuemask; XSetWindowAttributes attributes; Atom _net_um_window_type; long _net_um_window_type_tooltips; valuemask = CWOverrideRedirect | CWEventMask | CWColormap; attributes.override_redirect = True; attributes.event_mask = ExposureMask; attributes.colormap = Pcmap; win = XCreateWindow( dpy, DefaultRootWindow(dpy), 0, 0, 1, 1, current_config->border_width, Pdepth, InputOutput, Pvisual, valuemask, &attributes); _net_um_window_type = XInternAtom( dpy, "_NET_UM_WINDOW_TYPE", False); _net_um_window_type_tooltips = XInternAtom( dpy, "_NET_UM_WINDOW_TYPE_TOOLTIPS", False); XChangeProperty( dpy, win, _net_um_window_type, XA_ATOM, 32, PropModeReplace, (unsigned char *) &_net_um_window_type_tooltips, 1); _net_um_for = XInternAtom(dpy, "_NET_UM_FOR", False); gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv); return; }
/* Creates a pixmap that is a vertically stretched version of the input * pixmap */ Pixmap CreateStretchYPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int src_depth, int dest_height, GC gc) { int i; Pixmap pixmap; GC my_gc = None; if (src_height < 0 || src_depth < 0 || dest_height < 0) { return None; } pixmap = XCreatePixmap(dpy, src, src_width, dest_height, src_depth); if (pixmap == None) { return None; } if (gc == None) { my_gc = fvwmlib_XCreateGC(dpy, pixmap, 0, 0); } for (i = 0; i < dest_height; i++) { XCopyArea( dpy, src, pixmap, (gc == None)? my_gc:gc, 0, (i * src_height) / dest_height, src_width, 1, 0, i); } if (my_gc) { XFreeGC(dpy, my_gc); } return pixmap; }
static void CreateOrUpdateGoodyGC(void) { XGCValues gcval; unsigned long gcmask; Pixel pfore; Pixel pback; if (colorset >= 0) { pfore = Colorset[colorset].fg; pback = Colorset[colorset].bg; } else { pfore = fore; pback = back; } gcmask = GCForeground | GCBackground | GCGraphicsExposures; gcval.foreground = pfore; gcval.background = pback; gcval.graphics_exposures = False; if (FStatusFont->font != NULL) { gcval.font = FStatusFont->font->fid; gcmask = GCFont; } if (statusgc) XChangeGC(dpy, statusgc, gcmask, &gcval); else statusgc = fvwmlib_XCreateGC(dpy, win, gcmask, &gcval); if (do_check_mail) { if (mailpix) XFreePixmap(dpy, mailpix); mailpix = XCreatePixmapFromBitmapData( dpy, win, (char *)minimail_bits, minimail_width, minimail_height, pfore, pback, Pdepth); if (wmailpix) XFreePixmap(dpy, wmailpix); wmailpix = XCreatePixmapFromBitmapData( dpy, win, (char *)minimail_bits, minimail_width, minimail_height, PictureBlackPixel(), PictureWhitePixel(), Pdepth); goodies_width += minimail_width + 7; } else if (do_display_clock) { goodies_width += 3; } else { goodies_width += 0; } }
static void draw_highlight_background( struct MenuPaintItemParameters *mpip, int x, int y, int width, int height, colorset_t *cs, GC gc) { if (cs != NULL && cs->pixmap && cs->pixmap_type != PIXMAP_TILED) { Pixmap p; p = CreateOffsetBackgroundPixmap( dpy, mpip->w, 0, 0, width, height, cs, Pdepth, gc, False); switch (cs->pixmap_type) { case PIXMAP_STRETCH_X: /* todo: optimize to only create one pixmap and gc per * mr. */ case PIXMAP_STRETCH_Y: { XGCValues gcv; int gcm; GC bgc; gcv.tile = p; gcv.fill_style = FillTiled; gcm = GCFillStyle | GCTile; /* vertcal gradients has to be aligned properly */ if (cs->pixmap_type == PIXMAP_STRETCH_Y) { gcv.ts_y_origin = y; gcm|=GCTileStipYOrigin; } else if (cs->pixmap_type == PIXMAP_STRETCH_X) { gcv.ts_x_origin = x; gcm|=GCTileStipXOrigin; } bgc = fvwmlib_XCreateGC(dpy, mpip->w, gcm, &gcv); XFillRectangle(dpy, mpip->w, bgc, x, y, width, height); XFreeGC(dpy, bgc); break; } default: XCopyArea(dpy, p, mpip->w, gc, 0, 0, width, height, x, y); break; } XFreePixmap(dpy, p); } else { XFillRectangle(dpy, mpip->w, gc, x, y, width, height); } }
/*************************************************************************** * * * Looks for an application supplied bitmap or pixmap * *************************************************************************** */ void GetIconBitmap(struct icon_info *item) { int x, y; unsigned int bw, depth; Window Junkroot; GC gc; item->icon_file = NULL; item->icon_maskPixmap = None; item->iconPixmap = None; item->icon_w = 0; item->icon_h = 0; if (!XGetGeometry(dpy, item->wmhints->icon_pixmap, &Junkroot, &x, &y, (unsigned int *)&item->icon_w, (unsigned int *)&item->icon_h, &bw, &depth)) { /* disable icon pixmap hint */ item->wmhints->icon_pixmap = None; item->wmhints->flags &= ~IconPixmapHint; return; } /* sanity check the pixmap depth, it must be the same as the root or 1 */ if (depth != 1 && depth != DefaultDepth(dpy, screen)) { /* disable icon pixmap hint */ item->wmhints->icon_pixmap = None; item->wmhints->flags &= ~IconPixmapHint; return; } item->icon_depth = depth; if (FShapesSupported && (item->wmhints->flags & IconMaskHint)) { SET_ICON_SHAPED(item, True); item->icon_maskPixmap = item->wmhints->icon_mask; } item->icon_w = min(max_icon_width, item->icon_w); item->icon_h = min(max_icon_height, item->icon_h); if (item->icon_w <= 0 || item->icon_h <= 0) { item->icon_w = 0; item->icon_h = 0; return; } item->iconPixmap = XCreatePixmap(dpy, Root, item->icon_w, item->icon_h, depth); gc = fvwmlib_XCreateGC(dpy, item->iconPixmap, 0, NULL); XCopyArea(dpy, item->wmhints->icon_pixmap, item->iconPixmap, gc, 0, 0, item->icon_w, item->icon_h, 0, 0); XFreeGC(dpy, gc); SET_PIXMAP_OURS(item, False); }
/* * Fonction pour HDipstick * Création d'une jauge horizontale * plusieurs options */ void InitHDipstick(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; /* Enregistrement des couleurs et de la police */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } /* Minimum size */ if (xobj->width<30) xobj->width=30; if (xobj->height<11) xobj->height=11; mask=0; Attr.background_pixel=xobj->TabColor[back]; mask|=CWBackPixel; xobj->win=XCreateWindow(dpy,*xobj->ParentWin, xobj->x,xobj->y,xobj->width,xobj->height,0, CopyFromParent,InputOutput,CopyFromParent, mask,&Attr); xobj->gc=fvwmlib_XCreateGC(dpy,xobj->win,0,NULL); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSetForeground(dpy,xobj->gc,xobj->TabColor[fore]); XSetLineAttributes(dpy,xobj->gc,1,LineSolid,CapRound,JoinMiter); if (xobj->value2>xobj->value3) xobj->value3=xobj->value2+50; if (xobj->value<xobj->value2) xobj->value=xobj->value2; if (xobj->value>xobj->value3) xobj->value=xobj->value3; XSelectInput(dpy, xobj->win, ExposureMask); }
/* Creates a pixmap that is a stretched version of the input * pixmap */ Pixmap CreateStretchPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int src_depth, int dest_width, int dest_height, GC gc) { Pixmap pixmap = None; Pixmap temp_pixmap; GC my_gc = None; if (src_width < 0 || src_height < 0 || src_depth < 0 || dest_width < 0) { return None; } if (gc == None) { my_gc = fvwmlib_XCreateGC(dpy, src, 0, 0); } temp_pixmap = CreateStretchXPixmap( dpy, src, src_width, src_height, src_depth, dest_width, (gc == None)? my_gc:gc); if (temp_pixmap == None) { if (my_gc) { XFreeGC(dpy, my_gc); } return None; } pixmap = CreateStretchYPixmap( dpy, temp_pixmap, dest_width, src_height, src_depth, dest_height, (gc == None)? my_gc:gc); XFreePixmap(dpy, temp_pixmap); if (my_gc) { XFreeGC(dpy, my_gc); } return pixmap; }
/* scrolls a pixmap by x_off/y_off pixels, wrapping around at the edges. */ Pixmap ScrollPixmap( Display *dpy, Pixmap p, GC gc, int x_off, int y_off, int width, int height, unsigned int depth) { GC tgc; XGCValues xgcv; Pixmap p2; if (p == None || p == ParentRelative || (x_off == 0 && y_off == 0)) { return p; } tgc = fvwmlib_XCreateGC(dpy, p, 0, &xgcv); if (tgc == None) { return p; } XCopyGC(dpy, gc, GCFunction | GCPlaneMask| GCSubwindowMode | GCClipXOrigin | GCClipYOrigin | GCClipMask, tgc); xgcv.tile = p; xgcv.ts_x_origin = x_off; xgcv.ts_y_origin = y_off; xgcv.fill_style = FillTiled; XChangeGC( dpy, tgc, GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle, &xgcv); p2 = XCreatePixmap(dpy, p, width, height, depth); if (p2 == None) { return p; } XFillRectangle(dpy, p2, tgc, 0, 0, width, height); XFreeGC(dpy, tgc); return p2; }
void InitPopupMenu(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int i; char *str; /* Enregistrement des couleurs et de la police / set the colors and the font */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask = 0; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; Attr.cursor = XCreateFontCursor(dpy, XC_hand2); mask |= CWCursor; /* Curseur pour la fenetre / window cursor */ xobj->win = XCreateWindow(dpy, *xobj->ParentWin, xobj->x, xobj->y, xobj->width, xobj->height, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &Attr); xobj->gc = fvwmlib_XCreateGC(dpy, xobj->win, 0, NULL); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); if ((xobj->Ffont = FlocaleLoadFont(dpy, xobj->font, ScriptName)) == NULL) { fprintf(stderr, "%s: Couldn't load font. Exiting!\n", ScriptName); exit(1); } if (xobj->Ffont->font != NULL) XSetFont(dpy, xobj->gc, xobj->Ffont->font->fid); XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter); xobj->value3 = CountOption(xobj->title); if (xobj->value > xobj->value3) xobj->value = xobj->value3; if (xobj->value < 1) xobj->value = 1; /* Redimensionnement du widget / Widget resizing */ xobj->height = xobj->Ffont->height +12; xobj->width = 30; for (i = 1; i <= xobj->value3; i++) { str = (char*)GetMenuTitle(xobj->title, i); if (xobj->width < FlocaleTextWidth(xobj->Ffont, str, strlen(str))+34) xobj->width = FlocaleTextWidth(xobj->Ffont, str, strlen(str))+34; free(str); } XResizeWindow(dpy, xobj->win, xobj->width, xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSelectInput(dpy, xobj->win, ExposureMask); }
/* 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; }
/* Draws a colorset background into the specified rectangle in the target * drawable. */ void SetRectangleBackground( Display *dpy, Window win, int x, int y, int width, int height, colorset_struct *colorset, unsigned int depth, GC gc) { GC draw_gc; Pixmap pixmap2; Pixmap pixmap = None; static int last_depth = -1; static GC last_gc = None; XGCValues xgcv; Pixmap clipmask = None; GC clip_gc = None; Bool keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT); Bool stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X) || (colorset->pixmap_type == PIXMAP_STRETCH); Bool stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y) || (colorset->pixmap_type == PIXMAP_STRETCH); if (colorset->pixmap == ParentRelative) { XClearArea(dpy, win, x, y, width, height, False); /* don't do anything */ return; } /* minimize gc creation by remembering the last requested depth */ if (last_gc != None && depth != last_depth) { XFreeGC(dpy, last_gc); last_gc = None; } if (last_gc == None) { last_gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv); } draw_gc = last_gc; last_depth = depth; if (FHaveShapeExtension && colorset->shape_mask != None) { clipmask = CreateBackgroundPixmap( dpy, 0, width, height, colorset, 1, None, True); if (clipmask) { /* create a GC for clipping */ xgcv.clip_x_origin = x; xgcv.clip_y_origin = y; xgcv.clip_mask = clipmask; clip_gc = fvwmlib_XCreateGC( dpy, win, GCClipXOrigin|GCClipYOrigin|GCClipMask, &xgcv); draw_gc = clip_gc; } } if (!colorset->pixmap) { /* use the bg pixel */ XSetForeground(dpy, draw_gc, colorset->bg); XFillRectangle(dpy, win, draw_gc, x, y, width, height); } else { pixmap = CreateBackgroundPixmap( dpy, win, width, height, colorset, depth, gc, False); if (keep_aspect) { /* nothing to do */ } if (stretch_x || stretch_y) { if (!stretch_x && colorset->width != width) { pixmap2 = CreateStretchXPixmap( dpy, pixmap, colorset->width, height, depth, width, gc); XFreePixmap(dpy, pixmap); pixmap = pixmap2; } if (!stretch_y && colorset->height != height) { pixmap2 = CreateStretchYPixmap( dpy, pixmap, width, colorset->height, depth, width, gc); XFreePixmap(dpy, pixmap); pixmap = pixmap2; } } else { pixmap2 = CreateTiledPixmap( dpy, pixmap, colorset->width, colorset->height, width, height, depth, gc); XFreePixmap(dpy, pixmap); pixmap = pixmap2; } if (pixmap) { /* Copy the pixmap into the rectangle. */ XCopyArea(dpy, pixmap, win, draw_gc, 0, 0, width, height, x, y); XFreePixmap(dpy, pixmap); } } if (FHaveShapeExtension) { if (clipmask != None) XFreePixmap(dpy, clipmask); if (clip_gc != None) XFreeGC(dpy, clip_gc); } }
/* create a pixmap suitable for plonking on the background of a window */ Pixmap CreateBackgroundPixmap(Display *dpy, Window win, int width, int height, colorset_struct *colorset, unsigned int depth, GC gc, Bool is_shape_mask) { Pixmap pixmap = None; Pixmap cs_pixmap = None; XGCValues xgcv; static GC shape_gc = None; static GC solid_gc = None; int cs_width; int cs_height; Bool cs_keep_aspect; Bool cs_stretch_x; Bool cs_stretch_y; if (colorset->pixmap == ParentRelative && !is_shape_mask) { return ParentRelative; } if (!is_shape_mask) { cs_pixmap = colorset->pixmap; cs_width = colorset->width; cs_height = colorset->height; cs_keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT); cs_stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X) || (colorset->pixmap_type == PIXMAP_STRETCH); cs_stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y) || (colorset->pixmap_type == PIXMAP_STRETCH); } else { /* In spite of the name, win contains the pixmap */ cs_pixmap = colorset->shape_mask; win = colorset->shape_mask; if (shape_gc == None) { xgcv.foreground = 1; xgcv.background = 0; /* create a gc for 1 bit depth */ shape_gc = fvwmlib_XCreateGC(dpy, win, GCForeground|GCBackground, &xgcv); } gc = shape_gc; cs_width = colorset->shape_width; cs_height = colorset->shape_height; cs_keep_aspect = (colorset->shape_type == SHAPE_STRETCH_ASPECT); cs_stretch_x = !(colorset->shape_type == SHAPE_TILED); cs_stretch_y = !(colorset->shape_type == SHAPE_TILED); } if (cs_pixmap == None) { xgcv.foreground = colorset->bg; if (solid_gc == None) { /* create a gc for solid drawing */ solid_gc = fvwmlib_XCreateGC(dpy, win, GCForeground, &xgcv); } else { XChangeGC(dpy, solid_gc, GCForeground, &xgcv); } /* create a solid pixmap - not very useful most of the time */ pixmap = XCreatePixmap(dpy, win, width, height, depth); XFillRectangle(dpy, pixmap, solid_gc, 0, 0, width, height); } else if (cs_keep_aspect) { Bool trim_side; int big_width, big_height; Pixmap big_pixmap; int x, y; /* do sides need triming or top/bottom? */ trim_side = (cs_width * height > cs_height * width); /* make a pixmap big enough to cover the destination but with the aspect * ratio of the cs_pixmap */ big_width = trim_side ? height * cs_width / cs_height : width; big_height = trim_side ? height : width * cs_height / cs_width; big_pixmap = CreateStretchPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, big_width, big_height, gc); /* work out where to trim */ x = trim_side ? (big_width - width) / 2 : 0; y = trim_side ? 0 : (big_height - height) / 2; pixmap = XCreatePixmap(dpy, cs_pixmap, width, height, depth); if (pixmap && big_pixmap) XCopyArea(dpy, big_pixmap, pixmap, gc, x, y, width, height, 0, 0); if (big_pixmap) XFreePixmap(dpy, big_pixmap); } else if (!cs_stretch_x && !cs_stretch_y) { /* it's a tiled pixmap, create an unstretched one */ if (!is_shape_mask) { pixmap = XCreatePixmap(dpy, cs_pixmap, cs_width, cs_height, depth); if (pixmap) { XCopyArea(dpy, cs_pixmap, pixmap, gc, 0, 0, cs_width, cs_height, 0, 0); } } else { /* can't tile masks, create a tiled version of the mask */ pixmap = CreateTiledPixmap( dpy, cs_pixmap, cs_width, cs_height, width, height, 1, gc); } } else if (!cs_stretch_x) { /* it's an HGradient */ pixmap = CreateStretchYPixmap(dpy, cs_pixmap, cs_width, cs_height, depth, height, gc); } else if (!cs_stretch_y) { /* it's a VGradient */ pixmap = CreateStretchXPixmap(dpy, cs_pixmap, cs_width, cs_height, depth, width, gc); } else { /* It's a full window pixmap */ pixmap = CreateStretchPixmap(dpy, cs_pixmap, cs_width, cs_height, depth, width, height, gc); } return pixmap; }
Pixmap CreateRotatedPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int depth, GC gc, int rotation) { GC my_gc = None; Pixmap pixmap = None; int dest_width, dest_height, i, j; Bool error = False; FImage *fim = NULL; FImage *src_fim = NULL; if (src_width <= 0 || src_height <= 0) { return None; } switch(rotation) { case ROTATION_90: case ROTATION_270: dest_width = src_height; dest_height = src_width; break; case ROTATION_0: case ROTATION_180: dest_width = src_width; dest_height = src_height; break; default: return None; break; } pixmap = XCreatePixmap(dpy, src, dest_width, dest_height, depth); if (pixmap == None) { return None; } if (gc == None) { my_gc = fvwmlib_XCreateGC(dpy, src, 0, 0); } if (rotation == ROTATION_0) { XCopyArea( dpy, src, pixmap, (gc == None)? my_gc:gc, 0, 0, src_width, src_height, 0, 0); goto bail; } if (!(src_fim = FGetFImage( dpy, src, Pvisual, depth, 0, 0, src_width, src_height, AllPlanes, ZPixmap))) { error = True; goto bail; } if (!(fim = FCreateFImage( dpy, Pvisual, depth, ZPixmap, dest_width, dest_height))) { error = True; goto bail; } for (j = 0; j < src_height; j++) { for (i = 0; i < src_width; i++) { switch(rotation) { case ROTATION_270: XPutPixel( fim->im, j, src_width - i - 1, XGetPixel(src_fim->im, i, j)); break; case ROTATION_90: XPutPixel( fim->im, src_height - j - 1, i, XGetPixel(src_fim->im, i, j)); break; case ROTATION_180: XPutPixel( fim->im, src_width - i - 1, src_height - j - 1, XGetPixel(src_fim->im, i, j)); break; default: break; } } } FPutFImage(dpy, pixmap, gc, fim, 0, 0, 0, 0, dest_width, dest_height); bail: if (error && pixmap) { XFreePixmap(dpy,pixmap); pixmap = None; } if (fim) { FDestroyFImage(dpy, fim); } if (src_fim) { FDestroyFImage(dpy, src_fim); } if (my_gc) { XFreeGC(dpy, my_gc); } return pixmap; }
/* Draws a colorset background into the specified rectangle in the target * drawable. */ void SetClippedRectangleBackground( Display *dpy, Window win, int x, int y, int width, int height, XRectangle *clip, colorset_t *colorset, unsigned int depth, GC gc) { GC draw_gc; Pixmap pixmap2; Pixmap pixmap = None; static int last_depth = -1; static GC last_gc = None; XGCValues xgcv; Pixmap clipmask = None; GC clip_gc = None; Bool keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT); Bool stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X) || (colorset->pixmap_type == PIXMAP_STRETCH); Bool stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y) || (colorset->pixmap_type == PIXMAP_STRETCH); int dest_x, dest_y, dest_w, dest_h; if (clip) { dest_x = clip->x; dest_y = clip->y; dest_w = clip->width; dest_h = clip->height; } else { dest_x = x; dest_y = y; dest_w = width; dest_h = height; } if (CSETS_IS_TRANSPARENT_PR_TINT(colorset)) { XClearArea(dpy, win, dest_x, dest_y, dest_w, dest_h, False); PGraphicsTintRectangle( dpy, win, colorset->tint, colorset->tint_percent, win, True, gc, None, None, dest_x, dest_y, dest_w, dest_h); return; } if (CSETS_IS_TRANSPARENT_PR_PURE(colorset)) { XClearArea(dpy, win, dest_x, dest_y, dest_w, dest_h, False); /* don't do anything */ return; } if (CSETS_IS_TRANSPARENT_ROOT(colorset)) { /* FIXME: optimize this ! */ x = y = 0; width = width + dest_x; height = height + dest_y; } /* minimize gc creation by remembering the last requested depth */ if (last_gc != None && depth != last_depth) { XFreeGC(dpy, last_gc); last_gc = None; } if (last_gc == None) { last_gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv); } draw_gc = last_gc; last_depth = depth; if (FHaveShapeExtension && colorset->shape_mask != None) { clipmask = CreateBackgroundPixmap( dpy, 0, width, height, colorset, 1, None, True); if (clipmask) { /* create a GC for clipping */ xgcv.clip_x_origin = x; xgcv.clip_y_origin = y; xgcv.clip_mask = clipmask; clip_gc = fvwmlib_XCreateGC( dpy, win, GCClipXOrigin | GCClipYOrigin | GCClipMask, &xgcv); draw_gc = clip_gc; } } if (!colorset->pixmap) { /* use the bg pixel */ XSetForeground(dpy, draw_gc, colorset->bg); XFillRectangle( dpy, win, draw_gc, dest_x, dest_y, dest_w, dest_h); } else { pixmap = CreateBackgroundPixmap( dpy, win, width, height, colorset, depth, gc, False); if (keep_aspect) { /* nothing to do */ } if (stretch_x || stretch_y) { if (!stretch_x && colorset->width != width) { pixmap2 = CreateStretchXPixmap( dpy, pixmap, colorset->width, height, depth, width, gc); XFreePixmap(dpy, pixmap); pixmap = pixmap2; } if (!stretch_y && colorset->height != height) { pixmap2 = CreateStretchYPixmap( dpy, pixmap, width, colorset->height, depth, height, gc); XFreePixmap(dpy, pixmap); pixmap = pixmap2; } } else { pixmap2 = CreateTiledPixmap( dpy, pixmap, colorset->width, colorset->height, width, height, depth, gc); XFreePixmap(dpy, pixmap); pixmap = pixmap2; } if (pixmap) { /* Copy the pixmap into the rectangle. */ XCopyArea( dpy, pixmap, win, draw_gc, dest_x - x, dest_y - y, dest_w, dest_h, dest_x, dest_y); XFreePixmap(dpy, pixmap); } } if (FHaveShapeExtension) { if (clipmask != None) { XFreePixmap(dpy, clipmask); } if (clip_gc != None) { XFreeGC(dpy, clip_gc); } } return; }
int SetRootWindow(char *tline) { Pixmap shapeMask = None, temp_pix = None, alpha = None; int w, h; int depth; int nalloc_pixels = 0; Pixel *alloc_pixels = NULL; char *file_path; FvwmPictureAttributes fpa; if (use_our_color_limit) { PictureColorLimitOption colorLimitop = {-1, -1, -1, -1, -1}; colorLimitop.color_limit = opt_color_limit; PictureInitCMapRoot( dpy, !NoColorLimit, &colorLimitop, True, True); } else { /* this use the default visual (not the fvwm one) as * getenv("FVWM_VISUALID") is NULL in any case. But this use * the same color limit than fvwm. * This is "broken" when fvwm use depth <= 8 and a private * color map (i.e., fvwm is started with the -visual{ID} * option), because when fvwm use a private color map the * default color limit is 244. There is no way to know here if * getenv("FVWM_VISUALID") !=NULL. * So, in this unfortunate case the user should use the * --color-limit option */ PictureInitCMap(dpy); } flib_init_graphics(dpy); /* try built-in image path first, but not before pwd */ PictureSetImagePath(".:+"); file_path = PictureFindImageFile(tline, NULL, R_OK); if (file_path == NULL) { file_path = tline; } fpa.mask = FPAM_NO_ALLOC_PIXELS | FPAM_NO_ALPHA; if (Pdepth <= 8 && !NoDither) { fpa.mask |= FPAM_DITHER; } else if (Pdepth <= 16 && Dither) { fpa.mask |= FPAM_DITHER; } if (NoColorLimit) { fpa.mask |= FPAM_NO_COLOR_LIMIT; } if (!PImageLoadPixmapFromFile( dpy, root, file_path, &temp_pix, &shapeMask, &alpha, &w, &h, &depth, &nalloc_pixels, &alloc_pixels, 0, fpa)) { fprintf( stderr, "[fvwm-root] failed to load image file '%s'\n", tline); return -1; } if (depth == Pdepth) { rootImage = temp_pix; } else { XGCValues gcv; GC gc; gcv.background= WhitePixel(dpy, screen); gcv.foreground= BlackPixel(dpy, screen); gc = fvwmlib_XCreateGC( dpy, root, GCForeground | GCBackground, &gcv); rootImage = XCreatePixmap(dpy, root, w, h, Pdepth); XCopyPlane(dpy, temp_pix, rootImage, gc, 0, 0, w, h, 0, 0, 1); XFreePixmap(dpy, temp_pix); XFreeGC(dpy, gc); } XSetWindowBackgroundPixmap(dpy, root, rootImage); save_colors = 1; XClearWindow(dpy, root); return 0; }
void InitTextField(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int i; int num_chars; /* Enregistrement des couleurs et de la police */ /* colors and fonts */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask=0; Attr.cursor=XCreateFontCursor(dpy,XC_xterm); mask|=CWCursor; /* Curseur pour la fenetre / window cursor */ Attr.background_pixel=xobj->TabColor[back]; mask|=CWBackPixel; xobj->win=XCreateWindow(dpy,*xobj->ParentWin, xobj->x,xobj->y,xobj->width,xobj->height,0, CopyFromParent,InputOutput,CopyFromParent, mask,&Attr); xobj->gc=fvwmlib_XCreateGC(dpy,xobj->win,0,NULL); XSetForeground(dpy,xobj->gc,xobj->TabColor[fore]); if ((xobj->Ffont = FlocaleLoadFont( dpy, xobj->font, ScriptName)) == NULL) { fprintf( stderr, "%s: Couldn't load font. Exiting!\n", ScriptName); exit(1); } if (xobj->Ffont->font != NULL) XSetFont(dpy, xobj->gc, xobj->Ffont->font->fid); XSetLineAttributes(dpy,xobj->gc,1,LineSolid,CapRound,JoinMiter); /* value2 représente la fin de la zone selectionnee */ /* value2 gives the end of the selected zone */ /* calculate number of characters in title */ num_chars = FlocaleStringCharLength(xobj->Ffont, xobj->title); if (xobj->value > num_chars) xobj->value = num_chars; xobj->value2=xobj->value; /* left position of the visible title */ xobj->value3=0; /* Redimensionnement du widget */ /* widget resizing */ xobj->height= xobj->Ffont->height + 10; i = FlocaleTextWidth(xobj->Ffont,xobj->title,strlen(xobj->title))+40; if (xobj->width<i) xobj->width=i; XResizeWindow(dpy,xobj->win,xobj->width,xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSelectInput(dpy, xobj->win, ExposureMask); }
/* * Fonction pour PushButton */ void InitPushButton(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int i; char *str; /* Enregistrement des couleurs et de la police */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask = 0; Attr.cursor = XCreateFontCursor(dpy, XC_hand2); mask |= CWCursor; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; /* Epaisseur de la fenetre = 0 */ xobj->win = XCreateWindow( dpy, *xobj->ParentWin, xobj->x, xobj->y, xobj->width, xobj->height, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &Attr); xobj->gc = fvwmlib_XCreateGC(dpy, xobj->win, 0, NULL); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); if ((xobj->Ffont = FlocaleLoadFont( dpy, xobj->font, ScriptName)) == NULL) { fprintf( stderr, "%s: Couldn't load font. Exiting!\n", ScriptName); exit(1); } if (xobj->Ffont->font != NULL) XSetFont(dpy, xobj->gc, xobj->Ffont->font->fid); XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter); /* Redimensionnement du widget */ str = (char*)GetMenuTitle(xobj->title, 1); if (xobj->icon == NULL) { i = xobj->Ffont->height + 12; if (xobj->height < i) xobj->height = i; i = FlocaleTextWidth(xobj->Ffont, str, strlen(str)) + 16; if (xobj->width < i) xobj->width = i; } else if (strlen(str) == 0) { if (xobj->height < xobj->icon_h + 10) xobj->height = xobj->icon_h + 10; if (xobj->width < xobj->icon_w + 10) xobj->width = xobj->icon_w + 10; } else { if (xobj->icon_w + 10 > FlocaleTextWidth( xobj->Ffont, str, strlen(str)) + 16) i = xobj->icon_w + 10; else i = FlocaleTextWidth( xobj->Ffont, str, strlen(str)) + 16; if (xobj->width < i) xobj->width = i; i = xobj->icon_h+ 2 * (xobj->Ffont->height + 10); if (xobj->height < i) xobj->height = i; } XResizeWindow(dpy, xobj->win, xobj->width, xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); xobj->value3 = CountOption(xobj->title); XSelectInput(dpy, xobj->win, ExposureMask); }
void InitVScrollBar(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int i,j; char str[20]; int asc,desc,dir; XCharStruct struc; #ifdef I18N_MB char **ml; XFontStruct **fs_list; #endif /* Enregistrement des couleurs et de la police */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask = 0; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; Attr.cursor = XCreateFontCursor(dpy,XC_hand2); mask |= CWCursor; /* Curseur pour la fenetre */ xobj->win = XCreateWindow(dpy, *xobj->ParentWin, xobj->x, xobj->y, xobj->width, xobj->height, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &Attr); xobj->gc = fvwmlib_XCreateGC(dpy, xobj->win, 0, NULL); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); #ifdef I18N_MB if ((xobj->xfontset = GetFontSetOrFixed(dpy,xobj->font)) == NULL) { fprintf(stderr, "FvwmScript: Couldn't load font. Exiting!\n"); exit(1); } XFontsOfFontSet(xobj->xfontset, &fs_list, &ml); xobj->xfont = fs_list[0]; #else if ((xobj->xfont = GetFontOrFixed(dpy,xobj->font)) == NULL) { fprintf(stderr, "FvwmScript: Couldn't load font. Exiting!\n"); exit(1); } #endif XSetFont(dpy, xobj->gc, xobj->xfont->fid); XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter); if ((xobj->value3 - xobj->value2) <= 0) xobj->value3 = xobj->value2 + 10; if (!((xobj->value >= xobj->value2) && (xobj->value <= xobj->value3))) xobj->value = xobj->value2; XTextExtents(xobj->xfont, "lp", strlen("lp"), &dir, &asc, &desc, &struc); i = (asc+desc)*2+30; if (xobj->height < i) xobj->height = i; sprintf(str, "%d", xobj->value2); i = XTextWidth(xobj->xfont, str, strlen(str)); sprintf(str, "%d", xobj->value3); j = XTextWidth(xobj->xfont, str, strlen(str)); if (i<j) i = j*2+30; else i = i*2+30; xobj->width = i; XResizeWindow(dpy, xobj->win, xobj->width, xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSelectInput(dpy, xobj->win, ExposureMask); }
int FRenderRender( Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha, int depth, int added_alpha_percent, Pixel tint, int tint_percent, Drawable d, GC gc, GC alpha_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h, Bool do_repeat) { FRenderColor frc; Pixmap pixmap_copy = None; Pixmap alpha_copy = None; FRenderPicture shade_picture = None; FRenderPicture alpha_picture = None; FRenderPicture mask_picture = None; FRenderPicture src_picture = None; FRenderPicture dest_picture = None; FRenderPicture root_picture = None; FRenderPictureAttributes pa; unsigned long pam = 0; int alpha_x = src_x; int alpha_y = src_y; Bool rv = False; Bool free_alpha_gc = False; if (!XRenderSupport || !FRenderGetExtensionSupported()) { return 0; } if (!FRenderVisualInitialized) { FRenderVisualInitialized = True; FRenderVisualInit(dpy); } if (!PFrenderVisualFormat || !PFrenderAlphaFormat || !PFrenderAbsoluteFormat || !PFrenderMaskFormat) { return 0; } /* it is a bitmap ? */ if (Pdepth != depth && pixmap) { pixmap_copy = PictureBitmapToPixmap( dpy, win, pixmap, Pdepth, gc, src_x, src_y, src_w, src_h); src_x = src_y = 0; } pam = FRenderCPRepeat; if (do_repeat) { pa.repeat = True; } else { pa.repeat = False; } /* * build the src_picture */ if (pixmap == ParentRelative) { /* need backing store and good preparation of the win */ if (gc == None) { gc = PictureDefaultGC(dpy, win); } pixmap_copy = XCreatePixmap(dpy, win, src_w, src_h, Pdepth); if (pixmap_copy && gc) { XCopyArea( dpy, win, pixmap_copy, gc, src_x, src_y, src_w, src_h, 0, 0); } src_x = src_y = 0; } else if (tint_percent > 0 && !pixmap_copy) { if (gc == None) { gc = PictureDefaultGC(dpy, win); } pixmap_copy = XCreatePixmap(dpy, win, src_w, src_h, Pdepth); if (pixmap_copy && gc) { XCopyArea( dpy, pixmap, pixmap_copy, gc, src_x, src_y, src_w, src_h, 0, 0); } src_x = src_y = 0; } else if (!pixmap_copy) { SUPPRESS_UNUSED_VAR_WARNING(pa); SUPPRESS_UNUSED_VAR_WARNING(pam); src_picture = FRenderCreatePicture( dpy, pixmap, PFrenderVisualFormat, pam, &pa); } if (!src_picture && pixmap_copy) { src_picture = FRenderCreatePicture( dpy, pixmap_copy, PFrenderVisualFormat, pam, &pa); } if (!src_picture) { goto bail; } /* tint the src, it is why we have done a pixmap copy */ if (tint_percent > 0) { FRenderTintPicture( dpy, win, tint, tint_percent, src_picture, src_x, src_y, src_w, src_h); } if (added_alpha_percent >= 100) { if (alpha != None) { alpha_picture = FRenderCreatePicture( dpy, alpha, PFrenderAlphaFormat, pam, &pa); } else if (mask != None) { alpha_picture = FRenderCreatePicture( dpy, mask, PFrenderMaskFormat, pam, &pa); } else { /* fix a bug in certain XRender server implementation? */ if (!(shade_picture = FRenderCreateShadePicture( dpy, win, 100))) { goto bail; } alpha_x = alpha_y = 0; } } else { if (alpha != None) { alpha_copy = XCreatePixmap(dpy, win, src_w, src_h, 8); if (!alpha_gc) { alpha_gc = fvwmlib_XCreateGC( dpy, alpha, 0, NULL); free_alpha_gc = True; } if (alpha_copy && alpha_gc) { XCopyArea(dpy, alpha, alpha_copy, alpha_gc, alpha_x, alpha_y, src_w, src_h, 0, 0); alpha_picture = FRenderCreatePicture( dpy, alpha_copy, PFrenderAlphaFormat, pam, &pa); } if (alpha_gc && free_alpha_gc) { XFreeGC(dpy, alpha_gc); } alpha_x = alpha_y = 0; } else if (mask != None) { alpha_copy = XCreatePixmap(dpy, win, src_w, src_h, 8); if (alpha_copy) { alpha_picture = FRenderCreatePicture( dpy, alpha_copy, PFrenderAlphaFormat, pam, &pa); } if (alpha_picture) { frc.red = frc.green = frc.blue = frc.alpha = 0; FRenderFillRectangle( dpy, FRenderPictOpSrc, alpha_picture, &frc, 0, 0, src_w, src_h); } mask_picture = FRenderCreatePicture( dpy, mask, PFrenderMaskFormat, pam, &pa); } else { alpha_x = alpha_y = 0; } if (!(shade_picture = FRenderCreateShadePicture( dpy, win, added_alpha_percent))) { goto bail; } if (alpha != None && alpha_picture && shade_picture) { if (!FRenderCompositeAndCheck( dpy, FRenderPictOpAtopReverse, shade_picture, alpha_picture, alpha_picture, 0, 0, alpha_x, alpha_y, 0, 0, src_w, src_h)) { goto bail; } alpha_x = alpha_y = 0; } else if (mask != None && alpha_picture && shade_picture) { if (!FRenderCompositeAndCheck( dpy, FRenderPictOpAtopReverse, shade_picture, mask_picture, alpha_picture, 0, 0, alpha_x, alpha_y, 0, 0, src_w, src_h)) { goto bail; } alpha_x = alpha_y = 0; } } if (alpha_picture == None) { alpha_picture = shade_picture; } dest_picture = FRenderCreatePicture( dpy, d, PFrenderVisualFormat, 0, &pa); if (dest_picture) { rv = FRenderCompositeAndCheck( dpy, FRenderPictOpOver, src_picture, alpha_picture, dest_picture, src_x, src_y, alpha_x, alpha_y, dest_x, dest_y, dest_w, dest_h); } bail: if (dest_picture) { FRenderFreePicture(dpy, dest_picture); } if (src_picture) { FRenderFreePicture(dpy, src_picture); } if (alpha_picture && alpha_picture != shade_picture) { FRenderFreePicture(dpy, alpha_picture); } if (mask_picture) { FRenderFreePicture(dpy, mask_picture); } if (root_picture) { FRenderFreePicture(dpy, root_picture); } if (alpha_copy) { XFreePixmap(dpy, alpha_copy); } if (pixmap_copy) { XFreePixmap(dpy, pixmap_copy); } return rv; }
void InitVScrollBar(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int i,j; char str[20]; /* Enregistrement des couleurs et de la police */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask = 0; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; Attr.cursor = XCreateFontCursor(dpy,XC_hand2); mask |= CWCursor; /* Curseur pour la fenetre */ xobj->win = XCreateWindow( dpy, *xobj->ParentWin, xobj->x, xobj->y, xobj->width, xobj->height, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &Attr); xobj->gc = fvwmlib_XCreateGC(dpy, xobj->win, 0, NULL); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); if ((xobj->Ffont = FlocaleLoadFont(dpy, xobj->font, ScriptName)) == NULL) { fprintf( stderr, "%s: Couldn't load font. Exiting!\n", ScriptName); exit(1); } if (xobj->Ffont->font != NULL) XSetFont(dpy, xobj->gc, xobj->Ffont->font->fid); XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter); if ((xobj->value3 - xobj->value2) <= 0) xobj->value3 = xobj->value2 + 10; if (!((xobj->value >= xobj->value2) && (xobj->value <= xobj->value3))) xobj->value = xobj->value2; i = (xobj->Ffont->height)*2+30; if (xobj->height < i) xobj->height = i; sprintf(str, "%d", xobj->value2); i = FlocaleTextWidth(xobj->Ffont, str, strlen(str)); sprintf(str, "%d", xobj->value3); j = FlocaleTextWidth(xobj->Ffont, str, strlen(str)); if (i<j) i = j*2+30; else i = i*2+30; xobj->width = i; XResizeWindow(dpy, xobj->win, xobj->width, xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSelectInput(dpy, xobj->win, ExposureMask); }
void InitItemDraw(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int minHeight,minWidth; int asc,desc,dir; XCharStruct struc; #ifdef I18N_MB char **ml; XFontStruct **fs_list; #endif /* Enregistrement des couleurs et de la police */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } Attr.background_pixel = xobj->TabColor[back]; mask = CWBackPixel; xobj->win = XCreateWindow(dpy, *xobj->ParentWin, xobj->x, xobj->y, xobj->width, xobj->height, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &Attr); xobj->gc = fvwmlib_XCreateGC(dpy, xobj->win, 0, NULL); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); #ifdef I18N_MB if ((xobj->xfontset = GetFontSetOrFixed(dpy,xobj->font)) == NULL) { fprintf(stderr, "FvwmScript: Couldn't load font. Exiting!\n"); exit(1); } XFontsOfFontSet(xobj->xfontset, &fs_list, &ml); xobj->xfont = fs_list[0]; #else if ((xobj->xfont = GetFontOrFixed(dpy, xobj->font)) == NULL) { fprintf(stderr, "FvwmScript: Couldn't load font. Exiting!\n"); exit(1); } #endif XSetFont(dpy, xobj->gc, xobj->xfont->fid); XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter); /* Redimensionnement du widget */ if (strlen(xobj->title) != 0) XTextExtents(xobj->xfont, "lp", strlen("lp"), &dir, &asc, &desc, &struc); else { asc = 0; desc = 0; } if (xobj->icon == NULL) { if (strlen(xobj->title) != 0) { /* title but no icon */ minHeight = asc+desc+2; minWidth = XTextWidth(xobj->xfont, xobj->title, strlen(xobj->title))+2; if (xobj->height < minHeight) xobj->height = minHeight; if (xobj->width < minWidth) xobj->width = minWidth; } } else if (strlen(xobj->title)==0) { /* icon but no title */ if (xobj->height<xobj->icon_h) xobj->height = xobj->icon_h; if (xobj->width<xobj->icon_w) xobj->width = xobj->icon_w; } else { /* title and icon */ if (xobj->icon_w>XTextWidth(xobj->xfont, xobj->title, strlen(xobj->title))+2) { /* icon is wider than the title */ if (xobj->width<xobj->icon_w) xobj->width = xobj->icon_w; } else { /* title is wider than icon */ if (xobj->width < XTextWidth(xobj->xfont, xobj->title, strlen(xobj->title)) + 2) xobj->width = XTextWidth(xobj->xfont, xobj->title, strlen(xobj->title))+2; } xobj->height = xobj->icon_h+asc+desc+2; } XResizeWindow(dpy, xobj->win, xobj->width, xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSelectInput(dpy, xobj->win, ExposureMask); /* x and y value of a clic */ xobj->value2 = -1; xobj->value3 = -1; }
void InitCheckBox(struct XObj *xobj) { unsigned long mask; XSetWindowAttributes Attr; int asc,desc,dir; XCharStruct struc; #ifdef I18N_MB char **ml; XFontStruct **fs_list; #endif /* Enregistrement des couleurs et de la police / fonts and colors */ if (xobj->colorset >= 0) { xobj->TabColor[fore] = Colorset[xobj->colorset].fg; xobj->TabColor[back] = Colorset[xobj->colorset].bg; xobj->TabColor[hili] = Colorset[xobj->colorset].hilite; xobj->TabColor[shad] = Colorset[xobj->colorset].shadow; } else { xobj->TabColor[fore] = GetColor(xobj->forecolor); xobj->TabColor[back] = GetColor(xobj->backcolor); xobj->TabColor[hili] = GetColor(xobj->hilicolor); xobj->TabColor[shad] = GetColor(xobj->shadcolor); } mask = 0; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; Attr.cursor = XCreateFontCursor(dpy,XC_hand2); mask |= CWCursor; /* Curseur pour la fenetre / Cursor for the window */ xobj->win = XCreateWindow(dpy, *xobj->ParentWin, xobj->x, xobj->y, xobj->width, xobj->height,0, CopyFromParent, InputOutput, CopyFromParent, mask, &Attr); xobj->gc = fvwmlib_XCreateGC(dpy,xobj->win,0,NULL); XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]); #ifdef I18N_MB if ((xobj->xfontset = GetFontSetOrFixed(dpy,xobj->font)) == NULL) { fprintf(stderr, "FvwmScript: Couldn't load font. Exiting!\n"); exit(1); } XFontsOfFontSet(xobj->xfontset,&fs_list,&ml); xobj->xfont = fs_list[0]; #else if ((xobj->xfont = GetFontOrFixed(dpy,xobj->font)) == NULL) { fprintf(stderr, "FvwmScript: Couldn't load font. Exiting!\n"); exit(1); } #endif XSetFont(dpy, xobj->gc, xobj->xfont->fid); XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter); /* Redimensionnement du widget / resize the widget */ XTextExtents(xobj->xfont, "lp", strlen("lp"), &dir, &asc, &desc, &struc); xobj->height = asc+desc+5; xobj->width = XTextWidth(xobj->xfont, xobj->title, strlen(xobj->title)) + 30; XResizeWindow(dpy, xobj->win, xobj->width, xobj->height); if (xobj->colorset >= 0) SetWindowBackground(dpy, xobj->win, xobj->width, xobj->height, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XSelectInput(dpy, xobj->win, ExposureMask); }
/* create a pixmap suitable for plonking on the background of a part of a * window */ Pixmap CreateOffsetBackgroundPixmap( Display *dpy, Window win, int x, int y, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool is_shape_mask) { Pixmap pixmap = None; Pixmap cs_pixmap = None; XGCValues xgcv; static GC shape_gc = None; GC fill_gc = None; /* not static as dpy may change (FvwmBacker) */ int cs_width; int cs_height; Bool cs_keep_aspect; Bool cs_stretch_x; Bool cs_stretch_y; if (colorset->pixmap == ParentRelative && !is_shape_mask && colorset->tint_percent > 0) { FvwmRenderAttributes fra; fra.mask = FRAM_DEST_IS_A_WINDOW | FRAM_HAVE_TINT; fra.tint = colorset->tint; fra.tint_percent = colorset->tint_percent; MyXGrabServer(dpy); pixmap = PGraphicsCreateTransparency( dpy, win, &fra, gc, x, y, width, height, True); MyXUngrabServer(dpy); if (pixmap == None) { return ParentRelative; } return pixmap; } else if (colorset->pixmap == ParentRelative && !is_shape_mask) { return ParentRelative; } else if (CSETS_IS_TRANSPARENT_ROOT(colorset) && colorset->pixmap && !is_shape_mask) { int sx,sy; int h,w; XID dummy; cs_pixmap = colorset->pixmap; cs_width = colorset->width; cs_height = colorset->height; if (CSETS_IS_TRANSPARENT_ROOT_PURE(colorset)) { /* check if it is still here */ union { XID junk; unsigned int ui_junk; int i_junk; } XID_int; /* a priori we should grab the server, but this * cause PositiveWrite error when you move a * window with a transparent title bar */ if (!XGetGeometry( dpy, colorset->pixmap, &XID_int.junk, &XID_int.i_junk, &XID_int.i_junk, (unsigned int *)&w, (unsigned int *)&h, &XID_int.ui_junk, &XID_int.ui_junk) || w != cs_width || h != cs_height) { return None; } } XTranslateCoordinates( dpy, win, DefaultRootWindow(dpy), x, y, &sx, &sy, &dummy); pixmap = XCreatePixmap(dpy, win, width, height, Pdepth); if (!pixmap) { return None; } /* make sx and sy positif */ while (sx < 0) { sx = sx + cs_width; } while (sy < 0) { sy = sy + cs_height; } /* make sx and sy in (0,0,cs_width,cs_height) */ while (sx >= cs_width) { sx = sx - cs_width; } while (sy >= cs_height) { sy = sy - cs_height; } xgcv.fill_style = FillTiled; xgcv.tile = cs_pixmap; xgcv.ts_x_origin = cs_width-sx; xgcv.ts_y_origin = cs_height-sy; fill_gc = fvwmlib_XCreateGC( dpy, win, GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle, &xgcv); if (fill_gc == None) { XFreePixmap(dpy, pixmap); return None; } XSync(dpy, False); is_bad_gc = 0; ferror_set_temp_error_handler(BadGCErrorHandler); XFillRectangle(dpy, pixmap, fill_gc, 0, 0, width, height); if ( is_bad_gc == 0 && CSETS_IS_TRANSPARENT_ROOT_PURE(colorset) && colorset->tint_percent > 0) { FvwmRenderAttributes fra; fra.mask = FRAM_HAVE_TINT; fra.tint = colorset->tint; fra.tint_percent = colorset->tint_percent; PGraphicsRenderPixmaps( dpy, win, pixmap, None, None, Pdepth, &fra, pixmap, fill_gc, None, None, 0, 0, width, height, 0, 0, width, height, False); } XSync(dpy, False); ferror_reset_temp_error_handler(); if (is_bad_gc == 1) { is_bad_gc = 0; XFreePixmap(dpy, pixmap); pixmap = None; } XFreeGC(dpy,fill_gc); return pixmap; } if (!is_shape_mask) { cs_pixmap = colorset->pixmap; cs_width = colorset->width; cs_height = colorset->height; cs_keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT); cs_stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X) || (colorset->pixmap_type == PIXMAP_STRETCH); cs_stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y) || (colorset->pixmap_type == PIXMAP_STRETCH); } else { /* In spite of the name, win contains the pixmap */ cs_pixmap = colorset->shape_mask; win = colorset->shape_mask; if (shape_gc == None) { xgcv.foreground = 1; xgcv.background = 0; /* create a gc for 1 bit depth */ shape_gc = fvwmlib_XCreateGC( dpy, win, GCForeground|GCBackground, &xgcv); } gc = shape_gc; cs_width = colorset->shape_width; cs_height = colorset->shape_height; cs_keep_aspect = (colorset->shape_type == SHAPE_STRETCH_ASPECT); cs_stretch_x = !(colorset->shape_type == SHAPE_TILED); cs_stretch_y = !(colorset->shape_type == SHAPE_TILED); } if (cs_pixmap == None) { xgcv.foreground = colorset->bg; fill_gc = fvwmlib_XCreateGC(dpy, win, GCForeground, &xgcv); /* create a solid pixmap - not very useful most of the time */ pixmap = XCreatePixmap(dpy, win, 1, 1, depth); XFillRectangle(dpy, pixmap, fill_gc, 0, 0, 1, 1); XFreeGC(dpy,fill_gc); } else if (cs_keep_aspect) { Bool trim_side; int big_width, big_height; Pixmap big_pixmap; int x, y; /* make a pixmap big enough to cover the destination but with * the aspect ratio of the cs_pixmap */ trim_side = get_aspect_dimensions( &big_width, &big_height, width, height, cs_width, cs_height); big_pixmap = CreateStretchPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, big_width, big_height, gc); /* work out where to trim */ x = trim_side ? (big_width - width) / 2 : 0; y = trim_side ? 0 : (big_height - height) / 2; pixmap = XCreatePixmap(dpy, cs_pixmap, width, height, depth); if (pixmap && big_pixmap) { XCopyArea( dpy, big_pixmap, pixmap, gc, x, y, width, height, 0, 0); } if (big_pixmap) { XFreePixmap(dpy, big_pixmap); } } else if (!cs_stretch_x && !cs_stretch_y) { /* it's a tiled pixmap, create an unstretched one */ if (!is_shape_mask) { pixmap = XCreatePixmap( dpy, cs_pixmap, cs_width, cs_height, depth); if (pixmap) { XCopyArea( dpy, cs_pixmap, pixmap, gc, 0, 0, cs_width, cs_height, 0, 0); } } else { /* can't tile masks, create a tiled version of the * mask */ pixmap = CreateTiledPixmap( dpy, cs_pixmap, cs_width, cs_height, width, height, 1, gc); } } else if (!cs_stretch_x) { /* it's an HGradient */ pixmap = CreateStretchYPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, height, gc); } else if (!cs_stretch_y) { /* it's a VGradient */ pixmap = CreateStretchXPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, width, gc); } else { /* It's a full window pixmap */ pixmap = CreateStretchPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, width, height, gc); } if (x != 0 || y != 0) { Pixmap p2; p2 = ScrollPixmap( dpy, pixmap, gc, x, y, width, height, depth); if (p2 != None && p2 != ParentRelative && p2 != pixmap) { XFreePixmap(dpy, pixmap); pixmap = p2; } } return pixmap; }
int DrawDegradeRelief(Display *dpy, Drawable d, int x, int y, int w, int h, int from[3], int to[3], int relief, int maxcols) { int i = 0,j,k; int dr, dg, db; /* delta */ int dmax, dmax2; GC gc, gc2; XGCValues gcv; int px, py, pd; unsigned long lightcolor, darkcolor; int alloc_relief; unsigned long *colors; float c1,s1; if (w <= 0 || h <= 0) return 0; gcv.foreground = 1; gc = fvwmlib_XCreateGC(dpy, d, GCForeground, &gcv); gc2 = fvwmlib_XCreateGC(dpy, d, GCForeground, &gcv); dr = to[0] - from[0]; dg = to[1] - from[1]; db = to[2] - from[2]; dmax = abs(dr); dmax2 = dr; if (dmax < abs(dg)) { dmax = abs(dg); dmax2 = dg; } if (dmax < abs(db)) { dmax = abs(db); dmax2 = db; } /* if colors from and to are the same, force to one color */ if (dmax==0) dmax=1; if (relief!=0) { if (maxcols>4) { alloc_relief=1; maxcols -= 2; /* reserve two colors for the relief */ } else { alloc_relief=0; } } else alloc_relief = 0; if (dmax < maxcols) { maxcols = dmax; /* we need less colors than we expected */ } colors = malloc(sizeof(unsigned long)*maxcols); /* alloc colors */ if (!MakeColors(dpy, d, from, to, maxcols, colors, &darkcolor, &lightcolor, dr, dg, db, alloc_relief, dmax2>0)) return 0; /* display it */ s1 = (float)(maxcols)/((float)w*2.0); pd = relief==0 ? 0 : 1; for(py = pd; py < h-pd; py++) { c1 = ((float)maxcols/2.0)*((float)py/(float)((h-pd*2)-1)); j = -1; k=pd+x; for(px = pd+x; px < w-pd+x; px++) { i = (int)c1; if (i>=maxcols) i=maxcols-1; if (j != colors[i]) { j = colors[i]; XSetForeground(dpy, gc, j); XDrawLine(dpy, d, gc, k, y+py, px, y+py); k=px; } c1+=s1; } XSetForeground(dpy, gc, colors[i]); XDrawLine(dpy, d, gc, k, y+py, w-pd+x, y+py); } /* draw borders */ if (relief != 0) { if (relief>0) { XSetForeground(dpy, gc, lightcolor); XSetForeground(dpy, gc2, darkcolor); } else { XSetForeground(dpy, gc, darkcolor); XSetForeground(dpy, gc2, lightcolor); } XDrawLine(dpy, d, gc, x, y, x, y+h-1); XDrawLine(dpy, d, gc, x, y, x+w-1, y); XDrawLine(dpy, d, gc2, x, y+h-1, x+w-1, y+h-1); XDrawLine(dpy, d, gc2, x+w-1, y, x+w-1, y+h-1); } XFreeGC(dpy,gc); XFreeGC(dpy,gc2); free(colors); return 1; }
void SetDeskPageBackground(const Command *c) { Display *dpy2 = NULL; Window root2 = None; int screen2; Pixmap pix = None; current_colorset = -1; /* FvwmBacker bg preperation */ switch (c->type) { case 1: /* solid colors */ case 2: /* colorset */ dpy2 = XOpenDisplay(displayName); if (!dpy2) { fvwm_msg(ERR, "FvwmBacker", "Fail to create a forking dpy, Exit!"); exit(2); } screen2 = DefaultScreen(dpy2); root2 = RootWindow(dpy2, screen2); if (RetainPixmap) { XSetCloseDownMode(dpy2, RetainPermanent); } XGrabServer(dpy2); DeleteRootAtoms(dpy2, root2); switch (c->type) { case 2: current_colorset = c->colorset; /* Process a colorset */ if (CSET_IS_TRANSPARENT(c->colorset)) { fvwm_msg(ERR,"FvwmBacker", "You cannot " "use a transparent colorset as " "background!"); XUngrabServer(dpy2); XCloseDisplay(dpy2); return; } else if (Pdepth != DefaultDepth(dpy2, screen2)) { fvwm_msg(ERR,"FvwmBacker", "You cannot " "use a colorset background if\n" "the fvwm depth is not equal " "to the root depth!"); XUngrabServer(dpy2); XCloseDisplay(dpy2); return; } else if (RetainPixmap) { pix = CreateBackgroundPixmap( dpy2, root2, MyDisplayWidth, MyDisplayHeight, &Colorset[c->colorset], DefaultDepth(dpy2, screen2), DefaultGC(dpy2, screen2), False); if (pix != None) { XSetWindowBackgroundPixmap( dpy2, root2, pix); XClearWindow(dpy2, root2); } } else { SetWindowBackground( dpy2, root2, MyDisplayWidth, MyDisplayHeight, &Colorset[c->colorset], DefaultDepth(dpy2, screen2), DefaultGC(dpy2, screen2), True); } break; case 1: /* Process a solid color request */ if (RetainPixmap) { GC gc; XGCValues xgcv; xgcv.foreground = c->solidColor; gc = fvwmlib_XCreateGC( dpy2, root2, GCForeground, &xgcv); pix = XCreatePixmap( dpy2, root2, 1, 1, DefaultDepth(dpy2, screen2)); XFillRectangle( dpy2, pix, gc, 0, 0, 1, 1); XFreeGC(dpy2, gc); } XSetWindowBackground(dpy2, root2, c->solidColor); XClearWindow(dpy2, root2); break; } SetRootAtoms(dpy2, root2, pix); XUngrabServer(dpy2); XCloseDisplay(dpy2); /* this XSync, Ungrab, ...etc */ break; case -1: case 0: default: if(c->cmdStr != NULL) { SendFvwmPipe(fvwm_fd, c->cmdStr, (unsigned long)0); } break; } }
/* * Draws a vertical gradient * * from: r,g,b values of left color * to: r,g,b values of right color * relief: relief to add to the borders. 0=flat, >0 raised, <0 sunken * maxcols: max colors to use * type: gradient type. 0 for one-way, != 0 for cilindrical * * aborts and returns 0 on error. */ int DrawVGradient(Display *dpy, Drawable d, int x, int y, int w, int h, int from[3], int to[3], int relief, int maxcols, int type) { int i,j; XGCValues gcv; GC gc, gc2; int dr,dg,db; float s,c; int dmax; unsigned long *colors, lightcolor, darkcolor; int px,pd; int alloc_relief; if (w <= 1 || h <= 1) return 0; gcv.foreground = 1; gc = fvwmlib_XCreateGC(dpy, d, GCForeground, &gcv); gc2 = fvwmlib_XCreateGC(dpy, d, GCForeground, &gcv); dr = to[0] - from[0]; dg = to[1] - from[1]; db = to[2] - from[2]; dmax = dr; if (abs(dmax) < abs(dg)) { dmax = dg; } if (abs(dmax) < abs(db)) { dmax = db; } if (relief!=0) { if (maxcols>4) { alloc_relief=1; maxcols -= 2; /* reserve two colors for the relief */ } else { alloc_relief=0; } } else alloc_relief=0; if (type) { if (w/2 < maxcols) { maxcols = w/2; /* we need less colors than we expected */ } } else { if (w < maxcols) { maxcols = w; /* we need less colors than we expected */ } } /* alloc colors */ colors=malloc(maxcols*sizeof(unsigned long)); if (!MakeColors(dpy, d, from, to, maxcols, colors, &darkcolor, &lightcolor, dr, dg, db, alloc_relief, dmax>0)) return 0; /* display it */ if (type) { s = ((float)maxcols*2)/(float)w; } else { s = (float)maxcols/(float)w; } pd = relief==0 ? 0 : 1; c=0; j=-1; if (type==0) { /* one-way */ for(px = pd; px < w-pd; px++) { i=(int)c; if (i>=maxcols) i=maxcols-1; if (j != i) { XSetForeground(dpy, gc, colors[i]); } XDrawLine(dpy, d, gc, x+px, y+pd, x+px, y+h-pd-1); j = i; c += s; } } else { /* cylindrical */ for(px = pd; px < w-pd; px++) { i=(int)c; if (i>=maxcols) i=maxcols-1; if (j != i) { XSetForeground(dpy, gc, colors[i]); } XDrawLine(dpy, d, gc, x+px, y+pd, x+px, y+h-pd-1); j = i; if (px == w/2) s = -s; c += s; } } /* draw borders */ if (relief != 0) { if (relief>0) { XSetForeground(dpy, gc, lightcolor); XSetForeground(dpy, gc2, darkcolor); } else { XSetForeground(dpy, gc, darkcolor); XSetForeground(dpy, gc2, lightcolor); } XDrawLine(dpy, d, gc, x, y, x, y+h-1); XDrawLine(dpy, d, gc, x, y, x+w-1, y); XDrawLine(dpy, d, gc2, x, y+h-1, x+w-1, y+h-1); XDrawLine(dpy, d, gc2, x+w-1, y, x+w-1, y+h-1); } XFreeGC(dpy,gc); XFreeGC(dpy,gc2); free(colors); return 1; }