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
|
2021-03-04 23:24:42 -08:00
|
|
|
* Copyright (C) 2005-2021 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.
|
|
|
|
*/
|
1999-08-17 15:56:46 -07:00
|
|
|
#include "E.h"
|
2005-12-22 10:43:15 -08:00
|
|
|
#include "borders.h"
|
2004-12-28 15:46:49 -08:00
|
|
|
#include "conf.h"
|
2005-09-04 00:27:20 -07:00
|
|
|
#include "desktops.h"
|
2005-07-16 09:57:45 -07:00
|
|
|
#include "emodule.h"
|
|
|
|
#include "ewins.h"
|
2005-02-13 14:54:17 -08:00
|
|
|
#include "ewin-ops.h"
|
2013-06-06 13:37:06 -07:00
|
|
|
#include "list.h"
|
2006-11-19 13:55:52 -08:00
|
|
|
#include "windowmatch.h"
|
2005-02-13 14:54:17 -08:00
|
|
|
|
2005-11-27 05:11:06 -08:00
|
|
|
typedef struct _windowmatch WindowMatch;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2008-03-23 04:54:24 -07:00
|
|
|
struct _windowmatch {
|
2023-10-21 02:04:12 -07:00
|
|
|
dlist_t list;
|
|
|
|
char *name;
|
|
|
|
/* Match criteria */
|
|
|
|
char match;
|
|
|
|
char op;
|
|
|
|
char prop;
|
|
|
|
char qual;
|
|
|
|
char *value;
|
|
|
|
int width_min, width_max;
|
|
|
|
int height_min, height_max;
|
|
|
|
/* Match actions */
|
|
|
|
char *args;
|
|
|
|
Border *border;
|
2005-02-06 11:13:34 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
#define MATCH_TYPE_TITLE 1
|
|
|
|
#define MATCH_TYPE_WM_NAME 2
|
|
|
|
#define MATCH_TYPE_WM_CLASS 3
|
|
|
|
#define MATCH_TYPE_SIZE 4
|
|
|
|
#define MATCH_TYPE_SIZE_H 5
|
|
|
|
#define MATCH_TYPE_SIZE_V 6
|
|
|
|
#define MATCH_TYPE_PROP 7
|
|
|
|
|
|
|
|
#define MATCH_PROP_TRANSIENT 1
|
|
|
|
#define MATCH_PROP_SHAPED 2
|
|
|
|
#define MATCH_PROP_FIXEDSIZE 3
|
|
|
|
#define MATCH_PROP_FIXEDSIZE_H 4
|
|
|
|
#define MATCH_PROP_FIXEDSIZE_V 5
|
|
|
|
|
|
|
|
#define MATCH_OP_BORDER 1
|
|
|
|
#define MATCH_OP_ICON 2
|
|
|
|
#define MATCH_OP_WINOP 3
|
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
static int WindowMatchEobjOpsParse(EObj * eo, const char *ops);
|
2005-11-27 05:11:06 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
static LIST_HEAD(wm_list);
|
2006-02-18 00:30:09 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
static const char *const MatchType[] = {
|
|
|
|
NULL, "Title", "Name", "Class", "Size", "Width", "Height", "Prop", NULL
|
2005-02-06 11:13:34 -08:00
|
|
|
};
|
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
static const char *const MatchProp[] = {
|
|
|
|
NULL, "Transient", "Shaped", "FixedSize", "FixedWidth", "FixedHeight", NULL
|
2005-02-06 11:13:34 -08:00
|
|
|
};
|
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
static const char *const MatchOp[] = {
|
|
|
|
NULL, "Border", "Icon", "Winop", NULL
|
2005-02-06 11:13:34 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
2009-09-13 06:45:41 -07:00
|
|
|
MatchFind(const char *const *list, const char *str)
|
2005-02-06 11:13:34 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
int i;
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
for (i = 1; list[i]; i++)
|
|
|
|
if (!strcmp(str, list[i]))
|
|
|
|
return i;
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
return 0;
|
2005-02-06 11:13:34 -08:00
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
static WindowMatch *
|
|
|
|
WindowMatchCreate(const char *name)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatch *b;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
b = ECALLOC(WindowMatch, 1);
|
|
|
|
if (!b)
|
|
|
|
return NULL;
|
2005-01-25 13:58:28 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
LIST_PREPEND(WindowMatch, &wm_list, b);
|
2006-02-18 00:30:09 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
b->name = Estrdup(name);
|
|
|
|
b->width_max = 99999;
|
|
|
|
b->height_max = 99999;
|
2005-01-25 13:58:28 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
return b;
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
static void
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchDestroy(WindowMatch *wm)
|
2004-12-28 15:46:49 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
if (!wm)
|
|
|
|
return;
|
2004-12-28 15:46:49 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
LIST_REMOVE(WindowMatch, &wm_list, wm);
|
2004-12-28 15:46:49 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
Efree(wm->name);
|
|
|
|
Efree(wm->value);
|
|
|
|
Efree(wm->args);
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
Efree(wm);
|
2004-12-28 15:46:49 -08:00
|
|
|
}
|
|
|
|
|
2005-02-07 14:42:19 -08:00
|
|
|
int
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchConfigLoad(FILE *fs)
|
2004-12-28 15:46:49 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
int err = 0;
|
|
|
|
WindowMatch *wm = 0;
|
|
|
|
char s[FILEPATH_LEN_MAX];
|
|
|
|
char s2[FILEPATH_LEN_MAX];
|
|
|
|
char *p2;
|
|
|
|
int i1;
|
|
|
|
|
|
|
|
while (GetLine(s, sizeof(s), fs))
|
|
|
|
{
|
|
|
|
i1 = ConfigParseline1(s, s2, &p2, NULL);
|
|
|
|
switch (i1)
|
|
|
|
{
|
|
|
|
case CONFIG_WINDOWMATCH:
|
|
|
|
err = -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CONFIG_CLASSNAME:
|
|
|
|
wm = WindowMatchCreate(s2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CONFIG_CLOSE:
|
|
|
|
if (wm)
|
|
|
|
{
|
|
|
|
if (!wm->match || !wm->op)
|
|
|
|
{
|
|
|
|
Eprintf("%s: Skip invalid '%s'\n", __func__, wm->name);
|
|
|
|
WindowMatchDestroy(wm);
|
|
|
|
}
|
|
|
|
wm = NULL;
|
|
|
|
err = 0;
|
|
|
|
}
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
case WINDOWMATCH_MATCHTITLE:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->match = MATCH_TYPE_TITLE;
|
|
|
|
wm->value = Estrdup(p2);
|
|
|
|
break;
|
|
|
|
case WINDOWMATCH_MATCHNAME:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->match = MATCH_TYPE_WM_NAME;
|
|
|
|
wm->value = Estrdup(p2);
|
|
|
|
break;
|
|
|
|
case WINDOWMATCH_MATCHCLASS:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->match = MATCH_TYPE_WM_CLASS;
|
|
|
|
wm->value = Estrdup(p2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WINDOWMATCH_WIDTH:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
if (wm->match == MATCH_TYPE_SIZE_V)
|
|
|
|
wm->match = MATCH_TYPE_SIZE;
|
|
|
|
else
|
|
|
|
wm->match = MATCH_TYPE_SIZE_H;
|
|
|
|
sscanf(s, "%*s %u %u", &(wm->width_min), &(wm->width_max));
|
|
|
|
break;
|
|
|
|
case WINDOWMATCH_HEIGHT:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
if (wm->match == MATCH_TYPE_SIZE_H)
|
|
|
|
wm->match = MATCH_TYPE_SIZE;
|
|
|
|
else
|
|
|
|
wm->match = MATCH_TYPE_SIZE_V;
|
|
|
|
sscanf(s, "%*s %u %u", &(wm->height_min), &(wm->height_max));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WINDOWMATCH_TRANSIENT:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->match = MATCH_TYPE_PROP;
|
|
|
|
wm->prop = MATCH_PROP_TRANSIENT;
|
|
|
|
wm->qual = !atoi(s2);
|
|
|
|
break;
|
|
|
|
case WINDOWMATCH_SHAPED:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->match = MATCH_TYPE_PROP;
|
|
|
|
wm->prop = MATCH_PROP_SHAPED;
|
|
|
|
wm->qual = !atoi(s2);
|
|
|
|
break;
|
|
|
|
case WINDOWMATCH_NO_RESIZE_H:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->match = MATCH_TYPE_PROP;
|
|
|
|
if (wm->prop == MATCH_PROP_FIXEDSIZE_V)
|
|
|
|
wm->prop = MATCH_PROP_FIXEDSIZE;
|
|
|
|
else
|
|
|
|
wm->prop = MATCH_PROP_FIXEDSIZE_H;
|
|
|
|
wm->qual = !atoi(s2);
|
|
|
|
break;
|
|
|
|
case WINDOWMATCH_NO_RESIZE_V:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->match = MATCH_TYPE_PROP;
|
|
|
|
if (wm->prop == MATCH_PROP_FIXEDSIZE_H)
|
|
|
|
wm->prop = MATCH_PROP_FIXEDSIZE;
|
|
|
|
else
|
|
|
|
wm->prop = MATCH_PROP_FIXEDSIZE_V;
|
|
|
|
wm->qual = !atoi(s2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WINDOWMATCH_USEBORDER:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->border = BorderFind(s2);
|
|
|
|
if (!wm->border)
|
|
|
|
{
|
|
|
|
Eprintf("%s: No such border: '%s'\n", __func__, s2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
wm->op = MATCH_OP_BORDER;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WINDOWMATCH_ICON:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->args = Estrdup(s2);
|
|
|
|
wm->op = MATCH_OP_ICON;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WINDOWMATCH_DESKTOP:
|
|
|
|
#if 0 /* This has not been active since at least 0.16.5 */
|
|
|
|
wm->desk = atoi(s2);
|
2005-02-07 14:42:19 -08:00
|
|
|
#endif
|
2023-10-21 02:04:12 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WINDOWMATCH_MAKESTICKY:
|
|
|
|
if (!wm)
|
|
|
|
break;
|
|
|
|
wm->args = Estrdupcat2(wm->args, ":", "stick");
|
|
|
|
wm->op = MATCH_OP_WINOP;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ConfigParseError("WindowMatch", s);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
return err;
|
2004-12-28 15:46:49 -08:00
|
|
|
}
|
|
|
|
|
2012-12-24 02:41:50 -08:00
|
|
|
static void
|
2005-02-06 11:13:34 -08:00
|
|
|
WindowMatchDecode(const char *line)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
char match[32], value[1024], op[32];
|
|
|
|
const char *args;
|
|
|
|
WindowMatch *wm = NULL;
|
|
|
|
int err, num, w1, w2, h1, h2;
|
|
|
|
|
|
|
|
match[0] = value[0] = op[0] = '\0';
|
|
|
|
num = sscanf(line, "%31s %1023s %31s %n", match, value, op, &w1);
|
|
|
|
if (num < 3)
|
|
|
|
return;
|
|
|
|
args = line + w1;
|
|
|
|
if (*args == '\0')
|
|
|
|
return;
|
|
|
|
|
|
|
|
err = 0;
|
|
|
|
|
|
|
|
num = MatchFind(MatchType, match);
|
|
|
|
if (num <= 0)
|
|
|
|
{
|
|
|
|
Eprintf("%s: Error (%s): %s\n", __func__, match, line);
|
|
|
|
err = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
wm = WindowMatchCreate(NULL);
|
|
|
|
if (!wm)
|
|
|
|
return;
|
|
|
|
|
|
|
|
wm->match = num;
|
|
|
|
|
|
|
|
switch (wm->match)
|
|
|
|
{
|
|
|
|
case MATCH_TYPE_TITLE:
|
|
|
|
case MATCH_TYPE_WM_NAME:
|
|
|
|
case MATCH_TYPE_WM_CLASS:
|
|
|
|
wm->value = Estrdup(value);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_TYPE_SIZE:
|
|
|
|
num = sscanf(value, "%u-%ux%u-%u", &w1, &w2, &h1, &h2);
|
|
|
|
if (num < 4)
|
|
|
|
goto case_error;
|
|
|
|
wm->width_min = w1;
|
|
|
|
wm->width_max = w2;
|
|
|
|
wm->height_min = h1;
|
|
|
|
wm->height_max = h2;
|
|
|
|
break;
|
|
|
|
case MATCH_TYPE_SIZE_H:
|
|
|
|
num = sscanf(value, "%u-%u", &w1, &w2);
|
|
|
|
if (num < 2)
|
|
|
|
goto case_error;
|
|
|
|
wm->width_min = w1;
|
|
|
|
wm->width_max = w2;
|
|
|
|
break;
|
|
|
|
case MATCH_TYPE_SIZE_V:
|
|
|
|
num = sscanf(value, "%u-%u", &h1, &h2);
|
|
|
|
if (num < 2)
|
|
|
|
goto case_error;
|
|
|
|
wm->height_min = h1;
|
|
|
|
wm->height_max = h2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_TYPE_PROP:
|
|
|
|
num = 0;
|
|
|
|
if (*value == '!')
|
|
|
|
{
|
|
|
|
wm->qual = 1;
|
|
|
|
num = 1;
|
|
|
|
}
|
|
|
|
wm->prop = MatchFind(MatchProp, value + num);
|
|
|
|
if (wm->prop <= 0)
|
|
|
|
goto case_error;
|
|
|
|
break;
|
2005-02-06 11:13:34 -08:00
|
|
|
|
|
|
|
case_error:
|
2023-10-21 02:04:12 -07:00
|
|
|
Eprintf("%s: Error (%s): %s\n", __func__, value, line);
|
|
|
|
err = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
wm->op = MatchFind(MatchOp, op);
|
|
|
|
if (wm->op <= 0)
|
|
|
|
{
|
|
|
|
Eprintf("%s: Error (%s): %s\n", __func__, op, line);
|
|
|
|
err = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (wm->op)
|
|
|
|
{
|
|
|
|
case MATCH_OP_BORDER:
|
|
|
|
wm->border = BorderFind(args);
|
|
|
|
if (!wm->border)
|
|
|
|
{
|
|
|
|
Eprintf("%s: No such border: '%s'\n", __func__, args);
|
|
|
|
err = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_OP_ICON:
|
|
|
|
/* FIXME - Check if exists */
|
|
|
|
wm->args = Estrdup(args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_OP_WINOP:
|
|
|
|
if (WindowMatchEobjOpsParse(NULL, args))
|
|
|
|
{
|
|
|
|
Eprintf("%s: Error (%s): %s\n", __func__, args, line);
|
|
|
|
err = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
wm->args = Estrdup(args);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (err)
|
|
|
|
{
|
|
|
|
if (wm)
|
|
|
|
WindowMatchDestroy(wm);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LIST_APPEND(WindowMatch, &wm_list,
|
|
|
|
LIST_REMOVE(WindowMatch, &wm_list, wm));
|
|
|
|
}
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
static char *
|
|
|
|
WindowMatchEncode(const WindowMatch *wm, char *buf, int len)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
char s[1024];
|
|
|
|
const char *qual, *value, *args;
|
|
|
|
|
|
|
|
qual = " ";
|
|
|
|
|
|
|
|
switch (wm->match)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
value = wm->value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_TYPE_SIZE:
|
|
|
|
value = s;
|
|
|
|
sprintf(s, "%u-%ux%u-%u", wm->width_min, wm->width_max,
|
|
|
|
wm->height_min, wm->height_max);
|
|
|
|
break;
|
|
|
|
case MATCH_TYPE_SIZE_H:
|
|
|
|
value = s;
|
|
|
|
sprintf(s, "%u-%u", wm->width_min, wm->width_max);
|
|
|
|
break;
|
|
|
|
case MATCH_TYPE_SIZE_V:
|
|
|
|
value = s;
|
|
|
|
sprintf(s, "%u-%u", wm->height_min, wm->height_max);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_TYPE_PROP:
|
|
|
|
qual = (wm->qual) ? "!" : " ";
|
|
|
|
value = MatchProp[(int)wm->prop];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (wm->op)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
args = wm->args;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_OP_BORDER:
|
|
|
|
args = BorderGetName(wm->border);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Esnprintf(buf, len, "%-8s %s%-16s %s %s", MatchType[(int)wm->match],
|
|
|
|
qual, value, MatchOp[(int)wm->op], args);
|
|
|
|
|
|
|
|
return buf;
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2006-08-12 03:33:47 -07:00
|
|
|
static int
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchConfigLoad2(FILE *fs)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
char s[FILEPATH_LEN_MAX], *ss;
|
|
|
|
int len;
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
ss = fgets(s, sizeof(s), fs);
|
|
|
|
if (!ss)
|
|
|
|
break;
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
len = strcspn(s, "#\r\n");
|
|
|
|
if (len <= 0)
|
|
|
|
continue;
|
|
|
|
s[len] = '\0';
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchDecode(s);
|
|
|
|
}
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
return 0;
|
2005-02-06 11:13:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchEwinTest(const WindowMatch *wm, const EWin *ewin)
|
2005-02-06 11:13:34 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
int match;
|
|
|
|
|
|
|
|
match = 0;
|
|
|
|
|
|
|
|
switch (wm->match)
|
|
|
|
{
|
|
|
|
case MATCH_TYPE_TITLE:
|
|
|
|
return matchregexp(wm->value, EwinGetIcccmName(ewin));
|
|
|
|
|
|
|
|
case MATCH_TYPE_WM_NAME:
|
|
|
|
return matchregexp(wm->value, EwinGetIcccmCName(ewin));
|
|
|
|
|
|
|
|
case MATCH_TYPE_WM_CLASS:
|
|
|
|
return matchregexp(wm->value, EwinGetIcccmClass(ewin));
|
|
|
|
|
|
|
|
case MATCH_TYPE_SIZE:
|
|
|
|
match = (ewin->client.w >= wm->width_min &&
|
|
|
|
ewin->client.w <= wm->width_max &&
|
|
|
|
ewin->client.h >= wm->height_min &&
|
|
|
|
ewin->client.h <= wm->height_max);
|
|
|
|
break;
|
|
|
|
case MATCH_TYPE_SIZE_H:
|
|
|
|
match = (ewin->client.w >= wm->width_min &&
|
|
|
|
ewin->client.w <= wm->width_max);
|
|
|
|
break;
|
|
|
|
case MATCH_TYPE_SIZE_V:
|
|
|
|
match = (ewin->client.h >= wm->height_min &&
|
|
|
|
ewin->client.h <= wm->height_max);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_TYPE_PROP:
|
|
|
|
switch (wm->prop)
|
|
|
|
{
|
|
|
|
case MATCH_PROP_TRANSIENT:
|
|
|
|
match = EwinIsTransient(ewin);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_PROP_SHAPED:
|
|
|
|
match = ewin->state.shaped;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MATCH_PROP_FIXEDSIZE:
|
|
|
|
match = ewin->props.no_resize_h && ewin->props.no_resize_v;
|
|
|
|
break;
|
|
|
|
case MATCH_PROP_FIXEDSIZE_H:
|
|
|
|
match = ewin->props.no_resize_h;
|
|
|
|
break;
|
|
|
|
case MATCH_PROP_FIXEDSIZE_V:
|
|
|
|
match = ewin->props.no_resize_v;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wm->qual)
|
|
|
|
match = !match;
|
|
|
|
return match;
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2006-11-19 14:24:59 -08:00
|
|
|
#if USE_COMPOSITE
|
|
|
|
static int
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchEobjTest(const WindowMatch *wm, const EObj *eo)
|
2006-11-19 14:24:59 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
int match;
|
2006-11-19 14:24:59 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
match = 0;
|
2006-11-19 14:24:59 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
switch (wm->match)
|
|
|
|
{
|
|
|
|
case MATCH_TYPE_TITLE:
|
|
|
|
return matchregexp(wm->value, EobjGetName(eo));
|
2006-11-26 06:40:05 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
case MATCH_TYPE_WM_NAME:
|
|
|
|
return matchregexp(wm->value, EobjGetCName(eo));
|
2006-11-19 14:24:59 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
case MATCH_TYPE_WM_CLASS:
|
|
|
|
return matchregexp(wm->value, EobjGetClass(eo));
|
|
|
|
}
|
2006-11-19 14:24:59 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
if (wm->qual)
|
|
|
|
match = !match;
|
|
|
|
return match;
|
2006-11-19 14:24:59 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-03-23 04:54:24 -07:00
|
|
|
typedef struct {
|
2023-10-21 02:04:12 -07:00
|
|
|
int type;
|
|
|
|
const EWin *ewin;
|
2006-02-18 00:30:09 -08:00
|
|
|
} wmatch_type_data;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2006-02-18 00:30:09 -08:00
|
|
|
static int
|
|
|
|
WindowMatchTypeMatch(const void *data, const void *match)
|
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
const WindowMatch *wm = (const WindowMatch *)data;
|
|
|
|
const wmatch_type_data *wmtd = (const wmatch_type_data *)match;
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
return !(wm->op == wmtd->type && WindowMatchEwinTest(wm, wmtd->ewin));
|
2006-02-18 00:30:09 -08:00
|
|
|
}
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2006-02-18 00:30:09 -08:00
|
|
|
static WindowMatch *
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchType(const EWin *ewin, int type)
|
2006-02-18 00:30:09 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
wmatch_type_data wmtd;
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
wmtd.type = type;
|
|
|
|
wmtd.ewin = ewin;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
return LIST_FIND(WindowMatch, &wm_list, WindowMatchTypeMatch, &wmtd);
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
Border *
|
|
|
|
WindowMatchEwinBorder(const EWin *ewin)
|
2005-02-06 11:13:34 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatch *wm;
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
wm = WindowMatchType(ewin, MATCH_OP_BORDER);
|
2005-02-06 11:13:34 -08:00
|
|
|
#if 0
|
2023-10-21 02:04:12 -07:00
|
|
|
Eprintf("%s: %s %s\n", __func__, EwinGetTitle(ewin),
|
|
|
|
(wm) ? BorderGetName(wm->border) : "???");
|
2005-02-06 11:13:34 -08:00
|
|
|
#endif
|
2023-10-21 02:04:12 -07:00
|
|
|
if (wm)
|
|
|
|
return wm->border;
|
|
|
|
return NULL;
|
2005-02-06 11:13:34 -08:00
|
|
|
}
|
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
const char *
|
|
|
|
WindowMatchEwinIcon(const EWin *ewin)
|
2005-02-06 11:13:34 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatch *wm;
|
2005-02-06 11:13:34 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
wm = WindowMatchType(ewin, MATCH_OP_ICON);
|
2005-02-06 11:13:34 -08:00
|
|
|
#if 0
|
2023-10-21 02:04:12 -07:00
|
|
|
Eprintf("%s: %s %s\n", __func__, EwinGetTitle(ewin),
|
|
|
|
(wm) ? wm->args : "???");
|
2005-02-06 11:13:34 -08:00
|
|
|
#endif
|
2023-10-21 02:04:12 -07:00
|
|
|
if (wm)
|
|
|
|
return wm->args;
|
|
|
|
return NULL;
|
2005-02-06 11:13:34 -08:00
|
|
|
}
|
|
|
|
|
2005-02-13 14:54:17 -08:00
|
|
|
static int
|
|
|
|
GetBoolean(const char *value)
|
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
/* We set off if "0" or "off", otherwise on */
|
|
|
|
if (!value)
|
|
|
|
return 1;
|
|
|
|
else if (!strcmp(value, "0") || !strcmp(value, "off"))
|
|
|
|
return 0;
|
|
|
|
return 1;
|
2005-02-13 14:54:17 -08:00
|
|
|
}
|
|
|
|
|
2005-11-12 09:51:11 -08:00
|
|
|
#define WINOP_SET_BOOL(item, val) item = GetBoolean(val)
|
2005-02-13 14:54:17 -08:00
|
|
|
|
|
|
|
static void
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchEwinOpsAction(EWin *ewin, int op, const char *args)
|
2005-02-13 14:54:17 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
int a, b;
|
|
|
|
|
|
|
|
/* NB! This must only be used when a new client is being adopted */
|
|
|
|
|
|
|
|
switch (op)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
/* We should not get here */
|
|
|
|
return;
|
|
|
|
|
|
|
|
case EWIN_OP_BORDER:
|
|
|
|
EwinBorderSetInitially(ewin, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_TITLE:
|
|
|
|
EFREE_DUP(EwinGetIcccmName(ewin), args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_ICONIFY:
|
|
|
|
WINOP_SET_BOOL(ewin->icccm.start_iconified, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_SHADE:
|
|
|
|
WINOP_SET_BOOL(ewin->state.shaded, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_STICK:
|
|
|
|
WINOP_SET_BOOL(ewin->o.sticky, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_DESK:
|
|
|
|
EoSetDesk(ewin, DeskGetValid(atoi(args)));
|
|
|
|
break;
|
|
|
|
|
|
|
|
#if 0 /* Causes crash */
|
|
|
|
case EWIN_OP_AREA:
|
|
|
|
a = b = 0;
|
|
|
|
if (sscanf(args, "%u %u", &a, &b) < 2)
|
|
|
|
break;
|
|
|
|
EwinMoveToArea(ewin, a, b); /* FIXME - We should not move here */
|
|
|
|
break;
|
2008-06-05 10:32:50 -07:00
|
|
|
#endif
|
2005-08-27 07:42:58 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
case EWIN_OP_MOVE:
|
|
|
|
a = ewin->client.x;
|
|
|
|
b = ewin->client.y;
|
|
|
|
if (sscanf(args, "%i %i", &a, &b) < 2)
|
|
|
|
break;
|
|
|
|
ewin->client.x = a;
|
|
|
|
ewin->client.y = b;
|
|
|
|
ewin->state.placed = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_SIZE:
|
|
|
|
a = ewin->client.w;
|
|
|
|
b = ewin->client.h;
|
|
|
|
if (sscanf(args, "%u %u", &a, &b) < 2)
|
|
|
|
break;
|
|
|
|
ewin->client.w = a;
|
|
|
|
ewin->client.h = b;
|
|
|
|
ewin->state.maximized_horz = ewin->state.maximized_vert = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_FULLSCREEN:
|
|
|
|
WINOP_SET_BOOL(ewin->state.fullscreen, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_LAYER:
|
|
|
|
EoSetLayer(ewin, atoi(args));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_OPACITY:
|
|
|
|
a = atoi(args);
|
|
|
|
ewin->props.opacity = OpacityFromPercent(OpacityFix(a, 0));
|
|
|
|
ewin->ewmh.opacity_update = 1; /* Set opacity on client window */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_FOCUSED_OPACITY:
|
|
|
|
a = atoi(args);
|
|
|
|
ewin->props.focused_opacity = OpacityFromPercent(OpacityFix(a, 0));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_SKIP_LISTS:
|
|
|
|
WINOP_SET_BOOL(ewin->props.skip_winlist, args);
|
|
|
|
ewin->props.skip_focuslist = ewin->props.skip_ext_task =
|
|
|
|
ewin->props.skip_winlist;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_FOCUS_CLICK:
|
|
|
|
WINOP_SET_BOOL(ewin->props.focusclick, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_NEVER_USE_AREA:
|
|
|
|
WINOP_SET_BOOL(ewin->props.never_use_area, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_NO_BUTTON_GRABS:
|
|
|
|
WINOP_SET_BOOL(ewin->props.no_button_grabs, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_AUTOSHADE:
|
|
|
|
WINOP_SET_BOOL(ewin->props.autoshade, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_INH_APP_FOCUS:
|
|
|
|
WINOP_SET_BOOL(EwinInhGetApp(ewin, focus), args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_INH_APP_MOVE:
|
|
|
|
WINOP_SET_BOOL(EwinInhGetApp(ewin, move), args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_INH_APP_SIZE:
|
|
|
|
WINOP_SET_BOOL(EwinInhGetApp(ewin, size), args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_INH_USER_CLOSE:
|
|
|
|
WINOP_SET_BOOL(EwinInhGetUser(ewin, close), args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_INH_USER_MOVE:
|
|
|
|
WINOP_SET_BOOL(EwinInhGetUser(ewin, move), args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_INH_USER_SIZE:
|
|
|
|
WINOP_SET_BOOL(EwinInhGetUser(ewin, size), args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_INH_WM_FOCUS:
|
|
|
|
WINOP_SET_BOOL(EwinInhGetWM(ewin, focus), args);
|
|
|
|
break;
|
2005-11-12 09:51:11 -08:00
|
|
|
|
|
|
|
#if USE_COMPOSITE
|
2023-10-21 02:04:12 -07:00
|
|
|
case EWIN_OP_FADE:
|
|
|
|
WINOP_SET_BOOL(ewin->o.fade, args);
|
|
|
|
break;
|
2006-10-07 05:02:34 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
case EWIN_OP_SHADOW:
|
|
|
|
WINOP_SET_BOOL(ewin->o.shadow, args);
|
|
|
|
break;
|
2005-11-12 09:51:11 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
case EWIN_OP_NO_REDIRECT:
|
|
|
|
WINOP_SET_BOOL(ewin->o.noredir, args);
|
|
|
|
break;
|
2008-06-05 10:59:51 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
case EWIN_OP_NO_ARGB:
|
|
|
|
WINOP_SET_BOOL(ewin->props.no_argb, args);
|
|
|
|
break;
|
2005-11-12 09:51:11 -08:00
|
|
|
#endif
|
2023-10-21 02:04:12 -07:00
|
|
|
}
|
2005-02-13 14:54:17 -08:00
|
|
|
}
|
|
|
|
|
2006-11-19 14:24:59 -08:00
|
|
|
#if USE_COMPOSITE
|
|
|
|
static void
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchEobjOpsAction(EObj *eo, int op, const char *args)
|
2006-11-19 14:24:59 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
int a;
|
|
|
|
|
|
|
|
switch (op)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
/* We should not get here */
|
|
|
|
return;
|
|
|
|
|
|
|
|
case EWIN_OP_OPACITY:
|
|
|
|
a = atoi(args);
|
|
|
|
eo->opacity = OpacityFromPercent(OpacityFix(a, 100));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_FADE:
|
|
|
|
WINOP_SET_BOOL(eo->fade, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_SHADOW:
|
|
|
|
WINOP_SET_BOOL(eo->shadow, args);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EWIN_OP_NO_REDIRECT:
|
|
|
|
WINOP_SET_BOOL(eo->noredir, args);
|
|
|
|
break;
|
|
|
|
}
|
2006-11-19 14:24:59 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-02-13 14:54:17 -08:00
|
|
|
static int
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchEobjOpsParse(EObj *eo, const char *ops)
|
2005-02-13 14:54:17 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
int err, len;
|
|
|
|
const WinOp *wop;
|
|
|
|
char *ops2, *s, *p, op[32];
|
|
|
|
|
|
|
|
if (!ops)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* Parse ':' separated operations list, e.g. "layer 3:desk 1: shade" */
|
|
|
|
p = ops2 = Estrdup(ops);
|
|
|
|
|
|
|
|
err = 0;
|
|
|
|
for (; p; p = s)
|
|
|
|
{
|
|
|
|
/* Break at ':' */
|
|
|
|
s = strchr(p, ':');
|
|
|
|
if (s)
|
|
|
|
*s++ = '\0';
|
|
|
|
|
|
|
|
len = 0;
|
|
|
|
sscanf(p, "%31s %n", op, &len);
|
|
|
|
if (len <= 0)
|
|
|
|
break;
|
|
|
|
p += len;
|
|
|
|
|
|
|
|
wop = EwinOpFind(op);
|
|
|
|
if (!wop || !wop->ok_match)
|
|
|
|
{
|
|
|
|
err = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If eo is NULL, we are validating the configuration */
|
|
|
|
if (!eo)
|
|
|
|
continue;
|
2006-11-19 14:24:59 -08:00
|
|
|
#if USE_COMPOSITE
|
2023-10-21 02:04:12 -07:00
|
|
|
if (eo->type == EOBJ_TYPE_EWIN)
|
|
|
|
WindowMatchEwinOpsAction((EWin *) eo, wop->op, p);
|
|
|
|
else
|
|
|
|
WindowMatchEobjOpsAction(eo, wop->op, p);
|
2006-11-19 14:24:59 -08:00
|
|
|
#else
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchEwinOpsAction((EWin *) eo, wop->op, p);
|
2006-11-19 14:24:59 -08:00
|
|
|
#endif
|
2023-10-21 02:04:12 -07:00
|
|
|
}
|
2005-02-13 14:54:17 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
Efree(ops2);
|
2005-02-13 14:54:17 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
return err;
|
2005-02-13 14:54:17 -08:00
|
|
|
}
|
|
|
|
|
2008-03-22 23:49:50 -07:00
|
|
|
static void
|
2020-01-23 08:07:46 -08:00
|
|
|
_WindowMatchEwinFunc(const void *_wm, void *_ew)
|
2005-02-13 14:54:17 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
const WindowMatch *wm = (const WindowMatch *)_wm;
|
|
|
|
EWin *ew = (EWin *) _ew;
|
2005-02-13 14:54:17 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
if (wm->op != MATCH_OP_WINOP || !WindowMatchEwinTest(wm, ew))
|
|
|
|
return;
|
2006-11-19 14:24:59 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
/* Match found - do the ops */
|
|
|
|
WindowMatchEobjOpsParse(EoObj(ew), wm->args);
|
2006-11-19 14:24:59 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchEwinOps(EWin *ew)
|
2008-03-22 23:49:50 -07:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
const WindowMatch *wm;
|
2013-06-06 13:37:06 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
LIST_FOR_EACH(WindowMatch, &wm_list, wm) _WindowMatchEwinFunc(wm, ew);
|
2008-03-22 23:49:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#if USE_COMPOSITE
|
|
|
|
static void
|
|
|
|
_WindowMatchEobjFunc(void *_wm, void *_eo)
|
2006-11-19 14:24:59 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
const WindowMatch *wm = (WindowMatch *) _wm;
|
|
|
|
EObj *eo = (EObj *) _eo;
|
2008-03-22 23:49:50 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
if (wm->op != MATCH_OP_WINOP || !WindowMatchEobjTest(wm, eo))
|
|
|
|
return;
|
2006-11-19 14:24:59 -08:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
/* Match found - do the ops */
|
|
|
|
WindowMatchEobjOpsParse(eo, wm->args);
|
2008-03-22 23:49:50 -07:00
|
|
|
}
|
2005-02-13 14:54:17 -08:00
|
|
|
|
2008-03-22 23:49:50 -07:00
|
|
|
void
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatchEobjOps(EObj *eo)
|
2008-03-22 23:49:50 -07:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
WindowMatch *wm;
|
2013-06-06 13:37:06 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
LIST_FOR_EACH(WindowMatch, &wm_list, wm) _WindowMatchEobjFunc(wm, eo);
|
2005-02-13 14:54:17 -08:00
|
|
|
}
|
2006-11-19 14:24:59 -08:00
|
|
|
#endif
|
2005-02-13 14:54:17 -08:00
|
|
|
|
2005-02-06 11:13:34 -08:00
|
|
|
/*
|
|
|
|
* Winmatch module
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
WindowMatchSighan(int sig, void *prm __UNUSED__)
|
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
switch (sig)
|
|
|
|
{
|
|
|
|
case ESIGNAL_CONFIGURE:
|
|
|
|
#if 0 /* Done as part of theme loading */
|
|
|
|
ConfigFileLoad("windowmatches.cfg", Mode.theme.path,
|
|
|
|
WindowMatchConfigLoad, 1);
|
2005-02-06 11:13:34 -08:00
|
|
|
#endif
|
2023-10-21 02:04:12 -07:00
|
|
|
ConfigFileLoad("matches.cfg", NULL, WindowMatchConfigLoad2, 0);
|
|
|
|
break;
|
|
|
|
}
|
2005-02-06 11:13:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-05-18 01:25:06 -07:00
|
|
|
WindowMatchIpc(const char *params)
|
2005-02-06 11:13:34 -08:00
|
|
|
{
|
2023-10-21 02:04:12 -07:00
|
|
|
const char *p;
|
|
|
|
char cmd[128], prm[4096], buf[4096];
|
|
|
|
int len;
|
|
|
|
|
|
|
|
cmd[0] = prm[0] = '\0';
|
|
|
|
p = params;
|
|
|
|
if (p)
|
|
|
|
{
|
|
|
|
len = 0;
|
|
|
|
sscanf(p, "%100s %4000s %n", cmd, prm, &len);
|
|
|
|
p += len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!p || cmd[0] == '?')
|
|
|
|
{
|
|
|
|
}
|
|
|
|
else if (!strncmp(cmd, "list", 2))
|
|
|
|
{
|
|
|
|
WindowMatch *wm;
|
|
|
|
|
|
|
|
LIST_FOR_EACH(WindowMatch, &wm_list, wm)
|
|
|
|
IpcPrintf("%s\n", WindowMatchEncode(wm, buf, sizeof(buf)));
|
|
|
|
}
|
2005-02-06 11:13:34 -08:00
|
|
|
}
|
|
|
|
|
2005-10-30 11:40:49 -08:00
|
|
|
static const IpcItem WindowMatchIpcArray[] = {
|
2023-10-21 02:04:12 -07:00
|
|
|
{
|
|
|
|
WindowMatchIpc,
|
|
|
|
"wmatch", "wma",
|
|
|
|
"Window match functions",
|
|
|
|
" wmatch list List window matches\n" }
|
|
|
|
,
|
2005-02-06 11:13:34 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Module descriptor
|
|
|
|
*/
|
2007-01-16 17:10:44 -08:00
|
|
|
extern const EModule ModWindowMatch;
|
2010-08-08 12:03:34 -07:00
|
|
|
|
2023-10-21 02:04:12 -07:00
|
|
|
const EModule ModWindowMatch = {
|
|
|
|
"winmatch", NULL,
|
|
|
|
WindowMatchSighan,
|
|
|
|
MOD_ITEMS(WindowMatchIpcArray),
|
|
|
|
{ 0, NULL }
|
2005-02-06 11:13:34 -08:00
|
|
|
};
|