/* * Copyright (C) 2000-2005 Carsten Haitzler, Geoff Harrison and various contributors * Copyright (C) 2004-2005 Kim Woelders * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies of the Software, its documentation and marketing & publicity * materials, and acknowledgment shall be given in the documentation, materials * and software packages that this Software was used. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include "E.h" typedef struct { char *file; char *real_file; Imlib_Image *im; char keep_aspect; int xjust, yjust; int xperc, yperc; } BgPart; struct _background { char *name; Pixmap pmap; time_t last_viewed; XColor bg_solid; char bg_tile; BgPart bg; BgPart top; ColorModifierClass *cmclass; char keepim; unsigned int ref_count; }; char * BackgroundGetUniqueString(Background * bg) { char s[256]; const char *chmap = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; int r, g, b; int n1, n2, n3, n4, n5, f1, f2, f3, f4, f5, f6; EGetColor(&(bg->bg_solid), &r, &g, &b); n1 = (r << 24) | (g << 16) | (b << 8) | (bg->bg_tile << 7) | (bg->bg.keep_aspect << 6) | (bg->top.keep_aspect << 5); n2 = (bg->bg.xjust << 16) | (bg->bg.yjust); n3 = (bg->bg.xperc << 16) | (bg->bg.yperc); n4 = (bg->top.xjust << 16) | (bg->top.yjust); n5 = (bg->top.xperc << 16) | (bg->top.yperc); f1 = 0; f2 = 0; f3 = 0; f4 = 0; f5 = 0; f6 = 0; if (bg->bg.file) { char *f; f = ThemeFileFind(bg->bg.file); if (f) { f1 = fileinode(f); f2 = filedev(f); f3 = (int)moddate(f); Efree(f); } } if (bg->top.file) { char *f; f = ThemeFileFind(bg->top.file); if (f) { f4 = fileinode(f); f5 = filedev(f); f6 = (int)moddate(f); Efree(f); } } Esnprintf(s, sizeof(s), "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c", chmap[(n1 >> 0) & 0x3f], chmap[(n1 >> 6) & 0x3f], chmap[(n1 >> 12) & 0x3f], chmap[(n1 >> 18) & 0x3f], chmap[(n1 >> 24) & 0x3f], chmap[(n1 >> 28) & 0x3f], chmap[(n2 >> 0) & 0x3f], chmap[(n2 >> 6) & 0x3f], chmap[(n2 >> 12) & 0x3f], chmap[(n2 >> 18) & 0x3f], chmap[(n2 >> 24) & 0x3f], chmap[(n2 >> 28) & 0x3f], chmap[(n3 >> 0) & 0x3f], chmap[(n3 >> 6) & 0x3f], chmap[(n3 >> 12) & 0x3f], chmap[(n3 >> 18) & 0x3f], chmap[(n3 >> 24) & 0x3f], chmap[(n3 >> 28) & 0x3f], chmap[(n4 >> 0) & 0x3f], chmap[(n4 >> 6) & 0x3f], chmap[(n4 >> 12) & 0x3f], chmap[(n4 >> 18) & 0x3f], chmap[(n4 >> 24) & 0x3f], chmap[(n4 >> 28) & 0x3f], chmap[(n5 >> 0) & 0x3f], chmap[(n5 >> 6) & 0x3f], chmap[(n5 >> 12) & 0x3f], chmap[(n5 >> 18) & 0x3f], chmap[(n5 >> 24) & 0x3f], chmap[(n5 >> 28) & 0x3f], chmap[(f1 >> 0) & 0x3f], chmap[(f1 >> 6) & 0x3f], chmap[(f1 >> 12) & 0x3f], chmap[(f1 >> 18) & 0x3f], chmap[(f1 >> 24) & 0x3f], chmap[(f1 >> 28) & 0x3f], chmap[(f2 >> 0) & 0x3f], chmap[(f2 >> 6) & 0x3f], chmap[(f2 >> 12) & 0x3f], chmap[(f2 >> 18) & 0x3f], chmap[(f2 >> 24) & 0x3f], chmap[(f2 >> 28) & 0x3f], chmap[(f3 >> 0) & 0x3f], chmap[(f3 >> 6) & 0x3f], chmap[(f3 >> 12) & 0x3f], chmap[(f3 >> 18) & 0x3f], chmap[(f3 >> 24) & 0x3f], chmap[(f3 >> 28) & 0x3f], chmap[(f4 >> 0) & 0x3f], chmap[(f4 >> 6) & 0x3f], chmap[(f4 >> 12) & 0x3f], chmap[(f4 >> 18) & 0x3f], chmap[(f4 >> 24) & 0x3f], chmap[(f4 >> 28) & 0x3f], chmap[(f5 >> 0) & 0x3f], chmap[(f5 >> 6) & 0x3f], chmap[(f5 >> 12) & 0x3f], chmap[(f5 >> 18) & 0x3f], chmap[(f5 >> 24) & 0x3f], chmap[(f5 >> 28) & 0x3f], chmap[(f6 >> 0) & 0x3f], chmap[(f6 >> 6) & 0x3f], chmap[(f6 >> 12) & 0x3f], chmap[(f6 >> 18) & 0x3f], chmap[(f6 >> 24) & 0x3f], chmap[(f6 >> 28) & 0x3f]); return Estrdup(s); } void BackgroundPixmapFree(Background * bg) { if (bg && bg->pmap) { imlib_free_pixmap_and_mask(bg->pmap); bg->pmap = 0; } } void BackgroundImagesFree(Background * bg, int free_pmap) { if (bg->bg.im) { imlib_context_set_image(bg->bg.im); imlib_free_image(); bg->bg.im = NULL; } if (bg->top.im) { imlib_context_set_image(bg->top.im); imlib_free_image(); bg->top.im = NULL; } if (free_pmap && bg->pmap) BackgroundPixmapFree(bg); } static void BackgroundImagesKeep(Background * bg, int onoff) { if (onoff) { bg->keepim = 1; } else { bg->keepim = 0; BackgroundImagesFree(bg, 0); } } static void BackgroundImagesRemove(Background * bg) { if (bg->bg.file) Efree(bg->bg.file); bg->bg.file = NULL; if (bg->bg.real_file) Efree(bg->bg.real_file); bg->bg.real_file = NULL; if (bg->top.file) Efree(bg->top.file); bg->top.file = NULL; if (bg->top.real_file) Efree(bg->top.real_file); bg->top.real_file = NULL; BackgroundImagesFree(bg, 1); bg->keepim = 0; } static int BackgroundDestroy(Background * bg) { if (!bg) return -1; if (bg->ref_count > 0) { DialogOK(_("Background Error!"), _("%u references remain\n"), bg->ref_count); return -1; } RemoveItem((char *)bg, 0, LIST_FINDBY_POINTER, LIST_TYPE_BACKGROUND); BackgroundImagesRemove(bg); if (bg->name) Efree(bg->name); Efree(bg); return 0; } static void BackgroundDelete(Background * bg) { char *f; if (BackgroundDestroy(bg)) return; /* And delete the actual image files */ if (bg->bg.file) { f = ThemeFileFind(bg->bg.file); if (f) { E_rm(f); Efree(f); } } if (bg->top.file) { f = ThemeFileFind(bg->top.file); if (f) { E_rm(f); Efree(f); } } } static Background * BackgroundCreate(const char *name, XColor * solid, const char *bgn, char tile, char keep_aspect, int xjust, int yjust, int xperc, int yperc, const char *top, char tkeep_aspect, int txjust, int tyjust, int txperc, int typerc) { Background *bg; bg = Emalloc(sizeof(Background)); if (!bg) return NULL; bg->name = Estrdup(name); bg->pmap = 0; bg->last_viewed = 0; ESetColor(&(bg->bg_solid), 160, 160, 160); if (solid) bg->bg_solid = *solid; bg->bg.file = NULL; if (bgn) bg->bg.file = Estrdup(bgn); bg->bg.real_file = NULL; bg->bg.im = NULL; bg->bg_tile = tile; bg->bg.keep_aspect = keep_aspect; bg->bg.xjust = xjust; bg->bg.yjust = yjust; bg->bg.xperc = xperc; bg->bg.yperc = yperc; bg->top.file = NULL; if (top) bg->top.file = Estrdup(top); bg->top.real_file = NULL; bg->top.im = NULL; bg->top.keep_aspect = tkeep_aspect; bg->top.xjust = txjust; bg->top.yjust = tyjust; bg->top.xperc = txperc; bg->top.yperc = typerc; bg->cmclass = NULL; bg->keepim = 0; bg->ref_count = 0; AddItem(bg, bg->name, 0, LIST_TYPE_BACKGROUND); return bg; } void BackgroundDestroyByName(const char *name) { BackgroundDestroy(FindItem(name, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND)); } static int BackgroundModify(Background * bg, XColor * solid, const char *bgn, char tile, char keep_aspect, int xjust, int yjust, int xperc, int yperc, const char *top, char tkeep_aspect, int txjust, int tyjust, int txperc, int typerc) { int updated = 0; if (solid->red != bg->bg_solid.red) updated = 1; if (solid->green != bg->bg_solid.green) updated = 1; if (solid->blue != bg->bg_solid.blue) updated = 1; bg->bg_solid = *solid; if ((bg->bg.file) && (bgn)) { if (strcmp(bg->bg.file, bgn)) updated = 1; } else updated = 1; if (bg->bg.file) Efree(bg->bg.file); bg->bg.file = (bgn[0]) ? Estrdup(bgn) : NULL; if ((int)tile != bg->bg_tile) updated = 1; if ((int)keep_aspect != bg->bg.keep_aspect) updated = 1; if (xjust != bg->bg.xjust) updated = 1; if (yjust != bg->bg.yjust) updated = 1; if (xperc != bg->bg.xperc) updated = 1; if (yperc != bg->bg.yperc) updated = 1; bg->bg_tile = (char)tile; bg->bg.keep_aspect = (char)keep_aspect; bg->bg.xjust = xjust; bg->bg.yjust = yjust; bg->bg.xperc = xperc; bg->bg.yperc = yperc; if ((bg->top.file) && (top)) { if (strcmp(bg->top.file, top)) updated = 1; } else updated = 1; if (bg->top.file) Efree(bg->top.file); bg->top.file = (top[0]) ? Estrdup(top) : NULL; if ((int)tkeep_aspect != bg->top.keep_aspect) updated = 1; if (txjust != bg->top.xjust) updated = 1; if (tyjust != bg->top.yjust) updated = 1; if (txperc != bg->top.xperc) updated = 1; if (typerc != bg->top.yperc) updated = 1; bg->top.keep_aspect = (char)tkeep_aspect; bg->top.xjust = txjust; bg->top.yjust = tyjust; bg->top.xperc = txperc; bg->top.yperc = typerc; if (updated) { if (bg->pmap) imlib_free_pixmap_and_mask(bg->pmap); bg->pmap = 0; } return updated; } static void BackgroundSetColorMofifier(Background * bg, ColorModifierClass * cm) { cm->ref_count++; bg->cmclass = cm; } static void BgFindImageSize(BgPart * bgp, int rw, int rh, int *pw, int *ph, int setbg) { int w, h; if (bgp->xperc > 0) { w = (rw * bgp->xperc) >> 10; } else { if (!setbg) w = (imlib_image_get_width() * rw) / VRoot.w; else w = imlib_image_get_width(); } if (bgp->yperc > 0) { h = (rh * bgp->yperc) >> 10; } else { if (!setbg) { h = (imlib_image_get_height() * rh) / VRoot.h; } else { h = imlib_image_get_height(); } } if (w <= 0) w = 1; if (h <= 0) h = 1; if (bgp->keep_aspect) { if (bgp->yperc <= 0) { if (((w << 10) / h) != ((imlib_image_get_width() << 10) / imlib_image_get_height())) h = ((w * imlib_image_get_height()) / imlib_image_get_width()); } else { if (((h << 10) / w) != ((imlib_image_get_height() << 10) / imlib_image_get_width())) w = ((h * imlib_image_get_width()) / imlib_image_get_height()); } } *pw = w; *ph = h; } /* * Apply a background to window/pixmap. * * If setbg is != 0, the (scaled) BG pixmap is stored in bg->pmap, otherwise * bg->pmap is left unchanged. */ void BackgroundApply(Background * bg, Window win, int setbg) { unsigned int rw, rh, depth; Pixmap dpmap; GC gc; int rt; if (!WinExists(win)) return; EGetGeometry(win, NULL, NULL, NULL, &rw, &rh, NULL, &depth); imlib_context_set_drawable(win); EAllocColor(&bg->bg_solid); gc = 0; rt = imlib_context_get_dither(); if (Conf.backgrounds.hiquality) { imlib_context_set_dither(1); #if 0 /* ??? */ imlib_context_set_anti_alias(1); #endif } dpmap = (setbg) ? bg->pmap : None; if (!dpmap) { unsigned int w, h, x, y; char hasbg, hasfg; Pixmap pmap, mask; ColorModifierClass *cm; if (bg->bg.file && !bg->bg.im) { if (!bg->bg.real_file) bg->bg.real_file = ThemeFileFind(bg->bg.file); bg->bg.im = ELoadImage(bg->bg.real_file); } if (bg->top.file && !bg->top.im) { if (!bg->top.real_file) bg->top.real_file = ThemeFileFind(bg->top.file); bg->top.im = ELoadImage(bg->top.real_file); } cm = bg->cmclass; if (cm) cm->ref_count--; else cm = (ColorModifierClass *) FindItem("BACKGROUND", 0, LIST_FINDBY_NAME, LIST_TYPE_COLORMODIFIER); if (cm) { cm->ref_count++; #if 0 /* To be implemented? */ if (bg->top.im) { Imlib_set_image_red_curve(pImlib_Context, bg->top.im, cm->red.map); Imlib_set_image_green_curve(pImlib_Context, bg->top.im, cm->green.map); Imlib_set_image_blue_curve(pImlib_Context, bg->top.im, cm->blue.map); } if (bg->bg.im) { Imlib_set_image_red_curve(pImlib_Context, bg->bg.im, cm->red.map); Imlib_set_image_green_curve(pImlib_Context, bg->bg.im, cm->green.map); Imlib_set_image_blue_curve(pImlib_Context, bg->bg.im, cm->blue.map); } #endif } hasbg = hasfg = 0; if (bg->top.im) hasfg = 1; if (bg->bg.im) hasbg = 1; w = h = x = y = 0; if (hasbg) { imlib_context_set_image(bg->bg.im); BgFindImageSize(&(bg->bg), rw, rh, &w, &h, setbg); x = ((rw - w) * bg->bg.xjust) >> 10; y = ((rh - h) * bg->bg.yjust) >> 10; imlib_render_pixmaps_for_whole_image_at_size(&pmap, &mask, w, h); } if (hasbg && !hasfg && setbg && x == 0 && y == 0 && w == rw && h == rh) { /* Put image 1:1 onto the current root window */ dpmap = pmap; } else if (hasbg && !hasfg && bg->bg_tile && !TransparencyEnabled()) { /* BG only, tiled */ dpmap = ECreatePixmap(win, w, h, depth); gc = ECreateGC(dpmap, 0, NULL); } else { /* The rest that require some more work */ dpmap = ECreatePixmap(win, rw, rh, depth); gc = ECreateGC(dpmap, 0, NULL); if (!hasbg || !bg->bg_tile) { XSetForeground(disp, gc, bg->bg_solid.pixel); XFillRectangle(disp, dpmap, gc, 0, 0, rw, rh); } } if (hasbg && dpmap != pmap) { XSetTile(disp, gc, pmap); XSetTSOrigin(disp, gc, x, y); XSetFillStyle(disp, gc, FillTiled); if (bg->bg_tile) XFillRectangle(disp, dpmap, gc, 0, 0, rw, rh); else XFillRectangle(disp, dpmap, gc, x, y, w, h); imlib_free_pixmap_and_mask(pmap); } if (hasfg) { int ww, hh; imlib_context_set_image(bg->top.im); BgFindImageSize(&(bg->top), rw, rh, &ww, &hh, setbg); x = ((rw - ww) * bg->top.xjust) >> 10; y = ((rh - hh) * bg->top.yjust) >> 10; imlib_render_pixmaps_for_whole_image_at_size(&pmap, &mask, ww, hh); XSetTile(disp, gc, pmap); XSetTSOrigin(disp, gc, x, y); XSetFillStyle(disp, gc, FillTiled); if (mask) { XSetClipMask(disp, gc, mask); XSetClipOrigin(disp, gc, x, y); } XFillRectangle(disp, dpmap, gc, x, y, ww, hh); imlib_free_pixmap_and_mask(pmap); } if (!bg->keepim) BackgroundImagesFree(bg, 0); } if (setbg) { if (bg->pmap != dpmap) BackgroundPixmapFree(bg); bg->pmap = dpmap; if (dpmap) ESetWindowBackgroundPixmap(win, dpmap); else ESetWindowBackground(win, bg->bg_solid.pixel); EClearWindow(win); } else { if (dpmap) { if (!gc) gc = ECreateGC(dpmap, 0, NULL); XSetClipMask(disp, gc, 0); XSetTile(disp, gc, dpmap); XSetTSOrigin(disp, gc, 0, 0); XSetFillStyle(disp, gc, FillTiled); XFillRectangle(disp, win, gc, 0, 0, rw, rh); imlib_free_pixmap_and_mask(dpmap); } else { if (!gc) gc = ECreateGC(win, 0, NULL); XSetClipMask(disp, gc, 0); XSetFillStyle(disp, gc, FillSolid); XSetForeground(disp, gc, bg->bg_solid.pixel); XFillRectangle(disp, win, gc, 0, 0, rw, rh); } ecore_x_sync(); } if (gc) EFreeGC(gc); imlib_context_set_dither(rt); } Background * BrackgroundCreateFromImage(const char *bgid, const char *file, char *thumb, int thlen) { Background *bg; Imlib_Image *im, *im2; XColor xclr; char tile = 1, keep_asp = 0; int width, height; int scalex = 0, scaley = 0; int scr_asp, im_asp; int w2, h2; int maxw = 48, maxh = 48; int justx = 512, justy = 512; bg = FindItem(bgid, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); if (thumb) { Esnprintf(thumb, thlen, "%s/cached/img/%s", EDirUserCache(), bgid); if (bg && exists(thumb) && moddate(thumb) > moddate(file)) return bg; /* The thumbnail is gone or outdated - regererate */ } else { if (bg) return bg; } im = imlib_load_image(file); if (!im) return NULL; imlib_context_set_image(im); width = imlib_image_get_width(); height = imlib_image_get_height(); if (thumb) { h2 = maxh; w2 = (width * h2) / height; if (w2 > maxw) { w2 = maxw; h2 = (height * w2) / width; } im2 = imlib_create_cropped_scaled_image(0, 0, width, height, w2, h2); imlib_free_image_and_decache(); imlib_context_set_image(im2); imlib_image_set_format("png"); imlib_save_image(thumb); imlib_free_image_and_decache(); } /* Quit if the background itself already exists */ if (bg) return bg; scr_asp = (VRoot.w << 16) / VRoot.h; im_asp = (width << 16) / height; if (width == height) { justx = 0; justy = 0; scalex = 0; scaley = 0; tile = 1; keep_asp = 0; } else if ((!(IN_RANGE(scr_asp, im_asp, 16000))) && ((width < 480) && (height < 360))) { justx = 0; justy = 0; scalex = 0; scaley = 0; tile = 1; keep_asp = 0; } else if (IN_RANGE(scr_asp, im_asp, 16000)) { justx = 0; justy = 0; scalex = 1024; scaley = 1024; tile = 0; keep_asp = 0; } else if (im_asp > scr_asp) { justx = 512; justy = 512; scalex = 1024; scaley = 0; tile = 0; keep_asp = 1; } else { justx = 512; justy = 512; scalex = 0; scaley = 1024; tile = 0; keep_asp = 1; } ESetColor(&xclr, 0, 0, 0); bg = BackgroundCreate(bgid, &xclr, file, tile, keep_asp, justx, justy, scalex, scaley, NULL, 0, 0, 0, 0, 0); return bg; } void BackgroundIncRefcount(Background * bg) { if (bg == NULL) return; bg->ref_count++; } void BackgroundDecRefcount(Background * bg) { if (bg == NULL) return; bg->ref_count--; if (bg->ref_count <= 0) bg->last_viewed = 0; /* Clean out asap */ } void BackgroundTouch(Background * bg) { if (bg == NULL) return; bg->last_viewed = time(NULL); } const char * BackgroundGetName(const Background * bg) { return bg->name; } static const char * BackgroundGetBgFile(const Background * bg) { return bg->bg.file; } static const char * BackgroundGetFgFile(const Background * bg) { return bg->top.file; } int BackgroundGetColor(const Background * bg) { return (bg->pmap) ? 0 : bg->bg_solid.pixel; } Pixmap BackgroundGetPixmap(const Background * bg) { return (bg) ? bg->pmap : None; } static time_t BackgroundGetTimestamp(const Background * bg) { return bg->last_viewed; } #define S(str) ((str) ? str : "(null)") static void BackgroundGetInfoString1(const Background * bg, char *buf, int len) { int r, g, b; EGetColor(&(bg->bg_solid), &r, &g, &b); Esnprintf(buf, len, "%s ref_count %u keepim %u\n" " bg.solid\t %i %i %i \n" " bg.file\t %s\n" " top.file\t %s \n" " bg.tile\t %i \n" " bg.keep_aspect\t %i \ttop.keep_aspect\t %i \n" " bg.xjust\t %i \ttop.xjust\t %i \n" " bg.yjust\t %i \ttop.yjust\t %i \n" " bg.xperc\t %i \ttop.xperc\t %i \n" " bg.yperc\t %i \ttop.yperc\t %i \n", bg->name, bg->ref_count, bg->keepim, r, g, b, bg->bg.file, bg->top.file, bg->bg_tile, bg->bg.keep_aspect, bg->top.keep_aspect, bg->bg.xjust, bg->top.xjust, bg->bg.yjust, bg->top.yjust, bg->bg.xperc, bg->top.xperc, bg->bg.yperc, bg->top.yperc); } static void BackgroundGetInfoString2(const Background * bg, char *buf, int len) { int r, g, b; EGetColor(&(bg->bg_solid), &r, &g, &b); Esnprintf(buf, len, "%s %i %i %i %s %i %i %i %i %i %i %s %i %i %i %i %i", bg->name, r, g, b, S(bg->bg.file), bg->bg_tile, bg->bg.keep_aspect, bg->bg.xjust, bg->bg.yjust, bg->bg.xperc, bg->bg.yperc, S(bg->top.file), bg->top.keep_aspect, bg->top.xjust, bg->top.yjust, bg->top.xperc, bg->top.yperc); } /* * Config load/save */ #include "conf.h" int BackgroundsConfigLoad(FILE * fs) { int err = 0; Background *bg = 0; XColor xclr; char s[FILEPATH_LEN_MAX]; char s2[FILEPATH_LEN_MAX]; int ii1; int r, g, b; int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0; int j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0; char *bg1 = 0; char *bg2 = 0; char *name = 0; char ignore = 0; ColorModifierClass *cm = NULL; int fields; ESetColor(&xclr, 0, 0, 0); while (GetLine(s, sizeof(s), fs)) { s2[0] = 0; ii1 = CONFIG_INVALID; fields = sscanf(s, "%i %4000s", &ii1, s2); if (fields < 1) { ii1 = CONFIG_INVALID; } else if (ii1 == CONFIG_CLOSE) { if (fields != 1) { RecoverUserConfig(); Alert(_("CONFIG: ignoring extra data in \"%s\"\n"), s); } } else if (ii1 != CONFIG_INVALID) { if (fields != 2) { RecoverUserConfig(); Alert(_("CONFIG: missing required data in \"%s\"\n"), s); ii1 = CONFIG_INVALID; } } switch (ii1) { case CONFIG_CLOSE: if (!ignore) { if ((!bg) && (name)) { char *tmp; char ok = 1; /* check first if we can actually find the files */ if (bg1) { tmp = ThemeFileFind(bg1); if (!tmp) { ok = 0; } else { Efree(tmp); } } if (bg2) { tmp = ThemeFileFind(bg2); if (!tmp) { ok = 0; } else { Efree(tmp); } } if (ok) { bg = BackgroundCreate(name, &xclr, bg1, i1, i2, i3, i4, i5, i6, bg2, j1, j2, j3, j4, j5); if (cm) BackgroundSetColorMofifier(bg, cm); } } } goto done; case CONFIG_COLORMOD: case ICLASS_COLORMOD: cm = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_COLORMODIFIER); break; case CONFIG_CLASSNAME: case BG_NAME: if ((bg = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND))) { ignore = 1; } else { if (name) Efree(name); name = Estrdup(s2); } break; case BG_DESKNUM: if (!ignore) { /* if its the root desktop and its another visual ... */ /* create a desktop def all on its own */ if ((atoi(s2) < DesksGetNumber()) && (atoi(s2) >= 0)) { if ((DeskGetBackground(atoi(s2)) == NULL) || (Conf.backgrounds.user)) { if (!bg) bg = BackgroundCreate(name, &xclr, bg1, i1, i2, i3, i4, i5, i6, bg2, j1, j2, j3, j4, j5); DeskSetBg(atoi(s2), bg, 0); } } } else { if ((atoi(s2) < DesksGetNumber()) && (atoi(s2) >= 0)) { if ((DeskGetBackground(atoi(s2)) == NULL) || (Conf.backgrounds.user)) { if (bg) DeskSetBg(atoi(s2), bg, 0); } } } break; case BG_RGB: r = g = b = 0; sscanf(s, "%*s %d %d %d", &r, &g, &b); ESetColor(&xclr, r, g, b); if (ignore) bg->bg_solid = xclr; break; case BG_BG1: sscanf(s, "%*s %4000s %d %d %d %d %d %d", s2, &i1, &i2, &i3, &i4, &i5, &i6); if (!ignore) { if (bg1) Efree(bg1); bg1 = Estrdup(s2); } else { if (bg->bg.file) Efree(bg->bg.file); if (bg->top.file) { Efree(bg->top.file); bg->top.file = NULL; } bg->bg.file = Estrdup(s2); bg->bg_tile = i1; bg->bg.keep_aspect = i2; bg->bg.xjust = i3; bg->bg.yjust = i4; bg->bg.xperc = i5; bg->bg.yperc = i6; } break; case BG_BG2: sscanf(s, "%*s %4000s %d %d %d %d %d", s2, &j1, &j2, &j3, &j4, &j5); if (!ignore) { if (bg2) Efree(bg2); bg2 = Estrdup(s2); } else { bg->top.file = Estrdup(s2); bg->top.keep_aspect = j1; bg->top.xjust = j2; bg->top.yjust = j3; bg->top.xperc = j4; bg->top.yperc = j5; } break; default: break; } } err = -1; done: if (name) Efree(name); if (bg1) Efree(bg1); if (bg2) Efree(bg2); return err; } static void BackgroundsConfigLoadUser(void) { char s[4096]; Esnprintf(s, sizeof(s), "%s.backgrounds", EGetSavePrefix()); if (ConfigFileLoad(s, NULL, ConfigFileRead, 0)) { /* FIXME - Keep around a bit, and then remove */ Esnprintf(s, sizeof(s), "%s.misc", EGetSavePrefix()); Eprintf("Fallback - loading %s\n", s); ConfigFileLoad(s, NULL, ConfigFileRead, 0); } } static void BackgroundsConfigSave(void) { char s[FILEPATH_LEN_MAX], st[FILEPATH_LEN_MAX]; FILE *fs; int i, num; Background **bglist; int j, b, r, g; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); if (num <= 0) return; Etmp(st); fs = fopen(st, "w"); if (!fs) return; for (i = num - 1; i >= 0; i--) { fprintf(fs, "5 999\n"); fprintf(fs, "100 %s\n", bglist[i]->name); EGetColor(&(bglist[i]->bg_solid), &r, &g, &b); fprintf(fs, "560 %d %d %d\n", r, g, b); if ((bglist[i]->bg.file) && (!bglist[i]->bg.real_file)) bglist[i]->bg.real_file = ThemeFileFind(bglist[i]->bg.file); if ((bglist[i]->top.file) && (!bglist[i]->top.real_file)) bglist[i]->top.real_file = ThemeFileFind(bglist[i]->top.file); if ((bglist[i]->bg.file) && (bglist[i]->bg.real_file)) { fprintf(fs, "561 %s %d %d %d %d %d %d\n", bglist[i]->bg.real_file, bglist[i]->bg_tile, bglist[i]->bg.keep_aspect, bglist[i]->bg.xjust, bglist[i]->bg.yjust, bglist[i]->bg.xperc, bglist[i]->bg.yperc); } else if (bglist[i]->bg.file) { fprintf(fs, "561 %s %d %d %d %d %d %d\n", bglist[i]->bg.file, bglist[i]->bg_tile, bglist[i]->bg.keep_aspect, bglist[i]->bg.xjust, bglist[i]->bg.yjust, bglist[i]->bg.xperc, bglist[i]->bg.yperc); } if ((bglist[i]->top.file) && (bglist[i]->top.real_file)) { fprintf(fs, "562 %s %d %d %d %d %d\n", bglist[i]->top.real_file, bglist[i]->top.keep_aspect, bglist[i]->top.xjust, bglist[i]->top.yjust, bglist[i]->top.xperc, bglist[i]->top.yperc); } else if (bglist[i]->top.file) { fprintf(fs, "562 %s %d %d %d %d %d\n", bglist[i]->top.file, bglist[i]->top.keep_aspect, bglist[i]->top.xjust, bglist[i]->top.yjust, bglist[i]->top.xperc, bglist[i]->top.yperc); } if (bglist[i]->cmclass) { fprintf(fs, "370 %s\n", bglist[i]->cmclass->name); } for (j = 0; j < (DesksGetNumber()); j++) { if ((!strcmp(bglist[i]->name, "NONE")) && (!DeskGetBackground(j))) fprintf(fs, "564 %d\n", j); if (DeskGetBackground(j) == bglist[i]) fprintf(fs, "564 %d\n", j); } fprintf(fs, "1000\n"); } fclose(fs); Esnprintf(s, sizeof(s), "%s.backgrounds", EGetSavePrefix()); E_mv(st, s); Efree(bglist); } /* * Backgrounds module */ static void BackgroundsAccounting(void) { time_t now; int i, j, num; Background **lst; Window win; now = time(NULL); for (i = 0; i < DesksGetNumber(); i++) { if ((DeskGetBackground(i)) && (DeskIsViewable(i))) BackgroundTouch(DeskGetBackground(i)); } lst = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); for (i = 0; i < num; i++) { /* Skip if no pixmap or not timed out */ if ((BackgroundGetPixmap(lst[i]) == 0) || ((now - BackgroundGetTimestamp(lst[i])) <= Conf.backgrounds.timeout)) continue; /* Skip if associated with any viewable desktop */ for (j = 0; j < DesksGetNumber(); j++) if (lst[i] == DeskGetBackground(j) && DeskIsViewable(j)) goto next; for (j = 0; j < DesksGetNumber(); j++) { if (lst[i] != DeskGetBackground(j) || DeskIsViewable(j)) continue; /* Unviewable desktop - update the virtual root hints */ win = DeskGetWin(j); if (!Conf.hints.set_xroot_info_on_root_window) HintsSetRootInfo(win, 0, 0); ESetWindowBackground(win, 0); EClearWindow(win); } BackgroundPixmapFree(lst[i]); next: ; } if (lst) Efree(lst); } static void BackgroundsTimeout(int val __UNUSED__, void *data __UNUSED__) { BackgroundsAccounting(); /* RemoveTimerEvent("BACKGROUND_ACCOUNTING_TIMEOUT"); */ DoIn("BACKGROUND_ACCOUNTING_TIMEOUT", 30.0, BackgroundsTimeout, 0, NULL); } static void BackgroundsSighan(int sig, void *prm __UNUSED__) { switch (sig) { case ESIGNAL_INIT: EDirMake(EDirUserCache(), "cached/bgsel"); EDirMake(EDirUserCache(), "cached/img"); /* create a fallback background in case no background is found */ BackgroundCreate("NONE", NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0); break; case ESIGNAL_CONFIGURE: BackgroundsConfigLoadUser(); break; case ESIGNAL_START: DoIn("BACKGROUND_ACCOUNTING_TIMEOUT", 30.0, BackgroundsTimeout, 0, NULL); break; case ESIGNAL_EXIT: if (Mode.wm.save_ok) BackgroundsConfigSave(); break; } } /* * Configuration dialog */ static Dialog *bg_sel_dialog; static DItem *bg_sel; static DItem *bg_sel_slider; static DItem *bg_mini_disp; static DItem *bg_filename; static DItem *tmp_w[10]; static Background *tmp_bg; /* The background being configured */ static int tmp_bg_sel_sliderval = 0; static int tmp_bg_r; static int tmp_bg_g; static int tmp_bg_b; static char tmp_bg_image; static char tmp_bg_tile; static char tmp_bg_keep_aspect; static int tmp_bg_xjust; static int tmp_bg_yjust; static int tmp_bg_xperc; static int tmp_bg_yperc; static char tmp_hiq; static char tmp_userbg; static int tmp_bg_timeout; static void BG_RedrawView(char nuke_old); static void CB_ConfigureBG(Dialog * d __UNUSED__, int val, void *data __UNUSED__) { int i; if (val < 2) { Conf.backgrounds.timeout = tmp_bg_timeout; Conf.backgrounds.hiquality = tmp_hiq; Conf.backgrounds.user = tmp_userbg; ESetColor(&(tmp_bg->bg_solid), tmp_bg_r, tmp_bg_g, tmp_bg_b); tmp_bg->bg_tile = tmp_bg_tile; tmp_bg->bg.keep_aspect = tmp_bg_keep_aspect; tmp_bg->bg.xjust = tmp_bg_xjust; tmp_bg->bg.yjust = 1024 - tmp_bg_yjust; tmp_bg->bg.xperc = tmp_bg_xperc; tmp_bg->bg.yperc = 1024 - tmp_bg_yperc; if (!tmp_bg_image) BackgroundImagesRemove(tmp_bg); for (i = 0; i < DesksGetNumber(); i++) { if (DeskGetBackground(i) == tmp_bg) DeskSetBg(i, tmp_bg, 1); } { char s[4096]; Imlib_Image *im; Pixmap p2; Esnprintf(s, sizeof(s), "%s/cached/bgsel/%s", EDirUserCache(), BackgroundGetName(tmp_bg)); p2 = ECreatePixmap(VRoot.win, 64, 48, VRoot.depth); BackgroundApply(tmp_bg, p2, 0); imlib_context_set_drawable(p2); im = imlib_create_image_from_drawable(0, 0, 0, 64, 48, 0); imlib_context_set_image(im); imlib_image_set_format("png"); imlib_save_image(s); imlib_free_image_and_decache(); EFreePixmap(p2); BG_RedrawView(1); } } if (val != 1) { BackgroundImagesKeep(tmp_bg, 0); } HandleDrawQueue(); autosave(); } /* Draw the background preview image */ static void CB_DesktopMiniDisplayRedraw(Dialog * d __UNUSED__, int val __UNUSED__, void *data) { Background *bg; int w, h; DItem *di; Window win; Pixmap pmap; XColor xclr; const char *fbg, *ffg; if (!tmp_bg) return; di = (DItem *) data; win = DialogItemAreaGetWindow(di); DialogItemAreaGetSize(di, &w, &h); fbg = (tmp_bg_image) ? BackgroundGetBgFile(tmp_bg) : NULL; ffg = (tmp_bg_image) ? BackgroundGetFgFile(tmp_bg) : NULL; ESetColor(&xclr, tmp_bg_r, tmp_bg_g, tmp_bg_b); bg = BackgroundCreate("TEMP", &xclr, fbg, tmp_bg_tile, tmp_bg_keep_aspect, tmp_bg_xjust, 1024 - tmp_bg_yjust, tmp_bg_xperc, 1024 - tmp_bg_yperc, ffg, tmp_bg->top.keep_aspect, tmp_bg->top.xjust, tmp_bg->top.yjust, tmp_bg->top.xperc, tmp_bg->top.yperc); pmap = ECreatePixmap(win, w, h, VRoot.depth); ESetWindowBackgroundPixmap(win, pmap); BackgroundApply(bg, pmap, 0); EClearWindow(win); EFreePixmap(pmap); BackgroundDestroy(bg); } /* Update tmp vars according to the current tmp_bg */ static void BG_GetValues(void) { tmp_bg_image = (tmp_bg->bg.file) ? 1 : 0; EGetColor(&(tmp_bg->bg_solid), &tmp_bg_r, &tmp_bg_g, &tmp_bg_b); tmp_bg_tile = tmp_bg->bg_tile; tmp_bg_keep_aspect = tmp_bg->bg.keep_aspect; tmp_bg_xjust = tmp_bg->bg.xjust; tmp_bg_yjust = 1024 - tmp_bg->bg.yjust; tmp_bg_xperc = tmp_bg->bg.xperc; tmp_bg_yperc = 1024 - tmp_bg->bg.yperc; BackgroundImagesKeep(tmp_bg, 1); } static void BG_DialogSetFileName(DItem * di) { char *stmp; char s[1024]; if (BackgroundGetBgFile(tmp_bg)) stmp = fullfileof(BackgroundGetBgFile(tmp_bg)); else stmp = Estrdup(_("-NONE-")); Esnprintf(s, sizeof(s), _("Background definition information:\nName: %s\nFile: %s\n"), BackgroundGetName(tmp_bg), stmp); Efree(stmp); DialogItemTextSetText(di, s); } static void BgDialogSetNewCurrent(Background * bg) { int i; tmp_bg = bg; /* Fetch new BG values */ BG_GetValues(); /* Update dialog items */ BG_DialogSetFileName(bg_filename); DialogDrawItems(bg_sel_dialog, bg_filename, 0, 0, 99999, 99999); DialogItemSliderSetVal(tmp_w[0], tmp_bg_r); DialogItemCheckButtonSetState(tmp_w[1], tmp_bg_image); DialogItemSliderSetVal(tmp_w[2], tmp_bg_g); DialogItemCheckButtonSetState(tmp_w[3], tmp_bg_keep_aspect); DialogItemSliderSetVal(tmp_w[4], tmp_bg_b); DialogItemCheckButtonSetState(tmp_w[5], tmp_bg_tile); DialogItemSliderSetVal(tmp_w[6], tmp_bg_xjust); DialogItemSliderSetVal(tmp_w[7], tmp_bg_yjust); DialogItemSliderSetVal(tmp_w[8], tmp_bg_yperc); DialogItemSliderSetVal(tmp_w[9], tmp_bg_xperc); /* Redraw preview image */ CB_DesktopMiniDisplayRedraw(NULL, 0, bg_mini_disp); /* Redraw scrolling BG list */ BG_RedrawView(0); for (i = 0; i < 10; i++) DialogDrawItems(bg_sel_dialog, tmp_w[i], 0, 0, 99999, 99999); } /* Duplicate current (tmp_bg) to new */ static void CB_ConfigureNewBG(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__) { char s[1024]; XColor xclr; int lower, upper; Esnprintf(s, sizeof(s), "__NEWBG_%i", (unsigned)time(NULL)); ESetColor(&xclr, tmp_bg_r, tmp_bg_g, tmp_bg_b); tmp_bg = BackgroundCreate(s, &xclr, tmp_bg->bg.file, tmp_bg_tile, tmp_bg_keep_aspect, tmp_bg_xjust, 1024 - tmp_bg_yjust, tmp_bg_xperc, 1024 - tmp_bg_yperc, tmp_bg->top.file, tmp_bg->top.keep_aspect, tmp_bg->top.xjust, tmp_bg->top.yjust, tmp_bg->top.xperc, tmp_bg->top.yperc); DialogItemSliderGetBounds(bg_sel_slider, &lower, &upper); upper += 4; DialogItemSliderSetBounds(bg_sel_slider, lower, upper); DialogItemSliderSetVal(bg_sel_slider, 0); DialogDrawItems(bg_sel_dialog, bg_sel_slider, 0, 0, 99999, 99999); DeskSetBg(DesksGetCurrent(), tmp_bg, 0); BG_RedrawView(0); autosave(); } static void CB_ConfigureDelBG(Dialog * d __UNUSED__, int val, void *data __UNUSED__) { Background **bglist, *bg; int i, num; int slider, lower, upper; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); if (!bglist || num <= 1) goto done; DialogItemSliderGetBounds(bg_sel_slider, &lower, &upper); slider = DialogItemSliderGetVal(bg_sel_slider); upper -= 4; DialogItemSliderSetBounds(bg_sel_slider, lower, upper); if (slider > upper) DialogItemSliderSetVal(bg_sel_slider, upper); bg = NULL; for (i = 0; i < num; i++) { if (bglist[i] == tmp_bg) { if (i < (num - 1)) bg = bglist[i + 1]; else bg = bglist[i - 1]; break; } } DeskSetBg(DesksGetCurrent(), bg, 0); if (val == 0) BackgroundDestroy(tmp_bg); else BackgroundDelete(tmp_bg); BgDialogSetNewCurrent(bg); autosave(); done: if (bglist) Efree(bglist); } /* Move current background to first position in list */ static void CB_ConfigureFrontBG(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__) { MoveItemToListTop(tmp_bg, LIST_TYPE_BACKGROUND); BG_RedrawView(0); autosave(); } static int tmp_bg_selected = -1; /* Draw the scrolling background image window */ static void BG_RedrawView(char nuke_old) { int num, i; Background **bglist; int w, h; Window win; int x; Pixmap pmap; GC gc; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); if (!bglist) goto done; win = DialogItemAreaGetWindow(bg_sel); DialogItemAreaGetSize(bg_sel, &w, &h); pmap = ECreatePixmap(win, w, h, VRoot.depth); gc = ECreateGC(pmap, 0, NULL); XSetForeground(disp, gc, BlackPixel(disp, VRoot.scr)); XFillRectangle(disp, pmap, gc, 0, 0, w, h); ESetWindowBackgroundPixmap(win, pmap); x = -(tmp_bg_sel_sliderval * (64 + 8) / 4); if (x < (w - ((64 + 8) * num))) x = w - ((64 + 8) * num); for (i = 0; i < num; i++) { if (((x + 64 + 8) >= 0) && (x < w)) { Pixmap p2; ImageClass *ic; Imlib_Image *im; char s[4096]; ic = ImageclassFind("DIALOG_BUTTON", 0); if (ic) { PmapMask pmm; if (i == tmp_bg_selected) ImageclassApplyCopy(ic, pmap, 64 + 8, 48 + 8, 0, 0, STATE_CLICKED, &pmm, 0, ST_UNKNWN); else ImageclassApplyCopy(ic, pmap, 64 + 8, 48 + 8, 0, 0, STATE_NORMAL, &pmm, 0, ST_UNKNWN); XCopyArea(disp, pmm.pmap, pmap, gc, 0, 0, 64 + 8, 48 + 8, x, 0); FreePmapMask(&pmm); } if (!strcmp(BackgroundGetName(bglist[i]), "NONE")) { TextClass *tc; tc = TextclassFind("DIALOG", 1); if (tc) { int tw, th; TextSize(tc, 0, 0, STATE_NORMAL, _("No\nBackground"), &tw, &th, 17); TextDraw(tc, pmap, 0, 0, STATE_NORMAL, _("No\nBackground"), x + 4, 4 + ((48 - th) / 2), 64, 48, 17, 512); } } else { Esnprintf(s, sizeof(s), "%s/cached/bgsel/%s", EDirUserCache(), BackgroundGetName(bglist[i])); im = ELoadImage(s); if (!im) { Esnprintf(s, sizeof(s), "%s/cached/bgsel/%s", EDirUserCache(), BackgroundGetName(bglist[i])); p2 = ECreatePixmap(pmap, 64, 48, VRoot.depth); BackgroundApply(bglist[i], p2, 0); XCopyArea(disp, p2, pmap, gc, 0, 0, 64, 48, x + 4, 4); imlib_context_set_drawable(p2); im = imlib_create_image_from_drawable(0, 0, 0, 64, 48, 0); imlib_context_set_image(im); imlib_image_set_format("png"); imlib_save_image(s); imlib_free_image_and_decache(); EFreePixmap(p2); } else { if (nuke_old) { imlib_context_set_image(im); imlib_free_image_and_decache(); im = ELoadImage(s); } if (im) { imlib_context_set_image(im); imlib_context_set_drawable(pmap); imlib_render_image_on_drawable_at_size(x + 4, 4, 64, 48); imlib_free_image(); } } } } x += (64 + 8); } EFreeGC(gc); EFreePixmap(pmap); Efree(bglist); EClearWindow(win); done: return; } static void CB_BGAreaSlide(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__) { BG_RedrawView(0); } static void CB_BGScan(Dialog * d, int val __UNUSED__, void *data __UNUSED__) { int slider, lower, upper; SoundPlay("SOUND_WAIT"); DialogItemSliderGetBounds(bg_sel_slider, &lower, &upper); for (slider = lower; slider <= upper; slider += 8) { DialogItemSliderSetVal(bg_sel_slider, slider); DialogDrawItems(bg_sel_dialog, bg_sel_slider, 0, 0, 99999, 99999); DialogItemCallCallback(d, bg_sel_slider); } } static void CB_BGAreaEvent(int val __UNUSED__, void *data) { int x, num, w, h; Background **bglist; XEvent *ev = (XEvent *) data; DialogItemAreaGetSize(bg_sel, &w, &h); switch (ev->type) { case ButtonPress: bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); x = (tmp_bg_sel_sliderval * (64 + 8) / 4); if (x > ((num * (64 + 8)) - w)) x = ((num * (64 + 8)) - w); x += ev->xbutton.x; x = x / (64 + 8); tmp_bg_selected = x; if ((tmp_bg_selected >= 0) && (tmp_bg_selected < num)) { BackgroundImagesKeep(tmp_bg, 0); BgDialogSetNewCurrent(bglist[tmp_bg_selected]); DeskSetBg(DesksGetCurrent(), tmp_bg, 0); autosave(); } if (bglist) Efree(bglist); break; case ButtonRelease: tmp_bg_selected = -1; BG_RedrawView(0); break; } } static void CB_DesktopTimeout(Dialog * d __UNUSED__, int val __UNUSED__, void *data) { DItem *di; char s[256]; di = (DItem *) data; Esnprintf(s, sizeof(s), _("Unused backgrounds freed after %2i:%02i:%02i"), tmp_bg_timeout / 3600, (tmp_bg_timeout / 60) - (60 * (tmp_bg_timeout / 3600)), (tmp_bg_timeout) - (60 * (tmp_bg_timeout / 60))); DialogItemTextSetText(di, s); DialogDrawItems(bg_sel_dialog, di, 0, 0, 99999, 99999); } static void BGSettingsGoTo(Background * bg) { Dialog *bgd; Background **bglist; int i, num; if (!(bgd = FindItem("CONFIGURE_BG", 0, LIST_FINDBY_NAME, LIST_TYPE_DIALOG))) return; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); if (!bglist) return; for (i = 0; i < num; i++) { if (bglist[i] == bg) { DialogItemSliderSetVal(bg_sel_slider, 4 * i); DialogDrawItems(bg_sel_dialog, bg_sel_slider, 0, 0, 99999, 99999); DialogItemCallCallback(NULL, bg_sel_slider); tmp_bg_selected = i; BackgroundImagesKeep(tmp_bg, 0); BgDialogSetNewCurrent(bglist[tmp_bg_selected]); tmp_bg_selected = -1; break; } } Efree(bglist); } static void CB_BGPrev(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__) { Background **bglist; int i, num; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); for (i = 0; i < num; i++) { if ((bglist[i] == tmp_bg) && (i > 0)) { BGSettingsGoTo(bglist[i - 1]); DeskSetBg(DesksGetCurrent(), bglist[i - 1], 0); break; } } if (bglist) Efree(bglist); } static void CB_BGNext(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__) { Background **bglist; int i, num; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); for (i = 0; i < num; i++) { if ((bglist[i] == tmp_bg) && (i < (num - 1))) { BGSettingsGoTo(bglist[i + 1]); DeskSetBg(DesksGetCurrent(), bglist[i + 1], 0); break; } } if (bglist) Efree(bglist); } static int BG_SortFileCompare(Background * bg1, Background * bg2) { const char *name1, *name2; /* return < 0 is b1 < b2 */ /* return > 0 is b1 > b2 */ /* return 0 is b1 == b2 */ name1 = BackgroundGetBgFile(bg1); name2 = BackgroundGetBgFile(bg2); if (name1 && name2) return strcmp(name1, name2); name1 = BackgroundGetFgFile(bg1); name2 = BackgroundGetFgFile(bg2); if (name1 && name2) return strcmp(name1, name2); return 0; } static void CB_BGSortFile(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__) { Background **bglist; int i, num; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); if (!bglist) return; /* remove them all from the list */ for (i = 0; i < num; i++) RemoveItem((char *)(bglist[i]), 0, LIST_FINDBY_POINTER, LIST_TYPE_BACKGROUND); Quicksort((void **)bglist, 0, num - 1, (int (*)(void *d1, void *d2))BG_SortFileCompare); for (i = 0; i < num; i++) { Background *bg; bg = bglist[i]; AddItem(bg, BackgroundGetName(bg), 0, LIST_TYPE_BACKGROUND); } Efree(bglist); BGSettingsGoTo(tmp_bg); autosave(); } static void CB_BGSortAttrib(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__) { Background **bglist; int i, num; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); if (!bglist) return; /* remove them all from the list */ for (i = 0; i < num; i++) RemoveItem((char *)(bglist[i]), 0, LIST_FINDBY_POINTER, LIST_TYPE_BACKGROUND); for (i = 0; i < num; i++) { Background *bg; bg = bglist[i]; if ((bg) && (bg->bg_tile) && (bg->bg.xperc == 0) && (bg->bg.yperc == 0)) { AddItem(bg, bg->name, 0, LIST_TYPE_BACKGROUND); bglist[i] = NULL; } } for (i = 0; i < num; i++) { Background *bg; bg = bglist[i]; if (bg) { AddItem(bg, bg->name, 0, LIST_TYPE_BACKGROUND); bglist[i] = NULL; } } Efree(bglist); BGSettingsGoTo(tmp_bg); autosave(); } static void CB_BGSortContent(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__) { Background **bglist; int i, num; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); if (bglist) { /* remove them all from the list */ for (i = 0; i < num; i++) RemoveItem((char *)(bglist[i]), 0, LIST_FINDBY_POINTER, LIST_TYPE_BACKGROUND); for (i = 0; i < num; i++) { Background *bg; bg = bglist[i]; AddItem(bg, BackgroundGetName(bg), 0, LIST_TYPE_BACKGROUND); } Efree(bglist); } autosave(); } static void SettingsBackground(Background * bg) { Dialog *d; DItem *table, *di, *table2, *area, *slider, *slider2, *label; DItem *w1, *w2, *w3, *w4, *w5, *w6; int num; char s[1024]; if ((d = FindItem("CONFIGURE_BG", 0, LIST_FINDBY_NAME, LIST_TYPE_DIALOG))) { SoundPlay("SOUND_SETTINGS_ACTIVE"); ShowDialog(d); return; } SoundPlay("SOUND_SETTINGS_BG"); if ((!bg) || ((bg) && (!strcmp(BackgroundGetName(bg), "NONE")))) { Esnprintf(s, sizeof(s), "__NEWBG_%i", (unsigned)time(NULL)); bg = BackgroundCreate(s, NULL, NULL, 1, 1, 0, 0, 0, 0, NULL, 1, 512, 512, 0, 0); } tmp_bg = bg; BG_GetValues(); tmp_hiq = Conf.backgrounds.hiquality; tmp_userbg = Conf.backgrounds.user; tmp_bg_timeout = Conf.backgrounds.timeout; d = bg_sel_dialog = DialogCreate("CONFIGURE_BG"); DialogSetTitle(d, _("Desktop Background Settings")); table = DialogInitItem(d); DialogItemTableSetOptions(table, 3, 0, 0, 0); if (Conf.dialogs.headers) { di = DialogAddItem(table, DITEM_IMAGE); DialogItemSetColSpan(di, 2); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemImageSetFile(di, "pix/bg.png"); di = DialogAddItem(table, DITEM_TEXT); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemTextSetText(di, _("Enlightenment Desktop\n" "Background Settings Dialog\n")); di = DialogAddItem(table, DITEM_SEPARATOR); DialogItemSetColSpan(di, 3); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSeparatorSetOrientation(di, 0); } di = DialogAddItem(table, DITEM_TEXT); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemTextSetText(di, _("BG Colour\n")); di = DialogAddItem(table, DITEM_NONE); table2 = DialogAddItem(table, DITEM_TABLE); DialogItemSetPadding(table2, 2, 2, 2, 2); DialogItemTableSetOptions(table2, 4, 0, 0, 0); di = DialogAddItem(table2, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemButtonSetText(di, _("Move to Front\n")); DialogItemSetCallback(di, CB_ConfigureFrontBG, 0, NULL); DialogBindKey(d, "F", CB_ConfigureFrontBG, 0); di = DialogAddItem(table2, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemButtonSetText(di, _("Duplicate\n")); DialogItemSetCallback(di, CB_ConfigureNewBG, 0, NULL); di = DialogAddItem(table2, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemButtonSetText(di, _("Unlist\n")); DialogItemSetCallback(di, CB_ConfigureDelBG, 0, NULL); di = DialogAddItem(table2, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemButtonSetText(di, _("Delete File\n")); DialogItemSetCallback(di, CB_ConfigureDelBG, 0, NULL); DialogBindKey(d, "D", CB_ConfigureDelBG, 0); DialogBindKey(d, "Delete", CB_ConfigureDelBG, 1); di = DialogAddItem(table, DITEM_TEXT); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemSetAlign(di, 1024, 512); DialogItemTextSetText(di, _("Red:\n")); di = w1 = tmp_w[0] = DialogAddItem(table, DITEM_SLIDER); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSliderSetBounds(di, 0, 255); DialogItemSliderSetUnits(di, 1); DialogItemSliderSetJump(di, 16); DialogItemSliderSetVal(di, tmp_bg_r); DialogItemSliderSetValPtr(di, &tmp_bg_r); di = w2 = tmp_w[1] = DialogAddItem(table, DITEM_CHECKBUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemCheckButtonSetText(di, _("Use background image")); DialogItemCheckButtonSetState(di, tmp_bg_image); DialogItemCheckButtonSetPtr(di, &tmp_bg_image); di = DialogAddItem(table, DITEM_TEXT); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemSetAlign(di, 1024, 512); DialogItemTextSetText(di, _("Green:\n")); di = w3 = tmp_w[2] = DialogAddItem(table, DITEM_SLIDER); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSliderSetBounds(di, 0, 255); DialogItemSliderSetUnits(di, 1); DialogItemSliderSetJump(di, 16); DialogItemSliderSetVal(di, tmp_bg_g); DialogItemSliderSetValPtr(di, &tmp_bg_g); di = w4 = tmp_w[3] = DialogAddItem(table, DITEM_CHECKBUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemCheckButtonSetText(di, _("Keep aspect on scale")); DialogItemCheckButtonSetState(di, tmp_bg_keep_aspect); DialogItemCheckButtonSetPtr(di, &tmp_bg_keep_aspect); di = DialogAddItem(table, DITEM_TEXT); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemSetAlign(di, 1024, 512); DialogItemTextSetText(di, _("Blue:\n")); di = w5 = tmp_w[4] = DialogAddItem(table, DITEM_SLIDER); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSliderSetBounds(di, 0, 255); DialogItemSliderSetUnits(di, 1); DialogItemSliderSetJump(di, 16); DialogItemSliderSetVal(di, tmp_bg_b); DialogItemSliderSetValPtr(di, &tmp_bg_b); di = w6 = tmp_w[5] = DialogAddItem(table, DITEM_CHECKBUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemCheckButtonSetText(di, _("Tile image across background")); DialogItemCheckButtonSetState(di, tmp_bg_tile); DialogItemCheckButtonSetPtr(di, &tmp_bg_tile); di = DialogAddItem(table, DITEM_SEPARATOR); DialogItemSetColSpan(di, 3); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSeparatorSetOrientation(di, 0); di = DialogAddItem(table, DITEM_TEXT); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemSetAlign(di, 512, 512); DialogItemSetColSpan(di, 2); DialogItemTextSetText(di, _("Background\n" "Image\n" "Scaling\n" "and\n" "Alignment\n")); table2 = DialogAddItem(table, DITEM_TABLE); DialogItemSetPadding(table2, 2, 2, 2, 2); DialogItemTableSetOptions(table2, 3, 0, 0, 0); di = DialogAddItem(table2, DITEM_NONE); di = slider = tmp_w[6] = DialogAddItem(table2, DITEM_SLIDER); DialogItemSliderSetMinLength(di, 10); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSliderSetBounds(di, 0, 1024); DialogItemSliderSetUnits(di, 1); DialogItemSliderSetJump(di, 64); DialogItemSliderSetVal(di, tmp_bg_xjust); DialogItemSliderSetValPtr(di, &tmp_bg_xjust); di = DialogAddItem(table2, DITEM_NONE); di = slider2 = tmp_w[7] = DialogAddItem(table2, DITEM_SLIDER); DialogItemSliderSetMinLength(di, 10); DialogItemSliderSetOrientation(di, 0); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 1); DialogItemSliderSetBounds(di, 0, 1024); DialogItemSliderSetUnits(di, 1); DialogItemSliderSetJump(di, 64); DialogItemSliderSetVal(di, tmp_bg_yjust); DialogItemSliderSetValPtr(di, &tmp_bg_yjust); di = bg_mini_disp = area = DialogAddItem(table2, DITEM_AREA); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemAreaSetSize(di, 64, 48); DialogItemSetCallback(w1, CB_DesktopMiniDisplayRedraw, 0, (void *)area); DialogItemSetCallback(w2, CB_DesktopMiniDisplayRedraw, 0, (void *)area); DialogItemSetCallback(w3, CB_DesktopMiniDisplayRedraw, 0, (void *)area); DialogItemSetCallback(w4, CB_DesktopMiniDisplayRedraw, 0, (void *)area); DialogItemSetCallback(w5, CB_DesktopMiniDisplayRedraw, 0, (void *)area); DialogItemSetCallback(w6, CB_DesktopMiniDisplayRedraw, 0, (void *)area); DialogItemSetCallback(slider, CB_DesktopMiniDisplayRedraw, 0, (void *)area); DialogItemSetCallback(slider2, CB_DesktopMiniDisplayRedraw, 0, (void *)area); di = slider = tmp_w[8] = DialogAddItem(table2, DITEM_SLIDER); DialogItemSliderSetMinLength(di, 10); DialogItemSliderSetOrientation(di, 0); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 1); DialogItemSliderSetBounds(di, 0, 1024); DialogItemSliderSetUnits(di, 1); DialogItemSliderSetJump(di, 64); DialogItemSliderSetVal(di, tmp_bg_yperc); DialogItemSliderSetValPtr(di, &tmp_bg_yperc); DialogItemSetCallback(slider, CB_DesktopMiniDisplayRedraw, 0, (void *)area); di = DialogAddItem(table2, DITEM_NONE); di = slider = tmp_w[9] = DialogAddItem(table2, DITEM_SLIDER); DialogItemSliderSetMinLength(di, 10); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSliderSetBounds(di, 0, 1024); DialogItemSliderSetUnits(di, 1); DialogItemSliderSetJump(di, 64); DialogItemSliderSetVal(di, tmp_bg_xperc); DialogItemSliderSetValPtr(di, &tmp_bg_xperc); DialogItemSetCallback(slider, CB_DesktopMiniDisplayRedraw, 0, (void *)area); di = DialogAddItem(table, DITEM_SEPARATOR); DialogItemSetColSpan(di, 3); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSeparatorSetOrientation(di, 0); di = DialogAddItem(table, DITEM_CHECKBUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSetColSpan(di, 2); DialogItemCheckButtonSetText(di, _("Use dithering in Hi-Colour")); DialogItemCheckButtonSetState(di, tmp_hiq); DialogItemCheckButtonSetPtr(di, &tmp_hiq); di = DialogAddItem(table, DITEM_CHECKBUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemCheckButtonSetText(di, _("Background overrides theme")); DialogItemCheckButtonSetState(di, tmp_userbg); DialogItemCheckButtonSetPtr(di, &tmp_userbg); di = label = DialogAddItem(table, DITEM_TEXT); DialogItemSetColSpan(di, 3); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSetAlign(di, 512, 512); Esnprintf(s, sizeof(s), _("Unused backgrounds freed after %2i:%02i:%02i"), tmp_bg_timeout / 3600, (tmp_bg_timeout / 60) - (60 * (tmp_bg_timeout / 3600)), (tmp_bg_timeout) - (60 * (tmp_bg_timeout / 60))); DialogItemTextSetText(di, s); di = DialogAddItem(table, DITEM_SLIDER); DialogItemSetColSpan(di, 3); DialogItemSliderSetMinLength(di, 10); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSliderSetBounds(di, 0, 60 * 60 * 4); DialogItemSliderSetUnits(di, 30); DialogItemSliderSetJump(di, 60); DialogItemSliderSetVal(di, tmp_bg_timeout); DialogItemSliderSetValPtr(di, &tmp_bg_timeout); DialogItemSetCallback(di, CB_DesktopTimeout, 0, (void *)label); di = DialogAddItem(table, DITEM_SEPARATOR); DialogItemSetColSpan(di, 3); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSeparatorSetOrientation(di, 0); table2 = DialogAddItem(table, DITEM_TABLE); DialogItemSetPadding(table2, 2, 2, 2, 2); DialogItemTableSetOptions(table2, 2, 0, 0, 0); di = DialogAddItem(table2, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemButtonSetText(di, "<-"); DialogItemSetCallback(di, CB_BGPrev, 0, NULL); DialogBindKey(d, "Left", CB_BGPrev, 0); DialogBindKey(d, "BackSpace", CB_BGPrev, 0); di = DialogAddItem(table2, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemButtonSetText(di, "->"); DialogItemSetCallback(di, CB_BGNext, 0, NULL); DialogBindKey(d, "Right", CB_BGNext, 0); DialogBindKey(d, "space", CB_BGNext, 0); di = DialogAddItem(table, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemButtonSetText(di, _("Pre-scan BG's")); DialogItemSetCallback(di, CB_BGScan, 0, NULL); table2 = DialogAddItem(table, DITEM_TABLE); DialogItemSetPadding(table2, 2, 2, 2, 2); DialogItemTableSetOptions(table2, 3, 0, 0, 0); di = DialogAddItem(table2, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemButtonSetText(di, _("Sort by File")); DialogItemSetCallback(di, CB_BGSortFile, 0, NULL); di = DialogAddItem(table2, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemButtonSetText(di, _("Sort by Attr.")); DialogItemSetCallback(di, CB_BGSortAttrib, 0, NULL); di = DialogAddItem(table2, DITEM_BUTTON); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 0, 0); DialogItemButtonSetText(di, _("Sort by Image")); DialogItemSetCallback(di, CB_BGSortContent, 0, NULL); di = bg_sel = DialogAddItem(table, DITEM_AREA); DialogItemSetColSpan(di, 3); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemAreaSetSize(di, 160, 56); DialogItemAreaSetEventFunc(di, CB_BGAreaEvent); num = 0; { Background **bglist; bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); if (bglist) Efree(bglist); } di = bg_sel_slider = DialogAddItem(table, DITEM_SLIDER); DialogItemSetColSpan(di, 3); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSliderSetBounds(di, 0, num * 4); DialogItemSliderSetUnits(di, 1); DialogItemSliderSetJump(di, 9); DialogItemSliderSetVal(di, tmp_bg_sel_sliderval); DialogItemSliderSetValPtr(di, &tmp_bg_sel_sliderval); DialogItemSetCallback(bg_sel_slider, CB_BGAreaSlide, 0, NULL); di = bg_filename = DialogAddItem(table, DITEM_TEXT); DialogItemSetColSpan(di, 3); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSetAlign(di, 512, 512); BG_DialogSetFileName(bg_filename); di = DialogAddItem(table, DITEM_SEPARATOR); DialogItemSetColSpan(di, 3); DialogItemSetPadding(di, 2, 2, 2, 2); DialogItemSetFill(di, 1, 0); DialogItemSeparatorSetOrientation(di, 0); DialogAddButton(d, _("OK"), CB_ConfigureBG, 1, DIALOG_BUTTON_OK); DialogAddButton(d, _("Apply"), CB_ConfigureBG, 0, DIALOG_BUTTON_APPLY); DialogAddButton(d, _("Close"), CB_ConfigureBG, 1, DIALOG_BUTTON_CLOSE); DialogSetExitFunction(d, CB_ConfigureBG, 2); DialogBindKey(d, "Escape", DialogCallbackClose, 0); DialogBindKey(d, "Return", CB_ConfigureBG, 0); ShowDialog(d); CB_DesktopMiniDisplayRedraw(NULL, 1, area); BG_RedrawView(0); BGSettingsGoTo(tmp_bg); /* This is kind of a hack - somehow it loses the correct current desktop * information when we actually open up the dialog box, so this * should fix the atom which apparently gets clobbered somewhere * above here * --Mandrake */ DeskRefresh(DesksGetCurrent()); } /* * IPC functions */ static void BackgroundSet1(const char *name, const char *params) { const char *p = params; char type[FILEPATH_LEN_MAX]; char valu[FILEPATH_LEN_MAX]; int len; Background *bg; bg = FindItem(name, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); if (!bg) { bg = BackgroundCreate(name, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0); if (!bg) { IpcPrintf("Error: could not create background '%s'.", name); return; } } type[0] = valu[0] = '\0'; len = 0; sscanf(p, "%400s %4000s %n", type, valu, &len); p += len; if (!strcmp(type, "bg.solid")) { int r, b, g; r = g = b = 0; sscanf(p, "%i %i %i", &r, &g, &b); ESetColor(&(bg->bg_solid), r, g, b); } else if (!strcmp(type, "bg.file")) { if (bg->bg.file) Efree(bg->bg.file); bg->bg.file = Estrdup(valu); } else if (!strcmp(type, "bg.tile")) { bg->bg_tile = atoi(valu); } else if (!strcmp(type, "bg.keep_aspect")) { bg->bg.keep_aspect = atoi(valu); } else if (!strcmp(type, "bg.xjust")) { bg->bg.xjust = atoi(valu); } else if (!strcmp(type, "bg.yjust")) { bg->bg.yjust = atoi(valu); } else if (!strcmp(type, "bg.xperc")) { bg->bg.xperc = atoi(valu); } else if (!strcmp(type, "bg.yperc")) { bg->bg.yperc = atoi(valu); } else if (!strcmp(type, "top.file")) { if (bg->top.file) Efree(bg->top.file); bg->top.file = Estrdup(valu); } else if (!strcmp(type, "top.keep_aspect")) { bg->top.keep_aspect = atoi(valu); } else if (!strcmp(type, "top.xjust")) { bg->top.xjust = atoi(valu); } else if (!strcmp(type, "top.yjust")) { bg->top.yjust = atoi(valu); } else if (!strcmp(type, "top.xperc")) { bg->top.xperc = atoi(valu); } else if (!strcmp(type, "top.yperc")) { bg->top.yperc = atoi(valu); } else { IpcPrintf("Error: unknown background value type '%s'.", type); } autosave(); } static void BackgroundSet2(const char *name, const char *params) { Background *bg; XColor xclr; int i, r, g, b; char bgf[FILEPATH_LEN_MAX], topf[FILEPATH_LEN_MAX]; int updated, tile, keep_aspect, tkeep_aspect; int xjust, yjust, xperc, yperc; int txjust, tyjust, txperc, typerc; if (params == NULL) return; bgf[0] = topf[0] = '\0'; r = g = b = 99; i = sscanf(params, "%i %i %i %4000s %i %i %i %i %i %i %4000s %i %i %i %i %i", &r, &g, &b, bgf, &tile, &keep_aspect, &xjust, &yjust, &xperc, &yperc, topf, &tkeep_aspect, &txjust, &tyjust, &txperc, &typerc); ESetColor(&xclr, r, g, b); bg = FindItem(name, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); if (bg) { updated = BackgroundModify(bg, &xclr, bgf, tile, keep_aspect, xjust, yjust, xperc, yperc, topf, tkeep_aspect, txjust, tyjust, txperc, typerc); if (updated) { for (i = 0; i < DesksGetNumber(); i++) { if (DeskGetBackground(i) == bg) DeskSetBg(i, bg, 0); } } } else { bg = BackgroundCreate(name, &xclr, bgf, tile, keep_aspect, xjust, yjust, xperc, yperc, topf, tkeep_aspect, txjust, tyjust, txperc, typerc); } } static void BackgroundsIpc(const char *params, Client * c __UNUSED__) { const char *p; char cmd[128], prm[128], buf[4096]; int i, len, num; Background *bg; cmd[0] = prm[0] = '\0'; p = params; if (p) { len = 0; sscanf(p, "%100s %100s %n", cmd, prm, &len); p += len; } if (!p || cmd[0] == '?') { for (i = 0; i < Conf.desks.num; i++) { if (DeskGetBackground(i)) IpcPrintf("%i %s\n", i, BackgroundGetName(DeskGetBackground(i))); } } else if (!strncmp(cmd, "apply", 2)) { Window win; bg = FindItem(prm, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); if (bg) { win = None; sscanf(p, "%lx", &win); if (win) BackgroundApply(bg, win, 0); } } else if (!strncmp(cmd, "cfg", 2)) { SettingsBackground(DeskGetBackground(DesksGetCurrent())); } else if (!strncmp(cmd, "del", 2)) { BackgroundDestroyByName(prm); } else if (!strncmp(cmd, "list", 2)) { Background **lst; lst = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); for (i = 0; i < num; i++) { IpcPrintf("%s\n", BackgroundGetName(lst[i])); } if (lst) Efree(lst); } else if (!strncmp(cmd, "load", 2)) { bg = FindItem(prm, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); if (bg) { IpcPrintf("Background already defined\n"); } else { bg = BrackgroundCreateFromImage(prm, p, NULL, 0); } } else if (!strncmp(cmd, "set", 2)) { BackgroundSet1(prm, p); } else if (!strncmp(cmd, "show", 2)) { bg = FindItem(prm, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); if (bg) { BackgroundGetInfoString1(bg, buf, sizeof(buf)); IpcPrintf("%s\n", buf); } else IpcPrintf("Error: background '%s' does not exist.", prm); } else if (!strcmp(cmd, "use")) { if (!strcmp(prm, "-")) bg = NULL; else bg = FindItem(prm, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); num = DesksGetCurrent(); sscanf(p, "%d %n", &num, &len); DeskSetBg(num, bg, 1); autosave(); } else if (!strncmp(cmd, "xget", 2)) { bg = FindItem(prm, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); if (bg) { BackgroundGetInfoString2(bg, buf, sizeof(buf)); IpcPrintf("%s\n", buf); } else IpcPrintf("Error: background '%s' does not exist.", prm); } else if (!strncmp(cmd, "xset", 2)) { BackgroundSet2(prm, p); } else { /* Compatibility with pre- 0.16.8 clients */ BackgroundSet1(cmd, atword(params, 2)); } } static void IPC_BackgroundUse(const char *params, Client * c __UNUSED__) { char param1[FILEPATH_LEN_MAX], w[FILEPATH_LEN_MAX]; Background *bg; int i, wd; word(params, 1, param1); bg = FindItem(param1, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); if (!bg) return; for (wd = 2;; wd++) { w[0] = 0; word(params, wd++, w); if (!w[0]) break; i = atoi(w); DeskSetBg(i, bg, 1); } autosave(); } #if 0 /* I doubt this is used */ static void IPC_BackgroundColormodifierSet(const char *params, Client * c __UNUSED__) { Background *bg; ColorModifierClass *cm; int i; char buf[FILEPATH_LEN_MAX], buf2[FILEPATH_LEN_MAX]; if (params == NULL) return; sscanf(params, "%1000s %1000s", buf, buf2); bg = FindItem(buf, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); cm = FindItem(buf2, 0, LIST_FINDBY_NAME, LIST_TYPE_COLORMODIFIER); if ((bg) && (bg->cmclass != cm)) { if (!strcmp(buf, "(null)")) { bg->cmclass->ref_count--; bg->cmclass = NULL; } else if (cm) { bg->cmclass->ref_count--; bg->cmclass = cm; } if (bg->pmap) imlib_free_pixmap_and_mask(bg->pmap); bg->pmap = 0; for (i = 0; i < DesksGetNumber(); i++) { if ((desks.desk[i].bg == bg) && (desks.desk[i].viewable)) DeskRefresh(i); } } } static void IPC_BackgroundColormodifierGet(const char *params, Client * c) { char param1[FILEPATH_LEN_MAX], buf[FILEPATH_LEN_MAX]; Background *bg; if (params == NULL) return; sscanf(params, "%1000s", param1); bg = (Background *) FindItem(param1, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); Esnprintf(buf, sizeof(buf), "(null)"); if ((bg) && (bg->cmclass)) Esnprintf(buf, sizeof(buf), "%s", bg->cmclass->name); CommsSend(c, buf); } #endif IpcItem BackgroundsIpcArray[] = { { BackgroundsIpc, "background", "bg", "Background commands", " background Show current background\n" " background apply Apply background to window\n" " background cfg Configure backgrounds\n" " background del Delete background\n" " background list Show all background\n" " background load Load new wallpaper from file\n" " background set ... Set background parameters\n" " background show Show background info\n" " background use Switch to background \n" " background xget Special show background parameters\n" " background xset ... Special set background parameters\n"} , { IPC_BackgroundUse, "use_bg", NULL, "Deprecated - do not use", NULL} , #if 0 /* I doubt this is used */ {IPC_BackgroundColormodifierSet, "set_bg_colmod", NULL, "TBD", NULL} , {IPC_BackgroundColormodifierGet, "get_bg_colmod", NULL, "TBD", NULL} , #endif }; #define N_IPC_FUNCS (sizeof(BackgroundsIpcArray)/sizeof(IpcItem)) /* * Module descriptor */ EModule ModBackgrounds = { "backgrounds", "bg", BackgroundsSighan, {N_IPC_FUNCS, BackgroundsIpcArray} , {0, NULL} };