summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/compdisplay.h6
-rw-r--r--include/compiz-core.h106
-rw-r--r--include/compmatch.h52
-rw-r--r--src/Makefile.am2
-rw-r--r--src/display.cpp8
-rw-r--r--src/match.cpp926
-rw-r--r--src/metadata.cpp6
-rw-r--r--src/option.cpp22
-rw-r--r--src/privatematch.h57
-rw-r--r--src/window.cpp4
10 files changed, 562 insertions, 627 deletions
diff --git a/include/compdisplay.h b/include/compdisplay.h
index 7add2e5..11820af 100644
--- a/include/compdisplay.h
+++ b/include/compdisplay.h
@@ -2,6 +2,8 @@
#define _COMPDISPLAY_H
#include <list>
+
+#include <compmatch.h>
#include "wrapable.h"
class CompDisplay;
@@ -25,7 +27,7 @@ class DisplayInterface : public WrapableInterface<CompDisplay> {
const char *, int, int, int, void *);
- WRAPABLE_DEF(void, matchInitExp, CompMatchExp *, const char *);
+ WRAPABLE_DEF(CompMatch::Expression *, matchInitExp, const CompString);
WRAPABLE_DEF(void, matchExpHandlerChanged)
WRAPABLE_DEF(void, matchPropertyChanged, CompWindow *)
@@ -366,7 +368,7 @@ class CompDisplay : public WrapableHandler<DisplayInterface>, public CompObject
const char *, int, int, int, void *)
- WRAPABLE_HND(void, matchInitExp, CompMatchExp *, const char *);
+ WRAPABLE_HND(CompMatch::Expression *, matchInitExp, const CompString);
WRAPABLE_HND(void, matchExpHandlerChanged)
WRAPABLE_HND(void, matchPropertyChanged, CompWindow *)
diff --git a/include/compiz-core.h b/include/compiz-core.h
index b3dd1c6..d80b4a7 100644
--- a/include/compiz-core.h
+++ b/include/compiz-core.h
@@ -86,7 +86,7 @@ typedef struct _CompProgram CompProgram;
typedef struct _CompFunction CompFunction;
typedef struct _CompFunctionData CompFunctionData;
typedef struct _FragmentAttrib FragmentAttrib;
-typedef struct _CompMatch CompMatch;
+class CompMatch;
class CompOutput;
typedef struct _CompWalker CompWalker;
@@ -274,13 +274,7 @@ struct _CompAction {
CompPrivate priv;
};
-typedef union _CompMatchOp CompMatchOp;
-struct _CompMatch {
- CompDisplay *display;
- CompMatchOp *op;
- int nOp;
-};
typedef struct {
CompOptionType type;
@@ -295,7 +289,7 @@ union _CompOptionValue {
char *s;
unsigned short c[4];
CompAction action;
- CompMatch match;
+ CompMatch *match;
CompListValue list;
};
@@ -429,52 +423,7 @@ isActionOption (CompOption *option);
typedef void (*ForEachWindowProc) (CompWindow *window,
void *closure);
-#define MATCH_OP_AND_MASK (1 << 0)
-#define MATCH_OP_NOT_MASK (1 << 1)
-typedef enum {
- CompMatchOpTypeGroup,
- CompMatchOpTypeExp
-} CompMatchOpType;
-
-typedef struct _CompMatchAnyOp {
- CompMatchOpType type;
- int flags;
-} CompMatchAnyOp;
-
-typedef struct _CompMatchGroupOp {
- CompMatchOpType type;
- int flags;
- CompMatchOp *op;
- int nOp;
-} CompMatchGroupOp;
-
-typedef void (*CompMatchExpFiniProc) (CompDisplay *display,
- CompPrivate priv);
-
-typedef Bool (*CompMatchExpEvalProc) (CompDisplay *display,
- CompWindow *window,
- CompPrivate priv);
-
-typedef struct _CompMatchExp {
- CompMatchExpFiniProc fini;
- CompMatchExpEvalProc eval;
- CompPrivate priv;
-} CompMatchExp;
-
-typedef struct _CompMatchExpOp {
- CompMatchOpType type;
- int flags;
- char *value;
- CompMatchExp e;
-} CompMatchExpOp;
-
-union _CompMatchOp {
- CompMatchOpType type;
- CompMatchAnyOp any;
- CompMatchGroupOp group;
- CompMatchExpOp exp;
-};
bool
@@ -896,57 +845,6 @@ matrixGetIdentity (CompTransform *m);
/* match.c */
-void
-matchInit (CompMatch *match);
-
-void
-matchFini (CompMatch *match);
-
-Bool
-matchEqual (CompMatch *m1,
- CompMatch *m2);
-
-Bool
-matchCopy (CompMatch *dst,
- CompMatch *src);
-
-Bool
-matchAddGroup (CompMatch *match,
- int flags,
- CompMatch *group);
-
-Bool
-matchAddExp (CompMatch *match,
- int flags,
- const char *value);
-
-void
-matchAddFromString (CompMatch *match,
- const char *str);
-
-char *
-matchToString (CompMatch *match);
-
-void
-matchUpdate (CompDisplay *display,
- CompMatch *match);
-
-Bool
-matchEval (CompMatch *match,
- CompWindow *window);
-
-void
-matchInitExp (CompDisplay *display,
- CompMatchExp *exp,
- const char *value);
-
-void
-matchExpHandlerChanged (CompDisplay *display);
-
-void
-matchPropertyChanged (CompDisplay *display,
- CompWindow *window);
-
/* metadata.c */
diff --git a/include/compmatch.h b/include/compmatch.h
new file mode 100644
index 0000000..8582b2e
--- /dev/null
+++ b/include/compmatch.h
@@ -0,0 +1,52 @@
+#ifndef _COMPMATCH_H
+#define _COMPMATCH_H
+
+#include <compiz-core.h>
+
+class PrivateMatch;
+class CompWindow;
+class CompDisplay;
+
+class CompMatch {
+ public:
+
+ class Expression {
+ public:
+ virtual bool evaluate (CompWindow *window) = 0;
+ };
+
+ public:
+ CompMatch ();
+ CompMatch (const CompString);
+ CompMatch (const CompMatch &);
+ ~CompMatch ();
+
+ void update (CompDisplay *display);
+ bool evaluate (CompWindow *window);
+
+ CompString toString ();
+
+ CompDisplay *display ();
+
+ CompMatch & operator= (const CompMatch &);
+ CompMatch & operator&= (const CompMatch &);
+ CompMatch & operator|= (const CompMatch &);
+
+ const CompMatch & operator& (const CompMatch &);
+ const CompMatch & operator| (const CompMatch &);
+ const CompMatch & operator! ();
+
+ CompMatch & operator= (const CompString &);
+ CompMatch & operator&= (const CompString &);
+ CompMatch & operator|= (const CompString &);
+
+ const CompMatch & operator& (const CompString &);
+ const CompMatch & operator| (const CompString &);
+
+ bool operator== (const CompMatch &);
+
+ private:
+ PrivateMatch *priv;
+};
+
+#endif \ No newline at end of file
diff --git a/src/Makefile.am b/src/Makefile.am
index 04c8493..e13cadd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,6 +12,7 @@ bin_PROGRAMS = compiz
compiz_LDADD = @COMPIZ_LIBS@ @GL_LIBS@ -lm
compiz_LDFLAGS = -export-dynamic
compiz_SOURCES = \
+ match.cpp \
main.cpp \
object.cpp \
core.cpp \
@@ -26,7 +27,6 @@ compiz_SOURCES = \
session.cpp \
fragment.cpp \
matrix.cpp \
- match.cpp \
metadata.cpp \
output.cpp \
rect.cpp \
diff --git a/src/display.cpp b/src/display.cpp
index f8f4d3b..0b0901f 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -45,7 +45,7 @@
#include <boost/bind.hpp>
-#include <compiz-core.h>
+
#include "privatedisplay.h"
#include "privatescreen.h"
#include "privatewindow.h"
@@ -2587,9 +2587,9 @@ DisplayInterface::imageToFile (const char *path,
WRAPABLE_DEF_FUNC_RETURN(imageToFile, path, name, format, width, height,
stride, data)
-void
-DisplayInterface::matchInitExp (CompMatchExp *exp, const char *value)
- WRAPABLE_DEF_FUNC(matchInitExp, exp, value)
+CompMatch::Expression *
+DisplayInterface::matchInitExp (const CompString value)
+ WRAPABLE_DEF_FUNC_RETURN(matchInitExp, value)
void
DisplayInterface::matchExpHandlerChanged ()
diff --git a/src/match.cpp b/src/match.cpp
index e8697df..c58265f 100644
--- a/src/match.cpp
+++ b/src/match.cpp
@@ -26,288 +26,226 @@
#include <stdlib.h>
#include <string.h>
+#include <boost/foreach.hpp>
+#define foreach BOOST_FOREACH
+
#include <compiz-core.h>
#include "privatedisplay.h"
-static void
-matchResetOps (CompDisplay *display,
- CompMatchOp *op,
- int nOp)
-{
- while (nOp--)
- {
- switch (op->type) {
- case CompMatchOpTypeGroup:
- matchResetOps (display, op->group.op, op->group.nOp);
- break;
- case CompMatchOpTypeExp:
- if (op->exp.e.fini)
+#include <compmatch.h>
+#include "privatematch.h"
+
+class CoreExp : public CompMatch::Expression {
+ public:
+ typedef enum {
+ TypeXid,
+ TypeState,
+ TypeOverride,
+ TypeType
+ } Type;
+
+ CoreExp (CompString str)
+ {
+ if (str.compare (0, 4, "xid=") == 0)
+ {
+ mType = TypeXid;
+ priv.val = strtol (str.substr (4).c_str (), NULL, 0);
+ }
+ else if (str.compare (0, 6, "state=") == 0)
+ {
+ mType = TypeState;
+ priv.uval = CompDisplay::windowStateFromString
+ (str.substr (6).c_str ());
+ }
+ else if (str.compare (0, 18, "override_redirect=") == 0)
{
- (*op->exp.e.fini) (display, op->exp.e.priv);
- op->exp.e.fini = NULL;
+ mType = TypeOverride;
+ priv.val = strtol (str.substr (18).c_str (), NULL, 0);
}
+ else
+ {
+ if (str.compare (0, 5, "type=") == 0)
+ str = str.substr (5);
- op->exp.e.eval = NULL;
- op->exp.e.priv.val = 0;
- break;
+ mType = TypeType;
+ priv.uval = CompWindow::windowTypeFromString (str.c_str ());
+ }
}
- op++;
- }
-}
+ bool evaluate (CompWindow *w)
+ {
-static void
-matchReset (CompMatch *match)
-{
- if (match->display)
- matchResetOps (match->display, match->op, match->nOp);
+ switch (mType)
+ {
+
+ case TypeXid:
+ return ((unsigned int) priv.val == w->id ());
+ case TypeState:
+ return (priv.uval & w->state ());
+ case TypeOverride:
+ {
+ bool overrideRedirect = w->attrib ().override_redirect;
+ return ((priv.val == 1 && overrideRedirect) ||
+ (priv.val == 0 && !overrideRedirect));
+ }
+ case TypeType:
+ return (priv.uval & w->wmType ());
+ }
+ return true;
+ }
- match->display = NULL;
-}
+ Type mType;
+ CompPrivate priv;
+};
-void
-matchInit (CompMatch *match)
+CompMatch::Expression *
+CompDisplay::matchInitExp (const CompString str)
{
- match->display = NULL;
- match->op = NULL;
- match->nOp = 0;
+ WRAPABLE_HND_FUNC_RETURN(CompMatch::Expression *, matchInitExp, str)
+
+ return new CoreExp (str);
}
static void
-matchFiniOps (CompMatchOp *op,
- int nOp)
+matchUpdateMatchOptions (CompOption *option,
+ int nOption)
{
- while (nOp--)
+ while (nOption--)
{
- switch (op->type) {
- case CompMatchOpTypeGroup:
- matchFiniOps (op->group.op, op->group.nOp);
- free (op->group.op);
+ switch (option->type) {
+ case CompOptionTypeMatch:
+ if (option->value.match && option->value.match->display ())
+ option->value.match->update (option->value.match->display ());
break;
- case CompMatchOpTypeExp:
- free (op->exp.value);
+ case CompOptionTypeList:
+ if (option->value.list.type == CompOptionTypeMatch)
+ {
+ int i;
+
+ for (i = 0; i < option->value.list.nValue; i++)
+ if (option->value.list.value[i].match &&
+ option->value.list.value[i].match->display ())
+ option->value.list.value[i].match->update
+ (option->value.list.value[i].match->display ());
+ }
+ default:
break;
}
- op++;
+ option++;
}
}
void
-matchFini (CompMatch *match)
-{
- matchReset (match);
- matchFiniOps (match->op, match->nOp);
- free (match->op);
-}
-
-static Bool
-matchOpsEqual (CompMatchOp *op1,
- CompMatchOp *op2,
- int nOp)
+CompDisplay::matchExpHandlerChanged ()
{
- while (nOp--)
- {
- if (op1->type != op2->type)
- return FALSE;
-
- switch (op1->type) {
- case CompMatchOpTypeGroup:
- if (op1->group.nOp != op2->group.nOp)
- return FALSE;
-
- if (!matchOpsEqual (op1->group.op, op2->group.op, op1->group.nOp))
- return FALSE;
+ WRAPABLE_HND_FUNC(matchExpHandlerChanged)
- break;
- case CompMatchOpTypeExp:
- if (op1->exp.flags != op2->exp.flags)
- return FALSE;
+ CompOption *option;
+ int nOption;
+ CompPlugin *p;
+ CompScreen *s;
- if (strcmp (op1->exp.value, op2->exp.value))
- return FALSE;
+ for (p = getPlugins (); p; p = p->next)
+ {
+ option = p->vTable->getObjectOptions (this, &nOption);
+ matchUpdateMatchOptions (option, nOption);
+ }
- break;
+ for (s = priv->screens; s; s = s->next)
+ {
+ for (p = getPlugins (); p; p = p->next)
+ {
+ option = p->vTable->getObjectOptions (s, &nOption);
+ matchUpdateMatchOptions (option, nOption);
}
-
- op1++;
- op2++;
}
-
- return TRUE;
}
-Bool
-matchEqual (CompMatch *m1,
- CompMatch *m2)
+void
+CompDisplay::matchPropertyChanged (CompWindow *w)
{
- if (m1->nOp != m2->nOp)
- return FALSE;
-
- return matchOpsEqual (m1->op, m2->op, m1->nOp);
+ WRAPABLE_HND_FUNC(matchPropertyChanged, w)
}
-static CompMatchOp *
-matchAddOp (CompMatch *match,
- CompMatchOpType type,
- int flags)
-{
- CompMatchOp *op;
-
- /* remove AND prefix if this is the first op in this group */
- if (!match->nOp)
- flags &= ~MATCH_OP_AND_MASK;
-
- op = (CompMatchOp *) realloc (match->op, sizeof (CompMatchOp) * (match->nOp + 1));
- if (!op)
- return FALSE;
- op[match->nOp].any.type = type;
- op[match->nOp].any.flags = flags;
- match->op = op;
- match->nOp++;
-
- return &match->op[match->nOp - 1];
-}
-
-static Bool
-matchCopyOps (CompMatchOp *opDst,
- CompMatchOp *opSrc,
- int nOpSrc)
+static void
+matchResetOps (MatchOp::List &list)
{
- CompMatchOp *op, *first = opDst;
- int count = 0;
-
- while (nOpSrc--)
+ MatchExpOp *exp;
+ foreach (MatchOp &op, list)
{
- opDst->any.type = opSrc->any.type;
- opDst->any.flags = opSrc->any.flags;
-
- switch (opSrc->type) {
- case CompMatchOpTypeGroup:
- op = (CompMatchOp *) malloc (sizeof (CompMatchOp) * opSrc->group.nOp);
- if (!op)
- {
- matchFiniOps (first, count);
- return FALSE;
- }
-
- if (!matchCopyOps (op, opSrc->group.op, opSrc->group.nOp))
- {
- free (op);
- matchFiniOps (first, count);
- return FALSE;
- }
-
- opDst->group.op = op;
- opDst->group.nOp = opSrc->group.nOp;
- break;
- case CompMatchOpTypeExp:
- opDst->exp.value = strdup (opSrc->exp.value);
- if (!opDst->exp.value)
- {
- matchFiniOps (first, count);
- return FALSE;
- }
+ switch (op.type ()) {
+ case MatchOp::TypeGroup:
+ matchResetOps (dynamic_cast <MatchGroupOp &> (op).op);
+ break;
+ case MatchOp::TypeExp:
+ exp = dynamic_cast <MatchExpOp *> (&op);
+ if (exp && exp->e)
+ {
- opDst->exp.e.fini = NULL;
- opDst->exp.e.eval = NULL;
- opDst->exp.e.priv.val = 0;
- break;
+ exp->e.reset ();
+ }
+ break;
+ default:
+ break;
}
-
- count++;
- opDst++;
- opSrc++;
}
-
- return TRUE;
}
-Bool
-matchCopy (CompMatch *dst,
- CompMatch *src)
+static bool
+matchOpsEqual (MatchOp::List &list1,
+ MatchOp::List &list2)
{
- CompMatchOp *opDst;
+ MatchOp::List::iterator it1 = list1.begin (), it2 = list2.begin ();
- opDst = (CompMatchOp *) malloc (sizeof (CompMatchOp) * src->nOp);
- if (!opDst)
- return FALSE;
+ MatchGroupOp *g1, *g2;
+ MatchExpOp *e1, *e2;
+
+ if (list1.size () != list2.size ())
+ return false;
- if (!matchCopyOps (opDst, src->op, src->nOp))
+ while (it1 != list1.end ())
{
- free (opDst);
- return FALSE;
- }
-
- dst->op = opDst;
- dst->nOp = src->nOp;
+ if ((*it1).type () != (*it2).type ())
+ return false;
- return TRUE;
-}
+ if ((*it1).flags != (*it2).flags)
+ return false;
-Bool
-matchAddGroup (CompMatch *match,
- int flags,
- CompMatch *group)
-{
- CompMatchOp *op, *opDst;
+ switch ((*it1).type ()) {
+ case MatchOp::TypeGroup:
+ g1 = dynamic_cast<MatchGroupOp *> (&(*it1));
+ g2 = dynamic_cast<MatchGroupOp *> (&(*it2));
- opDst = (CompMatchOp *) malloc (sizeof (CompMatchOp) * group->nOp);
- if (!opDst)
- return FALSE;
+ if (!matchOpsEqual (g1->op, g2->op))
+ return false;
- if (!matchCopyOps (opDst, group->op, group->nOp))
- {
- free (opDst);
- return FALSE;
- }
-
- op = matchAddOp (match, CompMatchOpTypeGroup, flags);
- if (!op)
- {
- matchFiniOps (opDst, group->nOp);
- free (opDst);
- return FALSE;
- }
-
- op->group.op = opDst;
- op->group.nOp = group->nOp;
-
- return TRUE;
-}
+ break;
+ case MatchOp::TypeExp:
+ e1 = dynamic_cast<MatchExpOp *> (&(*it1));
+ e2 = dynamic_cast<MatchExpOp *> (&(*it2));
-Bool
-matchAddExp (CompMatch *match,
- int flags,
- const char *str)
-{
- CompMatchOp *op;
- char *value;
+ if (e1->value != e2->value)
+ return false;
- value = strdup (str);
- if (!value)
- return FALSE;
+ break;
+ default:
+ break;
+ }
- op = matchAddOp (match, CompMatchOpTypeExp, flags);
- if (!op)
- {
- free (value);
- return FALSE;
+ it1++;
+ it2++;
}
- op->exp.value = value;
- op->exp.e.fini = NULL;
- op->exp.e.eval = NULL;
- op->exp.e.priv.val = 0;
-
- return TRUE;
+ return true;
}
-static int
-nextIndex (const char *str,
- int i)
+
+static unsigned int
+nextIndex (CompString &str,
+ unsigned int i)
{
while (str[i] == '\\')
if (str[++i] != '\0')
@@ -316,55 +254,48 @@ nextIndex (const char *str,
return i;
}
-static char *
-strndupValue (const char *str,
- int n)
+
+static CompString
+strndupValue (CompString str)
{
- char *value;
+ CompString value;
- value = (char *) malloc (sizeof (char) * (n + 1));
- if (value)
- {
- int i, j;
+ unsigned int i, j, n = str.length ();
- /* count trialing white spaces */
- i = j = 0;
- while (i < n)
+ /* count trialing white spaces */
+ i = j = 0;
+ while (i < n)
+ {
+ if (str[i] != ' ')
{
- if (str[i] != ' ')
- {
- j = 0;
- if (str[i] == '\\')
- i++;
- }
- else
- {
- j++;
- }
-
- i++;
+ j = 0;
+ if (str[i] == '\\')
+ i++;
+ }
+ else
+ {
+ j++;
}
- /* remove trialing white spaces */
- n -= j;
+ i++;
+ }
- i = j = 0;
- for (;;)
- {
- if (str[i] == '\\')
- i++;
+ /* remove trialing white spaces */
+ n -= j;
- value[j++] = str[i++];
+ i = j = 0;
+ for (;;)
+ {
+ if (str[i] == '\\')
+ i++;
- if (i >= n)
- {
- value[j] = '\0';
- return value;
- }
+ value += str[i++];
+
+ if (i >= n)
+ {
+ return value;
}
}
-
- return NULL;
}
/*
@@ -376,14 +307,17 @@ strndupValue (const char *str,
"type=desktop | !type=dock"
"!type=dock & (state=fullscreen | state=shaded)"
*/
-void
-matchAddFromString (CompMatch *match,
- const char *str)
+
+static void
+matchAddFromString (MatchOp::List &list,
+ CompString str)
{
- char *value;
+ CompString value;
int j, i = 0;
int flags = 0;
+ str += "\0";
+
while (str[i] != '\0')
{
while (str[i] == ' ')
@@ -423,21 +357,10 @@ matchAddFromString (CompMatch *match,
length = j - i;
- value = (char *) malloc (sizeof (char) * (length + 1));
- if (value)
- {
- CompMatch group;
-
- strncpy (value, &str[i], length);
- value[length] = '\0';
-
- matchInit (&group);
- matchAddFromString (&group, value);
- matchAddGroup (match, flags, &group);
- matchFini (&group);
-
- free (value);
- }
+ MatchGroupOp group;
+ matchAddFromString (group.op, str.substr (i, length));
+ group.flags = flags;
+ list.push_back (group);
while (str[j] != '\0' && str[j] != '|' && str[j] != '&')
j++;
@@ -449,12 +372,12 @@ matchAddFromString (CompMatch *match,
while (str[j] != '\0' && str[j] != '|' && str[j] != '&')
j = nextIndex (str, ++j);
- value = strndupValue (&str[i], j - i);
- if (value)
+ if (j > i)
{
- matchAddExp (match, flags, value);
-
- free (value);
+ MatchExpOp exp;
+ exp.value = strndupValue (str.substr(i, j - i));
+ exp.flags = flags;
+ list.push_back (exp);
}
}
@@ -468,299 +391,302 @@ matchAddFromString (CompMatch *match,
i++;
}
}
+
+ if (list.size ())
+ list.front ().flags &= ~MATCH_OP_AND_MASK;
+
}
-static char *
-matchOpsToString (CompMatchOp *op,
- int nOp)
+static CompString
+matchOpsToString (MatchOp::List &list)
{
- char *value, *group;
- char *str = NULL;
- int length = 0;
+ CompString value (""), group;
- while (nOp--)
+ foreach (MatchOp &op, list)
{
- value = NULL;
-
- switch (op->type) {
- case CompMatchOpTypeGroup:
- group = matchOpsToString (op->group.op, op->group.nOp);
- if (group)
- {
- value = (char *) malloc (sizeof (char) * (strlen (group) + 7));
- if (value)
- sprintf (value, "%s%s(%s)%s", !str ? "" :
- ((op->any.flags & MATCH_OP_AND_MASK) ?
- "& " : "| "),
- (op->any.flags & MATCH_OP_NOT_MASK) ? "!" : "",
- group, nOp ? " " : "");
-
- free (group);
- }
- break;
- case CompMatchOpTypeExp:
- value = (char *) malloc (sizeof (char) * (strlen (op->exp.value) + 5));
- if (value)
- sprintf (value, "%s%s%s%s", !str ? "" :
- ((op->any.flags & MATCH_OP_AND_MASK) ? "& " : "| "),
- (op->any.flags & MATCH_OP_NOT_MASK) ? "!" : "",
- op->exp.value, nOp ? " " : "");
- break;
- }
-
- if (value)
- {
- char *s;
- int valueLength = strlen (value);
-
- s = (char *) malloc (sizeof (char) * (length + valueLength + 1));
- if (s)
- {
- if (str)
- memcpy (s, str, sizeof (char) * length);
-
- memcpy (s + length, value, sizeof (char) * valueLength);
-
- length += valueLength;
-
- s[length] = '\0';
-
- if (str)
- free (str);
-
- str = s;
- }
+ switch (op.type ()) {
+ case MatchOp::TypeGroup:
+ group = matchOpsToString (dynamic_cast <MatchGroupOp &> (op).op);
+ if (group.length ())
+ {
+ if (value.length ())
+ {
+ value += ((op.flags & MATCH_OP_AND_MASK) ?
+ "& " : "| ");
+ }
+ if (op.flags & MATCH_OP_NOT_MASK)
+ value += "!";
+ value += "(" + group + ") ";
+ }
+ break;
+ case MatchOp::TypeExp:
- free (value);
+ if (value.length ())
+ {
+ value += ((op.flags & MATCH_OP_AND_MASK) ?
+ "& " : "| ");
+ }
+ if (op.flags & MATCH_OP_NOT_MASK)
+ value += "!";
+ value += dynamic_cast <MatchExpOp &> (op).value;
+ break;
+ default:
+ break;
}
-
- op++;
}
- return str;
-}
-
-char *
-matchToString (CompMatch *match)
-{
- char *str;
-
- str = matchOpsToString (match->op, match->nOp);
- if (!str)
- str = strdup ("");
+ value.erase (value.length () - 1);
- return str;
+ return value;
}
static void
-matchUpdateOps (CompDisplay *display,
- CompMatchOp *op,
- int nOp)
+matchUpdateOps (CompDisplay *display,
+ MatchOp::List &list)
{
- while (nOp--)
+ MatchExpOp *exp;
+ foreach (MatchOp &op, list)
{
- switch (op->type) {
- case CompMatchOpTypeGroup:
- matchUpdateOps (display, op->group.op, op->group.nOp);
- break;
- case CompMatchOpTypeExp:
- display->matchInitExp (&op->exp.e, op->exp.value);
- break;
+ switch (op.type ()) {
+ case MatchOp::TypeGroup:
+ matchUpdateOps (display, dynamic_cast <MatchGroupOp &> (op).op);
+ break;
+ case MatchOp::TypeExp:
+ exp = dynamic_cast <MatchExpOp *> (&op);
+ if (exp)
+ exp->e.reset (display->matchInitExp (exp->value));
+ break;
+ default:
+ break;
}
-
- op++;
}
}
-void
-matchUpdate (CompDisplay *display,
- CompMatch *match)
+static bool
+matchEvalOps (MatchOp::List &list,
+ CompWindow *w)
{
- matchReset (match);
- matchUpdateOps (display, match->op, match->nOp);
- match->display = display;
-}
+ bool value, result = false;
+ MatchExpOp *exp;
-static Bool
-matchEvalOps (CompDisplay *display,
- CompMatchOp *op,
- int nOp,
- CompWindow *window)
-{
- Bool value, result = FALSE;
-
- while (nOp--)
+ foreach (MatchOp &op, list)
{
/* fast evaluation */
- if (op->any.flags & MATCH_OP_AND_MASK)
+ if (op.flags & MATCH_OP_AND_MASK)
{
/* result will never be true */
if (!result)
- return FALSE;
+ return false;
}
else
{
/* result will always be true */
if (result)
- return TRUE;
+ return true;
}
- switch (op->type) {
- case CompMatchOpTypeGroup:
- value = matchEvalOps (display, op->group.op, op->group.nOp, window);
- break;
- case CompMatchOpTypeExp:
- default:
- value = (*op->exp.e.eval) (display, window, op->exp.e.priv);
- break;
+ switch (op.type ()) {
+ case MatchOp::TypeGroup:
+ value = matchEvalOps (dynamic_cast <MatchGroupOp &> (op).op, w);
+ break;
+ case MatchOp::TypeExp:
+ exp = dynamic_cast <MatchExpOp *> (&op);
+ if (exp->e.get ())
+ value = exp->e->evaluate (w);
+ else
+ value = true;
+ break;
+ default:
+ value = true;
+ break;
}
- if (op->any.flags & MATCH_OP_NOT_MASK)
+ if (op.flags & MATCH_OP_NOT_MASK)
value = !value;
- if (op->any.flags & MATCH_OP_AND_MASK)
+ if (op.flags & MATCH_OP_AND_MASK)
result = (result && value);
else
result = (result || value);
-
- op++;
}
return result;
}
-Bool
-matchEval (CompMatch *match,
- CompWindow *window)
+MatchOp::MatchOp () :
+ flags (0)
{
- if (match->display)
- return matchEvalOps (match->display, match->op, match->nOp, window);
+}
- return FALSE;
+MatchOp::~MatchOp ()
+{
}
-static Bool
-matchEvalTypeExp (CompDisplay *display,
- CompWindow *window,
- CompPrivate c_private)
+MatchExpOp::MatchExpOp () :
+ value (""),
+ e ()
{
- return (c_private.uval & window->wmType ());
}
-static Bool
-matchEvalStateExp (CompDisplay *display,
- CompWindow *window,
- CompPrivate c_private)
+MatchGroupOp::MatchGroupOp () :
+ op (0)
{
- return (c_private.uval & window->state ());
}
-static Bool
-matchEvalIdExp (CompDisplay *display,
- CompWindow *window,
- CompPrivate c_private)
+PrivateMatch::PrivateMatch () :
+ op (),
+ display (NULL)
{
- return (c_private.val == window->id ());
}
-static Bool
-matchEvalOverrideRedirectExp (CompDisplay *display,
- CompWindow *window,
- CompPrivate c_private)
+
+CompMatch::CompMatch () :
+ priv (new PrivateMatch ())
{
- Bool overrideRedirect = window->attrib ().override_redirect;
- return ((c_private.val == 1 && overrideRedirect) ||
- (c_private.val == 0 && !overrideRedirect));
+}
+
+CompMatch::CompMatch (const CompString str) :
+ priv (new PrivateMatch ())
+{
+ matchAddFromString (priv->op.op, str);
+}
+
+CompMatch::CompMatch (const CompMatch &match) :
+ priv (new PrivateMatch ())
+{
+ priv->op = match.priv->op;
+}
+
+
+CompMatch::~CompMatch ()
+{
+ delete priv;
}
void
-CompDisplay::matchInitExp (CompMatchExp *exp, const char *value)
+CompMatch::update (CompDisplay *display)
{
- WRAPABLE_HND_FUNC(matchInitExp, exp, value)
+ matchResetOps (priv->op.op);
+ matchUpdateOps (display, priv->op.op);
+ priv->display = display;
+}
+
+bool
+CompMatch::evaluate (CompWindow *window)
+{
+ return matchEvalOps (priv->op.op, window);
+}
- if (strncmp (value, "xid=", 4) == 0)
- {
- exp->eval = matchEvalIdExp;
- exp->priv.val = strtol (value + 4, NULL, 0);
- }
- else if (strncmp (value, "state=", 6) == 0)
- {
- exp->eval = matchEvalStateExp;
- exp->priv.uval = windowStateFromString (value + 6);
- }
- else if (strncmp (value, "override_redirect=", 18) == 0)
- {
- exp->eval = matchEvalOverrideRedirectExp;
- exp->priv.val = strtol (value + 18, NULL, 0);
- }
- else
- {
- if (strncmp (value, "type=", 5) == 0)
- value += 5;
+CompString
+CompMatch::toString ()
+{
+ return matchOpsToString (priv->op.op);
+}
- exp->eval = matchEvalTypeExp;
- exp->priv.uval = CompWindow::windowTypeFromString (value);
- }
+CompDisplay *
+CompMatch::display ()
+{
+ return priv->display;
}
-static void
-matchUpdateMatchOptions (CompOption *option,
- int nOption)
+CompMatch &
+CompMatch::operator= (const CompMatch &match)
{
- while (nOption--)
- {
- switch (option->type) {
- case CompOptionTypeMatch:
- if (option->value.match.display)
- matchUpdate (option->value.match.display, &option->value.match);
- break;
- case CompOptionTypeList:
- if (option->value.list.type == CompOptionTypeMatch)
- {
- int i;
+ priv->op = match.priv->op;
+ priv->display = match.priv->display;
+ return *this;
+}
- for (i = 0; i < option->value.list.nValue; i++)
- if (option->value.list.value[i].match.display)
- matchUpdate (option->value.list.value[i].match.display,
- &option->value.list.value[i].match);
- }
- default:
- break;
- }
+CompMatch &
+CompMatch::operator&= (const CompMatch &match)
+{
+ MatchGroupOp g1;
+ MatchGroupOp g2;
- option++;
- }
+ g1.op = priv->op.op;
+ g2.op = match.priv->op.op;
+ g2.flags = MATCH_OP_AND_MASK;
+
+ priv->op.op.clear ();
+ priv->op.op.push_back (g1);
+ priv->op.op.push_back (g2);
+
+ return *this;
}
-void
-CompDisplay::matchExpHandlerChanged ()
+CompMatch &
+CompMatch::operator|= (const CompMatch &match)
{
- WRAPABLE_HND_FUNC(matchExpHandlerChanged)
+ MatchGroupOp g1;
+ MatchGroupOp g2;
- CompOption *option;
- int nOption;
- CompPlugin *p;
- CompScreen *s;
- CompWindow *w;
+ g1.op = priv->op.op;
+ g2.op = match.priv->op.op;
- for (p = getPlugins (); p; p = p->next)
- {
- option = p->vTable->getObjectOptions (this, &nOption);
- matchUpdateMatchOptions (option, nOption);
- }
+ priv->op.op.clear ();
+ priv->op.op.push_back (g1);
+ priv->op.op.push_back (g2);
- for (s = priv->screens; s; s = s->next)
- {
- for (p = getPlugins (); p; p = p->next)
- {
- option = p->vTable->getObjectOptions (s, &nOption);
- matchUpdateMatchOptions (option, nOption);
- }
- }
+ return *this;
}
-void
-CompDisplay::matchPropertyChanged (CompWindow *w)
+const CompMatch &
+CompMatch::operator& (const CompMatch &match)
{
- WRAPABLE_HND_FUNC(matchPropertyChanged, w)
+ return CompMatch (*this) &= match;
+}
+
+const CompMatch &
+CompMatch::operator| (const CompMatch &match)
+{
+ return CompMatch (*this) |= match;
+}
+
+const CompMatch &
+CompMatch::operator! ()
+{
+ MatchGroupOp g;
+ g.op = priv->op.op;
+ g.flags ^= MATCH_OP_NOT_MASK;
+ priv->op.op.clear ();
+ priv->op.op.push_back (g);
+ return *this;
+}
+
+CompMatch &
+CompMatch::operator= (const CompString &str)
+{
+ priv->op.op.clear ();
+ matchAddFromString (priv->op.op, str);
+ return *this;
+}
+
+CompMatch &
+CompMatch::operator&= (const CompString &str)
+{
+ return CompMatch (*this) &= CompMatch (str);
+}
+
+CompMatch &
+CompMatch::operator|= (const CompString &str)
+{
+ return CompMatch (*this) |= CompMatch (str);
+}
+
+const CompMatch &
+CompMatch::operator& (const CompString &str)
+{
+ return CompMatch(*this) &= str;
+}
+
+const CompMatch &
+CompMatch::operator| (const CompString &str)
+{
+ return CompMatch(*this) |= str;
+}
+
+bool
+CompMatch::operator== (const CompMatch &match)
+{
+ matchOpsEqual (priv->op.op, match.priv->op.op);
}
diff --git a/src/metadata.cpp b/src/metadata.cpp
index 88bdce6..51b69d2 100644
--- a/src/metadata.cpp
+++ b/src/metadata.cpp
@@ -715,7 +715,7 @@ initMatchValue (CompDisplay *d,
{
xmlChar *value;
- matchInit (&v->match);
+ v->match = new CompMatch ();
if (!doc)
return;
@@ -723,12 +723,12 @@ initMatchValue (CompDisplay *d,
value = xmlNodeListGetString (doc, node->xmlChildrenNode, 1);
if (value)
{
- matchAddFromString (&v->match, (char *) value);
+ *v->match = (char *) value;
xmlFree (value);
}
if (!helper)
- matchUpdate (d, &v->match);
+ v->match->update (d);
}
static void
diff --git a/src/option.cpp b/src/option.cpp
index e7b46ef..87bbb3c 100644
--- a/src/option.cpp
+++ b/src/option.cpp
@@ -83,7 +83,8 @@ compFiniOptionValue (CompOptionValue *v,
free (v->s);
break;
case CompOptionTypeMatch:
- matchFini (&v->match);
+ delete (v->match);
+ v->match = NULL;
break;
case CompOptionTypeList:
for (i = 0; i < v->list.nValue; i++)
@@ -292,22 +293,20 @@ Bool
compSetMatchOption (CompOption *option,
CompOptionValue *value)
{
- CompDisplay *display = option->value.match.display;
+ CompDisplay *display = option->value.match->display ();
CompMatch match;
- if (matchEqual (&option->value.match, &value->match))
+ if (*option->value.match == *value->match)
return FALSE;
- if (!matchCopy (&match, &value->match))
- return FALSE;
+ match = *value->match;
- matchFini (&option->value.match);
+ delete option->value.match;
- option->value.match.op = match.op;
- option->value.match.nOp = match.nOp;
+ option->value.match = new CompMatch (*value->match);
if (display)
- matchUpdate (display, &option->value.match);
+ option->value.match->update (display);
return TRUE;
}
@@ -338,7 +337,8 @@ compSetOptionList (CompOption *option,
free (option->value.list.value[i].s);
break;
case CompOptionTypeMatch:
- matchFini (&option->value.list.value[i].match);
+ delete option->value.list.value[i].match;
+ option->value.list.value[i].match = NULL;
default:
break;
}
@@ -524,7 +524,7 @@ getMatchOptionNamed (CompOption *option,
{
if (option->type == CompOptionTypeMatch)
if (strcmp (option->name, name) == 0)
- return &option->value.match;
+ return option->value.match;
option++;
}
diff --git a/src/privatematch.h b/src/privatematch.h
new file mode 100644
index 0000000..764bec4
--- /dev/null
+++ b/src/privatematch.h
@@ -0,0 +1,57 @@
+#ifndef _PRIVATEMATCH_H
+#define _PRIVATEMATCH_H
+
+#include <compmatch.h>
+#include <boost/shared_ptr.hpp>
+
+#define MATCH_OP_AND_MASK (1 << 0)
+#define MATCH_OP_NOT_MASK (1 << 1)
+
+class MatchOp {
+ public:
+ typedef enum {
+ TypeNone,
+ TypeGroup,
+ TypeExp
+ } Type;
+
+ typedef std::list<MatchOp> List;
+
+ MatchOp ();
+ virtual ~MatchOp ();
+
+ virtual Type type () { return TypeNone; };
+
+ unsigned int flags;
+};
+
+class MatchExpOp : public MatchOp {
+ public:
+ MatchExpOp ();
+
+ MatchOp::Type type () { return MatchOp::TypeExp; };
+
+ CompString value;
+
+ boost::shared_ptr<CompMatch::Expression> e;
+};
+
+class MatchGroupOp : public MatchOp {
+ public:
+ MatchGroupOp ();
+
+ MatchOp::Type type () { return MatchOp::TypeGroup; };
+
+ MatchOp::List op;
+};
+
+class PrivateMatch {
+ public:
+ PrivateMatch ();
+
+ public:
+ MatchGroupOp op;
+ CompDisplay *display;
+};
+
+#endif
diff --git a/src/window.cpp b/src/window.cpp
index d0cbadb..3c1d656 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -3768,8 +3768,8 @@ PrivateWindow::isWindowFocusAllowed (Time timestamp)
}
/* allow focus for excluded windows */
- match = &s->getOption ("focus_prevention_match")->value.match;
- if (!matchEval (match, window))
+ match = s->getOption ("focus_prevention_match")->value.match;
+ if (!match->evaluate (window))
return true;
if (level == FOCUS_PREVENTION_LEVEL_VERYHIGH)