/*
* Copyright 1989 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission. M.I.T. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**********************************************************************
*
* regions.c
*
* Region related routines
*
* 4/26/99 D. J. Hawkey Jr.
*
**********************************************************************/
#include <stdio.h>
#include <string.h>
#include "twm.h"
#include "screen.h"
#include "list.h"
#include "regions.h"
#include "gram.h"
#include "parse.h"
#include "util.h"
void
splitRegionEntry (re, grav1, grav2, w, h)
RegionEntry *re;
int grav1, grav2;
int w, h;
{
RegionEntry *new;
switch (grav1) {
case D_NORTH:
case D_SOUTH:
if (w != re->w)
splitRegionEntry (re, grav2, grav1, w, re->h);
if (h != re->h) {
new = (RegionEntry *)malloc (sizeof (RegionEntry));
new->u.twm_win = 0;
/* djhjr - 10/20/01 */
new->type = LTYPE_EXACT_NAME;
new->usedby = 0;
new->next = re->next;
re->next = new;
new->x = re->x;
new->h = (re->h - h);
new->w = re->w;
re->h = h;
if (grav1 == D_SOUTH) {
new->y = re->y;
re->y = new->y + new->h;
} else
new->y = re->y + re->h;
}
break;
case D_EAST:
case D_WEST:
if (h != re->h)
splitRegionEntry (re, grav2, grav1, re->w, h);
if (w != re->w) {
new = (RegionEntry *)malloc (sizeof (RegionEntry));
new->u.twm_win = 0;
/* djhjr - 10/20/01 */
new->type = LTYPE_EXACT_NAME;
new->usedby = 0;
new->next = re->next;
re->next = new;
new->y = re->y;
new->w = (re->w - w);
new->h = re->h;
re->w = w;
if (grav1 == D_EAST) {
new->x = re->x;
re->x = new->x + new->w;
} else
new->x = re->x + re->w;
}
break;
}
}
int
roundEntryUp (v, multiple)
{
return ((v + multiple - 1) / multiple) * multiple;
}
RegionEntry *
prevRegionEntry (re, rr)
RegionEntry *re;
RootRegion *rr;
{
RegionEntry *ep;
if (re == rr->entries)
return 0;
for (ep = rr->entries; ep->next != re; ep=ep->next)
;
return ep;
}
/*
* old is being freed; and is adjacent to re. Merge regions together.
*/
void
mergeRegionEntries (old, re)
RegionEntry *old, *re;
{
if (old->y == re->y) {
re->w = old->w + re->w;
if (old->x < re->x)
re->x = old->x;
} else {
re->h = old->h + re->h;
if (old->y < re->y)
re->y = old->y;
}
}
void
downRegionEntry(rr, re)
RootRegion *rr;
RegionEntry *re;
{
RegionEntry *ep, *en;
re->u.twm_win = 0;
re->usedby = 0;
ep = prevRegionEntry (re, rr);
en = re->next;
for (;;) {
if (ep && ep->usedby == 0 &&
((ep->x == re->x && ep->w == re->w) ||
(ep->y == re->y && ep->h == re->h)))
{
ep->next = re->next;
mergeRegionEntries (re, ep);
if (re->usedby == USEDBY_NAME)
free(re->u.name);
/* djhjr - 10/20/01 */
#ifndef NO_REGEX_SUPPORT
if (re->type & LTYPE_C_REGEXP)
regfree(&re->re);
#endif
free ((char *) re);
re = ep;
ep = prevRegionEntry (ep, rr);
} else if (en && en->usedby == 0 &&
((en->x == re->x && en->w == re->w) ||
(en->y == re->y && en->h == re->h)))
{
re->next = en->next;
mergeRegionEntries (en, re);
if (en->usedby == USEDBY_NAME)
free(en->u.name);
/* djhjr - 10/20/01 */
#ifndef NO_REGEX_SUPPORT
if (en->type & LTYPE_C_REGEXP)
regfree(&en->re);
#endif
free ((char *) en);
en = re->next;
} else
break;
}
}
RootRegion *
AddRegion(geom, grav1, grav2, stepx, stepy)
char *geom;
int grav1, grav2, stepx, stepy;
{
RootRegion *rr;
int mask;
rr = (RootRegion *)malloc(sizeof(RootRegion));
rr->next = NULL;
rr->grav1 = grav1;
rr->grav2 = grav2;
rr->stepx = (stepx <= 0) ? 2 : stepx; /* hard-coded value was '1' - djhjr - 9/26/99 */
rr->stepy = (stepy <= 0) ? 1 : stepy;
rr->x = rr->y = rr->w = rr->h = 0;
mask = XParseGeometry(geom, &rr->x, &rr->y, (unsigned int *)&rr->w, (unsigned int *)&rr->h);
if (mask & XNegative)
rr->x += Scr->MyDisplayWidth - rr->w;
if (mask & YNegative)
rr->y += Scr->MyDisplayHeight - rr->h;
rr->entries = (RegionEntry *)malloc(sizeof(RegionEntry));
rr->entries->next = 0;
rr->entries->x = rr->x;
rr->entries->y = rr->y;
rr->entries->w = rr->w;
rr->entries->h = rr->h;
rr->entries->u.twm_win = 0;
/* djhjr - 10/20/01 */
rr->entries->type = LTYPE_EXACT_NAME;
rr->entries->usedby = 0;
return rr;
}
void
FreeRegionEntries (rr)
RootRegion *rr;
{
RegionEntry *re, *tmp;
for (re = rr->entries; re; re=tmp)
{
tmp = re->next;
if (re->usedby == USEDBY_NAME)
free(re->u.name);
/* djhjr - 10/20/01 */
#ifndef NO_REGEX_SUPPORT
if (re->type & LTYPE_C_REGEXP)
regfree(&re->re);
#endif
free ((char *) re);
}
}
void
FreeRegions (first, last)
RootRegion *first, *last;
{
RootRegion *rr, *tmp;
for (rr = first; rr != NULL;)
{
tmp = rr;
FreeRegionEntries (rr);
rr = rr->next;
free((char *) tmp);
}
first = NULL;
last = NULL;
}
syntax highlighted by Code2HTML, v. 0.9.1