c2.h cleanup
Move most of the static functions into c2.c itself, and only keep the public functions in c2.h
This commit is contained in:
parent
e875f7566f
commit
4940a93f03
343
src/c2.c
343
src/c2.c
|
@ -8,8 +8,351 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
// libpcre
|
||||||
|
#ifdef CONFIG_REGEX_PCRE
|
||||||
|
#include <pcre.h>
|
||||||
|
|
||||||
|
// For compatiblity with <libpcre-8.20
|
||||||
|
#ifndef PCRE_STUDY_JIT_COMPILE
|
||||||
|
#define PCRE_STUDY_JIT_COMPILE 0
|
||||||
|
#define LPCRE_FREE_STUDY(extra) pcre_free(extra)
|
||||||
|
#else
|
||||||
|
#define LPCRE_FREE_STUDY(extra) pcre_free_study(extra)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "c2.h"
|
#include "c2.h"
|
||||||
|
|
||||||
|
#define C2_MAX_LEVELS 10
|
||||||
|
|
||||||
|
typedef struct _c2_b c2_b_t;
|
||||||
|
typedef struct _c2_l c2_l_t;
|
||||||
|
|
||||||
|
/// Pointer to a condition tree.
|
||||||
|
typedef struct {
|
||||||
|
bool isbranch : 1;
|
||||||
|
union {
|
||||||
|
c2_b_t *b;
|
||||||
|
c2_l_t *l;
|
||||||
|
};
|
||||||
|
} c2_ptr_t;
|
||||||
|
|
||||||
|
/// Initializer for c2_ptr_t.
|
||||||
|
#define C2_PTR_INIT { \
|
||||||
|
.isbranch = false, \
|
||||||
|
.l = NULL, \
|
||||||
|
}
|
||||||
|
|
||||||
|
const static c2_ptr_t C2_PTR_NULL = C2_PTR_INIT;
|
||||||
|
|
||||||
|
/// Operator of a branch element.
|
||||||
|
typedef enum {
|
||||||
|
C2_B_OUNDEFINED,
|
||||||
|
C2_B_OAND,
|
||||||
|
C2_B_OOR,
|
||||||
|
C2_B_OXOR,
|
||||||
|
} c2_b_op_t;
|
||||||
|
|
||||||
|
/// Structure for branch element in a window condition
|
||||||
|
struct _c2_b {
|
||||||
|
bool neg : 1;
|
||||||
|
c2_b_op_t op;
|
||||||
|
c2_ptr_t opr1;
|
||||||
|
c2_ptr_t opr2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Initializer for c2_b_t.
|
||||||
|
#define C2_B_INIT { \
|
||||||
|
.neg = false, \
|
||||||
|
.op = C2_B_OUNDEFINED, \
|
||||||
|
.opr1 = C2_PTR_INIT, \
|
||||||
|
.opr2 = C2_PTR_INIT, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Structure for leaf element in a window condition
|
||||||
|
struct _c2_l {
|
||||||
|
bool neg : 1;
|
||||||
|
enum {
|
||||||
|
C2_L_OEXISTS,
|
||||||
|
C2_L_OEQ,
|
||||||
|
C2_L_OGT,
|
||||||
|
C2_L_OGTEQ,
|
||||||
|
C2_L_OLT,
|
||||||
|
C2_L_OLTEQ,
|
||||||
|
} op : 3;
|
||||||
|
enum {
|
||||||
|
C2_L_MEXACT,
|
||||||
|
C2_L_MSTART,
|
||||||
|
C2_L_MCONTAINS,
|
||||||
|
C2_L_MWILDCARD,
|
||||||
|
C2_L_MPCRE,
|
||||||
|
} match : 3;
|
||||||
|
bool match_ignorecase : 1;
|
||||||
|
char *tgt;
|
||||||
|
Atom tgtatom;
|
||||||
|
bool tgt_onframe;
|
||||||
|
int index;
|
||||||
|
enum {
|
||||||
|
C2_L_PUNDEFINED,
|
||||||
|
C2_L_PID,
|
||||||
|
C2_L_PX,
|
||||||
|
C2_L_PY,
|
||||||
|
C2_L_PX2,
|
||||||
|
C2_L_PY2,
|
||||||
|
C2_L_PWIDTH,
|
||||||
|
C2_L_PHEIGHT,
|
||||||
|
C2_L_PWIDTHB,
|
||||||
|
C2_L_PHEIGHTB,
|
||||||
|
C2_L_PBDW,
|
||||||
|
C2_L_PFULLSCREEN,
|
||||||
|
C2_L_POVREDIR,
|
||||||
|
C2_L_PARGB,
|
||||||
|
C2_L_PFOCUSED,
|
||||||
|
C2_L_PWMWIN,
|
||||||
|
C2_L_PBSHAPED,
|
||||||
|
C2_L_PROUNDED,
|
||||||
|
C2_L_PCLIENT,
|
||||||
|
C2_L_PWINDOWTYPE,
|
||||||
|
C2_L_PLEADER,
|
||||||
|
C2_L_PNAME,
|
||||||
|
C2_L_PCLASSG,
|
||||||
|
C2_L_PCLASSI,
|
||||||
|
C2_L_PROLE,
|
||||||
|
} predef;
|
||||||
|
enum c2_l_type {
|
||||||
|
C2_L_TUNDEFINED,
|
||||||
|
C2_L_TSTRING,
|
||||||
|
C2_L_TCARDINAL,
|
||||||
|
C2_L_TWINDOW,
|
||||||
|
C2_L_TATOM,
|
||||||
|
C2_L_TDRAWABLE,
|
||||||
|
} type;
|
||||||
|
int format;
|
||||||
|
enum {
|
||||||
|
C2_L_PTUNDEFINED,
|
||||||
|
C2_L_PTSTRING,
|
||||||
|
C2_L_PTINT,
|
||||||
|
} ptntype;
|
||||||
|
char *ptnstr;
|
||||||
|
long ptnint;
|
||||||
|
#ifdef CONFIG_REGEX_PCRE
|
||||||
|
pcre *regex_pcre;
|
||||||
|
pcre_extra *regex_pcre_extra;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Initializer for c2_l_t.
|
||||||
|
#define C2_L_INIT { \
|
||||||
|
.neg = false, \
|
||||||
|
.op = C2_L_OEXISTS, \
|
||||||
|
.match = C2_L_MEXACT, \
|
||||||
|
.match_ignorecase = false, \
|
||||||
|
.tgt = NULL, \
|
||||||
|
.tgtatom = 0, \
|
||||||
|
.tgt_onframe = false, \
|
||||||
|
.predef = C2_L_PUNDEFINED, \
|
||||||
|
.index = -1, \
|
||||||
|
.type = C2_L_TUNDEFINED, \
|
||||||
|
.format = 0, \
|
||||||
|
.ptntype = C2_L_PTUNDEFINED, \
|
||||||
|
.ptnstr = NULL, \
|
||||||
|
.ptnint = 0, \
|
||||||
|
}
|
||||||
|
|
||||||
|
const static c2_l_t leaf_def = C2_L_INIT;
|
||||||
|
|
||||||
|
/// Linked list type of conditions.
|
||||||
|
struct _c2_lptr {
|
||||||
|
c2_ptr_t ptr;
|
||||||
|
void *data;
|
||||||
|
struct _c2_lptr *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Initializer for c2_lptr_t.
|
||||||
|
#define C2_LPTR_INIT { \
|
||||||
|
.ptr = C2_PTR_INIT, \
|
||||||
|
.data = NULL, \
|
||||||
|
.next = NULL, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Structure representing a predefined target.
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
enum c2_l_type type;
|
||||||
|
int format;
|
||||||
|
} c2_predef_t;
|
||||||
|
|
||||||
|
// Predefined targets.
|
||||||
|
const static c2_predef_t C2_PREDEFS[] = {
|
||||||
|
[C2_L_PID ] = { "id" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PX ] = { "x" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PY ] = { "y" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PX2 ] = { "x2" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PY2 ] = { "y2" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PWIDTH ] = { "width" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PHEIGHT ] = { "height" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PWIDTHB ] = { "widthb" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PHEIGHTB ] = { "heightb" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PBDW ] = { "border_width" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PFULLSCREEN ] = { "fullscreen" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_POVREDIR ] = { "override_redirect" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PARGB ] = { "argb" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PFOCUSED ] = { "focused" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PWMWIN ] = { "wmwin" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PBSHAPED ] = { "bounding_shaped" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PROUNDED ] = { "rounded_corners" , C2_L_TCARDINAL , 0 },
|
||||||
|
[C2_L_PCLIENT ] = { "client" , C2_L_TWINDOW , 0 },
|
||||||
|
[C2_L_PWINDOWTYPE ] = { "window_type" , C2_L_TSTRING , 0 },
|
||||||
|
[C2_L_PLEADER ] = { "leader" , C2_L_TWINDOW , 0 },
|
||||||
|
[C2_L_PNAME ] = { "name" , C2_L_TSTRING , 0 },
|
||||||
|
[C2_L_PCLASSG ] = { "class_g" , C2_L_TSTRING , 0 },
|
||||||
|
[C2_L_PCLASSI ] = { "class_i" , C2_L_TSTRING , 0 },
|
||||||
|
[C2_L_PROLE ] = { "role" , C2_L_TSTRING , 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define mstrncmp(s1, s2) strncmp((s1), (s2), strlen(s1))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare next word in a string with another string.
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
strcmp_wd(const char *needle, const char *src) {
|
||||||
|
int ret = mstrncmp(needle, src);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
char c = src[strlen(needle)];
|
||||||
|
if (isalnum(c) || '_' == c)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether a c2_ptr_t is empty.
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
c2_ptr_isempty(const c2_ptr_t p) {
|
||||||
|
return !(p.isbranch ? (bool) p.b: (bool) p.l);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset a c2_ptr_t.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
c2_ptr_reset(c2_ptr_t *pp) {
|
||||||
|
if (pp)
|
||||||
|
memcpy(pp, &C2_PTR_NULL, sizeof(c2_ptr_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combine two condition trees.
|
||||||
|
*/
|
||||||
|
static inline c2_ptr_t
|
||||||
|
c2h_comb_tree(c2_b_op_t op, c2_ptr_t p1, c2_ptr_t p2) {
|
||||||
|
c2_ptr_t p = {
|
||||||
|
.isbranch = true,
|
||||||
|
.b = malloc(sizeof(c2_b_t))
|
||||||
|
};
|
||||||
|
|
||||||
|
p.b->opr1 = p1;
|
||||||
|
p.b->opr2 = p2;
|
||||||
|
p.b->op = op;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the precedence value of a condition branch operator.
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
c2h_b_opp(c2_b_op_t op) {
|
||||||
|
switch (op) {
|
||||||
|
case C2_B_OAND: return 2;
|
||||||
|
case C2_B_OOR: return 1;
|
||||||
|
case C2_B_OXOR: return 1;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare precedence of two condition branch operators.
|
||||||
|
*
|
||||||
|
* Associativity is left-to-right, forever.
|
||||||
|
*
|
||||||
|
* @return positive number if op1 > op2, 0 if op1 == op2 in precedence,
|
||||||
|
* negative number otherwise
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
c2h_b_opcmp(c2_b_op_t op1, c2_b_op_t op2) {
|
||||||
|
return c2h_b_opp(op1) - c2h_b_opp(op2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult, int level);
|
||||||
|
|
||||||
|
static int
|
||||||
|
c2_parse_target(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||||
|
|
||||||
|
static int
|
||||||
|
c2_parse_op(const char *pattern, int offset, c2_ptr_t *presult);
|
||||||
|
|
||||||
|
static int
|
||||||
|
c2_parse_pattern(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||||
|
|
||||||
|
static int
|
||||||
|
c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
c2_l_postprocess(session_t *ps, c2_l_t *pleaf);
|
||||||
|
|
||||||
|
static void
|
||||||
|
c2_free(c2_ptr_t p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper of c2_free().
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
c2_freep(c2_ptr_t *pp) {
|
||||||
|
if (pp) {
|
||||||
|
c2_free(*pp);
|
||||||
|
c2_ptr_reset(pp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
c2h_dump_str_tgt(const c2_l_t *pleaf);
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
c2h_dump_str_type(const c2_l_t *pleaf);
|
||||||
|
|
||||||
|
static void
|
||||||
|
c2_dump_raw(c2_ptr_t p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper of c2_dump_raw().
|
||||||
|
*/
|
||||||
|
static inline void __attribute__((unused))
|
||||||
|
c2_dump(c2_ptr_t p) {
|
||||||
|
c2_dump_raw(p);
|
||||||
|
printf("\n");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Atom
|
||||||
|
c2_get_atom_type(const c2_l_t *pleaf);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
c2_match_once(session_t *ps, win *w, const c2_ptr_t cond);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a condition string.
|
* Parse a condition string.
|
||||||
*/
|
*/
|
||||||
|
|
353
src/c2.h
353
src/c2.h
|
@ -8,347 +8,26 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#pragma once
|
||||||
|
|
||||||
#include <fnmatch.h>
|
#include <stdbool.h>
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
// libpcre
|
typedef struct _c2_lptr c2_lptr_t;
|
||||||
#ifdef CONFIG_REGEX_PCRE
|
typedef struct session session_t;
|
||||||
#include <pcre.h>
|
typedef struct win win;
|
||||||
|
|
||||||
// For compatiblity with <libpcre-8.20
|
c2_lptr_t *
|
||||||
#ifndef PCRE_STUDY_JIT_COMPILE
|
c2_parsed(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
||||||
#define PCRE_STUDY_JIT_COMPILE 0
|
void *data);
|
||||||
#define LPCRE_FREE_STUDY(extra) pcre_free(extra)
|
|
||||||
#else
|
|
||||||
#define LPCRE_FREE_STUDY(extra) pcre_free_study(extra)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#define c2_parse(ps, pcondlst, pattern) c2_parsed((ps), (pcondlst), (pattern), NULL)
|
||||||
|
|
||||||
#define C2_MAX_LEVELS 10
|
c2_lptr_t *
|
||||||
|
c2_free_lptr(c2_lptr_t *lp);
|
||||||
|
|
||||||
typedef struct _c2_b c2_b_t;
|
bool
|
||||||
typedef struct _c2_l c2_l_t;
|
c2_matchd(session_t *ps, win *w, const c2_lptr_t *condlst,
|
||||||
|
const c2_lptr_t **cache, void **pdata);
|
||||||
/// Pointer to a condition tree.
|
|
||||||
typedef struct {
|
|
||||||
bool isbranch : 1;
|
|
||||||
union {
|
|
||||||
c2_b_t *b;
|
|
||||||
c2_l_t *l;
|
|
||||||
};
|
|
||||||
} c2_ptr_t;
|
|
||||||
|
|
||||||
/// Initializer for c2_ptr_t.
|
|
||||||
#define C2_PTR_INIT { \
|
|
||||||
.isbranch = false, \
|
|
||||||
.l = NULL, \
|
|
||||||
}
|
|
||||||
|
|
||||||
const static c2_ptr_t C2_PTR_NULL = C2_PTR_INIT;
|
|
||||||
|
|
||||||
/// Operator of a branch element.
|
|
||||||
typedef enum {
|
|
||||||
C2_B_OUNDEFINED,
|
|
||||||
C2_B_OAND,
|
|
||||||
C2_B_OOR,
|
|
||||||
C2_B_OXOR,
|
|
||||||
} c2_b_op_t;
|
|
||||||
|
|
||||||
/// Structure for branch element in a window condition
|
|
||||||
struct _c2_b {
|
|
||||||
bool neg : 1;
|
|
||||||
c2_b_op_t op;
|
|
||||||
c2_ptr_t opr1;
|
|
||||||
c2_ptr_t opr2;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Initializer for c2_b_t.
|
|
||||||
#define C2_B_INIT { \
|
|
||||||
.neg = false, \
|
|
||||||
.op = C2_B_OUNDEFINED, \
|
|
||||||
.opr1 = C2_PTR_INIT, \
|
|
||||||
.opr2 = C2_PTR_INIT, \
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Structure for leaf element in a window condition
|
|
||||||
struct _c2_l {
|
|
||||||
bool neg : 1;
|
|
||||||
enum {
|
|
||||||
C2_L_OEXISTS,
|
|
||||||
C2_L_OEQ,
|
|
||||||
C2_L_OGT,
|
|
||||||
C2_L_OGTEQ,
|
|
||||||
C2_L_OLT,
|
|
||||||
C2_L_OLTEQ,
|
|
||||||
} op : 3;
|
|
||||||
enum {
|
|
||||||
C2_L_MEXACT,
|
|
||||||
C2_L_MSTART,
|
|
||||||
C2_L_MCONTAINS,
|
|
||||||
C2_L_MWILDCARD,
|
|
||||||
C2_L_MPCRE,
|
|
||||||
} match : 3;
|
|
||||||
bool match_ignorecase : 1;
|
|
||||||
char *tgt;
|
|
||||||
Atom tgtatom;
|
|
||||||
bool tgt_onframe;
|
|
||||||
int index;
|
|
||||||
enum {
|
|
||||||
C2_L_PUNDEFINED,
|
|
||||||
C2_L_PID,
|
|
||||||
C2_L_PX,
|
|
||||||
C2_L_PY,
|
|
||||||
C2_L_PX2,
|
|
||||||
C2_L_PY2,
|
|
||||||
C2_L_PWIDTH,
|
|
||||||
C2_L_PHEIGHT,
|
|
||||||
C2_L_PWIDTHB,
|
|
||||||
C2_L_PHEIGHTB,
|
|
||||||
C2_L_PBDW,
|
|
||||||
C2_L_PFULLSCREEN,
|
|
||||||
C2_L_POVREDIR,
|
|
||||||
C2_L_PARGB,
|
|
||||||
C2_L_PFOCUSED,
|
|
||||||
C2_L_PWMWIN,
|
|
||||||
C2_L_PBSHAPED,
|
|
||||||
C2_L_PROUNDED,
|
|
||||||
C2_L_PCLIENT,
|
|
||||||
C2_L_PWINDOWTYPE,
|
|
||||||
C2_L_PLEADER,
|
|
||||||
C2_L_PNAME,
|
|
||||||
C2_L_PCLASSG,
|
|
||||||
C2_L_PCLASSI,
|
|
||||||
C2_L_PROLE,
|
|
||||||
} predef;
|
|
||||||
enum c2_l_type {
|
|
||||||
C2_L_TUNDEFINED,
|
|
||||||
C2_L_TSTRING,
|
|
||||||
C2_L_TCARDINAL,
|
|
||||||
C2_L_TWINDOW,
|
|
||||||
C2_L_TATOM,
|
|
||||||
C2_L_TDRAWABLE,
|
|
||||||
} type;
|
|
||||||
int format;
|
|
||||||
enum {
|
|
||||||
C2_L_PTUNDEFINED,
|
|
||||||
C2_L_PTSTRING,
|
|
||||||
C2_L_PTINT,
|
|
||||||
} ptntype;
|
|
||||||
char *ptnstr;
|
|
||||||
long ptnint;
|
|
||||||
#ifdef CONFIG_REGEX_PCRE
|
|
||||||
pcre *regex_pcre;
|
|
||||||
pcre_extra *regex_pcre_extra;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Initializer for c2_l_t.
|
|
||||||
#define C2_L_INIT { \
|
|
||||||
.neg = false, \
|
|
||||||
.op = C2_L_OEXISTS, \
|
|
||||||
.match = C2_L_MEXACT, \
|
|
||||||
.match_ignorecase = false, \
|
|
||||||
.tgt = NULL, \
|
|
||||||
.tgtatom = 0, \
|
|
||||||
.tgt_onframe = false, \
|
|
||||||
.predef = C2_L_PUNDEFINED, \
|
|
||||||
.index = -1, \
|
|
||||||
.type = C2_L_TUNDEFINED, \
|
|
||||||
.format = 0, \
|
|
||||||
.ptntype = C2_L_PTUNDEFINED, \
|
|
||||||
.ptnstr = NULL, \
|
|
||||||
.ptnint = 0, \
|
|
||||||
}
|
|
||||||
|
|
||||||
const static c2_l_t leaf_def = C2_L_INIT;
|
|
||||||
|
|
||||||
/// Linked list type of conditions.
|
|
||||||
struct _c2_lptr {
|
|
||||||
c2_ptr_t ptr;
|
|
||||||
void *data;
|
|
||||||
struct _c2_lptr *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Initializer for c2_lptr_t.
|
|
||||||
#define C2_LPTR_INIT { \
|
|
||||||
.ptr = C2_PTR_INIT, \
|
|
||||||
.data = NULL, \
|
|
||||||
.next = NULL, \
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Structure representing a predefined target.
|
|
||||||
typedef struct {
|
|
||||||
const char *name;
|
|
||||||
enum c2_l_type type;
|
|
||||||
int format;
|
|
||||||
} c2_predef_t;
|
|
||||||
|
|
||||||
// Predefined targets.
|
|
||||||
const static c2_predef_t C2_PREDEFS[] = {
|
|
||||||
[C2_L_PID ] = { "id" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PX ] = { "x" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PY ] = { "y" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PX2 ] = { "x2" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PY2 ] = { "y2" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PWIDTH ] = { "width" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PHEIGHT ] = { "height" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PWIDTHB ] = { "widthb" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PHEIGHTB ] = { "heightb" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PBDW ] = { "border_width" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PFULLSCREEN ] = { "fullscreen" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_POVREDIR ] = { "override_redirect" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PARGB ] = { "argb" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PFOCUSED ] = { "focused" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PWMWIN ] = { "wmwin" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PBSHAPED ] = { "bounding_shaped" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PROUNDED ] = { "rounded_corners" , C2_L_TCARDINAL , 0 },
|
|
||||||
[C2_L_PCLIENT ] = { "client" , C2_L_TWINDOW , 0 },
|
|
||||||
[C2_L_PWINDOWTYPE ] = { "window_type" , C2_L_TSTRING , 0 },
|
|
||||||
[C2_L_PLEADER ] = { "leader" , C2_L_TWINDOW , 0 },
|
|
||||||
[C2_L_PNAME ] = { "name" , C2_L_TSTRING , 0 },
|
|
||||||
[C2_L_PCLASSG ] = { "class_g" , C2_L_TSTRING , 0 },
|
|
||||||
[C2_L_PCLASSI ] = { "class_i" , C2_L_TSTRING , 0 },
|
|
||||||
[C2_L_PROLE ] = { "role" , C2_L_TSTRING , 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
#define mstrncmp(s1, s2) strncmp((s1), (s2), strlen(s1))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare next word in a string with another string.
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
strcmp_wd(const char *needle, const char *src) {
|
|
||||||
int ret = mstrncmp(needle, src);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
char c = src[strlen(needle)];
|
|
||||||
if (isalnum(c) || '_' == c)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether a c2_ptr_t is empty.
|
|
||||||
*/
|
|
||||||
static inline bool
|
|
||||||
c2_ptr_isempty(const c2_ptr_t p) {
|
|
||||||
return !(p.isbranch ? (bool) p.b: (bool) p.l);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset a c2_ptr_t.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
c2_ptr_reset(c2_ptr_t *pp) {
|
|
||||||
if (pp)
|
|
||||||
memcpy(pp, &C2_PTR_NULL, sizeof(c2_ptr_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combine two condition trees.
|
|
||||||
*/
|
|
||||||
static inline c2_ptr_t
|
|
||||||
c2h_comb_tree(c2_b_op_t op, c2_ptr_t p1, c2_ptr_t p2) {
|
|
||||||
c2_ptr_t p = {
|
|
||||||
.isbranch = true,
|
|
||||||
.b = malloc(sizeof(c2_b_t))
|
|
||||||
};
|
|
||||||
|
|
||||||
p.b->opr1 = p1;
|
|
||||||
p.b->opr2 = p2;
|
|
||||||
p.b->op = op;
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the precedence value of a condition branch operator.
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
c2h_b_opp(c2_b_op_t op) {
|
|
||||||
switch (op) {
|
|
||||||
case C2_B_OAND: return 2;
|
|
||||||
case C2_B_OOR: return 1;
|
|
||||||
case C2_B_OXOR: return 1;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare precedence of two condition branch operators.
|
|
||||||
*
|
|
||||||
* Associativity is left-to-right, forever.
|
|
||||||
*
|
|
||||||
* @return positive number if op1 > op2, 0 if op1 == op2 in precedence,
|
|
||||||
* negative number otherwise
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
c2h_b_opcmp(c2_b_op_t op1, c2_b_op_t op2) {
|
|
||||||
return c2h_b_opp(op1) - c2h_b_opp(op2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult, int level);
|
|
||||||
|
|
||||||
static int
|
|
||||||
c2_parse_target(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
|
||||||
|
|
||||||
static int
|
|
||||||
c2_parse_op(const char *pattern, int offset, c2_ptr_t *presult);
|
|
||||||
|
|
||||||
static int
|
|
||||||
c2_parse_pattern(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
|
||||||
|
|
||||||
static int
|
|
||||||
c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
|
||||||
|
|
||||||
static bool
|
|
||||||
c2_l_postprocess(session_t *ps, c2_l_t *pleaf);
|
|
||||||
|
|
||||||
static void
|
|
||||||
c2_free(c2_ptr_t p);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper of c2_free().
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
c2_freep(c2_ptr_t *pp) {
|
|
||||||
if (pp) {
|
|
||||||
c2_free(*pp);
|
|
||||||
c2_ptr_reset(pp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
c2h_dump_str_tgt(const c2_l_t *pleaf);
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
c2h_dump_str_type(const c2_l_t *pleaf);
|
|
||||||
|
|
||||||
static void
|
|
||||||
c2_dump_raw(c2_ptr_t p);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper of c2_dump_raw().
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
c2_dump(c2_ptr_t p) {
|
|
||||||
c2_dump_raw(p);
|
|
||||||
printf("\n");
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Atom
|
|
||||||
c2_get_atom_type(const c2_l_t *pleaf);
|
|
||||||
|
|
||||||
static bool
|
|
||||||
c2_match_once(session_t *ps, win *w, const c2_ptr_t cond);
|
|
||||||
|
|
||||||
|
#define c2_match(ps, w, condlst, cache) c2_matchd((ps), (w), (condlst), \
|
||||||
|
(cache), NULL)
|
||||||
|
|
47
src/common.h
47
src/common.h
|
@ -227,6 +227,7 @@
|
||||||
|
|
||||||
typedef uint32_t opacity_t;
|
typedef uint32_t opacity_t;
|
||||||
typedef long time_ms_t;
|
typedef long time_ms_t;
|
||||||
|
typedef struct _c2_lptr c2_lptr_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WINTYPE_UNKNOWN,
|
WINTYPE_UNKNOWN,
|
||||||
|
@ -519,9 +520,7 @@ typedef struct {
|
||||||
|
|
||||||
struct _timeout_t;
|
struct _timeout_t;
|
||||||
|
|
||||||
struct _win;
|
typedef struct win win;
|
||||||
|
|
||||||
typedef struct _c2_lptr c2_lptr_t;
|
|
||||||
|
|
||||||
/// Structure representing all options.
|
/// Structure representing all options.
|
||||||
typedef struct _options_t {
|
typedef struct _options_t {
|
||||||
|
@ -787,7 +786,7 @@ typedef struct {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Structure containing all necessary data for a compton session.
|
/// Structure containing all necessary data for a compton session.
|
||||||
typedef struct _session_t {
|
typedef struct session {
|
||||||
// === Display related ===
|
// === Display related ===
|
||||||
/// Display in use.
|
/// Display in use.
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
|
@ -888,13 +887,13 @@ typedef struct _session_t {
|
||||||
|
|
||||||
// === Window related ===
|
// === Window related ===
|
||||||
/// Linked list of all windows.
|
/// Linked list of all windows.
|
||||||
struct _win *list;
|
win *list;
|
||||||
/// Pointer to <code>win</code> of current active window. Used by
|
/// Pointer to <code>win</code> of current active window. Used by
|
||||||
/// EWMH <code>_NET_ACTIVE_WINDOW</code> focus detection. In theory,
|
/// EWMH <code>_NET_ACTIVE_WINDOW</code> focus detection. In theory,
|
||||||
/// it's more reliable to store the window ID directly here, just in
|
/// it's more reliable to store the window ID directly here, just in
|
||||||
/// case the WM does something extraordinary, but caching the pointer
|
/// case the WM does something extraordinary, but caching the pointer
|
||||||
/// means another layer of complexity.
|
/// means another layer of complexity.
|
||||||
struct _win *active_win;
|
win *active_win;
|
||||||
/// Window ID of leader window of currently active window. Used for
|
/// Window ID of leader window of currently active window. Used for
|
||||||
/// subsidiary window detection.
|
/// subsidiary window detection.
|
||||||
Window active_leader;
|
Window active_leader;
|
||||||
|
@ -1038,11 +1037,11 @@ typedef struct _session_t {
|
||||||
} session_t;
|
} session_t;
|
||||||
|
|
||||||
/// Structure representing a top-level window compton manages.
|
/// Structure representing a top-level window compton manages.
|
||||||
typedef struct _win {
|
struct win {
|
||||||
/// Pointer to the next structure in the linked list.
|
/// Pointer to the next structure in the linked list.
|
||||||
struct _win *next;
|
win *next;
|
||||||
/// Pointer to the next higher window to paint.
|
/// Pointer to the next higher window to paint.
|
||||||
struct _win *prev_trans;
|
win *prev_trans;
|
||||||
|
|
||||||
// Core members
|
// Core members
|
||||||
/// ID of the top-level frame window.
|
/// ID of the top-level frame window.
|
||||||
|
@ -1164,7 +1163,7 @@ typedef struct _win {
|
||||||
/// Override value of window fade state. Set by D-Bus method calls.
|
/// Override value of window fade state. Set by D-Bus method calls.
|
||||||
switch_t fade_force;
|
switch_t fade_force;
|
||||||
/// Callback to be called after fading completed.
|
/// Callback to be called after fading completed.
|
||||||
void (*fade_callback) (session_t *ps, struct _win *w);
|
void (*fade_callback) (session_t *ps, win *w);
|
||||||
|
|
||||||
// Frame-opacity-related members
|
// Frame-opacity-related members
|
||||||
/// Current window frame opacity. Affected by window opacity.
|
/// Current window frame opacity. Affected by window opacity.
|
||||||
|
@ -1216,7 +1215,7 @@ typedef struct _win {
|
||||||
/// Textures and FBO background blur use.
|
/// Textures and FBO background blur use.
|
||||||
glx_blur_cache_t glx_blur_cache;
|
glx_blur_cache_t glx_blur_cache;
|
||||||
#endif
|
#endif
|
||||||
} win;
|
};
|
||||||
|
|
||||||
/// Temporary structure used for communication between
|
/// Temporary structure used for communication between
|
||||||
/// <code>get_cfg()</code> and <code>parse_config()</code>.
|
/// <code>get_cfg()</code> and <code>parse_config()</code>.
|
||||||
|
@ -1879,7 +1878,7 @@ find_win(session_t *ps, Window id) {
|
||||||
* Find out the WM frame of a client window using existing data.
|
* Find out the WM frame of a client window using existing data.
|
||||||
*
|
*
|
||||||
* @param id window ID
|
* @param id window ID
|
||||||
* @return struct _win object of the found window, NULL if not found
|
* @return struct win object of the found window, NULL if not found
|
||||||
*/
|
*/
|
||||||
static inline win *
|
static inline win *
|
||||||
find_toplevel(session_t *ps, Window id) {
|
find_toplevel(session_t *ps, Window id) {
|
||||||
|
@ -1936,7 +1935,7 @@ win_is_focused_real(session_t *ps, const win *w) {
|
||||||
/**
|
/**
|
||||||
* Find out the currently focused window.
|
* Find out the currently focused window.
|
||||||
*
|
*
|
||||||
* @return struct _win object of the found window, NULL if not found
|
* @return struct win object of the found window, NULL if not found
|
||||||
*/
|
*/
|
||||||
static inline win *
|
static inline win *
|
||||||
find_focused(session_t *ps) {
|
find_focused(session_t *ps) {
|
||||||
|
@ -2466,28 +2465,6 @@ opts_set_no_fading_openclose(session_t *ps, bool newval);
|
||||||
//!@}
|
//!@}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @name c2
|
|
||||||
*/
|
|
||||||
///@{
|
|
||||||
|
|
||||||
c2_lptr_t *
|
|
||||||
c2_parsed(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
#define c2_parse(ps, pcondlst, pattern) c2_parsed((ps), (pcondlst), (pattern), NULL)
|
|
||||||
|
|
||||||
c2_lptr_t *
|
|
||||||
c2_free_lptr(c2_lptr_t *lp);
|
|
||||||
|
|
||||||
bool
|
|
||||||
c2_matchd(session_t *ps, win *w, const c2_lptr_t *condlst,
|
|
||||||
const c2_lptr_t **cache, void **pdata);
|
|
||||||
|
|
||||||
#define c2_match(ps, w, condlst, cache) c2_matchd((ps), (w), (condlst), \
|
|
||||||
(cache), NULL)
|
|
||||||
|
|
||||||
///@}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Dump the given data to a file.
|
* @brief Dump the given data to a file.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
// === Includes ===
|
// === Includes ===
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
@ -27,6 +25,9 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "c2.h"
|
||||||
|
|
||||||
// == Functions ==
|
// == Functions ==
|
||||||
|
|
||||||
// inline functions must be made static to compile correctly under clang:
|
// inline functions must be made static to compile correctly under clang:
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "c2.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a long number.
|
* Parse a long number.
|
||||||
|
|
Loading…
Reference in New Issue