chiark / gitweb /
Imported Upstream version 1.0.0
[e16] / src / finders.c
1 /*
2  * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3  * Copyright (C) 2008-2009 Kim Woelders
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to
7  * deal in the Software without restriction, including without limitation the
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9  * sell copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies of the Software, its documentation and marketing & publicity
14  * materials, and acknowledgment shall be given in the documentation, materials
15  * and software packages that this Software was used.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #include "E.h"
25 #include "borders.h"
26 #include "ewins.h"
27 #include "groups.h"
28 #include "util.h"
29 #include <ctype.h>
30 #include <string.h>
31
32 EWin               *
33 EwinFindByPtr(const EWin * ewin)
34 {
35    EWin               *const *ewins;
36    int                 i, num;
37
38    ewins = EwinListGetAll(&num);
39    for (i = 0; i < num; i++)
40      {
41         if (ewin == ewins[i])
42            return ewins[i];
43      }
44    return NULL;
45 }
46
47 EWin               *
48 EwinFindByClient(Window win)
49 {
50    EWin               *const *ewins;
51    int                 i, num;
52
53    ewins = EwinListGetAll(&num);
54    for (i = 0; i < num; i++)
55      {
56         if (win == EwinGetClientXwin(ewins[i]))
57            return ewins[i];
58      }
59    return NULL;
60 }
61
62 EWin               *
63 EwinFindByChildren(Window win)
64 {
65    EWin               *const *ewins;
66    int                 i, j, num;
67
68    ewins = EwinListGetAll(&num);
69    for (i = 0; i < num; i++)
70      {
71         if ((win == EwinGetClientXwin(ewins[i])) ||
72             (win == EwinGetContainerXwin(ewins[i])))
73           {
74              return ewins[i];
75           }
76         else
77           {
78              for (j = 0; j < ewins[i]->border->num_winparts; j++)
79                 if (win == WinGetXwin(ewins[i]->bits[j].win))
80                   {
81                      return ewins[i];
82                   }
83           }
84      }
85    return NULL;
86 }
87
88 EWin              **
89 EwinsFindByExpr(const char *match, int *pnum, int *pflags)
90 {
91    EWin               *ewin, **lst;
92    EWin               *const *ewins;
93    int                 type;
94    int                 i, num, len, nfound, match_one, flags;
95
96    if (pnum)
97       *pnum = 0;
98
99    if (!match || !match[0])
100       return NULL;
101
102    ewin = NULL;
103    flags = 0;
104
105    if (!strcmp(match, "*") || !strcmp(match, "=") || !strcmp(match, "current"))
106      {
107         ewin = GetContextEwin();
108         if (!ewin)
109            ewin = GetFocusEwin();
110         if (match[0] == '=')
111            flags = 1;           /* Nogroup */
112         goto do_one;
113      }
114
115    if (isdigit(match[0]))
116      {
117         unsigned int        win;
118
119         sscanf(match, "%x", &win);
120         ewin = EwinFindByChildren(win);
121         goto do_one;
122      }
123
124    match_one = 1;
125    if (!strcmp(match, "all"))
126      {
127         type = 'a';
128         match_one = 0;
129         flags = 1;              /* Nogroup */
130      }
131    else if (match[0] == '=')
132      {
133         type = 's';
134         match++;
135         flags = 1;              /* Nogroup */
136      }
137    else if (strchr(match, '*'))
138      {
139         type = 'w';
140         match_one = 0;
141         flags = 1;              /* Nogroup */
142      }
143    else
144      {
145         type = 's';
146      }
147
148    len = strlen(match);
149    if (len <= 0)
150       return NULL;
151
152    ewins = EwinListGetAll(&num);
153    if (!ewins)
154       return NULL;
155
156    nfound = 0;
157    lst = NULL;
158    for (i = 0; i < num; i++)
159      {
160         ewin = ewins[i];
161
162         if (type == 'a')        /* All */
163           {
164           }
165         else if (type == 'w')   /* Wildcard */
166           {
167              if (!matchregexp(match, EwinGetIcccmName(ewin)))
168                 continue;
169           }
170         else                    /* Match name (substring) */
171           {
172              const char         *name;
173
174              name = EwinGetIcccmName(ewin);
175              if (!name)
176                 continue;
177              if (!Estrcasestr(name, match))
178                 continue;
179           }
180         nfound++;
181         lst = EREALLOC(EWin *, lst, nfound);
182         lst[nfound - 1] = ewin;
183         if (match_one)
184            break;
185      }
186    goto done;
187
188  do_one:
189    if (!ewin)
190       return NULL;
191    nfound = 1;
192    lst = EMALLOC(EWin *, 1);
193    if (!lst)
194       return NULL;
195    lst[0] = ewin;
196
197  done:
198    if (pnum)
199       *pnum = nfound;
200    if (pflags)
201       *pflags = flags;
202    return lst;
203 }
204
205 EWin               *
206 EwinFindByExpr(const char *match)
207 {
208    EWin               *ewin, **lst;
209
210    lst = EwinsFindByExpr(match, NULL, NULL);
211    if (!lst)
212       return NULL;
213    ewin = lst[0];
214    Efree(lst);
215    return ewin;
216 }
217
218 EWin              **
219 ListWinGroupMembersForEwin(const EWin * ewin, int action, char nogroup,
220                            int *pnum)
221 {
222
223    EWin              **gwins, *ew;
224    EWin               *const *ewins;
225    Group              *grp;
226    int                 i, num, gwcnt;
227
228    if (!ewin)
229      {
230         *pnum = 0;
231         return NULL;
232      }
233
234    gwcnt = 0;
235    gwins = NULL;
236
237    if (nogroup || ewin->num_groups <= 0)
238       goto done;
239
240    ewins = EwinListGetAll(&num);
241    if (ewins == NULL)           /* Should not be possible */
242       goto done;
243
244    /* Loop through window stack, bottom up */
245    for (i = num - 1; i >= 0; i--)
246      {
247         ew = ewins[i];
248
249         if (ew == ewin)
250            goto do_add;
251
252         /* To get consistent behaviour, limit groups to a single desktop for now: */
253         if (EoGetDesk(ew) != EoGetDesk(ewin))
254            continue;
255
256         grp = EwinsInGroup(ewin, ew);
257         if (!grp)
258            continue;
259
260         switch (action)
261           {
262           case GROUP_ACTION_SET_WINDOW_BORDER:
263              if (!grp->cfg.set_border)
264                 continue;
265              break;
266           case GROUP_ACTION_ICONIFY:
267              if (!grp->cfg.iconify)
268                 continue;
269              break;
270           case GROUP_ACTION_MOVE:
271              if (!grp->cfg.move)
272                 continue;
273              break;
274           case GROUP_ACTION_STACKING:
275              if (!grp->cfg.raise)
276                 continue;
277              break;
278           case GROUP_ACTION_STICK:
279              if (!grp->cfg.stick)
280                 continue;
281              break;
282           case GROUP_ACTION_SHADE:
283              if (!grp->cfg.shade)
284                 continue;
285              break;
286           case GROUP_ACTION_KILL:
287              if (!grp->cfg.kill)
288                 continue;
289              break;
290           default:
291              break;
292           }
293
294       do_add:
295         gwins = EREALLOC(EWin *, gwins, gwcnt + 1);
296         gwins[gwcnt] = ew;
297         gwcnt++;
298      }
299
300  done:
301    if (gwins == NULL)
302      {
303         gwins = EMALLOC(EWin *, 1);
304         gwins[0] = (EWin *) ewin;
305         gwcnt = 1;
306      }
307    *pnum = gwcnt;
308    return gwins;
309 }