Shuffle prototypes to correct header, or add them there
[xboard.git] / xboard.c
index 51182a5..5877c3a 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -206,6 +206,8 @@ extern char *getenv();
 #include "menus.h"
 #include "board.h"
 #include "dialogs.h"
+#include "engineoutput.h"
+#include "usystem.h"
 #include "gettext.h"
 
 
@@ -225,8 +227,6 @@ extern char *getenv();
 #endif
 
 int main P((int argc, char **argv));
-FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *failed,
-               char *init_path, char *filter, char *mode, int (*show_entry)(), char **name_return));
 RETSIGTYPE CmailSigHandler P((int sig));
 RETSIGTYPE IntSigHandler P((int sig));
 RETSIGTYPE TermSizeSigHandler P((int sig));
@@ -236,65 +236,28 @@ void CreateXIMPieces P((void));
 void CreateXPMPieces P((void));
 void CreateXPMBoard P((char *s, int n));
 void CreatePieces P((void));
-void CreatePieceMenus P((void));
 Widget CreateMenuBar P((Menu *mb, int boardWidth));
-Widget CreateButtonBar P ((MenuItem *mi));
 #if ENABLE_NLS
 char *InsertPxlSize P((char *pattern, int targetPxlSize));
 XFontSet CreateFontSet P((char *base_fnt_lst));
 #else
 char *FindFont P((char *pattern, int targetPxlSize));
 #endif
-void PieceMenuPopup P((Widget w, XEvent *event,
-                      String *params, Cardinal *num_params));
-static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
-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 EventProc P((Widget widget, caddr_t unused, XEvent *event));
 void DelayedDrag P((void));
 static void MoveTypeInProc P((Widget widget, caddr_t unused, XEvent *event));
-void HandleUserMove P((Widget w, XEvent *event,
-                    String *prms, Cardinal *nprms));
-void AnimateUserMove P((Widget w, XEvent * event,
-                    String * params, Cardinal * nParams));
 void HandlePV P((Widget w, XEvent * event,
                     String * params, Cardinal * nParams));
-void SelectPV P((Widget w, XEvent * event,
-                    String * params, Cardinal * nParams));
-void StopPV P((Widget w, XEvent * event,
-                    String * params, Cardinal * nParams));
-void WhiteClock P((Widget w, XEvent *event,
-                  String *prms, Cardinal *nprms));
-void BlackClock P((Widget w, XEvent *event,
-                  String *prms, Cardinal *nprms));
 void DrawPositionProc P((Widget w, XEvent *event,
                     String *prms, Cardinal *nprms));
-void XDrawPosition P((Widget w, /*Boolean*/int repaint,
-                    Board board));
 void CommentClick P((Widget w, XEvent * event,
                   String * params, Cardinal * nParams));
-void CommentPopUp P((char *title, char *label));
-void CommentPopDown P((void));
 void ICSInputBoxPopUp P((void));
-void ICSInputBoxPopDown P((void));
 void FileNamePopUp P((char *label, char *def, char *filter,
                      FileProc proc, char *openMode));
-void FileNamePopDown P((void));
-void FileNameCallback P((Widget w, XtPointer client_data,
-                        XtPointer call_data));
-void FileNameAction P((Widget w, XEvent *event,
-                      String *prms, Cardinal *nprms));
-void AskQuestionReplyAction P((Widget w, XEvent *event,
-                         String *prms, Cardinal *nprms));
-void AskQuestionProc P((Widget w, XEvent *event,
-                         String *prms, Cardinal *nprms));
-void AskQuestionPopDown P((void));
-void PromotionPopDown P((void));
-void PromotionCallback P((Widget w, XtPointer client_data,
-                         XtPointer call_data));
 void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
 void KeyBindingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void QuitWrapper P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@ -307,15 +270,9 @@ Boolean TempBackwardActive = False;
 void ManInner P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void DisplayMove P((int moveNumber));
 void ICSInitScript P((void));
-static char *ExpandPathName P((char *path));
 void SelectMove P((Widget w, XEvent * event, String * params, Cardinal * nParams));
-void GameListOptionsPopDown P(());
-void GenericPopDown P(());
 void update_ics_width P(());
-int get_term_width P(());
 int CopyMemoProc P(());
-void DrawArrowHighlight P((int fromX, int fromY, int toX,int toY));
-Boolean IsDrawArrowEnabled P(());
 
 /*
 * XBoard depends on Xt R4 or higher
@@ -326,21 +283,15 @@ int xScreen;
 Display *xDisplay;
 Window xBoardWindow;
 Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
-  jailSquareColor, highlightSquareColor, premoveHighlightColor;
+  highlightSquareColor, premoveHighlightColor, dialogColor, buttonColor;
 Pixel lowTimeWarningColor;
-GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,
+GC lightSquareGC, darkSquareGC, lineGC, wdPieceGC, wlPieceGC,
   bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
-  wjPieceGC, bjPieceGC, prelineGC, countGC;
+  prelineGC, countGC;
 Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
-Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
-  whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16],
-  commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,
-  menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
-  ICSInputShell, fileNameShell, askQuestionShell;
-Widget historyShell, evalGraphShell, gameListShell;
-XSegment secondSegments[BOARD_RANKS + BOARD_FILES + 2];
+Widget shellWidget, formWidget, boardWidget, titleWidget, dropMenu, menuBarWidget;
+Option *optList; // contains all widgets of main window
 XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2];
-XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6];
 #if ENABLE_NLS
 XFontSet fontSet, clockFontSet;
 #else
@@ -351,7 +302,6 @@ Font coordFontID, countFontID;
 XFontStruct *coordFontStruct, *countFontStruct;
 XtAppContext appContext;
 char *layoutName;
-char *oldICSInteractionTitle;
 
 FileProc fileProc;
 char *fileOpenMode;
@@ -366,10 +316,8 @@ Boolean chessProgram;
 int  minX, minY; // [HGM] placement: volatile limits on upper-left corner
 int 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,
-  errorUp = False, errorExitStatus = -1, defaultLineGap;
+  fromX = -1, fromY = -1, toX, toY, commentUp = False,
+  errorExitStatus = -1, defaultLineGap;
 Dimension textHeight;
 Pixel timerForegroundPixel, timerBackgroundPixel;
 Pixel buttonForegroundPixel, buttonBackgroundPixel;
@@ -421,49 +369,6 @@ static Pixmap xpmMask[BlackKing + 1];
 
 SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
 
-#define PAUSE_BUTTON "P"
-MenuItem buttonBar[] = {
-    {"<<", "<<", ToStartEvent},
-    {"<", "<", BackwardEvent},
-    {N_(PAUSE_BUTTON), PAUSE_BUTTON, PauseEvent},
-    {">", ">", ForwardEvent},
-    {">>", ">>", ToEndEvent},
-    {NULL, NULL, NULL}
-};
-
-#define PIECE_MENU_SIZE 18
-String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
-    { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
-      N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"),
-      N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
-      N_("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, WhiteAlfil,
-       WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0,
-       PromotePiece, DemotePiece, EmptySquare, ClearBoard },
-    { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
-       BlackRook, BlackQueen, BlackKing, (ChessSquare) 0, BlackAlfil,
-       BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0,
-       PromotePiece, DemotePiece, EmptySquare, ClearBoard },
-};
-
-#define DROP_MENU_SIZE 6
-String dropMenuStrings[DROP_MENU_SIZE] = {
-    "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen")
-  };
-/* must be in same order as dropMenuStrings! */
-ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
-    (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
-    WhiteRook, WhiteQueen
-};
-
 typedef struct {
     char piece;
     char* widget;
@@ -486,41 +391,6 @@ Arg shellArgs[] = {
     { XtNmaxHeight, 0 }
 };
 
-Arg layoutArgs[] = {
-    { XtNborderWidth, 0 },
-    { XtNdefaultDistance, 0 },
-};
-
-Arg formArgs[] = {
-    { XtNborderWidth, 0 },
-    { XtNresizable, (XtArgVal) True },
-};
-
-Arg boardArgs[] = {
-    { XtNborderWidth, 0 },
-    { XtNwidth, 0 },
-    { XtNheight, 0 }
-};
-
-Arg titleArgs[] = {
-    { XtNjustify, (XtArgVal) XtJustifyRight },
-    { XtNlabel, (XtArgVal) "..." },
-    { XtNresizable, (XtArgVal) True },
-    { XtNresize, (XtArgVal) False }
-};
-
-Arg messageArgs[] = {
-    { XtNjustify, (XtArgVal) XtJustifyLeft },
-    { XtNlabel, (XtArgVal) "..." },
-    { XtNresizable, (XtArgVal) True },
-    { XtNresize, (XtArgVal) False }
-};
-
-Arg timerArgs[] = {
-    { XtNborderWidth, 0 },
-    { XtNjustify, (XtArgVal) XtJustifyLeft }
-};
-
 XtResource clientResources[] = {
     { "flashCount", "flashCount", XtRInt, sizeof(int),
        XtOffset(AppDataPtr, flashCount), XtRImmediate,
@@ -535,35 +405,17 @@ XrmOptionDescRec shellOptions[] = {
 
 XtActionsRec boardActions[] = {
     { "DrawPosition", DrawPositionProc },
-    { "HandleUserMove", HandleUserMove },
-    { "AnimateUserMove", AnimateUserMove },
     { "HandlePV", HandlePV },
     { "SelectPV", SelectPV },
     { "StopPV", StopPV },
-    { "FileNameAction", FileNameAction },
-    { "AskQuestionProc", AskQuestionProc },
-    { "AskQuestionReplyAction", AskQuestionReplyAction },
-    { "PieceMenuPopup", PieceMenuPopup },
-    { "WhiteClock", WhiteClock },
-    { "BlackClock", BlackClock },
     { "MenuItem", KeyBindingProc }, // [HGM] generic handler for key bindings
     { "QuitProc", QuitWrapper },
     { "ManProc", ManInner },
     { "TempBackwardProc", TempBackwardProc },
     { "TempForwardProc", TempForwardProc },
     { "CommentClick", (XtActionProc) CommentClick },
-    { "CommentPopDown", (XtActionProc) CommentPopDown },
-    { "TagsPopDown", (XtActionProc) TagsPopDown },
-    { "ErrorPopDown", (XtActionProc) ErrorPopDown },
-    { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
-    { "FileNamePopDown", (XtActionProc) FileNamePopDown },
-    { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
-    { "GameListPopDown", (XtActionProc) GameListPopDown },
-    { "GameListOptionsPopDown", (XtActionProc) GameListOptionsPopDown },
-    { "PromotionPopDown", (XtActionProc) PromotionPopDown },
-    { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
-    { "EvalGraphPopDown", (XtActionProc) EvalGraphPopDown },
     { "GenericPopDown", (XtActionProc) GenericPopDown },
+    { "ErrorPopDown", (XtActionProc) ErrorPopDown },
     { "CopyMemoProc", (XtActionProc) CopyMemoProc },
     { "SelectMove", (XtActionProc) SelectMove },
     { "LoadSelectedProc", LoadSelectedProc },
@@ -572,63 +424,65 @@ XtActionsRec boardActions[] = {
     { "EnterKeyProc", EnterKeyProc },
     { "UpKeyProc", UpKeyProc },
     { "DownKeyProc", DownKeyProc },
+    { "WheelProc", WheelProc },
+    { "TabProc", TabProc },
 };
 
 char globalTranslations[] =
-  ":<Key>F9: MenuItem(ResignProc) \n \
-   :Ctrl<Key>n: MenuItem(NewGame) \n \
-   :Meta<Key>V: MenuItem(NewVariant) \n \
-   :Ctrl<Key>o: MenuItem(LoadGame) \n \
+  ":<Key>F9: MenuItem(Actions.Resign) \n \
+   :Ctrl<Key>n: MenuItem(File.NewGame) \n \
+   :Meta<Key>V: MenuItem(File.NewVariant) \n \
+   :Ctrl<Key>o: MenuItem(File.LoadGame) \n \
    :Meta<Key>Next: MenuItem(LoadNextGameProc) \n \
    :Meta<Key>Prior: MenuItem(LoadPrevGameProc) \n \
    :Ctrl<Key>Down: LoadSelectedProc(3) \n \
    :Ctrl<Key>Up: LoadSelectedProc(-3) \n \
-   :Ctrl<Key>s: MenuItem(SaveGame) \n \
-   :Ctrl<Key>c: MenuItem(CopyGame) \n \
-   :Ctrl<Key>v: MenuItem(PasteGame) \n \
-   :Ctrl<Key>O: MenuItem(LoadPosition) \n \
+   :Ctrl<Key>s: MenuItem(File.SaveGame) \n \
+   :Ctrl<Key>c: MenuItem(Edit.CopyGame) \n \
+   :Ctrl<Key>v: MenuItem(Edit.PasteGame) \n \
+   :Ctrl<Key>O: MenuItem(File.LoadPosition) \n \
    :Shift<Key>Next: MenuItem(LoadNextPositionProc) \n \
    :Shift<Key>Prior: MenuItem(LoadPrevPositionProc) \n \
-   :Ctrl<Key>S: MenuItem(SavePosition) \n \
-   :Ctrl<Key>C: MenuItem(CopyPosition) \n \
-   :Ctrl<Key>V: MenuItem(PastePosition) \n \
-   :Ctrl<Key>q: MenuItem(Exit) \n \
-   :Ctrl<Key>w: MenuItem(MachineWhite) \n \
-   :Ctrl<Key>b: MenuItem(MachineBlack) \n \
-   :Ctrl<Key>t: MenuItem(TwoMachines) \n \
-   :Ctrl<Key>a: MenuItem(AnalysisMode) \n \
-   :Ctrl<Key>g: MenuItem(AnalyzeFile) \n \
-   :Ctrl<Key>e: MenuItem(EditGame) \n \
-   :Ctrl<Key>E: MenuItem(EditPosition) \n \
-   :Meta<Key>O: MenuItem(ShowEngineOutput) \n \
-   :Meta<Key>E: MenuItem(ShowEvaluationGraph) \n \
-   :Meta<Key>G: MenuItem(ShowGameList) \n \
-   :Meta<Key>H: MenuItem(ShowMoveHistory) \n \
-   :<Key>Pause: MenuItem(Pause) \n \
-   :<Key>F3: MenuItem(Accept) \n \
-   :<Key>F4: MenuItem(Decline) \n \
-   :<Key>F12: MenuItem(Rematch) \n \
-   :<Key>F5: MenuItem(CallFlag) \n \
-   :<Key>F6: MenuItem(Draw) \n \
-   :<Key>F7: MenuItem(Adjourn) \n \
-   :<Key>F8: MenuItem(Abort) \n \
-   :<Key>F10: MenuItem(StopObserving) \n \
-   :<Key>F11: MenuItem(StopExamining) \n \
+   :Ctrl<Key>S: MenuItem(File.SavePosition) \n \
+   :Ctrl<Key>C: MenuItem(Edit.CopyPosition) \n \
+   :Ctrl<Key>V: MenuItem(Edit.PastePosition) \n \
+   :Ctrl<Key>q: MenuItem(File.Quit) \n \
+   :Ctrl<Key>w: MenuItem(Mode.MachineWhite) \n \
+   :Ctrl<Key>b: MenuItem(Mode.MachineBlack) \n \
+   :Ctrl<Key>t: MenuItem(Mode.TwoMachines) \n \
+   :Ctrl<Key>a: MenuItem(Mode.AnalysisMode) \n \
+   :Ctrl<Key>g: MenuItem(Mode.AnalyzeFile) \n \
+   :Ctrl<Key>e: MenuItem(Mode.EditGame) \n \
+   :Ctrl<Key>E: MenuItem(Mode.EditPosition) \n \
+   :Meta<Key>O: MenuItem(View.EngineOutput) \n \
+   :Meta<Key>E: MenuItem(View.EvaluationGraph) \n \
+   :Meta<Key>G: MenuItem(View.GameList) \n \
+   :Meta<Key>H: MenuItem(View.MoveHistory) \n \
+   :<Key>Pause: MenuItem(Mode.Pause) \n \
+   :<Key>F3: MenuItem(Action.Accept) \n \
+   :<Key>F4: MenuItem(Action.Decline) \n \
+   :<Key>F12: MenuItem(Action.Rematch) \n \
+   :<Key>F5: MenuItem(Action.CallFlag) \n \
+   :<Key>F6: MenuItem(Action.Draw) \n \
+   :<Key>F7: MenuItem(Action.Adjourn) \n \
+   :<Key>F8: MenuItem(Action.Abort) \n \
+   :<Key>F10: MenuItem(Action.StopObserving) \n \
+   :<Key>F11: MenuItem(Action.StopExamining) \n \
    :Ctrl<Key>d: MenuItem(DebugProc) \n \
    :Meta Ctrl<Key>F12: MenuItem(DebugProc) \n \
-   :Meta<Key>End: MenuItem(ToEnd) \n \
-   :Meta<Key>Right: MenuItem(Forward) \n \
-   :Meta<Key>Home: MenuItem(ToStart) \n \
-   :Meta<Key>Left: MenuItem(Backward) \n \
-   :<Key>Left: MenuItem(Backward) \n \
-   :<Key>Right: MenuItem(Forward) \n \
-   :<Key>Home: MenuItem(Revert) \n \
-   :<Key>End: MenuItem(TruncateGame) \n \
-   :Ctrl<Key>m: MenuItem(MoveNow) \n \
-   :Ctrl<Key>x: MenuItem(RetractMove) \n \
-   :Meta<Key>J: MenuItem(Adjudications) \n \
-   :Meta<Key>U: MenuItem(CommonEngine) \n \
-   :Meta<Key>T: MenuItem(TimeControl) \n \
+   :Meta<Key>End: MenuItem(Edit.ForwardtoEnd) \n \
+   :Meta<Key>Right: MenuItem(Edit.Forward) \n \
+   :Meta<Key>Home: MenuItem(Edit.BacktoStart) \n \
+   :Meta<Key>Left: MenuItem(Edit.Backward) \n \
+   :<Key>Left: MenuItem(Edit.Backward) \n \
+   :<Key>Right: MenuItem(Edit.Forward) \n \
+   :<Key>Home: MenuItem(Edit.Revert) \n \
+   :<Key>End: MenuItem(Edit.TruncateGame) \n \
+   :Ctrl<Key>m: MenuItem(Engine.MoveNow) \n \
+   :Ctrl<Key>x: MenuItem(Engine.RetractMove) \n \
+   :Meta<Key>J: MenuItem(Options.Adjudications) \n \
+   :Meta<Key>U: MenuItem(Options.CommonEngine) \n \
+   :Meta<Key>T: MenuItem(Options.TimeControl) \n \
    :Ctrl<Key>P: MenuItem(PonderNextMove) \n "
 #ifndef OPTIONSDIALOG
     "\
@@ -639,36 +493,11 @@ char globalTranslations[] =
    :Ctrl<Key>H: MenuItem(HideThinkingProc) \n "
 #endif
    "\
-   :<Key>F1: MenuItem(Manual) \n \
-   :<Key>F2: MenuItem(FlipView) \n \
+   :<Key>F1: MenuItem(Help.ManXBoard) \n \
+   :<Key>F2: MenuItem(View.FlipView) \n \
    :<KeyDown>Return: TempBackwardProc() \n \
    :<KeyUp>Return: TempForwardProc() \n";
 
-char boardTranslations[] =
-   "<Btn1Down>: HandleUserMove(0) \n \
-   Shift<Btn1Up>: HandleUserMove(1) \n \
-   <Btn1Up>: HandleUserMove(0) \n \
-   <Btn1Motion>: AnimateUserMove() \n \
-   <Btn3Motion>: HandlePV() \n \
-   <Btn2Motion>: HandlePV() \n \
-   <Btn3Up>: PieceMenuPopup(menuB) \n \
-   <Btn2Up>: PieceMenuPopup(menuB) \n \
-   Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
-                 PieceMenuPopup(menuB) \n \
-   Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
-                 PieceMenuPopup(menuW) \n \
-   Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
-                 PieceMenuPopup(menuW) \n \
-   Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
-                 PieceMenuPopup(menuB) \n";
-
-char whiteTranslations[] =
-   "Shift<BtnDown>: WhiteClock(1)\n \
-   <BtnDown>: WhiteClock(0)\n";
-char blackTranslations[] =
-   "Shift<BtnDown>: BlackClock(1)\n \
-   <BtnDown>: BlackClock(0)\n";
-
 char ICSInputTranslations[] =
     "<Key>Up: UpKeyProc() \n "
     "<Key>Down: DownKeyProc() \n "
@@ -679,9 +508,7 @@ char ICSInputTranslations[] =
 char commentTranslations[] = "<Btn3Down>: extend-end() select-start() CommentClick() \n";
 
 String xboardResources[] = {
-    "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
-    "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
-    "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
+    "*Error*translations: #override\\n <Key>Return: ErrorPopDown()",
     NULL
   };
 
@@ -810,77 +637,6 @@ Warning: No DIR structure found on this system --\n\
 }
 #endif /* HAVE_DIR_STRUCT */
 
-static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
-                            "magenta", "cyan", "white" };
-typedef struct {
-    int attr, bg, fg;
-} TextColors;
-TextColors textColors[(int)NColorClasses];
-
-/* String is: "fg, bg, attr". Which is 0, 1, 2 */
-static int
-parse_color (char *str, int which)
-{
-    char *p, buf[100], *d;
-    int i;
-
-    if (strlen(str) > 99)      /* watch bounds on buf */
-      return -1;
-
-    p = str;
-    d = buf;
-    for (i=0; i<which; ++i) {
-       p = strchr(p, ',');
-       if (!p)
-         return -1;
-       ++p;
-    }
-
-    /* Could be looking at something like:
-       black, , 1
-       .. in which case we want to stop on a comma also */
-    while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
-      ++p;
-
-    if (*p == ',') {
-       return -1;              /* Use default for empty field */
-    }
-
-    if (which == 2 || isdigit(*p))
-      return atoi(p);
-
-    while (*p && isalpha(*p))
-      *(d++) = *(p++);
-
-    *d = 0;
-
-    for (i=0; i<8; ++i) {
-       if (!StrCaseCmp(buf, cnames[i]))
-         return which? (i+40) : (i+30);
-    }
-    if (!StrCaseCmp(buf, "default")) return -1;
-
-    fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
-    return -2;
-}
-
-static int
-parse_cpair (ColorClass cc, char *str)
-{
-    if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
-       fprintf(stderr, _("%s: can't parse foreground color in `%s'\n"),
-               programName, str);
-       return -1;
-    }
-
-    /* bg and attr are optional */
-    textColors[(int)cc].bg = parse_color(str, 1);
-    if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
-       textColors[(int)cc].attr = 0;
-    }
-    return 0;
-}
-
 
 /* Arrange to catch delete-window events */
 Atom wm_delete_window;
@@ -915,9 +671,6 @@ BoardToTop ()
 #define OPTCHAR "-"
 #define SEPCHAR " "
 
-// these two must some day move to frontend.h, when they are implemented
-Boolean GameListIsUp();
-
 // The option definition and parsing code common to XBoard and WinBoard is collected in this file
 #include "args.h"
 
@@ -1079,29 +832,25 @@ ParseCommPortSettings (char *s)
 { // no such option in XBoard (yet)
 }
 
-extern Widget engineOutputShell;
 int frameX, frameY;
 
 void
 GetActualPlacement (Widget wg, WindowPlacement *wp)
 {
-  Arg args[16];
-  Dimension w, h;
-  Position x, y;
   XWindowAttributes winAt;
   Window win, dummy;
-  int i, rx, ry;
+  int rx, ry;
 
   if(!wg) return;
 
-    win = XtWindow(wg);
-    XGetWindowAttributes(xDisplay, win, &winAt); // this works, where XtGetValues on XtNx, XtNy does not!
-    XTranslateCoordinates (xDisplay, win, winAt.root, -winAt.border_width, -winAt.border_width, &rx, &ry, &dummy);
-    wp->x = rx - winAt.x;
-    wp->y = ry - winAt.y;
-    wp->height = winAt.height;
-    wp->width = winAt.width;
-    frameX = winAt.x; frameY = winAt.y; // remember to decide if windows touch
+  win = XtWindow(wg);
+  XGetWindowAttributes(xDisplay, win, &winAt); // this works, where XtGetValues on XtNx, XtNy does not!
+  XTranslateCoordinates (xDisplay, win, winAt.root, -winAt.border_width, -winAt.border_width, &rx, &ry, &dummy);
+  wp->x = rx - winAt.x;
+  wp->y = ry - winAt.y;
+  wp->height = winAt.height;
+  wp->width = winAt.width;
+  frameX = winAt.x; frameY = winAt.y; // remember to decide if windows touch
 }
 
 void
@@ -1109,10 +858,10 @@ GetWindowCoords ()
 { // wrapper to shield use of window handles from back-end (make addressible by number?)
   // In XBoard this will have to wait until awareness of window parameters is implemented
   GetActualPlacement(shellWidget, &wpMain);
-  if(EngineOutputIsUp()) GetActualPlacement(engineOutputShell, &wpEngineOutput);
-  if(MoveHistoryIsUp()) GetActualPlacement(shells[HistoryDlg], &wpMoveHistory);
-  if(EvalGraphIsUp()) GetActualPlacement(evalGraphShell, &wpEvalGraph);
-  if(GameListIsUp()) GetActualPlacement(gameListShell, &wpGameList);
+  if(shellUp[EngOutDlg]) GetActualPlacement(shells[EngOutDlg], &wpEngineOutput);
+  if(shellUp[HistoryDlg]) GetActualPlacement(shells[HistoryDlg], &wpMoveHistory);
+  if(shellUp[EvalGraphDlg]) GetActualPlacement(shells[EvalGraphDlg], &wpEvalGraph);
+  if(shellUp[GameListDlg]) GetActualPlacement(shells[GameListDlg], &wpGameList);
   if(shellUp[CommentDlg]) GetActualPlacement(shells[CommentDlg], &wpComment);
   if(shellUp[TagsDlg]) GetActualPlacement(shells[TagsDlg], &wpTags);
 }
@@ -1122,26 +871,6 @@ PrintCommPortSettings (FILE *f, char *name)
 { // This option does not exist in XBoard
 }
 
-int
-MySearchPath (char *installDir, char *name, char *fullname)
-{ // just append installDir and name. Perhaps ExpandPath should be used here?
-  name = ExpandPathName(name);
-  if(name && name[0] == '/')
-    safeStrCpy(fullname, name, MSG_SIZ );
-  else {
-    sprintf(fullname, "%s%c%s", installDir, '/', name);
-  }
-  return 1;
-}
-
-int
-MyGetFullPathName (char *name, char *fullname)
-{ // should use ExpandPath?
-  name = ExpandPathName(name);
-  safeStrCpy(fullname, name, MSG_SIZ );
-  return 1;
-}
-
 void
 EnsureOnScreen (int *x, int *y, int minX, int minY)
 {
@@ -1155,6 +884,17 @@ MainWindowUp ()
 }
 
 void
+SwitchWindow ()
+{
+    extern Option dualOptions[];
+    static Window dual;
+    Window tmp = xBoardWindow;
+    if(!dual) dual = XtWindow(dualOptions[3].handle); // must be first call
+    xBoardWindow = dual; // swap them
+    dual = tmp;
+}
+
+void
 PopUpStartupDialog ()
 {  // start menu not implemented in XBoard
 }
@@ -1182,89 +922,34 @@ ConvertToLine (int argc, char **argv)
 
 //--------------------------------------------------------------------------------------------
 
-#ifdef IDSIZES
-  // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
-#else
 #define BoardSize int
 void
 InitDrawingSizes (BoardSize boardSize, int flags)
 {   // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
-    Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
-    Arg args[16];
-    XtGeometryResult gres;
+    Dimension boardWidth, boardHeight, w, h;
     int i;
     static Dimension oldWidth, oldHeight;
     static VariantClass oldVariant;
-    static int oldDual = -1, oldMono = -1;
+    static int oldMono = -1, oldTwoBoards = 0;
 
     if(!formWidget) return;
 
+    if(oldTwoBoards && !twoBoards) PopDown(DummyDlg);
+    oldTwoBoards = twoBoards;
+
     if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap;
     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
 
-  if(boardWidth != oldWidth || boardHeight != oldHeight || oldDual != twoBoards) { // do resizing stuff only if size actually changed
-    /*
-     * Enable shell resizing.
-     */
-    shellArgs[0].value = (XtArgVal) &w;
-    shellArgs[1].value = (XtArgVal) &h;
-    XtGetValues(shellWidget, shellArgs, 2);
-
-    shellArgs[4].value = 3*w; shellArgs[2].value = 10;
-    shellArgs[5].value = 2*h; shellArgs[3].value = 10;
-    XtSetValues(shellWidget, &shellArgs[2], 4);
-
-    XtSetArg(args[0], XtNdefaultDistance, &sep);
-    XtGetValues(formWidget, args, 1);
+  if(boardWidth != oldWidth || boardHeight != oldHeight) { // do resizing stuff only if size actually changed
 
-    oldWidth = boardWidth; oldHeight = boardHeight; oldDual = twoBoards;
+    oldWidth = boardWidth; oldHeight = boardHeight;
     CreateGrid();
-    hOffset = boardWidth + 10;
-    for(i=0; i<BOARD_WIDTH+BOARD_HEIGHT+2; i++) { // [HGM] dual: grid for second board
-       secondSegments[i] = gridSegments[i];
-       secondSegments[i].x1 += hOffset;
-       secondSegments[i].x2 += hOffset;
-    }
-
-    XtSetArg(args[0], XtNwidth, boardWidth);
-    XtSetArg(args[1], XtNheight, boardHeight);
-    XtSetValues(boardWidget, args, 2);
-
-    timerWidth = (boardWidth - sep) / 2;
-    XtSetArg(args[0], XtNwidth, timerWidth);
-    XtSetValues(whiteTimerWidget, args, 1);
-    XtSetValues(blackTimerWidget, args, 1);
-
-    XawFormDoLayout(formWidget, False);
-
-    if (appData.titleInWindow) {
-       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 - 2; // WIDTH_FUDGE
-       }
-
-       gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
-       if (gres != XtGeometryYes && appData.debugMode) {
-           fprintf(stderr,
-                   _("%s: titleWidget geometry error %d %d %d %d %d\n"),
-                   programName, gres, w, h, wr, hr);
-       }
-    }
-
-    XawFormDoLayout(formWidget, True);
 
     /*
      * Inhibit shell resizing.
      */
-    shellArgs[0].value = w = (XtArgVal) boardWidth + marginW + twoBoards*hOffset; // [HGM] dual
+    shellArgs[0].value = w = (XtArgVal) boardWidth + marginW ;
     shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
     shellArgs[4].value = shellArgs[2].value = w;
     shellArgs[5].value = shellArgs[3].value = h;
@@ -1354,30 +1039,6 @@ InitDrawingSizes (BoardSize boardSize, int flags)
 #endif
   oldMono = appData.monoMode;
 }
-#endif
-
-void
-ParseIcsTextColors ()
-{   // [HGM] tken out of main(), so it can be called from ICS-Options dialog
-    if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
-       parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
-       parse_cpair(ColorChannel1, appData.colorChannel1) < 0  ||
-       parse_cpair(ColorChannel, appData.colorChannel) < 0  ||
-       parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
-       parse_cpair(ColorTell, appData.colorTell) < 0 ||
-       parse_cpair(ColorChallenge, appData.colorChallenge) < 0  ||
-       parse_cpair(ColorRequest, appData.colorRequest) < 0  ||
-       parse_cpair(ColorSeek, appData.colorSeek) < 0  ||
-       parse_cpair(ColorNormal, appData.colorNormal) < 0)
-      {
-         if (appData.colorize) {
-             fprintf(stderr,
-                     _("%s: can't parse color names; disabling colorization\n"),
-                     programName);
-         }
-         appData.colorize = FALSE;
-      }
-}
 
 static int
 MakeOneColor (char *name, Pixel *color)
@@ -1408,6 +1069,10 @@ MakeColors ()
     forceMono |= MakeOneColor(appData.blackPieceColor, &blackPieceColor);
     forceMono |= MakeOneColor(appData.highlightSquareColor, &highlightSquareColor);
     forceMono |= MakeOneColor(appData.premoveHighlightColor, &premoveHighlightColor);
+    if (appData.lowTimeWarning)
+       forceMono |= MakeOneColor(appData.lowTimeWarningColor, &lowTimeWarningColor);
+    if(appData.dialogColor[0]) MakeOneColor(appData.dialogColor, &dialogColor);
+    if(appData.buttonColor[0]) MakeOneColor(appData.buttonColor, &buttonColor);
 
     return forceMono;
 }
@@ -1441,17 +1106,69 @@ InitDrawingParams ()
     CreateAnyPieces();
 }
 
+void
+InitializeFonts (int clockFontPxlSize, int coordFontPxlSize, int fontPxlSize)
+{   // detervtomine what fonts to use, and create them
+    XrmValue vTo;
+    XrmDatabase xdb;
+
+    if(!fontIsSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize])
+       appData.clockFont = fontTable[CLOCK_FONT][squareSize];
+    if(!fontIsSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize])
+       appData.font = fontTable[MESSAGE_FONT][squareSize];
+    if(!fontIsSet[COORD_FONT] && fontValid[COORD_FONT][squareSize])
+       appData.coordFont = fontTable[COORD_FONT][squareSize];
+
+#if ENABLE_NLS
+    appData.font = InsertPxlSize(appData.font, fontPxlSize);
+    appData.clockFont = InsertPxlSize(appData.clockFont, clockFontPxlSize);
+    appData.coordFont = InsertPxlSize(appData.coordFont, coordFontPxlSize);
+    fontSet = CreateFontSet(appData.font);
+    clockFontSet = CreateFontSet(appData.clockFont);
+    {
+      /* For the coordFont, use the 0th font of the fontset. */
+      XFontSet coordFontSet = CreateFontSet(appData.coordFont);
+      XFontStruct **font_struct_list;
+      XFontSetExtents *fontSize;
+      char **font_name_list;
+      XFontsOfFontSet(coordFontSet, &font_struct_list, &font_name_list);
+      coordFontID = XLoadFont(xDisplay, font_name_list[0]);
+      coordFontStruct = XQueryFont(xDisplay, coordFontID);
+      fontSize = XExtentsOfFontSet(fontSet); // [HGM] figure out how much vertical space font takes
+      textHeight = fontSize->max_logical_extent.height + 5; // add borderWidth
+    }
+#else
+    appData.font = FindFont(appData.font, fontPxlSize);
+    appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
+    appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
+    clockFontID = XLoadFont(xDisplay, appData.clockFont);
+    clockFontStruct = XQueryFont(xDisplay, clockFontID);
+    coordFontID = XLoadFont(xDisplay, appData.coordFont);
+    coordFontStruct = XQueryFont(xDisplay, coordFontID);
+    // textHeight in !NLS mode!
+#endif
+    countFontID = coordFontID;  // [HGM] holdings
+    countFontStruct = coordFontStruct;
+
+    xdb = XtDatabase(xDisplay);
+#if ENABLE_NLS
+    XrmPutLineResource(&xdb, "*international: True");
+    vTo.size = sizeof(XFontSet);
+    vTo.addr = (XtPointer) &fontSet;
+    XrmPutResource(&xdb, "*fontSet", XtRFontSet, &vTo);
+#else
+    XrmPutStringResource(&xdb, "*font", appData.font);
+#endif
+}
+
 int
 main (int argc, char **argv)
 {
-    int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
+    int i, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
     XSetWindowAttributes window_attributes;
     Arg args[16];
-    Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
-    XrmValue vFrom, vTo;
-    XtGeometryResult gres;
+    Dimension boardWidth, boardHeight, w, h;
     char *p;
-    XrmDatabase xdb;
     int forceMono = False;
 
     srandom(time(0)); // [HGM] book: make random truly random
@@ -1473,14 +1190,14 @@ main (int argc, char **argv)
 
 #ifdef ENABLE_NLS
     XtSetLanguageProc(NULL, NULL, NULL);
+    if (appData.debugMode) {
+      fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL));
+    }
+
     bindtextdomain(PACKAGE, LOCALEDIR);
     textdomain(PACKAGE);
 #endif
 
-    shellWidget =
-      XtAppInitialize(&appContext, "XBoard", shellOptions,
-                     XtNumber(shellOptions),
-                     &argc, argv, xboardResources, NULL, 0);
     appData.boardSize = "";
     InitAppData(ConvertToLine(argc, argv));
     p = getenv("HOME");
@@ -1491,10 +1208,6 @@ main (int argc, char **argv)
     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.firstInitString);
@@ -1526,12 +1239,6 @@ main (int argc, char **argv)
         setbuf(debugFP, NULL);
     }
 
-#if ENABLE_NLS
-    if (appData.debugMode) {
-      fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL));
-    }
-#endif
-
     /* [HGM,HR] make sure board size is acceptable */
     if(appData.NrFiles > BOARD_FILES ||
        appData.NrRanks > BOARD_RANKS   )
@@ -1543,16 +1250,25 @@ main (int argc, char **argv)
 #endif
     InitBackEnd1();
 
+       gameInfo.variant = StringToVariant(appData.variant);
+       InitPosition(FALSE);
+
+    shellWidget =
+      XtAppInitialize(&appContext, "XBoard", shellOptions,
+                     XtNumber(shellOptions),
+                     &argc, argv, xboardResources, NULL, 0);
+
+    XtGetApplicationResources(shellWidget, (XtPointer) &appData,
+                             clientResources, XtNumber(clientResources),
+                             NULL, 0);
+
     xDisplay = XtDisplay(shellWidget);
     xScreen = DefaultScreen(xDisplay);
     wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
 
-       gameInfo.variant = StringToVariant(appData.variant);
-       InitPosition(FALSE);
-
-#ifdef IDSIZE
-    InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
-#else
+    /*
+     * determine size, based on supplied or remembered -size, or screen size
+     */
     if (isdigit(appData.boardSize[0])) {
         i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
                   &lineGap, &clockFontPxlSize, &coordFontPxlSize,
@@ -1609,12 +1325,6 @@ main (int argc, char **argv)
        tinyLayout = szd->tinyLayout;
        // [HGM] font: use defaults from settings file if available and not overruled
     }
-    if(!fontIsSet[CLOCK_FONT] && fontValid[CLOCK_FONT][squareSize])
-       appData.clockFont = fontTable[CLOCK_FONT][squareSize];
-    if(!fontIsSet[MESSAGE_FONT] && fontValid[MESSAGE_FONT][squareSize])
-       appData.font = fontTable[MESSAGE_FONT][squareSize];
-    if(!fontIsSet[COORD_FONT] && fontValid[COORD_FONT][squareSize])
-       appData.coordFont = fontTable[COORD_FONT][squareSize];
 
     /* Now, using squareSize as a hint, find a good XPM/XIM set size */
     if (strlen(appData.pixmapDirectory) > 0) {
@@ -1640,64 +1350,11 @@ XBoard square size (hint): %d\n\
     /* [HR] height treated separately (hacked) */
     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
-    if (appData.showJail == 1) {
-       /* Jail on top and bottom */
-       XtSetArg(boardArgs[1], XtNwidth, boardWidth);
-       XtSetArg(boardArgs[2], XtNheight,
-                boardHeight + 2*(lineGap + squareSize));
-    } else if (appData.showJail == 2) {
-       /* Jail on sides */
-       XtSetArg(boardArgs[1], XtNwidth,
-                boardWidth + 2*(lineGap + squareSize));
-       XtSetArg(boardArgs[2], XtNheight, boardHeight);
-    } else {
-       /* No jail */
-       XtSetArg(boardArgs[1], XtNwidth, boardWidth);
-       XtSetArg(boardArgs[2], XtNheight, boardHeight);
-    }
 
     /*
      * Determine what fonts to use.
      */
-#if ENABLE_NLS
-    appData.font = InsertPxlSize(appData.font, fontPxlSize);
-    appData.clockFont = InsertPxlSize(appData.clockFont, clockFontPxlSize);
-    appData.coordFont = InsertPxlSize(appData.coordFont, coordFontPxlSize);
-    fontSet = CreateFontSet(appData.font);
-    clockFontSet = CreateFontSet(appData.clockFont);
-    {
-      /* For the coordFont, use the 0th font of the fontset. */
-      XFontSet coordFontSet = CreateFontSet(appData.coordFont);
-      XFontStruct **font_struct_list;
-      XFontSetExtents *fontSize;
-      char **font_name_list;
-      XFontsOfFontSet(coordFontSet, &font_struct_list, &font_name_list);
-      coordFontID = XLoadFont(xDisplay, font_name_list[0]);
-      coordFontStruct = XQueryFont(xDisplay, coordFontID);
-      fontSize = XExtentsOfFontSet(fontSet); // [HGM] figure out how much vertical space font takes
-      textHeight = fontSize->max_logical_extent.height + 5; // add borderWidth
-    }
-#else
-    appData.font = FindFont(appData.font, fontPxlSize);
-    appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
-    appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
-    clockFontID = XLoadFont(xDisplay, appData.clockFont);
-    clockFontStruct = XQueryFont(xDisplay, clockFontID);
-    coordFontID = XLoadFont(xDisplay, appData.coordFont);
-    coordFontStruct = XQueryFont(xDisplay, coordFontID);
-#endif
-    countFontID = coordFontID;  // [HGM] holdings
-    countFontStruct = coordFontStruct;
-
-    xdb = XtDatabase(xDisplay);
-#if ENABLE_NLS
-    XrmPutLineResource(&xdb, "*international: True");
-    vTo.size = sizeof(XFontSet);
-    vTo.addr = (XtPointer) &fontSet;
-    XrmPutResource(&xdb, "*fontSet", XtRFontSet, &vTo);
-#else
-    XrmPutStringResource(&xdb, "*font", appData.font);
-#endif
+    InitializeFonts(clockFontPxlSize, coordFontPxlSize, fontPxlSize);
 
     /*
      * Detect if there are not enough colors available and adapt.
@@ -1714,16 +1371,6 @@ XBoard square size (hint): %d\n\
        appData.monoMode = True;
     }
 
-    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"),
                (unsigned long) XWhitePixel(xDisplay, xScreen),
@@ -1731,8 +1378,6 @@ XBoard square size (hint): %d\n\
     }
 
     ParseIcsTextColors();
-    textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
-    textColors[ColorNone].attr = 0;
 
     XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
 
@@ -1746,250 +1391,32 @@ XBoard square size (hint): %d\n\
     } 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, boardWidth);
-    XtSetArg(args[0], XtNtop,    XtChainTop);
-    XtSetArg(args[1], XtNbottom, XtChainTop);
-    XtSetArg(args[2], XtNright,  XtChainLeft);
-    XtSetValues(menuBarWidget, args, 3);
-
-    widgetList[j++] = whiteTimerWidget =
-      XtCreateWidget("whiteTime", labelWidgetClass,
-                    formWidget, timerArgs, XtNumber(timerArgs));
-#if ENABLE_NLS
-    XtSetArg(args[0], XtNfontSet, clockFontSet);
-#else
-    XtSetArg(args[0], XtNfont, clockFontStruct);
-#endif
-    XtSetArg(args[1], XtNtop,    XtChainTop);
-    XtSetArg(args[2], XtNbottom, XtChainTop);
-    XtSetValues(whiteTimerWidget, args, 3);
 
-    widgetList[j++] = blackTimerWidget =
-      XtCreateWidget("blackTime", labelWidgetClass,
-                    formWidget, timerArgs, XtNumber(timerArgs));
+    optList = BoardPopUp(squareSize, lineGap, (void*)
 #if ENABLE_NLS
-    XtSetArg(args[0], XtNfontSet, clockFontSet);
+                                               &clockFontSet);
 #else
-    XtSetArg(args[0], XtNfont, clockFontStruct);
+                                               &clockFonStruct);
 #endif
-    XtSetArg(args[1], XtNtop,    XtChainTop);
-    XtSetArg(args[2], XtNbottom, XtChainTop);
-    XtSetValues(blackTimerWidget, args, 3);
-
-    if (appData.titleInWindow) {
-       widgetList[j++] = titleWidget =
-         XtCreateWidget("title", labelWidgetClass, formWidget,
-                        titleArgs, XtNumber(titleArgs));
-       XtSetArg(args[0], XtNtop,    XtChainTop);
-       XtSetArg(args[1], XtNbottom, XtChainTop);
-       XtSetValues(titleWidget, args, 2);
-    }
-
-    if (appData.showButtonBar) {
-      widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
-      XtSetArg(args[0], XtNleft,  XtChainRight); // [HGM] glue to right window edge
-      XtSetArg(args[1], XtNright, XtChainRight); //       for good run-time sizing
-      XtSetArg(args[2], XtNtop,    XtChainTop);
-      XtSetArg(args[3], XtNbottom, XtChainTop);
-      XtSetValues(buttonBarWidget, args, 4);
-    }
-
-    widgetList[j++] = messageWidget =
-      XtCreateWidget("message", labelWidgetClass, formWidget,
-                    messageArgs, XtNumber(messageArgs));
-    XtSetArg(args[0], XtNtop,    XtChainTop);
-    XtSetArg(args[1], XtNbottom, XtChainTop);
-    XtSetValues(messageWidget, args, 2);
-
-    widgetList[j++] = boardWidget =
-      XtCreateWidget("board", widgetClass, formWidget, boardArgs,
-                    XtNumber(boardArgs));
-
-    XtManageChildren(widgetList, j);
-
-    timerWidth = (boardWidth - sep) / 2;
-    XtSetArg(args[0], XtNwidth, timerWidth);
-    XtSetValues(whiteTimerWidget, args, 1);
-    XtSetValues(blackTimerWidget, args, 1);
-
+    boardWidget      = optList[W_BOARD].handle;
+    menuBarWidget    = optList[W_MENU].handle;
+    dropMenu         = optList[W_DROP].handle;
+    titleWidget = optList[optList[W_TITLE].type != -1 ? W_TITLE : W_SMALL].handle;
+    formWidget  = XtParent(boardWidget);
     XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
     XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
-    XtGetValues(whiteTimerWidget, args, 2);
-
-    if (appData.showButtonBar) {
+    XtGetValues(optList[W_WHITE].handle, args, 2);
+    if (appData.showButtonBar) { // can't we use timer pixels for this? (Or better yet, just black & white?)
       XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
       XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
-      XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
-    }
-
-    /*
-     * formWidget uses these constraints but they are stored
-     * in the children.
-     */
-    i = 0;
-    XtSetArg(args[i], XtNfromHoriz, 0); i++;
-    XtSetValues(menuBarWidget, args, i);
-    if (appData.titleInWindow) {
-       if (smallLayout) {
-           i = 0;
-           XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
-           XtSetValues(whiteTimerWidget, args, i);
-           i = 0;
-           XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
-           XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
-           XtSetValues(blackTimerWidget, args, i);
-           i = 0;
-           XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
-            XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
-           XtSetValues(titleWidget, args, i);
-           i = 0;
-           XtSetArg(args[i], XtNfromVert, titleWidget); i++;
-           XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
-           XtSetValues(messageWidget, args, i);
-           if (appData.showButtonBar) {
-             i = 0;
-             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
-             XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
-             XtSetValues(buttonBarWidget, args, i);
-           }
-       } else {
-           i = 0;
-           XtSetArg(args[i], XtNfromVert, titleWidget); i++;
-           XtSetValues(whiteTimerWidget, args, i);
-           i = 0;
-           XtSetArg(args[i], XtNfromVert, titleWidget); i++;
-           XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
-           XtSetValues(blackTimerWidget, args, i);
-           i = 0;
-           XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
-           XtSetValues(titleWidget, args, i);
-           i = 0;
-           XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
-           XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
-           XtSetValues(messageWidget, args, i);
-           if (appData.showButtonBar) {
-             i = 0;
-             XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
-             XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
-             XtSetValues(buttonBarWidget, args, i);
-           }
-       }
-    } else {
-       i = 0;
-       XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
-       XtSetValues(whiteTimerWidget, args, i);
-       i = 0;
-       XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
-       XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
-       XtSetValues(blackTimerWidget, args, i);
-       i = 0;
-       XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
-       XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
-       XtSetValues(messageWidget, args, i);
-       if (appData.showButtonBar) {
-         i = 0;
-         XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
-         XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
-         XtSetValues(buttonBarWidget, args, i);
-       }
-    }
-    i = 0;
-    XtSetArg(args[0], XtNfromVert, messageWidget);
-    XtSetArg(args[1], XtNtop,    XtChainTop);
-    XtSetArg(args[2], XtNbottom, XtChainBottom);
-    XtSetArg(args[3], XtNleft,   XtChainLeft);
-    XtSetArg(args[4], XtNright,  XtChainRight);
-    XtSetValues(boardWidget, args, 5);
-
-    XtRealizeWidget(shellWidget);
-
-    if(wpMain.x > 0) {
-      XtSetArg(args[0], XtNx, wpMain.x);
-      XtSetArg(args[1], XtNy, wpMain.y);
-      XtSetValues(shellWidget, args, 2);
-    }
-
-    /*
-     * 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 */
-    }
-
-    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(!textHeight) textHeight = hr; // [HGM] if !NLS textHeight is still undefined, and we grab it from here
-    XtSetArg(args[0], XtNleft,  XtChainLeft);  // [HGM] glue ends for good run-time sizing
-    XtSetArg(args[1], XtNright, XtChainRight);
-    XtSetValues(messageWidget, args, 2);
-
-    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;
-       }
-
-       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);
-       }
+      XtGetValues(optList[W_PAUSE].handle, args, 2);
     }
-    XawFormDoLayout(formWidget, True);
+    AppendEnginesToMenu(appData.recentEngineList);
 
     xBoardWindow = XtWindow(boardWidget);
 
     // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
     //       not need to go into InitDrawingSizes().
-#endif
 
     /*
      * Create X checkmark bitmap and initialize option menu checks.
@@ -2035,25 +1462,12 @@ XBoard square size (hint): %d\n\
     CreateGrid();
     CreateAnyPieces();
 
-    CreatePieceMenus();
-
     if (appData.animate || appData.animateDragging)
       CreateAnimVars();
 
     XtAugmentTranslations(formWidget,
                          XtParseTranslationTable(globalTranslations));
-    XtAugmentTranslations(boardWidget,
-                         XtParseTranslationTable(boardTranslations));
-    XtAugmentTranslations(whiteTimerWidget,
-                         XtParseTranslationTable(whiteTranslations));
-    XtAugmentTranslations(blackTimerWidget,
-                         XtParseTranslationTable(blackTranslations));
-
-    /* Why is the following needed on some versions of X instead
-     * of a translation? */
-    XtAddEventHandler(boardWidget, ExposureMask|PointerMotionMask, False,
-                     (XtEventHandler) EventProc, NULL);
-    /* end why */
+
     XtAddEventHandler(formWidget, KeyPressMask, False,
                      (XtEventHandler) MoveTypeInProc, NULL);
     XtAddEventHandler(shellWidget, StructureNotifyMask, False,
@@ -2103,20 +1517,6 @@ XBoard square size (hint): %d\n\
     return 0;
 }
 
-static Boolean noEcho;
-
-void
-ShutDownFrontEnd ()
-{
-    if (appData.icsActive && oldICSInteractionTitle != NULL) {
-        DisplayIcsInteractionTitle(oldICSInteractionTitle);
-    }
-    if (saveSettingsOnExit) SaveSettings(settingsFileName);
-    unlink(gameCopyFilename);
-    unlink(gamePasteFilename);
-    if(noEcho) EchoOn();
-}
-
 RETSIGTYPE
 TermSizeSigHandler (int sig)
 {
@@ -2152,46 +1552,6 @@ CmailSigHandlerCallBack (InputSourceRef isr, VOIDSTAR closure, char *message, in
 /**** end signal code ****/
 
 
-void
-ICSInitScript ()
-{
-  /* try to open the icsLogon script, either in the location given
-   * or in the users HOME directory
-   */
-
-  FILE *f;
-  char buf[MSG_SIZ];
-  char *homedir;
-
-  f = fopen(appData.icsLogon, "r");
-  if (f == NULL)
-    {
-      homedir = getenv("HOME");
-      if (homedir != NULL)
-       {
-         safeStrCpy(buf, homedir, sizeof(buf)/sizeof(buf[0]) );
-         strncat(buf, "/", MSG_SIZ - strlen(buf) - 1);
-         strncat(buf, appData.icsLogon,  MSG_SIZ - strlen(buf) - 1);
-         f = fopen(buf, "r");
-       }
-    }
-
-  if (f != NULL)
-    ProcessICSInitScript(f);
-  else
-    printf("Warning: Couldn't open icsLogon file (checked %s and %s).\n", appData.icsLogon, buf);
-
-  return;
-}
-
-void
-ResetFrontEnd ()
-{
-    CommentPopDown();
-    TagsPopDown();
-    return;
-}
-
 #define Abs(n) ((n)<0 ? -(n) : (n))
 
 #ifdef ENABLE_NLS
@@ -2364,13 +1724,10 @@ DeleteGCs ()
        }
     } else {
        XtReleaseGC(shellWidget, prelineGC);
-       XtReleaseGC(shellWidget, jailSquareGC);
        XtReleaseGC(shellWidget, wdPieceGC);
        XtReleaseGC(shellWidget, wlPieceGC);
-       XtReleaseGC(shellWidget, wjPieceGC);
        XtReleaseGC(shellWidget, bdPieceGC);
        XtReleaseGC(shellWidget, blPieceGC);
-       XtReleaseGC(shellWidget, bjPieceGC);
     }
 }
 
@@ -2387,8 +1744,6 @@ CreateOneGC (XGCValues *gc_values, Pixel foreground, Pixel background)
 static void
 CreateGCs (int redo)
 {
-    XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
-      | GCBackground | GCFunction | GCPlaneMask;
     XGCValues gc_values;
     GC copyInvertedGC;
     Pixel white = XWhitePixel(xDisplay, xScreen);
@@ -2436,13 +1791,10 @@ CreateGCs (int redo)
        prelineGC = CreateOneGC(&gc_values, premoveHighlightColor, premoveHighlightColor);
        lightSquareGC = CreateOneGC(&gc_values, lightSquareColor, darkSquareColor);
        darkSquareGC = CreateOneGC(&gc_values, darkSquareColor, lightSquareColor);
-       jailSquareGC = CreateOneGC(&gc_values, jailSquareColor, jailSquareColor);
        wdPieceGC = CreateOneGC(&gc_values, whitePieceColor, darkSquareColor);
        wlPieceGC = CreateOneGC(&gc_values, whitePieceColor, lightSquareColor);
-       wjPieceGC = CreateOneGC(&gc_values, whitePieceColor, jailSquareColor);
        bdPieceGC = CreateOneGC(&gc_values, blackPieceColor, darkSquareColor);
        blPieceGC = CreateOneGC(&gc_values, blackPieceColor, lightSquareColor);
-       bjPieceGC = CreateOneGC(&gc_values, blackPieceColor, jailSquareColor);
     }
 }
 
@@ -2916,64 +2268,30 @@ CreateGrid ()
     }
 }
 
-int nrOfMenuItems = 7;
-Widget menuWidget[150];
-MenuListItem menuItemList[150] = {
-    { "LoadNextGameProc", LoadNextGameProc },
-    { "LoadPrevGameProc", LoadPrevGameProc },
-    { "ReloadGameProc", ReloadGameProc },
-    { "ReloadPositionProc", ReloadPositionProc },
-#ifndef OPTIONSDIALOG
-    { "AlwaysQueenProc", AlwaysQueenProc },
-    { "AnimateDraggingProc", AnimateDraggingProc },
-    { "AnimateMovingProc", AnimateMovingProc },
-    { "AutoflagProc", AutoflagProc },
-    { "AutoflipProc", AutoflipProc },
-    { "BlindfoldProc", BlindfoldProc },
-    { "FlashMovesProc", FlashMovesProc },
-#if HIGHDRAG
-    { "HighlightDraggingProc", HighlightDraggingProc },
-#endif
-    { "HighlightLastMoveProc", HighlightLastMoveProc },
-//    { "IcsAlarmProc", IcsAlarmProc },
-    { "MoveSoundProc", MoveSoundProc },
-    { "PeriodicUpdatesProc", PeriodicUpdatesProc },
-    { "PopupExitMessageProc", PopupExitMessageProc },
-    { "PopupMoveErrorsProc", PopupMoveErrorsProc },
-//    { "PremoveProc", PremoveProc },
-    { "ShowCoordsProc", ShowCoordsProc },
-    { "ShowThinkingProc", ShowThinkingProc },
-    { "HideThinkingProc", HideThinkingProc },
-    { "TestLegalityProc", TestLegalityProc },
-#endif
-    { "AboutGameProc", AboutGameEvent },
-    { "DebugProc", DebugProc },
-    { "NothingProc", NothingProc },
-  {NULL, NothingProc}
-};
-
 void
 MarkMenuItem (char *menuRef, int state)
 {
-    int nr = MenuToNumber(menuRef);
-    if(nr >= 0) {
+    MenuItem *item = MenuNameToItem(menuRef);
+
+    if(item) {
        Arg args[2];
        XtSetArg(args[0], XtNleftBitmap, state ? xMarkPixmap : None);
-       XtSetValues(menuWidget[nr], args, 1);
+       XtSetValues(item->handle, args, 1);
     }
 }
 
 void
 EnableMenuItem (char *menuRef, int state)
 {
-    int nr = MenuToNumber(menuRef);
-    if(nr >= 0) XtSetSensitive(menuWidget[nr], state);
+    MenuItem *item = MenuNameToItem(menuRef);
+
+    if(item) XtSetSensitive(item->handle, state);
 }
 
 void
 EnableButtonBar (int state)
 {
-    XtSetSensitive(buttonBarWidget, state);
+    XtSetSensitive(optList[W_BUTTON].handle, state);
 }
 
 
@@ -2986,35 +2304,13 @@ SetMenuEnables (Enables *enab)
   }
 }
 
-int
-Equal(char *p, char *s)
-{   // compare strings skipping spaces in second
-    while(*s) {
-       if(*s == ' ') { s++; continue; }
-       if(*s++ != *p++) return 0;
-    }
-    return !*p;
-}
-
 void
 KeyBindingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 {   // [HGM] new method of key binding: specify MenuItem(FlipView) in stead of FlipViewProc in translation string
-    int i;
+    MenuItem *item;
     if(*nprms == 0) return;
-    for(i=0; menuItemList[i].name; i++) {
-       if(Equal(prms[0], menuItemList[i].name)) {
-           (menuItemList[i].proc) ();
-           return;
-       }
-    }
-}
-
-static void
-MenuBarSelect (Widget w, caddr_t addr, caddr_t index)
-{
-    MenuProc *proc = (MenuProc *) addr;
-
-    (proc)();
+    item = MenuNameToItem(prms[0]);
+    if(item) ((MenuProc *) item->proc) ();
 }
 
 static void
@@ -3023,194 +2319,10 @@ MenuEngineSelect (Widget w, caddr_t addr, caddr_t index)
     RecentEngineEvent((int) (intptr_t) addr);
 }
 
-// some stuff that must remain in front-end
-static Widget mainBar, currentMenu;
-static int wtot, nr = 0, widths[10];
-
 void
-AppendMenuItem (char *text, char *name, MenuProc *action)
+AppendMenuItem (char *msg, int n)
 {
-    int j;
-    Widget entry;
-    Arg args[16];
-
-    j = 0;
-    XtSetArg(args[j], XtNleftMargin, 20);   j++;
-    XtSetArg(args[j], XtNrightMargin, 20);  j++;
-
-       if (strcmp(text, "----") == 0) {
-         entry = XtCreateManagedWidget(text, smeLineObjectClass,
-                                         currentMenu, args, j);
-       } else {
-          XtSetArg(args[j], XtNlabel, XtNewString(_(text)));
-           entry = XtCreateManagedWidget(name, smeBSBObjectClass,
-                                         currentMenu, args, j+1);
-           XtAddCallback(entry, XtNcallback,
-                         (XtCallbackProc) (strcmp(name, "recent") ? MenuBarSelect : MenuEngineSelect),
-                         (caddr_t) action);
-           menuWidget[nrOfMenuItems] = entry;
-       }
-}
-
-void
-CreateMenuButton (char *name, Menu *mb)
-{   // create menu button on main bar, and shell for pull-down list
-    int i, j;
-    Arg args[16];
-    Dimension w;
-
-       j = 0;
-       XtSetArg(args[j], XtNmenuName, XtNewString(name));  j++;
-       XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name)));  j++;
-       XtSetArg(args[j], XtNborderWidth, 0);                   j++;
-       mb->subMenu = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,
-                                      mainBar, args, j);
-    currentMenu = XtCreatePopupShell(name, simpleMenuWidgetClass,
-                             mainBar, NULL, 0);
-       j = 0;
-       XtSetArg(args[j], XtNwidth, &w);                   j++;
-       XtGetValues(mb->subMenu, args, j);
-       wtot += mb->textWidth = widths[nr++] = w;
-}
-
-Widget
-CreateMenuBar (Menu *mb, int boardWidth)
-{
-    int i, j;
-    Arg args[16];
-    char menuName[MSG_SIZ];
-    Dimension w;
-    Menu *ma = mb;
-
-    // create bar itself
-    j = 0;
-    XtSetArg(args[j], XtNorientation, XtorientHorizontal);  j++;
-    XtSetArg(args[j], XtNvSpace, 0);                        j++;
-    XtSetArg(args[j], XtNborderWidth, 0);                   j++;
-    mainBar = XtCreateWidget("menuBar", boxWidgetClass,
-                            formWidget, args, j);
-
-    CreateMainMenus(mb); // put menus in bar according to description in back-end
-
-    // size buttons to make menu bar fit, clipping menu names where necessary
-    while(wtot > boardWidth - 40) {
-       int wmax=0, imax=0;
-       for(i=0; i<nr; i++) if(widths[i] > wmax) wmax = widths[imax=i];
-       widths[imax]--;
-       wtot--;
-    }
-    for(i=0; i<nr; i++) if(widths[i] != ma[i].textWidth) {
-       j = 0;
-       XtSetArg(args[j], XtNwidth, widths[i]);                   j++;
-       XtSetValues(ma[i].subMenu, args, j);
-    }
-
-    return mainBar;
-}
-
-Widget
-CreateButtonBar (MenuItem *mi)
-{
-    int j;
-    Widget button, buttonBar;
-    Arg args[16];
-
-    j = 0;
-    XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
-    if (tinyLayout) {
-       XtSetArg(args[j], XtNhSpace, 0); j++;
-    }
-    XtSetArg(args[j], XtNborderWidth, 0); j++;
-    XtSetArg(args[j], XtNvSpace, 0);                        j++;
-    buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,
-                              formWidget, args, j);
-
-    while (mi->string != NULL) {
-       j = 0;
-       if (tinyLayout) {
-           XtSetArg(args[j], XtNinternalWidth, 2); j++;
-           XtSetArg(args[j], XtNborderWidth, 0); j++;
-       }
-      XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); j++;
-       button = XtCreateManagedWidget(mi->string, commandWidgetClass,
-                                      buttonBar, args, j);
-       XtAddCallback(button, XtNcallback,
-                     (XtCallbackProc) MenuBarSelect,
-                     (caddr_t) mi->proc);
-       mi++;
-    }
-    return buttonBar;
-}
-
-Widget
-CreatePieceMenu (char *name, int color)
-{
-    int i;
-    Widget entry, menu;
-    Arg args[16];
-    ChessSquare selection;
-
-    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, args, 1);
-           selection = pieceMenuTranslation[color][i];
-           XtAddCallback(entry, XtNcallback,
-                         (XtCallbackProc) PieceMenuSelect,
-                         (caddr_t) selection);
-           if (selection == WhitePawn || selection == BlackPawn) {
-               XtSetArg(args[0], XtNpopupOnEntry, entry);
-               XtSetValues(menu, args, 1);
-           }
-       }
-    }
-    return menu;
-}
-
-void
-CreatePieceMenus ()
-{
-    int i;
-    Widget entry;
-    Arg args[16];
-    ChessSquare selection;
-
-    whitePieceMenu = CreatePieceMenu("menuW", 0);
-    blackPieceMenu = CreatePieceMenu("menuB", 1);
-
-    if(appData.pieceMenu) // [HGM] sweep: no idea what this was good for, but it stopped reporting button events outside the window
-    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);
-       }
-    }
+    CreateMenuItem((Widget) optList[W_ENGIN].textValue, msg, (XtCallbackProc) MenuEngineSelect, n);
 }
 
 void
@@ -3238,53 +2350,6 @@ SetupDropMenu ()
     }
 }
 
-void
-PieceMenuPopup (Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
-    String whichMenu; int menuNr = -2;
-    shiftKey = strcmp(params[0], "menuW"); // used to indicate black
-    if (event->type == ButtonRelease)
-        menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY);
-    else if (event->type == ButtonPress)
-        menuNr = RightClick(Press,   event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY);
-    switch(menuNr) {
-      case 0: whichMenu = params[0]; break;
-      case 1: SetupDropMenu(); whichMenu = "menuD"; break;
-      case 2:
-      case -1: if (errorUp) ErrorPopDown();
-      default: return;
-    }
-    XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu));
-}
-
-static void
-PieceMenuSelect (Widget w, ChessSquare piece, caddr_t junk)
-{
-    if (pmFromX < 0 || pmFromY < 0) return;
-    EditPositionMenuEvent(piece, pmFromX, pmFromY);
-}
-
-static void
-DropMenuSelect (Widget w, ChessSquare piece, caddr_t junk)
-{
-    if (pmFromX < 0 || pmFromY < 0) return;
-    DropMenuEvent(piece, pmFromX, pmFromY);
-}
-
-void
-WhiteClock (Widget w, XEvent *event, String *prms, Cardinal *nprms)
-{
-    shiftKey = prms[0][0] & 1;
-    ClockClick(0);
-}
-
-void
-BlackClock (Widget w, XEvent *event, String *prms, Cardinal *nprms)
-{
-    shiftKey = prms[0][0] & 1;
-    ClockClick(1);
-}
-
 
 static void
 do_flash_delay (unsigned long msec)
@@ -3340,7 +2405,7 @@ BlankSquare (int x, int y, int color, ChessSquare piece, Drawable dest, int fac)
            break;
          case 2: /* neutral */
          default:
-           pm = xpmJailSquare;
+           pm = xpmJailSquare; // [HGM] this is wrong, but apparently never used?
            break;
        }
        XCopyArea(xDisplay, pm, dest, wlPieceGC, 0, 0,
@@ -3356,7 +2421,7 @@ BlankSquare (int x, int y, int color, ChessSquare piece, Drawable dest, int fac)
            break;
          case 2: /* neutral */
          default:
-           gc = jailSquareGC;
+           gc = lineGC;
            break;
        }
        XFillRectangle(xDisplay, dest, gc, x*fac, y*fac, squareSize, squareSize);
@@ -3433,11 +2498,7 @@ colorDrawPiece (ChessSquare piece, int square_color, int x, int y, Drawable dest
        break;
       case 2: /* neutral */
       default:
-       XCopyPlane(xDisplay, *pieceToSolid(piece),
-                  dest, (int) piece < (int) BlackPawn
-                  ? wjPieceGC : bjPieceGC, 0, 0,
-                  squareSize, squareSize, x, y, 1);
-       break;
+       break; // should never contain pieces
     }
 }
 
@@ -3618,10 +2679,10 @@ DragProc ()
        if(wpNew.x == wpMain.x && wpNew.y == wpMain.y && // not moved
           wpNew.width == wpMain.width && wpNew.height == wpMain.height) // not sized
            return; // false alarm
-       if(EngineOutputIsUp()) CoDrag(engineOutputShell, &wpEngineOutput);
-       if(MoveHistoryIsUp()) CoDrag(shells[HistoryDlg], &wpMoveHistory);
-       if(EvalGraphIsUp()) CoDrag(evalGraphShell, &wpEvalGraph);
-       if(GameListIsUp()) CoDrag(gameListShell, &wpGameList);
+       if(shellUp[EngOutDlg]) CoDrag(shells[EngOutDlg], &wpEngineOutput);
+       if(shellUp[HistoryDlg]) CoDrag(shells[HistoryDlg], &wpMoveHistory);
+       if(shellUp[EvalGraphDlg]) CoDrag(shells[EvalGraphDlg], &wpEvalGraph);
+       if(shellUp[GameListDlg]) CoDrag(shells[GameListDlg], &wpGameList);
        wpMain = wpNew;
        DrawPosition(True, NULL);
        delayedDragID = 0; // now drag executed, make sure next DelayedDrag will not cancel timer event (which could now be used by other)
@@ -3636,33 +2697,12 @@ DelayedDrag ()
       XtAppAddTimeOut(appContext, 50, (XtTimerCallbackProc) DragProc, (XtPointer) 0); // and schedule new one 50 msec later
 }
 
-/* Why is this needed on some versions of X? */
 void
 EventProc (Widget widget, caddr_t unused, XEvent *event)
 {
-    if (!XtIsRealized(widget))
-      return;
-    switch (event->type) {
-      case ConfigureNotify: // main window is being dragged: drag attached windows with it
-       if(appData.useStickyWindows)
-           DelayedDrag(); // as long as events keep coming in faster than 50 msec, they destroy each other
-       break;
-      case Expose:
-       if (event->xexpose.count > 0) return;  /* no clipping is done */
-       DrawPosition(True, NULL);
-       if(twoBoards) { // [HGM] dual: draw other board in other orientation
-           flipView = !flipView; partnerUp = !partnerUp;
-           DrawPosition(True, NULL);
-           flipView = !flipView; partnerUp = !partnerUp;
-       }
-       break;
-      case MotionNotify:
-        if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break;
-      default:
-       return;
-    }
+    if(XtIsRealized(widget) && event->type == ConfigureNotify || appData.useStickyWindows)
+       DelayedDrag(); // as long as events keep coming in faster than 50 msec, they destroy each other
 }
-/* end why */
 
 // [HGM] seekgraph: some low-level drawing routines cloned from xevalgraph
 void
@@ -3699,10 +2739,9 @@ DrawSeekDot (int x, int y, int colorNr)
 }
 
 void
-DrawGrid (int second)
+DrawGrid ()
 {
          XDrawSegments(xDisplay, xBoardWindow, lineGC,
-                       second ? secondSegments : // [HGM] dual
                        gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);
 }
 
@@ -3717,46 +2756,6 @@ DrawPositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 }
 
 
-/*
- * 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 (Widget w, XEvent *event, String *prms, Cardinal *nprms)
-{
-    if (w != boardWidget || errorExitStatus != -1) return;
-    if(nprms) shiftKey = !strcmp(prms[0], "1");
-
-    if (promotionUp) {
-       if (event->type == ButtonPress) {
-           XtPopdown(promotionShell);
-           XtDestroyWidget(promotionShell);
-           promotionUp = False;
-           ClearHighlights();
-           fromX = fromY = -1;
-       } else {
-           return;
-       }
-    }
-
-    // [HGM] mouse: the rest of the mouse handler is moved to the backend, and called here
-    if(event->type == ButtonPress)   LeftClick(Press,   event->xbutton.x, event->xbutton.y);
-    if(event->type == ButtonRelease) LeftClick(Release, event->xbutton.x, event->xbutton.y);
-}
-
-void
-AnimateUserMove (Widget w, XEvent *event, String *params, Cardinal *nParams)
-{
-    if(!PromoScroll(event->xmotion.x, event->xmotion.y))
-    DragPieceMove(event->xmotion.x, event->xmotion.y);
-}
-
 void
 HandlePV (Widget w, XEvent * event, String * params, Cardinal * nParams)
 {   // [HGM] pv: walk PV
@@ -3789,20 +2788,6 @@ EditCommentPopUp (int index, char *title, char *text)
 }
 
 void
-ICSInputBoxPopUp ()
-{
-    InputBoxPopup();
-}
-
-extern Option boxOptions[];
-
-void
-ICSInputBoxPopDown ()
-{
-    PopDown(InputBoxDlg);
-}
-
-void
 CommentPopUp (char *title, char *text)
 {
     savedIndex = currentMove; // [HGM] vari
@@ -3830,286 +2815,11 @@ FileNamePopUp (char *label, char *def, char *filter, FileProc proc, char *openMo
     fileProc = proc;           /* I can't see a way not */
     fileOpenMode = openMode;   /*   to use globals here */
     {   // [HGM] use file-selector dialog stolen from Ghostview
-       int index; // this is not supported yet
-       if(openFP = XsraSelFile(shellWidget, label, NULL, NULL, _("could not open: "),
-                          (def[0] ? def : NULL), filter, openMode, NULL, &openName))
-         // [HGM] delay to give expose event opportunity to redraw board after browser-dialog popdown before lengthy load starts
-         ScheduleDelayedEvent(&DelayedLoad, 50);
+       // int index; // this is not supported yet
+       Browse(BoardWindow, label, (def[0] ? def : NULL), filter, False, openMode, &openName, &openFP);
     }
 }
 
-void
-FileNamePopDown ()
-{
-    if (!filenameUp) return;
-    XtPopdown(fileNameShell);
-    XtDestroyWidget(fileNameShell);
-    filenameUp = False;
-    ModeHighlight();
-}
-
-void
-FileNameCallback (Widget w, XtPointer client_data, XtPointer call_data)
-{
-    String name;
-    Arg args[16];
-
-    XtSetArg(args[0], XtNlabel, &name);
-    XtGetValues(w, args, 1);
-
-    if (strcmp(name, _("cancel")) == 0) {
-        FileNamePopDown();
-        return;
-    }
-
-    FileNameAction(w, NULL, NULL, NULL);
-}
-
-void
-FileNameAction (Widget w, XEvent *event, String *prms, Cardinal *nprms)
-{
-    char buf[MSG_SIZ];
-    String name;
-    FILE *f;
-    char *p, *fullname;
-    int index;
-
-    name = XawDialogGetValueString(w = XtParent(w));
-
-    if ((name != NULL) && (*name != NULLCHAR)) {
-        safeStrCpy(buf, name, sizeof(buf)/sizeof(buf[0]) );
-       XtPopdown(w = XtParent(XtParent(w)));
-       XtDestroyWidget(w);
-       filenameUp = False;
-
-       p = strrchr(buf, ' ');
-       if (p == NULL) {
-           index = 0;
-       } else {
-           *p++ = NULLCHAR;
-           index = atoi(p);
-       }
-       fullname = ExpandPathName(buf);
-       if (!fullname) {
-           ErrorPopUp(_("Error"), _("Can't open file"), FALSE);
-       }
-       else {
-           f = fopen(fullname, fileOpenMode);
-           if (f == NULL) {
-               DisplayError(_("Failed to open file"), errno);
-           } else {
-               (void) (*fileProc)(f, index, buf);
-           }
-       }
-       ModeHighlight();
-       return;
-    }
-
-    XtPopdown(w = XtParent(XtParent(w)));
-    XtDestroyWidget(w);
-    filenameUp = False;
-    ModeHighlight();
-}
-
-void
-PromotionPopUp ()
-{
-    Arg args[16];
-    Widget dialog, layout;
-    Position x, y;
-    Dimension bw_width, pw_width;
-    int j;
-    char *PromoChars = "wglcqrbnkac+=\0";
-
-    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 to what?")); j++;
-    XtSetArg(args[j], XtNborderWidth, 0); j++;
-    dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
-                                  layout, args, j);
-
-  if(gameInfo.variant != VariantShogi) {
-   if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) {
-      XawDialogAddButton(dialog, _("Warlord"), PromotionCallback, PromoChars + 0);
-      XawDialogAddButton(dialog, _("General"), PromotionCallback, PromoChars + 1);
-      XawDialogAddButton(dialog, _("Lieutenant"), PromotionCallback, PromoChars + 2);
-      XawDialogAddButton(dialog, _("Captain"), PromotionCallback, PromoChars + 3);
-    } else {
-    XawDialogAddButton(dialog, _("Queen"), PromotionCallback, PromoChars + 4);
-    XawDialogAddButton(dialog, _("Rook"), PromotionCallback, PromoChars + 5);
-    XawDialogAddButton(dialog, _("Bishop"), PromotionCallback, PromoChars + 6);
-    XawDialogAddButton(dialog, _("Knight"), PromotionCallback, PromoChars + 7);
-    }
-    if (!appData.testLegality || gameInfo.variant == VariantSuicide ||
-        gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove) ||
-        gameInfo.variant == VariantGiveaway) {
-      XawDialogAddButton(dialog, _("King"), PromotionCallback, PromoChars + 8);
-    }
-    if(gameInfo.variant == VariantCapablanca ||
-       gameInfo.variant == VariantGothic ||
-       gameInfo.variant == VariantCapaRandom) {
-      XawDialogAddButton(dialog, _("Archbishop"), PromotionCallback, PromoChars + 9);
-      XawDialogAddButton(dialog, _("Chancellor"), PromotionCallback, PromoChars + 10);
-    }
-  } else // [HGM] shogi
-  {
-      XawDialogAddButton(dialog, _("Promote"), PromotionCallback, PromoChars + 11);
-      XawDialogAddButton(dialog, _("Defer"), PromotionCallback, PromoChars + 12);
-  }
-    XawDialogAddButton(dialog, _("cancel"), PromotionCallback, PromoChars + 13);
-
-    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 == 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;
-}
-
-void
-PromotionPopDown ()
-{
-    if (!promotionUp) return;
-    XtPopdown(promotionShell);
-    XtDestroyWidget(promotionShell);
-    promotionUp = False;
-}
-
-void
-PromotionCallback (Widget w, XtPointer client_data, XtPointer call_data)
-{
-    int promoChar = * (const char *) client_data;
-
-    PromotionPopDown();
-
-    if (fromX == -1) return;
-
-    if (! promoChar) {
-       fromX = fromY = -1;
-       ClearHighlights();
-       return;
-    }
-    UserMoveEvent(fromX, fromY, toX, toY, promoChar);
-
-    if (!appData.highlightLastMove || gotPremove) ClearHighlights();
-    if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
-    fromX = fromY = -1;
-}
-
-
-void
-ErrorCallback (Widget w, XtPointer client_data, XtPointer call_data)
-{
-    dialogError = errorUp = False;
-    XtPopdown(w = XtParent(XtParent(XtParent(w))));
-    XtDestroyWidget(w);
-    if (errorExitStatus != -1) ExitEvent(errorExitStatus);
-}
-
-
-void
-ErrorPopDown ()
-{
-    if (!errorUp) return;
-    dialogError = errorUp = False;
-    XtPopdown(errorShell);
-    XtDestroyWidget(errorShell);
-    if (errorExitStatus != -1) ExitEvent(errorExitStatus);
-}
-
-void
-ErrorPopUp (char *title, char *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,
-                        shellUp[TransientDlg] ? (dialogError = modal = TRUE, shells[TransientDlg]) : shellWidget, args, i);
-    layout =
-      XtCreateManagedWidget(layoutName, formWidgetClass, errorShell,
-                           layoutArgs, XtNumber(layoutArgs));
-
-    i = 0;
-    XtSetArg(args[i], XtNlabel, label); i++;
-    XtSetArg(args[i], XtNborderWidth, 0); i++;
-    dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
-                                  layout, args, i);
-
-    XawDialogAddButton(dialog, _("ok"), ErrorCallback, (XtPointer) dialog);
-
-    XtRealizeWidget(errorShell);
-    CatchDeleteWindow(errorShell, "ErrorPopDown");
-
-    i = 0;
-    XtSetArg(args[i], XtNwidth, &bw_width);  i++;
-    XtGetValues(boardWidget, args, i);
-    i = 0;
-    XtSetArg(args[i], XtNwidth, &pw_width);  i++;
-    XtSetArg(args[i], XtNheight, &pw_height);  i++;
-    XtGetValues(errorShell, args, i);
-
-#ifdef NOTDEF
-    /* This code seems to tickle an X bug if it is executed too soon
-       after xboard starts up.  The coordinates get transformed as if
-       the main window was positioned at (0, 0).
-       */
-    XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
-                     0 - pw_height + squareSize / 3, &x, &y);
-#else
-    XTranslateCoordinates(xDisplay, XtWindow(boardWidget),
-                         RootWindowOfScreen(XtScreen(boardWidget)),
-                         (bw_width - pw_width) / 2,
-                         0 - pw_height + squareSize / 3, &xx, &yy, &junk);
-    x = xx;
-    y = yy;
-#endif
-    if (y < 0) y = 0; /*avoid positioning top offscreen*/
-
-    i = 0;
-    XtSetArg(args[i], XtNx, x);  i++;
-    XtSetArg(args[i], XtNy, y);  i++;
-    XtSetValues(errorShell, args, i);
-
-    errorUp = True;
-    XtPopup(errorShell, modal ? XtGrabExclusive : XtGrabNone);
-}
 
 /* Disable all user input other than deleting the window */
 static int frozen = 0;
@@ -4119,7 +2829,7 @@ FreezeUI ()
 {
   if (frozen) return;
   /* Grab by a widget that doesn't accept input */
-  XtAddGrab(messageWidget, TRUE, FALSE);
+  XtAddGrab(optList[W_MESSG].handle, TRUE, FALSE);
   frozen = 1;
 }
 
@@ -4128,7 +2838,7 @@ void
 ThawUI ()
 {
   if (!frozen) return;
-  XtRemoveGrab(messageWidget);
+  XtRemoveGrab(optList[W_MESSG].handle);
   frozen = 0;
 }
 
@@ -4144,7 +2854,7 @@ ModeHighlight ()
 
     if (pausing != oldPausing) {
        oldPausing = pausing;
-       MarkMenuItem("Pause", pausing);
+       MarkMenuItem("Mode.Pause", pausing);
 
        if (appData.showButtonBar) {
          /* Always toggle, don't set.  Previous code messes up when
@@ -4154,12 +2864,12 @@ ModeHighlight ()
            Pixel oldbg, oldfg;
            XtSetArg(args[0], XtNbackground, &oldbg);
            XtSetArg(args[1], XtNforeground, &oldfg);
-           XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON),
+           XtGetValues(optList[W_PAUSE].handle,
                        args, 2);
            XtSetArg(args[0], XtNbackground, oldfg);
            XtSetArg(args[1], XtNforeground, oldbg);
          }
-         XtSetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
+         XtSetValues(optList[W_PAUSE].handle, args, 2);
        }
     }
 
@@ -4172,34 +2882,16 @@ ModeHighlight ()
        MarkMenuItem(wname, True);
     }
     oldmode = gameMode;
-    MarkMenuItem("Machine Match", matchMode && matchGame < appData.matchGames);
+    MarkMenuItem("Mode.MachineMatch", matchMode && matchGame < appData.matchGames);
 
     /* Maybe all the enables should be handled here, not just this one */
-    EnableMenuItem("Training", gameMode == Training || gameMode == PlayFromGameFile);
+    EnableMenuItem("Mode.Training", gameMode == Training || gameMode == PlayFromGameFile);
 }
 
 
 /*
  * Button/menu procedures
  */
-int
-LoadGamePopUp (FILE *f, int gameNumber, char *title)
-{
-    cmailMsgLoaded = FALSE;
-    if (gameNumber == 0) {
-       int error = GameListBuild(f);
-       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);
-}
 
 /* this variable is shared between CopyPositionProc and SendPositionSelection */
 char *selected_fen_position=NULL;
@@ -4211,13 +2903,31 @@ SendPositionSelection (Widget w, Atom *selection, Atom *target,
 {
   char *selection_tmp;
 
-  if (!selected_fen_position) return False; /* should never happen */
+//  if (!selected_fen_position) return False; /* should never happen */
   if (*target == XA_STRING || *target == XA_UTF8_STRING(xDisplay)){
+   if (!selected_fen_position) { // since it never happens, we use it for indicating a game is being sent
+    FILE* f = fopen(gameCopyFilename, "r"); // This code, taken from SendGameSelection, now merges the two
+    long len;
+    size_t count;
+    if (f == NULL) return False;
+    fseek(f, 0, 2);
+    len = ftell(f);
+    rewind(f);
+    selection_tmp = XtMalloc(len + 1);
+    count = fread(selection_tmp, 1, len, f);
+    fclose(f);
+    if (len != count) {
+      XtFree(selection_tmp);
+      return False;
+    }
+    selection_tmp[len] = NULLCHAR;
+   } else {
     /* note: since no XtSelectionDoneProc was registered, Xt will
      * automatically call XtFree on the value returned.  So have to
      * make a copy of it allocated with XtMalloc */
     selection_tmp= XtMalloc(strlen(selected_fen_position)+16);
     safeStrCpy(selection_tmp, selected_fen_position, strlen(selected_fen_position)+16 );
+   }
 
     *value_return=selection_tmp;
     *length_return=strlen(selection_tmp);
@@ -4254,17 +2964,14 @@ SendPositionSelection (Widget w, Atom *selection, Atom *target,
  * Widget which was clicked on was, or what the click event was
  */
 void
-CopyPositionProc ()
+CopySomething (char *src)
 {
+    selected_fen_position = src;
     /*
      * Set both PRIMARY (the selection) and CLIPBOARD, since we don't
      * have a notion of a position that is selected but not copied.
      * See http://www.freedesktop.org/wiki/Specifications/ClipboardsWiki
      */
-    if(gameMode == EditPosition) EditPositionDone(TRUE);
-    if (selected_fen_position) free(selected_fen_position);
-    selected_fen_position = (char *)PositionToFEN(currentMove, NULL);
-    if (!selected_fen_position) return;
     XtOwnSelection(menuBarWidget, XA_PRIMARY,
                   CurrentTime,
                   SendPositionSelection,
@@ -4307,80 +3014,6 @@ PastePositionProc ()
     return;
 }
 
-static Boolean
-SendGameSelection (Widget w, Atom *selection, Atom *target,
-                  Atom *type_return, XtPointer *value_return,
-                  unsigned long *length_return, int *format_return)
-{
-  char *selection_tmp;
-
-  if (*target == XA_STRING || *target == XA_UTF8_STRING(xDisplay)){
-    FILE* f = fopen(gameCopyFilename, "r");
-    long len;
-    size_t count;
-    if (f == NULL) return False;
-    fseek(f, 0, 2);
-    len = ftell(f);
-    rewind(f);
-    selection_tmp = XtMalloc(len + 1);
-    count = fread(selection_tmp, 1, len, f);
-    fclose(f);
-    if (len != count) {
-      XtFree(selection_tmp);
-      return False;
-    }
-    selection_tmp[len] = NULLCHAR;
-    *value_return = selection_tmp;
-    *length_return = len;
-    *type_return = *target;
-    *format_return = 8; /* bits per byte */
-    return True;
-  } else if (*target == XA_TARGETS(xDisplay)) {
-    Atom *targets_tmp = (Atom *) XtMalloc(2 * sizeof(Atom));
-    targets_tmp[0] = XA_UTF8_STRING(xDisplay);
-    targets_tmp[1] = XA_STRING;
-    *value_return = targets_tmp;
-    *type_return = XA_ATOM;
-    *length_return = 2;
-#if 0
-    // This code leads to a read of value_return out of bounds on 64-bit systems.
-    // Other code which I have seen always sets *format_return to 32 independent of
-    // sizeof(Atom) without adjusting *length_return. For instance see TextConvertSelection()
-    // at http://cgit.freedesktop.org/xorg/lib/libXaw/tree/src/Text.c -- BJ
-    *format_return = 8 * sizeof(Atom);
-    if (*format_return > 32) {
-      *length_return *= *format_return / 32;
-      *format_return = 32;
-    }
-#else
-    *format_return = 32;
-#endif
-    return True;
-  } else {
-    return False;
-  }
-}
-
-void
-CopySomething ()
-{
-  /*
-   * Set both PRIMARY (the selection) and CLIPBOARD, since we don't
-   * have a notion of a game that is selected but not copied.
-   * See http://www.freedesktop.org/wiki/Specifications/ClipboardsWiki
-   */
-  XtOwnSelection(menuBarWidget, XA_PRIMARY,
-                CurrentTime,
-                SendGameSelection,
-                NULL/* lose_ownership_proc */ ,
-                NULL/* transfer_done_proc */);
-  XtOwnSelection(menuBarWidget, XA_CLIPBOARD(xDisplay),
-                CurrentTime,
-                SendGameSelection,
-                NULL/* lose_ownership_proc */ ,
-                NULL/* transfer_done_proc */);
-}
-
 /* note: when called from menu all parameters are NULL, so no clue what the
  * Widget which was clicked on was, or what the click event was
  */
@@ -4429,22 +3062,30 @@ QuitWrapper (Widget w, XEvent *event, String *prms, Cardinal *nprms)
     QuitProc();
 }
 
+int
+ShiftKeys ()
+{   // bassic primitive for determining if modifier keys are pressed
+    long int codes[] = { XK_Meta_L, XK_Meta_R, XK_Control_L, XK_Control_R, XK_Shift_L, XK_Shift_R };
+    char keys[32];
+    int i,j,  k=0;
+    XQueryKeymap(xDisplay,keys);
+    for(i=0; i<6; i++) {
+       k <<= 1;
+       j = XKeysymToKeycode(xDisplay, codes[i]);
+       k += ( (keys[j>>3]&1<<(j&7)) != 0 );
+    }
+    return k;
+}
+
 static void
 MoveTypeInProc (Widget widget, caddr_t unused, XEvent *event)
 {
-    char buf[10], keys[32];
+    char buf[10];
     KeySym sym;
-    KeyCode metaL, metaR; //, ctrlL, ctrlR;
     int n = XLookupString(&(event->xkey), buf, 10, &sym, NULL);
-    XQueryKeymap(xDisplay,keys);
-    metaL = XKeysymToKeycode(xDisplay, XK_Meta_L);
-    metaR = XKeysymToKeycode(xDisplay, XK_Meta_R);
-//    ctrlL = XKeysymToKeycode(xDisplay, XK_Control_L);
-//    ctrlR = XKeysymToKeycode(xDisplay, XK_Control_R);
     if ( n == 1 && *buf >= 32 // printable
-        && !(keys[metaL>>3]&1<<(metaL&7)) && !(keys[metaR>>3]&1<<(metaR&7)) // no alt key pressed
-//      && !(keys[ctrlL>>3]&1<<(ctrlL&7)) && !(keys[ctrlR>>3]&1<<(ctrlR&7)) // no ctrl key pressed
-       ) BoxAutoPopUp (buf);
+        && !(ShiftKeys() & 0x3C) // no Alt, Ctrl
+       ) BoxAutoPopUp (buf);
 }
 
 static void
@@ -4504,41 +3145,6 @@ ManInner (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 }
 
 void
-DisplayMessage (char *message, char *extMessage)
-{
-  /* display a message in the message widget */
-
-  char buf[MSG_SIZ];
-  Arg arg;
-
-  if (extMessage)
-    {
-      if (*message)
-       {
-         snprintf(buf, sizeof(buf), "%s  %s", message, extMessage);
-         message = buf;
-       }
-      else
-       {
-         message = extMessage;
-       };
-    };
-
-    safeStrCpy(lastMsg, message, MSG_SIZ); // [HGM] make available
-
-  /* need to test if messageWidget already exists, since this function
-     can also be called during the startup, if for example a Xresource
-     is not set up correctly */
-  if(messageWidget)
-    {
-      XtSetArg(arg, XtNlabel, message);
-      XtSetValues(messageWidget, &arg, 1);
-    };
-
-  return;
-}
-
-void
 SetWindowTitle (char *text, char *title, char *icon)
 {
     Arg args[16];
@@ -4591,326 +3197,6 @@ DisplayIcsInteractionTitle (String message)
   fflush(stdout);
 }
 
-char pendingReplyPrefix[MSG_SIZ];
-ProcRef pendingReplyPR;
-
-void
-AskQuestionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
-{
-    if (*nprms != 4) {
-       fprintf(stderr, _("AskQuestionProc needed 4 parameters, got %d\n"),
-               *nprms);
-       return;
-    }
-    AskQuestionEvent(prms[0], prms[1], prms[2], prms[3]);
-}
-
-void
-AskQuestionPopDown ()
-{
-    if (!askQuestionUp) return;
-    XtPopdown(askQuestionShell);
-    XtDestroyWidget(askQuestionShell);
-    askQuestionUp = False;
-}
-
-void
-AskQuestionReplyAction (Widget w, XEvent *event, String *prms, Cardinal *nprms)
-{
-    char buf[MSG_SIZ];
-    int err;
-    String reply;
-
-    reply = XawDialogGetValueString(w = XtParent(w));
-    safeStrCpy(buf, pendingReplyPrefix, sizeof(buf)/sizeof(buf[0]) );
-    if (*buf) strncat(buf, " ", MSG_SIZ - strlen(buf) - 1);
-    strncat(buf, reply, MSG_SIZ - strlen(buf) - 1);
-    strncat(buf, "\n",  MSG_SIZ - strlen(buf) - 1);
-    OutputToProcess(pendingReplyPR, buf, strlen(buf), &err);
-    AskQuestionPopDown();
-
-    if (err) DisplayFatalError(_("Error writing to chess program"), err, 0);
-}
-
-void
-AskQuestionCallback (Widget w, XtPointer client_data, XtPointer call_data)
-{
-    String name;
-    Arg args[16];
-
-    XtSetArg(args[0], XtNlabel, &name);
-    XtGetValues(w, args, 1);
-
-    if (strcmp(name, _("cancel")) == 0) {
-        AskQuestionPopDown();
-    } else {
-       AskQuestionReplyAction(w, NULL, NULL, NULL);
-    }
-}
-
-void
-AskQuestion (char *title, char *question, char *replyPrefix, ProcRef pr)
-{
-    Arg args[16];
-    Widget popup, layout, dialog, edit;
-    Window root, child;
-    int x, y, i;
-    int win_x, win_y;
-    unsigned int mask;
-
-    safeStrCpy(pendingReplyPrefix, replyPrefix, sizeof(pendingReplyPrefix)/sizeof(pendingReplyPrefix[0]) );
-    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,
-                      (XtPointer) dialog);
-    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);
-}
-
-
-void
-PlaySound (char *name)
-{
-  if (*name == NULLCHAR) {
-    return;
-  } else if (strcmp(name, "$") == 0) {
-    putc(BELLCHAR, stderr);
-  } else {
-    char buf[2048];
-    char *prefix = "", *sep = "";
-    if(appData.soundProgram[0] == NULLCHAR) return;
-    if(!strchr(name, '/')) { prefix = appData.soundDirectory; sep = "/"; }
-    snprintf(buf, sizeof(buf), "%s '%s%s%s' &", appData.soundProgram, prefix, sep, name);
-    system(buf);
-  }
-}
-
-void
-RingBell ()
-{
-  PlaySound(appData.soundMove);
-}
-
-void
-PlayIcsWinSound ()
-{
-  PlaySound(appData.soundIcsWin);
-}
-
-void
-PlayIcsLossSound ()
-{
-  PlaySound(appData.soundIcsLoss);
-}
-
-void
-PlayIcsDrawSound ()
-{
-  PlaySound(appData.soundIcsDraw);
-}
-
-void
-PlayIcsUnfinishedSound ()
-{
-  PlaySound(appData.soundIcsUnfinished);
-}
-
-void
-PlayAlarmSound ()
-{
-  PlaySound(appData.soundIcsAlarm);
-}
-
-void
-PlayTellSound ()
-{
-  PlaySound(appData.soundTell);
-}
-
-void
-EchoOn ()
-{
-    system("stty echo");
-    noEcho = False;
-}
-
-void
-EchoOff ()
-{
-    system("stty -echo");
-    noEcho = True;
-}
-
-void
-RunCommand (char *buf)
-{
-    system(buf);
-}
-
-void
-Colorize (ColorClass cc, int continuation)
-{
-    char buf[MSG_SIZ];
-    int count, outCount, error;
-
-    if (textColors[(int)cc].bg > 0) {
-       if (textColors[(int)cc].fg > 0) {
-         snprintf(buf, MSG_SIZ, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,
-                  textColors[(int)cc].fg, textColors[(int)cc].bg);
-       } else {
-         snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr,
-                  textColors[(int)cc].bg);
-       }
-    } else {
-       if (textColors[(int)cc].fg > 0) {
-         snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr,
-                   textColors[(int)cc].fg);
-       } else {
-         snprintf(buf, MSG_SIZ, "\033[0;%dm", textColors[(int)cc].attr);
-       }
-    }
-    count = strlen(buf);
-    outCount = OutputToProcess(NoProc, buf, count, &error);
-    if (outCount < count) {
-       DisplayFatalError(_("Error writing to display"), error, 1);
-    }
-
-    if (continuation) return;
-    switch (cc) {
-    case ColorShout:
-      PlaySound(appData.soundShout);
-      break;
-    case ColorSShout:
-      PlaySound(appData.soundSShout);
-      break;
-    case ColorChannel1:
-      PlaySound(appData.soundChannel1);
-      break;
-    case ColorChannel:
-      PlaySound(appData.soundChannel);
-      break;
-    case ColorKibitz:
-      PlaySound(appData.soundKibitz);
-      break;
-    case ColorTell:
-      PlaySound(appData.soundTell);
-      break;
-    case ColorChallenge:
-      PlaySound(appData.soundChallenge);
-      break;
-    case ColorRequest:
-      PlaySound(appData.soundRequest);
-      break;
-    case ColorSeek:
-      PlaySound(appData.soundSeek);
-      break;
-    case ColorNormal:
-    case ColorNone:
-    default:
-      break;
-    }
-}
-
-char *
-UserName ()
-{
-    return getpwuid(getuid())->pw_name;
-}
-
-static char *
-ExpandPathName (char *path)
-{
-    static char static_buf[4*MSG_SIZ];
-    char *d, *s, buf[4*MSG_SIZ];
-    struct passwd *pwd;
-
-    s = path;
-    d = static_buf;
-
-    while (*s && isspace(*s))
-      ++s;
-
-    if (!*s) {
-       *d = 0;
-       return static_buf;
-    }
-
-    if (*s == '~') {
-       if (*(s+1) == '/') {
-         safeStrCpy(d, getpwuid(getuid())->pw_dir, 4*MSG_SIZ );
-         strcat(d, s+1);
-       }
-       else {
-         safeStrCpy(buf, s+1, sizeof(buf)/sizeof(buf[0]) );
-         { char *p; if(p = strchr(buf, '/')) *p = 0; }
-         pwd = getpwnam(buf);
-         if (!pwd)
-           {
-             fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"),
-                     buf, path);
-             return NULL;
-           }
-         safeStrCpy(d, pwd->pw_dir, 4*MSG_SIZ );
-         strcat(d, strchr(s+1, '/'));
-       }
-    }
-    else
-      safeStrCpy(d, s, 4*MSG_SIZ );
-
-    return static_buf;
-}
-
-char *
-HostName ()
-{
-    static char host_name[MSG_SIZ];
-
-#if HAVE_GETHOSTNAME
-    gethostname(host_name, MSG_SIZ);
-    return host_name;
-#else  /* not HAVE_GETHOSTNAME */
-# if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
-    sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);
-    return host_name;
-# else /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
-    return "localhost";
-# endif/* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
-#endif /* not HAVE_GETHOSTNAME */
-}
 
 XtIntervalId delayedEventTimerXID = 0;
 DelayedEventCallback delayedEventCallback = 0;
@@ -5047,10 +3333,11 @@ StartClockTimer (long millisec)
 }
 
 void
-DisplayTimerLabel (Widget w, char *color, long timer, int highlight)
+DisplayTimerLabel (Option *opt, char *color, long timer, int highlight)
 {
     char buf[MSG_SIZ];
     Arg args[16];
+    Widget w = (Widget) opt->handle;
 
     /* check for low time warning */
     Pixel foregroundOrWarningColor = timerForegroundPixel;
@@ -5080,286 +3367,20 @@ DisplayTimerLabel (Widget w, char *color, long timer, int highlight)
     XtSetValues(w, args, 3);
 }
 
-void
-DisplayWhiteClock (long timeRemaining, int highlight)
-{
-    Arg args[16];
-
-    if(appData.noGUI) return;
-    DisplayTimerLabel(whiteTimerWidget, _("White"), timeRemaining, highlight);
-    if (highlight && iconPixmap == bIconPixmap) {
-       iconPixmap = wIconPixmap;
-       XtSetArg(args[0], XtNiconPixmap, iconPixmap);
-       XtSetValues(shellWidget, args, 1);
-    }
-}
+static Pixmap *clockIcons[] = { &wIconPixmap, &bIconPixmap };
 
 void
-DisplayBlackClock (long timeRemaining, int highlight)
+SetClockIcon (int color)
 {
     Arg args[16];
-
-    if(appData.noGUI) return;
-    DisplayTimerLabel(blackTimerWidget, _("Black"), timeRemaining, highlight);
-    if (highlight && iconPixmap == wIconPixmap) {
-       iconPixmap = bIconPixmap;
+    Pixmap pm = *clockIcons[color];
+    if (iconPixmap != pm) {
+       iconPixmap = pm;
        XtSetArg(args[0], XtNiconPixmap, iconPixmap);
        XtSetValues(shellWidget, args, 1);
     }
 }
 
-#define CPNone 0
-#define CPReal 1
-#define CPComm 2
-#define CPSock 3
-#define CPLoop 4
-typedef int CPKind;
-
-typedef struct {
-    CPKind kind;
-    int pid;
-    int fdTo, fdFrom;
-} ChildProc;
-
-
-int
-StartChildProcess (char *cmdLine, char *dir, ProcRef *pr)
-{
-    char *argv[64], *p;
-    int i, pid;
-    int to_prog[2], from_prog[2];
-    ChildProc *cp;
-    char buf[MSG_SIZ];
-
-    if (appData.debugMode) {
-       fprintf(debugFP, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine);
-    }
-
-    /* We do NOT feed the cmdLine to the shell; we just
-       parse it into blank-separated arguments in the
-       most simple-minded way possible.
-       */
-    i = 0;
-    safeStrCpy(buf, cmdLine, sizeof(buf)/sizeof(buf[0]) );
-    p = buf;
-    for (;;) {
-       while(*p == ' ') p++;
-       argv[i++] = p;
-       if(*p == '"' || *p == '\'')
-            p = strchr(++argv[i-1], *p);
-       else p = strchr(p, ' ');
-       if (p == NULL) break;
-       *p++ = NULLCHAR;
-    }
-    argv[i] = NULL;
-
-    SetUpChildIO(to_prog, from_prog);
-
-    if ((pid = fork()) == 0) {
-       /* Child process */
-       // [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]);
-       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;
-    cp->fdFrom = from_prog[0];
-    cp->fdTo = to_prog[1];
-    *pr = (ProcRef) cp;
-    return 0;
-}
-
-// [HGM] kill: implement the 'hard killing' of AS's Winboard_x
-static RETSIGTYPE
-AlarmCallBack (int n)
-{
-    return;
-}
-
-void
-DestroyChildProcess (ProcRef pr, int signalType)
-{
-    ChildProc *cp = (ChildProc *) pr;
-
-    if (cp->kind != CPReal) return;
-    cp->kind = CPNone;
-    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);
-    }
-    close(cp->fdFrom);
-    close(cp->fdTo);
-}
-
-void
-InterruptChildProcess (ProcRef pr)
-{
-    ChildProc *cp = (ChildProc *) pr;
-
-    if (cp->kind != CPReal) return;
-    (void) kill(cp->pid, SIGINT); /* stop it thinking */
-}
-
-int
-OpenTelnet (char *host, char *port, ProcRef *pr)
-{
-    char cmdLine[MSG_SIZ];
-
-    if (port[0] == NULLCHAR) {
-      snprintf(cmdLine, sizeof(cmdLine), "%s %s", appData.telnetProgram, host);
-    } else {
-      snprintf(cmdLine, sizeof(cmdLine), "%s %s %s", appData.telnetProgram, host, port);
-    }
-    return StartChildProcess(cmdLine, "", pr);
-}
-
-int
-OpenTCP (char *host, char *port, ProcRef *pr)
-{
-#if OMIT_SOCKETS
-    DisplayFatalError(_("Socket support is not configured in"), 0, 2);
-#else  /* !OMIT_SOCKETS */
-    struct addrinfo hints;
-    struct addrinfo *ais, *ai;
-    int error;
-    int s=0;
-    ChildProc *cp;
-
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = AF_UNSPEC;
-    hints.ai_socktype = SOCK_STREAM;
-
-    error = getaddrinfo(host, port, &hints, &ais);
-    if (error != 0) {
-      /* a getaddrinfo error is not an errno, so can't return it */
-      fprintf(debugFP, "getaddrinfo(%s, %s): %s\n",
-             host, port, gai_strerror(error));
-      return ENOENT;
-    }
-     
-    for (ai = ais; ai != NULL; ai = ai->ai_next) {
-      if ((s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) {
-       error = errno;
-       continue;
-      }
-      if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
-       error = errno;
-       continue;
-      }
-      error = 0;
-      break;
-    }
-    freeaddrinfo(ais);
-
-    if (error != 0) {
-      return error;
-    }
-
-    cp = (ChildProc *) calloc(1, sizeof(ChildProc));
-    cp->kind = CPSock;
-    cp->pid = 0;
-    cp->fdFrom = s;
-    cp->fdTo = s;
-    *pr = (ProcRef) cp;
-#endif /* !OMIT_SOCKETS */
-
-    return 0;
-}
-
-int
-OpenCommPort (char *name, ProcRef *pr)
-{
-    int fd;
-    ChildProc *cp;
-
-    fd = open(name, 2, 0);
-    if (fd < 0) return errno;
-
-    cp = (ChildProc *) calloc(1, sizeof(ChildProc));
-    cp->kind = CPComm;
-    cp->pid = 0;
-    cp->fdFrom = fd;
-    cp->fdTo = fd;
-    *pr = (ProcRef) cp;
-
-    return 0;
-}
-
-int
-OpenLoopback (ProcRef *pr)
-{
-    ChildProc *cp;
-    int to[2], from[2];
-
-    SetUpChildIO(to, from);
-
-    cp = (ChildProc *) calloc(1, sizeof(ChildProc));
-    cp->kind = CPLoop;
-    cp->pid = 0;
-    cp->fdFrom = to[0];                /* note not from[0]; we are doing a loopback */
-    cp->fdTo = to[1];
-    *pr = (ProcRef) cp;
-
-    return 0;
-}
-
-int
-OpenRcmd (char *host, char *user, char *cmd, ProcRef *pr)
-{
-    DisplayFatalError(_("internal rcmd not implemented for Unix"), 0, 1);
-    return -1;
-}
-
-#define INPUT_SOURCE_BUF_SIZE 8192
-
-typedef struct {
-    CPKind kind;
-    int fd;
-    int lineByLine;
-    char *unused;
-    InputCallback func;
-    XtInputId xid;
-    char buf[INPUT_SOURCE_BUF_SIZE];
-    VOIDSTAR closure;
-} InputSource;
-
 void
 DoInputCallback (caddr_t closure, int *source, XtInputId *xid)
 {
@@ -5437,72 +3458,6 @@ RemoveInputSource (InputSourceRef isr)
     is->xid = 0;
 }
 
-int
-OutputToProcess (ProcRef pr, char *message, int count, int *outError)
-{
-    static int line = 0;
-    ChildProc *cp = (ChildProc *) pr;
-    int outCount;
-
-    if (pr == NoProc)
-    {
-        if (appData.noJoin || !appData.useInternalWrap)
-            outCount = fwrite(message, 1, count, stdout);
-        else
-        {
-            int width = get_term_width();
-            int len = wrap(NULL, message, count, width, &line);
-            char *msg = malloc(len);
-            int dbgchk;
-
-            if (!msg)
-                outCount = fwrite(message, 1, count, stdout);
-            else
-            {
-                dbgchk = wrap(msg, message, count, width, &line);
-                if (dbgchk != len && appData.debugMode)
-                    fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len);
-                outCount = fwrite(msg, 1, dbgchk, stdout);
-                free(msg);
-            }
-        }
-    }
-    else
-      outCount = write(cp->fdTo, message, count);
-
-    if (outCount == -1)
-      *outError = errno;
-    else
-      *outError = 0;
-
-    return outCount;
-}
-
-/* Output message to process, with "ms" milliseconds of delay
-   between each character. This is needed when sending the logon
-   script to ICC, which for some reason doesn't like the
-   instantaneous send. */
-int
-OutputToProcessDelayed (ProcRef pr, char *message, int count, int *outError, long msdelay)
-{
-    ChildProc *cp = (ChildProc *) pr;
-    int outCount = 0;
-    int r;
-
-    while (count--) {
-       r = write(cp->fdTo, message++, 1);
-       if (r == -1) {
-           *outError = errno;
-           return outCount;
-       }
-       ++outCount;
-       if (msdelay >= 0)
-         TimeDelay(msdelay);
-    }
-
-    return outCount;
-}
-
 /****  Animation code by Hugh Fisher, DCS, ANU. ****/
 
 /*     Masks for XPM pieces. Black and white pieces can have
@@ -5783,44 +3738,6 @@ SetDragPiece (AnimNr anr, ChessSquare piece)
   XSetClipMask(xDisplay, animGCs[anr+2], mask);
 }
 
-#include <sys/ioctl.h>
-int
-get_term_width ()
-{
-    int fd, default_width;
-
-    fd = STDIN_FILENO;
-    default_width = 79; // this is FICS default anyway...
-
-#if !defined(TIOCGWINSZ) && defined(TIOCGSIZE)
-    struct ttysize win;
-    if (!ioctl(fd, TIOCGSIZE, &win))
-        default_width = win.ts_cols;
-#elif defined(TIOCGWINSZ)
-    struct winsize win;
-    if (!ioctl(fd, TIOCGWINSZ, &win))
-        default_width = win.ws_col;
-#endif
-    return default_width;
-}
-
-void
-update_ics_width ()
-{
-  static int old_width = 0;
-  int new_width = get_term_width();
-
-  if (old_width != new_width)
-    ics_printf("set width %d\n", new_width);
-  old_width = new_width;
-}
-
-void
-NotifyFrontendLogin ()
-{
-    update_ics_width();
-}
-
 /* [AS] Arrow highlighting support */
 
 void