Merge branch 'master' into gtk
authorArun Persaud <arun@nubati.net>
Sun, 7 Feb 2010 00:15:15 +0000 (16:15 -0800)
committerArun Persaud <arun@nubati.net>
Sun, 7 Feb 2010 00:15:15 +0000 (16:15 -0800)
Conflicts:
Makefile.am
backend.c
configure.ac
xboard.c
xgamelist.c

1  2 
Makefile.am
backend.c
configure.ac
frontend.h
xboard.c
xgamelist.c
xoptions.c

diff --combined Makefile.am
@@@ -6,16 -6,13 +6,16 @@@ els
  endif
  
  bin_PROGRAMS = xboard
 +
  xboard_SOURCES = backend.c backend.h backendz.h \
                 book.c \
 +               callback.c callback.h \
                 childio.c childio.h \
                 common.h \
                 frontend.h \
                 gamelist.c \
                 gettext.h  \
 +               interface.c interface.h \
                 lists.c lists.h \
                 moves.c moves.h \
                 parser.l parser.h \
                 xgamelist.c xgamelist.h\
                 xhistory.c  xhistory.h \
                 xoptions.c \
 +               gtk-interface.xml \
                 $(ZPY)
 -xboard_LDADD = -lm @XAW_LIBS@ @X_LIBS@ 
  
 -EXTRA_DIST = pixmaps bitmaps winboard sounds \
 -      xboard.texi gpl.texinfo texi2man texinfo.tex xboard.man \
 +xboard_LDADD = -lm  @XAW_LIBS@ @GTK_LIBS@
 +
 +EXTRA_DIST = pixmaps bitmaps svg sounds \
 +      xboard.texi gpl.texinfo texi2man texinfo.tex xboard.man xboard.conf \
        COPYRIGHT FAQ.html engine-intf.html ics-parsing.txt readme.htm readme_HGM.txt zippy.README
  
  DISTCLEANFILES = stamp-h
  
- AM_CPPFLAGS=-DINFODIR='"$(infodir)"' @GTK_CFLAGS@
 -AM_CPPFLAGS=-DINFODIR='"$(infodir)"' @X_CFLAGS@  -DSYSCONFDIR='"$(sysconfdir)"'
++
++AM_CPPFLAGS=-DINFODIR='"$(infodir)"' @GTK_CFLAGS@  -DSYSCONFDIR='"$(sysconfdir)"'
++
  
  info_TEXINFOS =  xboard.texi
  xboard_TEXINFOS =  copyright.texi 
  man6_MANS = xboard.man
  
- sysconf_DATA=xboard.conf
++
+ dist_sysconf_DATA = xboard.conf
 +
  xboard.man: xboard.texi copyright.texi gpl.texinfo version.texi
        $(srcdir)/texi2man $(srcdir)/xboard.texi > xboard.man || (rm -f xboard.man ; false)
diff --combined backend.c
+++ b/backend.c
@@@ -126,15 -126,15 +126,15 @@@ extern int gettimeofday(struct timeval 
  # include "zippy.h"
  #endif
  #include "backendz.h"
 -#include "gettext.h" 
 - 
 -#ifdef ENABLE_NLS 
 -# define _(s) gettext (s) 
 -# define N_(s) gettext_noop (s) 
 -#else 
 -# define _(s) (s) 
 -# define N_(s) s 
 -#endif 
 +#include "gettext.h"
 +
 +#ifdef ENABLE_NLS
 +# define _(s) gettext (s)
 +# define N_(s) gettext_noop (s)
 +#else
 +# define _(s) (s)
 +# define N_(s) s
 +#endif
  
  
  /* A point in time */
@@@ -167,6 -167,7 +167,7 @@@ int FinishMove P((ChessMove moveType, i
                   /*char*/int promoChar));
  void BackwardInner P((int target));
  void ForwardInner P((int target));
+ int Adjudicate P((ChessProgramState *cps));
  void GameEnds P((ChessMove result, char *resultDetails, int whosays));
  void EditPositionDone P((Boolean fakeRights));
  void PrintOpponents P((FILE *fp));
@@@ -187,6 -188,7 +188,7 @@@ void DisplayMove P((int moveNumber))
  
  void ParseGameHistory P((char *game));
  void ParseBoard12 P((char *string));
+ void KeepAlive P((void));
  void StartClocks P((void));
  void SwitchClocks P((void));
  void StopClocks P((void));
@@@ -244,6 -246,7 +246,7 @@@ char endingGame = 0;    /* [HGM] crash
  int whiteNPS, blackNPS; /* [HGM] nps: for easily making clocks aware of NPS     */
  VariantClass currentlyInitializedVariant; /* [HGM] variantswitch */
  int lastIndex = 0;      /* [HGM] autoinc: last game/position used in match mode */
+ Boolean connectionAlive;/* [HGM] alive: ICS connection status from probing      */
  int opponentKibitzes;
  int lastSavedGame; /* [HGM] save: ID of game */
  char chatPartner[MAX_CHAT][MSG_SIZ]; /* [HGM] chat: list of chatting partners */
@@@ -350,7 -353,7 +353,7 @@@ PosFlags(index
    case VariantKriegspiel:
      flags |= F_KRIEGSPIEL_CAPTURE;
      break;
 -  case VariantCapaRandom: 
 +  case VariantCapaRandom:
    case VariantFischeRandom:
      flags |= F_FRC_TYPE_CASTLING; /* [HGM] enable this through flag */
    case VariantNoCastle:
  
  FILE *gameFileFP, *debugFP;
  
 -/* 
 +/*
      [AS] Note: sometimes, the sscanf() function is used to parse the input
      into a fixed-size buffer. Because of this, we must be prepared to
      receive strings as long as the size of the input buffer, which is currently
@@@ -450,7 -453,7 +453,7 @@@ signed char  initialRights[BOARD_FILES]
  int   nrCastlingRights; // For TwoKings, or to implement castling-unknown status
  int   initialRulePlies, FENrulePlies;
  FILE  *serverMoves = NULL; // next two for broadcasting (/serverMoves option)
 -int loadFlag = 0; 
 +int loadFlag = 0;
  int shuffleOpenings;
  int mute; // mute all sounds
  
@@@ -527,31 -530,31 +530,31 @@@ ChessSquare XiangqiArray[2][BOARD_FILES
  };
  
  ChessSquare CapablancaArray[2][BOARD_FILES] = {
 -    { WhiteRook, WhiteKnight, WhiteAngel, WhiteBishop, WhiteQueen, 
 +    { WhiteRook, WhiteKnight, WhiteAngel, WhiteBishop, WhiteQueen,
          WhiteKing, WhiteBishop, WhiteMarshall, WhiteKnight, WhiteRook },
 -    { BlackRook, BlackKnight, BlackAngel, BlackBishop, BlackQueen, 
 +    { BlackRook, BlackKnight, BlackAngel, BlackBishop, BlackQueen,
          BlackKing, BlackBishop, BlackMarshall, BlackKnight, BlackRook }
  };
  
  ChessSquare GreatArray[2][BOARD_FILES] = {
 -    { WhiteDragon, WhiteKnight, WhiteAlfil, WhiteGrasshopper, WhiteKing, 
 +    { WhiteDragon, WhiteKnight, WhiteAlfil, WhiteGrasshopper, WhiteKing,
          WhiteSilver, WhiteCardinal, WhiteAlfil, WhiteKnight, WhiteDragon },
 -    { BlackDragon, BlackKnight, BlackAlfil, BlackGrasshopper, BlackKing, 
 +    { BlackDragon, BlackKnight, BlackAlfil, BlackGrasshopper, BlackKing,
          BlackSilver, BlackCardinal, BlackAlfil, BlackKnight, BlackDragon },
  };
  
  ChessSquare JanusArray[2][BOARD_FILES] = {
 -    { WhiteRook, WhiteAngel, WhiteKnight, WhiteBishop, WhiteKing, 
 +    { WhiteRook, WhiteAngel, WhiteKnight, WhiteBishop, WhiteKing,
          WhiteQueen, WhiteBishop, WhiteKnight, WhiteAngel, WhiteRook },
 -    { BlackRook, BlackAngel, BlackKnight, BlackBishop, BlackKing, 
 +    { BlackRook, BlackAngel, BlackKnight, BlackBishop, BlackKing,
          BlackQueen, BlackBishop, BlackKnight, BlackAngel, BlackRook }
  };
  
  #ifdef GOTHIC
  ChessSquare GothicArray[2][BOARD_FILES] = {
 -    { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen, WhiteMarshall, 
 +    { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen, WhiteMarshall,
          WhiteKing, WhiteAngel, WhiteBishop, WhiteKnight, WhiteRook },
 -    { BlackRook, BlackKnight, BlackBishop, BlackQueen, BlackMarshall, 
 +    { BlackRook, BlackKnight, BlackBishop, BlackQueen, BlackMarshall,
          BlackKing, BlackAngel, BlackBishop, BlackKnight, BlackRook }
  };
  #else // !GOTHIC
  
  #ifdef FALCON
  ChessSquare FalconArray[2][BOARD_FILES] = {
 -    { WhiteRook, WhiteKnight, WhiteBishop, WhiteLance, WhiteQueen, 
 +    { WhiteRook, WhiteKnight, WhiteBishop, WhiteLance, WhiteQueen,
          WhiteKing, WhiteLance, WhiteBishop, WhiteKnight, WhiteRook },
 -    { BlackRook, BlackKnight, BlackBishop, BlackLance, BlackQueen, 
 +    { BlackRook, BlackKnight, BlackBishop, BlackLance, BlackQueen,
          BlackKing, BlackLance, BlackBishop, BlackKnight, BlackRook }
  };
  #else // !FALCON
@@@ -647,7 -650,7 +650,7 @@@ InitBackEnd1(
      if (appData.icsActive) {
        appData.matchMode = FALSE;
        appData.matchGames = 0;
 -#if ZIPPY     
 +#if ZIPPY
        appData.noChessProgram = !appData.zippyPlay;
  #else
        appData.zippyPlay = FALSE;
  
      /* [AS] Adjudication threshold */
      adjudicateLossThreshold = appData.adjudicateLossThreshold;
 -    
 +
      first.which = "first";
      second.which = "second";
      first.maybeThinking = second.maybeThinking = FALSE;
        appData.clockMode = FALSE;
        first.sendTime = second.sendTime = 0;
      }
 -    
 +
  #if ZIPPY
      /* Override some settings from environment variables, for backward
         compatibility.  Unfortunately it's not feasible to have the env
        ZippyInit();
      }
  #endif
 -    
 +
      if (appData.noChessProgram) {
        programVersion = (char*) malloc(5 + strlen(PACKAGE_STRING));
        sprintf(programVersion, "%s", PACKAGE_STRING);
@@@ -967,7 -970,7 +970,7 @@@ int NextSessionFromString( char ** str
              if(result = NextIntegerFromString( str, &temp2)) return -1;
              *inc = temp2 * 1000;
          } else *inc = 0;
 -        *moves = 0; *tc = temp * 1000; 
 +        *moves = 0; *tc = temp * 1000;
          return 0;
      } else if(temp % 60 != 0) return -1;     /* moves was given as min:sec */
  
@@@ -1062,297 -1065,230 +1065,300 @@@ ParseTimeControl(tc, ti, mps
  void
  InitBackEnd2()
  {
 -    if (appData.debugMode) {
 -      fprintf(debugFP, "%s\n", programVersion);
 -    }
 +  if (appData.debugMode) {
 +    fprintf(debugFP, "%s\n", programVersion);
 +  }
  
 -    set_cont_sequence(appData.wrapContSeq);
 -    if (appData.matchGames > 0) {
 -      appData.matchMode = TRUE;
 -    } else if (appData.matchMode) {
 -      appData.matchGames = 1;
 -    }
 -    if(appData.matchMode && appData.sameColorGames > 0) /* [HGM] alternate: overrule matchGames */
 -      appData.matchGames = appData.sameColorGames;
 -    if(appData.rewindIndex > 1) { /* [HGM] autoinc: rewind implies auto-increment and overrules given index */
 -      if(appData.loadPositionIndex >= 0) appData.loadPositionIndex = -1;
 -      if(appData.loadGameIndex >= 0) appData.loadGameIndex = -1;
 -    }
 -    Reset(TRUE, FALSE);
 -    if (appData.noChessProgram || first.protocolVersion == 1) {
 -      InitBackEnd3();
 +  set_cont_sequence(appData.wrapContSeq);
 +  if (appData.matchGames > 0) {
 +    appData.matchMode = TRUE;
 +  } else if (appData.matchMode) {
 +    appData.matchGames = 1;
 +  }
 +  if(appData.matchMode && appData.sameColorGames > 0) /* [HGM] alternate: overrule matchGames */
 +    appData.matchGames = appData.sameColorGames;
 +  if(appData.rewindIndex > 1) { /* [HGM] autoinc: rewind implies auto-increment and overrules given index */
 +    if(appData.loadPositionIndex >= 0) appData.loadPositionIndex = -1;
 +    if(appData.loadGameIndex >= 0) appData.loadGameIndex = -1;
 +  }
 +  Reset(TRUE, FALSE);
 +  if (appData.noChessProgram || first.protocolVersion == 1) {
 +    InitBackEnd3();
      } else {
 -      /* kludge: allow timeout for initial "feature" commands */
 -      FreezeUI();
 -      DisplayMessage("", _("Starting chess program"));
 -      ScheduleDelayedEvent(InitBackEnd3, FEATURE_TIMEOUT);
 -    }
 +    /* kludge: allow timeout for initial "feature" commands */
 +    FreezeUI();
 +    DisplayMessage("", _("Starting chess program"));
 +    ScheduleDelayedEvent(InitBackEnd3, FEATURE_TIMEOUT);
 +  }
  }
  
  void
  InitBackEnd3 P((void))
  {
 -    GameMode initialMode;
 -    char buf[MSG_SIZ];
 -    int err;
 -
 -    InitChessProgram(&first, startedFromSetupPosition);
 -
 -
 -    if (appData.icsActive) {
 -#ifdef WIN32
 -        /* [DM] Make a console window if needed [HGM] merged ifs */
 -        ConsoleCreate(); 
 -#endif
 -      err = establish();
 -      if (err != 0) {
 -          if (*appData.icsCommPort != NULLCHAR) {
 -              sprintf(buf, _("Could not open comm port %s"),  
 -                      appData.icsCommPort);
 -          } else {
 -              snprintf(buf, sizeof(buf), _("Could not connect to host %s, port %s"),  
 -                      appData.icsHost, appData.icsPort);
 -          }
 -          DisplayFatalError(buf, err, 1);
 -          return;
 +  GameMode initialMode;
 +  char buf[MSG_SIZ];
 +  int err;
 +  
 +  InitChessProgram(&first, startedFromSetupPosition);
 +  
 +  
 +  if (appData.icsActive) 
 +    {
 +      err = establish();
 +      if (err != 0) 
 +      {
 +        if (*appData.icsCommPort != NULLCHAR) 
 +          {
 +            sprintf(buf, _("Could not open comm port %s"),
 +                    appData.icsCommPort);
 +          }
 +        else 
 +          {
 +            snprintf(buf, sizeof(buf), _("Could not connect to host %s, port %s"),
 +                     appData.icsHost, appData.icsPort);
 +          }
 +        DisplayFatalError(buf, err, 1);
 +        return;
        }
-       SetICSMode();
-       telnetISR =
-       AddInputSource(icsPR, FALSE, read_from_ics, &telnetISR);
-       fromUserISR =
-       AddInputSource(NoProc, FALSE, read_from_player, &fromUserISR);
++
+       SetICSMode();
+       telnetISR =
+         AddInputSource(icsPR, FALSE, read_from_ics, &telnetISR);
+       fromUserISR =
+         AddInputSource(NoProc, FALSE, read_from_player, &fromUserISR);
+       if(appData.keepAlive) // [HGM] alive: schedule sending of dummy 'date' command
+           ScheduleDelayedEvent(KeepAlive, appData.keepAlive*60*1000);
 -    } else if (appData.noChessProgram) {
 -      SetNCPMode();
 -    } else {
 -      SetGNUMode();
      }
 -
 -    if (*appData.cmailGameName != NULLCHAR) {
 -      SetCmailMode();
 -      OpenLoopback(&cmailPR);
 -      cmailISR =
 -        AddInputSource(cmailPR, FALSE, CmailSigHandlerCallBack, &cmailISR);
 +  else if (appData.noChessProgram) 
 +    {
 +      SetNCPMode();
 +    } 
 +  else 
 +    {
 +      SetGNUMode();
      }
 -    
 -    ThawUI();
 -    DisplayMessage("", "");
 -    if (StrCaseCmp(appData.initialMode, "") == 0) {
 +  
 +  if (*appData.cmailGameName != NULLCHAR) 
 +    {
 +      SetCmailMode();
 +      OpenLoopback(&cmailPR);
 +      cmailISR =
 +      AddInputSource(cmailPR, FALSE, CmailSigHandlerCallBack, &cmailISR);
 +    }
 +  
 +  ThawUI();
 +  DisplayMessage("", "");
 +  if (StrCaseCmp(appData.initialMode, "") == 0) 
 +    {
        initialMode = BeginningOfGame;
 -    } else if (StrCaseCmp(appData.initialMode, "TwoMachines") == 0) {
 +    } 
 +  else if (StrCaseCmp(appData.initialMode, "TwoMachines") == 0) 
 +    {
        initialMode = TwoMachinesPlay;
 -    } else if (StrCaseCmp(appData.initialMode, "AnalyzeFile") == 0) {
 -      initialMode = AnalyzeFile; 
 -    } else if (StrCaseCmp(appData.initialMode, "Analysis") == 0) {
 +    } 
 +  else if (StrCaseCmp(appData.initialMode, "AnalyzeFile") == 0) 
 +    {
 +      initialMode = AnalyzeFile;
 +    } 
 +  else if (StrCaseCmp(appData.initialMode, "Analysis") == 0) 
 +    {
        initialMode = AnalyzeMode;
 -    } else if (StrCaseCmp(appData.initialMode, "MachineWhite") == 0) {
 +    } 
 +  else if (StrCaseCmp(appData.initialMode, "MachineWhite") == 0) 
 +    {
        initialMode = MachinePlaysWhite;
 -    } else if (StrCaseCmp(appData.initialMode, "MachineBlack") == 0) {
 +    } 
 +  else if (StrCaseCmp(appData.initialMode, "MachineBlack") == 0) 
 +    {
        initialMode = MachinePlaysBlack;
 -    } else if (StrCaseCmp(appData.initialMode, "EditGame") == 0) {
 +    } 
 +  else if (StrCaseCmp(appData.initialMode, "EditGame") == 0) 
 +    {
        initialMode = EditGame;
 -    } else if (StrCaseCmp(appData.initialMode, "EditPosition") == 0) {
 +    } 
 +  else if (StrCaseCmp(appData.initialMode, "EditPosition") == 0) 
 +    {
        initialMode = EditPosition;
 -    } else if (StrCaseCmp(appData.initialMode, "Training") == 0) {
 +    } 
 +  else if (StrCaseCmp(appData.initialMode, "Training") == 0) 
 +    {
        initialMode = Training;
 -    } else {
 +    } 
 +  else 
 +    {
        sprintf(buf, _("Unknown initialMode %s"), appData.initialMode);
        DisplayFatalError(buf, 0, 2);
        return;
      }
 -
 -    if (appData.matchMode) {
 -      /* Set up machine vs. machine match */
 -      if (appData.noChessProgram) {
 -          DisplayFatalError(_("Can't have a match with no chess programs"),
 -                            0, 2);
 -          return;
 +  
 +  if (appData.matchMode) 
 +    {
 +      /* Set up machine vs. machine match */
 +      if (appData.noChessProgram) 
 +      {
 +        DisplayFatalError(_("Can't have a match with no chess programs"),
 +                          0, 2);
 +        return;
        }
 -      matchMode = TRUE;
 -      matchGame = 1;
 -      if (*appData.loadGameFile != NULLCHAR) {
 -          int index = appData.loadGameIndex; // [HGM] autoinc
 -          if(index<0) lastIndex = index = 1;
 -          if (!LoadGameFromFile(appData.loadGameFile,
 -                                index,
 -                                appData.loadGameFile, FALSE)) {
 -              DisplayFatalError(_("Bad game file"), 0, 1);
 -              return;
 -          }
 -      } else if (*appData.loadPositionFile != NULLCHAR) {
 -          int index = appData.loadPositionIndex; // [HGM] autoinc
 -          if(index<0) lastIndex = index = 1;
 -          if (!LoadPositionFromFile(appData.loadPositionFile,
 -                                    index,
 -                                    appData.loadPositionFile)) {
 -              DisplayFatalError(_("Bad position file"), 0, 1);
 -              return;
 +      matchMode = TRUE;
 +      matchGame = 1;
 +      if (*appData.loadGameFile != NULLCHAR) 
 +      {
 +        int index = appData.loadGameIndex; // [HGM] autoinc
 +        if(index<0) lastIndex = index = 1;
 +        if (!LoadGameFromFile(appData.loadGameFile,
 +                              index,
 +                              appData.loadGameFile, FALSE)) 
 +          {
 +            DisplayFatalError(_("Bad game file"), 0, 1);
 +            return;
            }
 -      }
 -      TwoMachinesEvent();
 -    } else if (*appData.cmailGameName != NULLCHAR) {
 -      /* Set up cmail mode */
 -      ReloadCmailMsgEvent(TRUE);
 -    } else {
 -      /* Set up other modes */
 -      if (initialMode == AnalyzeFile) {
 -        if (*appData.loadGameFile == NULLCHAR) {
 -          DisplayFatalError(_("AnalyzeFile mode requires a game file"), 0, 1);
 -          return;
 -        }
 -      }
 -      if (*appData.loadGameFile != NULLCHAR) {
 -          (void) LoadGameFromFile(appData.loadGameFile,
 -                                  appData.loadGameIndex,
 -                                  appData.loadGameFile, TRUE);
 -      } else if (*appData.loadPositionFile != NULLCHAR) {
 -          (void) LoadPositionFromFile(appData.loadPositionFile,
 -                                      appData.loadPositionIndex,
 -                                      appData.loadPositionFile);
 -            /* [HGM] try to make self-starting even after FEN load */
 -            /* to allow automatic setup of fairy variants with wtm */
 -            if(initialMode == BeginningOfGame && !blackPlaysFirst) {
 -                gameMode = BeginningOfGame;
 -                setboardSpoiledMachineBlack = 1;
 -            }
 -            /* [HGM] loadPos: make that every new game uses the setup */
 -            /* from file as long as we do not switch variant          */
 -            if(!blackPlaysFirst) {
 -                startedFromPositionFile = TRUE;
 -                CopyBoard(filePosition, boards[0]);
 +      } 
 +      else if (*appData.loadPositionFile != NULLCHAR) 
 +      {
 +        int index = appData.loadPositionIndex; // [HGM] autoinc
 +        if(index<0) lastIndex = index = 1;
 +        if (!LoadPositionFromFile(appData.loadPositionFile,
 +                                  index,
 +                                  appData.loadPositionFile)) 
 +          {
 +            DisplayFatalError(_("Bad position file"), 0, 1);
 +            return;
 +          }
 +      }
 +      TwoMachinesEvent();
 +    } 
 +  else if (*appData.cmailGameName != NULLCHAR) 
 +    {
 +      /* Set up cmail mode */
 +      ReloadCmailMsgEvent(TRUE);
 +    } 
 +  else 
 +    {
 +      /* Set up other modes */
 +      if (initialMode == AnalyzeFile) 
 +      {
 +        if (*appData.loadGameFile == NULLCHAR) 
 +          {
 +            DisplayFatalError(_("AnalyzeFile mode requires a game file"), 0, 1);
 +            return;
 +          }
 +      }
 +      if (*appData.loadGameFile != NULLCHAR) 
 +      {
 +        (void) LoadGameFromFile(appData.loadGameFile,
 +                                appData.loadGameIndex,
 +                                appData.loadGameFile, TRUE);
 +      } 
 +      else if (*appData.loadPositionFile != NULLCHAR) 
 +      {
 +        (void) LoadPositionFromFile(appData.loadPositionFile,
 +                                    appData.loadPositionIndex,
 +                                    appData.loadPositionFile);
 +        /* [HGM] try to make self-starting even after FEN load */
 +        /* to allow automatic setup of fairy variants with wtm */
 +        if(initialMode == BeginningOfGame && !blackPlaysFirst) 
 +          {
 +            gameMode = BeginningOfGame;
 +            setboardSpoiledMachineBlack = 1;
              }
 -      }
 -      if (initialMode == AnalyzeMode) {
 -        if (appData.noChessProgram) {
 -          DisplayFatalError(_("Analysis mode requires a chess engine"), 0, 2);
 -          return;
 -        }
 -        if (appData.icsActive) {
 -          DisplayFatalError(_("Analysis mode does not work with ICS mode"),0,2);
 -          return;
 -        }
 +        /* [HGM] loadPos: make that every new game uses the setup */
 +        /* from file as long as we do not switch variant          */
 +        if(!blackPlaysFirst) 
 +          {
 +            startedFromPositionFile = TRUE;
 +            CopyBoard(filePosition, boards[0]);
 +          }
 +      }
 +      if (initialMode == AnalyzeMode) 
 +      {
 +        if (appData.noChessProgram) 
 +          {
 +            DisplayFatalError(_("Analysis mode requires a chess engine"), 0, 2);
 +            return;
 +          }
 +        if (appData.icsActive) 
 +          {
 +            DisplayFatalError(_("Analysis mode does not work with ICS mode"),0,2);
 +            return;
 +          }
          AnalyzeModeEvent();
 -      } else if (initialMode == AnalyzeFile) {
 +      } 
 +      else if (initialMode == AnalyzeFile) 
 +      {
          appData.showThinking = TRUE; // [HGM] thinking: moved out of ShowThinkingEvent
          ShowThinkingEvent();
          AnalyzeFileEvent();
          AnalysisPeriodicEvent(1);
 -      } else if (initialMode == MachinePlaysWhite) {
 -        if (appData.noChessProgram) {
 -          DisplayFatalError(_("MachineWhite mode requires a chess engine"),
 -                            0, 2);
 -          return;
 -        }
 -        if (appData.icsActive) {
 -          DisplayFatalError(_("MachineWhite mode does not work with ICS mode"),
 -                            0, 2);
 -          return;
 -        }
 +      } 
 +      else if (initialMode == MachinePlaysWhite) 
 +      {
 +        if (appData.noChessProgram) 
 +          {
 +            DisplayFatalError(_("MachineWhite mode requires a chess engine"),
 +                              0, 2);
 +            return;
 +          }
 +        if (appData.icsActive) 
 +          {
 +            DisplayFatalError(_("MachineWhite mode does not work with ICS mode"),
 +                              0, 2);
 +            return;
 +          }
          MachineWhiteEvent();
 -      } else if (initialMode == MachinePlaysBlack) {
 -        if (appData.noChessProgram) {
 -          DisplayFatalError(_("MachineBlack mode requires a chess engine"),
 -                            0, 2);
 -          return;
 -        }
 -        if (appData.icsActive) {
 -          DisplayFatalError(_("MachineBlack mode does not work with ICS mode"),
 -                            0, 2);
 -          return;
 -        }
 +      } 
 +      else if (initialMode == MachinePlaysBlack) 
 +      {
 +        if (appData.noChessProgram) 
 +          {
 +            DisplayFatalError(_("MachineBlack mode requires a chess engine"),
 +                              0, 2);
 +            return;
 +          }
 +        if (appData.icsActive) 
 +          {
 +            DisplayFatalError(_("MachineBlack mode does not work with ICS mode"),
 +                              0, 2);
 +            return;
 +          }
          MachineBlackEvent();
 -      } else if (initialMode == TwoMachinesPlay) {
 -        if (appData.noChessProgram) {
 -          DisplayFatalError(_("TwoMachines mode requires a chess engine"),
 -                            0, 2);
 -          return;
 -        }
 -        if (appData.icsActive) {
 -          DisplayFatalError(_("TwoMachines mode does not work with ICS mode"),
 -                            0, 2);
 -          return;
 -        }
 +      } 
 +      else if (initialMode == TwoMachinesPlay) 
 +      {
 +        if (appData.noChessProgram) 
 +          {
 +            DisplayFatalError(_("TwoMachines mode requires a chess engine"),
 +                              0, 2);
 +            return;
 +          }
 +        if (appData.icsActive) 
 +          {
 +            DisplayFatalError(_("TwoMachines mode does not work with ICS mode"),
 +                              0, 2);
 +            return;
 +          }
          TwoMachinesEvent();
 -      } else if (initialMode == EditGame) {
 +      } 
 +      else if (initialMode == EditGame) 
 +      {
          EditGameEvent();
 -      } else if (initialMode == EditPosition) {
 +      } 
 +      else if (initialMode == EditPosition) 
 +      {
          EditPositionEvent();
 -      } else if (initialMode == Training) {
 -        if (*appData.loadGameFile == NULLCHAR) {
 -          DisplayFatalError(_("Training mode requires a game file"), 0, 2);
 -          return;
 -        }
 +      } 
 +      else if (initialMode == Training) 
 +      {
 +        if (*appData.loadGameFile == NULLCHAR) 
 +          {
 +            DisplayFatalError(_("Training mode requires a game file"), 0, 2);
 +            return;
 +          }
          TrainingEvent();
        }
      }
 +  
 +  return;
  }
  
  /*
@@@ -1385,7 -1321,7 +1391,7 @@@ establish(
                        appData.icsHost, appData.icsPort);
            } else {
                snprintf(buf, sizeof(buf), "%s %s -l %s %s %s %s",
 -                      appData.remoteShell, appData.gateway, 
 +                      appData.remoteShell, appData.gateway,
                        appData.remoteUser, appData.telnetProgram,
                        appData.icsHost, appData.icsPort);
            }
@@@ -1509,6 -1445,8 +1515,8 @@@ read_from_player(isr, closure, message
  void
  KeepAlive()
  {   // [HGM] alive: periodically send dummy (date) command to ICS to prevent time-out
+     if(!connectionAlive) DisplayFatalError("No response from ICS", 0, 1);
+     connectionAlive = FALSE; // only sticks if no response to 'date' command.
      SendToICS("date\n");
      if(appData.keepAlive) ScheduleDelayedEvent(KeepAlive, appData.keepAlive*60*1000);
  }
@@@ -1568,7 -1506,7 +1576,7 @@@ SendToICSDelayed(s,msdelay
  
  
  /* Remove all highlighting escape sequences in s
 -   Also deletes any suffix starting with '(' 
 +   Also deletes any suffix starting with '('
     */
  char *
  StripHighlightAndTitle(s)
@@@ -1658,7 -1596,7 +1666,7 @@@ StringToVariant(e
  
      if (!found) {
        if ((StrCaseStr(e, "fischer") && StrCaseStr(e, "random"))
 -        || StrCaseStr(e, "wild/fr") 
 +        || StrCaseStr(e, "wild/fr")
          || StrCaseStr(e, "frc") || StrCaseStr(e, "960")) {
          v = VariantFischeRandom;
        } else if ((i = 4, p = StrCaseStr(e, "wild")) ||
          v = VariantShatranj;
          break;
  
 -      /* Temporary names for future ICC types.  The name *will* change in 
 +      /* Temporary names for future ICC types.  The name *will* change in
           the next xboard/WinBoard release after ICC defines it. */
        case 29:
          v = Variant29;
@@@ -1843,7 -1781,7 +1851,7 @@@ looking_at(buf, index, pattern
      char *bufp = &buf[*index], *patternp = pattern;
      int star_count = 0;
      char *matchp = star_match[0];
 -    
 +
      for (;;) {
        if (*patternp == NULLCHAR) {
            *index = leftover_start = bufp - buf;
@@@ -2049,6 -1987,7 +2057,6 @@@ VariantSwitch(Board board, VariantClas
      * but also when receiving holdings of a crazyhouse game. In the latter
      * case we want to add those holdings to the already received position.
      */
 -
     
     if (appData.debugMode) {
       fprintf(debugFP, "Switch board from %s to %s\n",
@@@ -2125,6 -2064,203 +2133,203 @@@ static int player2Rating = -1
  ColorClass curColor = ColorNormal;
  int suppressKibitz = 0;
  
+ // [HGM] seekgraph
+ Boolean soughtPending = FALSE;
+ Boolean seekGraphUp;
+ #define MAX_SEEK_ADS 200
+ #define SQUARE 0x80
+ char *seekAdList[MAX_SEEK_ADS];
+ int ratingList[MAX_SEEK_ADS], xList[MAX_SEEK_ADS], yList[MAX_SEEK_ADS], seekNrList[MAX_SEEK_ADS], zList[MAX_SEEK_ADS];
+ float tcList[MAX_SEEK_ADS];
+ char colorList[MAX_SEEK_ADS];
+ int nrOfSeekAds = 0;
+ int minRating = 1010, maxRating = 2800;
+ int hMargin = 10, vMargin = 20, h, w;
+ extern int squareSize, lineGap;
+ void
+ PlotSeekAd(int i)
+ {
+       int x, y, color = 0, r = ratingList[i]; float tc = tcList[i];
+       xList[i] = yList[i] = -100; // outside graph, so cannot be clicked
+       if(r < minRating+100 && r >=0 ) r = minRating+100;
+       if(r > maxRating) r = maxRating;
+       if(tc < 1.) tc = 1.;
+       if(tc > 95.) tc = 95.;
+       x = (w-hMargin)* log(tc)/log(100.) + hMargin;
+       y = ((double)r - minRating)/(maxRating - minRating)
+           * (h-vMargin-squareSize/8-1) + vMargin;
+       if(ratingList[i] < 0) y = vMargin + squareSize/4;
+       if(strstr(seekAdList[i], " u ")) color = 1;
+       if(!strstr(seekAdList[i], "lightning") && // for now all wilds same color
+          !strstr(seekAdList[i], "bullet") &&
+          !strstr(seekAdList[i], "blitz") &&
+          !strstr(seekAdList[i], "standard") ) color = 2;
+       if(strstr(seekAdList[i], "(C) ")) color |= SQUARE; // plot computer seeks as squares
+       DrawSeekDot(xList[i]=x+3*(color&~SQUARE), yList[i]=h-1-y, colorList[i]=color);
+ }
+ void
+ AddAd(char *handle, char *rating, int base, int inc,  char rated, char *type, int nr, Boolean plot)
+ {
+       char buf[MSG_SIZ], *ext = "";
+       VariantClass v = StringToVariant(type);
+       if(strstr(type, "wild")) {
+           ext = type + 4; // append wild number
+           if(v == VariantFischeRandom) type = "chess960"; else
+           if(v == VariantLoadable) type = "setup"; else
+           type = VariantName(v);
+       }
+       sprintf(buf, "%s (%s) %d %d %c %s%s", handle, rating, base, inc, rated, type, ext);
+       if(nrOfSeekAds < MAX_SEEK_ADS-1) {
+           if(seekAdList[nrOfSeekAds]) free(seekAdList[nrOfSeekAds]);
+           ratingList[nrOfSeekAds] = -1; // for if seeker has no rating
+           sscanf(rating, "%d", &ratingList[nrOfSeekAds]);
+           tcList[nrOfSeekAds] = base + (2./3.)*inc;
+           seekNrList[nrOfSeekAds] = nr;
+           zList[nrOfSeekAds] = 0;
+           seekAdList[nrOfSeekAds++] = StrSave(buf);
+           if(plot) PlotSeekAd(nrOfSeekAds-1);
+       }
+ }
+ void
+ EraseSeekDot(int i)
+ {
+     int x = xList[i], y = yList[i], d=squareSize/4, k;
+     DrawSeekBackground(x-squareSize/8, y-squareSize/8, x+squareSize/8+1, y+squareSize/8+1);
+     if(x < hMargin+d) DrawSeekAxis(hMargin, y-squareSize/8, hMargin, y+squareSize/8+1);
+     // now replot every dot that overlapped
+     for(k=0; k<nrOfSeekAds; k++) if(k != i) {
+       int xx = xList[k], yy = yList[k];
+       if(xx <= x+d && xx > x-d && yy <= y+d && yy > y-d)
+           DrawSeekDot(xx, yy, colorList[k]);
+     }
+ }
+ void
+ RemoveSeekAd(int nr)
+ {
+       int i;
+       for(i=0; i<nrOfSeekAds; i++) if(seekNrList[i] == nr) {
+           EraseSeekDot(i);
+           if(seekAdList[i]) free(seekAdList[i]);
+           seekAdList[i] = seekAdList[--nrOfSeekAds];
+           seekNrList[i] = seekNrList[nrOfSeekAds];
+           ratingList[i] = ratingList[nrOfSeekAds];
+           colorList[i]  = colorList[nrOfSeekAds];
+           tcList[i] = tcList[nrOfSeekAds];
+           xList[i]  = xList[nrOfSeekAds];
+           yList[i]  = yList[nrOfSeekAds];
+           zList[i]  = zList[nrOfSeekAds];
+           seekAdList[nrOfSeekAds] = NULL;
+           break;
+       }
+ }
+ Boolean
+ MatchSoughtLine(char *line)
+ {
+     char handle[MSG_SIZ], rating[MSG_SIZ], type[MSG_SIZ];
+     int nr, base, inc, u=0; char dummy;
+     if(sscanf(line, "%d %s %s %d %d rated %s", &nr, rating, handle, &base, &inc, type) == 6 ||
+        sscanf(line, "%d %s %s %s %d %d rated %c", &nr, rating, handle, type, &base, &inc, &dummy) == 7 ||
+        (u=1) &&
+        (sscanf(line, "%d %s %s %d %d unrated %s", &nr, rating, handle, &base, &inc, type) == 6 ||
+         sscanf(line, "%d %s %s %s %d %d unrated %c", &nr, rating, handle, type, &base, &inc, &dummy) == 7)  ) {
+       // match: compact and save the line
+       AddAd(handle, rating, base, inc, u ? 'u' : 'r', type, nr, FALSE);
+       return TRUE;
+     }
+     return FALSE;
+ }
+ int
+ DrawSeekGraph()
+ {
+     if(!seekGraphUp) return FALSE;
+     int i;
+     h = BOARD_HEIGHT * (squareSize + lineGap) + lineGap;
+     w = BOARD_WIDTH  * (squareSize + lineGap) + lineGap;
+     DrawSeekBackground(0, 0, w, h);
+     DrawSeekAxis(hMargin, h-1-vMargin, w-5, h-1-vMargin);
+     DrawSeekAxis(hMargin, h-1-vMargin, hMargin, 5);
+     for(i=0; i<4000; i+= 100) if(i>=minRating && i<maxRating) {
+       int yy =((double)i - minRating)/(maxRating - minRating)*(h-vMargin-squareSize/8-1) + vMargin;
+       yy = h-1-yy;
+       DrawSeekAxis(hMargin+5*(i%500==0), yy, hMargin-5, yy); // rating ticks
+       if(i%500 == 0) {
+           char buf[MSG_SIZ];
+           sprintf(buf, "%d", i);
+           DrawSeekText(buf, hMargin+squareSize/8+7, yy);
+       }
+     }
+     DrawSeekText("unrated", hMargin+squareSize/8+7, h-1-vMargin-squareSize/4);
+     for(i=1; i<100; i+=(i<10?1:5)) {
+       int xx = (w-hMargin)* log((double)i)/log(100.) + hMargin;
+       DrawSeekAxis(xx, h-1-vMargin, xx, h-6-vMargin-3*(i%10==0)); // TC ticks
+       if(i<=5 || (i>40 ? i%20 : i%10) == 0) {
+           char buf[MSG_SIZ];
+           sprintf(buf, "%d", i);
+           DrawSeekText(buf, xx-2-3*(i>9), h-1-vMargin/2);
+       }
+     }
+     for(i=0; i<nrOfSeekAds; i++) PlotSeekAd(i);
+     return TRUE;
+ }
+ int SeekGraphClick(ClickType click, int x, int y, int moving)
+ {
+     static int lastDown = 0, displayed = 0, lastSecond;
+     if(!seekGraphUp) { // initiate cration of seek graph by requesting seek-ad list
+       if(click == Release || moving) return FALSE;
+       nrOfSeekAds = 0;
+       soughtPending = TRUE;
+       SendToICS(ics_prefix);
+       SendToICS("sought\n"); // should this be "sought all"?
+     } else { // issue challenge based on clicked ad
+       int dist = 10000; int i, closest = 0, second = 0;
+       for(i=0; i<nrOfSeekAds; i++) {
+           int d = (x-xList[i])*(x-xList[i]) +  (y-yList[i])*(y-yList[i]) + zList[i];
+           if(d < dist) { dist = d; closest = i; }
+           second += (d - zList[i] < 120); // count in-range ads
+           if(click == Press && moving != 1 && zList[i]>0) zList[i] *= 0.8; // age priority
+       }
+       if(dist < 120) {
+           char buf[MSG_SIZ];
+           second = (second > 1);
+           if(displayed != closest || second != lastSecond) {
+               DisplayMessage(second ? "!" : "", seekAdList[closest]);
+               lastSecond = second; displayed = closest;
+           }
+           sprintf(buf, "play %d\n", seekNrList[closest]);
+           if(click == Press) {
+               if(moving == 2) zList[closest] = 100; // right-click; push to back on press
+               lastDown = closest;
+               return TRUE;
+           } // on press 'hit', only show info
+           if(moving == 2) return TRUE; // ignore right up-clicks on dot
+           SendToICS(ics_prefix);
+           SendToICS(buf); // should this be "sought all"?
+       } else if(click == Release) { // release 'miss' is ignored
+           zList[lastDown] = 100; // make future selection of the rejected ad more difficult
+           if(moving == 2) { // right up-click
+               nrOfSeekAds = 0; // refresh graph
+               soughtPending = TRUE;
+               SendToICS(ics_prefix);
+               SendToICS("sought\n"); // should this be "sought all"?
+           }
+           return TRUE;
+       } else if(moving) { if(displayed >= 0) DisplayMessage("", ""); displayed = -1; return TRUE; }
+       // press miss or release hit 'pop down' seek graph
+       seekGraphUp = FALSE;
+       DrawPosition(TRUE, NULL);
+     }
+     return TRUE;
+ }
  void
  read_from_ics(isr, closure, data, count, error)
       InputSourceRef isr;
  #define STARTED_CHATTER 5
  #define STARTED_COMMENT 6
  #define STARTED_MOVES_NOHIDE 7
 -    
 +
      static int started = STARTED_NONE;
      static char parse[20000];
      static int parse_pos = 0;
      char talker[MSG_SIZ]; // [HGM] chat
      int channel;
  
+     connectionAlive = TRUE; // [HGM] alive: I think, therefore I am...
      if (appData.debugMode) {
        if (!error) {
        fprintf(debugFP, "<ICS: ");
  //    next_out = leftover_len; // [HGM] should we set this to 0, and not print it in advance?
        next_out = 0;
        leftover_start = 0;
 -      
 +
        i = 0;
        while (i < buf_len) {
            /* Deal with part of the TELNET option negotiation
                  next_out = i;
                continue;
            }
 -              
 +
            /* OK, this at least will *usually* work */
            if (!loggedOn && looking_at(buf, &i, "ics%")) {
                loggedOn = TRUE;
            }
 -          
 +
            if (loggedOn && !intfSet) {
                if (ics_type == ICS_ICC) {
                  sprintf(str,
                          "/set-quietly interface %s\n/set-quietly style 12\n",
                          programVersion);
+                 if(appData.seekGraph && appData.autoRefresh) // [HGM] seekgraph
+                     strcat(str, "/set-2 51 1\n/set seek 1\n");
                } else if (ics_type == ICS_CHESSNET) {
                  sprintf(str, "/style 12\n");
                } else {
                  strcpy(str, "alias $ @\n$set interface ");
                  strcat(str, programVersion);
                  strcat(str, "\n$iset startpos 1\n$iset ms 1\n");
+                 if(appData.seekGraph && appData.autoRefresh) // [HGM] seekgraph
+                     strcat(str, "$iset seekremove 1\n$set seek 1\n");
  #ifdef WIN32
                  strcat(str, "$iset nohighlight 1\n");
  #endif
              continue;
            }
  
+           // [HGM] seekgraph: recognize sought lines and end-of-sought message
+           if(appData.seekGraph) {
+               if(soughtPending && MatchSoughtLine(buf+i)) {
+                   i = strstr(buf+i, "rated") - buf;
+                   next_out = leftover_start = i;
+                   started = STARTED_CHATTER;
+                   suppressKibitz = TRUE;
+                   continue;
+               }
+               if((gameMode == IcsIdle || gameMode == BeginningOfGame)
+                       && looking_at(buf, &i, "* ads displayed")) {
+                   soughtPending = FALSE;
+                   seekGraphUp = TRUE;
+                   DrawSeekGraph();
+                   continue;
+               }
+               if(appData.autoRefresh) {
+                   if(looking_at(buf, &i, "* (*) seeking * * * * *\"play *\" to respond)\n")) {
+                       int s = (ics_type == ICS_ICC); // ICC format differs
+                       if(seekGraphUp)
+                       AddAd(star_match[0], star_match[1], atoi(star_match[2+s]), atoi(star_match[3+s]), 
+                             star_match[4+s][0], star_match[5-3*s], atoi(star_match[7]), TRUE);
+                       looking_at(buf, &i, "*% "); // eat prompt
+                       next_out = i; // suppress
+                       continue;
+                   }
+                   if(looking_at(buf, &i, "Ads removed: *\n") || looking_at(buf, &i, "\031(51 * *\031)")) {
+                       char *p = star_match[0];
+                       while(*p) {
+                           if(seekGraphUp) RemoveSeekAd(atoi(p));
+                           while(*p && *p++ != ' '); // next
+                       }
+                       looking_at(buf, &i, "*% "); // eat prompt
+                       next_out = i;
+                       continue;
+                   }
+               }
+           }
            /* skip formula vars */
            if (started == STARTED_NONE &&
                buf[i] == 'f' && isdigit(buf[i+1]) && buf[i+2] == ':') {
  
            oldi = i;
            // [HGM] kibitz: try to recognize opponent engine-score kibitzes, to divert them to engine-output window
 -          if (appData.autoKibitz && started == STARTED_NONE && 
 +          if (appData.autoKibitz && started == STARTED_NONE &&
                  !appData.icsEngineAnalyze &&                     // [HGM] [DM] ICS analyze
                (gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack || gameMode == IcsObserving)) {
                if(looking_at(buf, &i, "* kibitzes: ") &&
 -                 (StrStr(star_match[0], gameInfo.white) == star_match[0] || 
 +                 (StrStr(star_match[0], gameInfo.white) == star_match[0] ||
                    StrStr(star_match[0], gameInfo.black) == star_match[0]   )) { // kibitz of self or opponent
                        suppressKibitz = TRUE;
                        if((StrStr(star_match[0], gameInfo.white) == star_match[0]
                            savingComment = TRUE;
                            suppressKibitz = gameMode != IcsObserving ? 2 :
                                (StrStr(star_match[0], gameInfo.white) == NULL) + 1;
 -                      } 
 +                      }
                        continue;
                } else
                if(looking_at(buf, &i, "kibitzed to *\n") && atoi(star_match[0])) {
                    // suppress the acknowledgements of our own autoKibitz
+                   char *p;
+                   if(p = strchr(star_match[0], ' ')) p[1] = NULLCHAR; // clip off "players)" on FICS
                    SendToPlayer(star_match[0], strlen(star_match[0]));
                    looking_at(buf, &i, "*% "); // eat prompt
                    next_out = i;
                if(channel >= 0) // channel broadcast; look if there is a chatbox for this channel
                for(p=0; p<MAX_CHAT; p++) {
                    if(channel == atoi(chatPartner[p])) {
-                   talker[0] = '['; strcat(talker, "]");
+                   talker[0] = '['; strcat(talker, "] ");
                    chattingPartner = p; break;
                    }
                } else
                if(buf[i-3] == 'r') // whisper; look if there is a WHISPER chatbox
                for(p=0; p<MAX_CHAT; p++) {
                    if(!strcmp("WHISPER", chatPartner[p])) {
-                       talker[0] = '['; strcat(talker, "]");
+                       talker[0] = '['; strcat(talker, "] ");
                        chattingPartner = p; break;
                    }
                }
                if(chattingPartner<0) i = oldi; else {
                    started = STARTED_COMMENT;
                    parse_pos = 0; parse[0] = NULLCHAR;
-                   savingComment = TRUE;
+                   savingComment = 3 + chattingPartner; // counts as TRUE
                    suppressKibitz = TRUE;
                }
            } // [HGM] chat: end of patch
                    memcpy(parse, &buf[oldi], parse_pos);
                    parse[parse_pos] = NULLCHAR;
                    started = STARTED_COMMENT;
+                   if(savingComment >= 3) // [HGM] chat: continuation of line for chat box
+                       chattingPartner = savingComment - 3; // kludge to remember the box
                } else {
                    started = STARTED_CHATTER;
                }
                SendToICS("refresh\n");
                continue;
            }
 -          
 +
            if (!have_sent_ICS_logon && looking_at(buf, &i, "login:")) {
                ICSInitScript();
                have_sent_ICS_logon = 1;
                continue;
            }
 -            
 -          if (ics_getting_history != H_GETTING_MOVES /*smpos kludge*/ && 
 +
 +          if (ics_getting_history != H_GETTING_MOVES /*smpos kludge*/ &&
                (looking_at(buf, &i, "\n<12> ") ||
                 looking_at(buf, &i, "<12> "))) {
                loggedOn = TRUE;
                    gameInfo.whiteRating = string_to_rating(star_match[1]);
                    gameInfo.blackRating = string_to_rating(star_match[3]);
                    if (appData.debugMode)
 -                    fprintf(debugFP, _("Ratings from header: W %d, B %d\n"), 
 +                    fprintf(debugFP, _("Ratings from header: W %d, B %d\n"),
                              gameInfo.whiteRating, gameInfo.blackRating);
                }
                continue;
                    break;
                }
                continue;
 -          }                           
 -          
 +          }
 +
            if (looking_at(buf, &i, "% ") ||
                ((started == STARTED_MOVES || started == STARTED_MOVES_NOHIDE)
                 && looking_at(buf, &i, "}*"))) { char *bookHit = NULL; // [HGM] book
+               if(ics_type == ICS_ICC && soughtPending) { // [HGM] seekgraph: on ICC sought-list has no termination line
+                   soughtPending = FALSE;
+                   seekGraphUp = TRUE;
+                   DrawSeekGraph();
+               }
                if(suppressKibitz) next_out = i;
                savingComment = FALSE;
                suppressKibitz = 0;
                            if (WhiteOnMove(forwardMostMove)) {
                                if (first.sendTime) {
                                  if (first.useColors) {
 -                                  SendToProgram("black\n", &first); 
 +                                  SendToProgram("black\n", &first);
                                  }
                                  SendTimeRemaining(&first, TRUE);
                                }
                                  firstMove = TRUE;
                                }
                            }
 -                      }                       
 +                      }
                    }
  #endif
                    if (gameMode == IcsObserving && ics_gamenum == -1) {
                if(bookHit) { // [HGM] book: simulate book reply
                    static char bookMove[MSG_SIZ]; // a bit generous?
  
 -                  programStats.nodes = programStats.depth = programStats.time = 
 +                  programStats.nodes = programStats.depth = programStats.time =
                    programStats.score = programStats.got_only_move = 0;
                    sprintf(programStats.movelist, "%s (xbook)", bookHit);
  
                }
                continue;
            }
 -          
 +
            if ((started == STARTED_MOVES || started == STARTED_BOARD ||
                 started == STARTED_HOLDINGS ||
                 started == STARTED_MOVES_NOHIDE) && i >= leftover_len) {
                /* Accumulate characters in move list or board */
                parse[parse_pos++] = buf[i];
            }
 -          
 +
            /* Start of game messages.  Mostly we detect start of game
               when the first board image arrives.  On some versions
               of the ICS, though, we need to do a "refresh" after starting
                player2Rating = string_to_rating(star_match[3]);
  
                if (appData.debugMode)
 -                fprintf(debugFP, 
 +                fprintf(debugFP,
                          "Ratings from 'Game notification:' %s %d, %s %d\n",
                          player1Name, player1Rating,
                          player2Name, player2Rating);
                    SendToICS("refresh\n");
                }
                continue;
 -          }    
 -          
 +          }
 +
            /* Error messages */
  //        if (ics_user_moved) {
            if (1) { // [HGM] old way ignored error after move type in; ics_user_moved is not set then!
                   2    empty, white, or black (IGNORED)
                   3    player 2 name (not necessarily black)
                   4    player 2 rating
 -                 
 +
                   The names/ratings are sorted out when the game
                   actually starts (below).
                */
                player2Rating = string_to_rating(star_match[4]);
  
                if (appData.debugMode)
 -                fprintf(debugFP, 
 +                fprintf(debugFP,
                          "Ratings from 'Creating:' %s %d, %s %d\n",
                          player1Name, player1Rating,
                          player2Name, player2Rating);
  
                continue;
            }
 -          
 +
            /* Improved generic start/end-of-game messages */
            if ((tkind=0, looking_at(buf, &i, "{Game * (* vs. *) *}*")) ||
                (tkind=1, looking_at(buf, &i, "{Game * (*(*) vs. *(*)) *}*"))){
                        ClearPremoveHighlights();
                        if (appData.debugMode)
                          fprintf(debugFP, "Sending premove:\n");
 -                          UserMoveEvent(premoveFromX, premoveFromY, 
 -                                      premoveToX, premoveToY, 
 +                          UserMoveEvent(premoveFromX, premoveFromY,
 +                                      premoveToX, premoveToY,
                                          premovePromoChar);
                      }
                    }
            SendToPlayer(&buf[next_out], leftover_start - next_out);
            next_out = i;
        }
 -      
 +
        leftover_len = buf_len - leftover_start;
        /* if buffer ends with something we couldn't parse,
           reparse it after appending the next read */
 -      
 +
      } else if (count == 0) {
        RemoveInputSource(isr);
          DisplayFatalError(_("Connection closed by ICS"), 0, 0);
  
  
  /* Board style 12 looks like this:
 -   
 +
     <12> r-b---k- pp----pp ---bP--- ---p---- q------- ------P- P--Q--BP -----R-K W -1 0 0 0 0 0 0 paf MaxII 0 2 12 21 25 234 174 24 Q/d7-a4 (0:06) Qxa4 0 0
 -   
 +
   * The "<12> " is stripped before it gets to this routine.  The two
   * trailing 0's (flip state and clock ticking) are later addition, and
   * some chess servers may not have them, or may have only the first.
 - * Additional trailing fields may be added in the future.  
 + * Additional trailing fields may be added in the future.
   */
  
  #define PATTERN "%c%d%d%d%d%d%d%d%s%s%d%d%d%d%d%d%d%d%s%s%s%d%d"
  void
  ParseBoard12(string)
       char *string;
 -{ 
 +{
      GameMode newGameMode;
      int gamenum, newGame, newMove, relation, basetime, increment, ics_flip = 0, i;
      int j, k, n, moveNum, white_stren, black_stren, white_time, black_time, takeback;
      Boolean weird = FALSE, reqFlag = FALSE;
  
      fromX = fromY = toX = toY = -1;
 -    
 +
      newGame = FALSE;
  
      if (appData.debugMode)
                        0, 1);
        return;
      }
 -    
 +
      switch (relation) {
        case RELATION_OBSERVING_PLAYED:
        case RELATION_OBSERVING_STATIC:
        case RELATION_ISOLATED_BOARD:
        default:
        /* Just display this board.  If user was doing something else,
 -         we will forget about it until the next board comes. */ 
 +         we will forget about it until the next board comes. */
        newGameMode = IcsIdle;
        break;
        case RELATION_STARTING_POSITION:
        newGameMode = gameMode;
        break;
      }
 -    
 +
      /* Modify behavior for initial board display on move listing
         of wild games.
         */
         different game than is currently being displayed.  */
      if (gamenum != ics_gamenum || newGameMode != gameMode ||
        relation == RELATION_ISOLATED_BOARD) {
 -      
 +
        /* Forget the old game and get the history (if any) of the new one */
        if (gameMode != BeginningOfGame) {
          Reset(TRUE, TRUE);
            sprintf(str, "%smoves %d\n", ics_prefix, gamenum);
            SendToICS(str);
        }
 -      
 +
        /* Initially flip the board to have black on the bottom if playing
           black or if the ICS flip flag is set, but let the user change
           it with the Flip View button. */
 -      flipView = appData.autoFlipView ? 
 +      flipView = appData.autoFlipView ?
          (newGameMode == IcsPlayingBlack) || ics_flip :
          appData.flipView;
 -      
 +
        /* Done with values from previous mode; copy in new ones */
        gameMode = newGameMode;
        ModeHighlight();
    }
  
          gameInfo.outOfBook = NULL;
 -      
 +
        /* Do we have the ratings? */
        if (strcmp(player1Name, white) == 0 &&
            strcmp(player2Name, black) == 0) {
            SendToICS("set shout 0\n");
        }
      }
 -    
 +
      /* Deal with midgame name changes */
      if (!newGame) {
        if (!gameInfo.white || strcmp(gameInfo.white, white) != 0) {
            gameInfo.black = StrSave(black);
        }
      }
 -    
 +
      /* Throw away game result if anything actually changes in examine mode */
      if (gameMode == IcsExamining && !newGame) {
        gameInfo.result = GameUnfinished;
            gameInfo.resultDetails = NULL;
        }
      }
 -    
 +
      /* In pausing && IcsExamining mode, we ignore boards coming
         in if they are in a different variation than we are. */
      if (pauseExamInvalid) return;
            return;
        }
      }
 -    
 +
    if (appData.debugMode) {
      fprintf(debugFP, "load %dx%d board\n", files, ranks);
    }
      /* [HGM] e.p. rights. Assume that ICS sends file number here? */
      boards[moveNum][EP_STATUS] = double_push == -1 ? EP_NONE : double_push + BOARD_LEFT;
  
 -    
 +
      if (ics_getting_history == H_GOT_REQ_HEADER ||
        ics_getting_history == H_GOT_UNREQ_HEADER) {
        /* This was an initial position from a move list, not
           the current position */
        return;
      }
 -    
 +
      /* Update currentMove and known move number limits */
      newMove = newGame || moveNum > forwardMostMove;
  
        if (!pausing || currentMove > forwardMostMove)
          currentMove = forwardMostMove;
      } else {
 -      /* New part of history that is not contiguous with old part */ 
 +      /* New part of history that is not contiguous with old part */
        if (pausing && gameMode == IcsExamining) {
            pauseExamInvalid = TRUE;
            forwardMostMove = pauseExamForwardMostMove;
        }
        forwardMostMove = backwardMostMove = currentMove = moveNum;
      }
 -    
 +
      /* Update the clocks */
      if (strchr(elapsed_time, '.')) {
        /* Time is in ms */
        timeRemaining[0][moveNum] = whiteTimeRemaining = white_time * 1000;
        timeRemaining[1][moveNum] = blackTimeRemaining = black_time * 1000;
      }
 -      
 +
  
  #if ZIPPY
      if (appData.zippyPlay && newGame &&
        gameMode != IcsExamining)
        ZippyFirstBoard(moveNum, basetime, increment);
  #endif
 -    
 +
      /* Put the move on the move list, first converting
         to canonical algebraic form. */
      if (moveNum > 0) {
            startedFromSetupPosition = TRUE;
            fromX = fromY = toX = toY = -1;
        } else {
 -        // [HGM] long SAN: if legality-testing is off, disambiguation might not work or give wrong move. 
 +        // [HGM] long SAN: if legality-testing is off, disambiguation might not work or give wrong move.
          //                 So we parse the long-algebraic move string in stead of the SAN move
          int valid; char buf[MSG_SIZ], *prom;
  
          // str looks something like "Q/a1-a2"; kill the slash
 -        if(str[1] == '/') 
 +        if(str[1] == '/')
                sprintf(buf, "%c%s", str[0], str+2);
          else  strcpy(buf, str); // might be castling
 -        if((prom = strstr(move_str, "=")) && !strstr(buf, "=")) 
 +        if((prom = strstr(move_str, "=")) && !strstr(buf, "="))
                strcat(buf, prom); // long move lacks promo specification!
          if(!appData.testLegality && move_str[1] != '@') { // drops never ambiguous (parser chokes on long form!)
 -              if(appData.debugMode) 
 +              if(appData.debugMode)
                        fprintf(debugFP, "replaced ICS move '%s' by '%s'\n", move_str, buf);
                strcpy(move_str, buf);
            }
  
  #if ZIPPY
        /* Send move to chess program (BEFORE animating it). */
 -      if (appData.zippyPlay && !newGame && newMove && 
 +      if (appData.zippyPlay && !newGame && newMove &&
           (!appData.getMoveList || backwardMostMove == 0) && first.initDone) {
  
            if ((gameMode == IcsPlayingWhite && WhiteOnMove(moveNum)) ||
            SetHighlights(fromX, fromY, toX, toY);
        }
      }
 -    
 +
      /* Start the clocks */
      whiteFlag = blackFlag = FALSE;
      appData.clockMode = !(basetime == 0 && increment == 0);
        DisplayBothClocks();
      else
        StartClocks();
 -    
 +
      /* Display opponents and material strengths */
      if (gameInfo.variant != VariantBughouse &&
        gameInfo.variant != VariantCrazyhouse && !appData.noGUI) {
        if (tinyLayout || smallLayout) {
            if(gameInfo.variant == VariantNormal)
 -              sprintf(str, "%s(%d) %s(%d) {%d %d}", 
 +              sprintf(str, "%s(%d) %s(%d) {%d %d}",
                    gameInfo.white, white_stren, gameInfo.black, black_stren,
                    basetime, increment);
            else
 -              sprintf(str, "%s(%d) %s(%d) {%d %d w%d}", 
 +              sprintf(str, "%s(%d) %s(%d) {%d %d w%d}",
                    gameInfo.white, white_stren, gameInfo.black, black_stren,
                    basetime, increment, (int) gameInfo.variant);
        } else {
            if(gameInfo.variant == VariantNormal)
 -              sprintf(str, "%s (%d) vs. %s (%d) {%d %d}", 
 +              sprintf(str, "%s (%d) vs. %s (%d) {%d %d}",
                    gameInfo.white, white_stren, gameInfo.black, black_stren,
                    basetime, increment);
            else
 -              sprintf(str, "%s (%d) vs. %s (%d) {%d %d %s}", 
 +              sprintf(str, "%s (%d) vs. %s (%d) {%d %d %s}",
                    gameInfo.white, white_stren, gameInfo.black, black_stren,
                    basetime, increment, VariantName(gameInfo.variant));
        }
  
      /* Display the board */
      if (!pausing && !appData.noGUI) {
 -      
        if (appData.premove)
 -        if (!gotPremove || 
 +        if (!gotPremove ||
             ((gameMode == IcsPlayingWhite) && (WhiteOnMove(currentMove))) ||
             ((gameMode == IcsPlayingBlack) && (!WhiteOnMove(currentMove))))
              ClearPremoveHighlights();
  
-       DrawPosition(FALSE, boards[currentMove]);
+       j = seekGraphUp; seekGraphUp = FALSE; // [HGM] seekgraph: when we draw a board, it overwrites the seek graph
+       DrawPosition(j, boards[currentMove]);
        DisplayMove(moveNum - 1);
        if (appData.ringBellAfterMoves && /*!ics_user_moved*/ // [HGM] use absolute method to recognize own move
            !((gameMode == IcsPlayingWhite) && (!WhiteOnMove(moveNum)) ||
      if(bookHit) { // [HGM] book: simulate book reply
        static char bookMove[MSG_SIZ]; // a bit generous?
  
 -      programStats.nodes = programStats.depth = programStats.time = 
 +      programStats.nodes = programStats.depth = programStats.time =
        programStats.score = programStats.got_only_move = 0;
        sprintf(programStats.movelist, "%s (xbook)", bookHit);
  
@@@ -4191,17 -4384,17 +4452,17 @@@ SendMoveToProgram(moveNum, cps
        AlphaRank(moveList[moveNum], 4); // and back
        } else
        /* Added by Tord: Send castle moves in "O-O" in FRC games if required by
 -       * the engine. It would be nice to have a better way to identify castle 
 +       * the engine. It would be nice to have a better way to identify castle
         * moves here. */
        if((gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom)
                                                                         && cps->useOOCastle) {
 -        int fromX = moveList[moveNum][0] - AAA; 
 +        int fromX = moveList[moveNum][0] - AAA;
          int fromY = moveList[moveNum][1] - ONE;
 -        int toX = moveList[moveNum][2] - AAA; 
 +        int toX = moveList[moveNum][2] - AAA;
          int toY = moveList[moveNum][3] - ONE;
 -        if((boards[moveNum][fromY][fromX] == WhiteKing 
 +        if((boards[moveNum][fromY][fromX] == WhiteKing
              && boards[moveNum][toY][toX] == WhiteRook)
 -           || (boards[moveNum][fromY][fromX] == BlackKing 
 +           || (boards[moveNum][fromY][fromX] == BlackKing
                 && boards[moveNum][toY][toX] == BlackRook)) {
          if(toX > fromX) SendToProgram("O-O\n", cps);
          else SendToProgram("O-O-O\n", cps);
@@@ -4351,7 -4544,7 +4612,7 @@@ AlphaRank(char *move, int n
          fprintf(debugFP, "alphaRank(%s,%d)\n", move, n);
      }
  
 -    if(move[1]=='*' && 
 +    if(move[1]=='*' &&
         move[2]>='0' && move[2]<='9' &&
         move[3]>='a' && move[3]<='x'    ) {
          move[1] = '@';
@@@ -4399,7 -4592,7 +4660,7 @@@ ParseOneMove(move, moveNum, moveType, f
       ChessMove *moveType;
       int *fromX, *fromY, *toX, *toY;
       char *promoChar;
 -{       
 +{
      if (appData.debugMode) {
          fprintf(debugFP, "move to parse: %s\n", move);
      }
@@@ -4625,7 -4818,7 +4886,7 @@@ int put(Board board, int pieceType, in
                        board[rank][i] = (ChessSquare) pieceType;
                        squaresLeft[((i-BOARD_LEFT)&1) + 1]--;
                        squaresLeft[ANY]--;
 -                      piecesLeft[pieceType]--; 
 +                      piecesLeft[pieceType]--;
                        return i;
                }
        }
@@@ -4753,7 -4946,7 +5014,7 @@@ int SetCharTable( char *table, const ch
  {
      int result = FALSE; int NrPieces;
  
 -    if( map != NULL && (NrPieces=strlen(map)) <= (int) EmptySquare 
 +    if( map != NULL && (NrPieces=strlen(map)) <= (int) EmptySquare
                      && NrPieces >= 12 && !(NrPieces&1)) {
          int i; /* [HGM] Accept even length from 12 to 34 */
  
  
  void Prelude(Board board)
  {     // [HGM] superchess: random selection of exo-pieces
 -      int i, j, k; ChessSquare p; 
 +      int i, j, k; ChessSquare p;
        static ChessSquare exoPieces[4] = { WhiteAngel, WhiteMarshall, WhiteSilver, WhiteLance };
  
        GetPositionNumber(); // use FRC position number
  
        if(appData.pieceToCharTable != NULL) { // select pieces to participate from given char table
            SetCharTable(pieceToChar, appData.pieceToCharTable);
 -          for(i=(int)WhiteQueen+1, j=0; i<(int)WhiteKing && j<4; i++) 
 +          for(i=(int)WhiteQueen+1, j=0; i<(int)WhiteKing && j<4; i++)
                if(PieceToChar((ChessSquare)i) != '.') exoPieces[j++] = (ChessSquare) i;
        }
  
 -      j = seed%4;                 seed /= 4; 
 +      j = seed%4;                 seed /= 4;
        p = board[0][BOARD_LEFT+j];   board[0][BOARD_LEFT+j] = EmptySquare; k = PieceToNumber(p);
        board[k][BOARD_WIDTH-1] = p;  board[k][BOARD_WIDTH-2]++;
        board[BOARD_HEIGHT-1-k][0] = WHITE_TO_BLACK p;  board[BOARD_HEIGHT-1-k][1]++;
 -      j = seed%3 + (seed%3 >= j); seed /= 3; 
 +      j = seed%3 + (seed%3 >= j); seed /= 3;
        p = board[0][BOARD_LEFT+j];   board[0][BOARD_LEFT+j] = EmptySquare; k = PieceToNumber(p);
        board[k][BOARD_WIDTH-1] = p;  board[k][BOARD_WIDTH-2]++;
        board[BOARD_HEIGHT-1-k][0] = WHITE_TO_BLACK p;  board[BOARD_HEIGHT-1-k][1]++;
 -      j = seed%3;                 seed /= 3; 
 +      j = seed%3;                 seed /= 3;
        p = board[0][BOARD_LEFT+j+5]; board[0][BOARD_LEFT+j+5] = EmptySquare; k = PieceToNumber(p);
        board[k][BOARD_WIDTH-1] = p;  board[k][BOARD_WIDTH-2]++;
        board[BOARD_HEIGHT-1-k][0] = WHITE_TO_BLACK p;  board[BOARD_HEIGHT-1-k][1]++;
 -      j = seed%2 + (seed%2 >= j); seed /= 2; 
 +      j = seed%2 + (seed%2 >= j); seed /= 2;
        p = board[0][BOARD_LEFT+j+5]; board[0][BOARD_LEFT+j+5] = EmptySquare; k = PieceToNumber(p);
        board[k][BOARD_WIDTH-1] = p;  board[k][BOARD_WIDTH-2]++;
        board[BOARD_HEIGHT-1-k][0] = WHITE_TO_BLACK p;  board[BOARD_HEIGHT-1-k][1]++;
@@@ -4834,7 -5027,7 +5095,7 @@@ InitPosition(redraw
          castlingRank[3] = castlingRank[4] = castlingRank[5] = BOARD_HEIGHT-1;
      }
  
 -    
 +
      /* [HGM] logic here is completely changed. In stead of full positions */
      /* the initialized data only consist of the two backranks. The switch */
      /* selects which one we will use, which is than copied to the Board   */
      case VariantShatranj:
        pieces = ShatranjArray;
        nrCastlingRights = 0;
 -      SetCharTable(pieceToChar, "PN.R.QB...Kpn.r.qb...k"); 
 +      SetCharTable(pieceToChar, "PN.R.QB...Kpn.r.qb...k");
        break;
      case VariantMakruk:
        pieces = makrukArray;
      case VariantCapablanca:
        pieces = CapablancaArray;
        gameInfo.boardWidth = 10;
 -      SetCharTable(pieceToChar, "PNBRQ..ACKpnbrq..ack"); 
 +      SetCharTable(pieceToChar, "PNBRQ..ACKpnbrq..ack");
        break;
      case VariantGothic:
        pieces = GothicArray;
        gameInfo.boardWidth = 10;
 -      SetCharTable(pieceToChar, "PNBRQ..ACKpnbrq..ack"); 
 +      SetCharTable(pieceToChar, "PNBRQ..ACKpnbrq..ack");
        break;
      case VariantJanus:
        pieces = JanusArray;
        gameInfo.boardWidth = 10;
 -      SetCharTable(pieceToChar, "PNBRQ..JKpnbrq..jk"); 
 +      SetCharTable(pieceToChar, "PNBRQ..JKpnbrq..jk");
        nrCastlingRights = 6;
          initialPosition[CASTLING][0] = initialRights[0] = BOARD_RGHT-1;
          initialPosition[CASTLING][1] = initialRights[1] = BOARD_LEFT;
      case VariantFalcon:
        pieces = FalconArray;
        gameInfo.boardWidth = 10;
 -      SetCharTable(pieceToChar, "PNBRQ.............FKpnbrq.............fk"); 
 +      SetCharTable(pieceToChar, "PNBRQ.............FKpnbrq.............fk");
        break;
      case VariantXiangqi:
        pieces = XiangqiArray;
        gameInfo.boardWidth  = 9;
        gameInfo.boardHeight = 10;
        nrCastlingRights = 0;
 -      SetCharTable(pieceToChar, "PH.R.AE..K.C.ph.r.ae..k.c."); 
 +      SetCharTable(pieceToChar, "PH.R.AE..K.C.ph.r.ae..k.c.");
        break;
      case VariantShogi:
        pieces = ShogiArray;
        gameInfo.boardHeight = 9;
        gameInfo.holdingsSize = 7;
        nrCastlingRights = 0;
 -      SetCharTable(pieceToChar, "PNBRLS...G.++++++Kpnbrls...g.++++++k"); 
 +      SetCharTable(pieceToChar, "PNBRLS...G.++++++Kpnbrls...g.++++++k");
        break;
      case VariantCourier:
        pieces = CourierArray;
        break;
      case VariantKnightmate:
        pieces = KnightmateArray;
 -      SetCharTable(pieceToChar, "P.BRQ.....M.........K.p.brq.....m.........k."); 
 +      SetCharTable(pieceToChar, "P.BRQ.....M.........K.p.brq.....m.........k.");
        break;
      case VariantFairy:
        pieces = fairyArray;
      case VariantCrazyhouse:
      case VariantBughouse:
        pieces = FIDEArray;
 -      SetCharTable(pieceToChar, "PNBRQ.......~~~~Kpnbrq.......~~~~k"); 
 +      SetCharTable(pieceToChar, "PNBRQ.......~~~~Kpnbrq.......~~~~k");
        gameInfo.holdingsSize = 5;
        break;
      case VariantWildCastle:
          initialPosition[BOARD_HEIGHT-pawnRow-1][j] = BlackPawn;
          if(gameInfo.variant == VariantXiangqi) {
              if(j&1) {
 -                initialPosition[pawnRow][j] = 
 +                initialPosition[pawnRow][j] =
                  initialPosition[BOARD_HEIGHT-pawnRow-1][j] = EmptySquare;
                  if(j==BOARD_LEFT+1 || j>=BOARD_RGHT-2) {
                     initialPosition[2][j] = WhiteCannon;
          /*       This sets default castling rights from none to normal corners   */
          /* Variants with other castling rights must set them themselves above    */
          nrCastlingRights = 6;
 -       
          initialPosition[CASTLING][0] = initialRights[0] = BOARD_RGHT-1;
          initialPosition[CASTLING][1] = initialRights[1] = BOARD_LEFT;
          initialPosition[CASTLING][2] = initialRights[2] = BOARD_WIDTH>>1;
      }
  
      CopyBoard(boards[0], initialPosition);
 -
      if(oldx != gameInfo.boardWidth ||
         oldy != gameInfo.boardHeight ||
         oldh != gameInfo.holdingsWidth
         gameInfo.variant == VariantFalcon
  #endif
                                           )
 +      {
              InitDrawingSizes(-2 ,0);
 +      }
  
      if (redraw)
        DrawPosition(TRUE, boards[currentMove]);
 +
  }
  
  void
@@@ -5082,7 -5274,7 +5343,7 @@@ SendBoard(cps, moveNum
       int moveNum;
  {
      char message[MSG_SIZ];
 -    
 +
      if (cps->useSetboard) {
        char* fen = PositionToFEN(moveNum, cps->fenOverride);
        sprintf(message, "setboard %s\n", fen);
        bp = &boards[moveNum][i][BOARD_LEFT];
          for (j = BOARD_LEFT; j < BOARD_RGHT; j++, bp++) {
          if ((int) *bp < (int) BlackPawn) {
 -          sprintf(message, "%c%c%c\n", PieceToChar(*bp), 
 +          sprintf(message, "%c%c%c\n", PieceToChar(*bp),
                      AAA + j, ONE + i);
              if(message[0] == '+' || message[0] == '~') {
                  sprintf(message, "%c%c%c+\n",
          }
        }
        }
 -    
 +
        SendToProgram("c\n", cps);
        for (i = BOARD_HEIGHT - 1; i >= 0; i--) {
        bp = &boards[moveNum][i][BOARD_LEFT];
          }
        }
        }
 -    
 +
        SendToProgram(".\n", cps);
      }
      setboardSpoiledMachineBlack = 0; /* [HGM] assume WB 4.2.7 already solves this after sending setboard */
@@@ -5311,11 -5503,11 +5572,11 @@@ OKToStartUserMove(x, y
        if (!white_piece && WhiteOnMove(currentMove)) {
            DisplayMoveError(_("It is White's turn"));
            return FALSE;
 -      }           
 +      }
        if (white_piece && !WhiteOnMove(currentMove)) {
            DisplayMoveError(_("It is Black's turn"));
            return FALSE;
 -      }           
 +      }
        if (cmailMsgLoaded && (currentMove < cmailOldMove)) {
            /* Editing correspondence game history */
            /* Could disallow this or prompt for confirmation */
            }
        }
        break;
 -      
 +
        case Training:
        if (!white_piece && WhiteOnMove(currentMove)) {
            DisplayMoveError(_("It is White's turn"));
            return FALSE;
 -      }           
 +      }
        if (white_piece && !WhiteOnMove(currentMove)) {
            DisplayMoveError(_("It is Black's turn"));
            return FALSE;
 -      }           
 +      }
        break;
  
        default:
      return TRUE;
  }
  
+ Boolean
+ OnlyMove(int *x, int *y) {
+     DisambiguateClosure cl;
+     if (appData.zippyPlay) return FALSE;
+     switch(gameMode) {
+       case MachinePlaysBlack:
+       case IcsPlayingWhite:
+       case BeginningOfGame:
+       if(!WhiteOnMove(currentMove)) return FALSE;
+       break;
+       case MachinePlaysWhite:
+       case IcsPlayingBlack:
+       if(WhiteOnMove(currentMove)) return FALSE;
+       break;
+       default:
+       return FALSE;
+     }
+     cl.pieceIn = EmptySquare; 
+     cl.rfIn = *y;
+     cl.ffIn = *x;
+     cl.rtIn = -1;
+     cl.ftIn = -1;
+     cl.promoCharIn = NULLCHAR;
+     Disambiguate(boards[currentMove], PosFlags(currentMove), &cl);
+     if(cl.kind == NormalMove) {
+       fromX = cl.ff;
+       fromY = cl.rf;
+       *x = cl.ft;
+       *y = cl.rt;
+       return TRUE;
+     }
+     if(cl.kind != ImpossibleMove) return FALSE;
+     cl.pieceIn = EmptySquare;
+     cl.rfIn = -1;
+     cl.ffIn = -1;
+     cl.rtIn = *y;
+     cl.ftIn = *x;
+     cl.promoCharIn = NULLCHAR;
+     Disambiguate(boards[currentMove], PosFlags(currentMove), &cl);
+     if(cl.kind == NormalMove) {
+       fromX = cl.ff;
+       fromY = cl.rf;
+       *x = cl.ft;
+       *y = cl.rt;
+       return TRUE;
+     }
+     return FALSE;
+ }
  FILE *lastLoadGameFP = NULL, *lastLoadPositionFP = NULL;
  int lastLoadGameNumber = 0, lastLoadPositionNumber = 0;
  int lastLoadGameUseList = FALSE;
@@@ -5443,7 -5684,7 +5753,7 @@@ UserMoveTest(fromX, fromY, toX, toY, pr
                premoveFromY = fromY;
                premovePromoChar = promoChar;
                gotPremove = 1;
 -              if (appData.debugMode) 
 +              if (appData.debugMode)
                    fprintf(debugFP, "Got premove: fromX %d,"
                            "fromY %d, toX %d, toY %d\n",
                            fromX, fromY, toX, toY);
                premoveFromY = fromY;
                premovePromoChar = promoChar;
                gotPremove = 1;
 -              if (appData.debugMode) 
 +              if (appData.debugMode)
                    fprintf(debugFP, "Got premove: fromX %d,"
                            "fromY %d, toX %d, toY %d\n",
                            fromX, fromY, toX, toY);
      pup = boards[currentMove][toY][toX];
  
      /* [HGM] If move started in holdings, it means a drop */
 -    if( fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) { 
 +    if( fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) {
           if( pup != EmptySquare ) return ImpossibleMove;
           if(appData.testLegality) {
               /* it would be more logical if LegalityTest() also figured out
           return WhiteDrop; /* Not needed to specify white or black yet */
      }
  
-     userOfferedDraw = FALSE;
 +
      /* [HGM] always test for legality, to get promotion info */
      moveType = LegalityTest(boards[currentMove], PosFlags(currentMove),
                                           fromY, fromX, toY, toX, promoChar);
@@@ -5551,55 -5790,42 +5860,55 @@@ FinishMove(moveType, fromX, fromY, toX
       int fromX, fromY, toX, toY;
       /*char*/int promoChar;
  {
 -    char *bookHit = 0;
 +  char *bookHit = 0;
  
 -    if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) && promoChar != NULLCHAR) { 
 -      // [HGM] superchess: suppress promotions to non-available piece
 -      int k = PieceToNumber(CharToPiece(ToUpper(promoChar)));
 -      if(WhiteOnMove(currentMove)) {
 -          if(!boards[currentMove][k][BOARD_WIDTH-2]) return 0;
 -      } else {
 -          if(!boards[currentMove][BOARD_HEIGHT-1-k][1]) return 0;
 +  if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) && promoChar != NULLCHAR)
 +    {
 +      // [HGM] superchess: suppress promotions to non-available piece
 +      int k = PieceToNumber(CharToPiece(ToUpper(promoChar)));
 +      if(WhiteOnMove(currentMove))
 +      {
 +        if(!boards[currentMove][k][BOARD_WIDTH-2])
 +          return 0;
 +      }
 +      else
 +      {
 +        if(!boards[currentMove][BOARD_HEIGHT-1-k][1])
 +          return 0;
        }
      }
 -
 -    /* [HGM] <popupFix> kludge to avoid having to know the exact promotion
 -       move type in caller when we know the move is a legal promotion */
 -    if(moveType == NormalMove && promoChar)
 -        moveType = PromoCharToMoveType(WhiteOnMove(currentMove), promoChar);
 -
 -    /* [HGM] convert drag-and-drop piece drops to standard form */
 -    if( (fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) && fromY != DROP_RANK ){
 -         moveType = WhiteOnMove(currentMove) ? WhiteDrop : BlackDrop;
 -         if(appData.debugMode) fprintf(debugFP, "Drop move %d, curr=%d, x=%d,y=%d, p=%d\n", 
 -              moveType, currentMove, fromX, fromY, boards[currentMove][fromY][fromX]);
 -         // holdings might not be sent yet in ICS play; we have to figure out which piece belongs here
 -         if(fromX == 0) fromY = BOARD_HEIGHT-1 - fromY; // black holdings upside-down
 -         fromX = fromX ? WhitePawn : BlackPawn; // first piece type in selected holdings
 -         while(PieceToChar(fromX) == '.' || PieceToNumber(fromX) != fromY && fromX != (int) EmptySquare) fromX++; 
 -         fromY = DROP_RANK;
 +  
 +  /* [HGM] <popupFix> kludge to avoid having to know the exact promotion
 +     move type in caller when we know the move is a legal promotion */
 +  if(moveType == NormalMove && promoChar)
 +    moveType = PromoCharToMoveType(WhiteOnMove(currentMove), promoChar);
 +  
 +  /* [HGM] <popupFix> kludge to avoid having to know the exact promotion
 +     move type in caller when we know the move is a legal promotion */
 +  if(moveType == NormalMove && promoChar)
 +    moveType = PromoCharToMoveType(WhiteOnMove(currentMove), promoChar);
 +  
 +  /* [HGM] convert drag-and-drop piece drops to standard form */
 +  if( (fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) && fromY != DROP_RANK )
 +    {
 +      moveType = WhiteOnMove(currentMove) ? WhiteDrop : BlackDrop;
 +      if(appData.debugMode) fprintf(debugFP, "Drop move %d, curr=%d, x=%d,y=%d, p=%d\n", 
 +                                  moveType, currentMove, fromX, fromY, boards[currentMove][fromY][fromX]);
 +      // holdings might not be sent yet in ICS play; we have to figure out which piece belongs here
 +      if(fromX == 0) fromY = BOARD_HEIGHT-1 - fromY; // black holdings upside-down
 +      fromX = fromX ? WhitePawn : BlackPawn; // first piece type in selected holdings
 +      while(PieceToChar(fromX) == '.' || PieceToNumber(fromX) != fromY && fromX != (int) EmptySquare) fromX++; 
 +      fromY = DROP_RANK;
      }
 -
 -    /* [HGM] <popupFix> The following if has been moved here from
 -       UserMoveEvent(). Because it seemed to belong here (why not allow
 -       piece drops in training games?), and because it can only be
 -       performed after it is known to what we promote. */
 -    if (gameMode == Training) {
 +  
 +  /* [HGM] <popupFix> The following if has been moved here from
 +     UserMoveEvent(). Because it seemed to belong here (why not allow
 +     piece drops in training games?), and because it can only be
 +     performed after it is known to what we promote. */
 +  if (gameMode == Training) 
 +    {
        /* compare the move played on the board to the next move in the
 -       * game. If they match, display the move and the opponent's response. 
 +       * game. If they match, display the move and the opponent's response.
         * If they don't match, display an error message.
         */
        int saveAnimate;
        CopyBoard(testBoard, boards[currentMove]);
        ApplyMove(fromX, fromY, toX, toY, promoChar, testBoard);
  
 -      if (CompareBoards(testBoard, boards[currentMove+1])) {
 -      ForwardInner(currentMove+1);
 +      if (CompareBoards(testBoard, boards[currentMove+1]))
 +      {
 +        ForwardInner(currentMove+1);
  
 -      /* Autoplay the opponent's response.
 -       * if appData.animate was TRUE when Training mode was entered,
 -       * the response will be animated.
 -       */
 -      saveAnimate = appData.animate;
 -      appData.animate = animateTraining;
 -      ForwardInner(currentMove+1);
 -      appData.animate = saveAnimate;
 -
 -      /* check for the end of the game */
 -      if (currentMove >= forwardMostMove) {
 -        gameMode = PlayFromGameFile;
 -        ModeHighlight();
 -        SetTrainingModeOff();
 -        DisplayInformation(_("End of game"));
 +        /* Autoplay the opponent's response.
 +         * if appData.animate was TRUE when Training mode was entered,
 +         * the response will be animated.
 +         */
 +        saveAnimate = appData.animate;
 +        appData.animate = animateTraining;
 +        ForwardInner(currentMove+1);
 +        appData.animate = saveAnimate;
 +
 +        /* check for the end of the game */
 +        if (currentMove >= forwardMostMove)
 +          {
 +            gameMode = PlayFromGameFile;
 +            ModeHighlight();
 +            SetTrainingModeOff();
 +            DisplayInformation(_("End of game"));
 +          }
 +      }
 +      else
 +      {
 +        DisplayError(_("Incorrect move"), 0);
        }
 -      } else {
 -      DisplayError(_("Incorrect move"), 0);
 -      }
        return 1;
      }
  
  
    MakeMove(fromX, fromY, toX, toY, promoChar); /*updates forwardMostMove*/
  
-   if (gameMode == BeginningOfGame)
 -  if(Adjudicate(NULL)) return 1; // [HGM] adjudicate: take care of automtic game end
 -  if (gameMode == BeginningOfGame) {
 -    if (appData.noChessProgram) {
 -      gameMode = EditGame;
 -      SetGameInfo();
 -    } else {
 -      char buf[MSG_SIZ];
 -      gameMode = MachinePlaysBlack;
 -      StartClocks();
 -      SetGameInfo();
 -      sprintf(buf, "%s vs. %s", gameInfo.white, gameInfo.black);
 -      DisplayTitle(buf);
 -      if (first.sendName) {
 -      sprintf(buf, "name %s\n", gameInfo.white);
 -      SendToProgram(buf, &first);
 -      }
 -      StartClocks();
++ if(Adjudicate(NULL)) return 1; // [HGM] adjudicate: take care of automtic game end
++
++if (gameMode == BeginningOfGame)
 +    {
 +      if (appData.noChessProgram)
 +      {
 +        gameMode = EditGame;
 +        SetGameInfo();
 +      }
 +      else
 +      {
 +        char buf[MSG_SIZ];
 +        gameMode = MachinePlaysBlack;
 +        StartClocks();
 +        SetGameInfo();
 +        sprintf(buf, "%s vs. %s", gameInfo.white, gameInfo.black);
 +        DisplayTitle(buf);
 +        if (first.sendName)
 +          {
 +            sprintf(buf, "name %s\n", gameInfo.white);
 +            SendToProgram(buf, &first);
 +          }
 +        StartClocks();
 +      }
 +      ModeHighlight();
++
      }
 -    ModeHighlight();
 -  }
  
    /* Relay move to ICS or chess engine */
-   if (appData.icsActive)
-     {
-       if (gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack ||
-         gameMode == IcsExamining)
-       {
-         SendMoveToICS(moveType, fromX, fromY, toX, toY);
-         ics_user_moved = 1;
-       }
++
+   if (appData.icsActive) {
+     if (gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack ||
+       gameMode == IcsExamining) {
+       if(userOfferedDraw && (signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) {
+         SendToICS(ics_prefix); // [HGM] drawclaim: send caim and move on one line for FICS
+       SendToICS("draw ");
+         SendMoveToICS(moveType, fromX, fromY, toX, toY);
+       }
+       // also send plain move, in case ICS does not understand atomic claims
+       SendMoveToICS(moveType, fromX, fromY, toX, toY);
+       ics_user_moved = 1;
+     }
+   } else {
+     if (first.sendTime && (gameMode == BeginningOfGame ||
+                          gameMode == MachinePlaysWhite ||
+                          gameMode == MachinePlaysBlack)) {
+       SendTimeRemaining(&first, gameMode != MachinePlaysBlack);
+     }
+     if (gameMode != EditGame && gameMode != PlayFromGameFile) {
+        // [HGM] book: if program might be playing, let it use book
+       bookHit = SendMoveToBookUser(forwardMostMove-1, &first, FALSE);
+       first.maybeThinking = TRUE;
+     } else SendMoveToProgram(forwardMostMove-1, &first);
+     if (currentMove == cmailOldMove + 1) {
+       cmailMoveType[lastLoadGameNumber - 1] = CMAIL_MOVE;
      }
-   else
-     {
-       if (first.sendTime && (gameMode == BeginningOfGame ||
-                            gameMode == MachinePlaysWhite ||
-                            gameMode == MachinePlaysBlack))
-       {
-         SendTimeRemaining(&first, gameMode != MachinePlaysBlack);
-       }
-       if (gameMode != EditGame && gameMode != PlayFromGameFile)
-       {
-         // [HGM] book: if program might be playing, let it use book
-         bookHit = SendMoveToBookUser(forwardMostMove-1, &first, FALSE);
-         first.maybeThinking = TRUE;
-       }
-       else
-       SendMoveToProgram(forwardMostMove-1, &first);
-       if (currentMove == cmailOldMove + 1)
-       {
-         cmailMoveType[lastLoadGameNumber - 1] = CMAIL_MOVE;
-       }
 -  }
 +    }
  
    ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
  
 -  switch (gameMode) {
 -  case EditGame:
 -    switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) {
 -    case MT_NONE:
 -    case MT_CHECK:
 +  switch (gameMode) 
 +    {
 +    case EditGame:
 +      switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) 
 +      {
 +      case MT_NONE:
 +      case MT_CHECK:
 +        break;
 +      case MT_CHECKMATE:
 +      case MT_STAINMATE:
 +        if (WhiteOnMove(currentMove)) {
 +          GameEnds(BlackWins, "Black mates", GE_PLAYER);
 +        } else {
 +          GameEnds(WhiteWins, "White mates", GE_PLAYER);
 +        }
 +        break;
 +      case MT_STALEMATE:
 +        GameEnds(GameIsDrawn, "Stalemate", GE_PLAYER);
 +        break;
 +      }
        break;
 -    case MT_CHECKMATE:
 -    case MT_STAINMATE:
 -      if (WhiteOnMove(currentMove)) {
 -      GameEnds(BlackWins, "Black mates", GE_PLAYER);
 -      } else {
 -      GameEnds(WhiteWins, "White mates", GE_PLAYER);
 -      }
 +      
 +    case MachinePlaysBlack:
 +    case MachinePlaysWhite:
 +      /* disable certain menu options while machine is thinking */
 +      SetMachineThinkingEnables();
        break;
 -    case MT_STALEMATE:
 -      GameEnds(GameIsDrawn, "Stalemate", GE_PLAYER);
 +      
 +    default:
        break;
      }
-   
 -    break;
 -    
 -  case MachinePlaysBlack:
 -  case MachinePlaysWhite:
 -    /* disable certain menu options while machine is thinking */
 -    SetMachineThinkingEnables();
 -    break;
 -
 -  default:
 -    break;
 -  }
 -
+   userOfferedDraw = FALSE; // [HGM] drawclaim: after move made, and tested for claimable draw
+       
 -  if(bookHit) { // [HGM] book: simulate book reply
 +  if(bookHit)
 +    { // [HGM] book: simulate book reply
-       static char bookMove[MSG_SIZ]; // a bit generous?
+       static char bookMove[MSG_SIZ]; // a bit generous?
 -      programStats.nodes = programStats.depth = programStats.time = 
 +
 +      programStats.nodes = programStats.depth = programStats.time =
        programStats.score = programStats.got_only_move = 0;
 -      sprintf(programStats.movelist, "%s (xbook)", bookHit);
 +      sprintf(programStats.movelist, "%s (xbook)", bookHit);
 +
 +      strcpy(bookMove, "move ");
 +      strcat(bookMove, bookHit);
 +      HandleMachineMove(bookMove, &first);
 +    }
  
 -      strcpy(bookMove, "move ");
 -      strcat(bookMove, bookHit);
 -      HandleMachineMove(bookMove, &first);
 -  }
    return 1;
  }
  
@@@ -5773,14 -5987,14 +6086,14 @@@ UserMoveEvent(fromX, fromY, toX, toY, p
         slip a promotion popup in between. But that it always needs two
         calls, to the first part, (now called UserMoveTest() ), and to
         FinishMove if the first part succeeded. Calls that do not need
 -       to do anything in between, can call this routine the old way. 
 +       to do anything in between, can call this routine the old way.
      */
 -    ChessMove moveType = UserMoveTest(fromX, fromY, toX, toY, promoChar, FALSE);
 -if(appData.debugMode) fprintf(debugFP, "moveType 4 = %d, promochar = %x\n", moveType, promoChar);
 -    if(moveType == AmbiguousMove)
 -      DrawPosition(FALSE, boards[currentMove]);
 -    else if(moveType != ImpossibleMove && moveType != Comment)
 -        FinishMove(moveType, fromX, fromY, toX, toY, promoChar);
 +  ChessMove moveType = UserMoveTest(fromX, fromY, toX, toY, promoChar, FALSE);
 +  if(appData.debugMode) fprintf(debugFP, "moveType 4 = %d, promochar = %x\n", moveType, promoChar);
 +  if(moveType == AmbiguousMove)
 +    DrawPosition(FALSE, boards[currentMove]);
 +  else if(moveType != ImpossibleMove && moveType != Comment)
 +    FinishMove(moveType, fromX, fromY, toX, toY, promoChar);
  }
  
  void
@@@ -5827,6 -6041,12 +6140,12 @@@ void LeftClick(ClickType clickType, in
      static int second = 0, promotionChoice = 0;
      char promoChoice = NULLCHAR;
  
+     if(appData.seekGraph && appData.icsActive && loggedOn &&
+       (gameMode == BeginningOfGame || gameMode == IcsIdle)) {
+       SeekGraphClick(clickType, xPix, yPix, 0);
+       return;
+     }
      if (clickType == Press) ErrorPopDown();
      MarkTargetSquares(1);
  
        return;
  
      if (fromX == -1) {
+       if(!appData.oneClick || !OnlyMove(&x, &y)) {
        if (clickType == Press) {
            /* First square */
            if (OKToStartUserMove(x, y)) {
            }
        }
        return;
+       }
      }
  
      /* fromX != -1 */
             
            if(x == BOARD_LEFT-2 && piece >= BlackPawn) {
                n = PieceToNumber(piece - (int)BlackPawn);
-               if(n > gameInfo.holdingsSize) { n = 0; piece = BlackPawn; }
+               if(n >= gameInfo.holdingsSize) { n = 0; piece = BlackPawn; }
                boards[currentMove][BOARD_HEIGHT-1 - n][0] = piece;
                boards[currentMove][BOARD_HEIGHT-1 - n][1]++;
            } else
            if(x == BOARD_RGHT+1 && piece < BlackPawn) {
                n = PieceToNumber(piece);
-               if(n > gameInfo.holdingsSize) { n = 0; piece = WhitePawn; }
+               if(n >= gameInfo.holdingsSize) { n = 0; piece = WhitePawn; }
                boards[currentMove][n][BOARD_WIDTH-1] = piece;
                boards[currentMove][n][BOARD_WIDTH-2]++;
            }
      }
  }
  
+ int RightClick(ClickType action, int x, int y, int *fromX, int *fromY)
+ {   // front-end-free part taken out of PieceMenuPopup
+     int whichMenu; int xSqr, ySqr;
+     if(seekGraphUp) { // [HGM] seekgraph
+       if(action == Press)   SeekGraphClick(Press, x, y, 2); // 2 indicates right-click: no pop-down on miss
+       if(action == Release) SeekGraphClick(Release, x, y, 2); // and no challenge on hit
+       return -2;
+     }
+     xSqr = EventToSquare(x, BOARD_WIDTH);
+     ySqr = EventToSquare(y, BOARD_HEIGHT);
+     if (action == Release) UnLoadPV(); // [HGM] pv
+     if (action != Press) return -2; // return code to be ignored
+     switch (gameMode) {
+       case IcsExamining:
 -      if(xSqr < BOARD_LEFT || xSqr >= BOARD_RGHT) return -1;\r
++      if(xSqr < BOARD_LEFT || xSqr >= BOARD_RGHT) return -1;
+       case EditPosition:
 -      if (xSqr == BOARD_LEFT-1 || xSqr == BOARD_RGHT) return -1;\r
 -      if (xSqr < 0 || ySqr < 0) return -1;\r
++      if (xSqr == BOARD_LEFT-1 || xSqr == BOARD_RGHT) return -1;
++      if (xSqr < 0 || ySqr < 0) return -1;
+       whichMenu = 0; // edit-position menu
+       break;
+       case IcsObserving:
+       if(!appData.icsEngineAnalyze) return -1;
+       case IcsPlayingWhite:
+       case IcsPlayingBlack:
+       if(!appData.zippyPlay) goto noZip;
+       case AnalyzeMode:
+       case AnalyzeFile:
+       case MachinePlaysWhite:
+       case MachinePlaysBlack:
+       case TwoMachinesPlay: // [HGM] pv: use for showing PV
+       if (!appData.dropMenu) {
+         LoadPV(x, y);
+         return 2; // flag front-end to grab mouse events
+       }
+       if(gameMode == TwoMachinesPlay || gameMode == AnalyzeMode ||
+            gameMode == AnalyzeFile || gameMode == IcsObserving) return -1;
+       case EditGame:
+       noZip:
+       if (xSqr < 0 || ySqr < 0) return -1;
+       if (!appData.dropMenu || appData.testLegality &&
+           gameInfo.variant != VariantBughouse &&
+           gameInfo.variant != VariantCrazyhouse) return -1;
+       whichMenu = 1; // drop menu
+       break;
+       default:
+       return -1;
+     }
+     if (((*fromX = xSqr) < 0) ||
+       ((*fromY = ySqr) < 0)) {
+       *fromX = *fromY = -1;
+       return -1;
+     }
+     if (flipView)
+       *fromX = BOARD_WIDTH - 1 - *fromX;
+     else
+       *fromY = BOARD_HEIGHT - 1 - *fromY;
+     return whichMenu;
+ }
  void SendProgramStatsToFrontend( ChessProgramState * cps, ChessProgramStats * cpstats )
  {
  //    char * hint = lastHint;
      SetProgramStats( &stats );
  }
  
+ int
+ Adjudicate(ChessProgramState *cps)
+ {     // [HGM] some adjudications useful with buggy engines
+       // [HGM] adjudicate: made into separate routine, which now can be called after every move
+       //       In any case it determnes if the game is a claimable draw (filling in EP_STATUS).
+       //       Actually ending the game is now based on the additional internal condition canAdjudicate.
+       //       Only when the game is ended, and the opponent is a computer, this opponent gets the move relayed.
+       int k, count = 0; static int bare = 1;
+       ChessProgramState *engineOpponent = (gameMode == TwoMachinesPlay ? cps->other : (cps ? NULL : &first));
+       Boolean canAdjudicate = !appData.icsActive;
+       // most tests only when we understand the game, i.e. legality-checking on, and (for the time being) no piece drops
+       if(gameInfo.holdingsSize == 0 || gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) {
+           if( appData.testLegality )
+           {   /* [HGM] Some more adjudications for obstinate engines */
+               int NrWN=0, NrBN=0, NrWB=0, NrBB=0, NrWR=0, NrBR=0,
+                     NrWQ=0, NrBQ=0, NrW=0, NrK=0, bishopsColor = 0,
+                     NrPieces=0, NrPawns=0, PawnAdvance=0, i, j;
+               static int moveCount = 6;
+               ChessMove result;
+               char *reason = NULL;
++
+                 /* Count what is on board. */
+               for(i=0; i<BOARD_HEIGHT; i++) for(j=BOARD_LEFT; j<BOARD_RGHT; j++)
+               {   ChessSquare p = boards[forwardMostMove][i][j];
+                   int m=i;
+                   switch((int) p)
+                   {   /* count B,N,R and other of each side */
+                         case WhiteKing:
+                         case BlackKing:
+                            NrK++; break; // [HGM] atomic: count Kings
+                         case WhiteKnight:
+                              NrWN++; break;
+                         case WhiteBishop:
+                         case WhiteFerz:    // [HGM] shatranj: kludge to mke it work in shatranj
+                              bishopsColor |= 1 << ((i^j)&1);
+                              NrWB++; break;
+                         case BlackKnight:
+                              NrBN++; break;
+                         case BlackBishop:
+                         case BlackFerz:    // [HGM] shatranj: kludge to mke it work in shatranj
+                              bishopsColor |= 1 << ((i^j)&1);
+                              NrBB++; break;
+                         case WhiteRook:
+                              NrWR++; break;
+                         case BlackRook:
+                              NrBR++; break;
+                         case WhiteQueen:
+                              NrWQ++; break;
+                         case BlackQueen:
+                              NrBQ++; break;
+                         case EmptySquare: 
+                              break;
+                         case BlackPawn:
+                              m = 7-i;
+                         case WhitePawn:
+                              PawnAdvance += m; NrPawns++;
+                     }
+                     NrPieces += (p != EmptySquare);
+                     NrW += ((int)p < (int)BlackPawn);
+                   if(gameInfo.variant == VariantXiangqi && 
+                     (p == WhiteFerz || p == WhiteAlfil || p == BlackFerz || p == BlackAlfil)) {
+                       NrPieces--; // [HGM] XQ: do not count purely defensive pieces
+                         NrW -= ((int)p < (int)BlackPawn);
+                   }
+                 }
+               /* Some material-based adjudications that have to be made before stalemate test */
+               if(gameInfo.variant == VariantAtomic && NrK < 2) {
+                   // [HGM] atomic: stm must have lost his King on previous move, as destroying own K is illegal
+                    boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE; // make claimable as if stm is checkmated
+                    if(canAdjudicate && appData.checkMates) {
+                        if(engineOpponent)
+                          SendMoveToProgram(forwardMostMove-1, engineOpponent); // make sure opponent gets move
+                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                          GameEnds( WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins, 
+                                                       "Xboard adjudication: King destroyed", GE_XBOARD );
+                          return 1;
+                    }
+               }
+               /* Bare King in Shatranj (loses) or Losers (wins) */
+                 if( NrW == 1 || NrPieces - NrW == 1) {
+                   if( gameInfo.variant == VariantLosers) { // [HGM] losers: bare King wins (stm must have it first)
+                    boards[forwardMostMove][EP_STATUS] = EP_WINS;  // mark as win, so it becomes claimable
+                    if(canAdjudicate && appData.checkMates) {
+                        if(engineOpponent)
+                          SendMoveToProgram(forwardMostMove-1, engineOpponent); // make sure opponent gets to see move
+                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                          GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins, 
+                                                       "Xboard adjudication: Bare king", GE_XBOARD );
+                          return 1;
+                    }
+                 } else
+                   if( gameInfo.variant == VariantShatranj && --bare < 0)
+                   {    /* bare King */
+                       boards[forwardMostMove][EP_STATUS] = EP_WINS; // make claimable as win for stm
+                       if(canAdjudicate && appData.checkMates) {
+                           /* but only adjudicate if adjudication enabled */
+                           if(engineOpponent)
+                             SendMoveToProgram(forwardMostMove-1, engineOpponent); // make sure opponent gets move
+                           ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                           GameEnds( NrW > 1 ? WhiteWins : NrPieces - NrW > 1 ? BlackWins : GameIsDrawn, 
+                                                       "Xboard adjudication: Bare king", GE_XBOARD );
+                           return 1;
+                       }
+                 }
+                 } else bare = 1;
+             // don't wait for engine to announce game end if we can judge ourselves
+             switch (MateTest(boards[forwardMostMove], PosFlags(forwardMostMove)) ) {
+             case MT_CHECK:
+               if(gameInfo.variant == Variant3Check) { // [HGM] 3check: when in check, test if 3rd time
+                   int i, checkCnt = 0;    // (should really be done by making nr of checks part of game state)
+                   for(i=forwardMostMove-2; i>=backwardMostMove; i-=2) {
+                       if(MateTest(boards[i], PosFlags(i)) == MT_CHECK)
+                           checkCnt++;
+                       if(checkCnt >= 2) {
+                           reason = "Xboard adjudication: 3rd check";
+                           boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE;
+                           break;
+                       }
+                   }
+               }
+             case MT_NONE:
+             default:
+               break;
+             case MT_STALEMATE:
+             case MT_STAINMATE:
+               reason = "Xboard adjudication: Stalemate";
+               if((signed char)boards[forwardMostMove][EP_STATUS] != EP_CHECKMATE) { // [HGM] don't touch win through baring or K-capt
+                   boards[forwardMostMove][EP_STATUS] = EP_STALEMATE;   // default result for stalemate is draw
+                   if(gameInfo.variant == VariantLosers  || gameInfo.variant == VariantGiveaway) // [HGM] losers:
+                       boards[forwardMostMove][EP_STATUS] = EP_WINS;    // in these variants stalemated is always a win
+                   else if(gameInfo.variant == VariantSuicide) // in suicide it depends
+                       boards[forwardMostMove][EP_STATUS] = NrW == NrPieces-NrW ? EP_STALEMATE :
+                                                  ((NrW < NrPieces-NrW) != WhiteOnMove(forwardMostMove) ?
+                                                                       EP_CHECKMATE : EP_WINS);
+                   else if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantXiangqi)
+                       boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE; // and in these variants being stalemated loses
+               }
+               break;
+             case MT_CHECKMATE:
+               reason = "Xboard adjudication: Checkmate";
+               boards[forwardMostMove][EP_STATUS] = (gameInfo.variant == VariantLosers ? EP_WINS : EP_CHECKMATE);
+               break;
+           }
+               switch(i = (signed char)boards[forwardMostMove][EP_STATUS]) {
+                   case EP_STALEMATE:
+                       result = GameIsDrawn; break;
+                   case EP_CHECKMATE:
+                       result = WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins; break;
+                   case EP_WINS:
+                       result = WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins; break;
+                   default:
+                       result = (ChessMove) 0;
+               }
+                 if(canAdjudicate && appData.checkMates && result) { // [HGM] mates: adjudicate finished games if requested
+                   if(engineOpponent)
+                     SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
+                   ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                   GameEnds( result, reason, GE_XBOARD );
+                   return 1;
+               }
+                 /* Next absolutely insufficient mating material. */
+                 if( NrPieces == 2 || gameInfo.variant != VariantXiangqi && 
+                                    gameInfo.variant != VariantShatranj && // [HGM] baring will remain possible
+                       (NrPieces == 3 && NrWN+NrBN+NrWB+NrBB == 1 ||
+                        NrPieces == NrBB+NrWB+2 && bishopsColor != 3)) // [HGM] all Bishops (Ferz!) same color
+                 {    /* KBK, KNK, KK of KBKB with like Bishops */
+                      /* always flag draws, for judging claims */
+                      boards[forwardMostMove][EP_STATUS] = EP_INSUF_DRAW;
+                      if(canAdjudicate && appData.materialDraws) {
+                          /* but only adjudicate them if adjudication enabled */
+                        if(engineOpponent) {
+                          SendToProgram("force\n", engineOpponent); // suppress reply
+                          SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see last move */
+                        }
+                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                          GameEnds( GameIsDrawn, "Xboard adjudication: Insufficient mating material", GE_XBOARD );
+                          return 1;
+                      }
+                 }
+                 /* Then some trivial draws (only adjudicate, cannot be claimed) */
+                 if(NrPieces == 4 && 
+                    (   NrWR == 1 && NrBR == 1 /* KRKR */
+                    || NrWQ==1 && NrBQ==1     /* KQKQ */
+                    || NrWN==2 || NrBN==2     /* KNNK */
+                    || NrWN+NrWB == 1 && NrBN+NrBB == 1 /* KBKN, KBKB, KNKN */
+                   ) ) {
+                      if(canAdjudicate && --moveCount < 0 && appData.trivialDraws)
+                      {    /* if the first 3 moves do not show a tactical win, declare draw */
+                         if(engineOpponent) {
+                           SendToProgram("force\n", engineOpponent); // suppress reply
+                           SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
+                         }
+                           ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                           GameEnds( GameIsDrawn, "Xboard adjudication: Trivial draw", GE_XBOARD );
+                           return 1;
+                      }
+                 } else moveCount = 6;
+           }
+       }
+         
+       if (appData.debugMode) { int i;
+           fprintf(debugFP, "repeat test fmm=%d bmm=%d ep=%d, reps=%d\n",
+                   forwardMostMove, backwardMostMove, boards[backwardMostMove][EP_STATUS],
+                   appData.drawRepeats);
+           for( i=forwardMostMove; i>=backwardMostMove; i-- )
+             fprintf(debugFP, "%d ep=%d\n", i, (signed char)boards[i][EP_STATUS]);
+           
+       }
+       // Repetition draws and 50-move rule can be applied independently of legality testing
+                 /* Check for rep-draws */
+                 count = 0;
+                 for(k = forwardMostMove-2;
+                     k>=backwardMostMove && k>=forwardMostMove-100 &&
+                         (signed char)boards[k][EP_STATUS] < EP_UNKNOWN &&
+                         (signed char)boards[k+2][EP_STATUS] <= EP_NONE && (signed char)boards[k+1][EP_STATUS] <= EP_NONE;
+                     k-=2)
+                 {   int rights=0;
+                     if(CompareBoards(boards[k], boards[forwardMostMove])) {
+                         /* compare castling rights */
+                         if( boards[forwardMostMove][CASTLING][2] != boards[k][CASTLING][2] &&
+                              (boards[k][CASTLING][0] != NoRights || boards[k][CASTLING][1] != NoRights) )
+                                 rights++; /* King lost rights, while rook still had them */
+                         if( boards[forwardMostMove][CASTLING][2] != NoRights ) { /* king has rights */
+                             if( boards[forwardMostMove][CASTLING][0] != boards[k][CASTLING][0] ||
+                                 boards[forwardMostMove][CASTLING][1] != boards[k][CASTLING][1] )
+                                    rights++; /* but at least one rook lost them */
+                         }
+                         if( boards[forwardMostMove][CASTLING][5] != boards[k][CASTLING][5] &&
+                              (boards[k][CASTLING][3] != NoRights || boards[k][CASTLING][4] != NoRights) )
+                                 rights++; 
+                         if( boards[forwardMostMove][CASTLING][5] != NoRights ) {
+                             if( boards[forwardMostMove][CASTLING][3] != boards[k][CASTLING][3] ||
+                                 boards[forwardMostMove][CASTLING][4] != boards[k][CASTLING][4] )
+                                    rights++;
+                         }
+                         if( canAdjudicate && rights == 0 && ++count > appData.drawRepeats-2
+                             && appData.drawRepeats > 1) {
+                              /* adjudicate after user-specified nr of repeats */
+                            if(engineOpponent) {
+                              SendToProgram("force\n", engineOpponent); // suppress reply
+                              SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
+                            }
+                              ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                            if(gameInfo.variant == VariantXiangqi && appData.testLegality) { 
+                               // [HGM] xiangqi: check for forbidden perpetuals
+                               int m, ourPerpetual = 1, hisPerpetual = 1;
+                               for(m=forwardMostMove; m>k; m-=2) {
+                                   if(MateTest(boards[m], PosFlags(m)) != MT_CHECK)
+                                       ourPerpetual = 0; // the current mover did not always check
+                                   if(MateTest(boards[m-1], PosFlags(m-1)) != MT_CHECK)
+                                       hisPerpetual = 0; // the opponent did not always check
+                               }
+                               if(appData.debugMode) fprintf(debugFP, "XQ perpetual test, our=%d, his=%d\n",
+                                                                       ourPerpetual, hisPerpetual);
+                               if(ourPerpetual && !hisPerpetual) { // we are actively checking him: forfeit
+                                   GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins, 
+                                          "Xboard adjudication: perpetual checking", GE_XBOARD );
+                                   return 1;
+                               }
+                               if(hisPerpetual && !ourPerpetual)   // he is checking us, but did not repeat yet
+                                   break; // (or we would have caught him before). Abort repetition-checking loop.
+                               // Now check for perpetual chases
+                               if(!ourPerpetual && !hisPerpetual) { // no perpetual check, test for chase
+                                   hisPerpetual = PerpetualChase(k, forwardMostMove);
+                                   ourPerpetual = PerpetualChase(k+1, forwardMostMove);
+                                   if(ourPerpetual && !hisPerpetual) { // we are actively chasing him: forfeit
+                                       GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins, 
+                                                     "Xboard adjudication: perpetual chasing", GE_XBOARD );
+                                       return 1;
+                                   }
+                                   if(hisPerpetual && !ourPerpetual)   // he is chasing us, but did not repeat yet
+                                       break; // Abort repetition-checking loop.
+                               }
+                               // if neither of us is checking or chasing all the time, or both are, it is draw
+                            }
+                              GameEnds( GameIsDrawn, "Xboard adjudication: repetition draw", GE_XBOARD );
+                              return 1;
+                         }
+                         if( rights == 0 && count > 1 ) /* occurred 2 or more times before */
+                              boards[forwardMostMove][EP_STATUS] = EP_REP_DRAW;
+                     }
+                 }
+                 /* Now we test for 50-move draws. Determine ply count */
+                 count = forwardMostMove;
+                 /* look for last irreversble move */
+                 while( (signed char)boards[count][EP_STATUS] <= EP_NONE && count > backwardMostMove )
+                     count--;
+                 /* if we hit starting position, add initial plies */
+                 if( count == backwardMostMove )
+                     count -= initialRulePlies;
+                 count = forwardMostMove - count; 
+                 if( count >= 100)
+                          boards[forwardMostMove][EP_STATUS] = EP_RULE_DRAW;
+                          /* this is used to judge if draw claims are legal */
+                 if(canAdjudicate && appData.ruleMoves > 0 && count >= 2*appData.ruleMoves) {
+                        if(engineOpponent) {
+                          SendToProgram("force\n", engineOpponent); // suppress reply
+                          SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
+                        }
+                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                          GameEnds( GameIsDrawn, "Xboard adjudication: 50-move rule", GE_XBOARD );
+                          return 1;
+                 }
+                 /* if draw offer is pending, treat it as a draw claim
+                  * when draw condition present, to allow engines a way to
+                  * claim draws before making their move to avoid a race
+                  * condition occurring after their move
+                  */
+               if((gameMode == TwoMachinesPlay ? second.offeredDraw : userOfferedDraw) || first.offeredDraw ) {
+                          char *p = NULL;
+                          if((signed char)boards[forwardMostMove][EP_STATUS] == EP_RULE_DRAW)
+                              p = "Draw claim: 50-move rule";
+                          if((signed char)boards[forwardMostMove][EP_STATUS] == EP_REP_DRAW)
+                              p = "Draw claim: 3-fold repetition";
+                          if((signed char)boards[forwardMostMove][EP_STATUS] == EP_INSUF_DRAW)
+                              p = "Draw claim: insufficient mating material";
+                          if( p != NULL && canAdjudicate) {
+                            if(engineOpponent) {
+                              SendToProgram("force\n", engineOpponent); // suppress reply
+                              SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
+                            }
+                              ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                              GameEnds( GameIsDrawn, p, GE_XBOARD );
+                              return 1;
+                          }
+                 }
+               if( canAdjudicate && appData.adjudicateDrawMoves > 0 && forwardMostMove > (2*appData.adjudicateDrawMoves) ) {
+                   if(engineOpponent) {
+                     SendToProgram("force\n", engineOpponent); // suppress reply
+                     SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
+                   }
+                   ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+                   GameEnds( GameIsDrawn, "Xboard adjudication: long game", GE_XBOARD );
+                   return 1;
+               }
+       return 0;
+ }
  char *SendMoveToBookUser(int moveNr, ChessProgramState *cps, int initial)
  {   // [HGM] book: this routine intercepts moves to simulate book replies
      char *bookHit = NULL;
        cps->bookSuspend = FALSE; // after a 'go' we are never suspended
      } else { // 'go' might be sent based on 'firstMove' after this routine returns
        if(cps->bookSuspend && !firstMove) // 'go' needed, and it will not be done after we return
-           SendToProgram("go\n", cps);
+           SendToProgram("go\n", cps); 
        cps->bookSuspend = FALSE; // anyhow, we will not be suspended after a miss
      }
      return bookHit; // notify caller of hit, so it can take action to send move to opponent
@@@ -6150,7 -6789,7 +6889,7 @@@ FakeBookMove: // [HGM] book: we jump he
       * Look for machine move.
       */
      if ((sscanf(message, "%s %s %s", buf1, buf2, machineMove) == 3 && strcmp(buf2, "...") == 0) ||
 -      (sscanf(message, "%s %s", buf1, machineMove) == 2 && strcmp(buf1, "move") == 0)) 
 +      (sscanf(message, "%s %s", buf1, machineMove) == 2 && strcmp(buf1, "move") == 0))
      {
          /* This method is only useful on engines that support ping */
          if (cps->lastPing != cps->lastPong) {
            if (gameMode == TwoMachinesPlay) {
              GameEnds(machineWhite ? BlackWins : WhiteWins,
                         buf1, GE_XBOARD);
++<<<<<<< HEAD
 +          }
 +          return;
 +      }
 +
 +        /* [HGM] Apparently legal, but so far only tested with EP_UNKOWN */
 +        /* So we have to redo legality test with true e.p. status here,  */
 +        /* to make sure an illegal e.p. capture does not slip through,   */
 +        /* to cause a forfeit on a justified illegal-move complaint      */
 +        /* of the opponent.                                              */
 +        if( gameMode==TwoMachinesPlay && appData.testLegality
 +            && fromY != DROP_RANK /* [HGM] temporary; should still add legality test for drops */
 +                                                              ) {
 +           ChessMove moveType;
 +           moveType = LegalityTest(boards[forwardMostMove], PosFlags(forwardMostMove),
 +                             fromY, fromX, toY, toX, promoChar);
 +          if (appData.debugMode) {
 +                int i;
 +                for(i=0; i< nrCastlingRights; i++) fprintf(debugFP, "(%d,%d) ",
 +                    boards[forwardMostMove][CASTLING][i], castlingRank[i]);
 +                fprintf(debugFP, "castling rights\n");
 +          }
 +            if(moveType == IllegalMove) {
 +                sprintf(buf1, "Xboard: Forfeit due to illegal move: %s (%c%c%c%c)%c",
 +                        machineMove, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, 0);
 +                GameEnds(machineWhite ? BlackWins : WhiteWins,
 +                           buf1, GE_XBOARD);
 +              return;
 +           } else if(gameInfo.variant != VariantFischeRandom && gameInfo.variant != VariantCapaRandom)
 +           /* [HGM] Kludge to handle engines that send FRC-style castling
 +              when they shouldn't (like TSCP-Gothic) */
 +           switch(moveType) {
 +             case WhiteASideCastleFR:
 +             case BlackASideCastleFR:
 +               toX+=2;
 +               currentMoveString[2]++;
 +               break;
 +             case WhiteHSideCastleFR:
 +             case BlackHSideCastleFR:
 +               toX--;
 +               currentMoveString[2]--;
 +               break;
 +           default: ; // nothing to do, but suppresses warning of pedantic compilers
 +           }
 +        }
 +      hintRequested = FALSE;
 +      lastHint[0] = NULLCHAR;
 +      bookRequested = FALSE;
 +      /* Program may be pondering now */
 +      cps->maybeThinking = TRUE;
 +      if (cps->sendTime == 2) cps->sendTime = 1;
 +      if (cps->offeredDraw) cps->offeredDraw--;
 +
 +#if ZIPPY
 +      if ((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack) &&
 +          first.initDone) {
 +        SendMoveToICS(moveType, fromX, fromY, toX, toY);
 +        ics_user_moved = 1;
 +        if(appData.autoKibitz && !appData.icsEngineAnalyze ) { /* [HGM] kibitz: send most-recent PV info to ICS */
 +              char buf[3*MSG_SIZ];
 +
 +              sprintf(buf, "kibitz !!! %+.2f/%d (%.2f sec, %u nodes, %.0f knps) PV=%s\n",
 +                      programStats.score / 100.,
 +                      programStats.depth,
 +                      programStats.time / 100.,
 +                      (unsigned int)programStats.nodes,
 +                      (unsigned int)programStats.nodes / (10*abs(programStats.time) + 1.),
 +                      programStats.movelist);
 +              SendToICS(buf);
 +if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.nodes, programStats.nodes);
 +        }
 +      }
 +#endif
 +      /* currentMoveString is set as a side-effect of ParseOneMove */
 +      strcpy(machineMove, currentMoveString);
 +      strcat(machineMove, "\n");
 +      strcpy(moveList[forwardMostMove], machineMove);
 +
 +        /* [AS] Save move info and clear stats for next move */
 +        pvInfoList[ forwardMostMove ].score = programStats.score;
 +        pvInfoList[ forwardMostMove ].depth = programStats.depth;
 +        pvInfoList[ forwardMostMove ].time =  programStats.time; // [HGM] PGNtime: take time from engine stats
 +        ClearProgramStats();
 +        thinkOutput[0] = NULLCHAR;
 +        hiddenThinkOutputState = 0;
 +
 +      MakeMove(fromX, fromY, toX, toY, promoChar);/*updates forwardMostMove*/
 +
 +        /* [AS] Adjudicate game if needed (note: remember that forwardMostMove now points past the last move) */
 +        if( gameMode == TwoMachinesPlay && adjudicateLossThreshold != 0 && forwardMostMove >= adjudicateLossPlies ) {
 +            int count = 0;
 +
 +            while( count < adjudicateLossPlies ) {
 +                int score = pvInfoList[ forwardMostMove - count - 1 ].score;
 +
 +                if( count & 1 ) {
 +                    score = -score; /* Flip score for winning side */
 +                }
 +
 +                if( score > adjudicateLossThreshold ) {
 +                    break;
 +                }
 +
 +                count++;
 +            }
 +
 +            if( count >= adjudicateLossPlies ) {
 +              ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 +
 +                GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
 +                    "Xboard adjudication",
 +                    GE_XBOARD );
 +
 +                return;
 +            }
 +        }
 +
 +      if( gameMode == TwoMachinesPlay ) {
 +        // [HGM] some adjudications useful with buggy engines
 +            int k, count = 0; static int bare = 1;
 +        if(gameInfo.holdingsSize == 0 || gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) {
 +
 +
 +          if( appData.testLegality )
 +          {   /* [HGM] Some more adjudications for obstinate engines */
 +              int NrWN=0, NrBN=0, NrWB=0, NrBB=0, NrWR=0, NrBR=0,
 +                    NrWQ=0, NrBQ=0, NrW=0, NrK=0, bishopsColor = 0,
 +                    NrPieces=0, NrPawns=0, PawnAdvance=0, i, j;
 +              static int moveCount = 6;
 +              ChessMove result;
 +              char *reason = NULL;
 +
 +                /* Count what is on board. */
 +              for(i=0; i<BOARD_HEIGHT; i++) for(j=BOARD_LEFT; j<BOARD_RGHT; j++)
 +              {   ChessSquare p = boards[forwardMostMove][i][j];
 +                  int m=i;
 +
 +                  switch((int) p)
 +                  {   /* count B,N,R and other of each side */
 +                        case WhiteKing:
 +                        case BlackKing:
 +                           NrK++; break; // [HGM] atomic: count Kings
 +                        case WhiteKnight:
 +                             NrWN++; break;
 +                        case WhiteBishop:
 +                        case WhiteFerz:    // [HGM] shatranj: kludge to mke it work in shatranj
 +                             bishopsColor |= 1 << ((i^j)&1);
 +                             NrWB++; break;
 +                        case BlackKnight:
 +                             NrBN++; break;
 +                        case BlackBishop:
 +                        case BlackFerz:    // [HGM] shatranj: kludge to mke it work in shatranj
 +                             bishopsColor |= 1 << ((i^j)&1);
 +                             NrBB++; break;
 +                        case WhiteRook:
 +                             NrWR++; break;
 +                        case BlackRook:
 +                             NrBR++; break;
 +                        case WhiteQueen:
 +                             NrWQ++; break;
 +                        case BlackQueen:
 +                             NrBQ++; break;
 +                        case EmptySquare:
 +                             break;
 +                        case BlackPawn:
 +                             m = 7-i;
 +                        case WhitePawn:
 +                             PawnAdvance += m; NrPawns++;
 +                    }
 +                    NrPieces += (p != EmptySquare);
 +                    NrW += ((int)p < (int)BlackPawn);
 +                  if(gameInfo.variant == VariantXiangqi &&
 +                    (p == WhiteFerz || p == WhiteAlfil || p == BlackFerz || p == BlackAlfil)) {
 +                      NrPieces--; // [HGM] XQ: do not count purely defensive pieces
 +                        NrW -= ((int)p < (int)BlackPawn);
 +                  }
 +                }
 +
 +              /* Some material-based adjudications that have to be made before stalemate test */
 +              if(gameInfo.variant == VariantAtomic && NrK < 2) {
 +                  // [HGM] atomic: stm must have lost his King on previous move, as destroying own K is illegal
 +                   boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE; // make claimable as if stm is checkmated
 +                   if(appData.checkMates) {
 +                       SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets move
 +                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 +                         GameEnds( WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins,
 +                                                      "Xboard adjudication: King destroyed", GE_XBOARD );
 +                         return;
 +                   }
 +              }
 +
 +              /* Bare King in Shatranj (loses) or Losers (wins) */
 +                if( NrW == 1 || NrPieces - NrW == 1) {
 +                  if( gameInfo.variant == VariantLosers) { // [HGM] losers: bare King wins (stm must have it first)
 +                   boards[forwardMostMove][EP_STATUS] = EP_WINS;  // mark as win, so it becomes claimable
 +                   if(appData.checkMates) {
 +                       SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets to see move
 +                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 +                         GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
 +                                                      "Xboard adjudication: Bare king", GE_XBOARD );
 +                         return;
 +                   }
 +                } else
 +                  if( gameInfo.variant == VariantShatranj && --bare < 0)
 +                  {    /* bare King */
 +                      boards[forwardMostMove][EP_STATUS] = EP_WINS; // make claimable as win for stm
 +                      if(appData.checkMates) {
 +                          /* but only adjudicate if adjudication enabled */
 +                          SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets move
 +                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 +                          GameEnds( NrW > 1 ? WhiteWins : NrPieces - NrW > 1 ? BlackWins : GameIsDrawn,
 +                                                      "Xboard adjudication: Bare king", GE_XBOARD );
 +                          return;
 +                      }
 +                }
 +                } else bare = 1;
 +
 +
 +            // don't wait for engine to announce game end if we can judge ourselves
 +            switch (MateTest(boards[forwardMostMove], PosFlags(forwardMostMove)) ) {
 +            case MT_CHECK:
 +              if(gameInfo.variant == Variant3Check) { // [HGM] 3check: when in check, test if 3rd time
 +                  int i, checkCnt = 0;    // (should really be done by making nr of checks part of game state)
 +                  for(i=forwardMostMove-2; i>=backwardMostMove; i-=2) {
 +                      if(MateTest(boards[i], PosFlags(i)) == MT_CHECK)
 +                          checkCnt++;
 +                      if(checkCnt >= 2) {
 +                          reason = "Xboard adjudication: 3rd check";
 +                          boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE;
 +                          break;
 +                      }
 +                  }
 +              }
 +            case MT_NONE:
 +            default:
 +              break;
 +            case MT_STALEMATE:
 +            case MT_STAINMATE:
 +              reason = "Xboard adjudication: Stalemate";
 +              if((signed char)boards[forwardMostMove][EP_STATUS] != EP_CHECKMATE) { // [HGM] don't touch win through baring or K-capt
 +                  boards[forwardMostMove][EP_STATUS] = EP_STALEMATE;   // default result for stalemate is draw
 +                  if(gameInfo.variant == VariantLosers  || gameInfo.variant == VariantGiveaway) // [HGM] losers:
 +                      boards[forwardMostMove][EP_STATUS] = EP_WINS;    // in these variants stalemated is always a win
 +                  else if(gameInfo.variant == VariantSuicide) // in suicide it depends
 +                      boards[forwardMostMove][EP_STATUS] = NrW == NrPieces-NrW ? EP_STALEMATE :
 +                                                 ((NrW < NrPieces-NrW) != WhiteOnMove(forwardMostMove) ?
 +                                                                      EP_CHECKMATE : EP_WINS);
 +                  else if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantXiangqi)
 +                      boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE; // and in these variants being stalemated loses
 +              }
 +              break;
 +            case MT_CHECKMATE:
 +              reason = "Xboard adjudication: Checkmate";
 +              boards[forwardMostMove][EP_STATUS] = (gameInfo.variant == VariantLosers ? EP_WINS : EP_CHECKMATE);
 +              break;
++=======
++>>>>>>> master
            }
+           return;
+       }
  
++<<<<<<< HEAD
 +              switch(i = (signed char)boards[forwardMostMove][EP_STATUS]) {
 +                  case EP_STALEMATE:
 +                      result = GameIsDrawn; break;
 +                  case EP_CHECKMATE:
 +                      result = WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins; break;
 +                  case EP_WINS:
 +                      result = WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins; break;
 +                  default:
 +                      result = (ChessMove) 0;
 +              }
 +                if(appData.checkMates && result) { // [HGM] mates: adjudicate finished games if requested
 +                  SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
 +                  ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 +                  GameEnds( result, reason, GE_XBOARD );
 +                  return;
 +              }
 +
 +                /* Next absolutely insufficient mating material. */
 +                if( NrPieces == 2 || gameInfo.variant != VariantXiangqi &&
 +                                   gameInfo.variant != VariantShatranj && // [HGM] baring will remain possible
 +                      (NrPieces == 3 && NrWN+NrBN+NrWB+NrBB == 1 ||
 +                       NrPieces == NrBB+NrWB+2 && bishopsColor != 3)) // [HGM] all Bishops (Ferz!) same color
 +                {    /* KBK, KNK, KK of KBKB with like Bishops */
++=======
+         /* [HGM] Apparently legal, but so far only tested with EP_UNKOWN */
+         /* So we have to redo legality test with true e.p. status here,  */
+         /* to make sure an illegal e.p. capture does not slip through,   */
+         /* to cause a forfeit on a justified illegal-move complaint      */
+         /* of the opponent.                                              */
+         if( gameMode==TwoMachinesPlay && appData.testLegality
+             && fromY != DROP_RANK /* [HGM] temporary; should still add legality test for drops */
+                                                               ) {
+            ChessMove moveType;
+            moveType = LegalityTest(boards[forwardMostMove], PosFlags(forwardMostMove),
+                              fromY, fromX, toY, toX, promoChar);
+           if (appData.debugMode) {
+                 int i;
+                 for(i=0; i< nrCastlingRights; i++) fprintf(debugFP, "(%d,%d) ",
+                     boards[forwardMostMove][CASTLING][i], castlingRank[i]);
+                 fprintf(debugFP, "castling rights\n");
+           }
+             if(moveType == IllegalMove) {
+                 sprintf(buf1, "Xboard: Forfeit due to illegal move: %s (%c%c%c%c)%c",
+                         machineMove, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, 0);
+                 GameEnds(machineWhite ? BlackWins : WhiteWins,
+                            buf1, GE_XBOARD);
+               return;
+            } else if(gameInfo.variant != VariantFischeRandom && gameInfo.variant != VariantCapaRandom)
+            /* [HGM] Kludge to handle engines that send FRC-style castling
+               when they shouldn't (like TSCP-Gothic) */
+            switch(moveType) {
+              case WhiteASideCastleFR:
+              case BlackASideCastleFR:
+                toX+=2;
+                currentMoveString[2]++;
+                break;
+              case WhiteHSideCastleFR:
+              case BlackHSideCastleFR:
+                toX--;
+                currentMoveString[2]--;
+                break;
+            default: ; // nothing to do, but suppresses warning of pedantic compilers
+            }
+         }
+       hintRequested = FALSE;
+       lastHint[0] = NULLCHAR;
+       bookRequested = FALSE;
+       /* Program may be pondering now */
+       cps->maybeThinking = TRUE;
+       if (cps->sendTime == 2) cps->sendTime = 1;
+       if (cps->offeredDraw) cps->offeredDraw--;
++>>>>>>> master
  
-                      /* always flag draws, for judging claims */
-                      boards[forwardMostMove][EP_STATUS] = EP_INSUF_DRAW;
+       /* currentMoveString is set as a side-effect of ParseOneMove */
+       strcpy(machineMove, currentMoveString);
+       strcat(machineMove, "\n");
+       strcpy(moveList[forwardMostMove], machineMove);
  
-                      if(appData.materialDraws) {
-                          /* but only adjudicate them if adjudication enabled */
-                        SendToProgram("force\n", cps->other); // suppress reply
-                        SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see last move */
-                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
-                          GameEnds( GameIsDrawn, "Xboard adjudication: Insufficient mating material", GE_XBOARD );
-                          return;
-                      }
-                 }
+       MakeMove(fromX, fromY, toX, toY, promoChar);/*updates forwardMostMove*/
  
++<<<<<<< HEAD
 +                /* Then some trivial draws (only adjudicate, cannot be claimed) */
 +                if(NrPieces == 4 &&
 +                   (   NrWR == 1 && NrBR == 1 /* KRKR */
 +                   || NrWQ==1 && NrBQ==1     /* KQKQ */
 +                   || NrWN==2 || NrBN==2     /* KNNK */
 +                   || NrWN+NrWB == 1 && NrBN+NrBB == 1 /* KBKN, KBKB, KNKN */
 +                  ) ) {
 +                     if(--moveCount < 0 && appData.trivialDraws)
 +                     {    /* if the first 3 moves do not show a tactical win, declare draw */
 +                        SendToProgram("force\n", cps->other); // suppress reply
 +                        SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
 +                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 +                          GameEnds( GameIsDrawn, "Xboard adjudication: Trivial draw", GE_XBOARD );
 +                          return;
 +                     }
 +                } else moveCount = 6;
 +          }
 +        }
 +        
 +        if (appData.debugMode) { int i;
 +          fprintf(debugFP, "repeat test fmm=%d bmm=%d ep=%d, reps=%d\n",
 +                  forwardMostMove, backwardMostMove, boards[backwardMostMove][EP_STATUS],
 +                  appData.drawRepeats);
 +          for( i=forwardMostMove; i>=backwardMostMove; i-- )
 +            fprintf(debugFP, "%d ep=%d\n", i, (signed char)boards[i][EP_STATUS]);
 +          
 +        }
 +
 +                /* Check for rep-draws */
 +                count = 0;
 +                for(k = forwardMostMove-2;
 +                    k>=backwardMostMove && k>=forwardMostMove-100 &&
 +                        (signed char)boards[k][EP_STATUS] < EP_UNKNOWN &&
 +                        (signed char)boards[k+2][EP_STATUS] <= EP_NONE && (signed char)boards[k+1][EP_STATUS] <= EP_NONE;
 +                    k-=2)
 +                {   int rights=0;
 +                    if(CompareBoards(boards[k], boards[forwardMostMove])) {
 +                        /* compare castling rights */
 +                        if( boards[forwardMostMove][CASTLING][2] != boards[k][CASTLING][2] &&
 +                             (boards[k][CASTLING][0] != NoRights || boards[k][CASTLING][1] != NoRights) )
 +                                rights++; /* King lost rights, while rook still had them */
 +                        if( boards[forwardMostMove][CASTLING][2] != NoRights ) { /* king has rights */
 +                            if( boards[forwardMostMove][CASTLING][0] != boards[k][CASTLING][0] ||
 +                                boards[forwardMostMove][CASTLING][1] != boards[k][CASTLING][1] )
 +                                   rights++; /* but at least one rook lost them */
 +                        }
 +                        if( boards[forwardMostMove][CASTLING][5] != boards[k][CASTLING][5] &&
 +                             (boards[k][CASTLING][3] != NoRights || boards[k][CASTLING][4] != NoRights) )
 +                                rights++; 
 +                        if( boards[forwardMostMove][CASTLING][5] != NoRights ) {
 +                            if( boards[forwardMostMove][CASTLING][3] != boards[k][CASTLING][3] ||
 +                                boards[forwardMostMove][CASTLING][4] != boards[k][CASTLING][4] )
 +                                   rights++;
 +                        }
 +                        if( rights == 0 && ++count > appData.drawRepeats-2
 +                            && appData.drawRepeats > 1) {
 +                             /* adjudicate after user-specified nr of repeats */
 +                           SendToProgram("force\n", cps->other); // suppress reply
 +                           SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
 +                             ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 +                           if(gameInfo.variant == VariantXiangqi && appData.testLegality) {
 +                              // [HGM] xiangqi: check for forbidden perpetuals
 +                              int m, ourPerpetual = 1, hisPerpetual = 1;
 +                              for(m=forwardMostMove; m>k; m-=2) {
 +                                  if(MateTest(boards[m], PosFlags(m)) != MT_CHECK)
 +                                      ourPerpetual = 0; // the current mover did not always check
 +                                  if(MateTest(boards[m-1], PosFlags(m-1)) != MT_CHECK)
 +                                      hisPerpetual = 0; // the opponent did not always check
 +                              }
 +                              if(appData.debugMode) fprintf(debugFP, "XQ perpetual test, our=%d, his=%d\n",
 +                                                                      ourPerpetual, hisPerpetual);
 +                              if(ourPerpetual && !hisPerpetual) { // we are actively checking him: forfeit
 +                                  GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
 +                                         "Xboard adjudication: perpetual checking", GE_XBOARD );
 +                                  return;
 +                              }
 +                              if(hisPerpetual && !ourPerpetual)   // he is checking us, but did not repeat yet
 +                                  break; // (or we would have caught him before). Abort repetition-checking loop.
 +                              // Now check for perpetual chases
 +                              if(!ourPerpetual && !hisPerpetual) { // no perpetual check, test for chase
 +                                  hisPerpetual = PerpetualChase(k, forwardMostMove);
 +                                  ourPerpetual = PerpetualChase(k+1, forwardMostMove);
 +                                  if(ourPerpetual && !hisPerpetual) { // we are actively chasing him: forfeit
 +                                      GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
 +                                                    "Xboard adjudication: perpetual chasing", GE_XBOARD );
 +                                      return;
 +                                  }
 +                                  if(hisPerpetual && !ourPerpetual)   // he is chasing us, but did not repeat yet
 +                                      break; // Abort repetition-checking loop.
 +                              }
 +                              // if neither of us is checking or chasing all the time, or both are, it is draw
 +                           }
 +                             GameEnds( GameIsDrawn, "Xboard adjudication: repetition draw", GE_XBOARD );
 +                             return;
 +                        }
 +                        if( rights == 0 && count > 1 ) /* occurred 2 or more times before */
 +                             boards[forwardMostMove][EP_STATUS] = EP_REP_DRAW;
 +                    }
 +                }
 +
 +                /* Now we test for 50-move draws. Determine ply count */
 +                count = forwardMostMove;
 +                /* look for last irreversble move */
 +                while( (signed char)boards[count][EP_STATUS] <= EP_NONE && count > backwardMostMove )
 +                    count--;
 +                /* if we hit starting position, add initial plies */
 +                if( count == backwardMostMove )
 +                    count -= initialRulePlies;
 +                count = forwardMostMove - count;
 +                if( count >= 100)
 +                         boards[forwardMostMove][EP_STATUS] = EP_RULE_DRAW;
 +                         /* this is used to judge if draw claims are legal */
 +                if(appData.ruleMoves > 0 && count >= 2*appData.ruleMoves) {
 +                       SendToProgram("force\n", cps->other); // suppress reply
 +                       SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
 +                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 +                         GameEnds( GameIsDrawn, "Xboard adjudication: 50-move rule", GE_XBOARD );
 +                         return;
++=======
+         /* [AS] Adjudicate game if needed (note: remember that forwardMostMove now points past the last move) */
+         if( gameMode == TwoMachinesPlay && adjudicateLossThreshold != 0 && forwardMostMove >= adjudicateLossPlies ) {
+             int count = 0;
+             while( count < adjudicateLossPlies ) {
+                 int score = pvInfoList[ forwardMostMove - count - 1 ].score;
+                 if( count & 1 ) {
+                     score = -score; /* Flip score for winning side */
++>>>>>>> master
                  }
  
-                 /* if draw offer is pending, treat it as a draw claim
-                  * when draw condition present, to allow engines a way to
-                  * claim draws before making their move to avoid a race
-                  * condition occurring after their move
-                  */
-                 if( cps->other->offeredDraw || cps->offeredDraw ) {
-                          char *p = NULL;
-                          if((signed char)boards[forwardMostMove][EP_STATUS] == EP_RULE_DRAW)
-                              p = "Draw claim: 50-move rule";
-                          if((signed char)boards[forwardMostMove][EP_STATUS] == EP_REP_DRAW)
-                              p = "Draw claim: 3-fold repetition";
-                          if((signed char)boards[forwardMostMove][EP_STATUS] == EP_INSUF_DRAW)
-                              p = "Draw claim: insufficient mating material";
-                          if( p != NULL ) {
-                            SendToProgram("force\n", cps->other); // suppress reply
-                            SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
-                              GameEnds( GameIsDrawn, p, GE_XBOARD );
-                              ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
-                              return;
-                          }
+                 if( score > adjudicateLossThreshold ) {
+                     break;
                  }
  
+                 count++;
+             }
  
-               if( appData.adjudicateDrawMoves > 0 && forwardMostMove > (2*appData.adjudicateDrawMoves) ) {
-                   SendToProgram("force\n", cps->other); // suppress reply
-                   SendMoveToProgram(forwardMostMove-1, cps->other); /* make sure opponent gets to see move */
-                   ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+             if( count >= adjudicateLossPlies ) {
+               ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
  
-                   GameEnds( GameIsDrawn, "Xboard adjudication: long game", GE_XBOARD );
+                 GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins, 
+                     "Xboard adjudication", 
+                     GE_XBOARD );
  
-                   return;
-               }
+                 return;
+             }
          }
  
+       if(Adjudicate(cps)) return; // [HGM] adjudicate: for all automatic game ends
+ #if ZIPPY
+       if ((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack) &&
+           first.initDone) {
+         if(cps->offeredDraw && (signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) {
+               SendToICS(ics_prefix); // [HGM] drawclaim: send caim and move on one line for FICS
+               SendToICS("draw ");
+               SendMoveToICS(moveType, fromX, fromY, toX, toY);
+         }
+         SendMoveToICS(moveType, fromX, fromY, toX, toY);
+         ics_user_moved = 1;
+         if(appData.autoKibitz && !appData.icsEngineAnalyze ) { /* [HGM] kibitz: send most-recent PV info to ICS */
+               char buf[3*MSG_SIZ];
+               sprintf(buf, "kibitz !!! %+.2f/%d (%.2f sec, %u nodes, %.0f knps) PV=%s\n",
+                       programStats.score / 100.,
+                       programStats.depth,
+                       programStats.time / 100.,
+                       (unsigned int)programStats.nodes,
+                       (unsigned int)programStats.nodes / (10*abs(programStats.time) + 1.),
+                       programStats.movelist);
+               SendToICS(buf);
+ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.nodes, programStats.nodes);
+         }
+       }
+ #endif
+         /* [AS] Save move info and clear stats for next move */
+         pvInfoList[ forwardMostMove-1 ].score = programStats.score;
+         pvInfoList[ forwardMostMove-1 ].depth = programStats.depth;
+         pvInfoList[ forwardMostMove-1 ].time =  programStats.time; // [HGM] PGNtime: take time from engine stats
+         ClearProgramStats();
+         thinkOutput[0] = NULLCHAR;
+         hiddenThinkOutputState = 0;
        bookHit = NULL;
        if (gameMode == TwoMachinesPlay) {
              /* [HGM] relaying draw offers moved to after reception of move */
        }
  
        ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 -      
 +
          if (!pausing && appData.ringBellAfterMoves) {
            RingBell();
        }
  
 -      /* 
 +      /*
         * Reenable menu items that were disabled while
         * machine was thinking
         */
                strcat(bookMove, bookHit);
                message = bookMove;
                cps = cps->other;
 -              programStats.nodes = programStats.depth = programStats.time = 
 +              programStats.nodes = programStats.depth = programStats.time =
                programStats.score = programStats.got_only_move = 0;
                sprintf(programStats.movelist, "%s (xbook)", bookHit);
  
             CopyBoard(boards[0], initial_position);
             initialRulePlies = FENrulePlies;
             if(blackPlaysFirst) gameMode = MachinePlaysWhite;
 -           else gameMode = MachinePlaysBlack;                 
 +           else gameMode = MachinePlaysBlack;
             DrawPosition(FALSE, boards[currentMove]);
          }
        return;
        AskQuestion(realname, buf2, buf1, cps->pr);
        return;
      }
 -    /* Commands from the engine directly to ICS.  We don't allow these to be 
 -     *  sent until we are logged on. Crafty kibitzes have been known to 
 +    /* Commands from the engine directly to ICS.  We don't allow these to be
 +     *  sent until we are logged on. Crafty kibitzes have been known to
       *  interfere with the login process.
       */
      if (loggedOn) {
       */
      if (strncmp(message + 1, "llegal move", 11) == 0 ||
        strncmp(message, "Error", 5) == 0) {
 -      if (StrStr(message, "name") || 
 +      if (StrStr(message, "name") ||
            StrStr(message, "rating") || StrStr(message, "?") ||
            StrStr(message, "result") || StrStr(message, "board") ||
            StrStr(message, "bk") || StrStr(message, "computer") ||
           Don't use it. */
        cps->sendTime = 0;
      }
 -    
 +
      /*
       * If chess program startup fails, exit with an error message.
       * Attempts to recover here are futile.
        DisplayFatalError(buf1, 0, 1);
        return;
      }
 -    
 -    /* 
 +
 +    /*
       * Look for hint output
       */
      if (sscanf(message, "Hint: %s", buf1) == 1) {
                r = p + 1;
            }
        }
 -            
 +
          GameEnds(GameIsDrawn, r, GE_ENGINE1 + (cps != &first));
        return;
  
        }
      }
  
 -    
 +
      /*
       * Look for thinking output
       */
  
                  SendProgramStatsToFrontend( cps, &programStats );
  
 -                /* 
 +                /*
                      [AS] Protect the thinkOutput buffer from overflow... this
                      is only useful if buf1 hasn't overflowed first!
                  */
                sprintf(thinkOutput, "[%d]%c%+.2f %s%s",
 -                      plylev, 
 +                      plylev,
                        (gameMode == TwoMachinesPlay ?
                         ToUpper(cps->twoMachinesColor[0]) : ' '),
                        ((double) curscore) / 100.0,
                programStats.line_is_book = 1;
  
                  SendProgramStatsToFrontend( cps, &programStats );
 -                
 -              if (currentMove == forwardMostMove || gameMode==AnalyzeMode || 
 +
 +              if (currentMove == forwardMostMove || gameMode==AnalyzeMode ||
                             gameMode == AnalyzeFile || appData.icsEngineAnalyze) {
                    DisplayMove(currentMove - 1);
                }
            buf1[0] = NULLCHAR;
  
            if (sscanf(message, "%d%c %d %d " u64Display " %[^\n]\n",
 -                     &plylev, &plyext, &curscore, &time, &nodes, buf1) >= 5) 
 +                     &plylev, &plyext, &curscore, &time, &nodes, buf1) >= 5)
              {
                  ChessProgramStats cpstats;
  
  
  /* Parse a game score from the character string "game", and
     record it as the history of the current game.  The game
 -   score is NOT assumed to start from the standard position. 
 +   score is NOT assumed to start from the standard position.
     The display is not updated in any way.
     */
  void
@@@ -7690,10 -8006,10 +8510,10 @@@ ApplyMove(fromX, fromY, toX, toY, promo
                        gameInfo.variant != VariantBerolina || toX < fromX)
                      board[EP_STATUS] = toX | berolina;
                 if(toX<BOARD_RGHT-1 && board[toY][toX+1] == BlackPawn &&
 -                      gameInfo.variant != VariantBerolina || toX > fromX) 
 -                    board[EP_STATUS] = toX;
 +                gameInfo.variant != VariantBerolina || toX > fromX) 
 +               board[EP_STATUS] = toX;
           }
 -      } else 
 +      } else
        if( board[fromY][fromX] == BlackPawn ) {
             if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers
               board[EP_STATUS] = EP_PAWN_MOVE; 
    /* [HGM] In Shatranj and Courier all promotions are to Ferz */
    if((gameInfo.variant==VariantShatranj || gameInfo.variant==VariantCourier || gameInfo.variant == VariantMakruk)
         && promoChar != 0) promoChar = PieceToChar(WhiteFerz);
 -         
 +
    if (fromX == toX && fromY == toY) return;
  
    if (fromY == DROP_RANK) {
        if (captured != EmptySquare && gameInfo.holdingsSize > 0
            && gameInfo.variant != VariantBughouse        ) {
          /* [HGM] holdings: Add to holdings, if holdings exist */
 -      if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) { 
 +      if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) {
                // [HGM] superchess: suppress flipping color of captured pieces by reverse pre-flip
                captured = (int) captured >= (int) BlackPawn ? BLACK_TO_WHITE captured : WHITE_TO_BLACK captured;
        }
          board[toY][toX] = (ChessSquare) (PROMOTED piece);
      }
  
 -    if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) 
 -              && promoChar != NULLCHAR && gameInfo.holdingsSize) { 
 +    if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)
 +              && promoChar != NULLCHAR && gameInfo.holdingsSize) {
        // [HGM] superchess: take promotion piece out of holdings
        int k = PieceToNumber(CharToPiece(ToUpper(promoChar)));
        if((int)piece < (int)BlackPawn) { // determine stm from piece color
@@@ -7984,10 -8300,10 +8804,10 @@@ MakeMove(fromX, fromY, toX, toY, promoC
          if(gameInfo.variant == VariantKnightmate)
              king += (int) WhiteUnicorn - (int) WhiteKing;
          if(forwardMostMove == 0) {
 -            if(blackPlaysFirst) 
 +            if(blackPlaysFirst)
                  fprintf(serverMoves, "%s;", second.tidy);
              fprintf(serverMoves, "%s;", first.tidy);
 -            if(!blackPlaysFirst) 
 +            if(!blackPlaysFirst)
                  fprintf(serverMoves, "%s;", second.tidy);
          } else fprintf(serverMoves, loadFlag|lastLoadFlag ? ":" : ";");
          lastLoadFlag = loadFlag;
@@@ -8072,24 -8388,17 +8892,24 @@@ ShowMove(fromX, fromY, toX, toY
  {
      int instant = (gameMode == PlayFromGameFile) ?
        (matchMode || (appData.timeDelay == 0 && !pausing)) : pausing;
 +
      if(appData.noGUI) return;
 -    if (!pausing || gameMode == PlayFromGameFile || gameMode == AnalyzeFile) {
 -      if (!instant) {
 -          if (forwardMostMove == currentMove + 1) {
 -              AnimateMove(boards[forwardMostMove - 1],
 -                          fromX, fromY, toX, toY);
 -          }
 -          if (appData.highlightLastMove) {
 +
 +    if (!pausing || gameMode == PlayFromGameFile || gameMode == AnalyzeFile)
 +      {
 +      if (!instant)
 +        {
 +          if (forwardMostMove == currentMove + 1)
 +            {
 +//TODO
 +//            AnimateMove(boards[forwardMostMove - 1],
 +//                        fromX, fromY, toX, toY);
 +            }
 +          if (appData.highlightLastMove)
 +            {
                SetHighlights(fromX, fromY, toX, toY);
 -          }
 -      }
 +            }
 +        }
        currentMove = forwardMostMove;
      }
  
      DrawPosition(FALSE, boards[currentMove]);
      DisplayBothClocks();
      HistorySet(parseList,backwardMostMove,forwardMostMove,currentMove-1);
 +
 +    return;
  }
  
  void SendEgtPath(ChessProgramState *cps)
            name[0] = ','; // extract next format name from feature and copy with prefixed ','
            while(*p && *p != ',') *q++ = *p++;
            *q++ = ':'; *q = 0;
 -          if( appData.defaultPathEGTB && appData.defaultPathEGTB[0] && 
 +          if( appData.defaultPathEGTB && appData.defaultPathEGTB[0] &&
                strcmp(name, ",nalimov:") == 0 ) {
                // take nalimov path from the menu-changeable option first, if it is defined
                sprintf(buf, "egtpath nalimov %s\n", appData.defaultPathEGTB);
@@@ -8180,7 -8487,7 +9000,7 @@@ InitChessProgram(cps, setup
             overruled = gameInfo.boardWidth != 9 || gameInfo.boardHeight != 9 || gameInfo.holdingsSize != 7;
        if( gameInfo.variant == VariantBughouse || gameInfo.variant == VariantCrazyhouse )
             overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 5;
 -      if( gameInfo.variant == VariantCapablanca || gameInfo.variant == VariantCapaRandom || 
 +      if( gameInfo.variant == VariantCapablanca || gameInfo.variant == VariantCapaRandom ||
                                 gameInfo.variant == VariantGothic  || gameInfo.variant == VariantFalcon )
             overruled = gameInfo.boardWidth != 10 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 0;
        if( gameInfo.variant == VariantCourier )
             overruled = gameInfo.boardWidth != 10 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 8;
  
        if(overruled) {
 -           sprintf(b, "%dx%d+%d_%s", gameInfo.boardWidth, gameInfo.boardHeight, 
 +           sprintf(b, "%dx%d+%d_%s", gameInfo.boardWidth, gameInfo.boardHeight,
                                 gameInfo.holdingsSize, VariantName(gameInfo.variant)); // cook up sized variant name
             /* [HGM] varsize: try first if this defiant size variant is specifically known */
 -           if(StrStr(cps->variants, b) == NULL) { 
 +           if(StrStr(cps->variants, b) == NULL) {
                 // specific sized variant not known, check if general sizing allowed
                 if (cps->protocolVersion != 1) { // for protocol 1 we cannot check and hope for the best
                     if(StrStr(cps->variants, "boardsize") == NULL) {
                        timeIncrement, appData.searchDepth,
                        searchTime);
      }
 -    if (appData.showThinking 
 +    if (appData.showThinking
        // [HGM] thinking: four options require thinking output to be sent
        || !appData.hideThinkingFromHuman || appData.adjudicateLossThreshold != 0 || EngineOutputIsUp()
                                ) {
        SendToProgram(buf, cps);
      }
      cps->initDone = TRUE;
 -}   
 +}
  
  
  void
@@@ -8277,7 -8584,7 +9097,7 @@@ StartChessProgram(cps
        }
        err = StartChildProcess(buf, "", &cps->pr);
      }
 -    
 +
      if (err != 0) {
        sprintf(buf, _("Startup failure on '%s'"), cps->program);
        DisplayFatalError(buf, err, 1);
        cps->isr = NULL;
        return;
      }
 -    
 +
      cps->isr = AddInputSource(cps->pr, TRUE, ReceiveFromProgram, cps);
      if (cps->protocolVersion > 1) {
        sprintf(buf, "xboard\nprotover %d\n", cps->protocolVersion);
@@@ -8325,7 -8632,7 +9145,7 @@@ NextMatchGame P((void)
        if(index < 0) { // [HGM] autoinc
            lastIndex = index = (index == -2 && first.twoMachinesColor[0] == 'b') ? lastIndex : lastIndex+1;
            if(appData.rewindIndex > 0 && index > appData.rewindIndex) lastIndex = index = 1;
 -      } 
 +      }
        LoadGameFromFile(appData.loadGameFile,
                         index,
                         appData.loadGameFile, FALSE);
        if(index < 0) { // [HGM] autoinc
            lastIndex = index = (index == -2 && first.twoMachinesColor[0] == 'b') ? lastIndex : lastIndex+1;
            if(appData.rewindIndex > 0 && index > appData.rewindIndex) lastIndex = index = 1;
 -      } 
 +      }
        LoadPositionFromFile(appData.loadPositionFile,
                             index,
                             appData.loadPositionFile);
@@@ -8401,8 -8708,8 +9221,8 @@@ GameEnds(result, resultDetails, whosays
  
      if (appData.icsActive && (whosays == GE_ENGINE || whosays >= GE_ENGINE1)) {
        /* If we are playing on ICS, the server decides when the
 -         game is over, but the engine can offer to draw, claim 
 -         a draw, or resign. 
 +         game is over, but the engine can offer to draw, claim
 +         a draw, or resign.
         */
  #if ZIPPY
        if (appData.zippyPlay && first.initDone) {
  
      /* If this is an ICS game, only ICS can really say it's done;
         if not, anyone can. */
 -    isIcsGame = (gameMode == IcsPlayingWhite || 
 -               gameMode == IcsPlayingBlack || 
 -               gameMode == IcsObserving    || 
 +    isIcsGame = (gameMode == IcsPlayingWhite ||
 +               gameMode == IcsPlayingBlack ||
 +               gameMode == IcsObserving    ||
                 gameMode == IcsExamining);
  
      if (!isIcsGame || whosays == GE_ICS) {
        /* OK -- not an ICS game, or ICS said it was done */
        StopClocks();
 -      if (!isIcsGame && !appData.noChessProgram) 
 +      if (!isIcsGame && !appData.noChessProgram)
          SetUserThinkingEnables();
 -    
 +
          /* [HGM] if a machine claims the game end we verify this claim */
          if(gameMode == TwoMachinesPlay && appData.testClaims) {
            if(appData.testLegality && whosays >= GE_ENGINE1 ) {
                  }
                  /* (Claiming a loss is accepted no questions asked!) */
            }
 +
            /* [HGM] bare: don't allow bare King to win */
            if((gameInfo.holdingsWidth == 0 || gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)
 -             && gameInfo.variant != VariantLosers && gameInfo.variant != VariantGiveaway 
 +             && gameInfo.variant != VariantLosers && gameInfo.variant != VariantGiveaway
               && gameInfo.variant != VariantSuicide // [HGM] losers: except in losers, of course...
               && result != GameIsDrawn)
            {   int i, j, k=0, color = (result==WhiteWins ? (int)WhitePawn : (int)BlackPawn);
            }
          }
  
 -
          if(serverMoves != NULL && !loadFlag) { char c = '=';
              if(result==WhiteWins) c = '+';
              if(result==BlackWins) c = '-';
            /* display last move only if game was not loaded from file */
            if ((whosays != GE_FILE) && (currentMove == forwardMostMove))
                DisplayMove(currentMove - 1);
 -    
 +
            if (forwardMostMove != 0) {
                if (gameMode != PlayFromGameFile && gameMode != EditGame
                    && lastSavedGame != GameCheckSum() // [HGM] save: suppress duplicates
                }
            }
        } else if (gameMode == EditGame ||
 -                 gameMode == PlayFromGameFile || 
 -                 gameMode == AnalyzeMode || 
 +                 gameMode == PlayFromGameFile ||
 +                 gameMode == AnalyzeMode ||
                   gameMode == AnalyzeFile) {
            nextGameMode = gameMode;
        } else {
        if (first.isr != NULL)
          RemoveInputSource(first.isr);
        first.isr = NULL;
 -    
 +
        if (first.pr != NoProc) {
            ExitAnalyzeMode();
              DoSleep( appData.delayBeforeQuit );
        if (second.isr != NULL)
          RemoveInputSource(second.isr);
        second.isr = NULL;
 -    
 +
        if (second.pr != NoProc) {
              DoSleep( appData.delayBeforeQuit );
            SendToProgram("quit\n", &second);
  /* Assumes program was just initialized (initString sent).
     Leaves program in force mode. */
  void
 -FeedMovesToProgram(cps, upto) 
 +FeedMovesToProgram(cps, upto)
       ChessProgramState *cps;
       int upto;
  {
      int i;
 -    
 +
      if (appData.debugMode)
        fprintf(debugFP, "Feeding %smoves %d through %d to %s chess program\n",
              startedFromSetupPosition ? "position and " : "",
@@@ -8778,7 -9085,7 +9598,7 @@@ ResurrectChessProgram(
        If so, restart it and feed it all the moves made so far. */
  
      if (appData.noChessProgram || first.pr != NoProc) return;
 -    
 +
      StartChessProgram(&first);
      InitChessProgram(&first, FALSE);
      FeedMovesToProgram(&first, currentMove);
@@@ -8832,7 -9139,7 +9652,7 @@@ Reset(redraw, init
      white_holding[0] = black_holding[0] = NULLCHAR;
      ClearProgramStats();
      opponentKibitzes = FALSE; // [HGM] kibitz: do not reserve space in engine-output window in zippy mode
 -    
 +
      ResetFrontEnd();
      ClearHighlights();
      flipView = appData.flipView;
      ExitAnalyzeMode();
      gameMode = BeginningOfGame;
      ModeHighlight();
 +
      if(appData.icsActive) gameInfo.variant = VariantNormal;
      currentMove = forwardMostMove = backwardMostMove = 0;
      InitPosition(redraw);
            commentList[i] = NULL;
        }
      }
 +
      ResetClocks();
      timeRemaining[0][0] = whiteTimeRemaining;
      timeRemaining[1][0] = blackTimeRemaining;
      if (init) {
            InitChessProgram(&first, startedFromSetupPosition);
      }
 +
      DisplayTitle("");
      DisplayMessage("", "");
      HistorySet(parseList, backwardMostMove, forwardMostMove, currentMove-1);
      lastSavedGame = 0; // [HGM] save: make sure next game counts as unsaved
 +    return;
  }
  
  void
@@@ -8922,7 -9225,7 +9742,7 @@@ AutoPlayOneMove(
  
        return FALSE;
      }
 -    
 +
      toX = moveList[currentMove][2] - AAA;
      toY = moveList[currentMove][3] - ONE;
  
@@@ -8961,13 -9264,13 +9781,13 @@@ LoadGameOneMove(readAhead
      ChessMove moveType;
      char move[MSG_SIZ];
      char *p, *q;
 -    
 -    if (gameMode != PlayFromGameFile && gameMode != AnalyzeFile && 
 +
 +    if (gameMode != PlayFromGameFile && gameMode != AnalyzeFile &&
        gameMode != AnalyzeMode && gameMode != Training) {
        gameFileFP = NULL;
        return FALSE;
      }
 -    
 +
      yyboardindex = forwardMostMove;
      if (readAhead != (ChessMove)0) {
        moveType = readAhead;
          return FALSE;
        moveType = (ChessMove) yylex();
      }
 -    
 +
      done = FALSE;
      switch (moveType) {
        case Comment:
 -      if (appData.debugMode) 
 +      if (appData.debugMode)
          fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
        p = yy_text;
  
        /* currentMoveString is set as a side-effect of yylex */
        strcat(currentMoveString, "\n");
        strcpy(moveList[forwardMostMove], currentMoveString);
 -      
 +
        thinkOutput[0] = NULLCHAR;
        MakeMove(fromX, fromY, toX, toY, promoChar);
        currentMove = forwardMostMove;
@@@ -9232,8 -9535,7 +10052,8 @@@ LoadGameFromFile(filename, n, title, us
            DisplayError(_("Cannot build game list"), error);
        } else if (!ListEmpty(&gameList) &&
                   ((ListGame *) gameList.tailPred)->number > 1) {
 -          GameListPopUp(f, title);
 +        // TODO convert to GTK
 +        //        GameListPopUp(f, title);
            return TRUE;
        }
        GameListDestroy();
@@@ -9256,7 -9558,7 +10076,7 @@@ MakeRegisteredMove(
            if (appData.debugMode)
              fprintf(debugFP, "Restoring %s for game %d\n",
                      cmailMove[lastLoadGameNumber - 1], lastLoadGameNumber);
 -    
 +
            thinkOutput[0] = NULLCHAR;
            strcpy(moveList[currentMove], cmailMove[lastLoadGameNumber - 1]);
              fromX = cmailMove[lastLoadGameNumber - 1][0] - AAA;
            promoChar = cmailMove[lastLoadGameNumber - 1][4];
            MakeMove(fromX, fromY, toX, toY, promoChar);
            ShowMove(fromX, fromY, toX, toY);
 -            
            switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) {
              case MT_NONE:
              case MT_CHECK:
                break;
 -              
 +
              case MT_CHECKMATE:
              case MT_STAINMATE:
                if (WhiteOnMove(currentMove)) {
                    GameEnds(WhiteWins, "White mates", GE_PLAYER);
                }
                break;
 -              
 +
              case MT_STALEMATE:
                GameEnds(GameIsDrawn, "Stalemate", GE_PLAYER);
                break;
            }
  
            break;
 -          
 +
          case CMAIL_RESIGN:
            if (WhiteOnMove(currentMove)) {
                GameEnds(BlackWins, "White resigns", GE_PLAYER);
                GameEnds(WhiteWins, "Black resigns", GE_PLAYER);
            }
            break;
 -          
 +
          case CMAIL_ACCEPT:
            GameEnds(GameIsDrawn, "Draw agreed", GE_PLAYER);
            break;
 -            
 +
          default:
            break;
        }
@@@ -9394,90 -9697,71 +10214,90 @@@ LoadGame(f, gameNumber, title, useList
      GameMode oldGameMode;
      VariantClass oldVariant = gameInfo.variant; /* [HGM] PGNvariant */
  
 -    if (appData.debugMode) 
 +    if (appData.debugMode)
        fprintf(debugFP, "LoadGame(): on entry, gameMode %d\n", gameMode);
  
      if (gameMode == Training )
        SetTrainingModeOff();
  
      oldGameMode = gameMode;
 -    if (gameMode != BeginningOfGame) {
 -      Reset(FALSE, TRUE);
 -    }
 +    if (gameMode != BeginningOfGame) 
 +      {
 +      Reset(FALSE, TRUE);
 +      };
  
      gameFileFP = f;
 -    if (lastLoadGameFP != NULL && lastLoadGameFP != f) {
 +    if (lastLoadGameFP != NULL && lastLoadGameFP != f) 
 +      {
        fclose(lastLoadGameFP);
 -    }
 +      };
  
 -    if (useList) {
 +    if (useList) 
 +      {
        lg = (ListGame *) ListElem(&gameList, gameNumber-1);
        
 -      if (lg) {
 +      if (lg) 
 +        {
            fseek(f, lg->offset, 0);
            GameListHighlight(gameNumber);
            gn = 1;
 -      }
 -      else {
 +        }
 +      else 
 +        {
            DisplayError(_("Game number out of range"), 0);
            return FALSE;
 -      }
 -    } else {
 +        };
 +      } 
 +    else 
 +      {
        GameListDestroy();
 -      if (fseek(f, 0, 0) == -1) {
 +      if (fseek(f, 0, 0) == -1) 
 +        {
            if (f == lastLoadGameFP ?
                gameNumber == lastLoadGameNumber + 1 :
 -              gameNumber == 1) {
 +              gameNumber == 1) 
 +            {
                gn = 1;
 -          } else {
 +            } 
 +          else 
 +            {
                DisplayError(_("Can't seek on game file"), 0);
                return FALSE;
 -          }
 -      }
 -    }
 -    lastLoadGameFP = f;
 -    lastLoadGameNumber = gameNumber;
 +            };
 +        };
 +      };
 +
 +    lastLoadGameFP    = f;
 +    lastLoadGameNumber        = gameNumber;
      strcpy(lastLoadGameTitle, title);
      lastLoadGameUseList = useList;
  
      yynewfile(f);
  
 -    if (lg && lg->gameInfo.white && lg->gameInfo.black) {
 -      snprintf(buf, sizeof(buf), "%s vs. %s", lg->gameInfo.white,
 -              lg->gameInfo.black);
 -          DisplayTitle(buf);
 -    } else if (*title != NULLCHAR) {
 -      if (gameNumber > 1) {
 +    if (lg && lg->gameInfo.white && lg->gameInfo.black) 
 +      {
 +      snprintf(buf, sizeof(buf), "%s vs. %s", lg->gameInfo.white,
 +               lg->gameInfo.black);
 +      DisplayTitle(buf);
 +      } 
 +    else if (*title != NULLCHAR) 
 +      {
 +      if (gameNumber > 1) 
 +        {
            sprintf(buf, "%s %d", title, gameNumber);
            DisplayTitle(buf);
 -      } else {
 +        } 
 +      else 
 +        {
            DisplayTitle(title);
 -      }
 -    }
 +        };
 +      };
  
 -    if (gameMode != AnalyzeFile && gameMode != AnalyzeMode) {
 +    if (gameMode != AnalyzeFile && gameMode != AnalyzeMode) 
 +      {
        gameMode = PlayFromGameFile;
        ModeHighlight();
 -    }
 +      };
  
      currentMove = forwardMostMove = backwardMostMove = 0;
      CopyBoard(boards[0], initialPosition);
  
      /*
       * Skip the first gn-1 games in the file.
 -     * Also skip over anything that precedes an identifiable 
 -     * start of game marker, to avoid being confused by 
 -     * garbage at the start of the file.  Currently 
 +     * Also skip over anything that precedes an identifiable
 +     * start of game marker, to avoid being confused by
 +     * garbage at the start of the file.  Currently
       * recognized start of game markers are the move number "1",
       * the pattern "gnuchess .* game", the pattern
 -     * "^[#;%] [^ ]* game file", and a PGN tag block.  
 +     * "^[#;%] [^ ]* game file", and a PGN tag block.
       * A game that starts with one of the latter two patterns
       * will also have a move number 1, possibly
       * following a position diagram.
            gn--;
            lastLoadGameStart = cm;
            break;
 -          
 +
          case MoveNumberOne:
            switch (lastLoadGameStart) {
              case GNUChessGame:
            break;
        }
      }
 -    
 +
      if (appData.debugMode)
        fprintf(debugFP, "Parsed game start '%s' (%d)\n", yy_text, (int) cm);
  
            free(gameInfo.event);
        }
        gameInfo.event = StrSave(yy_text);
 -    } 
 +    }
  
      startedFromSetupPosition = FALSE;
      while (cm == PGNTag) {
 -      if (appData.debugMode) 
 +      if (appData.debugMode)
          fprintf(debugFP, "Parsed PGNTag: %s\n", yy_text);
        err = ParsePGNTag(yy_text, &gameInfo);
        if (!err) numPGNTags++;
              startedFromPositionFile = FALSE; /* [HGM] loadPos: variant switch likely makes position invalid */
            InitPosition(TRUE);
              oldVariant = gameInfo.variant;
 -          if (appData.debugMode) 
 +          if (appData.debugMode)
              fprintf(debugFP, "New variant %d\n", (int) oldVariant);
          }
  
        /* Handle comments interspersed among the tags */
        while (cm == Comment) {
            char *p;
 -          if (appData.debugMode) 
 +          if (appData.debugMode)
              fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
            p = yy_text;
            AppendComment(currentMove, p, FALSE);
                }
            while (*p == ' ' || *p == '\t' ||
                   *p == '\n' || *p == '\r') p++;
 -      
 +
            if (strncmp(p, "black", strlen("black"))==0)
              blackPlaysFirst = TRUE;
            else
              blackPlaysFirst = FALSE;
            startedFromSetupPosition = TRUE;
 -      
 +
            CopyBoard(boards[0], initial_position);
            if (blackPlaysFirst) {
                currentMove = forwardMostMove = backwardMostMove = 1;
          fprintf(debugFP, "Load Game\n");
      }
        DisplayBothClocks();
 -    }      
 +    }
  
      /* [HGM] server: flag to write setup moves in broadcast file as one */
      loadFlag = appData.suppressLoadMoves;
  
      while (cm == Comment) {
        char *p;
 -      if (appData.debugMode) 
 +      if (appData.debugMode)
          fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
        p = yy_text;
        AppendComment(currentMove, p, FALSE);
      if (!matchMode && (pausing || appData.timeDelay != 0)) {
        DisplayComment(currentMove - 1, commentList[currentMove]);
      }
 -    if (!matchMode && appData.timeDelay != 0) 
 +    if (!matchMode && appData.timeDelay != 0)
        DrawPosition(FALSE, boards[currentMove]);
  
      if (gameMode == AnalyzeFile || gameMode == AnalyzeMode) {
      }
  
      /* if the first token after the PGN tags is a move
 -     * and not move number 1, retrieve it from the parser 
 +     * and not move number 1, retrieve it from the parser
       */
      if (cm != MoveNumberOne)
        LoadGameOneMove(cm);
        AutoPlayGameLoop();
      }
  
 -    if (appData.debugMode) 
 +    if (appData.debugMode)
        fprintf(debugFP, "LoadGame(): on exit, gameMode %d\n", gameMode);
  
      loadFlag = 0; /* [HGM] true game starts */
@@@ -9897,7 -10181,7 +10717,7 @@@ LoadPosition(f, positionNumber, title
      char *p, line[MSG_SIZ];
      Board initial_position;
      int i, j, fenMode, pn;
 -    
 +
      if (gameMode == Training )
        SetTrainingModeOff();
  
      if (first.pr == NoProc) {
        StartChessProgram(&first);
        InitChessProgram(&first, FALSE);
 -    }    
 +    }
      pn = positionNumber;
      if (positionNumber < 0) {
        /* Negative position number means to seek to that byte offset */
      } else {
        (void) fgets(line, MSG_SIZ, f);
        (void) fgets(line, MSG_SIZ, f);
 -    
 +
          for (i = BOARD_HEIGHT - 1; i >= 0; i--) {
            (void) fgets(line, MSG_SIZ, f);
              for (p = line, j = BOARD_LEFT; j < BOARD_RGHT; p++) {
                initial_position[i][j++] = CharToPiece(*p);
            }
        }
 -    
 +
        blackPlaysFirst = FALSE;
        if (!feof(f)) {
            (void) fgets(line, MSG_SIZ, f);
        }
      }
      startedFromSetupPosition = TRUE;
 -    
 +
      SendToProgram("force\n", &first);
      CopyBoard(boards[0], initial_position);
      if (blackPlaysFirst) {
@@@ -10016,7 -10300,7 +10836,7 @@@ int i, j
      timeRemaining[0][1] = whiteTimeRemaining;
      timeRemaining[1][1] = blackTimeRemaining;
      DrawPosition(FALSE, boards[currentMove]);
 -   
 +
      return TRUE;
  }
  
@@@ -10083,7 -10367,7 +10903,7 @@@ SavePart(str
  {
      static char buf[MSG_SIZ];
      char *p;
 -    
 +
      p = strchr(str, ' ');
      if (p == NULL) return str;
      strncpy(buf, str, p - str);
@@@ -10162,7 -10446,7 +10982,7 @@@ void GetOutOfBookInfo( char * buf 
                  }
  
                  sprintf( buf+strlen(buf), "%d%s. ", (idx - offset)/2 + 1, idx & 1 ? ".." : "" );
 -                sprintf( buf+strlen(buf), "%s%.2f", 
 +                sprintf( buf+strlen(buf), "%s%.2f",
                      pvInfoList[idx].score >= 0 ? "+" : "",
                      pvInfoList[idx].score / 100.0 );
              }
@@@ -10183,11 -10467,11 +11003,11 @@@ SaveGamePGN(f
      char move_buffer[100]; /* [AS] Buffer for move+PV info */
  
      offset = backwardMostMove & (~1L); /* output move numbers start at 1 */
 -    
 +
      tm = time((time_t *) NULL);
 -    
 +
      PrintPGNTags(f, &gameInfo);
 -    
 +
      if (backwardMostMove > 0 || startedFromSetupPosition) {
          char *fen = PositionToFEN(backwardMostMove, NULL);
          fprintf(f, "[FEN \"%s\"]\n[SetUp \"1\"]\n", fen);
              GetOutOfBookInfo( buf );
  
              if( buf[0] != '\0' ) {
 -                fprintf( f, "[%s \"%s\"]\n", PGN_OUT_OF_BOOK, buf ); 
 +                fprintf( f, "[%s \"%s\"]\n", PGN_OUT_OF_BOOK, buf );
              }
          }
  
                                   sprintf(buf, " %d:%02d%c", seconds/60, seconds%60, 0);
            }
  
 -            sprintf( move_buffer, "{%s%.2f/%d%s}", 
 +            sprintf( move_buffer, "{%s%.2f/%d%s}",
                  pvInfoList[i].score >= 0 ? "+" : "",
                  pvInfoList[i].score / 100.0,
                  pvInfoList[i].depth,
  
        i++;
      }
 -    
 +
      /* Start a new line */
      if (linelen > 0) fprintf(f, "\n");
  
@@@ -10338,12 -10622,12 +11158,12 @@@ SaveGameOldStyle(f
  {
      int i, offset;
      time_t tm;
 -    
 +
      tm = time((time_t *) NULL);
 -    
 +
      fprintf(f, "# %s game file -- %s", programName, ctime(&tm));
      PrintOpponents(f);
 -    
 +
      if (backwardMostMove > 0 || startedFromSetupPosition) {
        fprintf(f, "\n[--------------\n");
        PrintPosition(f, backwardMostMove);
            i++;
        }
      }
 -    
 +
      if (commentList[i] != NULL) {
        fprintf(f, "[%s]\n", commentList[i]);
      }
@@@ -10443,10 -10727,11 +11263,10 @@@ SavePosition(f, dummy, dummy2
  {
      time_t tm;
      char *fen;
      if (gameMode == EditPosition) EditPositionDone(TRUE);
      if (appData.oldSaveStyle) {
        tm = time((time_t *) NULL);
 -    
 +
        fprintf(f, "# %s position file -- %s", programName, ctime(&tm));
        PrintOpponents(f);
        fprintf(f, "[--------------\n");
@@@ -10471,7 -10756,7 +11291,7 @@@ ReloadCmailMsgEvent(unregister
      int i;
      struct stat inbuf, outbuf;
      int status;
 -    
 +
      /* Any registered moves are unregistered if unregister is set, */
      /* i.e. invoked by the signal handler */
      if (unregister) {
        outFilename = (char *) malloc(strlen(appData.cmailGameName) + 5);
        sprintf(outFilename, "%s.out", appData.cmailGameName);
      }
 -    
 +
      status = stat(outFilename, &outbuf);
      if (status < 0) {
        cmailMailedMove = FALSE;
        status = stat(inFilename, &inbuf);
        cmailMailedMove = (inbuf.st_mtime < outbuf.st_mtime);
      }
 -    
 +
      /* LoadGameFromFile(CMAIL_MAX_GAMES) with cmailMsgLoaded == TRUE
         counts the games, notes how each one terminated, etc.
 -       
 +
         It would be nice to remove this kludge and instead gather all
         the information while building the game list.  (And to keep it
         in the game list nodes instead of having a bunch of fixed-size
         */
      cmailMsgLoaded = TRUE;
      LoadGameFromFile(inFilename, CMAIL_MAX_GAMES, "", FALSE);
 -    
 +
      /* Load first game in the file or popup game menu */
      LoadGameFromFile(inFilename, 0, appData.cmailGameName, TRUE);
  
@@@ -10546,7 -10831,7 +11366,7 @@@ RegisterMove(
        cmailMoveRegistered[lastLoadGameNumber - 1] = FALSE;
        nCmailMovesRegistered --;
  
 -      if (cmailCommentList[lastLoadGameNumber - 1] != NULL) 
 +      if (cmailCommentList[lastLoadGameNumber - 1] != NULL)
          {
              free(cmailCommentList[lastLoadGameNumber - 1]);
              cmailCommentList[lastLoadGameNumber - 1] = NULL;
  
        sprintf(string,
                "%s.game.out.%d", appData.cmailGameName, lastLoadGameNumber);
 -      
 +
        f = fopen(string, "w");
        if (appData.oldSaveStyle) {
            SaveGameOldStyle(f); /* also closes the file */
 -          
 +
            sprintf(string, "%s.pos.out", appData.cmailGameName);
            f = fopen(string, "w");
            SavePosition(f, 0, NULL); /* also closes the file */
            fprintf(f, "{--------------\n");
            PrintPosition(f, currentMove);
            fprintf(f, "--------------}\n\n");
 -          
 +
            SaveGame(f, 0, NULL); /* also closes the file*/
        }
 -      
 +
        cmailMoveRegistered[lastLoadGameNumber - 1] = TRUE;
        nCmailMovesRegistered ++;
      } else if (nCmailGames == 1) {
@@@ -10651,7 -10936,7 +11471,7 @@@ MailMoveEvent(
  #endif
  
      if (! (cmailMailedMove || RegisterMove())) return;
 -    
 +
      if (   cmailMailedMove
        || (nCmailMovesRegistered + nCmailResults == nCmailGames)) {
        sprintf(string, partCommandString,
@@@ -10717,7 -11002,7 +11537,7 @@@ CmailMsg(
      char number[5];
      char string[MSG_SIZ];     /* Space for game-list */
      int  i;
 -    
 +
      if (!cmailMsgLoaded) return "";
  
      if (cmailMailedMove) {
                    sprintf(number, "%d", i + 1);
                    prependComma = 1;
                }
 -              
 +
                strcat(string, number);
            }
        }
                sprintf(cmailMsg,
                        _("Still need to make move for game\n"));
                break;
 -              
 +
              case 2:
                sprintf(cmailMsg,
                        _("Still need to make moves for both games\n"));
                break;
 -              
 +
              default:
                sprintf(cmailMsg,
                        _("Still need to make moves for all %d games\n"),
                        _("Still need to make a move for game %s\n"),
                        string);
                break;
 -              
 +
              case 0:
                if (nCmailResults == nCmailGames) {
                    sprintf(cmailMsg, _("No unfinished games\n"));
                    sprintf(cmailMsg, _("Ready to send mail\n"));
                }
                break;
 -              
 +
              default:
                sprintf(cmailMsg,
                        _("Still need to make moves for games %s\n"),
@@@ -10836,7 -11121,7 +11656,7 @@@ ExitEvent(status
      /* Kill off chess programs */
      if (first.pr != NoProc) {
        ExitAnalyzeMode();
 -        
 +
          DoSleep( appData.delayBeforeQuit );
        SendToProgram("quit\n", &first);
          DoSleep( appData.delayAfterQuit );
@@@ -10874,7 -11159,7 +11694,7 @@@ PauseEvent(
            DisplayBothClocks();
        }
        if (gameMode == PlayFromGameFile) {
 -          if (appData.timeDelay >= 0) 
 +          if (appData.timeDelay >= 0)
                AutoPlayGameLoop();
        } else if (gameMode == IcsExamining && pauseExamInvalid) {
            Reset(FALSE, TRUE);
@@@ -11013,10 -11298,10 +11833,10 @@@ MachineWhiteEvent(
        return;
  
  
 -    if (gameMode == PlayFromGameFile || 
 -      gameMode == TwoMachinesPlay  || 
 -      gameMode == Training         || 
 -      gameMode == AnalyzeMode      || 
 +    if (gameMode == PlayFromGameFile ||
 +      gameMode == TwoMachinesPlay  ||
 +      gameMode == Training         ||
 +      gameMode == AnalyzeMode      ||
        gameMode == EndOfGame)
        EditGameEvent();
  
        DisplayError(_("It is not White's turn"), 0);
        return;
      }
 -  
 +
      if (gameMode == AnalyzeMode || gameMode == AnalyzeFile)
        ExitAnalyzeMode();
  
 -    if (gameMode == EditGame || gameMode == AnalyzeMode || 
 +    if (gameMode == EditGame || gameMode == AnalyzeMode ||
        gameMode == AnalyzeFile)
        TruncateGame();
  
      if(bookHit) { // [HGM] book: simulate book reply
        static char bookMove[MSG_SIZ]; // a bit generous?
  
 -      programStats.nodes = programStats.depth = programStats.time = 
 +      programStats.nodes = programStats.depth = programStats.time =
        programStats.score = programStats.got_only_move = 0;
        sprintf(programStats.movelist, "%s (xbook)", bookHit);
  
  void
  MachineBlackEvent()
  {
 -    char buf[MSG_SIZ];
 -   char *bookHit = NULL;
 -
 -    if (appData.noChessProgram || (gameMode == MachinePlaysBlack))
 -      return;
 -
 -
 -    if (gameMode == PlayFromGameFile || 
 -      gameMode == TwoMachinesPlay  || 
 -      gameMode == Training         || 
 -      gameMode == AnalyzeMode      || 
 -      gameMode == EndOfGame)
 -        EditGameEvent();
 -
 -    if (gameMode == EditPosition) 
 -        EditPositionDone(TRUE);
 -
 -    if (WhiteOnMove(currentMove)) {
 -      DisplayError(_("It is not Black's turn"), 0);
 -      return;
 +  char buf[MSG_SIZ];
 +  char *bookHit = NULL;
 +  
 +  if (appData.noChessProgram || (gameMode == MachinePlaysBlack))
 +    return;
 +  
 +  
 +  if (gameMode == PlayFromGameFile 
 +      || gameMode == TwoMachinesPlay  
 +      || gameMode == Training     
 +      || gameMode == AnalyzeMode
 +      || gameMode == EndOfGame)
 +    EditGameEvent();
 +  
 +  if (gameMode == EditPosition) 
 +    EditPositionDone(TRUE);
 +  
 +  if (WhiteOnMove(currentMove)) 
 +    {
 +      DisplayError(_("It is not Black's turn"), 0);
 +      return;
      }
 -    
 -    if (gameMode == AnalyzeMode || gameMode == AnalyzeFile)
 -      ExitAnalyzeMode();
 -
 -    if (gameMode == EditGame || gameMode == AnalyzeMode || 
 -      gameMode == AnalyzeFile)
 -      TruncateGame();
 -
 -    ResurrectChessProgram();  /* in case it isn't running */
 -    gameMode = MachinePlaysBlack;
 -    pausing = FALSE;
 -    ModeHighlight();
 -    SetGameInfo();
 -    sprintf(buf, "%s vs. %s", gameInfo.white, gameInfo.black);
 -    DisplayTitle(buf);
 -    if (first.sendName) {
 +  
 +  if (gameMode == AnalyzeMode || gameMode == AnalyzeFile)
 +    ExitAnalyzeMode();
 +  
 +  if (gameMode == EditGame || gameMode == AnalyzeMode 
 +      || gameMode == AnalyzeFile)
 +    TruncateGame();
 +  
 +  ResurrectChessProgram();    /* in case it isn't running */
 +  gameMode = MachinePlaysBlack;
 +  pausing  = FALSE;
 +  ModeHighlight();
 +  SetGameInfo();
 +  sprintf(buf, "%s vs. %s", gameInfo.white, gameInfo.black);
 +  DisplayTitle(buf);
 +  if (first.sendName) 
 +    {
        sprintf(buf, "name %s\n", gameInfo.white);
        SendToProgram(buf, &first);
      }
 -    if (first.sendTime) {
 -      if (first.useColors) {
 -      SendToProgram("white\n", &first); /*gnu kludge*/
 -      }
 +  if (first.sendTime) 
 +    {
 +      if (first.useColors) 
 +      {
 +        SendToProgram("white\n", &first); /*gnu kludge*/
 +      }
        SendTimeRemaining(&first, FALSE);
      }
 -    if (first.useColors) {
 +  if (first.useColors) 
 +    {
        SendToProgram("black\n", &first); // [HGM] book: 'go' sent separately
      }
 -    bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move
 -    SetMachineThinkingEnables();
 -    first.maybeThinking = TRUE;
 -    StartClocks();
 -
 -    if (appData.autoFlipView && flipView) {
 +  bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move
 +  SetMachineThinkingEnables();
 +  first.maybeThinking = TRUE;
 +  StartClocks();
 +  
 +  if (appData.autoFlipView && flipView) 
 +    {
        flipView = !flipView;
        DrawPosition(FALSE, NULL);
        DisplayBothClocks();       // [HGM] logo: clocks might have to be exchanged;
      }
 -    if(bookHit) { // [HGM] book: simulate book reply
 -      static char bookMove[MSG_SIZ]; // a bit generous?
 -
 -      programStats.nodes = programStats.depth = programStats.time = 
 -      programStats.score = programStats.got_only_move = 0;
 -      sprintf(programStats.movelist, "%s (xbook)", bookHit);
 -
 -      strcpy(bookMove, "move ");
 -      strcat(bookMove, bookHit);
 -      HandleMachineMove(bookMove, &first);
 +  if(bookHit) 
 +    { // [HGM] book: simulate book reply
 +      static char bookMove[MSG_SIZ]; // a bit generous?
 +      
 +      programStats.nodes = programStats.depth = programStats.time 
 +      = programStats.score = programStats.got_only_move = 0;
 +      sprintf(programStats.movelist, "%s (xbook)", bookHit);
 +      
 +      strcpy(bookMove, "move ");
 +      strcat(bookMove, bookHit);
 +      HandleMachineMove(bookMove, &first);
      }
 +  return;
  }
  
  
@@@ -11197,7 -11474,7 +12017,7 @@@ TwoMachinesEvent P((void)
      char buf[MSG_SIZ];
      ChessProgramState *onmove;
      char *bookHit = NULL;
 -    
 +
      if (appData.noChessProgram) return;
  
      switch (gameMode) {
      if(bookHit) { // [HGM] book: simulate book reply
        static char bookMove[MSG_SIZ]; // a bit generous?
  
 -      programStats.nodes = programStats.depth = programStats.time = 
 +      programStats.nodes = programStats.depth = programStats.time =
        programStats.score = programStats.got_only_move = 0;
        sprintf(programStats.movelist, "%s (xbook)", bookHit);
  
@@@ -11363,7 -11640,7 +12183,7 @@@ IcsClientEvent(
        case AnalyzeFile:
        ExitAnalyzeMode();
        break;
 -      
 +
        default:
        EditGameEvent();
        break;
@@@ -11428,7 -11705,7 +12248,7 @@@ EditGameEvent(
        default:
        return;
      }
 -    
 +
      pausing = FALSE;
      StopClocks();
      first.offeredDraw = second.offeredDraw = 0;
            whiteFlag = blackFlag = 0;
        }
        DisplayTitle("");
 -    }         
 -    
 +    }
 +
      gameMode = EditGame;
      ModeHighlight();
      SetGameInfo();
@@@ -11470,16 -11747,16 +12290,16 @@@ EditPositionEvent(
        EditGameEvent();
        return;
      }
 -    
 +
      EditGameEvent();
      if (gameMode != EditGame) return;
 -    
 +
      gameMode = EditPosition;
      ModeHighlight();
      SetGameInfo();
      if (currentMove > 0)
        CopyBoard(boards[0], boards[currentMove]);
 -    
 +
      blackPlaysFirst = !WhiteOnMove(currentMove);
      ResetClocks();
      currentMove = forwardMostMove = backwardMostMove = 0;
@@@ -11569,7 -11846,7 +12389,7 @@@ SendMultiLineToICS(buf
      len = strlen(buf);
      if (len > MSG_SIZ)
        len = MSG_SIZ;
 -  
 +
      strncpy(temp, buf, len);
      temp[len] = 0;
  
@@@ -11692,7 -11969,7 +12512,7 @@@ EditPositionMenuEvent(selection, x, y
             piece > (int)BlackMan && piece <= (int)BlackKing   ) {
              selection = (ChessSquare) (DEMOTED piece);
          } else if(piece == EmptySquare) selection = BlackSilver;
 -        else selection = (ChessSquare)((int)piece + 1);       
 +        else selection = (ChessSquare)((int)piece + 1);
          goto defaultlabel;
  
        case WhiteQueen:
                  int n;
                  if(x == BOARD_LEFT-2 && selection >= BlackPawn) {
                      n = PieceToNumber(selection - BlackPawn);
-                     if(n > gameInfo.holdingsSize) { n = 0; selection = BlackPawn; }
+                     if(n >= gameInfo.holdingsSize) { n = 0; selection = BlackPawn; }
                      boards[0][BOARD_HEIGHT-1-n][0] = selection;
                      boards[0][BOARD_HEIGHT-1-n][1]++;
                  } else
                  if(x == BOARD_RGHT+1 && selection < BlackPawn) {
                      n = PieceToNumber(selection);
-                     if(n > gameInfo.holdingsSize) { n = 0; selection = WhitePawn; }
+                     if(n >= gameInfo.holdingsSize) { n = 0; selection = WhitePawn; }
                      boards[0][n][BOARD_WIDTH-1] = selection;
                      boards[0][n][BOARD_WIDTH-2]++;
                  }
  AcceptEvent()
  {
      /* Accept a pending offer of any kind from opponent */
 -    
 +
      if (appData.icsActive) {
          SendToICS(ics_prefix);
        SendToICS("accept\n");
  DeclineEvent()
  {
      /* Decline a pending offer of any kind from opponent */
 -    
 +
      if (appData.icsActive) {
          SendToICS(ics_prefix);
        SendToICS("decline\n");
  DrawEvent()
  {
      /* Offer draw or accept pending draw offer from opponent */
 -    
 +
      if (appData.icsActive) {
        /* Note: tournament rules require draw offers to be
           made after you make your move but before you punch
           your clock.  Currently ICS doesn't let you do that;
           instead, you immediately punch your clock after making
           a move, but you can offer a draw at any time. */
 -      
 +
          SendToICS(ics_prefix);
        SendToICS("draw\n");
+         userOfferedDraw = TRUE; // [HGM] drawclaim: also set flag in ICS play
      } else if (cmailMsgLoaded) {
        if (currentMove == cmailOldMove &&
            commentList[cmailOldMove] != NULL &&
  AdjournEvent()
  {
      /* Offer Adjourn or accept pending Adjourn offer from opponent */
 -    
 +
      if (appData.icsActive) {
          SendToICS(ics_prefix);
        SendToICS("adjourn\n");
  AbortEvent()
  {
      /* Offer Abort or accept pending Abort offer from opponent */
 -    
 +
      if (appData.icsActive) {
          SendToICS(ics_prefix);
        SendToICS("abort\n");
  ResignEvent()
  {
      /* Resign.  You can do this even if it's not your turn. */
 -    
 +
      if (appData.icsActive) {
          SendToICS(ics_prefix);
        SendToICS("resign\n");
@@@ -12014,12 -12292,12 +12835,12 @@@ ForwardInner(target
  
      if (gameMode == PlayFromGameFile && !pausing)
        PauseEvent();
 -    
 +
      if (gameMode == IcsExamining && pausing)
        limit = pauseExamForwardMostMove;
      else
        limit = forwardMostMove;
 -    
 +
      if (target > limit) target = limit;
  
      if (target > 0 && moveList[target - 1][0]) {
            }
        }
      }
 -    if (gameMode == EditGame || gameMode == AnalyzeMode || 
 -      gameMode == Training || gameMode == PlayFromGameFile || 
 +    if (gameMode == EditGame || gameMode == AnalyzeMode ||
 +      gameMode == Training || gameMode == PlayFromGameFile ||
        gameMode == AnalyzeFile) {
        while (currentMove < target) {
            SendMoveToProgram(currentMove++, &first);
      } else {
        currentMove = target;
      }
 -    
 +
      if (gameMode == EditGame || gameMode == EndOfGame) {
        whiteTimeRemaining = timeRemaining[0][currentMove];
        blackTimeRemaining = timeRemaining[1][currentMove];
@@@ -12083,13 -12361,13 +12904,13 @@@ ToEndEvent(
        /* to optimze, we temporarily turn off analysis mode while we feed
         * the remaining moves to the engine. Otherwise we get analysis output
         * after each move.
 -       */ 
 +       */
          if (first.analysisSupport) {
          SendToProgram("exit\nforce\n", &first);
          first.analyzing = FALSE;
        }
      }
 -      
 +
      if (gameMode == IcsExamining && !pausing) {
          SendToICS(ics_prefix);
        SendToICS("forward 999999\n");
@@@ -12124,7 -12402,7 +12945,7 @@@ BackwardInner(target
      }
      if (gameMode == PlayFromGameFile && !pausing)
        PauseEvent();
 -    
 +
      if (moveList[target][0]) {
        int fromX, fromY, toX, toY;
          toX = moveList[target][2] - AAA;
      } else {
        currentMove = target;
      }
 -    
 +
      if (gameMode == EditGame || gameMode == EndOfGame) {
        whiteTimeRemaining = timeRemaining[0][currentMove];
        blackTimeRemaining = timeRemaining[1][currentMove];
@@@ -12183,7 -12461,7 +13004,7 @@@ ToStartEvent(
      if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
        /* to optimize, we temporarily turn off analysis mode while we undo
         * all the moves. Otherwise we get analysis output after each undo.
 -       */ 
 +       */
          if (first.analysisSupport) {
          SendToProgram("exit\nforce\n", &first);
          first.analyzing = FALSE;
@@@ -12408,7 -12686,7 +13229,7 @@@ PrintPosition(fp, move
       int move;
  {
      int i, j;
 -    
 +
      for (i = BOARD_HEIGHT - 1; i >= 0; i--) {
          for (j = BOARD_LEFT; j < BOARD_RGHT; j++) {
            char c = PieceToChar(boards[move][i][j]);
@@@ -12786,18 -13064,18 +13607,18 @@@ SendToProgram(message, cps
  
      if (cps->pr == NULL) return;
      Attention(cps);
 -    
 +
      if (appData.debugMode) {
        TimeMark now;
        GetTimeMark(&now);
 -      fprintf(debugFP, "%ld >%-6s: %s", 
 +      fprintf(debugFP, "%ld >%-6s: %s",
                SubtractTimeMarks(&now, &programStartTime),
                cps->which, message);
      }
 -    
 +
      count = strlen(message);
      outCount = OutputToProcess(cps->pr, message, count, &error);
 -    if (outCount < count && !exiting 
 +    if (outCount < count && !exiting
                           && !endingGame) { /* [HGM] crash: to not hang GameEnds() writing to deceased engines */
        sprintf(buf, _("Error writing to %s chess program"), cps->which);
          if(gameInfo.resultDetails==NULL) { /* [HGM] crash: if game in progress, give reason for abort */
@@@ -12858,12 -13136,12 +13679,12 @@@ ReceiveFromProgram(isr, closure, messag
        }
        return;
      }
 -    
 +
      if ((end_str = strchr(message, '\r')) != NULL)
        *end_str = NULLCHAR;
      if ((end_str = strchr(message, '\n')) != NULL)
        *end_str = NULLCHAR;
 -    
 +
      if (appData.debugMode) {
        TimeMark now; int print = 1;
        char *quote = ""; char c; int i;
        if(appData.engineComments != 1) { /* [HGM] debug: decide if protocol-violating output is written */
                char start = message[0];
                if(start >='A' && start <= 'Z') start += 'a' - 'A'; // be tolerant to capitalizing
 -              if(sscanf(message, "%d%c%d%d%d", &i, &c, &i, &i, &i) != 5 && 
 +              if(sscanf(message, "%d%c%d%d%d", &i, &c, &i, &i, &i) != 5 &&
                   sscanf(message, "move %c", &c)!=1  && sscanf(message, "offer%c", &c)!=1 &&
                   sscanf(message, "resign%c", &c)!=1 && sscanf(message, "feature %c", &c)!=1 &&
                   sscanf(message, "error %c", &c)!=1 && sscanf(message, "illegal %c", &c)!=1 &&
        }
        if(print) {
                GetTimeMark(&now);
 -              fprintf(debugFP, "%ld <%-6s: %s%s\n", 
 -                      SubtractTimeMarks(&now, &programStartTime), cps->which, 
 +              fprintf(debugFP, "%ld <%-6s: %s%s\n",
 +                      SubtractTimeMarks(&now, &programStartTime), cps->which,
                        quote,
                        message);
        }
      /* [DM] if icsEngineAnalyze is active we block all whisper and kibitz output, because nobody want to see this */
      if (appData.icsEngineAnalyze) {
          if (strstr(message, "whisper") != NULL ||
 -             strstr(message, "kibitz") != NULL || 
 +             strstr(message, "kibitz") != NULL ||
              strstr(message, "tellics") != NULL) return;
      }
  
@@@ -12971,7 -13249,7 +13792,7 @@@ SendTimeControl(cps, mps, tc, inc, sd, 
  ChessProgramState *WhitePlayer()
  /* [HGM] return pointer to 'first' or 'second', depending on who plays white */
  {
 -    if(gameMode == TwoMachinesPlay && first.twoMachinesColor[0] == 'b' || 
 +    if(gameMode == TwoMachinesPlay && first.twoMachinesColor[0] == 'b' ||
         gameMode == BeginningOfGame || gameMode == MachinePlaysBlack)
          return &second;
      return &first;
@@@ -13004,7 -13282,7 +13825,7 @@@ SendTimeRemaining(cps, machineWhite
  
      if (time <= 0) time = 1;
      if (otime <= 0) otime = 1;
 -    
 +
      sprintf(message, "time %ld\n", time);
      SendToProgram(message, cps);
  
@@@ -13076,7 -13354,7 +13897,7 @@@ StringFeature(p, name, loc, cps
    return FALSE;
  }
  
 -int 
 +int
  ParseOption(Option *opt, ChessProgramState *cps)
  // [HGM] options: process the string that defines an engine option, and determine
  // name, type, default value, and allowed value range
@@@ -13171,7 -13449,7 +13992,7 @@@ FeatureDone(cps, val
  void
  ParseFeatures(args, cps)
       char* args;
 -     ChessProgramState *cps;  
 +     ChessProgramState *cps;
  {
    char *p = args;
    char *q;
      if (*p == NULLCHAR) return;
  
      if (BoolFeature(&p, "setboard", &cps->useSetboard, cps)) continue;
 -    if (BoolFeature(&p, "time", &cps->sendTime, cps)) continue;    
 -    if (BoolFeature(&p, "draw", &cps->sendDrawOffers, cps)) continue;    
 -    if (BoolFeature(&p, "sigint", &cps->useSigint, cps)) continue;    
 -    if (BoolFeature(&p, "sigterm", &cps->useSigterm, cps)) continue;    
 +    if (BoolFeature(&p, "time", &cps->sendTime, cps)) continue;
 +    if (BoolFeature(&p, "draw", &cps->sendDrawOffers, cps)) continue;
 +    if (BoolFeature(&p, "sigint", &cps->useSigint, cps)) continue;
 +    if (BoolFeature(&p, "sigterm", &cps->useSigterm, cps)) continue;
      if (BoolFeature(&p, "reuse", &val, cps)) {
        /* Engine can disable reuse, but can't enable it if user said no */
        if (!val) cps->reuse = FALSE;
@@@ -13325,7 -13603,7 +14146,7 @@@ ShowThinkingEvent(
      int newState = appData.showThinking
        // [HGM] thinking: other features now need thinking output as well
        || !appData.hideThinkingFromHuman || appData.adjudicateLossThreshold != 0 || EngineOutputIsUp();
 -    
 +
      if (oldState == newState) return;
      oldState = newState;
      if (gameMode == EditPosition) EditPositionDone(TRUE);
@@@ -13362,8 -13640,8 +14183,8 @@@ DisplayMove(moveNumber
      char cpThinkOutput[MSG_SIZ];
  
      if(appData.noGUI) return; // [HGM] fast: suppress display of moves
 -    
 -    if (moveNumber == forwardMostMove - 1 || 
 +
 +    if (moveNumber == forwardMostMove - 1 ||
        gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
  
        safeStrCpy(cpThinkOutput, thinkOutput, sizeof(cpThinkOutput));
@@@ -13419,6 -13697,7 +14240,6 @@@ DisplayComment(moveNumber, text
      char title[MSG_SIZ];
      char buf[8000]; // comment can be long!
      int score, depth;
 -    
      if (moveNumber < 0 || parseList[moveNumber][0] == NULLCHAR) {
        strcpy(title, "Comment");
      } else {
        text = buf;
      }
      if (text != NULL && (appData.autoDisplayComment || commentUp))
 -        CommentPopUp(title, text);
 +      CommentPopUp(title, text);
  }
  
  /* This routine sends a ^C interrupt to gnuchess, to awaken it if it
@@@ -13574,7 -13853,7 +14395,7 @@@ GetTimeMark(tm
      struct timezone timeZone;
  
      gettimeofday(&timeVal, &timeZone);
 -    tm->sec = (long) timeVal.tv_sec; 
 +    tm->sec = (long) timeVal.tv_sec;
      tm->ms = (int) (timeVal.tv_usec / 1000L);
  
  #else /*!HAVE_GETTIMEOFDAY*/
@@@ -13613,7 -13892,7 +14434,7 @@@ SubtractTimeMarks(tm2, tm1
   * We give the human user a slight advantage if he is playing white---the
   * clocks don't run until he makes his first move, so it takes zero time.
   * Also, we don't account for network lag, so we could get out of sync
 - * with GNU Chess's clock -- but then, referees are always right.  
 + * with GNU Chess's clock -- but then, referees are always right.
   */
  
  static TimeMark tickStartTM;
@@@ -13646,7 -13925,7 +14467,7 @@@ AdjustClock(Boolean which, int dir
  
  /* Stop clocks and reset to a fresh time control */
  void
 -ResetClocks() 
 +ResetClocks()
  {
      (void) StopClockTimer();
      if (appData.icsActive) {
@@@ -13677,7 -13956,7 +14498,7 @@@ DecrementClocks(
  
      if (!appData.clockMode) return;
      if (gameMode==AnalyzeMode || gameMode == AnalyzeFile) return;
 -      
 +
      GetTimeMark(&now);
  
      lastTickLength = SubtractTimeMarks(&now, &tickStartTM);
      }
  
      if (CheckFlags()) return;
 -      
 +
      tickStartTM = now;
      intendedTickLength = NextTickLength(timeRemaining - fudge) + fudge;
      StartClockTimer(intendedTickLength);
      /* if the time remaining has fallen below the alarm threshold, sound the
       * alarm. if the alarm has sounded and (due to a takeback or time control
       * with increment) the time remaining has increased to a level above the
 -     * threshold, reset the alarm so it can sound again. 
 +     * threshold, reset the alarm so it can sound again.
       */
 -    
 +
      if (appData.icsActive && appData.icsAlarm) {
  
        /* make sure we are dealing with the user's clock */
  
        if (alarmSounded && (timeRemaining > appData.icsAlarmTime)) {
            alarmSounded = FALSE;
 -      } else if (!alarmSounded && (timeRemaining <= appData.icsAlarmTime)) { 
 +      } else if (!alarmSounded && (timeRemaining <= appData.icsAlarmTime)) {
            PlayAlarmSound();
            alarmSounded = TRUE;
        }
@@@ -13758,7 -14037,7 +14579,7 @@@ SwitchClocks(
           whiteTimeRemaining -= lastTickLength;
             /* [HGM] PGNtime: save time for PGN file if engine did not give it */
  //         if(pvInfoList[forwardMostMove-1].time == -1)
 -                 pvInfoList[forwardMostMove-1].time = 
 +                 pvInfoList[forwardMostMove-1].time =
                        (timeRemaining[0][forwardMostMove-1] - whiteTimeRemaining)/10;
        }
        flagged = CheckFlags();
        whiteTimeRemaining : blackTimeRemaining);
      StartClockTimer(intendedTickLength);
  }
 -      
 +
  
  /* Stop both clocks */
  void
  StopClocks()
 -{     
 +{
      long lastTickLength;
      TimeMark now;
  
      }
      CheckFlags();
  }
 -      
 +
  /* Start clock of player on move.  Time may have been reset, so
     if clock is already running, stop and restart it. */
  void
@@@ -13838,7 -14117,7 +14659,7 @@@ StartClocks(
        whiteTimeRemaining : blackTimeRemaining);
  
     /* [HGM] nps: figure out nps factors, by determining which engine plays white and/or black once and for all */
 -    whiteNPS = blackNPS = -1; 
 +    whiteNPS = blackNPS = -1;
      if(gameMode == MachinePlaysWhite || gameMode == TwoMachinesPlay && first.twoMachinesColor[0] == 'w'
         || appData.zippyPlay && gameMode == IcsPlayingBlack) // first (perhaps only) engine has white
        whiteNPS = first.nps;
@@@ -13861,7 -14140,7 +14682,7 @@@ TimeString(ms
      long second, minute, hour, day;
      char *sign = "";
      static char buf[32];
 -    
 +
      if (ms > 0 && ms <= 9900) {
        /* convert milliseconds to tenths, rounding up */
        double tenths = floor( ((double)(ms + 99L)) / 100.00 );
        sign = "-";
        second = -second;
      }
 -    
 +
      day = second / (60 * 60 * 24);
      second = second % (60 * 60 * 24);
      hour = second / (60 * 60);
      second = second % (60 * 60);
      minute = second / 60;
      second = second % 60;
 -    
 +
      if (day > 0)
        sprintf(buf, " %s%ld:%02ld:%02ld:%02ld ",
              sign, day, hour, minute, second);
        sprintf(buf, " %s%ld:%02ld:%02ld ", sign, hour, minute, second);
      else
        sprintf(buf, " %s%2ld:%02ld ", sign, minute, second);
 -    
 +
      return buf;
  }
  
@@@ -13907,13 -14186,13 +14728,13 @@@ StrStr(string, match
       char *string, *match;
  {
      int i, length;
 -    
 +
      length = strlen(match);
 -    
 +
      for (i = strlen(string) - length; i >= 0; i--, string++)
        if (!strncmp(match, string, length))
        return string;
 -    
 +
      return NULL;
  }
  
@@@ -13922,9 -14201,9 +14743,9 @@@ StrCaseStr(string, match
       char *string, *match;
  {
      int i, j, length;
 -    
 +
      length = strlen(match);
 -    
 +
      for (i = strlen(string) - length; i >= 0; i--, string++) {
        for (j = 0; j < length; j++) {
            if (ToLower(match[j]) != ToLower(string[j]))
@@@ -13942,7 -14221,7 +14763,7 @@@ StrCaseCmp(s1, s2
       char *s1, *s2;
  {
      char c1, c2;
 -    
 +
      for (;;) {
        c1 = ToLower(*s1++);
        c2 = ToLower(*s2++);
@@@ -14042,7 -14321,7 +14863,7 @@@ PositionToFEN(move, overrideCastling
                      /* [HGM] write promoted pieces as '+<unpromoted>' (Shogi) */
                      *p++ = '+';
                      piece = (ChessSquare)(DEMOTED piece);
 -                } 
 +                }
                  *p++ = PieceToChar(piece);
                  if(p[-1] == '~') {
                      /* [HGM] flag promoted pieces as '<promoted>~' (Crazyhouse) */
      }
      /* Fullmove number */
      sprintf(p, "%d", (move / 2) + 1);
 -    
 +
      return StrSave(buf);
  }
  
@@@ -14282,7 -14561,7 +15103,7 @@@ ParseFEN(board, blackPlaysFirst, fen
        case 'w':
          *blackPlaysFirst = FALSE;
        break;
 -      case 'b': 
 +      case 'b':
        *blackPlaysFirst = TRUE;
        break;
        default:
  
      return TRUE;
  }
 -      
 +
  void
  EditPositionPasteFEN(char *fen)
  {
diff --combined configure.ac
@@@ -28,7 -28,7 +28,8 @@@ dnl| to regenerate configure.  Then sub
  dnl| the standard version of xboard.
  
  dnl| define second argument as VERSION.PATCHLEVEL. e.g. 4.4.0j
 -AC_INIT([xboard],[master-20100118],[bug-xboard@gnu.org])
 +AC_INIT([xboard],[gtk-20100118],[bug-xboard@gnu.org])
++
  AM_INIT_AUTOMAKE
  
  AC_CONFIG_HEADERS([config.h])
@@@ -88,10 -88,6 +89,10 @@@ AC_SUBST(NROFFFLAGS
  AC_PATH_PROGS(AWKPATH, awk mawk gawk nawk)
  AC_PATH_PROGS(PERLPATH, perl)
  
 +PKG_CHECK_MODULES([GTK], [gtk+-2.0 >= 2.16.0 gmodule-export-2.0 ])
 +AC_SUBST(GTK_CFLAGS)
 +AC_SUBST(GTK_LIBS)
 +
  AC_HEADER_STDC
  AC_HEADER_TIME
  AC_HEADER_SYS_WAIT
@@@ -432,6 -428,9 +433,9 @@@ echo "
  echo " Configurations summary:"
  echo ""
  echo "        prefix:          $prefix"
+ echo "        datarootdir:     $datarootdir"
+ echo "        infodir:         $infodir"
+ echo "        sysconfdir:      $sysconfdir"
  echo ""
  echo "        Xaw3d:           $with_xaw3d"
  echo ""
diff --combined frontend.h
@@@ -55,7 -55,6 +55,7 @@@
  #define _FRONTEND
  
  #include <stdio.h>
 +#include <glib.h>
  
  typedef VOIDSTAR ProcRef;
  #define NoProc ((ProcRef) 0)
@@@ -91,6 -90,10 +91,10 @@@ void CommentPopDown P((void))
  void EditCommentPopUp P((int index, String title, String text));
  void ErrorPopDown P((void));
  int  EventToSquare P((int x, int limit));
+ void DrawSeekAxis P(( int x, int y, int xTo, int yTo ));
+ void DrawSeekBackground P(( int left, int top, int right, int bottom ));
+ void DrawSeekText P((char *buf, int x, int y));
+ void DrawSeekDot P((int x, int y, int color));
  
  void RingBell P((void));
  void PlayIcsWinSound P((void));
@@@ -118,7 -121,7 +122,7 @@@ void StartLoadGameTimer P((long millise
  void AutoSaveGame P((void));
  
  typedef void (*DelayedEventCallback) P((void));
 -void ScheduleDelayedEvent P((DelayedEventCallback cb, long millisec));
 +void ScheduleDelayedEvent P((DelayedEventCallback cb, guint millisec));
  DelayedEventCallback GetDelayedEvent P((void));
  void CancelDelayedEvent P((void));
  // [HGM] mouse: next six used by mouse handler, which was moved to backend
@@@ -128,6 -131,7 +132,7 @@@ void PromotionPopUp P((void))
  void DragPieceBegin P((int x, int y));
  void DragPieceEnd P((int x, int y));
  void LeftClick P((ClickType c, int x, int y));
+ int  RightClick P((ClickType c, int x, int y, int *col, int *row));
  
  int StartChildProcess P((char *cmdLine, char *dir, ProcRef *pr));
  void DestroyChildProcess P((ProcRef pr, int/*boolean*/ signal));
@@@ -156,6 -160,14 +161,14 @@@ void CmailSigHandlerCallBack P((InputSo
  
  extern ProcRef cmailPR;
  
+ /* in xgamelist.c or winboard.c */
+ void GLT_ClearList();
+ void GLT_DeSelectList();
+ void GLT_AddToList( char *name );
+ Boolean GLT_GetFromList( int index, char *name );
+ extern char lpUserGLT[];
  /* these are in wgamelist.c */
  void GameListPopUp P((FILE *fp, char *filename));
  void GameListPopDown P((void));
diff --combined xboard.c
+++ b/xboard.c
@@@ -1,8 -1,8 +1,8 @@@
--/*
++Xg/*
   * xboard.c -- X front end for XBoard
   *
   * Copyright 1991 by Digital Equipment Corporation, Maynard,
 - * Massachusetts. 
 + * Massachusetts.
   *
   * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
   * 2007, 2008, 2009 Free Software Foundation, Inc.
@@@ -185,10 -185,6 +185,10 @@@ extern char *getenv()
  #include "bitmaps/bitmaps.h"
  #endif
  
 +#include <gtk/gtk.h>
 +#include <gdk/gdk.h>
 +#include <gdk-pixbuf/gdk-pixbuf.h>
 +
  #include "bitmaps/icon_white.bm"
  #include "bitmaps/icon_black.bm"
  #include "bitmaps/checkmark.bm"
  #include "xhistory.h"
  #include "xedittags.h"
  #include "gettext.h"
 +#include "callback.h"
 +#include "interface.h"
  
  // must be moved to xengineoutput.h
  
@@@ -238,13 -232,6 +238,13 @@@ typedef struct 
      MenuItem *mi;
  } Menu;
  
 +typedef struct {
 +    char *name;
 +    gboolean value;
 +} Enables;
 +
 +
 +
  int main P((int argc, char **argv));
  RETSIGTYPE CmailSigHandler P((int sig));
  RETSIGTYPE IntSigHandler P((int sig));
@@@ -255,23 -242,45 +255,23 @@@ void CreateXPMPieces P((void))
  void CreatePieces P((void));
  void CreatePieceMenus P((void));
  Widget CreateMenuBar P((Menu *mb));
 -Widget CreateButtonBar P ((MenuItem *mi));
  char *FindFont P((char *pattern, int targetPxlSize));
  void PieceMenuPopup P((Widget w, XEvent *event,
                       String *params, Cardinal *num_params));
  static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
  static void DropMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
 -void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[],
 -                 u_int wreq, u_int hreq));
 -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 HandleUserMove P((Widget w, XEvent *event,
 -                   String *prms, Cardinal *nprms));
  void AnimateUserMove P((Widget w, XEvent * event,
                     String * params, Cardinal * nParams));
  void HandlePV P((Widget w, XEvent * event,
                     String * params, Cardinal * nParams));
 -void WhiteClock P((Widget w, XEvent *event,
 -                 String *prms, Cardinal *nprms));
 -void BlackClock P((Widget w, XEvent *event,
 -                 String *prms, Cardinal *nprms));
 -void DrawPositionProc P((Widget w, XEvent *event,
 -                   String *prms, Cardinal *nprms));
 -void XDrawPosition P((Widget w, /*Boolean*/int repaint,
 -                   Board board));
  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,
 -                    FileProc proc, char *openMode));
 -void FileNamePopDown P((void));
 -void FileNameCallback P((Widget w, XtPointer client_data,
 -                       XtPointer call_data));
 -void FileNameAction P((Widget w, XEvent *event,
 -                     String *prms, Cardinal *nprms));
  void AskQuestionReplyAction P((Widget w, XEvent *event,
                          String *prms, Cardinal *nprms));
  void AskQuestionProc P((Widget w, XEvent *event,
@@@ -284,23 -293,136 +284,23 @@@ 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));
 -void LoadNextGameProc P((Widget w, XEvent *event, String *prms,
 -                       Cardinal *nprms));
 -void LoadPrevGameProc P((Widget w, XEvent *event, String *prms,
 -                       Cardinal *nprms));
 -void ReloadGameProc P((Widget w, XEvent *event, String *prms,
 -                     Cardinal *nprms));
 -void LoadPositionProc P((Widget w, XEvent *event,
 -                       String *prms, Cardinal *nprms));
 -void LoadNextPositionProc P((Widget w, XEvent *event, String *prms,
 -                       Cardinal *nprms));
 -void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms,
 -                       Cardinal *nprms));
 -void ReloadPositionProc P((Widget w, XEvent *event, String *prms,
 -                     Cardinal *nprms));
  void CopyPositionProc P((Widget w, XEvent *event, String *prms,
                         Cardinal *nprms));
  void PastePositionProc P((Widget w, XEvent *event, String *prms,
                          Cardinal *nprms));
  void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms,
                            Cardinal *nprms));
 -void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void MachineBlackProc P((Widget w, XEvent *event, String *prms,
 -                       Cardinal *nprms));
 -void MachineWhiteProc P((Widget w, XEvent *event,
 -                       String *prms, Cardinal *nprms));
 -void AnalyzeModeProc P((Widget w, XEvent *event,
 -                       String *prms, Cardinal *nprms));
 -void AnalyzeFileProc P((Widget w, XEvent *event,
 -                       String *prms, Cardinal *nprms));
 -void TwoMachinesProc 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));
 -void EditPositionProc P((Widget w, XEvent *event,
 -                       String *prms, Cardinal *nprms));
 -void TrainingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  void EditCommentProc P((Widget w, XEvent *event,
                        String *prms, Cardinal *nprms));
  void IcsInputBoxProc P((Widget w, XEvent *event,
                        String *prms, Cardinal *nprms));
 -void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void RematchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -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 EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void StopObservingProc P((Widget w, XEvent *event, String *prms,
 -                        Cardinal *nprms));
 -void StopExaminingProc P((Widget w, XEvent *event, String *prms,
 -                        Cardinal *nprms));
 -void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void TruncateGameProc P((Widget w, XEvent *event, String *prms,
 -                       Cardinal *nprms));
 -void RetractMoveProc P((Widget w, XEvent *event, String *prms,
 -                      Cardinal *nprms));
 -void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void AlwaysQueenProc P((Widget w, XEvent *event, String *prms,
 -                      Cardinal *nprms));
 -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 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 PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
 -                       Cardinal *nprms));
 -void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
 -                         Cardinal *nprms));
 -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 ShowCoordsProc P((Widget w, XEvent *event, String *prms,
 -                     Cardinal *nprms));
 -void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
 -                       Cardinal *nprms));
 -void HideThinkingProc P((Widget w, XEvent *event, String *prms,
 -                       Cardinal *nprms));
 -void TestLegalityProc P((Widget w, XEvent *event, String *prms,
 -                        Cardinal *nprms));
  void SaveSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  void SaveOnExitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 -void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@@ -322,13 -444,14 +322,15 @@@ void TimeControlProc P((Widget w, XEven
  void NewVariantProc 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 GameListOptionsPopDown P(());
  void ShufflePopDown P(());
  void EnginePopDown P(());
  void UciPopDown P(());
  void TimeControlPopDown P(());
  void NewVariantPopDown P(());
  void SettingsPopDown P(());
 +void SetMenuEnables P((Enables *enab));
  void update_ics_width P(());
  int get_term_width P(());
  int CopyMemoProc P(());
  int xtVersion = XtSpecificationRelease;
  
  int xScreen;
 -Display *xDisplay;
 +
  Window xBoardWindow;
  Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
    jailSquareColor, highlightSquareColor, premoveHighlightColor;
  Pixel lowTimeWarningColor;
 -GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,
 -  bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
 -  wjPieceGC, bjPieceGC, prelineGC, countGC;
 +
 +#define LINE_TYPE_NORMAL 0
 +#define LINE_TYPE_HIGHLIGHT 1
 +#define LINE_TYPE_PRE 2
 +
 +
 +GC lightSquareGC, darkSquareGC, jailSquareGC,  wdPieceGC, wlPieceGC,
 +  bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC,
 +  wjPieceGC, bjPieceGC;
  Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
 -Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
 +Widget  layoutWidget, formWidget, boardWidget, messageWidget,
    whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16],
    commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,
 -  menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
 +  menuBarWidget,  editShell, errorShell, analysisShell,
    ICSInputShell, fileNameShell, askQuestionShell;
 -Widget historyShell, evalGraphShell, gameListShell;
 -XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2];
 -XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6];
 +
 +Widget  evalGraphShell, gameListShell;
 +//XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2];
 +//XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6];
 +
  Font clockFontID, coordFontID, countFontID;
  XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
  XtAppContext appContext;
@@@ -414,7 -529,7 +416,7 @@@ Pixmap pieceBitmap2[2][(int)BlackPawn+4
  Pixmap xpmPieceBitmap[4][(int)BlackPawn];     /* LL, LD, DL, DD actually used*/
  Pixmap xpmPieceBitmap2[4][(int)BlackPawn+4];  /* LL, LD, DL, DD set to select from */
  Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;
 -int useImages, useImageSqs;
 +int useImages=0, useImageSqs;
  XImage *ximPieceBitmap[4][(int)BlackPawn+4];  /* LL, LD, DL, DD */
  Pixmap ximMaskPm[(int)BlackPawn];               /* clipmasks, used for XIM pieces */
  Pixmap ximMaskPm2[(int)BlackPawn+4];            /* clipmasks, used for XIM pieces */
@@@ -457,273 -572,187 +459,274 @@@ static Pixmap xpmMask[BlackKing + 1]
  
  SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
  
 +Enables icsEnables[] = {
 +    { "menuFile.Mail Move", False },
 +    { "menuFile.Reload CMail Message", False },
 +    { "menuMode.Machine Black", False },
 +    { "menuMode.Machine White", False },
 +    { "menuMode.Analysis Mode", False },
 +    { "menuMode.Analyze File", False },
 +    { "menuMode.Two Machines", False },
 +#ifndef ZIPPY
 +    { "menuHelp.Hint", False },
 +    { "menuHelp.Book", False },
 +    { "menuStep.Move Now", False },
 +    { "menuOptions.Periodic Updates", False },
 +    { "menuOptions.Hide Thinking", False },
 +    { "menuOptions.Ponder Next Move", False },
 +#endif
 +    { NULL, False }
 +};
 +
 +Enables ncpEnables[] = {
 +    { "menuFile.Mail Move", False },
 +    { "menuFile.Reload CMail Message", False },
 +    { "menuMode.Machine White", False },
 +    { "menuMode.Machine Black", False },
 +    { "menuMode.Analysis Mode", False },
 +    { "menuMode.Analyze File", False },
 +    { "menuMode.Two Machines", False },
 +    { "menuMode.ICS Client", False },
 +    { "menuMode.ICS Input Box", False },
 +    { "Action", False },
 +    { "menuStep.Revert", False },
 +    { "menuStep.Move Now", False },
 +    { "menuStep.Retract Move", False },
 +    { "menuOptions.Auto Comment", False },
 +    { "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.Move Sound", False },
 +    { "menuOptions.Quiet Play", False },
 +    { "menuOptions.Hide Thinking", False },
 +    { "menuOptions.Periodic Updates", False },
 +    { "menuOptions.Ponder Next Move", False },
 +    { "menuHelp.Hint", False },
 +    { "menuHelp.Book", False },
 +    { NULL, False }
 +};
 +
 +Enables gnuEnables[] = {
 +    { "menuMode.ICS Client", False },
 +    { "menuMode.ICS Input Box", False },
 +    { "menuAction.Accept", False },
 +    { "menuAction.Decline", False },
 +    { "menuAction.Rematch", False },
 +    { "menuAction.Adjourn", False },
 +    { "menuAction.Stop Examining", False },
 +    { "menuAction.Stop Observing", False },
 +    { "menuStep.Revert", 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 },
 +
 +    /* The next two options rely on SetCmailMode being called *after*    */
 +    /* SetGNUMode so that when GNU is being used to give hints these     */
 +    /* menu options are still available                                  */
 +
 +    { "menuFile.Mail Move", False },
 +    { "menuFile.Reload CMail Message", False },
 +    { NULL, False }
 +};
 +
 +Enables cmailEnables[] = {
 +    { "Action", True },
 +    { "menuAction.Call Flag", False },
 +    { "menuAction.Draw", True },
 +    { "menuAction.Adjourn", False },
 +    { "menuAction.Abort", False },
 +    { "menuAction.Stop Observing", False },
 +    { "menuAction.Stop Examining", False },
 +    { "menuFile.Mail Move", True },
 +    { "menuFile.Reload CMail Message", True },
 +    { NULL, False }
 +};
 +
 +Enables trainingOnEnables[] = {
 +  { "menuMode.Edit Comment", False },
 +  { "menuMode.Pause", False },
 +  { "menuStep.Forward", False },
 +  { "menuStep.Backward", False },
 +  { "menuStep.Forward to End", False },
 +  { "menuStep.Back to Start", False },
 +  { "menuStep.Move Now", False },
 +  { "menuStep.Truncate Game", False },
 +  { NULL, False }
 +};
 +
 +Enables trainingOffEnables[] = {
 +  { "menuMode.Edit Comment", True },
 +  { "menuMode.Pause", True },
 +  { "menuStep.Forward", True },
 +  { "menuStep.Backward", True },
 +  { "menuStep.Forward to End", True },
 +  { "menuStep.Back to Start", True },
 +  { "menuStep.Move Now", True },
 +  { "menuStep.Truncate Game", True },
 +  { NULL, False }
 +};
 +
 +Enables machineThinkingEnables[] = {
 +  { "menuFile.Load Game", False },
 +  { "menuFile.Load Next Game", False },
 +  { "menuFile.Load Previous Game", False },
 +  { "menuFile.Reload Same Game", False },
 +  { "menuFile.Paste Game", False },
 +  { "menuFile.Load Position", False },
 +  { "menuFile.Load Next Position", False },
 +  { "menuFile.Load Previous Position", False },
 +  { "menuFile.Reload Same Position", False },
 +  { "menuFile.Paste Position", False },
 +  { "menuMode.Machine White", False },
 +  { "menuMode.Machine Black", False },
 +  { "menuMode.Two Machines", False },
 +  { "menuStep.Retract Move", False },
 +  { NULL, False }
 +};
 +
 +Enables userThinkingEnables[] = {
 +  { "menuFile.Load Game", True },
 +  { "menuFile.Load Next Game", True },
 +  { "menuFile.Load Previous Game", True },
 +  { "menuFile.Reload Same Game", True },
 +  { "menuFile.Paste Game", True },
 +  { "menuFile.Load Position", True },
 +  { "menuFile.Load Next Position", True },
 +  { "menuFile.Load Previous Position", True },
 +  { "menuFile.Reload Same Position", True },
 +  { "menuFile.Paste Position", True },
 +  { "menuMode.Machine White", True },
 +  { "menuMode.Machine Black", True },
 +  { "menuMode.Two Machines", True },
 +  { "menuStep.Retract Move", True },
 +  { NULL, False }
 +};
 +
 +
 +
  MenuItem fileMenu[] = {
 -    {N_("New Game"), ResetProc},
      {N_("New Shuffle Game ..."), ShuffleMenuProc},
      {N_("New Variant ..."), NewVariantProc},      // [HGM] variant: not functional yet
 -    {"----", NothingProc},
 -    {N_("Load Game"), LoadGameProc},
 -    {N_("Load Next Game"), LoadNextGameProc},
 -    {N_("Load Previous Game"), LoadPrevGameProc},
 -    {N_("Reload Same Game"), ReloadGameProc},
 -    {N_("Save Game"), SaveGameProc},
 -    {"----", NothingProc},
 +    //    {"----", NothingProc},
 +    //    {N_("Save Game"), SaveGameProc},
 +    //    {"----", NothingProc},
      {N_("Copy Game"), CopyGameProc},
      {N_("Paste Game"), PasteGameProc},
 -    {"----", NothingProc},
 -    {N_("Load Position"), LoadPositionProc},
 -    {N_("Load Next Position"), LoadNextPositionProc},
 -    {N_("Load Previous Position"), LoadPrevPositionProc},
 -    {N_("Reload Same Position"), ReloadPositionProc},
 -    {N_("Save Position"), SavePositionProc},
 -    {"----", NothingProc},
 +    //    {"----", NothingProc},
 +    //    {N_("Load Position"), LoadPositionProc},
 +    //    {N_("Load Next Position"), LoadNextPositionProc},
 +    //    {N_("Load Previous Position"), LoadPrevPositionProc},
 +    //    {N_("Reload Same Position"), ReloadPositionProc},
 +    //    {N_("Save Position"), SavePositionProc},
 +    //    {"----", NothingProc},
      {N_("Copy Position"), CopyPositionProc},
      {N_("Paste Position"), PastePositionProc},
 -    {"----", NothingProc},
 +    //    {"----", NothingProc},
      {N_("Mail Move"), MailMoveProc},
      {N_("Reload CMail Message"), ReloadCmailMsgProc},
 -    {"----", NothingProc},
 -    {N_("Exit"), QuitProc},
 +    //    {"----", NothingProc},
      {NULL, NULL}
  };
  
  MenuItem modeMenu[] = {
 -    {N_("Machine White"), MachineWhiteProc},
 -    {N_("Machine Black"), MachineBlackProc},
 -    {N_("Two Machines"), TwoMachinesProc},
 -    {N_("Analysis Mode"), AnalyzeModeProc},
 -    {N_("Analyze File"), AnalyzeFileProc },
 -    {N_("ICS Client"), IcsClientProc},
 -    {N_("Edit Game"), EditGameProc},
 -    {N_("Edit Position"), EditPositionProc},
 -    {N_("Training"), TrainingProc},
 -    {"----", NothingProc},
 +  //    {N_("Machine White"), MachineWhiteProc},
 +  //    {N_("Machine Black"), MachineBlackProc},
 +  //    {N_("Two Machines"), TwoMachinesProc},
 +  //    {N_("Analysis Mode"), AnalyzeModeProc},
 +    //    {N_("Analyze File"), AnalyzeFileProc },
 +    //    {N_("ICS Client"), IcsClientProc},
 +  //    {N_("Edit Game"), EditGameProc},
 +  //    {N_("Edit Position"), EditPositionProc},
 +  //    {N_("Training"), TrainingProc},
 +    //    {"----", NothingProc},
      {N_("Show Engine Output"), EngineOutputProc},
      {N_("Show Evaluation Graph"), EvalGraphProc},
      {N_("Show Game List"), ShowGameListProc},
 -    {N_("Show Move History"), HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
 -    {"----", NothingProc},
 -    {N_("Edit Tags"), EditTagsProc},
 +    //    {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
 +    //    {"----", NothingProc},
 +    //    {N_("Edit Tags"), EditTagsProc},
      {N_("Edit Comment"), EditCommentProc},
      {N_("ICS Input Box"), IcsInputBoxProc},
 -    {N_("Pause"), PauseProc},
 -    {NULL, NULL}
 -};
 -
 -MenuItem actionMenu[] = {
 -    {N_("Accept"), AcceptProc},
 -    {N_("Decline"), DeclineProc},
 -    {N_("Rematch"), RematchProc},
 -    {"----", NothingProc},
 -    {N_("Call Flag"), CallFlagProc},
 -    {N_("Draw"), DrawProc},
 -    {N_("Adjourn"), AdjournProc},
 -    {N_("Abort"), AbortProc},
 -    {N_("Resign"), ResignProc},
 -    {"----", NothingProc},
 -    {N_("Stop Observing"), StopObservingProc},
 -    {N_("Stop Examining"), StopExaminingProc},
 -    {"----", NothingProc},
 -    {N_("Adjudicate to White"), AdjuWhiteProc},
 -    {N_("Adjudicate to Black"), AdjuBlackProc},
 -    {N_("Adjudicate Draw"), AdjuDrawProc},
 -    {NULL, NULL}
 -};
 -
 -MenuItem stepMenu[] = {
 -    {N_("Backward"), BackwardProc},
 -    {N_("Forward"), ForwardProc},
 -    {N_("Back to Start"), ToStartProc},
 -    {N_("Forward to End"), ToEndProc},
 -    {N_("Revert"), RevertProc},
 -    {N_("Truncate Game"), TruncateGameProc},
 -    {"----", NothingProc},
 -    {N_("Move Now"), MoveNowProc},
 -    {N_("Retract Move"), RetractMoveProc},
      {NULL, NULL}
  };
  
  MenuItem optionsMenu[] = {
 -    {N_("Flip View"), FlipViewProc},
 -    {"----", NothingProc},
 +  //    {N_("Flip View"), FlipViewProc},
 +  //    {"----", NothingProc},
      {N_("Adjudications ..."), EngineMenuProc},
      {N_("General Settings ..."), UciMenuProc},
      {N_("Engine #1 Settings ..."), FirstSettingsProc},
      {N_("Engine #2 Settings ..."), SecondSettingsProc},
      {N_("Time Control ..."), TimeControlProc},
+     {N_("Game List ..."), GameListOptionsPopUp},
      {"----", NothingProc},
 -    {N_("Always Queen"), AlwaysQueenProc},
 -    {N_("Animate Dragging"), AnimateDraggingProc},
 -    {N_("Animate Moving"), AnimateMovingProc},
 -    {N_("Auto Comment"), AutocommProc},
 -    {N_("Auto Flag"), AutoflagProc},
 -    {N_("Auto Flip View"), AutoflipProc},
 -    {N_("Auto Observe"), AutobsProc},
 -    {N_("Auto Raise Board"), AutoraiseProc},
 -    {N_("Auto Save"), AutosaveProc},
 -    {N_("Blindfold"), BlindfoldProc},
 -    {N_("Flash Moves"), FlashMovesProc},
 -    {N_("Get Move List"), GetMoveListProc},
 -#if HIGHDRAG
 -    {N_("Highlight Dragging"), HighlightDraggingProc},
 -#endif
 -    {N_("Highlight Last Move"), HighlightLastMoveProc},
 -    {N_("Move Sound"), MoveSoundProc},
 -    {N_("ICS Alarm"), IcsAlarmProc},
 -    {N_("Old Save Style"), OldSaveStyleProc},
 -    {N_("Periodic Updates"), PeriodicUpdatesProc},
 -    {N_("Ponder Next Move"), PonderNextMoveProc},
 -    {N_("Popup Exit Message"), PopupExitMessageProc},
 -    {N_("Popup Move Errors"), PopupMoveErrorsProc},
 -    {N_("Premove"), PremoveProc},
 -    {N_("Quiet Play"), QuietPlayProc},
 -    {N_("Show Coords"), ShowCoordsProc},
 -    {N_("Hide Thinking"), HideThinkingProc},
 -    {N_("Test Legality"), TestLegalityProc},
 +    //    {N_("Always Queen"), AlwaysQueenProc},
 +    //    {N_("Animate Dragging"), AnimateDraggingProc},
 +    //    {N_("Animate Moving"), AnimateMovingProc},
 +    //    {N_("Auto Comment"), AutocommProc},
 +    //    {N_("Auto Flag"), AutoflagProc},
 +    //    {N_("Auto Flip View"), AutoflipProc},
 +    //    {N_("Auto Observe"), AutobsProc},
 +    //    {N_("Auto Raise Board"), AutoraiseProc},
 +    //    {N_("Auto Save"), AutosaveProc},
 +    //    {N_("Blindfold"), BlindfoldProc},
 +    //    {N_("Flash Moves"), FlashMovesProc},
 + //    {N_("Get Move List"), GetMoveListProc},
 +    //#if HIGHDRAG
 +    //    {N_("Highlight Dragging"), HighlightDraggingProc},
 +    //#endif
 +    //    {N_("Highlight Last Move"), HighlightLastMoveProc},
 +    //    {N_("Move Sound"), MoveSoundProc},
 +    //    {N_("ICS Alarm"), IcsAlarmProc},
 +    //    {N_("Old Save Style"), OldSaveStyleProc},
 +    //    {N_("Periodic Updates"), PeriodicUpdatesProc},
 +    //    {N_("Ponder Next Move"), PonderNextMoveProc},
 +    //    {N_("Popup Exit Message"), PopupExitMessageProc},
 +    //    {N_("Popup Move Errors"), PopupMoveErrorsProc},
 +    //    {N_("Premove"), PremoveProc},
 +    //    {N_("Quiet Play"), QuietPlayProc},
 +    //    {N_("Hide Thinking"), HideThinkingProc},
 +    //    {N_("Test Legality"), TestLegalityProc},
 +    //    {N_("Show Coords"), ShowCoordsProc},
      {"----", NothingProc},
      {N_("Save Settings Now"), SaveSettingsProc},
      {N_("Save Settings on Exit"), SaveOnExitProc},
      {NULL, NULL}
  };
  
  Menu menuBar[] = {
      {N_("File"), fileMenu},
      {N_("Mode"), modeMenu},
 -    {N_("Action"), actionMenu},
 -    {N_("Step"), stepMenu},
      {N_("Options"), optionsMenu},
 -    {N_("Help"), helpMenu},
 -    {NULL, NULL}
 -};
 -
 -#define PAUSE_BUTTON N_("P")
 -MenuItem buttonBar[] = {
 -    {"<<", ToStartProc},
 -    {"<", BackwardProc},
 -    {PAUSE_BUTTON, PauseProc},
 -    {">", ForwardProc},
 -    {">>", ToEndProc},
      {NULL, NULL}
  };
  
  #define PIECE_MENU_SIZE 18
  String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
      { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
 -      N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), 
 -      N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), 
 +      N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"),
 +      N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
        N_("Empty square"), N_("Clear board") },
      { N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
 -      N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), 
 -      N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), 
 +      N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"),
 +      N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
        N_("Empty square"), N_("Clear board") }
  };
  /* must be in same order as PieceMenuStrings! */
  ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
      { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
        WhiteRook, WhiteQueen, WhiteKing, (ChessSquare) 0, WhiteAlfil,
 -      WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0, 
 +      WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0,
        PromotePiece, DemotePiece, EmptySquare, ClearBoard },
      { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
        BlackRook, BlackQueen, BlackKing, (ChessSquare) 0, BlackAlfil,
 -      BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0, 
 +      BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0,
        PromotePiece, DemotePiece, EmptySquare, ClearBoard },
  };
  
@@@ -750,6 -779,15 +753,6 @@@ DropMenuEnables dmEnables[] = 
      { 'Q', "Queen" }
  };
  
 -Arg shellArgs[] = {
 -    { XtNwidth, 0 },
 -    { XtNheight, 0 },
 -    { XtNminWidth, 0 },
 -    { XtNminHeight, 0 },
 -    { XtNmaxWidth, 0 },
 -    { XtNmaxHeight, 0 }
 -};
 -
  Arg layoutArgs[] = {
      { XtNborderWidth, 0 },
      { XtNdefaultDistance, 0 },
@@@ -766,111 -804,147 +769,120 @@@ Arg boardArgs[] = 
      { XtNheight, 0 }
  };
  
 -Arg titleArgs[] = {
 -    { XtNjustify, (XtArgVal) XtJustifyRight },
 -    { XtNlabel, (XtArgVal) "..." },
 -    { XtNresizable, (XtArgVal) True },
 -    { XtNresize, (XtArgVal) False }
 -};
 -
 -Arg messageArgs[] = {
 -    { XtNjustify, (XtArgVal) XtJustifyLeft },
 -    { XtNlabel, (XtArgVal) "..." },
 -    { XtNresizable, (XtArgVal) True },
 -    { XtNresize, (XtArgVal) False }
 -};
 -
 -Arg timerArgs[] = {
 -    { XtNborderWidth, 0 },
 -    { XtNjustify, (XtArgVal) XtJustifyLeft }
 -};
 -
  XtResource clientResources[] = {
      { "flashCount", "flashCount", XtRInt, sizeof(int),
        XtOffset(AppDataPtr, flashCount), XtRImmediate,
        (XtPointer) FLASH_COUNT  },
  };
  
 -XrmOptionDescRec shellOptions[] = {
 -    { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
 -    { "-flash", "flashCount", XrmoptionNoArg, "3" },
 -    { "-xflash", "flashCount", XrmoptionNoArg, "0" },
 -};
 -
  XtActionsRec boardActions[] = {
 -    { "DrawPosition", DrawPositionProc },
 -    { "HandleUserMove", HandleUserMove },
 +    //    { "HandleUserMove", HandleUserMove },
      { "AnimateUserMove", AnimateUserMove },
 +    //    { "FileNameAction", FileNameAction },
      { "HandlePV", HandlePV },
      { "UnLoadPV", UnLoadPV },
      { "AskQuestionProc", AskQuestionProc },
      { "AskQuestionReplyAction", AskQuestionReplyAction },
      { "PieceMenuPopup", PieceMenuPopup },
 -    { "WhiteClock", WhiteClock },
 -    { "BlackClock", BlackClock },
 +    //    { "WhiteClock", WhiteClock },
 +    //    { "BlackClock", BlackClock },
      { "Iconify", Iconify },
 -    { "ResetProc", ResetProc },
 -    { "LoadGameProc", LoadGameProc },
 -    { "LoadNextGameProc", LoadNextGameProc },
 -    { "LoadPrevGameProc", LoadPrevGameProc },
      { "LoadSelectedProc", LoadSelectedProc },
++<<<<<<< HEAD
 +    //    { "LoadPositionProc", LoadPositionProc },
 +    //    { "LoadNextPositionProc", LoadNextPositionProc },
 +    //    { "LoadPrevPositionProc", LoadPrevPositionProc },
 +    //    { "ReloadPositionProc", ReloadPositionProc },
++=======
+     { "SetFilterProc", SetFilterProc },
+     { "ReloadGameProc", ReloadGameProc },
+     { "LoadPositionProc", LoadPositionProc },
+     { "LoadNextPositionProc", LoadNextPositionProc },
+     { "LoadPrevPositionProc", LoadPrevPositionProc },
+     { "ReloadPositionProc", ReloadPositionProc },
++>>>>>>> master
      { "CopyPositionProc", CopyPositionProc },
      { "PastePositionProc", PastePositionProc },
      { "CopyGameProc", CopyGameProc },
      { "PasteGameProc", PasteGameProc },
 -    { "SaveGameProc", SaveGameProc },
 -    { "SavePositionProc", SavePositionProc },
 +    //    { "SaveGameProc", SaveGameProc },
 +    //    { "SavePositionProc", SavePositionProc },
      { "MailMoveProc", MailMoveProc },
      { "ReloadCmailMsgProc", ReloadCmailMsgProc },
 -    { "QuitProc", QuitProc },
 -    { "MachineWhiteProc", MachineWhiteProc },
 -    { "MachineBlackProc", MachineBlackProc },
 -    { "AnalysisModeProc", AnalyzeModeProc },
 -    { "AnalyzeFileProc", AnalyzeFileProc },
 -    { "TwoMachinesProc", TwoMachinesProc },
 -    { "IcsClientProc", IcsClientProc },
 -    { "EditGameProc", EditGameProc },
 -    { "EditPositionProc", EditPositionProc },
 -    { "TrainingProc", EditPositionProc },
 +    //    { "MachineWhiteProc", MachineWhiteProc },
 +    //    { "MachineBlackProc", MachineBlackProc },
 +    //    { "AnalysisModeProc", AnalyzeModeProc },
 +    //    { "AnalyzeFileProc", AnalyzeFileProc },
 +    //    { "TwoMachinesProc", TwoMachinesProc },
 +    //    { "IcsClientProc", IcsClientProc },
 +    //    { "EditGameProc", EditGameProc },
 +    //    { "EditPositionProc", EditPositionProc },
 +    //    { "TrainingProc", EditPositionProc },
      { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
      { "EvalGraphProc", EvalGraphProc},       // [HGM] Winboard_x avaluation graph window
      { "ShowGameListProc", ShowGameListProc },
 -    { "ShowMoveListProc", HistoryShowProc},
 -    { "EditTagsProc", EditCommentProc },
 +    //    { "ShowMoveListProc", HistoryShowProc},
 +    //    { "EditTagsProc", EditCommentProc },
      { "EditCommentProc", EditCommentProc },
 -    { "IcsAlarmProc", IcsAlarmProc },
 +    //    { "IcsAlarmProc", IcsAlarmProc },
      { "IcsInputBoxProc", IcsInputBoxProc },
 -    { "PauseProc", PauseProc },
 -    { "AcceptProc", AcceptProc },
 -    { "DeclineProc", DeclineProc },
 -    { "RematchProc", RematchProc },
 -    { "CallFlagProc", CallFlagProc },
 -    { "DrawProc", DrawProc },
 -    { "AdjournProc", AdjournProc },
 -    { "AbortProc", AbortProc },
 -    { "ResignProc", ResignProc },
 -    { "AdjuWhiteProc", AdjuWhiteProc },
 -    { "AdjuBlackProc", AdjuBlackProc },
 -    { "AdjuDrawProc", AdjuDrawProc },
 +    //    { "AcceptProc", AcceptProc },
 +    //    { "DeclineProc", DeclineProc },
 +    //    { "RematchProc", RematchProc },
 +    //    { "CallFlagProc", CallFlagProc },
 +    //    { "DrawProc", DrawProc },
 +    //    { "AdjournProc", AdjournProc },
 +    //    { "AbortProc", AbortProc },
 +    //    { "ResignProc", ResignProc },
 +    //    { "AdjuWhiteProc", AdjuWhiteProc },
 +    //    { "AdjuBlackProc", AdjuBlackProc },
 +    //    { "AdjuDrawProc", AdjuDrawProc },
      { "EnterKeyProc", EnterKeyProc },
 -    { "StopObservingProc", StopObservingProc },
 -    { "StopExaminingProc", StopExaminingProc },
 -    { "BackwardProc", BackwardProc },
 -    { "ForwardProc", ForwardProc },
 -    { "ToStartProc", ToStartProc },
 -    { "ToEndProc", ToEndProc },
 -    { "RevertProc", RevertProc },
 -    { "TruncateGameProc", TruncateGameProc },
 -    { "MoveNowProc", MoveNowProc },
 -    { "RetractMoveProc", RetractMoveProc },
 -    { "AlwaysQueenProc", AlwaysQueenProc },
 -    { "AnimateDraggingProc", AnimateDraggingProc },
 -    { "AnimateMovingProc", AnimateMovingProc },
 -    { "AutoflagProc", AutoflagProc },
 -    { "AutoflipProc", AutoflipProc },
 -    { "AutobsProc", AutobsProc },
 -    { "AutoraiseProc", AutoraiseProc },
 -    { "AutosaveProc", AutosaveProc },
 -    { "BlindfoldProc", BlindfoldProc },
 -    { "FlashMovesProc", FlashMovesProc },
 -    { "FlipViewProc", FlipViewProc },
 -    { "GetMoveListProc", GetMoveListProc },
 +    //    { "StopObservingProc", StopObservingProc },
 +    //    { "StopExaminingProc", StopExaminingProc },
 +    //    { "BackwardProc", BackwardProc },
 +    //    { "ForwardProc", ForwardProc },
 +    //    { "ToStartProc", ToStartProc },
 +    //    { "ToEndProc", ToEndProc },
 +    //    { "RevertProc", RevertProc },
 +    //    { "TruncateGameProc", TruncateGameProc },
 +    //    { "MoveNowProc", MoveNowProc },
 +    //    { "RetractMoveProc", RetractMoveProc },
 +    //    { "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 },
 +    //    { "HighlightDraggingProc", HighlightDraggingProc },
  #endif
 -    { "HighlightLastMoveProc", HighlightLastMoveProc },
 -    { "IcsAlarmProc", IcsAlarmProc },
 -    { "MoveSoundProc", MoveSoundProc },
 -    { "OldSaveStyleProc", OldSaveStyleProc },
 -    { "PeriodicUpdatesProc", PeriodicUpdatesProc },
 -    { "PonderNextMoveProc", PonderNextMoveProc },
 -    { "PopupExitMessageProc", PopupExitMessageProc },
 -    { "PopupMoveErrorsProc", PopupMoveErrorsProc },
 -    { "PremoveProc", PremoveProc },
 -    { "QuietPlayProc", QuietPlayProc },
 -    { "ShowCoordsProc", ShowCoordsProc },
 -    { "ShowThinkingProc", ShowThinkingProc },
 -    { "HideThinkingProc", HideThinkingProc },
 -    { "TestLegalityProc", TestLegalityProc },
 +    //    { "HighlightLastMoveProc", HighlightLastMoveProc },
 +    //    { "IcsAlarmProc", IcsAlarmProc },
 +    //    { "MoveSoundProc", MoveSoundProc },
 +    //    { "OldSaveStyleProc", OldSaveStyleProc },
 +    //    { "PeriodicUpdatesProc", PeriodicUpdatesProc },
 +    //    { "PonderNextMoveProc", PonderNextMoveProc },
 +    //    { "PopupExitMessageProc", PopupExitMessageProc },
 +    //    { "PopupMoveErrorsProc", PopupMoveErrorsProc },
 +    //    { "PremoveProc", PremoveProc },
 +    //    { "QuietPlayProc", QuietPlayProc },
 +    //    { "ShowThinkingProc", ShowThinkingProc },
 +    //    { "HideThinkingProc", HideThinkingProc },
 +    //    { "TestLegalityProc", TestLegalityProc },
      { "SaveSettingsProc", SaveSettingsProc },
      { "SaveOnExitProc", SaveOnExitProc },
 -    { "InfoProc", InfoProc },
 -    { "ManProc", ManProc },
 -    { "HintProc", HintProc },
 -    { "BookProc", BookProc },
 +//    { "InfoProc", InfoProc },
 +//    { "ManProc", ManProc },
 +//    { "HintProc", HintProc },
 +//    { "BookProc", BookProc },
      { "AboutGameProc", AboutGameProc },
 -    { "AboutProc", AboutProc },
      { "DebugProc", DebugProc },
      { "NothingProc", NothingProc },
      { "CommentPopDown", (XtActionProc) CommentPopDown },
      { "TagsPopDown", (XtActionProc) TagsPopDown },
      { "ErrorPopDown", (XtActionProc) ErrorPopDown },
      { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
 -    { "FileNamePopDown", (XtActionProc) FileNamePopDown },
 +    //    { "FileNamePopDown", (XtActionProc) FileNamePopDown },
      { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
      { "GameListPopDown", (XtActionProc) GameListPopDown },
+     { "GameListOptionsPopDown", (XtActionProc) GameListOptionsPopDown },
      { "PromotionPopDown", (XtActionProc) PromotionPopDown },
 -    { "HistoryPopDown", (XtActionProc) HistoryPopDown },
 +    //    { "HistoryPopDown", (XtActionProc) HistoryPopDown },
      { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
      { "EvalGraphPopDown", (XtActionProc) EvalGraphPopDown },
      { "ShufflePopDown", (XtActionProc) ShufflePopDown },
      { "CopyMemoProc", (XtActionProc) CopyMemoProc },
  };
  
 -char globalTranslations[] =
 -  ":<Key>R: ResignProc() \n \
 -   :<Key>r: ResetProc() \n \
 -   :<Key>g: LoadGameProc() \n \
 -   :<Key>N: LoadNextGameProc() \n \
 -   :<Key>P: LoadPrevGameProc() \n \
 -   :<Key>Q: QuitProc() \n \
 -   :<Key>F: ToEndProc() \n \
 -   :<Key>f: ForwardProc() \n \
 -   :<Key>B: ToStartProc() \n \
 -   :<Key>b: BackwardProc() \n \
 -   :<Key>p: PauseProc() \n \
 -   :<Key>d: DrawProc() \n \
 -   :<Key>t: CallFlagProc() \n \
 -   :<Key>i: Iconify() \n \
 -   :<Key>c: Iconify() \n \
 -   :<Key>v: FlipViewProc() \n \
 -   <KeyDown>Control_L: BackwardProc() \n \
 -   <KeyUp>Control_L: ForwardProc() \n \
 -   <KeyDown>Control_R: BackwardProc() \n \
 -   <KeyUp>Control_R: ForwardProc() \n \
 -   Shift<Key>1: AskQuestionProc(\"Direct command\",\
 -                                \"Send to chess program:\",,1) \n \
 -   Shift<Key>2: AskQuestionProc(\"Direct command\",\
 -                                \"Send to second chess program:\",,2) \n";
 -
 -char boardTranslations[] =
 -   "<Btn1Down>: HandleUserMove() \n \
 -   <Btn1Up>: HandleUserMove() \n \
 -   <Btn1Motion>: AnimateUserMove() \n \
 -   <Btn3Motion>: HandlePV() \n \
 -   <Btn3Up>: PieceMenuPopup(menuB) \n \
 -   Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
 -                 PieceMenuPopup(menuB) \n \
 -   Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
 -                 PieceMenuPopup(menuW) \n \
 -   Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
 -                 PieceMenuPopup(menuW) \n \
 -   Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
 -                 PieceMenuPopup(menuB) \n";
 -
 -char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
 -char blackTranslations[] = "<BtnDown>: BlackClock()\n";
 +//char globalTranslations[] =
 +//  ":<Key>R: ResignProc() \n \
 +//   :<Key>r: ResetProc() \n \
 +//   :<Key>g: LoadGameProc() \n \
 +//   :<Key>N: LoadNextGameProc() \n \
 +//   :<Key>P: LoadPrevGameProc() \n \
 +//   :<Key>Q: QuitProc() \n \
 +//   :<Key>F: ToEndProc() \n \
 +//   :<Key>f: ForwardProc() \n \
 +//   :<Key>B: ToStartProc() \n \
 +//   :<Key>b: BackwardProc() \n \
 +//   :<Key>p: PauseProc() \n \
 +//   :<Key>d: DrawProc() \n \
 +//   :<Key>t: CallFlagProc() \n \
 +//   :<Key>i: Iconify() \n \
 +//   :<Key>c: Iconify() \n \
 +//   :<Key>v: FlipViewProc() \n \
 +//   <KeyDown>Control_L: BackwardProc() \n \
 +//   <KeyUp>Control_L: ForwardProc() \n \
 +//   <KeyDown>Control_R: BackwardProc() \n \
 +//   <KeyUp>Control_R: ForwardProc() \n \
 +//   Shift<Key>1: AskQuestionProc(\"Direct command\",\
 +//                                \"Send to chess program:\",,1) \n \
 +//   Shift<Key>2: AskQuestionProc(\"Direct command\",\
 +//                                \"Send to second chess program:\",,2) \n";
 +//
 +//char boardTranslations[] =
 +//   "<Btn1Down>: HandleUserMove() \n \
 +//   <Btn1Up>: HandleUserMove() \n \
 +//   <Btn1Motion>: AnimateUserMove() \n \
 +//   <Btn3Motion>: HandlePV() \n \
 +//   <Btn3Up>: UnLoadPV() \n \
 +//   Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
 +//                 PieceMenuPopup(menuB) \n \
 +//   Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
 +//                 PieceMenuPopup(menuW) \n \
 +//   Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
 +//                 PieceMenuPopup(menuW) \n \
 +//   Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
 +//                 PieceMenuPopup(menuB) \n";
 +//
 +//char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
 +//char blackTranslations[] = "<BtnDown>: BlackClock()\n";
  
  char ICSInputTranslations[] =
      "<Key>Return: EnterKeyProc() \n";
  
  String xboardResources[] = {
 -    "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
 +  //    "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
      "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
      "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
      NULL
    };
  
 -
 -/* Max possible square size */
 -#define MAXSQSIZE 256
 -
 -static int xpm_avail[MAXSQSIZE];
 -
 -#ifdef HAVE_DIR_STRUCT
 -
 -/* Extract piece size from filename */
 -static int
 -xpm_getsize(name, len, ext)
 -     char *name;
 -     int len;
 -     char *ext;
 -{
 -    char *p, *d;
 -    char buf[10];
 -
 -    if (len < 4)
 -      return 0;
 -
 -    if ((p=strchr(name, '.')) == NULL ||
 -      StrCaseCmp(p+1, ext) != 0)
 -      return 0;
 -
 -    p = name + 3;
 -    d = buf;
 -
 -    while (*p && isdigit(*p))
 -      *(d++) = *(p++);
 -
 -    *d = 0;
 -    return atoi(buf);
 -}
 -
 -/* Setup xpm_avail */
 -static int
 -xpm_getavail(dirname, ext)
 -     char *dirname;
 -     char *ext;
 -{
 -    DIR *dir;
 -    struct dirent *ent;
 -    int  i;
 -
 -    for (i=0; i<MAXSQSIZE; ++i)
 -      xpm_avail[i] = 0;
 -
 -    if (appData.debugMode)
 -      fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);
 -
 -    dir = opendir(dirname);
 -    if (!dir)
 -      {
 -        fprintf(stderr, _("%s: Can't access XPM directory %s\n"),
 -                programName, dirname);
 -        exit(1);
 -      }
 -
 -    while ((ent=readdir(dir)) != NULL) {
 -      i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);
 -      if (i > 0 && i < MAXSQSIZE)
 -        xpm_avail[i] = 1;
 -    }
 -
 -    closedir(dir);
 -
 -    return 0;
 -}
 -
 -void
 -xpm_print_avail(fp, ext)
 -     FILE *fp;
 -     char *ext;
 -{
 -    int i;
 -
 -    fprintf(fp, _("Available `%s' sizes:\n"), ext);
 -    for (i=1; i<MAXSQSIZE; ++i) {
 -      if (xpm_avail[i])
 -        printf("%d\n", i);
 -    }
 -}
 -
 -/* Return XPM piecesize closest to size */
 -int
 -xpm_closest_to(dirname, size, ext)
 -     char *dirname;
 -     int size;
 -     char *ext;
 -{
 -    int i;
 -    int sm_diff = MAXSQSIZE;
 -    int sm_index = 0;
 -    int diff;
 -
 -    xpm_getavail(dirname, ext);
 -
 -    if (appData.debugMode)
 -      xpm_print_avail(stderr, ext);
 -
 -    for (i=1; i<MAXSQSIZE; ++i) {
 -      if (xpm_avail[i]) {
 -          diff = size - i;
 -          diff = (diff<0) ? -diff : diff;
 -          if (diff < sm_diff) {
 -              sm_diff = diff;
 -              sm_index = i;
 -          }
 -      }
 -    }
 -
 -    if (!sm_index) {
 -      fprintf(stderr, _("Error: No `%s' files!\n"), ext);
 -      exit(1);
 -    }
 -
 -    return sm_index;
 -}
 -#else /* !HAVE_DIR_STRUCT */
 -/* If we are on a system without a DIR struct, we can't
 -   read the directory, so we can't collect a list of
 -   filenames, etc., so we can't do any size-fitting. */
 -int
 -xpm_closest_to(dirname, size, ext)
 -     char *dirname;
 -     int size;
 -     char *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"));
 -    return size;
 -}
 -#endif /* HAVE_DIR_STRUCT */
 -
  static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
                             "magenta", "cyan", "white" };
  typedef struct {
@@@ -1024,12 -1237,25 +1037,12 @@@ parse_cpair(cc, str
  }
  
  
  void
  BoardToTop()
  {
 -  Arg args[16];
 -  XtSetArg(args[0], XtNiconic, False);
 -  XtSetValues(shellWidget, args, 1);
 -
 -  XtPopup(shellWidget, XtGrabNone); /* Raise if lowered  */
 +  /* this should raise the board to the top */
 +  gtk_window_present(GTK_WINDOW(GUI_Window));
 +  return;
  }
  
  //---------------------------------------------------------------------------------------------------------
@@@ -1074,9 -1300,25 +1087,25 @@@ colorVariable[] = 
    NULL
  };
  
+ // [HGM] font: keep a font for each square size, even non-stndard ones
+ #define NUM_SIZES 18
+ #define MAX_SIZE 130
+ Boolean fontSet[NUM_FONTS], fontValid[NUM_FONTS][MAX_SIZE];
+ char *fontTable[NUM_FONTS][MAX_SIZE];
  void
  ParseFont(char *name, int number)
  { // in XBoard, only 2 of the fonts are currently implemented, and we just copy their name
+   int size;
+   if(sscanf(name, "size%d:", &size)) {
+     // [HGM] font: font is meant for specific boardSize (likely from settings file);
+     //       defer processing it until we know if it matches our board size
+     if(size >= 0 && size<MAX_SIZE) { // for now, fixed limit
+       fontTable[number][size] = strdup(strchr(name, ':')+1);
+       fontValid[number][size] = True;
+     }
+     return;
+   }
    switch(number) {
      case 0: // CLOCK_FONT
        appData.clockFont = strdup(name);
      default:
        return;
    }
+   fontSet[number] = True; // [HGM] font: indicate a font was specified (not from settings file)
  }
  
  void
@@@ -1137,8 -1380,9 +1167,9 @@@ SetCommPortDefaults(
  void
  SaveFontArg(FILE *f, ArgDescriptor *ad)
  {
-   char *name;
-   switch((int)ad->argLoc) {
+   char *name, buf[MSG_SIZ];
+   int i, n = (int)ad->argLoc;
+   switch(n) {
      case 0: // CLOCK_FONT
        name = appData.clockFont;
        break;
      default:
        return;
    }
- //  Do not save fonts for now, as the saved font would be board-size specific
- //  and not suitable for a re-start at another board size
- //  fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, name); 
+   for(i=0; i<NUM_SIZES; i++) // [HGM] font: current font becomes standard for current size
+     if(sizeDefaults[i].squareSize == squareSize) { // only for standard sizes!
+       fontTable[n][squareSize] = strdup(name);
+       fontValid[n][squareSize] = True;
+       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]); 
  }
  
  void
@@@ -1187,7 -1436,6 +1223,7 @@@ ParseCommPortSettings(char *s
  
  extern Widget engineOutputShell;
  extern Widget tagsShell, editTagsShell;
 +
  void
  GetActualPlacement(Widget wg, WindowPlacement *wp)
  {
  GetWindowCoords()
  { // wrapper to shield use of window handles from back-end (make addressible by number?)
    // In XBoard this will have to wait until awareness of window parameters is implemented
 -  GetActualPlacement(shellWidget, &wpMain);
 +
 +  //  GetActualPlacement(shellWidget, &wpMain);
    if(EngineOutputIsUp()) GetActualPlacement(engineOutputShell, &wpEngineOutput); else
 -  if(MoveHistoryIsUp()) GetActualPlacement(historyShell, &wpMoveHistory);
 +//  if(MoveHistoryIsUp()) GetActualPlacement(historyShell, &wpMoveHistory);
    if(EvalGraphIsUp()) GetActualPlacement(evalGraphShell, &wpEvalGraph);
    if(GameListIsUp()) GetActualPlacement(gameListShell, &wpGameList);
    if(commentShell) GetActualPlacement(commentShell, &wpComment);
@@@ -1288,7 -1535,6 +1324,7 @@@ ConvertToLine(int argc, char **argv
  #ifdef IDSIZES
    // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
  #else
 +
  #define BoardSize int
  void InitDrawingSizes(BoardSize boardSize, int flags)
  {   // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
      XtGeometryResult gres;
      int i;
  
 -    if(!formWidget) return;
 -
 -    /*
 -     * Enable shell resizing.
 -     */
 -    shellArgs[0].value = (XtArgVal) &w;
 -    shellArgs[1].value = (XtArgVal) &h;
 -    XtGetValues(shellWidget, shellArgs, 2);
 -
 -    shellArgs[4].value = 2*w; shellArgs[2].value = 10;
 -    shellArgs[5].value = 2*h; shellArgs[3].value = 10;
 -    XtSetValues(shellWidget, &shellArgs[2], 4);
 -
 -    XtSetArg(args[0], XtNdefaultDistance, &sep);
 -    XtGetValues(formWidget, args, 1);
 -
 -    boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
 +    boardWidth  = lineGap + BOARD_WIDTH  * (squareSize + lineGap);
      boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
 -    CreateGrid();
 -
 -    XtSetArg(args[0], XtNwidth, boardWidth);
 -    XtSetArg(args[1], XtNheight, boardHeight);
 -    XtSetValues(boardWidget, args, 2);
  
      timerWidth = (boardWidth - sep) / 2;
 -    XtSetArg(args[0], XtNwidth, timerWidth);
 -    XtSetValues(whiteTimerWidget, args, 1);
 -    XtSetValues(blackTimerWidget, args, 1);
  
 -    XawFormDoLayout(formWidget, False);
 -
 -    if (appData.titleInWindow) {
 +    if (appData.titleInWindow)
 +      {
        i = 0;
 -      XtSetArg(args[i], XtNborderWidth, &bor); i++;
 -      XtSetArg(args[i], XtNheight, &h);  i++;
 -      XtGetValues(titleWidget, args, i);
 -      if (smallLayout) {
 +      if (smallLayout)
 +        {
            w = boardWidth - 2*bor;
 -      } else {
 -          XtSetArg(args[0], XtNwidth, &w);
 -          XtGetValues(menuBarWidget, args, 1);
 +        }
 +      else
 +        {
            w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE
 -      }
 -
 -      gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
 -      if (gres != XtGeometryYes && appData.debugMode) {
 -          fprintf(stderr,
 -                  _("%s: titleWidget geometry error %d %d %d %d %d\n"),
 -                  programName, gres, w, h, wr, hr);
 -      }
 -    }
 +        }
 +      }
  
 -    XawFormDoLayout(formWidget, True);
 +    if(!formWidget) return;
  
      /*
       * Inhibit shell resizing.
       */
 -    shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
 -    shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
 -    shellArgs[4].value = shellArgs[2].value = w;
 -    shellArgs[5].value = shellArgs[3].value = h;
 -    XtSetValues(shellWidget, &shellArgs[0], 6);
  
      // [HGM] pieces: tailor piece bitmaps to needs of specific variant
      // (only for xpm)
@@@ -1434,79 -1719,12 +1470,79 @@@ main(argc, argv
      textdomain(PACKAGE);
  #endif
  
 -    shellWidget =
 -      XtAppInitialize(&appContext, "XBoard", shellOptions,
 -                    XtNumber(shellOptions),
 -                    &argc, argv, xboardResources, NULL, 0);
 +    /* set up GTK */
 +    gtk_init (&argc, &argv);
 +
 +    /* parse glade file to build widgets */
 +
 +    builder = gtk_builder_new ();
 +    gtk_builder_add_from_file (builder, "gtk-interface.xml", NULL);
 +
 +    /* test if everything worked ok */
 +
 +    GUI_Window = GTK_WIDGET (gtk_builder_get_object (builder, "MainWindow"));
 +    if(!GUI_Window) printf("Error: gtk_builder didn't work (MainWindow)!\n");
 +
 +    GUI_Aspect = GTK_WIDGET (gtk_builder_get_object (builder, "Aspectframe"));
 +    if(!GUI_Aspect) printf("Error: gtk_builder didn't work (Aspectframe)!\n");
 +
 +    GUI_Menubar  = GTK_WIDGET (gtk_builder_get_object (builder, "MenuBar"));
 +    if(!GUI_Menubar) printf("Error: gtk_builder didn't work (MenuBar)!\n");
 +    GUI_Timer  = GTK_WIDGET (gtk_builder_get_object (builder, "Timer"));
 +    if(!GUI_Timer) printf("Error: gtk_builder didn't work (Timer)!\n");
 +    GUI_Buttonbar  = GTK_WIDGET (gtk_builder_get_object (builder, "ButtonBar"));
 +    if(!GUI_Buttonbar) printf("Error: gtk_builder didn't work (ButtonBar)!\n");
 +    GUI_Board  = GTK_WIDGET (gtk_builder_get_object (builder, "Board"));
 +    if(!GUI_Board) printf("Error: gtk_builder didn't work (Board)!\n");
 +
 +    GUI_Whiteclock  = GTK_WIDGET (gtk_builder_get_object (builder, "WhiteClock"));
 +    if(!GUI_Whiteclock) printf("Error: gtk_builder didn't work (WhiteClock)!\n");
 +
 +    GUI_Blackclock  = GTK_WIDGET (gtk_builder_get_object (builder, "BlackClock"));
 +    if(!GUI_Blackclock) printf("Error: gtk_builder didn't work (BlackClock)!\n");
 +
 +    /* GTK lists stores*/
 +    LIST_MoveHistory = GTK_LIST_STORE (gtk_builder_get_object (builder, "MoveHistoryStore"));
 +    if(!LIST_MoveHistory) printf("Error: gtk_builder didn't work (MoveHistoryStore)!\n");
 +
 +    LIST_GameList = GTK_LIST_STORE (gtk_builder_get_object (builder, "GameListStore"));
 +    if(!LIST_GameList) printf("Error: gtk_builder didn't work (GameListStore)!\n");
 +
 +    /* EditTags window */
 +    GUI_EditTags = GTK_WIDGET (gtk_builder_get_object (builder, "EditTags"));
 +    if(!GUI_EditTags) printf("Error: gtk_builder didn't work (EditTags)!\n");
 +    
 +    GUI_EditTagsTextArea = GTK_WIDGET (gtk_builder_get_object (builder, "EditTagsTextArea"));
 +    if(!GUI_EditTagsTextArea) printf("Error: gtk_builder didn't work(EditTagsTextArea)!\n");
 +
 +    /* move history and game list windows */
 +    GUI_History = GTK_WIDGET (gtk_builder_get_object (builder, "MoveHistory"));
 +    if(!GUI_History) printf("Error: gtk_builder didn't work (MoveHistory)!\n");
 +
 +    TREE_History = GTK_TREE_VIEW (gtk_builder_get_object (builder, "MoveHistoryView"));
 +    if(!TREE_History) printf("Error: gtk_builder didn't work (MoveHistoryView)!\n");
 +
 +    GUI_GameList = GTK_WIDGET (gtk_builder_get_object (builder, "GameList"));
 +    if(!GUI_GameList) printf("Error: gtk_builder didn't work (GameList)!\n");
 +
 +    TREE_Game = GTK_TREE_VIEW (gtk_builder_get_object (builder, "GameListView"));
 +    if(!TREE_Game) printf("Error: gtk_builder didn't work (GameListView)!\n");
 +
 +
 +    /* connect lists to views */
 +    gtk_tree_view_set_model(TREE_History, GTK_TREE_MODEL(LIST_MoveHistory));
 +    gtk_tree_view_set_model(TREE_Game,    GTK_TREE_MODEL(LIST_GameList));
 +
 +    gtk_builder_connect_signals (builder, NULL);
 +
 +    // don't unref the builder, since we use it to get references to widgets
 +    //    g_object_unref (G_OBJECT (builder));
 +
 +    /* end parse glade file */
 +
      appData.boardSize = "";
      InitAppData(ConvertToLine(argc, argv));
 +
      p = getenv("HOME");
      if (p == NULL) p = "/tmp";
      i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
      snprintf(gameCopyFilename,i, "%s/.xboard%05uc.pgn", p, getpid());
      snprintf(gamePasteFilename,i, "%s/.xboard%05up.pgn", p, getpid());
  
 -    XtGetApplicationResources(shellWidget, (XtPointer) &appData,
 -                            clientResources, XtNumber(clientResources),
 -                            NULL, 0);
 +//    XtGetApplicationResources(shellWidget, (XtPointer) &appData,
 +//                          clientResources, XtNumber(clientResources),
 +//                          NULL, 0);
  
      { // [HGM] initstring: kludge to fix bad bug. expand '\n' characters in init string and computer string.
        static char buf[MSG_SIZ];
          setbuf(debugFP, NULL);
      }
  
 -    /* [HGM,HR] make sure board size is acceptable */
 -    if(appData.NrFiles > BOARD_FILES ||
 -       appData.NrRanks > BOARD_RANKS   )
 -       DisplayFatalError(_("Recompile with larger BOARD_RANKS or BOARD_FILES to support this size"), 0, 2);
  
  #if !HIGHDRAG
      /* This feature does not work; animation needs a rewrite */
  #endif
      InitBackEnd1();
  
 -    xDisplay = XtDisplay(shellWidget);
 -    xScreen = DefaultScreen(xDisplay);
 -    wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
 +    gameInfo.variant = StringToVariant(appData.variant);
 +    InitPosition(FALSE);
  
 -      gameInfo.variant = StringToVariant(appData.variant);
 -      InitPosition(FALSE);
  
 -#ifdef IDSIZE
 -    InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
 -#else
 -    if (isdigit(appData.boardSize[0])) {
 -        i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
 -                 &lineGap, &clockFontPxlSize, &coordFontPxlSize,
 -                 &fontPxlSize, &smallLayout, &tinyLayout);
 -        if (i == 0) {
 -          fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
 -                  programName, appData.boardSize);
 -          exit(2);
 -      }
 -      if (i < 7) {
 -          /* Find some defaults; use the nearest known size */
 -          SizeDefaults *szd, *nearest;
 -          int distance = 99999;
 -          nearest = szd = sizeDefaults;
 -          while (szd->name != NULL) {
 -              if (abs(szd->squareSize - squareSize) < distance) {
 -                  nearest = szd;
 -                  distance = abs(szd->squareSize - squareSize);
 -                  if (distance == 0) break;
 -              }
 -              szd++;
 -          }
 -          if (i < 2) lineGap = nearest->lineGap;
 -          if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
 -          if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
 -          if (i < 5) fontPxlSize = nearest->fontPxlSize;
 -          if (i < 6) smallLayout = nearest->smallLayout;
 -          if (i < 7) tinyLayout = nearest->tinyLayout;
 -      }
 -    } else {
 -        SizeDefaults *szd = sizeDefaults;
 -        if (*appData.boardSize == NULLCHAR) {
 -          while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
 -                 DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
 -            szd++;
 -          }
 -          if (szd->name == NULL) szd--;
 -          appData.boardSize = strdup(szd->name); // [HGM] settings: remember name for saving settings
 -      } else {
 -          while (szd->name != NULL &&
 -                 StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
 -          if (szd->name == NULL) {
 -              fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
 -                      programName, appData.boardSize);
 -              exit(2);
 -          }
 -      }
 -      squareSize = szd->squareSize;
 -      lineGap = szd->lineGap;
 -      clockFontPxlSize = szd->clockFontPxlSize;
 -      coordFontPxlSize = szd->coordFontPxlSize;
 -      fontPxlSize = szd->fontPxlSize;
 -      smallLayout = szd->smallLayout;
 -      tinyLayout = szd->tinyLayout;
 -      // [HGM] font: use defaults from settings file if available and not overruled
 -    }
 -    if(!fontSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize])
 -      appData.clockFont = fontTable[CLOCK_FONT][squareSize];
 -    if(!fontSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize])
 -      appData.font = fontTable[MESSAGE_FONT][squareSize];
 -    if(!fontSet[COORD_FONT] && fontValid[COORD_FONT][squareSize])
 -      appData.coordFont = fontTable[COORD_FONT][squareSize];
 -
 -    /* Now, using squareSize as a hint, find a good XPM/XIM set size */
 -    if (strlen(appData.pixmapDirectory) > 0) {
 -      p = ExpandPathName(appData.pixmapDirectory);
 -      if (!p) {
 -          fprintf(stderr, _("Error expanding path name \"%s\"\n"),
 -                 appData.pixmapDirectory);
 -          exit(1);
 -      }
 -      if (appData.debugMode) {
 -          fprintf(stderr, _("\
 -XBoard square size (hint): %d\n\
 -%s fulldir:%s:\n"), squareSize, IMAGE_EXT, p);
 -      }
 -      squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
 -      if (appData.debugMode) {
 -          fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
 -      }
 -    }
 +    squareSize                = 40;
 +    lineGap           = 1;
 +    clockFontPxlSize  = 20;
 +    coordFontPxlSize  = 20;
 +    fontPxlSize               = 20;
 +    smallLayout               = 16;
 +    tinyLayout                = 10;
  
 -    /* [HR] height treated separately (hacked) */
 -    boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
 +    
 +    boardWidth  = lineGap + BOARD_WIDTH * (squareSize + lineGap);
      boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
 -    if (appData.showJail == 1) {
 -      /* Jail on top and bottom */
 -      XtSetArg(boardArgs[1], XtNwidth, boardWidth);
 -      XtSetArg(boardArgs[2], XtNheight,
 -               boardHeight + 2*(lineGap + squareSize));
 -    } else if (appData.showJail == 2) {
 -      /* Jail on sides */
 -      XtSetArg(boardArgs[1], XtNwidth,
 -               boardWidth + 2*(lineGap + squareSize));
 -      XtSetArg(boardArgs[2], XtNheight, boardHeight);
 -    } else {
 -      /* No jail */
 -      XtSetArg(boardArgs[1], XtNwidth, boardWidth);
 -      XtSetArg(boardArgs[2], XtNheight, boardHeight);
 -    }
 -
 +    
      /*
       * Determine what fonts to use.
       */
 -    appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
 -    clockFontID = XLoadFont(xDisplay, appData.clockFont);
 -    clockFontStruct = XQueryFont(xDisplay, clockFontID);
 -    appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
 -    coordFontID = XLoadFont(xDisplay, appData.coordFont);
 -    coordFontStruct = XQueryFont(xDisplay, coordFontID);
 -    appData.font = FindFont(appData.font, fontPxlSize);
 -    countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
 -    countFontStruct = XQueryFont(xDisplay, countFontID);
 +//    appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
 +//    clockFontID = XLoadFont(xDisplay, appData.clockFont);
 +//    clockFontStruct = XQueryFont(xDisplay, clockFontID);
 +//    appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
 +//    coordFontID = XLoadFont(xDisplay, appData.coordFont);
 +//    coordFontStruct = XQueryFont(xDisplay, coordFontID);
 +//    appData.font = FindFont(appData.font, fontPxlSize);
 +//    countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
 +//    countFontStruct = XQueryFont(xDisplay, countFontID);
  //    appData.font = FindFont(appData.font, fontPxlSize);
  
 -    xdb = XtDatabase(xDisplay);
 -    XrmPutStringResource(&xdb, "*font", appData.font);
 +//    xdb = XtDatabase(xDisplay);
 +//    XrmPutStringResource(&xdb, "*font", appData.font);
  
      /*
       * Detect if there are not enough colors available and adapt.
       */
 -    if (DefaultDepth(xDisplay, xScreen) <= 2) {
 -      appData.monoMode = True;
 -    }
 +//    if (DefaultDepth(xDisplay, xScreen) <= 2) {
 +//      appData.monoMode = True;
 +//    }
  
      if (!appData.monoMode) {
        vFrom.addr = (caddr_t) appData.lightSquareColor;
        vFrom.size = strlen(appData.lightSquareColor);
 -      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
 +      //      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
        if (vTo.addr == NULL) {
          appData.monoMode = True;
          forceMono = True;
      if (!appData.monoMode) {
        vFrom.addr = (caddr_t) appData.darkSquareColor;
        vFrom.size = strlen(appData.darkSquareColor);
 -      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
 +      //      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
        if (vTo.addr == NULL) {
          appData.monoMode = True;
          forceMono = True;
      if (!appData.monoMode) {
        vFrom.addr = (caddr_t) appData.whitePieceColor;
        vFrom.size = strlen(appData.whitePieceColor);
 -      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
 +      //      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
        if (vTo.addr == NULL) {
          appData.monoMode = True;
          forceMono = True;
      if (!appData.monoMode) {
        vFrom.addr = (caddr_t) appData.blackPieceColor;
        vFrom.size = strlen(appData.blackPieceColor);
 -      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
 +      //      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
        if (vTo.addr == NULL) {
          appData.monoMode = True;
          forceMono = True;
      if (!appData.monoMode) {
        vFrom.addr = (caddr_t) appData.highlightSquareColor;
        vFrom.size = strlen(appData.highlightSquareColor);
 -      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
 +      //      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
        if (vTo.addr == NULL) {
          appData.monoMode = True;
          forceMono = True;
      if (!appData.monoMode) {
        vFrom.addr = (caddr_t) appData.premoveHighlightColor;
        vFrom.size = strlen(appData.premoveHighlightColor);
 -      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
 +      //      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
        if (vTo.addr == NULL) {
          appData.monoMode = True;
          forceMono = True;
      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;
      if (appData.lowTimeWarning && !appData.monoMode) {
        vFrom.addr = (caddr_t) appData.lowTimeWarningColor;
        vFrom.size = strlen(appData.lowTimeWarningColor);
 -      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
 -      if (vTo.addr == NULL) 
 +      //      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
 +      if (vTo.addr == NULL)
                appData.monoMode = True;
        else
                lowTimeWarningColor = *(Pixel *) vTo.addr;
      }
  
 -    if (appData.monoMode && appData.debugMode) {
 -      fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
 -              (unsigned long) XWhitePixel(xDisplay, xScreen),
 -              (unsigned long) XBlackPixel(xDisplay, xScreen));
 -    }
 -
      if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
        parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
        parse_cpair(ColorChannel1, appData.colorChannel1) < 0  ||
      textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
      textColors[ColorNone].attr = 0;
  
 -    XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
 +    //    XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
  
      /*
       * widget hierarchy
      } else {
        layoutName = "normalLayout";
      }
 -    /* Outer layoutWidget is there only to provide a name for use in
 -       resources that depend on the layout style */
 -    layoutWidget =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
 -                          layoutArgs, XtNumber(layoutArgs));
 -    formWidget =
 -      XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
 -                          formArgs, XtNumber(formArgs));
 -    XtSetArg(args[0], XtNdefaultDistance, &sep);
 -    XtGetValues(formWidget, args, 1);
 -
 -    j = 0;
 -    widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
 -    XtSetArg(args[0], XtNtop,    XtChainTop);
 -    XtSetArg(args[1], XtNbottom, XtChainTop);
 -    XtSetArg(args[2], XtNright,  XtChainLeft);
 -    XtSetValues(menuBarWidget, args, 3);
 -
 -    widgetList[j++] = whiteTimerWidget =
 -      XtCreateWidget("whiteTime", labelWidgetClass,
 -                   formWidget, timerArgs, XtNumber(timerArgs));
 -    XtSetArg(args[0], XtNfont, clockFontStruct);
 -    XtSetArg(args[1], XtNtop,    XtChainTop);
 -    XtSetArg(args[2], XtNbottom, XtChainTop);
 -    XtSetValues(whiteTimerWidget, args, 3);
 -
 -    widgetList[j++] = blackTimerWidget =
 -      XtCreateWidget("blackTime", labelWidgetClass,
 -                   formWidget, timerArgs, XtNumber(timerArgs));
 -    XtSetArg(args[0], XtNfont, clockFontStruct);
 -    XtSetArg(args[1], XtNtop,    XtChainTop);
 -    XtSetArg(args[2], XtNbottom, XtChainTop);
 -    XtSetValues(blackTimerWidget, args, 3);
  
      if (appData.titleInWindow) {
 -      widgetList[j++] = titleWidget =
 -        XtCreateWidget("title", labelWidgetClass, formWidget,
 -                       titleArgs, XtNumber(titleArgs));
 -      XtSetArg(args[0], XtNtop,    XtChainTop);
 -      XtSetArg(args[1], XtNbottom, XtChainTop);
 -      XtSetValues(titleWidget, args, 2);
 +      /* todo check what this appdata does */
      }
  
      if (appData.showButtonBar) {
 -      widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
 -      XtSetArg(args[0], XtNleft,  XtChainRight); // [HGM] glue to right window edge
 -      XtSetArg(args[1], XtNright, XtChainRight); //       for good run-time sizing
 -      XtSetArg(args[2], XtNtop,    XtChainTop);
 -      XtSetArg(args[3], XtNbottom, XtChainTop);
 -      XtSetValues(buttonBarWidget, args, 4);
 +      /* TODO hide button bar if requested */
      }
  
 -    widgetList[j++] = messageWidget =
 -      XtCreateWidget("message", labelWidgetClass, formWidget,
 -                   messageArgs, XtNumber(messageArgs));
 -    XtSetArg(args[0], XtNtop,    XtChainTop);
 -    XtSetArg(args[1], XtNbottom, XtChainTop);
 -    XtSetValues(messageWidget, args, 2);
 -
 -    widgetList[j++] = boardWidget =
 -      XtCreateWidget("board", widgetClass, formWidget, boardArgs,
 -                   XtNumber(boardArgs));
  
 -    XtManageChildren(widgetList, j);
 +    if (appData.titleInWindow)
 +      {
 +      if (smallLayout)
 +        {
 +          /* make it small */
 +          if (appData.showButtonBar)
 +            {
  
 -    timerWidth = (boardWidth - sep) / 2;
 -    XtSetArg(args[0], XtNwidth, timerWidth);
 -    XtSetValues(whiteTimerWidget, args, 1);
 -    XtSetValues(blackTimerWidget, args, 1);
 +            }
 +        }
 +      else
 +        {
 +          if (appData.showButtonBar)
 +            {
 +            }
 +        }
 +      }
 +    else
 +      {
 +      }
  
 -    XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
 -    XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
 -    XtGetValues(whiteTimerWidget, args, 2);
  
 -    if (appData.showButtonBar) {
 -      XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
 -      XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
 -      XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
 -    }
 +    /* set some checkboxes in the menu according to appData */
  
 -    /*
 -     * formWidget uses these constraints but they are stored
 -     * in the children.
 -     */
 -    i = 0;
 -    XtSetArg(args[i], XtNfromHoriz, 0); i++;
 -    XtSetValues(menuBarWidget, args, i);
 -    if (appData.titleInWindow) {
 -      if (smallLayout) {
 -          i = 0;
 -          XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
 -          XtSetValues(whiteTimerWidget, args, i);
 -          i = 0;
 -          XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
 -          XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
 -          XtSetValues(blackTimerWidget, args, i);
 -          i = 0;
 -          XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
 -            XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
 -          XtSetValues(titleWidget, args, i);
 -          i = 0;
 -          XtSetArg(args[i], XtNfromVert, titleWidget); i++;
 -          XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
 -          XtSetValues(messageWidget, args, i);
 -          if (appData.showButtonBar) {
 -            i = 0;
 -            XtSetArg(args[i], XtNfromVert, titleWidget); i++;
 -            XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
 -            XtSetValues(buttonBarWidget, args, i);
 -          }
 -      } else {
 -          i = 0;
 -          XtSetArg(args[i], XtNfromVert, titleWidget); i++;
 -          XtSetValues(whiteTimerWidget, args, i);
 -          i = 0;
 -          XtSetArg(args[i], XtNfromVert, titleWidget); i++;
 -          XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
 -          XtSetValues(blackTimerWidget, args, i);
 -          i = 0;
 -          XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
 -          XtSetValues(titleWidget, args, i);
 -          i = 0;
 -          XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
 -          XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
 -          XtSetValues(messageWidget, args, i);
 -          if (appData.showButtonBar) {
 -            i = 0;
 -            XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
 -            XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
 -            XtSetValues(buttonBarWidget, args, i);
 -          }
 -      }
 -    } else {
 -      i = 0;
 -      XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
 -      XtSetValues(whiteTimerWidget, args, i);
 -      i = 0;
 -      XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
 -      XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
 -      XtSetValues(blackTimerWidget, args, i);
 -      i = 0;
 -      XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
 -      XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
 -      XtSetValues(messageWidget, args, i);
 -      if (appData.showButtonBar) {
 -        i = 0;
 -        XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
 -        XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
 -        XtSetValues(buttonBarWidget, args, i);
 -      }
 -    }
 -    i = 0;
 -    XtSetArg(args[0], XtNfromVert, messageWidget);
 -    XtSetArg(args[1], XtNtop,    XtChainTop);
 -    XtSetArg(args[2], XtNbottom, XtChainBottom);
 -    XtSetArg(args[3], XtNleft,   XtChainLeft);
 -    XtSetArg(args[4], XtNright,  XtChainRight);
 -    XtSetValues(boardWidget, args, 5);
 -
 -    XtRealizeWidget(shellWidget);
 -
 -    if(wpMain.x > 0) {
 -      XtSetArg(args[0], XtNx, wpMain.x);
 -      XtSetArg(args[1], XtNy, wpMain.y);
 -      XtSetValues(shellWidget, args, 2);
 -    }
 +    if (appData.alwaysPromoteToQueen)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Always Queen")),TRUE);
  
 -    /*
 -     * Correct the width of the message and title widgets.
 -     * It is not known why some systems need the extra fudge term.
 -     * The value "2" is probably larger than needed.
 -     */
 -    XawFormDoLayout(formWidget, False);
 +    if (appData.animateDragging)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Animate Dragging")),TRUE);
  
 -#define WIDTH_FUDGE 2
 -    i = 0;
 -    XtSetArg(args[i], XtNborderWidth, &bor);  i++;
 -    XtSetArg(args[i], XtNheight, &h);  i++;
 -    XtGetValues(messageWidget, args, i);
 -    if (appData.showButtonBar) {
 -      i = 0;
 -      XtSetArg(args[i], XtNwidth, &w);  i++;
 -      XtGetValues(buttonBarWidget, args, i);
 -      w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
 -    } else {
 -      w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
 -    }
 +    if (appData.animate)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Animate Moving")),TRUE);
  
 -    gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
 -    if (gres != XtGeometryYes && appData.debugMode) {
 -      fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
 -            programName, gres, w, h, wr, hr);
 -    }
 +    if (appData.autoComment)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Comment")),TRUE);
  
 -    /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
 -    /* The size used for the child widget in layout lags one resize behind
 -       its true size, so we resize a second time, 1 pixel smaller.  Yeech! */
 -    w--;
 -    gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
 -    if (gres != XtGeometryYes && appData.debugMode) {
 -      fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
 -            programName, gres, w, h, wr, hr);
 -    }
 -    /* !! end hack */
 -    XtSetArg(args[0], XtNleft,  XtChainLeft);  // [HGM] glue ends for good run-time sizing
 -    XtSetArg(args[1], XtNright, XtChainRight);
 -    XtSetValues(messageWidget, args, 2);
 +    if (appData.autoCallFlag)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Flag")),TRUE);
  
 -    if (appData.titleInWindow) {
 -      i = 0;
 -      XtSetArg(args[i], XtNborderWidth, &bor); i++;
 -      XtSetArg(args[i], XtNheight, &h);  i++;
 -      XtGetValues(titleWidget, args, i);
 -      if (smallLayout) {
 -          w = boardWidth - 2*bor;
 -      } else {
 -          XtSetArg(args[0], XtNwidth, &w);
 -          XtGetValues(menuBarWidget, args, 1);
 -          w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
 -      }
 +    if (appData.autoFlipView)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Flip View")),TRUE);
  
 -      gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
 -      if (gres != XtGeometryYes && appData.debugMode) {
 -          fprintf(stderr,
 -                  _("%s: titleWidget geometry error %d %d %d %d %d\n"),
 -                  programName, gres, w, h, wr, hr);
 -      }
 -    }
 -    XawFormDoLayout(formWidget, True);
 +    if (appData.autoObserve)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Observe")),TRUE);
  
 -    xBoardWindow = XtWindow(boardWidget);
 +    if (appData.autoRaiseBoard)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Raise Board")),TRUE);
  
 -    // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
 -    //       not need to go into InitDrawingSizes().
 -#endif
 +    if (appData.autoSaveGames)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Save")),TRUE);
  
 -    /*
 -     * Create X checkmark bitmap and initialize option menu checks.
 -     */
 -    ReadBitmap(&xMarkPixmap, "checkmark.bm",
 -             checkmark_bits, checkmark_width, checkmark_height);
 -    XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    if (appData.alwaysPromoteToQueen) {
 -      XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
 -                  args, 1);
 -    }
 -    if (appData.animateDragging) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,
 -                                 "menuOptions.Animate Dragging"),
 -                  args, 1);
 -    }
 -    if (appData.animate) {
 -      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);
 -    }
 -    if (appData.autoFlipView) {
 -      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) {
 +    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);
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Save")),TRUE);
 +      gtk_action_set_sensitive(GTK_ACTION (gtk_builder_get_object (builder, "menuOptions.Auto Save")),FALSE);
 +      }
 +
 +    if (appData.blindfold)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Blindfold")),TRUE);
 +
 +    if (appData.flashCount > 0)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Flash Moves")),TRUE);
 +
 +    if (appData.getMoveList)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Get Move List")),TRUE);
  
 -    }
 -    if (appData.blindfold) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,
 -                                 "menuOptions.Blindfold"), args, 1);
 -    }
 -    if (appData.flashCount > 0) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,
 -                                 "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,
 -                                 "menuOptions.Highlight Dragging"),
 -                  args, 1);
 -    }
 +    if (appData.highlightDragging)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Highlight Dragging")),TRUE);
  #endif
 -    if (appData.highlightLastMove) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,
 -                                 "menuOptions.Highlight Last Move"),
 -                  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) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,
 -                                 "menuOptions.Old Save Style"), args, 1);
 -    }
 -    if (appData.periodicUpdates) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,
 -                                 "menuOptions.Periodic Updates"), args, 1);
 -    }
 -    if (appData.ponderNextMove) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,
 -                                 "menuOptions.Ponder Next Move"), args, 1);
 -    }
 -    if (appData.popupExitMessage) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,
 -                                 "menuOptions.Popup Exit Message"), args, 1);
 -    }
 -    if (appData.popupMoveErrors) {
 -      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.showCoords) {
 -      XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
 -                  args, 1);
 -    }
 -    if (appData.hideThinkingFromHuman) {
 -      XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
 -                  args, 1);
 -    }
 -    if (appData.testLegality) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
 -                  args, 1);
 -    }
 -    if (saveSettingsOnExit) {
 -      XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Save Settings on Exit"),
 -                  args, 1);
 -    }
  
 -    /*
 -     * Create an icon.
 -     */
 -    ReadBitmap(&wIconPixmap, "icon_white.bm",
 -             icon_white_bits, icon_white_width, icon_white_height);
 -    ReadBitmap(&bIconPixmap, "icon_black.bm",
 -             icon_black_bits, icon_black_width, icon_black_height);
 -    iconPixmap = wIconPixmap;
 -    i = 0;
 -    XtSetArg(args[i], XtNiconPixmap, iconPixmap);  i++;
 -    XtSetValues(shellWidget, args, i);
 +    if (appData.highlightLastMove)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Highlight Last Move")),TRUE);
  
 -    /*
 -     * Create a cursor for the board widget.
 -     */
 -    window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
 -    XChangeWindowAttributes(xDisplay, xBoardWindow,
 -                          CWCursor, &window_attributes);
 +    if (appData.icsAlarm)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.ICS Alarm")),TRUE);
  
 -    /*
 -     * Inhibit shell resizing.
 -     */
 -    shellArgs[0].value = (XtArgVal) &w;
 -    shellArgs[1].value = (XtArgVal) &h;
 -    XtGetValues(shellWidget, shellArgs, 2);
 -    shellArgs[4].value = shellArgs[2].value = w;
 -    shellArgs[5].value = shellArgs[3].value = h;
 -    XtSetValues(shellWidget, &shellArgs[2], 4);
 -    marginW =  w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
 -    marginH =  h - boardHeight;
 +    if (appData.ringBellAfterMoves)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Move Sound")),TRUE);
  
 -    CatchDeleteWindow(shellWidget, "QuitProc");
 +    if (appData.oldSaveStyle)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Old Save Style")),TRUE);
  
 -    CreateGCs();
 -    CreateGrid();
 -#if HAVE_LIBXPM
 -    if (appData.bitmapDirectory[0] != NULLCHAR) {
 -      CreatePieces();
 -    } else {
 -      CreateXPMPieces();
 -    }
 -#else
 -    CreateXIMPieces();
 -    /* Create regular pieces */
 -    if (!useImages) CreatePieces();
 -#endif
 +    if (appData.periodicUpdates)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Periodic Updates")),TRUE);
 +
 +    if (appData.ponderNextMove)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Ponder Next Move")),TRUE);
 +
 +    if (appData.popupExitMessage)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Popup Exit Message")),TRUE);
 +
 +    if (appData.popupMoveErrors)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Popup Move Errors")),TRUE);
  
 +    if (appData.premove)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Premove")),TRUE);
 +
 +    if (appData.quietPlay)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Quit Play")),TRUE);
 +
 +    if (appData.showCoords)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Show Coords")),TRUE);
 +
 +    if (appData.showThinking)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Hide Thinking")),TRUE);
 +
 +    if (appData.testLegality)
 +      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Test Legality")),TRUE);
 +
 +    // TODO: add
 +    //    if (saveSettingsOnExit) {
 +    //        XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Save Settings on Exit"),
 +    //                    args, 1);
 +    //   }
 +
 +
 +    /* end setting check boxes */
 +
 +    /* load square colors */
 +    SVGLightSquare   = load_pixbuf("svg/LightSquare.svg",squareSize);
 +    SVGDarkSquare    = load_pixbuf("svg/DarkSquare.svg",squareSize);
 +    SVGNeutralSquare = load_pixbuf("svg/NeutralSquare.svg",squareSize);
 +
 +    /* use two icons to indicate if it is white's or black's turn */
 +    WhiteIcon  = load_pixbuf("svg/icon_white.svg",0);
 +    BlackIcon  = load_pixbuf("svg/icon_black.svg",0);
 +    WindowIcon = WhiteIcon;
 +    gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
 +
 +
 +    /* realize window */
 +    gtk_widget_show (GUI_Window);
 +
 +    /* recalc boardsize */
 +    CreateGCs();
 +    CreatePieces();
      CreatePieceMenus();
  
      if (appData.animate || appData.animateDragging)
        CreateAnimVars();
  
 -    XtAugmentTranslations(formWidget,
 -                        XtParseTranslationTable(globalTranslations));
 -    XtAugmentTranslations(boardWidget,
 -                        XtParseTranslationTable(boardTranslations));
 -    XtAugmentTranslations(whiteTimerWidget,
 -                        XtParseTranslationTable(whiteTranslations));
 -    XtAugmentTranslations(blackTimerWidget,
 -                        XtParseTranslationTable(blackTranslations));
 -
 -    /* Why is the following needed on some versions of X instead
 -     * of a translation? */
 -    XtAddEventHandler(boardWidget, ExposureMask|PointerMotionMask, False,
 -                    (XtEventHandler) EventProc, NULL);
 -    /* end why */
 -
+     /* [AS] Restore layout */
+     if( wpMoveHistory.visible ) {
+       HistoryPopUp();
+     }
+     if( wpEvalGraph.visible ) 
+       {
+       EvalGraphPopUp();
+       };
+     
+     if( wpEngineOutput.visible ) {
+       EngineOutputPopUp();
+     }
      InitBackEnd2();
  
      if (errorExitStatus == -1) {
      gameInfo.boardWidth = 0; // [HGM] pieces: kludge to ensure InitPosition() calls InitDrawingSizes()
      InitPosition(TRUE);
  
 -    XtAppMainLoop(appContext);
 +    /*
 +     * Create a cursor for the board widget.
 +     * (This needs to be called after the window has been created to have access to board-window)
 +     */
 +
 +    BoardCursor = gdk_cursor_new(GDK_HAND2);
 +    gdk_window_set_cursor(GUI_Board->window, BoardCursor);
 +    gdk_cursor_destroy(BoardCursor);
 +
 +    /* end cursor */
 +    gtk_main ();
 +
      if (appData.debugMode) fclose(debugFP); // [DM] debug
      return 0;
  }
@@@ -1991,6 -2596,11 +2041,6 @@@ ResetFrontEnd(
      return;
  }
  
 -typedef struct {
 -    char *name;
 -    Boolean value;
 -} Enables;
 -
  void
  GreyRevert(grey)
       Boolean grey;
  SetMenuEnables(enab)
       Enables *enab;
  {
 -  Widget w;
 -  if (!menuBarWidget) return;
 +  GObject *o;
 +
 +  if (!builder) return;
    while (enab->name != NULL) {
 -    w = XtNameToWidget(menuBarWidget, enab->name);
 -    if (w == NULL) {
 -      DisplayError(enab->name, 0);
 -    } else {
 -      XtSetSensitive(w, enab->value);
 -    }
 +    o = gtk_builder_get_object(builder, enab->name);
 +    if(GTK_IS_WIDGET(o))
 +      gtk_widget_set_sensitive(GTK_WIDGET (o),enab->value);
 +    else
 +      {
 +      if(GTK_IS_ACTION(o))
 +        gtk_action_set_sensitive(GTK_ACTION (o),enab->value);
 +      else
 +        DisplayError(enab->name, 0);
 +      }
      enab++;
    }
  }
  
 -Enables icsEnables[] = {
 -    { "menuFile.Mail Move", False },
 -    { "menuFile.Reload CMail Message", False },
 -    { "menuMode.Machine Black", False },
 -    { "menuMode.Machine White", False },
 -    { "menuMode.Analysis Mode", False },
 -    { "menuMode.Analyze File", False },
 -    { "menuMode.Two Machines", False },
 -#ifndef ZIPPY
 -    { "menuHelp.Hint", False },
 -    { "menuHelp.Book", False },
 -    { "menuStep.Move Now", False },
 -    { "menuOptions.Periodic Updates", False },
 -    { "menuOptions.Hide Thinking", False },
 -    { "menuOptions.Ponder Next Move", False },
 -#endif
 -    { NULL, False }
 -};
 -
 -Enables ncpEnables[] = {
 -    { "menuFile.Mail Move", False },
 -    { "menuFile.Reload CMail Message", False },
 -    { "menuMode.Machine White", False },
 -    { "menuMode.Machine Black", False },
 -    { "menuMode.Analysis Mode", False },
 -    { "menuMode.Analyze File", False },
 -    { "menuMode.Two Machines", False },
 -    { "menuMode.ICS Client", False },
 -    { "menuMode.ICS Input Box", False },
 -    { "Action", False },
 -    { "menuStep.Revert", False },
 -    { "menuStep.Move Now", False },
 -    { "menuStep.Retract Move", False },
 -    { "menuOptions.Auto Comment", False },
 -    { "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.Move Sound", False },
 -    { "menuOptions.Quiet Play", False },
 -    { "menuOptions.Hide Thinking", False },
 -    { "menuOptions.Periodic Updates", False },
 -    { "menuOptions.Ponder Next Move", False },
 -    { "menuHelp.Hint", False },
 -    { "menuHelp.Book", False },
 -    { NULL, False }
 -};
 -
 -Enables gnuEnables[] = {
 -    { "menuMode.ICS Client", False },
 -    { "menuMode.ICS Input Box", False },
 -    { "menuAction.Accept", False },
 -    { "menuAction.Decline", False },
 -    { "menuAction.Rematch", False },
 -    { "menuAction.Adjourn", False },
 -    { "menuAction.Stop Examining", False },
 -    { "menuAction.Stop Observing", False },
 -    { "menuStep.Revert", 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 },
 -
 -    /* The next two options rely on SetCmailMode being called *after*    */
 -    /* SetGNUMode so that when GNU is being used to give hints these     */
 -    /* menu options are still available                                  */
 -
 -    { "menuFile.Mail Move", False },
 -    { "menuFile.Reload CMail Message", False },
 -    { NULL, False }
 -};
 -
 -Enables cmailEnables[] = {
 -    { "Action", True },
 -    { "menuAction.Call Flag", False },
 -    { "menuAction.Draw", True },
 -    { "menuAction.Adjourn", False },
 -    { "menuAction.Abort", False },
 -    { "menuAction.Stop Observing", False },
 -    { "menuAction.Stop Examining", False },
 -    { "menuFile.Mail Move", True },
 -    { "menuFile.Reload CMail Message", True },
 -    { NULL, False }
 -};
 -
 -Enables trainingOnEnables[] = {
 -  { "menuMode.Edit Comment", False },
 -  { "menuMode.Pause", False },
 -  { "menuStep.Forward", False },
 -  { "menuStep.Backward", False },
 -  { "menuStep.Forward to End", False },
 -  { "menuStep.Back to Start", False },
 -  { "menuStep.Move Now", False },
 -  { "menuStep.Truncate Game", False },
 -  { NULL, False }
 -};
 -
 -Enables trainingOffEnables[] = {
 -  { "menuMode.Edit Comment", True },
 -  { "menuMode.Pause", True },
 -  { "menuStep.Forward", True },
 -  { "menuStep.Backward", True },
 -  { "menuStep.Forward to End", True },
 -  { "menuStep.Back to Start", True },
 -  { "menuStep.Move Now", True },
 -  { "menuStep.Truncate Game", True },
 -  { NULL, False }
 -};
 -
 -Enables machineThinkingEnables[] = {
 -  { "menuFile.Load Game", False },
 -  { "menuFile.Load Next Game", False },
 -  { "menuFile.Load Previous Game", False },
 -  { "menuFile.Reload Same Game", False },
 -  { "menuFile.Paste Game", False },
 -  { "menuFile.Load Position", False },
 -  { "menuFile.Load Next Position", False },
 -  { "menuFile.Load Previous Position", False },
 -  { "menuFile.Reload Same Position", False },
 -  { "menuFile.Paste Position", False },
 -  { "menuMode.Machine White", False },
 -  { "menuMode.Machine Black", False },
 -  { "menuMode.Two Machines", False },
 -  { "menuStep.Retract Move", False },
 -  { NULL, False }
 -};
 -
 -Enables userThinkingEnables[] = {
 -  { "menuFile.Load Game", True },
 -  { "menuFile.Load Next Game", True },
 -  { "menuFile.Load Previous Game", True },
 -  { "menuFile.Reload Same Game", True },
 -  { "menuFile.Paste Game", True },
 -  { "menuFile.Load Position", True },
 -  { "menuFile.Load Next Position", True },
 -  { "menuFile.Load Previous Position", True },
 -  { "menuFile.Reload Same Position", True },
 -  { "menuFile.Paste Position", True },
 -  { "menuMode.Machine White", True },
 -  { "menuMode.Machine Black", True },
 -  { "menuMode.Two Machines", True },
 -  { "menuStep.Retract Move", True },
 -  { NULL, False }
 -};
 -
  void SetICSMode()
  {
    SetMenuEnables(icsEnables);
  
  #ifdef ZIPPY
    if (appData.zippyPlay && !appData.noChessProgram)   /* [DM] icsEngineAnalyze */
 -     XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
 +    {}; //     XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
  #endif
  }
  
@@@ -2060,7 -2814,7 +2110,7 @@@ SetTrainingModeOn(
  {
    SetMenuEnables(trainingOnEnables);
    if (appData.showButtonBar) {
 -    XtSetSensitive(buttonBarWidget, False);
 +    //    XtSetSensitive(buttonBarWidget, False);
    }
    CommentPopDown();
  }
@@@ -2070,7 -2824,7 +2120,7 @@@ SetTrainingModeOff(
  {
    SetMenuEnables(trainingOffEnables);
    if (appData.showButtonBar) {
 -    XtSetSensitive(buttonBarWidget, True);
 +    //    XtSetSensitive(buttonBarWidget, True);
    }
  }
  
@@@ -2090,8 -2844,8 +2140,8 @@@ SetMachineThinkingEnables(
    case MachinePlaysBlack:
    case MachinePlaysWhite:
    case TwoMachinesPlay:
 -    XtSetSensitive(XtNameToWidget(menuBarWidget,
 -                                ModeToWidgetName(gameMode)), True);
 +//    XtSetSensitive(XtNameToWidget(menuBarWidget,
 +//                              ModeToWidgetName(gameMode)), True);
      break;
    default:
      break;
@@@ -2142,12 -2896,12 +2192,12 @@@ char *FindFont(pattern, targetPxlSize
  
      nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
  #else
 -    fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
 -    if (nfonts < 1) {
 -      fprintf(stderr, _("%s: no fonts match pattern %s\n"),
 -              programName, pattern);
 -      exit(2);
 -    }
 +//    fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
 +//    if (nfonts < 1) {
 +//    fprintf(stderr, _("%s: no fonts match pattern %s\n"),
 +//            programName, pattern);
 +//    exit(2);
 +//    }
  #endif
  
      best = fonts[0];
  #ifdef ENABLE_NLS
      if (missing_count > 0)
         XFreeStringList(missing_list);
 -    XFreeFontSet(xDisplay, fntSet);
 +    //    XFreeFontSet(xDisplay, fntSet);
  #else
       XFreeFontNames(fonts);
  #endif
  
  void CreateGCs()
  {
 -    XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
 -      | GCBackground | GCFunction | GCPlaneMask;
 -    XGCValues gc_values;
 -    GC copyInvertedGC;
 -
 -    gc_values.plane_mask = AllPlanes;
 -    gc_values.line_width = lineGap;
 -    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);
 -
 -    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
 -    gc_values.foreground = XWhitePixel(xDisplay, xScreen);
 -    gc_values.background = XBlackPixel(xDisplay, xScreen);
 -    countGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -    XSetFont(xDisplay, countGC, countFontID);
 -
 -    if (appData.monoMode) {
 -      gc_values.foreground = XWhitePixel(xDisplay, xScreen);
 -      gc_values.background = XWhitePixel(xDisplay, xScreen);
 -      highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = XWhitePixel(xDisplay, xScreen);
 -      gc_values.background = XBlackPixel(xDisplay, xScreen);
 -      lightSquareGC = wbPieceGC
 -        = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = XBlackPixel(xDisplay, xScreen);
 -      gc_values.background = XWhitePixel(xDisplay, xScreen);
 -      darkSquareGC = bwPieceGC
 -        = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      if (DefaultDepth(xDisplay, xScreen) == 1) {
 -          /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
 -          gc_values.function = GXcopyInverted;
 -          copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -          gc_values.function = GXcopy;
 -          if (XBlackPixel(xDisplay, xScreen) == 1) {
 -              bwPieceGC = darkSquareGC;
 -              wbPieceGC = copyInvertedGC;
 -          } else {
 -              bwPieceGC = copyInvertedGC;
 -              wbPieceGC = lightSquareGC;
 -          }
 -      }
 -    } else {
 -      gc_values.foreground = highlightSquareColor;
 -      gc_values.background = highlightSquareColor;
 -      highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = premoveHighlightColor;
 -      gc_values.background = premoveHighlightColor;
 -      prelineGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = lightSquareColor;
 -      gc_values.background = darkSquareColor;
 -      lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = darkSquareColor;
 -      gc_values.background = lightSquareColor;
 -      darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = jailSquareColor;
 -      gc_values.background = jailSquareColor;
 -      jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = whitePieceColor;
 -      gc_values.background = darkSquareColor;
 -      wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = whitePieceColor;
 -      gc_values.background = lightSquareColor;
 -      wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = whitePieceColor;
 -      gc_values.background = jailSquareColor;
 -      wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = blackPieceColor;
 -      gc_values.background = darkSquareColor;
 -      bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = blackPieceColor;
 -      gc_values.background = lightSquareColor;
 -      blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -
 -      gc_values.foreground = blackPieceColor;
 -      gc_values.background = jailSquareColor;
 -      bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
 -    }
 -}
 -
 -void loadXIM(xim, xmask, filename, dest, mask)
 -     XImage *xim;
 -     XImage *xmask;
 -     char *filename;
 -     Pixmap *dest;
 -     Pixmap *mask;
 -{
 -    int x, y, w, h, p;
 -    FILE *fp;
 -    Pixmap temp;
 -    XGCValues values;
 -    GC maskGC;
 -
 -    fp = fopen(filename, "rb");
 -    if (!fp) {
 -      fprintf(stderr, _("%s: error loading XIM!\n"), programName);
 -      exit(1);
 -    }
 -
 -    w = fgetc(fp);
 -    h = fgetc(fp);
 -
 -    for (y=0; y<h; ++y) {
 -      for (x=0; x<h; ++x) {
 -          p = fgetc(fp);
 -
 -          switch (p) {
 -            case 0:
 -              XPutPixel(xim, x, y, blackPieceColor);
 -              if (xmask)
 -                XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
 -              break;
 -            case 1:
 -              XPutPixel(xim, x, y, darkSquareColor);
 -              if (xmask)
 -                XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
 -              break;
 -            case 2:
 -              XPutPixel(xim, x, y, whitePieceColor);
 -              if (xmask)
 -                XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
 -              break;
 -            case 3:
 -              XPutPixel(xim, x, y, lightSquareColor);
 -              if (xmask)
 -                XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
 -              break;
 -          }
 -      }
 -    }
 -
 -    /* create Pixmap of piece */
 -    *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
 -                        w, h, xim->depth);
 -    XPutImage(xDisplay, *dest, lightSquareGC, xim,
 -            0, 0, 0, 0, w, h);
 -
 -    /* create Pixmap of clipmask
 -       Note: We assume the white/black pieces have the same
 -             outline, so we make only 6 masks. This is okay
 -             since the XPM clipmask routines do the same. */
 -    if (xmask) {
 -      temp = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
 -                          w, h, xim->depth);
 -      XPutImage(xDisplay, temp, lightSquareGC, xmask,
 -            0, 0, 0, 0, w, h);
 -
 -      /* now create the 1-bit version */
 -      *mask = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
 -                        w, h, 1);
 -
 -      values.foreground = 1;
 -      values.background = 0;
 -
 -      /* Don't use XtGetGC, not read only */
 -      maskGC = XCreateGC(xDisplay, *mask,
 -                  GCForeground | GCBackground, &values);
 -      XCopyPlane(xDisplay, temp, *mask, maskGC,
 -                0, 0, squareSize, squareSize, 0, 0, 1);
 -      XFreePixmap(xDisplay, temp);
 -    }
 -}
 -
 -
 -char pieceBitmapNames[] = "pnbrqfeacwmohijgdvlsukpnsl";
 -
 -void CreateXIMPieces()
 -{
 -    int piece, kind;
 -    char buf[MSG_SIZ];
 -    u_int ss;
 -    static char *ximkind[] = { "ll", "ld", "dl", "dd" };
 -    XImage *ximtemp;
 -
 -    ss = squareSize;
 -
 -    /* The XSynchronize calls were copied from CreatePieces.
 -       Not sure if needed, but can't hurt */
 -    XSynchronize(xDisplay, True); /* Work-around for xlib/xt
 -                                   buffering bug */
 -
 -    /* temp needed by loadXIM() */
 -    ximtemp = XGetImage(xDisplay, DefaultRootWindow(xDisplay),
 -               0, 0, ss, ss, AllPlanes, XYPixmap);
 -
 -    if (strlen(appData.pixmapDirectory) == 0) {
 -      useImages = 0;
 -    } else {
 -      useImages = 1;
 -      if (appData.monoMode) {
 -        DisplayFatalError(_("XIM pieces cannot be used in monochrome mode"),
 -                          0, 2);
 -        ExitEvent(2);
 -      }
 -      fprintf(stderr, _("\nLoading XIMs...\n"));
 -      /* Load pieces */
 -      for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
 -          fprintf(stderr, "%d", piece+1);
 -          for (kind=0; kind<4; kind++) {
 -              fprintf(stderr, ".");
 -              snprintf(buf, sizeof(buf), "%s/%s%c%s%u.xim",
 -                      ExpandPathName(appData.pixmapDirectory),
 -                      piece <= (int) WhiteKing ? "" : "w",
 -                      pieceBitmapNames[piece],
 -                      ximkind[kind], ss);
 -              ximPieceBitmap[kind][piece] =
 -                XGetImage(xDisplay, DefaultRootWindow(xDisplay),
 -                          0, 0, ss, ss, AllPlanes, XYPixmap);
 -              if (appData.debugMode)
 -                fprintf(stderr, _("(File:%s:) "), buf);
 -              loadXIM(ximPieceBitmap[kind][piece],
 -                      ximtemp, buf,
 -                      &(xpmPieceBitmap2[kind][piece]),
 -                      &(ximMaskPm2[piece]));
 -              if(piece <= (int)WhiteKing)
 -                  xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
 -          }
 -          fprintf(stderr," ");
 -      }
 -      /* Load light and dark squares */
 -      /* If the LSQ and DSQ pieces don't exist, we will
 -         draw them with solid squares. */
 -      snprintf(buf,sizeof(buf), "%s/lsq%u.xim", ExpandPathName(appData.pixmapDirectory), ss);
 -      if (access(buf, 0) != 0) {
 -          useImageSqs = 0;
 -      } else {
 -          useImageSqs = 1;
 -          fprintf(stderr, _("light square "));
 -          ximLightSquare=
 -            XGetImage(xDisplay, DefaultRootWindow(xDisplay),
 -                      0, 0, ss, ss, AllPlanes, XYPixmap);
 -          if (appData.debugMode)
 -            fprintf(stderr, _("(File:%s:) "), buf);
 -
 -          loadXIM(ximLightSquare, NULL, buf, &xpmLightSquare, NULL);
 -          fprintf(stderr, _("dark square "));
 -          snprintf(buf,sizeof(buf), "%s/dsq%u.xim",
 -                  ExpandPathName(appData.pixmapDirectory), ss);
 -          if (appData.debugMode)
 -            fprintf(stderr, _("(File:%s:) "), buf);
 -          ximDarkSquare=
 -            XGetImage(xDisplay, DefaultRootWindow(xDisplay),
 -                      0, 0, ss, ss, AllPlanes, XYPixmap);
 -          loadXIM(ximDarkSquare, NULL, buf, &xpmDarkSquare, NULL);
 -          xpmJailSquare = xpmLightSquare;
 -      }
 -      fprintf(stderr, _("Done.\n"));
 -    }
 -    XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
 -}
 -
 -#if HAVE_LIBXPM
 -void CreateXPMPieces()
 -{
 -    int piece, kind, r;
 -    char buf[MSG_SIZ];
 -    u_int ss = squareSize;
 -    XpmAttributes attr;
 -    static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
 -    XpmColorSymbol symbols[4];
 -
 -    /* The XSynchronize calls were copied from CreatePieces.
 -       Not sure if needed, but can't hurt */
 -    XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */
 -
 -    /* Setup translations so piece colors match square colors */
 -    symbols[0].name = "light_piece";
 -    symbols[0].value = appData.whitePieceColor;
 -    symbols[1].name = "dark_piece";
 -    symbols[1].value = appData.blackPieceColor;
 -    symbols[2].name = "light_square";
 -    symbols[2].value = appData.lightSquareColor;
 -    symbols[3].name = "dark_square";
 -    symbols[3].value = appData.darkSquareColor;
 -
 -    attr.valuemask = XpmColorSymbols;
 -    attr.colorsymbols = symbols;
 -    attr.numsymbols = 4;
 -
 -    if (appData.monoMode) {
 -      DisplayFatalError(_("XPM pieces cannot be used in monochrome mode"),
 -                      0, 2);
 -      ExitEvent(2);
 -    }
 -    if (strlen(appData.pixmapDirectory) == 0) {
 -      XpmPieces* pieces = builtInXpms;
 -      useImages = 1;
 -      /* Load pieces */
 -      while (pieces->size != squareSize && pieces->size) pieces++;
 -      if (!pieces->size) {
 -        fprintf(stderr, _("No builtin XPM pieces of size %d\n"), squareSize);
 -        exit(1);
 -      }
 -      for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
 -          for (kind=0; kind<4; kind++) {
 -
 -              if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,
 -                                             pieces->xpm[piece][kind],
 -                                             &(xpmPieceBitmap2[kind][piece]),
 -                                             NULL, &attr)) != 0) {
 -                fprintf(stderr, _("Error %d loading XPM image \"%s\"\n"),
 -                        r, buf);
 -                exit(1);
 -              }
 -              if(piece <= (int) WhiteKing)
 -                  xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
 -          }
 -      }
 -      useImageSqs = 0;
 -      xpmJailSquare = xpmLightSquare;
 -    } else {
 -      useImages = 1;
 -
 -      fprintf(stderr, _("\nLoading XPMs...\n"));
 -
 -      /* Load pieces */
 -      for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
 -          fprintf(stderr, "%d ", piece+1);
 -          for (kind=0; kind<4; kind++) {
 -            snprintf(buf, sizeof(buf), "%s/%s%c%s%u.xpm",
 -                      ExpandPathName(appData.pixmapDirectory),
 -                      piece > (int) WhiteKing ? "w" : "",
 -                      pieceBitmapNames[piece],
 -                      xpmkind[kind], ss);
 -              if (appData.debugMode) {
 -                  fprintf(stderr, _("(File:%s:) "), buf);
 -              }
 -              if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
 -                                         &(xpmPieceBitmap2[kind][piece]),
 -                                         NULL, &attr)) != 0) {
 -                  if(piece != (int)WhiteKing && piece > (int)WhiteQueen) {
 -                    // [HGM] missing: read of unorthodox piece failed; substitute King.
 -                    snprintf(buf, sizeof(buf), "%s/k%s%u.xpm",
 -                              ExpandPathName(appData.pixmapDirectory),
 -                              xpmkind[kind], ss);
 -                      if (appData.debugMode) {
 -                          fprintf(stderr, _("(Replace by File:%s:) "), buf);
 -                      }
 -                      r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
 -                                              &(xpmPieceBitmap2[kind][piece]),
 -                                              NULL, &attr);
 -                  }
 -                  if (r != 0) {
 -                      fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"),
 -                              r, buf);
 -                      exit(1);
 -                  }
 -              }
 -              if(piece <= (int) WhiteKing) 
 -                  xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
 -          }
 -      }
 -      /* Load light and dark squares */
 -      /* If the LSQ and DSQ pieces don't exist, we will
 -         draw them with solid squares. */
 -      fprintf(stderr, _("light square "));
 -      snprintf(buf, sizeof(buf), "%s/lsq%u.xpm", ExpandPathName(appData.pixmapDirectory), ss);
 -      if (access(buf, 0) != 0) {
 -          useImageSqs = 0;
 -      } else {
 -          useImageSqs = 1;
 -          if (appData.debugMode)
 -            fprintf(stderr, _("(File:%s:) "), buf);
 -
 -          if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
 -                                     &xpmLightSquare, NULL, &attr)) != 0) {
 -              fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
 -              exit(1);
 -          }
 -          fprintf(stderr, _("dark square "));
 -          snprintf(buf, sizeof(buf), "%s/dsq%u.xpm",
 -                  ExpandPathName(appData.pixmapDirectory), ss);
 -          if (appData.debugMode) {
 -              fprintf(stderr, _("(File:%s:) "), buf);
 -          }
 -          if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
 -                                     &xpmDarkSquare, NULL, &attr)) != 0) {
 -              fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
 -              exit(1);
 -          }
 -      }
 -      xpmJailSquare = xpmLightSquare;
 -      fprintf(stderr, _("Done.\n"));
 -    }
 -    XSynchronize(xDisplay, False); /* Work-around for xlib/xt
 -                                    buffering bug */
 +  /* GCs are not needed anymore for GTK  just left them in here for the moment, since there is a lot of X-code still around that's wants them*/
 +  return;
  }
 -#endif /* HAVE_LIBXPM */
 -
 -#if HAVE_LIBXPM
 -/* No built-in bitmaps */
 -void CreatePieces()
 -{
 -    int piece, kind;
 -    char buf[MSG_SIZ];
 -    u_int ss = squareSize;
 -
 -    XSynchronize(xDisplay, True); /* Work-around for xlib/xt
 -                                   buffering bug */
 -
 -    for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
 -      for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
 -          sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
 -                  pieceBitmapNames[piece],
 -                  ss, kind == SOLID ? 's' : 'o');
 -          ReadBitmap(&pieceBitmap2[kind][piece], buf, NULL, ss, ss);
 -          if(piece <= (int)WhiteKing)
 -              pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
 -      }
 -    }
  
 -    XSynchronize(xDisplay, False); /* Work-around for xlib/xt
 -                                    buffering bug */
 -}
 -#else
 -/* With built-in bitmaps */
  void CreatePieces()
  {
 -    BuiltInBits* bib = builtInBits;
 -    int piece, kind;
 -    char buf[MSG_SIZ];
 -    u_int ss = squareSize;
 -
 -    XSynchronize(xDisplay, True); /* Work-around for xlib/xt
 -                                   buffering bug */
 -
 -    while (bib->squareSize != ss && bib->squareSize != 0) bib++;
 -
 -    for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
 -      for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
 -          sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
 -                  pieceBitmapNames[piece],
 -                  ss, kind == SOLID ? 's' : 'o');
 -          ReadBitmap(&pieceBitmap2[kind][piece], buf,
 -                     bib->bits[kind][piece], ss, ss);
 -          if(piece <= (int)WhiteKing)
 -              pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
 -      }
 -    }
 -
 -    XSynchronize(xDisplay, False); /* Work-around for xlib/xt
 -                                    buffering bug */
 -}
 -#endif
 +  int i;
  
 -void ReadBitmap(pm, name, bits, wreq, hreq)
 -     Pixmap *pm;
 -     String name;
 -     unsigned char bits[];
 -     u_int wreq, hreq;
 -{
 -    int x_hot, y_hot;
 -    u_int w, h;
 -    int errcode;
 -    char msg[MSG_SIZ], fullname[MSG_SIZ];
 -
 -    if (*appData.bitmapDirectory != NULLCHAR) {
 -        strcpy(fullname, appData.bitmapDirectory);
 -      strcat(fullname, "/");
 -      strcat(fullname, name);
 -      errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
 -                                &w, &h, pm, &x_hot, &y_hot);
 -    fprintf(stderr, "load %s\n", name);
 -      if (errcode != BitmapSuccess) {
 -          switch (errcode) {
 -            case BitmapOpenFailed:
 -              snprintf(msg, sizeof(msg), _("Can't open bitmap file %s"), fullname);
 -              break;
 -            case BitmapFileInvalid:
 -              snprintf(msg, sizeof(msg), _("Invalid bitmap in file %s"), fullname);
 -              break;
 -            case BitmapNoMemory:
 -              snprintf(msg, sizeof(msg), _("Ran out of memory reading bitmap file %s"),
 -                      fullname);
 -              break;
 -            default:
 -              snprintf(msg, sizeof(msg), _("Unknown XReadBitmapFile error %d on file %s"),
 -                      errcode, fullname);
 -              break;
 -          }
 -          fprintf(stderr, _("%s: %s...using built-in\n"),
 -                  programName, msg);
 -      } else if (w != wreq || h != hreq) {
 -          fprintf(stderr,
 -                  _("%s: Bitmap %s is %dx%d, not %dx%d...using built-in\n"),
 -                  programName, fullname, w, h, wreq, hreq);
 -      } else {
 -          return;
 +  /* free if used 
 +  for(i=0;i<MAXPIECES;i++)
 +    {
 +      if(SVGpieces[i])
 +      {       
 +        g_free(SVGpieces[i]);
 +        SVGpieces[i]=NULL;
        }
      }
 -    if (bits != NULL) {
 -      *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,
 -                                  wreq, hreq);
 -    }
 -}
 +  */
  
 -void CreateGrid()
 -{
 -    int i, j;
 +  /* reload these */
 +  SVGLightSquare   = load_pixbuf("svg/LightSquare.svg",squareSize);
 +  SVGDarkSquare    = load_pixbuf("svg/DarkSquare.svg",squareSize);
 +  SVGNeutralSquare = load_pixbuf("svg/NeutralSquare.svg",squareSize);
  
 -    if (lineGap == 0) return;
  
 -    /* [HR] Split this into 2 loops for non-square boards. */
 -
 -    for (i = 0; i < BOARD_HEIGHT + 1; i++) {
 -        gridSegments[i].x1 = 0;
 -        gridSegments[i].x2 =
 -          lineGap + BOARD_WIDTH * (squareSize + lineGap);
 -        gridSegments[i].y1 = gridSegments[i].y2
 -          = lineGap / 2 + (i * (squareSize + lineGap));
 -    }
 +  /* get some defaults going */
 +  for(i=WhitePawn; i<DemotePiece+1; i++)
 +    SVGpieces[i]   = load_pixbuf("svg/NeutralSquare.svg",squareSize);
 +    
 +  SVGpieces[WhitePawn]   = load_pixbuf("svg/WhitePawn.svg",squareSize);
 +  SVGpieces[WhiteKnight] = load_pixbuf("svg/WhiteKnight.svg",squareSize);
 +  SVGpieces[WhiteBishop] = load_pixbuf("svg/WhiteBishop.svg",squareSize);
 +  SVGpieces[WhiteRook]   = load_pixbuf("svg/WhiteRook.svg",squareSize);
 +  SVGpieces[WhiteQueen]  = load_pixbuf("svg/WhiteQueen.svg",squareSize);
 +  SVGpieces[WhiteKing]   = load_pixbuf("svg/WhiteKing.svg",squareSize);
 +
 +  SVGpieces[BlackPawn]   = load_pixbuf("svg/BlackPawn.svg",squareSize);
 +  SVGpieces[BlackKnight] = load_pixbuf("svg/BlackKnight.svg",squareSize);
 +  SVGpieces[BlackBishop] = load_pixbuf("svg/BlackBishop.svg",squareSize);
 +  SVGpieces[BlackRook]   = load_pixbuf("svg/BlackRook.svg",squareSize);
 +  SVGpieces[BlackQueen]  = load_pixbuf("svg/BlackQueen.svg",squareSize);
 +  SVGpieces[BlackKing]   = load_pixbuf("svg/BlackKing.svg",squareSize);
  
 -    for (j = 0; j < BOARD_WIDTH + 1; j++) {
 -        gridSegments[j + i].y1 = 0;
 -        gridSegments[j + i].y2 =
 -          lineGap + BOARD_HEIGHT * (squareSize + lineGap);
 -        gridSegments[j + i].x1 = gridSegments[j + i].x2
 -          = lineGap / 2 + (j * (squareSize + lineGap));
 -    }
 +  return;
  }
  
 +
  static void MenuBarSelect(w, addr, index)
       Widget w;
       caddr_t addr;
@@@ -2330,6 -3578,39 +2380,6 @@@ Widget CreateMenuBar(mb
      return menuBar;
  }
  
 -Widget CreateButtonBar(mi)
 -     MenuItem *mi;
 -{
 -    int j;
 -    Widget button, buttonBar;
 -    Arg args[16];
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
 -    if (tinyLayout) {
 -      XtSetArg(args[j], XtNhSpace, 0); j++;
 -    }
 -    XtSetArg(args[j], XtNborderWidth, 0); j++;
 -    XtSetArg(args[j], XtNvSpace, 0);                        j++;
 -    buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,
 -                             formWidget, args, j);
 -
 -    while (mi->string != NULL) {
 -      j = 0;
 -      if (tinyLayout) {
 -          XtSetArg(args[j], XtNinternalWidth, 2); j++;
 -          XtSetArg(args[j], XtNborderWidth, 0); j++;
 -      }
 -      XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); j++;
 -      button = XtCreateManagedWidget(mi->string, commandWidgetClass,
 -                                     buttonBar, args, j);
 -      XtAddCallback(button, XtNcallback,
 -                    (XtCallbackProc) MenuBarSelect,
 -                    (caddr_t) mi->proc);
 -      mi++;
 -    }
 -    return buttonBar;
 -}
  
  Widget
  CreatePieceMenu(name, color)
@@@ -2375,32 -3656,32 +2425,32 @@@ CreatePieceMenus(
      Arg args[16];
      ChessSquare selection;
  
 -    whitePieceMenu = CreatePieceMenu("menuW", 0);
 -    blackPieceMenu = CreatePieceMenu("menuB", 1);
 -
 -    XtRegisterGrabAction(PieceMenuPopup, True,
 -                       (unsigned)(ButtonPressMask|ButtonReleaseMask),
 -                       GrabModeAsync, GrabModeAsync);
 -
 -    XtSetArg(args[0], XtNlabel, _("Drop"));
 -    dropMenu = XtCreatePopupShell("menuD", simpleMenuWidgetClass,
 -                                boardWidget, args, 1);
 -    for (i = 0; i < DROP_MENU_SIZE; i++) {
 -      String item = dropMenuStrings[i];
 -
 -      if (strcmp(item, "----") == 0) {
 -          entry = XtCreateManagedWidget(item, smeLineObjectClass,
 -                                        dropMenu, NULL, 0);
 -      } else {
 -          XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
 -          entry = XtCreateManagedWidget(item, smeBSBObjectClass,
 -                                dropMenu, args, 1);
 -          selection = dropMenuTranslation[i];
 -          XtAddCallback(entry, XtNcallback,
 -                        (XtCallbackProc) DropMenuSelect,
 -                        (caddr_t) selection);
 -      }
 -    }
 +//    whitePieceMenu = CreatePieceMenu("menuW", 0);
 +//    blackPieceMenu = CreatePieceMenu("menuB", 1);
 +//
 +//    XtRegisterGrabAction(PieceMenuPopup, True,
 +//                     (unsigned)(ButtonPressMask|ButtonReleaseMask),
 +//                     GrabModeAsync, GrabModeAsync);
 +//
 +//    XtSetArg(args[0], XtNlabel, _("Drop"));
 +//    dropMenu = XtCreatePopupShell("menuD", simpleMenuWidgetClass,
 +//                              boardWidget, args, 1);
 +//    for (i = 0; i < DROP_MENU_SIZE; i++) {
 +//    String item = dropMenuStrings[i];
 +//
 +//    if (strcmp(item, "----") == 0) {
 +//        entry = XtCreateManagedWidget(item, smeLineObjectClass,
 +//                                      dropMenu, NULL, 0);
 +//    } else {
 +//          XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
 +//        entry = XtCreateManagedWidget(item, smeBSBObjectClass,
 +//                                dropMenu, args, 1);
 +//        selection = dropMenuTranslation[i];
 +//        XtAddCallback(entry, XtNcallback,
 +//                      (XtCallbackProc) DropMenuSelect,
 +//                      (caddr_t) selection);
 +//    }
 +//    }
  }
  
  void SetupDropMenu()
@@@ -2433,54 -3714,18 +2483,18 @@@ void PieceMenuPopup(w, event, params, n
       String *params;
       Cardinal *num_params;
  {
-     String whichMenu;
-     if (event->type != ButtonRelease) UnLoadPV(); // [HGM] pv
-     if (event->type != ButtonPress) return;
-     if (errorUp) ErrorPopDown();
-     switch (gameMode) {
-       case EditPosition:
-       case IcsExamining:
-       whichMenu = params[0];
-       break;
-       case IcsObserving:
-       if(!appData.icsEngineAnalyze) return;
-       case IcsPlayingWhite:
-       case IcsPlayingBlack:
-       if(!appData.zippyPlay) goto noZip;
-       case AnalyzeMode:
-       case AnalyzeFile:
-       case MachinePlaysWhite:
-       case MachinePlaysBlack:
-       case TwoMachinesPlay: // [HGM] pv: use for showing PV
-       if (!appData.dropMenu) {
-         LoadPV(event->xbutton.x, event->xbutton.y);
-         return;
-       }
-       if(gameMode == TwoMachinesPlay || gameMode == AnalyzeMode ||
-            gameMode == AnalyzeFile || gameMode == IcsObserving) return;
-       case EditGame:
-       noZip:
-       if (!appData.dropMenu || appData.testLegality &&
-           gameInfo.variant != VariantBughouse &&
-           gameInfo.variant != VariantCrazyhouse) return;
-       SetupDropMenu();
-       whichMenu = "menuD";
-       break;
-       default:
-       return;
-     }
-     if (((pmFromX = EventToSquare(event->xbutton.x, BOARD_WIDTH)) < 0) ||
-       ((pmFromY = EventToSquare(event->xbutton.y, BOARD_HEIGHT)) < 0)) {
-       pmFromX = pmFromY = -1;
-       return;
+     String whichMenu; int menuNr;
+     if (event->type == ButtonRelease)
+         menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY); 
+     else if (event->type == ButtonPress)
+         menuNr = RightClick(Press,   event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY);
+     switch(menuNr) {
+       case 0: whichMenu = params[0]; break;
+       case 1: SetupDropMenu(); whichMenu = "menuD"; break;
+       case 2:
+       case -1: if (errorUp) ErrorPopDown();
+       default: return;
      }
-     if (flipView)
-       pmFromX = BOARD_WIDTH - 1 - pmFromX;
-     else
-       pmFromY = BOARD_HEIGHT - 1 - pmFromY;
      XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu));
  }
  
@@@ -2502,6 -3747,33 +2516,6 @@@ static void DropMenuSelect(w, piece, ju
      DropMenuEvent(piece, pmFromX, pmFromY);
  }
  
 -void WhiteClock(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    if (gameMode == EditPosition || gameMode == IcsExamining) {
 -      SetWhiteToPlayEvent();
 -    } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
 -      CallFlagEvent();
 -    }
 -}
 -
 -void BlackClock(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    if (gameMode == EditPosition || gameMode == IcsExamining) {
 -      SetBlackToPlayEvent();
 -    } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
 -      CallFlagEvent();
 -    }
 -}
 -
 -
  /*
   * If the user selects on a border boundary, return -1; if off the board,
   *   return -2.  Otherwise map the event coordinate to the square.
@@@ -2528,58 -3800,26 +2542,58 @@@ static void do_flash_delay(msec
      TimeDelay(msec);
  }
  
 -static void drawHighlight(file, rank, gc)
 -     int file, rank;
 -     GC gc;
 +static void drawHighlight(file, rank, line_type)
 +     int file, rank, line_type;
  {
      int x, y;
 +    cairo_t *cr;
  
      if (lineGap == 0 || appData.blindfold) return;
  
 -    if (flipView) {
 +    if (flipView)
 +      {
        x = lineGap/2 + ((BOARD_WIDTH-1)-file) *
          (squareSize + lineGap);
        y = lineGap/2 + rank * (squareSize + lineGap);
 -    } else {
 +      }
 +    else
 +      {
        x = lineGap/2 + file * (squareSize + lineGap);
        y = lineGap/2 + ((BOARD_HEIGHT-1)-rank) *
          (squareSize + lineGap);
 -    }
 +      }
 +
 +    /* get a cairo_t */
 +    cr = gdk_cairo_create (GDK_WINDOW(GUI_Board->window));
 +
 +    /* draw the highlight */
 +    cairo_move_to (cr, x, y);
 +    cairo_rel_line_to (cr, 0,squareSize+lineGap);
 +    cairo_rel_line_to (cr, squareSize+lineGap,0);
 +    cairo_rel_line_to (cr, 0,-squareSize-lineGap);
 +    cairo_close_path (cr);
 +
 +    cairo_set_line_width (cr, lineGap);
 +    switch(line_type)
 +      {
 +      /* TODO: use appdata colors */
 +      case LINE_TYPE_HIGHLIGHT:
 +      cairo_set_source_rgba (cr, 1, 1, 0, 1.0);
 +      break;
 +      case LINE_TYPE_PRE:
 +      cairo_set_source_rgba (cr, 1, 0, 0, 1.0);
 +      break;
 +      case LINE_TYPE_NORMAL:
 +      default:
 +      cairo_set_source_rgba (cr, 0, 1, 0, 1.0);
 +      }
  
 -    XDrawRectangle(xDisplay, xBoardWindow, gc, x, y,
 -                 squareSize+lineGap, squareSize+lineGap);
 +    cairo_stroke (cr);
 +
 +    /* free memory */
 +    cairo_destroy (cr);
 +
 +    return;
  }
  
  int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1;
  SetHighlights(fromX, fromY, toX, toY)
       int fromX, fromY, toX, toY;
  {
 -    if (hi1X != fromX || hi1Y != fromY) {
 -      if (hi1X >= 0 && hi1Y >= 0) {
 -          drawHighlight(hi1X, hi1Y, lineGC);
 -      }
 -    } // [HGM] first erase both, then draw new!
 -    if (hi2X != toX || hi2Y != toY) {
 -      if (hi2X >= 0 && hi2Y >= 0) {
 -          drawHighlight(hi2X, hi2Y, lineGC);
 -      }
 -    }
 -    if (hi1X != fromX || hi1Y != fromY) {
 -      if (fromX >= 0 && fromY >= 0) {
 -          drawHighlight(fromX, fromY, highlineGC);
 -      }
 -    }
 -    if (hi2X != toX || hi2Y != toY) {
 -      if (toX >= 0 && toY >= 0) {
 -          drawHighlight(toX, toY, highlineGC);
 -      }
 -    }
 +    if (hi1X != fromX || hi1Y != fromY)
 +      {
 +      if (hi1X >= 0 && hi1Y >= 0)
 +        {
 +          drawHighlight(hi1X, hi1Y, LINE_TYPE_NORMAL);
 +        }
-       if (fromX >= 0 && fromY >= 0)
-         {
-           drawHighlight(fromX, fromY, LINE_TYPE_HIGHLIGHT);
-         }
 +      }
 +    if (hi2X != toX || hi2Y != toY)
 +      {
 +      if (hi2X >= 0 && hi2Y >= 0)
 +        {
 +          drawHighlight(hi2X, hi2Y, LINE_TYPE_NORMAL);
 +        }
++      }
++    if (hi1X != fromX || hi1Y != fromY)
++      {
++      if (fromX >= 0 && fromY >= 0)
++        {
++          drawHighlight(fromX, fromY, LINE_TYPE_HIGHLIGHT);
++        }
++    if (hi2X != toX || hi2Y != toY)
++      {    
 +      if (toX >= 0 && toY >= 0)
 +        {
 +          drawHighlight(toX, toY, LINE_TYPE_HIGHLIGHT);
 +        }
 +      }
      hi1X = fromX;
      hi1Y = fromY;
      hi2X = toX;
      hi2Y = toY;
 +
 +    return;
  }
  
  void
  SetPremoveHighlights(fromX, fromY, toX, toY)
       int fromX, fromY, toX, toY;
  {
 -    if (pm1X != fromX || pm1Y != fromY) {
 -      if (pm1X >= 0 && pm1Y >= 0) {
 -          drawHighlight(pm1X, pm1Y, lineGC);
 -      }
 -      if (fromX >= 0 && fromY >= 0) {
 -          drawHighlight(fromX, fromY, prelineGC);
 -      }
 -    }
 -    if (pm2X != toX || pm2Y != toY) {
 -      if (pm2X >= 0 && pm2Y >= 0) {
 -          drawHighlight(pm2X, pm2Y, lineGC);
 -      }
 -      if (toX >= 0 && toY >= 0) {
 -          drawHighlight(toX, toY, prelineGC);
 -      }
 -    }
 +    if (pm1X != fromX || pm1Y != fromY)
 +      {
 +      if (pm1X >= 0 && pm1Y >= 0)
 +        {
 +          drawHighlight(pm1X, pm1Y, LINE_TYPE_NORMAL);
 +        }
 +      if (fromX >= 0 && fromY >= 0)
 +        {
 +          drawHighlight(fromX, fromY, LINE_TYPE_PRE);
 +        }
 +      }
 +    if (pm2X != toX || pm2Y != toY)
 +      {
 +      if (pm2X >= 0 && pm2Y >= 0)
 +        {
 +          drawHighlight(pm2X, pm2Y, LINE_TYPE_NORMAL);
 +        }
 +      if (toX >= 0 && toY >= 0)
 +        {
 +          drawHighlight(toX, toY, LINE_TYPE_PRE);
 +        }
 +      }
 +
      pm1X = fromX;
      pm1Y = fromY;
      pm2X = toX;
      pm2Y = toY;
 +
 +    return;
  }
  
  void
@@@ -2672,38 -3899,172 +2691,38 @@@ static void BlankSquare(x, y, color, pi
       ChessSquare piece;
       Drawable dest;
  {
 -    if (useImages && useImageSqs) {
 -      Pixmap pm;
 -      switch (color) {
 -        case 1: /* light */
 -          pm = xpmLightSquare;
 -          break;
 -        case 0: /* dark */
 -          pm = xpmDarkSquare;
 -          break;
 -        case 2: /* neutral */
 -        default:
 -          pm = xpmJailSquare;
 -          break;
 -      }
 -      XCopyArea(xDisplay, pm, dest, wlPieceGC, 0, 0,
 -                squareSize, squareSize, x, y);
 -    } else {
 -      GC gc;
 -      switch (color) {
 -        case 1: /* light */
 -          gc = lightSquareGC;
 -          break;
 -        case 0: /* dark */
 -          gc = darkSquareGC;
 -          break;
 -        case 2: /* neutral */
 -        default:
 -          gc = jailSquareGC;
 -          break;
 -      }
 -      XFillRectangle(xDisplay, dest, gc, x, y, squareSize, squareSize);
 -    }
 -}
 +      GdkPixbuf *pb;
  
 -/*
 -   I split out the routines to draw a piece so that I could
 -   make a generic flash routine.
 -*/
 -static void monoDrawPiece_1bit(piece, square_color, x, y, dest)
 -     ChessSquare piece;
 -     int square_color, x, y;
 -     Drawable dest;
 -{
 -    /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
 -    switch (square_color) {
 -      case 1: /* light */
 -      case 2: /* neutral */
 -      default:
 -      XCopyArea(xDisplay, (int) piece < (int) BlackPawn
 -                ? *pieceToOutline(piece)
 -                : *pieceToSolid(piece),
 -                dest, bwPieceGC, 0, 0,
 -                squareSize, squareSize, x, y);
 -      break;
 -      case 0: /* dark */
 -      XCopyArea(xDisplay, (int) piece < (int) BlackPawn
 -                ? *pieceToSolid(piece)
 -                : *pieceToOutline(piece),
 -                dest, wbPieceGC, 0, 0,
 -                squareSize, squareSize, x, y);
 -      break;
 -    }
 +      switch (color) 
 +      {
 +      case 0: /* dark */
 +        pb = SVGDarkSquare;
 +        break;
 +      case 1: /* light */
 +        pb = SVGLightSquare;
 +        break;
 +      case 2: /* neutral */
 +      default:
 +        pb = SVGNeutralSquare;
 +        break;
 +      }
 +      gdk_draw_pixbuf(GDK_WINDOW(GUI_Board->window),NULL,pb,0,0,x,y,-1,-1, GDK_RGB_DITHER_NORMAL, 0, 0);
 +      return;
  }
  
 -static void monoDrawPiece(piece, square_color, x, y, dest)
 +static void DrawPiece(piece, square_color, x, y, dest)
       ChessSquare piece;
       int square_color, x, y;
       Drawable dest;
  {
 -    switch (square_color) {
 -      case 1: /* light */
 -      case 2: /* neutral */
 -      default:
 -      XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
 -                 ? *pieceToOutline(piece)
 -                 : *pieceToSolid(piece),
 -                 dest, bwPieceGC, 0, 0,
 -                 squareSize, squareSize, x, y, 1);
 -      break;
 -      case 0: /* dark */
 -      XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
 -                 ? *pieceToSolid(piece)
 -                 : *pieceToOutline(piece),
 -                 dest, wbPieceGC, 0, 0,
 -                 squareSize, squareSize, x, y, 1);
 -      break;
 -    }
 -}
 +  /* redraw background, since piece might be transparent in some areas */
 +  BlankSquare(x,y,square_color,piece,dest);
  
 -static void colorDrawPiece(piece, square_color, x, y, dest)
 -     ChessSquare piece;
 -     int square_color, x, y;
 -     Drawable dest;
 -{
 -    if(pieceToSolid(piece) == NULL) return; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
 -    switch (square_color) {
 -      case 1: /* light */
 -      XCopyPlane(xDisplay, *pieceToSolid(piece),
 -                 dest, (int) piece < (int) BlackPawn
 -                 ? wlPieceGC : blPieceGC, 0, 0,
 -                 squareSize, squareSize, x, y, 1);
 -      break;
 -      case 0: /* dark */
 -      XCopyPlane(xDisplay, *pieceToSolid(piece),
 -                 dest, (int) piece < (int) BlackPawn
 -                 ? wdPieceGC : bdPieceGC, 0, 0,
 -                 squareSize, squareSize, x, y, 1);
 -      break;
 -      case 2: /* neutral */
 -      default:
 -      XCopyPlane(xDisplay, *pieceToSolid(piece),
 -                 dest, (int) piece < (int) BlackPawn
 -                 ? wjPieceGC : bjPieceGC, 0, 0,
 -                 squareSize, squareSize, x, y, 1);
 -      break;
 -    }
 -}
 -
 -static void colorDrawPieceImage(piece, square_color, x, y, dest)
 -     ChessSquare piece;
 -     int square_color, x, y;
 -     Drawable dest;
 -{
 -    int kind;
 -
 -    switch (square_color) {
 -      case 1: /* light */
 -      case 2: /* neutral */
 -      default:
 -      if ((int)piece < (int) BlackPawn) {
 -          kind = 0;
 -      } else {
 -          kind = 2;
 -          piece -= BlackPawn;
 -      }
 -      break;
 -      case 0: /* dark */
 -      if ((int)piece < (int) BlackPawn) {
 -          kind = 1;
 -      } else {
 -          kind = 3;
 -          piece -= BlackPawn;
 -      }
 -      break;
 -    }
 -    XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
 -            dest, wlPieceGC, 0, 0,
 -            squareSize, squareSize, x, y);
 -}
 -
 -typedef void (*DrawFunc)();
 -
 -DrawFunc ChooseDrawFunc()
 -{
 -    if (appData.monoMode) {
 -      if (DefaultDepth(xDisplay, xScreen) == 1) {
 -          return monoDrawPiece_1bit;
 -      } else {
 -          return monoDrawPiece;
 -      }
 -    } else {
 -      if (useImages)
 -        return colorDrawPieceImage;
 -      else
 -        return colorDrawPiece;
 -    }
 +  /* draw piece */
 +  gdk_draw_pixbuf(GDK_WINDOW(GUI_Board->window),NULL,
 +                GDK_PIXBUF(SVGpieces[piece]),0,0,x,y,-1,-1,
 +                GDK_RGB_DITHER_NORMAL, 0, 0);
 +  return ;
  }
  
  /* [HR] determine square color depending on chess variant. */
@@@ -2736,182 -4097,147 +2755,195 @@@ void DrawSquare(row, column, piece, do_
       int row, column, do_flash;
       ChessSquare piece;
  {
 -    int square_color, x, y, direction, font_ascent, font_descent;
 +    int square_color, x, y;
      int i;
      char string[2];
 -    XCharStruct overall;
 -    DrawFunc drawfunc;
      int flash_delay;
  
      /* Calculate delay in milliseconds (2-delays per complete flash) */
      flash_delay = 500 / appData.flashRate;
  
 -    if (flipView) {
 +    /* calculate x and y coordinates from row and column */
 +    if (flipView)
 +      {
        x = lineGap + ((BOARD_WIDTH-1)-column) *
          (squareSize + lineGap);
        y = lineGap + row * (squareSize + lineGap);
 -    } else {
 +      }
 +    else
 +      {
        x = lineGap + column * (squareSize + lineGap);
        y = lineGap + ((BOARD_HEIGHT-1)-row) *
          (squareSize + lineGap);
 -    }
 +      }
  
      square_color = SquareColor(row, column);
  
 -    if ( // [HGM] holdings: blank out area between board and holdings
 -                 column == BOARD_LEFT-1 ||  column == BOARD_RGHT
 -              || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize)
 -                || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) ) {
 -                      BlankSquare(x, y, 2, EmptySquare, xBoardWindow);
 -
 -                      // [HGM] print piece counts next to holdings
 -                      string[1] = NULLCHAR;
 -                      if (column == (flipView ? BOARD_LEFT-1 : BOARD_RGHT) && piece > 1 ) {
 -                          string[0] = '0' + piece;
 -                          XTextExtents(countFontStruct, string, 1, &direction,
 -                               &font_ascent, &font_descent, &overall);
 -                          if (appData.monoMode) {
 -                              XDrawImageString(xDisplay, xBoardWindow, countGC,
 -                                               x + squareSize - overall.width - 2,
 -                                               y + font_ascent + 1, string, 1);
 -                          } else {
 -                              XDrawString(xDisplay, xBoardWindow, countGC,
 -                                          x + squareSize - overall.width - 2,
 -                                          y + font_ascent + 1, string, 1);
 -                          }
 -                      }
 -                      if (column == (flipView ? BOARD_RGHT : BOARD_LEFT-1) && piece > 1) {
 -                          string[0] = '0' + piece;
 -                          XTextExtents(countFontStruct, string, 1, &direction,
 -                                       &font_ascent, &font_descent, &overall);
 -                          if (appData.monoMode) {
 -                              XDrawImageString(xDisplay, xBoardWindow, countGC,
 -                                               x + 2, y + font_ascent + 1, string, 1);
 -                          } else {
 -                              XDrawString(xDisplay, xBoardWindow, countGC,
 -                                          x + 2, y + font_ascent + 1, string, 1);
 -                          }
 -                      }
 -    } else {
 -          if (piece == EmptySquare || appData.blindfold) {
 -                      BlankSquare(x, y, square_color, piece, xBoardWindow);
 -          } 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);
 -
 -                                      BlankSquare(x, y, square_color, piece, xBoardWindow);
 -                                      XSync(xDisplay, False);
 -                                      do_flash_delay(flash_delay);
 -                          }
 -                      }
 -                      drawfunc(piece, square_color, x, y, xBoardWindow);
 -      }
 -      }
 +    // [HGM] holdings: blank out area between board and holdings
 +    if ( column == BOARD_LEFT-1 ||  column == BOARD_RGHT
 +       || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize)
 +       || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) )
 +      {
 +      BlankSquare(x, y, 2, EmptySquare, xBoardWindow);
  
 -    string[1] = NULLCHAR;
 -    if (appData.showCoords && row == (flipView ? BOARD_HEIGHT-1 : 0)
 -              && column >= BOARD_LEFT && column < BOARD_RGHT) {
 -      string[0] = 'a' + column - BOARD_LEFT;
 -      XTextExtents(coordFontStruct, string, 1, &direction,
 -                   &font_ascent, &font_descent, &overall);
 -      if (appData.monoMode) {
 -          XDrawImageString(xDisplay, xBoardWindow, coordGC,
 -                           x + squareSize - overall.width - 2,
 -                           y + squareSize - font_descent - 1, string, 1);
 -      } else {
 -          XDrawString(xDisplay, xBoardWindow, coordGC,
 -                      x + squareSize - overall.width - 2,
 -                      y + squareSize - font_descent - 1, string, 1);
 -      }
 -    }
 -    if (appData.showCoords && column == (flipView ? BOARD_RGHT-1 : BOARD_LEFT)) {
 -      string[0] = ONE + row;
 -      XTextExtents(coordFontStruct, string, 1, &direction,
 -                   &font_ascent, &font_descent, &overall);
 -      if (appData.monoMode) {
 -          XDrawImageString(xDisplay, xBoardWindow, coordGC,
 -                           x + 2, y + font_ascent + 1, string, 1);
 -      } else {
 -          XDrawString(xDisplay, xBoardWindow, coordGC,
 -                      x + 2, y + font_ascent + 1, string, 1);
 -      }
 -    }
 -    if(marker[row][column]) {
 -      XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? prelineGC : highlineGC, 
 -              x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360);
 -    }
 -}
 +      // [HGM] print piece counts next to holdings
 +      string[1] = NULLCHAR;
 +      if(piece > 1)
 +        {
 +          cairo_text_extents_t extents;
 +          cairo_t *cr;
 +          int  xpos, ypos;
 +
 +          /* get a cairo_t */
 +          cr = gdk_cairo_create (GDK_WINDOW(GUI_Board->window));
 +
 +          string[0] = '0' + piece;
 +
 +          /* TODO this has to go into the font-selection */
 +          cairo_select_font_face (cr, "Sans",
 +                                  CAIRO_FONT_SLANT_NORMAL,
 +                                  CAIRO_FONT_WEIGHT_NORMAL);
++          //TODO
++//    switch (event->type) {
++//      case Expose:
++//    if (event->xexpose.count > 0) return;  /* no clipping is done */
++//    XDrawPosition(widget, True, NULL);
++//    break;
++//      case MotionNotify:
++//        if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break;
++//      default:
++//    return;
++//    }
++//}
++/* end why */
  
 +          cairo_set_font_size (cr, 12.0);
 +          cairo_text_extents (cr, string, &extents);
  
 -/* Why is this needed on some versions of X? */
 -void EventProc(widget, unused, event)
 -     Widget widget;
 -     caddr_t unused;
 -     XEvent *event;
 -{
 -    if (!XtIsRealized(widget))
 -      return;
 +          if (column == (flipView ? BOARD_LEFT-1 : BOARD_RGHT) )
 +            {
 +              xpos= x + squareSize - extents.width - 2;
 +              ypos= y + extents.y_bearing + 1;
 +            }
 +          if (column == (flipView ? BOARD_RGHT : BOARD_LEFT-1) && piece > 1)
 +            {
 +              xpos= x + 2;
 +              ypos = y + extents.y_bearing + 1;
 +            }
  
 -    switch (event->type) {
 -      case Expose:
 -      if (event->xexpose.count > 0) return;  /* no clipping is done */
 -      XDrawPosition(widget, True, NULL);
 -      break;
 -      case MotionNotify:
 -        if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break;\r
 -      default:
 -      return;
 -    }
 -}
 -/* end why */
 +          /* TODO mono mode? */
 +          cairo_move_to (cr, xpos, ypos);
 +          cairo_text_path (cr, string);
 +          cairo_set_source_rgb (cr, 1.0, 1.0, 1);
 +          cairo_fill_preserve (cr);
 +          cairo_set_source_rgb (cr, 0, 0, 0);
 +          cairo_set_line_width (cr, 0.1);
 +          cairo_stroke (cr);
 +
 +          /* free memory */
 +          cairo_destroy (cr);
 +        }
 +      }
 +    else
 +      {
 +      /* square on the board */
 +      if (piece == EmptySquare || appData.blindfold)
 +        {
 +          BlankSquare(x, y, square_color, piece, xBoardWindow);
 +        }
 +      else
 +        {
 +          if (do_flash && appData.flashCount > 0)
 +            {
 +              for (i=0; i<appData.flashCount; ++i)
 +                {
  
 -void DrawPosition(fullRedraw, board)
 -     /*Boolean*/int fullRedraw;
 -     Board board;
 -{
 -    XDrawPosition(boardWidget, fullRedraw, board);
 +                  DrawPiece(piece, square_color, x, y, xBoardWindow);
 +                  do_flash_delay(flash_delay);
 +
 +                  BlankSquare(x, y, square_color, piece, xBoardWindow);
 +                  do_flash_delay(flash_delay);
 +                }
 +            }
 +          DrawPiece(piece, square_color, x, y, xBoardWindow);
 +        }
 +      }
 +
 +    /* show coordinates if necessary */
 +    if(appData.showCoords)
 +      {
 +      cairo_text_extents_t extents;
 +      cairo_t *cr;
 +      int  xpos, ypos;
 +
 +      /* TODO this has to go into the font-selection */
 +      cairo_select_font_face (cr, "Sans",
 +                              CAIRO_FONT_SLANT_NORMAL,
 +                              CAIRO_FONT_WEIGHT_NORMAL);
 +      cairo_set_font_size (cr, 12.0);
 +
 +      string[1] = NULLCHAR;
 +
 +      /* get a cairo_t */
 +      cr = gdk_cairo_create (GDK_WINDOW(GUI_Board->window));
 +
 +      if (row == (flipView ? BOARD_HEIGHT-1 : 0) &&
 +          column >= BOARD_LEFT && column < BOARD_RGHT)
 +        {
 +          string[0] = 'a' + column - BOARD_LEFT;
 +          cairo_text_extents (cr, string, &extents);
 +
 +          xpos = x + squareSize - extents.width - 2;
 +          ypos = y + squareSize - extents.height - extents.y_bearing - 1;
 +
 +          if (appData.monoMode)
 +            { /*TODO*/
 +            }
 +          else
 +            {
 +            }
 +
 +          cairo_move_to (cr, xpos, ypos);
 +          cairo_text_path (cr, string);
 +          cairo_set_source_rgb (cr, 0.0, 0.0, 0);
 +          cairo_fill_preserve (cr);
 +          cairo_set_source_rgb (cr, 0, 1.0, 0);
 +          cairo_set_line_width (cr, 0.1);
 +          cairo_stroke (cr);
 +        }
 +      if ( column == (flipView ? BOARD_RGHT-1 : BOARD_LEFT))
 +        {
 +
 +          string[0] = ONE + row;
 +          cairo_text_extents (cr, string, &extents);
 +
 +          xpos = x + 2;
 +          ypos = y + extents.height + 1;
 +
 +          if (appData.monoMode)
 +            { /*TODO*/
 +            }
 +          else
 +            {
 +            }
 +
 +          cairo_move_to (cr, xpos, ypos);
 +          cairo_text_path (cr, string);
 +          cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
 +          cairo_fill_preserve (cr);
 +          cairo_set_source_rgb (cr, 0, 0, 1.0);
 +          cairo_set_line_width (cr, 0.1);
 +          cairo_stroke (cr);
 +
 +        }
 +      /* free memory */
 +      cairo_destroy (cr);
 +      }
 +
 +    return;
  }
  
 +
  /* Returns 1 if there are "too many" differences between b1 and b2
     (i.e. more than 1 move was made) */
  static int too_many_diffs(b1, b2)
@@@ -2979,153 -4305,186 +3011,185 @@@ static int check_castle_draw(newb, oldb
      return 0;
  }
  
+ // [HGM] seekgraph: some low-level drawing routines cloned from xevalgraph 
+ void DrawSeekAxis( int x, int y, int xTo, int yTo )
+ {
+       XDrawLine(xDisplay, xBoardWindow, lineGC, x, y, xTo, yTo);
+ }
+ void DrawSeekBackground( int left, int top, int right, int bottom )
+ {
+     XFillRectangle(xDisplay, xBoardWindow, lightSquareGC, left, top, right-left, bottom-top);
+ }
+ void DrawSeekText(char *buf, int x, int y)
+ {
+     XDrawString(xDisplay, xBoardWindow, coordGC, x, y+4, buf, strlen(buf));
+ }
+ void DrawSeekDot(int x, int y, int colorNr)
+ {
+     int square = colorNr & 0x80;
+     GC color;
+     colorNr &= 0x7F;
+     color = colorNr == 0 ? prelineGC : colorNr == 1 ? darkSquareGC : highlineGC;
+     if(square)
+       XFillRectangle(xDisplay, xBoardWindow, color,
+               x-squareSize/9, y-squareSize/9, 2*squareSize/9, 2*squareSize/9);
+     else
+       XFillArc(xDisplay, xBoardWindow, color, 
+               x-squareSize/8, y-squareSize/8, squareSize/4, squareSize/4, 0, 64*360);
+ }
  static int damage[BOARD_RANKS][BOARD_FILES];
  
  /*
   * event handler for redrawing the board
   */
 -void XDrawPosition(w, repaint, board)
 -     Widget w;
 +void DrawPosition( repaint, board)
       /*Boolean*/int repaint;
 -     Board board;
 +              Board board;
  {
 -    int i, j, do_flash;
 -    static int lastFlipView = 0;
 -    static int lastBoardValid = 0;
 -    static Board lastBoard;
 -    Arg args[16];
 -    int rrow, rcol;
 +  int i, j, do_flash;
 +  static int lastFlipView = 0;
 +  static int lastBoardValid = 0;
 +  static Board lastBoard;
 +  int rrow, rcol;
  
+     if(DrawSeekGraph()) return; // [HGM] seekgraph: suppress any drawing if seek graph up
 -    if (board == NULL) {
 -      if (!lastBoardValid) return;
 -      board = lastBoard;
 -    }
 -    if (!lastBoardValid || lastFlipView != flipView) {
 -      XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
 -      XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
 -                  args, 1);
 -    }
 -
 -    /*
 -     * It would be simpler to clear the window with XClearWindow()
 -     * but this causes a very distracting flicker.
 -     */
 +  if (board == NULL) {
 +    if (!lastBoardValid) return;
 +    board = lastBoard;
 +  }
 +  if (!lastBoardValid || lastFlipView != flipView) {
 +    //    XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
 +    // XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
 +    //        args, 1);
 +  }
  
 -    if (!repaint && lastBoardValid && lastFlipView == flipView) {
 +  /*
 +   * It would be simpler to clear the window with XClearWindow()
 +   * but this causes a very distracting flicker.
 +   */
  
 -      /* If too much changes (begin observing new game, etc.), don't
 -         do flashing */
 -      do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;
 +  if (!repaint && lastBoardValid && lastFlipView == flipView)
 +    {
 +      /* If too much changes (begin observing new game, etc.), don't
 +       do flashing */
 +      do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;
  
 -      /* Special check for castling so we don't flash both the king
 -         and the rook (just flash the king). */
 -      if (do_flash) {
 -          if (check_castle_draw(board, lastBoard, &rrow, &rcol)) {
 -              /* Draw rook with NO flashing. King will be drawn flashing later */
 -              DrawSquare(rrow, rcol, board[rrow][rcol], 0);
 -              lastBoard[rrow][rcol] = board[rrow][rcol];
 +      /* Special check for castling so we don't flash both the king
 +       and the rook (just flash the king). */
 +      if (do_flash)
 +      {
 +        if (check_castle_draw(board, lastBoard, &rrow, &rcol))
 +          {
 +            /* Draw rook with NO flashing. King will be drawn flashing later */
 +            DrawSquare(rrow, rcol, board[rrow][rcol], 0);
 +            lastBoard[rrow][rcol] = board[rrow][rcol];
            }
        }
  
 -      /* First pass -- Draw (newly) empty squares and repair damage.
 -         This prevents you from having a piece show up twice while it
 -         is flashing on its new square */
 -      for (i = 0; i < BOARD_HEIGHT; i++)
 -        for (j = 0; j < BOARD_WIDTH; j++)
 -          if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)
 -              || damage[i][j]) {
 -              DrawSquare(i, j, board[i][j], 0);
 -              damage[i][j] = False;
 +      /* First pass -- Draw (newly) empty squares and repair damage.
 +       This prevents you from having a piece show up twice while it
 +       is flashing on its new square */
 +      for (i = 0; i < BOARD_HEIGHT; i++)
 +      for (j = 0; j < BOARD_WIDTH; j++)
 +        if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)
 +            || damage[i][j])
 +          {
 +            DrawSquare(i, j, board[i][j], 0);
 +            damage[i][j] = False;
            }
  
 -      /* Second pass -- Draw piece(s) in new position and flash them */
 -      for (i = 0; i < BOARD_HEIGHT; i++)
 -        for (j = 0; j < BOARD_WIDTH; j++)
 -          if (board[i][j] != lastBoard[i][j]) {
 -              DrawSquare(i, j, board[i][j], do_flash);
 +      /* Second pass -- Draw piece(s) in new position and flash them */
 +      for (i = 0; i < BOARD_HEIGHT; i++)
 +      for (j = 0; j < BOARD_WIDTH; j++)
 +        if (board[i][j] != lastBoard[i][j])
 +          {
 +            DrawSquare(i, j, board[i][j], do_flash);
            }
 -    } else {
 -      if (lineGap > 0)
 -        XDrawSegments(xDisplay, xBoardWindow, lineGC,
 -                      gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);
 -
 -      for (i = 0; i < BOARD_HEIGHT; i++)
 -        for (j = 0; j < BOARD_WIDTH; j++) {
 -            DrawSquare(i, j, board[i][j], 0);
 -            damage[i][j] = False;
 -        }
      }
 +  else
 +    {
 +      /* redraw Grid */
 +      if (lineGap > 0)
 +      {
 +        int x1,x2,y1,y2;
 +        cairo_t *cr;
  
 -    CopyBoard(lastBoard, board);
 -    lastBoardValid = 1;
 -    lastFlipView = flipView;
 +        /* get a cairo_t */
 +        cr = gdk_cairo_create (GDK_WINDOW(GUI_Board->window));
  
 -    /* Draw highlights */
 -    if (pm1X >= 0 && pm1Y >= 0) {
 -      drawHighlight(pm1X, pm1Y, prelineGC);
 -    }
 -    if (pm2X >= 0 && pm2Y >= 0) {
 -      drawHighlight(pm2X, pm2Y, prelineGC);
 -    }
 -    if (hi1X >= 0 && hi1Y >= 0) {
 -      drawHighlight(hi1X, hi1Y, highlineGC);
 -    }
 -    if (hi2X >= 0 && hi2Y >= 0) {
 -      drawHighlight(hi2X, hi2Y, highlineGC);
 -    }
 +        cairo_set_line_width (cr, lineGap);
  
 -    /* If piece being dragged around board, must redraw that too */
 -    DrawDragPiece();
 +        /* TODO: use appdata colors */
 +        cairo_set_source_rgba (cr, 0, 1, 0, 1.0);
  
 -    XSync(xDisplay, False);
 -}
 +        cairo_stroke (cr);
  
 +        for (i = 0; i < BOARD_HEIGHT + 1; i++)
 +          {
 +            x1 = 0;
 +            x2 = lineGap + BOARD_WIDTH * (squareSize + lineGap);
 +            y1 = y2 = lineGap / 2 + (i * (squareSize + lineGap));
  
 -/*
 - * event handler for redrawing the board
 - */
 -void DrawPositionProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    XDrawPosition(w, True, NULL);
 -}
 +            cairo_move_to (cr, x1, y1);
 +            cairo_rel_line_to (cr, x2,0);
 +            cairo_stroke (cr);
 +          }
  
 +        for (j = 0; j < BOARD_WIDTH + 1; j++)
 +          {
 +            y1 = 0;
 +            y2 = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
 +            x1 = x2  = lineGap / 2 + (j * (squareSize + lineGap));
  
 -/*
 - * event handler for parsing user moves
 - */
 -// [HGM] This routine will need quite some reworking. Although the backend still supports the old
 -//       way of doing things, by calling UserMoveEvent() to test the legality of the move and then perform
 -//       it at the end, and doing all kind of preliminary tests here (e.g. to weed out self-captures), it
 -//       should be made to use the new way, of calling UserMoveTest early  to determine the legality of the
 -//       move, (which will weed out the illegal selfcaptures and moves into the holdings, and flag promotions),
 -//       and at the end FinishMove() to perform the move after optional promotion popups.
 -//       For now I patched it to allow self-capture with King, and suppress clicks between board and holdings.
 -void HandleUserMove(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    if (w != boardWidget || errorExitStatus != -1) return;
 +            cairo_move_to (cr, x1, y1);
 +            cairo_rel_line_to (cr, 0, y2);
 +            cairo_stroke (cr);
 +          }
  
 -    if (promotionUp) {
 -      if (event->type == ButtonPress) {
 -          XtPopdown(promotionShell);
 -          XtDestroyWidget(promotionShell);
 -          promotionUp = False;
 -          ClearHighlights();
 -          fromX = fromY = -1;
 -      } else {
 -          return;
 +        /* free memory */
 +        cairo_destroy (cr);
        }
 +
 +      /* draw pieces */
 +      for (i = 0; i < BOARD_HEIGHT; i++)
 +      for (j = 0; j < BOARD_WIDTH; j++)
 +        {
 +          DrawSquare(i, j, board[i][j], 0);
 +          damage[i][j] = False;
 +        }
      }
  
 -    // [HGM] mouse: the rest of the mouse handler is moved to the backend, and called here
 -    if(event->type == ButtonPress)   LeftClick(Press,   event->xbutton.x, event->xbutton.y);
 -    if(event->type == ButtonRelease) LeftClick(Release, event->xbutton.x, event->xbutton.y);
 +  CopyBoard(lastBoard, board);
 +  lastBoardValid = 1;
 +  lastFlipView = flipView;
 +
 +  /* Draw highlights */
 +  if (pm1X >= 0 && pm1Y >= 0)
 +    {
 +      drawHighlight(pm1X, pm1Y, LINE_TYPE_PRE);
 +    }
 +  if (pm2X >= 0 && pm2Y >= 0)
 +    {
 +      drawHighlight(pm2X, pm2Y, LINE_TYPE_PRE);
 +    }
 +  if (hi1X >= 0 && hi1Y >= 0)
 +    {
 +      drawHighlight(hi1X, hi1Y, LINE_TYPE_HIGHLIGHT);
 +    }
 +  if (hi2X >= 0 && hi2Y >= 0)
 +    {
 +      drawHighlight(hi2X, hi2Y, LINE_TYPE_HIGHLIGHT);
 +    }
 +
 +  /* If piece being dragged around board, must redraw that too */
 +  DrawDragPiece();
 +
 +  return;
  }
  
  void AnimateUserMove (Widget w, XEvent * event,
@@@ -3158,13 -4517,13 +3222,13 @@@ Widget CommentCreate(name, text, mutabl
      j = 0;
      XtSetArg(args[j], XtNresizable, True);  j++;
  #if TOPLEVEL
 -    shell =
 -      XtCreatePopupShell(name, topLevelShellWidgetClass,
 -                       shellWidget, args, j);
 +//    shell =
 +//      XtCreatePopupShell(name, topLevelShellWidgetClass,
 +//                     shellWidget, args, j);
  #else
 -    shell =
 -      XtCreatePopupShell(name, transientShellWidgetClass,
 -                       shellWidget, args, j);
 +//    shell =
 +//      XtCreatePopupShell(name, transientShellWidgetClass,
 +//                     shellWidget, args, j);
  #endif
      layout =
        XtCreateManagedWidget(layoutName, formWidgetClass, shell,
        commentH = pw_height + (lines - 1) * ew_height;
        commentW = bw_width - 16;
  
 -      XSync(xDisplay, False);
 +      //      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);
 +//    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);
 +//        XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
 +//                          RootWindowOfScreen(XtScreen(shellWidget)),
 +//                          (bw_width - commentW) / 2, 0 - commentH / 2,
 +//                          &xx, &yy, &junk);
        commentX = xx;
        commentY = yy;
  #endif /*!NOTDEF*/
@@@ -3321,13 -4680,13 +3385,13 @@@ Widget MiscCreate(name, text, mutable, 
      j = 0;
      XtSetArg(args[j], XtNresizable, True);  j++;
  #if TOPLEVEL
 -    shell =
 -      XtCreatePopupShell(name, topLevelShellWidgetClass,
 -                       shellWidget, args, j);
 +//    shell =
 +//      XtCreatePopupShell(name, topLevelShellWidgetClass,
 +//                     shellWidget, args, j);
  #else
 -    shell =
 -      XtCreatePopupShell(name, transientShellWidgetClass,
 -                       shellWidget, args, j);
 +//    shell =
 +//      XtCreatePopupShell(name, transientShellWidgetClass,
 +//                     shellWidget, args, j);
  #endif
      layout =
        XtCreateManagedWidget(layoutName, formWidgetClass, shell,
      h = pw_height + (lines - 1) * ew_height;
      w = bw_width - 16;
  
 -    XSync(xDisplay, False);
 +    //    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);
 +//    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);
 +//    XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
 +//                      RootWindowOfScreen(XtScreen(shellWidget)),
 +//                      (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk);
  #endif /*!NOTDEF*/
      x = xx;
      y = yy;
@@@ -3414,7 -4773,7 +3478,7 @@@ void EditCommentPopUp(index, title, tex
        editShell =
          CommentCreate(title, text, True, EditCommentCallback, 4);
        XtRealizeWidget(editShell);
 -      CatchDeleteWindow(editShell, "EditCommentPopDown");
 +      //      CatchDeleteWindow(editShell, "EditCommentPopDown");
      } else {
        edit = XtNameToWidget(editShell, "*form.text");
        j = 0;
@@@ -3498,7 -4857,7 +3562,7 @@@ void ICSInputBoxPopUp(
        edit = XtNameToWidget(ICSInputShell, "*form.text");
        XtOverrideTranslations(edit, tr);
        XtRealizeWidget(ICSInputShell);
 -      CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");
 +      //      CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");
  
      } else {
        edit = XtNameToWidget(ICSInputShell, "*form.text");
@@@ -3563,7 -4922,7 +3627,7 @@@ void CommentPopUp(title, text
        commentShell =
          CommentCreate(title, text, False, CommentCallback, 4);
        XtRealizeWidget(commentShell);
 -      CatchDeleteWindow(commentShell, "CommentPopDown");
 +      //      CatchDeleteWindow(commentShell, "CommentPopDown");
      } else {
        edit = XtNameToWidget(commentShell, "*form.text");
        j = 0;
      }
  
      XtPopup(commentShell, XtGrabNone);
 -    XSync(xDisplay, False);
 +    //    XSync(xDisplay, False);
  
      commentUp = True;
  }
@@@ -3615,10 -4974,142 +3679,10 @@@ void CommentPopDown(
      XtSetArg(args[j], XtNheight, &commentH); j++;
      XtGetValues(commentShell, args, j);
      XtPopdown(commentShell);
 -    XSync(xDisplay, False);
 +    //    XSync(xDisplay, False);
      commentUp = False;
  }
  
 -void FileNamePopUp(label, def, proc, openMode)
 -     char *label;
 -     char *def;
 -     FileProc proc;
 -     char *openMode;
 -{
 -    Arg args[16];
 -    Widget popup, layout, dialog, edit;
 -    Window root, child;
 -    int x, y, i;
 -    int win_x, win_y;
 -    unsigned int mask;
 -
 -    fileProc = proc;          /* I can't see a way not */
 -    fileOpenMode = openMode;  /*   to use globals here */
 -
 -    i = 0;
 -    XtSetArg(args[i], XtNresizable, True); i++;
 -    XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
 -    XtSetArg(args[i], XtNtitle, XtNewString(_("File name prompt"))); i++;
 -    fileNameShell = popup =
 -      XtCreatePopupShell("File name prompt", transientShellWidgetClass,
 -                       shellWidget, args, i);
 -
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 -                          layoutArgs, XtNumber(layoutArgs));
 -
 -    i = 0;
 -    XtSetArg(args[i], XtNlabel, label); i++;
 -    XtSetArg(args[i], XtNvalue, def); i++;
 -    XtSetArg(args[i], XtNborderWidth, 0); i++;
 -    dialog = XtCreateManagedWidget("fileName", dialogWidgetClass,
 -                                 layout, args, i);
 -
 -    XawDialogAddButton(dialog, _("ok"), FileNameCallback, (XtPointer) dialog);
 -    XawDialogAddButton(dialog, _("cancel"), FileNameCallback,
 -                     (XtPointer) dialog);
 -
 -    XtRealizeWidget(popup);
 -    CatchDeleteWindow(popup, "FileNamePopDown");
 -
 -    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 -                &x, &y, &win_x, &win_y, &mask);
 -
 -    XtSetArg(args[0], XtNx, x - 10);
 -    XtSetArg(args[1], XtNy, y - 30);
 -    XtSetValues(popup, args, 2);
 -
 -    XtPopup(popup, XtGrabExclusive);
 -    filenameUp = True;
 -
 -    edit = XtNameToWidget(dialog, "*value");
 -    XtSetKeyboardFocus(popup, edit);
 -}
 -
 -void FileNamePopDown()
 -{
 -    if (!filenameUp) return;
 -    XtPopdown(fileNameShell);
 -    XtDestroyWidget(fileNameShell);
 -    filenameUp = False;
 -    ModeHighlight();
 -}
 -
 -void FileNameCallback(w, client_data, call_data)
 -     Widget w;
 -     XtPointer client_data, call_data;
 -{
 -    String name;
 -    Arg args[16];
 -
 -    XtSetArg(args[0], XtNlabel, &name);
 -    XtGetValues(w, args, 1);
 -
 -    if (strcmp(name, _("cancel")) == 0) {
 -        FileNamePopDown();
 -        return;
 -    }
 -
 -    FileNameAction(w, NULL, NULL, NULL);
 -}
 -
 -void FileNameAction(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    char buf[MSG_SIZ];
 -    String name;
 -    FILE *f;
 -    char *p, *fullname;
 -    int index;
 -
 -    name = XawDialogGetValueString(w = XtParent(w));
 -
 -    if ((name != NULL) && (*name != NULLCHAR)) {
 -      strcpy(buf, name);
 -      XtPopdown(w = XtParent(XtParent(w)));
 -      XtDestroyWidget(w);
 -      filenameUp = False;
 -
 -      p = strrchr(buf, ' ');
 -      if (p == NULL) {
 -          index = 0;
 -      } else {
 -          *p++ = NULLCHAR;
 -          index = atoi(p);
 -      }
 -      fullname = ExpandPathName(buf);
 -      if (!fullname) {
 -          ErrorPopUp(_("Error"), _("Can't open file"), FALSE);
 -      }
 -      else {
 -          f = fopen(fullname, fileOpenMode);
 -          if (f == NULL) {
 -              DisplayError(_("Failed to open file"), errno);
 -          } else {
 -              (void) (*fileProc)(f, index, buf);
 -          }
 -      }
 -      ModeHighlight();
 -      return;
 -    }
 -
 -    XtPopdown(w = XtParent(XtParent(w)));
 -    XtDestroyWidget(w);
 -    filenameUp = False;
 -    ModeHighlight();
 -}
 -
  void PromotionPopUp()
  {
      Arg args[16];
      j = 0;
      XtSetArg(args[j], XtNresizable, True); j++;
      XtSetArg(args[j], XtNtitle, XtNewString(_("Promotion"))); j++;
 -    promotionShell =
 -      XtCreatePopupShell("Promotion", transientShellWidgetClass,
 -                       shellWidget, args, j);
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, promotionShell,
 -                          layoutArgs, XtNumber(layoutArgs));
 -
 +//    promotionShell =
 +//      XtCreatePopupShell("Promotion", transientShellWidgetClass,
 +//                     shellWidget, args, j);
 +//    layout =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, promotionShell,
 +//                        layoutArgs, XtNumber(layoutArgs));
 +//
      j = 0;
      XtSetArg(args[j], XtNlabel, _("Promote to what?")); j++;
      XtSetArg(args[j], XtNborderWidth, 0); j++;
        XawDialogAddButton(dialog, _("King"), PromotionCallback,
                         (XtPointer) dialog);
      }
 -    if(gameInfo.variant == VariantCapablanca || 
 -       gameInfo.variant == VariantGothic || 
 +    if(gameInfo.variant == VariantCapablanca ||
 +       gameInfo.variant == VariantGothic ||
         gameInfo.variant == VariantCapaRandom) {
        XawDialogAddButton(dialog, _("Archbishop"), PromotionCallback,
                         (XtPointer) dialog);
                       (XtPointer) dialog);
  
      XtRealizeWidget(promotionShell);
 -    CatchDeleteWindow(promotionShell, "PromotionPopDown");
 +    //    CatchDeleteWindow(promotionShell, "PromotionPopDown");
  
      j = 0;
      XtSetArg(args[j], XtNwidth, &pw_width); j++;
@@@ -3761,41 -5252,77 +3825,41 @@@ void ErrorPopDown(
  {
      if (!errorUp) return;
      errorUp = False;
 -    XtPopdown(errorShell);
 -    XtDestroyWidget(errorShell);
 +
 +    if(GUI_Error)
 +      gtk_widget_destroy(GTK_WIDGET(GUI_Error));
 +
      if (errorExitStatus != -1) ExitEvent(errorExitStatus);
 +
 +    return;
  }
  
  void ErrorPopUp(title, label, modal)
       char *title, *label;
       int modal;
  {
 -    Arg args[16];
 -    Widget dialog, layout;
 -    Position x, y;
 -    int xx, yy;
 -    Window junk;
 -    Dimension bw_width, pw_width;
 -    Dimension pw_height;
 -    int i;
 +  GUI_Error = gtk_message_dialog_new(GTK_WINDOW(GUI_Window),
 +                                  GTK_DIALOG_DESTROY_WITH_PARENT,
 +                                  GTK_MESSAGE_ERROR,
 +                                  GTK_BUTTONS_CLOSE,
 +                                  (gchar *)label);
  
 -    i = 0;
 -    XtSetArg(args[i], XtNresizable, True);  i++;
 -    XtSetArg(args[i], XtNtitle, title); i++;
 -    errorShell =
 -      XtCreatePopupShell("errorpopup", transientShellWidgetClass,
 -                       shellWidget, args, i);
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, errorShell,
 -                          layoutArgs, XtNumber(layoutArgs));
 -
 -    i = 0;
 -    XtSetArg(args[i], XtNlabel, label); i++;
 -    XtSetArg(args[i], XtNborderWidth, 0); i++;
 -    dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
 -                                 layout, args, i);
 -
 -    XawDialogAddButton(dialog, _("ok"), ErrorCallback, (XtPointer) dialog);
 -
 -    XtRealizeWidget(errorShell);
 -    CatchDeleteWindow(errorShell, "ErrorPopDown");
 -
 -    i = 0;
 -    XtSetArg(args[i], XtNwidth, &bw_width);  i++;
 -    XtGetValues(boardWidget, args, i);
 -    i = 0;
 -    XtSetArg(args[i], XtNwidth, &pw_width);  i++;
 -    XtSetArg(args[i], XtNheight, &pw_height);  i++;
 -    XtGetValues(errorShell, args, i);
 -
 -#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(boardWidget, (bw_width - pw_width) / 2,
 -                    0 - pw_height + squareSize / 3, &x, &y);
 -#else
 -    XTranslateCoordinates(xDisplay, XtWindow(boardWidget),
 -                        RootWindowOfScreen(XtScreen(boardWidget)),
 -                        (bw_width - pw_width) / 2,
 -                        0 - pw_height + squareSize / 3, &xx, &yy, &junk);
 -    x = xx;
 -    y = yy;
 -#endif
 -    if (y < 0) y = 0; /*avoid positioning top offscreen*/
 -
 -    i = 0;
 -    XtSetArg(args[i], XtNx, x);  i++;
 -    XtSetArg(args[i], XtNy, y);  i++;
 -    XtSetValues(errorShell, args, i);
 +  gtk_window_set_title(GTK_WINDOW(GUI_Error),(gchar *) title);
 +  if(modal)
 +    {
 +      gtk_dialog_run(GTK_DIALOG(GUI_Error));
 +      gtk_widget_destroy(GTK_WIDGET(GUI_Error));
 +    }
 +  else
 +    {
 +      g_signal_connect_swapped (GUI_Error, "response",
 +                                G_CALLBACK (ErrorPopDownProc),
 +                                GUI_Error);
 +      errorUp = True;
 +      gtk_widget_show(GTK_WIDGET(GUI_Error));
 +    }
  
 -    errorUp = True;
 -    XtPopup(errorShell, modal ? XtGrabExclusive : XtGrabNone);
 +  return;
  }
  
  /* Disable all user input other than deleting the window */
@@@ -3804,7 -5331,7 +3868,7 @@@ void FreezeUI(
  {
    if (frozen) return;
    /* Grab by a widget that doesn't accept input */
 -  XtAddGrab(messageWidget, TRUE, FALSE);
 +  //  XtAddGrab(messageWidget, TRUE, FALSE);
    frozen = 1;
  }
  
  void ThawUI()
  {
    if (!frozen) return;
 -  XtRemoveGrab(messageWidget);
 +  //  XtRemoveGrab(messageWidget);
    frozen = 0;
  }
  
@@@ -3860,44 -5387,69 +3924,44 @@@ char *ModeToWidgetName(mode
  
  void ModeHighlight()
  {
 -    Arg args[16];
      static int oldPausing = FALSE;
      static GameMode oldmode = (GameMode) -1;
      char *wname;
  
 -    if (!boardWidget || !XtIsRealized(boardWidget)) return;
 +   // todo this toggling of the pause button doesn't seem to work?
 +    // e.g. select pause from buttonbar doesn't activate menumode.pause
 +
 +    //    if (!boardWidget || !XtIsRealized(boardWidget)) return;
  
      if (pausing != oldPausing) {
 -      oldPausing = pausing;
 +      oldPausing = pausing;
 +      gtk_button_set_relief(GTK_BUTTON (gtk_builder_get_object (builder, "menuMode.Pause")),pausing?GTK_RELIEF_NORMAL:GTK_RELIEF_NONE);
 +      /* toggle background color in showbuttonbar */
 +      if (appData.showButtonBar) {
        if (pausing) {
 -          XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 +        gtk_button_pressed(GTK_BUTTON (gtk_builder_get_object (builder, "buttonbar.Pause")));
        } else {
 -          XtSetArg(args[0], XtNleftBitmap, None);
 -      }
 -      XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Pause"),
 -                  args, 1);
 -
 -      if (appData.showButtonBar) {
 -        /* Always toggle, don't set.  Previous code messes up when
 -           invoked while the button is pressed, as releasing it
 -           toggles the state again. */
 -        {
 -          Pixel oldbg, oldfg;
 -          XtSetArg(args[0], XtNbackground, &oldbg);
 -          XtSetArg(args[1], XtNforeground, &oldfg);
 -          XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON),
 -                      args, 2);
 -          XtSetArg(args[0], XtNbackground, oldfg);
 -          XtSetArg(args[1], XtNforeground, oldbg);
 -        }
 -        XtSetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
 +        gtk_button_released(GTK_BUTTON (gtk_builder_get_object (builder, "buttonbar.Pause")));
        }
 +      }
      }
  
 -    wname = ModeToWidgetName(oldmode);
 -    if (wname != NULL) {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -      XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
 -    }
 -    wname = ModeToWidgetName(gameMode);
 -    if (wname != NULL) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -      XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
 -    }
 +    // probably not needed anymore
 +//    wname = ModeToWidgetName(oldmode);
 +//    if(wname)
 +//       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, wname)),True);
 +
      oldmode = gameMode;
  
      /* Maybe all the enables should be handled here, not just this one */
 -    XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Training"),
 -                 gameMode == Training || gameMode == PlayFromGameFile);
 +    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuMode.Training")),
 +                           gameMode == Training || gameMode == PlayFromGameFile);
  }
  
  
  /*
   * Button/menu procedures
   */
 -void ResetProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ResetGameEvent();
 -}
  
  int LoadGamePopUp(f, gameNumber, title)
       FILE *f;
       char *title;
  {
      cmailMsgLoaded = FALSE;
 -    if (gameNumber == 0) {
 +
 +    if (gameNumber == 0) 
 +      {
        int error = GameListBuild(f);
 -      if (error) {
 +
 +      if (error) 
 +        {
            DisplayError(_("Cannot build game list"), error);
 -      } else if (!ListEmpty(&gameList) &&
 -                 ((ListGame *) gameList.tailPred)->number > 1) {
 +        } 
 +      else if (!ListEmpty(&gameList) 
 +               && ((ListGame *) gameList.tailPred)->number > 1) 
 +        {
 +          /* we need an answer which game to load, so let's make it modal for a while*/
 +          gtk_window_set_modal(GTK_WINDOW(GUI_GameList) , TRUE);  
            GameListPopUp(f, title);
 +          gtk_window_set_modal(GTK_WINDOW(GUI_GameList) , FALSE);  
 +
            return TRUE;
 -      }
 +        };
 +
        GameListDestroy();
        gameNumber = 1;
 -    }
 -    return LoadGame(f, gameNumber, title, FALSE);
 -}
 -
 -void LoadGameProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
 -      Reset(FALSE, TRUE);
 -    }
 -    FileNamePopUp(_("Load game file name?"), "", LoadGamePopUp, "rb");
 -}
 -
 -void LoadNextGameProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ReloadGame(1);
 -}
 -
 -void LoadPrevGameProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ReloadGame(-1);
 -}
 -
 -void ReloadGameProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ReloadGame(0);
 -}
 -
 -void LoadNextPositionProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ReloadPosition(1);
 -}
 -
 -void LoadPrevPositionProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ReloadPosition(-1);
 -}
 -
 -void ReloadPositionProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ReloadPosition(0);
 -}
 -
 -void LoadPositionProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
 -      Reset(FALSE, TRUE);
 -    }
 -    FileNamePopUp(_("Load position file name?"), "", LoadPosition, "rb");
 -}
 -
 -void SaveGameProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    FileNamePopUp(_("Save game file name?"),
 -                DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
 -                SaveGame, "a");
 -}
 +      };
  
 -void SavePositionProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    FileNamePopUp(_("Save position file name?"),
 -                DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
 -                SavePosition, "a");
 +    return LoadGame(f, gameNumber, title, FALSE);
  }
  
  void ReloadCmailMsgProc(w, event, prms, nprms)
@@@ -3961,34 -5601,34 +4025,34 @@@ SendPositionSelection(Widget w, Atom *s
    char *selection_tmp;
  
    if (!selected_fen_position) return False; /* should never happen */
 -  if (*target == XA_STRING || *target == XA_UTF8_STRING(xDisplay)){
 -    /* note: since no XtSelectionDoneProc was registered, Xt will
 -     * automatically call XtFree on the value returned.  So have to
 -     * make a copy of it allocated with XtMalloc */
 -    selection_tmp= XtMalloc(strlen(selected_fen_position)+16);
 -    strcpy(selection_tmp, selected_fen_position);
 -
 -    *value_return=selection_tmp;
 -    *length_return=strlen(selection_tmp);
 -    *type_return=*target;
 -    *format_return = 8; /* bits per byte */
 -    return True;
 -  } else if (*target == XA_TARGETS(xDisplay)) {
 -    Atom *targets_tmp = (Atom *) XtMalloc(2 * sizeof(Atom));
 -    targets_tmp[0] = XA_UTF8_STRING(xDisplay);
 -    targets_tmp[1] = XA_STRING;
 -    *value_return = targets_tmp;
 -    *type_return = XA_ATOM;
 -    *length_return = 2;
 -    *format_return = 8 * sizeof(Atom);
 -    if (*format_return > 32) {
 -      *length_return *= *format_return / 32;
 -      *format_return = 32;
 -    }
 -    return True;
 -  } else {
 -    return False;
 -  }
 +//  if (*target == XA_STRING || *target == XA_UTF8_STRING(xDisplay)){
 +//    /* note: since no XtSelectionDoneProc was registered, Xt will
 +//     * automatically call XtFree on the value returned.  So have to
 +//     * make a copy of it allocated with XtMalloc */
 +//    selection_tmp= XtMalloc(strlen(selected_fen_position)+16);
 +//    strcpy(selection_tmp, selected_fen_position);
 +//
 +//    *value_return=selection_tmp;
 +//    *length_return=strlen(selection_tmp);
 +//    *type_return=*target;
 +//    *format_return = 8; /* bits per byte */
 +//    return True;
 +//  } else if (*target == XA_TARGETS(xDisplay)) {
 +//    Atom *targets_tmp = (Atom *) XtMalloc(2 * sizeof(Atom));
 +//    targets_tmp[0] = XA_UTF8_STRING(xDisplay);
 +//    targets_tmp[1] = XA_STRING;
 +//    *value_return = targets_tmp;
 +//    *type_return = XA_ATOM;
 +//    *length_return = 2;
 +//    *format_return = 8 * sizeof(Atom);
 +//    if (*format_return > 32) {
 +//      *length_return *= *format_return / 32;
 +//      *format_return = 32;
 +//    }
 +//    return True;
 +//  } else {
 +//    return False;
 +//  }
  }
  
  /* note: when called from menu all parameters are NULL, so no clue what the
@@@ -4009,16 -5649,16 +4073,16 @@@ void CopyPositionProc(w, event, prms, n
      if (selected_fen_position) free(selected_fen_position);
      selected_fen_position = (char *)PositionToFEN(currentMove, NULL);
      if (!selected_fen_position) return;
 -    XtOwnSelection(menuBarWidget, XA_PRIMARY,
 -                 CurrentTime,
 -                 SendPositionSelection,
 -                 NULL/* lose_ownership_proc */ ,
 -                 NULL/* transfer_done_proc */);
 -    XtOwnSelection(menuBarWidget, XA_CLIPBOARD(xDisplay),
 -                 CurrentTime,
 -                 SendPositionSelection,
 -                 NULL/* lose_ownership_proc */ ,
 -                 NULL/* transfer_done_proc */);
 +//    XtOwnSelection(menuBarWidget, XA_PRIMARY,
 +//               CurrentTime,
 +//               SendPositionSelection,
 +//               NULL/* lose_ownership_proc */ ,
 +//               NULL/* transfer_done_proc */);
 +//    XtOwnSelection(menuBarWidget, XA_CLIPBOARD(xDisplay),
 +//               CurrentTime,
 +//               SendPositionSelection,
 +//               NULL/* lose_ownership_proc */ ,
 +//               NULL/* transfer_done_proc */);
    }
  
  /* function called when the data to Paste is ready */
@@@ -4041,16 -5681,16 +4105,16 @@@ void PastePositionProc(w, event, prms, 
    String *prms;
    Cardinal *nprms;
  {
 -    XtGetSelectionValue(menuBarWidget, 
 -      appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING,
 -      /* (XtSelectionCallbackProc) */ PastePositionCB,
 -      NULL, /* client_data passed to PastePositionCB */
 -
 -      /* better to use the time field from the event that triggered the
 -       * call to this function, but that isn't trivial to get
 -       */
 -      CurrentTime
 -    );
 +//    XtGetSelectionValue(menuBarWidget, 
 +//      appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING,
 +//      /* (XtSelectionCallbackProc) */ PastePositionCB,
 +//      NULL, /* client_data passed to PastePositionCB */
 +//
 +//      /* better to use the time field from the event that triggered the
 +//       * call to this function, but that isn't trivial to get
 +//       */
 +//      CurrentTime
 +//    );
      return;
  }
  
@@@ -4061,42 -5701,42 +4125,42 @@@ SendGameSelection(Widget w, Atom *selec
  {
    char *selection_tmp;
  
 -  if (*target == XA_STRING || *target == XA_UTF8_STRING(xDisplay)){
 -    FILE* f = fopen(gameCopyFilename, "r");
 -    long len;
 -    size_t count;
 -    if (f == NULL) return False;
 -    fseek(f, 0, 2);
 -    len = ftell(f);
 -    rewind(f);
 -    selection_tmp = XtMalloc(len + 1);
 -    count = fread(selection_tmp, 1, len, f);
 -    if (len != count) {
 -      XtFree(selection_tmp);
 -      return False;
 -    }
 -    selection_tmp[len] = NULLCHAR;
 -    *value_return = selection_tmp;
 -    *length_return = len;
 -    *type_return = *target;
 -    *format_return = 8; /* bits per byte */
 -    return True;
 -  } else if (*target == XA_TARGETS(xDisplay)) {
 -    Atom *targets_tmp = (Atom *) XtMalloc(2 * sizeof(Atom));
 -    targets_tmp[0] = XA_UTF8_STRING(xDisplay);
 -    targets_tmp[1] = XA_STRING;
 -    *value_return = targets_tmp;
 -    *type_return = XA_ATOM;
 -    *length_return = 2;
 -    *format_return = 8 * sizeof(Atom);
 -    if (*format_return > 32) {
 -      *length_return *= *format_return / 32;
 -      *format_return = 32;
 -    }
 -    return True;
 -  } else {
 -    return False;
 -  }
 +//  if (*target == XA_STRING || *target == XA_UTF8_STRING(xDisplay)){
 +//    FILE* f = fopen(gameCopyFilename, "r");
 +//    long len;
 +//    size_t count;
 +//    if (f == NULL) return False;
 +//    fseek(f, 0, 2);
 +//    len = ftell(f);
 +//    rewind(f);
 +//    selection_tmp = XtMalloc(len + 1);
 +//    count = fread(selection_tmp, 1, len, f);
 +//    if (len != count) {
 +//      XtFree(selection_tmp);
 +//      return False;
 +//    }
 +//    selection_tmp[len] = NULLCHAR;
 +//    *value_return = selection_tmp;
 +//    *length_return = len;
 +//    *type_return = *target;
 +//    *format_return = 8; /* bits per byte */
 +//    return True;
 +//  } else if (*target == XA_TARGETS(xDisplay)) {
 +//    Atom *targets_tmp = (Atom *) XtMalloc(2 * sizeof(Atom));
 +//    targets_tmp[0] = XA_UTF8_STRING(xDisplay);
 +//    targets_tmp[1] = XA_STRING;
 +//    *value_return = targets_tmp;
 +//    *type_return = XA_ATOM;
 +//    *length_return = 2;
 +//    *format_return = 8 * sizeof(Atom);
 +//    if (*format_return > 32) {
 +//      *length_return *= *format_return / 32;
 +//      *format_return = 32;
 +//    }
 +//    return True;
 +//  } else {
 +//    return False;
 +//  }
  }
  
  /* note: when called from menu all parameters are NULL, so no clue what the
@@@ -4118,16 -5758,16 +4182,16 @@@ void CopyGameProc(w, event, prms, nprms
     * have a notion of a game that is selected but not copied.
     * See http://www.freedesktop.org/wiki/Specifications/ClipboardsWiki
     */
 -  XtOwnSelection(menuBarWidget, XA_PRIMARY,
 -               CurrentTime,
 -               SendGameSelection,
 -               NULL/* lose_ownership_proc */ ,
 -               NULL/* transfer_done_proc */);
 -  XtOwnSelection(menuBarWidget, XA_CLIPBOARD(xDisplay),
 -               CurrentTime,
 -               SendGameSelection,
 -               NULL/* lose_ownership_proc */ ,
 -               NULL/* transfer_done_proc */);
 +//  XtOwnSelection(menuBarWidget, XA_PRIMARY,
 +//             CurrentTime,
 +//             SendGameSelection,
 +//             NULL/* lose_ownership_proc */ ,
 +//             NULL/* transfer_done_proc */);
 +//  XtOwnSelection(menuBarWidget, XA_CLIPBOARD(xDisplay),
 +//             CurrentTime,
 +//             SendGameSelection,
 +//             NULL/* lose_ownership_proc */ ,
 +//             NULL/* transfer_done_proc */);
  }
  
  /* function called when the data to Paste is ready */
@@@ -4158,54 -5798,172 +4222,54 @@@ void PasteGameProc(w, event, prms, nprm
    String *prms;
    Cardinal *nprms;
  {
 -    XtGetSelectionValue(menuBarWidget,
 -      appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING,
 -      /* (XtSelectionCallbackProc) */ PasteGameCB,
 -      NULL, /* client_data passed to PasteGameCB */
 -
 -      /* better to use the time field from the event that triggered the
 -       * call to this function, but that isn't trivial to get
 -       */
 -      CurrentTime
 -    );
 -    return;
 -}
 -
 -
 -void AutoSaveGame()
 -{
 -    SaveGameProc(NULL, NULL, NULL, NULL);
 -}
 -
 -
 -void QuitProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ExitEvent(0);
 +//    XtGetSelectionValue(menuBarWidget,
 +//      appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING,
 +//      /* (XtSelectionCallbackProc) */ PasteGameCB,
 +//      NULL, /* client_data passed to PasteGameCB */
 +//
 +//      /* better to use the time field from the event that triggered the
 +//       * call to this function, but that isn't trivial to get
 +//       */
 +//      CurrentTime
 +//    );
 +//    return;
  }
  
 -void PauseProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    PauseEvent();
 -}
 -
 -
 -void MachineBlackProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    MachineBlackEvent();
 -}
 -
 -void MachineWhiteProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    MachineWhiteEvent();
 -}
 -
 -void AnalyzeModeProc(w, event, prms, nprms)
 +void SaveOnExitProc(w, event, prms, nprms)
       Widget w;
       XEvent *event;
       String *prms;
       Cardinal *nprms;
  {
 -    char buf[MSG_SIZ];
 -
 -    if (!first.analysisSupport) {
 -      snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy);
 -      DisplayError(buf, 0);
 -      return;
 -    }
 -    /* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */
 -    if (appData.icsActive) {
 -        if (gameMode != IcsObserving) {
 -            sprintf(buf,_("You are not observing a game"));
 -            DisplayError(buf, 0);
 -            /* secure check */
 -            if (appData.icsEngineAnalyze) {
 -                if (appData.debugMode)
 -                    fprintf(debugFP, _("Found unexpected active ICS engine analyze \n"));
 -                ExitAnalyzeMode();
 -                ModeHighlight();
 -            }
 -            return;
 -        }
 -        /* if enable, use want disable icsEngineAnalyze */
 -        if (appData.icsEngineAnalyze) {
 -                ExitAnalyzeMode();
 -                ModeHighlight();
 -                return;
 -        }
 -        appData.icsEngineAnalyze = TRUE;
 -        if (appData.debugMode)
 -            fprintf(debugFP, _("ICS engine analyze starting... \n"));
 -    }
 -    if (!appData.showThinking)
 -      ShowThinkingProc(w,event,prms,nprms);
 +    Arg args[16];
  
 -    AnalyzeModeEvent();
 -}
 +    saveSettingsOnExit = !saveSettingsOnExit;
  
 -void AnalyzeFileProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    if (!first.analysisSupport) {
 -      char buf[MSG_SIZ];
 -      snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy);
 -      DisplayError(buf, 0);
 -      return;
 +    if (saveSettingsOnExit) {
 +      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 +    } else {
 +      XtSetArg(args[0], XtNleftBitmap, None);
      }
 -    Reset(FALSE, TRUE);
 -
 -    if (!appData.showThinking)
 -      ShowThinkingProc(w,event,prms,nprms);
 -
 -    AnalyzeFileEvent();
 -    FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
 -    AnalysisPeriodicEvent(1);
 -}
 -
 -void TwoMachinesProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    TwoMachinesEvent();
 +    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Save Settings on Exit"),
 +              args, 1);
  }
  
 -void IcsClientProc(w, event, prms, nprms)
 +void SaveSettingsProc(w, event, prms, nprms)
       Widget w;
       XEvent *event;
       String *prms;
       Cardinal *nprms;
  {
 -    IcsClientEvent();
 +     SaveSettings(settingsFileName);
  }
  
 -void EditGameProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    EditGameEvent();
 -}
  
 -void EditPositionProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 +void AutoSaveGame()
  {
 -    EditPositionEvent();
 +  SaveGameProc(NULL, NULL);
 +  return;
  }
  
 -void TrainingProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    TrainingEvent();
 -}
  
  void EditCommentProc(w, event, prms, nprms)
       Widget w;
@@@ -4233,6 -5991,104 +4297,6 @@@ void IcsInputBoxProc(w, event, prms, np
      }
  }
  
 -void AcceptProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    AcceptEvent();
 -}
 -
 -void DeclineProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    DeclineEvent();
 -}
 -
 -void RematchProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    RematchEvent();
 -}
 -
 -void CallFlagProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    CallFlagEvent();
 -}
 -
 -void DrawProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    DrawEvent();
 -}
 -
 -void AbortProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    AbortEvent();
 -}
 -
 -void AdjournProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    AdjournEvent();
 -}
 -
 -void ResignProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ResignEvent();
 -}
 -
 -void AdjuWhiteProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    UserAdjudicationEvent(+1);
 -}
 -
 -void AdjuBlackProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    UserAdjudicationEvent(-1);
 -}
 -
 -void AdjuDrawProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    UserAdjudicationEvent(0);
 -}
  
  void EnterKeyProc(w, event, prms, nprms)
       Widget w;
        ICSInputSendText();
  }
  
 -void StopObservingProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    StopObservingEvent();
 -}
 -
 -void StopExaminingProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    StopExaminingEvent();
 -}
 -
 -
 -void ForwardProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ForwardEvent();
 -}
 -
 -
 -void BackwardProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    BackwardEvent();
 -}
 -
 -void ToStartProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ToStartEvent();
 -}
 -
 -void ToEndProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    ToEndEvent();
 -}
 -
 -void RevertProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    RevertEvent();
 -}
 -
 -void TruncateGameProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    TruncateGameEvent();
 -}
 -void RetractMoveProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    RetractMoveEvent();
 -}
 -
 -void MoveNowProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    MoveNowEvent();
 -}
 -
 -
 -void AlwaysQueenProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
 -
 -    if (appData.alwaysPromoteToQueen) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
 -              args, 1);
 -}
 -
 -void AnimateDraggingProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.animateDragging = !appData.animateDragging;
 -
 -    if (appData.animateDragging) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -        CreateAnimVars();
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"),
 -              args, 1);
 -}
 -
 -void AnimateMovingProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.animate = !appData.animate;
 -
 -    if (appData.animate) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -        CreateAnimVars();
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
 -              args, 1);
 -}
 -
 -void AutocommProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.autoComment = !appData.autoComment;
 -
 -    if (appData.autoComment) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
 -              args, 1);
 -}
 -
 -
 -void AutoflagProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.autoCallFlag = !appData.autoCallFlag;
 -
 -    if (appData.autoCallFlag) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
 -              args, 1);
 -}
 -
 -void AutoflipProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.autoFlipView = !appData.autoFlipView;
 -
 -    if (appData.autoFlipView) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flip View"),
 -              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;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.blindfold = !appData.blindfold;
 -
 -    if (appData.blindfold) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"),
 -              args, 1);
 -
 -    DrawPosition(True, NULL);
 -}
 -
 -void TestLegalityProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.testLegality = !appData.testLegality;
 -
 -    if (appData.testLegality) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Test Legality"),
 -              args, 1);
 -}
 -
 -
 -void FlashMovesProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    if (appData.flashCount == 0) {
 -      appData.flashCount = 3;
 -    } else {
 -      appData.flashCount = -appData.flashCount;
 -    }
 -
 -    if (appData.flashCount > 0) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flash Moves"),
 -              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)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.getMoveList = !appData.getMoveList;
 -
 -    if (appData.getMoveList) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -      GetMoveListEvent();
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
 -              args, 1);
 -}
 -
 -#if HIGHDRAG
 -void HighlightDraggingProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.highlightDragging = !appData.highlightDragging;
 -
 -    if (appData.highlightDragging) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget,
 -                             "menuOptions.Highlight Dragging"), args, 1);
 -}
 -#endif
 -
 -void HighlightLastMoveProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.highlightLastMove = !appData.highlightLastMove;
 -
 -    if (appData.highlightLastMove) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget,
 -                             "menuOptions.Highlight Last Move"), args, 1);
 -}
 -
 -void IcsAlarmProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.icsAlarm = !appData.icsAlarm;
 -
 -    if (appData.icsAlarm) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget,
 -                             "menuOptions.ICS Alarm"), args, 1);
 -}
 -
 -void MoveSoundProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.ringBellAfterMoves = !appData.ringBellAfterMoves;
 -
 -    if (appData.ringBellAfterMoves) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
 -              args, 1);
 -}
 -
 -
 -void OldSaveStyleProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.oldSaveStyle = !appData.oldSaveStyle;
 -
 -    if (appData.oldSaveStyle) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"),
 -              args, 1);
 -}
 -
 -void PeriodicUpdatesProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    PeriodicUpdatesEvent(!appData.periodicUpdates);
 -
 -    if (appData.periodicUpdates) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Periodic Updates"),
 -              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;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.popupExitMessage = !appData.popupExitMessage;
 -
 -    if (appData.popupExitMessage) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget,
 -                             "menuOptions.Popup Exit Message"), args, 1);
 -}
 -
 -void PopupMoveErrorsProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.popupMoveErrors = !appData.popupMoveErrors;
 -
 -    if (appData.popupMoveErrors) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"),
 -              args, 1);
 -}
 -
 -void PremoveProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.premove = !appData.premove;
 -
 -    if (appData.premove) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    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);
 -}
 -
 -void ShowCoordsProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.showCoords = !appData.showCoords;
 -
 -    if (appData.showCoords) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
 -              args, 1);
 -
 -    DrawPosition(True, NULL);
 -}
 -
 -void ShowThinkingProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent
 -    ShowThinkingEvent();
 -}
 -
 -void HideThinkingProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    appData.hideThinkingFromHuman = !appData.hideThinkingFromHuman; // [HGM] thinking: tken out of ShowThinkingEvent
 -    ShowThinkingEvent();
 -
 -    if (appData.hideThinkingFromHuman) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
 -              args, 1);
 -}
 -
 -void SaveOnExitProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    Arg args[16];
 -
 -    saveSettingsOnExit = !saveSettingsOnExit;
 -
 -    if (saveSettingsOnExit) {
 -      XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
 -    } else {
 -      XtSetArg(args[0], XtNleftBitmap, None);
 -    }
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Save Settings on Exit"),
 -              args, 1);
 -}
 -
 -void SaveSettingsProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -     SaveSettings(settingsFileName);
 -}
 -
 -void InfoProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    char buf[MSG_SIZ];
 -    snprintf(buf, sizeof(buf), "xterm -e info --directory %s --directory . -f %s &",
 -          INFODIR, INFOFILE);
 -    system(buf);
 -}
 -
 -void ManProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    char buf[MSG_SIZ];
 -    String name;
 -    if (nprms && *nprms > 0)
 -      name = prms[0];
 -    else
 -      name = "xboard";
 -    snprintf(buf, sizeof(buf), "xterm -e man %s &", name);
 -    system(buf);
 -}
 -
 -void HintProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    HintEvent();
 -}
 -
 -void BookProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    BookEvent();
 -}
 -
 -void AboutProc(w, event, prms, nprms)
 -     Widget w;
 -     XEvent *event;
 -     String *prms;
 -     Cardinal *nprms;
 -{
 -    char buf[MSG_SIZ];
 -#if ZIPPY
 -    char *zippy = " (with Zippy code)";
 -#else
 -    char *zippy = "";
 -#endif
 -    snprintf(buf, sizeof(buf), "%s%s\n\n%s\n%s\n%s\n\n%s%s\n%s",
 -          programVersion, zippy,
 -          "Copyright 1991 Digital Equipment Corporation",
 -          "Enhancements Copyright 1992-2009 Free Software Foundation",
 -          "Enhancements Copyright 2005 Alessandro Scotti",
 -          PACKAGE, " is free software and carries NO WARRANTY;",
 -          "see the file COPYING for more information.");
 -    ErrorPopUp(_("About XBoard"), buf, FALSE);
 -}
  
  void DebugProc(w, event, prms, nprms)
       Widget w;
@@@ -4280,78 -6854,91 +4344,78 @@@ void Iconify(w, event, prms, nprms
  {
      Arg args[16];
  
 -    fromX = fromY = -1;
 -    XtSetArg(args[0], XtNiconic, True);
 -    XtSetValues(shellWidget, args, 1);
 +//    fromX = fromY = -1;
 +//    XtSetArg(args[0], XtNiconic, True);
 +//    XtSetValues(shellWidget, args, 1);
  }
  
  void DisplayMessage(message, extMessage)
 -     char *message, *extMessage;
 +     gchar *message, *extMessage;
  {
 -  /* display a message in the message widget */
 -  
 -  char buf[MSG_SIZ];
 -  Arg arg;
 -  
 -  if (extMessage) 
 -    {
 -      if (*message) 
 -      {
 -        snprintf(buf, sizeof(buf), "%s  %s", message, extMessage);
 -        message = buf;
 -      } 
 -      else 
 -      {
 -        message = extMessage;
 -      };
 -    };
 -  
 -  /* 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 */
 -  if(messageWidget)
 -    {
 -      XtSetArg(arg, XtNlabel, message);
 -      XtSetValues(messageWidget, &arg, 1);
 -    };
 -  
 -  return;
 +    char buf[MSG_SIZ];
 +    Arg arg;
 +
 +    if (extMessage) {
 +      if (*message) {
 +          snprintf(buf, sizeof(buf), "%s  %s", message, extMessage);
 +          message = buf;
 +      } else {
 +          message = extMessage;
 +      }
 +    }
 +    gtk_label_set_text( GTK_LABEL(gtk_builder_get_object (builder, "Messages")),message);
 +
 +    return;
  }
  
  void DisplayTitle(text)
       char *text;
  {
 -    Arg args[16];
 -    int i;
 -    char title[MSG_SIZ];
 -    char icon[MSG_SIZ];
 +    gchar title[MSG_SIZ];
  
      if (text == NULL) text = "";
  
 -    if (appData.titleInWindow) {
 -      i = 0;
 -      XtSetArg(args[i], XtNlabel, text);   i++;
 -      XtSetValues(titleWidget, args, i);
 -    }
 +    if (appData.titleInWindow)
 +      {
 +      /* TODO */
 +      }
  
 -    if (*text != NULLCHAR) {
 -      strcpy(icon, text);
 +    if (*text != NULLCHAR)
 +      {
        strcpy(title, text);
 -    } else if (appData.icsActive) {
 -        snprintf(icon, sizeof(icon), "%s", appData.icsHost);
 +      }
 +    else if (appData.icsActive)
 +      {
        snprintf(title, sizeof(title), "%s: %s", programName, appData.icsHost);
 -    } else if (appData.cmailGameName[0] != NULLCHAR) {
 -        snprintf(icon, sizeof(icon), "%s", "CMail");
 +      }
 +    else if (appData.cmailGameName[0] != NULLCHAR)
 +      {
        snprintf(title,sizeof(title), "%s: %s", programName, "CMail");
  #ifdef GOTHIC
      // [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it
 -    } else if (gameInfo.variant == VariantGothic) {
 -      strcpy(icon, programName);
 +      }
 +    else if (gameInfo.variant == VariantGothic)
 +      {
        strcpy(title, GOTHIC);
  #endif
  #ifdef FALCON
 -    } else if (gameInfo.variant == VariantFalcon) {
 -      strcpy(icon, programName);
 +      }
 +    else if (gameInfo.variant == VariantFalcon)
 +      {
        strcpy(title, FALCON);
  #endif
 -    } else if (appData.noChessProgram) {
 -      strcpy(icon, programName);
 +      }
 +    else if (appData.noChessProgram)
 +      {
        strcpy(title, programName);
 -    } else {
 -      strcpy(icon, first.tidy);
 +      }
 +    else
 +      {
        snprintf(title,sizeof(title), "%s: %s", programName, first.tidy);
 -    }
 -    i = 0;
 -    XtSetArg(args[i], XtNiconName, (XtArgVal) icon);    i++;
 -    XtSetArg(args[i], XtNtitle, (XtArgVal) title);      i++;
 -    XtSetValues(shellWidget, args, i);
 +      }
 +    gtk_window_set_title(GTK_WINDOW(GUI_Window),title);
 +
 +    return;
  }
  
  
@@@ -4449,14 -7036,14 +4513,14 @@@ void DisplayIcsInteractionTitle(message
        Window root, parent, *children;
        unsigned int nchildren;
        int (*oldHandler)() = XSetErrorHandler(NullXErrorCheck);
 -      for (;;) {
 -      if (XFetchName(xDisplay, win, &oldICSInteractionTitle)) break;
 -      if (!XQueryTree(xDisplay, win, &root, &parent,
 -                      &children, &nchildren)) break;
 -      if (children) XFree((void *)children);
 -      if (parent == root || parent == 0) break;
 -      win = parent;
 -      }
 +//      for (;;) {
 +//    if (XFetchName(xDisplay, win, &oldICSInteractionTitle)) break;
 +//    if (!XQueryTree(xDisplay, win, &root, &parent,
 +//                    &children, &nchildren)) break;
 +//    if (children) XFree((void *)children);
 +//    if (parent == root || parent == 0) break;
 +//    win = parent;
 +//      }
        XSetErrorHandler(oldHandler);
      }
      if (oldICSInteractionTitle == NULL) {
@@@ -4547,14 -7134,14 +4611,14 @@@ void AskQuestion(title, question, reply
      i = 0;
      XtSetArg(args[i], XtNresizable, True); i++;
      XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
 -    askQuestionShell = popup =
 -      XtCreatePopupShell(title, transientShellWidgetClass,
 -                       shellWidget, args, i);
 -
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 -                          layoutArgs, XtNumber(layoutArgs));
 -
 +//    askQuestionShell = popup =
 +//      XtCreatePopupShell(title, transientShellWidgetClass,
 +//                     shellWidget, args, i);
 +//
 +//    layout =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 +//                        layoutArgs, XtNumber(layoutArgs));
 +//
      i = 0;
      XtSetArg(args[i], XtNlabel, question); i++;
      XtSetArg(args[i], XtNvalue, ""); i++;
                       (XtPointer) dialog);
  
      XtRealizeWidget(popup);
 -    CatchDeleteWindow(popup, "AskQuestionPopDown");
 -
 -    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 -                &x, &y, &win_x, &win_y, &mask);
 -
 -    XtSetArg(args[0], XtNx, x - 10);
 -    XtSetArg(args[1], XtNy, y - 30);
 -    XtSetValues(popup, args, 2);
 +    //    CatchDeleteWindow(popup, "AskQuestionPopDown");
  
 -    XtPopup(popup, XtGrabExclusive);
 -    askQuestionUp = True;
 -
 -    edit = XtNameToWidget(dialog, "*value");
 -    XtSetKeyboardFocus(popup, edit);
 +//    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 +//              &x, &y, &win_x, &win_y, &mask);
 +//
 +//    XtSetArg(args[0], XtNx, x - 10);
 +//    XtSetArg(args[1], XtNy, y - 30);
 +//    XtSetValues(popup, args, 2);
 +//
 +//    XtPopup(popup, XtGrabExclusive);
 +//    askQuestionUp = True;
 +//
 +//    edit = XtNameToWidget(dialog, "*value");
 +//    XtSetKeyboardFocus(popup, edit);
  }
  
  
@@@ -4779,72 -7366,60 +4843,72 @@@ char *HostName(
  #endif /* not HAVE_GETHOSTNAME */
  }
  
 -XtIntervalId delayedEventTimerXID = 0;
 +guint delayedEventTimerTag = 0;
  DelayedEventCallback delayedEventCallback = 0;
  
  void
 -FireDelayedEvent()
 +FireDelayedEvent(data)
 +     gpointer data;
  {
 -    delayedEventTimerXID = 0;
 -    delayedEventCallback();
 +  /* remove timer */
 +  g_source_remove(delayedEventTimerTag);
 +  delayedEventTimerTag = 0;
 +
 +  /* call function */
 +  delayedEventCallback();
 +
 +  return;
  }
  
  void
  ScheduleDelayedEvent(cb, millisec)
 -     DelayedEventCallback cb; long millisec;
 +     DelayedEventCallback cb; guint millisec;
  {
 -    if(delayedEventTimerXID && delayedEventCallback == cb)
 +    if(delayedEventTimerTag && delayedEventCallback == cb)
        // [HGM] alive: replace, rather than add or flush identical event
 -      XtRemoveTimeOut(delayedEventTimerXID);
 +      g_source_remove(delayedEventTimerTag);
      delayedEventCallback = cb;
 -    delayedEventTimerXID =
 -      XtAppAddTimeOut(appContext, millisec,
 -                    (XtTimerCallbackProc) FireDelayedEvent, (XtPointer) 0);
 +    delayedEventTimerTag = g_timeout_add(millisec,(GSourceFunc) FireDelayedEvent, NULL);
 +    return;
  }
  
  DelayedEventCallback
  GetDelayedEvent()
  {
 -  if (delayedEventTimerXID) {
 -    return delayedEventCallback;
 -  } else {
 -    return NULL;
 -  }
 +  if (delayedEventTimerTag)
 +    {
 +      return delayedEventCallback;
 +    }
 +  else
 +    {
 +      return NULL;
 +    }
  }
  
  void
  CancelDelayedEvent()
  {
 -  if (delayedEventTimerXID) {
 -    XtRemoveTimeOut(delayedEventTimerXID);
 -    delayedEventTimerXID = 0;
 -  }
 +  if (delayedEventTimerTag)
 +    {
 +      g_source_remove(delayedEventTimerTag);
 +      delayedEventTimerTag = 0;
 +    }
 +
 +  return;
  }
  
 -XtIntervalId loadGameTimerXID = 0;
 +guint loadGameTimerTag = 0;
  
  int LoadGameTimerRunning()
  {
 -    return loadGameTimerXID != 0;
 +    return loadGameTimerTag != 0;
  }
  
  int StopLoadGameTimer()
  {
 -    if (loadGameTimerXID != 0) {
 -      XtRemoveTimeOut(loadGameTimerXID);
 -      loadGameTimerXID = 0;
 +    if (loadGameTimerTag != 0) {
 +      g_source_remove(loadGameTimerTag);
 +      loadGameTimerTag = 0;
        return TRUE;
      } else {
        return FALSE;
  }
  
  void
 -LoadGameTimerCallback(arg, id)
 -     XtPointer arg;
 -     XtIntervalId *id;
 +LoadGameTimerCallback(data)
 +     gpointer data;
  {
 -    loadGameTimerXID = 0;
 -    AutoPlayGameLoop();
 +  /* remove timer */
 +  g_source_remove(loadGameTimerTag);
 +  loadGameTimerTag = 0;
 +
 +  AutoPlayGameLoop();
 +  return;
  }
  
  void
  StartLoadGameTimer(millisec)
       long millisec;
  {
 -    loadGameTimerXID =
 -      XtAppAddTimeOut(appContext, millisec,
 -                    (XtTimerCallbackProc) LoadGameTimerCallback,
 -                    (XtPointer) 0);
 +  loadGameTimerTag =
 +    g_timeout_add( millisec, (GSourceFunc) LoadGameTimerCallback, NULL);
 +  return;
  }
  
 -XtIntervalId analysisClockXID = 0;
 +guint analysisClockTag = 0;
  
 -void
 -AnalysisClockCallback(arg, id)
 -     XtPointer arg;
 -     XtIntervalId *id;
 +gboolean
 +AnalysisClockCallback(data)
 +     gpointer data;
  {
      if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
 -         || appData.icsEngineAnalyze) { // [DM]
 +         || appData.icsEngineAnalyze)
 +      {
        AnalysisPeriodicEvent(0);
 -      StartAnalysisClock();
 -    }
 +      return 1; /* keep on going */
 +      }
 +    return 0; /* stop timer */
  }
  
  void
  StartAnalysisClock()
  {
 -    analysisClockXID =
 -      XtAppAddTimeOut(appContext, 2000,
 -                    (XtTimerCallbackProc) AnalysisClockCallback,
 -                    (XtPointer) 0);
 +  analysisClockTag =
 +    g_timeout_add( 2000,(GSourceFunc) AnalysisClockCallback, NULL);
 +  return;
  }
  
 -XtIntervalId clockTimerXID = 0;
 +guint clockTimerTag = 0;
  
  int ClockTimerRunning()
  {
 -    return clockTimerXID != 0;
 +    return clockTimerTag != 0;
  }
  
  int StopClockTimer()
  {
 -    if (clockTimerXID != 0) {
 -      XtRemoveTimeOut(clockTimerXID);
 -      clockTimerXID = 0;
 +    if (clockTimerTag != 0)
 +      {
 +      g_source_remove(clockTimerTag);
 +      clockTimerTag = 0;
        return TRUE;
 -    } else {
 +      }
 +    else
 +      {
        return FALSE;
 -    }
 +      }
  }
  
  void
 -ClockTimerCallback(arg, id)
 -     XtPointer arg;
 -     XtIntervalId *id;
 +ClockTimerCallback(data)
 +     gpointer data;
  {
 -    clockTimerXID = 0;
 -    DecrementClocks();
 +  /* remove timer */
 +  g_source_remove(clockTimerTag);
 +  clockTimerTag = 0;
 +
 +  DecrementClocks();
 +  return;
  }
  
  void
  StartClockTimer(millisec)
       long millisec;
  {
 -    clockTimerXID =
 -      XtAppAddTimeOut(appContext, millisec,
 -                    (XtTimerCallbackProc) ClockTimerCallback,
 -                    (XtPointer) 0);
 +  clockTimerTag = g_timeout_add(millisec,(GSourceFunc) ClockTimerCallback,NULL);
 +  return;
  }
  
  void
  DisplayTimerLabel(w, color, timer, highlight)
 -     Widget w;
 +     GtkWidget *w;
       char *color;
       long timer;
       int highlight;
  {
 -    char buf[MSG_SIZ];
 -    Arg args[16];
 -
 -    /* check for low time warning */
 -    Pixel foregroundOrWarningColor = timerForegroundPixel;
 -
 -    if (timer > 0 &&
 -        appData.lowTimeWarning && 
 -        (timer / 1000) < appData.icsAlarmTime)
 -      foregroundOrWarningColor = lowTimeWarningColor;
 -
 -    if (appData.clockMode) {
 -      sprintf(buf, "%s: %s", color, TimeString(timer));
 -      XtSetArg(args[0], XtNlabel, buf);
 -    } else {
 -      sprintf(buf, "%s  ", color);
 -      XtSetArg(args[0], XtNlabel, buf);
 -    }
 +  gchar buf[MSG_SIZ];
  
 -    if (highlight) {
 -
 -      XtSetArg(args[1], XtNbackground, foregroundOrWarningColor);
 -      XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
 -    } else {
 -      XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
 -      XtSetArg(args[2], XtNforeground, foregroundOrWarningColor);
 -    }
  
 -    XtSetValues(w, args, 3);
 +  if (appData.clockMode) {
 +    sprintf(buf, "%s: %s", color, TimeString(timer));
 +  } else {
 +    sprintf(buf, "%s  ", color);
 +  }
 +  gtk_label_set_text(GTK_LABEL(w),buf);
 +
 +  /* check for low time warning */
 +//    Pixel foregroundOrWarningColor = timerForegroundPixel;
 +
 +//    if (timer > 0 &&
 +//        appData.lowTimeWarning &&
 +//        (timer / 1000) < appData.icsAlarmTime)
 +//      foregroundOrWarningColor = lowTimeWarningColor;
 +//
 +//    if (appData.clockMode) {
 +//    sprintf(buf, "%s: %s", color, TimeString(timer));
 +//    XtSetArg(args[0], XtNlabel, buf);
 +//    } else {
 +//    sprintf(buf, "%s  ", color);
 +//    XtSetArg(args[0], XtNlabel, buf);
 +//    }
 +//
 +//    if (highlight) {
 +//
 +//    XtSetArg(args[1], XtNbackground, foregroundOrWarningColor);
 +//    XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
 +//    } else {
 +//    XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
 +//    XtSetArg(args[2], XtNforeground, foregroundOrWarningColor);
 +//    }
 +//
 +//    XtSetValues(w, args, 3);
 +//
  }
  
  void
@@@ -4987,13 -7548,14 +5051,13 @@@ DisplayWhiteClock(timeRemaining, highli
       long timeRemaining;
       int highlight;
  {
 -    Arg args[16];
 +  if(appData.noGUI) return;
  
 -    if(appData.noGUI) return;
 -    DisplayTimerLabel(whiteTimerWidget, _("White"), timeRemaining, highlight);
 -    if (highlight && iconPixmap == bIconPixmap) {
 -      iconPixmap = wIconPixmap;
 -      XtSetArg(args[0], XtNiconPixmap, iconPixmap);
 -      XtSetValues(shellWidget, args, 1);
 +  DisplayTimerLabel(GUI_Whiteclock, _("White"), timeRemaining, highlight);
 +  if (highlight && WindowIcon == BlackIcon)
 +    {
 +      WindowIcon = WhiteIcon;
 +      gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
      }
  }
  
@@@ -5002,14 -7564,15 +5066,14 @@@ DisplayBlackClock(timeRemaining, highli
       long timeRemaining;
       int highlight;
  {
 -    Arg args[16];
 -
      if(appData.noGUI) return;
 -    DisplayTimerLabel(blackTimerWidget, _("Black"), timeRemaining, highlight);
 -    if (highlight && iconPixmap == wIconPixmap) {
 -      iconPixmap = bIconPixmap;
 -      XtSetArg(args[0], XtNiconPixmap, iconPixmap);
 -      XtSetValues(shellWidget, args, 1);
 -    }
 +
 +    DisplayTimerLabel(GUI_Blackclock, _("Black"), timeRemaining, highlight);
 +    if (highlight && WindowIcon == WhiteIcon)
 +      {
 +        WindowIcon = BlackIcon;
 +        gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
 +      }
  }
  
  #define CPNone 0
@@@ -5280,75 -7843,51 +5344,75 @@@ typedef struct 
      int lineByLine;
      char *unused;
      InputCallback func;
 -    XtInputId xid;
 +    guint sid;
      char buf[INPUT_SOURCE_BUF_SIZE];
      VOIDSTAR closure;
  } InputSource;
  
  void
 -DoInputCallback(closure, source, xid)
 -     caddr_t closure;
 -     int *source;
 -     XtInputId *xid;
 +DoInputCallback(io,cond,data)
 +     GIOChannel   *io;
 +     GIOCondition  cond;
 +     gpointer *data;
  {
 -    InputSource *is = (InputSource *) closure;
 -    int count;
 -    int error;
 -    char *p, *q;
 -
 -    if (is->lineByLine) {
 -      count = read(is->fd, is->unused,
 -                   INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));
 -      if (count <= 0) {
 -          (is->func)(is, is->closure, is->buf, count, count ? errno : 0);
 -          return;
 +  /* read input from one of the input source (for example a chess program, ICS, etc).
 +   * and call a function that will handle the input
 +   */
 +
 +  int count; /* how many bytes did we read */
 +  int error; 
 +  char *p, *q;
 +  
 +  /* All information (callback function, file descriptor, etc) is
 +   * saved in an InputSource structure 
 +   */
 +  InputSource *is = (InputSource *) data; 
 +  
 +  if (is->lineByLine) 
 +    {
 +      count = read(is->fd, is->unused,
 +                 INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));
 +
 +      if (count <= 0) 
 +      {
 +        (is->func)(is, is->closure, is->buf, count, count ? errno : 0);
 +        return;
        }
 -      is->unused += count;
 -      p = is->buf;
 -      while (p < is->unused) {
 -          q = memchr(p, '\n', is->unused - p);
 -          if (q == NULL) break;
 -          q++;
 -          (is->func)(is, is->closure, p, q - p, 0);
 -          p = q;
 +      is->unused += count;
 +      p = is->buf;
 +      /* break input into lines and call the callback function on each
 +       * line 
 +       */
 +      while (p < is->unused) 
 +      {
 +        q = memchr(p, '\n', is->unused - p);
 +        if (q == NULL) break;
 +        q++;
 +        (is->func)(is, is->closure, p, q - p, 0);
 +        p = q;
        }
 -      q = is->buf;
 -      while (p < is->unused) {
 -          *q++ = *p++;
 +      /* remember not yet used part of the buffer */
 +      q = is->buf;
 +      while (p < is->unused) 
 +      {
 +        *q++ = *p++;
        }
 -      is->unused = q;
 -    } else {
 -      count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
 -      if (count == -1)
 -        error = errno;
 -      else
 -        error = 0;
 -      (is->func)(is, is->closure, is->buf, count, error);
 +      is->unused = q;
      }
 +  else 
 +    {
 +      /* read maximum length of input buffer and send the whole buffer
 +       * to the callback function 
 +       */
 +      count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
 +      if (count == -1)
 +      error = errno;
 +      else
 +      error = 0;
 +      (is->func)(is, is->closure, is->buf, count, error);
 +    }
 +  
 +  return;
  }
  
  InputSourceRef AddInputSource(pr, lineByLine, func, closure)
       VOIDSTAR closure;
  {
      InputSource *is;
 +    GIOChannel *channel;
      ChildProc *cp = (ChildProc *) pr;
  
      is = (InputSource *) calloc(1, sizeof(InputSource));
        is->kind = cp->kind;
        is->fd = cp->fdFrom;
      }
 -    if (lineByLine) {
 -      is->unused = is->buf;
 -    }
 +    if (lineByLine) 
 +      is->unused = is->buf;
 +    else
 +      is->unused = NULL;
  
 -    is->xid = XtAppAddInput(appContext, is->fd,
 -                          (XtPointer) (XtInputReadMask),
 -                          (XtInputCallbackProc) DoInputCallback,
 -                          (XtPointer) is);
 +//    is->xid = XtAppAddInput(appContext, is->fd,
 +//                        (XtPointer) (XtInputReadMask),
 +//                        (XtInputCallbackProc) DoInputCallback,
 +//                        (XtPointer) is);
 +//
 +
 +    /* TODO: will this work on windows?*/
 +
 +    channel = g_io_channel_unix_new(is->fd);
 +    g_io_channel_set_close_on_unref (channel, TRUE);
 +    is->sid = g_io_add_watch(channel, G_IO_IN,(GIOFunc) DoInputCallback, is);
      is->closure = closure;
      return (InputSourceRef) is;
  }
@@@ -5397,10 -7927,9 +5461,10 @@@ RemoveInputSource(isr
  {
      InputSource *is = (InputSource *) isr;
  
 -    if (is->xid == 0) return;
 -    XtRemoveInput(is->xid);
 -    is->xid = 0;
 +    if (is->sid == 0) return;
 +    g_source_remove(is->sid);
 +    is->sid = 0;
 +    return;
  }
  
  int OutputToProcess(pr, message, count, outError)
@@@ -5508,75 -8037,72 +5572,75 @@@ CreateAnimMasks (pieceDepth
    unsigned long       plane;
    XGCValues   values;
  
 +  /* just return for gtk at the moment */
 +  return;
 +
    /* Need a bitmap just to get a GC with right depth */
 -  buf = XCreatePixmap(xDisplay, xBoardWindow,
 -                      8, 8, 1);
 +//  buf = XCreatePixmap(xDisplay, xBoardWindow,
 +//                    8, 8, 1);
    values.foreground = 1;
    values.background = 0;
    /* Don't use XtGetGC, not read only */
 -  maskGC = XCreateGC(xDisplay, buf,
 -                  GCForeground | GCBackground, &values);
 -  XFreePixmap(xDisplay, buf);
 -
 -  buf = XCreatePixmap(xDisplay, xBoardWindow,
 -                    squareSize, squareSize, pieceDepth);
 -  values.foreground = XBlackPixel(xDisplay, xScreen);
 -  values.background = XWhitePixel(xDisplay, xScreen);
 -  bufGC = XCreateGC(xDisplay, buf,
 -                  GCForeground | GCBackground, &values);
 -
 +//  maskGC = XCreateGC(xDisplay, buf,
 +//                GCForeground | GCBackground, &values);
 +//  XFreePixmap(xDisplay, buf);
 +//
 +//  buf = XCreatePixmap(xDisplay, xBoardWindow,
 +//                  squareSize, squareSize, pieceDepth);
 +//  values.foreground = XBlackPixel(xDisplay, xScreen);
 +//  values.background = XWhitePixel(xDisplay, xScreen);
 +//  bufGC = XCreateGC(xDisplay, buf,
 +//                GCForeground | GCBackground, &values);
 +//
    for (piece = WhitePawn; piece <= BlackKing; piece++) {
      /* Begin with empty mask */
 -    if(!xpmDone) // [HGM] pieces: keep using existing
 -    xpmMask[piece] = XCreatePixmap(xDisplay, xBoardWindow,
 -                               squareSize, squareSize, 1);
 -    XSetFunction(xDisplay, maskGC, GXclear);
 -    XFillRectangle(xDisplay, xpmMask[piece], maskGC,
 -                 0, 0, squareSize, squareSize);
 -
 +//    if(!xpmDone) // [HGM] pieces: keep using existing
 +//    xpmMask[piece] = XCreatePixmap(xDisplay, xBoardWindow,
 +//                             squareSize, squareSize, 1);
 +//    XSetFunction(xDisplay, maskGC, GXclear);
 +//    XFillRectangle(xDisplay, xpmMask[piece], maskGC,
 +//               0, 0, squareSize, squareSize);
 +//
      /* Take a copy of the piece */
      if (White(piece))
        kind = 0;
      else
        kind = 2;
 -    XSetFunction(xDisplay, bufGC, GXcopy);
 -    XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
 -            buf, bufGC,
 -            0, 0, squareSize, squareSize, 0, 0);
 +//    XSetFunction(xDisplay, bufGC, GXcopy);
 +//    XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
 +//          buf, bufGC,
 +//          0, 0, squareSize, squareSize, 0, 0);
  
      /* XOR the background (light) over the piece */
 -    XSetFunction(xDisplay, bufGC, GXxor);
 -    if (useImageSqs)
 -      XCopyArea(xDisplay, xpmLightSquare, buf, bufGC,
 -              0, 0, squareSize, squareSize, 0, 0);
 -    else {
 -      XSetForeground(xDisplay, bufGC, lightSquareColor);
 -      XFillRectangle(xDisplay, buf, bufGC, 0, 0, squareSize, squareSize);
 -    }
 +//    XSetFunction(xDisplay, bufGC, GXxor);
 +//    if (useImageSqs)
 +//      XCopyArea(xDisplay, xpmLightSquare, buf, bufGC,
 +//            0, 0, squareSize, squareSize, 0, 0);
 +//    else {
 +//      XSetForeground(xDisplay, bufGC, lightSquareColor);
 +//      XFillRectangle(xDisplay, buf, bufGC, 0, 0, squareSize, squareSize);
 +//    }
  
      /* We now have an inverted piece image with the background
         erased. Construct mask by just selecting all the non-zero
         pixels - no need to reconstruct the original image.    */
 -    XSetFunction(xDisplay, maskGC, GXor);
 +    //    XSetFunction(xDisplay, maskGC, GXor);
      plane = 1;
      /* Might be quicker to download an XImage and create bitmap
         data from it rather than this N copies per piece, but it
         only takes a fraction of a second and there is a much
         longer delay for loading the pieces.           */
 -    for (n = 0; n < pieceDepth; n ++) {
 -      XCopyPlane(xDisplay, buf, xpmMask[piece], maskGC,
 -               0, 0, squareSize, squareSize,
 -               0, 0, plane);
 -      plane = plane << 1;
 -    }
 +//    for (n = 0; n < pieceDepth; n ++) {
 +//      XCopyPlane(xDisplay, buf, xpmMask[piece], maskGC,
 +//             0, 0, squareSize, squareSize,
 +//             0, 0, plane);
 +//      plane = plane << 1;
 +//    }
    }
    /* Clean up */
 -  XFreePixmap(xDisplay, buf);
 -  XFreeGC(xDisplay, bufGC);
 -  XFreeGC(xDisplay, maskGC);
 +//  XFreePixmap(xDisplay, buf);
 +//  XFreeGC(xDisplay, bufGC);
 +//  XFreeGC(xDisplay, maskGC);
  }
  
  static void
@@@ -5588,27 -8114,27 +5652,27 @@@ InitAnimState (anim, info
    XGCValues values;
  
    /* Each buffer is square size, same depth as window */
 -  anim->saveBuf = XCreatePixmap(xDisplay, xBoardWindow,
 -                      squareSize, squareSize, info->depth);
 -  anim->newBuf = XCreatePixmap(xDisplay, xBoardWindow,
 -                      squareSize, squareSize, info->depth);
 -
 -  /* Create a plain GC for blitting */
 -  mask = GCForeground | GCBackground | GCFunction |
 -         GCPlaneMask | GCGraphicsExposures;
 -  values.foreground = XBlackPixel(xDisplay, xScreen);
 -  values.background = XWhitePixel(xDisplay, xScreen);
 -  values.function   = GXcopy;
 -  values.plane_mask = AllPlanes;
 -  values.graphics_exposures = False;
 -  anim->blitGC = XCreateGC(xDisplay, xBoardWindow, mask, &values);
 -
 -  /* Piece will be copied from an existing context at
 -     the start of each new animation/drag. */
 -  anim->pieceGC = XCreateGC(xDisplay, xBoardWindow, 0, &values);
 -
 -  /* Outline will be a read-only copy of an existing */
 -  anim->outlineGC = None;
 +//  anim->saveBuf = XCreatePixmap(xDisplay, xBoardWindow,
 +//                    squareSize, squareSize, info->depth);
 +//  anim->newBuf = XCreatePixmap(xDisplay, xBoardWindow,
 +//                    squareSize, squareSize, info->depth);
 +//
 +//  /* Create a plain GC for blitting */
 +//  mask = GCForeground | GCBackground | GCFunction |
 +//         GCPlaneMask | GCGraphicsExposures;
 +//  values.foreground = XBlackPixel(xDisplay, xScreen);
 +//  values.background = XWhitePixel(xDisplay, xScreen);
 +//  values.function   = GXcopy;
 +//  values.plane_mask = AllPlanes;
 +//  values.graphics_exposures = False;
 +//  anim->blitGC = XCreateGC(xDisplay, xBoardWindow, mask, &values);
 +//
 +//  /* Piece will be copied from an existing context at
 +//     the start of each new animation/drag. */
 +//  anim->pieceGC = XCreateGC(xDisplay, xBoardWindow, 0, &values);
 +//
 +//  /* Outline will be a read-only copy of an existing */
 +//  anim->outlineGC = None;
  }
  
  static void
@@@ -5617,19 -8143,16 +5681,19 @@@ CreateAnimVars (
    static VariantClass old = (VariantClass) -1; // [HGM] pieces: redo every time variant changes
    XWindowAttributes info;
  
 +  /* for gtk at the moment just ... */
 +  return;
 +
    if (xpmDone && gameInfo.variant == old) return;
    if(xpmDone) old = gameInfo.variant; // first time pieces might not be created yet
 -  XGetWindowAttributes(xDisplay, xBoardWindow, &info);
 +  //  XGetWindowAttributes(xDisplay, xBoardWindow, &info);
  
 -  InitAnimState(&game, &info);
 -  InitAnimState(&player, &info);
 +  //  InitAnimState(&game, &info);
 +  //  InitAnimState(&player, &info);
  
    /* For XPM pieces, we need bitmaps to use as masks. */
 -  if (useImages)
 -    CreateAnimMasks(info.depth);
 +  //  if (useImages)
 +  //    CreateAnimMasks(info.depth);
     xpmDone = 1;
  }
  
@@@ -5674,7 -8197,7 +5738,7 @@@ static voi
  FrameDelay (time)
       int time;
  {
 -  XSync(xDisplay, False);
 +  //  XSync(xDisplay, False);
    if (time > 0)
      usleep(time * 1000);
  }
@@@ -5870,7 -8393,7 +5934,7 @@@ SelectGCMask(piece, clip, outline, mask
      else
        source = blPieceGC;
    }
 -  XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
 +  //  XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
  
    /* Outline only used in mono mode and is not modified */
    if (White(piece))
@@@ -5887,25 -8410,23 +5951,25 @@@ OverlayPiece(piece, clip, outline,  des
  
    if (!useImages) {
      /* Draw solid rectangle which will be clipped to shape of piece */
 -    XFillRectangle(xDisplay, dest, clip,
 -                 0, 0, squareSize, squareSize);
 +//    XFillRectangle(xDisplay, dest, clip,
 +//               0, 0, squareSize, squareSize)
 +;
      if (appData.monoMode)
        /* Also draw outline in contrasting color for black
         on black / white on white cases                */
 -      XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
 -               0, 0, squareSize, squareSize, 0, 0, 1);
 +//      XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
 +//             0, 0, squareSize, squareSize, 0, 0, 1)
 +;
    } else {
      /* Copy the piece */
      if (White(piece))
        kind = 0;
      else
        kind = 2;
 -    XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
 -            dest, clip,
 -            0, 0, squareSize, squareSize,
 -            0, 0);
 +//    XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
 +//          dest, clip,
 +//          0, 0, squareSize, squareSize,
 +//          0, 0);
    }
  }
  
@@@ -5925,8 -8446,8 +5989,8 @@@ BeginAnimation(anim, piece, startColor
    anim->prevFrame = *start;
  
    /* The piece will be drawn using its own bitmap as a matte  */
 -  SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask);
 -  XSetClipMask(xDisplay, anim->pieceGC, mask);
 +//  SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask);
 +//  XSetClipMask(xDisplay, anim->pieceGC, mask);
  }
  
  static void
@@@ -5941,46 -8462,45 +6005,46 @@@ AnimationFrame(anim, frame, piece
    int      count, i;
  
    /* Save what we are about to draw into the new buffer */
 -  XCopyArea(xDisplay, xBoardWindow, anim->newBuf, anim->blitGC,
 -          frame->x, frame->y, squareSize, squareSize,
 -          0, 0);
 +//  XCopyArea(xDisplay, xBoardWindow, anim->newBuf, anim->blitGC,
 +//        frame->x, frame->y, squareSize, squareSize,
 +//        0, 0);
  
    /* Erase bits of the previous frame */
    if (Intersect(&anim->prevFrame, frame, squareSize, &overlap, &pt)) {
      /* Where the new frame overlapped the previous,
         the contents in newBuf are wrong. */
 -    XCopyArea(xDisplay, anim->saveBuf, anim->newBuf, anim->blitGC,
 -            overlap.x, overlap.y,
 -            overlap.width, overlap.height,
 -            pt.x, pt.y);
 +//    XCopyArea(xDisplay, anim->saveBuf, anim->newBuf, anim->blitGC,
 +//          overlap.x, overlap.y,
 +//          overlap.width, overlap.height,
 +//          pt.x, pt.y);
      /* Repaint the areas in the old that don't overlap new */
      CalcUpdateRects(&anim->prevFrame, frame, squareSize, updates, &count);
      for (i = 0; i < count; i++)
 -      XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
 -              updates[i].x - anim->prevFrame.x,
 -              updates[i].y - anim->prevFrame.y,
 -              updates[i].width, updates[i].height,
 -              updates[i].x, updates[i].y);
 +//      XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
 +//            updates[i].x - anim->prevFrame.x,
 +//            updates[i].y - anim->prevFrame.y,
 +//            updates[i].width, updates[i].height,
 +//            updates[i].x, updates[i].y)
 +;
    } else {
      /* Easy when no overlap */
 -    XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
 -                0, 0, squareSize, squareSize,
 -                anim->prevFrame.x, anim->prevFrame.y);
 +//    XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
 +//              0, 0, squareSize, squareSize,
 +//              anim->prevFrame.x, anim->prevFrame.y);
    }
  
    /* Save this frame for next time round */
 -  XCopyArea(xDisplay, anim->newBuf, anim->saveBuf, anim->blitGC,
 -              0, 0, squareSize, squareSize,
 -              0, 0);
 +//  XCopyArea(xDisplay, anim->newBuf, anim->saveBuf, anim->blitGC,
 +//            0, 0, squareSize, squareSize,
 +//            0, 0);
    anim->prevFrame = *frame;
  
    /* Draw piece over original screen contents, not current,
       and copy entire rect. Wipes out overlapping piece images. */
    OverlayPiece(piece, anim->pieceGC, anim->outlineGC, anim->newBuf);
 -  XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC,
 -              0, 0, squareSize, squareSize,
 -              frame->x, frame->y);
 +//  XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC,
 +//            0, 0, squareSize, squareSize,
 +//            frame->x, frame->y);
  }
  
  static void
@@@ -5998,16 -8518,15 +6062,16 @@@ EndAnimation (anim, finish
    if (Intersect(&anim->prevFrame, finish, squareSize, &overlap, &pt)) {
      CalcUpdateRects(&anim->prevFrame, finish, squareSize, updates, &count);
      for (i = 0; i < count; i++)
 -      XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
 -              updates[i].x - anim->prevFrame.x,
 -              updates[i].y - anim->prevFrame.y,
 -              updates[i].width, updates[i].height,
 -              updates[i].x, updates[i].y);
 +//      XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
 +//            updates[i].x - anim->prevFrame.x,
 +//            updates[i].y - anim->prevFrame.y,
 +//            updates[i].width, updates[i].height,
 +//            updates[i].x, updates[i].y)
 +;
    } else {
 -    XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
 -              0, 0, squareSize, squareSize,
 -              anim->prevFrame.x, anim->prevFrame.y);
 +//    XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
 +//            0, 0, squareSize, squareSize,
 +//            anim->prevFrame.x, anim->prevFrame.y);
    }
  }
  
@@@ -6048,8 -8567,8 +6112,8 @@@ AnimateMove(board, fromX, fromY, toX, t
    if (!appData.animate || appData.blindfold)
      return;
  
 -  if(board[toY][toX] == WhiteRook && board[fromY][fromX] == WhiteKing || 
 -     board[toY][toX] == BlackRook && board[fromY][fromX] == BlackKing) 
 +  if(board[toY][toX] == WhiteRook && board[fromY][fromX] == WhiteKing ||
 +     board[toY][toX] == BlackRook && board[fromY][fromX] == BlackKing)
        return; // [HGM] FRC: no animtion of FRC castlings, as to-square is not true to-square
  
    if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return;
@@@ -6129,9 -8648,9 +6193,9 @@@ DragPieceBegin(x, y
           as seen by opponent) the move hasn't been made yet. */
             if(boardX == BOARD_RGHT+1 && PieceForSquare(boardX-1, boardY) > 1 ||
                boardX == BOARD_LEFT-2 && PieceForSquare(boardX+1, boardY) > 1)
 -           XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC,
 -                   corner.x, corner.y, squareSize, squareSize,
 -                   0, 0); // [HGM] zh: unstack in stead of grab
 +//           XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC,
 +//                 corner.x, corner.y, squareSize, squareSize,
 +//                 0, 0); // [HGM] zh: unstack in stead of grab
        damage[boardY][boardX] = True;
      } else {
        player.dragActive = False;
diff --combined xgamelist.c
@@@ -22,7 -22,6 +22,7 @@@
  
  #include "config.h"
  
 +#include <gtk/gtk.h>
  #include <stdio.h>
  #include <ctype.h>
  #include <errno.h>
@@@ -91,18 -90,30 +91,32 @@@ extern char *getenv()
  # define N_(s)  s
  #endif
  
 +extern GtkWidget               *GUI_GameList;
 +extern GtkListStore            *LIST_GameList;
  
+ void SetFocus P((Widget w, XtPointer data, XEvent *event, Boolean *b));
+ extern Widget formWidget, shellWidget, boardWidget, menuBarWidget, gameListShell;
 -extern Display *xDisplay;
 +
- extern Widget formWidget, boardWidget, menuBarWidget, gameListShell;
  extern int squareSize;
  extern Pixmap xMarkPixmap;
  extern char *layoutName;
  
+ static Widget filterText;
+ static char filterString[MSG_SIZ];
+ static int listLength;
  char gameListTranslations[] =
-   "<Btn1Up>(2): LoadSelectedProc() \n \
-    <Key>Return: LoadSelectedProc() \n";
+   "<Btn1Up>(2): LoadSelectedProc(0) \n \
+    <Key>Home: LoadSelectedProc(-2) \n \
+    <Key>End: LoadSelectedProc(2) \n \
+    <Key>Up: LoadSelectedProc(-1) \n \
+    <Key>Down: LoadSelectedProc(1) \n \
+    <Key>Left: LoadSelectedProc(-1) \n \
+    <Key>Right: LoadSelectedProc(1) \n \
+    <Key>Return: LoadSelectedProc(0) \n";
+ char filterTranslations[] =
+   "<Key>Return: SetFilterProc() \n";
  
  typedef struct {
      Widget shell;
      char *filename;
      char **strings;
  } GameListClosure;
+ static GameListClosure *glc = NULL;
  
  static Arg layoutArgs[] = {
      { XtNborderWidth, 0 },
@@@ -125,9 -137,236 +140,45 @@@ GameListCreate(name, callback, client_d
       XtCallbackProc callback;
       XtPointer client_data;
  {
 -    Arg args[16];
 -    Widget shell, form, viewport, listwidg, layout, label;
 -    Widget b_load, b_loadprev, b_loadnext, b_close, b_filter;
 -    Dimension fw_width;
 -    int j;
 -    GameListClosure *glc = (GameListClosure *) client_data;
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNwidth, &fw_width);  j++;
 -    XtGetValues(formWidget, args, j);
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNresizable, True);  j++;
 -    XtSetArg(args[j], XtNallowShellResize, True);  j++;
 -#if TOPLEVEL
 -    shell = gameListShell =
 -      XtCreatePopupShell(name, topLevelShellWidgetClass,
 -                       shellWidget, args, j);
 -#else
 -    shell = gameListShell =
 -      XtCreatePopupShell(name, transientShellWidgetClass,
 -                       shellWidget, args, j);
 -#endif
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, shell,
 -                          layoutArgs, XtNumber(layoutArgs));
 -    j = 0;
 -    XtSetArg(args[j], XtNborderWidth, 0); j++;
 -    form =
 -      XtCreateManagedWidget("form", formWidgetClass, layout, args, j);
 -
 -    j = 0;
 -    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, False);  j++;
 -    XtSetArg(args[j], XtNwidth, fw_width);  j++;
 -    XtSetArg(args[j], XtNallowVert, True); j++;
 -    viewport =
 -      XtCreateManagedWidget("viewport", viewportWidgetClass, form, args, j);
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNlist, glc->strings);  j++;
 -    XtSetArg(args[j], XtNdefaultColumns, 1);  j++;
 -    XtSetArg(args[j], XtNforceColumns, True);  j++;
 -    XtSetArg(args[j], XtNverticalList, True);  j++;
 -    listwidg = 
 -      XtCreateManagedWidget("list", listWidgetClass, viewport, args, j);
 -    XawListHighlight(listwidg, 0);
 -    XtAugmentTranslations(listwidg,
 -                        XtParseTranslationTable(gameListTranslations));
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNfromVert, viewport);  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_load =
 -      XtCreateManagedWidget(_("load"), commandWidgetClass, form, args, j);
 -    XtAddCallback(b_load, XtNcallback, callback, client_data);
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNfromVert, viewport);  j++;
 -    XtSetArg(args[j], XtNfromHoriz, b_load);  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_loadprev =
 -      XtCreateManagedWidget(_("prev"), commandWidgetClass, form, args, j);
 -    XtAddCallback(b_loadprev, XtNcallback, callback, client_data);
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNfromVert, viewport);  j++;
 -    XtSetArg(args[j], XtNfromHoriz, b_loadprev);  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_loadnext =
 -      XtCreateManagedWidget(_("next"), commandWidgetClass, form, args, j);
 -    XtAddCallback(b_loadnext, XtNcallback, callback, client_data);
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNfromVert, viewport);  j++;
 -    XtSetArg(args[j], XtNfromHoriz, b_loadnext);  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, client_data);
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNfromVert, viewport);  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++;
 -    XtSetArg(args[j], XtNborderWidth, 0); j++;
 -    label =
 -      XtCreateManagedWidget(_("Filter:"), labelWidgetClass, form, args, j);
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNfromVert, viewport);  j++;
 -    XtSetArg(args[j], XtNfromHoriz, label);  j++;
 -    XtSetArg(args[j], XtNtop, XtChainBottom); j++;
 -    XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
 -    XtSetArg(args[j], XtNleft, XtChainLeft); j++;
 -    XtSetArg(args[j], XtNright, XtChainRight); j++;
 -    XtSetArg(args[j], XtNwidth, fw_width - 225 - squareSize); j++;
 -    XtSetArg(args[j], XtNstring, filterString);  j++;
 -    XtSetArg(args[j], XtNdisplayCaret, False);  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], XtNeditType, XawtextEdit);  j++;
 -    XtSetArg(args[j], XtNuseStringInPlace, False);  j++;
 -    filterText =
 -      XtCreateManagedWidget(_("filtertext"), asciiTextWidgetClass, form, args, j);
 -    XtAddEventHandler(filterText, ButtonPressMask, False, SetFocus, (XtPointer) shell);
 -    XtOverrideTranslations(filterText,
 -                        XtParseTranslationTable(filterTranslations));
 -
 -    j = 0;
 -    XtSetArg(args[j], XtNfromVert, viewport);  j++;
 -    XtSetArg(args[j], XtNfromHoriz, filterText);  j++;
 -    XtSetArg(args[j], XtNtop, XtChainBottom); j++;
 -    XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
 -    XtSetArg(args[j], XtNleft, XtChainRight); j++;
 -    XtSetArg(args[j], XtNright, XtChainRight); j++;
 -    b_filter =
 -      XtCreateManagedWidget(_("apply"), commandWidgetClass, form, args, j);
 -    XtAddCallback(b_filter, XtNcallback, callback, client_data);
 -
 -
 -    if(wpGameList.width > 0) {
 -      glc->x = wpGameList.x;
 -      glc->y = wpGameList.y;
 -      glc->w = wpGameList.width;
 -      glc->h = wpGameList.height;
 -    }
 -
 -    if (glc->x == -1) {
 -      Position y1;
 -      Dimension h1;
 -      int xx, yy;
 -      Window junk;
 -
 -      j = 0;
 -      XtSetArg(args[j], XtNheight, &h1); j++;
 -      XtSetArg(args[j], XtNy, &y1); j++;
 -      XtGetValues(boardWidget, args, j);
 -      glc->w = fw_width * 3/4;
 -      glc->h = squareSize * 3;
 -
 -      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, (fw_width - glc->w) / 2,
 -                        y1 + (h1 - glc->h + appData.borderYoffset) / 2,
 -                        &glc->x, &glc->y);
 -#else /*!NOTDEF*/
 -        XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
 -                            RootWindowOfScreen(XtScreen(shellWidget)),
 -                            (fw_width - glc->w) / 2,
 -                            y1 + (h1 - glc->h + appData.borderYoffset) / 2,
 -                            &xx, &yy, &junk);
 -      glc->x = xx;
 -      glc->y = yy;
 -#endif /*!NOTDEF*/
 -      if (glc->y < 0) glc->y = 0; /*avoid positioning top offscreen*/
 -    }
 -    j = 0;
 -    XtSetArg(args[j], XtNheight, glc->h);  j++;
 -    XtSetArg(args[j], XtNwidth, glc->w);  j++;
 -    XtSetArg(args[j], XtNx, glc->x - appData.borderXoffset);  j++;
 -    XtSetArg(args[j], XtNy, glc->y - appData.borderYoffset);  j++;
 -    XtSetValues(shell, args, j);
 -
 -    XtRealizeWidget(shell);
 -    CatchDeleteWindow(shell, "GameListPopDown");
 -    XtSetKeyboardFocus(shell, listwidg);
 -
 -    return shell;
 +  return;
  }
  
+ static int
+ GameListPrepare()
+ {   // [HGM] filter: put in separate routine, to make callable from call-back
+     int nstrings;
+     ListGame *lg;
+     char **st, *line;
+     nstrings = ((ListGame *) gameList.tailPred)->number;
+     glc->strings = (char **) malloc((nstrings + 1) * sizeof(char *));
+     st = glc->strings;
+     lg = (ListGame *) gameList.head;
+     listLength = 0;
+     while (nstrings--) {
+       line = GameListLine(lg->number, &lg->gameInfo);
+       if(filterString[0] == NULLCHAR || SearchPattern( line, filterString ) ) {
+           *st++ = line; // [HGM] filter: make adding line conditional
+           listLength++;
+       }
+       lg = (ListGame *) lg->node.succ;
+      }
+     *st = NULL;
+     return listLength;
+ }
+ static void
+ GameListReplace()
+ {   // [HGM] filter: put in separate routine, to make callable from call-back
+     Arg args[16];
+     int j;
+     Widget listwidg;
+       listwidg = XtNameToWidget(glc->shell, "*form.viewport.list");
+       XawListChange(listwidg, glc->strings, 0, 0, True);
+       XawListHighlight(listwidg, 0);
+ }
  void
  GameListCallback(w, client_data, call_data)
       Widget w;
        }
      } else if (strcmp(name, _("next")) == 0) {
        index = rs->list_index + 1;
-       if (index >= ((ListGame *) gameList.tailPred)->number) {
+       if (index >= listLength) {
            DisplayError(_("Can't go forward any further"), 0);
            return;
        }
            return;
        }
        XawListHighlight(listwidg, index);
+     } else if (strcmp(name, _("apply")) == 0) {
+         String name;
+         j = 0;
+         XtSetArg(args[j], XtNstring, &name);  j++;
+       XtGetValues(filterText, args, j);
+         strcpy(filterString, name);
+       XawListHighlight(listwidg, 0);
+         if(GameListPrepare()) GameListReplace(); // crashes on empty list...
+         return;
      }
+     index = atoi(glc->strings[index])-1; // [HGM] filter: read true index from sequence nr of line
      if (cmailMsgLoaded) {
        CmailLoadGame(glc->fp, index + 1, glc->filename, True);
      } else {
      }
  }
  
- static GameListClosure *glc = NULL;
  void
  GameListPopUp(fp, filename)
       FILE *fp;
       char *filename;
  {
 -    Arg args[16];
 -    int j, nstrings;
 -    Widget listwidg;
 -    ListGame *lg;
 -    char **st;
 -
 -    if (glc == NULL) {
 -      glc = (GameListClosure *) calloc(1, sizeof(GameListClosure));
 -      glc->x = glc->y = -1;
 -    }
 -
 -    if (glc->strings != NULL) {
 -      st = glc->strings;
 -      while (*st) {
 -          free(*st++);
 -      }
 -      free(glc->strings);
 +  GtkTreeIter iter;
 +  int  i=0,nstrings;
 +  ListGame *lg;
 +  
 +  /* first clear everything, do we need this? */
 +  gtk_list_store_clear(LIST_GameList);
 +
 +  /* fill list with information */
 +  lg = (ListGame *) gameList.head;
 +  nstrings = ((ListGame *) gameList.tailPred)->number;
 +  while (nstrings--) 
 +    {
 +      gtk_list_store_append (LIST_GameList, &iter);
 +      gtk_list_store_set (LIST_GameList, &iter,
 +                        0, StrSave(filename),
 +                        1, GameListLine(lg->number, &lg->gameInfo),
 +                        2, fp,
 +                        -1);
 +      lg = (ListGame *) lg->node.succ;
      }
  
 -    GameListPrepare(); // [HGM] filter: code put in separate routine
 -
 -    glc->fp = fp;
 -
 -    if (glc->filename != NULL) free(glc->filename);
 -    glc->filename = StrSave(filename);
 +  /* show widget */
 +  gtk_widget_show (GUI_GameList);
  
 +//    XtPopup(glc->shell, XtGrabNone);
 +//    glc->up = True;
 +//    j = 0;
 +//    XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
 +//    XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Game List"),
 +//            args, j);
  
 -    if (glc->shell == NULL) {
 -      glc->shell = GameListCreate(filename, GameListCallback, glc); 
 -    } else {
 -        GameListReplace(); // [HGM] filter: code put in separate routine
 -      j = 0;
 -      XtSetArg(args[j], XtNiconName, (XtArgVal) filename);  j++;
 -      XtSetArg(args[j], XtNtitle, (XtArgVal) filename);  j++;
 -      XtSetValues(glc->shell, args, j);
 -    }
 -
 -    XtPopup(glc->shell, XtGrabNone);
 -    glc->up = True;
 -    j = 0;
 -    XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Game List"),
 -              args, j);
 +  return;
  }
  
  void
  GameListDestroy()
  {
 -    if (glc == NULL) return;
 -    GameListPopDown();
 -    if (glc->strings != NULL) {
 -      char **st;
 -      st = glc->strings;
 -      while (*st) {
 -          free(*st++);
 -      }
 -      free(glc->strings);
 -    }
 -    free(glc);
 -    glc = NULL;
 +  GameListPopDown();
 +
 +  gtk_list_store_clear(LIST_GameList);
 +  return;
  }
  
  void
@@@ -265,13 -530,22 +323,22 @@@ LoadSelectedProc(w, event, prms, nprms
  {
      Widget listwidg;
      XawListReturnStruct *rs;
-     int index;
+     int index, direction = atoi(prms[0]);
  
      if (glc == NULL) return;
      listwidg = XtNameToWidget(glc->shell, "*form.viewport.list");
      rs = XawListShowCurrent(listwidg);
      index = rs->list_index;
      if (index < 0) return;
+     if(direction != 0) {
+       index += direction; 
+       if(direction == -2) index = 0;
+       if(direction == 2) index = listLength-1;
+       if(index < 0 || index >= listLength) return;
+       XawListHighlight(listwidg, index);
+       return;
+     }
+     index = atoi(glc->strings[index])-1; // [HGM] filter: read true index from sequence nr of line
      if (cmailMsgLoaded) {
        CmailLoadGame(glc->fp, index + 1, glc->filename, True);
      } else {
  }
  
  void
+ SetFilterProc(w, event, prms, nprms)
+      Widget w;
+      XEvent *event;
+      String *prms;
+      Cardinal *nprms;
+ {
+       Arg args[16];
+         String name;
+       Widget list;
+         int j = 0;
+         XtSetArg(args[j], XtNstring, &name);  j++;
+       XtGetValues(filterText, args, j);
+         strcpy(filterString, name);
+         if(GameListPrepare()) GameListReplace(); // crashes on empty list...
+       list = XtNameToWidget(glc->shell, "*form.viewport.list");
+       XawListHighlight(list, 0);
+         j = 0;
+       XtSetArg(args[j], XtNdisplayCaret, False); j++;
+       XtSetValues(filterText, args, j);
+       XtSetKeyboardFocus(glc->shell, list);
+ }
+ void
  GameListPopDown()
  {
 -    Arg args[16];
 -    int j;
 +  /* hides the history window */
  
 -    if (glc == NULL) return;
 -    j = 0;
 -    XtSetArg(args[j], XtNx, &glc->x); j++;
 -    XtSetArg(args[j], XtNy, &glc->y); j++;
 -    XtSetArg(args[j], XtNheight, &glc->h); j++;
 -    XtSetArg(args[j], XtNwidth, &glc->w); j++;
 -    XtGetValues(glc->shell, args, j);
 -    wpGameList.x = glc->x - 4;
 -    wpGameList.y = glc->y - 23;
 -    wpGameList.width = glc->w;
 -    wpGameList.height = glc->h;
 -    XtPopdown(glc->shell);
 -    XtSetKeyboardFocus(shellWidget, formWidget);
 -    glc->up = False;
 -    j = 0;
 -    XtSetArg(args[j], XtNleftBitmap, None); j++;
 -    XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Game List"),
 -              args, j);
 +  gtk_widget_hide (GUI_GameList);
 +  return;
  }
  
  void
@@@ -293,15 -607,229 +383,231 @@@ GameListHighlight(index
       int index;
  {
      Widget listwidg;
+     int i=0; char **st;
      if (glc == NULL || !glc->up) return;
      listwidg = XtNameToWidget(glc->shell, "*form.viewport.list");
-     XawListHighlight(listwidg, index - 1);
+     st = glc->strings;
+     while(*st && atoi(*st)<index) st++,i++;
+     XawListHighlight(listwidg, i);
  }
  
  Boolean
  GameListIsUp()
  {
 -    return glc && glc->up;
 +  /* return status of history window */
 +  
 +  return gtk_widget_get_visible (GUI_GameList);
  }
+ //--------------------------------- Game-List options dialog ------------------------------------------
+ Widget gameListOptShell, listwidg;
+ char *strings[20];
+ int stringPtr;
+ void GLT_ClearList()
+ {
+     strings[0] = NULL;
+     stringPtr = 0;
+ }
+ void GLT_AddToList(char *name)
+ {
+     strings[stringPtr++] = name;
+     strings[stringPtr] = NULL;
+ }
+ Boolean GLT_GetFromList(int index, char *name)
+ {
+     strcpy(name, strings[index]);
+ }
+ void GLT_DeSelectList()
+ {
+     XawListChange(listwidg, strings, 0, 0, True);
+     XawListHighlight(listwidg, 0);
+ }
+ void
+ GameListOptionsPopDown()
+ {
+     Arg args[16];
+     int j;
+     if (gameListOptShell == NULL) return;
+     XtPopdown(gameListOptShell);
+     XtDestroyWidget(gameListOptShell);
+     gameListOptShell = 0;
+     XtSetKeyboardFocus(shellWidget, formWidget);
+ }
+ void
+ GameListOptionsCallback(w, client_data, call_data)
+      Widget w;
+      XtPointer client_data, call_data;
+ {
+     String name;
+     Arg args[16];
+     int j;
+     Widget listwidg;
+     XawListReturnStruct *rs;
+     int index;
+     char *p;
+     j = 0;
+     XtSetArg(args[j], XtNlabel, &name);  j++;
+     XtGetValues(w, args, j);
+     if (strcmp(name, _("OK")) == 0) {
+       GLT_ParseList();
+       appData.gameListTags = strdup(lpUserGLT);
+       GameListOptionsPopDown();
+       return;
+     } else
+     if (strcmp(name, _("cancel")) == 0) {
+       GameListOptionsPopDown();
+       return;
+     }
+     listwidg = XtNameToWidget(gameListOptShell, "*form.list");
+     rs = XawListShowCurrent(listwidg);
+     index = rs->list_index;
+     if (index < 0) {
+       DisplayError(_("No tag selected"), 0);
+       return;
+     }
+     p = strings[index];
+     if (strcmp(name, _("down")) == 0) {
+         if(index >= strlen(GLT_ALL_TAGS)) return;
+       strings[index] = strings[index+1];
+       strings[++index] = p;
+     } else
+     if (strcmp(name, _("up")) == 0) {
+         if(index == 0) return;
+       strings[index] = strings[index-1];
+       strings[--index] = p;
+     } else
+     if (strcmp(name, _("factory")) == 0) {
+       strcpy(lpUserGLT, GLT_DEFAULT_TAGS);
+       GLT_TagsToList(lpUserGLT);
+       index = 0;
+     }
+     XawListHighlight(listwidg, index);
+ }
+ Widget
+ GameListOptionsCreate()
+ {
+     Arg args[16];
+     Widget shell, form, viewport, layout;
+     Widget b_load, b_loadprev, b_loadnext, b_close, b_cancel;
+     Dimension fw_width;
+     XtPointer client_data = NULL;
+     int j;
+     j = 0;
+     XtSetArg(args[j], XtNwidth, &fw_width);  j++;
+     XtGetValues(formWidget, args, j);
+     j = 0;
+     XtSetArg(args[j], XtNresizable, True);  j++;
+     XtSetArg(args[j], XtNallowShellResize, True);  j++;
+     shell = gameListOptShell =
+       XtCreatePopupShell("Game-list options", transientShellWidgetClass,
+                        shellWidget, args, j);
+     layout =
+       XtCreateManagedWidget(layoutName, formWidgetClass, shell,
+                           layoutArgs, XtNumber(layoutArgs));
+     j = 0;
+     XtSetArg(args[j], XtNborderWidth, 0); j++;
+     form =
+       XtCreateManagedWidget("form", formWidgetClass, layout, args, j);
+     j = 0;
+     XtSetArg(args[j], XtNdefaultColumns, 1);  j++;
+     XtSetArg(args[j], XtNforceColumns, True);  j++;
+     XtSetArg(args[j], XtNverticalList, True);  j++;
+     listwidg = viewport =
+       XtCreateManagedWidget("list", listWidgetClass, form, args, j);
+     XawListHighlight(listwidg, 0);
+ //    XtAugmentTranslations(listwidg,
+ //                      XtParseTranslationTable(gameListOptTranslations));
+     j = 0;
+     XtSetArg(args[j], XtNfromVert, viewport);  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_load =
+       XtCreateManagedWidget(_("factory"), commandWidgetClass, form, args, j);
+     XtAddCallback(b_load, XtNcallback, GameListOptionsCallback, client_data);
+     j = 0;
+     XtSetArg(args[j], XtNfromVert, viewport);  j++;
+     XtSetArg(args[j], XtNfromHoriz, b_load);  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_loadprev =
+       XtCreateManagedWidget(_("up"), commandWidgetClass, form, args, j);
+     XtAddCallback(b_loadprev, XtNcallback, GameListOptionsCallback, client_data);
+     j = 0;
+     XtSetArg(args[j], XtNfromVert, viewport);  j++;
+     XtSetArg(args[j], XtNfromHoriz, b_loadprev);  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_loadnext =
+       XtCreateManagedWidget(_("down"), commandWidgetClass, form, args, j);
+     XtAddCallback(b_loadnext, XtNcallback, GameListOptionsCallback, client_data);
+     j = 0;
+     XtSetArg(args[j], XtNfromVert, viewport);  j++;
+     XtSetArg(args[j], XtNfromHoriz, b_loadnext);  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, GameListOptionsCallback, client_data);
+     j = 0;
+     XtSetArg(args[j], XtNfromVert, viewport);  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_close =
+       XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j);
+     XtAddCallback(b_close, XtNcallback, GameListOptionsCallback, client_data);
+     strcpy(lpUserGLT, appData.gameListTags);
+     GLT_TagsToList(lpUserGLT);
+     XtRealizeWidget(shell);
+     CatchDeleteWindow(shell, "GameListOptionsPopDown");
+     return shell;
+ }
+ void
+ GameListOptionsPopUp(Widget w, XEvent *event, String *prms, Cardinal *nprms)
+ {
+     Arg args[16];
+     int j, nstrings;
+     Widget listwidg;
+     if (gameListOptShell == NULL) {
+       gameListOptShell = GameListOptionsCreate(); 
+     }
+     XtPopup(gameListOptShell, XtGrabNone);
+ }
diff --combined xoptions.c
@@@ -81,13 -81,15 +81,14 @@@ extern char *getenv()
  
  extern void SendToProgram P((char *message, ChessProgramState *cps));
  
 -extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
 -extern Display *xDisplay;
 +extern Widget formWidget,  boardWidget, menuBarWidget;
  extern int squareSize;
  extern Pixmap xMarkPixmap;
  extern char *layoutName;
  extern Window xBoardWindow;
  extern Arg layoutArgs[2], formArgs[2];
  Pixel timerForegroundPixel, timerBackgroundPixel;
+ extern int searchTime;
  
  // [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines
  
@@@ -180,14 -182,14 +181,14 @@@ void ShufflePopUp(
      i = 0;
      XtSetArg(args[i], XtNresizable, True); i++;
      XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
 -    shuffleShell = popup =
 -      XtCreatePopupShell(_("New Shuffle Game"), transientShellWidgetClass,
 -                       shellWidget, args, i);
 -    
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 -                          layoutArgs, XtNumber(layoutArgs));
 -  
 +//    shuffleShell = popup =
 +//      XtCreatePopupShell(_("New Shuffle Game"), transientShellWidgetClass,
 +//                     shellWidget, args, i);
 +//    
 +//    layout =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 +//                        layoutArgs, XtNumber(layoutArgs));
 +//  
      sprintf(def, "%d\n", appData.defaultFrcPosition);
      i = 0;
      XtSetArg(args[i], XtNlabel, _("Start-position number:")); i++;
      XawDialogAddButton(dialog, _("off"), ShuffleCallback, (XtPointer) dialog);
      
      XtRealizeWidget(popup);
 -    CatchDeleteWindow(popup, "ShufflePopDown");
 +    //    CatchDeleteWindow(popup, "ShufflePopDown");
      
 -    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 -                &x, &y, &win_x, &win_y, &mask);
 +//    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 +//              &x, &y, &win_x, &win_y, &mask);
      
      XtSetArg(args[0], XtNx, x - 10);
      XtSetArg(args[1], XtNy, y - 30);
@@@ -266,54 -268,77 +267,77 @@@ void TimeControlCallback(w, client_data
      XtGetValues(w, args, 1);
      
      if (strcmp(name, _("classical")) == 0) {
-       if(!tcInc) return;
+       if(tcInc == 0) return;
        j=0;
        XtSetArg(args[j], XtNlabel, _("minutes for each")); j++;
        XtSetValues(tcMess1, args, j);
        j=0;
        XtSetArg(args[j], XtNlabel, _("moves")); j++;
        XtSetValues(tcMess2, args, j);
-       j=0;
-       XtSetArg(args[j], XtNstring, &name); j++;
-       XtGetValues(tcData, args, j);
-       tcIncrement = 0; sscanf(name, "%d", &tcIncrement);
+       if(tcInc == 1) {
+           j=0;
+           XtSetArg(args[j], XtNstring, &name); j++;
+           XtGetValues(tcData, args, j);
+           tcIncrement = 0; sscanf(name, "%d", &tcIncrement);
+       }
        sprintf(buf, "%d", tcMoves);
        j=0;
        XtSetArg(args[j], XtNstring, buf); j++;
        XtSetValues(tcData, args, j);
-       tcInc = False;
+       tcInc = 0;
          return;
      }
      if (strcmp(name, _("incremental")) == 0) {
-       if(tcInc) return;
+       if(tcInc == 1) return;
        j=0;
        XtSetArg(args[j], XtNlabel, _("minutes, plus")); j++;
        XtSetValues(tcMess1, args, j);
        j=0;
        XtSetArg(args[j], XtNlabel, _("sec/move")); j++;
        XtSetValues(tcMess2, args, j);
-       j=0;
-       XtSetArg(args[j], XtNstring, &name); j++;
-       XtGetValues(tcData, args, j);
-       tcMoves = appData.movesPerSession; sscanf(name, "%d", &tcMoves);
+       if(tcInc == 0) {
+           j=0;
+           XtSetArg(args[j], XtNstring, &name); j++;
+           XtGetValues(tcData, args, j);
+           tcMoves = appData.movesPerSession; sscanf(name, "%d", &tcMoves);
+       }
        sprintf(buf, "%d", tcIncrement);
        j=0;
        XtSetArg(args[j], XtNstring, buf); j++;
        XtSetValues(tcData, args, j);
-       tcInc = True;
+       tcInc = 1;
+         return;
+     }
+     if (strcmp(name, _("fixed time")) == 0) {
+       if(tcInc == 2) return;
+       j=0;
+       XtSetArg(args[j], XtNlabel, _("sec/move (max)")); j++;
+       XtSetValues(tcMess1, args, j);
+       j=0;
+       XtSetArg(args[j], XtNlabel, _("")); j++;
+       XtSetValues(tcMess2, args, j);
+       j=0;
+       XtSetArg(args[j], XtNstring, ""); j++;
+       XtSetValues(tcData, args, j);
+       tcInc = 2;
          return;
      }
      if (strcmp(name, _(" OK ")) == 0) {
        int inc, mps, tc, ok;
        XtSetArg(args[0], XtNstring, &txt);
        XtGetValues(tcData, args, 1);
-       if(tcInc) {
+       switch(tcInc) {
+         case 1:
            ok = sscanf(txt, "%d", &inc); mps = 0;
            if(!ok && txt[0] == 0) { inc = 0; ok = 1; } // accept empty string as zero
            ok &= (inc >= 0);
-       } else {
+           break;
+         case 0:
            ok = sscanf(txt, "%d", &mps); inc = -1;
            ok &= (mps > 0);
+           break;
+         case 2:
+           ok = 1; inc = -1; mps = 40;
        }
        if(ok != 1) {
            XtSetArg(args[0], XtNstring, ""); // erase any offending input
        }
        XtSetArg(args[0], XtNstring, &txt);
        XtGetValues(tcTime, args, 1);
-       if(!ParseTimeControl(txt, inc, mps)) {
-           XtSetArg(args[0], XtNstring, ""); // erase any offending input
-           XtSetValues(tcTime, args, 1);
-           DisplayError(_("Bad Time-Control String"), 0);
-           return;
+       if(tcInc == 2) {
+           if(sscanf(txt, "%d", &inc) != 1) {
+               XtSetArg(args[0], XtNstring, ""); // erase any offending input
+               XtSetValues(tcTime, args, 1);
+               DisplayError(_("Bad Time-Control String"), 0);
+               return;
+           }
+           searchTime = inc;
+       } else {
+           if(!ParseTimeControl(txt, inc, mps)) {
+               XtSetArg(args[0], XtNstring, ""); // erase any offending input
+               XtSetValues(tcTime, args, 1);
+               DisplayError(_("Bad Time-Control String"), 0);
+               return;
+           }
+           searchTime = 0;
+           appData.movesPerSession = mps;
+           appData.timeIncrement = inc;
+           appData.timeControl = strdup(txt);
        }
-       appData.movesPerSession = mps;
-       appData.timeIncrement = inc;
-       appData.timeControl = strdup(txt);
        XtSetArg(args[0], XtNstring, &txt);
        XtGetValues(tcOdds1, args, 1);
        appData.firstTimeOdds = first.timeOdds 
@@@ -355,7 -391,7 +390,7 @@@ void TimeControlPopUp(
      unsigned int mask;
      char def[80];
      
-     tcInc = (appData.timeIncrement >= 0);
+     tcInc = searchTime > 0 ? 2 : (appData.timeIncrement >= 0);
      tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement;
      if(!tcInc) tcIncrement = 0;
      sprintf(def, "%d", tcInc ? tcIncrement : tcMoves);
      i = 0;
      XtSetArg(args[i], XtNresizable, True); i++;
  //    XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
 -    TimeControlShell = popup =
 -      XtCreatePopupShell(_("TimeControl Menu"), transientShellWidgetClass,
 -                       shellWidget, args, i);
 -    
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 -                          layoutArgs, XtNumber(layoutArgs));
 -  
 -    form =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, layout,
 -                          formArgs, XtNumber(formArgs));
 -  
 +//    TimeControlShell = popup =
 +//      XtCreatePopupShell(_("TimeControl Menu"), transientShellWidgetClass,
 +//                     shellWidget, args, i);
 +//    
 +//    layout =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 +//                        layoutArgs, XtNumber(layoutArgs));
 +//  
 +//    form =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, layout,
 +//                        formArgs, XtNumber(formArgs));
 +//  
      j = 0;
  //    XtSetArg(args[j], XtNwidth,     (XtArgVal) 300); j++;
  //    XtSetArg(args[j], XtNheight,    (XtArgVal) 85); j++;
      XtAddEventHandler(tcTime, ButtonPressMask, False, SetFocus, (XtPointer) popup);
  
      j= 0;
-     XtSetArg(args[j], XtNlabel, tcInc ? _("   minutes, plus   ") : _("minutes for each")); j++;
+     XtSetArg(args[j], XtNlabel, tcInc ? tcInc == 2 ? _("sec/move (max)   ") : _("   minutes, plus   ") : _("minutes for each")); j++;
      XtSetArg(args[j], XtNborderWidth, 0); j++;
      XtSetArg(args[j], XtNfromHoriz, tcTime); j++;
      XtSetArg(args[j], XtNtop, XtChainTop);  j++;
      XtAddEventHandler(tcData, ButtonPressMask, False, SetFocus, (XtPointer) popup);
  
      j= 0;
-     XtSetArg(args[j], XtNlabel, tcInc ? _("sec/move") : _("moves     ")); j++;
+     XtSetArg(args[j], XtNlabel, tcInc ? tcInc == 2 ? _("             ") : _("sec/move") : _("moves     ")); j++;
      XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
      XtSetArg(args[j], XtNborderWidth, 0); j++;
      XtSetArg(args[j], XtNfromHoriz, tcData); j++;
      XtSetArg(args[j], XtNtop, XtChainBottom);  j++;
      XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
      XtSetArg(args[j], XtNright, XtChainLeft);  j++;
-     b_clas= XtCreateManagedWidget(_("classical"), commandWidgetClass,
+     XtSetArg(args[j], XtNstate, tcInc==0); j++;
+     b_clas= XtCreateManagedWidget(_("classical"), toggleWidgetClass,
                                   form, args, j);   
      XtAddCallback(b_clas, XtNcallback, TimeControlCallback, (XtPointer) 0);
  
      j=0;
+     XtSetArg(args[j], XtNradioGroup, b_clas); j++;
      XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;
      XtSetArg(args[j], XtNfromHoriz, b_clas);  j++;
      XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
      XtSetArg(args[j], XtNtop, XtChainBottom);  j++;
      XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
      XtSetArg(args[j], XtNright, XtChainLeft);  j++;
-     b_inc = XtCreateManagedWidget(_("incremental"), commandWidgetClass,
+     XtSetArg(args[j], XtNstate, tcInc==1); j++;
+     b_inc = XtCreateManagedWidget(_("incremental"), toggleWidgetClass,
+                                  form, args, j);   
+     XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0);
+     j=0;
+     XtSetArg(args[j], XtNradioGroup, b_inc); j++;
+     XtSetArg(args[j], XtNfromVert, tcOdds1);  j++;
+     XtSetArg(args[j], XtNfromHoriz, b_inc);  j++;
+     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
+     XtSetArg(args[j], XtNtop, XtChainBottom);  j++;
+     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
+     XtSetArg(args[j], XtNright, XtChainLeft);  j++;
+     XtSetArg(args[j], XtNstate, tcInc==2); j++;
+     b_inc = XtCreateManagedWidget(_("fixed time"), toggleWidgetClass,
                                   form, args, j);   
      XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0);
  
      XtAddCallback(b_cancel, XtNcallback, TimeControlPopDown, (XtPointer) 0);
  
      XtRealizeWidget(popup);
 -    CatchDeleteWindow(popup, "TimeControlPopDown");
 +    //    CatchDeleteWindow(popup, "TimeControlPopDown");
      
 -    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 -                &x, &y, &win_x, &win_y, &mask);
 +//    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 +//              &x, &y, &win_x, &win_y, &mask);
      
      XtSetArg(args[0], XtNx, x - 10);
      XtSetArg(args[1], XtNy, y - 30);
@@@ -653,18 -705,18 +704,18 @@@ void EnginePopUp(
      i = 0;
      XtSetArg(args[i], XtNresizable, True); i++;
  //    XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
 -    EngineShell = popup =
 -      XtCreatePopupShell(_("Adjudications"), transientShellWidgetClass,
 -                       shellWidget, args, i);
 -    
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 -                          layoutArgs, XtNumber(layoutArgs));
 -  
 -    form =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, layout,
 -                          formArgs, XtNumber(formArgs));
 -  
 +//    EngineShell = popup =
 +//      XtCreatePopupShell(_("Adjudications"), transientShellWidgetClass,
 +//                     shellWidget, args, i);
 +//    
 +//    layout =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 +//                        layoutArgs, XtNumber(layoutArgs));
 +//  
 +//    form =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, layout,
 +//                        formArgs, XtNumber(formArgs));
 +//  
      j = 0;
  //    XtSetArg(args[j], XtNwidth,     (XtArgVal) 250); j++;
  //    XtSetArg(args[j], XtNheight,    (XtArgVal) 400); j++;
      XtSetArg(args[j-3], XtNstate,       appData.secondScoreIsAbsolute);
      w4 = XtCreateManagedWidget(_("Engine #2 Score is Absolute"), toggleWidgetClass, form, args, j);
  
-     s1 = XtCreateManagedWidget(_("\nEngine-Engine Adjudications:"), labelWidgetClass, form, args, 3);
+     s1 = XtCreateManagedWidget(_("\nAdjudications in non-ICS games:"), labelWidgetClass, form, args, 3);
  
      XtSetArg(args[j-1], XtNfromVert,  (XtArgVal) s1);
      XtSetArg(args[j-3], XtNstate,       appData.testClaims);
      XtAddCallback(b_cancel, XtNcallback, EnginePopDown, (XtPointer) 0);
  
      XtRealizeWidget(popup);
 -    CatchDeleteWindow(popup, "EnginePopDown");
 -    
 -    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 -                &x, &y, &win_x, &win_y, &mask);
 +//    CatchDeleteWindow(popup, "EnginePopDown");
 +//    
 +//    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 +//              &x, &y, &win_x, &win_y, &mask);
      
      XtSetArg(args[0], XtNx, x - 10);
      XtSetArg(args[1], XtNy, y - 30);
@@@ -1006,24 -1058,24 +1057,24 @@@ void NewVariantPopUp(
      XtSetArg(args[i], XtNresizable, True); i++;
  //    XtSetArg(args[i], XtNwidth, 250); i++;
  //    XtSetArg(args[i], XtNheight, 300); i++;
 -    NewVariantShell = popup =
 -      XtCreatePopupShell(_("NewVariant Menu"), transientShellWidgetClass,
 -                       shellWidget, args, i);
 -    
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 -                          layoutArgs, XtNumber(layoutArgs));
 -  
 -    form =
 -      XtCreateManagedWidget("form", formWidgetClass, layout,
 -                          formArgs, XtNumber(formArgs));
 -  
 +//    NewVariantShell = popup =
 +//      XtCreatePopupShell(_("NewVariant Menu"), transientShellWidgetClass,
 +//                     shellWidget, args, i);
 +//    
 +//    layout =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 +//                        layoutArgs, XtNumber(layoutArgs));
 +//  
 +//    form =
 +//      XtCreateManagedWidget("form", formWidgetClass, layout,
 +//                        formArgs, XtNumber(formArgs));
 +//  
      for(i = 0; buttonDesc[i].name != NULL; i++) {
        Pixel buttonColor;
        if (!appData.monoMode) {
            vFrom.addr = (caddr_t) buttonDesc[i].color;
            vFrom.size = strlen(buttonDesc[i].color);
 -          XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
 +          //      XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
            if (vTo.addr == NULL) {
                buttonColor = (Pixel) -1;
            } else {
      XtCreateManagedWidget("warning", labelWidgetClass, form, args, j);
  
            XtRealizeWidget(popup);
 -    CatchDeleteWindow(popup, "NewVariantPopDown");
 -    
 -    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 -                &x, &y, &win_x, &win_y, &mask);
 +//    CatchDeleteWindow(popup, "NewVariantPopDown");
 +//    
 +//    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 +//              &x, &y, &win_x, &win_y, &mask);
      
      XtSetArg(args[0], XtNx, x - 10);
      XtSetArg(args[1], XtNy, y - 30);
@@@ -1201,19 -1253,19 +1252,19 @@@ void UciPopUp(
      i = 0;
      XtSetArg(args[i], XtNresizable, True); i++;
  //    XtSetArg(args[i], XtNwidth, 300); i++;
 -    UciShell = popup =
 -      XtCreatePopupShell(_("Engine Settings"), transientShellWidgetClass,
 -                       shellWidget, args, i);
 -    
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 -                          layoutArgs, XtNumber(layoutArgs));
 -  
 -    
 -    form =
 -      XtCreateManagedWidget("form", formWidgetClass, layout,
 -                          formArgs, XtNumber(formArgs));
 -  
 +//    UciShell = popup =
 +//      XtCreatePopupShell(_("Engine Settings"), transientShellWidgetClass,
 +//                     shellWidget, args, i);
 +//    
 +//    layout =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 +//                        layoutArgs, XtNumber(layoutArgs));
 +//  
 +//    
 +//    form =
 +//      XtCreateManagedWidget("form", formWidgetClass, layout,
 +//                        formArgs, XtNumber(formArgs));
 +//  
      j = 0;
      XtSetArg(args[j], XtNtop, XtChainTop);  j++;
      XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
  //    XtAddCallback(w3, XtNcallback, UciCallback, (XtPointer) 0);
  
      XtRealizeWidget(popup);
 -    CatchDeleteWindow(popup, "UciPopDown");
 -    
 -    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 -                &x, &y, &win_x, &win_y, &mask);
 +//    CatchDeleteWindow(popup, "UciPopDown");
 +//    
 +//    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 +//              &x, &y, &win_x, &win_y, &mask);
      
      XtSetArg(args[0], XtNx, x - 10);
      XtSetArg(args[1], XtNy, y - 30);
@@@ -1497,13 -1549,13 +1548,13 @@@ void SettingsPopUp(ChessProgramState *c
      height = cps->nrOptions / width + 1;
       i = 0;
      XtSetArg(args[i], XtNresizable, True); i++;
 -    SettingsShell = popup =
 -      XtCreatePopupShell(_("Settings Menu"), transientShellWidgetClass,
 -                       shellWidget, args, i);
 -    
 -    layout =
 -      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 -                          layoutArgs, XtNumber(layoutArgs));
 +//    SettingsShell = popup =
 +//      XtCreatePopupShell(_("Settings Menu"), transientShellWidgetClass,
 +//                     shellWidget, args, i);
 +//    
 +//    layout =
 +//      XtCreateManagedWidget(layoutName, formWidgetClass, popup,
 +//                        layoutArgs, XtNumber(layoutArgs));
    for(c=0; c<width; c++) {
      pane[4] = 'A'+c;
      form =
      XtAddCallback(b_cancel, XtNcallback, SettingsPopDown, (XtPointer) 0);
  
      XtRealizeWidget(popup);
 -    CatchDeleteWindow(popup, "SettingsPopDown");
 -    
 -    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 -                &x, &y, &win_x, &win_y, &mask);
 +//    CatchDeleteWindow(popup, "SettingsPopDown");
 +//    
 +//    XQueryPointer(xDisplay, xBoardWindow, &root, &child,
 +//              &x, &y, &win_x, &win_y, &mask);
      
      XtSetArg(args[0], XtNx, x - 10);
      XtSetArg(args[1], XtNy, y - 30);