Pop up ICS text menu with default item under mouse pointer
[xboard.git] / winboard / winboard.c
index 252e9b0..092574a 100644 (file)
@@ -2,10 +2,10 @@
  * WinBoard.c -- Windows NT front end to XBoard\r
  *\r
  * Copyright 1991 by Digital Equipment Corporation, Maynard,\r
- * Massachusetts.\r
+ * Massachusetts. \r
  *\r
  * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,\r
- * 2007, 2008, 2009 Free Software Foundation, Inc.\r
+ * 2007, 2008, 2009, 2010 Free Software Foundation, Inc.\r
  *\r
  * Enhancements Copyright 2005 Alessandro Scotti\r
  *\r
 #endif\r
 \r
 #include "common.h"\r
-#include "winboard.h"\r
 #include "frontend.h"\r
 #include "backend.h"\r
+#include "winboard.h"\r
 #include "moves.h"\r
 #include "wclipbrd.h"\r
-#include "wgamelist.h"\r
-#include "wedittags.h"\r
 #include "woptions.h"\r
 #include "wsockerr.h"\r
 #include "defaults.h"\r
@@ -106,13 +104,13 @@ extern int ics_type;
 void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber);\r
 VOID NewVariantPopup(HWND hwnd);\r
 int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY,\r
-           /*char*/int promoChar));\r
+                  /*char*/int promoChar));\r
 void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames);\r
 void DisplayMove P((int moveNumber));\r
 Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen));\r
-void ChatPopUp P(());\r
+void ChatPopUp P((char *s));\r
 typedef struct {\r
-  ChessSquare piece;\r
+  ChessSquare piece;  \r
   POINT pos;      /* window coordinates of current pos */\r
   POINT lastpos;  /* window coordinates of last pos - used for clipping */\r
   POINT from;     /* board coordinates of the piece's orig pos */\r
@@ -131,7 +129,7 @@ typedef struct {
 static DragInfo dragInfo = { {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1} };\r
 \r
 typedef struct {\r
-  POINT sq[2];    /* board coordinates of from, to squares */\r
+  POINT sq[2];   /* board coordinates of from, to squares */\r
 } HighlightInfo;\r
 \r
 static HighlightInfo highlightInfo        = { {{-1, -1}, {-1, -1}} };\r
@@ -153,15 +151,16 @@ char szConsoleTitle[] = "I C S Interaction";
 \r
 char *programName;\r
 char *settingsFileName;\r
-BOOLEAN saveSettingsOnExit;\r
+Boolean saveSettingsOnExit;\r
 char installDir[MSG_SIZ];\r
+int errorExitStatus;\r
 \r
 BoardSize boardSize;\r
-BOOLEAN chessProgram;\r
-static int boardX, boardY;\r
+Boolean chessProgram;\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, winW, winH;\r
+int squareSize, lineGap, minorSize;\r
+static int 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
@@ -176,16 +175,12 @@ char *icsNames;
 char *firstChessProgramNames;\r
 char *secondChessProgramNames;\r
 \r
-#define ARG_MAX 128*1024 /* [AS] For Roger Brown's very long list! */\r
-\r
 #define PALETTESIZE 256\r
 \r
 HINSTANCE hInst;          /* current instance */\r
-HWND hwndMain = NULL;        /* root window*/\r
-HWND hwndConsole = NULL;\r
-BOOLEAN alwaysOnTop = FALSE;\r
+Boolean alwaysOnTop = FALSE;\r
 RECT boardRect;\r
-COLORREF lightSquareColor, darkSquareColor, whitePieceColor,\r
+COLORREF lightSquareColor, darkSquareColor, whitePieceColor, \r
   blackPieceColor, highlightSquareColor, premoveHighlightColor;\r
 HPALETTE hPal;\r
 ColorClass currentColorClass;\r
@@ -196,9 +191,10 @@ static HBITMAP pieceBitmap[3][(int) BlackPawn]; /* [HGM] nr of bitmaps referred
 static HBRUSH lightSquareBrush, darkSquareBrush,\r
   blackSquareBrush, /* [HGM] for band between board and holdings */\r
   explodeBrush,     /* [HGM] atomic */\r
+  markerBrush,      /* [HGM] markers */\r
   whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/;\r
-static POINT gridEndpoints[(BOARD_SIZE + 1) * 4];\r
-static DWORD gridVertexCounts[(BOARD_SIZE + 1) * 2];\r
+static POINT gridEndpoints[(BOARD_RANKS + BOARD_FILES + 2) * 2];\r
+static DWORD gridVertexCounts[BOARD_RANKS + BOARD_FILES + 2];\r
 static HPEN gridPen = NULL;\r
 static HPEN highlightPen = NULL;\r
 static HPEN premovePen = NULL;\r
@@ -210,17 +206,12 @@ static int lastSizing = 0;
 static int prevStderrPort;\r
 static HBITMAP userLogo;\r
 \r
-/* [AS] Support for background textures */\r
-#define BACK_TEXTURE_MODE_DISABLED      0\r
-#define BACK_TEXTURE_MODE_PLAIN         1\r
-#define BACK_TEXTURE_MODE_FULL_RANDOM   2\r
-\r
 static HBITMAP liteBackTexture = NULL;\r
 static HBITMAP darkBackTexture = NULL;\r
 static int liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
 static int darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
 static int backTextureSquareSize = 0;\r
-static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOARD_SIZE];\r
+static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_RANKS][BOARD_FILES];\r
 \r
 #if __GNUC__ && !defined(_winmajor)\r
 #define oldDialog 0 /* cygwin doesn't define _winmajor; mingw does */\r
@@ -232,13 +223,6 @@ static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOAR
 #endif\r
 #endif\r
 \r
-char *defaultTextAttribs[] =\r
-{\r
-  COLOR_SHOUT, COLOR_SSHOUT, COLOR_CHANNEL1, COLOR_CHANNEL, COLOR_KIBITZ,\r
-  COLOR_TELL, COLOR_CHALLENGE, COLOR_REQUEST, COLOR_SEEK, COLOR_NORMAL,\r
-  COLOR_NONE\r
-};\r
-\r
 typedef struct {\r
   char *name;\r
   int squareSize;\r
@@ -248,7 +232,7 @@ typedef struct {
   int cliWidth, cliHeight;\r
 } SizeInfo;\r
 \r
-SizeInfo sizeInfo[] =\r
+SizeInfo sizeInfo[] = \r
 {\r
   { "tiny",     21, 0, 1, 1, 0, 0 },\r
   { "teeny",    25, 1, 1, 1, 0, 0 },\r
@@ -346,15 +330,7 @@ static char *commentTitle;
 static char *commentText;\r
 static int commentIndex;\r
 static Boolean editComment = FALSE;\r
-HWND commentDialog = NULL;\r
-BOOLEAN commentDialogUp = FALSE;\r
-static int commentX, commentY, commentH, commentW;\r
 \r
-static char *analysisTitle;\r
-static char *analysisText;\r
-HWND analysisDialog = NULL;\r
-BOOLEAN analysisDialogUp = FALSE;\r
-static int analysisX, analysisY, analysisH, analysisW;\r
 \r
 char errorTitle[MSG_SIZ];\r
 char errorMessage[2*MSG_SIZ];\r
@@ -424,37 +400,27 @@ VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca);
 int NewGameFRC();\r
 int GameListOptions();\r
 \r
-HWND moveHistoryDialog = NULL;\r
-BOOLEAN moveHistoryDialogUp = FALSE;\r
-\r
-WindowPlacement wpMoveHistory;\r
+int dummy; // [HGM] for obsolete args\r
 \r
+HWND hwndMain = NULL;        /* root window*/\r
+HWND hwndConsole = NULL;\r
+HWND commentDialog = NULL;\r
+HWND moveHistoryDialog = NULL;\r
 HWND evalGraphDialog = NULL;\r
-BOOLEAN evalGraphDialogUp = FALSE;\r
-\r
-WindowPlacement wpEvalGraph;\r
-\r
 HWND engineOutputDialog = NULL;\r
-BOOLEAN engineOutputDialogUp = FALSE;\r
+HWND gameListDialog = NULL;\r
+HWND editTagsDialog = NULL;\r
 \r
+int commentUp = FALSE;\r
+\r
+WindowPlacement wpMain;\r
+WindowPlacement wpConsole;\r
+WindowPlacement wpComment;\r
+WindowPlacement wpMoveHistory;\r
+WindowPlacement wpEvalGraph;\r
 WindowPlacement wpEngineOutput;\r
 WindowPlacement wpGameList;\r
-WindowPlacement wpConsole;\r
-\r
-VOID MoveHistoryPopUp();\r
-VOID MoveHistoryPopDown();\r
-VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
-BOOL MoveHistoryIsUp();\r
-\r
-VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
-VOID EvalGraphPopUp();\r
-VOID EvalGraphPopDown();\r
-BOOL EvalGraphIsUp();\r
-\r
-VOID EngineOutputPopUp();\r
-VOID EngineOutputPopDown();\r
-BOOL EngineOutputIsUp();\r
-VOID EngineOutputUpdate( FrontEndProgramStats * stats );\r
+WindowPlacement wpTags;\r
 \r
 VOID EngineOptionsPopup(); // [HGM] settings\r
 \r
@@ -522,7 +488,7 @@ void ThawUI()
 \r
 int APIENTRY\r
 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,\r
-    LPSTR lpCmdLine, int nCmdShow)\r
+       LPSTR lpCmdLine, int nCmdShow)\r
 {\r
   MSG msg;\r
   HANDLE hAccelMain, hAccelNoAlt, hAccelNoICS;\r
@@ -552,104 +518,104 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
   /* Acquire and dispatch messages until a WM_QUIT message is received. */\r
 \r
   while (GetMessage(&msg, /* message structure */\r
-            NULL, /* handle of window receiving the message */\r
-            0,    /* lowest message to examine */\r
-            0))   /* highest message to examine */\r
+                   NULL, /* handle of window receiving the message */\r
+                   0,    /* lowest message to examine */\r
+                   0))   /* highest message to examine */\r
     {\r
 \r
       if(msg.message == WM_CHAR && msg.wParam == '\t') {\r
-    // [HGM] navigate: switch between all windows with tab\r
-    HWND e1 = NULL, e2 = NULL, mh = NULL, hInput = NULL, hText = NULL;\r
-    int i, currentElement = 0;\r
-\r
-    // first determine what element of the chain we come from (if any)\r
-    if(appData.icsActive) {\r
-        hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
-        hText  = GetDlgItem(hwndConsole, OPT_ConsoleText);\r
-    }\r
-    if(engineOutputDialog && EngineOutputIsUp()) {\r
-        e1 = GetDlgItem(engineOutputDialog, IDC_EngineMemo1);\r
-        e2 = GetDlgItem(engineOutputDialog, IDC_EngineMemo2);\r
-    }\r
-    if(moveHistoryDialog && MoveHistoryIsUp()) {\r
-        mh = GetDlgItem(moveHistoryDialog, IDC_MoveHistory);\r
-    }\r
-    if(msg.hwnd == hwndMain) currentElement = 7 ; else\r
-    if(msg.hwnd == engineOutputDialog) currentElement = 2; else\r
-    if(msg.hwnd == e1)                 currentElement = 2; else\r
-    if(msg.hwnd == e2)                 currentElement = 3; else\r
-    if(msg.hwnd == moveHistoryDialog) currentElement = 4; else\r
-    if(msg.hwnd == mh)                currentElement = 4; else\r
-    if(msg.hwnd == evalGraphDialog)    currentElement = 6; else\r
-    if(msg.hwnd == hText)  currentElement = 5; else\r
-    if(msg.hwnd == hInput) currentElement = 6; else\r
-    for (i = 0; i < N_BUTTONS; i++) {\r
-        if (buttonDesc[i].hwnd == msg.hwnd) { currentElement = 1; break; }\r
-    }\r
-\r
-    // determine where to go to\r
-    if(currentElement) { HWND h = NULL; int direction = GetKeyState(VK_SHIFT) < 0 ? -1 : 1;\r
-      do {\r
-        currentElement = (currentElement + direction) % 7;\r
-        switch(currentElement) {\r
-        case 0:\r
-          h = hwndMain; break; // passing this case always makes the loop exit\r
-        case 1:\r
-          h = buttonDesc[0].hwnd; break; // could be NULL\r
-        case 2:\r
-          if(!EngineOutputIsUp()) continue; // skip closed auxiliary windows\r
-          h = e1; break;\r
-        case 3:\r
-          if(!EngineOutputIsUp()) continue;\r
-          h = e2; break;\r
-        case 4:\r
-          if(!MoveHistoryIsUp()) continue;\r
-          h = mh; break;\r
-//      case 6: // input to eval graph does not seem to get here!\r
-//        if(!EvalGraphIsUp()) continue;\r
-//        h = evalGraphDialog; break;\r
-        case 5:\r
-          if(!appData.icsActive) continue;\r
-          SAY("display");\r
-          h = hText; break;\r
-        case 6:\r
-          if(!appData.icsActive) continue;\r
-          SAY("input");\r
-          h = hInput; break;\r
-        }\r
-      } while(h == 0);\r
-\r
-      if(currentElement > 4 && IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
-      if(currentElement < 5 && IsIconic(hwndMain))    ShowWindow(hwndMain, SW_RESTORE); // all open together\r
-      SetFocus(h);\r
-\r
-      continue; // this message now has been processed\r
-    }\r
+       // [HGM] navigate: switch between all windows with tab\r
+       HWND e1 = NULL, e2 = NULL, mh = NULL, hInput = NULL, hText = NULL;\r
+       int i, currentElement = 0;\r
+\r
+       // first determine what element of the chain we come from (if any)\r
+       if(appData.icsActive) {\r
+           hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
+           hText  = GetDlgItem(hwndConsole, OPT_ConsoleText);\r
+       }\r
+       if(engineOutputDialog && EngineOutputIsUp()) {\r
+           e1 = GetDlgItem(engineOutputDialog, IDC_EngineMemo1);\r
+           e2 = GetDlgItem(engineOutputDialog, IDC_EngineMemo2);\r
+       }\r
+       if(moveHistoryDialog && MoveHistoryIsUp()) {\r
+           mh = GetDlgItem(moveHistoryDialog, IDC_MoveHistory);\r
+       }\r
+       if(msg.hwnd == hwndMain) currentElement = 7 ; else\r
+       if(msg.hwnd == engineOutputDialog) currentElement = 2; else\r
+       if(msg.hwnd == e1)                 currentElement = 2; else\r
+       if(msg.hwnd == e2)                 currentElement = 3; else\r
+       if(msg.hwnd == moveHistoryDialog) currentElement = 4; else\r
+       if(msg.hwnd == mh)                currentElement = 4; else\r
+       if(msg.hwnd == evalGraphDialog)    currentElement = 6; else\r
+       if(msg.hwnd == hText)  currentElement = 5; else\r
+       if(msg.hwnd == hInput) currentElement = 6; else\r
+       for (i = 0; i < N_BUTTONS; i++) {\r
+           if (buttonDesc[i].hwnd == msg.hwnd) { currentElement = 1; break; }\r
+       }\r
+\r
+       // determine where to go to\r
+       if(currentElement) { HWND h = NULL; int direction = GetKeyState(VK_SHIFT) < 0 ? -1 : 1;\r
+         do {\r
+           currentElement = (currentElement + direction) % 7;\r
+           switch(currentElement) {\r
+               case 0:\r
+                 h = hwndMain; break; // passing this case always makes the loop exit\r
+               case 1:\r
+                 h = buttonDesc[0].hwnd; break; // could be NULL\r
+               case 2:\r
+                 if(!EngineOutputIsUp()) continue; // skip closed auxiliary windows\r
+                 h = e1; break;\r
+               case 3:\r
+                 if(!EngineOutputIsUp()) continue;\r
+                 h = e2; break;\r
+               case 4:\r
+                 if(!MoveHistoryIsUp()) continue;\r
+                 h = mh; break;\r
+//             case 6: // input to eval graph does not seem to get here!\r
+//               if(!EvalGraphIsUp()) continue;\r
+//               h = evalGraphDialog; break;\r
+               case 5:\r
+                 if(!appData.icsActive) continue;\r
+                 SAY("display");\r
+                 h = hText; break;\r
+               case 6:\r
+                 if(!appData.icsActive) continue;\r
+                 SAY("input");\r
+                 h = hInput; break;\r
+           }\r
+         } while(h == 0);\r
+\r
+         if(currentElement > 4 && IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
+         if(currentElement < 5 && IsIconic(hwndMain))    ShowWindow(hwndMain, SW_RESTORE); // all open together\r
+         SetFocus(h);\r
+\r
+         continue; // this message now has been processed\r
+       }\r
       }\r
 \r
       if (!(commentDialog && IsDialogMessage(commentDialog, &msg)) &&\r
           !(moveHistoryDialog && IsDialogMessage(moveHistoryDialog, &msg)) &&\r
           !(evalGraphDialog && IsDialogMessage(evalGraphDialog, &msg)) &&\r
           !(engineOutputDialog && IsDialogMessage(engineOutputDialog, &msg)) &&\r
-      !(editTagsDialog && IsDialogMessage(editTagsDialog, &msg)) &&\r
-      !(gameListDialog && IsDialogMessage(gameListDialog, &msg)) &&\r
-      !(errorDialog && IsDialogMessage(errorDialog, &msg)) &&\r
-      !(!frozen && TranslateAccelerator(hwndMain, hAccelMain, &msg)) && JAWS_ACCEL\r
+         !(editTagsDialog && IsDialogMessage(editTagsDialog, &msg)) &&\r
+         !(gameListDialog && IsDialogMessage(gameListDialog, &msg)) &&\r
+         !(errorDialog && IsDialogMessage(errorDialog, &msg)) &&\r
+         !(!frozen && TranslateAccelerator(hwndMain, hAccelMain, &msg)) && JAWS_ACCEL\r
           !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoICS, &msg)) &&\r
-      !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoAlt, &msg))) {\r
-    int done = 0, i; // [HGM] chat: dispatch cat-box messages\r
-    for(i=0; i<MAX_CHAT; i++)\r
-        if(chatHandle[i] && IsDialogMessage(chatHandle[i], &msg)) {\r
-        done = 1; break;\r
-    }\r
-    if(done) continue; // [HGM] chat: end patch\r
-    TranslateMessage(&msg); /* Translates virtual key codes */\r
-    DispatchMessage(&msg);  /* Dispatches message to window */\r
+         !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoAlt, &msg))) {\r
+       int done = 0, i; // [HGM] chat: dispatch cat-box messages\r
+       for(i=0; i<MAX_CHAT; i++) \r
+           if(chatHandle[i] && IsDialogMessage(chatHandle[i], &msg)) {\r
+               done = 1; break;\r
+       }\r
+       if(done) continue; // [HGM] chat: end patch\r
+       TranslateMessage(&msg); /* Translates virtual key codes */\r
+       DispatchMessage(&msg);  /* Dispatches message to window */\r
       }\r
     }\r
 \r
 \r
-  return (msg.wParam);  /* Returns the value from PostQuitMessage */\r
+  return (msg.wParam); /* Returns the value from PostQuitMessage */\r
 }\r
 \r
 /*---------------------------------------------------------------------------*\\r
@@ -664,12 +630,12 @@ SetUserLogo()
     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
+         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
@@ -682,15 +648,15 @@ InitApplication(HINSTANCE hInstance)
   /* main window. */\r
 \r
   wc.style         = CS_HREDRAW | CS_VREDRAW; /* Class style(s). */\r
-  wc.lpfnWndProc   = (WNDPROC)WndProc;  /* Window Procedure */\r
-  wc.cbClsExtra    = 0;         /* No per-class extra data. */\r
-  wc.cbWndExtra    = 0;         /* No per-window extra data. */\r
-  wc.hInstance     = hInstance;     /* Owner of this class */\r
+  wc.lpfnWndProc   = (WNDPROC)WndProc; /* Window Procedure */\r
+  wc.cbClsExtra    = 0;                        /* No per-class extra data. */\r
+  wc.cbWndExtra    = 0;                        /* No per-window extra data. */\r
+  wc.hInstance     = hInstance;                /* Owner of this class */\r
   wc.hIcon         = LoadIcon(hInstance, "icon_white");\r
-  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);   /* Cursor */\r
-  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);  /* Default color */\r
-  wc.lpszMenuName  = szAppName;         /* Menu name from .RC */\r
-  wc.lpszClassName = szAppName;         /* Name to register as */\r
+  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);      /* Cursor */\r
+  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); /* Default color */\r
+  wc.lpszMenuName  = szAppName;                        /* Menu name from .RC */\r
+  wc.lpszClassName = szAppName;                        /* Name to register as */\r
 \r
   /* Register the window class and return success/failure code. */\r
   if (!RegisterClass(&wc)) return FALSE;\r
@@ -733,7 +699,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   WINDOWPLACEMENT wp;\r
   char *filepart;\r
 \r
-  hInst = hInstance;    /* Store instance handle in our global variable */\r
+  hInst = hInstance;   /* Store instance handle in our global variable */\r
+  programName = szAppName;\r
 \r
   if (SearchPath(NULL, "WinBoard.exe", NULL, MSG_SIZ, installDir, &filepart)) {\r
     *filepart = NULLCHAR;\r
@@ -743,6 +710,17 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   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
+  /* xboard, and older WinBoards, controlled the move sound with the\r
+     appData.ringBellAfterMoves option.  In the current WinBoard, we\r
+     always turn the option on (so that the backend will call us),\r
+     then let the user turn the sound off by setting it to silence if\r
+     desired.  To accommodate old winboard.ini files saved by old\r
+     versions of WinBoard, we also turn off the sound if the option\r
+     was initially set to false. [HGM] taken out of InitAppData */\r
+  if (!appData.ringBellAfterMoves) {\r
+    sounds[(int)SoundMove].name = strdup("");\r
+    appData.ringBellAfterMoves = TRUE;\r
+  }\r
   if (appData.debugMode) {\r
     debugFP = fopen(appData.nameOfDebugFile, "w");\r
     setbuf(debugFP, NULL);\r
@@ -755,9 +733,9 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
 \r
   /* Create a main window for this application instance. */\r
   hwnd = CreateWindow(szAppName, szTitle,\r
-              (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX),\r
-              CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,\r
-              NULL, NULL, hInstance, NULL);\r
+                     (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX),\r
+                     CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,\r
+                     NULL, NULL, hInstance, NULL);\r
   hwndMain = hwnd;\r
 \r
   /* If window could not be created, return "failure" */\r
@@ -774,9 +752,9 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
       }\r
   } else if(appData.autoLogo) {\r
       if(appData.firstDirectory && appData.firstDirectory[0]) {\r
-    char buf[MSG_SIZ];\r
-    sprintf(buf, "%s/logo.bmp", appData.firstDirectory);\r
-    first.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+       char buf[MSG_SIZ];\r
+       sprintf(buf, "%s/logo.bmp", appData.firstDirectory);\r
+       first.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );   \r
       }\r
   }\r
 \r
@@ -789,12 +767,12 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   } 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
+       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
-    sprintf(buf, "%s\\logo.bmp", appData.secondDirectory);\r
-    second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+       sprintf(buf, "%s\\logo.bmp", appData.secondDirectory);\r
+       second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );  \r
       }\r
   }\r
 \r
@@ -824,7 +802,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
 \r
   /* [AS] Load textures if specified */\r
   ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) );\r
-\r
+  \r
   if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) {\r
       liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
       liteBackTextureMode = appData.liteBackTextureMode;\r
@@ -833,7 +811,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
           fprintf( debugFP, "Unable to load lite texture bitmap '%s'\n", appData.liteBackTextureFile );\r
       }\r
   }\r
-\r
+  \r
   if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) {\r
       darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
       darkBackTextureMode = appData.darkBackTextureMode;\r
@@ -861,15 +839,15 @@ 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, minX, minY);\r
+  EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY);\r
   wp.length = sizeof(WINDOWPLACEMENT);\r
   wp.flags = 0;\r
   wp.showCmd = nCmdShow;\r
   wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
-  wp.rcNormalPosition.left = boardX;\r
-  wp.rcNormalPosition.right = boardX + winWidth;\r
-  wp.rcNormalPosition.top = boardY;\r
-  wp.rcNormalPosition.bottom = boardY + winHeight;\r
+  wp.rcNormalPosition.left = wpMain.x;\r
+  wp.rcNormalPosition.right = wpMain.x + wpMain.width;\r
+  wp.rcNormalPosition.top = wpMain.y;\r
+  wp.rcNormalPosition.bottom = wpMain.y + wpMain.height;\r
   SetWindowPlacement(hwndMain, &wp);\r
 \r
   if(!appData.noGUI) SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
@@ -889,580 +867,81 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
 \r
 }\r
 \r
+VOID\r
+InitMenuChecks()\r
+{\r
+  HMENU hmenu = GetMenu(hwndMain);\r
 \r
-typedef enum {\r
-  ArgString, ArgInt, ArgFloat, ArgBoolean, ArgTrue, ArgFalse, ArgNone,\r
-  ArgColor, ArgAttribs, ArgFilename, ArgBoardSize, ArgFont, ArgCommSettings,\r
-  ArgSettingsFilename,\r
-  ArgX, ArgY, ArgZ // [HGM] placement: for window-placement options stored relative to main window\r
-} ArgType;\r
+  (void) EnableMenuItem(hmenu, IDM_CommPort,\r
+                       MF_BYCOMMAND|((appData.icsActive &&\r
+                                      *appData.icsCommPort != NULLCHAR) ?\r
+                                     MF_ENABLED : MF_GRAYED));\r
+  (void) CheckMenuItem(hmenu, IDM_SaveSettingsOnExit,\r
+                      MF_BYCOMMAND|(saveSettingsOnExit ?\r
+                                    MF_CHECKED : MF_UNCHECKED));\r
+}\r
 \r
-typedef struct {\r
-  char *argName;\r
-  ArgType argType;\r
-  /***\r
-  union {\r
-    String *pString;       // ArgString\r
-    int *pInt;             // ArgInt\r
-    float *pFloat;         // ArgFloat\r
-    Boolean *pBoolean;     // ArgBoolean\r
-    COLORREF *pColor;      // ArgColor\r
-    ColorClass cc;         // ArgAttribs\r
-    String *pFilename;     // ArgFilename\r
-    BoardSize *pBoardSize; // ArgBoardSize\r
-    int whichFont;         // ArgFont\r
-    DCB *pDCB;             // ArgCommSettings\r
-    String *pFilename;     // ArgSettingsFilename\r
-  } argLoc;\r
-  ***/\r
-  LPVOID argLoc;\r
-  BOOL save;\r
-} ArgDescriptor;\r
-\r
-int junk;\r
-ArgDescriptor argDescriptors[] = {\r
-  /* positional arguments */\r
-  { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE },\r
-  { "", ArgNone, NULL },\r
-  /* keyword arguments */\r
-  JAWS_ARGS\r
-  { "whitePieceColor", ArgColor, (LPVOID) &whitePieceColor, TRUE },\r
-  { "wpc", ArgColor, (LPVOID) &whitePieceColor, FALSE },\r
-  { "blackPieceColor", ArgColor, (LPVOID) &blackPieceColor, TRUE },\r
-  { "bpc", ArgColor, (LPVOID) &blackPieceColor, FALSE },\r
-  { "lightSquareColor", ArgColor, (LPVOID) &lightSquareColor, TRUE },\r
-  { "lsc", ArgColor, (LPVOID) &lightSquareColor, FALSE },\r
-  { "darkSquareColor", ArgColor, (LPVOID) &darkSquareColor, TRUE },\r
-  { "dsc", ArgColor, (LPVOID) &darkSquareColor, FALSE },\r
-  { "highlightSquareColor", ArgColor, (LPVOID) &highlightSquareColor, TRUE },\r
-  { "hsc", ArgColor, (LPVOID) &highlightSquareColor, FALSE },\r
-  { "premoveHighlightColor", ArgColor, (LPVOID) &premoveHighlightColor, TRUE },\r
-  { "phc", ArgColor, (LPVOID) &premoveHighlightColor, FALSE },\r
-  { "movesPerSession", ArgInt, (LPVOID) &appData.movesPerSession, TRUE },\r
-  { "mps", ArgInt, (LPVOID) &appData.movesPerSession, FALSE },\r
-  { "initString", ArgString, (LPVOID) &appData.initString, FALSE },\r
-  { "firstInitString", ArgString, (LPVOID) &appData.initString, FALSE },\r
-  { "secondInitString", ArgString, (LPVOID) &appData.secondInitString, FALSE },\r
-  { "firstComputerString", ArgString, (LPVOID) &appData.firstComputerString,\r
-    FALSE },\r
-  { "secondComputerString", ArgString, (LPVOID) &appData.secondComputerString,\r
-    FALSE },\r
-  { "firstChessProgram", ArgFilename, (LPVOID) &appData.firstChessProgram,\r
-    FALSE },\r
-  { "fcp", ArgFilename, (LPVOID) &appData.firstChessProgram, FALSE },\r
-  { "secondChessProgram", ArgFilename, (LPVOID) &appData.secondChessProgram,\r
-    FALSE },\r
-  { "scp", ArgFilename, (LPVOID) &appData.secondChessProgram, FALSE },\r
-  { "firstPlaysBlack", ArgBoolean, (LPVOID) &appData.firstPlaysBlack, FALSE },\r
-  { "fb", ArgTrue, (LPVOID) &appData.firstPlaysBlack, FALSE },\r
-  { "xfb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE },\r
-  { "-fb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE },\r
-  { "noChessProgram", ArgBoolean, (LPVOID) &appData.noChessProgram, FALSE },\r
-  { "ncp", ArgTrue, (LPVOID) &appData.noChessProgram, FALSE },\r
-  { "xncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE },\r
-  { "-ncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE },\r
-  { "firstHost", ArgString, (LPVOID) &appData.firstHost, FALSE },\r
-  { "fh", ArgString, (LPVOID) &appData.firstHost, FALSE },\r
-  { "secondHost", ArgString, (LPVOID) &appData.secondHost, FALSE },\r
-  { "sh", ArgString, (LPVOID) &appData.secondHost, FALSE },\r
-  { "firstDirectory", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE },\r
-  { "fd", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE },\r
-  { "secondDirectory", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE },\r
-  { "sd", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE },\r
-  /*!!bitmapDirectory?*/\r
-  { "remoteShell", ArgFilename, (LPVOID) &appData.remoteShell, FALSE },\r
-  { "rsh", ArgFilename, (LPVOID) &appData.remoteShell, FALSE },\r
-  { "remoteUser", ArgString, (LPVOID) &appData.remoteUser, FALSE },\r
-  { "ruser", ArgString, (LPVOID) &appData.remoteUser, FALSE },\r
-  { "timeDelay", ArgFloat, (LPVOID) &appData.timeDelay, TRUE },\r
-  { "td", ArgFloat, (LPVOID) &appData.timeDelay, FALSE },\r
-  { "timeControl", ArgString, (LPVOID) &appData.timeControl, TRUE },\r
-  { "tc", ArgString, (LPVOID) &appData.timeControl, FALSE },\r
-  { "timeIncrement", ArgInt, (LPVOID) &appData.timeIncrement, TRUE },\r
-  { "inc", ArgInt, (LPVOID) &appData.timeIncrement, FALSE },\r
-  { "internetChessServerMode", ArgBoolean, (LPVOID) &appData.icsActive, FALSE },\r
-  { "ics", ArgTrue, (LPVOID) &appData.icsActive, FALSE },\r
-  { "xics", ArgFalse, (LPVOID) &appData.icsActive, FALSE },\r
-  { "-ics", ArgFalse, (LPVOID) &appData.icsActive, FALSE },\r
-  { "internetChessServerHost", ArgString, (LPVOID) &appData.icsHost, FALSE },\r
-  { "icshost", ArgString, (LPVOID) &appData.icsHost, FALSE },\r
-  { "internetChessServerPort", ArgString, (LPVOID) &appData.icsPort, FALSE },\r
-  { "icsport", ArgString, (LPVOID) &appData.icsPort, FALSE },\r
-  { "internetChessServerCommPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE },\r
-  { "icscomm", ArgString, (LPVOID) &appData.icsCommPort, FALSE },\r
-  { "internetChessServerComPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE },\r
-  { "icscom", ArgString, (LPVOID) &appData.icsCommPort, FALSE },\r
-  { "internetChessServerLogonScript", ArgFilename, (LPVOID) &appData.icsLogon, FALSE },\r
-  { "icslogon", ArgFilename, (LPVOID) &appData.icsLogon, FALSE },\r
-  { "useTelnet", ArgBoolean, (LPVOID) &appData.useTelnet, FALSE },\r
-  { "telnet", ArgTrue, (LPVOID) &appData.useTelnet, FALSE },\r
-  { "xtelnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE },\r
-  { "-telnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE },\r
-  { "telnetProgram", ArgFilename, (LPVOID) &appData.telnetProgram, FALSE },\r
-  { "icshelper", ArgFilename, (LPVOID) &appData.icsHelper, FALSE },\r
-  { "gateway", ArgString, (LPVOID) &appData.gateway, FALSE },\r
-  { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE },\r
-  { "lgf", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE },\r
-  { "loadGameIndex", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE },\r
-  { "lgi", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE },\r
-  { "saveGameFile", ArgFilename, (LPVOID) &appData.saveGameFile, TRUE },\r
-  { "sgf", ArgFilename, (LPVOID) &appData.saveGameFile, FALSE },\r
-  { "autoSaveGames", ArgBoolean, (LPVOID) &appData.autoSaveGames, TRUE },\r
-  { "autosave", ArgTrue, (LPVOID) &appData.autoSaveGames, FALSE },\r
-  { "xautosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE },\r
-  { "-autosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE },\r
-  { "loadPositionFile", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE },\r
-  { "lpf", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE },\r
-  { "loadPositionIndex", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE },\r
-  { "lpi", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE },\r
-  { "savePositionFile", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE },\r
-  { "spf", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE },\r
-  { "matchMode", ArgBoolean, (LPVOID) &appData.matchMode, FALSE },\r
-  { "mm", ArgTrue, (LPVOID) &appData.matchMode, FALSE },\r
-  { "xmm", ArgFalse, (LPVOID) &appData.matchMode, FALSE },\r
-  { "-mm", ArgFalse, (LPVOID) &appData.matchMode, FALSE },\r
-  { "matchGames", ArgInt, (LPVOID) &appData.matchGames, FALSE },\r
-  { "mg", ArgInt, (LPVOID) &appData.matchGames, FALSE },\r
-  { "monoMode", ArgBoolean, (LPVOID) &appData.monoMode, TRUE },\r
-  { "mono", ArgTrue, (LPVOID) &appData.monoMode, FALSE },\r
-  { "xmono", ArgFalse, (LPVOID) &appData.monoMode, FALSE },\r
-  { "-mono", ArgFalse, (LPVOID) &appData.monoMode, FALSE },\r
-  { "debugMode", ArgBoolean, (LPVOID) &appData.debugMode, FALSE },\r
-  { "debug", ArgTrue, (LPVOID) &appData.debugMode, FALSE },\r
-  { "xdebug", ArgFalse, (LPVOID) &appData.debugMode, FALSE },\r
-  { "-debug", ArgFalse, (LPVOID) &appData.debugMode, FALSE },\r
-  { "clockMode", ArgBoolean, (LPVOID) &appData.clockMode, FALSE },\r
-  { "clock", ArgTrue, (LPVOID) &appData.clockMode, FALSE },\r
-  { "xclock", ArgFalse, (LPVOID) &appData.clockMode, FALSE },\r
-  { "-clock", ArgFalse, (LPVOID) &appData.clockMode, FALSE },\r
-  { "searchTime", ArgString, (LPVOID) &appData.searchTime, FALSE },\r
-  { "st", ArgString, (LPVOID) &appData.searchTime, FALSE },\r
-  { "searchDepth", ArgInt, (LPVOID) &appData.searchDepth, FALSE },\r
-  { "depth", ArgInt, (LPVOID) &appData.searchDepth, FALSE },\r
-  { "showCoords", ArgBoolean, (LPVOID) &appData.showCoords, TRUE },\r
-  { "coords", ArgTrue, (LPVOID) &appData.showCoords, FALSE },\r
-  { "xcoords", ArgFalse, (LPVOID) &appData.showCoords, FALSE },\r
-  { "-coords", ArgFalse, (LPVOID) &appData.showCoords, FALSE },\r
-  { "showThinking", ArgBoolean, (LPVOID) &appData.showThinking, TRUE },\r
-  { "thinking", ArgTrue, (LPVOID) &appData.showThinking, FALSE },\r
-  { "xthinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE },\r
-  { "-thinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE },\r
-  { "ponderNextMove", ArgBoolean, (LPVOID) &appData.ponderNextMove, TRUE },\r
-  { "ponder", ArgTrue, (LPVOID) &appData.ponderNextMove, FALSE },\r
-  { "xponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE },\r
-  { "-ponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE },\r
-  { "periodicUpdates", ArgBoolean, (LPVOID) &appData.periodicUpdates, TRUE },\r
-  { "periodic", ArgTrue, (LPVOID) &appData.periodicUpdates, FALSE },\r
-  { "xperiodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE },\r
-  { "-periodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE },\r
-  { "popupExitMessage", ArgBoolean, (LPVOID) &appData.popupExitMessage, TRUE },\r
-  { "exit", ArgTrue, (LPVOID) &appData.popupExitMessage, FALSE },\r
-  { "xexit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE },\r
-  { "-exit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE },\r
-  { "popupMoveErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, TRUE },\r
-  { "popup", ArgTrue, (LPVOID) &appData.popupMoveErrors, FALSE },\r
-  { "xpopup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE },\r
-  { "-popup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE },\r
-  { "popUpErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors,\r
-    FALSE }, /* only so that old WinBoard.ini files from betas can be read */\r
-  { "clockFont", ArgFont, (LPVOID) CLOCK_FONT, TRUE },\r
-  { "messageFont", ArgFont, (LPVOID) MESSAGE_FONT, TRUE },\r
-  { "coordFont", ArgFont, (LPVOID) COORD_FONT, TRUE },\r
-  { "tagsFont", ArgFont, (LPVOID) EDITTAGS_FONT, TRUE },\r
-  { "commentFont", ArgFont, (LPVOID) COMMENT_FONT, TRUE },\r
-  { "icsFont", ArgFont, (LPVOID) CONSOLE_FONT, TRUE },\r
-  { "moveHistoryFont", ArgFont, (LPVOID) MOVEHISTORY_FONT, TRUE }, /* [AS] */\r
-  { "boardSize", ArgBoardSize, (LPVOID) &boardSize,\r
-    TRUE }, /* must come after all fonts */\r
-  { "size", ArgBoardSize, (LPVOID) &boardSize, FALSE },\r
-  { "ringBellAfterMoves", ArgBoolean, (LPVOID) &appData.ringBellAfterMoves,\r
-    FALSE }, /* historical; kept only so old winboard.ini files will parse */\r
-  { "alwaysOnTop", ArgBoolean, (LPVOID) &alwaysOnTop, TRUE },\r
-  { "top", ArgTrue, (LPVOID) &alwaysOnTop, FALSE },\r
-  { "xtop", ArgFalse, (LPVOID) &alwaysOnTop, FALSE },\r
-  { "-top", ArgFalse, (LPVOID) &alwaysOnTop, FALSE },\r
-  { "autoCallFlag", ArgBoolean, (LPVOID) &appData.autoCallFlag, TRUE },\r
-  { "autoflag", ArgTrue, (LPVOID) &appData.autoCallFlag, FALSE },\r
-  { "xautoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE },\r
-  { "-autoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE },\r
-  { "autoComment", ArgBoolean, (LPVOID) &appData.autoComment, TRUE },\r
-  { "autocomm", ArgTrue, (LPVOID) &appData.autoComment, FALSE },\r
-  { "xautocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE },\r
-  { "-autocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE },\r
-  { "autoObserve", ArgBoolean, (LPVOID) &appData.autoObserve, TRUE },\r
-  { "autobs", ArgTrue, (LPVOID) &appData.autoObserve, FALSE },\r
-  { "xautobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE },\r
-  { "-autobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE },\r
-  { "flipView", ArgBoolean, (LPVOID) &appData.flipView, FALSE },\r
-  { "flip", ArgTrue, (LPVOID) &appData.flipView, FALSE },\r
-  { "xflip", ArgFalse, (LPVOID) &appData.flipView, FALSE },\r
-  { "-flip", ArgFalse, (LPVOID) &appData.flipView, FALSE },\r
-  { "autoFlipView", ArgBoolean, (LPVOID) &appData.autoFlipView, TRUE },\r
-  { "autoflip", ArgTrue, (LPVOID) &appData.autoFlipView, FALSE },\r
-  { "xautoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE },\r
-  { "-autoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE },\r
-  { "autoRaiseBoard", ArgBoolean, (LPVOID) &appData.autoRaiseBoard, TRUE },\r
-  { "autoraise", ArgTrue, (LPVOID) &appData.autoRaiseBoard, FALSE },\r
-  { "xautoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE },\r
-  { "-autoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE },\r
-#if 0\r
-  { "cmailGameName", ArgString, (LPVOID) &appData.cmailGameName, FALSE },\r
-  { "cmail", ArgString, (LPVOID) &appData.cmailGameName, FALSE },\r
-#endif\r
-  { "alwaysPromoteToQueen", ArgBoolean, (LPVOID) &appData.alwaysPromoteToQueen, TRUE },\r
-  { "queen", ArgTrue, (LPVOID) &appData.alwaysPromoteToQueen, FALSE },\r
-  { "xqueen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE },\r
-  { "-queen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE },\r
-  { "oldSaveStyle", ArgBoolean, (LPVOID) &appData.oldSaveStyle, TRUE },\r
-  { "oldsave", ArgTrue, (LPVOID) &appData.oldSaveStyle, FALSE },\r
-  { "xoldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE },\r
-  { "-oldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE },\r
-  { "quietPlay", ArgBoolean, (LPVOID) &appData.quietPlay, TRUE },\r
-  { "quiet", ArgTrue, (LPVOID) &appData.quietPlay, FALSE },\r
-  { "xquiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE },\r
-  { "-quiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE },\r
-  { "getMoveList", ArgBoolean, (LPVOID) &appData.getMoveList, TRUE },\r
-  { "moves", ArgTrue, (LPVOID) &appData.getMoveList, FALSE },\r
-  { "xmoves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE },\r
-  { "-moves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE },\r
-  { "testLegality", ArgBoolean, (LPVOID) &appData.testLegality, TRUE },\r
-  { "legal", ArgTrue, (LPVOID) &appData.testLegality, FALSE },\r
-  { "xlegal", ArgFalse, (LPVOID) &appData.testLegality, FALSE },\r
-  { "-legal", ArgFalse, (LPVOID) &appData.testLegality, FALSE },\r
-  { "premove", ArgBoolean, (LPVOID) &appData.premove, TRUE },\r
-  { "pre", ArgTrue, (LPVOID) &appData.premove, FALSE },\r
-  { "xpre", ArgFalse, (LPVOID) &appData.premove, FALSE },\r
-  { "-pre", ArgFalse, (LPVOID) &appData.premove, FALSE },\r
-  { "premoveWhite", ArgBoolean, (LPVOID) &appData.premoveWhite, TRUE },\r
-  { "prewhite", ArgTrue, (LPVOID) &appData.premoveWhite, FALSE },\r
-  { "xprewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE },\r
-  { "-prewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE },\r
-  { "premoveWhiteText", ArgString, (LPVOID) &appData.premoveWhiteText, TRUE },\r
-  { "premoveBlack", ArgBoolean, (LPVOID) &appData.premoveBlack, TRUE },\r
-  { "preblack", ArgTrue, (LPVOID) &appData.premoveBlack, FALSE },\r
-  { "xpreblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE },\r
-  { "-preblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE },\r
-  { "premoveBlackText", ArgString, (LPVOID) &appData.premoveBlackText, TRUE },\r
-  { "icsAlarm", ArgBoolean, (LPVOID) &appData.icsAlarm, TRUE},\r
-  { "alarm", ArgTrue, (LPVOID) &appData.icsAlarm, FALSE},\r
-  { "xalarm", ArgFalse, (LPVOID) &appData.icsAlarm, FALSE},\r
-  { "-alarm", ArgFalse, (LPVOID) &appData.icsAlarm, FALSE},\r
-  { "icsAlarmTime", ArgInt, (LPVOID) &appData.icsAlarmTime, TRUE},\r
-  { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE},\r
-  { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE},\r
-  { "edit", ArgTrue, (LPVOID) &appData.localLineEditing, FALSE },\r
-  { "xedit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE },\r
-  { "-edit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE },\r
-  { "animateMoving", ArgBoolean, (LPVOID) &appData.animate, TRUE },\r
-  { "animate", ArgTrue, (LPVOID) &appData.animate, FALSE },\r
-  { "xanimate", ArgFalse, (LPVOID) &appData.animate, FALSE },\r
-  { "-animate", ArgFalse, (LPVOID) &appData.animate, FALSE },\r
-  { "animateSpeed", ArgInt, (LPVOID) &appData.animSpeed, TRUE },\r
-  { "animateDragging", ArgBoolean, (LPVOID) &appData.animateDragging, TRUE },\r
-  { "drag", ArgTrue, (LPVOID) &appData.animateDragging, FALSE },\r
-  { "xdrag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE },\r
-  { "-drag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE },\r
-  { "blindfold", ArgBoolean, (LPVOID) &appData.blindfold, TRUE },\r
-  { "blind", ArgTrue, (LPVOID) &appData.blindfold, FALSE },\r
-  { "xblind", ArgFalse, (LPVOID) &appData.blindfold, FALSE },\r
-  { "-blind", ArgFalse, (LPVOID) &appData.blindfold, FALSE },\r
-  { "highlightLastMove", ArgBoolean,\r
-    (LPVOID) &appData.highlightLastMove, TRUE },\r
-  { "highlight", ArgTrue, (LPVOID) &appData.highlightLastMove, FALSE },\r
-  { "xhighlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE },\r
-  { "-highlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE },\r
-  { "highlightDragging", ArgBoolean,\r
-    (LPVOID) &appData.highlightDragging, TRUE },\r
-  { "highdrag", ArgTrue, (LPVOID) &appData.highlightDragging, FALSE },\r
-  { "xhighdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE },\r
-  { "-highdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE },\r
-  { "colorizeMessages", ArgBoolean, (LPVOID) &appData.colorize, TRUE },\r
-  { "colorize", ArgTrue, (LPVOID) &appData.colorize, FALSE },\r
-  { "xcolorize", ArgFalse, (LPVOID) &appData.colorize, FALSE },\r
-  { "-colorize", ArgFalse, (LPVOID) &appData.colorize, FALSE },\r
-  { "colorShout", ArgAttribs, (LPVOID) ColorShout, TRUE },\r
-  { "colorSShout", ArgAttribs, (LPVOID) ColorSShout, TRUE },\r
-  { "colorChannel1", ArgAttribs, (LPVOID) ColorChannel1, TRUE },\r
-  { "colorChannel", ArgAttribs, (LPVOID) ColorChannel, TRUE },\r
-  { "colorKibitz", ArgAttribs, (LPVOID) ColorKibitz, TRUE },\r
-  { "colorTell", ArgAttribs, (LPVOID) ColorTell, TRUE },\r
-  { "colorChallenge", ArgAttribs, (LPVOID) ColorChallenge, TRUE },\r
-  { "colorRequest", ArgAttribs, (LPVOID) ColorRequest, TRUE },\r
-  { "colorSeek", ArgAttribs, (LPVOID) ColorSeek, TRUE },\r
-  { "colorNormal", ArgAttribs, (LPVOID) ColorNormal, TRUE },\r
-  { "colorBackground", ArgColor, (LPVOID) &consoleBackgroundColor, TRUE },\r
-  { "soundShout", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorShout].sound.name, TRUE },\r
-  { "soundSShout", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorSShout].sound.name, TRUE },\r
-  { "soundChannel1", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorChannel1].sound.name, TRUE },\r
-  { "soundChannel", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorChannel].sound.name, TRUE },\r
-  { "soundKibitz", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorKibitz].sound.name, TRUE },\r
-  { "soundTell", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorTell].sound.name, TRUE },\r
-  { "soundChallenge", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorChallenge].sound.name, TRUE },\r
-  { "soundRequest", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorRequest].sound.name, TRUE },\r
-  { "soundSeek", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorSeek].sound.name, TRUE },\r
-  { "soundMove", ArgFilename, (LPVOID) &sounds[(int)SoundMove].name, TRUE },\r
-  { "soundBell", ArgFilename, (LPVOID) &sounds[(int)SoundBell].name, TRUE },\r
-  { "soundIcsWin", ArgFilename, (LPVOID) &sounds[(int)SoundIcsWin].name,TRUE },\r
-  { "soundIcsLoss", ArgFilename,\r
-    (LPVOID) &sounds[(int)SoundIcsLoss].name, TRUE },\r
-  { "soundIcsDraw", ArgFilename,\r
-    (LPVOID) &sounds[(int)SoundIcsDraw].name, TRUE },\r
-  { "soundIcsUnfinished", ArgFilename,\r
-    (LPVOID) &sounds[(int)SoundIcsUnfinished].name, TRUE},\r
-  { "soundIcsAlarm", ArgFilename,\r
-    (LPVOID) &sounds[(int)SoundAlarm].name, TRUE },\r
-  { "reuseFirst", ArgBoolean, (LPVOID) &appData.reuseFirst, FALSE },\r
-  { "reuse", ArgTrue, (LPVOID) &appData.reuseFirst, FALSE },\r
-  { "xreuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE },\r
-  { "-reuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE },\r
-  { "reuseChessPrograms", ArgBoolean,\r
-    (LPVOID) &appData.reuseFirst, FALSE }, /* backward compat only */\r
-  { "reuseSecond", ArgBoolean, (LPVOID) &appData.reuseSecond, FALSE },\r
-  { "reuse2", ArgTrue, (LPVOID) &appData.reuseSecond, FALSE },\r
-  { "xreuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE },\r
-  { "-reuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE },\r
-  { "comPortSettings", ArgCommSettings, (LPVOID) &dcb, TRUE },\r
-  { "settingsFile", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE },\r
-  { "ini", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE },\r
-  { "saveSettingsOnExit", ArgBoolean, (LPVOID) &saveSettingsOnExit, TRUE },\r
-  { "chessProgram", ArgBoolean, (LPVOID) &chessProgram, FALSE },\r
-  { "cp", ArgTrue, (LPVOID) &chessProgram, FALSE },\r
-  { "xcp", ArgFalse, (LPVOID) &chessProgram, FALSE },\r
-  { "-cp", ArgFalse, (LPVOID) &chessProgram, FALSE },\r
-  { "icsMenu", ArgString, (LPVOID) &icsTextMenuString, TRUE },\r
-  { "icsNames", ArgString, (LPVOID) &icsNames, TRUE },\r
-  { "firstChessProgramNames", ArgString, (LPVOID) &firstChessProgramNames,\r
-    TRUE },\r
-  { "secondChessProgramNames", ArgString, (LPVOID) &secondChessProgramNames,\r
-    TRUE },\r
-  { "initialMode", ArgString, (LPVOID) &appData.initialMode, FALSE },\r
-  { "mode", ArgString, (LPVOID) &appData.initialMode, FALSE },\r
-  { "variant", ArgString, (LPVOID) &appData.variant, FALSE },\r
-  { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion, FALSE },\r
-  { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,FALSE },\r
-  { "showButtonBar", ArgBoolean, (LPVOID) &appData.showButtonBar, TRUE },\r
-  { "buttons", ArgTrue, (LPVOID) &appData.showButtonBar, FALSE },\r
-  { "xbuttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE },\r
-  { "-buttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE },\r
-  /* [AS] New features */\r
-  { "firstScoreAbs", ArgBoolean, (LPVOID) &appData.firstScoreIsAbsolute, FALSE },\r
-  { "secondScoreAbs", ArgBoolean, (LPVOID) &appData.secondScoreIsAbsolute, FALSE },\r
-  { "pgnExtendedInfo", ArgBoolean, (LPVOID) &appData.saveExtendedInfoInPGN, TRUE },\r
-  { "hideThinkingFromHuman", ArgBoolean, (LPVOID) &appData.hideThinkingFromHuman, TRUE },\r
-  { "liteBackTextureFile", ArgString, (LPVOID) &appData.liteBackTextureFile, TRUE },\r
-  { "darkBackTextureFile", ArgString, (LPVOID) &appData.darkBackTextureFile, TRUE },\r
-  { "liteBackTextureMode", ArgInt, (LPVOID) &appData.liteBackTextureMode, TRUE },\r
-  { "darkBackTextureMode", ArgInt, (LPVOID) &appData.darkBackTextureMode, TRUE },\r
-  { "renderPiecesWithFont", ArgString, (LPVOID) &appData.renderPiecesWithFont, TRUE },\r
-  { "fontPieceToCharTable", ArgString, (LPVOID) &appData.fontToPieceTable, TRUE },\r
-  { "fontPieceBackColorWhite", ArgColor, (LPVOID) &appData.fontBackColorWhite, TRUE },\r
-  { "fontPieceForeColorWhite", ArgColor, (LPVOID) &appData.fontForeColorWhite, TRUE },\r
-  { "fontPieceBackColorBlack", ArgColor, (LPVOID) &appData.fontBackColorBlack, TRUE },\r
-  { "fontPieceForeColorBlack", ArgColor, (LPVOID) &appData.fontForeColorBlack, TRUE },\r
-  { "fontPieceSize", ArgInt, (LPVOID) &appData.fontPieceSize, TRUE },\r
-  { "overrideLineGap", ArgInt, (LPVOID) &appData.overrideLineGap, TRUE },\r
-  { "adjudicateLossThreshold", ArgInt, (LPVOID) &appData.adjudicateLossThreshold, TRUE },\r
-  { "delayBeforeQuit", ArgInt, (LPVOID) &appData.delayBeforeQuit, TRUE },\r
-  { "delayAfterQuit", ArgInt, (LPVOID) &appData.delayAfterQuit, TRUE },\r
-  { "nameOfDebugFile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },\r
-  { "debugfile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },\r
-  { "pgnEventHeader", ArgString, (LPVOID) &appData.pgnEventHeader, TRUE },\r
-  { "defaultFrcPosition", ArgInt, (LPVOID) &appData.defaultFrcPosition, TRUE },\r
-  { "gameListTags", ArgString, (LPVOID) &appData.gameListTags, TRUE },\r
-  { "saveOutOfBookInfo", ArgBoolean, (LPVOID) &appData.saveOutOfBookInfo, TRUE },\r
-  { "showEvalInMoveHistory", ArgBoolean, (LPVOID) &appData.showEvalInMoveHistory, TRUE },\r
-  { "evalHistColorWhite", ArgColor, (LPVOID) &appData.evalHistColorWhite, TRUE },\r
-  { "evalHistColorBlack", ArgColor, (LPVOID) &appData.evalHistColorBlack, TRUE },\r
-  { "highlightMoveWithArrow", ArgBoolean, (LPVOID) &appData.highlightMoveWithArrow, TRUE },\r
-  { "highlightArrowColor", ArgColor, (LPVOID) &appData.highlightArrowColor, TRUE },\r
-  { "stickyWindows", ArgBoolean, (LPVOID) &appData.useStickyWindows, TRUE },\r
-  { "adjudicateDrawMoves", ArgInt, (LPVOID) &appData.adjudicateDrawMoves, TRUE },\r
-  { "autoDisplayComment", ArgBoolean, (LPVOID) &appData.autoDisplayComment, TRUE },\r
-  { "autoDisplayTags", ArgBoolean, (LPVOID) &appData.autoDisplayTags, TRUE },\r
-  { "firstIsUCI", ArgBoolean, (LPVOID) &appData.firstIsUCI, FALSE },\r
-  { "fUCI", ArgTrue, (LPVOID) &appData.firstIsUCI, FALSE },\r
-  { "secondIsUCI", ArgBoolean, (LPVOID) &appData.secondIsUCI, FALSE },\r
-  { "sUCI", ArgTrue, (LPVOID) &appData.secondIsUCI, FALSE },\r
-  { "firstHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
-  { "fNoOwnBookUCI", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
-  { "firstXBook", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
-  { "secondHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
-  { "sNoOwnBookUCI", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
-  { "secondXBook", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
-  { "polyglotDir", ArgFilename, (LPVOID) &appData.polyglotDir, TRUE },\r
-  { "usePolyglotBook", ArgBoolean, (LPVOID) &appData.usePolyglotBook, TRUE },\r
-  { "polyglotBook", ArgFilename, (LPVOID) &appData.polyglotBook, TRUE },\r
-  { "defaultHashSize", ArgInt, (LPVOID) &appData.defaultHashSize, TRUE },\r
-  { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE },\r
-  { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, 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
-  { "holdingsSize", ArgInt, (LPVOID) &appData.holdingsSize, TRUE },\r
-  { "matchPause", ArgInt, (LPVOID) &appData.matchPause, TRUE },\r
-  { "pieceToCharTable", ArgString, (LPVOID) &appData.pieceToCharTable, FALSE },\r
-  { "flipBlack", ArgBoolean, (LPVOID) &appData.upsideDown, TRUE },\r
-  { "allWhite", ArgBoolean, (LPVOID) &appData.allWhite, TRUE },\r
-  { "alphaRank", ArgBoolean, (LPVOID) &appData.alphaRank, FALSE },\r
-  { "firstAlphaRank", ArgBoolean, (LPVOID) &first.alphaRank, FALSE },\r
-  { "secondAlphaRank", ArgBoolean, (LPVOID) &second.alphaRank, FALSE },\r
-  { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE },\r
-  { "checkMates", ArgBoolean, (LPVOID) &appData.checkMates, TRUE },\r
-  { "materialDraws", ArgBoolean, (LPVOID) &appData.materialDraws, TRUE },\r
-  { "trivialDraws", ArgBoolean, (LPVOID) &appData.trivialDraws, TRUE },\r
-  { "ruleMoves", ArgInt, (LPVOID) &appData.ruleMoves, TRUE },\r
-  { "repeatsToDraw", ArgInt, (LPVOID) &appData.drawRepeats, TRUE },\r
-  { "autoKibitz", ArgTrue, (LPVOID) &appData.autoKibitz, FALSE },\r
-  { "engineDebugOutput", ArgInt, (LPVOID) &appData.engineComments, FALSE },\r
-  { "userName", ArgString, (LPVOID) &appData.userName, FALSE },\r
-  { "rewindIndex", ArgInt, (LPVOID) &appData.rewindIndex, FALSE },\r
-  { "sameColorGames", ArgInt, (LPVOID) &appData.sameColorGames, FALSE },\r
-  { "smpCores", ArgInt, (LPVOID) &appData.smpCores, TRUE },\r
-  { "egtFormats", ArgString, (LPVOID) &appData.egtFormats, TRUE },\r
-  { "niceEngines", ArgInt, (LPVOID) &appData.niceEngines, TRUE },\r
-  { "firstLogo", ArgFilename, (LPVOID) &appData.firstLogo, FALSE },\r
-  { "secondLogo", ArgFilename, (LPVOID) &appData.secondLogo, FALSE },\r
-  { "autoLogo", ArgBoolean, (LPVOID) &appData.autoLogo, TRUE },\r
-  { "firstOptions", ArgString, (LPVOID) &appData.firstOptions, FALSE },\r
-  { "secondOptions", ArgString, (LPVOID) &appData.secondOptions, FALSE },\r
-  { "firstNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride1, FALSE },\r
-  { "secondNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride2, FALSE },\r
-  { "keepAlive", ArgInt, (LPVOID) &appData.keepAlive, FALSE },\r
-  { "icstype", ArgInt, (LPVOID) &ics_type, FALSE },\r
-  { "forceIllegalMoves", ArgTrue, (LPVOID) &appData.forceIllegal, FALSE },\r
+//---------------------------------------------------------------------------------------------------------\r
 \r
-#ifdef ZIPPY\r
-  { "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE },\r
-  { "zt", ArgTrue, (LPVOID) &appData.zippyTalk, FALSE },\r
-  { "xzt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE },\r
-  { "-zt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE },\r
-  { "zippyPlay", ArgBoolean, (LPVOID) &appData.zippyPlay, FALSE },\r
-  { "zp", ArgTrue, (LPVOID) &appData.zippyPlay, FALSE },\r
-  { "xzp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE },\r
-  { "-zp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE },\r
-  { "zippyLines", ArgFilename, (LPVOID) &appData.zippyLines, FALSE },\r
-  { "zippyPinhead", ArgString, (LPVOID) &appData.zippyPinhead, FALSE },\r
-  { "zippyPassword", ArgString, (LPVOID) &appData.zippyPassword, FALSE },\r
-  { "zippyPassword2", ArgString, (LPVOID) &appData.zippyPassword2, FALSE },\r
-  { "zippyWrongPassword", ArgString, (LPVOID) &appData.zippyWrongPassword,\r
-    FALSE },\r
-  { "zippyAcceptOnly", ArgString, (LPVOID) &appData.zippyAcceptOnly, FALSE },\r
-  { "zippyUseI", ArgBoolean, (LPVOID) &appData.zippyUseI, FALSE },\r
-  { "zui", ArgTrue, (LPVOID) &appData.zippyUseI, FALSE },\r
-  { "xzui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE },\r
-  { "-zui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE },\r
-  { "zippyBughouse", ArgInt, (LPVOID) &appData.zippyBughouse, FALSE },\r
-  { "zippyNoplayCrafty", ArgBoolean, (LPVOID) &appData.zippyNoplayCrafty,\r
-    FALSE },\r
-  { "znc", ArgTrue, (LPVOID) &appData.zippyNoplayCrafty, FALSE },\r
-  { "xznc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE },\r
-  { "-znc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE },\r
-  { "zippyGameEnd", ArgString, (LPVOID) &appData.zippyGameEnd, FALSE },\r
-  { "zippyGameStart", ArgString, (LPVOID) &appData.zippyGameStart, FALSE },\r
-  { "zippyAdjourn", ArgBoolean, (LPVOID) &appData.zippyAdjourn, FALSE },\r
-  { "zadj", ArgTrue, (LPVOID) &appData.zippyAdjourn, FALSE },\r
-  { "xzadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE },\r
-  { "-zadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE },\r
-  { "zippyAbort", ArgBoolean, (LPVOID) &appData.zippyAbort, FALSE },\r
-  { "zab", ArgTrue, (LPVOID) &appData.zippyAbort, FALSE },\r
-  { "xzab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE },\r
-  { "-zab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE },\r
-  { "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
-  /* [HGM] options for broadcasting and time odds */\r
-  { "serverMoves", ArgString, (LPVOID) &appData.serverMovesName, FALSE },\r
-  { "suppressLoadMoves", ArgBoolean, (LPVOID) &appData.suppressLoadMoves, FALSE },\r
-  { "serverPause", ArgInt, (LPVOID) &appData.serverPause, FALSE },\r
-  { "firstTimeOdds", ArgInt, (LPVOID) &appData.firstTimeOdds, FALSE },\r
-  { "secondTimeOdds", ArgInt, (LPVOID) &appData.secondTimeOdds, FALSE },\r
-  { "timeOddsMode", ArgInt, (LPVOID) &appData.timeOddsMode, TRUE },\r
-  { "firstAccumulateTC", ArgInt, (LPVOID) &appData.firstAccumulateTC, FALSE },\r
-  { "secondAccumulateTC", ArgInt, (LPVOID) &appData.secondAccumulateTC, FALSE },\r
-  { "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
+#define ICS_TEXT_MENU_SIZE (IDM_CommandXLast - IDM_CommandX + 1)\r
+#define XBOARD FALSE\r
 \r
+#define OPTCHAR "/"\r
+#define SEPCHAR "="\r
 \r
-/* Kludge for indirection files on command line */\r
-char* lastIndirectionFilename;\r
-ArgDescriptor argDescriptorIndirection =\r
-{ "", ArgSettingsFilename, (LPVOID) NULL, FALSE };\r
+#include "args.h"\r
 \r
+// front-end part of option handling\r
 \r
 VOID\r
-ExitArgError(char *msg, char *badArg)\r
+LFfromMFP(LOGFONT* lf, MyFontParams *mfp)\r
 {\r
-  char buf[MSG_SIZ];\r
+  HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL);\r
+  lf->lfHeight = -(int)(mfp->pointSize * GetDeviceCaps(hdc, LOGPIXELSY) / 72.0 + 0.5);\r
+  DeleteDC(hdc);\r
+  lf->lfWidth = 0;\r
+  lf->lfEscapement = 0;\r
+  lf->lfOrientation = 0;\r
+  lf->lfWeight = mfp->bold ? FW_BOLD : FW_NORMAL;\r
+  lf->lfItalic = mfp->italic;\r
+  lf->lfUnderline = mfp->underline;\r
+  lf->lfStrikeOut = mfp->strikeout;\r
+  lf->lfCharSet = mfp->charset;\r
+  lf->lfOutPrecision = OUT_DEFAULT_PRECIS;\r
+  lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;\r
+  lf->lfQuality = DEFAULT_QUALITY;\r
+  lf->lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;\r
+  strcpy(lf->lfFaceName, mfp->faceName);\r
+}\r
 \r
-  sprintf(buf, "%s %s", msg, badArg);\r
-  DisplayFatalError(buf, 0, 2);\r
-  exit(2);\r
+void\r
+CreateFontInMF(MyFont *mf)\r
+{ \r
+  LFfromMFP(&mf->lf, &mf->mfp);\r
+  if (mf->hf) DeleteObject(mf->hf);\r
+  mf->hf = CreateFontIndirect(&mf->lf);\r
 }\r
 \r
+// [HGM] This platform-dependent table provides the location for storing the color info\r
+void *\r
+colorVariable[] = {\r
+  &whitePieceColor, \r
+  &blackPieceColor, \r
+  &lightSquareColor,\r
+  &darkSquareColor, \r
+  &highlightSquareColor,\r
+  &premoveHighlightColor,\r
+  NULL,\r
+  &consoleBackgroundColor,\r
+  &appData.fontForeColorWhite,\r
+  &appData.fontBackColorWhite,\r
+  &appData.fontForeColorBlack,\r
+  &appData.fontBackColorBlack,\r
+  &appData.evalHistColorWhite,\r
+  &appData.evalHistColorBlack,\r
+  &appData.highlightArrowColor,\r
+};\r
+\r
 /* Command line font name parser.  NULL name means do nothing.\r
    Syntax like "Courier New:10.0 bi" or "Arial:10" or "Arial:10b"\r
    For backward compatibility, syntax without the colon is also\r
@@ -1486,7 +965,7 @@ ParseFontName(char *name, MyFontParams *mfp)
     while (*p && !isdigit(*p)) {\r
       *q++ = *p++;\r
       if (q - mfp->faceName >= sizeof(mfp->faceName))\r
-    ExitArgError("Font name too long:", name);\r
+       ExitArgError("Font name too long:", name);\r
     }\r
     while (q > mfp->faceName && q[-1] == ' ') q--;\r
     *q = NULLCHAR;\r
@@ -1497,8 +976,42 @@ ParseFontName(char *name, MyFontParams *mfp)
   mfp->italic = (strchr(p, 'i') != NULL);\r
   mfp->underline = (strchr(p, 'u') != NULL);\r
   mfp->strikeout = (strchr(p, 's') != NULL);\r
+  mfp->charset = DEFAULT_CHARSET;\r
+  q = strchr(p, 'c');\r
+  if (q)\r
+    mfp->charset = (BYTE) atoi(q+1);\r
+}\r
+\r
+void\r
+ParseFont(char *name, int number)\r
+{ // wrapper to shield back-end from 'font'\r
+  ParseFontName(name, &font[boardSize][number]->mfp);\r
+}\r
+\r
+void\r
+SetFontDefaults()\r
+{ // in WB  we have a 2D array of fonts; this initializes their description\r
+  int i, j;\r
+  /* Point font array elements to structures and\r
+     parse default font names */\r
+  for (i=0; i<NUM_FONTS; i++) {\r
+    for (j=0; j<NUM_SIZES; j++) {\r
+      font[j][i] = &fontRec[j][i];\r
+      ParseFontName(font[j][i]->def, &font[j][i]->mfp);\r
+    }\r
+  }\r
 }\r
 \r
+void\r
+CreateFonts()\r
+{ // here we create the actual fonts from the selected descriptions\r
+  int i, j;\r
+  for (i=0; i<NUM_FONTS; i++) {\r
+    for (j=0; j<NUM_SIZES; j++) {\r
+      CreateFontInMF(font[j][i]);\r
+    }\r
+  }\r
+}\r
 /* Color name parser.\r
    X version accepts X color names, but this one\r
    handles only the #rrggbb form (hex) or rrr,ggg,bbb (decimal) */\r
@@ -1510,7 +1023,7 @@ ParseColorName(char *name)
 \r
   count = sscanf(name, "#%2x%2x%2x", &red, &green, &blue);\r
   if (count != 3) {\r
-    count = sscanf(name, "%3d%*[^0-9]%3d%*[^0-9]%3d",\r
+    count = sscanf(name, "%3d%*[^0-9]%3d%*[^0-9]%3d", \r
       &red, &green, &blue);\r
   }\r
   if (count != 3) {\r
@@ -1521,8 +1034,14 @@ ParseColorName(char *name)
   return PALETTERGB(red, green, blue);\r
 }\r
 \r
+void\r
+ParseColor(int n, char *name)\r
+{ // for WinBoard the color is an int, which needs to be derived from the string\r
+  if(colorVariable[n]) *(int*)colorVariable[n] = ParseColorName(name);\r
+}\r
 \r
-void ParseAttribs(COLORREF *color, int *effects, char* argValue)\r
+void\r
+ParseAttribs(COLORREF *color, int *effects, char* argValue)\r
 {\r
   char *e = argValue;\r
   int eff = 0;\r
@@ -1539,495 +1058,52 @@ void ParseAttribs(COLORREF *color, int *effects, char* argValue)
   *color   = ParseColorName(e);\r
 }\r
 \r
+void\r
+ParseTextAttribs(ColorClass cc, char *s)\r
+{   // [HGM] front-end wrapper that does the platform-dependent call\r
+    // for XBoard we would set (&appData.colorShout)[cc] = strdup(s);\r
+    ParseAttribs(&textAttribs[cc].color, &textAttribs[cc].effects, s);\r
+}\r
 \r
-BoardSize\r
-ParseBoardSize(char *name)\r
-{\r
+void\r
+ParseBoardSize(void *addr, char *name)\r
+{ // [HGM] rewritten with return-value ptr to shield back-end from BoardSize\r
   BoardSize bs = SizeTiny;\r
   while (sizeInfo[bs].name != NULL) {\r
-    if (StrCaseCmp(name, sizeInfo[bs].name) == 0) return bs;\r
+    if (StrCaseCmp(name, sizeInfo[bs].name) == 0) {\r
+       *(BoardSize *)addr = bs;\r
+       return;\r
+    }\r
     bs++;\r
   }\r
   ExitArgError("Unrecognized board size value", name);\r
-  return bs; /* not reached */\r
 }\r
 \r
-\r
-char\r
-StringGet(void *getClosure)\r
-{\r
-  char **p = (char **) getClosure;\r
-  return *((*p)++);\r
-}\r
-\r
-char\r
-FileGet(void *getClosure)\r
-{\r
-  int c;\r
-  FILE* f = (FILE*) getClosure;\r
-\r
-  c = getc(f);\r
-  if (c == '\r') c = getc(f); // work around DOS format files by bypassing the '\r' completely\r
-  if (c == EOF)\r
-    return NULLCHAR;\r
-  else\r
-    return (char) c;\r
-}\r
-\r
-/* Parse settings file named "name". If file found, return the\r
-   full name in fullname and return TRUE; else return FALSE */\r
-BOOLEAN\r
-ParseSettingsFile(char *name, char fullname[MSG_SIZ])\r
-{\r
-  char *dummy;\r
-  FILE *f;\r
-  int ok; char buf[MSG_SIZ];\r
-\r
-  ok = SearchPath(installDir, name, NULL, MSG_SIZ, fullname, &dummy);\r
-  if(!ok && strchr(name, '.') == NULL) { // [HGM] append default file-name extension '.ini' when needed\r
-    sprintf(buf, "%s.ini", name);\r
-    ok = SearchPath(installDir, buf, NULL, MSG_SIZ, fullname, &dummy);\r
-  }\r
-  if (ok) {\r
-    f = fopen(fullname, "r");\r
-    if (f != NULL) {\r
-      ParseArgs(FileGet, f);\r
-      fclose(f);\r
-      return TRUE;\r
-    }\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID\r
-ParseArgs(GetFunc get, void *cl)\r
-{\r
-  char argName[ARG_MAX];\r
-  char argValue[ARG_MAX];\r
-  ArgDescriptor *ad;\r
-  char start;\r
-  char *q;\r
-  int i, octval;\r
-  char ch;\r
-  int posarg = 0;\r
-\r
-  ch = get(cl);\r
-  for (;;) {\r
-    while (ch == ' ' || ch == '\n' || ch == '\t') ch = get(cl);\r
-    if (ch == NULLCHAR) break;\r
-    if (ch == ';') {\r
-      /* Comment to end of line */\r
-      ch = get(cl);\r
-      while (ch != '\n' && ch != NULLCHAR) ch = get(cl);\r
-      continue;\r
-    } else if (ch == '/' || ch == '-') {\r
-      /* Switch */\r
-      q = argName;\r
-      while (ch != ' ' && ch != '=' && ch != ':' && ch != NULLCHAR &&\r
-         ch != '\n' && ch != '\t') {\r
-    *q++ = ch;\r
-    ch = get(cl);\r
-      }\r
-      *q = NULLCHAR;\r
-\r
-      for (ad = argDescriptors; ad->argName != NULL; ad++)\r
-    if (strcmp(ad->argName, argName + 1) == 0) break;\r
-\r
-      if (ad->argName == NULL)\r
-    ExitArgError("Unrecognized argument", argName);\r
-\r
-    } else if (ch == '@') {\r
-      /* Indirection file */\r
-      ad = &argDescriptorIndirection;\r
-      ch = get(cl);\r
-    } else {\r
-      /* Positional argument */\r
-      ad = &argDescriptors[posarg++];\r
-      strcpy(argName, ad->argName);\r
-    }\r
-\r
-    if (ad->argType == ArgTrue) {\r
-      *(Boolean *) ad->argLoc = TRUE;\r
-      continue;\r
-    }\r
-    if (ad->argType == ArgFalse) {\r
-      *(Boolean *) ad->argLoc = FALSE;\r
-      continue;\r
-    }\r
-\r
-    while (ch == ' ' || ch == '=' || ch == ':' || ch == '\t') ch = get(cl);\r
-    if (ch == NULLCHAR || ch == '\n') {\r
-      ExitArgError("No value provided for argument", argName);\r
-    }\r
-    q = argValue;\r
-    if (ch == '{') {\r
-      // Quoting with { }.  No characters have to (or can) be escaped.\r
-      // Thus the string cannot contain a '}' character.\r
-      start = ch;\r
-      ch = get(cl);\r
-      while (start) {\r
-    switch (ch) {\r
-    case NULLCHAR:\r
-      start = NULLCHAR;\r
-      break;\r
-\r
-    case '}':\r
-      ch = get(cl);\r
-      start = NULLCHAR;\r
-      break;\r
-\r
-    default:\r
-      *q++ = ch;\r
-      ch = get(cl);\r
-      break;\r
-    }\r
-      }\r
-    } else if (ch == '\'' || ch == '"') {\r
-      // Quoting with ' ' or " ", with \ as escape character.\r
-      // Inconvenient for long strings that may contain Windows filenames.\r
-      start = ch;\r
-      ch = get(cl);\r
-      while (start) {\r
-    switch (ch) {\r
-    case NULLCHAR:\r
-      start = NULLCHAR;\r
-      break;\r
-\r
-    default:\r
-        not_special:\r
-      *q++ = ch;\r
-      ch = get(cl);\r
-      break;\r
-\r
-    case '\'':\r
-    case '\"':\r
-      if (ch == start) {\r
-        ch = get(cl);\r
-        start = NULLCHAR;\r
-        break;\r
-      } else {\r
-        goto not_special;\r
-      }\r
-\r
-    case '\\':\r
-          if (ad->argType == ArgFilename\r
-          || ad->argType == ArgSettingsFilename) {\r
-          goto not_special;\r
-      }\r
-      ch = get(cl);\r
-      switch (ch) {\r
-      case NULLCHAR:\r
-        ExitArgError("Incomplete \\ escape in value for", argName);\r
-        break;\r
-      case 'n':\r
-        *q++ = '\n';\r
-        ch = get(cl);\r
-        break;\r
-      case 'r':\r
-        *q++ = '\r';\r
-        ch = get(cl);\r
-        break;\r
-      case 't':\r
-        *q++ = '\t';\r
-        ch = get(cl);\r
-        break;\r
-      case 'b':\r
-        *q++ = '\b';\r
-        ch = get(cl);\r
-        break;\r
-      case 'f':\r
-        *q++ = '\f';\r
-        ch = get(cl);\r
-        break;\r
-      default:\r
-        octval = 0;\r
-        for (i = 0; i < 3; i++) {\r
-          if (ch >= '0' && ch <= '7') {\r
-        octval = octval*8 + (ch - '0');\r
-        ch = get(cl);\r
-          } else {\r
-        break;\r
-          }\r
-        }\r
-        if (i > 0) {\r
-          *q++ = (char) octval;\r
-        } else {\r
-          *q++ = ch;\r
-          ch = get(cl);\r
-        }\r
-        break;\r
-      }\r
-      break;\r
-    }\r
-      }\r
-    } else {\r
-      while (ch != ' ' && ch != NULLCHAR && ch != '\t' && ch != '\n') {\r
-    *q++ = ch;\r
-    ch = get(cl);\r
-      }\r
-    }\r
-    *q = NULLCHAR;\r
-\r
-    switch (ad->argType) {\r
-    case ArgInt:\r
-      *(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
-\r
-    case ArgString:\r
-    case ArgFilename:\r
-      *(char **) ad->argLoc = strdup(argValue);\r
-      break;\r
-\r
-    case ArgSettingsFilename:\r
-      {\r
-    char fullname[MSG_SIZ];\r
-    if (ParseSettingsFile(argValue, fullname)) {\r
-      if (ad->argLoc != NULL) {\r
-        *(char **) ad->argLoc = strdup(fullname);\r
-      }\r
-    } else {\r
-      if (ad->argLoc != NULL) {\r
-      } else {\r
-        ExitArgError("Failed to open indirection file", argValue);\r
-      }\r
-    }\r
-      }\r
-      break;\r
-\r
-    case ArgBoolean:\r
-      switch (argValue[0]) {\r
-      case 't':\r
-      case 'T':\r
-    *(Boolean *) ad->argLoc = TRUE;\r
-    break;\r
-      case 'f':\r
-      case 'F':\r
-    *(Boolean *) ad->argLoc = FALSE;\r
-    break;\r
-      default:\r
-    ExitArgError("Unrecognized boolean argument value", argValue);\r
-    break;\r
-      }\r
-      break;\r
-\r
-    case ArgColor:\r
-      *(COLORREF *)ad->argLoc = ParseColorName(argValue);\r
-      break;\r
-\r
-    case ArgAttribs: {\r
-      ColorClass cc = (ColorClass)ad->argLoc;\r
-      ParseAttribs(&textAttribs[cc].color, &textAttribs[cc].effects, argValue);\r
-      }\r
-      break;\r
-\r
-    case ArgBoardSize:\r
-      *(BoardSize *)ad->argLoc = ParseBoardSize(argValue);\r
-      break;\r
-\r
-    case ArgFont:\r
-      ParseFontName(argValue, &font[boardSize][(int)ad->argLoc]->mfp);\r
-      break;\r
-\r
-    case ArgCommSettings:\r
-      ParseCommSettings(argValue, &dcb);\r
-      break;\r
-\r
-    case ArgNone:\r
-      ExitArgError("Unrecognized argument", argValue);\r
-      break;\r
-    case ArgTrue:\r
-    case ArgFalse: ;\r
-    }\r
-  }\r
-}\r
-\r
-VOID\r
-LFfromMFP(LOGFONT* lf, MyFontParams *mfp)\r
-{\r
-  HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL);\r
-  lf->lfHeight = -(int)(mfp->pointSize * GetDeviceCaps(hdc, LOGPIXELSY) / 72.0 + 0.5);\r
-  DeleteDC(hdc);\r
-  lf->lfWidth = 0;\r
-  lf->lfEscapement = 0;\r
-  lf->lfOrientation = 0;\r
-  lf->lfWeight = mfp->bold ? FW_BOLD : FW_NORMAL;\r
-  lf->lfItalic = mfp->italic;\r
-  lf->lfUnderline = mfp->underline;\r
-  lf->lfStrikeOut = mfp->strikeout;\r
-  lf->lfCharSet = DEFAULT_CHARSET;\r
-  lf->lfOutPrecision = OUT_DEFAULT_PRECIS;\r
-  lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;\r
-  lf->lfQuality = DEFAULT_QUALITY;\r
-  lf->lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;\r
-  strcpy(lf->lfFaceName, mfp->faceName);\r
-}\r
-\r
-VOID\r
-CreateFontInMF(MyFont *mf)\r
-{\r
-  LFfromMFP(&mf->lf, &mf->mfp);\r
-  if (mf->hf) DeleteObject(mf->hf);\r
-  mf->hf = CreateFontIndirect(&mf->lf);\r
-}\r
-\r
-VOID\r
-SetDefaultTextAttribs()\r
-{\r
-  ColorClass cc;\r
-  for (cc = (ColorClass)0; cc < NColorClasses; cc++) {\r
-    ParseAttribs(&textAttribs[cc].color,\r
-         &textAttribs[cc].effects,\r
-             defaultTextAttribs[cc]);\r
-  }\r
-}\r
-\r
-VOID\r
-SetDefaultSounds()\r
-{\r
+void\r
+LoadAllSounds()\r
+{ // [HGM] import name from appData first\r
   ColorClass cc;\r
   SoundClass sc;\r
-  for (cc = (ColorClass)0; cc < NColorClasses; cc++) {\r
+  for (cc = (ColorClass)0; cc < ColorNormal; cc++) {\r
+    textAttribs[cc].sound.name = strdup((&appData.soundShout)[cc]);\r
+    textAttribs[cc].sound.data = NULL;\r
+    MyLoadSound(&textAttribs[cc].sound);\r
+  }\r
+  for (cc = ColorNormal; cc < NColorClasses; cc++) {\r
     textAttribs[cc].sound.name = strdup("");\r
     textAttribs[cc].sound.data = NULL;\r
   }\r
   for (sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
-    sounds[sc].name = strdup("");\r
+    sounds[sc].name = strdup((&appData.soundMove)[sc]);\r
     sounds[sc].data = NULL;\r
-  }\r
-  sounds[(int)SoundBell].name = strdup(SOUND_BELL);\r
-}\r
-\r
-VOID\r
-LoadAllSounds()\r
-{\r
-  ColorClass cc;\r
-  SoundClass sc;\r
-  for (cc = (ColorClass)0; cc < NColorClasses; cc++) {\r
-    MyLoadSound(&textAttribs[cc].sound);\r
-  }\r
-  for (sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
     MyLoadSound(&sounds[sc]);\r
   }\r
 }\r
 \r
-VOID\r
-InitAppData(LPSTR lpCmdLine)\r
+void\r
+SetCommPortDefaults()\r
 {\r
-  int i, j;\r
-  char buf[ARG_MAX], currDir[MSG_SIZ];\r
-  char *dummy, *p;\r
-\r
-  programName = szAppName;\r
-\r
-  /* Initialize to defaults */\r
-  lightSquareColor = ParseColorName(LIGHT_SQUARE_COLOR);\r
-  darkSquareColor = ParseColorName(DARK_SQUARE_COLOR);\r
-  whitePieceColor = ParseColorName(WHITE_PIECE_COLOR);\r
-  blackPieceColor = ParseColorName(BLACK_PIECE_COLOR);\r
-  highlightSquareColor = ParseColorName(HIGHLIGHT_SQUARE_COLOR);\r
-  premoveHighlightColor = ParseColorName(PREMOVE_HIGHLIGHT_COLOR);\r
-  consoleBackgroundColor = ParseColorName(COLOR_BKGD);\r
-  SetDefaultTextAttribs();\r
-  SetDefaultSounds();\r
-  appData.movesPerSession = MOVES_PER_SESSION;\r
-  appData.initString = INIT_STRING;\r
-  appData.secondInitString = INIT_STRING;\r
-  appData.firstComputerString = COMPUTER_STRING;\r
-  appData.secondComputerString = COMPUTER_STRING;\r
-  appData.firstChessProgram = FIRST_CHESS_PROGRAM;\r
-  appData.secondChessProgram = SECOND_CHESS_PROGRAM;\r
-  appData.firstPlaysBlack = FALSE;\r
-  appData.noChessProgram = FALSE;\r
-  chessProgram = FALSE;\r
-  appData.firstHost = FIRST_HOST;\r
-  appData.secondHost = SECOND_HOST;\r
-  appData.firstDirectory = FIRST_DIRECTORY;\r
-  appData.secondDirectory = SECOND_DIRECTORY;\r
-  appData.bitmapDirectory = "";\r
-  appData.remoteShell = REMOTE_SHELL;\r
-  appData.remoteUser = "";\r
-  appData.timeDelay = TIME_DELAY;\r
-  appData.timeControl = TIME_CONTROL;\r
-  appData.timeIncrement = TIME_INCREMENT;\r
-  appData.icsActive = FALSE;\r
-  appData.icsHost = "";\r
-  appData.icsPort = ICS_PORT;\r
-  appData.icsCommPort = ICS_COMM_PORT;\r
-  appData.icsLogon = ICS_LOGON;\r
-  appData.icsHelper = "";\r
-  appData.useTelnet = FALSE;\r
-  appData.telnetProgram = TELNET_PROGRAM;\r
-  appData.gateway = "";\r
-  appData.loadGameFile = "";\r
-  appData.loadGameIndex = 0;\r
-  appData.saveGameFile = "";\r
-  appData.autoSaveGames = FALSE;\r
-  appData.loadPositionFile = "";\r
-  appData.loadPositionIndex = 1;\r
-  appData.savePositionFile = "";\r
-  appData.matchMode = FALSE;\r
-  appData.matchGames = 0;\r
-  appData.monoMode = FALSE;\r
-  appData.debugMode = FALSE;\r
-  appData.clockMode = TRUE;\r
-  boardSize = (BoardSize) -1; /* determine by screen size */\r
-  appData.Iconic = FALSE; /*unused*/\r
-  appData.searchTime = "";\r
-  appData.searchDepth = 0;\r
-  appData.showCoords = FALSE;\r
-  appData.ringBellAfterMoves = TRUE; /*obsolete in WinBoard*/\r
-  appData.autoCallFlag = FALSE;\r
-  appData.flipView = FALSE;\r
-  appData.autoFlipView = TRUE;\r
-  appData.cmailGameName = "";\r
-  appData.alwaysPromoteToQueen = FALSE;\r
-  appData.oldSaveStyle = FALSE;\r
-  appData.quietPlay = FALSE;\r
-  appData.showThinking = FALSE;\r
-  appData.ponderNextMove = TRUE;\r
-  appData.periodicUpdates = TRUE;\r
-  appData.popupExitMessage = TRUE;\r
-  appData.popupMoveErrors = FALSE;\r
-  appData.autoObserve = FALSE;\r
-  appData.autoComment = FALSE;\r
-  appData.animate = TRUE;\r
-  appData.animSpeed = 10;\r
-  appData.animateDragging = TRUE;\r
-  appData.highlightLastMove = TRUE;\r
-  appData.getMoveList = TRUE;\r
-  appData.testLegality = TRUE;\r
-  appData.premove = TRUE;\r
-  appData.premoveWhite = FALSE;\r
-  appData.premoveWhiteText = "";\r
-  appData.premoveBlack = FALSE;\r
-  appData.premoveBlackText = "";\r
-  appData.icsAlarm = TRUE;\r
-  appData.icsAlarmTime = 5000;\r
-  appData.autoRaiseBoard = TRUE;\r
-  appData.localLineEditing = TRUE;\r
-  appData.colorize = TRUE;\r
-  appData.reuseFirst = TRUE;\r
-  appData.reuseSecond = TRUE;\r
-  appData.blindfold = FALSE;\r
-  appData.icsEngineAnalyze = FALSE;\r
-  memset(&dcb, 0, sizeof(DCB)); // required by VS 2002 +\r
+   memset(&dcb, 0, sizeof(DCB)); // required by VS 2002 +\r
   dcb.DCBlength = sizeof(DCB);\r
   dcb.BaudRate = 9600;\r
   dcb.fBinary = TRUE;\r
@@ -2045,475 +1121,121 @@ InitAppData(LPSTR lpCmdLine)
   dcb.ByteSize = 7;\r
   dcb.Parity = SPACEPARITY;\r
   dcb.StopBits = ONESTOPBIT;\r
-  settingsFileName = SETTINGS_FILE;\r
-  saveSettingsOnExit = TRUE;\r
-  boardX = CW_USEDEFAULT;\r
-  boardY = CW_USEDEFAULT;\r
-  analysisX = CW_USEDEFAULT;\r
-  analysisY = CW_USEDEFAULT;\r
-  analysisW = CW_USEDEFAULT;\r
-  analysisH = CW_USEDEFAULT;\r
-  commentX = CW_USEDEFAULT;\r
-  commentY = CW_USEDEFAULT;\r
-  commentW = CW_USEDEFAULT;\r
-  commentH = CW_USEDEFAULT;\r
-  editTagsX = CW_USEDEFAULT;\r
-  editTagsY = CW_USEDEFAULT;\r
-  editTagsW = CW_USEDEFAULT;\r
-  editTagsH = CW_USEDEFAULT;\r
-  icsTextMenuString = ICS_TEXT_MENU_DEFAULT;\r
-  icsNames = ICS_NAMES;\r
-  firstChessProgramNames = FCP_NAMES;\r
-  secondChessProgramNames = SCP_NAMES;\r
-  appData.initialMode = "";\r
-  appData.variant = "normal";\r
-  appData.firstProtocolVersion = PROTOVER;\r
-  appData.secondProtocolVersion = PROTOVER;\r
-  appData.showButtonBar = TRUE;\r
-\r
-   /* [AS] New properties (see comments in header file) */\r
-  appData.firstScoreIsAbsolute = FALSE;\r
-  appData.secondScoreIsAbsolute = FALSE;\r
-  appData.saveExtendedInfoInPGN = FALSE;\r
-  appData.hideThinkingFromHuman = FALSE;\r
-  appData.liteBackTextureFile = "";\r
-  appData.liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
-  appData.darkBackTextureFile = "";\r
-  appData.darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
-  appData.renderPiecesWithFont = "";\r
-  appData.fontToPieceTable = "";\r
-  appData.fontBackColorWhite = 0;\r
-  appData.fontForeColorWhite = 0;\r
-  appData.fontBackColorBlack = 0;\r
-  appData.fontForeColorBlack = 0;\r
-  appData.fontPieceSize = 80;\r
-  appData.overrideLineGap = 1;\r
-  appData.adjudicateLossThreshold = 0;\r
-  appData.delayBeforeQuit = 0;\r
-  appData.delayAfterQuit = 0;\r
-  appData.nameOfDebugFile = "winboard.debug";\r
-  appData.pgnEventHeader = "Computer Chess Game";\r
-  appData.defaultFrcPosition = -1;\r
-  appData.gameListTags = GLT_DEFAULT_TAGS;\r
-  appData.saveOutOfBookInfo = TRUE;\r
-  appData.showEvalInMoveHistory = TRUE;\r
-  appData.evalHistColorWhite = ParseColorName( "#FFFFB0" );\r
-  appData.evalHistColorBlack = ParseColorName( "#AD5D3D" );\r
-  appData.highlightMoveWithArrow = FALSE;\r
-  appData.highlightArrowColor = ParseColorName( "#FFFF80" );\r
-  appData.useStickyWindows = TRUE;\r
-  appData.adjudicateDrawMoves = 0;\r
-  appData.autoDisplayComment = TRUE;\r
-  appData.autoDisplayTags = TRUE;\r
-  appData.firstIsUCI = FALSE;\r
-  appData.secondIsUCI = FALSE;\r
-  appData.firstHasOwnBookUCI = TRUE;\r
-  appData.secondHasOwnBookUCI = TRUE;\r
-  appData.polyglotDir = "";\r
-  appData.usePolyglotBook = FALSE;\r
-  appData.polyglotBook = "";\r
-  appData.defaultHashSize = 64;\r
-  appData.defaultCacheSizeEGTB = 4;\r
-  appData.defaultPathEGTB = "c:\\egtb";\r
-  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
-  appData.NrRanks      = -1;\r
-  appData.holdingsSize = -1;\r
-  appData.testClaims   = FALSE;\r
-  appData.checkMates   = FALSE;\r
-  appData.materialDraws= FALSE;\r
-  appData.trivialDraws = FALSE;\r
-  appData.ruleMoves    = 51;\r
-  appData.drawRepeats  = 6;\r
-  appData.matchPause   = 10000;\r
-  appData.alphaRank    = FALSE;\r
-  appData.allWhite     = FALSE;\r
-  appData.upsideDown   = FALSE;\r
-  appData.serverPause  = 15;\r
-  appData.serverMovesName   = NULL;\r
-  appData.suppressLoadMoves = FALSE;\r
-  appData.firstTimeOdds  = 1;\r
-  appData.secondTimeOdds = 1;\r
-  appData.firstAccumulateTC  = 1; // combine previous and current sessions\r
-  appData.secondAccumulateTC = 1;\r
-  appData.firstNPS  = -1; // [HGM] nps: use wall-clock time\r
-  appData.secondNPS = -1;\r
-  appData.engineComments = 1;\r
-  appData.smpCores = 1; // [HGM] SMP: max nr of cores\r
-  appData.egtFormats = "";\r
-\r
-#ifdef ZIPPY\r
-  appData.zippyTalk = ZIPPY_TALK;\r
-  appData.zippyPlay = ZIPPY_PLAY;\r
-  appData.zippyLines = ZIPPY_LINES;\r
-  appData.zippyPinhead = ZIPPY_PINHEAD;\r
-  appData.zippyPassword = ZIPPY_PASSWORD;\r
-  appData.zippyPassword2 = ZIPPY_PASSWORD2;\r
-  appData.zippyWrongPassword = ZIPPY_WRONG_PASSWORD;\r
-  appData.zippyAcceptOnly = ZIPPY_ACCEPT_ONLY;\r
-  appData.zippyUseI = ZIPPY_USE_I;\r
-  appData.zippyBughouse = ZIPPY_BUGHOUSE;\r
-  appData.zippyNoplayCrafty = ZIPPY_NOPLAY_CRAFTY;\r
-  appData.zippyGameEnd = ZIPPY_GAME_END;\r
-  appData.zippyGameStart = ZIPPY_GAME_START;\r
-  appData.zippyAdjourn = ZIPPY_ADJOURN;\r
-  appData.zippyAbort = ZIPPY_ABORT;\r
-  appData.zippyVariants = ZIPPY_VARIANTS;\r
-  appData.zippyMaxGames = ZIPPY_MAX_GAMES;\r
-  appData.zippyReplayTimeout = ZIPPY_REPLAY_TIMEOUT;\r
-#endif\r
-\r
-  /* Point font array elements to structures and\r
-     parse default font names */\r
-  for (i=0; i<NUM_FONTS; i++) {\r
-    for (j=0; j<NUM_SIZES; j++) {\r
-      font[j][i] = &fontRec[j][i];\r
-      ParseFontName(font[j][i]->def, &font[j][i]->mfp);\r
-    }\r
-  }\r
-\r
-  /* Parse default settings file if any */\r
-  if (ParseSettingsFile(settingsFileName, buf)) {\r
-    settingsFileName = strdup(buf);\r
-  }\r
-\r
-  /* Parse command line */\r
-  ParseArgs(StringGet, &lpCmdLine);\r
-\r
-  /* [HGM] make sure board size is acceptable */\r
-  if(appData.NrFiles > BOARD_SIZE ||\r
-     appData.NrRanks > BOARD_SIZE   )\r
-      DisplayFatalError("Recompile with BOARD_SIZE > 12, to support this size", 0, 2);\r
+}\r
 \r
-  /* [HGM] After parsing the options from the .ini file, and overruling them\r
-   * with options from the command line, we now make an even higher priority\r
-   * overrule by WB options attached to the engine command line. This so that\r
-   * tournament managers can use WB options (such as /timeOdds) that follow\r
-   * the engines.\r
-   */\r
-  if(appData.firstChessProgram != NULL) {\r
-      char *p = StrStr(appData.firstChessProgram, "WBopt");\r
-      static char *f = "first";\r
-      char buf[MSG_SIZ], *q = buf;\r
-      if(p != NULL) { // engine command line contains WinBoard options\r
-          sprintf(buf, p+6, f, f, f, f, f, f, f, f, f, f); // replace %s in them by "first"\r
-          ParseArgs(StringGet, &q);\r
-          p[-1] = 0; // cut them offengine command line\r
-      }\r
-  }\r
-  // now do same for second chess program\r
-  if(appData.secondChessProgram != NULL) {\r
-      char *p = StrStr(appData.secondChessProgram, "WBopt");\r
-      static char *s = "second";\r
-      char buf[MSG_SIZ], *q = buf;\r
-      if(p != NULL) { // engine command line contains WinBoard options\r
-          sprintf(buf, p+6, s, s, s, s, s, s, s, s, s, s); // replace %s in them by "first"\r
-          ParseArgs(StringGet, &q);\r
-          p[-1] = 0; // cut them offengine command line\r
+// [HGM] args: these three cases taken out to stay in front-end\r
+void\r
+SaveFontArg(FILE *f, ArgDescriptor *ad)\r
+{      // in WinBoard every board size has its own font, and the "argLoc" identifies the table,\r
+       // while the curent board size determines the element. This system should be ported to XBoard.\r
+       // What the table contains pointers to, and how to print the font description, remains platform-dependent\r
+        int bs;\r
+       for (bs=0; bs<NUM_SIZES; bs++) {\r
+         MyFontParams *mfp = &font[bs][(int) ad->argLoc]->mfp;\r
+          fprintf(f, "/size=%s ", sizeInfo[bs].name);\r
+         fprintf(f, "/%s=\"%s:%g%s%s%s%s%sc%d\"\n",\r
+           ad->argName, mfp->faceName, mfp->pointSize,\r
+            mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "",\r
+           mfp->bold ? "b" : "",\r
+           mfp->italic ? "i" : "",\r
+           mfp->underline ? "u" : "",\r
+           mfp->strikeout ? "s" : "",\r
+            (int)mfp->charset);\r
+       }\r
       }\r
-  }\r
-\r
 \r
-  /* Propagate options that affect others */\r
-  if (appData.matchMode || appData.matchGames) chessProgram = TRUE;\r
-  if (appData.icsActive || appData.noChessProgram) {\r
-     chessProgram = FALSE;  /* not local chess program mode */\r
-  }\r
+void\r
+ExportSounds()\r
+{ // [HGM] copy the names from the internal WB variables to appData\r
+  ColorClass cc;\r
+  SoundClass sc;\r
+  for (cc = (ColorClass)0; cc < ColorNormal; cc++)\r
+    (&appData.soundShout)[cc] = textAttribs[cc].sound.name;\r
+  for (sc = (SoundClass)0; sc < NSoundClasses; sc++)\r
+    (&appData.soundMove)[sc] = sounds[sc].name;\r
+}\r
 \r
-  /* Open startup dialog if needed */\r
-  if ((!appData.noChessProgram && !chessProgram && !appData.icsActive) ||\r
-      (appData.icsActive && *appData.icsHost == NULLCHAR) ||\r
-      (chessProgram && (*appData.firstChessProgram == NULLCHAR ||\r
-                        *appData.secondChessProgram == NULLCHAR))) {\r
-    FARPROC lpProc;\r
+void\r
+SaveAttribsArg(FILE *f, ArgDescriptor *ad)\r
+{      // here the "argLoc" defines a table index. It could have contained the 'ta' pointer itself, though\r
+       MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc];\r
+       fprintf(f, "/%s=\"%s%s%s%s%s#%02lx%02lx%02lx\"\n", ad->argName,\r
+          (ta->effects & CFE_BOLD) ? "b" : "",\r
+          (ta->effects & CFE_ITALIC) ? "i" : "",\r
+          (ta->effects & CFE_UNDERLINE) ? "u" : "",\r
+          (ta->effects & CFE_STRIKEOUT) ? "s" : "",\r
+          (ta->effects) ? " " : "",\r
+         ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff);\r
+      }\r
 \r
-    lpProc = MakeProcInstance((FARPROC)StartupDialog, hInst);\r
-    DialogBox(hInst, MAKEINTRESOURCE(DLG_Startup), NULL, (DLGPROC)lpProc);\r
-    FreeProcInstance(lpProc);\r
-  }\r
+void\r
+SaveColor(FILE *f, ArgDescriptor *ad)\r
+{      // in WinBoard the color is an int and has to be converted to text. In X it would be a string already?\r
+       COLORREF color = *(COLORREF *)colorVariable[(int)ad->argLoc];\r
+       fprintf(f, "/%s=#%02lx%02lx%02lx\n", ad->argName, \r
+         color&0xff, (color>>8)&0xff, (color>>16)&0xff);\r
+}\r
 \r
-  /* Make sure save files land in the right (?) directory */\r
-  if (GetFullPathName(appData.saveGameFile, MSG_SIZ, buf, &dummy)) {\r
-    appData.saveGameFile = strdup(buf);\r
-  }\r
-  if (GetFullPathName(appData.savePositionFile, MSG_SIZ, buf, &dummy)) {\r
-    appData.savePositionFile = strdup(buf);\r
-  }\r
+void\r
+SaveBoardSize(FILE *f, char *name, void *addr)\r
+{ // wrapper to shield back-end from BoardSize & sizeInfo\r
+  fprintf(f, "/%s=%s\n", name, sizeInfo[*(BoardSize *)addr].name);\r
+}\r
 \r
-  /* Finish initialization for fonts and sounds */\r
-  for (i=0; i<NUM_FONTS; i++) {\r
-    for (j=0; j<NUM_SIZES; j++) {\r
-      CreateFontInMF(font[j][i]);\r
-    }\r
-  }\r
-  /* xboard, and older WinBoards, controlled the move sound with the\r
-     appData.ringBellAfterMoves option.  In the current WinBoard, we\r
-     always turn the option on (so that the backend will call us),\r
-     then let the user turn the sound off by setting it to silence if\r
-     desired.  To accommodate old winboard.ini files saved by old\r
-     versions of WinBoard, we also turn off the sound if the option\r
-     was initially set to false. */\r
-  if (!appData.ringBellAfterMoves) {\r
-    sounds[(int)SoundMove].name = strdup("");\r
-    appData.ringBellAfterMoves = TRUE;\r
-  }\r
-  GetCurrentDirectory(MSG_SIZ, currDir);\r
-  SetCurrentDirectory(installDir);\r
-  LoadAllSounds();\r
-  SetCurrentDirectory(currDir);\r
+void\r
+ParseCommPortSettings(char *s)\r
+{ // wrapper to keep dcb from back-end\r
+  ParseCommSettings(s, &dcb);\r
+}\r
 \r
-  p = icsTextMenuString;\r
-  if (p[0] == '@') {\r
-    FILE* f = fopen(p + 1, "r");\r
-    if (f == NULL) {\r
-      DisplayFatalError(p + 1, errno, 2);\r
-      return;\r
-    }\r
-    i = fread(buf, 1, sizeof(buf)-1, f);\r
-    fclose(f);\r
-    buf[i] = NULLCHAR;\r
-    p = buf;\r
-  }\r
-  ParseIcsTextMenu(strdup(p));\r
+void\r
+GetWindowCoords()\r
+{ // wrapper to shield use of window handles from back-end (make addressible by number?)\r
+  GetActualPlacement(hwndMain, &wpMain);\r
+  GetActualPlacement(hwndConsole, &wpConsole);\r
+  GetActualPlacement(commentDialog, &wpComment);\r
+  GetActualPlacement(editTagsDialog, &wpTags);\r
+  GetActualPlacement(gameListDialog, &wpGameList);\r
+  GetActualPlacement(moveHistoryDialog, &wpMoveHistory);\r
+  GetActualPlacement(evalGraphDialog, &wpEvalGraph);\r
+  GetActualPlacement(engineOutputDialog, &wpEngineOutput);\r
 }\r
 \r
+void\r
+PrintCommPortSettings(FILE *f, char *name)\r
+{ // wrapper to shield back-end from DCB\r
+      PrintCommSettings(f, name, &dcb);\r
+}\r
 \r
-VOID\r
-InitMenuChecks()\r
+int\r
+MySearchPath(char *installDir, char *name, char *fullname)\r
 {\r
-  HMENU hmenu = GetMenu(hwndMain);\r
-\r
-  (void) EnableMenuItem(hmenu, IDM_CommPort,\r
-            MF_BYCOMMAND|((appData.icsActive &&\r
-                       *appData.icsCommPort != NULLCHAR) ?\r
-                      MF_ENABLED : MF_GRAYED));\r
-  (void) CheckMenuItem(hmenu, IDM_SaveSettingsOnExit,\r
-               MF_BYCOMMAND|(saveSettingsOnExit ?\r
-                     MF_CHECKED : MF_UNCHECKED));\r
+  char *dummy;\r
+  return (int) SearchPath(installDir, name, NULL, MSG_SIZ, fullname, &dummy);\r
 }\r
 \r
-\r
-VOID\r
-SaveSettings(char* name)\r
+int\r
+MyGetFullPathName(char *name, char *fullname)\r
 {\r
-  FILE *f;\r
-  ArgDescriptor *ad;\r
-  WINDOWPLACEMENT wp;\r
-  char dir[MSG_SIZ];\r
-\r
-  if (!hwndMain) return;\r
-\r
-  GetCurrentDirectory(MSG_SIZ, dir);\r
-  SetCurrentDirectory(installDir);\r
-  f = fopen(name, "w");\r
-  SetCurrentDirectory(dir);\r
-  if (f == NULL) {\r
-    DisplayError(name, errno);\r
-    return;\r
-  }\r
-  fprintf(f, ";\n");\r
-  fprintf(f, "; %s Save Settings file\n", PACKAGE_STRING);\r
-  fprintf(f, ";\n");\r
-  fprintf(f, "; You can edit the values of options that are already set in this file,\n");\r
-  fprintf(f, "; but if you add other options, the next Save Settings will not save them.\n");\r
-  fprintf(f, "; Use a shortcut, an @indirection file, or a .bat file instead.\n");\r
-  fprintf(f, ";\n");\r
-\r
-  wp.length = sizeof(WINDOWPLACEMENT);\r
-  GetWindowPlacement(hwndMain, &wp);\r
-  boardX = wp.rcNormalPosition.left;\r
-  boardY = wp.rcNormalPosition.top;\r
-\r
-  if (hwndConsole) {\r
-    GetWindowPlacement(hwndConsole, &wp);\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
-    GetWindowPlacement(analysisDialog, &wp);\r
-    analysisX = wp.rcNormalPosition.left;\r
-    analysisY = wp.rcNormalPosition.top;\r
-    analysisW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    analysisH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  if (commentDialog) {\r
-    GetWindowPlacement(commentDialog, &wp);\r
-    commentX = wp.rcNormalPosition.left;\r
-    commentY = wp.rcNormalPosition.top;\r
-    commentW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    commentH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  if (editTagsDialog) {\r
-    GetWindowPlacement(editTagsDialog, &wp);\r
-    editTagsX = wp.rcNormalPosition.left;\r
-    editTagsY = wp.rcNormalPosition.top;\r
-    editTagsW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    editTagsH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  if (gameListDialog) {\r
-    GetWindowPlacement(gameListDialog, &wp);\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
-  wpMoveHistory.visible = MoveHistoryIsUp();\r
-\r
-  if( moveHistoryDialog ) {\r
-    GetWindowPlacement(moveHistoryDialog, &wp);\r
-    wpMoveHistory.x = wp.rcNormalPosition.left;\r
-    wpMoveHistory.y = wp.rcNormalPosition.top;\r
-    wpMoveHistory.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    wpMoveHistory.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  /* [AS] Eval graph */\r
-  wpEvalGraph.visible = EvalGraphIsUp();\r
-\r
-  if( evalGraphDialog ) {\r
-    GetWindowPlacement(evalGraphDialog, &wp);\r
-    wpEvalGraph.x = wp.rcNormalPosition.left;\r
-    wpEvalGraph.y = wp.rcNormalPosition.top;\r
-    wpEvalGraph.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    wpEvalGraph.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  /* [AS] Engine output */\r
-  wpEngineOutput.visible = EngineOutputIsUp();\r
-\r
-  if( engineOutputDialog ) {\r
-    GetWindowPlacement(engineOutputDialog, &wp);\r
-    wpEngineOutput.x = wp.rcNormalPosition.left;\r
-    wpEngineOutput.y = wp.rcNormalPosition.top;\r
-    wpEngineOutput.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    wpEngineOutput.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  for (ad = argDescriptors; ad->argName != NULL; ad++) {\r
-    if (!ad->save) continue;\r
-    switch (ad->argType) {\r
-    case ArgString:\r
-      {\r
-    char *p = *(char **)ad->argLoc;\r
-    if ((strchr(p, '\\') || strchr(p, '\n')) && !strchr(p, '}')) {\r
-      /* Quote multiline values or \-containing values\r
-         with { } if possible */\r
-      fprintf(f, "/%s={%s}\n", ad->argName, p);\r
-    } else {\r
-      /* Else quote with " " */\r
-      fprintf(f, "/%s=\"", ad->argName);\r
-      while (*p) {\r
-        if (*p == '\n') fprintf(f, "\n");\r
-        else if (*p == '\r') fprintf(f, "\\r");\r
-        else if (*p == '\t') fprintf(f, "\\t");\r
-        else if (*p == '\b') fprintf(f, "\\b");\r
-        else if (*p == '\f') fprintf(f, "\\f");\r
-        else if (*p < ' ') fprintf(f, "\\%03o", *p);\r
-        else if (*p == '\"') fprintf(f, "\\\"");\r
-        else if (*p == '\\') fprintf(f, "\\\\");\r
-        else putc(*p, f);\r
-        p++;\r
-      }\r
-      fprintf(f, "\"\n");\r
-    }\r
-      }\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
-    case ArgBoolean:\r
-      fprintf(f, "/%s=%s\n", ad->argName,\r
-    (*(Boolean *)ad->argLoc) ? "true" : "false");\r
-      break;\r
-    case ArgTrue:\r
-      if (*(Boolean *)ad->argLoc) fprintf(f, "/%s\n", ad->argName);\r
-      break;\r
-    case ArgFalse:\r
-      if (!*(Boolean *)ad->argLoc) fprintf(f, "/%s\n", ad->argName);\r
-      break;\r
-    case ArgColor:\r
-      {\r
-    COLORREF color = *(COLORREF *)ad->argLoc;\r
-    fprintf(f, "/%s=#%02lx%02lx%02lx\n", ad->argName,\r
-      color&0xff, (color>>8)&0xff, (color>>16)&0xff);\r
-      }\r
-      break;\r
-    case ArgAttribs:\r
-      {\r
-    MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc];\r
-    fprintf(f, "/%s=\"%s%s%s%s%s#%02lx%02lx%02lx\"\n", ad->argName,\r
-          (ta->effects & CFE_BOLD) ? "b" : "",\r
-          (ta->effects & CFE_ITALIC) ? "i" : "",\r
-          (ta->effects & CFE_UNDERLINE) ? "u" : "",\r
-          (ta->effects & CFE_STRIKEOUT) ? "s" : "",\r
-          (ta->effects) ? " " : "",\r
-      ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff);\r
-      }\r
-      break;\r
-    case ArgFilename:\r
-      if (strchr(*(char **)ad->argLoc, '\"')) {\r
-    fprintf(f, "/%s='%s'\n", ad->argName, *(char **)ad->argLoc);\r
-      } else {\r
-    fprintf(f, "/%s=\"%s\"\n", ad->argName, *(char **)ad->argLoc);\r
-      }\r
-      break;\r
-    case ArgBoardSize:\r
-      fprintf(f, "/%s=%s\n", ad->argName,\r
-          sizeInfo[*(BoardSize *)ad->argLoc].name);\r
-      break;\r
-    case ArgFont:\r
-      {\r
-        int bs;\r
-    for (bs=0; bs<NUM_SIZES; bs++) {\r
-      MyFontParams *mfp = &font[bs][(int) ad->argLoc]->mfp;\r
-          fprintf(f, "/size=%s ", sizeInfo[bs].name);\r
-      fprintf(f, "/%s=\"%s:%g%s%s%s%s%s\"\n",\r
-        ad->argName, mfp->faceName, mfp->pointSize,\r
-            mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "",\r
-        mfp->bold ? "b" : "",\r
-        mfp->italic ? "i" : "",\r
-        mfp->underline ? "u" : "",\r
-        mfp->strikeout ? "s" : "");\r
-    }\r
-      }\r
-      break;\r
-    case ArgCommSettings:\r
-      PrintCommSettings(f, ad->argName, (DCB *)ad->argLoc);\r
-    case ArgNone:\r
-    case ArgSettingsFilename: ;\r
-    }\r
-  }\r
-  fclose(f);\r
+  char *dummy;\r
+  return (int) GetFullPathName(name, MSG_SIZ, fullname, &dummy);\r
 }\r
 \r
+int\r
+MainWindowUp()\r
+{ // [HGM] args: allows testing if main window is realized from back-end\r
+  return hwndMain != NULL;\r
+}\r
 \r
+void\r
+PopUpStartupDialog()\r
+{\r
+    FARPROC lpProc;\r
+    \r
+    lpProc = MakeProcInstance((FARPROC)StartupDialog, hInst);\r
+    DialogBox(hInst, MAKEINTRESOURCE(DLG_Startup), NULL, (DLGPROC)lpProc);\r
+    FreeProcInstance(lpProc);\r
+}\r
 \r
 /*---------------------------------------------------------------------------*\\r
  *\r
@@ -2587,43 +1309,43 @@ static void DrawTile( int dx, int dy, int dw, int dh, HDC dst, HDC src, int mode
 \r
 /* [AS] [HGM] Make room for more piece types, so all pieces can be different */\r
 enum {\r
-    PM_WP = (int) WhitePawn,\r
-    PM_WN = (int) WhiteKnight,\r
-    PM_WB = (int) WhiteBishop,\r
-    PM_WR = (int) WhiteRook,\r
-    PM_WQ = (int) WhiteQueen,\r
-    PM_WF = (int) WhiteFerz,\r
-    PM_WW = (int) WhiteWazir,\r
-    PM_WE = (int) WhiteAlfil,\r
-    PM_WM = (int) WhiteMan,\r
-    PM_WO = (int) WhiteCannon,\r
-    PM_WU = (int) WhiteUnicorn,\r
-    PM_WH = (int) WhiteNightrider,\r
-    PM_WA = (int) WhiteAngel,\r
-    PM_WC = (int) WhiteMarshall,\r
-    PM_WAB = (int) WhiteCardinal,\r
-    PM_WD = (int) WhiteDragon,\r
-    PM_WL = (int) WhiteLance,\r
-    PM_WS = (int) WhiteCobra,\r
-    PM_WV = (int) WhiteFalcon,\r
-    PM_WSG = (int) WhiteSilver,\r
-    PM_WG = (int) WhiteGrasshopper,\r
+    PM_WP = (int) WhitePawn, \r
+    PM_WN = (int) WhiteKnight, \r
+    PM_WB = (int) WhiteBishop, \r
+    PM_WR = (int) WhiteRook, \r
+    PM_WQ = (int) WhiteQueen, \r
+    PM_WF = (int) WhiteFerz, \r
+    PM_WW = (int) WhiteWazir, \r
+    PM_WE = (int) WhiteAlfil, \r
+    PM_WM = (int) WhiteMan, \r
+    PM_WO = (int) WhiteCannon, \r
+    PM_WU = (int) WhiteUnicorn, \r
+    PM_WH = (int) WhiteNightrider, \r
+    PM_WA = (int) WhiteAngel, \r
+    PM_WC = (int) WhiteMarshall, \r
+    PM_WAB = (int) WhiteCardinal, \r
+    PM_WD = (int) WhiteDragon, \r
+    PM_WL = (int) WhiteLance, \r
+    PM_WS = (int) WhiteCobra, \r
+    PM_WV = (int) WhiteFalcon, \r
+    PM_WSG = (int) WhiteSilver, \r
+    PM_WG = (int) WhiteGrasshopper, \r
     PM_WK = (int) WhiteKing,\r
-    PM_BP = (int) BlackPawn,\r
-    PM_BN = (int) BlackKnight,\r
-    PM_BB = (int) BlackBishop,\r
-    PM_BR = (int) BlackRook,\r
-    PM_BQ = (int) BlackQueen,\r
-    PM_BF = (int) BlackFerz,\r
-    PM_BW = (int) BlackWazir,\r
-    PM_BE = (int) BlackAlfil,\r
+    PM_BP = (int) BlackPawn, \r
+    PM_BN = (int) BlackKnight, \r
+    PM_BB = (int) BlackBishop, \r
+    PM_BR = (int) BlackRook, \r
+    PM_BQ = (int) BlackQueen, \r
+    PM_BF = (int) BlackFerz, \r
+    PM_BW = (int) BlackWazir, \r
+    PM_BE = (int) BlackAlfil, \r
     PM_BM = (int) BlackMan,\r
-    PM_BO = (int) BlackCannon,\r
-    PM_BU = (int) BlackUnicorn,\r
-    PM_BH = (int) BlackNightrider,\r
-    PM_BA = (int) BlackAngel,\r
-    PM_BC = (int) BlackMarshall,\r
-    PM_BG = (int) BlackGrasshopper,\r
+    PM_BO = (int) BlackCannon, \r
+    PM_BU = (int) BlackUnicorn, \r
+    PM_BH = (int) BlackNightrider, \r
+    PM_BA = (int) BlackAngel, \r
+    PM_BC = (int) BlackMarshall, \r
+    PM_BG = (int) BlackGrasshopper, \r
     PM_BAB = (int) BlackCardinal,\r
     PM_BD = (int) BlackDragon,\r
     PM_BL = (int) BlackLance,\r
@@ -2638,9 +1360,9 @@ static HBITMAP hPieceMask[(int) EmptySquare];
 static HBITMAP hPieceFace[(int) EmptySquare];\r
 static int fontBitmapSquareSize = 0;\r
 static char pieceToFontChar[(int) EmptySquare] =\r
-                              { 'p', 'n', 'b', 'r', 'q',\r
+                              { 'p', 'n', 'b', 'r', 'q', \r
                       'n', 'b', 'p', 'n', 'b', 'r', 'b', 'r', 'q', 'k',\r
-                      'k', 'o', 'm', 'v', 't', 'w',\r
+                      'k', 'o', 'm', 'v', 't', 'w', \r
                       'v', 't', 'o', 'm', 'v', 't', 'v', 't', 'w', 'l',\r
                                                               'l' };\r
 \r
@@ -2663,7 +1385,7 @@ static void SetPieceBackground( HDC hdc, COLORREF color, int mode )
     SetRect( &rc, 0, 0, squareSize, squareSize );\r
     FillRect( hdc, &rc, hbrush );\r
     DeleteObject( hbrush );\r
-\r
+    \r
     if( mode == 1 ) {\r
         /* Vertical gradient, good for pawn, knight and rook, less for queen and king */\r
         int steps = squareSize / 2;\r
@@ -2726,9 +1448,9 @@ static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index )
     RECT rc;\r
     SIZE sz;\r
     POINT pt;\r
-    int backColor = whitePieceColor;\r
+    int backColor = whitePieceColor; \r
     int foreColor = blackPieceColor;\r
-\r
+    \r
     if( index < (int)BlackPawn && appData.fontBackColorWhite != appData.fontForeColorWhite ) {\r
         backColor = appData.fontBackColorWhite;\r
         foreColor = appData.fontForeColorWhite;\r
@@ -2769,7 +1491,7 @@ static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index )
     ExtFloodFill( hdc, squareSize-1, 0, 0, FLOODFILLSURFACE );\r
     ExtFloodFill( hdc, squareSize-1, squareSize-1, 0, FLOODFILLSURFACE );\r
     SelectObject( hdc, GetStockObject(BLACK_BRUSH) );\r
-    /*\r
+    /* \r
         Step 4: this is the tricky part, the area inside the piece is filled with black,\r
         but if the start point is not inside the piece we're lost!\r
         There should be a better way to do this... if we could create a region or path\r
@@ -2794,7 +1516,7 @@ static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index )
     }\r
 \r
     SetTextColor( hdc, 0 );\r
-    /*\r
+    /* \r
         Step 5: some fonts have "disconnected" areas that are skipped by the fill:\r
         draw the piece again in black for safety.\r
     */\r
@@ -2822,8 +1544,8 @@ static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index )
         SelectObject( dc2, bm2 );\r
         FillRect( dc2, &rc, GetStockObject(WHITE_BRUSH) );\r
         BitBlt( dc2, 0, 0, squareSize, squareSize, dc1, 0, 0, SRCINVERT );\r
-\r
-        /*\r
+        \r
+        /* \r
             Now dc2 contains the inverse of the piece mask, i.e. a mask that preserves\r
             the piece background and deletes (makes transparent) the rest.\r
             Thanks to that mask, we are free to paint the background with the greates\r
@@ -3028,7 +1750,7 @@ void CreatePiecesFromFont()
                 }\r
                 else if( strstr(lf.lfFaceName,"GC2004D") != NULL ) {\r
                     /* Good Companion (Some characters get warped as literal :-( */\r
-                    char s[] = "1cmWG0ñueOS¯®oYI23wgQU";\r
+                    char s[] = "1cmWG0??S??oYI23wgQU";\r
                     s[0]=0xB9; s[1]=0xA9; s[6]=0xB1; s[11]=0xBB; s[12]=0xAB; s[17]=0xB3;\r
                     SetCharTable(pieceToFontChar, s);\r
                 }\r
@@ -3040,57 +1762,10 @@ void CreatePiecesFromFont()
 \r
             /* Create bitmaps */\r
             hfont_old = SelectObject( hdc, hPieceFont );\r
-#if 0\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WP );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WN );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WB );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WR );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WQ );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WK );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BP );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BN );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BB );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BR );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BQ );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BK );\r
-\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WA );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WC );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WF );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WH );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WE );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WW );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WU );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WO );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WG );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WM );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WSG );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WV );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WAB );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WD );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WL );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_WS );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BA );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BC );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BF );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BH );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BE );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BW );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BU );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BO );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BG );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BM );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BSG );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BV );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BAB );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BD );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BL );\r
-            CreatePieceMaskFromFont( hdc_window, hdc, PM_BS );\r
-#else\r
-        for(i=(int)WhitePawn; i<(int)EmptySquare; i++) /* [HGM] made a loop for this */\r
-        if(PieceToChar((ChessSquare)i) != '.')     /* skip unused pieces         */\r
-            CreatePieceMaskFromFont( hdc_window, hdc, i );\r
-#endif\r
+           for(i=(int)WhitePawn; i<(int)EmptySquare; i++) /* [HGM] made a loop for this */\r
+               if(PieceToChar((ChessSquare)i) != '.')     /* skip unused pieces         */\r
+                   CreatePieceMaskFromFont( hdc_window, hdc, i );\r
+\r
             SelectObject( hdc, hfont_old );\r
 \r
             fontBitmapSquareSize = squareSize;\r
@@ -3155,7 +1830,7 @@ InitDrawingColors()
      */\r
     pLogPal = (NPLOGPALETTE)\r
       LocalAlloc(LMEM_FIXED, (sizeof(LOGPALETTE) +\r
-                  (sizeof(PALETTEENTRY) * (PALETTESIZE))));\r
+                             (sizeof(PALETTEENTRY) * (PALETTESIZE))));\r
     pLogPal->palVersion    = 0x300;\r
   }\r
   pLogPal->palNumEntries = 0;\r
@@ -3179,6 +1854,7 @@ InitDrawingColors()
   blackPieceBrush = CreateSolidBrush(blackPieceColor);\r
   iconBkgndBrush = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));\r
   explodeBrush = CreateSolidBrush(highlightSquareColor); // [HGM] atomic\r
+  markerBrush = CreateSolidBrush(premoveHighlightColor); // [HGM] markers\r
   /* [AS] Force rendering of the font-based pieces */\r
   if( fontBitmapSquareSize > 0 ) {\r
     fontBitmapSquareSize = 0;\r
@@ -3209,11 +1885,11 @@ ResizeBoard(int newSizeX, int newSizeY, int flags)
   if (recurse > 0) return;\r
   recurse++;\r
   while (newSize > 0) {\r
-    InitDrawingSizes(newSize+1000, 0); // [HGM] kludge to update sizeInfo without visible effects\r
-    if(newSizeX >= sizeInfo[newSize].cliWidth &&\r
-       newSizeY >= sizeInfo[newSize].cliHeight) break;\r
+       InitDrawingSizes(newSize+1000, 0); // [HGM] kludge to update sizeInfo without visible effects\r
+       if(newSizeX >= sizeInfo[newSize].cliWidth &&\r
+          newSizeY >= sizeInfo[newSize].cliHeight) break;\r
     newSize--;\r
-  }\r
+  } \r
   boardSize = newSize;\r
   InitDrawingSizes(boardSize, flags);\r
   recurse--;\r
@@ -3243,10 +1919,10 @@ 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
+  oldRect.left = wpMain.x; //[HGM] placement: remember previous window params\r
+  oldRect.top = wpMain.y;\r
+  oldRect.right = wpMain.x + wpMain.width;\r
+  oldRect.bottom = wpMain.y + wpMain.height;\r
 \r
   tinyLayout = sizeInfo[boardSize].tinyLayout;\r
   smallLayout = sizeInfo[boardSize].smallLayout;\r
@@ -3263,7 +1939,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
     if (tinyLayout) {\r
       style &= ~WS_SYSMENU;\r
       InsertMenu(hmenu, IDM_Exit, MF_BYCOMMAND, IDM_Minimize,\r
-         "&Minimize\tCtrl+F4");\r
+                "&Minimize\tCtrl+F4");\r
     } else {\r
       style |= WS_SYSMENU;\r
       RemoveMenu(hmenu, IDM_Minimize, MF_BYCOMMAND);\r
@@ -3271,8 +1947,8 @@ InitDrawingSizes(BoardSize boardSize, int flags)
     SetWindowLong(hwndMain, GWL_STYLE, style);\r
 \r
     for (i=0; menuBarText[tinyLayout][i]; i++) {\r
-      ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP,\r
-    (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]);\r
+      ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP, \r
+       (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]);\r
     }\r
     DrawMenuBar(hwndMain);\r
   }\r
@@ -3298,16 +1974,16 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   /* Compute where everything goes */\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
-    leftLogoRect.right  = leftLogoRect.left + 4*clockSize.cy;\r
-    leftLogoRect.top    = OUTER_MARGIN;\r
-    leftLogoRect.bottom = OUTER_MARGIN + logoHeight;\r
+       logoHeight =  2*clockSize.cy;\r
+       leftLogoRect.left   = OUTER_MARGIN;\r
+       leftLogoRect.right  = leftLogoRect.left + 4*clockSize.cy;\r
+       leftLogoRect.top    = OUTER_MARGIN;\r
+       leftLogoRect.bottom = OUTER_MARGIN + logoHeight;\r
 \r
-    rightLogoRect.right  = OUTER_MARGIN + boardWidth;\r
-    rightLogoRect.left   = rightLogoRect.right - 4*clockSize.cy;\r
-    rightLogoRect.top    = OUTER_MARGIN;\r
-    rightLogoRect.bottom = OUTER_MARGIN + logoHeight;\r
+       rightLogoRect.right  = OUTER_MARGIN + boardWidth;\r
+       rightLogoRect.left   = rightLogoRect.right - 4*clockSize.cy;\r
+       rightLogoRect.top    = OUTER_MARGIN;\r
+       rightLogoRect.bottom = OUTER_MARGIN + logoHeight;\r
 \r
 \r
     whiteRect.left = leftLogoRect.right;\r
@@ -3329,6 +2005,8 @@ InitDrawingSizes(BoardSize boardSize, int flags)
     blackRect.right = blackRect.left + boardWidth/2 - 1;\r
     blackRect.top = whiteRect.top;\r
     blackRect.bottom = whiteRect.bottom;\r
+\r
+    logoHeight = 0; // [HGM] logo: suppress logo after change to tiny layout!\r
   }\r
 \r
   messageRect.left = OUTER_MARGIN + MESSAGE_LINE_LEFTMARGIN;\r
@@ -3354,49 +2032,49 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   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
+  wpMain.width = winW;  // [HGM] placement: set through temporary which can used by initial sizing choice\r
+  wpMain.height = 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
+  SetWindowPos(hwndMain, NULL, 0, 0, wpMain.width, wpMain.height,\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
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, moveHistoryDialog, &wpMoveHistory );\r
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, evalGraphDialog, &wpEvalGraph );\r
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, engineOutputDialog, &wpEngineOutput );\r
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, gameListDialog, &wpGameList );\r
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, hwndConsole, &wpConsole );\r
 \r
   /* compensate if menu bar wrapped */\r
   GetClientRect(hwndMain, &crect);\r
   offby = boardRect.bottom + OUTER_MARGIN - crect.bottom;\r
-  winHeight += offby;\r
+  wpMain.height += offby;\r
   switch (flags) {\r
   case WMSZ_TOPLEFT:\r
-    SetWindowPos(hwndMain, NULL,\r
-                 wrect.right - winWidth, wrect.bottom - winHeight,\r
-                 winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER);\r
+    SetWindowPos(hwndMain, NULL, \r
+                 wrect.right - wpMain.width, wrect.bottom - wpMain.height, \r
+                 wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER);\r
     break;\r
 \r
   case WMSZ_TOPRIGHT:\r
   case WMSZ_TOP:\r
-    SetWindowPos(hwndMain, NULL,\r
-                 wrect.left, wrect.bottom - winHeight,\r
-                 winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER);\r
+    SetWindowPos(hwndMain, NULL, \r
+                 wrect.left, wrect.bottom - wpMain.height, \r
+                 wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER);\r
     break;\r
 \r
   case WMSZ_BOTTOMLEFT:\r
   case WMSZ_LEFT:\r
-    SetWindowPos(hwndMain, NULL,\r
-                 wrect.right - winWidth, wrect.top,\r
-                 winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER);\r
+    SetWindowPos(hwndMain, NULL, \r
+                 wrect.right - wpMain.width, wrect.top, \r
+                 wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER);\r
     break;\r
 \r
   case WMSZ_BOTTOMRIGHT:\r
   case WMSZ_BOTTOM:\r
   case WMSZ_RIGHT:\r
   default:\r
-    SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight,\r
+    SetWindowPos(hwndMain, NULL, 0, 0, wpMain.width, wpMain.height,\r
                SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE);\r
     break;\r
   }\r
@@ -3409,21 +2087,21 @@ InitDrawingSizes(BoardSize boardSize, int flags)
     }\r
     if (appData.showButtonBar) {\r
       buttonDesc[i].hwnd =\r
-    CreateWindow("BUTTON", buttonDesc[i].label,\r
-             WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,\r
-             boardRect.right - BUTTON_WIDTH*(N_BUTTONS-i),\r
-             messageRect.top, BUTTON_WIDTH, messageSize.cy, hwndMain,\r
-             (HMENU) buttonDesc[i].id,\r
-             (HINSTANCE) GetWindowLong(hwndMain, GWL_HINSTANCE), NULL);\r
+       CreateWindow("BUTTON", buttonDesc[i].label,\r
+                    WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,\r
+                    boardRect.right - BUTTON_WIDTH*(N_BUTTONS-i),\r
+                    messageRect.top, BUTTON_WIDTH, messageSize.cy, hwndMain,\r
+                    (HMENU) buttonDesc[i].id,\r
+                    (HINSTANCE) GetWindowLong(hwndMain, GWL_HINSTANCE), NULL);\r
       if (tinyLayout) {\r
-    SendMessage(buttonDesc[i].hwnd, WM_SETFONT,\r
-            (WPARAM)font[boardSize][MESSAGE_FONT]->hf,\r
-            MAKELPARAM(FALSE, 0));\r
+       SendMessage(buttonDesc[i].hwnd, WM_SETFONT, \r
+                   (WPARAM)font[boardSize][MESSAGE_FONT]->hf,\r
+                   MAKELPARAM(FALSE, 0));\r
       }\r
       if (buttonDesc[i].id == IDM_Pause)\r
-    hwndPause = buttonDesc[i].hwnd;\r
+       hwndPause = buttonDesc[i].hwnd;\r
       buttonDesc[i].wndproc = (WNDPROC)\r
-    SetWindowLong(buttonDesc[i].hwnd, GWL_WNDPROC, (LONG) ButtonProc);\r
+       SetWindowLong(buttonDesc[i].hwnd, GWL_WNDPROC, (LONG) ButtonProc);\r
     }\r
   }\r
   if (gridPen != NULL) DeleteObject(gridPen);\r
@@ -3440,7 +2118,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
       ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_FLAT|PS_JOIN_MITER,\r
                    lineGap, &logbrush, 0, NULL);\r
 \r
-    logbrush.lbColor = premoveHighlightColor;\r
+    logbrush.lbColor = premoveHighlightColor; \r
     premovePen =\r
       ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_FLAT|PS_JOIN_MITER,\r
                    lineGap, &logbrush, 0, NULL);\r
@@ -3449,7 +2127,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
     for (i = 0; i < BOARD_HEIGHT + 1; i++) {\r
       gridEndpoints[i*2].x = boardRect.left + lineGap / 2;\r
       gridEndpoints[i*2].y = gridEndpoints[i*2 + 1].y =\r
-    boardRect.top + lineGap / 2 + (i * (squareSize + lineGap));\r
+       boardRect.top + lineGap / 2 + (i * (squareSize + lineGap));\r
       gridEndpoints[i*2 + 1].x = boardRect.left + lineGap / 2 +\r
         BOARD_WIDTH * (squareSize + lineGap);\r
       gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2;\r
@@ -3458,7 +2136,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
       gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].y = boardRect.top + lineGap / 2;\r
       gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].x =\r
         gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].x = boardRect.left +\r
-    lineGap / 2 + (i * (squareSize + lineGap));\r
+       lineGap / 2 + (i * (squareSize + lineGap));\r
       gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].y =\r
         boardRect.top + BOARD_HEIGHT * (squareSize + lineGap);\r
       gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2;\r
@@ -3481,9 +2159,9 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   for (i=0; i<=2; i++) {\r
     for (piece = WhitePawn;\r
          (int) piece < (int) BlackPawn;\r
-     piece = (ChessSquare) ((int) piece + 1)) {\r
+        piece = (ChessSquare) ((int) piece + 1)) {\r
       if (pieceBitmap[i][piece] != NULL)\r
-    DeleteObject(pieceBitmap[i][piece]);\r
+       DeleteObject(pieceBitmap[i][piece]);\r
     }\r
   }\r
 \r
@@ -3515,7 +2193,7 @@ InitDrawingSizes(BoardSize boardSize, int flags)
     pieceBitmap[2][WhiteQueen] = DoLoadBitmap(hInst, "q", squareSize, "w");\r
   }\r
 \r
-  if(squareSize <= 72 && squareSize >= 33) {\r
+  if(squareSize <= 72 && squareSize >= 33) { \r
     /* A & C are available in most sizes now */\r
     if(squareSize != 49 && squareSize != 72 && squareSize != 33) { // Vortex-like\r
       pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "a", squareSize, "s");\r
@@ -3748,7 +2426,7 @@ DrawCoordsOnDC(HDC hdc)
     str[0] = ranks[start + i];\r
     ExtTextOut(hdc, x + squareSize - 2, y - 1, 0, NULL, str, 1, NULL);\r
     x += squareSize + lineGap;\r
-  }\r
+  }    \r
 \r
   SelectObject(hdc, oldBrush);\r
   SetBkMode(hdc, oldMode);\r
@@ -3760,7 +2438,7 @@ VOID
 DrawGridOnDC(HDC hdc)\r
 {\r
   HPEN oldPen;\r
-\r
\r
   if (lineGap != 0) {\r
     oldPen = SelectObject(hdc, gridPen);\r
     PolyPolyline(hdc, gridEndpoints, gridVertexCounts, BOARD_WIDTH+BOARD_HEIGHT + 2);\r
@@ -3803,18 +2481,18 @@ DrawHighlightsOnDC(HDC hdc)
 {\r
   int i;\r
   for (i=0; i<2; i++) {\r
-    if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0)\r
+    if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0) \r
       DrawHighlightOnDC(hdc, TRUE,\r
-            highlightInfo.sq[i].x, highlightInfo.sq[i].y,\r
-            HIGHLIGHT_PEN);\r
+                       highlightInfo.sq[i].x, highlightInfo.sq[i].y,\r
+                       HIGHLIGHT_PEN);\r
   }\r
   for (i=0; i<2; i++) {\r
-    if (premoveHighlightInfo.sq[i].x >= 0 &&\r
-    premoveHighlightInfo.sq[i].y >= 0) {\r
-    DrawHighlightOnDC(hdc, TRUE,\r
-              premoveHighlightInfo.sq[i].x,\r
-              premoveHighlightInfo.sq[i].y,\r
-              PREMOVE_PEN);\r
+    if (premoveHighlightInfo.sq[i].x >= 0 && \r
+       premoveHighlightInfo.sq[i].y >= 0) {\r
+       DrawHighlightOnDC(hdc, TRUE,\r
+                         premoveHighlightInfo.sq[i].x, \r
+                         premoveHighlightInfo.sq[i].y,\r
+                         PREMOVE_PEN);\r
     }\r
   }\r
 }\r
@@ -3862,10 +2540,10 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
   }\r
 \r
   if (appData.monoMode) {\r
-    SelectObject(tmphdc, PieceBitmap(piece,\r
+    SelectObject(tmphdc, PieceBitmap(piece, \r
       color == sqcolor ? OUTLINE_PIECE : SOLID_PIECE));\r
     BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0,\r
-       sqcolor ? SRCCOPY : NOTSRCCOPY);\r
+          sqcolor ? SRCCOPY : NOTSRCCOPY);\r
   } else {\r
     tmpSize = squareSize;\r
     if(minorSize &&\r
@@ -3886,35 +2564,13 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
         StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A);\r
       else\r
         BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
-#if 0\r
-      /* Use black piece color for outline of white pieces */\r
-      /* Not sure this looks really good (though xboard does it).\r
-     Maybe better to have another selectable color, default black */\r
-      SelectObject(hdc, blackPieceBrush); /* could have own brush */\r
-      SelectObject(tmphdc, PieceBitmap(piece, OUTLINE_PIECE));\r
-      BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
-#else\r
       /* Use black for outline of white pieces */\r
       SelectObject(tmphdc, PieceBitmap(piece, OUTLINE_PIECE));\r
       if(appData.upsideDown && color==flipView)\r
         StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, SRCAND);\r
       else\r
         BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, SRCAND);\r
-#endif\r
     } else {\r
-#if 0\r
-      /* Use white piece color for details of black pieces */\r
-      /* Requires filled-in solid bitmaps (BLACK_PIECE class); the\r
-     WHITE_PIECE ones aren't always the right shape. */\r
-      /* Not sure this looks really good (though xboard does it).\r
-     Maybe better to have another selectable color, default medium gray? */\r
-      oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, BLACK_PIECE));\r
-      oldBrush = SelectObject(hdc, whitePieceBrush); /* could have own brush */\r
-      BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
-      SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE));\r
-      SelectObject(hdc, blackPieceBrush);\r
-      BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
-#else\r
       /* Use square color for details of black pieces */\r
       oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE));\r
       oldBrush = SelectObject(hdc, blackPieceBrush);\r
@@ -3922,7 +2578,6 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
         StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A);\r
       else\r
         BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
-#endif\r
     }\r
     SelectObject(hdc, oldBrush);\r
     SelectObject(tmphdc, oldBitmap);\r
@@ -3934,7 +2589,7 @@ int GetBackTextureMode( int algo )
 {\r
     int result = BACK_TEXTURE_MODE_DISABLED;\r
 \r
-    switch( algo )\r
+    switch( algo ) \r
     {\r
         case BACK_TEXTURE_MODE_PLAIN:\r
             result = 1; /* Always use identity map */\r
@@ -3947,7 +2602,7 @@ int GetBackTextureMode( int algo )
     return result;\r
 }\r
 \r
-/*\r
+/* \r
     [AS] Compute and save texture drawing info, otherwise we may not be able\r
     to handle redraws cleanly (as random numbers would always be different).\r
 */\r
@@ -4074,7 +2729,7 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y )
         /* [AS] Needed a lot of paper for this! :-) */\r
         dy = (double) (d_y - s_y) / (double) (d_x - s_x);\r
         dx = (double) (s_x - d_x) / (double) (s_y - d_y);\r
-\r
+  \r
         j = sqrt( Sqr(A_WIDTH) / (1.0 + Sqr(dx)) );\r
 \r
         k = sqrt( Sqr(A_WIDTH*A_HEIGHT_FACTOR) / (1.0 + Sqr(dy)) );\r
@@ -4234,8 +2889,8 @@ HRGN GetArrowHighlightClipRegion( HDC hdc )
 }\r
 \r
 /*\r
-    Warning: this function modifies the behavior of several other functions.\r
-\r
+    Warning: this function modifies the behavior of several other functions. \r
+    \r
     Basically, Winboard is optimized to avoid drawing the whole board if not strictly\r
     needed. Unfortunately, the decision whether or not to perform a full or partial\r
     repaint is scattered all over the place, which is not good for features such as\r
@@ -4247,7 +2902,7 @@ HRGN GetArrowHighlightClipRegion( HDC hdc )
 \r
     In such patched places, I always try refer to this function so there is a single\r
     place to maintain knowledge.\r
-\r
+    \r
     To restore the original behavior, just return FALSE unconditionally.\r
 */\r
 BOOL IsFullRepaintPreferrable()\r
@@ -4262,25 +2917,25 @@ BOOL IsFullRepaintPreferrable()
     return result;\r
 }\r
 \r
-/*\r
+/* \r
     This function is called by DrawPosition to know whether a full repaint must\r
     be forced or not.\r
 \r
-    Only DrawPosition may directly call this function, which makes use of\r
-    some state information. Other function should call DrawPosition specifying\r
+    Only DrawPosition may directly call this function, which makes use of \r
+    some state information. Other function should call DrawPosition specifying \r
     the repaint flag, and can use IsFullRepaintPreferrable if needed.\r
 */\r
 BOOL DrawPositionNeedsFullRepaint()\r
 {\r
     BOOL result = FALSE;\r
 \r
-    /*\r
+    /* \r
         Probably a slightly better policy would be to trigger a full repaint\r
         when animInfo.piece changes state (i.e. empty -> non-empty and viceversa),\r
         but animation is fast enough that it's difficult to notice.\r
     */\r
     if( animInfo.piece == EmptySquare ) {\r
-        if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() && HasHighlightInfo() ) {\r
+        if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() /*&& HasHighlightInfo()*/ ) {\r
             result = TRUE;\r
         }\r
     }\r
@@ -4299,9 +2954,9 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)
   /* [AS] Initialize background textures if needed */\r
   if( liteBackTexture != NULL || darkBackTexture != NULL ) {\r
       static int backTextureBoardSize; /* [HGM] boardsize: also new texture if board format changed */\r
-      if( backTextureSquareSize != squareSize\r
-       || backTextureBoardSize != BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT) {\r
-      backTextureBoardSize = BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT;\r
+      if( backTextureSquareSize != squareSize \r
+       || backTextureBoardSize != BOARD_WIDTH+BOARD_FILES*BOARD_HEIGHT) {\r
+         backTextureBoardSize = BOARD_WIDTH+BOARD_FILES*BOARD_HEIGHT;\r
           backTextureSquareSize = squareSize;\r
           RebuildTextureSquareInfo();\r
       }\r
@@ -4311,7 +2966,7 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)
 \r
   for (row = 0; row < BOARD_HEIGHT; row++) {\r
     for (column = 0; column < BOARD_WIDTH; column++) {\r
-\r
+  \r
       SquareToPos(row, column, &x, &y);\r
 \r
       piece = board[row][column];\r
@@ -4338,7 +2993,7 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)
             if( row < gameInfo.holdingsSize )\r
                 square_color = 1;\r
             else {\r
-                DisplayHoldingsCount(hdc, x, y, 0, 0);\r
+                DisplayHoldingsCount(hdc, x, y, 0, 0); \r
                 continue;\r
             }\r
       }\r
@@ -4350,20 +3005,20 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)
       if (appData.monoMode) {\r
         if (piece == EmptySquare) {\r
           BitBlt(hdc, x, y, squareSize, squareSize, 0, 0, 0,\r
-         square_color ? WHITENESS : BLACKNESS);\r
+                square_color ? WHITENESS : BLACKNESS);\r
         } else {\r
           DrawPieceOnDC(hdc, piece, piece_color, square_color, x, y, tmphdc);\r
         }\r
-      }\r
+      } \r
       else if( backTextureSquareInfo[row][column].mode > 0 ) {\r
           /* [AS] Draw the square using a texture bitmap */\r
           HBITMAP hbm = SelectObject( texture_hdc, square_color ? liteBackTexture : darkBackTexture );\r
-      int r = row, c = column; // [HGM] do not flip board in flipView\r
-      if(flipView) { r = BOARD_HEIGHT-1 - r; c = BOARD_WIDTH-1 - c; }\r
+         int r = row, c = column; // [HGM] do not flip board in flipView\r
+         if(flipView) { r = BOARD_HEIGHT-1 - r; c = BOARD_WIDTH-1 - c; }\r
 \r
-          DrawTile( x, y,\r
-              squareSize, squareSize,\r
-              hdc,\r
+          DrawTile( x, y, \r
+              squareSize, squareSize, \r
+              hdc, \r
               texture_hdc,\r
               backTextureSquareInfo[r][c].mode,\r
               backTextureSquareInfo[r][c].x,\r
@@ -4395,10 +3050,10 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)
 int saveDiagFlag = 0; FILE *diagFile; // [HGM] diag\r
 void fputDW(FILE *f, int x)\r
 {\r
-    fputc(x     & 255, f);\r
-    fputc(x>>8  & 255, f);\r
-    fputc(x>>16 & 255, f);\r
-    fputc(x>>24 & 255, f);\r
+       fputc(x     & 255, f);\r
+       fputc(x>>8  & 255, f);\r
+       fputc(x>>16 & 255, f);\r
+       fputc(x>>24 & 255, f);\r
 }\r
 \r
 #define MAX_CLIPS 200   /* more than enough */\r
@@ -4416,19 +3071,75 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo)
   if(logo == NULL) return;\r
 //  GetClientRect(hwndMain, &Rect);\r
 //  bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1,\r
-//                  Rect.bottom-Rect.top+1);\r
+//                                     Rect.bottom-Rect.top+1);\r
   tmphdc = CreateCompatibleDC(hdc);\r
   hbm = SelectObject(tmphdc, logo);\r
   if( GetObject( logo, sizeof(bi), &bi ) > 0 ) {\r
             w = bi.bmWidth;\r
             h = bi.bmHeight;\r
   }\r
-  StretchBlt(hdc, logoRect.left, logoRect.top, logoRect.right - logoRect.left,\r
+  StretchBlt(hdc, logoRect.left, logoRect.top, logoRect.right - logoRect.left, \r
                   logoRect.bottom - logoRect.top, tmphdc, 0, 0, w, h, SRCCOPY);\r
   SelectObject(tmphdc, hbm);\r
   DeleteDC(tmphdc);\r
 }\r
 \r
+static HDC hdcSeek;\r
+\r
+// [HGM] seekgraph\r
+void DrawSeekAxis( int x, int y, int xTo, int yTo )\r
+{\r
+    POINT stPt;\r
+    HPEN hp = SelectObject( hdcSeek, gridPen );\r
+    MoveToEx( hdcSeek, boardRect.left+x, boardRect.top+y, &stPt );\r
+    LineTo( hdcSeek, boardRect.left+xTo, boardRect.top+yTo );\r
+    SelectObject( hdcSeek, hp );\r
+}\r
+\r
+// front-end wrapper for drawing functions to do rectangles\r
+void DrawSeekBackground( int left, int top, int right, int bottom )\r
+{\r
+    HPEN hp;\r
+    RECT rc;\r
+\r
+    if (hdcSeek == NULL) {\r
+    hdcSeek = GetDC(hwndMain);\r
+      if (!appData.monoMode) {\r
+        SelectPalette(hdcSeek, hPal, FALSE);\r
+        RealizePalette(hdcSeek);\r
+      }\r
+    }\r
+    hp = SelectObject( hdcSeek, gridPen );\r
+    rc.top = boardRect.top+top; rc.left = boardRect.left+left; \r
+    rc.bottom = boardRect.top+bottom; rc.right = boardRect.left+right;\r
+    FillRect( hdcSeek, &rc, lightSquareBrush );\r
+    SelectObject( hdcSeek, hp );\r
+}\r
+\r
+// front-end wrapper for putting text in graph\r
+void DrawSeekText(char *buf, int x, int y)\r
+{\r
+        SIZE stSize;\r
+       SetBkMode( hdcSeek, TRANSPARENT );\r
+        GetTextExtentPoint32( hdcSeek, buf, strlen(buf), &stSize );\r
+        TextOut( hdcSeek, boardRect.left+x-3, boardRect.top+y-stSize.cy/2, buf, strlen(buf) );\r
+}\r
+\r
+void DrawSeekDot(int x, int y, int color)\r
+{\r
+       int square = color & 0x80;\r
+       color &= 0x7F;\r
+           HBRUSH oldBrush = SelectObject(hdcSeek, \r
+                       color == 0 ? markerBrush : color == 1 ? darkSquareBrush : explodeBrush);\r
+       if(square)\r
+           Rectangle(hdcSeek, boardRect.left+x - squareSize/9, boardRect.top+y - squareSize/9,\r
+                              boardRect.left+x + squareSize/9, boardRect.top+y + squareSize/9);\r
+       else\r
+           Ellipse(hdcSeek, boardRect.left+x - squareSize/8, boardRect.top+y - squareSize/8,\r
+                            boardRect.left+x + squareSize/8, boardRect.top+y + squareSize/8);\r
+           SelectObject(hdcSeek, oldBrush);\r
+}\r
+\r
 VOID\r
 HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)\r
 {\r
@@ -4450,26 +3161,17 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
    * caller tell it that.  I think this can safely be set to FALSE - but\r
    * if we trust the callers not to request full repaints unnessesarily, then\r
    * we could skip some clipping work.  In other words, only request a full\r
-   * redraw when the majority of pieces have changed positions (ie. flip,\r
+   * redraw when the majority of pieces have changed positions (ie. flip, \r
    * gamestart and similar)  --Hawk\r
    */\r
   Boolean fullrepaint = repaint;\r
 \r
+  if(DrawSeekGraph()) return; // [HG} seekgraph: suppress printing board if seek graph up\r
+\r
   if( DrawPositionNeedsFullRepaint() ) {\r
       fullrepaint = TRUE;\r
   }\r
 \r
-#if 0\r
-  if( fullrepaint ) {\r
-      static int repaint_count = 0;\r
-      char buf[128];\r
-\r
-      repaint_count++;\r
-      sprintf( buf, "FULL repaint: %d\n", repaint_count );\r
-      OutputDebugString( buf );\r
-  }\r
-#endif\r
-\r
   if (board == NULL) {\r
     if (!lastReqValid) {\r
       return;\r
@@ -4499,35 +3201,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
     releaseDC = FALSE;\r
   }\r
 \r
-#if 0\r
-  fprintf(debugFP, "*******************************\n"\r
-                   "repaint = %s\n"\r
-                   "dragInfo.from (%d,%d)\n"\r
-                   "dragInfo.start (%d,%d)\n"\r
-                   "dragInfo.pos (%d,%d)\n"\r
-                   "dragInfo.lastpos (%d,%d)\n",\r
-                    repaint ? "TRUE" : "FALSE",\r
-                    dragInfo.from.x, dragInfo.from.y,\r
-                    dragInfo.start.x, dragInfo.start.y,\r
-                    dragInfo.pos.x, dragInfo.pos.y,\r
-                    dragInfo.lastpos.x, dragInfo.lastpos.y);\r
-  fprintf(debugFP, "prev:  ");\r
-  for (row = 0; row < BOARD_HEIGHT; row++) {\r
-    for (column = 0; column < BOARD_WIDTH; column++) {\r
-      fprintf(debugFP, "%d ", lastDrawn[row][column]);\r
-    }\r
-  }\r
-  fprintf(debugFP, "\n");\r
-  fprintf(debugFP, "board: ");\r
-  for (row = 0; row < BOARD_HEIGHT; row++) {\r
-    for (column = 0; column < BOARD_WIDTH; column++) {\r
-      fprintf(debugFP, "%d ", board[row][column]);\r
-    }\r
-  }\r
-  fprintf(debugFP, "\n");\r
-  fflush(debugFP);\r
-#endif\r
-\r
   /* Create some work-DCs */\r
   hdcmem = CreateCompatibleDC(hdc);\r
   tmphdc = CreateCompatibleDC(hdc);\r
@@ -4540,66 +3213,66 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
     if(dragInfo.from.x == BOARD_LEFT-2 ) {\r
             if(--board[dragInfo.from.y][dragInfo.from.x+1] == 0 )\r
         board[dragInfo.from.y][dragInfo.from.x] = EmptySquare;\r
-    } else\r
+    } else \r
     if(dragInfo.from.x == BOARD_RGHT+1) {\r
             if(--board[dragInfo.from.y][dragInfo.from.x-1] == 0 )\r
         board[dragInfo.from.y][dragInfo.from.x] = EmptySquare;\r
-    } else\r
+    } else \r
         board[dragInfo.from.y][dragInfo.from.x] = EmptySquare;\r
   }\r
 \r
-  /* Figure out which squares need updating by comparing the\r
+  /* Figure out which squares need updating by comparing the \r
    * newest board with the last drawn board and checking if\r
    * flipping has changed.\r
    */\r
   if (!fullrepaint && lastDrawnValid && 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
-      SquareToPos(row, column, &x, &y);\r
-      clips[num_clips++] =\r
-        CreateRectRgn(x, y, x + squareSize, y + squareSize);\r
-    }\r
+       if (lastDrawn[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
     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
-    if (lastDrawnHighlight.sq[i].x >= 0 &&\r
-        lastDrawnHighlight.sq[i].y >= 0) {\r
-      SquareToPos(lastDrawnHighlight.sq[i].y,\r
-              lastDrawnHighlight.sq[i].x, &x, &y);\r
-      clips[num_clips++] =\r
-        CreateRectRgn(x - lineGap, y - lineGap,\r
-                      x + squareSize + lineGap, y + squareSize + lineGap);\r
-    }\r
-    if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0) {\r
-      SquareToPos(highlightInfo.sq[i].y, highlightInfo.sq[i].x, &x, &y);\r
-      clips[num_clips++] =\r
-        CreateRectRgn(x - lineGap, y - lineGap,\r
-                      x + squareSize + lineGap, y + squareSize + lineGap);\r
-    }\r
+         lastDrawnHighlight.sq[i].y != highlightInfo.sq[i].y) {\r
+       if (lastDrawnHighlight.sq[i].x >= 0 &&\r
+           lastDrawnHighlight.sq[i].y >= 0) {\r
+         SquareToPos(lastDrawnHighlight.sq[i].y,\r
+                     lastDrawnHighlight.sq[i].x, &x, &y);\r
+         clips[num_clips++] =\r
+           CreateRectRgn(x - lineGap, y - lineGap, \r
+                         x + squareSize + lineGap, y + squareSize + lineGap);\r
+       }\r
+       if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0) {\r
+         SquareToPos(highlightInfo.sq[i].y, highlightInfo.sq[i].x, &x, &y);\r
+         clips[num_clips++] =\r
+           CreateRectRgn(x - lineGap, y - lineGap, \r
+                         x + squareSize + lineGap, y + squareSize + lineGap);\r
+       }\r
       }\r
     }\r
     for (i=0; i<2; i++) {\r
       if (lastDrawnPremove.sq[i].x != premoveHighlightInfo.sq[i].x ||\r
-      lastDrawnPremove.sq[i].y != premoveHighlightInfo.sq[i].y) {\r
-    if (lastDrawnPremove.sq[i].x >= 0 &&\r
-        lastDrawnPremove.sq[i].y >= 0) {\r
-      SquareToPos(lastDrawnPremove.sq[i].y,\r
-              lastDrawnPremove.sq[i].x, &x, &y);\r
-      clips[num_clips++] =\r
-        CreateRectRgn(x - lineGap, y - lineGap,\r
-                      x + squareSize + lineGap, y + squareSize + lineGap);\r
-    }\r
-    if (premoveHighlightInfo.sq[i].x >= 0 &&\r
-        premoveHighlightInfo.sq[i].y >= 0) {\r
-      SquareToPos(premoveHighlightInfo.sq[i].y,\r
-              premoveHighlightInfo.sq[i].x, &x, &y);\r
-      clips[num_clips++] =\r
-        CreateRectRgn(x - lineGap, y - lineGap,\r
-                      x + squareSize + lineGap, y + squareSize + lineGap);\r
-    }\r
+         lastDrawnPremove.sq[i].y != premoveHighlightInfo.sq[i].y) {\r
+       if (lastDrawnPremove.sq[i].x >= 0 &&\r
+           lastDrawnPremove.sq[i].y >= 0) {\r
+         SquareToPos(lastDrawnPremove.sq[i].y,\r
+                     lastDrawnPremove.sq[i].x, &x, &y);\r
+         clips[num_clips++] =\r
+           CreateRectRgn(x - lineGap, y - lineGap, \r
+                         x + squareSize + lineGap, y + squareSize + lineGap);\r
+       }\r
+       if (premoveHighlightInfo.sq[i].x >= 0 && \r
+           premoveHighlightInfo.sq[i].y >= 0) {\r
+         SquareToPos(premoveHighlightInfo.sq[i].y, \r
+                     premoveHighlightInfo.sq[i].x, &x, &y);\r
+         clips[num_clips++] =\r
+           CreateRectRgn(x - lineGap, y - lineGap, \r
+                         x + squareSize + lineGap, y + squareSize + lineGap);\r
+       }\r
       }\r
     }\r
   } else {\r
@@ -4613,7 +3286,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
    */\r
   GetClientRect(hwndMain, &Rect);\r
   bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1,\r
-                    Rect.bottom-Rect.top+1);\r
+                                       Rect.bottom-Rect.top+1);\r
   oldBitmap = SelectObject(hdcmem, bufferBitmap);\r
   if (!appData.monoMode) {\r
     SelectPalette(hdcmem, hPal, FALSE);\r
@@ -4641,8 +3314,8 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
     }\r
   }\r
 \r
-  /* Are we animating a move?\r
-   * If so,\r
+  /* Are we animating a move?  \r
+   * If so, \r
    *   - remove the piece from the board (temporarely)\r
    *   - calculate the clipping region\r
    */\r
@@ -4655,12 +3328,12 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
       y2 = boardRect.top + animInfo.pos.y;\r
       clips[num_clips++] = CreateRectRgn(MIN(x,x2), MIN(y,y2), MAX(x,x2)+squareSize, MAX(y,y2)+squareSize);\r
       /* Slight kludge.  The real problem is that after AnimateMove is\r
-     done, the position on the screen does not match lastDrawn.\r
-     This currently causes trouble only on e.p. captures in\r
-     atomic, where the piece moves to an empty square and then\r
-     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
+        done, the position on the screen does not match lastDrawn.\r
+        This currently causes trouble only on e.p. captures in\r
+        atomic, where the piece moves to an empty square and then\r
+        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
     }\r
   }\r
@@ -4680,61 +3353,73 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
 \r
   /* Do all the drawing to the memory DC */\r
   if(explodeInfo.radius) { // [HGM] atomic\r
-    HBRUSH oldBrush;\r
-    int x, y, r=(explodeInfo.radius * squareSize)/100;\r
+       HBRUSH oldBrush;\r
+       int x, y, r=(explodeInfo.radius * squareSize)/100;\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
+       SquareToPos(explodeInfo.toY, explodeInfo.toX, &x, &y);\r
+       x += squareSize/2;\r
+       y += squareSize/2;\r
         if(!fullrepaint) {\r
-      clips[num_clips] = CreateRectRgn(x-r, y-r, x+r, y+r);\r
-      ExtSelectClipRgn(hdcmem, clips[num_clips++], RGN_OR);\r
-    }\r
-    DrawGridOnDC(hdcmem);\r
-    DrawHighlightsOnDC(hdcmem);\r
-    DrawBoardOnDC(hdcmem, board, tmphdc);\r
-    oldBrush = SelectObject(hdcmem, explodeBrush);\r
-    Ellipse(hdcmem, x-r, y-r, x+r, y+r);\r
-    SelectObject(hdcmem, oldBrush);\r
+         clips[num_clips] = CreateRectRgn(x-r, y-r, x+r, y+r);\r
+         ExtSelectClipRgn(hdcmem, clips[num_clips++], RGN_OR);\r
+       }\r
+       DrawGridOnDC(hdcmem);\r
+       DrawHighlightsOnDC(hdcmem);\r
+       DrawBoardOnDC(hdcmem, board, tmphdc);\r
+       oldBrush = SelectObject(hdcmem, explodeBrush);\r
+       Ellipse(hdcmem, x-r, y-r, x+r, y+r);\r
+       SelectObject(hdcmem, oldBrush);\r
   } else {\r
     DrawGridOnDC(hdcmem);\r
     DrawHighlightsOnDC(hdcmem);\r
     DrawBoardOnDC(hdcmem, board, tmphdc);\r
   }\r
-  if(logoHeight) {\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
+  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
+           HBRUSH oldBrush = SelectObject(hdcmem, \r
+                       marker[row][column] == 2 ? markerBrush : explodeBrush);\r
+           SquareToPos(row, column, &x, &y);\r
+           Ellipse(hdcmem, x + squareSize/4, y + squareSize/4,\r
+                         x + 3*squareSize/4, y + 3*squareSize/4);\r
+           SelectObject(hdcmem, oldBrush);\r
+       }\r
     }\r
-    DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo);\r
-    DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo);\r
+  }\r
+  if(logoHeight) {\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
@@ -4758,21 +3443,21 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
     x = dragInfo.pos.x - squareSize / 2;\r
     y = dragInfo.pos.y - squareSize / 2;\r
     DrawPieceOnDC(hdcmem, dragged_piece,\r
-          ((int) dragged_piece < (int) BlackPawn),\r
+                 ((int) dragged_piece < (int) BlackPawn), \r
                   (dragInfo.from.y + dragInfo.from.x) % 2, x, y, tmphdc);\r
-  }\r
-\r
+  }   \r
+  \r
   /* Put the animated piece back into place and draw it */\r
   if (animInfo.piece != EmptySquare) {\r
     board[animInfo.from.y][animInfo.from.x]  = animInfo.piece;\r
     x = boardRect.left + animInfo.pos.x;\r
     y = boardRect.top + animInfo.pos.y;\r
     DrawPieceOnDC(hdcmem, animInfo.piece,\r
-          ((int) animInfo.piece < (int) BlackPawn),\r
+                 ((int) animInfo.piece < (int) BlackPawn),\r
                   (animInfo.from.y + animInfo.from.x) % 2, x, y, tmphdc);\r
   }\r
 \r
-  /* Release the bufferBitmap by selecting in the old bitmap\r
+  /* Release the bufferBitmap by selecting in the old bitmap \r
    * and delete the memory DC\r
    */\r
   SelectObject(hdcmem, oldBitmap);\r
@@ -4784,7 +3469,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
     for (x = 1; x < num_clips; x++) {\r
       if (ExtSelectClipRgn(hdc, clips[x], RGN_OR) == ERROR)\r
         abort();   // this should never ever happen!\r
-    }\r
+    } \r
   }\r
 \r
   /* Copy the new bitmap onto the screen in one go.\r
@@ -4792,66 +3477,65 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
    */\r
   oldBitmap = SelectObject(tmphdc, bufferBitmap);\r
   BitBlt(hdc, boardRect.left, boardRect.top,\r
-     boardRect.right - boardRect.left,\r
-     boardRect.bottom - boardRect.top,\r
-     tmphdc, boardRect.left, boardRect.top, SRCCOPY);\r
-  if(saveDiagFlag) {\r
-    BITMAP b; int i, j=0, m, w, wb, fac=0; char pData[1000000];\r
+        boardRect.right - boardRect.left,\r
+        boardRect.bottom - boardRect.top,\r
+        tmphdc, boardRect.left, boardRect.top, SRCCOPY);\r
+  if(saveDiagFlag) { \r
+    BITMAP b; int i, j=0, m, w, wb, fac=0; char pData[1000000]; \r
     BITMAPINFOHEADER bih; int color[16], nrColors=0;\r
 \r
     GetObject(bufferBitmap, sizeof(b), &b);\r
     if(b.bmWidthBytes*b.bmHeight <= 990000) {\r
-    bih.biSize = sizeof(BITMAPINFOHEADER);\r
-    bih.biWidth = b.bmWidth;\r
-    bih.biHeight = b.bmHeight;\r
-    bih.biPlanes = 1;\r
-    bih.biBitCount = b.bmBitsPixel;\r
-    bih.biCompression = 0;\r
-    bih.biSizeImage = b.bmWidthBytes*b.bmHeight;\r
-    bih.biXPelsPerMeter = 0;\r
-    bih.biYPelsPerMeter = 0;\r
-    bih.biClrUsed = 0;\r
-    bih.biClrImportant = 0;\r
-//  fprintf(diagFile, "t=%d\nw=%d\nh=%d\nB=%d\nP=%d\nX=%d\n",\r
-//      b.bmType,  b.bmWidth,  b.bmHeight, b.bmWidthBytes,  b.bmPlanes,  b.bmBitsPixel);\r
-    GetDIBits(tmphdc,bufferBitmap,0,b.bmHeight,pData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);\r
-//  fprintf(diagFile, "%8x\n", (int) pData);\r
-\r
-#if 1\r
-    wb = b.bmWidthBytes;\r
-    // count colors\r
-    for(i=0; i<wb*(b.bmHeight - boardRect.top + OUTER_MARGIN)>>2; i++) {\r
-        int k = ((int*) pData)[i];\r
-        for(j=0; j<nrColors; j++) if(color[j] == k) break;\r
-        if(j >= 16) break;\r
-        color[j] = k;\r
-        if(j >= nrColors) nrColors = j+1;\r
-    }\r
-    if(j<16) { // 16 colors is enough. Compress to 4 bits per pixel\r
-        INT p = 0;\r
-        for(i=0; i<b.bmHeight - boardRect.top + OUTER_MARGIN; i++) {\r
-            for(w=0; w<(wb>>2); w+=2) {\r
-            int k = ((int*) pData)[(wb*i>>2) + w];\r
-            for(j=0; j<nrColors; j++) if(color[j] == k) break;\r
-            k = ((int*) pData)[(wb*i>>2) + w + 1];\r
-            for(m=0; m<nrColors; m++) if(color[m] == k) break;\r
-            pData[p++] = m | j<<4;\r
-            }\r
-            while(p&3) pData[p++] = 0;\r
-        }\r
-        fac = 3;\r
-        wb = ((wb+31)>>5)<<2;\r
-    }\r
-    // write BITMAPFILEHEADER\r
-    fprintf(diagFile, "BM");\r
+       bih.biSize = sizeof(BITMAPINFOHEADER);\r
+       bih.biWidth = b.bmWidth;\r
+       bih.biHeight = b.bmHeight;\r
+       bih.biPlanes = 1;\r
+       bih.biBitCount = b.bmBitsPixel;\r
+       bih.biCompression = 0;\r
+       bih.biSizeImage = b.bmWidthBytes*b.bmHeight;\r
+       bih.biXPelsPerMeter = 0;\r
+       bih.biYPelsPerMeter = 0;\r
+       bih.biClrUsed = 0;\r
+       bih.biClrImportant = 0;\r
+//     fprintf(diagFile, "t=%d\nw=%d\nh=%d\nB=%d\nP=%d\nX=%d\n", \r
+//             b.bmType,  b.bmWidth,  b.bmHeight, b.bmWidthBytes,  b.bmPlanes,  b.bmBitsPixel);\r
+       GetDIBits(tmphdc,bufferBitmap,0,b.bmHeight,pData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);\r
+//     fprintf(diagFile, "%8x\n", (int) pData);\r
+\r
+       wb = b.bmWidthBytes;\r
+       // count colors\r
+       for(i=0; i<wb*(b.bmHeight - boardRect.top + OUTER_MARGIN)>>2; i++) {\r
+               int k = ((int*) pData)[i];\r
+               for(j=0; j<nrColors; j++) if(color[j] == k) break;\r
+               if(j >= 16) break;\r
+               color[j] = k;\r
+               if(j >= nrColors) nrColors = j+1;\r
+       }\r
+       if(j<16) { // 16 colors is enough. Compress to 4 bits per pixel\r
+               INT p = 0;\r
+               for(i=0; i<b.bmHeight - boardRect.top + OUTER_MARGIN; i++) {\r
+                   for(w=0; w<(wb>>2); w+=2) {\r
+                       int k = ((int*) pData)[(wb*i>>2) + w];\r
+                       for(j=0; j<nrColors; j++) if(color[j] == k) break;\r
+                       k = ((int*) pData)[(wb*i>>2) + w + 1];\r
+                       for(m=0; m<nrColors; m++) if(color[m] == k) break;\r
+                       pData[p++] = m | j<<4;\r
+                   }\r
+                   while(p&3) pData[p++] = 0;\r
+               }\r
+               fac = 3;\r
+               wb = ((wb+31)>>5)<<2;\r
+       }\r
+       // write BITMAPFILEHEADER\r
+       fprintf(diagFile, "BM");\r
         fputDW(diagFile, wb*(b.bmHeight - boardRect.top + OUTER_MARGIN)+0x36 + (fac?64:0));\r
         fputDW(diagFile, 0);\r
         fputDW(diagFile, 0x36 + (fac?64:0));\r
-    // write BITMAPINFOHEADER\r
+       // write BITMAPINFOHEADER\r
         fputDW(diagFile, 40);\r
         fputDW(diagFile, b.bmWidth);\r
         fputDW(diagFile, b.bmHeight - boardRect.top + OUTER_MARGIN);\r
-    if(fac) fputDW(diagFile, 0x040001);   // planes and bits/pixel\r
+       if(fac) fputDW(diagFile, 0x040001);   // planes and bits/pixel\r
         else    fputDW(diagFile, 0x200001);   // planes and bits/pixel\r
         fputDW(diagFile, 0);\r
         fputDW(diagFile, 0);\r
@@ -4859,13 +3543,12 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
         fputDW(diagFile, 0);\r
         fputDW(diagFile, 0);\r
         fputDW(diagFile, 0);\r
-    // write color table\r
-    if(fac)\r
-    for(i=0; i<16; i++) fputDW(diagFile, color[i]);\r
-    // write bitmap data\r
-    for(i=0; i<wb*(b.bmHeight - boardRect.top + OUTER_MARGIN); i++)\r
-        fputc(pData[i], diagFile);\r
-#endif\r
+       // write color table\r
+       if(fac)\r
+       for(i=0; i<16; i++) fputDW(diagFile, color[i]);\r
+       // write bitmap data\r
+       for(i=0; i<wb*(b.bmHeight - boardRect.top + OUTER_MARGIN); i++) \r
+               fputc(pData[i], diagFile);\r
      }\r
   }\r
 \r
@@ -4878,9 +3561,9 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   DeleteDC(tmphdc);\r
   DeleteObject(bufferBitmap);\r
 \r
-  if (releaseDC)\r
+  if (releaseDC) \r
     ReleaseDC(hwndMain, hdc);\r
-\r
+  \r
   if (lastDrawnFlipView != flipView) {\r
     if (flipView)\r
       CheckMenuItem(GetMenu(hwndMain),IDM_FlipView, MF_BYCOMMAND|MF_CHECKED);\r
@@ -4906,7 +3589,7 @@ SaveDiagram(f)
     saveDiagFlag = 0;\r
 \r
 //    if(f != NULL) fprintf(f, "Sorry, but this feature is still in preparation\n");\r
-\r
+    \r
     fclose(f);\r
     return TRUE;\r
 }\r
@@ -4929,15 +3612,15 @@ PaintProc(HWND hwnd)
       DrawIcon(hdc, 2, 2, iconCurrent);\r
     } else {\r
       if (!appData.monoMode) {\r
-    SelectPalette(hdc, hPal, FALSE);\r
-    RealizePalette(hdc);\r
+       SelectPalette(hdc, hPal, FALSE);\r
+       RealizePalette(hdc);\r
       }\r
       HDCDrawPosition(hdc, 1, NULL);\r
       oldFont =\r
-    SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf);\r
+       SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf);\r
       ExtTextOut(hdc, messageRect.left, messageRect.top,\r
-         ETO_CLIPPED|ETO_OPAQUE,\r
-         &messageRect, messageText, strlen(messageText), NULL);\r
+                ETO_CLIPPED|ETO_OPAQUE,\r
+                &messageRect, messageText, strlen(messageText), NULL);\r
       SelectObject(hdc, oldFont);\r
       DisplayBothClocks();\r
     }\r
@@ -4954,8 +3637,8 @@ PaintProc(HWND hwnd)
  * The offset boardRect.left or boardRect.top must already have been\r
  *   subtracted from x.\r
  */\r
-int\r
-EventToSquare(int x)\r
+int EventToSquare(x, limit)\r
+     int x, limit;\r
 {\r
   if (x <= 0)\r
     return -2;\r
@@ -4965,7 +3648,7 @@ EventToSquare(int x)
   if ((x % (squareSize + lineGap)) >= squareSize)\r
     return -1;\r
   x /= (squareSize + lineGap);\r
-  if (x >= BOARD_SIZE)\r
+    if (x >= limit)\r
     return -2;\r
   return x;\r
 }\r
@@ -4994,49 +3677,63 @@ SetupDropMenu(HMENU hmenu)
 \r
   for (i=0; i<sizeof(dropEnables)/sizeof(DropEnable); i++) {\r
     p = strchr(gameMode == IcsPlayingWhite ? white_holding : black_holding,\r
-           dropEnables[i].piece);\r
+              dropEnables[i].piece);\r
     count = 0;\r
     while (p && *p++ == dropEnables[i].piece) count++;\r
     sprintf(item, "%s  %d", dropEnables[i].name, count);\r
     enable = count > 0 || !appData.testLegality\r
       /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse\r
-              && !appData.icsActive);\r
+                     && !appData.icsActive);\r
     ModifyMenu(hmenu, dropEnables[i].command,\r
-           MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED) | MF_STRING,\r
-           dropEnables[i].command, item);\r
+              MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED) | MF_STRING,\r
+              dropEnables[i].command, item);\r
   }\r
 }\r
 \r
+void DragPieceBegin(int x, int y)\r
+{\r
+      dragInfo.lastpos.x = boardRect.left + x;\r
+      dragInfo.lastpos.y = boardRect.top + y;\r
+      dragInfo.from.x = fromX;\r
+      dragInfo.from.y = fromY;\r
+      dragInfo.start = dragInfo.from;\r
+      SetCapture(hwndMain);\r
+}\r
+\r
+void DragPieceEnd(int x, int y)\r
+{\r
+    ReleaseCapture();\r
+    dragInfo.start.x = dragInfo.start.y = -1;\r
+    dragInfo.from = dragInfo.start;\r
+    dragInfo.pos = dragInfo.lastpos = dragInfo.start;\r
+}\r
+\r
 /* Event handler for mouse messages */\r
 VOID\r
 MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
-  int x, y;\r
+  int x, y, menuNr;\r
   POINT pt;\r
   static int recursive = 0;\r
   HMENU hmenu;\r
-//  BOOLEAN needsRedraw = FALSE;\r
-  BOOLEAN saveAnimate;\r
   BOOLEAN forceFullRepaint = IsFullRepaintPreferrable(); /* [AS] */\r
-  static BOOLEAN sameAgain = FALSE, promotionChoice = FALSE;\r
-  ChessMove moveType;\r
 \r
   if (recursive) {\r
     if (message == WM_MBUTTONUP) {\r
       /* Hideous kludge to fool TrackPopupMenu into paying attention\r
-     to the middle button: we simulate pressing the left button too!\r
-     */\r
+        to the middle button: we simulate pressing the left button too!\r
+        */\r
       PostMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam);\r
       PostMessage(hwnd, WM_LBUTTONUP, wParam, lParam);\r
     }\r
     return;\r
   }\r
   recursive++;\r
-\r
+  \r
   pt.x = LOWORD(lParam);\r
   pt.y = HIWORD(lParam);\r
-  x = EventToSquare(pt.x - boardRect.left);\r
-  y = EventToSquare(pt.y - boardRect.top);\r
+  x = EventToSquare(pt.x - boardRect.left, BOARD_WIDTH);\r
+  y = EventToSquare(pt.y - boardRect.top, BOARD_HEIGHT);\r
   if (!flipView && y >= 0) {\r
     y = BOARD_HEIGHT - 1 - y;\r
   }\r
@@ -5046,262 +3743,62 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 \r
   switch (message) {\r
   case WM_LBUTTONDOWN:\r
-    if(promotionChoice) { // we are waiting for a click to indicate promotion piece\r
-    promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel\r
-    if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y);\r
-    if(gameInfo.holdingsWidth &&\r
-        (WhiteOnMove(currentMove)\r
-            ? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0\r
-            : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) {\r
-        // click in right holdings, for determining promotion piece\r
-        ChessSquare p = boards[currentMove][y][x];\r
-        if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p);\r
-        if(p != EmptySquare) {\r
-        FinishMove(WhitePromotionQueen, fromX, fromY, toX, toY, ToLower(PieceToChar(p)));\r
-        fromX = fromY = -1;\r
-        break;\r
-        }\r
-    }\r
-    DrawPosition(FALSE, boards[currentMove]);\r
-    break;\r
-    }\r
-    ErrorPopDown();\r
-    sameAgain = FALSE;\r
-    if (y == -2) {\r
-      /* Downclick vertically off board; check if on clock */\r
       if (PtInRect((LPRECT) &whiteRect, pt)) {\r
         if (gameMode == EditPosition) {\r
-      SetWhiteToPlayEvent();\r
-    } else if (gameMode == IcsPlayingBlack ||\r
-           gameMode == MachinePlaysWhite) {\r
-      CallFlagEvent();\r
+         SetWhiteToPlayEvent();\r
+       } else if (gameMode == IcsPlayingBlack ||\r
+                  gameMode == MachinePlaysWhite) {\r
+         CallFlagEvent();\r
         } else if (gameMode == EditGame) {\r
           AdjustClock(flipClock, -1);\r
         }\r
       } else if (PtInRect((LPRECT) &blackRect, pt)) {\r
-    if (gameMode == EditPosition) {\r
-      SetBlackToPlayEvent();\r
-    } else if (gameMode == IcsPlayingWhite ||\r
-           gameMode == MachinePlaysBlack) {\r
-      CallFlagEvent();\r
+       if (gameMode == EditPosition) {\r
+         SetBlackToPlayEvent();\r
+       } else if (gameMode == IcsPlayingWhite ||\r
+                  gameMode == MachinePlaysBlack) {\r
+         CallFlagEvent();\r
         } else if (gameMode == EditGame) {\r
           AdjustClock(!flipClock, -1);\r
-    }\r
+       }\r
       }\r
-      if (!appData.highlightLastMove) {\r
-        ClearHighlights();\r
-    DrawPosition((int) (forceFullRepaint || FALSE), NULL);\r
-      }\r
-      fromX = fromY = -1;\r
-      dragInfo.start.x = dragInfo.start.y = -1;\r
-      dragInfo.from = dragInfo.start;\r
-      break;\r
-    } else if (x < 0 || y < 0\r
-      /* [HGM] block clicks between board and holdings */\r
-              || x == BOARD_LEFT-1 || x == BOARD_RGHT\r
-              || (x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize)\r
-              || (x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize)\r
-    /* EditPosition, empty square, or different color piece;\r
-       click-click move is possible */\r
-                               ) {\r
-      break;\r
-    } else if (fromX == x && fromY == y) {\r
-      /* Downclick on same square again */\r
-      ClearHighlights();\r
-      DrawPosition(forceFullRepaint || FALSE, NULL);\r
-      sameAgain = TRUE;\r
-    } else if (fromX != -1 &&\r
-               x != BOARD_LEFT-2 && x != BOARD_RGHT+1\r
-                                                                        ) {\r
-      /* Downclick on different square. */\r
-      /* [HGM] if on holdings file, should count as new first click ! */\r
-      /* [HGM] <sameColor> now always do UserMoveTest(), and check colors there */\r
-    toX = x;\r
-    toY = y;\r
-        /* [HGM] <popupFix> UserMoveEvent requires two calls now,\r
-           to make sure move is legal before showing promotion popup */\r
-        moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR, FALSE);\r
-    if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */\r
-        fromX = fromY = -1;\r
-        ClearHighlights();\r
-        DrawPosition(FALSE, boards[currentMove]);\r
-        break;\r
-    } else\r
-        if(moveType != ImpossibleMove && moveType != Comment) {\r
-          /* [HGM] We use PromotionToKnight in Shogi to indicate frorced promotion */\r
-          if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight ||\r
-            ((moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) &&\r
-              appData.alwaysPromoteToQueen)) {\r
-                  FinishMove(moveType, fromX, fromY, toX, toY, 'q');\r
-                  if (!appData.highlightLastMove) {\r
-                      ClearHighlights();\r
-                      DrawPosition(forceFullRepaint || FALSE, NULL);\r
-                  }\r
-          } else\r
-          if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) {\r
-                  SetHighlights(fromX, fromY, toX, toY);\r
-                  DrawPosition(forceFullRepaint || FALSE, NULL);\r
-                  /* [HGM] <popupFix> Popup calls FinishMove now.\r
-                     If promotion to Q is legal, all are legal! */\r
-          if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)\r
-          { ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX];\r
-            // kludge to temporarily execute move on display, without promoting yet\r
-            promotionChoice = TRUE;\r
-            boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank\r
-            boards[currentMove][toY][toX] = p;\r
-            DrawPosition(FALSE, boards[currentMove]);\r
-            boards[currentMove][fromY][fromX] = p; // take back, but display stays\r
-            boards[currentMove][toY][toX] = q;\r
-            DisplayMessage("Select piece from holdings", "");\r
-          } else\r
-                  PromotionPopup(hwnd);\r
-          goto noClear;\r
-          } else { // not a promotion. Move can be illegal if testLegality off, and should be made then.\r
-             if (appData.animate || appData.highlightLastMove) {\r
-                 SetHighlights(fromX, fromY, toX, toY);\r
-             } else {\r
-                 ClearHighlights();\r
-             }\r
-             FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);\r
-             if (appData.animate && !appData.highlightLastMove) {\r
-                  ClearHighlights();\r
-                  DrawPosition(forceFullRepaint || FALSE, NULL);\r
-             }\r
-          }\r
-          fromX = fromY = -1;\r
-    noClear:\r
-      break;\r
-        }\r
-        if (gotPremove && moveType != Comment) {\r
-        SetPremoveHighlights(fromX, fromY, toX, toY);\r
-//            DrawPosition(forceFullRepaint || FALSE, NULL);\r
-    } else ClearHighlights();\r
-        fromX = fromY = -1;\r
-        DrawPosition(forceFullRepaint || FALSE, NULL);\r
-    if(moveType != Comment) break;\r
-    }\r
-    /* First downclick, or restart on a square with same color piece */\r
-    if (!frozen && OKToStartUserMove(x, y)) {\r
-      fromX = x;\r
-      fromY = y;\r
-      dragInfo.lastpos = pt;\r
-      dragInfo.from.x = fromX;\r
-      dragInfo.from.y = fromY;\r
-      dragInfo.start = dragInfo.from;\r
-      SetCapture(hwndMain);\r
-    } else {\r
-      fromX = fromY = -1;\r
       dragInfo.start.x = dragInfo.start.y = -1;\r
       dragInfo.from = dragInfo.start;\r
+    if(fromX == -1 && frozen) { // not sure where this is for\r
+               fromX = fromY = -1; \r
       DrawPosition(forceFullRepaint || FALSE, NULL); /* [AS] */\r
+      break;\r
     }\r
+      LeftClick(Press, pt.x - boardRect.left, pt.y - boardRect.top);\r
+      DrawPosition(TRUE, NULL);\r
     break;\r
 \r
   case WM_LBUTTONUP:\r
-    ReleaseCapture();\r
-    if (fromX == -1) break;\r
-    if (x == fromX && y == fromY) {\r
-      dragInfo.from.x = dragInfo.from.y = -1;\r
-      /* Upclick on same square */\r
-      if (sameAgain) {\r
-    /* Clicked same square twice: abort click-click move */\r
-    fromX = fromY = -1;\r
-    gotPremove = 0;\r
-    ClearPremoveHighlights();\r
-      } else {\r
-    /* First square clicked: start click-click move */\r
-    SetHighlights(fromX, fromY, -1, -1);\r
-      }\r
-      DrawPosition(forceFullRepaint || FALSE, NULL);\r
-    } else if (dragInfo.from.x < 0 || dragInfo.from.y < 0) {\r
-      /* Errant click; ignore */\r
-      break;\r
-    } else {\r
-      /* Finish drag move. */\r
-    if (appData.debugMode) {\r
-        fprintf(debugFP, "release\n");\r
-    }\r
-      dragInfo.from.x = dragInfo.from.y = -1;\r
-      toX = x;\r
-      toY = y;\r
-      saveAnimate = appData.animate; /* sorry, Hawk :) */\r
-      appData.animate = appData.animate && !appData.animateDragging;\r
-      moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR, TRUE);\r
-      if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */\r
-        fromX = fromY = -1;\r
-        ClearHighlights();\r
-        DrawPosition(FALSE, boards[currentMove]);\r
-        appData.animate = saveAnimate;\r
-        break;\r
-      } else\r
-      if(moveType != ImpossibleMove) {\r
-          /* [HGM] use move type to determine if move is promotion.\r
-             Knight is Shogi kludge for mandatory promotion, Queen means choice */\r
-          if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight ||\r
-            ((moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) &&\r
-              appData.alwaysPromoteToQueen))\r
-               FinishMove(moveType, fromX, fromY, toX, toY, 'q');\r
-          else\r
-          if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) {\r
-               DrawPosition(forceFullRepaint || FALSE, NULL);\r
-          if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)\r
-          { ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX];\r
-            // kludge to temporarily execute move on display, wthout promotng yet\r
-            promotionChoice = TRUE;\r
-            boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank\r
-            boards[currentMove][toY][toX] = p;\r
-            DrawPosition(FALSE, boards[currentMove]);\r
-            boards[currentMove][fromY][fromX] = p; // take back, but display stays\r
-            boards[currentMove][toY][toX] = q;\r
-            appData.animate = saveAnimate;\r
-            DisplayMessage("Select piece from holdings", "");\r
-            break;\r
-          } else\r
-               PromotionPopup(hwnd); /* [HGM] Popup now calls FinishMove */\r
-          } else {\r
-        if(saveAnimate /* ^$!%@#$!$ */  && gameInfo.variant == VariantAtomic\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
-      if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);\r
-      appData.animate = saveAnimate;\r
-      fromX = fromY = -1;\r
-      if (appData.highlightDragging && !appData.highlightLastMove) {\r
-    ClearHighlights();\r
-      }\r
-      if (appData.animate || appData.animateDragging ||\r
-      appData.highlightDragging || gotPremove) {\r
-    DrawPosition(forceFullRepaint || FALSE, NULL);\r
-      }\r
-    }\r
-    dragInfo.start.x = dragInfo.start.y = -1;\r
-    dragInfo.pos = dragInfo.lastpos = dragInfo.start;\r
+      LeftClick(Release, pt.x - boardRect.left, pt.y - boardRect.top);\r
+      DrawPosition(TRUE, NULL);\r
     break;\r
 \r
   case WM_MOUSEMOVE:\r
+    if(SeekGraphClick(Press, pt.x - boardRect.left, pt.y - boardRect.top, 1)) break;\r
+    MovePV(pt.x - boardRect.left, pt.y - boardRect.top, boardRect.bottom - boardRect.top);\r
     if ((appData.animateDragging || appData.highlightDragging)\r
-    && (wParam & MK_LBUTTON)\r
-    && dragInfo.from.x >= 0)\r
+       && (wParam & MK_LBUTTON)\r
+       && dragInfo.from.x >= 0) \r
     {\r
       BOOL full_repaint = FALSE;\r
 \r
-      sameAgain = FALSE; /* [HGM] if we drag something around, do keep square selected */\r
       if (appData.animateDragging) {\r
-    dragInfo.pos = pt;\r
+       dragInfo.pos = pt;\r
       }\r
       if (appData.highlightDragging) {\r
-    SetHighlights(fromX, fromY, x, y);\r
+       SetHighlights(fromX, fromY, x, y);\r
         if( IsDrawArrowEnabled() && (x < 0 || x >= BOARD_WIDTH || y < 0 || y >= BOARD_HEIGHT) ) {\r
             full_repaint = TRUE;\r
         }\r
       }\r
-\r
+      \r
       DrawPosition( full_repaint, NULL);\r
-\r
+      \r
       dragInfo.lastpos = dragInfo.pos;\r
     }\r
     break;\r
@@ -5311,16 +3808,22 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        /* Mouse Wheel is being rolled forward\r
         * Play moves forward\r
         */\r
-       if((short)HIWORD(wParam) > 0 && currentMove < forwardMostMove)\r
-        { if(lastDir == 1) ForwardEvent(); else lastDir = 1; } // [HGM] suppress first event in direction\r
+       if((short)HIWORD(wParam) > 0 && currentMove < forwardMostMove) \r
+               { if(lastDir == 1) ForwardEvent(); else lastDir = 1; } // [HGM] suppress first event in direction\r
        /* Mouse Wheel is being rolled backward\r
         * Play moves backward\r
         */\r
-       if((short)HIWORD(wParam) < 0 && currentMove > backwardMostMove)\r
-        { if(lastDir == -1) BackwardEvent(); else lastDir = -1; }\r
+       if((short)HIWORD(wParam) < 0 && currentMove > backwardMostMove) \r
+               { if(lastDir == -1) BackwardEvent(); else lastDir = -1; }\r
     }\r
     break;\r
 \r
+  case WM_MBUTTONUP:\r
+  case WM_RBUTTONUP:\r
+    ReleaseCapture();\r
+    RightClick(Release, pt.x - boardRect.left, pt.y - boardRect.top, &fromX, &fromY);\r
+    break;\r
\r
   case WM_MBUTTONDOWN:\r
   case WM_RBUTTONDOWN:\r
     ErrorPopDown();\r
@@ -5343,54 +3846,32 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     }\r
     DrawPosition(TRUE, NULL);\r
 \r
-    switch (gameMode) {\r
-    case EditPosition:\r
-    case IcsExamining:\r
-      if (x < 0 || y < 0) break;\r
-      fromX = x;\r
-      fromY = y;\r
+    menuNr = RightClick(Press, pt.x - boardRect.left, pt.y - boardRect.top, &fromX, &fromY);\r
+    switch (menuNr) {\r
+    case 0:\r
       if (message == WM_MBUTTONDOWN) {\r
-    buttonCount = 3;  /* even if system didn't think so */\r
-    if (wParam & MK_SHIFT)\r
-      MenuPopup(hwnd, pt, LoadMenu(hInst, "BlackPieceMenu"), -1);\r
-    else\r
-      MenuPopup(hwnd, pt, LoadMenu(hInst, "WhitePieceMenu"), -1);\r
+       buttonCount = 3;  /* even if system didn't think so */\r
+       if (wParam & MK_SHIFT) \r
+         MenuPopup(hwnd, pt, LoadMenu(hInst, "BlackPieceMenu"), -1);\r
+       else\r
+         MenuPopup(hwnd, pt, LoadMenu(hInst, "WhitePieceMenu"), -1);\r
       } else { /* message == WM_RBUTTONDOWN */\r
-#if 0\r
-    if (buttonCount == 3) {\r
-      if (wParam & MK_SHIFT)\r
-        MenuPopup(hwnd, pt, LoadMenu(hInst, "WhitePieceMenu"), -1);\r
-      else\r
-        MenuPopup(hwnd, pt, LoadMenu(hInst, "BlackPieceMenu"), -1);\r
-    } else {\r
-      MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\r
-    }\r
-#else\r
-    /* Just have one menu, on the right button.  Windows users don't\r
-       think to try the middle one, and sometimes other software steals\r
-       it, or it doesn't really exist. */\r
+       /* Just have one menu, on the right button.  Windows users don't\r
+          think to try the middle one, and sometimes other software steals\r
+          it, or it doesn't really exist. */\r
         if(gameInfo.variant != VariantShogi)\r
             MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\r
         else\r
             MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1);\r
-#endif\r
       }\r
       break;\r
-    case IcsPlayingWhite:\r
-    case IcsPlayingBlack:\r
-    case EditGame:\r
-    case MachinePlaysWhite:\r
-    case MachinePlaysBlack:\r
-      if (appData.testLegality &&\r
-      gameInfo.variant != VariantBughouse &&\r
-      gameInfo.variant != VariantCrazyhouse) break;\r
-      if (x < 0 || y < 0) break;\r
-      fromX = x;\r
-      fromY = y;\r
+    case 2:\r
+      SetCapture(hwndMain);
+      break;\r
+    case 1:\r
       hmenu = LoadMenu(hInst, "DropPieceMenu");\r
       SetupDropMenu(hmenu);\r
       MenuPopup(hwnd, pt, hmenu, -1);\r
-      break;\r
     default:\r
       break;\r
     }\r
@@ -5428,14 +3909,14 @@ ButtonProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       return TRUE;\r
     default:\r
       if (appData.icsActive && (isalpha((char)wParam) || wParam == '0')) {\r
-    // [HGM] movenum: only letters or leading zero should go to ICS input\r
+       // [HGM] movenum: only letters or leading zero should go to ICS input\r
         HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
-    if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
-    SetFocus(h);\r
-    SendMessage(h, WM_CHAR, wParam, lParam);\r
-    return TRUE;\r
+       if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
+       SetFocus(h);\r
+       SendMessage(h, WM_CHAR, wParam, lParam);\r
+       return TRUE;\r
       } else if (isalpha((char)wParam) || isdigit((char)wParam)){\r
-    PopUpMoveDialog((char)wParam);\r
+       PopUpMoveDialog((char)wParam);\r
       }\r
       break;\r
     }\r
@@ -5454,39 +3935,39 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
   case WM_INITDIALOG: /* message: initialize dialog box */\r
     /* Center the dialog over the application window */\r
     CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
-    ShowWindow(GetDlgItem(hDlg, PB_King),\r
+    ShowWindow(GetDlgItem(hDlg, PB_King), \r
       (!appData.testLegality || gameInfo.variant == VariantSuicide ||\r
        gameInfo.variant == VariantGiveaway || gameInfo.variant == VariantSuper ) ?\r
-           SW_SHOW : SW_HIDE);\r
+              SW_SHOW : SW_HIDE);\r
     /* [HGM] Only allow C & A promotions if these pieces are defined */\r
     ShowWindow(GetDlgItem(hDlg, PB_Archbishop),\r
        ((PieceToChar(WhiteAngel) >= 'A' &&\r
          PieceToChar(WhiteAngel) != '~') ||\r
         (PieceToChar(BlackAngel) >= 'A' &&\r
          PieceToChar(BlackAngel) != '~')   ) ?\r
-           SW_SHOW : SW_HIDE);\r
-    ShowWindow(GetDlgItem(hDlg, PB_Chancellor),\r
+              SW_SHOW : SW_HIDE);\r
+    ShowWindow(GetDlgItem(hDlg, PB_Chancellor), \r
        ((PieceToChar(WhiteMarshall) >= 'A' &&\r
          PieceToChar(WhiteMarshall) != '~') ||\r
         (PieceToChar(BlackMarshall) >= 'A' &&\r
          PieceToChar(BlackMarshall) != '~')   ) ?\r
-           SW_SHOW : SW_HIDE);\r
+              SW_SHOW : SW_HIDE);\r
     /* [HGM] Hide B & R button in Shogi, use Q as promote, N as defer */\r
     ShowWindow(GetDlgItem(hDlg, PB_Rook),\r
        gameInfo.variant != VariantShogi ?\r
-           SW_SHOW : SW_HIDE);\r
-    ShowWindow(GetDlgItem(hDlg, PB_Bishop),\r
+              SW_SHOW : SW_HIDE);\r
+    ShowWindow(GetDlgItem(hDlg, PB_Bishop), \r
        gameInfo.variant != VariantShogi ?\r
-           SW_SHOW : SW_HIDE);\r
-    ShowWindow(GetDlgItem(hDlg, IDC_Yes),\r
+              SW_SHOW : SW_HIDE);\r
+    ShowWindow(GetDlgItem(hDlg, IDC_Yes), \r
        gameInfo.variant == VariantShogi ?\r
-           SW_SHOW : SW_HIDE);\r
-    ShowWindow(GetDlgItem(hDlg, IDC_No),\r
+              SW_SHOW : SW_HIDE);\r
+    ShowWindow(GetDlgItem(hDlg, IDC_No), \r
        gameInfo.variant == VariantShogi ?\r
-           SW_SHOW : SW_HIDE);\r
-    ShowWindow(GetDlgItem(hDlg, IDC_Centaur),\r
+              SW_SHOW : SW_HIDE);\r
+    ShowWindow(GetDlgItem(hDlg, IDC_Centaur), \r
        gameInfo.variant == VariantSuper ?\r
-           SW_SHOW : SW_HIDE);\r
+              SW_SHOW : SW_HIDE);\r
     return TRUE;\r
 \r
   case WM_COMMAND: /* message: received a command */\r
@@ -5525,7 +4006,8 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
        only show the popup when we are already sure the move is valid or\r
        legal. We pass a faulty move type, but the kludge is that FinishMove\r
        will figure out it is a promotion from the promoChar. */\r
-    FinishMove(NormalMove, fromX, fromY, toX, toY, promoChar);\r
+    UserMoveEvent(fromX, fromY, toX, toY, promoChar);\r
+    fromX = fromY = -1;\r
     if (!appData.highlightLastMove) {\r
       ClearHighlights();\r
       DrawPosition(FALSE, NULL);\r
@@ -5547,6 +4029,13 @@ PromotionPopup(HWND hwnd)
   FreeProcInstance(lpProc);\r
 }\r
 \r
+void\r
+PromotionPopUp()\r
+{\r
+  DrawPosition(TRUE, NULL);\r
+  PromotionPopup(hwndMain);\r
+}\r
+\r
 /* Toggle ShowThinking */\r
 VOID\r
 ToggleShowThinking()\r
@@ -5562,9 +4051,9 @@ LoadGameDialog(HWND hwnd, char* title)
   FILE *f;\r
   char fileTitle[MSG_SIZ];\r
   f = OpenFileDialog(hwnd, "rb", "",\r
-                 appData.oldSaveStyle ? "gam" : "pgn",\r
-             GAME_FILT,\r
-             title, &number, fileTitle, NULL);\r
+                    appData.oldSaveStyle ? "gam" : "pgn",\r
+                    GAME_FILT,\r
+                    title, &number, fileTitle, NULL);\r
   if (f != NULL) {\r
     cmailMsgLoaded = FALSE;\r
     if (number == 0) {\r
@@ -5573,7 +4062,7 @@ LoadGameDialog(HWND hwnd, char* title)
         DisplayError("Cannot build game list", error);\r
       } else if (!ListEmpty(&gameList) &&\r
                  ((ListGame *) gameList.tailPred)->number > 1) {\r
-    GameListPopUp(f, fileTitle);\r
+       GameListPopUp(f, fileTitle);\r
         return;\r
       }\r
       GameListDestroy();\r
@@ -5583,6 +4072,57 @@ LoadGameDialog(HWND hwnd, char* title)
   }\r
 }\r
 \r
+int get_term_width()\r
+{\r
+    HDC hdc;\r
+    TEXTMETRIC tm;\r
+    RECT rc;\r
+    HFONT hfont, hold_font;\r
+    LOGFONT lf;\r
+    HWND hText;\r
+\r
+    if (hwndConsole)\r
+        hText = GetDlgItem(hwndConsole, OPT_ConsoleText);\r
+    else\r
+        return 79;\r
+\r
+    // get the text metrics\r
+    hdc = GetDC(hText);\r
+    lf = font[boardSize][CONSOLE_FONT]->lf;\r
+    if (consoleCF.dwEffects & CFE_BOLD)\r
+        lf.lfWeight = FW_BOLD;\r
+    if (consoleCF.dwEffects & CFE_ITALIC)\r
+        lf.lfItalic = TRUE;\r
+    if (consoleCF.dwEffects & CFE_STRIKEOUT)\r
+        lf.lfStrikeOut = TRUE;\r
+    if (consoleCF.dwEffects & CFE_UNDERLINE)\r
+        lf.lfUnderline = TRUE;\r
+    hfont = CreateFontIndirect(&lf);\r
+    hold_font = SelectObject(hdc, hfont);\r
+    GetTextMetrics(hdc, &tm);\r
+    SelectObject(hdc, hold_font);\r
+    DeleteObject(hfont);\r
+    ReleaseDC(hText, hdc);\r
+\r
+    // get the rectangle\r
+    SendMessage(hText, EM_GETRECT, 0, (LPARAM)&rc);\r
+\r
+    return (rc.right-rc.left) / tm.tmAveCharWidth;\r
+}\r
+\r
+void UpdateICSWidth(HWND hText)\r
+{\r
+    LONG old_width, new_width;\r
+\r
+    new_width = get_term_width(hText, FALSE);\r
+    old_width = GetWindowLong(hText, GWL_USERDATA);\r
+    if (new_width != old_width)\r
+    {\r
+        ics_update_width(new_width);\r
+        SetWindowLong(hText, GWL_USERDATA, new_width);\r
+    }\r
+}\r
+\r
 VOID\r
 ChangedConsoleFont()\r
 {\r
@@ -5603,16 +4143,16 @@ ChangedConsoleFont()
   cfmt.yHeight = (int)(f->mfp.pointSize * 20.0 + 0.5);\r
   cfmt.bCharSet = f->lf.lfCharSet;\r
   cfmt.bPitchAndFamily = f->lf.lfPitchAndFamily;\r
-  SendMessage(hText, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cfmt);\r
-  SendMessage(hInput, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cfmt);\r
+  SendMessage(hText, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cfmt); \r
+  SendMessage(hInput, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cfmt); \r
   /* Why are the following seemingly needed too? */\r
-  SendMessage(hText, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfmt);\r
-  SendMessage(hInput, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfmt);\r
+  SendMessage(hText, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfmt); \r
+  SendMessage(hInput, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfmt); \r
   SendMessage(hText, EM_EXGETSEL, 0, (LPARAM)&sel);\r
   tmpsel.cpMin = 0;\r
   tmpsel.cpMax = -1; /*999999?*/\r
   SendMessage(hText, EM_EXSETSEL, 0, (LPARAM)&tmpsel);\r
-  SendMessage(hText, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cfmt);\r
+  SendMessage(hText, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cfmt); \r
   /* Trying putting this here too.  It still seems to tickle a RichEdit\r
    *  bug: sometimes RichEdit indents the first line of a paragraph too.\r
    */\r
@@ -5622,6 +4162,7 @@ ChangedConsoleFont()
   paraf.dxOffset = WRAP_INDENT;\r
   SendMessage(hText, EM_SETPARAFORMAT, 0, (LPARAM) &paraf);\r
   SendMessage(hText, EM_EXSETSEL, 0, (LPARAM)&sel);\r
+  UpdateICSWidth(hText);\r
 }\r
 \r
 /*---------------------------------------------------------------------------*\\r
@@ -5672,20 +4213,20 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
   JAWS_KB_NAVIGATION\r
 \r
   case WM_CHAR:\r
-\r
+    \r
     JAWS_ALT_INTERCEPT\r
 \r
-    if (appData.icsActive && (char)wParam > ' ' && !((char)wParam >= '1' && (char)wParam <= '9')) {\r
-    // [HGM] movenum: for non-zero digits we always do type-in dialog\r
-    HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
-    if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
-    SetFocus(h);\r
-    SendMessage(h, message, wParam, lParam);\r
+    if (appData.icsActive && ((char)wParam == '\r' || (char)wParam > ' ' && !((char)wParam >= '1' && (char)wParam <= '9'))) { \r
+       // [HGM] movenum: for non-zero digits we always do type-in dialog\r
+       HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
+       if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
+       SetFocus(h);\r
+       SendMessage(h, message, wParam, lParam);\r
     } else if(lParam != KF_REPEAT) {\r
-    if (isalpha((char)wParam) || isdigit((char)wParam)) {\r
-        PopUpMoveDialog((char)wParam);\r
-    } else if((char)wParam == 003) CopyGameToClipboard();\r
-     else if((char)wParam == 026) PasteGameOrFENFromClipboard();\r
+       if (isalpha((char)wParam) || isdigit((char)wParam)) {\r
+               PopUpMoveDialog((char)wParam);\r
+       } else if((char)wParam == 003) CopyGameToClipboard();\r
+        else if((char)wParam == 026) PasteGameOrFENFromClipboard();\r
     }\r
 \r
     break;\r
@@ -5697,12 +4238,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       SelectPalette(hdc, hPal, TRUE);\r
       nnew = RealizePalette(hdc);\r
       if (nnew > 0) {\r
-    paletteChanged = TRUE;\r
-#if 0\r
-        UpdateColors(hdc);\r
-#else\r
-        InvalidateRect(hwnd, &boardRect, FALSE);/*faster!*/\r
-#endif\r
+       paletteChanged = TRUE;\r
+        InvalidateRect(hwnd, &boardRect, FALSE);\r
       }\r
       ReleaseDC(hwnd, hdc);\r
     }\r
@@ -5716,7 +4253,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       SelectPalette(hdc, hPal, FALSE);\r
       nnew = RealizePalette(hdc);\r
       if (nnew > 0) {\r
-    InvalidateRect(hwnd, &boardRect, FALSE);\r
+       InvalidateRect(hwnd, &boardRect, FALSE);\r
       }\r
       ReleaseDC(hwnd, hdc);\r
       return TRUE;\r
@@ -5730,14 +4267,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     switch (wmId) {\r
     case IDM_NewGame:\r
       ResetGameEvent();\r
-      AnalysisPopDown();\r
       SAY("new game enter a move to play against the computer with white");\r
       break;\r
 \r
     case IDM_NewGameFRC:\r
       if( NewGameFRC() == 0 ) {\r
         ResetGameEvent();\r
-        AnalysisPopDown();\r
       }\r
       break;\r
 \r
@@ -5767,11 +4302,11 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       }\r
       number = 1;\r
       f = OpenFileDialog(hwnd, "rb", "",\r
-             appData.oldSaveStyle ? "pos" : "fen",\r
-             POSITION_FILT,\r
-             "Load Position from File", &number, fileTitle, NULL);\r
+                        appData.oldSaveStyle ? "pos" : "fen",\r
+                        POSITION_FILT,\r
+                        "Load Position from File", &number, fileTitle, NULL);\r
       if (f != NULL) {\r
-    LoadPosition(f, number, fileTitle);\r
+       LoadPosition(f, number, fileTitle);\r
       }\r
       break;\r
 \r
@@ -5790,33 +4325,33 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case IDM_SaveGame:\r
       defName = DefaultFileName(appData.oldSaveStyle ? "gam" : "pgn");\r
       f = OpenFileDialog(hwnd, "a", defName,\r
-             appData.oldSaveStyle ? "gam" : "pgn",\r
-             GAME_FILT,\r
-             "Save Game to File", NULL, fileTitle, NULL);\r
+                        appData.oldSaveStyle ? "gam" : "pgn",\r
+                        GAME_FILT,\r
+                        "Save Game to File", NULL, fileTitle, NULL);\r
       if (f != NULL) {\r
-    SaveGame(f, 0, "");\r
+       SaveGame(f, 0, "");\r
       }\r
       break;\r
 \r
     case IDM_SavePosition:\r
       defName = DefaultFileName(appData.oldSaveStyle ? "pos" : "fen");\r
       f = OpenFileDialog(hwnd, "a", defName,\r
-             appData.oldSaveStyle ? "pos" : "fen",\r
-             POSITION_FILT,\r
-             "Save Position to File", NULL, fileTitle, NULL);\r
+                        appData.oldSaveStyle ? "pos" : "fen",\r
+                        POSITION_FILT,\r
+                        "Save Position to File", NULL, fileTitle, NULL);\r
       if (f != NULL) {\r
-    SavePosition(f, 0, "");\r
+       SavePosition(f, 0, "");\r
       }\r
       break;\r
 \r
     case IDM_SaveDiagram:\r
       defName = "diagram";\r
       f = OpenFileDialog(hwnd, "wb", defName,\r
-             "bmp",\r
-             DIAGRAM_FILT,\r
-             "Save Diagram to File", NULL, fileTitle, NULL);\r
+                        "bmp",\r
+                        DIAGRAM_FILT,\r
+                        "Save Diagram to File", NULL, fileTitle, NULL);\r
       if (f != NULL) {\r
-    SaveDiagram(f);\r
+       SaveDiagram(f);\r
       }\r
       break;\r
 \r
@@ -5854,7 +4389,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         }\r
         else {\r
             EvalGraphPopUp();\r
-        SetFocus(hwndMain);\r
+           SetFocus(hwndMain);\r
         }\r
         break;\r
 \r
@@ -5887,7 +4422,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       break;\r
 \r
     case IDM_NewChat:\r
-      ChatPopUp();\r
+      ChatPopUp(NULL);\r
       break;\r
 \r
     case IDM_CopyPosition:\r
@@ -5921,10 +4456,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        * refresh the tags dialog only if it's visible\r
        */\r
       if (gameMode == MachinePlaysWhite && IsWindowVisible(editTagsDialog)) {\r
-      char *tags;\r
-      tags = PGNTags(&gameInfo);\r
-      TagsPopUp(tags, CmailMsg());\r
-      free(tags);\r
+         char *tags;\r
+         tags = PGNTags(&gameInfo);\r
+         TagsPopUp(tags, CmailMsg());\r
+         free(tags);\r
       }\r
       SAY("computer starts playing white");\r
       break;\r
@@ -5935,10 +4470,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        * refresh the tags dialog only if it's visible\r
        */\r
       if (gameMode == MachinePlaysBlack && IsWindowVisible(editTagsDialog)) {\r
-      char *tags;\r
-      tags = PGNTags(&gameInfo);\r
-      TagsPopUp(tags, CmailMsg());\r
-      free(tags);\r
+         char *tags;\r
+         tags = PGNTags(&gameInfo);\r
+         TagsPopUp(tags, CmailMsg());\r
+         free(tags);\r
       }\r
       SAY("computer starts playing black");\r
       break;\r
@@ -5949,10 +4484,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        * refresh the tags dialog only if it's visible\r
        */\r
       if (gameMode == TwoMachinesPlay && IsWindowVisible(editTagsDialog)) {\r
-      char *tags;\r
-      tags = PGNTags(&gameInfo);\r
-      TagsPopUp(tags, CmailMsg());\r
-      free(tags);\r
+         char *tags;\r
+         tags = PGNTags(&gameInfo);\r
+         TagsPopUp(tags, CmailMsg());\r
+         free(tags);\r
       }\r
       SAY("programs start playing each other");\r
       break;\r
@@ -5962,7 +4497,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         sprintf(buf, "%s does not support analysis", first.tidy);\r
         DisplayError(buf, 0);\r
       } else {\r
-    SAY("analyzing current position");\r
+       SAY("analyzing current position");\r
         /* [DM] icsEngineAnlyze [HGM] Why is this front-end??? */\r
         if (appData.icsActive) {\r
                if (gameMode != IcsObserving) {\r
@@ -5970,7 +4505,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                        DisplayError(buf, 0);\r
                        /* secure check */\r
                        if (appData.icsEngineAnalyze) {\r
-                               if (appData.debugMode)\r
+                               if (appData.debugMode) \r
                                        fprintf(debugFP, "Found unexpected active ICS engine analyze \n");\r
                                ExitAnalyzeMode();\r
                                ModeHighlight();\r
@@ -5987,9 +4522,9 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                        appData.icsEngineAnalyze = TRUE;\r
                        if (appData.debugMode) fprintf(debugFP, "ICS engine analyze starting...\n");\r
                }\r
-        }\r
-    if (!appData.showThinking) ToggleShowThinking();\r
-    AnalyzeModeEvent();\r
+        } \r
+       if (!appData.showThinking) ToggleShowThinking();\r
+       AnalyzeModeEvent();\r
       }\r
       break;\r
 \r
@@ -5999,10 +4534,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         sprintf(buf, "%s does not support analysis", first.tidy);\r
         DisplayError(buf, 0);\r
       } else {\r
-    if (!appData.showThinking) ToggleShowThinking();\r
-    AnalyzeFileEvent();\r
-    LoadGameDialog(hwnd, "Analyze Game from File");\r
-    AnalysisPeriodicEvent(1);\r
+       if (!appData.showThinking) ToggleShowThinking();\r
+       AnalyzeFileEvent();\r
+       LoadGameDialog(hwnd, "Analyze Game from File");\r
+       AnalysisPeriodicEvent(1);\r
       }\r
       break;\r
 \r
@@ -6033,10 +4568,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       break;\r
 \r
     case IDM_EditComment:\r
-      if (commentDialogUp && editComment) {\r
-    CommentPopDown();\r
+      if (commentUp && editComment) {\r
+       CommentPopDown();\r
       } else {\r
-    EditCommentEvent();\r
+       EditCommentEvent();\r
       }\r
       break;\r
 \r
@@ -6143,8 +4678,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 \r
     case IDM_MuteSounds:\r
       mute = !mute; // [HGM] mute: keep track of global muting variable\r
-      CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds,\r
-                MF_BYCOMMAND|(mute?MF_CHECKED:MF_UNCHECKED));\r
+      CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds, \r
+                               MF_BYCOMMAND|(mute?MF_CHECKED:MF_UNCHECKED));\r
       break;\r
 \r
     case IDM_GeneralOptions:\r
@@ -6207,8 +4742,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case IDM_SaveSettingsOnExit:\r
       saveSettingsOnExit = !saveSettingsOnExit;\r
       (void) CheckMenuItem(GetMenu(hwndMain), IDM_SaveSettingsOnExit,\r
-               MF_BYCOMMAND|(saveSettingsOnExit ?\r
-                     MF_CHECKED : MF_UNCHECKED));\r
+                          MF_BYCOMMAND|(saveSettingsOnExit ?\r
+                                        MF_CHECKED : MF_UNCHECKED));\r
       break;\r
 \r
     case IDM_Hint:\r
@@ -6226,59 +4761,59 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case IDM_Debug:\r
       appData.debugMode = !appData.debugMode;\r
       if (appData.debugMode) {\r
-    char dir[MSG_SIZ];\r
-    GetCurrentDirectory(MSG_SIZ, dir);\r
-    SetCurrentDirectory(installDir);\r
-    debugFP = fopen(appData.nameOfDebugFile, "w");\r
+       char dir[MSG_SIZ];\r
+       GetCurrentDirectory(MSG_SIZ, dir);\r
+       SetCurrentDirectory(installDir);\r
+       debugFP = fopen(appData.nameOfDebugFile, "w");\r
         SetCurrentDirectory(dir);\r
         setbuf(debugFP, NULL);\r
       } else {\r
-    fclose(debugFP);\r
+       fclose(debugFP);\r
         debugFP = NULL;\r
       }\r
       break;\r
 \r
     case IDM_HELPCONTENTS:\r
       if (!MyHelp (hwnd, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS") &&\r
-      !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) {\r
-      MessageBox (GetFocus(),\r
-            "Unable to activate help",\r
-            szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
+         !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) {\r
+         MessageBox (GetFocus(),\r
+                   "Unable to activate help",\r
+                   szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
       }\r
       break;\r
 \r
     case IDM_HELPSEARCH:\r
         if (!MyHelp (hwnd, "winboard.hlp", HELP_PARTIALKEY, (DWORD)(LPSTR)"") &&\r
-        !HtmlHelp(hwnd, "winboard.chm", 0, 0)   ) {\r
-    MessageBox (GetFocus(),\r
-            "Unable to activate help",\r
-            szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
+           !HtmlHelp(hwnd, "winboard.chm", 0, 0)       ) {\r
+       MessageBox (GetFocus(),\r
+                   "Unable to activate help",\r
+                   szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
       }\r
       break;\r
 \r
     case IDM_HELPHELP:\r
       if(!WinHelp(hwnd, (LPSTR)NULL, HELP_HELPONHELP, 0)) {\r
-    MessageBox (GetFocus(),\r
-            "Unable to activate help",\r
-            szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
+       MessageBox (GetFocus(),\r
+                   "Unable to activate help",\r
+                   szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
       }\r
       break;\r
 \r
     case IDM_ABOUT:\r
       lpProc = MakeProcInstance((FARPROC)About, hInst);\r
-      DialogBox(hInst,\r
-    (gameInfo.event && strcmp(gameInfo.event, "Easter Egg Hunt") == 0) ?\r
-    "AboutBox2" : "AboutBox", hwnd, (DLGPROC)lpProc);\r
+      DialogBox(hInst, \r
+       (gameInfo.event && strcmp(gameInfo.event, "Easter Egg Hunt") == 0) ?\r
+       "AboutBox2" : "AboutBox", hwnd, (DLGPROC)lpProc);\r
       FreeProcInstance(lpProc);\r
       break;\r
 \r
     case IDM_DirectCommand1:\r
       AskQuestionEvent("Direct Command",\r
-               "Send to chess program:", "", "1");\r
+                      "Send to chess program:", "", "1");\r
       break;\r
     case IDM_DirectCommand2:\r
       AskQuestionEvent("Direct Command",\r
-               "Send to second chess program:", "", "2");\r
+                      "Send to second chess program:", "", "2");\r
       break;\r
 \r
     case EP_WhitePawn:\r
@@ -6476,10 +5011,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case ANALYSIS_TIMER_ID:\r
       if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile\r
                  || appData.icsEngineAnalyze) && appData.periodicUpdates) {\r
-    AnalysisPeriodicEvent(0);\r
+       AnalysisPeriodicEvent(0);\r
       } else {\r
-    KillTimer(hwnd, analysisTimerEvent);\r
-    analysisTimerEvent = 0;\r
+       KillTimer(hwnd, analysisTimerEvent);\r
+       analysisTimerEvent = 0;\r
       }\r
       break;\r
     case DELAYED_TIMER_ID:\r
@@ -6505,18 +5040,18 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             RECT rcMain;\r
 \r
 //            GetWindowRect( hwnd, &rcMain ); //[HGM] sticky: in XP this returned new position, not old\r
-        rcMain.left   = boardX;           //              replace by these 4 lines to reconstruct old rect\r
-        rcMain.right  = boardX + winWidth;\r
-        rcMain.top    = boardY;\r
-        rcMain.bottom = boardY + winHeight;\r
-\r
+           rcMain.left   = wpMain.x;           //              replace by these 4 lines to reconstruct old rect\r
+           rcMain.right  = wpMain.x + wpMain.width;\r
+           rcMain.top    = wpMain.y;\r
+           rcMain.bottom = wpMain.y + wpMain.height;\r
+            \r
             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
+           wpMain.x = lpwp->x;\r
+            wpMain.y = lpwp->y;\r
         }\r
     }\r
     break;\r
@@ -6566,7 +5101,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     }\r
     break;\r
 \r
-  default:  /* Passes it on if unprocessed */\r
+  default:     /* Passes it on if unprocessed */\r
     return (DefWindowProc(hwnd, message, wParam, lParam));\r
   }\r
   return 0;\r
@@ -6598,8 +5133,8 @@ mysrandom(unsigned int seed)
 }\r
 \r
 \r
-/*\r
- * returns TRUE if user selects a different color, FALSE otherwise\r
+/* \r
+ * returns TRUE if user selects a different color, FALSE otherwise \r
  */\r
 \r
 BOOL\r
@@ -6709,7 +5244,7 @@ MyPlaySound(MySound *ms)
   if(mute) return TRUE; // [HGM] mute: suppress all sound play when muted\r
   switch (ms->name[0]) {\r
   case NULLCHAR:\r
-    if(appData.debugMode) fprintf(debugFP, "silence\n");\r
+       if(appData.debugMode) fprintf(debugFP, "silence\n");\r
     /* Silence */\r
     ok = TRUE;\r
     break;\r
@@ -6720,7 +5255,7 @@ MyPlaySound(MySound *ms)
       ok = PlaySound(ms->name + 1, NULL, SND_ALIAS|SND_ASYNC);\r
     }\r
     if (!ok) ok = MessageBeep(MB_OK);\r
-    break;\r
+    break; \r
   case '!':\r
     /* Builtin wave resource, or "!" alone for silence */\r
     if (ms->name[1]) {\r
@@ -6739,13 +5274,6 @@ MyPlaySound(MySound *ms)
   /* Don't print an error: this can happen innocently if the sound driver\r
      is busy; for instance, if another instance of WinBoard is playing\r
      a sound at about the same time. */\r
-#if 0\r
-  if (!ok) {\r
-    char buf[MSG_SIZ];\r
-    sprintf(buf, "Error playing sound %s", ms->name);\r
-    DisplayError(buf, GetLastError());\r
-  }\r
-#endif\r
   return ok;\r
 }\r
 \r
@@ -6803,8 +5331,8 @@ OpenFileHook(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
 \r
 FILE *\r
 OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] diag: type of 'write' now string\r
-           char *nameFilt, char *dlgTitle, UINT *number,\r
-           char fileTitle[MSG_SIZ], char fileName[MSG_SIZ])\r
+              char *nameFilt, char *dlgTitle, UINT *number,\r
+              char fileTitle[MSG_SIZ], char fileName[MSG_SIZ])\r
 {\r
   OPENFILENAME openFileName;\r
   char buf1[MSG_SIZ];\r
@@ -6833,8 +5361,8 @@ OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] dia
   openFileName.nMaxFileTitle     = fileTitle ? MSG_SIZ : 0;\r
   openFileName.lpstrInitialDir   = NULL;\r
   openFileName.lpstrTitle        = dlgTitle;\r
-  openFileName.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY\r
-    | (write[0] != 'r' ? 0 : OFN_FILEMUSTEXIST)\r
+  openFileName.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY \r
+    | (write[0] != 'r' ? 0 : OFN_FILEMUSTEXIST) \r
     | (number ? OFN_ENABLETEMPLATE | OFN_ENABLEHOOK: 0)\r
     | (oldDialog ? 0 : OFN_EXPLORER);\r
   openFileName.nFileOffset       = 0;\r
@@ -6845,13 +5373,13 @@ OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] dia
     (LPOFNHOOKPROC) OldOpenFileHook : (LPOFNHOOKPROC) OpenFileHook;\r
   openFileName.lpTemplateName    = (LPSTR)(oldDialog ? 1536 : DLG_IndexNumber);\r
 \r
-  if (write[0] != 'r' ? GetSaveFileName(&openFileName) :\r
+  if (write[0] != 'r' ? GetSaveFileName(&openFileName) : \r
                         GetOpenFileName(&openFileName)) {\r
     /* open the file */\r
     f = fopen(openFileName.lpstrFile, write);\r
     if (f == NULL) {\r
       MessageBox(hwnd, "File open failed", NULL,\r
-         MB_OK|MB_ICONEXCLAMATION);\r
+                MB_OK|MB_ICONEXCLAMATION);\r
       return NULL;\r
     }\r
   } else {\r
@@ -6867,7 +5395,7 @@ OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] dia
 VOID APIENTRY\r
 MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def)\r
 {\r
-  HMENU hmenuTrackPopup;    /* floating pop-up menu  */\r
+  HMENU hmenuTrackPopup;       /* floating pop-up menu  */\r
 \r
   /*\r
    * Get the first pop-up menu in the menu template. This is the\r
@@ -6885,12 +5413,12 @@ MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def)
 \r
   /* Draw and track the floating pop-up menu. */\r
   TrackPopupMenu(hmenuTrackPopup, TPM_CENTERALIGN | TPM_RIGHTBUTTON,\r
-         pt.x, pt.y, 0, hwnd, NULL);\r
+                pt.x, pt.y, 0, hwnd, NULL);\r
 \r
   /* Destroy the menu.*/\r
   DestroyMenu(hmenu);\r
 }\r
-\r
+   \r
 typedef struct {\r
   HWND hDlg, hText;\r
   int sizeX, sizeY, newSizeX, newSizeY;\r
@@ -6909,7 +5437,7 @@ ResizeEditPlusButtonsCallback(HWND hChild, LPARAM lparam)
   pt.x = rect.left + (cl->newSizeX - cl->sizeX)/2;\r
   pt.y = rect.top + cl->newSizeY - cl->sizeY;\r
   ScreenToClient(cl->hDlg, &pt);\r
-  cl->hdwp = DeferWindowPos(cl->hdwp, hChild, NULL,\r
+  cl->hdwp = DeferWindowPos(cl->hdwp, hChild, NULL, \r
     pt.x, pt.y, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);\r
   return TRUE;\r
 }\r
@@ -6922,10 +5450,10 @@ ResizeEditPlusButtons(HWND hDlg, HWND hText, int sizeX, int sizeY, int newSizeX,
   RECT rectText;\r
   int newTextHeight, newTextWidth;\r
   ResizeEditPlusButtonsClosure cl;\r
-\r
+  \r
   /*if (IsIconic(hDlg)) return;*/\r
   if (newSizeX == sizeX && newSizeY == sizeY) return;\r
-\r
+  \r
   cl.hdwp = BeginDeferWindowPos(8);\r
 \r
   GetWindowRect(hText, &rectText); /* gives screen coords */\r
@@ -6935,7 +5463,7 @@ ResizeEditPlusButtons(HWND hDlg, HWND hText, int sizeX, int sizeY, int newSizeX,
     newSizeY += -newTextHeight;\r
     newTextHeight = 0;\r
   }\r
-  cl.hdwp = DeferWindowPos(cl.hdwp, hText, NULL, 0, 0,\r
+  cl.hdwp = DeferWindowPos(cl.hdwp, hText, NULL, 0, 0, \r
     newTextWidth, newTextHeight, SWP_NOZORDER|SWP_NOMOVE);\r
 \r
   cl.hDlg = hDlg;\r
@@ -6975,9 +5503,9 @@ BOOL CenterWindowEx(HWND hwndChild, HWND hwndParent, int mode)
     /* Calculate new X position, then adjust for screen */\r
     xNew = rParent.left + ((wParent - wChild) /2);\r
     if (xNew < 0) {\r
-    xNew = 0;\r
+       xNew = 0;\r
     } else if ((xNew+wChild) > wScreen) {\r
-    xNew = wScreen - wChild;\r
+       xNew = wScreen - wChild;\r
     }\r
 \r
     /* Calculate new Y position, then adjust for screen */\r
@@ -6989,14 +5517,14 @@ BOOL CenterWindowEx(HWND hwndChild, HWND hwndParent, int mode)
     }\r
 \r
     if (yNew < 0) {\r
-    yNew = 0;\r
+       yNew = 0;\r
     } else if ((yNew+hChild) > hScreen) {\r
-    yNew = hScreen - hChild;\r
+       yNew = hScreen - hChild;\r
     }\r
 \r
     /* Set it, and return */\r
     return SetWindowPos (hwndChild, NULL,\r
-             xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);\r
+                        xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);\r
 }\r
 \r
 /* Center one window over another */\r
@@ -7024,7 +5552,7 @@ InitComboStrings(HANDLE hwndCombo, char **cd)
 void\r
 InitComboStringsFromOption(HANDLE hwndCombo, char *str)\r
 {\r
-  char buf1[ARG_MAX];\r
+  char buf1[MAX_ARG_LEN];\r
   int len;\r
 \r
   if (str[0] == '@') {\r
@@ -7121,13 +5649,13 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     CenterWindow (hDlg, GetDesktopWindow());\r
     /* Initialize the dialog items */\r
     InitEngineBox(hDlg, GetDlgItem(hDlg, OPT_ChessEngineName),\r
-              appData.firstChessProgram, "fd", appData.firstDirectory,\r
-          firstChessProgramNames);\r
+                 appData.firstChessProgram, "fd", appData.firstDirectory,\r
+                 firstChessProgramNames);\r
     InitEngineBox(hDlg, GetDlgItem(hDlg, OPT_SecondChessEngineName),\r
-              appData.secondChessProgram, "sd", appData.secondDirectory,\r
-          secondChessProgramNames);\r
+                 appData.secondChessProgram, "sd", appData.secondDirectory,\r
+                 secondChessProgramNames);\r
     hwndCombo = GetDlgItem(hDlg, OPT_ChessServerName);\r
-    InitComboStringsFromOption(hwndCombo, icsNames);\r
+    InitComboStringsFromOption(hwndCombo, icsNames);    \r
     sprintf(buf, "%s /icsport=%s", appData.icsHost, appData.icsPort);\r
     if (*appData.icsHelper != NULLCHAR) {\r
       char *q = QuoteForFilename(appData.icsHelper);\r
@@ -7159,38 +5687,38 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     case IDOK:\r
       if (IsDlgButtonChecked(hDlg, OPT_ChessEngine)) {\r
         strcpy(buf, "/fcp=");\r
-    GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
+       GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
         p = buf;\r
-    ParseArgs(StringGet, &p);\r
+       ParseArgs(StringGet, &p);\r
         strcpy(buf, "/scp=");\r
-    GetDlgItemText(hDlg, OPT_SecondChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
+       GetDlgItemText(hDlg, OPT_SecondChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
         p = buf;\r
-    ParseArgs(StringGet, &p);\r
-    appData.noChessProgram = FALSE;\r
-    appData.icsActive = FALSE;\r
+       ParseArgs(StringGet, &p);\r
+       appData.noChessProgram = FALSE;\r
+       appData.icsActive = FALSE;\r
       } else if (IsDlgButtonChecked(hDlg, OPT_ChessServer)) {\r
         strcpy(buf, "/ics /icshost=");\r
-    GetDlgItemText(hDlg, OPT_ChessServerName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
+       GetDlgItemText(hDlg, OPT_ChessServerName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
         p = buf;\r
-    ParseArgs(StringGet, &p);\r
-    if (appData.zippyPlay) {\r
-      strcpy(buf, "/fcp=");\r
-      GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
-      p = buf;\r
-      ParseArgs(StringGet, &p);\r
-    }\r
+       ParseArgs(StringGet, &p);\r
+       if (appData.zippyPlay) {\r
+         strcpy(buf, "/fcp=");\r
+         GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
+         p = buf;\r
+         ParseArgs(StringGet, &p);\r
+       }\r
       } else if (IsDlgButtonChecked(hDlg, OPT_View)) {\r
-    appData.noChessProgram = TRUE;\r
-    appData.icsActive = FALSE;\r
+       appData.noChessProgram = TRUE;\r
+       appData.icsActive = FALSE;\r
       } else {\r
-    MessageBox(hDlg, "Choose an option, or cancel to exit",\r
-           "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-    return TRUE;\r
+       MessageBox(hDlg, "Choose an option, or cancel to exit",\r
+                  "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+       return TRUE;\r
       }\r
       if (IsDlgButtonChecked(hDlg, OPT_AnyAdditional)) {\r
-    GetDlgItemText(hDlg, OPT_AdditionalOptions, buf, sizeof(buf));\r
-    p = buf;\r
-    ParseArgs(StringGet, &p);\r
+       GetDlgItemText(hDlg, OPT_AdditionalOptions, buf, sizeof(buf));\r
+       p = buf;\r
+       ParseArgs(StringGet, &p);\r
       }\r
       EndDialog(hDlg, TRUE);\r
       return TRUE;\r
@@ -7201,9 +5729,9 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 \r
     case IDM_HELPCONTENTS:\r
       if (!WinHelp (hDlg, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS")) {\r
-    MessageBox (GetFocus(),\r
-            "Unable to activate help",\r
-            szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
+       MessageBox (GetFocus(),\r
+                   "Unable to activate help",\r
+                   szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
       }\r
       break;\r
 \r
@@ -7236,7 +5764,7 @@ About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 \r
   case WM_COMMAND: /* message: received a command */\r
     if (LOWORD(wParam) == IDOK /* "OK" box selected? */\r
-    || LOWORD(wParam) == IDCANCEL) { /* System menu close command? */\r
+       || LOWORD(wParam) == IDCANCEL) { /* System menu close command? */\r
       EndDialog(hDlg, TRUE); /* Exit the dialog */\r
       return (TRUE);\r
     }\r
@@ -7277,8 +5805,8 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       SetFocus(GetDlgItem(hDlg, IDOK));\r
     }\r
     SendMessage(GetDlgItem(hDlg, OPT_CommentText),\r
-        WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf,\r
-        MAKELPARAM(FALSE, 0));\r
+               WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf,\r
+               MAKELPARAM(FALSE, 0));\r
     /* Size and position the dialog */\r
     if (!commentDialog) {\r
       commentDialog = hDlg;\r
@@ -7286,27 +5814,27 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       GetClientRect(hDlg, &rect);\r
       sizeX = rect.right;\r
       sizeY = rect.bottom;\r
-      if (commentX != CW_USEDEFAULT && commentY != CW_USEDEFAULT &&\r
-      commentW != CW_USEDEFAULT && commentH != CW_USEDEFAULT) {\r
-    WINDOWPLACEMENT wp;\r
-    EnsureOnScreen(&commentX, &commentY, 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 = commentX;\r
-    wp.rcNormalPosition.right = commentX + commentW;\r
-    wp.rcNormalPosition.top = commentY;\r
-    wp.rcNormalPosition.bottom = commentY + commentH;\r
-    SetWindowPlacement(hDlg, &wp);\r
-\r
-    GetClientRect(hDlg, &rect);\r
-    newSizeX = rect.right;\r
-    newSizeY = rect.bottom;\r
+      if (wpComment.x != CW_USEDEFAULT && wpComment.y != CW_USEDEFAULT &&\r
+         wpComment.width != CW_USEDEFAULT && wpComment.height != CW_USEDEFAULT) {\r
+       WINDOWPLACEMENT wp;\r
+       EnsureOnScreen(&wpComment.x, &wpComment.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 = wpComment.x;\r
+       wp.rcNormalPosition.right = wpComment.x + wpComment.width;\r
+       wp.rcNormalPosition.top = wpComment.y;\r
+       wp.rcNormalPosition.bottom = wpComment.y + wpComment.height;\r
+       SetWindowPlacement(hDlg, &wp);\r
+\r
+       GetClientRect(hDlg, &rect);\r
+       newSizeX = rect.right;\r
+       newSizeY = rect.bottom;\r
         ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY,\r
-                  newSizeX, newSizeY);\r
-    sizeX = newSizeX;\r
-    sizeY = newSizeY;\r
+                             newSizeX, newSizeY);\r
+       sizeX = newSizeX;\r
+       sizeY = newSizeY;\r
       }\r
     }\r
     return FALSE;\r
@@ -7315,22 +5843,22 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     switch (LOWORD(wParam)) {\r
     case IDOK:\r
       if (editComment) {\r
-    char *p, *q;\r
-    /* Read changed options from the dialog box */\r
-    hwndText = GetDlgItem(hDlg, OPT_CommentText);\r
-    len = GetWindowTextLength(hwndText);\r
-    str = (char *) malloc(len + 1);\r
-    GetWindowText(hwndText, str, len + 1);\r
-    p = q = str;\r
-    while (*q) {\r
-      if (*q == '\r')\r
-        q++;\r
-      else\r
-        *p++ = *q++;\r
-    }\r
-    *p = NULLCHAR;\r
-    ReplaceComment(commentIndex, str);\r
-    free(str);\r
+       char *p, *q;\r
+       /* Read changed options from the dialog box */\r
+       hwndText = GetDlgItem(hDlg, OPT_CommentText);\r
+       len = GetWindowTextLength(hwndText);\r
+       str = (char *) malloc(len + 1);\r
+       GetWindowText(hwndText, str, len + 1);\r
+       p = q = str;\r
+       while (*q) {\r
+         if (*q == '\r')\r
+           q++;\r
+         else\r
+           *p++ = *q++;\r
+       }\r
+       *p = NULLCHAR;\r
+       ReplaceComment(commentIndex, str);\r
+       free(str);\r
       }\r
       CommentPopDown();\r
       return TRUE;\r
@@ -7396,21 +5924,21 @@ EitherCommentPopUp(int index, char *title, char *str, BOOLEAN edit)
 \r
   if (commentDialog) {\r
     SendMessage(commentDialog, WM_INITDIALOG, 0, 0);\r
-    if (!commentDialogUp) ShowWindow(commentDialog, SW_SHOW);\r
+    if (!commentUp) ShowWindow(commentDialog, SW_SHOW);\r
   } else {\r
     lpProc = MakeProcInstance((FARPROC)CommentDialog, hInst);\r
     CreateDialog(hInst, MAKEINTRESOURCE(DLG_EditComment),\r
-         hwndMain, (DLGPROC)lpProc);\r
+                hwndMain, (DLGPROC)lpProc);\r
     FreeProcInstance(lpProc);\r
   }\r
-  commentDialogUp = TRUE;\r
+  commentUp = TRUE;\r
 }\r
 \r
 \r
 /*---------------------------------------------------------------------------*\\r
  *\r
  * Type-in move dialog functions\r
- *\r
+ * \r
 \*---------------------------------------------------------------------------*/\r
 \r
 LRESULT CALLBACK\r
@@ -7438,40 +5966,35 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     case IDOK:\r
       GetDlgItemText(hDlg, OPT_Move, move, sizeof(move));\r
       { int n; Board board;\r
-    // [HGM] FENedit\r
-    if(gameMode == EditPosition && ParseFEN(board, &n, move) ) {\r
-        EditPositionPasteFEN(move);\r
-        EndDialog(hDlg, TRUE);\r
-        return TRUE;\r
-    }\r
-    // [HGM] movenum: allow move number to be typed in any mode\r
-    if(sscanf(move, "%d", &n) == 1 && n != 0 ) {\r
-      currentMove = 2*n-1;\r
-      if(currentMove > forwardMostMove)  currentMove = forwardMostMove;\r
-      if(currentMove < backwardMostMove) currentMove = backwardMostMove;\r
-      EndDialog(hDlg, TRUE);\r
-      DrawPosition(TRUE, boards[currentMove]);\r
-      if(currentMove > backwardMostMove) DisplayMove(currentMove - 1);\r
-      else DisplayMessage("", "");\r
-      return TRUE;\r
-    }\r
+       // [HGM] FENedit\r
+       if(gameMode == EditPosition && ParseFEN(board, &n, move) ) {\r
+               EditPositionPasteFEN(move);\r
+               EndDialog(hDlg, TRUE);\r
+               return TRUE;\r
+       }\r
+       // [HGM] movenum: allow move number to be typed in any mode\r
+       if(sscanf(move, "%d", &n) == 1 && n != 0 ) {\r
+         ToNrEvent(2*n-1);\r
+         EndDialog(hDlg, TRUE);\r
+         return TRUE;\r
+       }\r
       }\r
-      if (gameMode != EditGame && currentMove != forwardMostMove &&\r
-    gameMode != Training) {\r
-    DisplayMoveError("Displayed move is not current");\r
+      if (gameMode != EditGame && currentMove != forwardMostMove && \r
+       gameMode != Training) {\r
+       DisplayMoveError("Displayed move is not current");\r
       } else {\r
-//  GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); // moved upstream\r
-    int ok = ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove,\r
-      &moveType, &fromX, &fromY, &toX, &toY, &promoChar);\r
-    if(!ok && move[0] >= 'a') { move[0] += 'A' - 'a'; ok = 2; } // [HGM] try also capitalized\r
-    if (ok==1 || ok && ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove,\r
-      &moveType, &fromX, &fromY, &toX, &toY, &promoChar)) {\r
-      if (gameMode != Training)\r
-          forwardMostMove = currentMove;\r
-      UserMoveEvent(fromX, fromY, toX, toY, promoChar);\r
-    } else {\r
-      DisplayMoveError("Could not parse move");\r
-    }\r
+//     GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); // moved upstream\r
+       int ok = ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, \r
+         &moveType, &fromX, &fromY, &toX, &toY, &promoChar);\r
+       if(!ok && move[0] >= 'a') { move[0] += 'A' - 'a'; ok = 2; } // [HGM] try also capitalized\r
+       if (ok==1 || ok && ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, \r
+         &moveType, &fromX, &fromY, &toX, &toY, &promoChar)) {\r
+         if (gameMode != Training)\r
+             forwardMostMove = currentMove;\r
+         UserMoveEvent(fromX, fromY, toX, toY, promoChar);     \r
+       } else {\r
+         DisplayMoveError("Could not parse move");\r
+       }\r
       }\r
       EndDialog(hDlg, TRUE);\r
       return TRUE;\r
@@ -7490,19 +6013,19 @@ VOID
 PopUpMoveDialog(char firstchar)\r
 {\r
     FARPROC lpProc;\r
-\r
-    if ((gameMode == BeginningOfGame && !appData.icsActive) ||\r
+    \r
+    if ((gameMode == BeginningOfGame && !appData.icsActive) || \r
         gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack ||\r
-    gameMode == AnalyzeMode || gameMode == EditGame ||\r
-    gameMode == EditPosition || gameMode == IcsExamining ||\r
-    gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack ||\r
-    isdigit(firstchar) && // [HGM] movenum: allow typing in of move nr in 'passive' modes\r
-        ( gameMode == AnalyzeFile || gameMode == PlayFromGameFile ||\r
-          gameMode == IcsObserving || gameMode == TwoMachinesPlay    ) ||\r
-    gameMode == Training) {\r
+       gameMode == AnalyzeMode || gameMode == EditGame || \r
+       gameMode == EditPosition || gameMode == IcsExamining ||\r
+       gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack ||\r
+       isdigit(firstchar) && // [HGM] movenum: allow typing in of move nr in 'passive' modes\r
+               ( gameMode == AnalyzeFile || gameMode == PlayFromGameFile ||\r
+                 gameMode == IcsObserving || gameMode == TwoMachinesPlay    ) ||\r
+       gameMode == Training) {\r
       lpProc = MakeProcInstance((FARPROC)TypeInMoveDialog, hInst);\r
       DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_TypeInMove),\r
-    hwndMain, (DLGPROC)lpProc, (LPARAM)firstchar);\r
+       hwndMain, (DLGPROC)lpProc, (LPARAM)firstchar);\r
       FreeProcInstance(lpProc);\r
     }\r
 }\r
@@ -7510,7 +6033,7 @@ PopUpMoveDialog(char firstchar)
 /*---------------------------------------------------------------------------*\\r
  *\r
  * Type-in name dialog functions\r
- *\r
+ * \r
 \*---------------------------------------------------------------------------*/\r
 \r
 LRESULT CALLBACK\r
@@ -7554,22 +6077,22 @@ VOID
 PopUpNameDialog(char firstchar)\r
 {\r
     FARPROC lpProc;\r
-\r
+    \r
       lpProc = MakeProcInstance((FARPROC)TypeInNameDialog, hInst);\r
       DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_TypeInName),\r
-    hwndMain, (DLGPROC)lpProc, (LPARAM)firstchar);\r
+       hwndMain, (DLGPROC)lpProc, (LPARAM)firstchar);\r
       FreeProcInstance(lpProc);\r
 }\r
 \r
 /*---------------------------------------------------------------------------*\\r
  *\r
  *  Error dialogs\r
- *\r
+ * \r
 \*---------------------------------------------------------------------------*/\r
 \r
 /* Nonmodal error box */\r
 LRESULT CALLBACK ErrorDialog(HWND hDlg, UINT message,\r
-                 WPARAM wParam, LPARAM lParam);\r
+                            WPARAM wParam, LPARAM lParam);\r
 \r
 VOID\r
 ErrorPopUp(char *title, char *content)\r
@@ -7583,11 +6106,11 @@ ErrorPopUp(char *title, char *content)
   while (*p) {\r
     if (*p == '\n') {\r
       if (modal) {\r
-    *q++ = ' ';\r
-    p++;\r
+       *q++ = ' ';\r
+       p++;\r
       } else {\r
-    *q++ = '\r';\r
-    *q++ = *p++;\r
+       *q++ = '\r';\r
+       *q++ = *p++;\r
       }\r
     } else {\r
       *q++ = *p++;\r
@@ -7596,13 +6119,13 @@ ErrorPopUp(char *title, char *content)
   *q = NULLCHAR;\r
   strncpy(errorTitle, title, sizeof(errorTitle));\r
   errorTitle[sizeof(errorTitle) - 1] = '\0';\r
-\r
+  \r
   if (modal) {\r
     MessageBox(NULL, errorMessage, errorTitle, MB_OK|MB_ICONEXCLAMATION);\r
   } else {\r
     lpProc = MakeProcInstance((FARPROC)ErrorDialog, hInst);\r
     CreateDialog(hInst, MAKEINTRESOURCE(DLG_Error),\r
-         hwndMain, (DLGPROC)lpProc);\r
+                hwndMain, (DLGPROC)lpProc);\r
     FreeProcInstance(lpProc);\r
   }\r
 }\r
@@ -7614,6 +6137,7 @@ ErrorPopDown()
   if (errorDialog == NULL) return;\r
   DestroyWindow(errorDialog);\r
   errorDialog = NULL;\r
+  if(errorExitStatus) ExitEvent(errorExitStatus);\r
 }\r
 \r
 LRESULT CALLBACK\r
@@ -7628,11 +6152,11 @@ ErrorDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 \r
     /*\r
     SetWindowPos(hDlg, NULL, rChild.left,\r
-      rChild.top + boardRect.top - (rChild.bottom - rChild.top),\r
+      rChild.top + boardRect.top - (rChild.bottom - rChild.top), \r
       0, 0, SWP_NOZORDER|SWP_NOSIZE);\r
     */\r
 \r
-    /*\r
+    /* \r
         [AS] It seems that the above code wants to move the dialog up in the "caption\r
         area" of the main window, but it uses the dialog height as an hard-coded constant,\r
         and it doesn't work when you resize the dialog.\r
@@ -7676,10 +6200,10 @@ GothicDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
   case WM_INITDIALOG:\r
     GetWindowRect(hDlg, &rChild);\r
 \r
-    SetWindowPos(hDlg, NULL, boardX, boardY-height, winWidth, height,\r
+    SetWindowPos(hDlg, NULL, wpMain.x, wpMain.y-height, wpMain.width, height,\r
                                                              SWP_NOZORDER);\r
 \r
-    /*\r
+    /* \r
         [AS] It seems that the above code wants to move the dialog up in the "caption\r
         area" of the main window, but it uses the dialog height as an hard-coded constant,\r
         and it doesn't work when you resize the dialog.\r
@@ -7724,7 +6248,7 @@ GothicPopUp(char *title, VariantClass variant)
     title = lastTitle;\r
     lpProc = MakeProcInstance((FARPROC)GothicDialog, hInst);\r
     CreateDialog(hInst, MAKEINTRESOURCE(DLG_Error),\r
-         hwndMain, (DLGPROC)lpProc);\r
+                hwndMain, (DLGPROC)lpProc);\r
     FreeProcInstance(lpProc);\r
   }\r
 }\r
@@ -7776,76 +6300,7 @@ NextInHistory()
 {\r
   if (histP == histIn) return NULL;\r
   histP = (histP + 1) % HISTORY_SIZE;\r
-  return history[histP];\r
-}\r
-\r
-typedef struct {\r
-  char *item;\r
-  char *command;\r
-  BOOLEAN getname;\r
-  BOOLEAN immediate;\r
-} IcsTextMenuEntry;\r
-#define ICS_TEXT_MENU_SIZE (IDM_CommandXLast - IDM_CommandX + 1)\r
-IcsTextMenuEntry icsTextMenuEntry[ICS_TEXT_MENU_SIZE];\r
-\r
-void\r
-ParseIcsTextMenu(char *icsTextMenuString)\r
-{\r
-//  int flags = 0;\r
-  IcsTextMenuEntry *e = icsTextMenuEntry;\r
-  char *p = icsTextMenuString;\r
-  while (e->item != NULL && e < icsTextMenuEntry + ICS_TEXT_MENU_SIZE) {\r
-    free(e->item);\r
-    e->item = NULL;\r
-    if (e->command != NULL) {\r
-      free(e->command);\r
-      e->command = NULL;\r
-    }\r
-    e++;\r
-  }\r
-  e = icsTextMenuEntry;\r
-  while (*p && e < icsTextMenuEntry + ICS_TEXT_MENU_SIZE) {\r
-    if (*p == ';' || *p == '\n') {\r
-      e->item = strdup("-");\r
-      e->command = NULL;\r
-      p++;\r
-    } else if (*p == '-') {\r
-      e->item = strdup("-");\r
-      e->command = NULL;\r
-      p++;\r
-      if (*p) p++;\r
-    } else {\r
-      char *q, *r, *s, *t;\r
-      char c;\r
-      q = strchr(p, ',');\r
-      if (q == NULL) break;\r
-      *q = NULLCHAR;\r
-      r = strchr(q + 1, ',');\r
-      if (r == NULL) break;\r
-      *r = NULLCHAR;\r
-      s = strchr(r + 1, ',');\r
-      if (s == NULL) break;\r
-      *s = NULLCHAR;\r
-      c = ';';\r
-      t = strchr(s + 1, c);\r
-      if (t == NULL) {\r
-    c = '\n';\r
-    t = strchr(s + 1, c);\r
-      }\r
-      if (t != NULL) *t = NULLCHAR;\r
-      e->item = strdup(p);\r
-      e->command = strdup(q + 1);\r
-      e->getname = *(r + 1) != '0';\r
-      e->immediate = *(s + 1) != '0';\r
-      *q = ',';\r
-      *r = ',';\r
-      *s = ',';\r
-      if (t == NULL) break;\r
-      *t = c;\r
-      p = t + 1;\r
-    }\r
-    e++;\r
-  }\r
+  return history[histP];   \r
 }\r
 \r
 HMENU\r
@@ -7858,17 +6313,18 @@ LoadIcsTextMenu(IcsTextMenuEntry *e)
   while (e->item) {\r
     if (strcmp(e->item, "-") == 0) {\r
       AppendMenu(h, MF_SEPARATOR, 0, 0);\r
-    } else {\r
+    } else { // [HGM] re-written a bit to use only one AppendMenu call for both cases (| or no |)\r
+      int flags = MF_STRING, j = 0;\r
       if (e->item[0] == '|') {\r
-    AppendMenu(h, MF_STRING|MF_MENUBARBREAK,\r
-           IDM_CommandX + i, &e->item[1]);\r
-      } else {\r
-    AppendMenu(h, MF_STRING, IDM_CommandX + i, e->item);\r
+       flags |= MF_MENUBARBREAK;\r
+        j++;\r
       }\r
+      if(!strcmp(e->command, "none")) flags |= MF_GRAYED; // [HGM] chatclick: provide inactive dummy\r
+      AppendMenu(h, flags, IDM_CommandX + i, e->item + j);\r
     }\r
     e++;\r
     i++;\r
-  }\r
+  } \r
   return hmenu;\r
 }\r
 \r
@@ -7892,7 +6348,7 @@ CommandX(HWND hwnd, char *command, BOOLEAN getname, BOOLEAN immediate)
       SetFocus(hInput);\r
     }\r
     return;\r
-  }\r
+  }    \r
   SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
   if (sel.cpMin == sel.cpMax) {\r
     /* Expand to surrounding word */\r
@@ -7933,6 +6389,7 @@ CommandX(HWND hwnd, char *command, BOOLEAN getname, BOOLEAN immediate)
     SetWindowText(hInput, buf);\r
     SendMessage(hInput, WM_CHAR, '\r', 0);\r
   } else {\r
+    if(!strcmp(command, "chat")) { ChatPopUp(name); return; }\r
     sprintf(buf, "%s %s ", command, name); /* trailing space */\r
     SetWindowText(hInput, buf);\r
     sel.cpMin = 999999;\r
@@ -7942,7 +6399,7 @@ CommandX(HWND hwnd, char *command, BOOLEAN getname, BOOLEAN immediate)
   }\r
 }\r
 \r
-LRESULT CALLBACK\r
+LRESULT CALLBACK \r
 ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
   HWND hInput;\r
@@ -7967,16 +6424,16 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    if(wParam != '\022') {\r
     if (wParam == '\t') {\r
       if (GetKeyState(VK_SHIFT) < 0) {\r
-    /* shifted */\r
-    if (IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE);\r
-    if (buttonDesc[0].hwnd) {\r
-      SetFocus(buttonDesc[0].hwnd);\r
-    } else {\r
-      SetFocus(hwndMain);\r
-    }\r
+       /* shifted */\r
+       if (IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE);\r
+       if (buttonDesc[0].hwnd) {\r
+         SetFocus(buttonDesc[0].hwnd);\r
+       } else {\r
+         SetFocus(hwndMain);\r
+       }\r
       } else {\r
-    /* unshifted */\r
-    SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleInput));\r
+       /* unshifted */\r
+       SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleInput));\r
       }\r
     } else {\r
       hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
@@ -7985,11 +6442,20 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     }\r
     return 0;\r
    } // [HGM] navigate: for Ctrl+R, flow into nex case (moved up here) to summon up menu\r
-  case WM_RBUTTONUP:\r
-    if (GetKeyState(VK_SHIFT) & ~1) {\r
-      SendDlgItemMessage(hwndConsole, OPT_ConsoleText,\r
-        WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
-    } else {\r
+  case WM_RBUTTONDOWN:\r
+    if (!(GetKeyState(VK_SHIFT) & ~1)) {\r
+      /* Move selection here if it was empty */\r
+      POINT pt;\r
+      pt.x = LOWORD(lParam);\r
+      pt.y = HIWORD(lParam);\r
+      SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
+      if (sel.cpMin == sel.cpMax) {\r
+        sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/\r
+       sel.cpMax = sel.cpMin;\r
+       SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
+      }\r
+      SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE);\r
+{ // [HGM] chatclick: code moved here from WM_RBUTTONUP case, to have menu appear on down-click\r
       POINT pt;\r
       HMENU hmenu = LoadIcsTextMenu(icsTextMenuEntry);\r
       SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
@@ -8000,9 +6466,17 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       if (!IsClipboardFormatAvailable(CF_TEXT)) {\r
         EnableMenuItem(hmenu, IDM_Paste, MF_BYCOMMAND|MF_GRAYED);\r
       }\r
-      pt.x = LOWORD(lParam);\r
-      pt.y = HIWORD(lParam);\r
+      pt.x = LOWORD(lParam)-30; // [HGM] chatclick: make menu pop up with pointer above upper-right item\r
+      pt.y = HIWORD(lParam)-10; //       make it appear as if mouse moved there, so it will be selected on up-click\r
+      PostMessage(hwnd, WM_MOUSEMOVE, wParam, lParam+5);\r
       MenuPopup(hwnd, pt, hmenu, -1);\r
+}\r
+    }\r
+    return 0;\r
+  case WM_RBUTTONUP:\r
+    if (GetKeyState(VK_SHIFT) & ~1) {\r
+      SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
+        WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
     }\r
     return 0;\r
   case WM_PASTE:\r
@@ -8011,32 +6485,17 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     return SendMessage(hInput, message, wParam, lParam);\r
   case WM_MBUTTONDOWN:\r
     return SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
-  case WM_RBUTTONDOWN:\r
-    if (!(GetKeyState(VK_SHIFT) & ~1)) {\r
-      /* Move selection here if it was empty */\r
-      POINT pt;\r
-      pt.x = LOWORD(lParam);\r
-      pt.y = HIWORD(lParam);\r
-      SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
-      if (sel.cpMin == sel.cpMax) {\r
-        sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/\r
-    sel.cpMax = sel.cpMin;\r
-    SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
-      }\r
-      SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE);\r
-    }\r
-    return 0;\r
   case WM_COMMAND:\r
     switch (LOWORD(wParam)) {\r
     case IDM_QuickPaste:\r
       {\r
         SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
-    if (sel.cpMin == sel.cpMax) {\r
-      MessageBeep(MB_ICONEXCLAMATION);\r
+       if (sel.cpMin == sel.cpMax) {\r
+         MessageBeep(MB_ICONEXCLAMATION);\r
           return 0;\r
-    }\r
-    SendMessage(hwnd, WM_COPY, 0, 0);\r
-    hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
+       }\r
+       SendMessage(hwnd, WM_COPY, 0, 0);\r
+       hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
         SendMessage(hInput, WM_PASTE, 0, 0);\r
         SetFocus(hInput);\r
         return 0;\r
@@ -8052,14 +6511,14 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       return 0;\r
     default:\r
       {\r
-    int i = LOWORD(wParam) - IDM_CommandX;\r
-    if (i >= 0 && i < ICS_TEXT_MENU_SIZE &&\r
-        icsTextMenuEntry[i].command != NULL) {\r
-      CommandX(hwnd, icsTextMenuEntry[i].command,\r
-           icsTextMenuEntry[i].getname,\r
-           icsTextMenuEntry[i].immediate);\r
-      return 0;\r
-    }\r
+       int i = LOWORD(wParam) - IDM_CommandX;\r
+       if (i >= 0 && i < ICS_TEXT_MENU_SIZE &&\r
+           icsTextMenuEntry[i].command != NULL) {\r
+         CommandX(hwnd, icsTextMenuEntry[i].command,\r
+                  icsTextMenuEntry[i].getname,\r
+                  icsTextMenuEntry[i].immediate);\r
+         return 0;\r
+       }\r
       }\r
       break;\r
     }\r
@@ -8099,15 +6558,15 @@ ConsoleInputSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     }\r
     switch (wParam) {\r
     case '\r':   /* Enter key */\r
-      is->count = GetWindowText(hwnd, is->buf, INPUT_SOURCE_BUF_SIZE-1);\r
+      is->count = GetWindowText(hwnd, is->buf, INPUT_SOURCE_BUF_SIZE-1);     \r
       if (consoleEcho) SaveInHistory(is->buf);\r
       is->buf[is->count++] = '\n';\r
       is->buf[is->count] = NULLCHAR;\r
       SendMessage(hwndMain, WM_USER_Input, 0, (LPARAM) is);\r
       if (consoleEcho) {\r
-    ConsoleOutput(is->buf, is->count, TRUE);\r
+       ConsoleOutput(is->buf, is->count, TRUE);\r
       } else if (appData.localLineEditing) {\r
-    ConsoleOutput("\n", 1, TRUE);\r
+       ConsoleOutput("\n", 1, TRUE);\r
       }\r
       /* fall thru */\r
     case '\033': /* Escape key */\r
@@ -8117,23 +6576,23 @@ ConsoleInputSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       if (consoleEcho) {\r
         cf.crTextColor = textAttribs[ColorNormal].color;\r
       } else {\r
-    cf.crTextColor = COLOR_ECHOOFF;\r
+       cf.crTextColor = COLOR_ECHOOFF;\r
       }\r
       cf.dwEffects = textAttribs[ColorNormal].effects;\r
       SendMessage(hwnd, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
       return 0;\r
     case '\t':   /* Tab key */\r
       if (GetKeyState(VK_SHIFT) < 0) {\r
-    /* shifted */\r
-    SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleText));\r
+       /* shifted */\r
+       SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleText));\r
       } else {\r
-    /* unshifted */\r
-    if (IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE);\r
-    if (buttonDesc[0].hwnd) {\r
-      SetFocus(buttonDesc[0].hwnd);\r
-    } else {\r
-      SetFocus(hwndMain);\r
-    }\r
+       /* unshifted */\r
+       if (IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE);\r
+       if (buttonDesc[0].hwnd) {\r
+         SetFocus(buttonDesc[0].hwnd);\r
+       } else {\r
+         SetFocus(hwndMain);\r
+       }\r
       }\r
       return 0;\r
     case '\023': /* Ctrl+S */\r
@@ -8153,20 +6612,20 @@ ConsoleInputSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       GetWindowText(hwnd, buf, MSG_SIZ);\r
       p = PrevInHistory(buf);\r
       if (p != NULL) {\r
-    SetWindowText(hwnd, p);\r
-    sel.cpMin = 999999;\r
-    sel.cpMax = 999999;\r
-    SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
+       SetWindowText(hwnd, p);\r
+       sel.cpMin = 999999;\r
+       sel.cpMax = 999999;\r
+       SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
         return 0;\r
       }\r
       break;\r
     case VK_DOWN:\r
       p = NextInHistory();\r
       if (p != NULL) {\r
-    SetWindowText(hwnd, p);\r
-    sel.cpMin = 999999;\r
-    sel.cpMax = 999999;\r
-    SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
+       SetWindowText(hwnd, p);\r
+       sel.cpMin = 999999;\r
+       sel.cpMax = 999999;\r
+       SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
         return 0;\r
       }\r
       break;\r
@@ -8181,12 +6640,12 @@ ConsoleInputSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     }\r
     break;\r
   case WM_MBUTTONDOWN:\r
-    SendDlgItemMessage(hwndConsole, OPT_ConsoleText,\r
+    SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
       WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
     break;\r
   case WM_RBUTTONUP:\r
     if (GetKeyState(VK_SHIFT) & ~1) {\r
-      SendDlgItemMessage(hwndConsole, OPT_ConsoleText,\r
+      SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
         WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
     } else {\r
       POINT pt;\r
@@ -8206,7 +6665,7 @@ ConsoleInputSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     }\r
     return 0;\r
   case WM_COMMAND:\r
-    switch (LOWORD(wParam)) {\r
+    switch (LOWORD(wParam)) { \r
     case IDM_Undo:\r
       SendMessage(hwnd, EM_UNDO, 0, 0);\r
       return 0;\r
@@ -8237,12 +6696,15 @@ LRESULT CALLBACK
 ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
   static SnapData sd;\r
-  static HWND hText, hInput /*, hFocus*/;\r
-//  InputSource *is = consoleInputSource;\r
+  HWND hText, hInput;\r
   RECT rect;\r
   static int sizeX, sizeY;\r
   int newSizeX, newSizeY;\r
   MINMAXINFO *mmi;\r
+  WORD wMask;\r
+\r
+  hText = GetDlgItem(hDlg, OPT_ConsoleText);\r
+  hInput = GetDlgItem(hDlg, OPT_ConsoleInput);\r
 \r
   switch (message) {\r
   case WM_NOTIFY:\r
@@ -8251,21 +6713,18 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       ENLINK *pLink = (ENLINK*)lParam;\r
       if (pLink->msg == WM_LBUTTONUP)\r
       {\r
-          TEXTRANGE tr;\r
-\r
-          tr.chrg = pLink->chrg;\r
-          tr.lpstrText = malloc(1+tr.chrg.cpMax-tr.chrg.cpMin);\r
-          hText = GetDlgItem(hDlg, OPT_ConsoleText);\r
-          SendMessage(hText, EM_GETTEXTRANGE, 0, (LPARAM)&tr);\r
-          ShellExecute(NULL, "open", tr.lpstrText, NULL, NULL, SW_SHOW);\r
-          free(tr.lpstrText);\r
+        TEXTRANGE tr;\r
+\r
+        tr.chrg = pLink->chrg;\r
+        tr.lpstrText = malloc(1+tr.chrg.cpMax-tr.chrg.cpMin);\r
+        SendMessage(hText, EM_GETTEXTRANGE, 0, (LPARAM)&tr);\r
+        ShellExecute(NULL, "open", tr.lpstrText, NULL, NULL, SW_SHOW);\r
+        free(tr.lpstrText);\r
       }\r
     }\r
     break;\r
   case WM_INITDIALOG: /* message: initialize dialog box */\r
     hwndConsole = hDlg;\r
-    hText = GetDlgItem(hDlg, OPT_ConsoleText);\r
-    hInput = GetDlgItem(hDlg, OPT_ConsoleInput);\r
     SetFocus(hInput);\r
     consoleTextWindowProc = (WNDPROC)\r
       SetWindowLong(hText, GWL_WNDPROC, (LONG) ConsoleTextSubclass);\r
@@ -8280,7 +6739,7 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     sizeX = rect.right;\r
     sizeY = rect.bottom;\r
     if (wpConsole.x != CW_USEDEFAULT && wpConsole.y != CW_USEDEFAULT &&\r
-    wpConsole.width != CW_USEDEFAULT && wpConsole.height != CW_USEDEFAULT) {\r
+       wpConsole.width != CW_USEDEFAULT && wpConsole.height != CW_USEDEFAULT) {\r
       WINDOWPLACEMENT wp;\r
       EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0);\r
       wp.length = sizeof(WINDOWPLACEMENT);\r
@@ -8293,14 +6752,14 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height;\r
       SetWindowPlacement(hDlg, &wp);\r
     }\r
-#if 1\r
+\r
    // [HGM] Chessknight's change 2004-07-13\r
    else { /* Determine Defaults */\r
        WINDOWPLACEMENT wp;\r
-       wpConsole.x = winWidth + 1;\r
-       wpConsole.y = boardY;\r
-       wpConsole.width = screenWidth -  winWidth;\r
-       wpConsole.height = winHeight;\r
+       wpConsole.x = wpMain.width + 1;\r
+       wpConsole.y = wpMain.y;\r
+       wpConsole.width = screenWidth -  wpMain.width;\r
+       wpConsole.height = wpMain.height;\r
        EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0);\r
        wp.length = sizeof(WINDOWPLACEMENT);\r
        wp.flags = 0;\r
@@ -8312,7 +6771,13 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
        wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height;\r
        SetWindowPlacement(hDlg, &wp);\r
     }\r
-#endif\r
+\r
+   // Allow hText to highlight URLs and send notifications on them\r
+   wMask = (WORD) SendMessage(hText, EM_GETEVENTMASK, 0, 0L);\r
+   SendMessage(hText, EM_SETEVENTMASK, 0, wMask | ENM_LINK);\r
+   SendMessage(hText, EM_AUTOURLDETECT, TRUE, 0L);\r
+   SetWindowLong(hText, GWL_USERDATA, 79); // initialize the text window's width\r
+\r
     return FALSE;\r
 \r
   case WM_SETFOCUS:\r
@@ -8336,19 +6801,19 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       newTextWidth = rectText.right - rectText.left + newSizeX - sizeX;\r
       newTextHeight = rectText.bottom - rectText.top + newSizeY - sizeY;\r
       if (newTextHeight < 0) {\r
-    newSizeY += -newTextHeight;\r
+       newSizeY += -newTextHeight;\r
         newTextHeight = 0;\r
       }\r
       SetWindowPos(hText, NULL, 0, 0,\r
-    newTextWidth, newTextHeight, SWP_NOZORDER|SWP_NOMOVE);\r
+       newTextWidth, newTextHeight, SWP_NOZORDER|SWP_NOMOVE);\r
       GetWindowRect(hInput, &rectInput); /* gives screen coords */\r
       pt.x = rectInput.left;\r
       pt.y = rectInput.top + newSizeY - sizeY;\r
       ScreenToClient(hDlg, &pt);\r
-      SetWindowPos(hInput, NULL,\r
-    pt.x, pt.y, /* needs client coords */\r
-    rectInput.right - rectInput.left + newSizeX - sizeX,\r
-    rectInput.bottom - rectInput.top, SWP_NOZORDER);\r
+      SetWindowPos(hInput, NULL, \r
+       pt.x, pt.y, /* needs client coords */   \r
+       rectInput.right - rectInput.left + newSizeX - sizeX,\r
+       rectInput.bottom - rectInput.top, SWP_NOZORDER);\r
     }\r
     sizeX = newSizeX;\r
     sizeY = newSizeY;\r
@@ -8372,6 +6837,7 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     return OnMoving( &sd, hDlg, wParam, lParam );\r
 \r
   case WM_EXITSIZEMOVE:\r
+       UpdateICSWidth(hText);\r
     return OnExitSizeMove( &sd, hDlg, wParam, lParam );\r
   }\r
 \r
@@ -8382,17 +6848,10 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 VOID\r
 ConsoleCreate()\r
 {\r
-  HWND hCons, hText;\r
-  WORD wMask;\r
+  HWND hCons;\r
   if (hwndConsole) return;\r
   hCons = CreateDialog(hInst, szConsoleName, 0, NULL);\r
   SendMessage(hCons, WM_INITDIALOG, 0, 0);\r
-\r
-  // make the text item in the console do URL links\r
-  hText = GetDlgItem(hCons, OPT_ConsoleText);\r
-  wMask = SendMessage(hText, EM_GETEVENTMASK, 0, 0L);\r
-  SendMessage(hText, EM_SETEVENTMASK, 0, wMask | ENM_LINK);\r
-  SendMessage(hText, EM_AUTOURLDETECT, TRUE, 0L);\r
 }\r
 \r
 \r
@@ -8419,10 +6878,10 @@ ConsoleOutput(char* data, int length, int forceVisible)
   while (length--) {\r
     if (*p == '\n') {\r
       if (*++p) {\r
-    *q++ = '\r';\r
-    *q++ = '\n';\r
+       *q++ = '\r';\r
+       *q++ = '\n';\r
       } else {\r
-    delayLF = 1;\r
+       delayLF = 1;\r
       }\r
     } else if (*p == '\007') {\r
        MyPlaySound(&sounds[(int)SoundBell]);\r
@@ -8550,8 +7009,8 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight,
   JAWS_SILENCE\r
 \r
   ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN,\r
-         rect->top, ETO_CLIPPED|ETO_OPAQUE,\r
-         rect, str, strlen(str), NULL);\r
+            rect->top, ETO_CLIPPED|ETO_OPAQUE,\r
+            rect, str, strlen(str), NULL);\r
   if(logoHeight > 0 && appData.clockMode) {\r
       RECT r;\r
       sprintf(buf, "%s %s", buf+7, flagFell);\r
@@ -8560,8 +7019,8 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight,
       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.top, ETO_CLIPPED|ETO_OPAQUE,\r
+                &r, str, strlen(str), NULL);\r
   }\r
   (void) SetTextColor(hdc, oldFg);\r
   (void) SetBkColor(hdc, oldBg);\r
@@ -8571,7 +7030,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight,
 \r
 int\r
 DoReadFile(HANDLE hFile, char *buf, int count, DWORD *outCount,\r
-       OVERLAPPED *ovl)\r
+          OVERLAPPED *ovl)\r
 {\r
   int ok, err;\r
 \r
@@ -8594,9 +7053,9 @@ DoReadFile(HANDLE hFile, char *buf, int count, DWORD *outCount,
     if (err == ERROR_IO_PENDING) {\r
       ok = GetOverlappedResult(hFile, ovl, outCount, TRUE);\r
       if (ok)\r
-    err = NO_ERROR;\r
+       err = NO_ERROR;\r
       else\r
-    err = GetLastError();\r
+       err = GetLastError();\r
     }\r
   }\r
   return err;\r
@@ -8604,7 +7063,7 @@ DoReadFile(HANDLE hFile, char *buf, int count, DWORD *outCount,
 \r
 int\r
 DoWriteFile(HANDLE hFile, char *buf, int count, DWORD *outCount,\r
-        OVERLAPPED *ovl)\r
+           OVERLAPPED *ovl)\r
 {\r
   int ok, err;\r
 \r
@@ -8618,9 +7077,9 @@ DoWriteFile(HANDLE hFile, char *buf, int count, DWORD *outCount,
     if (err == ERROR_IO_PENDING) {\r
       ok = GetOverlappedResult(hFile, ovl, outCount, TRUE);\r
       if (ok)\r
-    err = NO_ERROR;\r
+       err = NO_ERROR;\r
       else\r
-    err = GetLastError();\r
+       err = GetLastError();\r
     }\r
   }\r
   return err;\r
@@ -8632,7 +7091,7 @@ void CheckForInputBufferFull( InputSource * is )
     if( is->lineByLine && (is->next - is->buf) >= INPUT_SOURCE_BUF_SIZE ) {\r
         /* Look for end of line */\r
         char * p = is->buf;\r
-\r
+        \r
         while( p < is->next && *p != '\n' ) {\r
             p++;\r
         }\r
@@ -8660,18 +7119,18 @@ InputThread(LPVOID arg)
   ovl.Internal = ovl.InternalHigh = ovl.Offset = ovl.OffsetHigh = 0;\r
   while (is->hThread != NULL) {\r
     is->error = DoReadFile(is->hFile, is->next,\r
-               INPUT_SOURCE_BUF_SIZE - (is->next - is->buf),\r
-               &is->count, &ovl);\r
+                          INPUT_SOURCE_BUF_SIZE - (is->next - is->buf),\r
+                          &is->count, &ovl);\r
     if (is->error == NO_ERROR) {\r
       is->next += is->count;\r
     } else {\r
       if (is->error == ERROR_BROKEN_PIPE) {\r
-    /* Correct for MS brain damage.  EOF reading a pipe is not an error. */\r
-    is->count = 0;\r
+       /* Correct for MS brain damage.  EOF reading a pipe is not an error. */\r
+       is->count = 0;\r
       } else {\r
-    is->count = (DWORD) -1;\r
+       is->count = (DWORD) -1;\r
         /* [AS] The (is->count <= 0) check below is not useful for unsigned values! */\r
-        break;\r
+        break; \r
       }\r
     }\r
 \r
@@ -8707,37 +7166,37 @@ NonOvlInputThread(LPVOID arg)
   is = (InputSource *) arg;\r
   while (is->hThread != NULL) {\r
     is->error = ReadFile(is->hFile, is->next,\r
-             INPUT_SOURCE_BUF_SIZE - (is->next - is->buf),\r
-             &is->count, NULL) ? NO_ERROR : GetLastError();\r
+                        INPUT_SOURCE_BUF_SIZE - (is->next - is->buf),\r
+                        &is->count, NULL) ? NO_ERROR : GetLastError();\r
     if (is->error == NO_ERROR) {\r
       /* Change CRLF to LF */\r
       if (is->next > is->buf) {\r
-    p = is->next - 1;\r
-    i = is->count + 1;\r
+       p = is->next - 1;\r
+       i = is->count + 1;\r
       } else {\r
-    p = is->next;\r
-    i = is->count;\r
+       p = is->next;\r
+       i = is->count;\r
       }\r
       q = p;\r
       prev = NULLCHAR;\r
       while (i > 0) {\r
-    if (prev == '\r' && *p == '\n') {\r
-      *(q-1) = '\n';\r
-      is->count--;\r
-    } else {\r
-      *q++ = *p;\r
-    }\r
-    prev = *p++;\r
-    i--;\r
+       if (prev == '\r' && *p == '\n') {\r
+         *(q-1) = '\n';\r
+         is->count--;\r
+       } else { \r
+         *q++ = *p;\r
+       }\r
+       prev = *p++;\r
+       i--;\r
       }\r
       *q = NULLCHAR;\r
       is->next = q;\r
     } else {\r
       if (is->error == ERROR_BROKEN_PIPE) {\r
-    /* Correct for MS brain damage.  EOF reading a pipe is not an error. */\r
-    is->count = 0;\r
+       /* Correct for MS brain damage.  EOF reading a pipe is not an error. */\r
+       is->count = 0; \r
       } else {\r
-    is->count = (DWORD) -1;\r
+       is->count = (DWORD) -1;\r
       }\r
     }\r
 \r
@@ -8768,8 +7227,8 @@ SocketInputThread(LPVOID arg)
       is->error = NO_ERROR;\r
       is->next += is->count;\r
       if (is->count == 0 && is->second == is) {\r
-    /* End of file on stderr; quit with no message */\r
-    break;\r
+       /* End of file on stderr; quit with no message */\r
+       break;\r
       }\r
     }\r
     SendMessage(hwndMain, WM_USER_Input, 0, (LPARAM) is);\r
@@ -8793,11 +7252,11 @@ InputEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     char *q = p;\r
     while (q < is->next) {\r
       if (*q++ == '\n') {\r
-    (is->func)(is, is->closure, p, q - p, NO_ERROR);\r
-    p = q;\r
+       (is->func)(is, is->closure, p, q - p, NO_ERROR);\r
+       p = q;\r
       }\r
     }\r
-\r
+    \r
     /* Move any partial line to the start of the buffer */\r
     q = is->buf;\r
     while (p < is->next) {\r
@@ -8807,8 +7266,8 @@ InputEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 \r
     if (is->error != NO_ERROR || is->count == 0) {\r
       /* Notify backend of the error.  Note: If there was a partial\r
-     line at the end, it is not flushed through. */\r
-      (is->func)(is, is->closure, is->buf, is->count, is->error);\r
+        line at the end, it is not flushed through. */\r
+      (is->func)(is, is->closure, is->buf, is->count, is->error);   \r
     }\r
   } else {\r
     /* Feed in the whole chunk of input at once */\r
@@ -8829,6 +7288,13 @@ typedef struct {
 } Enables;\r
 \r
 VOID\r
+GreyRevert(Boolean grey)\r
+{ // [HGM] vari: for retracting variations in local mode\r
+  HMENU hmenu = GetMenu(hwndMain);\r
+  EnableMenuItem(hmenu, IDM_Revert, MF_BYCOMMAND|(grey ? MF_GRAYED : MF_ENABLED));\r
+}\r
+\r
+VOID\r
 SetMenuEnables(HMENU hmenu, Enables *enab)\r
 {\r
   while (enab->item > 0) {\r
@@ -8848,6 +7314,7 @@ Enables gnuEnables[] = {
   { IDM_StopExamining, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_StopObserving, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_Revert, MF_BYCOMMAND|MF_GRAYED },\r
+  { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED },\r
   { -1, -1 }\r
 };\r
 \r
@@ -8857,6 +7324,7 @@ Enables icsEnables[] = {
   { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED },\r
+  { IDM_MachineBoth, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_AnalysisMode, MF_BYCOMMAND|MF_ENABLED },\r
   { IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_TimeControl, MF_BYCOMMAND|MF_GRAYED },\r
@@ -8864,6 +7332,8 @@ Enables icsEnables[] = {
   { IDM_Hint, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_Book, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_IcsOptions, MF_BYCOMMAND|MF_ENABLED },\r
+  { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED },\r
+  { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED },\r
   { -1, -1 }\r
 };\r
 \r
@@ -8872,6 +7342,7 @@ Enables zippyEnables[] = {
   { IDM_MoveNow, MF_BYCOMMAND|MF_ENABLED },\r
   { IDM_Hint, MF_BYCOMMAND|MF_ENABLED },\r
   { IDM_Book, MF_BYCOMMAND|MF_ENABLED },\r
+  { IDM_Engine1Options, MF_BYCOMMAND|MF_ENABLED },\r
   { -1, -1 }\r
 };\r
 #endif\r
@@ -8892,6 +7363,10 @@ Enables ncpEnables[] = {
   { IDM_TimeControl, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_Hint, MF_BYCOMMAND|MF_GRAYED },\r
   { IDM_Book, MF_BYCOMMAND|MF_GRAYED },\r
+  { IDM_MachineBoth, MF_BYCOMMAND|MF_GRAYED },\r
+  { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED },\r
+  { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED },\r
+  { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED },\r
   { -1, -1 }\r
 };\r
 \r
@@ -8973,7 +7448,7 @@ Enables userThinkingEnables[] = {
  *\r
  *  Front-end interface functions exported by XBoard.\r
  *  Functions appear in same order as prototypes in frontend.h.\r
- *\r
+ * \r
 \*---------------------------------------------------------------------------*/\r
 VOID\r
 ModeHighlight()\r
@@ -8985,7 +7460,7 @@ ModeHighlight()
   if (pausing != prevPausing) {\r
     prevPausing = pausing;\r
     (void) CheckMenuItem(GetMenu(hwndMain), IDM_Pause,\r
-             MF_BYCOMMAND|(pausing ? MF_CHECKED : MF_UNCHECKED));\r
+                        MF_BYCOMMAND|(pausing ? MF_CHECKED : MF_UNCHECKED));\r
     if (hwndPause) SetWindowText(hwndPause, pausing ? "C" : "P");\r
   }\r
 \r
@@ -9038,17 +7513,17 @@ ModeHighlight()
   }\r
   if (prevChecked != 0)\r
     (void) CheckMenuItem(GetMenu(hwndMain),\r
-             prevChecked, MF_BYCOMMAND|MF_UNCHECKED);\r
+                        prevChecked, MF_BYCOMMAND|MF_UNCHECKED);\r
   if (nowChecked != 0)\r
     (void) CheckMenuItem(GetMenu(hwndMain),\r
-             nowChecked, MF_BYCOMMAND|MF_CHECKED);\r
+                        nowChecked, MF_BYCOMMAND|MF_CHECKED);\r
 \r
   if (nowChecked == IDM_LoadGame || nowChecked == IDM_Training) {\r
-    (void) EnableMenuItem(GetMenu(hwndMain), IDM_Training,\r
-              MF_BYCOMMAND|MF_ENABLED);\r
+    (void) EnableMenuItem(GetMenu(hwndMain), IDM_Training, \r
+                         MF_BYCOMMAND|MF_ENABLED);\r
   } else {\r
-    (void) EnableMenuItem(GetMenu(hwndMain),\r
-              IDM_Training, MF_BYCOMMAND|MF_GRAYED);\r
+    (void) EnableMenuItem(GetMenu(hwndMain), \r
+                         IDM_Training, MF_BYCOMMAND|MF_GRAYED);\r
   }\r
 \r
   prevChecked = nowChecked;\r
@@ -9104,7 +7579,7 @@ SetCmailMode()
   SetMenuEnables(GetMenu(hwndMain), cmailEnables);\r
 }\r
 \r
-VOID\r
+VOID \r
 SetTrainingModeOn()\r
 {\r
   int i;\r
@@ -9160,7 +7635,7 @@ DisplayTitle(char *str)
   } else if (appData.icsActive) {\r
     if (appData.icsCommPort[0] != NULLCHAR)\r
       host = "ICS";\r
-    else\r
+    else \r
       host = appData.icsHost;\r
     sprintf(title, "%s: %s", szTitle, host);\r
   } else if (appData.noChessProgram) {\r
@@ -9209,7 +7684,7 @@ DisplayMessage(char *str1, char *str2)
   hdc = GetDC(hwndMain);\r
   oldFont = SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf);\r
   ExtTextOut(hdc, messageRect.left, messageRect.top, ETO_CLIPPED|ETO_OPAQUE,\r
-         &messageRect, messageText, strlen(messageText), NULL);\r
+            &messageRect, messageText, strlen(messageText), NULL);\r
   (void) SelectObject(hdc, oldFont);\r
   (void) ReleaseDC(hwndMain, hdc);\r
 }\r
@@ -9224,21 +7699,21 @@ DisplayError(char *str, int error)
     strcpy(buf, str);\r
   } else {\r
     len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,\r
-            NULL, error, LANG_NEUTRAL,\r
-            (LPSTR) buf2, MSG_SIZ, NULL);\r
+                       NULL, error, LANG_NEUTRAL,\r
+                       (LPSTR) buf2, MSG_SIZ, NULL);\r
     if (len > 0) {\r
       sprintf(buf, "%s:\n%s", str, buf2);\r
     } else {\r
       ErrorMap *em = errmap;\r
       while (em->err != 0 && em->err != error) em++;\r
       if (em->err != 0) {\r
-    sprintf(buf, "%s:\n%s", str, em->msg);\r
+       sprintf(buf, "%s:\n%s", str, em->msg);\r
       } else {\r
-    sprintf(buf, "%s:\nError code %d", str, error);\r
+       sprintf(buf, "%s:\nError code %d", str, error);\r
       }\r
     }\r
   }\r
-\r
+  \r
   ErrorPopUp("Error", buf);\r
 }\r
 \r
@@ -9266,17 +7741,17 @@ DisplayFatalError(char *str, int error, int exitStatus)
 \r
   if (error != 0) {\r
     len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,\r
-            NULL, error, LANG_NEUTRAL,\r
-            (LPSTR) buf2, MSG_SIZ, NULL);\r
+                       NULL, error, LANG_NEUTRAL,\r
+                       (LPSTR) buf2, MSG_SIZ, NULL);\r
     if (len > 0) {\r
       sprintf(buf, "%s:\n%s", str, buf2);\r
     } else {\r
       ErrorMap *em = errmap;\r
       while (em->err != 0 && em->err != error) em++;\r
       if (em->err != 0) {\r
-    sprintf(buf, "%s:\n%s", str, em->msg);\r
+       sprintf(buf, "%s:\n%s", str, em->msg);\r
       } else {\r
-    sprintf(buf, "%s:\nError code %d", str, error);\r
+       sprintf(buf, "%s:\nError code %d", str, error);\r
       }\r
     }\r
     str = buf;\r
@@ -9286,7 +7761,7 @@ DisplayFatalError(char *str, int error, int exitStatus)
   }\r
   if (appData.popupExitMessage) {\r
     (void) MessageBox(hwndMain, str, label, MB_OK|\r
-              (exitStatus ? MB_ICONSTOP : MB_ICONINFORMATION));\r
+                     (exitStatus ? MB_ICONSTOP : MB_ICONINFORMATION));\r
   }\r
   ExitEvent(exitStatus);\r
 }\r
@@ -9355,7 +7830,7 @@ AskQuestion(char* title, char *question, char *replyPrefix, ProcRef pr)
 {\r
     QuestionParams qp;\r
     FARPROC lpProc;\r
-\r
+    \r
     qp.title = title;\r
     qp.question = question;\r
     qp.replyPrefix = replyPrefix;\r
@@ -9392,10 +7867,10 @@ LRESULT CALLBACK NewGameFRC_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM
         case IDOK:\r
             *lpIndexFRC = GetDlgItemInt(hDlg, IDC_NFG_Edit, &index_is_ok, TRUE );\r
             EndDialog( hDlg, 0 );\r
-        shuffleOpenings = TRUE; /* [HGM] shuffle: switch shuffling on for as long as we stay in current variant */\r
+           shuffleOpenings = TRUE; /* [HGM] shuffle: switch shuffling on for as long as we stay in current variant */\r
             return TRUE;\r
         case IDCANCEL:\r
-            EndDialog( hDlg, 1 );\r
+            EndDialog( hDlg, 1 );   \r
             return TRUE;\r
         case IDC_NFG_Edit:\r
             if( HIWORD(wParam) == EN_CHANGE ) {\r
@@ -9431,104 +7906,42 @@ int NewGameFRC()
     return result;\r
 }\r
 \r
-/* [AS] Game list options */\r
-typedef struct {\r
-    char id;\r
-    char * name;\r
-} GLT_Item;\r
-\r
-static GLT_Item GLT_ItemInfo[] = {\r
-    { GLT_EVENT,      "Event" },\r
-    { GLT_SITE,       "Site" },\r
-    { GLT_DATE,       "Date" },\r
-    { GLT_ROUND,      "Round" },\r
-    { GLT_PLAYERS,    "Players" },\r
-    { GLT_RESULT,     "Result" },\r
-    { GLT_WHITE_ELO,  "White Rating" },\r
-    { GLT_BLACK_ELO,  "Black Rating" },\r
-    { GLT_TIME_CONTROL,"Time Control" },\r
-    { GLT_VARIANT,    "Variant" },\r
-    { GLT_OUT_OF_BOOK,PGN_OUT_OF_BOOK },\r
-    { GLT_RESULT_COMMENT, "Result Comment" }, // [HGM] rescom\r
-    { 0, 0 }\r
-};\r
-\r
-const char * GLT_FindItem( char id )\r
-{\r
-    const char * result = 0;\r
+/* [AS] Game list options. Refactored by HGM */\r
 \r
-    GLT_Item * list = GLT_ItemInfo;\r
+HWND gameListOptionsDialog;\r
 \r
-    while( list->id != 0 ) {\r
-        if( list->id == id ) {\r
-            result = list->name;\r
-            break;\r
-        }\r
-\r
-        list++;\r
-    }\r
-\r
-    return result;\r
+// low-level front-end: clear text edit / list widget\r
+void\r
+GLT_ClearList()\r
+{\r
+    SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_RESETCONTENT, 0, 0 );\r
 }\r
 \r
-void GLT_AddToList( HWND hDlg, int iDlgItem, char id, int index )\r
+// low-level front-end: clear text edit / list widget\r
+void\r
+GLT_DeSelectList()\r
 {\r
-    const char * name = GLT_FindItem( id );\r
-\r
-    if( name != 0 ) {\r
-        if( index >= 0 ) {\r
-            SendDlgItemMessage( hDlg, iDlgItem, LB_INSERTSTRING, index, (LPARAM) name );\r
-        }\r
-        else {\r
-            SendDlgItemMessage( hDlg, iDlgItem, LB_ADDSTRING, 0, (LPARAM) name );\r
-        }\r
-    }\r
+    SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_SETCURSEL, 0, 0 );\r
 }\r
 \r
-void GLT_TagsToList( HWND hDlg, char * tags )\r
+// low-level front-end: append line to text edit / list widget\r
+void\r
+GLT_AddToList( char *name )\r
 {\r
-    char * pc = tags;\r
-\r
-    SendDlgItemMessage( hDlg, IDC_GameListTags, LB_RESETCONTENT, 0, 0 );\r
-\r
-    while( *pc ) {\r
-        GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );\r
-        pc++;\r
-    }\r
-\r
-    SendDlgItemMessage( hDlg, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) "\t --- Hidden tags ---" );\r
-\r
-    pc = GLT_ALL_TAGS;\r
-\r
-    while( *pc ) {\r
-        if( strchr( tags, *pc ) == 0 ) {\r
-            GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );\r
-        }\r
-        pc++;\r
+    if( name != 0 ) {\r
+            SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) name );\r
     }\r
-\r
-    SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, 0, 0 );\r
 }\r
 \r
-char GLT_ListItemToTag( HWND hDlg, int index )\r
+// low-level front-end: get line from text edit / list widget\r
+Boolean\r
+GLT_GetFromList( int index, char *name )\r
 {\r
-    char result = '\0';\r
-    char name[128];\r
-\r
-    GLT_Item * list = GLT_ItemInfo;\r
-\r
-    if( SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR ) {\r
-        while( list->id != 0 ) {\r
-            if( strcmp( list->name, name ) == 0 ) {\r
-                result = list->id;\r
-                break;\r
-            }\r
-\r
-            list++;\r
-        }\r
+    if( name != 0 ) {\r
+           if( SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR )\r
+               return TRUE;\r
     }\r
-\r
-    return result;\r
+    return FALSE;\r
 }\r
 \r
 void GLT_MoveSelection( HWND hDlg, int delta )\r
@@ -9549,20 +7962,15 @@ void GLT_MoveSelection( HWND hDlg, int delta )
 \r
 LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
 {\r
-    static char glt[64];\r
-    static char * lpUserGLT;\r
-\r
     switch( message )\r
     {\r
     case WM_INITDIALOG:\r
-        lpUserGLT = (char *) lParam;\r
-\r
-        strcpy( glt, lpUserGLT );\r
-\r
+       gameListOptionsDialog = hDlg; // [HGM] pass through global to keep out off back-end\r
+        \r
         CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
 \r
         /* Initialize list */\r
-        GLT_TagsToList( hDlg, glt );\r
+        GLT_TagsToList( lpUserGLT );\r
 \r
         SetFocus( GetDlgItem(hDlg, IDC_GameListTags) );\r
 \r
@@ -9571,19 +7979,7 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP
     case WM_COMMAND:\r
         switch( LOWORD(wParam) ) {\r
         case IDOK:\r
-            {\r
-                char * pc = lpUserGLT;\r
-                int idx = 0;\r
-//                int cnt = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 );\r
-                char id;\r
-\r
-                do {\r
-                    id = GLT_ListItemToTag( hDlg, idx );\r
-\r
-                    *pc++ = id;\r
-                    idx++;\r
-                } while( id != '\0' );\r
-            }\r
+           GLT_ParseList();\r
             EndDialog( hDlg, 0 );\r
             return TRUE;\r
         case IDCANCEL:\r
@@ -9591,13 +7987,11 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP
             return TRUE;\r
 \r
         case IDC_GLT_Default:\r
-            strcpy( glt, GLT_DEFAULT_TAGS );\r
-            GLT_TagsToList( hDlg, glt );\r
+            GLT_TagsToList( GLT_DEFAULT_TAGS );\r
             return TRUE;\r
 \r
         case IDC_GLT_Restore:\r
-            strcpy( glt, lpUserGLT );\r
-            GLT_TagsToList( hDlg, glt );\r
+            GLT_TagsToList( appData.gameListTags );\r
             return TRUE;\r
 \r
         case IDC_GLT_Up:\r
@@ -9617,23 +8011,21 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP
 \r
 int GameListOptions()\r
 {\r
-    char glt[64];\r
     int result;\r
     FARPROC lpProc = MakeProcInstance( (FARPROC) GameListOptions_Proc, hInst );\r
 \r
-    strcpy( glt, appData.gameListTags );\r
+    strcpy( lpUserGLT, appData.gameListTags );\r
 \r
-    result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)glt );\r
+    result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)lpUserGLT );\r
 \r
     if( result == 0 ) {\r
         /* [AS] Memory leak here! */\r
-        appData.gameListTags = strdup( glt );\r
+        appData.gameListTags = strdup( lpUserGLT ); \r
     }\r
 \r
     return result;\r
 }\r
 \r
-\r
 VOID\r
 DisplayIcsInteractionTitle(char *str)\r
 {\r
@@ -9646,9 +8038,14 @@ DisplayIcsInteractionTitle(char *str)
 void\r
 DrawPosition(int fullRedraw, Board board)\r
 {\r
-  HDCDrawPosition(NULL, (BOOLEAN) fullRedraw, board);\r
+  HDCDrawPosition(NULL, (BOOLEAN) fullRedraw, board); \r
 }\r
 \r
+void NotifyFrontendLogin()\r
+{\r
+       if (hwndConsole)\r
+               UpdateICSWidth(GetDlgItem(hwndConsole, OPT_ConsoleText));\r
+}\r
 \r
 VOID\r
 ResetFrontEnd()\r
@@ -9682,7 +8079,7 @@ CommentPopDown(void)
   if (commentDialog) {\r
     ShowWindow(commentDialog, SW_HIDE);\r
   }\r
-  commentDialogUp = FALSE;\r
+  commentUp = FALSE;\r
 }\r
 \r
 VOID\r
@@ -9767,8 +8164,8 @@ UserName()
   static char buf[MSG_SIZ];\r
   DWORD bufsiz = MSG_SIZ;\r
 \r
-  if(appData.userName != NULL && appData.userName[0] != 0) {\r
-    return appData.userName; /* [HGM] username: prefer name selected by user over his system login */\r
+  if(appData.userName != NULL && appData.userName[0] != 0) { \r
+       return appData.userName; /* [HGM] username: prefer name selected by user over his system login */\r
   }\r
   if (!GetUserName(buf, &bufsiz)) {\r
     /*DisplayError("Error getting user name", GetLastError());*/\r
@@ -9810,7 +8207,7 @@ void
 StartClockTimer(long millisec)\r
 {\r
   clockTimerEvent = SetTimer(hwndMain, (UINT) CLOCK_TIMER_ID,\r
-                 (UINT) millisec, NULL);\r
+                            (UINT) millisec, NULL);\r
 }\r
 \r
 void\r
@@ -9822,8 +8219,8 @@ DisplayWhiteClock(long timeRemaining, int highlight)
   if(appData.noGUI) return;\r
   hdc = GetDC(hwndMain);\r
   if (!IsIconic(hwndMain)) {\r
-    DisplayAClock(hdc, timeRemaining, highlight,\r
-            flipClock ? &blackRect : &whiteRect, "White", flag);\r
+    DisplayAClock(hdc, timeRemaining, highlight, \r
+                       flipClock ? &blackRect : &whiteRect, "White", flag);\r
   }\r
   if (highlight && iconCurrent == iconBlack) {\r
     iconCurrent = iconWhite;\r
@@ -9846,8 +8243,8 @@ DisplayBlackClock(long timeRemaining, int highlight)
   if(appData.noGUI) return;\r
   hdc = GetDC(hwndMain);\r
   if (!IsIconic(hwndMain)) {\r
-    DisplayAClock(hdc, timeRemaining, highlight,\r
-            flipClock ? &whiteRect : &blackRect, "Black", flag);\r
+    DisplayAClock(hdc, timeRemaining, highlight, \r
+                       flipClock ? &whiteRect : &blackRect, "Black", flag);\r
   }\r
   if (highlight && iconCurrent == iconWhite) {\r
     iconCurrent = iconBlack;\r
@@ -9881,7 +8278,7 @@ void
 StartLoadGameTimer(long millisec)\r
 {\r
   loadGameTimerEvent = SetTimer(hwndMain, (UINT) LOAD_GAME_TIMER_ID,\r
-                (UINT) millisec, NULL);\r
+                               (UINT) millisec, NULL);\r
 }\r
 \r
 void\r
@@ -9893,9 +8290,9 @@ AutoSaveGame()
 \r
   defName = DefaultFileName(appData.oldSaveStyle ? "gam" : "pgn");\r
   f = OpenFileDialog(hwndMain, "a", defName,\r
-             appData.oldSaveStyle ? "gam" : "pgn",\r
-             GAME_FILT,\r
-             "Save Game to File", NULL, fileTitle, NULL);\r
+                    appData.oldSaveStyle ? "gam" : "pgn",\r
+                    GAME_FILT, \r
+                    "Save Game to File", NULL, fileTitle, NULL);\r
   if (f != NULL) {\r
     SaveGame(f, 0, "");\r
     fclose(f);\r
@@ -9917,7 +8314,7 @@ ScheduleDelayedEvent(DelayedEventCallback cb, long millisec)
   }\r
   delayedTimerCallback = cb;\r
   delayedTimerEvent = SetTimer(hwndMain, (UINT) DELAYED_TIMER_ID,\r
-                (UINT) millisec, NULL);\r
+                               (UINT) millisec, NULL);\r
 }\r
 \r
 DelayedEventCallback\r
@@ -10004,9 +8401,9 @@ StartChildProcess(char *cmdLine, char *dir, ProcRef *pr)
 \r
   /* Duplicate the read handle to the pipe, so it is not inherited. */\r
   fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,\r
-                 GetCurrentProcess(), &hChildStdoutRdDup, 0,\r
-                 FALSE, /* not inherited */\r
-                 DUPLICATE_SAME_ACCESS);\r
+                            GetCurrentProcess(), &hChildStdoutRdDup, 0,\r
+                            FALSE,     /* not inherited */\r
+                            DUPLICATE_SAME_ACCESS);\r
   if (! fSuccess) {\r
     return GetLastError();\r
   }\r
@@ -10026,9 +8423,9 @@ StartChildProcess(char *cmdLine, char *dir, ProcRef *pr)
 \r
   /* Duplicate the write handle to the pipe, so it is not inherited. */\r
   fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,\r
-                 GetCurrentProcess(), &hChildStdinWrDup, 0,\r
-                 FALSE, /* not inherited */\r
-                 DUPLICATE_SAME_ACCESS);\r
+                            GetCurrentProcess(), &hChildStdinWrDup, 0,\r
+                            FALSE,     /* not inherited */\r
+                            DUPLICATE_SAME_ACCESS);\r
   if (! fSuccess) {\r
     return GetLastError();\r
   }\r
@@ -10055,15 +8452,15 @@ StartChildProcess(char *cmdLine, char *dir, ProcRef *pr)
   siStartInfo.hStdError = hChildStdoutWr;\r
 \r
   fSuccess = CreateProcess(NULL,\r
-               cmdLine,    /* command line */\r
-               NULL,       /* process security attributes */\r
-               NULL,       /* primary thread security attrs */\r
-               TRUE,       /* handles are inherited */\r
-               DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP,\r
-               NULL,       /* use parent's environment */\r
-               NULL,\r
-               &siStartInfo, /* STARTUPINFO pointer */\r
-               &piProcInfo); /* receives PROCESS_INFORMATION */\r
+                          cmdLine,        /* command line */\r
+                          NULL,           /* process security attributes */\r
+                          NULL,           /* primary thread security attrs */\r
+                          TRUE,           /* handles are inherited */\r
+                          DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP,\r
+                          NULL,           /* use parent's environment */\r
+                          NULL,\r
+                          &siStartInfo, /* STARTUPINFO pointer */\r
+                          &piProcInfo); /* receives PROCESS_INFORMATION */\r
 \r
   err = GetLastError();\r
   SetCurrentDirectory(buf); /* return to prev directory */\r
@@ -10123,7 +8520,7 @@ DestroyChildProcess(ProcRef pr, int/*boolean*/ signal)
     /*!!if (signal) GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, cp->pid);*/\r
 \r
     /* [AS] Special termination modes for misbehaving programs... */\r
-    if( signal == 9 ) {\r
+    if( signal == 9 ) { \r
         result = TerminateProcess( cp->hProcess, 0 );\r
 \r
         if ( appData.debugMode) {\r
@@ -10276,7 +8673,7 @@ OpenTCP(char *host, char *port, ProcRef *pr)
 \r
   /* Make connection */\r
   if (connect(s, (struct sockaddr *) &sa,\r
-          sizeof(struct sockaddr_in)) == SOCKET_ERROR) {\r
+             sizeof(struct sockaddr_in)) == SOCKET_ERROR) {\r
     err = WSAGetLastError();\r
     WSACleanup();\r
     return err;\r
@@ -10305,7 +8702,7 @@ OpenCommPort(char *name, ProcRef *pr)
     strcpy(fullname, name);\r
 \r
   h = CreateFile(name, GENERIC_READ | GENERIC_WRITE,\r
-         0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);\r
+                0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);\r
   if (h == (HANDLE) -1) {\r
     return GetLastError();\r
   }\r
@@ -10398,15 +8795,15 @@ OpenRcmd(char* host, char* user, char* cmd, ProcRef* pr)
     }\r
     if (s == INVALID_SOCKET) {\r
       if ((s = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {\r
-    err = WSAGetLastError();\r
-    WSACleanup();\r
-    return err;\r
+       err = WSAGetLastError();\r
+       WSACleanup();\r
+       return err;\r
       }\r
     }\r
     uport = (unsigned short) fromPort;\r
     mysa.sin_port = htons(uport);\r
     if (bind(s, (struct sockaddr *) &mysa, sizeof(struct sockaddr_in))\r
-    == SOCKET_ERROR) {\r
+       == SOCKET_ERROR) {\r
       err = WSAGetLastError();\r
       if (err == WSAEADDRINUSE) continue;\r
       WSACleanup();\r
@@ -10416,9 +8813,9 @@ OpenRcmd(char* host, char* user, char* cmd, ProcRef* pr)
       sizeof(struct sockaddr_in)) == SOCKET_ERROR) {\r
       err = WSAGetLastError();\r
       if (err == WSAEADDRINUSE) {\r
-    closesocket(s);\r
+       closesocket(s);\r
         s = -1;\r
-    continue;\r
+       continue;\r
       }\r
       WSACleanup();\r
       return err;\r
@@ -10441,16 +8838,16 @@ OpenRcmd(char* host, char* user, char* cmd, ProcRef* pr)
     }\r
     if (s2 == INVALID_SOCKET) {\r
       if ((s2 = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {\r
-    err = WSAGetLastError();\r
-    closesocket(s);\r
-    WSACleanup();\r
-    return err;\r
+       err = WSAGetLastError();\r
+       closesocket(s);\r
+       WSACleanup();\r
+       return err;\r
       }\r
     }\r
     uport = (unsigned short) fromPort;\r
     mysa.sin_port = htons(uport);\r
     if (bind(s2, (struct sockaddr *) &mysa, sizeof(struct sockaddr_in))\r
-    == SOCKET_ERROR) {\r
+       == SOCKET_ERROR) {\r
       err = WSAGetLastError();\r
       if (err == WSAEADDRINUSE) continue;\r
       (void) closesocket(s);\r
@@ -10460,9 +8857,9 @@ OpenRcmd(char* host, char* user, char* cmd, ProcRef* pr)
     if (listen(s2, 1) == SOCKET_ERROR) {\r
       err = WSAGetLastError();\r
       if (err == WSAEADDRINUSE) {\r
-    closesocket(s2);\r
-    s2 = INVALID_SOCKET;\r
-    continue;\r
+       closesocket(s2);\r
+       s2 = INVALID_SOCKET;\r
+       continue;\r
       }\r
       (void) closesocket(s);\r
       (void) closesocket(s2);\r
@@ -10527,7 +8924,7 @@ OpenRcmd(char* host, char* user, char* cmd, ProcRef* pr)
 \r
 InputSourceRef\r
 AddInputSource(ProcRef pr, int lineByLine,\r
-           InputCallback func, VOIDSTAR closure)\r
+              InputCallback func, VOIDSTAR closure)\r
 {\r
   InputSource *is, *is2 = NULL;\r
   ChildProc *cp = (ChildProc *) pr;\r
@@ -10543,7 +8940,7 @@ AddInputSource(ProcRef pr, int lineByLine,
     consoleInputSource = is;\r
   } else {\r
     is->kind = cp->kind;\r
-    /*\r
+    /* \r
         [AS] Try to avoid a race condition if the thread is given control too early:\r
         we create all threads suspended so that the is->hThread variable can be\r
         safely assigned, then let the threads start with ResumeThread.\r
@@ -10553,23 +8950,23 @@ AddInputSource(ProcRef pr, int lineByLine,
       is->hFile = cp->hFrom;\r
       cp->hFrom = NULL; /* now owned by InputThread */\r
       is->hThread =\r
-    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) NonOvlInputThread,\r
-             (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
+       CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) NonOvlInputThread,\r
+                    (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
       break;\r
 \r
     case CPComm:\r
       is->hFile = cp->hFrom;\r
       cp->hFrom = NULL; /* now owned by InputThread */\r
       is->hThread =\r
-    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) InputThread,\r
-             (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
+       CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) InputThread,\r
+                    (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
       break;\r
 \r
     case CPSock:\r
       is->sock = cp->sock;\r
       is->hThread =\r
-    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
-             (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
+       CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
+                    (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
       break;\r
 \r
     case CPRcmd:\r
@@ -10580,11 +8977,11 @@ AddInputSource(ProcRef pr, int lineByLine,
       is2->sock = cp->sock2;\r
       is2->second = is2;\r
       is->hThread =\r
-    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
-             (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
+       CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
+                    (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
       is2->hThread =\r
-    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
-             (LPVOID) is2, CREATE_SUSPENDED, &is2->id);\r
+       CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
+                    (LPVOID) is2, CREATE_SUSPENDED, &is2->id);\r
       break;\r
     }\r
 \r
@@ -10614,6 +9011,11 @@ RemoveInputSource(InputSourceRef isr)
   }\r
 }\r
 \r
+int no_wrap(char *message, int count)\r
+{\r
+    ConsoleOutput(message, count, FALSE);\r
+    return count;\r
+}\r
 \r
 int\r
 OutputToProcess(ProcRef pr, char *message, int count, int *outError)\r
@@ -10622,10 +9024,31 @@ OutputToProcess(ProcRef pr, char *message, int count, int *outError)
   int outCount = SOCKET_ERROR;\r
   ChildProc *cp = (ChildProc *) pr;\r
   static OVERLAPPED ovl;\r
+  static int line = 0;\r
 \r
-  if (pr == NoProc) {\r
-    ConsoleOutput(message, count, FALSE);\r
-    return count;\r
+  if (pr == NoProc)\r
+  {\r
+    if (appData.noJoin || !appData.useInternalWrap)\r
+      return no_wrap(message, count);\r
+    else\r
+    {\r
+      int width = get_term_width();\r
+      int len = wrap(NULL, message, count, width, &line);\r
+      char *msg = malloc(len);\r
+      int dbgchk;\r
+\r
+      if (!msg)\r
+        return no_wrap(message, count);\r
+      else\r
+      {\r
+        dbgchk = wrap(msg, message, count, width, &line);\r
+        if (dbgchk != len && appData.debugMode)\r
+            fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len);\r
+        ConsoleOutput(msg, len, FALSE);\r
+        free(msg);\r
+        return len;\r
+      }\r
+    }\r
   }\r
 \r
   if (ovl.hEvent == NULL) {\r
@@ -10646,7 +9069,7 @@ OutputToProcess(ProcRef pr, char *message, int count, int *outError)
 \r
   case CPReal:\r
     if (WriteFile(((ChildProc *)pr)->hTo, message, count,\r
-          &dOutCount, NULL)) {\r
+                 &dOutCount, NULL)) {\r
       *outError = NO_ERROR;\r
       outCount = (int) dOutCount;\r
     } else {\r
@@ -10656,7 +9079,7 @@ OutputToProcess(ProcRef pr, char *message, int count, int *outError)
 \r
   case CPComm:\r
     *outError = DoWriteFile(((ChildProc *)pr)->hTo, message, count,\r
-                &dOutCount, &ovl);\r
+                           &dOutCount, &ovl);\r
     if (*outError == NO_ERROR) {\r
       outCount = (int) dOutCount;\r
     }\r
@@ -10667,7 +9090,7 @@ OutputToProcess(ProcRef pr, char *message, int count, int *outError)
 \r
 int\r
 OutputToProcessDelayed(ProcRef pr, char *message, int count, int *outError,\r
-               long msdelay)\r
+                      long msdelay)\r
 {\r
   /* Ignore delay, not implemented for WinBoard */\r
   return OutputToProcess(pr, message, count, outError);\r
@@ -10676,7 +9099,7 @@ OutputToProcessDelayed(ProcRef pr, char *message, int count, int *outError,
 \r
 void\r
 CmailSigHandlerCallBack(InputSourceRef isr, VOIDSTAR closure,\r
-            char *buf, int count, int error)\r
+                       char *buf, int count, int error)\r
 {\r
   DisplayFatalError("Not implemented", 0, 1);\r
 }\r
@@ -10707,135 +9130,10 @@ StartAnalysisClock()
 {\r
   if (analysisTimerEvent) return;\r
   analysisTimerEvent = SetTimer(hwndMain, (UINT) ANALYSIS_TIMER_ID,\r
-                                (UINT) 2000, NULL);\r
-}\r
-\r
-LRESULT CALLBACK\r
-AnalysisDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  static HANDLE hwndText;\r
-  RECT rect;\r
-  static int sizeX, sizeY;\r
-  int newSizeX, newSizeY, flags;\r
-  MINMAXINFO *mmi;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-    /* Initialize the dialog items */\r
-    hwndText = GetDlgItem(hDlg, OPT_AnalysisText);\r
-    SetWindowText(hDlg, analysisTitle);\r
-    SetDlgItemText(hDlg, OPT_AnalysisText, analysisText);\r
-    /* Size and position the dialog */\r
-    if (!analysisDialog) {\r
-      analysisDialog = hDlg;\r
-      flags = SWP_NOZORDER;\r
-      GetClientRect(hDlg, &rect);\r
-      sizeX = rect.right;\r
-      sizeY = rect.bottom;\r
-      if (analysisX != CW_USEDEFAULT && analysisY != CW_USEDEFAULT &&\r
-      analysisW != CW_USEDEFAULT && analysisH != CW_USEDEFAULT) {\r
-    WINDOWPLACEMENT wp;\r
-    EnsureOnScreen(&analysisX, &analysisY, 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 = analysisX;\r
-    wp.rcNormalPosition.right = analysisX + analysisW;\r
-    wp.rcNormalPosition.top = analysisY;\r
-    wp.rcNormalPosition.bottom = analysisY + analysisH;\r
-    SetWindowPlacement(hDlg, &wp);\r
-\r
-    GetClientRect(hDlg, &rect);\r
-    newSizeX = rect.right;\r
-    newSizeY = rect.bottom;\r
-        ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY,\r
-                  newSizeX, newSizeY);\r
-    sizeX = newSizeX;\r
-    sizeY = newSizeY;\r
-      }\r
-    }\r
-    return FALSE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDCANCEL:\r
-      if (appData.icsActive && appData.icsEngineAnalyze) { /* [DM] icsEngineAnalyze */\r
-          ExitAnalyzeMode();\r
-          ModeHighlight();\r
-          return TRUE;\r
-      }\r
-      EditGameEvent();\r
-      return TRUE;\r
-    default:\r
-      break;\r
-    }\r
-    break;\r
-\r
-  case WM_SIZE:\r
-    newSizeX = LOWORD(lParam);\r
-    newSizeY = HIWORD(lParam);\r
-    ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY, newSizeX, newSizeY);\r
-    sizeX = newSizeX;\r
-    sizeY = newSizeY;\r
-    break;\r
-\r
-  case WM_GETMINMAXINFO:\r
-    /* Prevent resizing window too small */\r
-    mmi = (MINMAXINFO *) lParam;\r
-    mmi->ptMinTrackSize.x = 100;\r
-    mmi->ptMinTrackSize.y = 100;\r
-    break;\r
-  }\r
-  return FALSE;\r
+                                       (UINT) 2000, NULL);\r
 }\r
 \r
 VOID\r
-AnalysisPopUp(char* title, char* str)\r
-{\r
-  FARPROC lpProc;\r
-  char *p, *q;\r
-\r
-  /* [AS] */\r
-  EngineOutputPopUp();\r
-  return;\r
-\r
-  if (str == NULL) str = "";\r
-  p = (char *) malloc(2 * strlen(str) + 2);\r
-  q = p;\r
-  while (*str) {\r
-    if (*str == '\n') *q++ = '\r';\r
-    *q++ = *str++;\r
-  }\r
-  *q = NULLCHAR;\r
-  if (analysisText != NULL) free(analysisText);\r
-  analysisText = p;\r
-\r
-  if (analysisDialog) {\r
-    SetWindowText(analysisDialog, title);\r
-    SetDlgItemText(analysisDialog, OPT_AnalysisText, analysisText);\r
-    ShowWindow(analysisDialog, SW_SHOW);\r
-  } else {\r
-    analysisTitle = title;\r
-    lpProc = MakeProcInstance((FARPROC)AnalysisDialog, hInst);\r
-    CreateDialog(hInst, MAKEINTRESOURCE(DLG_Analysis),\r
-         hwndMain, (DLGPROC)lpProc);\r
-    FreeProcInstance(lpProc);\r
-  }\r
-  analysisDialogUp = TRUE;\r
-}\r
-\r
-VOID\r
-AnalysisPopDown()\r
-{\r
-  if (analysisDialog) {\r
-    ShowWindow(analysisDialog, SW_HIDE);\r
-  }\r
-  analysisDialogUp = FALSE;\r
-}\r
-\r
-\r
-VOID\r
 SetHighlights(int fromX, int fromY, int toX, int toY)\r
 {\r
   highlightInfo.sq[0].x = fromX;\r
@@ -10847,7 +9145,7 @@ SetHighlights(int fromX, int fromY, int toX, int toY)
 VOID\r
 ClearHighlights()\r
 {\r
-  highlightInfo.sq[0].x = highlightInfo.sq[0].y =\r
+  highlightInfo.sq[0].x = highlightInfo.sq[0].y = \r
     highlightInfo.sq[1].x = highlightInfo.sq[1].y = -1;\r
 }\r
 \r
@@ -10863,7 +9161,7 @@ SetPremoveHighlights(int fromX, int fromY, int toX, int toY)
 VOID\r
 ClearPremoveHighlights()\r
 {\r
-  premoveHighlightInfo.sq[0].x = premoveHighlightInfo.sq[0].y =\r
+  premoveHighlightInfo.sq[0].x = premoveHighlightInfo.sq[0].y = \r
     premoveHighlightInfo.sq[1].x = premoveHighlightInfo.sq[1].y = -1;\r
 }\r
 \r
@@ -10893,20 +9191,20 @@ static void Tween( POINT * start, POINT * mid, POINT * finish, int factor,
 \r
 void\r
 AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames)\r
-{   // [HGM] atomic: animate blast wave\r
-    int i;\r
+{      // [HGM] atomic: animate blast wave\r
+       int i;\r
 if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY);\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
-    }\r
-    explodeInfo.radius = 0;\r
-    DrawPosition(TRUE, NULL);\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
+       }\r
+       explodeInfo.radius = 0;\r
+       DrawPosition(TRUE, NULL);\r
 }\r
 \r
 #define kFactor 4\r
@@ -10947,7 +9245,7 @@ AnimateMove(board, fromX, fromY, toX, toY)
        mid.y = start.y + (finish.y - start.y) / 2;\r
      }\r
   }\r
-\r
+  \r
   /* Don't use as many frames for very short moves */\r
   if (abs(toY - fromY) + abs(toX - fromX) <= 2)\r
     Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames);\r
@@ -10969,9 +9267,9 @@ AnimateMove(board, fromX, fromY, toX, toY)
   animInfo.pos = finish;\r
   DrawPosition(FALSE, NULL);\r
   animInfo.piece = EmptySquare;\r
-  if(gameInfo.variant == VariantAtomic &&\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
+       AnimateAtomicCapture(fromX, fromY, toX, toY, 2*nFrames);\r
 }\r
 \r
 /*      Convert board position to corner of screen rect and color       */\r
@@ -11016,11 +9314,11 @@ Tween(start, mid, finish, factor, frames, nFrames)
     count ++;\r
     fraction = fraction / 2;\r
   }\r
-\r
+  \r
   /* Midpoint */\r
   frames[count] = *mid;\r
   count ++;\r
-\r
+  \r
   /* Slow out, stepping 1/2, then 1/4, ... */\r
   fraction = 2;\r
   for (n = 0; n < factor; n++) {\r
@@ -11035,30 +9333,7 @@ Tween(start, mid, finish, factor, frames, nFrames)
 void\r
 HistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current )\r
 {\r
-#if 0\r
-    char buf[256];\r
-\r
-    sprintf( buf, "HistorySet: first=%d, last=%d, current=%d (%s)\n",\r
-        first, last, current, current >= 0 ? movelist[current] : "n/a" );\r
-\r
-    OutputDebugString( buf );\r
-#endif\r
-\r
     MoveHistorySet( movelist, first, last, current, pvInfoList );\r
 \r
     EvalGraphSet( first, last, current, pvInfoList );\r
 }\r
-\r
-void SetProgramStats( FrontEndProgramStats * stats )\r
-{\r
-#if 0\r
-    char buf[1024];\r
-\r
-    sprintf( buf, "SetStats for %d: depth=%d, nodes=%lu, score=%5.2f, time=%5.2f, pv=%s\n",\r
-        stats->which, stats->depth, stats->nodes, stats->score / 100.0, stats->time / 100.0, stats->pv == 0 ? "n/a" : stats->pv );\r
-\r
-    OutputDebugString( buf );\r
-#endif\r
-\r
-    EngineOutputUpdate( stats );\r
-}\r