removed X-version of buttonbar
[xboard.git] / xboard.c
index b31b64f..6058ec1 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -1,9 +1,11 @@
 /*
  * xboard.c -- X front end for XBoard
- * $Id$
  *
- * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
- * Enhancements Copyright 1992-2001 Free Software Foundation, Inc.
+ * Copyright 1991 by Digital Equipment Corporation, Maynard,
+ * Massachusetts.
+ *
+ * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
+ * 2007, 2008, 2009 Free Software Foundation, Inc.
  *
  * The following terms apply to Digital Equipment Corporation's copyright
  * interest in XBoard:
  * SOFTWARE.
  * ------------------------------------------------------------------------
  *
- * The following terms apply to the enhanced version of XBoard distributed
- * by the Free Software Foundation:
+ * The following terms apply to the enhanced version of XBoard
+ * distributed by the Free Software Foundation:
  * ------------------------------------------------------------------------
- * This program is free software; you can redistribute it and/or modify
+ *
+ * GNU XBoard is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * GNU XBoard is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * ------------------------------------------------------------------------
+ * along with this program. If not, see http://www.gnu.org/licenses/.  *
  *
- * See the file ChangeLog for a revision history.
- */
+ *------------------------------------------------------------------------
+ ** See the file ChangeLog for a revision history.  */
 
 #include "config.h"
 
@@ -169,6 +170,9 @@ extern char *getenv();
 #include <X11/Xaw/AsciiText.h>
 #endif
 
+// [HGM] bitmaps: put before incuding the bitmaps / pixmaps, to know how many piece types there are.
+#include "common.h"
+
 #if HAVE_LIBXPM
 #include <X11/xpm.h>
 #include "pixmaps/pixmaps.h"
@@ -178,11 +182,14 @@ 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 "common.h"
 #include "frontend.h"
 #include "backend.h"
 #include "moves.h"
@@ -191,6 +198,17 @@ extern char *getenv();
 #include "xgamelist.h"
 #include "xhistory.h"
 #include "xedittags.h"
+#include "gettext.h"
+#include "callback.h"
+#include "interface.h"
+
+// must be moved to xengineoutput.h
+
+void EngineOutputProc P((Widget w, XEvent *event,
+ String *prms, Cardinal *nprms));
+
+void EngineOutputPopDown();
+
 
 #ifdef __EMX__
 #ifndef HAVE_USLEEP
@@ -199,6 +217,14 @@ extern char *getenv();
 #define usleep(t)   _sleep2(((t)+500)/1000)
 #endif
 
+#ifdef ENABLE_NLS
+# define  _(s) gettext (s)
+# define N_(s) gettext_noop (s)
+#else
+# define  _(s) (s)
+# define N_(s)  s
+#endif
+
 typedef struct {
     String string;
     XtActionProc proc;
@@ -209,6 +235,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));
@@ -218,18 +251,13 @@ 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,
@@ -238,10 +266,6 @@ 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,
@@ -268,22 +292,8 @@ 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,
@@ -296,20 +306,10 @@ void SavePositionProc P((Widget w, XEvent *event,
 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));
@@ -318,29 +318,7 @@ 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 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,
@@ -358,9 +336,6 @@ 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,
@@ -379,18 +354,9 @@ 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 TestLegalityProc 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));
@@ -402,11 +368,26 @@ void ErrorPopUp P((char *title, char *text, int modal));
 void ErrorPopDown P((void));
 static char *ExpandPathName P((char *path));
 static void CreateAnimVars P((void));
-static void DragPieceBegin P((int x, int y));
+void DragPieceBegin P((int x, int y));
 static void DragPieceMove P((int x, int y));
-static void DragPieceEnd P((int x, int y));
+void DragPieceEnd P((int x, int y));
 static void DrawDragPiece P((void));
 char *ModeToWidgetName P((GameMode mode));
+void EngineOutputUpdate( FrontEndProgramStats * stats );
+void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void 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 ShufflePopDown P(());
+void EnginePopDown P(());
+void UciPopDown P(());
+void TimeControlPopDown P(());
+void NewVariantPopDown P(());
+void SettingsPopDown P(());
+void SetMenuEnables P((Enables *enab));
 
 /*
 * XBoard depends on Xt R4 or higher
@@ -418,30 +399,37 @@ Display *xDisplay;
 Window xBoardWindow;
 Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
   jailSquareColor, highlightSquareColor, premoveHighlightColor;
-GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,
-  bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
-  wjPieceGC, bjPieceGC, prelineGC;
+Pixel lowTimeWarningColor;
+
+#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, 
-  whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16], 
+Widget shellWidget, 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;
-XSegment gridSegments[(BOARD_SIZE + 1) * 2];
-XSegment jailGridSegments[(BOARD_SIZE + 3) * 2];
-Font clockFontID, coordFontID;
-XFontStruct *clockFontStruct, *coordFontStruct;
+Font clockFontID, coordFontID, countFontID;
+XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
 XtAppContext appContext;
 char *layoutName;
 char *oldICSInteractionTitle;
 
 FileProc fileProc;
 char *fileOpenMode;
+char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion
 
 Position commentX = -1, commentY = -1;
 Dimension commentW, commentH;
 
 int squareSize, smallLayout = 0, tinyLayout = 0,
+  marginW, marginH, // [HGM] for run-time resizing
   fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,
   ICSInputBoxUp = False, askQuestionUp = False,
   filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,
@@ -453,17 +441,20 @@ char *chessDir, *programName, *programVersion,
 
 #define SOLID 0
 #define OUTLINE 1
-Pixmap pieceBitmap[2][6];
-Pixmap xpmPieceBitmap[4][6];   /* LL, LD, DL, DD */
+Pixmap pieceBitmap[2][(int)BlackPawn];
+Pixmap pieceBitmap2[2][(int)BlackPawn+4];       /* [HGM] pieces */
+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;
-XImage *ximPieceBitmap[4][6];  /* LL, LD, DL, DD */
-Pixmap ximMaskPm[6];            /* clipmasks, used for XIM pieces */
+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 */
 XImage *ximLightSquare, *ximDarkSquare;
 XImage *xim_Cross;
 
-#define pieceToSolid(piece) &pieceBitmap[SOLID][((int)(piece)) % 6]
-#define pieceToOutline(piece) &pieceBitmap[OUTLINE][((int)(piece)) % 6]
+#define pieceToSolid(piece) &pieceBitmap[SOLID][(piece) % (int)BlackPawn]
+#define pieceToOutline(piece) &pieceBitmap[OUTLINE][(piece) % (int)BlackPawn]
 
 #define White(piece) ((int)(piece) < (int)BlackPawn)
 
@@ -498,167 +489,275 @@ 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[] = {
-    {"Reset Game", ResetProc},
+    {N_("New Shuffle Game ..."), ShuffleMenuProc},
+    {N_("New Variant ..."), NewVariantProc},      // [HGM] variant: not functional yet
     {"----", NothingProc},
-    {"Load Game", LoadGameProc},
-    {"Load Next Game", LoadNextGameProc},
-    {"Load Previous Game", LoadPrevGameProc},
-    {"Reload Same Game", ReloadGameProc},
-    {"Save Game", SaveGameProc},
+    {N_("Save Game"), SaveGameProc},
     {"----", NothingProc},
-    {"Copy Game", CopyGameProc},
-    {"Paste Game", PasteGameProc},
+    {N_("Copy Game"), CopyGameProc},
+    {N_("Paste Game"), PasteGameProc},
     {"----", NothingProc},
-    {"Load Position", LoadPositionProc},
-    {"Load Next Position", LoadNextPositionProc},
-    {"Load Previous Position", LoadPrevPositionProc},
-    {"Reload Same Position", ReloadPositionProc},
-    {"Save Position", SavePositionProc},
+    {N_("Load Position"), LoadPositionProc},
+    //    {N_("Load Next Position"), LoadNextPositionProc},
+    //    {N_("Load Previous Position"), LoadPrevPositionProc},
+    //    {N_("Reload Same Position"), ReloadPositionProc},
+    {N_("Save Position"), SavePositionProc},
     {"----", NothingProc},
-    {"Copy Position", CopyPositionProc},
-    {"Paste Position", PastePositionProc},
+    {N_("Copy Position"), CopyPositionProc},
+    {N_("Paste Position"), PastePositionProc},
     {"----", NothingProc},
-    {"Mail Move", MailMoveProc},
-    {"Reload CMail Message", ReloadCmailMsgProc},
+    {N_("Mail Move"), MailMoveProc},
+    {N_("Reload CMail Message"), ReloadCmailMsgProc},
     {"----", NothingProc},
-    {"Exit", QuitProc},
     {NULL, NULL}
 };
 
 MenuItem modeMenu[] = {
-    {"Machine White", MachineWhiteProc},
-    {"Machine Black", MachineBlackProc},
-    {"Two Machines", TwoMachinesProc},
-    {"Analysis Mode", AnalyzeModeProc},
-    {"Analyze File", AnalyzeFileProc },
-    {"ICS Client", IcsClientProc},
-    {"Edit Game", EditGameProc},
-    {"Edit Position", EditPositionProc},
-    {"Training", TrainingProc},
+  //    {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},
-    {"Show Game List", ShowGameListProc},
-    {"Show Move List", HistoryShowProc},
-    {"Edit Tags", EditTagsProc},
-    {"Edit Comment", EditCommentProc},
-    {"ICS Input Box", IcsInputBoxProc},
-    {"Pause", PauseProc},
-    {NULL, NULL}
-};
-
-MenuItem actionMenu[] = {
-    {"Accept", AcceptProc},
-    {"Decline", DeclineProc},
-    {"Rematch", RematchProc},
-    {"----", NothingProc},    
-    {"Call Flag", CallFlagProc},
-    {"Draw", DrawProc},
-    {"Adjourn", AdjournProc},
-    {"Abort", AbortProc},
-    {"Resign", ResignProc},
-    {"----", NothingProc},    
-    {"Stop Observing", StopObservingProc},
-    {"Stop Examining", StopExaminingProc},
+    {N_("Show Engine Output"), EngineOutputProc},
+    {N_("Show Evaluation Graph"), NothingProc}, // [HGM] evalgr: not functional yet
+    {N_("Show Game List"), ShowGameListProc},
+    //    {"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},
     {NULL, NULL}
 };
 
-MenuItem stepMenu[] = {
-    {"Backward", BackwardProc},
-    {"Forward", ForwardProc},
-    {"Back to Start", ToStartProc},
-    {"Forward to End", ToEndProc},
-    {"Revert", RevertProc},
-    {"Truncate Game", TruncateGameProc},
-    {"----", NothingProc},    
-    {"Move Now", MoveNowProc},
-    {"Retract Move", RetractMoveProc},
-    {NULL, NULL}
-};    
-
 MenuItem optionsMenu[] = {
-    {"Always Queen", AlwaysQueenProc},
-    {"Animate Dragging", AnimateDraggingProc},
-    {"Animate Moving", AnimateMovingProc},
-    {"Auto Comment", AutocommProc},
-    {"Auto Flag", AutoflagProc},
-    {"Auto Flip View", AutoflipProc},
-    {"Auto Observe", AutobsProc},
-    {"Auto Raise Board", AutoraiseProc},
-    {"Auto Save", AutosaveProc},
-    {"Blindfold", BlindfoldProc},
-    {"Flash Moves", FlashMovesProc},
-    {"Flip View", FlipViewProc},
-    {"Get Move List", GetMoveListProc},
+  //    {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},
+    {"----", 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
-    {"Highlight Dragging", HighlightDraggingProc},
+    {N_("Highlight Dragging"), HighlightDraggingProc},
 #endif
-    {"Highlight Last Move", HighlightLastMoveProc},
-    {"Move Sound", MoveSoundProc},
-    {"ICS Alarm", IcsAlarmProc},
-    {"Old Save Style", OldSaveStyleProc},
-    {"Periodic Updates", PeriodicUpdatesProc}, 
-    {"Ponder Next Move", PonderNextMoveProc},
-    {"Popup Exit Message", PopupExitMessageProc},      
-    {"Popup Move Errors", PopupMoveErrorsProc},        
-    {"Premove", PremoveProc},
-    {"Quiet Play", QuietPlayProc},
-    {"Show Coords", ShowCoordsProc},
-    {"Show Thinking", ShowThinkingProc},
-    {"Test Legality", TestLegalityProc},
-    {NULL, NULL}
-};
-
-MenuItem helpMenu[] = {
-    {"Info XBoard", InfoProc},
-    {"Man XBoard", ManProc},
-    {"----", NothingProc},
-    {"Hint", HintProc},
-    {"Book", BookProc},
-    {"----", NothingProc},
-    {"About XBoard", AboutProc},
+    {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},
     {NULL, NULL}
 };
 
 Menu menuBar[] = {
-    {"File", fileMenu},
-    {"Mode", modeMenu},
-    {"Action", actionMenu},
-    {"Step", stepMenu},
-    {"Options", optionsMenu},
-    {"Help", helpMenu},
-    {NULL, NULL}
-};
-
-#define PAUSE_BUTTON "P"
-MenuItem buttonBar[] = {
-    {"<<", ToStartProc},
-    {"<", BackwardProc},
-    {PAUSE_BUTTON, PauseProc},
-    {">", ForwardProc},
-    {">>", ToEndProc},
+    {N_("File"), fileMenu},
+    {N_("Mode"), modeMenu},
+    {N_("Options"), optionsMenu},
     {NULL, NULL}
 };
 
-#define PIECE_MENU_SIZE 11
+#define PIECE_MENU_SIZE 18
 String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
-    { "White", "----", "Pawn", "Knight", "Bishop", "Rook", "Queen", "King",
-      "----", "Empty square", "Clear board" },
-    { "Black", "----", "Pawn", "Knight", "Bishop", "Rook", "Queen", "King",
-      "----", "Empty square", "Clear board" },
-  };
+    { 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_("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_("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, EmptySquare, ClearBoard },
+       WhiteRook, WhiteQueen, WhiteKing, (ChessSquare) 0, WhiteAlfil,
+       WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0,
+       PromotePiece, DemotePiece, EmptySquare, ClearBoard },
     { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
-       BlackRook, BlackQueen, BlackKing,
-       (ChessSquare) 0, EmptySquare, ClearBoard },
+       BlackRook, BlackQueen, BlackKing, (ChessSquare) 0, BlackAlfil,
+       BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0,
+       PromotePiece, DemotePiece, EmptySquare, ClearBoard },
 };
 
 #define DROP_MENU_SIZE 6
 String dropMenuStrings[DROP_MENU_SIZE] = {
-    "----", "Pawn", "Knight", "Bishop", "Rook", "Queen"
+    "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen")
   };
 /* must be in same order as PieceMenuStrings! */
 ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
@@ -679,15 +778,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 },
@@ -704,25 +794,6 @@ 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[] = {
     { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
        XtOffset(AppDataPtr, whitePieceColor), XtRString,
@@ -732,7 +803,7 @@ XtResource clientResources[] = {
        BLACK_PIECE_COLOR },
     { "lightSquareColor", "lightSquareColor", XtRString,
        sizeof(String), XtOffset(AppDataPtr, lightSquareColor),
-       XtRString, LIGHT_SQUARE_COLOR }, 
+       XtRString, LIGHT_SQUARE_COLOR },
     { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),
        XtOffset(AppDataPtr, darkSquareColor), XtRString,
        DARK_SQUARE_COLOR },
@@ -775,9 +846,9 @@ XtResource clientResources[] = {
     { "secondHost", "secondHost", XtRString, sizeof(String),
        XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
     { "firstDirectory", "firstDirectory", XtRString, sizeof(String),
-       XtOffset(AppDataPtr, firstDirectory), XtRString, "" },
+       XtOffset(AppDataPtr, firstDirectory), XtRString, "." },
     { "secondDirectory", "secondDirectory", XtRString, sizeof(String),
-       XtOffset(AppDataPtr, secondDirectory), XtRString, "" },
+       XtOffset(AppDataPtr, secondDirectory), XtRString, "." },
     { "bitmapDirectory", "bitmapDirectory", XtRString,
        sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),
        XtRString, "" },
@@ -880,7 +951,7 @@ XtResource clientResources[] = {
        XtOffset(AppDataPtr, searchTime), XtRString,
        (XtPointer) "" },
     { "searchDepth", "searchDepth", XtRInt, sizeof(int),
-       XtOffset(AppDataPtr, searchDepth), XtRImmediate, 
+       XtOffset(AppDataPtr, searchDepth), XtRImmediate,
        (XtPointer) 0 },
     { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
        XtOffset(AppDataPtr, showCoords), XtRImmediate,
@@ -890,7 +961,7 @@ XtResource clientResources[] = {
        (XtPointer) 0 },
     { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),
        XtOffset(AppDataPtr, showThinking), XtRImmediate,
-       (XtPointer) False },
+       (XtPointer) True },
     { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),
        XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,
        (XtPointer) True },
@@ -956,7 +1027,7 @@ XtResource clientResources[] = {
     { "localLineEditing", "localLineEditing", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
        XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
-#ifdef ZIPPY
+#if ZIPPY
     { "zippyTalk", "zippyTalk", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
        XtRImmediate, (XtPointer) ZIPPY_TALK },
@@ -1003,6 +1074,9 @@ XtResource clientResources[] = {
     { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),
        XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,
         (XtPointer) ZIPPY_REPLAY_TIMEOUT },
+    { "zippyShortGame", "zippyShortGame", XtRInt, sizeof(int),
+       XtOffset(AppDataPtr, zippyShortGame), XtRImmediate,
+        (XtPointer) 0 },
 #endif
     { "flashCount", "flashCount", XtRInt, sizeof(int),
        XtOffset(AppDataPtr, flashCount), XtRImmediate,
@@ -1018,7 +1092,7 @@ XtResource clientResources[] = {
        (XtPointer) MS_LOGIN_DELAY },
     { "colorizeMessages", "colorizeMessages", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, colorize),
-       XtRImmediate, (XtPointer) False },      
+       XtRImmediate, (XtPointer) False },
     { "colorShout", "colorShout", XtRString,
        sizeof(String), XtOffset(AppDataPtr, colorShout),
        XtRString, COLOR_SHOUT },
@@ -1048,7 +1122,7 @@ XtResource clientResources[] = {
        XtRString, COLOR_SEEK },
     { "colorNormal", "colorNormal", XtRString,
        sizeof(String), XtOffset(AppDataPtr, colorNormal),
-       XtRString, COLOR_NORMAL },      
+       XtRString, COLOR_NORMAL },
     { "soundProgram", "soundProgram", XtRString,
       sizeof(String), XtOffset(AppDataPtr, soundProgram),
       XtRString, "play" },
@@ -1136,6 +1210,208 @@ XtResource clientResources[] = {
     { "showButtonBar", "showButtonBar", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),
        XtRImmediate, (XtPointer) True },
+    { "lowTimeWarningColor", "lowTimeWarningColor", XtRString,
+      sizeof(String), XtOffset(AppDataPtr, lowTimeWarningColor),
+      XtRString, COLOR_LOWTIMEWARNING },
+    { "lowTimeWarning", "lowTimeWarning", XtRBoolean,
+      sizeof(Boolean), XtOffset(AppDataPtr, lowTimeWarning),
+      XtRImmediate, (XtPointer) False },
+    {"icsEngineAnalyze", "icsEngineAnalyze", XtRBoolean,        /* [DM] icsEngineAnalyze */
+        sizeof(Boolean), XtOffset(AppDataPtr, icsEngineAnalyze),
+        XtRImmediate, (XtPointer) False },
+    { "firstScoreAbs", "firstScoreAbs", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, firstScoreIsAbsolute),
+       XtRImmediate, (XtPointer) False },
+    { "secondScoreAbs", "secondScoreAbs", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, secondScoreIsAbsolute),
+       XtRImmediate, (XtPointer) False },
+    { "pgnExtendedInfo", "pgnExtendedInfo", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, saveExtendedInfoInPGN),
+       XtRImmediate, (XtPointer) False },
+    { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),
+       XtRImmediate, (XtPointer) True },
+    { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
+       XtRImmediate, (XtPointer) 0},
+    { "adjudicateDrawMoves", "adjudicateDrawMoves", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, adjudicateDrawMoves),
+       XtRImmediate, (XtPointer) 0},
+    { "pgnEventHeader", "pgnEventHeader", XtRString,
+        sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),
+       XtRImmediate, (XtPointer) "Computer Chess Game" },
+    { "defaultFrcPosition", "defaultFrcPositon", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),
+       XtRImmediate, (XtPointer) -1},
+    { "gameListTags", "gameListTags", XtRString,
+        sizeof(String), XtOffset(AppDataPtr, gameListTags),
+       XtRImmediate, (XtPointer) GLT_DEFAULT_TAGS },
+
+    // [HGM] 4.3.xx options
+    { "boardWidth", "boardWidth", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, NrFiles),
+       XtRImmediate, (XtPointer) -1},
+    { "boardHeight", "boardHeight", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, NrRanks),
+       XtRImmediate, (XtPointer) -1},
+    { "matchPause", "matchPause", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, matchPause),
+       XtRImmediate, (XtPointer) 10000},
+    { "holdingsSize", "holdingsSize", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, holdingsSize),
+       XtRImmediate, (XtPointer) -1},
+    { "flipBlack", "flipBlack", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, upsideDown),
+       XtRImmediate, (XtPointer) False},
+    { "allWhite", "allWhite", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, allWhite),
+       XtRImmediate, (XtPointer) False},
+    { "pieceToCharTable", "pieceToCharTable", XtRString,
+       sizeof(String), XtOffset(AppDataPtr, pieceToCharTable),
+       XtRImmediate, (XtPointer) 0},
+    { "alphaRank", "alphaRank", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, alphaRank),
+       XtRImmediate, (XtPointer) False},
+    { "testClaims", "testClaims", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, testClaims),
+       XtRImmediate, (XtPointer) True},
+    { "checkMates", "checkMates", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, checkMates),
+       XtRImmediate, (XtPointer) True},
+    { "materialDraws", "materialDraws", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, materialDraws),
+       XtRImmediate, (XtPointer) True},
+    { "trivialDraws", "trivialDraws", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, trivialDraws),
+       XtRImmediate, (XtPointer) False},
+    { "ruleMoves", "ruleMoves", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, ruleMoves),
+       XtRImmediate, (XtPointer) 51},
+    { "repeatsToDraw", "repeatsToDraw", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, drawRepeats),
+       XtRImmediate, (XtPointer) 6},
+    { "engineDebugOutput", "engineDebugOutput", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, engineComments),
+       XtRImmediate, (XtPointer) 1},
+    { "userName", "userName", XtRString,
+       sizeof(int), XtOffset(AppDataPtr, userName),
+       XtRImmediate, (XtPointer) 0},
+    { "autoKibitz", "autoKibitz", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, autoKibitz),
+       XtRImmediate, (XtPointer) False},
+    { "firstTimeOdds", "firstTimeOdds", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, firstTimeOdds),
+       XtRImmediate, (XtPointer) 1},
+    { "secondTimeOdds", "secondTimeOdds", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, secondTimeOdds),
+       XtRImmediate, (XtPointer) 1},
+    { "timeOddsMode", "timeOddsMode", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, timeOddsMode),
+       XtRImmediate, (XtPointer) 0},
+    { "firstAccumulateTC", "firstAccumulateTC", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, firstAccumulateTC),
+       XtRImmediate, (XtPointer) 1},
+    { "secondAccumulateTC", "secondAccumulateTC", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, secondAccumulateTC),
+       XtRImmediate, (XtPointer) 1},
+    { "firstNPS", "firstNPS", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, firstNPS),
+       XtRImmediate, (XtPointer) -1},
+    { "secondNPS", "secondNPS", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, secondNPS),
+       XtRImmediate, (XtPointer) -1},
+    { "serverMoves", "serverMoves", XtRString,
+       sizeof(String), XtOffset(AppDataPtr, serverMovesName),
+       XtRImmediate, (XtPointer) 0},
+    { "serverPause", "serverPause", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, serverPause),
+       XtRImmediate, (XtPointer) 0},
+    { "suppressLoadMoves", "suppressLoadMoves", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, suppressLoadMoves),
+       XtRImmediate, (XtPointer) False},
+    { "userName", "userName", XtRString,
+       sizeof(String), XtOffset(AppDataPtr, userName),
+       XtRImmediate, (XtPointer) 0},
+    { "egtFormats", "egtFormats", XtRString,
+       sizeof(String), XtOffset(AppDataPtr, egtFormats),
+       XtRImmediate, (XtPointer) 0},
+    { "rewindIndex", "rewindIndex", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, rewindIndex),
+       XtRImmediate, (XtPointer) 0},
+    { "sameColorGames", "sameColorGames", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, sameColorGames),
+       XtRImmediate, (XtPointer) 0},
+    { "smpCores", "smpCores", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, smpCores),
+       XtRImmediate, (XtPointer) 1},
+    { "niceEngines", "niceEngines", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, niceEngines),
+       XtRImmediate, (XtPointer) 0},
+    { "nameOfDebugFile", "nameOfDebugFile", XtRString,
+       sizeof(String), XtOffset(AppDataPtr, nameOfDebugFile),
+       XtRImmediate, (XtPointer) "xboard.debug"},
+    { "engineDebugOutput", "engineDebugOutput", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, engineComments),
+       XtRImmediate, (XtPointer) 1},
+    { "noGUI", "noGUI", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, noGUI),
+       XtRImmediate, (XtPointer) 0},
+    { "firstOptions", "firstOptions", XtRString,
+        sizeof(String), XtOffset(AppDataPtr, firstOptions),
+       XtRImmediate, (XtPointer) "" },
+    { "secondOptions", "secondOptions", XtRString,
+        sizeof(String), XtOffset(AppDataPtr, secondOptions),
+       XtRImmediate, (XtPointer) "" },
+    { "firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XtRString,
+        sizeof(String), XtOffset(AppDataPtr, fenOverride1),
+       XtRImmediate, (XtPointer) 0 },
+    { "secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XtRString,
+        sizeof(String), XtOffset(AppDataPtr, fenOverride2),
+       XtRImmediate, (XtPointer) 0 },
+
+    // [HGM] Winboard_x UCI options
+    { "firstIsUCI", "firstIsUCI", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, firstIsUCI),
+       XtRImmediate, (XtPointer) False},
+    { "secondIsUCI", "secondIsUCI", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, secondIsUCI),
+       XtRImmediate, (XtPointer) False},
+    { "firstHasOwnBookUCI", "firstHasOwnBookUCI", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, firstHasOwnBookUCI),
+       XtRImmediate, (XtPointer) True},
+    { "secondHasOwnBookUCI", "secondHasOwnBookUCI", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, secondHasOwnBookUCI),
+       XtRImmediate, (XtPointer) True},
+    { "usePolyglotBook", "usePolyglotBook", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, usePolyglotBook),
+       XtRImmediate, (XtPointer) False},
+    { "defaultHashSize", "defaultHashSize", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, defaultHashSize),
+       XtRImmediate, (XtPointer) 64},
+    { "defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, defaultCacheSizeEGTB),
+       XtRImmediate, (XtPointer) 4},
+    { "polyglotDir", "polyglotDir", XtRString,
+        sizeof(String), XtOffset(AppDataPtr, polyglotDir),
+       XtRImmediate, (XtPointer) "." },
+    { "polyglotBook", "polyglotBook", XtRString,
+        sizeof(String), XtOffset(AppDataPtr, polyglotBook),
+       XtRImmediate, (XtPointer) "" },
+    { "defaultPathEGTB", "defaultPathEGTB", XtRString,
+       sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),
+       XtRImmediate, (XtPointer) "/usr/local/share/egtb"},
+    { "delayBeforeQuit", "delayBeforeQuit", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, delayBeforeQuit),
+       XtRImmediate, (XtPointer) 0},
+    { "delayAfterQuit", "delayAfterQuit", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
+       XtRImmediate, (XtPointer) 0},
+    { "keepAlive", "keepAlive", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, keepAlive),
+       XtRImmediate, (XtPointer) 0},
+    { "forceIllegalMoves", "forceIllegalMoves", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, forceIllegal),
+       XtRImmediate, (XtPointer) False},
 };
 
 XrmOptionDescRec shellOptions[] = {
@@ -1358,6 +1634,7 @@ XrmOptionDescRec shellOptions[] = {
     { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },
     { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },
     { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },
+    { "-zippyShortGame", "zippyShortGame", XrmoptionSepArg, NULL },
 #endif
     { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
     { "-flash", "flashCount", XrmoptionNoArg, "3" },
@@ -1426,11 +1703,88 @@ XrmOptionDescRec shellOptions[] = {
     { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },
     { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },
     { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },
+    { "-lowTimeWarningColor", "lowTimeWarningColor", XrmoptionSepArg, NULL },
+    { "-lowTimeWarning", "lowTimeWarning", XrmoptionSepArg, NULL },
+    /* [AS,HR] New features */
+    { "-firstScoreAbs", "firstScoreAbs", XrmoptionSepArg, NULL },
+    { "-secondScoreAbs", "secondScoreAbs", XrmoptionSepArg, NULL },
+    { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
+    { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
+    { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
+    { "-adjudicateDrawMoves", "adjudicateDrawMoves", XrmoptionSepArg, NULL },
+    { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
+    { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
+    { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
+    { "-fUCI", "firstIsUCI", XrmoptionNoArg, "True" },
+    { "-sUCI", "secondIsUCI", XrmoptionNoArg, "True" },
+    { "-firstHasOwnBookUCI", "firstHasOwnBookUCI", XrmoptionSepArg, NULL },
+    { "-secondHasOwnBookUCI", "secondHasOwnBookUCI", XrmoptionSepArg, NULL },
+    { "-fNoOwnBookUCI", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
+    { "-sNoOwnBookUCI", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
+    { "-firstXBook", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
+    { "-secondXBook", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
+    { "-polyglotDir", "polyglotDir", XrmoptionSepArg, NULL },
+    { "-usePolyglotBook", "usePolyglotBook", XrmoptionSepArg, NULL },
+    { "-polyglotBook", "polyglotBook", XrmoptionSepArg, NULL },
+    { "-defaultHashSize", "defaultHashSize", XrmoptionSepArg, NULL },
+    { "-defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XrmoptionSepArg, NULL },
+    { "-defaultPathEGTB", "defaultPathEGTB", XrmoptionSepArg, NULL },
+    { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },
+    { "-gameListTags", "gameListTags", XrmoptionSepArg, NULL },
+    // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c
+
+    /* [HGM,HR] User-selectable board size */
+    { "-boardWidth", "boardWidth", XrmoptionSepArg, NULL },
+    { "-boardHeight", "boardHeight", XrmoptionSepArg, NULL },
+    { "-matchPause", "matchPause", XrmoptionSepArg, NULL },
+
+    /* [HGM] new arguments of 4.3.xx. All except first three are back-end options, which should work immediately */
+    { "-holdingsSize", "holdingsSize", XrmoptionSepArg, NULL }, // requires extensive front-end changes to work
+    { "-flipBlack", "flipBlack", XrmoptionSepArg, NULL },       // requires front-end changes to work
+    { "-allWhite", "allWhite", XrmoptionSepArg, NULL },         // requires front-end changes to work
+    { "-pieceToCharTable", "pieceToCharTable", XrmoptionSepArg, NULL },
+    { "-alphaRank", "alphaRank", XrmoptionSepArg, NULL },
+    { "-testClaims", "testClaims", XrmoptionSepArg, NULL },
+    { "-checkMates", "checkMates", XrmoptionSepArg, NULL },
+    { "-materialDraws", "materialDraws", XrmoptionSepArg, NULL },
+    { "-trivialDraws", "trivialDraws", XrmoptionSepArg, NULL },
+    { "-ruleMoves", "ruleMoves", XrmoptionSepArg, NULL },
+    { "-repeatsToDraw", "repeatsToDraw", XrmoptionSepArg, NULL },
+    { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
+    { "-userName", "userName", XrmoptionSepArg, NULL },
+    { "-autoKibitz", "autoKibitz", XrmoptionNoArg, "True" },
+    { "-firstTimeOdds", "firstTimeOdds", XrmoptionSepArg, NULL },
+    { "-secondTimeOdds", "secondTimeOdds", XrmoptionSepArg, NULL },
+    { "-timeOddsMode", "timeOddsMode", XrmoptionSepArg, NULL },
+    { "-firstAccumulateTC", "firstAccumulateTC", XrmoptionSepArg, NULL },
+    { "-secondAccumulateTC", "secondAccumulateTC", XrmoptionSepArg, NULL },
+    { "-firstNPS", "firstNPS", XrmoptionSepArg, NULL },
+    { "-secondNPS", "secondNPS", XrmoptionSepArg, NULL },
+    { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL },
+    { "-serverPause", "serverPause", XrmoptionSepArg, NULL },
+    { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL },
+    { "-egtFormats", "egtFormats", XrmoptionSepArg, NULL },
+    { "-userName", "userName", XrmoptionSepArg, NULL },
+    { "-smpCores", "smpCores", XrmoptionSepArg, NULL },
+    { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL },
+    { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL },
+    { "-niceEngines", "niceEngines", XrmoptionSepArg, NULL },
+    { "-delayBeforeQuit", "delayBeforeQuit", XrmoptionSepArg, NULL },
+    { "-delayAfterQuit", "delayAfterQuit", XrmoptionSepArg, NULL },
+    { "-nameOfDebugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
+    { "-debugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
+    { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
+    { "-noGUI", "noGUI", XrmoptionNoArg, "True" },
+    { "-firstOptions", "firstOptions", XrmoptionSepArg, NULL },
+    { "-secondOptions", "secondOptions", XrmoptionSepArg, NULL },
+    { "-firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
+    { "-secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
+    { "-keepAlive", "keepAlive", XrmoptionSepArg, NULL },
+    { "-forceIllegalMoves", "forceIllegalMoves", XrmoptionNoArg, "True" },
 };
 
 
 XtActionsRec boardActions[] = {
-    { "DrawPosition", DrawPositionProc },
     { "HandleUserMove", HandleUserMove },
     { "AnimateUserMove", AnimateUserMove },
     { "FileNameAction", FileNameAction },
@@ -1440,16 +1794,11 @@ XtActionsRec boardActions[] = {
     { "WhiteClock", WhiteClock },
     { "BlackClock", BlackClock },
     { "Iconify", Iconify },
-    { "ResetProc", ResetProc },
-    { "LoadGameProc", LoadGameProc },
-    { "LoadNextGameProc", LoadNextGameProc },
-    { "LoadPrevGameProc", LoadPrevGameProc },
     { "LoadSelectedProc", LoadSelectedProc },
-    { "ReloadGameProc", ReloadGameProc },
     { "LoadPositionProc", LoadPositionProc },
-    { "LoadNextPositionProc", LoadNextPositionProc },
-    { "LoadPrevPositionProc", LoadPrevPositionProc },
-    { "ReloadPositionProc", ReloadPositionProc },
+    //    { "LoadNextPositionProc", LoadNextPositionProc },
+    //    { "LoadPrevPositionProc", LoadPrevPositionProc },
+    //    { "ReloadPositionProc", ReloadPositionProc },
     { "CopyPositionProc", CopyPositionProc },
     { "PastePositionProc", PastePositionProc },
     { "CopyGameProc", CopyGameProc },
@@ -1458,42 +1807,44 @@ XtActionsRec boardActions[] = {
     { "SavePositionProc", SavePositionProc },
     { "MailMoveProc", MailMoveProc },
     { "ReloadCmailMsgProc", ReloadCmailMsgProc },
-    { "QuitProc", QuitProc },
-    { "MachineWhiteProc", MachineWhiteProc },
-    { "MachineBlackProc", MachineBlackProc },
+    //    { "MachineWhiteProc", MachineWhiteProc },
+    //    { "MachineBlackProc", MachineBlackProc },
     { "AnalysisModeProc", AnalyzeModeProc },
     { "AnalyzeFileProc", AnalyzeFileProc },
-    { "TwoMachinesProc", TwoMachinesProc },
-    { "IcsClientProc", IcsClientProc },
+    //    { "TwoMachinesProc", TwoMachinesProc },
+    //    { "IcsClientProc", IcsClientProc },
     { "EditGameProc", EditGameProc },
     { "EditPositionProc", EditPositionProc },
     { "TrainingProc", EditPositionProc },
+    { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
     { "ShowGameListProc", ShowGameListProc },
-    { "ShowMoveListProc", HistoryShowProc},
+    //    { "ShowMoveListProc", HistoryShowProc},
     { "EditTagsProc", EditCommentProc },
     { "EditCommentProc", EditCommentProc },
     { "IcsAlarmProc", IcsAlarmProc },
     { "IcsInputBoxProc", IcsInputBoxProc },
-    { "PauseProc", PauseProc },
-    { "AcceptProc", AcceptProc },
-    { "DeclineProc", DeclineProc },
-    { "RematchProc", RematchProc },
-    { "CallFlagProc", CallFlagProc },
-    { "DrawProc", DrawProc },
-    { "AdjournProc", AdjournProc },
-    { "AbortProc", AbortProc },
-    { "ResignProc", ResignProc },
+    //    { "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 },
+    //    { "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 },
@@ -1504,8 +1855,8 @@ XtActionsRec boardActions[] = {
     { "AutosaveProc", AutosaveProc },
     { "BlindfoldProc", BlindfoldProc },
     { "FlashMovesProc", FlashMovesProc },
-    { "FlipViewProc", FlipViewProc },
-    { "GetMoveListProc", GetMoveListProc },
+    //    { "FlipViewProc", FlipViewProc },
+    //    { "GetMoveListProc", GetMoveListProc },
 #if HIGHDRAG
     { "HighlightDraggingProc", HighlightDraggingProc },
 #endif
@@ -1513,21 +1864,20 @@ XtActionsRec boardActions[] = {
     { "IcsAlarmProc", IcsAlarmProc },
     { "MoveSoundProc", MoveSoundProc },
     { "OldSaveStyleProc", OldSaveStyleProc },
-    { "PeriodicUpdatesProc", PeriodicUpdatesProc },    
+    { "PeriodicUpdatesProc", PeriodicUpdatesProc },
     { "PonderNextMoveProc", PonderNextMoveProc },
-    { "PopupExitMessageProc", PopupExitMessageProc },  
-    { "PopupMoveErrorsProc", PopupMoveErrorsProc },    
+    { "PopupExitMessageProc", PopupExitMessageProc },
+    { "PopupMoveErrorsProc", PopupMoveErrorsProc },
     { "PremoveProc", PremoveProc },
     { "QuietPlayProc", QuietPlayProc },
-    { "ShowCoordsProc", ShowCoordsProc },
-    { "ShowThinkingProc", ShowThinkingProc },
+    //    { "ShowThinkingProc", ShowThinkingProc },
+    //    { "HideThinkingProc", HideThinkingProc },
     { "TestLegalityProc", TestLegalityProc },
-    { "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 },
@@ -1540,51 +1890,17 @@ XtActionsRec boardActions[] = {
     { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
     { "GameListPopDown", (XtActionProc) GameListPopDown },
     { "PromotionPopDown", (XtActionProc) PromotionPopDown },
-    { "HistoryPopDown", (XtActionProc) HistoryPopDown },
+    //    { "HistoryPopDown", (XtActionProc) HistoryPopDown },
+    { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
+    { "ShufflePopDown", (XtActionProc) ShufflePopDown },
+    { "EnginePopDown", (XtActionProc) EnginePopDown },
+    { "UciPopDown", (XtActionProc) UciPopDown },
+    { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
+    { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
+    { "SettingsPopDown", (XtActionProc) SettingsPopDown },
 };
-     
-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 \
-   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";
 
@@ -1594,143 +1910,6 @@ String xboardResources[] = {
     "*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");
-    fprintf(stderr, "         Unable to autosize for XPM/XIM pieces.\n");
-    fprintf(stderr, "   Please report this error to frankm@hiwaay.net.\n");
-    fprintf(stderr, "   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" };
@@ -1747,7 +1926,7 @@ parse_color(str, which)
 {
     char *p, buf[100], *d;
     int i;
-  
+
     if (strlen(str) > 99)      /* watch bounds on buf */
       return -1;
 
@@ -1769,10 +1948,10 @@ parse_color(str, which)
     if (*p == ',') {
        return -1;              /* Use default for empty field */
     }
-    
+
     if (which == 2 || isdigit(*p))
       return atoi(p);
+
     while (*p && isalpha(*p))
       *(d++) = *(p++);
 
@@ -1784,7 +1963,7 @@ parse_color(str, which)
     }
     if (!StrCaseCmp(buf, "default")) return -1;
 
-    fprintf(stderr, "%s: unrecognized color %s\n", programName, buf);
+    fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
     return -2;
 }
 
@@ -1794,7 +1973,7 @@ parse_cpair(cc, str)
      char *str;
 {
     if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
-       fprintf(stderr, "%s: can't parse foreground color in `%s'\n",
+       fprintf(stderr, _("%s: can't parse foreground color in `%s'\n"),
                programName, str);
        return -1;
     }
@@ -1815,18 +1994,122 @@ CatchDeleteWindow(Widget w, String procname)
 {
   char buf[MSG_SIZ];
   XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);
-  sprintf(buf, "<Message>WM_PROTOCOLS: %s() \n", procname);
+  snprintf(buf, sizeof(buf), "<Message>WM_PROTOCOLS: %s() \n", procname);
   XtAugmentTranslations(w, XtParseTranslationTable(buf));
 }
 
 void
 BoardToTop()
 {
-  Arg args[16];
-  XtSetArg(args[0], XtNiconic, False);
-  XtSetValues(shellWidget, args, 1);
+  /* this should raise the board to the top */
+  gtk_window_present(GTK_WINDOW(GUI_Window));
+  return;
+}
+
+#define BoardSize int
+void InitDrawingSizes(BoardSize boardSize, int flags)
+{   // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
+    Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
+    Arg args[16];
+    XtGeometryResult gres;
+    int i;
+
+    boardWidth  = lineGap + BOARD_WIDTH  * (squareSize + lineGap);
+    boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
+
+    timerWidth = (boardWidth - sep) / 2;
+
+    if (appData.titleInWindow)
+      {
+       i = 0;
+       if (smallLayout)
+         {
+           w = boardWidth - 2*bor;
+         }
+       else
+         {
+           w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE
+         }
+      }
 
-  XtPopup(shellWidget, XtGrabNone); /* Raise if lowered  */
+    if(!formWidget) return;
+
+    /*
+     * Inhibit shell resizing.
+     */
+
+    // [HGM] pieces: tailor piece bitmaps to needs of specific variant
+    // (only for xpm)
+    if(useImages) {
+      for(i=0; i<4; i++) {
+       int p;
+       for(p=0; p<=(int)WhiteKing; p++)
+          xpmPieceBitmap[i][p] = xpmPieceBitmap2[i][p]; // defaults
+       if(gameInfo.variant == VariantShogi) {
+          xpmPieceBitmap[i][(int)WhiteCannon] = xpmPieceBitmap2[i][(int)WhiteKing+1];
+          xpmPieceBitmap[i][(int)WhiteNightrider] = xpmPieceBitmap2[i][(int)WhiteKing+2];
+          xpmPieceBitmap[i][(int)WhiteSilver] = xpmPieceBitmap2[i][(int)WhiteKing+3];
+          xpmPieceBitmap[i][(int)WhiteGrasshopper] = xpmPieceBitmap2[i][(int)WhiteKing+4];
+          xpmPieceBitmap[i][(int)WhiteQueen] = xpmPieceBitmap2[i][(int)WhiteLance];
+       }
+#ifdef GOTHIC
+       if(gameInfo.variant == VariantGothic) {
+          xpmPieceBitmap[i][(int)WhiteMarshall] = xpmPieceBitmap2[i][(int)WhiteSilver];
+       }
+#endif
+#if !HAVE_LIBXPM
+       // [HGM] why are thee ximMasks used at all? the ximPieceBitmaps seem to be never used!
+       for(p=0; p<=(int)WhiteKing; p++)
+          ximMaskPm[p] = ximMaskPm2[p]; // defaults
+       if(gameInfo.variant == VariantShogi) {
+          ximMaskPm[(int)WhiteCannon] = ximMaskPm2[(int)WhiteKing+1];
+          ximMaskPm[(int)WhiteNightrider] = ximMaskPm2[(int)WhiteKing+2];
+          ximMaskPm[(int)WhiteSilver] = ximMaskPm2[(int)WhiteKing+3];
+          ximMaskPm[(int)WhiteGrasshopper] = ximMaskPm2[(int)WhiteKing+4];
+          ximMaskPm[(int)WhiteQueen] = ximMaskPm2[(int)WhiteLance];
+       }
+#ifdef GOTHIC
+       if(gameInfo.variant == VariantGothic) {
+           ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[(int)WhiteSilver];
+       }
+#endif
+#endif
+      }
+    } else {
+      for(i=0; i<2; i++) {
+       int p;
+       for(p=0; p<=(int)WhiteKing; p++)
+          pieceBitmap[i][p] = pieceBitmap2[i][p]; // defaults
+       if(gameInfo.variant == VariantShogi) {
+          pieceBitmap[i][(int)WhiteCannon] = pieceBitmap2[i][(int)WhiteKing+1];
+          pieceBitmap[i][(int)WhiteNightrider] = pieceBitmap2[i][(int)WhiteKing+2];
+          pieceBitmap[i][(int)WhiteSilver] = pieceBitmap2[i][(int)WhiteKing+3];
+          pieceBitmap[i][(int)WhiteGrasshopper] = pieceBitmap2[i][(int)WhiteKing+4];
+          pieceBitmap[i][(int)WhiteQueen] = pieceBitmap2[i][(int)WhiteLance];
+       }
+#ifdef GOTHIC
+       if(gameInfo.variant == VariantGothic) {
+          pieceBitmap[i][(int)WhiteMarshall] = pieceBitmap2[i][(int)WhiteSilver];
+       }
+#endif
+      }
+    }
+#if HAVE_LIBXPM
+    CreateAnimVars();
+#endif
+}
+
+void EscapeExpand(char *p, char *q)
+{      // [HGM] initstring: routine to shape up string arguments
+       while(*p++ = *q++) if(p[-1] == '\\')
+           switch(*q++) {
+               case 'n': p[-1] = '\n'; break;
+               case 'r': p[-1] = '\r'; break;
+               case 't': p[-1] = '\t'; break;
+               case '\\': p[-1] = '\\'; break;
+               case 0: *p = 0; return;
+               default: p[-1] = q[-1]; break;
+           }
 }
 
 int
@@ -1837,54 +2120,190 @@ main(argc, argv)
     int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
     XSetWindowAttributes window_attributes;
     Arg args[16];
-    Dimension timerWidth, boardWidth, w, h, sep, bor, wr, hr;
+    Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
     XrmValue vFrom, vTo;
     XtGeometryResult gres;
     char *p;
     XrmDatabase xdb;
     int forceMono = False;
 
+#define INDIRECTION
+#ifdef INDIRECTION
+    // [HGM] before anything else, expand any indirection files amongst options
+    char *argvCopy[1000]; // 1000 seems enough
+    char newArgs[10000];  // holds actual characters
+    int k = 0;
+
+    srandom(time(0)); // [HGM] book: make random truly random
+
+    j = 0;
+    for(i=0; i<argc; i++) {
+       if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
+       //fprintf(stderr, "arg %s\n", argv[i]);
+       if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
+           char c;
+           FILE *f = fopen(argv[i]+1, "rb");
+           if(f == NULL) { fprintf(stderr, _("ignore %s\n"), argv[i]); continue; } // do not expand non-existing
+           argvCopy[j++] = newArgs + k; // get ready for first argument from file
+           while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
+               if(c == '\n') {
+                   if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
+                   newArgs[k++] = 0;  // terminate current arg
+                   if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
+                   argvCopy[j++] = newArgs + k; // get ready for next
+               } else {
+                   if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
+                   newArgs[k++] = c;
+               }
+           }
+           newArgs[k] = 0;
+           j--;
+           fclose(f);
+       }
+    }
+    argvCopy[j] = NULL;
+    argv = argvCopy;
+    argc = j;
+#endif
+
     setbuf(stdout, NULL);
     setbuf(stderr, NULL);
     debugFP = stderr;
-    
+
     programName = strrchr(argv[0], '/');
     if (programName == NULL)
       programName = argv[0];
     else
       programName++;
 
+#ifdef ENABLE_NLS
+    XtSetLanguageProc(NULL, NULL, NULL);
+    bindtextdomain(PACKAGE, LOCALEDIR);
+    textdomain(PACKAGE);
+#endif
+
     shellWidget =
       XtAppInitialize(&appContext, "XBoard", shellOptions,
                      XtNumber(shellOptions),
                      &argc, argv, xboardResources, NULL, 0);
-    if (argc > 1) {
-       fprintf(stderr, "%s: unrecognized argument %s\n",
+
+    /* 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!\n");
+
+    GUI_History = GTK_WIDGET (gtk_builder_get_object (builder, "MoveHistory"));
+    if(!GUI_History) printf("Error: gtk_builder didn't work!\n");
+
+    GUI_Menubar  = GTK_WIDGET (gtk_builder_get_object (builder, "MenuBar"));
+    if(!GUI_Menubar) printf("Error: gtk_builder didn't work!\n");
+    GUI_Timer  = GTK_WIDGET (gtk_builder_get_object (builder, "Timer"));
+    if(!GUI_Timer) printf("Error: gtk_builder didn't work!\n");
+    GUI_Buttonbar  = GTK_WIDGET (gtk_builder_get_object (builder, "ButtonBar"));
+    if(!GUI_Buttonbar) printf("Error: gtk_builder didn't work!\n");
+    GUI_Board  = GTK_WIDGET (gtk_builder_get_object (builder, "Board"));
+    if(!GUI_Board) printf("Error: gtk_builder didn't work!\n");
+
+    GUI_Whiteclock  = GTK_WIDGET (gtk_builder_get_object (builder, "WhiteClock"));
+    if(!GUI_Whiteclock) printf("Error: gtk_builder didn't work!\n");
+
+    GUI_Blackclock  = GTK_WIDGET (gtk_builder_get_object (builder, "BlackClock"));
+    if(!GUI_Blackclock) printf("Error: gtk_builder didn't work!\n");
+
+    LIST_MoveHistory = GTK_LIST_STORE (gtk_builder_get_object (builder, "MoveHistoryStore"));
+    if(!LIST_MoveHistory) printf("Error: gtk_builder didn't work!\n");
+
+
+    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 */
+
+    if (argc > 1)
+      {
+       fprintf(stderr, _("%s: unrecognized argument %s\n"),
                programName, argv[1]);
+
+       fprintf(stderr, "Recognized options:\n");
+       for(i = 0; i < XtNumber(shellOptions); i++) 
+         {
+           /* print first column */
+           j = fprintf(stderr, "  %s%s", shellOptions[i].option,
+                       (shellOptions[i].argKind == XrmoptionSepArg
+                        ? " ARG" : ""));
+           /* print second column and end line */
+           if (++i < XtNumber(shellOptions)) 
+             {         
+               fprintf(stderr, "%*c%s%s\n", 40 - j, ' ',
+                       shellOptions[i].option,
+                       (shellOptions[i].argKind == XrmoptionSepArg
+                        ? " ARG" : ""));
+             } 
+           else 
+             {
+               fprintf(stderr, "\n");
+             };
+         };
        exit(2);
+      };
+
+    p = getenv("HOME");
+    if (p == NULL) p = "/tmp";
+    i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
+    gameCopyFilename = (char*) malloc(i);
+    gamePasteFilename = (char*) malloc(i);
+    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);
+
+    { // [HGM] initstring: kludge to fix bad bug. expand '\n' characters in init string and computer string.
+       static char buf[MSG_SIZ];
+       EscapeExpand(buf, appData.initString);
+       appData.initString = strdup(buf);
+       EscapeExpand(buf, appData.secondInitString);
+       appData.secondInitString = strdup(buf);
+       EscapeExpand(buf, appData.firstComputerString);
+       appData.firstComputerString = strdup(buf);
+       EscapeExpand(buf, appData.secondComputerString);
+       appData.secondComputerString = strdup(buf);
     }
-    
+
     if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
        chessDir = ".";
     } else {
        if (chdir(chessDir) != 0) {
-           fprintf(stderr, "%s: can't cd to CHESSDIR: ", programName);
+           fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
            perror(chessDir);
            exit(1);
        }
     }
-    
-    p = getenv("HOME");
-    if (p == NULL) p = "/tmp";
-    i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
-    gameCopyFilename = (char*) malloc(i);
-    gamePasteFilename = (char*) malloc(i);
-    sprintf(gameCopyFilename, "%s/.xboard%05uc.pgn", p, getpid());
-    sprintf(gamePasteFilename, "%s/.xboard%05up.pgn", p, getpid());
 
-    XtGetApplicationResources(shellWidget, (XtPointer) &appData,
-                             clientResources, XtNumber(clientResources),
-                             NULL, 0);
+    if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
+       /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
+        if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL)  {
+           printf(_("Failed to open file '%s'\n"), appData.nameOfDebugFile);
+           exit(errno);
+        }
+        setbuf(debugFP, NULL);
+    }
+
+    /* [HGM,HR] make sure board size is acceptable */
+    if(appData.NrFiles > BOARD_SIZE ||
+       appData.NrRanks > BOARD_SIZE   )
+      DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
 
 #if !HIGHDRAG
     /* This feature does not work; animation needs a rewrite */
@@ -1896,55 +2315,69 @@ main(argc, argv)
     xScreen = DefaultScreen(xDisplay);
     wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
 
-    /*
-     * Determine boardSize
-     */
-    if (isdigit(appData.boardSize[0])) {
-        i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
+    gameInfo.variant = StringToVariant(appData.variant);
+    InitPosition(FALSE);
+
+    /* calc board size */
+    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",
+       if (i == 0) 
+         {
+           fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
                    programName, appData.boardSize);
            exit(2);
-       }
-       if (i < 7) {
+         }
+       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) {
+           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 {
+         }
+      } 
+    else 
+      {
         SizeDefaults *szd = sizeDefaults;
-        if (*appData.boardSize == NULLCHAR) {
-           while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
-                  DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
-             szd++;
-           }
+        if (*appData.boardSize == NULLCHAR) 
+         {
+           while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize 
+                  || DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) 
+             {
+               szd++;
+             }
            if (szd->name == NULL) szd--;
-       } else {
-           while (szd->name != NULL &&
-                  StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
-           if (szd->name == NULL) {
-               fprintf(stderr, "%s: unrecognized boardSize name %s\n",
+         } 
+       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;
@@ -1952,43 +2385,12 @@ main(argc, argv)
        fontPxlSize = szd->fontPxlSize;
        smallLayout = szd->smallLayout;
        tinyLayout = szd->tinyLayout;
-    }
-
-    /* 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", squareSize);
-           fprintf(stderr, "%s fulldir:%s:\n", IMAGE_EXT, p);
-       }
-       squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
-       if (appData.debugMode) {
-           fprintf(stderr, "Closest %s size: %d\n", IMAGE_EXT, squareSize);
-       }
-    }
-               
-    boardWidth = lineGap + BOARD_SIZE * (squareSize + lineGap);
-    if (appData.showJail == 1) {
-       /* Jail on top and bottom */
-       XtSetArg(boardArgs[1], XtNwidth, boardWidth);
-       XtSetArg(boardArgs[2], XtNheight,
-                boardWidth + 2*(lineGap + squareSize));
-    } else if (appData.showJail == 2) {
-       /* Jail on sides */
-       XtSetArg(boardArgs[1], XtNwidth,
-                boardWidth + 2*(lineGap + squareSize));
-       XtSetArg(boardArgs[2], XtNheight, boardWidth);
-    } else {
-       /* No jail */
-       XtSetArg(boardArgs[1], XtNwidth, boardWidth);
-       XtSetArg(boardArgs[2], XtNheight, boardWidth);
-    }
-
+      }
+    /* end figuring out what size to use */
+    
+    boardWidth  = lineGap + BOARD_WIDTH * (squareSize + lineGap);
+    boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
+    
     /*
      * Determine what fonts to use.
      */
@@ -1999,6 +2401,9 @@ main(argc, argv)
     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);
@@ -2080,16 +2485,30 @@ main(argc, argv)
     }
 
     if (forceMono) {
-      fprintf(stderr, "%s: too few colors available; trying monochrome mode\n",
+      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)
+               appData.monoMode = True;
+      else
+               lowTimeWarningColor = *(Pixel *) vTo.addr;
     }
 
     if (appData.monoMode && appData.debugMode) {
-       fprintf(stderr, "white pixel = 0x%lx, black pixel = 0x%lx\n",
+       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  ||
@@ -2103,16 +2522,16 @@ main(argc, argv)
       {
          if (appData.colorize) {
              fprintf(stderr,
-                     "%s: can't parse color names; disabling colorization\n",
+                     _("%s: can't parse color names; disabling colorization\n"),
                      programName);
          }
          appData.colorize = FALSE;
       }
     textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
     textColors[ColorNone].attr = 0;
-    
-    XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
-    
+
+    //    XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
+
     /*
      * widget hierarchy
      */
@@ -2123,397 +2542,154 @@ main(argc, argv)
     } 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);
 
-    widgetList[j++] = whiteTimerWidget =
-      XtCreateWidget("whiteTime", labelWidgetClass,
-                    formWidget, timerArgs, XtNumber(timerArgs));
-    XtSetArg(args[0], XtNfont, clockFontStruct);
-    XtSetValues(whiteTimerWidget, args, 1);
-    
-    widgetList[j++] = blackTimerWidget =
-      XtCreateWidget("blackTime", labelWidgetClass,
-                    formWidget, timerArgs, XtNumber(timerArgs));
-    XtSetArg(args[0], XtNfont, clockFontStruct);
-    XtSetValues(blackTimerWidget, args, 1);
-    
     if (appData.titleInWindow) {
-       widgetList[j++] = titleWidget = 
-         XtCreateWidget("title", labelWidgetClass, formWidget,
-                        titleArgs, XtNumber(titleArgs));
+      /* todo check what this appdata does */
     }
 
     if (appData.showButtonBar) {
-      widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
+      /* TODO hide button bar if requested */
     }
 
-    widgetList[j++] = messageWidget =
-      XtCreateWidget("message", labelWidgetClass, formWidget,
-                    messageArgs, XtNumber(messageArgs));
-    
-    widgetList[j++] = boardWidget =
-      XtCreateWidget("board", widgetClass, formWidget, boardArgs,
-                    XtNumber(boardArgs));
 
-    XtManageChildren(widgetList, j);
-    
-    timerWidth = (boardWidth - sep) / 2;
-    XtSetArg(args[0], XtNwidth, timerWidth);
-    XtSetValues(whiteTimerWidget, args, 1);
-    XtSetValues(blackTimerWidget, args, 1);
-    
-    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);
-    }
+    if (appData.titleInWindow)
+      {
+       if (smallLayout)
+         {
+           /* make it small */
+           if (appData.showButtonBar)
+             {
 
-    /*
-     * 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);
-    XtSetValues(boardWidget, args, 1);
+             }
+         }
+       else
+         {
+           if (appData.showButtonBar)
+             {
+             }
+         }
+      }
+    else
+      {
+      }
 
-    XtRealizeWidget(shellWidget);
 
-    /*
-     * 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);
-#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 */
-    }
+    /* set some checkboxes in the menu according to appData */
 
-    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);
-    }
-    
-    /* !! 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 */
+    if (appData.alwaysPromoteToQueen)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Always Queen")),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.animateDragging)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Animate Dragging")),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.animate)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Animate Moving")),TRUE);
 
-    xBoardWindow = XtWindow(boardWidget);
-    
-    /* 
-     * 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.autoComment)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Comment")),TRUE);
+
+    if (appData.autoCallFlag)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Flag")),TRUE);
+
+    if (appData.autoFlipView)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Flip View")),TRUE);
+
+    if (appData.autoObserve)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Observe")),TRUE);
+
+    if (appData.autoRaiseBoard)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Raise Board")),TRUE);
+
+    if (appData.autoSaveGames)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Save")),TRUE);
+
+    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.showThinking) {
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
-                   args, 1);
-    }
-    if (appData.testLegality) {
-       XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
-                   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);
-    
-    /*
-     * Create a cursor for the board widget.
-     */
-    window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
-    XChangeWindowAttributes(xDisplay, xBoardWindow,
-                           CWCursor, &window_attributes);
-    
-    /*
-     * 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);
-    
-    CatchDeleteWindow(shellWidget, "QuitProc");
+    if (appData.highlightLastMove)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Highlight Last Move")),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.icsAlarm)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.ICS Alarm")),TRUE);
+
+    if (appData.ringBellAfterMoves)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Move Sound")),TRUE);
+
+    if (appData.oldSaveStyle)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Old Save Style")),TRUE);
+
+    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.Show Thinking")),TRUE);
+
+    if (appData.testLegality)
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Test Legality")),TRUE);
+
+    /* 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, False,
-                     (XtEventHandler) EventProc, NULL);
-    /* end why */
 
     InitBackEnd2();
-    
+
     if (errorExitStatus == -1) {
        if (appData.icsActive) {
            /* We now wait until we see "login:" from the ICS before
@@ -2528,8 +2704,22 @@ main(argc, argv)
            signal(SIGUSR1, CmailSigHandler);
        }
     }
+    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;
 }
 
@@ -2609,180 +2799,36 @@ ResetFrontEnd()
     return;
 }
 
-typedef struct {
-    char *name;
-    Boolean value;
-} Enables;
-
 void
 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.Show 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.Show 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);
+#endif
 }
 
 void
@@ -2808,7 +2854,7 @@ SetTrainingModeOn()
 {
   SetMenuEnables(trainingOnEnables);
   if (appData.showButtonBar) {
-    XtSetSensitive(buttonBarWidget, False);
+    //    XtSetSensitive(buttonBarWidget, False);
   }
   CommentPopDown();
 }
@@ -2818,7 +2864,7 @@ SetTrainingModeOff()
 {
   SetMenuEnables(trainingOffEnables);
   if (appData.showButtonBar) {
-    XtSetSensitive(buttonBarWidget, True);
+    //    XtSetSensitive(buttonBarWidget, True);
   }
 }
 
@@ -2838,8 +2884,8 @@ SetMachineThinkingEnables()
   case MachinePlaysBlack:
   case MachinePlaysWhite:
   case TwoMachinesPlay:
-    XtSetSensitive(XtNameToWidget(menuBarWidget,
-                                 ModeToWidgetName(gameMode)), True);
+//    XtSetSensitive(XtNameToWidget(menuBarWidget,
+//                               ModeToWidgetName(gameMode)), True);
     break;
   default:
     break;
@@ -2852,7 +2898,7 @@ SetMachineThinkingEnables()
  * Find a font that matches "pattern" that is as close as
  * possible to the targetPxlSize.  Prefer fonts that are k
  * pixels smaller to fonts that are k pixels larger.  The
- * pattern must be in the X Consortium standard format, 
+ * pattern must be in the X Consortium standard format,
  * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
  * The return value should be freed with XtFree when no
  * longer needed.
@@ -2864,12 +2910,40 @@ char *FindFont(pattern, targetPxlSize)
     char **fonts, *p, *best, *scalable, *scalableTail;
     int i, j, nfonts, minerr, err, pxlSize;
 
+#ifdef ENABLE_NLS
+    char **missing_list;
+    int missing_count;
+    char *def_string, *base_fnt_lst, strInt[3];
+    XFontSet fntSet;
+    XFontStruct **fnt_list;
+
+    base_fnt_lst = calloc(1, strlen(pattern) + 3);
+    sprintf(strInt, "%d", targetPxlSize);
+    p = strstr(pattern, "--");
+    strncpy(base_fnt_lst, pattern, p - pattern + 2);
+    strcat(base_fnt_lst, strInt);
+    strcat(base_fnt_lst, strchr(p + 2, '-'));
+
+    if ((fntSet = XCreateFontSet(xDisplay,
+                                 base_fnt_lst,
+                                 &missing_list,
+                                 &missing_count,
+                                 &def_string)) == NULL) {
+
+       fprintf(stderr, _("Unable to create font set.\n"));
+       exit (2);
+    }
+
+    nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
+#else
     fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
     if (nfonts < 1) {
-       fprintf(stderr, "%s: no fonts match pattern %s\n",
+       fprintf(stderr, _("%s: no fonts match pattern %s\n"),
                programName, pattern);
        exit(2);
     }
+#endif
+
     best = fonts[0];
     scalable = NULL;
     minerr = 999999;
@@ -2907,42 +2981,42 @@ char *FindFont(pattern, targetPxlSize)
         strcpy(p, best);
     }
     if (appData.debugMode) {
-        fprintf(debugFP, "resolved %s at pixel size %d\n  to %s\n",
+        fprintf(debugFP, _("resolved %s at pixel size %d\n  to %s\n"),
                pattern, targetPxlSize, p);
     }
-    XFreeFontNames(fonts);
+#ifdef ENABLE_NLS
+    if (missing_count > 0)
+       XFreeStringList(missing_list);
+    XFreeFontSet(xDisplay, fntSet);
+#else
+     XFreeFontNames(fonts);
+#endif
     return p;
 }
 
 void CreateGCs()
 {
+  /* 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*/
+
     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);
-    
-    if (appData.monoMode) {
-       gc_values.foreground = XWhitePixel(xDisplay, xScreen);
-       gc_values.background = XWhitePixel(xDisplay, xScreen);
-       highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);      
 
+    if (appData.monoMode) {
        gc_values.foreground = XWhitePixel(xDisplay, xScreen);
        gc_values.background = XBlackPixel(xDisplay, xScreen);
-       lightSquareGC = wbPieceGC 
+       lightSquareGC = wbPieceGC
          = XtGetGC(shellWidget, value_mask, &gc_values);
 
        gc_values.foreground = XBlackPixel(xDisplay, xScreen);
@@ -2964,18 +3038,10 @@ void CreateGCs()
            }
        }
     } 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);
@@ -2987,19 +3053,19 @@ void CreateGCs()
        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);
@@ -3010,423 +3076,49 @@ void CreateGCs()
     }
 }
 
-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);
-    }
-}
-
-void CreateXIMPieces()
+void CreatePieces()
 {
-    int piece, kind;
-    char buf[MSG_SIZ];
-    u_int ss;
-    static char *ximkind[] = { "ll", "ld", "dl", "dd" };
-    XImage *ximtemp;
-
-    ss = squareSize;
+  int i;
 
-    /* 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);
+  /* free if used 
+  for(i=0;i<MAXPIECES;i++)
+    {
+      if(SVGpieces[i])
+       {       
+         g_free(SVGpieces[i]);
+         SVGpieces[i]=NULL;
        }
-       fprintf(stderr, "\nLoading XIMs...\n");
-       /* Load pieces */
-       for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
-           fprintf(stderr, "%d", piece+1);
-           for (kind=0; kind<4; kind++) {
-               fprintf(stderr, ".");
-               sprintf(buf, "%s/%c%s%u.xim",
-                       ExpandPathName(appData.pixmapDirectory),
-                       ToLower(PieceToChar((ChessSquare)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,
-                       &(xpmPieceBitmap[kind][piece]),
-                       &(ximMaskPm[piece%6]));
-           }
-           fprintf(stderr," ");
-       }
-       /* Load light and dark squares */
-       /* If the LSQ and DSQ pieces don't exist, we will 
-          draw them with solid squares. */
-       sprintf(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 ");
-           sprintf(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];
-
-#if 0
-    /* Apparently some versions of Xpm don't define XpmFormat at all --tpm */
-    if (appData.debugMode) {
-       fprintf(stderr, "XPM Library Version: %d.%d%c\n", 
-               XpmFormat, XpmVersion, (char)('a' + XpmRevision - 1));
-    }
-#endif
-  
-    /* 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; piece++) {
-           for (kind=0; kind<4; kind++) {
-
-               if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,
-                                              pieces->xpm[piece][kind],
-                                              &(xpmPieceBitmap[kind][piece]),
-                                              NULL, &attr)) != 0) {
-                 fprintf(stderr, "Error %d loading XPM image \"%s\"\n",
-                         r, buf);
-                 exit(1); 
-               }       
-           }   
-       }
-       useImageSqs = 0;
-       xpmJailSquare = xpmLightSquare;
-    } else {
-       useImages = 1;
-       
-       fprintf(stderr, "\nLoading XPMs...\n");
-
-       /* Load pieces */
-       for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
-           fprintf(stderr, "%d ", piece+1);
-           for (kind=0; kind<4; kind++) {
-               sprintf(buf, "%s/%c%s%u.xpm",
-                       ExpandPathName(appData.pixmapDirectory),
-                       ToLower(PieceToChar((ChessSquare)piece)),
-                       xpmkind[kind], ss);
-               if (appData.debugMode) {
-                   fprintf(stderr, "(File:%s:) ", buf);
-               }
-               if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
-                                          &(xpmPieceBitmap[kind][piece]),
-                                          NULL, &attr)) != 0) {
-                   fprintf(stderr, "Error %d loading XPM file \"%s\"\n",
-                           r, buf);
-                   exit(1); 
-               }       
-           }   
-       }
-       /* 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 ");
-       sprintf(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 ");
-           sprintf(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 */  
-}
-#endif /* HAVE_LIBXPM */
+  /* reload these */
+  SVGLightSquare   = load_pixbuf("svg/LightSquare.svg",squareSize);
+  SVGDarkSquare    = load_pixbuf("svg/DarkSquare.svg",squareSize);
+  SVGNeutralSquare = load_pixbuf("svg/NeutralSquare.svg",squareSize);
 
-#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; piece++) {
-           sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
-                   ss, kind == SOLID ? 's' : 'o');
-           ReadBitmap(&pieceBitmap[kind][piece], buf, NULL, ss, ss);
-       }
-    }
-    
-    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; piece++) {
-           sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
-                   ss, kind == SOLID ? 's' : 'o');
-           ReadBitmap(&pieceBitmap[kind][piece], buf,
-                      bib->bits[kind][piece], ss, ss);
-       }
-    }
-    
-    XSynchronize(xDisplay, False); /* Work-around for xlib/xt
-                                     buffering bug */
-}
-#endif
 
-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];
+  /* get some defaults going */
+  for(i=WhitePawn; i<DemotePiece+1; i++)
+    SVGpieces[i]   = load_pixbuf("svg/NeutralSquare.svg",squareSize);
     
-    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);
-       if (errcode != BitmapSuccess) {
-           switch (errcode) {
-             case BitmapOpenFailed:
-               sprintf(msg, "Can't open bitmap file %s", fullname);
-               break;
-             case BitmapFileInvalid:
-               sprintf(msg, "Invalid bitmap in file %s", fullname);
-               break;
-             case BitmapNoMemory:
-               sprintf(msg, "Ran out of memory reading bitmap file %s",
-                       fullname);
-               break;
-             default:
-               sprintf(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;
-       }
-    }
-    if (bits == NULL) {
-       fprintf(stderr, "%s: No built-in bitmap for %s; giving up\n",
-               programName, name);
-       exit(1);
-    } else {
-       *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,
-                                   wreq, hreq);
-    }
-}
+  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);
 
-void CreateGrid()
-{
-    int i;
-    
-    if (lineGap == 0) return;
-    for (i = 0; i < BOARD_SIZE + 1; i++) {
-       gridSegments[i].x1 = 0;
-       gridSegments[i].x2 =
-         lineGap + BOARD_SIZE * (squareSize + lineGap);
-       gridSegments[i].y1 = gridSegments[i].y2
-         = lineGap / 2 + (i * (squareSize + lineGap));
+  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);
 
-       gridSegments[i + BOARD_SIZE + 1].y1 = 0;
-       gridSegments[i + BOARD_SIZE + 1].y2 =
-         BOARD_SIZE * (squareSize + lineGap);
-       gridSegments[i + BOARD_SIZE + 1].x1 =
-         gridSegments[i + BOARD_SIZE + 1].x2
-           = lineGap / 2 + (i * (squareSize + lineGap));
-    }
+  return;
 }
 
+
 static void MenuBarSelect(w, addr, index)
      Widget w;
      caddr_t addr;
@@ -3458,15 +3150,16 @@ void CreateMenuBarPopup(parent, name, mb)
            entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,
                                          menu, args, j);
        } else {
+          XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string)));
            entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass,
-                                         menu, args, j);
+                                         menu, args, j+1);
            XtAddCallback(entry, XtNcallback,
                          (XtCallbackProc) MenuBarSelect,
                          (caddr_t) mi->proc);
        }
        mi++;
     }
-}      
+}
 
 Widget CreateMenuBar(mb)
      Menu *mb;
@@ -3490,10 +3183,14 @@ Widget CreateMenuBar(mb)
        XtSetArg(args[j], XtNmenuName, XtNewString(menuName));  j++;
        if (tinyLayout) {
            char shortName[2];
-           shortName[0] = mb->name[0];
+            shortName[0] = _(mb->name)[0];
            shortName[1] = NULLCHAR;
            XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++;
        }
+      else {
+          XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++;
+      }
+
        XtSetArg(args[j], XtNborderWidth, 0);                   j++;
        anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,
                                       menuBar, args, j);
@@ -3503,38 +3200,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++;
-       }
-       button = XtCreateManagedWidget(mi->string, commandWidgetClass,
-                                      buttonBar, args, j);
-       XtAddCallback(button, XtNcallback,
-                     (XtCallbackProc) MenuBarSelect,
-                     (caddr_t) mi->proc);
-       mi++;
-    }
-    return buttonBar;
-}     
 
 Widget
 CreatePieceMenu(name, color)
@@ -3548,16 +3213,17 @@ CreatePieceMenu(name, color)
 
     menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
                              boardWidget, args, 0);
-    
+
     for (i = 0; i < PIECE_MENU_SIZE; i++) {
        String item = pieceMenuStrings[color][i];
-       
+
        if (strcmp(item, "----") == 0) {
            entry = XtCreateManagedWidget(item, smeLineObjectClass,
                                          menu, NULL, 0);
        } else {
+          XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
            entry = XtCreateManagedWidget(item, smeBSBObjectClass,
-                                         menu, NULL, 0);
+                                menu, args, 1);
            selection = pieceMenuTranslation[color][i];
            XtAddCallback(entry, XtNcallback,
                          (XtCallbackProc) PieceMenuSelect,
@@ -3579,32 +3245,33 @@ 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 {
-           entry = XtCreateManagedWidget(item, smeBSBObjectClass,
-                                         dropMenu, NULL, 0);
-           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()
 {
@@ -3623,7 +3290,7 @@ void SetupDropMenu()
                                       && !appData.icsActive));
        count = 0;
        while (p && *p++ == dmEnables[i].piece) count++;
-       sprintf(label, "%s  %d", dmEnables[i].widget, count);
+       snprintf(label, sizeof(label), "%s  %d", dmEnables[i].widget, count);
        j = 0;
        XtSetArg(args[j], XtNlabel, label); j++;
        XtSetValues(entry, args, j);
@@ -3658,17 +3325,17 @@ void PieceMenuPopup(w, event, params, num_params)
       default:
        return;
     }
-    
-    if (((pmFromX = EventToSquare(event->xbutton.x, BOARD_SIZE)) < 0) ||
-       ((pmFromY = EventToSquare(event->xbutton.y, BOARD_SIZE)) < 0)) {
+
+    if (((pmFromX = EventToSquare(event->xbutton.x, BOARD_WIDTH)) < 0) ||
+       ((pmFromY = EventToSquare(event->xbutton.y, BOARD_HEIGHT)) < 0)) {
        pmFromX = pmFromY = -1;
        return;
     }
     if (flipView)
-      pmFromX = BOARD_SIZE - 1 - pmFromX;
+      pmFromX = BOARD_WIDTH - 1 - pmFromX;
     else
-      pmFromY = BOARD_SIZE - 1 - pmFromY;
-    
+      pmFromY = BOARD_HEIGHT - 1 - pmFromY;
+
     XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu));
 }
 
@@ -3724,7 +3391,7 @@ void BlackClock(w, event, prms, nprms)
 int EventToSquare(x, limit)
      int x;
 {
-    if (x <= 0) 
+    if (x <= 0)
       return -2;
     if (x < lineGap)
       return -1;
@@ -3743,26 +3410,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) {
-       x = lineGap/2 + ((BOARD_SIZE-1)-file) * 
+
+    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_SIZE-1)-rank) * 
+       y = lineGap/2 + ((BOARD_HEIGHT-1)-rank) *
          (squareSize + lineGap);
-    }
-    
-    XDrawRectangle(xDisplay, xBoardWindow, gc, x, y,
-                  squareSize+lineGap, 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);
+      }
+
+    cairo_stroke (cr);
+
+    /* free memory */
+    cairo_destroy (cr);
+
+    return;
 }
 
 int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1;
@@ -3772,26 +3471,34 @@ void
 SetHighlights(fromX, fromY, toX, toY)
      int fromX, fromY, toX, toY;
 {
-    if (hi1X != fromX || hi1Y != fromY) {
-       if (hi1X >= 0 && hi1Y >= 0) {
-           drawHighlight(hi1X, hi1Y, lineGC);
-       }
-       if (fromX >= 0 && fromY >= 0) {
-           drawHighlight(fromX, fromY, highlineGC);
-       }
-    }
-    if (hi2X != toX || hi2Y != toY) {
-       if (hi2X >= 0 && hi2Y >= 0) {
-           drawHighlight(hi2X, hi2Y, lineGC);
-       }
-       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 (toX >= 0 && toY >= 0)
+         {
+           drawHighlight(toX, toY, LINE_TYPE_HIGHLIGHT);
+         }
+      }
     hi1X = fromX;
     hi1Y = fromY;
     hi2X = toX;
     hi2Y = toY;
+
+    return;
 }
 
 void
@@ -3805,26 +3512,35 @@ 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
@@ -3838,275 +3554,246 @@ static void BlankSquare(x, y, color, piece, dest)
      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;
+      GdkPixbuf *pb;
+
+      switch (color) 
+       {
+       case 0: /* dark */
+         pb = SVGDarkSquare;
+         break;
+       case 1: /* light */
+         pb = SVGLightSquare;
+         break;
+       case 2: /* neutral */
+       default:
+         pb = SVGNeutralSquare;
+         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);
-    }
-}
-
-/*
-   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;
-    }
+      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;
-{
-    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;
-    }
+  /* 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 ;
 }
 
-static void colorDrawPieceImage(piece, square_color, x, y, dest)
-     ChessSquare piece;
-     int square_color, x, y;
-     Drawable dest;
+/* [HR] determine square color depending on chess variant. */
+static int SquareColor(row, column)
+     int row, column;
 {
-    int kind;
+    int square_color;
 
-    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;
+    if (gameInfo.variant == VariantXiangqi) {
+        if (column >= 3 && column <= 5 && row >= 0 && row <= 2) {
+            square_color = 1;
+        } else if (column >= 3 && column <= 5 && row >= 7 && row <= 9) {
+            square_color = 0;
+        } else if (row <= 4) {
+            square_color = 0;
+        } else {
+            square_color = 1;
+        }
+    } else {
+        square_color = ((column + row) % 2) == 1;
     }
-    XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
-             dest, wlPieceGC, 0, 0,
-             squareSize, squareSize, x, y);            
-}
 
-typedef void (*DrawFunc)();
+    /* [hgm] holdings: next line makes all holdings squares light */
+    if(column < BOARD_LEFT || column >= BOARD_RGHT) square_color = 1;
 
-DrawFunc ChooseDrawFunc()
-{
-    if (appData.monoMode) {
-       if (DefaultDepth(xDisplay, xScreen) == 1) {
-           return monoDrawPiece_1bit;
-       } else {
-           return monoDrawPiece;
-       }
-    } else {
-       if (useImages)
-         return colorDrawPieceImage;
-       else
-         return colorDrawPiece;
-    }
+    return square_color;
 }
 
 void DrawSquare(row, column, piece, do_flash)
      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) {
-       x = lineGap + ((BOARD_SIZE-1)-column) * 
+
+    /* 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_SIZE-1)-row) * 
+       y = lineGap + ((BOARD_HEIGHT-1)-row) *
          (squareSize + lineGap);
-    }
-    
-    square_color = ((column + row) % 2) == 1;
-    
-    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);
+    square_color = SquareColor(row, column);
 
-               BlankSquare(x, y, square_color, piece, xBoardWindow);
-               XSync(xDisplay, False);
-               do_flash_delay(flash_delay);
-           }
-       }
-       drawfunc(piece, square_color, x, y, xBoardWindow);
-    }
-       
-    string[1] = NULLCHAR;
-    if (appData.showCoords && row == (flipView ? 7 : 0)) {
-       string[0] = 'a' + column;
-       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 ? 7 : 0)) {
-       string[0] = '1' + 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);
-       }           
-    }   
-}
+    // [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);
 
+       // [HGM] print piece counts next to holdings
+       string[1] = NULLCHAR;
+       if(piece > 1)
+         {
+           cairo_text_extents_t extents;
+           cairo_t *cr;
+           int  xpos, ypos;
 
-/* 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;
+           /* get a cairo_t */
+           cr = gdk_cairo_create (GDK_WINDOW(GUI_Board->window));
 
-    switch (event->type) {
-      case Expose:
-       if (event->xexpose.count > 0) return;  /* no clipping is done */
-       XDrawPosition(widget, True, NULL);
-       break;
-      default:
-       return;
-    }
-}
-/* end why */
+           string[0] = '0' + piece;
 
-void DrawPosition(fullRedraw, board)
-     /*Boolean*/int fullRedraw;
-     Board board;
-{
-    XDrawPosition(boardWidget, fullRedraw, board);
+           /* 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);
+           cairo_text_extents (cr, string, &extents);
+
+           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;
+             }
+
+           /* 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)
+                 {
+
+                   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)
@@ -4114,9 +3801,9 @@ static int too_many_diffs(b1, b2)
 {
     int i, j;
     int c = 0;
-  
-    for (i=0; i<BOARD_SIZE; ++i) {
-       for (j=0; j<BOARD_SIZE; ++j) {
+
+    for (i=0; i<BOARD_HEIGHT; ++i) {
+       for (j=0; j<BOARD_WIDTH; ++j) {
            if (b1[i][j] != b2[i][j]) {
                if (++c > 4)    /* Castling causes 4 diffs */
                  return 1;
@@ -4138,9 +3825,9 @@ static int castling_matrix[4][5] = {
 
 /* Checks whether castling occurred. If it did, *rrow and *rcol
    are set to the destination (row,col) of the rook that moved.
-   
+
    Returns 1 if castling occurred, 0 if not.
-   
+
    Note: Only handles a max of 1 castling move, so be sure
    to call too_many_diffs() first.
    */
@@ -4179,119 +3866,160 @@ static int damage[BOARD_SIZE][BOARD_SIZE];
 /*
  * 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;
-    
-    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);
-    }
+  int i, j, do_flash;
+  static int lastFlipView = 0;
+  static int lastBoardValid = 0;
+  static Board lastBoard;
+  int rrow, rcol;
 
-    /*
-     * It would be simpler to clear the window with XClearWindow()
-     * but this causes a very distracting flicker.
-     */
-    
-    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];
+  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 (!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];
            }
        }
 
-       /* 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_SIZE; i++)
-         for (j = 0; j < BOARD_SIZE; 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_SIZE; i++)
-         for (j = 0; j < BOARD_SIZE; 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_SIZE + 1) * 2);
-       
-       for (i = 0; i < BOARD_SIZE; i++)
-         for (j = 0; j < BOARD_SIZE; 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;
+
+         /* get a cairo_t */
+         cr = gdk_cairo_create (GDK_WINDOW(GUI_Board->window));
+
+         cairo_set_line_width (cr, lineGap);
+
+         /* TODO: use appdata colors */
+         cairo_set_source_rgba (cr, 0, 1, 0, 1.0);
+
+         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));
+
+             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));
+
+             cairo_move_to (cr, x1, y1);
+             cairo_rel_line_to (cr, 0, y2);
+             cairo_stroke (cr);
+           }
+
+         /* 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;
          }
     }
 
-    CopyBoard(lastBoard, board);
-    lastBoardValid = 1;
-    lastFlipView = flipView;
+  CopyBoard(lastBoard, board);
+  lastBoardValid = 1;
+  lastFlipView = flipView;
 
-    /* Draw highlights */
-    if (pm1X >= 0 && pm1Y >= 0) {
-      drawHighlight(pm1X, pm1Y, prelineGC);
+  /* Draw highlights */
+  if (pm1X >= 0 && pm1Y >= 0)
+    {
+      drawHighlight(pm1X, pm1Y, LINE_TYPE_PRE);
     }
-    if (pm2X >= 0 && pm2Y >= 0) {
-      drawHighlight(pm2X, pm2Y, prelineGC);
+  if (pm2X >= 0 && pm2Y >= 0)
+    {
+      drawHighlight(pm2X, pm2Y, LINE_TYPE_PRE);
     }
-    if (hi1X >= 0 && hi1Y >= 0) {
-      drawHighlight(hi1X, hi1Y, highlineGC);
+  if (hi1X >= 0 && hi1Y >= 0)
+    {
+      drawHighlight(hi1X, hi1Y, LINE_TYPE_HIGHLIGHT);
     }
-    if (hi2X >= 0 && hi2Y >= 0) {
-      drawHighlight(hi2X, hi2Y, highlineGC);
+  if (hi2X >= 0 && hi2Y >= 0)
+    {
+      drawHighlight(hi2X, hi2Y, LINE_TYPE_HIGHLIGHT);
     }
 
-    /* If piece being dragged around board, must redraw that too */
-    DrawDragPiece();
+  /* If piece being dragged around board, must redraw that too */
+  DrawDragPiece();
 
-    XSync(xDisplay, False);
+  return;
 }
 
-
-/*
- * event handler for redrawing the board
- */
-void DrawPositionProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    XDrawPosition(w, True, NULL);
-}
-
-
 /*
  * 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;
@@ -4300,16 +4028,46 @@ void HandleUserMove(w, event, prms, nprms)
 {
     int x, y;
     Boolean saveAnimate;
-    static int second = 0;
-       
+    static int second = 0, promotionChoice = 0;
+    ChessMove moveType;
+
     if (w != boardWidget || errorExitStatus != -1) return;
 
+    x = EventToSquare(event->xbutton.x, BOARD_WIDTH);
+    y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);
+    if (!flipView && y >= 0) {
+       y = BOARD_HEIGHT - 1 - y;
+    }
+    if (flipView && x >= 0) {
+       x = BOARD_WIDTH - 1 - x;
+    }
+
+    if(promotionChoice) { // we are waiting for a click to indicate promotion piece
+       if(event->type == ButtonRelease) return; // ignore upclick of click-click destination
+       promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel
+       if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y);
+       if(gameInfo.holdingsWidth && 
+               (WhiteOnMove(currentMove) 
+                       ? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0
+                       : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) {
+           // click in right holdings, for determining promotion piece
+           ChessSquare p = boards[currentMove][y][x];
+           if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p);
+           if(p != EmptySquare) {
+               FinishMove(NormalMove, fromX, fromY, toX, toY, ToLower(PieceToChar(p)));
+               fromX = fromY = -1;
+               return;
+           }
+       }
+       DrawPosition(FALSE, boards[currentMove]);
+       return;
+    }
     if (event->type == ButtonPress) ErrorPopDown();
 
     if (promotionUp) {
        if (event->type == ButtonPress) {
-           XtPopdown(promotionShell);
-           XtDestroyWidget(promotionShell);
+//         XtPopdown(promotionShell);
+//         XtDestroyWidget(promotionShell);
            promotionUp = False;
            ClearHighlights();
            fromX = fromY = -1;
@@ -4317,19 +4075,18 @@ void HandleUserMove(w, event, prms, nprms)
            return;
        }
     }
-    
-    x = EventToSquare(event->xbutton.x, BOARD_SIZE);
-    y = EventToSquare(event->xbutton.y, BOARD_SIZE);
-    if (!flipView && y >= 0) {
-       y = BOARD_SIZE - 1 - y;
-    }
-    if (flipView && x >= 0) {
-       x = BOARD_SIZE - 1 - x;
-    }
+
+    /* [HGM] holdings: next 5 lines: ignore all clicks between board and holdings */
+    if(event->type == ButtonPress
+            && ( x == BOARD_LEFT-1 || 
+                x == BOARD_RGHT   || 
+                (x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize ) || 
+                (x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize)) )
+       return;
 
     if (fromX == -1) {
        if (event->type == ButtonPress) {
-           /* First square */ 
+           /* First square, prepare to drag */
            if (OKToStartUserMove(x, y)) {
                fromX = x;
                fromY = y;
@@ -4338,40 +4095,14 @@ void HandleUserMove(w, event, prms, nprms)
                if (appData.highlightDragging) {
                    SetHighlights(x, y, -1, -1);
                }
-           } 
+           }
        }
        return;
     }
 
     /* fromX != -1 */
-    if (event->type == ButtonPress && gameMode != EditPosition &&
-       x >= 0 && y >= 0) {
-       ChessSquare fromP;
-       ChessSquare toP;
-       /* Check if clicking again on the same color piece */
-       fromP = boards[currentMove][fromY][fromX];
-       toP = boards[currentMove][y][x];
-       if ((WhitePawn <= fromP && fromP <= WhiteKing &&
-            WhitePawn <= toP && toP <= WhiteKing) ||
-           (BlackPawn <= fromP && fromP <= BlackKing &&
-            BlackPawn <= toP && toP <= BlackKing)) {
-           /* Clicked again on same color piece -- changed his mind */
-           second = (x == fromX && y == fromY);
-           if (appData.highlightDragging) {
-               SetHighlights(x, y, -1, -1);
-           } else {
-               ClearHighlights();
-           }
-           if (OKToStartUserMove(x, y)) {
-               fromX = x;
-               fromY = y;
-               DragPieceBegin(event->xbutton.x, event->xbutton.y);
-           }
-           return;
-       }
-    }
-
     if (event->type == ButtonRelease &&        x == fromX && y == fromY) {
+    /* Click on single square in stead of drag-drop */
        DragPieceEnd(event->xbutton.x, event->xbutton.y);
        if (appData.animateDragging) {
            /* Undo animation damage if any */
@@ -4389,9 +4120,36 @@ void HandleUserMove(w, event, prms, nprms)
            SetHighlights(x, y, -1, -1);
        }
        return;
-    }  
+    }
 
-    /* Completed move */
+    moveType = UserMoveTest(fromX, fromY, x, y, NULLCHAR, event->type == ButtonRelease);
+
+    if (moveType == Comment) { // kludge for indicating capture-own on Press
+      /* Clicked again on same color piece -- changed his mind */
+      /* note that re-clicking same square always hits same color piece */
+      second = (x == fromX && y == fromY);
+      if (appData.highlightDragging) {
+       SetHighlights(x, y, -1, -1);
+      } else {
+       ClearHighlights();
+      }
+      if (OKToStartUserMove(x, y)) {
+       fromX = x;
+       fromY = y;
+       DragPieceBegin(event->xbutton.x, event->xbutton.y);
+      }
+      return;
+    }
+
+    if(moveType == AmbiguousMove) { // kludge to indicate edit-position move
+      fromX = fromY = -1; 
+      ClearHighlights();
+      DragPieceEnd(event->xbutton.x, event->xbutton.y);
+      DrawPosition(FALSE, boards[currentMove]);
+      return;
+    }
+
+    /* Complete move; (x,y) is now different from (fromX, fromY) on both Press and Release */
     toX = x;
     toY = y;
     saveAnimate = appData.animate;
@@ -4413,22 +4171,38 @@ void HandleUserMove(w, event, prms, nprms)
        /* Don't animate move and drag both */
        appData.animate = FALSE;
     }
-    if (IsPromotion(fromX, fromY, toX, toY)) {
-       if (appData.alwaysPromoteToQueen) {
-           UserMoveEvent(fromX, fromY, toX, toY, 'q');
+    if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight ||
+        (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) &&
+            appData.alwaysPromoteToQueen) { // promotion, but no choice
+      FinishMove(moveType, fromX, fromY, toX, toY, 'q');
+    } else
+    if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) {
+       SetHighlights(fromX, fromY, toX, toY);
+       if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) {
+           // [HGM] super: promotion to captured piece selected from holdings
+           ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX];
+           promotionChoice = TRUE;
+           // kludge follows to temporarily execute move on display, without promoting yet
+           boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank
+           boards[currentMove][toY][toX] = p;
+           DrawPosition(FALSE, boards[currentMove]);
+           boards[currentMove][fromY][fromX] = p; // take back, but display stays
+           boards[currentMove][toY][toX] = q;
+           DisplayMessage("Click in holdings to choose piece", "");
+           return;
+       }
+       PromotionPopUp();
+       goto skipClearingFrom; // the skipped stuff is done asynchronously by PromotionCallback
+    } else
+    if(moveType != ImpossibleMove) { // valid move, but no promotion
+      FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);
+    } else { // invalid move; could have set premove
+      ClearHighlights();
+    }
            if (!appData.highlightLastMove || gotPremove) ClearHighlights();
            if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
            fromX = fromY = -1;
-       } else {
-           SetHighlights(fromX, fromY, toX, toY);
-           PromotionPopUp();
-       }
-    } else {
-       UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
-       if (!appData.highlightLastMove || gotPremove) ClearHighlights();
-       if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
-       fromX = fromY = -1;
-    }
+skipClearingFrom:
     appData.animate = saveAnimate;
     if (appData.animate || appData.animateDragging) {
        /* Undo animation damage if needed */
@@ -4487,12 +4261,8 @@ Widget CommentCreate(name, text, mutable, callback, lines)
     XtSetArg(args[j], XtNright, XtChainRight);  j++;
     XtSetArg(args[j], XtNresizable, True);  j++;
     XtSetArg(args[j], XtNwidth, bw_width);  j++; /*force wider than buttons*/
-#if 0
-    XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded);  j++;
-#else
     /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
     XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways);  j++;
-#endif
     XtSetArg(args[j], XtNautoFill, True);  j++;
     XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
     edit =
@@ -4506,7 +4276,7 @@ Widget CommentCreate(name, text, mutable, callback, lines)
        XtSetArg(args[j], XtNleft, XtChainLeft); j++;
        XtSetArg(args[j], XtNright, XtChainLeft); j++;
        b_ok =
-         XtCreateManagedWidget("ok", commandWidgetClass, form, args, j);
+         XtCreateManagedWidget(_("ok"), commandWidgetClass, form, args, j);
        XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);
 
        j = 0;
@@ -4517,7 +4287,7 @@ Widget CommentCreate(name, text, mutable, callback, lines)
        XtSetArg(args[j], XtNleft, XtChainLeft); j++;
        XtSetArg(args[j], XtNright, XtChainLeft); j++;
        b_cancel =
-         XtCreateManagedWidget("cancel", commandWidgetClass, form, args, j);
+         XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j);
        XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);
 
        j = 0;
@@ -4528,7 +4298,7 @@ Widget CommentCreate(name, text, mutable, callback, lines)
        XtSetArg(args[j], XtNleft, XtChainLeft); j++;
        XtSetArg(args[j], XtNright, XtChainLeft); j++;
        b_clear =
-         XtCreateManagedWidget("clear", commandWidgetClass, form, args, j);
+         XtCreateManagedWidget(_("clear"), commandWidgetClass, form, args, j);
        XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);
     } else {
        j = 0;
@@ -4538,7 +4308,7 @@ Widget CommentCreate(name, text, mutable, callback, lines)
        XtSetArg(args[j], XtNleft, XtChainLeft); j++;
        XtSetArg(args[j], XtNright, XtChainLeft); j++;
        b_close =
-         XtCreateManagedWidget("close", commandWidgetClass, form, args, j);
+         XtCreateManagedWidget(_("close"), commandWidgetClass, form, args, j);
        XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);
 
        j = 0;
@@ -4549,7 +4319,7 @@ Widget CommentCreate(name, text, mutable, callback, lines)
        XtSetArg(args[j], XtNleft, XtChainLeft); j++;
        XtSetArg(args[j], XtNright, XtChainLeft); j++;
        b_edit =
-         XtCreateManagedWidget("edit", commandWidgetClass, form, args, j);
+         XtCreateManagedWidget(_("edit"), commandWidgetClass, form, args, j);
        XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);
     }
 
@@ -4645,12 +4415,8 @@ Widget MiscCreate(name, text, mutable, callback, lines)
     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
     XtSetArg(args[j], XtNright, XtChainRight);  j++;
     XtSetArg(args[j], XtNresizable, True);  j++;
-#if 0
-    XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded);  j++;
-#else
     /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
     XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways);  j++;
-#endif
     XtSetArg(args[j], XtNautoFill, True);  j++;
     XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
     edit =
@@ -4714,7 +4480,7 @@ void EditCommentPopUp(index, title, text)
 
     if (editShell == NULL) {
        editShell =
-         CommentCreate(title, text, True, EditCommentCallback, 4); 
+         CommentCreate(title, text, True, EditCommentCallback, 4);
        XtRealizeWidget(editShell);
        CatchDeleteWindow(editShell, "EditCommentPopDown");
     } else {
@@ -4750,16 +4516,16 @@ void EditCommentCallback(w, client_data, call_data)
     XtSetArg(args[j], XtNlabel, &name);  j++;
     XtGetValues(w, args, j);
 
-    if (strcmp(name, "ok") == 0) {
+    if (strcmp(name, _("ok")) == 0) {
        edit = XtNameToWidget(editShell, "*form.text");
        j = 0;
        XtSetArg(args[j], XtNstring, &val); j++;
        XtGetValues(edit, args, j);
        ReplaceComment(savedIndex, val);
        EditCommentPopDown();
-    } else if (strcmp(name, "cancel") == 0) {
+    } else if (strcmp(name, _("cancel")) == 0) {
        EditCommentPopDown();
-    } else if (strcmp(name, "clear") == 0) {
+    } else if (strcmp(name, _("clear")) == 0) {
        edit = XtNameToWidget(editShell, "*form.text");
        XtCallActionProc(edit, "select-all", NULL, NULL, 0);
        XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
@@ -4791,9 +4557,9 @@ void ICSInputBoxPopUp()
     Widget edit;
     Arg args[16];
     int j;
-    char *title = "ICS Input";
+    char *title = _("ICS Input");
     XtTranslations tr;
-       
+
     if (ICSInputShell == NULL) {
        ICSInputShell = MiscCreate(title, "", True, NULL, 1);
        tr = XtParseTranslationTable(ICSInputTranslations);
@@ -4801,7 +4567,7 @@ void ICSInputBoxPopUp()
        XtOverrideTranslations(edit, tr);
        XtRealizeWidget(ICSInputShell);
        CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");
-       
+
     } else {
        edit = XtNameToWidget(ICSInputShell, "*form.text");
        j = 0;
@@ -4829,7 +4595,7 @@ void ICSInputSendText()
     int j;
     Arg args[16];
     String val;
-  
+
     edit = XtNameToWidget(ICSInputShell, "*form.text");
     j = 0;
     XtSetArg(args[j], XtNstring, &val); j++;
@@ -4926,9 +4692,9 @@ void CommentCallback(w, client_data, call_data)
     XtSetArg(args[j], XtNlabel, &name);  j++;
     XtGetValues(w, args, j);
 
-    if (strcmp(name, "close") == 0) {
+    if (strcmp(name, _("close")) == 0) {
        CommentPopDown();
-    } else if (strcmp(name, "edit") == 0) {
+    } else if (strcmp(name, _("edit")) == 0) {
        CommentPopDown();
        EditCommentEvent();
     }
@@ -4958,6 +4724,7 @@ void AnalysisPopDown()
     XtPopdown(analysisShell);
     XSync(xDisplay, False);
     analysisUp = False;
+    if (appData.icsEngineAnalyze) ExitAnalyzeMode();    /* [DM] icsEngineAnalyze */
 }
 
 
@@ -4973,45 +4740,46 @@ void FileNamePopUp(label, def, proc, openMode)
     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,
+
+    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);
 }
@@ -5031,15 +4799,15 @@ void FileNameCallback(w, client_data, call_data)
 {
     String name;
     Arg args[16];
-    
+
     XtSetArg(args[0], XtNlabel, &name);
     XtGetValues(w, args, 1);
-    
-    if (strcmp(name, "cancel") == 0) {
+
+    if (strcmp(name, _("cancel")) == 0) {
         FileNamePopDown();
         return;
     }
-    
+
     FileNameAction(w, NULL, NULL, NULL);
 }
 
@@ -5056,7 +4824,7 @@ void FileNameAction(w, event, prms, nprms)
     int index;
 
     name = XawDialogGetValueString(w = XtParent(w));
-    
+
     if ((name != NULL) && (*name != NULLCHAR)) {
        strcpy(buf, name);
        XtPopdown(w = XtParent(XtParent(w)));
@@ -5072,12 +4840,12 @@ void FileNameAction(w, event, prms, nprms)
        }
        fullname = ExpandPathName(buf);
        if (!fullname) {
-           ErrorPopUp("Error", "Can't open file", FALSE);
+           ErrorPopUp(_("Error"), _("Can't open file"), FALSE);
        }
        else {
            f = fopen(fullname, fileOpenMode);
            if (f == NULL) {
-               DisplayError("Failed to open file", errno);
+               DisplayError(_("Failed to open file"), errno);
            } else {
                (void) (*fileProc)(f, index, buf);
            }
@@ -5085,7 +4853,7 @@ void FileNameAction(w, event, prms, nprms)
        ModeHighlight();
        return;
     }
-    
+
     XtPopdown(w = XtParent(XtParent(w)));
     XtDestroyWidget(w);
     filenameUp = False;
@@ -5103,57 +4871,74 @@ void PromotionPopUp()
     j = 0;
     XtSetArg(args[j], XtNwidth, &bw_width); j++;
     XtGetValues(boardWidget, args, j);
-    
+
     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));
-    
+
     j = 0;
-    XtSetArg(args[j], XtNlabel, "Promote pawn to what?"); j++;
+    XtSetArg(args[j], XtNlabel, _("Promote to what?")); j++;
     XtSetArg(args[j], XtNborderWidth, 0); j++;
     dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
                                   layout, args, j);
-    
-    XawDialogAddButton(dialog, "Queen", PromotionCallback, 
+
+  if(gameInfo.variant != VariantShogi) {
+    XawDialogAddButton(dialog, _("Queen"), PromotionCallback,
                       (XtPointer) dialog);
-    XawDialogAddButton(dialog, "Rook", PromotionCallback, 
+    XawDialogAddButton(dialog, _("Rook"), PromotionCallback,
                       (XtPointer) dialog);
-    XawDialogAddButton(dialog, "Bishop", PromotionCallback, 
+    XawDialogAddButton(dialog, _("Bishop"), PromotionCallback,
                       (XtPointer) dialog);
-    XawDialogAddButton(dialog, "Knight", PromotionCallback, 
+    XawDialogAddButton(dialog, _("Knight"), PromotionCallback,
                       (XtPointer) dialog);
     if (!appData.testLegality || gameInfo.variant == VariantSuicide ||
         gameInfo.variant == VariantGiveaway) {
-      XawDialogAddButton(dialog, "King", PromotionCallback, 
+      XawDialogAddButton(dialog, _("King"), PromotionCallback,
                         (XtPointer) dialog);
     }
-    XawDialogAddButton(dialog, "cancel", PromotionCallback, 
+    if(gameInfo.variant == VariantCapablanca ||
+       gameInfo.variant == VariantGothic ||
+       gameInfo.variant == VariantCapaRandom) {
+      XawDialogAddButton(dialog, _("Archbishop"), PromotionCallback,
+                        (XtPointer) dialog);
+      XawDialogAddButton(dialog, _("Chancellor"), PromotionCallback,
+                        (XtPointer) dialog);
+    }
+  } else // [HGM] shogi
+  {
+      XawDialogAddButton(dialog, _("Promote"), PromotionCallback,
+                        (XtPointer) dialog);
+      XawDialogAddButton(dialog, _("Defer"), PromotionCallback,
+                        (XtPointer) dialog);
+  }
+    XawDialogAddButton(dialog, _("cancel"), PromotionCallback,
                       (XtPointer) dialog);
-    
+
     XtRealizeWidget(promotionShell);
     CatchDeleteWindow(promotionShell, "PromotionPopDown");
-    
+
     j = 0;
     XtSetArg(args[j], XtNwidth, &pw_width); j++;
     XtGetValues(promotionShell, args, j);
-    
+
     XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
                      lineGap + squareSize/3 +
-                     ((toY == 7) ^ (flipView) ?
+                     ((toY == BOARD_HEIGHT-1) ^ (flipView) ?
                       0 : 6*(squareSize + lineGap)), &x, &y);
-    
+
     j = 0;
     XtSetArg(args[j], XtNx, x); j++;
     XtSetArg(args[j], XtNy, y); j++;
     XtSetValues(promotionShell, args, j);
-    
+
     XtPopup(promotionShell, XtGrabNone);
-    
+
     promotionUp = True;
 }
 
@@ -5172,25 +4957,29 @@ void PromotionCallback(w, client_data, call_data)
     String name;
     Arg args[16];
     int promoChar;
-    
+
     XtSetArg(args[0], XtNlabel, &name);
     XtGetValues(w, args, 1);
-    
+
     PromotionPopDown();
-    
+
     if (fromX == -1) return;
-    
-    if (strcmp(name, "cancel") == 0) {
+
+    if (strcmp(name, _("cancel")) == 0) {
        fromX = fromY = -1;
        ClearHighlights();
        return;
-    } else if (strcmp(name, "Knight") == 0) {
+    } else if (strcmp(name, _("Knight")) == 0) {
        promoChar = 'n';
+    } else if (strcmp(name, _("Promote")) == 0) {
+       promoChar = '+';
+    } else if (strcmp(name, _("Defer")) == 0) {
+       promoChar = '=';
     } else {
        promoChar = ToLower(name[0]);
     }
 
-    UserMoveEvent(fromX, fromY, toX, toY, promoChar);
+    FinishMove(NormalMove, fromX, fromY, toX, toY, promoChar);
 
     if (!appData.highlightLastMove || gotPremove) ClearHighlights();
     if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
@@ -5213,77 +5002,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;
-    
-    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*/
+  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], 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 */
@@ -5292,7 +5045,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;
 }
 
@@ -5300,7 +5053,7 @@ void FreezeUI()
 void ThawUI()
 {
   if (!frozen) return;
-  XtRemoveGrab(messageWidget);
+  //  XtRemoveGrab(messageWidget);
   frozen = 0;
 }
 
@@ -5344,84 +5097,47 @@ char *ModeToWidgetName(mode)
       case EndOfGame:
        return NULL;
     }
-}     
+}
 
 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) {
-#if 0
-         if (pausing) {
-           XtSetArg(args[0], XtNbackground, buttonForegroundPixel);
-           XtSetArg(args[1], XtNforeground, buttonBackgroundPixel);
-         } else {
-           XtSetArg(args[0], XtNbackground, buttonBackgroundPixel);
-           XtSetArg(args[1], XtNforeground, buttonForegroundPixel);
-         }
-#else
-         /* 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);
-         }
-#endif
-         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);
-    }
+    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();
-    AnalysisPopDown();
-}
 
 int LoadGamePopUp(f, gameNumber, title)
      FILE *f;
@@ -5429,85 +5145,27 @@ int LoadGamePopUp(f, gameNumber, title)
      char *title;
 {
     cmailMsgLoaded = FALSE;
-    if (gameNumber == 0) {
+
+    if (gameNumber == 0) 
+      {
        int error = GameListBuild(f);
-       if (error) {
-           DisplayError("Cannot build game list", error);
-       } else if (!ListEmpty(&gameList) &&
-                  ((ListGame *) gameList.tailPred)->number > 1) {
+
+       if (error) 
+         {
+           DisplayError(_("Cannot build game list"), error);
+         } 
+       else if (!ListEmpty(&gameList) 
+                && ((ListGame *) gameList.tailPred)->number > 1) 
+         {
            GameListPopUp(f, title);
            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);
+    return LoadGame(f, gameNumber, title, FALSE);
 }
 
 void LoadPositionProc(w, event, prms, nprms)
@@ -5519,7 +5177,7 @@ void LoadPositionProc(w, event, prms, nprms)
     if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
        Reset(FALSE, TRUE);
     }
-    FileNamePopUp("Load position file name?", "", LoadPosition, "rb");
+    FileNamePopUp(_("Load position file name?"), "", LoadPosition, "rb");
 }
 
 void SaveGameProc(w, event, prms, nprms)
@@ -5528,7 +5186,7 @@ void SaveGameProc(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    FileNamePopUp("Save game file name?",
+    FileNamePopUp(_("Save game file name?"),
                  DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
                  SaveGame, "a");
 }
@@ -5539,7 +5197,7 @@ void SavePositionProc(w, event, prms, nprms)
      String *prms;
      Cardinal *nprms;
 {
-    FileNamePopUp("Save position file name?",
+    FileNamePopUp(_("Save position file name?"),
                  DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
                  SavePosition, "a");
 }
@@ -5587,7 +5245,7 @@ SendPositionSelection(Widget w, Atom *selection, Atom *target,
     return True;
   } else {
     return False;
-  } 
+  }
 }
 
 /* note: when called from menu all parameters are NULL, so no clue what the
@@ -5602,7 +5260,7 @@ void CopyPositionProc(w, event, prms, nprms)
     int ret;
 
     if (selected_fen_position) free(selected_fen_position);
-    selected_fen_position = (char *)PositionToFEN(currentMove);
+    selected_fen_position = (char *)PositionToFEN(currentMove, NULL);
     if (!selected_fen_position) return;
     ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
                         CurrentTime,
@@ -5676,7 +5334,7 @@ SendGameSelection(Widget w, Atom *selection, Atom *target,
     return True;
   } else {
     return False;
-  } 
+  }
 }
 
 /* note: when called from menu all parameters are NULL, so no clue what the
@@ -5711,7 +5369,7 @@ PasteGameCB(Widget w, XtPointer client_data, Atom *selection,
   }
   f = fopen(gamePasteFilename, "w");
   if (f == NULL) {
-    DisplayError("Can't open temp file", errno);
+    DisplayError(_("Can't open temp file"), errno);
     return;
   }
   fwrite(value, 1, *len, f);
@@ -5746,58 +5404,45 @@ void AutoSaveGame()
     SaveGameProc(NULL, NULL, NULL, NULL);
 }
 
-
-void QuitProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    ExitEvent(0);
-}
-
-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)
      Widget w;
      XEvent *event;
      String *prms;
      Cardinal *nprms;
 {
+    char buf[MSG_SIZ];
+
     if (!first.analysisSupport) {
-      char buf[MSG_SIZ];
-      sprintf(buf, "%s does not support analysis", first.tidy);
+      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);
+      ShowThinkingProc(NULL,NULL);
 
     AnalyzeModeEvent();
 }
@@ -5810,37 +5455,20 @@ void AnalyzeFileProc(w, event, prms, nprms)
 {
     if (!first.analysisSupport) {
       char buf[MSG_SIZ];
-      sprintf(buf, "%s does not support analysis", first.tidy);
+      snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy);
       DisplayError(buf, 0);
       return;
     }
     Reset(FALSE, TRUE);
 
     if (!appData.showThinking)
-      ShowThinkingProc(w,event,prms,nprms);
+      ShowThinkingProc(NULL,NULL);
 
     AnalyzeFileEvent();
-    FileNamePopUp("File to analyze", "", LoadGamePopUp, "rb");
+    FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
     AnalysisPeriodicEvent(1);
 }
 
-void TwoMachinesProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    TwoMachinesEvent();
-}
-
-void IcsClientProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    IcsClientEvent();
-}
 
 void EditGameProc(w, event, prms, nprms)
      Widget w;
@@ -5895,77 +5523,6 @@ void IcsInputBoxProc(w, event, prms, nprms)
     }
 }
 
-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 EnterKeyProc(w, event, prms, nprms)
      Widget w;
@@ -5977,98 +5534,6 @@ void EnterKeyProc(w, event, prms, nprms)
       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;
@@ -6307,36 +5772,6 @@ void FlashMovesProc(w, event, prms, nprms)
                args, 1);
 }
 
-void FlipViewProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    flipView = !flipView;
-    DrawPosition(True, NULL);
-}
-
-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;
@@ -6444,7 +5879,7 @@ void PeriodicUpdatesProc(w, event, prms, nprms)
     Arg args[16];
 
     PeriodicUpdatesEvent(!appData.periodicUpdates);
-       
+
     if (appData.periodicUpdates) {
        XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
     } else {
@@ -6549,113 +5984,6 @@ void QuietPlayProc(w, event, prms, nprms)
                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;
-{
-    Arg args[16];
-
-    ShowThinkingEvent(!appData.showThinking);
-
-    if (appData.showThinking) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
-               args, 1);
-}
-
-void InfoProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    char buf[MSG_SIZ];
-    sprintf(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";
-    sprintf(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
-    sprintf(buf, "%s%s\n\n%s\n%s\n\n%s%s\n%s",
-           programVersion, zippy,
-           "Copyright 1991 Digital Equipment Corporation",
-           "Enhancements Copyright 1992-2001 Free Software Foundation",
-           PRODUCT, " 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;
      XEvent *event;
@@ -6690,66 +6018,79 @@ void Iconify(w, event, prms, nprms)
      Cardinal *nprms;
 {
     Arg args[16];
-    
+
     fromX = fromY = -1;
     XtSetArg(args[0], XtNiconic, True);
     XtSetValues(shellWidget, args, 1);
 }
 
 void DisplayMessage(message, extMessage)
-     char *message, *extMessage;
+     gchar *message, *extMessage;
 {
     char buf[MSG_SIZ];
     Arg arg;
-    
+
     if (extMessage) {
        if (*message) {
-           sprintf(buf, "%s  %s", message, extMessage);
+           snprintf(buf, sizeof(buf), "%s  %s", message, extMessage);
            message = buf;
        } else {
            message = extMessage;
        }
     }
-    XtSetArg(arg, XtNlabel, message);
-    XtSetValues(messageWidget, &arg, 1);
+    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) {
-       sprintf(icon, "%s", appData.icsHost);
-       sprintf(title, "%s: %s", programName, appData.icsHost);
-    } else if (appData.cmailGameName[0] != NULLCHAR) {
-       sprintf(icon, "%s", "CMail");
-       sprintf(title, "%s: %s", programName, "CMail");
-    } else if (appData.noChessProgram) {
-       strcpy(icon, programName);
+      }
+    else if (appData.icsActive)
+      {
+       snprintf(title, sizeof(title), "%s: %s", programName, appData.icsHost);
+      }
+    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(title, GOTHIC);
+#endif
+#ifdef FALCON
+      }
+    else if (gameInfo.variant == VariantFalcon)
+      {
+       strcpy(title, FALCON);
+#endif
+      }
+    else if (appData.noChessProgram)
+      {
        strcpy(title, programName);
-    } else {
-       strcpy(icon, first.tidy);
-       sprintf(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);
+      }
+    else
+      {
+       snprintf(title,sizeof(title), "%s: %s", programName, first.tidy);
+      }
+    gtk_window_set_title(GTK_WINDOW(GUI_Window),title);
+
+    return;
 }
 
 
@@ -6768,10 +6109,10 @@ void DisplayError(message, error)
            fprintf(stderr, "%s: %s: %s\n",
                    programName, message, strerror(error));
        }
-       sprintf(buf, "%s: %s", message, strerror(error));
+       snprintf(buf, sizeof(buf), "%s: %s", message, strerror(error));
        message = buf;
-    }  
-    ErrorPopUp("Error", message, FALSE);
+    }
+    ErrorPopUp(_("Error"), message, FALSE);
 }
 
 
@@ -6785,7 +6126,7 @@ void DisplayMoveError(message)
        fprintf(stderr, "%s: %s\n", programName, message);
     }
     if (appData.popupMoveErrors) {
-       ErrorPopUp("Error", message, FALSE);
+       ErrorPopUp(_("Error"), message, FALSE);
     } else {
        DisplayMessage(message, "");
     }
@@ -6804,11 +6145,11 @@ void DisplayFatalError(message, error, status)
     } else {
        fprintf(stderr, "%s: %s: %s\n",
                programName, message, strerror(error));
-       sprintf(buf, "%s: %s", message, strerror(error));
+       snprintf(buf, sizeof(buf), "%s: %s", message, strerror(error));
        message = buf;
     }
     if (appData.popupExitMessage && boardWidget && XtIsRealized(boardWidget)) {
-      ErrorPopUp(status ? "Fatal Error" : "Exiting", message, TRUE);
+      ErrorPopUp(status ? _("Fatal Error") : _("Exiting"), message, TRUE);
     } else {
       ExitEvent(status);
     }
@@ -6818,7 +6159,14 @@ void DisplayInformation(message)
      String message;
 {
     ErrorPopDown();
-    ErrorPopUp("Information", message, TRUE);
+    ErrorPopUp(_("Information"), message, TRUE);
+}
+
+void DisplayNote(message)
+     String message;
+{
+    ErrorPopDown();
+    ErrorPopUp(_("Note"), message, FALSE);
 }
 
 static int
@@ -6851,9 +6199,9 @@ void DisplayIcsInteractionTitle(message)
       XSetErrorHandler(oldHandler);
     }
     if (oldICSInteractionTitle == NULL) {
-      oldICSInteractionTitle = "xterm"; 
+      oldICSInteractionTitle = "xterm";
     }
-  }  
+  }
   printf("\033]0;%s\007", message);
   fflush(stdout);
 }
@@ -6868,7 +6216,7 @@ void AskQuestionProc(w, event, prms, nprms)
      Cardinal *nprms;
 {
     if (*nprms != 4) {
-       fprintf(stderr, "AskQuestionProc needed 4 parameters, got %d\n",
+       fprintf(stderr, _("AskQuestionProc needed 4 parameters, got %d\n"),
                *nprms);
        return;
     }
@@ -6901,7 +6249,7 @@ void AskQuestionReplyAction(w, event, prms, nprms)
     OutputToProcess(pendingReplyPR, buf, strlen(buf), &err);
     AskQuestionPopDown();
 
-    if (err) DisplayFatalError("Error writing to chess program", err, 0);
+    if (err) DisplayFatalError(_("Error writing to chess program"), err, 0);
 }
 
 void AskQuestionCallback(w, client_data, call_data)
@@ -6913,8 +6261,8 @@ void AskQuestionCallback(w, client_data, call_data)
 
     XtSetArg(args[0], XtNlabel, &name);
     XtGetValues(w, args, 1);
-    
-    if (strcmp(name, "cancel") == 0) {
+
+    if (strcmp(name, _("cancel")) == 0) {
         AskQuestionPopDown();
     } else {
        AskQuestionReplyAction(w, NULL, NULL, NULL);
@@ -6931,46 +6279,46 @@ void AskQuestion(title, question, replyPrefix, pr)
     int x, y, i;
     int win_x, win_y;
     unsigned int mask;
-    
+
     strcpy(pendingReplyPrefix, replyPrefix);
     pendingReplyPR = pr;
-    
+
     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));
-  
+
     i = 0;
     XtSetArg(args[i], XtNlabel, question); i++;
     XtSetArg(args[i], XtNvalue, ""); i++;
     XtSetArg(args[i], XtNborderWidth, 0); i++;
     dialog = XtCreateManagedWidget("question", dialogWidgetClass,
                                   layout, args, i);
-    
-    XawDialogAddButton(dialog, "enter", AskQuestionCallback,
+
+    XawDialogAddButton(dialog, _("enter"), AskQuestionCallback,
                       (XtPointer) dialog);
-    XawDialogAddButton(dialog, "cancel", AskQuestionCallback,
+    XawDialogAddButton(dialog, _("cancel"), AskQuestionCallback,
                       (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);
-    
+
     XtPopup(popup, XtGrabExclusive);
     askQuestionUp = True;
-    
+
     edit = XtNameToWidget(dialog, "*value");
     XtSetKeyboardFocus(popup, edit);
 }
@@ -6986,7 +6334,7 @@ PlaySound(name)
     putc(BELLCHAR, stderr);
   } else {
     char buf[2048];
-    sprintf(buf, "%s '%s' &", appData.soundProgram, name);
+    snprintf(buf, sizeof(buf), "%s '%s' &", appData.soundProgram, name);
     system(buf);
   }
 }
@@ -7066,7 +6414,7 @@ Colorize(cc, continuation)
     count = strlen(buf);
     outCount = OutputToProcess(NoProc, buf, count, &error);
     if (outCount < count) {
-       DisplayFatalError("Error writing to display", error, 1);
+       DisplayFatalError(_("Error writing to display"), error, 1);
     }
 
     if (continuation) return;
@@ -7116,7 +6464,7 @@ static char *ExpandPathName(path)
     static char static_buf[2000];
     char *d, *s, buf[2000];
     struct passwd *pwd;
-  
+
     s = path;
     d = static_buf;
 
@@ -7139,7 +6487,7 @@ static char *ExpandPathName(path)
            pwd = getpwnam(buf);
            if (!pwd)
              {
-                 fprintf(stderr, "ERROR: Unknown user %s (in path %s)\n",
+                 fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"),
                          buf, path);
                  return NULL;
              }
@@ -7151,12 +6499,12 @@ static char *ExpandPathName(path)
       strcpy(d, s);
 
     return static_buf;
-}  
+}
 
 char *HostName()
 {
     static char host_name[MSG_SIZ];
-    
+
 #if HAVE_GETHOSTNAME
     gethostname(host_name, MSG_SIZ);
     return host_name;
@@ -7170,57 +6518,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(delayedEventTimerTag && delayedEventCallback == cb)
+       // [HGM] alive: replace, rather than add or flush identical event
+       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;
@@ -7228,110 +6591,134 @@ int StopLoadGameTimer()
 }
 
 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) {
+    if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
+         || 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];
-    
-    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, timerForegroundPixel);
-       XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
-    } else {
-       XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
-       XtSetArg(args[2], XtNforeground, timerForegroundPixel);
-    }
-    
-    XtSetValues(w, args, 3);
+  gchar buf[MSG_SIZ];
+
+
+  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
@@ -7339,12 +6726,13 @@ DisplayWhiteClock(timeRemaining, highlight)
      long timeRemaining;
      int highlight;
 {
-    Arg args[16];
-    DisplayTimerLabel(whiteTimerWidget, "White", timeRemaining, highlight);
-    if (highlight && iconPixmap == bIconPixmap) {
-       iconPixmap = wIconPixmap;
-       XtSetArg(args[0], XtNiconPixmap, iconPixmap);
-       XtSetValues(shellWidget, args, 1);
+  if(appData.noGUI) return;
+
+  DisplayTimerLabel(GUI_Whiteclock, _("White"), timeRemaining, highlight);
+  if (highlight && WindowIcon == BlackIcon)
+    {
+      WindowIcon = WhiteIcon;
+      gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
     }
 }
 
@@ -7353,13 +6741,14 @@ DisplayBlackClock(timeRemaining, highlight)
      long timeRemaining;
      int highlight;
 {
-    Arg args[16];
-    DisplayTimerLabel(blackTimerWidget, "Black", timeRemaining, highlight);
-    if (highlight && iconPixmap == wIconPixmap) {
-       iconPixmap = bIconPixmap;
-       XtSetArg(args[0], XtNiconPixmap, iconPixmap);
-       XtSetValues(shellWidget, args, 1);
-    }
+    if(appData.noGUI) return;
+
+    DisplayTimerLabel(GUI_Blackclock, _("Black"), timeRemaining, highlight);
+    if (highlight && WindowIcon == WhiteIcon)
+      {
+        WindowIcon = BlackIcon;
+        gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
+      }
 }
 
 #define CPNone 0
@@ -7372,12 +6761,12 @@ typedef int CPKind;
 typedef struct {
     CPKind kind;
     int pid;
-    int fdTo, fdFrom;  
+    int fdTo, fdFrom;
 } ChildProc;
 
 
 int StartChildProcess(cmdLine, dir, pr)
-     char *cmdLine; 
+     char *cmdLine;
      char *dir;
      ProcRef *pr;
 {
@@ -7386,7 +6775,7 @@ int StartChildProcess(cmdLine, dir, pr)
     int to_prog[2], from_prog[2];
     ChildProc *cp;
     char buf[MSG_SIZ];
-    
+
     if (appData.debugMode) {
        fprintf(stderr, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine);
     }
@@ -7410,30 +6799,34 @@ int StartChildProcess(cmdLine, dir, pr)
 
     if ((pid = fork()) == 0) {
        /* Child process */
-       dup2(to_prog[0], 0);
-       dup2(from_prog[1], 1);
-       close(to_prog[0]);
-       close(to_prog[1]);
+       // [HGM] PSWBTM: made order resistant against case where fd of created pipe was 0 or 1
+       close(to_prog[1]);     // first close the unused pipe ends
        close(from_prog[0]);
-       close(from_prog[1]);
-       dup2(1, fileno(stderr)); /* force stderr to the pipe */
+       dup2(to_prog[0], 0);   // to_prog was created first, nd is the only one to use 0 or 1
+       dup2(from_prog[1], 1);
+       if(to_prog[0] >= 2) close(to_prog[0]); // if 0 or 1, the dup2 already cosed the original
+       close(from_prog[1]);                   // and closing again loses one of the pipes!
+       if(fileno(stderr) >= 2) // better safe than sorry...
+               dup2(1, fileno(stderr)); /* force stderr to the pipe */
 
        if (dir[0] != NULLCHAR && chdir(dir) != 0) {
            perror(dir);
            exit(1);
        }
 
+       nice(appData.niceEngines); // [HGM] nice: adjust priority of engine proc
+
         execvp(argv[0], argv);
-       
+
        /* If we get here, exec failed */
        perror(argv[0]);
        exit(1);
     }
-    
+
     /* Parent process */
     close(to_prog[0]);
     close(from_prog[1]);
-    
+
     cp = (ChildProc *) calloc(1, sizeof(ChildProc));
     cp->kind = CPReal;
     cp->pid = pid;
@@ -7443,22 +6836,37 @@ int StartChildProcess(cmdLine, dir, pr)
     return 0;
 }
 
+// [HGM] kill: implement the 'hard killing' of AS's Winboard_x
+static RETSIGTYPE AlarmCallBack(int n)
+{
+    return;
+}
+
 void
-DestroyChildProcess(pr, signal)
+DestroyChildProcess(pr, signalType)
      ProcRef pr;
-     int signal;
+     int signalType;
 {
     ChildProc *cp = (ChildProc *) pr;
 
     if (cp->kind != CPReal) return;
     cp->kind = CPNone;
-    if (signal) {
-      kill(cp->pid, SIGTERM);
+    if (signalType == 10) { // [HGM] kill: if it does not terminate in 3 sec, kill
+       signal(SIGALRM, AlarmCallBack);
+       alarm(3);
+       if(wait((int *) 0) == -1) { // process does not terminate on its own accord
+           kill(cp->pid, SIGKILL); // kill it forcefully
+           wait((int *) 0);        // and wait again
+       }
+    } else {
+       if (signalType) {
+           kill(cp->pid, signalType == 9 ? SIGKILL : SIGTERM); // [HGM] kill: use hard kill if so requested
+       }
+       /* Process is exiting either because of the kill or because of
+          a quit command sent by the backend; either way, wait for it to die.
+       */
+       wait((int *) 0);
     }
-    /* Process is exiting either because of the kill or because of
-       a quit command sent by the backend; either way, wait for it to die.
-    */
-    wait((int *) 0);
     close(cp->fdFrom);
     close(cp->fdTo);
 }
@@ -7481,9 +6889,9 @@ int OpenTelnet(host, port, pr)
     char cmdLine[MSG_SIZ];
 
     if (port[0] == NULLCHAR) {
-       sprintf(cmdLine, "%s %s", appData.telnetProgram, host);
+      snprintf(cmdLine, sizeof(cmdLine), "%s %s", appData.telnetProgram, host);
     } else {
-       sprintf(cmdLine, "%s %s %s", appData.telnetProgram, host, port);
+      snprintf(cmdLine, sizeof(cmdLine), "%s %s %s", appData.telnetProgram, host, port);
     }
     return StartChildProcess(cmdLine, "", pr);
 }
@@ -7494,7 +6902,7 @@ int OpenTCP(host, port, pr)
      ProcRef *pr;
 {
 #if OMIT_SOCKETS
-    DisplayFatalError("Socket support is not configured in", 0, 2);
+    DisplayFatalError(_("Socket support is not configured in"), 0, 2);
 #else  /* !OMIT_SOCKETS */
     int s;
     struct sockaddr_in sa;
@@ -7537,7 +6945,7 @@ int OpenTCP(host, port, pr)
     sa.sin_port = htons(uport);
     memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
 
-    if (connect(s, (struct sockaddr *) &sa, 
+    if (connect(s, (struct sockaddr *) &sa,
                sizeof(struct sockaddr_in)) < 0) {
        return errno;
     }
@@ -7596,9 +7004,9 @@ int OpenRcmd(host, user, cmd, pr)
      char *host, *user, *cmd;
      ProcRef *pr;
 {
-    DisplayFatalError("internal rcmd not implemented for Unix", 0, 1);
+    DisplayFatalError(_("internal rcmd not implemented for Unix"), 0, 1);
     return -1;
-}    
+}
 
 #define INPUT_SOURCE_BUF_SIZE 8192
 
@@ -7608,51 +7016,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;
+  /* read input from one of the input source (for example a chess program, ICS, etc).
+   * and call a function that will handle the input
+   */
 
-    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;
+  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)
@@ -7662,6 +7094,7 @@ InputSourceRef AddInputSource(pr, lineByLine, func, closure)
      VOIDSTAR closure;
 {
     InputSource *is;
+    GIOChannel *channel;
     ChildProc *cp = (ChildProc *) pr;
 
     is = (InputSource *) calloc(1, sizeof(InputSource));
@@ -7674,14 +7107,23 @@ InputSourceRef AddInputSource(pr, lineByLine, func, closure)
        is->kind = cp->kind;
        is->fd = cp->fdFrom;
     }
-    if (lineByLine) {
-       is->unused = is->buf;
-    }
-    
-    is->xid = XtAppAddInput(appContext, is->fd,
-                           (XtPointer) (XtInputReadMask),
-                           (XtInputCallbackProc) DoInputCallback,
-                           (XtPointer) is);
+    if (lineByLine) 
+      is->unused = is->buf;
+    else
+      is->unused = NULL;
+
+//    is->xid = XtAppAddInput(appContext, is->fd,
+//                         (XtPointer) (XtInputReadMask),
+//                         (XtInputCallbackProc) DoInputCallback,
+//                         (XtPointer) is);
+//
+
+    /* TODO: will this work on windows?*/
+    printf("DEBUG: fd=%d %d\n",is->fd,is);
+
+    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;
 }
@@ -7692,9 +7134,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)
@@ -7733,7 +7176,7 @@ int OutputToProcessDelayed(pr, message, count, outError, msdelay)
     ChildProc *cp = (ChildProc *) pr;
     int outCount = 0;
     int r;
-    
+
     while (count--) {
        r = write(cp->fdTo, message++, 1);
        if (r == -1) {
@@ -7767,6 +7210,8 @@ int OutputToProcessDelayed(pr, message, count, outError, msdelay)
        and dark squares, and all pieces must use the same
        background square colors/images.                */
 
+static int xpmDone = 0;
+
 static void
 CreateAnimMasks (pieceDepth)
      int pieceDepth;
@@ -7778,6 +7223,9 @@ 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);
@@ -7789,7 +7237,7 @@ CreateAnimMasks (pieceDepth)
   XFreePixmap(xDisplay, buf);
 
   buf = XCreatePixmap(xDisplay, xBoardWindow,
-                     squareSize, squareSize, pieceDepth);            
+                     squareSize, squareSize, pieceDepth);
   values.foreground = XBlackPixel(xDisplay, xScreen);
   values.background = XWhitePixel(xDisplay, xScreen);
   bufGC = XCreateGC(xDisplay, buf,
@@ -7797,22 +7245,23 @@ CreateAnimMasks (pieceDepth)
 
   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);
-                  
+
     /* Take a copy of the piece */
     if (White(piece))
       kind = 0;
     else
       kind = 2;
     XSetFunction(xDisplay, bufGC, GXcopy);
-    XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % 6],
+    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)
@@ -7822,7 +7271,7 @@ CreateAnimMasks (pieceDepth)
       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.     */
@@ -7852,47 +7301,51 @@ InitAnimState (anim, info)
 {
   XtGCMask  mask;
   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;
+  /* 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;
 }
 
 static void
 CreateAnimVars ()
 {
-  static int done = 0;
+  static VariantClass old = (VariantClass) -1; // [HGM] pieces: redo every time variant changes
   XWindowAttributes info;
 
-  if (done) return;
-  done = 1;
-  XGetWindowAttributes(xDisplay, xBoardWindow, &info);
-  
-  InitAnimState(&game, &info);
-  InitAnimState(&player, &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);
+
+  //  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;
 }
 
 #ifndef HAVE_USLEEP
@@ -7912,23 +7365,18 @@ FrameDelay (time)
      int time;
 {
   struct itimerval delay;
-  
+
   XSync(xDisplay, False);
 
   if (time > 0) {
     frameWaiting = True;
     signal(SIGALRM, FrameAlarm);
-    delay.it_interval.tv_sec = 
+    delay.it_interval.tv_sec =
       delay.it_value.tv_sec = time / 1000;
-    delay.it_interval.tv_usec = 
+    delay.it_interval.tv_usec =
       delay.it_value.tv_usec = (time % 1000) * 1000;
     setitimer(ITIMER_REAL, &delay, NULL);
-#if 0
-    /* Ugh -- busy-wait! --tpm */
-    while (frameWaiting); 
-#else
     while (frameWaiting) pause();
-#endif
     delay.it_interval.tv_sec = delay.it_value.tv_sec = 0;
     delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;
     setitimer(ITIMER_REAL, &delay, NULL);
@@ -7941,7 +7389,7 @@ static void
 FrameDelay (time)
      int time;
 {
-  XSync(xDisplay, False);
+  //  XSync(xDisplay, False);
   if (time > 0)
     usleep(time * 1000);
 }
@@ -7955,13 +7403,13 @@ ScreenSquare(column, row, pt, color)
      int column; int row; XPoint * pt; int * color;
 {
   if (flipView) {
-    pt->x = lineGap + ((BOARD_SIZE-1)-column) * (squareSize + lineGap);
+    pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);
     pt->y = lineGap + row * (squareSize + lineGap);
   } else {
     pt->x = lineGap + column * (squareSize + lineGap);
-    pt->y = lineGap + ((BOARD_SIZE-1)-row) * (squareSize + lineGap);
+    pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);
   }
-  *color = ((column + row) % 2) == 1;
+  *color = SquareColor(row, column);
 }
 
 /*     Convert window coords to square                 */
@@ -7970,12 +7418,12 @@ static void
 BoardSquare(x, y, column, row)
      int x; int y; int * column; int * row;
 {
-  *column = EventToSquare(x, BOARD_SIZE);
+  *column = EventToSquare(x, BOARD_WIDTH);
   if (flipView && *column >= 0)
-    *column = BOARD_SIZE - 1 - *column;
-  *row = EventToSquare(y, BOARD_SIZE);
+    *column = BOARD_WIDTH - 1 - *column;
+  *row = EventToSquare(y, BOARD_HEIGHT);
   if (!flipView && *row >= 0)
-    *row = BOARD_SIZE - 1 - *row;
+    *row = BOARD_HEIGHT - 1 - *row;
 }
 
 /*   Utilities */
@@ -7998,7 +7446,7 @@ SetRect(rect, x, y, width, height)
 /*     Test if two frames overlap. If they do, return
        intersection rect within old and location of
        that rect within new. */
-       
+
 static Boolean
 Intersect(old, new, size, area, pt)
      XPoint * old; XPoint * new;
@@ -8018,7 +7466,7 @@ Intersect(old, new, size, area, pt)
 
 /*     For two overlapping frames, return the rect(s)
        in the old that do not intersect with the new.   */
-       
+
 static void
 CalcUpdateRects(old, new, size, update, nUpdates)
      XPoint * old; XPoint * new; int size;
@@ -8087,11 +7535,11 @@ Tween(start, mid, finish, factor, frames, nFrames)
     count ++;
     fraction = fraction / 2;
   }
-  
+
   /* Midpoint */
   frames[count] = *mid;
   count ++;
-  
+
   /* Slow out, stepping 1/2, then 1/4, ... */
   fraction = 2;
   for (n = 0; n < factor; n++) {
@@ -8118,7 +7566,7 @@ SelectGCMask(piece, clip, outline, mask)
 #if HAVE_LIBXPM
       *mask = xpmMask[piece];
 #else
-      *mask = ximMaskPm[piece%6];
+      *mask = ximMaskPm[piece];
 #endif
   } else {
       *mask = *pieceToSolid(piece);
@@ -8137,8 +7585,8 @@ 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))
     *outline = bwPieceGC;
@@ -8151,32 +7599,34 @@ OverlayPiece(piece, clip, outline,  dest)
      ChessSquare piece; GC clip; GC outline; Drawable dest;
 {
   int  kind;
-  
+
   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][((int)piece) % 6],
-             dest, clip,
-             0, 0, squareSize, squareSize,
-             0, 0);            
+//    XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
+//           dest, clip,
+//           0, 0, squareSize, squareSize,
+//           0, 0);
   }
 }
 
 /* Animate the movement of a single piece */
 
-static void 
+static void
 BeginAnimation(anim, piece, startColor, start)
      AnimState *anim;
      ChessSquare piece;
@@ -8184,14 +7634,14 @@ BeginAnimation(anim, piece, startColor, start)
      XPoint * start;
 {
   Pixmap mask;
-  
+
   /* The old buffer is initialised with the start square (empty) */
   BlankSquare(0, 0, startColor, EmptySquare, anim->saveBuf);
   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
@@ -8204,47 +7654,48 @@ AnimationFrame(anim, frame, piece)
   XRectangle overlap;
   XPoint     pt;
   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
@@ -8262,15 +7713,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);
   }
 }
 
@@ -8311,6 +7763,10 @@ AnimateMove(board, fromX, fromY, toX, toY)
   if (!appData.animate || appData.blindfold)
     return;
 
+  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;
   piece = board[fromY][fromX];
   if (piece >= EmptySquare) return;
@@ -8322,9 +7778,9 @@ AnimateMove(board, fromX, fromY, toX, toY)
 #endif
 
   if (appData.debugMode) {
-      printf("AnimateMove: piece %d %s from %d,%d to %d,%d \n",
-            piece, hop ? "hops" : "slides", fromX, fromY, toX, toY);
-  }
+      fprintf(debugFP, hop ? _("AnimateMove: piece %d hops from %d,%d to %d,%d \n") :
+                             _("AnimateMove: piece %d slides from %d,%d to %d,%d \n"),
+             piece, fromX, fromY, toX, toY);  }
 
   ScreenSquare(fromX, fromY, &start, &startColor);
   ScreenSquare(toX, toY, &finish, &endColor);
@@ -8342,19 +7798,19 @@ AnimateMove(board, fromX, fromY, toX, toY)
     mid.x = start.x + (finish.x - start.x) / 2;
     mid.y = start.y + (finish.y - start.y) / 2;
   }
-  
+
   /* Don't use as many frames for very short moves */
   if (abs(toY - fromY) + abs(toX - fromX) <= 2)
     Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames);
   else
     Tween(&start, &mid, &finish, kFactor, frames, &nFrames);
   FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames);
-  
+
   /* Be sure end square is redrawn */
   damage[toY][toX] = True;
 }
 
-static void
+void
 DragPieceBegin(x, y)
      int x; int y;
 {
@@ -8364,7 +7820,7 @@ DragPieceBegin(x, y)
     /* Are we animating? */
     if (!appData.animateDragging || appData.blindfold)
       return;
-     
+
     /* Figure out which square we start in and the
        mouse position relative to top left corner. */
     BoardSquare(x, y, &boardX, &boardY);
@@ -8373,19 +7829,10 @@ DragPieceBegin(x, y)
     ScreenSquare(boardX, boardY, &corner, &color);
     player.startSquare  = corner;
     player.startColor   = color;
-#if 0
-    /* Start from exactly where the piece is.  This can be confusing
-       if you start dragging far from the center of the square; most
-       or all of the piece can be over a different square from the one
-       the mouse pointer is in. */
-    player.mouseDelta.x = x - corner.x;
-    player.mouseDelta.y = y - corner.y;
-#else
     /* As soon as we start dragging, the piece will jump slightly to
        be centered over the mouse pointer. */
     player.mouseDelta.x = squareSize/2;
     player.mouseDelta.y = squareSize/2;
-#endif
     /* Initialise animation */
     player.dragPiece = PieceForSquare(boardX, boardY);
     /* Sanity check */
@@ -8395,6 +7842,11 @@ DragPieceBegin(x, y)
        /* Mark this square as needing to be redrawn. Note that
           we don't remove the piece though, since logically (ie
           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
        damage[boardY][boardX] = True;
     } else {
        player.dragActive = False;
@@ -8410,7 +7862,7 @@ DragPieceMove(x, y)
     /* Are we animating? */
     if (!appData.animateDragging || appData.blindfold)
       return;
-     
+
     /* Sanity check */
     if (! player.dragActive)
       return;
@@ -8428,7 +7880,7 @@ DragPieceMove(x, y)
 #endif
 }
 
-static void
+void
 DragPieceEnd(x, y)
      int x; int y;
 {
@@ -8438,7 +7890,7 @@ DragPieceEnd(x, y)
     /* Are we animating? */
     if (!appData.animateDragging || appData.blindfold)
       return;
-     
+
     /* Sanity check */
     if (! player.dragActive)
       return;
@@ -8475,3 +7927,10 @@ DrawDragPiece ()
   damage[player.startBoardY][player.startBoardX] = TRUE;
 }
 
+void
+SetProgramStats( FrontEndProgramStats * stats )
+{
+  // [HR] TODO
+  // [HGM] done, but perhaps backend should call this directly?
+    EngineOutputUpdate( stats );
+}