X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=7a8a7ac7a0f360e1247c2261e7916939c1481e05;hb=b382d988c6f886f3a49483df9e3e36de0b6b0824;hp=67992f14c90e6dbac4dfbd5bfede7427d3d00b83;hpb=91f35c4c0e1494e9711f26bb86f843e176c81321;p=xboard.git diff --git a/xboard.c b/xboard.c index 67992f1..7a8a7ac 100644 --- a/xboard.c +++ b/xboard.c @@ -5,7 +5,7 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010 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 @@ -141,12 +142,6 @@ extern char *getenv(); # endif #endif - -# if HAVE_LIBREADLINE /* add gnu-readline support */ -#include -#include -# endif - #include #include #include @@ -231,11 +226,13 @@ 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; @@ -413,10 +410,11 @@ 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 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, @@ -475,10 +473,8 @@ void SettingsPopDown P(()); void update_ics_width P(()); int get_term_width P(()); int CopyMemoProc P(()); - -# if HAVE_LIBREADLINE /* add gnu-readline support */ -static void ReadlineCompleteHandler P((char *)); -# endif +void DrawArrowHighlight P((int fromX, int fromY, int toX,int toY)); +Boolean IsDrawArrowEnabled P(()); /* * XBoard depends on Xt R4 or higher @@ -515,13 +511,6 @@ FileProc fileProc; char *fileOpenMode; char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion -# if HAVE_LIBREADLINE /* gnu readline support */ -static char* readline_buffer; -static int readline_complete=0; -extern int sending_ICS_login; -extern int sending_ICS_password; -#endif - Position commentX = -1, commentY = -1; Dimension commentW, commentH; typedef unsigned int BoardSize; @@ -608,166 +597,183 @@ 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}, + {"----", NULL, NothingProc}, + {N_("Tags"), "Show Tags", EditTagsProc}, + {N_("Comments"), "Show Comments", EditCommentProc}, + {N_("ICS Input Box"), "ICS Input Box", IcsInputBoxProc}, + {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_("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}, - {N_("Upload to Examine"), UploadProc}, - {"----", 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_("Annotate"), AnnotateProc}, - {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}, + {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_("Game List ..."), "Game List", GameListOptionsPopUp}, + {"----", NULL, NothingProc}, + {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 Comment"), "Auto Comment", AutocommProc}, + {N_("Auto Flag Ctrl+Shift+F"), "Auto Flag", AutoflagProc}, + {N_("Auto Flip View"), "Auto Flip View", AutoflipProc}, + {N_("Auto Observe"), "Auto Observe", AutobsProc}, + {N_("Auto Raise Board"), "Auto Raise Board", AutoraiseProc}, + {N_("Auto Save"), "Auto Save", AutosaveProc}, + {N_("Blindfold"), "Blindfold", BlindfoldProc}, + {N_("Flash Moves"), "Flash Moves", FlashMovesProc}, + {N_("Get Move List"), "Get Move List", GetMoveListProc}, #if HIGHDRAG - {N_("Highlight Dragging"), HighlightDraggingProc}, + {N_("Highlight Dragging"), "Highlight Dragging", HighlightDraggingProc}, #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_("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_("Quiet Play"), "Quiet Play", QuietPlayProc}, + {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}, + {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 @@ -972,7 +978,6 @@ XtActionsRec boardActions[] = { { "HighlightLastMoveProc", HighlightLastMoveProc }, { "IcsAlarmProc", IcsAlarmProc }, { "MoveSoundProc", MoveSoundProc }, - { "OldSaveStyleProc", OldSaveStyleProc }, { "PeriodicUpdatesProc", PeriodicUpdatesProc }, { "PonderNextMoveProc", PonderNextMoveProc }, { "PopupExitMessageProc", PopupExitMessageProc }, @@ -1027,8 +1032,8 @@ char globalTranslations[] = :Ctrlc: CopyGameProc() \n \ :Ctrlv: PasteGameProc() \n \ :CtrlO: LoadPositionProc() \n \ - :Shift MetaNext: LoadNextPositionProc() \n \ - :Shift MetaPrior: LoadPrevPositionProc() \n \ + :ShiftNext: LoadNextPositionProc() \n \ + :ShiftPrior: LoadPrevPositionProc() \n \ :CtrlS: SavePositionProc() \n \ :CtrlC: CopyPositionProc() \n \ :CtrlV: PastePositionProc() \n \ @@ -1059,6 +1064,8 @@ char globalTranslations[] = :MetaRight: ForwardProc() \n \ :MetaHome: ToStartProc() \n \ :MetaLeft: BackwardProc() \n \ + :Home: RevertProc() \n \ + :End: TruncateGameProc() \n \ :Ctrlm: MoveNowProc() \n \ :Ctrlx: RetractMoveProc() \n \ :MetaJ: EngineMenuProc() \n \ @@ -1731,6 +1738,10 @@ void InitDrawingSizes(BoardSize boardSize, int flags) xpmPieceBitmap[i][(int)WhiteMarshall] = xpmPieceBitmap2[i][(int)WhiteSilver]; } #endif + if(gameInfo.variant == VariantSChess && (squareSize == 49 || squareSize == 72)) { + xpmPieceBitmap[i][(int)WhiteAngel] = xpmPieceBitmap2[i][(int)WhiteFalcon]; + xpmPieceBitmap[i][(int)WhiteMarshall] = xpmPieceBitmap2[i][(int)WhiteAlfil]; + } #if !HAVE_LIBXPM // [HGM] why are thee ximMasks used at all? the ximPieceBitmaps seem to be never used! for(p=0; p<=(int)WhiteKing; p++) @@ -1747,6 +1758,10 @@ void InitDrawingSizes(BoardSize boardSize, int flags) ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[(int)WhiteSilver]; } #endif + if(gameInfo.variant == VariantSChess && (squareSize == 49 || squareSize == 72)) { + ximMaskPm[(int)WhiteAngel] = ximMaskPm2[(int)WhiteFalcon]; + ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[(int)WhiteAlfil]; + } #endif } } else { @@ -1766,6 +1781,10 @@ void InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[i][(int)WhiteMarshall] = pieceBitmap2[i][(int)WhiteSilver]; } #endif + if(gameInfo.variant == VariantSChess && (squareSize == 49 || squareSize == 72)) { + pieceBitmap[i][(int)WhiteAngel] = pieceBitmap2[i][(int)WhiteFalcon]; + pieceBitmap[i][(int)WhiteMarshall] = pieceBitmap2[i][(int)WhiteAlfil]; + } } } #if HAVE_LIBXPM @@ -1794,12 +1813,6 @@ main(argc, argv) setbuf(stdout, NULL); setbuf(stderr, NULL); debugFP = stderr; - -# if HAVE_LIBREADLINE - /* install gnu-readline handler */ - rl_callback_handler_install("> ", ReadlineCompleteHandler); - rl_readline_name="XBoard"; -# endif if(argc > 1 && (!strcmp(argv[1], "-v" ) || !strcmp(argv[1], "--version" ))) { printf("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION); @@ -2453,6 +2466,11 @@ XBoard square size (hint): %d\n\ "menuOptions.Highlight Last Move"), args, 1); } + if (appData.highlightMoveWithArrow) { + XtSetValues(XtNameToWidget(menuBarWidget, + "menuOptions.Arrow"), + args, 1); + } if (appData.icsAlarm) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"), args, 1); @@ -2461,9 +2479,9 @@ XBoard square size (hint): %d\n\ 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, @@ -2626,13 +2644,6 @@ ShutDownFrontEnd() if (saveSettingsOnExit) SaveSettings(settingsFileName); unlink(gameCopyFilename); unlink(gamePasteFilename); - -# if HAVE_LIBREADLINE - /* remove gnu-readline handler. */ - rl_callback_handler_remove(); -#endif - - return; } RETSIGTYPE TermSizeSigHandler(int sig) @@ -2728,15 +2739,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, "menuStep.Annotate"); + w = XtNameToWidget(menuBarWidget, "menuEdit.Annotate"); if (w == NULL) { - DisplayError("menuStep.Annotate", 0); + DisplayError("menuEdit.Annotate", 0); } else { XtSetSensitive(w, !grey); } @@ -2768,14 +2779,16 @@ Enables icsEnables[] = { { "menuMode.Analyze File", False }, { "menuMode.Two Machines", False }, #ifndef ZIPPY - { "menuHelp.Hint", False }, - { "menuHelp.Book", False }, - { "menuStep.Move Now", False }, + { "menuEngine.Hint", False }, + { "menuEngine.Book", False }, + { "menuEngine.Move Now", False }, { "menuOptions.Periodic Updates", False }, { "menuOptions.Hide Thinking", False }, { "menuOptions.Ponder Next Move", False }, + { "menuEngine.Engine #1 Settings", False }, #endif - { "menuStep.Annotate", False }, + { "menuEngine.Engine #2 Settings", False }, + { "menuEdit.Annotate", False }, { NULL, False } }; @@ -2788,12 +2801,14 @@ Enables ncpEnables[] = { { "menuMode.Analyze File", False }, { "menuMode.Two Machines", False }, { "menuMode.ICS Client", False }, - { "menuMode.ICS Input Box", False }, + { "menuView.ICS Input Box", False }, { "Action", False }, - { "menuStep.Revert", False }, - { "menuStep.Annotate", False }, - { "menuStep.Move Now", False }, - { "menuStep.Retract Move", 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.Auto Comment", False }, { "menuOptions.Auto Flag", False }, { "menuOptions.Auto Flip View", False }, @@ -2806,14 +2821,14 @@ Enables ncpEnables[] = { { "menuOptions.Hide Thinking", False }, { "menuOptions.Periodic Updates", False }, { "menuOptions.Ponder Next Move", False }, - { "menuHelp.Hint", False }, - { "menuHelp.Book", False }, + { "menuEngine.Hint", False }, + { "menuEngine.Book", False }, { NULL, False } }; Enables gnuEnables[] = { { "menuMode.ICS Client", False }, - { "menuMode.ICS Input Box", False }, + { "menuView.ICS Input Box", False }, { "menuAction.Accept", False }, { "menuAction.Decline", False }, { "menuAction.Rematch", False }, @@ -2821,8 +2836,8 @@ Enables gnuEnables[] = { { "menuAction.Stop Examining", False }, { "menuAction.Stop Observing", False }, { "menuAction.Upload to Examine", False }, - { "menuStep.Revert", False }, - { "menuStep.Annotate", False }, + { "menuEdit.Revert", False }, + { "menuEdit.Annotate", False }, { "menuOptions.Auto Comment", False }, { "menuOptions.Auto Observe", False }, { "menuOptions.Auto Raise Board", False }, @@ -2855,60 +2870,60 @@ 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 }, + { "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 }, + { "menuEngine.Retract Move", True }, { NULL, False } }; @@ -2984,50 +2999,50 @@ 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 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)) /* @@ -3715,8 +3730,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, @@ -3743,17 +3758,17 @@ Widget CreateMenuBar(mb) while (mb->name != NULL) { safeStrCpy(menuName, "menu", sizeof(menuName)/sizeof(menuName[0]) ); - strncat(menuName, mb->name, MSG_SIZ - strlen(menuName) - 1); + 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++; @@ -3940,11 +3955,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) @@ -3953,11 +3964,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); } @@ -3993,7 +4000,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) * @@ -4450,7 +4457,7 @@ void EventProc(widget, unused, event) } break; case MotionNotify: - if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break; + if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break; default: return; } @@ -4587,7 +4594,7 @@ void XDrawPosition(w, repaint, board) } 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); } @@ -4596,6 +4603,7 @@ void XDrawPosition(w, repaint, board) * but this causes a very distracting flicker. */ + if ( lineGap && IsDrawArrowEnabled()) repaint = True; if (!repaint && lastBoardValid[nr] && (nr == 1 || lastFlipView == flipView)) { /* If too much changes (begin observing new game, etc.), don't @@ -4660,6 +4668,7 @@ 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(); @@ -5035,7 +5044,9 @@ void EditCommentPopUp(index, title, text) editUp = True; j = 0; XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuEdit.Edit Comment"), + args, j); + XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Comments"), args, j); } @@ -5084,7 +5095,9 @@ void EditCommentPopDown() editUp = False; j = 0; XtSetArg(args[j], XtNleftBitmap, None); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuEdit.Edit Comment"), + args, j); + XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Comments"), args, j); } @@ -5121,7 +5134,7 @@ void ICSInputBoxPopUp() ICSInputBoxUp = True; j = 0; XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuView.ICS Input Box"), args, j); } @@ -5153,7 +5166,7 @@ void ICSInputBoxPopDown() ICSInputBoxUp = False; j = 0; XtSetArg(args[j], XtNleftBitmap, None); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuView.ICS Input Box"), args, j); } @@ -5348,6 +5361,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, @@ -5356,7 +5379,9 @@ 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); @@ -5815,7 +5840,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); - safeStrCpy(selection_tmp, selected_fen_position, sizeof(selection_tmp)/sizeof(selection_tmp[0]) ); + safeStrCpy(selection_tmp, selected_fen_position, strlen(selected_fen_position)+16 ); *value_return=selection_tmp; *length_return=strlen(selection_tmp); @@ -6776,6 +6801,25 @@ void HighlightLastMoveProc(w, event, prms, nprms) "menuOptions.Highlight Last Move"), args, 1); } +void HighlightArrowProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + Arg args[16]; + + appData.highlightMoveWithArrow = !appData.highlightMoveWithArrow; + + if (appData.highlightMoveWithArrow) { + XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); + } else { + XtSetArg(args[0], XtNleftBitmap, None); + } + XtSetValues(XtNameToWidget(menuBarWidget, + "menuOptions.Arrow"), args, 1); +} + void IcsAlarmProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6814,8 +6858,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; @@ -6823,14 +6866,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); } @@ -7609,7 +7652,7 @@ ExpandPathName(path) } else { safeStrCpy(buf, s+1, sizeof(buf)/sizeof(buf[0]) ); - *strchr(buf, '/') = 0; + { char *p; if(p = strchr(buf, '/')) *p = 0; } pwd = getpwnam(buf); if (!pwd) { @@ -8155,98 +8198,16 @@ DoInputCallback(closure, source, xid) } q = is->buf; while (p < is->unused) { - *q++ = *p++; + *q++ = *p++; } is->unused = q; } else { -# if HAVE_LIBREADLINE - /* check if input is from stdin, if yes, use gnu-readline */ - if( is->fd==fileno(stdin) ) - { - /* to clear the line */ - printf("\r \r"); - - /* read from stdin */ - rl_callback_read_char(); - - /* redisplay the current line, check special case for login and password */ - if(sending_ICS_password) - { - int i; char buf[MSG_SIZ]; - - bzero(buf,MSG_SIZ); - - /* blank the password */ - count = strlen(rl_line_buffer); - if(count>MSG_SIZ-1) - { - printf("PROBLEM with readline\n"); - count=MSG_SIZ; - } - for(i=0;iINPUT_SOURCE_BUF_SIZE-1) - { - printf("PROBLEM with readline\n"); - count = INPUT_SOURCE_BUF_SIZE; - }; - strncpy(is->buf,readline_buffer,count); - is->buf[count]='\n';count++; - - /* reset gnu-readline state */ - free(readline_buffer); - readline_buffer=NULL; - readline_complete=0; - - if (count == -1) - error = errno; - else - error = 0; - (is->func)(is, is->closure, is->buf, count, error); - - /* are we done with the password? */ - if(sending_ICS_password) - sending_ICS_password=0; - if(sending_ICS_login) - sending_ICS_login=0; - } - } - else - { - /* input not from stdin, use default method */ - count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE); - if (count == -1) - error = errno; - else - error = 0; - (is->func)(is, is->closure, is->buf, count, error); - }; -#else /* no readline support */ - count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE); - if (count == -1) - error = errno; - else - error = 0; - (is->func)(is, is->closure, is->buf, count, error); -#endif - + count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE); + if (count == -1) + error = errno; + else + error = 0; + (is->func)(is, is->closure, is->buf, count, error); } } @@ -8302,36 +8263,28 @@ int OutputToProcess(pr, message, count, outError) ChildProc *cp = (ChildProc *) pr; int outCount; - if (pr == NoProc) { - if (appData.noJoin || !appData.useInternalWrap) - outCount = fwrite(message, 1, count, stdout); - else + if (appData.noJoin || !appData.useInternalWrap) + outCount = fwrite(message, 1, count, stdout); + else { - int width = get_term_width(); - int len = wrap(NULL, message, count, width, &line); - char *msg = malloc(len); - int dbgchk; - - if (!msg) - outCount = fwrite(message, 1, count, stdout); - else + int width = get_term_width(); + int len = wrap(NULL, message, count, width, &line); + char *msg = malloc(len); + int dbgchk; + + if (!msg) + outCount = fwrite(message, 1, count, stdout); + else { - dbgchk = wrap(msg, message, count, width, &line); - if (dbgchk != len && appData.debugMode) - fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len); - outCount = fwrite(msg, 1, dbgchk, stdout); - free(msg); + dbgchk = wrap(msg, message, count, width, &line); + if (dbgchk != len && appData.debugMode) + fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len); + outCount = fwrite(msg, 1, dbgchk, stdout); + free(msg); } } - -# if HAVE_LIBREADLINE - /* readline support */ - if(strlen(rl_line_buffer)) - printf("\n> %s",rl_line_buffer); -#endif - } else outCount = write(cp->fdTo, message, count); @@ -9048,6 +9001,17 @@ DragPieceBegin(x, y) XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC, corner.x, corner.y, squareSize, squareSize, 0, 0); // [HGM] zh: unstack in stead of grab + if(gatingPiece != EmptySquare) { + /* Kludge alert: When gating we want the introduced + piece to appear on the from square. To generate an + image of it, we draw it on the board, copy the image, + and draw the original piece again. */ + ChessSquare piece = boards[currentMove][boardY][boardX]; + DrawSquare(boardY, boardX, gatingPiece, 0); + XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC, + corner.x, corner.y, squareSize, squareSize, 0, 0); + DrawSquare(boardY, boardX, piece, 0); + } damage[0][boardY][boardX] = True; } else { player.dragActive = False; @@ -9164,17 +9128,198 @@ void NotifyFrontendLogin() update_ics_width(); } -# if HAVE_LIBREADLINE -static void -ReadlineCompleteHandler(char* ptr) +/* [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 ) { - /* make gnu-readline keep the history */ - readline_buffer = ptr; - readline_complete = 1; - - if (ptr && *ptr && !sending_ICS_password && !sending_ICS_login) - add_history(ptr); + return x*x; +} - return; +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 ); + + if(lineGap == 0) { + // this is a good idea, but it only works when lineGap == 0, because 'damage' on grid lines is not repaired + 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); } -#endif