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