[mod.sources] v09i060: Terminal emulator for X window system, Part07/07

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

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

[  Following the schedule, I'll be posting articles to both the old and
   the new name for a while; sorry, notes sites.  --r$  ]
  

#! /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:
#	Makefile scrollbar.c tabs.c termcap terminfo util.c Xlib/Makefile
#	Xlib/README Xlib/XKeyBind.c
if test -f Makefile
then
	echo shar: will not overwrite existing file "'Makefile'"
else
echo 'x - Makefile'
cat << \RAZZLE!DAZZLE > Makefile
#
# 	$Source: /u1/X/xterm/RCS/Makefile,v $
#	$Header: Makefile,v 10.2 86/12/01 17:52:22 swick Rel $
#

#
#	Makefile for X window system terminal emulator.
#	@(#)Makefile       X10/6.6B 12/26/86
#

DESTDIR=
# We put xterm in /etc so you can run on partial boot.  A link is put
# in CONFDIR so normal search paths will find xterm.
# 
# For the 4.3 distribution, the executable is put in /usr/local instead.
#
CONFDIR= /usr/local
INCLUDES= -I../include
LIBS= ../Xlib/libX.a -ltermcap
#
# The option KEYBD may be included if the keyboard mods have been done to
# XKeyBind.c in libX.a.
cflags = -O -DMODEMENU ${INCLUDES} -DUTMP -DKEYBD
#
# NOWINDOWMENU	disables the window manager menu (right button)
# DROPMENUS	causes the menus to drop from the cursor rather than be
#		centered vertically.
#cflags = -O -DMODEMENU ${INCLUDES} -DUTMP -DNOWINDOWMENU -DDROPMENUS
CFLAGS = -R ${cflags}
SOURCE = Makefile data.h error.h menu.h ptyx.h scrollbar.h VTparse.h \
		Tekparse.h button.c charproc.c cursor.c data.c input.c \
		main.c menu.c misc.c screen.c scrollbar.c tabs.c \
		Tekparsetable.c Tekproc.c util.c VTparsetable.c

.SUFFIXES: .o .h .c

OBJS =	main.o input.o charproc.o cursor.o util.o tabs.o \
	screen.o scrollbar.o button.o Tekproc.o misc.o \
	VTparsetable.o Tekparsetable.o data.o menu.o

all: xterm resize

xterm: $(OBJS) ../Xlib/libX.a
	$(CC) $(CFLAGS) -o xterm $(OBJS) $(LIBS)

button.o: data.h error.h menu.h ptyx.h scrollbar.h

charproc.o: VTparse.h error.h data.h menu.h ptyx.h scrollbar.h

cursor.o: ptyx.h

data.o: data.c ptyx.h scrollbar.h
	$(CC) $(cflags) -c data.c

input.o: ptyx.h

main.o: data.h error.h main.h ptyx.h scrollbar.h

menu.o: menu.h

misc.o: error.h ptyx.h scrollbar.h gray.ic hilite.ic icon.ic wait.ic waitmask.ic

screen.o: error.h ptyx.h scrollbar.h

scrollbar.o: error.h ptyx.h scrollbar.h button.ic dark.ic light.ic upline.ic \
	downline.ic uppage.ic downpage.ic top.ic bottom.ic saveoff.ic saveon.ic

tabs.o: ptyx.h

Tekparsetable.o: Tekparse.h

Tekproc.o: Tekparse.h error.h data.h menu.h ptyx.h scrollbar.h

VTparsetable.o: VTparse.h

util.o: ptyx.h scrollbar.h

resize: resize.o
	$(CC) $(cflags) -o resize resize.o -lc -ltermcap

resize.o: resize.c
	$(CC) $(cflags) -c resize.c

install: all
#	install -m 4755 xterm ${DESTDIR}/etc
	install -m 4755 xterm ${DESTDIR}${CONFDIR}
#	rm -f ${DESTDIR}${CONFDIR}/xterm
#	ln -s /etc/xterm ${DESTDIR}${CONFDIR}/xterm
	install resize ${DESTDIR}${CONFDIR}

clean:
	rm -f xterm resize *.o a.out core errs gmon.out *.bak *~

print:
	lpr -Pln ${SOURCE}
RAZZLE!DAZZLE
fi	# End Makefile
if test -f scrollbar.c
then
	echo shar: will not overwrite existing file "'scrollbar.c'"
else
echo 'x - scrollbar.c'
cat << \RAZZLE!DAZZLE > scrollbar.c
/*
 *	$Source: /u1/X/xterm/RCS/scrollbar.c,v $
 *	$Header: scrollbar.c,v 10.100 86/12/01 14:45:27 jg Rel $
 */

#include <stdio.h>
#include <sys/time.h>
#include <X/Xlib.h>
#include <setjmp.h>
#include "scrollbar.h"
#include "ptyx.h"
#include "data.h"
#include "error.h"
#ifdef MODEMENU
#include "menu.h"
#endif MODEMENU

#include "button.ic"
#include "dark.ic"
#include "light.ic"
#include "upline.ic"
#include "downline.ic"
#include "uppage.ic"
#include "downpage.ic"
#include "top.ic"
#include "bottom.ic"
#include "saveoff.ic"
#include "saveon.ic"
#ifndef lint
static char sccs_id[] = "@(#)scrollbar.c\tX10/6.6B\t12/26/86";
#endif	lint

static struct timeval stepspeed;

ScrollBar *
CreateScrollBar(w, x, y, height, fg, bg, bordertile, val, valregion,
 topval, botval, arrow)
	Window w;
	int x, y, height, fg, bg, val, valregion, topval, botval;
	Pixmap bordertile;
	Cursor arrow;
{
	register ScrollBar *sb;
	register int i;
	Pixmap btile, bgnd;
	extern char *calloc();
	static Window Make_tiled_window();
	extern Pixmap Make_tile();

	if(!w || height < MINSCROLLBARHEIGHT ||
	 (sb = (ScrollBar *)calloc(1, sizeof(ScrollBar))) == NULL)
		return(NULL);
	btile = bordertile;
	if(bg == BlackPixel && fg == WhitePixel) {
		bg = WhitePixel;
		fg = BlackPixel;
		if(btile == WhitePixmap)
			btile = BlackPixmap;
	}
	sb->fg = fg;
	sb->bg = bg;
	sb->cursor = arrow;
	if((sb->bar = Make_tiled_window(light_width, light_height, light_bits,
	 fg, bg, &bgnd, w, x, y, (SCROLLBARWIDTH - 1), height, 1, bordertile))
	 == NULL)
		goto failed_bar;
	if((sb->button = XCreateWindow(sb->bar, -1, -1, (SCROLLBARWIDTH - 1),
	 BUTTONHEIGHT - 1, 1, btile, bgnd)) == NULL)
		goto failed_button;
	if((sb->save = XCreateWindow(sb->bar, -1, BUTTONHEIGHT - 1,
	 (SCROLLBARWIDTH - 1), BUTTONHEIGHT - 1, 1, btile, bgnd)) == NULL)
		goto failed_save;
	if((sb->region = Make_tiled_window(dark_width, dark_height, dark_bits,
	 fg, bg, &bgnd, sb->bar, 0, 0, (SCROLLBARWIDTH - 1), 10, 0,
	 (Pixmap)NULL)) == NULL) {
		XDestroyWindow(sb->save);
failed_save:
		XDestroyWindow(sb->button);
failed_button:
		XDestroyWindow(sb->bar);
failed_bar:
		free((char *)sb);
		return(NULL);
	}
	sb->savebits[SAVE_OFF] = saveoff_bits;
	sb->savebits[SAVE_ON] = saveon_bits;
	sb->buttonbits[BUTTON_UPLINE / 2] = upline_bits;
	sb->buttonbits[BUTTON_DOWNLINE / 2] = downline_bits;
	sb->buttonbits[BUTTON_UPPAGE / 2] = uppage_bits;
	sb->buttonbits[BUTTON_DOWNPAGE / 2] = downpage_bits;
	sb->buttonbits[BUTTON_TOP / 2] = top_bits;
	sb->buttonbits[BUTTON_BOTTOM / 2] = bottom_bits;
	sb->buttonbits[BUTTON_NORMAL / 2] = button_bits;
	XDefineCursor(sb->bar, sb->cursor);
	XSelectInput(sb->bar, ButtonPressed | ButtonReleased | ExposeWindow |
	 EnterWindow | LeaveWindow | UnmapWindow);
	XSelectInput(sb->button, EnterWindow | LeaveWindow);
	XMapWindow(sb->button);	/* will really map when bar is mapped */
	XMapWindow(sb->save);	/* will really map when bar is mapped */
	sb->buttonstate = sb->buttonset = BUTTON_NORMAL;
	sb->savestate = sb->saveset = SAVE_ON;
	sb->set.value = val;
	sb->set.regionheight = valregion;
	sb->set.topvalue = topval;
	sb->set.bottomvalue = botval;
	sb->set.height = height - BARSTART;
	return(sb);
}

ShowScrollBar(sb)
	register ScrollBar *sb;
{
	if(sb->visible)
		return;
	sb->visible = 1;
	if(sb->regionvisible) {
		XUnmapWindow(sb->region);
		sb->regionvisible = 0;
	}
	XMapWindow(sb->bar);
	DrawScrollRegion(sb);
	sb->action = SHOW;
}

HideScrollBar(sb)
	register ScrollBar *sb;
{
	if(!sb->visible)
		return;
	sb->visible = 0;
	XUnmapWindow(sb->bar);
}

DrawScrollRegion(sb)
	register ScrollBar *sb;
{
	register int region, temp;

	if(sb->set.regionheight <= 0)
		sb->set.regionheight = 0;
	if((region = sb->set.topvalue - sb->set.bottomvalue) >= 0) {
		if(sb->set.value > sb->set.topvalue)
			sb->set.value = sb->set.topvalue;
		else if(sb->set.value < sb->set.bottomvalue)
			sb->set.value = sb->set.bottomvalue;
	} else {
		region = -region;
		if(sb->set.value < sb->set.topvalue)
			sb->set.value = sb->set.topvalue;
		else if(sb->set.value > sb->set.bottomvalue)
			sb->set.value = sb->set.bottomvalue;
	}
	if(sb->set.value == sb->set.topvalue) {
		sb->set.pixelheight = (region == 0) ? sb->set.height :
		 (sb->set.height - 1) * sb->set.regionheight /
		 (sb->set.regionheight + region);
		sb->set.y = BARSTART;
	} else if(sb->set.value == sb->set.bottomvalue) {
		sb->set.pixelheight = (sb->set.height - 1) *
		 sb->set.regionheight / (sb->set.regionheight + region);
		sb->set.y = BARSTART + sb->set.height - sb->set.pixelheight;
	} else {
		if(sb->set.topvalue >= sb->set.bottomvalue) {
			temp = sb->set.topvalue - 1;
			region = temp - (sb->set.bottomvalue + 1);
			sb->set.y = temp - sb->set.value;
		} else {
			temp = sb->set.topvalue + 1;
			region = (sb->set.bottomvalue - 1) - temp;
			sb->set.y = sb->set.value - temp;
		}
		sb->set.y = (BARSTART + 1) + sb->set.y * (sb->set.height - 2) /
		 (temp = sb->set.regionheight + region);
		sb->set.pixelheight = (sb->set.height - 2) *
		 sb->set.regionheight / temp;
	}
	if(sb->set.pixelheight <= 0)
		sb->set.pixelheight = 1;
	if(sb->set.regionheight == 0) {
		sb->state = sb->set;
		if(sb->regionvisible) {
			XUnmapWindow(sb->region);
			sb->regionvisible = 0;
		}
		return;
	}
	if(!sb->visible || sb->regionvisible
	 && sb->state.y == sb->set.y
	 && sb->state.pixelheight == sb->set.pixelheight) {
		sb->state = sb->set;
		return;
	}
	sb->state = sb->set;
	XConfigureWindow(sb->region, 0, sb->state.y, (SCROLLBARWIDTH - 1),
	 sb->state.pixelheight);
	if(!sb->regionvisible) {
		XMapWindow(sb->region);
		sb->regionvisible = 1;
	}
}

DrawButton(sb)
	register ScrollBar *sb;
{
	register int fg, bg;

	if(sb->visible && sb->buttonstate != sb->buttonset) {
		if((sb->buttonstate = sb->buttonset) & HILITED) {
			fg = sb->bg;
			bg = sb->fg;
		} else {
			fg = sb->fg;
			bg = sb->bg;
		}
		XBitmapBitsPut(sb->button, 0, 0, SCROLLBARWIDTH - 1,
		 BUTTONHEIGHT - 1, sb->buttonbits[sb->buttonstate / 2],
		 fg, bg, (Bitmap)0, GXcopy, AllPlanes);
	}
}

DrawSave(sb)
	register ScrollBar *sb;
{
	if(sb->visible && sb->savestate != sb->saveset)
		XBitmapBitsPut(sb->save, 0, 0, SCROLLBARWIDTH - 1,
		 BUTTONHEIGHT - 1, sb->savebits[sb->savestate = sb->saveset],
		 sb->fg, sb->bg, (Bitmap)0, GXcopy, AllPlanes);
}

ResizeScrollBar(sb, x, y, height, region)
	register ScrollBar *sb;
	int x, y, height, region;
{
	register int act;

	act = sb->action;
	sb->action = NONE;
	switch(act) {
	 case SHOW:
		return;
	 case HIDE:
		HideScrollBar(sb);
		return;
	}
	if(!sb->visible)
		return;
	if(sb->regionvisible) {
		XUnmapWindow(sb->region);
		sb->regionvisible = 0;
	}
	XConfigureWindow(sb->bar, x, y, (SCROLLBARWIDTH - 1), height);
	sb->set.height = height - BARSTART;
	sb->set.regionheight = region;
	DrawScrollRegion(sb);
}

PositionRegion(sb, y)
	register ScrollBar *sb;
	register int y;
{
	if(y <= BARSTART)
		sb->set.value = sb->set.topvalue;
	else if(y >= BARSTART + sb->set.height *
	 (sb->set.bottomvalue - sb->set.topvalue) /
	 (sb->set.bottomvalue + sb->set.regionheight - sb->set.topvalue))
		sb->set.value = sb->set.bottomvalue;
	else
		sb->set.value = sb->set.topvalue + (y - BARSTART) *
		 (sb->set.bottomvalue + sb->set.regionheight - sb->set.topvalue)
		 / sb->set.height;
	DrawScrollRegion(sb);
	return(sb->state.value);
}

ButtonRegion(sb)
	register ScrollBar *sb;
{
	register int reverse, pagesize;

	if(!(sb->buttonset & HILITED))
		return(sb->set.value);
	reverse = (sb->set.bottomvalue > sb->set.topvalue);
	pagesize = sb->set.regionheight - 1;
	switch(sb->buttonset) {
	 case BUTTON_UPLINEHI:
		if(reverse)
			sb->set.value--;
		else
			sb->set.value++;
		break;
	 case BUTTON_DOWNLINEHI:
		if(reverse)
			sb->set.value++;
		else
			sb->set.value--;
		break;
	 case BUTTON_UPPAGEHI:
		if(reverse)
			sb->set.value -= pagesize;
		else
			sb->set.value += pagesize;
		break;
	 case BUTTON_DOWNPAGEHI:
		if(reverse)
			sb->set.value += pagesize;
		else
			sb->set.value -= pagesize;
		break;
	 case BUTTON_TOPHI:
		sb->set.value = sb->set.topvalue;
		break;
	 case BUTTON_BOTTOMHI:
		sb->set.value = sb->set.bottomvalue;
	}
	DrawScrollRegion(sb);
	return(sb->set.value);
}

DownButtonDown(term, reply, pty)
	Terminal *term;
	register XKeyOrButtonEvent *reply;
	int pty;			/* file descriptor of pty */
{
	register Screen *screen = &term->screen;
	register ScrollBar *sb = screen->sb;
	register Window window = reply->subwindow;

	if(!window || window == sb->region) {
		WindowScroll(screen, PositionRegion(sb, reply->y));
		return;
	}
	if(window == sb->save) {
		SetSaveState(sb, !GetSaveState(sb));
		return;
	}
	if(window != sb->button || !XGrabMouse(sb->button, sb->cursor,
	 ButtonReleased | EnterWindow | LeaveWindow)) {
		Bell();
		return;
	}
	if(reply->detail & ControlMask)
		sb->buttonset = BUTTON_BOTTOMHI;
	else if(reply->detail & ShiftMask)
		sb->buttonset = BUTTON_DOWNPAGEHI;
	else {
		sb->buttonset = BUTTON_DOWNLINEHI;
		stepspeed.tv_usec = PAUSETIME;
		screen->timeout = &stepspeed;
		WindowScroll(screen, ButtonRegion(screen->sb));
	}
	DrawButton(sb);
}

UpButtonDown(term, reply, pty)
	Terminal *term;
	register XKeyOrButtonEvent *reply;
	int pty;			/* file descriptor of pty */
{
	register Screen *screen = &term->screen;
	register ScrollBar *sb = screen->sb;
	register Window window = reply->subwindow;

	if(!window || window == sb->region) {
		WindowScroll(screen, PositionRegion(sb, reply->y));
		return;
	}
	if(window == sb->save) {
		SetSaveState(sb, !GetSaveState(sb));
		return;
	}
	if(window != sb->button || !XGrabMouse(sb->button, sb->cursor,
	 ButtonReleased | EnterWindow | LeaveWindow)) {
		Bell();
		return;
	}
	if(reply->detail & ControlMask)
		sb->buttonset = BUTTON_TOPHI;
	else if(reply->detail & ShiftMask)
		sb->buttonset = BUTTON_UPPAGEHI;
	else {
		sb->buttonset = BUTTON_UPLINEHI;
		stepspeed.tv_usec = PAUSETIME;
		screen->timeout = &stepspeed;
		WindowScroll(screen, ButtonRegion(screen->sb));
	}
	DrawButton(sb);
}

ButtonUp(term, reply, pty)
	Terminal *term;
	XKeyOrButtonEvent *reply;
	int pty;			/* file descriptor of pty */
{
	register Screen *screen = &term->screen;
	register ScrollBar *sb = screen->sb;
	register int state;

	if((state = GetButtonState(sb)) == BUTTON_NORMAL)
		return;
	/* don't scroll further on line mode */
	if(state > BUTTON_DOWNLINEHI)
		WindowScroll(screen, ButtonRegion(sb));
	sb->buttonset = BUTTON_NORMAL;
	DrawButton(sb);
	screen->timeout = NULL;
	XUngrabMouse();
}

WindowScroll(screen, top)
	register Screen *screen;
	int top;
{
	register int i, lines;
	register int scrolltop, scrollheight, refreshtop;

	if((i = screen->topline - top) == 0)
		return;
	if(screen->cursor_state)
		HideCursor();
	lines = i > 0 ? i : -i;
	if(lines > screen->max_row + 1)
		lines = screen->max_row + 1;
	scrollheight = screen->max_row - lines + 1;
	if(i > 0)
		refreshtop = scrolltop = 0;
	else {
		scrolltop = lines;
		refreshtop = scrollheight;
	}
	if(scrollheight > 0) {
		if (screen->multiscroll && scrollheight == 1 &&
		 screen->topline == 0 && screen->top_marg == 0 &&
		 screen->bot_marg == screen->max_row) {
			if (screen->incopy < 0 && screen->scrolls == 0)
				CopyWait (screen);
			screen->scrolls++;
		} else {
			if (screen->incopy)
				CopyWait (screen);
			screen->incopy = -1;
		}
		XMoveArea(VWindow(screen), screen->border, scrolltop *
		 FontHeight(screen) + screen->border + Titlebar(screen),
		 screen->border, (scrolltop + i) * FontHeight(screen) +
		 screen->border + Titlebar(screen), Width(screen),
		 scrollheight * FontHeight(screen));
	}
	screen->topline = top;
	XTileSet(VWindow(screen), screen->border, refreshtop * FontHeight(screen) +
	 screen->border + Titlebar(screen), Width(screen), lines *
	 FontHeight(screen), screen->bgndtile);
	ScrnRefresh(screen, refreshtop, 0, lines, screen->max_col + 1);
}

ScrollBarOn(screen, show, init)
	register Screen *screen;
	int show, init;
{
	register int border = 2 * screen->border;
	register int i;
	char *realloc(), *calloc();

	if(screen->scrollbar)
		return;
	if(!screen->sb) {
		if((screen->sb = CreateScrollBar(VWindow(screen),
		 Width(screen) + border, Titlebar(screen) - 1,
		 Height(screen) + border, screen->foreground,
		 screen->background, screen->bordertile, 0,
		 screen->max_row + 1, 0, 0, screen->arrow)) == NULL) {
			Bell();
			return;
		}
		if((screen->allbuf = (ScrnBuf) realloc(screen->buf,
		 2*(screen->max_row + 2 + screen->savelines) * sizeof(char *)))
		 == NULL)
			Error (ERROR_SBRALLOC);
		screen->buf = &screen->allbuf[2 * screen->savelines];
		bcopy ((char *)screen->allbuf, (char *)screen->buf,
		 2 * (screen->max_row + 2) * sizeof (char *));
		for(i = 2 * screen->savelines - 1 ; i >= 0 ; i--)
			if((screen->allbuf[i] =
			 calloc(screen->max_col + 1, sizeof(char))) == NULL)
				Error (ERROR_SBRALLOC2);
		screen->sb->saveset = !screen->alternate;
	} else {
		XConfigureWindow(screen->sb->bar, FullWidth(screen),
		 Titlebar(screen) - 1, (SCROLLBARWIDTH - 1),
		 i = FullHeight(screen) - Titlebar(screen));
		screen->sb->set.height = i - BARSTART;
		screen->sb->set.regionheight = screen->max_row + 1;
	}
	if(show) {
		screen->scrollbar = SCROLLBARWIDTH;
		ShowScrollBar(screen->sb);
		if(!init) {
			XSetResizeHint(VWindow(screen), border + SCROLLBARWIDTH,
			 border + Titlebar(screen) + screen->statusheight,
			 FontWidth(screen), FontHeight(screen));
			XChangeWindow(VWindow(screen), (screen->max_col + 1) *
			 FontWidth(screen) + border + SCROLLBARWIDTH,
			 FontHeight(screen) * (screen->max_row + 1) +
			 screen->statusheight + border + Titlebar(screen));
		}
	}
}

ScrollBarOff(screen)
	register Screen *screen;
{
	register int border = 2 * screen->border;

	if(!screen->scrollbar)
		return;
	screen->sb->action = HIDE;
	screen->scrollbar = 0;
	XSetResizeHint(VWindow(screen), border, border + Titlebar(screen) +
	 screen->statusheight, FontWidth(screen), FontHeight(screen));
	XChangeWindow(VWindow(screen), (screen->max_col + 1) * FontWidth(screen) +
	 border, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight
	 + border + Titlebar(screen));
}

ClearLinesOffTop(screen)
	register Screen *screen;
{
	if(!screen->sb)
		return;
	if(screen->topline)
		WindowScroll(screen, 0);
	SetScrollBarTop(screen->sb, 0);
	DrawScrollRegion(screen->sb);
}

SetSaveState(sb, state)
	register ScrollBar *sb;
	int state;
{
	extern Terminal term;
	register Screen *screen = &term.screen;

	if(screen->alternate)
		return;
	if(screen->scroll_amt)
		FlushScroll(screen);
	sb->saveset = state;
	DrawSave(sb);
}

SetButtonState(sb, state)
	register ScrollBar *sb;
	int state;
{
	sb->buttonset = state;
	DrawButton(sb);
}

static Window
Make_tiled_window(bitmap_width, bitmap_height, bitmap_bits, foreground,
 background, bgnd, parent, x, y, width, height, borderwidth, bordertile)
	int bitmap_width, bitmap_height, foreground, background, x, y, width,
	 height, borderwidth;
	short *bitmap_bits;
	Window parent;
	Pixmap *bgnd, bordertile;
{
	register Pixmap pix;
	register Window w;
	extern Pixmap Make_tile();

	if((pix = Make_tile(bitmap_width, bitmap_height, bitmap_bits,
	 foreground, background)) == NULL)
		return(NULL);
	w = XCreateWindow(parent, x, y, width, height, borderwidth, bordertile,
	 pix);
	*bgnd = pix;
	return(w);
}

Pixmap
Make_tile(bitmap_width, bitmap_height, bitmap_bits, foreground, background)
	int bitmap_width, bitmap_height, foreground, background;
	short *bitmap_bits;
{
	register Bitmap bm;
	register Pixmap pix;

	if((bm = XStoreBitmap(bitmap_width, bitmap_height, bitmap_bits))
	 == NULL)
		return(NULL);
	pix = XMakePixmap(bm, foreground, background);
	XFreeBitmap(bm);
	return(pix);
}

ScrollToBottom(sb)
register ScrollBar *sb;
{
	SetScrollBarValue(sb, GetScrollBarBottom(sb));
	DrawScrollRegion(sb);
	WindowScroll(&term.screen, GetScrollBarValue(sb));
}

#ifdef MODEMENU
#define	SMENU_SCROLLKEY	0
#define	SMENU_SCROLLINPUT (SMENU_SCROLLKEY+1)
#define	SMENU_LINESTOP	(SMENU_SCROLLINPUT+1)
#define	SMENU_LINE	(SMENU_LINESTOP+1)
#define	SMENU_CLEARTOP	(SMENU_LINE+1)
#define	SMENU_HIDE	(SMENU_CLEARTOP+1)

static char *stext[] = {
	"Scroll to Bottom on Key",
	"Scroll to Bottom on Input",
	"Lines Off Top Saved",
	"-",
	"Clear Lines Off Top",
	"Hide Scrollbar",
	0,
};


static int salternate;
static int slinestop;
static int sscrollinput;
static int sscrollkey;

Menu *ssetupmenu(menu)
register Menu **menu;
{
	register Screen *screen = &term.screen;
	register char **cp;

	if (*menu == NULL) {
		if ((*menu = NewMenu("Scrollbar", re_verse)) == NULL)
			return(NULL);
		for(cp = stext ; *cp ; cp++)
			AddMenuItem(*menu, *cp);
		if(sscrollkey = screen->scrollkey)
			CheckItem(*menu, SMENU_SCROLLKEY);
		if(sscrollinput = screen->scrollinput)
			CheckItem(*menu, SMENU_SCROLLINPUT);
		if(slinestop = (screen->sb && GetSaveState(screen->sb)))
			CheckItem(*menu, SMENU_LINESTOP);
		if(salternate = screen->alternate)
			DisableItem(*menu, SMENU_LINESTOP);
		DisableItem(*menu, SMENU_LINE);
		return(*menu);
	}
	if(sscrollkey != screen->scrollkey)
		SetItemCheck(*menu, SMENU_SCROLLKEY, (sscrollkey =
		 screen->scrollkey));
	if(sscrollinput != screen->scrollinput)
		SetItemCheck(*menu, SMENU_SCROLLINPUT, (sscrollinput =
		 screen->scrollinput));
	if(screen->sb && slinestop != GetSaveState(screen->sb))
		SetItemCheck(*menu, SMENU_LINESTOP, (slinestop =
		 GetSaveState(screen->sb)));
	if(salternate != screen->alternate)
		SetItemDisable(*menu, SMENU_LINESTOP, (salternate =
		 screen->alternate));
	return(*menu);
}

sdomenufunc(item)
int item;
{
	register Screen *screen = &term.screen;

	switch (item) {
	 case SMENU_SCROLLKEY:
		screen->scrollkey = !screen->scrollkey;
		break;

	 case SMENU_SCROLLINPUT:
		screen->scrollinput = !screen->scrollinput;
		break;

	 case SMENU_LINESTOP:
		SetSaveState(screen->sb, !GetSaveState(screen->sb));
		break;

	 case SMENU_CLEARTOP:
		ClearLinesOffTop(screen);
		break;

	 case SMENU_HIDE:
		ScrollBarOff(screen);
		break;
	}
}
#endif MODEMENU
RAZZLE!DAZZLE
fi	# End scrollbar.c
if test -f tabs.c
then
	echo shar: will not overwrite existing file "'tabs.c'"
else
echo 'x - tabs.c'
cat << \RAZZLE!DAZZLE > tabs.c
/*
 *	$Source: /u1/X/xterm/RCS/tabs.c,v $
 *	$Header: tabs.c,v 10.100 86/12/01 14:45:38 jg Rel $
 */

#ifndef lint
static char *rcsid_tabs_c = "$Header: tabs.c,v 10.100 86/12/01 14:45:38 jg Rel $";
#endif	lint

#include <X/mit-copyright.h>

/* Copyright    Massachusetts Institute of Technology    1984	*/

/* tabs.c */

#ifndef lint
/* @(#)tabs.c       X10/6.6B 12/26/86 */
#endif	lint

#include <X/Xlib.h>
#include "scrollbar.h"
#include "ptyx.h"
/*
 * This file presumes 32bits/word.  This is somewhat of a crock, and should
 * be fixed sometime.
 */

/*
 * places tabstops at only every 8 columns
 */
TabReset(tabs)
Tabs	tabs;
{
	register int i;

	for (i=0; i<TAB_ARRAY_SIZE; ++i)
		tabs[i] = 0;

	for (i=0; i<MAX_TABS; i+=8)
		TabSet(tabs, i);
}	


/*
 * places a tabstop at col
 */
TabSet(tabs, col)
Tabs	tabs;
{
	tabs[col >> 5] |= (1 << (col & 31));
}

/*
 * clears a tabstop at col
 */
TabClear(tabs, col)
Tabs	tabs;
{
	tabs[col >> 5] &= ~(1 << (col & 31));
}

/*
 * returns the column of the next tabstop
 * (or MAX_TABS - 1 if there are no more).
 * A tabstop at col is ignored.
 */
TabNext (tabs, col)
Tabs	tabs;
{
	extern Terminal term;
	register Screen *screen = &term.screen;

	if(screen->curses && screen->do_wrap && (term.flags & WRAPAROUND)) {
		Index(screen, 1);
		col = screen->cur_col = screen->do_wrap = 0;
	}
	for (++col; col<MAX_TABS; ++col)
		if (tabs[col >> 5] & (1 << (col & 31)))
			return (col);

	return (MAX_TABS - 1);
}

/*
 * clears all tabs
 */
TabZonk (tabs)
Tabs	tabs;
{
	register int i;

	for (i=0; i<TAB_ARRAY_SIZE; ++i)
		tabs[i] = 0;
}
RAZZLE!DAZZLE
fi	# End tabs.c
if test -f termcap
then
	echo shar: will not overwrite existing file "'termcap'"
else
echo 'x - termcap'
cat << \RAZZLE!DAZZLE > termcap
# @(#)termcap       X10/6.6B 12/26/86
vs|xterm|vs100|xterm terminal emulator (X window system):\
	:cr=^M:do=^J:nl=^J:bl=^G:le=^H:ho=\E[H:\
	:co#80:li#65:cl=\E[H\E[2J:bs:am:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:\
	:ce=\E[K:cd=\E[J:so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\
	:md=\E[1m:mr=\E[7m:me=\E[m:\
	:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=^H:\
	:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:ta=^I:pt:sf=\n:sr=\EM:\
	:al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:\
	:MT:ks=\E[?1h\E=:ke=\E[?1l\E>:\
	:is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l:\
	:rs=\E[r\E<\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l:xn:\
	:AL=\E[%dL:DL=\E[%dM:IC=\E[%d@:DC=\E[%dP:\
	:ti=\E7\E[?47h:te=\E[2J\E[?47l\E8:\
	:hs:ts=\E[?E\E[?%i%dT:fs=\E[?F:es:ds=\E[?E:
v2|xterms|vs100s|xterm terminal emulator (small)(X window system):\
	:co#80:li#24:tc=xterm:
RAZZLE!DAZZLE
fi	# End termcap
if test -f terminfo
then
	echo shar: will not overwrite existing file "'terminfo'"
else
echo 'x - terminfo'
cat << \RAZZLE!DAZZLE > terminfo
# @(#)terminfo       X10/6.6B 12/26/86
xterm|vs100|xterm terminal emulator,
	ind=^J, cols#80, lines#65,
	clear=\E[H\E[2J, cub1=^H, am, cup=\E[%i%p1%d;%p2%dH,
	cuf1=\E[C, cuu1=\E[A, el=\E[K, ed=\E[J,
	cud=\E[%p1%dB, cuu=\E[%p1%dA, cub=\E[%p1%dD,
	cuf=\E[%p1%dC, km,
	smso=\E[7m, rmso=\E[m, smul@, rmul@,
	bold=\E[1m, rev=\E[7m, blink=@, sgr0=\E[m,
	rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H, rs2=@
	kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, ht=^I, ri=\EM,
	vt@, xon@, csr=\E[%i%p1%d;%p2%dr,
	il=\E[%p1%dL, dl=\E[%p1%dM, il1=\E[L, dl1=\E[M,
	ich=\E[%p1%d@, dch=\E[%p1%dP, ich1=\E[@, dch1=\E[P,
	use=vt100-am,
xterms|vs100s|xterm terminal emulator (small screen 24x80),
	cols#80, lines#24,
	use=xterm,
RAZZLE!DAZZLE
fi	# End terminfo
if test -f util.c
then
	echo shar: will not overwrite existing file "'util.c'"
else
echo 'x - util.c'
cat << \RAZZLE!DAZZLE > util.c
/*
 *	$Source: /u1/X/xterm/RCS/util.c,v $
 *	$Header: util.c,v 10.100 86/12/01 14:45:43 jg Rel $
 */

#include <X/mit-copyright.h>

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

/* util.c */

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

#include <stdio.h>
#include <X/Xlib.h>
#include <signal.h>
#include <setjmp.h>
typedef int *jmp_ptr;

#include "scrollbar.h"
#include "ptyx.h"
#include "data.h"
#include "error.h"

/*
 * These routines are used for the jump scroll feature
 */
FlushScroll(screen)
register Screen *screen;
{
	register int i;
	register int shift = -screen->topline;
	register int bot = screen->max_row - shift;
	register int refreshtop;
	register int refreshheight;
	register int scrolltop;
	register int scrollheight;

	if(screen->cursor_state)
		HideCursor();
	if(screen->scroll_amt > 0) {
		refreshheight = screen->refresh_amt;
		scrollheight = screen->bot_marg - screen->top_marg -
		 refreshheight + 1;
		if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
		 (i = screen->max_row - screen->scroll_amt + 1))
			refreshtop = i;
		if(screen->sb && GetSaveState(screen->sb) &&
		 screen->top_marg == 0) {
			scrolltop = 0;
			if((scrollheight += shift) > i)
				scrollheight = i;
			if((i = screen->bot_marg - bot) > 0 &&
			 (refreshheight -= i) < screen->scroll_amt)
				refreshheight = screen->scroll_amt;
			if((i = -GetScrollBarTop(screen->sb)) <
			 screen->savelines) {
				if((i += screen->scroll_amt) >
				 screen->savelines)
					i = screen->savelines;
				SetScrollBarTop(screen->sb, -i);
				DrawScrollRegion(screen->sb);
			}
		} else {
			scrolltop = screen->top_marg + shift;
			if((i = bot - (screen->bot_marg - screen->refresh_amt +
			 screen->scroll_amt)) > 0) {
				if(bot < screen->bot_marg)
					refreshheight = screen->scroll_amt + i;
			} else {
				scrollheight += i;
				refreshheight = screen->scroll_amt;
				if((i = screen->top_marg + screen->scroll_amt -
				 1 - bot) > 0) {
					refreshtop += i;
					refreshheight -= i;
				}
			}
		}
	} else {
		refreshheight = -screen->refresh_amt;
		scrollheight = screen->bot_marg - screen->top_marg -
		 refreshheight + 1;
		refreshtop = screen->top_marg + shift;
		scrolltop = refreshtop + refreshheight;
		if((i = screen->bot_marg - bot) > 0)
			scrollheight -= i;
		if((i = screen->top_marg + refreshheight - 1 - bot) > 0)
			refreshheight -= i;
	}
	if(scrollheight > 0) {
		if (screen->multiscroll && scrollheight == 1 &&
		 screen->topline == 0 && screen->top_marg == 0 &&
		 screen->bot_marg == screen->max_row) {
			if (screen->incopy < 0 && screen->scrolls == 0)
				CopyWait (screen);
			screen->scrolls++;
		} else {
			if (screen->incopy)
				CopyWait (screen);
			screen->incopy = -1;
		}

		XMoveArea (VWindow(screen), screen->border, (scrolltop +
		 screen->scroll_amt) * FontHeight(screen) + screen->border +
		 Titlebar(screen), screen->border, scrolltop * FontHeight(screen)
		 + screen->border + Titlebar(screen), Width(screen),
		 scrollheight * FontHeight(screen));
	}
	screen->scroll_amt = 0;
	screen->refresh_amt = 0;
	if(refreshheight > 0) {
		XTileSet (VWindow(screen), screen->border, refreshtop *
		 FontHeight(screen) + screen->border + Titlebar(screen),
		 Width(screen), refreshheight * FontHeight(screen),
		 screen->bgndtile);
		ScrnRefresh(screen, refreshtop, 0, refreshheight,
		 screen->max_col + 1);
	}
}

AddToRefresh(screen)
register Screen *screen;
{
	register int amount = screen->refresh_amt;
	register int row = screen->cur_row;

	if(amount == 0 || screen->instatus)
		return(0);
	if(amount > 0) {
		register int bottom;

		if(row == (bottom = screen->bot_marg) - amount) {
			screen->refresh_amt++;
			return(1);
		}
		return(row >= bottom - amount + 1 && row <= bottom);
	} else {
		register int top;

		amount = -amount;
		if(row == (top = screen->top_marg) + amount) {
			screen->refresh_amt--;
			return(1);
		}
		return(row <= top + amount - 1 && row >= top);
	}
}

/* 
 * scrolls the screen by amount lines, erases bottom, doesn't alter 
 * cursor position (i.e. cursor moves down amount relative to text).
 * All done within the scrolling region, of course. 
 * requires: amount > 0
 */
Scroll (screen, amount)
register Screen *screen;
register int amount;
{
	register int i = screen->bot_marg - screen->top_marg + 1;
	register int shift;
	register int bot;
	register int refreshtop;
	register int refreshheight;
	register int scrolltop;
	register int scrollheight;

	if(screen->cursor_state)
		HideCursor();
	if (amount > i)
		amount = i;
    if(screen->jumpscroll) {
	if(screen->scroll_amt > 0) {
		if(screen->refresh_amt + amount > i)
			FlushScroll(screen);
		screen->scroll_amt += amount;
		screen->refresh_amt += amount;
	} else {
		if(screen->scroll_amt < 0)
			FlushScroll(screen);
		screen->scroll_amt = amount;
		screen->refresh_amt = amount;
	}
	refreshheight = 0;
    } else {

	if (amount == i) {
		ClearScreen(screen);
		return;
	}
	shift = -screen->topline;
	bot = screen->max_row - shift;
	scrollheight = i - amount;
	refreshheight = amount;
	if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
	 (i = screen->max_row - refreshheight + 1))
		refreshtop = i;
	if(screen->sb && GetSaveState(screen->sb) && screen->top_marg == 0) {
		scrolltop = 0;
		if((scrollheight += shift) > i)
			scrollheight = i;
		if((i = -GetScrollBarTop(screen->sb)) < screen->savelines) {
			if((i += amount) > screen->savelines)
				i = screen->savelines;
			SetScrollBarTop(screen->sb, -i);
			DrawScrollRegion(screen->sb);
		}
	} else {
		scrolltop = screen->top_marg + shift;
		if((i = screen->bot_marg - bot) > 0) {
			scrollheight -= i;
			if((i = screen->top_marg + amount - 1 - bot) >= 0) {
				refreshtop += i;
				refreshheight -= i;
			}
		}
	}
	if(scrollheight > 0) {
		if (screen->multiscroll
		&& amount==1 && screen->topline == 0
		&& screen->top_marg==0
		&& screen->bot_marg==screen->max_row) {
			if (screen->incopy<0 && screen->scrolls==0)
				CopyWait(screen);
			screen->scrolls++;
		} else {
			if (screen->incopy)
				CopyWait(screen);
			screen->incopy = -1;
		}

		XMoveArea(VWindow(screen), screen->border, (scrolltop+amount) *
		 FontHeight(screen) + screen->border + Titlebar(screen),
		 screen->border, scrolltop * FontHeight(screen) + screen->border
		 + Titlebar(screen), Width(screen), scrollheight *
		 FontHeight(screen));
	}
	if(refreshheight > 0) {
		XTileSet (VWindow(screen), screen->border, refreshtop *
		 FontHeight(screen) + screen->border + Titlebar(screen),
		 Width(screen), refreshheight * FontHeight(screen),
		 screen->bgndtile);
		if(refreshheight > shift)
			refreshheight = shift;
	}
    }
	if(screen->sb && GetSaveState(screen->sb) && screen->top_marg == 0)
		ScrnDeleteLine(screen->allbuf, screen->bot_marg +
		 screen->savelines, 0, amount, screen->max_col + 1);
	else
		ScrnDeleteLine(screen->buf, screen->bot_marg, screen->top_marg,
		 amount, screen->max_col + 1);
	if(refreshheight > 0)
		ScrnRefresh(screen, refreshtop, 0, refreshheight,
		 screen->max_col + 1);
}


/*
 * Reverse scrolls the screen by amount lines, erases top, doesn't alter
 * cursor position (i.e. cursor moves up amount relative to text).
 * All done within the scrolling region, of course.
 * Requires: amount > 0
 */
RevScroll(screen, amount)
register Screen *screen;
register int amount;
{
	register int i = screen->bot_marg - screen->top_marg + 1;
	register int shift;
	register int bot;
	register int refreshtop;
	register int refreshheight;
	register int scrolltop;
	register int scrollheight;

	if(screen->cursor_state)
		HideCursor();
	if (amount > i)
		amount = i;
    if(screen->jumpscroll) {
	if(screen->scroll_amt < 0) {
		if(-screen->refresh_amt + amount > i)
			FlushScroll(screen);
		screen->scroll_amt -= amount;
		screen->refresh_amt -= amount;
	} else {
		if(screen->scroll_amt > 0)
			FlushScroll(screen);
		screen->scroll_amt = -amount;
		screen->refresh_amt = -amount;
	}
    } else {
	shift = -screen->topline;
	bot = screen->max_row - shift;
	refreshheight = amount;
	scrollheight = screen->bot_marg - screen->top_marg -
	 refreshheight + 1;
	refreshtop = screen->top_marg + shift;
	scrolltop = refreshtop + refreshheight;
	if((i = screen->bot_marg - bot) > 0)
		scrollheight -= i;
	if((i = screen->top_marg + refreshheight - 1 - bot) > 0)
		refreshheight -= i;
	if(scrollheight > 0) {
		if (screen->multiscroll
		&& amount==1 && screen->topline == 0
		&& screen->top_marg==0
		&& screen->bot_marg==screen->max_row) {
			if (screen->incopy<0 && screen->scrolls==0)
				CopyWait(screen);
			screen->scrolls++;
		} else {
			if (screen->incopy)
				CopyWait(screen);
			screen->incopy = -1;
		}

		XMoveArea (VWindow(screen), screen->border, (scrolltop-amount) *
		 FontHeight(screen) + screen->border + Titlebar(screen),
		 screen->border, scrolltop * FontHeight(screen) + screen->border
		 + Titlebar(screen), Width(screen), scrollheight *
		 FontHeight(screen));
	}
	if(refreshheight > 0)
		XTileSet (VWindow(screen), screen->border, refreshtop *
		 FontHeight(screen) + screen->border + Titlebar(screen),
		 Width(screen), refreshheight * FontHeight(screen),
		 screen->bgndtile);
    }
	ScrnInsertLine (screen->buf, screen->bot_marg, screen->top_marg,
			amount, screen->max_col + 1);
}

/*
 * If cursor not in scrolling region, returns.  Else,
 * inserts n blank lines at the cursor's position.  Lines above the
 * bottom margin are lost.
 */
InsertLine (screen, n)
register Screen *screen;
register int n;
{
	register int i;
	register int shift;
	register int bot;
	register int refreshtop;
	register int refreshheight;
	register int scrolltop;
	register int scrollheight;

	if (screen->cur_row < screen->top_marg ||
	 screen->cur_row > screen->bot_marg)
		return;
	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if (n > (i = screen->bot_marg - screen->cur_row + 1))
		n = i;
    if(screen->jumpscroll) {
	if(screen->scroll_amt <= 0 &&
	 screen->cur_row <= -screen->refresh_amt) {
		if(-screen->refresh_amt + n > screen->max_row + 1)
			FlushScroll(screen);
		screen->scroll_amt -= n;
		screen->refresh_amt -= n;
	} else if(screen->scroll_amt)
		FlushScroll(screen);
    }
    if(!screen->scroll_amt) {
	shift = -screen->topline;
	bot = screen->max_row - shift;
	refreshheight = n;
	scrollheight = screen->bot_marg - screen->cur_row - refreshheight + 1;
	refreshtop = screen->cur_row + shift;
	scrolltop = refreshtop + refreshheight;
	if((i = screen->bot_marg - bot) > 0)
		scrollheight -= i;
	if((i = screen->cur_row + refreshheight - 1 - bot) > 0)
		refreshheight -= i;
	if(scrollheight > 0) {
		if (screen->incopy)
			CopyWait (screen);
		screen->incopy = -1;
		XMoveArea (VWindow(screen), screen->border, (scrolltop - n) *
		 FontHeight(screen) + screen->border + Titlebar(screen),
		 screen->border, scrolltop * FontHeight(screen) + screen->border
		 + Titlebar(screen), Width(screen), scrollheight *
		 FontHeight(screen));
	}
	if(refreshheight > 0)
		XTileSet (VWindow(screen),
		 screen->border, refreshtop * FontHeight(screen) + screen->border
		 + Titlebar(screen), Width(screen), refreshheight *
		 FontHeight(screen), screen->bgndtile);
    }
	/* adjust screen->buf */
	ScrnInsertLine(screen->buf, screen->bot_marg, screen->cur_row, n,
			screen->max_col + 1);
}

/*
 * If cursor not in scrolling region, returns.  Else, deletes n lines
 * at the cursor's position, lines added at bottom margin are blank.
 */
DeleteLine(screen, n)
register Screen *screen;
register int n;
{
	register int i;
	register int shift;
	register int bot;
	register int refreshtop;
	register int refreshheight;
	register int scrolltop;
	register int scrollheight;

	if (screen->cur_row < screen->top_marg ||
	 screen->cur_row > screen->bot_marg)
		return;
	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if (n > (i = screen->bot_marg - screen->cur_row + 1))
		n = i;
    if(screen->jumpscroll) {
	if(screen->scroll_amt >= 0 && screen->cur_row == screen->top_marg) {
		if(screen->refresh_amt + n > screen->max_row + 1)
			FlushScroll(screen);
		screen->scroll_amt += n;
		screen->refresh_amt += n;
	} else if(screen->scroll_amt)
		FlushScroll(screen);
    }
    if(!screen->scroll_amt) {

	shift = -screen->topline;
	bot = screen->max_row - shift;
	scrollheight = i - n;
	refreshheight = n;
	if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
	 (i = screen->max_row - refreshheight + 1))
		refreshtop = i;
	if(screen->sb && GetSaveState(screen->sb) && screen->cur_row == 0) {
		scrolltop = 0;
		if((scrollheight += shift) > i)
			scrollheight = i;
		if((i = -GetScrollBarTop(screen->sb)) < screen->savelines) {
			if((i += n) > screen->savelines)
				i = screen->savelines;
			SetScrollBarTop(screen->sb, -i);
			DrawScrollRegion(screen->sb);
		}
	} else {
		scrolltop = screen->cur_row + shift;
		if((i = screen->bot_marg - bot) > 0) {
			scrollheight -= i;
			if((i = screen->cur_row + n - 1 - bot) >= 0) {
				refreshheight -= i;
			}
		}
	}
	if(scrollheight > 0) {
		if (screen->incopy)
			CopyWait(screen);
		screen->incopy = -1;

		XMoveArea (VWindow(screen), screen->border, (scrolltop + n) *
		 FontHeight(screen) + screen->border + Titlebar(screen),
		 screen->border, scrolltop * FontHeight(screen) + screen->border
		 + Titlebar(screen), Width(screen), scrollheight *
		 FontHeight(screen));
	}
	if(refreshheight > 0)
		XTileSet (VWindow(screen), screen->border, refreshtop *
		 FontHeight(screen) + screen->border + Titlebar(screen),
		 Width(screen), refreshheight * FontHeight(screen),
		 screen->bgndtile);
    }
	/* adjust screen->buf */
	if(screen->sb && GetSaveState(screen->sb) && screen->cur_row == 0)
		ScrnDeleteLine(screen->allbuf, screen->bot_marg +
		 screen->savelines, 0, n, screen->max_col + 1);
	else
		ScrnDeleteLine(screen->buf, screen->bot_marg, screen->cur_row,
		 n, screen->max_col + 1);
}

/*
 * Insert n blanks at the cursor's position, no wraparound
 */
InsertChar (screen, n)
register Screen *screen;
register int n;
{
	register int width = n * FontWidth(screen), cx, cy;

	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if(screen->cur_row - screen->topline <= screen->max_row ||
	 screen->instatus) {
	    if(!AddToRefresh(screen)) {
		if(screen->scroll_amt)
			FlushScroll(screen);
	
		if (screen->incopy)
			CopyWait (screen);
		screen->incopy = -1;
	
		cx = CursorX (screen, screen->cur_col);
		cy = CursorY (screen, screen->cur_row);
		XMoveArea(VWindow(screen), cx, cy, cx + width, cy,
		     Width(screen) - (screen->cur_col + n) * FontWidth(screen),
		     FontHeight(screen));
		XPixSet(VWindow(screen), cx, cy,
		     width, FontHeight(screen), screen->instatus ?
		     screen->foreground : screen->background);
	
	    }
	}
	/* adjust screen->buf */
	ScrnInsertChar(screen->buf, screen->cur_row, screen->cur_col, n,
			screen->max_col + 1);
}

/*
 * Deletes n chars at the cursor's position, no wraparound.
 */
DeleteChar (screen, n)
register Screen *screen;
register int	n;
{
	register int width, cx, cy;

	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if (n > (width = screen->max_col + 1 - screen->cur_col))
	  	n = width;
		
	if(screen->cur_row - screen->topline <= screen->max_row ||
	 screen->instatus) {
	    if(!AddToRefresh(screen)) {
		if(screen->scroll_amt)
			FlushScroll(screen);
	
		width = n * FontWidth(screen);
	
		if (screen->incopy)
			CopyWait (screen);
		screen->incopy = -1;
	
		cx = CursorX (screen, screen->cur_col);
		cy = CursorY (screen, screen->cur_row);
		XMoveArea(VWindow(screen), cx + width, cy, cx, cy,
		     Width(screen) - (screen->cur_col + n) * FontWidth(screen),
		     FontHeight(screen));
		XPixSet (VWindow(screen),
		     screen->border + Width(screen) - width, cy,
		     width, FontHeight(screen), screen->instatus ?
		     screen->foreground : screen->background);
	
	    }
	}
	/* adjust screen->buf */
	ScrnDeleteChar (screen->buf, screen->cur_row, screen->cur_col, n,
			screen->max_col + 1);

}

/*
 * Clear from cursor position to beginning of display, inclusive.
 */
ClearAbove (screen)
register Screen *screen;
{
	register top, height;

	if(screen->cursor_state)
		HideCursor();
	if((top = -screen->topline) <= screen->max_row) {
		if(screen->scroll_amt)
			FlushScroll(screen);
		if((height = screen->cur_row + top) > screen->max_row)
			height = screen->max_row;
		if((height -= top) > 0)
			XTileSet(VWindow(screen), screen->border, top *
			 FontHeight(screen) + screen->border + Titlebar(screen),
			 Width(screen), height * FontHeight(screen),
			 screen->bgndtile);

		if(screen->cur_row - screen->topline <= screen->max_row)
			ClearLeft(screen);
	}
	ClearBufRows(screen, 0, screen->cur_row - 1);
}

/*
 * Clear from cursor position to end of display, inclusive.
 */
ClearBelow (screen)
register Screen *screen;
{
	register top;

	ClearRight(screen);
	if((top = screen->cur_row - screen->topline) <= screen->max_row) {
		if(screen->scroll_amt)
			FlushScroll(screen);
		if(++top <= screen->max_row)
			XTileSet(VWindow(screen), screen->border, top *
			 FontHeight(screen) + screen->border + Titlebar(screen),
			 Width(screen), (screen->max_row - top + 1) *
			 FontHeight(screen), screen->bgndtile);
	}
	ClearBufRows(screen, screen->cur_row + 1, screen->max_row);
}

/* 
 * Clear last part of cursor's line, inclusive.
 */
ClearRight (screen)
register Screen *screen;
{
	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if(screen->cur_row - screen->topline <= screen->max_row ||
	 screen->instatus) {
	    if(!AddToRefresh(screen)) {
		if(screen->scroll_amt)
			FlushScroll(screen);
		XPixSet(VWindow(screen),
		 CursorX(screen, screen->cur_col),
		 CursorY(screen, screen->cur_row),
		 Width(screen) - screen->cur_col * FontWidth(screen),
		 FontHeight(screen), screen->instatus ? screen->foreground :
		 screen->background);
	    }
	}
	bzero(screen->buf [2 * screen->cur_row] + screen->cur_col,
	       (screen->max_col - screen->cur_col + 1));
	bzero(screen->buf [2 * screen->cur_row + 1] + screen->cur_col,
	       (screen->max_col - screen->cur_col + 1));
}

/*
 * Clear first part of cursor's line, inclusive.
 */
ClearLeft (screen)
register Screen *screen;
{
	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if(screen->cur_row - screen->topline <= screen->max_row ||
	 screen->instatus) {
	    if(!AddToRefresh(screen)) {
		if(screen->scroll_amt)
			FlushScroll(screen);
	
		XPixSet (VWindow(screen),
		     screen->border, CursorY (screen, screen->cur_row),
		     (screen->cur_col + 1) * FontWidth(screen),
		     FontHeight(screen), screen->instatus ? screen->foreground :
		     screen->background);
	    }
	}
	bzero (screen->buf [2 * screen->cur_row], (screen->cur_col + 1));
	bzero (screen->buf [2 * screen->cur_row + 1], (screen->cur_col + 1));
}

/* 
 * Erase the cursor's line.
 */
ClearLine(screen)
register Screen *screen;
{
	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if(screen->cur_row - screen->topline <= screen->max_row ||
	 screen->instatus) {
	    if(!AddToRefresh(screen)) {
		if(screen->scroll_amt)
			FlushScroll(screen);
		XPixSet (VWindow(screen),
		     screen->border, CursorY (screen, screen->cur_row),
		     Width(screen), FontHeight(screen), screen->instatus ?
		     screen->foreground : screen->background);
	    }
	}
	bzero (screen->buf [2 * screen->cur_row], (screen->max_col + 1));
	bzero (screen->buf [2 * screen->cur_row + 1], (screen->max_col + 1));
}

ClearScreen(screen)
register Screen *screen;
{
	register int top;

	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if((top = -screen->topline) <= screen->max_row) {
		if(screen->scroll_amt)
			FlushScroll(screen);
		if(top == 0 && !screen->statusline)
			XClear(VWindow(screen));
		else
			XTileSet(VWindow(screen), screen->border, top *
			 FontHeight(screen) + screen->border + Titlebar(screen),
			 Width(screen), (screen->max_row - top + 1) *
			 FontHeight(screen), screen->bgndtile);
	}
	ClearBufRows (screen, 0, screen->max_row);
	screen->pagecnt = 0;
}

CopyWait(screen)
register Screen *screen;
{
	XEvent reply;
	XEvent *rep = &reply;

	while (1) {
		XWindowEvent (VWindow(screen), ExposeRegion|ExposeCopy, &reply);
		switch (reply.type) {
		case ExposeRegion:
			if (((XExposeEvent *)rep)->detail == ExposeCopy &&
			    screen->incopy <= 0) {
				screen->incopy = 1;
				if (screen->scrolls > 0)
					screen->scrolls--;
			}
			HandleExposure (screen, &reply);
			break;
		case ExposeCopy:
			if (screen->incopy <= 0 && screen->scrolls > 0)
				screen->scrolls--;
			if (screen->scrolls == 0) {
				screen->incopy = 0;
				return;
			}
			screen->incopy = -1;
			break;
		}
	}
}
/*
 * This routine handles exposure events
 */
HandleExposure (screen, reply)
register Screen *screen;
register XExposeEvent *reply;
{
	register int toprow, leftcol, nrows, ncols;
	extern Terminal term;	/* kludge */
	XExposeRegionEvent event;

	if((toprow = (reply->y - screen->border - Titlebar(screen)) /
	 FontHeight(screen)) < 0)
		toprow = 0;
	if((leftcol = (reply->x - screen->border) / FontWidth(screen)) < 0)
		leftcol = 0;
	nrows = (reply->y + reply->height - 1 - screen->border
	 - Titlebar(screen)) / FontHeight(screen) - toprow + 1;
	ncols = (reply->x + reply->width - 1 - screen->border) /
			FontWidth(screen) - leftcol + 1;
	toprow -= screen->scrolls;
	if (toprow < 0) {
		nrows += toprow;
		toprow = 0;
	}
	if (toprow + nrows - 1 > screen->max_row)
		nrows = screen->max_row - toprow + 1 + screen->statusline;
	if (leftcol + ncols - 1 > screen->max_col)
		ncols = screen->max_col - leftcol + 1;

	if (nrows > 0 && ncols > 0) {
		ScrnRefresh (screen, toprow, leftcol, nrows, ncols);
		if (screen->cur_row >= toprow &&
		    screen->cur_row < toprow + nrows &&
		    screen->cur_col >= leftcol &&
		    screen->cur_col < leftcol + ncols)
			return (1);
	}
	return (0);
}

ReverseVideo (term)
	Terminal *term;
{
	register Screen *screen = &term->screen;
	register Pixmap pix;
	register int tmp;
	register Window tek = TWindow(screen);
	extern Pixmap B_Pixmap;
	extern Pixmap W_Pixmap;

	if(screen->color & C_BACKGROUND)
		XFreePixmap(screen->bgndtile);
	tmp = screen->background;
	if(screen->cursorcolor == screen->foreground)
		screen->cursorcolor = tmp;
	if(screen->mousecolor == screen->foreground)
		screen->mousecolor = tmp;
	screen->background = screen->foreground;
	screen->foreground = tmp;

	screen->color = (screen->color & ~C_FBMASK) | switchfb[screen->color
	 & C_FBMASK];

	if(screen->color & C_BACKGROUND) {
		if(!(screen->bgndtile = XMakeTile(screen->background)))
			Error(ERROR_UBACK);
	} else
		screen->bgndtile = (screen->background == W_Pixel) ? W_Pixmap
		 : B_Pixmap;

	XFreeCursor(screen->curs);
	screen->curs = make_xterm(screen->mousecolor, screen->background,
	 GXcopy);
	XFreeCursor(screen->arrow);
	screen->arrow = make_arrow(screen->mousecolor, screen->background,
	 GXcopy);

	XDefineCursor(VWindow(screen), screen->curs);
	if(screen->sb)
		XDefineCursor(screen->sb->bar, screen->sb->cursor =
		 screen->arrow);
	if(screen->title.tbar)
		XDefineCursor(screen->title.tbar, screen->arrow);
	if(tek)
		XDefineCursor(tek, screen->arrow);
#ifdef MODEMENU
	MenuNewCursor(screen->arrow);
#endif MODEMENU

	if (screen->background < 2 && screen->foreground < 2) {
	    if (screen->bgndtile == B_Pixmap)
		screen->bordertile = W_Pixmap;
	    else if (screen->bgndtile == W_Pixmap)
		screen->bordertile = B_Pixmap;
	    pix = screen->bordertile;
	    if(screen->sb)
		XChangeBorder (screen->sb->bar, pix);
	    if(screen->title.tbar)
		XChangeBorder (screen->title.tbar, pix);
	    if(tek && screen->Ttitle.tbar)
		XChangeBorder (screen->Ttitle.tbar, pix);
	    if(screen->borderwidth > 0) {
		XChangeBorder (VWindow(screen), pix);
		XChangeBorder (screen->iconVwin.window, pix);
		if(tek) {
		    XChangeBorder (tek, pix);
		    XChangeBorder (screen->iconTwin.window, pix);
		}
	    }
	}

	XChangeBackground (VWindow(screen), screen->bgndtile);
	XChangeBackground (screen->iconVwin.window, screen->bgndtile);
	if(screen->title.tbar)
	    XChangeBackground (screen->title.tbar, screen->bgndtile);
	if(tek) {
	    XChangeBackground (screen->iconTwin.window, screen->bgndtile);
	    if(screen->Ttitle.tbar)
		XChangeBackground (screen->Ttitle.tbar, screen->bgndtile);
	    TekReverseVideo(screen);
	}
	XClear (VWindow(screen));
	XClear (screen->iconVwin.window);
	ScrnRefresh (screen, 0, 0, screen->max_row + 1 + screen->statusline,
	 screen->max_col + 1);
	if(screen->Tshow) {
	    XClear (tek);
	    XClear (screen->iconTwin.window);
	    TekExpose((XExposeWindowEvent *)0);
	}
	if(Titlebar(screen)) {
	    XClear(screen->title.tbar);
	    VTTitleExpose(NULL);
	    if(screen->Tshow) {
		XClear(screen->Ttitle.tbar);
		TekTitleExpose(NULL);
	    }
	}
}
RAZZLE!DAZZLE
fi	# End util.c
if test ! -d Xlib
then
	mkdir Xlib
fi
if test -f Xlib/Makefile
then
	echo shar: will not overwrite existing file "'Xlib/Makefile'"
else
echo 'x - Xlib/Makefile'
cat << \RAZZLE!DAZZLE > Xlib/Makefile
INCLUDES= -I/usr/include/X -I../../Xlib
C2= /lib/c2
#
# The KEYBD define may be include to include the keyboard mods.
CFLAGS= -O ${INCLUDES} ${NETOPTIONS} -DKEYBD

.SUFFIXES: .o .h .c

.c.o:
#	${CC} -pg ${CFLAGS} -c -S $*.c
#	${C2} $*.s | ../../inline/inline | ${AS} -o $*.o
#	rm -f $*.s
#	-ld -X -r $*.o
#	mv a.out profiled/$*.o
	${CC} ${CFLAGS} -c -S $*.c
	${C2} $*.s | ../../inline/inline | ${AS} -o $*.o
	rm -f $*.s
	-ld -x -r $*.o
	mv a.out $*.o

OLIST=	XKeyBind.o

libX.a: $(OLIST)
	ar cr libX.a $(OLIST)
	@ranlib libX.a
#
#libX_p.a: $(OLIST)
#	cd profiled; ar cr ../libX_p.a $(OLIST)
#	@ranlib libX_p.a

$(OLIST): ../../Xlib/Xlib.h

XKeyBind.o: ../../Xlib/Xkeyboard.h ../../Xlib/Xkeymap.h Xdefault.h

XGetDefault.o: Xdefault.h
RAZZLE!DAZZLE
fi	# End Xlib/Makefile
if test -f Xlib/README
then
	echo shar: will not overwrite existing file "'Xlib/README'"
else
echo 'x - Xlib/README'
cat << \RAZZLE!DAZZLE > Xlib/README
This directory contains a changes to the Xlib routines XKeyBind.c:

XKeyBind.c:	This will allow (in the future) to define keymaps with
		the environment variable KEYBD.  This is needed, for example,
		when I log into a Sun from some other workstation.  Then, on
		the Sun, I wish to pop a window back on my workstation.  Since
		the default keymap would be for the Sun, if I were on some
		other workstation, my keyboard would be messed up.  I could
		keep a .Xkeymap file on the Sun, but if I use different
		workstations to log in, sometimes it might work and other times
		it wouldn't.  If I were originally on a MicroVax and set
		my KEYBD environment variable (from the .login file) to
		mvaxII, for instance, then I would get the right keymap.  From
		another Sun, I might set KEYBD to sun3.  The names of these
		keymap files have not yet been established yet.
RAZZLE!DAZZLE
fi	# End Xlib/README
if test -f Xlib/XKeyBind.c
then
	echo shar: will not overwrite existing file "'Xlib/XKeyBind.c'"
else
echo 'x - Xlib/XKeyBind.c'
cat << \RAZZLE!DAZZLE > Xlib/XKeyBind.c
#include <X/mit-copyright.h>

/* $Header: XKeyBind.c,v 10.12 86/07/21 15:27:14 wesommer Rel $ */
/* Copyright 1985, Massachusetts Institute of Technology */

#include "XlibInternal.h"
#include <sys/file.h>
#include <sys/stat.h>
#include "Xkeymap.h"
#include "Xkeyboard.h"
#include <stdio.h>
#include <strings.h>
#ifdef KEYBD
#include "Xdefault.h"
#endif KEYBD

#define EMPTY_ENTRY LeftMask 
   /* if the "metabits" field of a runtime table entry contains this,
    it's an empty entry */

static KeyMapElt *keymap = NULL;
static Bool inited = FALSE;

static ExtensionHeader *ext_begin, *ext_end;

/* Runtime table: contains multiple-byte character bindings defined
  at runtime with XRebindCode */

typedef struct {
    unsigned char keycode;
    unsigned short metabits;
    short length;
    char *value;
    } RuntimeTableEntry;

static RuntimeTableEntry
   *rt_begin,  /* first entry of runtime table */
   *rt_end,    /* this and all succeeding entries are empty */
   *rt_buf_end;/* points beyond end of allocated storage for table */

#ifdef KEYBD
char *keyboardtype = NULL;
#endif KEYBD

#define RT_INITIAL_SIZE 100  /* initial size of runtime table */
#define RT_INCREMENT 40  /* size to grow by if expanded */

XUseKeymap(filename) 
    char *filename;
{
    int file = -1;
	int filesize;
    unsigned char magic;
    struct stat filestat;
    file = open (filename, O_RDONLY, 0);
    if (file < 0) {
    	return(0);	    /* no keymap file found */
    }
    fstat (file, &filestat);
    filesize = filestat.st_size - 1; /* first byte is magic number */
    if (filesize < 256*sizeof(KeyMapElt)) {
	fprintf (stderr, "Keymap file %s is too small\n", filename);
	close (file);
	return(0);
    }
    read (file, &magic, 1);
    if (magic != X_KEYMAP_MAGIC) {
	fprintf (stderr, 
	  "Keymap file %s doesn't begin with the proper magic number\n",
	  filename);
        close (file);
      	return(0);
    }
    keymap = (KeyMapElt *) malloc (filesize);
    if (!keymap) {
	close (file);
      	return(0);  /* couldn't malloc; just act like there isn't a keymap */
    }
    read (file, (char *) keymap, filesize);
    ext_begin = (ExtensionHeader *) (keymap + 256);
    ext_end = (ExtensionHeader *) (((char *) keymap) + filesize);
    rt_begin = (RuntimeTableEntry *) malloc (RT_INITIAL_SIZE*sizeof(RuntimeTableEntry));
    if (!rt_begin)
     	_XIOError (_XlibCurrentDisplay);
    rt_end = rt_begin;
    rt_buf_end = rt_begin + RT_INITIAL_SIZE;
    close (file);
    inited = TRUE;
    return(1);
}

static Initialize() {
    int file = -1;
    int filesize;
    unsigned char magic;
    struct stat filestat;
    char *getenv();
    char *filename = NULL;
#ifdef KEYBD
    char *home;
    char *kdefault = "default";
    char *keybddir = KEYBDDIR;
#else KEYBD
    char *home = getenv ("HOME");
#endif KEYBD

    inited = TRUE;
#ifdef KEYBD
    if(keyboardtype && *keyboardtype) {	/* Use keyboard type keymap */
	filename = malloc(strlen(keybddir) + strlen(keyboardtype) + 1);
	strcpy(filename, keybddir);
	strcat(filename, keyboardtype);
	if((file = open (filename, O_RDONLY, 0)) < 0) {
	    free (filename);
	    filename = NULL;
	}
    }
    if(file < 0 && (home = getenv ("HOME")))
#else KEYBD
    if (home)
#endif KEYBD
     {
	int homelen = strlen (home);
	char *keymapstr = "/.Xkeymap";
	int keymapstrlen = strlen (keymapstr);
	filename = malloc (homelen + keymapstrlen + 1);
	strncpy (filename, home, homelen+1);
	strncat (filename, keymapstr, keymapstrlen);
	file = open (filename, O_RDONLY, 0);
	}
#ifdef KEYBD
    if (file < 0) {	/* Try system default keymap */
	if(filename)
	    free(filename);
	filename = malloc(strlen(keybddir) + strlen(kdefault) + 1);
	strcpy(filename, keybddir);
	strcat(filename, kdefault);
	file = open (filename, O_RDONLY, 0);
    }
#endif KEYBD
    if (file < 0) {
	if(filename)
	    free(filename);
	return; /* no keymap file found */
    }
    fstat (file, &filestat);
    filesize = filestat.st_size - 1; /* first byte is magic number */
    if (filesize < 256*sizeof(KeyMapElt)) {
	fprintf (stderr, "Keymap file %s is too small\n", filename);
	close (file);
	free (filename);
	return;
	}
    read (file, &magic, 1);
    if (magic != X_KEYMAP_MAGIC) {
	fprintf (stderr, 
	  "Keymap file %s doesn't begin with the proper magic number\n",
	  filename);
        close (file);
	free (filename);
      	return;
	}
    keymap = (KeyMapElt *) malloc (filesize);
    if (!keymap) {
	close (file);
	free (filename);
      	return;  /* couldn't malloc; just act like there isn't a keymap */
	}
    read (file, (char *) keymap, filesize);
    ext_begin = (ExtensionHeader *) (keymap + 256);
    ext_end = (ExtensionHeader *) (((char *) keymap) + filesize);
    rt_begin = (RuntimeTableEntry *) malloc (RT_INITIAL_SIZE*sizeof(RuntimeTableEntry));
    if (!rt_begin)
     	_XIOError (_XlibCurrentDisplay);
    rt_end = rt_begin;
    rt_buf_end = rt_begin + RT_INITIAL_SIZE;
    free (filename);
    close (file);
    }

/* this routine is used when initialization failed to find a
   valid keymap file */
static char *BackstopLookupMapping (event, nbytes)
    XKeyPressedEvent *event;
    int *nbytes;
    {
    int detail = event->detail;
    register int keycode = detail & ValueMask;
    extern KeyMapEntry StdMap[];
    static char c;
    short s;  /* needed to distinguish a real character (e.g. \0377) from -1 */
    s = StdMap [keycode] [KeyState(detail)];
    c = s;
    if ((detail & ShiftLockMask) && (c >= 'a') && (c <= 'z'))
    	c += ('A' - 'a');
    if (IsTypewriterKey(keycode)
      || keycode == KC_ESC || keycode == KC_BS || keycode == KC_LF)
	*nbytes = (s == -1 ? 0 : 1);
    else
    	*nbytes = 0;
    return (&c);
    }

char *XLookupMapping (event, nbytes)
    XKeyPressedEvent *event;
    int *nbytes;
    {
    int detail = event->detail;
    unsigned int metabits = FullKeyState (detail);
    unsigned int key = detail & ValueMask;
    register unsigned char *the_char;

    if (!inited)
      	Initialize();
    if (!keymap)
    	return (BackstopLookupMapping (event, nbytes));

    the_char = &keymap [key] [metabits];

    switch (*the_char) {

      	case UNBOUND: {
	    *nbytes = 0;
	    return (NULL);
	    }

      	case EXTENSION_BOUND: {
	    register ExtensionHeader *this;
	    for (this = ext_begin; this < ext_end; NextExtension(this))
	        if ((key == this->keycode)
	        && ((metabits == this->metabits) || (this->metabits == DontCareMetaBits))) {
	            *nbytes = this->length;
	            return ((char *)this + ExtensionHeaderSize);
	            }
	    /* if we get here, no match was found in the table extension */
	    *nbytes = 0;
	    return (NULL);
	    }

        case RUNTIME_TABLE_BOUND: {
	    register RuntimeTableEntry *entry;
	    for (entry = rt_begin; entry < rt_end; entry++)
	        if ((key == entry->keycode)
	        && ((metabits == entry->metabits) || (entry->metabits == DontCareMetaBits))) {
		    *nbytes = entry->length;
		    return (entry->value);
		    }

	    /* if we get here, no match was found in the runtime table */
	    *nbytes = 0;
	    return (NULL);
	    }

	default: {
	    *nbytes = 1;
	    return ((char *)the_char);
	    }
      	}

    }


XRebindCode (keycode, metabits, str, nbytes)
    unsigned int keycode, metabits;
    char *str;
    int nbytes;
    {
    unsigned char *table_char;
    metabits = FullKeyState (metabits);  /* shift meta bits to rightmost four bits */
    if (!inited)
    	Initialize();
    if (!keymap)
    	return;  /* no keymap file; what else can I do? */
    table_char = &keymap [keycode] [metabits];
    if (nbytes == 0) {
	if (*table_char == RUNTIME_TABLE_BOUND)
	    Unbind (keycode, metabits);
	*table_char = UNBOUND;
	return;
	}
    if ((nbytes == 1) && SingleCharBound (*str)) {
    	if (*table_char == RUNTIME_TABLE_BOUND)
	    Unbind (keycode, metabits);
	*table_char = *str;
	return;
	}
    
    /* the new binding is either multi-character, or one of the
       three reserved special characters */

    if (*table_char == RUNTIME_TABLE_BOUND) {
	/* entry is already in table; just change its binding */
	register RuntimeTableEntry *entry;
	for (entry = rt_begin; entry < rt_end; entry++)
	    if (keycode == entry->keycode && metabits == entry->metabits) {
		entry->value = str;
		entry->length = nbytes;
		return;
		}
	/* if we get here, entry wasn't found in table; shouldn't
	 * ever happen!  Not much to do but fall through to 
	 * the following code.  */
    	}

    /* new binding must go in a new entry in the table */
    *table_char = RUNTIME_TABLE_BOUND;
    if (rt_end < rt_buf_end) {
	rt_end->keycode = keycode;
	rt_end->metabits = metabits;
	rt_end->value = str;
	rt_end++->length = nbytes;
	return;
	}

    /* no room at end of table; look for holes in middle */
    {
    register RuntimeTableEntry *entry;
    for (entry = rt_begin; entry < rt_end; entry++)
    	if (entry->metabits == EMPTY_ENTRY) {
	    entry->keycode = keycode;
	    entry->metabits = metabits;
	    entry->value = str;
	    entry->length = nbytes;
	    return;
	    }
    }

    /* no room in table at all.  Must expand it. */
    {
    int rt_length = rt_end - rt_begin;
    rt_begin = (RuntimeTableEntry *) realloc ((char *)rt_begin, (rt_length+RT_INCREMENT)*sizeof (RuntimeTableEntry));
    rt_end = rt_begin + rt_length;
    rt_buf_end = rt_end + RT_INCREMENT;
    rt_end->keycode = keycode;
    rt_end->metabits = metabits;
    rt_end->value = str;
    rt_end++->length = nbytes;
    }
    }
    

static Unbind (keycode, metabits)
    unsigned int keycode, metabits;
    {
    register RuntimeTableEntry *entry;
    for (entry = rt_begin; entry < rt_end; entry++)
    	if (keycode == entry->keycode && metabits == entry->metabits) {
	    entry->metabits = EMPTY_ENTRY;
	    return;
	    }
    }
RAZZLE!DAZZLE
fi	# End Xlib/XKeyBind.c
echo '***** End of' xterm 6.6B - Part 7 of 7 '*****'
exit