Third method of sweep selection
[xboard.git] / xboard.c
index 4167b6c..6584d2a 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:
@@ -238,11 +238,11 @@ 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 CreateXIMPieces P((void));
 void CreateXPMPieces P((void));
 void CreateXPMBoard P((char *s, int n));
@@ -283,11 +283,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 +300,6 @@ void AskQuestionPopDown P((void));
 void PromotionPopDown P((void));
 void PromotionCallback P((Widget w, XtPointer client_data,
                          XtPointer call_data));
-void EditCommentPopDown P((void));
-void EditCommentCallback P((Widget w, XtPointer client_data,
-                           XtPointer call_data));
 void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
 void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@ -346,6 +341,8 @@ void AnalyzeFileProc P((Widget w, XEvent *event,
                         String *prms, Cardinal *nprms));
 void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
                        Cardinal *nprms));
+void MatchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void MatchOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void IcsClientProc P((Widget w, XEvent *event, String *prms,
                      Cardinal *nprms));
 void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@ -392,28 +389,21 @@ void AnimateDraggingProc P((Widget w, XEvent *event, String *prms,
                         Cardinal *nprms));
 void AnimateMovingProc P((Widget w, XEvent *event, String *prms,
                         Cardinal *nprms));
-void AutocommProc P((Widget w, XEvent *event, String *prms,
-                    Cardinal *nprms));
 void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AutobsProc P((Widget w, XEvent *event, String *prms,
-                       Cardinal *nprms));
-void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void FlashMovesProc P((Widget w, XEvent *event, String *prms,
                       Cardinal *nprms));
 void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void GetMoveListProc P((Widget w, XEvent *event, String *prms,
-                       Cardinal *nprms));
 void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
                              Cardinal *nprms));
 void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
                              Cardinal *nprms));
+void HighlightArrowProc P((Widget w, XEvent *event, String *prms,
+                             Cardinal *nprms));
 void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
-                        Cardinal *nprms));
+//void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void OneClickProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
                         Cardinal *nprms));
 void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
@@ -422,8 +412,7 @@ void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms,
                        Cardinal *nprms));
 void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
                             Cardinal *nprms));
-void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+//void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void ShowCoordsProc P((Widget w, XEvent *event, String *prms,
                       Cardinal *nprms));
 void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
@@ -458,17 +447,21 @@ void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms))
 void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void OptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void IcsTextProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void GameListOptionsPopUp P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void IcsOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void SoundOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void BoardOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void LoadOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void SaveOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void GameListOptionsPopDown P(());
 void ShufflePopDown P(());
-void EnginePopDown P(());
-void UciPopDown P(());
 void TimeControlPopDown P(());
-void NewVariantPopDown P(());
-void SettingsPopDown P(());
+void GenericPopDown P(());
 void update_ics_width P(());
 int get_term_width P(());
 int CopyMemoProc P(());
@@ -522,7 +515,7 @@ int squareSize, smallLayout = 0, tinyLayout = 0,
   fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,
   ICSInputBoxUp = False, askQuestionUp = False,
   filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,
-  editUp = False, errorUp = False, errorExitStatus = -1, lineGap;
+  errorUp = False, errorExitStatus = -1, lineGap, defaultLineGap;
 Pixel timerForegroundPixel, timerBackgroundPixel;
 Pixel buttonForegroundPixel, buttonBackgroundPixel;
 char *chessDir, *programName, *programVersion,
@@ -544,6 +537,9 @@ WindowPlacement wpEngineOutput;
 WindowPlacement wpGameList;
 WindowPlacement wpTags;
 
+extern Widget shells[];
+extern Boolean shellUp[];
+
 #define SOLID 0
 #define OUTLINE 1
 Pixmap pieceBitmap[2][(int)BlackPawn];
@@ -605,9 +601,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},
@@ -649,10 +645,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 +667,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}
 };
@@ -705,40 +706,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}
@@ -926,7 +934,6 @@ XtActionsRec boardActions[] = {
     { "ShowMoveListProc", HistoryShowProc},
     { "EditTagsProc", EditCommentProc },
     { "EditCommentProc", EditCommentProc },
-    { "IcsAlarmProc", IcsAlarmProc },
     { "IcsInputBoxProc", IcsInputBoxProc },
     { "PauseProc", PauseProc },
     { "AcceptProc", AcceptProc },
@@ -958,35 +965,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 +1002,6 @@ XtActionsRec boardActions[] = {
     { "NothingProc", NothingProc },
     { "CommentClick", (XtActionProc) CommentClick },
     { "CommentPopDown", (XtActionProc) CommentPopDown },
-    { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
     { "TagsPopDown", (XtActionProc) TagsPopDown },
     { "ErrorPopDown", (XtActionProc) ErrorPopDown },
     { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
@@ -1012,11 +1014,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 },
 };
 
@@ -1031,8 +1030,8 @@ char globalTranslations[] =
    :Ctrl<Key>c: CopyGameProc() \n \
    :Ctrl<Key>v: PasteGameProc() \n \
    :Ctrl<Key>O: LoadPositionProc() \n \
-   :Shift Meta<Key>Next: LoadNextPositionProc() \n \
-   :Shift Meta<Key>Prior: LoadPrevPositionProc() \n \
+   :Shift<Key>Next: LoadNextPositionProc() \n \
+   :Shift<Key>Prior: LoadPrevPositionProc() \n \
    :Ctrl<Key>S: SavePositionProc() \n \
    :Ctrl<Key>C: CopyPositionProc() \n \
    :Ctrl<Key>V: PastePositionProc() \n \
@@ -1070,12 +1069,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 \
@@ -1479,7 +1482,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;
@@ -1511,14 +1514,14 @@ ExportSounds()
 void
 SaveAttribsArg(FILE *f, ArgDescriptor *ad)
 {      // here the "argLoc" defines a table index. It could have contained the 'ta' pointer itself, though
-       fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, (&appData.colorShout)[(int)ad->argLoc]);
+       fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, (&appData.colorShout)[(int)(intptr_t)ad->argLoc]);
 }
 
 void
 SaveColor(FILE *f, ArgDescriptor *ad)
 {      // in WinBoard the color is an int and has to be converted to text. In X it would be a string already?
-       if(colorVariable[(int)ad->argLoc])
-       fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, *(char**)colorVariable[(int)ad->argLoc]);
+       if(colorVariable[(int)(intptr_t)ad->argLoc])
+       fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, *(char**)colorVariable[(int)(intptr_t)ad->argLoc]);
 }
 
 void
@@ -1533,7 +1536,7 @@ ParseCommPortSettings(char *s)
 }
 
 extern Widget engineOutputShell;
-extern Widget tagsShell, editTagsShell;
+
 void
 GetActualPlacement(Widget wg, WindowPlacement *wp)
 {
@@ -1565,10 +1568,8 @@ GetWindowCoords()
   if(MoveHistoryIsUp()) GetActualPlacement(historyShell, &wpMoveHistory);
   if(EvalGraphIsUp()) GetActualPlacement(evalGraphShell, &wpEvalGraph);
   if(GameListIsUp()) GetActualPlacement(gameListShell, &wpGameList);
-  if(commentShell) GetActualPlacement(commentShell, &wpComment);
-  else             GetActualPlacement(editShell,    &wpComment);
-  if(tagsShell) GetActualPlacement(tagsShell, &wpTags);
-  else      GetActualPlacement(editTagsShell, &wpTags);
+  if(shellUp[1]) GetActualPlacement(shells[1], &wpComment);
+  if(shellUp[2]) GetActualPlacement(shells[2], &wpTags);
 }
 
 void
@@ -1665,6 +1666,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 +1794,104 @@ 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;
+}
+
 int
 main(argc, argv)
      int argc;
@@ -1981,6 +2081,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) */
@@ -2026,74 +2127,7 @@ 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"),
@@ -2120,24 +2154,7 @@ XBoard square size (hint): %d\n\
                (unsigned long) XBlackPixel(xDisplay, xScreen));
     }
 
-    if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
-       parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
-       parse_cpair(ColorChannel1, appData.colorChannel1) < 0  ||
-       parse_cpair(ColorChannel, appData.colorChannel) < 0  ||
-       parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
-       parse_cpair(ColorTell, appData.colorTell) < 0 ||
-       parse_cpair(ColorChallenge, appData.colorChallenge) < 0  ||
-       parse_cpair(ColorRequest, appData.colorRequest) < 0  ||
-       parse_cpair(ColorSeek, appData.colorSeek) < 0  ||
-       parse_cpair(ColorNormal, appData.colorNormal) < 0)
-      {
-         if (appData.colorize) {
-             fprintf(stderr,
-                     _("%s: can't parse color names; disabling colorization\n"),
-                     programName);
-         }
-         appData.colorize = FALSE;
-      }
+    ParseIcsTextColors();
     textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
     textColors[ColorNone].attr = 0;
 
@@ -2395,6 +2412,7 @@ XBoard square size (hint): %d\n\
     ReadBitmap(&xMarkPixmap, "checkmark.bm",
               checkmark_bits, checkmark_width, checkmark_height);
     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
+#ifndef OPTIONSDIALOG
     if (appData.alwaysPromoteToQueen) {
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
                    args, 1);
@@ -2408,10 +2426,6 @@ XBoard square size (hint): %d\n\
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
                    args, 1);
     }
-    if (appData.autoComment) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
-                   args, 1);
-    }
     if (appData.autoCallFlag) {
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
                    args, 1);
@@ -2420,26 +2434,6 @@ XBoard square size (hint): %d\n\
        XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
                    args, 1);
     }
-    if (appData.autoObserve) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
-                   args, 1);
-    }
-    if (appData.autoRaiseBoard) {
-       XtSetValues(XtNameToWidget(menuBarWidget,
-                                  "menuOptions.Auto Raise Board"), args, 1);
-    }
-    if (appData.autoSaveGames) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
-                   args, 1);
-    }
-    if (appData.saveGameFile[0] != NULLCHAR) {
-       /* Can't turn this off from menu */
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
-                   args, 1);
-       XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
-                      False);
-
-    }
     if (appData.blindfold) {
        XtSetValues(XtNameToWidget(menuBarWidget,
                                   "menuOptions.Blindfold"), args, 1);
@@ -2449,10 +2443,6 @@ XBoard square size (hint): %d\n\
                                   "menuOptions.Flash Moves"),
                    args, 1);
     }
-    if (appData.getMoveList) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
-                   args, 1);
-    }
 #if HIGHDRAG
     if (appData.highlightDragging) {
        XtSetValues(XtNameToWidget(menuBarWidget,
@@ -2465,17 +2455,22 @@ XBoard square size (hint): %d\n\
                                   "menuOptions.Highlight Last Move"),
                    args, 1);
     }
-    if (appData.icsAlarm) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
+    if (appData.highlightMoveWithArrow) {
+       XtSetValues(XtNameToWidget(menuBarWidget,
+                                  "menuOptions.Arrow"),
                    args, 1);
     }
+//    if (appData.icsAlarm) {
+//     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
+//                 args, 1);
+//    }
     if (appData.ringBellAfterMoves) {
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
                    args, 1);
     }
-    if (appData.oldSaveStyle) {
+    if (appData.oneClick) {
        XtSetValues(XtNameToWidget(menuBarWidget,
-                                  "menuOptions.Old Save Style"), args, 1);
+                                  "menuOptions.OneClick"), args, 1);
     }
     if (appData.periodicUpdates) {
        XtSetValues(XtNameToWidget(menuBarWidget,
@@ -2493,14 +2488,10 @@ XBoard square size (hint): %d\n\
        XtSetValues(XtNameToWidget(menuBarWidget,
                                   "menuOptions.Popup Move Errors"), args, 1);
     }
-    if (appData.premove) {
-       XtSetValues(XtNameToWidget(menuBarWidget,
-                                  "menuOptions.Premove"), args, 1);
-    }
-    if (appData.quietPlay) {
-       XtSetValues(XtNameToWidget(menuBarWidget,
-                                  "menuOptions.Quiet Play"), args, 1);
-    }
+//    if (appData.premove) {
+//     XtSetValues(XtNameToWidget(menuBarWidget,
+//                                "menuOptions.Premove"), args, 1);
+//    }
     if (appData.showCoords) {
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
                    args, 1);
@@ -2513,6 +2504,7 @@ XBoard square size (hint): %d\n\
        XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
                    args, 1);
     }
+#endif
     if (saveSettingsOnExit) {
        XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Save Settings on Exit"),
                    args, 1);
@@ -2551,7 +2543,7 @@ XBoard square size (hint): %d\n\
 
     CatchDeleteWindow(shellWidget, "QuitProc");
 
-    CreateGCs();
+    CreateGCs(False);
     CreateGrid();
 #if HAVE_LIBXPM
     if (appData.bitmapDirectory[0] != NULLCHAR) {
@@ -2717,7 +2709,6 @@ void
 ResetFrontEnd()
 {
     CommentPopDown();
-    EditCommentPopDown();
     TagsPopDown();
     return;
 }
@@ -2772,13 +2763,16 @@ 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 },
+#endif
     { "menuEngine.Engine #1 Settings", False },
 #endif
     { "menuEngine.Engine #2 Settings", False },
@@ -2794,7 +2788,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 +2799,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 +2816,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 +2827,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     */
@@ -2899,6 +2889,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 +2908,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 }
 };
@@ -3140,7 +3132,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;
@@ -3152,20 +3169,23 @@ void CreateGCs()
     gc_values.line_style = LineSolid;
     gc_values.function = GXcopy;
 
-    gc_values.foreground = XBlackPixel(xDisplay, xScreen);
-    gc_values.background = XBlackPixel(xDisplay, xScreen);
-    lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
+  if(redo) {
+    DeleteGCs(); // called a second time; clean up old GCs first
+  } else { // [HGM] grid and font GCs created on first call only
     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
     gc_values.background = XWhitePixel(xDisplay, xScreen);
     coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
     XSetFont(xDisplay, coordGC, coordFontID);
 
-    // [HGM] make font for holdings counts (white on black0
+    // [HGM] make font for holdings counts (white on black)
     gc_values.foreground = XWhitePixel(xDisplay, xScreen);
     gc_values.background = XBlackPixel(xDisplay, xScreen);
     countGC = XtGetGC(shellWidget, value_mask, &gc_values);
     XSetFont(xDisplay, countGC, countFontID);
+  }
+    gc_values.foreground = XBlackPixel(xDisplay, xScreen);
+    gc_values.background = XBlackPixel(xDisplay, xScreen);
+    lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
 
     if (appData.monoMode) {
        gc_values.foreground = XWhitePixel(xDisplay, xScreen);
@@ -3293,6 +3313,8 @@ void loadXIM(xim, xmask, filename, dest, mask)
        }
     }
 
+    fclose(fp);
+
     /* create Pixmap of piece */
     *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
                          w, h, xim->depth);
@@ -3413,17 +3435,31 @@ void CreateXIMPieces()
     XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
 }
 
+static VariantClass oldVariant = (VariantClass) -1; // [HGM] pieces: redo every time variant changes
+
 #if HAVE_LIBXPM
 void CreateXPMBoard(char *s, int kind)
 {
     XpmAttributes attr;
     attr.valuemask = 0;
-    if(s == NULL || *s == 0 || *s == '*') 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;
@@ -3432,6 +3468,9 @@ void CreateXPMPieces()
     XpmAttributes attr;
     static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
     XpmColorSymbol symbols[4];
+    static int redo = False;
+
+    if(redo) FreeXPMPieces(); else redo = 1;
 
     /* The XSynchronize calls were copied from CreatePieces.
        Not sure if needed, but can't hurt */
@@ -3556,6 +3595,7 @@ void CreateXPMPieces()
        xpmJailSquare = xpmLightSquare;
        fprintf(stderr, _("Done.\n"));
     }
+    oldVariant = -1; // kludge to force re-makig of animation masks
     XSynchronize(xDisplay, False); /* Work-around for xlib/xt
                                      buffering bug */
 }
@@ -3911,6 +3951,7 @@ void PieceMenuPopup(w, event, params, num_params)
      Cardinal *num_params;
 {
     String whichMenu; int menuNr;
+    shiftKey = strcmp(params[0], "menuW"); // used to indicate black
     if (event->type == ButtonRelease)
         menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY);
     else if (event->type == ButtonPress)
@@ -3949,11 +3990,7 @@ void WhiteClock(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    if (gameMode == EditPosition || gameMode == IcsExamining) {
-       SetWhiteToPlayEvent();
-    } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
-       CallFlagEvent();
-    }
+    ClockClick(0);
 }
 
 void BlackClock(w, event, prms, nprms)
@@ -3962,11 +3999,7 @@ void BlackClock(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    if (gameMode == EditPosition || gameMode == IcsExamining) {
-       SetBlackToPlayEvent();
-    } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
-       CallFlagEvent();
-    }
+    ClockClick(1);
 }
 
 
@@ -4263,7 +4296,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 +4421,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 +4522,6 @@ static int too_many_diffs(b1, b2)
            }
        }
     }
-
     return 0;
 }
 
@@ -4605,9 +4637,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 +4766,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 +4776,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 +4796,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 +4815,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,90 +4827,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;
 {
@@ -5253,7 +4856,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);
     }
 }
@@ -5363,6 +4966,16 @@ void PromotionPopUp()
                                   layout, args, j);
 
   if(gameInfo.variant != VariantShogi) {
+   if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) {
+      XawDialogAddButton(dialog, _("Warlord"), PromotionCallback,
+                        (XtPointer) dialog);
+      XawDialogAddButton(dialog, _("General"), PromotionCallback,
+                        (XtPointer) dialog);
+      XawDialogAddButton(dialog, _("Lieutenant"), PromotionCallback,
+                        (XtPointer) dialog);
+      XawDialogAddButton(dialog, _("Captain"), PromotionCallback,
+                        (XtPointer) dialog);
+    } else {\r
     XawDialogAddButton(dialog, _("Queen"), PromotionCallback,
                       (XtPointer) dialog);
     XawDialogAddButton(dialog, _("Rook"), PromotionCallback,
@@ -5371,7 +4984,9 @@ void PromotionPopUp()
                       (XtPointer) dialog);
     XawDialogAddButton(dialog, _("Knight"), PromotionCallback,
                       (XtPointer) dialog);
+    }
     if (!appData.testLegality || gameInfo.variant == VariantSuicide ||
+        gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove) ||\r
         gameInfo.variant == VariantGiveaway) {
       XawDialogAddButton(dialog, _("King"), PromotionCallback,
                         (XtPointer) dialog);
@@ -5705,7 +5320,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 +5386,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 +5397,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 +5409,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 +5552,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;
@@ -6116,8 +5734,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 +5755,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 +5773,20 @@ void TwoMachinesProc(w, event, prms, nprms)
     TwoMachinesEvent();
 }
 
+void MatchProc(w, event, prms, nprms)
+     Widget w;
+     XEvent *event;
+     String *prms;
+     Cardinal *nprms;
+{
+    if(gameMode != BeginningOfGame) { DisplayError(_("You can only start a match from the initial position."), 0); return; }
+    matchMode = 2; // This is back-end, really\r
+    appData.matchGames = appData.defaultMatchGames;\r
+    matchGame = 1;\r
+    first.matchWins = second.matchWins = 0;\r
+    TwoMachinesEvent();
+}
+
 void IcsClientProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6195,11 +5829,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 +5846,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 +5954,7 @@ void EnterKeyProc(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    if (ICSInputBoxUp == True)
+    if (shellUp[4] == True)
       ICSInputSendText();
 }
 
@@ -6336,8 +5970,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 +5995,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 +6116,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 +6134,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 +6155,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 +6174,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 +6194,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 +6244,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 +6308,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 +6317,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 +6337,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 +6356,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 +6386,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 +6407,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 +6415,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 +6445,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 +6483,7 @@ void PopupMoveErrorsProc(w, event, prms, nprms)
                args, 1);
 }
 
+#if 0
 void PremoveProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6943,25 +6502,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 +6554,7 @@ void HideThinkingProc(w, event, prms, nprms)
     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
                args, 1);
 }
+#endif
 
 void SaveOnExitProc(w, event, prms, nprms)
      Widget w;
@@ -7474,7 +7016,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);
   }
 }
@@ -8433,11 +7977,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);
@@ -8735,6 +8278,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;
@@ -8990,6 +8534,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 +8826,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;
-        }
     }
 }