[comp.sources.games] v03i042: xchess - chess display program using X windows, Part01/06

games-request@tekred.TEK.COM (01/19/88)

Submitted by: faustus@ic.berkeley.edu (Wayne A. Christopher)
Comp.sources.games: Volume 3, Issue 42
Archive-name: xchess/Part01

	[This is a display program for chess programs (similar to
	 chesstool on the Suns).  This will work with the recently
	 posted gnuchess program, for example, on a X.10 system.
	 I have corresponded with the author and he indicated that he
	 hasn't made any recent changes and that I had his permission
	 to post it here.	-br]

#! /bin/sh

# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 6)."
# Contents:  README MANIFEST control.c parse.c scrollText
#   scrollText/Makefile scrollText/codeview.c window.c
# Wrapped by billr@tekred on Mon Jan 18 08:48:05 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(599 characters\)
sed "s/^X//" >README <<'END_OF_README'
XXchess is a chess display program which allows players to play a game on either
Xone or two displays, or play a chess-playing program.  It uses the X
Xwindow system.  If one or no display names are given, it will open up one
Xwindow and both black and white at the same board.  If two displays are
Xgiven, xchess will accept moves from each player in his turn.  Black's
Xboard will be drawn with his pieces at the bottom.  xchess will not
Xallow a player to make an illegal move.  It accepts all legal moves,
Xincluding castling and pawn capture en passant.
X
XWayne A. Christopher (faustus@ic.berkeley.edu)
END_OF_README
if test 599 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f MANIFEST -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MANIFEST\"
else
echo shar: Extracting \"MANIFEST\" \(2051 characters\)
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X COPYING                   3	
X MANIFEST                  1	
X MANIFEST.BAK              6	
X Makefile                  6	
X README                    1	
X XCircle.c                 6	
X bishop.bitmap             5	
X bishop_mask.bitmap        5	
X bishop_outline.bitmap     4	
X bishop_small.bitmap       6	
X bishop_small_outline.bitmap 6	
X board.c                   4	
X button.c                  3	
X clock.c                   4	
X control.c                 1	
X jail.c                    3	
X king.bitmap               5	
X king_mask.bitmap          5	
X king_outline.bitmap       4	
X king_small.bitmap         6	
X king_small_outline.bitmap 6	
X knight.bitmap             5	
X knight_mask.bitmap        4	
X knight_outline.bitmap     4	
X knight_small.bitmap       6	
X knight_small_outline.bitmap 6	
X message.c                 6	
X parse.c                   1	
X pawn.bitmap               5	
X pawn_mask.bitmap          5	
X pawn_outline.bitmap       4	
X pawn_small.bitmap         6	
X pawn_small_outline.bitmap 6	
X popup.c                   6	
X program.c                 6	
X queen.bitmap              5	
X queen_mask.bitmap         5	
X queen_outline.bitmap      4	
X queen_small.bitmap        6	
X queen_small_outline.bitmap 6	
X record.c                  3	
X rook.bitmap               5	
X rook_mask.bitmap          5	
X rook_outline.bitmap       4	
X rook_small.bitmap         6	
X rook_small_outline.bitmap 6	
X scrollText                1	
X scrollText/Makefile       1	
X scrollText/codeview.1     5	
X scrollText/codeview.c     1	
X scrollText/scrollText.3   3	
X scrollText/scrollText.c   2	
X scrollText/scrollText.h   6	
X scrollText/st.h           6	
X shade.bitmap              5	
X std.c                     3	
X std.h                     6	
X valid.c                   3	
X window.c                  1	
X xchess.1                  4	
X xchess.c                  4	
X xchess.cur                2	
X xchess.h                  3	
X xchess.icon               6	
X xchess_mask.cur           4	
END_OF_MANIFEST
if test 2051 -ne `wc -c <MANIFEST`; then
    echo shar: \"MANIFEST\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f control.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"control.c\"
else
echo shar: Extracting \"control.c\" \(11864 characters\)
sed "s/^X//" >control.c <<'END_OF_control.c'
X/* This file contains code for X-CHESS.
X   Copyright (C) 1986 Free Software Foundation, Inc.
X
XThis file is part of X-CHESS.
X
XX-CHESS is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY.  No author or distributor
Xaccepts responsibility to anyone for the consequences of using it
Xor for whether it serves any particular purpose or works at all,
Xunless he says so in writing.  Refer to the X-CHESS General Public
XLicense for full details.
X
XEveryone is granted permission to copy, modify and redistribute
XX-CHESS, but only under the conditions described in the
XX-CHESS General Public License.   A copy of this license is
Xsupposed to have been given to you along with X-CHESS so you
Xcan know your rights and responsibilities.  It should be in a
Xfile named COPYING.  Among other things, the copyright notice
Xand this notice must be preserved on all copies.  */
X
X
X/* RCS Info: $Revision: 1.4 $ on $Date: 86/11/23 17:17:32 $
X *           $Source: /users/faustus/xchess/RCS/control.c,v $
X * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
X *	Permission is granted to do anything with this code except sell it
X *	or remove this message.
X *
X * Deal with input from the user.
X */
X
X#include "xchess.h"
X
Xmove *moves;
Xmove *foremoves;
Xcolor nexttomove = WHITE;
Xbool noisyflag = false;
X
Xstatic move *lastmove;
Xstatic move *thismove;
X
Xstatic void screen_move();
X
Xvoid
Xbutton_pressed(event, win)
X	XEvent *event;
X	windata *win;
X{
X	int x, y;
X	XKeyOrButtonEvent *ev = (XKeyOrButtonEvent *) event;
X
X	if (!oneboard && (win->color != nexttomove)) {
X		message_add(win, "Wrong player!\n", true);
X		return;
X	}
X	if (progflag && (nexttomove == (blackflag ? WHITE : BLACK))) {
X		message_add(win, "Wait for the computer...\n", true);
X		return;
X	}
X	if (loading_flag) {
X		message_add(win, "You'd better not do that now...\n", true);
X		return;
X	}
X
X	/* Figure out what piece he is pointing at. */
X	x = ev->x / (SQUARE_WIDTH + BORDER_WIDTH);
X	y = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH);
X
X	if (win->flipped) {
X		y = SIZE - y - 1;
X		x = SIZE - x - 1;
X	}
X
X	if ((x < 0) || (x >= SIZE) || (y < 0) || (y >= SIZE)) {
X		fprintf(stderr, "Bad coords (%d, %d)\n", x, y);
X		return;
X	}
X
X	if (oneboard && (chessboard->square[y][x].color != nexttomove)) {
X		message_add(win, "Wrong player!\n", true);
X		return;
X	} else if (!oneboard && (chessboard->square[y][x].color !=
X			win->color)) {
X		message_add(win, "Can't move that\n", true);
X		return;
X	}
X
X	thismove = alloc(move);
X	thismove->fromx = x;
X	thismove->fromy = y;
X	thismove->piece.color = chessboard->square[y][x].color;
X	thismove->piece.type = chessboard->square[y][x].type;
X
X	if (debug)
X		fprintf(stderr, "%s selected his %s at (%d, %d)...\n",
X				colornames[(int) thismove->piece.color],
X				piecenames[(int) thismove->piece.type],
X				thismove->fromy, thismove->fromx);
X	return;
X}
X
Xvoid
Xbutton_released(event, win)
X	XEvent *event;
X	windata *win;
X{
X	int x, y;
X	XKeyOrButtonEvent *ev = (XKeyOrButtonEvent *) event;
X
X	if (!thismove) {
X		/* fprintf(stderr, "Error: button hasn't been pressed\n"); */
X		return;
X	}
X	if (loading_flag)
X		return;
X
X	/* Figure out what piece he is pointing at. */
X	x = ev->x / (SQUARE_WIDTH + BORDER_WIDTH);
X	y = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH);
X
X	if (win->flipped) {
X		y = SIZE - y - 1;
X		x = SIZE - x - 1;
X	}
X
X	if ((x < 0) || (x >= SIZE) || (y < 0) || (y >= SIZE)) {
X		fprintf(stderr, "Bad coords (%d, %d)\n", x, y);
X		return;
X	}
X
X	if ((thismove->fromx == x) && (thismove->fromy == y)) {
X		message_add(win, "Hey, you touch it, you move it, buddy.\n",
X				true);
X		return;
X	}
X	if (chessboard->square[y][x].color == thismove->piece.color) {
X		message_add(win, "Can't put one piece on top of another\n",
X				true);
X		return;
X	}
X
X	thismove->tox = x;
X	thismove->toy = y;
X	thismove->taken.color = chessboard->square[y][x].color;
X	thismove->taken.type = chessboard->square[y][x].type;
X	if (thismove->taken.color != NONE)
X		thismove->type = CAPTURE;
X	else if ((thismove->piece.type == KING) && (thismove->fromx == 4) &&
X			(thismove->tox == 6) &&
X			(thismove->toy == thismove->fromy))
X		thismove->type = KCASTLE;
X	else if ((thismove->piece.type == KING) && (thismove->tox == 2) &&
X			(thismove->fromx == 4) &&
X			(thismove->toy == thismove->fromy))
X		thismove->type = QCASTLE;
X	else
X		thismove->type = MOVE;
X	
X	/* Now check the en-passant case... */
X	if ((thismove->type == MOVE) && ((thismove->tox == thismove->fromx + 1)
X			|| (thismove->tox == thismove->fromx - 1)) &&
X			(thismove->piece.type == PAWN) && lastmove &&
X			(lastmove->tox == lastmove->fromx) && (lastmove->fromx
X			== thismove->tox) && ((lastmove->fromy + lastmove->toy)
X			/ 2 == thismove->toy)) {
X		thismove->type = CAPTURE;
X		thismove->enpassant = true;
X		thismove->taken = lastmove->piece;
X	}
X
X	if (!valid_move(thismove, chessboard)) {
X		message_add(win, "Invalid move.\n", true);
X		return;
X	}
X
X	if (debug)
X		fprintf(stderr, "\t... and moved it to (%d, %d), type %s\n",
X				thismove->toy, thismove->tox,
X				movetypenames[(int) thismove->type]);
X	move_piece(thismove);
X
X	if (thismove->check) {
X		message_add(win1, "Check.\n", true);
X		if (!oneboard) {
X			message_add(win2, "Check.\n", true);
X		}
X	}
X
X	if (!moves)
X		moves = lastmove = thismove;
X	else
X		lastmove = lastmove->next = thismove;
X
X	if (progflag)
X		program_send(thismove);
X
X	thismove = NULL;
X	nexttomove = ((nexttomove == WHITE) ? BLACK : WHITE);
X	clock_switch();
X
X	return;
X}
X
Xvoid
Xprog_move(m)
X	move *m;
X{
X	if (debug)
X		fprintf(stderr, "program moves from (%d, %d) to (%d, %d)\n",
X				m->fromy, m->fromx, m->toy, m->tox);
X	move_piece(m);
X
X	if (!moves)
X		moves = lastmove = m;
X	else
X		lastmove = lastmove->next = m;
X
X	nexttomove = ((nexttomove == WHITE) ? BLACK : WHITE);
X	clock_switch();
X
X	return;
X}
X
Xvoid
Xmove_piece(m)
X	move *m;
X{
X	/* Update the screen... */
X	screen_move(m);
X
X	/* Move the piece on the board... */
X	board_move(chessboard, m);
X
X	/* And record it... */
X	record_move(m);
X
X	if (noisyflag)
X		XFeep(-4);
X
X	return;
X}
X
Xstatic void
Xscreen_move(m)
X	move *m;
X{
X	piece pp;
X
X	switch (m->type) {
X	    case CAPTURE:
X		jail_add(&m->taken);
X		/* FALLTHRU */
X
X	    case MOVE:
X		win_erasepiece(m->fromy, m->fromx, WHITE);
X		if (win_flashmove)
X			win_flash(m, WHITE);
X		win_drawpiece(&m->piece, m->toy, m->tox, WHITE);
X		if (m->enpassant)
X			win_erasepiece(m->toy + ((m->piece.color == WHITE) ?
X					1 : -1), m->tox, WHITE);
X		if (!oneboard) {
X			win_erasepiece(m->fromy, m->fromx, BLACK);
X			if (win_flashmove)
X				win_flash(m, BLACK);
X			win_drawpiece(&m->piece, m->toy, m->tox, BLACK);
X			if (m->enpassant)
X				win_erasepiece(m->toy + ((m->piece.color ==
X					WHITE) ? 1 : -1), m->tox, WHITE);
X		}
X		if ((m->piece.type == PAWN) && (((m->piece.color == BLACK) &&
X				(m->toy == 7)) || ((m->piece.color == WHITE) &&
X				(m->toy == 0)))) {
X			pp.color = m->piece.color;
X			pp.type = QUEEN;
X			win_drawpiece(&pp,  m->toy, m->tox, WHITE);
X			if (!oneboard)
X				win_drawpiece(&m->piece, m->toy, m->tox, BLACK);
X		}
X		break;
X	    
X	    case KCASTLE:
X		if (m->piece.color == WHITE) {
X			win_erasepiece(7, 4, WHITE);
X			win_erasepiece(7, 7, WHITE);
X			if (win_flashmove)
X				win_flash(m, WHITE);
X			win_drawpiece(&m->piece, 7, 6, WHITE);
X			win_drawpiece(&chessboard->square[7][7], 7, 5, WHITE);
X			if (!oneboard) {
X				win_erasepiece(7, 4, BLACK);
X				win_erasepiece(7, 7, BLACK);
X				if (win_flashmove)
X					win_flash(m, BLACK);
X				win_drawpiece(&m->piece, 7, 6, BLACK);
X				win_drawpiece(&chessboard->square[7][7], 7, 5,
X						BLACK);
X			}
X		} else {
X			win_erasepiece(0, 4, WHITE);
X			win_erasepiece(0, 7, WHITE);
X			if (win_flashmove)
X				win_flash(m, WHITE);
X			win_drawpiece(&m->piece, 0, 6, WHITE);
X			win_drawpiece(&chessboard->square[0][7], 0, 5, WHITE);
X			if (!oneboard) {
X				win_erasepiece(0, 4, BLACK);
X				win_erasepiece(0, 7, BLACK);
X				if (win_flashmove)
X					win_flash(m, BLACK);
X				win_drawpiece(&m->piece, 0, 6, BLACK);
X				win_drawpiece(&chessboard->square[0][7], 0, 5,
X						BLACK);
X			}
X		}
X		break;
X
X	    case QCASTLE:
X		if (m->piece.color == WHITE) {
X			win_erasepiece(7, 4, WHITE);
X			win_erasepiece(7, 0, WHITE);
X			if (win_flashmove)
X				win_flash(m, WHITE);
X			win_drawpiece(&m->piece, 7, 2, WHITE);
X			win_drawpiece(&chessboard->square[7][0], 7, 3, WHITE);
X			if (!oneboard) {
X				win_erasepiece(7, 4, BLACK);
X				win_erasepiece(7, 0, BLACK);
X				if (win_flashmove)
X					win_flash(m, BLACK);
X				win_drawpiece(&m->piece, 7, 2, BLACK);
X				win_drawpiece(&chessboard->square[7][7], 7, 3,
X						BLACK);
X			}
X		} else {
X			win_erasepiece(0, 4, WHITE);
X			win_erasepiece(0, 0, WHITE);
X			if (win_flashmove)
X				win_flash(m, WHITE);
X			win_drawpiece(&m->piece, 0, 2, WHITE);
X			win_drawpiece(&chessboard->square[0][0], 0, 3, WHITE);
X			if (!oneboard) {
X				win_erasepiece(0, 4, BLACK);
X				win_erasepiece(0, 0, BLACK);
X				if (win_flashmove)
X					win_flash(m, BLACK);
X				win_drawpiece(&m->piece, 0, 2, BLACK);
X				win_drawpiece(&chessboard->square[0][7], 0, 3,
X						BLACK);
X			}
X		}
X		break;
X
X	    default:
X		fprintf(stderr, "Bad move type %d\n", m->type);
X	}
X	return;
X}
X
X/* Retract the last move made... */
X
Xvoid
Xreplay()
X{
X	move *m = lastmove, bm;
X
X	switch (m->type) {
X	    case MOVE:
X		bm.type = MOVE;
X		bm.piece = m->piece;
X		bm.fromx = m->tox;
X		bm.fromy = m->toy;
X		bm.tox = m->fromx;
X		bm.toy = m->fromy;
X		board_move(chessboard, &bm);
X		screen_move(&bm);
X		break;
X
X	    case CAPTURE:
X		bm.type = MOVE;
X		bm.piece = m->piece;
X		bm.fromx = m->tox;
X		bm.fromy = m->toy;
X		bm.tox = m->fromx;
X		bm.toy = m->fromy;
X		board_move(chessboard, &bm);
X		screen_move(&bm);
X		chessboard->square[m->toy][m->tox] = m->taken;
X		bm.piece = m->taken;
X		bm.fromx = bm.tox = m->tox;
X		bm.fromy = bm.toy = m->toy;
X		screen_move(&bm);
X		jail_remove(&m->taken);
X		break;
X
X	    case KCASTLE:
X		bm.type = MOVE;
X		bm.piece.type = KING;
X		bm.piece.color = m->piece.color;
X		bm.fromx = 6;
X		bm.tox = 4;
X		bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0;
X		board_move(chessboard, &bm);
X		screen_move(&bm);
X		bm.type = MOVE;
X		bm.piece.type = ROOK;
X		bm.piece.color = m->piece.color;
X		bm.fromx = 5;
X		bm.tox = 7;
X		bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0;
X		board_move(chessboard, &bm);
X		screen_move(&bm);
X		if (m->piece.color == WHITE)
X			chessboard->white_cant_castle_k = false;
X		else
X			chessboard->black_cant_castle_k = false;
X		break;
X
X	    case QCASTLE:
X		bm.type = MOVE;
X		bm.piece.type = KING;
X		bm.piece.color = m->piece.color;
X		bm.fromx = 2;
X		bm.tox = 4;
X		bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0;
X		board_move(chessboard, &bm);
X		screen_move(&bm);
X		bm.type = MOVE;
X		bm.piece.type = ROOK;
X		bm.piece.color = m->piece.color;
X		bm.fromx = 3;
X		bm.tox = 0;
X		bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0;
X		board_move(chessboard, &bm);
X		screen_move(&bm);
X		if (m->piece.color == WHITE)
X			chessboard->white_cant_castle_q = false;
X		else
X			chessboard->black_cant_castle_q = false;
X		break;
X	}
X	record_back();
X
X	nexttomove = ((nexttomove == WHITE) ? BLACK : WHITE);
X	clock_switch();
X
X	if (!moves->next) {
X		moves->next = foremoves;
X		foremoves = moves;
X		moves = lastmove = NULL;
X	} else {
X		for (m = moves; m->next; m = m->next)
X			lastmove = m;
X		lastmove->next->next = foremoves;
X		foremoves = lastmove->next;
X		lastmove->next = NULL;
X	}
X
X	if (progflag)
X		program_undo();
X
X	return;
X}
X
X/* Put back the last move undone. */
X
Xvoid
Xforward()
X{
X	prog_move(foremoves);
X	foremoves = foremoves->next;
X	return;
X}
X
X/* End the game. */
X
Xvoid
Xcleanup(s)
X	char *s;
X{
X	if (progflag)
X		program_end();
X	record_end(s);
X	XSync(0);
X	exit(0);
X}
X
Xvoid
Xrestart()
X{
X	moves = lastmove = thismove = NULL;
X	nexttomove = WHITE;
X
X	clock_init(win1, WHITE);
X	clock_init(win1, BLACK);
X	jail_init(win1);
X	if (!oneboard) {
X		clock_init(win2, WHITE);
X		clock_init(win2, BLACK);
X		jail_init(win2);
X	}
X	board_init(chessboard);
X	win_restart();
X	record_reset();
X	if (progflag) {
X		program_end();
X		program_init(progname);
X	}
X	return;
X}
X
END_OF_control.c
if test 11864 -ne `wc -c <control.c`; then
    echo shar: \"control.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f parse.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"parse.c\"
else
echo shar: Extracting \"parse.c\" \(8945 characters\)
sed "s/^X//" >parse.c <<'END_OF_parse.c'
X/* This file contains code for X-CHESS.
X   Copyright (C) 1986 Free Software Foundation, Inc.
X
XThis file is part of X-CHESS.
X
XX-CHESS is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY.  No author or distributor
Xaccepts responsibility to anyone for the consequences of using it
Xor for whether it serves any particular purpose or works at all,
Xunless he says so in writing.  Refer to the X-CHESS General Public
XLicense for full details.
X
XEveryone is granted permission to copy, modify and redistribute
XX-CHESS, but only under the conditions described in the
XX-CHESS General Public License.   A copy of this license is
Xsupposed to have been given to you along with X-CHESS so you
Xcan know your rights and responsibilities.  It should be in a
Xfile named COPYING.  Among other things, the copyright notice
Xand this notice must be preserved on all copies.  */
X
X
X/* RCS Info: $Revision: 1.2 $ on $Date: 86/11/23 17:17:59 $
X *           $Source: /users/faustus/xchess/RCS/parse.c,v $
X * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
X *	Permission is granted to do anything with this code except sell it
X *	or remove this message.
X *
X * Parse a sequence of chess moves...
X */
X
X#include "xchess.h"
X
Xbool loading_flag = false;
Xbool loading_paused = false;
X
Xstatic char *line;
X
X/* Load a record file in.  This returns a number of things -- the board, the
X * list of moves, and whose turn it is.
X */
X
Xvoid
Xload_game(file)
X	char *file;
X{
X	FILE *fp;
X	char buf[BSIZE];
X	bool eflag;
X	move *m;
X	board *tmpboard = alloc(board);
X
X	if (eq(file, "xchess.game") && saveflag) {
X		message_add(win1,
X			"Oops, I just overwrote the\nfile xchess.game...\n",
X				true);
X		message_add(win1, "I hope you had another copy.\n", true);
X		return;
X	}
X	if (!(fp = fopen(file, "r"))) {
X		perror(file);
X		return;
X	}
X
X	/* Get a few lines... */
X	fgets(buf, BSIZE, fp);
X	message_add(win1, buf, false);
X	if (!oneboard)
X		message_add(win2, buf, false);
X
X	fgets(buf, BSIZE, fp);
X	message_add(win1, buf, false);
X	if (!oneboard)
X		message_add(win2, buf, false);
X	
X	fgets(buf, BSIZE, fp);
X	if (eq(buf, "\tenglish\n"))
X		eflag = true;
X	else if (eq(buf, "\talgebraic\n"))
X		eflag = false;
X	else {
X		fprintf(stderr, "Can't decide whether this is english...\n");
X		return;
X	}
X
X	board_init(tmpboard);
X	line = NULL;
X	m = parse_file(fp, tmpboard, eflag);
X	tfree(tmpboard);
X
X	/* Now apply these moves to the board we were given... */
X	loading_flag = true;
X	while (m) {
X		if (!quickflag)
X			XSync(0);
X		win_process(true);
X		if (!quickflag)
X			sleep(1);
X		if (!loading_paused) {
X			prog_move(m);
X			m = m->next;
X		}
X	}
X	loading_flag = false;
X	if (line)
X		message_add(win1, line, false);
X
X	while (fgets(buf, BSIZE, fp))
X		message_add(win1, buf, false);
X	
X	fclose(fp);
X
X	return;
X}
X
X/* Given a starting position (usually the beginning board configuration),
X * read in a file of moves.
X */
X
Xmove *
Xparse_file(fp, b, english)
X	FILE *fp;
X	board *b;
X	bool english;
X{
X	move *mvs = NULL, *end = NULL;
X	char buf[BSIZE], *s, *t;
X	color whosemove = WHITE;
X	int c, i, j;
X
X	while (fgets(buf, BSIZE, fp)) {
X		if (*buf == '#')
X			continue;
X		s = buf;
X
X		/* The move number... */
X		if (!(t = gettok(&s)))
X			break;
X		if (!isdigit(*t)) {
X			line = copy(buf);
X			break;
X		}
X
X		if (!(t = gettok(&s)))
X			break;
X		if (end)
X			end = end->next = (english ? parse_move(b, t, WHITE) :
X					parse_imove(b, t, WHITE));
X		else
X			mvs = end = (english ? parse_move(b, t, WHITE) :
X					parse_imove(b, t, WHITE));
X		if (!end) {
X			fprintf(stderr, "Can't parse %s\n", buf);
X			return (NULL);
X		}
X		board_move(b, end);
X
X		if (!(t = gettok(&s)))
X			break;
X		if (end)
X			end = end->next = (english ? parse_move(b, t, BLACK) :
X					parse_imove(b, t, BLACK));
X		else
X			mvs = end = (english ? parse_move(b, t, BLACK) :
X					parse_imove(b, t, BLACK));
X		if (!end) {
X			fprintf(stderr, "Can't parse %s\n", buf);
X			return (NULL);
X		}
X		board_move(b, end);
X	}
X
X	return (mvs);
X}
X
X/* Parse a move.  The move format accepted is as follows -
X *	move:		spec-spec
X *	capture:	specxspec
X *	kcastle:	2 o's
X *	qcastle:	3 o's
X * A spec is either piece/pos, piece, or just pos.  A pos consists of a column
X * name followed by a row number.  If the column name is kr, kn, kb, k, q,
X * qb, qn, or qr, then the row number is according to the english system,
X * or if it is a-h then it is according to the international system.
X * 
X *** As of now the spec must include the position.
X */
X
Xmove *
Xparse_move(b, str, w)
X	board *b;
X	char *str;
X	color w;
X{
X	move *m = alloc(move);
X	char *s;
X	char spec1[16], spec2[16];
X	int i, j;
X
Xif (debug) fprintf(stderr, "parsing %s\n", str);
X
X	/* Check for castles. */
X	for (s = str, i = 0; *s; s++)
X		if ((*s == 'o') || (*s == 'O'))
X			i++;
X	if (i == 2) {
X		m->type = KCASTLE;
X		m->piece.type = KING;
X		m->piece.color = w;
X		return (m);
X	} else if (i == 3) {
X		m->type = QCASTLE;
X		m->piece.type = KING;
X		m->piece.color = w;
X		return (m);
X	}
X	if (index(str, '-'))
X		m->type = MOVE;
X	else if (index(str, 'x'))
X		m->type = CAPTURE;
X	else
X		return (NULL);
X	for (i = 0; str[i]; i++)
X		if ((str[i] == 'x') || (str[i] == '-'))
X			break;
X		else
X			spec1[i] = str[i];
X	spec1[i] = '\0';
X	for (i++, j = 0; str[i]; i++, j++)
X		if ((str[i] == 'x') || (str[i] == '-'))
X			break;
X		else
X			spec2[j] = str[i];
X	spec2[j] = '\0';
X
X	/* Now decode the specifications. */
X	s = spec1;
X	switch (*s) {
X	    case 'p': case 'P':
X		m->piece.type = PAWN; break;
X	    case 'r': case 'R':
X		m->piece.type = ROOK; break;
X	    case 'n': case 'N':
X		m->piece.type = KNIGHT; break;
X	    case 'b': case 'B':
X		m->piece.type = BISHOP; break;
X	    case 'q': case 'Q':
X		m->piece.type = QUEEN; break;
X	    case 'k': case 'K':
X		m->piece.type = KING; break;
X	    default:
X		return (NULL);
X	}
X	m->piece.color = w;
X	s += 2;
X
X	/* Now get the {q,k}{,b,n,r}n string... */
X	if ((s[0] == 'q') && (s[1] == 'r'))
X		m->fromx = 0, s += 2;
X	else if ((s[0] == 'q') && (s[1] == 'n'))
X		m->fromx = 1, s += 2;
X	else if ((s[0] == 'q') && (s[1] == 'b'))
X		m->fromx = 2, s += 2;
X	else if ((s[0] == 'q') && isdigit(s[1]))
X		m->fromx = 3, s += 1;
X	else if ((s[0] == 'k') && isdigit(s[1]))
X		m->fromx = 4, s += 1;
X	else if ((s[0] == 'k') && (s[1] == 'b'))
X		m->fromx = 5, s += 2;
X	else if ((s[0] == 'k') && (s[1] == 'n'))
X		m->fromx = 6, s += 2;
X	else if ((s[0] == 'k') && (s[1] == 'r'))
X		m->fromx = 7, s += 2;
X	m->fromy = ((w == WHITE) ? (SIZE - atoi(s)) : (atoi(s) - 1));
X
X	if ((b->square[m->fromy][m->fromx].color != w) ||
X		     (b->square[m->fromy][m->fromx].type != m->piece.type)) {
X		fprintf(stderr, "Error: bad stuff\n");
X		return (NULL);
X	}
X
X	s = spec2;
X	if (m->type == CAPTURE) {
X		switch (*s) {
X		    case 'p': case 'P':
X			m->taken.type = PAWN; break;
X		    case 'r': case 'R':
X			m->taken.type = ROOK; break;
X		    case 'n': case 'N':
X			m->taken.type = KNIGHT; break;
X		    case 'b': case 'B':
X			m->taken.type = BISHOP; break;
X		    case 'q': case 'Q':
X			m->taken.type = QUEEN; break;
X		    case 'k': case 'K':
X			m->taken.type = KING; break;
X		    default:
X			return (NULL);
X		}
X		m->taken.color = ((w == WHITE) ? BLACK : WHITE);
X		s += 2;
X	}
X
X	/* Now get the {q,k}{,b,n,r}n string... */
X	if ((s[0] == 'q') && (s[1] == 'r'))
X		m->tox = 0, s += 2;
X	else if ((s[0] == 'q') && (s[1] == 'n'))
X		m->tox = 1, s += 2;
X	else if ((s[0] == 'q') && (s[1] == 'b'))
X		m->tox = 2, s += 2;
X	else if ((s[0] == 'q') && isdigit(s[1]))
X		m->tox = 3, s += 1;
X	else if ((s[0] == 'k') && isdigit(s[1]))
X		m->tox = 4, s += 1;
X	else if ((s[0] == 'k') && (s[1] == 'b'))
X		m->tox = 5, s += 2;
X	else if ((s[0] == 'k') && (s[1] == 'n'))
X		m->tox = 6, s += 2;
X	else if ((s[0] == 'k') && (s[1] == 'r'))
X		m->tox = 7, s += 2;
X	m->toy = ((w == WHITE) ? (SIZE - atoi(s)) : (atoi(s) - 1));
X
X	if ((m->type == CAPTURE) && ((b->square[m->toy][m->tox].color !=
X			m->taken.color) || (b->square[m->toy][m->tox].type !=
X			m->taken.type))) {
X		fprintf(stderr, "Error: bad stuff\n");
X		return (NULL);
X	}
X
X	return (m);
X}
X
X/* Parse an algebraic notation move.  This is a lot easier... */
X
Xmove *
Xparse_imove(b, buf, w)
X	board *b;
X	char *buf;
X	color w;
X{
X	char *s;
X	move *m = alloc(move);
X	int n;
X
Xif (debug) fprintf(stderr, "(alg) parsing %s\n", buf);
X
X	for (s = buf, n = 0; *s; s++)
X		if ((*s == 'o') || (*s == 'O'))
X			n++;
X	s = buf;
X
X	if (n == 2)
X		m->type = KCASTLE;
X	else if (n == 3)
X		m->type = QCASTLE;
X	else {
X		m->fromx = *s++ - 'a';
X		m->fromy = SIZE - (*s++ - '0');
X		m->tox = *s++ - 'a';
X		m->toy = SIZE - (*s++ - '0');
X		m->piece = b->square[m->fromy][m->fromx];
X		m->taken = b->square[m->toy][m->tox];
X		if (m->taken.color == NONE)
X			m->type = MOVE;
X		else
X			m->type = CAPTURE;
X	}
X	if (m->piece.color != w) {
X		fprintf(stderr, "Error: parse_imove: piece of wrong color!\n");
X		return (NULL);
X	}
X	if ((m->piece.type == KING) && (m->fromy == m->toy) && (m->fromx == 4)
X			&& (m->tox == 6))
X		m->type = KCASTLE;
X	else if ((m->piece.type == KING) && (m->fromy == m->toy) &&
X			(m->fromx == 4) && (m->tox == 2))
X		m->type = QCASTLE;
X	
X	return (m);
X}
X
END_OF_parse.c
if test 8945 -ne `wc -c <parse.c`; then
    echo shar: \"parse.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test ! -d scrollText ; then
    echo shar: Creating directory \"scrollText\"
    mkdir scrollText
fi
if test -f scrollText/Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"scrollText/Makefile\"
else
echo shar: Extracting \"scrollText/Makefile\" \(294 characters\)
sed "s/^X//" >scrollText/Makefile <<'END_OF_scrollText/Makefile'
X#
X# Makefile for the scrollable text output system
X#
X
XCFLAGS = -g
X
XLIBS = libScroll.a /users/davidh/test/libCreate/libCreate.a -lX
X
X
XlibScroll.a:	scrollText.o
X	ar r libScroll.a scrollText.o
X	ranlib libScroll.a
X
Xcodeview:	codeview.o libScroll.a
X	cc $(CFLAGS) -o codeview codeview.o st.o $(LIBS)
END_OF_scrollText/Makefile
if test 294 -ne `wc -c <scrollText/Makefile`; then
    echo shar: \"scrollText/Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f scrollText/codeview.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"scrollText/codeview.c\"
else
echo shar: Extracting \"scrollText/codeview.c\" \(13042 characters\)
sed "s/^X//" >scrollText/codeview.c <<'END_OF_scrollText/codeview.c'
X/*
X * C Code Viewer for X
X *
X * David Harrison
X * University of California,  1986
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <X/Xlib.h>
X#include "st.h"
X
Xst_table *keywords = (st_table *) 0;
Xint in_comment = 0;
Xint in_string  = 0;
X
X/* Table to define which delimiters are interesting */
X#define MAXCHARS	256
Xchar specialChar[MAXCHARS];
X
Xextern int strcmp();
Xextern char *strcpy();
Xextern char *strncpy();
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X    FILE *incFile;
X    Display *theDisp;
X    Window theWin;
X    OpaqueFrame theFrame;
X    XEvent theEvent;
X    FontInfo *theFont;
X    char *dispname;
X    char *fontNames[4];
X    int colorPixels[4];
X    char *filename;
X    char *ProcessLine();
X    char linebuf[2048];
X    int index, count;
X    int bgPixel, fgPixel, curPixel, borPixel;
X
X    /* read the argument list */
X    dispname = "";
X    filename = (char *) 0;
X    fontNames[0] = "timrom12";
X    fontNames[1] = "timrom12i";
X    fontNames[2] = "timrom12b";
X    fontNames[3] = "helv12";
X    for (index = 0;  index < 4;  index++) colorPixels[index] = BlackPixel;
X    bgPixel = WhitePixel;
X    curPixel = BlackPixel;
X    borPixel = BlackPixel;
X    index = 1;
X    while (index < argc) {
X	if (argv[index][0] == '-') {
X	    /* Its an option */
X	    switch (argv[index][1]) {
X	    case 'f':
X		/* Read file into buffer */
X		filename = argv[index + 1];
X		index += 2;
X		break;
X	    default:
X		printf("Unknown option\n");
X		printf("format: %s [-f file] [host:display]\n",
X		       argv[0]);
X		exit(1);
X	    }
X	} else {
X	    /* Its the display */
X	    dispname = argv[index];
X	    index++;
X	}
X    }
X
X    theDisp = XOpenDisplay(dispname);
X    if (!theDisp) {
X	printf("Unable to open display\n");
X	exit(1);
X    }
X    readDefaults(argv[0], fontNames, colorPixels, &bgPixel, &fgPixel,
X		 &curPixel, &borPixel);
X    theFrame.bdrwidth = 2;
X    theFrame.border = XMakeTile(borPixel);
X    theFrame.background = XMakeTile(bgPixel);
X    theWin = XCreate("C Code Viewer", "codeView",
X		     "", "400x400+100+100", &theFrame, 50, 50);
X    XFreePixmap(theFrame.border);
X    XFreePixmap(theFrame.background);
X    if (!theWin) exit(1);
X    XSelectInput(theWin, ExposeRegion|ExposeCopy|ButtonReleased);
X    XMapWindow(theWin);
X
X    theFont = XOpenFont(fontNames[0]);
X    if (!TxtGrab(theWin, "codeView", theFont,
X		 bgPixel, fgPixel, curPixel)) {
X	printf("Text grab failed\n");
X	exit(1);
X    }
X    XFlush();
X
X    for (index = 0;  index < 4;  index++) {
X	if (fontNames[index]) {
X	    TxtAddFont(theWin, index, XOpenFont(fontNames[index]),
X		       colorPixels[index]);
X	}
X    }
X
X    incFile = stdin;
X    if (filename) {
X	incFile = fopen(filename, "r");
X	if (!incFile) {
X	    printf("can't read %s\n", filename);
X	    exit(1);
X	}
X    }
X
X    /* Initialize tables */
X    InitTable();
X
X    /* Jam in the text */
X    while (fgets(linebuf, 2047, incFile)) {
X	TxtJamStr(theWin, ProcessLine(linebuf));
X    }
X
X    /* Main event loop */
X    count = 0;
X    for (;;) {
X	XNextEvent(&theEvent);
X	if (!TxtFilter(&theEvent)) {
X	    switch (theEvent.type) {
X	    case ButtonReleased:
X		if ((((XButtonEvent *) &theEvent)->detail & ValueMask) ==
X		    MiddleButton)
X		  {
X		      count++;
X		      if (count > 1) {
X			  printf("done\n");
X			  exit(0);
X		      }
X		  }
X		else {
X		    XFeep(0);
X		}
X	    }
X	}
X    }
X}
X
XreadDefaults(name, fontNames, colorPixels, bg, fg, cur, bor)
Xchar *name;
Xchar *fontNames[3];
Xint colorPixels[3];
Xint *bg, *fg, *cur, *bor;
X/*
X * Reads all of the X defaults
X */
X{
X    char *value;
X    char buffer[1024];
X    Color clrdef;
X
X    value = XGetDefault(name, "Normal.Font");
X    if (value) fontNames[0] = value;
X    value = XGetDefault(name, "Comment.Font");
X    if (value) fontNames[1] = value;
X    value = XGetDefault(name, "Keyword.Font");
X    if (value) fontNames[2] = value;
X    value = XGetDefault(name, "String.Font");
X    if (value) fontNames[3] = value;
X
X    value = XGetDefault(name, "Background");
X    strcpy(buffer, value);
X    if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
X	*bg = clrdef.pixel;
X    }
X    value = XGetDefault(name, "Foreground");
X    strcpy(buffer, value);
X    if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
X	*fg = clrdef.pixel;
X	colorPixels[0] = clrdef.pixel;
X    }
X    value = XGetDefault(name, "Border");
X    strcpy(buffer, value);
X    if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
X	*bor = clrdef.pixel;
X    }
X    value = XGetDefault(name, "Cursor");
X    strcpy(buffer, value);
X    if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
X	*cur = clrdef.pixel;
X    }
X
X    value = XGetDefault(name, "Normal.Color");
X    strcpy(buffer, value);
X    if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
X	colorPixels[0] = clrdef.pixel;
X    }
X    value = XGetDefault(name, "Comment.Color");
X    strcpy(buffer, value);
X    if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
X	colorPixels[1] = clrdef.pixel;
X    }
X    value = XGetDefault(name, "Keyword.Color");
X    strcpy(buffer, value);
X    if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
X	colorPixels[2] = clrdef.pixel;
X    }
X    value = XGetDefault(name, "String.Color");
X    strcpy(buffer, value);
X    if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
X	colorPixels[3] = clrdef.pixel;
X    }
X}
X
X
XInitTable()
X/*
X * Initializes hash table of keywords and special character array
X */
X{
X    int index;
X
X    for (index = 0;  index < MAXCHARS;  index++) {
X	specialChar[index] = 0;
X    }
X    specialChar['\0'] = 1;	/* End of file */
X    specialChar[ ' '] = 1;	/* Space       */
X    specialChar['\t'] = 1;	/* Tab	       */
X    specialChar['\n'] = 1;	/* End of line */
X    specialChar[ '/'] = 1;	/* Slash       */
X    specialChar[ '*'] = 1;	/* Star        */
X    specialChar[ '"'] = 1;	/* Quote       */
X
X    keywords = st_init_table(strcmp, st_strhash);
X    st_insert(keywords, "int", (char *) 0);
X    st_insert(keywords, "char", (char *) 0);
X    st_insert(keywords, "float", (char *) 0);
X    st_insert(keywords, "double", (char *) 0);
X    st_insert(keywords, "struct", (char *) 0);
X    st_insert(keywords, "union", (char *) 0);
X    st_insert(keywords, "long", (char *) 0);
X    st_insert(keywords, "short", (char *) 0);
X    st_insert(keywords, "unsigned", (char *) 0);
X    st_insert(keywords, "auto", (char *) 0);
X    st_insert(keywords, "extern", (char *) 0);
X    st_insert(keywords, "register", (char *) 0);
X    st_insert(keywords, "typedef", (char *) 0);
X    st_insert(keywords, "static", (char *) 0);
X    st_insert(keywords, "goto", (char *) 0);
X    st_insert(keywords, "return", (char *) 0);
X    st_insert(keywords, "sizeof", (char *) 0);
X    st_insert(keywords, "break", (char *) 0);
X    st_insert(keywords, "continue", (char *) 0);
X    st_insert(keywords, "if", (char *) 0);
X    st_insert(keywords, "else", (char *) 0);
X    st_insert(keywords, "for", (char *) 0);
X    st_insert(keywords, "do", (char *) 0);
X    st_insert(keywords, "while", (char *) 0);
X    st_insert(keywords, "switch", (char *) 0);
X    st_insert(keywords, "case", (char *) 0);
X    st_insert(keywords, "default", (char *) 0);
X    st_insert(keywords, "entry", (char *) 0);
X}
X
X
X#define SPACE		1
X#define TAB		2
X#define COMBEGIN	3
X#define COMEND		4
X#define IDENT		5
X#define USRIDENT	6
X#define STR		7
X#define OTHER		8
X#define ENDLINE		9
X
Xchar *ProcessLine(someline)
Xchar *someline;
X/*
X * This routine takes a line,  expands out its tabs into spaces
X * italicizes comments and boldfaces keywords.
X */
X{
X    static char outbuf[2048];
X    int start, len, token, outspot, index, target;
X
X    /* Reinitializes the token generator */
X    get_token((char *) 0, (int *) 0, (int *) 0, (int *) 0);
X    outspot = 0;
X
X    while (get_token(someline, &start, &len, &token)) {
X#ifdef
Xprint_token(someline, start, len, token);
X#endif
X	switch (token) {
X	case SPACE:
X	    for (index = 0;  index < len;  index++) {
X		outbuf[outspot] = ' ';
X		outspot++;
X	    }
X	    break;
X	case TAB:
X	    /* Expand out using spaces */
X	    target = ((outspot / 8) + 1) * 8;
X	    for (index = outspot;  index < target;  index++) {
X		outbuf[index] = ' ';
X		outspot++;
X	    }
X	    break;
X	case COMBEGIN:
X	    /* Put it in and then change fonts */
X	    if (!in_string) {
X		outbuf[outspot++] = '\006';
X		outbuf[outspot++] = '1';
X		in_comment = 1;
X	    }
X	    outbuf[outspot++] = '/';
X	    outbuf[outspot++] = '*';
X	    break;
X	case COMEND:
X	    /* Change font back to normal and output */
X	    outbuf[outspot++] = '*';
X	    outbuf[outspot++] = '/';
X	    if (!in_string) {
X		outbuf[outspot++] = '\006';
X		outbuf[outspot++] = '0';
X		in_comment = 0;
X	    }
X	    break;
X	case STR:
X	    if (in_comment) {
X		outbuf[outspot++] = '"';
X	    } else {
X		if (in_string) {
X		    /* Change font back to normal and output */
X		    outbuf[outspot++] = '"';
X		    outbuf[outspot++] = '\006';
X		    outbuf[outspot++] = '0';
X		    in_string = 0;
X		} else {
X		    /* Put in string mode and change fonts */
X		    outbuf[outspot++] = '\006';
X		    outbuf[outspot++] = '3';
X		    outbuf[outspot++] = '"';
X		    in_string = 1;
X		}
X	    }
X	    break;
X	case IDENT:
X	    /* Output in boldface if not in comment */
X	    if (!(in_comment || in_string)) {
X		outbuf[outspot++] = '\006';
X		outbuf[outspot++] = '2';
X	    }
X	    for (index = 0;  index < len;  index++) {
X		outbuf[outspot++] = someline[start+index];
X	    }
X	    if (!(in_comment || in_string)) {
X		outbuf[outspot++] = '\006';
X		outbuf[outspot++] = '0';
X	    }
X	    break;
X	case USRIDENT:
X	case OTHER:
X	    /* Simply output */
X	    for (index = 0;  index < len;  index++) {
X		outbuf[outspot++] = someline[start+index];
X	    }
X	    break;
X	case ENDLINE:
X	    /* Output it */
X	    outbuf[outspot++] = '\n';
X	    break;
X	}
X    }
X    outbuf[outspot] = '\0';
X    return outbuf;
X}
X
X
X
X
X/* Macro to find special delimiters - see table initialization in main */
X#define isspecial(c)	(specialChar[c])
X
X/* Macro to ram don't care delimiters into an OTHER token */
X#define EATDELIM \
X  while (!isalnum(line[pos]) && !isspecial(line[pos])) pos++; \
X  *len = pos - *start; \
X  *token = OTHER;
X
Xint get_token(line, start, len, token)
Xchar *line;
Xint *start, *len, *token;
X/*
X * Reads a token from 'line'.  If all are zero,  resets the lexing
X * system.
X */
X{
X    static int pos;
X    static char ident[2048];
X    char *item;
X
X    if ((line == 0) && (start == 0) && (len == 0) && (token == 0)) {
X	pos = 0;
X	return 0;
X    }
X
X    *start = pos;
X    if (isspecial(line[pos])) {
X	/* One of the special punctuation characters */
X	if (line[pos] == '\0') {
X	    return 0;
X	} else if (line[pos] == '\t') {
X	    /* Generate a tab token */
X	    pos++;
X	    *len = 1;
X	    *token = TAB;
X	} else if (line[pos] == '\n') {
X	    /* End of line */
X	    *len = 1;
X	    *token = ENDLINE;
X	    pos++;
X	} else if (line[pos] == ' ') {
X	    /* Generate a space token */
X	    while (line[pos] == ' ') pos++;
X	    *len = pos - *start;
X	    *token = SPACE;
X	} else if (line[pos] == '/') {
X	    /* Possible beginning of comment */
X	    if (line[++pos] == '*') {
X		/* Start of comment */
X		*len = 2;
X		*token = COMBEGIN;
X		pos++;
X	    } else {
X		/* Something else */
X		EATDELIM;
X	    }
X	} else if (line[pos] == '*') {
X	    /* Could be an end to a comment */
X	    if (line[++pos] == '/') {
X		/* End of a comment */
X		*len = 2;
X		*token = COMEND;
X		pos++;
X	    } else {
X		/* Something else */
X		EATDELIM;
X	    }
X	} else if (line[pos] == '"') {
X	    /* Possible start or end of string */
X	    if ((pos == 0) ||
X		(((line[pos-1] == '\'') ? (line[pos+1] != '\'') : 1)
X		 && (line[pos] != '\\')))
X	      {
X		  *len = 1;
X		  *token = STR;
X		  pos++;
X	      } else {
X		  /* Something else */
X		  pos++;
X		  EATDELIM;
X	      }
X	}
X    } else if (isalnum(line[pos])) {
X	/* Go get an identifier */
X	do pos++; while (isalnum(line[pos]));
X	*len = pos - *start;
X	strncpy(ident, &(line[*start]), *len);
X	ident[*len] = '\0';
X	/* Try to look it up */
X	if (st_lookup(keywords, ident, &item)) {
X	    *token = IDENT;
X	} else {
X	    *token = USRIDENT;
X	}
X    } else {
X	/* Random delimiters */
X	pos++;
X	EATDELIM;
X    }
X    return 1;
X}
X
X
X/* Debugging */
X
Xprint_token(someline, start, len, token)
Xchar *someline;
Xint start, len, token;
X/* Prints out a token */
X{
X    char buffer[1024];
X    int index;
X
X    switch (token) {
X    case SPACE:
X	printf("space\n");
X	break;
X    case TAB:
X	printf("tab\n");
X	break;
X	/*
X	 * We try to break it by doing this
X	 * many times over.
X	 */
X    case COMBEGIN:
X	printf("start comment\n");
X	break;
X    case COMEND:
X	printf("end comment\n");
X	break;
X    case STR:
X	printf("string\n");
X	break;
X    case IDENT:
X	printf("identifier: '");
X	for (index = start;  index < start+len;  index++) {
X	    putchar(someline[index]);
X	}
X	printf("'\n");
X	break;
X    case USRIDENT:
X	printf("user identifier: '");
X	for (index = start;  index < start+len;  index++) {
X	    putchar(someline[index]);
X	}
X	printf("'\n");
X	break;
X    case OTHER:
X	printf("delimiters: I");
X	for (index = start;  index < start+len;  index++) {
X	    putchar(someline[index]);
X	}
X	printf("I\n");
X	break;
X    }
X}
END_OF_scrollText/codeview.c
if test 13042 -ne `wc -c <scrollText/codeview.c`; then
    echo shar: \"scrollText/codeview.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f window.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"window.c\"
else
echo shar: Extracting \"window.c\" \(18431 characters\)
sed "s/^X//" >window.c <<'END_OF_window.c'
X/* This file contains code for X-CHESS.
X   Copyright (C) 1986 Free Software Foundation, Inc.
X
XThis file is part of X-CHESS.
X
XX-CHESS is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY.  No author or distributor
Xaccepts responsibility to anyone for the consequences of using it
Xor for whether it serves any particular purpose or works at all,
Xunless he says so in writing.  Refer to the X-CHESS General Public
XLicense for full details.
X
XEveryone is granted permission to copy, modify and redistribute
XX-CHESS, but only under the conditions described in the
XX-CHESS General Public License.   A copy of this license is
Xsupposed to have been given to you along with X-CHESS so you
Xcan know your rights and responsibilities.  It should be in a
Xfile named COPYING.  Among other things, the copyright notice
Xand this notice must be preserved on all copies.  */
X
X
X/* RCS Info: $Revision: 1.5 $ on $Date: 86/11/26 12:11:15 $
X *           $Source: /users/faustus/xchess/RCS/window.c,v $
X * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
X *	Permission is granted to do anything with this code except sell it
X *	or remove this message.
X *
X * Deal with the two (or one) windows.
X */
X
X#include "xchess.h"
X#include <sys/time.h>
X
X#include "pawn.bitmap"
X#include "rook.bitmap"
X#include "knight.bitmap"
X#include "bishop.bitmap"
X#include "queen.bitmap"
X#include "king.bitmap"
X
X#include "pawn_outline.bitmap"
X#include "rook_outline.bitmap"
X#include "knight_outline.bitmap"
X#include "bishop_outline.bitmap"
X#include "queen_outline.bitmap"
X#include "king_outline.bitmap"
X
X#include "pawn_mask.bitmap"
X#include "rook_mask.bitmap"
X#include "knight_mask.bitmap"
X#include "bishop_mask.bitmap"
X#include "queen_mask.bitmap"
X#include "king_mask.bitmap"
X
X#include "shade.bitmap"
X
X#include "xchess.cur"
X#include "xchess_mask.cur"
X
X#include "xchess.icon"
X
Xwindata *win1, *win2;
Xbool win_flashmove = false;
X
Xextern bool setup();
Xextern void service(), drawgrid(), icon_refresh();
X
Xbool
Xwin_setup(disp1, disp2)
X	char *disp1, *disp2;
X{
X	win1 = alloc(windata);
X	if (!oneboard)
X		win2 = alloc(windata);
X
X	if (!setup(disp1, win1) || (!oneboard && !setup(disp2, win2)))
X		return (false);
X
X	if (blackflag) {
X		win1->color = BLACK;
X		win1->flipped = true;
X	} else
X		win1->color = WHITE;
X	win_drawboard(win1);
X
X	if (!oneboard) {
X		win2->color = BLACK;
X		win2->flipped = true;
X		win_drawboard(win2);
X	}
X	
X	return(true);
X}
X
X/* Draw the chess board... */
X
Xvoid
Xwin_drawboard(win)
X	windata *win;
X{
X	int i, j;
X
X	XSetDisplay(win->display);
X
X	drawgrid(win);
X
X	/* Now toss on the squares... */
X	for (i = 0; i < SIZE; i++)
X		for (j = 0; j < SIZE; j++)
X			win_erasepiece(j, i, win->color);
X
X	return;
X}
X
X/* Draw one piece. */
X
Xvoid
Xwin_drawpiece(p, y, x, wnum)
X	piece *p;
X	int y, x;
X	color wnum;
X{
X	short *bits, *maskbits, *outline;
X	windata *win;
X	Bitmap mask;
X	char buf[BSIZE];
X
X	if (oneboard || (wnum == win1->color))
X		win = win1;
X	else
X		win = win2;
X
X	XSetDisplay(win->display);
X
X	if (win->flipped) {
X		y = SIZE - y - 1;
X		x = SIZE - x - 1;
X	}
X
X	/*
X	if (debug)
X		fprintf(stderr, "draw a %s at (%d, %d) on board %d\n",
X				piecenames[(int) p->type], y, x, wnum);
X	 */
X
Xif ((x < 0) || (x > 7) || (y < 0) || (y > 7)) exit(1);
X
X	switch (p->type) {
X	    case PAWN:
X		bits = pawn_bits;
X		maskbits = pawn_mask_bits;
X		outline = pawn_outline_bits;
X		break;
X
X	    case ROOK:
X		bits = rook_bits;
X		maskbits = rook_mask_bits;
X		outline = rook_outline_bits;
X		break;
X
X	    case KNIGHT:
X		bits = knight_bits;
X		maskbits = knight_mask_bits;
X		outline = knight_outline_bits;
X		break;
X
X	    case BISHOP:
X		bits = bishop_bits;
X		maskbits = bishop_mask_bits;
X		outline = bishop_outline_bits;
X		break;
X
X	    case QUEEN:
X		bits = queen_bits;
X		maskbits = queen_mask_bits;
X		outline = queen_outline_bits;
X		break;
X
X	    case KING:
X		bits = king_bits;
X		maskbits = king_mask_bits;
X		outline = king_outline_bits;
X		break;
X
X	    default:
X		fprintf(stderr,
X			"Internal Error: win_drawpiece: bad piece type %d\n",
X			p->type);
X	}
X
X	/* There are two things we can do... If this is a black and white
X	 * display, we have to shade the square and use an outline if the piece
X	 * is white.  We also have to use a mask...  Since we don't want
X	 * to use up too many bitmaps, create the mask bitmap, put the bits,
X	 * and then destroy it.
X	 */
X	if (win->bnw && (p->color == WHITE))
X		bits = outline;
X	if (win->bnw && !iswhite(win, x, y)) {
X		XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
X			y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
X			SQUARE_HEIGHT, shade_bits, BlackPixel, WhitePixel,
X			0, GXcopy, AllPlanes);
X		mask = XStoreBitmap(SQUARE_WIDTH, SQUARE_HEIGHT, maskbits);
X		XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
X			y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
X			SQUARE_HEIGHT, bits, BlackPixel, WhitePixel,
X			mask, GXcopy, AllPlanes);
X		XFreeBitmap(mask);
X	} else if (win->bnw){
X		XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
X			y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
X			SQUARE_HEIGHT, bits, BlackPixel, WhitePixel,
X			0, GXcopy, AllPlanes);
X	} else {
X		XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
X			y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
X			SQUARE_HEIGHT, bits, ((p->color == WHITE) ?
X			win->whitepiece.pixel : win->blackpiece.pixel),
X			(iswhite(win, x, y) ? win->whitesquare.pixel :
X			win->blacksquare.pixel), 0, GXcopy, AllPlanes);
X	}
X
X	if (!record_english) {
X		if (!x) {
X			sprintf(buf, " %d", SIZE - y);
X			XText(win->boardwin, 1, (y + 1) * (SQUARE_HEIGHT + 
X					BORDER_WIDTH) - BORDER_WIDTH - 
X					win->small->height - 1, buf, 2,
X					win->small->id, win->textcolor.pixel, 
X					((iswhite(win, x, y) || win->bnw) ?
X					win->whitesquare.pixel : 
X					win->blacksquare.pixel));
X		}
X		if (y == SIZE - 1) {
X			sprintf(buf, "%c", 'A' + x);
X			XText(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH)
X					+ 1, SIZE * (SQUARE_HEIGHT + 
X					BORDER_WIDTH) - BORDER_WIDTH - 
X					win->small->height - 1, buf, 1,
X					win->small->id, win->textcolor.pixel,
X					((iswhite(win, x, y) || win->bnw) ? 
X					win->whitesquare.pixel : 
X					win->blacksquare.pixel));
X		}
X	}
X	return;
X}
X
Xvoid
Xwin_erasepiece(y, x, wnum)
X	int y, x;
X	color wnum;
X{
X	windata *win;
X	char buf[BSIZE];
X
X	if (oneboard || (wnum == win1->color))
X		win = win1;
X	else
X		win = win2;
X		
X	XSetDisplay(win->display);
X
X	if (win->flipped) {
X		y = SIZE - y - 1;
X		x = SIZE - x - 1;
X	}
X
X	/*
X	if (debug)
X		fprintf(stderr, "erase square (%d, %d) on board %d\n", y, x,
X				wnum);
X	 */
X
Xif ((x < 0) || (x > 7) || (y < 0) || (y > 7)) exit(1);
X
X	if (win->bnw && !iswhite(win, x, y)) {
X		XBitmapBitsPut(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
X			y * (SQUARE_HEIGHT + BORDER_WIDTH), SQUARE_WIDTH,
X			SQUARE_HEIGHT, shade_bits, BlackPixel, WhitePixel,
X			0, GXcopy, AllPlanes);
X	} else {
X		XPixSet(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH),
X				y * (SQUARE_HEIGHT + BORDER_WIDTH),
X				SQUARE_WIDTH, SQUARE_HEIGHT, iswhite(win, x, y)
X				? win->whitesquare.pixel :
X				win->blacksquare.pixel);
X	}
X
X	if (!record_english) {
X		if (!x) {
X			sprintf(buf, " %d", SIZE - y);
X			XText(win->boardwin, 1, (y + 1) * (SQUARE_HEIGHT + 
X					BORDER_WIDTH) - BORDER_WIDTH - 
X					win->small->height - 1, buf, 2,
X					win->small->id, win->textcolor.pixel, 
X					((iswhite(win, x, y) || win->bnw) ? 
X					win->whitesquare.pixel : 
X					win->blacksquare.pixel));
X		}
X		if (y == SIZE - 1) {
X			sprintf(buf, "%c", 'A' + x);
X			XText(win->boardwin, x * (SQUARE_WIDTH + BORDER_WIDTH)
X					+ 1, SIZE * (SQUARE_HEIGHT + 
X					BORDER_WIDTH) - BORDER_WIDTH - 
X					win->small->height - 1, buf, 1,
X					win->small->id, win->textcolor.pixel,
X					((iswhite(win, x, y) || win->bnw) ? 
X					win->whitesquare.pixel : 
X					win->blacksquare.pixel));
X		}
X	}
X
X	return;
X}
X
Xvoid
Xwin_flash(m, wnum)
X	move *m;
X	color wnum;
X{
X	windata *win;
X	int sx, sy, ex, ey, i;
X
X	if (oneboard || (wnum == win1->color))
X		win = win1;
X	else
X		win = win2;
X		
X	XSetDisplay(win->display);
X
X	if (win->flipped) {
X		sx = SIZE - m->fromx - 1;
X		sy = SIZE - m->fromy - 1;
X		ex = SIZE - m->tox - 1;
X		ey = SIZE - m->toy - 1;
X	} else {
X		sx = m->fromx;
X		sy = m->fromy;
X		ex = m->tox;
X		ey = m->toy;
X	}
X	sx = sx * (SQUARE_WIDTH + BORDER_WIDTH) + SQUARE_WIDTH / 2;
X	sy = sy * (SQUARE_HEIGHT + BORDER_WIDTH) + SQUARE_HEIGHT / 2;
X	ex = ex * (SQUARE_WIDTH + BORDER_WIDTH) + SQUARE_WIDTH / 2;
X	ey = ey * (SQUARE_HEIGHT + BORDER_WIDTH) + SQUARE_HEIGHT / 2;
X
X	for (i = 0; i < num_flashes * 2; i++)
X		XLine(win->boardwin, sx, sy, ex, ey, flash_size, flash_size,
X				BlackPixel, GXinvert, AllPlanes);
X	return;
X}
X
X/* Handle input from the players. */
X
Xvoid
Xwin_process(quick)
X	bool quick;
X{
X	int i, rfd = 0, wfd = 0, xfd = 0;
X	struct timeval timeout;
X
X	timeout.tv_sec = 0;
X	timeout.tv_usec = (quick ? 0 : 500000);
X
X	XSetDisplay(win1->display);
X	if (XPending())
X		service(win1);
X	if (!oneboard) {
X		XSetDisplay(win2->display);
X		if (XPending())
X			service(win2);
X	}
X
X	if (oneboard)
X		rfd = 1 << win1->display->fd;
X	else
X		rfd = (1 << win1->display->fd) | (1 << win2->display->fd);
X	if (!(i = select(32, &rfd, &wfd, &xfd, &timeout)))
X		return;
X	if (i == -1) {
X		perror("select");
X		exit(1);
X	}
X	if (rfd & (1 << win1->display->fd))
X		service(win1);
X	if (!oneboard && (rfd & (1 << win2->display->fd)))
X		service(win2);
X
X	return;
X}
X
Xstatic void
Xservice(win)
X	windata *win;
X{
X	XEvent ev;
X
X	XSetDisplay(win->display);
X
X	while(XPending()) {
X		XNextEvent(&ev);
X		if (TxtFilter(&ev))
X			continue;
X
X		if (ev.window == win->boardwin) {
X			switch (ev.type) {
X			    case ButtonPressed:
X				button_pressed(&ev, win);
X				break;
X
X			    case ButtonReleased:
X				button_released(&ev, win);
X				break;
X
X			    case ExposeRegion:
X			    case ExposeWindow:
X				/* Redraw... */
X				win_redraw(win, &ev);
X				break;
X
X			    case 0:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.window == win->wclockwin) {
X			switch (ev.type) {
X			    case ExposeRegion:
X			    case ExposeWindow:
X				clock_draw(win, WHITE);
X				break;
X
X			    case 0:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.window == win->bclockwin) {
X			switch (ev.type) {
X			    case ExposeRegion:
X			    case ExposeWindow:
X				clock_draw(win, BLACK);
X				break;
X
X			    case 0:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.window == win->jailwin) {
X			switch (ev.type) {
X			    case ExposeRegion:
X			    case ExposeWindow:
X				jail_draw(win);
X				break;
X
X			    case 0:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.window == win->buttonwin) {
X			switch (ev.type) {
X			    case ButtonPressed:
X				button_service(win, &ev);
X				break;
X
X			    case ExposeRegion:
X			    case ExposeWindow:
X				button_draw(win, &ev);
X				break;
X
X			    case 0:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.window == win->icon) {
X			icon_refresh(win);
X		} else if (ev.window == win->basewin) {
X			message_send(win, &ev);
X		} else {
X			fprintf(stderr, "Internal Error: service: bad win\n");
X			fprintf(stderr, "window = %d, event = %d\n", ev.window,
X					ev.type);
X		}
X	}
X	return;
X}
X
Xvoid
Xwin_redraw(win, event)
X	windata *win;
X	XEvent *event;
X{
X	XExposeEvent *ev = (XExposeEvent *) event;
X	int x1, y1, x2, y2, i, j;
X
X	drawgrid(win);
X	if (ev) {
X		x1 = ev->x / (SQUARE_WIDTH + BORDER_WIDTH);
X		y1 = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH);
X		x2 = (ev->x + ev->width) / (SQUARE_WIDTH + BORDER_WIDTH);
X		y2 = (ev->y + ev->height) / (SQUARE_HEIGHT + BORDER_WIDTH);
X	} else {
X		x1 = 0;
X		y1 = 0;
X		x2 = SIZE - 1;
X		y2 = SIZE - 1;
X	}
X
X	if (x1 < 0) x1 = 0;
X	if (y1 < 0) y1 = 0;
X	if (x2 < 0) x2 = 0;
X	if (y2 < 0) y2 = 0;
X	if (x1 > SIZE - 1) x1 = SIZE - 1;
X	if (y1 > SIZE - 1) y1 = SIZE - 1;
X	if (x2 > SIZE - 1) x2 = SIZE - 1;
X	if (y2 > SIZE - 1) y2 = SIZE - 1;
X
X	if (win->flipped) {
X		y1 = SIZE - y2 - 1;
X		y2 = SIZE - y1 - 1;
X		x1 = SIZE - x2 - 1;
X		x2 = SIZE - x1 - 1;
X	}
X
X	for (i = x1; i <= x2; i++) 
X		for (j = y1; j <= y2; j++) {
X			if (chessboard->square[j][i].color == NONE)
X				win_erasepiece(j, i, WHITE);
X			else
X				win_drawpiece(&chessboard->square[j][i], j, i,
X						WHITE);
X			if (!oneboard) {
X				if (chessboard->square[j][i].color == NONE)
X					win_erasepiece(j, i, BLACK);
X				else
X					win_drawpiece(&chessboard->square[j][i],
X							j, i, BLACK);
X			}
X		}
X	
X	return;
X}
X
Xstatic bool
Xsetup(dispname, win)
X	char *dispname;
X	windata *win;
X{
X	Pixmap btile, ttile;
X	char buf[BSIZE];
X	Bitmap bm;
X	Cursor cur;
X
X	if (!(win->display = XOpenDisplay(dispname)))
X		return (false);
X	
X	if ((DisplayPlanes() == 1) || bnwflag)
X		win->bnw = true;
X	
X	/* Allocate colors... */
X	if (win->bnw) {
X		win->blackpiece.pixel = BlackPixel;
X		win->whitepiece.pixel = WhitePixel;
X		win->blacksquare.pixel = BlackPixel;
X		win->whitesquare.pixel = WhitePixel;
X		win->border.pixel = BlackPixel;
X		win->textcolor.pixel = BlackPixel;
X		win->textback.pixel = WhitePixel;
X		win->playertext.pixel = BlackPixel;
X		win->errortext.pixel = BlackPixel;
X		win->cursorcolor.pixel = BlackPixel;
X	} else {
X		if (!XParseColor(black_piece_color, &win->blackpiece) ||
X		    !XParseColor(white_piece_color, &win->whitepiece) ||
X		    !XParseColor(black_square_color, &win->blacksquare) ||
X		    !XParseColor(white_square_color, &win->whitesquare) ||
X		    !XParseColor(border_color, &win->border) ||
X		    !XParseColor(text_color, &win->textcolor) ||
X		    !XParseColor(text_back, &win->textback) ||
X		    !XParseColor(error_text, &win->errortext) ||
X		    !XParseColor(player_text, &win->playertext) ||
X		    !XParseColor(cursor_color, &win->cursorcolor) ||
X		    !XGetHardwareColor(&win->blackpiece) ||
X		    !XGetHardwareColor(&win->whitepiece) ||
X		    !XGetHardwareColor(&win->blacksquare) ||
X		    !XGetHardwareColor(&win->whitesquare) ||
X		    !XGetHardwareColor(&win->border) ||
X		    !XGetHardwareColor(&win->textcolor) ||
X		    !XGetHardwareColor(&win->textback) ||
X		    !XGetHardwareColor(&win->errortext) ||
X		    !XGetHardwareColor(&win->playertext) ||
X		    !XGetHardwareColor(&win->cursorcolor))
X			fprintf(stderr, "Can't get color...\n");
X	}
X
X	/* Get fonts... */
X	win->small = XOpenFont(SMALL_FONT);
X	win->medium = XOpenFont(MEDIUM_FONT);
X	win->large = XOpenFont(LARGE_FONT);
X	
X	/* Create the windows... */
X
X	btile = XMakeTile(win->border.pixel);
X	ttile = XMakeTile(win->textback.pixel);
X	win->basewin = XCreateWindow(RootWindow, BASE_XPOS, BASE_YPOS,
X			BASE_WIDTH, BASE_HEIGHT, 0, WhitePixmap, WhitePixmap);
X	win->boardwin = XCreateWindow(win->basewin, BOARD_XPOS, BOARD_YPOS,
X			BOARD_WIDTH, BOARD_HEIGHT, BORDER_WIDTH, btile,
X			WhitePixmap);
X	win->recwin = XCreateWindow(win->basewin, RECORD_XPOS, RECORD_YPOS,
X			RECORD_WIDTH, RECORD_HEIGHT, BORDER_WIDTH,
X			btile, ttile);
X	win->jailwin = XCreateWindow(win->basewin, JAIL_XPOS, JAIL_YPOS,
X			JAIL_WIDTH, JAIL_HEIGHT, BORDER_WIDTH,
X			btile, ttile);
X	win->wclockwin = XCreateWindow(win->basewin, WCLOCK_XPOS, WCLOCK_YPOS,
X			CLOCK_WIDTH, CLOCK_HEIGHT, BORDER_WIDTH, btile,
X			ttile);
X	win->bclockwin = XCreateWindow(win->basewin, BCLOCK_XPOS, BCLOCK_YPOS,
X			CLOCK_WIDTH, CLOCK_HEIGHT, BORDER_WIDTH, btile,
X			ttile);
X	win->messagewin = XCreateWindow(win->basewin, MESS_XPOS, MESS_YPOS,
X			MESS_WIDTH, MESS_HEIGHT, BORDER_WIDTH, btile, ttile);
X	win->buttonwin = XCreateWindow(win->basewin, BUTTON_XPOS, BUTTON_YPOS,
X			BUTTON_WIDTH, BUTTON_HEIGHT, BORDER_WIDTH, btile,
X			ttile);
X	
X	/* Let's define an icon... */
X	bm = XStoreBitmap(icon_width, icon_height, icon_bits);
X	win->iconpixmap = XMakePixmap(bm, win->blacksquare.pixel,
X			win->whitesquare.pixel);
X	win->icon = XCreateWindow(RootWindow, BASE_XPOS, BASE_YPOS, icon_width,
X			icon_height, 2, btile, WhitePixmap);
X	XSetIconWindow(win->basewin, win->icon);
X	XSelectInput(win->icon, ExposeRegion);
X
X	cur = XCreateCursor(xchess_width, xchess_height, xchess_bits,
X			xchess_mask_bits, xchess_x_hot, xchess_y_hot,
X			win->cursorcolor.pixel, WhitePixel, GXcopy);
X	XDefineCursor(win->basewin, cur);
X
X	XMapWindow(win->basewin);
X	XMapSubwindows(win->basewin);
X
X	XSelectInput(win->basewin, KeyPressed);
X	XSelectInput(win->boardwin, ButtonPressed | ButtonReleased |
X			ExposeRegion | ExposeWindow);
X	XSelectInput(win->recwin, ButtonReleased | ExposeRegion |
X			ExposeWindow | ExposeCopy);
X	XSelectInput(win->jailwin, ExposeRegion | ExposeWindow);
X	XSelectInput(win->wclockwin, ExposeRegion | ExposeWindow);
X	XSelectInput(win->bclockwin, ExposeRegion | ExposeWindow);
X	XSelectInput(win->messagewin, ButtonReleased | ExposeRegion |
X			ExposeWindow | ExposeCopy);
X	XSelectInput(win->buttonwin, ButtonPressed | ExposeRegion |
X			ExposeWindow);
X	
X	message_init(win);
X	record_init(win);
X	button_draw(win);
X	jail_init(win);
X	clock_init(win, WHITE);
X	clock_init(win, BLACK);
X	if (timeunit) {
X		if (timeunit > 1800)
X			sprintf(buf, "%d moves every %.2lg hours.\n",
X				movesperunit, ((double) timeunit) / 3600);
X		else if (timeunit > 30)
X			sprintf(buf, "%d moves every %.2lg minutes.\n",
X				movesperunit, ((double) timeunit) / 60);
X		else
X			sprintf(buf, "%d moves every %d seconds.\n",
X				movesperunit, timeunit);
X		message_add(win, buf, false);
X	}
X
X	XFreePixmap(btile);
X	XFreePixmap(ttile);
X	
X	return (true);
X}
X
Xstatic void
Xdrawgrid(win)
X	windata *win;
X{
X	int i;
X
X	XSetDisplay(win->display);
X	/* Draw the lines... horizontal, */
X	for (i = 1; i < SIZE; i++)
X		XLine(win->boardwin, 0, i * (SQUARE_WIDTH + BORDER_WIDTH) -
X				(BORDER_WIDTH + 1) / 2 - 1, SIZE *
X				(SQUARE_WIDTH + BORDER_WIDTH),
X				i * (SQUARE_WIDTH +
X				BORDER_WIDTH) - (BORDER_WIDTH + 1) / 2 - 1,
X				BORDER_WIDTH, BORDER_WIDTH, win->border.pixel,
X				GXcopy, AllPlanes);
X
X	/* and vertical... */
X	for (i = 1; i < SIZE; i++)
X		XLine(win->boardwin, i * (SQUARE_WIDTH + BORDER_WIDTH) -
X				(BORDER_WIDTH + 1) / 2 - 1, 0,
X				i * (SQUARE_WIDTH +
X				BORDER_WIDTH) - (BORDER_WIDTH + 1) / 2 - 1,
X				SIZE * (SQUARE_WIDTH + BORDER_WIDTH),
X				BORDER_WIDTH, BORDER_WIDTH, win->border.pixel,
X				GXcopy, AllPlanes);
X	return;
X}
X
Xvoid
Xwin_restart()
X{
X	win1->flipped = false;
X	win_redraw(win1, (XEvent *) NULL);
X	if (!oneboard) {
X		win2->flipped = true;
X		win_redraw(win2, (XEvent *) NULL);
X	}
X	return;
X}
X
Xstatic void
Xicon_refresh(win)
X	windata *win;
X{
X	XPixmapPut(win->icon, 0, 0, 0, 0, icon_width, icon_height,
X			win->iconpixmap, GXcopy, AllPlanes);
X	return;
X}
X
END_OF_window.c
if test 18431 -ne `wc -c <window.c`; then
    echo shar: \"window.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 6\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0