Add -useBoardTexture and -usePieceFont options
[xboard.git] / xboard.c
index 4167b6c..033c53b 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:
@@ -142,6 +142,10 @@ extern char *getenv();
 # endif
 #endif
 
+#if ENABLE_NLS
+#include <locale.h>
+#endif
+
 #include <X11/Intrinsic.h>
 #include <X11/StringDefs.h>
 #include <X11/Shell.h>
@@ -238,11 +242,12 @@ typedef struct {
 
 int main P((int argc, char **argv));
 FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *failed,
-               char *init_path, char *mode, int (*show_entry)(), char **name_return));
+               char *init_path, char *filter, char *mode, int (*show_entry)(), char **name_return));
 RETSIGTYPE CmailSigHandler P((int sig));
 RETSIGTYPE IntSigHandler P((int sig));
 RETSIGTYPE TermSizeSigHandler P((int sig));
-void CreateGCs P((void));
+void CreateGCs P((int redo));
+void CreateAnyPieces P((void));
 void CreateXIMPieces P((void));
 void CreateXPMPieces P((void));
 void CreateXPMBoard P((char *s, int n));
@@ -250,7 +255,12 @@ void CreatePieces P((void));
 void CreatePieceMenus P((void));
 Widget CreateMenuBar P((Menu *mb));
 Widget CreateButtonBar P ((MenuItem *mi));
+#if ENABLE_NLS
+char *InsertPxlSize P((char *pattern, int targetPxlSize));
+XFontSet CreateFontSet P((char *base_fnt_lst));
+#else
 char *FindFont P((char *pattern, int targetPxlSize));
+#endif
 void PieceMenuPopup P((Widget w, XEvent *event,
                       String *params, Cardinal *num_params));
 static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
@@ -261,6 +271,7 @@ void CreateGrid P((void));
 int EventToSquare P((int x, int limit));
 void DrawSquare P((int row, int column, ChessSquare piece, int do_flash));
 void EventProc P((Widget widget, caddr_t unused, XEvent *event));
+void MoveTypeInProc P((Widget widget, caddr_t unused, XEvent *event));
 void HandleUserMove P((Widget w, XEvent *event,
                     String *prms, Cardinal *nprms));
 void AnimateUserMove P((Widget w, XEvent * event,
@@ -283,11 +294,9 @@ void CommentClick P((Widget w, XEvent * event,
                   String * params, Cardinal * nParams));
 void CommentPopUp P((char *title, char *label));
 void CommentPopDown P((void));
-void CommentCallback P((Widget w, XtPointer client_data,
-                       XtPointer call_data));
 void ICSInputBoxPopUp P((void));
 void ICSInputBoxPopDown P((void));
-void FileNamePopUp P((char *label, char *def,
+void FileNamePopUp P((char *label, char *def, char *filter,
                      FileProc proc, char *openMode));
 void FileNamePopDown P((void));
 void FileNameCallback P((Widget w, XtPointer client_data,
@@ -302,9 +311,6 @@ void AskQuestionPopDown P((void));
 void PromotionPopDown P((void));
 void PromotionCallback P((Widget w, XtPointer client_data,
                          XtPointer call_data));
-void EditCommentPopDown P((void));
-void EditCommentCallback P((Widget w, XtPointer client_data,
-                           XtPointer call_data));
 void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
 void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@ -327,6 +333,7 @@ void CopyPositionProc P((Widget w, XEvent *event, String *prms,
 void PastePositionProc P((Widget w, XEvent *event, String *prms,
                          Cardinal *nprms));
 void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void CopyGameListProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void SavePositionProc P((Widget w, XEvent *event,
@@ -346,6 +353,8 @@ void AnalyzeFileProc P((Widget w, XEvent *event,
                         String *prms, Cardinal *nprms));
 void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
                        Cardinal *nprms));
+void MatchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void MatchOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void IcsClientProc P((Widget w, XEvent *event, String *prms,
                      Cardinal *nprms));
 void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@ -367,6 +376,7 @@ void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void AdjuWhiteProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void AdjuBlackProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void AdjuDrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void TypeInProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void UpKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void DownKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@ -392,28 +402,21 @@ void AnimateDraggingProc P((Widget w, XEvent *event, String *prms,
                         Cardinal *nprms));
 void AnimateMovingProc P((Widget w, XEvent *event, String *prms,
                         Cardinal *nprms));
-void AutocommProc P((Widget w, XEvent *event, String *prms,
-                    Cardinal *nprms));
 void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AutobsProc P((Widget w, XEvent *event, String *prms,
-                       Cardinal *nprms));
-void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void FlashMovesProc P((Widget w, XEvent *event, String *prms,
                       Cardinal *nprms));
 void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void GetMoveListProc P((Widget w, XEvent *event, String *prms,
-                       Cardinal *nprms));
 void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
                              Cardinal *nprms));
 void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
                              Cardinal *nprms));
+void HighlightArrowProc P((Widget w, XEvent *event, String *prms,
+                             Cardinal *nprms));
 void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
-                        Cardinal *nprms));
+//void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void OneClickProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
                         Cardinal *nprms));
 void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
@@ -422,8 +425,7 @@ void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms,
                        Cardinal *nprms));
 void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
                             Cardinal *nprms));
-void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+//void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void ShowCoordsProc P((Widget w, XEvent *event, String *prms,
                       Cardinal *nprms));
 void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
@@ -458,17 +460,22 @@ void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms))
 void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void OptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void IcsTextProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void LoadEngineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void GameListOptionsPopUp P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void IcsOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void SoundOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void BoardOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void LoadOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void SaveOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void EditBookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void SelectMove P((Widget w, XEvent * event, String * params, Cardinal * nParams));
 void GameListOptionsPopDown P(());
-void ShufflePopDown P(());
-void EnginePopDown P(());
-void UciPopDown P(());
-void TimeControlPopDown P(());
-void NewVariantPopDown P(());
-void SettingsPopDown P(());
+void GenericPopDown P(());
 void update_ics_width P(());
 int get_term_width P(());
 int CopyMemoProc P(());
@@ -500,8 +507,14 @@ int hOffset; // [HGM] dual
 XSegment secondSegments[BOARD_RANKS + BOARD_FILES + 2];
 XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2];
 XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6];
-Font clockFontID, coordFontID, countFontID;
-XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
+#if ENABLE_NLS
+XFontSet fontSet, clockFontSet;
+#else
+Font clockFontID;
+XFontStruct *clockFontStruct;
+#endif
+Font coordFontID, countFontID;
+XFontStruct *coordFontStruct, *countFontStruct;
 XtAppContext appContext;
 char *layoutName;
 char *oldICSInteractionTitle;
@@ -522,7 +535,7 @@ int squareSize, smallLayout = 0, tinyLayout = 0,
   fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,
   ICSInputBoxUp = False, askQuestionUp = False,
   filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,
-  editUp = False, errorUp = False, errorExitStatus = -1, lineGap;
+  errorUp = False, errorExitStatus = -1, lineGap, defaultLineGap;
 Pixel timerForegroundPixel, timerBackgroundPixel;
 Pixel buttonForegroundPixel, buttonBackgroundPixel;
 char *chessDir, *programName, *programVersion,
@@ -544,6 +557,9 @@ WindowPlacement wpEngineOutput;
 WindowPlacement wpGameList;
 WindowPlacement wpTags;
 
+extern Widget shells[];
+extern Boolean shellUp[];
+
 #define SOLID 0
 #define OUTLINE 1
 Pixmap pieceBitmap[2][(int)BlackPawn];
@@ -605,9 +621,9 @@ MenuItem fileMenu[] = {
 //    {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_("Load Next Position"), "Load Next Position", LoadNextPositionProc},
-//    {N_("Load Previous Position"), "Load Previous Position", LoadPrevPositionProc},
 //    {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},
@@ -622,6 +638,7 @@ MenuItem fileMenu[] = {
 MenuItem editMenu[] = {
     {N_("Copy Game    Ctrl+C"),        "Copy Game", CopyGameProc},
     {N_("Copy Position Ctrl+Shift+C"), "Copy Position", CopyPositionProc},
+    {N_("Copy Game List"),        "Copy Game List", CopyGameListProc},
     {"----", NULL, NothingProc},
     {N_("Paste Game    Ctrl+V"),        "Paste Game", PasteGameProc},
     {N_("Paste Position Ctrl+Shift+V"), "Paste Position", PastePositionProc},
@@ -630,6 +647,7 @@ MenuItem editMenu[] = {
     {N_("Edit Position   Ctrl+Shift+E"), "Edit Position", EditPositionProc},
     {N_("Edit Tags"),                    "Edit Tags", EditTagsProc},
     {N_("Edit Comment"),                 "Edit Comment", EditCommentProc},
+    {N_("Edit Book"),                    "Edit Book", EditBookProc},
     {"----", NULL, NothingProc},
     {N_("Revert              Home"), "Revert", RevertProc},
     {N_("Annotate"),                 "Annotate", AnnotateProc},
@@ -649,10 +667,14 @@ MenuItem viewMenu[] = {
     {N_("Move History       Alt+Shift+H"),   "Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
     {N_("Evaluation Graph  Alt+Shift+E"),    "Show Evaluation Graph", EvalGraphProc},
     {N_("Game List            Alt+Shift+G"), "Show Game List", ShowGameListProc},
+    {N_("ICS text menu"), "ICStex", IcsTextProc},
     {"----", NULL, NothingProc},
     {N_("Tags"),             "Show Tags", EditTagsProc},
     {N_("Comments"),         "Show Comments", EditCommentProc},
     {N_("ICS Input Box"),    "ICS Input Box", IcsInputBoxProc},
+    {"----", NULL, NothingProc},
+    {N_("Board..."),          "Board Options", BoardOptionsProc},
+    {N_("Game List Tags..."), "Game List", GameListOptionsPopUp},
     {NULL, NULL, NULL}
 };
 
@@ -667,6 +689,7 @@ MenuItem modeMenu[] = {
     {N_("Training"),      "Training", TrainingProc},
     {N_("ICS Client"),    "ICS Client", IcsClientProc},
     {"----", NULL, NothingProc},
+    {N_("Machine Match"),         "Machine Match", MatchProc},
     {N_("Pause               Pause"),         "Pause", PauseProc},
     {NULL, NULL, NULL}
 };
@@ -693,6 +716,8 @@ MenuItem actionMenu[] = {
 };
 
 MenuItem engineMenu[] = {
+    {N_("Load New Engine ..."), "Load Engine", LoadEngineProc},
+    {"----", NULL, NothingProc},
     {N_("Engine #1 Settings ..."), "Engine #1 Settings", FirstSettingsProc},
     {N_("Engine #2 Settings ..."), "Engine #2 Settings", SecondSettingsProc},
     {"----", NULL, NothingProc},
@@ -705,40 +730,47 @@ MenuItem engineMenu[] = {
 };
 
 MenuItem optionsMenu[] = {
+#define OPTIONSDIALOG
+#ifdef OPTIONSDIALOG
+    {N_("General ..."), "General", OptionsProc},
+#endif
     {N_("Time Control ...       Alt+Shift+T"), "Time Control", TimeControlProc},
     {N_("Common Engine ...  Alt+Shift+U"),     "Common Engine", UciMenuProc},
     {N_("Adjudications ...      Alt+Shift+J"), "Adjudications", EngineMenuProc},
+    {N_("ICS ..."),    "ICS", IcsOptionsProc},
+    {N_("Match ..."), "Match", MatchOptionsProc},
+    {N_("Load Game ..."),    "Load Game", LoadOptionsProc},
+    {N_("Save Game ..."),    "Save Game", SaveOptionsProc},
+//    {N_(" ..."),    "", OptionsProc},
     {N_("Game List ..."),    "Game List", GameListOptionsPopUp},
+    {N_("Sounds ..."),    "Sounds", SoundOptionsProc},
     {"----", NULL, NothingProc},
+#ifndef OPTIONSDIALOG
     {N_("Always Queen        Ctrl+Shift+Q"),   "Always Queen", AlwaysQueenProc},
     {N_("Animate Dragging"), "Animate Dragging", AnimateDraggingProc},
     {N_("Animate Moving      Ctrl+Shift+A"),   "Animate Moving", AnimateMovingProc},
-    {N_("Auto 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"),    "Highlight Dragging", HighlightDraggingProc},
 #endif
     {N_("Highlight Last Move"),   "Highlight Last Move", HighlightLastMoveProc},
+    {N_("Highlight With Arrow"),  "Arrow", HighlightArrowProc},
     {N_("Move Sound"),            "Move Sound", MoveSoundProc},
-    {N_("ICS Alarm"),             "ICS Alarm", IcsAlarmProc},
-    {N_("Old Save Style"),        "Old Save Style", OldSaveStyleProc},
+//    {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_("Premove"),               "Premove", PremoveProc},
     {N_("Show Coords"),           "Show Coords", ShowCoordsProc},
     {N_("Hide Thinking        Ctrl+Shift+H"),   "Hide Thinking", HideThinkingProc},
     {N_("Test Legality          Ctrl+Shift+L"), "Test Legality", TestLegalityProc},
     {"----", NULL, NothingProc},
+#endif
     {N_("Save Settings Now"),     "Save Settings Now", SaveSettingsProc},
     {N_("Save Settings on Exit"), "Save Settings on Exit", SaveOnExitProc},
     {NULL, NULL, NULL}
@@ -785,7 +817,7 @@ String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
       N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
       N_("Empty square"), N_("Clear board") }
 };
-/* must be in same order as PieceMenuStrings! */
+/* must be in same order as pieceMenuStrings! */
 ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
     { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
        WhiteRook, WhiteQueen, WhiteKing, (ChessSquare) 0, WhiteAlfil,
@@ -801,7 +833,7 @@ ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
 String dropMenuStrings[DROP_MENU_SIZE] = {
     "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen")
   };
-/* must be in same order as PieceMenuStrings! */
+/* must be in same order as dropMenuStrings! */
 ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
     (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
     WhiteRook, WhiteQueen
@@ -905,6 +937,7 @@ XtActionsRec boardActions[] = {
     { "CopyPositionProc", CopyPositionProc },
     { "PastePositionProc", PastePositionProc },
     { "CopyGameProc", CopyGameProc },
+    { "CopyGameListProc", CopyGameListProc },
     { "PasteGameProc", PasteGameProc },
     { "SaveGameProc", SaveGameProc },
     { "SavePositionProc", SavePositionProc },
@@ -925,8 +958,8 @@ XtActionsRec boardActions[] = {
     { "ShowGameListProc", ShowGameListProc },
     { "ShowMoveListProc", HistoryShowProc},
     { "EditTagsProc", EditCommentProc },
+    { "EditBookProc", EditBookProc },
     { "EditCommentProc", EditCommentProc },
-    { "IcsAlarmProc", IcsAlarmProc },
     { "IcsInputBoxProc", IcsInputBoxProc },
     { "PauseProc", PauseProc },
     { "AcceptProc", AcceptProc },
@@ -940,6 +973,7 @@ XtActionsRec boardActions[] = {
     { "AdjuWhiteProc", AdjuWhiteProc },
     { "AdjuBlackProc", AdjuBlackProc },
     { "AdjuDrawProc", AdjuDrawProc },
+    { "TypeInProc", TypeInProc },
     { "EnterKeyProc", EnterKeyProc },
     { "UpKeyProc", UpKeyProc },
     { "DownKeyProc", DownKeyProc },
@@ -958,35 +992,31 @@ XtActionsRec boardActions[] = {
     { "EngineMenuProc", (XtActionProc) EngineMenuProc },
     { "UciMenuProc", (XtActionProc) UciMenuProc },
     { "TimeControlProc", (XtActionProc) TimeControlProc },
+    { "FlipViewProc", FlipViewProc },
+    { "PonderNextMoveProc", PonderNextMoveProc },
+#ifndef OPTIONSDIALOG
     { "AlwaysQueenProc", AlwaysQueenProc },
     { "AnimateDraggingProc", AnimateDraggingProc },
     { "AnimateMovingProc", AnimateMovingProc },
     { "AutoflagProc", AutoflagProc },
     { "AutoflipProc", AutoflipProc },
-    { "AutobsProc", AutobsProc },
-    { "AutoraiseProc", AutoraiseProc },
-    { "AutosaveProc", AutosaveProc },
     { "BlindfoldProc", BlindfoldProc },
     { "FlashMovesProc", FlashMovesProc },
-    { "FlipViewProc", FlipViewProc },
-    { "GetMoveListProc", GetMoveListProc },
 #if HIGHDRAG
     { "HighlightDraggingProc", HighlightDraggingProc },
 #endif
     { "HighlightLastMoveProc", HighlightLastMoveProc },
-    { "IcsAlarmProc", IcsAlarmProc },
+//    { "IcsAlarmProc", IcsAlarmProc },
     { "MoveSoundProc", MoveSoundProc },
-    { "OldSaveStyleProc", OldSaveStyleProc },
     { "PeriodicUpdatesProc", PeriodicUpdatesProc },
-    { "PonderNextMoveProc", PonderNextMoveProc },
     { "PopupExitMessageProc", PopupExitMessageProc },
     { "PopupMoveErrorsProc", PopupMoveErrorsProc },
-    { "PremoveProc", PremoveProc },
-    { "QuietPlayProc", QuietPlayProc },
+//    { "PremoveProc", PremoveProc },
     { "ShowCoordsProc", ShowCoordsProc },
     { "ShowThinkingProc", ShowThinkingProc },
     { "HideThinkingProc", HideThinkingProc },
     { "TestLegalityProc", TestLegalityProc },
+#endif
     { "SaveSettingsProc", SaveSettingsProc },
     { "SaveOnExitProc", SaveOnExitProc },
     { "InfoProc", InfoProc },
@@ -999,7 +1029,6 @@ XtActionsRec boardActions[] = {
     { "NothingProc", NothingProc },
     { "CommentClick", (XtActionProc) CommentClick },
     { "CommentPopDown", (XtActionProc) CommentPopDown },
-    { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
     { "TagsPopDown", (XtActionProc) TagsPopDown },
     { "ErrorPopDown", (XtActionProc) ErrorPopDown },
     { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
@@ -1008,16 +1037,11 @@ XtActionsRec boardActions[] = {
     { "GameListPopDown", (XtActionProc) GameListPopDown },
     { "GameListOptionsPopDown", (XtActionProc) GameListOptionsPopDown },
     { "PromotionPopDown", (XtActionProc) PromotionPopDown },
-    { "HistoryPopDown", (XtActionProc) HistoryPopDown },
     { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
     { "EvalGraphPopDown", (XtActionProc) EvalGraphPopDown },
-    { "ShufflePopDown", (XtActionProc) ShufflePopDown },
-    { "EnginePopDown", (XtActionProc) EnginePopDown },
-    { "UciPopDown", (XtActionProc) UciPopDown },
-    { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
-    { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
-    { "SettingsPopDown", (XtActionProc) SettingsPopDown },
+    { "GenericPopDown", (XtActionProc) GenericPopDown },
     { "CopyMemoProc", (XtActionProc) CopyMemoProc },
+    { "SelectMove", (XtActionProc) SelectMove },
 };
 
 char globalTranslations[] =
@@ -1027,12 +1051,14 @@ char globalTranslations[] =
    :Ctrl<Key>o: LoadGameProc() \n \
    :Meta<Key>Next: LoadNextGameProc() \n \
    :Meta<Key>Prior: LoadPrevGameProc() \n \
+   :Ctrl<Key>Down: LoadSelectedProc(3) \n \
+   :Ctrl<Key>Up: LoadSelectedProc(-3) \n \
    :Ctrl<Key>s: SaveGameProc() \n \
    :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 \
@@ -1063,6 +1089,8 @@ char globalTranslations[] =
    :Meta<Key>Right: ForwardProc() \n \
    :Meta<Key>Home: ToStartProc() \n \
    :Meta<Key>Left: BackwardProc() \n \
+   :<Key>Left: BackwardProc() \n \
+   :<Key>Right: ForwardProc() \n \
    :<Key>Home: RevertProc() \n \
    :<Key>End: TruncateGameProc() \n \
    :Ctrl<Key>m: MoveNowProc() \n \
@@ -1070,12 +1098,16 @@ char globalTranslations[] =
    :Meta<Key>J: EngineMenuProc() \n \
    :Meta<Key>U: UciMenuProc() \n \
    :Meta<Key>T: TimeControlProc() \n \
+   :Ctrl<Key>P: PonderNextMoveProc() \n "
+#ifndef OPTIONSDIALOG
+    "\
    :Ctrl<Key>Q: AlwaysQueenProc() \n \
    :Ctrl<Key>F: AutoflagProc() \n \
    :Ctrl<Key>A: AnimateMovingProc() \n \
-   :Ctrl<Key>P: PonderNextMoveProc() \n \
    :Ctrl<Key>L: TestLegalityProc() \n \
-   :Ctrl<Key>H: HideThinkingProc() \n \
+   :Ctrl<Key>H: HideThinkingProc() \n "
+#endif
+   "\
    :<Key>-: Iconify() \n \
    :<Key>F1: ManProc() \n \
    :<Key>F2: FlipViewProc() \n \
@@ -1102,8 +1134,12 @@ char boardTranslations[] =
    Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
                  PieceMenuPopup(menuB) \n";
 
-char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
-char blackTranslations[] = "<BtnDown>: BlackClock()\n";
+char whiteTranslations[] =
+   "Shift<BtnDown>: WhiteClock(1)\n \
+   <BtnDown>: WhiteClock(0)\n";
+char blackTranslations[] =
+   "Shift<BtnDown>: BlackClock(1)\n \
+   <BtnDown>: BlackClock(0)\n";
 
 char ICSInputTranslations[] =
     "<Key>Up: UpKeyProc() \n "
@@ -1253,8 +1289,8 @@ xpm_closest_to(dirname, size, ext)
     fprintf(stderr, _("\
 Warning: No DIR structure found on this system --\n\
          Unable to autosize for XPM/XIM pieces.\n\
-   Please report this error to frankm@hiwaay.net.\n\
-   Include system type & operating system in message.\n"));
+   Please report this error to %s.\n\
+   Include system type & operating system in message.\n"), PACKAGE_BUGREPORT););
     return size;
 }
 #endif /* HAVE_DIR_STRUCT */
@@ -1401,7 +1437,7 @@ colorVariable[] = {
 // [HGM] font: keep a font for each square size, even non-stndard ones
 #define NUM_SIZES 18
 #define MAX_SIZE 130
-Boolean fontSet[NUM_FONTS], fontValid[NUM_FONTS][MAX_SIZE];
+Boolean fontIsSet[NUM_FONTS], fontValid[NUM_FONTS][MAX_SIZE];
 char *fontTable[NUM_FONTS][MAX_SIZE];
 
 void
@@ -1430,7 +1466,7 @@ ParseFont(char *name, int number)
     default:
       return;
   }
-  fontSet[number] = True; // [HGM] font: indicate a font was specified (not from settings file)
+  fontIsSet[number] = True; // [HGM] font: indicate a font was specified (not from settings file)
 }
 
 void
@@ -1479,7 +1515,7 @@ void
 SaveFontArg(FILE *f, ArgDescriptor *ad)
 {
   char *name;
-  int i, n = (int)ad->argLoc;
+  int i, n = (int)(intptr_t)ad->argLoc;
   switch(n) {
     case 0: // CLOCK_FONT
        name = appData.clockFont;
@@ -1500,7 +1536,7 @@ SaveFontArg(FILE *f, ArgDescriptor *ad)
        break;
   }
   for(i=0; i<MAX_SIZE; i++) if(fontValid[n][i]) // [HGM] font: store all standard fonts
-    fprintf(f, OPTCHAR "%s" SEPCHAR "size%d:%s\n", ad->argName, i, fontTable[n][i]);
+    fprintf(f, OPTCHAR "%s" SEPCHAR "\"size%d:%s\"\n", ad->argName, i, fontTable[n][i]);
 }
 
 void
@@ -1511,14 +1547,14 @@ ExportSounds()
 void
 SaveAttribsArg(FILE *f, ArgDescriptor *ad)
 {      // here the "argLoc" defines a table index. It could have contained the 'ta' pointer itself, though
-       fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, (&appData.colorShout)[(int)ad->argLoc]);
+       fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, (&appData.colorShout)[(int)(intptr_t)ad->argLoc]);
 }
 
 void
 SaveColor(FILE *f, ArgDescriptor *ad)
 {      // in WinBoard the color is an int and has to be converted to text. In X it would be a string already?
-       if(colorVariable[(int)ad->argLoc])
-       fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, *(char**)colorVariable[(int)ad->argLoc]);
+       if(colorVariable[(int)(intptr_t)ad->argLoc])
+       fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, *(char**)colorVariable[(int)(intptr_t)ad->argLoc]);
 }
 
 void
@@ -1533,7 +1569,7 @@ ParseCommPortSettings(char *s)
 }
 
 extern Widget engineOutputShell;
-extern Widget tagsShell, editTagsShell;
+
 void
 GetActualPlacement(Widget wg, WindowPlacement *wp)
 {
@@ -1561,14 +1597,12 @@ GetWindowCoords()
 { // wrapper to shield use of window handles from back-end (make addressible by number?)
   // In XBoard this will have to wait until awareness of window parameters is implemented
   GetActualPlacement(shellWidget, &wpMain);
-  if(EngineOutputIsUp()) GetActualPlacement(engineOutputShell, &wpEngineOutput); else
-  if(MoveHistoryIsUp()) GetActualPlacement(historyShell, &wpMoveHistory);
+  if(EngineOutputIsUp()) GetActualPlacement(engineOutputShell, &wpEngineOutput);
+  if(MoveHistoryIsUp()) GetActualPlacement(shells[7], &wpMoveHistory);
   if(EvalGraphIsUp()) GetActualPlacement(evalGraphShell, &wpEvalGraph);
   if(GameListIsUp()) GetActualPlacement(gameListShell, &wpGameList);
-  if(commentShell) GetActualPlacement(commentShell, &wpComment);
-  else             GetActualPlacement(editShell,    &wpComment);
-  if(tagsShell) GetActualPlacement(tagsShell, &wpTags);
-  else      GetActualPlacement(editTagsShell, &wpTags);
+  if(shellUp[1]) GetActualPlacement(shells[1], &wpComment);
+  if(shellUp[2]) GetActualPlacement(shells[2], &wpTags);
 }
 
 void
@@ -1622,7 +1656,7 @@ ConvertToLine(int argc, char **argv)
   line[0] = NULLCHAR;
   for(i=1; i<argc; i++)
     {
-      if( (strchr(argv[i], ' ') || strchr(argv[i], '\n') ||strchr(argv[i], '\t') )
+      if( (strchr(argv[i], ' ') || strchr(argv[i], '\n') ||strchr(argv[i], '\t') || argv[i][0] == NULLCHAR)
          && argv[i][0] != '{' )
        snprintf(buf, sizeof(buf)/sizeof(buf[0]), "{%s} ", argv[i]);
       else
@@ -1665,6 +1699,7 @@ void InitDrawingSizes(BoardSize boardSize, int flags)
     XtSetArg(args[0], XtNdefaultDistance, &sep);
     XtGetValues(formWidget, args, 1);
 
+    if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap;
     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
     CreateGrid();
@@ -1792,6 +1827,126 @@ void InitDrawingSizes(BoardSize boardSize, int flags)
 }
 #endif
 
+void ParseIcsTextColors()
+{   // [HGM] tken out of main(), so it can be called from ICS-Options dialog
+    if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
+       parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
+       parse_cpair(ColorChannel1, appData.colorChannel1) < 0  ||
+       parse_cpair(ColorChannel, appData.colorChannel) < 0  ||
+       parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
+       parse_cpair(ColorTell, appData.colorTell) < 0 ||
+       parse_cpair(ColorChallenge, appData.colorChallenge) < 0  ||
+       parse_cpair(ColorRequest, appData.colorRequest) < 0  ||
+       parse_cpair(ColorSeek, appData.colorSeek) < 0  ||
+       parse_cpair(ColorNormal, appData.colorNormal) < 0)
+      {
+         if (appData.colorize) {
+             fprintf(stderr,
+                     _("%s: can't parse color names; disabling colorization\n"),
+                     programName);
+         }
+         appData.colorize = FALSE;
+      }
+}
+
+int MakeColors()
+{   // [HGM] taken out of main(), so it can be called from BoardOptions dialog
+    XrmValue vFrom, vTo;
+    int forceMono = False;
+
+    if (!appData.monoMode) {
+       vFrom.addr = (caddr_t) appData.lightSquareColor;
+       vFrom.size = strlen(appData.lightSquareColor);
+       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
+       if (vTo.addr == NULL) {
+         appData.monoMode = True;
+         forceMono = True;
+       } else {
+         lightSquareColor = *(Pixel *) vTo.addr;
+       }
+    }
+    if (!appData.monoMode) {
+       vFrom.addr = (caddr_t) appData.darkSquareColor;
+       vFrom.size = strlen(appData.darkSquareColor);
+       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
+       if (vTo.addr == NULL) {
+         appData.monoMode = True;
+         forceMono = True;
+       } else {
+         darkSquareColor = *(Pixel *) vTo.addr;
+       }
+    }
+    if (!appData.monoMode) {
+       vFrom.addr = (caddr_t) appData.whitePieceColor;
+       vFrom.size = strlen(appData.whitePieceColor);
+       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
+       if (vTo.addr == NULL) {
+         appData.monoMode = True;
+         forceMono = True;
+       } else {
+         whitePieceColor = *(Pixel *) vTo.addr;
+       }
+    }
+    if (!appData.monoMode) {
+       vFrom.addr = (caddr_t) appData.blackPieceColor;
+       vFrom.size = strlen(appData.blackPieceColor);
+       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
+       if (vTo.addr == NULL) {
+         appData.monoMode = True;
+         forceMono = True;
+       } else {
+         blackPieceColor = *(Pixel *) vTo.addr;
+       }
+    }
+
+    if (!appData.monoMode) {
+       vFrom.addr = (caddr_t) appData.highlightSquareColor;
+       vFrom.size = strlen(appData.highlightSquareColor);
+       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
+       if (vTo.addr == NULL) {
+         appData.monoMode = True;
+         forceMono = True;
+       } else {
+         highlightSquareColor = *(Pixel *) vTo.addr;
+       }
+    }
+
+    if (!appData.monoMode) {
+       vFrom.addr = (caddr_t) appData.premoveHighlightColor;
+       vFrom.size = strlen(appData.premoveHighlightColor);
+       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
+       if (vTo.addr == NULL) {
+         appData.monoMode = True;
+         forceMono = True;
+       } else {
+         premoveHighlightColor = *(Pixel *) vTo.addr;
+       }
+    }
+    return forceMono;
+}
+
+void
+CreateAnyPieces()
+{   // [HGM] taken out of main
+#if HAVE_LIBXPM
+    if (appData.monoMode && // [HGM] no sense to go on to certain doom
+       (appData.bitmapDirectory == NULL || appData.bitmapDirectory[0] == NULLCHAR))
+           appData.bitmapDirectory = DEF_BITMAP_DIR;
+
+    if (appData.bitmapDirectory[0] != NULLCHAR) {
+      CreatePieces();
+    } else {
+      CreateXPMPieces();
+      CreateXPMBoard(appData.liteBackTextureFile, 1);
+      CreateXPMBoard(appData.darkBackTextureFile, 0);
+    }
+#else
+    CreateXIMPieces();
+    /* Create regular pieces */
+    if (!useImages) CreatePieces();
+#endif
+}
+
 int
 main(argc, argv)
      int argc;
@@ -1850,8 +2005,8 @@ main(argc, argv)
 
     { // [HGM] initstring: kludge to fix bad bug. expand '\n' characters in init string and computer string.
        static char buf[MSG_SIZ];
-       EscapeExpand(buf, appData.initString);
-       appData.initString = strdup(buf);
+       EscapeExpand(buf, appData.firstInitString);
+       appData.firstInitString = strdup(buf);
        EscapeExpand(buf, appData.secondInitString);
        appData.secondInitString = strdup(buf);
        EscapeExpand(buf, appData.firstComputerString);
@@ -1879,6 +2034,12 @@ main(argc, argv)
         setbuf(debugFP, NULL);
     }
 
+#if ENABLE_NLS
+    if (appData.debugMode) {
+      fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL));
+    }
+#endif
+
     /* [HGM,HR] make sure board size is acceptable */
     if(appData.NrFiles > BOARD_FILES ||
        appData.NrRanks > BOARD_RANKS   )
@@ -1956,11 +2117,11 @@ main(argc, argv)
        tinyLayout = szd->tinyLayout;
        // [HGM] font: use defaults from settings file if available and not overruled
     }
-    if(!fontSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize])
+    if(!fontIsSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize])
        appData.clockFont = fontTable[CLOCK_FONT][squareSize];
-    if(!fontSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize])
+    if(!fontIsSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize])
        appData.font = fontTable[MESSAGE_FONT][squareSize];
-    if(!fontSet[COORD_FONT] && fontValid[COORD_FONT][squareSize])
+    if(!fontIsSet[COORD_FONT] && fontValid[COORD_FONT][squareSize])
        appData.coordFont = fontTable[COORD_FONT][squareSize];
 
     /* Now, using squareSize as a hint, find a good XPM/XIM set size */
@@ -1981,6 +2142,7 @@ XBoard square size (hint): %d\n\
            fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
        }
     }
+    defaultLineGap = lineGap;
     if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap;
 
     /* [HR] height treated separately (hacked) */
@@ -2005,19 +2167,42 @@ XBoard square size (hint): %d\n\
     /*
      * Determine what fonts to use.
      */
+#if ENABLE_NLS
+    appData.font = InsertPxlSize(appData.font, fontPxlSize);
+    appData.clockFont = InsertPxlSize(appData.clockFont, clockFontPxlSize);
+    appData.coordFont = InsertPxlSize(appData.coordFont, coordFontPxlSize);
+    fontSet = CreateFontSet(appData.font);
+    clockFontSet = CreateFontSet(appData.clockFont);
+    {
+      /* For the coordFont, use the 0th font of the fontset. */
+      XFontSet coordFontSet = CreateFontSet(appData.coordFont);
+      XFontStruct **font_struct_list;
+      char **font_name_list;
+      XFontsOfFontSet(coordFontSet, &font_struct_list, &font_name_list);
+      coordFontID = XLoadFont(xDisplay, font_name_list[0]);
+      coordFontStruct = XQueryFont(xDisplay, coordFontID);
+    }
+#else
+    appData.font = FindFont(appData.font, fontPxlSize);
     appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
+    appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
     clockFontID = XLoadFont(xDisplay, appData.clockFont);
     clockFontStruct = XQueryFont(xDisplay, clockFontID);
-    appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
     coordFontID = XLoadFont(xDisplay, appData.coordFont);
     coordFontStruct = XQueryFont(xDisplay, coordFontID);
-    appData.font = FindFont(appData.font, fontPxlSize);
-    countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
-    countFontStruct = XQueryFont(xDisplay, countFontID);
-//    appData.font = FindFont(appData.font, fontPxlSize);
+#endif
+    countFontID = coordFontID;  // [HGM] holdings
+    countFontStruct = coordFontStruct;
 
     xdb = XtDatabase(xDisplay);
+#if ENABLE_NLS
+    XrmPutLineResource(&xdb, "*international: True");
+    vTo.size = sizeof(XFontSet);
+    vTo.addr = (XtPointer) &fontSet;
+    XrmPutResource(&xdb, "*fontSet", XtRFontSet, &vTo);
+#else
     XrmPutStringResource(&xdb, "*font", appData.font);
+#endif
 
     /*
      * Detect if there are not enough colors available and adapt.
@@ -2026,82 +2211,12 @@ XBoard square size (hint): %d\n\
       appData.monoMode = True;
     }
 
-    if (!appData.monoMode) {
-       vFrom.addr = (caddr_t) appData.lightSquareColor;
-       vFrom.size = strlen(appData.lightSquareColor);
-       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
-       if (vTo.addr == NULL) {
-         appData.monoMode = True;
-         forceMono = True;
-       } else {
-         lightSquareColor = *(Pixel *) vTo.addr;
-       }
-    }
-    if (!appData.monoMode) {
-       vFrom.addr = (caddr_t) appData.darkSquareColor;
-       vFrom.size = strlen(appData.darkSquareColor);
-       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
-       if (vTo.addr == NULL) {
-         appData.monoMode = True;
-         forceMono = True;
-       } else {
-         darkSquareColor = *(Pixel *) vTo.addr;
-       }
-    }
-    if (!appData.monoMode) {
-       vFrom.addr = (caddr_t) appData.whitePieceColor;
-       vFrom.size = strlen(appData.whitePieceColor);
-       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
-       if (vTo.addr == NULL) {
-         appData.monoMode = True;
-         forceMono = True;
-       } else {
-         whitePieceColor = *(Pixel *) vTo.addr;
-       }
-    }
-    if (!appData.monoMode) {
-       vFrom.addr = (caddr_t) appData.blackPieceColor;
-       vFrom.size = strlen(appData.blackPieceColor);
-       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
-       if (vTo.addr == NULL) {
-         appData.monoMode = True;
-         forceMono = True;
-       } else {
-         blackPieceColor = *(Pixel *) vTo.addr;
-       }
-    }
-
-    if (!appData.monoMode) {
-       vFrom.addr = (caddr_t) appData.highlightSquareColor;
-       vFrom.size = strlen(appData.highlightSquareColor);
-       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
-       if (vTo.addr == NULL) {
-         appData.monoMode = True;
-         forceMono = True;
-       } else {
-         highlightSquareColor = *(Pixel *) vTo.addr;
-       }
-    }
-
-    if (!appData.monoMode) {
-       vFrom.addr = (caddr_t) appData.premoveHighlightColor;
-       vFrom.size = strlen(appData.premoveHighlightColor);
-       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
-       if (vTo.addr == NULL) {
-         appData.monoMode = True;
-         forceMono = True;
-       } else {
-         premoveHighlightColor = *(Pixel *) vTo.addr;
-       }
-    }
+    forceMono = MakeColors();
 
     if (forceMono) {
       fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
              programName);
-
-      if (appData.bitmapDirectory == NULL ||
-             appData.bitmapDirectory[0] == NULLCHAR)
-           appData.bitmapDirectory = DEF_BITMAP_DIR;
+       appData.monoMode = True;
     }
 
     if (appData.lowTimeWarning && !appData.monoMode) {
@@ -2120,24 +2235,7 @@ XBoard square size (hint): %d\n\
                (unsigned long) XBlackPixel(xDisplay, xScreen));
     }
 
-    if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
-       parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
-       parse_cpair(ColorChannel1, appData.colorChannel1) < 0  ||
-       parse_cpair(ColorChannel, appData.colorChannel) < 0  ||
-       parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
-       parse_cpair(ColorTell, appData.colorTell) < 0 ||
-       parse_cpair(ColorChallenge, appData.colorChallenge) < 0  ||
-       parse_cpair(ColorRequest, appData.colorRequest) < 0  ||
-       parse_cpair(ColorSeek, appData.colorSeek) < 0  ||
-       parse_cpair(ColorNormal, appData.colorNormal) < 0)
-      {
-         if (appData.colorize) {
-             fprintf(stderr,
-                     _("%s: can't parse color names; disabling colorization\n"),
-                     programName);
-         }
-         appData.colorize = FALSE;
-      }
+    ParseIcsTextColors();
     textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
     textColors[ColorNone].attr = 0;
 
@@ -2174,7 +2272,11 @@ XBoard square size (hint): %d\n\
     widgetList[j++] = whiteTimerWidget =
       XtCreateWidget("whiteTime", labelWidgetClass,
                     formWidget, timerArgs, XtNumber(timerArgs));
+#if ENABLE_NLS
+    XtSetArg(args[0], XtNfontSet, clockFontSet);
+#else
     XtSetArg(args[0], XtNfont, clockFontStruct);
+#endif
     XtSetArg(args[1], XtNtop,    XtChainTop);
     XtSetArg(args[2], XtNbottom, XtChainTop);
     XtSetValues(whiteTimerWidget, args, 3);
@@ -2182,7 +2284,11 @@ XBoard square size (hint): %d\n\
     widgetList[j++] = blackTimerWidget =
       XtCreateWidget("blackTime", labelWidgetClass,
                     formWidget, timerArgs, XtNumber(timerArgs));
+#if ENABLE_NLS
+    XtSetArg(args[0], XtNfontSet, clockFontSet);
+#else
     XtSetArg(args[0], XtNfont, clockFontStruct);
+#endif
     XtSetArg(args[1], XtNtop,    XtChainTop);
     XtSetArg(args[2], XtNbottom, XtChainTop);
     XtSetValues(blackTimerWidget, args, 3);
@@ -2395,6 +2501,7 @@ XBoard square size (hint): %d\n\
     ReadBitmap(&xMarkPixmap, "checkmark.bm",
               checkmark_bits, checkmark_width, checkmark_height);
     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
+#ifndef OPTIONSDIALOG
     if (appData.alwaysPromoteToQueen) {
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
                    args, 1);
@@ -2408,10 +2515,6 @@ XBoard square size (hint): %d\n\
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
                    args, 1);
     }
-    if (appData.autoComment) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
-                   args, 1);
-    }
     if (appData.autoCallFlag) {
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
                    args, 1);
@@ -2420,26 +2523,6 @@ XBoard square size (hint): %d\n\
        XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
                    args, 1);
     }
-    if (appData.autoObserve) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
-                   args, 1);
-    }
-    if (appData.autoRaiseBoard) {
-       XtSetValues(XtNameToWidget(menuBarWidget,
-                                  "menuOptions.Auto Raise Board"), args, 1);
-    }
-    if (appData.autoSaveGames) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
-                   args, 1);
-    }
-    if (appData.saveGameFile[0] != NULLCHAR) {
-       /* Can't turn this off from menu */
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
-                   args, 1);
-       XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
-                      False);
-
-    }
     if (appData.blindfold) {
        XtSetValues(XtNameToWidget(menuBarWidget,
                                   "menuOptions.Blindfold"), args, 1);
@@ -2449,10 +2532,6 @@ XBoard square size (hint): %d\n\
                                   "menuOptions.Flash Moves"),
                    args, 1);
     }
-    if (appData.getMoveList) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
-                   args, 1);
-    }
 #if HIGHDRAG
     if (appData.highlightDragging) {
        XtSetValues(XtNameToWidget(menuBarWidget,
@@ -2465,17 +2544,22 @@ XBoard square size (hint): %d\n\
                                   "menuOptions.Highlight Last Move"),
                    args, 1);
     }
-    if (appData.icsAlarm) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
+    if (appData.highlightMoveWithArrow) {
+       XtSetValues(XtNameToWidget(menuBarWidget,
+                                  "menuOptions.Arrow"),
                    args, 1);
     }
+//    if (appData.icsAlarm) {
+//     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
+//                 args, 1);
+//    }
     if (appData.ringBellAfterMoves) {
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
                    args, 1);
     }
-    if (appData.oldSaveStyle) {
+    if (appData.oneClick) {
        XtSetValues(XtNameToWidget(menuBarWidget,
-                                  "menuOptions.Old Save Style"), args, 1);
+                                  "menuOptions.OneClick"), args, 1);
     }
     if (appData.periodicUpdates) {
        XtSetValues(XtNameToWidget(menuBarWidget,
@@ -2493,14 +2577,10 @@ XBoard square size (hint): %d\n\
        XtSetValues(XtNameToWidget(menuBarWidget,
                                   "menuOptions.Popup Move Errors"), args, 1);
     }
-    if (appData.premove) {
-       XtSetValues(XtNameToWidget(menuBarWidget,
-                                  "menuOptions.Premove"), args, 1);
-    }
-    if (appData.quietPlay) {
-       XtSetValues(XtNameToWidget(menuBarWidget,
-                                  "menuOptions.Quiet Play"), args, 1);
-    }
+//    if (appData.premove) {
+//     XtSetValues(XtNameToWidget(menuBarWidget,
+//                                "menuOptions.Premove"), args, 1);
+//    }
     if (appData.showCoords) {
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
                    args, 1);
@@ -2513,6 +2593,7 @@ XBoard square size (hint): %d\n\
        XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
                    args, 1);
     }
+#endif
     if (saveSettingsOnExit) {
        XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Save Settings on Exit"),
                    args, 1);
@@ -2551,21 +2632,9 @@ XBoard square size (hint): %d\n\
 
     CatchDeleteWindow(shellWidget, "QuitProc");
 
-    CreateGCs();
+    CreateGCs(False);
     CreateGrid();
-#if HAVE_LIBXPM
-    if (appData.bitmapDirectory[0] != NULLCHAR) {
-      CreatePieces();
-    } else {
-      CreateXPMPieces();
-      CreateXPMBoard(appData.liteBackTextureFile, 1);
-      CreateXPMBoard(appData.darkBackTextureFile, 0);
-    }
-#else
-    CreateXIMPieces();
-    /* Create regular pieces */
-    if (!useImages) CreatePieces();
-#endif
+    CreateAnyPieces();
 
     CreatePieceMenus();
 
@@ -2586,6 +2655,8 @@ XBoard square size (hint): %d\n\
     XtAddEventHandler(boardWidget, ExposureMask|PointerMotionMask, False,
                      (XtEventHandler) EventProc, NULL);
     /* end why */
+    XtAddEventHandler(formWidget, KeyPressMask, False,
+                     (XtEventHandler) MoveTypeInProc, NULL);
 
     /* [AS] Restore layout */
     if( wpMoveHistory.visible ) {
@@ -2622,13 +2693,16 @@ XBoard square size (hint): %d\n\
     }
     gameInfo.boardWidth = 0; // [HGM] pieces: kludge to ensure InitPosition() calls InitDrawingSizes()
     InitPosition(TRUE);
-    XtSetKeyboardFocus(shellWidget, formWidget);
+//    XtSetKeyboardFocus(shellWidget, formWidget);
+    XSetInputFocus(xDisplay, XtWindow(formWidget), RevertToPointerRoot, CurrentTime);
 
     XtAppMainLoop(appContext);
     if (appData.debugMode) fclose(debugFP); // [DM] debug
     return 0;
 }
 
+static Boolean noEcho;
+
 void
 ShutDownFrontEnd()
 {
@@ -2638,6 +2712,7 @@ ShutDownFrontEnd()
     if (saveSettingsOnExit) SaveSettings(settingsFileName);
     unlink(gameCopyFilename);
     unlink(gamePasteFilename);
+    if(noEcho) EchoOn();
 }
 
 RETSIGTYPE TermSizeSigHandler(int sig)
@@ -2717,7 +2792,6 @@ void
 ResetFrontEnd()
 {
     CommentPopDown();
-    EditCommentPopDown();
     TagsPopDown();
     return;
 }
@@ -2772,17 +2846,22 @@ Enables icsEnables[] = {
     { "menuMode.Analysis Mode", False },
     { "menuMode.Analyze File", False },
     { "menuMode.Two Machines", False },
+    { "menuMode.Machine Match", False },
 #ifndef ZIPPY
     { "menuEngine.Hint", False },
     { "menuEngine.Book", False },
     { "menuEngine.Move Now", False },
+#ifndef OPTIONSDIALOG
     { "menuOptions.Periodic Updates", False },
     { "menuOptions.Hide Thinking", False },
     { "menuOptions.Ponder Next Move", False },
-    { "menuEngine.Engine #1 Settings", False },
 #endif
+#endif
+    { "menuEngine.Engine #1 Settings", False },
     { "menuEngine.Engine #2 Settings", False },
+    { "menuEngine.Load Engine", False },
     { "menuEdit.Annotate", False },
+    { "menuOptions.Match", False },
     { NULL, False }
 };
 
@@ -2794,7 +2873,9 @@ Enables ncpEnables[] = {
     { "menuMode.Analysis Mode", False },
     { "menuMode.Analyze File", False },
     { "menuMode.Two Machines", False },
+    { "menuMode.Machine Match", False },
     { "menuMode.ICS Client", False },
+    { "menuView.ICStex", False },
     { "menuView.ICS Input Box", False },
     { "Action", False },
     { "menuEdit.Revert", False },
@@ -2803,18 +2884,16 @@ Enables ncpEnables[] = {
     { "menuEngine.Engine #2 Settings", False },
     { "menuEngine.Move Now", False },
     { "menuEngine.Retract Move", False },
-    { "menuOptions.Auto Comment", False },
+    { "menuOptions.ICS", False },
+#ifndef OPTIONSDIALOG
     { "menuOptions.Auto Flag", False },
     { "menuOptions.Auto Flip View", False },
-    { "menuOptions.Auto Observe", False },
-    { "menuOptions.Auto Raise Board", False },
-    { "menuOptions.Get Move List", False },
-    { "menuOptions.ICS Alarm", False },
+//    { "menuOptions.ICS Alarm", False },
     { "menuOptions.Move Sound", False },
-    { "menuOptions.Quiet Play", False },
     { "menuOptions.Hide Thinking", False },
     { "menuOptions.Periodic Updates", False },
     { "menuOptions.Ponder Next Move", False },
+#endif
     { "menuEngine.Hint", False },
     { "menuEngine.Book", False },
     { NULL, False }
@@ -2822,6 +2901,7 @@ Enables ncpEnables[] = {
 
 Enables gnuEnables[] = {
     { "menuMode.ICS Client", False },
+    { "menuView.ICStex", False },
     { "menuView.ICS Input Box", False },
     { "menuAction.Accept", False },
     { "menuAction.Decline", False },
@@ -2832,12 +2912,7 @@ Enables gnuEnables[] = {
     { "menuAction.Upload to Examine", False },
     { "menuEdit.Revert", False },
     { "menuEdit.Annotate", False },
-    { "menuOptions.Auto Comment", False },
-    { "menuOptions.Auto Observe", False },
-    { "menuOptions.Auto Raise Board", False },
-    { "menuOptions.Get Move List", False },
-    { "menuOptions.Premove", False },
-    { "menuOptions.Quiet Play", False },
+    { "menuOptions.ICS", False },
 
     /* The next two options rely on SetCmailMode being called *after*    */
     /* SetGNUMode so that when GNU is being used to give hints these     */
@@ -2845,6 +2920,20 @@ Enables gnuEnables[] = {
 
     { "menuFile.Mail Move", False },
     { "menuFile.Reload CMail Message", False },
+    // [HGM] The following have been added to make a switch from ncp to GNU mode possible
+    { "menuMode.Machine White", True },
+    { "menuMode.Machine Black", True },
+    { "menuMode.Analysis Mode", True },
+    { "menuMode.Analyze File", True },
+    { "menuMode.Two Machines", True },
+    { "menuMode.Machine Match", True },
+    { "menuEngine.Engine #1 Settings", True },
+    { "menuEngine.Engine #2 Settings", True },
+    { "menuEngine.Hint", True },
+    { "menuEngine.Book", True },
+    { "menuEngine.Move Now", True },
+    { "menuEngine.Retract Move", True },
+    { "Action", True },
     { NULL, False }
 };
 
@@ -2899,6 +2988,7 @@ Enables machineThinkingEnables[] = {
   { "menuMode.Machine White", False },
   { "menuMode.Machine Black", False },
   { "menuMode.Two Machines", False },
+//  { "menuMode.Machine Match", False },
   { "menuEngine.Retract Move", False },
   { NULL, False }
 };
@@ -2917,6 +3007,7 @@ Enables userThinkingEnables[] = {
   { "menuMode.Machine White", True },
   { "menuMode.Machine Black", True },
   { "menuMode.Two Machines", True },
+//  { "menuMode.Machine Match", True },
   { "menuEngine.Retract Move", True },
   { NULL, False }
 };
@@ -2926,8 +3017,10 @@ void SetICSMode()
   SetMenuEnables(icsEnables);
 
 #if ZIPPY
-  if (appData.zippyPlay && !appData.noChessProgram)   /* [DM] icsEngineAnalyze */
+  if (appData.zippyPlay && !appData.noChessProgram) { /* [DM] icsEngineAnalyze */
      XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
+     XtSetSensitive(XtNameToWidget(menuBarWidget, "menuEngine.Engine #1 Settings"), True);
+  }
 #endif
 }
 
@@ -3039,6 +3132,96 @@ NextInHistory()
 
 #define Abs(n) ((n)<0 ? -(n) : (n))
 
+#ifdef ENABLE_NLS
+char *
+InsertPxlSize(pattern, targetPxlSize)
+     char *pattern;
+     int targetPxlSize;
+{
+    char *base_fnt_lst, strInt[12], *p, *q;
+    int alternatives, i, len, strIntLen;
+
+    /*
+     * Replace the "*" (if present) in the pixel-size slot of each
+     * alternative with the targetPxlSize.
+     */
+    p = pattern;
+    alternatives = 1;
+    while ((p = strchr(p, ',')) != NULL) {
+      alternatives++;
+      p++;
+    }
+    snprintf(strInt, sizeof(strInt), "%d", targetPxlSize);
+    strIntLen = strlen(strInt);
+    base_fnt_lst = calloc(1, strlen(pattern) + strIntLen * alternatives + 1);
+
+    p = pattern;
+    q = base_fnt_lst;
+    while (alternatives--) {
+      char *comma = strchr(p, ',');
+      for (i=0; i<14; i++) {
+       char *hyphen = strchr(p, '-');
+       if (!hyphen) break;
+       if (comma && hyphen > comma) break;
+       len = hyphen + 1 - p;
+       if (i == 7 && *p == '*' && len == 2) {
+         p += len;
+         memcpy(q, strInt, strIntLen);
+         q += strIntLen;
+         *q++ = '-';
+       } else {
+         memcpy(q, p, len);
+         p += len;
+         q += len;
+       }
+      }
+      if (!comma) break;
+      len = comma + 1 - p;
+      memcpy(q, p, len);
+      p += len;
+      q += len;
+    }
+    strcpy(q, p);
+
+    return base_fnt_lst;
+}
+
+XFontSet
+CreateFontSet(base_fnt_lst)
+     char *base_fnt_lst;
+{
+    XFontSet fntSet;
+    char **missing_list;
+    int missing_count;
+    char *def_string;
+
+    fntSet = XCreateFontSet(xDisplay, base_fnt_lst,
+                           &missing_list, &missing_count, &def_string);
+    if (appData.debugMode) {
+      int i, count;
+      XFontStruct **font_struct_list;
+      char **font_name_list;
+      fprintf(debugFP, "Requested font set for list %s\n", base_fnt_lst);
+      if (fntSet) {
+       fprintf(debugFP, " got list %s, locale %s\n",
+               XBaseFontNameListOfFontSet(fntSet),
+               XLocaleOfFontSet(fntSet));
+       count = XFontsOfFontSet(fntSet, &font_struct_list, &font_name_list);
+       for (i = 0; i < count; i++) {
+         fprintf(debugFP, " got charset %s\n", font_name_list[i]);
+       }
+      }
+      for (i = 0; i < missing_count; i++) {
+       fprintf(debugFP, " missing charset %s\n", missing_list[i]);
+      }
+    }
+    if (fntSet == NULL) {
+      fprintf(stderr, _("Unable to create font set for %s.\n"), base_fnt_lst);
+      exit(2);
+    }
+    return fntSet;
+}
+#else // not ENABLE_NLS
 /*
  * Find a font that matches "pattern" that is as close as
  * possible to the targetPxlSize.  Prefer fonts that are k
@@ -3056,39 +3239,12 @@ FindFont(pattern, targetPxlSize)
     char **fonts, *p, *best, *scalable, *scalableTail;
     int i, j, nfonts, minerr, err, pxlSize;
 
-#ifdef ENABLE_NLS
-    char **missing_list;
-    int missing_count;
-    char *def_string, *base_fnt_lst, strInt[3];
-    XFontSet fntSet;
-    XFontStruct **fnt_list;
-
-    base_fnt_lst = calloc(1, strlen(pattern) + 3);
-    snprintf(strInt, sizeof(strInt)/sizeof(strInt[0]), "%d", targetPxlSize);
-    p = strstr(pattern, "--");
-    strncpy(base_fnt_lst, pattern, p - pattern + 2);
-    strcat(base_fnt_lst, strInt);
-    strcat(base_fnt_lst, strchr(p + 2, '-'));
-
-    if ((fntSet = XCreateFontSet(xDisplay,
-                                 base_fnt_lst,
-                                 &missing_list,
-                                 &missing_count,
-                                 &def_string)) == NULL) {
-
-       fprintf(stderr, _("Unable to create font set.\n"));
-       exit (2);
-    }
-
-    nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
-#else
     fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
     if (nfonts < 1) {
        fprintf(stderr, _("%s: no fonts match pattern %s\n"),
                programName, pattern);
        exit(2);
     }
-#endif
 
     best = fonts[0];
     scalable = NULL;
@@ -3130,17 +3286,37 @@ FindFont(pattern, targetPxlSize)
         fprintf(debugFP, _("resolved %s at pixel size %d\n  to %s\n"),
                pattern, targetPxlSize, p);
     }
-#ifdef ENABLE_NLS
-    if (missing_count > 0)
-       XFreeStringList(missing_list);
-    XFreeFontSet(xDisplay, fntSet);
-#else
-     XFreeFontNames(fonts);
-#endif
+    XFreeFontNames(fonts);
     return p;
 }
+#endif
+
+void DeleteGCs()
+{   // [HGM] deletes GCs that are to be remade, to prevent resource leak;
+    // must be called before all non-first callse to CreateGCs()
+    XtReleaseGC(shellWidget, highlineGC);
+    XtReleaseGC(shellWidget, lightSquareGC);
+    XtReleaseGC(shellWidget, darkSquareGC);
+    XtReleaseGC(shellWidget, lineGC);
+    if (appData.monoMode) {
+       if (DefaultDepth(xDisplay, xScreen) == 1) {
+           XtReleaseGC(shellWidget, wbPieceGC);
+       } else {
+           XtReleaseGC(shellWidget, bwPieceGC);
+       }
+    } else {
+       XtReleaseGC(shellWidget, prelineGC);
+       XtReleaseGC(shellWidget, jailSquareGC);
+       XtReleaseGC(shellWidget, wdPieceGC);
+       XtReleaseGC(shellWidget, wlPieceGC);
+       XtReleaseGC(shellWidget, wjPieceGC);
+       XtReleaseGC(shellWidget, bdPieceGC);
+       XtReleaseGC(shellWidget, blPieceGC);
+       XtReleaseGC(shellWidget, bjPieceGC);
+    }
+}
 
-void CreateGCs()
+void CreateGCs(int redo)
 {
     XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
       | GCBackground | GCFunction | GCPlaneMask;
@@ -3152,20 +3328,23 @@ void CreateGCs()
     gc_values.line_style = LineSolid;
     gc_values.function = GXcopy;
 
-    gc_values.foreground = XBlackPixel(xDisplay, xScreen);
-    gc_values.background = XBlackPixel(xDisplay, xScreen);
-    lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
+  if(redo) {
+    DeleteGCs(); // called a second time; clean up old GCs first
+  } else { // [HGM] grid and font GCs created on first call only
     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
     gc_values.background = XWhitePixel(xDisplay, xScreen);
     coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
     XSetFont(xDisplay, coordGC, coordFontID);
 
-    // [HGM] make font for holdings counts (white on black0
+    // [HGM] make font for holdings counts (white on black)
     gc_values.foreground = XWhitePixel(xDisplay, xScreen);
     gc_values.background = XBlackPixel(xDisplay, xScreen);
     countGC = XtGetGC(shellWidget, value_mask, &gc_values);
     XSetFont(xDisplay, countGC, countFontID);
+  }
+    gc_values.foreground = XBlackPixel(xDisplay, xScreen);
+    gc_values.background = XBlackPixel(xDisplay, xScreen);
+    lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
 
     if (appData.monoMode) {
        gc_values.foreground = XWhitePixel(xDisplay, xScreen);
@@ -3293,6 +3472,8 @@ void loadXIM(xim, xmask, filename, dest, mask)
        }
     }
 
+    fclose(fp);
+
     /* create Pixmap of piece */
     *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
                          w, h, xim->depth);
@@ -3413,17 +3594,31 @@ void CreateXIMPieces()
     XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
 }
 
+static VariantClass oldVariant = (VariantClass) -1; // [HGM] pieces: redo every time variant changes
+
 #if HAVE_LIBXPM
 void CreateXPMBoard(char *s, int kind)
 {
     XpmAttributes attr;
     attr.valuemask = 0;
-    if(s == NULL || *s == 0 || *s == '*') return;
+    if(!appData.useBitmaps || s == NULL || *s == 0 || *s == '*') { useTexture &= ~(kind+1); return; }
     if (XpmReadFileToPixmap(xDisplay, xBoardWindow, s, &(xpmBoardBitmap[kind]), NULL, &attr) == 0) {
        useTexture |= kind + 1; textureW[kind] = attr.width; textureH[kind] = attr.height;
     }
 }
 
+void FreeXPMPieces()
+{   // [HGM] to prevent resoucre leak on calling CreaeXPMPieces() a second time,
+    // thisroutine has to be called t free the old piece pixmaps
+    int piece, kind;
+    for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++)
+       for (kind=0; kind<4; kind++) XFreePixmap(xDisplay, xpmPieceBitmap2[kind][piece]);
+    if(useImageSqs) {
+       XFreePixmap(xDisplay, xpmLightSquare);
+       XFreePixmap(xDisplay, xpmDarkSquare);
+    }
+}
+
 void CreateXPMPieces()
 {
     int piece, kind, r;
@@ -3432,6 +3627,9 @@ void CreateXPMPieces()
     XpmAttributes attr;
     static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
     XpmColorSymbol symbols[4];
+    static int redo = False;
+
+    if(redo) FreeXPMPieces(); else redo = 1;
 
     /* The XSynchronize calls were copied from CreatePieces.
        Not sure if needed, but can't hurt */
@@ -3556,6 +3754,7 @@ void CreateXPMPieces()
        xpmJailSquare = xpmLightSquare;
        fprintf(stderr, _("Done.\n"));
     }
+    oldVariant = -1; // kludge to force re-makig of animation masks
     XSynchronize(xDisplay, False); /* Work-around for xlib/xt
                                      buffering bug */
 }
@@ -3721,10 +3920,10 @@ void CreateMenuBarPopup(parent, name, mb)
     mi = mb->mi;
     while (mi->string != NULL) {
        if (strcmp(mi->string, "----") == 0) {
-           entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,
+         entry = XtCreateManagedWidget(_(mi->string), smeLineObjectClass,
                                          menu, args, j);
        } else {
-          XtSetArg(args[j], XtNlabel, XtNewString(mi->string));
+          XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string)));
            entry = XtCreateManagedWidget(mi->ref, smeBSBObjectClass,
                                          menu, args, j+1);
            XtAddCallback(entry, XtNcallback,
@@ -3762,7 +3961,7 @@ Widget CreateMenuBar(mb)
            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++;
@@ -3910,7 +4109,8 @@ void PieceMenuPopup(w, event, params, num_params)
      String *params;
      Cardinal *num_params;
 {
-    String whichMenu; int menuNr;
+    String whichMenu; int menuNr = -2;
+    shiftKey = strcmp(params[0], "menuW"); // used to indicate black
     if (event->type == ButtonRelease)
         menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY);
     else if (event->type == ButtonPress)
@@ -3949,11 +4149,8 @@ void WhiteClock(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    if (gameMode == EditPosition || gameMode == IcsExamining) {
-       SetWhiteToPlayEvent();
-    } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
-       CallFlagEvent();
-    }
+    shiftKey = prms[0][0] & 1;
+    ClockClick(0);
 }
 
 void BlackClock(w, event, prms, nprms)
@@ -3962,11 +4159,8 @@ void BlackClock(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    if (gameMode == EditPosition || gameMode == IcsExamining) {
-       SetBlackToPlayEvent();
-    } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
-       CallFlagEvent();
-    }
+    shiftKey = prms[0][0] & 1;
+    ClockClick(1);
 }
 
 
@@ -4263,7 +4457,7 @@ static void colorDrawPieceImage(piece, square_color, x, y, dest)
        }
        break;
     }
-    if(appData.upsideDown && flipView) kind ^= 2; // swap white and black pieces
+    if(appData.upsideDown && flipView) { kind ^= 2; p += p < BlackPawn ? BlackPawn : -BlackPawn; }// swap white and black pieces
     if(useTexture & square_color+1) {
         BlankSquare(x, y, square_color, piece, dest, 1); // erase previous contents with background
        XSetClipMask(xDisplay, wlPieceGC, xpmMask[p]);
@@ -4388,9 +4582,9 @@ void DrawSquare(row, column, piece, do_flash)
                        BlankSquare(x, y, square_color, piece, xBoardWindow, 1);
            } else {
                        drawfunc = ChooseDrawFunc();
+
                        if (do_flash && appData.flashCount > 0) {
                            for (i=0; i<appData.flashCount; ++i) {
-
                                        drawfunc(piece, square_color, x, y, xBoardWindow);
                                        XSync(xDisplay, False);
                                        do_flash_delay(flash_delay);
@@ -4489,7 +4683,6 @@ static int too_many_diffs(b1, b2)
            }
        }
     }
-
     return 0;
 }
 
@@ -4605,9 +4798,12 @@ 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 ( lineGap && IsDrawArrowEnabled())
+           XDrawSegments(xDisplay, xBoardWindow, lineGC,
+                       gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);
+
        /* If too much changes (begin observing new game, etc.), don't
           do flashing */
        do_flash = too_many_diffs(board, lastBoard[nr]) ? 0 : 1;
@@ -4731,6 +4927,7 @@ void HandleUserMove(w, event, prms, nprms)
 void AnimateUserMove (Widget w, XEvent * event,
                      String * params, Cardinal * nParams)
 {
+    if(!PromoScroll(event->xmotion.x, event->xmotion.y))
     DragPieceMove(event->xmotion.x, event->xmotion.y);
 }
 
@@ -4740,264 +4937,6 @@ void HandlePV (Widget w, XEvent * event,
     MovePV(event->xmotion.x, event->xmotion.y, lineGap + BOARD_HEIGHT * (squareSize + lineGap));
 }
 
-Widget CommentCreate(name, text, mutable, callback, lines)
-     char *name, *text;
-     int /*Boolean*/ mutable;
-     XtCallbackProc callback;
-     int lines;
-{
-    Arg args[16];
-    Widget shell, layout, form, edit, b_ok, b_cancel, b_clear, b_close, b_edit;
-    Dimension bw_width;
-    int j;
-
-    j = 0;
-    XtSetArg(args[j], XtNwidth, &bw_width);  j++;
-    XtGetValues(boardWidget, args, j);
-
-    j = 0;
-    XtSetArg(args[j], XtNresizable, True);  j++;
-#if TOPLEVEL
-    shell =
-      XtCreatePopupShell(name, topLevelShellWidgetClass,
-                        shellWidget, args, j);
-#else
-    shell =
-      XtCreatePopupShell(name, transientShellWidgetClass,
-                        shellWidget, args, j);
-#endif
-    layout =
-      XtCreateManagedWidget(layoutName, formWidgetClass, shell,
-                           layoutArgs, XtNumber(layoutArgs));
-    form =
-      XtCreateManagedWidget("form", formWidgetClass, layout,
-                           formArgs, XtNumber(formArgs));
-
-    j = 0;
-    if (mutable) {
-       XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;
-       XtSetArg(args[j], XtNuseStringInPlace, False);  j++;
-    }
-    XtSetArg(args[j], XtNstring, text);  j++;
-    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
-    XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
-    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
-    XtSetArg(args[j], XtNright, XtChainRight);  j++;
-    XtSetArg(args[j], XtNresizable, True);  j++;
-    XtSetArg(args[j], XtNwidth, bw_width);  j++; /*force wider than buttons*/
-    /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
-    XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways);  j++;
-    XtSetArg(args[j], XtNautoFill, True);  j++;
-    XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
-    edit =
-      XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
-    XtOverrideTranslations(edit, XtParseTranslationTable(commentTranslations));
-
-    if (mutable) {
-       j = 0;
-       XtSetArg(args[j], XtNfromVert, edit);  j++;
-       XtSetArg(args[j], XtNtop, XtChainBottom); j++;
-       XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
-       XtSetArg(args[j], XtNleft, XtChainLeft); j++;
-       XtSetArg(args[j], XtNright, XtChainLeft); j++;
-       b_ok =
-         XtCreateManagedWidget(_("ok"), commandWidgetClass, form, args, j);
-       XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);
-
-       j = 0;
-       XtSetArg(args[j], XtNfromVert, edit);  j++;
-       XtSetArg(args[j], XtNfromHoriz, b_ok);  j++;
-       XtSetArg(args[j], XtNtop, XtChainBottom); j++;
-       XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
-       XtSetArg(args[j], XtNleft, XtChainLeft); j++;
-       XtSetArg(args[j], XtNright, XtChainLeft); j++;
-       b_cancel =
-         XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j);
-       XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);
-
-       j = 0;
-       XtSetArg(args[j], XtNfromVert, edit);  j++;
-       XtSetArg(args[j], XtNfromHoriz, b_cancel);  j++;
-       XtSetArg(args[j], XtNtop, XtChainBottom); j++;
-       XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
-       XtSetArg(args[j], XtNleft, XtChainLeft); j++;
-       XtSetArg(args[j], XtNright, XtChainLeft); j++;
-       b_clear =
-         XtCreateManagedWidget(_("clear"), commandWidgetClass, form, args, j);
-       XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);
-    } else {
-       j = 0;
-       XtSetArg(args[j], XtNfromVert, edit);  j++;
-       XtSetArg(args[j], XtNtop, XtChainBottom); j++;
-       XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
-       XtSetArg(args[j], XtNleft, XtChainLeft); j++;
-       XtSetArg(args[j], XtNright, XtChainLeft); j++;
-       b_close =
-         XtCreateManagedWidget(_("close"), commandWidgetClass, form, args, j);
-       XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);
-
-       j = 0;
-       XtSetArg(args[j], XtNfromVert, edit);  j++;
-       XtSetArg(args[j], XtNfromHoriz, b_close);  j++;
-       XtSetArg(args[j], XtNtop, XtChainBottom); j++;
-       XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
-       XtSetArg(args[j], XtNleft, XtChainLeft); j++;
-       XtSetArg(args[j], XtNright, XtChainLeft); j++;
-       b_edit =
-         XtCreateManagedWidget(_("edit"), commandWidgetClass, form, args, j);
-       XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);
-    }
-
-    XtRealizeWidget(shell);
-
-    if (commentX == -1) {
-       int xx, yy;
-       Window junk;
-       Dimension pw_height;
-       Dimension ew_height;
-
-       j = 0;
-       XtSetArg(args[j], XtNheight, &ew_height);  j++;
-       XtGetValues(edit, args, j);
-
-       j = 0;
-       XtSetArg(args[j], XtNheight, &pw_height);  j++;
-       XtGetValues(shell, args, j);
-       commentH = pw_height + (lines - 1) * ew_height;
-       commentW = bw_width - 16;
-
-       XSync(xDisplay, False);
-#ifdef NOTDEF
-       /* This code seems to tickle an X bug if it is executed too soon
-          after xboard starts up.  The coordinates get transformed as if
-          the main window was positioned at (0, 0).
-          */
-       XtTranslateCoords(shellWidget,
-                         (bw_width - commentW) / 2, 0 - commentH / 2,
-                         &commentX, &commentY);
-#else  /*!NOTDEF*/
-        XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
-                             RootWindowOfScreen(XtScreen(shellWidget)),
-                             (bw_width - commentW) / 2, 0 - commentH / 2,
-                             &xx, &yy, &junk);
-       commentX = xx;
-       commentY = yy;
-#endif /*!NOTDEF*/
-       if (commentY < 0) commentY = 0; /*avoid positioning top offscreen*/
-    }
-
-    if(wpComment.width > 0) {
-      commentX = wpComment.x;
-      commentY = wpComment.y;
-      commentW = wpComment.width;
-      commentH = wpComment.height;
-    }
-
-    j = 0;
-    XtSetArg(args[j], XtNheight, commentH);  j++;
-    XtSetArg(args[j], XtNwidth, commentW);  j++;
-    XtSetArg(args[j], XtNx, commentX);  j++;
-    XtSetArg(args[j], XtNy, commentY);  j++;
-    XtSetValues(shell, args, j);
-    XtSetKeyboardFocus(shell, edit);
-
-    return shell;
-}
-
-/* Used for analysis window and ICS input window */
-Widget MiscCreate(name, text, mutable, callback, lines)
-     char *name, *text;
-     int /*Boolean*/ mutable;
-     XtCallbackProc callback;
-     int lines;
-{
-    Arg args[16];
-    Widget shell, layout, form, edit;
-    Position x, y;
-    Dimension bw_width, pw_height, ew_height, w, h;
-    int j;
-    int xx, yy;
-    Window junk;
-
-    j = 0;
-    XtSetArg(args[j], XtNresizable, True);  j++;
-#if TOPLEVEL
-    shell =
-      XtCreatePopupShell(name, topLevelShellWidgetClass,
-                        shellWidget, args, j);
-#else
-    shell =
-      XtCreatePopupShell(name, transientShellWidgetClass,
-                        shellWidget, args, j);
-#endif
-    layout =
-      XtCreateManagedWidget(layoutName, formWidgetClass, shell,
-                           layoutArgs, XtNumber(layoutArgs));
-    form =
-      XtCreateManagedWidget("form", formWidgetClass, layout,
-                           formArgs, XtNumber(formArgs));
-
-    j = 0;
-    if (mutable) {
-       XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;
-       XtSetArg(args[j], XtNuseStringInPlace, False);  j++;
-    }
-    XtSetArg(args[j], XtNstring, text);  j++;
-    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
-    XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
-    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
-    XtSetArg(args[j], XtNright, XtChainRight);  j++;
-    XtSetArg(args[j], XtNresizable, True);  j++;
-    /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
-    XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways);  j++;
-    XtSetArg(args[j], XtNautoFill, True);  j++;
-    XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
-    edit =
-      XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
-
-    XtRealizeWidget(shell);
-
-    j = 0;
-    XtSetArg(args[j], XtNwidth, &bw_width);  j++;
-    XtGetValues(boardWidget, args, j);
-
-    j = 0;
-    XtSetArg(args[j], XtNheight, &ew_height);  j++;
-    XtGetValues(edit, args, j);
-
-    j = 0;
-    XtSetArg(args[j], XtNheight, &pw_height);  j++;
-    XtGetValues(shell, args, j);
-    h = pw_height + (lines - 1) * ew_height;
-    w = bw_width - 16;
-
-    XSync(xDisplay, False);
-#ifdef NOTDEF
-    /* This code seems to tickle an X bug if it is executed too soon
-       after xboard starts up.  The coordinates get transformed as if
-       the main window was positioned at (0, 0).
-    */
-    XtTranslateCoords(shellWidget, (bw_width - w) / 2, 0 - h / 2, &x, &y);
-#else  /*!NOTDEF*/
-    XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
-                         RootWindowOfScreen(XtScreen(shellWidget)),
-                         (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk);
-#endif /*!NOTDEF*/
-    x = xx;
-    y = yy;
-    if (y < 0) y = 0; /*avoid positioning top offscreen*/
-
-    j = 0;
-    XtSetArg(args[j], XtNheight, h);  j++;
-    XtSetArg(args[j], XtNwidth, w);  j++;
-    XtSetArg(args[j], XtNx, x);  j++;
-    XtSetArg(args[j], XtNy, y);  j++;
-    XtSetValues(shell, args, j);
-
-    return shell;
-}
-
-
 static int savedIndex;  /* gross that this is global */
 
 void CommentClick (Widget w, XEvent * event, String * params, Cardinal * nParams)
@@ -5018,128 +4957,18 @@ void EditCommentPopUp(index, title, text)
      int index;
      char *title, *text;
 {
-    Widget edit;
-    Arg args[16];
-    int j;
-
     savedIndex = index;
     if (text == NULL) text = "";
-
-    if (editShell == NULL) {
-       editShell =
-         CommentCreate(title, text, True, EditCommentCallback, 4);
-       XtRealizeWidget(editShell);
-       CatchDeleteWindow(editShell, "EditCommentPopDown");
-    } else {
-       edit = XtNameToWidget(editShell, "*form.text");
-       j = 0;
-       XtSetArg(args[j], XtNstring, text); j++;
-       XtSetValues(edit, args, j);
-       j = 0;
-       XtSetArg(args[j], XtNiconName, (XtArgVal) title);   j++;
-       XtSetArg(args[j], XtNtitle, (XtArgVal) title);      j++;
-       XtSetValues(editShell, args, j);
-    }
-
-    XtPopup(editShell, XtGrabNone);
-
-    editUp = True;
-    j = 0;
-    XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuEdit.Edit Comment"),
-               args, j);
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Comments"),
-               args, j);
-}
-
-void EditCommentCallback(w, client_data, call_data)
-     Widget w;
-     XtPointer client_data, call_data;
-{
-    String name, val;
-    Arg args[16];
-    int j;
-    Widget edit;
-
-    j = 0;
-    XtSetArg(args[j], XtNlabel, &name);  j++;
-    XtGetValues(w, args, j);
-
-    if (strcmp(name, _("ok")) == 0) {
-       edit = XtNameToWidget(editShell, "*form.text");
-       j = 0;
-       XtSetArg(args[j], XtNstring, &val); j++;
-       XtGetValues(edit, args, j);
-       ReplaceComment(savedIndex, val);
-       EditCommentPopDown();
-    } else if (strcmp(name, _("cancel")) == 0) {
-       EditCommentPopDown();
-    } else if (strcmp(name, _("clear")) == 0) {
-       edit = XtNameToWidget(editShell, "*form.text");
-       XtCallActionProc(edit, "select-all", NULL, NULL, 0);
-       XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
-    }
-}
-
-void EditCommentPopDown()
-{
-    Arg args[16];
-    int j;
-
-    if (!editUp) return;
-    j = 0;
-    XtSetArg(args[j], XtNx, &commentX); j++;
-    XtSetArg(args[j], XtNy, &commentY); j++;
-    XtSetArg(args[j], XtNheight, &commentH); j++;
-    XtSetArg(args[j], XtNwidth, &commentW); j++;
-    XtGetValues(editShell, args, j);
-    XtPopdown(editShell);
-    editUp = False;
-    j = 0;
-    XtSetArg(args[j], XtNleftBitmap, None); j++;
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuEdit.Edit Comment"),
-               args, j);
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Comments"),
-               args, j);
+    NewCommentPopup(title, text, index);
 }
 
 void ICSInputBoxPopUp()
 {
-    Widget edit;
-    Arg args[16];
-    int j;
-    char *title = _("ICS Input");
-    XtTranslations tr;
-
-    if (ICSInputShell == NULL) {
-       ICSInputShell = MiscCreate(title, "", True, NULL, 1);
-       tr = XtParseTranslationTable(ICSInputTranslations);
-       edit = XtNameToWidget(ICSInputShell, "*form.text");
-       XtOverrideTranslations(edit, tr);
-       XtRealizeWidget(ICSInputShell);
-       CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");
-
-    } else {
-       edit = XtNameToWidget(ICSInputShell, "*form.text");
-       j = 0;
-       XtSetArg(args[j], XtNstring, ""); j++;
-       XtSetValues(edit, args, j);
-       j = 0;
-       XtSetArg(args[j], XtNiconName, (XtArgVal) title);   j++;
-       XtSetArg(args[j], XtNtitle, (XtArgVal) title);      j++;
-       XtSetValues(ICSInputShell, args, j);
-    }
-
-    XtPopup(ICSInputShell, XtGrabNone);
-    XtSetKeyboardFocus(ICSInputShell, edit);
-
-    ICSInputBoxUp = True;
-    j = 0;
-    XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuView.ICS Input Box"),
-               args, j);
+    InputBoxPopup();
 }
 
+extern Option boxOptions[];
+
 void ICSInputSendText()
 {
     Widget edit;
@@ -5147,7 +4976,7 @@ void ICSInputSendText()
     Arg args[16];
     String val;
 
-    edit = XtNameToWidget(ICSInputShell, "*form.text");
+    edit = boxOptions[0].handle;
     j = 0;
     XtSetArg(args[j], XtNstring, &val); j++;
     XtGetValues(edit, args, j);
@@ -5159,102 +4988,44 @@ void ICSInputSendText()
 
 void ICSInputBoxPopDown()
 {
-    Arg args[16];
-    int j;
-
-    if (!ICSInputBoxUp) return;
-    j = 0;
-    XtPopdown(ICSInputShell);
-    ICSInputBoxUp = False;
-    j = 0;
-    XtSetArg(args[j], XtNleftBitmap, None); j++;
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuView.ICS Input Box"),
-               args, j);
+    PopDown(4);
 }
 
 void CommentPopUp(title, text)
      char *title, *text;
 {
-    Arg args[16];
-    int j;
-    Widget edit;
-
     savedIndex = currentMove; // [HGM] vari
-    if (commentShell == NULL) {
-       commentShell =
-         CommentCreate(title, text, False, CommentCallback, 4);
-       XtRealizeWidget(commentShell);
-       CatchDeleteWindow(commentShell, "CommentPopDown");
-    } else {
-       edit = XtNameToWidget(commentShell, "*form.text");
-       j = 0;
-       XtSetArg(args[j], XtNstring, text); j++;
-       XtSetValues(edit, args, j);
-       j = 0;
-       XtSetArg(args[j], XtNiconName, (XtArgVal) title);   j++;
-       XtSetArg(args[j], XtNtitle, (XtArgVal) title);      j++;
-       XtSetValues(commentShell, args, j);
-    }
-
-    XtPopup(commentShell, XtGrabNone);
-    XSync(xDisplay, False);
-
-    commentUp = True;
+    NewCommentPopup(title, text, currentMove);
 }
 
-void CommentCallback(w, client_data, call_data)
-     Widget w;
-     XtPointer client_data, call_data;
+void CommentPopDown()
 {
-    String name;
-    Arg args[16];
-    int j;
-
-    j = 0;
-    XtSetArg(args[j], XtNlabel, &name);  j++;
-    XtGetValues(w, args, j);
-
-    if (strcmp(name, _("close")) == 0) {
-       CommentPopDown();
-    } else if (strcmp(name, _("edit")) == 0) {
-       CommentPopDown();
-       EditCommentEvent();
-    }
+    PopDown(1);
 }
 
+static char *openName;
+FILE *openFP;
 
-void CommentPopDown()
+void DelayedLoad()
 {
-    Arg args[16];
-    int j;
-
-    if (!commentUp) return;
-    j = 0;
-    XtSetArg(args[j], XtNx, &commentX); j++;
-    XtSetArg(args[j], XtNy, &commentY); j++;
-    XtSetArg(args[j], XtNwidth, &commentW); j++;
-    XtSetArg(args[j], XtNheight, &commentH); j++;
-    XtGetValues(commentShell, args, j);
-    XtPopdown(commentShell);
-    XSync(xDisplay, False);
-    commentUp = False;
+  (void) (*fileProc)(openFP, 0, openName);
 }
 
-void FileNamePopUp(label, def, proc, openMode)
+void FileNamePopUp(label, def, filter, proc, openMode)
      char *label;
      char *def;
+     char *filter;
      FileProc proc;
      char *openMode;
 {
     fileProc = proc;           /* I can't see a way not */
     fileOpenMode = openMode;   /*   to use globals here */
     {   // [HGM] use file-selector dialog stolen from Ghostview
-       char *name;
        int index; // this is not supported yet
-       FILE *f;
-       if(f = XsraSelFile(shellWidget, label, NULL, NULL, "could not open: ",
-                          def, openMode, NULL, &name))
-         (void) (*fileProc)(f, index=0, name);
+       if(openFP = XsraSelFile(shellWidget, label, NULL, NULL, "could not open: ",
+                          (def[0] ? def : NULL), filter, openMode, NULL, &openName))
+         // [HGM] delay to give expose event opportunity to redraw board after browser-dialog popdown before lengthy load starts
+         ScheduleDelayedEvent(&DelayedLoad, 50);
     }
 }
 
@@ -5363,6 +5134,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,
@@ -5371,7 +5152,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);
@@ -5656,6 +5439,8 @@ void ModeHighlight()
        XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
     }
     oldmode = gameMode;
+    XtSetArg(args[0], XtNleftBitmap, matchMode && matchGame < appData.matchGames ? xMarkPixmap : None);
+    XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Machine Match"), args, 1);
 
     /* Maybe all the enables should be handled here, not just this one */
     XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Training"),
@@ -5705,7 +5490,7 @@ void LoadGameProc(w, event, prms, nprms)
     if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
        Reset(FALSE, TRUE);
     }
-    FileNamePopUp(_("Load game file name?"), "", LoadGamePopUp, "rb");
+    FileNamePopUp(_("Load game file name?"), "", ".pgn .game", LoadGamePopUp, "rb");
 }
 
 void LoadNextGameProc(w, event, prms, nprms)
@@ -5771,7 +5556,7 @@ void LoadPositionProc(w, event, prms, nprms)
     if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
        Reset(FALSE, TRUE);
     }
-    FileNamePopUp(_("Load position file name?"), "", LoadPosition, "rb");
+    FileNamePopUp(_("Load position file name?"), "", ".fen .epd .pos", LoadPosition, "rb");
 }
 
 void SaveGameProc(w, event, prms, nprms)
@@ -5782,6 +5567,7 @@ void SaveGameProc(w, event, prms, nprms)
 {
     FileNamePopUp(_("Save game file name?"),
                  DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
+                 appData.oldSaveStyle ? ".game" : ".pgn",
                  SaveGame, "a");
 }
 
@@ -5793,6 +5579,7 @@ void SavePositionProc(w, event, prms, nprms)
 {
     FileNamePopUp(_("Save position file name?"),
                  DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
+                 appData.oldSaveStyle ? ".pos" : ".fen",
                  SavePosition, "a");
 }
 
@@ -5935,6 +5722,7 @@ SendGameSelection(Widget w, Atom *selection, Atom *target,
     rewind(f);
     selection_tmp = XtMalloc(len + 1);
     count = fread(selection_tmp, 1, len, f);
+    fclose(f);
     if (len != count) {
       XtFree(selection_tmp);
       return False;
@@ -5963,20 +5751,8 @@ SendGameSelection(Widget w, Atom *selection, Atom *target,
   }
 }
 
-/* note: when called from menu all parameters are NULL, so no clue what the
- * Widget which was clicked on was, or what the click event was
- */
-void CopyGameProc(w, event, prms, nprms)
-  Widget w;
-  XEvent *event;
-  String *prms;
-  Cardinal *nprms;
+void CopySomething()
 {
-  int ret;
-
-  ret = SaveGameToFile(gameCopyFilename, FALSE);
-  if (!ret) return;
-
   /*
    * Set both PRIMARY (the selection) and CLIPBOARD, since we don't
    * have a notion of a game that is selected but not copied.
@@ -5994,6 +5770,33 @@ void CopyGameProc(w, event, prms, nprms)
                 NULL/* transfer_done_proc */);
 }
 
+/* note: when called from menu all parameters are NULL, so no clue what the
+ * Widget which was clicked on was, or what the click event was
+ */
+void CopyGameProc(w, event, prms, nprms)
+  Widget w;
+  XEvent *event;
+  String *prms;
+  Cardinal *nprms;
+{
+  int ret;
+
+  ret = SaveGameToFile(gameCopyFilename, FALSE);
+  if (!ret) return;
+
+  CopySomething();
+}
+
+void CopyGameListProc(w, event, prms, nprms)
+  Widget w;
+  XEvent *event;
+  String *prms;
+  Cardinal *nprms;
+{
+  if(!SaveGameListAsText(fopen(gameCopyFilename, "w"))) return;
+  CopySomething();
+}
+
 /* function called when the data to Paste is ready */
 static void
 PasteGameCB(Widget w, XtPointer client_data, Atom *selection,
@@ -6116,8 +5919,10 @@ void AnalyzeModeProc(w, event, prms, nprms)
         if (appData.debugMode)
             fprintf(debugFP, _("ICS engine analyze starting... \n"));
     }
+#ifndef OPTIONSDIALOG
     if (!appData.showThinking)
       ShowThinkingProc(w,event,prms,nprms);
+#endif
 
     AnalyzeModeEvent();
 }
@@ -6135,12 +5940,12 @@ void AnalyzeFileProc(w, event, prms, nprms)
       return;
     }
     Reset(FALSE, TRUE);
-
+#ifndef OPTIONSDIALOG
     if (!appData.showThinking)
       ShowThinkingProc(w,event,prms,nprms);
-
+#endif
     AnalyzeFileEvent();
-    FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
+    FileNamePopUp(_("File to analyze"), "", ".pgn .game", LoadGamePopUp, "rb");
     AnalysisPeriodicEvent(1);
 }
 
@@ -6153,6 +5958,15 @@ void TwoMachinesProc(w, event, prms, nprms)
     TwoMachinesEvent();
 }
 
+void MatchProc(w, event, prms, nprms)
+     Widget w;
+     XEvent *event;
+     String *prms;
+     Cardinal *nprms;
+{
+    MatchEvent(2);
+}
+
 void IcsClientProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6195,11 +6009,15 @@ void EditCommentProc(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    if (editUp) {
-       EditCommentPopDown();
-    } else {
+    Arg args[5];
+    int j;
+    if (PopDown(1)) { // popdown succesful
+       j = 0;
+       XtSetArg(args[j], XtNleftBitmap, None); j++;
+       XtSetValues(XtNameToWidget(menuBarWidget, "menuEdit.Edit Comment"), args, j);
+       XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Comments"), args, j);
+    } else // was not up
        EditCommentEvent();
-    }
 }
 
 void IcsInputBoxProc(w, event, prms, nprms)
@@ -6208,11 +6026,7 @@ void IcsInputBoxProc(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    if (ICSInputBoxUp) {
-       ICSInputBoxPopDown();
-    } else {
-       ICSInputBoxPopUp();
-    }
+    if (!PopDown(4)) ICSInputBoxPopUp();
 }
 
 void AcceptProc(w, event, prms, nprms)
@@ -6320,7 +6134,7 @@ void EnterKeyProc(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    if (ICSInputBoxUp == True)
+    if (shellUp[4] == True)
       ICSInputSendText();
 }
 
@@ -6336,8 +6150,8 @@ void UpKeyProc(w, event, prms, nprms)
     String val;
     XawTextBlock t;
 
-    if (!ICSInputBoxUp) return;
-    edit = XtNameToWidget(ICSInputShell, "*form.text");
+    if (!shellUp[4]) return;
+    edit = boxOptions[0].handle;
     j = 0;
     XtSetArg(args[j], XtNstring, &val); j++;
     XtGetValues(edit, args, j);
@@ -6361,8 +6175,8 @@ void DownKeyProc(w, event, prms, nprms)
     String val;
     XawTextBlock t;
 
-    if (!ICSInputBoxUp) return;
-    edit = XtNameToWidget(ICSInputShell, "*form.text");
+    if (!shellUp[4]) return;
+    edit = boxOptions[0].handle;
     val = NextInHistory();
     XtCallActionProc(edit, "select-all", NULL, NULL, 0);
     XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
@@ -6482,8 +6296,17 @@ void MoveNowProc(w, event, prms, nprms)
     MoveNowEvent();
 }
 
+void FlipViewProc(w, event, prms, nprms)
+     Widget w;
+     XEvent *event;
+     String *prms;
+     Cardinal *nprms;
+{
+    flipView = !flipView;
+    DrawPosition(True, NULL);
+}
 
-void AlwaysQueenProc(w, event, prms, nprms)
+void PonderNextMoveProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
      String *prms;
@@ -6491,18 +6314,20 @@ void AlwaysQueenProc(w, event, prms, nprms)
 {
     Arg args[16];
 
-    appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
-
-    if (appData.alwaysPromoteToQueen) {
+    PonderNextMoveEvent(!appData.ponderNextMove);
+#ifndef OPTIONSDIALOG
+    if (appData.ponderNextMove) {
        XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
     } else {
        XtSetArg(args[0], XtNleftBitmap, None);
     }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
+    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"),
                args, 1);
+#endif
 }
 
-void AnimateDraggingProc(w, event, prms, nprms)
+#ifndef OPTIONSDIALOG
+void AlwaysQueenProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
      String *prms;
@@ -6510,19 +6335,18 @@ void AnimateDraggingProc(w, event, prms, nprms)
 {
     Arg args[16];
 
-    appData.animateDragging = !appData.animateDragging;
+    appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
 
-    if (appData.animateDragging) {
+    if (appData.alwaysPromoteToQueen) {
        XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-        CreateAnimVars();
     } else {
        XtSetArg(args[0], XtNleftBitmap, None);
     }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"),
+    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
                args, 1);
 }
 
-void AnimateMovingProc(w, event, prms, nprms)
+void AnimateDraggingProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
      String *prms;
@@ -6530,19 +6354,19 @@ void AnimateMovingProc(w, event, prms, nprms)
 {
     Arg args[16];
 
-    appData.animate = !appData.animate;
+    appData.animateDragging = !appData.animateDragging;
 
-    if (appData.animate) {
+    if (appData.animateDragging) {
        XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
         CreateAnimVars();
     } else {
        XtSetArg(args[0], XtNleftBitmap, None);
     }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
+    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"),
                args, 1);
 }
 
-void AutocommProc(w, event, prms, nprms)
+void AnimateMovingProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
      String *prms;
@@ -6550,18 +6374,18 @@ void AutocommProc(w, event, prms, nprms)
 {
     Arg args[16];
 
-    appData.autoComment = !appData.autoComment;
+    appData.animate = !appData.animate;
 
-    if (appData.autoComment) {
+    if (appData.animate) {
        XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
+        CreateAnimVars();
     } else {
        XtSetArg(args[0], XtNleftBitmap, None);
     }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
+    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
                args, 1);
 }
 
-
 void AutoflagProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6600,63 +6424,6 @@ void AutoflipProc(w, event, prms, nprms)
                args, 1);
 }
 
-void AutobsProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    appData.autoObserve = !appData.autoObserve;
-
-    if (appData.autoObserve) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
-               args, 1);
-}
-
-void AutoraiseProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    appData.autoRaiseBoard = !appData.autoRaiseBoard;
-
-    if (appData.autoRaiseBoard) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Raise Board"),
-               args, 1);
-}
-
-void AutosaveProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    appData.autoSaveGames = !appData.autoSaveGames;
-
-    if (appData.autoSaveGames) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
-               args, 1);
-}
-
 void BlindfoldProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6721,17 +6488,8 @@ void FlashMovesProc(w, event, prms, nprms)
                args, 1);
 }
 
-void FlipViewProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    flipView = !flipView;
-    DrawPosition(True, NULL);
-}
-
-void GetMoveListProc(w, event, prms, nprms)
+#if HIGHDRAG
+void HighlightDraggingProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
      String *prms;
@@ -6739,20 +6497,19 @@ void GetMoveListProc(w, event, prms, nprms)
 {
     Arg args[16];
 
-    appData.getMoveList = !appData.getMoveList;
+    appData.highlightDragging = !appData.highlightDragging;
 
-    if (appData.getMoveList) {
+    if (appData.highlightDragging) {
        XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-       GetMoveListEvent();
     } else {
        XtSetArg(args[0], XtNleftBitmap, None);
     }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
-               args, 1);
+    XtSetValues(XtNameToWidget(menuBarWidget,
+                              "menuOptions.Highlight Dragging"), args, 1);
 }
+#endif
 
-#if HIGHDRAG
-void HighlightDraggingProc(w, event, prms, nprms)
+void HighlightLastMoveProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
      String *prms;
@@ -6760,19 +6517,18 @@ void HighlightDraggingProc(w, event, prms, nprms)
 {
     Arg args[16];
 
-    appData.highlightDragging = !appData.highlightDragging;
+    appData.highlightLastMove = !appData.highlightLastMove;
 
-    if (appData.highlightDragging) {
+    if (appData.highlightLastMove) {
        XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
     } else {
        XtSetArg(args[0], XtNleftBitmap, None);
     }
     XtSetValues(XtNameToWidget(menuBarWidget,
-                              "menuOptions.Highlight Dragging"), args, 1);
+                              "menuOptions.Highlight Last Move"), args, 1);
 }
-#endif
 
-void HighlightLastMoveProc(w, event, prms, nprms)
+void HighlightArrowProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
      String *prms;
@@ -6780,17 +6536,18 @@ void HighlightLastMoveProc(w, event, prms, nprms)
 {
     Arg args[16];
 
-    appData.highlightLastMove = !appData.highlightLastMove;
+    appData.highlightMoveWithArrow = !appData.highlightMoveWithArrow;
 
-    if (appData.highlightLastMove) {
+    if (appData.highlightMoveWithArrow) {
        XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
     } else {
        XtSetArg(args[0], XtNleftBitmap, None);
     }
     XtSetValues(XtNameToWidget(menuBarWidget,
-                              "menuOptions.Highlight Last Move"), args, 1);
+                              "menuOptions.Arrow"), args, 1);
 }
 
+#if 0
 void IcsAlarmProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6809,6 +6566,7 @@ void IcsAlarmProc(w, event, prms, nprms)
     XtSetValues(XtNameToWidget(menuBarWidget,
                               "menuOptions.ICS Alarm"), args, 1);
 }
+#endif
 
 void MoveSoundProc(w, event, prms, nprms)
      Widget w;
@@ -6829,8 +6587,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;
@@ -6838,14 +6595,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);
 }
 
@@ -6868,25 +6625,6 @@ void PeriodicUpdatesProc(w, event, prms, nprms)
                args, 1);
 }
 
-void PonderNextMoveProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    PonderNextMoveEvent(!appData.ponderNextMove);
-
-    if (appData.ponderNextMove) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"),
-               args, 1);
-}
-
 void PopupExitMessageProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6925,6 +6663,7 @@ void PopupMoveErrorsProc(w, event, prms, nprms)
                args, 1);
 }
 
+#if 0
 void PremoveProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6943,25 +6682,7 @@ void PremoveProc(w, event, prms, nprms)
     XtSetValues(XtNameToWidget(menuBarWidget,
                               "menuOptions.Premove"), args, 1);
 }
-
-void QuietPlayProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    appData.quietPlay = !appData.quietPlay;
-
-    if (appData.quietPlay) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"),
-               args, 1);
-}
+#endif
 
 void ShowCoordsProc(w, event, prms, nprms)
      Widget w;
@@ -7013,6 +6734,7 @@ void HideThinkingProc(w, event, prms, nprms)
     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
                args, 1);
 }
+#endif
 
 void SaveOnExitProc(w, event, prms, nprms)
      Widget w;
@@ -7171,6 +6893,8 @@ void DisplayMessage(message, extMessage)
        };
     };
 
+    safeStrCpy(lastMsg, message, MSG_SIZ); // [HGM] make available
+
   /* need to test if messageWidget already exists, since this function
      can also be called during the startup, if for example a Xresource
      is not set up correctly */
@@ -7230,6 +6954,7 @@ void DisplayTitle(text)
     XtSetArg(args[i], XtNiconName, (XtArgVal) icon);    i++;
     XtSetArg(args[i], XtNtitle, (XtArgVal) title);      i++;
     XtSetValues(shellWidget, args, i);
+    XSync(xDisplay, False);
 }
 
 
@@ -7474,7 +7199,9 @@ PlaySound(name)
     putc(BELLCHAR, stderr);
   } else {
     char buf[2048];
-    snprintf(buf, sizeof(buf), "%s '%s' &", appData.soundProgram, name);
+    char *prefix = "", *sep = "";
+    if(!strchr(name, '/')) { prefix = appData.soundDirectory; sep = "/"; }
+    snprintf(buf, sizeof(buf), "%s '%s%s%s' &", appData.soundProgram, prefix, sep, name);
     system(buf);
   }
 }
@@ -7516,15 +7243,23 @@ PlayAlarmSound()
 }
 
 void
+PlayTellSound()
+{
+  PlaySound(appData.soundTell);
+}
+
+void
 EchoOn()
 {
     system("stty echo");
+    noEcho = False;
 }
 
 void
 EchoOff()
 {
     system("stty -echo");
+    noEcho = True;
 }
 
 void
@@ -8024,50 +7759,40 @@ int OpenTCP(host, port, pr)
 #if OMIT_SOCKETS
     DisplayFatalError(_("Socket support is not configured in"), 0, 2);
 #else  /* !OMIT_SOCKETS */
-    int s;
-    struct sockaddr_in sa;
-    struct hostent     *hp;
-    unsigned short uport;
+    struct addrinfo hints;
+    struct addrinfo *ais, *ai;
+    int error;
+    int s=0;
     ChildProc *cp;
 
-    if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
-       return errno;
-    }
-
-    memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
-    sa.sin_family = AF_INET;
-    sa.sin_addr.s_addr = INADDR_ANY;
-    uport = (unsigned short) 0;
-    sa.sin_port = htons(uport);
-    if (bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) {
-       return errno;
-    }
-
-    memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
-    if (!(hp = gethostbyname(host))) {
-       int b0, b1, b2, b3;
-       if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {
-           hp = (struct hostent *) calloc(1, sizeof(struct hostent));
-           hp->h_addrtype = AF_INET;
-           hp->h_length = 4;
-           hp->h_addr_list = (char **) calloc(2, sizeof(char *));
-           hp->h_addr_list[0] = (char *) malloc(4);
-           hp->h_addr_list[0][0] = b0;
-           hp->h_addr_list[0][1] = b1;
-           hp->h_addr_list[0][2] = b2;
-           hp->h_addr_list[0][3] = b3;
-       } else {
-           return ENOENT;
-       }
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+
+    error = getaddrinfo(host, port, &hints, &ais);
+    if (error != 0) {
+      /* a getaddrinfo error is not an errno, so can't return it */
+      fprintf(debugFP, "getaddrinfo(%s, %s): %s\n",
+             host, port, gai_strerror(error));
+      return ENOENT;
+    }
+     
+    for (ai = ais; ai != NULL; ai = ai->ai_next) {
+      if ((s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) {
+       error = errno;
+       continue;
+      }
+      if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
+       error = errno;
+       continue;
+      }
+      error = 0;
+      break;
     }
-    sa.sin_family = hp->h_addrtype;
-    uport = (unsigned short) atoi(port);
-    sa.sin_port = htons(uport);
-    memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
+    freeaddrinfo(ais);
 
-    if (connect(s, (struct sockaddr *) &sa,
-               sizeof(struct sockaddr_in)) < 0) {
-       return errno;
+    if (error != 0) {
+      return error;
     }
 
     cp = (ChildProc *) calloc(1, sizeof(ChildProc));
@@ -8076,7 +7801,6 @@ int OpenTCP(host, port, pr)
     cp->fdFrom = s;
     cp->fdTo = s;
     *pr = (ProcRef) cp;
-
 #endif /* !OMIT_SOCKETS */
 
     return 0;
@@ -8433,11 +8157,10 @@ InitAnimState (anim, info)
 static void
 CreateAnimVars ()
 {
-  static VariantClass old = (VariantClass) -1; // [HGM] pieces: redo every time variant changes
   XWindowAttributes info;
 
-  if (xpmDone && gameInfo.variant == old) return;
-  if(xpmDone) old = gameInfo.variant; // first time pieces might not be created yet
+  if (xpmDone && gameInfo.variant == oldVariant) return;
+  if(xpmDone) oldVariant = gameInfo.variant; // first time pieces might not be created yet
   XGetWindowAttributes(xDisplay, xBoardWindow, &info);
 
   InitAnimState(&game, &info);
@@ -8445,8 +8168,7 @@ CreateAnimVars ()
 
   /* For XPM pieces, we need bitmaps to use as masks. */
   if (useImages)
-    CreateAnimMasks(info.depth);
-   xpmDone = 1;
+    CreateAnimMasks(info.depth), xpmDone = 1;
 }
 
 #ifndef HAVE_USLEEP
@@ -8735,6 +8457,7 @@ BeginAnimation(anim, piece, startColor, start)
 {
   Pixmap mask;
 
+  if(appData.upsideDown && flipView) piece += piece < BlackPawn ? BlackPawn : -BlackPawn;
   /* The old buffer is initialised with the start square (empty) */
   BlankSquare(start->x, start->y, startColor, EmptySquare, anim->saveBuf, 0);
   anim->prevFrame = *start;
@@ -8937,8 +8660,8 @@ AnimateMove(board, fromX, fromY, toX, toY)
 }
 
 void
-DragPieceBegin(x, y)
-     int x; int y;
+DragPieceBegin(x, y, instantly)
+     int x; int y; Boolean instantly;
 {
     int         boardX, boardY, color;
     XPoint corner;
@@ -8990,6 +8713,16 @@ DragPieceBegin(x, y)
     }
 }
 
+void
+ChangeDragPiece(ChessSquare piece)
+{
+  Pixmap mask;
+  player.dragPiece = piece;
+  /* The piece will be drawn using its own bitmap as a matte   */
+  SelectGCMask(piece, &player.pieceGC, &player.outlineGC, &mask);
+  XSetClipMask(xDisplay, player.pieceGC, mask);
+}
+
 static void
 DragPieceMove(x, y)
      int x; int y;
@@ -9272,16 +9005,13 @@ void DrawArrowBetweenSquares( int s_col, int s_row, int d_col, int d_row )
 
     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++) {
+    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;
-        }
     }
 }
 
@@ -9295,3 +9025,9 @@ 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);
 }
+
+void UpdateLogos(int displ)
+{
+    return; // no logos in XBoard yet
+}
+