[comp.sources.x] v09i009: TWM with a virtual root window, Part08/09

toml@marvin.Solbourne.COM (Tom LaStrange) (08/30/90)

Submitted-by: toml@marvin.Solbourne.COM (Tom LaStrange)
Posting-number: Volume 9, Issue 9
Archive-name: tvtwm/part08

#! /bin/sh
# This is a shell archive, meaning:
# 1.  Remove everything above the #! /bin/sh line.
# 2.  Save the resulting test in a file
# 3.  Execute the file with /bin/sh (not csh) to create the files:
#
#util.c
#util.h
#vdt.c
#vdt.h
#version.c
#version.h
#
# Created by toml () on Wed Aug 29 08:43:39 MDT 1990
#
if test -f 'util.c'
then
    echo shar: will not over-write existing file "util.c"
else
echo extracting "util.c"
sed 's/^X//' >util.c <<'SHAR_EOF'
X/*****************************************************************************/
X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
X/**                          Salt Lake City, Utah                           **/
X/**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
X/**                        Cambridge, Massachusetts                         **/
X/**                                                                         **/
X/**                           All Rights Reserved                           **/
X/**                                                                         **/
X/**    Permission to use, copy, modify, and distribute this software and    **/
X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
X/**    granted, provided that the above copyright notice appear  in  all    **/
X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
X/**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
X/**    in publicity pertaining to distribution of the  software  without    **/
X/**    specific, written prior permission.                                  **/
X/**                                                                         **/
X/**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
X/**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
X/**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
X/**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
X/**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
X/**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
X/**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
X/**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
X/*****************************************************************************/
X
X
X/***********************************************************************
X *
X * $XConsortium: util.c,v 1.39 90/03/16 12:06:46 jim Exp $
X *
X * utility routines for twm
X *
X * 28-Oct-87 Thomas E. LaStrange	File created
X *
X ***********************************************************************/
X
X#if !defined(lint) && !defined(SABER)
Xstatic char RCSinfo[]=
X"$XConsortium: util.c,v 1.39 90/03/16 12:06:46 jim Exp $";
X#endif
X
X#include <stdio.h>
X#include "twm.h"
X#include "util.h"
X#include "gram.h"
X#include "screen.h"
X#include <X11/Xos.h>
X#include <X11/Xatom.h>
X#include <X11/Xmu/Drawing.h>
X#include <X11/Xmu/CharSet.h>
X
Xstatic Pixmap CreateXLogoPixmap(), CreateResizePixmap();
Xstatic Pixmap CreateQuestionPixmap(), CreateMenuPixmap();
Xint HotX, HotY;
X
X/***********************************************************************
X *
X *  Procedure:
X *	MoveOutline - move a window outline
X *
X *  Inputs:
X *	root	    - the window we are outlining
X *	x	    - upper left x coordinate
X *	y	    - upper left y coordinate
X *	width	    - the width of the rectangle
X *	height	    - the height of the rectangle
X *      bw          - the border width of the frame
X *      th          - title height
X *
X ***********************************************************************
X */
X
X/* ARGSUSED */
Xvoid MoveOutline(root, x, y, width, height, bw, th)
X    Window root;
X    int x, y, width, height, bw, th;
X{
X    static int	lastx = 0;
X    static int	lasty = 0;
X    static int	lastWidth = 0;
X    static int	lastHeight = 0;
X    static int	lastBW = 0;
X    static int	lastTH = 0;
X    int		xl, xr, yt, yb, xinnerl, xinnerr, yinnert, yinnerb;
X    int		xthird, ythird;
X    XSegment	outline[18];
X    register XSegment	*r;
X
X    if (x == lastx && y == lasty && width == lastWidth && height == lastHeight
X	&& lastBW == bw && th == lastTH)
X	return;
X    
X    r = outline;
X
X#define DRAWIT() \
X    if (lastWidth || lastHeight)			\
X    {							\
X	xl = lastx;					\
X	xr = lastx + lastWidth - 1;			\
X	yt = lasty;					\
X	yb = lasty + lastHeight - 1;			\
X	xinnerl = xl + lastBW;				\
X	xinnerr = xr - lastBW;				\
X	yinnert = yt + lastTH + lastBW;			\
X	yinnerb = yb - lastBW;				\
X	xthird = (xinnerr - xinnerl) / 3;		\
X	ythird = (yinnerb - yinnert) / 3;		\
X							\
X	r->x1 = xl;					\
X	r->y1 = yt;					\
X	r->x2 = xr;					\
X	r->y2 = yt;					\
X	r++;						\
X							\
X	r->x1 = xl;					\
X	r->y1 = yb;					\
X	r->x2 = xr;					\
X	r->y2 = yb;					\
X	r++;						\
X							\
X	r->x1 = xl;					\
X	r->y1 = yt;					\
X	r->x2 = xl;					\
X	r->y2 = yb;					\
X	r++;						\
X							\
X	r->x1 = xr;					\
X	r->y1 = yt;					\
X	r->x2 = xr;					\
X	r->y2 = yb;					\
X	r++;						\
X							\
X	r->x1 = xinnerl + xthird;			\
X	r->y1 = yinnert;				\
X	r->x2 = r->x1;					\
X	r->y2 = yinnerb;				\
X	r++;						\
X							\
X	r->x1 = xinnerl + (2 * xthird);			\
X	r->y1 = yinnert;				\
X	r->x2 = r->x1;					\
X	r->y2 = yinnerb;				\
X	r++;						\
X							\
X	r->x1 = xinnerl;				\
X	r->y1 = yinnert + ythird;			\
X	r->x2 = xinnerr;				\
X	r->y2 = r->y1;					\
X	r++;						\
X							\
X	r->x1 = xinnerl;				\
X	r->y1 = yinnert + (2 * ythird);			\
X	r->x2 = xinnerr;				\
X	r->y2 = r->y1;					\
X	r++;						\
X							\
X	if (lastTH != 0) {				\
X	    r->x1 = xl;					\
X	    r->y1 = yt + lastTH;			\
X	    r->x2 = xr;					\
X	    r->y2 = r->y1;				\
X	    r++;					\
X	}						\
X    }
X
X    /* undraw the old one, if any */
X    DRAWIT ();
X
X    lastx = x;
X    lasty = y;
X    lastWidth = width;
X    lastHeight = height;
X    lastBW = bw;
X    lastTH = th;
X
X    /* draw the new one, if any */
X    DRAWIT ();
X
X#undef DRAWIT
X
X
X    if (r != outline)
X    {
X	XDrawSegments(dpy, root, Scr->DrawGC, outline, r - outline);
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	Zoom - zoom in or out of an icon
X *
X *  Inputs:
X *	wf	- window to zoom from
X *	wt	- window to zoom to
X *
X ***********************************************************************
X */
X
Xvoid
XZoom(wf, wt)
X    Window wf, wt;
X{
X    int fx, fy, tx, ty;			/* from, to */
X    unsigned int fw, fh, tw, th;	/* from, to */
X    long dx, dy, dw, dh;
X    long z;
X    int j;
X
X    if (!Scr->DoZoom || Scr->ZoomCount < 1) return;
X
X    if (wf == None || wt == None) return;
X
X    XGetGeometry (dpy, wf, &JunkRoot, &fx, &fy, &fw, &fh, &JunkBW, &JunkDepth);
X    XGetGeometry (dpy, wt, &JunkRoot, &tx, &ty, &tw, &th, &JunkBW, &JunkDepth);
X
X    dx = ((long) (tx - fx));	/* going from -> to */
X    dy = ((long) (ty - fy));	/* going from -> to */
X    dw = ((long) (tw - fw));	/* going from -> to */
X    dh = ((long) (th - fh));	/* going from -> to */
X    z = (long) (Scr->ZoomCount + 1);
X
X    for (j = 0; j < 2; j++) {
X	long i;
X
X	XDrawRectangle (dpy, Scr->Root, Scr->DrawGC, fx, fy, fw, fh);
X	for (i = 1; i < z; i++) {
X	    int x = fx + (int) ((dx * i) / z);
X	    int y = fy + (int) ((dy * i) / z);
X	    unsigned width = (unsigned) (((long) fw) + (dw * i) / z);
X	    unsigned height = (unsigned) (((long) fh) + (dh * i) / z);
X	
X	    XDrawRectangle (dpy, Scr->Root, Scr->DrawGC,
X			    x, y, width, height);
X	}
X	XDrawRectangle (dpy, Scr->Root, Scr->DrawGC, tx, ty, tw, th);
X    }
X}
X
X
X/***********************************************************************
X *
X *  Procedure:
X *	ExpandFilename - expand the tilde character to HOME
X *		if it is the first character of the filename
X *
X *  Returned Value:
X *	a pointer to the new name
X *
X *  Inputs:
X *	name	- the filename to expand
X *
X ***********************************************************************
X */
X
Xchar *
XExpandFilename(name)
Xchar *name;
X{
X    char *newname;
X
X    if (name[0] != '~') return name;
X
X    newname = (char *) malloc (HomeLen + strlen(name) + 2);
X    if (!newname) {
X	fprintf (stderr, 
X		 "%s:  unable to allocate %d bytes to expand filename %s/%s\n",
X		 ProgramName, HomeLen + strlen(name) + 2, Home, &name[1]);
X    } else {
X	(void) sprintf (newname, "%s/%s", Home, &name[1]);
X    }
X
X    return newname;
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	GetUnknownIcon - read in the bitmap file for the unknown icon
X *
X *  Inputs:
X *	name - the filename to read
X *
X ***********************************************************************
X */
X
Xvoid
XGetUnknownIcon(name)
Xchar *name;
X{
X    if ((Scr->UnknownPm = GetBitmap(name)) != None)
X    {
X	XGetGeometry(dpy, Scr->UnknownPm, &JunkRoot, &JunkX, &JunkY,
X	    (unsigned int *)&Scr->UnknownWidth, (unsigned int *)&Scr->UnknownHeight, &JunkBW, &JunkDepth);
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	FindBitmap - read in a bitmap file and return size
X *
X *  Returned Value:
X *	the pixmap associated with the bitmap
X *      widthp	- pointer to width of bitmap
X *      heightp	- pointer to height of bitmap
X *
X *  Inputs:
X *	name	- the filename to read
X *
X ***********************************************************************
X */
X
XPixmap FindBitmap (name, widthp, heightp)
X    char *name;
X    unsigned int *widthp, *heightp;
X{
X    char *bigname;
X    Pixmap pm;
X
X    if (!name) return None;
X
X    /*
X     * Names of the form :name refer to hardcoded images that are scaled to
X     * look nice in title buttons.  Eventually, it would be nice to put in a
X     * menu symbol as well....
X     */
X    if (name[0] == ':') {
X	int i;
X	static struct {
X	    char *name;
X	    Pixmap (*proc)();
X	} pmtab[] = {
X	    { TBPM_XLOGO,	CreateXLogoPixmap },
X	    { TBPM_ICONIFY,	CreateXLogoPixmap },
X	    { TBPM_RESIZE,	CreateResizePixmap },
X	    { TBPM_QUESTION,	CreateQuestionPixmap },
X	    { TBPM_MENU,	CreateMenuPixmap },  /* XXX - don't doc, niy */
X	};
X	
X	for (i = 0; i < (sizeof pmtab)/(sizeof pmtab[0]); i++) {
X	    if (XmuCompareISOLatin1 (pmtab[i].name, name) == 0)
X	      return (*pmtab[i].proc) (widthp, heightp);
X	}
X	fprintf (stderr, "%s:  no such built-in bitmap \"%s\"\n",
X		 ProgramName, name);
X	return None;
X    }
X
X    /*
X     * Generate a full pathname if any special prefix characters (such as ~)
X     * are used.  If the bigname is different from name, bigname will need to
X     * be freed.
X     */
X    bigname = ExpandFilename (name);
X    if (!bigname) return None;
X
X    /*
X     * look along bitmapFilePath resource same as toolkit clients
X     */
X    pm = XmuLocateBitmapFile (ScreenOfDisplay(dpy, Scr->screen), bigname,
X			      NULL, 0, widthp, heightp, &HotX, &HotY);
X    if (pm == None && Scr->IconDirectory && bigname[0] != '/') {
X	if (bigname != name) free (bigname);
X	/*
X	 * Attempt to find icon in old IconDirectory (now obsolete)
X	 */
X	bigname = (char *) malloc (strlen(name) + strlen(Scr->IconDirectory) +
X				   2);
X	if (!bigname) {
X	    fprintf (stderr,
X		     "%s:  unable to allocate memory for \"%s/%s\"\n",
X		     ProgramName, Scr->IconDirectory, name);
X	    return None;
X	}
X	(void) sprintf (bigname, "%s/%s", Scr->IconDirectory, name);
X	if (XReadBitmapFile (dpy, Scr->Root, bigname, widthp, heightp, &pm,
X			     &HotX, &HotY) != BitmapSuccess) {
X	    pm = None;
X	}
X    }
X    if (bigname != name) free (bigname);
X    if (pm == None) {
X	fprintf (stderr, "%s:  unable to find bitmap \"%s\"\n", 
X		 ProgramName, name);
X    }
X
X    return pm;
X}
X
XPixmap GetBitmap (name)
X    char *name;
X{
X    return FindBitmap (name, &JunkWidth, &JunkHeight);
X}
X
X
XInsertRGBColormap (a, maps, nmaps, replace)
X    Atom a;
X    XStandardColormap *maps;
X    int nmaps;
X    Bool replace;
X{
X    StdCmap *sc = NULL;
X
X    if (replace) {			/* locate existing entry */
X	for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) {
X	    if (sc->atom == a) break;
X	}
X    }
X
X    if (!sc) {				/* no existing, allocate new */
X	sc = (StdCmap *) malloc (sizeof (StdCmap));
X	if (!sc) {
X	    fprintf (stderr, "%s:  unable to allocate %d bytes for StdCmap\n",
X		     ProgramName, sizeof (StdCmap));
X	    return;
X	}
X    }
X
X    if (replace) {			/* just update contents */
X	if (sc->maps) XFree ((char *) maps);
X	if (sc == Scr->StdCmapInfo.mru) Scr->StdCmapInfo.mru = NULL;
X    } else {				/* else appending */
X	sc->next = NULL;
X	sc->atom = a;
X	if (Scr->StdCmapInfo.tail) {
X	    Scr->StdCmapInfo.tail->next = sc;
X	} else {
X	    Scr->StdCmapInfo.head = sc;
X	}
X	Scr->StdCmapInfo.tail = sc;
X    }
X    sc->nmaps = nmaps;
X    sc->maps = maps;
X
X    return;
X}
X
XRemoveRGBColormap (a)
X    Atom a;
X{
X    StdCmap *sc, *prev;
X
X    prev = NULL;
X    for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) {  
X	if (sc->atom == a) break;
X	prev = sc;
X    }
X    if (sc) {				/* found one */
X	if (sc->maps) XFree ((char *) sc->maps);
X	if (prev) prev->next = sc->next;
X	if (Scr->StdCmapInfo.head == sc) Scr->StdCmapInfo.head = sc->next;
X	if (Scr->StdCmapInfo.tail == sc) Scr->StdCmapInfo.tail = prev;
X	if (Scr->StdCmapInfo.mru == sc) Scr->StdCmapInfo.mru = NULL;
X    }
X    return;
X}
X
XLocateStandardColormaps()
X{
X    Atom *atoms;
X    int natoms;
X    int i;
X
X    atoms = XListProperties (dpy, Scr->Root, &natoms);
X    for (i = 0; i < natoms; i++) {
X	XStandardColormap *maps = NULL;
X	int nmaps;
X
X	if (XGetRGBColormaps (dpy, Scr->Root, &maps, &nmaps, atoms[i])) {
X	    /* if got one, then append to current list */
X	    InsertRGBColormap (atoms[i], maps, nmaps, False);
X	}
X    }
X    if (atoms) XFree ((char *) atoms);
X    return;
X}
X
XGetColor(kind, what, name)
Xint kind;
XPixel *what;
Xchar *name;
X{
X    XColor color, junkcolor;
X    Status stat = 0;
X    Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c;
X
X#ifndef TOM
X    if (!Scr->FirstTime)
X	return;
X#endif
X
X    if (Scr->Monochrome != kind)
X	return;
X
X    /*
X     * small hack to avoid extra roundtrip for color allocation
X     */
X    if (!((name[0] == '#')
X	  ? ((stat = XParseColor (dpy, cmap, name, &color)) &&
X	     XAllocColor (dpy, cmap, &color))
X	  : XAllocNamedColor (dpy, cmap, name, &color, &junkcolor)))
X    {
X	/* if we could not allocate the color, let's see if this is a
X	 * standard colormap
X	 */
X	XStandardColormap *stdcmap = NULL;
X
X	/* parse the named color */
X	if (name[0] != '#')
X	    stat = XParseColor (dpy, cmap, name, &color);
X	if (!stat)
X	{
X	    fprintf (stderr, "%s:  invalid color name \"%s\"\n", 
X		     ProgramName, name);
X	    return;
X	}
X
X	/*
X	 * look through the list of standard colormaps (check cache first)
X	 */
X	if (Scr->StdCmapInfo.mru && Scr->StdCmapInfo.mru->maps &&
X	    (Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex].colormap ==
X	     cmap)) {
X	    stdcmap = &(Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex]);
X	} else {
X	    StdCmap *sc;
X
X	    for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) {
X		int i;
X
X		for (i = 0; i < sc->nmaps; i++) {
X		    if (sc->maps[i].colormap == cmap) {
X			Scr->StdCmapInfo.mru = sc;
X			Scr->StdCmapInfo.mruindex = i;
X			stdcmap = &(sc->maps[i]);
X			goto gotit;
X		    }
X		}
X	    }
X	}
X
X      gotit:
X	if (stdcmap) {
X            color.pixel = (stdcmap->base_pixel +
X			   ((Pixel)((color.red / 65535.0) *
X				    stdcmap->red_max + 0.5) *
X			    stdcmap->red_mult) +
X			   ((Pixel)((color.green /65535.0) *
X				    stdcmap->green_max + 0.5) *
X			    stdcmap->green_mult) +
X			   ((Pixel)((color.blue  / 65535.0) *
X				    stdcmap->blue_max + 0.5) *
X			    stdcmap->blue_mult));
X        } else {
X	    fprintf (stderr, "%s:  unable to allocate color \"%s\"\n", 
X		     ProgramName, name);
X	    return;
X	}
X    }
X
X    *what = color.pixel;
X}
X
XGetFont(font)
XMyFont *font;
X{
X    char *deffontname = "fixed";
X
X    if (font->font != NULL)
X	XFreeFont(dpy, font->font);
X
X    if ((font->font = XLoadQueryFont(dpy, font->name)) == NULL)
X    {
X	if (Scr->DefaultFont.name) {
X	    deffontname = Scr->DefaultFont.name;
X	}
X	if ((font->font = XLoadQueryFont(dpy, deffontname)) == NULL)
X	{
X	    fprintf (stderr, "%s:  unable to open fonts \"%s\" or \"%s\"\n",
X		     ProgramName, font->name, deffontname);
X	    exit(1);
X	}
X
X    }
X    font->height = font->font->ascent + font->font->descent;
X    font->y = font->font->ascent;
X}
X
X
X/*
X * SetFocus - separate routine to set focus to make things more understandable
X * and easier to debug
X */
XSetFocus (tmp_win)
X    TwmWindow *tmp_win;
X{
X    Window w = (tmp_win ? tmp_win->w : PointerRoot);
X
X#ifdef TRACE
X    if (tmp_win) {
X	printf ("Focusing on window \"%s\"\n", tmp_win->full_name);
X    } else {
X	printf ("Unfocusing; Scr->Focus was \"%s\"\n",
X		Scr->Focus ? Scr->Focus->full_name : "(nil)");
X    }
X#endif
X
X    XSetInputFocus (dpy, w, RevertToPointerRoot, CurrentTime);
X}
X
X
X#ifdef NOPUTENV
X/*
X * define our own putenv() if the system doesn't have one.
X * putenv(s): place s (a string of the form "NAME=value") in
X * the environment; replacing any existing NAME.  s is placed in
X * environment, so if you change s, the environment changes (like
X * putenv on a sun).  Binding removed if you putenv something else
X * called NAME.
X */
Xint
Xputenv(s)
X    char *s;
X{
X    extern char *index();
X    char *v;
X    int varlen, idx;
X    extern char **environ;
X    char **newenv;
X    static int virgin = 1; /* true while "environ" is a virgin */
X
X    v = index(s, '=');
X    if(v == 0)
X	return 0; /* punt if it's not of the right form */
X    varlen = (v + 1) - s;
X
X    for (idx = 0; environ[idx] != 0; idx++) {
X	if (strncmp(environ[idx], s, varlen) == 0) {
X	    if(v[1] != 0) { /* true if there's a value */
X		environ[idx] = s;
X		return 0;
X	    } else {
X		do {
X		    environ[idx] = environ[idx+1];
X		} while(environ[++idx] != 0);
X		return 0;
X	    }
X	}
X    }
X    
X    /* add to environment (unless no value; then just return) */
X    if(v[1] == 0)
X	return 0;
X    if(virgin) {
X	register i;
X
X	newenv = (char **) malloc((unsigned) ((idx + 2) * sizeof(char*)));
X	if(newenv == 0)
X	    return -1;
X	for(i = idx-1; i >= 0; --i)
X	    newenv[i] = environ[i];
X	virgin = 0;     /* you're not a virgin anymore, sweety */
X    } else {
X	newenv = (char **) realloc((char *) environ,
X				   (unsigned) ((idx + 2) * sizeof(char*)));
X	if (newenv == 0)
X	    return -1;
X    }
X
X    environ = newenv;
X    environ[idx] = s;
X    environ[idx+1] = 0;
X    
X    return 0;
X}
X#endif /* NOPUTENV */
X
X
Xstatic Pixmap CreateXLogoPixmap (widthp, heightp)
X    unsigned int *widthp, *heightp;
X{
X    int h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
X    if (h < 0) h = 0;
X
X    *widthp = *heightp = (unsigned int) h;
X    if (Scr->tbpm.xlogo == None) {
X	GC gc, gcBack;
X
X	Scr->tbpm.xlogo = XCreatePixmap (dpy, Scr->Root, h, h, 1);
X	gc = XCreateGC (dpy, Scr->tbpm.xlogo, 0L, NULL);
X	XSetForeground (dpy, gc, 0);
X	XFillRectangle (dpy, Scr->tbpm.xlogo, gc, 0, 0, h, h);
X	XSetForeground (dpy, gc, 1);
X	gcBack = XCreateGC (dpy, Scr->tbpm.xlogo, 0L, NULL);
X	XSetForeground (dpy, gcBack, 0);
X
X	/*
X	 * draw the logo large so that it gets as dense as possible; then white
X	 * out the edges so that they look crisp
X	 */
X	XmuDrawLogo (dpy, Scr->tbpm.xlogo, gc, gcBack, -1, -1, h + 2, h + 2);
X	XDrawRectangle (dpy, Scr->tbpm.xlogo, gcBack, 0, 0, h - 1, h - 1);
X
X	/*
X	 * done drawing
X	 */
X	XFreeGC (dpy, gc);
X	XFreeGC (dpy, gcBack);
X    }
X    return Scr->tbpm.xlogo;
X}
X
X
Xstatic Pixmap CreateResizePixmap (widthp, heightp)
X    unsigned int *widthp, *heightp;
X{
X    int h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
X    if (h < 0) h = 0;
X
X    *widthp = *heightp = (unsigned int) h;
X    if (Scr->tbpm.resize == None) {
X	XSegment segs[4];
X	GC gc;
X	int w;
X
X	/*
X	 * create the pixmap
X	 */
X	Scr->tbpm.resize = XCreatePixmap (dpy, Scr->Root, h, h, 1);
X	gc = XCreateGC (dpy, Scr->tbpm.resize, 0L, NULL);
X	XSetForeground (dpy, gc, 0);
X	XFillRectangle (dpy, Scr->tbpm.resize, gc, 0, 0, h, h);
X	XSetForeground (dpy, gc, 1);
X
X	/*
X	 * draw the resize button, 
X	 */
X	w = (h * 2) / 3;
X	segs[0].x1 = w; segs[0].y1 = 0; segs[0].x2 = w; segs[0].y2 = w;
X	segs[1].x1 = 0; segs[1].y1 = w; segs[1].x2 = w; segs[1].y2 = w;
X	w = w / 2;
X	segs[2].x1 = w; segs[2].y1 = 0; segs[2].x2 = w; segs[2].y2 = w;
X	segs[3].x1 = 0; segs[3].y1 = w; segs[3].x2 = w; segs[3].y2 = w;
X	XDrawSegments (dpy, Scr->tbpm.resize, gc, segs, 4);
X
X	/*
X	 * done drawing
X	 */
X	XFreeGC(dpy, gc);
X    }
X    return Scr->tbpm.resize;
X}
X
X
X#define questionmark_width 8
X#define questionmark_height 8
Xstatic char questionmark_bits[] = {
X   0x38, 0x7c, 0x64, 0x30, 0x18, 0x00, 0x18, 0x18};
X
Xstatic Pixmap CreateQuestionPixmap (widthp, heightp)
X    unsigned int *widthp, *heightp;
X{
X    *widthp = questionmark_width;
X    *heightp = questionmark_height;
X    if (Scr->tbpm.question == None) {
X	Scr->tbpm.question = XCreateBitmapFromData (dpy, Scr->Root,
X						    questionmark_bits,
X						    questionmark_width,
X						    questionmark_height);
X    }
X    /*
X     * this must succeed or else we are in deep trouble elsewhere
X     */
X    return Scr->tbpm.question;
X}
X
X
X/* ARGSUSED */
Xstatic Pixmap CreateMenuPixmap (widthp, heightp)
X    int *widthp, *heightp;
X{
X    fprintf (stderr, "%s:  built-in bitmap \"%s\" not implemented.\n",
X	     ProgramName, TBPM_MENU);
X    return None;
X}
SHAR_EOF
if test 20619 -ne "`wc -c < util.c`"
then
    echo shar: error transmitting "util.c" '(should have been 20619 characters)'
fi
fi
if test -f 'util.h'
then
    echo shar: will not over-write existing file "util.h"
else
echo extracting "util.h"
sed 's/^X//' >util.h <<'SHAR_EOF'
X/*****************************************************************************/
X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
X/**                          Salt Lake City, Utah                           **/
X/**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
X/**                        Cambridge, Massachusetts                         **/
X/**                                                                         **/
X/**                           All Rights Reserved                           **/
X/**                                                                         **/
X/**    Permission to use, copy, modify, and distribute this software and    **/
X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
X/**    granted, provided that the above copyright notice appear  in  all    **/
X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
X/**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
X/**    in publicity pertaining to distribution of the  software  without    **/
X/**    specific, written prior permission.                                  **/
X/**                                                                         **/
X/**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
X/**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
X/**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
X/**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
X/**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
X/**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
X/**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
X/**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
X/*****************************************************************************/
X
X
X/***********************************************************************
X *
X * $XConsortium: util.h,v 1.10 89/12/10 17:47:04 jim Exp $
X *
X * utility routines header file
X *
X * 28-Oct-87 Thomas E. LaStrange		File created
X *
X ***********************************************************************/
X
X#ifndef _UTIL_
X#define _UTIL_
X
Xextern void	Zoom();
Xextern void	MoveOutline();
Xextern Pixmap	GetBitmap(), FindBitmap();
Xextern void	GetUnknownIcon();
Xextern char 	*ExpandFilename();
Xextern int	GetColor();
X
Xextern int HotX, HotY;
X
X#endif /* _UTIL_ */
SHAR_EOF
if test 2629 -ne "`wc -c < util.h`"
then
    echo shar: error transmitting "util.h" '(should have been 2629 characters)'
fi
fi
if test -f 'vdt.c'
then
    echo shar: will not over-write existing file "vdt.c"
else
echo extracting "vdt.c"
sed 's/^X//' >vdt.c <<'SHAR_EOF'
X/*****************************************************************************/
X/**               Copyright 1990 by Solbourne Computer Inc.                 **/
X/**                          Longmont, Colorado                             **/
X/**                                                                         **/
X/**                           All Rights Reserved                           **/
X/**                                                                         **/
X/**    Permission to use, copy, modify, and distribute this software and    **/
X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
X/**    granted, provided that the above copyright notice appear  in  all    **/
X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
X/**    name of Solbourne not be used in advertising                         **/
X/**    in publicity pertaining to distribution of the  software  without    **/
X/**    specific, written prior permission.                                  **/
X/**                                                                         **/
X/**    SOLBOURNE COMPUTER INC. DISCLAIMS ALL WARRANTIES WITH REGARD         **/
X/**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
X/**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL SOLBOURNE                **/
X/**    BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-           **/
X/**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
X/**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
X/**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
X/**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
X/*****************************************************************************/
X
X/**********************************************************************
X *
X * $XConsortium: vdt.c,v 1.140 90/03/23 11:42:33 jim Exp $
X *
X * Virtual Desktop routines
X *
X * 22-Aug-90 Tom LaStrange        Initial Version.
X *
X **********************************************************************/
X
X#if !defined(lint) && !defined(SABER)
Xstatic char RCSinfo[]=
X"$XConsortium: vdt.c,v 1.140 90/03/23 11:42:33 jim Exp $";
X#endif
X
X#include <stdio.h>
X#include <X11/X.h>
X#include <X11/Xatom.h>
X#include "twm.h"
X#include "screen.h"
X#include "vdt.h"
X#include "parse.h"
X#include "move.h"
X
Xstatic int pointerX;
Xstatic int pointerY;
X
X/* private swm atoms */
X/* it would be nice at some point to get these atoms blessed so that
X * we don't have to make them swm specific
X */
X
X/* version 1.2 of swm sends synthetic ConfigureNotify events
X * with respect to the actual root window rather than a 
X * clients logical root window.  OI clients lokk for this 
X * version string on the root window to determine how to
X * interpret the ConfigureNotify event
X */
X#define SWM_VERSION "1.2"
X
XAtom XA_SWM_ROOT = None;
XAtom XA_SWM_VROOT = None;
XAtom XA_SWM_VERSION = None;
X
X/***********************************************************************
X *
X *  Procedure:
X *	InitVirtualDesktop - init vdt stuff
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XInitVirtualDesktop()
X{
X    XA_SWM_ROOT          = XInternAtom(dpy, "__SWM_ROOT", False);
X    XA_SWM_VROOT         = XInternAtom(dpy, "__SWM_VROOT", False);
X    XA_SWM_VERSION       = XInternAtom(dpy, "__SWM_VERSION", False);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	SetSWM_ROOT - set the XA_SWM_ROOT property 
X *		This property always indicates to the application
X *		what its "root" window is.  This is currently needed
X *		by OI based clients, other toolkits don't know about
X *		virtual desktops.
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XSetSWM_ROOT(tmp_win)
XTwmWindow *tmp_win;
X{
X    if (Scr->VirtualDesktop && !tmp_win->iconmgr)
X    {
X	XChangeProperty(dpy, tmp_win->w, XA_SWM_ROOT, XA_WINDOW,
X	    32, PropModeReplace, (unsigned char *)&tmp_win->root, 1);
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	SetSWM_VERSION - set the XA_SWM_VERSION property 
X *		This property always indicates to the application
X *		what its "root" window is.  This is needed by OI
X *		clients so they can know how to interpret the
X *		incoming synthetic ConfigureNotify events.
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XSetSWM_VERSION()
X{
X    static char *version = SWM_VERSION;
X    XChangeProperty(dpy,Scr->Root,XA_SWM_VERSION, XA_STRING, 8,
X	PropModeReplace, (unsigned char *)version, strlen(version));
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	RemoveSWM_VERSION - remove the XA_SWM_VERSION property 
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XRemoveSWM_VERSION()
X{
X    XDeleteProperty(dpy, Scr->Root, XA_SWM_VERSION);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	MakeVirtual - make a small virtual window
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
XWindow
XMakeVirtual(tmp_win, x, y, width, height, background, border)
XTwmWindow *tmp_win;
Xint x;
Xint y;
Xint width;
Xint height;
Xlong background;
Xlong border;
X{
X    Window virtual;
X
X    width /= Scr->PannerScale;
X    height /= Scr->PannerScale;
X    if (width <= 0) width = 1;
X    if (height <= 0) height = 1;
X    virtual = XCreateSimpleWindow(dpy, Scr->Panner, x, y,
X	width, height, 1, border, background);
X    XGrabButton(dpy, Button2, AnyModifier, virtual,
X	True, ButtonPressMask | ButtonReleaseMask,
X	GrabModeAsync, GrabModeAsync, Scr->Panner, None);
X    XSelectInput(dpy, virtual, KeyPressMask);
X    XSaveContext(dpy, virtual, TwmContext, (caddr_t) tmp_win);
X    XSaveContext(dpy, virtual, VirtualContext, (caddr_t) tmp_win);
X    XSaveContext(dpy, virtual, ScreenContext, (caddr_t) Scr);
X    return (virtual);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	ResizeVirtual - resize one of the small virtual windows
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XResizeVirtual(window, width, height)
XWindow window;
Xint width;
Xint height;
X{
X    if (window) {
X	width /= Scr->PannerScale;
X	height /= Scr->PannerScale;
X	if (width <= 0) width = 1;
X	if (height <= 0) height = 1;
X	XResizeWindow(dpy, window, width, height);
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	MapFrame - map a client window and its frame
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XMapFrame(tmp_win)
XTwmWindow *tmp_win;
X{
X    XMapWindow(dpy, tmp_win->w);
X    XMapWindow(dpy, tmp_win->frame);
X    if (tmp_win->virtualWindow && !tmp_win->sticky)
X	XMapWindow(dpy, tmp_win->virtualWindow);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	UnmapFrame - unmap a client window and its frame
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XUnmapFrame(tmp_win)
XTwmWindow *tmp_win;
X{
X    XUnmapWindow(dpy, tmp_win->frame);
X    XUnmapWindow(dpy, tmp_win->w);
X    if (tmp_win->virtualWindow && !tmp_win->sticky)
X	XUnmapWindow(dpy, tmp_win->virtualWindow);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	RaiseFrame - raise a client window and its frame
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XRaiseFrame(tmp_win)
XTwmWindow *tmp_win;
X{
X    XRaiseWindow(dpy, tmp_win->frame);
X    if (tmp_win->virtualWindow && !tmp_win->sticky)
X	XRaiseWindow(dpy, tmp_win->virtualWindow);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	LowerFrame - lower a client window and its frame
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XLowerFrame(tmp_win)
XTwmWindow *tmp_win;
X{
X    XWindowChanges xwc;
X
X    if (tmp_win->sticky && Scr->VirtualDesktop) {
X	xwc.sibling = Scr->VirtualDesktop;
X	xwc.stack_mode = Above;
X	XConfigureWindow(dpy, tmp_win->frame, CWSibling|CWStackMode, &xwc);
X    }
X    else
X	XLowerWindow(dpy, tmp_win->frame);
X    if (tmp_win->virtualWindow && !tmp_win->sticky)
X	XLowerWindow(dpy, tmp_win->virtualWindow);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	MapIcon - map the icon window
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XMapIcon(tmp_win)
XTwmWindow *tmp_win;
X{
X    XMapRaised(dpy, tmp_win->icon_w);
X    if (tmp_win->virtualIcon && !tmp_win->sticky)
X	XMapRaised(dpy, tmp_win->virtualIcon);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	UnmapIcon - unmap the icon window
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XUnmapIcon(tmp_win)
XTwmWindow *tmp_win;
X{
X    XUnmapWindow(dpy, tmp_win->icon_w);
X    if (tmp_win->virtualIcon && !tmp_win->sticky)
X	XUnmapWindow(dpy, tmp_win->virtualIcon);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	RaiseIcon - raise a client icon
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XRaiseIcon(tmp_win)
XTwmWindow *tmp_win;
X{
X    XRaiseWindow(dpy, tmp_win->icon_w);
X    if (tmp_win->virtualIcon && !tmp_win->sticky)
X	XRaiseWindow(dpy, tmp_win->virtualIcon);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	LowerIcon - lower an icon
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XLowerIcon(tmp_win)
XTwmWindow *tmp_win;
X{
X    XWindowChanges xwc;
X
X    if (tmp_win->sticky && Scr->VirtualDesktop) {
X	xwc.sibling = Scr->VirtualDesktop;
X	xwc.stack_mode = Above;
X	XConfigureWindow(dpy, tmp_win->icon_w, CWSibling|CWStackMode, &xwc);
X    }
X    else
X	XLowerWindow(dpy, tmp_win->icon_w);
X    if (tmp_win->virtualIcon && !tmp_win->sticky)
X	XLowerWindow(dpy, tmp_win->virtualIcon);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	MoveIcon - move an icon
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XMoveIcon(tmp_win, x, y)
XTwmWindow *tmp_win;
X{
X    XWindowChanges xwc;
X
X    XMoveWindow(dpy, tmp_win->icon_w, x, y);
X    tmp_win->icon_loc_x = x;
X    tmp_win->icon_loc_y = y;
X    if (tmp_win->virtualIcon)
X	XMoveWindow(dpy, tmp_win->virtualIcon, x/Scr->PannerScale, y/Scr->PannerScale);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	MakeVirtualDesktop - create the virtual desktop window
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XMakeVirtualDesktop(width, height)
Xint width, height;
X{
X    Pixmap pm, bm;
X    unsigned int bmWidth, bmHeight;
X    XSetWindowAttributes attr;
X    unsigned attrMask;
X
X    if (width < Scr->MyDisplayWidth)
X	    width = 2 * Scr->MyDisplayWidth;
X    if (height < Scr->MyDisplayHeight)
X	    height = 2 * Scr->MyDisplayHeight;
X
X    bm = None;
X    pm = None;
X    if (Scr->vdtPixmap) {
X	bm = FindBitmap(Scr->vdtPixmap, &bmWidth, &bmHeight);
X	if (bm) {
X	    GC gc;
X	    XGCValues gcv;
X
X	    pm = XCreatePixmap(dpy, Scr->Root, bmWidth, bmHeight, Scr->d_depth);
X	    gcv.foreground = Scr->vdtC.fore;
X	    gcv.background = Scr->vdtC.back;
X	    gc = XCreateGC(dpy, Scr->Root, GCForeground|GCBackground, &gcv);
X	    XCopyPlane(dpy, bm, pm, gc, 0,0, bmWidth, bmHeight, 0,0, 1);
X	    XFreeGC(dpy, gc);
X	}
X    }
X    attrMask = CWOverrideRedirect | CWEventMask | CWBackPixmap;
X    attr.override_redirect = True;
X    attr.event_mask = SubstructureRedirectMask|SubstructureNotifyMask;
X    attr.background_pixmap = Scr->rootWeave;
X    if (pm)
X	attr.background_pixmap = pm;
X    else if (Scr->vdtBackgroundSet) {
X	attrMask &= ~CWBackPixmap;
X	attrMask |= CWBackPixel;
X	attr.background_pixel = Scr->vdtC.back;
X    }
X
X    Scr->VirtualDesktop = XCreateWindow(dpy, Scr->Root, 0, 0, 
X	    width+50, height+50, 0, Scr->d_depth, CopyFromParent,
X	    Scr->d_visual, attrMask, &attr);
X    Scr->vdtWidth = width;
X    Scr->vdtHeight = height;
X
X    /* this property allows ssetroot to find the virtual root window */
X    XChangeProperty(dpy, Scr->VirtualDesktop, XA_SWM_VROOT, XA_WINDOW, 32,
X	PropModeReplace, (unsigned char *)&Scr->VirtualDesktop, 1);
X
X    if (bm)
X	XFreePixmap(dpy, bm);
X    if (pm)
X	XFreePixmap(dpy, pm);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	MakePanner - create the virtual desktop panner window
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XMakePanner()
X{
X    static XTextProperty wName={(unsigned char *) "Virtual Desktop",XA_STRING,8,15};
X    static XTextProperty iName={(unsigned char *) "Desktop",XA_STRING,8,7};
X    XSetWindowAttributes attr;
X    XSizeHints *sizeHints;
X    XWMHints *wmHints;
X    XClassHint *classHints;
X    int status;
X    int x, y, width, height;
X    Pixmap pm, bm;
X    unsigned int bmWidth, bmHeight;
X    unsigned attrMask;
X
X    width = Scr->vdtWidth/Scr->PannerScale;
X    height = Scr->vdtHeight/Scr->PannerScale;
X
X    sizeHints = XAllocSizeHints();
X    sizeHints->flags = PBaseSize;
X    sizeHints->base_width = width;
X    sizeHints->base_height = height;
X    sizeHints->min_width = Scr->MyDisplayWidth/Scr->PannerScale;
X    sizeHints->min_height = Scr->MyDisplayHeight/Scr->PannerScale;
X    XWMGeometry(dpy, Scr->screen, Scr->PannerGeometry, NULL,
X	1, sizeHints, &x, &y, &width, &height, &sizeHints->win_gravity);
X    sizeHints->flags = USPosition|PWinGravity|PMinSize;
X
X    wmHints = XAllocWMHints();
X    wmHints->initial_state = Scr->PannerState;
X    wmHints->flags = StateHint;
X
X    classHints = XAllocClassHint();
X    classHints->res_name = "virtualDesktop";
X    classHints->res_class = "Twm";
X
X    bm = None;
X    pm = None;
X    if (Scr->PannerPixmap) {
X	bm = FindBitmap(Scr->PannerPixmap, &bmWidth, &bmHeight);
X	if (bm) {
X	    GC gc;
X	    XGCValues gcv;
X
X	    pm = XCreatePixmap(dpy, Scr->Root, bmWidth, bmHeight, Scr->d_depth);
X	    gcv.foreground = Scr->PannerC.fore;
X	    gcv.background = Scr->PannerC.back;
X	    gc = XCreateGC(dpy, Scr->Root, GCForeground|GCBackground, &gcv);
X	    XCopyPlane(dpy, bm, pm, gc, 0,0, bmWidth, bmHeight, 0,0, 1);
X	    XFreeGC(dpy, gc);
X	}
X    }
X
X    attrMask = CWBackPixmap|CWEventMask;
X    attr.background_pixmap = Scr->rootWeave;
X    attr.event_mask = ExposureMask | ButtonPressMask;
X    if (pm)
X	attr.background_pixmap = pm;
X    else if (Scr->PannerBackgroundSet) {
X	attrMask &= ~CWBackPixmap;
X	attrMask |= CWBackPixel;
X	attr.background_pixel = Scr->PannerC.back;
X    }
X    Scr->Panner = XCreateWindow(dpy, Scr->Root, x, y, 
X	    sizeHints->base_width, sizeHints->base_height, 1,
X	    Scr->d_depth, CopyFromParent,
X	    Scr->d_visual, attrMask, &attr);
X    
X    Scr->PannerWidth = sizeHints->base_width;
X    Scr->PannerHeight = sizeHints->base_height;
X
X    XGrabButton(dpy, Button1, AnyModifier, Scr->Panner,
X	True, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
X	GrabModeAsync, GrabModeAsync, Scr->Panner, None);
X    XGrabButton(dpy, Button3, AnyModifier, Scr->Panner,
X	True, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
X	GrabModeAsync, GrabModeAsync, Scr->Panner, None);
X    XSetWMProperties(dpy, Scr->Panner, wName, iName, NULL, 0,
X	sizeHints, wmHints, classHints);
X
X    if (Scr->PannerState != WithdrawnState)
X	XMapRaised(dpy, Scr->Panner);
X    XSaveContext(dpy, Scr->Panner, ScreenContext, (caddr_t) Scr);
X}
X
Xvoid
XHandlePannerExpose(ev)
XXEvent *ev;
X{
X    if (ev->xexpose.count)
X	return;
X
X    if (!Scr->PannerOutlineWidth) {
X	Scr->PannerOutlineWidth = Scr->MyDisplayWidth / Scr->PannerScale -1;
X	Scr->PannerOutlineHeight = Scr->MyDisplayHeight / Scr->PannerScale -1;
X    }
X    XClearWindow(dpy, Scr->Panner);
X    XDrawRectangle(dpy, Scr->Panner, Scr->PannerGC,
X	Scr->PannerOutlineX, Scr->PannerOutlineY,
X	Scr->PannerOutlineWidth, Scr->PannerOutlineHeight);
X}
X
Xvoid
XHandlePannerButtonPress(ev)
XXEvent *ev;
X{
X    pointerX = Scr->PannerOutlineX + Scr->PannerOutlineWidth/2;
X    pointerY = Scr->PannerOutlineY + Scr->PannerOutlineHeight/2;
X    XWarpPointer(dpy, None, Scr->Panner, 0,0,0,0,
X	pointerX, pointerY);
X    XClearWindow(dpy, Scr->Panner);
X    XDrawRectangle(dpy, Scr->Panner, Scr->DrawGC,
X	Scr->PannerOutlineX, Scr->PannerOutlineY,
X	Scr->PannerOutlineWidth, Scr->PannerOutlineHeight);
X}
X
Xvoid
XHandlePannerButtonRelease(ev)
XXEvent *ev;
X{
X    XDrawRectangle(dpy, Scr->Panner, Scr->DrawGC,
X	Scr->PannerOutlineX, Scr->PannerOutlineY,
X	Scr->PannerOutlineWidth, Scr->PannerOutlineHeight);
X    XClearWindow(dpy, Scr->Panner);
X    XDrawRectangle(dpy, Scr->Panner, Scr->PannerGC,
X	Scr->PannerOutlineX, Scr->PannerOutlineY,
X	Scr->PannerOutlineWidth, Scr->PannerOutlineHeight);
X
X    MoveDesktop(Scr->PannerOutlineX * Scr->PannerScale,
X	Scr->PannerOutlineY * Scr->PannerScale);
X}
X
Xvoid
XHandlePannerMotionNotify(ev)
XXEvent *ev;
X{
X    int deltaX, deltaY;
X    int newOutlineX, newOutlineY;
X
X    /* get rid of the last outline */
X    XDrawRectangle(dpy, Scr->Panner, Scr->DrawGC,
X	Scr->PannerOutlineX, Scr->PannerOutlineY,
X	Scr->PannerOutlineWidth, Scr->PannerOutlineHeight);
X
X    /* figure out the position of the next outline */
X    deltaX = ev->xmotion.x - pointerX;
X    deltaY = ev->xmotion.y - pointerY;
X
X    newOutlineX = Scr->PannerOutlineX + deltaX;
X    newOutlineY = Scr->PannerOutlineY + deltaY;
X
X    if (newOutlineX < 0)
X	newOutlineX = 0;
X    if (newOutlineY < 0)
X	newOutlineY = 0;
X    if ((newOutlineX + Scr->PannerOutlineWidth) >= Scr->PannerWidth)
X	newOutlineX = Scr->PannerWidth - Scr->PannerOutlineWidth - 1;
X    if ((newOutlineY + Scr->PannerOutlineHeight) >= Scr->PannerHeight)
X	newOutlineY = Scr->PannerHeight - Scr->PannerOutlineHeight - 1;
X
X    pointerX = ev->xmotion.x;
X    pointerY = ev->xmotion.y;
X    Scr->PannerOutlineX = newOutlineX;
X    Scr->PannerOutlineY = newOutlineY;
X
X    /* draw the new outline */
X    XDrawRectangle(dpy, Scr->Panner, Scr->DrawGC,
X	Scr->PannerOutlineX, Scr->PannerOutlineY,
X	Scr->PannerOutlineWidth, Scr->PannerOutlineHeight);
X}
X
X
X/***********************************************************************
X *
X *  Procedure:
X *	MoveDesktop - move the desktop to a pixel location
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XMoveDesktop(x, y)
Xint x;
Xint y;
X{
X    TwmWindow *tmp;
X    XEvent ev;
X
X    if (x != Scr->vdtPositionX || y != Scr->vdtPositionY) {
X	if (x < 0) x = 0;
X	if (y < 0) y = 0;
X	if ((x + Scr->MyDisplayWidth) > Scr->vdtWidth)
X	    x = Scr->vdtWidth - Scr->MyDisplayWidth;
X	if ((y + Scr->MyDisplayHeight) > Scr->vdtHeight)
X	    y = Scr->vdtHeight - Scr->MyDisplayHeight;
X	XMoveWindow(dpy, Scr->VirtualDesktop, -x, -y);
X	Scr->PannerOutlineX = x / Scr->PannerScale;
X	Scr->PannerOutlineY = y / Scr->PannerScale;
X	Scr->vdtPositionX = x;
X	Scr->vdtPositionY = y;
X
X	for (tmp = Scr->TwmRoot.next; tmp != NULL; tmp = tmp->next)
X	    if (!tmp->sticky)
X		SendSyntheticConfigureNotify(tmp);
X
X	/* go repaint the panner */
X	ev.xexpose.count = 0;
X	HandlePannerExpose(&ev);
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	ScrollDesktop - scroll the desktop by screenfuls
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XScrollDesktop(func)
Xint func;
X{
X    int x, y;
X
X    x = Scr->vdtPositionX;
X    y = Scr->vdtPositionY;
X
X    switch (func)
X    {
X	case F_SCROLLHOME:
X	    x = 0;
X	    y = 0;
X	    break;
X	case F_SCROLLRIGHT:
X	    x += Scr->MyDisplayWidth;
X	    break;
X	case F_SCROLLLEFT:
X	    x -= Scr->MyDisplayWidth;
X	    break;
X	case F_SCROLLDOWN:
X	    y += Scr->MyDisplayHeight;
X	    break;
X	case F_SCROLLUP:
X	    y -= Scr->MyDisplayHeight;
X	    break;
X    }
X    if (x < 0)
X	x = 0;
X    if (y < 0)
X	y = 0;
X    if ((x + Scr->MyDisplayWidth) > Scr->vdtWidth)
X	x = Scr->vdtWidth - Scr->MyDisplayWidth;
X    if ((y + Scr->MyDisplayHeight) > Scr->vdtHeight)
X	y = Scr->vdtHeight - Scr->MyDisplayHeight;
X    MoveDesktop(x, y);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	ResizeDesktop - resize the desktop, the coordinates are in panner
X *		units.
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XResizeDesktop(width, height)
Xint width;
Xint height;
X{
X    int vdtWidth, vdtHeight;
X
X    if (width != Scr->PannerWidth || height != Scr->PannerHeight) {
X	Scr->PannerWidth = width;
X	Scr->PannerHeight = height;
X
X	vdtWidth = width * Scr->PannerScale;
X	vdtHeight = height * Scr->PannerScale;
X
X	if (vdtWidth < Scr->vdtWidth) {
X	    if ((Scr->PannerOutlineX + Scr->PannerOutlineWidth) >= Scr->PannerWidth)
X		Scr->PannerOutlineX = Scr->PannerWidth-Scr->PannerOutlineWidth - 1;
X	}
X	if (vdtHeight < Scr->vdtHeight) {
X	    if ((Scr->PannerOutlineY+Scr->PannerOutlineHeight) >= Scr->PannerHeight)
X		Scr->PannerOutlineY = Scr->PannerHeight-Scr->PannerOutlineHeight-1;
X	}
X	Scr->vdtWidth = vdtWidth;
X	Scr->vdtHeight = vdtHeight;
X
X	MoveDesktop(Scr->PannerOutlineX * Scr->PannerScale,
X	    Scr->PannerOutlineY * Scr->PannerScale);
X
X	/* make it just a tad larger than requested */
X	XResizeWindow(dpy, Scr->VirtualDesktop, vdtWidth + 2*Scr->PannerScale,
X	    vdtHeight + 2*Scr->PannerScale);
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandlePannerMove - prepare to move a small panner window
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XHandlePannerMove(ev, tmp_win)
XXButtonEvent *ev;
XTwmWindow *tmp_win;
X{
X    int cancel;
X    int x_root, y_root;
X    unsigned objWidth, objHeight;
X    int moving_frame;
X
X    tmp_win->root = Scr->Panner;
X
X    x_root = ev->x_root;
X    y_root = ev->y_root;
X
X    if (ev->window == tmp_win->virtualWindow) {
X	moving_frame = True;
X	objWidth = tmp_win->frame_width + 2*tmp_win->frame_bw;
X	objHeight = tmp_win->frame_height + 2*tmp_win->frame_bw;
X    }
X    else {
X	moving_frame - False;
X	objWidth = tmp_win->icon_w_width + 2;
X	objHeight = tmp_win->icon_w_height + 2;
X    }
X
X    StartMove(tmp_win, ev->window, tmp_win->title_height,
X	&x_root, &y_root, &cancel, IN_PANNER, Scr->PannerScale,
X	objWidth, objHeight, False, False);
X
X    tmp_win->root = Scr->VirtualDesktop;
X
X    if (!cancel) {
X	if (moving_frame) {
X	    SetupWindow (tmp_win, x_root, y_root,
X		 tmp_win->frame_width, tmp_win->frame_height, -1);
X	}
X	else {
X	    MoveIcon(tmp_win, x_root, y_root);
X	}
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	ScrollTo - scroll the virtual desktop to a window of non of
X *		the frame is visible
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XScrollTo(tmp_win)
XTwmWindow *tmp_win;
X{
X    int x, y;
X    int xr, yb;
X
X    if (!tmp_win->sticky) {
X	x = Scr->vdtPositionX;
X	y = Scr->vdtPositionY;
X	xr = x + Scr->MyDisplayWidth;
X	yb = y + Scr->MyDisplayHeight;
X
X	if ((tmp_win->frame_x + tmp_win->frame_width) <= x)
X	    x = tmp_win->frame_x;
X	else if (tmp_win->frame_x >= xr)
X	    x = tmp_win->frame_x;
X
X	if ((tmp_win->frame_y + tmp_win->frame_height) <= y)
X	    y = tmp_win->frame_y;
X	else if (tmp_win->frame_y >= yb)
X	    y = tmp_win->frame_y;
X
X	/* if we are going to scroll, we might as well do it in both
X	 * directions
X	 */
X	if (x != Scr->vdtPositionX || y != Scr->vdtPositionY) {
X	    x = tmp_win->frame_x;
X	    y = tmp_win->frame_y;
X	    MoveDesktop(x, y);
X	}
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	ScrollToQuadrant - scroll the virtual desktop to a the quadrant 
X *		that contains the client window.
X *	
X *  Returned Value:
X *	None
X *
X ***********************************************************************
X */
X
Xvoid
XScrollToQuadrant(tmp_win)
XTwmWindow *tmp_win;
X{
X    int x, y;
X    int xr, yb;
X
X    if (!tmp_win->sticky) {
X	x = (tmp_win->frame_x / Scr->MyDisplayWidth) * Scr->MyDisplayWidth;
X	y = (tmp_win->frame_y / Scr->MyDisplayHeight) * Scr->MyDisplayHeight;
X	MoveDesktop(x, y);
X    }
X}
SHAR_EOF
if test 24996 -ne "`wc -c < vdt.c`"
then
    echo shar: error transmitting "vdt.c" '(should have been 24996 characters)'
fi
fi
if test -f 'vdt.h'
then
    echo shar: will not over-write existing file "vdt.h"
else
echo extracting "vdt.h"
sed 's/^X//' >vdt.h <<'SHAR_EOF'
X/*****************************************************************************/
X/**               Copyright 1990 by Solbourne Computer Inc.                 **/
X/**                          Longmont, Colorado                             **/
X/**                                                                         **/
X/**                           All Rights Reserved                           **/
X/**                                                                         **/
X/**    Permission to use, copy, modify, and distribute this software and    **/
X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
X/**    granted, provided that the above copyright notice appear  in  all    **/
X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
X/**    name of Solbourne not be used in advertising                         **/
X/**    in publicity pertaining to distribution of the  software  without    **/
X/**    specific, written prior permission.                                  **/
X/**                                                                         **/
X/**    SOLBOURNE COMPUTER INC. DISCLAIMS ALL WARRANTIES WITH REGARD         **/
X/**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
X/**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL SOLBOURNE                **/
X/**    BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-           **/
X/**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
X/**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
X/**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
X/**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
X/*****************************************************************************/
X
X/**********************************************************************
X *
X * $XConsortium: vdt.c,v 1.140 90/03/23 11:42:33 jim Exp $
X *
X * Virtual Desktop includes
X *
X * 22-Aug-90 Tom LaStrange        Initial Version.
X *
X **********************************************************************/
X
X#ifndef _VDT_
X#define _VDT_
X
X#define DEFAULT_PANNER_SCALE 20
X#define DEFAULT_PANNER_GEOMETRY "-0-0"
X
Xextern void InitVirtualDesktop();
Xextern void Set__SWM_ROOT();
Xextern void Set__SWM_VERSION();
Xextern void Remove__SWM_VERSION();
Xextern void MakePanner();
Xextern void MakeVirtualDesktop();
Xextern void MapFrame();
Xextern void UnmapFrame();
Xextern void RaiseFrame();
Xextern void LowerFrame();
Xextern void MapIcon();
Xextern void UnmapIcon();
Xextern void RaiseIcon();
Xextern void LowerIcon();
Xextern void MoveIcon();
Xextern void ResizeVirtual();
Xextern Window MakeVirtual();
Xextern void HandlePannerExpose();
Xextern void HandlePannerButtonPress();
Xextern void HandlePannerButtonRelease();
Xextern void HandlePannerMotionNotify();
Xextern void MoveDesktop();
Xextern void ScrollDesktop();
Xextern void ResizeDesktop();
Xextern void ScrollTo();
X
X#endif /* _VDT_ */
X
SHAR_EOF
if test 3074 -ne "`wc -c < vdt.h`"
then
    echo shar: error transmitting "vdt.h" '(should have been 3074 characters)'
fi
fi
if test -f 'version.c'
then
    echo shar: will not over-write existing file "version.c"
else
echo extracting "version.c"
sed 's/^X//' >version.c <<'SHAR_EOF'
X/*****************************************************************************/
X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
X/**                          Salt Lake City, Utah                           **/
X/**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
X/**                        Cambridge, Massachusetts                         **/
X/**                                                                         **/
X/**                           All Rights Reserved                           **/
X/**                                                                         **/
X/**    Permission to use, copy, modify, and distribute this software and    **/
X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
X/**    granted, provided that the above copyright notice appear  in  all    **/
X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
X/**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
X/**    in publicity pertaining to distribution of the  software  without    **/
X/**    specific, written prior permission.                                  **/
X/**                                                                         **/
X/**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
X/**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
X/**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
X/**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
X/**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
X/**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
X/**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
X/**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
X/*****************************************************************************/
X
X/* char *Version = "MIT X Consortium, R4"; */
Xchar *Version = "$Revision: 4.0 $";
X
SHAR_EOF
if test 2164 -ne "`wc -c < version.c`"
then
    echo shar: error transmitting "version.c" '(should have been 2164 characters)'
fi
fi
if test -f 'version.h'
then
    echo shar: will not over-write existing file "version.h"
else
echo extracting "version.h"
sed 's/^X//' >version.h <<'SHAR_EOF'
X/*****************************************************************************/
X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
X/**                          Salt Lake City, Utah                           **/
X/**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
X/**                        Cambridge, Massachusetts                         **/
X/**                                                                         **/
X/**                           All Rights Reserved                           **/
X/**                                                                         **/
X/**    Permission to use, copy, modify, and distribute this software and    **/
X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
X/**    granted, provided that the above copyright notice appear  in  all    **/
X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
X/**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
X/**    in publicity pertaining to distribution of the  software  without    **/
X/**    specific, written prior permission.                                  **/
X/**                                                                         **/
X/**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
X/**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
X/**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
X/**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
X/**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
X/**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
X/**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
X/**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
X/*****************************************************************************/
X
X/**********************************************************************
X *
X * $XConsortium: version.h,v 1.7 89/10/27 14:01:42 jim Exp $
X *
X * TWM version externs
X *
X *  8-Apr-88 Tom LaStrange        Initial Version.
X *
X **********************************************************************/
X
X#ifndef _VERSION_
X#define _VERSION_
X
Xextern char *Version;
X
X#endif /* _VERSION_ */
SHAR_EOF
if test 2457 -ne "`wc -c < version.h`"
then
    echo shar: error transmitting "version.h" '(should have been 2457 characters)'
fi
fi
# end of shell archive
exit 0

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.