changed font in engine output window
[xboard.git] / winboard / winboard.c
index fb317b7..813445b 100644 (file)
@@ -103,7 +103,7 @@ void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber);
 VOID NewVariantPopup(HWND hwnd);\r
 int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY,\r
                   /*char*/int promoChar));\r
-void AnimateAtomicCapture(int toX, int toY, int nFrames);\r
+void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames);\r
 \r
 typedef struct {\r
   ChessSquare piece;  \r
@@ -132,10 +132,10 @@ static HighlightInfo highlightInfo        = { {{-1, -1}, {-1, -1}} };
 static HighlightInfo premoveHighlightInfo = { {{-1, -1}, {-1, -1}} };\r
 \r
 typedef struct { // [HGM] atomic\r
-  int x, y, radius;\r
+  int fromX, fromY, toX, toY, radius;\r
 } ExplodeInfo;\r
 \r
-static ExplodeInfo explodeInfo = {0, 0, 0};\r
+static ExplodeInfo explodeInfo;\r
 \r
 /* Window class names */\r
 char szAppName[] = "WinBoard";\r
@@ -152,9 +152,10 @@ char installDir[MSG_SIZ];
 \r
 BoardSize boardSize;\r
 BOOLEAN chessProgram;\r
-static int boardX, boardY, consoleX, consoleY, consoleW, consoleH;\r
+static int boardX, boardY;\r
+int  minX, minY; // [HGM] placement: volatile limits on upper-left corner\r
 static int squareSize, lineGap, minorSize;\r
-static int winWidth, winHeight;\r
+static int winWidth, winHeight, winW, winH;\r
 static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo\r
 static int logoHeight = 0;\r
 static char messageText[MESSAGE_TEXT_MAX];\r
@@ -201,6 +202,7 @@ static HICON iconWhite, iconBlack, iconCurrent;
 static int doingSizing = FALSE;\r
 static int lastSizing = 0;\r
 static int prevStderrPort;\r
+static HBITMAP userLogo;\r
 \r
 /* [AS] Support for background textures */\r
 #define BACK_TEXTURE_MODE_DISABLED      0\r
@@ -426,6 +428,8 @@ HWND engineOutputDialog = NULL;
 BOOLEAN engineOutputDialogUp = FALSE;\r
 \r
 WindowPlacement wpEngineOutput;\r
+WindowPlacement wpGameList;\r
+WindowPlacement wpConsole;\r
 \r
 VOID MoveHistoryPopUp();\r
 VOID MoveHistoryPopDown();\r
@@ -543,6 +547,21 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  *\r
 \*---------------------------------------------------------------------------*/\r
 \r
+void\r
+SetUserLogo()\r
+{   // update user logo if necessary\r
+    static char oldUserName[MSG_SIZ], *curName;\r
+\r
+    if(appData.autoLogo) {\r
+         curName = UserName();\r
+         if(strcmp(curName, oldUserName)) {\r
+               sprintf(oldUserName, "logos\\%s.bmp", curName);\r
+               userLogo = LoadImage( 0, oldUserName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );    \r
+               strcpy(oldUserName, curName);\r
+         }\r
+    }\r
+}\r
+\r
 BOOL\r
 InitApplication(HINSTANCE hInstance)\r
 {\r
@@ -585,16 +604,14 @@ InitApplication(HINSTANCE hInstance)
 int screenHeight, screenWidth;\r
 \r
 void\r
-EnsureOnScreen(int *x, int *y)\r
+EnsureOnScreen(int *x, int *y, int minX, int minY)\r
 {\r
 //  int gap = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION);\r
   /* Be sure window at (x,y) is not off screen (or even mostly off screen) */\r
   if (*x > screenWidth - 32) *x = 0;\r
   if (*y > screenHeight - 32) *y = 0;\r
-  if (*x < 0) *x = 0;\r
-  if (*y < 0) *y = 0;\r
-//  if (*x < 10) *x = 10;\r
-//  if (*y < gap) *y = gap;\r
+  if (*x < minX) *x = minX;\r
+  if (*y < minY) *y = minY;\r
 }\r
 \r
 BOOL\r
@@ -613,6 +630,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
     GetCurrentDirectory(MSG_SIZ, installDir);\r
   }\r
   gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] won't have open window otherwise\r
+  screenWidth = screenHeight = 1000; // [HGM] placement: kludge to allow calling EnsureOnScreen from InitAppData\r
   InitAppData(lpCmdLine);      /* Get run-time parameters */\r
   if (appData.debugMode) {\r
     debugFP = fopen(appData.nameOfDebugFile, "w");\r
@@ -658,13 +676,19 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
           fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.secondLogo );\r
       }\r
   } else if(appData.autoLogo) {\r
+      char buf[MSG_SIZ];\r
+      if(appData.icsActive) { // [HGM] logo: in ICS mode second can be used for ICS\r
+       sprintf(buf, "logos\\%s.bmp", appData.icsHost);\r
+       second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+      } else\r
       if(appData.secondDirectory && appData.secondDirectory[0]) {\r
-       char buf[MSG_SIZ];\r
        sprintf(buf, "%s\\logo.bmp", appData.secondDirectory);\r
        second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );  \r
       }\r
   }\r
 \r
+  SetUserLogo();\r
+\r
   iconWhite = LoadIcon(hInstance, "icon_white");\r
   iconBlack = LoadIcon(hInstance, "icon_black");\r
   iconCurrent = iconWhite;\r
@@ -674,11 +698,11 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   for (ibs = (int) NUM_SIZES - 1; ibs >= 0; ibs--) {\r
     /* Compute window size for each board size, and use the largest\r
        size that fits on this screen as the default. */\r
-    InitDrawingSizes((BoardSize)ibs, 0);\r
+    InitDrawingSizes((BoardSize)(ibs+1000), 0);\r
     if (boardSize == (BoardSize)-1 &&\r
-        winHeight <= screenHeight\r
+        winH <= screenHeight\r
            - GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYCAPTION) - 10\r
-        && winWidth <= screenWidth) {\r
+        && winW <= screenWidth) {\r
       boardSize = (BoardSize)ibs;\r
     }\r
   }\r
@@ -726,7 +750,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   InitBackEnd2();\r
 \r
   /* Make the window visible; update its client area; and return "success" */\r
-  EnsureOnScreen(&boardX, &boardY);\r
+  EnsureOnScreen(&boardX, &boardY, minX, minY);\r
   wp.length = sizeof(WINDOWPLACEMENT);\r
   wp.flags = 0;\r
   wp.showCmd = nCmdShow;\r
@@ -740,12 +764,6 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
                0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
 \r
-#if 0\r
-  /* [AS] Disable the FRC stuff if not playing the proper variant */\r
-  if( gameInfo.variant != VariantFischeRandom ) {\r
-      EnableMenuItem( GetMenu(hwndMain), IDM_NewGameFRC, MF_GRAYED );\r
-  }\r
-#endif\r
   if (hwndConsole) {\r
 #if AOT_CONSOLE\r
     SetWindowPos(hwndConsole, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
@@ -763,7 +781,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
 typedef enum {\r
   ArgString, ArgInt, ArgFloat, ArgBoolean, ArgTrue, ArgFalse, ArgNone, \r
   ArgColor, ArgAttribs, ArgFilename, ArgBoardSize, ArgFont, ArgCommSettings,\r
-  ArgSettingsFilename\r
+  ArgSettingsFilename,\r
+  ArgX, ArgY, ArgZ // [HGM] placement: for window-placement options stored relative to main window\r
 } ArgType;\r
 \r
 typedef struct {\r
@@ -1099,28 +1118,6 @@ ArgDescriptor argDescriptors[] = {
   { "xreuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE },\r
   { "-reuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE },\r
   { "comPortSettings", ArgCommSettings, (LPVOID) &dcb, TRUE },\r
-  { "x", ArgInt, (LPVOID) &boardX, TRUE },\r
-  { "y", ArgInt, (LPVOID) &boardY, TRUE },\r
-  { "icsX", ArgInt, (LPVOID) &consoleX, TRUE },\r
-  { "icsY", ArgInt, (LPVOID) &consoleY, TRUE },\r
-  { "icsW", ArgInt, (LPVOID) &consoleW, TRUE },\r
-  { "icsH", ArgInt, (LPVOID) &consoleH, TRUE },\r
-  { "analysisX", ArgInt, (LPVOID) &analysisX, TRUE },\r
-  { "analysisY", ArgInt, (LPVOID) &analysisY, TRUE },\r
-  { "analysisW", ArgInt, (LPVOID) &analysisW, TRUE },\r
-  { "analysisH", ArgInt, (LPVOID) &analysisH, TRUE },\r
-  { "commentX", ArgInt, (LPVOID) &commentX, TRUE },\r
-  { "commentY", ArgInt, (LPVOID) &commentY, TRUE },\r
-  { "commentW", ArgInt, (LPVOID) &commentW, TRUE },\r
-  { "commentH", ArgInt, (LPVOID) &commentH, TRUE },\r
-  { "tagsX", ArgInt, (LPVOID) &editTagsX, TRUE },\r
-  { "tagsY", ArgInt, (LPVOID) &editTagsY, TRUE },\r
-  { "tagsW", ArgInt, (LPVOID) &editTagsW, TRUE },\r
-  { "tagsH", ArgInt, (LPVOID) &editTagsH, TRUE },\r
-  { "gameListX", ArgInt, (LPVOID) &gameListX, TRUE },\r
-  { "gameListY", ArgInt, (LPVOID) &gameListY, TRUE },\r
-  { "gameListW", ArgInt, (LPVOID) &gameListW, TRUE },\r
-  { "gameListH", ArgInt, (LPVOID) &gameListH, TRUE },\r
   { "settingsFile", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE },\r
   { "ini", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE },\r
   { "saveSettingsOnExit", ArgBoolean, (LPVOID) &saveSettingsOnExit, TRUE },\r
@@ -1195,25 +1192,6 @@ ArgDescriptor argDescriptors[] = {
   { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE },\r
   { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE },\r
 \r
-  /* [AS] Layout stuff */\r
-  { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE },\r
-  { "moveHistoryX", ArgInt, (LPVOID) &wpMoveHistory.x, TRUE },\r
-  { "moveHistoryY", ArgInt, (LPVOID) &wpMoveHistory.y, TRUE },\r
-  { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE },\r
-  { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE },\r
-\r
-  { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE },\r
-  { "evalGraphX", ArgInt, (LPVOID) &wpEvalGraph.x, TRUE },\r
-  { "evalGraphY", ArgInt, (LPVOID) &wpEvalGraph.y, TRUE },\r
-  { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE },\r
-  { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE },\r
-\r
-  { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE },\r
-  { "engineOutputX", ArgInt, (LPVOID) &wpEngineOutput.x, TRUE },\r
-  { "engineOutputY", ArgInt, (LPVOID) &wpEngineOutput.y, TRUE },\r
-  { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE },\r
-  { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE },\r
-\r
   /* [HGM] board-size, adjudication and misc. options */\r
   { "boardWidth", ArgInt, (LPVOID) &appData.NrFiles, TRUE },\r
   { "boardHeight", ArgInt, (LPVOID) &appData.NrRanks, TRUE },\r
@@ -1286,6 +1264,7 @@ ArgDescriptor argDescriptors[] = {
   { "zippyVariants", ArgString, (LPVOID) &appData.zippyVariants, FALSE },\r
   { "zippyMaxGames", ArgInt, (LPVOID)&appData.zippyMaxGames, FALSE },\r
   { "zippyReplayTimeout", ArgInt, (LPVOID)&appData.zippyReplayTimeout, FALSE },\r
+  { "zippyShortGame", ArgInt, (LPVOID)&appData.zippyShortGame, FALSE },\r
   /* Kludge to allow winboard.ini files from buggy 4.0.4 to be read: */\r
   { "zippyReplyTimeout", ArgInt, (LPVOID)&junk, FALSE },\r
 #endif\r
@@ -1301,6 +1280,53 @@ ArgDescriptor argDescriptors[] = {
   { "firstNPS", ArgInt, (LPVOID) &appData.firstNPS, FALSE },\r
   { "secondNPS", ArgInt, (LPVOID) &appData.secondNPS, FALSE },\r
   { "noGUI", ArgTrue, (LPVOID) &appData.noGUI, FALSE },\r
+\r
+  // [HGM] placement: put all window layouts last in ini file, but man X,Y before all others\r
+  { "minX", ArgZ, (LPVOID) &minX, FALSE }, // [HGM] placement: to make suer auxialary windows can be placed\r
+  { "minY", ArgZ, (LPVOID) &minY, FALSE },\r
+  { "winWidth",  ArgInt, (LPVOID) &winWidth,  TRUE }, // [HGM] placement: dummies to remember right & bottom\r
+  { "winHeight", ArgInt, (LPVOID) &winHeight, TRUE }, //       for attaching auxiliary windows to them\r
+  { "x", ArgInt, (LPVOID) &boardX, TRUE },\r
+  { "y", ArgInt, (LPVOID) &boardY, TRUE },\r
+  { "icsX", ArgX,   (LPVOID) &wpConsole.x, TRUE },\r
+  { "icsY", ArgY,   (LPVOID) &wpConsole.y, TRUE },\r
+  { "icsW", ArgInt, (LPVOID) &wpConsole.width, TRUE },\r
+  { "icsH", ArgInt, (LPVOID) &wpConsole.height, TRUE },\r
+  { "analysisX", ArgX,   (LPVOID) &analysisX, FALSE }, // [HGM] placement: analysis window no longer exists\r
+  { "analysisY", ArgY,   (LPVOID) &analysisY, FALSE }, //       provided for compatibility with old ini files\r
+  { "analysisW", ArgInt, (LPVOID) &analysisW, FALSE },\r
+  { "analysisH", ArgInt, (LPVOID) &analysisH, FALSE },\r
+  { "commentX", ArgX,   (LPVOID) &commentX, TRUE },\r
+  { "commentY", ArgY,   (LPVOID) &commentY, TRUE },\r
+  { "commentW", ArgInt, (LPVOID) &commentW, TRUE },\r
+  { "commentH", ArgInt, (LPVOID) &commentH, TRUE },\r
+  { "tagsX", ArgX,   (LPVOID) &editTagsX, TRUE },\r
+  { "tagsY", ArgY,   (LPVOID) &editTagsY, TRUE },\r
+  { "tagsW", ArgInt, (LPVOID) &editTagsW, TRUE },\r
+  { "tagsH", ArgInt, (LPVOID) &editTagsH, TRUE },\r
+  { "gameListX", ArgX,   (LPVOID) &wpGameList.x, TRUE },\r
+  { "gameListY", ArgY,   (LPVOID) &wpGameList.y, TRUE },\r
+  { "gameListW", ArgInt, (LPVOID) &wpGameList.width, TRUE },\r
+  { "gameListH", ArgInt, (LPVOID) &wpGameList.height, TRUE },\r
+  /* [AS] Layout stuff */\r
+  { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE },\r
+  { "moveHistoryX", ArgX,   (LPVOID) &wpMoveHistory.x, TRUE },\r
+  { "moveHistoryY", ArgY,   (LPVOID) &wpMoveHistory.y, TRUE },\r
+  { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE },\r
+  { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE },\r
+\r
+  { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE },\r
+  { "evalGraphX", ArgX,   (LPVOID) &wpEvalGraph.x, TRUE },\r
+  { "evalGraphY", ArgY,   (LPVOID) &wpEvalGraph.y, TRUE },\r
+  { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE },\r
+  { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE },\r
+\r
+  { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE },\r
+  { "engineOutputX", ArgX,   (LPVOID) &wpEngineOutput.x, TRUE },\r
+  { "engineOutputY", ArgY,   (LPVOID) &wpEngineOutput.y, TRUE },\r
+  { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE },\r
+  { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE },\r
+\r
   { NULL, ArgNone, NULL, FALSE }\r
 };\r
 \r
@@ -1631,6 +1657,19 @@ ParseArgs(GetFunc get, void *cl)
       *(int *) ad->argLoc = atoi(argValue);\r
       break;\r
 \r
+    case ArgX:\r
+      *(int *) ad->argLoc = atoi(argValue) + boardX; // [HGM] placement: translate stored relative to absolute \r
+      break;\r
+\r
+    case ArgY:\r
+      *(int *) ad->argLoc = atoi(argValue) + boardY; // (this is really kludgey, it should be done where used...)\r
+      break;\r
+\r
+    case ArgZ:\r
+      *(int *) ad->argLoc = atoi(argValue);\r
+      EnsureOnScreen(&boardX, &boardY, minX, minY); \r
+      break;\r
+\r
     case ArgFloat:\r
       *(float *) ad->argLoc = (float) atof(argValue);\r
       break;\r
@@ -1894,10 +1933,6 @@ InitAppData(LPSTR lpCmdLine)
   saveSettingsOnExit = TRUE;\r
   boardX = CW_USEDEFAULT;\r
   boardY = CW_USEDEFAULT;\r
-  consoleX = CW_USEDEFAULT; \r
-  consoleY = CW_USEDEFAULT; \r
-  consoleW = CW_USEDEFAULT;\r
-  consoleH = CW_USEDEFAULT;\r
   analysisX = CW_USEDEFAULT; \r
   analysisY = CW_USEDEFAULT; \r
   analysisW = CW_USEDEFAULT;\r
@@ -1910,10 +1945,6 @@ InitAppData(LPSTR lpCmdLine)
   editTagsY = CW_USEDEFAULT; \r
   editTagsW = CW_USEDEFAULT;\r
   editTagsH = CW_USEDEFAULT;\r
-  gameListX = CW_USEDEFAULT; \r
-  gameListY = CW_USEDEFAULT; \r
-  gameListW = CW_USEDEFAULT;\r
-  gameListH = CW_USEDEFAULT;\r
   icsTextMenuString = ICS_TEXT_MENU_DEFAULT;\r
   icsNames = ICS_NAMES;\r
   firstChessProgramNames = FCP_NAMES;\r
@@ -1971,9 +2002,11 @@ InitAppData(LPSTR lpCmdLine)
   appData.firstOptions = "";\r
   appData.secondOptions = "";\r
 \r
+  InitWindowPlacement( &wpGameList );\r
   InitWindowPlacement( &wpMoveHistory );\r
   InitWindowPlacement( &wpEvalGraph );\r
   InitWindowPlacement( &wpEngineOutput );\r
+  InitWindowPlacement( &wpConsole );\r
 \r
   /* [HGM] User-selectable board size, adjudication control, miscellaneous */\r
   appData.NrFiles      = -1;\r
@@ -2186,10 +2219,10 @@ SaveSettings(char* name)
 \r
   if (hwndConsole) {\r
     GetWindowPlacement(hwndConsole, &wp);\r
-    consoleX = wp.rcNormalPosition.left;\r
-    consoleY = wp.rcNormalPosition.top;\r
-    consoleW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    consoleH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+    wpConsole.x = wp.rcNormalPosition.left;\r
+    wpConsole.y = wp.rcNormalPosition.top;\r
+    wpConsole.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+    wpConsole.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
   }\r
 \r
   if (analysisDialog) {\r
@@ -2218,10 +2251,10 @@ SaveSettings(char* name)
 \r
   if (gameListDialog) {\r
     GetWindowPlacement(gameListDialog, &wp);\r
-    gameListX = wp.rcNormalPosition.left;\r
-    gameListY = wp.rcNormalPosition.top;\r
-    gameListW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    gameListH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+    wpGameList.x = wp.rcNormalPosition.left;\r
+    wpGameList.y = wp.rcNormalPosition.top;\r
+    wpGameList.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+    wpGameList.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
   }\r
 \r
   /* [AS] Move history */\r
@@ -2287,8 +2320,15 @@ SaveSettings(char* name)
       }\r
       break;\r
     case ArgInt:\r
+    case ArgZ:\r
       fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc);\r
       break;\r
+    case ArgX:\r
+      fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardX); // [HGM] placement: stor relative value\r
+      break;\r
+    case ArgY:\r
+      fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardY);\r
+      break;\r
     case ArgFloat:\r
       fprintf(f, "/%s=%g\n", ad->argName, *(float *)ad->argLoc);\r
       break;\r
@@ -3077,7 +3117,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   char buf[MSG_SIZ];\r
   char *str;\r
   HMENU hmenu = GetMenu(hwndMain);\r
-  RECT crect, wrect;\r
+  RECT crect, wrect, oldRect;\r
   int offby;\r
   LOGBRUSH logbrush;\r
 \r
@@ -3087,6 +3127,11 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   /* [HGM] call with -2 uses old size (for if nr of files, ranks changes) */\r
   if(boardSize == (BoardSize)(-2) ) boardSize = oldBoardSize;\r
 \r
+  oldRect.left = boardX; //[HGM] placement: remember previous window params\r
+  oldRect.top = boardY;\r
+  oldRect.right = boardX + winWidth;\r
+  oldRect.bottom = boardY + winHeight;\r
+\r
   tinyLayout = sizeInfo[boardSize].tinyLayout;\r
   smallLayout = sizeInfo[boardSize].smallLayout;\r
   squareSize = sizeInfo[boardSize].squareSize;\r
@@ -3135,7 +3180,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   ReleaseDC(hwndMain, hdc);\r
 \r
   /* Compute where everything goes */\r
-  if(first.programLogo || second.programLogo) {\r
+  if((first.programLogo || second.programLogo) && !tinyLayout) {\r
         /* [HGM] logo: if either logo is on, reserve space for it */\r
        logoHeight =  2*clockSize.cy;\r
        leftLogoRect.left   = OUTER_MARGIN;\r
@@ -3149,19 +3194,19 @@ InitDrawingSizes(BoardSize boardSize, int flags)
        rightLogoRect.bottom = OUTER_MARGIN + logoHeight;\r
 \r
 \r
-    blackRect.left = leftLogoRect.right;\r
-    blackRect.right = rightLogoRect.left;\r
-    blackRect.top = OUTER_MARGIN;\r
-    blackRect.bottom = blackRect.top + clockSize.cy;\r
+    whiteRect.left = leftLogoRect.right;\r
+    whiteRect.right = OUTER_MARGIN + boardWidth/2 - INNER_MARGIN/2;\r
+    whiteRect.top = OUTER_MARGIN;\r
+    whiteRect.bottom = whiteRect.top + logoHeight;\r
 \r
-    whiteRect.left = blackRect.left ;\r
-    whiteRect.right = blackRect.right;\r
-    whiteRect.top = blackRect.bottom;\r
-    whiteRect.bottom = leftLogoRect.bottom;\r
+    blackRect.right = rightLogoRect.left;\r
+    blackRect.left = whiteRect.right + INNER_MARGIN;\r
+    blackRect.top = whiteRect.top;\r
+    blackRect.bottom = whiteRect.bottom;\r
   } else {\r
     whiteRect.left = OUTER_MARGIN;\r
     whiteRect.right = whiteRect.left + boardWidth/2 - INNER_MARGIN/2;\r
-    whiteRect.top = OUTER_MARGIN + logoHeight;\r
+    whiteRect.top = OUTER_MARGIN;\r
     whiteRect.bottom = whiteRect.top + clockSize.cy;\r
 \r
     blackRect.left = whiteRect.right + INNER_MARGIN;\r
@@ -3187,13 +3232,25 @@ InitDrawingSizes(BoardSize boardSize, int flags)
 \r
   sizeInfo[boardSize].cliWidth = boardRect.right + OUTER_MARGIN;\r
   sizeInfo[boardSize].cliHeight = boardRect.bottom + OUTER_MARGIN;\r
-  if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only\r
-  winWidth = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN;\r
-  winHeight = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) +\r
+  oldBoardSize = boardSize;\r
+  oldTinyLayout = tinyLayout;\r
+  winW = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN;\r
+  winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) +\r
     GetSystemMetrics(SM_CYCAPTION) + boardRect.bottom + OUTER_MARGIN;\r
+  if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only\r
+  winWidth = winW;  // [HGM] placement: set through temporary which can used by initial sizing choice\r
+  winHeight = winH; //       without disturbing window attachments\r
   GetWindowRect(hwndMain, &wrect);\r
   SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight,\r
               SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE);\r
+\r
+  // [HGM] placement: let attached windows follow size change.\r
+  ReattachAfterSize( &oldRect, winWidth, winHeight, moveHistoryDialog, &wpMoveHistory );\r
+  ReattachAfterSize( &oldRect, winWidth, winHeight, evalGraphDialog, &wpEvalGraph );\r
+  ReattachAfterSize( &oldRect, winWidth, winHeight, engineOutputDialog, &wpEngineOutput );\r
+  ReattachAfterSize( &oldRect, winWidth, winHeight, gameListDialog, &wpGameList );\r
+  ReattachAfterSize( &oldRect, winWidth, winHeight, hwndConsole, &wpConsole );\r
+\r
   /* compensate if menu bar wrapped */\r
   GetClientRect(hwndMain, &crect);\r
   offby = boardRect.bottom + OUTER_MARGIN - crect.bottom;\r
@@ -3303,8 +3360,6 @@ InitDrawingSizes(BoardSize boardSize, int flags)
 \r
 \r
 /*  if (boardSize == oldBoardSize) return; [HGM] variant might have changed */\r
-  oldBoardSize = boardSize;\r
-  oldTinyLayout = tinyLayout;\r
 \r
   /* Load piece bitmaps for this board size */\r
   for (i=0; i<=2; i++) {\r
@@ -4233,7 +4288,7 @@ void fputDW(FILE *f, int x)
 #define MAX_CLIPS 200   /* more than enough */\r
 \r
 VOID\r
-DrawLogoOnDC(HDC hdc, RECT logoRect, ChessProgramState *cps)\r
+DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo)\r
 {\r
 //  HBITMAP bufferBitmap;\r
   BITMAP bi;\r
@@ -4242,13 +4297,13 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, ChessProgramState *cps)
   HBITMAP hbm;\r
   int w = 100, h = 50;\r
 \r
-  if(cps->programLogo == NULL) return;\r
+  if(logo == NULL) return;\r
 //  GetClientRect(hwndMain, &Rect);\r
 //  bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1,\r
 //                                     Rect.bottom-Rect.top+1);\r
   tmphdc = CreateCompatibleDC(hdc);\r
-  hbm = SelectObject(tmphdc, (HBITMAP) cps->programLogo);\r
-  if( GetObject( cps->programLogo, sizeof(bi), &bi ) > 0 ) {\r
+  hbm = SelectObject(tmphdc, logo);\r
+  if( GetObject( logo, sizeof(bi), &bi ) > 0 ) {\r
             w = bi.bmWidth;\r
             h = bi.bmHeight;\r
   }\r
@@ -4511,7 +4566,8 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   if(explodeInfo.radius) { // [HGM] atomic\r
        HBRUSH oldBrush;\r
        int x, y, r=(explodeInfo.radius * squareSize)/100;\r
-       SquareToPos(explodeInfo.y, explodeInfo.x, &x, &y);\r
+        board[explodeInfo.fromY][explodeInfo.fromX] = EmptySquare; // suppress display of capturer\r
+       SquareToPos(explodeInfo.toY, explodeInfo.toX, &x, &y);\r
        x += squareSize/2;\r
        y += squareSize/2;\r
         if(!fullrepaint) {\r
@@ -4530,8 +4586,39 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
     DrawBoardOnDC(hdcmem, board, tmphdc);\r
   }\r
   if(logoHeight) {\r
-       DrawLogoOnDC(hdc, leftLogoRect, flipClock ? &second : &first);\r
-       DrawLogoOnDC(hdc, rightLogoRect, flipClock ? &first : &second);\r
+       HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo;\r
+       if(appData.autoLogo) {\r
+         \r
+         switch(gameMode) { // pick logos based on game mode\r
+           case IcsObserving:\r
+               whiteLogo = second.programLogo; // ICS logo\r
+               blackLogo = second.programLogo;\r
+           default:\r
+               break;\r
+           case IcsPlayingWhite:\r
+               if(!appData.zippyPlay) whiteLogo = userLogo;\r
+               blackLogo = second.programLogo; // ICS logo\r
+               break;\r
+           case IcsPlayingBlack:\r
+               whiteLogo = second.programLogo; // ICS logo\r
+               blackLogo = appData.zippyPlay ? first.programLogo : userLogo;\r
+               break;\r
+           case TwoMachinesPlay:\r
+               if(first.twoMachinesColor[0] == 'b') {\r
+                   whiteLogo = second.programLogo;\r
+                   blackLogo = first.programLogo;\r
+               }\r
+               break;\r
+           case MachinePlaysWhite:\r
+               blackLogo = userLogo;\r
+               break;\r
+           case MachinePlaysBlack:\r
+               whiteLogo = userLogo;\r
+               blackLogo = first.programLogo;\r
+         }\r
+       }\r
+       DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo);\r
+       DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo);\r
   }\r
 \r
   if( appData.highlightMoveWithArrow ) {\r
@@ -4875,7 +4962,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                   gameMode == MachinePlaysWhite) {\r
          CallFlagEvent();\r
         } else if (gameMode == EditGame) {\r
-          AdjustClock((logoHeight > 0 ? flipView: flipClock), -1);\r
+          AdjustClock(flipClock, -1);\r
         }\r
       } else if (PtInRect((LPRECT) &blackRect, pt)) {\r
        if (gameMode == EditPosition) {\r
@@ -4884,7 +4971,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                   gameMode == MachinePlaysBlack) {\r
          CallFlagEvent();\r
         } else if (gameMode == EditGame) {\r
-          AdjustClock(!(logoHeight > 0 ? flipView: flipClock), -1);\r
+          AdjustClock(!flipClock, -1);\r
        }\r
       }\r
       if (!appData.highlightLastMove) {\r
@@ -5055,7 +5142,10 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                PromotionPopup(hwnd); /* [HGM] Popup now calls FinishMove */\r
           } else {\r
            if(saveAnimate /* ^$!%@#$!$ */  && gameInfo.variant == VariantAtomic \r
-                       && boards[currentMove][toY][toX] != EmptySquare) AnimateAtomicCapture(toX, toY, 20);\r
+                         && (boards[currentMove][toY][toX] != EmptySquare || \r
+                                       moveType == WhiteCapturesEnPassant || \r
+                                       moveType == BlackCapturesEnPassant   ) )\r
+               AnimateAtomicCapture(fromX, fromY, toX, toY, 20);\r
            FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);\r
          }\r
       }\r
@@ -5128,9 +5218,9 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     if(y == -2) {\r
       /* [HGM] right mouse button in clock area edit-game mode ups clock */\r
       if (PtInRect((LPRECT) &whiteRect, pt)) {\r
-          if (gameMode == EditGame) AdjustClock((logoHeight > 0 ? flipView: flipClock), 1);\r
+          if (gameMode == EditGame) AdjustClock(flipClock, 1);\r
       } else if (PtInRect((LPRECT) &blackRect, pt)) {\r
-          if (gameMode == EditGame) AdjustClock(!(logoHeight > 0 ? flipView: flipClock), 1);\r
+          if (gameMode == EditGame) AdjustClock(!flipClock, 1);\r
       }\r
     }\r
     DrawPosition(TRUE, NULL);\r
@@ -5936,6 +6026,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case IDM_FlipClock:\r
       flipClock = !flipClock;\r
       DisplayBothClocks();\r
+      DrawPosition(FALSE, NULL);\r
       break;\r
 \r
     case IDM_GeneralOptions:\r
@@ -6294,6 +6385,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, moveHistoryDialog, &wpMoveHistory );\r
             ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, evalGraphDialog, &wpEvalGraph );\r
             ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, engineOutputDialog, &wpEngineOutput );\r
+            ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, gameListDialog, &wpGameList );\r
+            ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, hwndConsole, &wpConsole );\r
            boardX = lpwp->x;\r
             boardY = lpwp->y;\r
         }\r
@@ -7064,7 +7157,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       if (commentX != CW_USEDEFAULT && commentY != CW_USEDEFAULT &&\r
          commentW != CW_USEDEFAULT && commentH != CW_USEDEFAULT) {\r
        WINDOWPLACEMENT wp;\r
-       EnsureOnScreen(&commentX, &commentY);\r
+       EnsureOnScreen(&commentX, &commentY, 0, 0);\r
        wp.length = sizeof(WINDOWPLACEMENT);\r
        wp.flags = 0;\r
        wp.showCmd = SW_SHOW;\r
@@ -7284,6 +7377,7 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     case IDOK:\r
       GetDlgItemText(hDlg, OPT_Name, move, sizeof(move));\r
       appData.userName = strdup(move);\r
+      SetUserLogo();\r
 \r
       EndDialog(hDlg, TRUE);\r
       return TRUE;\r
@@ -8007,40 +8101,37 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     GetClientRect(hDlg, &rect);\r
     sizeX = rect.right;\r
     sizeY = rect.bottom;\r
-    if (consoleX != CW_USEDEFAULT && consoleY != CW_USEDEFAULT &&\r
-       consoleW != CW_USEDEFAULT && consoleH != CW_USEDEFAULT) {\r
+    if (wpConsole.x != CW_USEDEFAULT && wpConsole.y != CW_USEDEFAULT &&\r
+       wpConsole.width != CW_USEDEFAULT && wpConsole.height != CW_USEDEFAULT) {\r
       WINDOWPLACEMENT wp;\r
-      EnsureOnScreen(&consoleX, &consoleY);\r
+      EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0);\r
       wp.length = sizeof(WINDOWPLACEMENT);\r
       wp.flags = 0;\r
       wp.showCmd = SW_SHOW;\r
       wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
-      wp.rcNormalPosition.left = consoleX;\r
-      wp.rcNormalPosition.right = consoleX + consoleW;\r
-      wp.rcNormalPosition.top = consoleY;\r
-      wp.rcNormalPosition.bottom = consoleY + consoleH;\r
+      wp.rcNormalPosition.left = wpConsole.x;\r
+      wp.rcNormalPosition.right = wpConsole.x + wpConsole.width;\r
+      wp.rcNormalPosition.top = wpConsole.y;\r
+      wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height;\r
       SetWindowPlacement(hDlg, &wp);\r
     }\r
-#if 0 \r
-   // [HGM] Chessknight's change 2004-07-13\r
    else { /* Determine Defaults */\r
        WINDOWPLACEMENT wp;\r
-       consoleX = winWidth + 1;\r
-       consoleY = boardY;\r
-       consoleW = screenWidth -  winWidth;\r
-       consoleH = winHeight;\r
-       EnsureOnScreen(&consoleX, &consoleY);\r
+       wpConsole.x = winWidth + 1;\r
+       wpConsole.y = boardY;\r
+       wpConsole.width = screenWidth -  winWidth;\r
+       wpConsole.height = winHeight;\r
+       EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0);\r
        wp.length = sizeof(WINDOWPLACEMENT);\r
        wp.flags = 0;\r
        wp.showCmd = SW_SHOW;\r
        wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
-       wp.rcNormalPosition.left = consoleX;\r
-       wp.rcNormalPosition.right = consoleX + consoleW;\r
-       wp.rcNormalPosition.top = consoleY;\r
-       wp.rcNormalPosition.bottom = consoleY + consoleH;\r
+       wp.rcNormalPosition.left = wpConsole.x;\r
+       wp.rcNormalPosition.right = wpConsole.x + wpConsole.width;\r
+       wp.rcNormalPosition.top = wpConsole.y;\r
+       wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height;\r
        SetWindowPlacement(hDlg, &wp);\r
     }\r
-#endif\r
     return FALSE;\r
 \r
   case WM_SETFOCUS:\r
@@ -8253,7 +8344,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight,
     if (tinyLayout)\r
       sprintf(buf, "%c %s %s", color[0], TimeString(timeRemaining), flagFell);\r
     else\r
-      sprintf(buf, "%s: %s %s", color, TimeString(timeRemaining), flagFell);\r
+      sprintf(buf, "%s:%c%s %s", color, (logoHeight>0 ? 0 : ' '), TimeString(timeRemaining), flagFell);\r
     str = buf;\r
   } else {\r
     str = color;\r
@@ -8271,7 +8362,17 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight,
   ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN,\r
             rect->top, ETO_CLIPPED|ETO_OPAQUE,\r
             rect, str, strlen(str), NULL);\r
-\r
+  if(logoHeight > 0 && appData.clockMode) {\r
+      RECT r;\r
+      sprintf(buf, "%s %s", TimeString(timeRemaining), flagFell);\r
+      r.top = rect->top + logoHeight/2;\r
+      r.left = rect->left;\r
+      r.right = rect->right;\r
+      r.bottom = rect->bottom;\r
+      ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN,\r
+                r.top, ETO_CLIPPED|ETO_OPAQUE,\r
+                &r, str, strlen(str), NULL);\r
+  }\r
   (void) SetTextColor(hdc, oldFg);\r
   (void) SetBkColor(hdc, oldBg);\r
   (void) SelectObject(hdc, oldFont);\r
@@ -9527,7 +9628,7 @@ DisplayWhiteClock(long timeRemaining, int highlight)
   hdc = GetDC(hwndMain);\r
   if (!IsIconic(hwndMain)) {\r
     DisplayAClock(hdc, timeRemaining, highlight, \r
-                       (logoHeight > 0 ? flipView: flipClock) ? &blackRect : &whiteRect, "White", flag);\r
+                       flipClock ? &blackRect : &whiteRect, "White", flag);\r
   }\r
   if (highlight && iconCurrent == iconBlack) {\r
     iconCurrent = iconWhite;\r
@@ -9551,7 +9652,7 @@ DisplayBlackClock(long timeRemaining, int highlight)
   hdc = GetDC(hwndMain);\r
   if (!IsIconic(hwndMain)) {\r
     DisplayAClock(hdc, timeRemaining, highlight, \r
-                       (logoHeight > 0 ? flipView: flipClock) ? &whiteRect : &blackRect, "Black", flag);\r
+                       flipClock ? &whiteRect : &blackRect, "Black", flag);\r
   }\r
   if (highlight && iconCurrent == iconWhite) {\r
     iconCurrent = iconBlack;\r
@@ -10438,7 +10539,7 @@ AnalysisDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       if (analysisX != CW_USEDEFAULT && analysisY != CW_USEDEFAULT &&\r
          analysisW != CW_USEDEFAULT && analysisH != CW_USEDEFAULT) {\r
        WINDOWPLACEMENT wp;\r
-       EnsureOnScreen(&analysisX, &analysisY);\r
+       EnsureOnScreen(&analysisX, &analysisY, 0, 0);\r
        wp.length = sizeof(WINDOWPLACEMENT);\r
        wp.flags = 0;\r
        wp.showCmd = SW_SHOW;\r
@@ -10595,13 +10696,15 @@ static void Tween( POINT * start, POINT * mid, POINT * finish, int factor,
 \r
 \r
 void\r
-AnimateAtomicCapture(int toX, int toY, int nFrames)\r
+AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames)\r
 {      // [HGM] atomic: animate blast wave\r
        int i;\r
 if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY);\r
-       explodeInfo.x = toX;\r
-       explodeInfo.y = toY;\r
-       for(i=0; i<nFrames; i++) {\r
+       explodeInfo.fromX = fromX;\r
+       explodeInfo.fromY = fromY;\r
+       explodeInfo.toX = toX;\r
+       explodeInfo.toY = toY;\r
+       for(i=1; i<nFrames; i++) {\r
            explodeInfo.radius = (i*180)/(nFrames-1);\r
            DrawPosition(FALSE, NULL);\r
            Sleep(appData.animSpeed);\r
@@ -10670,8 +10773,9 @@ AnimateMove(board, fromX, fromY, toX, toY)
   animInfo.pos = finish;\r
   DrawPosition(FALSE, NULL);\r
   animInfo.piece = EmptySquare;\r
-  if(gameInfo.variant == VariantAtomic && board[toY][toX] != EmptySquare)\r
-    AnimateAtomicCapture(toX, toY, 2*nFrames);\r
+  if(gameInfo.variant == VariantAtomic && \r
+     (board[toY][toX] != EmptySquare || fromX != toX && (piece == WhitePawn || piece == BlackPawn) ) )\r
+       AnimateAtomicCapture(fromX, fromY, toX, toY, 2*nFrames);\r
 }\r
 \r
 /*      Convert board position to corner of screen rect and color       */\r