e16/src/buttons.c

1101 lines
24 KiB
C
Raw Normal View History

/*
2007-01-13 11:14:29 -08:00
* Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
* Copyright (C) 2004-2014 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 "buttons.h"
#include "cursors.h"
#include "desktops.h"
2006-03-29 11:13:17 -08:00
#include "eimage.h"
#include "emodule.h"
#include "file.h"
#include "grabs.h"
#include "iclass.h"
#include "list.h"
#include "tclass.h"
#include "tooltips.h"
#include "xwin.h"
2004-12-28 15:46:49 -08:00
#define BUTTON_EVENT_MASK \
(KeyPressMask | KeyReleaseMask | \
ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | \
PointerMotionMask)
2004-12-28 15:46:49 -08:00
typedef struct {
int width_min, width_max;
int height_min, height_max;
2004-12-28 15:46:49 -08:00
int xorigin, yorigin;
int xabs, xrel;
int yabs, yrel;
int xsizerel, xsizeabs;
int ysizerel, ysizeabs;
char size_from_image;
} BGeometry;
2004-12-28 15:46:49 -08:00
struct _button {
dlist_t list;
2004-12-28 15:46:49 -08:00
EObj o;
BGeometry geom;
ImageClass *iclass;
ActionClass *aclass;
TextClass *tclass;
char *label;
int id;
2004-12-28 15:46:49 -08:00
int flags;
char internal;
char default_show;
2013-06-29 07:09:59 -07:00
char state;
char left;
2013-06-29 07:43:39 -07:00
ButtonCbFunc *cb_func;
void *cb_prm;
2004-12-28 15:46:49 -08:00
#if 0 /* Unused */
EX_Window inside_win;
EX_Window event_win;
#endif
2004-12-28 15:46:49 -08:00
unsigned int ref_count;
};
static LIST_HEAD(button_list);
static struct {
2004-12-28 15:46:49 -08:00
Button *button;
char loading_user;
2005-06-09 11:28:13 -07:00
char move_pending;
char action_inhibit;
int start_x, start_y;
} Mode_buttons;
2004-12-28 15:46:49 -08:00
static void ButtonHandleEvents(Win win, XEvent * ev, void *btn);
#if 0 /* Unused */
void
ButtonIncRefcount(Button * b)
{
b->ref_count++;
}
void
ButtonDecRefcount(Button * b)
{
b->ref_count--;
}
#endif
static int
ButtonIsFixed(const Button * b)
{
return b->flags & FLAG_FIXED;
}
static int
ButtonIsInternal(const Button * b)
{
return b->internal;
}
Button *
ButtonCreate(const char *name, int id, const char *iclass,
const char *aclass, const char *tclass, const char *label,
int ontop, int flags, int minw, int maxw, int minh, int maxh,
2005-03-31 08:02:56 -08:00
int xo, int yo, int xa, int xr, int ya, int yr, int xsr, int xsa,
int ysr, int ysa, char simg, int desk, char sticky)
{
Button *b;
if (desk < 0 || desk >= (int)DesksGetNumber())
2004-12-28 15:46:49 -08:00
return NULL;
2004-12-28 15:46:49 -08:00
if (sticky && ontop == 1)
desk = 0;
b = ECALLOC(Button, 1);
if (!b)
return b;
LIST_APPEND(Button, &button_list, b);
b->id = id;
if (label && *label)
b->label = Estrdup(label);
b->iclass = ImageclassAlloc(iclass, 1);
b->aclass = ActionclassAlloc(aclass);
if (b->label)
b->tclass = TextclassAlloc(tclass, 1);
b->flags = flags;
b->geom.width_min = minw;
b->geom.width_max = maxw;
b->geom.height_min = minh;
b->geom.height_max = maxh;
b->geom.xorigin = xo;
b->geom.yorigin = yo;
b->geom.xabs = xa;
b->geom.xrel = xr;
b->geom.yabs = ya;
b->geom.yrel = yr;
b->geom.xsizeabs = xsa;
b->geom.xsizerel = xsr;
b->geom.ysizeabs = ysa;
b->geom.ysizerel = ysr;
b->geom.size_from_image = simg;
b->default_show = 1;
2004-12-28 15:46:49 -08:00
EoSetSticky(b, sticky);
EoSetDesk(b, DeskGet(desk));
2013-12-28 09:59:09 -08:00
EoInit(b, EOBJ_TYPE_BUTTON, NoXID, -100, -100, 50, 50, 0, name);
2004-12-28 15:46:49 -08:00
EoSetLayer(b, ontop);
EoSetFade(b, 1);
2004-12-28 15:46:49 -08:00
ESelectInput(EoGetWin(b), BUTTON_EVENT_MASK);
EventCallbackRegister(EoGetWin(b), ButtonHandleEvents, b);
2004-12-28 15:46:49 -08:00
return b;
}
void
ButtonDestroy(Button * b)
{
if (!b)
return;
if (b->ref_count > 0)
{
DialogOK("Button Error!", _("%u references remain"), b->ref_count);
return;
}
LIST_REMOVE(Button, &button_list, b);
2005-10-16 02:33:49 -07:00
EoFini(b);
ImageclassFree(b->iclass);
ActionclassFree(b->aclass);
TextclassFree(b->tclass);
Efree(b->label);
Efree(b);
}
static int
_ButtonMatchName(const void *data, const void *match)
{
return strcmp(EoGetName((const Button *)data), (const char *)match);
}
Button *
ButtonFind(const char *name)
{
return LIST_FIND(Button, &button_list, _ButtonMatchName, name);
}
static void
ButtonCalc(Button * b)
{
int w, h, x, y, xo, yo;
2006-03-29 11:13:17 -08:00
EImage *im;
w = 32;
h = 32;
if (b->geom.size_from_image)
{
im = ImageclassGetImage(b->iclass, 0, 0, 0);
if (im)
{
2006-03-29 11:13:17 -08:00
EImageGetSize(im, &w, &h);
EImageFree(im);
}
else
{
if (!b->iclass)
b->iclass = ImageclassAlloc(NULL, 1);
w = 32;
h = 32;
}
}
else
{
w = ((b->geom.xsizerel * WinGetW(VROOT)) >> 10) + b->geom.xsizeabs;
h = ((b->geom.ysizerel * WinGetH(VROOT)) >> 10) + b->geom.ysizeabs;
}
if (w > b->geom.width_max)
w = b->geom.width_max;
else if (w < b->geom.width_min)
w = b->geom.width_min;
if (h > b->geom.height_max)
h = b->geom.height_max;
else if (h < b->geom.height_min)
h = b->geom.height_min;
xo = (w * b->geom.xorigin) >> 10;
yo = (h * b->geom.yorigin) >> 10;
x = ((b->geom.xrel * WinGetW(VROOT)) >> 10) + b->geom.xabs - xo;
y = ((b->geom.yrel * WinGetH(VROOT)) >> 10) + b->geom.yabs - yo;
EoMoveResize(b, x, y, w, h);
}
static void
ButtonDraw(Button * b)
{
ITApply(EoGetWin(b), b->iclass, NULL,
b->state, 0, 0, ST_BUTTON, b->tclass, NULL, b->label, 0);
EoShapeUpdate(b, 0);
}
#if 0 /* Unused */
void
ButtonDrawWithState(Button * b, int state)
{
b->state = state;
ButtonDraw(b);
}
#endif
void
ButtonShow(Button * b)
{
ButtonCalc(b);
ButtonDraw(b);
EoMap(b, 0);
}
EObj *
ButtonSwallowInto(Button * b, EObj * eo)
{
b->internal = 1;
b->default_show = 0;
b->flags |= FLAG_FIXED;
b->ref_count++;
EobjReparent(EoObj(b), eo, 0, 0);
ButtonCalc(b);
ButtonDraw(b);
EMapWindow(EoGetWin(b));
return EoObj(b);
}
void
2013-06-29 07:43:39 -07:00
ButtonSetCallback(Button * b, ButtonCbFunc * func, void *prm)
{
2013-06-29 07:43:39 -07:00
b->cb_prm = prm;
b->cb_func = func;
}
static void
ButtonMoveToDesktop(Button * b, Desk * dsk)
{
2004-12-28 15:46:49 -08:00
if (EoIsSticky(b) && EoGetLayer(b) == 1)
dsk = DeskGet(0);
if (!dsk)
return;
if (EoGetDesk(b) != dsk)
EoReparent(b, EoObj(dsk), EoGetX(b), EoGetY(b));
}
void
ButtonHide(Button * b)
{
EoUnmap(b);
}
static void
ButtonToggle(Button * b)
{
if (b->internal)
return;
if (EoIsShown(b))
ButtonHide(b);
else
ButtonShow(b);
}
void
ButtonMoveToCoord(Button * b, int x, int y)
{
int rx, ry, relx, rely, absx, absy;
if (ButtonIsFixed(b))
return;
if ((x + (EoGetW(b) >> 1)) < (WinGetW(VROOT) / 3))
relx = 0;
else if ((x + (EoGetW(b) >> 1)) > ((WinGetW(VROOT) * 2) / 3))
relx = 1024;
else
relx = 512;
rx = (relx * WinGetW(VROOT)) >> 10;
absx = x - rx;
if ((y + (EoGetH(b) >> 1)) < (WinGetH(VROOT) / 3))
rely = 0;
else if ((y + (EoGetH(b) >> 1)) > ((WinGetH(VROOT) * 2) / 3))
rely = 1024;
else
rely = 512;
ry = (rely * WinGetH(VROOT)) >> 10;
absy = y - ry;
if (!(b->flags & FLAG_FIXED_HORIZ))
{
b->geom.xorigin = 0;
b->geom.xabs = absx;
b->geom.xrel = relx;
}
if (!(b->flags & FLAG_FIXED_VERT))
{
b->geom.yorigin = 0;
b->geom.yabs = absy;
b->geom.yrel = rely;
}
ButtonCalc(b);
}
void
ButtonMoveRelative(Button * b, int dx, int dy)
{
2004-12-28 15:46:49 -08:00
ButtonMoveToCoord(b, EoGetX(b) + dx, EoGetY(b) + dy);
}
2004-12-28 15:46:49 -08:00
int
ButtonDoShowDefault(const Button * b)
{
return !b->internal && b->default_show;
}
#if 0 /* Unused */
2004-12-28 15:46:49 -08:00
int
ButtonEmbedWindow(Button * b, EX_Window WindowToEmbed)
{
int w, h;
EReparentWindow(WindowToEmbed, EoGetWin(b), 0, 0);
2004-12-28 15:46:49 -08:00
b->inside_win = WindowToEmbed;
EGetGeometry(WindowToEmbed, NULL, NULL, NULL, &w, &h, NULL, NULL);
EMoveWindow(b->inside_win, (EoGetW(b) - w) >> 1, (EoGetH(b) - h) >> 1);
2004-12-28 15:46:49 -08:00
b->event_win = ECreateEventWindow(EoGetWin(b), 0, 0, w, h);
EventCallbackRegister(b->event_win, ButtonHandleEvents, b);
ESelectInput(b->event_win,
ButtonPressMask | ButtonReleaseMask | EnterWindowMask |
LeaveWindowMask | ButtonMotionMask);
EMoveWindow(b->event_win, (EoGetW(b) - w) >> 1, (EoGetH(b) - h) >> 1);
EMapRaised(b->event_win);
return 0;
}
#endif
2004-12-28 15:46:49 -08:00
static void
ButtonDragStart(Button * b)
{
if (ButtonIsFixed(b))
return;
GrabPointerSet(EoGetWin(b), ECSR_GRAB, 0);
2004-12-28 15:46:49 -08:00
Mode.mode = MODE_BUTTONDRAG;
2005-06-09 11:28:13 -07:00
Mode_buttons.move_pending = 1;
Mode_buttons.start_x = Mode.events.cx;
Mode_buttons.start_y = Mode.events.cy;
2004-12-28 15:46:49 -08:00
}
static void
ButtonDragEnd(Button * b)
{
Desk *dsk;
2004-12-28 15:46:49 -08:00
Mode.mode = MODE_NONE;
2005-06-09 11:28:13 -07:00
if (!Mode_buttons.move_pending)
2004-12-28 15:46:49 -08:00
{
dsk = DesktopAt(Mode.events.mx, Mode.events.my);
ButtonMoveToDesktop(b, dsk);
dsk = EoGetDesk(b);
ButtonMoveRelative(b, -EoGetX(dsk), -EoGetY(dsk));
2004-12-28 15:46:49 -08:00
}
else
2005-06-09 11:28:13 -07:00
Mode_buttons.move_pending = 0;
2004-12-28 15:46:49 -08:00
autosave();
}
void
ButtonsForeach(int id, Desk * dsk, void (*func) (Button * b))
{
2013-09-08 13:11:04 -07:00
Button *b, *tmp;
2013-09-08 13:11:04 -07:00
LIST_FOR_EACH_SAFE(Button, &button_list, b, tmp)
2006-04-16 15:59:26 -07:00
{
if (id >= 0 && id != b->id)
continue;
if (dsk && dsk != EoGetDesk(b))
continue;
func(b);
}
}
void
ButtonsMoveStickyToDesk(Desk * dsk)
{
Button *b;
LIST_FOR_EACH(Button, &button_list, b)
{
if (!EoIsSticky(b) || ButtonIsInternal(b))
continue;
ButtonMoveToDesktop(b, dsk);
}
}
/*
* Button event handlers
*/
2004-12-28 15:46:49 -08:00
static void
ButtonDoAction(Button * b, XEvent * ev)
2004-12-28 15:46:49 -08:00
{
2013-06-29 07:43:39 -07:00
if (b->cb_func)
b->cb_func(b->cb_prm, ev, b->aclass);
else
ActionclassEvent(b->aclass, ev, NULL);
}
static void
ButtonEventMouseDown(Button * b, XEvent * ev)
{
Mode_buttons.button = b;
GrabPointerSet(EoGetWin(b), ECSR_GRAB, 0);
2004-12-28 15:46:49 -08:00
2013-06-29 07:25:36 -07:00
#if 0 /* Unused */
2004-12-28 15:46:49 -08:00
if (b->inside_win)
{
EX_Window win = ev->xbutton.window;
2004-12-28 15:46:49 -08:00
ev->xbutton.window = b->inside_win;
EXSendEvent(b->inside_win, ButtonPressMask, ev);
2004-12-28 15:46:49 -08:00
ev->xbutton.window = win;
}
2013-06-29 07:25:36 -07:00
#endif
2004-12-28 15:46:49 -08:00
b->state = STATE_CLICKED;
ButtonDraw(b);
if (!ButtonIsInternal(b))
2005-06-09 11:28:13 -07:00
{
ActionClass *ac;
ac = ActionclassFind("ACTION_BUTTON_DRAG");
if (ac && !Mode_buttons.action_inhibit)
ActionclassEvent(ac, ev, NULL);
2005-06-09 11:28:13 -07:00
}
if (b->aclass && !Mode_buttons.action_inhibit)
ButtonDoAction(b, ev);
}
2004-12-28 15:46:49 -08:00
static void
ButtonEventMouseUp(Button * b, XEvent * ev)
{
2013-06-29 07:25:36 -07:00
#if 0 /* Unused */
if (b->inside_win && !Mode_buttons.action_inhibit)
{
EX_Window win = ev->xbutton.window;
2004-12-28 15:46:49 -08:00
ev->xbutton.window = b->inside_win;
EXSendEvent(b->inside_win, ButtonReleaseMask, ev);
2004-12-28 15:46:49 -08:00
ev->xbutton.window = win;
}
2013-06-29 07:25:36 -07:00
#endif
2004-12-28 15:46:49 -08:00
if ((b->state == STATE_CLICKED) && (!b->left))
b->state = STATE_HILITED;
else
b->state = STATE_NORMAL;
ButtonDraw(b);
2005-06-09 11:28:13 -07:00
GrabPointerRelease();
2004-12-28 15:46:49 -08:00
b->left = 0;
if (Mode.mode == MODE_BUTTONDRAG)
ButtonDragEnd(Mode_buttons.button);
Mode_buttons.button = NULL;
if (b->aclass && !b->left && !Mode_buttons.action_inhibit)
ButtonDoAction(b, ev);
Mode_buttons.action_inhibit = 0;
2004-12-28 15:46:49 -08:00
}
static void
ButtonEventMotion(Button * b, XEvent * ev __UNUSED__)
{
int dx, dy;
if (Mode.mode != MODE_BUTTONDRAG)
return;
dx = Mode.events.mx - Mode.events.px;
dy = Mode.events.my - Mode.events.py;
2004-12-28 15:46:49 -08:00
2005-06-09 11:28:13 -07:00
if (Mode_buttons.move_pending)
2004-12-28 15:46:49 -08:00
{
int x, y;
x = Mode.events.mx - Mode_buttons.start_x;
y = Mode.events.my - Mode_buttons.start_y;
2004-12-28 15:46:49 -08:00
if (x < 0)
x = -x;
if (y < 0)
y = -y;
if ((x > Conf.buttons.move_resistance) ||
(y > Conf.buttons.move_resistance))
2005-06-09 11:28:13 -07:00
Mode_buttons.move_pending = 0;
Mode_buttons.action_inhibit = 1;
2004-12-28 15:46:49 -08:00
}
2005-06-09 11:28:13 -07:00
if (!Mode_buttons.move_pending)
ButtonMoveRelative(b, dx, dy);
2004-12-28 15:46:49 -08:00
}
2004-12-28 15:46:49 -08:00
static void
ButtonEventMouseIn(Button * b, XEvent * ev)
{
if (b->state == STATE_CLICKED)
b->left = 0;
else
{
b->state = STATE_HILITED;
ButtonDraw(b);
if (b->aclass && !Mode_buttons.action_inhibit)
ActionclassEvent(b->aclass, ev, NULL);
}
2004-12-28 15:46:49 -08:00
}
2004-12-28 15:46:49 -08:00
static void
ButtonEventMouseOut(Button * b, XEvent * ev)
{
if (b->state == STATE_CLICKED)
b->left = 1;
else
{
b->state = STATE_NORMAL;
ButtonDraw(b);
if (b->aclass && !Mode_buttons.action_inhibit)
ActionclassEvent(b->aclass, ev, NULL);
2004-12-28 15:46:49 -08:00
}
}
static ActionClass *
ButtonGetAclass(void *data)
{
Button *b = (Button *) data;
/* Validate button */
if (!LIST_CHECK(Button, &button_list, b))
return NULL;
return b->aclass;
}
2004-12-28 15:46:49 -08:00
static void
ButtonHandleEvents(Win win __UNUSED__, XEvent * ev, void *prm)
{
2004-12-28 15:46:49 -08:00
Button *b = (Button *) prm;
2004-12-28 15:46:49 -08:00
switch (ev->type)
{
case ButtonPress:
ButtonEventMouseDown(b, ev);
break;
case ButtonRelease:
ButtonEventMouseUp(b, ev);
break;
case MotionNotify:
ButtonEventMotion(b, ev);
if (b->aclass)
TooltipsSetPending(0, ButtonGetAclass, b);
2004-12-28 15:46:49 -08:00
break;
case EnterNotify:
ButtonEventMouseIn(b, ev);
break;
case LeaveNotify:
ButtonEventMouseOut(b, ev);
break;
}
2013-06-29 07:43:39 -07:00
if (b->cb_func)
b->cb_func(b->cb_prm, ev, NULL);
}
2004-12-28 15:46:49 -08:00
/*
* Configuration load/save
*/
#include "conf.h"
int
ButtonsConfigLoad(FILE * fs)
2004-12-28 15:46:49 -08:00
{
int err = 0;
char s[FILEPATH_LEN_MAX];
char s2[FILEPATH_LEN_MAX];
char *p2;
int i1, i2;
char name[64], label[64];
char iclass[64], aclass[64], tclass[64];
2004-12-28 15:46:49 -08:00
Button *bt = NULL;
Button *pbt = NULL;
int ontop = 0;
2004-12-28 15:46:49 -08:00
int flags = 0, minw = 1, maxw = 99999, minh = 1;
int maxh = 99999, xo = 0, yo = 0, xa = 0;
int xr = 0, ya = 0, yr = 0;
int xsr = 0, xsa = 0, ysr = 0, ysa = 0;
char simg = 0;
int desk = 0;
char sticky = 0;
char show = 1;
char internal = 0;
name[0] = label[0] = '\0';
iclass[0] = aclass[0] = tclass[0] = '\0';
while (GetLine(s, sizeof(s), fs))
{
i1 = ConfigParseline1(s, s2, &p2, NULL);
i2 = atoi(s2);
2004-12-28 15:46:49 -08:00
switch (i1)
{
case CONFIG_CLOSE:
if (!pbt && !Mode_buttons.loading_user)
2004-12-28 15:46:49 -08:00
{
bt = ButtonCreate(name, 0, iclass, aclass, tclass, label,
ontop, flags, minw, maxw, minh, maxh,
xo, yo, xa, xr, ya, yr, xsr, xsa, ysr, ysa,
simg, desk, sticky);
if (bt)
{
bt->default_show = show;
bt->internal = internal;
}
2004-12-28 15:46:49 -08:00
}
else if (pbt)
{
if (label[0])
_EFDUP(pbt->label, label);
EoSetLayer(pbt, ontop);
EoSetSticky(pbt, sticky);
ButtonMoveToDesktop(pbt, DeskGet(desk));
if (iclass[0])
pbt->iclass = ImageclassFind(iclass, 1);
if (aclass[0])
pbt->aclass = ActionclassFind(aclass);
if (tclass[0])
pbt->tclass = TextclassFind(tclass, 1);
pbt->flags = flags;
pbt->internal = internal;
pbt->default_show = show;
pbt->geom.width_min = minw;
pbt->geom.width_max = maxw;
pbt->geom.height_min = minh;
pbt->geom.height_max = maxh;
pbt->geom.xorigin = xo;
pbt->geom.yorigin = yo;
pbt->geom.xabs = xa;
pbt->geom.xrel = xr;
pbt->geom.yabs = ya;
pbt->geom.yrel = yr;
pbt->geom.xsizerel = xsr;
pbt->geom.xsizeabs = xsa;
pbt->geom.ysizerel = ysr;
pbt->geom.ysizeabs = ysa;
pbt->geom.size_from_image = simg;
}
goto done;
2004-12-28 15:46:49 -08:00
case CONFIG_CLASSNAME:
STRCPY(name, s2);
pbt = ButtonFind(name);
2004-12-28 15:46:49 -08:00
break;
case BUTTON_LABEL:
STRCPY(label, s2);
2004-12-28 15:46:49 -08:00
break;
case CONFIG_IMAGECLASS:
STRCPY(iclass, s2);
break;
case CONFIG_ACTIONCLASS:
STRCPY(aclass, s2);
break;
case CONFIG_TEXT:
STRCPY(tclass, s2);
break;
case BORDERPART_ONTOP:
ontop = i2;
2004-12-28 15:46:49 -08:00
break;
case BORDERPART_WMIN:
minw = i2;
2004-12-28 15:46:49 -08:00
break;
case BORDERPART_WMAX:
maxw = i2;
2004-12-28 15:46:49 -08:00
break;
case BORDERPART_HMIN:
minh = i2;
2004-12-28 15:46:49 -08:00
break;
case BORDERPART_FLAGS:
flags = i2;
2004-12-28 15:46:49 -08:00
break;
case BORDERPART_HMAX:
maxh = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_XO:
xo = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_YO:
yo = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_XA:
xa = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_XR:
xr = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_YA:
ya = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_YR:
yr = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_XSR:
xsr = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_XSA:
xsa = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_YSR:
ysr = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_YSA:
ysa = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_SIMG:
simg = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_DESK:
desk = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_STICKY:
sticky = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_INTERNAL:
internal = i2;
2004-12-28 15:46:49 -08:00
break;
case BUTTON_SHOW:
show = i2;
2004-12-28 15:46:49 -08:00
break;
default:
break;
}
}
2004-12-28 15:46:49 -08:00
err = -1;
2004-12-28 15:46:49 -08:00
done:
return err;
}
static void
ButtonsConfigLoadUser(void)
{
char s[4096];
Esnprintf(s, sizeof(s), "%s.buttons", EGetSavePrefix());
Mode_buttons.loading_user = 1;
ConfigFileLoad(s, NULL, ConfigFileRead, 0);
Mode_buttons.loading_user = 0;
}
static void
ButtonsConfigSave(void)
{
char s[FILEPATH_LEN_MAX], st[FILEPATH_LEN_MAX];
FILE *fs;
Button *b;
2004-12-28 15:46:49 -08:00
int flags;
if (LIST_IS_EMPTY(&button_list))
return;
Etmp(st);
fs = fopen(st, "w");
if (!fs)
return;
LIST_FOR_EACH(Button, &button_list, b)
{
if (b->id != 0 || b->internal)
continue;
fprintf(fs, "4 999\n");
fprintf(fs, "100 %s\n", EoGetName(b));
#if 0 /* Remove? */
if (b->iclass)
fprintf(fs, "12 %s\n", ImageclassGetName(b->iclass));
if (b->aclass)
fprintf(fs, "11 %s\n", ActionclassGetName(b->aclass));
if (EoGetLayer(b) >= 0)
fprintf(fs, "453 %i\n", EoGetLayer(b));
#endif
fprintf(fs, "456 %i\n", b->geom.width_min);
fprintf(fs, "457 %i\n", b->geom.width_max);
fprintf(fs, "468 %i\n", b->geom.height_min);
fprintf(fs, "469 %i\n", b->geom.height_max);
fprintf(fs, "528 %i\n", b->geom.xorigin);
fprintf(fs, "529 %i\n", b->geom.yorigin);
fprintf(fs, "530 %i\n", b->geom.xabs);
fprintf(fs, "531 %i\n", b->geom.xrel);
fprintf(fs, "532 %i\n", b->geom.yabs);
fprintf(fs, "533 %i\n", b->geom.yrel);
fprintf(fs, "534 %i\n", b->geom.xsizerel);
fprintf(fs, "535 %i\n", b->geom.xsizeabs);
fprintf(fs, "536 %i\n", b->geom.ysizerel);
fprintf(fs, "537 %i\n", b->geom.ysizeabs);
fprintf(fs, "538 %i\n", b->geom.size_from_image);
2012-10-24 10:20:38 -07:00
fprintf(fs, "539 %u\n", EoGetDeskNum(b));
fprintf(fs, "540 %i\n", EoIsSticky(b));
2012-10-24 10:20:38 -07:00
fprintf(fs, "542 %u\n", EoIsShown(b));
if (b->flags)
{
flags = 0;
if (((b->flags & FLAG_FIXED_HORIZ) &&
(b->flags & FLAG_FIXED_VERT)) || (b->flags & FLAG_FIXED))
flags = 2;
else if (b->flags & FLAG_FIXED_HORIZ)
flags = 3;
else if (b->flags & FLAG_FIXED_VERT)
flags = 4;
else if (b->flags & FLAG_TITLE)
flags = 0;
else if (b->flags & FLAG_MINIICON)
flags = 1;
fprintf(fs, "454 %i\n", flags);
}
fprintf(fs, "1000\n");
}
2004-12-28 15:46:49 -08:00
fclose(fs);
Esnprintf(s, sizeof(s), "%s.buttons", EGetSavePrefix());
E_mv(st, s);
2004-12-28 15:46:49 -08:00
}
/*
* Buttons Module
*/
static void
ButtonsSighan(int sig, void *prm __UNUSED__)
{
switch (sig)
{
case ESIGNAL_INIT:
memset(&Mode_buttons, 0, sizeof(Mode_buttons));
break;
case ESIGNAL_CONFIGURE:
ButtonsConfigLoadUser();
break;
case ESIGNAL_EXIT:
if (Mode.wm.save_ok)
ButtonsConfigSave();
break;
}
2004-12-28 15:46:49 -08:00
}
typedef struct {
int id;
int match;
const char *regex;
} button_match_data;
static void
_ButtonHideShow(void *data, void *prm)
{
Button *b = (Button *) data;
button_match_data *bmd = (button_match_data *) prm;
int match;
if (bmd->id >= 0 && bmd->id != b->id)
return;
if (bmd->regex)
{
match = matchregexp(bmd->regex, EoGetName(b));
if ((match && !bmd->match) || (!match && bmd->match))
return;
#if ENABLE_DESKRAY
if (!strcmp(EoGetName(b), "_DESKTOP_DESKRAY_DRAG_CONTROL"))
return;
#endif
}
ButtonToggle(b);
}
2004-12-28 15:46:49 -08:00
static void
doHideShowButton(const char *params)
{
char s[1024];
const char *ss;
int len;
button_match_data bmd = { -1, 1, NULL };
Button *b;
2005-02-26 17:53:22 -08:00
if (!params)
2004-12-28 15:46:49 -08:00
{
bmd.id = 0;
LIST_FOR_EACH(Button, &button_list, b) _ButtonHideShow(b, &bmd);
2005-02-26 17:53:22 -08:00
goto done;
}
s[0] = '\0';
len = 0;
sscanf(params, "%1000s %n", s, &len);
ss = (len > 0) ? params + len : NULL;
2005-02-26 17:53:22 -08:00
if (!strcmp(s, "button"))
{
sscanf(params, "%*s %1000s", s);
b = ButtonFind(s);
2005-02-26 17:53:22 -08:00
if (b)
ButtonToggle(b);
}
else if (!strcmp(s, "buttons"))
{
if (!ss)
return;
bmd.regex = ss;
LIST_FOR_EACH(Button, &button_list, b) _ButtonHideShow(b, &bmd);
2005-02-26 17:53:22 -08:00
}
else if (!strcmp(s, "all_buttons_except"))
{
if (!ss)
return;
bmd.id = 0;
bmd.match = 0;
bmd.regex = ss;
LIST_FOR_EACH(Button, &button_list, b) _ButtonHideShow(b, &bmd);
2004-12-28 15:46:49 -08:00
}
2005-02-26 17:53:22 -08:00
else if (!strcmp(s, "all"))
2004-12-28 15:46:49 -08:00
{
LIST_FOR_EACH(Button, &button_list, b) _ButtonHideShow(b, &bmd);
2004-12-28 15:46:49 -08:00
}
2005-02-26 17:53:22 -08:00
done:
2004-12-28 15:46:49 -08:00
autosave();
}
2004-12-28 15:46:49 -08:00
static void
ButtonsIpc(const char *params)
{
2004-12-28 15:46:49 -08:00
const char *p;
char cmd[128], prm[4096];
int len;
Button *b;
2004-12-28 15:46:49 -08:00
cmd[0] = prm[0] = '\0';
p = params;
if (p)
{
len = 0;
sscanf(p, "%100s %4000s %n", cmd, prm, &len);
p += len;
}
2004-12-28 15:46:49 -08:00
if (!p || cmd[0] == '?')
{
2004-12-28 15:46:49 -08:00
}
else if (!strncmp(cmd, "list", 2))
{
IpcPrintf("Win d s l x y w h name\n");
LIST_FOR_EACH(Button, &button_list, b)
IpcPrintf("%#x %2d %2d %2d %5d+%5d %5dx%5d %s\n",
EoGetXwin(b), EoGetDeskNum(b), EoIsSticky(b),
EoGetLayer(b), EoGetX(b), EoGetY(b), EoGetW(b), EoGetH(b),
EoGetName(b));
2004-12-28 15:46:49 -08:00
}
else if (!strncmp(cmd, "move", 2))
{
if (Mode_buttons.button)
ButtonDragStart(Mode_buttons.button);
}
2004-12-28 15:46:49 -08:00
}
2004-12-28 15:46:49 -08:00
static void
IPC_ButtonShow(const char *params)
2004-12-28 15:46:49 -08:00
{
doHideShowButton(params);
}
2004-12-28 15:46:49 -08:00
static const IpcItem ButtonsIpcArray[] = {
2004-12-28 15:46:49 -08:00
{
ButtonsIpc,
"button", "btn",
"Button functions",
" button list List buttons\n"},
{
IPC_ButtonShow,
"button_show", NULL,
"Show or Hide buttons on desktop",
"use \"button_show <button/buttons/all_buttons_except/all> "
"<BUTTON_STRING>\"\nexamples: \"button_show buttons all\" "
"(removes all buttons and the dragbar)\n\"button_show\" "
"(removes all buttons)\n \"button_show buttons CONFIG*\" "
"(removes all buttons with CONFIG in the start)\n"},
};
#define N_IPC_FUNCS (sizeof(ButtonsIpcArray)/sizeof(IpcItem))
#if 0
static const CfgItem ButtonsCfgItems[] = {
CFG_ITEM_BOOL(Conf.buttons, enable, 1),
};
#define N_CFG_ITEMS (sizeof(ButtonsCfgItems)/sizeof(CfgItem))
#endif
/*
* Module descriptor
*/
extern const EModule ModButtons;
const EModule ModButtons = {
2004-12-28 15:46:49 -08:00
"buttons", "btn",
ButtonsSighan,
{N_IPC_FUNCS, ButtonsIpcArray},
{0, NULL}
};