Redraw second board on expose events
authorH.G. Muller <h.g.muller@hccnet.nl>
Thu, 25 Feb 2010 11:02:58 +0000 (12:02 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Thu, 25 Feb 2010 14:28:33 +0000 (15:28 +0100)
The -dualBoard option now does refresh the second board after another
window uncovers it. To acheive this, some data structures remembering
what is displayed had to be duplicated. (lastBoard and damage for XB,
lastReq, lastDrawn, lastReqValid and lastDrawnValid for WB.)
WinBoard now uses clipping also for second board. This required the
clips for the destination to be translated horizontally!

backend.c
winboard/winboard.c
xboard.c

index cf62bb4..24e8378 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -3667,7 +3667,7 @@ read_from_ics(isr, closure, data, count, error)
                         CopyHoldings(partnerBoard, black_holding, BlackPawn);
                         if(twoBoards) { partnerUp = 1; flipView = !flipView; } // [HGM] dual: always draw
                         if(partnerUp) DrawPosition(FALSE, partnerBoard);
-                        if(twoBoards) { partnerUp = 0; flipView = !flipView; DrawPosition(TRUE, boards[currentMove]); } // [HGM] dual: redraw own
+                        if(twoBoards) { partnerUp = 0; flipView = !flipView; }
                      }
                    }
                    /* Suppress following prompt */
@@ -3744,7 +3744,7 @@ ParseBoard12(string)
     char promoChar;
     int ranks=1, files=0; /* [HGM] ICS80: allow variable board size */
     char *bookHit = NULL; // [HGM] book
-    Boolean weird = FALSE, reqFlag = FALSE;
+    Boolean weird = FALSE, reqFlag = FALSE, repaint = FALSE;
 
     fromX = fromY = toX = toY = -1;
     
@@ -3829,10 +3829,11 @@ ParseBoard12(string)
              board[k][1] = board[k][BOARD_WIDTH-2] = (ChessSquare) 0;;
         }
       }
-      if(appData.dualBoard) { twoBoards = partnerUp = 1; flipView = !flipView; InitDrawingSizes(-2,0); } // [HGM] dual
       CopyBoard(partnerBoard, board);
-      if(partnerUp) DrawPosition(FALSE, partnerBoard);
-      if(twoBoards) { partnerUp = 0; flipView = !flipView; DrawPosition(TRUE, boards[currentMove]); } // [HGM] dual: redraw own game!
+      if(appData.dualBoard && !twoBoards) { twoBoards = repaint = 1; InitDrawingSizes(-2,0); }
+      if(twoBoards) { partnerUp = 1; flipView = !flipView; } // [HGM] dual
+      if(partnerUp) DrawPosition(repaint, partnerBoard);
+      if(twoBoards) { partnerUp = 0; flipView = !flipView; } // [HGM] dual
       sprintf(partnerStatus, "W: %d:%02d B: %d:%02d (%d-%d) %c", white_time/60000, (white_time%60000)/1000,
                 (black_time/60000), (black_time%60000)/1000, white_stren, black_stren, to_play);
       DisplayMessage(partnerStatus, "");
@@ -8904,8 +8905,10 @@ GameEnds(result, resultDetails, whosays)
 
     if(endingGame) return; /* [HGM] crash: forbid recursion */
     endingGame = 1;
-    if(twoBoards) { twoBoards = partnerUp = 0; InitDrawingSizes(-2, 0); } // [HGM] dual
-
+    if(twoBoards) { // [HGM] dual: switch back to one board
+       twoBoards = partnerUp = 0; InitDrawingSizes(-2, 0);
+       DrawPosition(TRUE, partnerBoard); // observed game becomes foreground
+    }
     if (appData.debugMode) {
       fprintf(debugFP, "GameEnds(%d, %s, %d)\n",
              result, resultDetails ? resultDetails : "(null)", whosays);
index 6eca914..e943a22 100644 (file)
@@ -3155,10 +3155,10 @@ void DrawSeekDot(int x, int y, int color)
 VOID\r
 HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)\r
 {\r
-  static Board lastReq, lastDrawn;\r
+  static Board lastReq[2], lastDrawn[2];\r
   static HighlightInfo lastDrawnHighlight, lastDrawnPremove;\r
   static int lastDrawnFlipView = 0;\r
-  static int lastReqValid = 0, lastDrawnValid = 0;\r
+  static int lastReqValid[2] = {0, 0}, lastDrawnValid[2] = {0, 0};\r
   int releaseDC, x, y, x2, y2, row, column, num_clips = 0, i;\r
   HDC tmphdc;\r
   HDC hdcmem;\r
@@ -3167,6 +3167,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   RECT Rect;\r
   HRGN clips[MAX_CLIPS];\r
   ChessSquare dragged_piece = EmptySquare;\r
+  int nr = twoBoards*partnerUp;\r
 \r
   /* I'm undecided on this - this function figures out whether a full\r
    * repaint is necessary on its own, so there's no real reason to have the\r
@@ -3183,16 +3184,15 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   if( DrawPositionNeedsFullRepaint() ) {\r
       fullrepaint = TRUE;\r
   }\r
-  if(twoBoards) fullrepaint = TRUE; // [HGM] dual: our memory of last-drawn will be all wrong\r
 \r
   if (board == NULL) {\r
-    if (!lastReqValid) {\r
+    if (!lastReqValid[nr]) {\r
       return;\r
     }\r
-    board = lastReq;\r
+    board = lastReq[nr];\r
   } else {\r
-    CopyBoard(lastReq, board);\r
-    lastReqValid = 1;\r
+    CopyBoard(lastReq[nr], board);\r
+    lastReqValid[nr] = 1;\r
   }\r
 \r
   if (doingSizing) {\r
@@ -3238,16 +3238,17 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
    * newest board with the last drawn board and checking if\r
    * flipping has changed.\r
    */\r
-  if (!fullrepaint && lastDrawnValid && lastDrawnFlipView == flipView) {\r
+  if (!fullrepaint && lastDrawnValid[nr] && (nr == 1 || lastDrawnFlipView == flipView)) {\r
     for (row = 0; row < BOARD_HEIGHT; row++) { /* [HGM] true size, not 8 */\r
       for (column = 0; column < BOARD_WIDTH; column++) {\r
-       if (lastDrawn[row][column] != board[row][column]) {\r
+       if (lastDrawn[nr][row][column] != board[row][column]) {\r
          SquareToPos(row, column, &x, &y);\r
          clips[num_clips++] =\r
            CreateRectRgn(x, y, x + squareSize, y + squareSize);\r
        }\r
       }\r
     }\r
+   if(nr == 0) { // [HGM] dual: no highlights on second board\r
     for (i=0; i<2; i++) {\r
       if (lastDrawnHighlight.sq[i].x != highlightInfo.sq[i].x ||\r
          lastDrawnHighlight.sq[i].y != highlightInfo.sq[i].y) {\r
@@ -3288,6 +3289,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
        }\r
       }\r
     }\r
+   }\r
   } else {\r
     fullrepaint = TRUE;\r
   }\r
@@ -3347,7 +3349,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
         explodes.  The old and new positions both had an empty square\r
         at the destination, but animation has drawn a piece there and\r
         we have to remember to erase it. [HGM] moved until after setting lastDrawn */\r
-      lastDrawn[animInfo.to.y][animInfo.to.x] = animInfo.piece;\r
+      lastDrawn[0][animInfo.to.y][animInfo.to.x] = animInfo.piece;\r
     }\r
   }\r
 \r
@@ -3384,9 +3386,10 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
        SelectObject(hdcmem, oldBrush);\r
   } else {\r
     DrawGridOnDC(hdcmem);\r
-    DrawHighlightsOnDC(hdcmem);\r
+    if(nr == 0) DrawHighlightsOnDC(hdcmem); // [HGM] dual: no highlights on right board yet\r
     DrawBoardOnDC(hdcmem, board, tmphdc);\r
   }\r
+  if(nr == 0) // [HGM] dual: markers only on left board\r
   for (row = 0; row < BOARD_HEIGHT; row++) {\r
     for (column = 0; column < BOARD_WIDTH; column++) {\r
        if (marker[row][column]) { // marker changes only occur with full repaint!\r
@@ -3441,7 +3444,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
 \r
   DrawCoordsOnDC(hdcmem);\r
 \r
-  CopyBoard(lastDrawn, board); /* [HGM] Moved to here from end of routine, */\r
+  CopyBoard(lastDrawn[nr], board); /* [HGM] Moved to here from end of routine, */\r
                  /* to make sure lastDrawn contains what is actually drawn */\r
 \r
   /* Put the dragged piece back into place and draw it (out of place!) */\r
@@ -3478,6 +3481,13 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
 \r
   /* Set clipping on the target DC */\r
   if (!fullrepaint) {\r
+    if(nr == 1) for (x = 0; x < num_clips; x++) { // [HGM] dual: translate clips\r
+       RECT rect;\r
+       GetRgnBox(clips[x], &rect);\r
+       DeleteObject(clips[x]);\r
+       clips[x] = CreateRectRgn(rect.left + wpMain.width/2, rect.top, \r
+                         rect.right + wpMain.width/2, rect.bottom);\r
+    }\r
     SelectClipRgn(hdc, clips[0]);\r
     for (x = 1; x < num_clips; x++) {\r
       if (ExtSelectClipRgn(hdc, clips[x], RGN_OR) == ERROR)\r
@@ -3577,7 +3587,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   if (releaseDC) \r
     ReleaseDC(hwndMain, hdc);\r
   \r
-  if (lastDrawnFlipView != flipView) {\r
+  if (lastDrawnFlipView != flipView && nr == 0) {\r
     if (flipView)\r
       CheckMenuItem(GetMenu(hwndMain),IDM_FlipView, MF_BYCOMMAND|MF_CHECKED);\r
     else\r
@@ -3588,7 +3598,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   lastDrawnHighlight = highlightInfo;\r
   lastDrawnPremove   = premoveHighlightInfo;\r
   lastDrawnFlipView = flipView;\r
-  lastDrawnValid = 1;\r
+  lastDrawnValid[nr] = 1;\r
 }\r
 \r
 /* [HGM] diag: Save the current board display to the given open file and close the file */\r
@@ -3629,6 +3639,11 @@ PaintProc(HWND hwnd)
        RealizePalette(hdc);\r
       }\r
       HDCDrawPosition(hdc, 1, NULL);\r
+      if(twoBoards) { // [HGM] dual: also redraw other board in other orientation\r
+       flipView = !flipView; partnerUp = !partnerUp;\r
+       HDCDrawPosition(hdc, 1, NULL);\r
+       flipView = !flipView; partnerUp = !partnerUp;\r
+      }\r
       oldFont =\r
        SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf);\r
       ExtTextOut(hdc, messageRect.left, messageRect.top,\r
index 2ce05c6..d049062 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -4283,7 +4283,7 @@ void DrawSquare(row, column, piece, do_flash)
                        x + 2, y + font_ascent + 1, string, 1);
        }
     }
-    if(marker[row][column]) {
+    if(!partnerUp && marker[row][column]) {
        XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? prelineGC : highlineGC, 
                x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360);
     }
@@ -4303,6 +4303,11 @@ void EventProc(widget, unused, event)
       case Expose:
        if (event->xexpose.count > 0) return;  /* no clipping is done */
        XDrawPosition(widget, True, NULL);
+       if(twoBoards) { // [HGM] dual: draw other board in other orientation
+           flipView = !flipView; partnerUp = !partnerUp;
+           XDrawPosition(widget, True, NULL);
+           flipView = !flipView; partnerUp = !partnerUp;
+       }
        break;
       case MotionNotify:
         if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break;\r
@@ -4416,7 +4421,7 @@ void DrawSeekDot(int x, int y, int colorNr)
                x-squareSize/8, y-squareSize/8, squareSize/4, squareSize/4, 0, 64*360);
 }
 
-static int damage[BOARD_RANKS][BOARD_FILES];
+static int damage[2][BOARD_RANKS][BOARD_FILES];
 
 /*
  * event handler for redrawing the board
@@ -4428,19 +4433,19 @@ void XDrawPosition(w, repaint, board)
 {
     int i, j, do_flash;
     static int lastFlipView = 0;
-    static int lastBoardValid = 0;
-    static Board lastBoard;
+    static int lastBoardValid[2] = {0, 0};
+    static Board lastBoard[2];
     Arg args[16];
     int rrow, rcol;
+    int nr = twoBoards*partnerUp;
 
     if(DrawSeekGraph()) return; // [HGM] seekgraph: suppress any drawing if seek graph up
-    if(twoBoards) repaint = True;
 
     if (board == NULL) {
        if (!lastBoardValid) return;
-       board = lastBoard;
+       board = lastBoard[nr];
     }
-    if (!lastBoardValid || lastFlipView != flipView) {
+    if (!lastBoardValid[nr] || (nr == 0 && lastFlipView != flipView)) {
        XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
        XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
                    args, 1);
@@ -4451,19 +4456,19 @@ void XDrawPosition(w, repaint, board)
      * but this causes a very distracting flicker.
      */
 
-    if (!repaint && lastBoardValid && lastFlipView == flipView) {
+    if (!repaint && lastBoardValid[nr] && (nr == 1 || lastFlipView == flipView)) {
 
        /* If too much changes (begin observing new game, etc.), don't
           do flashing */
-       do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;
+       do_flash = too_many_diffs(board, lastBoard[nr]) ? 0 : 1;
 
        /* Special check for castling so we don't flash both the king
           and the rook (just flash the king). */
        if (do_flash) {
-           if (check_castle_draw(board, lastBoard, &rrow, &rcol)) {
+           if (check_castle_draw(board, lastBoard[nr], &rrow, &rcol)) {
                /* Draw rook with NO flashing. King will be drawn flashing later */
                DrawSquare(rrow, rcol, board[rrow][rcol], 0);
-               lastBoard[rrow][rcol] = board[rrow][rcol];
+               lastBoard[nr][rrow][rcol] = board[rrow][rcol];
            }
        }
 
@@ -4472,16 +4477,16 @@ void XDrawPosition(w, repaint, board)
           is flashing on its new square */
        for (i = 0; i < BOARD_HEIGHT; i++)
          for (j = 0; j < BOARD_WIDTH; j++)
-           if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)
-               || damage[i][j]) {
+           if ((board[i][j] != lastBoard[nr][i][j] && board[i][j] == EmptySquare)
+               || damage[nr][i][j]) {
                DrawSquare(i, j, board[i][j], 0);
-               damage[i][j] = False;
+               damage[nr][i][j] = False;
            }
 
        /* Second pass -- Draw piece(s) in new position and flash them */
        for (i = 0; i < BOARD_HEIGHT; i++)
          for (j = 0; j < BOARD_WIDTH; j++)
-           if (board[i][j] != lastBoard[i][j]) {
+           if (board[i][j] != lastBoard[nr][i][j]) {
                DrawSquare(i, j, board[i][j], do_flash);
            }
     } else {
@@ -4493,12 +4498,13 @@ void XDrawPosition(w, repaint, board)
        for (i = 0; i < BOARD_HEIGHT; i++)
          for (j = 0; j < BOARD_WIDTH; j++) {
              DrawSquare(i, j, board[i][j], 0);
-             damage[i][j] = False;
+             damage[nr][i][j] = False;
          }
     }
 
-    CopyBoard(lastBoard, board);
-    lastBoardValid = 1;
+    CopyBoard(lastBoard[nr], board);
+    lastBoardValid[nr] = 1;
+  if(nr == 0) { // [HGM] dual: no highlights on second board yet
     lastFlipView = flipView;
 
     /* Draw highlights */
@@ -4514,7 +4520,7 @@ void XDrawPosition(w, repaint, board)
     if (hi2X >= 0 && hi2Y >= 0) {
       drawHighlight(hi2X, hi2Y, highlineGC);
     }
-
+  }
     /* If piece being dragged around board, must redraw that too */
     DrawDragPiece();
 
@@ -8731,7 +8737,7 @@ AnimateMove(board, fromX, fromY, toX, toY)
   FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames);
 
   /* Be sure end square is redrawn */
-  damage[toY][toX] = True;
+  damage[0][toY][toX] = True;
 }
 
 void
@@ -8771,7 +8777,7 @@ DragPieceBegin(x, y)
            XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC,
                     corner.x, corner.y, squareSize, squareSize,
                     0, 0); // [HGM] zh: unstack in stead of grab
-       damage[boardY][boardX] = True;
+       damage[0][boardY][boardX] = True;
     } else {
        player.dragActive = False;
     }
@@ -8825,7 +8831,7 @@ DragPieceEnd(x, y)
     EndAnimation(&player, &corner);
 
     /* Be sure end square is redrawn */
-    damage[boardY][boardX] = True;
+    damage[0][boardY][boardX] = True;
 
     /* This prevents weird things happening with fast successive
        clicks which on my Sun at least can cause motion events
@@ -8848,7 +8854,7 @@ DrawDragPiece ()
   BlankSquare(player.startSquare.x, player.startSquare.y,
                player.startColor, EmptySquare, xBoardWindow);
   AnimationFrame(&player, &player.prevFrame, player.dragPiece);
-  damage[player.startBoardY][player.startBoardX] = TRUE;
+  damage[0][player.startBoardY][player.startBoardX] = TRUE;
 }
 
 #include <sys/ioctl.h>