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.
25 #include "backgrounds.h"
28 #include "e16-ecore_list.h"
35 #define ENABLE_DESTROY 0 /* Broken */
48 EColor bg, hi, lo, hihi, lolo;
60 ImageStateArray norm, active, sticky, sticky_active;
62 unsigned int ref_count;
65 static Ecore_List *iclass_list = NULL;
67 static ImageClass *ImageclassGetFallback(void);
69 #ifdef ENABLE_THEME_TRANSPARENCY
71 static EImageColorModifier *icm = NULL;
72 static unsigned char gray[256];
73 static unsigned char alpha[256];
75 static int prev_alpha = -1;
78 TransparencyEnabled(void)
80 return Conf.trans.alpha;
84 TransparencyUpdateNeeded(void)
86 return Conf.trans.alpha || prev_alpha;
90 TransparencyMakeColorModifier(void)
94 for (i = 0; i < 256; i++)
97 alpha[i] = 255 - Conf.trans.alpha;
101 icm = EImageColorModifierCreate();
102 EImageColorModifierSetTables(icm, gray, gray, gray, alpha);
106 TransparencySet(int transparency)
110 if (transparency < 0)
112 else if (transparency > 255)
115 /* This will render the initial startup stuff correctly since !changed */
116 if (prev_alpha == -1)
118 prev_alpha = Conf.trans.alpha = transparency;
123 changed = Conf.trans.alpha != transparency;
124 prev_alpha = Conf.trans.alpha;
125 Conf.trans.alpha = transparency;
131 /* Generate the color modifier tables */
132 TransparencyMakeColorModifier();
139 /* Hack to get tiled backgrounds regenerated at full size */
140 BackgroundsInvalidate(1);
142 ModulesSignal(ESIGNAL_THEME_TRANS_CHANGE, NULL);
145 #endif /* ENABLE_THEME_TRANSPARENCY */
148 ThemeImageLoad(const char *file)
158 im = EImageLoad(file);
162 f = ThemeFileFind(file);
174 ImagestateColorsSetGray(ImageState * is,
175 unsigned int hihi, unsigned int hi,
176 unsigned int bg, unsigned int lo, unsigned int lolo)
178 SET_COLOR(&(is->hihi), hihi, hihi, hihi);
179 SET_COLOR(&(is->hi), hi, hi, hi);
180 SET_COLOR(&(is->bg), bg, bg, bg);
181 SET_COLOR(&(is->lo), lo, lo, lo);
182 SET_COLOR(&(is->lolo), lolo, lolo, lolo);
186 ImagestateCreate(const char *file)
190 is = ECALLOC(ImageState, 1);
194 is->pixmapfillstyle = FILL_STRETCH;
195 ImagestateColorsSetGray(is, 255, 200, 160, 120, 64);
196 is->bevelstyle = BEVEL_NONE;
197 is->im_file = Estrdup(file);
204 ImagestateDestroy(ImageState * is)
210 Efree(is->real_file);
221 FreeImageStateArray(ImageStateArray * isa)
223 ImagestateDestroy(isa->normal);
224 ImagestateDestroy(isa->hilited);
225 ImagestateDestroy(isa->clicked);
226 ImagestateDestroy(isa->disabled);
228 #endif /* ENABLE_DESTROY */
231 ImagestateColorsAlloc(ImageState * is)
233 if (!is || is->got_colors)
236 EAllocColor(WinGetCmap(VROOT), &is->bg);
237 EAllocColor(WinGetCmap(VROOT), &is->hi);
238 EAllocColor(WinGetCmap(VROOT), &is->lo);
239 EAllocColor(WinGetCmap(VROOT), &is->hihi);
240 EAllocColor(WinGetCmap(VROOT), &is->lolo);
246 ImagestateRealize(ImageState * is)
250 if (is->im) /* Image is already loaded */
256 return; /* No file - quit */
257 /* not loaded, load and setup */
258 is->real_file = ThemeFileFind(is->im_file);
262 is->im = EImageLoad(is->real_file);
263 if (is->im && is->rotate)
264 EImageOrientate(is->im, is->rotate);
268 #define S(s) ((s) ? (s) : "(null)")
270 ("ImagestateRealize: Hmmm... is->im is NULL (im_file=%s real_file=%s)\n",
271 S(is->im_file), S(is->real_file));
272 Efree(is->real_file);
273 is->real_file = NULL;
277 Efree(is->im_file); /* We no longer need the file */
280 EImageCheckAlpha(is->im);
283 EImageSetBorder(is->im, is->border);
285 #if 0 /* To be implemented? */
288 Imlib_set_image_red_curve(pImlib_Context, is->im, is->colmod->red.map);
289 Imlib_set_image_green_curve(pImlib_Context, is->im,
290 is->colmod->green.map);
291 Imlib_set_image_blue_curve(pImlib_Context, is->im,
292 is->colmod->blue.map);
298 ImageclassCreate(const char *name)
302 ic = ECALLOC(ImageClass, 1);
307 iclass_list = ecore_list_new();
308 ecore_list_prepend(iclass_list, ic);
310 ic->name = Estrdup(name);
311 ic->norm.normal = ic->norm.hilited = ic->norm.clicked = ic->norm.disabled =
313 ic->active.normal = ic->active.hilited = ic->active.clicked =
314 ic->active.disabled = NULL;
315 ic->sticky.normal = ic->sticky.hilited = ic->sticky.clicked =
316 ic->sticky.disabled = NULL;
317 ic->sticky_active.normal = ic->sticky_active.hilited =
318 ic->sticky_active.clicked = ic->sticky_active.disabled = NULL;
319 ic->padding.left = 0;
320 ic->padding.right = 0;
322 ic->padding.bottom = 0;
330 ImageclassDestroy(ImageClass * ic)
335 if (ic->ref_count > 0)
337 DialogOK("ImageClass Error!", _("%u references remain\n"),
342 ecore_list_node_remove(iclass_list, ic);
346 FreeImageStateArray(&(ic->norm));
347 FreeImageStateArray(&(ic->active));
348 FreeImageStateArray(&(ic->sticky));
349 FreeImageStateArray(&(ic->sticky_active));
353 #endif /* ENABLE_DESTROY */
356 ImageclassAlloc(const char *name, int fallback)
360 if (!name || !name[0])
363 ic = ImageclassFind(name, fallback);
371 ImageclassFree(ImageClass * ic)
378 ImageclassGetName(ImageClass * ic)
380 return (ic) ? ic->name : NULL;
384 ImageclassGetPadding(ImageClass * ic)
386 return (ic) ? &(ic->padding) : NULL;
390 _ImageclassMatchName(const void *data, const void *match)
392 return strcmp(((const ImageClass *)data)->name, (const char *)match);
396 ImageclassFind(const char *name, int fallback)
398 ImageClass *ic = NULL;
401 ic = (ImageClass *) ecore_list_find(iclass_list, _ImageclassMatchName,
407 Eprintf("%s: Get fallback (%s)\n", __func__, name);
409 return ImageclassGetFallback();
412 #define ISTATE_SET_STATE(which, fallback) \
413 if (!ic->which) ic->which = ic->fallback;
416 ImageclassPopulate(ImageClass * ic)
421 if (!ic->norm.normal)
424 ISTATE_SET_STATE(norm.hilited, norm.normal);
425 ISTATE_SET_STATE(norm.clicked, norm.normal);
426 ISTATE_SET_STATE(norm.disabled, norm.normal);
428 ISTATE_SET_STATE(active.normal, norm.normal);
429 ISTATE_SET_STATE(active.hilited, active.normal);
430 ISTATE_SET_STATE(active.clicked, active.normal);
431 ISTATE_SET_STATE(active.disabled, active.normal);
433 ISTATE_SET_STATE(sticky.normal, norm.normal);
434 ISTATE_SET_STATE(sticky.hilited, sticky.normal);
435 ISTATE_SET_STATE(sticky.clicked, sticky.normal);
436 ISTATE_SET_STATE(sticky.disabled, sticky.normal);
438 ISTATE_SET_STATE(sticky_active.normal, norm.normal);
439 ISTATE_SET_STATE(sticky_active.hilited, sticky_active.normal);
440 ISTATE_SET_STATE(sticky_active.clicked, sticky_active.normal);
441 ISTATE_SET_STATE(sticky_active.disabled, sticky_active.normal);
445 ImageclassConfigLoad(FILE * fs)
448 char s[FILEPATH_LEN_MAX];
449 char s2[FILEPATH_LEN_MAX];
452 ImageClass *ic = NULL;
453 ImageState *is = NULL;
456 while (GetLine(s, sizeof(s), fs))
458 i1 = ConfigParseline1(s, s2, &p2, NULL);
464 ImageclassPopulate(ic);
466 case CONFIG_COLORMOD:
467 case ICLASS_COLORMOD:
469 case CONFIG_CLASSNAME:
471 if (ImageclassFind(s2, 0))
476 ic = ImageclassCreate(s2);
490 ic2 = ImageclassFind(s2, 0);
493 ic->norm = ic2->norm;
494 ic->active = ic2->active;
495 ic->sticky = ic2->sticky;
496 ic->sticky_active = ic2->sticky_active;
497 ic->padding = ic2->padding;
502 sscanf(p2, "%i %i %i %i", &l, &r, &t, &b);
503 ic->padding.left = l;
504 ic->padding.right = r;
506 ic->padding.bottom = b;
509 /* don't ask... --mandrake */
511 ic->norm.normal = is = ImagestateCreate(s2);
514 ic->norm.clicked = is = ImagestateCreate(s2);
517 ic->norm.hilited = is = ImagestateCreate(s2);
519 case ICLASS_DISABLED:
520 ic->norm.disabled = is = ImagestateCreate(s2);
522 case ICLASS_STICKY_NORMAL:
523 ic->sticky.normal = is = ImagestateCreate(s2);
525 case ICLASS_STICKY_CLICKED:
526 ic->sticky.clicked = is = ImagestateCreate(s2);
528 case ICLASS_STICKY_HILITED:
529 ic->sticky.hilited = is = ImagestateCreate(s2);
531 case ICLASS_STICKY_DISABLED:
532 ic->sticky.disabled = is = ImagestateCreate(s2);
534 case ICLASS_ACTIVE_NORMAL:
535 ic->active.normal = is = ImagestateCreate(s2);
537 case ICLASS_ACTIVE_CLICKED:
538 ic->active.clicked = is = ImagestateCreate(s2);
540 case ICLASS_ACTIVE_HILITED:
541 ic->active.hilited = is = ImagestateCreate(s2);
543 case ICLASS_ACTIVE_DISABLED:
544 ic->active.disabled = is = ImagestateCreate(s2);
546 case ICLASS_STICKY_ACTIVE_NORMAL:
547 ic->sticky_active.normal = is = ImagestateCreate(s2);
549 case ICLASS_STICKY_ACTIVE_CLICKED:
550 ic->sticky_active.clicked = is = ImagestateCreate(s2);
552 case ICLASS_STICKY_ACTIVE_HILITED:
553 ic->sticky_active.hilited = is = ImagestateCreate(s2);
555 case ICLASS_STICKY_ACTIVE_DISABLED:
556 ic->sticky_active.disabled = is = ImagestateCreate(s2);
567 is->border = EMALLOC(EImageBorder, 1);
569 sscanf(p2, "%i %i %i %i", &l, &r, &t, &b);
570 is->border->left = l;
571 is->border->right = r;
573 is->border->bottom = b;
574 /* Hmmm... imlib2 works better with this */
576 is->border->bottom++;
578 case ICLASS_FILLRULE:
579 is->pixmapfillstyle = atoi(s2);
581 case ICLASS_TRANSPARENT:
582 is->transparent = strtoul(s2, NULL, 0);
584 case ICLASS_ROTATE: /* flip goes here too */
585 is->rotate = strtoul(s2, NULL, 0);
588 #define _R(x) (((x) >> 16) & 0xff)
589 #define _G(x) (((x) >> 8) & 0xff)
590 #define _B(x) (((x) ) & 0xff)
591 #define INT_TO_COLOR(xc, rgb) \
592 do { (&(xc))->red = _R(rgb); (&(xc))->green = _G(rgb); (&(xc))->blue = _B(rgb); } while(0)
594 int n, bevel, hihi, hi, bg, lo, lolo;
596 n = sscanf(p2, "%i %i %i %i %i %i",
597 &bevel, &hihi, &hi, &bg, &lo, &lolo);
600 is->bevelstyle = bevel;
601 INT_TO_COLOR(is->hihi, hihi);
602 INT_TO_COLOR(is->hi, hi);
603 INT_TO_COLOR(is->bg, bg);
604 INT_TO_COLOR(is->lo, lo);
605 INT_TO_COLOR(is->lolo, lolo);
620 ImageclassCreateSimple(const char *name, const char *image)
624 ic = ImageclassCreate(name);
628 ic->norm.normal = ImagestateCreate(image);
629 ic->norm.normal->unloadable = 1;
630 ImageclassPopulate(ic);
632 ImagestateRealize(ic->norm.normal);
637 #ifdef ENABLE_THEME_TRANSPARENCY
639 ImageclassIsTransparent(ImageClass * ic)
641 return ic && ic->norm.normal && ic->norm.normal->transparent;
646 ImageclassGetImageState1(ImageStateArray * pisa, int state)
673 ImageclassGetImageState(ImageClass * ic, int state, int active, int sticky)
680 is = ImageclassGetImageState1(&ic->sticky_active, state);
682 is = ImageclassGetImageState1(&ic->active, state);
687 is = ImageclassGetImageState1(&ic->sticky, state);
689 is = ImageclassGetImageState1(&ic->norm, state);
696 ImageclassGetImage(ImageClass * ic, int active, int sticky, int state)
704 is = ImageclassGetImageState(ic, state, active, sticky);
709 ImagestateRealize(is);
719 #ifdef ENABLE_TRANSPARENCY
721 pt_type_to_flags(int image_type)
725 if (Conf.trans.alpha == 0)
726 return ICLASS_ATTR_OPAQUE;
733 flags = ICLASS_ATTR_OPAQUE;
736 flags = Conf.trans.border;
739 flags = Conf.trans.widget;
742 flags = Conf.trans.iconbox;
745 flags = Conf.trans.menu;
748 flags = Conf.trans.menu_item;
751 flags = Conf.trans.tooltip;
754 flags = Conf.trans.dialog;
757 flags = Conf.trans.hilight;
760 flags = Conf.trans.pager;
763 flags = Conf.trans.warplist;
766 if (flags != ICLASS_ATTR_OPAQUE)
767 flags |= ICLASS_ATTR_USE_CM;
773 pt_get_bg_image(Win win, int w, int h, int use_root)
780 bg = DeskGetBackgroundPixmap(DesksGetCurrent());
781 if (use_root || bg == None)
784 bg = WinGetXwin(VROOT);
788 cr = EoGetWin(DesksGetCurrent());
790 ETranslateCoordinates(win, cr, 0, 0, &xx, &yy, NULL);
792 Eprintf("pt_get_bg_image %#lx %d %d %d %d\n", win, xx, yy, w, h);
794 if (xx < WinGetW(VROOT) && yy < WinGetH(VROOT) && xx + w >= 0 && yy + h >= 0)
796 /* Create the background base image */
797 ii = EImageGrabDrawable(bg, None, xx, yy, w, h, !EServerIsGrabbed());
806 ImageclassGetImageBlended(ImageClass * ic, Win win, int w, int h, int active,
807 int sticky, int state, int image_type)
816 is = ImageclassGetImageState(ic, state, active, sticky);
821 ImagestateRealize(is);
826 #ifdef ENABLE_TRANSPARENCY
827 flags = pt_type_to_flags(image_type);
828 if (flags != ICLASS_ATTR_OPAQUE)
830 bg = pt_get_bg_image(win, w, h, flags & ICLASS_ATTR_GLASS);
833 /* FIXME - Tiling not implemented */
834 EImageBlendCM(bg, im, (flags & ICLASS_ATTR_USE_CM) ? icm : NULL);
843 if (is->pixmapfillstyle == FILL_STRETCH)
845 bg = EImageCreateScaled(im, 0, 0, 0, 0, w, h);
851 EImageGetSize(im, &iw, &ih);
855 if (is->pixmapfillstyle & FILL_TILE_H)
857 if (is->pixmapfillstyle & FILL_TILE_V)
860 bg = EImageCreate(w, h);
861 EImageTile(bg, im, 0, tw, th, 0, 0, w, h, 0, 0);
864 #ifdef ENABLE_TRANSPARENCY
867 if ((is->unloadable) || (Conf.memory_paranoia))
877 ImagestateMakePmapMask(ImageState * is, Win win, PmapMask * pmm,
878 int pmapflags, int w, int h, int image_type)
880 #ifdef ENABLE_TRANSPARENCY
885 flags = pt_type_to_flags(image_type);
888 * is->transparent flags:
889 * 0x01: Use desktop background pixmap as base
890 * 0x02: Use root window as base (use only for transients, if at all)
891 * 0x04: Don't apply image mask to result
893 if (is->transparent && EImageHasAlpha(is->im))
894 flags = is->transparent;
896 if (flags != ICLASS_ATTR_OPAQUE)
898 ii = pt_get_bg_image(win, w, h, flags & ICLASS_ATTR_GLASS);
903 Eprintf("ImagestateMakePmapMask %#lx %d %d\n", win, w, h);
909 EImageBlendCM(ii, is->im, (flags & ICLASS_ATTR_USE_CM) ? icm : NULL);
912 pmm->pmap = pmap = ECreatePixmap(win, w, h, 0);
916 EImageRenderOnDrawable(ii, win, pmap, 0, 0, 0, w, h);
918 if ((pmapflags & IC_FLAG_MAKE_MASK) && !(flags & ICLASS_ATTR_NO_CLIP))
920 if (EImageHasAlpha(is->im))
922 /* Make the scaled clip mask to be used */
923 EImageRenderPixmaps(is->im, win, EIMAGE_ANTI_ALIAS, &pmap,
926 /* Replace the mask with the correct one */
927 pmm->mask = EXCreatePixmapCopy(mask, w, h, 1);
929 EImagePixmapsFree(pmap, mask);
938 #endif /* ENABLE_TRANSPARENCY */
939 if (is->pixmapfillstyle == FILL_STRETCH)
942 pmm->pmap = pmm->mask = None;
945 EImageRenderPixmaps(is->im, win, EIMAGE_ANTI_ALIAS, &pmm->pmap,
950 int ww, hh, cw, ch, pw, ph;
952 EImageGetSize(is->im, &ww, &hh);
956 if (is->pixmapfillstyle & FILL_TILE_H)
958 if (is->pixmapfillstyle & FILL_TILE_V)
960 if (is->pixmapfillstyle & FILL_INT_TILE_H)
969 if (is->pixmapfillstyle & FILL_INT_TILE_V)
979 pmm->pmap = pmm->mask = None;
982 EImageRenderPixmaps(is->im, win, EIMAGE_ANTI_ALIAS, &pmm->pmap,
987 #define LINE(x1, y1, x2, y2) \
988 XDrawLine(disp, win, gc, x + (x1), y + (y1), x + (x2), y + (y2))
989 #define RECT(x, y, w, h) \
990 XDrawRectangle(disp, win, gc, x, y, w, h);
993 ImagestateDrawBevel(ImageState * is, Drawable win, GC gc,
994 int x, int y, int w, int h)
996 ImagestateColorsAlloc(is);
998 switch (is->bevelstyle)
1001 XSetForeground(disp, gc, is->hihi.pixel);
1002 LINE(0, 0, w - 2, 0);
1003 LINE(0, 0, 0, h - 2);
1004 XSetForeground(disp, gc, is->lolo.pixel);
1005 LINE(1, h - 1, w - 1, h - 1);
1006 LINE(w - 1, 1, w - 1, h - 1);
1009 XSetForeground(disp, gc, is->hi.pixel);
1010 LINE(0, 0, w - 1, 0);
1011 LINE(0, 0, 0, h - 1);
1012 LINE(1, 1, w - 2, 1);
1013 LINE(1, 1, 1, h - 2);
1014 XSetForeground(disp, gc, is->lo.pixel);
1015 LINE(0, h - 1, w - 1, h - 1);
1016 LINE(w - 1, 1, w - 1, h - 1);
1017 LINE(1, h - 2, w - 2, h - 2);
1018 LINE(w - 2, 2, w - 2, h - 2);
1021 XSetForeground(disp, gc, is->hihi.pixel);
1022 LINE(0, 0, w - 1, 0);
1023 LINE(0, 0, 0, h - 1);
1024 XSetForeground(disp, gc, is->hi.pixel);
1025 LINE(1, 1, w - 2, 1);
1026 LINE(1, 1, 1, h - 2);
1027 XSetForeground(disp, gc, is->lolo.pixel);
1028 LINE(1, h - 1, w - 1, h - 1);
1029 LINE(w - 1, 1, w - 1, h - 1);
1030 XSetForeground(disp, gc, is->lo.pixel);
1031 LINE(2, h - 2, w - 2, h - 2);
1032 LINE(w - 2, 2, w - 2, h - 2);
1035 XSetForeground(disp, gc, is->hi.pixel);
1036 LINE(0, 0, w - 2, 0);
1037 LINE(0, 0, 0, h - 2);
1038 XSetForeground(disp, gc, is->lo.pixel);
1039 LINE(1, 1, w - 3, 1);
1040 LINE(1, 1, 1, h - 3);
1041 XSetForeground(disp, gc, is->lo.pixel);
1042 LINE(1, h - 1, w - 1, h - 1);
1043 LINE(w - 1, 1, w - 1, h - 1);
1044 XSetForeground(disp, gc, is->hi.pixel);
1045 LINE(2, h - 2, w - 2, h - 2);
1046 LINE(w - 2, 2, w - 2, h - 2);
1048 case BEVEL_WIDEDOUBLE:
1049 XSetForeground(disp, gc, is->hihi.pixel);
1050 LINE(0, 0, w - 1, 0);
1051 LINE(0, 0, 0, h - 1);
1052 XSetForeground(disp, gc, is->hi.pixel);
1053 LINE(1, 1, w - 2, 1);
1054 LINE(1, 1, 1, h - 2);
1055 LINE(3, h - 4, w - 4, h - 4);
1056 LINE(w - 4, 3, w - 4, h - 4);
1057 XSetForeground(disp, gc, is->lolo.pixel);
1058 LINE(1, h - 1, w - 1, h - 1);
1059 LINE(w - 1, 1, w - 1, h - 1);
1060 XSetForeground(disp, gc, is->lo.pixel);
1061 LINE(2, h - 2, w - 2, h - 2);
1062 LINE(w - 2, 2, w - 2, h - 2);
1063 LINE(3, 3, w - 4, 3);
1064 LINE(3, 3, 3, h - 4);
1066 case BEVEL_THINPOINT:
1067 XSetForeground(disp, gc, is->hi.pixel);
1068 LINE(0, 0, w - 2, 0);
1069 LINE(0, 0, 0, h - 2);
1070 XSetForeground(disp, gc, is->lo.pixel);
1071 LINE(1, h - 1, w - 1, h - 1);
1072 LINE(w - 1, 1, w - 1, h - 1);
1073 XSetForeground(disp, gc, is->hihi.pixel);
1076 XSetForeground(disp, gc, is->lolo.pixel);
1077 LINE(w - 2, h - 1, w - 1, h - 1);
1078 LINE(w - 1, h - 2, w - 1, h - 1);
1080 case BEVEL_THICKPOINT:
1081 XSetForeground(disp, gc, is->hi.pixel);
1082 RECT(x, y, w - 1, h - 1);
1090 ImagestateDrawNoImg(ImageState * is, Drawable draw, int x, int y, int w, int h)
1094 ImagestateColorsAlloc(is);
1096 gc = EXCreateGC(draw, 0, NULL);
1097 XSetFillStyle(disp, gc, FillSolid);
1098 XSetForeground(disp, gc, is->bg.pixel);
1099 XFillRectangle(disp, draw, gc, x, y, w, h);
1100 if (is->bevelstyle != BEVEL_NONE)
1101 ImagestateDrawBevel(is, draw, gc, x, y, w, h);
1106 ITApply(Win win, ImageClass * ic, ImageState * is,
1107 int state, int active, int sticky, int image_type,
1108 TextClass * tc, TextState * ts, const char *text, int flags)
1112 if (win == NULL || !ic)
1117 if (w <= 0 || h <= 0)
1121 is = ImageclassGetImageState(ic, state, active, sticky);
1128 ts = TextclassGetTextState(tc, state, active, sticky);
1132 ImagestateRealize(is);
1134 /* Imlib2 will not render pixmaps with dimensions > 8192 */
1135 if (is->im && w <= 8192 && h <= 8192)
1139 ImagestateMakePmapMask(is, win, &pmm, IC_FLAG_MAKE_MASK, w, h,
1144 Pixmap pmap = pmm.pmap;
1146 if ((ts && text) || (is->bevelstyle != BEVEL_NONE))
1150 pmap = EGetWindowBackgroundPixmap(win);
1151 EXCopyAreaTiled(pmm.pmap, None, pmap, 0, 0, w, h, 0, 0);
1154 if (is->bevelstyle != BEVEL_NONE)
1158 gc = EXCreateGC(WinGetXwin(win), 0, NULL);
1159 Eprintf("%s: bevel=%d\n", __func__, is->bevelstyle);
1160 ImagestateDrawBevel(is, pmap, gc, 0, 0, w, h);
1165 TextstateTextDraw(ts, win, pmap, text, 0, 0, w, h,
1167 TextclassGetJustification(tc), flags);
1170 /* Set window pixmap */
1171 if (pmap == pmm.pmap)
1173 ESetWindowBackgroundPixmap(win, pmap);
1174 EFreeWindowBackgroundPixmap(win);
1177 if (pmm.w == w && pmm.h == h)
1178 EShapeSetMask(win, 0, 0, pmm.mask);
1180 EShapeSetMaskTiled(win, 0, 0, pmm.mask, w, h);
1185 if ((is->unloadable) || (Conf.memory_paranoia))
1193 ImagestateColorsAlloc(is);
1195 if (is->bevelstyle == BEVEL_NONE && !text)
1197 ESetWindowBackground(win, is->bg.pixel);
1203 pmap = EGetWindowBackgroundPixmap(win);
1204 ImagestateDrawNoImg(is, pmap, 0, 0, w, h);
1206 TextstateTextDraw(ts, win, pmap, text, 0, 0, w, h,
1208 TextclassGetJustification(tc), flags);
1215 ImageclassApply(ImageClass * ic, Win win, int active, int sticky, int state,
1218 ITApply(win, ic, NULL, state, active, sticky, image_type, NULL, NULL, NULL,
1223 PmapMaskTile(PmapMask * pmm, Win win, unsigned int w, unsigned int h)
1227 pmap = ECreatePixmap(win, w, h, 0);
1230 EXCopyAreaTiled(pmm->pmap, None, pmap, 0, 0, w, h, 0, 0);
1233 if (pmm->mask != None)
1234 mask = ECreatePixmap(win, w, h, 1);
1236 EXCopyAreaTiled(pmm->mask, None, mask, 0, 0, w, h, 0, 0);
1247 ImageclassApplyCopy(ImageClass * ic, Win win, int w, int h,
1248 int active, int sticky, int state,
1249 PmapMask * pmm, int pmapflags, int image_type)
1257 pmm->pmap = pmm->mask = 0;
1259 if ((!ic) || (!win) || (w <= 0) || (h <= 0))
1262 is = ImageclassGetImageState(ic, state, active, sticky);
1267 ImagestateRealize(is);
1269 /* Imlib2 will not render pixmaps with dimensions > 8192 */
1270 if (is->im && w <= 8192 && h <= 8192)
1272 ImagestateMakePmapMask(is, win, pmm, pmapflags, w, h, image_type);
1274 if ((pmapflags & IC_FLAG_FULL_SIZE) && pmm->pmap &&
1275 (pmm->w != w || pmm->h != h))
1277 /* Create new full sized pixmaps and fill them with the */
1278 /* pmap and mask tiles */
1279 PmapMaskTile(pmm, win, w, h);
1282 if ((is->unloadable) || (Conf.memory_paranoia))
1291 Eprintf("ImageclassApplyCopy: Hmm... pmm->pmap already set\n");
1294 pmm->pmap = ECreatePixmap(win, w, h, 0);
1297 ImagestateDrawNoImg(is, pmm->pmap, 0, 0, w, h);
1298 /* FIXME - No text */
1303 ImageclassApplySimple(ImageClass * ic, Win win, Drawable draw, int state,
1304 int x, int y, int w, int h)
1311 im = ImageclassGetImage(ic, 0, 0, state);
1314 EImageRenderOnDrawable(im, win, draw, 0, x, y, w, h);
1321 is = ImageclassGetImageState(ic, state, 0, 0);
1325 ImagestateDrawNoImg(is, draw, x, y, w, h);
1330 ImageclassGetFallback(void)
1334 ic = ImageclassFind("__fb_ic", 0);
1338 /* Create fallback imageclass */
1339 ic = ImageclassCreate("__fb_ic");
1343 ic->norm.normal = ImagestateCreate(NULL);
1344 ImagestateColorsSetGray(ic->norm.normal, 255, 255, 160, 0, 0);
1345 ic->norm.normal->bevelstyle = BEVEL_AMIGA;
1347 ic->norm.hilited = ImagestateCreate(NULL);
1348 ImagestateColorsSetGray(ic->norm.hilited, 255, 255, 192, 0, 0);
1349 ic->norm.hilited->bevelstyle = BEVEL_AMIGA;
1351 ic->norm.clicked = ImagestateCreate(NULL);
1352 ImagestateColorsSetGray(ic->norm.clicked, 0, 0, 192, 255, 255);
1353 ic->norm.clicked->bevelstyle = BEVEL_AMIGA;
1355 ic->active.normal = ImagestateCreate(NULL);
1356 ImagestateColorsSetGray(ic->active.normal, 255, 255, 0, 0, 0);
1357 SET_COLOR(&(ic->active.normal->bg), 180, 140, 160);
1358 ic->active.normal->bevelstyle = BEVEL_AMIGA;
1360 ic->active.hilited = ImagestateCreate(NULL);
1361 ImagestateColorsSetGray(ic->active.hilited, 255, 255, 0, 0, 0);
1362 SET_COLOR(&(ic->active.hilited->bg), 230, 190, 210);
1363 ic->active.hilited->bevelstyle = BEVEL_AMIGA;
1365 ic->active.clicked = ImagestateCreate(NULL);
1366 ImagestateColorsSetGray(ic->active.clicked, 0, 0, 0, 255, 255);
1367 SET_COLOR(&(ic->active.clicked->bg), 230, 190, 210);
1368 ic->active.clicked->bevelstyle = BEVEL_AMIGA;
1370 ic->padding.left = 4;
1371 ic->padding.right = 4;
1372 ic->padding.top = 4;
1373 ic->padding.bottom = 4;
1375 ImageclassPopulate(ic);
1381 ImageclassGetBlack(void)
1385 ic = ImageclassFind("__BLACK", 0);
1389 /* Create all black image class for filler borders */
1390 ic = ImageclassCreate("__BLACK");
1394 ic->norm.normal = ImagestateCreate(NULL);
1395 ImagestateColorsSetGray(ic->norm.normal, 0, 0, 0, 0, 0);
1397 ImageclassPopulate(ic);
1407 ImageclassIpc(const char *params)
1417 IpcPrintf("Please specify...\n");
1423 param1[0] = param2[0] = '\0';
1424 sscanf(p, "%1000s %1000s %n", param1, param2, &l);
1427 if (!strncmp(param1, "list", 2))
1429 ECORE_LIST_FOR_EACH(iclass_list, ic) IpcPrintf("%s\n", ic->name);
1435 IpcPrintf("ImageClass not specified\n");
1439 if (!strcmp(param2, "create"))
1441 /* Not implemented */
1444 else if (!strcmp(param2, "free_pixmap"))
1448 pmap = (Pixmap) strtol(p, NULL, 0);
1449 EImagePixmapsFree(pmap, None);
1453 ic = ImageclassFind(param1, 0);
1456 IpcPrintf("ImageClass not found: %s\n", param1);
1460 if (!strcmp(param2, "delete"))
1463 ImageclassDestroy(ic);
1466 else if (!strcmp(param2, "modify"))
1468 /* Not implemented */
1470 else if (!strcmp(param2, "get_padding"))
1472 IpcPrintf("%i %i %i %i\n",
1473 ic->padding.left, ic->padding.right,
1474 ic->padding.top, ic->padding.bottom);
1476 else if (!strcmp(param2, "get_image_size"))
1478 ImagestateRealize(ic->norm.normal);
1479 if (ic->norm.normal->im)
1483 EImageGetSize(ic->norm.normal->im, &w, &h);
1484 EImageFree(ic->norm.normal->im);
1485 IpcPrintf("%i %i\n", w, h);
1488 else if (!strcmp(param2, "apply"))
1495 /* 3:xwin 4:state 5:w 6:h */
1499 sscanf(p, "%lx %16s %d %d", &xwin, state, &w, &h);
1501 win = ECreateWinFromXwin(xwin);
1505 if (!strcmp(state, "normal"))
1507 else if (!strcmp(state, "hilited"))
1509 else if (!strcmp(state, "clicked"))
1511 else if (!strcmp(state, "disabled"))
1512 st = STATE_DISABLED;
1516 ImageclassApply(ic, win, 0, 0, st, ST_SOLID);
1519 else if (!strcmp(param2, "apply_copy"))
1527 /* 3:xwin 4:state 5:w 6:h */
1531 sscanf(p, "%lx %16s %d %d", &xwin, state, &w, &h);
1533 win = ECreateWinFromXwin(xwin);
1537 if (!strcmp(state, "normal"))
1539 else if (!strcmp(state, "hilited"))
1541 else if (!strcmp(state, "clicked"))
1543 else if (!strcmp(state, "disabled"))
1544 st = STATE_DISABLED;
1550 IpcPrintf("Error: missing width and/or height\n");
1554 ImageclassApplyCopy(ic, win, w, h, 0, 0, st, &pmm,
1555 IC_FLAG_MAKE_MASK | IC_FLAG_FULL_SIZE, ST_SOLID);
1556 IpcPrintf("0x%08lx 0x%08lx\n", pmm.pmap, pmm.mask);
1559 else if (!strcmp(param2, "query"))
1561 IpcPrintf("ImageClass %s found\n", ic->name);
1563 else if (!strcmp(param2, "ref_count"))
1565 IpcPrintf("%u references remain\n", ic->ref_count);
1569 IpcPrintf("Error: unknown operation specified\n");
1573 static const IpcItem ImageclassIpcArray[] = {
1577 "List imageclasses, apply an imageclass",
1581 #define N_IPC_FUNCS (sizeof(ImageclassIpcArray)/sizeof(IpcItem))
1586 extern const EModule ModImageclass;
1587 const EModule ModImageclass = {
1590 {N_IPC_FUNCS, ImageclassIpcArray}