Lock game an position file during writing
[xboard.git] / xboard.c
index 1b95e50..e9c4347 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -238,11 +238,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));
@@ -261,6 +262,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 +285,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 +302,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 +324,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 +344,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 +367,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));
@@ -450,19 +451,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 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(());
@@ -516,7 +520,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,
@@ -538,6 +542,9 @@ WindowPlacement wpEngineOutput;
 WindowPlacement wpGameList;
 WindowPlacement wpTags;
 
+extern Widget shells[];
+extern Boolean shellUp[];
+
 #define SOLID 0
 #define OUTLINE 1
 Pixmap pieceBitmap[2][(int)BlackPawn];
@@ -616,6 +623,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},
@@ -643,10 +651,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}
 };
 
@@ -661,6 +673,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}
 };
@@ -687,6 +700,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},
@@ -699,14 +714,22 @@ 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},
@@ -731,6 +754,7 @@ MenuItem optionsMenu[] = {
     {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}
@@ -897,6 +921,7 @@ XtActionsRec boardActions[] = {
     { "CopyPositionProc", CopyPositionProc },
     { "PastePositionProc", PastePositionProc },
     { "CopyGameProc", CopyGameProc },
+    { "CopyGameListProc", CopyGameListProc },
     { "PasteGameProc", PasteGameProc },
     { "SaveGameProc", SaveGameProc },
     { "SavePositionProc", SavePositionProc },
@@ -931,6 +956,7 @@ XtActionsRec boardActions[] = {
     { "AdjuWhiteProc", AdjuWhiteProc },
     { "AdjuBlackProc", AdjuBlackProc },
     { "AdjuDrawProc", AdjuDrawProc },
+    { "TypeInProc", TypeInProc },
     { "EnterKeyProc", EnterKeyProc },
     { "UpKeyProc", UpKeyProc },
     { "DownKeyProc", DownKeyProc },
@@ -949,6 +975,9 @@ XtActionsRec boardActions[] = {
     { "EngineMenuProc", (XtActionProc) EngineMenuProc },
     { "UciMenuProc", (XtActionProc) UciMenuProc },
     { "TimeControlProc", (XtActionProc) TimeControlProc },
+    { "FlipViewProc", FlipViewProc },
+    { "PonderNextMoveProc", PonderNextMoveProc },
+#ifndef OPTIONSDIALOG
     { "AlwaysQueenProc", AlwaysQueenProc },
     { "AnimateDraggingProc", AnimateDraggingProc },
     { "AnimateMovingProc", AnimateMovingProc },
@@ -956,7 +985,6 @@ XtActionsRec boardActions[] = {
     { "AutoflipProc", AutoflipProc },
     { "BlindfoldProc", BlindfoldProc },
     { "FlashMovesProc", FlashMovesProc },
-    { "FlipViewProc", FlipViewProc },
 #if HIGHDRAG
     { "HighlightDraggingProc", HighlightDraggingProc },
 #endif
@@ -964,7 +992,6 @@ XtActionsRec boardActions[] = {
 //    { "IcsAlarmProc", IcsAlarmProc },
     { "MoveSoundProc", MoveSoundProc },
     { "PeriodicUpdatesProc", PeriodicUpdatesProc },
-    { "PonderNextMoveProc", PonderNextMoveProc },
     { "PopupExitMessageProc", PopupExitMessageProc },
     { "PopupMoveErrorsProc", PopupMoveErrorsProc },
 //    { "PremoveProc", PremoveProc },
@@ -972,6 +999,7 @@ XtActionsRec boardActions[] = {
     { "ShowThinkingProc", ShowThinkingProc },
     { "HideThinkingProc", HideThinkingProc },
     { "TestLegalityProc", TestLegalityProc },
+#endif
     { "SaveSettingsProc", SaveSettingsProc },
     { "SaveOnExitProc", SaveOnExitProc },
     { "InfoProc", InfoProc },
@@ -984,7 +1012,6 @@ XtActionsRec boardActions[] = {
     { "NothingProc", NothingProc },
     { "CommentClick", (XtActionProc) CommentClick },
     { "CommentPopDown", (XtActionProc) CommentPopDown },
-    { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
     { "TagsPopDown", (XtActionProc) TagsPopDown },
     { "ErrorPopDown", (XtActionProc) ErrorPopDown },
     { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
@@ -997,11 +1024,8 @@ XtActionsRec boardActions[] = {
     { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
     { "EvalGraphPopDown", (XtActionProc) EvalGraphPopDown },
     { "ShufflePopDown", (XtActionProc) ShufflePopDown },
-    { "EnginePopDown", (XtActionProc) EnginePopDown },
-    { "UciPopDown", (XtActionProc) UciPopDown },
     { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
-    { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
-    { "SettingsPopDown", (XtActionProc) SettingsPopDown },
+    { "GenericPopDown", (XtActionProc) GenericPopDown },
     { "CopyMemoProc", (XtActionProc) CopyMemoProc },
 };
 
@@ -1055,12 +1079,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 \
@@ -1238,8 +1266,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 */
@@ -1485,7 +1513,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
@@ -1518,7 +1546,7 @@ ParseCommPortSettings(char *s)
 }
 
 extern Widget engineOutputShell;
-extern Widget tagsShell, editTagsShell;
+
 void
 GetActualPlacement(Widget wg, WindowPlacement *wp)
 {
@@ -1550,10 +1578,8 @@ GetWindowCoords()
   if(MoveHistoryIsUp()) GetActualPlacement(historyShell, &wpMoveHistory);
   if(EvalGraphIsUp()) GetActualPlacement(evalGraphShell, &wpEvalGraph);
   if(GameListIsUp()) GetActualPlacement(gameListShell, &wpGameList);
-  if(commentShell) GetActualPlacement(commentShell, &wpComment);
-  else             GetActualPlacement(editShell,    &wpComment);
-  if(tagsShell) GetActualPlacement(tagsShell, &wpTags);
-  else      GetActualPlacement(editTagsShell, &wpTags);
+  if(shellUp[1]) GetActualPlacement(shells[1], &wpComment);
+  if(shellUp[2]) GetActualPlacement(shells[2], &wpTags);
 }
 
 void
@@ -1650,6 +1676,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();
@@ -1777,6 +1804,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;
@@ -1835,8 +1982,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);
@@ -1966,6 +2113,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) */
@@ -2011,82 +2159,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) {
@@ -2105,24 +2183,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;
 
@@ -2380,6 +2441,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);
@@ -2471,6 +2533,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);
@@ -2509,21 +2572,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();
 
@@ -2544,6 +2595,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 ) {
@@ -2580,7 +2633,8 @@ 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
@@ -2675,7 +2729,6 @@ void
 ResetFrontEnd()
 {
     CommentPopDown();
-    EditCommentPopDown();
     TagsPopDown();
     return;
 }
@@ -2730,17 +2783,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 }
 };
 
@@ -2752,7 +2810,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 },
@@ -2761,6 +2821,8 @@ Enables ncpEnables[] = {
     { "menuEngine.Engine #2 Settings", False },
     { "menuEngine.Move Now", False },
     { "menuEngine.Retract Move", False },
+    { "menuOptions.ICS", False },
+#ifndef OPTIONSDIALOG
     { "menuOptions.Auto Flag", False },
     { "menuOptions.Auto Flip View", False },
 //    { "menuOptions.ICS Alarm", False },
@@ -2768,6 +2830,7 @@ Enables ncpEnables[] = {
     { "menuOptions.Hide Thinking", False },
     { "menuOptions.Periodic Updates", False },
     { "menuOptions.Ponder Next Move", False },
+#endif
     { "menuEngine.Hint", False },
     { "menuEngine.Book", False },
     { NULL, False }
@@ -2775,6 +2838,7 @@ Enables ncpEnables[] = {
 
 Enables gnuEnables[] = {
     { "menuMode.ICS Client", False },
+    { "menuView.ICStex", False },
     { "menuView.ICS Input Box", False },
     { "menuAction.Accept", False },
     { "menuAction.Decline", False },
@@ -2785,6 +2849,7 @@ Enables gnuEnables[] = {
     { "menuAction.Upload to Examine", False },
     { "menuEdit.Revert", False },
     { "menuEdit.Annotate", False },
+    { "menuOptions.ICS", False },
 
     /* The next two options rely on SetCmailMode being called *after*    */
     /* SetGNUMode so that when GNU is being used to give hints these     */
@@ -2792,6 +2857,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 }
 };
 
@@ -2846,6 +2925,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 }
 };
@@ -2864,6 +2944,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 }
 };
@@ -2873,8 +2954,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
 }
 
@@ -3009,7 +3092,6 @@ FindFont(pattern, targetPxlSize)
     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, "--");
@@ -3087,7 +3169,32 @@ FindFont(pattern, targetPxlSize)
     return p;
 }
 
-void CreateGCs()
+void DeleteGCs()
+{   // [HGM] deletes GCs that are to be remade, to prevent resource leak;
+    // must be called before all non-first callse to CreateGCs()
+    XtReleaseGC(shellWidget, highlineGC);
+    XtReleaseGC(shellWidget, lightSquareGC);
+    XtReleaseGC(shellWidget, darkSquareGC);
+    XtReleaseGC(shellWidget, lineGC);
+    if (appData.monoMode) {
+       if (DefaultDepth(xDisplay, xScreen) == 1) {
+           XtReleaseGC(shellWidget, wbPieceGC);
+       } else {
+           XtReleaseGC(shellWidget, bwPieceGC);
+       }
+    } else {
+       XtReleaseGC(shellWidget, prelineGC);
+       XtReleaseGC(shellWidget, jailSquareGC);
+       XtReleaseGC(shellWidget, wdPieceGC);
+       XtReleaseGC(shellWidget, wlPieceGC);
+       XtReleaseGC(shellWidget, wjPieceGC);
+       XtReleaseGC(shellWidget, bdPieceGC);
+       XtReleaseGC(shellWidget, blPieceGC);
+       XtReleaseGC(shellWidget, bjPieceGC);
+    }
+}
+
+void CreateGCs(int redo)
 {
     XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
       | GCBackground | GCFunction | GCPlaneMask;
@@ -3099,20 +3206,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);
@@ -3362,17 +3472,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(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;
@@ -3381,6 +3505,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 */
@@ -3505,6 +3632,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 */
 }
@@ -3670,10 +3798,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,
@@ -3711,7 +3839,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++;
@@ -3859,7 +3987,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)
@@ -4329,9 +4458,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);
@@ -4430,7 +4559,6 @@ static int too_many_diffs(b1, b2)
            }
        }
     }
-
     return 0;
 }
 
@@ -4675,6 +4803,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);
 }
 
@@ -4684,264 +4813,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);
-    x = xx;
-    y = yy;
-#endif /*!NOTDEF*/
-    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)
@@ -4962,128 +4833,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;
@@ -5091,7 +4852,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);
@@ -5103,90 +4864,25 @@ 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;
-}
-
-void CommentCallback(w, client_data, call_data)
-     Widget w;
-     XtPointer client_data, call_data;
-{
-    String name;
-    Arg args[16];
-    int j;
-
-    j = 0;
-    XtSetArg(args[j], XtNlabel, &name);  j++;
-    XtGetValues(w, args, j);
-
-    if (strcmp(name, _("close")) == 0) {
-       CommentPopDown();
-    } else if (strcmp(name, _("edit")) == 0) {
-       CommentPopDown();
-       EditCommentEvent();
-    }
+    NewCommentPopup(title, text, currentMove);
 }
 
-
 void CommentPopDown()
 {
-    Arg args[16];
-    int j;
-
-    if (!commentUp) return;
-    j = 0;
-    XtSetArg(args[j], XtNx, &commentX); j++;
-    XtSetArg(args[j], XtNy, &commentY); j++;
-    XtSetArg(args[j], XtNwidth, &commentW); j++;
-    XtSetArg(args[j], XtNheight, &commentH); j++;
-    XtGetValues(commentShell, args, j);
-    XtPopdown(commentShell);
-    XSync(xDisplay, False);
-    commentUp = False;
+    PopDown(1);
 }
 
-void FileNamePopUp(label, def, proc, openMode)
+void FileNamePopUp(label, def, filter, proc, openMode)
      char *label;
      char *def;
+     char *filter;
      FileProc proc;
      char *openMode;
 {
@@ -5197,7 +4893,7 @@ void FileNamePopUp(label, def, proc, openMode)
        int index; // this is not supported yet
        FILE *f;
        if(f = XsraSelFile(shellWidget, label, NULL, NULL, "could not open: ",
-                          def, openMode, NULL, &name))
+                          (def[0] ? def : NULL), filter, openMode, NULL, &name))
          (void) (*fileProc)(f, index=0, name);
     }
 }
@@ -5661,7 +5357,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)
@@ -5727,7 +5423,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)
@@ -5738,6 +5434,7 @@ void SaveGameProc(w, event, prms, nprms)
 {
     FileNamePopUp(_("Save game file name?"),
                  DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
+                 appData.oldSaveStyle ? ".game" : ".pgn",
                  SaveGame, "a");
 }
 
@@ -5749,6 +5446,7 @@ void SavePositionProc(w, event, prms, nprms)
 {
     FileNamePopUp(_("Save position file name?"),
                  DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
+                 appData.oldSaveStyle ? ".pos" : ".fen",
                  SavePosition, "a");
 }
 
@@ -5920,20 +5618,10 @@ 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.
@@ -5951,6 +5639,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,
@@ -6073,8 +5788,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();
 }
@@ -6092,12 +5809,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);
 }
 
@@ -6110,6 +5827,17 @@ void TwoMachinesProc(w, event, prms, nprms)
     TwoMachinesEvent();
 }
 
+void MatchProc(w, event, prms, nprms)
+     Widget w;
+     XEvent *event;
+     String *prms;
+     Cardinal *nprms;
+{
+    if(gameMode != BeginningOfGame) { DisplayError(_("You can only start a match from the initial position."), 0); return; }
+    appData.matchGames = appData.defaultMatchGames;
+    MatchEvent(2);\r
+}
+
 void IcsClientProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6152,11 +5880,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)
@@ -6165,11 +5897,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)
@@ -6277,7 +6005,7 @@ void EnterKeyProc(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    if (ICSInputBoxUp == True)
+    if (shellUp[4] == True)
       ICSInputSendText();
 }
 
@@ -6293,8 +6021,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);
@@ -6318,8 +6046,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);
@@ -6439,7 +6167,37 @@ 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 PonderNextMoveProc(w, event, prms, nprms)
+     Widget w;
+     XEvent *event;
+     String *prms;
+     Cardinal *nprms;
+{
+    Arg args[16];
+
+    PonderNextMoveEvent(!appData.ponderNextMove);
+#ifndef OPTIONSDIALOG
+    if (appData.ponderNextMove) {
+       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
+    } else {
+       XtSetArg(args[0], XtNleftBitmap, None);
+    }
+    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"),
+               args, 1);
+#endif
+}
 
+#ifndef OPTIONSDIALOG
 void AlwaysQueenProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6601,16 +6359,6 @@ 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);
-}
-
 #if HIGHDRAG
 void HighlightDraggingProc(w, event, prms, nprms)
      Widget w;
@@ -6748,25 +6496,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;
@@ -6876,6 +6605,7 @@ void HideThinkingProc(w, event, prms, nprms)
     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
                args, 1);
 }
+#endif
 
 void SaveOnExitProc(w, event, prms, nprms)
      Widget w;
@@ -7034,6 +6764,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 */
@@ -7337,7 +7069,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);
   }
 }
@@ -7887,50 +7621,40 @@ int OpenTCP(host, port, pr)
 #if OMIT_SOCKETS
     DisplayFatalError(_("Socket support is not configured in"), 0, 2);
 #else  /* !OMIT_SOCKETS */
+    struct addrinfo hints;
+    struct addrinfo *ais, *ai;
+    int error;
     int s;
-    struct sockaddr_in sa;
-    struct hostent     *hp;
-    unsigned short uport;
     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));
@@ -7939,7 +7663,6 @@ int OpenTCP(host, port, pr)
     cp->fdFrom = s;
     cp->fdTo = s;
     *pr = (ProcRef) cp;
-
 #endif /* !OMIT_SOCKETS */
 
     return 0;
@@ -8296,11 +8019,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);
@@ -8308,8 +8030,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
@@ -8854,6 +8575,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;