From: Arun Persaud Date: Wed, 22 Jul 2009 03:23:23 +0000 (-0700) Subject: converted files from dos to unix format X-Git-Tag: v4.4.0.beta2~34 X-Git-Url: http://winboard.nl/cgi-bin?p=xboard.git;a=commitdiff_plain;h=21b2748b7e01ca15af0c2dce7102df401dc2666f converted files from dos to unix format run dos2unix over a bunch of files --- diff --git a/backend.h b/backend.h index a4a7acf..81d0566 100644 --- a/backend.h +++ b/backend.h @@ -1,370 +1,370 @@ -/* - * backend.h -- Interface exported by XBoard back end - * - * Copyright 1991 by Digital Equipment Corporation, Maynard, - * Massachusetts. - * - * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009 Free Software Foundation, Inc. - * - * Enhancements Copyright 2005 Alessandro Scotti - * - * 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. - * ------------------------------------------------------------------------ - * - * The following terms apply to the enhanced version of XBoard - * distributed by the Free Software Foundation: - * ------------------------------------------------------------------------ - * - * GNU XBoard is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * GNU XBoard is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. * - * - *------------------------------------------------------------------------ - ** See the file ChangeLog for a revision history. */ - -#ifndef _BACKEND -#define _BACKEND - -/* unsigned int 64 for engine nodes work and display */ -#ifdef WIN32 - /* I don't know the name for this type of other compiler - * If it not work, just modify here - * This is for MS Visual Studio - */ - #ifdef _MSC_VER - #define u64 unsigned __int64 - #define s64 signed __int64 - #define u64Display "%I64u" - #define s64Display "%I64d" - #define u64Const(c) (c ## UI64) - #define s64Const(c) (c ## I64) - #else - /* place holder - * or dummy types for other compiler - */ - #define u64 unsigned long long - #define s64 signed long long - #define u64Display "%llu" - #define s64Display "%lld" - #define u64Const(c) (c ## ULL) - #define s64Const(c) (c ## LL) - #endif -#else - /* GNU gcc */ - #define u64 unsigned long long - #define s64 signed long long - #define u64Display "%llu" - #define s64Display "%lld" - #define u64Const(c) (c ## ull) - #define s64Const(c) (c ## ll) -#endif - -#include "lists.h" -#include "frontend.h" - -extern int gotPremove; -extern GameMode gameMode; -extern int pausing, cmailMsgLoaded, flipView; -extern char white_holding[], black_holding[]; -extern int currentMove, backwardMostMove, forwardMostMove; -extern int blackPlaysFirst; -extern FILE *debugFP; -extern char* programVersion; -extern ProcRef firstProgramPR, secondProgramPR; -extern Board boards[]; - -char *CmailMsg P((void)); -/* Tord: Added the useFEN960 parameter in PositionToFEN() below */ -char *PositionToFEN P((int move, char* useFEN960)); -void AlphaRank P((char *s, int n)); /* [HGM] Shogi move preprocessor */ -void EditPositionPasteFEN P((char *fen)); -void TimeDelay P((long ms)); -void SendMultiLineToICS P(( char *text )); -void AnalysisPeriodicEvent P((int force)); -void SetWhiteToPlayEvent P((void)); -void SetBlackToPlayEvent P((void)); -void InitBackEnd1 P((void)); -void InitBackEnd2 P((void)); -int IsPromotion P((int fromX, int fromY, int toX, int toY)); -int InPalace P((int row, int column)); -int PieceForSquare P((int x, int y)); -int OKToStartUserMove P((int x, int y)); -void Reset P((int redraw, int init)); -void ResetGameEvent P((void)); -int LoadGame P((FILE *f, int n, char *title, int useList)); -int LoadGameFromFile P((char *filename, int n, char *title, int useList)); -int CmailLoadGame P((FILE *f, int n, char *title, int useList)); -int ReloadGame P((int offset)); -int SaveGame P((FILE *f, int dummy, char *dummy2)); -int SaveGameToFile P((char *filename, int append)); -int LoadPosition P((FILE *f, int n, char *title)); -int ReloadPosition P((int offset)); -int SavePosition P((FILE *f, int dummy, char *dummy2)); -void EditPositionEvent P((void)); -void FlipViewEvent P((void)); -void MachineWhiteEvent P((void)); -void MachineBlackEvent P((void)); -void TwoMachinesEvent P((void)); -void EditGameEvent P((void)); -void TrainingEvent P((void)); -void IcsClientEvent P((void)); -void ForwardEvent P((void)); -void BackwardEvent P((void)); -void ToEndEvent P((void)); -void ToStartEvent P((void)); -void ToNrEvent P((int to)); -void RevertEvent P((void)); -void RetractMoveEvent P((void)); -void MoveNowEvent P((void)); -void TruncateGameEvent P((void)); -void PauseEvent P((void)); -void CallFlagEvent P((void)); -void AcceptEvent P((void)); -void DeclineEvent P((void)); -void RematchEvent P((void)); -void DrawEvent P((void)); -void AbortEvent P((void)); -void AdjournEvent P((void)); -void ResignEvent P((void)); -void UserAdjudicationEvent P((int result)); -void StopObservingEvent P((void)); -void StopExaminingEvent P((void)); -void PonderNextMoveEvent P((int newState)); -void NewSettingeEvent P((int option, char *command, int value)); -void ShowThinkingEvent P(()); -void PeriodicUpdatesEvent P((int newState)); -void HintEvent P((void)); -void BookEvent P((void)); -void AboutGameEvent P((void)); -void ExitEvent P((int status)); -char *DefaultFileName P((char *)); -ChessMove UserMoveTest P((int fromX, int fromY, int toX, int toY, int promoChar)); -void UserMoveEvent P((int fromX, int fromY, int toX, int toY, int promoChar)); -void DecrementClocks P((void)); -char *TimeString P((long millisec)); -void AutoPlayGameLoop P((void)); -void AdjustClock P((Boolean which, int dir)); -void DisplayBothClocks P((void)); -void EditPositionMenuEvent P((ChessSquare selection, int x, int y)); -void DropMenuEvent P((ChessSquare selection, int x, int y)); -int ParseTimeControl P((char *tc, int ti, int mps)); -void ProcessICSInitScript P((FILE * f)); -void EditCommentEvent P((void)); -void ReplaceComment P((int index, char *text)); -int ReplaceTags P((char *tags, GameInfo *gi));/* returns nonzero on error */ -void AppendComment P((int index, char *text)); -void ReloadCmailMsgEvent P((int unregister)); -void MailMoveEvent P((void)); -void EditTagsEvent P((void)); -void GetMoveListEvent P((void)); -void ExitAnalyzeMode P((void)); -void AnalyzeModeEvent P((void)); -void AnalyzeFileEvent P((void)); -void DoEcho P((void)); -void DontEcho P((void)); -void TidyProgramName P((char *prog, char *host, char *buf)); -void AskQuestionEvent P((char *title, char *question, - char *replyPrefix, char *which)); -Boolean ParseOneMove P((char *move, int moveNum, - ChessMove *moveType, int *fromX, int *fromY, - int *toX, int *toY, char *promoChar)); -char *VariantName P((VariantClass v)); -VariantClass StringToVariant P((char *e)); -double u64ToDouble P((u64 value)); - -char *StrStr P((char *string, char *match)); -char *StrCaseStr P((char *string, char *match)); -char *StrSave P((char *s)); -char *StrSavePtr P((char *s, char **savePtr)); - -#ifndef _amigados -int StrCaseCmp P((char *s1, char *s2)); -int ToLower P((int c)); -int ToUpper P((int c)); -#else -#define StrCaseCmp Stricmp /* Use utility.library functions */ -#include -#endif - -extern GameInfo gameInfo; - -/* ICS vars used with backend.c and zippy.c */ -#define ICS_GENERIC 0 -#define ICS_ICC 1 -#define ICS_FICS 2 -#define ICS_CHESSNET 3 /* not really supported */ -int ics_type; - - - -/* pgntags.c prototypes - */ -char *PGNTags P((GameInfo *)); -void PrintPGNTags P((FILE *f, GameInfo *)); -int ParsePGNTag P((char *, GameInfo *)); -char *PGNResult P((ChessMove result)); - - -/* gamelist.c prototypes - */ -/* A game node in the double linked list of games. - */ -typedef struct _ListGame { - ListNode node; - int number; - unsigned long offset; /* Byte offset of game within file. */ - GameInfo gameInfo; /* Note that some entries may be NULL. */ -} ListGame; - -extern List gameList; -void ClearGameInfo P((GameInfo *)); -int GameListBuild P((FILE *)); -void GameListInitGameInfo P((GameInfo *)); -char *GameListLine P((int, GameInfo *)); -char * GameListLineFull P(( int, GameInfo *)); - -extern char* StripHighlight P((char *)); /* returns static data */ -extern char* StripHighlightAndTitle P((char *)); /* returns static data */ - -typedef enum { CheckBox, ComboBox, TextBox, Button, Spin, SaveButton } Control; - -typedef struct _OPT { // [HGM] options: descriptor of UCI-style option - int value; // current setting, starts as default - int min; - int max; - void *handle; // for use by front end - char *textValue; // points to beginning of text value in name field - char **choice; // points to array of combo choices in cps->combo - Control type; - char name[MSG_SIZ]; // holds both option name and text value -} Option; - -typedef struct _CPS { - char *which; - int maybeThinking; - ProcRef pr; - InputSourceRef isr; - char *twoMachinesColor; /* "white\n" or "black\n" */ - char *program; - char *host; - char *dir; - struct _CPS *other; - char *initString; - char *computerString; - int sendTime; /* 0=don't, 1=do, 2=test */ - int sendDrawOffers; - int useSigint; - int useSigterm; - int offeredDraw; /* countdown */ - int reuse; - int useSetboard; /* 0=use "edit"; 1=use "setboard" */ - int useSAN; /* 0=use coordinate notation; 1=use SAN */ - int usePing; /* 0=not OK to use ping; 1=OK */ - int lastPing; - int lastPong; - int usePlayother;/* 0=not OK to use playother; 1=OK */ - int useColors; /* 0=avoid obsolete white/black commands; 1=use them */ - int useUsermove; /* 0=just send move; 1=send "usermove move" */ - int sendICS; /* 0=don't use "ics" command; 1=do */ - int sendName; /* 0=don't use "name" command; 1=do */ - int sdKludge; /* 0=use "sd DEPTH" command; 1=use "depth\nDEPTH" */ - int stKludge; /* 0=use "st TIME" command; 1=use "level 1 TIME" */ - char tidy[MSG_SIZ]; - int matchWins; - char variants[MSG_SIZ]; - int analysisSupport; - int analyzing; - int protocolVersion; - int initDone; - - /* Added by Tord: */ - int useFEN960; /* 0=use "KQkq" style FENs, 1=use "HAha" style FENs */ - int useOOCastle; /* 0="O-O" notation for castling, 1="king capture rook" notation */ - /* End of additions by Tord */ - - int scoreIsAbsolute; /* [AS] 0=don't know (standard), 1=score is always from white side */ - int isUCI; /* [AS] 0=no (Winboard), 1=UCI (requires Polyglot) */ - int hasOwnBookUCI; /* [AS] 0=use GUI or Polyglot book, 1=has own book */ - - /* [HGM] time odds */ - int timeOdds; /* factor through which we divide time for this engine */ - int debug; /* [HGM] ignore engine debug lines starting with '#' */ - int maxNrOfSessions; /* [HGM] secondary TC: max args in 'level' command */ - int accumulateTC; /* [HGM] secondary TC: how to handle extra sessions */ - int nps; /* [HGM] nps: factor for node count to replace time */ - int supportsNPS; - int alphaRank; /* [HGM] shogi: engine uses shogi-type coordinates */ - int maxCores; /* [HGM] SMP: engine understands cores command */ - int memSize; /* [HGM] memsize: engine understands memory command */ - char egtFormats[MSG_SIZ]; /* [HGM] EGT: supported tablebase formats */ - int bookSuspend; /* [HGM] book: go was deferred because of book hit */ - int nrOptions; /* [HGM] options: remembered option="..." features */ -#define MAX_OPTIONS 100 - Option option[MAX_OPTIONS]; - int comboCnt; - char *comboList[20*MAX_OPTIONS]; - char *optionSettings; - void *programLogo; /* [HGM] logo: bitmap of the logo */ - char *fenOverride; /* [HGM} FRC: force FEN casling & ep fields by hand */ -} ChessProgramState; - -extern ChessProgramState first, second; - -/* [AS] Search stats from chessprogram, for the played move */ -typedef struct { - int score; /* Centipawns */ - int depth; /* Plies */ - int time; /* Milliseconds */ -} ChessProgramStats_Move; - -/* Search stats from chessprogram */ -typedef struct { - char movelist[2*MSG_SIZ]; /* Last PV we were sent */ - int depth; /* Current search depth */ - int nr_moves; /* Total nr of root moves */ - int moves_left; /* Moves remaining to be searched */ - char move_name[MOVE_LEN]; /* Current move being searched, if provided */ - u64 nodes; /* # of nodes searched */ - int time; /* Search time (centiseconds) */ - int score; /* Score (centipawns) */ - int got_only_move; /* If last msg was "(only move)" */ - int got_fail; /* 0 - nothing, 1 - got "--", 2 - got "++" */ - int ok_to_send; /* handshaking between send & recv */ - int line_is_book; /* 1 if movelist is book moves */ - int seen_stat; /* 1 if we've seen the stat01: line */ -} ChessProgramStats; - -extern ChessProgramStats_Move pvInfoList[MAX_MOVES]; -extern int shuffleOpenings; -extern ChessProgramStats programStats; - -#endif /* _BACKEND */ +/* + * backend.h -- Interface exported by XBoard back end + * + * Copyright 1991 by Digital Equipment Corporation, Maynard, + * Massachusetts. + * + * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, + * 2007, 2008, 2009 Free Software Foundation, Inc. + * + * Enhancements Copyright 2005 Alessandro Scotti + * + * 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. + * ------------------------------------------------------------------------ + * + * The following terms apply to the enhanced version of XBoard + * distributed by the Free Software Foundation: + * ------------------------------------------------------------------------ + * + * GNU XBoard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * GNU XBoard is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. * + * + *------------------------------------------------------------------------ + ** See the file ChangeLog for a revision history. */ + +#ifndef _BACKEND +#define _BACKEND + +/* unsigned int 64 for engine nodes work and display */ +#ifdef WIN32 + /* I don't know the name for this type of other compiler + * If it not work, just modify here + * This is for MS Visual Studio + */ + #ifdef _MSC_VER + #define u64 unsigned __int64 + #define s64 signed __int64 + #define u64Display "%I64u" + #define s64Display "%I64d" + #define u64Const(c) (c ## UI64) + #define s64Const(c) (c ## I64) + #else + /* place holder + * or dummy types for other compiler + */ + #define u64 unsigned long long + #define s64 signed long long + #define u64Display "%llu" + #define s64Display "%lld" + #define u64Const(c) (c ## ULL) + #define s64Const(c) (c ## LL) + #endif +#else + /* GNU gcc */ + #define u64 unsigned long long + #define s64 signed long long + #define u64Display "%llu" + #define s64Display "%lld" + #define u64Const(c) (c ## ull) + #define s64Const(c) (c ## ll) +#endif + +#include "lists.h" +#include "frontend.h" + +extern int gotPremove; +extern GameMode gameMode; +extern int pausing, cmailMsgLoaded, flipView; +extern char white_holding[], black_holding[]; +extern int currentMove, backwardMostMove, forwardMostMove; +extern int blackPlaysFirst; +extern FILE *debugFP; +extern char* programVersion; +extern ProcRef firstProgramPR, secondProgramPR; +extern Board boards[]; + +char *CmailMsg P((void)); +/* Tord: Added the useFEN960 parameter in PositionToFEN() below */ +char *PositionToFEN P((int move, char* useFEN960)); +void AlphaRank P((char *s, int n)); /* [HGM] Shogi move preprocessor */ +void EditPositionPasteFEN P((char *fen)); +void TimeDelay P((long ms)); +void SendMultiLineToICS P(( char *text )); +void AnalysisPeriodicEvent P((int force)); +void SetWhiteToPlayEvent P((void)); +void SetBlackToPlayEvent P((void)); +void InitBackEnd1 P((void)); +void InitBackEnd2 P((void)); +int IsPromotion P((int fromX, int fromY, int toX, int toY)); +int InPalace P((int row, int column)); +int PieceForSquare P((int x, int y)); +int OKToStartUserMove P((int x, int y)); +void Reset P((int redraw, int init)); +void ResetGameEvent P((void)); +int LoadGame P((FILE *f, int n, char *title, int useList)); +int LoadGameFromFile P((char *filename, int n, char *title, int useList)); +int CmailLoadGame P((FILE *f, int n, char *title, int useList)); +int ReloadGame P((int offset)); +int SaveGame P((FILE *f, int dummy, char *dummy2)); +int SaveGameToFile P((char *filename, int append)); +int LoadPosition P((FILE *f, int n, char *title)); +int ReloadPosition P((int offset)); +int SavePosition P((FILE *f, int dummy, char *dummy2)); +void EditPositionEvent P((void)); +void FlipViewEvent P((void)); +void MachineWhiteEvent P((void)); +void MachineBlackEvent P((void)); +void TwoMachinesEvent P((void)); +void EditGameEvent P((void)); +void TrainingEvent P((void)); +void IcsClientEvent P((void)); +void ForwardEvent P((void)); +void BackwardEvent P((void)); +void ToEndEvent P((void)); +void ToStartEvent P((void)); +void ToNrEvent P((int to)); +void RevertEvent P((void)); +void RetractMoveEvent P((void)); +void MoveNowEvent P((void)); +void TruncateGameEvent P((void)); +void PauseEvent P((void)); +void CallFlagEvent P((void)); +void AcceptEvent P((void)); +void DeclineEvent P((void)); +void RematchEvent P((void)); +void DrawEvent P((void)); +void AbortEvent P((void)); +void AdjournEvent P((void)); +void ResignEvent P((void)); +void UserAdjudicationEvent P((int result)); +void StopObservingEvent P((void)); +void StopExaminingEvent P((void)); +void PonderNextMoveEvent P((int newState)); +void NewSettingeEvent P((int option, char *command, int value)); +void ShowThinkingEvent P(()); +void PeriodicUpdatesEvent P((int newState)); +void HintEvent P((void)); +void BookEvent P((void)); +void AboutGameEvent P((void)); +void ExitEvent P((int status)); +char *DefaultFileName P((char *)); +ChessMove UserMoveTest P((int fromX, int fromY, int toX, int toY, int promoChar)); +void UserMoveEvent P((int fromX, int fromY, int toX, int toY, int promoChar)); +void DecrementClocks P((void)); +char *TimeString P((long millisec)); +void AutoPlayGameLoop P((void)); +void AdjustClock P((Boolean which, int dir)); +void DisplayBothClocks P((void)); +void EditPositionMenuEvent P((ChessSquare selection, int x, int y)); +void DropMenuEvent P((ChessSquare selection, int x, int y)); +int ParseTimeControl P((char *tc, int ti, int mps)); +void ProcessICSInitScript P((FILE * f)); +void EditCommentEvent P((void)); +void ReplaceComment P((int index, char *text)); +int ReplaceTags P((char *tags, GameInfo *gi));/* returns nonzero on error */ +void AppendComment P((int index, char *text)); +void ReloadCmailMsgEvent P((int unregister)); +void MailMoveEvent P((void)); +void EditTagsEvent P((void)); +void GetMoveListEvent P((void)); +void ExitAnalyzeMode P((void)); +void AnalyzeModeEvent P((void)); +void AnalyzeFileEvent P((void)); +void DoEcho P((void)); +void DontEcho P((void)); +void TidyProgramName P((char *prog, char *host, char *buf)); +void AskQuestionEvent P((char *title, char *question, + char *replyPrefix, char *which)); +Boolean ParseOneMove P((char *move, int moveNum, + ChessMove *moveType, int *fromX, int *fromY, + int *toX, int *toY, char *promoChar)); +char *VariantName P((VariantClass v)); +VariantClass StringToVariant P((char *e)); +double u64ToDouble P((u64 value)); + +char *StrStr P((char *string, char *match)); +char *StrCaseStr P((char *string, char *match)); +char *StrSave P((char *s)); +char *StrSavePtr P((char *s, char **savePtr)); + +#ifndef _amigados +int StrCaseCmp P((char *s1, char *s2)); +int ToLower P((int c)); +int ToUpper P((int c)); +#else +#define StrCaseCmp Stricmp /* Use utility.library functions */ +#include +#endif + +extern GameInfo gameInfo; + +/* ICS vars used with backend.c and zippy.c */ +#define ICS_GENERIC 0 +#define ICS_ICC 1 +#define ICS_FICS 2 +#define ICS_CHESSNET 3 /* not really supported */ +int ics_type; + + + +/* pgntags.c prototypes + */ +char *PGNTags P((GameInfo *)); +void PrintPGNTags P((FILE *f, GameInfo *)); +int ParsePGNTag P((char *, GameInfo *)); +char *PGNResult P((ChessMove result)); + + +/* gamelist.c prototypes + */ +/* A game node in the double linked list of games. + */ +typedef struct _ListGame { + ListNode node; + int number; + unsigned long offset; /* Byte offset of game within file. */ + GameInfo gameInfo; /* Note that some entries may be NULL. */ +} ListGame; + +extern List gameList; +void ClearGameInfo P((GameInfo *)); +int GameListBuild P((FILE *)); +void GameListInitGameInfo P((GameInfo *)); +char *GameListLine P((int, GameInfo *)); +char * GameListLineFull P(( int, GameInfo *)); + +extern char* StripHighlight P((char *)); /* returns static data */ +extern char* StripHighlightAndTitle P((char *)); /* returns static data */ + +typedef enum { CheckBox, ComboBox, TextBox, Button, Spin, SaveButton } Control; + +typedef struct _OPT { // [HGM] options: descriptor of UCI-style option + int value; // current setting, starts as default + int min; + int max; + void *handle; // for use by front end + char *textValue; // points to beginning of text value in name field + char **choice; // points to array of combo choices in cps->combo + Control type; + char name[MSG_SIZ]; // holds both option name and text value +} Option; + +typedef struct _CPS { + char *which; + int maybeThinking; + ProcRef pr; + InputSourceRef isr; + char *twoMachinesColor; /* "white\n" or "black\n" */ + char *program; + char *host; + char *dir; + struct _CPS *other; + char *initString; + char *computerString; + int sendTime; /* 0=don't, 1=do, 2=test */ + int sendDrawOffers; + int useSigint; + int useSigterm; + int offeredDraw; /* countdown */ + int reuse; + int useSetboard; /* 0=use "edit"; 1=use "setboard" */ + int useSAN; /* 0=use coordinate notation; 1=use SAN */ + int usePing; /* 0=not OK to use ping; 1=OK */ + int lastPing; + int lastPong; + int usePlayother;/* 0=not OK to use playother; 1=OK */ + int useColors; /* 0=avoid obsolete white/black commands; 1=use them */ + int useUsermove; /* 0=just send move; 1=send "usermove move" */ + int sendICS; /* 0=don't use "ics" command; 1=do */ + int sendName; /* 0=don't use "name" command; 1=do */ + int sdKludge; /* 0=use "sd DEPTH" command; 1=use "depth\nDEPTH" */ + int stKludge; /* 0=use "st TIME" command; 1=use "level 1 TIME" */ + char tidy[MSG_SIZ]; + int matchWins; + char variants[MSG_SIZ]; + int analysisSupport; + int analyzing; + int protocolVersion; + int initDone; + + /* Added by Tord: */ + int useFEN960; /* 0=use "KQkq" style FENs, 1=use "HAha" style FENs */ + int useOOCastle; /* 0="O-O" notation for castling, 1="king capture rook" notation */ + /* End of additions by Tord */ + + int scoreIsAbsolute; /* [AS] 0=don't know (standard), 1=score is always from white side */ + int isUCI; /* [AS] 0=no (Winboard), 1=UCI (requires Polyglot) */ + int hasOwnBookUCI; /* [AS] 0=use GUI or Polyglot book, 1=has own book */ + + /* [HGM] time odds */ + int timeOdds; /* factor through which we divide time for this engine */ + int debug; /* [HGM] ignore engine debug lines starting with '#' */ + int maxNrOfSessions; /* [HGM] secondary TC: max args in 'level' command */ + int accumulateTC; /* [HGM] secondary TC: how to handle extra sessions */ + int nps; /* [HGM] nps: factor for node count to replace time */ + int supportsNPS; + int alphaRank; /* [HGM] shogi: engine uses shogi-type coordinates */ + int maxCores; /* [HGM] SMP: engine understands cores command */ + int memSize; /* [HGM] memsize: engine understands memory command */ + char egtFormats[MSG_SIZ]; /* [HGM] EGT: supported tablebase formats */ + int bookSuspend; /* [HGM] book: go was deferred because of book hit */ + int nrOptions; /* [HGM] options: remembered option="..." features */ +#define MAX_OPTIONS 100 + Option option[MAX_OPTIONS]; + int comboCnt; + char *comboList[20*MAX_OPTIONS]; + char *optionSettings; + void *programLogo; /* [HGM] logo: bitmap of the logo */ + char *fenOverride; /* [HGM} FRC: force FEN casling & ep fields by hand */ +} ChessProgramState; + +extern ChessProgramState first, second; + +/* [AS] Search stats from chessprogram, for the played move */ +typedef struct { + int score; /* Centipawns */ + int depth; /* Plies */ + int time; /* Milliseconds */ +} ChessProgramStats_Move; + +/* Search stats from chessprogram */ +typedef struct { + char movelist[2*MSG_SIZ]; /* Last PV we were sent */ + int depth; /* Current search depth */ + int nr_moves; /* Total nr of root moves */ + int moves_left; /* Moves remaining to be searched */ + char move_name[MOVE_LEN]; /* Current move being searched, if provided */ + u64 nodes; /* # of nodes searched */ + int time; /* Search time (centiseconds) */ + int score; /* Score (centipawns) */ + int got_only_move; /* If last msg was "(only move)" */ + int got_fail; /* 0 - nothing, 1 - got "--", 2 - got "++" */ + int ok_to_send; /* handshaking between send & recv */ + int line_is_book; /* 1 if movelist is book moves */ + int seen_stat; /* 1 if we've seen the stat01: line */ +} ChessProgramStats; + +extern ChessProgramStats_Move pvInfoList[MAX_MOVES]; +extern int shuffleOpenings; +extern ChessProgramStats programStats; + +#endif /* _BACKEND */ diff --git a/configure.ac b/configure.ac index 0ec602d..87f71b2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,404 +1,404 @@ -dnl| configure.in -dnl| -dnl| Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, 2007, -dnl| 2008, 2009 Free Software Foundation, Inc. -dnl| -dnl| GNU XBoard is free software: you can redistribute it and/or modify -dnl| it under the terms of the GNU General Public License as published by -dnl| the Free Software Foundation, either version 3 of the License, or (at -dnl| your option) any later version. -dnl| -dnl| GNU XBoard is distributed in the hope that it will be useful, but -dnl| WITHOUT ANY WARRANTY; without even the implied warranty of -dnl| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl| General Public License for more details. -dnl| -dnl| You should have received a copy of the GNU General Public License -dnl| along with this program. If not, see http://www.gnu.org/licenses/. -dnl| -dnl| -------------------------------------------------------------------- -dnl| -dnl| You can process this file with autoconf to produce a configure script. -dnl| However, normally the supplied configure script will work fine. -dnl| -dnl| If you do need to change the configure script, instead of editing -dnl| it directly, try to edit configure.in (in a way that will keep -dnl| it portable to sites and systems other than your own), and run autoconf -dnl| to regenerate configure. Then submit your changes to be folded into -dnl| the standard version of xboard. - -dnl| define second argument as VERSION.PATCHLEVEL. e.g. 4.4.0j -AC_INIT([xboard],[4.4.0.beta1],[bug-xboard@gnu.org]) -AM_INIT_AUTOMAKE - -AC_CONFIG_HEADERS([config.h]) - -dnl | a bunch of templates for defines used below -AH_TEMPLATE([FIRST_PTY_LETTER],[template]) -AH_TEMPLATE([HAVE_FCNTL_H],[template]) -AH_TEMPLATE([HAVE_GETHOSTNAME],[template]) -AH_TEMPLATE([HAVE_GETTIMEOFDAY],[template]) -AH_TEMPLATE([HAVE_RANDOM],[template]) -AH_TEMPLATE([HAVE_SYS_SOCKET_H],[template]) -AH_TEMPLATE([IBMRTAIX],[template]) -AH_TEMPLATE([LAST_PTY_LETTER],[template]) -AH_TEMPLATE([PTY_ITERATION],[template]) -AH_TEMPLATE([PTY_NAME_SPRINTF],[template]) -AH_TEMPLATE([PTY_OPEN],[template]) -AH_TEMPLATE([PTY_TTY_NAME_SPRINTF],[template]) -AH_TEMPLATE([REMOTE_SHELL],[template]) -AH_TEMPLATE([RTU],[template]) -AH_TEMPLATE([UNIPLUS],[template]) -AH_TEMPLATE([USE_PTYS],[template]) -AH_TEMPLATE([X_WCHAR],[template]) -AH_TEMPLATE([ATTENTION],[template]) -AH_TEMPLATE([DEFINED_SYS_ERRLIST],[template]) -AH_TEMPLATE([HAVE_LIBXPM],[template]) -AH_TEMPLATE([USE_XAW3D],[template]) -AH_TEMPLATE([X_LOCALE],[template]) - - - -if test -z "$CFLAGS" ; then -dnl| Prevent the next macro from setting CFLAGS to -g - CFLAGS=" " -fi -AC_PROG_CC -AC_PROG_CPP -AC_ISC_POSIX -AC_PROG_INSTALL - -AC_PROG_LEX -if test "$LEX" != flex; then - LEX="$SHELL $missing_dir/missing flex" - AC_SUBST([LEX_OUTPUT_ROOT], [lex.yy]) - AC_SUBST([LEXLIB], ['']) -fi - - -AC_CHECK_PROGS(RSH, remsh rsh, rsh) -AC_CHECK_PROGS(MINFO, makeinfo, makeinfo_not_found) -if test "$MINFO" == makeinfo_not_found ; then - echo Please install \"makeinfo\" - exit 1 -fi -AC_DEFINE_UNQUOTED(REMOTE_SHELL, "$RSH") -AC_CHECK_PROG(NROFF, nroff, [nroff -man], cat) -AC_SUBST(NROFFFLAGS) -AC_PATH_PROGS(AWKPATH, awk mawk gawk nawk) -AC_PATH_PROGS(PERLPATH, perl) - -AC_HEADER_STDC -AC_HEADER_TIME -AC_HEADER_SYS_WAIT -AC_HEADER_DIRENT -AC_TYPE_SIGNAL -AC_CHECK_HEADERS(stropts.h sys/time.h string.h unistd.h sys/systeminfo.h) -AC_CHECK_HEADERS(fcntl.h sys/fcntl.h, break) -AC_CHECK_HEADERS(sys/socket.h lan/socket.h, break) -AC_CHECK_HEADER(stddef.h, [], AC_DEFINE(X_WCHAR, 1)) - -AC_CHECK_FUNCS(_getpty grantpt setitimer usleep) -AC_CHECK_FUNCS(gettimeofday ftime, break) -AC_CHECK_FUNCS(random rand48, break) -AC_CHECK_FUNCS(gethostname sysinfo, break) -AC_CHECK_FUNC(setlocale, [], - AC_CHECK_LIB(i, setlocale, [], AC_DEFINE(X_LOCALE, 1))) - -AC_CHECK_LIB(seq, getpseudotty) - -AC_PATH_XTRA -if test -n "$no_x" ; then - echo $PACKAGE requires the X Window System header files and libraries! - echo They were not found on your system. See FAQ topic C.2. - echo configure failed - exit 1 -fi - -AC_CHECK_HEADER(X11/Intrinsic.h,xt="yes",xt="no") - -if test "$xt" == "no" ; then - echo Xt headers not found - exit 1 -fi - -dnl | test if user wants ot use Xaw3d headers -AC_ARG_WITH([Xaw3d], - [AS_HELP_STRING([--with-Xaw3d], - [use Xaw3d instead of Xaw])], - [with_xaw3d=yes], - [with_xaw3d=no]) - -XAW_LIBS= -AS_IF([test "x$with_xaw3d" != xno], - [AC_CHECK_LIB([Xaw3d], - [XawTextReplace], - [AC_SUBST([XAW_LIBS], - ["-lXaw3d"]) - AC_DEFINE([USE_XAW3D], [1], - [Define if you want to use Xaw3d])], - [AC_CHECK_HEADER(X11/Xaw/Dialog.h,xaw_headers="yes") - AC_MSG_FAILURE( - [--with-Xaw3d was given, but test for Xaw3d failed])], - [-lXaw])]) -if test "$with_xaw3d" == "no" ; then - XAW_LIBS="-lXaw" -fi -AC_SUBST(XAW_LIBS) - -dnl | end Xaw3d test - -if test "$xaw_headers" == "no" ; then - echo Xaw headers not found - exit 1 - -fi - - -AC_CANONICAL_HOST - -dnl| The following info is mostly gathered from GNU Emacs 19.24. Basically, -dnl| we are trying to find out whether this is a System-V derivative in -dnl| which pipes don't work with select() and if so, whether there is anything -dnl| strange about the way to open a pty. Some of the work was done above -dnl| by looking for _getpty, grantpt, and getpseudotty. A few other strange -dnl| properties of particular systems are also handled here. - -dnl| 4/6/97 I'm not sure there really are any systems where pipes -dnl| don't work with select(), and ptys cause problems on many -dnl| systems, so I'm changing the default to disable ptys in all -dnl| cases. I will change it back if I get bug reports that are fixed -dnl| by doing a "configure --enable-ptys" - -USE_PTYS=0 -case "$host" in - *-*-hpux* ) - AC_DEFINE(PTY_TTY_NAME_SPRINTF, - [sprintf (pty_name, "/dev/pty/tty%c%x", c, i);]) - AC_DEFINE(PTY_NAME_SPRINTF, - [sprintf (pty_name, "/dev/ptym/pty%c%x", c, i);]) -dnl| USE_PTYS=1 - if test "$GCC" = yes; then - CONF_CFLAGS="-fwritable-strings" - else - -dnl| Note: You might be able to build xboard even if your compiler does not -dnl| support ANSI C (-Aa). xboard itself does not require ANSI C. I don't -dnl| know whether the X header files on HP-UX require it. - - CONF_CFLAGS="-Aa -D_HPUX_SOURCE" - fi - -dnl| HP doesn't supply a full set of X header files and libraries. People -dnl| often have some things installed in one place and some in another. -dnl| AC_PATH_XTRA will find only one place, so we try to add all the -dnl| likely ones that might be missing here. It might be better to -dnl| change AC_PATH_XTRA to try to extract this information from imake, -dnl| since folks who install the missing bits often configure their -dnl| imake to find them, but I don't want to delve into autoconf and -dnl| hack on its internals. - - if test -d /opt/hppd/include/X11; then - X_CFLAGS="$X_CFLAGS -I/opt/hppd/include" - X_LIBS="$X_LIBS -L/opt/hppd/lib" - elif test -d /usr/contrib/X11R5/include; then - X_CFLAGS="$X_CFLAGS -I/usr/contrib/X11R5/include" - X_LIBS="$X_LIBS -L/usr/contrib/X11R5/lib" - elif test -d /usr/contrib/mitX11R5/include; then - X_CFLAGS="$X_CFLAGS -I/usr/contrib/mitX11R5/include" - X_LIBS="$X_LIBS -L/usr/contrib/mitX11R5/lib" - elif test -d /MIT/X11R5/include; then - X_CFLAGS="$X_CFLAGS -I/MIT/X11R5/include" - X_LIBS="$X_LIBS -L/MIT/X11R5/lib" - elif test -d /usr/local/include/X11R5; then - X_CFLAGS="$X_CFLAGS -I/usr/local/include/X11R5" - X_LIBS="$X_LIBS -L/usr/local/lib/X11R5" - fi - if test -d /usr/include/X11R5; then - X_CFLAGS="$X_CFLAGS -I/usr/include/X11R5" - X_LIBS="$X_LIBS -L/usr/lib/X11R5 -L/usr/lib/X11R4" - elif test -d /usr/include/X11R4; then - X_CFLAGS="$X_CFLAGS -I/usr/include/X11R4" - X_LIBS="$X_LIBS -L/usr/lib/X11R4" - fi - ;; - - romp-ibm-aix* ) - AC_DEFINE(IBMRTAIX, 1) -dnl| USE_PTYS=1 - ;; - - i386-ibm-aix ) -dnl| USE_PTYS=1 - if test "$GCC" = yes; then - CONF_CFLAGS="-fwritable-strings" - fi - ;; - - *-*-aix3* | *-*-bosx* ) - AC_DEFINE(PTY_ITERATION, [for (c = 0; !c; c++)]) - AC_DEFINE(PTY_NAME_SPRINTF, [strcpy (pty_name, "/dev/ptc");]) - AC_DEFINE(PTY_TTY_NAME_SPRINTF, [strcpy (pty_name, ttyname (fd));]) -dnl| USE_PTYS=1 - ;; - - *-*-cxux* ) - AC_DEFINE(FIRST_PTY_LETTER, 'A') - AC_DEFINE(LAST_PTY_LETTER, 'P') -dnl| USE_PTYS=1 - ;; - - *-*-uniplus* ) - AC_DEFINE(UNIPLUS, 1) -dnl| USE_PTYS=1 - ;; - - *-*-rtu* ) - AC_DEFINE(FIRST_PTY_LETTER, 'z') - AC_DEFINE(PTY_TTY_NAME_SPRINTF, - [sprintf (pty_name, "/dev/ttyp%x", i);]) - AC_DEFINE(PTY_NAME_SPRINTF, - [sprintf (pty_name, "/dev/pty%x", i);]) - AC_DEFINE(RTU, 1) -dnl| USE_PTYS=1 - ;; - - *-*-iris* | *-*-irix3* ) - AC_DEFINE(PTY_ITERATION, [for (c = 0; !c; c++)]) - AC_DEFINE(PTY_NAME_SPRINTF, [strcpy (pty_name, "/dev/ptc");]) - AC_DEFINE(PTY_TTY_NAME_SPRINTF, - [sprintf (pty_name, "/dev/ttyq%d", minor(stb.st_rdev));]) -dnl| USE_PTYS=1 - ;; - - *-*-irix* ) -dnl| USE_PTYS=1 - ;; - - *-*-sunos4* | *-*-solaris1* ) - -dnl| Work around a bug in the SunOS 4.x linker. Not needed if you have patches -dnl| 100512-02 and 100573-03 from Sun. The X FAQ says that the following is -dnl| "overkill," but doesn't explain what should be done instead. - - if test "$GCC" = yes; then - PRE_XMULIB="-static" - POST_XMULIB="-dynamic" - else - PRE_XMULIB="-Bstatic" - POST_XMULIB="-Bdynamic" - fi - ;; - - *-*-sunos5* | *-*-solaris2* ) -dnl| USE_PTYS=1 - -dnl| I'm not sure -lelf is needed, but it was in the old Imakefile. -dnl| The other libraries should all be found by Ac_PATH_XTRA or other -dnl| code above. - - X_LIBS="$X_LIBS -lelf" - ;; - - *-*-sco* ) - AC_DEFINE(PTY_ITERATION, [for (i = 0; ; i++)]) - AC_DEFINE(PTY_NAME_SPRINTF, [sprintf (pty_name, "/dev/ptyp%d", i);]) - AC_DEFINE(PTY_TTY_NAME_SPRINTF, [sprintf (pty_name, "/dev/ttyp%d", i);]) -dnl| USE_PTYS=1 - ;; - - *-*-dynix* | *-*-ptx* ) -dnl| USE_PTYS=1 - ;; - - *-*-esix* ) -dnl| USE_PTYS=1 - ;; - - *-*-usg5-4* | *-*-sysvr4* ) -dnl| USE_PTYS=1 - ;; - - *-*-usg* | *-*-sysv* | *-*-aix* ) -dnl| USE_PTYS=1 - ;; - - vax-*-ultrix ) - if test "$GCC" = yes; then - CONF_CFLAGS="-fwritable-strings" - fi - ;; -esac - -AC_ARG_ENABLE(xpm, -[ --enable-xpm libXpm will be used if found (default) - --disable-xpm libXpm will not be used], -[enable_xpm="$enableval"], [enable_xpm="yes"]) - -if test "$enable_xpm" = "yes"; then - save_cflags="$CFLAGS" - CFLAGS="$CFLAGS $X_CFLAGS" - CPPFLAGS="$CPPFLAGS $X_CFLAGS" - AC_CHECK_HEADERS(X11/xpm.h) - CFLAGS="$save_cflags" - if test "$ac_cv_header_X11_xpm_h" = "yes"; then - save_ldflags="$LDFLAGS" - LDFLAGS="$LDFLAGS $X_LIBS" - AC_CHECK_LIB(Xpm, XpmReadFileToPixmap, - [X_PRE_LIBS="-lXpm $X_PRE_LIBS"; AC_DEFINE(HAVE_LIBXPM)], [], - [$X_PRE_LIBS -lX11 $X_EXTRA_LIBS]) - LDFLAGS="$save_ldflags" - fi -fi - -AC_SUBST(PRE_XMULIB) -AC_SUBST(POST_XMULIB) -AC_SUBST(CONF_CFLAGS) -AC_SUBST(CONF_LDFLAGS) - -AC_MSG_CHECKING(whether ptys or pipes should be used) -AC_ARG_ENABLE(ptys, -[ --enable-ptys force use of pseudo-ttys with child processes - --disable-ptys force use of pipes with child processes], -[if test "$enableval" = yes; then - USE_PTYS=1 - AC_MSG_RESULT([ptys (user override)]) -fi -if test "$enableval" = no; then - USE_PTYS=0 - AC_MSG_RESULT([pipes (user override)]) -fi], -[if test "$USE_PTYS" = 1; then - AC_MSG_RESULT(ptys) -else - AC_MSG_RESULT(pipes) -fi]) -AC_DEFINE_UNQUOTED(USE_PTYS, $USE_PTYS) - - -dnl | define not to build zippy as a default, so that autoheader is happy -AC_DEFINE(ZIPPY, 0,[should zippy be enabled]) -AC_ARG_ENABLE(zippy, -[ --enable-zippy support interfacing a chess program to ICS (default) - --disable-zippy do not support interfacing a chess program to ICS], -[enable_zippy="$enableval"], [enable_zippy="yes"]) -if test "$enable_zippy" = yes; then - AC_DEFINE(ZIPPY, 1,[should zippy be enabled]) - ZIPPY_O=zippy.o - ZIPPY_H=zippy.h -fi -AC_SUBST(ZIPPY_O) -AC_SUBST(ZIPPY_H) - -AC_ARG_ENABLE(sigint, -[ --enable-sigint sending SIGINT (^C) wakes up GNU Chess (default) - --disable-sigint typing a command wakes up GNU Chess], -[if test "$enableval" = yes; then - AC_DEFINE(ATTENTION, 1) -fi], -[AC_DEFINE(ATTENTION, 1)]) - -AC_CONFIG_FILES([Makefile cmail]) -AC_CONFIG_COMMANDS([test-stamp-h],[test -z "$CONFIG_HEADERS" || date > stamp-h]) -AC_CONFIG_COMMANDS([chmod-cmail],[chmod 755 cmail]) -AC_OUTPUT +dnl| configure.in +dnl| +dnl| Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, 2007, +dnl| 2008, 2009 Free Software Foundation, Inc. +dnl| +dnl| GNU XBoard is free software: you can redistribute it and/or modify +dnl| it under the terms of the GNU General Public License as published by +dnl| the Free Software Foundation, either version 3 of the License, or (at +dnl| your option) any later version. +dnl| +dnl| GNU XBoard is distributed in the hope that it will be useful, but +dnl| WITHOUT ANY WARRANTY; without even the implied warranty of +dnl| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl| General Public License for more details. +dnl| +dnl| You should have received a copy of the GNU General Public License +dnl| along with this program. If not, see http://www.gnu.org/licenses/. +dnl| +dnl| -------------------------------------------------------------------- +dnl| +dnl| You can process this file with autoconf to produce a configure script. +dnl| However, normally the supplied configure script will work fine. +dnl| +dnl| If you do need to change the configure script, instead of editing +dnl| it directly, try to edit configure.in (in a way that will keep +dnl| it portable to sites and systems other than your own), and run autoconf +dnl| to regenerate configure. Then submit your changes to be folded into +dnl| the standard version of xboard. + +dnl| define second argument as VERSION.PATCHLEVEL. e.g. 4.4.0j +AC_INIT([xboard],[4.4.0.beta1],[bug-xboard@gnu.org]) +AM_INIT_AUTOMAKE + +AC_CONFIG_HEADERS([config.h]) + +dnl | a bunch of templates for defines used below +AH_TEMPLATE([FIRST_PTY_LETTER],[template]) +AH_TEMPLATE([HAVE_FCNTL_H],[template]) +AH_TEMPLATE([HAVE_GETHOSTNAME],[template]) +AH_TEMPLATE([HAVE_GETTIMEOFDAY],[template]) +AH_TEMPLATE([HAVE_RANDOM],[template]) +AH_TEMPLATE([HAVE_SYS_SOCKET_H],[template]) +AH_TEMPLATE([IBMRTAIX],[template]) +AH_TEMPLATE([LAST_PTY_LETTER],[template]) +AH_TEMPLATE([PTY_ITERATION],[template]) +AH_TEMPLATE([PTY_NAME_SPRINTF],[template]) +AH_TEMPLATE([PTY_OPEN],[template]) +AH_TEMPLATE([PTY_TTY_NAME_SPRINTF],[template]) +AH_TEMPLATE([REMOTE_SHELL],[template]) +AH_TEMPLATE([RTU],[template]) +AH_TEMPLATE([UNIPLUS],[template]) +AH_TEMPLATE([USE_PTYS],[template]) +AH_TEMPLATE([X_WCHAR],[template]) +AH_TEMPLATE([ATTENTION],[template]) +AH_TEMPLATE([DEFINED_SYS_ERRLIST],[template]) +AH_TEMPLATE([HAVE_LIBXPM],[template]) +AH_TEMPLATE([USE_XAW3D],[template]) +AH_TEMPLATE([X_LOCALE],[template]) + + + +if test -z "$CFLAGS" ; then +dnl| Prevent the next macro from setting CFLAGS to -g + CFLAGS=" " +fi +AC_PROG_CC +AC_PROG_CPP +AC_ISC_POSIX +AC_PROG_INSTALL + +AC_PROG_LEX +if test "$LEX" != flex; then + LEX="$SHELL $missing_dir/missing flex" + AC_SUBST([LEX_OUTPUT_ROOT], [lex.yy]) + AC_SUBST([LEXLIB], ['']) +fi + + +AC_CHECK_PROGS(RSH, remsh rsh, rsh) +AC_CHECK_PROGS(MINFO, makeinfo, makeinfo_not_found) +if test "$MINFO" == makeinfo_not_found ; then + echo Please install \"makeinfo\" + exit 1 +fi +AC_DEFINE_UNQUOTED(REMOTE_SHELL, "$RSH") +AC_CHECK_PROG(NROFF, nroff, [nroff -man], cat) +AC_SUBST(NROFFFLAGS) +AC_PATH_PROGS(AWKPATH, awk mawk gawk nawk) +AC_PATH_PROGS(PERLPATH, perl) + +AC_HEADER_STDC +AC_HEADER_TIME +AC_HEADER_SYS_WAIT +AC_HEADER_DIRENT +AC_TYPE_SIGNAL +AC_CHECK_HEADERS(stropts.h sys/time.h string.h unistd.h sys/systeminfo.h) +AC_CHECK_HEADERS(fcntl.h sys/fcntl.h, break) +AC_CHECK_HEADERS(sys/socket.h lan/socket.h, break) +AC_CHECK_HEADER(stddef.h, [], AC_DEFINE(X_WCHAR, 1)) + +AC_CHECK_FUNCS(_getpty grantpt setitimer usleep) +AC_CHECK_FUNCS(gettimeofday ftime, break) +AC_CHECK_FUNCS(random rand48, break) +AC_CHECK_FUNCS(gethostname sysinfo, break) +AC_CHECK_FUNC(setlocale, [], + AC_CHECK_LIB(i, setlocale, [], AC_DEFINE(X_LOCALE, 1))) + +AC_CHECK_LIB(seq, getpseudotty) + +AC_PATH_XTRA +if test -n "$no_x" ; then + echo $PACKAGE requires the X Window System header files and libraries! + echo They were not found on your system. See FAQ topic C.2. + echo configure failed + exit 1 +fi + +AC_CHECK_HEADER(X11/Intrinsic.h,xt="yes",xt="no") + +if test "$xt" == "no" ; then + echo Xt headers not found + exit 1 +fi + +dnl | test if user wants ot use Xaw3d headers +AC_ARG_WITH([Xaw3d], + [AS_HELP_STRING([--with-Xaw3d], + [use Xaw3d instead of Xaw])], + [with_xaw3d=yes], + [with_xaw3d=no]) + +XAW_LIBS= +AS_IF([test "x$with_xaw3d" != xno], + [AC_CHECK_LIB([Xaw3d], + [XawTextReplace], + [AC_SUBST([XAW_LIBS], + ["-lXaw3d"]) + AC_DEFINE([USE_XAW3D], [1], + [Define if you want to use Xaw3d])], + [AC_CHECK_HEADER(X11/Xaw/Dialog.h,xaw_headers="yes") + AC_MSG_FAILURE( + [--with-Xaw3d was given, but test for Xaw3d failed])], + [-lXaw])]) +if test "$with_xaw3d" == "no" ; then + XAW_LIBS="-lXaw" +fi +AC_SUBST(XAW_LIBS) + +dnl | end Xaw3d test + +if test "$xaw_headers" == "no" ; then + echo Xaw headers not found + exit 1 + +fi + + +AC_CANONICAL_HOST + +dnl| The following info is mostly gathered from GNU Emacs 19.24. Basically, +dnl| we are trying to find out whether this is a System-V derivative in +dnl| which pipes don't work with select() and if so, whether there is anything +dnl| strange about the way to open a pty. Some of the work was done above +dnl| by looking for _getpty, grantpt, and getpseudotty. A few other strange +dnl| properties of particular systems are also handled here. + +dnl| 4/6/97 I'm not sure there really are any systems where pipes +dnl| don't work with select(), and ptys cause problems on many +dnl| systems, so I'm changing the default to disable ptys in all +dnl| cases. I will change it back if I get bug reports that are fixed +dnl| by doing a "configure --enable-ptys" + +USE_PTYS=0 +case "$host" in + *-*-hpux* ) + AC_DEFINE(PTY_TTY_NAME_SPRINTF, + [sprintf (pty_name, "/dev/pty/tty%c%x", c, i);]) + AC_DEFINE(PTY_NAME_SPRINTF, + [sprintf (pty_name, "/dev/ptym/pty%c%x", c, i);]) +dnl| USE_PTYS=1 + if test "$GCC" = yes; then + CONF_CFLAGS="-fwritable-strings" + else + +dnl| Note: You might be able to build xboard even if your compiler does not +dnl| support ANSI C (-Aa). xboard itself does not require ANSI C. I don't +dnl| know whether the X header files on HP-UX require it. + + CONF_CFLAGS="-Aa -D_HPUX_SOURCE" + fi + +dnl| HP doesn't supply a full set of X header files and libraries. People +dnl| often have some things installed in one place and some in another. +dnl| AC_PATH_XTRA will find only one place, so we try to add all the +dnl| likely ones that might be missing here. It might be better to +dnl| change AC_PATH_XTRA to try to extract this information from imake, +dnl| since folks who install the missing bits often configure their +dnl| imake to find them, but I don't want to delve into autoconf and +dnl| hack on its internals. + + if test -d /opt/hppd/include/X11; then + X_CFLAGS="$X_CFLAGS -I/opt/hppd/include" + X_LIBS="$X_LIBS -L/opt/hppd/lib" + elif test -d /usr/contrib/X11R5/include; then + X_CFLAGS="$X_CFLAGS -I/usr/contrib/X11R5/include" + X_LIBS="$X_LIBS -L/usr/contrib/X11R5/lib" + elif test -d /usr/contrib/mitX11R5/include; then + X_CFLAGS="$X_CFLAGS -I/usr/contrib/mitX11R5/include" + X_LIBS="$X_LIBS -L/usr/contrib/mitX11R5/lib" + elif test -d /MIT/X11R5/include; then + X_CFLAGS="$X_CFLAGS -I/MIT/X11R5/include" + X_LIBS="$X_LIBS -L/MIT/X11R5/lib" + elif test -d /usr/local/include/X11R5; then + X_CFLAGS="$X_CFLAGS -I/usr/local/include/X11R5" + X_LIBS="$X_LIBS -L/usr/local/lib/X11R5" + fi + if test -d /usr/include/X11R5; then + X_CFLAGS="$X_CFLAGS -I/usr/include/X11R5" + X_LIBS="$X_LIBS -L/usr/lib/X11R5 -L/usr/lib/X11R4" + elif test -d /usr/include/X11R4; then + X_CFLAGS="$X_CFLAGS -I/usr/include/X11R4" + X_LIBS="$X_LIBS -L/usr/lib/X11R4" + fi + ;; + + romp-ibm-aix* ) + AC_DEFINE(IBMRTAIX, 1) +dnl| USE_PTYS=1 + ;; + + i386-ibm-aix ) +dnl| USE_PTYS=1 + if test "$GCC" = yes; then + CONF_CFLAGS="-fwritable-strings" + fi + ;; + + *-*-aix3* | *-*-bosx* ) + AC_DEFINE(PTY_ITERATION, [for (c = 0; !c; c++)]) + AC_DEFINE(PTY_NAME_SPRINTF, [strcpy (pty_name, "/dev/ptc");]) + AC_DEFINE(PTY_TTY_NAME_SPRINTF, [strcpy (pty_name, ttyname (fd));]) +dnl| USE_PTYS=1 + ;; + + *-*-cxux* ) + AC_DEFINE(FIRST_PTY_LETTER, 'A') + AC_DEFINE(LAST_PTY_LETTER, 'P') +dnl| USE_PTYS=1 + ;; + + *-*-uniplus* ) + AC_DEFINE(UNIPLUS, 1) +dnl| USE_PTYS=1 + ;; + + *-*-rtu* ) + AC_DEFINE(FIRST_PTY_LETTER, 'z') + AC_DEFINE(PTY_TTY_NAME_SPRINTF, + [sprintf (pty_name, "/dev/ttyp%x", i);]) + AC_DEFINE(PTY_NAME_SPRINTF, + [sprintf (pty_name, "/dev/pty%x", i);]) + AC_DEFINE(RTU, 1) +dnl| USE_PTYS=1 + ;; + + *-*-iris* | *-*-irix3* ) + AC_DEFINE(PTY_ITERATION, [for (c = 0; !c; c++)]) + AC_DEFINE(PTY_NAME_SPRINTF, [strcpy (pty_name, "/dev/ptc");]) + AC_DEFINE(PTY_TTY_NAME_SPRINTF, + [sprintf (pty_name, "/dev/ttyq%d", minor(stb.st_rdev));]) +dnl| USE_PTYS=1 + ;; + + *-*-irix* ) +dnl| USE_PTYS=1 + ;; + + *-*-sunos4* | *-*-solaris1* ) + +dnl| Work around a bug in the SunOS 4.x linker. Not needed if you have patches +dnl| 100512-02 and 100573-03 from Sun. The X FAQ says that the following is +dnl| "overkill," but doesn't explain what should be done instead. + + if test "$GCC" = yes; then + PRE_XMULIB="-static" + POST_XMULIB="-dynamic" + else + PRE_XMULIB="-Bstatic" + POST_XMULIB="-Bdynamic" + fi + ;; + + *-*-sunos5* | *-*-solaris2* ) +dnl| USE_PTYS=1 + +dnl| I'm not sure -lelf is needed, but it was in the old Imakefile. +dnl| The other libraries should all be found by Ac_PATH_XTRA or other +dnl| code above. + + X_LIBS="$X_LIBS -lelf" + ;; + + *-*-sco* ) + AC_DEFINE(PTY_ITERATION, [for (i = 0; ; i++)]) + AC_DEFINE(PTY_NAME_SPRINTF, [sprintf (pty_name, "/dev/ptyp%d", i);]) + AC_DEFINE(PTY_TTY_NAME_SPRINTF, [sprintf (pty_name, "/dev/ttyp%d", i);]) +dnl| USE_PTYS=1 + ;; + + *-*-dynix* | *-*-ptx* ) +dnl| USE_PTYS=1 + ;; + + *-*-esix* ) +dnl| USE_PTYS=1 + ;; + + *-*-usg5-4* | *-*-sysvr4* ) +dnl| USE_PTYS=1 + ;; + + *-*-usg* | *-*-sysv* | *-*-aix* ) +dnl| USE_PTYS=1 + ;; + + vax-*-ultrix ) + if test "$GCC" = yes; then + CONF_CFLAGS="-fwritable-strings" + fi + ;; +esac + +AC_ARG_ENABLE(xpm, +[ --enable-xpm libXpm will be used if found (default) + --disable-xpm libXpm will not be used], +[enable_xpm="$enableval"], [enable_xpm="yes"]) + +if test "$enable_xpm" = "yes"; then + save_cflags="$CFLAGS" + CFLAGS="$CFLAGS $X_CFLAGS" + CPPFLAGS="$CPPFLAGS $X_CFLAGS" + AC_CHECK_HEADERS(X11/xpm.h) + CFLAGS="$save_cflags" + if test "$ac_cv_header_X11_xpm_h" = "yes"; then + save_ldflags="$LDFLAGS" + LDFLAGS="$LDFLAGS $X_LIBS" + AC_CHECK_LIB(Xpm, XpmReadFileToPixmap, + [X_PRE_LIBS="-lXpm $X_PRE_LIBS"; AC_DEFINE(HAVE_LIBXPM)], [], + [$X_PRE_LIBS -lX11 $X_EXTRA_LIBS]) + LDFLAGS="$save_ldflags" + fi +fi + +AC_SUBST(PRE_XMULIB) +AC_SUBST(POST_XMULIB) +AC_SUBST(CONF_CFLAGS) +AC_SUBST(CONF_LDFLAGS) + +AC_MSG_CHECKING(whether ptys or pipes should be used) +AC_ARG_ENABLE(ptys, +[ --enable-ptys force use of pseudo-ttys with child processes + --disable-ptys force use of pipes with child processes], +[if test "$enableval" = yes; then + USE_PTYS=1 + AC_MSG_RESULT([ptys (user override)]) +fi +if test "$enableval" = no; then + USE_PTYS=0 + AC_MSG_RESULT([pipes (user override)]) +fi], +[if test "$USE_PTYS" = 1; then + AC_MSG_RESULT(ptys) +else + AC_MSG_RESULT(pipes) +fi]) +AC_DEFINE_UNQUOTED(USE_PTYS, $USE_PTYS) + + +dnl | define not to build zippy as a default, so that autoheader is happy +AC_DEFINE(ZIPPY, 0,[should zippy be enabled]) +AC_ARG_ENABLE(zippy, +[ --enable-zippy support interfacing a chess program to ICS (default) + --disable-zippy do not support interfacing a chess program to ICS], +[enable_zippy="$enableval"], [enable_zippy="yes"]) +if test "$enable_zippy" = yes; then + AC_DEFINE(ZIPPY, 1,[should zippy be enabled]) + ZIPPY_O=zippy.o + ZIPPY_H=zippy.h +fi +AC_SUBST(ZIPPY_O) +AC_SUBST(ZIPPY_H) + +AC_ARG_ENABLE(sigint, +[ --enable-sigint sending SIGINT (^C) wakes up GNU Chess (default) + --disable-sigint typing a command wakes up GNU Chess], +[if test "$enableval" = yes; then + AC_DEFINE(ATTENTION, 1) +fi], +[AC_DEFINE(ATTENTION, 1)]) + +AC_CONFIG_FILES([Makefile cmail]) +AC_CONFIG_COMMANDS([test-stamp-h],[test -z "$CONFIG_HEADERS" || date > stamp-h]) +AC_CONFIG_COMMANDS([chmod-cmail],[chmod 755 cmail]) +AC_OUTPUT diff --git a/parser.h b/parser.h index abce968..c7b87e2 100644 --- a/parser.h +++ b/parser.h @@ -1,66 +1,66 @@ -/* - * parser.h -- Interface to XBoard move parser - * - * Copyright 1991 by Digital Equipment Corporation, Maynard, - * Massachusetts. - * - * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009 Free Software Foundation, Inc. - * - * Enhancements Copyright 2005 Alessandro Scotti - * - * 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. - * ------------------------------------------------------------------------ - * - * The following terms apply to the enhanced version of XBoard - * distributed by the Free Software Foundation: - * ------------------------------------------------------------------------ - * - * GNU XBoard is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * GNU XBoard is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. * - * - *------------------------------------------------------------------------ - ** See the file ChangeLog for a revision history. */ - -extern void yynewfile P((FILE *f)); -extern void yynewstr P((char *s)); -extern int yylex P((void)); -extern ChessMove yylexstr P((int boardIndex, char *s)); -extern char currentMoveString[]; -extern int yyboardindex; -extern int yyskipmoves; /* If TRUE, all moves are reported as AmbiguousMove - instead of being disambiguated. */ -extern char *yy_text; /* Needed because yytext can be either a char[] - or a (non-constant) char* */ -extern int yyoffset P((void)); -extern char initialRights[BOARD_SIZE]; -extern char castlingRights[MAX_MOVES][BOARD_SIZE]; +/* + * parser.h -- Interface to XBoard move parser + * + * Copyright 1991 by Digital Equipment Corporation, Maynard, + * Massachusetts. + * + * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, + * 2007, 2008, 2009 Free Software Foundation, Inc. + * + * Enhancements Copyright 2005 Alessandro Scotti + * + * 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. + * ------------------------------------------------------------------------ + * + * The following terms apply to the enhanced version of XBoard + * distributed by the Free Software Foundation: + * ------------------------------------------------------------------------ + * + * GNU XBoard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * GNU XBoard is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. * + * + *------------------------------------------------------------------------ + ** See the file ChangeLog for a revision history. */ + +extern void yynewfile P((FILE *f)); +extern void yynewstr P((char *s)); +extern int yylex P((void)); +extern ChessMove yylexstr P((int boardIndex, char *s)); +extern char currentMoveString[]; +extern int yyboardindex; +extern int yyskipmoves; /* If TRUE, all moves are reported as AmbiguousMove + instead of being disambiguated. */ +extern char *yy_text; /* Needed because yytext can be either a char[] + or a (non-constant) char* */ +extern int yyoffset P((void)); +extern char initialRights[BOARD_SIZE]; +extern char castlingRights[MAX_MOVES][BOARD_SIZE]; diff --git a/xengineoutput.c b/xengineoutput.c index 29e987e..77d5bf3 100644 --- a/xengineoutput.c +++ b/xengineoutput.c @@ -1,979 +1,979 @@ -/* - * Engine output (PV) - * - * Author: Alessandro Scotti (Dec 2005) - * - * Copyright 2005 Alessandro Scotti - * - * Enhancements Copyright 2009 Free Software Foundation, Inc. - * - * ------------------------------------------------------------------------ - * - * GNU XBoard is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * GNU XBoard is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - * - * ------------------------------------------------------------------------ - ** See the file ChangeLog for a revision history. */ - -#include "config.h" - -#include -#include -#include -#include - -#if STDC_HEADERS -# include -# include -#else /* not STDC_HEADERS */ -extern char *getenv(); -# if HAVE_STRING_H -# include -# else /* not HAVE_STRING_H */ -# include -# endif /* not HAVE_STRING_H */ -#endif /* not STDC_HEADERS */ - -#if HAVE_UNISTD_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "frontend.h" -#include "backend.h" -#include "xboard.h" -// Add xengineo.h later -#include "gettext.h" - -#ifdef ENABLE_NLS -# define _(s) gettext (s) -# define N_(s) gettext_noop (s) -#else -# define _(s) (s) -# define N_(s) s -#endif - -#include - -// [HGM] pixmaps of some ICONS used in the engine-outut window -#include "pixmaps/WHITE_14.xpm" -#include "pixmaps/BLACK_14.xpm" -#include "pixmaps/CLEAR_14.xpm" -#include "pixmaps/UNKNOWN_14.xpm" -#include "pixmaps/THINKING_14.xpm" -#include "pixmaps/PONDER_14.xpm" -#include "pixmaps/ANALYZING_14.xpm" - -#ifdef SNAP -#include "wsnap.h" -#endif - -#define _LL_ 100 - -// imports from xboard.c -extern Widget formWidget, shellWidget, boardWidget, menuBarWidget; -extern Display *xDisplay; -extern Window xBoardWindow; -extern int squareSize; -extern Pixmap xMarkPixmap, wIconPixmap, bIconPixmap; -extern char *layoutName; - -// temporary kludge to avoid compile errors untill all Windows code has been replaced -#define HICON int * -#define HWND int * - -// [HGM] define numbers to indicate icons, for referring to them in platform-independent way -#define nColorBlack 1 -#define nColorWhite 2 -#define nColorUnknown 3 -#define nClear 4 -#define nPondering 5 -#define nThinking 6 -#define nAnalyzing 7 - -Pixmap icons[8]; // [HGM] this front-end array translates back-end icon indicator to handle - -// [HGM] same for output fields (note that there are two of each type, one per color) -#define nColorIcon 1 -#define nStateIcon 2 -#define nLabel 3 -#define nStateData 4 -#define nLabelNPS 5 -#define nMemo 6 - -Widget outputField[2][7]; // [HGM] front-end array to translate output field to window handle - -void EngineOutputPopDown(); -void engineOutputPopUp(char *title, char *text); -int EngineOutputIsUp(); -static void SetEngineColorIcon( int which ); - -#define SHOW_PONDERING - -/* Imports from backend.c */ -char * SavePart(char *str); -extern int opponentKibitzes; - -/* Imports from winboard.c */ -//extern HWND engineOutputDialog; -extern Arg layoutArgs[2], formArgs[2], messageArgs[4]; - -//extern WindowPlacement wpEngineOutput; - -Position engineOutputX = -1, engineOutputY = -1; -Dimension engineOutputW, engineOutputH; -Widget engineOutputShell; -int engineOutputDialogUp; - -/* Module variables */ -#define H_MARGIN 2 -#define V_MARGIN 2 -#define LABEL_V_DISTANCE 1 /* Distance between label and memo */ -#define SPLITTER_SIZE 4 /* Distance between first memo and second label */ - -#define ICON_SIZE 14 - -#define STATE_UNKNOWN -1 -#define STATE_THINKING 0 -#define STATE_IDLE 1 -#define STATE_PONDERING 2 -#define STATE_ANALYZING 3 - -static int windowMode = 1; - -static int needInit = TRUE; - -static int lastDepth[2] = { -1, -1 }; -static int lastForwardMostMove[2] = { -1, -1 }; -static int engineState[2] = { -1, -1 }; - -typedef struct { - char * name; - int which; - int depth; - u64 nodes; - int score; - int time; - char * pv; - char * hint; - int an_move_index; - int an_move_count; -} EngineOutputData; - -static int VerifyDisplayMode(); -static void UpdateControls( EngineOutputData * ed ); -static SetEngineState( int which, int state, char * state_data ); - -void ReadIcon(char *pixData[], int iconNr) -{ - int r; - - if ((r=XpmCreatePixmapFromData(xDisplay, XtWindow(outputField[0][nColorIcon]), - pixData, - &(icons[iconNr]), - NULL, NULL /*&attr*/)) != 0) { - fprintf(stderr, _("Error %d loading icon image\n"), r); - exit(1); - } -} - -static void InitializeEngineOutput() -{ int i; - - ReadIcon(WHITE_14, nColorWhite); - ReadIcon(BLACK_14, nColorBlack); - ReadIcon(UNKNOWN_14, nColorUnknown); - - ReadIcon(CLEAR_14, nClear); - ReadIcon(PONDER_14, nPondering); - ReadIcon(THINK_14, nThinking); - ReadIcon(ANALYZE_14, nAnalyzing); -} - -void DoSetWindowText(int which, int field, char *s_label) -{ - Arg arg; - - XtSetArg(arg, XtNlabel, (XtArgVal) s_label); - XtSetValues(outputField[which][field], &arg, 1); -} - -static void InsertIntoMemo( int which, char * text ) -{ - Arg arg; XawTextBlock t; Widget edit; - - t.ptr = text; t.firstPos = 0; t.length = strlen(text); t.format = XawFmt8Bit; - edit = XtNameToWidget(engineOutputShell, which ? "*form2.text" : "*form.text"); - XawTextReplace(edit, 0, 0, &t); -// XtSetArg(arg, XtNstring, (XtArgVal) text); -// XtSetValues(outputField[which][nMemo], &arg, 1); -} - -static void SetIcon( int which, int field, int nIcon ) -{ - Arg arg; - - if( nIcon != 0 ) { - XtSetArg(arg, XtNleftBitmap, (XtArgVal) icons[nIcon]); - XtSetValues(outputField[which][field], &arg, 1); - } -} - -void DoClearMemo(int which) -{ - Arg args[16]; - int j; - Widget edit; - - edit = XtNameToWidget(engineOutputShell, which ? "*form2.text" : "*form.text"); - XtCallActionProc(edit, "select-all", NULL, NULL, 0); - XtCallActionProc(edit, "kill-selection", NULL, NULL, 0); -} - -// The following routines are mutated clones of the commentPopUp routines - -void PositionControlSet(which, form, bw_width) - int which; - Widget form; - Dimension bw_width; -{ - Arg args[16]; - Widget edit, NameWidget, ColorWidget, ModeWidget, MoveWidget, NodesWidget; - int j, mutable=1; - j = 0; - XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; - XtSetArg(args[j], XtNlabel, (XtArgVal) ""); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; - XtSetArg(args[j], XtNwidth, (XtArgVal) 17); j++; - outputField[which][nColorIcon] = ColorWidget = - XtCreateManagedWidget("Color", labelWidgetClass, - form, args, j); - - j = 0; - XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; - XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; - XtSetArg(args[j], XtNfromHoriz, (XtArgVal) ColorWidget); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; - XtSetArg(args[j], XtNwidth, (XtArgVal) bw_width/2 - 57); j++; - outputField[which][nLabel] = NameWidget = - XtCreateManagedWidget("Engine", labelWidgetClass, - form, args, j); - - j = 0; - XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; - XtSetArg(args[j], XtNlabel, (XtArgVal) ""); j++; - XtSetArg(args[j], XtNfromHoriz, (XtArgVal) NameWidget); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; - XtSetArg(args[j], XtNwidth, (XtArgVal) 20); j++; - outputField[which][nStateIcon] = ModeWidget = - XtCreateManagedWidget("Mode", labelWidgetClass, - form, args, j); - - j = 0; - XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; - XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; - XtSetArg(args[j], XtNlabel, (XtArgVal) ""); j++; - XtSetArg(args[j], XtNfromHoriz, (XtArgVal) ModeWidget); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; - XtSetArg(args[j], XtNwidth, (XtArgVal) bw_width/2 - 102); j++; - outputField[which][nStateData] = MoveWidget = - XtCreateManagedWidget("Move", labelWidgetClass, - form, args, j); - - j = 0; - XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; - XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyRight); j++; - XtSetArg(args[j], XtNlabel, (XtArgVal) _("NPS")); j++; - XtSetArg(args[j], XtNfromHoriz, (XtArgVal) MoveWidget); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; - XtSetArg(args[j], XtNwidth, (XtArgVal) 100); j++; - outputField[which][nLabelNPS] = NodesWidget = - XtCreateManagedWidget("Nodes", labelWidgetClass, - form, args, j); - - // create "text" within "form" - j = 0; - if (mutable) { - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - } - XtSetArg(args[j], XtNstring, ""); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, bw_width); j++; /*force wider than buttons*/ -#if 0 - XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++; -#else - /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */ - XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++; - XtSetArg(args[j], XtNscrollHorizontal, XawtextScrollWhenNeeded); j++; -#endif -// XtSetArg(args[j], XtNautoFill, True); j++; -// XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++; - outputField[which][nMemo] = edit = - XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j); - - j = 0; - XtSetArg(args[j], XtNfromVert, ColorWidget); j++; -// XtSetArg(args[j], XtNresizable, (XtArgVal) True); j++; - XtSetValues(edit, args, j); -} - -Widget EngineOutputCreate(name, text) - char *name, *text; -{ - Arg args[16]; - Widget shell, layout, form, form2, edit; - Dimension bw_width, bw_height; - int j; - - // get board width - j = 0; - XtSetArg(args[j], XtNwidth, &bw_width); j++; - XtSetArg(args[j], XtNheight, &bw_height); j++; - XtGetValues(boardWidget, args, j); - - // define form within layout within shell. - j = 0; - XtSetArg(args[j], XtNresizable, True); j++; - shell = - XtCreatePopupShell(name, transientShellWidgetClass, - shellWidget, args, j); - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, shell, - layoutArgs, XtNumber(layoutArgs)); - // divide window vertically into two equal parts, by creating two forms - form = - XtCreateManagedWidget("form", formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - form2 = - XtCreateManagedWidget("form2", formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - j = 0; - XtSetArg(args[j], XtNfromVert, (XtArgVal) form); j++; - XtSetValues(form2, args, j); - // make sure width is known in advance, for better placement of child widgets - j = 0; - XtSetArg(args[j], XtNwidth, (XtArgVal) bw_width-16); j++; - XtSetArg(args[j], XtNheight, (XtArgVal) bw_height/2); j++; - XtSetValues(shell, args, j); - - // fill up both forms with control elements - PositionControlSet(0, form, bw_width); - PositionControlSet(1, form2, bw_width); - - XtRealizeWidget(shell); - - if (engineOutputX == -1) { - int xx, yy; - Window junk; - Dimension pw_height; - Dimension ew_height; -#if 0 - j = 0; - XtSetArg(args[j], XtNheight, &ew_height); j++; - XtGetValues(edit, args, j); - - j = 0; - XtSetArg(args[j], XtNheight, &pw_height); j++; - XtGetValues(shell, args, j); - engineOutputH = pw_height + (lines - 1) * ew_height; - engineOutputW = bw_width - 16; -#else - engineOutputH = bw_height/2; - engineOutputW = bw_width-16; -#endif - - XSync(xDisplay, False); -#ifdef NOTDEF - /* This code seems to tickle an X bug if it is executed too soon - after xboard starts up. The coordinates get transformed as if - the main window was positioned at (0, 0). - */ - XtTranslateCoords(shellWidget, - (bw_width - engineOutputW) / 2, 0 - engineOutputH / 2, - &engineOutputX, &engineOutputY); -#else /*!NOTDEF*/ - XTranslateCoordinates(xDisplay, XtWindow(shellWidget), - RootWindowOfScreen(XtScreen(shellWidget)), - (bw_width - engineOutputW) / 2, 0 - engineOutputH / 2, - &xx, &yy, &junk); - engineOutputX = xx; - engineOutputY = yy; -#endif /*!NOTDEF*/ - if (engineOutputY < 0) engineOutputY = 0; /*avoid positioning top offscreen*/ - } - j = 0; - XtSetArg(args[j], XtNheight, engineOutputH); j++; - XtSetArg(args[j], XtNwidth, engineOutputW); j++; - XtSetArg(args[j], XtNx, engineOutputX); j++; - XtSetArg(args[j], XtNy, engineOutputY); j++; - XtSetValues(shell, args, j); -// XtSetKeyboardFocus(shell, edit); - - return shell; -} - -void ResizeWindowControls(shell, mode) - Widget shell; - int mode; -{ - Widget form1, form2; - Arg args[16]; - int j; - Dimension ew_height, tmp; - - form1 = XtNameToWidget(shell, "*form"); - form2 = XtNameToWidget(shell, "*form2"); - - j = 0; - XtSetArg(args[j], XtNheight, (XtArgVal) &ew_height); j++; - XtGetValues(form1, args, j); - j = 0; - XtSetArg(args[j], XtNheight, (XtArgVal) &tmp); j++; - XtGetValues(form2, args, j); - ew_height += tmp; // total height - - if(mode==0) { - j = 0; - XtSetArg(args[j], XtNheight, (XtArgVal) 5); j++; - XtSetValues(form2, args, j); - j = 0; - XtSetArg(args[j], XtNheight, (XtArgVal) (ew_height-5)); j++; - XtSetValues(form1, args, j); - } else { - j = 0; - XtSetArg(args[j], XtNheight, (XtArgVal) (ew_height/2)); j++; - XtSetValues(form1, args, j); - j = 0; - XtSetArg(args[j], XtNheight, (XtArgVal) (ew_height/2)); j++; - XtSetValues(form2, args, j); - } -} - -void EngineOutputPopUp(title, text) - char *title, *text; -{ - Arg args[16]; - int j; - Widget edit; - - if (engineOutputShell == NULL) { - engineOutputShell = - EngineOutputCreate(title, text); - XtRealizeWidget(engineOutputShell); - CatchDeleteWindow(engineOutputShell, "EngineOutputPopDown"); - if( needInit ) { - InitializeEngineOutput(); - needInit = FALSE; - } - SetEngineColorIcon( 0 ); - SetEngineColorIcon( 1 ); - SetEngineState( 0, STATE_IDLE, "" ); - SetEngineState( 1, STATE_IDLE, "" ); - } else { - edit = XtNameToWidget(engineOutputShell, "*form.text"); - j = 0; - XtSetArg(args[j], XtNstring, text); j++; - XtSetValues(edit, args, j); - j = 0; - XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++; - XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++; - XtSetValues(engineOutputShell, args, j); - } - - XtPopup(engineOutputShell, XtGrabNone); - XSync(xDisplay, False); - - j=0; - XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Engine Output"), - args, j); - - engineOutputDialogUp = True; - ShowThinkingEvent(); // [HGM] thinking: might need to prompt engine for thinking output -} - -void EngineOutputPopDown() -{ - Arg args[16]; - int j; - - if (!engineOutputDialogUp) return; - DoClearMemo(1); - j = 0; - XtSetArg(args[j], XtNx, &engineOutputX); j++; - XtSetArg(args[j], XtNy, &engineOutputY); j++; - XtSetArg(args[j], XtNwidth, &engineOutputW); j++; - XtSetArg(args[j], XtNheight, &engineOutputH); j++; - XtGetValues(engineOutputShell, args, j); - XtPopdown(engineOutputShell); - XSync(xDisplay, False); - j=0; - XtSetArg(args[j], XtNleftBitmap, None); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Engine Output"), - args, j); - - engineOutputDialogUp = False; - ShowThinkingEvent(); // [HGM] thinking: might need to shut off thinking output -} - -//------------------------ pure back-end routines ------------------------------- - - -// back end, due to front-end wrapper for SetWindowText, and new SetIcon arguments -static SetEngineState( int which, int state, char * state_data ) -{ - int x_which = 1 - which; - - if( engineState[ which ] != state ) { - engineState[ which ] = state; - - switch( state ) { - case STATE_THINKING: - SetIcon( which, nStateIcon, nThinking ); - if( engineState[ x_which ] == STATE_THINKING ) { - SetEngineState( x_which, STATE_IDLE, "" ); - } - break; - case STATE_PONDERING: - SetIcon( which, nStateIcon, nPondering ); - break; - case STATE_ANALYZING: - SetIcon( which, nStateIcon, nAnalyzing ); - break; - default: - SetIcon( which, nStateIcon, nClear ); - break; - } - } - - if( state_data != 0 ) { - DoSetWindowText( which, nStateData, state_data ); - } -} - -// back end, now the front-end wrapper ClearMemo is used, and ed no longer contains handles. -void EngineOutputUpdate( FrontEndProgramStats * stats ) -{ - EngineOutputData ed; - int clearMemo = FALSE; - int which; - int depth; - - if( stats == 0 ) { - SetEngineState( 0, STATE_IDLE, "" ); - SetEngineState( 1, STATE_IDLE, "" ); - return; - } - - if(gameMode == IcsObserving && !appData.icsEngineAnalyze) - return; // [HGM] kibitz: shut up engine if we are observing an ICS game - - which = stats->which; - depth = stats->depth; - - if( which < 0 || which > 1 || depth < 0 || stats->time < 0 || stats->pv == 0 ) { - return; - } - - if( engineOutputShell == NULL ) { - return; - } - - VerifyDisplayMode(); - - ed.which = which; - ed.depth = depth; - ed.nodes = stats->nodes; - ed.score = stats->score; - ed.time = stats->time; - ed.pv = stats->pv; - ed.hint = stats->hint; - ed.an_move_index = stats->an_move_index; - ed.an_move_count = stats->an_move_count; - - /* Get target control. [HGM] this is moved to front end, which get them from a table */ - if( which == 0 ) { - ed.name = first.tidy; - } - else { - ed.name = second.tidy; - } - - /* Clear memo if needed */ - if( lastDepth[which] > depth || (lastDepth[which] == depth && depth <= 1) ) { - clearMemo = TRUE; - } - - if( lastForwardMostMove[which] != forwardMostMove ) { - clearMemo = TRUE; - } - - if( clearMemo ) DoClearMemo(which); - - /* Update */ - lastDepth[which] = depth; - lastForwardMostMove[which] = forwardMostMove; - - if( ed.pv != 0 && ed.pv[0] == ' ' ) { - if( strncmp( ed.pv, " no PV", 6 ) == 0 ) { /* Hack on hack! :-O */ - ed.pv = ""; - } - } - - UpdateControls( &ed ); -} - -#define ENGINE_COLOR_WHITE 'w' -#define ENGINE_COLOR_BLACK 'b' -#define ENGINE_COLOR_UNKNOWN ' ' - -// pure back end -char GetEngineColor( int which ) -{ - char result = ENGINE_COLOR_UNKNOWN; - - if( which == 0 || which == 1 ) { - ChessProgramState * cps; - - switch (gameMode) { - case MachinePlaysBlack: - case IcsPlayingBlack: - result = ENGINE_COLOR_BLACK; - break; - case MachinePlaysWhite: - case IcsPlayingWhite: - result = ENGINE_COLOR_WHITE; - break; - case AnalyzeMode: - case AnalyzeFile: - result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK; - break; - case TwoMachinesPlay: - cps = (which == 0) ? &first : &second; - result = cps->twoMachinesColor[0]; - result = result == 'w' ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK; - break; - } - } - - return result; -} - -// pure back end -char GetActiveEngineColor() -{ - char result = ENGINE_COLOR_UNKNOWN; - - if( gameMode == TwoMachinesPlay ) { - result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK; - } - - return result; -} - -// pure back end -static int IsEnginePondering( int which ) -{ - int result = FALSE; - - switch (gameMode) { - case MachinePlaysBlack: - case IcsPlayingBlack: - if( WhiteOnMove(forwardMostMove) ) result = TRUE; - break; - case MachinePlaysWhite: - case IcsPlayingWhite: - if( ! WhiteOnMove(forwardMostMove) ) result = TRUE; - break; - case TwoMachinesPlay: - if( GetActiveEngineColor() != ENGINE_COLOR_UNKNOWN ) { - if( GetEngineColor( which ) != GetActiveEngineColor() ) result = TRUE; - } - break; - } - - return result; -} - -// back end -static void SetDisplayMode( int mode ) -{ - if( windowMode != mode ) { - windowMode = mode; - - ResizeWindowControls( engineOutputShell, mode ); - } -} - -// pure back end -int VerifyDisplayMode() -{ - int mode; - - /* Get proper mode for current game */ - switch( gameMode ) { - case IcsObserving: // [HGM] ICS analyze - if(!appData.icsEngineAnalyze) return; - case AnalyzeMode: - case AnalyzeFile: - case MachinePlaysWhite: - case MachinePlaysBlack: - mode = 0; - break; - case IcsPlayingWhite: - case IcsPlayingBlack: - mode = appData.zippyPlay && opponentKibitzes; // [HGM] kibitz - break; - case TwoMachinesPlay: - mode = 1; - break; - default: - /* Do not change */ - return; - } - - SetDisplayMode( mode ); -} - -// back end. Determine what icon to se in the color-icon field, and print it -static void SetEngineColorIcon( int which ) -{ - char color = GetEngineColor(which); - int nicon = 0; - - if( color == ENGINE_COLOR_BLACK ) - nicon = nColorBlack; - else if( color == ENGINE_COLOR_WHITE ) - nicon = nColorWhite; - else - nicon = nColorUnknown; - - SetIcon( which, nColorIcon, nicon ); -} - -#define MAX_NAME_LENGTH 32 - -// pure back end, now SetWindowText is called via wrapper DoSetWindowText -static void UpdateControls( EngineOutputData * ed ) -{ - int isPondering = FALSE; - - char s_label[MAX_NAME_LENGTH + 32]; - - char * name = ed->name; - - /* Label */ - if( name == 0 || *name == '\0' ) { - name = "?"; - } - - strncpy( s_label, name, MAX_NAME_LENGTH ); - s_label[ MAX_NAME_LENGTH-1 ] = '\0'; - -#ifdef SHOW_PONDERING - if( IsEnginePondering( ed->which ) ) { - char buf[8]; - - buf[0] = '\0'; - - if( ed->hint != 0 && *ed->hint != '\0' ) { - strncpy( buf, ed->hint, sizeof(buf) ); - buf[sizeof(buf)-1] = '\0'; - } - else if( ed->pv != 0 && *ed->pv != '\0' ) { - char * sep = strchr( ed->pv, ' ' ); - int buflen = sizeof(buf); - - if( sep != NULL ) { - buflen = sep - ed->pv + 1; - if( buflen > sizeof(buf) ) buflen = sizeof(buf); - } - - strncpy( buf, ed->pv, buflen ); - buf[ buflen-1 ] = '\0'; - } - - SetEngineState( ed->which, STATE_PONDERING, buf ); - } - else if( gameMode == TwoMachinesPlay ) { - SetEngineState( ed->which, STATE_THINKING, "" ); - } - else if( gameMode == AnalyzeMode || gameMode == AnalyzeFile - || gameMode == IcsObserving && appData.icsEngineAnalyze) { // [HGM] ICS-analyze - char buf[64]; - int time_secs = ed->time / 100; - int time_mins = time_secs / 60; - - buf[0] = '\0'; - - if( ed->an_move_index != 0 && ed->an_move_count != 0 && *ed->hint != '\0' ) { - char mov[16]; - - strncpy( mov, ed->hint, sizeof(mov) ); - mov[ sizeof(mov)-1 ] = '\0'; - - sprintf( buf, "%d/%d: %s [%02d:%02d:%02d]", ed->an_move_index, ed->an_move_count, mov, time_mins / 60, time_mins % 60, time_secs % 60 ); - } - - SetEngineState( ed->which, STATE_ANALYZING, buf ); - } - else { - SetEngineState( ed->which, STATE_IDLE, "" ); - } -#endif - - DoSetWindowText( ed->which, nLabel, s_label ); - - s_label[0] = '\0'; - - if( ed->time > 0 && ed->nodes > 0 ) { - unsigned long nps_100 = ed->nodes / ed->time; - - if( nps_100 < 100000 ) { - sprintf( s_label, _("NPS: %lu"), nps_100 * 100 ); - } - else { - sprintf( s_label, _("NPS: %.1fk"), nps_100 / 10.0 ); - } - } - - DoSetWindowText( ed->which, nLabelNPS, s_label ); - - /* Memo */ - if( ed->pv != 0 && *ed->pv != '\0' ) { - char s_nodes[24]; - char s_score[16]; - char s_time[24]; - char buf[256]; - int buflen; - int time_secs = ed->time / 100; - int time_cent = ed->time % 100; - - /* Nodes */ - if( ed->nodes < 1000000 ) { - sprintf( s_nodes, u64Display, ed->nodes ); - } - else { - sprintf( s_nodes, "%.1fM", u64ToDouble(ed->nodes) / 1000000.0 ); - } - - /* Score */ - if( ed->score > 0 ) { - sprintf( s_score, "+%.2f", ed->score / 100.0 ); - } else - sprintf( s_score, "%.2f", ed->score / 100.0 ); - - /* Time */ - sprintf( s_time, "%d:%02d.%02d", time_secs / 60, time_secs % 60, time_cent ); - - /* Put all together... */ - sprintf( buf, "%3d %s %s\t%s\t", ed->depth, s_score, s_nodes, s_time ); - - /* Add PV */ - buflen = strlen(buf); - - strncpy( buf + buflen, ed->pv, sizeof(buf) - buflen ); - - buf[ sizeof(buf) - 3 ] = '\0'; - - strcat( buf + buflen, "\n" ); - - /* Update memo */ - InsertIntoMemo( ed->which, buf ); - } - - /* Colors */ - SetEngineColorIcon( ed->which ); -} - -// back end -int EngineOutputIsUp() -{ - return engineOutputDialogUp; -} - -void -EngineOutputProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - if (engineOutputDialogUp) { - EngineOutputPopDown(); - } else { - EngineOutputPopUp(_("engine output"),_("This feature is experimental")); - } -// ToNrEvent(currentMove); -} - -// [HGM] kibitz: write kibitz line; split window for it if necessary -void OutputKibitz(int window, char *text) -{ - if(!EngineOutputIsUp()) return; - if(!opponentKibitzes) { // on first kibitz of game, clear memos - DoClearMemo(1); - if(gameMode == IcsObserving) DoClearMemo(0); - } - opponentKibitzes = TRUE; // this causes split window DisplayMode in ICS modes. - VerifyDisplayMode(); - if(gameMode == IcsObserving) { - DoSetWindowText(0, nLabel, gameInfo.white); - SetIcon( 0, nColorIcon, nColorWhite); - SetIcon( 0, nStateIcon, nClear); - } - DoSetWindowText(1, nLabel, gameMode == IcsPlayingBlack ? gameInfo.white : gameInfo.black); // opponent name - SetIcon( 1, nColorIcon, gameMode == IcsPlayingBlack ? nColorWhite : nColorBlack); - SetIcon( 1, nStateIcon, nClear); - InsertIntoMemo(window-1, text); -} +/* + * Engine output (PV) + * + * Author: Alessandro Scotti (Dec 2005) + * + * Copyright 2005 Alessandro Scotti + * + * Enhancements Copyright 2009 Free Software Foundation, Inc. + * + * ------------------------------------------------------------------------ + * + * GNU XBoard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * GNU XBoard is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + * ------------------------------------------------------------------------ + ** See the file ChangeLog for a revision history. */ + +#include "config.h" + +#include +#include +#include +#include + +#if STDC_HEADERS +# include +# include +#else /* not STDC_HEADERS */ +extern char *getenv(); +# if HAVE_STRING_H +# include +# else /* not HAVE_STRING_H */ +# include +# endif /* not HAVE_STRING_H */ +#endif /* not STDC_HEADERS */ + +#if HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "frontend.h" +#include "backend.h" +#include "xboard.h" +// Add xengineo.h later +#include "gettext.h" + +#ifdef ENABLE_NLS +# define _(s) gettext (s) +# define N_(s) gettext_noop (s) +#else +# define _(s) (s) +# define N_(s) s +#endif + +#include + +// [HGM] pixmaps of some ICONS used in the engine-outut window +#include "pixmaps/WHITE_14.xpm" +#include "pixmaps/BLACK_14.xpm" +#include "pixmaps/CLEAR_14.xpm" +#include "pixmaps/UNKNOWN_14.xpm" +#include "pixmaps/THINKING_14.xpm" +#include "pixmaps/PONDER_14.xpm" +#include "pixmaps/ANALYZING_14.xpm" + +#ifdef SNAP +#include "wsnap.h" +#endif + +#define _LL_ 100 + +// imports from xboard.c +extern Widget formWidget, shellWidget, boardWidget, menuBarWidget; +extern Display *xDisplay; +extern Window xBoardWindow; +extern int squareSize; +extern Pixmap xMarkPixmap, wIconPixmap, bIconPixmap; +extern char *layoutName; + +// temporary kludge to avoid compile errors untill all Windows code has been replaced +#define HICON int * +#define HWND int * + +// [HGM] define numbers to indicate icons, for referring to them in platform-independent way +#define nColorBlack 1 +#define nColorWhite 2 +#define nColorUnknown 3 +#define nClear 4 +#define nPondering 5 +#define nThinking 6 +#define nAnalyzing 7 + +Pixmap icons[8]; // [HGM] this front-end array translates back-end icon indicator to handle + +// [HGM] same for output fields (note that there are two of each type, one per color) +#define nColorIcon 1 +#define nStateIcon 2 +#define nLabel 3 +#define nStateData 4 +#define nLabelNPS 5 +#define nMemo 6 + +Widget outputField[2][7]; // [HGM] front-end array to translate output field to window handle + +void EngineOutputPopDown(); +void engineOutputPopUp(char *title, char *text); +int EngineOutputIsUp(); +static void SetEngineColorIcon( int which ); + +#define SHOW_PONDERING + +/* Imports from backend.c */ +char * SavePart(char *str); +extern int opponentKibitzes; + +/* Imports from winboard.c */ +//extern HWND engineOutputDialog; +extern Arg layoutArgs[2], formArgs[2], messageArgs[4]; + +//extern WindowPlacement wpEngineOutput; + +Position engineOutputX = -1, engineOutputY = -1; +Dimension engineOutputW, engineOutputH; +Widget engineOutputShell; +int engineOutputDialogUp; + +/* Module variables */ +#define H_MARGIN 2 +#define V_MARGIN 2 +#define LABEL_V_DISTANCE 1 /* Distance between label and memo */ +#define SPLITTER_SIZE 4 /* Distance between first memo and second label */ + +#define ICON_SIZE 14 + +#define STATE_UNKNOWN -1 +#define STATE_THINKING 0 +#define STATE_IDLE 1 +#define STATE_PONDERING 2 +#define STATE_ANALYZING 3 + +static int windowMode = 1; + +static int needInit = TRUE; + +static int lastDepth[2] = { -1, -1 }; +static int lastForwardMostMove[2] = { -1, -1 }; +static int engineState[2] = { -1, -1 }; + +typedef struct { + char * name; + int which; + int depth; + u64 nodes; + int score; + int time; + char * pv; + char * hint; + int an_move_index; + int an_move_count; +} EngineOutputData; + +static int VerifyDisplayMode(); +static void UpdateControls( EngineOutputData * ed ); +static SetEngineState( int which, int state, char * state_data ); + +void ReadIcon(char *pixData[], int iconNr) +{ + int r; + + if ((r=XpmCreatePixmapFromData(xDisplay, XtWindow(outputField[0][nColorIcon]), + pixData, + &(icons[iconNr]), + NULL, NULL /*&attr*/)) != 0) { + fprintf(stderr, _("Error %d loading icon image\n"), r); + exit(1); + } +} + +static void InitializeEngineOutput() +{ int i; + + ReadIcon(WHITE_14, nColorWhite); + ReadIcon(BLACK_14, nColorBlack); + ReadIcon(UNKNOWN_14, nColorUnknown); + + ReadIcon(CLEAR_14, nClear); + ReadIcon(PONDER_14, nPondering); + ReadIcon(THINK_14, nThinking); + ReadIcon(ANALYZE_14, nAnalyzing); +} + +void DoSetWindowText(int which, int field, char *s_label) +{ + Arg arg; + + XtSetArg(arg, XtNlabel, (XtArgVal) s_label); + XtSetValues(outputField[which][field], &arg, 1); +} + +static void InsertIntoMemo( int which, char * text ) +{ + Arg arg; XawTextBlock t; Widget edit; + + t.ptr = text; t.firstPos = 0; t.length = strlen(text); t.format = XawFmt8Bit; + edit = XtNameToWidget(engineOutputShell, which ? "*form2.text" : "*form.text"); + XawTextReplace(edit, 0, 0, &t); +// XtSetArg(arg, XtNstring, (XtArgVal) text); +// XtSetValues(outputField[which][nMemo], &arg, 1); +} + +static void SetIcon( int which, int field, int nIcon ) +{ + Arg arg; + + if( nIcon != 0 ) { + XtSetArg(arg, XtNleftBitmap, (XtArgVal) icons[nIcon]); + XtSetValues(outputField[which][field], &arg, 1); + } +} + +void DoClearMemo(int which) +{ + Arg args[16]; + int j; + Widget edit; + + edit = XtNameToWidget(engineOutputShell, which ? "*form2.text" : "*form.text"); + XtCallActionProc(edit, "select-all", NULL, NULL, 0); + XtCallActionProc(edit, "kill-selection", NULL, NULL, 0); +} + +// The following routines are mutated clones of the commentPopUp routines + +void PositionControlSet(which, form, bw_width) + int which; + Widget form; + Dimension bw_width; +{ + Arg args[16]; + Widget edit, NameWidget, ColorWidget, ModeWidget, MoveWidget, NodesWidget; + int j, mutable=1; + j = 0; + XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; + XtSetArg(args[j], XtNlabel, (XtArgVal) ""); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; + XtSetArg(args[j], XtNwidth, (XtArgVal) 17); j++; + outputField[which][nColorIcon] = ColorWidget = + XtCreateManagedWidget("Color", labelWidgetClass, + form, args, j); + + j = 0; + XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; + XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; + XtSetArg(args[j], XtNfromHoriz, (XtArgVal) ColorWidget); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; + XtSetArg(args[j], XtNwidth, (XtArgVal) bw_width/2 - 57); j++; + outputField[which][nLabel] = NameWidget = + XtCreateManagedWidget("Engine", labelWidgetClass, + form, args, j); + + j = 0; + XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; + XtSetArg(args[j], XtNlabel, (XtArgVal) ""); j++; + XtSetArg(args[j], XtNfromHoriz, (XtArgVal) NameWidget); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; + XtSetArg(args[j], XtNwidth, (XtArgVal) 20); j++; + outputField[which][nStateIcon] = ModeWidget = + XtCreateManagedWidget("Mode", labelWidgetClass, + form, args, j); + + j = 0; + XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; + XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; + XtSetArg(args[j], XtNlabel, (XtArgVal) ""); j++; + XtSetArg(args[j], XtNfromHoriz, (XtArgVal) ModeWidget); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; + XtSetArg(args[j], XtNwidth, (XtArgVal) bw_width/2 - 102); j++; + outputField[which][nStateData] = MoveWidget = + XtCreateManagedWidget("Move", labelWidgetClass, + form, args, j); + + j = 0; + XtSetArg(args[j], XtNborderWidth, (XtArgVal) 0); j++; + XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyRight); j++; + XtSetArg(args[j], XtNlabel, (XtArgVal) _("NPS")); j++; + XtSetArg(args[j], XtNfromHoriz, (XtArgVal) MoveWidget); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + XtSetArg(args[j], XtNheight, (XtArgVal) 16); j++; + XtSetArg(args[j], XtNwidth, (XtArgVal) 100); j++; + outputField[which][nLabelNPS] = NodesWidget = + XtCreateManagedWidget("Nodes", labelWidgetClass, + form, args, j); + + // create "text" within "form" + j = 0; + if (mutable) { + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + } + XtSetArg(args[j], XtNstring, ""); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, bw_width); j++; /*force wider than buttons*/ +#if 0 + XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++; +#else + /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */ + XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++; + XtSetArg(args[j], XtNscrollHorizontal, XawtextScrollWhenNeeded); j++; +#endif +// XtSetArg(args[j], XtNautoFill, True); j++; +// XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++; + outputField[which][nMemo] = edit = + XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j); + + j = 0; + XtSetArg(args[j], XtNfromVert, ColorWidget); j++; +// XtSetArg(args[j], XtNresizable, (XtArgVal) True); j++; + XtSetValues(edit, args, j); +} + +Widget EngineOutputCreate(name, text) + char *name, *text; +{ + Arg args[16]; + Widget shell, layout, form, form2, edit; + Dimension bw_width, bw_height; + int j; + + // get board width + j = 0; + XtSetArg(args[j], XtNwidth, &bw_width); j++; + XtSetArg(args[j], XtNheight, &bw_height); j++; + XtGetValues(boardWidget, args, j); + + // define form within layout within shell. + j = 0; + XtSetArg(args[j], XtNresizable, True); j++; + shell = + XtCreatePopupShell(name, transientShellWidgetClass, + shellWidget, args, j); + layout = + XtCreateManagedWidget(layoutName, formWidgetClass, shell, + layoutArgs, XtNumber(layoutArgs)); + // divide window vertically into two equal parts, by creating two forms + form = + XtCreateManagedWidget("form", formWidgetClass, layout, + formArgs, XtNumber(formArgs)); + form2 = + XtCreateManagedWidget("form2", formWidgetClass, layout, + formArgs, XtNumber(formArgs)); + j = 0; + XtSetArg(args[j], XtNfromVert, (XtArgVal) form); j++; + XtSetValues(form2, args, j); + // make sure width is known in advance, for better placement of child widgets + j = 0; + XtSetArg(args[j], XtNwidth, (XtArgVal) bw_width-16); j++; + XtSetArg(args[j], XtNheight, (XtArgVal) bw_height/2); j++; + XtSetValues(shell, args, j); + + // fill up both forms with control elements + PositionControlSet(0, form, bw_width); + PositionControlSet(1, form2, bw_width); + + XtRealizeWidget(shell); + + if (engineOutputX == -1) { + int xx, yy; + Window junk; + Dimension pw_height; + Dimension ew_height; +#if 0 + j = 0; + XtSetArg(args[j], XtNheight, &ew_height); j++; + XtGetValues(edit, args, j); + + j = 0; + XtSetArg(args[j], XtNheight, &pw_height); j++; + XtGetValues(shell, args, j); + engineOutputH = pw_height + (lines - 1) * ew_height; + engineOutputW = bw_width - 16; +#else + engineOutputH = bw_height/2; + engineOutputW = bw_width-16; +#endif + + XSync(xDisplay, False); +#ifdef NOTDEF + /* This code seems to tickle an X bug if it is executed too soon + after xboard starts up. The coordinates get transformed as if + the main window was positioned at (0, 0). + */ + XtTranslateCoords(shellWidget, + (bw_width - engineOutputW) / 2, 0 - engineOutputH / 2, + &engineOutputX, &engineOutputY); +#else /*!NOTDEF*/ + XTranslateCoordinates(xDisplay, XtWindow(shellWidget), + RootWindowOfScreen(XtScreen(shellWidget)), + (bw_width - engineOutputW) / 2, 0 - engineOutputH / 2, + &xx, &yy, &junk); + engineOutputX = xx; + engineOutputY = yy; +#endif /*!NOTDEF*/ + if (engineOutputY < 0) engineOutputY = 0; /*avoid positioning top offscreen*/ + } + j = 0; + XtSetArg(args[j], XtNheight, engineOutputH); j++; + XtSetArg(args[j], XtNwidth, engineOutputW); j++; + XtSetArg(args[j], XtNx, engineOutputX); j++; + XtSetArg(args[j], XtNy, engineOutputY); j++; + XtSetValues(shell, args, j); +// XtSetKeyboardFocus(shell, edit); + + return shell; +} + +void ResizeWindowControls(shell, mode) + Widget shell; + int mode; +{ + Widget form1, form2; + Arg args[16]; + int j; + Dimension ew_height, tmp; + + form1 = XtNameToWidget(shell, "*form"); + form2 = XtNameToWidget(shell, "*form2"); + + j = 0; + XtSetArg(args[j], XtNheight, (XtArgVal) &ew_height); j++; + XtGetValues(form1, args, j); + j = 0; + XtSetArg(args[j], XtNheight, (XtArgVal) &tmp); j++; + XtGetValues(form2, args, j); + ew_height += tmp; // total height + + if(mode==0) { + j = 0; + XtSetArg(args[j], XtNheight, (XtArgVal) 5); j++; + XtSetValues(form2, args, j); + j = 0; + XtSetArg(args[j], XtNheight, (XtArgVal) (ew_height-5)); j++; + XtSetValues(form1, args, j); + } else { + j = 0; + XtSetArg(args[j], XtNheight, (XtArgVal) (ew_height/2)); j++; + XtSetValues(form1, args, j); + j = 0; + XtSetArg(args[j], XtNheight, (XtArgVal) (ew_height/2)); j++; + XtSetValues(form2, args, j); + } +} + +void EngineOutputPopUp(title, text) + char *title, *text; +{ + Arg args[16]; + int j; + Widget edit; + + if (engineOutputShell == NULL) { + engineOutputShell = + EngineOutputCreate(title, text); + XtRealizeWidget(engineOutputShell); + CatchDeleteWindow(engineOutputShell, "EngineOutputPopDown"); + if( needInit ) { + InitializeEngineOutput(); + needInit = FALSE; + } + SetEngineColorIcon( 0 ); + SetEngineColorIcon( 1 ); + SetEngineState( 0, STATE_IDLE, "" ); + SetEngineState( 1, STATE_IDLE, "" ); + } else { + edit = XtNameToWidget(engineOutputShell, "*form.text"); + j = 0; + XtSetArg(args[j], XtNstring, text); j++; + XtSetValues(edit, args, j); + j = 0; + XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++; + XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++; + XtSetValues(engineOutputShell, args, j); + } + + XtPopup(engineOutputShell, XtGrabNone); + XSync(xDisplay, False); + + j=0; + XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++; + XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Engine Output"), + args, j); + + engineOutputDialogUp = True; + ShowThinkingEvent(); // [HGM] thinking: might need to prompt engine for thinking output +} + +void EngineOutputPopDown() +{ + Arg args[16]; + int j; + + if (!engineOutputDialogUp) return; + DoClearMemo(1); + j = 0; + XtSetArg(args[j], XtNx, &engineOutputX); j++; + XtSetArg(args[j], XtNy, &engineOutputY); j++; + XtSetArg(args[j], XtNwidth, &engineOutputW); j++; + XtSetArg(args[j], XtNheight, &engineOutputH); j++; + XtGetValues(engineOutputShell, args, j); + XtPopdown(engineOutputShell); + XSync(xDisplay, False); + j=0; + XtSetArg(args[j], XtNleftBitmap, None); j++; + XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Engine Output"), + args, j); + + engineOutputDialogUp = False; + ShowThinkingEvent(); // [HGM] thinking: might need to shut off thinking output +} + +//------------------------ pure back-end routines ------------------------------- + + +// back end, due to front-end wrapper for SetWindowText, and new SetIcon arguments +static SetEngineState( int which, int state, char * state_data ) +{ + int x_which = 1 - which; + + if( engineState[ which ] != state ) { + engineState[ which ] = state; + + switch( state ) { + case STATE_THINKING: + SetIcon( which, nStateIcon, nThinking ); + if( engineState[ x_which ] == STATE_THINKING ) { + SetEngineState( x_which, STATE_IDLE, "" ); + } + break; + case STATE_PONDERING: + SetIcon( which, nStateIcon, nPondering ); + break; + case STATE_ANALYZING: + SetIcon( which, nStateIcon, nAnalyzing ); + break; + default: + SetIcon( which, nStateIcon, nClear ); + break; + } + } + + if( state_data != 0 ) { + DoSetWindowText( which, nStateData, state_data ); + } +} + +// back end, now the front-end wrapper ClearMemo is used, and ed no longer contains handles. +void EngineOutputUpdate( FrontEndProgramStats * stats ) +{ + EngineOutputData ed; + int clearMemo = FALSE; + int which; + int depth; + + if( stats == 0 ) { + SetEngineState( 0, STATE_IDLE, "" ); + SetEngineState( 1, STATE_IDLE, "" ); + return; + } + + if(gameMode == IcsObserving && !appData.icsEngineAnalyze) + return; // [HGM] kibitz: shut up engine if we are observing an ICS game + + which = stats->which; + depth = stats->depth; + + if( which < 0 || which > 1 || depth < 0 || stats->time < 0 || stats->pv == 0 ) { + return; + } + + if( engineOutputShell == NULL ) { + return; + } + + VerifyDisplayMode(); + + ed.which = which; + ed.depth = depth; + ed.nodes = stats->nodes; + ed.score = stats->score; + ed.time = stats->time; + ed.pv = stats->pv; + ed.hint = stats->hint; + ed.an_move_index = stats->an_move_index; + ed.an_move_count = stats->an_move_count; + + /* Get target control. [HGM] this is moved to front end, which get them from a table */ + if( which == 0 ) { + ed.name = first.tidy; + } + else { + ed.name = second.tidy; + } + + /* Clear memo if needed */ + if( lastDepth[which] > depth || (lastDepth[which] == depth && depth <= 1) ) { + clearMemo = TRUE; + } + + if( lastForwardMostMove[which] != forwardMostMove ) { + clearMemo = TRUE; + } + + if( clearMemo ) DoClearMemo(which); + + /* Update */ + lastDepth[which] = depth; + lastForwardMostMove[which] = forwardMostMove; + + if( ed.pv != 0 && ed.pv[0] == ' ' ) { + if( strncmp( ed.pv, " no PV", 6 ) == 0 ) { /* Hack on hack! :-O */ + ed.pv = ""; + } + } + + UpdateControls( &ed ); +} + +#define ENGINE_COLOR_WHITE 'w' +#define ENGINE_COLOR_BLACK 'b' +#define ENGINE_COLOR_UNKNOWN ' ' + +// pure back end +char GetEngineColor( int which ) +{ + char result = ENGINE_COLOR_UNKNOWN; + + if( which == 0 || which == 1 ) { + ChessProgramState * cps; + + switch (gameMode) { + case MachinePlaysBlack: + case IcsPlayingBlack: + result = ENGINE_COLOR_BLACK; + break; + case MachinePlaysWhite: + case IcsPlayingWhite: + result = ENGINE_COLOR_WHITE; + break; + case AnalyzeMode: + case AnalyzeFile: + result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK; + break; + case TwoMachinesPlay: + cps = (which == 0) ? &first : &second; + result = cps->twoMachinesColor[0]; + result = result == 'w' ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK; + break; + } + } + + return result; +} + +// pure back end +char GetActiveEngineColor() +{ + char result = ENGINE_COLOR_UNKNOWN; + + if( gameMode == TwoMachinesPlay ) { + result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK; + } + + return result; +} + +// pure back end +static int IsEnginePondering( int which ) +{ + int result = FALSE; + + switch (gameMode) { + case MachinePlaysBlack: + case IcsPlayingBlack: + if( WhiteOnMove(forwardMostMove) ) result = TRUE; + break; + case MachinePlaysWhite: + case IcsPlayingWhite: + if( ! WhiteOnMove(forwardMostMove) ) result = TRUE; + break; + case TwoMachinesPlay: + if( GetActiveEngineColor() != ENGINE_COLOR_UNKNOWN ) { + if( GetEngineColor( which ) != GetActiveEngineColor() ) result = TRUE; + } + break; + } + + return result; +} + +// back end +static void SetDisplayMode( int mode ) +{ + if( windowMode != mode ) { + windowMode = mode; + + ResizeWindowControls( engineOutputShell, mode ); + } +} + +// pure back end +int VerifyDisplayMode() +{ + int mode; + + /* Get proper mode for current game */ + switch( gameMode ) { + case IcsObserving: // [HGM] ICS analyze + if(!appData.icsEngineAnalyze) return; + case AnalyzeMode: + case AnalyzeFile: + case MachinePlaysWhite: + case MachinePlaysBlack: + mode = 0; + break; + case IcsPlayingWhite: + case IcsPlayingBlack: + mode = appData.zippyPlay && opponentKibitzes; // [HGM] kibitz + break; + case TwoMachinesPlay: + mode = 1; + break; + default: + /* Do not change */ + return; + } + + SetDisplayMode( mode ); +} + +// back end. Determine what icon to se in the color-icon field, and print it +static void SetEngineColorIcon( int which ) +{ + char color = GetEngineColor(which); + int nicon = 0; + + if( color == ENGINE_COLOR_BLACK ) + nicon = nColorBlack; + else if( color == ENGINE_COLOR_WHITE ) + nicon = nColorWhite; + else + nicon = nColorUnknown; + + SetIcon( which, nColorIcon, nicon ); +} + +#define MAX_NAME_LENGTH 32 + +// pure back end, now SetWindowText is called via wrapper DoSetWindowText +static void UpdateControls( EngineOutputData * ed ) +{ + int isPondering = FALSE; + + char s_label[MAX_NAME_LENGTH + 32]; + + char * name = ed->name; + + /* Label */ + if( name == 0 || *name == '\0' ) { + name = "?"; + } + + strncpy( s_label, name, MAX_NAME_LENGTH ); + s_label[ MAX_NAME_LENGTH-1 ] = '\0'; + +#ifdef SHOW_PONDERING + if( IsEnginePondering( ed->which ) ) { + char buf[8]; + + buf[0] = '\0'; + + if( ed->hint != 0 && *ed->hint != '\0' ) { + strncpy( buf, ed->hint, sizeof(buf) ); + buf[sizeof(buf)-1] = '\0'; + } + else if( ed->pv != 0 && *ed->pv != '\0' ) { + char * sep = strchr( ed->pv, ' ' ); + int buflen = sizeof(buf); + + if( sep != NULL ) { + buflen = sep - ed->pv + 1; + if( buflen > sizeof(buf) ) buflen = sizeof(buf); + } + + strncpy( buf, ed->pv, buflen ); + buf[ buflen-1 ] = '\0'; + } + + SetEngineState( ed->which, STATE_PONDERING, buf ); + } + else if( gameMode == TwoMachinesPlay ) { + SetEngineState( ed->which, STATE_THINKING, "" ); + } + else if( gameMode == AnalyzeMode || gameMode == AnalyzeFile + || gameMode == IcsObserving && appData.icsEngineAnalyze) { // [HGM] ICS-analyze + char buf[64]; + int time_secs = ed->time / 100; + int time_mins = time_secs / 60; + + buf[0] = '\0'; + + if( ed->an_move_index != 0 && ed->an_move_count != 0 && *ed->hint != '\0' ) { + char mov[16]; + + strncpy( mov, ed->hint, sizeof(mov) ); + mov[ sizeof(mov)-1 ] = '\0'; + + sprintf( buf, "%d/%d: %s [%02d:%02d:%02d]", ed->an_move_index, ed->an_move_count, mov, time_mins / 60, time_mins % 60, time_secs % 60 ); + } + + SetEngineState( ed->which, STATE_ANALYZING, buf ); + } + else { + SetEngineState( ed->which, STATE_IDLE, "" ); + } +#endif + + DoSetWindowText( ed->which, nLabel, s_label ); + + s_label[0] = '\0'; + + if( ed->time > 0 && ed->nodes > 0 ) { + unsigned long nps_100 = ed->nodes / ed->time; + + if( nps_100 < 100000 ) { + sprintf( s_label, _("NPS: %lu"), nps_100 * 100 ); + } + else { + sprintf( s_label, _("NPS: %.1fk"), nps_100 / 10.0 ); + } + } + + DoSetWindowText( ed->which, nLabelNPS, s_label ); + + /* Memo */ + if( ed->pv != 0 && *ed->pv != '\0' ) { + char s_nodes[24]; + char s_score[16]; + char s_time[24]; + char buf[256]; + int buflen; + int time_secs = ed->time / 100; + int time_cent = ed->time % 100; + + /* Nodes */ + if( ed->nodes < 1000000 ) { + sprintf( s_nodes, u64Display, ed->nodes ); + } + else { + sprintf( s_nodes, "%.1fM", u64ToDouble(ed->nodes) / 1000000.0 ); + } + + /* Score */ + if( ed->score > 0 ) { + sprintf( s_score, "+%.2f", ed->score / 100.0 ); + } else + sprintf( s_score, "%.2f", ed->score / 100.0 ); + + /* Time */ + sprintf( s_time, "%d:%02d.%02d", time_secs / 60, time_secs % 60, time_cent ); + + /* Put all together... */ + sprintf( buf, "%3d %s %s\t%s\t", ed->depth, s_score, s_nodes, s_time ); + + /* Add PV */ + buflen = strlen(buf); + + strncpy( buf + buflen, ed->pv, sizeof(buf) - buflen ); + + buf[ sizeof(buf) - 3 ] = '\0'; + + strcat( buf + buflen, "\n" ); + + /* Update memo */ + InsertIntoMemo( ed->which, buf ); + } + + /* Colors */ + SetEngineColorIcon( ed->which ); +} + +// back end +int EngineOutputIsUp() +{ + return engineOutputDialogUp; +} + +void +EngineOutputProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + if (engineOutputDialogUp) { + EngineOutputPopDown(); + } else { + EngineOutputPopUp(_("engine output"),_("This feature is experimental")); + } +// ToNrEvent(currentMove); +} + +// [HGM] kibitz: write kibitz line; split window for it if necessary +void OutputKibitz(int window, char *text) +{ + if(!EngineOutputIsUp()) return; + if(!opponentKibitzes) { // on first kibitz of game, clear memos + DoClearMemo(1); + if(gameMode == IcsObserving) DoClearMemo(0); + } + opponentKibitzes = TRUE; // this causes split window DisplayMode in ICS modes. + VerifyDisplayMode(); + if(gameMode == IcsObserving) { + DoSetWindowText(0, nLabel, gameInfo.white); + SetIcon( 0, nColorIcon, nColorWhite); + SetIcon( 0, nStateIcon, nClear); + } + DoSetWindowText(1, nLabel, gameMode == IcsPlayingBlack ? gameInfo.white : gameInfo.black); // opponent name + SetIcon( 1, nColorIcon, gameMode == IcsPlayingBlack ? nColorWhite : nColorBlack); + SetIcon( 1, nStateIcon, nClear); + InsertIntoMemo(window-1, text); +} diff --git a/xoptions.c b/xoptions.c index 04924c7..22737c1 100644 --- a/xoptions.c +++ b/xoptions.c @@ -1,1728 +1,1728 @@ -/* - * xoptions.c -- Move list window, part of X front end for XBoard - * - * Copyright 2000,2009 Free Software Foundation, Inc. - * ------------------------------------------------------------------------ - * - * GNU XBoard is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * GNU XBoard is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. * - * - *------------------------------------------------------------------------ - ** See the file ChangeLog for a revision history. */ - -// [HGM] this file is the counterpart of woptions.c, containing xboard popup menus -// similar to those of WinBoard, to set the most common options interactively. - -#include "config.h" - -#include -#include -#include -#include - -#if STDC_HEADERS -# include -# include -#else /* not STDC_HEADERS */ -extern char *getenv(); -# if HAVE_STRING_H -# include -# else /* not HAVE_STRING_H */ -# include -# endif /* not HAVE_STRING_H */ -#endif /* not STDC_HEADERS */ - -#if HAVE_UNISTD_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "backend.h" -#include "xboard.h" -#include "gettext.h" - -#ifdef ENABLE_NLS -# define _(s) gettext (s) -# define N_(s) gettext_noop (s) -#else -# define _(s) (s) -# define N_(s) s -#endif - -extern Widget formWidget, shellWidget, boardWidget, menuBarWidget; -extern Display *xDisplay; -extern int squareSize; -extern Pixmap xMarkPixmap; -extern char *layoutName; -extern Window xBoardWindow; -extern Arg layoutArgs[2], formArgs[2]; -Pixel timerForegroundPixel, timerBackgroundPixel; - -// [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines - -static Widget previous = NULL; - -void SetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b) -{ - Arg args; - - if(previous) { - XtSetArg(args, XtNdisplayCaret, False); - XtSetValues(previous, &args, 1); - } - XtSetArg(args, XtNdisplayCaret, True); - XtSetValues(w, &args, 1); - XtSetKeyboardFocus((Widget) data, w); - previous = w; -} - -//--------------------------- New Shuffle Game -------------------------------------------- -extern int shuffleOpenings; -extern int startedFromPositionFile; -int shuffleUp; -Widget shuffleShell; - -void ShufflePopDown() -{ - if (!shuffleUp) return; - XtPopdown(shuffleShell); - XtDestroyWidget(shuffleShell); - shuffleUp = False; - ModeHighlight(); -} - -void ShuffleCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name; - Widget w2; - Arg args[16]; - char buf[80]; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _("cancel")) == 0) { - ShufflePopDown(); - return; - } - if (strcmp(name, _("off")) == 0) { - ShufflePopDown(); - shuffleOpenings = False; // [HGM] should be moved to New Variant menu, once we have it! - ResetGameEvent(); - AnalysisPopDown(); - return; - } - if (strcmp(name, _("random")) == 0) { - sprintf(buf, "%d", rand()); - XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value - XtSetValues(XtParent(w), args, 1); - return; - } - if (strcmp(name, _("ok")) == 0) { - int nr; String name; - name = XawDialogGetValueString(w2 = XtParent(w)); - if(sscanf(name ,"%d",&nr) != 1) { - sprintf(buf, "%d", appData.defaultFrcPosition); - XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value - XtSetValues(w2, args, 1); - return; - } - appData.defaultFrcPosition = nr; - shuffleOpenings = True; - ShufflePopDown(); - ResetGameEvent(); - AnalysisPopDown(); - return; - } -} - -void ShufflePopUp() -{ - Arg args[16]; - Widget popup, layout, dialog, edit; - Window root, child; - int x, y, i; - int win_x, win_y; - unsigned int mask; - char def[80]; - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; - XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++; - shuffleShell = popup = - XtCreatePopupShell(_("New Shuffle Game"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - sprintf(def, "%d\n", appData.defaultFrcPosition); - i = 0; - XtSetArg(args[i], XtNlabel, _("Start-position number:")); i++; - XtSetArg(args[i], XtNvalue, def); i++; - XtSetArg(args[i], XtNborderWidth, 0); i++; - dialog = XtCreateManagedWidget(_("Shuffle"), dialogWidgetClass, - layout, args, i); - -// XtSetArg(args[0], XtNeditType, XawtextEdit); // [HGM] can't get edit to work decently -// XtSetArg(args[1], XtNuseStringInPlace, False); -// XtSetValues(dialog, args, 2); - - XawDialogAddButton(dialog, _("ok"), ShuffleCallback, (XtPointer) dialog); - XawDialogAddButton(dialog, _("cancel"), ShuffleCallback, (XtPointer) dialog); - XawDialogAddButton(dialog, _("random"), ShuffleCallback, (XtPointer) dialog); - XawDialogAddButton(dialog, _("off"), ShuffleCallback, (XtPointer) dialog); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "ShufflePopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - shuffleUp = True; - - edit = XtNameToWidget(dialog, "*value"); - - XtSetKeyboardFocus(popup, edit); -} - -void ShuffleMenuProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ -// if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) { -// Reset(FALSE, TRUE); -// } - ShufflePopUp(); -} - -//--------------------------- Time-Control Menu Popup ---------------------------------- -int TimeControlUp; -Widget TimeControlShell; -int tcInc; -Widget tcMess1, tcMess2, tcData, tcTime, tcOdds1, tcOdds2; -int tcIncrement, tcMoves; - -void TimeControlPopDown() -{ - if (!TimeControlUp) return; - XtPopdown(TimeControlShell); - XtDestroyWidget(TimeControlShell); - TimeControlUp = False; - ModeHighlight(); -} - -void TimeControlCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name, txt; - Widget w2; - Arg args[16]; - char buf[80]; - int j; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _("classical")) == 0) { - if(!tcInc) return; - j=0; - XtSetArg(args[j], XtNlabel, _("minutes for each")); j++; - XtSetValues(tcMess1, args, j); - j=0; - XtSetArg(args[j], XtNlabel, _("moves")); j++; - XtSetValues(tcMess2, args, j); - j=0; - XtSetArg(args[j], XtNstring, &name); j++; - XtGetValues(tcData, args, j); - tcIncrement = 0; sscanf(name, "%d", &tcIncrement); - sprintf(buf, "%d", tcMoves); - j=0; - XtSetArg(args[j], XtNstring, buf); j++; - XtSetValues(tcData, args, j); - tcInc = False; - return; - } - if (strcmp(name, _("incremental")) == 0) { - if(tcInc) return; - j=0; - XtSetArg(args[j], XtNlabel, _("minutes, plus")); j++; - XtSetValues(tcMess1, args, j); - j=0; - XtSetArg(args[j], XtNlabel, _("sec/move")); j++; - XtSetValues(tcMess2, args, j); - j=0; - XtSetArg(args[j], XtNstring, &name); j++; - XtGetValues(tcData, args, j); - tcMoves = appData.movesPerSession; sscanf(name, "%d", &tcMoves); - sprintf(buf, "%d", tcIncrement); - j=0; - XtSetArg(args[j], XtNstring, buf); j++; - XtSetValues(tcData, args, j); - tcInc = True; - return; - } - if (strcmp(name, _(" OK ")) == 0) { - int inc, mps, tc, ok; - XtSetArg(args[0], XtNstring, &txt); - XtGetValues(tcData, args, 1); - if(tcInc) { - ok = sscanf(txt, "%d", &inc); mps = 0; - if(!ok && txt[0] == 0) { inc = 0; ok = 1; } // accept empty string as zero - ok &= (inc >= 0); - } else { - ok = sscanf(txt, "%d", &mps); inc = -1; - ok &= (mps > 0); - } - if(ok != 1) { - XtSetArg(args[0], XtNstring, ""); // erase any offending input - XtSetValues(tcData, args, 1); - return; - } - XtSetArg(args[0], XtNstring, &txt); - XtGetValues(tcTime, args, 1); - if(!ParseTimeControl(txt, inc, mps)) { - XtSetArg(args[0], XtNstring, ""); // erase any offending input - XtSetValues(tcTime, args, 1); - DisplayError(_("Bad Time-Control String"), 0); - return; - } - appData.movesPerSession = mps; - appData.timeIncrement = inc; - appData.timeControl = strdup(txt); - XtSetArg(args[0], XtNstring, &txt); - XtGetValues(tcOdds1, args, 1); - appData.firstTimeOdds = first.timeOdds - = (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1; - XtGetValues(tcOdds2, args, 1); - appData.secondTimeOdds = second.timeOdds - = (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1; - - Reset(True, True); - TimeControlPopDown(); - return; - } -} - -void TimeControlPopUp() -{ - Arg args[16]; - Widget popup, layout, form, edit, b_ok, b_cancel, b_clas, b_inc, mess; - Window root, child; - int x, y, i, j; - int win_x, win_y; - unsigned int mask; - char def[80]; - - tcInc = (appData.timeIncrement >= 0); - tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement; - if(!tcInc) tcIncrement = 0; - sprintf(def, "%d", tcInc ? tcIncrement : tcMoves); - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; -// XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++; - TimeControlShell = popup = - XtCreatePopupShell(_("TimeControl Menu"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - form = - XtCreateManagedWidget(layoutName, formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - - j = 0; -// XtSetArg(args[j], XtNwidth, (XtArgVal) 300); j++; -// XtSetArg(args[j], XtNheight, (XtArgVal) 85); j++; - XtSetValues(popup, args, j); - - j= 0; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNstring, appData.timeControl); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, 85); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - tcTime = XtCreateManagedWidget("TC", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(tcTime, ButtonPressMask, False, SetFocus, (XtPointer) popup); - - j= 0; - XtSetArg(args[j], XtNlabel, tcInc ? _(" minutes, plus ") : _("minutes for each")); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNfromHoriz, tcTime); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - // XtSetArg(args[j], XtNwidth, 100); j++; - // XtSetArg(args[j], XtNheight, 20); j++; - tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j); - - j= 0; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNfromHoriz, tcMess1); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNstring, def); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, 40); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - tcData = XtCreateManagedWidget("MPS", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(tcData, ButtonPressMask, False, SetFocus, (XtPointer) popup); - - j= 0; - XtSetArg(args[j], XtNlabel, tcInc ? _("sec/move") : _("moves ")); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNfromHoriz, tcData); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; -// XtSetArg(args[j], XtNwidth, 80); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, - form, args, j); - - j= 0; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNfromVert, tcTime); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNstring, "1"); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, 40); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - tcOdds1 = XtCreateManagedWidget("Odds1", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(tcOdds1, ButtonPressMask, False, SetFocus, (XtPointer) popup); - - j= 0; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNfromVert, tcTime); j++; - XtSetArg(args[j], XtNfromHoriz, tcOdds1); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNstring, "1"); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, 40); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - tcOdds2 = XtCreateManagedWidget("Odds2", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(tcOdds2, ButtonPressMask, False, SetFocus, (XtPointer) popup); - - j= 0; - XtSetArg(args[j], XtNlabel, _("Engine #1 and #2 Time-Odds Factors")); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNfromVert, tcTime); j++; - XtSetArg(args[j], XtNfromHoriz, tcOdds2); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; -// XtSetArg(args[j], XtNwidth, 200); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - mess = XtCreateManagedWidget("Oddstext", labelWidgetClass, - form, args, j); - j=0; - XtSetArg(args[j], XtNfromVert, tcOdds1); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - b_clas= XtCreateManagedWidget(_("classical"), commandWidgetClass, - form, args, j); - XtAddCallback(b_clas, XtNcallback, TimeControlCallback, (XtPointer) 0); - - j=0; - XtSetArg(args[j], XtNfromVert, tcOdds1); j++; - XtSetArg(args[j], XtNfromHoriz, b_clas); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - b_inc = XtCreateManagedWidget(_("incremental"), commandWidgetClass, - form, args, j); - XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0); - - j=0; - XtSetArg(args[j], XtNfromVert, tcOdds1); j++; - XtSetArg(args[j], XtNfromHoriz, tcData); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - b_ok= XtCreateManagedWidget(_(" OK "), commandWidgetClass, - form, args, j); - XtAddCallback(b_ok, XtNcallback, TimeControlCallback, (XtPointer) 0); - - j=0; - XtSetArg(args[j], XtNfromVert, tcOdds1); j++; - XtSetArg(args[j], XtNfromHoriz, b_ok); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - b_cancel= XtCreateManagedWidget(_("cancel"), commandWidgetClass, - form, args, j); - XtAddCallback(b_cancel, XtNcallback, TimeControlPopDown, (XtPointer) 0); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "TimeControlPopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - TimeControlUp = True; - - previous = NULL; - SetFocus(tcTime, popup, (XEvent*) NULL, False); -// XtSetKeyboardFocus(popup, tcTime); -} - -void TimeControlProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - TimeControlPopUp(); -} - -//--------------------------- Engine-Options Menu Popup ---------------------------------- -int EngineUp; -Widget EngineShell; -extern int adjudicateLossThreshold; - -Widget engDrawMoves, engThreshold, engRule, engRepeat; - -void EnginePopDown() -{ - if (!EngineUp) return; - XtPopdown(EngineShell); - XtDestroyWidget(EngineShell); - EngineUp = False; - ModeHighlight(); -} - -int ReadToggle(Widget w) -{ - Arg args; Boolean res; - - XtSetArg(args, XtNstate, &res); - XtGetValues(w, &args, 1); - - return res; -} - -Widget w1, w2, w3, w4, w5, w6, w7, w8; - -void EngineCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name; - Widget s2; - Arg args[16]; - char buf[80]; - int j; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _("OK")) == 0) { - // read all switches - appData.periodicUpdates = ReadToggle(w1); -// appData.hideThinkingFromHuman = ReadToggle(w2); - appData.firstScoreIsAbsolute = ReadToggle(w3); - appData.secondScoreIsAbsolute = ReadToggle(w4); - appData.testClaims = ReadToggle(w5); - appData.checkMates = ReadToggle(w6); - appData.materialDraws = ReadToggle(w7); - appData.trivialDraws = ReadToggle(w8); - - // adjust setting in other menu for duplicates - // (perhaps duplicates should be removed from general Option Menu?) -// XtSetArg(args[0], XtNleftBitmap, appData.showThinking ? xMarkPixmap : None); -// XtSetValues(XtNameToWidget(menuBarWidget, -// "menuOptions.Show Thinking"), args, 1); - - // read out numeric controls, simply ignore bad formats for now - XtSetArg(args[0], XtNstring, &name); - XtGetValues(engDrawMoves, args, 1); - if(sscanf(name, "%d", &j) == 1) appData.adjudicateDrawMoves = j; - XtGetValues(engThreshold, args, 1); - if(sscanf(name, "%d", &j) == 1) - adjudicateLossThreshold = appData.adjudicateLossThreshold = -j; // inverted! - XtGetValues(engRule, args, 1); - if(sscanf(name, "%d", &j) == 1) appData.ruleMoves = j; - XtGetValues(engRepeat, args, 1); - if(sscanf(name, "%d", &j) == 1) appData.drawRepeats = j; - - EnginePopDown(); - ShowThinkingEvent(); // [HGM] thinking: score adjudication might need thinking output - return; - } -} - -void EnginePopUp() -{ - Arg args[16]; - Widget popup, layout, form, edit, b_ok, b_cancel, b_clas, b_inc, s1; - Window root, child; - int x, y, i, j, width; - int win_x, win_y; - unsigned int mask; - char def[80]; - - tcInc = (appData.timeIncrement >= 0); - tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement; - if(!tcInc) tcIncrement = 0; - sprintf(def, "%d", tcInc ? tcIncrement : tcMoves); - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; -// XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++; - EngineShell = popup = - XtCreatePopupShell(_("Adjudications"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - form = - XtCreateManagedWidget(layoutName, formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - - j = 0; -// XtSetArg(args[j], XtNwidth, (XtArgVal) 250); j++; -// XtSetArg(args[j], XtNheight, (XtArgVal) 400); j++; -// XtSetValues(popup, args, j); - - j = 0; -// XtSetArg(args[j], XtNwidth, (XtArgVal) 250); j++; -// XtSetArg(args[j], XtNheight, (XtArgVal) 20); j++; - XtSetArg(args[j], XtNleft, (XtArgVal) XtChainLeft); j++; - XtSetArg(args[j], XtNright, (XtArgVal) XtChainRight); j++; - XtSetArg(args[j], XtNstate, appData.periodicUpdates); j++; -// XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; - w1 = XtCreateManagedWidget(_("Periodic Updates (Analysis Mode)"), toggleWidgetClass, form, args, j); - - XtSetArg(args[j], XtNwidth, (XtArgVal) &width); - XtGetValues(w1, &args[j], 1); - -// XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w1); -// XtSetArg(args[j-3], XtNstate, appData.hideThinkingFromHuman); -// w2 = XtCreateManagedWidget(_("Hide Thinking from Human"), toggleWidgetClass, form, args, j); - - XtSetArg(args[j], XtNwidth, (XtArgVal) width); j++; - XtSetArg(args[j-2], XtNstate, appData.firstScoreIsAbsolute); - XtSetArg(args[j], XtNfromVert, (XtArgVal) w1); j++; - w3 = XtCreateManagedWidget(_("Engine #1 Score is Absolute"), toggleWidgetClass, form, args, j); - - XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w3); - XtSetArg(args[j-3], XtNstate, appData.secondScoreIsAbsolute); - w4 = XtCreateManagedWidget(_("Engine #2 Score is Absolute"), toggleWidgetClass, form, args, j); - - s1 = XtCreateManagedWidget(_("\nEngine-Engine Adjudications:"), labelWidgetClass, form, args, 3); - - XtSetArg(args[j-1], XtNfromVert, (XtArgVal) s1); - XtSetArg(args[j-3], XtNstate, appData.testClaims); - w5 = XtCreateManagedWidget(_("Verify Engine Result Claims"), toggleWidgetClass, form, args, j); - - XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w5); - XtSetArg(args[j-3], XtNstate, appData.checkMates); - w6 = XtCreateManagedWidget(_("Detect All Mates"), toggleWidgetClass, form, args, j); - - XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w6); - XtSetArg(args[j-3], XtNstate, appData.materialDraws); - w7 = XtCreateManagedWidget(_("Draw when Insuff. Mating Material"), toggleWidgetClass, form, args, j); - - XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w7); - XtSetArg(args[j-3], XtNstate, appData.trivialDraws); - w8 = XtCreateManagedWidget(_("Adjudicate Trivial Draws"), toggleWidgetClass, form, args, j); - - XtSetArg(args[0], XtNfromVert, (XtArgVal) w4); - XtSetArg(args[1], XtNborderWidth, (XtArgVal) 0); - XtSetValues(s1, args, 2); - - sprintf(def, "%d", appData.adjudicateDrawMoves); - j= 0; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNfromVert, w8); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNstring, def); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, 60); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - engDrawMoves = XtCreateManagedWidget("Length", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(engDrawMoves, ButtonPressMask, False, SetFocus, (XtPointer) popup); - - j= 0; - XtSetArg(args[j], XtNlabel, _(" moves maximum, then draw")); j++; - XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNfromVert, w8); j++; - XtSetArg(args[j], XtNfromHoriz, engDrawMoves); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; -// XtSetArg(args[j], XtNwidth, 170); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j); - - sprintf(def, "%d", -appData.adjudicateLossThreshold); // inverted! - j= 0; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNfromVert, engDrawMoves); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNstring, def); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, 60); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - engThreshold = XtCreateManagedWidget("Threshold", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(engThreshold, ButtonPressMask, False, SetFocus, (XtPointer) popup); - - j= 0; - XtSetArg(args[j], XtNlabel, _("-centiPawn lead is win")); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNfromVert, engDrawMoves); j++; - XtSetArg(args[j], XtNfromHoriz, engThreshold); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; -// XtSetArg(args[j], XtNwidth, 150); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, form, args, j); - - sprintf(def, "%d", appData.ruleMoves); - j= 0; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNfromVert, engThreshold); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNstring, def); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, 30); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - engRule = XtCreateManagedWidget("Rule", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(engRule, ButtonPressMask, False, SetFocus, (XtPointer) popup); - - j= 0; - XtSetArg(args[j], XtNlabel, _("-move rule applied")); j++; - XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNfromVert, engThreshold); j++; - XtSetArg(args[j], XtNfromHoriz, engRule); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; -// XtSetArg(args[j], XtNwidth, 130); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j); - - sprintf(def, "%d", appData.drawRepeats); - j= 0; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNfromVert, engRule); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNstring, def); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, 30); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - engRepeat = XtCreateManagedWidget("Repeats", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(engRepeat, ButtonPressMask, False, SetFocus, (XtPointer) popup); - - j= 0; - XtSetArg(args[j], XtNlabel, _("-fold repeat is draw")); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNfromVert, engRule); j++; - XtSetArg(args[j], XtNfromHoriz, engRepeat); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; -// XtSetArg(args[j], XtNwidth, 130); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, form, args, j); - - j=0; - XtSetArg(args[j], XtNfromVert, engRepeat); j++; - XtSetArg(args[j], XtNfromHoriz, tcMess2); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - b_ok= XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); - XtAddCallback(b_ok, XtNcallback, EngineCallback, (XtPointer) 0); - - j=0; - XtSetArg(args[j], XtNfromVert, engRepeat); j++; - XtSetArg(args[j], XtNfromHoriz, b_ok); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - b_cancel= XtCreateManagedWidget(_("cancel"), commandWidgetClass, - form, args, j); - XtAddCallback(b_cancel, XtNcallback, EnginePopDown, (XtPointer) 0); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "EnginePopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - EngineUp = True; - - previous = NULL; - SetFocus(engThreshold, popup, (XEvent*) NULL, False); -} - -void EngineMenuProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - EnginePopUp(); -} - -//--------------------------- New-Variant Menu PopUp ----------------------------------- -struct NewVarButton { - char *name; - char *color; - Widget handle; - VariantClass variant; -}; - -struct NewVarButton buttonDesc[] = { - {N_("normal"), "#FFFFFF", 0, VariantNormal}, - {N_("FRC"), "#FFFFFF", 0, VariantFischeRandom}, - {N_("wild castle"), "#FFFFFF", 0, VariantWildCastle}, - {N_("no castle"), "#FFFFFF", 0, VariantNoCastle}, - {N_("knightmate"), "#FFFFFF", 0, VariantKnightmate}, - {N_("berolina"), "#FFFFFF", 0, VariantBerolina}, - {N_("cylinder"), "#FFFFFF", 0, VariantCylinder}, - {N_("shatranj"), "#FFFFFF", 0, VariantShatranj}, - {N_("atomic"), "#FFFFFF", 0, VariantAtomic}, - {N_("two kings"), "#FFFFFF", 0, VariantTwoKings}, - {N_("3-checks"), "#FFFFFF", 0, Variant3Check}, - {N_("suicide"), "#FFFFBF", 0, VariantSuicide}, - {N_("give-away"), "#FFFFBF", 0, VariantGiveaway}, - {N_("losers"), "#FFFFBF", 0, VariantLosers}, - {N_("fairy"), "#BFBFBF", 0, VariantFairy}, - {N_("Superchess"), "#FFBFBF", 0, VariantSuper}, - {N_("crazyhouse"), "#FFBFBF", 0, VariantCrazyhouse}, - {N_("bughouse"), "#FFBFBF", 0, VariantBughouse}, - {N_("shogi (9x9)"), "#BFFFFF", 0, VariantShogi}, - {N_("xiangqi (9x10)"), "#BFFFFF", 0, VariantXiangqi}, - {N_("courier (12x8)"), "#BFFFBF", 0, VariantCourier}, - {N_("janus (10x8)"), "#BFBFFF", 0, VariantJanus}, - {N_("Capablanca (10x8)"), "#BFBFFF", 0, VariantCapablanca}, - {N_("CRC (10x8)"), "#BFBFFF", 0, VariantCapaRandom}, -#ifdef GOTHIC - {N_("Gothic (10x8)"), "#BFBFFF", 0, VariantGothic}, -#endif -#ifdef FALCON - {N_("Falcon (10x8)"), "#BFBFFF", 0, VariantFalcon}, -#endif - {NULL, 0, 0, (VariantClass) 0} -}; - -int NewVariantUp; -Widget NewVariantShell; - -void NewVariantPopDown() -{ - if (!NewVariantUp) return; - XtPopdown(NewVariantShell); - XtDestroyWidget(NewVariantShell); - NewVariantUp = False; - ModeHighlight(); -} - -void NewVariantCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name; - Widget w2; - Arg args[16]; - char buf[80]; - VariantClass v; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _(" OK ")) == 0) { - int nr = (int) XawToggleGetCurrent(buttonDesc[0].handle) - 1; - if(nr < 0) return; - v = buttonDesc[nr].variant; - if(!appData.noChessProgram) { - char *name = VariantName(v), buf[MSG_SIZ]; - if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) { - /* [HGM] in protocol 2 we check if variant is suported by engine */ - sprintf(buf, _("Variant %s not supported by %s"), name, first.tidy); - DisplayError(buf, 0); -// NewVariantPopDown(); - return; /* ignore OK if first engine does not support it */ - } else - if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) { - sprintf(buf, _("Warning: second engine (%s) does not support this!"), second.tidy); - DisplayError(buf, 0); /* use of second engine is optional; only warn user */ - } - } - - gameInfo.variant = v; - appData.variant = VariantName(v); - - shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */ - startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */ - appData.pieceToCharTable = NULL; - Reset(True, True); - NewVariantPopDown(); - return; - } -} - -void NewVariantPopUp() -{ - Arg args[16]; - Widget popup, layout, dialog, edit, form, last = NULL, b_ok, b_cancel; - Window root, child; - int x, y, i, j; - int win_x, win_y; - unsigned int mask; - char def[80]; - XrmValue vFrom, vTo; - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; -// XtSetArg(args[i], XtNwidth, 250); i++; -// XtSetArg(args[i], XtNheight, 300); i++; - NewVariantShell = popup = - XtCreatePopupShell(_("NewVariant Menu"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - form = - XtCreateManagedWidget("form", formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - - for(i = 0; buttonDesc[i].name != NULL; i++) { - Pixel buttonColor; - if (!appData.monoMode) { - vFrom.addr = (caddr_t) buttonDesc[i].color; - vFrom.size = strlen(buttonDesc[i].color); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - buttonColor = (Pixel) -1; - } else { - buttonColor = *(Pixel *) vTo.addr; - } - } - - j = 0; - XtSetArg(args[j], XtNradioGroup, last); j++; - XtSetArg(args[j], XtNwidth, 125); j++; -// XtSetArg(args[j], XtNheight, 16); j++; - XtSetArg(args[j], XtNfromVert, i == 15 ? NULL : last); j++; - XtSetArg(args[j], XtNfromHoriz, i < 15 ? NULL : buttonDesc[i-15].handle); j++; - XtSetArg(args[j], XtNradioData, i+1); j++; - XtSetArg(args[j], XtNbackground, buttonColor); j++; - XtSetArg(args[j], XtNstate, gameInfo.variant == buttonDesc[i].variant); j++; - buttonDesc[i].handle = last = - XtCreateManagedWidget(buttonDesc[i].name, toggleWidgetClass, form, args, j); - } - - j=0; - XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle); j++; - XtSetArg(args[j], XtNfromHoriz, buttonDesc[12].handle); j++; - XtSetArg(args[j], XtNheight, 35); j++; -// XtSetArg(args[j], XtNwidth, 60); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - b_cancel= XtCreateManagedWidget(_("CANCEL"), commandWidgetClass, form, args, j); - XtAddCallback(b_cancel, XtNcallback, NewVariantPopDown, (XtPointer) 0); - - j=0; - XtSetArg(args[j], XtNfromHoriz, b_cancel); j++; - XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle); j++; - XtSetArg(args[j], XtNheight, 35); j++; -// XtSetArg(args[j], XtNwidth, 60); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - b_ok= XtCreateManagedWidget(_(" OK "), commandWidgetClass, form, args, j); - XtAddCallback(b_ok, XtNcallback, NewVariantCallback, (XtPointer) 0); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "NewVariantPopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - NewVariantUp = True; -} - -void NewVariantProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - NewVariantPopUp(); -} - -//--------------------------- UCI Menu Popup ------------------------------------------ -int UciUp; -Widget UciShell; - -struct UciControl { - char *name; - Widget handle; - void *ptr; -}; - -struct UciControl controlDesc[] = { - {N_("maximum nr of CPUs:"), 0, &appData.smpCores}, - {N_("Polyglot Directory:"), 0, &appData.polyglotDir}, - {N_("Hash Size (MB):"), 0, &appData.defaultHashSize}, - {N_("EGTB Path:"), 0, &appData.defaultPathEGTB}, - {N_("EGTB Cache (MB):"), 0, &appData.defaultCacheSizeEGTB}, - {N_("Polyglot Book:"), 0, &appData.polyglotBook}, - {NULL, 0, NULL}, -}; - -void UciPopDown() -{ - if (!UciUp) return; - XtPopdown(UciShell); - XtDestroyWidget(UciShell); - UciUp = False; - ModeHighlight(); -} - -void UciCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name; - Arg args[16]; - char buf[80]; - int oldCores = appData.smpCores, ponder = 0; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _("OK")) == 0) { - int nr, i, j; String name; - for(i=0; i<6; i++) { - XtSetArg(args[0], XtNstring, &name); - XtGetValues(controlDesc[i].handle, args, 1); - if(i&1) { - if(name) - *(char**) controlDesc[i].ptr = strdup(name); - } else { - if(sscanf(name, "%d", &j) == 1) - *(int*) controlDesc[i].ptr = j; - } - } - XtSetArg(args[0], XtNstate, &appData.usePolyglotBook); - XtGetValues(w1, args, 1); - XtSetArg(args[0], XtNstate, &appData.firstHasOwnBookUCI); - XtGetValues(w2, args, 1); - XtSetArg(args[0], XtNstate, &appData.secondHasOwnBookUCI); - XtGetValues(w3, args, 1); - XtSetArg(args[0], XtNstate, &ponder); - XtGetValues(w4, args, 1); - - // adjust setting in other menu for duplicates - // (perhaps duplicates should be removed from general Option Menu?) - XtSetArg(args[0], XtNleftBitmap, ponder ? xMarkPixmap : None); - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Ponder Next Move"), args, 1); - - // make sure changes are sent to first engine by re-initializing it - // if it was already started pre-emptively at end of previous game - if(gameMode == BeginningOfGame) Reset(True, True); else { - // Some changed setting need immediate sending always. - PonderNextMoveEvent(ponder); - if(oldCores != appData.smpCores) - NewSettingEvent(False, "cores", appData.smpCores); - } - UciPopDown(); - return; - } -} - -void UciPopUp() -{ - Arg args[16]; - Widget popup, layout, dialog, edit, form, b_ok, b_cancel, last = NULL, new, upperLeft; - Window root, child; - int x, y, i, j; - int win_x, win_y; - unsigned int mask; - char def[80]; - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; -// XtSetArg(args[i], XtNwidth, 300); i++; - UciShell = popup = - XtCreatePopupShell(_("Engine Settings"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - - form = - XtCreateManagedWidget("form", formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - - j = 0; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; -// XtSetArg(args[j], XtNheight, 20); j++; - for(i = 0; controlDesc[i].name != NULL; i++) { - j = 3; - XtSetArg(args[j], XtNfromVert, last); j++; -// XtSetArg(args[j], XtNwidth, 130); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - new = XtCreateManagedWidget(controlDesc[i].name, labelWidgetClass, form, args, j); - if(i==0) upperLeft = new; - - j = 4; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNwidth, i&1 ? 245 : 50); j++; - if(i&1) { - XtSetArg(args[j], XtNstring, * (char**) controlDesc[i].ptr ? - * (char**) controlDesc[i].ptr : ""); j++; - } else { - sprintf(def, "%d", * (int*) controlDesc[i].ptr); - XtSetArg(args[j], XtNstring, def); j++; - } - XtSetArg(args[j], XtNfromHoriz, upperLeft); j++; - controlDesc[i].handle = last = - XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j); - XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup); - } - - j=0; - XtSetArg(args[j], XtNfromHoriz, controlDesc[0].handle); j++; - XtSetArg(args[j], XtNbottom, XtChainTop); j++; - XtSetArg(args[j], XtNtop, XtChainTop); j++; - XtSetArg(args[j], XtNleft, XtChainRight); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNstate, appData.ponderNextMove); j++; - w4 = XtCreateManagedWidget(_("Ponder"), toggleWidgetClass, form, args, j); - - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); - XtAddCallback(b_ok, XtNcallback, UciCallback, (XtPointer) 0); - - XtSetArg(args[j], XtNfromHoriz, b_ok); j++; - b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j); - XtAddCallback(b_cancel, XtNcallback, UciPopDown, (XtPointer) 0); - - j = 5; - XtSetArg(args[j], XtNfromHoriz, upperLeft); j++; - XtSetArg(args[j], XtNstate, appData.usePolyglotBook); j++; - w1 = XtCreateManagedWidget(_(" use book "), toggleWidgetClass, form, args, j); -// XtAddCallback(w1, XtNcallback, UciCallback, (XtPointer) 0); - - j = 5; - XtSetArg(args[j], XtNfromHoriz, w1); j++; - XtSetArg(args[j], XtNstate, appData.firstHasOwnBookUCI); j++; - w2 = XtCreateManagedWidget(_("own book 1"), toggleWidgetClass, form, args, j); -// XtAddCallback(w2, XtNcallback, UciCallback, (XtPointer) 0); - - j = 5; - XtSetArg(args[j], XtNfromHoriz, w2); j++; - XtSetArg(args[j], XtNstate, appData.secondHasOwnBookUCI); j++; - w3 = XtCreateManagedWidget(_("own book 2"), toggleWidgetClass, form, args, j); -// XtAddCallback(w3, XtNcallback, UciCallback, (XtPointer) 0); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "UciPopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - UciUp = True; - - previous = NULL; - SetFocus(controlDesc[2].handle, popup, (XEvent*) NULL, False); -// XtSetKeyboardFocus(popup, controlDesc[1].handle); -} - -void UciMenuProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - UciPopUp(); -} - -//--------------------------- Engine-specific options menu ---------------------------------- - -int SettingsUp; -Widget SettingsShell; -int values[MAX_OPTIONS]; -ChessProgramState *currentCps; - -void SettingsPopDown() -{ - if (!SettingsUp) return; - XtPopdown(SettingsShell); - XtDestroyWidget(SettingsShell); - SettingsUp = False; - ModeHighlight(); -} - -void SpinCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name, val; - Widget w2; - Arg args[16]; - char buf[MSG_SIZ]; - int i, j; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - j = 0; - XtSetArg(args[0], XtNstring, &val); - XtGetValues(currentCps->option[(int)client_data].handle, args, 1); - sscanf(val, "%d", &j); - if (strcmp(name, "+") == 0) { - if(++j > currentCps->option[(int)client_data].max) return; - } else - if (strcmp(name, "-") == 0) { - if(--j < currentCps->option[(int)client_data].min) return; - } else return; - sprintf(buf, "%d", j); - XtSetArg(args[0], XtNstring, buf); - XtSetValues(currentCps->option[(int)client_data].handle, args, 1); -} - -void SettingsCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name, val; - Widget w2; - Arg args[16]; - char buf[MSG_SIZ]; - int i, j; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _("cancel")) == 0) { - SettingsPopDown(); - return; - } - if (strcmp(name, _("OK")) == 0 || (int)client_data) { // save buttons imply OK - int nr; - - for(i=0; inrOptions; i++) { // send all options that had to be OK-ed to engine - switch(currentCps->option[i].type) { - case TextBox: - XtSetArg(args[0], XtNstring, &val); - XtGetValues(currentCps->option[i].handle, args, 1); - if(strcmp(currentCps->option[i].textValue, val)) { - strcpy(currentCps->option[i].textValue, val); - sprintf(buf, "option %s=%s\n", currentCps->option[i].name, val); - SendToProgram(buf, currentCps); - } - break; - case Spin: - XtSetArg(args[0], XtNstring, &val); - XtGetValues(currentCps->option[i].handle, args, 1); - sscanf(val, "%d", &j); - if(j > currentCps->option[i].max) j = currentCps->option[i].max; - if(j < currentCps->option[i].min) j = currentCps->option[i].min; - if(currentCps->option[i].value != j) { - currentCps->option[i].value = j; - sprintf(buf, "option %s=%d\n", currentCps->option[i].name, j); - SendToProgram(buf, currentCps); - } - break; - case CheckBox: - j = 0; - XtSetArg(args[0], XtNstate, &j); - XtGetValues(currentCps->option[i].handle, args, 1); - if(currentCps->option[i].value != j) { - currentCps->option[i].value = j; - sprintf(buf, "option %s=%d\n", currentCps->option[i].name, j); - SendToProgram(buf, currentCps); - } - break; - case ComboBox: - if(currentCps->option[i].value != values[i]) { - currentCps->option[i].value = values[i]; - sprintf(buf, "option %s=%s\n", currentCps->option[i].name, - ((char**)currentCps->option[i].textValue)[values[i]]); - SendToProgram(buf, currentCps); - } - break; - } - } - if((int)client_data) { // send save-button command to engine - sprintf(buf, "option %s\n", name); - SendToProgram(buf, currentCps); - } - SettingsPopDown(); - return; - } - sprintf(buf, "option %s\n", name); - SendToProgram(buf, currentCps); -} - -void ComboSelect(w, addr, index) // callback for all combo items - Widget w; - caddr_t addr; - caddr_t index; -{ - Arg args[16]; - int i = ((int)addr)>>8; - int j = 255 & (int) addr; - - values[i] = j; // store in temporary, for transfer at OK - XtSetArg(args[0], XtNlabel, ((char**)currentCps->option[i].textValue)[j]); - XtSetValues(currentCps->option[i].handle, args, 1); -} - -void CreateComboPopup(parent, name, n, mb) - Widget parent; - String name; - int n; - char *mb[]; -{ - int i=0, j; - Widget menu, entry; - Arg args[16]; - - menu = XtCreatePopupShell(name, simpleMenuWidgetClass, - parent, NULL, 0); - j = 0; - XtSetArg(args[j], XtNwidth, 100); j++; -// XtSetArg(args[j], XtNright, XtChainRight); j++; - while (mb[i] != NULL) { - entry = XtCreateManagedWidget(mb[i], smeBSBObjectClass, - menu, args, j); - XtAddCallback(entry, XtNcallback, - (XtCallbackProc) ComboSelect, - (caddr_t) (256*n+i)); - i++; - } -} - -void SettingsPopUp(ChessProgramState *cps) -{ - Arg args[16]; - Widget popup, layout, dialog, edit, form, oldform, last, b_ok, b_cancel; - Window root, child; - int x, y, i, j; - int win_x, win_y; - unsigned int mask; - char def[80], *p, *q; - - // to do: start up second engine if needed - if(!cps->initDone || !cps->nrOptions) return; // nothing to be done - currentCps = cps; - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; - SettingsShell = popup = - XtCreatePopupShell(_("Settings Menu"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - form = - XtCreateManagedWidget(layoutName, formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - last = NULL; - for(i=0; inrOptions; i++) { - switch(cps->option[i].type) { - case Spin: - sprintf(def, "%d", cps->option[i].value); - case TextBox: - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - dialog = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNfromHoriz, dialog); j++; - XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNwidth, cps->option[i].type == Spin ? 40 : 100); j++; - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - XtSetArg(args[j], XtNdisplayCaret, False); j++; - XtSetArg(args[j], XtNright, XtChainRight); j++; - XtSetArg(args[j], XtNresizable, True); j++; - XtSetArg(args[j], XtNstring, cps->option[i].type==Spin ? def : cps->option[i].textValue); j++; - edit = last; - cps->option[i].handle = (void*) - (last = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j)); - XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup); - if(cps->option[i].type == TextBox) break; - - // add increment and decrement controls for spin - j=0; - XtSetArg(args[j], XtNfromVert, edit); j++; - XtSetArg(args[j], XtNfromHoriz, last); j++; - XtSetArg(args[j], XtNheight, 10); j++; - XtSetArg(args[j], XtNwidth, 20); j++; - edit = XtCreateManagedWidget("+", commandWidgetClass, form, args, j); - XtAddCallback(edit, XtNcallback, SpinCallback, (XtPointer) i); - - j=0; - XtSetArg(args[j], XtNfromVert, edit); j++; - XtSetArg(args[j], XtNfromHoriz, last); j++; - XtSetArg(args[j], XtNheight, 10); j++; - XtSetArg(args[j], XtNwidth, 20); j++; - last = XtCreateManagedWidget("-", commandWidgetClass, form, args, j); - XtAddCallback(last, XtNcallback, SpinCallback, (XtPointer) i); - break; - case CheckBox: - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNwidth, 10); j++; - XtSetArg(args[j], XtNheight, 10); j++; - XtSetArg(args[j], XtNstate, cps->option[i].value); j++; - cps->option[i].handle = (void*) - (dialog = XtCreateManagedWidget(" ", toggleWidgetClass, form, args, j)); - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNfromHoriz, dialog); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - last = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); - break; - case SaveButton: - case Button: - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNstate, cps->option[i].value); j++; - cps->option[i].handle = (void*) - (last = XtCreateManagedWidget(cps->option[i].name, commandWidgetClass, form, args, j)); - XtAddCallback(last, XtNcallback, SettingsCallback, (XtPointer) (cps->option[i].type == SaveButton)); - break; - case ComboBox: - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; - dialog = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); - - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNfromHoriz, dialog); j++; - XtSetArg(args[j], XtNwidth, 100); j++; - XtSetArg(args[j], XtNmenuName, XtNewString(cps->option[i].name)); j++; - XtSetArg(args[j], XtNlabel, ((char**)cps->option[i].textValue)[cps->option[i].value]); j++; - cps->option[i].handle = (void*) - (last = XtCreateManagedWidget(" ", menuButtonWidgetClass, form, args, j)); - CreateComboPopup(last, cps->option[i].name, i, (char **) cps->option[i].textValue); - values[i] = cps->option[i].value; - break; - } - } - - j=0; - XtSetArg(args[j], XtNfromVert, last); j++; - XtSetArg(args[j], XtNbottom, XtChainBottom); j++; - XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; - b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); - XtAddCallback(b_ok, XtNcallback, SettingsCallback, (XtPointer) 0); - - XtSetArg(args[j], XtNfromHoriz, b_ok); j++; - b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j); - XtAddCallback(b_cancel, XtNcallback, SettingsPopDown, (XtPointer) 0); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "SettingsPopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - SettingsUp = True; - - previous = NULL; - SetFocus(edit, popup, (XEvent*) NULL, False); -} - -void FirstSettingsProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - SettingsPopUp(&first); -} - -void SecondSettingsProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - SettingsPopUp(&second); -} - -//--------------------------- General Popup for Cloning ---------------------------------- -#if 0 -int XXXUp; -Widget XXXShell; - -void XXXPopDown() -{ - if (!XXXUp) return; - XtPopdown(XXXShell); - XtDestroyWidget(XXXShell); - XXXUp = False; - ModeHighlight(); -} - -void XXXCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name; - Widget w2; - Arg args[16]; - char buf[80]; - - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); - - if (strcmp(name, _("cancel")) == 0) { - XXXPopDown(); - return; - } - if (strcmp(name, _("ok")) == 0) { - int nr; String name; - name = XawDialogGetValueString(w2 = XtParent(w)); - if(sscanf(name ,"%d",&nr) != 1) { - sprintf(buf, "%d", appData.defaultFrcPosition); - XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value - XtSetValues(w2, args, 1); - return; - } - XXXPopDown(); - return; - } -} - -void XXXPopUp() -{ - Arg args[16]; - Widget popup, layout, dialog, edit; - Window root, child; - int x, y, i; - int win_x, win_y; - unsigned int mask; - char def[80]; - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; - XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++; - XXXShell = popup = - XtCreatePopupShell(_("XXX Menu"), transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - sprintf(def, "%d\n", appData.defaultFrcPosition); - i = 0; - XtSetArg(args[i], XtNlabel, ""); i++; - XtSetArg(args[i], XtNvalue, def); i++; - XtSetArg(args[i], XtNborderWidth, 0); i++; - dialog = XtCreateManagedWidget("XXX", dialogWidgetClass, - layout, args, i); - - XawDialogAddButton(dialog, _("ok"), XXXCallback, (XtPointer) dialog); - XawDialogAddButton(dialog, _("cancel"), XXXCallback, (XtPointer) dialog); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "XXXPopDown"); - - XQueryPointer(xDisplay, xBoardWindow, &root, &child, - &x, &y, &win_x, &win_y, &mask); - - XtSetArg(args[0], XtNx, x - 10); - XtSetArg(args[1], XtNy, y - 30); - XtSetValues(popup, args, 2); - - XtPopup(popup, XtGrabExclusive); - XXXUp = True; - - edit = XtNameToWidget(dialog, "*value"); - - previous = NULL; - SetFocus(engThreshold, popup, (XEvent*) NULL, False); -} - -void XXXMenuProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - XXXPopUp(); -} -#endif - +/* + * xoptions.c -- Move list window, part of X front end for XBoard + * + * Copyright 2000,2009 Free Software Foundation, Inc. + * ------------------------------------------------------------------------ + * + * GNU XBoard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * GNU XBoard is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. * + * + *------------------------------------------------------------------------ + ** See the file ChangeLog for a revision history. */ + +// [HGM] this file is the counterpart of woptions.c, containing xboard popup menus +// similar to those of WinBoard, to set the most common options interactively. + +#include "config.h" + +#include +#include +#include +#include + +#if STDC_HEADERS +# include +# include +#else /* not STDC_HEADERS */ +extern char *getenv(); +# if HAVE_STRING_H +# include +# else /* not HAVE_STRING_H */ +# include +# endif /* not HAVE_STRING_H */ +#endif /* not STDC_HEADERS */ + +#if HAVE_UNISTD_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "backend.h" +#include "xboard.h" +#include "gettext.h" + +#ifdef ENABLE_NLS +# define _(s) gettext (s) +# define N_(s) gettext_noop (s) +#else +# define _(s) (s) +# define N_(s) s +#endif + +extern Widget formWidget, shellWidget, boardWidget, menuBarWidget; +extern Display *xDisplay; +extern int squareSize; +extern Pixmap xMarkPixmap; +extern char *layoutName; +extern Window xBoardWindow; +extern Arg layoutArgs[2], formArgs[2]; +Pixel timerForegroundPixel, timerBackgroundPixel; + +// [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines + +static Widget previous = NULL; + +void SetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b) +{ + Arg args; + + if(previous) { + XtSetArg(args, XtNdisplayCaret, False); + XtSetValues(previous, &args, 1); + } + XtSetArg(args, XtNdisplayCaret, True); + XtSetValues(w, &args, 1); + XtSetKeyboardFocus((Widget) data, w); + previous = w; +} + +//--------------------------- New Shuffle Game -------------------------------------------- +extern int shuffleOpenings; +extern int startedFromPositionFile; +int shuffleUp; +Widget shuffleShell; + +void ShufflePopDown() +{ + if (!shuffleUp) return; + XtPopdown(shuffleShell); + XtDestroyWidget(shuffleShell); + shuffleUp = False; + ModeHighlight(); +} + +void ShuffleCallback(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + String name; + Widget w2; + Arg args[16]; + char buf[80]; + + XtSetArg(args[0], XtNlabel, &name); + XtGetValues(w, args, 1); + + if (strcmp(name, _("cancel")) == 0) { + ShufflePopDown(); + return; + } + if (strcmp(name, _("off")) == 0) { + ShufflePopDown(); + shuffleOpenings = False; // [HGM] should be moved to New Variant menu, once we have it! + ResetGameEvent(); + AnalysisPopDown(); + return; + } + if (strcmp(name, _("random")) == 0) { + sprintf(buf, "%d", rand()); + XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value + XtSetValues(XtParent(w), args, 1); + return; + } + if (strcmp(name, _("ok")) == 0) { + int nr; String name; + name = XawDialogGetValueString(w2 = XtParent(w)); + if(sscanf(name ,"%d",&nr) != 1) { + sprintf(buf, "%d", appData.defaultFrcPosition); + XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value + XtSetValues(w2, args, 1); + return; + } + appData.defaultFrcPosition = nr; + shuffleOpenings = True; + ShufflePopDown(); + ResetGameEvent(); + AnalysisPopDown(); + return; + } +} + +void ShufflePopUp() +{ + Arg args[16]; + Widget popup, layout, dialog, edit; + Window root, child; + int x, y, i; + int win_x, win_y; + unsigned int mask; + char def[80]; + + i = 0; + XtSetArg(args[i], XtNresizable, True); i++; + XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++; + shuffleShell = popup = + XtCreatePopupShell(_("New Shuffle Game"), transientShellWidgetClass, + shellWidget, args, i); + + layout = + XtCreateManagedWidget(layoutName, formWidgetClass, popup, + layoutArgs, XtNumber(layoutArgs)); + + sprintf(def, "%d\n", appData.defaultFrcPosition); + i = 0; + XtSetArg(args[i], XtNlabel, _("Start-position number:")); i++; + XtSetArg(args[i], XtNvalue, def); i++; + XtSetArg(args[i], XtNborderWidth, 0); i++; + dialog = XtCreateManagedWidget(_("Shuffle"), dialogWidgetClass, + layout, args, i); + +// XtSetArg(args[0], XtNeditType, XawtextEdit); // [HGM] can't get edit to work decently +// XtSetArg(args[1], XtNuseStringInPlace, False); +// XtSetValues(dialog, args, 2); + + XawDialogAddButton(dialog, _("ok"), ShuffleCallback, (XtPointer) dialog); + XawDialogAddButton(dialog, _("cancel"), ShuffleCallback, (XtPointer) dialog); + XawDialogAddButton(dialog, _("random"), ShuffleCallback, (XtPointer) dialog); + XawDialogAddButton(dialog, _("off"), ShuffleCallback, (XtPointer) dialog); + + XtRealizeWidget(popup); + CatchDeleteWindow(popup, "ShufflePopDown"); + + XQueryPointer(xDisplay, xBoardWindow, &root, &child, + &x, &y, &win_x, &win_y, &mask); + + XtSetArg(args[0], XtNx, x - 10); + XtSetArg(args[1], XtNy, y - 30); + XtSetValues(popup, args, 2); + + XtPopup(popup, XtGrabExclusive); + shuffleUp = True; + + edit = XtNameToWidget(dialog, "*value"); + + XtSetKeyboardFocus(popup, edit); +} + +void ShuffleMenuProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ +// if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) { +// Reset(FALSE, TRUE); +// } + ShufflePopUp(); +} + +//--------------------------- Time-Control Menu Popup ---------------------------------- +int TimeControlUp; +Widget TimeControlShell; +int tcInc; +Widget tcMess1, tcMess2, tcData, tcTime, tcOdds1, tcOdds2; +int tcIncrement, tcMoves; + +void TimeControlPopDown() +{ + if (!TimeControlUp) return; + XtPopdown(TimeControlShell); + XtDestroyWidget(TimeControlShell); + TimeControlUp = False; + ModeHighlight(); +} + +void TimeControlCallback(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + String name, txt; + Widget w2; + Arg args[16]; + char buf[80]; + int j; + + XtSetArg(args[0], XtNlabel, &name); + XtGetValues(w, args, 1); + + if (strcmp(name, _("classical")) == 0) { + if(!tcInc) return; + j=0; + XtSetArg(args[j], XtNlabel, _("minutes for each")); j++; + XtSetValues(tcMess1, args, j); + j=0; + XtSetArg(args[j], XtNlabel, _("moves")); j++; + XtSetValues(tcMess2, args, j); + j=0; + XtSetArg(args[j], XtNstring, &name); j++; + XtGetValues(tcData, args, j); + tcIncrement = 0; sscanf(name, "%d", &tcIncrement); + sprintf(buf, "%d", tcMoves); + j=0; + XtSetArg(args[j], XtNstring, buf); j++; + XtSetValues(tcData, args, j); + tcInc = False; + return; + } + if (strcmp(name, _("incremental")) == 0) { + if(tcInc) return; + j=0; + XtSetArg(args[j], XtNlabel, _("minutes, plus")); j++; + XtSetValues(tcMess1, args, j); + j=0; + XtSetArg(args[j], XtNlabel, _("sec/move")); j++; + XtSetValues(tcMess2, args, j); + j=0; + XtSetArg(args[j], XtNstring, &name); j++; + XtGetValues(tcData, args, j); + tcMoves = appData.movesPerSession; sscanf(name, "%d", &tcMoves); + sprintf(buf, "%d", tcIncrement); + j=0; + XtSetArg(args[j], XtNstring, buf); j++; + XtSetValues(tcData, args, j); + tcInc = True; + return; + } + if (strcmp(name, _(" OK ")) == 0) { + int inc, mps, tc, ok; + XtSetArg(args[0], XtNstring, &txt); + XtGetValues(tcData, args, 1); + if(tcInc) { + ok = sscanf(txt, "%d", &inc); mps = 0; + if(!ok && txt[0] == 0) { inc = 0; ok = 1; } // accept empty string as zero + ok &= (inc >= 0); + } else { + ok = sscanf(txt, "%d", &mps); inc = -1; + ok &= (mps > 0); + } + if(ok != 1) { + XtSetArg(args[0], XtNstring, ""); // erase any offending input + XtSetValues(tcData, args, 1); + return; + } + XtSetArg(args[0], XtNstring, &txt); + XtGetValues(tcTime, args, 1); + if(!ParseTimeControl(txt, inc, mps)) { + XtSetArg(args[0], XtNstring, ""); // erase any offending input + XtSetValues(tcTime, args, 1); + DisplayError(_("Bad Time-Control String"), 0); + return; + } + appData.movesPerSession = mps; + appData.timeIncrement = inc; + appData.timeControl = strdup(txt); + XtSetArg(args[0], XtNstring, &txt); + XtGetValues(tcOdds1, args, 1); + appData.firstTimeOdds = first.timeOdds + = (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1; + XtGetValues(tcOdds2, args, 1); + appData.secondTimeOdds = second.timeOdds + = (sscanf(txt, "%d", &j) == 1 && j > 0) ? j : 1; + + Reset(True, True); + TimeControlPopDown(); + return; + } +} + +void TimeControlPopUp() +{ + Arg args[16]; + Widget popup, layout, form, edit, b_ok, b_cancel, b_clas, b_inc, mess; + Window root, child; + int x, y, i, j; + int win_x, win_y; + unsigned int mask; + char def[80]; + + tcInc = (appData.timeIncrement >= 0); + tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement; + if(!tcInc) tcIncrement = 0; + sprintf(def, "%d", tcInc ? tcIncrement : tcMoves); + + i = 0; + XtSetArg(args[i], XtNresizable, True); i++; +// XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++; + TimeControlShell = popup = + XtCreatePopupShell(_("TimeControl Menu"), transientShellWidgetClass, + shellWidget, args, i); + + layout = + XtCreateManagedWidget(layoutName, formWidgetClass, popup, + layoutArgs, XtNumber(layoutArgs)); + + form = + XtCreateManagedWidget(layoutName, formWidgetClass, layout, + formArgs, XtNumber(formArgs)); + + j = 0; +// XtSetArg(args[j], XtNwidth, (XtArgVal) 300); j++; +// XtSetArg(args[j], XtNheight, (XtArgVal) 85); j++; + XtSetValues(popup, args, j); + + j= 0; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNstring, appData.timeControl); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, 85); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + tcTime = XtCreateManagedWidget("TC", asciiTextWidgetClass, form, args, j); + XtAddEventHandler(tcTime, ButtonPressMask, False, SetFocus, (XtPointer) popup); + + j= 0; + XtSetArg(args[j], XtNlabel, tcInc ? _(" minutes, plus ") : _("minutes for each")); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNfromHoriz, tcTime); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + // XtSetArg(args[j], XtNwidth, 100); j++; + // XtSetArg(args[j], XtNheight, 20); j++; + tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j); + + j= 0; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNfromHoriz, tcMess1); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNstring, def); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, 40); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + tcData = XtCreateManagedWidget("MPS", asciiTextWidgetClass, form, args, j); + XtAddEventHandler(tcData, ButtonPressMask, False, SetFocus, (XtPointer) popup); + + j= 0; + XtSetArg(args[j], XtNlabel, tcInc ? _("sec/move") : _("moves ")); j++; + XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNfromHoriz, tcData); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; +// XtSetArg(args[j], XtNwidth, 80); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, + form, args, j); + + j= 0; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNfromVert, tcTime); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNstring, "1"); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, 40); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + tcOdds1 = XtCreateManagedWidget("Odds1", asciiTextWidgetClass, form, args, j); + XtAddEventHandler(tcOdds1, ButtonPressMask, False, SetFocus, (XtPointer) popup); + + j= 0; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNfromVert, tcTime); j++; + XtSetArg(args[j], XtNfromHoriz, tcOdds1); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNstring, "1"); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, 40); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + tcOdds2 = XtCreateManagedWidget("Odds2", asciiTextWidgetClass, form, args, j); + XtAddEventHandler(tcOdds2, ButtonPressMask, False, SetFocus, (XtPointer) popup); + + j= 0; + XtSetArg(args[j], XtNlabel, _("Engine #1 and #2 Time-Odds Factors")); j++; + XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNfromVert, tcTime); j++; + XtSetArg(args[j], XtNfromHoriz, tcOdds2); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; +// XtSetArg(args[j], XtNwidth, 200); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + mess = XtCreateManagedWidget("Oddstext", labelWidgetClass, + form, args, j); + j=0; + XtSetArg(args[j], XtNfromVert, tcOdds1); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + b_clas= XtCreateManagedWidget(_("classical"), commandWidgetClass, + form, args, j); + XtAddCallback(b_clas, XtNcallback, TimeControlCallback, (XtPointer) 0); + + j=0; + XtSetArg(args[j], XtNfromVert, tcOdds1); j++; + XtSetArg(args[j], XtNfromHoriz, b_clas); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + b_inc = XtCreateManagedWidget(_("incremental"), commandWidgetClass, + form, args, j); + XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0); + + j=0; + XtSetArg(args[j], XtNfromVert, tcOdds1); j++; + XtSetArg(args[j], XtNfromHoriz, tcData); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + b_ok= XtCreateManagedWidget(_(" OK "), commandWidgetClass, + form, args, j); + XtAddCallback(b_ok, XtNcallback, TimeControlCallback, (XtPointer) 0); + + j=0; + XtSetArg(args[j], XtNfromVert, tcOdds1); j++; + XtSetArg(args[j], XtNfromHoriz, b_ok); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + b_cancel= XtCreateManagedWidget(_("cancel"), commandWidgetClass, + form, args, j); + XtAddCallback(b_cancel, XtNcallback, TimeControlPopDown, (XtPointer) 0); + + XtRealizeWidget(popup); + CatchDeleteWindow(popup, "TimeControlPopDown"); + + XQueryPointer(xDisplay, xBoardWindow, &root, &child, + &x, &y, &win_x, &win_y, &mask); + + XtSetArg(args[0], XtNx, x - 10); + XtSetArg(args[1], XtNy, y - 30); + XtSetValues(popup, args, 2); + + XtPopup(popup, XtGrabExclusive); + TimeControlUp = True; + + previous = NULL; + SetFocus(tcTime, popup, (XEvent*) NULL, False); +// XtSetKeyboardFocus(popup, tcTime); +} + +void TimeControlProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + TimeControlPopUp(); +} + +//--------------------------- Engine-Options Menu Popup ---------------------------------- +int EngineUp; +Widget EngineShell; +extern int adjudicateLossThreshold; + +Widget engDrawMoves, engThreshold, engRule, engRepeat; + +void EnginePopDown() +{ + if (!EngineUp) return; + XtPopdown(EngineShell); + XtDestroyWidget(EngineShell); + EngineUp = False; + ModeHighlight(); +} + +int ReadToggle(Widget w) +{ + Arg args; Boolean res; + + XtSetArg(args, XtNstate, &res); + XtGetValues(w, &args, 1); + + return res; +} + +Widget w1, w2, w3, w4, w5, w6, w7, w8; + +void EngineCallback(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + String name; + Widget s2; + Arg args[16]; + char buf[80]; + int j; + + XtSetArg(args[0], XtNlabel, &name); + XtGetValues(w, args, 1); + + if (strcmp(name, _("OK")) == 0) { + // read all switches + appData.periodicUpdates = ReadToggle(w1); +// appData.hideThinkingFromHuman = ReadToggle(w2); + appData.firstScoreIsAbsolute = ReadToggle(w3); + appData.secondScoreIsAbsolute = ReadToggle(w4); + appData.testClaims = ReadToggle(w5); + appData.checkMates = ReadToggle(w6); + appData.materialDraws = ReadToggle(w7); + appData.trivialDraws = ReadToggle(w8); + + // adjust setting in other menu for duplicates + // (perhaps duplicates should be removed from general Option Menu?) +// XtSetArg(args[0], XtNleftBitmap, appData.showThinking ? xMarkPixmap : None); +// XtSetValues(XtNameToWidget(menuBarWidget, +// "menuOptions.Show Thinking"), args, 1); + + // read out numeric controls, simply ignore bad formats for now + XtSetArg(args[0], XtNstring, &name); + XtGetValues(engDrawMoves, args, 1); + if(sscanf(name, "%d", &j) == 1) appData.adjudicateDrawMoves = j; + XtGetValues(engThreshold, args, 1); + if(sscanf(name, "%d", &j) == 1) + adjudicateLossThreshold = appData.adjudicateLossThreshold = -j; // inverted! + XtGetValues(engRule, args, 1); + if(sscanf(name, "%d", &j) == 1) appData.ruleMoves = j; + XtGetValues(engRepeat, args, 1); + if(sscanf(name, "%d", &j) == 1) appData.drawRepeats = j; + + EnginePopDown(); + ShowThinkingEvent(); // [HGM] thinking: score adjudication might need thinking output + return; + } +} + +void EnginePopUp() +{ + Arg args[16]; + Widget popup, layout, form, edit, b_ok, b_cancel, b_clas, b_inc, s1; + Window root, child; + int x, y, i, j, width; + int win_x, win_y; + unsigned int mask; + char def[80]; + + tcInc = (appData.timeIncrement >= 0); + tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement; + if(!tcInc) tcIncrement = 0; + sprintf(def, "%d", tcInc ? tcIncrement : tcMoves); + + i = 0; + XtSetArg(args[i], XtNresizable, True); i++; +// XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++; + EngineShell = popup = + XtCreatePopupShell(_("Adjudications"), transientShellWidgetClass, + shellWidget, args, i); + + layout = + XtCreateManagedWidget(layoutName, formWidgetClass, popup, + layoutArgs, XtNumber(layoutArgs)); + + form = + XtCreateManagedWidget(layoutName, formWidgetClass, layout, + formArgs, XtNumber(formArgs)); + + j = 0; +// XtSetArg(args[j], XtNwidth, (XtArgVal) 250); j++; +// XtSetArg(args[j], XtNheight, (XtArgVal) 400); j++; +// XtSetValues(popup, args, j); + + j = 0; +// XtSetArg(args[j], XtNwidth, (XtArgVal) 250); j++; +// XtSetArg(args[j], XtNheight, (XtArgVal) 20); j++; + XtSetArg(args[j], XtNleft, (XtArgVal) XtChainLeft); j++; + XtSetArg(args[j], XtNright, (XtArgVal) XtChainRight); j++; + XtSetArg(args[j], XtNstate, appData.periodicUpdates); j++; +// XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; + w1 = XtCreateManagedWidget(_("Periodic Updates (Analysis Mode)"), toggleWidgetClass, form, args, j); + + XtSetArg(args[j], XtNwidth, (XtArgVal) &width); + XtGetValues(w1, &args[j], 1); + +// XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w1); +// XtSetArg(args[j-3], XtNstate, appData.hideThinkingFromHuman); +// w2 = XtCreateManagedWidget(_("Hide Thinking from Human"), toggleWidgetClass, form, args, j); + + XtSetArg(args[j], XtNwidth, (XtArgVal) width); j++; + XtSetArg(args[j-2], XtNstate, appData.firstScoreIsAbsolute); + XtSetArg(args[j], XtNfromVert, (XtArgVal) w1); j++; + w3 = XtCreateManagedWidget(_("Engine #1 Score is Absolute"), toggleWidgetClass, form, args, j); + + XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w3); + XtSetArg(args[j-3], XtNstate, appData.secondScoreIsAbsolute); + w4 = XtCreateManagedWidget(_("Engine #2 Score is Absolute"), toggleWidgetClass, form, args, j); + + s1 = XtCreateManagedWidget(_("\nEngine-Engine Adjudications:"), labelWidgetClass, form, args, 3); + + XtSetArg(args[j-1], XtNfromVert, (XtArgVal) s1); + XtSetArg(args[j-3], XtNstate, appData.testClaims); + w5 = XtCreateManagedWidget(_("Verify Engine Result Claims"), toggleWidgetClass, form, args, j); + + XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w5); + XtSetArg(args[j-3], XtNstate, appData.checkMates); + w6 = XtCreateManagedWidget(_("Detect All Mates"), toggleWidgetClass, form, args, j); + + XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w6); + XtSetArg(args[j-3], XtNstate, appData.materialDraws); + w7 = XtCreateManagedWidget(_("Draw when Insuff. Mating Material"), toggleWidgetClass, form, args, j); + + XtSetArg(args[j-1], XtNfromVert, (XtArgVal) w7); + XtSetArg(args[j-3], XtNstate, appData.trivialDraws); + w8 = XtCreateManagedWidget(_("Adjudicate Trivial Draws"), toggleWidgetClass, form, args, j); + + XtSetArg(args[0], XtNfromVert, (XtArgVal) w4); + XtSetArg(args[1], XtNborderWidth, (XtArgVal) 0); + XtSetValues(s1, args, 2); + + sprintf(def, "%d", appData.adjudicateDrawMoves); + j= 0; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNfromVert, w8); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNstring, def); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, 60); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + engDrawMoves = XtCreateManagedWidget("Length", asciiTextWidgetClass, form, args, j); + XtAddEventHandler(engDrawMoves, ButtonPressMask, False, SetFocus, (XtPointer) popup); + + j= 0; + XtSetArg(args[j], XtNlabel, _(" moves maximum, then draw")); j++; + XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNfromVert, w8); j++; + XtSetArg(args[j], XtNfromHoriz, engDrawMoves); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; +// XtSetArg(args[j], XtNwidth, 170); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j); + + sprintf(def, "%d", -appData.adjudicateLossThreshold); // inverted! + j= 0; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNfromVert, engDrawMoves); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNstring, def); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, 60); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + engThreshold = XtCreateManagedWidget("Threshold", asciiTextWidgetClass, form, args, j); + XtAddEventHandler(engThreshold, ButtonPressMask, False, SetFocus, (XtPointer) popup); + + j= 0; + XtSetArg(args[j], XtNlabel, _("-centiPawn lead is win")); j++; + XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNfromVert, engDrawMoves); j++; + XtSetArg(args[j], XtNfromHoriz, engThreshold); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; +// XtSetArg(args[j], XtNwidth, 150); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, form, args, j); + + sprintf(def, "%d", appData.ruleMoves); + j= 0; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNfromVert, engThreshold); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNstring, def); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, 30); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + engRule = XtCreateManagedWidget("Rule", asciiTextWidgetClass, form, args, j); + XtAddEventHandler(engRule, ButtonPressMask, False, SetFocus, (XtPointer) popup); + + j= 0; + XtSetArg(args[j], XtNlabel, _("-move rule applied")); j++; + XtSetArg(args[j], XtNjustify, (XtArgVal) XtJustifyLeft); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNfromVert, engThreshold); j++; + XtSetArg(args[j], XtNfromHoriz, engRule); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; +// XtSetArg(args[j], XtNwidth, 130); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + tcMess1 = XtCreateManagedWidget("TCtext", labelWidgetClass, form, args, j); + + sprintf(def, "%d", appData.drawRepeats); + j= 0; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNfromVert, engRule); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNstring, def); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, 30); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + engRepeat = XtCreateManagedWidget("Repeats", asciiTextWidgetClass, form, args, j); + XtAddEventHandler(engRepeat, ButtonPressMask, False, SetFocus, (XtPointer) popup); + + j= 0; + XtSetArg(args[j], XtNlabel, _("-fold repeat is draw")); j++; + XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNfromVert, engRule); j++; + XtSetArg(args[j], XtNfromHoriz, engRepeat); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; +// XtSetArg(args[j], XtNwidth, 130); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + tcMess2 = XtCreateManagedWidget("MPStext", labelWidgetClass, form, args, j); + + j=0; + XtSetArg(args[j], XtNfromVert, engRepeat); j++; + XtSetArg(args[j], XtNfromHoriz, tcMess2); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + b_ok= XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); + XtAddCallback(b_ok, XtNcallback, EngineCallback, (XtPointer) 0); + + j=0; + XtSetArg(args[j], XtNfromVert, engRepeat); j++; + XtSetArg(args[j], XtNfromHoriz, b_ok); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + b_cancel= XtCreateManagedWidget(_("cancel"), commandWidgetClass, + form, args, j); + XtAddCallback(b_cancel, XtNcallback, EnginePopDown, (XtPointer) 0); + + XtRealizeWidget(popup); + CatchDeleteWindow(popup, "EnginePopDown"); + + XQueryPointer(xDisplay, xBoardWindow, &root, &child, + &x, &y, &win_x, &win_y, &mask); + + XtSetArg(args[0], XtNx, x - 10); + XtSetArg(args[1], XtNy, y - 30); + XtSetValues(popup, args, 2); + + XtPopup(popup, XtGrabExclusive); + EngineUp = True; + + previous = NULL; + SetFocus(engThreshold, popup, (XEvent*) NULL, False); +} + +void EngineMenuProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + EnginePopUp(); +} + +//--------------------------- New-Variant Menu PopUp ----------------------------------- +struct NewVarButton { + char *name; + char *color; + Widget handle; + VariantClass variant; +}; + +struct NewVarButton buttonDesc[] = { + {N_("normal"), "#FFFFFF", 0, VariantNormal}, + {N_("FRC"), "#FFFFFF", 0, VariantFischeRandom}, + {N_("wild castle"), "#FFFFFF", 0, VariantWildCastle}, + {N_("no castle"), "#FFFFFF", 0, VariantNoCastle}, + {N_("knightmate"), "#FFFFFF", 0, VariantKnightmate}, + {N_("berolina"), "#FFFFFF", 0, VariantBerolina}, + {N_("cylinder"), "#FFFFFF", 0, VariantCylinder}, + {N_("shatranj"), "#FFFFFF", 0, VariantShatranj}, + {N_("atomic"), "#FFFFFF", 0, VariantAtomic}, + {N_("two kings"), "#FFFFFF", 0, VariantTwoKings}, + {N_("3-checks"), "#FFFFFF", 0, Variant3Check}, + {N_("suicide"), "#FFFFBF", 0, VariantSuicide}, + {N_("give-away"), "#FFFFBF", 0, VariantGiveaway}, + {N_("losers"), "#FFFFBF", 0, VariantLosers}, + {N_("fairy"), "#BFBFBF", 0, VariantFairy}, + {N_("Superchess"), "#FFBFBF", 0, VariantSuper}, + {N_("crazyhouse"), "#FFBFBF", 0, VariantCrazyhouse}, + {N_("bughouse"), "#FFBFBF", 0, VariantBughouse}, + {N_("shogi (9x9)"), "#BFFFFF", 0, VariantShogi}, + {N_("xiangqi (9x10)"), "#BFFFFF", 0, VariantXiangqi}, + {N_("courier (12x8)"), "#BFFFBF", 0, VariantCourier}, + {N_("janus (10x8)"), "#BFBFFF", 0, VariantJanus}, + {N_("Capablanca (10x8)"), "#BFBFFF", 0, VariantCapablanca}, + {N_("CRC (10x8)"), "#BFBFFF", 0, VariantCapaRandom}, +#ifdef GOTHIC + {N_("Gothic (10x8)"), "#BFBFFF", 0, VariantGothic}, +#endif +#ifdef FALCON + {N_("Falcon (10x8)"), "#BFBFFF", 0, VariantFalcon}, +#endif + {NULL, 0, 0, (VariantClass) 0} +}; + +int NewVariantUp; +Widget NewVariantShell; + +void NewVariantPopDown() +{ + if (!NewVariantUp) return; + XtPopdown(NewVariantShell); + XtDestroyWidget(NewVariantShell); + NewVariantUp = False; + ModeHighlight(); +} + +void NewVariantCallback(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + String name; + Widget w2; + Arg args[16]; + char buf[80]; + VariantClass v; + + XtSetArg(args[0], XtNlabel, &name); + XtGetValues(w, args, 1); + + if (strcmp(name, _(" OK ")) == 0) { + int nr = (int) XawToggleGetCurrent(buttonDesc[0].handle) - 1; + if(nr < 0) return; + v = buttonDesc[nr].variant; + if(!appData.noChessProgram) { + char *name = VariantName(v), buf[MSG_SIZ]; + if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) { + /* [HGM] in protocol 2 we check if variant is suported by engine */ + sprintf(buf, _("Variant %s not supported by %s"), name, first.tidy); + DisplayError(buf, 0); +// NewVariantPopDown(); + return; /* ignore OK if first engine does not support it */ + } else + if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) { + sprintf(buf, _("Warning: second engine (%s) does not support this!"), second.tidy); + DisplayError(buf, 0); /* use of second engine is optional; only warn user */ + } + } + + gameInfo.variant = v; + appData.variant = VariantName(v); + + shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */ + startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */ + appData.pieceToCharTable = NULL; + Reset(True, True); + NewVariantPopDown(); + return; + } +} + +void NewVariantPopUp() +{ + Arg args[16]; + Widget popup, layout, dialog, edit, form, last = NULL, b_ok, b_cancel; + Window root, child; + int x, y, i, j; + int win_x, win_y; + unsigned int mask; + char def[80]; + XrmValue vFrom, vTo; + + i = 0; + XtSetArg(args[i], XtNresizable, True); i++; +// XtSetArg(args[i], XtNwidth, 250); i++; +// XtSetArg(args[i], XtNheight, 300); i++; + NewVariantShell = popup = + XtCreatePopupShell(_("NewVariant Menu"), transientShellWidgetClass, + shellWidget, args, i); + + layout = + XtCreateManagedWidget(layoutName, formWidgetClass, popup, + layoutArgs, XtNumber(layoutArgs)); + + form = + XtCreateManagedWidget("form", formWidgetClass, layout, + formArgs, XtNumber(formArgs)); + + for(i = 0; buttonDesc[i].name != NULL; i++) { + Pixel buttonColor; + if (!appData.monoMode) { + vFrom.addr = (caddr_t) buttonDesc[i].color; + vFrom.size = strlen(buttonDesc[i].color); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + buttonColor = (Pixel) -1; + } else { + buttonColor = *(Pixel *) vTo.addr; + } + } + + j = 0; + XtSetArg(args[j], XtNradioGroup, last); j++; + XtSetArg(args[j], XtNwidth, 125); j++; +// XtSetArg(args[j], XtNheight, 16); j++; + XtSetArg(args[j], XtNfromVert, i == 15 ? NULL : last); j++; + XtSetArg(args[j], XtNfromHoriz, i < 15 ? NULL : buttonDesc[i-15].handle); j++; + XtSetArg(args[j], XtNradioData, i+1); j++; + XtSetArg(args[j], XtNbackground, buttonColor); j++; + XtSetArg(args[j], XtNstate, gameInfo.variant == buttonDesc[i].variant); j++; + buttonDesc[i].handle = last = + XtCreateManagedWidget(buttonDesc[i].name, toggleWidgetClass, form, args, j); + } + + j=0; + XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle); j++; + XtSetArg(args[j], XtNfromHoriz, buttonDesc[12].handle); j++; + XtSetArg(args[j], XtNheight, 35); j++; +// XtSetArg(args[j], XtNwidth, 60); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + b_cancel= XtCreateManagedWidget(_("CANCEL"), commandWidgetClass, form, args, j); + XtAddCallback(b_cancel, XtNcallback, NewVariantPopDown, (XtPointer) 0); + + j=0; + XtSetArg(args[j], XtNfromHoriz, b_cancel); j++; + XtSetArg(args[j], XtNfromVert, buttonDesc[12].handle); j++; + XtSetArg(args[j], XtNheight, 35); j++; +// XtSetArg(args[j], XtNwidth, 60); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + b_ok= XtCreateManagedWidget(_(" OK "), commandWidgetClass, form, args, j); + XtAddCallback(b_ok, XtNcallback, NewVariantCallback, (XtPointer) 0); + + XtRealizeWidget(popup); + CatchDeleteWindow(popup, "NewVariantPopDown"); + + XQueryPointer(xDisplay, xBoardWindow, &root, &child, + &x, &y, &win_x, &win_y, &mask); + + XtSetArg(args[0], XtNx, x - 10); + XtSetArg(args[1], XtNy, y - 30); + XtSetValues(popup, args, 2); + + XtPopup(popup, XtGrabExclusive); + NewVariantUp = True; +} + +void NewVariantProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + NewVariantPopUp(); +} + +//--------------------------- UCI Menu Popup ------------------------------------------ +int UciUp; +Widget UciShell; + +struct UciControl { + char *name; + Widget handle; + void *ptr; +}; + +struct UciControl controlDesc[] = { + {N_("maximum nr of CPUs:"), 0, &appData.smpCores}, + {N_("Polyglot Directory:"), 0, &appData.polyglotDir}, + {N_("Hash Size (MB):"), 0, &appData.defaultHashSize}, + {N_("EGTB Path:"), 0, &appData.defaultPathEGTB}, + {N_("EGTB Cache (MB):"), 0, &appData.defaultCacheSizeEGTB}, + {N_("Polyglot Book:"), 0, &appData.polyglotBook}, + {NULL, 0, NULL}, +}; + +void UciPopDown() +{ + if (!UciUp) return; + XtPopdown(UciShell); + XtDestroyWidget(UciShell); + UciUp = False; + ModeHighlight(); +} + +void UciCallback(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + String name; + Arg args[16]; + char buf[80]; + int oldCores = appData.smpCores, ponder = 0; + + XtSetArg(args[0], XtNlabel, &name); + XtGetValues(w, args, 1); + + if (strcmp(name, _("OK")) == 0) { + int nr, i, j; String name; + for(i=0; i<6; i++) { + XtSetArg(args[0], XtNstring, &name); + XtGetValues(controlDesc[i].handle, args, 1); + if(i&1) { + if(name) + *(char**) controlDesc[i].ptr = strdup(name); + } else { + if(sscanf(name, "%d", &j) == 1) + *(int*) controlDesc[i].ptr = j; + } + } + XtSetArg(args[0], XtNstate, &appData.usePolyglotBook); + XtGetValues(w1, args, 1); + XtSetArg(args[0], XtNstate, &appData.firstHasOwnBookUCI); + XtGetValues(w2, args, 1); + XtSetArg(args[0], XtNstate, &appData.secondHasOwnBookUCI); + XtGetValues(w3, args, 1); + XtSetArg(args[0], XtNstate, &ponder); + XtGetValues(w4, args, 1); + + // adjust setting in other menu for duplicates + // (perhaps duplicates should be removed from general Option Menu?) + XtSetArg(args[0], XtNleftBitmap, ponder ? xMarkPixmap : None); + XtSetValues(XtNameToWidget(menuBarWidget, + "menuOptions.Ponder Next Move"), args, 1); + + // make sure changes are sent to first engine by re-initializing it + // if it was already started pre-emptively at end of previous game + if(gameMode == BeginningOfGame) Reset(True, True); else { + // Some changed setting need immediate sending always. + PonderNextMoveEvent(ponder); + if(oldCores != appData.smpCores) + NewSettingEvent(False, "cores", appData.smpCores); + } + UciPopDown(); + return; + } +} + +void UciPopUp() +{ + Arg args[16]; + Widget popup, layout, dialog, edit, form, b_ok, b_cancel, last = NULL, new, upperLeft; + Window root, child; + int x, y, i, j; + int win_x, win_y; + unsigned int mask; + char def[80]; + + i = 0; + XtSetArg(args[i], XtNresizable, True); i++; +// XtSetArg(args[i], XtNwidth, 300); i++; + UciShell = popup = + XtCreatePopupShell(_("Engine Settings"), transientShellWidgetClass, + shellWidget, args, i); + + layout = + XtCreateManagedWidget(layoutName, formWidgetClass, popup, + layoutArgs, XtNumber(layoutArgs)); + + + form = + XtCreateManagedWidget("form", formWidgetClass, layout, + formArgs, XtNumber(formArgs)); + + j = 0; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; +// XtSetArg(args[j], XtNheight, 20); j++; + for(i = 0; controlDesc[i].name != NULL; i++) { + j = 3; + XtSetArg(args[j], XtNfromVert, last); j++; +// XtSetArg(args[j], XtNwidth, 130); j++; + XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + new = XtCreateManagedWidget(controlDesc[i].name, labelWidgetClass, form, args, j); + if(i==0) upperLeft = new; + + j = 4; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNwidth, i&1 ? 245 : 50); j++; + if(i&1) { + XtSetArg(args[j], XtNstring, * (char**) controlDesc[i].ptr ? + * (char**) controlDesc[i].ptr : ""); j++; + } else { + sprintf(def, "%d", * (int*) controlDesc[i].ptr); + XtSetArg(args[j], XtNstring, def); j++; + } + XtSetArg(args[j], XtNfromHoriz, upperLeft); j++; + controlDesc[i].handle = last = + XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j); + XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup); + } + + j=0; + XtSetArg(args[j], XtNfromHoriz, controlDesc[0].handle); j++; + XtSetArg(args[j], XtNbottom, XtChainTop); j++; + XtSetArg(args[j], XtNtop, XtChainTop); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + XtSetArg(args[j], XtNstate, appData.ponderNextMove); j++; + w4 = XtCreateManagedWidget(_("Ponder"), toggleWidgetClass, form, args, j); + + j=0; + XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); + XtAddCallback(b_ok, XtNcallback, UciCallback, (XtPointer) 0); + + XtSetArg(args[j], XtNfromHoriz, b_ok); j++; + b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j); + XtAddCallback(b_cancel, XtNcallback, UciPopDown, (XtPointer) 0); + + j = 5; + XtSetArg(args[j], XtNfromHoriz, upperLeft); j++; + XtSetArg(args[j], XtNstate, appData.usePolyglotBook); j++; + w1 = XtCreateManagedWidget(_(" use book "), toggleWidgetClass, form, args, j); +// XtAddCallback(w1, XtNcallback, UciCallback, (XtPointer) 0); + + j = 5; + XtSetArg(args[j], XtNfromHoriz, w1); j++; + XtSetArg(args[j], XtNstate, appData.firstHasOwnBookUCI); j++; + w2 = XtCreateManagedWidget(_("own book 1"), toggleWidgetClass, form, args, j); +// XtAddCallback(w2, XtNcallback, UciCallback, (XtPointer) 0); + + j = 5; + XtSetArg(args[j], XtNfromHoriz, w2); j++; + XtSetArg(args[j], XtNstate, appData.secondHasOwnBookUCI); j++; + w3 = XtCreateManagedWidget(_("own book 2"), toggleWidgetClass, form, args, j); +// XtAddCallback(w3, XtNcallback, UciCallback, (XtPointer) 0); + + XtRealizeWidget(popup); + CatchDeleteWindow(popup, "UciPopDown"); + + XQueryPointer(xDisplay, xBoardWindow, &root, &child, + &x, &y, &win_x, &win_y, &mask); + + XtSetArg(args[0], XtNx, x - 10); + XtSetArg(args[1], XtNy, y - 30); + XtSetValues(popup, args, 2); + + XtPopup(popup, XtGrabExclusive); + UciUp = True; + + previous = NULL; + SetFocus(controlDesc[2].handle, popup, (XEvent*) NULL, False); +// XtSetKeyboardFocus(popup, controlDesc[1].handle); +} + +void UciMenuProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + UciPopUp(); +} + +//--------------------------- Engine-specific options menu ---------------------------------- + +int SettingsUp; +Widget SettingsShell; +int values[MAX_OPTIONS]; +ChessProgramState *currentCps; + +void SettingsPopDown() +{ + if (!SettingsUp) return; + XtPopdown(SettingsShell); + XtDestroyWidget(SettingsShell); + SettingsUp = False; + ModeHighlight(); +} + +void SpinCallback(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + String name, val; + Widget w2; + Arg args[16]; + char buf[MSG_SIZ]; + int i, j; + + XtSetArg(args[0], XtNlabel, &name); + XtGetValues(w, args, 1); + + j = 0; + XtSetArg(args[0], XtNstring, &val); + XtGetValues(currentCps->option[(int)client_data].handle, args, 1); + sscanf(val, "%d", &j); + if (strcmp(name, "+") == 0) { + if(++j > currentCps->option[(int)client_data].max) return; + } else + if (strcmp(name, "-") == 0) { + if(--j < currentCps->option[(int)client_data].min) return; + } else return; + sprintf(buf, "%d", j); + XtSetArg(args[0], XtNstring, buf); + XtSetValues(currentCps->option[(int)client_data].handle, args, 1); +} + +void SettingsCallback(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + String name, val; + Widget w2; + Arg args[16]; + char buf[MSG_SIZ]; + int i, j; + + XtSetArg(args[0], XtNlabel, &name); + XtGetValues(w, args, 1); + + if (strcmp(name, _("cancel")) == 0) { + SettingsPopDown(); + return; + } + if (strcmp(name, _("OK")) == 0 || (int)client_data) { // save buttons imply OK + int nr; + + for(i=0; inrOptions; i++) { // send all options that had to be OK-ed to engine + switch(currentCps->option[i].type) { + case TextBox: + XtSetArg(args[0], XtNstring, &val); + XtGetValues(currentCps->option[i].handle, args, 1); + if(strcmp(currentCps->option[i].textValue, val)) { + strcpy(currentCps->option[i].textValue, val); + sprintf(buf, "option %s=%s\n", currentCps->option[i].name, val); + SendToProgram(buf, currentCps); + } + break; + case Spin: + XtSetArg(args[0], XtNstring, &val); + XtGetValues(currentCps->option[i].handle, args, 1); + sscanf(val, "%d", &j); + if(j > currentCps->option[i].max) j = currentCps->option[i].max; + if(j < currentCps->option[i].min) j = currentCps->option[i].min; + if(currentCps->option[i].value != j) { + currentCps->option[i].value = j; + sprintf(buf, "option %s=%d\n", currentCps->option[i].name, j); + SendToProgram(buf, currentCps); + } + break; + case CheckBox: + j = 0; + XtSetArg(args[0], XtNstate, &j); + XtGetValues(currentCps->option[i].handle, args, 1); + if(currentCps->option[i].value != j) { + currentCps->option[i].value = j; + sprintf(buf, "option %s=%d\n", currentCps->option[i].name, j); + SendToProgram(buf, currentCps); + } + break; + case ComboBox: + if(currentCps->option[i].value != values[i]) { + currentCps->option[i].value = values[i]; + sprintf(buf, "option %s=%s\n", currentCps->option[i].name, + ((char**)currentCps->option[i].textValue)[values[i]]); + SendToProgram(buf, currentCps); + } + break; + } + } + if((int)client_data) { // send save-button command to engine + sprintf(buf, "option %s\n", name); + SendToProgram(buf, currentCps); + } + SettingsPopDown(); + return; + } + sprintf(buf, "option %s\n", name); + SendToProgram(buf, currentCps); +} + +void ComboSelect(w, addr, index) // callback for all combo items + Widget w; + caddr_t addr; + caddr_t index; +{ + Arg args[16]; + int i = ((int)addr)>>8; + int j = 255 & (int) addr; + + values[i] = j; // store in temporary, for transfer at OK + XtSetArg(args[0], XtNlabel, ((char**)currentCps->option[i].textValue)[j]); + XtSetValues(currentCps->option[i].handle, args, 1); +} + +void CreateComboPopup(parent, name, n, mb) + Widget parent; + String name; + int n; + char *mb[]; +{ + int i=0, j; + Widget menu, entry; + Arg args[16]; + + menu = XtCreatePopupShell(name, simpleMenuWidgetClass, + parent, NULL, 0); + j = 0; + XtSetArg(args[j], XtNwidth, 100); j++; +// XtSetArg(args[j], XtNright, XtChainRight); j++; + while (mb[i] != NULL) { + entry = XtCreateManagedWidget(mb[i], smeBSBObjectClass, + menu, args, j); + XtAddCallback(entry, XtNcallback, + (XtCallbackProc) ComboSelect, + (caddr_t) (256*n+i)); + i++; + } +} + +void SettingsPopUp(ChessProgramState *cps) +{ + Arg args[16]; + Widget popup, layout, dialog, edit, form, oldform, last, b_ok, b_cancel; + Window root, child; + int x, y, i, j; + int win_x, win_y; + unsigned int mask; + char def[80], *p, *q; + + // to do: start up second engine if needed + if(!cps->initDone || !cps->nrOptions) return; // nothing to be done + currentCps = cps; + + i = 0; + XtSetArg(args[i], XtNresizable, True); i++; + SettingsShell = popup = + XtCreatePopupShell(_("Settings Menu"), transientShellWidgetClass, + shellWidget, args, i); + + layout = + XtCreateManagedWidget(layoutName, formWidgetClass, popup, + layoutArgs, XtNumber(layoutArgs)); + + form = + XtCreateManagedWidget(layoutName, formWidgetClass, layout, + formArgs, XtNumber(formArgs)); + last = NULL; + for(i=0; inrOptions; i++) { + switch(cps->option[i].type) { + case Spin: + sprintf(def, "%d", cps->option[i].value); + case TextBox: + j=0; + XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; + dialog = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); + j=0; + XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNfromHoriz, dialog); j++; + XtSetArg(args[j], XtNborderWidth, 1); j++; + XtSetArg(args[j], XtNwidth, cps->option[i].type == Spin ? 40 : 100); j++; + XtSetArg(args[j], XtNeditType, XawtextEdit); j++; + XtSetArg(args[j], XtNuseStringInPlace, False); j++; + XtSetArg(args[j], XtNdisplayCaret, False); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + XtSetArg(args[j], XtNresizable, True); j++; + XtSetArg(args[j], XtNstring, cps->option[i].type==Spin ? def : cps->option[i].textValue); j++; + edit = last; + cps->option[i].handle = (void*) + (last = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j)); + XtAddEventHandler(last, ButtonPressMask, False, SetFocus, (XtPointer) popup); + if(cps->option[i].type == TextBox) break; + + // add increment and decrement controls for spin + j=0; + XtSetArg(args[j], XtNfromVert, edit); j++; + XtSetArg(args[j], XtNfromHoriz, last); j++; + XtSetArg(args[j], XtNheight, 10); j++; + XtSetArg(args[j], XtNwidth, 20); j++; + edit = XtCreateManagedWidget("+", commandWidgetClass, form, args, j); + XtAddCallback(edit, XtNcallback, SpinCallback, (XtPointer) i); + + j=0; + XtSetArg(args[j], XtNfromVert, edit); j++; + XtSetArg(args[j], XtNfromHoriz, last); j++; + XtSetArg(args[j], XtNheight, 10); j++; + XtSetArg(args[j], XtNwidth, 20); j++; + last = XtCreateManagedWidget("-", commandWidgetClass, form, args, j); + XtAddCallback(last, XtNcallback, SpinCallback, (XtPointer) i); + break; + case CheckBox: + j=0; + XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNwidth, 10); j++; + XtSetArg(args[j], XtNheight, 10); j++; + XtSetArg(args[j], XtNstate, cps->option[i].value); j++; + cps->option[i].handle = (void*) + (dialog = XtCreateManagedWidget(" ", toggleWidgetClass, form, args, j)); + j=0; + XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNfromHoriz, dialog); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; + last = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); + break; + case SaveButton: + case Button: + j=0; + XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNstate, cps->option[i].value); j++; + cps->option[i].handle = (void*) + (last = XtCreateManagedWidget(cps->option[i].name, commandWidgetClass, form, args, j)); + XtAddCallback(last, XtNcallback, SettingsCallback, (XtPointer) (cps->option[i].type == SaveButton)); + break; + case ComboBox: + j=0; + XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; + dialog = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); + + j=0; + XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNfromHoriz, dialog); j++; + XtSetArg(args[j], XtNwidth, 100); j++; + XtSetArg(args[j], XtNmenuName, XtNewString(cps->option[i].name)); j++; + XtSetArg(args[j], XtNlabel, ((char**)cps->option[i].textValue)[cps->option[i].value]); j++; + cps->option[i].handle = (void*) + (last = XtCreateManagedWidget(" ", menuButtonWidgetClass, form, args, j)); + CreateComboPopup(last, cps->option[i].name, i, (char **) cps->option[i].textValue); + values[i] = cps->option[i].value; + break; + } + } + + j=0; + XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); + XtAddCallback(b_ok, XtNcallback, SettingsCallback, (XtPointer) 0); + + XtSetArg(args[j], XtNfromHoriz, b_ok); j++; + b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j); + XtAddCallback(b_cancel, XtNcallback, SettingsPopDown, (XtPointer) 0); + + XtRealizeWidget(popup); + CatchDeleteWindow(popup, "SettingsPopDown"); + + XQueryPointer(xDisplay, xBoardWindow, &root, &child, + &x, &y, &win_x, &win_y, &mask); + + XtSetArg(args[0], XtNx, x - 10); + XtSetArg(args[1], XtNy, y - 30); + XtSetValues(popup, args, 2); + + XtPopup(popup, XtGrabExclusive); + SettingsUp = True; + + previous = NULL; + SetFocus(edit, popup, (XEvent*) NULL, False); +} + +void FirstSettingsProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + SettingsPopUp(&first); +} + +void SecondSettingsProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + SettingsPopUp(&second); +} + +//--------------------------- General Popup for Cloning ---------------------------------- +#if 0 +int XXXUp; +Widget XXXShell; + +void XXXPopDown() +{ + if (!XXXUp) return; + XtPopdown(XXXShell); + XtDestroyWidget(XXXShell); + XXXUp = False; + ModeHighlight(); +} + +void XXXCallback(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + String name; + Widget w2; + Arg args[16]; + char buf[80]; + + XtSetArg(args[0], XtNlabel, &name); + XtGetValues(w, args, 1); + + if (strcmp(name, _("cancel")) == 0) { + XXXPopDown(); + return; + } + if (strcmp(name, _("ok")) == 0) { + int nr; String name; + name = XawDialogGetValueString(w2 = XtParent(w)); + if(sscanf(name ,"%d",&nr) != 1) { + sprintf(buf, "%d", appData.defaultFrcPosition); + XtSetArg(args[0],XtNvalue, buf); // erase bad (non-numeric) value + XtSetValues(w2, args, 1); + return; + } + XXXPopDown(); + return; + } +} + +void XXXPopUp() +{ + Arg args[16]; + Widget popup, layout, dialog, edit; + Window root, child; + int x, y, i; + int win_x, win_y; + unsigned int mask; + char def[80]; + + i = 0; + XtSetArg(args[i], XtNresizable, True); i++; + XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++; + XXXShell = popup = + XtCreatePopupShell(_("XXX Menu"), transientShellWidgetClass, + shellWidget, args, i); + + layout = + XtCreateManagedWidget(layoutName, formWidgetClass, popup, + layoutArgs, XtNumber(layoutArgs)); + + sprintf(def, "%d\n", appData.defaultFrcPosition); + i = 0; + XtSetArg(args[i], XtNlabel, ""); i++; + XtSetArg(args[i], XtNvalue, def); i++; + XtSetArg(args[i], XtNborderWidth, 0); i++; + dialog = XtCreateManagedWidget("XXX", dialogWidgetClass, + layout, args, i); + + XawDialogAddButton(dialog, _("ok"), XXXCallback, (XtPointer) dialog); + XawDialogAddButton(dialog, _("cancel"), XXXCallback, (XtPointer) dialog); + + XtRealizeWidget(popup); + CatchDeleteWindow(popup, "XXXPopDown"); + + XQueryPointer(xDisplay, xBoardWindow, &root, &child, + &x, &y, &win_x, &win_y, &mask); + + XtSetArg(args[0], XtNx, x - 10); + XtSetArg(args[1], XtNy, y - 30); + XtSetValues(popup, args, 2); + + XtPopup(popup, XtGrabExclusive); + XXXUp = True; + + edit = XtNameToWidget(dialog, "*value"); + + previous = NULL; + SetFocus(engThreshold, popup, (XEvent*) NULL, False); +} + +void XXXMenuProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + XXXPopUp(); +} +#endif + diff --git a/zippy.c b/zippy.c index 9f5b2a8..5626092 100644 --- a/zippy.c +++ b/zippy.c @@ -1,1170 +1,1170 @@ -/* - * zippy.c -- Implements Zippy the Pinhead chess player on ICS in XBoard - * - * Copyright 1991 by Digital Equipment Corporation, Maynard, - * Massachusetts. - * - * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009 Free Software Foundation, Inc. - * - * Enhancements Copyright 2005 Alessandro Scotti - * - * 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. - * ------------------------------------------------------------------------ - * - * The following terms apply to the enhanced version of XBoard - * distributed by the Free Software Foundation: - * ------------------------------------------------------------------------ - * - * GNU XBoard is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * GNU XBoard is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - * - *------------------------------------------------------------------------ - ** See the file ChangeLog for a revision history. */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#if STDC_HEADERS -# include -# include -#else /* not STDC_HEADERS */ -extern char *getenv(); -# if HAVE_STRING_H -# include -# else /* not HAVE_STRING_H */ -# include -# endif /* not HAVE_STRING_H */ -#endif /* not STDC_HEADERS */ - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif -#define HI "hlelo " - -#if HAVE_UNISTD_H -# include -#endif - -#include "common.h" -#include "zippy.h" -#include "frontend.h" -#include "backend.h" -#include "backendz.h" - -char *SendMoveToBookUser P((int nr, ChessProgramState *cps, int initial)); // [HGM] book -void HandleMachineMove P((char *message, ChessProgramState *cps)); - -static char zippyPartner[MSG_SIZ]; -static char zippyLastOpp[MSG_SIZ]; -static char zippyOffender[MSG_SIZ]; // [HGM] aborter -static int zippyConsecGames; -static time_t zippyLastGameEnd; - -extern void mysrandom(unsigned int seed); -extern int myrandom(void); - -void ZippyInit() -{ - char *p; - - /* Get name of Zippy lines file */ - p = getenv("ZIPPYLINES"); - if (p != NULL) { - appData.zippyLines = p; - } - - /* Get word that Zippy thinks is insulting */ - p = getenv("ZIPPYPINHEAD"); - if (p != NULL) { - appData.zippyPinhead = p; - } - - /* What password is used for remote control? */ - p = getenv("ZIPPYPASSWORD"); - if (p != NULL) { - appData.zippyPassword = p; - } - - /* What password is used for remote commands to gnuchess? */ - p = getenv("ZIPPYPASSWORD2"); - if (p != NULL) { - appData.zippyPassword2 = p; - } - - /* Joke feature for people who try an old password */ - p = getenv("ZIPPYWRONGPASSWORD"); - if (p != NULL) { - appData.zippyWrongPassword = p; - } - - /* While testing, I want to accept challenges from only one person - (namely, my "anonymous" account), so I set an environment - variable ZIPPYACCEPTONLY. */ - p = getenv("ZIPPYACCEPTONLY"); - if ( p != NULL ) { - appData.zippyAcceptOnly = p; - } - - /* Should Zippy use "i" command? */ - /* Defaults to 1=true */ - p = getenv("ZIPPYUSEI"); - if (p != NULL) { - appData.zippyUseI = atoi(p); - } - - /* How does Zippy handle bughouse partnering? */ - /* 0=say we can't play, 1=manual partnering, 2=auto partnering */ - p = getenv("ZIPPYBUGHOUSE"); - if (p != NULL) { - appData.zippyBughouse = atoi(p); - } - - /* Does Zippy abort games with Crafty? */ - /* Defaults to 0=false */ - p = getenv("ZIPPYNOPLAYCRAFTY"); - if (p != NULL) { - appData.zippyNoplayCrafty = atoi(p); - } - - /* What ICS command does Zippy send at game end? Default: "gameend". */ - p = getenv("ZIPPYGAMEEND"); - if (p != NULL) { - appData.zippyGameEnd = p; - } - - /* What ICS command does Zippy send at game start? Default: none. */ - p = getenv("ZIPPYGAMESTART"); - if (p != NULL) { - appData.zippyGameStart = p; - } - - /* Should Zippy accept adjourns? */ - /* Defaults to 0=false */ - p = getenv("ZIPPYADJOURN"); - if (p != NULL) { - appData.zippyAdjourn = atoi(p); - } - - /* Should Zippy accept aborts? */ - /* Defaults to 0=false */ - p = getenv("ZIPPYABORT"); - if (p != NULL) { - appData.zippyAbort = atoi(p); - } - - /* Should Zippy play chess variants (besides bughouse)? */ - p = getenv("ZIPPYVARIANTS"); - if (p != NULL) { - appData.zippyVariants = p; - } - strcpy(first.variants, appData.zippyVariants); - - srandom(time(NULL)); -} - -/* - * Routines to implement Zippy talking - */ - - -char *swifties[] = { - "i acclaims:", "i admonishes:", "i advertises:", "i advises:", - "i advocates:", "i affirms:", "i alleges:", "i anathematizes:", - "i animadverts:", "i announces:", "i apostrophizes:", - "i appeals:", "i applauds:", "i approves:", "i argues:", - "i articulates:", "i asserts:", "i asseverates:", "i attests:", - "i avers:", "i avows:", "i baas:", "i babbles:", "i banters:", - "i barks:", "i bawls:", "i bays:", "i begs:", "i belches:", - "i bellows:", "i belts out:", "i berates:", "i beshrews:", - "i blabbers:", "i blabs:", "i blares:", "i blasphemes:", - "i blasts:", "i blathers:", "i bleats:", "i blithers:", - "i blubbers:", "i blurts out:", "i blusters:", "i boasts:", - "i brags:", "i brays:", "i broadcasts:", "i burbles:", - "i buzzes:", "i cachinnates:", "i cackles:", "i caterwauls:", - "i calumniates:", "i caws:", "i censures:", "i chants:", - "i chatters:", "i cheeps:", "i cheers:", "i chides:", "i chins:", - "i chirps:", "i chortles:", "i chuckles:", "i claims:", - "i clamors:", "i clucks:", "i commands:", "i commends:", - "i comments:", "i commiserates:", "i communicates:", - "i complains:", "i concludes:", "i confabulates:", "i confesses:", - "i coos:", "i coughs:", "i counsels:", "i cries:", "i croaks:", - "i crows:", "i curses:", "i daydreams:", "i debates:", - "i declaims:", "i declares:", "i delivers:", "i denounces:", - "i deposes:", "i directs:", "i discloses:", "i disparages:", - "i discourses:", "i divulges:", "i documents:", "i drawls:", - "i dreams:", "i drivels:", "i drones:", "i effuses:", - /*"i ejaculates:",*/ "i elucidates:", "i emotes:", "i endorses:", - "i enthuses:", "i entreats:", "i enunciates:", "i eulogizes:", - "i exclaims:", "i execrates:", "i exhorts:", "i expatiates:", - "i explains:", "i explicates:", "i explodes:", "i exposes:", - "i exposits:", "i expostulates: ", - "i expounds:", "i expresses:", "i extols:", - "i exults:", "i fantasizes:", "i fibs:", "i filibusters:", - "i flatters:", "i flutes:", "i fools:", "i free-associates:", - "i fulminates:", "i gabbles:", "i gabs:", "i gasps:", - "i giggles:", "i gossips:", "i gripes:", "i groans:", "i growls:", - "i grunts:", "i guesses:", "i guffaws:", "i gushes:", "i hails:", - "i hallucinates:", "i harangues:", "i harmonizes:", "i hectors:", - "i hints:", "i hisses:", "i hollers:", "i honks:", "i hoots:", - "i hosannas:", "i howls:", "i hums:", "i hypothecates:", - "i hypothesizes:", "i imagines:", "i implies:", "i implores:", - "i imprecates:", "i indicates:", "i infers:", - "i informs everyone:", "i instructs:", "i interjects:", - "i interposes:", "i intimates:", "i intones:", "i introspects:", - "i inveighs:", "i jabbers:", "i japes:", "i jests:", "i jibes:", - "i jives:", "i jokes:", "i joshes:", "i keens:", "i laments:", - "i lauds:", "i laughs:", "i lectures:", "i lies:", "i lilts:", - "i lisps:", "i maintains:", "i maledicts:", "i maunders:", - "i meows:", "i mewls:", "i mimes:", "i minces:", "i moans:", - "i moos:", "i mourns:", "i mouths:", "i mumbles:", "i murmurs:", - "i muses:", "i mutters:", "i nags:", "i natters:", "i neighs:", - "i notes:", "i nuncupates:", "i objurgates:", "i observes:", - "i offers:", "i oinks:", "i opines:", "i orates:", "i orders:", - "i panegyrizes:", "i pantomimes:", "i pants:", "i peals:", - "i peeps:", "i perorates:", "i persuades:", "i petitions:", - "i phonates:", "i pipes up:", "i pitches:", "i pleads:", - "i points out:", "i pontificates:", "i postulates:", "i praises:", - "i prates:", "i prattles:", "i preaches:", "i prescribes:", - "i prevaricates:", "i proclaims:", "i projects:", "i pronounces:", - "i proposes:", "i proscribes:", "i quacks:", "i queries:", - "i questions:", "i quips:", "i quotes:", "i rages:", "i rambles:", - "i rants:", "i raps:", "i rasps:", "i rattles:", "i raves:", - "i reacts:", "i recites:", "i recommends:", "i records:", - "i reiterates:", "i rejoins:", "i releases:", "i remarks:", - "i reminisces:", "i remonstrates:", "i repeats:", "i replies:", - "i reports:", "i reprimands:", "i reproaches:", "i reproves:", - "i resounds:", "i responds:", "i retorts:", "i reveals:", - "i reviles:", "i roars:", "i rumbles:", "i sanctions:", - "i satirizes:", "i sauces:", "i scolds:", "i screams:", - "i screeches:", "i semaphores:", "i sends:", "i sermonizes:", - "i shrieks:", "i sibilates:", "i sighs:", "i signals:", - "i signifies:", "i signs:", "i sings:", "i slurs:", "i snaps:", - "i snarls:", "i sneezes:", "i snickers:", "i sniggers:", - "i snivels:", "i snores:", "i snorts:", "i sobs:", - "i soliloquizes:", "i sounds off:", "i sounds out:", "i speaks:", - "i spews:", "i spits out:", "i splutters:", "i spoofs:", - "i spouts:", "i sputters:", "i squalls:", "i squawks:", - "i squeaks:", "i squeals:", "i stammers:", "i states:", - "i stresses:", "i stutters:", "i submits:", "i suggests:", - "i summarizes:", "i sums up:", "i swears:", "i talks:", - "i tattles:", "i teases:", "i telegraphs:", "i testifies:", - "i threatens:", "i thunders:", "i titters:", "i tongue-lashes:", - "i toots:", "i transcribes:", "i transmits:", "i trills:", - "i trumpets:", "i twaddles:", "i tweets:", "i twitters:", - "i types:", "i upbraids:", "i urges:", "i utters:", "i ventures:", - "i vibrates:", "i vilifies:", "i vituperates:", "i vocalizes:", - "i vociferates:", "i voices:", "i waffles:", "i wails:", - "i warbles:", "i warns:", "i weeps:", "i wheezes:", "i whimpers:", - "i whines:", "i whinnies:", "i whistles:", "i wisecracks:", - "i witnesses:", "i woofs:", "i writes:", "i yammers:", "i yawps:", - "i yells:", "i yelps:", "i yodels:", "i yowls:", "i zings:", -}; - -#define MAX_SPEECH 250 - -void Speak(how, whom) - char *how, *whom; -{ - static FILE *zipfile = NULL; - static struct stat zipstat; - char zipbuf[MAX_SPEECH + 1]; - static time_t lastShout = 0; - time_t now; - char *p; - int c, speechlen; - Boolean done; - - if (strcmp(how, "shout") == 0) { - now = time((time_t *) NULL); - if (now - lastShout < 1*60) return; - lastShout = now; - if (appData.zippyUseI) { - how = swifties[(unsigned) random() % - (sizeof(swifties)/sizeof(char *))]; - } - } - - if (zipfile == NULL) { - zipfile = fopen(appData.zippyLines, "r"); - if (zipfile == NULL) { - DisplayFatalError("Can't open Zippy lines file", errno, 1); - return; - } - fstat(fileno(zipfile), &zipstat); - } - - for (;;) { - fseek(zipfile, (unsigned) random() % zipstat.st_size, 0); - do { - c = getc(zipfile); - } while (c != NULLCHAR && c != '^' && c != EOF); - if (c == EOF) continue; - while ((c = getc(zipfile)) == '\n') ; - if (c == EOF) continue; - break; - } - done = FALSE; - - /* Don't use ics_prefix; we need to let FICS expand the alias i -> it, - but use the real command "i" on ICC */ - strcpy(zipbuf, how); - strcat(zipbuf, " "); - if (whom != NULL) { - strcat(zipbuf, whom); - strcat(zipbuf, " "); - } - speechlen = strlen(zipbuf); - p = zipbuf + speechlen; - - while (++speechlen < MAX_SPEECH) { - if (c == NULLCHAR || c == '^') { - *p++ = '\n'; - *p = '\0'; - SendToICS(zipbuf); - return; - } else if (c == '\n') { - *p++ = ' '; - do { - c = getc(zipfile); - } while (c == ' '); - } else if (c == EOF) { - break; - } else { - *p++ = c; - c = getc(zipfile); - } - } - /* Tried to say something too long, or junk at the end of the - file. Try something else. */ - Speak(how, whom); /* tail recursion */ -} - -int ZippyCalled(str) - char *str; -{ - return ics_handle[0] != NULLCHAR && StrCaseStr(str, ics_handle) != NULL; -} - -static char opp_name[128][32]; -static int num_opps=0; - -extern ColorClass curColor; - -static void SetCurColor( ColorClass color ) -{ - curColor = color; -} - -static void ColorizeEx( ColorClass color, int cont ) -{ - if( appData.colorize ) { - Colorize( color, cont ); - SetCurColor( color ); - } -} - -int ZippyControl(buf, i) - char *buf; - int *i; -{ - char *player, *p; - char reply[MSG_SIZ]; - -#if TRIVIA -#include "trivia.c" -#endif - - /* Possibly reject Crafty as opponent */ - if (appData.zippyPlay && appData.zippyNoplayCrafty && forwardMostMove < 4 - && looking_at(buf, i, "* kibitzes: Hello from Crafty")) - { - player = StripHighlightAndTitle(star_match[0]); - if ((gameMode == IcsPlayingWhite && - StrCaseCmp(player, gameInfo.black) == 0) || - (gameMode == IcsPlayingBlack && - StrCaseCmp(player, gameInfo.white) == 0)) { - - sprintf(reply, "%ssay This computer does not play Crafty clones\n%sabort\n%s+noplay %s\n", - ics_prefix, ics_prefix, ics_prefix, player); - SendToICS(reply); - } - return TRUE; - } - - /* If this is a computer, save the name. Then later, once the */ - /* game is really started, we will send the "computer" notice to */ - /* the engine. */ - if (appData.zippyPlay && - looking_at(buf, i, "* is in the computer list")) { - int i; - for (i=0;i= num_opps) strcpy(opp_name[num_opps++],star_match[0]); - } - if (appData.zippyPlay && looking_at(buf, i, "* * is a computer *")) { - int i; - for (i=0;i= num_opps) strcpy(opp_name[num_opps++],star_match[1]); - } - - /* Tells and says */ - if (appData.zippyPlay && - (looking_at(buf, i, "* offers to be your bughouse partner") || - looking_at(buf, i, "* tells you: [automatic message] I chose you"))) { - player = StripHighlightAndTitle(star_match[0]); - if (appData.zippyBughouse > 1 && first.initDone) { - sprintf(reply, "%spartner %s\n", ics_prefix, player); - SendToICS(reply); - if (strcmp(zippyPartner, player) != 0) { - strcpy(zippyPartner, player); - SendToProgram(reply + strlen(ics_prefix), &first); - } - } else if (appData.zippyBughouse > 0) { - sprintf(reply, "%sdecline %s\n", ics_prefix, player); - SendToICS(reply); - } else { - sprintf(reply, "%stell %s This computer cannot play bughouse\n", - ics_prefix, player); - SendToICS(reply); - } - return TRUE; - } - - if (appData.zippyPlay && appData.zippyBughouse && first.initDone && - looking_at(buf, i, "* agrees to be your partner")) { - player = StripHighlightAndTitle(star_match[0]); - sprintf(reply, "partner %s\n", player); - if (strcmp(zippyPartner, player) != 0) { - strcpy(zippyPartner, player); - SendToProgram(reply, &first); - } - return TRUE; - } - - if (appData.zippyPlay && appData.zippyBughouse && first.initDone && - (looking_at(buf, i, "are no longer *'s partner") || - looking_at(buf, i, - "* tells you: [automatic message] I'm no longer your"))) { - player = StripHighlightAndTitle(star_match[0]); - if (strcmp(zippyPartner, player) == 0) { - zippyPartner[0] = NULLCHAR; - SendToProgram("partner\n", &first); - } - return TRUE; - } - - if (appData.zippyPlay && appData.zippyBughouse && first.initDone && - (looking_at(buf, i, "no longer have a bughouse partner") || - looking_at(buf, i, "partner has disconnected") || - looking_at(buf, i, "partner has just chosen a new partner"))) { - zippyPartner[0] = NULLCHAR; - SendToProgram("partner\n", &first); - return TRUE; - } - - if (appData.zippyPlay && appData.zippyBughouse && first.initDone && - looking_at(buf, i, "* (your partner) tells you: *")) { - /* This pattern works on FICS but not ICC */ - player = StripHighlightAndTitle(star_match[0]); - if (strcmp(zippyPartner, player) != 0) { - strcpy(zippyPartner, player); - sprintf(reply, "partner %s\n", player); - SendToProgram(reply, &first); - } - sprintf(reply, "ptell %s\n", star_match[1]); - SendToProgram(reply, &first); - return TRUE; - } - - if (looking_at(buf, i, "* tells you: *") || - looking_at(buf, i, "* says: *")) - { - player = StripHighlightAndTitle(star_match[0]); - if (appData.zippyPassword[0] != NULLCHAR && - strncmp(star_match[1], appData.zippyPassword, - strlen(appData.zippyPassword)) == 0) { - p = star_match[1] + strlen(appData.zippyPassword); - while (*p == ' ') p++; - SendToICS(p); - SendToICS("\n"); - } else if (appData.zippyPassword2[0] != NULLCHAR && first.initDone && - strncmp(star_match[1], appData.zippyPassword2, - strlen(appData.zippyPassword2)) == 0) { - p = star_match[1] + strlen(appData.zippyPassword2); - while (*p == ' ') p++; - SendToProgram(p, &first); - SendToProgram("\n", &first); - } else if (appData.zippyWrongPassword[0] != NULLCHAR && - strncmp(star_match[1], appData.zippyWrongPassword, - strlen(appData.zippyWrongPassword)) == 0) { - p = star_match[1] + strlen(appData.zippyWrongPassword); - while (*p == ' ') p++; - sprintf(reply, "wrong %s\n", player); - SendToICS(reply); - } else if (appData.zippyBughouse && first.initDone && - strcmp(player, zippyPartner) == 0) { - SendToProgram("ptell ", &first); - SendToProgram(star_match[1], &first); - SendToProgram("\n", &first); - } else if (strncmp(star_match[1], HI, 6) == 0) { - extern char* programVersion; - sprintf(reply, "%stell %s %s\n", - ics_prefix, player, programVersion); - SendToICS(reply); - } else if (strncmp(star_match[1], "W0W!! ", 6) == 0) { - extern char* programVersion; - sprintf(reply, "%stell %s %s\n", ics_prefix, - player, programVersion); - SendToICS(reply); - } else if (appData.zippyTalk && (((unsigned) random() % 10) < 9)) { - if (strcmp(player, ics_handle) != 0) { - Speak("tell", player); - } - } - - ColorizeEx( ColorTell, FALSE ); - - return TRUE; - } - - if( appData.colorize && looking_at(buf, i, "* (*) seeking") ) { - ColorizeEx(ColorSeek, FALSE); - return FALSE; - } - - if (looking_at(buf, i, "* spoofs you:")) { - player = StripHighlightAndTitle(star_match[0]); - sprintf(reply, "spoofedby %s\n", player); - SendToICS(reply); - } - - return FALSE; -} - -int ZippyConverse(buf, i) - char *buf; - int *i; -{ - static char lastgreet[MSG_SIZ]; - char reply[MSG_SIZ]; - int oldi; - - /* Shouts and emotes */ - if (looking_at(buf, i, "--> * *") || - looking_at(buf, i, "* shouts: *")) - { - if (appData.zippyTalk) { - char *player = StripHighlightAndTitle(star_match[0]); - if (strcmp(player, ics_handle) == 0) { - return TRUE; - } else if (appData.zippyPinhead[0] != NULLCHAR && - StrCaseStr(star_match[1], appData.zippyPinhead) != NULL) { - sprintf(reply, "insult %s\n", player); - SendToICS(reply); - } else if (ZippyCalled(star_match[1])) { - Speak("shout", NULL); - } - } - - ColorizeEx(ColorShout, FALSE); - - return TRUE; - } - - if (looking_at(buf, i, "* kibitzes: *")) { - if (appData.zippyTalk && ((unsigned) random() % 10) < 9) { - char *player = StripHighlightAndTitle(star_match[0]); - if (strcmp(player, ics_handle) != 0) { - Speak("kibitz", NULL); - } - } - - ColorizeEx(ColorKibitz, FALSE); - - return TRUE; - } - - if (looking_at(buf, i, "* whispers: *")) { - if (appData.zippyTalk && ((unsigned) random() % 10) < 9) { - char *player = StripHighlightAndTitle(star_match[0]); - if (strcmp(player, ics_handle) != 0) { - Speak("whisper", NULL); - } - } - - ColorizeEx(ColorKibitz, FALSE); - - return TRUE; - } - - /* Messages */ - if ((looking_at(buf, i, ". * (*:*): *") && isdigit(star_match[1][0])) || - looking_at(buf, i, ". * at *:*: *")) { - if (appData.zippyTalk) { - FILE *f; - char *player = StripHighlightAndTitle(star_match[0]); - - if (strcmp(player, ics_handle) != 0) { - if (((unsigned) random() % 10) < 9) - Speak("message", player); - f = fopen("zippy.messagelog", "a"); - fprintf(f, "%s (%s:%s): %s\n", player, - star_match[1], star_match[2], star_match[3]); - fclose(f); - } - } - return TRUE; - } - - /* Channel tells */ - oldi = *i; - if (looking_at(buf, i, "*(*: *")) { - char *player; - char *channel; - if (star_match[0][0] == NULLCHAR || - strchr(star_match[0], ' ') || - strchr(star_match[1], ' ')) { - /* Oops, did not want to match this; probably a message */ - *i = oldi; - return FALSE; - } - if (appData.zippyTalk) { - player = StripHighlightAndTitle(star_match[0]); - channel = strrchr(star_match[1], '('); - if (channel == NULL) { - channel = star_match[1]; - } else { - channel++; - } - channel[strlen(channel)-1] = NULLCHAR; -#if 0 - /* Always tell to the channel (probability 90%) */ - if (strcmp(player, ics_handle) != 0 && - ((unsigned) random() % 10) < 9) { - Speak("tell", channel); - } -#else - /* Tell to the channel only if someone mentions our name */ - if (ZippyCalled(star_match[2])) { - Speak("tell", channel); - } -#endif - - ColorizeEx( atoi(channel) == 1 ? ColorChannel1 : ColorChannel, FALSE ); - } - return TRUE; - } - - if (!appData.zippyTalk) return FALSE; - - if ((looking_at(buf, i, "You have * message") && - atoi(star_match[0]) != 0) || - looking_at(buf, i, "* has left a message for you") || - looking_at(buf, i, "* just sent you a message")) { - sprintf(reply, "%smessages\n%sclearmessages *\n", - ics_prefix, ics_prefix); - SendToICS(reply); - return TRUE; - } - - if (looking_at(buf, i, "Notification: * has arrived")) { - if (((unsigned) random() % 3) == 0) { - char *player = StripHighlightAndTitle(star_match[0]); - strcpy(lastgreet, player); - sprintf(reply, "greet %s\n", player); - SendToICS(reply); - Speak("tell", player); - } - } - - if (looking_at(buf, i, "Notification: * has departed")) { - if (((unsigned) random() % 3) == 0) { - char *player = StripHighlightAndTitle(star_match[0]); - sprintf(reply, "farewell %s\n", player); - SendToICS(reply); - } - } - - if (looking_at(buf, i, "Not sent -- * is censoring you")) { - char *player = StripHighlightAndTitle(star_match[0]); - if (strcmp(player, lastgreet) == 0) { - sprintf(reply, "%s-notify %s\n", ics_prefix, player); - SendToICS(reply); - } - } - - if (looking_at(buf, i, "command is currently turned off")) { - appData.zippyUseI = 0; - } - - return FALSE; -} - -void ZippyGameStart(white, black) - char *white, *black; -{ - if (!first.initDone) { - /* Game is starting prematurely. We can't deal with this */ - SendToICS(ics_prefix); - SendToICS("abort\n"); - SendToICS(ics_prefix); - SendToICS("say Sorry, the chess program is not initialized yet.\n"); - return; - } - - if (appData.zippyGameStart[0] != NULLCHAR) { - SendToICS(appData.zippyGameStart); - SendToICS("\n"); - } -} - -void ZippyGameEnd(result, resultDetails) - ChessMove result; - char *resultDetails; -{ - if (appData.zippyAcceptOnly[0] == NULLCHAR && - appData.zippyGameEnd[0] != NULLCHAR) { - SendToICS(appData.zippyGameEnd); - SendToICS("\n"); - } - zippyLastGameEnd = time(0); - if(forwardMostMove < appData.zippyShortGame) - strcpy(zippyOffender, zippyLastOpp); else zippyOffender[0] = 0; // [HGM] aborter -} - -/* - * Routines to implement Zippy playing chess - */ - -void ZippyHandleChallenge(srated, swild, sbase, sincrement, opponent) - char *srated, *swild, *sbase, *sincrement, *opponent; -{ - char buf[MSG_SIZ]; - int base, increment, i=0; - char rated; - VariantClass variant; - char *varname; - - rated = srated[0]; - variant = StringToVariant(swild); - varname = VariantName(variant); - base = atoi(sbase); - increment = atoi(sincrement); - - /* [DM] If icsAnalyzeEngine active we don't accept automatic games */ - if (appData.icsActive && appData.icsEngineAnalyze) return; - - /* If desired, you can insert more code here to decline matches - based on rated, variant, base, and increment, but it is - easier to use the ICS formula feature instead. */ - - if (variant == VariantLoadable) { - sprintf(buf, - "%stell %s This computer can't play wild type %s\n%sdecline %s\n", - ics_prefix, opponent, swild, ics_prefix, opponent); - SendToICS(buf); - return; - } - if (StrStr(appData.zippyVariants, varname) == NULL || - ((i=first.protocolVersion) != 1 && StrStr(first.variants, varname) == NULL) /* [HGM] zippyvar */ - ) { - sprintf(buf, - "%stell %s This computer can't play %s [%s], only %s\n%sdecline %s\n", - ics_prefix, opponent, swild, varname, - i ? first.variants : appData.zippyVariants, /* [HGM] zippyvar */ - ics_prefix, opponent); - SendToICS(buf); - return; - } - - /* Are we blocking match requests from all but one person? */ - if (appData.zippyAcceptOnly[0] != NULLCHAR && - StrCaseCmp(opponent, appData.zippyAcceptOnly)) { - /* Yes, and this isn't him. Ignore challenge. */ - return; - } - - /* Too many consecutive games with same opponent? If so, make him - wait until someone else has played or a timeout has elapsed. */ - if (appData.zippyMaxGames && - strcmp(opponent, zippyLastOpp) == 0 && - zippyConsecGames >= appData.zippyMaxGames && - difftime(time(0), zippyLastGameEnd) < appData.zippyReplayTimeout) { - sprintf(buf, "%stell %s Sorry, you have just played %d consecutive games against %s. To give others a chance, please wait %d seconds or until someone else has played.\n%sdecline %s\n", - ics_prefix, opponent, zippyConsecGames, ics_handle, - appData.zippyReplayTimeout, ics_prefix, opponent); - SendToICS(buf); - return; - } - - /* [HGM] aborter: opponent is cheater that aborts games he doesn't like on first move. Make him wait */ - if (strcmp(opponent, zippyOffender) == 0 && - difftime(time(0), zippyLastGameEnd) < appData.zippyReplayTimeout) { - sprintf(buf, "%stell %s Sorry, your previous game against %s was rather short. " - " It will wait %d seconds to see if a tougher opponent comes along.\n%sdecline %s\n", - ics_prefix, opponent, ics_handle, - appData.zippyReplayTimeout, ics_prefix, opponent); - SendToICS(buf); - return; - } - - /* Engine not yet initialized or still thinking about last game? */ - if (!first.initDone || first.lastPing != first.lastPong) { - sprintf(buf, "%stell %s I'm not quite ready for a new game yet; try again soon.\n%sdecline %s\n", - ics_prefix, opponent, ics_prefix, opponent); - SendToICS(buf); - return; - } - - sprintf(buf, "%saccept %s\n", ics_prefix, opponent); - SendToICS(buf); - if (appData.zippyTalk) { - Speak("tell", opponent); - } -} - - -/* Accept matches */ -int ZippyMatch(buf, i) - char *buf; - int *i; -{ - if (looking_at(buf, i, "* * match * * requested with * (*)")) { - - ZippyHandleChallenge(star_match[0], star_match[1], - star_match[2], star_match[3], - StripHighlightAndTitle(star_match[4])); - return TRUE; - } - - /* Old FICS 0-increment form */ - if (looking_at(buf, i, "* * match * requested with * (*)")) { - - ZippyHandleChallenge(star_match[0], star_match[1], - star_match[2], "0", - StripHighlightAndTitle(star_match[3])); - return TRUE; - } - - if (looking_at(buf, i, - "* has made an alternate proposal of * * match * *.")) { - - ZippyHandleChallenge(star_match[1], star_match[2], - star_match[3], star_match[4], - StripHighlightAndTitle(star_match[0])); - return TRUE; - } - - /* FICS wild/nonstandard forms */ - if (looking_at(buf, i, "Challenge: * (*) *(*) * * * * Loaded from *")) { - /* note: star_match[2] can include "[white] " or "[black] " - before our own name. */ - if(star_match[8] == NULL || star_match[8][0] == 0) // [HGM] chessd: open-source ICS has file on next line - ZippyHandleChallenge(star_match[4], star_match[5], - star_match[6], star_match[7], StripHighlightAndTitle(star_match[0])); - else ZippyHandleChallenge(star_match[4], star_match[8], - star_match[6], star_match[7], - StripHighlightAndTitle(star_match[0])); - return TRUE; - } - - if (looking_at(buf, i, - "Challenge: * (*) *(*) * * * * : * * Loaded from *")) { - /* note: star_match[2] can include "[white] " or "[black] " - before our own name. */ - ZippyHandleChallenge(star_match[4], star_match[10], - star_match[8], star_match[9], - StripHighlightAndTitle(star_match[0])); - return TRUE; - } - - /* Regular forms */ - if (looking_at(buf, i, "Challenge: * (*) *(*) * * * * : * *") | - looking_at(buf, i, "Challenge: * (*) *(*) * * * * * *")) { - /* note: star_match[2] can include "[white] " or "[black] " - before our own name. */ - ZippyHandleChallenge(star_match[4], star_match[5], - star_match[8], star_match[9], - StripHighlightAndTitle(star_match[0])); - return TRUE; - } - - if (looking_at(buf, i, "Challenge: * (*) *(*) * * * *")) { - /* note: star_match[2] can include "[white] " or "[black] " - before our own name. */ - ZippyHandleChallenge(star_match[4], star_match[5], - star_match[6], star_match[7], - StripHighlightAndTitle(star_match[0])); - return TRUE; - } - - - if (ics_type == ICS_ICC) { // [DM] - if (looking_at(buf, i, "Your opponent offers you a draw")) { - if (first.sendDrawOffers && first.initDone) - SendToProgram("draw\n", &first); - return TRUE; - } - } else { - if (looking_at(buf, i, "offers you a draw")) { - if (first.sendDrawOffers && first.initDone) { - SendToProgram("draw\n", &first); - } - return TRUE; - } - } - - if (looking_at(buf, i, "requests that the game be aborted") || - looking_at(buf, i, "would like to abort")) { - if (appData.zippyAbort || - (gameMode == IcsPlayingWhite && whiteTimeRemaining < 0) || - (gameMode == IcsPlayingBlack && blackTimeRemaining < 0)) { - SendToICS(ics_prefix); - SendToICS("abort\n"); - } else { - SendToICS(ics_prefix); - if (appData.zippyTalk) - SendToICS("say Whoa no! I am having FUN!!\n"); - else - SendToICS("say Sorry, this computer doesn't accept aborts.\n"); - } - return TRUE; - } - - if (looking_at(buf, i, "requests adjournment") || - looking_at(buf, i, "would like to adjourn")) { - if (appData.zippyAdjourn) { - SendToICS(ics_prefix); - SendToICS("adjourn\n"); - } else { - SendToICS(ics_prefix); - if (appData.zippyTalk) - SendToICS("say Whoa no! I am having FUN playing NOW!!\n"); - else - SendToICS("say Sorry, this computer doesn't accept adjourns.\n"); - } - return TRUE; - } - - return FALSE; -} - -/* Initialize chess program with data from the first board - * of a new or resumed game. - */ -void ZippyFirstBoard(moveNum, basetime, increment) - int moveNum, basetime, increment; -{ - char buf[MSG_SIZ]; - int w, b; - char *opp = (gameMode==IcsPlayingWhite ? gameInfo.black : gameInfo.white); - Boolean sentPos = FALSE; - char *bookHit = NULL; // [HGM] book - - if (!first.initDone) { - /* Game is starting prematurely. We can't deal with this */ - SendToICS(ics_prefix); - SendToICS("abort\n"); - SendToICS(ics_prefix); - SendToICS("say Sorry, the chess program is not initialized yet.\n"); - return; - } - - /* Send the variant command if needed */ - if (gameInfo.variant != VariantNormal) { - sprintf(buf, "variant %s\n", VariantName(gameInfo.variant)); - SendToProgram(buf, &first); - } - - if ((startedFromSetupPosition && moveNum == 0) || - (!appData.getMoveList && moveNum > 0)) { - SendToProgram("force\n", &first); - SendBoard(&first, moveNum); - sentPos = TRUE; - } - - sprintf(buf, "level 0 %d %d\n", basetime, increment); - SendToProgram(buf, &first); - - /* Count consecutive games from one opponent */ - if (strcmp(opp, zippyLastOpp) == 0) { - zippyConsecGames++; - } else { - zippyConsecGames = 1; - strcpy(zippyLastOpp, opp); - } - - /* Send the "computer" command if the opponent is in the list - we've been gathering. */ - for (w=0; w= 0) ? gameInfo.whiteRating : 0; - b = (gameInfo.blackRating >= 0) ? gameInfo.blackRating : 0; - - firstMove = FALSE; - if (gameMode == IcsPlayingWhite) { - if (first.sendName) { - sprintf(buf, "name %s\n", gameInfo.black); - SendToProgram(buf, &first); - } - strcpy(ics_handle, gameInfo.white); - sprintf(buf, "rating %d %d\n", w, b); - SendToProgram(buf, &first); - if (sentPos) { - /* Position sent above, engine is in force mode */ - if (WhiteOnMove(moveNum)) { - /* Engine is on move now */ - if (first.sendTime) { - if (first.useColors) { - SendToProgram("black\n", &first); /*gnu kludge*/ - SendTimeRemaining(&first, TRUE); - SendToProgram("white\n", &first); - } else { - SendTimeRemaining(&first, TRUE); - } - } - bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move - } else { - /* Engine's opponent is on move now */ - if (first.usePlayother) { - if (first.sendTime) { - SendTimeRemaining(&first, TRUE); - } - SendToProgram("playother\n", &first); - } else { - /* Need to send a "go" after opponent moves */ - firstMove = TRUE; - } - } - } else { - /* Position not sent above, move list might be sent later */ - if (moveNum == 0) { - /* No move list coming; at start of game */ - if (first.sendTime) { - if (first.useColors) { - SendToProgram("black\n", &first); /*gnu kludge*/ - SendTimeRemaining(&first, TRUE); - SendToProgram("white\n", &first); - } else { - SendTimeRemaining(&first, TRUE); - } - } -// SendToProgram("go\n", &first); - bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move - } - } - } else if (gameMode == IcsPlayingBlack) { - if (first.sendName) { - sprintf(buf, "name %s\n", gameInfo.white); - SendToProgram(buf, &first); - } - strcpy(ics_handle, gameInfo.black); - sprintf(buf, "rating %d %d\n", b, w); - SendToProgram(buf, &first); - if (sentPos) { - /* Position sent above, engine is in force mode */ - if (!WhiteOnMove(moveNum)) { - /* Engine is on move now */ - if (first.sendTime) { - if (first.useColors) { - SendToProgram("white\n", &first); /*gnu kludge*/ - SendTimeRemaining(&first, FALSE); - SendToProgram("black\n", &first); - } else { - SendTimeRemaining(&first, FALSE); - } - } -// SendToProgram("go\n", &first); - bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move - } else { - /* Engine's opponent is on move now */ - if (first.usePlayother) { - if (first.sendTime) { - SendTimeRemaining(&first, FALSE); - } - SendToProgram("playother\n", &first); - } else { - /* Need to send a "go" after opponent moves */ - firstMove = TRUE; - } - } - } else { - /* Position not sent above, move list might be sent later */ - /* Nothing needs to be done here */ - } - } - - if(bookHit) { // [HGM] book: simulate book reply - static char bookMove[MSG_SIZ]; // a bit generous? - - programStats.depth = programStats.nodes = programStats.time = - programStats.score = programStats.got_only_move = 0; - sprintf(programStats.movelist, "%s (xbook)", bookHit); - - strcpy(bookMove, "move "); - strcat(bookMove, bookHit); - HandleMachineMove(bookMove, &first); - } -} - - -void -ZippyHoldings(white_holding, black_holding, new_piece) - char *white_holding, *black_holding, *new_piece; -{ - char buf[MSG_SIZ]; - if (gameMode != IcsPlayingBlack && gameMode != IcsPlayingWhite) return; - sprintf(buf, "holding [%s] [%s] %s\n", - white_holding, black_holding, new_piece); - SendToProgram(buf, &first); -} +/* + * zippy.c -- Implements Zippy the Pinhead chess player on ICS in XBoard + * + * Copyright 1991 by Digital Equipment Corporation, Maynard, + * Massachusetts. + * + * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, + * 2007, 2008, 2009 Free Software Foundation, Inc. + * + * Enhancements Copyright 2005 Alessandro Scotti + * + * 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. + * ------------------------------------------------------------------------ + * + * The following terms apply to the enhanced version of XBoard + * distributed by the Free Software Foundation: + * ------------------------------------------------------------------------ + * + * GNU XBoard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * GNU XBoard is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + *------------------------------------------------------------------------ + ** See the file ChangeLog for a revision history. */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#if STDC_HEADERS +# include +# include +#else /* not STDC_HEADERS */ +extern char *getenv(); +# if HAVE_STRING_H +# include +# else /* not HAVE_STRING_H */ +# include +# endif /* not HAVE_STRING_H */ +#endif /* not STDC_HEADERS */ + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#define HI "hlelo " + +#if HAVE_UNISTD_H +# include +#endif + +#include "common.h" +#include "zippy.h" +#include "frontend.h" +#include "backend.h" +#include "backendz.h" + +char *SendMoveToBookUser P((int nr, ChessProgramState *cps, int initial)); // [HGM] book +void HandleMachineMove P((char *message, ChessProgramState *cps)); + +static char zippyPartner[MSG_SIZ]; +static char zippyLastOpp[MSG_SIZ]; +static char zippyOffender[MSG_SIZ]; // [HGM] aborter +static int zippyConsecGames; +static time_t zippyLastGameEnd; + +extern void mysrandom(unsigned int seed); +extern int myrandom(void); + +void ZippyInit() +{ + char *p; + + /* Get name of Zippy lines file */ + p = getenv("ZIPPYLINES"); + if (p != NULL) { + appData.zippyLines = p; + } + + /* Get word that Zippy thinks is insulting */ + p = getenv("ZIPPYPINHEAD"); + if (p != NULL) { + appData.zippyPinhead = p; + } + + /* What password is used for remote control? */ + p = getenv("ZIPPYPASSWORD"); + if (p != NULL) { + appData.zippyPassword = p; + } + + /* What password is used for remote commands to gnuchess? */ + p = getenv("ZIPPYPASSWORD2"); + if (p != NULL) { + appData.zippyPassword2 = p; + } + + /* Joke feature for people who try an old password */ + p = getenv("ZIPPYWRONGPASSWORD"); + if (p != NULL) { + appData.zippyWrongPassword = p; + } + + /* While testing, I want to accept challenges from only one person + (namely, my "anonymous" account), so I set an environment + variable ZIPPYACCEPTONLY. */ + p = getenv("ZIPPYACCEPTONLY"); + if ( p != NULL ) { + appData.zippyAcceptOnly = p; + } + + /* Should Zippy use "i" command? */ + /* Defaults to 1=true */ + p = getenv("ZIPPYUSEI"); + if (p != NULL) { + appData.zippyUseI = atoi(p); + } + + /* How does Zippy handle bughouse partnering? */ + /* 0=say we can't play, 1=manual partnering, 2=auto partnering */ + p = getenv("ZIPPYBUGHOUSE"); + if (p != NULL) { + appData.zippyBughouse = atoi(p); + } + + /* Does Zippy abort games with Crafty? */ + /* Defaults to 0=false */ + p = getenv("ZIPPYNOPLAYCRAFTY"); + if (p != NULL) { + appData.zippyNoplayCrafty = atoi(p); + } + + /* What ICS command does Zippy send at game end? Default: "gameend". */ + p = getenv("ZIPPYGAMEEND"); + if (p != NULL) { + appData.zippyGameEnd = p; + } + + /* What ICS command does Zippy send at game start? Default: none. */ + p = getenv("ZIPPYGAMESTART"); + if (p != NULL) { + appData.zippyGameStart = p; + } + + /* Should Zippy accept adjourns? */ + /* Defaults to 0=false */ + p = getenv("ZIPPYADJOURN"); + if (p != NULL) { + appData.zippyAdjourn = atoi(p); + } + + /* Should Zippy accept aborts? */ + /* Defaults to 0=false */ + p = getenv("ZIPPYABORT"); + if (p != NULL) { + appData.zippyAbort = atoi(p); + } + + /* Should Zippy play chess variants (besides bughouse)? */ + p = getenv("ZIPPYVARIANTS"); + if (p != NULL) { + appData.zippyVariants = p; + } + strcpy(first.variants, appData.zippyVariants); + + srandom(time(NULL)); +} + +/* + * Routines to implement Zippy talking + */ + + +char *swifties[] = { + "i acclaims:", "i admonishes:", "i advertises:", "i advises:", + "i advocates:", "i affirms:", "i alleges:", "i anathematizes:", + "i animadverts:", "i announces:", "i apostrophizes:", + "i appeals:", "i applauds:", "i approves:", "i argues:", + "i articulates:", "i asserts:", "i asseverates:", "i attests:", + "i avers:", "i avows:", "i baas:", "i babbles:", "i banters:", + "i barks:", "i bawls:", "i bays:", "i begs:", "i belches:", + "i bellows:", "i belts out:", "i berates:", "i beshrews:", + "i blabbers:", "i blabs:", "i blares:", "i blasphemes:", + "i blasts:", "i blathers:", "i bleats:", "i blithers:", + "i blubbers:", "i blurts out:", "i blusters:", "i boasts:", + "i brags:", "i brays:", "i broadcasts:", "i burbles:", + "i buzzes:", "i cachinnates:", "i cackles:", "i caterwauls:", + "i calumniates:", "i caws:", "i censures:", "i chants:", + "i chatters:", "i cheeps:", "i cheers:", "i chides:", "i chins:", + "i chirps:", "i chortles:", "i chuckles:", "i claims:", + "i clamors:", "i clucks:", "i commands:", "i commends:", + "i comments:", "i commiserates:", "i communicates:", + "i complains:", "i concludes:", "i confabulates:", "i confesses:", + "i coos:", "i coughs:", "i counsels:", "i cries:", "i croaks:", + "i crows:", "i curses:", "i daydreams:", "i debates:", + "i declaims:", "i declares:", "i delivers:", "i denounces:", + "i deposes:", "i directs:", "i discloses:", "i disparages:", + "i discourses:", "i divulges:", "i documents:", "i drawls:", + "i dreams:", "i drivels:", "i drones:", "i effuses:", + /*"i ejaculates:",*/ "i elucidates:", "i emotes:", "i endorses:", + "i enthuses:", "i entreats:", "i enunciates:", "i eulogizes:", + "i exclaims:", "i execrates:", "i exhorts:", "i expatiates:", + "i explains:", "i explicates:", "i explodes:", "i exposes:", + "i exposits:", "i expostulates: ", + "i expounds:", "i expresses:", "i extols:", + "i exults:", "i fantasizes:", "i fibs:", "i filibusters:", + "i flatters:", "i flutes:", "i fools:", "i free-associates:", + "i fulminates:", "i gabbles:", "i gabs:", "i gasps:", + "i giggles:", "i gossips:", "i gripes:", "i groans:", "i growls:", + "i grunts:", "i guesses:", "i guffaws:", "i gushes:", "i hails:", + "i hallucinates:", "i harangues:", "i harmonizes:", "i hectors:", + "i hints:", "i hisses:", "i hollers:", "i honks:", "i hoots:", + "i hosannas:", "i howls:", "i hums:", "i hypothecates:", + "i hypothesizes:", "i imagines:", "i implies:", "i implores:", + "i imprecates:", "i indicates:", "i infers:", + "i informs everyone:", "i instructs:", "i interjects:", + "i interposes:", "i intimates:", "i intones:", "i introspects:", + "i inveighs:", "i jabbers:", "i japes:", "i jests:", "i jibes:", + "i jives:", "i jokes:", "i joshes:", "i keens:", "i laments:", + "i lauds:", "i laughs:", "i lectures:", "i lies:", "i lilts:", + "i lisps:", "i maintains:", "i maledicts:", "i maunders:", + "i meows:", "i mewls:", "i mimes:", "i minces:", "i moans:", + "i moos:", "i mourns:", "i mouths:", "i mumbles:", "i murmurs:", + "i muses:", "i mutters:", "i nags:", "i natters:", "i neighs:", + "i notes:", "i nuncupates:", "i objurgates:", "i observes:", + "i offers:", "i oinks:", "i opines:", "i orates:", "i orders:", + "i panegyrizes:", "i pantomimes:", "i pants:", "i peals:", + "i peeps:", "i perorates:", "i persuades:", "i petitions:", + "i phonates:", "i pipes up:", "i pitches:", "i pleads:", + "i points out:", "i pontificates:", "i postulates:", "i praises:", + "i prates:", "i prattles:", "i preaches:", "i prescribes:", + "i prevaricates:", "i proclaims:", "i projects:", "i pronounces:", + "i proposes:", "i proscribes:", "i quacks:", "i queries:", + "i questions:", "i quips:", "i quotes:", "i rages:", "i rambles:", + "i rants:", "i raps:", "i rasps:", "i rattles:", "i raves:", + "i reacts:", "i recites:", "i recommends:", "i records:", + "i reiterates:", "i rejoins:", "i releases:", "i remarks:", + "i reminisces:", "i remonstrates:", "i repeats:", "i replies:", + "i reports:", "i reprimands:", "i reproaches:", "i reproves:", + "i resounds:", "i responds:", "i retorts:", "i reveals:", + "i reviles:", "i roars:", "i rumbles:", "i sanctions:", + "i satirizes:", "i sauces:", "i scolds:", "i screams:", + "i screeches:", "i semaphores:", "i sends:", "i sermonizes:", + "i shrieks:", "i sibilates:", "i sighs:", "i signals:", + "i signifies:", "i signs:", "i sings:", "i slurs:", "i snaps:", + "i snarls:", "i sneezes:", "i snickers:", "i sniggers:", + "i snivels:", "i snores:", "i snorts:", "i sobs:", + "i soliloquizes:", "i sounds off:", "i sounds out:", "i speaks:", + "i spews:", "i spits out:", "i splutters:", "i spoofs:", + "i spouts:", "i sputters:", "i squalls:", "i squawks:", + "i squeaks:", "i squeals:", "i stammers:", "i states:", + "i stresses:", "i stutters:", "i submits:", "i suggests:", + "i summarizes:", "i sums up:", "i swears:", "i talks:", + "i tattles:", "i teases:", "i telegraphs:", "i testifies:", + "i threatens:", "i thunders:", "i titters:", "i tongue-lashes:", + "i toots:", "i transcribes:", "i transmits:", "i trills:", + "i trumpets:", "i twaddles:", "i tweets:", "i twitters:", + "i types:", "i upbraids:", "i urges:", "i utters:", "i ventures:", + "i vibrates:", "i vilifies:", "i vituperates:", "i vocalizes:", + "i vociferates:", "i voices:", "i waffles:", "i wails:", + "i warbles:", "i warns:", "i weeps:", "i wheezes:", "i whimpers:", + "i whines:", "i whinnies:", "i whistles:", "i wisecracks:", + "i witnesses:", "i woofs:", "i writes:", "i yammers:", "i yawps:", + "i yells:", "i yelps:", "i yodels:", "i yowls:", "i zings:", +}; + +#define MAX_SPEECH 250 + +void Speak(how, whom) + char *how, *whom; +{ + static FILE *zipfile = NULL; + static struct stat zipstat; + char zipbuf[MAX_SPEECH + 1]; + static time_t lastShout = 0; + time_t now; + char *p; + int c, speechlen; + Boolean done; + + if (strcmp(how, "shout") == 0) { + now = time((time_t *) NULL); + if (now - lastShout < 1*60) return; + lastShout = now; + if (appData.zippyUseI) { + how = swifties[(unsigned) random() % + (sizeof(swifties)/sizeof(char *))]; + } + } + + if (zipfile == NULL) { + zipfile = fopen(appData.zippyLines, "r"); + if (zipfile == NULL) { + DisplayFatalError("Can't open Zippy lines file", errno, 1); + return; + } + fstat(fileno(zipfile), &zipstat); + } + + for (;;) { + fseek(zipfile, (unsigned) random() % zipstat.st_size, 0); + do { + c = getc(zipfile); + } while (c != NULLCHAR && c != '^' && c != EOF); + if (c == EOF) continue; + while ((c = getc(zipfile)) == '\n') ; + if (c == EOF) continue; + break; + } + done = FALSE; + + /* Don't use ics_prefix; we need to let FICS expand the alias i -> it, + but use the real command "i" on ICC */ + strcpy(zipbuf, how); + strcat(zipbuf, " "); + if (whom != NULL) { + strcat(zipbuf, whom); + strcat(zipbuf, " "); + } + speechlen = strlen(zipbuf); + p = zipbuf + speechlen; + + while (++speechlen < MAX_SPEECH) { + if (c == NULLCHAR || c == '^') { + *p++ = '\n'; + *p = '\0'; + SendToICS(zipbuf); + return; + } else if (c == '\n') { + *p++ = ' '; + do { + c = getc(zipfile); + } while (c == ' '); + } else if (c == EOF) { + break; + } else { + *p++ = c; + c = getc(zipfile); + } + } + /* Tried to say something too long, or junk at the end of the + file. Try something else. */ + Speak(how, whom); /* tail recursion */ +} + +int ZippyCalled(str) + char *str; +{ + return ics_handle[0] != NULLCHAR && StrCaseStr(str, ics_handle) != NULL; +} + +static char opp_name[128][32]; +static int num_opps=0; + +extern ColorClass curColor; + +static void SetCurColor( ColorClass color ) +{ + curColor = color; +} + +static void ColorizeEx( ColorClass color, int cont ) +{ + if( appData.colorize ) { + Colorize( color, cont ); + SetCurColor( color ); + } +} + +int ZippyControl(buf, i) + char *buf; + int *i; +{ + char *player, *p; + char reply[MSG_SIZ]; + +#if TRIVIA +#include "trivia.c" +#endif + + /* Possibly reject Crafty as opponent */ + if (appData.zippyPlay && appData.zippyNoplayCrafty && forwardMostMove < 4 + && looking_at(buf, i, "* kibitzes: Hello from Crafty")) + { + player = StripHighlightAndTitle(star_match[0]); + if ((gameMode == IcsPlayingWhite && + StrCaseCmp(player, gameInfo.black) == 0) || + (gameMode == IcsPlayingBlack && + StrCaseCmp(player, gameInfo.white) == 0)) { + + sprintf(reply, "%ssay This computer does not play Crafty clones\n%sabort\n%s+noplay %s\n", + ics_prefix, ics_prefix, ics_prefix, player); + SendToICS(reply); + } + return TRUE; + } + + /* If this is a computer, save the name. Then later, once the */ + /* game is really started, we will send the "computer" notice to */ + /* the engine. */ + if (appData.zippyPlay && + looking_at(buf, i, "* is in the computer list")) { + int i; + for (i=0;i= num_opps) strcpy(opp_name[num_opps++],star_match[0]); + } + if (appData.zippyPlay && looking_at(buf, i, "* * is a computer *")) { + int i; + for (i=0;i= num_opps) strcpy(opp_name[num_opps++],star_match[1]); + } + + /* Tells and says */ + if (appData.zippyPlay && + (looking_at(buf, i, "* offers to be your bughouse partner") || + looking_at(buf, i, "* tells you: [automatic message] I chose you"))) { + player = StripHighlightAndTitle(star_match[0]); + if (appData.zippyBughouse > 1 && first.initDone) { + sprintf(reply, "%spartner %s\n", ics_prefix, player); + SendToICS(reply); + if (strcmp(zippyPartner, player) != 0) { + strcpy(zippyPartner, player); + SendToProgram(reply + strlen(ics_prefix), &first); + } + } else if (appData.zippyBughouse > 0) { + sprintf(reply, "%sdecline %s\n", ics_prefix, player); + SendToICS(reply); + } else { + sprintf(reply, "%stell %s This computer cannot play bughouse\n", + ics_prefix, player); + SendToICS(reply); + } + return TRUE; + } + + if (appData.zippyPlay && appData.zippyBughouse && first.initDone && + looking_at(buf, i, "* agrees to be your partner")) { + player = StripHighlightAndTitle(star_match[0]); + sprintf(reply, "partner %s\n", player); + if (strcmp(zippyPartner, player) != 0) { + strcpy(zippyPartner, player); + SendToProgram(reply, &first); + } + return TRUE; + } + + if (appData.zippyPlay && appData.zippyBughouse && first.initDone && + (looking_at(buf, i, "are no longer *'s partner") || + looking_at(buf, i, + "* tells you: [automatic message] I'm no longer your"))) { + player = StripHighlightAndTitle(star_match[0]); + if (strcmp(zippyPartner, player) == 0) { + zippyPartner[0] = NULLCHAR; + SendToProgram("partner\n", &first); + } + return TRUE; + } + + if (appData.zippyPlay && appData.zippyBughouse && first.initDone && + (looking_at(buf, i, "no longer have a bughouse partner") || + looking_at(buf, i, "partner has disconnected") || + looking_at(buf, i, "partner has just chosen a new partner"))) { + zippyPartner[0] = NULLCHAR; + SendToProgram("partner\n", &first); + return TRUE; + } + + if (appData.zippyPlay && appData.zippyBughouse && first.initDone && + looking_at(buf, i, "* (your partner) tells you: *")) { + /* This pattern works on FICS but not ICC */ + player = StripHighlightAndTitle(star_match[0]); + if (strcmp(zippyPartner, player) != 0) { + strcpy(zippyPartner, player); + sprintf(reply, "partner %s\n", player); + SendToProgram(reply, &first); + } + sprintf(reply, "ptell %s\n", star_match[1]); + SendToProgram(reply, &first); + return TRUE; + } + + if (looking_at(buf, i, "* tells you: *") || + looking_at(buf, i, "* says: *")) + { + player = StripHighlightAndTitle(star_match[0]); + if (appData.zippyPassword[0] != NULLCHAR && + strncmp(star_match[1], appData.zippyPassword, + strlen(appData.zippyPassword)) == 0) { + p = star_match[1] + strlen(appData.zippyPassword); + while (*p == ' ') p++; + SendToICS(p); + SendToICS("\n"); + } else if (appData.zippyPassword2[0] != NULLCHAR && first.initDone && + strncmp(star_match[1], appData.zippyPassword2, + strlen(appData.zippyPassword2)) == 0) { + p = star_match[1] + strlen(appData.zippyPassword2); + while (*p == ' ') p++; + SendToProgram(p, &first); + SendToProgram("\n", &first); + } else if (appData.zippyWrongPassword[0] != NULLCHAR && + strncmp(star_match[1], appData.zippyWrongPassword, + strlen(appData.zippyWrongPassword)) == 0) { + p = star_match[1] + strlen(appData.zippyWrongPassword); + while (*p == ' ') p++; + sprintf(reply, "wrong %s\n", player); + SendToICS(reply); + } else if (appData.zippyBughouse && first.initDone && + strcmp(player, zippyPartner) == 0) { + SendToProgram("ptell ", &first); + SendToProgram(star_match[1], &first); + SendToProgram("\n", &first); + } else if (strncmp(star_match[1], HI, 6) == 0) { + extern char* programVersion; + sprintf(reply, "%stell %s %s\n", + ics_prefix, player, programVersion); + SendToICS(reply); + } else if (strncmp(star_match[1], "W0W!! ", 6) == 0) { + extern char* programVersion; + sprintf(reply, "%stell %s %s\n", ics_prefix, + player, programVersion); + SendToICS(reply); + } else if (appData.zippyTalk && (((unsigned) random() % 10) < 9)) { + if (strcmp(player, ics_handle) != 0) { + Speak("tell", player); + } + } + + ColorizeEx( ColorTell, FALSE ); + + return TRUE; + } + + if( appData.colorize && looking_at(buf, i, "* (*) seeking") ) { + ColorizeEx(ColorSeek, FALSE); + return FALSE; + } + + if (looking_at(buf, i, "* spoofs you:")) { + player = StripHighlightAndTitle(star_match[0]); + sprintf(reply, "spoofedby %s\n", player); + SendToICS(reply); + } + + return FALSE; +} + +int ZippyConverse(buf, i) + char *buf; + int *i; +{ + static char lastgreet[MSG_SIZ]; + char reply[MSG_SIZ]; + int oldi; + + /* Shouts and emotes */ + if (looking_at(buf, i, "--> * *") || + looking_at(buf, i, "* shouts: *")) + { + if (appData.zippyTalk) { + char *player = StripHighlightAndTitle(star_match[0]); + if (strcmp(player, ics_handle) == 0) { + return TRUE; + } else if (appData.zippyPinhead[0] != NULLCHAR && + StrCaseStr(star_match[1], appData.zippyPinhead) != NULL) { + sprintf(reply, "insult %s\n", player); + SendToICS(reply); + } else if (ZippyCalled(star_match[1])) { + Speak("shout", NULL); + } + } + + ColorizeEx(ColorShout, FALSE); + + return TRUE; + } + + if (looking_at(buf, i, "* kibitzes: *")) { + if (appData.zippyTalk && ((unsigned) random() % 10) < 9) { + char *player = StripHighlightAndTitle(star_match[0]); + if (strcmp(player, ics_handle) != 0) { + Speak("kibitz", NULL); + } + } + + ColorizeEx(ColorKibitz, FALSE); + + return TRUE; + } + + if (looking_at(buf, i, "* whispers: *")) { + if (appData.zippyTalk && ((unsigned) random() % 10) < 9) { + char *player = StripHighlightAndTitle(star_match[0]); + if (strcmp(player, ics_handle) != 0) { + Speak("whisper", NULL); + } + } + + ColorizeEx(ColorKibitz, FALSE); + + return TRUE; + } + + /* Messages */ + if ((looking_at(buf, i, ". * (*:*): *") && isdigit(star_match[1][0])) || + looking_at(buf, i, ". * at *:*: *")) { + if (appData.zippyTalk) { + FILE *f; + char *player = StripHighlightAndTitle(star_match[0]); + + if (strcmp(player, ics_handle) != 0) { + if (((unsigned) random() % 10) < 9) + Speak("message", player); + f = fopen("zippy.messagelog", "a"); + fprintf(f, "%s (%s:%s): %s\n", player, + star_match[1], star_match[2], star_match[3]); + fclose(f); + } + } + return TRUE; + } + + /* Channel tells */ + oldi = *i; + if (looking_at(buf, i, "*(*: *")) { + char *player; + char *channel; + if (star_match[0][0] == NULLCHAR || + strchr(star_match[0], ' ') || + strchr(star_match[1], ' ')) { + /* Oops, did not want to match this; probably a message */ + *i = oldi; + return FALSE; + } + if (appData.zippyTalk) { + player = StripHighlightAndTitle(star_match[0]); + channel = strrchr(star_match[1], '('); + if (channel == NULL) { + channel = star_match[1]; + } else { + channel++; + } + channel[strlen(channel)-1] = NULLCHAR; +#if 0 + /* Always tell to the channel (probability 90%) */ + if (strcmp(player, ics_handle) != 0 && + ((unsigned) random() % 10) < 9) { + Speak("tell", channel); + } +#else + /* Tell to the channel only if someone mentions our name */ + if (ZippyCalled(star_match[2])) { + Speak("tell", channel); + } +#endif + + ColorizeEx( atoi(channel) == 1 ? ColorChannel1 : ColorChannel, FALSE ); + } + return TRUE; + } + + if (!appData.zippyTalk) return FALSE; + + if ((looking_at(buf, i, "You have * message") && + atoi(star_match[0]) != 0) || + looking_at(buf, i, "* has left a message for you") || + looking_at(buf, i, "* just sent you a message")) { + sprintf(reply, "%smessages\n%sclearmessages *\n", + ics_prefix, ics_prefix); + SendToICS(reply); + return TRUE; + } + + if (looking_at(buf, i, "Notification: * has arrived")) { + if (((unsigned) random() % 3) == 0) { + char *player = StripHighlightAndTitle(star_match[0]); + strcpy(lastgreet, player); + sprintf(reply, "greet %s\n", player); + SendToICS(reply); + Speak("tell", player); + } + } + + if (looking_at(buf, i, "Notification: * has departed")) { + if (((unsigned) random() % 3) == 0) { + char *player = StripHighlightAndTitle(star_match[0]); + sprintf(reply, "farewell %s\n", player); + SendToICS(reply); + } + } + + if (looking_at(buf, i, "Not sent -- * is censoring you")) { + char *player = StripHighlightAndTitle(star_match[0]); + if (strcmp(player, lastgreet) == 0) { + sprintf(reply, "%s-notify %s\n", ics_prefix, player); + SendToICS(reply); + } + } + + if (looking_at(buf, i, "command is currently turned off")) { + appData.zippyUseI = 0; + } + + return FALSE; +} + +void ZippyGameStart(white, black) + char *white, *black; +{ + if (!first.initDone) { + /* Game is starting prematurely. We can't deal with this */ + SendToICS(ics_prefix); + SendToICS("abort\n"); + SendToICS(ics_prefix); + SendToICS("say Sorry, the chess program is not initialized yet.\n"); + return; + } + + if (appData.zippyGameStart[0] != NULLCHAR) { + SendToICS(appData.zippyGameStart); + SendToICS("\n"); + } +} + +void ZippyGameEnd(result, resultDetails) + ChessMove result; + char *resultDetails; +{ + if (appData.zippyAcceptOnly[0] == NULLCHAR && + appData.zippyGameEnd[0] != NULLCHAR) { + SendToICS(appData.zippyGameEnd); + SendToICS("\n"); + } + zippyLastGameEnd = time(0); + if(forwardMostMove < appData.zippyShortGame) + strcpy(zippyOffender, zippyLastOpp); else zippyOffender[0] = 0; // [HGM] aborter +} + +/* + * Routines to implement Zippy playing chess + */ + +void ZippyHandleChallenge(srated, swild, sbase, sincrement, opponent) + char *srated, *swild, *sbase, *sincrement, *opponent; +{ + char buf[MSG_SIZ]; + int base, increment, i=0; + char rated; + VariantClass variant; + char *varname; + + rated = srated[0]; + variant = StringToVariant(swild); + varname = VariantName(variant); + base = atoi(sbase); + increment = atoi(sincrement); + + /* [DM] If icsAnalyzeEngine active we don't accept automatic games */ + if (appData.icsActive && appData.icsEngineAnalyze) return; + + /* If desired, you can insert more code here to decline matches + based on rated, variant, base, and increment, but it is + easier to use the ICS formula feature instead. */ + + if (variant == VariantLoadable) { + sprintf(buf, + "%stell %s This computer can't play wild type %s\n%sdecline %s\n", + ics_prefix, opponent, swild, ics_prefix, opponent); + SendToICS(buf); + return; + } + if (StrStr(appData.zippyVariants, varname) == NULL || + ((i=first.protocolVersion) != 1 && StrStr(first.variants, varname) == NULL) /* [HGM] zippyvar */ + ) { + sprintf(buf, + "%stell %s This computer can't play %s [%s], only %s\n%sdecline %s\n", + ics_prefix, opponent, swild, varname, + i ? first.variants : appData.zippyVariants, /* [HGM] zippyvar */ + ics_prefix, opponent); + SendToICS(buf); + return; + } + + /* Are we blocking match requests from all but one person? */ + if (appData.zippyAcceptOnly[0] != NULLCHAR && + StrCaseCmp(opponent, appData.zippyAcceptOnly)) { + /* Yes, and this isn't him. Ignore challenge. */ + return; + } + + /* Too many consecutive games with same opponent? If so, make him + wait until someone else has played or a timeout has elapsed. */ + if (appData.zippyMaxGames && + strcmp(opponent, zippyLastOpp) == 0 && + zippyConsecGames >= appData.zippyMaxGames && + difftime(time(0), zippyLastGameEnd) < appData.zippyReplayTimeout) { + sprintf(buf, "%stell %s Sorry, you have just played %d consecutive games against %s. To give others a chance, please wait %d seconds or until someone else has played.\n%sdecline %s\n", + ics_prefix, opponent, zippyConsecGames, ics_handle, + appData.zippyReplayTimeout, ics_prefix, opponent); + SendToICS(buf); + return; + } + + /* [HGM] aborter: opponent is cheater that aborts games he doesn't like on first move. Make him wait */ + if (strcmp(opponent, zippyOffender) == 0 && + difftime(time(0), zippyLastGameEnd) < appData.zippyReplayTimeout) { + sprintf(buf, "%stell %s Sorry, your previous game against %s was rather short. " + " It will wait %d seconds to see if a tougher opponent comes along.\n%sdecline %s\n", + ics_prefix, opponent, ics_handle, + appData.zippyReplayTimeout, ics_prefix, opponent); + SendToICS(buf); + return; + } + + /* Engine not yet initialized or still thinking about last game? */ + if (!first.initDone || first.lastPing != first.lastPong) { + sprintf(buf, "%stell %s I'm not quite ready for a new game yet; try again soon.\n%sdecline %s\n", + ics_prefix, opponent, ics_prefix, opponent); + SendToICS(buf); + return; + } + + sprintf(buf, "%saccept %s\n", ics_prefix, opponent); + SendToICS(buf); + if (appData.zippyTalk) { + Speak("tell", opponent); + } +} + + +/* Accept matches */ +int ZippyMatch(buf, i) + char *buf; + int *i; +{ + if (looking_at(buf, i, "* * match * * requested with * (*)")) { + + ZippyHandleChallenge(star_match[0], star_match[1], + star_match[2], star_match[3], + StripHighlightAndTitle(star_match[4])); + return TRUE; + } + + /* Old FICS 0-increment form */ + if (looking_at(buf, i, "* * match * requested with * (*)")) { + + ZippyHandleChallenge(star_match[0], star_match[1], + star_match[2], "0", + StripHighlightAndTitle(star_match[3])); + return TRUE; + } + + if (looking_at(buf, i, + "* has made an alternate proposal of * * match * *.")) { + + ZippyHandleChallenge(star_match[1], star_match[2], + star_match[3], star_match[4], + StripHighlightAndTitle(star_match[0])); + return TRUE; + } + + /* FICS wild/nonstandard forms */ + if (looking_at(buf, i, "Challenge: * (*) *(*) * * * * Loaded from *")) { + /* note: star_match[2] can include "[white] " or "[black] " + before our own name. */ + if(star_match[8] == NULL || star_match[8][0] == 0) // [HGM] chessd: open-source ICS has file on next line + ZippyHandleChallenge(star_match[4], star_match[5], + star_match[6], star_match[7], StripHighlightAndTitle(star_match[0])); + else ZippyHandleChallenge(star_match[4], star_match[8], + star_match[6], star_match[7], + StripHighlightAndTitle(star_match[0])); + return TRUE; + } + + if (looking_at(buf, i, + "Challenge: * (*) *(*) * * * * : * * Loaded from *")) { + /* note: star_match[2] can include "[white] " or "[black] " + before our own name. */ + ZippyHandleChallenge(star_match[4], star_match[10], + star_match[8], star_match[9], + StripHighlightAndTitle(star_match[0])); + return TRUE; + } + + /* Regular forms */ + if (looking_at(buf, i, "Challenge: * (*) *(*) * * * * : * *") | + looking_at(buf, i, "Challenge: * (*) *(*) * * * * * *")) { + /* note: star_match[2] can include "[white] " or "[black] " + before our own name. */ + ZippyHandleChallenge(star_match[4], star_match[5], + star_match[8], star_match[9], + StripHighlightAndTitle(star_match[0])); + return TRUE; + } + + if (looking_at(buf, i, "Challenge: * (*) *(*) * * * *")) { + /* note: star_match[2] can include "[white] " or "[black] " + before our own name. */ + ZippyHandleChallenge(star_match[4], star_match[5], + star_match[6], star_match[7], + StripHighlightAndTitle(star_match[0])); + return TRUE; + } + + + if (ics_type == ICS_ICC) { // [DM] + if (looking_at(buf, i, "Your opponent offers you a draw")) { + if (first.sendDrawOffers && first.initDone) + SendToProgram("draw\n", &first); + return TRUE; + } + } else { + if (looking_at(buf, i, "offers you a draw")) { + if (first.sendDrawOffers && first.initDone) { + SendToProgram("draw\n", &first); + } + return TRUE; + } + } + + if (looking_at(buf, i, "requests that the game be aborted") || + looking_at(buf, i, "would like to abort")) { + if (appData.zippyAbort || + (gameMode == IcsPlayingWhite && whiteTimeRemaining < 0) || + (gameMode == IcsPlayingBlack && blackTimeRemaining < 0)) { + SendToICS(ics_prefix); + SendToICS("abort\n"); + } else { + SendToICS(ics_prefix); + if (appData.zippyTalk) + SendToICS("say Whoa no! I am having FUN!!\n"); + else + SendToICS("say Sorry, this computer doesn't accept aborts.\n"); + } + return TRUE; + } + + if (looking_at(buf, i, "requests adjournment") || + looking_at(buf, i, "would like to adjourn")) { + if (appData.zippyAdjourn) { + SendToICS(ics_prefix); + SendToICS("adjourn\n"); + } else { + SendToICS(ics_prefix); + if (appData.zippyTalk) + SendToICS("say Whoa no! I am having FUN playing NOW!!\n"); + else + SendToICS("say Sorry, this computer doesn't accept adjourns.\n"); + } + return TRUE; + } + + return FALSE; +} + +/* Initialize chess program with data from the first board + * of a new or resumed game. + */ +void ZippyFirstBoard(moveNum, basetime, increment) + int moveNum, basetime, increment; +{ + char buf[MSG_SIZ]; + int w, b; + char *opp = (gameMode==IcsPlayingWhite ? gameInfo.black : gameInfo.white); + Boolean sentPos = FALSE; + char *bookHit = NULL; // [HGM] book + + if (!first.initDone) { + /* Game is starting prematurely. We can't deal with this */ + SendToICS(ics_prefix); + SendToICS("abort\n"); + SendToICS(ics_prefix); + SendToICS("say Sorry, the chess program is not initialized yet.\n"); + return; + } + + /* Send the variant command if needed */ + if (gameInfo.variant != VariantNormal) { + sprintf(buf, "variant %s\n", VariantName(gameInfo.variant)); + SendToProgram(buf, &first); + } + + if ((startedFromSetupPosition && moveNum == 0) || + (!appData.getMoveList && moveNum > 0)) { + SendToProgram("force\n", &first); + SendBoard(&first, moveNum); + sentPos = TRUE; + } + + sprintf(buf, "level 0 %d %d\n", basetime, increment); + SendToProgram(buf, &first); + + /* Count consecutive games from one opponent */ + if (strcmp(opp, zippyLastOpp) == 0) { + zippyConsecGames++; + } else { + zippyConsecGames = 1; + strcpy(zippyLastOpp, opp); + } + + /* Send the "computer" command if the opponent is in the list + we've been gathering. */ + for (w=0; w= 0) ? gameInfo.whiteRating : 0; + b = (gameInfo.blackRating >= 0) ? gameInfo.blackRating : 0; + + firstMove = FALSE; + if (gameMode == IcsPlayingWhite) { + if (first.sendName) { + sprintf(buf, "name %s\n", gameInfo.black); + SendToProgram(buf, &first); + } + strcpy(ics_handle, gameInfo.white); + sprintf(buf, "rating %d %d\n", w, b); + SendToProgram(buf, &first); + if (sentPos) { + /* Position sent above, engine is in force mode */ + if (WhiteOnMove(moveNum)) { + /* Engine is on move now */ + if (first.sendTime) { + if (first.useColors) { + SendToProgram("black\n", &first); /*gnu kludge*/ + SendTimeRemaining(&first, TRUE); + SendToProgram("white\n", &first); + } else { + SendTimeRemaining(&first, TRUE); + } + } + bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move + } else { + /* Engine's opponent is on move now */ + if (first.usePlayother) { + if (first.sendTime) { + SendTimeRemaining(&first, TRUE); + } + SendToProgram("playother\n", &first); + } else { + /* Need to send a "go" after opponent moves */ + firstMove = TRUE; + } + } + } else { + /* Position not sent above, move list might be sent later */ + if (moveNum == 0) { + /* No move list coming; at start of game */ + if (first.sendTime) { + if (first.useColors) { + SendToProgram("black\n", &first); /*gnu kludge*/ + SendTimeRemaining(&first, TRUE); + SendToProgram("white\n", &first); + } else { + SendTimeRemaining(&first, TRUE); + } + } +// SendToProgram("go\n", &first); + bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move + } + } + } else if (gameMode == IcsPlayingBlack) { + if (first.sendName) { + sprintf(buf, "name %s\n", gameInfo.white); + SendToProgram(buf, &first); + } + strcpy(ics_handle, gameInfo.black); + sprintf(buf, "rating %d %d\n", b, w); + SendToProgram(buf, &first); + if (sentPos) { + /* Position sent above, engine is in force mode */ + if (!WhiteOnMove(moveNum)) { + /* Engine is on move now */ + if (first.sendTime) { + if (first.useColors) { + SendToProgram("white\n", &first); /*gnu kludge*/ + SendTimeRemaining(&first, FALSE); + SendToProgram("black\n", &first); + } else { + SendTimeRemaining(&first, FALSE); + } + } +// SendToProgram("go\n", &first); + bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move + } else { + /* Engine's opponent is on move now */ + if (first.usePlayother) { + if (first.sendTime) { + SendTimeRemaining(&first, FALSE); + } + SendToProgram("playother\n", &first); + } else { + /* Need to send a "go" after opponent moves */ + firstMove = TRUE; + } + } + } else { + /* Position not sent above, move list might be sent later */ + /* Nothing needs to be done here */ + } + } + + if(bookHit) { // [HGM] book: simulate book reply + static char bookMove[MSG_SIZ]; // a bit generous? + + programStats.depth = programStats.nodes = programStats.time = + programStats.score = programStats.got_only_move = 0; + sprintf(programStats.movelist, "%s (xbook)", bookHit); + + strcpy(bookMove, "move "); + strcat(bookMove, bookHit); + HandleMachineMove(bookMove, &first); + } +} + + +void +ZippyHoldings(white_holding, black_holding, new_piece) + char *white_holding, *black_holding, *new_piece; +{ + char buf[MSG_SIZ]; + if (gameMode != IcsPlayingBlack && gameMode != IcsPlayingWhite) return; + sprintf(buf, "holding [%s] [%s] %s\n", + white_holding, black_holding, new_piece); + SendToProgram(buf, &first); +}