2 * Copyright (C) 2004-2008 Kim Woelders
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies of the Software, its documentation and marketing & publicity
13 * materials, and acknowledgment shall be given in the documentation, materials
14 * and software packages that this Software was used.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #define ENABLE_DEBUG_STACKING 1
30 #define EobjGetCwin(p) \
31 ((p->type == EOBJ_TYPE_EWIN) ? EwinGetClientXwin(((EWin*)(p))) : None)
33 typedef struct _eobjlist EobjList;
44 static int EobjListRaise(EobjList * ewl, EObj * eo, int test);
45 static int EobjListLower(EobjList * ewl, EObj * eo, int test);
47 #if ENABLE_DEBUG_STACKING
49 EobjListShow(const char *txt, EobjList * ewl)
54 if (!EDebug(EDBUG_TYPE_STACKING))
57 Eprintf("%s-%s:\n", ewl->name, txt);
58 for (i = 0; i < ewl->nwins; i++)
61 Eprintf(" %2d: %#10lx %#10lx %d %d %s\n", i, EobjGetXwin(eo),
62 EobjGetCwin(eo), eo->desk->num, eo->ilayer, EobjGetName(eo));
66 #define EobjListShow(txt, ewl)
70 EobjListGetIndex(EobjList * ewl, EObj * eo)
74 for (i = 0; i < ewl->nwins; i++)
75 if (ewl->list[i] == eo)
82 EobjListAdd(EobjList * ewl, EObj * eo, int ontop)
86 /* Quit if already in list */
87 i = EobjListGetIndex(ewl, eo);
91 if (ewl->nwins >= ewl->nalloc)
94 ewl->list = EREALLOC(EObj *, ewl->list, ewl->nalloc);
99 /* The simple way for now (add, raise/lower) */
102 ewl->list[ewl->nwins] = eo;
104 EobjListRaise(ewl, eo, 0);
108 memmove(ewl->list + 1, ewl->list, ewl->nwins * sizeof(EObj *));
111 EobjListLower(ewl, eo, 0);
113 if (eo->stacked == 0)
114 DeskSetDirtyStack(eo->desk, eo);
120 memmove(ewl->list + 1, ewl->list, ewl->nwins * sizeof(EObj *));
125 ewl->list[ewl->nwins] = eo;
130 EobjListShow("EobjListAdd", ewl);
134 EobjListDel(EobjList * ewl, EObj * eo)
138 /* Quit if not in list */
139 i = EobjListGetIndex(ewl, eo);
147 memmove(ewl->list + i, ewl->list + i + 1, n * sizeof(EObj *));
149 else if (ewl->nwins <= 0)
151 /* Enables autocleanup at shutdown, if ever implemented */
157 EobjListShow("EobjListDel", ewl);
161 EobjListLower(EobjList * ewl, EObj * eo, int test)
165 /* Quit if not in list */
166 i = EobjListGetIndex(ewl, eo);
173 /* Take the layer into account */
175 if (i != j && eo->ilayer <= ewl->list[j]->ilayer)
187 memmove(ewl->list + i, ewl->list + i + 1, n * sizeof(EObj *));
189 if (ewl->layered && eo->stacked > 0)
190 DeskSetDirtyStack(eo->desk, eo);
194 memmove(ewl->list + j + 1, ewl->list + j, -n * sizeof(EObj *));
196 if (ewl->layered && eo->stacked > 0)
197 DeskSetDirtyStack(eo->desk, eo);
200 EobjListShow("EobjListLower", ewl);
205 EobjListRaise(EobjList * ewl, EObj * eo, int test)
209 /* Quit if not in list */
210 i = EobjListGetIndex(ewl, eo);
217 /* Take the layer into account */
218 for (; j < ewl->nwins; j++)
219 if (j != i && eo->ilayer >= ewl->list[j]->ilayer)
231 memmove(ewl->list + i, ewl->list + i + 1, n * sizeof(EObj *));
233 if (ewl->layered && eo->stacked > 0)
234 DeskSetDirtyStack(eo->desk, eo);
238 memmove(ewl->list + j + 1, ewl->list + j, -n * sizeof(EObj *));
240 if (ewl->layered && eo->stacked > 0)
241 DeskSetDirtyStack(eo->desk, eo);
244 EobjListShow("EobjListRaise", ewl);
249 EobjListFind(const EobjList * ewl, Window win)
253 for (i = 0; i < ewl->nwins; i++)
254 if (EobjGetXwin(ewl->list[i]) == win)
261 EobjListTypeCount(const EobjList * ewl, int type)
265 for (i = n = 0; i < ewl->nwins; i++)
266 if (ewl->list[i]->type == type)
273 * The global object/client lists
275 static EobjList EwinListStack = { "Stack", 0, 0, NULL, 1, 0 };
276 static EobjList EwinListFocus = { "Focus", 0, 0, NULL, 0, 1 };
277 static EobjList EwinListOrder = { "Order", 0, 0, NULL, 0, 2 };
280 EobjListGet(EobjList * ewl, int *num)
287 EobjListStackCheck(EObj * eo)
289 return EobjListGetIndex(&EwinListStack, eo);
293 EobjListStackFind(Window win)
295 return EobjListFind(&EwinListStack, win);
299 EobjListStackGet(int *num)
301 return EobjListGet(&EwinListStack, num);
305 EobjListStackAdd(EObj * eo, int ontop)
307 EobjListAdd(&EwinListStack, eo, ontop);
311 EobjListStackDel(EObj * eo)
313 EobjListDel(&EwinListStack, eo);
317 EobjListStackRaise(EObj * eo, int test)
319 return EobjListRaise(&EwinListStack, eo, test);
323 EobjListStackLower(EObj * eo, int test)
325 return EobjListLower(&EwinListStack, eo, test);
329 EobjListFocusAdd(EObj * eo, int ontop)
331 EobjListAdd(&EwinListFocus, eo, ontop);
335 EobjListFocusDel(EObj * eo)
337 EobjListDel(&EwinListFocus, eo);
341 EobjListFocusRaise(EObj * eo)
343 return EobjListRaise(&EwinListFocus, eo, 0);
347 EwinListStackGet(int *num)
349 static EWin **lst = NULL;
350 static int nalloc = 0;
355 ewl = &EwinListStack;
356 newins = EobjListTypeCount(ewl, EOBJ_TYPE_EWIN);
359 nalloc = (newins + 16) & ~0xf; /* 16 at the time */
360 lst = EREALLOC(EWin *, lst, nalloc);
363 for (i = j = 0; i < ewl->nwins; i++)
366 if (eo->type != EOBJ_TYPE_EWIN)
369 lst[j++] = (EWin *) eo;
377 EwinListFocusGet(int *num)
379 return (EWin * const *)EobjListGet(&EwinListFocus, num);
383 EwinListGetForDesk(int *num, Desk * dsk)
385 static EWin **lst = NULL;
386 static int nalloc = 0;
391 ewl = &EwinListStack;
392 newins = EobjListTypeCount(ewl, EOBJ_TYPE_EWIN);
393 /* Too many - who cares. */
396 nalloc = (newins + 16) & ~0xf; /* 16 at the time */
397 lst = EREALLOC(EWin *, lst, nalloc);
400 for (i = j = 0; i < ewl->nwins; i++)
403 if (eo->type != EOBJ_TYPE_EWIN || eo->desk != dsk)
406 lst[j++] = (EWin *) eo;
414 EobjListStackGetForDesk(int *num, Desk * dsk)
416 static EObj **lst = NULL;
417 static int nalloc = 0;
422 ewl = &EwinListStack;
424 /* Too many - who cares. */
425 if (nalloc < ewl->nwins)
427 nalloc = (ewl->nwins + 16) & ~0xf; /* 16 at the time */
428 lst = EREALLOC(EObj *, lst, nalloc);
431 for (i = j = 0; i < ewl->nwins; i++)
446 EwinListStackGetTop(void)
452 ewl = &EwinListStack;
454 for (i = 0; i < ewl->nwins; i++)
457 if (eo->type == EOBJ_TYPE_EWIN)
466 EwinListStackIsRaised(const EWin * ewin)
470 const EObj *eo, *eox;
472 ewl = &EwinListStack;
475 for (i = 0; i < ewl->nwins; i++)
478 if (eo->type != EOBJ_TYPE_EWIN)
480 if (eo->desk != eox->desk)
482 if (eo->ilayer > eox->ilayer)
484 if (EwinGetTransientFor((EWin *) eo) == EwinGetClientXwin(ewin))
489 return 1; /* It should be impossible to get here */
493 EobjListOrderAdd(EObj * eo)
495 EobjListAdd(&EwinListOrder, eo, 0);
499 EobjListOrderDel(EObj * eo)
501 EobjListDel(&EwinListOrder, eo);
505 EwinListOrderGet(int *num)
507 return (EWin * const *)EobjListGet(&EwinListOrder, num);