diff options
author | Dennis Kasprzyk <onestone@opencompositing.org> | 2008-08-14 13:56:14 +0200 |
---|---|---|
committer | Dennis kasprzyk <onestone@opencompositing.org> | 2008-08-14 13:56:14 +0200 |
commit | fa7e9361989282eddfc3012ffc392fadebf2b3c5 (patch) | |
tree | 9f9d6926eae7c793e4b9e878da65406e872b754a | |
parent | c9b8f6dff3c7457f5e05802335327200fa169110 (diff) | |
download | zcomp-fa7e9361989282eddfc3012ffc392fadebf2b3c5.tar.gz zcomp-fa7e9361989282eddfc3012ffc392fadebf2b3c5.tar.bz2 |
Implementation of CompMatch as C++ class.
-rw-r--r-- | include/compdisplay.h | 6 | ||||
-rw-r--r-- | include/compiz-core.h | 106 | ||||
-rw-r--r-- | include/compmatch.h | 52 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/display.cpp | 8 | ||||
-rw-r--r-- | src/match.cpp | 926 | ||||
-rw-r--r-- | src/metadata.cpp | 6 | ||||
-rw-r--r-- | src/option.cpp | 22 | ||||
-rw-r--r-- | src/privatematch.h | 57 | ||||
-rw-r--r-- | src/window.cpp | 4 |
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) |