changes from H.G. Muller; version 4.3.16
[xboard.git] / winboard / woptions.c
index 0941cce..aa272e9 100644 (file)
-/*\r
- * woptions.c -- Options dialog box routines for WinBoard\r
- * $Id: woptions.c,v 2.1 2003/10/27 19:21:02 mann Exp $\r
- *\r
- * Copyright 2000 Free Software Foundation, Inc.\r
- *\r
- * ------------------------------------------------------------------------\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- * ------------------------------------------------------------------------\r
- */\r
-\r
-#include "config.h"\r
-\r
-#include <windows.h>   /* required for all Windows applications */\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <shlobj.h>    /* [AS] Requires NT 4.0 or Win95 */\r
-\r
-#include "common.h"\r
-#include "winboard.h"\r
-#include "backend.h"\r
-#include "woptions.h"\r
-#include "defaults.h"\r
-#include "wedittags.h"\r
-#include <richedit.h>\r
-\r
-#if __GNUC__\r
-#include <errno.h>\r
-#include <string.h>\r
-#endif\r
-\r
-/* Imports from winboard.c */\r
-\r
-extern MyFont *font[NUM_SIZES][NUM_FONTS];\r
-extern HINSTANCE hInst;          /* current instance */\r
-extern HWND hwndMain;            /* root window*/\r
-extern BOOLEAN alwaysOnTop;\r
-extern RECT boardRect;\r
-extern COLORREF lightSquareColor, darkSquareColor, whitePieceColor, \r
-  blackPieceColor, highlightSquareColor, premoveHighlightColor;\r
-extern HPALETTE hPal;\r
-extern BoardSize boardSize;\r
-extern COLORREF consoleBackgroundColor;\r
-extern MyColorizeAttribs colorizeAttribs[]; /* do I need the size? */\r
-extern MyTextAttribs textAttribs[];\r
-extern MySound sounds[];\r
-extern ColorClass currentColorClass;\r
-extern HWND hwndConsole;\r
-extern char *defaultTextAttribs[];\r
-extern HWND commentDialog;\r
-extern HWND moveHistoryDialog;\r
-extern char installDir[];\r
-extern HWND hCommPort;    /* currently open comm port */\r
-extern DCB dcb;\r
-extern BOOLEAN chessProgram;\r
-extern startedFromPositionFile; /* [HGM] loadPos */\r
-\r
-/* types */\r
-\r
-typedef struct {\r
-  char *label;\r
-  unsigned value;\r
-} ComboData;\r
-\r
-typedef struct {\r
-  char *label;\r
-  char *name;\r
-} SoundComboData;\r
-\r
-/* module prototypes */\r
-\r
-LRESULT CALLBACK GeneralOptions(HWND, UINT, WPARAM, LPARAM);\r
-LRESULT CALLBACK BoardOptions(HWND, UINT, WPARAM, LPARAM);\r
-LRESULT CALLBACK NewVariant(HWND, UINT, WPARAM, LPARAM);\r
-LRESULT CALLBACK IcsOptions(HWND, UINT, WPARAM, LPARAM);\r
-LRESULT CALLBACK FontOptions(HWND, UINT, WPARAM, LPARAM);\r
-LRESULT CALLBACK CommPortOptions(HWND, UINT, WPARAM, LPARAM);\r
-LRESULT CALLBACK LoadOptions(HWND, UINT, WPARAM, LPARAM);\r
-LRESULT CALLBACK SaveOptions(HWND, UINT, WPARAM, LPARAM);\r
-LRESULT CALLBACK TimeControl(HWND, UINT, WPARAM, LPARAM);\r
-VOID ChangeBoardSize(BoardSize newSize);\r
-VOID PaintSampleSquare(\r
-    HWND     hwnd, \r
-    int      ctrlid, \r
-    COLORREF squareColor, \r
-    COLORREF pieceColor,\r
-    COLORREF squareOutlineColor,\r
-    COLORREF pieceDetailColor,\r
-    BOOL     isWhitePiece,\r
-    BOOL     isMono,\r
-    HBITMAP  pieces[3] \r
-    );\r
-VOID PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color);\r
-VOID SetBoardOptionEnables(HWND hDlg);\r
-BoardSize BoardOptionsWhichRadio(HWND hDlg);\r
-BOOL APIENTRY MyCreateFont(HWND hwnd, MyFont *font);\r
-VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca);\r
-LRESULT CALLBACK ColorizeTextDialog(HWND , UINT, WPARAM, LPARAM);\r
-VOID ColorizeTextPopup(HWND hwnd, ColorClass cc);\r
-VOID SetIcsOptionEnables(HWND hDlg);\r
-VOID SetSampleFontText(HWND hwnd, int id, const MyFont *mf);\r
-VOID CopyFont(MyFont *dest, const MyFont *src);\r
-void InitSoundComboData(SoundComboData *scd);\r
-void ResetSoundComboData(SoundComboData *scd);\r
-void InitSoundCombo(HWND hwndCombo, SoundComboData *scd);\r
-int SoundDialogWhichRadio(HWND hDlg);\r
-VOID SoundDialogSetEnables(HWND hDlg, int radio);\r
-char * SoundDialogGetName(HWND hDlg, int radio);\r
-void DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name);\r
-VOID ParseCommSettings(char *arg, DCB *dcb);\r
-VOID PrintCommSettings(FILE *f, char *name, DCB *dcb);\r
-void InitCombo(HANDLE hwndCombo, ComboData *cd);\r
-void SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value);\r
-VOID SetLoadOptionEnables(HWND hDlg);\r
-VOID SetSaveOptionEnables(HWND hDlg);\r
-VOID SetTimeControlEnables(HWND hDlg);\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * General Options Dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-\r
-\r
-LRESULT CALLBACK\r
-GeneralOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  static Boolean oldShowCoords;\r
-  static Boolean oldBlindfold;\r
-  static Boolean oldShowButtonBar;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-    oldShowCoords = appData.showCoords;\r
-    oldBlindfold  = appData.blindfold;\r
-    oldShowButtonBar = appData.showButtonBar;\r
-\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-\r
-    /* Initialize the dialog items */\r
-#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
-\r
-    CHECK_BOX(OPT_AlwaysOnTop, alwaysOnTop);\r
-    CHECK_BOX(OPT_AlwaysQueen, appData.alwaysPromoteToQueen);\r
-    CHECK_BOX(OPT_AnimateDragging, appData.animateDragging);\r
-    CHECK_BOX(OPT_AnimateMoving, appData.animate);\r
-    CHECK_BOX(OPT_AutoFlag, appData.autoCallFlag);\r
-    CHECK_BOX(OPT_AutoFlipView, appData.autoFlipView);\r
-    CHECK_BOX(OPT_AutoRaiseBoard, appData.autoRaiseBoard);\r
-    CHECK_BOX(OPT_Blindfold, appData.blindfold);\r
-    CHECK_BOX(OPT_HighlightDragging, appData.highlightDragging);\r
-    CHECK_BOX(OPT_HighlightLastMove, appData.highlightLastMove);\r
-    CHECK_BOX(OPT_PeriodicUpdates, appData.periodicUpdates);\r
-    CHECK_BOX(OPT_PonderNextMove, appData.ponderNextMove);\r
-    CHECK_BOX(OPT_PopupExitMessage, appData.popupExitMessage);\r
-    CHECK_BOX(OPT_PopupMoveErrors, appData.popupMoveErrors);\r
-    CHECK_BOX(OPT_ShowButtonBar, appData.showButtonBar);\r
-    CHECK_BOX(OPT_ShowCoordinates, appData.showCoords);\r
-    CHECK_BOX(OPT_ShowThinking, appData.showThinking);\r
-    CHECK_BOX(OPT_TestLegality, appData.testLegality);\r
-    CHECK_BOX(OPT_HideThinkFromHuman, appData.hideThinkingFromHuman);\r
-    CHECK_BOX(OPT_SaveExtPGN, appData.saveExtendedInfoInPGN);\r
-    CHECK_BOX(OPT_ExtraInfoInMoveHistory, appData.showEvalInMoveHistory);\r
-    CHECK_BOX(OPT_HighlightMoveArrow, appData.highlightMoveWithArrow);\r
-\r
-#undef CHECK_BOX\r
-\r
-    EnableWindow(GetDlgItem(hDlg, OPT_AutoFlag),\r
-                appData.icsActive || !appData.noChessProgram);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_AutoFlipView),\r
-                appData.icsActive || !appData.noChessProgram);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_PonderNextMove),\r
-                !appData.noChessProgram);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_PeriodicUpdates), \r
-                !appData.noChessProgram && !appData.icsActive);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_ShowThinking), \r
-                !appData.noChessProgram);\r
-    return TRUE;\r
-\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* Read changed options from the dialog box */\r
-      \r
-#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
-\r
-      alwaysOnTop                  = IS_CHECKED(OPT_AlwaysOnTop);\r
-      appData.alwaysPromoteToQueen = IS_CHECKED(OPT_AlwaysQueen);\r
-      appData.animateDragging      = IS_CHECKED(OPT_AnimateDragging);\r
-      appData.animate              = IS_CHECKED(OPT_AnimateMoving);\r
-      appData.autoCallFlag         = IS_CHECKED(OPT_AutoFlag);\r
-      appData.autoFlipView         = IS_CHECKED(OPT_AutoFlipView);\r
-      appData.autoRaiseBoard       = IS_CHECKED(OPT_AutoRaiseBoard);\r
-      appData.blindfold            = IS_CHECKED(OPT_Blindfold);\r
-      appData.highlightDragging    = IS_CHECKED(OPT_HighlightDragging);\r
-      appData.highlightLastMove    = IS_CHECKED(OPT_HighlightLastMove);\r
-      PeriodicUpdatesEvent(          IS_CHECKED(OPT_PeriodicUpdates));\r
-      PonderNextMoveEvent(           IS_CHECKED(OPT_PonderNextMove));\r
-      appData.popupExitMessage     = IS_CHECKED(OPT_PopupExitMessage);\r
-      appData.popupMoveErrors      = IS_CHECKED(OPT_PopupMoveErrors);\r
-      appData.showButtonBar        = IS_CHECKED(OPT_ShowButtonBar);\r
-      appData.showCoords           = IS_CHECKED(OPT_ShowCoordinates);\r
-      // [HGM] thinking: next three moved up\r
-      appData.saveExtendedInfoInPGN= IS_CHECKED(OPT_SaveExtPGN);\r
-      appData.hideThinkingFromHuman= IS_CHECKED(OPT_HideThinkFromHuman);\r
-      appData.showEvalInMoveHistory= IS_CHECKED(OPT_ExtraInfoInMoveHistory);\r
-#if 0\r
-      ShowThinkingEvent(             IS_CHECKED(OPT_ShowThinking));\r
-#else\r
-      appData.showThinking         = IS_CHECKED(OPT_ShowThinking);\r
-      ShowThinkingEvent(); // [HGM] thinking: tests four options\r
-#endif\r
-      appData.testLegality         = IS_CHECKED(OPT_TestLegality);\r
-      appData.highlightMoveWithArrow=IS_CHECKED(OPT_HighlightMoveArrow);\r
-\r
-#undef IS_CHECKED\r
-\r
-      SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
-                  0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
-#if AOT_CONSOLE\r
-      if (hwndConsole) {\r
-       SetWindowPos(hwndConsole, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
-                    0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
-      }\r
-#endif\r
-      if (!appData.highlightLastMove) {\r
-       ClearHighlights();\r
-       DrawPosition(FALSE, NULL);\r
-      }\r
-      /* \r
-       * for some reason the redraw seems smoother when we invalidate\r
-       * the board rect after the call to EndDialog()\r
-       */\r
-      EndDialog(hDlg, TRUE);\r
-\r
-      if (oldShowButtonBar != appData.showButtonBar) {\r
-       InitDrawingSizes(boardSize, 0);\r
-      } else if ((oldShowCoords != appData.showCoords) || \r
-                (oldBlindfold != appData.blindfold)) {\r
-       InvalidateRect(hwndMain, &boardRect, FALSE);\r
-      }\r
-\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID \r
-GeneralOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc;\r
-\r
-  lpProc = MakeProcInstance((FARPROC)GeneralOptionsDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_GeneralOptions), hwnd,\r
-           (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * Board Options Dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-\r
-const int SAMPLE_SQ_SIZE = 54;\r
-\r
-VOID\r
-ChangeBoardSize(BoardSize newSize)\r
-{\r
-  if (newSize != boardSize) {\r
-    boardSize = newSize;\r
-    InitDrawingSizes(boardSize, 0);\r
-  }\r
-}\r
-\r
-VOID\r
-PaintSampleSquare(\r
-    HWND     hwnd, \r
-    int      ctrlid, \r
-    COLORREF squareColor, \r
-    COLORREF pieceColor,\r
-    COLORREF squareOutlineColor,\r
-    COLORREF pieceDetailColor,\r
-    BOOL     isWhitePiece,\r
-    BOOL     isMono,\r
-    HBITMAP  pieces[3] \r
-    )\r
-{\r
-  HBRUSH  brushSquare;\r
-  HBRUSH  brushSquareOutline;\r
-  HBRUSH  brushPiece;\r
-  HBRUSH  brushPieceDetail;\r
-  HBRUSH  oldBrushPiece;\r
-  HBRUSH  oldBrushSquare;\r
-  HBITMAP oldBitmapMem;\r
-  HBITMAP oldBitmapTemp;\r
-  HBITMAP bufferBitmap;\r
-  RECT    rect;\r
-  HDC     hdcScreen, hdcMem, hdcTemp;\r
-  HPEN    pen, oldPen;\r
-  HWND    hCtrl = GetDlgItem(hwnd, ctrlid);\r
-  int     x, y;\r
-\r
-  const int SOLID   = 0;\r
-  const int WHITE   = 1;\r
-  const int OUTLINE = 2;\r
-  const int BORDER  = 4;\r
-\r
-  InvalidateRect(hCtrl, NULL, TRUE);\r
-  UpdateWindow(hCtrl);\r
-  GetClientRect(hCtrl, &rect);\r
-  x = rect.left + (BORDER / 2);\r
-  y = rect.top  + (BORDER / 2);\r
-  hdcScreen = GetDC(hCtrl);\r
-  hdcMem  = CreateCompatibleDC(hdcScreen);\r
-  hdcTemp = CreateCompatibleDC(hdcScreen);\r
-\r
-  bufferBitmap = CreateCompatibleBitmap(hdcScreen, rect.right-rect.left+1,\r
-                                       rect.bottom-rect.top+1);\r
-  oldBitmapMem = SelectObject(hdcMem, bufferBitmap);\r
-  if (!isMono) {\r
-    SelectPalette(hdcMem, hPal, FALSE);\r
-  }\r
-  brushSquare         = CreateSolidBrush(squareColor);\r
-  brushSquareOutline  = CreateSolidBrush(squareOutlineColor);\r
-  brushPiece          = CreateSolidBrush(pieceColor);\r
-  brushPieceDetail    = CreateSolidBrush(pieceDetailColor);\r
-\r
-  /* \r
-   * first draw the rectangle \r
-   */\r
-  pen      = CreatePen(PS_SOLID, BORDER, squareOutlineColor);\r
-  oldPen   = (HPEN)  SelectObject(hdcMem, pen);\r
-  oldBrushSquare = (HBRUSH)SelectObject(hdcMem, brushSquare);\r
-  Rectangle(hdcMem, rect.left, rect.top, rect.right, rect.bottom);\r
-\r
-  /* \r
-   * now draw the piece\r
-   */\r
-  if (isMono) {\r
-    oldBitmapTemp = SelectObject(hdcTemp, pieces[OUTLINE]);\r
-    BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, hdcTemp, 0, 0,\r
-          isWhitePiece ? SRCCOPY : NOTSRCCOPY);\r
-    SelectObject(hdcTemp, oldBitmapTemp);\r
-  } else {\r
-    if (isWhitePiece) {\r
-      oldBitmapTemp = SelectObject(hdcTemp, pieces[WHITE]);\r
-      oldBrushPiece = SelectObject(hdcMem, brushPiece);\r
-      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
-            hdcTemp, 0, 0, 0x00B8074A);\r
-#if 0\r
-      /* Use pieceDetailColor for outline of white pieces */\r
-      SelectObject(hdcTemp, pieces[OUTLINE]);\r
-      SelectObject(hdcMem, brushPieceDetail);\r
-      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
-            hdcTemp, 0, 0, 0x00B8074A);\r
-#else\r
-      /* Use black for outline of white pieces */\r
-      SelectObject(hdcTemp, pieces[OUTLINE]);\r
-      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
-            hdcTemp, 0, 0, SRCAND);\r
-#endif\r
-    } else {\r
-#if 0\r
-      /* Use pieceDetailColor 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
-      oldBitmapTemp = SelectObject(hdcTemp, pieces[BLACK]);\r
-      oldBrushPiece = SelectObject(hdcMem, brushPieceDetail);\r
-      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
-            hdcTemp, 0, 0, 0x00B8074A);\r
-      SelectObject(hdcTemp, pieces[SOLID]);\r
-      SelectObject(hdcMem, brushPiece);\r
-      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
-            hdcTemp, 0, 0, 0x00B8074A);\r
-#else\r
-      /* Use square color for details of black pieces */\r
-      oldBitmapTemp = SelectObject(hdcTemp, pieces[SOLID]);\r
-      oldBrushPiece = SelectObject(hdcMem, brushPiece);\r
-      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
-            hdcTemp, 0, 0, 0x00B8074A);\r
-#endif\r
-    }\r
-    SelectObject(hdcMem, oldBrushPiece);\r
-    SelectObject(hdcTemp, oldBitmapTemp);\r
-  }\r
-  /* \r
-   * copy the memory dc to the screen\r
-   */\r
-  SelectObject(hdcMem, bufferBitmap);\r
-  BitBlt(hdcScreen, rect.left, rect.top,\r
-        rect.right - rect.left,\r
-        rect.bottom - rect.top,\r
-        hdcMem, rect.left, rect.top, SRCCOPY);\r
-  SelectObject(hdcMem, oldBitmapMem);\r
-  /* \r
-   * clean up\r
-   */\r
-  SelectObject(hdcMem, oldBrushPiece);\r
-  SelectObject(hdcMem, oldPen);\r
-  DeleteObject(brushPiece);\r
-  DeleteObject(brushPieceDetail);\r
-  DeleteObject(brushSquare);\r
-  DeleteObject(brushSquareOutline);\r
-  DeleteObject(pen);\r
-  DeleteDC(hdcTemp);\r
-  DeleteDC(hdcMem);\r
-  ReleaseDC(hCtrl, hdcScreen);\r
-}\r
-\r
-\r
-VOID\r
-PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color)\r
-{\r
-  HDC    hdc;\r
-  HBRUSH brush, oldBrush;\r
-  RECT   rect;\r
-  HWND   hCtrl = GetDlgItem(hwnd, ctrlid);\r
-\r
-  hdc = GetDC(hCtrl);\r
-  InvalidateRect(hCtrl, NULL, TRUE);\r
-  UpdateWindow(hCtrl);\r
-  GetClientRect(hCtrl, &rect);\r
-  brush = CreateSolidBrush(color);\r
-  oldBrush = (HBRUSH)SelectObject(hdc, brush);\r
-  Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);\r
-  SelectObject(hdc, oldBrush);\r
-  DeleteObject(brush);\r
-  ReleaseDC(hCtrl, hdc);\r
-}\r
-\r
-\r
-VOID\r
-SetBoardOptionEnables(HWND hDlg)\r
-{\r
-  if (IsDlgButtonChecked(hDlg, OPT_Monochrome)) {\r
-    ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_HIDE);\r
-    ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_HIDE);\r
-    ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_HIDE);\r
-    ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_HIDE);\r
-\r
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), FALSE);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), FALSE);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), FALSE);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), FALSE);\r
-  } else {\r
-    ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_SHOW);\r
-    ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_SHOW);\r
-    ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_SHOW);\r
-    ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_SHOW);\r
-\r
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), TRUE);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), TRUE);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), TRUE);\r
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), TRUE);\r
-  }\r
-}\r
-\r
-BoardSize \r
-BoardOptionsWhichRadio(HWND hDlg)\r
-{\r
-  return (IsDlgButtonChecked(hDlg, OPT_SizeTiny) ? SizeTiny :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeTeeny) ? SizeTeeny :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeDinky) ? SizeDinky :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizePetite) ? SizePetite :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeSlim) ? SizeSlim :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeSmall) ? SizeSmall :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeMediocre) ? SizeMediocre :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeMiddling) ? SizeMiddling :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeAverage) ? SizeAverage :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeModerate) ? SizeModerate :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeMedium) ? SizeMedium :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeBulky) ? SizeBulky :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeLarge) ? SizeLarge :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeBig) ? SizeBig :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeHuge) ? SizeHuge :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeGiant) ? SizeGiant :\r
-         (IsDlgButtonChecked(hDlg, OPT_SizeColossal) ? SizeColossal :\r
-          SizeTitanic )))))))))))))))));\r
-}\r
-\r
-LRESULT CALLBACK\r
-BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  static Boolean  mono, white, flip;\r
-  static BoardSize size;\r
-  static COLORREF lsc, dsc, wpc, bpc, hsc, phc;\r
-  static HBITMAP pieces[3];\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-    /* Initialize the dialog items */\r
-    switch (boardSize) {\r
-    case SizeTiny:\r
-      CheckDlgButton(hDlg, OPT_SizeTiny, TRUE);\r
-      break;\r
-    case SizeTeeny:\r
-      CheckDlgButton(hDlg, OPT_SizeTeeny, TRUE);\r
-      break;\r
-    case SizeDinky:\r
-      CheckDlgButton(hDlg, OPT_SizeDinky, TRUE);\r
-      break;\r
-    case SizePetite:\r
-      CheckDlgButton(hDlg, OPT_SizePetite, TRUE);\r
-      break;\r
-    case SizeSlim:\r
-      CheckDlgButton(hDlg, OPT_SizeSlim, TRUE);\r
-      break;\r
-    case SizeSmall:\r
-      CheckDlgButton(hDlg, OPT_SizeSmall, TRUE);\r
-      break;\r
-    case SizeMediocre:\r
-      CheckDlgButton(hDlg, OPT_SizeMediocre, TRUE);\r
-      break;\r
-    case SizeMiddling:\r
-      CheckDlgButton(hDlg, OPT_SizeMiddling, TRUE);\r
-      break;\r
-    case SizeAverage:\r
-      CheckDlgButton(hDlg, OPT_SizeAverage, TRUE);\r
-      break;\r
-    case SizeModerate:\r
-      CheckDlgButton(hDlg, OPT_SizeModerate, TRUE);\r
-      break;\r
-    case SizeMedium:\r
-      CheckDlgButton(hDlg, OPT_SizeMedium, TRUE);\r
-      break;\r
-    case SizeBulky:\r
-      CheckDlgButton(hDlg, OPT_SizeBulky, TRUE);\r
-      break;\r
-    case SizeLarge:\r
-      CheckDlgButton(hDlg, OPT_SizeLarge, TRUE);\r
-      break;\r
-    case SizeBig:\r
-      CheckDlgButton(hDlg, OPT_SizeBig, TRUE);\r
-      break;\r
-    case SizeHuge:\r
-      CheckDlgButton(hDlg, OPT_SizeHuge, TRUE);\r
-      break;\r
-    case SizeGiant:\r
-      CheckDlgButton(hDlg, OPT_SizeGiant, TRUE);\r
-      break;\r
-    case SizeColossal:\r
-      CheckDlgButton(hDlg, OPT_SizeColossal, TRUE);\r
-      break;\r
-    case SizeTitanic:\r
-      CheckDlgButton(hDlg, OPT_SizeTitanic, TRUE);\r
-    }\r
-\r
-    if (appData.monoMode)\r
-      CheckDlgButton(hDlg, OPT_Monochrome, TRUE);\r
-\r
-    if (appData.allWhite)\r
-      CheckDlgButton(hDlg, OPT_AllWhite, TRUE);\r
-\r
-    if (appData.upsideDown)\r
-      CheckDlgButton(hDlg, OPT_UpsideDown, TRUE);\r
-\r
-    pieces[0] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "s");\r
-    pieces[1] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "w");\r
-    pieces[2] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "o");\r
-       \r
-    lsc = lightSquareColor;\r
-    dsc = darkSquareColor;\r
-    wpc = whitePieceColor;\r
-    bpc = blackPieceColor;\r
-    hsc = highlightSquareColor;\r
-    phc = premoveHighlightColor;\r
-    mono = appData.monoMode;\r
-    white= appData.allWhite;\r
-    flip = appData.upsideDown;\r
-    size = boardSize;\r
-\r
-    SetBoardOptionEnables(hDlg);\r
-    return TRUE;\r
-\r
-  case WM_PAINT:\r
-    PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);\r
-    PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);\r
-    PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);\r
-    PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);\r
-    PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);\r
-    PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);\r
-    PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
-       TRUE, mono, pieces);\r
-    PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
-       FALSE, mono, pieces);\r
-\r
-    return FALSE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* \r
-       * if we call EndDialog() after the call to ChangeBoardSize(),\r
-       * then ChangeBoardSize() does not take effect, although the new\r
-       * boardSize is saved. Go figure...\r
-       */\r
-      EndDialog(hDlg, TRUE);\r
-\r
-      size = BoardOptionsWhichRadio(hDlg);\r
-\r
-      /*\r
-       * did any settings change?\r
-       */\r
-      if (size != boardSize) {\r
-       ChangeBoardSize(size);\r
-      }\r
-\r
-      if ((mono != appData.monoMode) ||\r
-         (lsc  != lightSquareColor) ||\r
-         (dsc  != darkSquareColor) ||\r
-         (wpc  != whitePieceColor) ||\r
-         (bpc  != blackPieceColor) ||\r
-         (hsc  != highlightSquareColor) ||\r
-          (flip != appData.upsideDown) ||\r
-          (white != appData.allWhite) ||\r
-         (phc  != premoveHighlightColor)) {\r
-\r
-         lightSquareColor = lsc;\r
-         darkSquareColor = dsc;\r
-         whitePieceColor = wpc;\r
-         blackPieceColor = bpc;\r
-         highlightSquareColor = hsc;\r
-         premoveHighlightColor = phc;\r
-         appData.monoMode = mono;\r
-          appData.allWhite = white;\r
-          appData.upsideDown = flip;\r
-\r
-         InitDrawingColors();\r
-         InitDrawingSizes(boardSize, 0);\r
-         InvalidateRect(hwndMain, &boardRect, FALSE);\r
-      }\r
-      DeleteObject(pieces[0]);\r
-      DeleteObject(pieces[1]);\r
-      DeleteObject(pieces[2]);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      DeleteObject(pieces[0]);\r
-      DeleteObject(pieces[1]);\r
-      DeleteObject(pieces[2]);\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    case OPT_ChooseLightSquareColor:\r
-      if (ChangeColor(hDlg, &lsc)) \r
-       PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);\r
-       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
-           TRUE, mono, pieces);\r
-      break;\r
-\r
-    case OPT_ChooseDarkSquareColor:\r
-      if (ChangeColor(hDlg, &dsc)) \r
-       PaintColorBlock(hDlg, OPT_DarkSquareColor, dsc);\r
-       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
-           FALSE, mono, pieces);\r
-      break;\r
-\r
-    case OPT_ChooseWhitePieceColor:\r
-      if (ChangeColor(hDlg, &wpc)) \r
-       PaintColorBlock(hDlg, OPT_WhitePieceColor, wpc);\r
-       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
-           TRUE, mono, pieces);\r
-      break;\r
-\r
-    case OPT_ChooseBlackPieceColor:\r
-      if (ChangeColor(hDlg, &bpc)) \r
-       PaintColorBlock(hDlg, OPT_BlackPieceColor, bpc);\r
-       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
-           FALSE, mono, pieces);\r
-      break;\r
-\r
-    case OPT_ChooseHighlightSquareColor:\r
-      if (ChangeColor(hDlg, &hsc)) \r
-       PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);\r
-       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
-           TRUE, mono, pieces);\r
-      break;\r
-\r
-    case OPT_ChoosePremoveHighlightColor:\r
-      if (ChangeColor(hDlg, &phc)) \r
-       PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);\r
-       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
-           FALSE, mono, pieces);\r
-      break;\r
-\r
-    case OPT_DefaultBoardColors:\r
-      lsc = ParseColorName(LIGHT_SQUARE_COLOR);\r
-      dsc = ParseColorName(DARK_SQUARE_COLOR);\r
-      wpc = ParseColorName(WHITE_PIECE_COLOR);\r
-      bpc = ParseColorName(BLACK_PIECE_COLOR);\r
-      hsc = ParseColorName(HIGHLIGHT_SQUARE_COLOR);\r
-      phc = ParseColorName(PREMOVE_HIGHLIGHT_COLOR);\r
-      mono = FALSE;\r
-      white= FALSE;\r
-      flip = FALSE;\r
-      CheckDlgButton(hDlg, OPT_Monochrome, FALSE);\r
-      CheckDlgButton(hDlg, OPT_AllWhite,   FALSE);\r
-      CheckDlgButton(hDlg, OPT_UpsideDown, FALSE);\r
-      PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);\r
-      PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);\r
-      PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);\r
-      PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);\r
-      PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);\r
-      PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);\r
-      SetBoardOptionEnables(hDlg);\r
-      PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
-         TRUE, mono, pieces);\r
-      PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
-         FALSE, mono, pieces);\r
-      break;\r
-\r
-    case OPT_Monochrome:\r
-      mono = !mono;\r
-      SetBoardOptionEnables(hDlg);\r
-      break;\r
-\r
-    case OPT_AllWhite:\r
-      white = !white;\r
-      SetBoardOptionEnables(hDlg);\r
-      break;\r
-\r
-    case OPT_UpsideDown:\r
-      flip = !flip;\r
-      SetBoardOptionEnables(hDlg);\r
-      break;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-\r
-VOID\r
-BoardOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc = MakeProcInstance((FARPROC)BoardOptionsDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_BoardOptions), hwnd,\r
-         (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-VariantClass\r
-VariantWhichRadio(HWND hDlg)\r
-{\r
-  return (IsDlgButtonChecked(hDlg, OPT_VariantFairy) ? VariantFairy :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantGothic) ? VariantGothic :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCrazyhouse) ? VariantCrazyhouse :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantBughouse) ? VariantBughouse :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCourier) ? VariantCourier :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantShogi) ? VariantShogi :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantXiangqi) ? VariantXiangqi :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCapablanca) ? VariantCapablanca :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantTwoKings) ? VariantTwoKings :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantKnightmate) ? VariantKnightmate :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantLosers) ? VariantLosers :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantSuicide) ? VariantSuicide :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantAtomic) ? VariantAtomic :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantFRC) ? VariantFischeRandom :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCylinder) ? VariantCylinder :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantFalcon) ? VariantFalcon :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantCRC) ? VariantCapaRandom :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantSuper) ? VariantSuper :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantBerolina) ? VariantBerolina :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantJanus) ? VariantJanus :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantWildcastle) ? VariantWildCastle :\r
-         (IsDlgButtonChecked(hDlg, OPT_VariantNocastle) ? VariantNoCastle :\r
-          VariantNormal ))))))))))))))))))))))));\r
-}\r
-\r
-LRESULT CALLBACK\r
-NewVariantDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  static Boolean  mono;\r
-  static VariantClass v;\r
-  static COLORREF lsc, dsc, wpc, bpc, hsc, phc;\r
-  static HBITMAP pieces[3];\r
-  static int n1_ok, n2_ok, n3_ok;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-    /* Initialize the dialog items */\r
-    switch (gameInfo.variant) {\r
-    case VariantNormal:\r
-      CheckDlgButton(hDlg, OPT_VariantNormal, TRUE);\r
-      break;\r
-    case VariantCrazyhouse:\r
-      CheckDlgButton(hDlg, OPT_VariantCrazyhouse, TRUE);\r
-      break;\r
-    case VariantBughouse:\r
-      CheckDlgButton(hDlg, OPT_VariantBughouse, TRUE);\r
-      break;\r
-    case VariantShogi:\r
-      CheckDlgButton(hDlg, OPT_VariantShogi, TRUE);\r
-      break;\r
-    case VariantXiangqi:\r
-      CheckDlgButton(hDlg, OPT_VariantXiangqi, TRUE);\r
-      break;\r
-    case VariantCapablanca:\r
-      CheckDlgButton(hDlg, OPT_VariantCapablanca, TRUE);\r
-      break;\r
-    case VariantGothic:\r
-      CheckDlgButton(hDlg, OPT_VariantGothic, TRUE);\r
-      break;\r
-    case VariantCourier:\r
-      CheckDlgButton(hDlg, OPT_VariantCourier, TRUE);\r
-      break;\r
-    case VariantKnightmate:\r
-      CheckDlgButton(hDlg, OPT_VariantKnightmate, TRUE);\r
-      break;\r
-    case VariantTwoKings:\r
-      CheckDlgButton(hDlg, OPT_VariantTwoKings, TRUE);\r
-      break;\r
-    case VariantFairy:\r
-      CheckDlgButton(hDlg, OPT_VariantFairy, TRUE);\r
-      break;\r
-    case VariantAtomic:\r
-      CheckDlgButton(hDlg, OPT_VariantAtomic, TRUE);\r
-      break;\r
-    case VariantSuicide:\r
-      CheckDlgButton(hDlg, OPT_VariantSuicide, TRUE);\r
-      break;\r
-    case VariantLosers:\r
-      CheckDlgButton(hDlg, OPT_VariantLosers, TRUE);\r
-      break;\r
-    case VariantShatranj:\r
-      CheckDlgButton(hDlg, OPT_VariantShatranj, TRUE);\r
-      break;\r
-    case VariantFischeRandom:\r
-      CheckDlgButton(hDlg, OPT_VariantFRC, TRUE);\r
-      break;\r
-    case VariantCapaRandom:\r
-      CheckDlgButton(hDlg, OPT_VariantCRC, TRUE);\r
-      break;\r
-    case VariantFalcon:\r
-      CheckDlgButton(hDlg, OPT_VariantFalcon, TRUE);\r
-      break;\r
-    case VariantCylinder:\r
-      CheckDlgButton(hDlg, OPT_VariantCylinder, TRUE);\r
-      break;\r
-    case Variant3Check:\r
-    case VariantSuper:\r
-      CheckDlgButton(hDlg, OPT_VariantSuper, TRUE);\r
-      break;\r
-    case VariantBerolina:\r
-      CheckDlgButton(hDlg, OPT_VariantBerolina, TRUE);\r
-      break;\r
-    case VariantJanus:\r
-      CheckDlgButton(hDlg, OPT_VariantJanus, TRUE);\r
-      break;\r
-    case VariantWildCastle:\r
-      CheckDlgButton(hDlg, OPT_VariantWildcastle, TRUE);\r
-      break;\r
-    case VariantNoCastle:\r
-      CheckDlgButton(hDlg, OPT_VariantNocastle, TRUE);\r
-      break;\r
-    }\r
-\r
-    SetDlgItemInt( hDlg, IDC_Files, -1, TRUE );\r
-    SendDlgItemMessage( hDlg, IDC_Files, EM_SETSEL, 0, -1 );\r
-\r
-    SetDlgItemInt( hDlg, IDC_Ranks, -1, TRUE );\r
-    SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );\r
-\r
-    SetDlgItemInt( hDlg, IDC_Holdings, -1, TRUE );\r
-    SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );\r
-\r
-    n1_ok = n2_ok = n3_ok = FALSE;\r
-\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* \r
-       * if we call EndDialog() after the call to ChangeBoardSize(),\r
-       * then ChangeBoardSize() does not take effect, although the new\r
-       * boardSize is saved. Go figure...\r
-       */\r
-      EndDialog(hDlg, TRUE);\r
-\r
-      v = VariantWhichRadio(hDlg);\r
-      if(!appData.noChessProgram) { char *name = VariantName(v), buf[MSG_SIZ];\r
-       if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) {\r
-           /* [HGM] in protocol 2 we check if variant is suported by engine */\r
-           sprintf(buf, "Variant %s not supported by %s", name, first.tidy);\r
-           DisplayError(buf, 0);\r
-           return TRUE; /* treat as "Cancel" if first engine does not support it */\r
-       } else\r
-       if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) {\r
-           sprintf(buf, "Warning: second engine (%s) does not support this!", second.tidy);\r
-           DisplayError(buf, 0);   /* use of second engine is optional; only warn user */\r
-       }\r
-      }\r
-\r
-      gameInfo.variant = v;\r
-      appData.variant = VariantName(v);\r
-\r
-      appData.NrFiles = (int) GetDlgItemInt(hDlg, IDC_Files, NULL, FALSE );\r
-      appData.NrRanks = (int) GetDlgItemInt(hDlg, IDC_Ranks, NULL, FALSE );\r
-      appData.holdingsSize = (int) GetDlgItemInt(hDlg, IDC_Holdings, NULL, FALSE );\r
-\r
-      if(!n1_ok) appData.NrFiles = -1;\r
-      if(!n2_ok) appData.NrRanks = -1;\r
-      if(!n3_ok) appData.holdingsSize = -1;\r
-\r
-      shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */\r
-      startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */\r
-      appData.pieceToCharTable = NULL;\r
-      Reset(TRUE, TRUE);\r
-\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    case IDC_Ranks:\r
-    case IDC_Files:\r
-    case IDC_Holdings:\r
-        if( HIWORD(wParam) == EN_CHANGE ) {\r
-\r
-            GetDlgItemInt(hDlg, IDC_Files, &n1_ok, FALSE );\r
-            GetDlgItemInt(hDlg, IDC_Ranks, &n2_ok, FALSE );\r
-            GetDlgItemInt(hDlg, IDC_Holdings, &n3_ok, FALSE );\r
-\r
-            /*EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok ? TRUE : FALSE );*/\r
-        }\r
-        return TRUE;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-\r
-VOID\r
-NewVariantPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc = MakeProcInstance((FARPROC)NewVariantDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_NewVariant), hwnd,\r
-         (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * ICS Options Dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-\r
-BOOL APIENTRY\r
-MyCreateFont(HWND hwnd, MyFont *font)\r
-{\r
-  CHOOSEFONT cf;\r
-  HFONT hf;\r
-\r
-  /* Initialize members of the CHOOSEFONT structure. */\r
-  cf.lStructSize = sizeof(CHOOSEFONT);\r
-  cf.hwndOwner = hwnd;\r
-  cf.hDC = (HDC)NULL;\r
-  cf.lpLogFont = &font->lf;\r
-  cf.iPointSize = 0;\r
-  cf.Flags = CF_SCREENFONTS|/*CF_ANSIONLY|*/CF_INITTOLOGFONTSTRUCT;\r
-  cf.rgbColors = RGB(0,0,0);\r
-  cf.lCustData = 0L;\r
-  cf.lpfnHook = (LPCFHOOKPROC)NULL;\r
-  cf.lpTemplateName = (LPSTR)NULL;\r
-  cf.hInstance = (HINSTANCE) NULL;\r
-  cf.lpszStyle = (LPSTR)NULL;\r
-  cf.nFontType = SCREEN_FONTTYPE;\r
-  cf.nSizeMin = 0;\r
-  cf.nSizeMax = 0;\r
-\r
-  /* Display the CHOOSEFONT common-dialog box. */\r
-  if (!ChooseFont(&cf)) {\r
-    return FALSE;\r
-  }\r
-\r
-  /* Create a logical font based on the user's   */\r
-  /* selection and return a handle identifying   */\r
-  /* that font. */\r
-  hf = CreateFontIndirect(cf.lpLogFont);\r
-  if (hf == NULL) {\r
-    return FALSE;\r
-  }\r
-\r
-  font->hf = hf;\r
-  font->mfp.pointSize = (float) (cf.iPointSize / 10.0);\r
-  font->mfp.bold = (font->lf.lfWeight >= FW_BOLD);\r
-  font->mfp.italic = font->lf.lfItalic;\r
-  font->mfp.underline = font->lf.lfUnderline;\r
-  font->mfp.strikeout = font->lf.lfStrikeOut;\r
-  strcpy(font->mfp.faceName, font->lf.lfFaceName);\r
-  return TRUE;\r
-}\r
-\r
-\r
-VOID\r
-UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca)\r
-{\r
-  CHARFORMAT cf;\r
-  cf.cbSize = sizeof(CHARFORMAT);\r
-  cf.dwMask = \r
-    CFM_COLOR|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE;\r
-  cf.crTextColor = mca->color;\r
-  cf.dwEffects = mca->effects;\r
-  strcpy(cf.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName);\r
-  /* \r
-   * The 20.0 below is in fact documented. yHeight is expressed in twips.\r
-   * A twip is 1/20 of a font's point size. See documentation of CHARFORMAT.\r
-   * --msw\r
-   */\r
-  cf.yHeight = (int)(font[boardSize][CONSOLE_FONT]->mfp.pointSize * 20.0 + 0.5);\r
-  cf.bCharSet = DEFAULT_CHARSET; /* should be ignored anyway */\r
-  cf.bPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;\r
-  SendDlgItemMessage(hDlg, id, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
-}\r
-\r
-LRESULT CALLBACK\r
-ColorizeTextDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  static MyColorizeAttribs mca;\r
-  static ColorClass cc;\r
-  COLORREF background = (COLORREF)0;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG:\r
-    cc = (ColorClass)lParam;\r
-    mca = colorizeAttribs[cc];\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-    /* Initialize the dialog items */\r
-    CheckDlgButton(hDlg, OPT_Bold, (mca.effects & CFE_BOLD) != 0);\r
-    CheckDlgButton(hDlg, OPT_Italic, (mca.effects & CFE_ITALIC) != 0);\r
-    CheckDlgButton(hDlg, OPT_Underline, (mca.effects & CFE_UNDERLINE) != 0);\r
-    CheckDlgButton(hDlg, OPT_Strikeout, (mca.effects & CFE_STRIKEOUT) != 0);\r
-\r
-    /* get the current background color from the parent window */\r
-    SendMessage(GetWindow(hDlg, GW_OWNER),WM_COMMAND, \r
-               (WPARAM)WM_USER_GetConsoleBackground, \r
-               (LPARAM)&background);\r
-\r
-    /* set the background color */\r
-    SendDlgItemMessage(hDlg, OPT_Sample, EM_SETBKGNDCOLOR, FALSE, background);\r
-\r
-    SetDlgItemText(hDlg, OPT_Sample, mca.name);\r
-    UpdateSampleText(hDlg, OPT_Sample, &mca);\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* Read changed options from the dialog box */\r
-      colorizeAttribs[cc] = mca;\r
-      textAttribs[cc].color = mca.color;\r
-      textAttribs[cc].effects = mca.effects;\r
-      Colorize(currentColorClass, TRUE);\r
-      if (cc == ColorNormal) {\r
-       CHARFORMAT cf;\r
-       cf.cbSize = sizeof(CHARFORMAT);\r
-       cf.dwMask = CFM_COLOR;\r
-       cf.crTextColor = mca.color;\r
-       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
-         EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
-      }\r
-      EndDialog(hDlg, TRUE);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    case OPT_ChooseColor:\r
-      ChangeColor(hDlg, &mca.color);\r
-      UpdateSampleText(hDlg, OPT_Sample, &mca);\r
-      return TRUE;\r
-\r
-    default:\r
-      mca.effects =\r
-       (IsDlgButtonChecked(hDlg, OPT_Bold) ? CFE_BOLD : 0) |\r
-       (IsDlgButtonChecked(hDlg, OPT_Italic) ? CFE_ITALIC : 0) |\r
-       (IsDlgButtonChecked(hDlg, OPT_Underline) ? CFE_UNDERLINE : 0) |\r
-       (IsDlgButtonChecked(hDlg, OPT_Strikeout) ? CFE_STRIKEOUT : 0);\r
-      UpdateSampleText(hDlg, OPT_Sample, &mca);\r
-      break;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID\r
-ColorizeTextPopup(HWND hwnd, ColorClass cc)\r
-{\r
-  FARPROC lpProc;\r
-\r
-  lpProc = MakeProcInstance((FARPROC)ColorizeTextDialog, hInst);\r
-  DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_Colorize),\r
-    hwnd, (DLGPROC)lpProc, (LPARAM) cc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-VOID\r
-SetIcsOptionEnables(HWND hDlg)\r
-{\r
-#define ENABLE_DLG_ITEM(x,y) EnableWindow(GetDlgItem(hDlg,(x)), (y))\r
-\r
-  UINT state = IsDlgButtonChecked(hDlg, OPT_Premove);\r
-  ENABLE_DLG_ITEM(OPT_PremoveWhite, state);\r
-  ENABLE_DLG_ITEM(OPT_PremoveWhiteText, state);\r
-  ENABLE_DLG_ITEM(OPT_PremoveBlack, state);\r
-  ENABLE_DLG_ITEM(OPT_PremoveBlackText, state);\r
-\r
-  ENABLE_DLG_ITEM(OPT_IcsAlarmTime, IsDlgButtonChecked(hDlg, OPT_IcsAlarm));\r
-\r
-#undef ENABLE_DLG_ITEM\r
-}\r
-\r
-\r
-LRESULT CALLBACK\r
-IcsOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  char buf[MSG_SIZ];\r
-  int number;\r
-  int i;\r
-  static COLORREF cbc;\r
-  static MyColorizeAttribs *mca;\r
-  COLORREF *colorref;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-\r
-    mca = colorizeAttribs;\r
-\r
-    for (i=0; i < NColorClasses - 1; i++) {\r
-      mca[i].color   = textAttribs[i].color;\r
-      mca[i].effects = textAttribs[i].effects;\r
-    }\r
-    cbc = consoleBackgroundColor;\r
-\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-\r
-    /* Initialize the dialog items */\r
-#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
-\r
-    CHECK_BOX(OPT_AutoComment, appData.autoComment);\r
-    CHECK_BOX(OPT_AutoObserve, appData.autoObserve);\r
-    CHECK_BOX(OPT_GetMoveList, appData.getMoveList);\r
-    CHECK_BOX(OPT_LocalLineEditing, appData.localLineEditing);\r
-    CHECK_BOX(OPT_QuietPlay, appData.quietPlay);\r
-    CHECK_BOX(OPT_Premove, appData.premove);\r
-    CHECK_BOX(OPT_PremoveWhite, appData.premoveWhite);\r
-    CHECK_BOX(OPT_PremoveBlack, appData.premoveBlack);\r
-    CHECK_BOX(OPT_IcsAlarm, appData.icsAlarm);\r
-    CHECK_BOX(OPT_DontColorize, !appData.colorize);\r
-\r
-#undef CHECK_BOX\r
-\r
-    sprintf(buf, "%d", appData.icsAlarmTime / 1000);\r
-    SetDlgItemText(hDlg, OPT_IcsAlarmTime, buf);\r
-    SetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText);\r
-    SetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText);\r
-\r
-    SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
-    SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
-    SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
-    SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
-    SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
-    SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
-    SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
-    SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
-    SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
-    SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
-\r
-    SetDlgItemText(hDlg, OPT_SampleShout,     mca[ColorShout].name);\r
-    SetDlgItemText(hDlg, OPT_SampleSShout,    mca[ColorSShout].name);\r
-    SetDlgItemText(hDlg, OPT_SampleChannel1,  mca[ColorChannel1].name);\r
-    SetDlgItemText(hDlg, OPT_SampleChannel,   mca[ColorChannel].name);\r
-    SetDlgItemText(hDlg, OPT_SampleKibitz,    mca[ColorKibitz].name);\r
-    SetDlgItemText(hDlg, OPT_SampleTell,      mca[ColorTell].name);\r
-    SetDlgItemText(hDlg, OPT_SampleChallenge, mca[ColorChallenge].name);\r
-    SetDlgItemText(hDlg, OPT_SampleRequest,   mca[ColorRequest].name);\r
-    SetDlgItemText(hDlg, OPT_SampleSeek,      mca[ColorSeek].name);\r
-    SetDlgItemText(hDlg, OPT_SampleNormal,    mca[ColorNormal].name);\r
-\r
-    UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
-    UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
-    UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
-    UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
-    UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
-    UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
-    UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
-    UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
-    UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
-    UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
-\r
-    SetIcsOptionEnables(hDlg);\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-\r
-    case WM_USER_GetConsoleBackground: \r
-      /* the ColorizeTextDialog needs the current background color */\r
-      colorref = (COLORREF *)lParam;\r
-      *colorref = cbc;\r
-      return FALSE;\r
-\r
-    case IDOK:\r
-      /* Read changed options from the dialog box */\r
-      GetDlgItemText(hDlg, OPT_IcsAlarmTime, buf, MSG_SIZ);\r
-      if (sscanf(buf, "%d", &number) != 1 || (number < 0)){\r
-         MessageBox(hDlg, "Invalid ICS Alarm Time",\r
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-         return FALSE;\r
-      }\r
-\r
-#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
-\r
-      appData.icsAlarm         = IS_CHECKED(OPT_IcsAlarm);\r
-      appData.premove          = IS_CHECKED(OPT_Premove);\r
-      appData.premoveWhite     = IS_CHECKED(OPT_PremoveWhite);\r
-      appData.premoveBlack     = IS_CHECKED(OPT_PremoveBlack);\r
-      appData.autoComment      = IS_CHECKED(OPT_AutoComment);\r
-      appData.autoObserve      = IS_CHECKED(OPT_AutoObserve);\r
-      appData.getMoveList      = IS_CHECKED(OPT_GetMoveList);\r
-      appData.localLineEditing = IS_CHECKED(OPT_LocalLineEditing);\r
-      appData.quietPlay        = IS_CHECKED(OPT_QuietPlay);\r
-\r
-#undef IS_CHECKED\r
-\r
-      appData.icsAlarmTime = number * 1000;\r
-      GetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText, 5);\r
-      GetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText, 5);\r
-\r
-      if (appData.localLineEditing) {\r
-       DontEcho();\r
-       EchoOn();\r
-      } else {\r
-       DoEcho();\r
-       EchoOff();\r
-      }\r
-\r
-      appData.colorize =\r
-       (Boolean)!IsDlgButtonChecked(hDlg, OPT_DontColorize);\r
-\r
-      if (!appData.colorize) {\r
-       CHARFORMAT cf;\r
-       COLORREF background = ParseColorName(COLOR_BKGD);\r
-       /*\r
-       SetDefaultTextAttribs();\r
-        Colorize(currentColorClass);\r
-       */\r
-       cf.cbSize = sizeof(CHARFORMAT);\r
-       cf.dwMask = CFM_COLOR;\r
-       cf.crTextColor = ParseColorName(COLOR_NORMAL);\r
-\r
-       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
-         EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
-        SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
-         EM_SETBKGNDCOLOR, FALSE, background);\r
-       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
-         EM_SETBKGNDCOLOR, FALSE, background);\r
-      }\r
-\r
-      if (cbc != consoleBackgroundColor) {\r
-       consoleBackgroundColor = cbc;\r
-       if (appData.colorize) {\r
-         SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
-           EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
-         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
-           EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
-       }\r
-      }\r
-\r
-      for (i=0; i < NColorClasses - 1; i++) {\r
-       textAttribs[i].color   = mca[i].color;\r
-       textAttribs[i].effects = mca[i].effects;\r
-      }\r
-\r
-      EndDialog(hDlg, TRUE);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    case OPT_ChooseShoutColor:\r
-      ColorizeTextPopup(hDlg, ColorShout);\r
-      UpdateSampleText(hDlg, OPT_SampleShout, &mca[ColorShout]);\r
-      break;\r
-\r
-    case OPT_ChooseSShoutColor:\r
-      ColorizeTextPopup(hDlg, ColorSShout);\r
-      UpdateSampleText(hDlg, OPT_SampleSShout, &mca[ColorSShout]);\r
-      break;\r
-\r
-    case OPT_ChooseChannel1Color:\r
-      ColorizeTextPopup(hDlg, ColorChannel1);\r
-      UpdateSampleText(hDlg, OPT_SampleChannel1, \r
-                      &colorizeAttribs[ColorChannel1]);\r
-      break;\r
-\r
-    case OPT_ChooseChannelColor:\r
-      ColorizeTextPopup(hDlg, ColorChannel);\r
-      UpdateSampleText(hDlg, OPT_SampleChannel, &mca[ColorChannel]);\r
-      break;\r
-\r
-    case OPT_ChooseKibitzColor:\r
-      ColorizeTextPopup(hDlg, ColorKibitz);\r
-      UpdateSampleText(hDlg, OPT_SampleKibitz, &mca[ColorKibitz]);\r
-      break;\r
-\r
-    case OPT_ChooseTellColor:\r
-      ColorizeTextPopup(hDlg, ColorTell);\r
-      UpdateSampleText(hDlg, OPT_SampleTell, &mca[ColorTell]);\r
-      break;\r
-\r
-    case OPT_ChooseChallengeColor:\r
-      ColorizeTextPopup(hDlg, ColorChallenge);\r
-      UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
-      break;\r
-\r
-    case OPT_ChooseRequestColor:\r
-      ColorizeTextPopup(hDlg, ColorRequest);\r
-      UpdateSampleText(hDlg, OPT_SampleRequest, &mca[ColorRequest]);\r
-      break;\r
-\r
-    case OPT_ChooseSeekColor:\r
-      ColorizeTextPopup(hDlg, ColorSeek);\r
-      UpdateSampleText(hDlg, OPT_SampleSeek, &mca[ColorSeek]);\r
-      break;\r
-\r
-    case OPT_ChooseNormalColor:\r
-      ColorizeTextPopup(hDlg, ColorNormal);\r
-      UpdateSampleText(hDlg, OPT_SampleNormal, &mca[ColorNormal]);\r
-      break;\r
-\r
-    case OPT_ChooseBackgroundColor:\r
-      if (ChangeColor(hDlg, &cbc)) {\r
-       SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
-       SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
-       SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
-       SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
-       SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
-       SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
-       SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
-       SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
-       SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
-       SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
-      }\r
-      break;\r
-\r
-    case OPT_DefaultColors:\r
-      for (i=0; i < NColorClasses - 1; i++)\r
-       ParseAttribs(&mca[i].color, \r
-                    &mca[i].effects,\r
-                    defaultTextAttribs[i]);\r
-\r
-      cbc = ParseColorName(COLOR_BKGD);\r
-      SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
-      SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
-      SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
-      SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
-      SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
-      SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
-      SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
-      SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
-      SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
-      SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
-\r
-      UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
-      UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
-      UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
-      UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
-      UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
-      UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
-      UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
-      UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
-      UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
-      UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
-      break;\r
-\r
-    default:\r
-      SetIcsOptionEnables(hDlg);\r
-      break;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID\r
-IcsOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc = MakeProcInstance((FARPROC)IcsOptionsDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_IcsOptions), hwnd,\r
-           (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * Fonts Dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-\r
-VOID\r
-SetSampleFontText(HWND hwnd, int id, const MyFont *mf)\r
-{\r
-  char buf[MSG_SIZ];\r
-  HWND hControl;\r
-  HDC hdc;\r
-  CHARFORMAT cf;\r
-  SIZE size;\r
-  RECT rectClient, rectFormat;\r
-  HFONT oldFont;\r
-  POINT center;\r
-  int len;\r
-\r
-  len = sprintf(buf, "%.0f pt. %s%s%s\n",\r
-               mf->mfp.pointSize, mf->mfp.faceName,\r
-               mf->mfp.bold ? " bold" : "",\r
-               mf->mfp.italic ? " italic" : "");\r
-  SetDlgItemText(hwnd, id, buf);\r
-\r
-  hControl = GetDlgItem(hwnd, id);\r
-  hdc = GetDC(hControl);\r
-  SetMapMode(hdc, MM_TEXT);    /* 1 pixel == 1 logical unit */\r
-  oldFont = SelectObject(hdc, mf->hf);\r
-  \r
-  /* get number of logical units necessary to display font name */\r
-  GetTextExtentPoint32(hdc, buf, len, &size);\r
-\r
-  /* calculate formatting rectangle in the rich edit control.  \r
-   * May be larger or smaller than the actual control.\r
-   */\r
-  GetClientRect(hControl, &rectClient);\r
-  center.x = (rectClient.left + rectClient.right) / 2;\r
-  center.y = (rectClient.top  + rectClient.bottom) / 2;\r
-  rectFormat.top    = center.y - (size.cy / 2) - 1;\r
-  rectFormat.bottom = center.y + (size.cy / 2) + 1;\r
-  rectFormat.left   = center.x - (size.cx / 2) - 1;\r
-  rectFormat.right  = center.x + (size.cx / 2) + 1;\r
-\r
-#if 0\r
-  fprintf(debugFP, "\nfont: %s\n"\r
-                   "center.x   %d, centerY %d\n"\r
-                  "size.cx    %d, size.cy %d\n"\r
-                  "client.top %d, bottom %d, left %d, right %d\n"\r
-                  "format.top %d, bottom %d, left %d, right %d\n",\r
-                  buf,\r
-                  center.x, center.y,\r
-                  size.cx, size.cy,\r
-                  rectClient.top, rectClient.bottom, rectClient.left,\r
-                  rectClient.right,\r
-                  rectFormat.top, rectFormat.bottom, rectFormat.left,\r
-                  rectFormat.right);\r
-#endif\r
-\r
-  cf.cbSize = sizeof(CHARFORMAT);\r
-  cf.dwMask = CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_BOLD|CFM_ITALIC;\r
-  cf.dwEffects = 0;\r
-  if (mf->lf.lfWeight == FW_BOLD) cf.dwEffects |= CFE_BOLD;\r
-  if (mf->lf.lfItalic) cf.dwEffects |= CFE_ITALIC;\r
-  strcpy(cf.szFaceName, mf->mfp.faceName);\r
-  /*\r
-   * yHeight is expressed in twips.  A twip is 1/20 of a font's point\r
-   * size. See documentation of CHARFORMAT.  --msw\r
-   */\r
-  cf.yHeight = (int)(mf->mfp.pointSize * 20.0 + 0.5);\r
-  cf.bCharSet = mf->lf.lfCharSet;\r
-  cf.bPitchAndFamily = mf->lf.lfPitchAndFamily;\r
-\r
-  /* format the text in the rich edit control */\r
-  SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf);\r
-  SendMessage(hControl, EM_SETRECT, (WPARAM)0, (LPARAM) &rectFormat);\r
-\r
-  /* clean up */\r
-  SelectObject(hdc, oldFont);\r
-  ReleaseDC(hControl, hdc);\r
-}\r
-\r
-VOID\r
-CopyFont(MyFont *dest, const MyFont *src)\r
-{\r
-  dest->mfp.pointSize = src->mfp.pointSize;\r
-  dest->mfp.bold      = src->mfp.bold;\r
-  dest->mfp.italic    = src->mfp.italic;\r
-  dest->mfp.underline = src->mfp.underline;\r
-  dest->mfp.strikeout = src->mfp.strikeout;\r
-  lstrcpy(dest->mfp.faceName, src->mfp.faceName);\r
-  CreateFontInMF(dest);\r
-}\r
-\r
-\r
-LRESULT CALLBACK\r
-FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  static MyFont workFont[NUM_FONTS];\r
-  static BOOL firstPaint;\r
-  int i;\r
-  RECT rect;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG:\r
-\r
-    /* copy the current font settings into a working copy */\r
-    for (i=0; i < NUM_FONTS; i++)\r
-      CopyFont(&workFont[i], font[boardSize][i]);\r
-\r
-    if (!appData.icsActive)\r
-      EnableWindow(GetDlgItem(hDlg, OPT_ChooseConsoleFont), FALSE);\r
-\r
-    firstPaint = TRUE; /* see rant below */\r
-\r
-    /* If I don't call SetFocus(), the dialog won't respond to the keyboard\r
-     * when first drawn. Why is this the only dialog that behaves this way? Is\r
-     * is the WM_PAINT stuff below?? Sigh...\r
-     */\r
-    SetFocus(GetDlgItem(hDlg, IDOK));\r
-    break;\r
-\r
-  case WM_PAINT:\r
-    /* This should not be necessary. However, if SetSampleFontText() is called\r
-     * in response to WM_INITDIALOG, the strings are not properly centered in\r
-     * the controls when the dialog first appears. I can't figure out why, so\r
-     * this is the workaround.  --msw\r
-     */\r
-    if (firstPaint) {\r
-      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
-      firstPaint = FALSE;\r
-    }\r
-    break;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-\r
-    case IDOK:\r
-      /* again, it seems to avoid redraw problems if we call EndDialog first */\r
-      EndDialog(hDlg, FALSE);\r
-\r
-      /* copy modified settings back to the fonts array */\r
-      for (i=0; i < NUM_FONTS; i++)\r
-       CopyFont(font[boardSize][i], &workFont[i]);\r
-\r
-      /* a sad necessity due to the original design of having a separate\r
-       * console font, tags font, and comment font for each board size.  IMHO\r
-       * these fonts should not be dependent on the current board size.  I'm\r
-       * running out of time, so I am doing this hack rather than redesign the\r
-       * data structure. Besides, I think if I redesigned the data structure, I\r
-       * might break backwards compatibility with old winboard.ini files.\r
-       * --msw\r
-       */\r
-      for (i=0; i < NUM_SIZES; i++) {\r
-       CopyFont(font[i][EDITTAGS_FONT], &workFont[EDITTAGS_FONT]);\r
-       CopyFont(font[i][CONSOLE_FONT],  &workFont[CONSOLE_FONT]);\r
-       CopyFont(font[i][COMMENT_FONT],  &workFont[COMMENT_FONT]);\r
-       CopyFont(font[i][MOVEHISTORY_FONT],  &workFont[MOVEHISTORY_FONT]);\r
-      }\r
-      /* end sad necessity */\r
-\r
-      InitDrawingSizes(boardSize, 0);\r
-      InvalidateRect(hwndMain, NULL, TRUE);\r
-\r
-      if (commentDialog) {\r
-       SendDlgItemMessage(commentDialog, OPT_CommentText,\r
-         WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf, \r
-         MAKELPARAM(TRUE, 0));\r
-       GetClientRect(GetDlgItem(commentDialog, OPT_CommentText), &rect);\r
-       InvalidateRect(commentDialog, &rect, TRUE);\r
-      }\r
-\r
-      if (editTagsDialog) {\r
-       SendDlgItemMessage(editTagsDialog, OPT_TagsText,\r
-         WM_SETFONT, (WPARAM)font[boardSize][EDITTAGS_FONT]->hf, \r
-         MAKELPARAM(TRUE, 0));\r
-       GetClientRect(GetDlgItem(editTagsDialog, OPT_TagsText), &rect);\r
-       InvalidateRect(editTagsDialog, &rect, TRUE);\r
-      }\r
-\r
-      if( moveHistoryDialog != NULL ) {\r
-       SendDlgItemMessage(moveHistoryDialog, IDC_MoveHistory,\r
-         WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
-         MAKELPARAM(TRUE, 0));\r
-       InvalidateRect(editTagsDialog, NULL, TRUE);\r
-      }\r
-\r
-      if (hwndConsole) {\r
-       ChangedConsoleFont();\r
-      }\r
-\r
-      for (i=0; i<NUM_FONTS; i++)\r
-       DeleteObject(&workFont[i].hf);\r
-\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      for (i=0; i<NUM_FONTS; i++)\r
-       DeleteObject(&workFont[i].hf);\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    case OPT_ChooseClockFont:\r
-      MyCreateFont(hDlg, &workFont[CLOCK_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
-      break;\r
-\r
-    case OPT_ChooseMessageFont:\r
-      MyCreateFont(hDlg, &workFont[MESSAGE_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
-      break;\r
-\r
-    case OPT_ChooseCoordFont:\r
-      MyCreateFont(hDlg, &workFont[COORD_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
-      break;\r
-\r
-    case OPT_ChooseTagFont:\r
-      MyCreateFont(hDlg, &workFont[EDITTAGS_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
-      break;\r
-\r
-    case OPT_ChooseCommentsFont:\r
-      MyCreateFont(hDlg, &workFont[COMMENT_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
-      break;\r
-\r
-    case OPT_ChooseConsoleFont:\r
-      MyCreateFont(hDlg, &workFont[CONSOLE_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
-      break;\r
-\r
-    case OPT_ChooseMoveHistoryFont:\r
-      MyCreateFont(hDlg, &workFont[MOVEHISTORY_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
-      break;\r
-\r
-    case OPT_DefaultFonts:\r
-      for (i=0; i<NUM_FONTS; i++) {\r
-       DeleteObject(&workFont[i].hf);\r
-       ParseFontName(font[boardSize][i]->def, &workFont[i].mfp);\r
-       CreateFontInMF(&workFont[i]);\r
-      }\r
-      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
-      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
-      break;\r
-    }\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID\r
-FontsOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc = MakeProcInstance((FARPROC)FontOptionsDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_Fonts), hwnd,\r
-         (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * Sounds Dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-\r
-\r
-SoundComboData soundComboData[] = {\r
-  {"Move", NULL},\r
-  {"Bell", NULL},\r
-  {"ICS Alarm", NULL},\r
-  {"ICS Win", NULL},\r
-  {"ICS Loss", NULL},\r
-  {"ICS Draw", NULL},\r
-  {"ICS Unfinished", NULL},\r
-  {"Shout", NULL},\r
-  {"SShout/CShout", NULL},\r
-  {"Channel 1", NULL},\r
-  {"Channel", NULL},\r
-  {"Kibitz", NULL},\r
-  {"Tell", NULL},\r
-  {"Challenge", NULL},\r
-  {"Request", NULL},\r
-  {"Seek", NULL},\r
-  {NULL, NULL},\r
-};\r
-\r
-\r
-void\r
-InitSoundComboData(SoundComboData *scd)\r
-{\r
-  SoundClass sc;\r
-  ColorClass cc;\r
-  int index;\r
-\r
-  /* copy current sound settings to combo array */\r
-\r
-  for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
-    scd[sc].name = strdup(sounds[sc].name);\r
-  }\r
-  for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
-    index = (int)cc + (int)NSoundClasses;\r
-    scd[index].name = strdup(textAttribs[cc].sound.name);\r
-  }\r
-}\r
-\r
-\r
-void\r
-ResetSoundComboData(SoundComboData *scd)\r
-{\r
-  while (scd->label) {\r
-    if (scd->name != NULL) {\r
-      free (scd->name);\r
-      scd->name = NULL;\r
-    }\r
-    scd++;\r
-  }\r
-}\r
-\r
-void\r
-InitSoundCombo(HWND hwndCombo, SoundComboData *scd)\r
-{\r
-  char buf[255];\r
-  DWORD err;\r
-  DWORD cnt = 0;\r
-  SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
-\r
-  /* send the labels to the combo box */\r
-  while (scd->label) {\r
-    err = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) scd->label);\r
-    if (err != cnt++) {\r
-      sprintf(buf, "InitSoundCombo(): err '%d', cnt '%d'\n",\r
-         err, cnt);\r
-      MessageBox(NULL, buf, NULL, MB_OK);\r
-    }\r
-    scd++;\r
-  }\r
-  SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
-}\r
-\r
-int\r
-SoundDialogWhichRadio(HWND hDlg)\r
-{\r
-  if (IsDlgButtonChecked(hDlg, OPT_NoSound)) return OPT_NoSound;\r
-  if (IsDlgButtonChecked(hDlg, OPT_DefaultBeep)) return OPT_DefaultBeep;\r
-  if (IsDlgButtonChecked(hDlg, OPT_BuiltInSound)) return OPT_BuiltInSound;\r
-  if (IsDlgButtonChecked(hDlg, OPT_WavFile)) return OPT_WavFile;\r
-  return -1;\r
-}\r
-\r
-VOID\r
-SoundDialogSetEnables(HWND hDlg, int radio)\r
-{\r
-  EnableWindow(GetDlgItem(hDlg, OPT_BuiltInSoundName),\r
-              radio == OPT_BuiltInSound);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_WavFileName), radio == OPT_WavFile);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_BrowseSound), radio == OPT_WavFile);\r
-}\r
-\r
-char *\r
-SoundDialogGetName(HWND hDlg, int radio)\r
-{\r
-  static char buf[MSG_SIZ], buf2[MSG_SIZ], buf3[MSG_SIZ];\r
-  char *dummy, *ret;\r
-  switch (radio) {\r
-  case OPT_NoSound:\r
-  default:\r
-    return "";\r
-  case OPT_DefaultBeep:\r
-    return "$";\r
-  case OPT_BuiltInSound:\r
-    buf[0] = '!';\r
-    GetDlgItemText(hDlg, OPT_BuiltInSoundName, buf + 1, sizeof(buf) - 1);\r
-    return buf;\r
-  case OPT_WavFile:\r
-    GetDlgItemText(hDlg, OPT_WavFileName, buf, sizeof(buf));\r
-    GetCurrentDirectory(MSG_SIZ, buf3);\r
-    SetCurrentDirectory(installDir);\r
-    if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
-      ret = buf2;\r
-    } else {\r
-      ret = buf;\r
-    }\r
-    SetCurrentDirectory(buf3);\r
-    return ret;\r
-  }\r
-}\r
-\r
-void\r
-DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name)\r
-{\r
-  int radio;\r
-  /* \r
-   * I think it's best to clear the combo and edit boxes. It looks stupid\r
-   * to have a value from another sound event sitting there grayed out.\r
-   */\r
-  SetDlgItemText(hDlg, OPT_WavFileName, "");\r
-  SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
-\r
-  if (appData.debugMode)\r
-      fprintf(debugFP, "DisplaySelectedSound(,,'%s'):\n", name);\r
-  switch (name[0]) {\r
-  case NULLCHAR:\r
-    radio = OPT_NoSound;\r
-    break;\r
-  case '$':\r
-    if (name[1] == NULLCHAR) {\r
-      radio = OPT_DefaultBeep;\r
-    } else {\r
-      radio = OPT_WavFile;\r
-      SetDlgItemText(hDlg, OPT_WavFileName, name);\r
-    }\r
-    break;\r
-  case '!':\r
-    if (name[1] == NULLCHAR) {\r
-      radio = OPT_NoSound;\r
-    } else {\r
-      radio = OPT_BuiltInSound;\r
-      if (SendMessage(hCombo, CB_SELECTSTRING, (WPARAM) -1, \r
-                     (LPARAM) (name + 1)) == CB_ERR) {\r
-       SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
-       SendMessage(hCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) (name + 1));\r
-      }\r
-    }\r
-    break;\r
-  default:\r
-    radio = OPT_WavFile;\r
-    SetDlgItemText(hDlg, OPT_WavFileName, name);\r
-    break;\r
-  }\r
-  SoundDialogSetEnables(hDlg, radio);\r
-  CheckRadioButton(hDlg, OPT_NoSound, OPT_WavFile, radio);\r
-}\r
-    \r
-\r
-char *builtInSoundNames[] = BUILT_IN_SOUND_NAMES;\r
-\r
-LRESULT CALLBACK\r
-SoundOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  static HWND hSoundCombo;\r
-  static DWORD index;\r
-  static HWND hBISN;\r
-  int radio;\r
-  MySound tmp;\r
-  FILE *f;\r
-  char buf[MSG_SIZ];\r
-  char *newName;\r
-  SoundClass sc;\r
-  ColorClass cc;\r
-  SoundComboData *scd;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG:\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-\r
-    /* Initialize the built-in sounds combo */\r
-    hBISN = GetDlgItem(hDlg, OPT_BuiltInSoundName);\r
-     InitComboStrings(hBISN, builtInSoundNames);\r
-\r
-    /* Initialize the  sound events combo */\r
-    index = 0;\r
-    InitSoundComboData(soundComboData);\r
-    hSoundCombo = GetDlgItem(hDlg, CBO_Sounds);\r
-    InitSoundCombo(hSoundCombo, soundComboData);\r
-\r
-    /* update the dialog */\r
-    DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-\r
-    if (((HWND)lParam == hSoundCombo) && \r
-       (HIWORD(wParam) == CBN_SELCHANGE)) {\r
-      /* \r
-       * the user has selected a new sound event. We must store the name for\r
-       * the previously selected event, then retrieve the name for the\r
-       * newly selected event and update the dialog. \r
-       */\r
-      radio = SoundDialogWhichRadio(hDlg);\r
-      newName = strdup(SoundDialogGetName(hDlg, radio));\r
-      \r
-      if (strcmp(newName, soundComboData[index].name) != 0) {\r
-       free(soundComboData[index].name);\r
-       soundComboData[index].name = newName;\r
-      } else {\r
-       free(newName);\r
-       newName = NULL;\r
-      }\r
-      /* now get the settings for the newly selected event */\r
-      index = SendMessage(hSoundCombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);\r
-      DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
-      \r
-      return TRUE;\r
-    }\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* \r
-       * save the name for the currently selected sound event \r
-       */\r
-      radio = SoundDialogWhichRadio(hDlg);\r
-      newName = strdup(SoundDialogGetName(hDlg, radio));\r
-\r
-      if (strcmp(soundComboData[index].name, newName) != 0) {\r
-       free(soundComboData[index].name);\r
-       soundComboData[index].name = newName;\r
-      } else {\r
-       free(newName);\r
-       newName = NULL;\r
-      }\r
-\r
-      /* save all the sound names that changed and load the sounds */\r
-\r
-      for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
-       if (strcmp(soundComboData[sc].name, sounds[sc].name) != 0) {\r
-         free(sounds[sc].name);\r
-         sounds[sc].name = strdup(soundComboData[sc].name);\r
-         MyLoadSound(&sounds[sc]);\r
-       }\r
-      }\r
-      for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
-       index = (int)cc + (int)NSoundClasses;\r
-       if (strcmp(soundComboData[index].name, \r
-                  textAttribs[cc].sound.name) != 0) {\r
-         free(textAttribs[cc].sound.name);\r
-         textAttribs[cc].sound.name = strdup(soundComboData[index].name);\r
-         MyLoadSound(&textAttribs[cc].sound);\r
-       }\r
-      }\r
-\r
-      ResetSoundComboData(soundComboData);\r
-      EndDialog(hDlg, TRUE);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      ResetSoundComboData(soundComboData);\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    case OPT_DefaultSounds:\r
-      /* can't use SetDefaultSounds() because we need to be able to "undo" if\r
-       * user selects "Cancel" later on. So we do it the hard way here.\r
-       */\r
-      scd = &soundComboData[0];\r
-      while (scd->label != NULL) {\r
-       if (scd->name != NULL) free(scd->name);\r
-       scd->name = strdup("");\r
-       scd++;\r
-      }\r
-      free(soundComboData[(int)SoundBell].name);\r
-      soundComboData[(int)SoundBell].name = strdup(SOUND_BELL);\r
-      DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
-      break;\r
-\r
-    case OPT_PlaySound:\r
-      radio = SoundDialogWhichRadio(hDlg);\r
-      tmp.name = strdup(SoundDialogGetName(hDlg, radio));\r
-      tmp.data = NULL;\r
-      MyLoadSound(&tmp);\r
-      MyPlaySound(&tmp);\r
-      if (tmp.data  != NULL) free(tmp.data);\r
-      if (tmp.name != NULL) free(tmp.name);\r
-      return TRUE;\r
-\r
-    case OPT_BrowseSound:\r
-      f = OpenFileDialog(hDlg, "rb", NULL, "wav", SOUND_FILT,\r
-       "Browse for Sound File", NULL, NULL, buf);\r
-      if (f != NULL) {\r
-       fclose(f);\r
-       SetDlgItemText(hDlg, OPT_WavFileName, buf);\r
-      }\r
-      return TRUE;\r
-\r
-    default:\r
-      radio = SoundDialogWhichRadio(hDlg);\r
-      SoundDialogSetEnables(hDlg, radio);\r
-      break;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-\r
-VOID SoundOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc;\r
-\r
-  lpProc = MakeProcInstance((FARPROC)SoundOptionsDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_Sound), hwnd, (DLGPROC)lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * Comm Port dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-\r
-\r
-#define FLOW_NONE   0\r
-#define FLOW_XOFF   1\r
-#define FLOW_CTS    2\r
-#define FLOW_DSR    3\r
-\r
-#define PORT_NONE\r
-\r
-ComboData cdPort[]     = { {"None", PORT_NONE}, {"COM1", 1}, {"COM2", 2},\r
-                          {"COM3", 3}, {"COM4", 4}, {NULL, 0} };\r
-ComboData cdDataRate[] = { {"110", 110}, {"300", 300}, {"600", 600}, {"1200", 1200},\r
-                          {"2400", 2400}, {"4800", 4800}, {"9600", 9600}, {"19200", 19200},\r
-                          {"38400", 38400}, {NULL, 0} };\r
-ComboData cdDataBits[] = { {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {NULL, 0} };\r
-ComboData cdParity[]   = { {"None", NOPARITY}, {"Odd", ODDPARITY}, {"Even", EVENPARITY},\r
-                          {"Mark", MARKPARITY}, {"Space", SPACEPARITY}, {NULL, 0} };\r
-ComboData cdStopBits[] = { {"1", ONESTOPBIT}, {"1.5", ONE5STOPBITS},\r
-                          {"2", TWOSTOPBITS}, {NULL, 0} };\r
-ComboData cdFlow[]     = { {"None", FLOW_NONE}, {"Xoff/Xon", FLOW_XOFF}, {"CTS", FLOW_CTS},\r
-                          {"DSR", FLOW_DSR}, {NULL, 0} };\r
-\r
-\r
-VOID\r
-ParseCommSettings(char *arg, DCB *dcb)\r
-{\r
-  int dataRate, count;\r
-  char bits[MSG_SIZ], parity[MSG_SIZ], stopBits[MSG_SIZ], flow[MSG_SIZ];\r
-  ComboData *cd;\r
-  count = sscanf(arg, "%d%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]",\r
-    &dataRate, bits, parity, stopBits, flow);\r
-  if (count != 5) goto cant_parse;\r
-  dcb->BaudRate = dataRate;\r
-  cd = cdDataBits;\r
-  while (cd->label != NULL) {\r
-    if (StrCaseCmp(cd->label, bits) == 0) {\r
-      dcb->ByteSize = cd->value;\r
-      break;\r
-    }\r
-    cd++;\r
-  }\r
-  if (cd->label == NULL) goto cant_parse;\r
-  cd = cdParity;\r
-  while (cd->label != NULL) {\r
-    if (StrCaseCmp(cd->label, parity) == 0) {\r
-      dcb->Parity = cd->value;\r
-      break;\r
-    }\r
-    cd++;\r
-  }\r
-  if (cd->label == NULL) goto cant_parse;\r
-  cd = cdStopBits;\r
-  while (cd->label != NULL) {\r
-    if (StrCaseCmp(cd->label, stopBits) == 0) {\r
-      dcb->StopBits = cd->value;\r
-      break;\r
-    }\r
-    cd++;\r
-  }\r
-  cd = cdFlow;\r
-  if (cd->label == NULL) goto cant_parse;\r
-  while (cd->label != NULL) {\r
-    if (StrCaseCmp(cd->label, flow) == 0) {\r
-      switch (cd->value) {\r
-      case FLOW_NONE:\r
-       dcb->fOutX = FALSE;\r
-       dcb->fOutxCtsFlow = FALSE;\r
-       dcb->fOutxDsrFlow = FALSE;\r
-       break;\r
-      case FLOW_CTS:\r
-       dcb->fOutX = FALSE;\r
-       dcb->fOutxCtsFlow = TRUE;\r
-       dcb->fOutxDsrFlow = FALSE;\r
-       break;\r
-      case FLOW_DSR:\r
-       dcb->fOutX = FALSE;\r
-       dcb->fOutxCtsFlow = FALSE;\r
-       dcb->fOutxDsrFlow = TRUE;\r
-       break;\r
-      case FLOW_XOFF:\r
-       dcb->fOutX = TRUE;\r
-       dcb->fOutxCtsFlow = FALSE;\r
-       dcb->fOutxDsrFlow = FALSE;\r
-       break;\r
-      }\r
-      break;\r
-    }\r
-    cd++;\r
-  }\r
-  if (cd->label == NULL) goto cant_parse;\r
-  return;\r
-cant_parse:\r
-    ExitArgError("Can't parse com port settings", arg);\r
-}\r
-\r
-\r
-VOID PrintCommSettings(FILE *f, char *name, DCB *dcb)\r
-{\r
-  char *flow = "??", *parity = "??", *stopBits = "??";\r
-  ComboData *cd;\r
-  \r
-  cd = cdParity;\r
-  while (cd->label != NULL) {\r
-    if (dcb->Parity == cd->value) {\r
-      parity = cd->label;\r
-      break;\r
-    }\r
-    cd++;\r
-  }\r
-  cd = cdStopBits;\r
-  while (cd->label != NULL) {\r
-    if (dcb->StopBits == cd->value) {\r
-      stopBits = cd->label;\r
-      break;\r
-    }\r
-    cd++;\r
-  }\r
-  if (dcb->fOutX) {\r
-    flow = cdFlow[FLOW_XOFF].label;\r
-  } else if (dcb->fOutxCtsFlow) {\r
-    flow = cdFlow[FLOW_CTS].label;\r
-  } else if (dcb->fOutxDsrFlow) {\r
-    flow = cdFlow[FLOW_DSR].label;\r
-  } else {\r
-    flow = cdFlow[FLOW_NONE].label;\r
-  }\r
-  fprintf(f, "/%s=%d,%d,%s,%s,%s\n", name,\r
-    dcb->BaudRate, dcb->ByteSize, parity, stopBits, flow);\r
-}\r
-\r
-\r
-void\r
-InitCombo(HANDLE hwndCombo, ComboData *cd)\r
-{\r
-  SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
-\r
-  while (cd->label != NULL) {\r
-    SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) cd->label);\r
-    cd++;\r
-  }\r
-}\r
-\r
-void\r
-SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value)\r
-{\r
-  int i;\r
-\r
-  i = 0;\r
-  while (cd->label != NULL) {\r
-    if (cd->value == value) {\r
-      SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) i, (LPARAM) 0);\r
-      return;\r
-    }\r
-    cd++;\r
-    i++;\r
-  }\r
-}\r
-\r
-LRESULT CALLBACK\r
-CommPortOptionsDialog(HWND hDlg, UINT message, WPARAM wParam,  LPARAM lParam)\r
-{\r
-  char buf[MSG_SIZ];\r
-  HANDLE hwndCombo;\r
-  char *p;\r
-  LRESULT index;\r
-  unsigned value;\r
-  int err;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow(hDlg, GW_OWNER));\r
-    /* Initialize the dialog items */\r
-    /* !! There should probably be some synchronization\r
-       in accessing hCommPort and dcb.  Or does modal nature\r
-       of this dialog box do it for us?\r
-       */\r
-    hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
-    InitCombo(hwndCombo, cdPort);\r
-    p = strrchr(appData.icsCommPort, '\\');\r
-    if (p++ == NULL) p = appData.icsCommPort;\r
-    if ((*p == '\0') ||\r
-       (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) p) == CB_ERR)) {\r
-      SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) "None");\r
-    }\r
-    EnableWindow(hwndCombo, hCommPort == NULL); /*!! don't allow change for now*/\r
-\r
-    hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
-    InitCombo(hwndCombo, cdDataRate);\r
-    sprintf(buf, "%u", dcb.BaudRate);\r
-    if (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) buf) == CB_ERR) {\r
-      SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
-      SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);\r
-    }\r
-\r
-    hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
-    InitCombo(hwndCombo, cdDataBits);\r
-    SelectComboValue(hwndCombo, cdDataBits, dcb.ByteSize);\r
-\r
-    hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
-    InitCombo(hwndCombo, cdParity);\r
-    SelectComboValue(hwndCombo, cdParity, dcb.Parity);\r
-\r
-    hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
-    InitCombo(hwndCombo, cdStopBits);\r
-    SelectComboValue(hwndCombo, cdStopBits, dcb.StopBits);\r
-\r
-    hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
-    InitCombo(hwndCombo, cdFlow);\r
-    if (dcb.fOutX) {\r
-      SelectComboValue(hwndCombo, cdFlow, FLOW_XOFF);\r
-    } else if (dcb.fOutxCtsFlow) {\r
-      SelectComboValue(hwndCombo, cdFlow, FLOW_CTS);\r
-    } else if (dcb.fOutxDsrFlow) {\r
-      SelectComboValue(hwndCombo, cdFlow, FLOW_DSR);\r
-    } else {\r
-      SelectComboValue(hwndCombo, cdFlow, FLOW_NONE);\r
-    }\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* Read changed options from the dialog box */\r
-#ifdef NOTDEF\r
-      /* !! Currently we can't change comm ports in midstream */\r
-      hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
-      if (index == PORT_NONE) {\r
-       appData.icsCommPort = "";\r
-       if (hCommPort != NULL) {\r
-         CloseHandle(hCommPort);\r
-         hCommPort = NULL;\r
-       }\r
-       EndDialog(hDlg, TRUE);\r
-       return TRUE;\r
-      }\r
-      SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
-      appData.icsCommPort = strdup(buf);\r
-      if (hCommPort != NULL) {\r
-       CloseHandle(hCommPort);\r
-       hCommPort = NULL;\r
-      }\r
-      /* now what?? can't really do this; have to fix up the ChildProc\r
-        and InputSource records for the comm port that we gave to the\r
-        back end. */\r
-#endif /*NOTDEF*/\r
-\r
-      hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
-      SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
-      if (sscanf(buf, "%u", &value) != 1) {\r
-       MessageBox(hDlg, "Invalid data rate",\r
-                  "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-       return TRUE;\r
-      }\r
-      dcb.BaudRate = value;\r
-\r
-      hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
-      dcb.ByteSize = cdDataBits[index].value;\r
-\r
-      hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
-      dcb.Parity = cdParity[index].value;\r
-\r
-      hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
-      dcb.StopBits = cdStopBits[index].value;\r
-\r
-      hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
-      switch (cdFlow[index].value) {\r
-      case FLOW_NONE:\r
-       dcb.fOutX = FALSE;\r
-       dcb.fOutxCtsFlow = FALSE;\r
-       dcb.fOutxDsrFlow = FALSE;\r
-       break;\r
-      case FLOW_CTS:\r
-       dcb.fOutX = FALSE;\r
-       dcb.fOutxCtsFlow = TRUE;\r
-       dcb.fOutxDsrFlow = FALSE;\r
-       break;\r
-      case FLOW_DSR:\r
-       dcb.fOutX = FALSE;\r
-       dcb.fOutxCtsFlow = FALSE;\r
-       dcb.fOutxDsrFlow = TRUE;\r
-       break;\r
-      case FLOW_XOFF:\r
-       dcb.fOutX = TRUE;\r
-       dcb.fOutxCtsFlow = FALSE;\r
-       dcb.fOutxDsrFlow = FALSE;\r
-       break;\r
-      }\r
-      if (!SetCommState(hCommPort, (LPDCB) &dcb)) {\r
-       err = GetLastError();\r
-       switch(MessageBox(hDlg, \r
-                        "Failed to set comm port state;\r\ninvalid options?",\r
-                        "Option Error", MB_ABORTRETRYIGNORE|MB_ICONQUESTION)) {\r
-       case IDABORT:\r
-         DisplayFatalError("Failed to set comm port state", err, 1);\r
-         exit(1);  /*is it ok to do this from here?*/\r
-\r
-       case IDRETRY:\r
-         return TRUE;\r
-\r
-       case IDIGNORE:\r
-         EndDialog(hDlg, TRUE);\r
-         return TRUE;\r
-       }\r
-      }\r
-\r
-      EndDialog(hDlg, TRUE);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    default:\r
-      break;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID\r
-CommPortOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc = MakeProcInstance((FARPROC)CommPortOptionsDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_CommPort), hwnd, (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * Load Options dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-\r
-VOID\r
-SetLoadOptionEnables(HWND hDlg)\r
-{\r
-  UINT state;\r
-\r
-  state = IsDlgButtonChecked(hDlg, OPT_Autostep);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_ASTimeDelay), state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_AStext1), state);\r
-}\r
-\r
-LRESULT CALLBACK\r
-LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  char buf[MSG_SIZ];\r
-  float fnumber;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-    /* Initialize the dialog items */\r
-    if (appData.timeDelay >= 0.0) {\r
-      CheckDlgButton(hDlg, OPT_Autostep, TRUE);\r
-      sprintf(buf, "%.2g", appData.timeDelay);\r
-      SetDlgItemText(hDlg, OPT_ASTimeDelay, buf);\r
-    } else {\r
-      CheckDlgButton(hDlg, OPT_Autostep, FALSE);\r
-    }\r
-    SetLoadOptionEnables(hDlg);\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* Read changed options from the dialog box */\r
-      if (IsDlgButtonChecked(hDlg, OPT_Autostep)) {\r
-       GetDlgItemText(hDlg, OPT_ASTimeDelay, buf, MSG_SIZ);\r
-       if (sscanf(buf, "%f", &fnumber) != 1) {\r
-         MessageBox(hDlg, "Invalid load game step rate",\r
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-         return FALSE;\r
-       }\r
-       appData.timeDelay = fnumber;\r
-      } else {\r
-       appData.timeDelay = (float) -1.0;\r
-      }\r
-      EndDialog(hDlg, TRUE);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    default:\r
-      SetLoadOptionEnables(hDlg);\r
-      break;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-\r
-VOID \r
-LoadOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc = MakeProcInstance((FARPROC)LoadOptions, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_LoadOptions), hwnd, (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * Save Options dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-\r
-VOID\r
-SetSaveOptionEnables(HWND hDlg)\r
-{\r
-  UINT state;\r
-\r
-  state = IsDlgButtonChecked(hDlg, OPT_Autosave);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_AVPrompt), state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_AVToFile), state);\r
-  if (state && !IsDlgButtonChecked(hDlg, OPT_AVPrompt) &&\r
-      !IsDlgButtonChecked(hDlg, OPT_AVToFile)) {\r
-    CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
-  }\r
-\r
-  state = state && IsDlgButtonChecked(hDlg, OPT_AVToFile);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_AVFilename), state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_AVBrowse), state);\r
-}\r
-\r
-LRESULT CALLBACK\r
-SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  char buf[MSG_SIZ];\r
-  FILE *f;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-    /* Initialize the dialog items */\r
-    if (*appData.saveGameFile != NULLCHAR) {\r
-      CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
-      CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVToFile);\r
-      SetDlgItemText(hDlg, OPT_AVFilename, appData.saveGameFile);\r
-    } else if (appData.autoSaveGames) {\r
-      CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
-      CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
-    } else {\r
-      CheckDlgButton(hDlg, OPT_Autosave, (UINT) FALSE);\r
-    }\r
-    if (appData.oldSaveStyle) {\r
-      CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_Old);\r
-    } else {\r
-      CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_PGN);\r
-    }\r
-    CheckDlgButton( hDlg, OPT_OutOfBookInfo, appData.saveOutOfBookInfo );\r
-    SetSaveOptionEnables(hDlg);\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* Read changed options from the dialog box */\r
-      if (IsDlgButtonChecked(hDlg, OPT_Autosave)) {\r
-       appData.autoSaveGames = TRUE;\r
-       if (IsDlgButtonChecked(hDlg, OPT_AVPrompt)) {\r
-         appData.saveGameFile = "";\r
-       } else /*if (IsDlgButtonChecked(hDlg, OPT_AVToFile))*/ {\r
-         GetDlgItemText(hDlg, OPT_AVFilename, buf, MSG_SIZ);\r
-         if (*buf == NULLCHAR) {\r
-           MessageBox(hDlg, "Invalid save game file name",\r
-                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-           return FALSE;\r
-         }\r
-         if ((isalpha(buf[0]) && buf[1] == ':') ||\r
-           (buf[0] == '\\' && buf[1] == '\\')) {\r
-           appData.saveGameFile = strdup(buf);\r
-         } else {\r
-           char buf2[MSG_SIZ], buf3[MSG_SIZ];\r
-           char *dummy;\r
-           GetCurrentDirectory(MSG_SIZ, buf3);\r
-           SetCurrentDirectory(installDir);\r
-           if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
-             appData.saveGameFile = strdup(buf2);\r
-           } else {\r
-             appData.saveGameFile = strdup(buf);\r
-           }\r
-           SetCurrentDirectory(buf3);\r
-         }\r
-       }\r
-      } else {\r
-       appData.autoSaveGames = FALSE;\r
-       appData.saveGameFile = "";\r
-      }\r
-      appData.oldSaveStyle = IsDlgButtonChecked(hDlg, OPT_Old);\r
-      appData.saveOutOfBookInfo = IsDlgButtonChecked( hDlg, OPT_OutOfBookInfo );\r
-      EndDialog(hDlg, TRUE);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    case OPT_AVBrowse:\r
-      f = OpenFileDialog(hDlg, "a", NULL, \r
-                        appData.oldSaveStyle ? "gam" : "pgn", \r
-                        GAME_FILT, "Browse for Auto Save File", \r
-                        NULL, NULL, buf);\r
-      if (f != NULL) {\r
-       fclose(f);\r
-       SetDlgItemText(hDlg, OPT_AVFilename, buf);\r
-      }\r
-      break;\r
-\r
-    default:\r
-      SetSaveOptionEnables(hDlg);\r
-      break;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID\r
-SaveOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc = MakeProcInstance((FARPROC)SaveOptionsDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_SaveOptions), hwnd, (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * Time Control Options dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-\r
-VOID\r
-SetTimeControlEnables(HWND hDlg)\r
-{\r
-  UINT state;\r
-\r
-  state = IsDlgButtonChecked(hDlg, OPT_TCUseMoves);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_TCTime), state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_TCMoves), state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_TCtext1), state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_TCtext2), state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_TCTime2), !state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_TCInc), !state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_TCitext1), !state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_TCitext2), !state);\r
-  EnableWindow(GetDlgItem(hDlg, OPT_TCitext3), !state);\r
-}\r
-\r
-\r
-LRESULT CALLBACK\r
-TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  char buf[MSG_SIZ];\r
-  int mps, increment, odds1, odds2;\r
-  BOOL ok, ok2;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-    /* Initialize the dialog items */\r
-    if (appData.clockMode && !appData.icsActive) {\r
-      if (appData.timeIncrement == -1) {\r
-       CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseInc,\r
-                        OPT_TCUseMoves);\r
-       SetDlgItemText(hDlg, OPT_TCTime, appData.timeControl);\r
-       SetDlgItemInt(hDlg, OPT_TCMoves, appData.movesPerSession,\r
-                     FALSE);\r
-       SetDlgItemText(hDlg, OPT_TCTime2, "");\r
-       SetDlgItemText(hDlg, OPT_TCInc, "");\r
-      } else {\r
-       CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseInc,\r
-                        OPT_TCUseInc);\r
-       SetDlgItemText(hDlg, OPT_TCTime, "");\r
-       SetDlgItemText(hDlg, OPT_TCMoves, "");\r
-       SetDlgItemText(hDlg, OPT_TCTime2, appData.timeControl);\r
-       SetDlgItemInt(hDlg, OPT_TCInc, appData.timeIncrement, FALSE);\r
-      }\r
-      SetDlgItemInt(hDlg, OPT_TCOdds1, 1, FALSE);\r
-      SetDlgItemInt(hDlg, OPT_TCOdds2, 1, FALSE);\r
-      SetTimeControlEnables(hDlg);\r
-    }\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* Read changed options from the dialog box */\r
-      if (IsDlgButtonChecked(hDlg, OPT_TCUseMoves)) {\r
-       increment = -1;\r
-       mps = GetDlgItemInt(hDlg, OPT_TCMoves, &ok, FALSE);\r
-       if (!ok || mps <= 0) {\r
-         MessageBox(hDlg, "Invalid moves per time control",\r
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-         return FALSE;\r
-       }\r
-       GetDlgItemText(hDlg, OPT_TCTime, buf, MSG_SIZ);\r
-       if (!ParseTimeControl(buf, increment, mps)) {\r
-         MessageBox(hDlg, "Invalid minutes per time control",\r
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-         return FALSE;\r
-       }\r
-      } else {\r
-       increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE);\r
-       mps = appData.movesPerSession;\r
-       if (!ok || increment < 0) {\r
-         MessageBox(hDlg, "Invalid increment",\r
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-         return FALSE;\r
-       }\r
-       GetDlgItemText(hDlg, OPT_TCTime2, buf, MSG_SIZ);\r
-       if (!ParseTimeControl(buf, increment, mps)) {\r
-         MessageBox(hDlg, "Invalid initial time",\r
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-         return FALSE;\r
-       }\r
-      }\r
-      odds1 = GetDlgItemInt(hDlg, OPT_TCOdds1, &ok, FALSE);\r
-      odds2 = GetDlgItemInt(hDlg, OPT_TCOdds2, &ok2, FALSE);\r
-      if (!ok || !ok2 || odds1 <= 0 || odds2 <= 0) {\r
-         MessageBox(hDlg, "Invalid time-odds factor",\r
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
-         return FALSE;\r
-      }\r
-      appData.timeControl = strdup(buf);\r
-      appData.movesPerSession = mps;\r
-      appData.timeIncrement = increment;\r
-      appData.firstTimeOdds  = first.timeOdds  = odds1;\r
-      appData.secondTimeOdds = second.timeOdds = odds2;\r
-      Reset(TRUE, TRUE);\r
-      EndDialog(hDlg, TRUE);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    default:\r
-      SetTimeControlEnables(hDlg);\r
-      break;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID\r
-TimeControlOptionsPopup(HWND hwnd)\r
-{\r
-  if (gameMode != BeginningOfGame) {\r
-    DisplayError("Changing time control during a game is not implemented", 0);\r
-  } else {\r
-    FARPROC lpProc = MakeProcInstance((FARPROC)TimeControl, hInst);\r
-    DialogBox(hInst, MAKEINTRESOURCE(DLG_TimeControl), hwnd, (DLGPROC) lpProc);\r
-    FreeProcInstance(lpProc);\r
-  }\r
-}\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * Engine Options Dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
-#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
-\r
-#define INT_ABS( n )    ((n) >= 0 ? (n) : -(n))\r
-\r
-LRESULT CALLBACK EnginePlayOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-\r
-    /* Initialize the dialog items */\r
-    CHECK_BOX(IDC_EpPeriodicUpdates, appData.periodicUpdates);\r
-    CHECK_BOX(IDC_EpPonder, appData.ponderNextMove);\r
-    CHECK_BOX(IDC_EpShowThinking, appData.showThinking);\r
-    CHECK_BOX(IDC_EpHideThinkingHuman, appData.hideThinkingFromHuman);\r
-\r
-    CHECK_BOX(IDC_TestClaims, appData.testClaims);\r
-    CHECK_BOX(IDC_DetectMates, appData.checkMates);\r
-    CHECK_BOX(IDC_MaterialDraws, appData.materialDraws);\r
-    CHECK_BOX(IDC_TrivialDraws, appData.trivialDraws);\r
-\r
-    CHECK_BOX(IDC_ScoreAbs1, appData.firstScoreIsAbsolute);\r
-    CHECK_BOX(IDC_ScoreAbs2, appData.secondScoreIsAbsolute);\r
-\r
-    SetDlgItemInt( hDlg, IDC_EpDrawMoveCount, appData.adjudicateDrawMoves, TRUE );\r
-    SendDlgItemMessage( hDlg, IDC_EpDrawMoveCount, EM_SETSEL, 0, -1 );\r
-\r
-    SetDlgItemInt( hDlg, IDC_EpAdjudicationThreshold, INT_ABS(appData.adjudicateLossThreshold), TRUE );\r
-    SendDlgItemMessage( hDlg, IDC_EpAdjudicationThreshold, EM_SETSEL, 0, -1 );\r
-\r
-    SetDlgItemInt( hDlg, IDC_RuleMoves, appData.ruleMoves, TRUE );\r
-    SendDlgItemMessage( hDlg, IDC_RuleMoves, EM_SETSEL, 0, -1 );\r
-\r
-    SetDlgItemInt( hDlg, IDC_DrawRepeats, INT_ABS(appData.drawRepeats), TRUE );\r
-    SendDlgItemMessage( hDlg, IDC_DrawRepeats, EM_SETSEL, 0, -1 );\r
-\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      /* Read changed options from the dialog box */\r
-      PeriodicUpdatesEvent(          IS_CHECKED(IDC_EpPeriodicUpdates));\r
-      PonderNextMoveEvent(           IS_CHECKED(IDC_EpPonder));\r
-      appData.hideThinkingFromHuman= IS_CHECKED(IDC_EpHideThinkingHuman); // [HGM] thinking: moved up\r
-#if 0\r
-      ShowThinkingEvent(             IS_CHECKED(IDC_EpShowThinking));\r
-#else\r
-      appData.showThinking   = IS_CHECKED(IDC_EpShowThinking);\r
-      ShowThinkingEvent(); // [HGM] thinking: tests all options that need thinking output\r
-#endif\r
-      appData.testClaims    = IS_CHECKED(IDC_TestClaims);\r
-      appData.checkMates    = IS_CHECKED(IDC_DetectMates);\r
-      appData.materialDraws = IS_CHECKED(IDC_MaterialDraws);\r
-      appData.trivialDraws  = IS_CHECKED(IDC_TrivialDraws);\r
-\r
-      appData.adjudicateDrawMoves = GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, NULL, FALSE );\r
-      appData.adjudicateLossThreshold = - (int) GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, NULL, FALSE );\r
-      appData.ruleMoves = GetDlgItemInt(hDlg, IDC_RuleMoves, NULL, FALSE );\r
-      appData.drawRepeats = (int) GetDlgItemInt(hDlg, IDC_DrawRepeats, NULL, FALSE );\r
-\r
-      appData.firstScoreIsAbsolute  = IS_CHECKED(IDC_ScoreAbs1);\r
-      appData.secondScoreIsAbsolute = IS_CHECKED(IDC_ScoreAbs2);\r
-\r
-      EndDialog(hDlg, TRUE);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    case IDC_EpDrawMoveCount:\r
-    case IDC_EpAdjudicationThreshold:\r
-    case IDC_DrawRepeats:\r
-    case IDC_RuleMoves:\r
-        if( HIWORD(wParam) == EN_CHANGE ) {\r
-            int n1_ok;\r
-            int n2_ok;\r
-            int n3_ok;\r
-            int n4_ok;\r
-\r
-            GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, &n1_ok, FALSE );\r
-            GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, &n2_ok, FALSE );\r
-            GetDlgItemInt(hDlg, IDC_RuleMoves, &n3_ok, FALSE );\r
-            GetDlgItemInt(hDlg, IDC_DrawRepeats, &n4_ok, FALSE );\r
-\r
-            EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok && n4_ok ? TRUE : FALSE );\r
-        }\r
-        return TRUE;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID EnginePlayOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc;\r
-\r
-  lpProc = MakeProcInstance((FARPROC)EnginePlayOptionsDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_EnginePlayOptions), hwnd, (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
-\r
-/*---------------------------------------------------------------------------*\\r
- *\r
- * UCI Options Dialog functions\r
- *\r
-\*---------------------------------------------------------------------------*/\r
-static BOOL BrowseForFolder( const char * title, char * path )\r
-{\r
-    BOOL result = FALSE;\r
-    BROWSEINFO bi;\r
-    LPITEMIDLIST pidl;\r
-\r
-    ZeroMemory( &bi, sizeof(bi) );\r
-\r
-    bi.lpszTitle = title == 0 ? "Choose Folder" : title;\r
-    bi.ulFlags = BIF_RETURNONLYFSDIRS;\r
-\r
-    pidl = SHBrowseForFolder( &bi );\r
-\r
-    if( pidl != 0 ) {\r
-        IMalloc * imalloc = 0;\r
-\r
-        if( SHGetPathFromIDList( pidl, path ) ) {\r
-            result = TRUE;\r
-        }\r
-\r
-        if( SUCCEEDED( SHGetMalloc ( &imalloc ) ) ) {\r
-            imalloc->lpVtbl->Free(imalloc,pidl);\r
-            imalloc->lpVtbl->Release(imalloc);\r
-        }\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  char buf[MAX_PATH];\r
-  int oldCores;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-\r
-    /* Center the dialog over the application window */\r
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
-\r
-    /* Initialize the dialog items */\r
-    SetDlgItemText( hDlg, IDC_PolyglotDir, appData.polyglotDir );\r
-    SetDlgItemInt( hDlg, IDC_HashSize, appData.defaultHashSize, TRUE );\r
-    SetDlgItemText( hDlg, IDC_PathToEGTB, appData.defaultPathEGTB );\r
-    SetDlgItemInt( hDlg, IDC_SizeOfEGTB, appData.defaultCacheSizeEGTB, TRUE );\r
-    CheckDlgButton( hDlg, IDC_UseBook, (BOOL) appData.usePolyglotBook );\r
-    SetDlgItemText( hDlg, IDC_BookFile, appData.polyglotBook );\r
-    // [HGM] smp: input field for nr of cores:\r
-    SetDlgItemInt( hDlg, IDC_Cores, appData.smpCores, TRUE );\r
-    // [HGM] book: tick boxes for own book use\r
-    CheckDlgButton( hDlg, IDC_OwnBook1, (BOOL) appData.firstHasOwnBookUCI );\r
-    CheckDlgButton( hDlg, IDC_OwnBook2, (BOOL) appData.secondHasOwnBookUCI );\r
-\r
-    SendDlgItemMessage( hDlg, IDC_PolyglotDir, EM_SETSEL, 0, -1 );\r
-\r
-    return TRUE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDOK:\r
-      GetDlgItemText( hDlg, IDC_PolyglotDir, buf, sizeof(buf) );\r
-      appData.polyglotDir = strdup(buf);\r
-      appData.defaultHashSize = GetDlgItemInt(hDlg, IDC_HashSize, NULL, FALSE );\r
-      appData.defaultCacheSizeEGTB = GetDlgItemInt(hDlg, IDC_SizeOfEGTB, NULL, FALSE );\r
-      GetDlgItemText( hDlg, IDC_PathToEGTB, buf, sizeof(buf) );\r
-      appData.defaultPathEGTB = strdup(buf);\r
-      GetDlgItemText( hDlg, IDC_BookFile, buf, sizeof(buf) );\r
-      appData.polyglotBook = strdup(buf);\r
-      appData.usePolyglotBook = (Boolean) IsDlgButtonChecked( hDlg, IDC_UseBook );\r
-      // [HGM] smp: get nr of cores:\r
-      oldCores = appData.smpCores;\r
-      appData.smpCores = GetDlgItemInt(hDlg, IDC_Cores, NULL, FALSE );\r
-      if(appData.smpCores != oldCores) NewSettingEvent(FALSE, "cores", appData.smpCores);\r
-      // [HGM] book: read tick boxes for own book use\r
-      appData.firstHasOwnBookUCI  = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook1 );\r
-      appData.secondHasOwnBookUCI = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook2 );\r
-\r
-      if(gameMode == BeginningOfGame) Reset(TRUE, TRUE);\r
-      EndDialog(hDlg, TRUE);\r
-      return TRUE;\r
-\r
-    case IDCANCEL:\r
-      EndDialog(hDlg, FALSE);\r
-      return TRUE;\r
-\r
-    case IDC_BrowseForBook:\r
-      {\r
-          char filter[] = { \r
-              'A','l','l',' ','F','i','l','e','s', 0,\r
-              '*','.','*', 0,\r
-              'B','I','N',' ','F','i','l','e','s', 0,\r
-              '*','.','b','i','n', 0,\r
-              0 };\r
-\r
-          OPENFILENAME ofn;\r
-\r
-          strcpy( buf, "" );\r
-\r
-          ZeroMemory( &ofn, sizeof(ofn) );\r
-\r
-          ofn.lStructSize = sizeof(ofn);\r
-          ofn.hwndOwner = hDlg;\r
-          ofn.hInstance = hInst;\r
-          ofn.lpstrFilter = filter;\r
-          ofn.lpstrFile = buf;\r
-          ofn.nMaxFile = sizeof(buf);\r
-          ofn.lpstrTitle = "Choose Book";\r
-          ofn.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_HIDEREADONLY;\r
-\r
-          if( GetOpenFileName( &ofn ) ) {\r
-              SetDlgItemText( hDlg, IDC_BookFile, buf );\r
-          }\r
-      }\r
-      return TRUE;\r
-\r
-    case IDC_BrowseForPolyglotDir:\r
-      if( BrowseForFolder( "Choose Polyglot Directory", buf ) ) {\r
-        SetDlgItemText( hDlg, IDC_PolyglotDir, buf );\r
-\r
-        strcat( buf, "\\polyglot.exe" );\r
-\r
-        if( GetFileAttributes(buf) == 0xFFFFFFFF ) {\r
-            MessageBox( hDlg, "Polyglot was not found in the specified folder!", "Warning", MB_OK | MB_ICONWARNING );\r
-        }\r
-      }\r
-      return TRUE;\r
-\r
-    case IDC_BrowseForEGTB:\r
-      if( BrowseForFolder( "Choose EGTB Directory:", buf ) ) {\r
-        SetDlgItemText( hDlg, IDC_PathToEGTB, buf );\r
-      }\r
-      return TRUE;\r
-\r
-    case IDC_HashSize:\r
-    case IDC_SizeOfEGTB:\r
-        if( HIWORD(wParam) == EN_CHANGE ) {\r
-            int n1_ok;\r
-            int n2_ok;\r
-\r
-            GetDlgItemInt(hDlg, IDC_HashSize, &n1_ok, FALSE );\r
-            GetDlgItemInt(hDlg, IDC_SizeOfEGTB, &n2_ok, FALSE );\r
-\r
-            EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok ? TRUE : FALSE );\r
-        }\r
-        return TRUE;\r
-    }\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-VOID UciOptionsPopup(HWND hwnd)\r
-{\r
-  FARPROC lpProc;\r
-\r
-  lpProc = MakeProcInstance((FARPROC)UciOptionsDialog, hInst);\r
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_OptionsUCI), hwnd, (DLGPROC) lpProc);\r
-  FreeProcInstance(lpProc);\r
-}\r
+/*
+ * woptions.c -- Options dialog box routines for WinBoard
+ * $Id: woptions.c,v 2.1 2003/10/27 19:21:02 mann Exp $
+ *
+ * Copyright 2000 Free Software Foundation, Inc.
+ *
+ * ------------------------------------------------------------------------
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ------------------------------------------------------------------------
+ */
+
+#include "config.h"
+
+#include <windows.h>   /* required for all Windows applications */
+#include <stdio.h>
+#include <stdlib.h>
+#include <shlobj.h>    /* [AS] Requires NT 4.0 or Win95 */
+
+#include "common.h"
+#include "winboard.h"
+#include "backend.h"
+#include "woptions.h"
+#include "defaults.h"
+#include "wedittags.h"
+#include <richedit.h>
+
+#if __GNUC__
+#include <errno.h>
+#include <string.h>
+#endif
+
+/* Imports from winboard.c */
+
+extern MyFont *font[NUM_SIZES][NUM_FONTS];
+extern HINSTANCE hInst;          /* current instance */
+extern HWND hwndMain;            /* root window*/
+extern BOOLEAN alwaysOnTop;
+extern RECT boardRect;
+extern COLORREF lightSquareColor, darkSquareColor, whitePieceColor, 
+  blackPieceColor, highlightSquareColor, premoveHighlightColor;
+extern HPALETTE hPal;
+extern BoardSize boardSize;
+extern COLORREF consoleBackgroundColor;
+extern MyColorizeAttribs colorizeAttribs[]; /* do I need the size? */
+extern MyTextAttribs textAttribs[];
+extern MySound sounds[];
+extern ColorClass currentColorClass;
+extern HWND hwndConsole;
+extern char *defaultTextAttribs[];
+extern HWND commentDialog;
+extern HWND moveHistoryDialog;
+extern char installDir[];
+extern HWND hCommPort;    /* currently open comm port */
+extern DCB dcb;
+extern BOOLEAN chessProgram;
+extern startedFromPositionFile; /* [HGM] loadPos */
+
+/* types */
+
+typedef struct {
+  char *label;
+  unsigned value;
+} ComboData;
+
+typedef struct {
+  char *label;
+  char *name;
+} SoundComboData;
+
+/* module prototypes */
+
+LRESULT CALLBACK GeneralOptions(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK BoardOptions(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK NewVariant(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK IcsOptions(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK FontOptions(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK CommPortOptions(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK LoadOptions(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK SaveOptions(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK TimeControl(HWND, UINT, WPARAM, LPARAM);
+VOID ChangeBoardSize(BoardSize newSize);
+VOID PaintSampleSquare(
+    HWND     hwnd, 
+    int      ctrlid, 
+    COLORREF squareColor, 
+    COLORREF pieceColor,
+    COLORREF squareOutlineColor,
+    COLORREF pieceDetailColor,
+    BOOL     isWhitePiece,
+    BOOL     isMono,
+    HBITMAP  pieces[3] 
+    );
+VOID PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color);
+VOID SetBoardOptionEnables(HWND hDlg);
+BoardSize BoardOptionsWhichRadio(HWND hDlg);
+BOOL APIENTRY MyCreateFont(HWND hwnd, MyFont *font);
+VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca);
+LRESULT CALLBACK ColorizeTextDialog(HWND , UINT, WPARAM, LPARAM);
+VOID ColorizeTextPopup(HWND hwnd, ColorClass cc);
+VOID SetIcsOptionEnables(HWND hDlg);
+VOID SetSampleFontText(HWND hwnd, int id, const MyFont *mf);
+VOID CopyFont(MyFont *dest, const MyFont *src);
+void InitSoundComboData(SoundComboData *scd);
+void ResetSoundComboData(SoundComboData *scd);
+void InitSoundCombo(HWND hwndCombo, SoundComboData *scd);
+int SoundDialogWhichRadio(HWND hDlg);
+VOID SoundDialogSetEnables(HWND hDlg, int radio);
+char * SoundDialogGetName(HWND hDlg, int radio);
+void DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name);
+VOID ParseCommSettings(char *arg, DCB *dcb);
+VOID PrintCommSettings(FILE *f, char *name, DCB *dcb);
+void InitCombo(HANDLE hwndCombo, ComboData *cd);
+void SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value);
+VOID SetLoadOptionEnables(HWND hDlg);
+VOID SetSaveOptionEnables(HWND hDlg);
+VOID SetTimeControlEnables(HWND hDlg);
+
+/*---------------------------------------------------------------------------*\
+ *
+ * General Options Dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+
+
+LRESULT CALLBACK
+GeneralOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  static Boolean oldShowCoords;
+  static Boolean oldBlindfold;
+  static Boolean oldShowButtonBar;
+
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+    oldShowCoords = appData.showCoords;
+    oldBlindfold  = appData.blindfold;
+    oldShowButtonBar = appData.showButtonBar;
+
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+
+    /* Initialize the dialog items */
+#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))
+
+    CHECK_BOX(OPT_AlwaysOnTop, alwaysOnTop);
+    CHECK_BOX(OPT_AlwaysQueen, appData.alwaysPromoteToQueen);
+    CHECK_BOX(OPT_AnimateDragging, appData.animateDragging);
+    CHECK_BOX(OPT_AnimateMoving, appData.animate);
+    CHECK_BOX(OPT_AutoFlag, appData.autoCallFlag);
+    CHECK_BOX(OPT_AutoFlipView, appData.autoFlipView);
+    CHECK_BOX(OPT_AutoRaiseBoard, appData.autoRaiseBoard);
+    CHECK_BOX(OPT_Blindfold, appData.blindfold);
+    CHECK_BOX(OPT_HighlightDragging, appData.highlightDragging);
+    CHECK_BOX(OPT_HighlightLastMove, appData.highlightLastMove);
+    CHECK_BOX(OPT_PeriodicUpdates, appData.periodicUpdates);
+    CHECK_BOX(OPT_PonderNextMove, appData.ponderNextMove);
+    CHECK_BOX(OPT_PopupExitMessage, appData.popupExitMessage);
+    CHECK_BOX(OPT_PopupMoveErrors, appData.popupMoveErrors);
+    CHECK_BOX(OPT_ShowButtonBar, appData.showButtonBar);
+    CHECK_BOX(OPT_ShowCoordinates, appData.showCoords);
+    CHECK_BOX(OPT_ShowThinking, appData.showThinking);
+    CHECK_BOX(OPT_TestLegality, appData.testLegality);
+    CHECK_BOX(OPT_HideThinkFromHuman, appData.hideThinkingFromHuman);
+    CHECK_BOX(OPT_SaveExtPGN, appData.saveExtendedInfoInPGN);
+    CHECK_BOX(OPT_ExtraInfoInMoveHistory, appData.showEvalInMoveHistory);
+    CHECK_BOX(OPT_HighlightMoveArrow, appData.highlightMoveWithArrow);
+
+#undef CHECK_BOX
+
+    EnableWindow(GetDlgItem(hDlg, OPT_AutoFlag),
+                appData.icsActive || !appData.noChessProgram);
+    EnableWindow(GetDlgItem(hDlg, OPT_AutoFlipView),
+                appData.icsActive || !appData.noChessProgram);
+    EnableWindow(GetDlgItem(hDlg, OPT_PonderNextMove),
+                !appData.noChessProgram);
+    EnableWindow(GetDlgItem(hDlg, OPT_PeriodicUpdates), 
+                !appData.noChessProgram && !appData.icsActive);
+    EnableWindow(GetDlgItem(hDlg, OPT_ShowThinking), 
+                !appData.noChessProgram);
+    return TRUE;
+
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* Read changed options from the dialog box */
+      
+#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))
+
+      alwaysOnTop                  = IS_CHECKED(OPT_AlwaysOnTop);
+      appData.alwaysPromoteToQueen = IS_CHECKED(OPT_AlwaysQueen);
+      appData.animateDragging      = IS_CHECKED(OPT_AnimateDragging);
+      appData.animate              = IS_CHECKED(OPT_AnimateMoving);
+      appData.autoCallFlag         = IS_CHECKED(OPT_AutoFlag);
+      appData.autoFlipView         = IS_CHECKED(OPT_AutoFlipView);
+      appData.autoRaiseBoard       = IS_CHECKED(OPT_AutoRaiseBoard);
+      appData.blindfold            = IS_CHECKED(OPT_Blindfold);
+      appData.highlightDragging    = IS_CHECKED(OPT_HighlightDragging);
+      appData.highlightLastMove    = IS_CHECKED(OPT_HighlightLastMove);
+      PeriodicUpdatesEvent(          IS_CHECKED(OPT_PeriodicUpdates));
+      PonderNextMoveEvent(           IS_CHECKED(OPT_PonderNextMove));
+      appData.popupExitMessage     = IS_CHECKED(OPT_PopupExitMessage);
+      appData.popupMoveErrors      = IS_CHECKED(OPT_PopupMoveErrors);
+      appData.showButtonBar        = IS_CHECKED(OPT_ShowButtonBar);
+      appData.showCoords           = IS_CHECKED(OPT_ShowCoordinates);
+      // [HGM] thinking: next three moved up
+      appData.saveExtendedInfoInPGN= IS_CHECKED(OPT_SaveExtPGN);
+      appData.hideThinkingFromHuman= IS_CHECKED(OPT_HideThinkFromHuman);
+      appData.showEvalInMoveHistory= IS_CHECKED(OPT_ExtraInfoInMoveHistory);
+#if 0
+      ShowThinkingEvent(             IS_CHECKED(OPT_ShowThinking));
+#else
+      appData.showThinking         = IS_CHECKED(OPT_ShowThinking);
+      ShowThinkingEvent(); // [HGM] thinking: tests four options
+#endif
+      appData.testLegality         = IS_CHECKED(OPT_TestLegality);
+      appData.highlightMoveWithArrow=IS_CHECKED(OPT_HighlightMoveArrow);
+
+#undef IS_CHECKED
+
+      SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
+                  0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+#if AOT_CONSOLE
+      if (hwndConsole) {
+       SetWindowPos(hwndConsole, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
+                    0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+      }
+#endif
+      if (!appData.highlightLastMove) {
+       ClearHighlights();
+       DrawPosition(FALSE, NULL);
+      }
+      /* 
+       * for some reason the redraw seems smoother when we invalidate
+       * the board rect after the call to EndDialog()
+       */
+      EndDialog(hDlg, TRUE);
+
+      if (oldShowButtonBar != appData.showButtonBar) {
+       InitDrawingSizes(boardSize, 0);
+      } else if ((oldShowCoords != appData.showCoords) || 
+                (oldBlindfold != appData.blindfold)) {
+       InvalidateRect(hwndMain, &boardRect, FALSE);
+      }
+
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    }
+    break;
+  }
+  return FALSE;
+}
+
+VOID 
+GeneralOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc;
+
+  lpProc = MakeProcInstance((FARPROC)GeneralOptionsDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_GeneralOptions), hwnd,
+           (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}
+/*---------------------------------------------------------------------------*\
+ *
+ * Board Options Dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+
+const int SAMPLE_SQ_SIZE = 54;
+
+VOID
+ChangeBoardSize(BoardSize newSize)
+{
+  if (newSize != boardSize) {
+    boardSize = newSize;
+    InitDrawingSizes(boardSize, 0);
+  }
+}
+
+VOID
+PaintSampleSquare(
+    HWND     hwnd, 
+    int      ctrlid, 
+    COLORREF squareColor, 
+    COLORREF pieceColor,
+    COLORREF squareOutlineColor,
+    COLORREF pieceDetailColor,
+    BOOL     isWhitePiece,
+    BOOL     isMono,
+    HBITMAP  pieces[3] 
+    )
+{
+  HBRUSH  brushSquare;
+  HBRUSH  brushSquareOutline;
+  HBRUSH  brushPiece;
+  HBRUSH  brushPieceDetail;
+  HBRUSH  oldBrushPiece;
+  HBRUSH  oldBrushSquare;
+  HBITMAP oldBitmapMem;
+  HBITMAP oldBitmapTemp;
+  HBITMAP bufferBitmap;
+  RECT    rect;
+  HDC     hdcScreen, hdcMem, hdcTemp;
+  HPEN    pen, oldPen;
+  HWND    hCtrl = GetDlgItem(hwnd, ctrlid);
+  int     x, y;
+
+  const int SOLID   = 0;
+  const int WHITE   = 1;
+  const int OUTLINE = 2;
+  const int BORDER  = 4;
+
+  InvalidateRect(hCtrl, NULL, TRUE);
+  UpdateWindow(hCtrl);
+  GetClientRect(hCtrl, &rect);
+  x = rect.left + (BORDER / 2);
+  y = rect.top  + (BORDER / 2);
+  hdcScreen = GetDC(hCtrl);
+  hdcMem  = CreateCompatibleDC(hdcScreen);
+  hdcTemp = CreateCompatibleDC(hdcScreen);
+
+  bufferBitmap = CreateCompatibleBitmap(hdcScreen, rect.right-rect.left+1,
+                                       rect.bottom-rect.top+1);
+  oldBitmapMem = SelectObject(hdcMem, bufferBitmap);
+  if (!isMono) {
+    SelectPalette(hdcMem, hPal, FALSE);
+  }
+  brushSquare         = CreateSolidBrush(squareColor);
+  brushSquareOutline  = CreateSolidBrush(squareOutlineColor);
+  brushPiece          = CreateSolidBrush(pieceColor);
+  brushPieceDetail    = CreateSolidBrush(pieceDetailColor);
+
+  /* 
+   * first draw the rectangle 
+   */
+  pen      = CreatePen(PS_SOLID, BORDER, squareOutlineColor);
+  oldPen   = (HPEN)  SelectObject(hdcMem, pen);
+  oldBrushSquare = (HBRUSH)SelectObject(hdcMem, brushSquare);
+  Rectangle(hdcMem, rect.left, rect.top, rect.right, rect.bottom);
+
+  /* 
+   * now draw the piece
+   */
+  if (isMono) {
+    oldBitmapTemp = SelectObject(hdcTemp, pieces[OUTLINE]);
+    BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, hdcTemp, 0, 0,
+          isWhitePiece ? SRCCOPY : NOTSRCCOPY);
+    SelectObject(hdcTemp, oldBitmapTemp);
+  } else {
+    if (isWhitePiece) {
+      oldBitmapTemp = SelectObject(hdcTemp, pieces[WHITE]);
+      oldBrushPiece = SelectObject(hdcMem, brushPiece);
+      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, 
+            hdcTemp, 0, 0, 0x00B8074A);
+#if 0
+      /* Use pieceDetailColor for outline of white pieces */
+      SelectObject(hdcTemp, pieces[OUTLINE]);
+      SelectObject(hdcMem, brushPieceDetail);
+      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, 
+            hdcTemp, 0, 0, 0x00B8074A);
+#else
+      /* Use black for outline of white pieces */
+      SelectObject(hdcTemp, pieces[OUTLINE]);
+      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, 
+            hdcTemp, 0, 0, SRCAND);
+#endif
+    } else {
+#if 0
+      /* Use pieceDetailColor for details of black pieces */
+      /* Requires filled-in solid bitmaps (BLACK_PIECE class); the
+        WHITE_PIECE ones aren't always the right shape. */
+      oldBitmapTemp = SelectObject(hdcTemp, pieces[BLACK]);
+      oldBrushPiece = SelectObject(hdcMem, brushPieceDetail);
+      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, 
+            hdcTemp, 0, 0, 0x00B8074A);
+      SelectObject(hdcTemp, pieces[SOLID]);
+      SelectObject(hdcMem, brushPiece);
+      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, 
+            hdcTemp, 0, 0, 0x00B8074A);
+#else
+      /* Use square color for details of black pieces */
+      oldBitmapTemp = SelectObject(hdcTemp, pieces[SOLID]);
+      oldBrushPiece = SelectObject(hdcMem, brushPiece);
+      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, 
+            hdcTemp, 0, 0, 0x00B8074A);
+#endif
+    }
+    SelectObject(hdcMem, oldBrushPiece);
+    SelectObject(hdcTemp, oldBitmapTemp);
+  }
+  /* 
+   * copy the memory dc to the screen
+   */
+  SelectObject(hdcMem, bufferBitmap);
+  BitBlt(hdcScreen, rect.left, rect.top,
+        rect.right - rect.left,
+        rect.bottom - rect.top,
+        hdcMem, rect.left, rect.top, SRCCOPY);
+  SelectObject(hdcMem, oldBitmapMem);
+  /* 
+   * clean up
+   */
+  SelectObject(hdcMem, oldBrushPiece);
+  SelectObject(hdcMem, oldPen);
+  DeleteObject(brushPiece);
+  DeleteObject(brushPieceDetail);
+  DeleteObject(brushSquare);
+  DeleteObject(brushSquareOutline);
+  DeleteObject(pen);
+  DeleteDC(hdcTemp);
+  DeleteDC(hdcMem);
+  ReleaseDC(hCtrl, hdcScreen);
+}
+
+
+VOID
+PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color)
+{
+  HDC    hdc;
+  HBRUSH brush, oldBrush;
+  RECT   rect;
+  HWND   hCtrl = GetDlgItem(hwnd, ctrlid);
+
+  hdc = GetDC(hCtrl);
+  InvalidateRect(hCtrl, NULL, TRUE);
+  UpdateWindow(hCtrl);
+  GetClientRect(hCtrl, &rect);
+  brush = CreateSolidBrush(color);
+  oldBrush = (HBRUSH)SelectObject(hdc, brush);
+  Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
+  SelectObject(hdc, oldBrush);
+  DeleteObject(brush);
+  ReleaseDC(hCtrl, hdc);
+}
+
+
+VOID
+SetBoardOptionEnables(HWND hDlg)
+{
+  if (IsDlgButtonChecked(hDlg, OPT_Monochrome)) {
+    ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_HIDE);
+    ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_HIDE);
+    ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_HIDE);
+    ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_HIDE);
+
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), FALSE);
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), FALSE);
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), FALSE);
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), FALSE);
+  } else {
+    ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_SHOW);
+    ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_SHOW);
+    ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_SHOW);
+    ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_SHOW);
+
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), TRUE);
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), TRUE);
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), TRUE);
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), TRUE);
+  }
+}
+
+BoardSize 
+BoardOptionsWhichRadio(HWND hDlg)
+{
+  return (IsDlgButtonChecked(hDlg, OPT_SizeTiny) ? SizeTiny :
+         (IsDlgButtonChecked(hDlg, OPT_SizeTeeny) ? SizeTeeny :
+         (IsDlgButtonChecked(hDlg, OPT_SizeDinky) ? SizeDinky :
+         (IsDlgButtonChecked(hDlg, OPT_SizePetite) ? SizePetite :
+         (IsDlgButtonChecked(hDlg, OPT_SizeSlim) ? SizeSlim :
+         (IsDlgButtonChecked(hDlg, OPT_SizeSmall) ? SizeSmall :
+         (IsDlgButtonChecked(hDlg, OPT_SizeMediocre) ? SizeMediocre :
+         (IsDlgButtonChecked(hDlg, OPT_SizeMiddling) ? SizeMiddling :
+         (IsDlgButtonChecked(hDlg, OPT_SizeAverage) ? SizeAverage :
+         (IsDlgButtonChecked(hDlg, OPT_SizeModerate) ? SizeModerate :
+         (IsDlgButtonChecked(hDlg, OPT_SizeMedium) ? SizeMedium :
+         (IsDlgButtonChecked(hDlg, OPT_SizeBulky) ? SizeBulky :
+         (IsDlgButtonChecked(hDlg, OPT_SizeLarge) ? SizeLarge :
+         (IsDlgButtonChecked(hDlg, OPT_SizeBig) ? SizeBig :
+         (IsDlgButtonChecked(hDlg, OPT_SizeHuge) ? SizeHuge :
+         (IsDlgButtonChecked(hDlg, OPT_SizeGiant) ? SizeGiant :
+         (IsDlgButtonChecked(hDlg, OPT_SizeColossal) ? SizeColossal :
+          SizeTitanic )))))))))))))))));
+}
+
+LRESULT CALLBACK
+BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  static Boolean  mono, white, flip;
+  static BoardSize size;
+  static COLORREF lsc, dsc, wpc, bpc, hsc, phc;
+  static HBITMAP pieces[3];
+
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+    /* Initialize the dialog items */
+    switch (boardSize) {
+    case SizeTiny:
+      CheckDlgButton(hDlg, OPT_SizeTiny, TRUE);
+      break;
+    case SizeTeeny:
+      CheckDlgButton(hDlg, OPT_SizeTeeny, TRUE);
+      break;
+    case SizeDinky:
+      CheckDlgButton(hDlg, OPT_SizeDinky, TRUE);
+      break;
+    case SizePetite:
+      CheckDlgButton(hDlg, OPT_SizePetite, TRUE);
+      break;
+    case SizeSlim:
+      CheckDlgButton(hDlg, OPT_SizeSlim, TRUE);
+      break;
+    case SizeSmall:
+      CheckDlgButton(hDlg, OPT_SizeSmall, TRUE);
+      break;
+    case SizeMediocre:
+      CheckDlgButton(hDlg, OPT_SizeMediocre, TRUE);
+      break;
+    case SizeMiddling:
+      CheckDlgButton(hDlg, OPT_SizeMiddling, TRUE);
+      break;
+    case SizeAverage:
+      CheckDlgButton(hDlg, OPT_SizeAverage, TRUE);
+      break;
+    case SizeModerate:
+      CheckDlgButton(hDlg, OPT_SizeModerate, TRUE);
+      break;
+    case SizeMedium:
+      CheckDlgButton(hDlg, OPT_SizeMedium, TRUE);
+      break;
+    case SizeBulky:
+      CheckDlgButton(hDlg, OPT_SizeBulky, TRUE);
+      break;
+    case SizeLarge:
+      CheckDlgButton(hDlg, OPT_SizeLarge, TRUE);
+      break;
+    case SizeBig:
+      CheckDlgButton(hDlg, OPT_SizeBig, TRUE);
+      break;
+    case SizeHuge:
+      CheckDlgButton(hDlg, OPT_SizeHuge, TRUE);
+      break;
+    case SizeGiant:
+      CheckDlgButton(hDlg, OPT_SizeGiant, TRUE);
+      break;
+    case SizeColossal:
+      CheckDlgButton(hDlg, OPT_SizeColossal, TRUE);
+      break;
+    case SizeTitanic:
+      CheckDlgButton(hDlg, OPT_SizeTitanic, TRUE);
+    }
+
+    if (appData.monoMode)
+      CheckDlgButton(hDlg, OPT_Monochrome, TRUE);
+
+    if (appData.allWhite)
+      CheckDlgButton(hDlg, OPT_AllWhite, TRUE);
+
+    if (appData.upsideDown)
+      CheckDlgButton(hDlg, OPT_UpsideDown, TRUE);
+
+    pieces[0] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "s");
+    pieces[1] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "w");
+    pieces[2] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "o");
+       
+    lsc = lightSquareColor;
+    dsc = darkSquareColor;
+    wpc = whitePieceColor;
+    bpc = blackPieceColor;
+    hsc = highlightSquareColor;
+    phc = premoveHighlightColor;
+    mono = appData.monoMode;
+    white= appData.allWhite;
+    flip = appData.upsideDown;
+    size = boardSize;
+
+    SetBoardOptionEnables(hDlg);
+    return TRUE;
+
+  case WM_PAINT:
+    PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);
+    PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);
+    PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);
+    PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);
+    PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);
+    PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);
+    PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
+       TRUE, mono, pieces);
+    PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
+       FALSE, mono, pieces);
+
+    return FALSE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* 
+       * if we call EndDialog() after the call to ChangeBoardSize(),
+       * then ChangeBoardSize() does not take effect, although the new
+       * boardSize is saved. Go figure...
+       */
+      EndDialog(hDlg, TRUE);
+
+      size = BoardOptionsWhichRadio(hDlg);
+
+      /*
+       * did any settings change?
+       */
+      if (size != boardSize) {
+       ChangeBoardSize(size);
+      }
+
+      if ((mono != appData.monoMode) ||
+         (lsc  != lightSquareColor) ||
+         (dsc  != darkSquareColor) ||
+         (wpc  != whitePieceColor) ||
+         (bpc  != blackPieceColor) ||
+         (hsc  != highlightSquareColor) ||
+          (flip != appData.upsideDown) ||
+          (white != appData.allWhite) ||
+         (phc  != premoveHighlightColor)) {
+
+         lightSquareColor = lsc;
+         darkSquareColor = dsc;
+         whitePieceColor = wpc;
+         blackPieceColor = bpc;
+         highlightSquareColor = hsc;
+         premoveHighlightColor = phc;
+         appData.monoMode = mono;
+          appData.allWhite = white;
+          appData.upsideDown = flip;
+
+         InitDrawingColors();
+         InitDrawingSizes(boardSize, 0);
+         InvalidateRect(hwndMain, &boardRect, FALSE);
+      }
+      DeleteObject(pieces[0]);
+      DeleteObject(pieces[1]);
+      DeleteObject(pieces[2]);
+      return TRUE;
+
+    case IDCANCEL:
+      DeleteObject(pieces[0]);
+      DeleteObject(pieces[1]);
+      DeleteObject(pieces[2]);
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    case OPT_ChooseLightSquareColor:
+      if (ChangeColor(hDlg, &lsc)) 
+       PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);
+       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
+           TRUE, mono, pieces);
+      break;
+
+    case OPT_ChooseDarkSquareColor:
+      if (ChangeColor(hDlg, &dsc)) 
+       PaintColorBlock(hDlg, OPT_DarkSquareColor, dsc);
+       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
+           FALSE, mono, pieces);
+      break;
+
+    case OPT_ChooseWhitePieceColor:
+      if (ChangeColor(hDlg, &wpc)) 
+       PaintColorBlock(hDlg, OPT_WhitePieceColor, wpc);
+       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
+           TRUE, mono, pieces);
+      break;
+
+    case OPT_ChooseBlackPieceColor:
+      if (ChangeColor(hDlg, &bpc)) 
+       PaintColorBlock(hDlg, OPT_BlackPieceColor, bpc);
+       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
+           FALSE, mono, pieces);
+      break;
+
+    case OPT_ChooseHighlightSquareColor:
+      if (ChangeColor(hDlg, &hsc)) 
+       PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);
+       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
+           TRUE, mono, pieces);
+      break;
+
+    case OPT_ChoosePremoveHighlightColor:
+      if (ChangeColor(hDlg, &phc)) 
+       PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);
+       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
+           FALSE, mono, pieces);
+      break;
+
+    case OPT_DefaultBoardColors:
+      lsc = ParseColorName(LIGHT_SQUARE_COLOR);
+      dsc = ParseColorName(DARK_SQUARE_COLOR);
+      wpc = ParseColorName(WHITE_PIECE_COLOR);
+      bpc = ParseColorName(BLACK_PIECE_COLOR);
+      hsc = ParseColorName(HIGHLIGHT_SQUARE_COLOR);
+      phc = ParseColorName(PREMOVE_HIGHLIGHT_COLOR);
+      mono = FALSE;
+      white= FALSE;
+      flip = FALSE;
+      CheckDlgButton(hDlg, OPT_Monochrome, FALSE);
+      CheckDlgButton(hDlg, OPT_AllWhite,   FALSE);
+      CheckDlgButton(hDlg, OPT_UpsideDown, FALSE);
+      PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);
+      PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);
+      PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);
+      PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);
+      PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);
+      PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);
+      SetBoardOptionEnables(hDlg);
+      PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
+         TRUE, mono, pieces);
+      PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
+         FALSE, mono, pieces);
+      break;
+
+    case OPT_Monochrome:
+      mono = !mono;
+      SetBoardOptionEnables(hDlg);
+      break;
+
+    case OPT_AllWhite:
+      white = !white;
+      SetBoardOptionEnables(hDlg);
+      break;
+
+    case OPT_UpsideDown:
+      flip = !flip;
+      SetBoardOptionEnables(hDlg);
+      break;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+
+VOID
+BoardOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc = MakeProcInstance((FARPROC)BoardOptionsDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_BoardOptions), hwnd,
+         (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}
+
+VariantClass
+VariantWhichRadio(HWND hDlg)
+{
+  return (IsDlgButtonChecked(hDlg, OPT_VariantFairy) ? VariantFairy :
+         (IsDlgButtonChecked(hDlg, OPT_VariantGothic) ? VariantGothic :
+         (IsDlgButtonChecked(hDlg, OPT_VariantCrazyhouse) ? VariantCrazyhouse :
+         (IsDlgButtonChecked(hDlg, OPT_VariantBughouse) ? VariantBughouse :
+         (IsDlgButtonChecked(hDlg, OPT_VariantCourier) ? VariantCourier :
+         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :
+         (IsDlgButtonChecked(hDlg, OPT_VariantShogi) ? VariantShogi :
+         (IsDlgButtonChecked(hDlg, OPT_VariantXiangqi) ? VariantXiangqi :
+         (IsDlgButtonChecked(hDlg, OPT_VariantCapablanca) ? VariantCapablanca :
+         (IsDlgButtonChecked(hDlg, OPT_VariantTwoKings) ? VariantTwoKings :
+         (IsDlgButtonChecked(hDlg, OPT_VariantKnightmate) ? VariantKnightmate :
+         (IsDlgButtonChecked(hDlg, OPT_VariantLosers) ? VariantLosers :
+         (IsDlgButtonChecked(hDlg, OPT_VariantSuicide) ? VariantSuicide :
+         (IsDlgButtonChecked(hDlg, OPT_VariantAtomic) ? VariantAtomic :
+         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :
+         (IsDlgButtonChecked(hDlg, OPT_VariantFRC) ? VariantFischeRandom :
+         (IsDlgButtonChecked(hDlg, OPT_VariantCylinder) ? VariantCylinder :
+         (IsDlgButtonChecked(hDlg, OPT_VariantFalcon) ? VariantFalcon :
+         (IsDlgButtonChecked(hDlg, OPT_VariantCRC) ? VariantCapaRandom :
+         (IsDlgButtonChecked(hDlg, OPT_VariantSuper) ? VariantSuper :
+         (IsDlgButtonChecked(hDlg, OPT_VariantBerolina) ? VariantBerolina :
+         (IsDlgButtonChecked(hDlg, OPT_VariantJanus) ? VariantJanus :
+         (IsDlgButtonChecked(hDlg, OPT_VariantWildcastle) ? VariantWildCastle :
+         (IsDlgButtonChecked(hDlg, OPT_VariantNocastle) ? VariantNoCastle :
+          VariantNormal ))))))))))))))))))))))));
+}
+
+LRESULT CALLBACK
+NewVariantDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  static Boolean  mono;
+  static VariantClass v;
+  static COLORREF lsc, dsc, wpc, bpc, hsc, phc;
+  static HBITMAP pieces[3];
+  static int n1_ok, n2_ok, n3_ok;
+
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+    /* Initialize the dialog items */
+    switch (gameInfo.variant) {
+    case VariantNormal:
+      CheckDlgButton(hDlg, OPT_VariantNormal, TRUE);
+      break;
+    case VariantCrazyhouse:
+      CheckDlgButton(hDlg, OPT_VariantCrazyhouse, TRUE);
+      break;
+    case VariantBughouse:
+      CheckDlgButton(hDlg, OPT_VariantBughouse, TRUE);
+      break;
+    case VariantShogi:
+      CheckDlgButton(hDlg, OPT_VariantShogi, TRUE);
+      break;
+    case VariantXiangqi:
+      CheckDlgButton(hDlg, OPT_VariantXiangqi, TRUE);
+      break;
+    case VariantCapablanca:
+      CheckDlgButton(hDlg, OPT_VariantCapablanca, TRUE);
+      break;
+    case VariantGothic:
+      CheckDlgButton(hDlg, OPT_VariantGothic, TRUE);
+      break;
+    case VariantCourier:
+      CheckDlgButton(hDlg, OPT_VariantCourier, TRUE);
+      break;
+    case VariantKnightmate:
+      CheckDlgButton(hDlg, OPT_VariantKnightmate, TRUE);
+      break;
+    case VariantTwoKings:
+      CheckDlgButton(hDlg, OPT_VariantTwoKings, TRUE);
+      break;
+    case VariantFairy:
+      CheckDlgButton(hDlg, OPT_VariantFairy, TRUE);
+      break;
+    case VariantAtomic:
+      CheckDlgButton(hDlg, OPT_VariantAtomic, TRUE);
+      break;
+    case VariantSuicide:
+      CheckDlgButton(hDlg, OPT_VariantSuicide, TRUE);
+      break;
+    case VariantLosers:
+      CheckDlgButton(hDlg, OPT_VariantLosers, TRUE);
+      break;
+    case VariantShatranj:
+      CheckDlgButton(hDlg, OPT_VariantShatranj, TRUE);
+      break;
+    case VariantFischeRandom:
+      CheckDlgButton(hDlg, OPT_VariantFRC, TRUE);
+      break;
+    case VariantCapaRandom:
+      CheckDlgButton(hDlg, OPT_VariantCRC, TRUE);
+      break;
+    case VariantFalcon:
+      CheckDlgButton(hDlg, OPT_VariantFalcon, TRUE);
+      break;
+    case VariantCylinder:
+      CheckDlgButton(hDlg, OPT_VariantCylinder, TRUE);
+      break;
+    case Variant3Check:
+    case VariantSuper:
+      CheckDlgButton(hDlg, OPT_VariantSuper, TRUE);
+      break;
+    case VariantBerolina:
+      CheckDlgButton(hDlg, OPT_VariantBerolina, TRUE);
+      break;
+    case VariantJanus:
+      CheckDlgButton(hDlg, OPT_VariantJanus, TRUE);
+      break;
+    case VariantWildCastle:
+      CheckDlgButton(hDlg, OPT_VariantWildcastle, TRUE);
+      break;
+    case VariantNoCastle:
+      CheckDlgButton(hDlg, OPT_VariantNocastle, TRUE);
+      break;
+    }
+
+    SetDlgItemInt( hDlg, IDC_Files, -1, TRUE );
+    SendDlgItemMessage( hDlg, IDC_Files, EM_SETSEL, 0, -1 );
+
+    SetDlgItemInt( hDlg, IDC_Ranks, -1, TRUE );
+    SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );
+
+    SetDlgItemInt( hDlg, IDC_Holdings, -1, TRUE );
+    SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );
+
+    n1_ok = n2_ok = n3_ok = FALSE;
+
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* 
+       * if we call EndDialog() after the call to ChangeBoardSize(),
+       * then ChangeBoardSize() does not take effect, although the new
+       * boardSize is saved. Go figure...
+       */
+      EndDialog(hDlg, TRUE);
+
+      v = VariantWhichRadio(hDlg);
+      if(!appData.noChessProgram) { char *name = VariantName(v), buf[MSG_SIZ];
+       if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) {
+           /* [HGM] in protocol 2 we check if variant is suported by engine */
+           sprintf(buf, "Variant %s not supported by %s", name, first.tidy);
+           DisplayError(buf, 0);
+           return TRUE; /* treat as "Cancel" if first engine does not support it */
+       } else
+       if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) {
+           sprintf(buf, "Warning: second engine (%s) does not support this!", second.tidy);
+           DisplayError(buf, 0);   /* use of second engine is optional; only warn user */
+       }
+      }
+
+      gameInfo.variant = v;
+      appData.variant = VariantName(v);
+
+      appData.NrFiles = (int) GetDlgItemInt(hDlg, IDC_Files, NULL, FALSE );
+      appData.NrRanks = (int) GetDlgItemInt(hDlg, IDC_Ranks, NULL, FALSE );
+      appData.holdingsSize = (int) GetDlgItemInt(hDlg, IDC_Holdings, NULL, FALSE );
+
+      if(!n1_ok) appData.NrFiles = -1;
+      if(!n2_ok) appData.NrRanks = -1;
+      if(!n3_ok) appData.holdingsSize = -1;
+
+      shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */
+      startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */
+      appData.pieceToCharTable = NULL;
+      Reset(TRUE, TRUE);
+
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    case IDC_Ranks:
+    case IDC_Files:
+    case IDC_Holdings:
+        if( HIWORD(wParam) == EN_CHANGE ) {
+
+            GetDlgItemInt(hDlg, IDC_Files, &n1_ok, FALSE );
+            GetDlgItemInt(hDlg, IDC_Ranks, &n2_ok, FALSE );
+            GetDlgItemInt(hDlg, IDC_Holdings, &n3_ok, FALSE );
+
+            /*EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok ? TRUE : FALSE );*/
+        }
+        return TRUE;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+
+VOID
+NewVariantPopup(HWND hwnd)
+{
+  FARPROC lpProc = MakeProcInstance((FARPROC)NewVariantDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_NewVariant), hwnd,
+         (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}
+
+/*---------------------------------------------------------------------------*\
+ *
+ * ICS Options Dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+
+BOOL APIENTRY
+MyCreateFont(HWND hwnd, MyFont *font)
+{
+  CHOOSEFONT cf;
+  HFONT hf;
+
+  /* Initialize members of the CHOOSEFONT structure. */
+  cf.lStructSize = sizeof(CHOOSEFONT);
+  cf.hwndOwner = hwnd;
+  cf.hDC = (HDC)NULL;
+  cf.lpLogFont = &font->lf;
+  cf.iPointSize = 0;
+  cf.Flags = CF_SCREENFONTS|/*CF_ANSIONLY|*/CF_INITTOLOGFONTSTRUCT;
+  cf.rgbColors = RGB(0,0,0);
+  cf.lCustData = 0L;
+  cf.lpfnHook = (LPCFHOOKPROC)NULL;
+  cf.lpTemplateName = (LPSTR)NULL;
+  cf.hInstance = (HINSTANCE) NULL;
+  cf.lpszStyle = (LPSTR)NULL;
+  cf.nFontType = SCREEN_FONTTYPE;
+  cf.nSizeMin = 0;
+  cf.nSizeMax = 0;
+
+  /* Display the CHOOSEFONT common-dialog box. */
+  if (!ChooseFont(&cf)) {
+    return FALSE;
+  }
+
+  /* Create a logical font based on the user's   */
+  /* selection and return a handle identifying   */
+  /* that font. */
+  hf = CreateFontIndirect(cf.lpLogFont);
+  if (hf == NULL) {
+    return FALSE;
+  }
+
+  font->hf = hf;
+  font->mfp.pointSize = (float) (cf.iPointSize / 10.0);
+  font->mfp.bold = (font->lf.lfWeight >= FW_BOLD);
+  font->mfp.italic = font->lf.lfItalic;
+  font->mfp.underline = font->lf.lfUnderline;
+  font->mfp.strikeout = font->lf.lfStrikeOut;
+  strcpy(font->mfp.faceName, font->lf.lfFaceName);
+  return TRUE;
+}
+
+
+VOID
+UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca)
+{
+  CHARFORMAT cf;
+  cf.cbSize = sizeof(CHARFORMAT);
+  cf.dwMask = 
+    CFM_COLOR|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE;
+  cf.crTextColor = mca->color;
+  cf.dwEffects = mca->effects;
+  strcpy(cf.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName);
+  /* 
+   * The 20.0 below is in fact documented. yHeight is expressed in twips.
+   * A twip is 1/20 of a font's point size. See documentation of CHARFORMAT.
+   * --msw
+   */
+  cf.yHeight = (int)(font[boardSize][CONSOLE_FONT]->mfp.pointSize * 20.0 + 0.5);
+  cf.bCharSet = DEFAULT_CHARSET; /* should be ignored anyway */
+  cf.bPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
+  SendDlgItemMessage(hDlg, id, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+}
+
+LRESULT CALLBACK
+ColorizeTextDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  static MyColorizeAttribs mca;
+  static ColorClass cc;
+  COLORREF background = (COLORREF)0;
+
+  switch (message) {
+  case WM_INITDIALOG:
+    cc = (ColorClass)lParam;
+    mca = colorizeAttribs[cc];
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+    /* Initialize the dialog items */
+    CheckDlgButton(hDlg, OPT_Bold, (mca.effects & CFE_BOLD) != 0);
+    CheckDlgButton(hDlg, OPT_Italic, (mca.effects & CFE_ITALIC) != 0);
+    CheckDlgButton(hDlg, OPT_Underline, (mca.effects & CFE_UNDERLINE) != 0);
+    CheckDlgButton(hDlg, OPT_Strikeout, (mca.effects & CFE_STRIKEOUT) != 0);
+
+    /* get the current background color from the parent window */
+    SendMessage(GetWindow(hDlg, GW_OWNER),WM_COMMAND, 
+               (WPARAM)WM_USER_GetConsoleBackground, 
+               (LPARAM)&background);
+
+    /* set the background color */
+    SendDlgItemMessage(hDlg, OPT_Sample, EM_SETBKGNDCOLOR, FALSE, background);
+
+    SetDlgItemText(hDlg, OPT_Sample, mca.name);
+    UpdateSampleText(hDlg, OPT_Sample, &mca);
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* Read changed options from the dialog box */
+      colorizeAttribs[cc] = mca;
+      textAttribs[cc].color = mca.color;
+      textAttribs[cc].effects = mca.effects;
+      Colorize(currentColorClass, TRUE);
+      if (cc == ColorNormal) {
+       CHARFORMAT cf;
+       cf.cbSize = sizeof(CHARFORMAT);
+       cf.dwMask = CFM_COLOR;
+       cf.crTextColor = mca.color;
+       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, 
+         EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+      }
+      EndDialog(hDlg, TRUE);
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    case OPT_ChooseColor:
+      ChangeColor(hDlg, &mca.color);
+      UpdateSampleText(hDlg, OPT_Sample, &mca);
+      return TRUE;
+
+    default:
+      mca.effects =
+       (IsDlgButtonChecked(hDlg, OPT_Bold) ? CFE_BOLD : 0) |
+       (IsDlgButtonChecked(hDlg, OPT_Italic) ? CFE_ITALIC : 0) |
+       (IsDlgButtonChecked(hDlg, OPT_Underline) ? CFE_UNDERLINE : 0) |
+       (IsDlgButtonChecked(hDlg, OPT_Strikeout) ? CFE_STRIKEOUT : 0);
+      UpdateSampleText(hDlg, OPT_Sample, &mca);
+      break;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+VOID
+ColorizeTextPopup(HWND hwnd, ColorClass cc)
+{
+  FARPROC lpProc;
+
+  lpProc = MakeProcInstance((FARPROC)ColorizeTextDialog, hInst);
+  DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_Colorize),
+    hwnd, (DLGPROC)lpProc, (LPARAM) cc);
+  FreeProcInstance(lpProc);
+}
+
+VOID
+SetIcsOptionEnables(HWND hDlg)
+{
+#define ENABLE_DLG_ITEM(x,y) EnableWindow(GetDlgItem(hDlg,(x)), (y))
+
+  UINT state = IsDlgButtonChecked(hDlg, OPT_Premove);
+  ENABLE_DLG_ITEM(OPT_PremoveWhite, state);
+  ENABLE_DLG_ITEM(OPT_PremoveWhiteText, state);
+  ENABLE_DLG_ITEM(OPT_PremoveBlack, state);
+  ENABLE_DLG_ITEM(OPT_PremoveBlackText, state);
+
+  ENABLE_DLG_ITEM(OPT_IcsAlarmTime, IsDlgButtonChecked(hDlg, OPT_IcsAlarm));
+
+#undef ENABLE_DLG_ITEM
+}
+
+
+LRESULT CALLBACK
+IcsOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  char buf[MSG_SIZ];
+  int number;
+  int i;
+  static COLORREF cbc;
+  static MyColorizeAttribs *mca;
+  COLORREF *colorref;
+
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+
+    mca = colorizeAttribs;
+
+    for (i=0; i < NColorClasses - 1; i++) {
+      mca[i].color   = textAttribs[i].color;
+      mca[i].effects = textAttribs[i].effects;
+    }
+    cbc = consoleBackgroundColor;
+
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+
+    /* Initialize the dialog items */
+#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))
+
+    CHECK_BOX(OPT_AutoComment, appData.autoComment);
+    CHECK_BOX(OPT_AutoObserve, appData.autoObserve);
+    CHECK_BOX(OPT_GetMoveList, appData.getMoveList);
+    CHECK_BOX(OPT_LocalLineEditing, appData.localLineEditing);
+    CHECK_BOX(OPT_QuietPlay, appData.quietPlay);
+    CHECK_BOX(OPT_Premove, appData.premove);
+    CHECK_BOX(OPT_PremoveWhite, appData.premoveWhite);
+    CHECK_BOX(OPT_PremoveBlack, appData.premoveBlack);
+    CHECK_BOX(OPT_IcsAlarm, appData.icsAlarm);
+    CHECK_BOX(OPT_DontColorize, !appData.colorize);
+
+#undef CHECK_BOX
+
+    sprintf(buf, "%d", appData.icsAlarmTime / 1000);
+    SetDlgItemText(hDlg, OPT_IcsAlarmTime, buf);
+    SetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText);
+    SetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText);
+
+    SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);
+    SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);
+    SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);
+    SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);
+    SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);
+    SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);
+    SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);
+    SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);
+    SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);
+    SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);
+
+    SetDlgItemText(hDlg, OPT_SampleShout,     mca[ColorShout].name);
+    SetDlgItemText(hDlg, OPT_SampleSShout,    mca[ColorSShout].name);
+    SetDlgItemText(hDlg, OPT_SampleChannel1,  mca[ColorChannel1].name);
+    SetDlgItemText(hDlg, OPT_SampleChannel,   mca[ColorChannel].name);
+    SetDlgItemText(hDlg, OPT_SampleKibitz,    mca[ColorKibitz].name);
+    SetDlgItemText(hDlg, OPT_SampleTell,      mca[ColorTell].name);
+    SetDlgItemText(hDlg, OPT_SampleChallenge, mca[ColorChallenge].name);
+    SetDlgItemText(hDlg, OPT_SampleRequest,   mca[ColorRequest].name);
+    SetDlgItemText(hDlg, OPT_SampleSeek,      mca[ColorSeek].name);
+    SetDlgItemText(hDlg, OPT_SampleNormal,    mca[ColorNormal].name);
+
+    UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);
+    UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);
+    UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);
+    UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);
+    UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);
+    UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);
+    UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);
+    UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);
+    UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);
+    UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);
+
+    SetIcsOptionEnables(hDlg);
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+
+    case WM_USER_GetConsoleBackground: 
+      /* the ColorizeTextDialog needs the current background color */
+      colorref = (COLORREF *)lParam;
+      *colorref = cbc;
+      return FALSE;
+
+    case IDOK:
+      /* Read changed options from the dialog box */
+      GetDlgItemText(hDlg, OPT_IcsAlarmTime, buf, MSG_SIZ);
+      if (sscanf(buf, "%d", &number) != 1 || (number < 0)){
+         MessageBox(hDlg, "Invalid ICS Alarm Time",
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
+         return FALSE;
+      }
+
+#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))
+
+      appData.icsAlarm         = IS_CHECKED(OPT_IcsAlarm);
+      appData.premove          = IS_CHECKED(OPT_Premove);
+      appData.premoveWhite     = IS_CHECKED(OPT_PremoveWhite);
+      appData.premoveBlack     = IS_CHECKED(OPT_PremoveBlack);
+      appData.autoComment      = IS_CHECKED(OPT_AutoComment);
+      appData.autoObserve      = IS_CHECKED(OPT_AutoObserve);
+      appData.getMoveList      = IS_CHECKED(OPT_GetMoveList);
+      appData.localLineEditing = IS_CHECKED(OPT_LocalLineEditing);
+      appData.quietPlay        = IS_CHECKED(OPT_QuietPlay);
+
+#undef IS_CHECKED
+
+      appData.icsAlarmTime = number * 1000;
+      GetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText, 5);
+      GetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText, 5);
+
+      if (appData.localLineEditing) {
+       DontEcho();
+       EchoOn();
+      } else {
+       DoEcho();
+       EchoOff();
+      }
+
+      appData.colorize =
+       (Boolean)!IsDlgButtonChecked(hDlg, OPT_DontColorize);
+
+      if (!appData.colorize) {
+       CHARFORMAT cf;
+       COLORREF background = ParseColorName(COLOR_BKGD);
+       /*
+       SetDefaultTextAttribs();
+        Colorize(currentColorClass);
+       */
+       cf.cbSize = sizeof(CHARFORMAT);
+       cf.dwMask = CFM_COLOR;
+       cf.crTextColor = ParseColorName(COLOR_NORMAL);
+
+       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, 
+         EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+        SendDlgItemMessage(hwndConsole, OPT_ConsoleText, 
+         EM_SETBKGNDCOLOR, FALSE, background);
+       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, 
+         EM_SETBKGNDCOLOR, FALSE, background);
+      }
+
+      if (cbc != consoleBackgroundColor) {
+       consoleBackgroundColor = cbc;
+       if (appData.colorize) {
+         SendDlgItemMessage(hwndConsole, OPT_ConsoleText, 
+           EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);
+         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, 
+           EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);
+       }
+      }
+
+      for (i=0; i < NColorClasses - 1; i++) {
+       textAttribs[i].color   = mca[i].color;
+       textAttribs[i].effects = mca[i].effects;
+      }
+
+      EndDialog(hDlg, TRUE);
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    case OPT_ChooseShoutColor:
+      ColorizeTextPopup(hDlg, ColorShout);
+      UpdateSampleText(hDlg, OPT_SampleShout, &mca[ColorShout]);
+      break;
+
+    case OPT_ChooseSShoutColor:
+      ColorizeTextPopup(hDlg, ColorSShout);
+      UpdateSampleText(hDlg, OPT_SampleSShout, &mca[ColorSShout]);
+      break;
+
+    case OPT_ChooseChannel1Color:
+      ColorizeTextPopup(hDlg, ColorChannel1);
+      UpdateSampleText(hDlg, OPT_SampleChannel1, 
+                      &colorizeAttribs[ColorChannel1]);
+      break;
+
+    case OPT_ChooseChannelColor:
+      ColorizeTextPopup(hDlg, ColorChannel);
+      UpdateSampleText(hDlg, OPT_SampleChannel, &mca[ColorChannel]);
+      break;
+
+    case OPT_ChooseKibitzColor:
+      ColorizeTextPopup(hDlg, ColorKibitz);
+      UpdateSampleText(hDlg, OPT_SampleKibitz, &mca[ColorKibitz]);
+      break;
+
+    case OPT_ChooseTellColor:
+      ColorizeTextPopup(hDlg, ColorTell);
+      UpdateSampleText(hDlg, OPT_SampleTell, &mca[ColorTell]);
+      break;
+
+    case OPT_ChooseChallengeColor:
+      ColorizeTextPopup(hDlg, ColorChallenge);
+      UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);
+      break;
+
+    case OPT_ChooseRequestColor:
+      ColorizeTextPopup(hDlg, ColorRequest);
+      UpdateSampleText(hDlg, OPT_SampleRequest, &mca[ColorRequest]);
+      break;
+
+    case OPT_ChooseSeekColor:
+      ColorizeTextPopup(hDlg, ColorSeek);
+      UpdateSampleText(hDlg, OPT_SampleSeek, &mca[ColorSeek]);
+      break;
+
+    case OPT_ChooseNormalColor:
+      ColorizeTextPopup(hDlg, ColorNormal);
+      UpdateSampleText(hDlg, OPT_SampleNormal, &mca[ColorNormal]);
+      break;
+
+    case OPT_ChooseBackgroundColor:
+      if (ChangeColor(hDlg, &cbc)) {
+       SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);
+       SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);
+       SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);
+       SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);
+       SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);
+       SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);
+       SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);
+       SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);
+       SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);
+       SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);
+      }
+      break;
+
+    case OPT_DefaultColors:
+      for (i=0; i < NColorClasses - 1; i++)
+       ParseAttribs(&mca[i].color, 
+                    &mca[i].effects,
+                    defaultTextAttribs[i]);
+
+      cbc = ParseColorName(COLOR_BKGD);
+      SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);
+      SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);
+      SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);
+      SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);
+      SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);
+      SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);
+      SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);
+      SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);
+      SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);
+      SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);
+
+      UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);
+      UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);
+      UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);
+      UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);
+      UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);
+      UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);
+      UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);
+      UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);
+      UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);
+      UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);
+      break;
+
+    default:
+      SetIcsOptionEnables(hDlg);
+      break;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+VOID
+IcsOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc = MakeProcInstance((FARPROC)IcsOptionsDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_IcsOptions), hwnd,
+           (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}
+
+/*---------------------------------------------------------------------------*\
+ *
+ * Fonts Dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+
+VOID
+SetSampleFontText(HWND hwnd, int id, const MyFont *mf)
+{
+  char buf[MSG_SIZ];
+  HWND hControl;
+  HDC hdc;
+  CHARFORMAT cf;
+  SIZE size;
+  RECT rectClient, rectFormat;
+  HFONT oldFont;
+  POINT center;
+  int len;
+
+  len = sprintf(buf, "%.0f pt. %s%s%s\n",
+               mf->mfp.pointSize, mf->mfp.faceName,
+               mf->mfp.bold ? " bold" : "",
+               mf->mfp.italic ? " italic" : "");
+  SetDlgItemText(hwnd, id, buf);
+
+  hControl = GetDlgItem(hwnd, id);
+  hdc = GetDC(hControl);
+  SetMapMode(hdc, MM_TEXT);    /* 1 pixel == 1 logical unit */
+  oldFont = SelectObject(hdc, mf->hf);
+  
+  /* get number of logical units necessary to display font name */
+  GetTextExtentPoint32(hdc, buf, len, &size);
+
+  /* calculate formatting rectangle in the rich edit control.  
+   * May be larger or smaller than the actual control.
+   */
+  GetClientRect(hControl, &rectClient);
+  center.x = (rectClient.left + rectClient.right) / 2;
+  center.y = (rectClient.top  + rectClient.bottom) / 2;
+  rectFormat.top    = center.y - (size.cy / 2) - 1;
+  rectFormat.bottom = center.y + (size.cy / 2) + 1;
+  rectFormat.left   = center.x - (size.cx / 2) - 1;
+  rectFormat.right  = center.x + (size.cx / 2) + 1;
+
+#if 0
+  fprintf(debugFP, "\nfont: %s\n"
+                   "center.x   %d, centerY %d\n"
+                  "size.cx    %d, size.cy %d\n"
+                  "client.top %d, bottom %d, left %d, right %d\n"
+                  "format.top %d, bottom %d, left %d, right %d\n",
+                  buf,
+                  center.x, center.y,
+                  size.cx, size.cy,
+                  rectClient.top, rectClient.bottom, rectClient.left,
+                  rectClient.right,
+                  rectFormat.top, rectFormat.bottom, rectFormat.left,
+                  rectFormat.right);
+#endif
+
+  cf.cbSize = sizeof(CHARFORMAT);
+  cf.dwMask = CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_BOLD|CFM_ITALIC;
+  cf.dwEffects = 0;
+  if (mf->lf.lfWeight == FW_BOLD) cf.dwEffects |= CFE_BOLD;
+  if (mf->lf.lfItalic) cf.dwEffects |= CFE_ITALIC;
+  strcpy(cf.szFaceName, mf->mfp.faceName);
+  /*
+   * yHeight is expressed in twips.  A twip is 1/20 of a font's point
+   * size. See documentation of CHARFORMAT.  --msw
+   */
+  cf.yHeight = (int)(mf->mfp.pointSize * 20.0 + 0.5);
+  cf.bCharSet = mf->lf.lfCharSet;
+  cf.bPitchAndFamily = mf->lf.lfPitchAndFamily;
+
+  /* format the text in the rich edit control */
+  SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf);
+  SendMessage(hControl, EM_SETRECT, (WPARAM)0, (LPARAM) &rectFormat);
+
+  /* clean up */
+  SelectObject(hdc, oldFont);
+  ReleaseDC(hControl, hdc);
+}
+
+VOID
+CopyFont(MyFont *dest, const MyFont *src)
+{
+  dest->mfp.pointSize = src->mfp.pointSize;
+  dest->mfp.bold      = src->mfp.bold;
+  dest->mfp.italic    = src->mfp.italic;
+  dest->mfp.underline = src->mfp.underline;
+  dest->mfp.strikeout = src->mfp.strikeout;
+  lstrcpy(dest->mfp.faceName, src->mfp.faceName);
+  CreateFontInMF(dest);
+}
+
+
+LRESULT CALLBACK
+FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  static MyFont workFont[NUM_FONTS];
+  static BOOL firstPaint;
+  int i;
+  RECT rect;
+
+  switch (message) {
+  case WM_INITDIALOG:
+
+    /* copy the current font settings into a working copy */
+    for (i=0; i < NUM_FONTS; i++)
+      CopyFont(&workFont[i], font[boardSize][i]);
+
+    if (!appData.icsActive)
+      EnableWindow(GetDlgItem(hDlg, OPT_ChooseConsoleFont), FALSE);
+
+    firstPaint = TRUE; /* see rant below */
+
+    /* If I don't call SetFocus(), the dialog won't respond to the keyboard
+     * when first drawn. Why is this the only dialog that behaves this way? Is
+     * is the WM_PAINT stuff below?? Sigh...
+     */
+    SetFocus(GetDlgItem(hDlg, IDOK));
+    break;
+
+  case WM_PAINT:
+    /* This should not be necessary. However, if SetSampleFontText() is called
+     * in response to WM_INITDIALOG, the strings are not properly centered in
+     * the controls when the dialog first appears. I can't figure out why, so
+     * this is the workaround.  --msw
+     */
+    if (firstPaint) {
+      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);
+      firstPaint = FALSE;
+    }
+    break;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+
+    case IDOK:
+      /* again, it seems to avoid redraw problems if we call EndDialog first */
+      EndDialog(hDlg, FALSE);
+
+      /* copy modified settings back to the fonts array */
+      for (i=0; i < NUM_FONTS; i++)
+       CopyFont(font[boardSize][i], &workFont[i]);
+
+      /* a sad necessity due to the original design of having a separate
+       * console font, tags font, and comment font for each board size.  IMHO
+       * these fonts should not be dependent on the current board size.  I'm
+       * running out of time, so I am doing this hack rather than redesign the
+       * data structure. Besides, I think if I redesigned the data structure, I
+       * might break backwards compatibility with old winboard.ini files.
+       * --msw
+       */
+      for (i=0; i < NUM_SIZES; i++) {
+       CopyFont(font[i][EDITTAGS_FONT], &workFont[EDITTAGS_FONT]);
+       CopyFont(font[i][CONSOLE_FONT],  &workFont[CONSOLE_FONT]);
+       CopyFont(font[i][COMMENT_FONT],  &workFont[COMMENT_FONT]);
+       CopyFont(font[i][MOVEHISTORY_FONT],  &workFont[MOVEHISTORY_FONT]);
+      }
+      /* end sad necessity */
+
+      InitDrawingSizes(boardSize, 0);
+      InvalidateRect(hwndMain, NULL, TRUE);
+
+      if (commentDialog) {
+       SendDlgItemMessage(commentDialog, OPT_CommentText,
+         WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf, 
+         MAKELPARAM(TRUE, 0));
+       GetClientRect(GetDlgItem(commentDialog, OPT_CommentText), &rect);
+       InvalidateRect(commentDialog, &rect, TRUE);
+      }
+
+      if (editTagsDialog) {
+       SendDlgItemMessage(editTagsDialog, OPT_TagsText,
+         WM_SETFONT, (WPARAM)font[boardSize][EDITTAGS_FONT]->hf, 
+         MAKELPARAM(TRUE, 0));
+       GetClientRect(GetDlgItem(editTagsDialog, OPT_TagsText), &rect);
+       InvalidateRect(editTagsDialog, &rect, TRUE);
+      }
+
+      if( moveHistoryDialog != NULL ) {
+       SendDlgItemMessage(moveHistoryDialog, IDC_MoveHistory,
+         WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, 
+         MAKELPARAM(TRUE, 0));
+       InvalidateRect(editTagsDialog, NULL, TRUE);
+      }
+
+      if (hwndConsole) {
+       ChangedConsoleFont();
+      }
+
+      for (i=0; i<NUM_FONTS; i++)
+       DeleteObject(&workFont[i].hf);
+
+      return TRUE;
+
+    case IDCANCEL:
+      for (i=0; i<NUM_FONTS; i++)
+       DeleteObject(&workFont[i].hf);
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    case OPT_ChooseClockFont:
+      MyCreateFont(hDlg, &workFont[CLOCK_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);
+      break;
+
+    case OPT_ChooseMessageFont:
+      MyCreateFont(hDlg, &workFont[MESSAGE_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);
+      break;
+
+    case OPT_ChooseCoordFont:
+      MyCreateFont(hDlg, &workFont[COORD_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);
+      break;
+
+    case OPT_ChooseTagFont:
+      MyCreateFont(hDlg, &workFont[EDITTAGS_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);
+      break;
+
+    case OPT_ChooseCommentsFont:
+      MyCreateFont(hDlg, &workFont[COMMENT_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);
+      break;
+
+    case OPT_ChooseConsoleFont:
+      MyCreateFont(hDlg, &workFont[CONSOLE_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);
+      break;
+
+    case OPT_ChooseMoveHistoryFont:
+      MyCreateFont(hDlg, &workFont[MOVEHISTORY_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);
+      break;
+
+    case OPT_DefaultFonts:
+      for (i=0; i<NUM_FONTS; i++) {
+       DeleteObject(&workFont[i].hf);
+       ParseFontName(font[boardSize][i]->def, &workFont[i].mfp);
+       CreateFontInMF(&workFont[i]);
+      }
+      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);
+      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);
+      break;
+    }
+  }
+  return FALSE;
+}
+
+VOID
+FontsOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc = MakeProcInstance((FARPROC)FontOptionsDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_Fonts), hwnd,
+         (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}
+
+/*---------------------------------------------------------------------------*\
+ *
+ * Sounds Dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+
+
+SoundComboData soundComboData[] = {
+  {"Move", NULL},
+  {"Bell", NULL},
+  {"ICS Alarm", NULL},
+  {"ICS Win", NULL},
+  {"ICS Loss", NULL},
+  {"ICS Draw", NULL},
+  {"ICS Unfinished", NULL},
+  {"Shout", NULL},
+  {"SShout/CShout", NULL},
+  {"Channel 1", NULL},
+  {"Channel", NULL},
+  {"Kibitz", NULL},
+  {"Tell", NULL},
+  {"Challenge", NULL},
+  {"Request", NULL},
+  {"Seek", NULL},
+  {NULL, NULL},
+};
+
+
+void
+InitSoundComboData(SoundComboData *scd)
+{
+  SoundClass sc;
+  ColorClass cc;
+  int index;
+
+  /* copy current sound settings to combo array */
+
+  for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {
+    scd[sc].name = strdup(sounds[sc].name);
+  }
+  for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {
+    index = (int)cc + (int)NSoundClasses;
+    scd[index].name = strdup(textAttribs[cc].sound.name);
+  }
+}
+
+
+void
+ResetSoundComboData(SoundComboData *scd)
+{
+  while (scd->label) {
+    if (scd->name != NULL) {
+      free (scd->name);
+      scd->name = NULL;
+    }
+    scd++;
+  }
+}
+
+void
+InitSoundCombo(HWND hwndCombo, SoundComboData *scd)
+{
+  char buf[255];
+  DWORD err;
+  DWORD cnt = 0;
+  SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
+
+  /* send the labels to the combo box */
+  while (scd->label) {
+    err = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) scd->label);
+    if (err != cnt++) {
+      sprintf(buf, "InitSoundCombo(): err '%d', cnt '%d'\n",
+         err, cnt);
+      MessageBox(NULL, buf, NULL, MB_OK);
+    }
+    scd++;
+  }
+  SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);
+}
+
+int
+SoundDialogWhichRadio(HWND hDlg)
+{
+  if (IsDlgButtonChecked(hDlg, OPT_NoSound)) return OPT_NoSound;
+  if (IsDlgButtonChecked(hDlg, OPT_DefaultBeep)) return OPT_DefaultBeep;
+  if (IsDlgButtonChecked(hDlg, OPT_BuiltInSound)) return OPT_BuiltInSound;
+  if (IsDlgButtonChecked(hDlg, OPT_WavFile)) return OPT_WavFile;
+  return -1;
+}
+
+VOID
+SoundDialogSetEnables(HWND hDlg, int radio)
+{
+  EnableWindow(GetDlgItem(hDlg, OPT_BuiltInSoundName),
+              radio == OPT_BuiltInSound);
+  EnableWindow(GetDlgItem(hDlg, OPT_WavFileName), radio == OPT_WavFile);
+  EnableWindow(GetDlgItem(hDlg, OPT_BrowseSound), radio == OPT_WavFile);
+}
+
+char *
+SoundDialogGetName(HWND hDlg, int radio)
+{
+  static char buf[MSG_SIZ], buf2[MSG_SIZ], buf3[MSG_SIZ];
+  char *dummy, *ret;
+  switch (radio) {
+  case OPT_NoSound:
+  default:
+    return "";
+  case OPT_DefaultBeep:
+    return "$";
+  case OPT_BuiltInSound:
+    buf[0] = '!';
+    GetDlgItemText(hDlg, OPT_BuiltInSoundName, buf + 1, sizeof(buf) - 1);
+    return buf;
+  case OPT_WavFile:
+    GetDlgItemText(hDlg, OPT_WavFileName, buf, sizeof(buf));
+    GetCurrentDirectory(MSG_SIZ, buf3);
+    SetCurrentDirectory(installDir);
+    if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {
+      ret = buf2;
+    } else {
+      ret = buf;
+    }
+    SetCurrentDirectory(buf3);
+    return ret;
+  }
+}
+
+void
+DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name)
+{
+  int radio;
+  /* 
+   * I think it's best to clear the combo and edit boxes. It looks stupid
+   * to have a value from another sound event sitting there grayed out.
+   */
+  SetDlgItemText(hDlg, OPT_WavFileName, "");
+  SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
+
+  if (appData.debugMode)
+      fprintf(debugFP, "DisplaySelectedSound(,,'%s'):\n", name);
+  switch (name[0]) {
+  case NULLCHAR:
+    radio = OPT_NoSound;
+    break;
+  case '$':
+    if (name[1] == NULLCHAR) {
+      radio = OPT_DefaultBeep;
+    } else {
+      radio = OPT_WavFile;
+      SetDlgItemText(hDlg, OPT_WavFileName, name);
+    }
+    break;
+  case '!':
+    if (name[1] == NULLCHAR) {
+      radio = OPT_NoSound;
+    } else {
+      radio = OPT_BuiltInSound;
+      if (SendMessage(hCombo, CB_SELECTSTRING, (WPARAM) -1, 
+                     (LPARAM) (name + 1)) == CB_ERR) {
+       SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
+       SendMessage(hCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) (name + 1));
+      }
+    }
+    break;
+  default:
+    radio = OPT_WavFile;
+    SetDlgItemText(hDlg, OPT_WavFileName, name);
+    break;
+  }
+  SoundDialogSetEnables(hDlg, radio);
+  CheckRadioButton(hDlg, OPT_NoSound, OPT_WavFile, radio);
+}
+    
+
+char *builtInSoundNames[] = BUILT_IN_SOUND_NAMES;
+
+LRESULT CALLBACK
+SoundOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  static HWND hSoundCombo;
+  static DWORD index;
+  static HWND hBISN;
+  int radio;
+  MySound tmp;
+  FILE *f;
+  char buf[MSG_SIZ];
+  char *newName;
+  SoundClass sc;
+  ColorClass cc;
+  SoundComboData *scd;
+
+  switch (message) {
+  case WM_INITDIALOG:
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+
+    /* Initialize the built-in sounds combo */
+    hBISN = GetDlgItem(hDlg, OPT_BuiltInSoundName);
+     InitComboStrings(hBISN, builtInSoundNames);
+
+    /* Initialize the  sound events combo */
+    index = 0;
+    InitSoundComboData(soundComboData);
+    hSoundCombo = GetDlgItem(hDlg, CBO_Sounds);
+    InitSoundCombo(hSoundCombo, soundComboData);
+
+    /* update the dialog */
+    DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+
+    if (((HWND)lParam == hSoundCombo) && 
+       (HIWORD(wParam) == CBN_SELCHANGE)) {
+      /* 
+       * the user has selected a new sound event. We must store the name for
+       * the previously selected event, then retrieve the name for the
+       * newly selected event and update the dialog. 
+       */
+      radio = SoundDialogWhichRadio(hDlg);
+      newName = strdup(SoundDialogGetName(hDlg, radio));
+      
+      if (strcmp(newName, soundComboData[index].name) != 0) {
+       free(soundComboData[index].name);
+       soundComboData[index].name = newName;
+      } else {
+       free(newName);
+       newName = NULL;
+      }
+      /* now get the settings for the newly selected event */
+      index = SendMessage(hSoundCombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
+      DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);
+      
+      return TRUE;
+    }
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* 
+       * save the name for the currently selected sound event 
+       */
+      radio = SoundDialogWhichRadio(hDlg);
+      newName = strdup(SoundDialogGetName(hDlg, radio));
+
+      if (strcmp(soundComboData[index].name, newName) != 0) {
+       free(soundComboData[index].name);
+       soundComboData[index].name = newName;
+      } else {
+       free(newName);
+       newName = NULL;
+      }
+
+      /* save all the sound names that changed and load the sounds */
+
+      for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {
+       if (strcmp(soundComboData[sc].name, sounds[sc].name) != 0) {
+         free(sounds[sc].name);
+         sounds[sc].name = strdup(soundComboData[sc].name);
+         MyLoadSound(&sounds[sc]);
+       }
+      }
+      for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {
+       index = (int)cc + (int)NSoundClasses;
+       if (strcmp(soundComboData[index].name, 
+                  textAttribs[cc].sound.name) != 0) {
+         free(textAttribs[cc].sound.name);
+         textAttribs[cc].sound.name = strdup(soundComboData[index].name);
+         MyLoadSound(&textAttribs[cc].sound);
+       }
+      }
+
+      ResetSoundComboData(soundComboData);
+      EndDialog(hDlg, TRUE);
+      return TRUE;
+
+    case IDCANCEL:
+      ResetSoundComboData(soundComboData);
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    case OPT_DefaultSounds:
+      /* can't use SetDefaultSounds() because we need to be able to "undo" if
+       * user selects "Cancel" later on. So we do it the hard way here.
+       */
+      scd = &soundComboData[0];
+      while (scd->label != NULL) {
+       if (scd->name != NULL) free(scd->name);
+       scd->name = strdup("");
+       scd++;
+      }
+      free(soundComboData[(int)SoundBell].name);
+      soundComboData[(int)SoundBell].name = strdup(SOUND_BELL);
+      DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);
+      break;
+
+    case OPT_PlaySound:
+      radio = SoundDialogWhichRadio(hDlg);
+      tmp.name = strdup(SoundDialogGetName(hDlg, radio));
+      tmp.data = NULL;
+      MyLoadSound(&tmp);
+      MyPlaySound(&tmp);
+      if (tmp.data  != NULL) free(tmp.data);
+      if (tmp.name != NULL) free(tmp.name);
+      return TRUE;
+
+    case OPT_BrowseSound:
+      f = OpenFileDialog(hDlg, "rb", NULL, "wav", SOUND_FILT,
+       "Browse for Sound File", NULL, NULL, buf);
+      if (f != NULL) {
+       fclose(f);
+       SetDlgItemText(hDlg, OPT_WavFileName, buf);
+      }
+      return TRUE;
+
+    default:
+      radio = SoundDialogWhichRadio(hDlg);
+      SoundDialogSetEnables(hDlg, radio);
+      break;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+
+VOID SoundOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc;
+
+  lpProc = MakeProcInstance((FARPROC)SoundOptionsDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_Sound), hwnd, (DLGPROC)lpProc);
+  FreeProcInstance(lpProc);
+}
+
+
+/*---------------------------------------------------------------------------*\
+ *
+ * Comm Port dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+
+
+#define FLOW_NONE   0
+#define FLOW_XOFF   1
+#define FLOW_CTS    2
+#define FLOW_DSR    3
+
+#define PORT_NONE
+
+ComboData cdPort[]     = { {"None", PORT_NONE}, {"COM1", 1}, {"COM2", 2},
+                          {"COM3", 3}, {"COM4", 4}, {NULL, 0} };
+ComboData cdDataRate[] = { {"110", 110}, {"300", 300}, {"600", 600}, {"1200", 1200},
+                          {"2400", 2400}, {"4800", 4800}, {"9600", 9600}, {"19200", 19200},
+                          {"38400", 38400}, {NULL, 0} };
+ComboData cdDataBits[] = { {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {NULL, 0} };
+ComboData cdParity[]   = { {"None", NOPARITY}, {"Odd", ODDPARITY}, {"Even", EVENPARITY},
+                          {"Mark", MARKPARITY}, {"Space", SPACEPARITY}, {NULL, 0} };
+ComboData cdStopBits[] = { {"1", ONESTOPBIT}, {"1.5", ONE5STOPBITS},
+                          {"2", TWOSTOPBITS}, {NULL, 0} };
+ComboData cdFlow[]     = { {"None", FLOW_NONE}, {"Xoff/Xon", FLOW_XOFF}, {"CTS", FLOW_CTS},
+                          {"DSR", FLOW_DSR}, {NULL, 0} };
+
+
+VOID
+ParseCommSettings(char *arg, DCB *dcb)
+{
+  int dataRate, count;
+  char bits[MSG_SIZ], parity[MSG_SIZ], stopBits[MSG_SIZ], flow[MSG_SIZ];
+  ComboData *cd;
+  count = sscanf(arg, "%d%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]",
+    &dataRate, bits, parity, stopBits, flow);
+  if (count != 5) goto cant_parse;
+  dcb->BaudRate = dataRate;
+  cd = cdDataBits;
+  while (cd->label != NULL) {
+    if (StrCaseCmp(cd->label, bits) == 0) {
+      dcb->ByteSize = cd->value;
+      break;
+    }
+    cd++;
+  }
+  if (cd->label == NULL) goto cant_parse;
+  cd = cdParity;
+  while (cd->label != NULL) {
+    if (StrCaseCmp(cd->label, parity) == 0) {
+      dcb->Parity = cd->value;
+      break;
+    }
+    cd++;
+  }
+  if (cd->label == NULL) goto cant_parse;
+  cd = cdStopBits;
+  while (cd->label != NULL) {
+    if (StrCaseCmp(cd->label, stopBits) == 0) {
+      dcb->StopBits = cd->value;
+      break;
+    }
+    cd++;
+  }
+  cd = cdFlow;
+  if (cd->label == NULL) goto cant_parse;
+  while (cd->label != NULL) {
+    if (StrCaseCmp(cd->label, flow) == 0) {
+      switch (cd->value) {
+      case FLOW_NONE:
+       dcb->fOutX = FALSE;
+       dcb->fOutxCtsFlow = FALSE;
+       dcb->fOutxDsrFlow = FALSE;
+       break;
+      case FLOW_CTS:
+       dcb->fOutX = FALSE;
+       dcb->fOutxCtsFlow = TRUE;
+       dcb->fOutxDsrFlow = FALSE;
+       break;
+      case FLOW_DSR:
+       dcb->fOutX = FALSE;
+       dcb->fOutxCtsFlow = FALSE;
+       dcb->fOutxDsrFlow = TRUE;
+       break;
+      case FLOW_XOFF:
+       dcb->fOutX = TRUE;
+       dcb->fOutxCtsFlow = FALSE;
+       dcb->fOutxDsrFlow = FALSE;
+       break;
+      }
+      break;
+    }
+    cd++;
+  }
+  if (cd->label == NULL) goto cant_parse;
+  return;
+cant_parse:
+    ExitArgError("Can't parse com port settings", arg);
+}
+
+
+VOID PrintCommSettings(FILE *f, char *name, DCB *dcb)
+{
+  char *flow = "??", *parity = "??", *stopBits = "??";
+  ComboData *cd;
+  
+  cd = cdParity;
+  while (cd->label != NULL) {
+    if (dcb->Parity == cd->value) {
+      parity = cd->label;
+      break;
+    }
+    cd++;
+  }
+  cd = cdStopBits;
+  while (cd->label != NULL) {
+    if (dcb->StopBits == cd->value) {
+      stopBits = cd->label;
+      break;
+    }
+    cd++;
+  }
+  if (dcb->fOutX) {
+    flow = cdFlow[FLOW_XOFF].label;
+  } else if (dcb->fOutxCtsFlow) {
+    flow = cdFlow[FLOW_CTS].label;
+  } else if (dcb->fOutxDsrFlow) {
+    flow = cdFlow[FLOW_DSR].label;
+  } else {
+    flow = cdFlow[FLOW_NONE].label;
+  }
+  fprintf(f, "/%s=%d,%d,%s,%s,%s\n", name,
+    dcb->BaudRate, dcb->ByteSize, parity, stopBits, flow);
+}
+
+
+void
+InitCombo(HANDLE hwndCombo, ComboData *cd)
+{
+  SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
+
+  while (cd->label != NULL) {
+    SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) cd->label);
+    cd++;
+  }
+}
+
+void
+SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value)
+{
+  int i;
+
+  i = 0;
+  while (cd->label != NULL) {
+    if (cd->value == value) {
+      SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) i, (LPARAM) 0);
+      return;
+    }
+    cd++;
+    i++;
+  }
+}
+
+LRESULT CALLBACK
+CommPortOptionsDialog(HWND hDlg, UINT message, WPARAM wParam,  LPARAM lParam)
+{
+  char buf[MSG_SIZ];
+  HANDLE hwndCombo;
+  char *p;
+  LRESULT index;
+  unsigned value;
+  int err;
+
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow(hDlg, GW_OWNER));
+    /* Initialize the dialog items */
+    /* !! There should probably be some synchronization
+       in accessing hCommPort and dcb.  Or does modal nature
+       of this dialog box do it for us?
+       */
+    hwndCombo = GetDlgItem(hDlg, OPT_Port);
+    InitCombo(hwndCombo, cdPort);
+    p = strrchr(appData.icsCommPort, '\\');
+    if (p++ == NULL) p = appData.icsCommPort;
+    if ((*p == '\0') ||
+       (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) p) == CB_ERR)) {
+      SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) "None");
+    }
+    EnableWindow(hwndCombo, hCommPort == NULL); /*!! don't allow change for now*/
+
+    hwndCombo = GetDlgItem(hDlg, OPT_DataRate);
+    InitCombo(hwndCombo, cdDataRate);
+    sprintf(buf, "%u", dcb.BaudRate);
+    if (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) buf) == CB_ERR) {
+      SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
+      SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);
+    }
+
+    hwndCombo = GetDlgItem(hDlg, OPT_Bits);
+    InitCombo(hwndCombo, cdDataBits);
+    SelectComboValue(hwndCombo, cdDataBits, dcb.ByteSize);
+
+    hwndCombo = GetDlgItem(hDlg, OPT_Parity);
+    InitCombo(hwndCombo, cdParity);
+    SelectComboValue(hwndCombo, cdParity, dcb.Parity);
+
+    hwndCombo = GetDlgItem(hDlg, OPT_StopBits);
+    InitCombo(hwndCombo, cdStopBits);
+    SelectComboValue(hwndCombo, cdStopBits, dcb.StopBits);
+
+    hwndCombo = GetDlgItem(hDlg, OPT_Flow);
+    InitCombo(hwndCombo, cdFlow);
+    if (dcb.fOutX) {
+      SelectComboValue(hwndCombo, cdFlow, FLOW_XOFF);
+    } else if (dcb.fOutxCtsFlow) {
+      SelectComboValue(hwndCombo, cdFlow, FLOW_CTS);
+    } else if (dcb.fOutxDsrFlow) {
+      SelectComboValue(hwndCombo, cdFlow, FLOW_DSR);
+    } else {
+      SelectComboValue(hwndCombo, cdFlow, FLOW_NONE);
+    }
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* Read changed options from the dialog box */
+#ifdef NOTDEF
+      /* !! Currently we can't change comm ports in midstream */
+      hwndCombo = GetDlgItem(hDlg, OPT_Port);
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
+      if (index == PORT_NONE) {
+       appData.icsCommPort = "";
+       if (hCommPort != NULL) {
+         CloseHandle(hCommPort);
+         hCommPort = NULL;
+       }
+       EndDialog(hDlg, TRUE);
+       return TRUE;
+      }
+      SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);
+      appData.icsCommPort = strdup(buf);
+      if (hCommPort != NULL) {
+       CloseHandle(hCommPort);
+       hCommPort = NULL;
+      }
+      /* now what?? can't really do this; have to fix up the ChildProc
+        and InputSource records for the comm port that we gave to the
+        back end. */
+#endif /*NOTDEF*/
+
+      hwndCombo = GetDlgItem(hDlg, OPT_DataRate);
+      SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);
+      if (sscanf(buf, "%u", &value) != 1) {
+       MessageBox(hDlg, "Invalid data rate",
+                  "Option Error", MB_OK|MB_ICONEXCLAMATION);
+       return TRUE;
+      }
+      dcb.BaudRate = value;
+
+      hwndCombo = GetDlgItem(hDlg, OPT_Bits);
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
+      dcb.ByteSize = cdDataBits[index].value;
+
+      hwndCombo = GetDlgItem(hDlg, OPT_Parity);
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
+      dcb.Parity = cdParity[index].value;
+
+      hwndCombo = GetDlgItem(hDlg, OPT_StopBits);
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
+      dcb.StopBits = cdStopBits[index].value;
+
+      hwndCombo = GetDlgItem(hDlg, OPT_Flow);
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
+      switch (cdFlow[index].value) {
+      case FLOW_NONE:
+       dcb.fOutX = FALSE;
+       dcb.fOutxCtsFlow = FALSE;
+       dcb.fOutxDsrFlow = FALSE;
+       break;
+      case FLOW_CTS:
+       dcb.fOutX = FALSE;
+       dcb.fOutxCtsFlow = TRUE;
+       dcb.fOutxDsrFlow = FALSE;
+       break;
+      case FLOW_DSR:
+       dcb.fOutX = FALSE;
+       dcb.fOutxCtsFlow = FALSE;
+       dcb.fOutxDsrFlow = TRUE;
+       break;
+      case FLOW_XOFF:
+       dcb.fOutX = TRUE;
+       dcb.fOutxCtsFlow = FALSE;
+       dcb.fOutxDsrFlow = FALSE;
+       break;
+      }
+      if (!SetCommState(hCommPort, (LPDCB) &dcb)) {
+       err = GetLastError();
+       switch(MessageBox(hDlg, 
+                        "Failed to set comm port state;\r\ninvalid options?",
+                        "Option Error", MB_ABORTRETRYIGNORE|MB_ICONQUESTION)) {
+       case IDABORT:
+         DisplayFatalError("Failed to set comm port state", err, 1);
+         exit(1);  /*is it ok to do this from here?*/
+
+       case IDRETRY:
+         return TRUE;
+
+       case IDIGNORE:
+         EndDialog(hDlg, TRUE);
+         return TRUE;
+       }
+      }
+
+      EndDialog(hDlg, TRUE);
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    default:
+      break;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+VOID
+CommPortOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc = MakeProcInstance((FARPROC)CommPortOptionsDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_CommPort), hwnd, (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}
+
+/*---------------------------------------------------------------------------*\
+ *
+ * Load Options dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+
+VOID
+SetLoadOptionEnables(HWND hDlg)
+{
+  UINT state;
+
+  state = IsDlgButtonChecked(hDlg, OPT_Autostep);
+  EnableWindow(GetDlgItem(hDlg, OPT_ASTimeDelay), state);
+  EnableWindow(GetDlgItem(hDlg, OPT_AStext1), state);
+}
+
+LRESULT CALLBACK
+LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  char buf[MSG_SIZ];
+  float fnumber;
+
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+    /* Initialize the dialog items */
+    if (appData.timeDelay >= 0.0) {
+      CheckDlgButton(hDlg, OPT_Autostep, TRUE);
+      sprintf(buf, "%.2g", appData.timeDelay);
+      SetDlgItemText(hDlg, OPT_ASTimeDelay, buf);
+    } else {
+      CheckDlgButton(hDlg, OPT_Autostep, FALSE);
+    }
+    SetLoadOptionEnables(hDlg);
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* Read changed options from the dialog box */
+      if (IsDlgButtonChecked(hDlg, OPT_Autostep)) {
+       GetDlgItemText(hDlg, OPT_ASTimeDelay, buf, MSG_SIZ);
+       if (sscanf(buf, "%f", &fnumber) != 1) {
+         MessageBox(hDlg, "Invalid load game step rate",
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
+         return FALSE;
+       }
+       appData.timeDelay = fnumber;
+      } else {
+       appData.timeDelay = (float) -1.0;
+      }
+      EndDialog(hDlg, TRUE);
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    default:
+      SetLoadOptionEnables(hDlg);
+      break;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+
+VOID 
+LoadOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc = MakeProcInstance((FARPROC)LoadOptions, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_LoadOptions), hwnd, (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}
+
+/*---------------------------------------------------------------------------*\
+ *
+ * Save Options dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+
+VOID
+SetSaveOptionEnables(HWND hDlg)
+{
+  UINT state;
+
+  state = IsDlgButtonChecked(hDlg, OPT_Autosave);
+  EnableWindow(GetDlgItem(hDlg, OPT_AVPrompt), state);
+  EnableWindow(GetDlgItem(hDlg, OPT_AVToFile), state);
+  if (state && !IsDlgButtonChecked(hDlg, OPT_AVPrompt) &&
+      !IsDlgButtonChecked(hDlg, OPT_AVToFile)) {
+    CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);
+  }
+
+  state = state && IsDlgButtonChecked(hDlg, OPT_AVToFile);
+  EnableWindow(GetDlgItem(hDlg, OPT_AVFilename), state);
+  EnableWindow(GetDlgItem(hDlg, OPT_AVBrowse), state);
+}
+
+LRESULT CALLBACK
+SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  char buf[MSG_SIZ];
+  FILE *f;
+
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+    /* Initialize the dialog items */
+    if (*appData.saveGameFile != NULLCHAR) {
+      CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);
+      CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVToFile);
+      SetDlgItemText(hDlg, OPT_AVFilename, appData.saveGameFile);
+    } else if (appData.autoSaveGames) {
+      CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);
+      CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);
+    } else {
+      CheckDlgButton(hDlg, OPT_Autosave, (UINT) FALSE);
+    }
+    if (appData.oldSaveStyle) {
+      CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_Old);
+    } else {
+      CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_PGN);
+    }
+    CheckDlgButton( hDlg, OPT_OutOfBookInfo, appData.saveOutOfBookInfo );
+    SetSaveOptionEnables(hDlg);
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* Read changed options from the dialog box */
+      if (IsDlgButtonChecked(hDlg, OPT_Autosave)) {
+       appData.autoSaveGames = TRUE;
+       if (IsDlgButtonChecked(hDlg, OPT_AVPrompt)) {
+         appData.saveGameFile = "";
+       } else /*if (IsDlgButtonChecked(hDlg, OPT_AVToFile))*/ {
+         GetDlgItemText(hDlg, OPT_AVFilename, buf, MSG_SIZ);
+         if (*buf == NULLCHAR) {
+           MessageBox(hDlg, "Invalid save game file name",
+                      "Option Error", MB_OK|MB_ICONEXCLAMATION);
+           return FALSE;
+         }
+         if ((isalpha(buf[0]) && buf[1] == ':') ||
+           (buf[0] == '\\' && buf[1] == '\\')) {
+           appData.saveGameFile = strdup(buf);
+         } else {
+           char buf2[MSG_SIZ], buf3[MSG_SIZ];
+           char *dummy;
+           GetCurrentDirectory(MSG_SIZ, buf3);
+           SetCurrentDirectory(installDir);
+           if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {
+             appData.saveGameFile = strdup(buf2);
+           } else {
+             appData.saveGameFile = strdup(buf);
+           }
+           SetCurrentDirectory(buf3);
+         }
+       }
+      } else {
+       appData.autoSaveGames = FALSE;
+       appData.saveGameFile = "";
+      }
+      appData.oldSaveStyle = IsDlgButtonChecked(hDlg, OPT_Old);
+      appData.saveOutOfBookInfo = IsDlgButtonChecked( hDlg, OPT_OutOfBookInfo );
+      EndDialog(hDlg, TRUE);
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    case OPT_AVBrowse:
+      f = OpenFileDialog(hDlg, "a", NULL, 
+                        appData.oldSaveStyle ? "gam" : "pgn", 
+                        GAME_FILT, "Browse for Auto Save File", 
+                        NULL, NULL, buf);
+      if (f != NULL) {
+       fclose(f);
+       SetDlgItemText(hDlg, OPT_AVFilename, buf);
+      }
+      break;
+
+    default:
+      SetSaveOptionEnables(hDlg);
+      break;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+VOID
+SaveOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc = MakeProcInstance((FARPROC)SaveOptionsDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_SaveOptions), hwnd, (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}
+
+/*---------------------------------------------------------------------------*\
+ *
+ * Time Control Options dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+
+VOID
+SetTimeControlEnables(HWND hDlg)
+{
+  UINT state;
+
+  state = IsDlgButtonChecked(hDlg, OPT_TCUseMoves);
+  EnableWindow(GetDlgItem(hDlg, OPT_TCTime), state);
+  EnableWindow(GetDlgItem(hDlg, OPT_TCMoves), state);
+  EnableWindow(GetDlgItem(hDlg, OPT_TCtext1), state);
+  EnableWindow(GetDlgItem(hDlg, OPT_TCtext2), state);
+  EnableWindow(GetDlgItem(hDlg, OPT_TCTime2), !state);
+  EnableWindow(GetDlgItem(hDlg, OPT_TCInc), !state);
+  EnableWindow(GetDlgItem(hDlg, OPT_TCitext1), !state);
+  EnableWindow(GetDlgItem(hDlg, OPT_TCitext2), !state);
+  EnableWindow(GetDlgItem(hDlg, OPT_TCitext3), !state);
+}
+
+
+LRESULT CALLBACK
+TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  char buf[MSG_SIZ];
+  int mps, increment, odds1, odds2;
+  BOOL ok, ok2;
+
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+    /* Initialize the dialog items */
+    if (appData.clockMode && !appData.icsActive) {
+      if (appData.timeIncrement == -1) {
+       CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseInc,
+                        OPT_TCUseMoves);
+       SetDlgItemText(hDlg, OPT_TCTime, appData.timeControl);
+       SetDlgItemInt(hDlg, OPT_TCMoves, appData.movesPerSession,
+                     FALSE);
+       SetDlgItemText(hDlg, OPT_TCTime2, "");
+       SetDlgItemText(hDlg, OPT_TCInc, "");
+      } else {
+       CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseInc,
+                        OPT_TCUseInc);
+       SetDlgItemText(hDlg, OPT_TCTime, "");
+       SetDlgItemText(hDlg, OPT_TCMoves, "");
+       SetDlgItemText(hDlg, OPT_TCTime2, appData.timeControl);
+       SetDlgItemInt(hDlg, OPT_TCInc, appData.timeIncrement, FALSE);
+      }
+      SetDlgItemInt(hDlg, OPT_TCOdds1, 1, FALSE);
+      SetDlgItemInt(hDlg, OPT_TCOdds2, 1, FALSE);
+      SetTimeControlEnables(hDlg);
+    }
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* Read changed options from the dialog box */
+      if (IsDlgButtonChecked(hDlg, OPT_TCUseMoves)) {
+       increment = -1;
+       mps = GetDlgItemInt(hDlg, OPT_TCMoves, &ok, FALSE);
+       if (!ok || mps <= 0) {
+         MessageBox(hDlg, "Invalid moves per time control",
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
+         return FALSE;
+       }
+       GetDlgItemText(hDlg, OPT_TCTime, buf, MSG_SIZ);
+       if (!ParseTimeControl(buf, increment, mps)) {
+         MessageBox(hDlg, "Invalid minutes per time control",
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
+         return FALSE;
+       }
+      } else {
+       increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE);
+       mps = appData.movesPerSession;
+       if (!ok || increment < 0) {
+         MessageBox(hDlg, "Invalid increment",
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
+         return FALSE;
+       }
+       GetDlgItemText(hDlg, OPT_TCTime2, buf, MSG_SIZ);
+       if (!ParseTimeControl(buf, increment, mps)) {
+         MessageBox(hDlg, "Invalid initial time",
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
+         return FALSE;
+       }
+      }
+      odds1 = GetDlgItemInt(hDlg, OPT_TCOdds1, &ok, FALSE);
+      odds2 = GetDlgItemInt(hDlg, OPT_TCOdds2, &ok2, FALSE);
+      if (!ok || !ok2 || odds1 <= 0 || odds2 <= 0) {
+         MessageBox(hDlg, "Invalid time-odds factor",
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
+         return FALSE;
+      }
+      appData.timeControl = strdup(buf);
+      appData.movesPerSession = mps;
+      appData.timeIncrement = increment;
+      appData.firstTimeOdds  = first.timeOdds  = odds1;
+      appData.secondTimeOdds = second.timeOdds = odds2;
+      Reset(TRUE, TRUE);
+      EndDialog(hDlg, TRUE);
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    default:
+      SetTimeControlEnables(hDlg);
+      break;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+VOID
+TimeControlOptionsPopup(HWND hwnd)
+{
+  if (gameMode != BeginningOfGame) {
+    DisplayError("Changing time control during a game is not implemented", 0);
+  } else {
+    FARPROC lpProc = MakeProcInstance((FARPROC)TimeControl, hInst);
+    DialogBox(hInst, MAKEINTRESOURCE(DLG_TimeControl), hwnd, (DLGPROC) lpProc);
+    FreeProcInstance(lpProc);
+  }
+}
+
+/*---------------------------------------------------------------------------*\
+ *
+ * Engine Options Dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))
+#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))
+
+#define INT_ABS( n )    ((n) >= 0 ? (n) : -(n))
+
+LRESULT CALLBACK EnginePlayOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+
+    /* Initialize the dialog items */
+    CHECK_BOX(IDC_EpPeriodicUpdates, appData.periodicUpdates);
+    CHECK_BOX(IDC_EpPonder, appData.ponderNextMove);
+    CHECK_BOX(IDC_EpShowThinking, appData.showThinking);
+    CHECK_BOX(IDC_EpHideThinkingHuman, appData.hideThinkingFromHuman);
+
+    CHECK_BOX(IDC_TestClaims, appData.testClaims);
+    CHECK_BOX(IDC_DetectMates, appData.checkMates);
+    CHECK_BOX(IDC_MaterialDraws, appData.materialDraws);
+    CHECK_BOX(IDC_TrivialDraws, appData.trivialDraws);
+
+    CHECK_BOX(IDC_ScoreAbs1, appData.firstScoreIsAbsolute);
+    CHECK_BOX(IDC_ScoreAbs2, appData.secondScoreIsAbsolute);
+
+    SetDlgItemInt( hDlg, IDC_EpDrawMoveCount, appData.adjudicateDrawMoves, TRUE );
+    SendDlgItemMessage( hDlg, IDC_EpDrawMoveCount, EM_SETSEL, 0, -1 );
+
+    SetDlgItemInt( hDlg, IDC_EpAdjudicationThreshold, INT_ABS(appData.adjudicateLossThreshold), TRUE );
+    SendDlgItemMessage( hDlg, IDC_EpAdjudicationThreshold, EM_SETSEL, 0, -1 );
+
+    SetDlgItemInt( hDlg, IDC_RuleMoves, appData.ruleMoves, TRUE );
+    SendDlgItemMessage( hDlg, IDC_RuleMoves, EM_SETSEL, 0, -1 );
+
+    SetDlgItemInt( hDlg, IDC_DrawRepeats, INT_ABS(appData.drawRepeats), TRUE );
+    SendDlgItemMessage( hDlg, IDC_DrawRepeats, EM_SETSEL, 0, -1 );
+
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      /* Read changed options from the dialog box */
+      PeriodicUpdatesEvent(          IS_CHECKED(IDC_EpPeriodicUpdates));
+      PonderNextMoveEvent(           IS_CHECKED(IDC_EpPonder));
+      appData.hideThinkingFromHuman= IS_CHECKED(IDC_EpHideThinkingHuman); // [HGM] thinking: moved up
+#if 0
+      ShowThinkingEvent(             IS_CHECKED(IDC_EpShowThinking));
+#else
+      appData.showThinking   = IS_CHECKED(IDC_EpShowThinking);
+      ShowThinkingEvent(); // [HGM] thinking: tests all options that need thinking output
+#endif
+      appData.testClaims    = IS_CHECKED(IDC_TestClaims);
+      appData.checkMates    = IS_CHECKED(IDC_DetectMates);
+      appData.materialDraws = IS_CHECKED(IDC_MaterialDraws);
+      appData.trivialDraws  = IS_CHECKED(IDC_TrivialDraws);
+
+      appData.adjudicateDrawMoves = GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, NULL, FALSE );
+      appData.adjudicateLossThreshold = - (int) GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, NULL, FALSE );
+      appData.ruleMoves = GetDlgItemInt(hDlg, IDC_RuleMoves, NULL, FALSE );
+      appData.drawRepeats = (int) GetDlgItemInt(hDlg, IDC_DrawRepeats, NULL, FALSE );
+
+      appData.firstScoreIsAbsolute  = IS_CHECKED(IDC_ScoreAbs1);
+      appData.secondScoreIsAbsolute = IS_CHECKED(IDC_ScoreAbs2);
+
+      EndDialog(hDlg, TRUE);
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    case IDC_EpDrawMoveCount:
+    case IDC_EpAdjudicationThreshold:
+    case IDC_DrawRepeats:
+    case IDC_RuleMoves:
+        if( HIWORD(wParam) == EN_CHANGE ) {
+            int n1_ok;
+            int n2_ok;
+            int n3_ok;
+            int n4_ok;
+
+            GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, &n1_ok, FALSE );
+            GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, &n2_ok, FALSE );
+            GetDlgItemInt(hDlg, IDC_RuleMoves, &n3_ok, FALSE );
+            GetDlgItemInt(hDlg, IDC_DrawRepeats, &n4_ok, FALSE );
+
+            EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok && n4_ok ? TRUE : FALSE );
+        }
+        return TRUE;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+VOID EnginePlayOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc;
+
+  lpProc = MakeProcInstance((FARPROC)EnginePlayOptionsDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_EnginePlayOptions), hwnd, (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}
+
+/*---------------------------------------------------------------------------*\
+ *
+ * UCI Options Dialog functions
+ *
+\*---------------------------------------------------------------------------*/
+static BOOL BrowseForFolder( const char * title, char * path )
+{
+    BOOL result = FALSE;
+    BROWSEINFO bi;
+    LPITEMIDLIST pidl;
+
+    ZeroMemory( &bi, sizeof(bi) );
+
+    bi.lpszTitle = title == 0 ? "Choose Folder" : title;
+    bi.ulFlags = BIF_RETURNONLYFSDIRS;
+
+    pidl = SHBrowseForFolder( &bi );
+
+    if( pidl != 0 ) {
+        IMalloc * imalloc = 0;
+
+        if( SHGetPathFromIDList( pidl, path ) ) {
+            result = TRUE;
+        }
+
+        if( SUCCEEDED( SHGetMalloc ( &imalloc ) ) ) {
+            imalloc->lpVtbl->Free(imalloc,pidl);
+            imalloc->lpVtbl->Release(imalloc);
+        }
+    }
+
+    return result;
+}
+
+LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  char buf[MAX_PATH];
+  int oldCores;
+
+  switch (message) {
+  case WM_INITDIALOG: /* message: initialize dialog box */
+
+    /* Center the dialog over the application window */
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
+
+    /* Initialize the dialog items */
+    SetDlgItemText( hDlg, IDC_PolyglotDir, appData.polyglotDir );
+    SetDlgItemInt( hDlg, IDC_HashSize, appData.defaultHashSize, TRUE );
+    SetDlgItemText( hDlg, IDC_PathToEGTB, appData.defaultPathEGTB );
+    SetDlgItemInt( hDlg, IDC_SizeOfEGTB, appData.defaultCacheSizeEGTB, TRUE );
+    CheckDlgButton( hDlg, IDC_UseBook, (BOOL) appData.usePolyglotBook );
+    SetDlgItemText( hDlg, IDC_BookFile, appData.polyglotBook );
+    // [HGM] smp: input field for nr of cores:
+    SetDlgItemInt( hDlg, IDC_Cores, appData.smpCores, TRUE );
+    // [HGM] book: tick boxes for own book use
+    CheckDlgButton( hDlg, IDC_OwnBook1, (BOOL) appData.firstHasOwnBookUCI );
+    CheckDlgButton( hDlg, IDC_OwnBook2, (BOOL) appData.secondHasOwnBookUCI );
+
+    SendDlgItemMessage( hDlg, IDC_PolyglotDir, EM_SETSEL, 0, -1 );
+
+    return TRUE;
+
+  case WM_COMMAND: /* message: received a command */
+    switch (LOWORD(wParam)) {
+    case IDOK:
+      GetDlgItemText( hDlg, IDC_PolyglotDir, buf, sizeof(buf) );
+      appData.polyglotDir = strdup(buf);
+      appData.defaultHashSize = GetDlgItemInt(hDlg, IDC_HashSize, NULL, FALSE );
+      appData.defaultCacheSizeEGTB = GetDlgItemInt(hDlg, IDC_SizeOfEGTB, NULL, FALSE );
+      GetDlgItemText( hDlg, IDC_PathToEGTB, buf, sizeof(buf) );
+      appData.defaultPathEGTB = strdup(buf);
+      GetDlgItemText( hDlg, IDC_BookFile, buf, sizeof(buf) );
+      appData.polyglotBook = strdup(buf);
+      appData.usePolyglotBook = (Boolean) IsDlgButtonChecked( hDlg, IDC_UseBook );
+      // [HGM] smp: get nr of cores:
+      oldCores = appData.smpCores;
+      appData.smpCores = GetDlgItemInt(hDlg, IDC_Cores, NULL, FALSE );
+      if(appData.smpCores != oldCores) NewSettingEvent(FALSE, "cores", appData.smpCores);
+      // [HGM] book: read tick boxes for own book use
+      appData.firstHasOwnBookUCI  = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook1 );
+      appData.secondHasOwnBookUCI = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook2 );
+
+      if(gameMode == BeginningOfGame) Reset(TRUE, TRUE);
+      EndDialog(hDlg, TRUE);
+      return TRUE;
+
+    case IDCANCEL:
+      EndDialog(hDlg, FALSE);
+      return TRUE;
+
+    case IDC_BrowseForBook:
+      {
+          char filter[] = { 
+              'A','l','l',' ','F','i','l','e','s', 0,
+              '*','.','*', 0,
+              'B','I','N',' ','F','i','l','e','s', 0,
+              '*','.','b','i','n', 0,
+              0 };
+
+          OPENFILENAME ofn;
+
+          strcpy( buf, "" );
+
+          ZeroMemory( &ofn, sizeof(ofn) );
+
+          ofn.lStructSize = sizeof(ofn);
+          ofn.hwndOwner = hDlg;
+          ofn.hInstance = hInst;
+          ofn.lpstrFilter = filter;
+          ofn.lpstrFile = buf;
+          ofn.nMaxFile = sizeof(buf);
+          ofn.lpstrTitle = "Choose Book";
+          ofn.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_HIDEREADONLY;
+
+          if( GetOpenFileName( &ofn ) ) {
+              SetDlgItemText( hDlg, IDC_BookFile, buf );
+          }
+      }
+      return TRUE;
+
+    case IDC_BrowseForPolyglotDir:
+      if( BrowseForFolder( "Choose Polyglot Directory", buf ) ) {
+        SetDlgItemText( hDlg, IDC_PolyglotDir, buf );
+
+        strcat( buf, "\\polyglot.exe" );
+
+        if( GetFileAttributes(buf) == 0xFFFFFFFF ) {
+            MessageBox( hDlg, "Polyglot was not found in the specified folder!", "Warning", MB_OK | MB_ICONWARNING );
+        }
+      }
+      return TRUE;
+
+    case IDC_BrowseForEGTB:
+      if( BrowseForFolder( "Choose EGTB Directory:", buf ) ) {
+        SetDlgItemText( hDlg, IDC_PathToEGTB, buf );
+      }
+      return TRUE;
+
+    case IDC_HashSize:
+    case IDC_SizeOfEGTB:
+        if( HIWORD(wParam) == EN_CHANGE ) {
+            int n1_ok;
+            int n2_ok;
+
+            GetDlgItemInt(hDlg, IDC_HashSize, &n1_ok, FALSE );
+            GetDlgItemInt(hDlg, IDC_SizeOfEGTB, &n2_ok, FALSE );
+
+            EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok ? TRUE : FALSE );
+        }
+        return TRUE;
+    }
+    break;
+  }
+  return FALSE;
+}
+
+VOID UciOptionsPopup(HWND hwnd)
+{
+  FARPROC lpProc;
+
+  lpProc = MakeProcInstance((FARPROC)UciOptionsDialog, hInst);
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_OptionsUCI), hwnd, (DLGPROC) lpProc);
+  FreeProcInstance(lpProc);
+}