Merge branch 'v4.7.x'
[xboard.git] / backend.c
index 24ae75d..94d715d 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -5239,7 +5239,8 @@ ProcessICSInitScript (FILE *f)
 }
 
 
-static int lastX, lastY, selectFlag, dragging;
+static int lastX, lastY, lastLeftX, lastLeftY, selectFlag, dragging;
+static ClickType lastClickType;
 
 void
 Sweep (int step)
@@ -7025,6 +7026,7 @@ MarkByFEN(char *fen)
        while(*fen) {
            int s = 0;
            marker[r][f] = 0;
+           if(*fen == 'M') legal[r][f] = 2; else // request promotion choice
            if(*fen >= 'A' && *fen <= 'Z') legal[r][f] = 1; else
            if(*fen >= 'a' && *fen <= 'z') *fen += 'A' - 'a';
            if(*fen == '/' && f > BOARD_LEFT) f = BOARD_LEFT, r--; else
@@ -7124,8 +7126,8 @@ HoverEvent (int hiX, int hiY, int x, int y)
          // [HGM] lift: entered new to-square; redraw arrow, and inform engine
          for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++)
            marker[r][f] = baseMarker[r][f], legal[r][f] = baseLegal[r][f];
-         if(marker[y][x] == 2 && legal[y][x] == 1) {
-           char buf[MSG_SIZ];
+         if((marker[y][x] == 2 || marker[y][x] == 6) && legal[y][x]) {
+           char buf[MSG_SIZ];
            snprintf(buf, MSG_SIZ, "hover %c%d\n", x + AAA, y + ONE - '0');
            SendToProgram(buf, &first);
          }
@@ -7159,6 +7161,7 @@ LeftClick (ClickType clickType, int xPix, int yPix)
     prevClickTime = lastClickTime; GetTimeMark(&lastClickTime);
 
     if (clickType == Press) ErrorPopDown();
+    lastClickType = clickType, lastLeftX = xPix, lastLeftY = yPix; // [HGM] alien: remember state
 
     x = EventToSquare(xPix, BOARD_WIDTH);
     y = EventToSquare(yPix, BOARD_HEIGHT);
@@ -7378,7 +7381,7 @@ LeftClick (ClickType clickType, int xPix, int yPix)
            if(x >= BOARD_LEFT && x < BOARD_RGHT) clearFlag = 1; // and defer click-click move of empty-square to up-click
            return;
        }
-       if(HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, FALSE)) {
+       if(legal[y][x] == 2 || HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, FALSE)) {
          if(appData.sweepSelect) {
            ChessSquare piece = boards[currentMove][fromY][fromX];
            promoSweep = defaultPromoChoice;
@@ -8664,6 +8667,23 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
        MarkByFEN(message+10); // [HGM] alien: allow engine to mark board squares
        return;
     }
+    if(!strncmp(message, "click ", 6)) {
+       char f, c=0; int x, y; // [HGM] alien: allow engine to finish user moves (i.e. engine-driven one-click moving)
+       if(appData.testLegality || !appData.oneClick) return;
+       sscanf(message+6, "%c%d%c", &f, &y, &c);
+       x = f - 'a' + BOARD_LEFT, y -= ONE - '0';
+       if(flipView) x = BOARD_WIDTH-1 - x; else y = BOARD_HEIGHT-1 - y;
+       x = x*squareSize + (x+1)*lineGap + squareSize/2;
+       y = y*squareSize + (y+1)*lineGap + squareSize/2;
+       f = first.highlight; first.highlight = 0; // kludge to suppress lift/put in response to own clicks
+       if(lastClickType == Press) // if button still down, fake release on same square, to be ready for next click
+           LeftClick(Release, lastLeftX, lastLeftY);
+       controlKey  = (c == ',');
+       LeftClick(Press, x, y);
+       LeftClick(Release, x, y);
+       first.highlight = f;
+       return;
+    }
     /*
      * If the move is illegal, cancel it and redraw the board.
      * Also deal with other error cases.  Matching is rather loose