236 lines
5.0 KiB
C
236 lines
5.0 KiB
C
/*
|
|
* Copyright (C) 2004 Kim Woelders
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies of the Software, its documentation and marketing & publicity
|
|
* materials, and acknowledgment shall be given in the documentation, materials
|
|
* and software packages that this Software was used.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
#include "E.h"
|
|
|
|
#define ENABLE_DEBUG_STACKING 1
|
|
|
|
struct _ewinlist
|
|
{
|
|
const char *name;
|
|
int nalloc;
|
|
int nwins;
|
|
EWin **list;
|
|
};
|
|
|
|
#if ENABLE_DEBUG_STACKING
|
|
static void
|
|
EwinListShow(const char *txt, EWinList * ewl)
|
|
{
|
|
int i;
|
|
EWin *ewin;
|
|
|
|
if (!EventDebug(129))
|
|
return;
|
|
|
|
printf("%s-%s:\n", ewl->name, txt);
|
|
for (i = 0; i < ewl->nwins; i++)
|
|
{
|
|
ewin = ewl->list[i];
|
|
printf(" %2d: %#lx %d %s\n", i, ewin->client.win, ewin->layer,
|
|
EwinGetTitle(ewin));
|
|
}
|
|
}
|
|
#else
|
|
#define EwinListShow(txt, ewl)
|
|
#endif
|
|
|
|
static int
|
|
EwinListGetIndex(EWinList * ewl, EWin * ewin)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ewl->nwins; i++)
|
|
if (ewl->list[i] == ewin)
|
|
return i;
|
|
|
|
return -1;
|
|
}
|
|
|
|
void
|
|
EwinListAdd(EWinList * ewl, EWin * ewin)
|
|
{
|
|
int i;
|
|
|
|
/* Quit if already in list */
|
|
i = EwinListGetIndex(ewl, ewin);
|
|
if (i >= 0)
|
|
return;
|
|
|
|
if (ewl->nwins >= ewl->nalloc)
|
|
{
|
|
ewl->nalloc += 16;
|
|
ewl->list = (EWin **) Erealloc(ewl->list, ewl->nalloc * sizeof(EWin *));
|
|
}
|
|
|
|
/* Add to end */
|
|
ewl->list[ewl->nwins] = ewin;
|
|
ewl->nwins++;
|
|
|
|
EwinListShow("EwinListAdd", ewl);
|
|
}
|
|
|
|
void
|
|
EwinListDelete(EWinList * ewl, EWin * ewin)
|
|
{
|
|
int i, n;
|
|
|
|
/* Quit if not in list */
|
|
i = EwinListGetIndex(ewl, ewin);
|
|
if (i < 0)
|
|
return;
|
|
|
|
ewl->nwins--;
|
|
n = ewl->nwins - i;
|
|
if (n > 0)
|
|
{
|
|
memmove(ewl->list + i, ewl->list + i + 1, n * sizeof(EWin *));
|
|
}
|
|
else if (ewl->nwins <= 0)
|
|
{
|
|
/* Enables autocleanup at shutdown, if ever implemented */
|
|
Efree(ewl->list);
|
|
ewl->list = NULL;
|
|
}
|
|
|
|
EwinListShow("EwinListDelete", ewl);
|
|
}
|
|
|
|
int
|
|
EwinListLower(EWinList * ewl, EWin * ewin, int mode)
|
|
{
|
|
int i, j, n;
|
|
|
|
/* Quit if not in list */
|
|
i = EwinListGetIndex(ewl, ewin);
|
|
if (i < 0)
|
|
return 0;
|
|
|
|
j = ewl->nwins - 1;
|
|
if (mode)
|
|
{
|
|
/* Take the layer into account */
|
|
for (; j > i; j--)
|
|
if (ewin->layer <= ewl->list[j]->layer)
|
|
break;
|
|
}
|
|
|
|
n = j - i;
|
|
if (n > 0)
|
|
{
|
|
memmove(ewl->list + i, ewl->list + i + 1, n * sizeof(EWin *));
|
|
ewl->list[j] = ewin;
|
|
}
|
|
|
|
EwinListShow("EwinListLower", ewl);
|
|
return n;
|
|
}
|
|
|
|
int
|
|
EwinListRaise(EWinList * ewl, EWin * ewin, int mode)
|
|
{
|
|
int i, j, n;
|
|
|
|
/* Quit if not in list */
|
|
i = EwinListGetIndex(ewl, ewin);
|
|
if (i < 0)
|
|
return 0;
|
|
|
|
j = 0;
|
|
if (mode)
|
|
{
|
|
/* Take the layer into account */
|
|
for (; j < i; j++)
|
|
if (ewin->layer >= ewl->list[j]->layer)
|
|
break;
|
|
}
|
|
|
|
n = i - j;
|
|
if (n > 0)
|
|
{
|
|
memmove(ewl->list + j + 1, ewl->list + j, n * sizeof(EWin *));
|
|
ewl->list[j] = ewin;
|
|
}
|
|
|
|
EwinListShow("EwinListRaise", ewl);
|
|
return n;
|
|
}
|
|
|
|
/*
|
|
* The global stacking and focus lists
|
|
*/
|
|
EWinList EwinListFocus = { "Focus" };
|
|
EWinList EwinListStack = { "Stack" };
|
|
|
|
EWin **
|
|
EwinListGetStacking(int *num)
|
|
{
|
|
*num = EwinListStack.nwins;
|
|
return EwinListStack.list;
|
|
}
|
|
|
|
EWin **
|
|
EwinListGetForDesktop(int desk, int *num)
|
|
{
|
|
static EWin **lst = NULL;
|
|
static int nalloc;
|
|
int i, n, nwins;
|
|
EWin *ewin;
|
|
|
|
/* TBD: Maintain per desktop lists? Not sure it's worth while */
|
|
nwins = EwinListStack.nwins;
|
|
if (nalloc < nwins)
|
|
{
|
|
nalloc = nwins;
|
|
lst = Erealloc(lst, nalloc * sizeof(EWin *));
|
|
}
|
|
|
|
n = 0;
|
|
for (i = 0; i < nwins; i++)
|
|
{
|
|
ewin = EwinListStack.list[i];
|
|
if (EwinGetDesk(ewin) == desk)
|
|
lst[n++] = ewin;
|
|
}
|
|
*num = n;
|
|
|
|
return lst;
|
|
}
|
|
|
|
int
|
|
EwinListStackingRaise(EWin * ewin)
|
|
{
|
|
return EwinListRaise(&EwinListStack, ewin, 1);
|
|
}
|
|
|
|
int
|
|
EwinListStackingLower(EWin * ewin)
|
|
{
|
|
return EwinListLower(&EwinListStack, ewin, 1);
|
|
}
|
|
|
|
int
|
|
EwinListFocusRaise(EWin * ewin)
|
|
{
|
|
return EwinListRaise(&EwinListFocus, ewin, 0);
|
|
}
|