removed X-version of buttonbar
[xboard.git] / xboard.c
index d5de474..6058ec1 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -251,7 +251,6 @@ void CreateXPMPieces P((void));
 void CreatePieces P((void));
 void CreatePieceMenus P((void));
 Widget CreateMenuBar P((Menu *mb));
-Widget CreateButtonBar P ((MenuItem *mi));
 char *FindFont P((char *pattern, int targetPxlSize));
 void PieceMenuPopup P((Widget w, XEvent *event,
                       String *params, Cardinal *num_params));
@@ -295,12 +294,6 @@ void EditCommentCallback P((Widget w, XtPointer client_data,
 void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
 void LoadPositionProc P((Widget w, XEvent *event,
                         String *prms, Cardinal *nprms));
-void LoadNextPositionProc P((Widget w, XEvent *event, String *prms,
-                        Cardinal *nprms));
-void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms,
-                        Cardinal *nprms));
-void ReloadPositionProc P((Widget w, XEvent *event, String *prms,
-                      Cardinal *nprms));
 void CopyPositionProc P((Widget w, XEvent *event, String *prms,
                         Cardinal *nprms));
 void PastePositionProc P((Widget w, XEvent *event, String *prms,
@@ -343,8 +336,6 @@ void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void FlashMovesProc P((Widget w, XEvent *event, String *prms,
                       Cardinal *nprms));
-void GetMoveListProc P((Widget w, XEvent *event, String *prms,
-                       Cardinal *nprms));
 void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
                              Cardinal *nprms));
 void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
@@ -363,10 +354,6 @@ void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
                             Cardinal *nprms));
 void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
-                        Cardinal *nprms));
-void HideThinkingProc P((Widget w, XEvent *event, String *prms,
-                        Cardinal *nprms));
 void TestLegalityProc P((Widget w, XEvent *event, String *prms,
                          Cardinal *nprms));
 void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@ -426,7 +413,7 @@ 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,
+  menuBarWidget,  editShell, errorShell, analysisShell,
   ICSInputShell, fileNameShell, askQuestionShell;
 Font clockFontID, coordFontID, countFontID;
 XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
@@ -663,9 +650,9 @@ MenuItem fileMenu[] = {
     {N_("Paste Game"), PasteGameProc},
     {"----", NothingProc},
     {N_("Load Position"), LoadPositionProc},
-    {N_("Load Next Position"), LoadNextPositionProc},
-    {N_("Load Previous Position"), LoadPrevPositionProc},
-    {N_("Reload Same Position"), ReloadPositionProc},
+    //    {N_("Load Next Position"), LoadNextPositionProc},
+    //    {N_("Load Previous Position"), LoadPrevPositionProc},
+    //    {N_("Reload Same Position"), ReloadPositionProc},
     {N_("Save Position"), SavePositionProc},
     {"----", NothingProc},
     {N_("Copy Position"), CopyPositionProc},
@@ -691,7 +678,7 @@ MenuItem modeMenu[] = {
     {N_("Show Engine Output"), EngineOutputProc},
     {N_("Show Evaluation Graph"), NothingProc}, // [HGM] evalgr: not functional yet
     {N_("Show Game List"), ShowGameListProc},
-    {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
+    //    {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
     {"----", NothingProc},
     {N_("Edit Tags"), EditTagsProc},
     {N_("Edit Comment"), EditCommentProc},
@@ -719,7 +706,7 @@ MenuItem optionsMenu[] = {
     {N_("Auto Save"), AutosaveProc},
     {N_("Blindfold"), BlindfoldProc},
     {N_("Flash Moves"), FlashMovesProc},
-    {N_("Get Move List"), GetMoveListProc},
+ //    {N_("Get Move List"), GetMoveListProc},
 #if HIGHDRAG
     {N_("Highlight Dragging"), HighlightDraggingProc},
 #endif
@@ -733,7 +720,7 @@ MenuItem optionsMenu[] = {
     {N_("Popup Move Errors"), PopupMoveErrorsProc},
     {N_("Premove"), PremoveProc},
     {N_("Quiet Play"), QuietPlayProc},
-    {N_("Hide Thinking"), HideThinkingProc},
+    //    {N_("Hide Thinking"), HideThinkingProc},
     {N_("Test Legality"), TestLegalityProc},
     {NULL, NULL}
 };
@@ -745,16 +732,6 @@ Menu menuBar[] = {
     {NULL, NULL}
 };
 
-#define PAUSE_BUTTON N_("P")
-MenuItem buttonBar[] = {
-  //    {"<<", ToStartProc},
-    //    {"<", BackwardProc},
-    //    {PAUSE_BUTTON, PauseProc},
-    //    {">", ForwardProc},
-  //    {">>", ToEndProc},
-    {NULL, NULL}
-};
-
 #define PIECE_MENU_SIZE 18
 String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
     { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
@@ -1050,7 +1027,7 @@ XtResource clientResources[] = {
     { "localLineEditing", "localLineEditing", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
        XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
-#ifdef ZIPPY
+#if ZIPPY
     { "zippyTalk", "zippyTalk", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
        XtRImmediate, (XtPointer) ZIPPY_TALK },
@@ -1257,6 +1234,9 @@ XtResource clientResources[] = {
     { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
        sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
        XtRImmediate, (XtPointer) 0},
+    { "adjudicateDrawMoves", "adjudicateDrawMoves", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, adjudicateDrawMoves),
+       XtRImmediate, (XtPointer) 0},
     { "pgnEventHeader", "pgnEventHeader", XtRString,
         sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),
        XtRImmediate, (XtPointer) "Computer Chess Game" },
@@ -1372,7 +1352,7 @@ XtResource clientResources[] = {
        XtRImmediate, (XtPointer) "xboard.debug"},
     { "engineDebugOutput", "engineDebugOutput", XtRInt,
        sizeof(int), XtOffset(AppDataPtr, engineComments),
-       XtRImmediate, (XtPointer) 0},
+       XtRImmediate, (XtPointer) 1},
     { "noGUI", "noGUI", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, noGUI),
        XtRImmediate, (XtPointer) 0},
@@ -1426,6 +1406,12 @@ XtResource clientResources[] = {
     { "delayAfterQuit", "delayAfterQuit", XtRInt,
        sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
        XtRImmediate, (XtPointer) 0},
+    { "keepAlive", "keepAlive", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, keepAlive),
+       XtRImmediate, (XtPointer) 0},
+    { "forceIllegalMoves", "forceIllegalMoves", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, forceIllegal),
+       XtRImmediate, (XtPointer) False},
 };
 
 XrmOptionDescRec shellOptions[] = {
@@ -1725,6 +1711,7 @@ XrmOptionDescRec shellOptions[] = {
     { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
     { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
     { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
+    { "-adjudicateDrawMoves", "adjudicateDrawMoves", XrmoptionSepArg, NULL },
     { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
     { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
     { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
@@ -1792,6 +1779,8 @@ XrmOptionDescRec shellOptions[] = {
     { "-secondOptions", "secondOptions", XrmoptionSepArg, NULL },
     { "-firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
     { "-secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
+    { "-keepAlive", "keepAlive", XrmoptionSepArg, NULL },
+    { "-forceIllegalMoves", "forceIllegalMoves", XrmoptionNoArg, "True" },
 };
 
 
@@ -1807,9 +1796,9 @@ XtActionsRec boardActions[] = {
     { "Iconify", Iconify },
     { "LoadSelectedProc", LoadSelectedProc },
     { "LoadPositionProc", LoadPositionProc },
-    { "LoadNextPositionProc", LoadNextPositionProc },
-    { "LoadPrevPositionProc", LoadPrevPositionProc },
-    { "ReloadPositionProc", ReloadPositionProc },
+    //    { "LoadNextPositionProc", LoadNextPositionProc },
+    //    { "LoadPrevPositionProc", LoadPrevPositionProc },
+    //    { "ReloadPositionProc", ReloadPositionProc },
     { "CopyPositionProc", CopyPositionProc },
     { "PastePositionProc", PastePositionProc },
     { "CopyGameProc", CopyGameProc },
@@ -1829,7 +1818,7 @@ XtActionsRec boardActions[] = {
     { "TrainingProc", EditPositionProc },
     { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
     { "ShowGameListProc", ShowGameListProc },
-    { "ShowMoveListProc", HistoryShowProc},
+    //    { "ShowMoveListProc", HistoryShowProc},
     { "EditTagsProc", EditCommentProc },
     { "EditCommentProc", EditCommentProc },
     { "IcsAlarmProc", IcsAlarmProc },
@@ -1867,7 +1856,7 @@ XtActionsRec boardActions[] = {
     { "BlindfoldProc", BlindfoldProc },
     { "FlashMovesProc", FlashMovesProc },
     //    { "FlipViewProc", FlipViewProc },
-    { "GetMoveListProc", GetMoveListProc },
+    //    { "GetMoveListProc", GetMoveListProc },
 #if HIGHDRAG
     { "HighlightDraggingProc", HighlightDraggingProc },
 #endif
@@ -1881,8 +1870,8 @@ XtActionsRec boardActions[] = {
     { "PopupMoveErrorsProc", PopupMoveErrorsProc },
     { "PremoveProc", PremoveProc },
     { "QuietPlayProc", QuietPlayProc },
-    { "ShowThinkingProc", ShowThinkingProc },
-    { "HideThinkingProc", HideThinkingProc },
+    //    { "ShowThinkingProc", ShowThinkingProc },
+    //    { "HideThinkingProc", HideThinkingProc },
     { "TestLegalityProc", TestLegalityProc },
     //    { "InfoProc", InfoProc },
     //    { "ManProc", ManProc },
@@ -1901,7 +1890,7 @@ XtActionsRec boardActions[] = {
     { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
     { "GameListPopDown", (XtActionProc) GameListPopDown },
     { "PromotionPopDown", (XtActionProc) PromotionPopDown },
-    { "HistoryPopDown", (XtActionProc) HistoryPopDown },
+    //    { "HistoryPopDown", (XtActionProc) HistoryPopDown },
     { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
     { "ShufflePopDown", (XtActionProc) ShufflePopDown },
     { "EnginePopDown", (XtActionProc) EnginePopDown },
@@ -2017,9 +2006,6 @@ BoardToTop()
   return;
 }
 
-#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)
@@ -2084,7 +2070,7 @@ void InitDrawingSizes(BoardSize boardSize, int flags)
        }
 #ifdef GOTHIC
        if(gameInfo.variant == VariantGothic) {
-           ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[i][(int)WhiteSilver];
+           ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[(int)WhiteSilver];
        }
 #endif
 #endif
@@ -2112,7 +2098,19 @@ void InitDrawingSizes(BoardSize boardSize, int flags)
     CreateAnimVars();
 #endif
 }
-#endif
+
+void EscapeExpand(char *p, char *q)
+{      // [HGM] initstring: routine to shape up string arguments
+       while(*p++ = *q++) if(p[-1] == '\\')
+           switch(*q++) {
+               case 'n': p[-1] = '\n'; break;
+               case 'r': p[-1] = '\r'; break;
+               case 't': p[-1] = '\t'; break;
+               case '\\': p[-1] = '\\'; break;
+               case 0: *p = 0; return;
+               default: p[-1] = q[-1]; break;
+           }
+}
 
 int
 main(argc, argv)
@@ -2166,13 +2164,7 @@ main(argc, argv)
     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
-
 
     setbuf(stdout, NULL);
     setbuf(stderr, NULL);
@@ -2195,7 +2187,6 @@ main(argc, argv)
                      XtNumber(shellOptions),
                      &argc, argv, xboardResources, NULL, 0);
 
-
     /* set up GTK */
     gtk_init (&argc, &argv);
 
@@ -2208,13 +2199,29 @@ main(argc, argv)
 
     GUI_Window = GTK_WIDGET (gtk_builder_get_object (builder, "MainWindow"));
     if(!GUI_Window) printf("Error: gtk_builder didn't work!\n");
+
+    GUI_History = GTK_WIDGET (gtk_builder_get_object (builder, "MoveHistory"));
+    if(!GUI_History) printf("Error: gtk_builder didn't work!\n");
+
+    GUI_Menubar  = GTK_WIDGET (gtk_builder_get_object (builder, "MenuBar"));
+    if(!GUI_Menubar) printf("Error: gtk_builder didn't work!\n");
+    GUI_Timer  = GTK_WIDGET (gtk_builder_get_object (builder, "Timer"));
+    if(!GUI_Timer) printf("Error: gtk_builder didn't work!\n");
+    GUI_Buttonbar  = GTK_WIDGET (gtk_builder_get_object (builder, "ButtonBar"));
+    if(!GUI_Buttonbar) printf("Error: gtk_builder didn't work!\n");
     GUI_Board  = GTK_WIDGET (gtk_builder_get_object (builder, "Board"));
     if(!GUI_Board) printf("Error: gtk_builder didn't work!\n");
+
     GUI_Whiteclock  = GTK_WIDGET (gtk_builder_get_object (builder, "WhiteClock"));
     if(!GUI_Whiteclock) printf("Error: gtk_builder didn't work!\n");
+
     GUI_Blackclock  = GTK_WIDGET (gtk_builder_get_object (builder, "BlackClock"));
     if(!GUI_Blackclock) printf("Error: gtk_builder didn't work!\n");
 
+    LIST_MoveHistory = GTK_LIST_STORE (gtk_builder_get_object (builder, "MoveHistoryStore"));
+    if(!LIST_MoveHistory) printf("Error: gtk_builder didn't work!\n");
+
+
     gtk_builder_connect_signals (builder, NULL);
 
     // don't unref the builder, since we use it to get references to widgets
@@ -2226,40 +2233,29 @@ main(argc, argv)
       {
        fprintf(stderr, _("%s: unrecognized argument %s\n"),
                programName, argv[1]);
+
        fprintf(stderr, "Recognized options:\n");
-       for(i = 0; i < XtNumber(shellOptions); i++)
+       for(i = 0; i < XtNumber(shellOptions); i++) 
          {
+           /* print first column */
            j = fprintf(stderr, "  %s%s", shellOptions[i].option,
                        (shellOptions[i].argKind == XrmoptionSepArg
                         ? " ARG" : ""));
-           if (i++ < XtNumber(shellOptions))
-             {
+           /* print second column and end line */
+           if (++i < XtNumber(shellOptions)) 
+             {         
                fprintf(stderr, "%*c%s%s\n", 40 - j, ' ',
                        shellOptions[i].option,
                        (shellOptions[i].argKind == XrmoptionSepArg
                         ? " ARG" : ""));
-             }
-           else
+             } 
+           else 
              {
                fprintf(stderr, "\n");
-             }
-         }
+             };
+         };
        exit(2);
-      }
-
-    if ((chessDir = (char *) getenv("CHESSDIR")) == NULL)
-      {
-       chessDir = ".";
-      }
-    else
-      {
-       if (chdir(chessDir) != 0)
-         {
-           fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
-           perror(chessDir);
-           exit(1);
-         }
-      }
+      };
 
     p = getenv("HOME");
     if (p == NULL) p = "/tmp";
@@ -2273,6 +2269,28 @@ main(argc, argv)
                              clientResources, XtNumber(clientResources),
                              NULL, 0);
 
+    { // [HGM] initstring: kludge to fix bad bug. expand '\n' characters in init string and computer string.
+       static char buf[MSG_SIZ];
+       EscapeExpand(buf, appData.initString);
+       appData.initString = strdup(buf);
+       EscapeExpand(buf, appData.secondInitString);
+       appData.secondInitString = strdup(buf);
+       EscapeExpand(buf, appData.firstComputerString);
+       appData.firstComputerString = strdup(buf);
+       EscapeExpand(buf, appData.secondComputerString);
+       appData.secondComputerString = strdup(buf);
+    }
+
+    if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
+       chessDir = ".";
+    } else {
+       if (chdir(chessDir) != 0) {
+           fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
+           perror(chessDir);
+           exit(1);
+       }
+    }
+
     if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
        /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
         if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL)  {
@@ -2299,70 +2317,67 @@ main(argc, argv)
 
     gameInfo.variant = StringToVariant(appData.variant);
     InitPosition(FALSE);
-#if 0
 
-    /*
-     * Determine boardSize
-     */
-    gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
-
-    //#ifndef IDSIZE
-    // [HGM] as long as we have not created the possibility to change size while running, start with requested size
-    gameInfo.boardWidth    = appData.NrFiles > 0 ? appData.NrFiles : 8;
-    gameInfo.boardHeight   = appData.NrRanks > 0 ? appData.NrRanks : 8;
-    gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
-#endif
-
-
-#ifdef IDSIZE
-    InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
-#else
-    if (isdigit(appData.boardSize[0])) {
-      i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
-                &lineGap, &clockFontPxlSize, &coordFontPxlSize,
-                &fontPxlSize, &smallLayout, &tinyLayout);
-      if (i == 0) {
-       fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
-               programName, appData.boardSize);
-       exit(2);
-      }
-      if (i < 7) {
-       /* Find some defaults; use the nearest known size */
-       SizeDefaults *szd, *nearest;
-       int distance = 99999;
-       nearest = szd = sizeDefaults;
-       while (szd->name != NULL) {
-         if (abs(szd->squareSize - squareSize) < distance) {
-           nearest = szd;
-           distance = abs(szd->squareSize - squareSize);
-                          if (distance == 0) break;
-                          }
-             szd++;
-         }
-         if (i < 2) lineGap = nearest->lineGap;
-         if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
-         if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
-         if (i < 5) fontPxlSize = nearest->fontPxlSize;
-         if (i < 6) smallLayout = nearest->smallLayout;
-         if (i < 7) tinyLayout = nearest->tinyLayout;
-       }
-      } else {
-        SizeDefaults *szd = sizeDefaults;
-        if (*appData.boardSize == NULLCHAR) {
-         while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
-                DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
-           szd++;
-         }
-         if (szd->name == NULL) szd--;
-       } else {
-         while (szd->name != NULL &&
-                StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
-         if (szd->name == NULL) {
-           fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
+    /* calc board size */
+    if (isdigit(appData.boardSize[0])) 
+      {
+       i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
+                  &lineGap, &clockFontPxlSize, &coordFontPxlSize,
+                  &fontPxlSize, &smallLayout, &tinyLayout);
+       if (i == 0) 
+         {
+           fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
                    programName, appData.boardSize);
            exit(2);
          }
-       }
+       if (i < 7) 
+         {
+           /* Find some defaults; use the nearest known size */
+           SizeDefaults *szd, *nearest;
+           int distance = 99999;
+           nearest = szd = sizeDefaults;
+           while (szd->name != NULL) 
+             {
+               if (abs(szd->squareSize - squareSize) < distance) 
+                 {
+                   nearest = szd;
+                   distance = abs(szd->squareSize - squareSize);
+                   if (distance == 0) break;
+                 }
+               szd++;
+             };
+           if (i < 2) lineGap = nearest->lineGap;
+           if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
+           if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
+           if (i < 5) fontPxlSize = nearest->fontPxlSize;
+           if (i < 6) smallLayout = nearest->smallLayout;
+           if (i < 7) tinyLayout = nearest->tinyLayout;
+         }
+      } 
+    else 
+      {
+        SizeDefaults *szd = sizeDefaults;
+        if (*appData.boardSize == NULLCHAR) 
+         {
+           while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize 
+                  || DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) 
+             {
+               szd++;
+             }
+           if (szd->name == NULL) szd--;
+         } 
+       else 
+         {
+           while (szd->name != NULL 
+                  && StrCaseCmp(szd->name, appData.boardSize) != 0) 
+             szd++;
+           if (szd->name == NULL) 
+             {
+               fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
+                       programName, appData.boardSize);
+               exit(2);
+             }
+         }
        squareSize = szd->squareSize;
        lineGap = szd->lineGap;
        clockFontPxlSize = szd->clockFontPxlSize;
@@ -2370,26 +2385,12 @@ main(argc, argv)
        fontPxlSize = szd->fontPxlSize;
        smallLayout = szd->smallLayout;
        tinyLayout = szd->tinyLayout;
-    }
-
+      }
+    /* end figuring out what size to use */
+    
     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.
      */
@@ -2550,15 +2551,6 @@ main(argc, argv)
       /* TODO hide button bar if requested */
     }
 
-    /*
-     *  gtk set properties of widgets
-     */
-
-    /* set board size */
-    gtk_widget_set_size_request(GTK_WIDGET(GUI_Board),
-                               boardWidth,boardHeight);
-
-    /* end gtk set properties of widgets */
 
     if (appData.titleInWindow)
       {
@@ -2581,9 +2573,6 @@ main(argc, argv)
       {
       }
 
-    // [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
 
     /* set some checkboxes in the menu according to appData */
 
@@ -2676,7 +2665,6 @@ main(argc, argv)
 
     /* end setting check boxes */
 
-
     /* load square colors */
     SVGLightSquare   = load_pixbuf("svg/LightSquare.svg",squareSize);
     SVGDarkSquare    = load_pixbuf("svg/DarkSquare.svg",squareSize);
@@ -2688,16 +2676,11 @@ main(argc, argv)
     WindowIcon = WhiteIcon;
     gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
 
-    /* do resizing to a fixed aspect ratio */
-
-    {
-      int i,j;
-    }
-    GUI_SetAspectRatio(0.7);
 
     /* realize window */
     gtk_widget_show (GUI_Window);
 
+    /* recalc boardsize */
     CreateGCs();
     CreatePieces();
     CreatePieceMenus();
@@ -3013,6 +2996,8 @@ char *FindFont(pattern, targetPxlSize)
 
 void CreateGCs()
 {
+  /* GCs are not needed anymore for GTK  just left them in here for the moment, since there is a lot of X-code still around that's wants them*/
+
     XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
       | GCBackground | GCFunction | GCPlaneMask;
     XGCValues gc_values;
@@ -3093,17 +3078,29 @@ void CreateGCs()
 
 void CreatePieces()
 {
-  /* order of pieces
-  WhitePawn, WhiteKnight, WhiteBishop, WhiteRook, WhiteQueen, WhiteKing,
-  BlackPawn, BlackKnight, BlackBishop, BlackRook, BlackQueen, BlackKing,
-  */
   int i;
 
+  /* free if used 
+  for(i=0;i<MAXPIECES;i++)
+    {
+      if(SVGpieces[i])
+       {       
+         g_free(SVGpieces[i]);
+         SVGpieces[i]=NULL;
+       }
+    }
+  */
+
+  /* reload these */
+  SVGLightSquare   = load_pixbuf("svg/LightSquare.svg",squareSize);
+  SVGDarkSquare    = load_pixbuf("svg/DarkSquare.svg",squareSize);
+  SVGNeutralSquare = load_pixbuf("svg/NeutralSquare.svg",squareSize);
+
+
   /* get some defaults going */
   for(i=WhitePawn; i<DemotePiece+1; i++)
     SVGpieces[i]   = load_pixbuf("svg/NeutralSquare.svg",squareSize);
     
-
   SVGpieces[WhitePawn]   = load_pixbuf("svg/WhitePawn.svg",squareSize);
   SVGpieces[WhiteKnight] = load_pixbuf("svg/WhiteKnight.svg",squareSize);
   SVGpieces[WhiteBishop] = load_pixbuf("svg/WhiteBishop.svg",squareSize);
@@ -3203,39 +3200,6 @@ Widget CreateMenuBar(mb)
     return menuBar;
 }
 
-Widget CreateButtonBar(mi)
-     MenuItem *mi;
-{
-    int j;
-    Widget button, buttonBar;
-    Arg args[16];
-
-    j = 0;
-    XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
-    if (tinyLayout) {
-       XtSetArg(args[j], XtNhSpace, 0); j++;
-    }
-    XtSetArg(args[j], XtNborderWidth, 0); j++;
-    XtSetArg(args[j], XtNvSpace, 0);                        j++;
-    buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,
-                              formWidget, args, j);
-
-    while (mi->string != NULL) {
-       j = 0;
-       if (tinyLayout) {
-           XtSetArg(args[j], XtNinternalWidth, 2); j++;
-           XtSetArg(args[j], XtNborderWidth, 0); j++;
-       }
-      XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); j++;
-       button = XtCreateManagedWidget(mi->string, commandWidgetClass,
-                                      buttonBar, args, j);
-       XtAddCallback(button, XtNcallback,
-                     (XtCallbackProc) MenuBarSelect,
-                     (caddr_t) mi->proc);
-       mi++;
-    }
-    return buttonBar;
-}
 
 Widget
 CreatePieceMenu(name, color)
@@ -4064,10 +4028,40 @@ void HandleUserMove(w, event, prms, nprms)
 {
     int x, y;
     Boolean saveAnimate;
-    static int second = 0;
+    static int second = 0, promotionChoice = 0;
+    ChessMove moveType;
 
     if (w != boardWidget || errorExitStatus != -1) return;
 
+    x = EventToSquare(event->xbutton.x, BOARD_WIDTH);
+    y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);
+    if (!flipView && y >= 0) {
+       y = BOARD_HEIGHT - 1 - y;
+    }
+    if (flipView && x >= 0) {
+       x = BOARD_WIDTH - 1 - x;
+    }
+
+    if(promotionChoice) { // we are waiting for a click to indicate promotion piece
+       if(event->type == ButtonRelease) return; // ignore upclick of click-click destination
+       promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel
+       if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y);
+       if(gameInfo.holdingsWidth && 
+               (WhiteOnMove(currentMove) 
+                       ? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0
+                       : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) {
+           // click in right holdings, for determining promotion piece
+           ChessSquare p = boards[currentMove][y][x];
+           if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p);
+           if(p != EmptySquare) {
+               FinishMove(NormalMove, fromX, fromY, toX, toY, ToLower(PieceToChar(p)));
+               fromX = fromY = -1;
+               return;
+           }
+       }
+       DrawPosition(FALSE, boards[currentMove]);
+       return;
+    }
     if (event->type == ButtonPress) ErrorPopDown();
 
     if (promotionUp) {
@@ -4082,15 +4076,6 @@ void HandleUserMove(w, event, prms, nprms)
        }
     }
 
-    x = EventToSquare(event->xbutton.x, BOARD_WIDTH);
-    y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);
-    if (!flipView && y >= 0) {
-       y = BOARD_HEIGHT - 1 - y;
-    }
-    if (flipView && x >= 0) {
-       x = BOARD_WIDTH - 1 - x;
-    }
-
     /* [HGM] holdings: next 5 lines: ignore all clicks between board and holdings */
     if(event->type == ButtonPress
             && ( x == BOARD_LEFT-1 || 
@@ -4101,7 +4086,7 @@ void HandleUserMove(w, event, prms, nprms)
 
     if (fromX == -1) {
        if (event->type == ButtonPress) {
-           /* First square */
+           /* First square, prepare to drag */
            if (OKToStartUserMove(x, y)) {
                fromX = x;
                fromY = y;
@@ -4116,35 +4101,8 @@ void HandleUserMove(w, event, prms, nprms)
     }
 
     /* fromX != -1 */
-    if (event->type == ButtonPress && gameMode != EditPosition &&
-       x >= 0 && y >= 0) {
-       ChessSquare fromP;
-       ChessSquare toP;
-
-       /* Check if clicking again on the same color piece */
-       fromP = boards[currentMove][fromY][fromX];
-       toP = boards[currentMove][y][x];
-       if ((WhitePawn <= fromP && fromP < WhiteKing && // [HGM] this test should go, as UserMoveTest now does it.
-            WhitePawn <= toP && toP <= WhiteKing) ||   //       For now I made it less critical by exempting King
-           (BlackPawn <= fromP && fromP < BlackKing && //       moves, to not interfere with FRC castlings.
-            BlackPawn <= toP && toP <= BlackKing)) {
-           /* Clicked again on same color piece -- changed his mind */
-           second = (x == fromX && y == fromY);
-           if (appData.highlightDragging) {
-               SetHighlights(x, y, -1, -1);
-           } else {
-               ClearHighlights();
-           }
-           if (OKToStartUserMove(x, y)) {
-               fromX = x;
-               fromY = y;
-               DragPieceBegin(event->xbutton.x, event->xbutton.y);
-           }
-           return;
-       }
-    }
-
     if (event->type == ButtonRelease &&        x == fromX && y == fromY) {
+    /* Click on single square in stead of drag-drop */
        DragPieceEnd(event->xbutton.x, event->xbutton.y);
        if (appData.animateDragging) {
            /* Undo animation damage if any */
@@ -4164,7 +4122,34 @@ void HandleUserMove(w, event, prms, nprms)
        return;
     }
 
-    /* Completed move */
+    moveType = UserMoveTest(fromX, fromY, x, y, NULLCHAR, event->type == ButtonRelease);
+
+    if (moveType == Comment) { // kludge for indicating capture-own on Press
+      /* Clicked again on same color piece -- changed his mind */
+      /* note that re-clicking same square always hits same color piece */
+      second = (x == fromX && y == fromY);
+      if (appData.highlightDragging) {
+       SetHighlights(x, y, -1, -1);
+      } else {
+       ClearHighlights();
+      }
+      if (OKToStartUserMove(x, y)) {
+       fromX = x;
+       fromY = y;
+       DragPieceBegin(event->xbutton.x, event->xbutton.y);
+      }
+      return;
+    }
+
+    if(moveType == AmbiguousMove) { // kludge to indicate edit-position move
+      fromX = fromY = -1; 
+      ClearHighlights();
+      DragPieceEnd(event->xbutton.x, event->xbutton.y);
+      DrawPosition(FALSE, boards[currentMove]);
+      return;
+    }
+
+    /* Complete move; (x,y) is now different from (fromX, fromY) on both Press and Release */
     toX = x;
     toY = y;
     saveAnimate = appData.animate;
@@ -4186,22 +4171,38 @@ void HandleUserMove(w, event, prms, nprms)
        /* Don't animate move and drag both */
        appData.animate = FALSE;
     }
-    if (IsPromotion(fromX, fromY, toX, toY)) {
-       if (appData.alwaysPromoteToQueen) {
-           UserMoveEvent(fromX, fromY, toX, toY, 'q');
+    if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight ||
+        (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) &&
+            appData.alwaysPromoteToQueen) { // promotion, but no choice
+      FinishMove(moveType, fromX, fromY, toX, toY, 'q');
+    } else
+    if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) {
+       SetHighlights(fromX, fromY, toX, toY);
+       if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) {
+           // [HGM] super: promotion to captured piece selected from holdings
+           ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX];
+           promotionChoice = TRUE;
+           // kludge follows to temporarily execute move on display, without promoting yet
+           boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank
+           boards[currentMove][toY][toX] = p;
+           DrawPosition(FALSE, boards[currentMove]);
+           boards[currentMove][fromY][fromX] = p; // take back, but display stays
+           boards[currentMove][toY][toX] = q;
+           DisplayMessage("Click in holdings to choose piece", "");
+           return;
+       }
+       PromotionPopUp();
+       goto skipClearingFrom; // the skipped stuff is done asynchronously by PromotionCallback
+    } else
+    if(moveType != ImpossibleMove) { // valid move, but no promotion
+      FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);
+    } else { // invalid move; could have set premove
+      ClearHighlights();
+    }
            if (!appData.highlightLastMove || gotPremove) ClearHighlights();
            if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
            fromX = fromY = -1;
-       } else {
-           SetHighlights(fromX, fromY, toX, toY);
-           PromotionPopUp();
-       }
-    } else {
-       UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
-       if (!appData.highlightLastMove || gotPremove) ClearHighlights();
-       if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
-       fromX = fromY = -1;
-    }
+skipClearingFrom:
     appData.animate = saveAnimate;
     if (appData.animate || appData.animateDragging) {
        /* Undo animation damage if needed */
@@ -4260,12 +4261,8 @@ Widget CommentCreate(name, text, mutable, callback, lines)
     XtSetArg(args[j], XtNright, XtChainRight);  j++;
     XtSetArg(args[j], XtNresizable, True);  j++;
     XtSetArg(args[j], XtNwidth, bw_width);  j++; /*force wider than buttons*/
-#if 0
-    XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded);  j++;
-#else
     /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
     XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways);  j++;
-#endif
     XtSetArg(args[j], XtNautoFill, True);  j++;
     XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
     edit =
@@ -4418,12 +4415,8 @@ Widget MiscCreate(name, text, mutable, callback, lines)
     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
     XtSetArg(args[j], XtNright, XtChainRight);  j++;
     XtSetArg(args[j], XtNresizable, True);  j++;
-#if 0
-    XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded);  j++;
-#else
     /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
     XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways);  j++;
-#endif
     XtSetArg(args[j], XtNautoFill, True);  j++;
     XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
     edit =
@@ -4986,7 +4979,7 @@ void PromotionCallback(w, client_data, call_data)
        promoChar = ToLower(name[0]);
     }
 
-    UserMoveEvent(fromX, fromY, toX, toY, promoChar);
+    FinishMove(NormalMove, fromX, fromY, toX, toY, promoChar);
 
     if (!appData.highlightLastMove || gotPremove) ClearHighlights();
     if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
@@ -5152,47 +5145,27 @@ int LoadGamePopUp(f, gameNumber, title)
      char *title;
 {
     cmailMsgLoaded = FALSE;
-    if (gameNumber == 0) {
+
+    if (gameNumber == 0) 
+      {
        int error = GameListBuild(f);
-       if (error) {
+
+       if (error) 
+         {
            DisplayError(_("Cannot build game list"), error);
-       } else if (!ListEmpty(&gameList) &&
-                  ((ListGame *) gameList.tailPred)->number > 1) {
+         } 
+       else if (!ListEmpty(&gameList) 
+                && ((ListGame *) gameList.tailPred)->number > 1) 
+         {
            GameListPopUp(f, title);
            return TRUE;
-       }
+         };
+
        GameListDestroy();
        gameNumber = 1;
-    }
-    return LoadGame(f, gameNumber, title, FALSE);
-}
+      };
 
-
-void LoadNextPositionProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    ReloadPosition(1);
-}
-
-void LoadPrevPositionProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    ReloadPosition(-1);
-}
-
-void ReloadPositionProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    ReloadPosition(0);
+    return LoadGame(f, gameNumber, title, FALSE);
 }
 
 void LoadPositionProc(w, event, prms, nprms)
@@ -5469,7 +5442,7 @@ void AnalyzeModeProc(w, event, prms, nprms)
             fprintf(debugFP, _("ICS engine analyze starting... \n"));
     }
     if (!appData.showThinking)
-      ShowThinkingProc(w,event,prms,nprms);
+      ShowThinkingProc(NULL,NULL);
 
     AnalyzeModeEvent();
 }
@@ -5489,7 +5462,7 @@ void AnalyzeFileProc(w, event, prms, nprms)
     Reset(FALSE, TRUE);
 
     if (!appData.showThinking)
-      ShowThinkingProc(w,event,prms,nprms);
+      ShowThinkingProc(NULL,NULL);
 
     AnalyzeFileEvent();
     FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
@@ -5799,26 +5772,6 @@ void FlashMovesProc(w, event, prms, nprms)
                args, 1);
 }
 
-void GetMoveListProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    appData.getMoveList = !appData.getMoveList;
-
-    if (appData.getMoveList) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-       GetMoveListEvent();
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
-               args, 1);
-}
-
 #if HIGHDRAG
 void HighlightDraggingProc(w, event, prms, nprms)
      Widget w;
@@ -6031,48 +5984,6 @@ void QuietPlayProc(w, event, prms, nprms)
                args, 1);
 }
 
-void ShowThinkingProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent
-    ShowThinkingEvent();
-#if 0
-    // [HGM] thinking: currently no suc menu item; replaced by Hide Thinking (From Human)
-    if (appData.showThinking) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
-               args, 1);
-#endif
-}
-
-void HideThinkingProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    appData.hideThinkingFromHuman = !appData.hideThinkingFromHuman; // [HGM] thinking: tken out of ShowThinkingEvent
-    ShowThinkingEvent();
-
-    if (appData.hideThinkingFromHuman) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
-               args, 1);
-}
-
 void DebugProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6628,6 +6539,9 @@ void
 ScheduleDelayedEvent(cb, millisec)
      DelayedEventCallback cb; guint millisec;
 {
+    if(delayedEventTimerTag && delayedEventCallback == cb)
+       // [HGM] alive: replace, rather than add or flush identical event
+       g_source_remove(delayedEventTimerTag);
     delayedEventCallback = cb;
     delayedEventTimerTag = g_timeout_add(millisec,(GSourceFunc) FireDelayedEvent, NULL);
     return;
@@ -7462,12 +7376,7 @@ FrameDelay (time)
     delay.it_interval.tv_usec =
       delay.it_value.tv_usec = (time % 1000) * 1000;
     setitimer(ITIMER_REAL, &delay, NULL);
-#if 0
-    /* Ugh -- busy-wait! --tpm */
-    while (frameWaiting);
-#else
     while (frameWaiting) pause();
-#endif
     delay.it_interval.tv_sec = delay.it_value.tv_sec = 0;
     delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;
     setitimer(ITIMER_REAL, &delay, NULL);
@@ -7920,19 +7829,10 @@ DragPieceBegin(x, y)
     ScreenSquare(boardX, boardY, &corner, &color);
     player.startSquare  = corner;
     player.startColor   = color;
-#if 0
-    /* Start from exactly where the piece is.  This can be confusing
-       if you start dragging far from the center of the square; most
-       or all of the piece can be over a different square from the one
-       the mouse pointer is in. */
-    player.mouseDelta.x = x - corner.x;
-    player.mouseDelta.y = y - corner.y;
-#else
     /* As soon as we start dragging, the piece will jump slightly to
        be centered over the mouse pointer. */
     player.mouseDelta.x = squareSize/2;
     player.mouseDelta.y = squareSize/2;
-#endif
     /* Initialise animation */
     player.dragPiece = PieceForSquare(boardX, boardY);
     /* Sanity check */