v02i029: gnu chess for X, Part02/06

Mike Wexler mikew at wyse.wyse.com
Tue Dec 6 12:36:00 AEST 1988


Submitted-by: aperez at blazer.prime.com (Arturo Perez Ext.)
Posting-number: Volume 2, Issue 29
Archive-name: xchess/part02

#! /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 2 (of 6)."
# Contents:  control.c parse.c popup.c record.c.UU window.c
# Wrapped by mikew at wyse on Mon Dec  5 18:32:47 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'control.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'control.c'\"
else
echo shar: Extracting \"'control.c'\" \(11973 characters\)
sed "s/^X//" >'control.c' <<'END_OF_FILE'
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
Xmove *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	XKeyEvent *ev = (XKeyEvent *) 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	XKeyEvent *ev = (XKeyEvent *) 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	    XBell(win1->display, 50);
X	    XBell(win2->display, 50);
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	memset(&bm, 0, sizeof(bm));
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(win1->display, 0);
X	if (!oneboard) {
X	    XSync(win2->display, 0);
X	}
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_FILE
if test 11973 -ne `wc -c <'control.c'`; then
    echo shar: \"'control.c'\" unpacked with wrong size!
fi
# end of 'control.c'
fi
if test -f 'parse.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'parse.c'\"
else
echo shar: Extracting \"'parse.c'\" \(9117 characters\)
sed "s/^X//" >'parse.c' <<'END_OF_FILE'
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(win1->display, 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
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		/* for pawns we must account for en passant */
X		if (m->piece.type == PAWN) {
X		    if (m->type == MOVE && m->fromx != m->tox) {
X			m->enpassant = 1;
X			m->type = CAPTURE;
X		    }
X		}
X	    }
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_FILE
if test 9117 -ne `wc -c <'parse.c'`; then
    echo shar: \"'parse.c'\" unpacked with wrong size!
fi
# end of 'parse.c'
fi
if test -f 'popup.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'popup.c'\"
else
echo shar: Extracting \"'popup.c'\" \(3227 characters\)
sed "s/^X//" >'popup.c' <<'END_OF_FILE'
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/26 12:10:38 $
X *           $Source: /users/faustus/xchess/RCS/popup.c,v $
X * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group 
X *	 faustus at cad.berkeley.edu, ucbvax!faustus
X * Permission is granted to modify and re-distribute this code in any manner
X * as long as this notice is preserved.  All standard disclaimers apply.
X *
X * A simple pop-up menu system.
X */
X
X#include "xchess.h"
X
X/* Open a small window with some text in it and two buttons -- yes and no.
X * Use black and white pixel, and the medium font.
X */
X
Xbool
Xpop_question(win, text)
X	windata *win;
X	char *text;
X{
X	char *s, *t;
X	int nlines = 1, ncols = 0, i = 0, j;
X	int x, y;
X	Window w;
X	bool ch;
X	XEvent ev;
X
X	for (s = text; *s; s++) {
X		if ((*s == '\n') && s[1])
X			nlines++;
X		if ((*s == '\n') || !s[1]) {
X			if (i > ncols)
X				ncols = i;
X			i = 0;
X		} else
X			i++;
X	}
X
X	if (ncols < 12)
X		ncols = 12;
X	nlines += 4;
X	ncols += 4;
X
X	x = (BASE_WIDTH - ncols * win->medium->max_bounds.width) / 2;
X	y = (BASE_HEIGHT - nlines * win->medium->max_bounds.ascent) / 2;
X
X	w = XCreateSimpleWindow(win->display, win->basewin,
X				x, y, ncols * win->medium->max_bounds.width,
X				nlines * win->medium->ascent,
X				BORDER_WIDTH, win->border.pixel,
X				win->textback.pixel);
X	XMapRaised(win->display, w);
X	XSetFont(win->display, DefaultGC(win->display, 0),
X		 win->medium->fid);
X	
X	for (i = 0, s = text; i < nlines - 4; i++) {
X		for (t = s, j = 0; *t && (*t != '\n'); t++, j++)
X			;
X		XDrawString(win->display, w, DefaultGC(win->display, 0),
X			    (ncols - j) / 2 * win->medium->max_bounds.width,
X			    (i + 1) * win->medium->ascent,
X			    s, j);
X		s = t + 1;
X	}
X	XDrawString(win->display, w, DefaultGC(win->display, 0),
X		    (ncols - 8) * win->medium->max_bounds.width / 4,
X		    (nlines - 2) * win->medium->ascent,
X		    "YES", 3);
X	XDrawString(win->display, w, DefaultGC(win->display, 0),
X		    (ncols - 4) * win->medium->max_bounds.width * 3 / 4,
X		    (nlines - 2) * win->medium->ascent,
X		    "NO", 2);
X
X	XSync(win->display, 0);
X	XSelectInput(win->display, w, ButtonPressMask);
X	XWindowEvent(win->display, w, ButtonPressMask, &ev);
X	x = ev.xkey.x;
X	y = ev.xkey.y;
X
X	if (x > ncols * win->medium->max_bounds.width / 2)
X		ch = false;
X	else
X		ch = true;
X
X	XDestroyWindow(win->display, w);
X	XSync(win->display, 0);
X	return (ch);
X}
X
END_OF_FILE
if test 3227 -ne `wc -c <'popup.c'`; then
    echo shar: \"'popup.c'\" unpacked with wrong size!
fi
# end of 'popup.c'
fi
if test -f 'record.c.UU' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'record.c.UU'\"
else
echo shar: Extracting \"'record.c.UU'\" \(9641 characters\)
sed "s/^X//" >'record.c.UU' <<'END_OF_FILE'
Xbegin 666 record.c
XM+RH at 5&AI<R!F:6QE(&-O;G1A:6YS(&-O9&4 at 9F]R(%@M0TA%4U,N"B`@($-O
XM<'ER:6=H="`H0RD@,3DX-B!&<F5E(%-O9G1W87)E($9O=6YD871I;VXL($EN
XM8RX*"E1H:7, at 9FEL92!I<R!P87)T(&]F(%@M0TA%4U,N"@I8+4-(15-3(&ES
XM(&1I<W1R:6)U=&5D(&EN('1H92!H;W!E('1H870@:70@=VEL;"!B92!U<V5F
XM=6PL"F)U="!7251(3U54($%.62!705)204Y462X@($YO(&%U=&AO<B!O<B!D
XM:7-T<FEB=71O<@IA8V-E<'1S(')E<W!O;G-I8FEL:71Y('1O(&%N>6]N92!F
XM;W(@=&AE(&-O;G-E<75E;F-E<R!O9B!U<VEN9R!I=`IO<B!F;W(@=VAE=&AE
XM<B!I="!S97)V97, at 86YY('!A<G1I8W5L87(@<'5R<&]S92!O<B!W;W)K<R!A
XM="!A;&PL"G5N;&5S<R!H92!S87ES('-O(&EN('=R:71I;F<N("!2969E<B!T
XM;R!T:&4 at 6"U#2$534R!'96YE<F%L(%!U8FQI8PI,:6-E;G-E(&9O<B!F=6QL
XM(&1E=&%I;',N"@I%=F5R>6]N92!I<R!G<F%N=&5D('!E<FUI<W-I;VX@=&\@
XM8V]P>2P@;6]D:69Y(&%N9"!R961I<W1R:6)U=&4*6"U#2$534RP at 8G5T(&]N
XM;'D@=6YD97(@=&AE(&-O;F1I=&EO;G, at 9&5S8W)I8F5D(&EN('1H90I8+4-(
XM15-3($=E;F5R86P at 4'5B;&EC($QI8V5N<V4N("`@02!C;W!Y(&]F('1H:7,@
XM;&EC96YS92!I<PIS=7!P;W-E9"!T;R!H879E(&)E96X at 9VEV96X@=&\@>6]U
XM(&%L;VYG('=I=&@@6"U#2$534R!S;R!Y;W4*8V%N(&MN;W<@>6]U<B!R:6=H
XM=', at 86YD(')E<W!O;G-I8FEL:71I97,N("!)="!S:&]U;&0 at 8F4@:6X at 80IF
XM:6QE(&YA;65D($-/4%E)3D<N("!!;6]N9R!O=&AE<B!T:&EN9W,L('1H92!C
XM;W!Y<FEG:'0@;F]T:6-E"F%N9"!T:&ES(&YO=&EC92!M=7-T(&)E('!R97-E
XM<G9E9"!O;B!A;&P at 8V]P:65S+B`@*B\*"@HO*B!20U, at 26YF;SH@)%)E=FES
XM:6]N.B`Q+C0@)"!O;B`D1&%T93H at .#8O,3$O,C,@,3<Z,3 at Z,C`@)`H@*B`@
XM("`@("`@("`@)%-O=7)C93H at +W5S97)S+V9A=7-T=7,O>&-H97-S+U)#4R]R
XM96-O<F0N8RQV("0*("H at 0V]P>7)I9VAT("AC*2`Q.3 at V(%=A>6YE($$N($-H
XM<FES=&]P:&5R+"!5+B!#+B!"97)K96QE>2!#040 at 1W)O=7`*("H)4&5R;6ES
XM<VEO;B!I<R!G<F%N=&5D('1O(&1O(&%N>71H:6YG('=I=&@@=&AI<R!C;V1E
XM(&5X8V5P="!S96QL(&ET"B`J"6]R(')E;6]V92!T:&ES(&UE<W-A9V4N"B`J
XM"B`J($1E86P@=VET:"!R96-O<F1I;F<@;6]V97,N"B`J+PH*(VEN8VQU9&4@
XM(GAC:&5S<RYH(@H*(W5N9&5F('-M87)T87-S"@IB;V]L(')E8V]R9%]E;F=L
XM:7-H(#T@=')U93L*8VAA<B`J<F5C;W)D7V9I;&4@/2!$149?4D5#3U)$7T9)
XM3$4["FEN="!M;W9E;G5M(#T@,#L*8F]O;"!S879E9FQA9R`](&9A;'-E.PH*
XM<W1A=&EC(&-H87(@*F-O;&YA;65S6UT@/2![(")Q<B(L(")Q;B(L(")Q8B(L
XM(")Q(BP@(FLB+"`B:V(B+"`B:VXB+"`B:W(B('T at .PIS=&%T:6, at 8VAA<B`J
XM<&-N86UE<UM=(#T@>R`B4"(L(")2(BP@(DXB+"`B0B(L(")1(BP@(DLB('T@
XM.PH*<W1A=&EC(&-H87(@*FUO=F5S=')I;F<H*3L*<W1A=&EC(&-H87(@*G1S
XM=')I;F<H*3L*<W1A=&EC($9)3$4@*F)A8VMU<#L*"B-D969I;F4 at 4D5#3U)$
XM7TA%041%4 at DB7&X&,2`@("!80VAE<W, at 1V%M92!296-O<F0&,%QN(@H*=F]I
XM9`IR96-O<F1?:6YI="AW:6XI"@EW:6YD871A("IW:6X["GL*"6EN="!I.PH*
XM"6D@/2!85&5X=%=I9'1H*'=I;BT^;65D:75M+"!214-/4D1?2$5!1$52+`H)
XM"2`@("`@("!S:7IE;V8H4D5#3U)$7TA%041%4BD at +2`Q*3L*"6D@/2`H-#`@
XM*B!W:6XM/G-M86QL+3YM87A?8F]U;F1S+G=I9'1H("T@:2`J"@D@("`@('=I
XM;BT^;65D:75M+3YM87A?8F]U;F1S+G=I9'1H*2`O(`H)"0EW:6XM/FUE9&EU
XM;2T^;6%X7V)O=6YD<RYW:61T:"`O(#(["@E4>'1'<F%B*'=I;BT^9&ES<&QA
XM>2P@=VEN+3YR96-W:6XL(")X8VAE<W,B+"!W:6XM/G-M86QL+"!W:6XM/G1E
XM>'1B86-K+G!I>&5L+`H)"0EW:6XM/G1E>'1C;VQO<BYP:7AE;"P@=VEN+3YC
XM=7)S;W)C;VQO<BYP:7AE;"D["@E4>'1!9&1&;VYT*'=I;BT^9&ES<&QA>2P@
XM=VEN+3YR96-W:6XL(#$L('=I;BT^;65D:75M+"!W:6XM/G1E>'1C;VQO<BYP
XM:7AE;"D["@EF;W(@*#L@:2`^(#`[(&DK*RD*"0E4>'17<FET95-T<BAW:6XM
XM/F1I<W!L87DL('=I;BT^<F5C=VEN+"`B("(I.PH)5'AT5W)I=&53='(H=VEN
XM+3YD:7-P;&%Y+"!W:6XM/G)E8W=I;BP at 4D5#3U)$7TA%041%4BD["@D*"6EF
XM("AS879E9FQA9RD@>PH)"6EF("@A*&)A8VMU<"`](&9O<&5N*')E8V]R9%]F
XM:6QE+"`B=R(I*2D@>PH)"0EP97)R;W(H<F5C;W)D7V9I;&4I.PH)"0ES879E
XM9FQA9R`](&9A;'-E.PH)"7T at 96QS92!["@D)"69P<FEN=&8H8F%C:W5P+"`B
XM6"!#:&5S<R`M+2`E<UQN(BP at 9&%T97-T<FEN9R at I*3L*"0D):68@*&1I<W!N
XM86UE,BD*"0D)"69P<FEN=&8H8F%C:W5P+"`B7'17:&ET92!O;B`E<RP at 8FQA
XM8VL@;VX@)7-<;B(L(`H)"0D)"0ED:7-P;F%M93$L(&1I<W!N86UE,BD["@D)
XM"65L<V4*"0D)"69P<FEN=&8H8F%C:W5P+"`B7'1'86UE('!L87EE9"!O;B`E
XM<UQN(BP*"0D)"0D)9&ES<&YA;64Q*3L*"0D)9G!R:6YT9BAB86-K=7`L(")<
XM="5S7&XB+"!R96-O<F1?96YG;&ES:"`_(")E;F=L:7-H(B`Z"@D)"0D)(F%L
XM9V5B<F%I8R(I.PH)"0EF9FQU<V at H8F%C:W5P*3L*"0E]"@E]"@H);6]V96YU
XM;2`](#`["@ER971U<FX["GT*"G9O:60*<F5C;W)D7W)E<V5T*"D*>PH)5'AT
XM5W)I=&53='(H=VEN,2T^9&ES<&QA>2P@=VEN,2T^<F5C=VEN+"`B7&Y<;@8Q
XM("`@($YE=R!'86UE!C!<;EQN(BD["@EI9B`H(6]N96)O87)D*2!["@D)5'AT
XM5W)I=&53='(H=VEN,BT^9&ES<&QA>2P@=VEN,BT^<F5C=VEN+"`B7&Y<;@8Q
XM("`@($YE=R!'86UE!C!<;EQN(BD["@E]"@EM;W9E;G5M(#T@,#L*"6EF("AS
XM879E9FQA9RD@>PH)"69P<FEN=&8H8F%C:W5P+"`B7&Y<;DYE=R!'86UE7&Y<
XM;B(I.PH)"69F;'5S:"AB86-K=7`I.PH)?0H)<F5T=7)N.PI]"@IV;VED"G)E
XM8V]R9%]E;F0H<RD*"6-H87(@*G,["GL*"6-H87(@8G5F6T)325I%73L*"@ES
XM<')I;G1F*&)U9BP@(EQN)7-<;B(L(',I.PH)5'AT5W)I=&53='(H=VEN,2T^
XM9&ES<&QA>2P@=VEN,2T^<F5C=VEN+"!S*3L*"6EF("@A;VYE8F]A<F0I('L*
XM"0E4>'17<FET95-T<BAW:6XR+3YD:7-P;&%Y+"!W:6XR+3YR96-W:6XL(',I
XM.PH)?0H):68@*'-A=F5F;&%G*2!["@D)9G!R:6YT9BAB86-K=7`L(")<;B5S
XM7&XB+"!S*3L*"0EF<')I;G1F*&)A8VMU<"P@(E1I;64Z('=H:71E.B`E<RP@
XM(BP@='-T<FEN9RAW:&ET97-E8V]N9',I*3L*"0EF<')I;G1F*&)A8VMU<"P@
XM(F)L86-K.B`E<UQN(BP@='-T<FEN9RAB;&%C:W-E8V]N9',I*3L*"0EF8VQO
XM<V4H8F%C:W5P*3L*"7T*"7)E='5R;CL*?0H*=F]I9`IR96-O<F1?<V%V92 at I
XM"GL*"6UO=F4@*FT["@E&24Q%("IF<#L*"6EN="!I.PH)8VAA<B`J<SL*"@EI
XM9B`H(2AF<"`](&9O<&5N*')E8V]R9%]F:6QE+"`B=R(I*2D@>PH)"7!E<G)O
XM<BAR96-O<F1?9FEL92D["@D)<F5T=7)N.PH)?0H)9G!R:6YT9BAF<"P@(E@@
XM0VAE<W, at +2T@)7-<;B(L(&1A=&5S=')I;F<H*2D["@EI9B`H9&ES<&YA;64R
XM*0H)"69P<FEN=&8H9G`L(")<=%=H:71E(&]N("5S+"!B;&%C:R!O;B`E<UQN
XM(BP@"@D)"0ED:7-P;F%M93$L(&1I<W!N86UE,BD["@EE;'-E"@D)9G!R:6YT
XM9BAF<"P@(EQT1V%M92!P;&%Y960@;VX@)7-<;B(L(&1I<W!N86UE,2D["@EF
XM<')I;G1F*&9P+"`B7'0E<UQN(BP@<F5C;W)D7V5N9VQI<V@@/R`B96YG;&ES
XM:"(@.B`B86QG96)R86EC(BD["@H)9F]R("AM(#T@;6]V97,L(&D@/2`Q.R!M
XM.R!I*RLI('L*"0ES(#T@;6]V97-T<FEN9RAM*3L*"0EF<')I;G1F*&9P+"`B
XM)3)D+B`E+3$V<R`B+"!I+"!S*3L*"0EM(#T@;2T^;F5X=#L*"0EI9B`H;2D*
XM"0D)<R`](&UO=F5S=')I;F<H;2D["@D)96QS90H)"0ES(#T@(B(["@D)9G!R
XM:6YT9BAF<"P@(B5S7&XB+"!S*3L*"0EI9B`H;2D*"0D);2`](&TM/FYE>'0[
XM"@E]"@EF8VQO<V4H9G`I.PH)<F5T=7)N.PI]"@IV;VED"G)E8V]R9%]M;W9E
XM*&TI"@EM;W9E("IM.PI["@EC:&%R("IS+"!B=69;0E-)6D5=.PH*"7,@/2!M
XM;W9E<W1R:6YG*&TI.PH*"6EF("AM+3YP:65C92YC;VQO<B`]/2!72$E412D@
XM>PH)"6UO=F5N=6TK*SL*"0ES<')I;G1F*&)U9BP@(B4R9"X@)2TQ-G,@(BP@
XM;6]V96YU;2P@<RD["@E](&5L<V4@>PH)"7-P<FEN=&8H8G5F+"`B)7-<;B(L
XM(',I.PH)?0H)5'AT5W)I=&53='(H=VEN,2T^9&ES<&QA>2P@=VEN,2T^<F5C
XM=VEN+"!B=68I.PH):68@*"%O;F5B;V%R9"D@>PH)"51X=%=R:71E4W1R*'=I
XM;C(M/F1I<W!L87DL('=I;C(M/G)E8W=I;BP at 8G5F*3L*"7T*"6EF("AS879E
XM9FQA9RD@>PH)"69P<FEN=&8H8F%C:W5P+"`B)7,B+"!B=68I.PH)"69F;'5S
XM:"AB86-K=7`I.PH)?0H*"7)E='5R;CL*?0H*=F]I9`IR96-O<F1?8F%C:R at I
XM"GL*("`@(&5X=&5R;B!M;W9E("IL87-T;6]V93L*("`@(&UO=F4@*FT@/2!L
XM87-T;6]V93L*("`@(&-H87(@*G,@/2!M;W9E<W1R:6YG*&TI.PH@("`@8VAA
XM<B!B=69;0E-)6D5=.PH@("`@;&]N9R!I.PH*("`@(&EF("AM+3YP:65C92YC
XM;VQO<B`]/2!72$E412D@>PH)<W!R:6YT9BAB=68L("(E,F0N("4M,39S("(L
XM(&UO=F5N=6TL(',I.PH@("`@?2!E;'-E('L*"7-P<FEN=&8H8G5F+"`B)7-<
XM;B(L(',I.PH@("`@?0H@("`@<R`](&)U9CL*("`@(&9O<B`H:2`](#`[("IS
XM("$]("=<,"<[(&DK*RD*"2IS*RL@/2`G""<["0DO*B!C;VYT<F]L($@L(&)A
XM8VMS<&%C92`J+PH@("`*("`@(%1X=%=R:71E4W1R*'=I;C$M/F1I<W!L87DL
XM('=I;C$M/G)E8W=I;BP at 8G5F*3L*("`@(&EF("@A;VYE8F]A<F0I('L*"51X
XM=%=R:71E4W1R*'=I;C(M/F1I<W!L87DL('=I;C(M/G)E8W=I;BP at 8G5F*3L*
XM("`@('T*"B`@("!I9B`H;F5X='1O;6]V92`]/2!"3$%#2RD*"6UO=F5N=6TM
XM+3L*("`@(&EF("AS879E9FQA9RD@>PH)9G-E96LH8F%C:W5P+"`M:2P@,2D[
XM"@EF9FQU<V at H8F%C:W5P*3L*("`@('T*"B`@("!R971U<FX["GT*"G-T871I
XM8R!C:&%R("H*;6]V97-T<FEN9RAM*0H);6]V92`J;3L*>PH):6YT(&9Y+"!T
XM>3L*"7-T871I8R!C:&%R(&)U9EM"4TE:15T["@H):68@*"%R96-O<F1?96YG
XM;&ES:"!\?"`H;2T^<&EE8V4N8V]L;W(@/3T at 5TA)5$4I*2!["@D)9GD@/2!3
XM25I%("T@;2T^9G)O;7D["@D)='D@/2!325I%("T@;2T^=&]Y.PH)?2!E;'-E
XM('L*"0EF>2`](&TM/F9R;VUY("L@,3L*"0ET>2`](&TM/G1O>2`K(#$["@E]
XM"@H)<W=I=&-H("AM+3YT>7!E*2!["@D@("`@8V%S92!-3U9%. at H)"6EF("AR
XM96-O<F1?96YG;&ES:"D*"0D)<W!R:6YT9BAB=68L("(E<R\E<R5D+25S)60E
XM<R(L('!C;F%M97-;*&EN="D@;2T^<&EE8V4N"@D)"0D)='EP95TL(&-O;&YA
XM;65S6VTM/F9R;VUX72P at 9GDL"@D)"0D)8V]L;F%M97-;;2T^=&]X72P@='DL
XM(&TM/F-H96-K(#\@(BLB(#H*"0D)"0DB(BD["@D)96QS90H)"0ES<')I;G1F
XM*&)U9BP@(B5C)60E8R5D(BP@)V$G("L@;2T^9G)O;7 at L(&9Y+"`G82<@*PH)
XM"0D)"6TM/G1O>"P@='DI.PH)"6)R96%K.PH)("`@(&-A<V4 at 0T%05%5213H*
XM"0EI9B`H<F5C;W)D7V5N9VQI<V at I"@D)"7-P<FEN=&8H8G5F+"`B)7,O)7,E
XM9'@E<R\E<R5D)7,E<R(L"@D)"0D)<&-N86UE<ULH:6YT*2!M+3YP:65C92YT
XM>7!E72P*"0D)"0EC;VQN86UE<UMM+3YF<F]M>%TL(&9Y+`H)"0D)"7!C;F%M
XM97-;*&EN="D@;2T^=&%K96XN='EP95TL"@D)"0D)8V]L;F%M97-;;2T^=&]X
XM72P@='DL"@D)"0D);2T^96YP87-S86YT(#\@(F4N<"XB(#H@(B(L"@D)"0D)
XM;2T^8VAE8VL@/R`B*R(@.B`B(BD["@D)96QS90H)"0ES<')I;G1F*&)U9BP@
XM(B5C)60E8R5D(BP@)V$G("L@;2T^9G)O;7 at L(&9Y+"`G82<@*PH)"0D)"6TM
XM/G1O>"P@='DI.PH)"6)R96%K.PH*"2`@("!C87-E($M#05-43$4Z"@D):68@
XM*')E8V]R9%]E;F=L:7-H*0H)"0ES<')I;G1F*&)U9BP@(D\M3R5S(BP@;2T^
XM8VAE8VL@/R`B8V at B(#H@(B(I.PH)"65L<V4@:68@*&TM/G!I96-E+F-O;&]R
XM(#T](%=(251%*0H)"0ES=')C<'DH8G5F+"`B93%G,2(I.PH)"65L<V4*"0D)
XM<W1R8W!Y*&)U9BP@(F4X9S at B*3L*"0EB<F5A:SL*"@D@("`@8V%S92!10T%3
XM5$Q%. at H)"6EF("AR96-O<F1?96YG;&ES:"D*"0D)<W!R:6YT9BAB=68L(")/
XM+4\M3R5S(BP@;2T^8VAE8VL@/R`B8V at B(#H@(B(I.PH)"65L<V4@:68@*&TM
XM/G!I96-E+F-O;&]R(#T](%=(251%*0H)"0ES=')C<'DH8G5F+"`B93%C,2(I
XM.PH)"65L<V4*"0D)<W1R8W!Y*&)U9BP@(F4X8S at B*3L*"0EB<F5A:SL*"@D@
XM("`@9&5F875L=#H*"0ES<')I;G1F*&)U9BP@(G-O;65T:&EN9R!S=')A;F=E
XM(BD["@D)8G)E86L["@E]"@EI9B`H*&TM/G!I96-E+G1Y<&4@/3T at 4$%73BD@
XM)B8@*"@H;2T^<&EE8V4N8V]L;W(@/3T at 0DQ!0TLI("8F(`H)"0DH;2T^=&]Y
XM(#T](#<I*2!\?"`H*&TM/G!I96-E+F-O;&]R(#T](%=(251%*2`F)@H)"0DH
XM;2T^=&]Y(#T](#`I*2DI(`H)"7-T<F-A="AB=68L("(H42DB*3L*"B-I9F1E
XM9B!S;6%R=&%S<PH):68@*"$H<F%N9&]M*"D@)2`U,"DI"@D)<W1R8V%T*&)U
XM9BP@(C\B*3L*"65L<V4@:68@*"$H<F%N9&]M*"D@)2`U,"DI"@D)<W1R8V%T
XM*&)U9BP@(B$B*3L*"65L<V4@:68@*"$H<F%N9&]M*"D@)2`U,#`I*0H)"7-T
XM<F-A="AB=68L("(_/S\B*3L*"65L<V4@:68@*"$H<F%N9&]M*"D@)2`U,#`I
XM*0H)"7-T<F-A="AB=68L("(A(2$B*3L*(V5N9&EF('-M87)T87-S"@H)<F5T
XM=7)N("AB=68I.PI]"@IS=&%T:6, at 8VAA<B`J"G1S=')I;F<H<RD*"6EN="!S
XM.PI["@ES=&%T:6, at 8VAA<B!B=69;-C1=.PH*"6EF("AS(#X@,S8P,"D*"0ES
XM<')I;G1F*&)U9BP@(B5D:"`E9&T@)61S(BP@<R`O(#,V,#`L("AS("4@,S8P
XM,"D at +R`V,"P@<R`E(#8P*3L*"65L<V4@:68@*',@/B`V,"D*"0ES<')I;G1F
XM*&)U9BP@(B5D;2`E9',B+"`H<R`E(#,V,#`I("\@-C`L(',@)2`V,"D["@EE
XM;'-E"@D)<W!R:6YT9BAB=68L("(E9',B+"!S*3L*"7)E='5R;B`H8G5F*3L*
X#?0H*
X`
Xend
END_OF_FILE
if test 9641 -ne `wc -c <'record.c.UU'`; then
    echo shar: \"'record.c.UU'\" unpacked with wrong size!
fi
# end of 'record.c.UU'
fi
if test -f 'window.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'window.c'\"
else
echo shar: Extracting \"'window.c'\" \(25887 characters\)
sed "s/^X//" >'window.c' <<'END_OF_FILE'
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 <X11/Xutil.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	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    char *bits, *maskbits, *outline;
X    windata *win;
X    char buf[BSIZE];
X    XImage *tmpImage;
X    Pixmap tmpPM, maskPM;
X    XGCValues gc;
X
X    if (oneboard || (wnum == win1->color))
X	win = win1;
X    else
X	win = win2;
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
X    if ((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	XSetState(win->display, DefaultGC(win->display, 0),
X		  BlackPixel(win->display, 0),
X		  WhitePixel(win->display, 0), GXcopy, AllPlanes);
X	
X	tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
X				shade_bits, SQUARE_WIDTH, SQUARE_HEIGHT);
X
X	XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
X		   0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
X		   x * (SQUARE_WIDTH + BORDER_WIDTH),
X		   y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
X
X	XFreePixmap(win->display, tmpPM);
X	
X	XSetFunction(win->display, DefaultGC(win->display, 0),
X		     GXandInverted);
X	maskPM = XCreateBitmapFromData(win->display, win->boardwin,
X				      maskbits, SQUARE_WIDTH, SQUARE_HEIGHT);
X	XCopyPlane(win->display, maskPM, win->boardwin, DefaultGC(win->display, 0),
X		   0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
X		   x * (SQUARE_WIDTH + BORDER_WIDTH),
X		   y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
X	XFreePixmap(win->display, maskPM);
X
X	XSetFunction(win->display, DefaultGC(win->display, 0),
X		     GXor);
X	tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
X				bits, SQUARE_WIDTH, SQUARE_HEIGHT);
X	XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
X		   0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
X		   x * (SQUARE_WIDTH + BORDER_WIDTH),
X		   y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
X	XFreePixmap(win->display, tmpPM);
X
X	XSetFunction(win->display, DefaultGC(win->display, 0), GXcopy);
X
X    } else if (win->bnw){
X	XSetState(win->display, DefaultGC(win->display, 0),
X		  BlackPixel(win->display, 0),
X		  WhitePixel(win->display, 0), GXcopy, AllPlanes);
X
X	tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
X				bits, SQUARE_WIDTH, SQUARE_HEIGHT);
X	XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
X		   0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
X		   x * (SQUARE_WIDTH + BORDER_WIDTH),
X		   y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
X	XFreePixmap(win->display, tmpPM);
X    } else {
X	XSetState(win->display, DefaultGC(win->display, 0),
X		 ((p->color == WHITE) ? win->whitepiece.pixel :
X		  			win->blackpiece.pixel),
X		  (iswhite(win, x, y) ? win->whitesquare.pixel :
X		   			win->blacksquare.pixel),
X		  GXcopy, AllPlanes);
X	tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
X				bits, SQUARE_WIDTH, SQUARE_HEIGHT);
X	XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
X		   0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
X		   x * (SQUARE_WIDTH + BORDER_WIDTH),
X		   y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
X	XFreePixmap(win->display, tmpPM);
X    }
X
X    if (!record_english) {
X	gc.foreground = win->textcolor.pixel;
X	if (iswhite(win, x, y) || win->bnw)
X	    gc.background = win->whitesquare.pixel;
X	else
X	    gc.background = win->blacksquare.pixel;
X
X	gc.font = win->small->fid;
X	    
X	XChangeGC(win->display, DefaultGC(win->display, 0),
X		  GCForeground | GCBackground | GCFont, &gc);
X	    
X	if (!x) {
X	    sprintf(buf, " %d", SIZE - y);
X	    XDrawImageString(win->display, win->boardwin,
X			     DefaultGC(win->display, 0),
X			     1, (y + 1) * (SQUARE_HEIGHT + 
X					   BORDER_WIDTH) - BORDER_WIDTH + 
X			     win->small->max_bounds.ascent - 1, buf, 2);
X	}
X	if (y == SIZE - 1) {
X	    sprintf(buf, "%c", 'A' + x);
X	    XDrawImageString(win->display, win->boardwin,
X			     DefaultGC(win->display, 0),
X			     x * (SQUARE_WIDTH + BORDER_WIDTH) + 1,
X			     SIZE * (SQUARE_HEIGHT + BORDER_WIDTH) - BORDER_WIDTH + 
X			     win->small->max_bounds.ascent - 1, buf, 1);
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    XGCValues gc;
X    Pixmap tmpPM;
X    
X    if (oneboard || (wnum == win1->color))
X	win = win1;
X    else
X	win = win2;
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
X    if ((x < 0) || (x > 7) || (y < 0) || (y > 7)) exit(1);
X
X    if (win->bnw && !iswhite(win, x, y)) {
X	XSetState(win->display, DefaultGC(win->display, 0),
X		  BlackPixel(win->display, 0),
X		  WhitePixel(win->display, 0), GXcopy, AllPlanes);
X	tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
X				shade_bits, SQUARE_WIDTH, SQUARE_HEIGHT);
X
X	XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
X		   0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
X		   x * (SQUARE_WIDTH + BORDER_WIDTH),
X		   y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
X
X	XFreePixmap(win->display, tmpPM);
X    } else {
X	XSetFillStyle(win->display, DefaultGC(win->display, 0),
X		      FillSolid);
X	XSetForeground(win->display, DefaultGC(win->display, 0),
X		       iswhite(win, x, y) ? win->whitesquare.pixel :
X		       win->blacksquare.pixel);
X	XFillRectangle(win->display, win->boardwin,
X		       DefaultGC(win->display, 0),
X		       x * (SQUARE_WIDTH + BORDER_WIDTH),
X		       y * (SQUARE_HEIGHT + BORDER_WIDTH),
X		       SQUARE_WIDTH, SQUARE_HEIGHT);
X    }
X
X    if (!record_english) {
X	gc.foreground = win->textcolor.pixel;
X	if (iswhite(win, x, y) || win->bnw)
X	    gc.background = win->whitesquare.pixel;
X	else
X	    gc.background = win->blacksquare.pixel;
X
X	gc.font = win->small->fid;
X	    
X	XChangeGC(win->display, DefaultGC(win->display, 0),
X		  GCForeground | GCBackground | GCFont, &gc);
X	    
X	if (!x) {
X	    sprintf(buf, " %d", SIZE - y);
X	    XDrawImageString(win->display, win->boardwin,
X			     DefaultGC(win->display, 0),
X			     1, (y + 1) * (SQUARE_HEIGHT + 
X					   BORDER_WIDTH) - BORDER_WIDTH + 
X			     win->small->max_bounds.ascent - 1, buf, 2);
X	}
X	if (y == SIZE - 1) {
X	    sprintf(buf, "%c", 'A' + x);
X	    XDrawImageString(win->display, win->boardwin,
X			     DefaultGC(win->display, 0),
X			     x * (SQUARE_WIDTH + BORDER_WIDTH) + 1,
X			     SIZE * (SQUARE_HEIGHT + BORDER_WIDTH) - BORDER_WIDTH + 
X			     win->small->max_bounds.ascent - 1, buf, 1);
X	}
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	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	XSetFunction(win->display, DefaultGC(win->display, 0), GXinvert);
X	XSetLineAttributes(win->display, DefaultGC(win->display, 0),
X		0, LineSolid, 0, 0);
X	for (i = 0; i < num_flashes * 2; i++) {
X	    XDrawLine(win->display,win->boardwin,
X		      DefaultGC(win->display, 0),
X		      sx, sy, ex, ey);
X	}
X	
X	XSetFunction(win->display, DefaultGC(win->display, 0), GXcopy);
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	if (XPending(win1->display))
X		service(win1);
X	if (!oneboard) {
X	    if (XPending(win1->display))
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	while(XPending(win->display)) {
X		XNextEvent(win->display, &ev);
X		if (TxtFilter(win->display, &ev))
X			continue;
X
X		if (ev.xany.window == win->boardwin) {
X			switch (ev.type) {
X			    case ButtonPress:
X				button_pressed(&ev, win);
X				break;
X
X			    case ButtonRelease:
X				button_released(&ev, win);
X				break;
X
X			    case Expose:
X				/* Redraw... */
X				win_redraw(win, &ev);
X				break;
X
X			    case 0:
X			    case NoExpose:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.xany.window == win->wclockwin) {
X			switch (ev.type) {
X			    case Expose:
X				clock_draw(win, WHITE);
X				break;
X
X			    case 0:
X			    case NoExpose:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.xany.window == win->bclockwin) {
X			switch (ev.type) {
X			    case Expose:
X				clock_draw(win, BLACK);
X				break;
X
X			    case 0:
X			    case NoExpose:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.xany.window == win->jailwin) {
X			switch (ev.type) {
X			    case Expose:
X				jail_draw(win);
X				break;
X
X			    case 0:
X			    case NoExpose:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.xany.window == win->buttonwin) {
X			switch (ev.type) {
X			    case ButtonPress:
X				button_service(win, &ev);
X				break;
X
X			    case Expose:
X				button_draw(win);
X				break;
X
X			    case 0:
X			    case NoExpose:
X				break;
X			    default:
X				fprintf(stderr, "Bad event type %d\n", ev.type);
X				exit(1);
X			}
X		} else if (ev.xany.window == win->icon) {
X			icon_refresh(win);
X		} else if (ev.xany.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.xany.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 = &event->xexpose;
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	char buf[BSIZE], *s;
X	Pixmap bm, bmask;
X	Cursor cur;
X	extern char *program, *recfile;
X	XSizeHints xsizes;
X	
X
X	if (!(win->display = XOpenDisplay(dispname)))
X		return (false);
X	
X
X	/* Now get boolean defaults... */
X	if ((s = XGetDefault(win->display, program, "noisy")) && eq(s, "on"))
X		noisyflag = true;
X	if ((s = XGetDefault(win->display, program, "savemoves")) && eq(s, "on"))
X		saveflag = true;
X	if ((s = XGetDefault(win->display, program, "algebraic")) && eq(s, "on"))
X		record_english = false;
X	if ((s = XGetDefault(win->display, program, "blackandwhite")) && eq(s, "on"))
X		bnwflag = true;
X	if ((s = XGetDefault(win->display, program, "quickrestore")) && eq(s, "on"))
X		quickflag = true;
X	if ((s = XGetDefault(win->display, program, "flash")) && eq(s, "on"))
X		win_flashmove = true;
X	
X	/* ... numeric variables ... */
X	if (s = XGetDefault(win->display, program, "numflashes"))
X		num_flashes = atoi(s);
X	if (s = XGetDefault(win->display, program, "flashsize"))
X		flash_size = atoi(s);
X	
X	/* ... and strings. */
X	if (s = XGetDefault(win->display, program, "progname"))
X		progname = s;
X	if (s = XGetDefault(win->display, program, "proghost"))
X		proghost = s;
X	if (s = XGetDefault(win->display, program, "recordfile"))
X		recfile = s;
X	if (s = XGetDefault(win->display, program, "blackpiece"))
X		black_piece_color = s;
X	if (s = XGetDefault(win->display, program, "whitepiece"))
X		white_piece_color = s;
X	if (s = XGetDefault(win->display, program, "blacksquare"))
X		black_square_color = s;
X	if (s = XGetDefault(win->display, program, "whitesquare"))
X		white_square_color = s;
X	if (s = XGetDefault(win->display, program, "bordercolor"))
X		border_color = s;
X	if (s = XGetDefault(win->display, program, "textcolor"))
X		text_color = s;
X	if (s = XGetDefault(win->display, program, "textback"))
X		text_back = s;
X	if (s = XGetDefault(win->display, program, "errortext"))
X		error_text = s;
X	if (s = XGetDefault(win->display, program, "playertext"))
X		player_text = s;
X	if (s = XGetDefault(win->display, program, "cursorcolor"))
X		cursor_color = s;
X
X	if ((DisplayPlanes(win->display, 0) == 1) || bnwflag)
X		win->bnw = true;
X	
X	/* Allocate colors... */
X	if (win->bnw) {
X		win->blackpiece.pixel = BlackPixel (win->display, 0);
X		win->whitepiece.pixel = WhitePixel (win->display, 0);
X		win->blacksquare.pixel = BlackPixel (win->display, 0);
X		win->whitesquare.pixel = WhitePixel (win->display, 0);
X		win->border.pixel = BlackPixel (win->display, 0);
X		win->textcolor.pixel = BlackPixel (win->display, 0);
X		win->textback.pixel = WhitePixel (win->display, 0);
X		win->playertext.pixel = BlackPixel (win->display, 0);
X		win->errortext.pixel = BlackPixel (win->display, 0);
X		win->cursorcolor.pixel = BlackPixel (win->display, 0) ;
X	} else {
X	    if (!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     black_piece_color, &win->blackpiece) ||  
X		!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     white_piece_color, &win->whitepiece) ||  
X		!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     black_square_color, &win->blacksquare) ||  
X		!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     white_square_color, &win->whitesquare) ||  
X		!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     border_color, &win->border) ||  
X		!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     text_color, &win->textcolor) ||  
X		!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     text_back, &win->textback) ||  
X		!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     error_text, &win->errortext) ||  
X		!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     player_text, &win->playertext) ||  
X		!XParseColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     cursor_color, &win->cursorcolor) ||
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->blackpiece) ||  
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->whitepiece) ||  
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->blacksquare) ||  
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->whitesquare) ||   
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->border) ||  
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->textcolor) ||  
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->textback) ||  
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->errortext) ||  
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->playertext) ||  
X		!XAllocColor(win->display,
X			     DefaultColormap(win->display, 0),
X			     &win->cursorcolor))   
X		fprintf(stderr, "Can't get colors...\n");
X	}
X
X	/* Get fonts... */
X	if ((win->small = XLoadQueryFont(win->display,SMALL_FONT)) ==
X	    NULL)
X		fprintf(stderr, "Can't get small font...\n");
X
X	if ((win->medium = XLoadQueryFont(win->display,MEDIUM_FONT))
X	    == NULL)
X	    fprintf(stderr, "Can't get medium font...\n");
X
X	if ((win->large = XLoadQueryFont(win->display,LARGE_FONT)) ==
X	    NULL)
X	    fprintf(stderr, "Can't get large font...\n");
X
X	
X	/* Create the windows... */
X
X	win->basewin =
X	    XCreateSimpleWindow(win->display,DefaultRootWindow(win->display),
X			  BASE_XPOS, BASE_YPOS, 
X			  BASE_WIDTH, BASE_HEIGHT, 0,
X			  BlackPixel(win->display, 0),
X			  WhitePixel(win->display, 0)); 
X	win->boardwin = XCreateSimpleWindow(win->display,win->basewin,
X					    BOARD_XPOS, BOARD_YPOS, 
X					    BOARD_WIDTH, BOARD_HEIGHT,
X					    BORDER_WIDTH,
X					    win->border.pixel,
X					    WhitePixel(win->display, 0));
X	win->recwin = XCreateSimpleWindow(win->display,win->basewin,
X					  RECORD_XPOS, RECORD_YPOS,
X					  RECORD_WIDTH, RECORD_HEIGHT,
X					  BORDER_WIDTH, win->border.pixel,
X					  win->textback.pixel);
X	win->jailwin = XCreateSimpleWindow(win->display,win->basewin,
X					   JAIL_XPOS, JAIL_YPOS,
X					   JAIL_WIDTH, JAIL_HEIGHT,
X					   BORDER_WIDTH,
X					   win->border.pixel,
X					   win->textback.pixel);
X	win->wclockwin = XCreateSimpleWindow(win->display,win->basewin,
X					     WCLOCK_XPOS, WCLOCK_YPOS,
X					     CLOCK_WIDTH, CLOCK_HEIGHT,
X					     BORDER_WIDTH, win->border.pixel,
X					     win->textback.pixel);
X	win->bclockwin = XCreateSimpleWindow(win->display,win->basewin,
X					     BCLOCK_XPOS, BCLOCK_YPOS,
X					     CLOCK_WIDTH, CLOCK_HEIGHT,
X					     BORDER_WIDTH, win->border.pixel,
X					     win->textback.pixel);
X	win->messagewin = XCreateSimpleWindow(win->display,win->basewin,
X					      MESS_XPOS, MESS_YPOS,
X					      MESS_WIDTH, MESS_HEIGHT,
X					      BORDER_WIDTH, win->border.pixel,
X					      win->textback.pixel);
X	win->buttonwin = XCreateSimpleWindow(win->display,win->basewin,
X					     BUTTON_XPOS, BUTTON_YPOS,
X					     BUTTON_WIDTH, BUTTON_HEIGHT,
X					     BORDER_WIDTH, win->border.pixel,
X					     win->textback.pixel);
X	
X	/* Let's define an icon... */
X	win->iconpixmap = XCreatePixmapFromBitmapData(win->display,
X						      win->basewin, icon_bits,
X						      icon_width, icon_height,
X						      win->blacksquare.pixel,
X						      win->whitesquare.pixel,
X						      1);
X	xsizes.flags = PSize | PMinSize | PPosition;
X	xsizes.min_width = BASE_WIDTH;
X	xsizes.min_height = BASE_HEIGHT;
X	xsizes.x = BASE_XPOS;
X	xsizes.y = BASE_YPOS;
X	XSetStandardProperties(win->display, win->basewin,
X			       program, program, win->iconpixmap,
X			       0, NULL, &xsizes);
X	
X	bm = XCreateBitmapFromData(win->display,
X				   win->basewin, xchess_bits,
X				   xchess_width, xchess_height);
X	bmask = XCreateBitmapFromData(win->display,
X				   win->basewin, xchess_mask_bits,
X				   xchess_width, xchess_height);
X	cur = XCreatePixmapCursor(win->display, bm, bmask,
X			    &win->cursorcolor,
X			    &WhitePixel(win->display, 0),
X			    xchess_x_hot, xchess_y_hot);
X	XFreePixmap(win->display, bm);
X	XFreePixmap(win->display, bmask);
X	
X	XDefineCursor(win->display,win->basewin, cur);
X
X	XMapSubwindows(win->display,win->basewin);
X	XMapRaised(win->display,win->basewin);
X
X	XSelectInput(win->display,win->basewin, KeyPressMask);
X	XSelectInput(win->display,win->boardwin,
X		     ButtonPressMask | ButtonReleaseMask | ExposureMask);
X	XSelectInput(win->display,win->recwin,
X		     ButtonReleaseMask | ExposureMask);
X	XSelectInput(win->display,win->jailwin, ExposureMask);
X	XSelectInput(win->display,win->wclockwin, ExposureMask);
X	XSelectInput(win->display,win->bclockwin, ExposureMask);
X	XSelectInput(win->display,win->messagewin,
X		     ButtonReleaseMask | ExposureMask);
X	XSelectInput(win->display,win->buttonwin,
X		     ButtonPressMask | ExposureMask);
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	return (true);
X}
X
Xstatic void
Xdrawgrid(win)
X	windata *win;
X{
X	int i;
X	XGCValues gc;
X
X	gc.function = GXcopy;
X	gc.plane_mask = AllPlanes;
X	gc.foreground = win->border.pixel;
X	gc.line_width = 0;
X	gc.line_style = LineSolid;
X	
X	XChangeGC(win->display,
X		  DefaultGC(win->display, 0),
X		  GCFunction | GCPlaneMask | GCForeground |
X		  GCLineWidth | GCLineStyle, &gc);
X	
X	/* Draw the lines... horizontal, */
X	for (i = 1; i < SIZE; i++)
X		XDrawLine(win->display, win->boardwin,
X			  DefaultGC(win->display, 0), 0,
X			  i * (SQUARE_WIDTH + BORDER_WIDTH) -
X			      BORDER_WIDTH / 2,
X			  SIZE * (SQUARE_WIDTH + BORDER_WIDTH),
X			  i * (SQUARE_WIDTH + BORDER_WIDTH) -
X			      BORDER_WIDTH / 2);
X
X	/* and vertical... */
X	for (i = 1; i < SIZE; i++)
X		XDrawLine(win->display, win->boardwin,
X			  DefaultGC(win->display, 0),
X			  i * (SQUARE_WIDTH + BORDER_WIDTH) -
X				BORDER_WIDTH / 2, 0,
X			  i * (SQUARE_WIDTH + BORDER_WIDTH) -
X			        BORDER_WIDTH / 2, 
X			  SIZE * (SQUARE_WIDTH + BORDER_WIDTH));
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	XCopyArea(win->display, win->iconpixmap, win->icon,
X		  DefaultGC(win->display, 0),
X		  0, 0, icon_width, icon_height, 0, 0);
X	return;
X}
X
END_OF_FILE
if test 25887 -ne `wc -c <'window.c'`; then
    echo shar: \"'window.c'\" unpacked with wrong size!
fi
# end of 'window.c'
fi
echo shar: End of archive 2 \(of 6\).
cp /dev/null ark2isdone
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
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
Moderator of comp.sources.x



More information about the Comp.sources.x mailing list