changes from H.G. Muller; version 4.3.15
[xboard.git] / xboard.c
index ca74313..54718f3 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -192,7 +192,13 @@ extern char *getenv();
 #include "childio.h"\r
 #include "xgamelist.h"\r
 #include "xhistory.h"\r
-#include "xedittags.h"\r
+#include "xedittags.h"
+
+// must be moved to xengineoutput.h
+void EngineOutputProc P((Widget w, XEvent *event,
+                       String *prms, Cardinal *nprms));
+void EngineOutputPopDown();\r
+\r
 \r
 #ifdef __EMX__\r
 #ifndef HAVE_USLEEP\r
@@ -385,6 +391,8 @@ void ShowCoordsProc P((Widget w, XEvent *event, String *prms,
                       Cardinal *nprms));\r
 void ShowThinkingProc P((Widget w, XEvent *event, String *prms,\r
                         Cardinal *nprms));\r
+void HideThinkingProc P((Widget w, XEvent *event, String *prms,\r
+                        Cardinal *nprms));\r
 void TestLegalityProc P((Widget w, XEvent *event, String *prms,\r
                          Cardinal *nprms));\r
 void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
@@ -409,7 +417,17 @@ static void DragPieceMove P((int x, int y));
 static void DragPieceEnd P((int x, int y));\r
 static void DrawDragPiece P((void));\r
 char *ModeToWidgetName P((GameMode mode));\r
-\r
+void EngineOutputUpdate( FrontEndProgramStats * stats );\r
+void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void ShufflePopDown P(());\r
+void EnginePopDown P(());\r
+void UciPopDown P(());\r
+void TimeControlPopDown P(());\r
+void NewVariantPopDown P(());\r
 /*\r
 * XBoard depends on Xt R4 or higher\r
 */\r
@@ -422,7 +440,7 @@ Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
   jailSquareColor, highlightSquareColor, premoveHighlightColor;\r
 GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,\r
   bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,\r
-  wjPieceGC, bjPieceGC, prelineGC;\r
+  wjPieceGC, bjPieceGC, prelineGC, countGC;\r
 Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;\r
 Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget, \r
   whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16], \r
@@ -431,19 +449,21 @@ Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
   ICSInputShell, fileNameShell, askQuestionShell;\r
 XSegment gridSegments[(BOARD_SIZE + 1) * 2];\r
 XSegment jailGridSegments[(BOARD_SIZE + 3) * 2];\r
-Font clockFontID, coordFontID;\r
-XFontStruct *clockFontStruct, *coordFontStruct;\r
+Font clockFontID, coordFontID, countFontID;\r
+XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;\r
 XtAppContext appContext;\r
 char *layoutName;\r
 char *oldICSInteractionTitle;\r
 \r
 FileProc fileProc;\r
-char *fileOpenMode;\r
+char *fileOpenMode;
+char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion\r
 \r
 Position commentX = -1, commentY = -1;\r
 Dimension commentW, commentH;\r
 \r
-int squareSize, smallLayout = 0, tinyLayout = 0,\r
+int squareSize, smallLayout = 0, tinyLayout = 0,
+  marginW, marginH, // [HGM] for run-time resizing\r
   fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,\r
   ICSInputBoxUp = False, askQuestionUp = False,\r
   filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,\r
@@ -501,7 +521,9 @@ static Pixmap xpmMask[BlackKing + 1];
 SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;\r
 \r
 MenuItem fileMenu[] = {\r
-    {"Reset Game", ResetProc},\r
+    {"New Game", ResetProc},\r
+    {"New Shuffle Game ...", ShuffleMenuProc},\r
+    {"New Variant ...", NewVariantProc},      // [HGM] variant: not functional yet\r
     {"----", NothingProc},\r
     {"Load Game", LoadGameProc},\r
     {"Load Next Game", LoadNextGameProc},\r
@@ -539,8 +561,11 @@ MenuItem modeMenu[] = {
     {"Edit Position", EditPositionProc},\r
     {"Training", TrainingProc},\r
     {"----", NothingProc},\r
+    {"Show Engine Output", EngineOutputProc},\r
+    {"Show Evaluation Graph", NothingProc}, // [HGM] evalgr: not functional yet\r
     {"Show Game List", ShowGameListProc},\r
-    {"Show Move List", HistoryShowProc},\r
+    {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code\r
+    {"----", NothingProc},\r
     {"Edit Tags", EditTagsProc},\r
     {"Edit Comment", EditCommentProc},\r
     {"ICS Input Box", IcsInputBoxProc},\r
@@ -577,7 +602,13 @@ MenuItem stepMenu[] = {
     {NULL, NULL}\r
 };    \r
 \r
-MenuItem optionsMenu[] = {\r
+MenuItem optionsMenu[] = {
+    {"Flip View", FlipViewProc},\r
+    {"----", NothingProc},    \r
+    {"Adjudications ...", EngineMenuProc},    \r
+    {"Engine Settings ...", UciMenuProc},    \r
+    {"Time Control ...", TimeControlProc},    \r
+    {"----", NothingProc},    \r
     {"Always Queen", AlwaysQueenProc},\r
     {"Animate Dragging", AnimateDraggingProc},\r
     {"Animate Moving", AnimateMovingProc},\r
@@ -589,7 +620,6 @@ MenuItem optionsMenu[] = {
     {"Auto Save", AutosaveProc},\r
     {"Blindfold", BlindfoldProc},\r
     {"Flash Moves", FlashMovesProc},\r
-    {"Flip View", FlipViewProc},\r
     {"Get Move List", GetMoveListProc},\r
 #if HIGHDRAG\r
     {"Highlight Dragging", HighlightDraggingProc},\r
@@ -605,7 +635,7 @@ MenuItem optionsMenu[] = {
     {"Premove", PremoveProc},\r
     {"Quiet Play", QuietPlayProc},\r
     {"Show Coords", ShowCoordsProc},\r
-    {"Show Thinking", ShowThinkingProc},\r
+    {"Hide Thinking", HideThinkingProc},\r
     {"Test Legality", TestLegalityProc},\r
     {NULL, NULL}\r
 };\r
@@ -777,9 +807,9 @@ XtResource clientResources[] = {
     { "secondHost", "secondHost", XtRString, sizeof(String),\r
        XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },\r
     { "firstDirectory", "firstDirectory", XtRString, sizeof(String),\r
-       XtOffset(AppDataPtr, firstDirectory), XtRString, FIRST_DIRECTORY },\r
+       XtOffset(AppDataPtr, firstDirectory), XtRString, "." },\r
     { "secondDirectory", "secondDirectory", XtRString, sizeof(String),\r
-       XtOffset(AppDataPtr, secondDirectory), XtRString, SECOND_DIRECTORY },\r
+       XtOffset(AppDataPtr, secondDirectory), XtRString, "." },\r
     { "bitmapDirectory", "bitmapDirectory", XtRString,\r
        sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),\r
        XtRString, "" },\r
@@ -892,7 +922,7 @@ XtResource clientResources[] = {
        (XtPointer) 0 },\r
     { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),\r
        XtOffset(AppDataPtr, showThinking), XtRImmediate,\r
-       (XtPointer) False },\r
+       (XtPointer) True },\r
     { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),\r
        XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,\r
        (XtPointer) True },\r
@@ -1149,16 +1179,16 @@ XtResource clientResources[] = {
        XtRImmediate, (XtPointer) False },\r
     { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,\r
        sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),\r
-       XtRImmediate, (XtPointer) False },\r
+       XtRImmediate, (XtPointer) True },\r
     { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,\r
        sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),\r
        XtRImmediate, (XtPointer) 0},\r
     { "pgnEventHeader", "pgnEventHeader", XtRString,\r
         sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),\r
        XtRImmediate, (XtPointer) "Computer Chess Game" },    \r
-    { "defaultFrcPosition", "defaultFrcPosition", XtRInt,\r
-        sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),\r
-       XtRImmediate, (XtPointer) -1 },    \r
+    { "defaultFrcPosition", "defaultFrcPositon", XtRInt,\r
+       sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),\r
+       XtRImmediate, (XtPointer) -1},\r
 \r
     // [HGM] 4.3.xx options\r
     { "boardWidth", "boardWidth", XtRInt,\r
@@ -1187,13 +1217,13 @@ XtResource clientResources[] = {
        XtRImmediate, (XtPointer) False},\r
     { "testClaims", "testClaims", XtRBoolean,\r
        sizeof(Boolean), XtOffset(AppDataPtr, testClaims),\r
-       XtRImmediate, (XtPointer) False},\r
+       XtRImmediate, (XtPointer) True},\r
     { "checkMates", "checkMates", XtRBoolean,\r
        sizeof(Boolean), XtOffset(AppDataPtr, checkMates),\r
-       XtRImmediate, (XtPointer) False},\r
+       XtRImmediate, (XtPointer) True},\r
     { "materialDraws", "materialDraws", XtRBoolean,\r
        sizeof(Boolean), XtOffset(AppDataPtr, materialDraws),\r
-       XtRImmediate, (XtPointer) False},\r
+       XtRImmediate, (XtPointer) True},\r
     { "trivialDraws", "trivialDraws", XtRBoolean,\r
        sizeof(Boolean), XtOffset(AppDataPtr, trivialDraws),\r
        XtRImmediate, (XtPointer) False},\r
@@ -1241,7 +1271,54 @@ XtResource clientResources[] = {
        XtRImmediate, (XtPointer) 0},\r
     { "suppressLoadMoves", "suppressLoadMoves", XtRBoolean,\r
        sizeof(Boolean), XtOffset(AppDataPtr, suppressLoadMoves),\r
+       XtRImmediate, (XtPointer) False},
+    { "userName", "userName", XtRString,\r
+       sizeof(String), XtOffset(AppDataPtr, userName),\r
+       XtRImmediate, (XtPointer) 0},\r
+    { "egtFormats", "egtFormats", XtRString,\r
+       sizeof(String), XtOffset(AppDataPtr, egtFormats),\r
+       XtRImmediate, (XtPointer) 0},\r
+    { "rewindIndex", "rewindIndex", XtRInt,\r
+       sizeof(int), XtOffset(AppDataPtr, rewindIndex),\r
+       XtRImmediate, (XtPointer) 0},\r
+    { "sameColorGames", "sameColorGames", XtRInt,\r
+       sizeof(int), XtOffset(AppDataPtr, sameColorGames),\r
+       XtRImmediate, (XtPointer) 0},\r
+    { "smpCores", "smpCores", XtRInt,\r
+       sizeof(int), XtOffset(AppDataPtr, smpCores),\r
+       XtRImmediate, (XtPointer) 1},\r
+
+    // [HGM] Winboard_x UCI options\r
+    { "firstIsUCI", "firstIsUCI", XtRBoolean,\r
+       sizeof(Boolean), XtOffset(AppDataPtr, firstIsUCI),\r
+       XtRImmediate, (XtPointer) False},\r
+    { "secondIsUCI", "secondIsUCI", XtRBoolean,\r
+       sizeof(Boolean), XtOffset(AppDataPtr, secondIsUCI),\r
        XtRImmediate, (XtPointer) False},\r
+    { "firstHasOwnBookUCI", "firstHasOwnBookUCI", XtRBoolean,\r
+       sizeof(Boolean), XtOffset(AppDataPtr, firstHasOwnBookUCI),\r
+       XtRImmediate, (XtPointer) True},\r
+    { "secondHasOwnBookUCI", "secondHasOwnBookUCI", XtRBoolean,\r
+       sizeof(Boolean), XtOffset(AppDataPtr, secondHasOwnBookUCI),\r
+       XtRImmediate, (XtPointer) True},\r
+    { "usePolyglotBook", "usePolyglotBook", XtRBoolean,\r
+       sizeof(Boolean), XtOffset(AppDataPtr, usePolyglotBook),\r
+       XtRImmediate, (XtPointer) False},\r
+    { "defaultHashSize", "defaultHashSize", XtRInt,\r
+       sizeof(int), XtOffset(AppDataPtr, defaultHashSize),\r
+       XtRImmediate, (XtPointer) 64},\r
+    { "defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XtRInt,\r
+       sizeof(int), XtOffset(AppDataPtr, defaultCacheSizeEGTB),\r
+       XtRImmediate, (XtPointer) 4},\r
+    { "polyglotDir", "polyglotDir", XtRString,\r
+        sizeof(String), XtOffset(AppDataPtr, polyglotDir),\r
+       XtRImmediate, (XtPointer) "." },\r
+    { "polyglotBook", "polyglotBook", XtRString,\r
+        sizeof(String), XtOffset(AppDataPtr, polyglotBook),\r
+       XtRImmediate, (XtPointer) "" },    \r
+    { "defaultPathEGTB", "defaultPathEGTB", XtRString,\r
+       sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),\r
+       XtRImmediate, (XtPointer) "/usr/local/share/egtb"},\r
 };\r
 \r
 XrmOptionDescRec shellOptions[] = {\r
@@ -1539,6 +1616,20 @@ XrmOptionDescRec shellOptions[] = {
     { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },\r
     { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },\r
     { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },\r
+    { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },\r
+    { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },\r
+    { "-fUCI", "firstIsUCI", XrmoptionNoArg, "True" },\r
+    { "-sUCI", "secondIsUCI", XrmoptionNoArg, "True" },\r
+    { "-firstHasOwnBookUCI", "firstHasOwnBookUCI", XrmoptionSepArg, NULL },\r
+    { "-secondHasOwnBookUCI", "secondHasOwnBookUCI", XrmoptionSepArg, NULL },\r
+    { "-fNoOwnBookUCI", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },\r
+    { "-sNoOwnBookUCI", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },\r
+    { "-polyglotDir", "polyglotDir", XrmoptionSepArg, NULL },\r
+    { "-usePolyglotBook", "usePolyglotBook", XrmoptionSepArg, NULL },\r
+    { "-polyglotBook", "polyglotBook", XrmoptionSepArg, NULL },\r
+    { "-defaultHashSize", "defaultHashSize", XrmoptionSepArg, NULL },\r
+    { "-defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XrmoptionSepArg, NULL },\r
+    { "-defaultPathEGTB", "defaultPathEGTB", XrmoptionSepArg, NULL },\r
     { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },\r
     // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c\r
 \r
@@ -1572,6 +1663,11 @@ XrmOptionDescRec shellOptions[] = {
     { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL }, \r
     { "-serverPause", "serverPause", XrmoptionSepArg, NULL }, \r
     { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL }, \r
+    { "-egtFormats", "egtFormats", XrmoptionSepArg, NULL }, \r
+    { "-userName", "userName", XrmoptionSepArg, NULL }, \r
+    { "-smpCores", "smpCores", XrmoptionSepArg, NULL }, \r
+    { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL }, \r
+    { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL }, \r
 };\r
 \r
 \r
@@ -1614,6 +1710,7 @@ XtActionsRec boardActions[] = {
     { "EditGameProc", EditGameProc },\r
     { "EditPositionProc", EditPositionProc },\r
     { "TrainingProc", EditPositionProc },\r
+    { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window\r
     { "ShowGameListProc", ShowGameListProc },\r
     { "ShowMoveListProc", HistoryShowProc},\r
     { "EditTagsProc", EditCommentProc },\r
@@ -1667,6 +1764,7 @@ XtActionsRec boardActions[] = {
     { "QuietPlayProc", QuietPlayProc },\r
     { "ShowCoordsProc", ShowCoordsProc },\r
     { "ShowThinkingProc", ShowThinkingProc },\r
+    { "HideThinkingProc", HideThinkingProc },\r
     { "TestLegalityProc", TestLegalityProc },\r
     { "InfoProc", InfoProc },\r
     { "ManProc", ManProc },\r
@@ -1687,6 +1785,12 @@ XtActionsRec boardActions[] = {
     { "GameListPopDown", (XtActionProc) GameListPopDown },\r
     { "PromotionPopDown", (XtActionProc) PromotionPopDown },\r
     { "HistoryPopDown", (XtActionProc) HistoryPopDown },\r
+    { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },\r
+    { "ShufflePopDown", (XtActionProc) ShufflePopDown },\r
+    { "EnginePopDown", (XtActionProc) EnginePopDown },\r
+    { "UciPopDown", (XtActionProc) UciPopDown },\r
+    { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },\r
+    { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },\r
 };\r
      \r
 char globalTranslations[] =\r
@@ -1977,10 +2081,76 @@ BoardToTop()
 \r
 #ifdef IDSIZES\r
   // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined\r
-#else\r
+#else
+#define BoardSize int\r
 void InitDrawingSizes(BoardSize boardSize, int flags)\r
-{ // [HGM] Dummy routine to be able to link with backend files from 4.3.xx, which call it\r
-  ;\r
+{   // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)\r
+    Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
+    Arg args[16];
+    XtGeometryResult gres;\r
+    int i;
+
+    if(!formWidget) return;\r
+
+    /*\r
+     * Enable shell resizing.\r
+     */\r
+    shellArgs[0].value = (XtArgVal) &w;\r
+    shellArgs[1].value = (XtArgVal) &h;\r
+    XtGetValues(shellWidget, shellArgs, 2);\r
+
+    shellArgs[4].value = 2*w; shellArgs[2].value = 10;\r
+    shellArgs[5].value = 2*h; shellArgs[3].value = 10;\r
+    XtSetValues(shellWidget, &shellArgs[2], 4);
+\r
+    XtSetArg(args[0], XtNdefaultDistance, &sep);\r    XtGetValues(formWidget, args, 1);
+\r
+    boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);\r
+    boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
+    CreateGrid();\r
+
+    XtSetArg(args[0], XtNwidth, boardWidth);\r
+    XtSetArg(args[1], XtNheight, boardHeight);\r
+    XtSetValues(boardWidget, args, 2);\r
+\r
+    timerWidth = (boardWidth - sep) / 2;\r
+    XtSetArg(args[0], XtNwidth, timerWidth);\r
+    XtSetValues(whiteTimerWidget, args, 1);\r
+    XtSetValues(blackTimerWidget, args, 1);\r
+\r
+    XawFormDoLayout(formWidget, False);\r
+
+    if (appData.titleInWindow) {\r
+       i = 0;\r
+       XtSetArg(args[i], XtNborderWidth, &bor); i++;\r
+       XtSetArg(args[i], XtNheight, &h);  i++;\r
+       XtGetValues(titleWidget, args, i);\r
+       if (smallLayout) {\r
+           w = boardWidth - 2*bor;\r
+       } else {\r
+           XtSetArg(args[0], XtNwidth, &w);\r
+           XtGetValues(menuBarWidget, args, 1);\r
+           w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE\r
+       }\r
+\r
+       gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);\r
+       if (gres != XtGeometryYes && appData.debugMode) {\r
+           fprintf(stderr,\r
+                   "%s: titleWidget geometry error %d %d %d %d %d\n",\r
+                   programName, gres, w, h, wr, hr);\r
+       }\r
+    }\r
+\r
+    XawFormDoLayout(formWidget, True);\r
+
+    /*\r
+     * Inhibit shell resizing.\r
+     */
+    shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;\r
+    shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;\r
+    shellArgs[4].value = shellArgs[2].value = w;\r
+    shellArgs[5].value = shellArgs[3].value = h;\r
+    XtSetValues(shellWidget, &shellArgs[0], 6);\r
 }\r
 #endif\r
 \r
@@ -1997,7 +2167,51 @@ main(argc, argv)
     XtGeometryResult gres;\r
     char *p;\r
     XrmDatabase xdb;\r
-    int forceMono = False;\r
+    int forceMono = False;
+#define INDIRECTION\r
+#ifdef INDIRECTION
+    // [HGM] before anything else, expand any indirection files amongst options
+    char *argvCopy[1000]; // 1000 seems enough
+    char newArgs[10000];  // holds actual characters
+    int k = 0;
+
+    srandom(time(0)); // [HGM] book: make random truly random
+
+    j = 0;
+    for(i=0; i<argc; i++) {
+       if(j >= 1000-2) { printf("too many arguments\n"); exit(-1); }
+//fprintf(stderr, "arg %s\n", argv[i]);
+       if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
+           char c;
+           FILE *f = fopen(argv[i]+1, "rb");
+           if(f == NULL) { fprintf(stderr, "ignore %s\n", argv[i]); continue; } // do not expand non-existing
+           argvCopy[j++] = newArgs + k; // get ready for first argument from file
+           while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
+               if(c == '\n') {
+                   if(j >= 1000-2) { printf("too many arguments\n"); exit(-1); }
+                   newArgs[k++] = 0;  // terminate current arg
+                   if(k >= 10000-1) { printf("too long arguments\n"); exit(-1); }
+                   argvCopy[j++] = newArgs + k; // get ready for next
+               } else {
+                   if(k >= 10000-1) { printf("too long arguments\n"); exit(-1); }
+                   newArgs[k++] = c;
+               }
+           }
+           newArgs[k] = 0;
+           j--;
+           fclose(f);
+       }
+    }
+    argvCopy[j] = NULL;
+    argv = argvCopy;
+    argc = j;
+#if 0
+    if(appData.debugMode,1) { // OK, appData is not initialized here yet...
+       for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
+    }
+#endif
+#endif
+
 \r
     setbuf(stdout, NULL);\r
     setbuf(stderr, NULL);\r
@@ -2046,9 +2260,6 @@ main(argc, argv)
        appData.NrRanks > BOARD_SIZE   )\r
         DisplayFatalError("Recompile with BOARD_SIZE > 12, to support this size", 0, 2);\r
 \r
-    /* [HGM] The following line must be moved to the "New Shuffle Game" menu as soon as there is one! */\r
-    if(appData.defaultFrcPosition != -1) shuffleOpenings = TRUE;\r
-\r
 #if !HIGHDRAG\r
     /* This feature does not work; animation needs a rewrite */\r
     appData.highlightDragging = FALSE;\r
@@ -2180,6 +2391,9 @@ main(argc, argv)
     coordFontID = XLoadFont(xDisplay, appData.coordFont);\r
     coordFontStruct = XQueryFont(xDisplay, coordFontID);\r
     appData.font = FindFont(appData.font, fontPxlSize);\r
+    countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings\r
+    countFontStruct = XQueryFont(xDisplay, countFontID);\r
+//    appData.font = FindFont(appData.font, fontPxlSize);\r
 \r
     xdb = XtDatabase(xDisplay);\r
     XrmPutStringResource(&xdb, "*font", appData.font);\r
@@ -2314,36 +2528,54 @@ main(argc, argv)
                            formArgs, XtNumber(formArgs));\r
     XtSetArg(args[0], XtNdefaultDistance, &sep);\r
     XtGetValues(formWidget, args, 1);\r
-    \r
+\r
     j = 0;\r
     widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);\r
+    XtSetArg(args[0], XtNtop,    XtChainTop);\r
+    XtSetArg(args[1], XtNbottom, XtChainTop);
+    XtSetValues(menuBarWidget, args, 2);\r
 \r
     widgetList[j++] = whiteTimerWidget =\r
       XtCreateWidget("whiteTime", labelWidgetClass,\r
                     formWidget, timerArgs, XtNumber(timerArgs));\r
     XtSetArg(args[0], XtNfont, clockFontStruct);\r
-    XtSetValues(whiteTimerWidget, args, 1);\r
+    XtSetArg(args[1], XtNtop,    XtChainTop);\r
+    XtSetArg(args[2], XtNbottom, XtChainTop);
+    XtSetValues(whiteTimerWidget, args, 3);\r
     \r
     widgetList[j++] = blackTimerWidget =\r
       XtCreateWidget("blackTime", labelWidgetClass,\r
                     formWidget, timerArgs, XtNumber(timerArgs));\r
     XtSetArg(args[0], XtNfont, clockFontStruct);\r
-    XtSetValues(blackTimerWidget, args, 1);\r
+    XtSetArg(args[1], XtNtop,    XtChainTop);\r
+    XtSetArg(args[2], XtNbottom, XtChainTop);
+    XtSetValues(blackTimerWidget, args, 3);\r
     \r
     if (appData.titleInWindow) {\r
        widgetList[j++] = titleWidget = \r
          XtCreateWidget("title", labelWidgetClass, formWidget,\r
                         titleArgs, XtNumber(titleArgs));\r
+       XtSetArg(args[0], XtNtop,    XtChainTop);\r
+       XtSetArg(args[1], XtNbottom, XtChainTop);
+       XtSetValues(titleWidget, args, 2);\r
     }\r
 \r
     if (appData.showButtonBar) {\r
       widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);\r
+      XtSetArg(args[0], XtNleft,  XtChainRight); // [HGM] glue to right window edge\r
+      XtSetArg(args[1], XtNright, XtChainRight); //       for good run-time sizing
+      XtSetArg(args[2], XtNtop,    XtChainTop);\r
+      XtSetArg(args[3], XtNbottom, XtChainTop);
+      XtSetValues(buttonBarWidget, args, 4);\r
     }\r
 \r
     widgetList[j++] = messageWidget =\r
       XtCreateWidget("message", labelWidgetClass, formWidget,\r
-                    messageArgs, XtNumber(messageArgs));\r
-    \r
+                    messageArgs, XtNumber(messageArgs));
+    XtSetArg(args[0], XtNtop,    XtChainTop);\r
+    XtSetArg(args[1], XtNbottom, XtChainTop);
+    XtSetValues(messageWidget, args, 2);\r
+\r
     widgetList[j++] = boardWidget =\r
       XtCreateWidget("board", widgetClass, formWidget, boardArgs,\r
                     XtNumber(boardArgs));\r
@@ -2438,7 +2670,11 @@ main(argc, argv)
     }\r
     i = 0;\r
     XtSetArg(args[0], XtNfromVert, messageWidget);\r
-    XtSetValues(boardWidget, args, 1);\r
+    XtSetArg(args[1], XtNtop,    XtChainTop);\r
+    XtSetArg(args[2], XtNbottom, XtChainBottom);
+    XtSetArg(args[3], XtNleft,   XtChainLeft);\r
+    XtSetArg(args[4], XtNright,  XtChainRight);
+    XtSetValues(boardWidget, args, 5);\r
 \r
     XtRealizeWidget(shellWidget);\r
 \r
@@ -2448,6 +2684,7 @@ main(argc, argv)
      * The value "2" is probably larger than needed.\r
      */\r
     XawFormDoLayout(formWidget, False);\r
+
 #define WIDTH_FUDGE 2\r
     i = 0;\r
     XtSetArg(args[i], XtNborderWidth, &bor);  i++;\r
@@ -2478,6 +2715,9 @@ main(argc, argv)
              programName, gres, w, h, wr, hr);\r
     }\r
     /* !! end hack */\r
+    XtSetArg(args[0], XtNleft,  XtChainLeft);  // [HGM] glue ends for good run-time sizing\r
+    XtSetArg(args[1], XtNright, XtChainRight);
+    XtSetValues(messageWidget, args, 2);\r
 \r
     if (appData.titleInWindow) {\r
        i = 0;\r
@@ -2623,8 +2863,8 @@ main(argc, argv)
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),\r
                    args, 1);\r
     }\r
-    if (appData.showThinking) {\r
-       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),\r
+    if (appData.hideThinkingFromHuman) {\r
+       XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),\r
                    args, 1);\r
     }\r
     if (appData.testLegality) {\r
@@ -2659,8 +2899,10 @@ main(argc, argv)
     XtGetValues(shellWidget, shellArgs, 2);\r
     shellArgs[4].value = shellArgs[2].value = w;\r
     shellArgs[5].value = shellArgs[3].value = h;\r
-    XtSetValues(shellWidget, &shellArgs[2], 4);\r
-    \r
+    XtSetValues(shellWidget, &shellArgs[2], 4);
+    marginW =  w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board\r
+    marginH =  h - boardHeight;\r
+\r
     CatchDeleteWindow(shellWidget, "QuitProc");\r
 \r
     CreateGCs();\r
@@ -2830,7 +3072,7 @@ Enables icsEnables[] = {
     { "menuHelp.Book", False },\r
     { "menuStep.Move Now", False },\r
     { "menuOptions.Periodic Updates", False }, \r
-    { "menuOptions.Show Thinking", False },\r
+    { "menuOptions.Hide Thinking", False },\r
     { "menuOptions.Ponder Next Move", False },\r
 #endif\r
     { NULL, False }\r
@@ -2859,7 +3101,7 @@ Enables ncpEnables[] = {
     { "menuOptions.ICS Alarm", False },\r
     { "menuOptions.Move Sound", False },\r
     { "menuOptions.Quiet Play", False },\r
-    { "menuOptions.Show Thinking", False },\r
+    { "menuOptions.Hide Thinking", False },\r
     { "menuOptions.Periodic Updates", False }, \r
     { "menuOptions.Ponder Next Move", False },\r
     { "menuHelp.Hint", False },\r
@@ -3121,6 +3363,12 @@ void CreateGCs()
     coordGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
     XSetFont(xDisplay, coordGC, coordFontID);\r
     \r
+    // [HGM] make font for holdings counts (white on black0
+    gc_values.foreground = XWhitePixel(xDisplay, xScreen);\r
+    gc_values.background = XBlackPixel(xDisplay, xScreen);\r
+    countGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+    XSetFont(xDisplay, countGC, countFontID);\r
+    \r
     if (appData.monoMode) {\r
        gc_values.foreground = XWhitePixel(xDisplay, xScreen);\r
        gc_values.background = XWhitePixel(xDisplay, xScreen);\r
@@ -4207,20 +4455,20 @@ static int SquareColor(row, column)
 \r
     if (gameInfo.variant == VariantXiangqi) {\r
         if (column >= 3 && column <= 5 && row >= 0 && row <= 2) {\r
-            square_color = 0;\r
-        } else if (column >= 3 && column <= 5 && row >= 7 && row <= 9) {\r
             square_color = 1;\r
+        } else if (column >= 3 && column <= 5 && row >= 7 && row <= 9) {\r
+            square_color = 0;\r
         } else if (row <= 4) {\r
-            square_color = 1;\r
-        } else {\r
             square_color = 0;\r
+        } else {\r
+            square_color = 1;\r
         }\r
     } else {\r
         square_color = ((column + row) % 2) == 1;\r
     }\r
 \r
     /* [hgm] holdings: next line makes all holdings squares light */\r
-    if(column < BOARD_LEFT || column >= BOARD_RGHT) square_color = 0;\r
+    if(column < BOARD_LEFT || column >= BOARD_RGHT) square_color = 1;\r
  \r
     return square_color;\r
 }\r
@@ -4236,6 +4484,17 @@ void DrawSquare(row, column, piece, do_flash)
     DrawFunc drawfunc;\r
     int flash_delay;\r
 \r
+    if(gameInfo.variant == VariantShogi) { // [HGM] shogi: in shogi Q is used for Lance
+       if(piece == WhiteQueen) piece = WhiteLance; else
+       if(piece == BlackQueen) piece = BlackLance;
+    }
+#ifdef GOTHIC
+    else if(gameInfo.variant == VariantGothic) { // [HGM] shogi: in Gothic Chancelor has alternative look
+       if(piece == WhiteMarshall) piece = WhiteSilver; else
+       if(piece == BlackMarshall) piece = BlackSilver;
+    }
+#endif
+
     /* Calculate delay in milliseconds (2-delays per complete flash) */\r
     flash_delay = 500 / appData.flashRate;\r
        \r
@@ -4251,11 +4510,40 @@ void DrawSquare(row, column, piece, do_flash)
   \r
     square_color = SquareColor(row, column);\r
     \r
-    if ( // [HGM] holdings: next 5 lines blank out area between board and holdings\r
+    if ( // [HGM] holdings: blank out area between board and holdings\r
                  column == BOARD_LEFT-1 ||  column == BOARD_RGHT\r
               || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize)\r
                  || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) ) {\r
-                       BlankSquare(x, y, 2, EmptySquare, xBoardWindow);\r
+                       BlankSquare(x, y, 2, EmptySquare, xBoardWindow);
+\r
+                       // [HGM] print piece counts next to holdings
+                       string[1] = NULLCHAR;\r
+                       if (column == (flipView ? BOARD_LEFT-1 : BOARD_RGHT) && piece > 1 ) {\r
+                           string[0] = '0' + piece;\r
+                           XTextExtents(countFontStruct, string, 1, &direction, \r
+                                &font_ascent, &font_descent, &overall);\r
+                           if (appData.monoMode) {\r
+                               XDrawImageString(xDisplay, xBoardWindow, countGC,\r
+                                                x + squareSize - overall.width - 2, \r
+                                                y + font_ascent + 1, string, 1);\r
+                           } else {\r
+                               XDrawString(xDisplay, xBoardWindow, countGC,\r
+                                           x + squareSize - overall.width - 2, \r
+                                           y + font_ascent + 1, string, 1);\r
+                           }\r
+                       }\r
+                       if (column == (flipView ? BOARD_RGHT : BOARD_LEFT-1) && piece > 1) {\r
+                           string[0] = '0' + piece;\r
+                           XTextExtents(countFontStruct, string, 1, &direction, \r
+                                        &font_ascent, &font_descent, &overall);\r
+                           if (appData.monoMode) {\r
+                               XDrawImageString(xDisplay, xBoardWindow, countGC,\r
+                                                x + 2, y + font_ascent + 1, string, 1);\r
+                           } else {\r
+                               XDrawString(xDisplay, xBoardWindow, countGC,\r
+                                           x + 2, y + font_ascent + 1, string, 1);\r
+                           }       \r
+                       }   \r
     } else {\r
            if (piece == EmptySquare || appData.blindfold) {\r
                        BlankSquare(x, y, square_color, piece, xBoardWindow);\r
@@ -4278,8 +4566,9 @@ void DrawSquare(row, column, piece, do_flash)
        }\r
        \r
     string[1] = NULLCHAR;\r
-    if (appData.showCoords && row == (flipView ? BOARD_HEIGHT-1 : 0)) {\r
-       string[0] = 'a' + column;\r
+    if (appData.showCoords && row == (flipView ? BOARD_HEIGHT-1 : 0)
+               && column >= BOARD_LEFT && column < BOARD_RGHT) {\r
+       string[0] = 'a' + column - BOARD_LEFT;\r
        XTextExtents(coordFontStruct, string, 1, &direction, \r
                     &font_ascent, &font_descent, &overall);\r
        if (appData.monoMode) {\r
@@ -4292,7 +4581,7 @@ void DrawSquare(row, column, piece, do_flash)
                        y + squareSize - font_descent - 1, string, 1);\r
        }\r
     }\r
-    if (appData.showCoords && column == (flipView ? BOARD_WIDTH-1 : 0)) {\r
+    if (appData.showCoords && column == (flipView ? BOARD_RGHT-1 : BOARD_LEFT)) {\r
        string[0] = ONE + row;\r
        XTextExtents(coordFontStruct, string, 1, &direction, \r
                     &font_ascent, &font_descent, &overall);\r
@@ -4469,7 +4758,7 @@ void XDrawPosition(w, repaint, board)
     } else {\r
        if (lineGap > 0)\r
          XDrawSegments(xDisplay, xBoardWindow, lineGC,\r
-                       gridSegments, (BOARD_SIZE + 1) * 2);\r
+                       gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);\r
        \r
        for (i = 0; i < BOARD_HEIGHT; i++)\r
          for (j = 0; j < BOARD_WIDTH; j++) {\r
@@ -6820,14 +7109,37 @@ void ShowThinkingProc(w, event, prms, nprms)
 {\r
     Arg args[16];\r
 \r
-    ShowThinkingEvent(!appData.showThinking);\r
-\r
+    appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent
+    ShowThinkingEvent();\r
+#if 0
+    // [HGM] thinking: currently no suc menu item; replaced by Hide Thinking (From Human)\r
     if (appData.showThinking) {\r
        XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
     } else {\r
        XtSetArg(args[0], XtNleftBitmap, None);\r
     }\r
     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),\r
+               args, 1);
+#endif\r
+}\r
+\r
+void HideThinkingProc(w, event, prms, nprms)\r
+     Widget w;\r
+     XEvent *event;\r
+     String *prms;\r
+     Cardinal *nprms;\r
+{\r
+    Arg args[16];\r
+\r
+    appData.hideThinkingFromHuman = !appData.hideThinkingFromHuman; // [HGM] thinking: tken out of ShowThinkingEvent
+    ShowThinkingEvent();\r
+\r
+    if (appData.hideThinkingFromHuman) {\r
+       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+    } else {\r
+       XtSetArg(args[0], XtNleftBitmap, None);\r
+    }\r
+    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),\r
                args, 1);\r
 }\r
 \r
@@ -6889,10 +7201,12 @@ void AboutProc(w, event, prms, nprms)
 #else\r
     char *zippy = "";\r
 #endif\r
-    sprintf(buf, "%s%s\n\n%s\n%s\n\n%s%s\n%s",\r
+    sprintf(buf, "%s%s\n\n%s\n%s\n%s\n%s\n\n%s%s\n%s",\r
            programVersion, zippy,\r
            "Copyright 1991 Digital Equipment Corporation",\r
-           "Enhancements Copyright 1992-2001 Free Software Foundation",\r
+           "Enhancements Copyright 1992-2001 Free Software Foundation",
+           "Enhancements Copyright 2005 Alessandro Scotti",\r
+           "Enhancements Copyright 2007-2008 H.G.Muller",\r
            PRODUCT, " is free software and carries NO WARRANTY;",\r
            "see the file COPYING for more information.");\r
     ErrorPopUp("About XBoard", buf, FALSE);\r
@@ -6981,6 +7295,17 @@ void DisplayTitle(text)
     } else if (appData.cmailGameName[0] != NULLCHAR) {\r
        sprintf(icon, "%s", "CMail");\r
        sprintf(title, "%s: %s", programName, "CMail");\r
+#ifdef GOTHIC
+    // [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it
+    } else if (gameInfo.variant == VariantGothic) {\r
+       strcpy(icon, programName);\r
+       strcpy(title, GOTHIC);\r
+#endif
+#ifdef FALCON
+    } else if (gameInfo.variant == VariantFalcon) {\r
+       strcpy(icon, programName);\r
+       strcpy(title, FALCON);\r
+#endif
     } else if (appData.noChessProgram) {\r
        strcpy(icon, programName);\r
        strcpy(title, programName);\r
@@ -7658,14 +7983,16 @@ int StartChildProcess(cmdLine, dir, pr)
     SetUpChildIO(to_prog, from_prog);\r
 \r
     if ((pid = fork()) == 0) {\r
-       /* Child process */\r
-       dup2(to_prog[0], 0);\r
-       dup2(from_prog[1], 1);\r
-       close(to_prog[0]);\r
-       close(to_prog[1]);\r
+       /* Child process */
+       // [HGM] PSWBTM: made order resistant against case where fd of created pipe was 0 or 1\r
+       close(to_prog[1]);     // first close the unused pipe ends\r
        close(from_prog[0]);\r
-       close(from_prog[1]);\r
-       dup2(1, fileno(stderr)); /* force stderr to the pipe */\r
+       dup2(to_prog[0], 0);   // to_prog was created first, nd is the only one to use 0 or 1\r
+       dup2(from_prog[1], 1);\r
+       if(to_prog[0] >= 2) close(to_prog[0]); // if 0 or 1, the dup2 already cosed the original\r
+       close(from_prog[1]);                   // and closing again loses one of the pipes!\r
+       if(fileno(stderr) >= 2) // better safe than sorry...
+               dup2(1, fileno(stderr)); /* force stderr to the pipe */\r
 \r
        if (dir[0] != NULLCHAR && chdir(dir) != 0) {\r
            perror(dir);\r
@@ -8727,5 +9054,7 @@ DrawDragPiece ()
 void\r
 SetProgramStats( FrontEndProgramStats * stats )\r
 {\r
-  // [HR] TODO\r
+  // [HR] TODO
+  // [HGM] done, but perhaps backend should call this directly?\r
+    EngineOutputUpdate( stats );\r
 }\r