Updated copyright notice to 2011
[xboard.git] / xboard.c
index fc6ba3a..7a8a7ac 100644 (file)
--- 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 <sys/types.h>
 #include <sys/stat.h>
 #include <pwd.h>
+#include <math.h>
 
 #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 <readline/readline.h>
-#include <readline/history.h>
-# endif
-
 #include <X11/Intrinsic.h>
 #include <X11/StringDefs.h>
 #include <X11/Shell.h>
@@ -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[] =
    :Ctrl<Key>c: CopyGameProc() \n \
    :Ctrl<Key>v: PasteGameProc() \n \
    :Ctrl<Key>O: LoadPositionProc() \n \
-   :Shift Meta<Key>Next: LoadNextPositionProc() \n \
-   :Shift Meta<Key>Prior: LoadPrevPositionProc() \n \
+   :Shift<Key>Next: LoadNextPositionProc() \n \
+   :Shift<Key>Prior: LoadPrevPositionProc() \n \
    :Ctrl<Key>S: SavePositionProc() \n \
    :Ctrl<Key>C: CopyPositionProc() \n \
    :Ctrl<Key>V: PastePositionProc() \n \
@@ -1059,6 +1064,8 @@ char globalTranslations[] =
    :Meta<Key>Right: ForwardProc() \n \
    :Meta<Key>Home: ToStartProc() \n \
    :Meta<Key>Left: BackwardProc() \n \
+   :<Key>Home: RevertProc() \n \
+   :<Key>End: TruncateGameProc() \n \
    :Ctrl<Key>m: MoveNowProc() \n \
    :Ctrl<Key>x: RetractMoveProc() \n \
    :Meta<Key>J: 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\r
-static char *history[HISTORY_SIZE];\r
-int histIn = 0, histP = 0;\r
-\r
-void\r
-SaveInHistory(char *cmd)\r
-{\r
-  if (history[histIn] != NULL) {\r
-    free(history[histIn]);\r
-    history[histIn] = NULL;\r
-  }\r
-  if (*cmd == NULLCHAR) return;\r
-  history[histIn] = StrSave(cmd);\r
-  histIn = (histIn + 1) % HISTORY_SIZE;\r
-  if (history[histIn] != NULL) {\r
-    free(history[histIn]);\r
-    history[histIn] = NULL;\r
-  }\r
-  histP = histIn;\r
-}\r
-\r
-char *\r
-PrevInHistory(char *cmd)\r
-{\r
-  int newhp;\r
-  if (histP == histIn) {\r
-    if (history[histIn] != NULL) free(history[histIn]);\r
-    history[histIn] = StrSave(cmd);\r
-  }\r
-  newhp = (histP - 1 + HISTORY_SIZE) % HISTORY_SIZE;\r
-  if (newhp == histIn || history[newhp] == NULL) return NULL;\r
-  histP = newhp;\r
-  return history[histP];\r
-}\r
-\r
-char *\r
-NextInHistory()\r
-{\r
-  if (histP == histIn) return NULL;\r
-  histP = (histP + 1) % HISTORY_SIZE;\r
-  return history[histP];   \r
-}
-// end of borrowed code\r
-\r
+#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;\r
+        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 {\r
     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) ||\r
         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;i<count;i++)
-               buf[i]='*';
-             i++;
-             buf[i]='\0';
-             printf("\rpassword: %s",buf);
-           }
-         else if (sending_ICS_login)
-           {
-             /* show login prompt */
-             count = strlen(rl_line_buffer);
-             printf("\rlogin: %s",rl_line_buffer);
-           }
-         else
-           rl_reset_line_state();
-         
-         if(readline_complete)
-           {
-             /* copy into XBoards buffer */
-             count = strlen(readline_buffer);
-             if (count>INPUT_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);
@@ -8916,6 +8869,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
@@ -8978,6 +8954,11 @@ 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<BOARD_WIDTH; i++) for(j=0; j<BOARD_HEIGHT; j++)
+      if((i-toX)*(i-toX) + (j-toY)*(j-toY) < 6) damage[0][j][i] = True;
+  }
 
   /* Be sure end square is redrawn */
   damage[0][toY][toX] = True;
@@ -9020,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;
@@ -9136,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 )
+{
+    return x*x;
+}
+
+static int Round( 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 (int) (x + 0.5);
+}
 
-  return;
+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