[mod.sources] v09i059: Terminal emulator for X window system, Part06/07

sources-request@mirror.TMC.COM (04/21/87)

Submitted by: edmoy@opal.Berkeley.EDU
Mod.sources: Volume 9, Issue 59
Archive-name: xterm6.6b/Part06

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	input.c menu.h misc.c resize.c screen.c
if test -f input.c
then
	echo shar: will not overwrite existing file "'input.c'"
else
echo 'x - input.c'
cat << \RAZZLE!DAZZLE > input.c
/*
 *	$Source: /u1/X/xterm/RCS/input.c,v $
 *	$Header: input.c,v 10.100 86/12/01 14:44:04 jg Rel $
 */

#ifndef lint
static char *rcsid_input_c = "$Header: input.c,v 10.100 86/12/01 14:44:04 jg Rel $";
#endif	lint

#include <X/mit-copyright.h>

/* Copyright    Massachusetts Institute of Technology    1984, 1985	*/

/* input.c */

#ifndef lint
static char sccs_id[] = "@(#)input.c\tX10/6.6B\t12/26/86";
#endif	lint

#include <X/Xlib.h>
#include <X/Xkeyboard.h>
#include "scrollbar.h"
#include "ptyx.h"
#include <stdio.h>

static char *kypd_num = "0x.\r123456,789-";
static char *kypd_apl = "pxnMqrstuvlwxym";
static char *cur = "DCBA";

Input (keyboard, screen, event)
register Keyboard	*keyboard;
register Screen		*screen;
register XKeyPressedEvent *event;
{
	register int keycode = event->detail;
	register char *string;
	register int col, key = FALSE;
	int	pty	= screen->respond;
	int	nbytes;
	ANSI	reply;

	string = XLookupMapping (event, &nbytes);

	if (nbytes > 0) {
		if(screen->TekGIN) {
			TekEnqMouse(*string++);
			TekGINoff();
			nbytes--;
		}
		while (nbytes-- > 0)
			unparseputc(*string++, pty);
		key = TRUE;
	} else {
	    keycode &= ValueMask; /* no longer need shift bits for anything */
	    reply.a_pintro = 0;
	    reply.a_final = 0;
	    reply.a_nparam = 0;
	    reply.a_inters = 0;
	    if (IsKeypadKey(keycode)) {
	  	if (keyboard->flags & KYPD_APL)	{
			reply.a_type   = SS3;
			unparseseq(&reply, pty);
			unparseputc(kypd_apl[keycode-KC_KEYPAD_0], pty);
		} else
			unparseputc(kypd_num[keycode-KC_KEYPAD_0], pty);
		key = TRUE;
	    } else if (IsCursorKey(keycode)) {
       		if (keyboard->flags & CURSOR_APL) {
			reply.a_type = SS3;
			unparseseq(&reply, pty);
			unparseputc(cur[keycode-KC_CURSOR_LEFT], pty);
		} else {
			reply.a_type = CSI;
			reply.a_final = cur[keycode-KC_CURSOR_LEFT];
			unparseseq(&reply, pty);
		}
		key = TRUE;
	    } else if (IsPFKey(keycode)) {
		reply.a_type = SS3;
		unparseseq(&reply, pty);
		unparseputc((char)(keycode-KC_PF1+'P'), pty);
		key = TRUE;
	    } else if (IsFunctionKey(keycode)) {
		reply.a_type = CSI;
		reply.a_nparam = 1;
		reply.a_param[0] = funcvalue(keycode);
		reply.a_final = '~';
		if (reply.a_param[0] > 0)
			unparseseq(&reply, pty);
		key = TRUE;
	    }
	}
	if(key && !screen->TekEmu) {
		if(screen->scrollkey && screen->topline != 0)
			ScrollToBottom(screen->sb);
		if(screen->marginbell) {
			col = screen->max_col - screen->nmarginbell;
			if(screen->bellarmed >= 0) {
				if(screen->bellarmed == screen->cur_row) {
					if(screen->cur_col >= col) {
						if(screen->cur_col == col)
							Bell();
						screen->bellarmed = -1;
					}
				} else
					screen->bellarmed = screen->cur_col <
					 col ? screen->cur_row : -1;
			} else if(screen->cur_col < col)
				screen->bellarmed = screen->cur_row;
		}
	}
#ifdef ENABLE_PRINT
	if (keycode == KC_F2) TekPrint();
#endif
	return;
}

funcvalue(keycode)
{
	switch (keycode) {
		case KC_F1:	return(11);
		case KC_F2:	return(12);
		case KC_F3:	return(13);
		case KC_F4:	return(14);
		case KC_F5:	return(15);
		case KC_F6:	return(17);
		case KC_F7:	return(18);
		case KC_F8:	return(19);
		case KC_F9:	return(20);
		case KC_F10:	return(21);
		case KC_F11:	return(23);
		case KC_F12:	return(24);
		case KC_F13:	return(25);
		case KC_F14:	return(26);
		case KC_F15:	return(28);
		case KC_F16:	return(29);
		case KC_F17:	return(31);
		case KC_F18:	return(32);
		case KC_F19:	return(33);
		case KC_F20:	return(34);
		case KC_E1 :	return(1);
		case KC_E2:	return(2);
		case KC_E3:	return(3);
		case KC_E4:	return(4);
		case KC_E5:	return(5);
		case KC_E6:	return(6);
		default:	return(-1);
	}
}
RAZZLE!DAZZLE
fi	# End input.c
if test -f menu.h
then
	echo shar: will not overwrite existing file "'menu.h'"
else
echo 'x - menu.h'
cat << \RAZZLE!DAZZLE > menu.h
/*
 *	$Source: /u1/X/xterm/RCS/menu.h,v $
 *	$Header: menu.h,v 10.100 86/12/01 14:40:05 jg Rel $
 */

/* @(#)menu.h       X10/6.6B 12/26/86 */
/*
 * Menu items are constructed as follows, starting from the left side:
 *
 *	menuItemPad
 *	space for check mark
 *	menuItemPad
 *	text + padding
 *	menuItemPad
 *
 * The padding for the text is that amount that this text is narrower than the
 * widest text.
 */

typedef struct _menuItem {
	int itemHeight;			/* total height of this item */
	int itemFlags;			/* flags of item */

#define	itemDisabled		0x0001	/* item is disabled */
#define	itemChecked		0x0002	/* item has check mark */
#define	itemStateMask		0x0003	/* mask for current state */
#define	itemSetDisabled		0x0004	/* item wants to be disabled */
#define	itemSetChecked		0x0008	/* item wants check mark */
#define	itemSetMask		0x000c	/* mask for desired state */
#define	itemSetMaskShift	2	/* for comparison with actual */
#define	itemChanged		0x0010	/* item desires change */

	char *itemText;			/* text of item */
	int itemTextWidth;		/* width of text */
	int itemTextLength;		/* length of text */
	struct _menuItem *nextItem;	/* next item in chain */
} MenuItem;

typedef struct _menu {
	int menuWidth;			/* full width of menu */
	int menuHeight;			/* full height of menu */
	int menuFlags;			/* flags of this menu */

# define	menuChanged	0x0001		/* menu changed, must redraw */
# define	menuItemChanged	0x0002		/* item changed, must redraw */
# define	menuMapped	0x0004		/* menu is now mapped */
# define	menuFreeze	0x0008		/* freeze when doing menu */
# define	menuSaveMenu	0x0010		/* save copy of menu */

	int menuMaxTextWidth;		/* width of widest text */
	int menuInitialItem;		/* < 0 none, >= 0 initial item */
	int menuBorderWidth;		/* width of border */
	int menuBgColor;		/* background color */
	int menuFgColor;		/* foreground color */
	Pixmap menuBgTile;		/* backgroud tile */
	FontInfo *menuFontInfo;		/* fontinfo for menu font */
	int menuItemPad;		/* pad amount */
	Window menuWindow;		/* window of menu */
	int (*menuEventHandler)();	/* external event handler */
	Cursor menuCursor;		/* cursor used in menu */
	Pixmap menuSaved;		/* copy of menu */
	Pixmap menuSavedImage;		/* copy of image under menu */
	int menuSavedImageX;		/* X coordinate of the saved image */
	int menuSavedImageY;		/* Y coordinate of the saved image */
	MenuItem *menuItems;		/* head of menu item chain */
	char *menuTitle;		/* title of menu */
	int menuTitleWidth;		/* width of title */
	int menuTitleLength;		/* length of title */
	int menuItemTop;		/* position of top of first item */
} Menu;

#define	checkMarkWidth		9
#define	checkMarkHeight		8
#define	defaultCursorWidth	16
#define	defaultCursorHeight	16
#define	defaultCursorX		1
#define	defaultCursorY		1
#define	grayHeight		16
#define	grayWidth		16
#define	lineSeparatorHeight	9

#define	CheckItem(menu,item)	SetItemCheck(menu,item,1)
#define	DisableItem(menu,item)	SetItemDisable(menu,item,1)
#define	EnableItem(menu,item)	SetItemDisable(menu,item,0)
#define	SetMenuEventHandler(menu,f)	menu->menuEventHandler = f
#define	UncheckItem(menu,item)	SetItemCheck(menu,item,0)

extern Menu *NewMenu();
RAZZLE!DAZZLE
fi	# End menu.h
if test -f misc.c
then
	echo shar: will not overwrite existing file "'misc.c'"
else
echo 'x - misc.c'
cat << \RAZZLE!DAZZLE > misc.c
/*
 *	$Source: /u1/X/xterm/RCS/misc.c,v $
 *	$Header: misc.c,v 10.101 86/12/02 08:49:20 swick Exp $
 */

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <ctype.h>
#include <pwd.h>
#include <sys/time.h>
#include <sys/file.h>
#include <X/Xlib.h>
#include "scrollbar.h"
#include "ptyx.h"
#include "data.h"
#include "error.h"
#include "gray.ic"
#include "hilite.ic"
#include "icon.ic"
#include "tek_icon.ic"
#include "wait.ic"
#include "waitmask.ic"
#include "../cursors/left_ptr.cursor"
#include "../cursors/left_ptr_mask.cursor"
#include "../cursors/tcross.cursor"
#include "../cursors/tcross_mask.cursor"
#include "../cursors/xterm.cursor"
#include "../cursors/xterm_mask.cursor"

#ifndef lint
static char sccs_id[] = "@(#)misc.c\tX10/6.6B\t1/9/87";
#endif	lint

xevents()
{
	XEvent reply;
	register XEvent *rep = & reply;
	register Screen *screen = &term.screen;

	if(screen->scroll_amt)
		FlushScroll(screen);
	XPending ();
	do {
		XNextEvent (&reply);
		xeventpass(&reply);
	} while (QLength() > 0);
}

xeventpass(rep)
register XEvent *rep;
{
	register Screen *screen = &term.screen;
	register Window window = rep->window;
	register Window w;
	register int i;

	switch ((int)rep->type) {
	 case KeyPressed:
		Input (&term.keyboard, &term.screen,
		 (XKeyPressedEvent *)rep);
		break;

	 case ExposeWindow:
		if(screen->sb && window == screen->sb->bar) {
#ifdef DEBUG
			if(debug)
				fputs("ExposeWindow scrollbar\n", stderr);
#endif DEBUG
			if(((XExposeEvent *)rep)->subwindow ==
			 screen->sb->button) {
				screen->sb->buttonstate = -1;
				DrawButton(screen->sb);
			} else if(((XExposeEvent *)rep)->subwindow ==
			 screen->sb->save) {
				screen->sb->savestate = -1;
				DrawSave(screen->sb);
			}
			break;
		}
		if (screen->active_icon) {
#ifdef DEBUG
		    fputs( "ExposeWindow icon\n", stderr );
#endif DEBUG
		    if (window == screen->iconVwin.window) {
		        if (!screen->icon_show) {
			    screen->mappedVwin = &screen->iconVwin;
			    screen->icon_show = TRUE;
			    screen->show = FALSE;
			    screen->timer = 0;
			    screen->holdoff = FALSE;
			    if(screen->fullTwin.window)
				moveiconwindow( screen->fullTwin.window,
						screen->fullVwin.window );
			}
			if (screen->TekEmu)
			    VTUnselect();
			if (term.flags & ICONINPUT)
			    reselectwindow(screen);
			else
			    unselectwindow(screen, INWINDOW);
			screen->iconinput = FALSE;
			VTExpose(rep);
		    } else if (window == screen->iconTwin.window) {
			if (!screen->icon_show) {
			    screen->mappedTwin = &screen->iconTwin;
			    screen->icon_show = TRUE;
			    screen->Tshow = FALSE;
			    screen->timer = 0;
			    screen->holdoff = FALSE;
			    if (screen->fullVwin.window)
				moveiconwindow( screen->fullVwin.window,
						screen->fullTwin.window );
			}
			if (!screen->TekEmu)
			    TekUnselect();
			if (term.flags & ICONINPUT)
			    reselectwindow(screen);
			else
			    unselectwindow(screen, INWINDOW);
			screen->iconinput = FALSE;
			TekExpose(rep);
			}
		} else if (window == screen->iconVwin.window ||
			   window == screen->iconTwin.window) {
#ifdef DEBUG
			if(debug)
				fprintf(stderr, "ExposeWindow %s\n", window ==
				 screen->iconVwin.window ? "icon" : "Ticon");
#endif DEBUG
			RefreshIcon(screen, window);
			break;
		}
		if(Titlebar(screen) || screen->icon_show) {
		/* icon_show is a kludge as the titlebar exposure event
		 * frequently arrives before the full window exposure event */
			if(window == screen->title.tbar) {
#ifdef DEBUG
			if(debug)
				fputs("ExposeWindow title\n", stderr);
#endif DEBUG
				VTTitleExpose((XExposeWindowEvent *)rep);
				break;
			} else if(window == screen->Ttitle.tbar) {
#ifdef DEBUG
			if(debug)
				fputs("ExposeWindow Ttitle\n", stderr);
#endif DEBUG
				TekTitleExpose((XExposeWindowEvent *)rep);
				break;
			}
		}
		if(window == screen->fullVwin.window) {
#ifdef DEBUG
			if(debug)
				fputs("ExposeWindow VT\n", stderr);
#endif DEBUG
			if(!screen->show) {
				screen->mappedVwin = &screen->fullVwin;
				if(screen->Ticonunmap) {
					screen->Ticonunmap = FALSE;
					XMapWindow( screen->fullTwin.window );
					screen->Tshow = TRUE;
					if(!screen->TekEmu) {
					    screen->holdoff = TRUE;
					    XUnmapTransparent(VWindow(screen));
					    XMapWindow(VWindow(screen));
					    break;
					}
				} else {
					screen->timer = 0;
					screen->holdoff = FALSE;
				}
				screen->show = TRUE;
				reselectwindow(screen);
				if(screen->icon_show && screen->deiconwarp)
				    DeiconWarp(screen);

				screen->icon_show = FALSE;
				screen->iconinput = FALSE;
			}
			VTExpose(rep);
		} else if(window == screen->fullTwin.window) {
#ifdef DEBUG
			if(debug)
				fputs("ExposeWindow Tek\n", stderr);
#endif DEBUG
			if(!screen->Tshow) {
				screen->mappedTwin = &screen->fullTwin;
				if(screen->iconunmap) {
					screen->iconunmap = FALSE;
					XMapWindow( screen->fullVwin.window );
					screen->show = TRUE;
					if(screen->TekEmu) {
					    screen->holdoff = TRUE;
					    XUnmapTransparent(TWindow(screen));
					    XMapWindow(TWindow(screen));
					    break;
					}
				} else {
					screen->timer = 0;
					screen->holdoff = FALSE;
				}
				screen->Tshow = TRUE;
				reselectwindow(screen);
				if(screen->icon_show && screen->deiconwarp)
					DeiconWarp(screen);
				screen->icon_show = FALSE;
				screen->iconinput = FALSE;
			}
			TekExpose(rep);
		}
		break;

	 case ExposeRegion:
		if (!screen->active_icon && window == screen->iconVwin.window ||
			   window == screen->iconTwin.window) {
#ifdef DEBUG
			if(debug)
				fprintf(stderr, "ExposeRegion %s\n", window ==
				 screen->iconVwin.window ? "icon" : "Ticon");
#endif DEBUG
			RefreshIcon(screen, window);
			break;
		}
#ifdef DEBUG
		if(debug)
			fputs("ExposeRegion\n", stderr);
#endif DEBUG
		if (((XExposeWindowEvent *)rep)->detail == ExposeCopy &&
		    screen->incopy <= 0) {
			screen->incopy = 1;
			if (screen->scrolls > 0)
				screen->scrolls--;
		}
		if (HandleExposure (screen, rep))
			screen->cursor_state = OFF;
		break;

	 case ExposeCopy:
#ifdef DEBUG
			if(debug)
				fputs("ExposeCopy\n", stderr);
#endif DEBUG
		if (screen->incopy <= 0 && screen->scrolls > 0)
			screen->scrolls--;
		if (screen->scrolls)
			screen->incopy = -1;
		else
			screen->incopy = 0;
		break;

	 case ButtonPressed:
		if (screen->incopy)
			CopyWait (screen);
		if(window == screen->iconVwin.window) {
#ifdef DEBUG
			if(debug)
				fputs("ButtonPressed icon\n", stderr);
#endif DEBUG
			XUnmapWindow(window);
			if(screen->Ticonunmap && !screen->TekEmu) {
				screen->Ticonunmap = FALSE;
				XMapWindow(TWindow(screen));
				screen->Tshow = TRUE;
				screen->holdoff = TRUE;
			}
			XMapWindow(screen->fullVwin.window);
			break;
		} else if(window == screen->iconTwin.window) {
#ifdef DEBUG
			if(debug)
				fputs("ButtonPressed Ticon\n", stderr);
#endif DEBUG
			XUnmapWindow(window);
			if(screen->iconunmap && screen->TekEmu) {
				screen->iconunmap = FALSE;
				XMapWindow(VWindow(screen));
				screen->show = TRUE;
				screen->holdoff = TRUE;
			}
			XMapWindow(screen->fullTwin.window);
			break;
		}
		/* drop through */
	 case ButtonReleased:
#ifdef DEBUG
			if(debug)
				fputs("ButtonPressed or ButtonReleased\n",
				 stderr);
#endif DEBUG
		HandleButtons(&term, rep, screen->respond);
		break;

	 case UnmapWindow:		/* full windows */
		if (window == screen->fullVwin.window) {
#ifdef DEBUG
			if(debug)
				fputs("UnmapWindow VT\n", stderr);
#endif DEBUG
			if (screen->fullVwin.titlebar)
				VTTitleUnhilite();
			screen->show = FALSE;
			if(screen->Tshow) {
				screen->Ticonunmap = TRUE;
				screen->Tshow = FALSE;
				XUnmapWindow( screen->fullTwin.window );
				SyncUnmap( screen->fullTwin.window,
					   TWINDOWEVENTS );
			}
		} else if(window == screen->fullTwin.window) {
#ifdef DEBUG
			if(debug)
				fputs("UnmapWindow Tek\n", stderr);
#endif DEBUG
			if (screen->fullTwin.titlebar)
				TekTitleUnhilite();
			screen->Tshow = FALSE;
			if(screen->show) {
				screen->iconunmap = TRUE;
				screen->show = FALSE;
				XUnmapWindow( screen->fullVwin.window );
				SyncUnmap( screen->fullVwin.window,
					   WINDOWEVENTS );
			}
		}
		reselectwindow(screen);
		screen->timer = 0;
		break;
	 case EnterWindow:
		if(screen->sb) {
			if(window == screen->sb->button) {
				if((i = GetButtonState(screen->sb)) !=
				 BUTTON_NORMAL)
					SetButtonState(screen->sb, i | HILITED);
				break;
			} else if(window == screen->sb->bar)
				break;
		}
		if((window == VWindow(screen) || window == TWindow(screen)) &&
		 (((XEnterWindowEvent *)rep)->detail & 0xff) !=
		 IntoOrFromSubwindow) {
#ifdef DEBUG
			if(debug)
				fprintf(stderr, "EnterWindow %s\n", window ==
				 VWindow(screen) ? "VT" : "Tek");
#endif DEBUG
			screen->autowindow = window;
			DoEnterLeave(screen, EnterWindow);
		}
		break;
	 case LeaveWindow:
		if(screen->sb) {
			if(window == screen->sb->button) {
				if((i = GetButtonState(screen->sb)) !=
				 BUTTON_NORMAL)
					SetButtonState(screen->sb, i& ~HILITED);
				break;
			} else if(window == screen->sb->bar)
				break;
		}
		if((window == VWindow(screen) || window == TWindow(screen)) &&
		 (((XEnterWindowEvent *)rep)->detail & 0xff) !=
		 IntoOrFromSubwindow)
#ifdef DEBUG
		{
			if(debug)
				fprintf(stderr, "LeaveWindow %s\n", window ==
				 VWindow(screen) ? "VT" : "Tek");
#endif DEBUG
			DoEnterLeave(screen, LeaveWindow);
#ifdef DEBUG
		}
#endif DEBUG
		break;
	 case FocusChange:
		if(((XFocusChangeEvent *)rep)->detail == EnterWindow)
			selectwindow(screen, FOCUS);
		else
			unselectwindow(screen, FOCUS);
		break;
	 default:
		break;
	}
}

selectwindow(screen, flag)
register Screen *screen;
register int flag;
{
	if(screen->TekEmu) {
		TekSelect();
		if(!Ttoggled)
			TCursorToggle(TOGGLE);
		if(screen->cellsused) {
			screen->colorcells[2].pixel =
			 screen->Tcursorcolor;
			XStoreColor(&screen->colorcells[2]);
		}
		screen->select |= flag;
		if(!Ttoggled)
			TCursorToggle(TOGGLE);
		return;
	} else {
		VTSelect();
		if(screen->cursor_state &&
		   (screen->cursor_col != screen->cur_col ||
		    screen->cursor_row != screen->cur_row))
		    HideCursor();
		screen->select |= flag;
		if(screen->cursor_state)
			ShowCursor();
		return;
	}
}

unselectwindow(screen, flag)
register Screen *screen;
register int flag;
{
	register int i;

	screen->select &= ~flag;
	if(!screen->select) {
		if(screen->TekEmu) {
			TekUnselect();
			if(!Ttoggled)
				TCursorToggle(TOGGLE);
			if(screen->cellsused) {
				i = (term.flags & REVERSE_VIDEO) == 0;
				screen->colorcells[i].pixel =
				 screen->Tcursorcolor;
				XStoreColor(
				 &screen->colorcells[i]);
			}
			if(!Ttoggled)
				TCursorToggle(TOGGLE);
			return;
		} else {
			VTUnselect();
			if(screen->cursor_state &&
			 (screen->cursor_col != screen->cur_col ||
			 screen->cursor_row != screen->cur_row))
				HideCursor();
			if(screen->cursor_state)
				ShowCursor();
			return;
		}
	}
}

reselectwindow(screen)
register Screen *screen;
{
	Window win;
	int x, y;

	if(XQueryMouse(RootWindow, &x, &y, &win)) {
		if(win && (win == VWindow(screen) || win == TWindow(screen))
		       && (!screen->icon_show
			   || (screen->active_icon && term.flags & ICONINPUT)))
			selectwindow(screen, INWINDOW);
		else	unselectwindow(screen, INWINDOW);
	}
}

DeiconWarp(screen)
register Screen *screen;
{
	if(screen->TekEmu)
		XWarpMouse(TWindow(screen), TFullWidth(screen) / 2,
		 TFullHeight(screen) / 2);
	else
		XWarpMouse(VWindow(screen), FullWidth(screen) / 2,
		 FullHeight(screen) / 2);
}

#define	ENTERLEAVE	500000L

DoEnterLeave(screen, type)
register Screen *screen;
int type;
{
	if (!screen->autoraise && !screen->holdoff) {
	    if (type == EnterWindow)
		    selectwindow( screen, INWINDOW );
	    else    unselectwindow( screen, INWINDOW );
	    return;
	}

	screen->timer = type;
	if(!screen->holdoff)
		Timer(ENTERLEAVE);
}

Timer(val)
long val;
{
	struct itimerval it;

	bzero(&it, sizeof(it));
	it.it_value.tv_usec = val;
	setitimer(ITIMER_REAL, &it, (struct itimerval *)0);
}

onalarm()
{
	register Screen *screen = &term.screen;

	if(screen->timer == 0 || screen->holdoff) {	/* extraneous alarm */
		Timer(0L);
		return;
	}
	if(screen->timer == EnterWindow) {
#ifdef DEBUG
		if(debug)
			fprintf(stderr, "onalarm: EnterWindow %s\n",
			 screen->autoraise ? (screen->autowindow ==
			 VWindow(screen) ? "VT" : "Tek") : "");
#endif DEBUG
		selectwindow(screen, INWINDOW);
		if(screen->autoraise)
			XRaiseWindow(screen->autowindow);
	} else	/* LeaveWindow */
#ifdef DEBUG
	{
		if(debug)
			fputs("onalarm: LeaveWindow\n", stderr);
#endif DEBUG
		unselectwindow(screen, INWINDOW);
#ifdef DEBUG
	}
#endif DEBUG
	screen->timer = 0;
}

Pixmap make_hilite(fg, bg)
int fg, bg;
{
	extern Pixmap Make_tile();

	return(Make_tile(hilite_width, hilite_height, hilite_bits, fg,
	 bg));
}

Pixmap make_gray()
{
	extern Pixmap Make_tile();

	return(Make_tile(gray_width, gray_height, gray_bits, BlackPixel,
	 WhitePixel));
}

Cursor make_tcross(fg, bg, func)
int fg, bg, func;
{
	return(XCreateCursor(tcross_width, tcross_height, tcross_bits,
	 tcross_mask_bits, tcross_x_hot, tcross_y_hot, fg, bg, func));
}

Cursor make_xterm(fg, bg, func)
int fg, bg, func;
{
	return(XCreateCursor(xterm_width, xterm_height, xterm_bits,
	 xterm_mask_bits, xterm_x_hot, xterm_y_hot, fg, bg, func));
}

Cursor make_wait(fg, bg, func)
int fg, bg, func;
{
	return(XCreateCursor(wait_width, wait_height, wait_bits, waitmask_bits,
	 wait_x_hot, wait_y_hot, fg, bg, func));
}

Cursor make_arrow(fg, bg, func)
int fg, bg, func;
{
	return(XCreateCursor(left_ptr_width, left_ptr_height, left_ptr_bits,
	 left_ptr_mask_bits, left_ptr_x_hot, left_ptr_y_hot, fg, bg, func));
}

char *uniquesuffix(name)
char *name;
{
	register int *np, *fp, i;
	register Window *cp;
	register int temp, j, k, exact, *number;
	char *wname;
	Window *children, parent;
	int nchildren;
	static char *suffix, sufbuf[10];
	char *malloc();

	if(suffix)
		return(suffix);
	suffix = sufbuf;
	if(!XQueryTree(RootWindow, &parent, &nchildren, &children) ||
	 nchildren < 1 || (number = (int *)malloc(nchildren * sizeof(int)))
	 == NULL)
		return(suffix);
	exact = FALSE;
	i = strlen(name);
	for(np = number, cp = children, j = nchildren ; j > 0 ; cp++, j--) {
		if(!XFetchName(*cp, &wname) || wname == NULL)
			continue;
		if(strncmp(name, wname, i) == 0) {
			if(wname[i] == 0 || strcmp(&wname[i], " (Tek)") == 0)
				exact = TRUE;
			else if(strncmp(&wname[i], " #", 2) == 0)
				*np++ = atoi(&wname[i + 2]);
		}
		free(wname);
	}
	free((char *)children);
	if(exact) {
		if(np <= number)
			strcpy(suffix, " #2");
		else {
			exact = np - number;
			np = number;
			/* shell sort */
			for(i = exact / 2 ; i > 0 ; i /= 2)
				for(k = i ; k < exact ; k++)
					for(j = k - i ; j >= 0 &&
					 np[j] > np[j + i] ; j -= i) {
						temp = np[j];
						np[j] = np[j + i];
						np[j + i] = temp;
					}
			/* make numbers unique */
			for(fp = np + 1, i = exact - 1 ; i > 0 ; fp++, i--)
				if(*fp != *np)
					*++np = *fp;
			/* find least unique number */
			for(i = 2, fp = number ; fp <= np ; fp++) {
				if(i < *fp)
					break;
				if(i == *fp)
					i++;
			}
			sprintf(suffix, " #%d", i);
		}
	}
	free((char *)number);
	return(suffix);
}

Bell()
{
	extern Terminal term;
	register Screen *screen = &term.screen;

	if(screen->visualbell) {
		if(screen->TekEmu) {
			if(screen->icon_show && !screen->active_icon) {
				XPixSet(screen->iconTwin.window, 0, 0,
				 screen->iconTwin.width, screen->iconTwin.height,
				 screen->foreground);
				XFlush();
				XClear(screen->iconTwin.window);
				RefreshIcon(screen, screen->iconTwin.window);
			} else {
				XPixFill(TWindow(screen), 0, 0,
				 TFullWidth(screen), TFullHeight(screen),
				 screen->foreground, (Bitmap)0, GXinvert,
				 screen->xorplane);
				XFlush();
				XPixFill(TWindow(screen), 0, 0,
				 TFullWidth(screen), TFullHeight(screen),
				 screen->foreground, (Bitmap)0, GXinvert,
				 screen->xorplane);
			}
		} else {
			if(screen->icon_show && !screen->active_icon) {
				XPixSet(screen->iconVwin.window, 0, 0,
				 screen->iconVwin.width, screen->iconVwin.height,
				 screen->foreground);
				XFlush();
				XClear(screen->iconVwin.window);
				RefreshIcon(screen, screen->iconVwin.window);
			} else {
				XPixSet(VWindow(screen), 0, 0, FullWidth(screen),
				 FullHeight(screen), screen->foreground);
				XFlush();
				XClear(VWindow(screen));
				ScrnRefresh(screen, 0, 0, screen->max_row + 1 +
				 screen->statusline, screen->max_col + 1);
			}
		}
	} else
		XFeep(0);
}

Redraw()
{
	extern Terminal term;
	register Screen *screen = &term.screen;

	if(VWindow(screen) && screen->show) {
		VTExpose(NULL);
		if(screen->scrollbar) {
			XClear(screen->sb->bar);
			XClear(screen->sb->region);
			screen->sb->buttonstate = -1;
			DrawButton(screen->sb);
			screen->sb->savestate = -1;
			DrawSave(screen->sb);
		}
		if(Titlebar(screen)) {
			XClear(screen->title.tbar);
			XClear(screen->title.left);
			XClear(screen->title.right);
			VTTitleExpose(NULL);
		}
	}
	if(TWindow(screen) && screen->Tshow) {
		TekExpose(NULL);
		if(Titlebar(screen)) {
			XClear(screen->Ttitle.tbar);
			XClear(screen->Ttitle.left);
			XClear(screen->Ttitle.right);
			TekTitleExpose(NULL);
		}
	}
}

IconInit(screen, bm, Tbm)
register Screen *screen;
char *bm, *Tbm;
{
	register int w;

	if(!bm && !Tbm) {	/* use default bitmaps */
		screen->iconbitmap.bits = icon_bits;
		screen->Ticonbitmap.bits = tek_icon_bits;
		screen->bitmapwidth = screen->iconbitmap.width =
		 screen->Ticonbitmap.width = icon_width;
		screen->bitmapheight = screen->iconbitmap.height =
		 screen->Ticonbitmap.height = icon_height;
	} else if(bm && !*bm && Tbm && !*Tbm)	/* both empty means no bitmap */
		screen->bitmapwidth = screen->bitmapheight = 0;
	else {			/* user defined bitmap(s) */
		if(bm && *bm) {
			if((w = XReadBitmapFile(bm, &screen->iconbitmap.width,
			 &screen->iconbitmap.height, &screen->iconbitmap.bits,
			 NULL, NULL)) == 0) {
openerror:
				fprintf(stderr, "%s: Can't open %s\n",
				 xterm_name, bm);
				Exit(ERROR_OPENBITMAP);
			} else if(w < 0) {
syntaxerror:
				fprintf(stderr, "%s: Syntax error in %s\n",
				 xterm_name, bm);
				Exit(ERROR_SYNTAXBITMAP);
			}
			screen->bitmapwidth = screen->iconbitmap.width;
			screen->bitmapheight = screen->iconbitmap.height;
		}
		if(Tbm && *Tbm) {
			if((w = XReadBitmapFile(Tbm, &screen->Ticonbitmap.width,
			 &screen->Ticonbitmap.height, &screen->Ticonbitmap.bits,
			 NULL, NULL)) == 0)
				goto openerror;
			else if(w < 0)
				goto syntaxerror;
			if(screen->bitmapwidth < screen->Ticonbitmap.width)
				screen->bitmapwidth = screen->Ticonbitmap.width;
			if(screen->bitmapheight < screen->Ticonbitmap.height)
				screen->bitmapheight =
				 screen->Ticonbitmap.height;
		}
		if(!screen->iconbitmap.bits) {
			if(!screen->Ticonbitmap.bits) {
				screen->Ticonbitmap.bits = tek_icon_bits;
				screen->bitmapwidth = screen->Ticonbitmap.width
				 = icon_width;
				screen->bitmapheight =
				 screen->Ticonbitmap.height = icon_height;
			}
			screen->iconbitmap.bits = screen->Ticonbitmap.bits;
			screen->iconbitmap.width = screen->Ticonbitmap.width;
			screen->iconbitmap.height = screen->Ticonbitmap.height;
		} else if(!screen->Ticonbitmap.bits) {
			if(!screen->iconbitmap.bits) {
				screen->iconbitmap.bits = icon_bits;
				screen->bitmapwidth = screen->iconbitmap.width
				 = icon_width;
				screen->bitmapheight =
				 screen->iconbitmap.height = icon_height;
			}
			screen->Ticonbitmap.bits = screen->iconbitmap.bits;
			screen->Ticonbitmap.width = screen->iconbitmap.width;
			screen->Ticonbitmap.height = screen->iconbitmap.height;
		}
	}
	if((screen->winname = malloc(strlen(win_name) + 10)) == NULL)
		Error(ERROR_WINNAME);
	strcpy(screen->winname, win_name);
	strcat(screen->winname, uniquesuffix(win_name));
	screen->winnamelen = strlen(screen->winname);
	IconRecalc(screen);
}

IconRecalc(screen)
register Screen *screen;
{
	register int i, w;

	if (screen->active_icon) return;

	w = XQueryWidth(screen->winname, screen->titlefont->id);
	if(screen->bitmapwidth > 0) {
		if(screen->textundericon) {
			screen->icon_text_x = TITLEPAD;
			screen->icon_text_y = screen->bitmapheight +
			 2 * TITLEPAD;
			screen->iconVwin.height = screen->bitmapheight +
			  screen->titlefont->height + 3 * TITLEPAD;
			screen->iconbitmap.x = screen->Ticonbitmap.x =
			 screen->iconbitmap.y = screen->Ticonbitmap.y =
			 TITLEPAD;
			if((i = screen->bitmapwidth - w) >= 0) {
				screen->iconVwin.width = screen->bitmapwidth +
				 2 * TITLEPAD;
				screen->icon_text_x += i / 2;
			} else {
				screen->iconVwin.width = w + 2 * TITLEPAD;
				i = (-i) / 2;
				screen->iconbitmap.x += i;
				screen->Ticonbitmap.x += i;
			}
		} else {
			screen->icon_text_x = screen->bitmapwidth +
			 2 * TITLEPAD;
			screen->icon_text_y = TITLEPAD;
			screen->iconVwin.width = w + screen->bitmapwidth +
			 3 * TITLEPAD;
			screen->iconbitmap.x = screen->Ticonbitmap.x =
			 screen->iconbitmap.y = screen->Ticonbitmap.y =
			 TITLEPAD;
			if((i = screen->bitmapheight -
			 screen->titlefont->height) >= 0) {
				screen->iconVwin.height = screen->bitmapheight +
				 2 * TITLEPAD;
				screen->icon_text_y += i / 2;
			} else {
				screen->iconVwin.height = screen->titlefont->height
				 + 2 * TITLEPAD;
				i = (-i) / 2;
				screen->iconbitmap.y += i;
				screen->Ticonbitmap.y += i;
			}
		}
		if((i = screen->iconbitmap.width - screen->Ticonbitmap.width)
		 >= 0)
			screen->Ticonbitmap.x += i / 2;
		else
			screen->iconbitmap.x += (-i) / 2;
		if((i = screen->iconbitmap.height - screen->Ticonbitmap.height)
		 >= 0)
			screen->Ticonbitmap.y += i / 2;
		else
			screen->iconbitmap.y += (-i) / 2;
	} else {
		screen->icon_text_x = TITLEPAD;
		screen->iconVwin.width = w + 2 * TITLEPAD;
		screen->iconVwin.height = screen->titlefont->height + 2 * TITLEPAD;
	}

	if (screen->iconVwin.window)
	    XChangeWindow( screen->iconVwin.window, screen->iconVwin.width,
			   screen->iconVwin.height );

	if (screen->iconTwin.window) {
	    screen->iconTwin.width = screen->iconVwin.width;
	    screen->iconTwin.height = screen->iconVwin.height;
	    XChangeWindow( screen->iconTwin.window, screen->iconTwin.width,
			   screen->iconTwin.height );
	}

	icon_box[0].x = screen->icon_text_x - 2;
	icon_box[0].y = screen->icon_text_y - 2;
	icon_box[3].x = -(icon_box[1].x = w + 3);
	icon_box[4].y = -(icon_box[2].y = screen->titlefont->height + 3);
}

RefreshIcon(screen, window)
register Screen *screen;
Window window;
{
	register BitmapBits *bb;
	register int fg, bg;

	bb = screen->TekEmu ? &screen->Ticonbitmap : &screen->iconbitmap;
	fg = screen->foreground;
	bg = screen->background;
	if(screen->bitmapwidth > 0)
		XBitmapBitsPut(window, bb->x, bb->y, bb->width, bb->height,
		 bb->bits, fg, bg, (Bitmap)0, GXcopy, AllPlanes);
	XText(window, screen->icon_text_x, screen->icon_text_y,
	 screen->winname, screen->winnamelen, screen->titlefont->id, fg, bg);
	screen->icon_show = TRUE;
	if(screen->iconinput)
		IconBox(screen);
}

IconBox(screen)
register Screen *screen;
{
	if (screen->active_icon) return;

	XDraw(screen->TekEmu ? screen->iconTwin.window : screen->iconVwin.window,
	 icon_box, NBOX, 1, 1, screen->foreground, GXcopy, AllPlanes);
}

/*
 * Move win1's icon window to where win2's icon window is.
 */
moveiconwindow(win1, win2)
register Window win1, win2;
{
	WindowInfo wininfo1, wininfo2;

	XQueryWindow(win1, &wininfo1);
	XQueryWindow(win2, &wininfo2);
	if(wininfo1.assoc_wind && wininfo2.assoc_wind) {
		XQueryWindow(wininfo2.assoc_wind, &wininfo2);
		XMoveWindow(wininfo1.assoc_wind, wininfo2.x, wininfo2.y);
	}
}

IconGeometry(screen, ix, iy)
register Screen *screen;
register int *ix, *iy;
{
	register int i;
	int w, h;

	if(icon_geom) {
		i = XParseGeometry(icon_geom, ix, iy, &w, &h);
		/*
		 * XParseGeometry returns negative values in addition to
		 * setting the bitmask.
		 */
		if((i & XValue) && (i & XNegative))
			*ix = DisplayWidth() + *ix - screen->iconVwin.width - 2 *
			 screen->borderwidth;
		if((i & YValue) && (i & YNegative))
			*iy = DisplayHeight() + *iy - screen->iconVwin.height - 2 *
			 screen->borderwidth;
	}
}

InTitle(screen, window, x)
register Screen *screen;
Window window;
int x;
{
	register int i, j;

	if(window == screen->title.tbar) {
		i = (j = FullWidth(screen) / 2) - (screen->title.x -
		 screen->title_n_size);
		j = x - j;
		if(j < 0)
			j = -j;
		if(j < i) {
			XUnmapWindow(VWindow(screen));
			XMapWindow(screen->iconVwin.window);
			return(TRUE);
		}
	} else {
		i = (j = TFullWidth(screen) / 2) - (screen->Ttitle.x -
		 screen->title_n_size);
		j = x - j;
		if(j < 0)
			j = -j;
		if(j < i) {
			XUnmapWindow(TWindow(screen));
			XMapWindow(screen->iconTwin.window);
			return(TRUE);
		}
	}
	return(FALSE);
}

SyncUnmap(win, mask)
register Window win;
register int mask;
{
	XEvent ev;
	register XEvent *rep = &ev;

	do { /* ignore events through unmap */
		XWindowEvent(win, mask, rep);
	} while(rep->type != UnmapWindow);
}

StartLog(screen)
register Screen *screen;
{
	register char *cp;
	register int i;
	static char *log_default;
	char *malloc(), *rindex();
	extern logpipe();

	if(screen->logging || (screen->inhibit & I_LOG))
		return;
	if(screen->logfile == NULL || *screen->logfile == 0) {
		if(screen->logfile)
			free(screen->logfile);
		if(log_default == NULL)
			mktemp(log_default = log_def_name);
		if((screen->logfile = malloc(strlen(log_default) + 1)) == NULL)
			return;
		strcpy(screen->logfile, log_default);
	}
	if(*screen->logfile == '|') {	/* exec command */
		int p[2];
		static char *shell;

		if(pipe(p) < 0 || (i = fork()) < 0)
			return;
		if(i == 0) {	/* child */
			close(p[1]);
			dup2(p[0], 0);
			close(p[0]);
			dup2(fileno(stderr), 1);
			dup2(fileno(stderr), 2);
			close(fileno(stderr));
			fileno(stderr) = 2;
			close(screen->display->fd);
			close(screen->respond);
			if(!shell) {
				register struct passwd *pw;
				char *getenv(), *malloc();
				struct passwd *getpwuid();

				if(((cp = getenv("SHELL")) == NULL || *cp == 0)
				 && ((pw = getpwuid(screen->uid)) == NULL ||
				 *(cp = pw->pw_shell) == 0) ||
				 (shell = malloc(strlen(cp) + 1)) == NULL)
					shell = "/bin/sh";
				else
					strcpy(shell, cp);
			}
			signal(SIGHUP, SIG_DFL);
			signal(SIGCHLD, SIG_DFL);
			setgid(screen->gid);
			setuid(screen->uid);
			execl(shell, shell, "-c", &screen->logfile[1], 0);
			fprintf(stderr, "%s: Can't exec `%s'\n", xterm_name,
			 &screen->logfile[1]);
			exit(ERROR_LOGEXEC);
		}
		close(p[0]);
		screen->logfd = p[1];
		signal(SIGPIPE, logpipe);
	} else {
		if(access(screen->logfile, F_OK) == 0) {
			if(access(screen->logfile, W_OK) < 0)
				return;
		} else if(cp = rindex(screen->logfile, '/')) {
			*cp = 0;
			i = access(screen->logfile, W_OK);
			*cp = '/';
			if(i < 0)
				return;
		} else if(access(".", W_OK) < 0)
			return;
		if((screen->logfd = open(screen->logfile, O_WRONLY | O_APPEND |
		 O_CREAT, 0644)) < 0)
			return;
		chown(screen->logfile, screen->uid, screen->gid);

	}
	screen->logstart = screen->TekEmu ? Tbptr : bptr;
	screen->logging = TRUE;
}

CloseLog(screen)
register Screen *screen;
{
	if(!screen->logging || (screen->inhibit & I_LOG))
		return;
	FlushLog(screen);
	close(screen->logfd);
	screen->logging = FALSE;
}

FlushLog(screen)
register Screen *screen;
{
	register char *cp;
	register int i;

	cp = screen->TekEmu ? Tbptr : bptr;
	if((i = cp - screen->logstart) > 0)
		write(screen->logfd, screen->logstart, i);
	screen->logstart = screen->TekEmu ? Tbuffer : buffer;
}

logpipe()
{
	register Screen *screen = &term.screen;

	if(screen->logging)
		CloseLog(screen);
}

do_osc(func)
int (*func)();
{
	register Screen *screen = &term.screen;
	register int mode, c;
	register char *cp;
	char buf[512];
	extern char *malloc();

	mode = 0;
	while(isdigit(c = (*func)()))
		mode = 10 * mode + (c - '0');
	cp = buf;
	while(isprint(c = (*func)()))
		*cp++ = c;
	*cp = 0;
	switch(mode) {
	 case 0:	/* new title */
		Retitle(buf);
		break;
	 case 46:	/* new log file */
		if((cp = malloc(strlen(buf) + 1)) == NULL)
			break;
		strcpy(cp, buf);
		if(screen->logfile)
			free(screen->logfile);
		screen->logfile = cp;
		break;
	}
}

Retitle(name)
register char *name;
{
	register Screen *screen = &term.screen;
	register int w, i, j;
	char icon[512];

	free(screen->winname);
	if((screen->winname = malloc((screen->winnamelen = strlen(name)) + 1))
	 == NULL)
		Error(ERROR_RTMALLOC1);
	strcpy(screen->winname, name);
	strcpy(icon, name);
	strcat(icon, " (icon)");
	IconRecalc(screen);
	if(screen->fullVwin.window) {
		XStoreName(screen->fullVwin.window, name);
		XStoreName(screen->iconVwin.window, icon);
		XChangeWindow(screen->iconVwin.window, screen->iconVwin.width,
		 screen->iconVwin.height);
		if(screen->title.tbar) {
			w = FullWidth(screen);
			screen->title.fullwidth = XQueryWidth(name,
			 screen->titlefont->id);
			if((screen->title.width = i = screen->title.fullwidth)
			 > (j = w - 2 * (MINHILITE + screen->title_n_size + 1)))
				screen->title.width = (i = j) +
				 screen->title_n_size;
			j = w - i - 2 * (screen->title_n_size + 1);
			i = j / 2;
			j -= i;
			screen->title.x = i + 1 + screen->title_n_size;
			screen->title.y = TITLEPAD;
			XClear(screen->title.tbar);
			XChangeWindow(screen->title.left, i,
			 screen->titlefont->height);
			XConfigureWindow(screen->title.right, w - j - 1,
			 TITLEPAD, j, screen->titlefont->height);
			VTTitleExpose((XExposeWindowEvent *)NULL);
		}
	}
	if(screen->fullTwin.window) {
		free(screen->Twinname);
		if((screen->Twinname = malloc((screen->Twinnamelen =
		 screen->winnamelen + 6) + 1)) == NULL)
			Error(ERROR_RTMALLOC2);
		strcpy(screen->Twinname, name);
		strcat(screen->Twinname, " (Tek)");
		XStoreName(screen->fullTwin.window, screen->Twinname);
		XStoreName(screen->iconTwin.window, icon);
		XChangeWindow(screen->iconTwin.window, screen->iconTwin.width,
		 screen->iconTwin.height);
		if(screen->Ttitle.tbar) {
			w = TFullWidth(screen);
			screen->Ttitle.fullwidth = XQueryWidth(screen->Twinname,
			 screen->titlefont->id);
			if((screen->Ttitle.width = i = screen->Ttitle.fullwidth)
			 > (j = w - 2 * (MINHILITE + screen->title_n_size + 1)))
				screen->Ttitle.width = (i = j) +
				 screen->title_n_size;
			j = w - i - 2 * (screen->title_n_size + 1);
			i = j / 2;
			j -= i;
			screen->Ttitle.x = i + 1 + screen->title_n_size;
			screen->Ttitle.y = TITLEPAD;
			XClear(screen->Ttitle.tbar);
			XChangeWindow(screen->Ttitle.left, i,
			 screen->titlefont->height);
			XConfigureWindow(screen->Ttitle.right, w - j - 1,
			 TITLEPAD, j, screen->titlefont->height);
			TekTitleExpose((XExposeWindowEvent *)NULL);
		}
	}
}

Panic(s, a)
char	*s;
int a;
{
#ifdef DEBUG
	if(debug) {
		fprintf(stderr, "%s: PANIC!	", xterm_name);
		fprintf(stderr, s, a);
		fputs("\r\n", stderr);
		fflush(stderr);
	}
#endif DEBUG
}

SysError (i)
int i;
{
	fprintf (stderr, "%s: Error %d, errno %d:", xterm_name, i, errno);
	perror ("");
	Cleanup(i);
}

Error (i)
int i;
{
	fprintf (stderr, "%s: Error %d\n", xterm_name, i);
	Cleanup(i);
}

/*
 * cleanup by sending SIGHUP to client processes
 */
Cleanup (code)
int code;
{
#ifdef notdef
	extern Terminal term;
	register Screen *screen;

	screen = &term.screen;
	if (screen->pid > 1)
		killpg(getpgrp(screen->pid), SIGHUP);
#endif
	Exit (code);
}

/*
 * sets the value of var to be arg in the Unix 4.2 BSD environment env.
 * Var should end with '=' (bindings are of the form "var=value").
 * This procedure assumes the memory for the first level of environ
 * was allocated using calloc, with enough extra room at the end so not
 * to have to do a realloc().
 */
Setenv (var, value)
register char *var, *value;
{
	extern char **environ;
	register int index = 0;
	register int len = strlen(var);

	while (environ [index] != NULL) {
	    if (strncmp (environ [index], var, len) == 0) {
		/* found it */
		environ[index] = (char *)malloc (len + strlen (value) + 1);
		strcpy (environ [index], var);
		strcat (environ [index], value);
		return;
	    }
	    index ++;
	}

#ifdef DEBUG
	if (debug) fputs ("expanding env\n", stderr);
#endif DEBUG

	environ [index] = (char *) malloc (len + strlen (value) + 1);
	strcpy (environ [index], var);
	strcat (environ [index], value);
	environ [++index] = NULL;
}

/*
 * returns a pointer to the first occurrence of s2 in s1,
 * or NULL if there are none.
 */
char *strindex (s1, s2)
register char	*s1, *s2;
{
	register char	*s3;
	char		*index();

	while ((s3=index(s1, *s2)) != NULL) {
		if (strncmp(s3, s2, strlen(s2)) == 0)
			return (s3);
		s1 = ++s3;
	}
	return (NULL);
}

xerror(d, ev)
Display *d;
register XErrorEvent *ev;
{
	fprintf(stderr, "%s: %s\n", xterm_name,
	 XErrDescrip(ev->error_code));
	fprintf(stderr, "Request code %d, func %d, serial #%ld, window %ld\n",
	 ev->request_code, ev->func, ev->serial, (long)ev->window);
	Exit(ERROR_XERROR);
}

xioerror(d)
Display *d;
{
	perror(xterm_name);
	Exit(ERROR_XIOERROR);
}
RAZZLE!DAZZLE
fi	# End misc.c
if test -f resize.c
then
	echo shar: will not overwrite existing file "'resize.c'"
else
echo 'x - resize.c'
cat << \RAZZLE!DAZZLE > resize.c
/*
 *	$Source: /u1/X/xterm/RCS/resize.c,v $
 *	$Header: resize.c,v 10.101 86/12/02 10:35:30 swick Exp $
 */

#ifndef lint
static char *rcsid_resize_c = "$Header: resize.c,v 10.101 86/12/02 10:35:30 swick Exp $";
#endif	lint

#include <X/mit-copyright.h>

/* Copyright    Massachusetts Institute of Technology    1984	*/

/* resize.c */

#include <stdio.h>
#include <sgtty.h>
#include <strings.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/time.h>

#ifndef lint
static char sccs_id[] = "@(#)resize.c\tX10/6.6B\t12/26/86";
#endif

#define	EMULATIONS	2
#define	SUN		1
#define	TIMEOUT		10
#define	VT100		0

char *emuname[EMULATIONS] = {
	"VT100",
	"Sun",
};
char *myname;
int stdsh;
char *getsize[EMULATIONS] = {
	"\0337\033[r\033[999;999H\033[6n",
	"\033[18t",
};
#ifndef sun
#ifdef TIOCSWINSZ
char *getwsize[EMULATIONS] = {
	0,
	"\033[14t",
};
#endif TIOCSWINSZ
#endif sun
char *restore[EMULATIONS] = {
	"\0338",
	0,
};
char *setname = "";
char *setsize[EMULATIONS] = {
	0,
	"\033[8;%s;%st",
};
struct sgttyb sgorig;
char *size[EMULATIONS] = {
	"\033[%d;%dR",
	"\033[8;%d;%dt",
};
char sunname[] = "sunsize";
int tty;
FILE *ttyfp;
#ifndef sun
#ifdef TIOCSWINSZ
char *wsize[EMULATIONS] = {
	0,
	"\033[4;%hd;%hdt",
};
#endif TIOCSWINSZ
#endif sun

char *strindex (), *index (), *rindex();

main (argc, argv)
char **argv;
/*
   resets termcap string to reflect current screen size
 */
{
	register char *ptr, *env;
	register int emu = VT100;
	int rows, cols;
	struct sgttyb sg;
	char termcap [1024];
	char newtc [1024];
	char buf[BUFSIZ];
#ifdef sun
#ifdef TIOCSSIZE
	struct ttysize ts;
#endif TIOCSSIZE
#else sun
#ifdef TIOCSWINSZ
	struct winsize ws;
#endif TIOCSWINSZ
#endif sun
	char *getenv();
	int onintr();

	if(ptr = rindex(myname = argv[0], '/'))
		myname = ptr + 1;
	if(strcmp(myname, sunname) == 0)
		emu = SUN;
	for(argv++, argc-- ; argc > 0 && **argv == '-' ; argv++, argc--) {
		switch((*argv)[1]) {
		 case 's':	/* Sun emulation */
			if(emu == SUN)
				Usage();	/* Never returns */
			emu = SUN;
			break;
		 case 'u':	/* Bourne (Unix) shell */
		  	stdsh++;
			break;
		 default:
			Usage();	/* Never returns */
		}
	}
	if(argc == 2) {
		if(!setsize[emu]) {
			fprintf(stderr,
			 "%s: Can't set window size under %s emulation\n",
			 myname, emuname[emu]);
			exit(1);
		}
		if(!checkdigits(argv[0]) || !checkdigits(argv[1]))
			Usage();	/* Never returns */
	} else if(argc != 0)
		Usage();	/* Never returns */
	if((ttyfp = fopen("/dev/tty", "r+")) == NULL) {
		fprintf(stderr, "%s: Can't open /dev/tty\n", myname);
		exit(1);
	}
	tty = fileno(ttyfp);
	if((env = getenv("TERMCAP")) && *env)
		strcpy(termcap, env);
	else {
		if(!(env = getenv("TERM")) || !*env) {
			env = "xterm";
			if(stdsh)
				setname = "TERM=xterm;\n";
			else	setname = "setenv TERM xterm;\n";
		}
		if(tgetent (termcap, env) <= 0) {
			fprintf(stderr, "%s: Can't get entry \"%s\"\n",
			 myname, env);
			exit(1);
		}
	}

 	ioctl (tty, TIOCGETP, &sgorig);
	sg = sgorig;
	sg.sg_flags |= RAW;
	sg.sg_flags &= ~ECHO;
	signal(SIGINT, onintr);
	signal(SIGQUIT, onintr);
	signal(SIGTERM, onintr);
	ioctl (tty, TIOCSETP, &sg);

	if (argc == 2) {
		sprintf (buf, setsize[emu], argv[0], argv[1]);
		write(tty, buf, strlen(buf));
	}
	write(tty, getsize[emu], strlen(getsize[emu]));
	readstring(ttyfp, buf, size[emu]);
	if(sscanf (buf, size[emu], &rows, &cols) != 2) {
		fprintf(stderr, "%s: Can't get rows and columns\r\n", myname);
		onintr();
	}
	if(restore[emu])
		write(tty, restore[emu], strlen(restore[emu]));
#ifdef sun
#ifdef TIOCGSIZE
	/* finally, set the tty's window size */
	if (ioctl (tty, TIOCGSIZE, &ts) != -1) {
		ts.ts_lines = rows;
		ts.ts_cols = cols;
		ioctl (tty, TIOCSSIZE, &ts);
	}
#endif TIOCGSIZE
#else sun
#ifdef TIOCGWINSZ
	/* finally, set the tty's window size */
	if(getwsize[emu]) {
	    /* get the window size in pixels */
	    write (tty, getwsize[emu], strlen (getwsize[emu]));
	    readstring(ttyfp, buf, wsize[emu]);
	    if(sscanf (buf, wsize[emu], &ws.ws_xpixel, &ws.ws_ypixel) != 2) {
		fprintf(stderr, "%s: Can't get window size\r\n", myname);
		onintr();
	    }
	    ws.ws_row = rows;
	    ws.ws_col = cols;
	    ioctl (tty, TIOCSWINSZ, &ws);
	} else if (ioctl (tty, TIOCGWINSZ, &ws) != -1) {
	    /* we don't have any way of directly finding out
	       the current height & width of the window in pixels.  We try
	       our best by computing the font height and width from the "old"
	       struct winsize values, and multiplying by these ratios...*/
	    if (ws.ws_xpixel != 0)
	        ws.ws_xpixel = cols * (ws.ws_xpixel / ws.ws_col);
	    if (ws.ws_ypixel != 0)
	        ws.ws_ypixel = rows * (ws.ws_ypixel / ws.ws_row);
	    ws.ws_row = rows;
	    ws.ws_col = cols;
	    ioctl (tty, TIOCSWINSZ, &ws);
	}
#endif TIOCGWINSZ
#endif sun

	ioctl (tty, TIOCSETP, &sgorig);
	signal(SIGINT, SIG_DFL);
	signal(SIGQUIT, SIG_DFL);
	signal(SIGTERM, SIG_DFL);

	/* update termcap string */
	/* first do columns */
	if ((ptr = strindex (termcap, "co#")) == NULL) {
		fprintf(stderr, "%s: No `co#'\n", myname);
		exit (1);
	}
	strncpy (newtc, termcap, ptr - termcap + 3);
	sprintf (newtc + strlen (newtc), "%d", cols);
	ptr = index (ptr, ':');
	strcat (newtc, ptr);

	/* now do lines */
	if ((ptr = strindex (newtc, "li#")) == NULL) {
		fprintf(stderr, "%s: No `li#'\n", myname);
		exit (1);
	}
	strncpy (termcap, newtc, ptr - newtc + 3);
	sprintf (termcap + ((int) ptr - (int) newtc + 3), "%d", rows);
	ptr = index (ptr, ':');
	strcat (termcap, ptr);

	if(stdsh)
		printf ("%sTERMCAP='%s'\n",
		 setname, termcap);
	else	printf ("set noglob;\n%ssetenv TERMCAP '%s';\nunset noglob;\n",
		 setname, termcap);
	exit(0);
}

char *strindex (s1, s2)
/*
   returns a pointer to the first occurrence of s2 in s1, or NULL if there are
   none.
 */
register char *s1, *s2;
{
	register char *s3;

	while ((s3 = index (s1, *s2)) != NULL)
	{
		if (strncmp (s3, s2, strlen (s2)) == 0) return (s3);
		s1 = ++s3;
	}
	return (NULL);
}

checkdigits(str)
register char *str;
{
	while(*str) {
		if(!isdigit(*str))
			return(0);
		str++;
	}
	return(1);
}

readstring(fp, buf, str)
register FILE *fp;
register char *buf;
char *str;
{
	register int i, last;
	struct itimerval it;
	int timeout();

	signal(SIGALRM, timeout);
	bzero((char *)&it, sizeof(struct itimerval));
	it.it_value.tv_sec = TIMEOUT;
	setitimer(ITIMER_REAL, &it, (struct itimerval *)NULL);
	if((*buf++ = getc(fp)) != *str) {
		fprintf(stderr, "%s: unknown character, exiting.\r\n", myname);
		onintr();
	}
	last = str[i = strlen(str) - 1];
	while((*buf++ = getc(fp)) != last);
	bzero((char *)&it, sizeof(struct itimerval));
	setitimer(ITIMER_REAL, &it, (struct itimerval *)NULL);
	*buf = 0;
}

Usage()
{
	fprintf(stderr, strcmp(myname, sunname) == 0 ?
	 "Usage: %s [rows cols]\n" :
	 "Usage: %s [-u] [-s [rows cols]]\n", myname);
	exit(1);
}

timeout()
{
	fprintf(stderr, "%s: Time out occurred\r\n", myname);
	onintr();
}

onintr()
{
	ioctl (tty, TIOCSETP, &sgorig);
	exit(1);
}
RAZZLE!DAZZLE
fi	# End resize.c
if test -f screen.c
then
	echo shar: will not overwrite existing file "'screen.c'"
else
echo 'x - screen.c'
cat << \RAZZLE!DAZZLE > screen.c
/*
 *	$Source: /u1/X/xterm/RCS/screen.c,v $
 *	$Header: screen.c,v 10.100 86/12/01 14:45:17 jg Rel $
 */

#include <X/mit-copyright.h>

/* Copyright    Massachusetts Institute of Technology    1984, 1985	*/

/* screen.c */

#ifndef lint
static char sccs_id[] = "@(#)screen.c\tX10/6.6B\t12/26/86";
#endif	lint

#include <X/Xlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <signal.h>
#include "scrollbar.h"
#include "ptyx.h"
#include "error.h"

extern char *calloc();
extern char *malloc();
extern char *realloc();

ScrnBuf Allocate (nrow, ncol)
/*
   allocates memory for a 2-dimensional array of chars and returns a pointer
   thereto
   each line is formed from a pair of char arrays.  The first (even) one is
   the actual character array and the second (odd) one is the attributes.
 */
register int nrow, ncol;
{
	register ScrnBuf base;

	if ((base = (ScrnBuf) calloc ((nrow *= 2), sizeof (char *))) == 0)
		SysError (ERROR_SCALLOC);

	for (nrow--; nrow >= 0; nrow--)
		if ((base [nrow] = calloc (ncol, sizeof(char))) == 0)
			SysError (ERROR_SCALLOC2);

	return (base);
}

ScreenWrite (screen, str, flags, length)
/*
   Writes str into buf at row row and column col.  Characters are set to match
   flags.
 */
Screen *screen;
char *str;
register unsigned flags;
register int length;		/* length of string */
{
	register char *att;
	register int avail  = screen->max_col - screen->cur_col + 1;
	register char *col;

	if (length > avail)
	    length = avail;
	if (length <= 0)
		return;

	col = screen->buf[avail = 2 * screen->cur_row] + screen->cur_col;
	att = screen->buf[avail + 1] + screen->cur_col;
	flags &= ATTRIBUTES;
	bcopy(str, col, length);
	while(length-- > 0)
		*att++ = flags;
}

ScrnInsertLine (sb, last, where, n, size)
/*
   Inserts n blank lines at sb + where, treating last as a bottom margin.
   Size is the size of each entry in sb.
   Requires: 0 <= where < where + n <= last
   	     n <= MAX_ROWS
 */
register ScrnBuf sb;
int last;
register int where, n, size;
{
	register int i;
	char *save [2 * MAX_ROWS];

	/* save n lines at bottom */
	bcopy ((char *) &sb [2 * (last -= n - 1)], (char *) save,
		2 * sizeof (char *) * n);
	
	/* clear contents of old rows */
	for (i = 2 * n - 1; i >= 0; i--)
		bzero ((char *) save [i], size);

	/* move down lines */
	bcopy ((char *) &sb [2 * where], (char *) &sb [2 * (where + n)],
		2 * sizeof (char *) * (last - where));

	/* reuse storage for new lines at where */
	bcopy ((char *)save, (char *) &sb[2 * where], 2 * sizeof(char *) * n);
}


ScrnDeleteLine (sb, last, where, n, size)
/*
   Deletes n lines at sb + where, treating last as a bottom margin.
   Size is the size of each entry in sb.
   Requires 0 <= where < where + n < = last
   	    n <= MAX_ROWS
 */
register ScrnBuf sb;
register int n, last, size;
int where;
{
	register int i;
	char *save [2 * MAX_ROWS];

	/* save n lines at where */
	bcopy ((char *) &sb[2 * where], (char *)save, 2 * sizeof(char *) * n);

	/* clear contents of old rows */
	for (i = 2 * n - 1 ; i >= 0 ; i--)
		bzero ((char *) save [i], size);

	/* move up lines */
	bcopy ((char *) &sb[2 * (where + n)], (char *) &sb[2 * where],
		2 * sizeof (char *) * ((last -= n - 1) - where));

	/* reuse storage for new bottom lines */
	bcopy ((char *)save, (char *) &sb[2 * last],
		2 * sizeof(char *) * n);
}


ScrnInsertChar (sb, row, col, n, size)
/*
   Inserts n blanks in sb at row, col.  Size is the size of each row.
 */
ScrnBuf sb;
int row, size;
register int col, n;
{
	register int i, j;
	register char *ptr = sb [2 * row];
	register char *att = sb [2 * row + 1];

	for (i = size - 1; i >= col + n; i--) {
		ptr[i] = ptr[j = i - n];
		att[i] = att[j];
	}

	bzero (ptr + col, n);
	bzero (att + col, n);
}


ScrnDeleteChar (sb, row, col, n, size)
/*
   Deletes n characters in sb at row, col. Size is the size of each row.
 */
ScrnBuf sb;
register int row, size;
register int n, col;
{
	register char *ptr = sb[2 * row];
	register char *att = sb[2 * row + 1];
	register nbytes = (size - n - col);

	bcopy (ptr + col + n, ptr + col, nbytes);
	bcopy (att + col + n, att + col, nbytes);
	bzero (ptr + size - n, n);
	bzero (att + size - n, n);
}


ScrnRefresh (screen, toprow, leftcol, nrows, ncols)
/*
   Repaints the area enclosed by the parameters.
   Requires: (toprow, leftcol), (toprow + nrows, leftcol + ncols) are
   	     coordinates of characters in screen;
	     nrows and ncols positive.
 */
register Screen *screen;
int toprow, leftcol, nrows, ncols;
{
	int y = toprow * FontHeight(screen) + screen->border + Titlebar(screen);
	register int row;
	register int topline = screen->topline;
	int maxrow = toprow + nrows - 1;
	int scrollamt = screen->scroll_amt;
	int max = screen->max_row;
	int dostatus = 0, left, width;
	

	if(screen->statusline && maxrow == screen->max_row + 1) {
		dostatus++;
		maxrow--;
	}
	if(screen->cursor_col >= leftcol && screen->cursor_col <=
	 (leftcol + ncols - 1) && screen->cursor_row >= toprow + topline &&
	 screen->cursor_row <= maxrow + topline)
		screen->cursor_state = OFF;
    for( ; ; ) {
	for (row = toprow; row <= maxrow; y += FontHeight(screen), row++)
	{
	   register char *chars;
	   register char *att;
	   register int col = leftcol;
	   int maxcol = leftcol + ncols - 1;
	   int lastind;
	   int flags;
	   int gxfunction;
	   Font fnt;
	   int x, yb, pix, n;

	   lastind = row - scrollamt;
	   if (lastind < 0 || lastind > max)
	   	continue;
	   chars = screen->buf [2 * (lastind + topline)];
	   att = screen->buf [2 * (lastind + topline) + 1];

	   while (col <= maxcol && (att[col] & ~BOLD) == 0 &&
	    (chars[col] & ~040) == 0)
		col++;

	   while (col <= maxcol && (att[maxcol] & ~BOLD) == 0 &&
	    (chars[maxcol] & ~040) == 0)
		maxcol--;

	   if (col > maxcol) continue;

	   flags = att[col];

	   fnt = ActiveIcon(screen)
		 ? screen->fnt_icon
		 : (flags & BOLD)
		   ? screen->fnt_bold
		   : screen->fnt_norm;

	   x = col * FontWidth(screen) + screen->border;
	   lastind = col;

	   for (; col <= maxcol; col++) {
		if (att[col] != flags) {
		   if (((flags & INVERSE) != 0) ^ (dostatus < 0 &&
		    screen->reversestatus))
		   	XText (VWindow(screen), x, y, &chars[lastind],
				n = col - lastind, fnt,
		   		pix = screen->background, screen->foreground);
		   else
		 	XText (VWindow(screen), x, y, &chars[lastind],
				n = col - lastind, fnt,
		   		pix = screen->foreground, screen->background);
		   if((flags & BOLD) && screen->enbolden)
		 	XTextMask (VWindow(screen), x + 1, y, &chars[lastind],
				n, fnt, pix);
		   if(flags & UNDERLINE) {
			yb = y + FontHeight(screen) - 2;
			XLine(VWindow(screen), x, yb, x + n * FontWidth(screen),
			 yb, 1, 1, pix, GXcopy, AllPlanes);
		   }

		   x += (col - lastind) * FontWidth(screen);

		   lastind = col;

		   flags = att[col];

		   fnt = ActiveIcon(screen)
		   	 ? screen->fnt_icon
			 : (flags & BOLD)
			   ? screen->fnt_bold
			   : screen->fnt_norm;
		}

		if(chars[col] == 0)
			chars[col] = ' ';
	   }

	   if (((flags & INVERSE) != 0) ^ (dostatus < 0 &&
	    screen->reversestatus))
	   	XText (VWindow(screen), x, y, &chars[lastind],
		 n = col - lastind, fnt, pix = screen->background,
		 screen->foreground);
	   else
	   	XText (VWindow(screen), x, y, &chars[lastind],
		 n = col - lastind, fnt, pix = screen->foreground,
		 screen->background);
	   if((flags & BOLD) && screen->enbolden)
		XTextMask (VWindow(screen), x + 1, y, &chars[lastind],
			n, fnt, pix);
	   if(flags & UNDERLINE) {
		yb = y + FontHeight(screen) - 2;
		XLine(VWindow(screen), x, yb, x + n * FontWidth(screen), yb, 1, 1,
		 pix, GXcopy, AllPlanes);
	   }
	}
	if(dostatus <= 0)
		break;
	dostatus = -1;
	topline = 0;
	scrollamt = 0;
	toprow = maxrow = max = screen->max_row + 1;
	left = leftcol * FontWidth(screen) + screen->border;
	width = ncols * FontWidth(screen);
	if(leftcol == 0) {
		left--;
		width++;
	}
	if(leftcol + ncols - 1 >= screen->max_col)
		width++;
	XPixSet(VWindow(screen), left, y, width, screen->statusheight,
	 screen->reversestatus ? screen->foreground : screen->background);
	if(!screen->reversestatus)
		StatusBox(screen);
	y++;
    }
}

ClearBufRows (screen, first, last)
/*
   Sets the rows first though last of the buffer of screen to spaces.
   Requires first <= last; first, last are rows of screen->buf.
 */
register Screen *screen;
register int first, last;
{
	first *= 2;
	last = 2 * last + 1;
	while (first <= last)
		bzero (screen->buf [first++], (screen->max_col + 1));
}

ScreenResize (screen, width, height, flags)
/*
   Resizes screen:
   1. If new window would have fractional characters, sets window size so as to
      discard fractional characters and returns -1.
      Minimum screen size is 1 X 1.
      Note that this causes another ExposeWindow event.
   2. Enlarges screen->buf if necessary.  New space is appended to the bottom
      and to the right
   3. Reduces  screen->buf if necessary.  Old space is removed from the bottom
      and from the right
   4. Cursor is positioned as closely to its former position as possible
   5. Sets screen->max_row and screen->max_col to reflect new size
   6. Maintains the inner border.
   7. Clears origin mode and sets scrolling region to be entire screen.
   8. Returns 0
 */
register Screen *screen;
int width, height;
unsigned *flags;
{
	register int rows, cols;
	register int index;
	register int savelines;
	register ScrnBuf sb = screen->allbuf;
	register ScrnBuf ab = screen->altbuf;
	register int x;
	register int border = 2 * screen->border;
	register int extra, i, j, k;
	register char *sl0, *sl1;	/* keep status line */
	double scale_x, scale_y;
#ifdef sun
#ifdef TIOCSSIZE
	struct ttysize ts;
#endif TIOCSSIZE
#else sun
#ifdef TIOCSWINSZ
	struct winsize ws;
#endif TIOCSWINSZ
#endif sun


	if (ActiveIcon(screen)) return( 0 );	/* don't resize on icon exposure */

	extra = Titlebar(screen) + screen->statusheight;
	/* round so that it is unlikely the screen will change size on  */
	/* small mouse movements.					*/
	rows = (height + FontHeight(screen) / 2 - border - extra) /
	 FontHeight(screen);
	cols = (width + FontWidth(screen) / 2 - border - screen->scrollbar) /
	 FontWidth(screen);
	if (rows < 1) rows = 1;
	if (cols < 1) cols = 1;

	if ((width - border - screen->scrollbar) % FontWidth(screen)
	 != 0 || (height - border - extra) % FontHeight(screen) != 0 ||
	 rows < screen->minrows) {
		XChangeWindow (VWindow(screen),
		 cols * FontWidth(screen) + border + screen->scrollbar,
		 (rows < screen->minrows ? screen->minrows : rows) *
		 FontHeight(screen) + border + extra);
		return (-1);
	}

	/* change buffers if the screen has changed size */
	if (screen->max_row != rows - 1 || screen->max_col != cols - 1) {
		if(screen->cursor_state)
			HideCursor();
		savelines = screen->sb ? screen->savelines : 0;
		j = screen->max_col + 1;
		i = cols - j;
		k = screen->max_row;
		if(rows < k)
			k = rows;
		if(ab) {
			/* resize current lines in alternate buf */
			for (index = x = 0; index <= k; x += 2, index++) {
				if ((ab[x] = realloc(ab[x], cols)) == NULL)
					SysError(ERROR_SREALLOC);
				if((ab[x + 1] = realloc(ab[x + 1], cols)) ==
				 NULL)
					SysError (ERROR_SREALLOC2);
				if (cols > j) {
					bzero (ab [x] + j, i);
					bzero (ab [x + 1] + j, i);
				}
			}
			/* discard excess bottom rows in alt buf */
			for (index = rows, x = 2 * k ; index <=
			 screen->max_row; x += 2, index++) {
			   free (ab [x]);
			   free (ab [x + 1]);
			}
		}
		/* resize current lines */
		k += savelines + 1;	/* includes status line */
		for (index = x = 0; index <= k; x += 2, index++) {
			if ((sb[x] = realloc(sb[x], cols)) == NULL)
				SysError(ERROR_SREALLOC3);
			if((sb[x + 1] = realloc(sb[x + 1], cols)) == NULL)
				SysError (ERROR_SREALLOC4);
			if (cols > j) {
				bzero (sb [x] + j, i);
				bzero (sb [x + 1] + j, i);
			}
		}
		/* discard excess bottom rows, but not status line */
		for (index = rows, x = 2 * (k - 1); index <= screen->max_row;
		 x += 2, index++) {
		   free (sb [x]);
		   free (sb [x + 1]);
		}
		if(ab) {
		    if((ab = (ScrnBuf)realloc(ab, 2 * sizeof(char *) * rows))
		     == NULL)
			SysError (ERROR_RESIZE);
		    screen->altbuf = ab;
		}
		/* save status line */
		sl0 = sb[i = 2 * (savelines + screen->max_row + 1)];
		sl1 = sb[i + 1];
		k = 2 * (rows + savelines + 1);	/* includes status line */
		/* resize sb */
		if((sb = (ScrnBuf)realloc(sb, k * sizeof(char *))) == NULL)
			SysError (ERROR_RESIZE2);
		screen->allbuf = sb;
		screen->buf = &sb[2 * savelines];
	
		if(ab) {
			/* create additional bottom rows as required in alt */
			for (index = screen->max_row + 1, x = 2 * index ;
			 index < rows; x += 2, index++) {
			   if((ab[x] = calloc (cols, sizeof(char))) == NULL)
				SysError(ERROR_RESIZROW);
			   if((ab[x + 1] = calloc (cols, sizeof(char))) == NULL)
				SysError(ERROR_RESIZROW2);
			}
		}
		/* create additional bottom rows as required */
		for (index = screen->max_row + 1, x = 2 * (index + savelines) ;
		 index < rows; x += 2, index++) {
		   if((sb[x] = calloc (cols, sizeof(char))) == NULL)
			SysError(ERROR_RESIZROW3);
		   if((sb[x + 1] = calloc (cols, sizeof(char))) == NULL)
			SysError(ERROR_RESIZROW4);
		}

		/* reinstall status line */
		sb[x = 2 * (rows + savelines)] = sl0;
		sb[x + 1] = sl1;
	
		screen->max_row = rows - 1;
		screen->max_col = cols - 1;
	
		/* adjust scrolling region */
		screen->top_marg = 0;
		screen->bot_marg = screen->max_row;
		*flags &= ~ORIGIN;
	
		if (screen->instatus)
			screen->cur_row = screen->max_row + 1;
		else if (screen->cur_row > screen->max_row)
			screen->cur_row = screen->max_row;
		if (screen->cur_col > screen->max_col)
			screen->cur_col = screen->max_col;
	
		screen->fullVwin.height = height - border - extra;
		screen->fullVwin.width = width - border - screen->scrollbar;

		if (screen->active_icon)
		    SetIconSize( screen );

	} else if(FullHeight(screen) == height && FullWidth(screen) == width)
	 	return(0);	/* nothing has changed at all */

	if(screen->sb)
		ResizeScrollBar(screen->sb, width - SCROLLBARWIDTH,
		 Titlebar(screen) - 1, height - Titlebar(screen), rows);
	if(screen->title.tbar && FullWidth(screen) != width)
		VTTitleResize(width);
	
	screen->fullVwin.fullheight = height;
	screen->fullVwin.fullwidth = width;
#ifdef sun
#ifdef TIOCSSIZE
	/* Set tty's idea of window size */
	ts.ts_lines = rows;
	ts.ts_cols = cols;
	ioctl (screen->respond, TIOCSSIZE, &ts);
#ifdef SIGWINCH
	if(screen->pid > 1)
		killpg(getpgrp(screen->pid), SIGWINCH);
#endif SIGWINCH
#endif TIOCSSIZE
#else sun
#ifdef TIOCSWINSZ
	/* Set tty's idea of window size */
	ws.ws_row = rows;
	ws.ws_col = cols;
	ws.ws_xpixel = width;
	ws.ws_ypixel = height;
	ioctl (screen->respond, TIOCSWINSZ, &ws);
#ifdef SIGWINCH
	if(screen->pid > 1)
		killpg(getpgrp(screen->pid), SIGWINCH);
#endif SIGWINCH
#endif TIOCSWINSZ
#endif sun
	return (0);
}


SetIconSize( screen )
  Screen *screen;
{
	if (screen->active_icon) {
	    screen->iconVwin.width = (screen->max_col + 1)
				     * screen->iconVwin.f_width
	    			     + screen->border * 2;
	    screen->iconVwin.height = (screen->max_row + 1)
				      * screen->iconVwin.f_height
	    			      + screen->border * 2;
	    XChangeWindow( screen->iconVwin.window,
			   screen->iconVwin.width,
			   screen->iconVwin.height );
	} else {
	    IconRecalc( screen );
	}

	screen->iconVwin.fullwidth = screen->iconVwin.width;
	screen->iconVwin.fullheight = screen->iconVwin.height;
}
RAZZLE!DAZZLE
fi	# End screen.c
echo '***** End of' xterm 6.6B - Part 6 of 7 '*****'
exit