v12i062: olvwm - Open Look Virtual Window Manager, Part06/16

Scott Oaks - Sun Consulting NYC sdo at soliado.East.Sun.COM
Mon Apr 29 03:29:32 AEST 1991


Submitted-by: sdo at soliado.East.Sun.COM (Scott Oaks - Sun Consulting NYC)
Posting-number: Volume 12, Issue 62
Archive-name: olvwm/part06

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 6 (of 16)."
# Contents:  client.c slots.c win.h
# Wrapped by sdo at piccolo on Fri Apr 26 17:31:05 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'client.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'client.c'\"
else
echo shar: Extracting \"'client.c'\" \(14648 characters\)
sed "s/^X//" >'client.c' <<'END_OF_FILE'
X/* 
X *      (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
X *      pending in the U.S. and foreign countries. See LEGAL_NOTICE
X *      file for terms of the license.
X *
X *	Written for Sun Microsystems by Crucible, Santa Cruz, CA.
X */
X
X/* client.c - functions relating to clients as a whole 
X */
X
static  char	sccsid[] = "@(#)client.c	1.2 olvwm version 3/30/91";
X
X/*
X * Based on
static	char	sccsid[] = "@(#) client.c 25.15 90/05/31 Crucible";
X *
X */
X
X#include <errno.h>
X#include <stdio.h>
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/Xatom.h>
X#include <olgx/olgx.h>
X
X#include "events.h"
X#include "mem.h"
X#include "olwm.h"
X#include "win.h"
X#include "menu.h"
X#include "group.h"
X#include "globals.h"
X
X/***************************************************************************
X* global data
X***************************************************************************/
X
List *ActiveClientList;
X
X/*
X * FocusIndeterminate indicates that no window has the focus and that the 
X * focus should be transferred to the NoFocus window.  FocusIndeterminate is 
X * set when the window with the focus becomes Withdrawn.  Since the Unmap-
X * Notify event has no timestamp, setting the focus to the NoFocus window 
X * immediately is difficult to do properly.  Instead, this flag is set and a 
X * message is sent to the NoFocus window.  If this flag is still set when the 
X * message is received, the focus is set to the NoFocus window.  This flag is 
X * unset whenever the focus changes, so the transfer of focus to the NoFocus 
X * window is nullified if there has been an intervening focus transfer.
X */
Bool FocusIndeterminate = False;
X
extern Atom AtomColorMapWindows;
extern Atom AtomDeleteWindow;
extern Atom AtomLeftFooter;
extern Atom AtomProtocols;
extern Atom AtomRightFooter;
extern Atom AtomShowProperties;
extern Atom AtomTakeFocus;
extern Atom AtomWindowBusy;
extern Atom AtomWMState;
X
extern Window NoFocusWin;
X
extern void RecursiveRefresh();
X
X/***************************************************************************
X* private data
X***************************************************************************/
X
X/***************************************************************************
X* private functions
X***************************************************************************/
X
static void clientSetBusy();
X
X/***************************************************************************
X* global functions
X***************************************************************************/
X
X
X/* ClientSendProtocol - send a protocol message to a client
X */
void *
ClientSendProtocol(cli,proto,evtime)
Client *cli;
Atom proto;
Time evtime;
X{
X	XEvent          clientEvent;
X
X	clientEvent.xclient.type = ClientMessage;
X	clientEvent.xclient.message_type = AtomProtocols;
X	clientEvent.xclient.format = 32;
X	clientEvent.xclient.display = cli->dpy;
X	clientEvent.xclient.window = ClientPane(cli);
X	clientEvent.xclient.data.l[0] = proto;
X	clientEvent.xclient.data.l[1] = evtime;
X
X	XSendEvent(cli->dpy, clientEvent.xclient.window, False,
X		NoEventMask, &clientEvent);
X	return NULL;
X}
X
X/* ClientShowProps - send a ClientMessage of type WM_SHOW_PROPERTIES
X */
void
ClientShowProps(cli)
Client *cli;
X{
X	XEvent clientEvent;
X	
X	clientEvent.xclient.type = ClientMessage;
X	clientEvent.xclient.message_type = AtomShowProperties;
X	clientEvent.xclient.format = 32;
X	clientEvent.xclient.display = cli->dpy;
X	clientEvent.xclient.window = PANEWINOFCLIENT(cli);
X
X	XSendEvent(cli->dpy, clientEvent.xclient.window, False,
X		NoEventMask, &clientEvent);
X}
X
X/* ClientKill - a client must be killed.  If it can handle the DELETE_WINDOW
X *	protocol, use it; otherwise, if we are forcing the client to go
X *	away, kill it.
X */
void *
ClientKill(cli,pforce)
Client *cli;
Bool pforce;
X{
X	if (cli->protocols & DELETE_WINDOW)
X		ClientSendProtocol(cli,AtomDeleteWindow,LastEventTime);
X	else
X		if (pforce)
X			XKillClient(cli->dpy,ClientPane(cli));
X	return NULL;	
X}
X
X
X/* UnparentClient - while exiting OLWM: unmap all icons that are on the
X * screen.  Reparent all windows back to the root, suitably offset
X * according to their window-gravities.  Also remap all non-withdrawn
X * windows, and remove all Withdrawn windows from the save-set (so
X * they don't get remapped.  REMIND: We have to do this because
X * Withdrawn windows are still left reparented inside the frame; this
X * shouldn't be the case.
X */
void *
UnparentClient(cli,junk)
Client *cli;
void *junk;
X{
X	WinPaneFrame *frameInfo;
X	WinPane *paneInfo;
X	Window pane;
X	extern int IgnoreErrors(), ErrorHandler();
X
X#ifdef DEBUG
X	printf("UnparentClient: %x\n",cli);
X#endif
X
X	if (cli->wmState == IconicState)
X	{
X		IconHide(cli, cli->iconwin);
X	}
X
X	frameInfo = cli->framewin;
X	paneInfo = (WinPane*)(frameInfo->fcore.panewin);
X	pane = paneInfo->core.self;
X	FrameUnparentPane(cli, frameInfo, paneInfo);
X
X	if (cli->wmState == DontCareState) 
X	{ 
X		XChangeSaveSet(cli->dpy, pane, SetModeDelete);
X	} 
X	else 
X	{
X		XMapWindow(cli->dpy,pane);
X	}
X
X	return NULL;
X}
X
X/*
X * addClient -- add this client structure to the list of active clients
X */
static void
addClient(cli)
Client *cli;
X{
X	List *l = ActiveClientList;
X	Client *tc;
X
X#ifdef DEBUG
X	printf("addClient: %x\n",cli);
X#endif
X        /* First look to see if window is already listed.  */
X        for(tc = ListEnum(&l); tc != NULL; tc = ListEnum(&l))
X        {
X                if (tc == cli)
X                        return;
X        }
X
X        /* Wasn't present, add to list. */
X	ActiveClientList = ListCons(cli, ActiveClientList);
X}
X
X/*
X * removeClient -- remove this client structure from the list of active
X *      clients.
X */
static void
removeClient(cli)
Client *cli;
X{
X	List **l;
X
X	for (l = &ActiveClientList ; *l != NULL; l = &((*l)->next))
X	{
X		if ((*l)->value == cli)
X		{
X			ListDestroyCell(l);
X			return;
X		}
X	}
X}
X
X/* 
X * DestroyClient -- destroy all resources associated with this client
X */
void 
DestroyClient(cli)
Client *cli;
X{
X	/* remove any possible external references to the client */
X
X	UnTrackSubwindows(cli, True);
X	if (IsSelected(cli))
X		RemoveSelection(cli);
X	removeClient(cli);
X
X	/* destroy the window resources associated with the client */
X	WinCallDestroy(cli);
X
X	GroupRemove(cli->groupid, cli);
X
X	/* free up the client structure resources */
X	/* REMIND  there's lots of other stuff to free up here */
X	/* REMIND  what's to be done with followers here? */
X	MemFree(cli);
X}
X
X/*
X * ClientConfigure - a configure request event has been received on the
X * pane.  Configure the windows accordingly.
X */
void
ClientConfigure(cli,win,pxcre)
Client *cli;
WinGeneric *win;
XXConfigureRequestEvent *pxcre;
X{
X        XWindowChanges          winChange;
X
X	if ((cli == NULL) || (win == NULL))
X	{
X                /* We don't know about this window, or it's withdrawn
X                 * convert the request into an XConfigureWindow
X                 * call. We do not look at the hints to see if
X                 * the resize is in the proper increments, but since
X                 * the app is asking for the reconfigure this seems
X                 * right.
X                 */
X                winChange.x = pxcre->x;
X                winChange.y = pxcre->y;
X                winChange.width = pxcre->width;
X                winChange.height = pxcre->height;
X                winChange.border_width = pxcre->border_width;
X                winChange.stack_mode = pxcre->detail;
X                winChange.sibling = pxcre->above;
X
X                XConfigureWindow(pxcre->display,
X                         pxcre->window,
X                         /* lint will warn: this is a long, not int */
X                         pxcre->value_mask,
X                         &winChange );
X	}
X	else /* cli->wmState == NormalState or IconicState */
X	{
X		WinCallConfig(cli->dpy,win,pxcre);
X	}
X}
X
X/*
X * ClientGetWMState      -- get the contents of the WM_STATE property.
X */
Bool
ClientGetWMState( dpy, win, state, iconwin )
X    Window win;
X    int *state;
X    Window *iconwin;
X{
X    int nitems, remain;
X    int *data;
X
X    data = GetWindowProperty(dpy, win, AtomWMState, 0L, 
X		LONG_LENGTH(int)+LONG_LENGTH(Window), AtomWMState, 32, &nitems,
X                &remain);
X    if (data == NULL)
X    {
X	return False;
X    } 
X    else if (nitems != 2)
X    {
X        XFree(data);
X        return False;
X    }
X    *state = data[0];
X    *iconwin = (Window) data[1];
X    XFree(data);
X    return True;
X}
X
X/*
X * ClientSetWMState     -- set the contents of the WM_STATE property,
X *                         given the information in the WinInfo struct.
X */
void
ClientSetWMState( cli )
X    Client *cli;
X{
X    unsigned long data[2];
X    WinIconFrame *iconWinInfo = cli->iconwin;
X    Window pane = PANEWINOFCLIENT(cli);
X
X    data[0] = cli->wmState;
X    if ( iconWinInfo ) {
X        if ( iconWinInfo->fcore.panewin )
X            data[1] = iconWinInfo->fcore.panewin->core.self;
X        else
X            data[1] = iconWinInfo->core.self;
X    } else {
X        data[1] = None;
X    }
X    XChangeProperty(cli->dpy, pane, AtomWMState, AtomWMState,
X                    32, PropModeReplace, (unsigned char *)data, 2);
X}
X
X
X/* ClientCreate -- allocate and initialise a client structure 
X */
Client *
ClientCreate(dpy,screen)
Display *dpy;
int screen;
X{
X	Client *cli = MemNew(Client);
X
X	cli->wmState = DontCareState;
X	cli->dpy = dpy;
X	cli->screen = screen;
X	/* all other fields set to zero by allocation function */
X	addClient(cli);
X	return cli;
X}
X
X/* ClientPane - return the pane window of a client
X */
Window
ClientPane(cli)
Client *cli;
X{
X	WinPaneFrame *wf;
X	WinPane *wp;
X
X	if ((wf = cli->framewin) == NULL)
X		return NULL;
X	if ((wp = (WinPane *)(wf->fcore.panewin)) == NULL)
X		return NULL;
X	return wp->core.self;
X}
X
X/* ClientDistributeProperty -- a property of the client has changed.
X *	Forward the change notification to the appropriate handler.
X */
X /* REMIND this is pretty sketchy at the moment */
void
ClientDistributeProperty(cli, event)
Client *cli;
XXPropertyEvent *event;
X{
X
X	/* REMIND check that we're seeing a change, not a delete
X	 * on some of these */
X
X	if (event->atom == AtomColorMapWindows)
X	{
X		if (event->state == PropertyNewValue)
X		{
X			TrackSubwindows(cli);
X		}
X		else
X		{
X			UnTrackSubwindows(cli, False);
X		}
X	}
X	else if (event->atom == XA_WM_ICON_NAME)
X	{
X		IconChangeName(cli->iconwin, PANEWINOFCLIENT(cli));
X	}
X	else if ((event->atom == AtomRightFooter) || (event->atom == AtomLeftFooter))
X	{
X		FrameNewFooter(cli);
X	}
X	else if (event->atom == XA_WM_NAME)
X	{
X		FrameNewHeader(cli);
X	}
X        else if (event->atom == AtomWindowBusy)
X        {
X		clientSetBusy(cli,event->time,event->state);
X        }
X}
X
X/* refresh the window.  We do this by creating a window on top
X * of the window to refresh and then immediately destroy it
X */
void
ClientRefresh(cli)
Client *cli;
X{
X	WinPaneFrame *winFrame = cli->framewin;
X	Window w;
X	XSetWindowAttributes xswa;
X
X    if (GRV.RefreshRecursively) {
X	RecursiveRefresh(cli->dpy, winFrame->core.self);
X    } else {
X	w = XCreateWindow(cli->dpy, winFrame->core.self, 0, 0,
X	    winFrame->core.width, winFrame->core.height, 0,
X	    CopyFromParent, InputOutput, CopyFromParent,
X	    0, &xswa);
X	XMapRaised(cli->dpy,w);
X	XDestroyWindow(cli->dpy,w);
X    }
X}
X
X
X/* ClientInBox -- given a bounding box, apply a function to all clients
X *      which fall inside the rectangle
X */
void *
ClientInBox(cli, close)
Client *cli;
clientInBoxClosure *close;
X{
X	int x, y, w, h;
X
X	if (cli->wmState == IconicState)
X	{
X		x = cli->iconwin->core.x;
X		y = cli->iconwin->core.y;
X		w = cli->iconwin->core.width;
X		h = cli->iconwin->core.height;
X	}
X	else
X	{
X		x = cli->framewin->core.x;
X		y = cli->framewin->core.y;
X		w = cli->framewin->core.width;
X		h = cli->framewin->core.height;
X	}
X
X	if ((x >= close->bx) &&
X	    (y >= close->by) &&
X	    ((x + w) <= (close->bx + close->bw)) &&
X	    ((y + h) <= (close->by + close->bh)))
X		(close->func)(cli, close->timestamp);
X
X	return NULL;
X}
X
X/*
X * ClientSetBusy -- the busy state has (possibly) been changed for a client.
X *	if the client is going from normal to busy:
X *          mark the client as busy
X *          put up a busy window
X *      if the client is going from busy to normal:
X *          mark the client as unbusy
X *          take down a busy window (if it exists)
X */
static void
clientSetBusy(cli,evtime,state)
X    Client *cli;
X    Time evtime;
X    int state;
X{
X        int *newBusyPtr;
X	int newBusy;
X        unsigned long nItems, remain;
X
X	if (state == PropertyNewValue) {
X	    newBusyPtr = GetWindowProperty(cli->dpy, PANEWINOFCLIENT(cli),
X		AtomWindowBusy, 0L, LONG_LENGTH(*newBusyPtr), 
X		XA_INTEGER, 32, &nItems, &remain);
X
X	    if (newBusyPtr == NULL) {
X		/* property not found or has the wrong type */
X		newBusy = 0;
X	    } else {
X		if (nItems != LONG_LENGTH(newBusy) || remain != 0) {
X		    /* got a property, but it is invalid */
X		    newBusy = 0;
X		} else {
X		    /* valid property */
X		    newBusy = *newBusyPtr;
X		}
X		XFree(newBusyPtr);
X	    }
X	} else {
X	    /* property was deleted */
X	    newBusy = 0;
X	}
X
X        if (cli->isBusy && (newBusy == 0)) {
X	    /* losing busy */
X            cli->isBusy = False;
X	    if (cli->isFocus)
X		ClientSetFocus(cli,True,evtime);
X	    FrameSetBusy(cli->framewin, False);
X        }
X        else if (!cli->isBusy && (newBusy == 1)) {
X	    /* gaining busy */
X            cli->isBusy = True;
X	    FrameSetBusy(cli->framewin, True);
X	    if (cli->isFocus)
X	    	    ClientSetFocus(cli,True,evtime);
X        }
X}
X
X/*
X * ClientSetFocus -- possibly set the focus to this client.  If the
X *	client is GloballyActive, we only send TakeFocus messages
X *	if sendTF is true.  If the client has a different focus
X *	mode sendTF is ignored.
X */
void
ClientSetFocus(cli,sendTF,evtime)
Client *cli;
Bool sendTF;
Time evtime;
X{
X	FocusIndeterminate = False;
X
X	if (cli->isBusy)
X	{
X	    /* REMIND
X	     * setting RevertToNone is problematic.  When the window goes 
X	     * unbusy, the winBusy will be unmapped, which may leave the focus 
X	     * at None until the client gets around to responding to our
X	     * WM_TAKE_FOCUS message.
X	     */
X	    if (cli->framewin->winBusy != NULL)
X		XSetInputFocus(cli->dpy, cli->framewin->winBusy->core.self,
X			RevertToNone, evtime);
X	    else
X		XSetInputFocus(cli->dpy, NoFocusWin,
X			RevertToPointerRoot, evtime);
X	}
X	else
X	{
X	    switch (cli->focusMode)
X	    {
X	    case NoInput:
X	        /* do nothing */
X	        break;
X
X	    case Passive:
X	    case LocallyActive:
X	        XSetInputFocus(cli->dpy, PANEWINOFCLIENT(cli),
X		    RevertToParent, evtime);
X	        break;
X
X	    case GloballyActive:
X	        if (sendTF)
X	        {
X		    ClientSendProtocol(cli, AtomTakeFocus, evtime);
X	        }
X	        break;
X	    }
X	}
X}
END_OF_FILE
if test 14648 -ne `wc -c <'client.c'`; then
    echo shar: \"'client.c'\" unpacked with wrong size!
fi
# end of 'client.c'
fi
if test -f 'slots.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'slots.c'\"
else
echo shar: Extracting \"'slots.c'\" \(14674 characters\)
sed "s/^X//" >'slots.c' <<'END_OF_FILE'
X/*
X *      (c) Copyright 1990 Sun Microsystems, Inc. Sun design patents
X *      pending in the U.S. and foreign countries. See LEGAL_NOTICE
X *      file for terms of the license.
X *
X *	Written for Sun Microsystems by Crucible, Santa Cruz, CA.
X */
X
static char     sccsid[] = "@(#)slots.c	1.2 olvwm version 3/30/91";
X
X/* based on @(#) slots.c 1.5 90/05/15 Crucible */
X
X#include <stdio.h>
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "mem.h"
X#include "st.h"
X#include "olwm.h"
X#include "win.h"
X#include "globals.h"
X#include "list.h"
X#include "slots.h"
X
X/***************************************************************************
X* Local data
X***************************************************************************/
X
static SlotOrder SOmajor = SOBottomToTop;
static SlotOrder SOminor = SOLeftToRight;
X
typedef struct _slotrgn {
X	int ma, mi, maw, miw;
X	} slotRgn;
typedef struct _slotabs {
X	int x, y, w, h;
X	} slotAbs;
X
static int *occupancy = NULL;
static int minoccupancy = 0;
static List *iconList = NULL_LIST;
static int maslots, mislots;
static int slotshoriz, slotsvert;
static int pixhoriz, pixvert;
X
X#define PLUSINFINITY 0xfffffff	/* REMIND fix this for architecture-independence */
X
X#ifdef BRAP
extern int VirtualDesktopHeight, VirtualDesktopWidth, VirtualDesktopX, VirtualDesktopY;
X#endif
X
X/***************************************************************************
X* Local functions
X***************************************************************************/
X
X
X#define ROUNDUP(n,d) (((n)+(d)-1)/(d))
X/* #define ROUND(n,d) ((0.5+((float)(n)/(float)(d)))*(int)(d)) */
X#define ROUND(n,d) (((((n)%(d))>((d)/2))?(((n)/(d))+1):((n)/(d)))*(d))
X
X#define SLOTOFFSET(ma, mi) (((ma))*mislots+(mi))
X#define AOCCUPANCY(ma,mi) ((occupancy+SLOTOFFSET((ma),(mi))))
X#define OCCUPANCY(ma,mi) (*(AOCCUPANCY((ma),(mi))))
X
X#define ISVERT(so) (((so)==SOBottomToTop)||((so)==SOTopToBottom))
X#define ISHORZ(so) (((so)==SOLeftToRight)||((so)==SORightToLeft))
X#define ISDECREASING(so) (((so)==SORightToLeft)||((so)==SOBottomToTop))
X
X#ifdef NOTDEF
static char *
sotochar(so)
SlotOrder so;
X{
X	if (so == SOTopToBottom)
X		return ("SOTopToBottom");
X	if (so == SOBottomToTop)
X		return ("SOBottomToTop");
X	if (so == SOLeftToRight)
X		return ("SOLeftToRight");
X	if (so == SORightToLeft)
X		return ("SORightToLeft");
X	return("SOIllegal");
X}
X#endif
X
X#ifdef DEBUG
X/* dumpocc -- print the occupancy count table to stderr
X */
static void
dumpocc()
X{
X	int ima, imi;
X
X	fprintf(stderr,"dump of occupancy table:\n");
X	for (ima = 0; ima<maslots; ima++)
X	    for (imi = 0; imi<mislots; imi++)
X		if (OCCUPANCY(ima,imi)!=0)
X		    fprintf(stderr,"%x: occ[%d,%d]/[%d] = %d\n",AOCCUPANCY(ima,imi),ima,imi,SLOTOFFSET(ima,imi),OCCUPANCY(ima,imi));
X	fprintf(stderr,"end of dump of occupancy table\n");
X}
X#endif
X
X
X/* setMajorMinor -- set two output variables from two input variables,
X * based on the major/minor settings.
X */
static void
setMajorMinor(r,c,pma,pmi)
int r, c, *pma, *pmi;
X{
X	if (ISVERT(SOmajor))
X	{
X	    *pma = r;
X	    *pmi = c;
X	}
X	else
X	{
X	    *pma = c;
X	    *pmi = r;
X	}
X}
X
X/* setAbsolute -- set two output variables from two input variables, based
X * on major/minor settings; this is the inverse of setMajorMinor.
X */
static void
setAbsolute(ma,mi,pr,pc)
int ma, mi;
int *pr, *pc;
X{
X    if (ISVERT(SOmajor))
X    {
X	*pr = ma;
X	*pc = mi;
X    }
X    else
X    {
X	*pc = ma;
X	*pr = mi;
X    }
X}
X
X/* incrRegion -- increment the occupancy count of a region
X */
static void
incrRegion(slot,val)
IconSlot *slot;
int val;
X{
X	int ii,jj;
X
X	for (ii = slot->ma; (ii>=0)&&(ii<maslots)&&(ii<slot->ma+slot->maw); ii++)
X	    for (jj = slot->mi; (jj>=0)&&(jj<mislots)&&(jj<slot->mi+slot->miw); jj++)
X	    {
X		if ((OCCUPANCY(ii,jj) += val) < minoccupancy)
X		    minoccupancy = OCCUPANCY(ii,jj);
X	    }
X}
X
X/* findMinMaxRgn -- find the minimum and maximum occupancies of a region
X */
static void
findMinMaxRgn(ma, mi, nmajor, nminor, pminrgn, pmaxrgn)
int ma, mi, nmajor, nminor, *pminrgn, *pmaxrgn;
X{
X	int min, max;
X	int ii, jj;
X	int occ;
X
X	min = PLUSINFINITY;
X	max = -1;
X
X	for (ii=ma; ii<ma+nmajor; ii++)
X	    for (jj = mi; jj<mi+nminor; jj++)
X	    {
X		occ = OCCUPANCY(ii,jj);
X		if (occ < min)
X		    min = occ;
X		if (occ > max)
X		    max = occ;
X	    }
X	*pminrgn = min;
X	*pmaxrgn = max;
X}
X
static IconSlot *
incrDynamicSlots(nmajor, nminor)
int nmajor, nminor;
X{
X    	int minoccrgn; /* smallest occupancy found for a region of given size */
X    	int minfound, minfoundrgn; 	/* smallest occupancy found for one slot
X				         * and a region respectively; used to reset
X				         * search values */
X    	int ma, mi;	/* indices in major and minor directions */
X    	int maxrgn, minrgn;	  /* max and min occupancies in a region */
X	IconSlot *slot = MemNew(IconSlot);
X
X	minoccrgn = minoccupancy;
X	slot->positioned = False;
X
X	for (;;)	/* will actually only iterate twice */
X	{
X	    minfound = minfoundrgn = PLUSINFINITY;
X	    for (ma = 0; (ma <= maslots-nmajor); ma++)
X	    {
X	        for (mi = 0; (mi <= mislots-nminor); mi++)
X	        {
X		    findMinMaxRgn(ma, mi, nmajor, nminor, &minrgn, &maxrgn);
X		    if (minrgn < minfound)
X			minfound = minrgn;
X		    if (maxrgn < minfoundrgn)
X			minfoundrgn = maxrgn;
X		    if (maxrgn <= minoccrgn)
X		    {
X			slot->ma = ma;
X			slot->mi = mi;
X			slot->maw = nmajor;
X			slot->miw = nminor;
X			incrRegion(slot,1);
X			return slot;
X		    }
X	        }
X	    }
X	    /* no regions available with occupancy <= known minimum */
X	    if (minfound > minoccupancy)	/* increase global slot minimum */
X		minoccupancy = minfound;
X	    minoccrgn = minfoundrgn;		/* increase local region min */
X	}
X}
X
X/* setIconPos -- given a slot, position the icon frame window accordingly.
X */
static void 
setIconPos(win, slot)
WinIconFrame *win;
IconSlot *slot;
X{
X    int x,y;
X
X    if (SOmajor == SOTopToBottom)
X    {
X	y = ICON_GRID_HEIGHT*slot->ma;
X	if (SOminor == SOLeftToRight)
X	{
X	    x = ICON_GRID_WIDTH*slot->mi;
X	}
X	else
X	{
X	    x = pixhoriz - slot->mi*ICON_GRID_WIDTH - win->core.width;
X	}
X    }
X    else if (SOmajor == SOBottomToTop)
X    {
X	y = pixvert - ICON_GRID_HEIGHT*slot->ma - win->core.height;
X	if (SOminor == SOLeftToRight)
X	{
X	    x = ICON_GRID_WIDTH*slot->mi;
X	}
X	else
X	{
X	    x = pixhoriz - slot->mi*ICON_GRID_WIDTH - win->core.width;
X	}
X    }
X    else if (SOmajor == SOLeftToRight)
X    {
X	x = ICON_GRID_WIDTH*slot->ma;
X	if (SOminor == SOTopToBottom)
X	{
X	    y = ICON_GRID_HEIGHT*slot->mi;
X	}
X	else
X	{
X	    y = pixvert - slot->mi*ICON_GRID_HEIGHT - win->core.height;
X	}
X    }
X    else if (SOmajor == SORightToLeft)
X    {
X	x = pixhoriz - ICON_GRID_WIDTH*slot->ma - win->core.width;
X	if (SOminor == SOTopToBottom)
X	{
X	    y = ICON_GRID_HEIGHT*slot->mi;
X	}
X	else
X	{
X	    y = pixvert - slot->mi*ICON_GRID_HEIGHT - win->core.height;
X	}
X    }
X
X    (WinFunc(win,core.newposfunc))(win,x,y);
X}
X
X/* incrPositionedSlots -- an icon has been explicitly positioned; create an
X * iconslot record and increment the occupancy count of the affected slots.
X */
static IconSlot *
incrPositionedSlots(x,y,w,h,snaptogrid)
int x,y,w,h;
Bool snaptogrid;
X{
X	IconSlot *slot = MemNew(IconSlot);
X#define ROUNDIF(v,w) (snaptogrid?ROUND((v),(w)):(v))/(w)
X#define ROUNDDIM(p,s,w) (ROUNDUP(((p)%(w))+(s),(w)))
X
X	if (SOmajor == SOTopToBottom)
X	{
X	    slot->ma = ROUNDIF(y,ICON_GRID_HEIGHT);
X	    slot->maw = ROUNDDIM(y,h,ICON_GRID_HEIGHT);
X	    if (SOminor == SOLeftToRight)
X	    {
X		slot->mi = ROUNDIF(x,ICON_GRID_WIDTH);
X	        slot->miw = ROUNDDIM(x,w,ICON_GRID_WIDTH);
X	    }
X	    else
X	    {
X		slot->mi = ROUNDIF(pixhoriz-(x+w),ICON_GRID_WIDTH);
X	        slot->miw = ROUNDDIM(pixhoriz-(x+w),w,ICON_GRID_WIDTH);
X	    }
X	}
X	else if (SOmajor == SOBottomToTop)
X	{
X	    slot->ma = ROUNDIF(pixvert-(y+h),ICON_GRID_HEIGHT);
X	    slot->maw = ROUNDDIM(pixvert-(y+h),h,ICON_GRID_HEIGHT);
X	    slot->miw = w;
X	    if (SOminor == SOLeftToRight)
X	    {
X		slot->mi = ROUNDIF(x,ICON_GRID_WIDTH);
X	        slot->miw = ROUNDDIM(x,w,ICON_GRID_WIDTH);
X	    }
X	    else
X	    {
X		slot->mi = ROUNDIF(pixhoriz-(x+w),ICON_GRID_WIDTH);
X	        slot->miw = ROUNDDIM(pixhoriz-(x+w),w,ICON_GRID_WIDTH);
X	    }
X	}
X	else if (SOmajor == SOLeftToRight)
X	{
X	    slot->ma = ROUNDIF(x,ICON_GRID_WIDTH);
X	    slot->maw = ROUNDDIM(x,w,ICON_GRID_WIDTH);
X	    if (SOminor == SOTopToBottom)
X	    {
X		slot->mi = ROUNDIF(y,ICON_GRID_HEIGHT);
X		slot->miw = ROUNDDIM(y,h,ICON_GRID_HEIGHT);
X	    }
X	    else
X	    {
X		slot->mi = ROUNDIF(pixvert-(y+h),ICON_GRID_HEIGHT);
X		slot->miw = ROUNDDIM(pixvert-(y+h),h,ICON_GRID_HEIGHT);
X	    }
X	}
X	else if (SOmajor == SORightToLeft)
X	{
X	    slot->ma = ROUNDIF(pixhoriz-(x+w),ICON_GRID_WIDTH);
X	    slot->maw = ROUNDDIM(pixhoriz-(x+w),w,ICON_GRID_WIDTH);
X	    if (SOminor == SOTopToBottom)
X	    {
X		slot->mi = ROUNDIF(y,ICON_GRID_HEIGHT);
X		slot->miw = ROUNDDIM(y,h,ICON_GRID_HEIGHT);
X	    }
X	    else
X	    {
X		slot->mi = ROUNDIF(pixvert-(y+h),ICON_GRID_HEIGHT);
X		slot->miw = ROUNDDIM(pixvert-(y+h),h,ICON_GRID_HEIGHT);
X	    }
X	}
X	if (slot->ma < 0) slot->ma = 0;
X	if (slot->ma >= maslots) slot->ma = maslots-1;
X	if (slot->mi < 0) slot->mi = 0;
X	if (slot->mi >= mislots) slot->mi = mislots-1;
X	slot->positioned = True;
X	incrRegion(slot,1);
X	return slot;
X}
X
X
X/***************************************************************************
X* Global functions
X***************************************************************************/
X
X/*
X * SlotInit -- does nothing right now
X */
void 
SlotInit(dpy)
Display *dpy;
X{
X	if (occupancy != NULL)
X	{
X		ErrorGeneral("Tried to multiply initialise Slots module\n");
X	}
X
X	iconList = NULL_LIST;
X	pixhoriz = DisplayWidth(dpy,DefaultScreen(dpy));
X	pixvert = DisplayHeight(dpy,DefaultScreen(dpy));
X	slotshoriz = pixhoriz/ICON_GRID_WIDTH;
X	slotsvert = pixvert/ICON_GRID_HEIGHT;
X	occupancy = MemAlloc(slotshoriz*slotsvert*sizeof(int));
X	SlotSetLocations(dpy);
X}
X
X/* SlotAlloc - given a sized and possibly positioned icon window, allocate 
X * the appropriate slots for it.  If the window is positioned, 
X * True should be passed for the second parameter, and the x,y
X * position will be honoured.  If the window is not positioned, it
X * will be positioned by this function to the appropriate slots(s).
X * If snaptogrid is true and positioned is true, the given position is
X * modified so that the upper left corner of the icon is at the closest
X * icon grid point.  Modifies the icon structure to assign it the icon
X * slot.
X * Returns an IconSlot pointer if successful; NULL otherwise.
X */
struct _iconSlot * 
SlotAlloc(winicon, positioned, snaptogrid)
WinIconFrame *winicon;
Bool positioned;
Bool snaptogrid;
X{
X    int nhoriz, nvert;	/* number of slots occupied, horizontally & vertically */
X    int nmajor, nminor;	/* number of slots occupied, in major & minor directions */
X    IconSlot *slot;
X
X    iconList = ListCons(winicon, iconList);
X
X    if (positioned)
X    {
X	slot = incrPositionedSlots(winicon->core.x, winicon->core.y, 
X		winicon->core.width, winicon->core.height, snaptogrid);
X	winicon->iconslot = slot;
X	if (snaptogrid)
X	    setIconPos(winicon,slot);
X	else
X	    (WinFunc(winicon,core.newposfunc))(winicon,winicon->core.x,winicon->core.y);
X    }
X    else
X    {
X        nhoriz = ROUNDUP(winicon->core.width, ICON_GRID_WIDTH);
X        nvert = ROUNDUP(winicon->core.height, ICON_GRID_HEIGHT);
X	setMajorMinor(nvert, nhoriz, &nmajor, &nminor);
X	slot = incrDynamicSlots(nmajor, nminor);
X	winicon->iconslot = slot;
X	setIconPos(winicon,slot);
X    }
X
X    return slot;
X}
X
X/* SlotFree -- An icon is going away, so its references to slots should also go
X * away.  Returns True iff the free was successful.
X * Note that if this code is changed, the similar code in SlotSetLocations
X * may need to be changed also.
X */
Bool 
SlotFree(winicon)
WinIconFrame *winicon;
X{
X	List **l;
X
X	if (winicon->iconslot == NULL)
X	{
X		return;
X	}
X
X	incrRegion(winicon->iconslot,-1);
X	MemFree(winicon->iconslot);
X	winicon->iconslot = NULL;
X
X	l = &iconList;
X	for (l = &iconList ; (*l) != NULL ; l = &((*l)->next))
X	{
X	    if ((WinIconFrame *)((*l)->value) == winicon)
X	    {
X		ListDestroyCell(l);
X		break;
X	    }
X	}
X}
X
X/* sets the order in which slots are allocated for icons which are
X * not explicitly positioned.  The order is gotten from the global
X * resource vector.
X * For example, the AlongBottom order is expressed as
X * major BottomToTop, minor LeftToRight.  The major and minor orders
X * cannot be both vertical or horizontal.  Any icons which were 
X * automatically positioned are repositioned to equivalent positions
X * in the new order.
X */
Bool 
SlotSetLocations(dpy)
Display *dpy;
X{
X	List *lauto, *lpos;
X	List **l;
X	WinIconFrame *win;
X	int ima, imi;
X
X	/* set up the new order of things */
X        switch (GRV.IconPlacement)
X        {
X        case AlongTop:
X		SOmajor = SOTopToBottom;
X		SOminor = SOLeftToRight;
X                break;
X
X        case AlongTopRL:
X		SOmajor = SOTopToBottom;
X		SOminor = SORightToLeft;
X                break;
X
X        case AlongBottom:
X		SOmajor = SOBottomToTop;
X		SOminor = SOLeftToRight;
X                break;
X
X        case AlongBottomRL:
X		SOmajor = SOBottomToTop;
X		SOminor = SORightToLeft;
X                break;
X
X        case AlongLeft:
X		SOmajor = SOLeftToRight;
X		SOminor = SOTopToBottom;
X                break;
X
X        case AlongLeftBT:
X		SOmajor = SOLeftToRight;
X		SOminor = SOBottomToTop;
X                break;
X
X        case AlongRight:
X		SOmajor = SORightToLeft;
X		SOminor = SOTopToBottom;
X                break;
X
X        case AlongRightBT:
X		SOmajor = SORightToLeft;
X		SOminor = SOBottomToTop;
X                break;
X        }
X
X	setMajorMinor(slotsvert,slotshoriz,&maslots,&mislots);
X
X	if (iconList == NULL_LIST)
X	{
X		for (ima = 0; ima<maslots; ima++)
X		    for (imi = 0; imi<mislots; imi++)
X			OCCUPANCY(ima,imi)=0;
X		return;
X	}
X
X	/* partition existing icons */
X	lauto = NULL_LIST;
X	lpos = NULL_LIST;
X	l = &iconList;
X	for (win = ListEnum(l); win != NULL; win = ListEnum(l))
X	{
X	    if (!win->iconslot->positioned)
X	    {
X		lauto = ListCons(win,lauto);
X	    }
X	    else
X	    {
X		lpos = ListCons(win,lpos);
X	    }
X	    /* this is the basics of a SlotFree */
X	    MemFree(win->iconslot);
X	    win->iconslot = NULL;
X	}
X	ListDestroy(iconList);
X	iconList = NULL_LIST;
X
X	for (ima = 0; ima<maslots; ima++)
X	    for (imi = 0; imi<mislots; imi++)
X		OCCUPANCY(ima,imi)=0;
X
X	/* place positioned icons */
X	l = &lpos;
X	for (win = ListEnum(l); win != NULL; win = ListEnum(l))
X	{
X	    SlotAlloc(win,True,False);
X	    (WinFunc(win,core.setconfigfunc))(win->core.client->dpy,win);
X	}
X	ListDestroy(lpos);
X
X	/* place auto-positioned icons */
X	l = &lauto;
X	for (win = ListEnum(l); win != NULL; win = ListEnum(l))
X	{
X	    SlotAlloc(win,False,False);
X	    (WinFunc(win,core.setconfigfunc))(win->core.client->dpy,win);
X	}
X	ListDestroy(lauto);
X}
END_OF_FILE
if test 14674 -ne `wc -c <'slots.c'`; then
    echo shar: \"'slots.c'\" unpacked with wrong size!
fi
# end of 'slots.c'
fi
if test -f 'win.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'win.h'\"
else
echo shar: Extracting \"'win.h'\" \(14880 characters\)
sed "s/^X//" >'win.h' <<'END_OF_FILE'
X/*
X *      (c) Copyright 1989 Sun Microsystems, Inc. Sun design patents
X *      pending in the U.S. and foreign countries. See LEGAL_NOTICE
X *      file for terms of the license.
X *
X *	Written for Sun Microsystems by Crucible, Santa Cruz, CA.
X */
X
X/* @(#)win.h	1.2 olvwm version 3/30/91 */
X/* based on @(#) win.h 25.8 90/05/23 Crucible */
X
X#include "list.h"
X
X/***************************************************************************
X* Client state structures
X***************************************************************************/
X
X/*
X * The following structure is defined in Xutil.h, but it differs between X11R3
X * and X11R4 to reflect the acceptance of the ICCCM (version 1.0) as a
X * Consortium standard.  This replacement is necessary so that olwm can be
X * assured of getting the right structure, independent of the include files
X * present on the system it's compiled on.  Defining this this way allows olwm
X * to accomodate clients that use the R4-based structure as well as older
X * clients.
X */
typedef struct {
X	long	flags;
X	struct {
X	    int x;
X	    int y;
X	    int width;
X	    int height;
X	} pad;			/* x, y, w, h replaced by pad[4] for X11R4 */
X	int	min_width;
X	int	min_height;
X	int	max_width;
X	int	max_height;
X	int	width_inc;
X	int	height_inc;
X	struct	{
X	    int x;
X	    int y;
X	} min_aspect, max_aspect;
X	int	base_width;	/* added in X11R4 */
X	int	base_height;	/* added in X11R4 */
X	int	win_gravity;	/* added in X11R4 */
X} NewXSizeHints;
X
X/*
X * The following definitions are new in ICCCM version 1.0.  Olwm requires 
X * them, but they may not be present if olwm is being compiled against an old 
X * version of Xutil.h (e.g. from X11R3).  We define them here if necessary.
X */
X
X#ifndef PBaseSize
X#define PBaseSize	(1L << 8) /* program specified base for incrementing */
X#endif
X
X#ifndef PWinGravity
X#define PWinGravity	(1L << 9) /* program specified window gravity */
X#endif
X
X#ifndef WithdrawnState
X#define WithdrawnState 0        /* for windows that are not mapped */
X#endif
X
X/* a type for the four possible focus modes */
typedef enum { Passive, NoInput, LocallyActive, GloballyActive } FocusMode;
X
typedef struct {
X        long flags;
X        enum {
X                MENU_FULL = 0,          /* Close, Zoom, Props, Scale, Back,
X                                         * Refresh, Quit
X                                         */
X                MENU_LIMITED = 1,       /* Dismiss, Scale, Refresh */
X                MENU_NONE = 2,  	/* No Menu */
X        } menu_type;
X        int pushpin_initial_state;
X	/* numbers assigned as per OLXCI 3/20/89 */
X} WMDecorations;
X
X/* pin states numbers, as per OLXCI 3/20/89 */
X#define PIN_OUT 0
X#define PIN_IN 1
X
X/* value for flags */
X#define WMDecorationHeader      (1L<<0)
X#define WMDecorationFooter      (1L<<1)
X#define WMDecorationPushPin     (1L<<2)
X#define WMDecorationCloseButton (1L<<3)
X#define WMDecorationHeaderDeco (WMDecorationPushPin | WMDecorationCloseButton)
X#define WMDecorationOKButton    (1L<<4)
X#define WMDecorationResizeable  (1L<<5)
X
X/* window kinds */
typedef enum { OLBASEWINDOW, OLCMDWINDOW, OLPROPWINDOW, OLHELPWINDOW,
X	OLNOTICEWINDOW, OLOTHERWINDOW, OLTRANSIENTWINDOW, OLSPECIAL,
X	OLMINIMALDECOR } OLType;
X
typedef int WMState;	/* use state codes in Xutil.h */
X
typedef struct {	/* pointer warp state data */
X	int		warpToX, warpToY;	/* where to pointer goes on warp */
X	int		dflButtonX, dflButtonY;	/* location of default button */
X	int		dflButtonW, dflButtonH;	/* size of default button */
X	Window		warpBackWin;		/* return warp window */
X	int		warpBackX, warpBackY;	/* where to put it back */
X} WarpInfo;
X
X/***************************************************************************
X* Client structures
X***************************************************************************/
X
X/* a top-level client window */
X
typedef struct _client
X{
X	OLType		*olType;
X	WMDecorations	*wmDecors;
X	WMState		wmState;
X	NewXSizeHints	*normHints;	/* WM_NORMAL_HINTS */
X	XWMHints	*wmHints;	/* WM_HINTS */
X	char		*wmInstance;	/* WM_CLASS instance name */
X	char		*wmClass;	/* WM_CLASS class name */
X	Bool		hasMessages;	/* WM_HINTS has obsolete fields */
X	int 		protocols;
X	FocusMode	focusMode;
X	Bool		isFocus;
X	Bool		isSelected;
X	Bool		isBusy;
X	Display		*dpy;
X	int		screen;
X	struct _winpaneframe *framewin;	
X	struct _winiconframe *iconwin;
X	WarpInfo	warpInfo;
X	Window		groupid;	/* Actually GroupID */
X	unsigned int	groupmask;	/* role that client is playing in group */
X	long		busyState;
X	List		*colormapWins;
X	int		sticky;
X	Window		virtualWindow;
X	int		root;
X	Window		virtualInactive;
X} Client;
X
X
X/***************************************************************************
X* Window class structures
X***************************************************************************/
X
X/* classes of window which we can deal with */
typedef enum { WIN_FRAME, WIN_ICON, WIN_RESIZE, WIN_PUSHPIN, WIN_WINBUTTON,
X	WIN_PANE, WIN_ICONPANE, WIN_COLORMAP, WIN_MENU, WIN_NOFOCUS, 
X	WIN_ROOT, WIN_BUSY } WinKind;
X
typedef int (*EvFunc)();
typedef int (*IntFunc)();
typedef struct _genericclasscore {
X	WinKind kind;
X	EvFunc xevents[LASTEvent];	/* function for each X event */
X	EvFunc focusfunc;	/* focus state has changed */
X	EvFunc drawfunc;	/* draw window */
X	EvFunc destroyfunc;	/* destroy window and structures */
X	EvFunc selectfunc;	/* selecte state has changed */
X	EvFunc newconfigfunc;  	/* compute configuration */
X	EvFunc newposfunc;     	/* set position */
X	EvFunc setconfigfunc;  	/* set configuration */
X	EvFunc createcallback; 	/* used in menu creation */
X	IntFunc heightfunc;	/* compute correct height */
X	IntFunc widthfunc;	/* compute correct width */
X} GenericClassCore;
X
typedef struct _classgeneric {
X	GenericClassCore core;
X} ClassGeneric;
X
typedef struct _genericframeclasscore {
X	IntFunc heighttop, heightbottom, widthleft, widthright;
X	IntFunc menuPress;
X	IntFunc adjustPress, adjustClick;
X	IntFunc selectPress, selectClick, selectDoubleClick, selectDrag;
X} GenericFrameClassCore;
X
typedef struct _classgenericframe {
X	GenericClassCore core;
X	GenericFrameClassCore fcore;
X} ClassGenericFrame;
X
typedef struct _genericpaneclasscore {
X	EvFunc setsizefunc;
X} GenericPaneClassCore;
X
typedef struct _classpane {
X	GenericClassCore core;
X	GenericPaneClassCore pcore;
X} ClassGenericPane;
X
typedef ClassGenericFrame ClassPaneFrame;
typedef ClassGenericFrame ClassIconFrame;
typedef ClassGeneric ClassPushPin;
typedef ClassGenericPane ClassPane;
typedef ClassGenericPane ClassMenu;
typedef ClassGeneric ClassResize;
typedef ClassGeneric ClassButton;
typedef ClassGeneric ClassBusy;
typedef ClassGenericPane ClassIconPane;
typedef ClassGeneric ClassRoot;
typedef ClassGeneric ClassNoFocus;
typedef ClassGeneric ClassColormap;
X
X/* Core functions:
X *
X * destroyfunc - int (*destroyfunc)(Display *dpy, WinGeneric *win)
X *   Called when the window is being destroyed; should destroy any private
X *   resources associated with the window (including possibly destroying
X *   the X window) and destroy the window information structure.
X *
X * selectfunc - int (*selectfunc)(Display *dpy, WinGeneric *win, Bool selected)
X *   Called whenever the window is selected/deselected.  The window should
X *   update its private state -- most particularly, its screen appearance --
X *   to match the new state.  This function is only called when the selection
X *   state has changed.
X *
X * focusfunc - int (*focusfunc)(Display *dpy, WinGeneric *win, Bool focus)
X *   Called whenever the window gains/loses focus.  The window should update
X *   its private state -- most particularly, its screen appearance --
X *   to match the new state.  The window does _not_ need to take focus if
X *   it is active; this has already been taken care of.  This function is
X *   only called when the focus has changed.
X *
X * newconfigfunc - int (*newconfigfunc)(WinGeneric *win, 
X *			XConfigureRequestEvent *xcre)
X *   Called when the configuration of a window should be recomputed.  It
X *   can be assumed that all child windows will have already computed their
X *   sizes.  This function should compute the size of this window, and call
X *   the newposfunc of each child that needs to be moved.  If the configuration
X *   of the window is changed by this function, the dirtyconfig flag should be
X *   set.  The xcre parameter will be be set to a configure request event
X *   structure only if a configure request was received for this
X *   particular window; otherwise the parameter will be null.
X *   Returns True if any dirtyconfig flag has been set.
X *
X * newposfunc - int (*newposfunc)(WinGeneric *win, int x, y)
X *   Instructs a child window to move to a position (x,y).  If this position
X *   is different from the old position, then the dirtyconfig flag
X *   should be set.  Returns True if any dirtyconfig flag has been set.
X *
X * setconfigfunc - int (*setconfigfunc)(Display *dpy, WinGeneric *win)
X *   The window's configuration may have changed; if so, call XConfigureWindow
X *   to make the changes.  Clear the dirtyconfig bits in the process.
X *   The pane window will need to send a synthetic configure notify for
X *   any configuration call.
X *
X * createcallback - int (*createcallback)(WinGeneric *self, Client *cli, 
X *			WinGeneric *parent)
X *   For internally-created panes, the client and parent are filled out
X *   when the StateNew process would normally create a pane.
X *
X * heightfunc - int (*heightfunc)(WinGeneric *self, XConfigureRequestEvent *pxcre)
X *   should return the window's correct height, given a configure request
X *   event and the current environment.  Used to see if a window needs to 
X *   be resized.
X * 
X * widthfunc - same as heightfunc, except that it returns correct width
X */
X
X/***************************************************************************
X* Window instance structures
X***************************************************************************/
X
X/*
X * The wincore structure contains common information about each window.
X *
X * stack_mode, stack_sib, and dirtyconfig contain information pending window 
X * configuration changes that have not yet been sent to the server.
X *
X * exposures is a list of exposed rectangles that have not yet been repainted.
X *
X * colormapClients is a list of clients that have this window in their 
X * colormapWins list.  tag is used only while processing changes to a client's 
X * colormapWins list.
X */
typedef struct _wincore {
X	Window			self;
X	WinKind			kind;
X	struct _wingeneric 	*parent;
X	List			*children;
X	Client			*client;
X	int			x, y;
X	unsigned int		width, height;
X	int			stack_mode;
X	Window			stack_sib;
X	unsigned int		dirtyconfig;
X	Colormap		colormap;
X	List			*exposures;
X	List			*colormapClients;
X	Bool			tag;
X} WinCore;
X/* REMIND maybe add: cursor */
X
X/* macros associated with a window core */
X#define WinIsKind(w,k) ((w)->core.kind == (k))
X#define WinClass(w) ((w)->class)
X#define WinFunc(w,f) ((w)->class->f)
X
X/* FrameCore defines fields common to all types of frame */
typedef struct _winframecore {
X	struct _wingenericpane *panewin;	/* pane inside frame */
X	char *name;		/* name to be displayed on frame */
X	void *menu;		/* actually Menu * */
X} WinFrameCore;
X
X/* PaneCore defines fields common to all types of panes */
typedef struct _winpanecore {
X	int		oldBorderWidth;
X	int		oldSaveUnder;
X	int		pendingUnmaps;
X} WinPaneCore;
X
X/* Specific window types */
X
typedef struct _wingeneric {
X	ClassGeneric	*class;
X	WinCore		core;
X} WinGeneric;
X
typedef struct _wingenericframe {
X	ClassGenericFrame *class;
X	WinCore 	core;
X	WinFrameCore	fcore;
X} WinGenericFrame;
X
X/* macros for generic frames */
X#define FrameHeightTop(w) (WinFunc((w),fcore.heighttop))((w))
X#define FrameHeightBottom(w) (WinFunc((w),fcore.heightbottom))((w))
X#define FrameWidthLeft(w) (WinFunc((w),fcore.widthleft))((w))
X#define FrameWidthRight(w) (WinFunc((w),fcore.widthright))((w))
X
X
typedef struct _wingenericpane {
X	ClassGenericPane *class;
X	WinCore core;
X	WinPaneCore pcore;
X} WinGenericPane;
X
typedef struct _winpaneframe {
X	ClassPaneFrame 		*class;
X	WinCore			core;
X	WinFrameCore		fcore;
X
X	/* footer fields */
X	char			*leftfooter;
X	int			leftfooterLength, leftfooterWidth;
X	char			*rightfooter;
X	int			rightfooterLength, rightfooterWidth;
X
X	/* title fields */
X	int			titleOff;	/* x offset of title area in pix */
X	int			nameLength;	/* length of name in chars */
X	int			nameWidth;	/* width of name in pix */
X	int			titlex, titley;	/* title position */
X
X	/* pointer warp status */
X	Bool			pointerIsWarped;
X
X	/* sizing functions */
X	void (*normfullsizefunc)();	/* normal/full size function */
X	Bool restoreSet;		/* True => restore values valid */
X	int			restoreY, restoreWidth, restoreHeight;
X					/* context for full/norm size 
X					 * note that y is frame; w/h are pane
X					 */
X
X	/* other decorations */
X	WinGeneric *winDeco;	/* window button or pushpin */
X	struct _winbusy *winBusy; /* special window when busy */
X} WinPaneFrame;
X
typedef struct _winiconframe {
X	ClassIconFrame *class;
X	WinCore		core;
X	WinFrameCore	fcore;
X	struct _iconSlot *iconslot;
X	Bool		fManuallyPositioned;
X	int		nameX, nameY;		/* name of icon */
X	int		nameWidth;
X	int		nameLength;
X} WinIconFrame;
X
typedef struct _winiconpane {
X	ClassIconPane 	*class;
X	WinCore 	core;
X	WinPaneCore 	pcore;
X	Bool		iconClientWindow;	/* true iff client owns pane */
X	Pixmap		iconPixmap;		/* None if icon has client window */
X#ifdef OBSOLETE
X	int		iconX, iconY;		/* geometry of iconDrawable */
X	unsigned int	iconWidth, iconHeight;
X#endif
X} WinIconPane;
X
typedef struct _winpushpin {
X	ClassPushPin *class;
X	WinCore		core;
X	Bool		pushpinin;
X} WinPushPin;
X
typedef struct _winpane {
X	ClassPane *class;
X	WinCore 	core;
X	WinPaneCore	pcore;
X} WinPane;
X
typedef struct _winmenu {		/* menus are a subclass of panes */
X	ClassMenu *class;
X	WinCore		core;
X	WinPaneCore	pcore;
X	Bool		pushpinin;
X	void		*menu;	/* actually Menu * */
X} WinMenu;
X
typedef enum {upleft, upright, lowleft, lowright} WhichResize;
X
typedef struct _winresize {
X	ClassResize *class;
X	WinCore		core;
X	WhichResize	which;
X	Bool		depressed;
X} WinResize;
X
typedef struct _winbutton {
X	ClassButton *class;
X	WinCore		core;
X} WinButton;
X
typedef struct _winbusy {
X	ClassBusy *class;
X	WinCore core;
X	Bool isFocus;
X} WinBusy;
X
typedef WinGeneric WinRoot;
typedef WinGeneric WinNoFocus;
X
X/* colormap windows aren't linked into the ordinary window tree since they
X * are presumed under client control.  We create info structures for them 
X * only so appropriate events can be dispatched on them.  Colormap windows
X * are in a list on the client structure.
X */
typedef WinGeneric WinColormap;
X
X/* functions mapping windows to infos */
X
extern void WIInstallInfo();
extern Bool WIUninstallInfo();
extern WinGeneric *WIGetInfo();
extern void WIApply();
X
X/* window functions */
extern void WinAddChild();
extern void WinRemoveChild();
X
X/* Useful client macros */
X#define PANEOFCLIENT(cli) ((cli)->framewin->fcore.panewin)
X#define PANEWINOFCLIENT(cli) (PANEOFCLIENT(cli)->core.self)
END_OF_FILE
if test 14880 -ne `wc -c <'win.h'`; then
    echo shar: \"'win.h'\" unpacked with wrong size!
fi
# end of 'win.h'
fi
echo shar: End of archive 6 \(of 16\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 16 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

--
Dan Heller
O'Reilly && Associates       Z-Code Software    Comp-sources-x:
Senior Writer                President          comp-sources.x at uunet.uu.net
argv at ora.com                 argv at zipcode.com



More information about the Comp.sources.x mailing list