Redo arrow highlighting with cairo
[xboard.git] / backend.c
index 6442bea..c830d4e 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -270,6 +270,7 @@ char lastMsg[MSG_SIZ];
 ChessSquare pieceSweep = EmptySquare;
 ChessSquare promoSweep = EmptySquare, defaultPromoChoice;
 int promoDefaultAltered;
+int keepInfo = 0; /* [HGM] to protect PGN tags in auto-step game analysis */
 
 /* States for ics_getting_history */
 #define H_FALSE 0
@@ -2510,6 +2511,14 @@ PlotSeekAd (int i)
 }
 
 void
+PlotSingleSeekAd (int i)
+{
+       DrawSeekOpen();
+       PlotSeekAd(i);
+       DrawSeekClose();
+}
+
+void
 AddAd (char *handle, char *rating, int base, int inc,  char rated, char *type, int nr, Boolean plot)
 {
        char buf[MSG_SIZ], *ext = "";
@@ -2529,7 +2538,7 @@ AddAd (char *handle, char *rating, int base, int inc,  char rated, char *type, i
            seekNrList[nrOfSeekAds] = nr;
            zList[nrOfSeekAds] = 0;
            seekAdList[nrOfSeekAds++] = StrSave(buf);
-           if(plot) PlotSeekAd(nrOfSeekAds-1);
+           if(plot) PlotSingleSeekAd(nrOfSeekAds-1);
        }
 }
 
@@ -2593,6 +2602,7 @@ DrawSeekGraph ()
     h = BOARD_HEIGHT * (squareSize + lineGap) + lineGap;
     w = BOARD_WIDTH  * (squareSize + lineGap) + lineGap;
 
+    DrawSeekOpen();
     DrawSeekBackground(0, 0, w, h);
     DrawSeekAxis(hMargin, h-1-vMargin, w-5, h-1-vMargin);
     DrawSeekAxis(hMargin, h-1-vMargin, hMargin, 5);
@@ -2617,6 +2627,7 @@ DrawSeekGraph ()
        }
     }
     for(i=0; i<nrOfSeekAds; i++) PlotSeekAd(i);
+    DrawSeekClose();
     return TRUE;
 }
 
@@ -7101,6 +7112,9 @@ LeftClick (ClickType clickType, int xPix, int yPix)
        return;
       }
       doubleClick = FALSE;
+      if(gameMode == AnalyzeMode && pausing && first.excludeMoves) { // use pause state to exclude moves
+       doubleClick = TRUE; gatingPiece = boards[currentMove][y][x];
+      }
       fromX = x; fromY = y; toX = toY = -1;
       if(!appData.oneClick || !OnlyMove(&x, &y, FALSE) ||
         // even if only move, we treat as normal when this would trigger a promotion popup, to allow sweep selection
@@ -10202,9 +10216,10 @@ GetEngineLine (char *s, int n)
     char buf[MSG_SIZ];
     extern char *icsNames;
     if(!s || !*s) return 0;
-    NamesToList(n == 10 ? icsNames : firstChessProgramNames, command, mnemonic, "all");
+    NamesToList(n >= 10 ? icsNames : firstChessProgramNames, command, mnemonic, "all");
     for(i=1; mnemonic[i]; i++) if(!strcmp(s, mnemonic[i])) break;
     if(!mnemonic[i]) return 0;
+    if(n == 11) return 1; // just testing if there was a match
     snprintf(buf, MSG_SIZ, "-%s %s", n == 10 ? "icshost" : "fcp", command[i]);
     if(n == 1) SwapEngines(n);
     ParseArgsFromString(buf);
@@ -11007,6 +11022,11 @@ AutoPlayGameLoop ()
     }
 }
 
+void
+AnalyzeNextGame()
+{
+    ReloadGame(1); // next game
+}
 
 int
 AutoPlayOneMove ()
@@ -11028,7 +11048,14 @@ AutoPlayOneMove ()
     }
 
     if (currentMove >= forwardMostMove) {
-      if(gameMode == AnalyzeFile) { ExitAnalyzeMode(); SendToProgram("force\n", &first); }
+      if(gameMode == AnalyzeFile) {
+         if(appData.loadGameIndex == -1) {
+           GameEnds(EndOfFile, NULL, GE_FILE);
+          ScheduleDelayedEvent(AnalyzeNextGame, 10);
+         } else {
+          ExitAnalyzeMode(); SendToProgram("force\n", &first);
+        }
+      }
 //      gameMode = EndOfGame;
 //      ModeHighlight();
 
@@ -11872,6 +11899,9 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList)
            gn = 1;
        }
        else {
+           if(gameMode == AnalyzeFile && appData.loadGameIndex == -1)
+             appData.loadGameIndex = 0; // [HGM] suppress error message if we reach file end after auto-stepping analysis
+           else
            DisplayError(_("Game number out of range"), 0);
            return FALSE;
        }
@@ -12265,7 +12295,10 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList)
 
     if (oldGameMode == AnalyzeFile ||
        oldGameMode == AnalyzeMode) {
+      appData.loadGameIndex = -1; // [HGM] order auto-stepping through games
+      keepInfo = 1;
       AnalyzeFileEvent();
+      keepInfo = 0;
     }
 
     if (!matchMode && pos > 0) {
@@ -13359,6 +13392,7 @@ PauseEvent ()
                 WhiteOnMove(forwardMostMove))) {
                StopClocks();
            }
+         case AnalyzeMode:
            pausing = TRUE;
            ModeHighlight();
            break;
@@ -15053,6 +15087,8 @@ SetGameInfo ()
     ChessMove r = GameUnfinished;
     char *p = NULL;
 
+    if(keepInfo) return;
+
     if(gameMode == EditGame) { // [HGM] vari: do not erase result on EditGame
        r = gameInfo.result;
        p = gameInfo.resultDetails;