2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3 * Copyright (C) 2004-2009 Kim Woelders
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies of the Software, its documentation and marketing & publicity
14 * materials, and acknowledgment shall be given in the documentation, materials
15 * and software packages that this Software was used.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 #include "backgrounds.h"
29 #include "e16-ecore_list.h"
59 unsigned int ref_count;
63 static Ecore_List *bg_list = NULL;
64 static Timer *bg_timer = NULL;
65 static unsigned int bg_seq_no = 0;
67 #define N_BG_ASSIGNED 32
68 static Background *bg_assigned[N_BG_ASSIGNED];
71 BackgroundGetUniqueString(const Background * bg)
75 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
77 int n1, n2, n3, n4, n5, f1, f2, f3, f4, f5, f6;
79 GET_COLOR(&(bg->bg_solid), r, g, b);
80 n1 = (r << 24) | (g << 16) | (b << 8) | (bg->bg_tile << 7)
81 | (bg->bg.keep_aspect << 6) | (bg->top.keep_aspect << 5);
82 n2 = (bg->bg.xjust << 16) | (bg->bg.yjust);
83 n3 = (bg->bg.xperc << 16) | (bg->bg.yperc);
84 n4 = (bg->top.xjust << 16) | (bg->top.yjust);
85 n5 = (bg->top.xperc << 16) | (bg->top.yperc);
96 f = ThemeFileFind(bg->bg.file);
101 f3 = (int)moddate(f);
109 f = ThemeFileFind(bg->top.file);
114 f6 = (int)moddate(f);
118 Esnprintf(s, sizeof(s),
119 "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c"
120 "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c"
121 "%c%c%c%c%c%c" "%c%c%c%c%c%c" "%c%c%c%c%c%c",
122 chmap[(n1 >> 0) & 0x3f], chmap[(n1 >> 6) & 0x3f],
123 chmap[(n1 >> 12) & 0x3f], chmap[(n1 >> 18) & 0x3f],
124 chmap[(n1 >> 24) & 0x3f], chmap[(n1 >> 28) & 0x3f],
125 chmap[(n2 >> 0) & 0x3f], chmap[(n2 >> 6) & 0x3f],
126 chmap[(n2 >> 12) & 0x3f], chmap[(n2 >> 18) & 0x3f],
127 chmap[(n2 >> 24) & 0x3f], chmap[(n2 >> 28) & 0x3f],
128 chmap[(n3 >> 0) & 0x3f], chmap[(n3 >> 6) & 0x3f],
129 chmap[(n3 >> 12) & 0x3f], chmap[(n3 >> 18) & 0x3f],
130 chmap[(n3 >> 24) & 0x3f], chmap[(n3 >> 28) & 0x3f],
131 chmap[(n4 >> 0) & 0x3f], chmap[(n4 >> 6) & 0x3f],
132 chmap[(n4 >> 12) & 0x3f], chmap[(n4 >> 18) & 0x3f],
133 chmap[(n4 >> 24) & 0x3f], chmap[(n4 >> 28) & 0x3f],
134 chmap[(n5 >> 0) & 0x3f], chmap[(n5 >> 6) & 0x3f],
135 chmap[(n5 >> 12) & 0x3f], chmap[(n5 >> 18) & 0x3f],
136 chmap[(n5 >> 24) & 0x3f], chmap[(n5 >> 28) & 0x3f],
137 chmap[(f1 >> 0) & 0x3f], chmap[(f1 >> 6) & 0x3f],
138 chmap[(f1 >> 12) & 0x3f], chmap[(f1 >> 18) & 0x3f],
139 chmap[(f1 >> 24) & 0x3f], chmap[(f1 >> 28) & 0x3f],
140 chmap[(f2 >> 0) & 0x3f], chmap[(f2 >> 6) & 0x3f],
141 chmap[(f2 >> 12) & 0x3f], chmap[(f2 >> 18) & 0x3f],
142 chmap[(f2 >> 24) & 0x3f], chmap[(f2 >> 28) & 0x3f],
143 chmap[(f3 >> 0) & 0x3f], chmap[(f3 >> 6) & 0x3f],
144 chmap[(f3 >> 12) & 0x3f], chmap[(f3 >> 18) & 0x3f],
145 chmap[(f3 >> 24) & 0x3f], chmap[(f3 >> 28) & 0x3f],
146 chmap[(f4 >> 0) & 0x3f], chmap[(f4 >> 6) & 0x3f],
147 chmap[(f4 >> 12) & 0x3f], chmap[(f4 >> 18) & 0x3f],
148 chmap[(f4 >> 24) & 0x3f], chmap[(f4 >> 28) & 0x3f],
149 chmap[(f5 >> 0) & 0x3f], chmap[(f5 >> 6) & 0x3f],
150 chmap[(f5 >> 12) & 0x3f], chmap[(f5 >> 18) & 0x3f],
151 chmap[(f5 >> 24) & 0x3f], chmap[(f5 >> 28) & 0x3f],
152 chmap[(f6 >> 0) & 0x3f], chmap[(f6 >> 6) & 0x3f],
153 chmap[(f6 >> 12) & 0x3f], chmap[(f6 >> 18) & 0x3f],
154 chmap[(f6 >> 24) & 0x3f], chmap[(f6 >> 28) & 0x3f]);
159 BackgroundPixmapSet(Background * bg, Pixmap pmap)
161 if (bg->pmap != None && bg->pmap != pmap)
162 Eprintf("*** BackgroundPixmapSet %s: pmap was set %#lx/%#lx\n",
163 bg->name, bg->pmap, pmap);
168 BackgroundPixmapFree(Background * bg)
172 EImagePixmapsFree(bg->pmap, None);
178 BackgroundImagesFree(Background * bg)
182 EImageFree(bg->bg.im);
187 EImageFree(bg->top.im);
194 BackgroundImagesKeep(Background * bg, int onoff)
203 BackgroundImagesFree(bg);
206 #endif /* ENABLE_DIALOGS */
209 BackgroundFilesRemove(Background * bg)
214 Efree(bg->bg.real_file);
215 bg->bg.real_file = NULL;
220 Efree(bg->top.real_file);
221 bg->top.real_file = NULL;
223 BackgroundImagesFree(bg);
229 BackgroundDestroy(Background * bg)
234 if (bg->ref_count > 0)
236 DialogOK("Background Error!", _("%u references remain\n"),
241 ecore_list_node_remove(bg_list, bg);
243 BackgroundFilesRemove(bg);
244 BackgroundPixmapFree(bg);
255 BackgroundDelete(Background * bg)
259 if (BackgroundDestroy(bg))
262 /* And delete the actual image files */
265 f = ThemeFileFind(bg->bg.file);
274 f = ThemeFileFind(bg->top.file);
282 #endif /* ENABLE_DIALOGS */
285 BackgroundCreate(const char *name, EColor * solid, const char *bgn, char tile,
286 char keep_aspect, int xjust, int yjust, int xperc,
287 int yperc, const char *top, char tkeep_aspect, int txjust,
288 int tyjust, int txperc, int typerc)
292 bg = ECALLOC(Background, 1);
296 bg->name = Estrdup(name);
298 SET_COLOR(&(bg->bg_solid), 160, 160, 160);
300 bg->bg_solid = *solid;
304 bg->bg.file = Estrdup(bgn);
306 bg->bg.keep_aspect = keep_aspect;
307 bg->bg.xjust = xjust;
308 bg->bg.yjust = yjust;
309 bg->bg.xperc = xperc;
310 bg->bg.yperc = yperc;
313 bg->top.file = Estrdup(top);
314 bg->top.keep_aspect = tkeep_aspect;
315 bg->top.xjust = txjust;
316 bg->top.yjust = tyjust;
317 bg->top.xperc = txperc;
318 bg->top.yperc = typerc;
320 bg->seq_no = ++bg_seq_no;
323 bg_list = ecore_list_new();
324 ecore_list_prepend(bg_list, bg);
330 BackgroundCmp(Background * bg, Background * bgx)
332 if (*bgx->name != '.') /* Discard only generated backgrounds */
335 if (bg->bg.file && bgx->bg.file)
337 if ((strcmp(bg->bg.file, bgx->bg.file)) ||
338 (bg->bg.keep_aspect != bgx->bg.keep_aspect) ||
339 (bg->bg.xjust != bgx->bg.xjust || bg->bg.xjust != bgx->bg.xjust) ||
340 (bg->bg.xperc != bgx->bg.xperc || bg->bg.xperc != bgx->bg.xperc))
343 else if (bg->bg.file || bgx->bg.file)
346 if (bg->top.file && bgx->top.file)
348 if ((strcmp(bg->top.file, bgx->top.file)) ||
349 (bg->top.keep_aspect != bgx->top.keep_aspect) ||
350 (bg->top.xjust != bgx->top.xjust ||
351 bg->top.xjust != bgx->top.xjust) ||
352 (bg->top.xperc != bgx->top.xperc ||
353 bg->top.xperc != bgx->top.xperc))
356 else if (bg->top.file || bgx->top.file)
359 if ((bg->bg_solid.red != bgx->bg_solid.red) ||
360 (bg->bg_solid.green != bgx->bg_solid.green) ||
361 (bg->bg_solid.blue != bgx->bg_solid.blue))
363 if (bg->bg_tile != bgx->bg_tile)
370 _BackgroundMatchName(const void *data, const void *match)
372 return strcmp(((const Background *)data)->name, (const char *)match);
376 BackgroundFind(const char *name)
378 return (Background *) ecore_list_find(bg_list, _BackgroundMatchName, name);
382 BackgroundCheck(Background * bg)
384 return (Background *) ecore_list_goto(bg_list, bg);
388 BackgroundDestroyByName(const char *name)
390 BackgroundDestroy(BackgroundFind(name));
394 BackgroundInvalidate(Background * bg, int refresh)
396 BackgroundPixmapFree(bg);
397 bg->seq_no = ++bg_seq_no;
398 if (bg->ref_count && refresh)
399 DesksBackgroundRefresh(bg, DESK_BG_REFRESH);
403 BackgroundModify(Background * bg, EColor * solid, const char *bgn, char tile,
404 char keep_aspect, int xjust, int yjust, int xperc,
405 int yperc, const char *top, char tkeep_aspect, int txjust,
406 int tyjust, int txperc, int typerc)
410 if (solid->red != bg->bg_solid.red)
412 if (solid->green != bg->bg_solid.green)
414 if (solid->blue != bg->bg_solid.blue)
416 bg->bg_solid = *solid;
418 if ((bg->bg.file) && (bgn))
420 if (strcmp(bg->bg.file, bgn))
426 bg->bg.file = (bgn[0]) ? Estrdup(bgn) : NULL;
427 if ((int)tile != bg->bg_tile)
429 if ((int)keep_aspect != bg->bg.keep_aspect)
431 if (xjust != bg->bg.xjust)
433 if (yjust != bg->bg.yjust)
435 if (xperc != bg->bg.xperc)
437 if (yperc != bg->bg.yperc)
439 bg->bg_tile = (char)tile;
440 bg->bg.keep_aspect = (char)keep_aspect;
441 bg->bg.xjust = xjust;
442 bg->bg.yjust = yjust;
443 bg->bg.xperc = xperc;
444 bg->bg.yperc = yperc;
446 if ((bg->top.file) && (top))
448 if (strcmp(bg->top.file, top))
454 bg->top.file = (top[0]) ? Estrdup(top) : NULL;
455 if ((int)tkeep_aspect != bg->top.keep_aspect)
457 if (txjust != bg->top.xjust)
459 if (tyjust != bg->top.yjust)
461 if (txperc != bg->top.xperc)
463 if (typerc != bg->top.yperc)
465 bg->top.keep_aspect = (char)tkeep_aspect;
466 bg->top.xjust = txjust;
467 bg->top.yjust = tyjust;
468 bg->top.xperc = txperc;
469 bg->top.yperc = typerc;
472 BackgroundInvalidate(bg, 1);
478 BgFindImageSize(BgPart * bgp, unsigned int rw, unsigned int rh,
479 unsigned int *pw, unsigned int *ph)
483 EImageGetSize(bgp->im, &iw, &ih);
485 #if 0 /* FIXME - Remove? */
486 if (bgp->keep_aspect)
487 bgp->xperc = bgp->yperc;
491 w = (rw * bgp->xperc) >> 10;
493 w = (iw * rw) / WinGetW(VROOT);
496 h = (rh * bgp->yperc) >> 10;
498 h = (ih * rh) / WinGetH(VROOT);
505 if (bgp->keep_aspect)
509 if (((w << 10) / h) != ((iw << 10) / ih))
514 if (((h << 10) / w) != ((ih << 10) / iw))
519 *pw = (unsigned int)w;
520 *ph = (unsigned int)h;
524 BackgroundCreatePixmap(Win win, unsigned int w, unsigned int h)
529 * Stupid hack to avoid that a new root pixmap has the same ID as the now
530 * invalid one from a previous session.
532 pmap = ECreatePixmap(win, w, h, 0);
533 if (win == RROOT && pmap == Mode.root.ext_pmap)
536 pmap = ECreatePixmap(win, w, h, 0);
537 Mode.root.ext_pmap = None;
538 Mode.root.ext_pmap_valid = 0;
544 BackgroundRealize(Background * bg, Win win, Drawable draw, unsigned int rw,
545 unsigned int rh, int is_win, Pixmap * ppmap,
546 unsigned long *ppixel)
555 if (bg->bg.file && !bg->bg.im)
557 if (!bg->bg.real_file)
558 bg->bg.real_file = ThemeFileFind(bg->bg.file);
559 if (bg->bg.real_file)
560 bg->bg.im = EImageLoad(bg->bg.real_file);
563 if (bg->top.file && !bg->top.im)
565 if (!bg->top.real_file)
566 bg->top.real_file = ThemeFileFind(bg->top.file);
567 if (bg->top.real_file)
568 bg->top.im = EImageLoad(bg->top.real_file);
572 draw = WinGetXwin(win);
574 hasbg = bg->bg.im != NULL;
575 hasfg = bg->top.im != NULL;
577 if (!hasbg && !hasfg)
579 /* Solid color only */
580 EAllocColor(WinGetCmap(VROOT), &bg->bg_solid);
584 gc = EXCreateGC(draw, 0, NULL);
585 XSetClipMask(disp, gc, 0);
586 XSetFillStyle(disp, gc, FillSolid);
587 XSetForeground(disp, gc, bg->bg_solid.pixel);
588 XFillRectangle(disp, draw, gc, 0, 0, rw, rh);
594 *ppixel = bg->bg_solid.pixel;
598 /* Has either bg or fg image */
604 BgFindImageSize(&(bg->bg), rw, rh, &w, &h);
605 x = ((int)(rw - w) * bg->bg.xjust) >> 10;
606 y = ((int)(rh - h) * bg->bg.yjust) >> 10;
609 if (is_win && hasbg && !hasfg && x == 0 && y == 0 &&
610 ((w == rw && h == rh) || (bg->bg_tile && !TransparencyEnabled())))
612 /* Window, no fg, no offset, and scale to 100%, or tiled, no trans */
613 pmap = BackgroundCreatePixmap(win, w, h);
614 EImageRenderOnDrawable(bg->bg.im, win, pmap, EIMAGE_ANTI_ALIAS,
617 #if 0 /* FIXME - Remove? */
618 if (x == 0 && y == 0) /* Hmmm. Always true. */
620 ESetWindowBackgroundPixmap(draw, pmap);
624 gc = EXCreateGC(draw, 0, NULL);
625 XSetTile(disp, gc, pmap);
626 XSetTSOrigin(disp, gc, x, y);
627 XSetFillStyle(disp, gc, FillTiled);
628 XFillRectangle(disp, draw, gc, 0, 0, rw, rh);
635 /* The rest that require some more work */
637 pmap = BackgroundCreatePixmap(win, rw, rh);
641 if (hasbg && !hasfg && x == 0 && y == 0 && w == rw && h == rh)
647 /* Create full size image */
648 im = EImageCreate(rw, rh);
649 EImageSetHasAlpha(im, 0);
650 if (!hasbg || !bg->bg_tile)
653 EImageFill(im, 0, 0, rw, rh, bg->bg_solid.red, bg->bg_solid.green,
654 bg->bg_solid.blue, 255);
660 EImageTile(im, bg->bg.im, 0, w, h, 0, 0, rw, rh, x, y);
664 EImageGetSize(bg->bg.im, &ww, &hh);
665 EImageBlend(im, bg->bg.im, EIMAGE_ANTI_ALIAS, 0, 0, ww, hh,
673 EImageGetSize(bg->top.im, &ww, &hh);
675 BgFindImageSize(&(bg->top), rw, rh, &w, &h);
676 x = ((rw - w) * bg->top.xjust) >> 10;
677 y = ((rh - h) * bg->top.yjust) >> 10;
679 EImageBlend(im, bg->top.im, EIMAGE_BLEND | EIMAGE_ANTI_ALIAS,
680 0, 0, ww, hh, x, y, w, h, 0);
683 EImageRenderOnDrawable(im, win, pmap, EIMAGE_ANTI_ALIAS, 0, 0, rw, rh);
689 BackgroundImagesFree(bg);
698 BackgroundApplyPmap(Background * bg, Win win, Drawable draw,
699 unsigned int w, unsigned int h)
701 BackgroundRealize(bg, win, draw, w, h, 0, NULL, NULL);
705 BackgroundApplyWin(Background * bg, Win win)
711 if (!EGetGeometry(win, NULL, NULL, NULL, &w, &h, NULL, NULL))
714 BackgroundRealize(bg, win, None, w, h, 1, &pmap, &pixel);
717 ESetWindowBackgroundPixmap(win, pmap);
718 EImagePixmapsFree(pmap, None);
722 ESetWindowBackground(win, pixel);
728 * Apply a background to window.
729 * The BG pixmap is stored in bg->pmap.
732 BackgroundSet(Background * bg, Win win, unsigned int w, unsigned int h)
735 unsigned long pixel = 0;
740 BackgroundRealize(bg, win, None, w, h, 1, &pmap, &pixel);
744 ESetWindowBackgroundPixmap(win, pmap);
746 ESetWindowBackground(win, pixel);
751 BrackgroundCreateFromImage(const char *bgid, const char *file,
752 char *thumb, int thlen)
757 char tile = 1, keep_asp = 0;
759 int scalex = 0, scaley = 0;
762 int maxw = 48, maxh = 48;
763 int justx = 512, justy = 512;
765 bg = BackgroundFind(bgid);
769 Esnprintf(thumb, thlen, "%s/cached/img/%s.png", EDirUserCache(), bgid);
770 if (bg && exists(thumb) && moddate(thumb) > moddate(file))
772 /* The thumbnail is gone or outdated - regererate */
780 im = EImageLoad(file);
784 EImageGetSize(im, &width, &height);
789 w2 = (width * h2) / height;
793 h2 = (height * w2) / width;
795 im2 = EImageCreateScaled(im, 0, 0, width, height, w2, h2);
796 EImageSave(im2, thumb);
802 /* Quit if the background itself already exists */
806 scr_asp = (WinGetW(VROOT) << 16) / WinGetH(VROOT);
807 im_asp = (width << 16) / height;
817 else if ((!(IN_RANGE(scr_asp, im_asp, 16000)))
818 && ((width < 480) && (height < 360)))
827 else if (IN_RANGE(scr_asp, im_asp, 16000))
836 else if (im_asp > scr_asp)
855 SET_COLOR(&color, 0, 0, 0);
857 bg = BackgroundCreate(bgid, &color, file, tile,
858 keep_asp, justx, justy,
859 scalex, scaley, NULL, 0, 0, 0, 0, 0);
865 BackgroundIncRefcount(Background * bg)
873 BackgroundDecRefcount(Background * bg)
878 if (bg->ref_count <= 0)
879 bg->last_viewed = 0; /* Clean out asap */
883 BackgroundTouch(Background * bg)
887 bg->last_viewed = time(NULL);
891 BackgroundGetName(const Background * bg)
898 BackgroundGetBgFile(const Background * bg)
904 BackgroundGetFgFile(const Background * bg)
908 #endif /* ENABLE_DIALOGS */
911 BackgroundGetPixmap(const Background * bg)
913 return (bg) ? bg->pmap : None;
917 BackgroundGetSeqNo(const Background * bg)
923 BackgroundIsNone(const Background * bg)
925 return (bg) ? bg->external : 1;
930 BackgroundCacheMini(Background * bg, int keep, int nuke)
936 Esnprintf(s, sizeof(s), "%s/cached/bgsel/%s.png", EDirUserCache(),
937 BackgroundGetName(bg));
948 /* Create new cached bg mini image */
949 pmap = ECreatePixmap(VROOT, 64, 48, 0);
950 BackgroundApplyPmap(bg, VROOT, pmap, 64, 48);
951 im = EImageGrabDrawable(pmap, None, 0, 0, 64, 48, 0);
961 #endif /* ENABLE_DIALOGS */
963 #define S(str) ((str) ? str : "(null)")
965 BackgroundGetInfoString1(const Background * bg, char *buf, int len)
969 GET_COLOR(&(bg->bg_solid), r, g, b);
971 "%s ref_count %u keepim %u\n"
972 " bg.solid\t %i %i %i \n"
976 " bg.keep_aspect\t %i \ttop.keep_aspect\t %i \n"
977 " bg.xjust\t %i \ttop.xjust\t %i \n"
978 " bg.yjust\t %i \ttop.yjust\t %i \n"
979 " bg.xperc\t %i \ttop.xperc\t %i \n"
980 " bg.yperc\t %i \ttop.yperc\t %i \n", bg->name,
981 bg->ref_count, bg->keepim, r, g, b,
982 bg->bg.file, bg->top.file, bg->bg_tile,
983 bg->bg.keep_aspect, bg->top.keep_aspect,
984 bg->bg.xjust, bg->top.xjust, bg->bg.yjust,
985 bg->top.yjust, bg->bg.xperc, bg->top.xperc,
986 bg->bg.yperc, bg->top.yperc);
990 BackgroundGetInfoString2(const Background * bg, char *buf, int len)
994 GET_COLOR(&(bg->bg_solid), r, g, b);
996 "%s %i %i %i %s %i %i %i %i %i %i %s %i %i %i %i %i",
997 bg->name, r, g, b, S(bg->bg.file), bg->bg_tile,
998 bg->bg.keep_aspect, bg->bg.xjust, bg->bg.yjust,
999 bg->bg.xperc, bg->bg.yperc, S(bg->top.file),
1000 bg->top.keep_aspect, bg->top.xjust, bg->top.yjust,
1001 bg->top.xperc, bg->top.yperc);
1005 BackgroundsInvalidate(int refresh)
1009 ECORE_LIST_FOR_EACH(bg_list, bg) BackgroundInvalidate(bg, refresh);
1013 BackgroundGetRandom(void)
1019 num = ecore_list_count(bg_list);
1023 bg = (Background *) ecore_list_index_goto(bg_list, rnd % num);
1024 if (num <= 1 || !BackgroundIsNone(bg))
1032 BackgroundSetForDesk(Background * bg, unsigned int desk)
1034 if (desk >= N_BG_ASSIGNED)
1037 bg_assigned[desk] = bg;
1041 BackgroundGetForDesk(unsigned int desk)
1045 if (desk >= N_BG_ASSIGNED)
1048 bg = bg_assigned[desk];
1050 bg = BackgroundCheck(bg);
1052 bg = BackgroundGetRandom();
1063 BackgroundsConfigLoad(FILE * fs)
1068 char s[FILEPATH_LEN_MAX];
1069 char s2[FILEPATH_LEN_MAX];
1072 int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
1073 int j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0;
1080 SET_COLOR(&color, 0, 0, 0);
1082 while (GetLine(s, sizeof(s), fs))
1084 ii1 = ConfigParseline1(s, s2, NULL, NULL);
1088 if (!ignore && !bg && name)
1089 bg = BackgroundCreate(name, &color, bg1, i1, i2, i3, i4, i5,
1090 i6, bg2, j1, j2, j3, j4, j5);
1093 case CONFIG_COLORMOD:
1094 case ICLASS_COLORMOD:
1097 case CONFIG_CLASSNAME:
1099 bg = BackgroundFind(s2);
1112 if (!ignore && !bg && name)
1113 bg = BackgroundCreate(name, &color, bg1, i1, i2, i3, i4, i5,
1114 i6, bg2, j1, j2, j3, j4, j5);
1118 if (desk >= N_BG_ASSIGNED)
1122 if (!bg_assigned[desk] || Conf.backgrounds.user)
1124 bg_assigned[desk] = bg;
1131 for (ii1 = 0; ii1 < N_BG_ASSIGNED; ii1++)
1133 if (!bg_assigned[ii1])
1134 bg_assigned[ii1] = bg;
1141 sscanf(s, "%*s %d %d %d", &r, &g, &b);
1142 SET_COLOR(&color, r, g, b);
1144 bg->bg_solid = color;
1148 sscanf(s, "%*s %4000s %d %d %d %d %d %d", s2, &i1, &i2,
1149 &i3, &i4, &i5, &i6);
1158 Efree(bg->top.file);
1159 bg->top.file = NULL;
1160 bg->bg.file = Estrdup(s2);
1162 bg->bg.keep_aspect = i2;
1171 sscanf(s, "%*s %4000s %d %d %d %d %d", s2, &j1, &j2, &j3,
1180 bg->top.file = Estrdup(s2);
1181 bg->top.keep_aspect = j1;
1204 BackgroundsConfigLoadUser(void)
1208 Esnprintf(s, sizeof(s), "%s.backgrounds", EGetSavePrefix());
1210 Mode.backgrounds.force_scan = 1;
1211 ConfigFileLoad(s, NULL, ConfigFileRead, 0);
1215 BackgroundsConfigSave(void)
1217 char s[FILEPATH_LEN_MAX], st[FILEPATH_LEN_MAX];
1221 int i, num, r, g, b;
1223 num = ecore_list_count(bg_list);
1228 fs = fopen(st, "w");
1232 for (i = num - 1; i >= 0; i--)
1234 bg = (Background *) ecore_list_index_goto(bg_list, i);
1238 fprintf(fs, "5 999\n");
1240 fprintf(fs, "100 %s\n", bg->name);
1241 GET_COLOR(&(bg->bg_solid), r, g, b);
1242 fprintf(fs, "560 %d %d %d\n", r, g, b);
1244 if ((bg->bg.file) && (!bg->bg.real_file))
1245 bg->bg.real_file = ThemeFileFind(bg->bg.file);
1247 if ((bg->top.file) && (!bg->top.real_file))
1248 bg->top.real_file = ThemeFileFind(bg->top.file);
1250 if ((bg->bg.file) && (bg->bg.real_file))
1252 fprintf(fs, "561 %s %d %d %d %d %d %d\n",
1253 bg->bg.real_file, bg->bg_tile,
1254 bg->bg.keep_aspect, bg->bg.xjust,
1255 bg->bg.yjust, bg->bg.xperc, bg->bg.yperc);
1257 else if (bg->bg.file)
1259 fprintf(fs, "561 %s %d %d %d %d %d %d\n",
1260 bg->bg.file, bg->bg_tile,
1261 bg->bg.keep_aspect, bg->bg.xjust,
1262 bg->bg.yjust, bg->bg.xperc, bg->bg.yperc);
1265 if ((bg->top.file) && (bg->top.real_file))
1267 fprintf(fs, "562 %s %d %d %d %d %d\n",
1269 bg->top.keep_aspect, bg->top.xjust,
1270 bg->top.yjust, bg->top.xperc, bg->top.yperc);
1272 else if (bg->top.file)
1274 fprintf(fs, "562 %s %d %d %d %d %d\n",
1275 bg->top.file, bg->top.keep_aspect,
1276 bg->top.xjust, bg->top.yjust, bg->top.xperc,
1280 for (j = 0; j < N_BG_ASSIGNED; j++)
1282 if (bg == bg_assigned[j])
1283 fprintf(fs, "564 %d\n", j);
1286 fprintf(fs, "1000\n");
1291 Esnprintf(s, sizeof(s), "%s.backgrounds", EGetSavePrefix());
1296 * Backgrounds module
1300 BackgroundsCheckDups(void)
1303 Background *bg, *bgx;
1307 ecore_list_index_goto(bg_list, ix);
1308 bg = (Background *) ecore_list_next(bg_list);
1311 for (; (bgx = (Background *) ecore_list_next(bg_list)) != NULL;)
1313 if (bgx->ref_count > 0 || bgx->referenced)
1316 if (BackgroundCmp(bg, bgx))
1319 Eprintf("Remove duplicate background %s (==%s)\n", bgx->name,
1322 BackgroundDestroy(bgx);
1328 BackgroundsAccounting(void)
1333 DesksBackgroundRefresh(NULL, DESK_BG_TIMEOUT);
1336 ECORE_LIST_FOR_EACH(bg_list, bg)
1338 /* Skip if no pixmap or not timed out */
1339 if (bg->pmap == None ||
1340 ((now - bg->last_viewed) <= Conf.backgrounds.timeout))
1343 DesksBackgroundRefresh(bg, DESK_BG_FREE);
1344 BackgroundPixmapFree(bg);
1349 BackgroundsTimeout(void *data __UNUSED__)
1351 if (Conf.backgrounds.timeout <= 0)
1352 Conf.backgrounds.timeout = 1;
1354 BackgroundsAccounting();
1356 TimerSetInterval(bg_timer, 1.0 * Conf.backgrounds.timeout);
1362 BackgroundsSighan(int sig, void *prm __UNUSED__)
1367 EDirMake(EDirUserCache(), "cached/bgsel");
1368 EDirMake(EDirUserCache(), "cached/img");
1369 /* create a fallback background in case no background is found */
1370 BackgroundCreate("NONE", NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, 0, 0, 0, 0,
1374 case ESIGNAL_CONFIGURE:
1375 BackgroundsConfigLoadUser();
1376 BackgroundsCheckDups();
1377 StartupBackgroundsDestroy();
1381 TIMER_ADD(bg_timer, 30.0, BackgroundsTimeout, NULL);
1385 if (Mode.wm.save_ok)
1386 BackgroundsConfigSave();
1393 * Configuration dialog
1395 static Dialog *bg_sel_dialog;
1396 static DItem *bg_sel;
1397 static DItem *bg_sel_slider;
1398 static DItem *bg_mini_disp;
1399 static DItem *bg_filename;
1400 static DItem *tmp_w[10];
1402 static Background *tmp_bg; /* The background being configured */
1403 static int tmp_bg_sel_sliderval;
1404 static int tmp_bg_sel_sliderval_old;
1405 static int tmp_bg_r;
1406 static int tmp_bg_g;
1407 static int tmp_bg_b;
1408 static char tmp_bg_image;
1409 static char tmp_bg_tile;
1410 static char tmp_bg_keep_aspect;
1411 static int tmp_bg_xjust;
1412 static int tmp_bg_yjust;
1413 static int tmp_bg_xperc;
1414 static int tmp_bg_yperc;
1415 static char tmp_hiq;
1416 static char tmp_userbg;
1417 static char tmp_root_hint;
1418 static int tmp_bg_timeout;
1420 static void BG_RedrawView(void);
1421 static void BGSettingsGoTo(Background * bg);
1424 CB_ConfigureBG(Dialog * d __UNUSED__, int val, void *data __UNUSED__)
1428 bg_sel = bg_sel_slider = bg_mini_disp = bg_filename = NULL;
1429 memset(tmp_w, 0, sizeof(tmp_w));
1430 BackgroundImagesKeep(tmp_bg, 0);
1437 Conf.backgrounds.timeout = tmp_bg_timeout;
1438 Conf.backgrounds.hiquality = tmp_hiq;
1439 Conf.backgrounds.user = tmp_userbg;
1440 Conf.hints.set_xroot_info_on_root_window = tmp_root_hint;
1442 SET_COLOR(&(tmp_bg->bg_solid), tmp_bg_r, tmp_bg_g, tmp_bg_b);
1443 tmp_bg->bg_tile = tmp_bg_tile;
1444 tmp_bg->bg.keep_aspect = tmp_bg_keep_aspect;
1445 tmp_bg->bg.xjust = tmp_bg_xjust;
1446 tmp_bg->bg.yjust = tmp_bg_yjust;
1447 tmp_bg->bg.xperc = tmp_bg_xperc;
1448 tmp_bg->bg.yperc = tmp_bg_yperc;
1450 BackgroundFilesRemove(tmp_bg);
1452 BackgroundInvalidate(tmp_bg, 1);
1454 BackgroundCacheMini(tmp_bg, 0, 1);
1461 /* Draw the background preview image */
1463 CB_DesktopMiniDisplayRedraw(Dialog * d __UNUSED__, int val __UNUSED__,
1472 const char *fbg, *ffg;
1477 di = (DItem *) data;
1478 win = DialogItemAreaGetWindow(di);
1479 DialogItemAreaGetSize(di, &w, &h);
1481 pmap = EGetWindowBackgroundPixmap(win);
1482 fbg = (tmp_bg_image) ? BackgroundGetBgFile(tmp_bg) : NULL;
1483 ffg = (tmp_bg_image) ? BackgroundGetFgFile(tmp_bg) : NULL;
1484 SET_COLOR(&color, tmp_bg_r, tmp_bg_g, tmp_bg_b);
1485 bg = BackgroundCreate("TEMP", &color,
1486 fbg, tmp_bg_tile, tmp_bg_keep_aspect,
1487 tmp_bg_xjust, tmp_bg_yjust,
1488 tmp_bg_xperc, tmp_bg_yperc,
1489 ffg, tmp_bg->top.keep_aspect,
1490 tmp_bg->top.xjust, tmp_bg->top.yjust,
1491 tmp_bg->top.xperc, tmp_bg->top.yperc);
1493 BackgroundApplyPmap(bg, win, pmap, w, h);
1494 BackgroundDestroy(bg);
1498 /* Update tmp vars according to the current tmp_bg */
1502 tmp_bg_image = (tmp_bg->bg.file) ? 1 : 0;
1504 GET_COLOR(&(tmp_bg->bg_solid), tmp_bg_r, tmp_bg_g, tmp_bg_b);
1505 tmp_bg_tile = tmp_bg->bg_tile;
1506 tmp_bg_keep_aspect = tmp_bg->bg.keep_aspect;
1507 tmp_bg_xjust = tmp_bg->bg.xjust;
1508 tmp_bg_yjust = tmp_bg->bg.yjust;
1509 tmp_bg_xperc = tmp_bg->bg.xperc;
1510 tmp_bg_yperc = tmp_bg->bg.yperc;
1514 BG_DialogSetFileName(DItem * di)
1519 stmp = fullfileof(BackgroundGetBgFile(tmp_bg));
1520 Esnprintf(s, sizeof(s),
1521 _("Background definition information:\nName: %s\nFile: %s\n"),
1522 BackgroundGetName(tmp_bg), (stmp) ? stmp : _("-NONE-"));
1523 DialogItemSetText(di, s);
1527 BgDialogSetNewCurrent(Background * bg)
1531 if (tmp_bg && tmp_bg != bg)
1532 BackgroundImagesKeep(tmp_bg, 0);
1534 BackgroundImagesKeep(tmp_bg, 1);
1536 /* Fetch new BG values */
1539 /* Update dialog items */
1540 BG_DialogSetFileName(bg_filename);
1541 DialogDrawItems(bg_sel_dialog, bg_filename, 0, 0, 99999, 99999);
1543 DialogItemCheckButtonSetState(tmp_w[0], tmp_bg_image);
1544 DialogItemCheckButtonSetState(tmp_w[1], tmp_bg_keep_aspect);
1545 DialogItemCheckButtonSetState(tmp_w[2], tmp_bg_tile);
1546 DialogItemSliderSetVal(tmp_w[3], tmp_bg_r);
1547 DialogItemSliderSetVal(tmp_w[4], tmp_bg_g);
1548 DialogItemSliderSetVal(tmp_w[5], tmp_bg_b);
1549 DialogItemSliderSetVal(tmp_w[6], tmp_bg_xjust);
1550 DialogItemSliderSetVal(tmp_w[7], tmp_bg_yjust);
1551 DialogItemSliderSetVal(tmp_w[8], tmp_bg_yperc);
1552 DialogItemSliderSetVal(tmp_w[9], tmp_bg_xperc);
1554 /* Redraw mini BG display */
1555 CB_DesktopMiniDisplayRedraw(NULL, 0, bg_mini_disp);
1557 /* Redraw scrolling BG list */
1560 for (i = 0; i < 10; i++)
1561 DialogDrawItems(bg_sel_dialog, tmp_w[i], 0, 0, 99999, 99999);
1564 /* Duplicate current (tmp_bg) to new */
1566 CB_ConfigureNewBG(Dialog * d __UNUSED__, int val __UNUSED__,
1567 void *data __UNUSED__)
1573 Esnprintf(s, sizeof(s), "__NEWBG_%i", (unsigned)time(NULL));
1575 SET_COLOR(&color, tmp_bg_r, tmp_bg_g, tmp_bg_b);
1577 tmp_bg = BackgroundCreate(s, &color,
1578 tmp_bg->bg.file, tmp_bg_tile, tmp_bg_keep_aspect,
1579 tmp_bg_xjust, tmp_bg_yjust,
1580 tmp_bg_xperc, tmp_bg_yperc,
1581 tmp_bg->top.file, tmp_bg->top.keep_aspect,
1582 tmp_bg->top.xjust, tmp_bg->top.yjust,
1583 tmp_bg->top.xperc, tmp_bg->top.yperc);
1585 DialogItemSliderGetBounds(bg_sel_slider, &lower, &upper);
1587 DialogItemSliderSetBounds(bg_sel_slider, lower, upper);
1589 DialogItemSliderSetVal(bg_sel_slider, 0);
1590 DialogDrawItems(bg_sel_dialog, bg_sel_slider, 0, 0, 99999, 99999);
1592 DeskBackgroundSet(DesksGetCurrent(), tmp_bg);
1600 CB_ConfigureDelBG(Dialog * d __UNUSED__, int val, void *data __UNUSED__)
1604 int slider, lower, upper;
1606 num = ecore_list_count(bg_list);
1610 bg = (Background *) ecore_list_goto(bg_list, tmp_bg);
1614 i = ecore_list_index(bg_list);
1616 (Background *) ecore_list_index_goto(bg_list,
1617 (i < num - 1) ? i + 1 : i - 1);
1619 DeskBackgroundSet(DesksGetCurrent(), bg);
1622 BackgroundDestroy(tmp_bg);
1624 BackgroundDelete(tmp_bg);
1627 DialogItemSliderGetBounds(bg_sel_slider, &lower, &upper);
1628 slider = DialogItemSliderGetVal(bg_sel_slider);
1630 DialogItemSliderSetBounds(bg_sel_slider, lower, upper);
1632 DialogItemSliderSetVal(bg_sel_slider, upper);
1634 BgDialogSetNewCurrent(bg);
1639 /* Move current background to first position in list */
1641 CB_ConfigureFrontBG(Dialog * d __UNUSED__, int val __UNUSED__,
1642 void *data __UNUSED__)
1644 ecore_list_prepend(bg_list, ecore_list_node_remove(bg_list, tmp_bg));
1645 BGSettingsGoTo(tmp_bg);
1650 /* Draw the scrolling background image window */
1658 ImageClass *ic_button;
1660 num = ecore_list_count(bg_list);
1664 win = DialogItemAreaGetWindow(bg_sel);
1665 DialogItemAreaGetSize(bg_sel, &w, &h);
1667 pmap = EGetWindowBackgroundPixmap(win);
1669 ic_button = ImageclassFind("DIALOG_BUTTON", 1);
1671 ImageclassApplySimple(ic_button, win, pmap, STATE_NORMAL, 0, 0, w, h);
1673 x = -(num * (64 + 8) - w) * tmp_bg_sel_sliderval / (4 * num);
1675 ECORE_LIST_FOR_EACH(bg_list, bg)
1677 if (((x + 64 + 8) >= 0) && (x < w))
1681 ImageclassApplySimple(ic_button, win, pmap,
1682 (bg == tmp_bg) ? STATE_CLICKED : STATE_NORMAL,
1683 x, 0, 64 + 8, 48 + 8);
1685 if (BackgroundIsNone(bg))
1689 tc = TextclassFind("DIALOG", 1);
1694 TextSize(tc, 0, 0, STATE_NORMAL,
1695 _("No\nBackground"), &tw, &th, 17);
1696 TextDraw(tc, win, pmap, 0, 0, STATE_NORMAL,
1697 _("No\nBackground"), x + 4,
1698 4 + ((48 - th) / 2), 64, 48, 17, 512);
1703 im = BackgroundCacheMini(bg, 1, 0);
1706 EImageRenderOnDrawable(im, win, pmap, 0, x + 4, 4, 64, 48);
1718 CB_BGAreaSlide(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__)
1720 if (tmp_bg_sel_sliderval == tmp_bg_sel_sliderval_old)
1723 tmp_bg_sel_sliderval_old = tmp_bg_sel_sliderval;
1727 CB_BGScan(Dialog * d, int val __UNUSED__, void *data __UNUSED__)
1731 SoundPlay(SOUND_WAIT);
1733 /* Forcing re-scan should not be necessary but provides the progress bars
1734 * so it actually looks like something is going on */
1735 Mode.backgrounds.force_scan = 1;
1736 ScanBackgroundMenu();
1738 num = ecore_list_count(bg_list);
1739 DialogItemSliderSetBounds(bg_sel_slider, 0, num * 4);
1740 DialogDrawItems(d, bg_sel_slider, 0, 0, 99999, 99999);
1741 DialogItemCallCallback(d, bg_sel_slider);
1745 CB_BGAreaEvent(DItem * di __UNUSED__, int val __UNUSED__, void *data)
1749 XEvent *ev = (XEvent *) data;
1751 DialogItemAreaGetSize(bg_sel, &w, &h);
1756 switch (ev->xbutton.button)
1759 num = ecore_list_count(bg_list);
1760 x = (num * (64 + 8) - w) * tmp_bg_sel_sliderval / (4 * num) +
1762 bg = (Background *) ecore_list_index_goto(bg_list, x / (64 + 8));
1763 if (!bg || bg == DeskBackgroundGet(DesksGetCurrent()))
1765 BgDialogSetNewCurrent(bg);
1766 DeskBackgroundSet(DesksGetCurrent(), bg);
1770 tmp_bg_sel_sliderval += 4;
1773 tmp_bg_sel_sliderval -= 4;
1776 DialogItemSliderSetVal(bg_sel_slider, tmp_bg_sel_sliderval);
1777 CB_BGAreaSlide(NULL, 0, NULL);
1778 DialogDrawItems(bg_sel_dialog, bg_sel_slider, 0, 0, 99999, 99999);
1785 CB_DesktopTimeout(Dialog * d __UNUSED__, int val __UNUSED__, void *data)
1790 di = (DItem *) data;
1791 Esnprintf(s, sizeof(s), _("Unused backgrounds freed after %2i:%02i:%02i"),
1792 tmp_bg_timeout / 3600,
1793 (tmp_bg_timeout / 60) - (60 * (tmp_bg_timeout / 3600)),
1794 (tmp_bg_timeout) - (60 * (tmp_bg_timeout / 60)));
1795 DialogItemSetText(di, s);
1796 DialogDrawItems(bg_sel_dialog, di, 0, 0, 99999, 99999);
1800 BGSettingsGoTo(Background * bg)
1807 bg = (Background *) ecore_list_goto(bg_list, bg);
1811 i = ecore_list_index(bg_list);
1812 num = ecore_list_count(bg_list);
1813 i = ((4 * num + 20) * i) / num - 8;
1816 else if (i > 4 * num)
1818 DialogItemSliderSetVal(bg_sel_slider, i);
1819 DialogDrawItems(bg_sel_dialog, bg_sel_slider, 0, 0, 99999, 99999);
1820 BgDialogSetNewCurrent(bg);
1824 CB_BGNext(Dialog * d __UNUSED__, int val, void *data __UNUSED__)
1828 bg = (Background *) ecore_list_goto(bg_list, tmp_bg);
1833 (Background *) ecore_list_index_goto(bg_list,
1834 ecore_list_index(bg_list) + val);
1839 DeskBackgroundSet(DesksGetCurrent(), bg);
1843 BG_SortFileCompare(void *_bg1, void *_bg2)
1845 Background *bg1 = (Background *) _bg1;
1846 Background *bg2 = (Background *) _bg2;
1847 const char *name1, *name2;
1849 /* return < 0 is b1 < b2 */
1850 /* return > 0 is b1 > b2 */
1851 /* return 0 is b1 == b2 */
1853 name1 = BackgroundGetBgFile(bg1);
1854 name2 = BackgroundGetBgFile(bg2);
1856 return strcmp(name1, name2);
1861 return (bg1 < bg2) ? -1 : 1;
1865 CB_BGSortFile(Dialog * d __UNUSED__, int val __UNUSED__, void *data __UNUSED__)
1867 Background **bglist;
1870 bglist = (Background **) ecore_list_items_get(bg_list, &num);
1874 /* remove them all from the list */
1875 for (i = 0; i < num; i++)
1876 ecore_list_node_remove(bg_list, bglist[i]);
1877 Quicksort((void **)bglist, 0, num - 2, BG_SortFileCompare);
1878 for (i = 0; i < num; i++)
1879 ecore_list_append(bg_list, bglist[i]);
1882 BGSettingsGoTo(tmp_bg);
1888 CB_BGSortAttrib(Dialog * d __UNUSED__, int val __UNUSED__,
1889 void *data __UNUSED__)
1891 Background **bglist;
1894 bglist = (Background **) ecore_list_items_get(bg_list, &num);
1898 /* remove them all from the list */
1899 for (i = 0; i < num; i++)
1900 ecore_list_node_remove(bg_list, bglist[i]);
1901 for (i = 0; i < num; i++)
1906 if ((bg) && (bg->bg_tile) && (bg->bg.xperc == 0) && (bg->bg.yperc == 0))
1908 ecore_list_prepend(bg_list, bg);
1912 for (i = 0; i < num; i++)
1919 ecore_list_prepend(bg_list, bg);
1925 BGSettingsGoTo(tmp_bg);
1930 #if 0 /* Doesn't do anything useful */
1932 CB_BGSortContent(Dialog * d __UNUSED__, int val __UNUSED__,
1933 void *data __UNUSED__)
1935 Background **bglist;
1938 bglist = (Background **) ecore_list_items_get(bg_list, &num);
1942 /* remove them all from the list */
1943 for (i = 0; i < num; i++)
1944 ecore_list_node_remove(bg_list, bglist[i]);
1945 for (i = 0; i < num; i++)
1946 ecore_list_prepend(bg_list, bglist[i]);
1955 CB_DesktopMiniDisplayAreaInit(DItem * di, int val __UNUSED__,
1956 void *data __UNUSED__)
1958 CB_DesktopMiniDisplayRedraw(DialogItemGetDialog(di), 1, di);
1963 CB_InitView(DItem * di __UNUSED__, int val __UNUSED__, void *data __UNUSED__)
1965 tmp_bg_sel_sliderval_old = tmp_bg_sel_sliderval = -1;
1966 BGSettingsGoTo(tmp_bg);
1970 _DlgFillBackground(Dialog * d, DItem * table, void *data)
1972 Background *bg = (Background *) data;
1973 DItem *di, *table2, *table3, *area, *label;
1977 if (!Conf.backgrounds.no_scan)
1978 ScanBackgroundMenu();
1981 bg = DeskBackgroundGet(DesksGetCurrent());
1983 bg = BackgroundFind("NONE");
1988 tmp_hiq = Conf.backgrounds.hiquality;
1989 tmp_userbg = Conf.backgrounds.user;
1990 tmp_root_hint = Conf.hints.set_xroot_info_on_root_window;
1991 tmp_bg_timeout = Conf.backgrounds.timeout;
1995 DialogItemTableSetOptions(table, 1, 0, 0, 0);
1997 table2 = DialogAddItem(table, DITEM_TABLE);
1998 DialogItemTableSetOptions(table2, 2, 0, 1, 0);
2000 di = bg_filename = DialogAddItem(table2, DITEM_TEXT);
2001 DialogItemSetFill(di, 1, 0);
2002 BG_DialogSetFileName(bg_filename);
2004 table3 = DialogAddItem(table2, DITEM_TABLE);
2006 di = tmp_w[0] = DialogAddItem(table3, DITEM_CHECKBUTTON);
2007 DialogItemSetText(di, _("Use background image"));
2008 DialogItemCheckButtonSetPtr(di, &tmp_bg_image);
2010 di = tmp_w[1] = DialogAddItem(table3, DITEM_CHECKBUTTON);
2011 DialogItemSetText(di, _("Keep aspect on scale"));
2012 DialogItemCheckButtonSetPtr(di, &tmp_bg_keep_aspect);
2014 di = tmp_w[2] = DialogAddItem(table3, DITEM_CHECKBUTTON);
2015 DialogItemSetText(di, _("Tile image across background"));
2016 DialogItemCheckButtonSetPtr(di, &tmp_bg_tile);
2018 table2 = DialogAddItem(table, DITEM_TABLE);
2019 DialogItemTableSetOptions(table2, 4, 0, 1, 0);
2020 DialogItemSetFill(table2, 0, 0);
2021 DialogItemSetAlign(table2, 512, 0);
2023 di = DialogAddItem(table2, DITEM_BUTTON);
2024 DialogItemSetText(di, _("Move to Front\n"));
2025 DialogItemSetCallback(di, CB_ConfigureFrontBG, 0, NULL);
2026 DialogBindKey(d, "F", CB_ConfigureFrontBG, 0, NULL);
2028 di = DialogAddItem(table2, DITEM_BUTTON);
2029 DialogItemSetText(di, _("Duplicate\n"));
2030 DialogItemSetCallback(di, CB_ConfigureNewBG, 0, NULL);
2032 di = DialogAddItem(table2, DITEM_BUTTON);
2033 DialogItemSetText(di, _("Unlist\n"));
2034 DialogItemSetCallback(di, CB_ConfigureDelBG, 0, NULL);
2035 DialogBindKey(d, "D", CB_ConfigureDelBG, 0, NULL);
2037 di = DialogAddItem(table2, DITEM_BUTTON);
2038 DialogItemSetText(di, _("Delete File\n"));
2039 DialogItemSetCallback(di, CB_ConfigureDelBG, 1, NULL);
2040 DialogBindKey(d, "Delete", CB_ConfigureDelBG, 1, NULL);
2042 table2 = DialogAddItem(table, DITEM_TABLE);
2043 DialogItemTableSetOptions(table2, 3, 0, 1, 0);
2045 di = DialogAddItem(table2, DITEM_TEXT);
2046 DialogItemSetFill(di, 0, 0);
2047 DialogItemSetAlign(di, 512, 512);
2048 DialogItemSetText(di,
2049 _("Background\n" "Image\n" "Scaling\n" "and\n"
2052 table3 = DialogAddItem(table2, DITEM_TABLE);
2053 DialogItemTableSetOptions(table3, 3, 0, 0, 0);
2055 di = DialogAddItem(table3, DITEM_NONE);
2057 di = tmp_w[6] = DialogAddItem(table3, DITEM_SLIDER);
2058 DialogItemSliderSetMinLength(di, 10);
2059 DialogItemSliderSetBounds(di, 0, 1024);
2060 DialogItemSliderSetUnits(di, 1);
2061 DialogItemSliderSetJump(di, 64);
2062 DialogItemSliderSetValPtr(di, &tmp_bg_xjust);
2064 di = DialogAddItem(table3, DITEM_NONE);
2066 di = tmp_w[7] = DialogAddItem(table3, DITEM_SLIDER);
2067 DialogItemSliderSetMinLength(di, 10);
2068 DialogItemSliderSetOrientation(di, 0);
2069 DialogItemSetFill(di, 0, 1);
2070 DialogItemSliderSetBounds(di, 0, 1024);
2071 DialogItemSliderSetUnits(di, 1);
2072 DialogItemSliderSetJump(di, 64);
2073 DialogItemSliderSetValPtr(di, &tmp_bg_yjust);
2075 di = bg_mini_disp = area = DialogAddItem(table3, DITEM_AREA);
2076 DialogItemAreaSetSize(di, 64, 48);
2078 DialogItemAreaSetInitFunc(di, CB_DesktopMiniDisplayAreaInit);
2081 di = tmp_w[8] = DialogAddItem(table3, DITEM_SLIDER);
2082 DialogItemSliderSetMinLength(di, 10);
2083 DialogItemSliderSetOrientation(di, 0);
2084 DialogItemSetFill(di, 0, 1);
2085 DialogItemSliderSetBounds(di, 0, 1024);
2086 DialogItemSliderSetUnits(di, 1);
2087 DialogItemSliderSetJump(di, 64);
2088 DialogItemSliderSetValPtr(di, &tmp_bg_yperc);
2090 di = DialogAddItem(table3, DITEM_NONE);
2092 di = tmp_w[9] = DialogAddItem(table3, DITEM_SLIDER);
2093 DialogItemSliderSetMinLength(di, 10);
2094 DialogItemSliderSetBounds(di, 0, 1024);
2095 DialogItemSliderSetUnits(di, 1);
2096 DialogItemSliderSetJump(di, 64);
2097 DialogItemSliderSetValPtr(di, &tmp_bg_xperc);
2099 table3 = DialogAddItem(table2, DITEM_TABLE);
2100 DialogItemTableSetOptions(table3, 2, 0, 0, 0);
2102 di = DialogAddItem(table3, DITEM_TEXT);
2103 DialogItemSetColSpan(di, 2);
2104 DialogItemSetFill(di, 0, 0);
2105 DialogItemSetAlign(di, 512, 512);
2106 DialogItemSetText(di, _("BG Colour\n"));
2108 di = DialogAddItem(table3, DITEM_TEXT);
2109 DialogItemSetFill(di, 0, 0);
2110 DialogItemSetAlign(di, 1024, 512);
2111 DialogItemSetText(di, _("Red:\n"));
2113 di = tmp_w[3] = DialogAddItem(table3, DITEM_SLIDER);
2114 DialogItemSliderSetBounds(di, 0, 255);
2115 DialogItemSliderSetUnits(di, 1);
2116 DialogItemSliderSetJump(di, 16);
2117 DialogItemSliderSetValPtr(di, &tmp_bg_r);
2119 di = DialogAddItem(table3, DITEM_TEXT);
2120 DialogItemSetFill(di, 0, 0);
2121 DialogItemSetAlign(di, 1024, 512);
2122 DialogItemSetText(di, _("Green:\n"));
2124 di = tmp_w[4] = DialogAddItem(table3, DITEM_SLIDER);
2125 DialogItemSliderSetBounds(di, 0, 255);
2126 DialogItemSliderSetUnits(di, 1);
2127 DialogItemSliderSetJump(di, 16);
2128 DialogItemSliderSetValPtr(di, &tmp_bg_g);
2130 di = DialogAddItem(table3, DITEM_TEXT);
2131 DialogItemSetFill(di, 0, 0);
2132 DialogItemSetAlign(di, 1024, 512);
2133 DialogItemSetText(di, _("Blue:\n"));
2135 di = tmp_w[5] = DialogAddItem(table3, DITEM_SLIDER);
2136 DialogItemSliderSetBounds(di, 0, 255);
2137 DialogItemSliderSetUnits(di, 1);
2138 DialogItemSliderSetJump(di, 16);
2139 DialogItemSliderSetValPtr(di, &tmp_bg_b);
2141 for (i = 0; i < 10; i++)
2142 DialogItemSetCallback(tmp_w[i], CB_DesktopMiniDisplayRedraw, 0, area);
2144 di = DialogAddItem(table, DITEM_SEPARATOR);
2146 table2 = DialogAddItem(table, DITEM_TABLE);
2147 DialogItemTableSetOptions(table2, 3, 0, 0, 0);
2149 table3 = DialogAddItem(table2, DITEM_TABLE);
2150 DialogItemTableSetOptions(table3, 2, 0, 0, 0);
2152 di = DialogAddItem(table3, DITEM_BUTTON);
2153 DialogItemSetFill(di, 0, 0);
2154 DialogItemSetText(di, "<-");
2155 DialogItemSetCallback(di, CB_BGNext, -1, NULL);
2156 DialogBindKey(d, "Left", CB_BGNext, -1, NULL);
2158 di = DialogAddItem(table3, DITEM_BUTTON);
2159 DialogItemSetFill(di, 0, 0);
2160 DialogItemSetText(di, "->");
2161 DialogItemSetCallback(di, CB_BGNext, 1, NULL);
2162 DialogBindKey(d, "Right", CB_BGNext, 1, NULL);
2164 di = DialogAddItem(table2, DITEM_BUTTON);
2165 DialogItemSetFill(di, 0, 0);
2166 DialogItemSetText(di, _("Pre-scan BG's"));
2167 DialogItemSetCallback(di, CB_BGScan, 0, NULL);
2169 table3 = DialogAddItem(table2, DITEM_TABLE);
2170 DialogItemTableSetOptions(table3, 3, 0, 0, 0);
2172 di = DialogAddItem(table3, DITEM_BUTTON);
2173 DialogItemSetFill(di, 0, 0);
2174 DialogItemSetText(di, _("Sort by File"));
2175 DialogItemSetCallback(di, CB_BGSortFile, 0, NULL);
2177 di = DialogAddItem(table3, DITEM_BUTTON);
2178 DialogItemSetFill(di, 0, 0);
2179 DialogItemSetText(di, _("Sort by Attr."));
2180 DialogItemSetCallback(di, CB_BGSortAttrib, 0, NULL);
2182 #if 0 /* Doesn't do anything useful */
2183 di = DialogAddItem(table3, DITEM_BUTTON);
2184 DialogItemSetFill(di, 0, 0);
2185 DialogItemSetText(di, _("Sort by Image"));
2186 DialogItemSetCallback(di, CB_BGSortContent, 0, NULL);
2189 di = bg_sel = DialogAddItem(table, DITEM_AREA);
2190 DialogItemAreaSetSize(di, 160, 56);
2191 DialogItemAreaSetEventFunc(di, CB_BGAreaEvent);
2192 DialogItemAreaSetInitFunc(di, CB_InitView);
2194 num = ecore_list_count(bg_list);
2195 di = bg_sel_slider = DialogAddItem(table, DITEM_SLIDER);
2196 DialogItemSliderSetBounds(di, 0, num * 4);
2197 DialogItemSliderSetUnits(di, 1);
2198 DialogItemSliderSetJump(di, 9);
2199 DialogItemSliderSetValPtr(di, &tmp_bg_sel_sliderval);
2200 DialogItemSetCallback(bg_sel_slider, CB_BGAreaSlide, 0, NULL);
2202 di = DialogAddItem(table, DITEM_SEPARATOR);
2204 di = DialogAddItem(table, DITEM_CHECKBUTTON);
2205 DialogItemSetText(di, _("Use dithering in Hi-Colour"));
2206 DialogItemCheckButtonSetPtr(di, &tmp_hiq);
2208 di = DialogAddItem(table, DITEM_CHECKBUTTON);
2209 DialogItemSetText(di, _("Background overrides theme"));
2210 DialogItemCheckButtonSetPtr(di, &tmp_userbg);
2212 di = DialogAddItem(table, DITEM_CHECKBUTTON);
2213 DialogItemSetText(di,
2214 _("Enable background transparency compatibility mode"));
2215 DialogItemCheckButtonSetPtr(di, &tmp_root_hint);
2217 di = DialogAddItem(table, DITEM_SEPARATOR);
2219 di = label = DialogAddItem(table, DITEM_TEXT);
2220 DialogItemSetAlign(di, 512, 512);
2221 Esnprintf(s, sizeof(s), _("Unused backgrounds freed after %2i:%02i:%02i"),
2222 tmp_bg_timeout / 3600,
2223 (tmp_bg_timeout / 60) - (60 * (tmp_bg_timeout / 3600)),
2224 (tmp_bg_timeout) - (60 * (tmp_bg_timeout / 60)));
2225 DialogItemSetText(di, s);
2227 di = DialogAddItem(table, DITEM_SLIDER);
2228 DialogItemSliderSetMinLength(di, 10);
2229 DialogItemSliderSetBounds(di, 0, 60 * 60 * 4);
2230 DialogItemSliderSetUnits(di, 30);
2231 DialogItemSliderSetJump(di, 60);
2232 DialogItemSliderSetValPtr(di, &tmp_bg_timeout);
2233 DialogItemSetCallback(di, CB_DesktopTimeout, 0, label);
2236 const DialogDef DlgBackground = {
2239 N_("Desktop Background Settings"),
2242 N_("Enlightenment Desktop\n" "Background Settings Dialog\n"),
2244 DLG_OAC, CB_ConfigureBG,
2247 #endif /* ENABLE_DIALOGS */
2254 BackgroundSet1(const char *name, const char *params)
2256 const char *p = params;
2257 char type[FILEPATH_LEN_MAX];
2265 bg = BackgroundFind(name);
2268 SET_COLOR(&color, 0, 0, 0);
2269 bg = BackgroundCreate(name, &color, NULL, 0, 0, 0,
2270 0, 0, 0, NULL, 0, 0, 0, 0, 0);
2273 IpcPrintf("Error: could not create background '%s'.", name);
2280 sscanf(p, "%400s %n", type, &len);
2284 if (!strcmp(type, "bg.solid"))
2289 sscanf(p, "%i %i %i", &r, &g, &b);
2290 SET_COLOR(&(bg->bg_solid), r, g, b);
2292 else if (!strcmp(type, "bg.file"))
2295 bg->bg.file = Estrdup(p);
2297 else if (!strcmp(type, "bg.tile"))
2299 bg->bg_tile = value;
2301 else if (!strcmp(type, "bg.keep_aspect"))
2303 bg->bg.keep_aspect = value;
2305 else if (!strcmp(type, "bg.xjust"))
2307 bg->bg.xjust = value;
2309 else if (!strcmp(type, "bg.yjust"))
2311 bg->bg.yjust = value;
2313 else if (!strcmp(type, "bg.xperc"))
2315 bg->bg.xperc = value;
2317 else if (!strcmp(type, "bg.yperc"))
2319 bg->bg.yperc = value;
2321 else if (!strcmp(type, "top.file"))
2323 Efree(bg->top.file);
2324 bg->top.file = Estrdup(p);
2326 else if (!strcmp(type, "top.keep_aspect"))
2328 bg->top.keep_aspect = value;
2330 else if (!strcmp(type, "top.xjust"))
2332 bg->top.xjust = value;
2334 else if (!strcmp(type, "top.yjust"))
2336 bg->top.yjust = value;
2338 else if (!strcmp(type, "top.xperc"))
2340 bg->top.xperc = value;
2342 else if (!strcmp(type, "top.yperc"))
2344 bg->top.yperc = value;
2348 IpcPrintf("Error: unknown background value type '%s'.", type);
2354 BackgroundSet2(const char *name, const char *params)
2360 char bgf[FILEPATH_LEN_MAX], topf[FILEPATH_LEN_MAX];
2361 int tile, keep_aspect, tkeep_aspect;
2362 int xjust, yjust, xperc, yperc;
2363 int txjust, tyjust, txperc, typerc;
2368 bgf[0] = topf[0] = '\0';
2371 "%i %i %i %4000s %i %i %i %i %i %i %4000s %i %i %i %i %i",
2373 bgf, &tile, &keep_aspect, &xjust, &yjust, &xperc, &yperc,
2374 topf, &tkeep_aspect, &txjust, &tyjust, &txperc, &typerc);
2375 SET_COLOR(&color, r, g, b);
2377 bg = BackgroundFind(name);
2380 BackgroundModify(bg, &color, bgf, tile, keep_aspect, xjust,
2381 yjust, xperc, yperc, topf, tkeep_aspect,
2382 txjust, tyjust, txperc, typerc);
2386 bg = BackgroundCreate(name, &color, bgf, tile, keep_aspect, xjust,
2387 yjust, xperc, yperc, topf, tkeep_aspect,
2388 txjust, tyjust, txperc, typerc);
2393 BackgroundsIpc(const char *params)
2396 char cmd[128], prm[128], buf[4096];
2397 int i, len, num, len2;
2401 cmd[0] = prm[0] = '\0';
2405 sscanf(p, "%100s %n%100s %n", cmd, &len2, prm, &len);
2409 if (!p || cmd[0] == '?')
2411 for (i = 0; i < (int)DesksGetNumber(); i++)
2413 bg = DeskBackgroundGet(DeskGet(i));
2415 IpcPrintf("%i %s\n", i, BackgroundGetName(bg));
2417 IpcPrintf("%i %s\n", i, "-NONE-");
2420 else if (!strncmp(cmd, "apply", 2))
2425 bg = BackgroundFind(prm);
2430 sscanf(p, "%lx", &xwin);
2432 win = ECreateWinFromXwin(xwin);
2435 BackgroundApplyWin(bg, win);
2438 else if (!strncmp(cmd, "del", 2))
2440 BackgroundDestroyByName(prm);
2442 else if (!strncmp(cmd, "list", 2))
2444 ECORE_LIST_FOR_EACH(bg_list, bg) IpcPrintf("%s\n", bg->name);
2446 else if (!strncmp(cmd, "load", 2))
2448 bg = BackgroundFind(prm);
2451 IpcPrintf("Background already defined\n");
2455 bg = BrackgroundCreateFromImage(prm, p, NULL, 0);
2458 else if (!strncmp(cmd, "set", 2))
2460 BackgroundSet1(prm, p);
2462 else if (!strncmp(cmd, "show", 2))
2464 bg = BackgroundFind(prm);
2468 BackgroundGetInfoString1(bg, buf, sizeof(buf));
2469 IpcPrintf("%s\n", buf);
2472 IpcPrintf("Error: background '%s' does not exist.", prm);
2474 else if (!strcmp(cmd, "use"))
2476 if (!strcmp(prm, "-"))
2479 bg = BackgroundFind(prm);
2481 num = DesksGetCurrentNum();
2482 sscanf(p, "%d %n", &num, &len);
2483 DeskBackgroundSet(DeskGet(num), bg);
2486 else if (!strncmp(cmd, "xget", 2))
2488 bg = BackgroundFind(prm);
2492 BackgroundGetInfoString2(bg, buf, sizeof(buf));
2493 IpcPrintf("%s\n", buf);
2496 IpcPrintf("Error: background '%s' does not exist.", prm);
2498 else if (!strncmp(cmd, "xset", 2))
2500 BackgroundSet2(prm, p);
2504 /* Compatibility with pre- 0.16.8 clients */
2505 BackgroundSet1(cmd, params + len2);
2510 IPC_BackgroundUse(const char *params)
2520 sscanf(p, "%1000s %n", name, &l);
2523 bg = BackgroundFind(name);
2530 sscanf(p, "%d %n", &i, &l);
2534 DeskBackgroundSet(DeskGet(i), bg);
2540 static const IpcItem BackgroundsIpcArray[] = {
2544 "Background commands",
2545 " background Show current background\n"
2546 " background apply <name> <win> Apply background to window\n"
2547 " background del <name> Delete background\n"
2548 " background list Show all background\n"
2549 " background load <name> <file> Load new wallpaper from file\n"
2550 " background set <name> ... Set background parameters\n"
2551 " background show <name> Show background info\n"
2552 " background use <name> <desks...> Switch to background <name>\n"
2553 " background xget <name> Special show background parameters\n"
2554 " background xset <name> ... Special set background parameters\n"}
2557 IPC_BackgroundUse, "use_bg", NULL, "Deprecated - do not use", NULL}
2560 #define N_IPC_FUNCS (sizeof(BackgroundsIpcArray)/sizeof(IpcItem))
2563 * Configuration items
2565 static const CfgItem BackgroundsCfgItems[] = {
2566 CFG_ITEM_BOOL(Conf.backgrounds, hiquality, 1),
2567 CFG_ITEM_BOOL(Conf.backgrounds, user, 1),
2568 CFG_ITEM_BOOL(Conf.backgrounds, no_scan, 0),
2569 CFG_ITEM_INT(Conf.backgrounds, timeout, 240),
2571 #define N_CFG_ITEMS (sizeof(BackgroundsCfgItems)/sizeof(CfgItem))
2576 extern const EModule ModBackgrounds;
2577 const EModule ModBackgrounds = {
2578 "backgrounds", "bg",
2580 {N_IPC_FUNCS, BackgroundsIpcArray},
2581 {N_CFG_ITEMS, BackgroundsCfgItems}