1379 lines
33 KiB
C
1379 lines
33 KiB
C
/*
|
|
* Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
|
|
* Copyright (C) 2004-2007 Kim Woelders
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies of the Software, its documentation and marketing & publicity
|
|
* materials, and acknowledgment shall be given in the documentation, materials
|
|
* and software packages that this Software was used.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
#include "E.h"
|
|
#include "aclass.h"
|
|
#include "borders.h"
|
|
#include "cursors.h"
|
|
#include "e16-ecore_list.h"
|
|
#include "ewins.h"
|
|
#include "focus.h"
|
|
#include "grabs.h"
|
|
#include "hints.h"
|
|
#include "iclass.h"
|
|
#include "snaps.h"
|
|
#include "tclass.h"
|
|
#include "tooltips.h"
|
|
#include "windowmatch.h"
|
|
#include "xwin.h"
|
|
|
|
#define EWIN_BORDER_PART_EVENT_MASK \
|
|
(KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
|
|
EnterWindowMask | LeaveWindowMask | PointerMotionMask)
|
|
#define EWIN_BORDER_TITLE_EVENT_MASK \
|
|
(EWIN_BORDER_PART_EVENT_MASK)
|
|
|
|
static Ecore_List *border_list = NULL;
|
|
|
|
static void BorderDestroy(Border * b);
|
|
static void BorderWinpartHandleEvents(Win win, XEvent * ev, void *prm);
|
|
static void BorderFrameHandleEvents(Win win, XEvent * ev, void *prm);
|
|
|
|
static void
|
|
BorderWinpartRealise(EWin * ewin, int i)
|
|
{
|
|
EWinBit *ewb = &ewin->bits[i];
|
|
|
|
if ((ewb->cx != ewb->x) || (ewb->cy != ewb->y) ||
|
|
(ewb->cw != ewb->w) || (ewb->ch != ewb->h))
|
|
{
|
|
if ((ewb->w <= 0) || (ewb->h <= 0))
|
|
{
|
|
EUnmapWindow(ewb->win);
|
|
}
|
|
else
|
|
{
|
|
EMapWindow(ewb->win);
|
|
EMoveResizeWindow(ewb->win, ewb->x, ewb->y, ewb->w, ewb->h);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
BorderWinpartITclassApply(EWin * ewin, int i, int force)
|
|
{
|
|
EWinBit *ewb = &ewin->bits[i];
|
|
ImageState *is;
|
|
TextState *ts;
|
|
const char *txt;
|
|
|
|
if (ewb->win == None)
|
|
return;
|
|
|
|
#if 0 /* Debug */
|
|
Eprintf("BorderWpITApply: %#lx %#lx %2d %d %s\n",
|
|
EwinGetClientXwin(ewin), EoGetWin(ewin), i, force,
|
|
EwinGetTitle(ewin));
|
|
#endif
|
|
|
|
is = ImageclassGetImageState(ewin->border->part[i].iclass, ewb->state,
|
|
ewin->state.active, EoIsSticky(ewin));
|
|
|
|
ts = NULL;
|
|
txt = NULL;
|
|
switch (ewin->border->part[i].flags)
|
|
{
|
|
case FLAG_TITLE:
|
|
txt = EwinGetTitle(ewin);
|
|
if (txt && ewin->border->part[i].tclass)
|
|
ts = TextclassGetTextState(ewin->border->part[i].tclass, ewb->state,
|
|
ewin->state.active, EoIsSticky(ewin));
|
|
break;
|
|
case FLAG_MINIICON:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!force && ewb->is == is && ewb->ts == ts)
|
|
return;
|
|
ewb->is = is;
|
|
ewb->ts = ts;
|
|
|
|
ITApply(ewb->win, ewin->border->part[i].iclass, is, ewb->w, ewb->h,
|
|
ewb->state, ewin->state.active, EoIsSticky(ewin),
|
|
ST_BORDER, ewin->border->part[i].tclass, ts, txt);
|
|
}
|
|
|
|
static int
|
|
BorderWinpartDraw(EWin * ewin, int i)
|
|
{
|
|
EWinBit *ewb = &ewin->bits[i];
|
|
int move = 0, resize = 0, ret = 0;
|
|
|
|
if ((ewb->x != ewb->cx) || (ewb->y != ewb->cy))
|
|
{
|
|
move = 1;
|
|
ewb->cx = ewb->x;
|
|
ewb->cy = ewb->y;
|
|
ret = 1;
|
|
}
|
|
|
|
if ((ewb->w != ewb->cw) || (ewb->h != ewb->ch))
|
|
{
|
|
resize = 1;
|
|
ewb->cw = ewb->w;
|
|
ewb->ch = ewb->h;
|
|
}
|
|
|
|
if ((resize) || (ewb->expose))
|
|
{
|
|
BorderWinpartITclassApply(ewin, i, 1);
|
|
ewb->expose = 0;
|
|
ret = 1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
BorderWinpartChange(EWin * ewin, int i, int force)
|
|
{
|
|
BorderWinpartITclassApply(ewin, i, force);
|
|
|
|
if (ewin->update.shape || ewin->border->changes_shape)
|
|
EwinPropagateShapes(ewin);
|
|
}
|
|
|
|
void
|
|
EwinBorderDraw(EWin * ewin, int do_shape, int do_paint)
|
|
{
|
|
int i;
|
|
|
|
if (!ewin)
|
|
return;
|
|
|
|
#if 0 /* Debug */
|
|
Eprintf("EwinBorderDraw %#lx %s d=%d s=%d p=%d\n",
|
|
EwinGetClientXwin(ewin), EoGetName(ewin), EoGetDeskNum(ewin),
|
|
do_shape, do_paint);
|
|
#endif
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
BorderWinpartITclassApply(ewin, i, do_shape || do_paint);
|
|
|
|
if (do_shape || ewin->update.shape || ewin->border->changes_shape)
|
|
EwinPropagateShapes(ewin);
|
|
}
|
|
|
|
void
|
|
EwinBorderUpdateInfo(EWin * ewin)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
{
|
|
if (ewin->border->part[i].flags == FLAG_TITLE)
|
|
BorderWinpartITclassApply(ewin, i, 1);
|
|
}
|
|
}
|
|
|
|
static void
|
|
BorderWinpartCalc(EWin * ewin, int i, int ww, int hh)
|
|
{
|
|
int x, y, w, h, ox, oy, max, min;
|
|
int topleft, bottomright;
|
|
|
|
topleft = ewin->border->part[i].geom.topleft.originbox;
|
|
bottomright = ewin->border->part[i].geom.bottomright.originbox;
|
|
if (topleft >= 0)
|
|
BorderWinpartCalc(ewin, topleft, ww, hh);
|
|
if (bottomright >= 0)
|
|
BorderWinpartCalc(ewin, bottomright, ww, hh);
|
|
x = y = 0;
|
|
if (topleft == -1)
|
|
{
|
|
x = ((ewin->border->part[i].geom.topleft.x.percent *
|
|
ww) >> 10) + ewin->border->part[i].geom.topleft.x.absolute;
|
|
y = ((ewin->border->part[i].geom.topleft.y.percent *
|
|
hh) >> 10) + ewin->border->part[i].geom.topleft.y.absolute;
|
|
}
|
|
else if (topleft >= 0)
|
|
{
|
|
x = ((ewin->border->part[i].geom.topleft.x.percent *
|
|
ewin->bits[topleft].w) >> 10) +
|
|
ewin->border->part[i].geom.topleft.x.absolute +
|
|
ewin->bits[topleft].x;
|
|
y = ((ewin->border->part[i].geom.topleft.y.percent *
|
|
ewin->bits[topleft].h) >> 10) +
|
|
ewin->border->part[i].geom.topleft.y.absolute +
|
|
ewin->bits[topleft].y;
|
|
}
|
|
ox = oy = 0;
|
|
if (bottomright == -1)
|
|
{
|
|
ox = ((ewin->border->
|
|
part[i].geom.bottomright.x.percent * ww) >> 10) +
|
|
ewin->border->part[i].geom.bottomright.x.absolute;
|
|
oy = ((ewin->border->
|
|
part[i].geom.bottomright.y.percent * hh) >> 10) +
|
|
ewin->border->part[i].geom.bottomright.y.absolute;
|
|
}
|
|
else if (bottomright >= 0)
|
|
{
|
|
ox = ((ewin->border->part[i].geom.bottomright.x.percent *
|
|
ewin->bits[bottomright].w) >> 10) +
|
|
ewin->border->part[i].geom.bottomright.x.absolute +
|
|
ewin->bits[bottomright].x;
|
|
oy = ((ewin->border->part[i].geom.bottomright.y.percent *
|
|
ewin->bits[bottomright].h) >> 10) +
|
|
ewin->border->part[i].geom.bottomright.y.absolute +
|
|
ewin->bits[bottomright].y;
|
|
}
|
|
/*
|
|
* calculate height before width, because we may need it in order to
|
|
* determine the font size. But we might do it the other way around for
|
|
* side borders :-)
|
|
*/
|
|
|
|
h = (oy - y) + 1;
|
|
max = ewin->border->part[i].geom.height.max;
|
|
min = ewin->border->part[i].geom.height.min;
|
|
|
|
/*
|
|
* If the title bar max size is set to zero, then set the title bar size to
|
|
* just a little bit more than the size of the title text.
|
|
*/
|
|
|
|
if (max == 0 && ewin->border->part[i].flags == FLAG_TITLE)
|
|
{
|
|
int dummywidth, wmax, wmin;
|
|
ImageClass *iclass;
|
|
TextClass *tclass;
|
|
EImageBorder *pad;
|
|
|
|
/*
|
|
* calculate width before height, because we need it in order to
|
|
* determine the font size.
|
|
*/
|
|
|
|
w = (ox - x) + 1;
|
|
wmax = ewin->border->part[i].geom.width.max;
|
|
wmin = ewin->border->part[i].geom.width.min;
|
|
if (w > wmax)
|
|
{
|
|
w = wmax;
|
|
x = ((x + ox) - w) >> 1;
|
|
}
|
|
else if (w < wmin)
|
|
{
|
|
w = wmin;
|
|
}
|
|
iclass = ewin->border->part[i].iclass;
|
|
tclass = ewin->border->part[i].tclass;
|
|
pad = ImageclassGetPadding(iclass);
|
|
TextSize(tclass, ewin->state.active, EoIsSticky(ewin),
|
|
ewin->bits[i].state, EwinGetTitle(ewin), &max, &dummywidth,
|
|
w - (pad->top + pad->bottom));
|
|
max += pad->left + pad->right;
|
|
if (h > max)
|
|
{
|
|
y = y + (((h - max) * TextclassGetJustification(tclass)) >> 10);
|
|
h = max;
|
|
}
|
|
if (h < min)
|
|
{
|
|
h = min;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (h > max)
|
|
{
|
|
h = max;
|
|
y = ((y + oy) - h) >> 1;
|
|
}
|
|
else if (h < min)
|
|
{
|
|
h = min;
|
|
}
|
|
/*
|
|
* and now the width.
|
|
*/
|
|
|
|
w = (ox - x) + 1;
|
|
max = ewin->border->part[i].geom.width.max;
|
|
min = ewin->border->part[i].geom.width.min;
|
|
|
|
/*
|
|
* If the title bar max size is set to zero, then set the title bar
|
|
* size to just a little bit more than the size of the title text.
|
|
*/
|
|
|
|
if (max == 0 && ewin->border->part[i].flags == FLAG_TITLE)
|
|
{
|
|
int dummyheight;
|
|
ImageClass *iclass;
|
|
TextClass *tclass;
|
|
EImageBorder *pad;
|
|
|
|
iclass = ewin->border->part[i].iclass;
|
|
tclass = ewin->border->part[i].tclass;
|
|
pad = ImageclassGetPadding(iclass);
|
|
TextSize(tclass, ewin->state.active, EoIsSticky(ewin),
|
|
ewin->bits[i].state, EwinGetTitle(ewin), &max,
|
|
&dummyheight, h - (pad->top + pad->bottom));
|
|
max += pad->left + pad->right;
|
|
|
|
if (w > max)
|
|
{
|
|
x = x +
|
|
(((w - max) * TextclassGetJustification(tclass)) >> 10);
|
|
w = max;
|
|
}
|
|
}
|
|
if (w > max)
|
|
{
|
|
w = max;
|
|
x = ((x + ox) - w) >> 1;
|
|
}
|
|
else if (w < min)
|
|
{
|
|
w = min;
|
|
}
|
|
}
|
|
if ((ewin->state.shaded) && (!ewin->border->part[i].keep_for_shade))
|
|
{
|
|
ewin->bits[i].x = -100;
|
|
ewin->bits[i].y = -100;
|
|
ewin->bits[i].w = -1;
|
|
ewin->bits[i].h = -1;
|
|
}
|
|
else
|
|
{
|
|
ewin->bits[i].x = x;
|
|
ewin->bits[i].y = y;
|
|
ewin->bits[i].w = w;
|
|
ewin->bits[i].h = h;
|
|
}
|
|
}
|
|
|
|
void
|
|
EwinBorderCalcSizes(EWin * ewin, int propagate)
|
|
{
|
|
int i, ww, hh;
|
|
char reshape;
|
|
|
|
if (!ewin)
|
|
return;
|
|
if (!ewin->border)
|
|
return;
|
|
|
|
ww = EoGetW(ewin);
|
|
hh = EoGetH(ewin);
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
ewin->bits[i].w = -2;
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
if (ewin->bits[i].w == -2)
|
|
BorderWinpartCalc(ewin, i, ww, hh);
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
BorderWinpartRealise(ewin, i);
|
|
|
|
reshape = 0;
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
{
|
|
reshape |= BorderWinpartDraw(ewin, i);
|
|
ewin->bits[i].no_expose = 1;
|
|
}
|
|
|
|
#if 0 /* Debug */
|
|
Eprintf("EwinBorderCalcSizes prop=%d reshape=%d\n", propagate, reshape);
|
|
#endif
|
|
if (reshape)
|
|
ewin->update.shape = 1;
|
|
if (propagate && ewin->update.shape)
|
|
EwinPropagateShapes(ewin);
|
|
}
|
|
|
|
void
|
|
BorderIncRefcount(const Border * b)
|
|
{
|
|
((Border *) b)->ref_count++;
|
|
}
|
|
|
|
void
|
|
BorderDecRefcount(const Border * b)
|
|
{
|
|
((Border *) b)->ref_count--;
|
|
}
|
|
|
|
const char *
|
|
BorderGetName(const Border * b)
|
|
{
|
|
return (b) ? b->name : NULL;
|
|
}
|
|
|
|
void
|
|
EwinBorderSelect(EWin * ewin)
|
|
{
|
|
const Border *b;
|
|
|
|
if (ewin->inh_wm.b.border)
|
|
{
|
|
b = BorderFind("BORDERLESS");
|
|
goto done;
|
|
}
|
|
|
|
/* Quit if we already have a border that isn't an internal one */
|
|
b = ewin->border;
|
|
if (b && strncmp(b->name, "__", 2))
|
|
goto done;
|
|
|
|
b = NULL;
|
|
|
|
if (ewin->props.no_border)
|
|
b = BorderFind("BORDERLESS");
|
|
|
|
if (!b)
|
|
b = WindowMatchEwinBorder(ewin);
|
|
|
|
if (!b)
|
|
b = BorderFind("DEFAULT");
|
|
|
|
if (!b)
|
|
b = BorderFind("__FALLBACK_BORDER");
|
|
|
|
done:
|
|
ewin->normal_border = ewin->border = b;
|
|
}
|
|
|
|
void
|
|
EwinBorderDetach(EWin * ewin)
|
|
{
|
|
const Border *b = ewin->border;
|
|
int i;
|
|
|
|
if (!b)
|
|
return;
|
|
|
|
TooltipsSetPending(0, NULL, NULL);
|
|
|
|
EventCallbackUnregister(EoGetWin(ewin), 0, BorderFrameHandleEvents, ewin);
|
|
for (i = 0; i < b->num_winparts; i++)
|
|
{
|
|
EventCallbackUnregister(ewin->bits[i].win, 0,
|
|
BorderWinpartHandleEvents, &ewin->bits[i]);
|
|
if (ewin->bits[i].win)
|
|
EDestroyWindow(ewin->bits[i].win);
|
|
}
|
|
if (ewin->bits)
|
|
Efree(ewin->bits);
|
|
ewin->bits = NULL;
|
|
BorderDecRefcount(b);
|
|
|
|
ewin->border = NULL;
|
|
|
|
if (b->throwaway)
|
|
BorderDestroy((Border *) b);
|
|
}
|
|
|
|
void
|
|
EwinBorderSetTo(EWin * ewin, const Border * b)
|
|
{
|
|
int i;
|
|
|
|
if (ewin->border == b)
|
|
return;
|
|
|
|
if (b == NULL)
|
|
{
|
|
b = ewin->border;
|
|
ewin->border = NULL;
|
|
}
|
|
|
|
if (ewin->border)
|
|
EwinBorderDetach(ewin);
|
|
|
|
ewin->border = b;
|
|
BorderIncRefcount(b);
|
|
HintsSetWindowBorder(ewin);
|
|
|
|
ewin->state.no_border = b->num_winparts <= 0;
|
|
|
|
EventCallbackRegister(EoGetWin(ewin), 0, BorderFrameHandleEvents, ewin);
|
|
|
|
if (b->num_winparts > 0)
|
|
ewin->bits = Emalloc(sizeof(EWinBit) * b->num_winparts);
|
|
|
|
for (i = 0; i < b->num_winparts; i++)
|
|
{
|
|
ewin->bits[i].ewin = ewin; /* Reference to associated Ewin */
|
|
|
|
ewin->bits[i].win = ECreateWindow(EoGetWin(ewin), -10, -10, 1, 1, 0);
|
|
ECursorApply(b->part[i].ec, ewin->bits[i].win);
|
|
EMapWindow(ewin->bits[i].win);
|
|
EventCallbackRegister(ewin->bits[i].win, 0,
|
|
BorderWinpartHandleEvents, &ewin->bits[i]);
|
|
/*
|
|
* KeyPressMask KeyReleaseMask ButtonPressMask
|
|
* ButtonReleaseMask
|
|
* EnterWindowMask LeaveWindowMask PointerMotionMask
|
|
* PointerMotionHintMask Button1MotionMask
|
|
* Button2MotionMask
|
|
* Button3MotionMask Button4MotionMask Button5MotionMask
|
|
* ButtonMotionMask KeymapStateMask ExposureMask
|
|
* VisibilityChangeMask StructureNotifyMask
|
|
* ResizeRedirectMask
|
|
* SubstructureNotifyMask SubstructureRedirectMask
|
|
* FocusChangeMask PropertyChangeMas ColormapChangeMask
|
|
* OwnerGrabButtonMask
|
|
*/
|
|
if (b->part[i].flags & FLAG_TITLE)
|
|
ESelectInput(ewin->bits[i].win, EWIN_BORDER_TITLE_EVENT_MASK);
|
|
else
|
|
ESelectInput(ewin->bits[i].win, EWIN_BORDER_PART_EVENT_MASK);
|
|
ewin->bits[i].x = -10;
|
|
ewin->bits[i].y = -10;
|
|
ewin->bits[i].w = -10;
|
|
ewin->bits[i].h = -10;
|
|
ewin->bits[i].cx = -99;
|
|
ewin->bits[i].cy = -99;
|
|
ewin->bits[i].cw = -99;
|
|
ewin->bits[i].ch = -99;
|
|
ewin->bits[i].state = 0;
|
|
ewin->bits[i].expose = 0;
|
|
ewin->bits[i].no_expose = 0;
|
|
ewin->bits[i].left = 0;
|
|
ewin->bits[i].is = NULL;
|
|
}
|
|
|
|
{
|
|
Window *wl;
|
|
int j = 0;
|
|
|
|
wl = Emalloc((b->num_winparts + 1) * sizeof(Window));
|
|
for (i = b->num_winparts - 1; i >= 0; i--)
|
|
{
|
|
if (b->part[i].ontop)
|
|
wl[j++] = WinGetXwin(ewin->bits[i].win);
|
|
}
|
|
wl[j++] = WinGetXwin(ewin->win_container);
|
|
for (i = b->num_winparts - 1; i >= 0; i--)
|
|
{
|
|
if (!b->part[i].ontop)
|
|
wl[j++] = WinGetXwin(ewin->bits[i].win);
|
|
}
|
|
XRestackWindows(disp, wl, j);
|
|
Efree(wl);
|
|
}
|
|
|
|
if (!ewin->state.shaded)
|
|
EMoveWindow(ewin->win_container, b->border.left, b->border.top);
|
|
|
|
ewin->update.shape = 1;
|
|
EwinBorderCalcSizes(ewin, 0);
|
|
EwinStateUpdate(ewin);
|
|
|
|
SnapshotEwinUpdate(ewin, SNAP_USE_BORDER);
|
|
}
|
|
|
|
void
|
|
EwinSetBorder(EWin * ewin, const Border * b, int apply)
|
|
{
|
|
if (!b || ewin->border == b || ewin->inh_wm.b.border)
|
|
return;
|
|
|
|
if (apply)
|
|
{
|
|
EwinBorderSetTo(ewin, b);
|
|
EwinMoveResize(ewin, EoGetX(ewin), EoGetY(ewin),
|
|
ewin->client.w, ewin->client.h);
|
|
}
|
|
else
|
|
{
|
|
if (ewin->border)
|
|
BorderDecRefcount(ewin->border);
|
|
ewin->border = b;
|
|
BorderIncRefcount(b);
|
|
}
|
|
|
|
if (!ewin->state.fullscreen)
|
|
ewin->normal_border = b;
|
|
}
|
|
|
|
void
|
|
EwinSetBorderByName(EWin * ewin, const char *name)
|
|
{
|
|
EwinSetBorder(ewin, BorderFind(name), 0);
|
|
}
|
|
|
|
static Border *
|
|
BorderCreate(const char *name)
|
|
{
|
|
Border *b;
|
|
|
|
b = Ecalloc(1, sizeof(Border));
|
|
if (!b)
|
|
return NULL;
|
|
|
|
if (!border_list)
|
|
border_list = ecore_list_new();
|
|
ecore_list_prepend(border_list, b);
|
|
|
|
b->name = Estrdup(name);
|
|
b->group_border_name = NULL;
|
|
b->shadedir = 2;
|
|
|
|
return b;
|
|
}
|
|
|
|
static void
|
|
BorderDestroy(Border * b)
|
|
{
|
|
int i;
|
|
|
|
if (!b)
|
|
return;
|
|
|
|
if (b->ref_count > 0)
|
|
{
|
|
DialogOK("Border Error!", _("%u references remain\n"), b->ref_count);
|
|
return;
|
|
}
|
|
|
|
ecore_list_remove_node(border_list, b);
|
|
|
|
for (i = 0; i < b->num_winparts; i++)
|
|
{
|
|
if (b->part[i].iclass)
|
|
ImageclassDecRefcount(b->part[i].iclass);
|
|
if (b->part[i].tclass)
|
|
TextclassDecRefcount(b->part[i].tclass);
|
|
if (b->part[i].aclass)
|
|
ActionclassDecRefcount(b->part[i].aclass);
|
|
if (b->part[i].ec)
|
|
ECursorDecRefcount(b->part[i].ec);
|
|
}
|
|
|
|
if (b->num_winparts > 0)
|
|
Efree(b->part);
|
|
|
|
if (b->name)
|
|
Efree(b->name);
|
|
if (b->group_border_name)
|
|
Efree(b->group_border_name);
|
|
if (b->aclass)
|
|
ActionclassDecRefcount(b->aclass);
|
|
}
|
|
|
|
static int
|
|
_BorderMatchName(const void *data, const void *match)
|
|
{
|
|
return strcmp(((const Border *)data)->name, match);
|
|
}
|
|
|
|
Border *
|
|
BorderFind(const char *name)
|
|
{
|
|
return ecore_list_find(border_list, _BorderMatchName, name);
|
|
}
|
|
|
|
static void
|
|
BorderWinpartAdd(Border * b, ImageClass * iclass, ActionClass * aclass,
|
|
TextClass * tclass, ECursor * ec, char ontop, int flags,
|
|
char isregion __UNUSED__, int wmin, int wmax, int hmin,
|
|
int hmax, int torigin, int txp, int txa, int typ, int tya,
|
|
int borigin, int bxp, int bxa, int byp, int bya,
|
|
char keep_for_shade)
|
|
{
|
|
int n;
|
|
|
|
b->num_winparts++;
|
|
n = b->num_winparts;
|
|
|
|
b->part = Erealloc(b->part, n * sizeof(WinPart));
|
|
|
|
if (!iclass)
|
|
iclass = ImageclassFind(NULL, 0);
|
|
|
|
b->part[n - 1].iclass = iclass;
|
|
if (iclass)
|
|
ImageclassIncRefcount(iclass);
|
|
|
|
b->part[n - 1].aclass = aclass;
|
|
if (aclass)
|
|
ActionclassIncRefcount(aclass);
|
|
|
|
b->part[n - 1].tclass = tclass;
|
|
if (tclass)
|
|
TextclassIncRefcount(tclass);
|
|
|
|
b->part[n - 1].ec = ec;
|
|
if (ec)
|
|
ECursorIncRefcount(ec);
|
|
|
|
b->part[n - 1].ontop = ontop;
|
|
b->part[n - 1].flags = flags;
|
|
b->part[n - 1].keep_for_shade = keep_for_shade;
|
|
b->part[n - 1].geom.width.min = wmin;
|
|
b->part[n - 1].geom.width.max = wmax;
|
|
b->part[n - 1].geom.height.min = hmin;
|
|
b->part[n - 1].geom.height.max = hmax;
|
|
b->part[n - 1].geom.topleft.originbox = torigin;
|
|
b->part[n - 1].geom.topleft.x.percent = txp;
|
|
b->part[n - 1].geom.topleft.x.absolute = txa;
|
|
b->part[n - 1].geom.topleft.y.percent = typ;
|
|
b->part[n - 1].geom.topleft.y.absolute = tya;
|
|
b->part[n - 1].geom.bottomright.originbox = borigin;
|
|
b->part[n - 1].geom.bottomright.x.percent = bxp;
|
|
b->part[n - 1].geom.bottomright.x.absolute = bxa;
|
|
b->part[n - 1].geom.bottomright.y.percent = byp;
|
|
b->part[n - 1].geom.bottomright.y.absolute = bya;
|
|
}
|
|
|
|
void
|
|
EwinBorderMinShadeSize(EWin * ewin, int *mw, int *mh)
|
|
{
|
|
int i, pw, ph, w, h, min_w, min_h;
|
|
int leftborderwidth, rightborderwidth;
|
|
int topborderwidth, bottomborderwidth;
|
|
|
|
min_w = 32;
|
|
min_h = 32;
|
|
|
|
if (!ewin)
|
|
goto done;
|
|
|
|
pw = EoGetW(ewin);
|
|
ph = EoGetH(ewin);
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
ewin->bits[i].w = -2;
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
if (ewin->bits[i].w == -2)
|
|
BorderWinpartCalc(ewin, i, pw, ph);
|
|
|
|
switch (ewin->border->shadedir)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
/* get the correct width, based on the borderparts that */
|
|
/*are remaining visible */
|
|
leftborderwidth = rightborderwidth = 0;
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
{
|
|
if (!ewin->border->part[i].keep_for_shade)
|
|
continue;
|
|
|
|
w = ewin->border->border.left - ewin->bits[i].x;
|
|
if (leftborderwidth < w)
|
|
leftborderwidth = w;
|
|
|
|
w = ewin->bits[i].x + ewin->bits[i].w -
|
|
(EoGetW(ewin) - ewin->border->border.right);
|
|
if (rightborderwidth < w)
|
|
rightborderwidth = w;
|
|
}
|
|
pw = rightborderwidth + leftborderwidth;
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
topborderwidth = bottomborderwidth = 0;
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
{
|
|
if (!ewin->border->part[i].keep_for_shade)
|
|
continue;
|
|
|
|
h = ewin->border->border.top - ewin->bits[i].y;
|
|
if (topborderwidth < h)
|
|
topborderwidth = h;
|
|
|
|
h = ewin->bits[i].y + ewin->bits[i].h -
|
|
(EoGetH(ewin) - ewin->border->border.bottom);
|
|
if (bottomborderwidth < h)
|
|
bottomborderwidth = h;
|
|
}
|
|
ph = bottomborderwidth + topborderwidth;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
ewin->bits[i].w = -2;
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
if (ewin->bits[i].w == -2)
|
|
BorderWinpartCalc(ewin, i, pw, ph);
|
|
|
|
min_w = 0;
|
|
min_h = 0;
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
{
|
|
if (!ewin->border->part[i].keep_for_shade)
|
|
continue;
|
|
|
|
w = ewin->bits[i].x + ewin->bits[i].w;
|
|
if (min_w < w)
|
|
min_w = w;
|
|
|
|
h = ewin->bits[i].y + ewin->bits[i].h;
|
|
if (min_h < h)
|
|
min_h = h;
|
|
}
|
|
|
|
done:
|
|
*mw = min_w;
|
|
*mh = min_h;
|
|
}
|
|
|
|
int
|
|
BorderWinpartIndex(EWin * ewin, Win win)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
{
|
|
if (win == ewin->bits[i].win)
|
|
return i;
|
|
}
|
|
|
|
return -1; /* Not found */
|
|
}
|
|
|
|
void
|
|
EwinBorderEventsConfigure(EWin * ewin, int mode)
|
|
{
|
|
int i;
|
|
long emask;
|
|
|
|
emask = (mode) ? ~((long)0) : ~(EnterWindowMask | LeaveWindowMask);
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
{
|
|
if (ewin->border->part[i].flags & FLAG_TITLE)
|
|
ESelectInput(ewin->bits[i].win,
|
|
EWIN_BORDER_TITLE_EVENT_MASK & emask);
|
|
else
|
|
ESelectInput(ewin->bits[i].win, EWIN_BORDER_PART_EVENT_MASK & emask);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Border event handlers
|
|
*/
|
|
#define DEBUG_BORDER_EVENTS 0
|
|
|
|
static void
|
|
BorderWinpartEventMouseDown(EWinBit * wbit, XEvent * ev)
|
|
{
|
|
EWin *ewin = wbit->ewin;
|
|
int part = wbit - ewin->bits;
|
|
|
|
GrabPointerSet(wbit->win, 0, 0);
|
|
|
|
wbit->state = STATE_CLICKED;
|
|
#if DEBUG_BORDER_EVENTS
|
|
Eprintf("BorderWinpartEventMouseDown %#lx %d\n", WinGetXwin(wbit->win),
|
|
wbit->state);
|
|
#endif
|
|
BorderWinpartChange(ewin, part, 0);
|
|
|
|
FocusHandleClick(ewin, wbit->win);
|
|
|
|
if (ewin->border->part[part].aclass)
|
|
ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
|
|
}
|
|
|
|
static void
|
|
BorderWinpartEventMouseUp(EWinBit * wbit, XEvent * ev)
|
|
{
|
|
EWin *ewin = wbit->ewin;
|
|
int part = wbit - ewin->bits;
|
|
int left = wbit->left;
|
|
|
|
GrabPointerRelease();
|
|
|
|
if ((wbit->state == STATE_CLICKED) && (!wbit->left))
|
|
wbit->state = STATE_HILITED;
|
|
else
|
|
wbit->state = STATE_NORMAL;
|
|
#if DEBUG_BORDER_EVENTS
|
|
Eprintf("BorderWinpartEventMouseUp %#lx %d\n", WinGetXwin(wbit->win),
|
|
wbit->state);
|
|
#endif
|
|
BorderWinpartChange(ewin, part, 0);
|
|
|
|
/* Beware! Actions may destroy the current border */
|
|
wbit->left = 0;
|
|
|
|
if (ev && WinGetXwin(wbit->win) == Mode.events.last_bpress && !left &&
|
|
ewin->border->part[part].aclass)
|
|
ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
|
|
}
|
|
|
|
static void
|
|
BorderWinpartEventEnter(EWinBit * wbit, XEvent * ev)
|
|
{
|
|
EWin *ewin = wbit->ewin;
|
|
int part = wbit - ewin->bits;
|
|
|
|
#if DEBUG_BORDER_EVENTS
|
|
Eprintf("BorderWinpartEventEnter %#lx %d\n", WinGetXwin(wbit->win),
|
|
wbit->state);
|
|
#endif
|
|
if (wbit->state == STATE_CLICKED)
|
|
wbit->left = 0;
|
|
#if 0 /* Hmmm.. */
|
|
else
|
|
#endif
|
|
{
|
|
wbit->state = STATE_HILITED;
|
|
BorderWinpartChange(ewin, part, 0);
|
|
if (ewin->border->part[part].aclass)
|
|
ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
|
|
}
|
|
}
|
|
|
|
static void
|
|
BorderWinpartEventLeave(EWinBit * wbit, XEvent * ev)
|
|
{
|
|
EWin *ewin = wbit->ewin;
|
|
int part = wbit - ewin->bits;
|
|
|
|
#if DEBUG_BORDER_EVENTS
|
|
Eprintf("BorderWinpartEventLeave %#lx %d\n", WinGetXwin(wbit->win),
|
|
wbit->state);
|
|
#endif
|
|
if (wbit->state == STATE_CLICKED)
|
|
wbit->left = 1;
|
|
else
|
|
{
|
|
wbit->state = STATE_NORMAL;
|
|
BorderWinpartChange(ewin, part, 0);
|
|
if (ewin->border->part[part].aclass)
|
|
ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
|
|
}
|
|
}
|
|
|
|
void
|
|
BorderCheckState(EWin * ewin, XEvent * ev)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
{
|
|
switch (ev->type)
|
|
{
|
|
default:
|
|
break;
|
|
|
|
case ButtonRelease:
|
|
BorderWinpartEventMouseUp(ewin->bits + i, NULL);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
BorderFrameHandleEvents(Win win __UNUSED__, XEvent * ev, void *prm)
|
|
{
|
|
EWin *ewin = (EWin *) prm;
|
|
|
|
switch (ev->type)
|
|
{
|
|
case EnterNotify:
|
|
case LeaveNotify:
|
|
if (ewin->border->aclass)
|
|
ActionclassEvent(ewin->border->aclass, ev, ewin);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static ActionClass *
|
|
BorderWinpartGetAclass(void *data)
|
|
{
|
|
EWinBit *wbit = (EWinBit *) data;
|
|
EWin *ewin;
|
|
int part;
|
|
|
|
/* Validate border part */
|
|
ewin = Mode.mouse_over_ewin;
|
|
if (!ewin)
|
|
return NULL;
|
|
|
|
part = wbit - ewin->bits;
|
|
if (part < 0 || part >= ewin->border->num_winparts)
|
|
return NULL;
|
|
|
|
return ewin->border->part[part].aclass;
|
|
}
|
|
|
|
static void
|
|
BorderWinpartHandleTooltip(EWinBit * wbit, int event)
|
|
{
|
|
EWin *ewin = wbit->ewin;
|
|
int part = wbit - ewin->bits;
|
|
|
|
switch (event)
|
|
{
|
|
case ButtonPress:
|
|
case LeaveNotify:
|
|
TooltipsSetPending(0, NULL, NULL);
|
|
break;
|
|
case ButtonRelease:
|
|
case EnterNotify:
|
|
case MotionNotify:
|
|
if (!ewin->border->part[part].aclass)
|
|
return;
|
|
TooltipsSetPending(0, BorderWinpartGetAclass, wbit);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
BorderWinpartHandleEvents(Win win __UNUSED__, XEvent * ev, void *prm)
|
|
{
|
|
EWinBit *wbit = (EWinBit *) prm;
|
|
|
|
/* Beware! Actions may destroy the current border */
|
|
BorderWinpartHandleTooltip(wbit, ev->type);
|
|
|
|
switch (ev->type)
|
|
{
|
|
case ButtonPress:
|
|
BorderWinpartEventMouseDown(wbit, ev);
|
|
break;
|
|
case ButtonRelease:
|
|
BorderWinpartEventMouseUp(wbit, ev);
|
|
break;
|
|
case EnterNotify:
|
|
BorderWinpartEventEnter(wbit, ev);
|
|
break;
|
|
case LeaveNotify:
|
|
BorderWinpartEventLeave(wbit, ev);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Configuration load/save
|
|
*/
|
|
#include "conf.h"
|
|
|
|
static int
|
|
BorderPartLoad(FILE * fs, char type __UNUSED__, Border * b)
|
|
{
|
|
int err = 0;
|
|
char s[FILEPATH_LEN_MAX];
|
|
char s2[FILEPATH_LEN_MAX];
|
|
int i1;
|
|
ImageClass *iclass = 0;
|
|
ActionClass *aclass = 0;
|
|
TextClass *tclass = 0;
|
|
ECursor *ec = NULL;
|
|
char ontop = 1;
|
|
int flags = FLAG_BUTTON;
|
|
char isregion = 0, keepshade = 1;
|
|
int wmin = 0, wmax = 0, hmin = 0, hmax = 0, torigin =
|
|
0, txp = 0, txa = 0, typ = 0, tya = 0, borigin = 0;
|
|
int bxp = 0, bxa = 0, byp = 0, bya = 0;
|
|
int fields;
|
|
|
|
while (GetLine(s, sizeof(s), fs))
|
|
{
|
|
s2[0] = 0;
|
|
i1 = CONFIG_INVALID;
|
|
fields = sscanf(s, "%i %4000s", &i1, s2);
|
|
|
|
if (fields < 1)
|
|
{
|
|
i1 = CONFIG_INVALID;
|
|
}
|
|
else if (i1 == CONFIG_CLOSE)
|
|
{
|
|
if (fields != 1)
|
|
Alert(_("CONFIG: ignoring extra data in \"%s\"\n"), s);
|
|
}
|
|
else if (i1 != CONFIG_INVALID)
|
|
{
|
|
if (fields != 2)
|
|
{
|
|
Alert(_("CONFIG: missing required data in \"%s\"\n"), s);
|
|
i1 = CONFIG_INVALID;
|
|
}
|
|
}
|
|
switch (i1)
|
|
{
|
|
case CONFIG_CLOSE:
|
|
BorderWinpartAdd(b, iclass, aclass, tclass, ec, ontop, flags,
|
|
isregion, wmin, wmax, hmin, hmax, torigin, txp,
|
|
txa, typ, tya, borigin, bxp, bxa, byp, bya,
|
|
keepshade);
|
|
goto done;
|
|
case CONFIG_IMAGECLASS:
|
|
case BORDERPART_ICLASS:
|
|
iclass = ImageclassFind(s2, 1);
|
|
break;
|
|
case CONFIG_ACTIONCLASS:
|
|
case BORDERPART_ACLASS:
|
|
aclass = ActionclassFind(s2);
|
|
break;
|
|
case CONFIG_TEXT:
|
|
case BORDERPART_TEXTCLASS:
|
|
tclass = TextclassFind(s2, 1);
|
|
break;
|
|
case CONFIG_CURSOR:
|
|
ec = ECursorFind(s2);
|
|
break;
|
|
case BORDERPART_ONTOP:
|
|
ontop = atoi(s2);
|
|
break;
|
|
case BORDERPART_FLAGS:
|
|
flags = atoi(s2);
|
|
break;
|
|
case BORDERPART_ISREGION:
|
|
isregion = atoi(s2);
|
|
break;
|
|
case BORDERPART_WMIN:
|
|
wmin = atoi(s2);
|
|
if (!wmax)
|
|
wmax = wmin;
|
|
break;
|
|
case BORDERPART_WMAX:
|
|
wmax = atoi(s2);
|
|
break;
|
|
case BORDERPART_HMIN:
|
|
hmin = atoi(s2);
|
|
if (!hmax)
|
|
hmax = hmin;
|
|
break;
|
|
case BORDERPART_HMAX:
|
|
hmax = atoi(s2);
|
|
break;
|
|
case BORDERPART_TORIGIN:
|
|
torigin = atoi(s2);
|
|
break;
|
|
case BORDERPART_TXP:
|
|
txp = atoi(s2);
|
|
break;
|
|
case BORDERPART_TXA:
|
|
txa = atoi(s2);
|
|
break;
|
|
case BORDERPART_TYP:
|
|
typ = atoi(s2);
|
|
break;
|
|
case BORDERPART_TYA:
|
|
tya = atoi(s2);
|
|
break;
|
|
case BORDERPART_BORIGIN:
|
|
borigin = atoi(s2);
|
|
break;
|
|
case BORDERPART_BXP:
|
|
bxp = atoi(s2);
|
|
break;
|
|
case BORDERPART_BXA:
|
|
bxa = atoi(s2);
|
|
break;
|
|
case BORDERPART_BYP:
|
|
byp = atoi(s2);
|
|
break;
|
|
case BORDERPART_BYA:
|
|
bya = atoi(s2);
|
|
break;
|
|
case BORDERPART_KEEPSHADE:
|
|
keepshade = atoi(s2);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
err = -1;
|
|
done:
|
|
return err;
|
|
}
|
|
|
|
int
|
|
BorderConfigLoad(FILE * fs)
|
|
{
|
|
int err = 0;
|
|
Border *b = 0;
|
|
char s[FILEPATH_LEN_MAX];
|
|
char s2[FILEPATH_LEN_MAX];
|
|
int i1;
|
|
int fields;
|
|
|
|
while (GetLine(s, sizeof(s), fs))
|
|
{
|
|
s2[0] = 0;
|
|
i1 = CONFIG_INVALID;
|
|
fields = sscanf(s, "%i %4000s", &i1, s2);
|
|
|
|
if (fields < 1)
|
|
{
|
|
i1 = CONFIG_INVALID;
|
|
}
|
|
else if (i1 == CONFIG_CLOSE)
|
|
{
|
|
if (fields != 1)
|
|
Alert(_("CONFIG: ignoring extra data in \"%s\"\n"), s);
|
|
}
|
|
else if (i1 != CONFIG_INVALID)
|
|
{
|
|
if (fields != 2)
|
|
{
|
|
Alert(_("CONFIG: missing required data in \"%s\"\n"), s);
|
|
i1 = CONFIG_INVALID;
|
|
}
|
|
}
|
|
if (atoi(s2) == CONFIG_OPEN)
|
|
{
|
|
err = BorderPartLoad(fs, i1, b);
|
|
if (err)
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
switch (i1)
|
|
{
|
|
case CONFIG_CLOSE:
|
|
goto done;
|
|
case BORDER_INIT:
|
|
break;
|
|
case CONFIG_CLASSNAME:
|
|
case BORDER_NAME:
|
|
if (BorderFind(s2))
|
|
{
|
|
SkipTillEnd(fs);
|
|
goto done;
|
|
}
|
|
b = BorderCreate(s2);
|
|
break;
|
|
case BORDER_GROUP_NAME:
|
|
b->group_border_name = Estrdup(s2);
|
|
break;
|
|
case BORDER_LEFT:
|
|
b->border.left = atoi(s2);
|
|
break;
|
|
case BORDER_RIGHT:
|
|
b->border.right = atoi(s2);
|
|
break;
|
|
case BORDER_TOP:
|
|
b->border.top = atoi(s2);
|
|
break;
|
|
case BORDER_BOTTOM:
|
|
b->border.bottom = atoi(s2);
|
|
break;
|
|
case SHADEDIR:
|
|
b->shadedir = atoi(s2);
|
|
break;
|
|
case BORDER_CHANGES_SHAPE:
|
|
b->changes_shape = atoi(s2);
|
|
break;
|
|
case CONFIG_ACTIONCLASS:
|
|
b->aclass = ActionclassFind(s2);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
err = -1;
|
|
|
|
done:
|
|
return err;
|
|
}
|
|
|
|
Border *
|
|
BorderCreateFiller(int left, int right, int top, int bottom)
|
|
{
|
|
Border *b;
|
|
ImageClass *ic;
|
|
|
|
ic = ImageclassFind("__BLACK", 1);
|
|
|
|
b = BorderCreate("__FILLER");
|
|
b->throwaway = 1;
|
|
|
|
b->border.left = left;
|
|
b->border.right = right;
|
|
b->border.top = top;
|
|
b->border.bottom = bottom;
|
|
|
|
if (top)
|
|
BorderWinpartAdd(b, ic, NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
|
|
1, 99999, 1, 99999,
|
|
-1, 0, 0, 0, 0, -1, 1024, -1, 0, top - 1, 1);
|
|
if (bottom)
|
|
BorderWinpartAdd(b, ic, NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
|
|
1, 99999, 1, 99999,
|
|
-1, 0, 0, 1024, -bottom, -1, 1024, -1, 1024, -1, 1);
|
|
if (left)
|
|
BorderWinpartAdd(b, ic, NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
|
|
1, 99999, 1, 99999,
|
|
-1, 0, 0, 0, top,
|
|
-1, 0, left - 1, 1024, -(bottom + 1), 1);
|
|
if (right)
|
|
BorderWinpartAdd(b, ic, NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
|
|
1, 99999, 1, 99999,
|
|
-1, 1024, -right, 0, top,
|
|
-1, 1024, -1, 1024, -(bottom + 1), 1);
|
|
|
|
return b;
|
|
}
|
|
|
|
void
|
|
BordersForeach(void (*func) (Border * b, void *data), void *data)
|
|
{
|
|
ecore_list_for_each(border_list, (Ecore_For_Each) func, data);
|
|
}
|
|
|
|
Border **
|
|
BordersGetList(int *pnum)
|
|
{
|
|
return (Border **) ecore_list_items_get(border_list, pnum);
|
|
}
|
|
|
|
void
|
|
BordersSetupFallback(void)
|
|
{
|
|
/*
|
|
* This function creates simple internal data members to be used in
|
|
* emergencies - ie when all else fails - ie a button is told to use an
|
|
* imageclass that doesn't exist, or no DEFAULT border is defined... at
|
|
* least E won't barf on us then.
|
|
*/
|
|
Border *b;
|
|
ImageClass *ic;
|
|
ActionClass *ac;
|
|
|
|
ac = ActionclassFind("__FALLBACK_ACTION");
|
|
ic = ImageclassFind("__FALLBACK_ICLASS", 0);
|
|
|
|
/* create a fallback border in case no border is found */
|
|
b = BorderCreate("__FALLBACK_BORDER");
|
|
|
|
b->border.left = 8;
|
|
b->border.right = 8;
|
|
b->border.top = 8;
|
|
b->border.bottom = 8;
|
|
BorderWinpartAdd(b, ic, ac, NULL, NULL, 1, FLAG_BUTTON, 0, 8, 99999, 8,
|
|
99999, -1, 0, 0, 0, 0, -1, 1024, -1, 0, 7, 1);
|
|
BorderWinpartAdd(b, ic, ac, NULL, NULL, 1, FLAG_BUTTON, 0, 8, 99999, 8,
|
|
99999, -1, 0, 0, 1024, -8, -1, 1024, -1, 1024, -1, 1);
|
|
BorderWinpartAdd(b, ic, ac, NULL, NULL, 1, FLAG_BUTTON, 0, 8, 99999, 8,
|
|
99999, -1, 0, 0, 0, 8, -1, 0, 7, 1024, -9, 1);
|
|
BorderWinpartAdd(b, ic, ac, NULL, NULL, 1, FLAG_BUTTON, 0, 8, 99999, 8,
|
|
99999, -1, 1024, -8, 0, 8, -1, 1024, -1, 1024, -9, 1);
|
|
}
|