[comp.windows.x] twm 3.0, part 3 of 5

tlastran@esunix.UUCP (Tom LaStrange) (06/04/88)

#! /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:
#
#parse.c
#events.c
#list.c
#resize.c
#
# Created by tlastran (Tom LaStrange) on Fri Jun  3 11:32:35 MDT 1988
#
if test -f 'parse.c'
then
    echo shar: will not over-write existing file "parse.c"
else
echo extracting "parse.c"
sed 's/^X//' >parse.c <<'SHAR_EOF'
X/*****************************************************************************/
X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
X/**                          Salt Lake City, Utah                           **/
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 Evans & Sutherland  not be used in advertising or publi-    **/
X/**    city pertaining to distribution  of the software without  specif-    **/
X/**    ic, written prior permission.                                        **/
X/**                                                                         **/
X/**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
X/**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
X/**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
X/**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
X/**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
X/**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
X/**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
X/**    FORMANCE OF THIS SOFTWARE.                                           **/
X/*****************************************************************************/
X
X/***********************************************************************
X *
X * $Header: parse.c,v 1.15 88/05/31 07:43:53 tlastran Exp $
X *
X * parse the .twmrc file
X *
X * 17-Nov-87 Thomas E. LaStrange		File created
X *
X ***********************************************************************/
X
X#ifndef lint
Xstatic char RCSinfo[]=
X"$Header: parse.c,v 1.15 88/05/31 07:43:53 tlastran Exp $";
X#endif
X
X#include <stdio.h>
X#include "twm.h"
X#include "menus.h"
X#include "util.h"
X
X#define BUF_LEN 300
X
Xstatic FILE *twmrc;
Xstatic int ptr = 0;
Xstatic int len = 0;
Xstatic char buff[BUF_LEN+1];
Xextern int yylineno;
X
X/***********************************************************************
X *
X *  Procedure:
X *	ParseTwmrc - parse the .twmrc file
X *
X *  Inputs:
X *	filename  - the filename to parse.  A NULL indicates $HOME/.twmrc
X *
X ***********************************************************************
X */
X
Xvoid
XParseTwmrc(filename)
Xchar *filename;
X{
X    char *home;
X    char init_file[200];
X
X    InitMenus();
X
X    if (filename == NULL)
X    {
X	home = (char *)getenv("HOME");
X	strcpy(init_file, home);
X	strcat(init_file, "/.twmrc");
X    }
X    else
X	strcpy(init_file, filename);
X
X    if ((twmrc = fopen(init_file, "r")) == NULL)
X    {
X	fprintf(stderr, "twm: couldn't open \"%s\"\n", init_file);
X    	return;
X    }
X
X    ptr = 0;
X    len = 0;
X    yylineno = 0;
X    ParseError = FALSE;
X
X    yyparse();
X
X    fclose(twmrc);
X
X    if (ParseError)
X    {
X	fprintf(stderr, "twm: errors found in \"%s\", twm aborting\n",
X	    init_file);
X	Done();
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	TwmInput - redefinition of the lex input routine
X *
X *  Returned Value:
X *	the next input character
X *
X ***********************************************************************
X */
X
Xchar
XTwmInput()
X{
X    while (ptr == len)
X    {
X	if (fgets(buff, BUF_LEN, twmrc) == NULL)
X	    return NULL;
X
X	yylineno++;
X
X	ptr = 0;
X	len = strlen(buff);
X    }
X    return (buff[ptr++]);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	TwmUnput - redefinition of the lex unput routine
X *
X *  Inputs:
X *	c	- the character to push back onto the input stream
X *
X ***********************************************************************
X */
X
Xvoid
XTwmUnput(c)
X{
X    buff[--ptr] = c;
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	TwmOutput - redefinition of the lex output routine
X *
X *  Inputs:
X *	c	- the character to print
X *
X ***********************************************************************
X */
X
Xvoid
XTwmOutput(c)
X{
X    putchar(c);
X}
SHAR_EOF
if test 4563 -ne "`wc -c < parse.c`"
then
    echo shar: error transmitting "parse.c" '(should have been 4563 characters)'
fi
fi
if test -f 'events.c'
then
    echo shar: will not over-write existing file "events.c"
else
echo extracting "events.c"
sed 's/^X//' >events.c <<'SHAR_EOF'
X/*****************************************************************************/
X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
X/**                          Salt Lake City, Utah                           **/
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 Evans & Sutherland  not be used in advertising or publi-    **/
X/**    city pertaining to distribution  of the software without  specif-    **/
X/**    ic, written prior permission.                                        **/
X/**                                                                         **/
X/**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
X/**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
X/**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
X/**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
X/**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
X/**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
X/**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
X/**    FORMANCE OF THIS SOFTWARE.                                           **/
X/*****************************************************************************/
X
X/***********************************************************************
X *
X * $Header: events.c,v 1.56 88/06/02 14:37:24 tlastran Exp $
X *
X * twm event handling
X *
X * 17-Nov-87 Thomas E. LaStrange		File created
X *
X ***********************************************************************/
X
X#ifndef lint
Xstatic char RCSinfo[]=
X"$Header: events.c,v 1.56 88/06/02 14:37:24 tlastran Exp $";
X#endif
X
X#include <stdio.h>
X#include "twm.h"
X#include <X11/Xatom.h>
X#include "add_window.h"
X#include "menus.h"
X#include "events.h"
X#include "resize.h"
X#include "gram.h"
X
X#include "twm.bm"
X
Xevent_proc EventHandler[LASTEvent]; /* event handler jump table */
Xstatic XEvent event;		/* the current event */
Xstatic TwmWindow *tmp_win;	/* the current twm window */
Xstatic Window w;		/* the window that caused the event */
Xstatic int Context = C_NO_CONTEXT;  /* current button press context */
Xstatic TwmWindow *ButtonWindow;	/* button press window structure */
Xstatic XEvent ButtonEvent;	/* button preee event */
Xstatic MouseButton ButtonMouse;	/* mouse button function */
X
Xint ConstMove = FALSE;		/* constrained move variables */
Xint ConstMoveDir;
Xint ConstMoveX;
Xint ConstMoveY;
Xint ConstMoveXL;
Xint ConstMoveXR;
Xint ConstMoveYT;
Xint ConstMoveYB;
X
XWindow DragWindow;		/* variables used in moving windows */
Xint DragX;
Xint DragY;
Xint DragWidth;
Xint DragHeight;
Xstatic int enter_flag;
X
X/***********************************************************************
X *
X *  Procedure:
X *	InitEvents - initialize the event jump table
X *
X ***********************************************************************
X */
X
Xvoid
XInitEvents()
X{
X    int i;
X
X    ResizeWindow = NULL;
X    DragWindow = NULL;
X    enter_flag = FALSE;
X
X    for (i = 0; i < LASTEvent; i++)
X	EventHandler[i] = HandleUnknown;
X
X    EventHandler[Expose] = HandleExpose;
X    EventHandler[DestroyNotify] = HandleDestroyNotify;
X    EventHandler[MapRequest] = HandleMapRequest;
X    EventHandler[MapNotify] = HandleMapNotify;
X    EventHandler[UnmapNotify] = HandleUnmapNotify;
X    EventHandler[MotionNotify] = HandleMotionNotify;
X    EventHandler[ButtonRelease] = HandleButtonRelease;
X    EventHandler[ButtonPress] = HandleButtonPress;
X    EventHandler[EnterNotify] = HandleEnterNotify;
X    EventHandler[LeaveNotify] = HandleLeaveNotify;
X    EventHandler[ConfigureNotify] = HandleConfigureNotify;
X    EventHandler[ClientMessage] = HandleClientMessage;
X    EventHandler[PropertyNotify] = HandlePropertyNotify;
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleEvents - handle X events
X *
X ***********************************************************************
X */
X
Xvoid
XHandleEvents()
X{
X    while (TRUE)
X    {
X	if ( (DragWindow || ResizeWindow) && !XPending(dpy) )
X	{
X	    /*
X	    ** Hack to support polled dynamics.  Should really
X	    ** build up "mode" support that callers can register
X	    ** handlers with, etc.
X	    */
X	    w = DragWindow ? DragWindow : ResizeWindow;
X	    XQueryPointer( dpy, w, &(event.xmotion.root), &JunkChild,
X			  &(event.xmotion.x_root), &(event.xmotion.y_root),
X			  &JunkX, &JunkY, &JunkX, &JunkY, &JunkMask);
X	    (*EventHandler[MotionNotify])();
X	}
X	else
X	{
X	    XNextEvent(dpy, &event);
X	    w = event.xany.window;
X	    if (XFindContext(dpy, w, TwmContext, &tmp_win) == XCNOENT)
X		tmp_win = NULL;
X
X#ifdef DEBUG
X	    if (event.type != MotionNotify)
X	    if (tmp_win != NULL)
X	    {
X		fprintf(stderr, "Event w=%x, t->w=%x, t->frame=%x, t->title=%x, ",
X			w, tmp_win->w, tmp_win->frame, tmp_win->title_w);
X	    }
X	    else
X	    {
X		fprintf(stderr, "Event w=%x, ", w);
X	    }
X#endif
X	    if (event.type >= 0 && event.type < LASTEvent)
X	        (*EventHandler[event.type])();
X	}
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandlePropertyNotify - property notify event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandlePropertyNotify()
X{
X    char *prop;
X    XWMHints *wmhints;
X    XSizeHints hints;
X    int junk1, junk2, junk3, len;
X    int width, x;
X    unsigned long valuemask;		/* mask for create windows */
X    XSetWindowAttributes attributes;	/* attributes for create windows */
X    Pixmap pm;
X
X#ifdef DEBUG
X    fprintf(stderr, "PropertyNotify\n");
X#endif
X
X    if (tmp_win == NULL)
X	return;
X
X    XGetWindowProperty(dpy, w, event.xproperty.atom, 0, 200, False,
X	AnyPropertyType, &junk1, &junk2, &junk3, &len, &prop);
X
X    if (prop == NULL)
X	prop = NoName;
X
X    switch (event.xproperty.atom)
X    {
X    case XA_WM_NAME:
X	tmp_win->full_name = prop;
X	tmp_win->name = prop;
X
X	if (strncmp("xterm_", tmp_win->name, 6) == 0)
X	    tmp_win->name = &tmp_win->name[6];
X
X	tmp_win->name_width = XTextWidth(TitleBarFont, tmp_win->name,
X	    strlen(tmp_win->name));
X
X	SetupWindow(tmp_win,
X	    tmp_win->frame_x,
X	    tmp_win->frame_y,
X	    tmp_win->attr.width,
X	    tmp_win->attr.height + tmp_win->title_height);
X
X	XClearArea(dpy, tmp_win->title_w, 0, 0, 0, 0, False);
X
X	XDrawImageString(dpy, tmp_win->title_w,
X	    TitleNormalGC,
X	    TitleBarX, TitleBarY,
X	    tmp_win->name, strlen(tmp_win->name));
X
X	/* if the icon name is NoName, set the name of the icon to be
X	 * the same as the window 
X	 */
X	if (tmp_win->icon_name == NoName)
X	{
X	    tmp_win->icon_name = tmp_win->name;
X	    RedoIconName();
X	}
X	break;
X
X    case XA_WM_ICON_NAME:
X	tmp_win->icon_name = prop;
X
X	RedoIconName();
X	break;
X
X    case XA_WM_HINTS:
X	wmhints = XGetWMHints(dpy, w);
X
X	if (!tmp_win->forced && tmp_win->wmhints &&
X	    tmp_win->wmhints->flags & IconWindowHint)
X	{
X	    tmp_win->icon_w = tmp_win->wmhints->icon_window;
X	}
X
X	if (!tmp_win->forced && wmhints && (wmhints->flags & IconPixmapHint))
X	{
X	    XGetGeometry(dpy, wmhints->icon_pixmap, &JunkRoot, &JunkX, &JunkY,
X		 &tmp_win->icon_width, &tmp_win->icon_height,
X		 &JunkBW, &JunkDepth);
X
X	    pm = XCreatePixmap(dpy, Root, tmp_win->icon_width,
X		tmp_win->icon_height, DefaultDepth(dpy, screen));
X
X	    XCopyPlane(dpy, wmhints->icon_pixmap, pm, IconNormalGC,
X		0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 );
X
X	    valuemask = CWBackPixmap;
X	    attributes.background_pixmap = pm;
X
X	    if (tmp_win->icon_bm_w)
X		XDestroyWindow(dpy, tmp_win->icon_bm_w);
X
X	    tmp_win->icon_bm_w = XCreateWindow(dpy, tmp_win->icon_w,
X		0, 0, tmp_win->icon_width, tmp_win->icon_height,
X		0, DefaultDepth(dpy, 0), CopyFromParent,
X		DefaultVisual(dpy,0),
X		valuemask, &attributes);
X
X	    RedoIconName();
X	}
X	break;
X
X    case XA_WM_NORMAL_HINTS:
X	XGetNormalHints(dpy, w, &hints);
X	/* don't do anything yet */
X	break;
X
X    default:
X#ifdef DEBUG
X	fprintf(stderr, "TWM Not handling property %d\n",event.xproperty.atom);
X#endif
X	break;
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	RedoIconName - procedure to re-position the icon window and name
X *
X ***********************************************************************
X */
X
XRedoIconName()
X{
X    int x;
X
X    tmp_win->icon_w_width = XTextWidth(IconFont,
X	tmp_win->icon_name, strlen(tmp_win->icon_name));
X
X    tmp_win->icon_w_width += 6;
X    if (tmp_win->icon_w_width < tmp_win->icon_width)
X    {
X	tmp_win->icon_x = (tmp_win->icon_width - tmp_win->icon_w_width)/2;
X	tmp_win->icon_x += 3;
X	tmp_win->icon_w_width = tmp_win->icon_width;
X    }
X    else
X    {
X	tmp_win->icon_x = 3;
X    }
X
X    if (tmp_win->icon_w_width == tmp_win->icon_width)
X	x = 0;
X    else
X	x = (tmp_win->icon_w_width - tmp_win->icon_width)/2;
X
X    XResizeWindow(dpy, tmp_win->icon_w, tmp_win->icon_w_width,
X	tmp_win->icon_height + IconFontHeight + 4);
X    if (tmp_win->icon_bm_w)
X    {
X	XMoveWindow(dpy, tmp_win->icon_bm_w, x, 0);
X	XMapWindow(dpy, tmp_win->icon_bm_w);
X    }
X    if (tmp_win->icon)
X    {
X	XClearArea(dpy, tmp_win->icon_w, 0, 0, 0, 0, False);
X	XDrawImageString(dpy, tmp_win->icon_w,
X	    IconNormalGC,
X	    tmp_win->icon_x, tmp_win->icon_y,
X	    tmp_win->icon_name, strlen(tmp_win->icon_name));
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleClientMessage - client message event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleClientMessage()
X{
X#ifdef DEBUG
X    fprintf(stderr, "ClientMessage\n");
X#endif
X
X    enter_flag = FALSE;
X}
X/***********************************************************************
X *
X *  Procedure:
X *	HandleExpose - expose event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleExpose()
X{
X    MenuItem *tmp;
X
X#ifdef DEBUG
X    fprintf(stderr, "Expose %d\n", event.xexpose.count);
X#endif
X
X    if (event.xexpose.count != 0)
X	return;
X
X    if (w == VersionWindow)
X    {
X	XDrawImageString(dpy, VersionWindow, VersionNormalGC,
X	    twm_width + 10,
X	    2 + VersionFont->ascent, Version, strlen(Version));
X    }
X
X    if (tmp_win != NULL)
X    {
X	if (tmp_win->title_w == w)
X	{
X	    XDrawImageString(dpy, tmp_win->title_w,
X		TitleNormalGC,
X		TitleBarX, TitleBarY,
X		tmp_win->name, strlen(tmp_win->name));
X	    return;
X	}
X
X	if (tmp_win->icon_w == w)
X	{
X	    XDrawImageString(dpy, tmp_win->icon_w,
X		IconNormalGC,
X		tmp_win->icon_x, tmp_win->icon_y,
X		tmp_win->icon_name, strlen(tmp_win->icon_name));
X	    return;
X	}
X    }
X
X    if (XFindContext(dpy, w, MenuContext, &tmp) == 0)
X    {
X	if (tmp->func == F_TITLE)
X	    XDrawImageString(dpy,w, MenuTitleGC, tmp->y, MenuY,
X		tmp->item, strlen(tmp->item));
X	else if (tmp->state)
X	    XDrawImageString(dpy,w, MenuReverseGC, tmp->y, MenuY,
X		tmp->item, strlen(tmp->item));
X	else
X	    XDrawImageString(dpy,w, MenuNormalGC, tmp->y, MenuY,
X		tmp->item, strlen(tmp->item));
X
X	return;
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleDestroyNotify - DestroyNotify event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleDestroyNotify()
X{
X#ifdef DEBUG
X    fprintf(stderr, "DestroyNotify\n");
X#endif
X    if (tmp_win == NULL)
X	return;
X
X    if (tmp_win == Focus)
X    {
X	FocusOnRoot();
X    }
X    XDeleteContext(dpy, tmp_win->w, TwmContext);
X    XDeleteContext(dpy, tmp_win->frame, TwmContext);
X    XDeleteContext(dpy, tmp_win->title_w, TwmContext);
X    XDeleteContext(dpy, tmp_win->iconify_w, TwmContext);
X    XDeleteContext(dpy, tmp_win->resize_w, TwmContext);
X    XDeleteContext(dpy, tmp_win->icon_w, TwmContext);
X#ifndef NOFOCUS
X    XDeleteContext(dpy, tmp_win->focus_w, TwmContext);
X#endif
X    XDeleteContext(dpy, tmp_win->hilite_w, TwmContext);
X
X    XDestroyWindow(dpy, tmp_win->frame);
X    XDestroyWindow(dpy, tmp_win->icon_w);
X    tmp_win->prev->next = tmp_win->next;
X    if (tmp_win->next != NULL)
X	tmp_win->next->prev = tmp_win->prev;
X
X    free((char *)tmp_win);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleMapRequest - MapRequest event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleMapRequest()
X{
X    int stat;
X
X#ifdef DEBUG
X    fprintf(stderr, "MapRequest\n");
X#endif
X
X    /*
X    XBell(dpy, 0);
X    */
X
X    stat = XFindContext(dpy, event.xmaprequest.window, TwmContext, &tmp_win);
X    if (stat == XCNOENT)
X	tmp_win = NULL;
X
X    if (tmp_win == NULL)
X    {
X	XGrabServer(dpy);
X	XGrabKeyboard(dpy, Root, False, GrabModeSync, GrabModeSync,CurrentTime);
X	tmp_win = AddWindow(event.xmaprequest.window);
X	if (tmp_win->wmhints && (tmp_win->wmhints->flags & StateHint))
X	{
X	    switch (tmp_win->wmhints->initial_state)
X	    {
X		case DontCareState:
X		case NormalState:
X		case ZoomState:
X		case InactiveState:
X		    XMapWindow(dpy, tmp_win->w);
X		    XMapRaised(dpy, tmp_win->frame);
X		    break;
X
X		case IconicState:
X		    if (tmp_win->wmhints->flags & IconPositionHint)
X		    {
X			int x, y;
X
X			x = tmp_win->wmhints->icon_x;
X			y = tmp_win->wmhints->icon_y;
X
X			if (x > MyDisplayWidth)
X			    x = MyDisplayWidth - tmp_win->icon_w_width -
X				(2 * BorderWidth);
X
X			if (y > MyDisplayHeight)
X			    y = MyDisplayHeight - tmp_win->icon_height -
X				IconFontHeight - 4 - (2 * BorderWidth);
X
X
X			XMoveWindow(dpy, tmp_win->icon_w, x, y);
X		    }
X		    else
X		    {
X			XMoveWindow(dpy, tmp_win->icon_w, 0, 0);
X		    }
X
X		    XMapSubwindows(dpy, tmp_win->icon_w);
X		    XMapRaised(dpy, tmp_win->icon_w);
X		    tmp_win->iconified = TRUE;
X		    tmp_win->icon = TRUE;
X		    break;
X	    }
X	}
X	else
X	{
X	    if (!tmp_win->icon)
X	    {
X		XMapWindow(dpy, tmp_win->w);
X		XMapRaised(dpy, tmp_win->frame);
X	    }
X	}
X	XUngrabKeyboard(dpy, CurrentTime);
X	XUngrabServer(dpy);
X    }
X    else
X    {
X	if (!tmp_win->icon)
X	{
X	    XMapWindow(dpy, event.xmaprequest.window);
X	    XMapRaised(dpy, tmp_win->frame);
X	}
X    }
X    XRaiseWindow(dpy, VersionWindow);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleMapNotify - MapNotify event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleMapNotify()
X{
X#ifdef DEBUG
X    fprintf(stderr, "MapNotify\n");
X#endif
X    if (tmp_win == NULL)
X	return;
X
X    XMapSubwindows(dpy, tmp_win->title_w);
X    XMapSubwindows(dpy, tmp_win->frame);
X    XUnmapWindow(dpy, tmp_win->hilite_w);
X
X    if (tmp_win->title_height == 0)
X	XUnmapWindow(dpy, tmp_win->title_w);
X
X    XMapRaised(dpy, tmp_win->frame);
X    tmp_win->mapped = TRUE;
X    XRaiseWindow(dpy, VersionWindow);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleUnmapNotify - UnmapNotify event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleUnmapNotify()
X{
X#ifdef DEBUG
X    fprintf(stderr, "UnmapNotify\n");
X#endif
X    if (tmp_win == NULL)
X	return;
X
X    XUnmapWindow(dpy, tmp_win->frame);
X    tmp_win->mapped = FALSE;
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleMotionNotify - MotionNotify event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleMotionNotify()
X{
X#ifdef DEBUG
X    /*
X    fprintf(stderr, "MotionNotify\n");
X    */
X#endif
X    if (ConstMove)
X    {
X	switch (ConstMoveDir)
X	{
X	    case MOVE_NONE:
X		if (event.xmotion.x_root < ConstMoveXL ||
X		    event.xmotion.x_root > ConstMoveXR)
X		    ConstMoveDir = MOVE_HORIZ;
X
X		if (event.xmotion.y_root < ConstMoveYT ||
X		    event.xmotion.y_root > ConstMoveYB)
X		    ConstMoveDir = MOVE_VERT;
X
X		XQueryPointer(dpy, DragWindow, &JunkRoot, &JunkChild,
X		    &JunkX, &JunkY, &DragX, &DragY, &JunkMask);
X		break;
X
X	    case MOVE_VERT:
X		ConstMoveY = event.xmotion.y_root - DragY - BorderWidth;
X		break;
X
X	    case MOVE_HORIZ:
X		ConstMoveX= event.xmotion.x_root - DragX - BorderWidth;
X		break;
X	}
X
X	if (ConstMoveDir != MOVE_NONE)
X	{
X	    int xl, yt, xr, yb, w, h;
X
X	    xl = ConstMoveX;
X	    yt = ConstMoveY;
X	    w = DragWidth + 2 * BorderWidth;
X	    h = DragHeight + 2 * BorderWidth;
X
X	    if (DontMoveOff)
X	    {
X		xr = xl + w;
X		yb = yt + h;
X
X		if (xl < 0)
X		    xl = 0;
X		if (xr > MyDisplayWidth)
X		    xl = MyDisplayWidth - w;
X
X		if (yt < 0)
X		    yt = 0;
X		if (yb > MyDisplayHeight)
X		    yt = MyDisplayHeight - h;
X	    }
X	    MoveOutline(event.xmotion.root, xl, yt, w, h);
X	}
X	return;
X    }
X
X    if (DragWindow != NULL)
X    {
X	int xl, yt, xr, yb, w, h;
X
X	xl = event.xmotion.x_root - DragX - BorderWidth;
X	yt = event.xmotion.y_root - DragY - BorderWidth;
X	w = DragWidth + 2 * BorderWidth;
X	h = DragHeight + 2 * BorderWidth;
X
X	if (DontMoveOff)
X	{
X	    xr = xl + w;
X	    yb = yt + h;
X
X	    if (xl < 0)
X		xl = 0;
X	    if (xr > MyDisplayWidth)
X		xl = MyDisplayWidth - w;
X
X	    if (yt < 0)
X		yt = 0;
X	    if (yb > MyDisplayHeight)
X		yt = MyDisplayHeight - h;
X	}
X
X	MoveOutline(event.xmotion.root, xl, yt, w, h);
X	return;
X    }
X
X    if (ResizeWindow != NULL)
X    {
X	XFindContext(dpy, ResizeWindow, TwmContext, &tmp_win);
X	DoResize(event.xmotion.x_root, event.xmotion.y_root, tmp_win);
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleButtonRelease - ButtonRelease event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleButtonRelease()
X{
X    int xl, xr, yt, yb, w, h;
X
X#ifdef DEBUG
X    fprintf(stderr, "ButtonRelease\n");
X#endif
X
X    if (RootFunction == NULL)
X    {
X	XUngrabPointer(dpy, CurrentTime);
X	XUngrabServer(dpy);
X	EventHandler[EnterNotify] = HandleEnterNotify;
X	EventHandler[LeaveNotify] = HandleLeaveNotify;
X	EventHandler[Expose] = HandleExpose;
X    }
X
X    if (DragWindow != NULL)
X    {
X	XEvent client_event;
X
X	MoveOutline(event.xbutton.root, 0, 0, 0, 0);
X
X	xl = event.xbutton.x_root - DragX - BorderWidth;
X	yt = event.xbutton.y_root - DragY - BorderWidth;
X
X	if (ConstMove)
X	{
X	    if (ConstMoveDir == MOVE_HORIZ)
X		yt = ConstMoveY;
X
X	    if (ConstMoveDir == MOVE_VERT)
X		xl = ConstMoveX;
X
X	    if (ConstMoveDir == MOVE_NONE)
X	    {
X		yt = ConstMoveY;
X		xl = ConstMoveX;
X	    }
X	}
X	
X	w = DragWidth + 2 * BorderWidth;
X	h = DragHeight + 2 * BorderWidth;
X
X	if (DontMoveOff)
X	{
X	    xr = xl + w;
X	    yb = yt + h;
X
X	    if (xl < 0)
X		xl = 0;
X	    if (xr > MyDisplayWidth)
X		xl = MyDisplayWidth - w;
X
X	    if (yt < 0)
X		yt = 0;
X	    if (yb > MyDisplayHeight)
X		yt = MyDisplayHeight - h;
X	}
X
X	XFindContext(dpy, DragWindow, TwmContext, &tmp_win);
X	if (DragWindow == tmp_win->frame)
X	{
X	    tmp_win->frame_x = xl;
X	    tmp_win->frame_y = yt;
X	}
X
X	XMoveWindow(dpy, DragWindow, xl, yt);
X	if (!NoRaiseMove)
X	    XRaiseWindow(dpy, DragWindow);
X	DragWindow = NULL;
X	ConstMove = FALSE;
X
X	enter_flag = TRUE;
X	client_event.type = ClientMessage;
X	XSendEvent(dpy, tmp_win->frame, False, 0, &client_event);
X	SetHints(tmp_win);
X
X	return;
X    }
X
X    if (ResizeWindow != NULL)
X    {
X	EndResize();
X	EventHandler[EnterNotify] = HandleEnterNotify;
X	EventHandler[LeaveNotify] = HandleLeaveNotify;
X	XUngrabPointer(dpy, CurrentTime);
X	XUngrabServer(dpy);
X	return;
X    }
X
X    if (ActiveMenu != NULL)
X    {
X	MenuRoot *tmp;
X
X	for (tmp = ActiveMenu; tmp != NULL; tmp = tmp->prev)
X	{
X	    XUnmapWindow(dpy, tmp->shadow);
X	    XUnmapWindow(dpy, tmp->w);
X	}
X	XFlush(dpy);
X	ActiveMenu = NULL;
X
X	if (ActiveItem != NULL)
X	{
X	    ActiveItem->state = 0;
X	    ExecuteFunction(ActiveItem->func, ActiveItem, NULL, ButtonWindow,
X		ButtonEvent, Context, TRUE);
X	    ActiveItem = NULL;
X	    Context = C_NO_CONTEXT;
X	    ButtonWindow = NULL;
X	}
X	return;
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleButtonPress - ButtonPress event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleButtonPress()
X{
X    int modifier;
X
X#ifdef DEBUG
X    fprintf(stderr, "ButtonPress\n");
X#endif
X
X    if (ResizeWindow != NULL ||
X	DragWindow != NULL  ||
X	ActiveMenu != NULL)
X	return;
X
X    XUnmapWindow(dpy, VersionWindow);
X    if (AddingWindow != 0)
X    {
X	AddingWindow -= 1;
X	return;
X    }
X
X    /* check the title bar buttons */
X
X    if (tmp_win && w == tmp_win->iconify_w)
X    {
X	ExecuteFunction(F_ICONIFY, NULL, w, tmp_win, event, C_TITLE, FALSE);
X	return;
X    }
X
X    if (tmp_win && w == tmp_win->resize_w)
X    {
X	ExecuteFunction(F_RESIZE, NULL, w, tmp_win, event, C_TITLE, FALSE);
X	return;
X    }
X
X#ifndef NOFOCUS
X    if (tmp_win && w == tmp_win->focus_w)
X    {
X	ExecuteFunction(F_FOCUS, NULL, w, tmp_win, event, C_TITLE, FALSE);
X	return;
X    }
X#endif
X
X    Context = C_NO_CONTEXT;
X
X    if (w == Root)
X	Context = C_ROOT;
X    if (tmp_win)
X    {
X	if (w == tmp_win->title_w)
X	    Context = C_TITLE;
X	if (w == tmp_win->w)
X	    Context = C_WINDOW;
X	if (w == tmp_win->icon_w)
X	    Context = C_ICON;
X    }
X
X    /* this section of code checks to see if we were in the middle of
X     * a command executed from a menu
X     */
X    if (RootFunction != NULL)
X    {
X	if (w == Root)
X	{
X	    RootFunction = NULL;
X	    XBell(dpy, 0);
X	    return;
X	}
X
X	ExecuteFunction(RootFunction, ButtonMouse.item, w,
X	    tmp_win, event, Context, FALSE);
X
X	RootFunction = NULL;
X	return;
X    }
X
X    ButtonEvent = event;
X    ButtonWindow = tmp_win;
X
X    /* if we get to here, we have to execute a function or pop up a 
X     * menu
X     */
X    modifier = event.xbutton.state & (ShiftMask | ControlMask | Mod1Mask);
X
X    ButtonMouse = Mouse[event.xbutton.button][Context][modifier];
X
X    if (Context == C_NO_CONTEXT)
X	return;
X
X    RootFunction = NULL;
X    if (Mouse[event.xbutton.button][Context][modifier].func == F_MENU &&
X	Mouse[event.xbutton.button][Context][modifier].menu->items != 0)
X    {
X	XGrabPointer(dpy, Root, True,
X	    ButtonReleaseMask,
X	    GrabModeAsync, GrabModeSync,
X	    Root, RightArrowCursor, CurrentTime);
X
X	PopUpMenu(Mouse[event.xbutton.button][Context][modifier].menu, 
X	    event.xbutton.x_root, event.xbutton.y_root);
X    }
X    else if (Mouse[event.xbutton.button][Context][modifier].func != NULL)
X    {
X	ExecuteFunction(Mouse[event.xbutton.button][Context][modifier].func,
X	    Mouse[event.xbutton.button][Context][modifier].item,
X	    w, tmp_win, event, Context, FALSE);
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleEnterNotify - EnterNotify event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleEnterNotify()
X{
X    MenuItem *tmp;
X
X#ifdef DEBUG
X    fprintf(stderr, "EnterNotify\n");
X#endif
X
X    if (ActiveMenu == NULL && tmp_win != NULL)
X    {
X	if (FocusRoot && tmp_win->mapped)
X	{
X	    if (Focus != NULL && Focus != tmp_win)
X		XUnmapWindow(dpy, Focus->hilite_w);
X
X	    XMapWindow(dpy, tmp_win->hilite_w);
X	    /*
X	    XSetWindowBorder(dpy, tmp_win->frame, Foreground);
X	    XSetWindowBorder(dpy, tmp_win->title_w, Foreground);
X	    */
X	    XSetInputFocus(dpy, tmp_win->w, RevertToPointerRoot,
X		    CurrentTime);
X	    XUngrabKeyboard(dpy, CurrentTime);
X	    Focus = tmp_win;
X	}
X	if (enter_flag == FALSE && tmp_win->auto_raise)
X	{
X	    XEvent client_event;
X
X	    XRaiseWindow(dpy, tmp_win->frame);
X	    enter_flag = TRUE;
X	    client_event.type = ClientMessage;
X	    XSendEvent(dpy, tmp_win->frame, False, 0, &client_event);
X	}
X	return;
X    }
X
X
X    if (XFindContext(dpy, w, MenuContext, &tmp) != 0)
X	return;
X
X    if (w == tmp->w && tmp->root == ActiveMenu)
X    {
X	if (ActiveItem != NULL && ActiveItem->state != 0)
X	{
X#ifdef DEBUG
X	    fprintf(stderr, "turning off \"%s\"\n", ActiveItem->item);
X#endif
X	    XFillRectangle(dpy, ActiveItem->w,MenuXorGC,0,0,1000, 100);
X	    if (tmp->pull != NULL)
X		XFillRectangle(dpy, ActiveItem->pull, MenuXorGC,0,0,1000, 100);
X	    ActiveItem->state = 0;
X	}
X
X	if (tmp->state == 0)
X	{
X#ifdef DEBUG
X	    fprintf(stderr, "turning on \"%s\"\n", tmp->item);
X#endif
X	    XFillRectangle(dpy, tmp->w,MenuXorGC,0,0,1000, 100);
X	    if (tmp->pull)
X		XFillRectangle(dpy, tmp->pull, MenuXorGC,0,0,1000, 100);
X	    tmp->state = 1;
X	}
X	ActiveItem = tmp;
X
X	return;
X    }
X
X    if (w == tmp->pull && tmp->root == ActiveMenu)
X    {
X	XGrabServer(dpy);
X	PopUpMenu(tmp->sub, event.xcrossing.x_root,
X	    event.xcrossing.y_root);
X	XUngrabServer(dpy);
X
X	return;
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleLeaveNotify - LeaveNotify event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleLeaveNotify()
X{
X    MenuItem *tmp;
X
X#ifdef DEBUG
X    fprintf(stderr, "LeaveNotify\n");
X#endif
X    if (tmp_win != NULL)
X    {
X	XUnmapWindow(dpy, VersionWindow);
X	if (FocusRoot)
X	{
X	    if (event.xcrossing.detail != NotifyInferior)
X	    {
X		XUnmapWindow(dpy, tmp_win->hilite_w);
X		/*
X		XSetWindowBorderPixmap(dpy, tmp_win->frame, GrayTile);
X		XSetWindowBorderPixmap(dpy, tmp_win->title_w, GrayTile);
X		*/
X		XGrabKeyboard(dpy, Root, True, GrabModeAsync,
X		    GrabModeAsync, CurrentTime);
X		XSetInputFocus(dpy, Root, RevertToPointerRoot,
X			CurrentTime);
X		Focus = NULL;
X	    }
X	}
X	return;
X    }
X
X    if (XFindContext(dpy, w, MenuContext, &tmp) != 0)
X	return;
X
X    if (w == tmp->root->w)
X    {
X	int rootx, rooty, x, y;
X	int wx, wy, ww, wh;
X
X	/* see if the mouse really left the window
X	 * or just crossed into a sub-window
X	 */
X
X	XQueryPointer(dpy, w, &JunkRoot,
X	    &JunkChild, &rootx, &rooty, &x, &y, &JunkMask);
X
X	XGetGeometry(dpy, w, &JunkRoot, &wx, &wy,
X	    &ww, &wh, &JunkBW,
X	    &JunkDepth);
X	
X	if (rootx < wx ||
X	    rootx > (wx + ww) ||
X	    rooty < wy ||
X	    rooty > (wy + wh))
X	{
X	    ActiveItem = NULL;
X	    if (tmp->root->prev != NULL)
X	    {
X		if (ActiveMenu == tmp->root)
X		{
X		    XUnmapWindow(dpy, ActiveMenu->shadow);
X		    XUnmapWindow(dpy, ActiveMenu->w);
X		    ActiveMenu = tmp->root->prev;
X		}
X	    }
X	}
X	return;
X    }
X
X    if (w == tmp->w);
X    {
X	if (tmp == ActiveItem)
X	    ActiveItem = NULL;
X
X	if (tmp->state != 0)
X	{
X#ifdef DEBUG
X	    fprintf(stderr, "turning off \"%s\"\n", tmp->item);
X#endif
X	    XFillRectangle(dpy, tmp->w,MenuXorGC,0,0,1000, 100);
X	    if (tmp->pull != NULL)
X		XFillRectangle(dpy, tmp->pull, MenuXorGC,0,0,1000, 100);
X	    tmp->state = 0;
X	}
X
X	return;
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleConfigureNotify - ConfigureNotify event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleConfigureNotify()
X{
X#ifdef DEBUG
X    fprintf(stderr, "ConfigureNotify\n");
X#endif
X    if (tmp_win == NULL)
X	return;
X
X    if (event.xconfigure.override_redirect)
X	return;
X
X    SetupWindow(tmp_win,
X	tmp_win->frame_x + event.xconfigure.x,
X	tmp_win->frame_y + event.xconfigure.y - tmp_win->title_height,
X	event.xconfigure.width,
X	event.xconfigure.height + tmp_win->title_height);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	HandleUnknown - unknown event handler
X *
X ***********************************************************************
X */
X
Xvoid
XHandleUnknown()
X{
X#ifdef DEBUG
X    fprintf(stderr, "type = %d\n", event.type);
X#endif
X}
SHAR_EOF
if test 27714 -ne "`wc -c < events.c`"
then
    echo shar: error transmitting "events.c" '(should have been 27714 characters)'
fi
fi
if test -f 'list.c'
then
    echo shar: will not over-write existing file "list.c"
else
echo extracting "list.c"
sed 's/^X//' >list.c <<'SHAR_EOF'
X/*****************************************************************************/
X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
X/**                          Salt Lake City, Utah                           **/
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 Evans & Sutherland  not be used in advertising or publi-    **/
X/**    city pertaining to distribution  of the software without  specif-    **/
X/**    ic, written prior permission.                                        **/
X/**                                                                         **/
X/**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
X/**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
X/**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
X/**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
X/**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
X/**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
X/**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
X/**    FORMANCE OF THIS SOFTWARE.                                           **/
X/*****************************************************************************/
X
X/**********************************************************************
X *
X * $Header: list.c,v 1.5 88/05/31 07:43:00 tlastran Exp $
X *
X * TWM code to deal with the name lists for the NoTitle list and
X * the AutoRaise list
X *
X * 11-Apr-88 Tom LaStrange        Initial Version.
X *
X **********************************************************************/
X
X#ifndef lint
Xstatic char RCSinfo[]=
X"$Header: list.c,v 1.5 88/05/31 07:43:00 tlastran Exp $";
X#endif lint
X
X#include <stdio.h>
X#include "twm.h"
X#include "gram.h"
X
Xtypedef struct name_list name_list;
X
Xstruct name_list
X{
X    name_list *next;		/* pointer to the next name */
X    char *name;			/* the name of the window */
X    char *ptr;			/* list dependent data */
X};
X
Xname_list *NoTitle = NULL;	/* list of window names with no title bar */
Xname_list *AutoRaise = NULL;	/* list of window names to auto-raise */
Xname_list *Icons = NULL;	/* list of window names and icons */
X
X/***********************************************************************
X *
X *  Procedure:
X *	AddToList - add a window name to the appropriate list
X *
X *  Inputs:
X *	list	- a #define to identify the list
X *	name	- a pointer to the name of the window 
X *	ptr	- pointer to list dependent data
X *
X *  Special Considerations
X *	If the list does not use the ptr value, a non-null value 
X *	should be placed in it.  LookInList returns this ptr value
X *	and procedures calling LookInList will check for a non-null 
X *	return value as an indication of success.
X *
X ***********************************************************************
X */
X
Xvoid
XAddToList(list, name, ptr)
Xint list;
Xchar *name;
Xchar *ptr;
X{
X    name_list *nptr;
X
X    nptr = (name_list *)malloc(sizeof(name_list));
X    if (nptr == NULL)
X    {
X	fprintf(stderr, "twm: out of memory\n");
X	Done();
X    }
X
X    nptr->name = name;
X
X    switch (list)
X    {
X    case AUTO_RAISE:
X	nptr->next = AutoRaise;
X	nptr->ptr = (char *)TRUE;
X	AutoRaise = nptr;
X	break;
X
X    case NO_TITLE:
X	nptr->next = NoTitle;
X	nptr->ptr = (char *)TRUE;
X	NoTitle = nptr;
X	break;
X
X    case ICONS:
X	nptr->next = Icons;
X	nptr->ptr = ptr;	/* this is the pixmap */
X	Icons = nptr;
X	break;
X    }
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	LookInList - look through a list for a window name, or class
X *
X *  Returned Value:
X *	the ptr field of the list structure or NULL if the name 
X *	or class was not found in the list
X *
X *  Inputs:
X *	list	- a #define to identify the list
X *	name	- a pointer to the name to look for
X *	class	- a pointer to the class to look for
X *
X ***********************************************************************
X */
X
Xchar *
XLookInList(list, name, class)
Xint list;
Xchar *name;
XXClassHint *class;
X{
X    name_list *l;
X    name_list *nptr;
X
X    switch (list)
X    {
X    case AUTO_RAISE:
X	l = AutoRaise;
X	break;
X
X    case NO_TITLE:
X	l = NoTitle;
X	break;
X
X    case ICONS:
X	l = Icons;
X	break;
X    }
X
X    for (nptr = l; nptr != NULL; nptr = nptr->next)
X    {
X	int len;
X
X	len = strlen(nptr->name);
X	if (strncmp(name, nptr->name, len) == 0 ||
X	    strncmp(class->res_name, nptr->name, len) == 0 ||
X	    strncmp(class->res_class, nptr->name, len) == 0)
X	    return (nptr->ptr);
X    }
X    return (NULL);
X}
SHAR_EOF
if test 5140 -ne "`wc -c < list.c`"
then
    echo shar: error transmitting "list.c" '(should have been 5140 characters)'
fi
fi
if test -f 'resize.c'
then
    echo shar: will not over-write existing file "resize.c"
else
echo extracting "resize.c"
sed 's/^X//' >resize.c <<'SHAR_EOF'
X/*****************************************************************************/
X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
X/**                          Salt Lake City, Utah                           **/
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 Evans & Sutherland  not be used in advertising or publi-    **/
X/**    city pertaining to distribution  of the software without  specif-    **/
X/**    ic, written prior permission.                                        **/
X/**                                                                         **/
X/**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
X/**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
X/**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
X/**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
X/**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
X/**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
X/**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
X/**    FORMANCE OF THIS SOFTWARE.                                           **/
X/*****************************************************************************/
X
X/***********************************************************************
X *
X * $Header: resize.c,v 1.16 88/06/03 10:31:52 tlastran Exp $
X *
X * window resizing borrowed from the "wm" window manager
X *
X * 11-Dec-87 Thomas E. LaStrange		File created
X *
X ***********************************************************************/
X
X#ifndef lint
Xstatic char RCSinfo[]=
X"$Header: resize.c,v 1.16 88/06/03 10:31:52 tlastran Exp $";
X#endif
X
X#include <stdio.h>
X#include "twm.h"
X#include "util.h"
X#include "resize.h"
X#include "add_window.h"
X#include "resize.bm"
X#ifndef NOFOCUS
X#include "focus.bm"
X#else
X#define focus_width 0
X#endif
X
X#define MINHEIGHT 32
X#define MINWIDTH 60
X
Xstatic int dragx;	/* all these variables are used */
Xstatic int dragy;	/* in resize operations */
Xstatic int dragWidth;
Xstatic int dragHeight;
X
Xstatic int origx;
Xstatic int origy;
Xstatic int origWidth;
Xstatic int origHeight;
X
Xstatic int clampTop;
Xstatic int clampBottom;
Xstatic int clampLeft;
Xstatic int clampRight;
X
Xstatic int last_width;
Xstatic int last_height;
X
X/***********************************************************************
X *
X *  Procedure:
X *	StartResize - begin a window resize operation
X *
X *  Inputs:
X *	ev	- the event structure (button press)
X *	tmp_win	- the TwmWindow pointer
X *
X ***********************************************************************
X */
X
Xvoid
XStartResize(ev, tmp_win)
XXEvent ev;
XTwmWindow *tmp_win;
X{
X    Window      junkRoot;
X    int         junkbw, junkDepth;
X
X    ResizeWindow = tmp_win->frame;
X    XGrabServer(dpy);
X    XGrabPointer(dpy, ev.xbutton.root, True,
X	ButtonReleaseMask,
X	GrabModeAsync, GrabModeSync,
X	Root, MoveCursor, CurrentTime);
X
X    XGetGeometry(dpy, (Drawable) tmp_win->frame, &junkRoot,
X	&dragx, &dragy, &dragWidth, &dragHeight, &junkbw,
X		 &junkDepth);
X    dragx += BorderWidth;
X    dragy += BorderWidth;
X    origx = dragx;
X    origy = dragy;
X    origWidth = dragWidth;
X    origHeight = dragHeight;
X    clampTop = clampBottom = clampLeft = clampRight = 0;
X
X    XMoveWindow(dpy, SizeWindow, 0, 0);
X    XMapRaised(dpy, SizeWindow);
X    last_width = 0;
X    last_height = 0;
X    DisplaySize(tmp_win, origWidth, origHeight);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	AddStartResize - begin a window resize operation from AddWindow
X *
X *  Inputs:
X *	tmp_win	- the TwmWindow pointer
X *
X ***********************************************************************
X */
X
Xvoid
XAddStartResize(tmp_win, x, y, w, h)
XTwmWindow *tmp_win;
Xint x, y, w, h;
X{
X    Window      junkRoot;
X    int         junkbw, junkDepth;
X
X    XGrabServer(dpy);
X    XGrabPointer(dpy, Root, True,
X	ButtonReleaseMask,
X	GrabModeAsync, GrabModeSync,
X	Root, MoveCursor, CurrentTime);
X
X    dragx = x + BorderWidth;
X    dragy = y + BorderWidth;
X    origx = dragx;
X    origy = dragy;
X    dragWidth = origWidth = w - 2 * BorderWidth;
X    dragHeight = origHeight = h - 2 * BorderWidth;
X    clampTop = clampBottom = clampLeft = clampRight = 0;
X
X    XMoveWindow(dpy, SizeWindow, 0, InitialFontHeight + 4 + BW);
X    XMapRaised(dpy, SizeWindow);
X    last_width = 0;
X    last_height = 0;
X    DisplaySize(tmp_win, origWidth, origHeight);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	DoResize - move the rubberband around.  This is called for
X *		   each motion event when we are resizing 
X *
X *  Inputs:
X *	x_root	- the X corrdinate in the root window
X *	y_root	- the Y corrdinate in the root window
X *	tmp_win	- the current twm window
X *
X ***********************************************************************
X */
X
Xvoid
XDoResize(x_root, y_root, tmp_win)
Xint x_root;
Xint y_root;
XTwmWindow *tmp_win;
X{
X    int action;
X
X    action = 0;
X
X    if (clampTop) {
X	int         delta = y_root - dragy;
X	if (dragHeight - delta < MINHEIGHT) {
X	    delta = dragHeight - MINHEIGHT;
X	    clampTop = 0;
X	}
X	dragy += delta;
X	dragHeight -= delta;
X	action = 1;
X    }
X    else if (y_root <= dragy/* ||
X	     y_root == findRootInfo(root)->rooty*/) {
X	dragy = y_root;
X	dragHeight = origy + origHeight -
X	    y_root;
X	clampBottom = 0;
X	clampTop = 1;
X	action = 1;
X    }
X    if (clampLeft) {
X	int         delta = x_root - dragx;
X	if (dragWidth - delta < MINWIDTH) {
X	    delta = dragWidth - MINWIDTH;
X	    clampLeft = 0;
X	}
X	dragx += delta;
X	dragWidth -= delta;
X	action = 1;
X    }
X    else if (x_root <= dragx/* ||
X	     x_root == findRootInfo(root)->rootx*/) {
X	dragx = x_root;
X	dragWidth = origx + origWidth -
X	    x_root;
X	clampRight = 0;
X	clampLeft = 1;
X	action = 1;
X    }
X    if (clampBottom) {
X	int         delta = y_root - dragy - dragHeight;
X	if (dragHeight + delta < MINHEIGHT) {
X	    delta = MINHEIGHT - dragHeight;
X	    clampBottom = 0;
X	}
X	dragHeight += delta;
X	action = 1;
X    }
X    else if (y_root >= dragy + dragHeight - 1/* ||
X	   y_root == findRootInfo(root)->rooty
X	   + findRootInfo(root)->rootheight - 1*/) {
X	dragy = origy;
X	dragHeight = 1 + y_root - dragy;
X	clampTop = 0;
X	clampBottom = 1;
X	action = 1;
X    }
X    if (clampRight) {
X	int         delta = x_root - dragx - dragWidth;
X	if (dragWidth + delta < MINWIDTH) {
X	    delta = MINWIDTH - dragWidth;
X	    clampRight = 0;
X	}
X	dragWidth += delta;
X	action = 1;
X    }
X    else if (x_root >= dragx + dragWidth - 1/* ||
X	     x_root == findRootInfo(root)->rootx +
X	     findRootInfo(root)->rootwidth - 1*/) {
X	dragx = origx;
X	dragWidth = 1 + x_root - origx;
X	clampLeft = 0;
X	clampRight = 1;
X	action = 1;
X    }
X    if (action) {
X	MoveOutline(Root,
X		    dragx - BorderWidth,
X		    dragy - BorderWidth,
X		    dragWidth + 2 * BorderWidth,
X		    dragHeight + 2 * BorderWidth);
X    }
X
X    DisplaySize(tmp_win, dragWidth, dragHeight);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	DisplaySize - display the size in the dimensions window
X *
X *  Inputs:
X *	tmp_win - the current twm window 
X *	width	- the width of the rubber band
X *	height	- the height of the rubber band
X *
X ***********************************************************************
X */
X
Xvoid
XDisplaySize(tmp_win, width, height)
XTwmWindow *tmp_win;
Xint width;
Xint height;
X{
X    char str[100];
X    int dwidth;
X    int dheight;
X
X    if (last_width == width && last_height == height)
X	return;
X
X    last_width = width;
X    last_height = height;
X
X    dwidth = width;
X    dheight = height - tmp_win->title_height;
X
X    if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
X    {
X	dwidth -= tmp_win->hints.min_width;
X	dheight -= tmp_win->hints.min_height;
X    }
X
X    if (tmp_win->hints.flags & PResizeInc)
X    {
X	dwidth /= tmp_win->hints.width_inc;
X	dheight /= tmp_win->hints.height_inc;
X    }
X
X    sprintf(str, "%d x %d", dwidth, dheight);
X
X    width = XTextWidth(SizeFont, str, strlen(str)) + 20;
X    strcat(str, "        ");
X    XResizeWindow(dpy, SizeWindow, width, SizeFontHeight + 4);
X    XRaiseWindow(dpy, SizeWindow);
X    XDrawImageString(dpy, SizeWindow, SizeNormalGC,
X	10, 2 + SizeFont->ascent, str, strlen(str));
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	EndResize - finish the resize operation
X *
X ***********************************************************************
X */
X
Xvoid
XEndResize()
X{
X    TwmWindow *tmp_win;
X    Window w;
X
X#ifdef DEBUG
X    fprintf(stderr, "EndResize\n");
X#endif
X
X    XUnmapWindow(dpy, SizeWindow);
X    MoveOutline(Root, 0, 0, 0, 0);
X
X    XFindContext(dpy, ResizeWindow, TwmContext, &tmp_win);
X
X    dragHeight = dragHeight - tmp_win->title_height;
X
X    if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
X    {
X	dragWidth -= tmp_win->hints.min_width;
X	dragHeight -= tmp_win->hints.min_height;
X    }
X
X    if (tmp_win->hints.flags & PResizeInc)
X    {
X	dragWidth /= tmp_win->hints.width_inc;
X	dragHeight /= tmp_win->hints.height_inc;
X
X	dragWidth *= tmp_win->hints.width_inc;
X	dragHeight *= tmp_win->hints.height_inc;
X    }
X
X    if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
X    {
X	dragWidth += tmp_win->hints.min_width;
X	dragHeight += tmp_win->hints.min_height;
X    }
X
X    dragHeight = dragHeight + tmp_win->title_height;
X
X    SetupWindow(tmp_win,
X	dragx - BorderWidth,
X	dragy - BorderWidth,
X	dragWidth, dragHeight);
X
X#ifdef SUN386
X    /* This is a kludge to fix a problem in the Sun 386 server which
X     * causes windows to not be repainted after a resize operation.
X     */
X    w = XCreateSimpleWindow(dpy, tmp_win->frame,
X	0, 0, 9999, 9999, 0, Black, Black);
X
X    XMapWindow(dpy, w);
X    XDestroyWindow(dpy, w);
X    XFlush(dpy);
X#endif
X 
X    if (!NoRaiseResize)
X	XRaiseWindow(dpy, tmp_win->frame);
X
X    ResizeWindow = NULL;
X    SetHints(tmp_win);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	AddEndResize - finish the resize operation for AddWindow
X *
X ***********************************************************************
X */
X
Xvoid
XAddEndResize(tmp_win)
XTwmWindow *tmp_win;
X{
X
X#ifdef DEBUG
X    fprintf(stderr, "AddEndResize\n");
X#endif
X
X    XUnmapWindow(dpy, SizeWindow);
X
X    dragHeight = dragHeight - tmp_win->title_height;
X
X    if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
X    {
X	dragWidth -= tmp_win->hints.min_width;
X	dragHeight -= tmp_win->hints.min_height;
X    }
X
X    if (tmp_win->hints.flags & PResizeInc)
X    {
X	dragWidth /= tmp_win->hints.width_inc;
X	dragHeight /= tmp_win->hints.height_inc;
X
X	dragWidth *= tmp_win->hints.width_inc;
X	dragHeight *= tmp_win->hints.height_inc;
X    }
X
X    if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
X    {
X	dragWidth += tmp_win->hints.min_width;
X	dragHeight += tmp_win->hints.min_height;
X    }
X
X    AddingX = dragx;
X    AddingY = dragy;
X    AddingW = dragWidth + (2 * BorderWidth);
X    AddingH = dragHeight + tmp_win->title_height + (2 * BorderWidth);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	SetupWindow - set window sizes, this was called from either
X *		AddWindow, EndResize, or HandleConfigureNotify.
X *
X *  Inputs:
X *	tmp_win	- the TwmWindow pointer
X *	x	- the x coordinate of the frame window
X *	y	- the y coordinate of the frame window
X *	w	- the width of the frame window
X *	h	- the height of the frame window
X *
X *  Special Considerations:
X *	This routine will check to make sure the window is not completely 
X *	off the display, if it is, it'll bring some of it back on.
X *
X ***********************************************************************
X */
X
Xvoid
XSetupWindow(tmp_win, x, y, w, h)
XTwmWindow *tmp_win;
Xint x, y, w, h;
X{
X    XWindowChanges xwc;
X    unsigned int   xwcm;
X    int width;
X
X#ifdef DEBUG
X    fprintf(stderr, "SetupWindow: x=%d, y=%d, w=%d, h=%d\n",
X	x, y, w, h);
X#endif
X
X    if (x > MyDisplayWidth)
X	x = MyDisplayWidth - 64;
X    if (y > MyDisplayHeight)
X	y = MyDisplayHeight - 64;
X
X    tmp_win->frame_x = x;
X    tmp_win->frame_y = y;
X
X    XMoveResizeWindow(dpy, tmp_win->frame, x, y, w, h);
X
X    xwcm = CWWidth;
X    xwc.width = w;
X    XConfigureWindow(dpy, tmp_win->title_w, xwcm, &xwc);
X
X    tmp_win->attr.width = w;
X    tmp_win->attr.height = h - tmp_win->title_height;
X
X    XMoveResizeWindow(dpy, tmp_win->w, 0, tmp_win->title_height, w, 
X	h - tmp_win->title_height);
X
X    xwcm = CWX;
X    xwc.x = w - resize_width - 1;
X    XConfigureWindow(dpy, tmp_win->resize_w, xwcm, &xwc);
X
X    xwc.x = w - resize_width - focus_width - 3;
X#ifndef NOFOCUS
X    XConfigureWindow(dpy, tmp_win->focus_w, xwcm, &xwc);
X#endif
X
X    width = w - TitleBarX - focus_width - resize_width - 5 -
X	tmp_win->name_width - 10;
X
X    if (width <= 0)
X    {
X	xwc.x = MyDisplayWidth;
X	xwc.width = 1;
X    }
X    else
X    {
X	xwc.x = TitleBarX + tmp_win->name_width + 6;
X	xwc.width = width;
X    }
X
X    xwcm = CWX | CWWidth;
X    XConfigureWindow(dpy, tmp_win->hilite_w, xwcm, &xwc);
X}
X
X/***********************************************************************
X *
X *  Procedure:
X *	SetHints - set window hints so that if twm is killed the windows
X *		will start up in the same places they were at when twm was
X *		killed.
X *
X *  Inputs:
X *	tmp_win	- the TwmWindow pointer
X *
X ***********************************************************************
X */
X
Xvoid
XSetHints(tmp_win)
XTwmWindow *tmp_win;
X{
X    XWMHints wmhints;
X    XSizeHints hints;
X    int x, y, w, h;
X
X    /*
X    wmhints = *(tmp_win->wmhints);
X
X    if (tmp_win->icon)
X	wmhints.initial_state = IconicState;
X    else
X	wmhints.initial_state = NormalState;
X
X    XGetGeometry(dpy, tmp_win->icon_w, &JunkRoot, &x, &y, &w, &h,
X	&JunkBW, &JunkDepth);
X    wmhints.icon_x = x;
X    wmhints.icon_y = y;
X
X    wmhints.flags |= (StateHint | IconPositionHint);
X    XSetWMHints(dpy, tmp_win->w, &wmhints);
X    */
X
X    XGetGeometry(dpy, tmp_win->frame, &JunkRoot, &x, &y, &w, &h,
X	&JunkBW, &JunkDepth);
X    hints = tmp_win->hints;
X    hints.x = x;
X    hints.y = y + tmp_win->title_height;
X    hints.width = w;
X    hints.height = h - tmp_win->title_height;
X
X    hints.flags |= (USPosition | USSize);
X    XSetNormalHints(dpy, tmp_win->w, &hints);
X}
SHAR_EOF
if test 14884 -ne "`wc -c < resize.c`"
then
    echo shar: error transmitting "resize.c" '(should have been 14884 characters)'
fi
fi
# end of shell archive
exit 0