home *** CD-ROM | disk | FTP | other *** search
- /*
- * XBoard -- an Xt/Athena user interface for GNU Chess
- *
- * Original authors: Dan Sears and Chris Sears.
- * Enhancements (Version 2.0 and following): Tim Mann.
- * Thanks to John Chanak for the initial implementation of ICS mode.
- *
- * XBoard borrows its colors, icon and piece bitmaps from XChess
- * which was written and is copyrighted by Wayne Christopher.
- *
- * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
- * Enhancements Copyright 1992 Free Software Foundation, Inc.
- *
- * The following terms apply to Digital Equipment Corporation's copyright
- * interest in XBoard:
- * ------------------------------------------------------------------------
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Digital not be
- * used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- *
- * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * ------------------------------------------------------------------------
- *
- * This file is part of XBOARD.
- *
- * XBOARD is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY. No author or distributor accepts responsibility to anyone for
- * the consequences of using it or for whether it serves any particular
- * purpose or works at all, unless he says so in writing. Refer to the XBOARD
- * General Public License for full details.
- *
- * Everyone is granted permission to copy, modify and redistribute XBOARD, but
- * only under the conditions described in the XBOARD General Public License. A
- * copy of this license is supposed to have been given to you along with
- * XBOARD so you can know your rights and responsibilities. It should be in a
- * file named COPYING. Among other things, the copyright notice and this
- * notice must be preserved on all copies.
- * ------------------------------------------------------------------------
- *
- * See the file ChangeLog for a detailed revision history.
- */
-
- #define VERSION "2.1"
-
- #include <stdio.h>
- #include <ctype.h>
- #include <signal.h>
- #include <errno.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <time.h>
- #ifdef HAS_GETTIMEOFDAY
- #ifndef ESIX
- #include <sys/time.h>
- #endif
- #endif
- #ifdef __STDC__
- #ifndef ESIX
- #include <stdlib.h>
- #endif
- #endif
- #if defined(SYSTEM_FIVE) || defined(SYSV)
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifdef AIXV3
- #include <fcntl.h>
- #else
- #include <sys/fcntl.h>
- #endif /*AIXV3*/
- #ifdef SVR4
- #include <stropts.h>
- #ifdef sun
- #include <sys/systeminfo.h>
- #endif
- #endif
- #endif
- #if defined(__STDC__) || defined(SYSTEM_FIVE) || defined(SYSV) || defined(sun)
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #include <pwd.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Shell.h>
- #include <X11/Xaw/Dialog.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/List.h>
- #include <X11/Xaw/Label.h>
- #include <X11/Xaw/SimpleMenu.h>
- #include <X11/Xaw/SmeBSB.h>
- #include <X11/Xaw/SmeLine.h>
- #include <X11/cursorfont.h>
- #include "xboard.h"
- #include "patchlevel.h"
-
- #include "bitmaps/s_p.bm"
- #include "bitmaps/s_r.bm"
- #include "bitmaps/s_n.bm"
- #include "bitmaps/s_b.bm"
- #include "bitmaps/s_q.bm"
- #include "bitmaps/s_k.bm"
-
- #include "bitmaps/ol_p.bm"
- #include "bitmaps/ol_r.bm"
- #include "bitmaps/ol_n.bm"
- #include "bitmaps/ol_b.bm"
- #include "bitmaps/ol_q.bm"
- #include "bitmaps/ol_k.bm"
-
- #include "bitmaps/sm_s_p.bm"
- #include "bitmaps/sm_s_r.bm"
- #include "bitmaps/sm_s_n.bm"
- #include "bitmaps/sm_s_b.bm"
- #include "bitmaps/sm_s_q.bm"
- #include "bitmaps/sm_s_k.bm"
-
- #include "bitmaps/sm_ol_p.bm"
- #include "bitmaps/sm_ol_r.bm"
- #include "bitmaps/sm_ol_n.bm"
- #include "bitmaps/sm_ol_b.bm"
- #include "bitmaps/sm_ol_q.bm"
- #include "bitmaps/sm_ol_k.bm"
-
- #include "bitmaps/xs_s_p.bm"
- #include "bitmaps/xs_s_r.bm"
- #include "bitmaps/xs_s_n.bm"
- #include "bitmaps/xs_s_b.bm"
- #include "bitmaps/xs_s_q.bm"
- #include "bitmaps/xs_s_k.bm"
-
- #include "bitmaps/xs_ol_p.bm"
- #include "bitmaps/xs_ol_r.bm"
- #include "bitmaps/xs_ol_n.bm"
- #include "bitmaps/xs_ol_b.bm"
- #include "bitmaps/xs_ol_q.bm"
- #include "bitmaps/xs_ol_k.bm"
-
- #include "bitmaps/icon.bm"
-
- int establish P((char *host, int port));
- void read_from_player P((caddr_t client_data, int *file_num, XtInputId *id));
- void read_from_ics P((caddr_t client_data, int *file_num, XtInputId *id));
- void main P((int argc, char **argv));
- void CreateGCs P((void));
- void CreatePieces P((void));
- void CreatePieceMenus P((void));
- char *FindFont P((char *pattern, int targetPxlSize));
- void PieceMenuPopup P((Widget w, XEvent *event,
- String *params, Cardinal *num_params));
- static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
- static void SetWhiteToPlay P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- static void SetBlackToPlay P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- void ReadBitmap P((String name, Pixmap *pm, char large_bits[],
- char medium_bits[], char small_bits[]));
- void CreateGrid P((void));
- int EventToSquare P((int x));
- ChessSquare CharToPiece P((int c));
- char PieceToChar P((ChessSquare p));
- ChessSquare PromoPiece P((ChessMove move_type));
- ChessMove CoordsToAlgebraic P((int fromX, int fromY, int toX, int toY,
- int promoChar, int currentBoardIndex,
- char out[MOVE_LEN]));
- void DrawSquare P((int row, int column, ChessSquare piece));
- void EventProc P((Widget widget, caddr_t unused, XEvent *event));
- void DrawPosition P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- void InitPosition P((int/*Boolean*/ redraw));
- void CopyBoard P((Board to, Board from));
- Boolean CompareBoards P((Board board1, Board board2));
- void SendCurrentBoard P((FILE *fp));
- void SendBoard P((FILE *fp, Board board));
- void HandleUserMove P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- void FinishUserMove P((ChessMove move_type, int to_x, int to_y));
- void HandleMachineMove P((char *message, FILE *fp));
- void LoadGameLoop P((void));
- Boolean LoadGameOneMove P((void));
- void ApplyMove P((ChessMove *move_type, int from_x, int from_y,
- int to_x, int to_y, Board board));
- void MakeMove P((ChessMove *move_type, int from_x, int from_y,
- int to_x, int to_y));
- void InitChessProgram P((char *host_name, char *program_name, int *pid,
- FILE **to, FILE **from, XtIntervalId *xid,
- int *sendTime));
- void GameEnds P((char *message));
- void ShutdownChessPrograms P((char *message));
- void CommentPopUp P((char *label));
- void CommentPopDown P((void));
- void FileNamePopUp P((char *label, char *def,
- Boolean (*proc)(char *name)));
- void FileNameCallback P((Widget w, XtPointer client_data,
- XtPointer call_data));
- void FileNameAction P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- void PromotionPopUp P((ChessSquare piece, int to_x, int to_y));
- void PromotionCallback P((Widget w, XtPointer client_data,
- XtPointer call_data));
- void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
- void ModeHighlight P((void));
- void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void DeclineDrawProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- Boolean LoadGame P((char *name));
- void MachineBlackProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
- void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void Reset P((int/*Boolean*/ redraw));
- void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- Boolean LoadPosition P((char *name));
- void LoadPositionProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- void MachineWhiteProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- Boolean SaveGame P((char *name));
- void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void SwitchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void EditPositionProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- void EditPositionDone P((void));
- void ForceProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- Boolean SavePosition P((char *name));
- void SavePositionProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
- void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
- void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
- void PrintOpponents P((FILE *fp));
- void PrintPosition P((FILE *fp, int move));
- void SendToProgram P((char *message, FILE *fp));
- void ReceiveFromProgram P((FILE *fp, int *source, XtInputId *id));
- void SendSearchDepth P((FILE *fp));
- void SendTimeRemaining P((FILE *fp));
- void DisplayMessage P((char *message));
- void DisplayMove P((int moveNumber));
- void DisplayTitle P((char *title));
- void Attention P((int pid));
- void DisplayClocks P((int clock_mode));
- void DisplayTimerLabel P((Widget w, char *color, long timer));
- char *TimeString P((long tm));
- void Usage P((void));
- char *StrStr P((char *string, char *match));
- int StrCaseCmp P((char *s1, char *s2));
- int ToLower P((int c));
- int ToUpper P((int c));
- #if defined(SYSTEM_FIVE) || defined(SYSV)
- char *PseudoTTY P((int *ptyv));
- #else
- void CatchPipeSignal P((int dummy));
- #endif
- extern int yylex P((void));
- extern int yynewfile P((void));
- extern ChessMove yylexstr P((int boardIndex, char *s, char **next));
- extern ChessMove LegalityTest P((int whiteOnMove, Board board,
- int rf, int ff, int rt, int ft,
- int promoChar));
- void ParseMachineMove P((char *machine_move, int move_num,
- ChessMove *move_type, int *from_x, int *from_y,
- int *to_x, int *to_y, char *promo_char));
- void ParseGameHistory P((char *game));
- void ParseBoard8 P((char *string));
-
- /*
- * XBoard depends on Xt R4 or higher
- */
- int xtVersion = XtSpecificationRelease;
-
- int xScreen;
- Display *xDisplay;
- Window xBoardWindow;
- GC lightSquareGC, darkSquareGC, lineGC, wdPieceGC, wlPieceGC,
- bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC;
- Pixmap solidPawnBitmap, solidRookBitmap, solidKnightBitmap,
- solidBishopBitmap, solidQueenBitmap, solidKingBitmap,
- outlinePawnBitmap, outlineRookBitmap, outlineKnightBitmap,
- outlineBishopBitmap, outlineQueenBitmap, outlineKingBitmap, iconPixmap;
- Widget shellWidget, formWidget, boardWidget, commandsWidget, messageWidget,
- whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[6],
- commentShell, promotionShell, whitePieceMenu, blackPieceMenu;
- XSegment gridSegments[(BOARD_SIZE + 1) * 2];
- XtIntervalId firstProgramXID = 0, secondProgramXID = 0,
- readGameXID = 0, timerXID = 0;
- Font mainFontID, coordFontID;
- XFontStruct *mainFontStruct, *coordFontStruct;
- XtAppContext appContext;
- Boolean (*fileProc) P((char *name));
- Position commentX = -1, commentY = -1;
-
- FILE *fromFirstProgFP, *toFirstProgFP, *fromSecondProgFP,
- *toSecondProgFP, *gameFileFP, *lastMsgFP;
- int currentMove = 0, forwardMostMove = 0, backwardMostMove = 0,
- firstProgramPID = 0, secondProgramPID = 0, telnetPID = 0,
- squareSize = LARGE_SQUARE_SIZE, fromX = -1,
- fromY = -1, firstMove = True, flipView = False,
- commentUp = False, filenameUp = False,
- blackPlaysFirst = False, startedFromSetupPosition = False,
- promotionUp = False, searchTime = 0, pmFromX = -1, pmFromY = -1,
- whiteFlag = False, blackFlag = False, maybeThinking = False,
- ics_input = -1, ics_output = -1, ics_user_moved = 0, ics_gamenum = -1,
- ics_getting_history = False;
- int firstSendTime = 2, secondSendTime = 2; /* 0=don't, 1=do, 2=test first*/
- IcsMode ics_mode = IcsIdle;
- Pixel timerForegroundPixel, timerBackgroundPixel;
- MatchMode matchMode = MatchFalse;
- GameMode gameMode = BeginningOfGame, lastGameMode = BeginningOfGame,
- pausePreviousMode = BeginningOfGame;
- BoardSize boardSize = Large;
- char moveList[MAX_MOVES][MOVE_LEN], parseList[MAX_MOVES][MOVE_LEN * 2],
- ptyname[24], *chessDir, *programName, ics_black[32], ics_white[32],
- endMessage[MOVE_LEN * 4];
-
- long whiteTimeRemaining, blackTimeRemaining, timeControl;
- long timeRemaining[2][MAX_MOVES];
- extern char currentMoveString[];
- extern char yytext[];
- extern int yyboardindex;
-
- Board boards[MAX_MOVES], initialPosition = {
- { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen,
- WhiteKing, WhiteBishop, WhiteKnight, WhiteRook },
- { WhitePawn, WhitePawn, WhitePawn, WhitePawn,
- WhitePawn, WhitePawn, WhitePawn, WhitePawn },
- { EmptySquare, EmptySquare, EmptySquare, EmptySquare,
- EmptySquare, EmptySquare, EmptySquare, EmptySquare },
- { EmptySquare, EmptySquare, EmptySquare, EmptySquare,
- EmptySquare, EmptySquare, EmptySquare, EmptySquare },
- { EmptySquare, EmptySquare, EmptySquare, EmptySquare,
- EmptySquare, EmptySquare, EmptySquare, EmptySquare },
- { EmptySquare, EmptySquare, EmptySquare, EmptySquare,
- EmptySquare, EmptySquare, EmptySquare, EmptySquare },
- { BlackPawn, BlackPawn, BlackPawn, BlackPawn,
- BlackPawn, BlackPawn, BlackPawn, BlackPawn },
- { BlackRook, BlackKnight, BlackBishop, BlackQueen,
- BlackKing, BlackBishop, BlackKnight, BlackRook }
- };
-
- String gnuButtonStrings[] = {
- "Quit", "Machine Black", "Load Game", "Forward",
- "Reset", "Machine White", "Save Game", "Backward",
- "Flip View", "Force Moves", "Load Position", "Pause",
- "Edit Position", "Two Machines", "Save Position", "Hint"
- };
- /* must be in same order as buttonStrings! */
- XtActionProc gnuButtonProcs[] = {
- QuitProc, MachineBlackProc, LoadGameProc, ForwardProc,
- ResetProc, MachineWhiteProc, SaveGameProc, BackwardProc,
- FlipViewProc, ForceProc, LoadPositionProc, PauseProc,
- EditPositionProc, TwoMachinesProc, SavePositionProc, HintProc,
- NULL
- };
-
- String icsButtonStrings[] = {
- "Quit", "Call Flag", "Load Game", "Forward",
- "Reset", "Draw", "Save Game", "Backward",
- "Flip View", "Decline Draw", "Load Position", "Pause",
- "Edit Position", "Resign", "Save Position", ""
- };
- /* must be in same order as icsButtonStrings! */
- XtActionProc icsButtonProcs[] = {
- QuitProc, CallFlagProc, LoadGameProc, ForwardProc,
- ResetProc, DrawProc, SaveGameProc, BackwardProc,
- FlipViewProc, DeclineDrawProc, LoadPositionProc, PauseProc,
- EditPositionProc, ResignProc, SavePositionProc, NothingProc,
- NULL
- };
-
- String *buttonStrings;
- XtActionProc *buttonProcs;
- int buttonCount;
-
- #define PIECE_MENU_SIZE 10
- String pieceMenuStrings[PIECE_MENU_SIZE] = {
- "----", "Pawn", "Knight", "Bishop", "Rook", "Queen", "King",
- "----", "Empty square", "Clear board"
- };
- /* must be in same order as PieceMenuStrings! */
- ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
- { (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
- WhiteRook, WhiteQueen, WhiteKing,
- (ChessSquare) 0, EmptySquare, ClearBoard },
- { (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
- BlackRook, BlackQueen, BlackKing,
- (ChessSquare) 0, EmptySquare, ClearBoard },
- };
-
- Arg shellArgs[] = {
- { XtNwidth, 0 },
- { XtNheight, 0 },
- { XtNminWidth, 0 },
- { XtNminHeight, 0 },
- { XtNmaxWidth, 0 },
- { XtNmaxHeight, 0 }
- };
-
- Arg boardArgs[] = {
- { XtNborderWidth, 0 },
- { XtNwidth, LINE_GAP + BOARD_SIZE * (LARGE_SQUARE_SIZE + LINE_GAP) },
- { XtNheight, LINE_GAP + BOARD_SIZE * (LARGE_SQUARE_SIZE + LINE_GAP) }
- };
-
- Arg messageArgs[] = {
- { XtNborderWidth, 0 },
- { XtNjustify, (XtArgVal) XtJustifyLeft },
- { XtNlabel, (XtArgVal) "starting..." }
- };
-
- Arg timerArgs[] = {
- { XtNborderWidth, 0 },
- { XtNjustify, (XtArgVal) XtJustifyLeft }
- };
-
- Arg titleArgs[] = {
- { XtNborderWidth, 0 },
- { XtNjustify, (XtArgVal) XtJustifyLeft }
- };
-
- typedef struct {
- Pixel whitePieceColor;
- Pixel blackPieceColor;
- Pixel lightSquareColor;
- Pixel darkSquareColor;
- int movesPerSession;
- String initString;
- String whiteString;
- String blackString;
- String firstChessProgram;
- String secondChessProgram;
- Boolean noChessProgram;
- String firstHost;
- String secondHost;
- String solidPawnBitmap;
- String solidRookBitmap;
- String solidBishopBitmap;
- String solidKnightBitmap;
- String solidQueenBitmap;
- String solidKingBitmap;
- String outlinePawnBitmap;
- String outlineRookBitmap;
- String outlineBishopBitmap;
- String outlineKnightBitmap;
- String outlineQueenBitmap;
- String outlineKingBitmap;
- String remoteShell;
- float timeDelay;
- String timeControl;
- Boolean icsActive;
- String icsHost;
- int icsPort;
- Boolean useTelnet;
- String telnetProgram;
- String gateway;
- String loadGameFile;
- String saveGameFile;
- Boolean autoSaveGames;
- String loadPositionFile;
- String savePositionFile;
- String matchMode;
- Boolean monoMode;
- Boolean debugMode;
- Boolean clockMode;
- String boardSize;
- Boolean Iconic;
- String searchTime;
- int searchDepth;
- Boolean showCoords;
- String mainFont;
- String coordFont;
- Boolean ringBellAfterMoves;
- Boolean autoCallFlag;
- int borderXoffset;
- int borderYoffset;
- } AppData, *AppDataPtr;
-
- AppData appData;
-
- XtResource clientResources[] = {
- { "whitePieceColor", "WhitePieceColor", XtRPixel, sizeof(Pixel),
- XtOffset(AppDataPtr, whitePieceColor), XtRString,
- WHITE_PIECE_COLOR },
- { "blackPieceColor", "BlackPieceColor", XtRPixel, sizeof(Pixel),
- XtOffset(AppDataPtr, blackPieceColor), XtRString,
- BLACK_PIECE_COLOR },
- { "lightSquareColor", "LightSquareColor", XtRPixel,
- sizeof(Pixel), XtOffset(AppDataPtr, lightSquareColor),
- XtRString, LIGHT_SQUARE_COLOR },
- { "darkSquareColor", "DarkSquareColor", XtRPixel, sizeof(Pixel),
- XtOffset(AppDataPtr, darkSquareColor), XtRString,
- DARK_SQUARE_COLOR },
- { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
- (XtPointer) MOVES_PER_SESSION },
- { "initString", "initString", XtRString, sizeof(String),
- XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },
- { "whiteString", "whiteString", XtRString, sizeof(String),
- XtOffset(AppDataPtr, whiteString), XtRString, WHITE_STRING },
- { "blackString", "blackString", XtRString, sizeof(String),
- XtOffset(AppDataPtr, blackString), XtRString, BLACK_STRING },
- { "firstChessProgram", "firstChessProgram", XtRString,
- sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
- XtRString, FIRST_CHESS_PROGRAM },
- { "secondChessProgram", "secondChessProgram", XtRString,
- sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
- XtRString, SECOND_CHESS_PROGRAM },
- { "noChessProgram", "noChessProgram", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
- XtRImmediate, (XtPointer) False },
- { "firstHost", "firstHost", XtRString, sizeof(String),
- XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },
- { "secondHost", "secondHost", XtRString, sizeof(String),
- XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
- { "solidPawnBitmap", "solidPawnBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, solidPawnBitmap),
- XtRString, "" },
- { "solidRookBitmap", "solidRookBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, solidRookBitmap),
- XtRString, "" },
- { "solidKnightBitmap", "solidKnightBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, solidKnightBitmap),
- XtRString, "" },
- { "solidBishopBitmap", "solidBishopBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, solidBishopBitmap),
- XtRString, "" },
- { "solidQueenBitmap", "solidQueenBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, solidQueenBitmap),
- XtRString, "" },
- { "solidKingBitmap", "solidKingBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, solidKingBitmap),
- XtRString, "" },
- { "outlinePawnBitmap", "outlinePawnBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, outlinePawnBitmap),
- XtRString, "" },
- { "outlineRookBitmap", "outlineRookBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, outlineRookBitmap),
- XtRString, "" },
- { "outlineKnightBitmap", "outlineKnightBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, outlineKnightBitmap),
- XtRString, "" },
- { "outlineBishopBitmap", "outlineBishopBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, outlineBishopBitmap),
- XtRString, "" },
- { "outlineQueenBitmap", "outlineQueenBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, outlineQueenBitmap),
- XtRString, "" },
- { "outlineKingBitmap", "outlineKingBitmap", XtRString,
- sizeof(String), XtOffset(AppDataPtr, outlineKingBitmap),
- XtRString, "" },
- { "remoteShell", "remoteShell", XtRString, sizeof(String),
- XtOffset(AppDataPtr, remoteShell), XtRString, "rsh" },
- { "timeDelay", "timeDelay", XtRFloat, sizeof(float),
- XtOffset(AppDataPtr, timeDelay), XtRString,
- (XtPointer) TIME_DELAY },
- { "timeControl", "timeControl", XtRString, sizeof(String),
- XtOffset(AppDataPtr, timeControl), XtRString,
- (XtPointer) TIME_CONTROL },
- { "internetChessServerMode", "internetChessServerMode",
- XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, icsActive), XtRImmediate,
- (XtPointer) False },
- { "internetChessServerHost", "internetChessServerHost",
- XtRString, sizeof(String),
- XtOffset(AppDataPtr, icsHost),
- XtRString, (XtPointer) ICS_HOST },
- { "internetChessServerPort", "internetChessServerPort",
- XtRInt, sizeof(int),
- XtOffset(AppDataPtr, icsPort), XtRImmediate,
- (XtPointer) ICS_PORT },
- { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, useTelnet), XtRImmediate,
- (XtPointer) False },
- { "telnetProgram", "telnetProgram", XtRString, sizeof(String),
- XtOffset(AppDataPtr, telnetProgram), XtRString, "telnet" },
- { "gateway", "gateway", XtRString, sizeof(String),
- XtOffset(AppDataPtr, gateway), XtRString, "" },
- { "loadGameFile", "loadGameFile", XtRString, sizeof(String),
- XtOffset(AppDataPtr, loadGameFile), XtRString, "" },
- { "saveGameFile", "saveGameFile", XtRString, sizeof(String),
- XtOffset(AppDataPtr, saveGameFile), XtRString, "" },
- { "autoSaveGames", "autoSaveGames", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
- XtRImmediate, (XtPointer) False },
- { "loadPositionFile", "loadPositionFile", XtRString,
- sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
- XtRString, "" },
- { "savePositionFile", "savePositionFile", XtRString,
- sizeof(String), XtOffset(AppDataPtr, savePositionFile),
- XtRString, "" },
- { "matchMode", "matchMode", XtRString, sizeof(String),
- XtOffset(AppDataPtr, matchMode), XtRString, MATCH_MODE },
- { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, monoMode), XtRImmediate,
- (XtPointer) False },
- { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, debugMode), XtRImmediate,
- (XtPointer) False },
- { "Iconic", "Iconic", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, Iconic), XtRImmediate,
- (XtPointer) False },
- { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, clockMode), XtRImmediate,
- (XtPointer) True },
- { "autoCallFlag", "autoCallFlag", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
- XtRImmediate, (XtPointer) False },
- { "boardSize", "boardSize", XtRString, sizeof(String),
- XtOffset(AppDataPtr, boardSize), XtRString, DEFAULT_SIZE },
- { "searchTime", "searchTime", XtRString, sizeof(String),
- XtOffset(AppDataPtr, searchTime), XtRString,
- (XtPointer) "" },
- { "searchDepth", "searchDepth", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, searchDepth), XtRImmediate,
- (XtPointer) 0 },
- { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, showCoords), XtRImmediate,
- (XtPointer) False },
- { "mainFont", "mainFont", XtRString, sizeof(String),
- XtOffset(AppDataPtr, mainFont), XtRString, MAIN_FONT },
- { "coordFont", "coordFont", XtRString, sizeof(String),
- XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },
- { "ringBellAfterMoves", "ringBellAfterMoves",
- XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, ringBellAfterMoves),
- XtRImmediate, (XtPointer) False },
- { "borderXoffset", "borderXoffset", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, borderXoffset), XtRImmediate,
- (XtPointer) BORDER_X_OFFSET },
- { "borderYoffset", "borderYOffset", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, borderYoffset), XtRImmediate,
- (XtPointer) BORDER_Y_OFFSET },
- };
-
- Pixmap *pieceToSolid[] = {
- &solidPawnBitmap, &solidRookBitmap, &solidKnightBitmap,
- &solidBishopBitmap, &solidQueenBitmap, &solidKingBitmap,
- &solidPawnBitmap, &solidRookBitmap, &solidKnightBitmap,
- &solidBishopBitmap, &solidQueenBitmap, &solidKingBitmap
- };
-
- Pixmap *pieceToOutline[] = {
- &outlinePawnBitmap, &outlineRookBitmap, &outlineKnightBitmap,
- &outlineBishopBitmap, &outlineQueenBitmap, &outlineKingBitmap,
- &outlinePawnBitmap, &outlineRookBitmap, &outlineKnightBitmap,
- &outlineBishopBitmap, &outlineQueenBitmap, &outlineKingBitmap
- };
-
- char pieceToChar[] = {
- 'P', 'R', 'N', 'B', 'Q', 'K',
- 'p', 'r', 'n', 'b', 'q', 'k', '.'
- };
-
- XrmOptionDescRec shellOptions[] = {
- { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
- { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
- { "-internetChessServerMode", "internetChessServerMode",
- XrmoptionSepArg, NULL },
- { "-ics", "internetChessServerMode", XrmoptionSepArg, NULL },
- { "-internetChessServerPort", "internetChessServerPort",
- XrmoptionSepArg, NULL },
- { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
- { "-internetChessServerHost", "internetChessServerHost",
- XrmoptionSepArg, NULL },
- { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
- { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
- { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
- { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
- { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
- { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
- { "-ncp", "noChessProgram", XrmoptionSepArg, NULL },
- { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
- { "-fh", "firstHost", XrmoptionSepArg, NULL },
- { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
- { "-sh", "secondHost", XrmoptionSepArg, NULL },
- { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
- { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
- { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
- { "-td", "timeDelay", XrmoptionSepArg, NULL },
- { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
- { "-tc", "timeControl", XrmoptionSepArg, NULL },
- { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
- { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
- { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
- { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
- { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
- { "-autosave", "autoSaveGames", XrmoptionSepArg, NULL },
- { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
- { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
- { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
- { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
- { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
- { "-mm", "matchMode", XrmoptionSepArg, NULL },
- { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
- { "-mono", "monoMode", XrmoptionSepArg, NULL },
- { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
- { "-debug", "debugMode", XrmoptionSepArg, NULL },
- { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
- { "-clock", "clockMode", XrmoptionSepArg, NULL },
- { "-autoCallFlag", "autoCallFlags", XrmoptionSepArg, NULL },
- { "-autoflag", "autoCallFlag", XrmoptionSepArg, NULL },
- { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
- { "-size", "boardSize", XrmoptionSepArg, NULL },
- { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
- { "-st", "searchTime", XrmoptionSepArg, NULL },
- { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
- { "-sd", "searchDepth", XrmoptionSepArg, NULL },
- { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
- { "-coords", "showCoords", XrmoptionSepArg, NULL },
- { "-bell", "ringBellAfterMoves", XrmoptionSepArg, NULL },
- { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
- { "-iconic", "Iconic", XrmoptionNoArg, "True" }
- };
-
- XtActionsRec boardActions[] = {
- { "DrawPosition", DrawPosition },
- { "HandleUserMove", HandleUserMove },
- { "ResetProc", ResetProc },
- { "LoadGameProc", LoadGameProc },
- { "QuitProc", QuitProc },
- { "ForwardProc", ForwardProc },
- { "BackwardProc", BackwardProc },
- { "PauseProc", PauseProc },
- { "Iconify", Iconify },
- { "FileNameAction", FileNameAction },
- { "PieceMenuPopup", PieceMenuPopup },
- { "SetWhiteToPlay", SetWhiteToPlay },
- { "SetBlackToPlay", SetBlackToPlay }
- };
-
- char translationsTable[] =
- "<Expose>: DrawPosition() \n \
- <Btn1Down>: HandleUserMove() \n \
- <Btn1Up>: HandleUserMove() \n \
- <Btn2Down>: XawPositionSimpleMenu(menuW) PieceMenuPopup(menuW) \n \
- <Btn3Down>: XawPositionSimpleMenu(menuB) PieceMenuPopup(menuB) \n \
- <Key>r: ResetProc() \n \
- <Key>R: ResetProc() \n \
- <Key>g: LoadGameProc() \n \
- <Key>G: LoadGameProc() \n \
- <Key>q: QuitProc() \n \
- <Key>Q: QuitProc() \n \
- <Message>WM_PROTOCOLS: QuitProc() \n \
- <Key>f: ForwardProc() \n \
- <Key>F: ForwardProc() \n \
- <Key>b: BackwardProc() \n \
- <Key>B: BackwardProc() \n \
- <Key>p: PauseProc() \n \
- <Key>P: PauseProc() \n \
- <Key>i: Iconify() \n \
- <Key>I: Iconify() \n \
- <Key>c: Iconify() \n \
- <Key>C: Iconify() \n";
-
- char whiteTranslations[] = "<BtnDown>: SetWhiteToPlay()\n";
- char blackTranslations[] = "<BtnDown>: SetBlackToPlay()\n";
-
- String xboardResources[] = {
- DEFAULT_FONT,
- "*Dialog*value.translations: #override \\n <Key>Return: FileNameAction()",
- NULL
- };
-
- void main(argc, argv)
- int argc;
- char **argv;
- {
- int ok, i, mainFontPxlSize, coordFontPxlSize;
- int min, sec, matched;
- XSetWindowAttributes window_attributes;
- char buf[MSG_SIZ];
- Arg args[10];
- Dimension timerWidth, boardWidth, commandsWidth, w, h;
- XFontStruct *labelFontStruct;
-
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
- programName = strrchr(argv[0], '/');
- if (programName == NULL)
- programName = argv[0];
- else
- programName++;
-
- shellWidget =
- XtAppInitialize(&appContext, "XBoard", shellOptions,
- XtNumber(shellOptions), &argc, argv,
- xboardResources, NULL, 0);
- if (argc > 1)
- Usage();
-
- if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
- chessDir = ".";
- } else {
- if (chdir(chessDir) != 0) {
- fprintf(stderr, "%s: can't cd to CHESSDIR: ", programName);
- perror(chessDir);
- exit(1);
- }
- }
-
- XtGetApplicationResources(shellWidget, &appData, clientResources,
- XtNumber(clientResources), NULL, 0);
-
- /*
- * Determine matchMode state -- poor man's resource converter
- */
- if (StrCaseCmp(appData.matchMode, "Init") == 0)
- matchMode = MatchInit;
- else if (StrCaseCmp(appData.matchMode, "Position") == 0)
- matchMode = MatchPosition;
- else if (StrCaseCmp(appData.matchMode, "Opening") == 0)
- matchMode = MatchOpening;
- else if (StrCaseCmp(appData.matchMode, "False") == 0)
- matchMode = MatchFalse;
- else {
- fprintf(stderr, "%s: bad matchMode option %s\n",
- programName, appData.matchMode);
- Usage();
- }
-
- /*
- * Parse internet chess server status
- */
- if (appData.icsActive) {
- ok = establish(appData.icsHost,
- (unsigned short)appData.icsPort);
- if (ok == -1) {
- fprintf(stderr,
- "%s: could not connect to host %s, port %d: ",
- programName, appData.icsHost, appData.icsPort);
- perror("");
- exit(1);
- }
- appData.noChessProgram = True;
- buttonStrings = icsButtonStrings;
- buttonProcs = icsButtonProcs;
- buttonCount = XtNumber(icsButtonStrings);
- } else {
- buttonStrings = gnuButtonStrings;
- buttonProcs = gnuButtonProcs;
- buttonCount = XtNumber(gnuButtonStrings);
- }
-
- /*
- * Parse timeControl resource
- */
- matched = sscanf(appData.timeControl, "%d:%d", &min, &sec);
- if (matched == 1) {
- timeControl = min * 60 * 1000;
- } else if (matched == 2) {
- timeControl = (min * 60 + sec) * 1000;
- } else {
- fprintf(stderr, "%s: bad timeControl option %s\n",
- programName, appData.timeControl);
- Usage();
- }
- if (appData.icsActive) timeControl = 0;
-
- /*
- * Parse searchTime resource
- */
- if (*appData.searchTime != NULLCHAR) {
- matched = sscanf(appData.searchTime, "%d:%d", &min, &sec);
- if (matched == 1) {
- searchTime = min * 60;
- } else if (matched == 2) {
- searchTime = min * 60 + sec;
- } else {
- fprintf(stderr, "%s: bad searchTime option %s\n",
- programName, appData.searchTime);
- Usage();
- }
- }
-
- /*
- * Determine boardSize
- */
- if (StrCaseCmp(appData.boardSize, "Large") == 0)
- boardSize = Large;
- else if (StrCaseCmp(appData.boardSize, "Medium") == 0)
- boardSize = Medium;
- else if (StrCaseCmp(appData.boardSize, "Small") == 0)
- boardSize = Small;
- else {
- fprintf(stderr, "%s: bad boardSize option %s\n",
- programName, appData.boardSize);
- Usage();
- }
- xDisplay = XtDisplay(shellWidget);
- xScreen = DefaultScreen(xDisplay);
- if (((DisplayWidth(xDisplay, xScreen) < 800) ||
- (DisplayHeight(xDisplay, xScreen) < 800))
- && (boardSize == Large)) {
- boardSize = Medium;
- }
- switch (boardSize) {
- case Small:
- squareSize = SMALL_SQUARE_SIZE;
- mainFontPxlSize = 11;
- coordFontPxlSize = 10;
- break;
- case Medium:
- squareSize = MEDIUM_SQUARE_SIZE;
- mainFontPxlSize = 17;
- coordFontPxlSize = 12;
- break;
- case Large:
- squareSize = LARGE_SQUARE_SIZE;
- mainFontPxlSize = 17;
- coordFontPxlSize = 14;
- break;
- }
- boardWidth = LINE_GAP + BOARD_SIZE * (squareSize + LINE_GAP);
- XtSetArg(boardArgs[1], XtNwidth, boardWidth);
- XtSetArg(boardArgs[2], XtNheight,
- LINE_GAP + BOARD_SIZE * (squareSize + LINE_GAP));
-
- /*
- * Determine what fonts to use.
- */
- appData.mainFont = FindFont(appData.mainFont, mainFontPxlSize);
- mainFontID = XLoadFont(xDisplay, appData.mainFont);
- mainFontStruct = XQueryFont(xDisplay, mainFontID);
- appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
- coordFontID = XLoadFont(xDisplay, appData.coordFont);
- coordFontStruct = XQueryFont(xDisplay, coordFontID);
-
- if ((*appData.searchTime != NULLCHAR) || (appData.searchDepth > 0)
- || appData.noChessProgram)
- appData.clockMode = False;
- if (appData.icsActive) appData.clockMode = True;
-
- /*
- * Detect if there are not enough colors are available and adapt.
- */
- if (DefaultDepth(xDisplay, xScreen) <= 2)
- appData.monoMode = True;
-
- /*
- * widget hierarchy
- */
- formWidget =
- XtCreateManagedWidget("form", formWidgetClass, shellWidget, NULL, 0);
-
- widgetList[0] = whiteTimerWidget =
- XtCreateWidget("white time:", labelWidgetClass,
- formWidget, timerArgs, XtNumber(timerArgs));
- XtSetArg(args[0], XtNfont, mainFontStruct);
- XtSetValues(whiteTimerWidget, args, 1);
-
- widgetList[1] = blackTimerWidget =
- XtCreateWidget("black time:", labelWidgetClass,
- formWidget, timerArgs, XtNumber(timerArgs));
- XtSetArg(args[0], XtNfont, mainFontStruct);
- XtSetValues(blackTimerWidget, args, 1);
-
- widgetList[2] = titleWidget =
- XtCreateWidget("", labelWidgetClass,
- formWidget, titleArgs, XtNumber(titleArgs));
- XtSetArg(args[0], XtNfont, mainFontStruct);
- XtSetValues(titleWidget, args, 1);
-
- widgetList[3] = messageWidget =
- XtCreateWidget("message", labelWidgetClass, formWidget,
- messageArgs, XtNumber(messageArgs));
- XtSetArg(args[0], XtNfont, mainFontStruct);
- XtSetValues(messageWidget, args, 1);
-
- i = 0;
- XtSetArg(args[i], XtNborderWidth, 0); i++;
- XtSetArg(args[i], XtNdefaultColumns, 4); i++;
- XtSetArg(args[i], XtNforceColumns, True); i++;
- XtSetArg(args[i], XtNcolumnSpacing, 12); i++;
- XtSetArg(args[i], XtNlist, (XtArgVal) buttonStrings); i++;
- XtSetArg(args[i], XtNnumberStrings, buttonCount); i++;
- XtSetArg(args[i], XtNfont, mainFontStruct); i++;
- widgetList[4] = commandsWidget =
- XtCreateWidget("commands", listWidgetClass, formWidget, args, i);
-
- widgetList[5] = boardWidget =
- XtCreateWidget("board", widgetClass, formWidget, boardArgs,
- XtNumber(boardArgs));
-
- XtManageChildren(widgetList, XtNumber(widgetList));
-
- /*
- * Calculate the width of the timer labels.
- */
- XtSetArg(args[0], XtNfont, &labelFontStruct);
- XtGetValues(whiteTimerWidget, args, 1);
- if (appData.clockMode) {
- if (timeControl == 0)
- sprintf(buf, "White: %s ", TimeString(2 * 60 * 60 * 1000));
- else
- sprintf(buf, "White: %s ", TimeString(-timeControl));
- timerWidth = XTextWidth(labelFontStruct, buf, strlen(buf) - 1);
- } else {
- timerWidth = XTextWidth(labelFontStruct, "White ", 7);
- }
- XtSetArg(args[0], XtNwidth, timerWidth);
- XtSetValues(whiteTimerWidget, args, 1);
- XtSetValues(blackTimerWidget, args, 1);
-
- XtSetArg(args[0], XtNbackground, &timerForegroundPixel);
- XtSetArg(args[1], XtNforeground, &timerBackgroundPixel);
- XtGetValues(whiteTimerWidget, args, 2);
-
- /*
- * Calculate the width of the title and message labels.
- */
- XtSetArg(args[0], XtNwidth, &commandsWidth);
- XtGetValues(commandsWidget, args, 1);
- w = (commandsWidth > boardWidth) ? commandsWidth : boardWidth;
- XtSetArg(args[0], XtNwidth, w - timerWidth*2 - 12);
- XtSetValues(titleWidget, args, 1);
- XtSetArg(args[0], XtNwidth, w - 8);
- XtSetValues(messageWidget, args, 1);
-
- /*
- * formWidget uses these constraints but they are stored
- * in the children.
- */
- XtSetArg(args[0], XtNfromHoriz, whiteTimerWidget);
- XtSetValues(blackTimerWidget, args, 1);
- XtSetArg(args[0], XtNfromHoriz, blackTimerWidget);
- XtSetValues(titleWidget, args, 1);
- XtSetArg(args[0], XtNfromVert, whiteTimerWidget);
- XtSetValues(messageWidget, args, 1);
- XtSetArg(args[0], XtNfromVert, messageWidget);
- XtSetValues(commandsWidget, args, 1);
- XtSetArg(args[0], XtNfromVert, commandsWidget);
- XtSetValues(boardWidget, args, 1);
-
- if (appData.icsActive) {
- XtAppAddInput(appContext, ics_input,
- (XtPointer) (XtInputExceptMask|XtInputReadMask),
- (XtInputCallbackProc) read_from_ics,
- (XtPointer) NULL);
- XtAppAddInput(appContext, fileno(stdin),
- (XtPointer) XtInputReadMask,
- (XtInputCallbackProc) read_from_player,
- (XtPointer) NULL);
- }
-
- XtRealizeWidget(shellWidget);
-
- xBoardWindow = XtWindow(boardWidget);
-
- /*
- * Create an icon.
- */
- iconPixmap = XCreateBitmapFromData(xDisplay, XtWindow(shellWidget),
- icon_bits, icon_width, icon_height);
- XtSetArg(args[0], XtNiconPixmap, iconPixmap);
- XtSetValues(shellWidget, args, 1);
-
- /*
- * Create a cursor for the board widget.
- */
- window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
- XChangeWindowAttributes(xDisplay, xBoardWindow,
- CWCursor, &window_attributes);
-
- /*
- * Inhibit shell resizing.
- */
- shellArgs[0].value = (XtArgVal) &w;
- shellArgs[1].value = (XtArgVal) &h;
- XtGetValues(shellWidget, shellArgs, 2);
- shellArgs[4].value = shellArgs[2].value = w;
- shellArgs[5].value = shellArgs[3].value = h;
- XtSetValues(shellWidget, &shellArgs[2], 4);
-
- CreateGCs();
- CreateGrid();
- CreatePieces();
- CreatePieceMenus();
-
- XtAddCallback(commandsWidget, XtNcallback, SelectCommand, NULL);
- XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
-
- XtSetArg(args[0], XtNtranslations,
- XtParseTranslationTable(translationsTable));
- XtSetValues(boardWidget, &args[0], 1);
- XtSetArg(args[0], XtNtranslations,
- XtParseTranslationTable(whiteTranslations));
- XtSetValues(whiteTimerWidget, &args[0], 1);
- XtSetArg(args[0], XtNtranslations,
- XtParseTranslationTable(blackTranslations));
- XtSetValues(blackTimerWidget, &args[0], 1);
-
- XtAddEventHandler(boardWidget, ExposureMask | ButtonPressMask
- | ButtonReleaseMask | Button1MotionMask | KeyPressMask,
- False, (XtEventHandler) EventProc, NULL);
-
- sprintf(buf, "xboard version %s, patchlevel %d", VERSION, PATCHLEVEL);
-
- /*
- * If there is to be a machine match, set it up.
- */
- if (matchMode != MatchFalse){
- if (appData.noChessProgram) {
- fprintf(stderr,
- "%s: can't have a match with no chess programs!\n",
- programName);
- exit(1);
- }
- DisplayMessage(buf);
- TwoMachinesProc(NULL, NULL, NULL, NULL);
- }
- else {
- Reset(True);
- DisplayMessage(buf);
- if (*appData.loadGameFile != NULLCHAR)
- LoadGame(appData.loadGameFile);
- else if (*appData.loadPositionFile != NULLCHAR)
- LoadPosition(appData.loadPositionFile);
- }
-
- XtAppMainLoop(appContext);
- }
-
- /*
- * Establish will establish a contact to a remote host.port.
- * Returns 0 if okay, -1 if not.
- */
- int establish(host, port)
- char *host;
- int port;
- {
- int s;
- char str[100];
- int to_prog[2], from_prog[2];
- struct sockaddr_in sa;
- struct hostent *hp;
- unsigned short uport;
- #if defined(SYSTEM_FIVE) || defined(SYSV)
- char *pty_name;
- #endif
-
- if (appData.useTelnet || (*appData.gateway != NULLCHAR)) {
- #if defined(SYSTEM_FIVE) || defined(SYSV)
- if ((pty_name = PseudoTTY(&to_prog[1])) == NULL) {
- fprintf(stderr, "%s: can't open pseudo-tty: ", programName);
- perror("");
- exit(1);
- }
- from_prog[0] = to_prog[1];
- to_prog[0] = from_prog[1] = open(pty_name, O_RDWR, 0);
- #ifdef SVR4
- if (ioctl (to_prog[0], I_PUSH, "ptem") == -1 ||
- ioctl (to_prog[0], I_PUSH, "ldterm") == -1 ||
- ioctl (to_prog[0], I_PUSH, "ttcompat") == -1) {
- fprintf(stderr, "%s: can't ioctl pseudo-tty: ", programName);
- perror("");
- exit(1);
- }
- #endif
- #else
- pipe(to_prog);
- pipe(from_prog);
- #endif
- if ((telnetPID = fork()) == 0) {
- dup2(to_prog[0], 0);
- dup2(from_prog[1], 1);
- close(to_prog[0]);
- close(to_prog[1]);
- close(from_prog[0]);
- close(from_prog[1]);
- dup2(1, fileno(stderr)); /* force stderr to the pipe */
-
- uport = (unsigned short) port;
- sprintf(str, "%d", uport);
- if (*appData.gateway != NULLCHAR) {
- execlp(appData.remoteShell, appData.remoteShell,
- appData.gateway, appData.telnetProgram,
- host, str, (char *) NULL);
- } else {
- execlp(appData.telnetProgram, appData.telnetProgram,
- host, str, (char *) NULL);
- }
- perror(appData.telnetProgram);
- exit(1);
- }
- close(to_prog[0]);
- close(from_prog[1]);
- ics_input = from_prog[0];
- ics_output = to_prog[1];
- } else {
- #ifdef SVR4
- memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
- #else /*!SVR4*/
- bzero((char *) &sa, sizeof(struct sockaddr_in));
- #endif
- if (!(hp = gethostbyname(host))) {
- int b0, b1, b2, b3;
- if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {
- hp = (struct hostent *) calloc(1, sizeof(struct hostent));
- hp->h_addrtype = AF_INET;
- hp->h_length = 4;
- hp->h_addr_list = (char **) calloc(2, sizeof(char *));
- hp->h_addr_list[0] = (char *) malloc(4);
- hp->h_addr_list[0][0] = b0;
- hp->h_addr_list[0][1] = b1;
- hp->h_addr_list[0][2] = b2;
- hp->h_addr_list[0][3] = b3;
- } else {
- fprintf(stderr, "%s: could not gethostbyname %s\n",
- programName, host);
- return(-1);
- }
- }
- sa.sin_family = hp->h_addrtype;
- uport = (unsigned short) port;
- sa.sin_port = htons(uport);
-
- #ifdef SVR4
- memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
- #else /*!SVR4*/
- bcopy(hp->h_addr, (char *) &sa.sin_addr, hp->h_length);
- #endif
-
- if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
- fprintf(stderr, "%s: could not get socket\n", programName);
- return(-1);
- }
- if (connect(s, (struct sockaddr *) &sa,
- sizeof(struct sockaddr_in)) < 0) {
- fprintf(stderr, "%s: could not bind socket\n", programName);
- return(-1);
- }
- ics_input = ics_output = s;
- }
- return(0);
- }
-
- void read_from_player(client_data, file_num, id)
- caddr_t client_data;
- int *file_num;
- XtInputId *id;
- {
- #define BUF_SIZE 1024
- int s = *file_num;
- static char buf[BUF_SIZE];
- int buf_len, tmp_len;
- int out_len = 0;
-
- buf_len = read(s, buf, BUF_SIZE);
-
- if (buf_len > 0) {
- while (out_len < buf_len) {
- tmp_len = write(ics_output, &buf[out_len], buf_len - out_len);
- if (tmp_len == -1) {
- fprintf(stderr, "%s: error writing to ICS: ", programName);
- perror("");
- exit(1);
- }
- out_len += tmp_len;
- }
- } else {
- fprintf(stderr, "%s: got end of file from keyboard\n", programName);
- if (telnetPID != 0) {
- if (kill(telnetPID, SIGTERM) == 0)
- wait((union wait *) 0);
- }
- exit(0);
- }
- }
-
- void SendToICS(s)
- char *s;
- {
- int i, j, tmp;
-
- i = strlen(s);
- j = 0;
-
- if (appData.debugMode)
- fprintf(stderr, "Sending to ICS: %s", s);
-
- while (j < i) {
- tmp = write(ics_output, &s[j], i - j);
- if (tmp == -1) {
- fprintf(stderr, "%s: error writing to ICS: ", programName);
- perror("");
- exit(1);
- }
- j += tmp;
- }
- }
-
-
- static int leftover_start = 0, leftover_len = 0;
- static char star_match[8][256];
-
- /* Test whether pattern is present at &buf[*index]; if so, return True,
- advance *index beyond it, and set leftover_start to the new value of
- *index; else return False. If pattern contains the character '*', it
- matches any sequence of characters not containing '\r', '\n', or the
- character following the '*' (if any), and the matched sequence(s) are
- copied into star_match. The pattern must not contain '\r' or '\n'.
- */
- Boolean looking_at(buf, index, pattern)
- char *buf;
- int *index;
- char *pattern;
- {
- char *bufp = &buf[*index], *patternp = pattern;
- int star_count = 0;
- char *matchp = star_match[0];
-
- for (;;) {
- if (*patternp == NULLCHAR) {
- *index = leftover_start = bufp - buf;
- *matchp = NULLCHAR;
- return True;
- }
- if (*bufp == NULLCHAR) return False;
- if (*patternp == '*') {
- if (*bufp == *(patternp + 1)) {
- *matchp = NULLCHAR;
- matchp = star_match[++star_count];
- patternp += 2;
- bufp++;
- continue;
- } else if (*bufp == '\n' || *bufp == '\r') {
- patternp++;
- if (*patternp == NULLCHAR)
- continue;
- else
- return False;
- } else {
- *matchp++ = *bufp++;
- continue;
- }
- }
- if (*patternp != *bufp) return False;
- patternp++;
- bufp++;
- }
- }
-
-
- void read_from_ics(client_data, file_num, id)
- caddr_t client_data;
- int *file_num;
- XtInputId *id;
- {
- #define BUF_SIZE 1024
- #define BOARD 1
- #define MOVES 2
-
- static int started = 0;
- static char parse[20000];
- static int parse_pos;
- static char buf[BUF_SIZE + 1];
-
- char str[500];
- int i, oldi;
- int buf_len;
- int next_out;
-
- /* If last read ended with a partial line that we couldn't parse,
- prepend it to the new read and try again. */
- if (leftover_len > 0) {
- for (i=0; i<leftover_len; i++)
- buf[i] = buf[leftover_start + i];
- }
- buf_len = read(ics_input, &buf[leftover_len], BUF_SIZE - leftover_len);
- next_out = leftover_len;
-
- if (buf_len > 0) {
- buf_len += leftover_len;
- leftover_start = 0;
- buf[buf_len] = NULLCHAR;
-
- i = 0;
- while (i < buf_len) {
-
- /* Skip over what people say */
- if (looking_at(buf, &i, "shouts: *") ||
- looking_at(buf, &i, "tells you: *") ||
- looking_at(buf, &i, "says: *") ||
- looking_at(buf, &i, "whispers: *") ||
- looking_at(buf, &i, "kibitzes: *")) {
- continue;
- }
-
- if (looking_at(buf, &i,
- "a b c d e f g h") ||
- looking_at(buf, &i,
- "h g f e d c b a")) {
- /* End of board style 1 */
- SendToICS("style 8\n");
- SendToICS("refresh\n");
- continue;
- }
-
- oldi = i;
- if (looking_at(buf, &i, "#@#")) {
- started = BOARD;
- parse_pos = 0;
- fwrite(&buf[next_out], oldi - next_out, 1, stdout);
- continue;
- }
-
- if (started == BOARD && looking_at(buf, &i, "@#@")) {
- /* Board read is done */
- started = 0;
- next_out = i;
- parse[parse_pos] = NULLCHAR;
-
- /* Parse and display the board */
- ParseBoard8(parse);
-
- ics_user_moved = 0;
- continue;
- }
-
- oldi = i;
- if ((ics_getting_history || ics_mode == IcsIdle) &&
- looking_at(buf, &i, "Move ")) {
- /* Beginning of move list */
- started = MOVES;
- parse_pos = 0;
- fwrite(&buf[next_out], oldi - next_out, 1, stdout);
- continue;
- }
-
- if(looking_at(buf, &i, "% ")) {
- switch (started) {
- case 0:
- continue;
- case BOARD:
- /* Something went wrong; found a prompt while
- accumulating a board */
- started = 0;
- fprintf(stderr, "%s: error gathering board\n",
- programName);
- continue;
- case MOVES:
- started = 0;
- parse[parse_pos] = NULLCHAR;
- /* If moves came from oldmoves or moves command
- while in IcsIdle mode, load them in. If the
- game was wild, we are already in "observing -1"
- mode because we've seen the initial board;
- otherwise we enter it here.
- */
- if (ics_mode == IcsIdle) {
- Reset(False);
- ics_mode = IcsObserving;
- ics_gamenum = -1;
- ics_getting_history = True;
- }
- if (ics_mode == IcsObserving && ics_gamenum == -1) {
- ParseGameHistory(parse);
- currentMove = forwardMostMove;
- DrawPosition(boardWidget, NULL, NULL, NULL);
- DisplayClocks(ReDisplayTimers);
- sprintf(str, "%s vs. %s", ics_white, ics_black);
- DisplayTitle(str);
- ics_mode = IcsIdle;
- } else {
- ParseGameHistory(parse);
- }
- DisplayMove(currentMove - 1);
- SendToICS("\n"); /*kludge: force a prompt*/
- next_out = i;
- ics_getting_history = False;
- continue;
- }
- }
-
- if (started && i >= leftover_len) {
- /* Accumulate characters in board
- or move list*/
- if (buf[i] != '\r')
- parse[parse_pos++] = buf[i];
- }
-
- /* Start of game messages. Mostly we detect start of game
- when the first board image arrives, but we need to prime
- the pump for games we're just observing. */
- if (looking_at(buf, &i, "Adding game * to observation list")) {
- sprintf(str, "refresh %d\n", atoi(star_match[0]));
- SendToICS(str);
- continue;
- }
-
- /* Error messages */
- if (ics_user_moved) {
- if (looking_at(buf, &i, "No such command") ||
- looking_at(buf, &i, "Illegal move") ||
- looking_at(buf, &i, "Not a legal move") ||
- looking_at(buf, &i, "Your king is in check") ||
- looking_at(buf, &i, "It isn't your turn")) {
- /**** Illegal move ****/
- ics_user_moved = 0;
- if (forwardMostMove > backwardMostMove) {
- currentMove = --forwardMostMove;
- DisplayMessage("Illegal move");
- DrawPosition(boardWidget, NULL, NULL, NULL);
- DisplayClocks(SwitchTimers);
- }
- continue;
- }
- }
-
- if (looking_at(buf, &i, "You and your opponent still have time")) {
- /* We must have called his flag a little too soon */
- whiteFlag = blackFlag = False;
- continue;
- }
-
- /* End-of-game messages */
- if (looking_at(buf, &i, "{Game * (* vs. *)* * *}")) {
- /* New style generic game start/end messages */
- /* star_match[0] is the game number */
- /* [1] is the white player's name */
- /* [2] is the black player's name */
- /* [3] is either ":" or empty (don't care) */
- /* [4] is usually the loser's name or a noise word */
- /* [5] contains the reason for the game end */
- int gamenum = atoi(star_match[0]);
- char *white = star_match[1];
- char *loser = star_match[4];
- char *why = star_match[5];
-
- if (ics_gamenum != gamenum) continue;
-
- if (StrStr(why, "checkmate")) {
- if (strcmp(loser, white) == 0)
- GameEnds("Black mates");
- else
- GameEnds("White mates");
- } else if (StrStr(why, "resign")) {
- if (strcmp(loser, white) == 0)
- GameEnds("White resigns");
- else
- GameEnds("Black resigns");
- } else if (StrStr(why, "forfeits on time")) {
- if (strcmp(loser, white) == 0)
- GameEnds("Black wins on time");
- else
- GameEnds("White wins on time");
- } else if (StrStr(why, "stalemate")) {
- GameEnds("Stalemate");
- } else if (StrStr(why, "drawn by mutual agreement")) {
- GameEnds("Draw agreed");
- } else if (StrStr(why, "repetition")) {
- GameEnds("Draw by repetition");
- } else if (StrStr(why, "50")) {
- GameEnds("Draw (50 move rule)");
- } else if (StrStr(why, "neither player has mating")) {
- GameEnds("Draw (insufficient material)");
- } else if (StrStr(why, "no material")) {
- GameEnds("Draw (insufficient material to win on time)");
- } else if (StrStr(why, "time")) {
- GameEnds("Draw (both players ran out of time)");
- } else if (StrStr(why, "disconnected and forfeits")) {
- /* in this case the word "abuser" preceded the loser */
- loser = why;
- why = strchr(loser, ' ');
- *why++ = NULLCHAR;
- if (strcmp(loser, white) == 0)
- GameEnds("Black wins (forfeit)");
- else
- GameEnds("White wins (forfeit)");
- } else if (StrStr(why, "assert")) {
- /* "loser" is actually the winner in this case */
- if (strcmp(loser, white) == 0)
- GameEnds("White asserts a win");
- else
- GameEnds("Black asserts a win");
- } else if (StrStr(why, "aborted")) {
- DisplayClocks(StopTimers);
- DisplayMessage("Game aborted");
- ics_mode = IcsIdle;
- ics_gamenum = -1;
- ics_user_moved = False;
- } else if (StrStr(why, "removed")) {
- DisplayClocks(StopTimers);
- DisplayMessage("Game aborted");
- ics_mode = IcsIdle;
- ics_gamenum = -1;
- ics_user_moved = False;
- } else if (StrStr(why, "adjourn")) {
- DisplayClocks(StopTimers);
- DisplayMessage("Game adjourned");
- ics_mode = IcsIdle;
- ics_gamenum = -1;
- ics_user_moved = False;
- }
- continue;
- }
-
- if (looking_at(buf, &i, "Removing game * from observation list")) {
- if (ics_mode == IcsObserving &&
- atoi(star_match[0]) == ics_gamenum)
- {
- DisplayClocks(StopTimers);
- ics_mode = IcsIdle;
- ics_gamenum = -1;
- ics_user_moved = False;
- }
- continue;
- }
-
- /* Advance leftover_start past any newlines we find,
- so only partial lines can get reparsed */
- if (looking_at(buf, &i, "\n")) continue;
- if (looking_at(buf, &i, "\r")) continue;
-
- i++; /* skip unparsed character and loop back */
- }
-
- if (started == 0)
- fwrite(&buf[next_out], i - next_out, 1, stdout);
-
- leftover_len = buf_len - leftover_start;
- /* if buffer ends with something we couldn't parse,
- reparse it after appending the next read */
-
- } else if (buf_len == 0) {
- fprintf(stderr, "%s: connection closed by ICS\n", programName);
- if (telnetPID != 0) {
- if (kill(telnetPID, SIGTERM) == 0)
- wait((union wait *) 0);
- }
- exit(0);
- } else {
- fprintf(stderr, "%s: error reading from ICS: ", programName);
- perror("");
- exit(1);
- }
- }
-
- /*
- ICS board style 8 looks like this:
-
- #@#000observer :aaa :RNBQKBNRPPPPPPPP pppppppprnbqkbnr001W39390360003600@#@
-
- Information offsets, descriptions and lengths:
- +3 Game # (3)
- +6 White's name (16 + ':' = 17)
- +23 Black's name (16 + ':' = 17)
- +40 Board (64)
- +104 Move # (3)
- +107 Whose move (1)
- +108 White Strength (2)
- +110 Black Strength (2)
- +112 White Time (5)
- +117 Black Time (5)
- +122 Move string (variable
- A "*" instead of a ":" after the name implies that the person using xboard
- is playing the game.
- The move string is either empty or consists of a move followed by
- elapsed time in parentheses.
- The pattern defined below doesn't include the #@# and @#@ brackets,
- and it assumes the board string is null-terminated. ParseBoard8's
- caller takes care of this.
- */
-
- #define PATTERN "%3d%16s %1c%16s %1c%64c%3d%1c%2d%2d%5d%5d%s %s"
-
- void ParseBoard8(string)
- char *string;
- {
- IcsMode new_ics_mode;
- int gamenum;
- int j, k, n, move_num, white_stren, black_stren, white_time, black_time;
- char playing_white, playing_black, to_play, board_chars[64];
- char move_str[500], str[500], elapsed_time[500];
- char black[32], white[32];
- Board board;
-
- if (appData.debugMode)
- fprintf(stderr, "Parsing board: %s\n", string);
-
- move_str[0] = NULLCHAR;
- elapsed_time[0] = NULLCHAR;
-
- n = sscanf(string, PATTERN, &gamenum, white, &playing_white,
- black, &playing_black, board_chars, &move_num, &to_play,
- &white_stren, &black_stren, &white_time, &black_time,
- move_str, elapsed_time);
- if (n < 12) {
- fprintf(stderr, "%s: Failed to parse board string: '%s'\n",
- programName, string);
- return;
- }
-
- if (playing_white == '*')
- new_ics_mode = IcsPlayingWhite;
- else if (playing_black == '*')
- new_ics_mode = IcsPlayingBlack;
- else
- new_ics_mode = IcsObserving;
-
- /* Convert the move number to internal form */
- move_num = (move_num - 1) * 2;
- if (to_play == 'B') move_num++;
-
- /* Deal with initial board display for wild games */
- if (gamenum == -1) {
- if (ics_mode == IcsIdle) {
- /* Initial board for "moves" or "oldmoves" output
- that we are going to parse. Go into IcsObserving
- state with ics_gamenum = -1.
- */
- Reset(False);
- ics_mode = IcsObserving;
- ics_gamenum = -1;
- ics_getting_history = True;
- } else {
- /* Ignore this board */
- return;
- }
- }
-
- /* Take action if this is the first board of a new game */
- if (gamenum != ics_gamenum) {
- if (ics_mode == IcsObserving) {
- /* Error: xboard can't handle two games at once */
- /* Stop observing the old game */
- fprintf(stderr, "%s: Aren't you currently observing game %d",
- programName, ics_gamenum);
- fprintf(stderr, "? Attempting to stop observing it.\n");
- sprintf(str, "observe %d\n", ics_gamenum);
- SendToICS(str);
- /* continue as in normal case */
- } else if (ics_mode != IcsIdle) {
- /* Error: xboard can't handle two games at once */
- if (new_ics_mode == IcsObserving) {
- /* Stop observing the new game */
- fprintf(stderr, "%s: Aren't you playing a game now? ",
- programName);
- fprintf(stderr, "Attempting to stop observing game %d.\n",
- gamenum);
- SendToICS("observe\n");
- /* ignore this board */
- return;
- } else /* new_ics_mode == IcsPlaying(White|Black) */ {
- /* Playing two games??? ICS supposedly can't do this. */
- fprintf(stderr, "%s: BUG: playing two games (%d and %d)\n",
- programName, ics_gamenum, gamenum);
- /* continue as in normal case, hoping old game is gone */
- }
- }
- /* Normal case (ics_mode == IcsIdle), or error recovered */
- Reset(False);
- if (move_num > 0) {
- /* Need to get game history */
- ics_getting_history = True;
- sprintf(str, "moves %d\n", gamenum);
- SendToICS(str);
- }
- }
-
- /* Initially flip the board to have black on the bottom iff playing
- black, but let the user change it with the Flip View button. */
- if (ics_mode == IcsIdle)
- flipView = (new_ics_mode == IcsPlayingBlack);
-
- /* Update known move number limits */
- if (ics_mode == IcsIdle) {
- forwardMostMove = backwardMostMove = currentMove = move_num;
- } else if (move_num > forwardMostMove) {
- forwardMostMove = move_num;
- if (gameMode != PauseGame)
- currentMove = move_num;
- }
-
- /* Done with values from previous mode; copy in new ones */
- ics_mode = new_ics_mode;
- ics_gamenum = gamenum;
- strcpy(ics_white, white);
- strcpy(ics_black, black);
-
- /* Parse the board */
- for (k = 0; k < 8; k++)
- for (j = 0; j < 8; j++)
- board[k][j] = CharToPiece(board_chars[k*8 + j]);
- CopyBoard(boards[move_num], board);
- if (move_num == 0) {
- startedFromSetupPosition =
- !CompareBoards(board, initialPosition);
- }
-
- /* Put the move on the move list, first converting
- to canonical algebraic form. */
- if (move_num > 0) {
- ChessMove move_type;
- int from_x, from_y, to_x, to_y;
- char promo_char;
-
- if (move_num - 1 < backwardMostMove) {
- /* We don't know what the board looked like before
- this move. Punt. */
- strcpy(parseList[move_num - 1], move_str);
- } else {
- ParseMachineMove(move_str, move_num - 1, &move_type,
- &from_x, &from_y, &to_x, &to_y, &promo_char);
-
- /* Work around ICS bug: pawn promotion is not indicated,
- even if underpromoted. Unfortunately there is no
- workaround for the same bug when it bites us in
- ParseGameHistory().
- */
- if (move_str[0] == 'P' && (to_y == 0 || to_y == 7))
- promo_char = ToLower(PieceToChar(board[to_y][to_x]));
-
- (void) CoordsToAlgebraic(from_x, from_y, to_x, to_y, promo_char,
- move_num - 1, parseList[move_num - 1]);
- strcat(parseList[move_num - 1], " ");
- strcat(parseList[move_num - 1], elapsed_time);
- }
- }
-
- if (move_num < forwardMostMove || ics_gamenum == -1) return;
-
- /* Update and display the clocks */
- timeRemaining[0][move_num] = whiteTimeRemaining = white_time * 1000;
- timeRemaining[1][move_num] = blackTimeRemaining = black_time * 1000;
- DisplayClocks(StartTimers);
-
- /* Display opponents and material strengths */
- sprintf(str, "%s (%d) vs. %s (%d)",
- ics_white, white_stren, ics_black, black_stren);
- DisplayTitle(str);
-
- /* Display the board */
- if (gameMode != PauseGame) {
- DrawPosition(boardWidget, NULL, NULL, NULL);
- DisplayMove(move_num - 1);
- if (appData.ringBellAfterMoves && !ics_user_moved)
- putc(BELLCHAR, stderr);
- }
- }
-
-
- #define abs(n) ((n)<0 ? -(n) : (n))
-
- /*
- * Find a font that matches "pattern" that is as close as
- * possible to the targetPxlSize. Prefer fonts that are k
- * pixels smaller to fonts that are k pixels larger. The
- * pattern must be in the X Consortium standard format,
- * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
- * The return value should be freed with XtFree when no
- * longer needed.
- */
- char *FindFont(pattern, targetPxlSize)
- char *pattern;
- int targetPxlSize;
- {
- char **fonts, *p, *best;
- int i, j, nfonts, minerr, err, pxlSize;
-
- fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
- if (nfonts < 1) {
- fprintf(stderr, "%s: No fonts match pattern %s\n",
- programName, pattern);
- exit(1);
- }
- best = "";
- minerr = 999999;
- for (i=0; i<nfonts; i++) {
- j = 0;
- p = fonts[i];
- if (*p != '-') continue;
- while (j < 7) {
- if (*p == NULLCHAR) break;
- if (*p++ == '-') j++;
- }
- if (j < 7) continue;
- pxlSize = atoi(p);
- if (pxlSize == targetPxlSize) {
- best = fonts[i];
- break;
- }
- err = pxlSize - targetPxlSize;
- if (abs(err) < abs(minerr) ||
- (minerr > 0 && err < 0 && -err == minerr)) {
- best = fonts[i];
- minerr = err;
- }
- }
- p = (char *) XtMalloc(strlen(best) + 1);
- strcpy(p, best);
- XFreeFontNames(fonts);
- return p;
- }
-
- void CreateGCs()
- {
- XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
- | GCBackground | GCFunction | GCPlaneMask;
- XGCValues gc_values;
-
- gc_values.plane_mask = AllPlanes;
- gc_values.line_width = LINE_GAP;
- gc_values.line_style = LineSolid;
- gc_values.function = GXcopy;
-
- gc_values.foreground = XBlackPixel(xDisplay, xScreen);
- gc_values.background = XBlackPixel(xDisplay, xScreen);
- lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.background = XWhitePixel(xDisplay, xScreen);
- coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
- XSetFont(xDisplay, coordGC, coordFontID);
-
- if (appData.monoMode) {
- gc_values.foreground = XWhitePixel(xDisplay, xScreen);
- gc_values.background = XBlackPixel(xDisplay, xScreen);
- lightSquareGC = wbPieceGC
- = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = XBlackPixel(xDisplay, xScreen);
- gc_values.background = XWhitePixel(xDisplay, xScreen);
- darkSquareGC = bwPieceGC
- = XtGetGC(shellWidget, value_mask, &gc_values);
- } else {
- gc_values.foreground = appData.lightSquareColor;
- gc_values.background = appData.darkSquareColor;
- lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = appData.darkSquareColor;
- gc_values.background = appData.lightSquareColor;
- darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = appData.whitePieceColor;
- gc_values.background = appData.darkSquareColor;
- wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = appData.whitePieceColor;
- gc_values.background = appData.lightSquareColor;
- wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = appData.blackPieceColor;
- gc_values.background = appData.darkSquareColor;
- bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = appData.blackPieceColor;
- gc_values.background = appData.lightSquareColor;
- blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
- }
- }
-
- void CreatePieces()
- {
- XSynchronize(xDisplay, True); /* Work-around for xlib/xt
- buffering bug */
-
- ReadBitmap(appData.solidPawnBitmap, &solidPawnBitmap,
- s_p_bits, sm_s_p_bits, xs_s_p_bits);
- ReadBitmap(appData.solidRookBitmap, &solidRookBitmap,
- s_r_bits, sm_s_r_bits, xs_s_r_bits);
- ReadBitmap(appData.solidKnightBitmap, &solidKnightBitmap,
- s_n_bits, sm_s_n_bits, xs_s_n_bits);
- ReadBitmap(appData.solidBishopBitmap, &solidBishopBitmap,
- s_b_bits, sm_s_b_bits, xs_s_b_bits);
- ReadBitmap(appData.solidQueenBitmap, &solidQueenBitmap,
- s_q_bits, sm_s_q_bits, xs_s_q_bits);
- ReadBitmap(appData.solidKingBitmap, &solidKingBitmap,
- s_k_bits, sm_s_k_bits, xs_s_k_bits);
-
- if (appData.monoMode) {
- ReadBitmap(appData.outlinePawnBitmap, &outlinePawnBitmap,
- ol_p_bits, sm_ol_p_bits, xs_ol_p_bits);
- ReadBitmap(appData.outlineRookBitmap, &outlineRookBitmap,
- ol_r_bits, sm_ol_r_bits, xs_ol_r_bits);
- ReadBitmap(appData.outlineKnightBitmap, &outlineKnightBitmap,
- ol_n_bits, sm_ol_n_bits, xs_ol_n_bits);
- ReadBitmap(appData.outlineBishopBitmap, &outlineBishopBitmap,
- ol_b_bits, sm_ol_b_bits, xs_ol_b_bits);
- ReadBitmap(appData.outlineQueenBitmap, &outlineQueenBitmap,
- ol_q_bits, sm_ol_q_bits, xs_ol_q_bits);
- ReadBitmap(appData.outlineKingBitmap, &outlineKingBitmap,
- ol_k_bits, sm_ol_k_bits, xs_ol_k_bits);
- }
-
- XSynchronize(xDisplay, False); /* Work-around for xlib/xt
- buffering bug */
- }
-
- void ReadBitmap(name, pm, large_bits, medium_bits, small_bits)
- String name;
- Pixmap *pm;
- char large_bits[], medium_bits[], small_bits[];
- {
- int x_hot, y_hot;
- u_int w, h;
-
- if (*name == NULLCHAR ||
- XReadBitmapFile(xDisplay, xBoardWindow, name,
- &w, &h, pm, &x_hot, &y_hot) != BitmapSuccess ||
- w != squareSize || h != squareSize) {
- switch (boardSize) {
- case Large:
- *pm = XCreateBitmapFromData(xDisplay, xBoardWindow,
- large_bits, squareSize, squareSize);
- break;
- case Medium:
- *pm = XCreateBitmapFromData(xDisplay, xBoardWindow,
- medium_bits, squareSize, squareSize);
- break;
- case Small:
- *pm = XCreateBitmapFromData(xDisplay, xBoardWindow,
- small_bits, squareSize, squareSize);
- break;
- }
- }
- }
-
- void CreateGrid()
- {
- int i;
-
- for (i = 0; i < BOARD_SIZE + 1; i++) {
- gridSegments[i].x1 = gridSegments[i + BOARD_SIZE + 1].y1 = 0;
- gridSegments[i].y1 = gridSegments[i].y2
- = LINE_GAP / 2 + (i * (squareSize + LINE_GAP));
- gridSegments[i].x2 = LINE_GAP + BOARD_SIZE *
- (squareSize + LINE_GAP);
- gridSegments[i + BOARD_SIZE + 1].x1 =
- gridSegments[i + BOARD_SIZE + 1].x2 = LINE_GAP / 2
- + (i * (squareSize + LINE_GAP));
- gridSegments[i + BOARD_SIZE + 1].y2 =
- BOARD_SIZE * (squareSize + LINE_GAP);
- }
- }
-
- void CreatePieceMenus()
- {
- int i;
- Widget entry;
- Arg args[1];
- ChessSquare selection;
-
- XtSetArg(args[0], XtNlabel, "White");
- whitePieceMenu = XtCreatePopupShell("menuW", simpleMenuWidgetClass,
- boardWidget, args, 1);
- for (i = 0; i < PIECE_MENU_SIZE; i++) {
- String item = pieceMenuStrings[i];
-
- if (strcmp(item, "----") == 0) {
- entry = XtCreateManagedWidget(item, smeLineObjectClass,
- whitePieceMenu, NULL, 0);
- } else {
- entry = XtCreateManagedWidget(item, smeBSBObjectClass,
- whitePieceMenu, NULL, 0);
- selection = pieceMenuTranslation[0][i];
- XtAddCallback(entry, XtNcallback,
- (XtCallbackProc) PieceMenuSelect,
- (caddr_t) selection);
- if (selection == WhitePawn) {
- XtSetArg(args[0], XtNpopupOnEntry, entry);
- XtSetValues(whitePieceMenu, args, 1);
- }
- }
- }
-
- XtSetArg(args[0], XtNlabel, "Black");
- blackPieceMenu = XtCreatePopupShell("menuB", simpleMenuWidgetClass,
- boardWidget, args, 1);
- for (i = 0; i < PIECE_MENU_SIZE; i++) {
- String item = pieceMenuStrings[i];
-
- if (strcmp(item, "----") == 0) {
- entry = XtCreateManagedWidget(item, smeLineObjectClass,
- blackPieceMenu, NULL, 0);
- } else {
- entry = XtCreateManagedWidget(item, smeBSBObjectClass,
- blackPieceMenu, NULL, 0);
- selection = pieceMenuTranslation[1][i];
- XtAddCallback(entry, XtNcallback,
- (XtCallbackProc) PieceMenuSelect,
- (caddr_t) selection);
- if (selection == BlackPawn) {
- XtSetArg(args[0], XtNpopupOnEntry, entry);
- XtSetValues(blackPieceMenu, args, 1);
- }
- }
- }
-
- XtRegisterGrabAction(PieceMenuPopup, True,
- (unsigned)(ButtonPressMask|ButtonReleaseMask),
- GrabModeAsync, GrabModeAsync);
- }
-
- void PieceMenuPopup(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- if (event->type != ButtonPress) return;
- if (gameMode != EditPosition) return;
-
- if (((pmFromX = EventToSquare(event->xbutton.x)) < 0) ||
- ((pmFromY = EventToSquare(event->xbutton.y)) < 0)) {
- pmFromX = pmFromY = -1;
- return;
- }
- if (flipView)
- pmFromX = BOARD_SIZE - 1 - pmFromX;
- else
- pmFromY = BOARD_SIZE - 1 - pmFromY;
-
- XtPopupSpringLoaded(XtNameToWidget(boardWidget, params[0]));
- }
-
- static void PieceMenuSelect(w, piece, junk)
- Widget w;
- ChessSquare piece;
- caddr_t junk;
- {
- if (pmFromX < 0 || pmFromY < 0) return;
- switch (piece) {
- case ClearBoard:
- for (pmFromY = 0; pmFromY < BOARD_SIZE; pmFromY++)
- for (pmFromX = 0; pmFromX < BOARD_SIZE; pmFromX++)
- boards[0][pmFromY][pmFromX] = EmptySquare;
- DrawPosition(boardWidget, NULL, NULL, NULL);
- break;
-
- case WhitePlay: /*not currently on menu*/
- SetWhiteToPlay(NULL, NULL, NULL, NULL);
- break;
-
- case BlackPlay: /*not currently on menu*/
- SetBlackToPlay(NULL, NULL, NULL, NULL);
- break;
-
- default:
- boards[0][pmFromY][pmFromX] = piece;
- DrawPosition(boardWidget, NULL, NULL, NULL);
- break;
- }
- XSync(xDisplay, False);
- }
-
- static void SetWhiteToPlay(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- if (gameMode != EditPosition) return;
- blackPlaysFirst = False;
- DisplayClocks(ReDisplayTimers); /* works because currentMove is 0 */
- }
-
- static void SetBlackToPlay(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- if (gameMode != EditPosition) return;
- blackPlaysFirst = True;
- currentMove = 1; /* kludge */
- DisplayClocks(ReDisplayTimers);
- currentMove = 0;
- }
-
- char PieceToChar(p)
- ChessSquare p;
- {
- return pieceToChar[(int) p];
- }
-
- ChessSquare CharToPiece(c)
- int c;
- {
- switch (c) {
- default:
- case '.': return EmptySquare;
- case 'P': return WhitePawn;
- case 'R': return WhiteRook;
- case 'N': return WhiteKnight;
- case 'B': return WhiteBishop;
- case 'Q': return WhiteQueen;
- case 'K': return WhiteKing;
- case 'p': return BlackPawn;
- case 'r': return BlackRook;
- case 'n': return BlackKnight;
- case 'b': return BlackBishop;
- case 'q': return BlackQueen;
- case 'k': return BlackKing;
- }
- }
-
- ChessSquare PromoPiece(move_type)
- ChessMove move_type;
- {
- switch (move_type) {
- default:
- return EmptySquare;
- case WhitePromotionQueen:
- return WhiteQueen;
- case BlackPromotionQueen:
- return BlackQueen;
- case WhitePromotionRook:
- return WhiteRook;
- case BlackPromotionRook:
- return BlackRook;
- case WhitePromotionBishop:
- return WhiteBishop;
- case BlackPromotionBishop:
- return BlackBishop;
- case WhitePromotionKnight:
- return WhiteKnight;
- case BlackPromotionKnight:
- return BlackKnight;
- }
- }
-
-
- /* Convert coordinates to normal algebraic notation.
- promoChar must be NULLCHAR or '.' if not a promotion.
- */
- ChessMove CoordsToAlgebraic(fromX, fromY, toX, toY, promoChar,
- currentBoardIndex, out)
- int fromX, fromY, toX, toY;
- int promoChar;
- int currentBoardIndex;
- char out[MOVE_LEN];
- {
- ChessSquare piece;
- ChessMove ret;
- char *outp = out;
- int i;
-
- if (promoChar == '.') promoChar = NULLCHAR;
- piece = boards[currentBoardIndex][fromY][fromX];
- switch (piece) {
- case WhitePawn:
- case BlackPawn:
- /* Pawn move */
- *outp++ = fromX + 'a';
- if (fromX == toX) {
- /* Non-capture; use style "e5" or "e8Q" */
- *outp++ = toY + '1';
- *outp++ = ToUpper(promoChar);
- *outp = NULLCHAR;
- } else {
- /* Capture; use style "exd5" or "exd8Q" */
- *outp++ = 'x';
- *outp++ = toX + 'a';
- *outp++ = toY + '1';
- *outp++ = ToUpper(promoChar);
- *outp = NULLCHAR;
- }
-
- /* Test if okay by parsing; this notation should parse
- unambiguously if the original move was legal. More
- code would be needed if we wanted the style "ed" for
- captures, since that can be ambiguous.
- */
- ret = yylexstr(currentBoardIndex, out, (char **) NULL);
- break;
-
- case WhiteKing:
- case BlackKing:
- /* Test for castling or ICS wild castling */
- /* Use style "0-0" (zero-zero) */
- if (fromY == toY &&
- fromY == ((piece == WhiteKing) ? 0 : 7) &&
- ((fromX == 4 && (toX == 2 || toX == 6)) ||
- (fromX == 3 && (toX == 1 || toX == 5)))) {
- switch (toX) {
- case 1:
- case 6:
- strcpy(out, "0-0");
- break;
- case 2:
- case 5:
- strcpy(out, "0-0-0");
- break;
- }
- ret = yylexstr(currentBoardIndex, out, (char **) NULL);
- break;
- }
- /* else fall through */
-
- default:
- /* Piece move */
- /* First try style "Nf3" or "Nxf7" */
- *outp++ = ToUpper(PieceToChar(piece));
-
- /* Capture? */
- if(boards[currentBoardIndex][toY][toX] != EmptySquare)
- *outp++ = 'x';
-
- *outp++ = toX + 'a';
- *outp++ = toY + '1';
- *outp = NULLCHAR;
-
- /* Test if ambiguous */
- ret = yylexstr(currentBoardIndex, out, (char **) NULL);
- if (ret != AmbiguousMove) break;
-
- /* Try style "Ngf3" or "Nexf7" */
- for (i=4; i>=1; i--) out[i+1] = out[i];
- out[1] = fromX + 'a';
-
- /* Test if ambiguous */
- ret = yylexstr(currentBoardIndex, out, (char **) NULL);
- if (ret != AmbiguousMove) break;
-
- /* Try style "N1f3" */
- out[1] = fromY + '1';
-
- /* Test if ambiguous */
- ret = yylexstr(currentBoardIndex, out, (char **) NULL);
- if (ret != AmbiguousMove) break;
-
- /* Try style "Ng1f3" or "Ne5xf7" */
- /* Can be needed iff there are 3 or more pieces of the
- type being moved on the board, due to promotion */
- for (i=5; i>=2; i--) out[i+1] = out[i];
- out[1] = fromX + 'a';
- out[2] = fromY + '1';
-
- /* Test if okay */
- ret = yylexstr(currentBoardIndex, out, (char **) NULL);
- break;
-
- case EmptySquare:
- /* Illegal move; use coordinate notation */
- *outp++ = fromX + 'a';
- *outp++ = fromY + '1';
- *outp++ = toX + 'a';
- *outp++ = toY + '1';
- *outp++ = ToUpper(promoChar);
- *outp = NULLCHAR;
- return BadMove;
- }
-
- switch (ret) {
- case NormalMove:
- case WhitePromotionKnight:
- case WhitePromotionBishop:
- case WhitePromotionRook:
- case WhitePromotionQueen:
- case BlackPromotionKnight:
- case BlackPromotionBishop:
- case BlackPromotionRook:
- case BlackPromotionQueen:
- case WhiteCapturesEnPassant:
- case BlackCapturesEnPassant:
- case WhiteKingSideCastle:
- case WhiteQueenSideCastle:
- case BlackKingSideCastle:
- case BlackQueenSideCastle:
- case WhiteKingSideCastleWild:
- case WhiteQueenSideCastleWild:
- case BlackKingSideCastleWild:
- case BlackQueenSideCastleWild:
- if (currentMoveString[0] != fromX + 'a' ||
- currentMoveString[1] != fromY + '1' ||
- currentMoveString[2] != toX + 'a' ||
- currentMoveString[3] != toY + '1' ||
- (promoChar != NULLCHAR &&
- currentMoveString[4] != ToLower(promoChar))) {
- /* Illegal move; use coordinate notation */
- outp = out;
- *outp++ = fromX + 'a';
- *outp++ = fromY + '1';
- *outp++ = toX + 'a';
- *outp++ = toY + '1';
- *outp++ = ToUpper(promoChar);
- *outp = NULLCHAR;
- return BadMove;
- }
- else
- return ret;
-
- default:
- /* Illegal move; use coordinate notation */
- outp = out;
- *outp++ = fromX + 'a';
- *outp++ = fromY + '1';
- *outp++ = toX + 'a';
- *outp++ = toY + '1';
- *outp++ = ToUpper(promoChar);
- *outp = NULLCHAR;
- return BadMove;
- }
- }
-
-
- /*
- * If the user selects on a border boundary, return -1; if off the board,
- * return -2. Otherwise map the event coordinate to the square.
- */
- int EventToSquare(x)
- int x;
- {
- if (x <= 0)
- return -2;
- if (x < LINE_GAP)
- return -1;
- x -= LINE_GAP;
- if ((x % (squareSize + LINE_GAP)) >= squareSize)
- return -1;
- x /= (squareSize + LINE_GAP);
- if (x >= BOARD_SIZE)
- return -2;
- return x;
- }
-
- void DrawSquare(row, column, piece)
- int row, column;
- ChessSquare piece;
- {
- int square_color, x, y, direction, font_ascent, font_descent;
- char string[2];
- XCharStruct overall;
-
- if (flipView) {
- x = LINE_GAP + ((BOARD_SIZE-1)-column) *
- (squareSize + LINE_GAP);
- y = LINE_GAP + row * (squareSize + LINE_GAP);
- } else {
- x = LINE_GAP + column * (squareSize + LINE_GAP);
- y = LINE_GAP + ((BOARD_SIZE-1)-row) *
- (squareSize + LINE_GAP);
- }
-
- square_color = ((column + row) % 2) == 1;
-
- if (piece == EmptySquare)
- XFillRectangle(xDisplay, xBoardWindow,
- square_color ? lightSquareGC : darkSquareGC,
- x, y, squareSize, squareSize);
- else if (appData.monoMode) {
- if (square_color)
- XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
- ? *pieceToOutline[(int) piece]
- : *pieceToSolid[(int) piece],
- xBoardWindow, bwPieceGC, 0, 0,
- squareSize, squareSize, x, y, 1);
- else
- XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
- ? *pieceToSolid[(int) piece]
- : *pieceToOutline[(int) piece],
- xBoardWindow, wbPieceGC, 0, 0,
- squareSize, squareSize, x, y, 1);
- } else {
- if (square_color)
- XCopyPlane(xDisplay, *pieceToSolid[(int) piece],
- xBoardWindow, (int) piece < (int) BlackPawn
- ? wlPieceGC : blPieceGC, 0, 0,
- squareSize, squareSize, x, y, 1);
- else
- XCopyPlane(xDisplay, *pieceToSolid[(int) piece],
- xBoardWindow, (int) piece < (int) BlackPawn
- ? wdPieceGC : bdPieceGC, 0, 0,
- squareSize, squareSize, x, y, 1);
- }
- string[1] = NULLCHAR;
- if (appData.showCoords && row == (flipView ? 7 : 0)) {
- string[0] = 'a' + column;
- XTextExtents(coordFontStruct, string, 1, &direction,
- &font_ascent, &font_descent, &overall);
- if (appData.monoMode) {
- XDrawImageString(xDisplay, xBoardWindow, coordGC,
- x + squareSize - overall.width - 2,
- y + squareSize - font_descent - 1, string, 1);
- } else {
- XDrawString(xDisplay, xBoardWindow, coordGC,
- x + squareSize - overall.width - 2,
- y + squareSize - font_descent - 1, string, 1);
- }
- }
- if (appData.showCoords && column == (flipView ? 7 : 0)) {
- string[0] = '1' + row;
- XTextExtents(coordFontStruct, string, 1, &direction,
- &font_ascent, &font_descent, &overall);
- if (appData.monoMode) {
- XDrawImageString(xDisplay, xBoardWindow, coordGC,
- x + 2, y + font_ascent + 1, string, 1);
- } else {
- XDrawString(xDisplay, xBoardWindow, coordGC,
- x + 2, y + font_ascent + 1, string, 1);
- }
- }
- }
-
- void EventProc(widget, unused, event)
- Widget widget;
- caddr_t unused;
- XEvent *event;
- {
- if (event->type == MappingNotify) {
- XRefreshKeyboardMapping((XMappingEvent *) event);
- return;
- }
-
- if (!XtIsRealized(widget))
- return;
-
- if ((event->type == ButtonPress) || (event->type == ButtonRelease))
- if (event->xbutton.button != Button1)
- return;
-
- switch (event->type) {
- case Expose:
- DrawPosition(widget, event, NULL, NULL);
- break;
- default:
- return;
- }
- }
-
- /*
- * event handler for redrawing the board
- */
- void DrawPosition(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- Arg args[1];
- int i, j;
- static Board lastBoard;
- static int lastBoardValid = 0;
- static int lastFlipView = 0;
-
- if (!appData.Iconic){
- XtSetArg(args[0], XtNiconic, False);
- XtSetValues(shellWidget, args, 1);
- }
-
- /*
- * It would be simpler to clear the window with XClearWindow()
- * but this causes a very distracting flicker.
- */
-
- if (event == NULL && lastBoardValid && lastFlipView == flipView) {
- for (i = 0; i < BOARD_SIZE; i++)
- for (j = 0; j < BOARD_SIZE; j++)
- if (boards[currentMove][i][j] != lastBoard[i][j])
- DrawSquare(i, j, boards[currentMove][i][j]);
- } else {
- XDrawSegments(xDisplay, xBoardWindow, lineGC,
- gridSegments, (BOARD_SIZE + 1) * 2);
-
- for (i = 0; i < BOARD_SIZE; i++)
- for (j = 0; j < BOARD_SIZE; j++)
- DrawSquare(i, j, boards[currentMove][i][j]);
- }
-
- CopyBoard(lastBoard, boards[currentMove]);
- lastBoardValid = 1;
- lastFlipView = flipView;
-
- XSync(xDisplay, False);
- }
-
- void InitPosition(redraw)
- int redraw;
- {
- currentMove = forwardMostMove = backwardMostMove = 0;
- CopyBoard(boards[0], initialPosition);
- if (redraw)
- DrawPosition(boardWidget, NULL, NULL, NULL);
- }
-
- void CopyBoard(to, from)
- Board to, from;
- {
- int i, j;
-
- for (i = 0; i < BOARD_SIZE; i++)
- for (j = 0; j < BOARD_SIZE; j++)
- to[i][j] = from[i][j];
- }
-
- Boolean CompareBoards(board1, board2)
- Board board1, board2;
- {
- int i, j;
-
- for (i = 0; i < BOARD_SIZE; i++)
- for (j = 0; j < BOARD_SIZE; j++) {
- if (board1[i][j] != board2[i][j])
- return FALSE;
- }
- return TRUE;
- }
-
- void SendCurrentBoard(fp)
- FILE *fp;
- {
- SendBoard(fp, boards[currentMove]);
- }
-
- void SendBoard(fp, board)
- FILE *fp;
- Board board;
- {
- char message[MSG_SIZ];
- ChessSquare *bp;
- int i, j;
-
- SendToProgram("edit\n", fp);
- SendToProgram("#\n", fp);
- for (i = BOARD_SIZE - 1; i >= 0; i--) {
- bp = &board[i][0];
- for (j = 0; j < BOARD_SIZE; j++, bp++) {
- if ((int) *bp < (int) BlackPawn) {
- sprintf(message, "%c%c%c\n", PieceToChar(*bp),
- 'a' + j, '1' + i);
- SendToProgram(message, fp);
- }
- }
- }
-
- SendToProgram("c\n", fp);
- for (i = BOARD_SIZE - 1; i >= 0; i--) {
- bp = &board[i][0];
- for (j = 0; j < BOARD_SIZE; j++, bp++) {
- if (((int) *bp != (int) EmptySquare)
- && ((int) *bp >= (int) BlackPawn)) {
- sprintf(message, "%c%c%c\n", ToUpper(PieceToChar(*bp)),
- 'a' + j, '1' + i);
- SendToProgram(message, fp);
- }
- }
- }
-
- SendToProgram(".\n", fp);
- }
-
- /*
- * event handler for parsing user moves
- */
- void HandleUserMove(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- ChessMove move_type;
- ChessSquare from_piece;
- int to_x, to_y;
-
- if ((w != boardWidget) || (matchMode != MatchFalse))
- return;
-
- if (promotionUp) {
- XtPopdown(promotionShell);
- XtDestroyWidget(promotionShell);
- promotionUp = False;
- fromX = fromY = -1;
- }
-
- switch (gameMode) {
- case EndOfGame:
- case PlayFromGameFile:
- case TwoMachinesPlay:
- return;
- case MachinePlaysWhite:
- if (WhiteOnMove(forwardMostMove)) {
- DisplayMessage("It is not your turn");
- return;
- }
- break;
- case MachinePlaysBlack:
- if (!WhiteOnMove(forwardMostMove)) {
- DisplayMessage("It is not your turn");
- return;
- }
- break;
- case ForceMoves:
- if (appData.icsActive) {
- if (ics_user_moved ||
- ics_mode == IcsObserving ||
- ics_mode == IcsIdle)
- return;
- } else {
- forwardMostMove = currentMove;
- }
- break;
- default:
- break;
- }
-
- if (currentMove != forwardMostMove) {
- DisplayMessage("Displayed position is not current");
- return;
- }
-
- switch (event->type) {
- case ButtonPress:
- if ((fromX >= 0) || (fromY >= 0))
- return;
- if (((fromX = EventToSquare(event->xbutton.x)) < 0) ||
- ((fromY = EventToSquare(event->xbutton.y)) < 0)) {
- fromX = fromY = -1;
- return;
- }
- if (flipView)
- fromX = BOARD_SIZE - 1 - fromX;
- else
- fromY = BOARD_SIZE - 1 - fromY;
- break;
-
- case ButtonRelease:
- if ((fromX < 0) || (fromY < 0)) return;
-
- if (((to_x = EventToSquare(event->xbutton.x)) < 0)
- || ((to_y = EventToSquare(event->xbutton.y)) < 0)) {
- if (gameMode == EditPosition && (to_x == -2 || to_y == -2)) {
- boards[0][fromY][fromX] = EmptySquare;
- DrawPosition(boardWidget, NULL, NULL, NULL);
- XSync(xDisplay, False);
- }
- fromX = fromY = -1;
- return;
- }
- if (flipView)
- to_x = BOARD_SIZE - 1 - to_x;
- else
- to_y = BOARD_SIZE - 1 - to_y;
-
- if ((fromX == to_x) && (fromY == to_y)) {
- fromX = fromY = -1;
- return;
- }
-
- if (gameMode == EditPosition) {
- boards[0][to_y][to_x] = boards[0][fromY][fromX];
- boards[0][fromY][fromX] = EmptySquare;
- fromX = fromY = -1;
- DrawPosition(boardWidget, NULL, NULL, NULL);
- XSync(xDisplay, False);
- return;
- }
-
- from_piece = boards[currentMove][fromY][fromX];
- if (from_piece == EmptySquare) {
- fromX = fromY = -1;
- return;
- }
- if (WhiteOnMove(currentMove)) {
- if ((int)from_piece < (int)WhitePawn ||
- (int)from_piece > (int)WhiteKing) {
- DisplayMessage("It is White's turn");
- fromX = fromY = -1;
- return;
- }
- } else {
- if ((int)from_piece < (int)BlackPawn ||
- (int)from_piece > (int)BlackKing) {
- DisplayMessage("It is Black's turn");
- fromX = fromY = -1;
- return;
- }
- }
- if (((from_piece == WhitePawn && to_y == 7) ||
- (from_piece == BlackPawn && to_y == 0))) {
- PromotionPopUp(from_piece, to_x, to_y);
- return;
- }
- move_type = LegalityTest(WhiteOnMove(currentMove),
- boards[currentMove], fromY, fromX,
- to_y, to_x, NULLCHAR);
- if (move_type == BadMove) {
- DisplayMessage("Illegal move");
- fromX = fromY = -1;
- return;
- }
- MakeMove(&move_type, fromX, fromY, to_x, to_y);
- FinishUserMove(move_type, to_x, to_y);
- break;
- }
- }
-
- void FinishUserMove(move_type, to_x, to_y)
- ChessMove move_type;
- int to_x, to_y;
- {
- char user_move[MSG_SIZ];
- char promoChar;
-
- if (appData.icsActive) {
- sprintf(user_move, "%c%c%c%c\n",
- 'a' + fromX, '1' + fromY, 'a' + to_x, '1' + to_y);
- switch (move_type) {
- default:
- fprintf(stderr, "%s: internal error; bad move_type\n",
- programName);
- break;
- case WhiteKingSideCastle:
- case BlackKingSideCastle:
- case WhiteQueenSideCastleWild:
- case BlackQueenSideCastleWild:
- sprintf(user_move, "o-o\n");
- break;
- case WhiteQueenSideCastle:
- case BlackQueenSideCastle:
- case WhiteKingSideCastleWild:
- case BlackKingSideCastleWild:
- sprintf(user_move, "o-o-o\n");
- break;
- case WhitePromotionQueen:
- case BlackPromotionQueen:
- SendToICS("promote queen\n");
- break;
- case WhitePromotionRook:
- case BlackPromotionRook:
- SendToICS("promote rook\n");
- break;
- case WhitePromotionBishop:
- case BlackPromotionBishop:
- SendToICS("promote bishop\n");
- break;
- case WhitePromotionKnight:
- case BlackPromotionKnight:
- SendToICS("promote knight\n");
- break;
- case NormalMove:
- case WhiteCapturesEnPassant:
- case BlackCapturesEnPassant:
- break;
- }
- SendToICS(user_move);
- ics_user_moved = 1;
- } else {
- promoChar = ToLower(PieceToChar(PromoPiece(move_type)));
- if (promoChar == '.')
- sprintf(user_move, "%c%c%c%c\n",
- 'a' + fromX, '1' + fromY, 'a' + to_x, '1' + to_y);
- else
- sprintf(user_move, "%c%c%c%c%c\n",
- 'a' + fromX, '1' + fromY, 'a' + to_x, '1' + to_y,
- promoChar);
-
- Attention(firstProgramPID);
- if (firstSendTime)
- SendTimeRemaining(toFirstProgFP);
- SendToProgram(user_move, toFirstProgFP);
- }
-
- fromX = fromY = -1;
-
- strcpy(moveList[currentMove - 1], user_move);
-
- /* A user move restarts a paused game*/
- if (gameMode == PauseGame)
- PauseProc(NULL, NULL, NULL, NULL);
-
- switch (gameMode) {
- case ForceMoves:
- break;
- case PlayFromGameFile:
- ForceProc(NULL, NULL, NULL, NULL);
- break;
- case BeginningOfGame:
- if (appData.noChessProgram)
- lastGameMode = gameMode = ForceMoves;
- else
- lastGameMode = gameMode = MachinePlaysBlack;
- ModeHighlight();
- break;
- case MachinePlaysBlack:
- case MachinePlaysWhite:
- default:
- break;
- }
- }
-
- /* Parser for moves from gnuchess or ICS */
- void ParseMachineMove(machine_move, move_num,
- move_type, from_x, from_y, to_x, to_y, promo_char)
- char *machine_move;
- int move_num;
- ChessMove *move_type;
- int *from_x, *from_y, *to_x, *to_y;
- char *promo_char;
- {
- *move_type = yylexstr(move_num, machine_move, NULL);
- switch (*move_type) {
- case WhitePromotionQueen:
- case BlackPromotionQueen:
- case WhitePromotionRook:
- case BlackPromotionRook:
- case WhitePromotionBishop:
- case BlackPromotionBishop:
- case WhitePromotionKnight:
- case BlackPromotionKnight:
- case NormalMove:
- case WhiteCapturesEnPassant:
- case BlackCapturesEnPassant:
- case WhiteKingSideCastle:
- case WhiteQueenSideCastle:
- case BlackKingSideCastle:
- case BlackQueenSideCastle:
- case WhiteKingSideCastleWild:
- case WhiteQueenSideCastleWild:
- case BlackKingSideCastleWild:
- case BlackQueenSideCastleWild:
- *from_x = currentMoveString[0] - 'a';
- *from_y = currentMoveString[1] - '1';
- *to_x = currentMoveString[2] - 'a';
- *to_y = currentMoveString[3] - '1';
- *promo_char = currentMoveString[4];
- break;
- case BadMove:
- case AmbiguousMove:
- case 0: /* end of file */
- case ElapsedTime:
- case Comment:
- case StartGame:
- case WhiteWins:
- case BlackWins:
- case GameIsDrawn:
- default:
- /* bug? */
- fprintf(stderr, "%s: bad move in chess program output: %s\n",
- programName, machine_move);
- *from_x = *from_y = *to_x = *to_y = 0;
- break;
- }
- }
-
- void HandleMachineMove(message, fp)
- char *message;
- FILE *fp;
- {
- char machine_move[MSG_SIZ], buf1[MSG_SIZ], buf2[MSG_SIZ];
- int from_x, from_y, to_x, to_y;
- ChessMove move_type;
- char promo_char;
-
- maybeThinking = False;
-
- if (strncmp(message, "warning:", 8) == 0) {
- DisplayMessage(message);
- return;
- }
-
- /*
- * If chess program startup fails, exit with an error message.
- * Attempts to recover here are futile.
- */
- if ((StrStr(message, "unknown host") != NULL)
- || (StrStr(message, "No remote directory") != NULL)
- || (StrStr(message, "not found") != NULL)
- || (StrStr(message, "No such file") != NULL)
- || (StrStr(message, "Permission denied") != NULL)) {
- fprintf(stderr,
- "%s: failed to start chess program %s on %s: %s\n",
- programName,
- fp == fromFirstProgFP ? appData.firstChessProgram
- : appData.secondChessProgram,
- fp == fromFirstProgFP ? appData.firstHost
- : appData.secondHost,
- message);
- ShutdownChessPrograms(message);
- exit(1);
- }
-
- if (strncmp(message, "time", 4) == 0) {
- if (StrStr(message, "CHESS")) {
- /* Program has a broken "time" command that
- outputs a string not ending in newline.
- Don't use it. */
- if (fp == fromFirstProgFP) firstSendTime = 0;
- if (fp == fromSecondProgFP) secondSendTime = 0;
- }
- }
-
- /*
- * If the move is illegal, cancel it and redraw the board.
- */
- if (strncmp(message, "Illegal move", 12) == 0) {
-
- if (fp == fromFirstProgFP && firstSendTime == 2) {
- /* First program doesn't have the "time" command */
- firstSendTime = 0;
- return;
- } else if (fp == fromSecondProgFP && secondSendTime == 2) {
- /* Second program doesn't have the "time" command */
- secondSendTime = 0;
- return;
- }
- if (forwardMostMove <= backwardMostMove) return;
- if (gameMode == PauseGame) PauseProc(NULL, NULL, NULL, NULL);
- if (gameMode == PlayFromGameFile) {
- /* Stop reading this game file */
- gameMode = ForceMoves;
- ModeHighlight();
- }
- currentMove = --forwardMostMove;
- if ((gameMode == PlayFromGameFile) || (gameMode == ForceMoves))
- DisplayClocks(ReDisplayTimers);
- else
- DisplayClocks(SwitchTimers);
- sprintf(buf1, "Illegal move: %s", parseList[currentMove]);
- DisplayMessage(buf1);
-
- DrawPosition(boardWidget, NULL, NULL, NULL);
-
- XSync(xDisplay, False);
- return;
- }
-
- if (strncmp(message, "Hint:", 5) == 0) {
- sscanf(message, "Hint: %s", machine_move);
- ParseMachineMove(machine_move, forwardMostMove, &move_type,
- &from_x, &from_y, &to_x, &to_y, &promo_char);
- move_type = CoordsToAlgebraic(from_x, from_y, to_x, to_y, promo_char,
- forwardMostMove, buf1);
- sprintf(buf2, "Hint: %s", buf1);
- DisplayMessage(buf2);
- return;
- }
-
- /*
- * win, lose or draw
- */
- if (strncmp(message, "White", 5) == 0) {
- ShutdownChessPrograms("White mates");
- return;
- } else if (strncmp(message, "Black", 5) == 0) {
- ShutdownChessPrograms("Black mates");
- return;
- } else if (strncmp(message, "opponent mates!", 15) == 0) {
- switch (gameMode == PauseGame ? pausePreviousMode : gameMode) {
- case MachinePlaysBlack:
- ShutdownChessPrograms("White mates");
- break;
- case MachinePlaysWhite:
- ShutdownChessPrograms("Black mates");
- break;
- case TwoMachinesPlay:
- ShutdownChessPrograms(fp == fromFirstProgFP ?
- "White mates" : "Black mates");
- break;
- default:
- /* can't happen */
- break;
- }
- return;
- } else if (strncmp(message, "computer mates!", 15) == 0) {
- switch (gameMode == PauseGame ? pausePreviousMode : gameMode) {
- case MachinePlaysBlack:
- ShutdownChessPrograms("Black mates");
- break;
- case MachinePlaysWhite:
- ShutdownChessPrograms("White mates");
- break;
- case TwoMachinesPlay:
- ShutdownChessPrograms(fp == fromFirstProgFP ?
- "Black mates" : "White mates");
- break;
- default:
- /* can't happen */
- break;
- }
- return;
- } else if (strncmp(message, "Draw", 4) == 0) {
- ShutdownChessPrograms("Draw");
- return;
- }
-
- /*
- * normal machine reply move
- */
- maybeThinking = True;
- if (StrStr(message, "...") != NULL) {
- sscanf(message, "%s %s %s", buf1, buf2, machine_move);
- if (machine_move[0] == NULLCHAR)
- return;
- } else
- return; /* ignore noise */
-
- strcpy(moveList[forwardMostMove], machine_move);
-
- ParseMachineMove(machine_move, forwardMostMove, &move_type,
- &from_x, &from_y, &to_x, &to_y, &promo_char);
-
- if (gameMode != PauseGame)
- currentMove = forwardMostMove; /*display latest move*/
-
- MakeMove(&move_type, from_x, from_y, to_x, to_y);
-
- if (gameMode != PauseGame && appData.ringBellAfterMoves)
- putc(BELLCHAR, stderr);
-
- if (gameMode == TwoMachinesPlay ||
- (gameMode == PauseGame && pausePreviousMode == TwoMachinesPlay)) {
- strcat(machine_move, "\n");
- if (WhiteOnMove(forwardMostMove)) {
- Attention(secondProgramPID);
- if (secondSendTime)
- SendTimeRemaining(toSecondProgFP);
- SendToProgram(machine_move, toSecondProgFP);
- if (firstMove) {
- firstMove = False;
- SendToProgram(appData.whiteString,
- toSecondProgFP);
- }
- } else {
- Attention(firstProgramPID);
- if (firstSendTime)
- SendTimeRemaining(toFirstProgFP);
- SendToProgram(machine_move, toFirstProgFP);
- if (firstMove) {
- firstMove = False;
- SendToProgram(appData.blackString,
- toFirstProgFP);
- }
- }
- }
- }
-
-
- /* Parse a game score from the character string "game", and
- record it as the history of the current game. The game
- score is NOT assumed to start from the standard position.
- The display is not updated in any way.
- */
- void ParseGameHistory(game)
- char *game;
- {
- ChessMove move_type;
- int from_x, from_y, to_x, to_y, boardIndex;
- char promo_char;
- char *p;
-
- if (appData.debugMode)
- fprintf(stderr, "Parsing game history: %s\n", game);
-
- /* Parse out names of players */
- while (*game == ' ') game++;
- p = ics_white;
- while (*game != ' ') *p++ = *game++;
- *p = NULLCHAR;
- while (*game == ' ') game++;
- p = ics_black;
- while (*game != ' ' && *game != '\n') *p++ = *game++;
- *p = NULLCHAR;
-
- /* Parse moves */
- boardIndex = 0;
- for (;;) {
- move_type = yylexstr(boardIndex, game, &game);
- switch (move_type) {
- case WhitePromotionQueen:
- case BlackPromotionQueen:
- case WhitePromotionRook:
- case BlackPromotionRook:
- case WhitePromotionBishop:
- case BlackPromotionBishop:
- case WhitePromotionKnight:
- case BlackPromotionKnight:
- case NormalMove:
- case WhiteCapturesEnPassant:
- case BlackCapturesEnPassant:
- case WhiteKingSideCastle:
- case WhiteQueenSideCastle:
- case BlackKingSideCastle:
- case BlackQueenSideCastle:
- case WhiteKingSideCastleWild:
- case WhiteQueenSideCastleWild:
- case BlackKingSideCastleWild:
- case BlackQueenSideCastleWild:
- from_x = currentMoveString[0] - 'a';
- from_y = currentMoveString[1] - '1';
- to_x = currentMoveString[2] - 'a';
- to_y = currentMoveString[3] - '1';
- promo_char = currentMoveString[4];
- break;
- case BadMove:
- case AmbiguousMove:
- /* bug? */
- fprintf(stderr, "%s: ?bad move in ICS output: %s\n",
- programName, yytext);
- /* fall thru */
- case 0: /* end of file */
- if (boardIndex < backwardMostMove) {
- /* Oops, gap. How did that happen? */
- return;
- }
- backwardMostMove = 0;
- if (boardIndex > forwardMostMove) {
- forwardMostMove = boardIndex;
- }
- return;
- case ElapsedTime:
- if (boardIndex > 0) {
- strcat(parseList[boardIndex-1], " ");
- strcat(parseList[boardIndex-1], yytext);
- }
- continue;
- case Comment:
- case StartGame:
- default:
- /* ignore */
- continue;
- case WhiteWins:
- case BlackWins:
- case GameIsDrawn:
- strncpy(endMessage, yytext, MOVE_LEN * 4);
- endMessage[MOVE_LEN * 4 - 1] = NULLCHAR;
- continue;
- }
- (void) CoordsToAlgebraic(from_x, from_y, to_x, to_y, promo_char,
- boardIndex, parseList[boardIndex]);
- CopyBoard(boards[boardIndex + 1], boards[boardIndex]);
- boardIndex++;
- ApplyMove(&move_type, from_x, from_y, to_x, to_y,
- boards[boardIndex]);
- }
- }
-
- void LoadGameLoop()
- {
- readGameXID = 0;
- for (;;) {
- if (!LoadGameOneMove())
- return;
- if (matchMode == MatchOpening || appData.timeDelay == 0)
- continue;
- if (appData.timeDelay < 0)
- return;
- readGameXID =
- XtAppAddTimeOut(appContext, (int) (1000 * appData.timeDelay),
- (XtTimerCallbackProc) LoadGameLoop, NULL);
- break;
- }
- }
-
- Boolean LoadGameOneMove()
- {
- int from_x, from_y, to_x, to_y, done;
- ChessMove move_type;
- char move[MSG_SIZ];
-
- if (gameFileFP == NULL)
- return False;
-
- if (!(gameMode == PlayFromGameFile ||
- (gameMode == PauseGame && pausePreviousMode == PlayFromGameFile))) {
- fclose(gameFileFP);
- gameFileFP = NULL;
- yynewfile();
- return False;
- }
-
- if (commentUp) CommentPopDown();
-
- yyboardindex = forwardMostMove;
- move_type = (ChessMove) yylex();
-
- if (appData.debugMode) {
- switch (move_type) {
- case BadMove:
- fprintf(stderr, "Parsed BadMove: %s\n", yytext);
- break;
- case AmbiguousMove:
- fprintf(stderr, "Parsed AmbiguousMove: %s\n", yytext);
- break;
- case Comment:
- fprintf(stderr, "Parsed Comment: %s\n", yytext);
- break;
- case WhiteWins:
- case BlackWins:
- case GameIsDrawn:
- case 0:
- fprintf(stderr, "Parsed game end: %s\n", yytext);
- break;
- case StartGame:
- fprintf(stderr, "Parsed StartGame: %s\n", yytext);
- break;
- case ElapsedTime:
- fprintf(stderr, "Parsed ElapsedTime: %s\n", yytext);
- break;
- default:
- fprintf(stderr, "Parsed %s into %s", yytext, currentMoveString);
- break;
- }
- }
-
- done = False;
- switch (move_type) {
- case Comment:
- CommentPopUp(yytext);
- return True;
- case WhiteCapturesEnPassant:
- case BlackCapturesEnPassant:
- case WhitePromotionQueen:
- case BlackPromotionQueen:
- case WhitePromotionRook:
- case BlackPromotionRook:
- case WhitePromotionBishop:
- case BlackPromotionBishop:
- case WhitePromotionKnight:
- case BlackPromotionKnight:
- case NormalMove:
- case WhiteKingSideCastle:
- case WhiteQueenSideCastle:
- case BlackKingSideCastle:
- case BlackQueenSideCastle:
- case WhiteKingSideCastleWild:
- case WhiteQueenSideCastleWild:
- case BlackKingSideCastleWild:
- case BlackQueenSideCastleWild:
- from_x = currentMoveString[0] - 'a';
- from_y = currentMoveString[1] - '1';
- to_x = currentMoveString[2] - 'a';
- to_y = currentMoveString[3] - '1';
- break;
- case 0: /* end of file */
- DisplayMessage("End of game file");
- done = True;
- break;
- case WhiteWins:
- case BlackWins:
- case GameIsDrawn:
- GameEnds(yytext);
- return False;
- case StartGame:
- #ifdef notdef
- /* We see too many bogus StartGame markers with current
- lex definition, especially in gnuchess listing files,
- so this code is disabled. */
- /* Reached start of next game in file */
- DisplayMessage("End of game");
- done = True;
- #else /*!notdef*/
- /* ignore */
- return LoadGameOneMove(); /* tail recursion */
- #endif /*notdef*/
- break;
- case ElapsedTime:
- /* ignore */
- return LoadGameOneMove(); /* tail recursion */
- default:
- case BadMove:
- sprintf(move, "Bad move: %d. %s%s",
- (forwardMostMove / 2) + 1,
- WhiteOnMove(forwardMostMove) ? "" : "... ", yytext);
- DisplayMessage(move);
- done = True;
- break;
- case AmbiguousMove:
- sprintf(move, "Ambiguous move: %d. %s%s",
- (forwardMostMove / 2) + 1,
- WhiteOnMove(forwardMostMove) ? "" : "... ", yytext);
- DisplayMessage(move);
- done = True;
- break;
- }
-
- if (done) {
- lastGameMode = (gameMode == PauseGame ? pausePreviousMode : gameMode);
- gameMode = ForceMoves;
- ModeHighlight();
- if (readGameXID != 0) {
- XtRemoveTimeOut(readGameXID);
- readGameXID = 0;
- }
- fclose(gameFileFP);
- gameFileFP = NULL;
- yynewfile();
- return (int) False;
- } else {
- SendToProgram(currentMoveString, toFirstProgFP);
- strcpy(moveList[forwardMostMove], currentMoveString);
-
- MakeMove(&move_type, from_x, from_y, to_x, to_y);
-
- return (int) True;
- }
- }
-
- /* Apply a move to the given board. Oddity: move_type is ignored on
- input unless the move is seen to be a pawn promotion, in which case
- move_type tells us what to promote to.
- */
- void ApplyMove(move_type, from_x, from_y, to_x, to_y, board)
- ChessMove *move_type;
- int from_x, from_y, to_x, to_y;
- Board board;
- {
- if (from_y == 0 && from_x == 4
- && board[from_y][from_x] == WhiteKing
- && to_y == 0 && to_x == 6) {
- *move_type = WhiteKingSideCastle;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = WhiteKing;
- board[from_y][7] = EmptySquare;
- board[to_y][5] = WhiteRook;
- } else if (from_y == 0 && from_x == 4
- && board[from_y][from_x] == WhiteKing
- && to_y == 0 && to_x == 2) {
- *move_type = WhiteQueenSideCastle;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = WhiteKing;
- board[from_y][0] = EmptySquare;
- board[to_y][3] = WhiteRook;
- } else if (from_y == 0 && from_x == 3
- && board[from_y][from_x] == WhiteKing
- && to_y == 0 && to_x == 5) {
- *move_type = WhiteKingSideCastleWild;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = WhiteKing;
- board[from_y][7] = EmptySquare;
- board[to_y][4] = WhiteRook;
- } else if (from_y == 0 && from_x == 3
- && board[from_y][from_x] == WhiteKing
- && to_y == 0 && to_x == 1) {
- *move_type = WhiteQueenSideCastleWild;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = WhiteKing;
- board[from_y][0] = EmptySquare;
- board[to_y][2] = WhiteRook;
- } else if (from_y == 6
- && board[from_y][from_x] == WhitePawn
- && to_y == 7) {
- /* white pawn promotion */
- board[7][to_x] = PromoPiece(*move_type);
- if (board[7][to_x] == EmptySquare) {
- board[7][to_x] = WhiteQueen;
- *move_type = WhitePromotionQueen;
- }
- board[6][from_x] = EmptySquare;
- } else if ((from_y == 4)
- && (to_x != from_x)
- && (board[from_y][from_x] == WhitePawn)
- && (board[to_y][to_x] == EmptySquare)) {
- *move_type = WhiteCapturesEnPassant;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = WhitePawn;
- board[to_y - 1][to_x] = EmptySquare;
- } else if (from_y == 7 && from_x == 4
- && board[from_y][from_x] == BlackKing
- && to_y == 7 && to_x == 6) {
- *move_type = BlackKingSideCastle;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = BlackKing;
- board[from_y][7] = EmptySquare;
- board[to_y][5] = BlackRook;
- } else if (from_y == 7 && from_x == 4
- && board[from_y][from_x] == BlackKing
- && to_y == 7 && to_x == 2) {
- *move_type = BlackQueenSideCastle;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = BlackKing;
- board[from_y][0] = EmptySquare;
- board[to_y][3] = BlackRook;
- } else if (from_y == 7 && from_x == 3
- && board[from_y][from_x] == BlackKing
- && to_y == 7 && to_x == 5) {
- *move_type = BlackKingSideCastleWild;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = BlackKing;
- board[from_y][7] = EmptySquare;
- board[to_y][4] = BlackRook;
- } else if (from_y == 7 && from_x == 3
- && board[from_y][from_x] == BlackKing
- && to_y == 7 && to_x == 1) {
- *move_type = BlackQueenSideCastleWild;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = BlackKing;
- board[from_y][0] = EmptySquare;
- board[to_y][2] = BlackRook;
- } else if (from_y == 1
- && board[from_y][from_x] == BlackPawn
- && to_y == 0) {
- /* black pawn promotion */
- board[0][to_x] = PromoPiece(*move_type);
- if (board[0][to_x] == EmptySquare) {
- board[0][to_x] = BlackQueen;
- *move_type = BlackPromotionQueen;
- }
- board[1][from_x] = EmptySquare;
- } else if ((from_y == 3)
- && (to_x != from_x)
- && (board[from_y][from_x] == BlackPawn)
- && (board[to_y][to_x] == EmptySquare)) {
- *move_type = BlackCapturesEnPassant;
- board[from_y][from_x] = EmptySquare;
- board[to_y][to_x] = BlackPawn;
- board[to_y + 1][to_x] = EmptySquare;
- } else {
- *move_type = NormalMove;
- board[to_y][to_x] = board[from_y][from_x];
- board[from_y][from_x] = EmptySquare;
- }
- }
-
- /*
- * MakeMove() displays moves. If they are illegal, GNU chess will detect
- * this and send an Illegal move message. XBoard will then retract the move.
- *
- * Oddity: move_type is ignored on input unless the move is seen to be a
- * pawn promotion, in which case move_type tells us what to promote to.
- */
- void MakeMove(move_type, from_x, from_y, to_x, to_y)
- ChessMove *move_type;
- int from_x, from_y, to_x, to_y;
- {
- forwardMostMove++;
- CopyBoard(boards[forwardMostMove], boards[forwardMostMove - 1]);
- ApplyMove(move_type, from_x, from_y, to_x, to_y,
- boards[forwardMostMove]);
- endMessage[0] = NULLCHAR;
- (void) CoordsToAlgebraic(from_x, from_y, to_x, to_y,
- ToLower(PieceToChar(PromoPiece(*move_type))),
- forwardMostMove - 1,
- parseList[forwardMostMove - 1]);
- timeRemaining[0][forwardMostMove] = whiteTimeRemaining;
- timeRemaining[1][forwardMostMove] = blackTimeRemaining;
-
- if (gameMode == PauseGame && pausePreviousMode != PlayFromGameFile)
- return;
-
- currentMove = forwardMostMove;
- if ((gameMode == PlayFromGameFile) || (gameMode == ForceMoves) ||
- (gameMode == PauseGame && pausePreviousMode == PlayFromGameFile))
- DisplayClocks(ReDisplayTimers);
- else
- DisplayClocks(SwitchTimers);
- DisplayMove(currentMove - 1);
- DrawPosition(boardWidget, NULL, NULL, NULL);
- XSync(xDisplay, False);
- }
-
- void InitChessProgram(host_name, program_name, pid, to, from, xid, sendTime)
- char *host_name, *program_name;
- int *pid;
- FILE **to, **from;
- XtIntervalId *xid;
- int *sendTime;
- {
- char arg_buf[10];
- char *arg1, *arg2;
- int to_prog[2], from_prog[2];
- FILE *from_fp, *to_fp;
- int dummy_source;
- XtInputId dummy_id;
- #if defined(SYSTEM_FIVE) || defined(SYSV)
- char *pty_name;
- #endif
-
- if (appData.noChessProgram) return;
-
- #if defined(SYSTEM_FIVE) || defined(SYSV)
- if ((pty_name = PseudoTTY(&to_prog[1])) == NULL) {
- fprintf(stderr, "%s: can't open pseudo-tty: ", programName);
- perror("");
- exit(1);
- }
-
- from_prog[0] = to_prog[1];
- to_prog[0] = from_prog[1] = open(pty_name, O_RDWR, 0);
- #ifdef SVR4
- if (ioctl (to_prog[0], I_PUSH, "ptem") == -1 ||
- ioctl (to_prog[0], I_PUSH, "ldterm") == -1 ||
- ioctl (to_prog[0], I_PUSH, "ttcompat") == -1) {
- fprintf(stderr, "%s: can't ioctl pseudo-tty: ", programName);
- perror("");
- exit(1);
- }
- #endif
- #else
- signal(SIGPIPE, CatchPipeSignal);
- pipe(to_prog);
- pipe(from_prog);
- #endif
-
- if ((*pid = fork()) == 0) {
- #if !defined(SYSTEM_FIVE) && !defined(SYSV)
- signal(SIGPIPE, CatchPipeSignal);
- #endif
- dup2(to_prog[0], 0);
- dup2(from_prog[1], 1);
- close(to_prog[0]);
- close(to_prog[1]);
- close(from_prog[0]);
- close(from_prog[1]);
- dup2(1, fileno(stderr)); /* force stderr to the pipe */
- if (*appData.searchTime != NULLCHAR) {
- sprintf(arg_buf, "%d", searchTime);
- arg1 = arg_buf;
- arg2 = (char *) NULL;
- } else if (appData.searchDepth > 0) {
- sprintf(arg_buf, "%d", appData.searchDepth);
- arg1 = "1";
- arg2 = "9999";
- } else {
- sprintf(arg_buf, "%d", appData.movesPerSession);
- arg1 = arg_buf;
- arg2 = appData.timeControl;
- }
- if (strcmp(host_name, "localhost") == 0) {
- execlp(program_name, program_name, arg1, arg2,
- (char *) NULL);
- } else {
- execlp(appData.remoteShell, appData.remoteShell,
- host_name, program_name, arg1, arg2,
- (char *) NULL);
- }
-
- perror(program_name);
- exit(1);
- }
-
- close(to_prog[0]);
- close(from_prog[1]);
-
- *from = from_fp = fdopen(from_prog[0], "r");
- *to = to_fp = fdopen(to_prog[1], "w");
- setbuf(from_fp, NULL); setbuf(to_fp, NULL);
-
- ReceiveFromProgram(from_fp, &dummy_source, &dummy_id); /*"Chess"*/
- if (*pid == 0) return;
-
- *xid = XtAppAddInput(appContext, fileno(from_fp),
- (XtPointer)XtInputReadMask,
- (XtInputCallbackProc)ReceiveFromProgram,
- (XtPointer)from_fp);
-
- SendToProgram(appData.initString, to_fp);
- SendSearchDepth(to_fp);
-
- if (*sendTime == 2) {
- /* Does program have "time" command? */
- char buf[MSG_SIZ];
-
- sprintf(buf, "time %d\nhelp\n", blackTimeRemaining/10);
- /* "help" is a kludge to work around a gnuchess bug;
- some versions do not send a newline at the end of
- their response to the time command */
- SendToProgram(buf, to_fp);
- ReceiveFromProgram(from_fp, &dummy_source, &dummy_id);
- if (*sendTime == 2) *sendTime = 1; /* yes! */
- }
-
- }
-
- void GameEnds(why)
- char *why;
- {
- ics_mode = IcsIdle;
- ics_gamenum = -1;
- ics_user_moved = False;
- if (readGameXID != 0) {
- XtRemoveTimeOut(readGameXID);
- readGameXID = 0;
- }
- if (gameFileFP != NULL) {
- fclose(gameFileFP);
- gameFileFP = NULL;
- yynewfile();
- }
- DisplayClocks(StopTimers);
-
- if (why == NULL) return;
-
- strncpy(endMessage, why, MOVE_LEN * 4);
- endMessage[MOVE_LEN * 4 - 1] = NULLCHAR;
- if (currentMove == forwardMostMove)
- DisplayMove(currentMove - 1);
-
- if (!(gameMode == PlayFromGameFile ||
- (gameMode == PauseGame && pausePreviousMode == PlayFromGameFile))) {
- if (*appData.saveGameFile != NULLCHAR) {
- SaveGame(appData.saveGameFile);
- } else if (appData.autoSaveGames) {
- SaveGameProc(NULL, NULL, NULL, NULL);
- }
- if (appData.savePositionFile[0] != NULLCHAR)
- SavePosition(appData.savePositionFile);
- }
- }
-
- void ShutdownChessPrograms(why)
- char *why;
- {
- GameEnds(why);
-
- lastGameMode = gameMode;
- if (gameMode == PauseGame) {
- pausePreviousMode = EndOfGame;
- } else {
- gameMode = EndOfGame;
- ModeHighlight();
- }
-
- if (firstProgramPID != 0) {
- if (kill(firstProgramPID, 0) == 0)
- SendToProgram("quit\n", toFirstProgFP);
- fclose(fromFirstProgFP);
- fclose(toFirstProgFP);
- fromFirstProgFP = toFirstProgFP = NULL;
- if (kill(firstProgramPID, SIGTERM)==0)
- wait((union wait *)0);
-
- }
- firstProgramPID = 0;
-
- if (firstProgramXID != 0)
- XtRemoveInput(firstProgramXID);
- firstProgramXID = 0;
-
- if (secondProgramPID != 0) {
- if (kill(secondProgramPID, 0) == 0)
- SendToProgram("quit\n", toSecondProgFP);
- fclose(fromSecondProgFP);
- fclose(toSecondProgFP);
- fromSecondProgFP = toSecondProgFP = NULL;
- if (kill(secondProgramPID, SIGTERM)==0)
- wait((union wait *)0);
- }
- secondProgramPID = 0;
-
- if (secondProgramXID != 0)
- XtRemoveInput(secondProgramXID);
- secondProgramXID = 0;
-
- if (matchMode != MatchFalse) exit(0);
- }
-
- void CommentPopDown()
- {
- Arg args[2];
-
- XtSetArg(args[0], XtNx, &commentX);
- XtSetArg(args[1], XtNy, &commentY);
- XtGetValues(commentShell, args, 2);
- XtPopdown(commentShell);
- XtDestroyWidget(commentShell);
- commentUp = False;
- }
-
-
- void CommentPopUp(label)
- char *label;
- {
- Arg args[2];
- Position x, y;
- Dimension bw_width, pw_width;
-
- if (commentUp) CommentPopDown();
-
- XtSetArg(args[0], XtNwidth, &bw_width);
- XtGetValues(formWidget, args, 1);
-
- XtSetArg(args[0], XtNresizable, True);
- XtSetArg(args[1], XtNwidth, bw_width - 8);
-
- commentShell =
- XtCreatePopupShell("Comment", transientShellWidgetClass,
- commandsWidget, args, 2);
-
- XtSetArg(args[0], XtNlabel, label);
-
- (void) XtCreateManagedWidget("commentLabel", labelWidgetClass,
- commentShell, args, 1);
-
- XtRealizeWidget(commentShell);
-
- XtSetArg(args[0], XtNwidth, &pw_width);
- XtGetValues(commentShell, args, 1);
-
- if (commentX == -1) {
- XtTranslateCoords(shellWidget, (bw_width - pw_width) / 2, -50, &x, &y);
- } else {
- x = commentX - appData.borderXoffset;
- y = commentY - appData.borderYoffset;
- }
-
- XtSetArg(args[0], XtNx, x);
- XtSetArg(args[1], XtNy, y);
- XtSetValues(commentShell, args, 2);
-
- XtPopup(commentShell, XtGrabNone);
-
- commentUp = True;
- }
-
- void FileNamePopUp(label, def, proc)
- char *label;
- char *def;
- Boolean (*proc) P((char *name));
- {
- Arg args[2];
- Widget popup, dialog;
- Dimension bw_width, pw_width;
- Window root, child;
- int x, y;
- int win_x, win_y;
- unsigned int mask;
-
- fileProc = proc;
-
- XtSetArg(args[0], XtNwidth, &bw_width);
- XtGetValues(boardWidget, args, 1);
-
- XtSetArg(args[0], XtNresizable, True);
- XtSetArg(args[1], XtNwidth, DIALOG_SIZE);
-
- popup =
- XtCreatePopupShell("File Name Prompt", transientShellWidgetClass,
- commandsWidget, args, 2);
-
- XtSetArg(args[0], XtNlabel, label);
- XtSetArg(args[1], XtNvalue, def);
-
- dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
- popup, args, 2);
-
- XawDialogAddButton(dialog, "ok", FileNameCallback, (XtPointer) dialog);
- XawDialogAddButton(dialog, "cancel", FileNameCallback,
- (XtPointer) dialog);
-
- XtRealizeWidget(popup);
-
- XtSetArg(args[0], XtNwidth, &pw_width);
- XtGetValues(popup, args, 1);
-
- XQueryPointer(xDisplay, xBoardWindow, &root, &child,
- &x, &y, &win_x, &win_y, &mask);
-
- XtSetArg(args[0], XtNx, x - 10);
- XtSetArg(args[1], XtNy, y - 10);
- XtSetValues(popup, args, 2);
-
- XtPopup(popup, XtGrabExclusive);
- filenameUp = True;
-
- XtSetKeyboardFocus(shellWidget, popup);
- }
-
- void FileNameCallback(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
- {
- String name;
- Arg args[1];
-
- XtSetArg(args[0], XtNlabel, &name);
- XtGetValues(w, args, 1);
-
- if (strcmp(name, "cancel") == 0) {
- XtPopdown(w = XtParent(XtParent(w)));
- XtDestroyWidget(w);
- filenameUp = False;
- ModeHighlight();
- return;
- }
-
- FileNameAction(w, NULL, NULL, NULL);
- }
-
- void FileNameAction(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- char buf[MSG_SIZ];
- String name;
-
- name = XawDialogGetValueString(w = XtParent(w));
-
- if ((name != NULL) && (*name != NULLCHAR)) {
- strcpy(buf, name);
- XtPopdown(w = XtParent(w));
- XtDestroyWidget(w);
- filenameUp = False;
- (void) (*fileProc)(buf); /* I can't see a way not
- to use a global here */
- ModeHighlight();
- return;
- }
-
- XtPopdown(w = XtParent(w));
- XtDestroyWidget(w);
- filenameUp = False;
- ModeHighlight();
- }
-
- typedef struct {
- ChessSquare piece;
- int to_x, to_y;
- } PromotionMoveInfo;
-
- static PromotionMoveInfo pmi; /*making this global is gross */
-
- void PromotionPopUp(piece, to_x, to_y)
- ChessSquare piece;
- int to_x, to_y;
- {
- Arg args[2];
- Widget dialog;
- Position x, y;
- Dimension bw_width, bw_height, pw_width, pw_height;
-
- pmi.piece = piece;
- pmi.to_x = to_x;
- pmi.to_y = to_y;
-
- XtSetArg(args[0], XtNwidth, &bw_width);
- XtSetArg(args[1], XtNheight, &bw_height);
- XtGetValues(boardWidget, args, 2);
-
- XtSetArg(args[0], XtNresizable, True);
- promotionShell =
- XtCreatePopupShell("Promotion", transientShellWidgetClass,
- commandsWidget, args, 1);
-
- XtSetArg(args[0], XtNlabel, "Promote pawn to what?");
- dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
- promotionShell, args, 1);
-
- XawDialogAddButton(dialog, "Queen", PromotionCallback,
- (XtPointer) dialog);
- XawDialogAddButton(dialog, "Rook", PromotionCallback,
- (XtPointer) dialog);
- XawDialogAddButton(dialog, "Bishop", PromotionCallback,
- (XtPointer) dialog);
- XawDialogAddButton(dialog, "Knight", PromotionCallback,
- (XtPointer) dialog);
- XawDialogAddButton(dialog, "cancel", PromotionCallback,
- (XtPointer) dialog);
-
- XtRealizeWidget(promotionShell);
-
- XtSetArg(args[0], XtNwidth, &pw_width);
- XtSetArg(args[1], XtNheight, &pw_height);
- XtGetValues(promotionShell, args, 2);
-
- XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
- LINE_GAP + squareSize/3 +
- ((piece == WhitePawn) ^ (flipView) ?
- 0 : 6*(squareSize + LINE_GAP)), &x, &y);
-
- XtSetArg(args[0], XtNx, x);
- XtSetArg(args[1], XtNy, y);
- XtSetValues(promotionShell, args, 2);
-
- XtPopup(promotionShell, XtGrabNone);
-
- promotionUp = True;
- }
-
- void PromotionCallback(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
- {
- String name;
- Arg args[1];
- ChessMove move_type;
- int promoChar;
-
- XtSetArg(args[0], XtNlabel, &name);
- XtGetValues(w, args, 1);
-
- XtPopdown(w = XtParent(XtParent(w)));
- XtDestroyWidget(w);
- promotionUp = False;
-
- if (fromX == -1) return;
-
- if (strcmp(name, "cancel") == 0) {
- fromX = fromY = -1;
- return;
- } else if (strcmp(name, "Knight") == 0) {
- promoChar = 'n';
- } else {
- promoChar = ToLower(name[0]);
- }
-
- move_type = LegalityTest(WhiteOnMove(forwardMostMove),
- boards[forwardMostMove], fromY, fromX,
- pmi.to_y, pmi.to_x, promoChar);
- if (move_type == BadMove) {
- DisplayMessage("Illegal move");
- fromX = fromY = -1;
- return;
- }
- MakeMove(&move_type, fromX, fromY, pmi.to_x, pmi.to_y);
- FinishUserMove(move_type, pmi.to_x, pmi.to_y);
- }
-
- void SelectCommand(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
- {
- XawListReturnStruct *list_return = XawListShowCurrent(w);
-
- fromX = fromY = -1;
-
- if (promotionUp) {
- XtPopdown(promotionShell);
- XtDestroyWidget(promotionShell);
- promotionUp = False;
- }
-
- (*buttonProcs[list_return->list_index])(w, NULL, NULL, NULL);
-
- if (!filenameUp) ModeHighlight();
- }
-
- void HighlightProcButton(proc)
- XtActionProc proc;
- {
- int i = 0;
-
- if (proc == NULL) {
- XawListUnhighlight(commandsWidget);
- return;
- }
-
- for (;;) {
- if (buttonProcs[i] == NULL) {
- XawListUnhighlight(commandsWidget);
- return;
- }
- if (buttonProcs[i] == proc) {
- XawListHighlight(commandsWidget, i);
- return;
- }
- i++;
- }
- }
-
- void ModeHighlight()
- {
- switch (gameMode) {
- case BeginningOfGame:
- if (appData.icsActive)
- HighlightProcButton(NULL);
- else if (appData.noChessProgram)
- HighlightProcButton(ForceProc);
- else
- HighlightProcButton(MachineBlackProc);
- break;
- case MachinePlaysBlack:
- HighlightProcButton(MachineBlackProc);
- break;
- case MachinePlaysWhite:
- HighlightProcButton(MachineWhiteProc);
- break;
- case TwoMachinesPlay:
- HighlightProcButton(TwoMachinesProc);
- break;
- case ForceMoves:
- if (appData.icsActive)
- HighlightProcButton(NULL);
- else
- HighlightProcButton(ForceProc);
- break;
- case PlayFromGameFile:
- HighlightProcButton(LoadGameProc);
- break;
- case PauseGame:
- HighlightProcButton(PauseProc);
- break;
- case EditPosition:
- HighlightProcButton(EditPositionProc);
- break;
- case EndOfGame:
- default:
- HighlightProcButton(NULL);
- break;
- }
- }
-
- /*
- * Button procedures
- */
- void QuitProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- /* Save game if resource set and not already saved */
- if (*endMessage == NULLCHAR) {
- if (appData.saveGameFile[0] != NULLCHAR)
- SaveGame(appData.saveGameFile);
- if (appData.savePositionFile[0] != NULLCHAR)
- SavePosition(appData.savePositionFile);
- }
- ShutdownChessPrograms(NULL);
- if (telnetPID != 0) {
- if (kill(telnetPID, SIGTERM) == 0)
- wait((union wait *) 0);
- }
- exit(0);
- }
-
- void CallFlagProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- /* Call your opponent's flag (claim a win on time) */
- if (appData.icsActive) {
- SendToICS("flag\n");
- } else {
- switch (gameMode) {
- default:
- return;
- case MachinePlaysWhite:
- if (whiteFlag) {
- if (blackFlag)
- ShutdownChessPrograms("Draw (both players ran out of time)");
- else
- ShutdownChessPrograms("Black wins on time");
- }
- break;
- case MachinePlaysBlack:
- if (blackFlag) {
- if (whiteFlag)
- ShutdownChessPrograms("Draw (both players ran out of time)");
- else
- ShutdownChessPrograms("White wins on time");
- }
- break;
- }
- }
- }
-
- void DrawProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- /* Offer draw or accept pending draw offer from opponent */
-
- if (appData.icsActive) {
- /* Note: tournament rules require draw offers to be
- made after you make your move but before you punch
- your clock. Currently ICS doesn't let you do that;
- instead, you always punch your clock after making a
- move, but you can offer a draw at any time. */
-
- SendToICS("draw\n");
- } else {
- /* Currently GNU Chess doesn't offer or accept draws
- at all, so there is no Draw button in GNU Chess
- mode. */
-
- fprintf(stderr, "Draw function not implemented\n");
- }
- }
-
-
- void DeclineDrawProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- /* Decline a pending draw offer from opponent */
-
- if (appData.icsActive) {
- /* Note: ICS also lets you withdraw your own draw
- offer with this command. I'm not sure how long
- your draw offer remains pending if you don't
- withdraw it. */
-
- SendToICS("decline draw\n");
- } else {
- /* Currently GNU Chess doesn't offer or accept draws
- at all, so there is no Decline Draw button in
- GNU Chess mode. */
-
- fprintf(stderr, "Decline Draw function not implemented\n");
- }
- }
-
-
- void ResignProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- /* Resign. You can do this even if it's not your turn. */
-
- if (appData.icsActive) {
- SendToICS("resign\n");
- } else {
- /* This button is not currently used in GNU Chess mode,
- but it should work. */
-
- switch (gameMode) {
- case MachinePlaysWhite:
- ShutdownChessPrograms("Black resigns");
- break;
- case MachinePlaysBlack:
- ShutdownChessPrograms("White resigns");
- break;
- default:
- break;
- }
- }
- }
-
-
- Boolean LoadGame(name)
- char *name;
- {
- char buf[MSG_SIZ], lname[MSG_SIZ];
- ChessMove cm;
- int gameNumber;
- char *p;
-
- if (gameMode != BeginningOfGame) {
- DisplayMessage("Press Reset first");
- return False;
- }
-
- /* Parse game number if given */
- strcpy(lname, name);
- p = strrchr(lname, ' ');
- if (p == NULL) {
- gameNumber = 1;
- } else {
- *p++ = NULLCHAR;
- gameNumber = atoi(p);
- }
-
- yynewfile();
- if ((gameFileFP = fopen(lname, "r")) == NULL) {
- sprintf(buf, "Can't open %s", lname);
- DisplayMessage(buf);
- return False;
- }
-
- p = strrchr(name, '/');
- if (p == NULL)
- p = name;
- else
- p++;
- DisplayTitle(p);
-
- lastGameMode = gameMode = PlayFromGameFile;
- ModeHighlight();
- InitPosition(True);
- DisplayClocks(StopTimers);
- if (firstProgramXID == 0) {
- InitChessProgram(appData.firstHost, appData.firstChessProgram,
- &firstProgramPID, &toFirstProgFP,
- &fromFirstProgFP, &firstProgramXID,
- &firstSendTime);
- } else {
- SendToProgram(appData.initString, toFirstProgFP);
- SendSearchDepth(toFirstProgFP);
- }
- SendToProgram("force\n", toFirstProgFP);
-
- /*
- * Skip the first gameNumber-1 games in the file.
- * Also skip over anything that precedes an identifiable
- * StartGame marker, to avoid being confused by
- * garbage at the start of the file. Currently
- * recognized StartGame markers are the move number "1",
- * the pattern "gnuchess .* game", or a position diagram.
- */
- cm = StartGame;
- while (gameNumber > 0) {
- yyboardindex = forwardMostMove;
- cm = (ChessMove) yylex();
- if (cm == (ChessMove) 0) {
- Reset(True);
- DisplayMessage("Game not found in file");
- return False;
- }
- if (cm == StartGame || cm == PositionDiagram)
- gameNumber--;
- }
-
- /* If the file starts with a position diagram,
- set up the position */
- if (cm == PositionDiagram) {
- Board initial_position;
- int i, j;
- char *p = yytext;
-
- startedFromSetupPosition = True;
-
- for (i = BOARD_SIZE - 1; i >= 0; i--)
- for (j = 0; j < BOARD_SIZE; p++)
- switch (*p) {
- case '[':
- case '-':
- case ' ':
- case '\t':
- case '\n':
- break;
- default:
- initial_position[i][j++] = CharToPiece(*p);
- break;
- }
-
- while (*p == ' ' || *p == '\t' || *p == '\n') p++;
-
- if (strncmp(p, "black", strlen("black"))==0)
- blackPlaysFirst = True;
- else
- blackPlaysFirst = False;
-
- if (blackPlaysFirst) {
- CopyBoard(boards[0], initial_position);
- strcpy(moveList[0], "");
- strcpy(parseList[0], "");
- currentMove = forwardMostMove = backwardMostMove = 1;
- CopyBoard(boards[1], initial_position);
- SendToProgram("a3\n", toFirstProgFP);
- SendCurrentBoard(toFirstProgFP);
- } else {
- currentMove = forwardMostMove = backwardMostMove = 0;
- CopyBoard(boards[0], initial_position);
- SendCurrentBoard(toFirstProgFP);
- }
-
- DrawPosition(boardWidget, NULL, NULL, NULL);
- }
-
- DisplayClocks(ResetTimers);
- timeRemaining[0][forwardMostMove] = whiteTimeRemaining;
- timeRemaining[1][forwardMostMove] = blackTimeRemaining;
-
- LoadGameLoop();
-
- return True;
- }
-
- void ResurrectChessProgram()
- /* Get out of EndOfGame mode. This may require us to restart the
- chess program and feed it all the moves made so far. */
- {
- char buf[MSG_SIZ];
- int i;
-
- /* assert(gameMode == EndOfGame) */
-
- gameMode = lastGameMode = ForceMoves;
- ModeHighlight();
-
- if (firstProgramPID != 0) return;
-
- InitChessProgram(appData.firstHost, appData.firstChessProgram,
- &firstProgramPID, &toFirstProgFP, &fromFirstProgFP,
- &firstProgramXID, &firstSendTime);
- SendToProgram("force\n", toFirstProgFP);
-
- if (startedFromSetupPosition) {
- if (backwardMostMove % 2 == 1)
- SendToProgram("a3\n", toFirstProgFP);
- SendBoard(toFirstProgFP, boards[backwardMostMove]);
- }
-
- for (i = backwardMostMove; i < currentMove; i++) {
- strcpy(buf, moveList[i]);
- SendToProgram(buf, toFirstProgFP);
- }
-
- if (!firstSendTime) {
- /* can't tell gnuchess what its clock should read,
- so we bow to its notion. */
- DisplayClocks(ResetTimers);
- timeRemaining[0][currentMove] = whiteTimeRemaining;
- timeRemaining[1][currentMove] = blackTimeRemaining;
- }
- }
-
- void MachineBlackProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- if (gameMode == PauseGame) PauseProc(w, event, prms, nprms);
- if (gameMode == PlayFromGameFile) ForceProc(w, event, prms, nprms);
- if (gameMode == EditPosition) EditPositionDone();
-
- if ((gameMode == EndOfGame) || (gameMode == TwoMachinesPlay) ||
- (appData.noChessProgram) || (gameMode == MachinePlaysBlack))
- return;
-
- if (WhiteOnMove(gameMode == ForceMoves ? currentMove : forwardMostMove)) {
- DisplayMessage("It is not Black's turn");
- return;
- }
-
- if (gameMode == ForceMoves) forwardMostMove = currentMove;
-
- lastGameMode = gameMode = MachinePlaysBlack;
- ModeHighlight();
- SendToProgram(appData.blackString, toFirstProgFP);
- DisplayClocks(StartTimers);
- }
-
- void ForwardProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- char buf[MSG_SIZ];
- int target;
- unsigned int state;
-
- if ((gameMode == EndOfGame) || (gameMode == EditPosition))
- return;
-
- if (gameMode == PlayFromGameFile)
- PauseProc(w, event, prms, nprms);
-
- if (currentMove >= forwardMostMove) {
- if (gameFileFP != NULL)
- (void) LoadGameOneMove();
- return;
- }
-
- if (event == NULL) {
- /* Kludge */
- Window root, child;
- int root_x, root_y;
- int win_x, win_y;
- XQueryPointer(xDisplay, xBoardWindow,
- &root, &child, &root_x, &root_y,
- &win_x, &win_y, &state);
- } else {
- state = event->xkey.state;
- }
-
- if (state & ShiftMask)
- target = forwardMostMove;
- else
- target = currentMove + 1;
-
- if (gameMode == ForceMoves) {
- while (currentMove < target) {
- strcpy(buf, moveList[currentMove++]);
- SendToProgram(buf, toFirstProgFP);
- }
- } else {
- currentMove = target;
- }
-
- if (!appData.icsActive && gameMode == ForceMoves) {
- whiteTimeRemaining = timeRemaining[0][currentMove];
- blackTimeRemaining = timeRemaining[1][currentMove];
- }
- DisplayClocks(ReDisplayTimers);
- DisplayMove(currentMove - 1);
- DrawPosition(boardWidget, NULL, NULL, NULL);
- }
-
-
- void ResetProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- Reset(True);
- }
-
- void Reset(redraw)
- int redraw;
- {
- flipView = False;
- startedFromSetupPosition = blackPlaysFirst = False;
- matchMode = MatchFalse;
- firstMove = True;
- whiteFlag = blackFlag = False;
- maybeThinking = False;
- endMessage[0] = NULLCHAR;
- ics_white[0] = ics_black[0] = NULLCHAR;
- ics_user_moved = ics_getting_history = False;
- ics_mode = IcsIdle;
- ics_gamenum = -1;
-
- ShutdownChessPrograms(NULL);
- lastGameMode = gameMode = BeginningOfGame;
- ModeHighlight();
- InitPosition(redraw);
- DisplayClocks(ResetTimers);
- timeRemaining[0][0] = whiteTimeRemaining;
- timeRemaining[1][0] = blackTimeRemaining;
- InitChessProgram(appData.firstHost, appData.firstChessProgram,
- &firstProgramPID, &toFirstProgFP,
- &fromFirstProgFP, &firstProgramXID, &firstSendTime);
- DisplayTitle("");
- DisplayMessage("");
- if (commentUp) CommentPopDown();
- if (promotionUp) {
- XtPopdown(promotionShell);
- XtDestroyWidget(promotionShell);
- promotionUp = False;
- }
- }
-
- void LoadPositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- if (gameMode != BeginningOfGame) {
- DisplayMessage("Press Reset first");
- return;
- }
- FileNamePopUp("Position file name?", "", LoadPosition);
- }
-
- Boolean LoadPosition(name)
- char *name;
- {
- char *p, line[MSG_SIZ], buf[MSG_SIZ];
- Board initial_position;
- FILE *fp;
- int i, j, positionNumber;
-
- if (gameMode != BeginningOfGame) {
- DisplayMessage("Press Reset first");
- return False;
- }
-
- /* Parse position number if given */
- strcpy(line, name);
- p = strrchr(line, ' ');
- if (p == NULL) {
- positionNumber = 0;
- } else {
- *p++ = NULLCHAR;
- positionNumber = atoi(p);
- }
-
- if ((fp = fopen(line, "r")) == NULL) {
- sprintf(buf, "Can't open %s", line);
- DisplayMessage(buf);
- return False;
- }
-
- p = strrchr(name, '/');
- if (p == NULL)
- p = name;
- else
- p++;
- DisplayTitle(p);
-
- lastGameMode = gameMode = ForceMoves;
- ModeHighlight();
- startedFromSetupPosition = True;
-
- if (firstProgramXID == 0)
- InitChessProgram(appData.firstHost, appData.firstChessProgram,
- &firstProgramPID, &toFirstProgFP,
- &fromFirstProgFP, &firstProgramXID, &firstSendTime);
-
- if (positionNumber == 0) {
- /* Backward compatibility---don't look for '#' */
- (void) fgets(line, MSG_SIZ, fp);
- } else {
- while (positionNumber > 0) {
- /* skip postions before number positionNumber */
- if (fgets(line, MSG_SIZ, fp) == NULL) {
- Reset(True);
- DisplayMessage("Position not found in file");
- return False;
- }
- if (line[0] == '#') positionNumber--;
- }
- }
-
- (void) fgets(line, MSG_SIZ, fp);
- (void) fgets(line, MSG_SIZ, fp);
-
- for (i = BOARD_SIZE - 1; i >= 0; i--) {
- (void) fgets(line, MSG_SIZ, fp);
- for (p = line, j = 0; j < BOARD_SIZE; p++) {
- if (*p == ' ')
- continue;
- initial_position[i][j++] = CharToPiece(*p);
- }
- }
-
- blackPlaysFirst = False;
- if (!feof(fp)) {
- (void) fgets(line, MSG_SIZ, fp);
- if (strncmp(line, "black", strlen("black"))==0)
- blackPlaysFirst = True;
- }
- fclose(fp);
-
- if (blackPlaysFirst) {
- CopyBoard(boards[0], initial_position);
- strcpy(moveList[0], "");
- strcpy(parseList[0], "");
- currentMove = forwardMostMove = backwardMostMove = 1;
- CopyBoard(boards[1], initial_position);
- SendToProgram("force\na3\n", toFirstProgFP);
- SendCurrentBoard(toFirstProgFP);
- DisplayMessage("Black to play");
- } else {
- currentMove = forwardMostMove = backwardMostMove = 0;
- CopyBoard(boards[0], initial_position);
- SendCurrentBoard(toFirstProgFP);
- SendToProgram("force\n", toFirstProgFP);
- DisplayMessage("White to play");
- }
-
- DisplayClocks(ResetTimers);
- timeRemaining[0][1] = whiteTimeRemaining;
- timeRemaining[1][1] = blackTimeRemaining;
-
- DrawPosition(boardWidget, NULL, NULL, NULL);
-
- return (int) True;
- }
-
- void EditPositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- if (gameMode == EditPosition) {
- ForceProc(w, event, prms, nprms);
- return;
- }
-
- ForceProc(w, event, prms, nprms);
- if (gameMode != ForceMoves) return;
-
- DisplayTitle("<-- Press to set side to play next");
- DisplayMessage("Mouse: 1=drag, 2=white, 3=black");
-
- lastGameMode = gameMode = EditPosition;
- ModeHighlight();
- if (currentMove > 0)
- CopyBoard(boards[0], boards[currentMove]);
-
- blackPlaysFirst = !WhiteOnMove(currentMove);
- DisplayClocks(ResetTimers);
- currentMove = forwardMostMove = backwardMostMove = 0;
- }
-
- void EditPositionDone()
- {
- startedFromSetupPosition = True;
- SendToProgram(appData.initString, toFirstProgFP);
- SendSearchDepth(toFirstProgFP);
- if (blackPlaysFirst) {
- strcpy(moveList[0], "");
- strcpy(parseList[0], "");
- currentMove = forwardMostMove = backwardMostMove = 1;
- CopyBoard(boards[1], boards[0]);
- SendToProgram("force\na3\n", toFirstProgFP);
- SendCurrentBoard(toFirstProgFP);
- DisplayTitle("");
- DisplayMessage("Black to play");
- } else {
- currentMove = forwardMostMove = backwardMostMove = 0;
- SendCurrentBoard(toFirstProgFP);
- SendToProgram("force\n", toFirstProgFP);
- DisplayTitle("");
- DisplayMessage("White to play");
- }
- timeRemaining[0][forwardMostMove] = whiteTimeRemaining;
- timeRemaining[1][forwardMostMove] = blackTimeRemaining;
- lastGameMode = gameMode = ForceMoves;
- }
-
- void MachineWhiteProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- if (gameMode == PauseGame) PauseProc(w, event, prms, nprms);
- if (gameMode == PlayFromGameFile) ForceProc(w, event, prms, nprms);
- if (gameMode == EditPosition) EditPositionDone();
-
- if ((gameMode == EndOfGame) || (gameMode == TwoMachinesPlay) ||
- (appData.noChessProgram) || (gameMode == MachinePlaysWhite))
- return;
-
- if (!WhiteOnMove(gameMode == ForceMoves ? currentMove : forwardMostMove)) {
- DisplayMessage("It is not White's turn");
- return;
- }
-
- if (gameMode == ForceMoves) forwardMostMove = currentMove;
-
- lastGameMode = gameMode = MachinePlaysWhite;
- ModeHighlight();
- SendToProgram(appData.whiteString, toFirstProgFP);
- DisplayClocks(StartTimers);
- }
-
- void BackwardProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- int target;
- unsigned int state;
-
- if ((currentMove <= backwardMostMove) || (gameMode == EditPosition))
- return;
-
- if (gameMode == EndOfGame)
- ResurrectChessProgram();
-
- if (gameMode == PlayFromGameFile)
- PauseProc(w, event, prms, nprms);
-
- if (event == NULL) {
- /* Kludge */
- Window root, child;
- int root_x, root_y;
- int win_x, win_y;
- XQueryPointer(xDisplay, xBoardWindow,
- &root, &child, &root_x, &root_y,
- &win_x, &win_y, &state);
- } else {
- state = event->xkey.state;
- }
- if (state & ShiftMask)
- target = backwardMostMove;
- else
- target = currentMove - 1;
-
- if (gameMode == ForceMoves) {
- Attention(firstProgramPID);
- while (currentMove > target) {
- SendToProgram("undo\n", toFirstProgFP);
- currentMove--;
- }
- } else {
- currentMove = target;
- }
-
- if (!appData.icsActive && gameMode == ForceMoves) {
- whiteTimeRemaining = timeRemaining[0][currentMove];
- blackTimeRemaining = timeRemaining[1][currentMove];
- }
- DisplayClocks(ReDisplayTimers);
- DisplayMove(currentMove - 1);
- DrawPosition(boardWidget, NULL, NULL, NULL);
- }
-
- void FlipViewProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- flipView = !flipView;
- DrawPosition(boardWidget, NULL, NULL, NULL);
- }
-
- void SaveGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- char def[MSG_SIZ];
-
- if (appData.icsActive && ics_white[0] != NULLCHAR) {
- sprintf(def, "%s-%s.game", ics_white, ics_black);
- } else {
- def[0] = NULLCHAR;
- }
- FileNamePopUp("Filename for saved game?", def, SaveGame);
- }
-
- Boolean SaveGame(name)
- char *name;
- {
- char buf[MSG_SIZ];
- int i;
- time_t tm;
-
- if ((gameFileFP = fopen(name, "a")) == NULL) {
- sprintf(buf, "Can't open %s", name);
- DisplayMessage(buf);
- return False;
- }
-
- tm = time((time_t *) NULL);
-
- fprintf(gameFileFP, "# %s game file -- %s", programName, ctime(&tm));
- PrintOpponents(gameFileFP);
- fprintf(gameFileFP, "\talgebraic\n");
-
- if (backwardMostMove > 0 || startedFromSetupPosition) {
- fprintf(gameFileFP, "[--------------\n");
- PrintPosition(gameFileFP, backwardMostMove);
- fprintf(gameFileFP, "--------------]\n");
- }
- i = backwardMostMove;
- if ((i % 2) == 1 && i < forwardMostMove) {
- fprintf(gameFileFP, "%d. ... %s\n", i/2 + 1, parseList[i]);
- i++;
- }
- while (i < forwardMostMove) {
- fprintf(gameFileFP, "%d. %s ", i/2 + 1, parseList[i]);
- i++;
- if (i >= forwardMostMove) {
- fprintf(gameFileFP, "\n");
- break;
- }
- fprintf(gameFileFP, "%s\n", parseList[i]);
- i++;
- }
-
- if (endMessage[0] != NULLCHAR)
- fprintf(gameFileFP, "%s\n", endMessage);
-
- fclose(gameFileFP);
- gameFileFP = NULL;
- yynewfile();
- return True;
- }
-
- #ifdef notdef
- /* currently unused */
- void SwitchProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- if (appData.noChessProgram) return;
- if (gameMode == PauseGame) PauseProc(w, event);
- switch (gameMode) {
- default:
- return;
- case MachinePlaysWhite:
- if (WhiteOnMove(forwardMostMove)) {
- DisplayMessage("Wait until your turn");
- return;
- }
- lastGameMode = gameMode = MachinePlaysBlack;
- ModeHighlight();
- break;
- case BeginningOfGame:
- case MachinePlaysBlack:
- if (!WhiteOnMove(forwardMostMove)) {
- DisplayMessage("Wait until your turn");
- return;
- }
- if (forwardMostMove == 0) {
- MachineWhiteProc(w, event);
- return;
- }
- lastGameMode = gameMode = MachinePlaysWhite;
- ModeHighlight();
- break;
- }
-
- Attention(firstProgramPID);
- SendToProgram("switch\n", toFirstProgFP);
- }
- #endif /*notdef*/
-
- void ForceProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- int i;
-
- if (gameMode == PauseGame) PauseProc(w, event, prms, nprms);
- switch (gameMode) {
- case MachinePlaysWhite:
- if (WhiteOnMove(forwardMostMove)) {
- DisplayMessage("Wait until your turn");
- return;
- }
- Attention(firstProgramPID);
- SendToProgram("force\n", toFirstProgFP);
- break;
- case MachinePlaysBlack:
- if (!WhiteOnMove(forwardMostMove)) {
- DisplayMessage("Wait until your turn");
- return;
- }
- Attention(firstProgramPID);
- SendToProgram("force\n", toFirstProgFP);
- break;
- case BeginningOfGame:
- SendToProgram("force\n", toFirstProgFP);
- break;
- case PlayFromGameFile:
- if (readGameXID != 0) {
- XtRemoveTimeOut(readGameXID);
- readGameXID = 0;
- }
- if (gameFileFP != NULL) {
- fclose(gameFileFP);
- gameFileFP = NULL;
- yynewfile();
- }
- break;
- case EndOfGame:
- ResurrectChessProgram();
- return;
- case EditPosition:
- EditPositionDone();
- break;
- case TwoMachinesPlay:
- ShutdownChessPrograms("");
- ResurrectChessProgram();
- return;
- default:
- return;
- }
-
- if (gameMode == MachinePlaysWhite ||
- gameMode == MachinePlaysBlack ||
- gameMode == TwoMachinesPlay ||
- gameMode == PlayFromGameFile) {
- i = forwardMostMove;
- while (i > currentMove) {
- SendToProgram("undo\n", toFirstProgFP);
- i--;
- }
- whiteTimeRemaining = timeRemaining[0][currentMove];
- blackTimeRemaining = timeRemaining[1][currentMove];
- if (whiteFlag || blackFlag) {
- whiteFlag = blackFlag = 0;
- }
- DisplayTitle("");
- }
-
- lastGameMode = gameMode = ForceMoves;
- ModeHighlight();
-
- DisplayClocks(StopTimers);
- }
-
- void NothingProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- return;
- }
-
- void HintProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- if (appData.noChessProgram) return;
- switch (gameMode) {
- case MachinePlaysWhite:
- if (WhiteOnMove(forwardMostMove)) {
- DisplayMessage("Wait until your turn");
- return;
- }
- break;
- case BeginningOfGame:
- case MachinePlaysBlack:
- if (!WhiteOnMove(forwardMostMove)) {
- DisplayMessage("Wait until your turn");
- return;
- }
- break;
- default:
- DisplayMessage("No hint available");
- return;
- }
- Attention(firstProgramPID);
- SendToProgram("hint\n", toFirstProgFP);
- }
-
- void PrintPosition(fp, move)
- FILE *fp;
- int move;
- {
- int i, j;
-
- for (i = BOARD_SIZE - 1; i >= 0; i--) {
- for (j = 0; j < BOARD_SIZE; j++) {
- fprintf(fp, "%c", PieceToChar(boards[move][i][j]));
- fputc(j == BOARD_SIZE - 1 ? '\n' : ' ', fp);
- }
- }
- if ((gameMode == EditPosition) ? !blackPlaysFirst : (move % 2 == 0))
- fprintf(fp, "white to play\n");
- else
- fprintf(fp, "black to play\n");
- }
-
- void PrintOpponents(fp)
- FILE *fp;
- {
- char host_name[MSG_SIZ];
-
- #if defined(SVR4) && defined(sun)
- sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);
- #else
- gethostname(host_name, MSG_SIZ);
- #endif
- switch (lastGameMode) {
- case MachinePlaysWhite:
- fprintf(fp, "\t%s@%s vs. %s@%s\n", appData.firstChessProgram,
- appData.firstHost, getpwuid(getuid())->pw_name,
- host_name);
- break;
- case MachinePlaysBlack:
- fprintf(fp, "\t%s@%s vs. %s@%s\n", getpwuid(getuid())->pw_name,
- host_name, appData.firstChessProgram,
- appData.firstHost);
- break;
- case TwoMachinesPlay:
- fprintf(fp, "\t%s@%s vs. %s@%s\n", appData.secondChessProgram,
- appData.secondHost, appData.firstChessProgram,
- appData.firstHost);
- break;
- default:
- if (appData.icsActive && ics_white[0] != NULLCHAR) {
- fprintf(fp, "\t%s vs. %s\n",
- ics_white, ics_black);
- } else {
- fprintf(fp, "\n");
- }
- break;
- }
- }
-
- void SavePositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- char def[MSG_SIZ];
-
- if (appData.icsActive && ics_white[0] != NULLCHAR) {
- sprintf(def, "%s-%s.pos", ics_white, ics_black);
- } else {
- def[0] = NULLCHAR;
- }
- FileNamePopUp("Filename for saved position?", def, SavePosition);
- }
-
- Boolean SavePosition(name)
- char *name;
- {
- char buf[MSG_SIZ];
- FILE *fp;
- time_t tm;
-
- if ((fp = fopen(name, "a")) == NULL) {
- sprintf(buf, "Can't open %s", name);
- DisplayMessage(buf);
- return False;
- }
-
- tm = time((time_t *) NULL);
-
- fprintf(fp, "# %s position file -- %s", programName, ctime(&tm));
- PrintOpponents(fp);
- fprintf(fp, "\n");
- PrintPosition(fp, currentMove);
- fclose(fp);
- return True;
- }
-
- void TwoMachinesProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- int i;
- MatchMode matchKind;
-
- if (gameMode == PauseGame) PauseProc(w, event, prms, nprms);
- if (gameMode == PlayFromGameFile) ForceProc(w, event, prms, nprms);
- if ((gameMode == EndOfGame) || (gameMode == TwoMachinesPlay)
- || appData.noChessProgram)
- return;
-
- if (matchMode == MatchFalse) {
- switch (gameMode) {
- case PauseGame:
- case PlayFromGameFile:
- return;
- case MachinePlaysWhite:
- case MachinePlaysBlack:
- ForceProc(w, event, prms, nprms);
- if (gameMode != ForceMoves) return;
- matchKind = MatchOpening;
- break;
- case ForceMoves:
- matchKind = MatchOpening;
- break;
- case EditPosition:
- EditPositionDone();
- matchKind = MatchPosition;
- break;
- case BeginningOfGame:
- default:
- matchKind = MatchInit;
- break;
- }
- } else {
- matchKind = matchMode;
- }
-
- forwardMostMove = currentMove;
-
- flipView = False;
- firstMove = False;
-
- switch (matchKind) {
- case MatchOpening:
- if (firstProgramXID == 0) {
- if (*appData.loadGameFile == NULLCHAR) {
- DisplayMessage("You need to specify a game file");
- return;
- }
- InitChessProgram(appData.firstHost,
- appData.firstChessProgram,
- &firstProgramPID, &toFirstProgFP,
- &fromFirstProgFP, &firstProgramXID,
- &firstSendTime);
- if (!LoadGame(appData.loadGameFile)) {
- ShutdownChessPrograms("Bad game file");
- return;
- }
- DrawPosition(boardWidget, NULL, NULL, NULL);
- }
- InitChessProgram(appData.secondHost,
- appData.secondChessProgram,
- &secondProgramPID, &toSecondProgFP,
- &fromSecondProgFP, &secondProgramXID,
- &secondSendTime);
- if (startedFromSetupPosition) {
- if (blackPlaysFirst) {
- SendToProgram("force\na3\n", toSecondProgFP);
- SendBoard(toSecondProgFP,
- boards[backwardMostMove]);
- } else {
- SendBoard(toSecondProgFP,
- boards[backwardMostMove]);
- SendToProgram("force\n", toSecondProgFP);
- }
- } else {
- SendToProgram("force\n", toSecondProgFP);
- }
- for (i = backwardMostMove; i < forwardMostMove; i++)
- SendToProgram(moveList[i], toSecondProgFP);
- lastGameMode = gameMode = TwoMachinesPlay;
- ModeHighlight();
- firstMove = True;
- if (WhiteOnMove(forwardMostMove))
- SendToProgram(appData.whiteString, toSecondProgFP);
- else
- SendToProgram(appData.blackString, toFirstProgFP);
- break;
-
- case MatchPosition:
- if (firstProgramXID == 0) {
- if (*appData.loadPositionFile == NULLCHAR) {
- DisplayMessage("You need to specify a position file");
- return;
- }
- InitChessProgram(appData.firstHost,
- appData.firstChessProgram,
- &firstProgramPID, &toFirstProgFP,
- &fromFirstProgFP, &firstProgramXID,
- &firstSendTime);
- if (!LoadPosition(appData.loadPositionFile))
- return;
- }
- InitChessProgram(appData.secondHost,
- appData.secondChessProgram,
- &secondProgramPID, &toSecondProgFP,
- &fromSecondProgFP, &secondProgramXID,
- &secondSendTime);
- if (blackPlaysFirst)
- SendToProgram("force\na3\n", toSecondProgFP);
- SendCurrentBoard(toSecondProgFP);
- lastGameMode = gameMode = TwoMachinesPlay;
- ModeHighlight();
- firstMove = True;
- if (WhiteOnMove(forwardMostMove))
- SendToProgram(appData.whiteString, toSecondProgFP);
- else
- SendToProgram(appData.blackString, toFirstProgFP);
- break;
-
- case MatchInit:
- InitPosition(True);
- if (firstProgramXID == 0)
- InitChessProgram(appData.firstHost,
- appData.firstChessProgram,
- &firstProgramPID, &toFirstProgFP,
- &fromFirstProgFP, &firstProgramXID,
- &firstSendTime);
- InitChessProgram(appData.secondHost,
- appData.secondChessProgram,
- &secondProgramPID, &toSecondProgFP,
- &fromSecondProgFP, &secondProgramXID,
- &secondSendTime);
- lastGameMode = gameMode = TwoMachinesPlay;
- ModeHighlight();
- SendToProgram(appData.whiteString, toSecondProgFP);
-
- default:
- break;
- }
-
- if (!firstSendTime || !secondSendTime) {
- DisplayClocks(ResetTimers);
- timeRemaining[0][forwardMostMove] = whiteTimeRemaining;
- timeRemaining[1][forwardMostMove] = blackTimeRemaining;
- }
- DisplayClocks(StartTimers);
- }
-
- void PauseProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- switch (gameMode) {
- case EndOfGame:
- case EditPosition:
- default:
- return;
- case ForceMoves:
- if (appData.icsActive) {
- pausePreviousMode = gameMode;
- gameMode = PauseGame;
- ModeHighlight();
- }
- return;
- case PauseGame:
- gameMode = pausePreviousMode;
- ModeHighlight();
- pausePreviousMode = PauseGame;
- if (gameMode == MachinePlaysWhite ||
- gameMode == MachinePlaysBlack) {
- DisplayClocks(StartTimers);
- } else {
- DisplayClocks(ReDisplayTimers);
- }
- if (gameMode == PlayFromGameFile &&
- readGameXID == 0 &&
- appData.timeDelay >= 0) {
- readGameXID =
- XtAppAddTimeOut(appContext,
- (int) (1000 * appData.timeDelay),
- (XtTimerCallbackProc) LoadGameLoop, NULL);
- }
- break;
- case PlayFromGameFile:
- if (readGameXID != 0) {
- XtRemoveTimeOut(readGameXID);
- readGameXID = 0;
- }
- pausePreviousMode = gameMode;
- gameMode = PauseGame;
- ModeHighlight();
- break;
- case BeginningOfGame:
- case MachinePlaysWhite:
- case MachinePlaysBlack:
- case TwoMachinesPlay:
- if (forwardMostMove == 0)
- return; /* don't pause if no one has moved */
- if ((gameMode == MachinePlaysWhite &&
- !WhiteOnMove(forwardMostMove)) ||
- (gameMode == MachinePlaysBlack &&
- WhiteOnMove(forwardMostMove))) {
- DisplayClocks(StopTimers);
- }
- pausePreviousMode = gameMode;
- gameMode = PauseGame;
- ModeHighlight();
- break;
- }
- }
-
- void LoadGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- if (gameMode == PlayFromGameFile) {
- ForceProc(w, event, prms, nprms);
- return;
- }
- if (gameMode != BeginningOfGame) {
- DisplayMessage("Press Reset first");
- return;
- }
- FileNamePopUp("Game file name?", "", LoadGame);
- }
-
- void Iconify(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- Arg args[1];
-
- fromX = fromY = -1;
-
- XtSetArg(args[0], XtNiconic, True);
- XtSetValues(shellWidget, args, 1);
- }
-
- void SendToProgram(message, fp)
- char *message;
- FILE *fp;
- {
- if (fp == NULL) return;
- lastMsgFP = fp;
-
- if (appData.debugMode)
- fprintf(stderr, "Sending to %s: %s\n",
- fp == toFirstProgFP ? "first" : "second", message);
-
- if (message[strlen(message) - 1] != '\n')
- fprintf(fp, "\n%s\n", message);
- else
- fputs(message, fp);
- fflush(fp);
- }
-
- void ReceiveFromProgram(fp, source, id)
- FILE *fp;
- int *source;
- XtInputId *id;
- {
- char message[MSG_SIZ], *end_str, *name, *number;
- extern char *sys_errlist[];
-
- if (fgets(message, MSG_SIZ, fp) == NULL) {
- if (fp == fromFirstProgFP) {
- number = "first";
- name = appData.firstChessProgram;
- } else if (fp == fromSecondProgFP) {
- number = "second";
- name = appData.secondChessProgram;
- } else {
- return;
- }
- if (ferror(fp) == 0) {
- sprintf(message, "%s chess program (%s) exited unexpectedly",
- number, name);
- fprintf(stderr, "%s: %s\n", programName, message);
- } else {
- sprintf(message,
- "error reading from %s chess program (%s): %s",
- number, name, sys_errlist[ferror(fp)]);
- fprintf(stderr, "%s: %s\n", programName, message);
- }
- ShutdownChessPrograms(message);
- return;
- }
-
- if ((end_str = strchr(message, '\r')) != NULL)
- *end_str = NULLCHAR;
- if ((end_str = strchr(message, '\n')) != NULL)
- *end_str = NULLCHAR;
-
- if (appData.debugMode)
- fprintf(stderr, "Received from %s: %s\n",
- fp == fromFirstProgFP ? "first" : "second", message);
- HandleMachineMove(message, fp);
- }
-
- void SendSearchDepth(fp)
- FILE *fp;
- {
- char message[MSG_SIZ];
-
- if (appData.searchDepth <= 0) return;
-
- sprintf(message, "depth\n%d\nhelp\n", appData.searchDepth);
- /* note kludge: "help" command forces gnuchessx to print
- out something that ends with a newline. */
- SendToProgram(message, fp);
- }
-
- void SendTimeRemaining(fp)
- FILE *fp;
- {
- char message[MSG_SIZ];
- long time;
-
- if (WhiteOnMove(forwardMostMove))
- time = whiteTimeRemaining;
- else
- time = blackTimeRemaining;
-
- if (time <= 0) time = 1000;
-
- sprintf(message, "time %d\n", time/10);
- SendToProgram(message, fp);
- }
-
-
- void DisplayMove(moveNumber)
- int moveNumber;
- {
- char message[MSG_SIZ];
-
- if (moveNumber < 0) {
- if (moveNumber == forwardMostMove - 1)
- DisplayMessage(endMessage);
- else
- DisplayMessage("");
- } else {
- sprintf(message, "%d. %s%s %s", moveNumber / 2 + 1,
- WhiteOnMove(moveNumber) ? "" : "... ",
- parseList[moveNumber],
- moveNumber == forwardMostMove - 1 ? endMessage : "");
- DisplayMessage(message);
- }
- }
-
- void DisplayMessage(message)
- char *message;
- {
- Arg arg;
-
- XtSetArg(arg, XtNlabel, message);
- XtSetValues(messageWidget, &arg, 1);
- }
-
- void DisplayTitle(title)
- char *title;
- {
- Arg arg;
-
- XtSetArg(arg, XtNlabel, title);
- XtSetValues(titleWidget, &arg, 1);
- }
-
- /*
- * This routine sends a SIGINT (^C interrupt) to gnuchess to awaken it
- * if it might be busy thinking on our time. This normally isn't needed,
- * but is useful on systems where the FIONREAD ioctl doesn't work (such
- * as ESIX), since on those systems the gnuchess feature that lets you
- * interrupt its thinking just by typing a command does not work.
- *
- * In the future, similar code could be used to stop gnuchess and make
- * it move immediately when it is thinking about its own move; this could
- * be useful if we want to make Backward or ForceMoves work while gnuchess
- * is thinking. --t.mann
- */
- void Attention(pid)
- int pid;
- {
- #if defined(ATTENTION) || defined(ESIX) || !defined(FIONREAD)
- if (appData.noChessProgram || (pid == 0)) return;
- switch (gameMode) {
- case MachinePlaysWhite:
- case MachinePlaysBlack:
- case TwoMachinesPlay:
- if (forwardMostMove > backwardMostMove + 1 && maybeThinking) {
- if (appData.debugMode)
- fprintf(stderr, "Sending SIGINT to %s\n",
- pid == firstProgramPID ? "first" : "second");
- (void) kill(pid, SIGINT); /* stop it thinking */
- }
- break;
- }
- #endif /*ATTENTION*/
- }
-
- void CheckFlags()
- {
- if (whiteTimeRemaining <= 0) {
- if (!whiteFlag) {
- whiteFlag = True;
- if (appData.icsActive) {
- if (appData.autoCallFlag &&
- ics_mode == IcsPlayingBlack && !blackFlag)
- SendToICS("flag\n");
- } else {
- if (blackFlag)
- DisplayTitle("Both flags have fallen");
- else
- DisplayTitle("White's flag has fallen");
- }
- }
- }
- if (blackTimeRemaining <= 0) {
- if (!blackFlag) {
- blackFlag = True;
- if (appData.icsActive) {
- if (appData.autoCallFlag &&
- ics_mode == IcsPlayingWhite && !whiteFlag)
- SendToICS("flag\n");
- } else {
- if (whiteFlag)
- DisplayTitle("Both flags have fallen");
- else
- DisplayTitle("Black's flag has fallen");
- }
- }
- }
- }
-
- void CheckTimeControl()
- {
- if (!appData.clockMode) return;
- if (appData.icsActive) return;
- if (forwardMostMove == 0) return;
- /*
- * add time to clocks when time control is achieved
- */
- if ((forwardMostMove % (appData.movesPerSession * 2)) == 0) {
- whiteTimeRemaining += timeControl;
- blackTimeRemaining += timeControl;
- }
- }
-
- void DisplayLabels()
- {
- DisplayTimerLabel(whiteTimerWidget, "White", whiteTimeRemaining);
- DisplayTimerLabel(blackTimerWidget, "Black", blackTimeRemaining);
- }
-
- #ifdef HAS_GETTIMEOFDAY
- static struct timeval tickStartTV;
- static int tickLength;
-
- int PartialTickLength()
- {
- struct timeval tv;
- struct timezone tz;
- int ptl;
-
- gettimeofday(&tv, &tz);
- ptl = ( (tv.tv_sec - tickStartTV.tv_sec)*1000000 +
- (tv.tv_usec - tickStartTV.tv_usec) + 500 ) / 1000;
- if (ptl > tickLength) ptl = tickLength;
- return ptl;
- }
- #else /*!HAS_GETTIMEOFDAY*/
- #define tickLength 1000
- #endif /*HAS_GETTIMEOFDAY*/
-
- /*
- * DisplayClocks manages the game clocks.
- *
- * In tournament play, black starts the clock and then white makes a move.
- * We give the human user a slight advantage if he is playing white---the
- * clocks don't run until he makes his first move, so it takes zero time.
- * Also, DisplayClocks doesn't account for network lag so it could get
- * out of sync with GNU Chess's clock -- but then, referees are always right.
- */
- void DisplayClocks(clock_mode)
- int clock_mode;
- {
- #ifdef HAS_GETTIMEOFDAY
- struct timezone tz;
- #endif /*HAS_GETTIMEOFDAY*/
- long timeRemaining;
-
- switch (clock_mode) {
- case ResetTimers:
- /* Stop clocks and reset to a fresh time control */
- if (timerXID != 0) {
- XtRemoveTimeOut(timerXID);
- timerXID = 0;
- }
- whiteTimeRemaining = timeControl;
- blackTimeRemaining = timeControl;
- if (whiteFlag || blackFlag) {
- DisplayTitle("");
- whiteFlag = blackFlag = False;
- }
- DisplayLabels();
- break;
-
- case DecrementTimers:
- /* Decrement running clock to next 1-second boundary */
- timerXID = 0;
- if (!appData.clockMode) return;
-
- if (WhiteOnMove(forwardMostMove)) {
- timeRemaining = whiteTimeRemaining -= tickLength;
- DisplayTimerLabel(whiteTimerWidget, "White", whiteTimeRemaining);
- } else {
- timeRemaining = blackTimeRemaining -= tickLength;
- DisplayTimerLabel(blackTimerWidget, "Black", blackTimeRemaining);
- }
-
- CheckFlags();
-
- #ifdef HAS_GETTIMEOFDAY
- tickLength = (timeRemaining <= 1000 && timeRemaining > 0) ? 100 : 1000;
- gettimeofday(&tickStartTV, &tz);
- #endif /*HAS_GETTIMEOFDAY*/
- timerXID =
- XtAppAddTimeOut(appContext, tickLength,
- (XtTimerCallbackProc) DisplayClocks,
- (XtPointer) DecrementTimers);
- break;
-
- case SwitchTimers:
- /* A player has just moved, so stop the previously running
- clock and start the other one. */
- if (timerXID != 0) {
- XtRemoveTimeOut(timerXID);
- timerXID = 0;
- #ifdef HAS_GETTIMEOFDAY
- if (appData.clockMode) {
- if (WhiteOnMove(forwardMostMove))
- blackTimeRemaining -= PartialTickLength();
- else
- whiteTimeRemaining -= PartialTickLength();
- CheckFlags();
- }
- #endif /*HAS_GETTIMEOFDAY*/
- }
- CheckTimeControl();
- DisplayLabels();
- if (!appData.clockMode) return;
- if (gameMode == PauseGame &&
- (pausePreviousMode == MachinePlaysBlack ||
- pausePreviousMode == MachinePlaysWhite)) return;
-
- timeRemaining = WhiteOnMove(forwardMostMove) ?
- whiteTimeRemaining : blackTimeRemaining;
-
- #ifdef HAS_GETTIMEOFDAY
- tickLength = (timeRemaining <= 1000 && timeRemaining > 0) ?
- ((timeRemaining-1) % 100) + 1 : ((timeRemaining-1) % 1000) + 1;
- if (tickLength <= 0) tickLength += 1000;
- gettimeofday(&tickStartTV, &tz);
- #endif /*HAS_GETTIMEOFDAY*/
- timerXID =
- XtAppAddTimeOut(appContext, tickLength,
- (XtTimerCallbackProc) DisplayClocks,
- (XtPointer) DecrementTimers);
- break;
-
- case ReDisplayTimers:
- /* Display current clock values */
- DisplayLabels();
- break;
-
- case StopTimers:
- /* Stop both clocks */
- if (timerXID == 0) return;
- XtRemoveTimeOut(timerXID);
- timerXID = 0;
- if (!appData.clockMode) return;
- #ifdef HAS_GETTIMEOFDAY
- if (WhiteOnMove(forwardMostMove))
- whiteTimeRemaining -= PartialTickLength();
- else
- blackTimeRemaining -= PartialTickLength();
- CheckFlags();
- DisplayLabels();
- #endif /*HAS_GETTIMEOFDAY*/
- break;
-
- case StartTimers:
- /* Start clock of player on move, if not already running. */
- DisplayLabels();
- if (!appData.clockMode) return;
- if (timerXID != 0) return;
-
- timeRemaining = WhiteOnMove(forwardMostMove) ?
- whiteTimeRemaining : blackTimeRemaining;
-
- #ifdef HAS_GETTIMEOFDAY
- tickLength = (timeRemaining <= 1000 && timeRemaining > 0) ?
- ((timeRemaining-1) % 100) + 1 : ((timeRemaining-1) % 1000) + 1;
- if (tickLength <= 0) tickLength += 1000;
- gettimeofday(&tickStartTV, &tz);
- #endif /*HAS_GETTIMEOFDAY*/
- timerXID =
- XtAppAddTimeOut(appContext, tickLength,
- (XtTimerCallbackProc) DisplayClocks,
- (XtPointer)DecrementTimers);
- break;
- }
- }
-
- void DisplayTimerLabel(w, color, timer)
- Widget w;
- char *color;
- long timer;
- {
- char buf[MSG_SIZ];
- Arg args[3];
-
- if (appData.clockMode) {
- sprintf(buf, "%s: %s", color, TimeString(timer));
- XtSetArg(args[0], XtNlabel, buf);
- } else {
- XtSetArg(args[0], XtNlabel, color);
- }
-
- if (((color[0] == 'B') && WhiteOnMove(currentMove))
- || ((color[0] == 'W') && !WhiteOnMove(currentMove))) {
- XtSetArg(args[1], XtNbackground, timerForegroundPixel);
- XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
- } else {
- XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
- XtSetArg(args[2], XtNforeground, timerForegroundPixel);
- }
-
- XtSetValues(w, args, 3);
- }
-
- char *TimeString(tm)
- long tm;
- {
- int second, minute, hour, day;
- char *sign = "";
- static char buf[32];
-
- if (tm > 0 && tm <= 900) {
- /* convert milliseconds to tenths, rounding up */
- sprintf(buf, " 0.%1d ", (tm+99)/100);
- return buf;
- }
-
- /* convert milliseconds to seconds, rounding up */
- tm = (tm + 999) / 1000;
-
- if (tm < 0) {
- sign = "-";
- tm = -tm;
- }
-
- if (tm >= (60 * 60 * 24)) {
- day = (int) (tm / (60 * 60 * 24));
- tm -= day * 60 * 60 * 24;
- } else {
- day = 0;
- }
-
- if (tm >= (60 * 60)) {
- hour = (int) (tm / (60 * 60));
- tm -= hour * 60 * 60;
- } else {
- hour = 0;
- }
-
- if (tm >= 60) {
- minute = (int) (tm / 60);
- tm -= minute * 60;
- } else {
- minute = 0;
- }
-
- second = tm % 60;
-
- if (day > 0)
- sprintf(buf, " %s%d:%02d:%02d:%02d ", sign, day, hour, minute, second);
- else if (hour > 0)
- sprintf(buf, " %s%d:%02d:%02d ", sign, hour, minute, second);
- else
- sprintf(buf, " %s%2d:%02d ", sign, minute, second);
-
- return buf;
- }
-
- void Usage()
- {
- fprintf(stderr, "Usage: %s\n", programName);
- fprintf(stderr, "\tstandard Xt options\n");
- fprintf(stderr, "\t-iconic\n");
- fprintf(stderr, "\t-tc or -timeControl minutes[:seconds]\n");
- fprintf(stderr, "\t-mps or -movesPerSession moves\n");
- fprintf(stderr, "\t-st or -searchTime minutes[:seconds]\n");
- fprintf(stderr, "\t-sd or -searchDepth number\n");
- fprintf(stderr, "\t-clock or -clockMode (True | False)\n");
- fprintf(stderr, "\t-autoflag or -autoCallFlag (True | False)\n");
- fprintf(stderr, "\t-td or -timeDelay seconds\n");
- fprintf(stderr, "\t-ics or -internetChessServerMode (True | False)\n");
- fprintf(stderr, "\t-icshost or -internetChessServerHost host_name\n");
- fprintf(stderr, "\t-icsport or -internetChessServerPort port_number\n");
- fprintf(stderr, "\t-ncp or -noChessProgram (True | False)\n");
- fprintf(stderr, "\t-fcp or -firstChessProgram program_name\n");
- fprintf(stderr, "\t-scp or -secondChessProgram program_name\n");
- fprintf(stderr, "\t-fh or -firstHost host_name\n");
- fprintf(stderr, "\t-sh or -secondHost host_name\n");
- fprintf(stderr, "\t-rsh or -remoteShell shell_name\n");
- fprintf(stderr,
- "\t-mm or -matchMode (False | Init | Position | Opening)\n");
- fprintf(stderr, "\t-lgf or -loadGameFile file_name\n");
- fprintf(stderr, "\t-sgf or -saveGameFile file_name\n");
- fprintf(stderr, "\t-autosave or -autoSaveGames (True | False)\n");
- fprintf(stderr, "\t-lpf or -loadPositionFile file_name\n");
- fprintf(stderr, "\t-spf or -savePositionFile file_name\n");
- fprintf(stderr, "\t-bell or -ringBellAfterMoves (True | False)\n");
- fprintf(stderr, "\t-size or -boardSize (Large | Medium | Small)\n");
- fprintf(stderr, "\t-coords or -showCoords (True | False)\n");
- fprintf(stderr, "\t-mono or -monoMode (True | False)\n");
- fprintf(stderr, "\t-debug or -debugMode (True | False)\n");
- exit(2);
- }
-
- /*
- * This is necessary because some C libraries aren't ANSI C compliant yet.
- */
- char *StrStr(string, match)
- char *string, *match;
- {
- int i, length;
-
- length = strlen(match);
-
- for (i = strlen(string) - length; i >= 0; i--, string++)
- if (!strncmp(match, string, (size_t) length))
- return string;
-
- return NULL;
- }
-
- int StrCaseCmp(s1, s2)
- char *s1, *s2;
- {
- char c1, c2;
-
- for (;;) {
- c1 = ToLower(*s1++);
- c2 = ToLower(*s2++);
- if (c1 > c2) return 1;
- if (c1 < c2) return -1;
- if (c1 == NULLCHAR) return 0;
- }
- }
-
-
- int ToLower(c)
- int c;
- {
- return isupper(c) ? tolower(c) : c;
- }
-
-
- int ToUpper(c)
- int c;
- {
- return islower(c) ? toupper(c) : c;
- }
-
-
- #if defined(SYSTEM_FIVE) || defined(SYSV)
- #ifdef IRIX /*??*/
- char *PseudoTTY(ptyv)
- int *ptyv;
- {
- char *line;
-
- line = (char *)_getpty(ptyv, O_RDWR, 0600, 0);
- if (0 == line)
- return NULL;
- return line;
- }
- #else /*!IRIX*/
- char *PseudoTTY(ptyv)
- int *ptyv;
- {
- #ifdef SVR4
- char *ptsname(), *ptss;
-
- *ptyv = open("/dev/ptmx", O_RDWR);
- if (*ptyv > 0 ) {
- if (grantpt(*ptyv) == -1)
- return NULL;
- if (unlockpt(*ptyv) == -1)
- return NULL;
- if (!(ptss = ptsname(*ptyv)))
- return NULL;
- strncpy(ptyname, ptss, sizeof(ptyname));
- ptyname[sizeof(ptyname) -1] = 0;
- return ptyname;
- }
-
- #else /* !SVR4 */
- struct stat stb;
- int c, i;
-
- for (c = 'p'; c <= 'z'; c++)
- #if defined(HPUX) || defined(hpux)
- for (i = 0; i < 15 /*??*/; i++) {
- sprintf(ptyname, "/dev/ptym/pty%c%x", c, i);
- #else /* !HPUX */
- for (i = 0; i < 16; i++) {
- #ifdef RTU
- sprintf(ptyname, "/dev/pty%x", i);
- #else /* !RTU */
- sprintf(ptyname, "/dev/pty%c%x", c, i);
- #endif /* RTU */
- #endif /* HPUX */
-
- #ifdef IRIS
- *ptyv = open("/dev/ptc", O_RDWR, 0);
- if (*ptyv < 0)
- return NULL;
- if (fstat(*ptyv, &stb) < 0)
- return NULL;
- #else /* !IRIS */
- if (stat(ptyname, &stb) < 0)
- return NULL;
- *ptyv = open(ptyname, O_RDWR, 0);
- #endif /* IRIS */
-
- if (*ptyv >= 0) {
- #if defined(HPUX) || defined(hpux)
- sprintf(ptyname, "/dev/pty/tty%c%x", c, i);
- #else /* !HPUX */
- #ifdef RTU
- sprintf(ptyname, "/dev/ttyp%x", i);
- #else /* !RTU */
- #ifdef IRIS
- sprintf(ptyname, "/dev/ttyq%d",
- minor(stb.st_rdev));
- #else /* !IRIS, !RTU, !HPUX */
- sprintf(ptyname, "/dev/tty%c%x", c, i);
- #endif /* IRIS */
- #endif /* RTU */
- #endif /* HPUX */
-
- #ifndef UNIPLUS
- if (access(ptyname, 6) != 0) {
- close(*ptyv);
- #ifdef IRIS
- return NULL;
- #else /* !IRIS */
- continue;
- #endif /* IRIS */
- }
- #endif /* !UNIPLUS */
-
- #ifdef IBMRTAIX
- signal(SIGHUP, SIG_IGN);
- #endif /* IBMRTAIX */
- return ptyname;
- }
- }
-
- #endif
- return NULL;
- }
- #endif /*IRIX*/
-
- #else /* !SYSTEM_FIVE */
-
- void CatchPipeSignal(dummy)
- int dummy;
- {
- char message[MSG_SIZ];
- char *number, *name;
-
- if (lastMsgFP == toFirstProgFP) {
- number = "first";
- name = appData.firstChessProgram;
- } else if (lastMsgFP == toSecondProgFP) {
- number = "second";
- name = appData.secondChessProgram;
- } else {
- return;
- }
-
- sprintf(message,
- "%s chess program (%s) exited unexpectedly (pipe signal)",
- number, name);
- fprintf(stderr, "%s: %s\n", programName, message);
- ShutdownChessPrograms(message);
- return;
- }
- #endif
-