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.
28 #include "e16-ecore_list.h"
38 #include "windowmatch.h"
41 #define EWIN_BORDER_PART_EVENT_MASK \
42 (KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
43 EnterWindowMask | LeaveWindowMask | PointerMotionMask)
44 #define EWIN_BORDER_TITLE_EVENT_MASK \
45 (EWIN_BORDER_PART_EVENT_MASK)
47 static Ecore_List *border_list = NULL;
49 static void BorderDestroy(const Border * b);
50 static void BorderWinpartHandleEvents(Win win, XEvent * ev, void *prm);
51 static void BorderFrameHandleEvents(Win win, XEvent * ev, void *prm);
52 static Border *BorderGetFallback(void);
55 BorderWinpartRealise(EWin * ewin, int i)
57 EWinBit *ewb = &ewin->bits[i];
59 if ((ewb->cx != ewb->x) || (ewb->cy != ewb->y) ||
60 (ewb->cw != ewb->w) || (ewb->ch != ewb->h))
62 if ((ewb->w <= 0) || (ewb->h <= 0))
64 EUnmapWindow(ewb->win);
69 EMoveResizeWindow(ewb->win, ewb->x, ewb->y, ewb->w, ewb->h);
75 BorderWinpartITclassApply(EWin * ewin, int i, int force)
77 EWinBit *ewb = &ewin->bits[i];
86 Eprintf("BorderWpITApply: %#lx %#lx %2d %d %s\n",
87 EwinGetClientXwin(ewin), EoGetWin(ewin), i, force,
91 is = ImageclassGetImageState(ewin->border->part[i].iclass, ewb->state,
92 ewin->state.active, EoIsSticky(ewin));
96 switch (ewin->border->part[i].flags)
99 txt = EwinGetTitle(ewin);
100 if (txt && ewin->border->part[i].tclass)
101 ts = TextclassGetTextState(ewin->border->part[i].tclass, ewb->state,
102 ewin->state.active, EoIsSticky(ewin));
110 if (!force && ewb->is == is && ewb->ts == ts)
115 ITApply(ewb->win, ewin->border->part[i].iclass, is,
116 ewb->state, ewin->state.active, EoIsSticky(ewin),
117 ST_BORDER, ewin->border->part[i].tclass, ts, txt, 1);
121 BorderWinpartDraw(EWin * ewin, int i)
123 EWinBit *ewb = &ewin->bits[i];
124 int move = 0, resize = 0, ret = 0;
126 if ((ewb->x != ewb->cx) || (ewb->y != ewb->cy))
134 if ((ewb->w != ewb->cw) || (ewb->h != ewb->ch))
141 if ((resize) || (ewb->expose))
143 BorderWinpartITclassApply(ewin, i, 1);
152 BorderWinpartChange(EWin * ewin, int i, int force)
154 BorderWinpartITclassApply(ewin, i, force);
156 if (ewin->update.shape || ewin->border->changes_shape)
157 EwinPropagateShapes(ewin);
161 EwinBorderDraw(EWin * ewin, int do_shape, int do_paint)
169 Eprintf("EwinBorderDraw %#lx %s d=%d s=%d p=%d\n",
170 EwinGetClientXwin(ewin), EoGetName(ewin), EoGetDeskNum(ewin),
174 for (i = 0; i < ewin->border->num_winparts; i++)
175 BorderWinpartITclassApply(ewin, i, do_shape || do_paint);
177 if (do_shape || ewin->update.shape || ewin->border->changes_shape)
178 EwinPropagateShapes(ewin);
182 EwinBorderUpdateInfo(EWin * ewin)
186 for (i = 0; i < ewin->border->num_winparts; i++)
188 if (ewin->border->part[i].flags == FLAG_TITLE)
189 BorderWinpartITclassApply(ewin, i, 1);
194 BorderWinpartCalc(EWin * ewin, int i, int ww, int hh)
196 int x, y, w, h, ox, oy, max, min;
197 int topleft, bottomright;
199 topleft = ewin->border->part[i].geom.topleft.originbox;
200 bottomright = ewin->border->part[i].geom.bottomright.originbox;
202 BorderWinpartCalc(ewin, topleft, ww, hh);
203 if (bottomright >= 0)
204 BorderWinpartCalc(ewin, bottomright, ww, hh);
209 x = ((ewin->border->part[i].geom.topleft.x.percent * ww) >> 10) +
210 ewin->border->part[i].geom.topleft.x.absolute;
211 y = ((ewin->border->part[i].geom.topleft.y.percent * hh) >> 10) +
212 ewin->border->part[i].geom.topleft.y.absolute;
214 else if (topleft >= 0)
216 x = ((ewin->border->part[i].geom.topleft.x.percent *
217 ewin->bits[topleft].w) >> 10) +
218 ewin->border->part[i].geom.topleft.x.absolute +
219 ewin->bits[topleft].x;
220 y = ((ewin->border->part[i].geom.topleft.y.percent *
221 ewin->bits[topleft].h) >> 10) +
222 ewin->border->part[i].geom.topleft.y.absolute +
223 ewin->bits[topleft].y;
227 if (bottomright == -1)
229 ox = ((ewin->border->part[i].geom.bottomright.x.percent * ww) >> 10) +
230 ewin->border->part[i].geom.bottomright.x.absolute;
231 oy = ((ewin->border->part[i].geom.bottomright.y.percent * hh) >> 10) +
232 ewin->border->part[i].geom.bottomright.y.absolute;
234 else if (bottomright >= 0)
236 ox = ((ewin->border->part[i].geom.bottomright.x.percent *
237 ewin->bits[bottomright].w) >> 10) +
238 ewin->border->part[i].geom.bottomright.x.absolute +
239 ewin->bits[bottomright].x;
240 oy = ((ewin->border->part[i].geom.bottomright.y.percent *
241 ewin->bits[bottomright].h) >> 10) +
242 ewin->border->part[i].geom.bottomright.y.absolute +
243 ewin->bits[bottomright].y;
247 * calculate height before width, because we may need it in order to
248 * determine the font size. But we might do it the other way around for
253 max = ewin->border->part[i].geom.height.max;
254 min = ewin->border->part[i].geom.height.min;
257 * If the title bar max size is set to zero, then set the title bar size to
258 * just a little bit more than the size of the title text.
261 if (max == 0 && ewin->border->part[i].flags == FLAG_TITLE)
263 int dummywidth, wmax, wmin;
269 * calculate width before height, because we need it in order to
270 * determine the font size.
274 wmax = ewin->border->part[i].geom.width.max;
275 wmin = ewin->border->part[i].geom.width.min;
279 x = ((x + ox) - w) >> 1;
285 iclass = ewin->border->part[i].iclass;
286 tclass = ewin->border->part[i].tclass;
287 pad = ImageclassGetPadding(iclass);
288 TextSize(tclass, ewin->state.active, EoIsSticky(ewin),
289 ewin->bits[i].state, EwinGetTitle(ewin), &max, &dummywidth,
290 w - (pad->top + pad->bottom));
291 max += pad->left + pad->right;
294 y = y + (((h - max) * TextclassGetJustification(tclass)) >> 10);
307 y = ((y + oy) - h) >> 1;
318 max = ewin->border->part[i].geom.width.max;
319 min = ewin->border->part[i].geom.width.min;
322 * If the title bar max size is set to zero, then set the title bar
323 * size to just a little bit more than the size of the title text.
326 if (max == 0 && ewin->border->part[i].flags == FLAG_TITLE)
333 iclass = ewin->border->part[i].iclass;
334 tclass = ewin->border->part[i].tclass;
335 pad = ImageclassGetPadding(iclass);
336 TextSize(tclass, ewin->state.active, EoIsSticky(ewin),
337 ewin->bits[i].state, EwinGetTitle(ewin), &max,
338 &dummyheight, h - (pad->top + pad->bottom));
339 max += pad->left + pad->right;
344 (((w - max) * TextclassGetJustification(tclass)) >> 10);
351 x = ((x + ox) - w) >> 1;
358 if ((ewin->state.shaded) && (!ewin->border->part[i].keep_for_shade))
360 ewin->bits[i].x = -100;
361 ewin->bits[i].y = -100;
362 ewin->bits[i].w = -1;
363 ewin->bits[i].h = -1;
375 EwinBorderCalcSizes(EWin * ewin, int propagate)
388 for (i = 0; i < ewin->border->num_winparts; i++)
389 ewin->bits[i].w = -2;
390 for (i = 0; i < ewin->border->num_winparts; i++)
391 if (ewin->bits[i].w == -2)
392 BorderWinpartCalc(ewin, i, ww, hh);
393 for (i = 0; i < ewin->border->num_winparts; i++)
394 BorderWinpartRealise(ewin, i);
397 for (i = 0; i < ewin->border->num_winparts; i++)
399 reshape |= BorderWinpartDraw(ewin, i);
403 Eprintf("EwinBorderCalcSizes prop=%d reshape=%d\n", propagate, reshape);
406 ewin->update.shape = 1;
407 if (propagate && ewin->update.shape)
408 EwinPropagateShapes(ewin);
412 BorderIncRefcount(const Border * b)
414 ((Border *) b)->ref_count++;
418 BorderDecRefcount(const Border * b)
420 ((Border *) b)->ref_count--;
424 BorderGetName(const Border * b)
426 return (b) ? b->name : NULL;
430 EwinBorderSelect(EWin * ewin)
434 if (ewin->inh_wm.b.border)
436 b = BorderFind("BORDERLESS");
440 /* Quit if we already have a border that isn't an internal one */
442 if (b && strncmp(b->name, "__", 2))
447 if (ewin->props.no_border)
448 b = BorderFind("BORDERLESS");
451 b = WindowMatchEwinBorder(ewin);
454 b = BorderFind("DEFAULT");
457 b = BorderGetFallback();
460 ewin->normal_border = ewin->border = b;
464 EwinBorderDetach(EWin * ewin)
466 const Border *b = ewin->border;
472 TooltipsSetPending(0, NULL, NULL);
474 EventCallbackUnregister(EoGetWin(ewin), 0, BorderFrameHandleEvents, ewin);
475 for (i = 0; i < b->num_winparts; i++)
477 EventCallbackUnregister(ewin->bits[i].win, 0,
478 BorderWinpartHandleEvents, &ewin->bits[i]);
479 if (ewin->bits[i].win)
480 EDestroyWindow(ewin->bits[i].win);
484 BorderDecRefcount(b);
489 BorderDestroy((Border *) b);
493 EwinBorderSetTo(EWin * ewin, const Border * b)
497 if (ewin->border == b)
507 EwinBorderDetach(ewin);
510 BorderIncRefcount(b);
511 HintsSetWindowBorder(ewin);
513 ewin->state.no_border = b->num_winparts <= 0;
515 EventCallbackRegister(EoGetWin(ewin), 0, BorderFrameHandleEvents, ewin);
517 if (b->num_winparts > 0)
518 ewin->bits = EMALLOC(EWinBit, b->num_winparts);
520 for (i = 0; i < b->num_winparts; i++)
522 ewin->bits[i].ewin = ewin; /* Reference to associated Ewin */
524 ewin->bits[i].win = ECreateWindow(EoGetWin(ewin), -10, -10, 1, 1, 0);
525 ECursorApply(b->part[i].ec, ewin->bits[i].win);
526 EMapWindow(ewin->bits[i].win);
527 EventCallbackRegister(ewin->bits[i].win, 0,
528 BorderWinpartHandleEvents, &ewin->bits[i]);
529 if (b->part[i].flags & FLAG_TITLE)
530 ESelectInput(ewin->bits[i].win, EWIN_BORDER_TITLE_EVENT_MASK);
532 ESelectInput(ewin->bits[i].win, EWIN_BORDER_PART_EVENT_MASK);
533 ewin->bits[i].x = -10;
534 ewin->bits[i].y = -10;
535 ewin->bits[i].w = -10;
536 ewin->bits[i].h = -10;
537 ewin->bits[i].cx = -99;
538 ewin->bits[i].cy = -99;
539 ewin->bits[i].cw = -99;
540 ewin->bits[i].ch = -99;
541 ewin->bits[i].state = 0;
542 ewin->bits[i].expose = 0;
543 ewin->bits[i].left = 0;
544 ewin->bits[i].is = NULL;
551 wl = EMALLOC(Window, b->num_winparts + 1);
552 for (i = b->num_winparts - 1; i >= 0; i--)
554 if (b->part[i].ontop)
555 wl[j++] = WinGetXwin(ewin->bits[i].win);
557 wl[j++] = WinGetXwin(ewin->win_container);
558 for (i = b->num_winparts - 1; i >= 0; i--)
560 if (!b->part[i].ontop)
561 wl[j++] = WinGetXwin(ewin->bits[i].win);
563 EXRestackWindows(wl, j);
567 if (!ewin->state.shaded)
568 EMoveWindow(ewin->win_container, b->border.left, b->border.top);
570 ewin->update.shape = 1;
571 EwinBorderCalcSizes(ewin, 0);
572 EwinStateUpdate(ewin);
574 SnapshotEwinUpdate(ewin, SNAP_USE_BORDER);
578 EwinBorderChange(EWin * ewin, const Border * b, int normal)
580 if (!b || ewin->border == b ||
581 ewin->inh_wm.b.border || ewin->state.fullscreen)
584 EwinBorderSetTo(ewin, b);
585 EwinMoveResize(ewin, EoGetX(ewin), EoGetY(ewin),
586 ewin->client.w, ewin->client.h);
589 ewin->normal_border = b;
593 EwinBorderAssign(EWin * ewin, const Border * b)
595 if (!b || ewin->border == b || ewin->inh_wm.b.border)
599 BorderDecRefcount(ewin->border);
600 BorderIncRefcount(b);
602 ewin->border = ewin->normal_border = b;
606 EwinBorderSetInitially(EWin * ewin, const char *name)
608 EwinBorderAssign(ewin, BorderFind(name));
612 BorderCreate(const char *name)
616 b = ECALLOC(Border, 1);
621 border_list = ecore_list_new();
622 ecore_list_prepend(border_list, b);
624 b->name = Estrdup(name);
625 b->group_border_name = NULL;
632 BorderDestroy(const Border * b)
639 if (b->ref_count > 0)
641 DialogOK("Border Error!", _("%u references remain\n"), b->ref_count);
645 ecore_list_node_remove(border_list, (Border *) b);
647 for (i = 0; i < b->num_winparts; i++)
649 ImageclassFree(b->part[i].iclass);
650 ActionclassFree(b->part[i].aclass);
651 TextclassFree(b->part[i].tclass);
652 ECursorFree(b->part[i].ec);
657 Efree(b->group_border_name);
658 ActionclassFree(b->aclass);
662 _BorderMatchName(const void *data, const void *match)
664 return strcmp(((const Border *)data)->name, (const char *)match);
668 BorderFind(const char *name)
672 return (Border *) ecore_list_find(border_list, _BorderMatchName, name);
676 BorderWinpartAdd(Border * b, const char *iclass, const char *aclass,
677 const char *tclass, const char *cclass, char ontop, int flags,
678 char isregion __UNUSED__, int wmin, int wmax, int hmin,
679 int hmax, int torigin, int txp, int txa, int typ, int tya,
680 int borigin, int bxp, int bxa, int byp, int bya,
688 b->part = EREALLOC(WinPart, b->part, n);
690 b->part[n - 1].iclass = (iclass) ? ImageclassAlloc(iclass, 1) : NULL;
691 b->part[n - 1].aclass = (aclass) ? ActionclassAlloc(aclass) : NULL;
692 b->part[n - 1].tclass = (tclass) ? TextclassAlloc(tclass, 1) : NULL;
693 b->part[n - 1].ec = (cclass) ? ECursorAlloc(cclass) : NULL;
695 b->part[n - 1].ontop = ontop;
696 b->part[n - 1].flags = flags;
697 b->part[n - 1].keep_for_shade = keep_for_shade;
698 b->part[n - 1].geom.width.min = wmin;
699 b->part[n - 1].geom.width.max = wmax;
700 b->part[n - 1].geom.height.min = hmin;
701 b->part[n - 1].geom.height.max = hmax;
702 b->part[n - 1].geom.topleft.originbox = torigin;
703 b->part[n - 1].geom.topleft.x.percent = txp;
704 b->part[n - 1].geom.topleft.x.absolute = txa;
705 b->part[n - 1].geom.topleft.y.percent = typ;
706 b->part[n - 1].geom.topleft.y.absolute = tya;
707 b->part[n - 1].geom.bottomright.originbox = borigin;
708 b->part[n - 1].geom.bottomright.x.percent = bxp;
709 b->part[n - 1].geom.bottomright.x.absolute = bxa;
710 b->part[n - 1].geom.bottomright.y.percent = byp;
711 b->part[n - 1].geom.bottomright.y.absolute = bya;
715 EwinBorderMinShadeSize(EWin * ewin, int *mw, int *mh)
717 int i, pw, ph, w, h, min_w, min_h;
718 int leftborderwidth, rightborderwidth;
719 int topborderwidth, bottomborderwidth;
730 for (i = 0; i < ewin->border->num_winparts; i++)
731 ewin->bits[i].w = -2;
732 for (i = 0; i < ewin->border->num_winparts; i++)
733 if (ewin->bits[i].w == -2)
734 BorderWinpartCalc(ewin, i, pw, ph);
736 switch (ewin->border->shadedir)
740 /* get the correct width, based on the borderparts that */
741 /*are remaining visible */
742 leftborderwidth = rightborderwidth = 0;
743 for (i = 0; i < ewin->border->num_winparts; i++)
745 if (!ewin->border->part[i].keep_for_shade)
748 w = ewin->border->border.left - ewin->bits[i].x;
749 if (leftborderwidth < w)
752 w = ewin->bits[i].x + ewin->bits[i].w -
753 (EoGetW(ewin) - ewin->border->border.right);
754 if (rightborderwidth < w)
755 rightborderwidth = w;
757 pw = rightborderwidth + leftborderwidth;
761 topborderwidth = bottomborderwidth = 0;
762 for (i = 0; i < ewin->border->num_winparts; i++)
764 if (!ewin->border->part[i].keep_for_shade)
767 h = ewin->border->border.top - ewin->bits[i].y;
768 if (topborderwidth < h)
771 h = ewin->bits[i].y + ewin->bits[i].h -
772 (EoGetH(ewin) - ewin->border->border.bottom);
773 if (bottomborderwidth < h)
774 bottomborderwidth = h;
776 ph = bottomborderwidth + topborderwidth;
782 for (i = 0; i < ewin->border->num_winparts; i++)
783 ewin->bits[i].w = -2;
784 for (i = 0; i < ewin->border->num_winparts; i++)
785 if (ewin->bits[i].w == -2)
786 BorderWinpartCalc(ewin, i, pw, ph);
790 for (i = 0; i < ewin->border->num_winparts; i++)
792 if (!ewin->border->part[i].keep_for_shade)
795 w = ewin->bits[i].x + ewin->bits[i].w;
799 h = ewin->bits[i].y + ewin->bits[i].h;
810 BorderWinpartIndex(EWin * ewin, Win win)
814 for (i = 0; i < ewin->border->num_winparts; i++)
816 if (win == ewin->bits[i].win)
820 return -1; /* Not found */
824 * Border event handlers
826 #define DEBUG_BORDER_EVENTS 0
829 BorderWinpartEventMouseDown(EWinBit * wbit, XEvent * ev)
831 EWin *ewin = wbit->ewin;
832 int part = wbit - ewin->bits;
834 GrabPointerSet(wbit->win, 0, 0);
836 wbit->state = STATE_CLICKED;
837 #if DEBUG_BORDER_EVENTS
838 Eprintf("BorderWinpartEventMouseDown %#lx %d\n", WinGetXwin(wbit->win),
841 BorderWinpartChange(ewin, part, 0);
843 FocusHandleClick(ewin, wbit->win);
845 if (ewin->border->part[part].aclass)
846 ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
850 BorderWinpartEventMouseUp(EWinBit * wbit, XEvent * ev)
852 EWin *ewin = wbit->ewin;
853 int part = wbit - ewin->bits;
854 int left = wbit->left;
858 GrabPointerRelease();
862 if ((wbit->state == STATE_CLICKED) && (!wbit->left))
863 wbit->state = STATE_HILITED;
865 wbit->state = STATE_NORMAL;
866 #if DEBUG_BORDER_EVENTS
867 Eprintf("BorderWinpartEventMouseUp %#lx %d\n", WinGetXwin(wbit->win),
870 BorderWinpartChange(ewin, part, 0);
872 /* Beware! Actions may destroy the current border */
875 if (ev && WinGetXwin(wbit->win) == Mode.events.last_bpress && !left &&
876 ewin->border->part[part].aclass)
877 ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
881 BorderWinpartEventEnter(EWinBit * wbit, XEvent * ev)
883 EWin *ewin = wbit->ewin;
884 int part = wbit - ewin->bits;
886 #if DEBUG_BORDER_EVENTS
887 Eprintf("BorderWinpartEventEnter %#lx %d\n", WinGetXwin(wbit->win),
890 if (wbit->state == STATE_CLICKED)
896 wbit->state = STATE_HILITED;
897 BorderWinpartChange(ewin, part, 0);
898 if (ewin->border->part[part].aclass)
899 ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
904 BorderWinpartEventLeave(EWinBit * wbit, XEvent * ev)
906 EWin *ewin = wbit->ewin;
907 int part = wbit - ewin->bits;
909 #if DEBUG_BORDER_EVENTS
910 Eprintf("BorderWinpartEventLeave %#lx %d\n", WinGetXwin(wbit->win),
913 if (wbit->state == STATE_CLICKED)
917 wbit->state = STATE_NORMAL;
918 BorderWinpartChange(ewin, part, 0);
919 if (ewin->border->part[part].aclass)
920 ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
925 BorderCheckState(EWin * ewin, XEvent * ev)
929 for (i = 0; i < ewin->border->num_winparts; i++)
937 BorderWinpartEventMouseUp(ewin->bits + i, NULL);
944 _BorderAutoshadeTimeout(void *data)
946 EWin *ewin = (EWin *) data;
948 if (!EwinFindByPtr(ewin)) /* Check, window may be gone */
952 EwinOpShade(ewin, OPSRC_USER, 1);
958 BorderFrameHandleEvents(Win win __UNUSED__, XEvent * ev, void *prm)
960 EWin *ewin = (EWin *) prm;
966 if (ewin->props.autoshade)
968 EwinOpShade(ewin, OPSRC_USER, 0);
970 if (ewin->border->aclass)
971 ActionclassEvent(ewin->border->aclass, ev, ewin);
974 if (ewin->props.autoshade && !ewin->state.shaded)
976 EQueryPointer(EoGetWin(ewin), &x, &y, NULL, NULL);
977 if (x >= 4 && x < EoGetW(ewin) - 4 &&
978 y >= 4 && y < EoGetH(ewin) - 4)
980 TIMER_DEL(ewin->timer);
981 TIMER_ADD(ewin->timer, .5, _BorderAutoshadeTimeout, ewin);
983 if (ewin->border->aclass)
984 ActionclassEvent(ewin->border->aclass, ev, ewin);
990 BorderWinpartGetAclass(void *data)
992 EWinBit *wbit = (EWinBit *) data;
996 /* Validate border part */
997 ewin = Mode.mouse_over_ewin;
1001 part = wbit - ewin->bits;
1002 if (part < 0 || part >= ewin->border->num_winparts)
1005 return ewin->border->part[part].aclass;
1009 BorderWinpartHandleTooltip(EWinBit * wbit)
1011 EWin *ewin = wbit->ewin;
1012 int part = wbit - ewin->bits;
1014 if (!ewin->border->part[part].aclass)
1016 TooltipsSetPending(0, BorderWinpartGetAclass, wbit);
1020 BorderWinpartHandleEvents(Win win __UNUSED__, XEvent * ev, void *prm)
1022 EWinBit *wbit = (EWinBit *) prm;
1027 BorderWinpartEventMouseDown(wbit, ev);
1030 BorderWinpartEventMouseUp(wbit, ev);
1033 /* Beware! Actions may destroy the current border */
1034 BorderWinpartHandleTooltip(wbit);
1035 BorderWinpartEventEnter(wbit, ev);
1038 BorderWinpartEventLeave(wbit, ev);
1041 BorderWinpartHandleTooltip(wbit);
1047 * Configuration load/save
1052 BorderPartLoad(FILE * fs, char type __UNUSED__, Border * b)
1055 char s[FILEPATH_LEN_MAX];
1056 char s2[FILEPATH_LEN_MAX];
1058 char iclass[64], aclass[64], tclass[64], cclass[64];
1059 char *piclass, *paclass, *ptclass, *pcclass;
1061 int flags = FLAG_BUTTON;
1062 char isregion = 0, keepshade = 1;
1063 int wmin = 0, wmax = 0, hmin = 0, hmax = 0, torigin =
1064 0, txp = 0, txa = 0, typ = 0, tya = 0, borigin = 0;
1065 int bxp = 0, bxa = 0, byp = 0, bya = 0;
1067 piclass = paclass = ptclass = pcclass = NULL;
1069 while (GetLine(s, sizeof(s), fs))
1071 i1 = ConfigParseline1(s, s2, NULL, NULL);
1076 BorderWinpartAdd(b, piclass, paclass, ptclass, pcclass, ontop,
1077 flags, isregion, wmin, wmax, hmin, hmax,
1078 torigin, txp, txa, typ, tya,
1079 borigin, bxp, bxa, byp, bya, keepshade);
1081 case CONFIG_IMAGECLASS:
1082 case BORDERPART_ICLASS:
1086 case CONFIG_ACTIONCLASS:
1087 case BORDERPART_ACLASS:
1092 case BORDERPART_TEXTCLASS:
1100 case BORDERPART_ONTOP:
1103 case BORDERPART_FLAGS:
1106 case BORDERPART_ISREGION:
1109 case BORDERPART_WMIN:
1114 case BORDERPART_WMAX:
1117 case BORDERPART_HMIN:
1122 case BORDERPART_HMAX:
1125 case BORDERPART_TORIGIN:
1128 case BORDERPART_TXP:
1131 case BORDERPART_TXA:
1134 case BORDERPART_TYP:
1137 case BORDERPART_TYA:
1140 case BORDERPART_BORIGIN:
1143 case BORDERPART_BXP:
1146 case BORDERPART_BXA:
1149 case BORDERPART_BYP:
1152 case BORDERPART_BYA:
1155 case BORDERPART_KEEPSHADE:
1168 BorderConfigLoad(FILE * fs)
1172 char s[FILEPATH_LEN_MAX];
1173 char s2[FILEPATH_LEN_MAX];
1176 while (GetLine(s, sizeof(s), fs))
1178 i1 = ConfigParseline1(s, s2, NULL, NULL);
1185 case CONFIG_CLASSNAME:
1192 b = BorderCreate(s2);
1204 if (i2 != CONFIG_OPEN)
1206 err = BorderPartLoad(fs, i1, b);
1210 case BORDER_GROUP_NAME:
1211 b->group_border_name = Estrdup(s2);
1214 b->border.left = i2;
1217 b->border.right = i2;
1223 b->border.bottom = i2;
1225 case BORDER_SHADEDIR:
1228 case BORDER_CHANGES_SHAPE:
1229 b->changes_shape = i2;
1231 case CONFIG_ACTIONCLASS:
1232 b->aclass = ActionclassFind(s2);
1243 BorderCreateFiller(int left, int right, int top, int bottom)
1247 b = BorderCreate("__FILLER");
1253 b->border.left = left;
1254 b->border.right = right;
1255 b->border.top = top;
1256 b->border.bottom = bottom;
1258 ImageclassGetBlack(); /* Creates the __BLACK ImageClass */
1261 BorderWinpartAdd(b, "__BLACK", NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
1263 -1, 0, 0, 0, 0, -1, 1024, -1, 0, top - 1, 1);
1265 BorderWinpartAdd(b, "__BLACK", NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
1267 -1, 0, 0, 1024, -bottom, -1, 1024, -1, 1024, -1, 1);
1269 BorderWinpartAdd(b, "__BLACK", NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
1272 -1, 0, left - 1, 1024, -(bottom + 1), 1);
1274 BorderWinpartAdd(b, "__BLACK", NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
1276 -1, 1024, -right, 0, top,
1277 -1, 1024, -1, 1024, -(bottom + 1), 1);
1283 BordersForeach(void (*func) (Border * b, void *data), void *data)
1285 ecore_list_for_each(border_list, (Ecore_For_Each) func, data);
1289 BordersGetList(int *pnum)
1291 return (Border **) ecore_list_items_get(border_list, pnum);
1294 static ActionClass *
1295 BorderGetFallbackAclass(void)
1300 ac = ActionclassFind("__fb_bd_ac");
1304 /* Create fallback actionclass for the fallback border */
1305 ac = ActionclassCreate("__fb_bd_ac", 0);
1309 aa = ActionCreate(EVENT_MOUSE_DOWN, 1, 0, 0, 1, 0, NULL, NULL);
1310 ActionclassAddAction(ac, aa);
1311 ActionAddTo(aa, "wop * mo ptr");
1313 aa = ActionCreate(EVENT_MOUSE_DOWN, 1, 0, 0, 2, 0, NULL, NULL);
1314 ActionclassAddAction(ac, aa);
1315 ActionAddTo(aa, "wop * close");
1317 aa = ActionCreate(EVENT_MOUSE_DOWN, 1, 0, 0, 3, 0, NULL, NULL);
1318 ActionclassAddAction(ac, aa);
1319 ActionAddTo(aa, "wop * sz ptr");
1325 BorderGetFallback(void)
1328 * This function creates simple internal data members to be used in
1329 * emergencies - ie when all else fails - ie a button is told to use an
1330 * imageclass that doesn't exist, or no DEFAULT border is defined... at
1331 * least E won't barf on us then.
1336 b = BorderFind("__fb_bd");
1340 ac = BorderGetFallbackAclass(); /* Creates the fallback ac */
1342 /* Create fallback border */
1343 b = BorderCreate("__fb_bd");
1348 b->border.right = 8;
1350 b->border.bottom = 8;
1351 BorderWinpartAdd(b, "__fb_ic", "__fb_bd_ac", NULL, NULL,
1352 1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, -1, 0, 0, 0, 0,
1353 -1, 1024, -1, 0, 7, 1);
1354 BorderWinpartAdd(b, "__fb_ic", "__fb_bd_ac", NULL, NULL,
1355 1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, -1, 0, 0, 1024,
1356 -8, -1, 1024, -1, 1024, -1, 1);
1357 BorderWinpartAdd(b, "__fb_ic", "__fb_bd_ac", NULL, NULL,
1358 1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, -1, 0, 0, 0, 8,
1359 -1, 0, 7, 1024, -9, 1);
1360 BorderWinpartAdd(b, "__fb_ic", "__fb_bd_ac", NULL, NULL,
1361 1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, -1, 1024, -8, 0,
1362 8, -1, 1024, -1, 1024, -9, 1);