X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=079d42b155ffa06cba488bd0f6f50392ab6f02a6;hb=9bf9105bf4c9f7063c261d15b5f8326bf7c20439;hp=715a7b36020f178b00d0d233a3c7efdd3ca5c155;hpb=8fba2f04319bfc92a9611cb2434a209dfa1f34f5;p=xboard.git diff --git a/xboard.c b/xboard.c index 715a7b3..079d42b 100644 --- a/xboard.c +++ b/xboard.c @@ -2,10 +2,10 @@ * xboard.c -- X front end for XBoard * * Copyright 1991 by Digital Equipment Corporation, Maynard, - * Massachusetts. + * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. * * The following terms apply to Digital Equipment Corporation's copyright * interest in XBoard: @@ -60,6 +60,7 @@ #include #include #include +#include #if !OMIT_SOCKETS # if HAVE_SYS_SOCKET_H @@ -191,6 +192,7 @@ extern char *getenv(); #include "frontend.h" #include "backend.h" +#include "backendz.h" #include "moves.h" #include "xboard.h" #include "childio.h" @@ -224,21 +226,26 @@ void EvalGraphProc P((Widget w, XEvent *event, typedef struct { String string; + String ref; XtActionProc proc; } MenuItem; typedef struct { String name; + String ref; MenuItem *mi; } Menu; int main P((int argc, char **argv)); +FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *failed, + char *init_path, char *filter, char *mode, int (*show_entry)(), char **name_return)); RETSIGTYPE CmailSigHandler P((int sig)); RETSIGTYPE IntSigHandler P((int sig)); RETSIGTYPE TermSizeSigHandler P((int sig)); -void CreateGCs P((void)); +void CreateGCs P((int redo)); void CreateXIMPieces P((void)); void CreateXPMPieces P((void)); +void CreateXPMBoard P((char *s, int n)); void CreatePieces P((void)); void CreatePieceMenus P((void)); Widget CreateMenuBar P((Menu *mb)); @@ -260,6 +267,10 @@ void AnimateUserMove P((Widget w, XEvent * event, String * params, Cardinal * nParams)); void HandlePV P((Widget w, XEvent * event, String * params, Cardinal * nParams)); +void SelectPV P((Widget w, XEvent * event, + String * params, Cardinal * nParams)); +void StopPV P((Widget w, XEvent * event, + String * params, Cardinal * nParams)); void WhiteClock P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void BlackClock P((Widget w, XEvent *event, @@ -268,13 +279,13 @@ void DrawPositionProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void XDrawPosition P((Widget w, /*Boolean*/int repaint, Board board)); +void CommentClick P((Widget w, XEvent * event, + String * params, Cardinal * nParams)); void CommentPopUp P((char *title, char *label)); void CommentPopDown P((void)); -void CommentCallback P((Widget w, XtPointer client_data, - XtPointer call_data)); void ICSInputBoxPopUp P((void)); void ICSInputBoxPopDown P((void)); -void FileNamePopUp P((char *label, char *def, +void FileNamePopUp P((char *label, char *def, char *filter, FileProc proc, char *openMode)); void FileNamePopDown P((void)); void FileNameCallback P((Widget w, XtPointer client_data, @@ -289,9 +300,6 @@ void AskQuestionPopDown P((void)); void PromotionPopDown P((void)); void PromotionCallback P((Widget w, XtPointer client_data, XtPointer call_data)); -void EditCommentPopDown P((void)); -void EditCommentCallback P((Widget w, XtPointer client_data, - XtPointer call_data)); void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data)); void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); @@ -333,6 +341,8 @@ void AnalyzeFileProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void TwoMachinesProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void MatchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void MatchOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void IcsClientProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); @@ -355,15 +365,19 @@ void AdjuWhiteProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AdjuBlackProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AdjuDrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void UpKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void DownKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void StopObservingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void StopExaminingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void UploadProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void AnnotateProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void TruncateGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void RetractMoveProc P((Widget w, XEvent *event, String *prms, @@ -375,28 +389,21 @@ void AnimateDraggingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AnimateMovingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AutocommProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AutobsProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void FlashMovesProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void GetMoveListProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); void HighlightDraggingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void HighlightArrowProc P((Widget w, XEvent *event, String *prms, + Cardinal *nprms)); void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void OldSaveStyleProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); +//void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void OneClickProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void PonderNextMoveProc P((Widget w, XEvent *event, String *prms, @@ -405,8 +412,7 @@ void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void PopupExitMessageProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +//void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ShowCoordsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ShowThinkingProc P((Widget w, XEvent *event, String *prms, @@ -441,20 +447,27 @@ void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)) void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void OptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void IcsTextProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void GameListOptionsPopUp P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void IcsOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void SoundOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void BoardOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void LoadOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void SaveOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void GameListOptionsPopDown P(()); void ShufflePopDown P(()); -void EnginePopDown P(()); -void UciPopDown P(()); void TimeControlPopDown P(()); -void NewVariantPopDown P(()); -void SettingsPopDown P(()); +void GenericPopDown P(()); void update_ics_width P(()); int get_term_width P(()); int CopyMemoProc P(()); +void DrawArrowHighlight P((int fromX, int fromY, int toX,int toY)); +Boolean IsDrawArrowEnabled P(()); + /* * XBoard depends on Xt R4 or higher */ @@ -476,6 +489,8 @@ Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget, menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell, ICSInputShell, fileNameShell, askQuestionShell; Widget historyShell, evalGraphShell, gameListShell; +int hOffset; // [HGM] dual +XSegment secondSegments[BOARD_RANKS + BOARD_FILES + 2]; XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2]; XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6]; Font clockFontID, coordFontID, countFontID; @@ -500,7 +515,7 @@ int squareSize, smallLayout = 0, tinyLayout = 0, fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False, ICSInputBoxUp = False, askQuestionUp = False, filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1, - editUp = False, errorUp = False, errorExitStatus = -1, lineGap; + errorUp = False, errorExitStatus = -1, lineGap, defaultLineGap; Pixel timerForegroundPixel, timerBackgroundPixel; Pixel buttonForegroundPixel, buttonBackgroundPixel; char *chessDir, *programName, *programVersion, @@ -522,6 +537,9 @@ WindowPlacement wpEngineOutput; WindowPlacement wpGameList; WindowPlacement wpTags; +extern Widget shells[]; +extern Boolean shellUp[]; + #define SOLID 0 #define OUTLINE 1 Pixmap pieceBitmap[2][(int)BlackPawn]; @@ -529,7 +547,8 @@ Pixmap pieceBitmap2[2][(int)BlackPawn+4]; /* [HGM] pieces */ Pixmap xpmPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD actually used*/ Pixmap xpmPieceBitmap2[4][(int)BlackPawn+4]; /* LL, LD, DL, DD set to select from */ Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare; -int useImages, useImageSqs; +Pixmap xpmBoardBitmap[2]; +int useImages, useImageSqs, useTexture, textureW[2], textureH[2]; XImage *ximPieceBitmap[4][(int)BlackPawn+4]; /* LL, LD, DL, DD */ Pixmap ximMaskPm[(int)BlackPawn]; /* clipmasks, used for XIM pieces */ Pixmap ximMaskPm2[(int)BlackPawn+4]; /* clipmasks, used for XIM pieces */ @@ -573,186 +592,216 @@ static Pixmap xpmMask[BlackKing + 1]; SizeDefaults sizeDefaults[] = SIZE_DEFAULTS; MenuItem fileMenu[] = { - {N_("New Game"), ResetProc}, - {N_("New Shuffle Game ..."), ShuffleMenuProc}, - {N_("New Variant ..."), NewVariantProc}, // [HGM] variant: not functional yet - {"----", NothingProc}, - {N_("Load Game"), LoadGameProc}, - {N_("Load Next Game"), LoadNextGameProc}, - {N_("Load Previous Game"), LoadPrevGameProc}, - {N_("Reload Same Game"), ReloadGameProc}, - {N_("Save Game"), SaveGameProc}, - {"----", NothingProc}, - {N_("Copy Game"), CopyGameProc}, - {N_("Paste Game"), PasteGameProc}, - {"----", NothingProc}, - {N_("Load Position"), LoadPositionProc}, - {N_("Load Next Position"), LoadNextPositionProc}, - {N_("Load Previous Position"), LoadPrevPositionProc}, - {N_("Reload Same Position"), ReloadPositionProc}, - {N_("Save Position"), SavePositionProc}, - {"----", NothingProc}, - {N_("Copy Position"), CopyPositionProc}, - {N_("Paste Position"), PastePositionProc}, - {"----", NothingProc}, - {N_("Mail Move"), MailMoveProc}, - {N_("Reload CMail Message"), ReloadCmailMsgProc}, - {"----", NothingProc}, - {N_("Exit"), QuitProc}, - {NULL, NULL} + {N_("New Game Ctrl+N"), "New Game", ResetProc}, + {N_("New Shuffle Game ..."), "New Shuffle Game", ShuffleMenuProc}, + {N_("New Variant ... Alt+Shift+V"), "New Variant", NewVariantProc}, // [HGM] variant: not functional yet + {"----", NULL, NothingProc}, + {N_("Load Game Ctrl+O"), "Load Game", LoadGameProc}, + {N_("Load Position Ctrl+Shift+O"), "Load Position", LoadPositionProc}, +// {N_("Load Next Game"), "Load Next Game", LoadNextGameProc}, +// {N_("Load Previous Game"), "Load Previous Game", LoadPrevGameProc}, +// {N_("Reload Same Game"), "Reload Same Game", ReloadGameProc}, + {N_("Next Position Shift+PgDn"), "Load Next Position", LoadNextPositionProc}, + {N_("Prev Position Shift+PgUp"), "Load Previous Position", LoadPrevPositionProc}, + {"----", NULL, NothingProc}, +// {N_("Reload Same Position"), "Reload Same Position", ReloadPositionProc}, + {N_("Save Game Ctrl+S"), "Save Game", SaveGameProc}, + {N_("Save Position Ctrl+Shift+S"), "Save Position", SavePositionProc}, + {"----", NULL, NothingProc}, + {N_("Mail Move"), "Mail Move", MailMoveProc}, + {N_("Reload CMail Message"), "Reload CMail Message", ReloadCmailMsgProc}, + {"----", NULL, NothingProc}, + {N_("Quit Ctr+Q"), "Exit", QuitProc}, + {NULL, NULL, NULL} +}; + +MenuItem editMenu[] = { + {N_("Copy Game Ctrl+C"), "Copy Game", CopyGameProc}, + {N_("Copy Position Ctrl+Shift+C"), "Copy Position", CopyPositionProc}, + {"----", NULL, NothingProc}, + {N_("Paste Game Ctrl+V"), "Paste Game", PasteGameProc}, + {N_("Paste Position Ctrl+Shift+V"), "Paste Position", PastePositionProc}, + {"----", NULL, NothingProc}, + {N_("Edit Game Ctrl+E"), "Edit Game", EditGameProc}, + {N_("Edit Position Ctrl+Shift+E"), "Edit Position", EditPositionProc}, + {N_("Edit Tags"), "Edit Tags", EditTagsProc}, + {N_("Edit Comment"), "Edit Comment", EditCommentProc}, + {"----", NULL, NothingProc}, + {N_("Revert Home"), "Revert", RevertProc}, + {N_("Annotate"), "Annotate", AnnotateProc}, + {N_("Truncate Game End"), "Truncate Game", TruncateGameProc}, + {"----", NULL, NothingProc}, + {N_("Backward Alt+Left"), "Backward", BackwardProc}, + {N_("Forward Alt+Right"), "Forward", ForwardProc}, + {N_("Back to Start Alt+Home"), "Back to Start", ToStartProc}, + {N_("Forward to End Alt+End"), "Forward to End", ToEndProc}, + {NULL, NULL, NULL} +}; + +MenuItem viewMenu[] = { + {N_("Flip View F2"), "Flip View", FlipViewProc}, + {"----", NULL, NothingProc}, + {N_("Engine Output Alt+Shift+O"), "Show Engine Output", EngineOutputProc}, + {N_("Move History Alt+Shift+H"), "Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code + {N_("Evaluation Graph Alt+Shift+E"), "Show Evaluation Graph", EvalGraphProc}, + {N_("Game List Alt+Shift+G"), "Show Game List", ShowGameListProc}, + {N_("ICS text menu"), "ICStex", IcsTextProc}, + {"----", NULL, NothingProc}, + {N_("Tags"), "Show Tags", EditTagsProc}, + {N_("Comments"), "Show Comments", EditCommentProc}, + {N_("ICS Input Box"), "ICS Input Box", IcsInputBoxProc}, + {"----", NULL, NothingProc}, + {N_("Board..."), "Board Options", BoardOptionsProc}, + {N_("Game List Tags..."), "Game List", GameListOptionsPopUp}, + {NULL, NULL, NULL} }; MenuItem modeMenu[] = { - {N_("Machine White"), MachineWhiteProc}, - {N_("Machine Black"), MachineBlackProc}, - {N_("Two Machines"), TwoMachinesProc}, - {N_("Analysis Mode"), AnalyzeModeProc}, - {N_("Analyze File"), AnalyzeFileProc }, - {N_("ICS Client"), IcsClientProc}, - {N_("Edit Game"), EditGameProc}, - {N_("Edit Position"), EditPositionProc}, - {N_("Training"), TrainingProc}, - {"----", NothingProc}, - {N_("Show Engine Output"), EngineOutputProc}, - {N_("Show Evaluation Graph"), EvalGraphProc}, - {N_("Show Game List"), ShowGameListProc}, - {N_("Show Move History"), HistoryShowProc}, // [HGM] hist: activate 4.2.7 code - {"----", NothingProc}, - {N_("Edit Tags"), EditTagsProc}, - {N_("Edit Comment"), EditCommentProc}, - {N_("ICS Input Box"), IcsInputBoxProc}, - {N_("Pause"), PauseProc}, - {NULL, NULL} + {N_("Machine White Ctrl+W"), "Machine White", MachineWhiteProc}, + {N_("Machine Black Ctrl+B"), "Machine Black", MachineBlackProc}, + {N_("Two Machines Ctrl+T"), "Two Machines", TwoMachinesProc}, + {N_("Analysis Mode Ctrl+A"), "Analysis Mode", AnalyzeModeProc}, + {N_("Analyze File Ctrl+F"), "Analyze File", AnalyzeFileProc }, + {N_("Edit Game Ctrl+E"), "Edit Game", EditGameProc}, + {N_("Edit Position Ctrl+Shift+E"), "Edit Position", EditPositionProc}, + {N_("Training"), "Training", TrainingProc}, + {N_("ICS Client"), "ICS Client", IcsClientProc}, + {"----", NULL, NothingProc}, + {N_("Machine Match"), "Machine Match", MatchProc}, + {N_("Pause Pause"), "Pause", PauseProc}, + {NULL, NULL, NULL} }; MenuItem actionMenu[] = { - {N_("Accept"), AcceptProc}, - {N_("Decline"), DeclineProc}, - {N_("Rematch"), RematchProc}, - {"----", NothingProc}, - {N_("Call Flag"), CallFlagProc}, - {N_("Draw"), DrawProc}, - {N_("Adjourn"), AdjournProc}, - {N_("Abort"), AbortProc}, - {N_("Resign"), ResignProc}, - {"----", NothingProc}, - {N_("Stop Observing"), StopObservingProc}, - {N_("Stop Examining"), StopExaminingProc}, - {"----", NothingProc}, - {N_("Adjudicate to White"), AdjuWhiteProc}, - {N_("Adjudicate to Black"), AdjuBlackProc}, - {N_("Adjudicate Draw"), AdjuDrawProc}, - {NULL, NULL} + {N_("Accept F3"), "Accept", AcceptProc}, + {N_("Decline F4"), "Decline", DeclineProc}, + {N_("Rematch F12"), "Rematch", RematchProc}, + {"----", NULL, NothingProc}, + {N_("Call Flag F5"), "Call Flag", CallFlagProc}, + {N_("Draw F6"), "Draw", DrawProc}, + {N_("Adjourn F7"), "Adjourn", AdjournProc}, + {N_("Abort F8"),"Abort", AbortProc}, + {N_("Resign F9"), "Resign", ResignProc}, + {"----", NULL, NothingProc}, + {N_("Stop Observing F10"), "Stop Observing", StopObservingProc}, + {N_("Stop Examining F11"), "Stop Examining", StopExaminingProc}, + {N_("Upload to Examine"), "Upload to Examine", UploadProc}, + {"----", NULL, NothingProc}, + {N_("Adjudicate to White"), "Adjudicate to White", AdjuWhiteProc}, + {N_("Adjudicate to Black"), "Adjudicate to Black", AdjuBlackProc}, + {N_("Adjudicate Draw"), "Adjudicate Draw", AdjuDrawProc}, + {NULL, NULL, NULL} }; -MenuItem stepMenu[] = { - {N_("Backward"), BackwardProc}, - {N_("Forward"), ForwardProc}, - {N_("Back to Start"), ToStartProc}, - {N_("Forward to End"), ToEndProc}, - {N_("Revert"), RevertProc}, - {N_("Truncate Game"), TruncateGameProc}, - {"----", NothingProc}, - {N_("Move Now"), MoveNowProc}, - {N_("Retract Move"), RetractMoveProc}, - {NULL, NULL} +MenuItem engineMenu[] = { + {N_("Engine #1 Settings ..."), "Engine #1 Settings", FirstSettingsProc}, + {N_("Engine #2 Settings ..."), "Engine #2 Settings", SecondSettingsProc}, + {"----", NULL, NothingProc}, + {N_("Hint"), "Hint", HintProc}, + {N_("Book"), "Book", BookProc}, + {"----", NULL, NothingProc}, + {N_("Move Now Ctrl+M"), "Move Now", MoveNowProc}, + {N_("Retract Move Ctrl+X"), "Retract Move", RetractMoveProc}, + {NULL, NULL, NULL} }; MenuItem optionsMenu[] = { - {N_("Flip View"), FlipViewProc}, - {"----", NothingProc}, - {N_("Adjudications ..."), EngineMenuProc}, - {N_("General Settings ..."), UciMenuProc}, - {N_("Engine #1 Settings ..."), FirstSettingsProc}, - {N_("Engine #2 Settings ..."), SecondSettingsProc}, - {N_("Time Control ..."), TimeControlProc}, - {N_("Game List ..."), GameListOptionsPopUp}, - {"----", NothingProc}, - {N_("Always Queen"), AlwaysQueenProc}, - {N_("Animate Dragging"), AnimateDraggingProc}, - {N_("Animate Moving"), AnimateMovingProc}, - {N_("Auto Comment"), AutocommProc}, - {N_("Auto Flag"), AutoflagProc}, - {N_("Auto Flip View"), AutoflipProc}, - {N_("Auto Observe"), AutobsProc}, - {N_("Auto Raise Board"), AutoraiseProc}, - {N_("Auto Save"), AutosaveProc}, - {N_("Blindfold"), BlindfoldProc}, - {N_("Flash Moves"), FlashMovesProc}, - {N_("Get Move List"), GetMoveListProc}, +#define OPTIONSDIALOG +#ifdef OPTIONSDIALOG + {N_("General ..."), "General", OptionsProc}, +#endif + {N_("Time Control ... Alt+Shift+T"), "Time Control", TimeControlProc}, + {N_("Common Engine ... Alt+Shift+U"), "Common Engine", UciMenuProc}, + {N_("Adjudications ... Alt+Shift+J"), "Adjudications", EngineMenuProc}, + {N_("ICS ..."), "ICS", IcsOptionsProc}, + {N_("Match ..."), "Match", MatchOptionsProc}, + {N_("Load Game ..."), "Load Game", LoadOptionsProc}, + {N_("Save Game ..."), "Save Game", SaveOptionsProc}, +// {N_(" ..."), "", OptionsProc}, + {N_("Game List ..."), "Game List", GameListOptionsPopUp}, + {N_("Sounds ..."), "Sounds", SoundOptionsProc}, + {"----", NULL, NothingProc}, +#ifndef OPTIONSDIALOG + {N_("Always Queen Ctrl+Shift+Q"), "Always Queen", AlwaysQueenProc}, + {N_("Animate Dragging"), "Animate Dragging", AnimateDraggingProc}, + {N_("Animate Moving Ctrl+Shift+A"), "Animate Moving", AnimateMovingProc}, + {N_("Auto Flag Ctrl+Shift+F"), "Auto Flag", AutoflagProc}, + {N_("Auto Flip View"), "Auto Flip View", AutoflipProc}, + {N_("Blindfold"), "Blindfold", BlindfoldProc}, + {N_("Flash Moves"), "Flash Moves", FlashMovesProc}, #if HIGHDRAG - {N_("Highlight Dragging"), HighlightDraggingProc}, + {N_("Highlight Dragging"), "Highlight Dragging", HighlightDraggingProc}, +#endif + {N_("Highlight Last Move"), "Highlight Last Move", HighlightLastMoveProc}, + {N_("Highlight With Arrow"), "Arrow", HighlightArrowProc}, + {N_("Move Sound"), "Move Sound", MoveSoundProc}, +// {N_("ICS Alarm"), "ICS Alarm", IcsAlarmProc}, + {N_("One-Click Moving"), "OneClick", OneClickProc}, + {N_("Periodic Updates"), "Periodic Updates", PeriodicUpdatesProc}, + {N_("Ponder Next Move Ctrl+Shift+P"), "Ponder Next Move", PonderNextMoveProc}, + {N_("Popup Exit Message"), "Popup Exit Message", PopupExitMessageProc}, + {N_("Popup Move Errors"), "Popup Move Errors", PopupMoveErrorsProc}, +// {N_("Premove"), "Premove", PremoveProc}, + {N_("Show Coords"), "Show Coords", ShowCoordsProc}, + {N_("Hide Thinking Ctrl+Shift+H"), "Hide Thinking", HideThinkingProc}, + {N_("Test Legality Ctrl+Shift+L"), "Test Legality", TestLegalityProc}, + {"----", NULL, NothingProc}, #endif - {N_("Highlight Last Move"), HighlightLastMoveProc}, - {N_("Move Sound"), MoveSoundProc}, - {N_("ICS Alarm"), IcsAlarmProc}, - {N_("Old Save Style"), OldSaveStyleProc}, - {N_("Periodic Updates"), PeriodicUpdatesProc}, - {N_("Ponder Next Move"), PonderNextMoveProc}, - {N_("Popup Exit Message"), PopupExitMessageProc}, - {N_("Popup Move Errors"), PopupMoveErrorsProc}, - {N_("Premove"), PremoveProc}, - {N_("Quiet Play"), QuietPlayProc}, - {N_("Show Coords"), ShowCoordsProc}, - {N_("Hide Thinking"), HideThinkingProc}, - {N_("Test Legality"), TestLegalityProc}, - {"----", NothingProc}, - {N_("Save Settings Now"), SaveSettingsProc}, - {N_("Save Settings on Exit"), SaveOnExitProc}, - {NULL, NULL} + {N_("Save Settings Now"), "Save Settings Now", SaveSettingsProc}, + {N_("Save Settings on Exit"), "Save Settings on Exit", SaveOnExitProc}, + {NULL, NULL, NULL} }; MenuItem helpMenu[] = { - {N_("Info XBoard"), InfoProc}, - {N_("Man XBoard"), ManProc}, - {"----", NothingProc}, - {N_("Hint"), HintProc}, - {N_("Book"), BookProc}, - {"----", NothingProc}, - {N_("About XBoard"), AboutProc}, - {NULL, NULL} + {N_("Info XBoard"), "Info XBoard", InfoProc}, + {N_("Man XBoard F1"), "Man XBoard", ManProc}, + {"----", NULL, NothingProc}, + {N_("About XBoard"), "About XBoard", AboutProc}, + {NULL, NULL, NULL} }; Menu menuBar[] = { - {N_("File"), fileMenu}, - {N_("Mode"), modeMenu}, - {N_("Action"), actionMenu}, - {N_("Step"), stepMenu}, - {N_("Options"), optionsMenu}, - {N_("Help"), helpMenu}, - {NULL, NULL} + {N_("File"), "File", fileMenu}, + {N_("Edit"), "Edit", editMenu}, + {N_("View"), "View", viewMenu}, + {N_("Mode"), "Mode", modeMenu}, + {N_("Action"), "Action", actionMenu}, + {N_("Engine"), "Engine", engineMenu}, + {N_("Options"), "Options", optionsMenu}, + {N_("Help"), "Help", helpMenu}, + {NULL, NULL, NULL} }; -#define PAUSE_BUTTON N_("P") +#define PAUSE_BUTTON "P" MenuItem buttonBar[] = { - {"<<", ToStartProc}, - {"<", BackwardProc}, - {PAUSE_BUTTON, PauseProc}, - {">", ForwardProc}, - {">>", ToEndProc}, - {NULL, NULL} + {"<<", "<<", ToStartProc}, + {"<", "<", BackwardProc}, + {PAUSE_BUTTON, PAUSE_BUTTON, PauseProc}, + {">", ">", ForwardProc}, + {">>", ">>", ToEndProc}, + {NULL, NULL, NULL} }; #define PIECE_MENU_SIZE 18 String pieceMenuStrings[2][PIECE_MENU_SIZE] = { { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), - N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), - N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), + N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), + N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), N_("Empty square"), N_("Clear board") }, { N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), - N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), - N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), + N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), + N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), N_("Empty square"), N_("Clear board") } }; /* must be in same order as PieceMenuStrings! */ ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = { { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop, WhiteRook, WhiteQueen, WhiteKing, (ChessSquare) 0, WhiteAlfil, - WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0, + WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0, PromotePiece, DemotePiece, EmptySquare, ClearBoard }, { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop, BlackRook, BlackQueen, BlackKing, (ChessSquare) 0, BlackAlfil, - BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0, + BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0, PromotePiece, DemotePiece, EmptySquare, ClearBoard }, }; @@ -840,7 +889,8 @@ XtActionsRec boardActions[] = { { "HandleUserMove", HandleUserMove }, { "AnimateUserMove", AnimateUserMove }, { "HandlePV", HandlePV }, - { "UnLoadPV", UnLoadPV }, + { "SelectPV", SelectPV }, + { "StopPV", StopPV }, { "FileNameAction", FileNameAction }, { "AskQuestionProc", AskQuestionProc }, { "AskQuestionReplyAction", AskQuestionReplyAction }, @@ -849,6 +899,7 @@ XtActionsRec boardActions[] = { { "BlackClock", BlackClock }, { "Iconify", Iconify }, { "ResetProc", ResetProc }, + { "NewVariantProc", NewVariantProc }, { "LoadGameProc", LoadGameProc }, { "LoadNextGameProc", LoadNextGameProc }, { "LoadPrevGameProc", LoadPrevGameProc }, @@ -883,7 +934,6 @@ XtActionsRec boardActions[] = { { "ShowMoveListProc", HistoryShowProc}, { "EditTagsProc", EditCommentProc }, { "EditCommentProc", EditCommentProc }, - { "IcsAlarmProc", IcsAlarmProc }, { "IcsInputBoxProc", IcsInputBoxProc }, { "PauseProc", PauseProc }, { "AcceptProc", AcceptProc }, @@ -898,45 +948,48 @@ XtActionsRec boardActions[] = { { "AdjuBlackProc", AdjuBlackProc }, { "AdjuDrawProc", AdjuDrawProc }, { "EnterKeyProc", EnterKeyProc }, + { "UpKeyProc", UpKeyProc }, + { "DownKeyProc", DownKeyProc }, { "StopObservingProc", StopObservingProc }, { "StopExaminingProc", StopExaminingProc }, + { "UploadProc", UploadProc }, { "BackwardProc", BackwardProc }, { "ForwardProc", ForwardProc }, { "ToStartProc", ToStartProc }, { "ToEndProc", ToEndProc }, { "RevertProc", RevertProc }, + { "AnnotateProc", AnnotateProc }, { "TruncateGameProc", TruncateGameProc }, { "MoveNowProc", MoveNowProc }, { "RetractMoveProc", RetractMoveProc }, + { "EngineMenuProc", (XtActionProc) EngineMenuProc }, + { "UciMenuProc", (XtActionProc) UciMenuProc }, + { "TimeControlProc", (XtActionProc) TimeControlProc }, + { "FlipViewProc", FlipViewProc }, + { "PonderNextMoveProc", PonderNextMoveProc }, +#ifndef OPTIONSDIALOG { "AlwaysQueenProc", AlwaysQueenProc }, { "AnimateDraggingProc", AnimateDraggingProc }, { "AnimateMovingProc", AnimateMovingProc }, { "AutoflagProc", AutoflagProc }, { "AutoflipProc", AutoflipProc }, - { "AutobsProc", AutobsProc }, - { "AutoraiseProc", AutoraiseProc }, - { "AutosaveProc", AutosaveProc }, { "BlindfoldProc", BlindfoldProc }, { "FlashMovesProc", FlashMovesProc }, - { "FlipViewProc", FlipViewProc }, - { "GetMoveListProc", GetMoveListProc }, #if HIGHDRAG { "HighlightDraggingProc", HighlightDraggingProc }, #endif { "HighlightLastMoveProc", HighlightLastMoveProc }, - { "IcsAlarmProc", IcsAlarmProc }, +// { "IcsAlarmProc", IcsAlarmProc }, { "MoveSoundProc", MoveSoundProc }, - { "OldSaveStyleProc", OldSaveStyleProc }, { "PeriodicUpdatesProc", PeriodicUpdatesProc }, - { "PonderNextMoveProc", PonderNextMoveProc }, { "PopupExitMessageProc", PopupExitMessageProc }, { "PopupMoveErrorsProc", PopupMoveErrorsProc }, - { "PremoveProc", PremoveProc }, - { "QuietPlayProc", QuietPlayProc }, +// { "PremoveProc", PremoveProc }, { "ShowCoordsProc", ShowCoordsProc }, { "ShowThinkingProc", ShowThinkingProc }, { "HideThinkingProc", HideThinkingProc }, { "TestLegalityProc", TestLegalityProc }, +#endif { "SaveSettingsProc", SaveSettingsProc }, { "SaveOnExitProc", SaveOnExitProc }, { "InfoProc", InfoProc }, @@ -947,8 +1000,8 @@ XtActionsRec boardActions[] = { { "AboutProc", AboutProc }, { "DebugProc", DebugProc }, { "NothingProc", NothingProc }, + { "CommentClick", (XtActionProc) CommentClick }, { "CommentPopDown", (XtActionProc) CommentPopDown }, - { "EditCommentPopDown", (XtActionProc) EditCommentPopDown }, { "TagsPopDown", (XtActionProc) TagsPopDown }, { "ErrorPopDown", (XtActionProc) ErrorPopDown }, { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown }, @@ -961,43 +1014,85 @@ XtActionsRec boardActions[] = { { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown }, { "EvalGraphPopDown", (XtActionProc) EvalGraphPopDown }, { "ShufflePopDown", (XtActionProc) ShufflePopDown }, - { "EnginePopDown", (XtActionProc) EnginePopDown }, - { "UciPopDown", (XtActionProc) UciPopDown }, { "TimeControlPopDown", (XtActionProc) TimeControlPopDown }, - { "NewVariantPopDown", (XtActionProc) NewVariantPopDown }, - { "SettingsPopDown", (XtActionProc) SettingsPopDown }, + { "GenericPopDown", (XtActionProc) GenericPopDown }, { "CopyMemoProc", (XtActionProc) CopyMemoProc }, }; char globalTranslations[] = - ":R: ResignProc() \n \ - :r: ResetProc() \n \ - :g: LoadGameProc() \n \ - :N: LoadNextGameProc() \n \ - :P: LoadPrevGameProc() \n \ - :Q: QuitProc() \n \ - :F: ToEndProc() \n \ - :f: ForwardProc() \n \ - :B: ToStartProc() \n \ - :b: BackwardProc() \n \ - :p: PauseProc() \n \ - :d: DrawProc() \n \ - :t: CallFlagProc() \n \ - :i: Iconify() \n \ - :c: Iconify() \n \ - :v: FlipViewProc() \n \ - Control_L: BackwardProc() \n \ - Control_L: ForwardProc() \n \ - Control_R: BackwardProc() \n \ - Control_R: ForwardProc() \n \ + ":F9: ResignProc() \n \ + :Ctrln: ResetProc() \n \ + :MetaV: NewVariantProc() \n \ + :Ctrlo: LoadGameProc() \n \ + :MetaNext: LoadNextGameProc() \n \ + :MetaPrior: LoadPrevGameProc() \n \ + :Ctrls: SaveGameProc() \n \ + :Ctrlc: CopyGameProc() \n \ + :Ctrlv: PasteGameProc() \n \ + :CtrlO: LoadPositionProc() \n \ + :ShiftNext: LoadNextPositionProc() \n \ + :ShiftPrior: LoadPrevPositionProc() \n \ + :CtrlS: SavePositionProc() \n \ + :CtrlC: CopyPositionProc() \n \ + :CtrlV: PastePositionProc() \n \ + :Ctrlq: QuitProc() \n \ + :Ctrlw: MachineWhiteProc() \n \ + :Ctrlb: MachineBlackProc() \n \ + :Ctrlt: TwoMachinesProc() \n \ + :Ctrla: AnalysisModeProc() \n \ + :Ctrlf: AnalyzeFileProc() \n \ + :Ctrle: EditGameProc() \n \ + :CtrlE: EditPositionProc() \n \ + :MetaO: EngineOutputProc() \n \ + :MetaE: EvalGraphProc() \n \ + :MetaG: ShowGameListProc() \n \ + :MetaH: ShowMoveListProc() \n \ + :Pause: PauseProc() \n \ + :F3: AcceptProc() \n \ + :F4: DeclineProc() \n \ + :F12: RematchProc() \n \ + :F5: CallFlagProc() \n \ + :F6: DrawProc() \n \ + :F7: AdjournProc() \n \ + :F8: AbortProc() \n \ + :F10: StopObservingProc() \n \ + :F11: StopExaminingProc() \n \ + :Meta CtrlF12: DebugProc() \n \ + :MetaEnd: ToEndProc() \n \ + :MetaRight: ForwardProc() \n \ + :MetaHome: ToStartProc() \n \ + :MetaLeft: BackwardProc() \n \ + :Home: RevertProc() \n \ + :End: TruncateGameProc() \n \ + :Ctrlm: MoveNowProc() \n \ + :Ctrlx: RetractMoveProc() \n \ + :MetaJ: EngineMenuProc() \n \ + :MetaU: UciMenuProc() \n \ + :MetaT: TimeControlProc() \n \ + :CtrlP: PonderNextMoveProc() \n " +#ifndef OPTIONSDIALOG + "\ + :CtrlQ: AlwaysQueenProc() \n \ + :CtrlF: AutoflagProc() \n \ + :CtrlA: AnimateMovingProc() \n \ + :CtrlL: TestLegalityProc() \n \ + :CtrlH: HideThinkingProc() \n " +#endif + "\ + :-: Iconify() \n \ + :F1: ManProc() \n \ + :F2: FlipViewProc() \n \ + .: BackwardProc() \n \ + .: ForwardProc() \n \ Shift1: AskQuestionProc(\"Direct command\",\ \"Send to chess program:\",,1) \n \ Shift2: AskQuestionProc(\"Direct command\",\ \"Send to second chess program:\",,2) \n"; char boardTranslations[] = - ": HandleUserMove() \n \ - : HandleUserMove() \n \ + ": HandleUserMove(0) \n \ + Shift: HandleUserMove(1) \n \ + : HandleUserMove(0) \n \ : AnimateUserMove() \n \ : HandlePV() \n \ : PieceMenuPopup(menuB) \n \ @@ -1014,8 +1109,14 @@ char whiteTranslations[] = ": WhiteClock()\n"; char blackTranslations[] = ": BlackClock()\n"; char ICSInputTranslations[] = + "Up: UpKeyProc() \n " + "Down: DownKeyProc() \n " "Return: EnterKeyProc() \n"; +// [HGM] vari: another hideous kludge: call extend-end first so we can be sure select-start works, +// as the widget is destroyed before the up-click can call extend-end +char commentTranslations[] = ": extend-end() select-start() CommentClick() \n"; + String xboardResources[] = { "*fileName*value.translations: #override\\n Return: FileNameAction()", "*question*value.translations: #override\\n Return: AskQuestionReplyAction()", @@ -1283,10 +1384,10 @@ extern char *crWhite, * crBlack; void * colorVariable[] = { - &appData.whitePieceColor, - &appData.blackPieceColor, + &appData.whitePieceColor, + &appData.blackPieceColor, &appData.lightSquareColor, - &appData.darkSquareColor, + &appData.darkSquareColor, &appData.highlightSquareColor, &appData.premoveHighlightColor, &appData.lowTimeWarningColor, @@ -1356,7 +1457,7 @@ ParseColor(int n, char *name) void ParseTextAttribs(ColorClass cc, char *s) -{ +{ (&appData.colorShout)[cc] = strdup(s); } @@ -1380,8 +1481,8 @@ SetCommPortDefaults() void SaveFontArg(FILE *f, ArgDescriptor *ad) { - char *name, buf[MSG_SIZ]; - int i, n = (int)ad->argLoc; + char *name; + int i, n = (int)(intptr_t)ad->argLoc; switch(n) { case 0: // CLOCK_FONT name = appData.clockFont; @@ -1402,7 +1503,7 @@ SaveFontArg(FILE *f, ArgDescriptor *ad) break; } for(i=0; iargName, i, fontTable[n][i]); + fprintf(f, OPTCHAR "%s" SEPCHAR "size%d:%s\n", ad->argName, i, fontTable[n][i]); } void @@ -1413,14 +1514,14 @@ ExportSounds() void SaveAttribsArg(FILE *f, ArgDescriptor *ad) { // here the "argLoc" defines a table index. It could have contained the 'ta' pointer itself, though - fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, (&appData.colorShout)[(int)ad->argLoc]); + fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, (&appData.colorShout)[(int)(intptr_t)ad->argLoc]); } void SaveColor(FILE *f, ArgDescriptor *ad) { // in WinBoard the color is an int and has to be converted to text. In X it would be a string already? - if(colorVariable[(int)ad->argLoc]) - fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, *(char**)colorVariable[(int)ad->argLoc]); + if(colorVariable[(int)(intptr_t)ad->argLoc]) + fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, *(char**)colorVariable[(int)(intptr_t)ad->argLoc]); } void @@ -1435,7 +1536,7 @@ ParseCommPortSettings(char *s) } extern Widget engineOutputShell; -extern Widget tagsShell, editTagsShell; + void GetActualPlacement(Widget wg, WindowPlacement *wp) { @@ -1445,7 +1546,7 @@ GetActualPlacement(Widget wg, WindowPlacement *wp) int i; if(!wg) return; - + i = 0; XtSetArg(args[i], XtNx, &x); i++; XtSetArg(args[i], XtNy, &y); i++; @@ -1467,10 +1568,8 @@ GetWindowCoords() if(MoveHistoryIsUp()) GetActualPlacement(historyShell, &wpMoveHistory); if(EvalGraphIsUp()) GetActualPlacement(evalGraphShell, &wpEvalGraph); if(GameListIsUp()) GetActualPlacement(gameListShell, &wpGameList); - if(commentShell) GetActualPlacement(commentShell, &wpComment); - else GetActualPlacement(editShell, &wpComment); - if(tagsShell) GetActualPlacement(tagsShell, &wpTags); - else GetActualPlacement(editTagsShell, &wpTags); + if(shellUp[1]) GetActualPlacement(shells[1], &wpComment); + if(shellUp[2]) GetActualPlacement(shells[2], &wpTags); } void @@ -1482,7 +1581,9 @@ int MySearchPath(char *installDir, char *name, char *fullname) { // just append installDir and name. Perhaps ExpandPath should be used here? name = ExpandPathName(name); - if(name && name[0] == '/') strcpy(fullname, name); else { + if(name && name[0] == '/') + safeStrCpy(fullname, name, MSG_SIZ ); + else { sprintf(fullname, "%s%c%s", installDir, '/', name); } return 1; @@ -1492,7 +1593,7 @@ int MyGetFullPathName(char *name, char *fullname) { // should use ExpandPath? name = ExpandPathName(name); - strcpy(fullname, name); + safeStrCpy(fullname, name, MSG_SIZ ); return 1; } @@ -1512,6 +1613,7 @@ void PopUpStartupDialog() { // start menu not implemented in XBoard } + char * ConvertToLine(int argc, char **argv) { @@ -1519,19 +1621,24 @@ ConvertToLine(int argc, char **argv) int i; line[0] = NULLCHAR; - for(i=1; i= 0) lineGap = appData.overrideLineGap; boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap); boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap); CreateGrid(); + hOffset = boardWidth + 10; + for(i=0; i= 0) lineGap = appData.overrideLineGap; /* [HR] height treated separately (hacked) */ boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap); @@ -1914,79 +2127,12 @@ XBoard square size (hint): %d\n\ appData.monoMode = True; } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.lightSquareColor; - vFrom.size = strlen(appData.lightSquareColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - lightSquareColor = *(Pixel *) vTo.addr; - } - } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.darkSquareColor; - vFrom.size = strlen(appData.darkSquareColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - darkSquareColor = *(Pixel *) vTo.addr; - } - } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.whitePieceColor; - vFrom.size = strlen(appData.whitePieceColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - whitePieceColor = *(Pixel *) vTo.addr; - } - } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.blackPieceColor; - vFrom.size = strlen(appData.blackPieceColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - blackPieceColor = *(Pixel *) vTo.addr; - } - } - - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.highlightSquareColor; - vFrom.size = strlen(appData.highlightSquareColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - highlightSquareColor = *(Pixel *) vTo.addr; - } - } - - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.premoveHighlightColor; - vFrom.size = strlen(appData.premoveHighlightColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - premoveHighlightColor = *(Pixel *) vTo.addr; - } - } + forceMono = MakeColors(); if (forceMono) { fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"), programName); - + if (appData.bitmapDirectory == NULL || appData.bitmapDirectory[0] == NULLCHAR) appData.bitmapDirectory = DEF_BITMAP_DIR; @@ -1996,7 +2142,7 @@ XBoard square size (hint): %d\n\ vFrom.addr = (caddr_t) appData.lowTimeWarningColor; vFrom.size = strlen(appData.lowTimeWarningColor); XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) + if (vTo.addr == NULL) appData.monoMode = True; else lowTimeWarningColor = *(Pixel *) vTo.addr; @@ -2008,24 +2154,7 @@ XBoard square size (hint): %d\n\ (unsigned long) XBlackPixel(xDisplay, xScreen)); } - if (parse_cpair(ColorShout, appData.colorShout) < 0 || - parse_cpair(ColorSShout, appData.colorSShout) < 0 || - parse_cpair(ColorChannel1, appData.colorChannel1) < 0 || - parse_cpair(ColorChannel, appData.colorChannel) < 0 || - parse_cpair(ColorKibitz, appData.colorKibitz) < 0 || - parse_cpair(ColorTell, appData.colorTell) < 0 || - parse_cpair(ColorChallenge, appData.colorChallenge) < 0 || - parse_cpair(ColorRequest, appData.colorRequest) < 0 || - parse_cpair(ColorSeek, appData.colorSeek) < 0 || - parse_cpair(ColorNormal, appData.colorNormal) < 0) - { - if (appData.colorize) { - fprintf(stderr, - _("%s: can't parse color names; disabling colorization\n"), - programName); - } - appData.colorize = FALSE; - } + ParseIcsTextColors(); textColors[ColorNone].fg = textColors[ColorNone].bg = -1; textColors[ColorNone].attr = 0; @@ -2283,6 +2412,7 @@ XBoard square size (hint): %d\n\ ReadBitmap(&xMarkPixmap, "checkmark.bm", checkmark_bits, checkmark_width, checkmark_height); XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); +#ifndef OPTIONSDIALOG if (appData.alwaysPromoteToQueen) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"), args, 1); @@ -2296,10 +2426,6 @@ XBoard square size (hint): %d\n\ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"), args, 1); } - if (appData.autoComment) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"), - args, 1); - } if (appData.autoCallFlag) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"), args, 1); @@ -2308,26 +2434,6 @@ XBoard square size (hint): %d\n\ XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"), args, 1); } - if (appData.autoObserve) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"), - args, 1); - } - if (appData.autoRaiseBoard) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Auto Raise Board"), args, 1); - } - if (appData.autoSaveGames) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"), - args, 1); - } - if (appData.saveGameFile[0] != NULLCHAR) { - /* Can't turn this off from menu */ - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"), - args, 1); - XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"), - False); - - } if (appData.blindfold) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"), args, 1); @@ -2337,10 +2443,6 @@ XBoard square size (hint): %d\n\ "menuOptions.Flash Moves"), args, 1); } - if (appData.getMoveList) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"), - args, 1); - } #if HIGHDRAG if (appData.highlightDragging) { XtSetValues(XtNameToWidget(menuBarWidget, @@ -2353,17 +2455,22 @@ XBoard square size (hint): %d\n\ "menuOptions.Highlight Last Move"), args, 1); } - if (appData.icsAlarm) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"), + if (appData.highlightMoveWithArrow) { + XtSetValues(XtNameToWidget(menuBarWidget, + "menuOptions.Arrow"), args, 1); } +// if (appData.icsAlarm) { +// XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"), +// args, 1); +// } if (appData.ringBellAfterMoves) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"), args, 1); } - if (appData.oldSaveStyle) { + if (appData.oneClick) { XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Old Save Style"), args, 1); + "menuOptions.OneClick"), args, 1); } if (appData.periodicUpdates) { XtSetValues(XtNameToWidget(menuBarWidget, @@ -2381,14 +2488,10 @@ XBoard square size (hint): %d\n\ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"), args, 1); } - if (appData.premove) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Premove"), args, 1); - } - if (appData.quietPlay) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Quiet Play"), args, 1); - } +// if (appData.premove) { +// XtSetValues(XtNameToWidget(menuBarWidget, +// "menuOptions.Premove"), args, 1); +// } if (appData.showCoords) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"), args, 1); @@ -2401,6 +2504,7 @@ XBoard square size (hint): %d\n\ XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"), args, 1); } +#endif if (saveSettingsOnExit) { XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Save Settings on Exit"), args, 1); @@ -2439,13 +2543,15 @@ XBoard square size (hint): %d\n\ CatchDeleteWindow(shellWidget, "QuitProc"); - CreateGCs(); + CreateGCs(False); CreateGrid(); #if HAVE_LIBXPM if (appData.bitmapDirectory[0] != NULLCHAR) { CreatePieces(); } else { CreateXPMPieces(); + CreateXPMBoard(appData.liteBackTextureFile, 1); + CreateXPMBoard(appData.darkBackTextureFile, 0); } #else CreateXIMPieces(); @@ -2469,7 +2575,7 @@ XBoard square size (hint): %d\n\ /* Why is the following needed on some versions of X instead * of a translation? */ - XtAddEventHandler(boardWidget, ExposureMask, False, + XtAddEventHandler(boardWidget, ExposureMask|PointerMotionMask, False, (XtEventHandler) EventProc, NULL); /* end why */ @@ -2478,11 +2584,11 @@ XBoard square size (hint): %d\n\ HistoryPopUp(); } - if( wpEvalGraph.visible ) + if( wpEvalGraph.visible ) { EvalGraphPopUp(); }; - + if( wpEngineOutput.visible ) { EngineOutputPopUp(); } @@ -2508,6 +2614,7 @@ XBoard square size (hint): %d\n\ } gameInfo.boardWidth = 0; // [HGM] pieces: kludge to ensure InitPosition() calls InitDrawingSizes() InitPosition(TRUE); + XtSetKeyboardFocus(shellWidget, formWidget); XtAppMainLoop(appContext); if (appData.debugMode) fclose(debugFP); // [DM] debug @@ -2569,29 +2676,39 @@ CmailSigHandlerCallBack(isr, closure, message, count, error) void ICSInitScript() { - FILE *f; - char buf[MSG_SIZ]; - char *p; + /* try to open the icsLogon script, either in the location given + * or in the users HOME directory + */ + + FILE *f; + char buf[MSG_SIZ]; + char *homedir; - f = fopen(appData.icsLogon, "r"); - if (f == NULL) { - p = getenv("HOME"); - if (p != NULL) { - strcpy(buf, p); - strcat(buf, "/"); - strcat(buf, appData.icsLogon); - f = fopen(buf, "r"); + f = fopen(appData.icsLogon, "r"); + if (f == NULL) + { + homedir = getenv("HOME"); + if (homedir != NULL) + { + safeStrCpy(buf, homedir, sizeof(buf)/sizeof(buf[0]) ); + strncat(buf, "/", MSG_SIZ - strlen(buf) - 1); + strncat(buf, appData.icsLogon, MSG_SIZ - strlen(buf) - 1); + f = fopen(buf, "r"); } } - if (f != NULL) - ProcessICSInitScript(f); + + if (f != NULL) + ProcessICSInitScript(f); + else + printf("Warning: Couldn't open icsLogon file (checked %s and %s).\n", appData.icsLogon, buf); + + return; } void ResetFrontEnd() { CommentPopDown(); - EditCommentPopDown(); TagsPopDown(); return; } @@ -2607,9 +2724,15 @@ GreyRevert(grey) { Widget w; if (!menuBarWidget) return; - w = XtNameToWidget(menuBarWidget, "menuStep.Revert"); + w = XtNameToWidget(menuBarWidget, "menuEdit.Revert"); if (w == NULL) { - DisplayError("menuStep.Revert", 0); + DisplayError("menuEdit.Revert", 0); + } else { + XtSetSensitive(w, !grey); + } + w = XtNameToWidget(menuBarWidget, "menuEdit.Annotate"); + if (w == NULL) { + DisplayError("menuEdit.Annotate", 0); } else { XtSetSensitive(w, !grey); } @@ -2640,14 +2763,20 @@ Enables icsEnables[] = { { "menuMode.Analysis Mode", False }, { "menuMode.Analyze File", False }, { "menuMode.Two Machines", False }, + { "menuMode.Machine Match", False }, #ifndef ZIPPY - { "menuHelp.Hint", False }, - { "menuHelp.Book", False }, - { "menuStep.Move Now", False }, + { "menuEngine.Hint", False }, + { "menuEngine.Book", False }, + { "menuEngine.Move Now", False }, +#ifndef OPTIONSDIALOG { "menuOptions.Periodic Updates", False }, { "menuOptions.Hide Thinking", False }, { "menuOptions.Ponder Next Move", False }, #endif + { "menuEngine.Engine #1 Settings", False }, +#endif + { "menuEngine.Engine #2 Settings", False }, + { "menuEdit.Annotate", False }, { NULL, False } }; @@ -2659,45 +2788,46 @@ Enables ncpEnables[] = { { "menuMode.Analysis Mode", False }, { "menuMode.Analyze File", False }, { "menuMode.Two Machines", False }, + { "menuMode.Machine Match", False }, { "menuMode.ICS Client", False }, - { "menuMode.ICS Input Box", False }, + { "menuView.ICStex", False }, + { "menuView.ICS Input Box", False }, { "Action", False }, - { "menuStep.Revert", False }, - { "menuStep.Move Now", False }, - { "menuStep.Retract Move", False }, - { "menuOptions.Auto Comment", False }, + { "menuEdit.Revert", False }, + { "menuEdit.Annotate", False }, + { "menuEngine.Engine #1 Settings", False }, + { "menuEngine.Engine #2 Settings", False }, + { "menuEngine.Move Now", False }, + { "menuEngine.Retract Move", False }, + { "menuOptions.ICS", False }, +#ifndef OPTIONSDIALOG { "menuOptions.Auto Flag", False }, { "menuOptions.Auto Flip View", False }, - { "menuOptions.Auto Observe", False }, - { "menuOptions.Auto Raise Board", False }, - { "menuOptions.Get Move List", False }, - { "menuOptions.ICS Alarm", False }, +// { "menuOptions.ICS Alarm", False }, { "menuOptions.Move Sound", False }, - { "menuOptions.Quiet Play", False }, { "menuOptions.Hide Thinking", False }, { "menuOptions.Periodic Updates", False }, { "menuOptions.Ponder Next Move", False }, - { "menuHelp.Hint", False }, - { "menuHelp.Book", False }, +#endif + { "menuEngine.Hint", False }, + { "menuEngine.Book", False }, { NULL, False } }; Enables gnuEnables[] = { { "menuMode.ICS Client", False }, - { "menuMode.ICS Input Box", False }, + { "menuView.ICStex", False }, + { "menuView.ICS Input Box", False }, { "menuAction.Accept", False }, { "menuAction.Decline", False }, { "menuAction.Rematch", False }, { "menuAction.Adjourn", False }, { "menuAction.Stop Examining", False }, { "menuAction.Stop Observing", False }, - { "menuStep.Revert", False }, - { "menuOptions.Auto Comment", False }, - { "menuOptions.Auto Observe", False }, - { "menuOptions.Auto Raise Board", False }, - { "menuOptions.Get Move List", False }, - { "menuOptions.Premove", False }, - { "menuOptions.Quiet Play", False }, + { "menuAction.Upload to Examine", False }, + { "menuEdit.Revert", False }, + { "menuEdit.Annotate", False }, + { "menuOptions.ICS", False }, /* The next two options rely on SetCmailMode being called *after* */ /* SetGNUMode so that when GNU is being used to give hints these */ @@ -2724,60 +2854,62 @@ Enables cmailEnables[] = { Enables trainingOnEnables[] = { { "menuMode.Edit Comment", False }, { "menuMode.Pause", False }, - { "menuStep.Forward", False }, - { "menuStep.Backward", False }, - { "menuStep.Forward to End", False }, - { "menuStep.Back to Start", False }, - { "menuStep.Move Now", False }, - { "menuStep.Truncate Game", False }, + { "menuEdit.Forward", False }, + { "menuEdit.Backward", False }, + { "menuEdit.Forward to End", False }, + { "menuEdit.Back to Start", False }, + { "menuEngine.Move Now", False }, + { "menuEdit.Truncate Game", False }, { NULL, False } }; Enables trainingOffEnables[] = { { "menuMode.Edit Comment", True }, { "menuMode.Pause", True }, - { "menuStep.Forward", True }, - { "menuStep.Backward", True }, - { "menuStep.Forward to End", True }, - { "menuStep.Back to Start", True }, - { "menuStep.Move Now", True }, - { "menuStep.Truncate Game", True }, + { "menuEdit.Forward", True }, + { "menuEdit.Backward", True }, + { "menuEdit.Forward to End", True }, + { "menuEdit.Back to Start", True }, + { "menuEngine.Move Now", True }, + { "menuEdit.Truncate Game", True }, { NULL, False } }; Enables machineThinkingEnables[] = { { "menuFile.Load Game", False }, - { "menuFile.Load Next Game", False }, - { "menuFile.Load Previous Game", False }, - { "menuFile.Reload Same Game", False }, - { "menuFile.Paste Game", False }, +// { "menuFile.Load Next Game", False }, +// { "menuFile.Load Previous Game", False }, +// { "menuFile.Reload Same Game", False }, + { "menuEdit.Paste Game", False }, { "menuFile.Load Position", False }, - { "menuFile.Load Next Position", False }, - { "menuFile.Load Previous Position", False }, - { "menuFile.Reload Same Position", False }, - { "menuFile.Paste Position", False }, +// { "menuFile.Load Next Position", False }, +// { "menuFile.Load Previous Position", False }, +// { "menuFile.Reload Same Position", False }, + { "menuEdit.Paste Position", False }, { "menuMode.Machine White", False }, { "menuMode.Machine Black", False }, { "menuMode.Two Machines", False }, - { "menuStep.Retract Move", False }, + { "menuMode.Machine Match", False }, + { "menuEngine.Retract Move", False }, { NULL, False } }; Enables userThinkingEnables[] = { { "menuFile.Load Game", True }, - { "menuFile.Load Next Game", True }, - { "menuFile.Load Previous Game", True }, - { "menuFile.Reload Same Game", True }, - { "menuFile.Paste Game", True }, +// { "menuFile.Load Next Game", True }, +// { "menuFile.Load Previous Game", True }, +// { "menuFile.Reload Same Game", True }, + { "menuEdit.Paste Game", True }, { "menuFile.Load Position", True }, - { "menuFile.Load Next Position", True }, - { "menuFile.Load Previous Position", True }, - { "menuFile.Reload Same Position", True }, - { "menuFile.Paste Position", True }, +// { "menuFile.Load Next Position", True }, +// { "menuFile.Load Previous Position", True }, +// { "menuFile.Reload Same Position", True }, + { "menuEdit.Paste Position", True }, { "menuMode.Machine White", True }, { "menuMode.Machine Black", True }, { "menuMode.Two Machines", True }, - { "menuStep.Retract Move", True }, + { "menuMode.Machine Match", True }, + { "menuEngine.Retract Move", True }, { NULL, False } }; @@ -2785,7 +2917,7 @@ void SetICSMode() { SetMenuEnables(icsEnables); -#ifdef ZIPPY +#if ZIPPY if (appData.zippyPlay && !appData.noChessProgram) /* [DM] icsEngineAnalyze */ XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True); #endif @@ -2852,6 +2984,51 @@ SetMachineThinkingEnables() } } +// [HGM] code borrowed from winboard.c (which should thus go to backend.c!) +#define HISTORY_SIZE 64 +static char *history[HISTORY_SIZE]; +int histIn = 0, histP = 0; + +void +SaveInHistory(char *cmd) +{ + if (history[histIn] != NULL) { + free(history[histIn]); + history[histIn] = NULL; + } + if (*cmd == NULLCHAR) return; + history[histIn] = StrSave(cmd); + histIn = (histIn + 1) % HISTORY_SIZE; + if (history[histIn] != NULL) { + free(history[histIn]); + history[histIn] = NULL; + } + histP = histIn; +} + +char * +PrevInHistory(char *cmd) +{ + int newhp; + if (histP == histIn) { + if (history[histIn] != NULL) free(history[histIn]); + history[histIn] = StrSave(cmd); + } + newhp = (histP - 1 + HISTORY_SIZE) % HISTORY_SIZE; + if (newhp == histIn || history[newhp] == NULL) return NULL; + histP = newhp; + return history[histP]; +} + +char * +NextInHistory() +{ + if (histP == histIn) return NULL; + histP = (histP + 1) % HISTORY_SIZE; + return history[histP]; +} +// end of borrowed code + #define Abs(n) ((n)<0 ? -(n) : (n)) /* @@ -2863,7 +3040,8 @@ SetMachineThinkingEnables() * The return value should be freed with XtFree when no * longer needed. */ -char *FindFont(pattern, targetPxlSize) +char * +FindFont(pattern, targetPxlSize) char *pattern; int targetPxlSize; { @@ -2878,7 +3056,7 @@ char *FindFont(pattern, targetPxlSize) XFontStruct **fnt_list; base_fnt_lst = calloc(1, strlen(pattern) + 3); - sprintf(strInt, "%d", targetPxlSize); + snprintf(strInt, sizeof(strInt)/sizeof(strInt[0]), "%d", targetPxlSize); p = strstr(pattern, "--"); strncpy(base_fnt_lst, pattern, p - pattern + 2); strcat(base_fnt_lst, strInt); @@ -2937,8 +3115,8 @@ char *FindFont(pattern, targetPxlSize) while (isdigit(*scalableTail)) scalableTail++; sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail); } else { - p = (char *) XtMalloc(strlen(best) + 1); - strcpy(p, best); + p = (char *) XtMalloc(strlen(best) + 2); + safeStrCpy(p, best, strlen(best)+1 ); } if (appData.debugMode) { fprintf(debugFP, _("resolved %s at pixel size %d\n to %s\n"), @@ -2954,7 +3132,32 @@ char *FindFont(pattern, targetPxlSize) return p; } -void CreateGCs() +void DeleteGCs() +{ // [HGM] deletes GCs that are to be remade, to prevent resource leak; + // must be called before all non-first callse to CreateGCs() + XtReleaseGC(shellWidget, highlineGC); + XtReleaseGC(shellWidget, lightSquareGC); + XtReleaseGC(shellWidget, darkSquareGC); + XtReleaseGC(shellWidget, lineGC); + if (appData.monoMode) { + if (DefaultDepth(xDisplay, xScreen) == 1) { + XtReleaseGC(shellWidget, wbPieceGC); + } else { + XtReleaseGC(shellWidget, bwPieceGC); + } + } else { + XtReleaseGC(shellWidget, prelineGC); + XtReleaseGC(shellWidget, jailSquareGC); + XtReleaseGC(shellWidget, wdPieceGC); + XtReleaseGC(shellWidget, wlPieceGC); + XtReleaseGC(shellWidget, wjPieceGC); + XtReleaseGC(shellWidget, bdPieceGC); + XtReleaseGC(shellWidget, blPieceGC); + XtReleaseGC(shellWidget, bjPieceGC); + } +} + +void CreateGCs(int redo) { XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground | GCBackground | GCFunction | GCPlaneMask; @@ -2966,20 +3169,23 @@ void CreateGCs() gc_values.line_style = LineSolid; gc_values.function = GXcopy; - gc_values.foreground = XBlackPixel(xDisplay, xScreen); - gc_values.background = XBlackPixel(xDisplay, xScreen); - lineGC = XtGetGC(shellWidget, value_mask, &gc_values); - + if(redo) { + DeleteGCs(); // called a second time; clean up old GCs first + } else { // [HGM] grid and font GCs created on first call only gc_values.foreground = XBlackPixel(xDisplay, xScreen); gc_values.background = XWhitePixel(xDisplay, xScreen); coordGC = XtGetGC(shellWidget, value_mask, &gc_values); XSetFont(xDisplay, coordGC, coordFontID); - // [HGM] make font for holdings counts (white on black0 + // [HGM] make font for holdings counts (white on black) gc_values.foreground = XWhitePixel(xDisplay, xScreen); gc_values.background = XBlackPixel(xDisplay, xScreen); countGC = XtGetGC(shellWidget, value_mask, &gc_values); XSetFont(xDisplay, countGC, countFontID); + } + gc_values.foreground = XBlackPixel(xDisplay, xScreen); + gc_values.background = XBlackPixel(xDisplay, xScreen); + lineGC = XtGetGC(shellWidget, value_mask, &gc_values); if (appData.monoMode) { gc_values.foreground = XWhitePixel(xDisplay, xScreen); @@ -3107,6 +3313,8 @@ void loadXIM(xim, xmask, filename, dest, mask) } } + fclose(fp); + /* create Pixmap of piece */ *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay), w, h, xim->depth); @@ -3227,7 +3435,31 @@ void CreateXIMPieces() XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */ } +static VariantClass oldVariant = (VariantClass) -1; // [HGM] pieces: redo every time variant changes + #if HAVE_LIBXPM +void CreateXPMBoard(char *s, int kind) +{ + XpmAttributes attr; + attr.valuemask = 0; + if(s == NULL || *s == 0 || *s == '*') { useTexture &= ~(kind+1); return; } + if (XpmReadFileToPixmap(xDisplay, xBoardWindow, s, &(xpmBoardBitmap[kind]), NULL, &attr) == 0) { + useTexture |= kind + 1; textureW[kind] = attr.width; textureH[kind] = attr.height; + } +} + +void FreeXPMPieces() +{ // [HGM] to prevent resoucre leak on calling CreaeXPMPieces() a second time, + // thisroutine has to be called t free the old piece pixmaps + int piece, kind; + for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) + for (kind=0; kind<4; kind++) XFreePixmap(xDisplay, xpmPieceBitmap2[kind][piece]); + if(useImageSqs) { + XFreePixmap(xDisplay, xpmLightSquare); + XFreePixmap(xDisplay, xpmDarkSquare); + } +} + void CreateXPMPieces() { int piece, kind, r; @@ -3236,6 +3468,9 @@ void CreateXPMPieces() XpmAttributes attr; static char *xpmkind[] = { "ll", "ld", "dl", "dd" }; XpmColorSymbol symbols[4]; + static int redo = False; + + if(redo) FreeXPMPieces(); else redo = 1; /* The XSynchronize calls were copied from CreatePieces. Not sure if needed, but can't hurt */ @@ -3324,7 +3559,7 @@ void CreateXPMPieces() exit(1); } } - if(piece <= (int) WhiteKing) + if(piece <= (int) WhiteKing) xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece]; } } @@ -3360,6 +3595,7 @@ void CreateXPMPieces() xpmJailSquare = xpmLightSquare; fprintf(stderr, _("Done.\n")); } + oldVariant = -1; // kludge to force re-makig of animation masks XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */ } @@ -3378,12 +3614,12 @@ void CreatePieces() for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) { for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) { - sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "", - pieceBitmapNames[piece], - ss, kind == SOLID ? 's' : 'o'); - ReadBitmap(&pieceBitmap2[kind][piece], buf, NULL, ss, ss); - if(piece <= (int)WhiteKing) - pieceBitmap[kind][piece] = pieceBitmap2[kind][piece]; + snprintf(buf, MSG_SIZ, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "", + pieceBitmapNames[piece], + ss, kind == SOLID ? 's' : 'o'); + ReadBitmap(&pieceBitmap2[kind][piece], buf, NULL, ss, ss); + if(piece <= (int)WhiteKing) + pieceBitmap[kind][piece] = pieceBitmap2[kind][piece]; } } @@ -3406,13 +3642,13 @@ void CreatePieces() for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) { for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) { - sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "", - pieceBitmapNames[piece], - ss, kind == SOLID ? 's' : 'o'); - ReadBitmap(&pieceBitmap2[kind][piece], buf, - bib->bits[kind][piece], ss, ss); - if(piece <= (int)WhiteKing) - pieceBitmap[kind][piece] = pieceBitmap2[kind][piece]; + snprintf(buf, MSG_SIZ, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "", + pieceBitmapNames[piece], + ss, kind == SOLID ? 's' : 'o'); + ReadBitmap(&pieceBitmap2[kind][piece], buf, + bib->bits[kind][piece], ss, ss); + if(piece <= (int)WhiteKing) + pieceBitmap[kind][piece] = pieceBitmap2[kind][piece]; } } @@ -3433,12 +3669,12 @@ void ReadBitmap(pm, name, bits, wreq, hreq) char msg[MSG_SIZ], fullname[MSG_SIZ]; if (*appData.bitmapDirectory != NULLCHAR) { - strcpy(fullname, appData.bitmapDirectory); - strcat(fullname, "/"); - strcat(fullname, name); - errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname, - &w, &h, pm, &x_hot, &y_hot); - fprintf(stderr, "load %s\n", name); + safeStrCpy(fullname, appData.bitmapDirectory, sizeof(fullname)/sizeof(fullname[0]) ); + strncat(fullname, "/", MSG_SIZ - strlen(fullname) - 1); + strncat(fullname, name, MSG_SIZ - strlen(fullname) - 1); + errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname, + &w, &h, pm, &x_hot, &y_hot); + fprintf(stderr, "load %s\n", name); if (errcode != BitmapSuccess) { switch (errcode) { case BitmapOpenFailed: @@ -3528,8 +3764,8 @@ void CreateMenuBarPopup(parent, name, mb) entry = XtCreateManagedWidget(mi->string, smeLineObjectClass, menu, args, j); } else { - XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); - entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass, + XtSetArg(args[j], XtNlabel, XtNewString(mi->string)); + entry = XtCreateManagedWidget(mi->ref, smeBSBObjectClass, menu, args, j+1); XtAddCallback(entry, XtNcallback, (XtCallbackProc) MenuBarSelect, @@ -3555,18 +3791,18 @@ Widget CreateMenuBar(mb) formWidget, args, j); while (mb->name != NULL) { - strcpy(menuName, "menu"); - strcat(menuName, mb->name); + safeStrCpy(menuName, "menu", sizeof(menuName)/sizeof(menuName[0]) ); + strncat(menuName, mb->ref, MSG_SIZ - strlen(menuName) - 1); j = 0; XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++; if (tinyLayout) { char shortName[2]; - shortName[0] = _(mb->name)[0]; + shortName[0] = mb->name[0]; shortName[1] = NULLCHAR; XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++; } else { - XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++; + XtSetArg(args[j], XtNlabel, XtNewString(mb->name)); j++; } XtSetArg(args[j], XtNborderWidth, 0); j++; @@ -3715,8 +3951,9 @@ void PieceMenuPopup(w, event, params, num_params) Cardinal *num_params; { String whichMenu; int menuNr; + shiftKey = strcmp(params[0], "menuW"); // used to indicate black if (event->type == ButtonRelease) - menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY); + menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY); else if (event->type == ButtonPress) menuNr = RightClick(Press, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY); switch(menuNr) { @@ -3753,11 +3990,7 @@ void WhiteClock(w, event, prms, nprms) String *prms; Cardinal *nprms; { - if (gameMode == EditPosition || gameMode == IcsExamining) { - SetWhiteToPlayEvent(); - } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) { - CallFlagEvent(); - } + ClockClick(0); } void BlackClock(w, event, prms, nprms) @@ -3766,11 +3999,7 @@ void BlackClock(w, event, prms, nprms) String *prms; Cardinal *nprms; { - if (gameMode == EditPosition || gameMode == IcsExamining) { - SetBlackToPlayEvent(); - } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) { - CallFlagEvent(); - } + ClockClick(1); } @@ -3806,7 +4035,7 @@ static void drawHighlight(file, rank, gc) { int x, y; - if (lineGap == 0 || appData.blindfold) return; + if (lineGap == 0) return; if (flipView) { x = lineGap/2 + ((BOARD_WIDTH-1)-file) * @@ -3894,11 +4123,34 @@ ClearPremoveHighlights() SetPremoveHighlights(-1, -1, -1, -1); } -static void BlankSquare(x, y, color, piece, dest) - int x, y, color; +static int CutOutSquare(x, y, x0, y0, kind) + int x, y, *x0, *y0, kind; +{ + int W = BOARD_WIDTH, H = BOARD_HEIGHT; + int nx = x/(squareSize + lineGap), ny = y/(squareSize + lineGap); + *x0 = 0; *y0 = 0; + if(textureW[kind] < squareSize || textureH[kind] < squareSize) return 0; + if(textureW[kind] < W*squareSize) + *x0 = (textureW[kind] - squareSize) * nx/(W-1); + else + *x0 = textureW[kind]*nx / W + (textureW[kind] - W*squareSize) / (2*W); + if(textureH[kind] < H*squareSize) + *y0 = (textureH[kind] - squareSize) * ny/(H-1); + else + *y0 = textureH[kind]*ny / H + (textureH[kind] - H*squareSize) / (2*H); + return 1; +} + +static void BlankSquare(x, y, color, piece, dest, fac) + int x, y, color, fac; ChessSquare piece; Drawable dest; -{ +{ // [HGM] extra param 'fac' for forcing destination to (0,0) for copying to animation buffer + int x0, y0; + if (useImages && color != 2 && (useTexture & color+1) && CutOutSquare(x, y, &x0, &y0, color)) { + XCopyArea(xDisplay, xpmBoardBitmap[color], dest, wlPieceGC, x0, y0, + squareSize, squareSize, x*fac, y*fac); + } else if (useImages && useImageSqs) { Pixmap pm; switch (color) { @@ -3914,7 +4166,7 @@ static void BlankSquare(x, y, color, piece, dest) break; } XCopyArea(xDisplay, pm, dest, wlPieceGC, 0, 0, - squareSize, squareSize, x, y); + squareSize, squareSize, x*fac, y*fac); } else { GC gc; switch (color) { @@ -3929,7 +4181,7 @@ static void BlankSquare(x, y, color, piece, dest) gc = jailSquareGC; break; } - XFillRectangle(xDisplay, dest, gc, x, y, squareSize, squareSize); + XFillRectangle(xDisplay, dest, gc, x*fac, y*fac, squareSize, squareSize); } } @@ -4022,7 +4274,7 @@ static void colorDrawPieceImage(piece, square_color, x, y, dest) int square_color, x, y; Drawable dest; { - int kind; + int kind, p = piece; switch (square_color) { case 1: /* light */ @@ -4044,6 +4296,15 @@ static void colorDrawPieceImage(piece, square_color, x, y, dest) } break; } + if(appData.upsideDown && flipView) { kind ^= 2; p += p < BlackPawn ? BlackPawn : -BlackPawn; }// swap white and black pieces + if(useTexture & square_color+1) { + BlankSquare(x, y, square_color, piece, dest, 1); // erase previous contents with background + XSetClipMask(xDisplay, wlPieceGC, xpmMask[p]); + XSetClipOrigin(xDisplay, wlPieceGC, x, y); + XCopyArea(xDisplay, xpmPieceBitmap[kind][piece], dest, wlPieceGC, 0, 0, squareSize, squareSize, x, y); + XSetClipMask(xDisplay, wlPieceGC, None); + XSetClipOrigin(xDisplay, wlPieceGC, 0, 0); + } else XCopyArea(xDisplay, xpmPieceBitmap[kind][piece], dest, wlPieceGC, 0, 0, squareSize, squareSize, x, y); @@ -4117,13 +4378,15 @@ void DrawSquare(row, column, piece, do_flash) (squareSize + lineGap); } + if(twoBoards && partnerUp) x += hOffset; // [HGM] dual: draw second board + square_color = SquareColor(row, column); if ( // [HGM] holdings: blank out area between board and holdings column == BOARD_LEFT-1 || column == BOARD_RGHT || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize) || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) ) { - BlankSquare(x, y, 2, EmptySquare, xBoardWindow); + BlankSquare(x, y, 2, EmptySquare, xBoardWindow, 1); // [HGM] print piece counts next to holdings string[1] = NULLCHAR; @@ -4155,17 +4418,17 @@ void DrawSquare(row, column, piece, do_flash) } } else { if (piece == EmptySquare || appData.blindfold) { - BlankSquare(x, y, square_color, piece, xBoardWindow); + BlankSquare(x, y, square_color, piece, xBoardWindow, 1); } else { drawfunc = ChooseDrawFunc(); + if (do_flash && appData.flashCount > 0) { for (i=0; ixexpose.count > 0) return; /* no clipping is done */ XDrawPosition(widget, True, NULL); + if(twoBoards) { // [HGM] dual: draw other board in other orientation + flipView = !flipView; partnerUp = !partnerUp; + XDrawPosition(widget, True, NULL); + flipView = !flipView; partnerUp = !partnerUp; + } break; + case MotionNotify: + if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break; default: return; } @@ -4252,7 +4522,6 @@ static int too_many_diffs(b1, b2) } } } - return 0; } @@ -4303,7 +4572,37 @@ static int check_castle_draw(newb, oldb, rrow, rcol) return 0; } -static int damage[BOARD_RANKS][BOARD_FILES]; +// [HGM] seekgraph: some low-level drawing routines cloned from xevalgraph +void DrawSeekAxis( int x, int y, int xTo, int yTo ) +{ + XDrawLine(xDisplay, xBoardWindow, lineGC, x, y, xTo, yTo); +} + +void DrawSeekBackground( int left, int top, int right, int bottom ) +{ + XFillRectangle(xDisplay, xBoardWindow, lightSquareGC, left, top, right-left, bottom-top); +} + +void DrawSeekText(char *buf, int x, int y) +{ + XDrawString(xDisplay, xBoardWindow, coordGC, x, y+4, buf, strlen(buf)); +} + +void DrawSeekDot(int x, int y, int colorNr) +{ + int square = colorNr & 0x80; + GC color; + colorNr &= 0x7F; + color = colorNr == 0 ? prelineGC : colorNr == 1 ? darkSquareGC : highlineGC; + if(square) + XFillRectangle(xDisplay, xBoardWindow, color, + x-squareSize/9, y-squareSize/9, 2*squareSize/9, 2*squareSize/9); + else + XFillArc(xDisplay, xBoardWindow, color, + x-squareSize/8, y-squareSize/8, squareSize/4, squareSize/4, 0, 64*360); +} + +static int damage[2][BOARD_RANKS][BOARD_FILES]; /* * event handler for redrawing the board @@ -4315,18 +4614,21 @@ void XDrawPosition(w, repaint, board) { int i, j, do_flash; static int lastFlipView = 0; - static int lastBoardValid = 0; - static Board lastBoard; + static int lastBoardValid[2] = {0, 0}; + static Board lastBoard[2]; Arg args[16]; int rrow, rcol; + int nr = twoBoards*partnerUp; + + if(DrawSeekGraph()) return; // [HGM] seekgraph: suppress any drawing if seek graph up if (board == NULL) { - if (!lastBoardValid) return; - board = lastBoard; + if (!lastBoardValid[nr]) return; + board = lastBoard[nr]; } - if (!lastBoardValid || lastFlipView != flipView) { + if (!lastBoardValid[nr] || (nr == 0 && lastFlipView != flipView)) { XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None)); - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Flip View"), args, 1); } @@ -4335,19 +4637,23 @@ void XDrawPosition(w, repaint, board) * but this causes a very distracting flicker. */ - if (!repaint && lastBoardValid && lastFlipView == flipView) { + if (!repaint && lastBoardValid[nr] && (nr == 1 || lastFlipView == flipView)) { + + if ( lineGap && IsDrawArrowEnabled()) + XDrawSegments(xDisplay, xBoardWindow, lineGC, + gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2); /* If too much changes (begin observing new game, etc.), don't do flashing */ - do_flash = too_many_diffs(board, lastBoard) ? 0 : 1; + do_flash = too_many_diffs(board, lastBoard[nr]) ? 0 : 1; /* Special check for castling so we don't flash both the king and the rook (just flash the king). */ if (do_flash) { - if (check_castle_draw(board, lastBoard, &rrow, &rcol)) { + if (check_castle_draw(board, lastBoard[nr], &rrow, &rcol)) { /* Draw rook with NO flashing. King will be drawn flashing later */ DrawSquare(rrow, rcol, board[rrow][rcol], 0); - lastBoard[rrow][rcol] = board[rrow][rcol]; + lastBoard[nr][rrow][rcol] = board[rrow][rcol]; } } @@ -4356,32 +4662,34 @@ void XDrawPosition(w, repaint, board) is flashing on its new square */ for (i = 0; i < BOARD_HEIGHT; i++) for (j = 0; j < BOARD_WIDTH; j++) - if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare) - || damage[i][j]) { + if ((board[i][j] != lastBoard[nr][i][j] && board[i][j] == EmptySquare) + || damage[nr][i][j]) { DrawSquare(i, j, board[i][j], 0); - damage[i][j] = False; + damage[nr][i][j] = False; } /* Second pass -- Draw piece(s) in new position and flash them */ for (i = 0; i < BOARD_HEIGHT; i++) for (j = 0; j < BOARD_WIDTH; j++) - if (board[i][j] != lastBoard[i][j]) { + if (board[i][j] != lastBoard[nr][i][j]) { DrawSquare(i, j, board[i][j], do_flash); } } else { if (lineGap > 0) XDrawSegments(xDisplay, xBoardWindow, lineGC, + twoBoards & partnerUp ? secondSegments : // [HGM] dual gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2); for (i = 0; i < BOARD_HEIGHT; i++) for (j = 0; j < BOARD_WIDTH; j++) { DrawSquare(i, j, board[i][j], 0); - damage[i][j] = False; + damage[nr][i][j] = False; } } - CopyBoard(lastBoard, board); - lastBoardValid = 1; + CopyBoard(lastBoard[nr], board); + lastBoardValid[nr] = 1; + if(nr == 0) { // [HGM] dual: no highlights on second board yet lastFlipView = flipView; /* Draw highlights */ @@ -4397,7 +4705,8 @@ void XDrawPosition(w, repaint, board) if (hi2X >= 0 && hi2Y >= 0) { drawHighlight(hi2X, hi2Y, highlineGC); } - + DrawArrowHighlight(hi1X, hi1Y, hi2X, hi2Y); + } /* If piece being dragged around board, must redraw that too */ DrawDragPiece(); @@ -4435,6 +4744,7 @@ void HandleUserMove(w, event, prms, nprms) Cardinal *nprms; { if (w != boardWidget || errorExitStatus != -1) return; + if(nprms) shiftKey = !strcmp(prms[0], "1"); if (promotionUp) { if (event->type == ButtonPress) { @@ -4465,387 +4775,38 @@ void HandlePV (Widget w, XEvent * event, MovePV(event->xmotion.x, event->xmotion.y, lineGap + BOARD_HEIGHT * (squareSize + lineGap)); } -Widget CommentCreate(name, text, mutable, callback, lines) - char *name, *text; - int /*Boolean*/ mutable; - XtCallbackProc callback; - int lines; -{ - Arg args[16]; - Widget shell, layout, form, edit, b_ok, b_cancel, b_clear, b_close, b_edit; - Dimension bw_width; - int j; - - j = 0; - XtSetArg(args[j], XtNwidth, &bw_width); j++; - XtGetValues(boardWidget, args, j); - - j = 0; - XtSetArg(args[j], XtNresizable, True); j++; -#if TOPLEVEL - shell = - XtCreatePopupShell(name, topLevelShellWidgetClass, - shellWidget, args, j); -#else - shell = - XtCreatePopupShell(name, transientShellWidgetClass, - shellWidget, args, j); -#endif - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, shell, - layoutArgs, XtNumber(layoutArgs)); - form = - XtCreateManagedWidget("form", formWidgetClass, layout, - formArgs, XtNumber(formArgs)); - - j = 0; - if (mutable) { - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - } - XtSetArg(args[j], XtNstring, text); 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*/ - /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */ - XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++; - XtSetArg(args[j], XtNautoFill, True); j++; - XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++; - edit = - XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j); - - if (mutable) { - j = 0; - XtSetArg(args[j], XtNfromVert, edit); 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++; - b_ok = - XtCreateManagedWidget(_("ok"), commandWidgetClass, form, args, j); - XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0); - - j = 0; - XtSetArg(args[j], XtNfromVert, edit); j++; - XtSetArg(args[j], XtNfromHoriz, b_ok); 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++; - b_cancel = - XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j); - XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0); - - j = 0; - XtSetArg(args[j], XtNfromVert, edit); j++; - XtSetArg(args[j], XtNfromHoriz, b_cancel); 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++; - b_clear = - XtCreateManagedWidget(_("clear"), commandWidgetClass, form, args, j); - XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0); - } else { - j = 0; - XtSetArg(args[j], XtNfromVert, edit); 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++; - b_close = - XtCreateManagedWidget(_("close"), commandWidgetClass, form, args, j); - XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0); - - j = 0; - XtSetArg(args[j], XtNfromVert, edit); j++; - XtSetArg(args[j], XtNfromHoriz, b_close); 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++; - b_edit = - XtCreateManagedWidget(_("edit"), commandWidgetClass, form, args, j); - XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0); - } - - XtRealizeWidget(shell); - - if (commentX == -1) { - int xx, yy; - Window junk; - Dimension pw_height; - Dimension ew_height; - - 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); - commentH = pw_height + (lines - 1) * ew_height; - commentW = bw_width - 16; - - 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 - commentW) / 2, 0 - commentH / 2, - &commentX, &commentY); -#else /*!NOTDEF*/ - XTranslateCoordinates(xDisplay, XtWindow(shellWidget), - RootWindowOfScreen(XtScreen(shellWidget)), - (bw_width - commentW) / 2, 0 - commentH / 2, - &xx, &yy, &junk); - commentX = xx; - commentY = yy; -#endif /*!NOTDEF*/ - if (commentY < 0) commentY = 0; /*avoid positioning top offscreen*/ - } - - if(wpComment.width > 0) { - commentX = wpComment.x; - commentY = wpComment.y; - commentW = wpComment.width; - commentH = wpComment.height; - } - - j = 0; - XtSetArg(args[j], XtNheight, commentH); j++; - XtSetArg(args[j], XtNwidth, commentW); j++; - XtSetArg(args[j], XtNx, commentX); j++; - XtSetArg(args[j], XtNy, commentY); j++; - XtSetValues(shell, args, j); - XtSetKeyboardFocus(shell, edit); - - return shell; -} +static int savedIndex; /* gross that this is global */ -/* Used for analysis window and ICS input window */ -Widget MiscCreate(name, text, mutable, callback, lines) - char *name, *text; - int /*Boolean*/ mutable; - XtCallbackProc callback; - int lines; +void CommentClick (Widget w, XEvent * event, String * params, Cardinal * nParams) { - Arg args[16]; - Widget shell, layout, form, edit; - Position x, y; - Dimension bw_width, pw_height, ew_height, w, h; - int j; - int xx, yy; - Window junk; - - j = 0; - XtSetArg(args[j], XtNresizable, True); j++; -#if TOPLEVEL - shell = - XtCreatePopupShell(name, topLevelShellWidgetClass, - shellWidget, args, j); -#else - shell = - XtCreatePopupShell(name, transientShellWidgetClass, - shellWidget, args, j); -#endif - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, shell, - layoutArgs, XtNumber(layoutArgs)); - form = - XtCreateManagedWidget("form", formWidgetClass, layout, - formArgs, XtNumber(formArgs)); + String val; + XawTextPosition index, dummy; + Arg arg; - j = 0; - if (mutable) { - XtSetArg(args[j], XtNeditType, XawtextEdit); j++; - XtSetArg(args[j], XtNuseStringInPlace, False); j++; - } - XtSetArg(args[j], XtNstring, text); 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++; - /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */ - XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++; - XtSetArg(args[j], XtNautoFill, True); j++; - XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++; - edit = - XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j); - - XtRealizeWidget(shell); - - j = 0; - XtSetArg(args[j], XtNwidth, &bw_width); j++; - XtGetValues(boardWidget, args, j); - - 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); - h = pw_height + (lines - 1) * ew_height; - w = bw_width - 16; - - 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 - w) / 2, 0 - h / 2, &x, &y); -#else /*!NOTDEF*/ - XTranslateCoordinates(xDisplay, XtWindow(shellWidget), - RootWindowOfScreen(XtScreen(shellWidget)), - (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk); -#endif /*!NOTDEF*/ - x = xx; - y = yy; - if (y < 0) y = 0; /*avoid positioning top offscreen*/ - - j = 0; - XtSetArg(args[j], XtNheight, h); j++; - XtSetArg(args[j], XtNwidth, w); j++; - XtSetArg(args[j], XtNx, x); j++; - XtSetArg(args[j], XtNy, y); j++; - XtSetValues(shell, args, j); - - return shell; + XawTextGetSelectionPos(w, &index, &dummy); + XtSetArg(arg, XtNstring, &val); + XtGetValues(w, &arg, 1); + ReplaceComment(savedIndex, val); + if(savedIndex != currentMove) ToNrEvent(savedIndex); + LoadVariation( index, val ); // [HGM] also does the actual moving to it, now } - -static int savedIndex; /* gross that this is global */ - void EditCommentPopUp(index, title, text) int index; char *title, *text; { - Widget edit; - Arg args[16]; - int j; - savedIndex = index; if (text == NULL) text = ""; - - if (editShell == NULL) { - editShell = - CommentCreate(title, text, True, EditCommentCallback, 4); - XtRealizeWidget(editShell); - CatchDeleteWindow(editShell, "EditCommentPopDown"); - } else { - edit = XtNameToWidget(editShell, "*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(editShell, args, j); - } - - XtPopup(editShell, XtGrabNone); - - editUp = True; - j = 0; - XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"), - args, j); -} - -void EditCommentCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name, val; - Arg args[16]; - int j; - Widget edit; - - j = 0; - XtSetArg(args[j], XtNlabel, &name); j++; - XtGetValues(w, args, j); - - if (strcmp(name, _("ok")) == 0) { - edit = XtNameToWidget(editShell, "*form.text"); - j = 0; - XtSetArg(args[j], XtNstring, &val); j++; - XtGetValues(edit, args, j); - ReplaceComment(savedIndex, val); - EditCommentPopDown(); - } else if (strcmp(name, _("cancel")) == 0) { - EditCommentPopDown(); - } else if (strcmp(name, _("clear")) == 0) { - edit = XtNameToWidget(editShell, "*form.text"); - XtCallActionProc(edit, "select-all", NULL, NULL, 0); - XtCallActionProc(edit, "kill-selection", NULL, NULL, 0); - } -} - -void EditCommentPopDown() -{ - Arg args[16]; - int j; - - if (!editUp) return; - j = 0; - XtSetArg(args[j], XtNx, &commentX); j++; - XtSetArg(args[j], XtNy, &commentY); j++; - XtSetArg(args[j], XtNheight, &commentH); j++; - XtSetArg(args[j], XtNwidth, &commentW); j++; - XtGetValues(editShell, args, j); - XtPopdown(editShell); - editUp = False; - j = 0; - XtSetArg(args[j], XtNleftBitmap, None); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"), - args, j); + NewCommentPopup(title, text, index); } void ICSInputBoxPopUp() { - Widget edit; - Arg args[16]; - int j; - char *title = _("ICS Input"); - XtTranslations tr; - - if (ICSInputShell == NULL) { - ICSInputShell = MiscCreate(title, "", True, NULL, 1); - tr = XtParseTranslationTable(ICSInputTranslations); - edit = XtNameToWidget(ICSInputShell, "*form.text"); - XtOverrideTranslations(edit, tr); - XtRealizeWidget(ICSInputShell); - CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown"); - - } else { - edit = XtNameToWidget(ICSInputShell, "*form.text"); - j = 0; - XtSetArg(args[j], XtNstring, ""); j++; - XtSetValues(edit, args, j); - j = 0; - XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++; - XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++; - XtSetValues(ICSInputShell, args, j); - } - - XtPopup(ICSInputShell, XtGrabNone); - XtSetKeyboardFocus(ICSInputShell, edit); - - ICSInputBoxUp = True; - j = 0; - XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"), - args, j); + InputBoxPopup(); } +extern Option boxOptions[]; + void ICSInputSendText() { Widget edit; @@ -4853,10 +4814,11 @@ void ICSInputSendText() Arg args[16]; String val; - edit = XtNameToWidget(ICSInputShell, "*form.text"); + edit = boxOptions[0].handle; j = 0; XtSetArg(args[j], XtNstring, &val); j++; XtGetValues(edit, args, j); + SaveInHistory(val); SendMultiLineToICS(val); XtCallActionProc(edit, "select-all", NULL, NULL, 0); XtCallActionProc(edit, "kill-selection", NULL, NULL, 0); @@ -4864,140 +4826,38 @@ void ICSInputSendText() void ICSInputBoxPopDown() { - Arg args[16]; - int j; - - if (!ICSInputBoxUp) return; - j = 0; - XtPopdown(ICSInputShell); - ICSInputBoxUp = False; - j = 0; - XtSetArg(args[j], XtNleftBitmap, None); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"), - args, j); + PopDown(4); } void CommentPopUp(title, text) char *title, *text; { - Arg args[16]; - int j; - Widget edit; - - if (commentShell == NULL) { - commentShell = - CommentCreate(title, text, False, CommentCallback, 4); - XtRealizeWidget(commentShell); - CatchDeleteWindow(commentShell, "CommentPopDown"); - } else { - edit = XtNameToWidget(commentShell, "*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(commentShell, args, j); - } - - XtPopup(commentShell, XtGrabNone); - XSync(xDisplay, False); - - commentUp = True; + savedIndex = currentMove; // [HGM] vari + NewCommentPopup(title, text, currentMove); } -void CommentCallback(w, client_data, call_data) - Widget w; - XtPointer client_data, call_data; -{ - String name; - Arg args[16]; - int j; - - j = 0; - XtSetArg(args[j], XtNlabel, &name); j++; - XtGetValues(w, args, j); - - if (strcmp(name, _("close")) == 0) { - CommentPopDown(); - } else if (strcmp(name, _("edit")) == 0) { - CommentPopDown(); - EditCommentEvent(); - } -} - - void CommentPopDown() { - Arg args[16]; - int j; - - if (!commentUp) return; - j = 0; - XtSetArg(args[j], XtNx, &commentX); j++; - XtSetArg(args[j], XtNy, &commentY); j++; - XtSetArg(args[j], XtNwidth, &commentW); j++; - XtSetArg(args[j], XtNheight, &commentH); j++; - XtGetValues(commentShell, args, j); - XtPopdown(commentShell); - XSync(xDisplay, False); - commentUp = False; + PopDown(1); } -void FileNamePopUp(label, def, proc, openMode) +void FileNamePopUp(label, def, filter, proc, openMode) char *label; char *def; + char *filter; FileProc proc; char *openMode; { - Arg args[16]; - Widget popup, layout, dialog, edit; - Window root, child; - int x, y, i; - int win_x, win_y; - unsigned int mask; - fileProc = proc; /* I can't see a way not */ fileOpenMode = openMode; /* to use globals here */ - - i = 0; - XtSetArg(args[i], XtNresizable, True); i++; - XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++; - XtSetArg(args[i], XtNtitle, XtNewString(_("File name prompt"))); i++; - fileNameShell = popup = - XtCreatePopupShell("File name prompt", transientShellWidgetClass, - shellWidget, args, i); - - layout = - XtCreateManagedWidget(layoutName, formWidgetClass, popup, - layoutArgs, XtNumber(layoutArgs)); - - i = 0; - XtSetArg(args[i], XtNlabel, label); i++; - XtSetArg(args[i], XtNvalue, def); i++; - XtSetArg(args[i], XtNborderWidth, 0); i++; - dialog = XtCreateManagedWidget("fileName", dialogWidgetClass, - layout, args, i); - - XawDialogAddButton(dialog, _("ok"), FileNameCallback, (XtPointer) dialog); - XawDialogAddButton(dialog, _("cancel"), FileNameCallback, - (XtPointer) dialog); - - XtRealizeWidget(popup); - CatchDeleteWindow(popup, "FileNamePopDown"); - - 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); - filenameUp = True; - - edit = XtNameToWidget(dialog, "*value"); - XtSetKeyboardFocus(popup, edit); + { // [HGM] use file-selector dialog stolen from Ghostview + char *name; + int index; // this is not supported yet + FILE *f; + if(f = XsraSelFile(shellWidget, label, NULL, NULL, "could not open: ", + (def[0] ? def : NULL), filter, openMode, NULL, &name)) + (void) (*fileProc)(f, index=0, name); + } } void FileNamePopDown() @@ -5042,7 +4902,7 @@ void FileNameAction(w, event, prms, nprms) name = XawDialogGetValueString(w = XtParent(w)); if ((name != NULL) && (*name != NULLCHAR)) { - strcpy(buf, name); + safeStrCpy(buf, name, sizeof(buf)/sizeof(buf[0]) ); XtPopdown(w = XtParent(XtParent(w))); XtDestroyWidget(w); filenameUp = False; @@ -5105,6 +4965,16 @@ void PromotionPopUp() layout, args, j); if(gameInfo.variant != VariantShogi) { + if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) { + XawDialogAddButton(dialog, _("Warlord"), PromotionCallback, + (XtPointer) dialog); + XawDialogAddButton(dialog, _("General"), PromotionCallback, + (XtPointer) dialog); + XawDialogAddButton(dialog, _("Lieutenant"), PromotionCallback, + (XtPointer) dialog); + XawDialogAddButton(dialog, _("Captain"), PromotionCallback, + (XtPointer) dialog); + } else { XawDialogAddButton(dialog, _("Queen"), PromotionCallback, (XtPointer) dialog); XawDialogAddButton(dialog, _("Rook"), PromotionCallback, @@ -5113,13 +4983,15 @@ void PromotionPopUp() (XtPointer) dialog); XawDialogAddButton(dialog, _("Knight"), PromotionCallback, (XtPointer) dialog); + } if (!appData.testLegality || gameInfo.variant == VariantSuicide || + gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove) || gameInfo.variant == VariantGiveaway) { XawDialogAddButton(dialog, _("King"), PromotionCallback, (XtPointer) dialog); } - if(gameInfo.variant == VariantCapablanca || - gameInfo.variant == VariantGothic || + if(gameInfo.variant == VariantCapablanca || + gameInfo.variant == VariantGothic || gameInfo.variant == VariantCapaRandom) { XawDialogAddButton(dialog, _("Archbishop"), PromotionCallback, (XtPointer) dialog); @@ -5447,7 +5319,7 @@ void LoadGameProc(w, event, prms, nprms) if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) { Reset(FALSE, TRUE); } - FileNamePopUp(_("Load game file name?"), "", LoadGamePopUp, "rb"); + FileNamePopUp(_("Load game file name?"), "", ".pgn .game", LoadGamePopUp, "rb"); } void LoadNextGameProc(w, event, prms, nprms) @@ -5513,7 +5385,7 @@ void LoadPositionProc(w, event, prms, nprms) if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) { Reset(FALSE, TRUE); } - FileNamePopUp(_("Load position file name?"), "", LoadPosition, "rb"); + FileNamePopUp(_("Load position file name?"), "", ".fen .epd .pos", LoadPosition, "rb"); } void SaveGameProc(w, event, prms, nprms) @@ -5524,6 +5396,7 @@ void SaveGameProc(w, event, prms, nprms) { FileNamePopUp(_("Save game file name?"), DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"), + appData.oldSaveStyle ? ".game" : ".pgn", SaveGame, "a"); } @@ -5535,6 +5408,7 @@ void SavePositionProc(w, event, prms, nprms) { FileNamePopUp(_("Save position file name?"), DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"), + appData.oldSaveStyle ? ".pos" : ".fen", SavePosition, "a"); } @@ -5572,7 +5446,7 @@ SendPositionSelection(Widget w, Atom *selection, Atom *target, * automatically call XtFree on the value returned. So have to * make a copy of it allocated with XtMalloc */ selection_tmp= XtMalloc(strlen(selected_fen_position)+16); - strcpy(selection_tmp, selected_fen_position); + safeStrCpy(selection_tmp, selected_fen_position, strlen(selected_fen_position)+16 ); *value_return=selection_tmp; *length_return=strlen(selection_tmp); @@ -5647,7 +5521,7 @@ void PastePositionProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - XtGetSelectionValue(menuBarWidget, + XtGetSelectionValue(menuBarWidget, appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING, /* (XtSelectionCallbackProc) */ PastePositionCB, NULL, /* client_data passed to PastePositionCB */ @@ -5677,6 +5551,7 @@ SendGameSelection(Widget w, Atom *selection, Atom *target, rewind(f); selection_tmp = XtMalloc(len + 1); count = fread(selection_tmp, 1, len, f); + fclose(f); if (len != count) { XtFree(selection_tmp); return False; @@ -5837,7 +5712,7 @@ void AnalyzeModeProc(w, event, prms, nprms) /* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */ if (appData.icsActive) { if (gameMode != IcsObserving) { - sprintf(buf,_("You are not observing a game")); + snprintf(buf, MSG_SIZ, _("You are not observing a game")); DisplayError(buf, 0); /* secure check */ if (appData.icsEngineAnalyze) { @@ -5858,8 +5733,10 @@ void AnalyzeModeProc(w, event, prms, nprms) if (appData.debugMode) fprintf(debugFP, _("ICS engine analyze starting... \n")); } +#ifndef OPTIONSDIALOG if (!appData.showThinking) ShowThinkingProc(w,event,prms,nprms); +#endif AnalyzeModeEvent(); } @@ -5877,12 +5754,12 @@ void AnalyzeFileProc(w, event, prms, nprms) return; } Reset(FALSE, TRUE); - +#ifndef OPTIONSDIALOG if (!appData.showThinking) ShowThinkingProc(w,event,prms,nprms); - +#endif AnalyzeFileEvent(); - FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb"); + FileNamePopUp(_("File to analyze"), "", ".pgn .game", LoadGamePopUp, "rb"); AnalysisPeriodicEvent(1); } @@ -5895,6 +5772,20 @@ void TwoMachinesProc(w, event, prms, nprms) TwoMachinesEvent(); } +void MatchProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + if(gameMode != BeginningOfGame) { DisplayError(_("You can only start a match from the initial position."), 0); return; } + matchMode = 2; // This is back-end, really + appData.matchGames = appData.defaultMatchGames; + matchGame = 1; + first.matchWins = second.matchWins = 0; + TwoMachinesEvent(); +} + void IcsClientProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -5937,11 +5828,15 @@ void EditCommentProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - if (editUp) { - EditCommentPopDown(); - } else { + Arg args[5]; + int j; + if (PopDown(1)) { // popdown succesful + j = 0; + XtSetArg(args[j], XtNleftBitmap, None); j++; + XtSetValues(XtNameToWidget(menuBarWidget, "menuEdit.Edit Comment"), args, j); + XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Comments"), args, j); + } else // was not up EditCommentEvent(); - } } void IcsInputBoxProc(w, event, prms, nprms) @@ -5950,11 +5845,7 @@ void IcsInputBoxProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - if (ICSInputBoxUp) { - ICSInputBoxPopDown(); - } else { - ICSInputBoxPopUp(); - } + if (!PopDown(4)) ICSInputBoxPopUp(); } void AcceptProc(w, event, prms, nprms) @@ -6062,10 +5953,59 @@ void EnterKeyProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - if (ICSInputBoxUp == True) + if (shellUp[4] == True) ICSInputSendText(); } +void UpKeyProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ // [HGM] input: let up-arrow recall previous line from history + Widget edit; + int j; + Arg args[16]; + String val; + XawTextBlock t; + + if (!shellUp[4]) return; + edit = boxOptions[0].handle; + j = 0; + XtSetArg(args[j], XtNstring, &val); j++; + XtGetValues(edit, args, j); + val = PrevInHistory(val); + XtCallActionProc(edit, "select-all", NULL, NULL, 0); + XtCallActionProc(edit, "kill-selection", NULL, NULL, 0); + if(val) { + t.ptr = val; t.firstPos = 0; t.length = strlen(val); t.format = XawFmt8Bit; + XawTextReplace(edit, 0, 0, &t); + XawTextSetInsertionPoint(edit, 9999); + } +} + +void DownKeyProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ // [HGM] input: let down-arrow recall next line from history + Widget edit; + String val; + XawTextBlock t; + + if (!shellUp[4]) return; + edit = boxOptions[0].handle; + val = NextInHistory(); + XtCallActionProc(edit, "select-all", NULL, NULL, 0); + XtCallActionProc(edit, "kill-selection", NULL, NULL, 0); + if(val) { + t.ptr = val; t.firstPos = 0; t.length = strlen(val); t.format = XawFmt8Bit; + XawTextReplace(edit, 0, 0, &t); + XawTextSetInsertionPoint(edit, 9999); + } +} + void StopObservingProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6084,6 +6024,15 @@ void StopExaminingProc(w, event, prms, nprms) StopExaminingEvent(); } +void UploadProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + UploadGameEvent(); +} + void ForwardProc(w, event, prms, nprms) Widget w; @@ -6128,7 +6077,16 @@ void RevertProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - RevertEvent(); + RevertEvent(False); +} + +void AnnotateProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + RevertEvent(True); } void TruncateGameProc(w, event, prms, nprms) @@ -6157,8 +6115,17 @@ void MoveNowProc(w, event, prms, nprms) MoveNowEvent(); } +void FlipViewProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + flipView = !flipView; + DrawPosition(True, NULL); +} -void AlwaysQueenProc(w, event, prms, nprms) +void PonderNextMoveProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6166,18 +6133,20 @@ void AlwaysQueenProc(w, event, prms, nprms) { Arg args[16]; - appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen; - - if (appData.alwaysPromoteToQueen) { + PonderNextMoveEvent(!appData.ponderNextMove); +#ifndef OPTIONSDIALOG + if (appData.ponderNextMove) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); } else { XtSetArg(args[0], XtNleftBitmap, None); } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"), args, 1); +#endif } -void AnimateDraggingProc(w, event, prms, nprms) +#ifndef OPTIONSDIALOG +void AlwaysQueenProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6185,19 +6154,18 @@ void AnimateDraggingProc(w, event, prms, nprms) { Arg args[16]; - appData.animateDragging = !appData.animateDragging; + appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen; - if (appData.animateDragging) { + if (appData.alwaysPromoteToQueen) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - CreateAnimVars(); } else { XtSetArg(args[0], XtNleftBitmap, None); } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"), args, 1); } -void AnimateMovingProc(w, event, prms, nprms) +void AnimateDraggingProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6205,19 +6173,19 @@ void AnimateMovingProc(w, event, prms, nprms) { Arg args[16]; - appData.animate = !appData.animate; + appData.animateDragging = !appData.animateDragging; - if (appData.animate) { + if (appData.animateDragging) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); CreateAnimVars(); } else { XtSetArg(args[0], XtNleftBitmap, None); } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"), args, 1); } -void AutocommProc(w, event, prms, nprms) +void AnimateMovingProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6225,18 +6193,18 @@ void AutocommProc(w, event, prms, nprms) { Arg args[16]; - appData.autoComment = !appData.autoComment; + appData.animate = !appData.animate; - if (appData.autoComment) { + if (appData.animate) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); + CreateAnimVars(); } else { XtSetArg(args[0], XtNleftBitmap, None); } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"), args, 1); } - void AutoflagProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6275,63 +6243,6 @@ void AutoflipProc(w, event, prms, nprms) args, 1); } -void AutobsProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - appData.autoObserve = !appData.autoObserve; - - if (appData.autoObserve) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"), - args, 1); -} - -void AutoraiseProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - appData.autoRaiseBoard = !appData.autoRaiseBoard; - - if (appData.autoRaiseBoard) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Raise Board"), - args, 1); -} - -void AutosaveProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - appData.autoSaveGames = !appData.autoSaveGames; - - if (appData.autoSaveGames) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"), - args, 1); -} - void BlindfoldProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6396,17 +6307,8 @@ void FlashMovesProc(w, event, prms, nprms) args, 1); } -void FlipViewProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - flipView = !flipView; - DrawPosition(True, NULL); -} - -void GetMoveListProc(w, event, prms, nprms) +#if HIGHDRAG +void HighlightDraggingProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6414,20 +6316,19 @@ void GetMoveListProc(w, event, prms, nprms) { Arg args[16]; - appData.getMoveList = !appData.getMoveList; + appData.highlightDragging = !appData.highlightDragging; - if (appData.getMoveList) { + if (appData.highlightDragging) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - GetMoveListEvent(); } else { XtSetArg(args[0], XtNleftBitmap, None); } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"), - args, 1); + XtSetValues(XtNameToWidget(menuBarWidget, + "menuOptions.Highlight Dragging"), args, 1); } +#endif -#if HIGHDRAG -void HighlightDraggingProc(w, event, prms, nprms) +void HighlightLastMoveProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6435,19 +6336,18 @@ void HighlightDraggingProc(w, event, prms, nprms) { Arg args[16]; - appData.highlightDragging = !appData.highlightDragging; + appData.highlightLastMove = !appData.highlightLastMove; - if (appData.highlightDragging) { + if (appData.highlightLastMove) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); } else { XtSetArg(args[0], XtNleftBitmap, None); } XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Highlight Dragging"), args, 1); + "menuOptions.Highlight Last Move"), args, 1); } -#endif -void HighlightLastMoveProc(w, event, prms, nprms) +void HighlightArrowProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6455,17 +6355,18 @@ void HighlightLastMoveProc(w, event, prms, nprms) { Arg args[16]; - appData.highlightLastMove = !appData.highlightLastMove; + appData.highlightMoveWithArrow = !appData.highlightMoveWithArrow; - if (appData.highlightLastMove) { + if (appData.highlightMoveWithArrow) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); } else { XtSetArg(args[0], XtNleftBitmap, None); } XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Highlight Last Move"), args, 1); + "menuOptions.Arrow"), args, 1); } +#if 0 void IcsAlarmProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6484,6 +6385,7 @@ void IcsAlarmProc(w, event, prms, nprms) XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"), args, 1); } +#endif void MoveSoundProc(w, event, prms, nprms) Widget w; @@ -6504,8 +6406,7 @@ void MoveSoundProc(w, event, prms, nprms) args, 1); } - -void OldSaveStyleProc(w, event, prms, nprms) +void OneClickProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6513,14 +6414,14 @@ void OldSaveStyleProc(w, event, prms, nprms) { Arg args[16]; - appData.oldSaveStyle = !appData.oldSaveStyle; + appData.oneClick = !appData.oneClick; - if (appData.oldSaveStyle) { + if (appData.oneClick) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); } else { XtSetArg(args[0], XtNleftBitmap, None); } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.OneClick"), args, 1); } @@ -6543,25 +6444,6 @@ void PeriodicUpdatesProc(w, event, prms, nprms) args, 1); } -void PonderNextMoveProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - PonderNextMoveEvent(!appData.ponderNextMove); - - if (appData.ponderNextMove) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"), - args, 1); -} - void PopupExitMessageProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6600,6 +6482,7 @@ void PopupMoveErrorsProc(w, event, prms, nprms) args, 1); } +#if 0 void PremoveProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6618,25 +6501,7 @@ void PremoveProc(w, event, prms, nprms) XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Premove"), args, 1); } - -void QuietPlayProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - appData.quietPlay = !appData.quietPlay; - - if (appData.quietPlay) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"), - args, 1); -} +#endif void ShowCoordsProc(w, event, prms, nprms) Widget w; @@ -6688,6 +6553,7 @@ void HideThinkingProc(w, event, prms, nprms) XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"), args, 1); } +#endif void SaveOnExitProc(w, event, prms, nprms) Widget w; @@ -6829,23 +6695,23 @@ void DisplayMessage(message, extMessage) char *message, *extMessage; { /* display a message in the message widget */ - + char buf[MSG_SIZ]; Arg arg; - - if (extMessage) + + if (extMessage) { - if (*message) + if (*message) { snprintf(buf, sizeof(buf), "%s %s", message, extMessage); message = buf; - } - else + } + else { message = extMessage; }; }; - + /* need to test if messageWidget already exists, since this function can also be called during the startup, if for example a Xresource is not set up correctly */ @@ -6854,7 +6720,7 @@ void DisplayMessage(message, extMessage) XtSetArg(arg, XtNlabel, message); XtSetValues(messageWidget, &arg, 1); }; - + return; } @@ -6875,8 +6741,8 @@ void DisplayTitle(text) } if (*text != NULLCHAR) { - strcpy(icon, text); - strcpy(title, text); + safeStrCpy(icon, text, sizeof(icon)/sizeof(icon[0]) ); + safeStrCpy(title, text, sizeof(title)/sizeof(title[0]) ); } else if (appData.icsActive) { snprintf(icon, sizeof(icon), "%s", appData.icsHost); snprintf(title, sizeof(title), "%s: %s", programName, appData.icsHost); @@ -6886,19 +6752,19 @@ void DisplayTitle(text) #ifdef GOTHIC // [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it } else if (gameInfo.variant == VariantGothic) { - strcpy(icon, programName); - strcpy(title, GOTHIC); + safeStrCpy(icon, programName, sizeof(icon)/sizeof(icon[0]) ); + safeStrCpy(title, GOTHIC, sizeof(title)/sizeof(title[0]) ); #endif #ifdef FALCON } else if (gameInfo.variant == VariantFalcon) { - strcpy(icon, programName); - strcpy(title, FALCON); + safeStrCpy(icon, programName, sizeof(icon)/sizeof(icon[0]) ); + safeStrCpy(title, FALCON, sizeof(title)/sizeof(title[0]) ); #endif } else if (appData.noChessProgram) { - strcpy(icon, programName); - strcpy(title, programName); + safeStrCpy(icon, programName, sizeof(icon)/sizeof(icon[0]) ); + safeStrCpy(title, programName, sizeof(title)/sizeof(title[0]) ); } else { - strcpy(icon, first.tidy); + safeStrCpy(icon, first.tidy, sizeof(icon)/sizeof(icon[0]) ); snprintf(title,sizeof(title), "%s: %s", programName, first.tidy); } i = 0; @@ -6908,7 +6774,8 @@ void DisplayTitle(text) } -void DisplayError(message, error) +void +DisplayError(message, error) String message; int error; { @@ -7056,10 +6923,10 @@ void AskQuestionReplyAction(w, event, prms, nprms) String reply; reply = XawDialogGetValueString(w = XtParent(w)); - strcpy(buf, pendingReplyPrefix); - if (*buf) strcat(buf, " "); - strcat(buf, reply); - strcat(buf, "\n"); + safeStrCpy(buf, pendingReplyPrefix, sizeof(buf)/sizeof(buf[0]) ); + if (*buf) strncat(buf, " ", MSG_SIZ - strlen(buf) - 1); + strncat(buf, reply, MSG_SIZ - strlen(buf) - 1); + strncat(buf, "\n", MSG_SIZ - strlen(buf) - 1); OutputToProcess(pendingReplyPR, buf, strlen(buf), &err); AskQuestionPopDown(); @@ -7094,7 +6961,7 @@ void AskQuestion(title, question, replyPrefix, pr) int win_x, win_y; unsigned int mask; - strcpy(pendingReplyPrefix, replyPrefix); + safeStrCpy(pendingReplyPrefix, replyPrefix, sizeof(pendingReplyPrefix)/sizeof(pendingReplyPrefix[0]) ); pendingReplyPR = pr; i = 0; @@ -7148,7 +7015,9 @@ PlaySound(name) putc(BELLCHAR, stderr); } else { char buf[2048]; - snprintf(buf, sizeof(buf), "%s '%s' &", appData.soundProgram, name); + char *prefix = "", *sep = ""; + if(!strchr(name, '/')) { prefix = appData.soundDirectory; sep = "/"; } + snprintf(buf, sizeof(buf), "%s '%s%s%s' &", appData.soundProgram, prefix, sep, name); system(buf); } } @@ -7211,18 +7080,18 @@ Colorize(cc, continuation) if (textColors[(int)cc].bg > 0) { if (textColors[(int)cc].fg > 0) { - sprintf(buf, "\033[0;%d;%d;%dm", textColors[(int)cc].attr, - textColors[(int)cc].fg, textColors[(int)cc].bg); + snprintf(buf, MSG_SIZ, "\033[0;%d;%d;%dm", textColors[(int)cc].attr, + textColors[(int)cc].fg, textColors[(int)cc].bg); } else { - sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr, - textColors[(int)cc].bg); + snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr, + textColors[(int)cc].bg); } } else { if (textColors[(int)cc].fg > 0) { - sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr, + snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr, textColors[(int)cc].fg); } else { - sprintf(buf, "\033[0;%dm", textColors[(int)cc].attr); + snprintf(buf, MSG_SIZ, "\033[0;%dm", textColors[(int)cc].attr); } } count = strlen(buf); @@ -7272,11 +7141,12 @@ char *UserName() return getpwuid(getuid())->pw_name; } -static char *ExpandPathName(path) +static char * +ExpandPathName(path) char *path; { - static char static_buf[2000]; - char *d, *s, buf[2000]; + static char static_buf[4*MSG_SIZ]; + char *d, *s, buf[4*MSG_SIZ]; struct passwd *pwd; s = path; @@ -7292,25 +7162,25 @@ static char *ExpandPathName(path) if (*s == '~') { if (*(s+1) == '/') { - strcpy(d, getpwuid(getuid())->pw_dir); - strcat(d, s+1); + safeStrCpy(d, getpwuid(getuid())->pw_dir, 4*MSG_SIZ ); + strcat(d, s+1); } else { - strcpy(buf, s+1); - *strchr(buf, '/') = 0; - pwd = getpwnam(buf); - if (!pwd) - { - fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"), - buf, path); - return NULL; - } - strcpy(d, pwd->pw_dir); - strcat(d, strchr(s+1, '/')); + safeStrCpy(buf, s+1, sizeof(buf)/sizeof(buf[0]) ); + { char *p; if(p = strchr(buf, '/')) *p = 0; } + pwd = getpwnam(buf); + if (!pwd) + { + fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"), + buf, path); + return NULL; + } + safeStrCpy(d, pwd->pw_dir, 4*MSG_SIZ ); + strcat(d, strchr(s+1, '/')); } } else - strcpy(d, s); + safeStrCpy(d, s, 4*MSG_SIZ ); return static_buf; } @@ -7485,16 +7355,16 @@ DisplayTimerLabel(w, color, timer, highlight) Pixel foregroundOrWarningColor = timerForegroundPixel; if (timer > 0 && - appData.lowTimeWarning && + appData.lowTimeWarning && (timer / 1000) < appData.icsAlarmTime) foregroundOrWarningColor = lowTimeWarningColor; if (appData.clockMode) { - sprintf(buf, "%s: %s", color, TimeString(timer)); - XtSetArg(args[0], XtNlabel, buf); + snprintf(buf, MSG_SIZ, "%s: %s", color, TimeString(timer)); + XtSetArg(args[0], XtNlabel, buf); } else { - sprintf(buf, "%s ", color); - XtSetArg(args[0], XtNlabel, buf); + snprintf(buf, MSG_SIZ, "%s ", color); + XtSetArg(args[0], XtNlabel, buf); } if (highlight) { @@ -7575,7 +7445,7 @@ int StartChildProcess(cmdLine, dir, pr) most simple-minded way possible. */ i = 0; - strcpy(buf, cmdLine); + safeStrCpy(buf, cmdLine, sizeof(buf)/sizeof(buf[0]) ); p = buf; for (;;) { while(*p == ' ') p++; @@ -8106,11 +7976,10 @@ InitAnimState (anim, info) static void CreateAnimVars () { - static VariantClass old = (VariantClass) -1; // [HGM] pieces: redo every time variant changes XWindowAttributes info; - if (xpmDone && gameInfo.variant == old) return; - if(xpmDone) old = gameInfo.variant; // first time pieces might not be created yet + if (xpmDone && gameInfo.variant == oldVariant) return; + if(xpmDone) oldVariant = gameInfo.variant; // first time pieces might not be created yet XGetWindowAttributes(xDisplay, xBoardWindow, &info); InitAnimState(&game, &info); @@ -8389,6 +8258,7 @@ OverlayPiece(piece, clip, outline, dest) kind = 0; else kind = 2; + if(appData.upsideDown && flipView) kind ^= 2; XCopyArea(xDisplay, xpmPieceBitmap[kind][piece], dest, clip, 0, 0, squareSize, squareSize, @@ -8407,8 +8277,9 @@ BeginAnimation(anim, piece, startColor, start) { Pixmap mask; + if(appData.upsideDown && flipView) piece += piece < BlackPawn ? BlackPawn : -BlackPawn; /* The old buffer is initialised with the start square (empty) */ - BlankSquare(0, 0, startColor, EmptySquare, anim->saveBuf); + BlankSquare(start->x, start->y, startColor, EmptySquare, anim->saveBuf, 0); anim->prevFrame = *start; /* The piece will be drawn using its own bitmap as a matte */ @@ -8513,6 +8384,29 @@ FrameSequence(anim, piece, startColor, start, finish, frames, nFrames) EndAnimation(anim, finish); } +void +AnimateAtomicCapture(Board board, int fromX, int fromY, int toX, int toY) +{ + int i, x, y; + ChessSquare piece = board[fromY][toY]; + board[fromY][toY] = EmptySquare; + DrawPosition(FALSE, board); + if (flipView) { + x = lineGap + ((BOARD_WIDTH-1)-toX) * (squareSize + lineGap); + y = lineGap + toY * (squareSize + lineGap); + } else { + x = lineGap + toX * (squareSize + lineGap); + y = lineGap + ((BOARD_HEIGHT-1)-toY) * (squareSize + lineGap); + } + for(i=1; i<4*kFactor; i++) { + int r = squareSize * 9 * i/(20*kFactor - 5); + XFillArc(xDisplay, xBoardWindow, highlineGC, + x + squareSize/2 - r, y+squareSize/2 - r, 2*r, 2*r, 0, 64*360); + FrameDelay(appData.animSpeed); + } + board[fromY][toY] = piece; +} + /* Main control logic for deciding what to animate and how */ void @@ -8533,8 +8427,8 @@ AnimateMove(board, fromX, fromY, toX, toY) if (!appData.animate || appData.blindfold) return; - if(board[toY][toX] == WhiteRook && board[fromY][fromX] == WhiteKing || - board[toY][toX] == BlackRook && board[fromY][fromX] == BlackKing) + if(board[toY][toX] == WhiteRook && board[fromY][fromX] == WhiteKing || + board[toY][toX] == BlackRook && board[fromY][fromX] == BlackKing) return; // [HGM] FRC: no animtion of FRC castlings, as to-square is not true to-square if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return; @@ -8544,7 +8438,7 @@ AnimateMove(board, fromX, fromY, toX, toY) #if DONT_HOP hop = FALSE; #else - hop = (piece == WhiteKnight || piece == BlackKnight); + hop = abs(fromX-toX) == 1 && abs(fromY-toY) == 2 || abs(fromX-toX) == 2 && abs(fromY-toY) == 1; #endif if (appData.debugMode) { @@ -8556,12 +8450,12 @@ AnimateMove(board, fromX, fromY, toX, toY) ScreenSquare(toX, toY, &finish, &endColor); if (hop) { - /* Knight: make diagonal movement then straight */ + /* Knight: make straight movement then diagonal */ if (abs(toY - fromY) < abs(toX - fromX)) { mid.x = start.x + (finish.x - start.x) / 2; - mid.y = finish.y; + mid.y = start.y; } else { - mid.x = finish.x; + mid.x = start.x; mid.y = start.y + (finish.y - start.y) / 2; } } else { @@ -8575,9 +8469,14 @@ AnimateMove(board, fromX, fromY, toX, toY) else Tween(&start, &mid, &finish, kFactor, frames, &nFrames); FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames); + if(Explode(board, fromX, fromY, toX, toY)) { // mark as damaged + int i,j; + for(i=0; i @@ -8717,17 +8627,211 @@ int get_term_width() return default_width; } -void update_ics_width() +void +update_ics_width() { - static int old_width = 0; - int new_width = get_term_width(); + static int old_width = 0; + int new_width = get_term_width(); - if (old_width != new_width) - ics_printf("set width %d\n", new_width); - old_width = new_width; + if (old_width != new_width) + ics_printf("set width %d\n", new_width); + old_width = new_width; } void NotifyFrontendLogin() { update_ics_width(); } + +/* [AS] Arrow highlighting support */ + +static double A_WIDTH = 5; /* Width of arrow body */ + +#define A_HEIGHT_FACTOR 6 /* Length of arrow "point", relative to body width */ +#define A_WIDTH_FACTOR 3 /* Width of arrow "point", relative to body width */ + +static double Sqr( double x ) +{ + return x*x; +} + +static int Round( double x ) +{ + return (int) (x + 0.5); +} + +void SquareToPos(int rank, int file, int *x, int *y) +{ + if (flipView) { + *x = lineGap + ((BOARD_WIDTH-1)-file) * (squareSize + lineGap); + *y = lineGap + rank * (squareSize + lineGap); + } else { + *x = lineGap + file * (squareSize + lineGap); + *y = lineGap + ((BOARD_HEIGHT-1)-rank) * (squareSize + lineGap); + } +} + +/* Draw an arrow between two points using current settings */ +void DrawArrowBetweenPoints( int s_x, int s_y, int d_x, int d_y ) +{ + XPoint arrow[7]; + double dx, dy, j, k, x, y; + + if( d_x == s_x ) { + int h = (d_y > s_y) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; + + arrow[0].x = s_x + A_WIDTH + 0.5; + arrow[0].y = s_y; + + arrow[1].x = s_x + A_WIDTH + 0.5; + arrow[1].y = d_y - h; + + arrow[2].x = arrow[1].x + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + arrow[2].y = d_y - h; + + arrow[3].x = d_x; + arrow[3].y = d_y; + + arrow[5].x = arrow[1].x - 2*A_WIDTH + 0.5; + arrow[5].y = d_y - h; + + arrow[4].x = arrow[5].x - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + arrow[4].y = d_y - h; + + arrow[6].x = arrow[1].x - 2*A_WIDTH + 0.5; + arrow[6].y = s_y; + } + else if( d_y == s_y ) { + int w = (d_x > s_x) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; + + arrow[0].x = s_x; + arrow[0].y = s_y + A_WIDTH + 0.5; + + arrow[1].x = d_x - w; + arrow[1].y = s_y + A_WIDTH + 0.5; + + arrow[2].x = d_x - w; + arrow[2].y = arrow[1].y + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + + arrow[3].x = d_x; + arrow[3].y = d_y; + + arrow[5].x = d_x - w; + arrow[5].y = arrow[1].y - 2*A_WIDTH + 0.5; + + arrow[4].x = d_x - w; + arrow[4].y = arrow[5].y - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + + arrow[6].x = s_x; + arrow[6].y = arrow[1].y - 2*A_WIDTH + 0.5; + } + else { + /* [AS] Needed a lot of paper for this! :-) */ + dy = (double) (d_y - s_y) / (double) (d_x - s_x); + dx = (double) (s_x - d_x) / (double) (s_y - d_y); + + j = sqrt( Sqr(A_WIDTH) / (1.0 + Sqr(dx)) ); + + k = sqrt( Sqr(A_WIDTH*A_HEIGHT_FACTOR) / (1.0 + Sqr(dy)) ); + + x = s_x; + y = s_y; + + arrow[0].x = Round(x - j); + arrow[0].y = Round(y + j*dx); + + arrow[1].x = Round(arrow[0].x + 2*j); // [HGM] prevent width to be affected by rounding twice + arrow[1].y = Round(arrow[0].y - 2*j*dx); + + if( d_x > s_x ) { + x = (double) d_x - k; + y = (double) d_y - k*dy; + } + else { + x = (double) d_x + k; + y = (double) d_y + k*dy; + } + + x = Round(x); y = Round(y); // [HGM] make sure width of shaft is rounded the same way on both ends + + arrow[6].x = Round(x - j); + arrow[6].y = Round(y + j*dx); + + arrow[2].x = Round(arrow[6].x + 2*j); + arrow[2].y = Round(arrow[6].y - 2*j*dx); + + arrow[3].x = Round(arrow[2].x + j*(A_WIDTH_FACTOR-1)); + arrow[3].y = Round(arrow[2].y - j*(A_WIDTH_FACTOR-1)*dx); + + arrow[4].x = d_x; + arrow[4].y = d_y; + + arrow[5].x = Round(arrow[6].x - j*(A_WIDTH_FACTOR-1)); + arrow[5].y = Round(arrow[6].y + j*(A_WIDTH_FACTOR-1)*dx); + } + + XFillPolygon(xDisplay, xBoardWindow, highlineGC, arrow, 7, Nonconvex, CoordModeOrigin); +// Polygon( hdc, arrow, 7 ); +} + +/* [AS] Draw an arrow between two squares */ +void DrawArrowBetweenSquares( int s_col, int s_row, int d_col, int d_row ) +{ + int s_x, s_y, d_x, d_y, hor, vert, i; + + if( s_col == d_col && s_row == d_row ) { + return; + } + + /* Get source and destination points */ + SquareToPos( s_row, s_col, &s_x, &s_y); + SquareToPos( d_row, d_col, &d_x, &d_y); + + if( d_y > s_y ) { + d_y += squareSize / 2 - squareSize / 4; // [HGM] round towards same centers on all sides! + } + else if( d_y < s_y ) { + d_y += squareSize / 2 + squareSize / 4; + } + else { + d_y += squareSize / 2; + } + + if( d_x > s_x ) { + d_x += squareSize / 2 - squareSize / 4; + } + else if( d_x < s_x ) { + d_x += squareSize / 2 + squareSize / 4; + } + else { + d_x += squareSize / 2; + } + + s_x += squareSize / 2; + s_y += squareSize / 2; + + /* Adjust width */ + A_WIDTH = squareSize / 14.; //[HGM] make float + + DrawArrowBetweenPoints( s_x, s_y, d_x, d_y ); + + hor = 64*s_col + 32; vert = 64*s_row + 32; + for(i=0; i<= 64; i++) { + damage[0][vert+6>>6][hor+6>>6] = True; + damage[0][vert-6>>6][hor+6>>6] = True; + damage[0][vert+6>>6][hor-6>>6] = True; + damage[0][vert-6>>6][hor-6>>6] = True; + hor += d_col - s_col; vert += d_row - s_row; + } +} + +Boolean IsDrawArrowEnabled() +{ + return appData.highlightMoveWithArrow && squareSize >= 32; +} + +void DrawArrowHighlight(int fromX, int fromY, int toX,int toY) +{ + if( IsDrawArrowEnabled() && fromX >= 0 && fromY >= 0 && toX >= 0 && toY >= 0) + DrawArrowBetweenSquares(fromX, fromY, toX, toY); +}