Xinqi Bao's Git

making Copyright notices more compact
[dwm.git] / tag.c
1 /* © 2004-2007 Anselm R. Garbe <garbeam at gmail dot com>
2 * See LICENSE file for license details. */
3 #include "dwm.h"
4 #include <regex.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <X11/Xutil.h>
8
9 /* static */
10
11 typedef struct {
12 const char *prop;
13 const char *tags;
14 Bool isfloating;
15 } Rule;
16
17 typedef struct {
18 regex_t *propregex;
19 regex_t *tagregex;
20 } Regs;
21
22 TAGS
23 RULES
24
25 static Regs *regs = NULL;
26 static unsigned int nrules = 0;
27
28 /* extern */
29
30 void
31 compileregs(void) {
32 unsigned int i;
33 regex_t *reg;
34
35 if(regs)
36 return;
37 nrules = sizeof rule / sizeof rule[0];
38 regs = emallocz(nrules * sizeof(Regs));
39 for(i = 0; i < nrules; i++) {
40 if(rule[i].prop) {
41 reg = emallocz(sizeof(regex_t));
42 if(regcomp(reg, rule[i].prop, REG_EXTENDED))
43 free(reg);
44 else
45 regs[i].propregex = reg;
46 }
47 if(rule[i].tags) {
48 reg = emallocz(sizeof(regex_t));
49 if(regcomp(reg, rule[i].tags, REG_EXTENDED))
50 free(reg);
51 else
52 regs[i].tagregex = reg;
53 }
54 }
55 }
56
57 Bool
58 isvisible(Client *c) {
59 unsigned int i;
60
61 for(i = 0; i < ntags; i++)
62 if(c->tags[i] && seltag[i])
63 return True;
64 return False;
65 }
66
67 void
68 settags(Client *c, Client *trans) {
69 char prop[512];
70 unsigned int i, j;
71 regmatch_t tmp;
72 Bool matched = trans != NULL;
73 XClassHint ch = { 0 };
74
75 if(matched)
76 for(i = 0; i < ntags; i++)
77 c->tags[i] = trans->tags[i];
78 else {
79 XGetClassHint(dpy, c->win, &ch);
80 snprintf(prop, sizeof prop, "%s:%s:%s",
81 ch.res_class ? ch.res_class : "",
82 ch.res_name ? ch.res_name : "", c->name);
83 for(i = 0; i < nrules; i++)
84 if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
85 c->isfloating = rule[i].isfloating;
86 for(j = 0; regs[i].tagregex && j < ntags; j++) {
87 if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
88 matched = True;
89 c->tags[j] = True;
90 }
91 }
92 }
93 if(ch.res_class)
94 XFree(ch.res_class);
95 if(ch.res_name)
96 XFree(ch.res_name);
97 }
98 if(!matched)
99 for(i = 0; i < ntags; i++)
100 c->tags[i] = seltag[i];
101 }
102
103 void
104 tag(const char *arg) {
105 int i;
106
107 if(!sel)
108 return;
109 for(i = 0; i < ntags; i++)
110 sel->tags[i] = arg == NULL;
111 i = arg ? atoi(arg) : 0;
112 if(i >= 0 && i < ntags)
113 sel->tags[i] = True;
114 lt->arrange();
115 }
116
117 void
118 toggletag(const char *arg) {
119 int i, j;
120
121 if(!sel)
122 return;
123 i = arg ? atoi(arg) : 0;
124 sel->tags[i] = !sel->tags[i];
125 for(j = 0; j < ntags && !sel->tags[j]; j++);
126 if(j == ntags)
127 sel->tags[i] = True;
128 lt->arrange();
129 }
130
131 void
132 toggleview(const char *arg) {
133 int i, j;
134
135 i = arg ? atoi(arg) : 0;
136 seltag[i] = !seltag[i];
137 for(j = 0; j < ntags && !seltag[j]; j++);
138 if(j == ntags)
139 seltag[i] = True; /* cannot toggle last view */
140 lt->arrange();
141 }
142
143 void
144 view(const char *arg) {
145 int i;
146
147 for(i = 0; i < ntags; i++)
148 seltag[i] = arg == NULL;
149 i = arg ? atoi(arg) : 0;
150 if(i >= 0 && i < ntags)
151 seltag[i] = True;
152 lt->arrange();
153 }