1999-10-04 15:06:00 -07:00
|
|
|
/*
|
2007-01-13 11:14:29 -08:00
|
|
|
* Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
|
2018-02-04 00:35:32 -08:00
|
|
|
* Copyright (C) 2004-2018 Kim Woelders
|
2000-04-05 16:22:56 -07:00
|
|
|
*
|
1999-10-04 15:06:00 -07:00
|
|
|
* 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:
|
2000-04-05 16:22:56 -07:00
|
|
|
*
|
1999-10-04 15:06:00 -07:00
|
|
|
* 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.
|
2000-04-05 16:22:56 -07:00
|
|
|
*
|
1999-10-04 15:06:00 -07:00
|
|
|
* 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.
|
|
|
|
*/
|
2015-01-17 11:06:03 -08:00
|
|
|
#include "config.h"
|
|
|
|
|
2015-01-15 22:25:38 -08:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
|
1999-08-17 15:56:46 -07:00
|
|
|
#include "E.h"
|
2005-11-27 05:11:06 -08:00
|
|
|
#include "aclass.h"
|
2005-12-22 10:43:15 -08:00
|
|
|
#include "borders.h"
|
2006-11-19 13:55:52 -08:00
|
|
|
#include "cursors.h"
|
2005-07-16 09:57:45 -07:00
|
|
|
#include "ewins.h"
|
2006-11-19 13:55:52 -08:00
|
|
|
#include "focus.h"
|
|
|
|
#include "grabs.h"
|
2005-10-27 16:18:35 -07:00
|
|
|
#include "hints.h"
|
2005-09-26 10:32:10 -07:00
|
|
|
#include "iclass.h"
|
2009-10-17 01:04:48 -07:00
|
|
|
#include "icons.h"
|
2013-06-06 13:37:06 -07:00
|
|
|
#include "list.h"
|
2005-03-24 01:40:59 -08:00
|
|
|
#include "snaps.h"
|
2005-09-26 10:32:10 -07:00
|
|
|
#include "tclass.h"
|
2009-03-21 13:58:00 -07:00
|
|
|
#include "timers.h"
|
2005-08-20 06:55:51 -07:00
|
|
|
#include "tooltips.h"
|
2006-11-19 13:55:52 -08:00
|
|
|
#include "windowmatch.h"
|
2005-07-16 09:57:45 -07:00
|
|
|
#include "xwin.h"
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2004-04-15 12:44:38 -07:00
|
|
|
#define EWIN_BORDER_PART_EVENT_MASK \
|
|
|
|
(KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
|
2005-01-28 23:41:49 -08:00
|
|
|
EnterWindowMask | LeaveWindowMask | PointerMotionMask)
|
2004-04-15 12:44:38 -07:00
|
|
|
#define EWIN_BORDER_TITLE_EVENT_MASK \
|
2005-01-28 23:41:49 -08:00
|
|
|
(EWIN_BORDER_PART_EVENT_MASK)
|
2004-04-15 12:44:38 -07:00
|
|
|
|
2013-06-06 13:37:06 -07:00
|
|
|
static LIST_HEAD(border_list);
|
2006-02-18 00:30:09 -08:00
|
|
|
|
2010-07-18 11:52:45 -07:00
|
|
|
static void BorderDestroy(Border * b);
|
2006-04-29 12:39:21 -07:00
|
|
|
static void BorderWinpartHandleEvents(Win win, XEvent * ev, void *prm);
|
|
|
|
static void BorderFrameHandleEvents(Win win, XEvent * ev, void *prm);
|
2008-06-22 06:34:42 -07:00
|
|
|
static Border *BorderGetFallback(void);
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2004-06-07 09:46:08 -07:00
|
|
|
static void
|
|
|
|
BorderWinpartRealise(EWin * ewin, int i)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2004-06-07 09:46:08 -07:00
|
|
|
EWinBit *ewb = &ewin->bits[i];
|
|
|
|
|
|
|
|
if ((ewb->cx != ewb->x) || (ewb->cy != ewb->y) ||
|
|
|
|
(ewb->cw != ewb->w) || (ewb->ch != ewb->h))
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2005-06-02 12:02:13 -07:00
|
|
|
if ((ewb->w <= 0) || (ewb->h <= 0))
|
2004-06-07 09:46:08 -07:00
|
|
|
{
|
2005-02-02 09:12:07 -08:00
|
|
|
EUnmapWindow(ewb->win);
|
2004-06-07 09:46:08 -07:00
|
|
|
}
|
2003-05-22 12:15:03 -07:00
|
|
|
else
|
2004-06-07 09:46:08 -07:00
|
|
|
{
|
2005-02-02 09:12:07 -08:00
|
|
|
EMapWindow(ewb->win);
|
|
|
|
EMoveResizeWindow(ewb->win, ewb->x, ewb->y, ewb->w, ewb->h);
|
2004-06-07 09:46:08 -07:00
|
|
|
}
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2004-04-09 06:45:59 -07:00
|
|
|
static void
|
2004-06-26 10:49:01 -07:00
|
|
|
BorderWinpartITclassApply(EWin * ewin, int i, int force)
|
2004-04-09 06:45:59 -07:00
|
|
|
{
|
2004-06-07 09:46:08 -07:00
|
|
|
EWinBit *ewb = &ewin->bits[i];
|
2009-10-25 01:17:18 -07:00
|
|
|
WinPart *ebp = &ewin->border->part[i];
|
2004-06-26 10:49:01 -07:00
|
|
|
ImageState *is;
|
2004-12-12 12:00:18 -08:00
|
|
|
TextState *ts;
|
2005-01-28 23:41:49 -08:00
|
|
|
const char *txt;
|
2009-10-17 01:04:48 -07:00
|
|
|
int flags;
|
2004-05-24 10:39:51 -07:00
|
|
|
|
2017-02-11 23:11:34 -08:00
|
|
|
if (!ewb->win)
|
2004-06-26 10:49:01 -07:00
|
|
|
return;
|
|
|
|
|
2005-01-29 07:00:00 -08:00
|
|
|
#if 0 /* Debug */
|
2014-05-10 05:37:15 -07:00
|
|
|
Eprintf("%s: %#x %#x %2d %d %s\n", __func__,
|
|
|
|
EwinGetClientXwin(ewin), EoGetXwin(ewin), i, force,
|
2006-11-26 03:30:59 -08:00
|
|
|
EwinGetTitle(ewin));
|
2005-01-29 07:00:00 -08:00
|
|
|
#endif
|
|
|
|
|
2009-10-25 01:17:18 -07:00
|
|
|
is = ImageclassGetImageState(ebp->iclass, ewb->state,
|
2005-07-08 09:48:19 -07:00
|
|
|
ewin->state.active, EoIsSticky(ewin));
|
2004-04-09 06:45:59 -07:00
|
|
|
|
2005-01-28 23:41:49 -08:00
|
|
|
ts = NULL;
|
|
|
|
txt = NULL;
|
2009-10-17 01:04:48 -07:00
|
|
|
flags = 0;
|
2009-10-25 01:17:18 -07:00
|
|
|
if (ebp->flags & FLAG_TITLE)
|
2004-05-24 10:39:51 -07:00
|
|
|
{
|
2006-11-26 03:30:59 -08:00
|
|
|
txt = EwinGetTitle(ewin);
|
2009-10-25 01:17:18 -07:00
|
|
|
if (txt && ebp->tclass)
|
|
|
|
{
|
|
|
|
ts = TextclassGetTextState(ebp->tclass, ewb->state,
|
|
|
|
ewin->state.active, EoIsSticky(ewin));
|
|
|
|
flags = ITA_BGPMAP | ITA_JUSTV;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ebp->flags & FLAG_MINIICON)
|
|
|
|
{
|
|
|
|
flags |= ITA_BGPMAP;
|
2004-05-24 10:39:51 -07:00
|
|
|
}
|
2005-01-28 23:41:49 -08:00
|
|
|
|
|
|
|
if (!force && ewb->is == is && ewb->ts == ts)
|
|
|
|
return;
|
|
|
|
ewb->is = is;
|
|
|
|
ewb->ts = ts;
|
|
|
|
|
2018-02-04 00:35:32 -08:00
|
|
|
ITApply(ewb->win, ebp->iclass, is, ewb->state, ewin->state.active,
|
|
|
|
EoIsSticky(ewin), ebp->tclass, ts, txt, flags);
|
2009-10-17 01:04:48 -07:00
|
|
|
|
2009-10-25 01:17:18 -07:00
|
|
|
if (ebp->flags & FLAG_MINIICON)
|
2009-10-17 01:04:48 -07:00
|
|
|
{
|
|
|
|
EImage *im;
|
|
|
|
|
|
|
|
im = EwinIconImageGet(ewin, 16, Conf.warplist.icon_mode);
|
|
|
|
if (im)
|
|
|
|
{
|
2009-12-03 11:29:30 -08:00
|
|
|
EX_Pixmap pmap;
|
2009-10-17 01:04:48 -07:00
|
|
|
EImageBorder *pad;
|
|
|
|
int x, y, w, h;
|
|
|
|
|
|
|
|
x = y = 0;
|
|
|
|
w = WinGetW(ewb->win);
|
|
|
|
h = WinGetH(ewb->win);
|
2009-10-25 01:17:18 -07:00
|
|
|
pad = ImageclassGetPadding(ebp->iclass);
|
|
|
|
if (ts)
|
|
|
|
{
|
|
|
|
/* Occupy square on one side */
|
|
|
|
switch (ts->style.orientation)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case FONT_TO_RIGHT:
|
|
|
|
case FONT_TO_LEFT:
|
|
|
|
w = h;
|
|
|
|
break;
|
|
|
|
case FONT_TO_UP:
|
|
|
|
y = h - w;
|
2010-06-06 03:05:50 -07:00
|
|
|
/* FALLTHROUGH */
|
2009-10-25 01:17:18 -07:00
|
|
|
case FONT_TO_DOWN:
|
|
|
|
h = w;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-10-17 01:04:48 -07:00
|
|
|
if (pad)
|
|
|
|
{
|
2009-10-25 01:17:18 -07:00
|
|
|
/* Probably not quite right for vertical borders */
|
2009-10-17 01:04:48 -07:00
|
|
|
x += pad->left;
|
|
|
|
y += pad->top;
|
2009-10-25 01:17:18 -07:00
|
|
|
w -= pad->left + pad->right;
|
|
|
|
h -= pad->top + pad->bottom;
|
2009-10-17 01:04:48 -07:00
|
|
|
}
|
2009-10-25 01:17:18 -07:00
|
|
|
if (w < 8 || h < 8)
|
|
|
|
goto skip_icon;
|
2009-10-17 01:04:48 -07:00
|
|
|
pmap = EGetWindowBackgroundPixmap(ewb->win);
|
|
|
|
EImageRenderOnDrawable(im, ewb->win, pmap,
|
|
|
|
EIMAGE_BLEND | EIMAGE_ANTI_ALIAS,
|
|
|
|
x, y, w, h);
|
|
|
|
EClearWindow(ewb->win);
|
2009-10-25 01:17:18 -07:00
|
|
|
skip_icon:
|
|
|
|
EImageFree(im);
|
2009-10-17 01:04:48 -07:00
|
|
|
}
|
|
|
|
}
|
2004-04-09 06:45:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2004-06-07 09:46:08 -07:00
|
|
|
BorderWinpartDraw(EWin * ewin, int i)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2004-06-07 09:46:08 -07:00
|
|
|
EWinBit *ewb = &ewin->bits[i];
|
2010-01-29 11:45:04 -08:00
|
|
|
int resize = 0, ret = 0;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2004-06-07 09:46:08 -07:00
|
|
|
if ((ewb->x != ewb->cx) || (ewb->y != ewb->cy))
|
|
|
|
{
|
|
|
|
ewb->cx = ewb->x;
|
|
|
|
ewb->cy = ewb->y;
|
2003-05-22 12:15:03 -07:00
|
|
|
ret = 1;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2004-06-07 09:46:08 -07:00
|
|
|
|
|
|
|
if ((ewb->w != ewb->cw) || (ewb->h != ewb->ch))
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2004-06-07 09:46:08 -07:00
|
|
|
resize = 1;
|
|
|
|
ewb->cw = ewb->w;
|
|
|
|
ewb->ch = ewb->h;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((resize) || (ewb->expose))
|
|
|
|
{
|
2004-06-26 10:49:01 -07:00
|
|
|
BorderWinpartITclassApply(ewin, i, 1);
|
2004-06-07 09:46:08 -07:00
|
|
|
ewb->expose = 0;
|
2003-05-22 12:15:03 -07:00
|
|
|
ret = 1;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2004-06-07 09:46:08 -07:00
|
|
|
|
2005-01-25 13:58:28 -08:00
|
|
|
return ret;
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2005-10-30 11:40:49 -08:00
|
|
|
static void
|
2004-06-26 10:49:01 -07:00
|
|
|
BorderWinpartChange(EWin * ewin, int i, int force)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2004-06-26 10:49:01 -07:00
|
|
|
BorderWinpartITclassApply(ewin, i, force);
|
2004-04-09 06:45:59 -07:00
|
|
|
|
2005-07-08 09:48:19 -07:00
|
|
|
if (ewin->update.shape || ewin->border->changes_shape)
|
2004-08-31 10:24:40 -07:00
|
|
|
EwinPropagateShapes(ewin);
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
void
|
2005-05-14 12:40:35 -07:00
|
|
|
EwinBorderDraw(EWin * ewin, int do_shape, int do_paint)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2005-05-14 12:40:35 -07:00
|
|
|
int i;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2005-05-08 13:26:49 -07:00
|
|
|
#if 0 /* Debug */
|
2014-05-10 05:37:15 -07:00
|
|
|
Eprintf("%s: %#x %s s=%d p=%d\n", __func__,
|
|
|
|
EwinGetClientXwin(ewin), EoGetName(ewin), do_shape, do_paint);
|
2005-05-08 13:26:49 -07:00
|
|
|
#endif
|
|
|
|
|
1999-08-17 15:56:46 -07:00
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
2005-01-29 07:00:00 -08:00
|
|
|
BorderWinpartITclassApply(ewin, i, do_shape || do_paint);
|
2004-04-09 06:45:59 -07:00
|
|
|
|
2005-07-08 09:48:19 -07:00
|
|
|
if (do_shape || ewin->update.shape || ewin->border->changes_shape)
|
2004-08-31 10:24:40 -07:00
|
|
|
EwinPropagateShapes(ewin);
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2004-06-26 10:49:01 -07:00
|
|
|
void
|
|
|
|
EwinBorderUpdateInfo(EWin * ewin)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
|
|
{
|
2009-10-26 10:47:32 -07:00
|
|
|
if (ewin->border->part[i].flags & FLAG_TITLE)
|
2004-06-26 10:49:01 -07:00
|
|
|
BorderWinpartITclassApply(ewin, i, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-02-01 08:48:05 -08:00
|
|
|
static void
|
2009-11-22 01:53:10 -08:00
|
|
|
BorderWinpartCalc(const EWin * ewin, int i, int ww, int hh)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
|
|
|
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)
|
2005-05-01 04:27:43 -07:00
|
|
|
BorderWinpartCalc(ewin, topleft, ww, hh);
|
1999-08-17 15:56:46 -07:00
|
|
|
if (bottomright >= 0)
|
2005-05-01 04:27:43 -07:00
|
|
|
BorderWinpartCalc(ewin, bottomright, ww, hh);
|
2007-12-30 12:58:00 -08:00
|
|
|
|
1999-08-17 15:56:46 -07:00
|
|
|
x = y = 0;
|
|
|
|
if (topleft == -1)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2007-12-30 12:58:00 -08:00
|
|
|
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;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
1999-08-17 15:56:46 -07:00
|
|
|
else if (topleft >= 0)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2003-05-22 12:15:03 -07:00
|
|
|
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;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2007-12-30 12:58:00 -08:00
|
|
|
|
1999-08-17 15:56:46 -07:00
|
|
|
ox = oy = 0;
|
|
|
|
if (bottomright == -1)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2007-12-30 12:58:00 -08:00
|
|
|
ox = ((ewin->border->part[i].geom.bottomright.x.percent * ww) >> 10) +
|
2003-05-22 12:15:03 -07:00
|
|
|
ewin->border->part[i].geom.bottomright.x.absolute;
|
2007-12-30 12:58:00 -08:00
|
|
|
oy = ((ewin->border->part[i].geom.bottomright.y.percent * hh) >> 10) +
|
2003-05-22 12:15:03 -07:00
|
|
|
ewin->border->part[i].geom.bottomright.y.absolute;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
1999-08-17 15:56:46 -07:00
|
|
|
else if (bottomright >= 0)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2003-05-22 12:15:03 -07:00
|
|
|
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;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2007-12-30 12:58:00 -08:00
|
|
|
|
1999-08-17 15:56:46 -07:00
|
|
|
/*
|
2000-04-05 16:22:56 -07:00
|
|
|
* 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 :-)
|
1999-08-17 15:56:46 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
h = (oy - y) + 1;
|
|
|
|
max = ewin->border->part[i].geom.height.max;
|
|
|
|
min = ewin->border->part[i].geom.height.min;
|
|
|
|
|
|
|
|
/*
|
2000-04-05 16:22:56 -07:00
|
|
|
* 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.
|
1999-08-17 15:56:46 -07:00
|
|
|
*/
|
|
|
|
|
2009-10-26 10:47:32 -07:00
|
|
|
if (max == 0 && ewin->border->part[i].flags & FLAG_TITLE)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2003-05-22 12:15:03 -07:00
|
|
|
int dummywidth, wmax, wmin;
|
|
|
|
ImageClass *iclass;
|
|
|
|
TextClass *tclass;
|
2006-03-29 11:13:17 -08:00
|
|
|
EImageBorder *pad;
|
2003-05-22 12:15:03 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
2005-09-26 10:32:10 -07:00
|
|
|
pad = ImageclassGetPadding(iclass);
|
2005-07-08 09:48:19 -07:00
|
|
|
TextSize(tclass, ewin->state.active, EoIsSticky(ewin),
|
2006-11-26 03:30:59 -08:00
|
|
|
ewin->bits[i].state, EwinGetTitle(ewin), &max, &dummywidth,
|
2005-09-26 10:32:10 -07:00
|
|
|
w - (pad->top + pad->bottom));
|
|
|
|
max += pad->left + pad->right;
|
2003-05-22 12:15:03 -07:00
|
|
|
if (h > max)
|
|
|
|
{
|
2018-02-17 03:56:43 -08:00
|
|
|
y += ((h - max) * TextclassGetJustification(tclass)) >> 10;
|
2003-05-22 12:15:03 -07:00
|
|
|
h = max;
|
|
|
|
}
|
|
|
|
if (h < min)
|
|
|
|
{
|
|
|
|
h = min;
|
|
|
|
}
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
1999-12-21 00:09:27 -08:00
|
|
|
else
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2003-05-22 12:15:03 -07:00
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2009-10-26 10:47:32 -07:00
|
|
|
if (max == 0 && ewin->border->part[i].flags & FLAG_TITLE)
|
2003-05-22 12:15:03 -07:00
|
|
|
{
|
|
|
|
int dummyheight;
|
|
|
|
ImageClass *iclass;
|
|
|
|
TextClass *tclass;
|
2006-03-29 11:13:17 -08:00
|
|
|
EImageBorder *pad;
|
2003-05-22 12:15:03 -07:00
|
|
|
|
|
|
|
iclass = ewin->border->part[i].iclass;
|
|
|
|
tclass = ewin->border->part[i].tclass;
|
2005-09-26 10:32:10 -07:00
|
|
|
pad = ImageclassGetPadding(iclass);
|
2005-07-08 09:48:19 -07:00
|
|
|
TextSize(tclass, ewin->state.active, EoIsSticky(ewin),
|
2006-11-26 03:30:59 -08:00
|
|
|
ewin->bits[i].state, EwinGetTitle(ewin), &max,
|
2005-09-26 10:32:10 -07:00
|
|
|
&dummyheight, h - (pad->top + pad->bottom));
|
|
|
|
max += pad->left + pad->right;
|
2003-05-22 12:15:03 -07:00
|
|
|
|
|
|
|
if (w > max)
|
|
|
|
{
|
2018-02-17 03:56:43 -08:00
|
|
|
x += ((w - max) * TextclassGetJustification(tclass)) >> 10;
|
2003-05-22 12:15:03 -07:00
|
|
|
w = max;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (w > max)
|
|
|
|
{
|
|
|
|
w = max;
|
|
|
|
x = ((x + ox) - w) >> 1;
|
|
|
|
}
|
|
|
|
else if (w < min)
|
|
|
|
{
|
|
|
|
w = min;
|
|
|
|
}
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2005-07-08 09:48:19 -07:00
|
|
|
if ((ewin->state.shaded) && (!ewin->border->part[i].keep_for_shade))
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2003-05-22 12:15:03 -07:00
|
|
|
ewin->bits[i].x = -100;
|
|
|
|
ewin->bits[i].y = -100;
|
|
|
|
ewin->bits[i].w = -1;
|
|
|
|
ewin->bits[i].h = -1;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
1999-12-21 00:09:27 -08:00
|
|
|
else
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2003-05-22 12:15:03 -07:00
|
|
|
ewin->bits[i].x = x;
|
|
|
|
ewin->bits[i].y = y;
|
|
|
|
ewin->bits[i].w = w;
|
|
|
|
ewin->bits[i].h = h;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
1999-12-21 00:09:27 -08:00
|
|
|
}
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
void
|
2005-05-21 13:58:18 -07:00
|
|
|
EwinBorderCalcSizes(EWin * ewin, int propagate)
|
1999-12-21 00:09:27 -08:00
|
|
|
{
|
2005-05-01 04:27:43 -07:00
|
|
|
int i, ww, hh;
|
1999-12-21 00:09:27 -08:00
|
|
|
char reshape;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
1999-12-21 00:09:27 -08:00
|
|
|
if (!ewin->border)
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
1999-11-19 11:50:49 -08:00
|
|
|
|
2005-05-01 04:27:43 -07:00
|
|
|
ww = EoGetW(ewin);
|
|
|
|
hh = EoGetH(ewin);
|
|
|
|
|
1999-12-21 00:09:27 -08:00
|
|
|
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)
|
2005-05-01 04:27:43 -07:00
|
|
|
BorderWinpartCalc(ewin, i, ww, hh);
|
1999-12-21 00:09:27 -08:00
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
2004-06-07 09:46:08 -07:00
|
|
|
BorderWinpartRealise(ewin, i);
|
2003-09-28 12:08:27 -07:00
|
|
|
|
1999-12-21 00:09:27 -08:00
|
|
|
reshape = 0;
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2004-06-07 09:46:08 -07:00
|
|
|
reshape |= BorderWinpartDraw(ewin, i);
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2003-12-27 11:20:15 -08:00
|
|
|
|
2005-05-21 13:58:18 -07:00
|
|
|
#if 0 /* Debug */
|
2014-05-10 05:37:15 -07:00
|
|
|
Eprintf("%s: prop=%d reshape=%d\n", __func__, propagate, reshape);
|
2005-05-21 13:58:18 -07:00
|
|
|
#endif
|
2005-05-08 09:01:48 -07:00
|
|
|
if (reshape)
|
2005-07-10 06:14:16 -07:00
|
|
|
ewin->update.shape = 1;
|
|
|
|
if (propagate && ewin->update.shape)
|
|
|
|
EwinPropagateShapes(ewin);
|
1999-12-21 00:09:27 -08:00
|
|
|
}
|
1999-09-16 16:21:57 -07:00
|
|
|
|
2007-07-27 09:59:50 -07:00
|
|
|
static void
|
2005-01-23 10:23:04 -08:00
|
|
|
BorderIncRefcount(const Border * b)
|
|
|
|
{
|
|
|
|
((Border *) b)->ref_count++;
|
|
|
|
}
|
|
|
|
|
2007-07-27 09:59:50 -07:00
|
|
|
static void
|
2005-01-23 10:23:04 -08:00
|
|
|
BorderDecRefcount(const Border * b)
|
|
|
|
{
|
|
|
|
((Border *) b)->ref_count--;
|
|
|
|
}
|
|
|
|
|
2005-02-06 11:13:34 -08:00
|
|
|
const char *
|
|
|
|
BorderGetName(const Border * b)
|
|
|
|
{
|
|
|
|
return (b) ? b->name : NULL;
|
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
void
|
2004-07-01 02:13:22 -07:00
|
|
|
EwinBorderSelect(EWin * ewin)
|
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
const Border *b;
|
2004-07-01 02:13:22 -07:00
|
|
|
|
2006-01-20 14:04:49 -08:00
|
|
|
if (ewin->inh_wm.b.border)
|
2005-07-08 09:48:19 -07:00
|
|
|
{
|
2006-02-18 00:30:09 -08:00
|
|
|
b = BorderFind("BORDERLESS");
|
2006-01-20 14:04:49 -08:00
|
|
|
goto done;
|
2005-07-08 09:48:19 -07:00
|
|
|
}
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2006-01-20 14:04:49 -08:00
|
|
|
/* 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)
|
2006-02-18 00:30:09 -08:00
|
|
|
b = BorderFind("BORDERLESS");
|
2006-01-20 14:04:49 -08:00
|
|
|
|
|
|
|
if (!b)
|
|
|
|
b = WindowMatchEwinBorder(ewin);
|
|
|
|
|
2004-07-01 02:13:22 -07:00
|
|
|
if (!b)
|
2006-02-18 00:30:09 -08:00
|
|
|
b = BorderFind("DEFAULT");
|
2004-07-01 02:13:22 -07:00
|
|
|
|
|
|
|
if (!b)
|
2008-06-22 06:34:42 -07:00
|
|
|
b = BorderGetFallback();
|
2004-07-01 02:13:22 -07:00
|
|
|
|
2005-01-30 03:02:43 -08:00
|
|
|
done:
|
2004-08-14 22:02:14 -07:00
|
|
|
ewin->normal_border = ewin->border = b;
|
2004-07-01 02:13:22 -07:00
|
|
|
}
|
|
|
|
|
2005-01-23 10:23:04 -08:00
|
|
|
void
|
|
|
|
EwinBorderDetach(EWin * ewin)
|
|
|
|
{
|
|
|
|
const Border *b = ewin->border;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!b)
|
|
|
|
return;
|
|
|
|
|
2006-01-29 06:03:37 -08:00
|
|
|
TooltipsSetPending(0, NULL, NULL);
|
|
|
|
|
2009-07-27 09:46:54 -07:00
|
|
|
EventCallbackUnregister(EoGetWin(ewin), BorderFrameHandleEvents, ewin);
|
2005-01-23 10:23:04 -08:00
|
|
|
for (i = 0; i < b->num_winparts; i++)
|
|
|
|
{
|
2009-07-27 09:46:54 -07:00
|
|
|
EventCallbackUnregister(ewin->bits[i].win,
|
2005-01-23 10:23:04 -08:00
|
|
|
BorderWinpartHandleEvents, &ewin->bits[i]);
|
|
|
|
if (ewin->bits[i].win)
|
2005-02-02 09:12:07 -08:00
|
|
|
EDestroyWindow(ewin->bits[i].win);
|
2005-01-23 10:23:04 -08:00
|
|
|
}
|
2008-02-23 04:09:38 -08:00
|
|
|
Efree(ewin->bits);
|
2005-01-23 10:23:04 -08:00
|
|
|
ewin->bits = NULL;
|
|
|
|
BorderDecRefcount(b);
|
|
|
|
|
|
|
|
ewin->border = NULL;
|
2005-01-30 03:02:43 -08:00
|
|
|
|
|
|
|
if (b->throwaway)
|
|
|
|
BorderDestroy((Border *) b);
|
2005-01-23 10:23:04 -08:00
|
|
|
}
|
|
|
|
|
2004-06-27 08:59:32 -07:00
|
|
|
void
|
2004-12-28 15:46:49 -08:00
|
|
|
EwinBorderSetTo(EWin * ewin, const Border * b)
|
2004-06-27 08:59:32 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (ewin->border == b)
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2004-06-27 08:59:32 -07:00
|
|
|
|
2010-08-13 10:04:13 -07:00
|
|
|
if (!b)
|
2004-06-27 08:59:32 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
b = ewin->border;
|
|
|
|
ewin->border = NULL;
|
2004-06-27 08:59:32 -07:00
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
if (ewin->border)
|
2005-01-23 10:23:04 -08:00
|
|
|
EwinBorderDetach(ewin);
|
2003-12-27 11:20:15 -08:00
|
|
|
|
1999-12-21 00:09:27 -08:00
|
|
|
ewin->border = b;
|
2004-12-28 15:46:49 -08:00
|
|
|
BorderIncRefcount(b);
|
2003-12-27 11:20:15 -08:00
|
|
|
HintsSetWindowBorder(ewin);
|
1999-12-21 00:09:27 -08:00
|
|
|
|
2006-01-20 14:04:49 -08:00
|
|
|
ewin->state.no_border = b->num_winparts <= 0;
|
|
|
|
|
2009-07-27 09:46:54 -07:00
|
|
|
EventCallbackRegister(EoGetWin(ewin), BorderFrameHandleEvents, ewin);
|
2004-12-28 15:46:49 -08:00
|
|
|
|
1999-12-21 00:09:27 -08:00
|
|
|
if (b->num_winparts > 0)
|
2007-01-16 17:10:44 -08:00
|
|
|
ewin->bits = EMALLOC(EWinBit, b->num_winparts);
|
2004-12-28 15:46:49 -08:00
|
|
|
|
1999-12-21 00:09:27 -08:00
|
|
|
for (i = 0; i < b->num_winparts; i++)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
ewin->bits[i].ewin = ewin; /* Reference to associated Ewin */
|
2005-03-20 07:58:51 -08:00
|
|
|
|
|
|
|
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);
|
2009-07-27 09:46:54 -07:00
|
|
|
EventCallbackRegister(ewin->bits[i].win,
|
2005-03-20 07:58:51 -08:00
|
|
|
BorderWinpartHandleEvents, &ewin->bits[i]);
|
|
|
|
if (b->part[i].flags & FLAG_TITLE)
|
|
|
|
ESelectInput(ewin->bits[i].win, EWIN_BORDER_TITLE_EVENT_MASK);
|
2003-05-22 12:15:03 -07:00
|
|
|
else
|
2005-03-20 07:58:51 -08:00
|
|
|
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].left = 0;
|
|
|
|
ewin->bits[i].is = NULL;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
1999-08-17 15:56:46 -07:00
|
|
|
|
1999-12-21 00:09:27 -08:00
|
|
|
{
|
2009-12-03 11:29:30 -08:00
|
|
|
EX_Window *wl;
|
1999-12-21 00:09:27 -08:00
|
|
|
int j = 0;
|
|
|
|
|
2009-12-03 11:29:30 -08:00
|
|
|
wl = EMALLOC(EX_Window, b->num_winparts + 1);
|
2010-06-06 03:05:50 -07:00
|
|
|
if (!wl)
|
|
|
|
return;
|
1999-12-21 00:09:27 -08:00
|
|
|
for (i = b->num_winparts - 1; i >= 0; i--)
|
2003-05-22 12:15:03 -07:00
|
|
|
{
|
|
|
|
if (b->part[i].ontop)
|
2006-08-07 13:47:12 -07:00
|
|
|
wl[j++] = WinGetXwin(ewin->bits[i].win);
|
2003-05-22 12:15:03 -07:00
|
|
|
}
|
2013-01-27 13:00:54 -08:00
|
|
|
wl[j++] = WinGetXwin(EwinGetClientConWin(ewin));
|
1999-12-21 00:09:27 -08:00
|
|
|
for (i = b->num_winparts - 1; i >= 0; i--)
|
2003-05-22 12:15:03 -07:00
|
|
|
{
|
|
|
|
if (!b->part[i].ontop)
|
2006-08-07 13:47:12 -07:00
|
|
|
wl[j++] = WinGetXwin(ewin->bits[i].win);
|
2003-05-22 12:15:03 -07:00
|
|
|
}
|
2008-03-30 05:13:16 -07:00
|
|
|
EXRestackWindows(wl, j);
|
1999-12-21 00:09:27 -08:00
|
|
|
Efree(wl);
|
|
|
|
}
|
|
|
|
|
2013-01-27 13:00:54 -08:00
|
|
|
#if USE_CONTAINER_WIN
|
2005-07-08 09:48:19 -07:00
|
|
|
if (!ewin->state.shaded)
|
2005-02-02 09:12:07 -08:00
|
|
|
EMoveWindow(ewin->win_container, b->border.left, b->border.top);
|
2013-01-27 13:00:54 -08:00
|
|
|
#endif
|
2004-06-26 11:24:39 -07:00
|
|
|
|
2005-07-08 09:48:19 -07:00
|
|
|
ewin->update.shape = 1;
|
2005-05-21 13:58:18 -07:00
|
|
|
EwinBorderCalcSizes(ewin, 0);
|
2006-01-20 14:04:49 -08:00
|
|
|
EwinStateUpdate(ewin);
|
2005-03-24 01:40:59 -08:00
|
|
|
|
|
|
|
SnapshotEwinUpdate(ewin, SNAP_USE_BORDER);
|
1999-12-21 00:09:27 -08:00
|
|
|
}
|
|
|
|
|
2003-12-27 11:20:15 -08:00
|
|
|
void
|
2008-11-22 13:16:55 -08:00
|
|
|
EwinBorderChange(EWin * ewin, const Border * b, int normal)
|
2003-12-27 11:20:15 -08:00
|
|
|
{
|
2008-11-22 13:16:55 -08:00
|
|
|
if (!b || ewin->border == b ||
|
|
|
|
ewin->inh_wm.b.border || ewin->state.fullscreen)
|
2003-12-27 11:20:15 -08:00
|
|
|
return;
|
|
|
|
|
2008-11-22 13:16:55 -08:00
|
|
|
EwinBorderSetTo(ewin, b);
|
|
|
|
EwinMoveResize(ewin, EoGetX(ewin), EoGetY(ewin),
|
2012-04-22 10:39:37 -07:00
|
|
|
ewin->client.w, ewin->client.h, 0);
|
2004-07-02 13:59:32 -07:00
|
|
|
|
2008-11-22 13:16:55 -08:00
|
|
|
if (normal)
|
2004-07-02 13:59:32 -07:00
|
|
|
ewin->normal_border = b;
|
2003-12-27 11:20:15 -08:00
|
|
|
}
|
|
|
|
|
2008-11-22 13:16:55 -08:00
|
|
|
static void
|
|
|
|
EwinBorderAssign(EWin * ewin, const Border * b)
|
|
|
|
{
|
|
|
|
if (!b || ewin->border == b || ewin->inh_wm.b.border)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (ewin->border)
|
|
|
|
BorderDecRefcount(ewin->border);
|
|
|
|
BorderIncRefcount(b);
|
|
|
|
|
|
|
|
ewin->border = ewin->normal_border = b;
|
|
|
|
}
|
|
|
|
|
2003-12-27 11:20:15 -08:00
|
|
|
void
|
2008-11-16 09:20:37 -08:00
|
|
|
EwinBorderSetInitially(EWin * ewin, const char *name)
|
2003-12-27 11:20:15 -08:00
|
|
|
{
|
2008-11-22 13:16:55 -08:00
|
|
|
EwinBorderAssign(ewin, BorderFind(name));
|
2003-12-27 11:20:15 -08:00
|
|
|
}
|
|
|
|
|
2005-10-30 11:40:49 -08:00
|
|
|
static Border *
|
2004-12-28 15:46:49 -08:00
|
|
|
BorderCreate(const char *name)
|
1999-12-21 00:09:27 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
Border *b;
|
2004-02-08 14:51:50 -08:00
|
|
|
|
2007-01-16 17:10:44 -08:00
|
|
|
b = ECALLOC(Border, 1);
|
2004-12-28 15:46:49 -08:00
|
|
|
if (!b)
|
2005-01-25 13:58:28 -08:00
|
|
|
return NULL;
|
2004-03-02 11:17:17 -08:00
|
|
|
|
2013-06-06 13:37:06 -07:00
|
|
|
LIST_PREPEND(Border, &border_list, b);
|
2006-02-18 00:30:09 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
b->name = Estrdup(name);
|
|
|
|
b->group_border_name = NULL;
|
|
|
|
b->shadedir = 2;
|
2003-12-28 09:57:31 -08:00
|
|
|
|
2005-01-25 13:58:28 -08:00
|
|
|
return b;
|
1999-12-21 00:09:27 -08:00
|
|
|
}
|
|
|
|
|
2005-10-30 11:40:49 -08:00
|
|
|
static void
|
2010-07-18 11:52:45 -07:00
|
|
|
BorderDestroy(Border * b)
|
2004-06-06 09:38:17 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
int i;
|
2004-06-06 09:38:17 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
if (!b)
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2004-02-17 15:28:25 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
if (b->ref_count > 0)
|
2004-02-21 11:48:32 -08:00
|
|
|
{
|
2010-05-09 12:03:19 -07:00
|
|
|
DialogOK("Border Error!", _("%u references remain"), b->ref_count);
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2004-02-21 11:48:32 -08:00
|
|
|
}
|
|
|
|
|
2013-06-06 13:37:06 -07:00
|
|
|
LIST_REMOVE(Border, &border_list, b);
|
2004-02-17 15:28:25 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
for (i = 0; i < b->num_winparts; i++)
|
2004-02-17 15:28:25 -08:00
|
|
|
{
|
2007-07-27 09:59:50 -07:00
|
|
|
ImageclassFree(b->part[i].iclass);
|
|
|
|
ActionclassFree(b->part[i].aclass);
|
|
|
|
TextclassFree(b->part[i].tclass);
|
|
|
|
ECursorFree(b->part[i].ec);
|
2004-02-17 15:28:25 -08:00
|
|
|
}
|
|
|
|
|
2008-02-23 04:09:38 -08:00
|
|
|
Efree(b->part);
|
|
|
|
Efree(b->name);
|
|
|
|
Efree(b->group_border_name);
|
2007-07-27 09:59:50 -07:00
|
|
|
ActionclassFree(b->aclass);
|
2010-07-18 11:52:45 -07:00
|
|
|
Efree(b);
|
2004-02-17 15:28:25 -08:00
|
|
|
}
|
|
|
|
|
2006-02-18 00:30:09 -08:00
|
|
|
static int
|
|
|
|
_BorderMatchName(const void *data, const void *match)
|
|
|
|
{
|
2007-01-16 17:10:44 -08:00
|
|
|
return strcmp(((const Border *)data)->name, (const char *)match);
|
2006-02-18 00:30:09 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
Border *
|
|
|
|
BorderFind(const char *name)
|
|
|
|
{
|
2008-06-22 06:34:42 -07:00
|
|
|
if (!name)
|
|
|
|
return NULL;
|
2013-06-06 13:37:06 -07:00
|
|
|
return LIST_FIND(Border, &border_list, _BorderMatchName, name);
|
2006-02-18 00:30:09 -08:00
|
|
|
}
|
|
|
|
|
2005-10-30 11:40:49 -08:00
|
|
|
static void
|
2007-07-27 09:59:50 -07:00
|
|
|
BorderWinpartAdd(Border * b, const char *iclass, const char *aclass,
|
|
|
|
const char *tclass, const char *cclass, char ontop, int flags,
|
2005-10-30 11:40:49 -08:00
|
|
|
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)
|
2004-02-17 15:28:25 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
int n;
|
2004-02-17 15:28:25 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
b->num_winparts++;
|
|
|
|
n = b->num_winparts;
|
2004-02-17 15:28:25 -08:00
|
|
|
|
2007-01-16 17:10:44 -08:00
|
|
|
b->part = EREALLOC(WinPart, b->part, n);
|
1999-12-21 00:09:27 -08:00
|
|
|
|
2007-07-27 09:59:50 -07:00
|
|
|
b->part[n - 1].iclass = (iclass) ? ImageclassAlloc(iclass, 1) : NULL;
|
|
|
|
b->part[n - 1].aclass = (aclass) ? ActionclassAlloc(aclass) : NULL;
|
|
|
|
b->part[n - 1].tclass = (tclass) ? TextclassAlloc(tclass, 1) : NULL;
|
|
|
|
b->part[n - 1].ec = (cclass) ? ECursorAlloc(cclass) : NULL;
|
1999-12-21 00:09:27 -08:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
void
|
2009-11-22 01:53:10 -08:00
|
|
|
EwinBorderMinShadeSize(const EWin * ewin, int *mw, int *mh)
|
1999-12-21 00:09:27 -08:00
|
|
|
{
|
2004-02-01 08:48:05 -08:00
|
|
|
int i, pw, ph, w, h, min_w, min_h;
|
1999-12-21 00:09:27 -08:00
|
|
|
int leftborderwidth, rightborderwidth;
|
|
|
|
int topborderwidth, bottomborderwidth;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2009-11-22 01:53:10 -08:00
|
|
|
pw = ewin->client.w + ewin->border->border.left + ewin->border->border.right;
|
|
|
|
ph = ewin->client.h + ewin->border->border.top + ewin->border->border.bottom;
|
2004-02-01 08:48:05 -08:00
|
|
|
|
|
|
|
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)
|
2005-05-01 04:27:43 -07:00
|
|
|
BorderWinpartCalc(ewin, i, pw, ph);
|
2004-02-01 08:48:05 -08:00
|
|
|
|
1999-12-21 00:09:27 -08:00
|
|
|
switch (ewin->border->shadedir)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2003-05-22 12:15:03 -07:00
|
|
|
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++)
|
|
|
|
{
|
2004-02-01 08:48:05 -08:00
|
|
|
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 -
|
2009-11-22 01:53:10 -08:00
|
|
|
(pw - ewin->border->border.right);
|
2004-02-01 08:48:05 -08:00
|
|
|
if (rightborderwidth < w)
|
|
|
|
rightborderwidth = w;
|
2003-05-22 12:15:03 -07:00
|
|
|
}
|
2005-05-01 04:27:43 -07:00
|
|
|
pw = rightborderwidth + leftborderwidth;
|
2003-05-22 12:15:03 -07:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
topborderwidth = bottomborderwidth = 0;
|
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
|
|
|
{
|
2004-02-01 08:48:05 -08:00
|
|
|
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 -
|
2009-11-22 01:53:10 -08:00
|
|
|
(ph - ewin->border->border.bottom);
|
2004-03-26 13:51:22 -08:00
|
|
|
if (bottomborderwidth < h)
|
|
|
|
bottomborderwidth = h;
|
2003-05-22 12:15:03 -07:00
|
|
|
}
|
2005-05-01 04:27:43 -07:00
|
|
|
ph = bottomborderwidth + topborderwidth;
|
2003-05-22 12:15:03 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2004-02-01 08:48:05 -08:00
|
|
|
|
|
|
|
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)
|
2005-05-01 04:27:43 -07:00
|
|
|
BorderWinpartCalc(ewin, i, pw, ph);
|
2004-02-01 08:48:05 -08:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
*mw = min_w;
|
|
|
|
*mh = min_h;
|
1999-12-21 00:09:27 -08:00
|
|
|
}
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
int
|
2006-04-29 12:39:21 -07:00
|
|
|
BorderWinpartIndex(EWin * ewin, Win win)
|
1999-12-21 00:09:27 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
int i;
|
2003-12-27 11:20:15 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
for (i = 0; i < ewin->border->num_winparts; i++)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
if (win == ewin->bits[i].win)
|
|
|
|
return i;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2004-12-28 15:46:49 -08:00
|
|
|
|
|
|
|
return -1; /* Not found */
|
1999-12-21 00:09:27 -08:00
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
/*
|
|
|
|
* Border event handlers
|
|
|
|
*/
|
|
|
|
#define DEBUG_BORDER_EVENTS 0
|
|
|
|
|
|
|
|
static void
|
|
|
|
BorderWinpartEventMouseDown(EWinBit * wbit, XEvent * ev)
|
|
|
|
{
|
|
|
|
EWin *ewin = wbit->ewin;
|
|
|
|
int part = wbit - ewin->bits;
|
2004-07-04 14:33:06 -07:00
|
|
|
|
2010-01-29 11:44:54 -08:00
|
|
|
#if 0 /* Remove? */
|
2004-12-28 15:46:49 -08:00
|
|
|
GrabPointerSet(wbit->win, 0, 0);
|
2010-01-29 11:44:54 -08:00
|
|
|
#endif
|
2004-07-04 14:33:06 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
wbit->state = STATE_CLICKED;
|
|
|
|
#if DEBUG_BORDER_EVENTS
|
2014-05-10 05:37:15 -07:00
|
|
|
Eprintf("%s: %#x %d\n", __func__, WinGetXwin(wbit->win), wbit->state);
|
2004-12-28 15:46:49 -08:00
|
|
|
#endif
|
|
|
|
BorderWinpartChange(ewin, part, 0);
|
2004-07-04 14:33:06 -07:00
|
|
|
|
2005-04-15 11:41:04 -07:00
|
|
|
FocusHandleClick(ewin, wbit->win);
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
if (ewin->border->part[part].aclass)
|
2005-06-30 05:37:43 -07:00
|
|
|
ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
|
1999-12-21 00:09:27 -08:00
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
static void
|
|
|
|
BorderWinpartEventMouseUp(EWinBit * wbit, XEvent * ev)
|
1999-12-21 00:09:27 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
EWin *ewin = wbit->ewin;
|
|
|
|
int part = wbit - ewin->bits;
|
2005-08-21 14:00:55 -07:00
|
|
|
int left = wbit->left;
|
2004-07-04 14:33:06 -07:00
|
|
|
|
2007-04-08 12:25:02 -07:00
|
|
|
if (ev)
|
|
|
|
{
|
2010-01-29 11:44:54 -08:00
|
|
|
#if 0 /* Remove? */
|
2007-04-08 12:25:02 -07:00
|
|
|
GrabPointerRelease();
|
2010-01-29 11:44:54 -08:00
|
|
|
#endif
|
2010-01-20 08:59:18 -08:00
|
|
|
/*
|
|
|
|
* During a move/resize operation initiated by a border part click
|
|
|
|
* the ButtonRelease event may be reported on the border part window
|
|
|
|
* if the event happens before the pointer grab is moved to the
|
|
|
|
* move/resize event window.
|
|
|
|
* This can be tested e.g. by inserting usleep(100000) at the start
|
|
|
|
* of BorderWinpartEventMouseDown().
|
|
|
|
*/
|
|
|
|
MoveResizeEnd(ewin);
|
2007-04-08 12:25:02 -07:00
|
|
|
}
|
2004-07-04 14:33:06 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
if ((wbit->state == STATE_CLICKED) && (!wbit->left))
|
|
|
|
wbit->state = STATE_HILITED;
|
|
|
|
else
|
|
|
|
wbit->state = STATE_NORMAL;
|
|
|
|
#if DEBUG_BORDER_EVENTS
|
2014-05-10 05:37:15 -07:00
|
|
|
Eprintf("%s: %#x %d\n", __func__, WinGetXwin(wbit->win), wbit->state);
|
2004-12-28 15:46:49 -08:00
|
|
|
#endif
|
|
|
|
BorderWinpartChange(ewin, part, 0);
|
2004-07-04 14:33:06 -07:00
|
|
|
|
2005-08-21 14:00:55 -07:00
|
|
|
/* Beware! Actions may destroy the current border */
|
|
|
|
wbit->left = 0;
|
|
|
|
|
2006-11-26 09:10:40 -08:00
|
|
|
if (ev && WinGetXwin(wbit->win) == Mode.events.last_bpress && !left &&
|
2004-12-28 15:46:49 -08:00
|
|
|
ewin->border->part[part].aclass)
|
2005-06-30 05:37:43 -07:00
|
|
|
ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
|
1999-12-21 00:09:27 -08:00
|
|
|
}
|
2004-01-11 05:20:17 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
static void
|
|
|
|
BorderWinpartEventEnter(EWinBit * wbit, XEvent * ev)
|
2004-05-31 13:30:12 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
EWin *ewin = wbit->ewin;
|
|
|
|
int part = wbit - ewin->bits;
|
2004-05-31 13:30:12 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
#if DEBUG_BORDER_EVENTS
|
2014-05-10 05:37:15 -07:00
|
|
|
Eprintf("%s: %#x %d\n", __func__, WinGetXwin(wbit->win), wbit->state);
|
2004-12-28 15:46:49 -08:00
|
|
|
#endif
|
|
|
|
if (wbit->state == STATE_CLICKED)
|
|
|
|
wbit->left = 0;
|
2010-06-06 03:05:50 -07:00
|
|
|
|
|
|
|
wbit->state = STATE_HILITED;
|
|
|
|
BorderWinpartChange(ewin, part, 0);
|
|
|
|
if (ewin->border->part[part].aclass)
|
|
|
|
ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
|
2004-02-28 17:30:18 -08:00
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
static void
|
|
|
|
BorderWinpartEventLeave(EWinBit * wbit, XEvent * ev)
|
2004-02-28 17:30:18 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
EWin *ewin = wbit->ewin;
|
|
|
|
int part = wbit - ewin->bits;
|
2004-02-28 17:30:18 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
#if DEBUG_BORDER_EVENTS
|
2014-05-10 05:37:15 -07:00
|
|
|
Eprintf("%s: %#x %d\n", __func__, WinGetXwin(wbit->win), wbit->state);
|
2004-02-28 17:30:18 -08:00
|
|
|
#endif
|
2004-12-28 15:46:49 -08:00
|
|
|
if (wbit->state == STATE_CLICKED)
|
|
|
|
wbit->left = 1;
|
|
|
|
else
|
2004-01-18 05:43:53 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
wbit->state = STATE_NORMAL;
|
|
|
|
BorderWinpartChange(ewin, part, 0);
|
|
|
|
if (ewin->border->part[part].aclass)
|
2005-06-30 05:37:43 -07:00
|
|
|
ActionclassEvent(ewin->border->part[part].aclass, ev, ewin);
|
2004-01-18 05:43:53 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-26 09:10:40 -08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-21 13:58:00 -07:00
|
|
|
static int
|
|
|
|
_BorderAutoshadeTimeout(void *data)
|
|
|
|
{
|
|
|
|
EWin *ewin = (EWin *) data;
|
|
|
|
|
|
|
|
if (!EwinFindByPtr(ewin)) /* Check, window may be gone */
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ewin->timer = NULL;
|
|
|
|
EwinOpShade(ewin, OPSRC_USER, 1);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
static void
|
2006-04-29 12:39:21 -07:00
|
|
|
BorderFrameHandleEvents(Win win __UNUSED__, XEvent * ev, void *prm)
|
2004-02-28 17:30:18 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
EWin *ewin = (EWin *) prm;
|
2009-02-01 02:15:13 -08:00
|
|
|
int x, y;
|
2004-02-28 17:30:18 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
switch (ev->type)
|
2004-02-28 17:30:18 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
case EnterNotify:
|
2009-03-21 13:58:00 -07:00
|
|
|
if (ewin->props.autoshade)
|
2009-02-01 02:15:13 -08:00
|
|
|
{
|
2009-02-05 09:35:48 -08:00
|
|
|
EwinOpShade(ewin, OPSRC_USER, 0);
|
2009-02-01 02:15:13 -08:00
|
|
|
}
|
|
|
|
if (ewin->border->aclass)
|
|
|
|
ActionclassEvent(ewin->border->aclass, ev, ewin);
|
|
|
|
break;
|
2004-12-28 15:46:49 -08:00
|
|
|
case LeaveNotify:
|
2009-02-01 02:15:13 -08:00
|
|
|
if (ewin->props.autoshade && !ewin->state.shaded)
|
|
|
|
{
|
|
|
|
EQueryPointer(EoGetWin(ewin), &x, &y, NULL, NULL);
|
|
|
|
if (x >= 4 && x < EoGetW(ewin) - 4 &&
|
|
|
|
y >= 4 && y < EoGetH(ewin) - 4)
|
|
|
|
break;
|
2009-03-21 13:58:00 -07:00
|
|
|
TIMER_DEL(ewin->timer);
|
2011-01-05 10:05:57 -08:00
|
|
|
TIMER_ADD(ewin->timer, 500, _BorderAutoshadeTimeout, ewin);
|
2009-02-01 02:15:13 -08:00
|
|
|
}
|
2004-12-28 15:46:49 -08:00
|
|
|
if (ewin->border->aclass)
|
2005-06-30 05:37:43 -07:00
|
|
|
ActionclassEvent(ewin->border->aclass, ev, ewin);
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
2004-02-28 17:30:18 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-20 06:55:51 -07:00
|
|
|
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
|
2007-07-23 12:02:15 -07:00
|
|
|
BorderWinpartHandleTooltip(EWinBit * wbit)
|
2005-08-20 06:55:51 -07:00
|
|
|
{
|
|
|
|
EWin *ewin = wbit->ewin;
|
|
|
|
int part = wbit - ewin->bits;
|
|
|
|
|
2007-07-23 12:02:15 -07:00
|
|
|
if (!ewin->border->part[part].aclass)
|
|
|
|
return;
|
|
|
|
TooltipsSetPending(0, BorderWinpartGetAclass, wbit);
|
2005-08-20 06:55:51 -07:00
|
|
|
}
|
|
|
|
|
2004-04-12 06:57:43 -07:00
|
|
|
static void
|
2006-04-29 12:39:21 -07:00
|
|
|
BorderWinpartHandleEvents(Win win __UNUSED__, XEvent * ev, void *prm)
|
2004-04-12 06:57:43 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
EWinBit *wbit = (EWinBit *) prm;
|
2004-04-12 06:57:43 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
switch (ev->type)
|
2004-04-12 06:57:43 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
case ButtonPress:
|
|
|
|
BorderWinpartEventMouseDown(wbit, ev);
|
|
|
|
break;
|
|
|
|
case ButtonRelease:
|
|
|
|
BorderWinpartEventMouseUp(wbit, ev);
|
|
|
|
break;
|
|
|
|
case EnterNotify:
|
2007-07-23 12:02:15 -07:00
|
|
|
/* Beware! Actions may destroy the current border */
|
|
|
|
BorderWinpartHandleTooltip(wbit);
|
2004-12-28 15:46:49 -08:00
|
|
|
BorderWinpartEventEnter(wbit, ev);
|
|
|
|
break;
|
|
|
|
case LeaveNotify:
|
|
|
|
BorderWinpartEventLeave(wbit, ev);
|
|
|
|
break;
|
2007-07-23 12:02:15 -07:00
|
|
|
case MotionNotify:
|
|
|
|
BorderWinpartHandleTooltip(wbit);
|
|
|
|
break;
|
2004-12-28 15:46:49 -08:00
|
|
|
}
|
|
|
|
}
|
2004-04-12 06:57:43 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
/*
|
|
|
|
* Configuration load/save
|
|
|
|
*/
|
|
|
|
#include "conf.h"
|
2004-04-12 06:57:43 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
static int
|
2005-10-30 11:40:49 -08:00
|
|
|
BorderPartLoad(FILE * fs, char type __UNUSED__, Border * b)
|
2004-12-28 15:46:49 -08:00
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
char s[FILEPATH_LEN_MAX];
|
|
|
|
char s2[FILEPATH_LEN_MAX];
|
2007-07-27 09:59:50 -07:00
|
|
|
int i1, i2;
|
|
|
|
char iclass[64], aclass[64], tclass[64], cclass[64];
|
|
|
|
char *piclass, *paclass, *ptclass, *pcclass;
|
2004-12-28 15:46:49 -08:00
|
|
|
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;
|
2007-07-27 09:59:50 -07:00
|
|
|
|
|
|
|
piclass = paclass = ptclass = pcclass = NULL;
|
2004-12-28 15:46:49 -08:00
|
|
|
|
|
|
|
while (GetLine(s, sizeof(s), fs))
|
|
|
|
{
|
2007-07-27 09:59:50 -07:00
|
|
|
i1 = ConfigParseline1(s, s2, NULL, NULL);
|
|
|
|
i2 = atoi(s2);
|
2004-12-28 15:46:49 -08:00
|
|
|
switch (i1)
|
2004-09-19 02:27:38 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
case CONFIG_CLOSE:
|
2007-07-27 09:59:50 -07:00
|
|
|
BorderWinpartAdd(b, piclass, paclass, ptclass, pcclass, ontop,
|
|
|
|
flags, isregion, wmin, wmax, hmin, hmax,
|
|
|
|
torigin, txp, txa, typ, tya,
|
|
|
|
borigin, bxp, bxa, byp, bya, keepshade);
|
2004-12-28 15:46:49 -08:00
|
|
|
goto done;
|
|
|
|
case CONFIG_IMAGECLASS:
|
|
|
|
case BORDERPART_ICLASS:
|
2007-07-27 09:59:50 -07:00
|
|
|
STRCPY(iclass, s2);
|
|
|
|
piclass = iclass;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case CONFIG_ACTIONCLASS:
|
|
|
|
case BORDERPART_ACLASS:
|
2007-07-27 09:59:50 -07:00
|
|
|
STRCPY(aclass, s2);
|
|
|
|
paclass = aclass;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case CONFIG_TEXT:
|
|
|
|
case BORDERPART_TEXTCLASS:
|
2007-07-27 09:59:50 -07:00
|
|
|
STRCPY(tclass, s2);
|
|
|
|
ptclass = tclass;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case CONFIG_CURSOR:
|
2007-07-27 09:59:50 -07:00
|
|
|
STRCPY(cclass, s2);
|
|
|
|
pcclass = cclass;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_ONTOP:
|
2007-07-27 09:59:50 -07:00
|
|
|
ontop = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_FLAGS:
|
2007-07-27 09:59:50 -07:00
|
|
|
flags = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_ISREGION:
|
2007-07-27 09:59:50 -07:00
|
|
|
isregion = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_WMIN:
|
2007-07-27 09:59:50 -07:00
|
|
|
wmin = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
if (!wmax)
|
|
|
|
wmax = wmin;
|
|
|
|
break;
|
|
|
|
case BORDERPART_WMAX:
|
2007-07-27 09:59:50 -07:00
|
|
|
wmax = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_HMIN:
|
2007-07-27 09:59:50 -07:00
|
|
|
hmin = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
if (!hmax)
|
|
|
|
hmax = hmin;
|
|
|
|
break;
|
|
|
|
case BORDERPART_HMAX:
|
2007-07-27 09:59:50 -07:00
|
|
|
hmax = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_TORIGIN:
|
2007-07-27 09:59:50 -07:00
|
|
|
torigin = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_TXP:
|
2007-07-27 09:59:50 -07:00
|
|
|
txp = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_TXA:
|
2007-07-27 09:59:50 -07:00
|
|
|
txa = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_TYP:
|
2007-07-27 09:59:50 -07:00
|
|
|
typ = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_TYA:
|
2007-07-27 09:59:50 -07:00
|
|
|
tya = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_BORIGIN:
|
2007-07-27 09:59:50 -07:00
|
|
|
borigin = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_BXP:
|
2007-07-27 09:59:50 -07:00
|
|
|
bxp = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_BXA:
|
2007-07-27 09:59:50 -07:00
|
|
|
bxa = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_BYP:
|
2007-07-27 09:59:50 -07:00
|
|
|
byp = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_BYA:
|
2007-07-27 09:59:50 -07:00
|
|
|
bya = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
case BORDERPART_KEEPSHADE:
|
2007-07-27 09:59:50 -07:00
|
|
|
keepshade = i2;
|
2004-12-28 15:46:49 -08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2004-09-19 02:27:38 -07:00
|
|
|
}
|
|
|
|
}
|
2004-12-28 15:46:49 -08:00
|
|
|
err = -1;
|
|
|
|
done:
|
|
|
|
return err;
|
2004-01-11 05:20:17 -08:00
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
int
|
|
|
|
BorderConfigLoad(FILE * fs)
|
2004-01-11 05:20:17 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
int err = 0;
|
|
|
|
Border *b = 0;
|
|
|
|
char s[FILEPATH_LEN_MAX];
|
|
|
|
char s2[FILEPATH_LEN_MAX];
|
2007-07-27 09:59:50 -07:00
|
|
|
int i1, i2;
|
2004-01-11 05:20:17 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
while (GetLine(s, sizeof(s), fs))
|
2004-01-11 05:20:17 -08:00
|
|
|
{
|
2007-07-27 09:59:50 -07:00
|
|
|
i1 = ConfigParseline1(s, s2, NULL, NULL);
|
|
|
|
i2 = atoi(s2);
|
2004-01-11 05:20:17 -08:00
|
|
|
|
2007-12-30 13:03:57 -08:00
|
|
|
switch (i1)
|
2004-12-28 15:46:49 -08:00
|
|
|
{
|
2007-12-30 13:03:57 -08:00
|
|
|
case CONFIG_CLOSE:
|
|
|
|
goto done;
|
|
|
|
case CONFIG_CLASSNAME:
|
|
|
|
case BORDER_NAME:
|
|
|
|
if (BorderFind(s2))
|
2004-01-11 05:20:17 -08:00
|
|
|
{
|
2007-12-30 13:03:57 -08:00
|
|
|
SkipTillEnd(fs);
|
2004-03-20 07:49:05 -08:00
|
|
|
goto done;
|
2004-01-11 05:20:17 -08:00
|
|
|
}
|
2007-12-30 13:03:57 -08:00
|
|
|
b = BorderCreate(s2);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!b)
|
|
|
|
break;
|
|
|
|
|
|
|
|
switch (i1)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
case BORDER_INIT:
|
|
|
|
if (i2 != CONFIG_OPEN)
|
|
|
|
break;
|
|
|
|
err = BorderPartLoad(fs, i1, b);
|
|
|
|
if (err)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case BORDER_GROUP_NAME:
|
|
|
|
b->group_border_name = Estrdup(s2);
|
|
|
|
break;
|
|
|
|
case BORDER_LEFT:
|
|
|
|
b->border.left = i2;
|
|
|
|
break;
|
|
|
|
case BORDER_RIGHT:
|
|
|
|
b->border.right = i2;
|
|
|
|
break;
|
|
|
|
case BORDER_TOP:
|
|
|
|
b->border.top = i2;
|
|
|
|
break;
|
|
|
|
case BORDER_BOTTOM:
|
|
|
|
b->border.bottom = i2;
|
|
|
|
break;
|
2009-01-18 03:17:12 -08:00
|
|
|
case BORDER_SHADEDIR:
|
2007-12-30 13:03:57 -08:00
|
|
|
b->shadedir = i2;
|
|
|
|
break;
|
|
|
|
case BORDER_CHANGES_SHAPE:
|
|
|
|
b->changes_shape = i2;
|
|
|
|
break;
|
|
|
|
case CONFIG_ACTIONCLASS:
|
|
|
|
b->aclass = ActionclassFind(s2);
|
|
|
|
break;
|
2004-01-11 05:20:17 -08:00
|
|
|
}
|
|
|
|
}
|
2004-12-28 15:46:49 -08:00
|
|
|
err = -1;
|
2004-01-11 05:20:17 -08:00
|
|
|
|
2004-03-20 07:49:05 -08:00
|
|
|
done:
|
2004-12-28 15:46:49 -08:00
|
|
|
return err;
|
2004-01-11 05:20:17 -08:00
|
|
|
}
|
|
|
|
|
2005-01-30 03:02:43 -08:00
|
|
|
Border *
|
2010-07-18 11:52:54 -07:00
|
|
|
BorderCreateFiller(int w, int h, int sw, int sh)
|
2005-01-30 03:02:43 -08:00
|
|
|
{
|
|
|
|
Border *b;
|
2010-07-18 11:52:54 -07:00
|
|
|
int left, right, top, bottom;
|
2005-01-30 03:02:43 -08:00
|
|
|
|
2010-08-05 10:53:54 -07:00
|
|
|
if (w > sw || h > sh) /* Borders must be >= 0 */
|
|
|
|
return NULL;
|
|
|
|
|
2005-01-30 03:02:43 -08:00
|
|
|
b = BorderCreate("__FILLER");
|
2008-06-22 06:34:42 -07:00
|
|
|
if (!b)
|
|
|
|
return b;
|
|
|
|
|
2010-07-18 11:52:54 -07:00
|
|
|
left = (sw - w) / 2;
|
|
|
|
left = (left < 0) ? 0 : left;
|
|
|
|
right = sw - w - left;
|
|
|
|
top = (sh - h) / 2;
|
|
|
|
top = (top < 0) ? 0 : top;
|
|
|
|
bottom = sh - h - top;
|
|
|
|
|
2005-01-30 03:02:43 -08:00
|
|
|
b->throwaway = 1;
|
|
|
|
|
|
|
|
b->border.left = left;
|
|
|
|
b->border.right = right;
|
|
|
|
b->border.top = top;
|
|
|
|
b->border.bottom = bottom;
|
|
|
|
|
2008-06-22 06:34:42 -07:00
|
|
|
ImageclassGetBlack(); /* Creates the __BLACK ImageClass */
|
|
|
|
|
2005-01-30 03:02:43 -08:00
|
|
|
if (top)
|
2007-07-27 09:59:50 -07:00
|
|
|
BorderWinpartAdd(b, "__BLACK", NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
|
2005-01-30 03:02:43 -08:00
|
|
|
1, 99999, 1, 99999,
|
|
|
|
-1, 0, 0, 0, 0, -1, 1024, -1, 0, top - 1, 1);
|
|
|
|
if (bottom)
|
2007-07-27 09:59:50 -07:00
|
|
|
BorderWinpartAdd(b, "__BLACK", NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
|
2005-01-30 03:02:43 -08:00
|
|
|
1, 99999, 1, 99999,
|
|
|
|
-1, 0, 0, 1024, -bottom, -1, 1024, -1, 1024, -1, 1);
|
|
|
|
if (left)
|
2007-07-27 09:59:50 -07:00
|
|
|
BorderWinpartAdd(b, "__BLACK", NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
|
2005-01-30 03:02:43 -08:00
|
|
|
1, 99999, 1, 99999,
|
|
|
|
-1, 0, 0, 0, top,
|
|
|
|
-1, 0, left - 1, 1024, -(bottom + 1), 1);
|
|
|
|
if (right)
|
2007-07-27 09:59:50 -07:00
|
|
|
BorderWinpartAdd(b, "__BLACK", NULL, NULL, NULL, 1, FLAG_BUTTON, 0,
|
2005-01-30 03:02:43 -08:00
|
|
|
1, 99999, 1, 99999,
|
|
|
|
-1, 1024, -right, 0, top,
|
|
|
|
-1, 1024, -1, 1024, -(bottom + 1), 1);
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2013-07-07 14:01:22 -07:00
|
|
|
static int
|
|
|
|
_BorderNameCompare(const void *b1, const void *b2)
|
2006-02-18 00:30:09 -08:00
|
|
|
{
|
2013-07-07 14:01:22 -07:00
|
|
|
if (b1 && b2)
|
|
|
|
return strcmp((*(const Border **)b1)->name, (*(const Border **)b2)->name);
|
|
|
|
|
|
|
|
return 0;
|
2006-02-18 00:30:09 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
Border **
|
|
|
|
BordersGetList(int *pnum)
|
|
|
|
{
|
2013-07-07 14:01:22 -07:00
|
|
|
Border **lst;
|
|
|
|
|
2013-06-06 13:37:06 -07:00
|
|
|
lst = LIST_GET_ITEMS(Border, &border_list, pnum);
|
2013-07-07 14:01:22 -07:00
|
|
|
qsort(lst, *pnum, sizeof(Border *), _BorderNameCompare);
|
|
|
|
|
|
|
|
return lst;
|
2006-02-18 00:30:09 -08:00
|
|
|
}
|
|
|
|
|
2008-06-22 06:34:42 -07:00
|
|
|
static ActionClass *
|
|
|
|
BorderGetFallbackAclass(void)
|
|
|
|
{
|
|
|
|
ActionClass *ac;
|
|
|
|
Action *aa;
|
|
|
|
|
|
|
|
ac = ActionclassFind("__fb_bd_ac");
|
|
|
|
if (ac)
|
|
|
|
return ac;
|
|
|
|
|
|
|
|
/* Create fallback actionclass for the fallback border */
|
|
|
|
ac = ActionclassCreate("__fb_bd_ac", 0);
|
|
|
|
if (!ac)
|
|
|
|
return ac;
|
|
|
|
|
|
|
|
aa = ActionCreate(EVENT_MOUSE_DOWN, 1, 0, 0, 1, 0, NULL, NULL);
|
|
|
|
ActionclassAddAction(ac, aa);
|
|
|
|
ActionAddTo(aa, "wop * mo ptr");
|
|
|
|
|
|
|
|
aa = ActionCreate(EVENT_MOUSE_DOWN, 1, 0, 0, 2, 0, NULL, NULL);
|
|
|
|
ActionclassAddAction(ac, aa);
|
|
|
|
ActionAddTo(aa, "wop * close");
|
|
|
|
|
|
|
|
aa = ActionCreate(EVENT_MOUSE_DOWN, 1, 0, 0, 3, 0, NULL, NULL);
|
|
|
|
ActionclassAddAction(ac, aa);
|
|
|
|
ActionAddTo(aa, "wop * sz ptr");
|
|
|
|
|
|
|
|
return ac;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Border *
|
|
|
|
BorderGetFallback(void)
|
2004-01-16 07:34:57 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2008-06-22 06:34:42 -07:00
|
|
|
b = BorderFind("__fb_bd");
|
|
|
|
if (b)
|
|
|
|
return b;
|
|
|
|
|
2010-01-29 11:45:04 -08:00
|
|
|
BorderGetFallbackAclass(); /* Creates the fallback ac */
|
2004-12-28 15:46:49 -08:00
|
|
|
|
2008-06-22 06:34:42 -07:00
|
|
|
/* Create fallback border */
|
|
|
|
b = BorderCreate("__fb_bd");
|
|
|
|
if (!b)
|
|
|
|
return b;
|
2004-12-28 15:46:49 -08:00
|
|
|
|
|
|
|
b->border.left = 8;
|
|
|
|
b->border.right = 8;
|
|
|
|
b->border.top = 8;
|
|
|
|
b->border.bottom = 8;
|
2008-06-22 06:34:42 -07:00
|
|
|
BorderWinpartAdd(b, "__fb_ic", "__fb_bd_ac", NULL, NULL,
|
2007-07-27 09:59:50 -07:00
|
|
|
1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, -1, 0, 0, 0, 0,
|
|
|
|
-1, 1024, -1, 0, 7, 1);
|
2008-06-22 06:34:42 -07:00
|
|
|
BorderWinpartAdd(b, "__fb_ic", "__fb_bd_ac", NULL, NULL,
|
2007-07-27 09:59:50 -07:00
|
|
|
1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, -1, 0, 0, 1024,
|
|
|
|
-8, -1, 1024, -1, 1024, -1, 1);
|
2008-06-22 06:34:42 -07:00
|
|
|
BorderWinpartAdd(b, "__fb_ic", "__fb_bd_ac", NULL, NULL,
|
2007-07-27 09:59:50 -07:00
|
|
|
1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, -1, 0, 0, 0, 8,
|
|
|
|
-1, 0, 7, 1024, -9, 1);
|
2008-06-22 06:34:42 -07:00
|
|
|
BorderWinpartAdd(b, "__fb_ic", "__fb_bd_ac", NULL, NULL,
|
2007-07-27 09:59:50 -07:00
|
|
|
1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, -1, 1024, -8, 0,
|
|
|
|
8, -1, 1024, -1, 1024, -9, 1);
|
2008-06-22 06:34:42 -07:00
|
|
|
|
|
|
|
return b;
|
2004-01-16 07:34:57 -08:00
|
|
|
}
|