Add option Display Logo in WB general-options menu
[xboard.git] / winboard / woptions.c
1 /*\r
2  * woptions.c -- Options dialog box routines for WinBoard\r
3  *\r
4  * Copyright 2000, 2009, 2010 Free Software Foundation, Inc.\r
5  *\r
6  * Enhancements Copyright 2005 Alessandro Scotti\r
7  *\r
8  * ------------------------------------------------------------------------\r
9  *\r
10  * GNU XBoard is free software: you can redistribute it and/or modify\r
11  * it under the terms of the GNU General Public License as published by\r
12  * the Free Software Foundation, either version 3 of the License, or (at\r
13  * your option) any later version.\r
14  *\r
15  * GNU XBoard is distributed in the hope that it will be useful, but\r
16  * WITHOUT ANY WARRANTY; without even the implied warranty of\r
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
18  * General Public License for more details.\r
19  *\r
20  * You should have received a copy of the GNU General Public License\r
21  * along with this program. If not, see http://www.gnu.org/licenses/.  *\r
22  *\r
23  *------------------------------------------------------------------------\r
24  ** See the file ChangeLog for a revision history.  */\r
25 \r
26 #include "config.h"\r
27 \r
28 #include <windows.h>   /* required for all Windows applications */\r
29 #include <stdio.h>\r
30 #include <stdlib.h>\r
31 #include <shlobj.h>    /* [AS] Requires NT 4.0 or Win95 */\r
32 #include <ctype.h>\r
33 \r
34 #include "common.h"\r
35 #include "frontend.h"\r
36 #include "winboard.h"\r
37 #include "backend.h"\r
38 #include "woptions.h"\r
39 #include "defaults.h"\r
40 #include <richedit.h>\r
41 \r
42 #if __GNUC__\r
43 #include <errno.h>\r
44 #include <string.h>\r
45 #endif\r
46 \r
47 /* Imports from winboard.c */\r
48 \r
49 extern MyFont *font[NUM_SIZES][NUM_FONTS];\r
50 extern HINSTANCE hInst;          /* current instance */\r
51 extern HWND hwndMain;            /* root window*/\r
52 extern BOOLEAN alwaysOnTop;\r
53 extern RECT boardRect;\r
54 extern COLORREF lightSquareColor, darkSquareColor, whitePieceColor, \r
55   blackPieceColor, highlightSquareColor, premoveHighlightColor;\r
56 extern HPALETTE hPal;\r
57 extern BoardSize boardSize;\r
58 extern COLORREF consoleBackgroundColor;\r
59 extern MyColorizeAttribs colorizeAttribs[]; /* do I need the size? */\r
60 extern MyTextAttribs textAttribs[];\r
61 extern MySound sounds[];\r
62 extern ColorClass currentColorClass;\r
63 extern HWND hwndConsole;\r
64 extern char *defaultTextAttribs[];\r
65 extern HWND commentDialog;\r
66 extern HWND moveHistoryDialog;\r
67 extern HWND engineOutputDialog;\r
68 extern char installDir[];\r
69 extern HWND hCommPort;    /* currently open comm port */\r
70 extern DCB dcb;\r
71 extern BOOLEAN chessProgram;\r
72 extern int startedFromPositionFile; /* [HGM] loadPos */\r
73 extern int searchTime;\r
74 \r
75 /* types */\r
76 \r
77 typedef struct {\r
78   char *label;\r
79   unsigned value;\r
80 } ComboData;\r
81 \r
82 typedef struct {\r
83   char *label;\r
84   char *name;\r
85 } SoundComboData;\r
86 \r
87 /* module prototypes */\r
88 \r
89 LRESULT CALLBACK GeneralOptions(HWND, UINT, WPARAM, LPARAM);\r
90 LRESULT CALLBACK BoardOptions(HWND, UINT, WPARAM, LPARAM);\r
91 LRESULT CALLBACK NewVariant(HWND, UINT, WPARAM, LPARAM);\r
92 LRESULT CALLBACK IcsOptions(HWND, UINT, WPARAM, LPARAM);\r
93 LRESULT CALLBACK FontOptions(HWND, UINT, WPARAM, LPARAM);\r
94 LRESULT CALLBACK CommPortOptions(HWND, UINT, WPARAM, LPARAM);\r
95 LRESULT CALLBACK LoadOptions(HWND, UINT, WPARAM, LPARAM);\r
96 LRESULT CALLBACK SaveOptions(HWND, UINT, WPARAM, LPARAM);\r
97 LRESULT CALLBACK TimeControl(HWND, UINT, WPARAM, LPARAM);\r
98 VOID ChangeBoardSize(BoardSize newSize);\r
99 VOID PaintSampleSquare(\r
100     HWND     hwnd, \r
101     int      ctrlid, \r
102     COLORREF squareColor, \r
103     COLORREF pieceColor,\r
104     COLORREF squareOutlineColor,\r
105     COLORREF pieceDetailColor,\r
106     BOOL     isWhitePiece,\r
107     BOOL     isMono,\r
108     HBITMAP  pieces[3] \r
109     );\r
110 VOID PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color);\r
111 VOID SetBoardOptionEnables(HWND hDlg);\r
112 BoardSize BoardOptionsWhichRadio(HWND hDlg);\r
113 BOOL APIENTRY MyCreateFont(HWND hwnd, MyFont *font);\r
114 VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca);\r
115 LRESULT CALLBACK ColorizeTextDialog(HWND , UINT, WPARAM, LPARAM);\r
116 VOID ColorizeTextPopup(HWND hwnd, ColorClass cc);\r
117 VOID SetIcsOptionEnables(HWND hDlg);\r
118 VOID SetSampleFontText(HWND hwnd, int id, const MyFont *mf);\r
119 VOID CopyFont(MyFont *dest, const MyFont *src);\r
120 void InitSoundComboData(SoundComboData *scd);\r
121 void ResetSoundComboData(SoundComboData *scd);\r
122 void InitSoundCombo(HWND hwndCombo, SoundComboData *scd);\r
123 int SoundDialogWhichRadio(HWND hDlg);\r
124 VOID SoundDialogSetEnables(HWND hDlg, int radio);\r
125 char * SoundDialogGetName(HWND hDlg, int radio);\r
126 void DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name);\r
127 VOID ParseCommSettings(char *arg, DCB *dcb);\r
128 VOID PrintCommSettings(FILE *f, char *name, DCB *dcb);\r
129 void InitCombo(HANDLE hwndCombo, ComboData *cd);\r
130 void SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value);\r
131 VOID SetLoadOptionEnables(HWND hDlg);\r
132 VOID SetSaveOptionEnables(HWND hDlg);\r
133 VOID SetTimeControlEnables(HWND hDlg);\r
134 void NewSettingEvent(int option, char *command, int value);\r
135 \r
136 /*---------------------------------------------------------------------------*\\r
137  *\r
138  * General Options Dialog functions\r
139  *\r
140 \*---------------------------------------------------------------------------*/\r
141 \r
142 \r
143 LRESULT CALLBACK\r
144 GeneralOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
145 {\r
146   static Boolean oldShowCoords;\r
147   static Boolean oldBlindfold;\r
148   static Boolean oldShowButtonBar;\r
149   static Boolean oldAutoLogo;\r
150 \r
151   switch (message) {\r
152   case WM_INITDIALOG: /* message: initialize dialog box */\r
153     oldShowCoords = appData.showCoords;\r
154     oldBlindfold  = appData.blindfold;\r
155     oldShowButtonBar = appData.showButtonBar;\r
156     oldAutoLogo  = appData.autoLogo;\r
157 \r
158     /* Center the dialog over the application window */\r
159     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
160 \r
161     /* Initialize the dialog items */\r
162 #define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
163 \r
164     CHECK_BOX(OPT_AlwaysOnTop, alwaysOnTop);\r
165     CHECK_BOX(OPT_AlwaysQueen, appData.alwaysPromoteToQueen);\r
166     CHECK_BOX(OPT_AnimateDragging, appData.animateDragging);\r
167     CHECK_BOX(OPT_AnimateMoving, appData.animate);\r
168     CHECK_BOX(OPT_AutoFlag, appData.autoCallFlag);\r
169     CHECK_BOX(OPT_AutoFlipView, appData.autoFlipView);\r
170     CHECK_BOX(OPT_AutoRaiseBoard, appData.autoRaiseBoard);\r
171     CHECK_BOX(OPT_Blindfold, appData.blindfold);\r
172     CHECK_BOX(OPT_HighlightDragging, appData.highlightDragging);\r
173     CHECK_BOX(OPT_HighlightLastMove, appData.highlightLastMove);\r
174     CHECK_BOX(OPT_PeriodicUpdates, appData.periodicUpdates);\r
175     CHECK_BOX(OPT_PonderNextMove, appData.ponderNextMove);\r
176     CHECK_BOX(OPT_PopupExitMessage, appData.popupExitMessage);\r
177     CHECK_BOX(OPT_PopupMoveErrors, appData.popupMoveErrors);\r
178     CHECK_BOX(OPT_ShowButtonBar, appData.showButtonBar);\r
179     CHECK_BOX(OPT_ShowCoordinates, appData.showCoords);\r
180     CHECK_BOX(OPT_ShowThinking, appData.showThinking);\r
181     CHECK_BOX(OPT_TestLegality, appData.testLegality);\r
182     CHECK_BOX(OPT_HideThinkFromHuman, appData.hideThinkingFromHuman);\r
183     CHECK_BOX(OPT_SaveExtPGN, appData.saveExtendedInfoInPGN);\r
184     CHECK_BOX(OPT_ExtraInfoInMoveHistory, appData.showEvalInMoveHistory);\r
185     CHECK_BOX(OPT_HighlightMoveArrow, appData.highlightMoveWithArrow);\r
186     CHECK_BOX(OPT_AutoLogo, appData.autoLogo); // [HGM] logo\r
187 \r
188 #undef CHECK_BOX\r
189 \r
190     EnableWindow(GetDlgItem(hDlg, OPT_AutoFlag),\r
191                  appData.icsActive || !appData.noChessProgram);\r
192     EnableWindow(GetDlgItem(hDlg, OPT_AutoFlipView),\r
193                  appData.icsActive || !appData.noChessProgram);\r
194     EnableWindow(GetDlgItem(hDlg, OPT_PonderNextMove),\r
195                  !appData.noChessProgram);\r
196     EnableWindow(GetDlgItem(hDlg, OPT_PeriodicUpdates), \r
197                  !appData.noChessProgram && !appData.icsActive);\r
198     EnableWindow(GetDlgItem(hDlg, OPT_ShowThinking), \r
199                  !appData.noChessProgram);\r
200     return TRUE;\r
201 \r
202 \r
203   case WM_COMMAND: /* message: received a command */\r
204     switch (LOWORD(wParam)) {\r
205     case IDOK:\r
206       /* Read changed options from the dialog box */\r
207       \r
208 #define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
209 \r
210       alwaysOnTop                  = IS_CHECKED(OPT_AlwaysOnTop);\r
211       appData.alwaysPromoteToQueen = IS_CHECKED(OPT_AlwaysQueen);\r
212       appData.animateDragging      = IS_CHECKED(OPT_AnimateDragging);\r
213       appData.animate              = IS_CHECKED(OPT_AnimateMoving);\r
214       appData.autoCallFlag         = IS_CHECKED(OPT_AutoFlag);\r
215       appData.autoFlipView         = IS_CHECKED(OPT_AutoFlipView);\r
216       appData.autoRaiseBoard       = IS_CHECKED(OPT_AutoRaiseBoard);\r
217       appData.blindfold            = IS_CHECKED(OPT_Blindfold);\r
218       appData.highlightDragging    = IS_CHECKED(OPT_HighlightDragging);\r
219       appData.highlightLastMove    = IS_CHECKED(OPT_HighlightLastMove);\r
220       PeriodicUpdatesEvent(          IS_CHECKED(OPT_PeriodicUpdates));\r
221       PonderNextMoveEvent(           IS_CHECKED(OPT_PonderNextMove));\r
222       appData.popupExitMessage     = IS_CHECKED(OPT_PopupExitMessage);\r
223       appData.popupMoveErrors      = IS_CHECKED(OPT_PopupMoveErrors);\r
224       appData.showButtonBar        = IS_CHECKED(OPT_ShowButtonBar);\r
225       appData.showCoords           = IS_CHECKED(OPT_ShowCoordinates);\r
226       // [HGM] thinking: next three moved up\r
227       appData.saveExtendedInfoInPGN= IS_CHECKED(OPT_SaveExtPGN);\r
228       appData.hideThinkingFromHuman= IS_CHECKED(OPT_HideThinkFromHuman);\r
229       appData.showEvalInMoveHistory= IS_CHECKED(OPT_ExtraInfoInMoveHistory);\r
230       appData.showThinking         = IS_CHECKED(OPT_ShowThinking);\r
231       ShowThinkingEvent(); // [HGM] thinking: tests four options\r
232       appData.testLegality         = IS_CHECKED(OPT_TestLegality);\r
233       appData.highlightMoveWithArrow=IS_CHECKED(OPT_HighlightMoveArrow);\r
234       appData.autoLogo             =IS_CHECKED(OPT_AutoLogo); // [HGM] logo\r
235 \r
236 #undef IS_CHECKED\r
237 \r
238       SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
239                    0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
240 #if AOT_CONSOLE\r
241       if (hwndConsole) {\r
242         SetWindowPos(hwndConsole, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
243                      0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
244       }\r
245 #endif\r
246       if (!appData.highlightLastMove) {\r
247         ClearHighlights();\r
248         DrawPosition(FALSE, NULL);\r
249       }\r
250       /* \r
251        * for some reason the redraw seems smoother when we invalidate\r
252        * the board rect after the call to EndDialog()\r
253        */\r
254       EndDialog(hDlg, TRUE);\r
255 \r
256       if (oldAutoLogo != appData.autoLogo) { // [HGM] logo: remove any logos when we switch autologo off\r
257         if(oldAutoLogo) first.programLogo = second.programLogo = NULL;\r
258         InitDrawingSizes(boardSize, 0);\r
259       } else if (oldShowButtonBar != appData.showButtonBar) {\r
260         InitDrawingSizes(boardSize, 0);\r
261       } else if ((oldShowCoords != appData.showCoords) || \r
262                  (oldBlindfold != appData.blindfold)) {\r
263         InvalidateRect(hwndMain, &boardRect, FALSE);\r
264       }\r
265 \r
266       return TRUE;\r
267 \r
268     case IDCANCEL:\r
269       EndDialog(hDlg, FALSE);\r
270       return TRUE;\r
271 \r
272     }\r
273     break;\r
274   }\r
275   return FALSE;\r
276 }\r
277 \r
278 VOID \r
279 GeneralOptionsPopup(HWND hwnd)\r
280 {\r
281   FARPROC lpProc;\r
282 \r
283   lpProc = MakeProcInstance((FARPROC)GeneralOptionsDialog, hInst);\r
284   DialogBox(hInst, MAKEINTRESOURCE(DLG_GeneralOptions), hwnd,\r
285             (DLGPROC) lpProc);\r
286   FreeProcInstance(lpProc);\r
287 }\r
288 /*---------------------------------------------------------------------------*\\r
289  *\r
290  * Board Options Dialog functions\r
291  *\r
292 \*---------------------------------------------------------------------------*/\r
293 \r
294 const int SAMPLE_SQ_SIZE = 54;\r
295 \r
296 VOID\r
297 ChangeBoardSize(BoardSize newSize)\r
298 {\r
299   if (newSize != boardSize) {\r
300     boardSize = newSize;\r
301     InitDrawingSizes(boardSize, 0);\r
302   }\r
303 }\r
304 \r
305 VOID\r
306 PaintSampleSquare(\r
307     HWND     hwnd, \r
308     int      ctrlid, \r
309     COLORREF squareColor, \r
310     COLORREF pieceColor,\r
311     COLORREF squareOutlineColor,\r
312     COLORREF pieceDetailColor,\r
313     BOOL     isWhitePiece,\r
314     BOOL     isMono,\r
315     HBITMAP  pieces[3] \r
316     )\r
317 {\r
318   HBRUSH  brushSquare;\r
319   HBRUSH  brushSquareOutline;\r
320   HBRUSH  brushPiece;\r
321   HBRUSH  brushPieceDetail;\r
322   HBRUSH  oldBrushPiece = NULL;\r
323   HBRUSH  oldBrushSquare;\r
324   HBITMAP oldBitmapMem;\r
325   HBITMAP oldBitmapTemp;\r
326   HBITMAP bufferBitmap;\r
327   RECT    rect;\r
328   HDC     hdcScreen, hdcMem, hdcTemp;\r
329   HPEN    pen, oldPen;\r
330   HWND    hCtrl = GetDlgItem(hwnd, ctrlid);\r
331   int     x, y;\r
332 \r
333   const int SOLID   = 0;\r
334   const int WHITE   = 1;\r
335   const int OUTLINE = 2;\r
336   const int BORDER  = 4;\r
337 \r
338   InvalidateRect(hCtrl, NULL, TRUE);\r
339   UpdateWindow(hCtrl);\r
340   GetClientRect(hCtrl, &rect);\r
341   x = rect.left + (BORDER / 2);\r
342   y = rect.top  + (BORDER / 2);\r
343   hdcScreen = GetDC(hCtrl);\r
344   hdcMem  = CreateCompatibleDC(hdcScreen);\r
345   hdcTemp = CreateCompatibleDC(hdcScreen);\r
346 \r
347   bufferBitmap = CreateCompatibleBitmap(hdcScreen, rect.right-rect.left+1,\r
348                                         rect.bottom-rect.top+1);\r
349   oldBitmapMem = SelectObject(hdcMem, bufferBitmap);\r
350   if (!isMono) {\r
351     SelectPalette(hdcMem, hPal, FALSE);\r
352   }\r
353   brushSquare         = CreateSolidBrush(squareColor);\r
354   brushSquareOutline  = CreateSolidBrush(squareOutlineColor);\r
355   brushPiece          = CreateSolidBrush(pieceColor);\r
356   brushPieceDetail    = CreateSolidBrush(pieceDetailColor);\r
357 \r
358   /* \r
359    * first draw the rectangle \r
360    */\r
361   pen      = CreatePen(PS_SOLID, BORDER, squareOutlineColor);\r
362   oldPen   = (HPEN)  SelectObject(hdcMem, pen);\r
363   oldBrushSquare = (HBRUSH)SelectObject(hdcMem, brushSquare);\r
364   Rectangle(hdcMem, rect.left, rect.top, rect.right, rect.bottom);\r
365 \r
366   /* \r
367    * now draw the piece\r
368    */\r
369   if (isMono) {\r
370     oldBitmapTemp = SelectObject(hdcTemp, pieces[OUTLINE]);\r
371     BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, hdcTemp, 0, 0,\r
372            isWhitePiece ? SRCCOPY : NOTSRCCOPY);\r
373     SelectObject(hdcTemp, oldBitmapTemp);\r
374   } else {\r
375     if (isWhitePiece) {\r
376       oldBitmapTemp = SelectObject(hdcTemp, pieces[WHITE]);\r
377       oldBrushPiece = SelectObject(hdcMem, brushPiece);\r
378       BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
379              hdcTemp, 0, 0, 0x00B8074A);\r
380       /* Use black for outline of white pieces */\r
381       SelectObject(hdcTemp, pieces[OUTLINE]);\r
382       BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
383              hdcTemp, 0, 0, SRCAND);\r
384     } else {\r
385       /* Use square color for details of black pieces */\r
386       oldBitmapTemp = SelectObject(hdcTemp, pieces[SOLID]);\r
387       oldBrushPiece = SelectObject(hdcMem, brushPiece);\r
388       BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
389              hdcTemp, 0, 0, 0x00B8074A);\r
390     }\r
391     SelectObject(hdcMem, oldBrushPiece);\r
392     SelectObject(hdcTemp, oldBitmapTemp);\r
393   }\r
394   /* \r
395    * copy the memory dc to the screen\r
396    */\r
397   SelectObject(hdcMem, bufferBitmap);\r
398   BitBlt(hdcScreen, rect.left, rect.top,\r
399          rect.right - rect.left,\r
400          rect.bottom - rect.top,\r
401          hdcMem, rect.left, rect.top, SRCCOPY);\r
402   SelectObject(hdcMem, oldBitmapMem);\r
403   /* \r
404    * clean up\r
405    */\r
406   SelectObject(hdcMem, oldBrushPiece);\r
407   SelectObject(hdcMem, oldPen);\r
408   DeleteObject(brushPiece);\r
409   DeleteObject(brushPieceDetail);\r
410   DeleteObject(brushSquare);\r
411   DeleteObject(brushSquareOutline);\r
412   DeleteObject(pen);\r
413   DeleteDC(hdcTemp);\r
414   DeleteDC(hdcMem);\r
415   ReleaseDC(hCtrl, hdcScreen);\r
416 }\r
417 \r
418 \r
419 VOID\r
420 PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color)\r
421 {\r
422   HDC    hdc;\r
423   HBRUSH brush, oldBrush;\r
424   RECT   rect;\r
425   HWND   hCtrl = GetDlgItem(hwnd, ctrlid);\r
426 \r
427   hdc = GetDC(hCtrl);\r
428   InvalidateRect(hCtrl, NULL, TRUE);\r
429   UpdateWindow(hCtrl);\r
430   GetClientRect(hCtrl, &rect);\r
431   brush = CreateSolidBrush(color);\r
432   oldBrush = (HBRUSH)SelectObject(hdc, brush);\r
433   Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);\r
434   SelectObject(hdc, oldBrush);\r
435   DeleteObject(brush);\r
436   ReleaseDC(hCtrl, hdc);\r
437 }\r
438 \r
439 \r
440 VOID\r
441 SetBoardOptionEnables(HWND hDlg)\r
442 {\r
443   if (IsDlgButtonChecked(hDlg, OPT_Monochrome)) {\r
444     ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_HIDE);\r
445     ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_HIDE);\r
446     ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_HIDE);\r
447     ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_HIDE);\r
448 \r
449     EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), FALSE);\r
450     EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), FALSE);\r
451     EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), FALSE);\r
452     EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), FALSE);\r
453   } else {\r
454     ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_SHOW);\r
455     ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_SHOW);\r
456     ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_SHOW);\r
457     ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_SHOW);\r
458 \r
459     EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), TRUE);\r
460     EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), TRUE);\r
461     EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), TRUE);\r
462     EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), TRUE);\r
463   }\r
464 }\r
465 \r
466 BoardSize \r
467 BoardOptionsWhichRadio(HWND hDlg)\r
468 {\r
469   return (IsDlgButtonChecked(hDlg, OPT_SizeTiny) ? SizeTiny :\r
470          (IsDlgButtonChecked(hDlg, OPT_SizeTeeny) ? SizeTeeny :\r
471          (IsDlgButtonChecked(hDlg, OPT_SizeDinky) ? SizeDinky :\r
472          (IsDlgButtonChecked(hDlg, OPT_SizePetite) ? SizePetite :\r
473          (IsDlgButtonChecked(hDlg, OPT_SizeSlim) ? SizeSlim :\r
474          (IsDlgButtonChecked(hDlg, OPT_SizeSmall) ? SizeSmall :\r
475          (IsDlgButtonChecked(hDlg, OPT_SizeMediocre) ? SizeMediocre :\r
476          (IsDlgButtonChecked(hDlg, OPT_SizeMiddling) ? SizeMiddling :\r
477          (IsDlgButtonChecked(hDlg, OPT_SizeAverage) ? SizeAverage :\r
478          (IsDlgButtonChecked(hDlg, OPT_SizeModerate) ? SizeModerate :\r
479          (IsDlgButtonChecked(hDlg, OPT_SizeMedium) ? SizeMedium :\r
480          (IsDlgButtonChecked(hDlg, OPT_SizeBulky) ? SizeBulky :\r
481          (IsDlgButtonChecked(hDlg, OPT_SizeLarge) ? SizeLarge :\r
482          (IsDlgButtonChecked(hDlg, OPT_SizeBig) ? SizeBig :\r
483          (IsDlgButtonChecked(hDlg, OPT_SizeHuge) ? SizeHuge :\r
484          (IsDlgButtonChecked(hDlg, OPT_SizeGiant) ? SizeGiant :\r
485          (IsDlgButtonChecked(hDlg, OPT_SizeColossal) ? SizeColossal :\r
486           SizeTitanic )))))))))))))))));\r
487 }\r
488 \r
489 LRESULT CALLBACK\r
490 BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
491 {\r
492   static Boolean  mono, white, flip;\r
493   static BoardSize size;\r
494   static COLORREF lsc, dsc, wpc, bpc, hsc, phc;\r
495   static HBITMAP pieces[3];\r
496 \r
497   switch (message) {\r
498   case WM_INITDIALOG: /* message: initialize dialog box */\r
499     /* Center the dialog over the application window */\r
500     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
501     /* Initialize the dialog items */\r
502     switch (boardSize) {\r
503     case SizeTiny:\r
504       CheckDlgButton(hDlg, OPT_SizeTiny, TRUE);\r
505       break;\r
506     case SizeTeeny:\r
507       CheckDlgButton(hDlg, OPT_SizeTeeny, TRUE);\r
508       break;\r
509     case SizeDinky:\r
510       CheckDlgButton(hDlg, OPT_SizeDinky, TRUE);\r
511       break;\r
512     case SizePetite:\r
513       CheckDlgButton(hDlg, OPT_SizePetite, TRUE);\r
514       break;\r
515     case SizeSlim:\r
516       CheckDlgButton(hDlg, OPT_SizeSlim, TRUE);\r
517       break;\r
518     case SizeSmall:\r
519       CheckDlgButton(hDlg, OPT_SizeSmall, TRUE);\r
520       break;\r
521     case SizeMediocre:\r
522       CheckDlgButton(hDlg, OPT_SizeMediocre, TRUE);\r
523       break;\r
524     case SizeMiddling:\r
525       CheckDlgButton(hDlg, OPT_SizeMiddling, TRUE);\r
526       break;\r
527     case SizeAverage:\r
528       CheckDlgButton(hDlg, OPT_SizeAverage, TRUE);\r
529       break;\r
530     case SizeModerate:\r
531       CheckDlgButton(hDlg, OPT_SizeModerate, TRUE);\r
532       break;\r
533     case SizeMedium:\r
534       CheckDlgButton(hDlg, OPT_SizeMedium, TRUE);\r
535       break;\r
536     case SizeBulky:\r
537       CheckDlgButton(hDlg, OPT_SizeBulky, TRUE);\r
538       break;\r
539     case SizeLarge:\r
540       CheckDlgButton(hDlg, OPT_SizeLarge, TRUE);\r
541       break;\r
542     case SizeBig:\r
543       CheckDlgButton(hDlg, OPT_SizeBig, TRUE);\r
544       break;\r
545     case SizeHuge:\r
546       CheckDlgButton(hDlg, OPT_SizeHuge, TRUE);\r
547       break;\r
548     case SizeGiant:\r
549       CheckDlgButton(hDlg, OPT_SizeGiant, TRUE);\r
550       break;\r
551     case SizeColossal:\r
552       CheckDlgButton(hDlg, OPT_SizeColossal, TRUE);\r
553       break;\r
554     case SizeTitanic:\r
555       CheckDlgButton(hDlg, OPT_SizeTitanic, TRUE);\r
556     default: ; // should not happen, but suppresses warning on pedantic compilers\r
557     }\r
558 \r
559     if (appData.monoMode)\r
560       CheckDlgButton(hDlg, OPT_Monochrome, TRUE);\r
561 \r
562     if (appData.allWhite)\r
563       CheckDlgButton(hDlg, OPT_AllWhite, TRUE);\r
564 \r
565     if (appData.upsideDown)\r
566       CheckDlgButton(hDlg, OPT_UpsideDown, TRUE);\r
567 \r
568     pieces[0] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "s");\r
569     pieces[1] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "w");\r
570     pieces[2] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "o");\r
571         \r
572     lsc = lightSquareColor;\r
573     dsc = darkSquareColor;\r
574     wpc = whitePieceColor;\r
575     bpc = blackPieceColor;\r
576     hsc = highlightSquareColor;\r
577     phc = premoveHighlightColor;\r
578     mono = appData.monoMode;\r
579     white= appData.allWhite;\r
580     flip = appData.upsideDown;\r
581     size = boardSize;\r
582 \r
583     SetBoardOptionEnables(hDlg);\r
584     return TRUE;\r
585 \r
586   case WM_PAINT:\r
587     PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);\r
588     PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);\r
589     PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);\r
590     PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);\r
591     PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);\r
592     PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);\r
593     PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
594         TRUE, mono, pieces);\r
595     PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
596         FALSE, mono, pieces);\r
597 \r
598     return FALSE;\r
599 \r
600   case WM_COMMAND: /* message: received a command */\r
601     switch (LOWORD(wParam)) {\r
602     case IDOK:\r
603       /* \r
604        * if we call EndDialog() after the call to ChangeBoardSize(),\r
605        * then ChangeBoardSize() does not take effect, although the new\r
606        * boardSize is saved. Go figure...\r
607        */\r
608       EndDialog(hDlg, TRUE);\r
609 \r
610       size = BoardOptionsWhichRadio(hDlg);\r
611 \r
612       /*\r
613        * did any settings change?\r
614        */\r
615       if (size != boardSize) {\r
616         ChangeBoardSize(size);\r
617       }\r
618 \r
619       if ((mono != appData.monoMode) ||\r
620           (lsc  != lightSquareColor) ||\r
621           (dsc  != darkSquareColor) ||\r
622           (wpc  != whitePieceColor) ||\r
623           (bpc  != blackPieceColor) ||\r
624           (hsc  != highlightSquareColor) ||\r
625           (flip != appData.upsideDown) ||\r
626           (white != appData.allWhite) ||\r
627           (phc  != premoveHighlightColor)) {\r
628 \r
629           lightSquareColor = lsc;\r
630           darkSquareColor = dsc;\r
631           whitePieceColor = wpc;\r
632           blackPieceColor = bpc;\r
633           highlightSquareColor = hsc;\r
634           premoveHighlightColor = phc;\r
635           appData.monoMode = mono;\r
636           appData.allWhite = white;\r
637           appData.upsideDown = flip;\r
638 \r
639           InitDrawingColors();\r
640           InitDrawingSizes(boardSize, 0);\r
641           InvalidateRect(hwndMain, &boardRect, FALSE);\r
642       }\r
643       DeleteObject(pieces[0]);\r
644       DeleteObject(pieces[1]);\r
645       DeleteObject(pieces[2]);\r
646       return TRUE;\r
647 \r
648     case IDCANCEL:\r
649       DeleteObject(pieces[0]);\r
650       DeleteObject(pieces[1]);\r
651       DeleteObject(pieces[2]);\r
652       EndDialog(hDlg, FALSE);\r
653       return TRUE;\r
654 \r
655     case OPT_ChooseLightSquareColor:\r
656       if (ChangeColor(hDlg, &lsc)) \r
657         PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);\r
658         PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
659             TRUE, mono, pieces);\r
660       break;\r
661 \r
662     case OPT_ChooseDarkSquareColor:\r
663       if (ChangeColor(hDlg, &dsc)) \r
664         PaintColorBlock(hDlg, OPT_DarkSquareColor, dsc);\r
665         PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
666             FALSE, mono, pieces);\r
667       break;\r
668 \r
669     case OPT_ChooseWhitePieceColor:\r
670       if (ChangeColor(hDlg, &wpc)) \r
671         PaintColorBlock(hDlg, OPT_WhitePieceColor, wpc);\r
672         PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
673             TRUE, mono, pieces);\r
674       break;\r
675 \r
676     case OPT_ChooseBlackPieceColor:\r
677       if (ChangeColor(hDlg, &bpc)) \r
678         PaintColorBlock(hDlg, OPT_BlackPieceColor, bpc);\r
679         PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
680             FALSE, mono, pieces);\r
681       break;\r
682 \r
683     case OPT_ChooseHighlightSquareColor:\r
684       if (ChangeColor(hDlg, &hsc)) \r
685         PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);\r
686         PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
687             TRUE, mono, pieces);\r
688       break;\r
689 \r
690     case OPT_ChoosePremoveHighlightColor:\r
691       if (ChangeColor(hDlg, &phc)) \r
692         PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);\r
693         PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
694             FALSE, mono, pieces);\r
695       break;\r
696 \r
697     case OPT_DefaultBoardColors:\r
698       lsc = ParseColorName(LIGHT_SQUARE_COLOR);\r
699       dsc = ParseColorName(DARK_SQUARE_COLOR);\r
700       wpc = ParseColorName(WHITE_PIECE_COLOR);\r
701       bpc = ParseColorName(BLACK_PIECE_COLOR);\r
702       hsc = ParseColorName(HIGHLIGHT_SQUARE_COLOR);\r
703       phc = ParseColorName(PREMOVE_HIGHLIGHT_COLOR);\r
704       mono = FALSE;\r
705       white= FALSE;\r
706       flip = FALSE;\r
707       CheckDlgButton(hDlg, OPT_Monochrome, FALSE);\r
708       CheckDlgButton(hDlg, OPT_AllWhite,   FALSE);\r
709       CheckDlgButton(hDlg, OPT_UpsideDown, FALSE);\r
710       PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);\r
711       PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);\r
712       PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);\r
713       PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);\r
714       PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);\r
715       PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);\r
716       SetBoardOptionEnables(hDlg);\r
717       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
718           TRUE, mono, pieces);\r
719       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
720           FALSE, mono, pieces);\r
721       break;\r
722 \r
723     case OPT_Monochrome:\r
724       mono = !mono;\r
725       SetBoardOptionEnables(hDlg);\r
726       break;\r
727 \r
728     case OPT_AllWhite:\r
729       white = !white;\r
730       SetBoardOptionEnables(hDlg);\r
731       break;\r
732 \r
733     case OPT_UpsideDown:\r
734       flip = !flip;\r
735       SetBoardOptionEnables(hDlg);\r
736       break;\r
737     }\r
738     break;\r
739   }\r
740   return FALSE;\r
741 }\r
742 \r
743 \r
744 VOID\r
745 BoardOptionsPopup(HWND hwnd)\r
746 {\r
747   FARPROC lpProc = MakeProcInstance((FARPROC)BoardOptionsDialog, hInst);\r
748   DialogBox(hInst, MAKEINTRESOURCE(DLG_BoardOptions), hwnd,\r
749           (DLGPROC) lpProc);\r
750   FreeProcInstance(lpProc);\r
751 }\r
752 \r
753 VariantClass\r
754 VariantWhichRadio(HWND hDlg)\r
755 {\r
756   return (IsDlgButtonChecked(hDlg, OPT_VariantFairy) ? VariantFairy :\r
757          (IsDlgButtonChecked(hDlg, OPT_VariantGothic) ? VariantGothic :\r
758          (IsDlgButtonChecked(hDlg, OPT_VariantCrazyhouse) ? VariantCrazyhouse :\r
759          (IsDlgButtonChecked(hDlg, OPT_VariantBughouse) ? VariantBughouse :\r
760          (IsDlgButtonChecked(hDlg, OPT_VariantCourier) ? VariantCourier :\r
761          (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :\r
762          (IsDlgButtonChecked(hDlg, OPT_VariantShogi) ? VariantShogi :\r
763          (IsDlgButtonChecked(hDlg, OPT_VariantXiangqi) ? VariantXiangqi :\r
764          (IsDlgButtonChecked(hDlg, OPT_VariantCapablanca) ? VariantCapablanca :\r
765          (IsDlgButtonChecked(hDlg, OPT_VariantTwoKings) ? VariantTwoKings :\r
766          (IsDlgButtonChecked(hDlg, OPT_VariantKnightmate) ? VariantKnightmate :\r
767          (IsDlgButtonChecked(hDlg, OPT_VariantLosers) ? VariantLosers :\r
768          (IsDlgButtonChecked(hDlg, OPT_VariantSuicide) ? VariantSuicide :\r
769          (IsDlgButtonChecked(hDlg, OPT_VariantAtomic) ? VariantAtomic :\r
770          (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :\r
771          (IsDlgButtonChecked(hDlg, OPT_VariantFRC) ? VariantFischeRandom :\r
772          (IsDlgButtonChecked(hDlg, OPT_VariantCylinder) ? VariantCylinder :\r
773          (IsDlgButtonChecked(hDlg, OPT_VariantFalcon) ? VariantFalcon :\r
774          (IsDlgButtonChecked(hDlg, OPT_VariantCRC) ? VariantCapaRandom :\r
775          (IsDlgButtonChecked(hDlg, OPT_VariantSuper) ? VariantSuper :\r
776          (IsDlgButtonChecked(hDlg, OPT_VariantBerolina) ? VariantBerolina :\r
777          (IsDlgButtonChecked(hDlg, OPT_VariantJanus) ? VariantJanus :\r
778          (IsDlgButtonChecked(hDlg, OPT_VariantWildcastle) ? VariantWildCastle :\r
779          (IsDlgButtonChecked(hDlg, OPT_VariantNocastle) ? VariantNoCastle :\r
780          (IsDlgButtonChecked(hDlg, OPT_Variant3Check) ? Variant3Check :\r
781          (IsDlgButtonChecked(hDlg, OPT_VariantGreat) ? VariantGreat :\r
782          (IsDlgButtonChecked(hDlg, OPT_VariantGiveaway) ? VariantGiveaway :\r
783          (IsDlgButtonChecked(hDlg, OPT_VariantTwilight) ? VariantTwilight :\r
784          (IsDlgButtonChecked(hDlg, OPT_VariantMakruk) ? VariantMakruk :\r
785           VariantNormal )))))))))))))))))))))))))))));\r
786 }\r
787 \r
788 LRESULT CALLBACK\r
789 NewVariantDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
790 {\r
791   static VariantClass v;\r
792   static int n1_ok, n2_ok, n3_ok;\r
793 \r
794   switch (message) {\r
795   case WM_INITDIALOG: /* message: initialize dialog box */\r
796     /* Center the dialog over the application window */\r
797     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
798     /* Initialize the dialog items */\r
799     switch (gameInfo.variant) {\r
800     case VariantNormal:\r
801       CheckDlgButton(hDlg, OPT_VariantNormal, TRUE);\r
802       break;\r
803     case VariantCrazyhouse:\r
804       CheckDlgButton(hDlg, OPT_VariantCrazyhouse, TRUE);\r
805       break;\r
806     case VariantBughouse:\r
807       CheckDlgButton(hDlg, OPT_VariantBughouse, TRUE);\r
808       break;\r
809     case VariantShogi:\r
810       CheckDlgButton(hDlg, OPT_VariantShogi, TRUE);\r
811       break;\r
812     case VariantXiangqi:\r
813       CheckDlgButton(hDlg, OPT_VariantXiangqi, TRUE);\r
814       break;\r
815     case VariantCapablanca:\r
816       CheckDlgButton(hDlg, OPT_VariantCapablanca, TRUE);\r
817       break;\r
818     case VariantGothic:\r
819       CheckDlgButton(hDlg, OPT_VariantGothic, TRUE);\r
820       break;\r
821     case VariantCourier:\r
822       CheckDlgButton(hDlg, OPT_VariantCourier, TRUE);\r
823       break;\r
824     case VariantKnightmate:\r
825       CheckDlgButton(hDlg, OPT_VariantKnightmate, TRUE);\r
826       break;\r
827     case VariantTwoKings:\r
828       CheckDlgButton(hDlg, OPT_VariantTwoKings, TRUE);\r
829       break;\r
830     case VariantFairy:\r
831       CheckDlgButton(hDlg, OPT_VariantFairy, TRUE);\r
832       break;\r
833     case VariantAtomic:\r
834       CheckDlgButton(hDlg, OPT_VariantAtomic, TRUE);\r
835       break;\r
836     case VariantSuicide:\r
837       CheckDlgButton(hDlg, OPT_VariantSuicide, TRUE);\r
838       break;\r
839     case VariantLosers:\r
840       CheckDlgButton(hDlg, OPT_VariantLosers, TRUE);\r
841       break;\r
842     case VariantShatranj:\r
843       CheckDlgButton(hDlg, OPT_VariantShatranj, TRUE);\r
844       break;\r
845     case VariantFischeRandom:\r
846       CheckDlgButton(hDlg, OPT_VariantFRC, TRUE);\r
847       break;\r
848     case VariantCapaRandom:\r
849       CheckDlgButton(hDlg, OPT_VariantCRC, TRUE);\r
850       break;\r
851     case VariantFalcon:\r
852       CheckDlgButton(hDlg, OPT_VariantFalcon, TRUE);\r
853       break;\r
854     case VariantCylinder:\r
855       CheckDlgButton(hDlg, OPT_VariantCylinder, TRUE);\r
856       break;\r
857     case Variant3Check:\r
858       CheckDlgButton(hDlg, OPT_Variant3Check, TRUE);\r
859       break;\r
860     case VariantSuper:\r
861       CheckDlgButton(hDlg, OPT_VariantSuper, TRUE);\r
862       break;\r
863     case VariantBerolina:\r
864       CheckDlgButton(hDlg, OPT_VariantBerolina, TRUE);\r
865       break;\r
866     case VariantJanus:\r
867       CheckDlgButton(hDlg, OPT_VariantJanus, TRUE);\r
868       break;\r
869     case VariantWildCastle:\r
870       CheckDlgButton(hDlg, OPT_VariantWildcastle, TRUE);\r
871       break;\r
872     case VariantNoCastle:\r
873       CheckDlgButton(hDlg, OPT_VariantNocastle, TRUE);\r
874       break;\r
875     case VariantGreat:\r
876       CheckDlgButton(hDlg, OPT_VariantGreat, TRUE);\r
877       break;\r
878     case VariantGiveaway:\r
879       CheckDlgButton(hDlg, OPT_VariantGiveaway, TRUE);\r
880       break;\r
881     case VariantTwilight:\r
882       CheckDlgButton(hDlg, OPT_VariantTwilight, TRUE);\r
883       break;\r
884     case VariantMakruk:\r
885       CheckDlgButton(hDlg, OPT_VariantMakruk, TRUE);\r
886       break;\r
887     default: ;\r
888     }\r
889 \r
890     SetDlgItemInt( hDlg, IDC_Files, -1, TRUE );\r
891     SendDlgItemMessage( hDlg, IDC_Files, EM_SETSEL, 0, -1 );\r
892 \r
893     SetDlgItemInt( hDlg, IDC_Ranks, -1, TRUE );\r
894     SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );\r
895 \r
896     SetDlgItemInt( hDlg, IDC_Holdings, -1, TRUE );\r
897     SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );\r
898 \r
899     n1_ok = n2_ok = n3_ok = FALSE;\r
900 \r
901     return TRUE;\r
902 \r
903   case WM_COMMAND: /* message: received a command */\r
904     switch (LOWORD(wParam)) {\r
905     case IDOK:\r
906       /* \r
907        * if we call EndDialog() after the call to ChangeBoardSize(),\r
908        * then ChangeBoardSize() does not take effect, although the new\r
909        * boardSize is saved. Go figure...\r
910        */\r
911       EndDialog(hDlg, TRUE);\r
912 \r
913       v = VariantWhichRadio(hDlg);\r
914       if(!appData.noChessProgram) { char *name = VariantName(v), buf[MSG_SIZ];\r
915         if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) {\r
916             /* [HGM] in protocol 2 we check if variant is suported by engine */\r
917             sprintf(buf, "Variant %s not supported by %s", name, first.tidy);\r
918             DisplayError(buf, 0);\r
919             return TRUE; /* treat as "Cancel" if first engine does not support it */\r
920         } else\r
921         if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) {\r
922             sprintf(buf, "Warning: second engine (%s) does not support this!", second.tidy);\r
923             DisplayError(buf, 0);   /* use of second engine is optional; only warn user */\r
924         }\r
925       }\r
926 \r
927       gameInfo.variant = v;\r
928       appData.variant = VariantName(v);\r
929 \r
930       appData.NrFiles = (int) GetDlgItemInt(hDlg, IDC_Files, NULL, FALSE );\r
931       appData.NrRanks = (int) GetDlgItemInt(hDlg, IDC_Ranks, NULL, FALSE );\r
932       appData.holdingsSize = (int) GetDlgItemInt(hDlg, IDC_Holdings, NULL, FALSE );\r
933 \r
934       if(!n1_ok) appData.NrFiles = -1;\r
935       if(!n2_ok) appData.NrRanks = -1;\r
936       if(!n3_ok) appData.holdingsSize = -1;\r
937 \r
938       shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */\r
939       startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */\r
940       appData.pieceToCharTable = NULL;\r
941       Reset(TRUE, TRUE);\r
942 \r
943       return TRUE;\r
944 \r
945     case IDCANCEL:\r
946       EndDialog(hDlg, FALSE);\r
947       return TRUE;\r
948 \r
949     case IDC_Ranks:\r
950     case IDC_Files:\r
951     case IDC_Holdings:\r
952         if( HIWORD(wParam) == EN_CHANGE ) {\r
953 \r
954             GetDlgItemInt(hDlg, IDC_Files, &n1_ok, FALSE );\r
955             GetDlgItemInt(hDlg, IDC_Ranks, &n2_ok, FALSE );\r
956             GetDlgItemInt(hDlg, IDC_Holdings, &n3_ok, FALSE );\r
957 \r
958             /*EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok ? TRUE : FALSE );*/\r
959         }\r
960         return TRUE;\r
961     }\r
962     break;\r
963   }\r
964   return FALSE;\r
965 }\r
966 \r
967 \r
968 VOID\r
969 NewVariantPopup(HWND hwnd)\r
970 {\r
971   FARPROC lpProc = MakeProcInstance((FARPROC)NewVariantDialog, hInst);\r
972   DialogBox(hInst, MAKEINTRESOURCE(DLG_NewVariant), hwnd,\r
973           (DLGPROC) lpProc);\r
974   FreeProcInstance(lpProc);\r
975 }\r
976 \r
977 /*---------------------------------------------------------------------------*\\r
978  *\r
979  * ICS Options Dialog functions\r
980  *\r
981 \*---------------------------------------------------------------------------*/\r
982 \r
983 BOOL APIENTRY\r
984 MyCreateFont(HWND hwnd, MyFont *font)\r
985 {\r
986   CHOOSEFONT cf;\r
987   HFONT hf;\r
988 \r
989   /* Initialize members of the CHOOSEFONT structure. */\r
990   cf.lStructSize = sizeof(CHOOSEFONT);\r
991   cf.hwndOwner = hwnd;\r
992   cf.hDC = (HDC)NULL;\r
993   cf.lpLogFont = &font->lf;\r
994   cf.iPointSize = 0;\r
995   cf.Flags = CF_SCREENFONTS|/*CF_ANSIONLY|*/CF_INITTOLOGFONTSTRUCT;\r
996   cf.rgbColors = RGB(0,0,0);\r
997   cf.lCustData = 0L;\r
998   cf.lpfnHook = (LPCFHOOKPROC)NULL;\r
999   cf.lpTemplateName = (LPSTR)NULL;\r
1000   cf.hInstance = (HINSTANCE) NULL;\r
1001   cf.lpszStyle = (LPSTR)NULL;\r
1002   cf.nFontType = SCREEN_FONTTYPE;\r
1003   cf.nSizeMin = 0;\r
1004   cf.nSizeMax = 0;\r
1005 \r
1006   /* Display the CHOOSEFONT common-dialog box. */\r
1007   if (!ChooseFont(&cf)) {\r
1008     return FALSE;\r
1009   }\r
1010 \r
1011   /* Create a logical font based on the user's   */\r
1012   /* selection and return a handle identifying   */\r
1013   /* that font. */\r
1014   hf = CreateFontIndirect(cf.lpLogFont);\r
1015   if (hf == NULL) {\r
1016     return FALSE;\r
1017   }\r
1018 \r
1019   font->hf = hf;\r
1020   font->mfp.pointSize = (float) (cf.iPointSize / 10.0);\r
1021   font->mfp.bold = (font->lf.lfWeight >= FW_BOLD);\r
1022   font->mfp.italic = font->lf.lfItalic;\r
1023   font->mfp.underline = font->lf.lfUnderline;\r
1024   font->mfp.strikeout = font->lf.lfStrikeOut;\r
1025   font->mfp.charset = font->lf.lfCharSet;\r
1026   strcpy(font->mfp.faceName, font->lf.lfFaceName);\r
1027   return TRUE;\r
1028 }\r
1029 \r
1030 \r
1031 VOID\r
1032 UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca)\r
1033 {\r
1034   CHARFORMAT cf;\r
1035   cf.cbSize = sizeof(CHARFORMAT);\r
1036   cf.dwMask = \r
1037     CFM_COLOR|CFM_CHARSET|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE;\r
1038   cf.crTextColor = mca->color;\r
1039   cf.dwEffects = mca->effects;\r
1040   strcpy(cf.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName);\r
1041   /* \r
1042    * The 20.0 below is in fact documented. yHeight is expressed in twips.\r
1043    * A twip is 1/20 of a font's point size. See documentation of CHARFORMAT.\r
1044    * --msw\r
1045    */\r
1046   cf.yHeight = (int)(font[boardSize][CONSOLE_FONT]->mfp.pointSize * 20.0 + 0.5);\r
1047   cf.bCharSet = DEFAULT_CHARSET; /* should be ignored anyway */\r
1048   cf.bPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;\r
1049   SendDlgItemMessage(hDlg, id, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
1050 }\r
1051 \r
1052 LRESULT CALLBACK\r
1053 ColorizeTextDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1054 {\r
1055   static MyColorizeAttribs mca;\r
1056   static ColorClass cc;\r
1057   COLORREF background = (COLORREF)0;\r
1058 \r
1059   switch (message) {\r
1060   case WM_INITDIALOG:\r
1061     cc = (ColorClass)lParam;\r
1062     mca = colorizeAttribs[cc];\r
1063     /* Center the dialog over the application window */\r
1064     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
1065     /* Initialize the dialog items */\r
1066     CheckDlgButton(hDlg, OPT_Bold, (mca.effects & CFE_BOLD) != 0);\r
1067     CheckDlgButton(hDlg, OPT_Italic, (mca.effects & CFE_ITALIC) != 0);\r
1068     CheckDlgButton(hDlg, OPT_Underline, (mca.effects & CFE_UNDERLINE) != 0);\r
1069     CheckDlgButton(hDlg, OPT_Strikeout, (mca.effects & CFE_STRIKEOUT) != 0);\r
1070 \r
1071     /* get the current background color from the parent window */\r
1072     SendMessage(GetWindow(hDlg, GW_OWNER),WM_COMMAND, \r
1073                 (WPARAM)WM_USER_GetConsoleBackground, \r
1074                 (LPARAM)&background);\r
1075 \r
1076     /* set the background color */\r
1077     SendDlgItemMessage(hDlg, OPT_Sample, EM_SETBKGNDCOLOR, FALSE, background);\r
1078 \r
1079     SetDlgItemText(hDlg, OPT_Sample, mca.name);\r
1080     UpdateSampleText(hDlg, OPT_Sample, &mca);\r
1081     return TRUE;\r
1082 \r
1083   case WM_COMMAND: /* message: received a command */\r
1084     switch (LOWORD(wParam)) {\r
1085     case IDOK:\r
1086       /* Read changed options from the dialog box */\r
1087       colorizeAttribs[cc] = mca;\r
1088       textAttribs[cc].color = mca.color;\r
1089       textAttribs[cc].effects = mca.effects;\r
1090       Colorize(currentColorClass, TRUE);\r
1091       if (cc == ColorNormal) {\r
1092         CHARFORMAT cf;\r
1093         cf.cbSize = sizeof(CHARFORMAT);\r
1094         cf.dwMask = CFM_COLOR;\r
1095         cf.crTextColor = mca.color;\r
1096         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
1097           EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
1098       }\r
1099       EndDialog(hDlg, TRUE);\r
1100       return TRUE;\r
1101 \r
1102     case IDCANCEL:\r
1103       EndDialog(hDlg, FALSE);\r
1104       return TRUE;\r
1105 \r
1106     case OPT_ChooseColor:\r
1107       ChangeColor(hDlg, &mca.color);\r
1108       UpdateSampleText(hDlg, OPT_Sample, &mca);\r
1109       return TRUE;\r
1110 \r
1111     default:\r
1112       mca.effects =\r
1113         (IsDlgButtonChecked(hDlg, OPT_Bold) ? CFE_BOLD : 0) |\r
1114         (IsDlgButtonChecked(hDlg, OPT_Italic) ? CFE_ITALIC : 0) |\r
1115         (IsDlgButtonChecked(hDlg, OPT_Underline) ? CFE_UNDERLINE : 0) |\r
1116         (IsDlgButtonChecked(hDlg, OPT_Strikeout) ? CFE_STRIKEOUT : 0);\r
1117       UpdateSampleText(hDlg, OPT_Sample, &mca);\r
1118       break;\r
1119     }\r
1120     break;\r
1121   }\r
1122   return FALSE;\r
1123 }\r
1124 \r
1125 VOID\r
1126 ColorizeTextPopup(HWND hwnd, ColorClass cc)\r
1127 {\r
1128   FARPROC lpProc;\r
1129 \r
1130   lpProc = MakeProcInstance((FARPROC)ColorizeTextDialog, hInst);\r
1131   DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_Colorize),\r
1132     hwnd, (DLGPROC)lpProc, (LPARAM) cc);\r
1133   FreeProcInstance(lpProc);\r
1134 }\r
1135 \r
1136 VOID\r
1137 SetIcsOptionEnables(HWND hDlg)\r
1138 {\r
1139 #define ENABLE_DLG_ITEM(x,y) EnableWindow(GetDlgItem(hDlg,(x)), (y))\r
1140 \r
1141   UINT state = IsDlgButtonChecked(hDlg, OPT_Premove);\r
1142   ENABLE_DLG_ITEM(OPT_PremoveWhite, state);\r
1143   ENABLE_DLG_ITEM(OPT_PremoveWhiteText, state);\r
1144   ENABLE_DLG_ITEM(OPT_PremoveBlack, state);\r
1145   ENABLE_DLG_ITEM(OPT_PremoveBlackText, state);\r
1146 \r
1147   ENABLE_DLG_ITEM(OPT_IcsAlarmTime, IsDlgButtonChecked(hDlg, OPT_IcsAlarm));\r
1148 \r
1149 #undef ENABLE_DLG_ITEM\r
1150 }\r
1151 \r
1152 \r
1153 LRESULT CALLBACK\r
1154 IcsOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1155 {\r
1156   char buf[MSG_SIZ];\r
1157   int number;\r
1158   int i;\r
1159   static COLORREF cbc;\r
1160   static MyColorizeAttribs *mca;\r
1161   COLORREF *colorref;\r
1162 \r
1163   switch (message) {\r
1164   case WM_INITDIALOG: /* message: initialize dialog box */\r
1165 \r
1166     mca = colorizeAttribs;\r
1167 \r
1168     for (i=0; i < NColorClasses - 1; i++) {\r
1169       mca[i].color   = textAttribs[i].color;\r
1170       mca[i].effects = textAttribs[i].effects;\r
1171     }\r
1172     cbc = consoleBackgroundColor;\r
1173 \r
1174     /* Center the dialog over the application window */\r
1175     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
1176 \r
1177     /* Initialize the dialog items */\r
1178 #define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
1179 \r
1180     CHECK_BOX(OPT_AutoComment, appData.autoComment);\r
1181     CHECK_BOX(OPT_AutoObserve, appData.autoObserve);\r
1182     CHECK_BOX(OPT_GetMoveList, appData.getMoveList);\r
1183     CHECK_BOX(OPT_LocalLineEditing, appData.localLineEditing);\r
1184     CHECK_BOX(OPT_QuietPlay, appData.quietPlay);\r
1185     CHECK_BOX(OPT_SeekGraph, appData.seekGraph);\r
1186     CHECK_BOX(OPT_AutoRefresh, appData.autoRefresh);\r
1187     CHECK_BOX(OPT_BgObserve, appData.bgObserve);\r
1188     CHECK_BOX(OPT_DualBoard, appData.dualBoard);\r
1189     CHECK_BOX(OPT_SmartMove, appData.oneClick);\r
1190     CHECK_BOX(OPT_Premove, appData.premove);\r
1191     CHECK_BOX(OPT_PremoveWhite, appData.premoveWhite);\r
1192     CHECK_BOX(OPT_PremoveBlack, appData.premoveBlack);\r
1193     CHECK_BOX(OPT_IcsAlarm, appData.icsAlarm);\r
1194     CHECK_BOX(OPT_DontColorize, !appData.colorize);\r
1195 \r
1196 #undef CHECK_BOX\r
1197 \r
1198     sprintf(buf, "%d", appData.icsAlarmTime / 1000);\r
1199     SetDlgItemText(hDlg, OPT_IcsAlarmTime, buf);\r
1200     SetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText);\r
1201     SetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText);\r
1202     SetDlgItemText(hDlg, OPT_StartupChatBoxes, appData.chatBoxes);\r
1203 \r
1204     SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
1205     SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
1206     SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
1207     SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
1208     SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
1209     SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
1210     SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
1211     SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
1212     SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
1213     SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
1214 \r
1215     SetDlgItemText(hDlg, OPT_SampleShout,     mca[ColorShout].name);\r
1216     SetDlgItemText(hDlg, OPT_SampleSShout,    mca[ColorSShout].name);\r
1217     SetDlgItemText(hDlg, OPT_SampleChannel1,  mca[ColorChannel1].name);\r
1218     SetDlgItemText(hDlg, OPT_SampleChannel,   mca[ColorChannel].name);\r
1219     SetDlgItemText(hDlg, OPT_SampleKibitz,    mca[ColorKibitz].name);\r
1220     SetDlgItemText(hDlg, OPT_SampleTell,      mca[ColorTell].name);\r
1221     SetDlgItemText(hDlg, OPT_SampleChallenge, mca[ColorChallenge].name);\r
1222     SetDlgItemText(hDlg, OPT_SampleRequest,   mca[ColorRequest].name);\r
1223     SetDlgItemText(hDlg, OPT_SampleSeek,      mca[ColorSeek].name);\r
1224     SetDlgItemText(hDlg, OPT_SampleNormal,    mca[ColorNormal].name);\r
1225 \r
1226     UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
1227     UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
1228     UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
1229     UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
1230     UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
1231     UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
1232     UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
1233     UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
1234     UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
1235     UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
1236 \r
1237     SetIcsOptionEnables(hDlg);\r
1238     return TRUE;\r
1239 \r
1240   case WM_COMMAND: /* message: received a command */\r
1241     switch (LOWORD(wParam)) {\r
1242 \r
1243     case WM_USER_GetConsoleBackground: \r
1244       /* the ColorizeTextDialog needs the current background color */\r
1245       colorref = (COLORREF *)lParam;\r
1246       *colorref = cbc;\r
1247       return FALSE;\r
1248 \r
1249     case IDOK:\r
1250       /* Read changed options from the dialog box */\r
1251       GetDlgItemText(hDlg, OPT_IcsAlarmTime, buf, MSG_SIZ);\r
1252       if (sscanf(buf, "%d", &number) != 1 || (number < 0)){\r
1253           MessageBox(hDlg, "Invalid ICS Alarm Time",\r
1254                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
1255           return FALSE;\r
1256       }\r
1257 \r
1258 #define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
1259 \r
1260       appData.icsAlarm         = IS_CHECKED(OPT_IcsAlarm);\r
1261       appData.premove          = IS_CHECKED(OPT_Premove);\r
1262       appData.premoveWhite     = IS_CHECKED(OPT_PremoveWhite);\r
1263       appData.premoveBlack     = IS_CHECKED(OPT_PremoveBlack);\r
1264       appData.autoComment      = IS_CHECKED(OPT_AutoComment);\r
1265       appData.autoObserve      = IS_CHECKED(OPT_AutoObserve);\r
1266       appData.getMoveList      = IS_CHECKED(OPT_GetMoveList);\r
1267       appData.localLineEditing = IS_CHECKED(OPT_LocalLineEditing);\r
1268       appData.quietPlay        = IS_CHECKED(OPT_QuietPlay);\r
1269       appData.seekGraph        = IS_CHECKED(OPT_SeekGraph);\r
1270       appData.autoRefresh      = IS_CHECKED(OPT_AutoRefresh);\r
1271       appData.bgObserve        = IS_CHECKED(OPT_BgObserve);\r
1272       appData.dualBoard        = IS_CHECKED(OPT_DualBoard);\r
1273       appData.oneClick         = IS_CHECKED(OPT_SmartMove);\r
1274 \r
1275 #undef IS_CHECKED\r
1276 \r
1277       appData.icsAlarmTime = number * 1000;\r
1278       GetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText, 5);\r
1279       GetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText, 5);\r
1280       GetDlgItemText(hDlg, OPT_StartupChatBoxes, buf, sizeof(buf));\r
1281       buf[sizeof(buf)-1] = NULLCHAR; appData.chatBoxes = StrSave(buf); // memory leak\r
1282 \r
1283       if (appData.localLineEditing) {\r
1284         DontEcho();\r
1285         EchoOn();\r
1286       } else {\r
1287         DoEcho();\r
1288         EchoOff();\r
1289       }\r
1290 \r
1291       appData.colorize =\r
1292         (Boolean)!IsDlgButtonChecked(hDlg, OPT_DontColorize);\r
1293 \r
1294     ChangedConsoleFont();\r
1295 \r
1296     if (!appData.colorize) {\r
1297         CHARFORMAT cf;\r
1298         COLORREF background = ParseColorName(COLOR_BKGD);\r
1299         /*\r
1300         SetDefaultTextAttribs();\r
1301         Colorize(currentColorClass);\r
1302         */\r
1303         cf.cbSize = sizeof(CHARFORMAT);\r
1304         cf.dwMask = CFM_COLOR;\r
1305         cf.crTextColor = ParseColorName(COLOR_NORMAL);\r
1306 \r
1307         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
1308           EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
1309         SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
1310           EM_SETBKGNDCOLOR, FALSE, background);\r
1311         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
1312           EM_SETBKGNDCOLOR, FALSE, background);\r
1313       }\r
1314 \r
1315       if (cbc != consoleBackgroundColor) {\r
1316         consoleBackgroundColor = cbc;\r
1317         if (appData.colorize) {\r
1318           SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
1319             EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
1320           SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
1321             EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
1322         }\r
1323       }\r
1324 \r
1325       for (i=0; i < NColorClasses - 1; i++) {\r
1326         textAttribs[i].color   = mca[i].color;\r
1327         textAttribs[i].effects = mca[i].effects;\r
1328       }\r
1329 \r
1330       EndDialog(hDlg, TRUE);\r
1331       return TRUE;\r
1332 \r
1333     case IDCANCEL:\r
1334       EndDialog(hDlg, FALSE);\r
1335       return TRUE;\r
1336 \r
1337     case OPT_ChooseShoutColor:\r
1338       ColorizeTextPopup(hDlg, ColorShout);\r
1339       UpdateSampleText(hDlg, OPT_SampleShout, &mca[ColorShout]);\r
1340       break;\r
1341 \r
1342     case OPT_ChooseSShoutColor:\r
1343       ColorizeTextPopup(hDlg, ColorSShout);\r
1344       UpdateSampleText(hDlg, OPT_SampleSShout, &mca[ColorSShout]);\r
1345       break;\r
1346 \r
1347     case OPT_ChooseChannel1Color:\r
1348       ColorizeTextPopup(hDlg, ColorChannel1);\r
1349       UpdateSampleText(hDlg, OPT_SampleChannel1, \r
1350                        &colorizeAttribs[ColorChannel1]);\r
1351       break;\r
1352 \r
1353     case OPT_ChooseChannelColor:\r
1354       ColorizeTextPopup(hDlg, ColorChannel);\r
1355       UpdateSampleText(hDlg, OPT_SampleChannel, &mca[ColorChannel]);\r
1356       break;\r
1357 \r
1358     case OPT_ChooseKibitzColor:\r
1359       ColorizeTextPopup(hDlg, ColorKibitz);\r
1360       UpdateSampleText(hDlg, OPT_SampleKibitz, &mca[ColorKibitz]);\r
1361       break;\r
1362 \r
1363     case OPT_ChooseTellColor:\r
1364       ColorizeTextPopup(hDlg, ColorTell);\r
1365       UpdateSampleText(hDlg, OPT_SampleTell, &mca[ColorTell]);\r
1366       break;\r
1367 \r
1368     case OPT_ChooseChallengeColor:\r
1369       ColorizeTextPopup(hDlg, ColorChallenge);\r
1370       UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
1371       break;\r
1372 \r
1373     case OPT_ChooseRequestColor:\r
1374       ColorizeTextPopup(hDlg, ColorRequest);\r
1375       UpdateSampleText(hDlg, OPT_SampleRequest, &mca[ColorRequest]);\r
1376       break;\r
1377 \r
1378     case OPT_ChooseSeekColor:\r
1379       ColorizeTextPopup(hDlg, ColorSeek);\r
1380       UpdateSampleText(hDlg, OPT_SampleSeek, &mca[ColorSeek]);\r
1381       break;\r
1382 \r
1383     case OPT_ChooseNormalColor:\r
1384       ColorizeTextPopup(hDlg, ColorNormal);\r
1385       UpdateSampleText(hDlg, OPT_SampleNormal, &mca[ColorNormal]);\r
1386       break;\r
1387 \r
1388     case OPT_ChooseBackgroundColor:\r
1389       if (ChangeColor(hDlg, &cbc)) {\r
1390         SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
1391         SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
1392         SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
1393         SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
1394         SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
1395         SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
1396         SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
1397         SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
1398         SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
1399         SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
1400       }\r
1401       break;\r
1402 \r
1403     case OPT_DefaultColors:\r
1404       for (i=0; i < NColorClasses - 1; i++)\r
1405         ParseAttribs(&mca[i].color, \r
1406                      &mca[i].effects,\r
1407                      defaultTextAttribs[i]);\r
1408 \r
1409       cbc = ParseColorName(COLOR_BKGD);\r
1410       SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
1411       SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
1412       SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
1413       SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
1414       SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
1415       SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
1416       SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
1417       SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
1418       SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
1419       SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
1420 \r
1421       UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
1422       UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
1423       UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
1424       UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
1425       UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
1426       UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
1427       UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
1428       UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
1429       UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
1430       UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
1431       break;\r
1432 \r
1433     default:\r
1434       SetIcsOptionEnables(hDlg);\r
1435       break;\r
1436     }\r
1437     break;\r
1438   }\r
1439   return FALSE;\r
1440 }\r
1441 \r
1442 VOID\r
1443 IcsOptionsPopup(HWND hwnd)\r
1444 {\r
1445   FARPROC lpProc = MakeProcInstance((FARPROC)IcsOptionsDialog, hInst);\r
1446   DialogBox(hInst, MAKEINTRESOURCE(DLG_IcsOptions), hwnd,\r
1447             (DLGPROC) lpProc);\r
1448   FreeProcInstance(lpProc);\r
1449 }\r
1450 \r
1451 /*---------------------------------------------------------------------------*\\r
1452  *\r
1453  * Fonts Dialog functions\r
1454  *\r
1455 \*---------------------------------------------------------------------------*/\r
1456 \r
1457 VOID\r
1458 SetSampleFontText(HWND hwnd, int id, const MyFont *mf)\r
1459 {\r
1460   char buf[MSG_SIZ];\r
1461   HWND hControl;\r
1462   HDC hdc;\r
1463   CHARFORMAT cf;\r
1464   SIZE size;\r
1465   RECT rectClient, rectFormat;\r
1466   HFONT oldFont;\r
1467   POINT center;\r
1468   int len;\r
1469 \r
1470   len = sprintf(buf, "%.0f pt. %s%s%s\n",\r
1471                 mf->mfp.pointSize, mf->mfp.faceName,\r
1472                 mf->mfp.bold ? " bold" : "",\r
1473                 mf->mfp.italic ? " italic" : "");\r
1474   SetDlgItemText(hwnd, id, buf);\r
1475 \r
1476   hControl = GetDlgItem(hwnd, id);\r
1477   hdc = GetDC(hControl);\r
1478   SetMapMode(hdc, MM_TEXT);     /* 1 pixel == 1 logical unit */\r
1479   oldFont = SelectObject(hdc, mf->hf);\r
1480   \r
1481   /* get number of logical units necessary to display font name */\r
1482   GetTextExtentPoint32(hdc, buf, len, &size);\r
1483 \r
1484   /* calculate formatting rectangle in the rich edit control.  \r
1485    * May be larger or smaller than the actual control.\r
1486    */\r
1487   GetClientRect(hControl, &rectClient);\r
1488   center.x = (rectClient.left + rectClient.right) / 2;\r
1489   center.y = (rectClient.top  + rectClient.bottom) / 2;\r
1490   rectFormat.top    = center.y - (size.cy / 2) - 1;\r
1491   rectFormat.bottom = center.y + (size.cy / 2) + 1;\r
1492   rectFormat.left   = center.x - (size.cx / 2) - 1;\r
1493   rectFormat.right  = center.x + (size.cx / 2) + 1;\r
1494 \r
1495   cf.cbSize = sizeof(CHARFORMAT);\r
1496   cf.dwMask = CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_BOLD|CFM_ITALIC;\r
1497   cf.dwEffects = 0;\r
1498   if (mf->lf.lfWeight == FW_BOLD) cf.dwEffects |= CFE_BOLD;\r
1499   if (mf->lf.lfItalic) cf.dwEffects |= CFE_ITALIC;\r
1500   strcpy(cf.szFaceName, mf->mfp.faceName);\r
1501   /*\r
1502    * yHeight is expressed in twips.  A twip is 1/20 of a font's point\r
1503    * size. See documentation of CHARFORMAT.  --msw\r
1504    */\r
1505   cf.yHeight = (int)(mf->mfp.pointSize * 20.0 + 0.5);\r
1506   cf.bCharSet = mf->lf.lfCharSet;\r
1507   cf.bPitchAndFamily = mf->lf.lfPitchAndFamily;\r
1508 \r
1509   /* format the text in the rich edit control */\r
1510   SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf);\r
1511   SendMessage(hControl, EM_SETRECT, (WPARAM)0, (LPARAM) &rectFormat);\r
1512 \r
1513   /* clean up */\r
1514   SelectObject(hdc, oldFont);\r
1515   ReleaseDC(hControl, hdc);\r
1516 }\r
1517 \r
1518 VOID\r
1519 CopyFont(MyFont *dest, const MyFont *src)\r
1520 {\r
1521   dest->mfp.pointSize = src->mfp.pointSize;\r
1522   dest->mfp.bold      = src->mfp.bold;\r
1523   dest->mfp.italic    = src->mfp.italic;\r
1524   dest->mfp.underline = src->mfp.underline;\r
1525   dest->mfp.strikeout = src->mfp.strikeout;\r
1526   dest->mfp.charset   = src->mfp.charset;\r
1527   lstrcpy(dest->mfp.faceName, src->mfp.faceName);\r
1528   CreateFontInMF(dest);\r
1529 }\r
1530 \r
1531 \r
1532 LRESULT CALLBACK\r
1533 FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1534 {\r
1535   static MyFont workFont[NUM_FONTS];\r
1536   static BOOL firstPaint;\r
1537   int i;\r
1538   RECT rect;\r
1539 \r
1540   switch (message) {\r
1541   case WM_INITDIALOG:\r
1542 \r
1543     /* copy the current font settings into a working copy */\r
1544     for (i=0; i < NUM_FONTS; i++)\r
1545       CopyFont(&workFont[i], font[boardSize][i]);\r
1546 \r
1547     if (!appData.icsActive)\r
1548       EnableWindow(GetDlgItem(hDlg, OPT_ChooseConsoleFont), FALSE);\r
1549 \r
1550     firstPaint = TRUE;  /* see rant below */\r
1551 \r
1552     /* If I don't call SetFocus(), the dialog won't respond to the keyboard\r
1553      * when first drawn. Why is this the only dialog that behaves this way? Is\r
1554      * is the WM_PAINT stuff below?? Sigh...\r
1555      */\r
1556     SetFocus(GetDlgItem(hDlg, IDOK));\r
1557     break;\r
1558 \r
1559   case WM_PAINT:\r
1560     /* This should not be necessary. However, if SetSampleFontText() is called\r
1561      * in response to WM_INITDIALOG, the strings are not properly centered in\r
1562      * the controls when the dialog first appears. I can't figure out why, so\r
1563      * this is the workaround.  --msw\r
1564      */\r
1565     if (firstPaint) {\r
1566       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1567       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1568       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1569       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1570       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1571       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1572       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1573       firstPaint = FALSE;\r
1574     }\r
1575     break;\r
1576 \r
1577   case WM_COMMAND: /* message: received a command */\r
1578     switch (LOWORD(wParam)) {\r
1579 \r
1580     case IDOK:\r
1581       /* again, it seems to avoid redraw problems if we call EndDialog first */\r
1582       EndDialog(hDlg, FALSE);\r
1583 \r
1584       /* copy modified settings back to the fonts array */\r
1585       for (i=0; i < NUM_FONTS; i++)\r
1586         CopyFont(font[boardSize][i], &workFont[i]);\r
1587 \r
1588       /* a sad necessity due to the original design of having a separate\r
1589        * console font, tags font, and comment font for each board size.  IMHO\r
1590        * these fonts should not be dependent on the current board size.  I'm\r
1591        * running out of time, so I am doing this hack rather than redesign the\r
1592        * data structure. Besides, I think if I redesigned the data structure, I\r
1593        * might break backwards compatibility with old winboard.ini files.\r
1594        * --msw\r
1595        */\r
1596       for (i=0; i < NUM_SIZES; i++) {\r
1597         CopyFont(font[i][EDITTAGS_FONT], &workFont[EDITTAGS_FONT]);\r
1598         CopyFont(font[i][CONSOLE_FONT],  &workFont[CONSOLE_FONT]);\r
1599         CopyFont(font[i][COMMENT_FONT],  &workFont[COMMENT_FONT]);\r
1600         CopyFont(font[i][MOVEHISTORY_FONT],  &workFont[MOVEHISTORY_FONT]);\r
1601       }\r
1602       /* end sad necessity */\r
1603 \r
1604       InitDrawingSizes(boardSize, 0);\r
1605       InvalidateRect(hwndMain, NULL, TRUE);\r
1606 \r
1607       if (commentDialog) {\r
1608         SendDlgItemMessage(commentDialog, OPT_CommentText,\r
1609           WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf, \r
1610           MAKELPARAM(TRUE, 0));\r
1611         GetClientRect(GetDlgItem(commentDialog, OPT_CommentText), &rect);\r
1612         InvalidateRect(commentDialog, &rect, TRUE);\r
1613       }\r
1614 \r
1615       if (editTagsDialog) {\r
1616         SendDlgItemMessage(editTagsDialog, OPT_TagsText,\r
1617           WM_SETFONT, (WPARAM)font[boardSize][EDITTAGS_FONT]->hf, \r
1618           MAKELPARAM(TRUE, 0));\r
1619         GetClientRect(GetDlgItem(editTagsDialog, OPT_TagsText), &rect);\r
1620         InvalidateRect(editTagsDialog, &rect, TRUE);\r
1621       }\r
1622 \r
1623       if( moveHistoryDialog != NULL ) {\r
1624         SendDlgItemMessage(moveHistoryDialog, IDC_MoveHistory,\r
1625           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
1626           MAKELPARAM(TRUE, 0));\r
1627         SendMessage( moveHistoryDialog, WM_INITDIALOG, 0, 0 );\r
1628 //      InvalidateRect(editTagsDialog, NULL, TRUE); // [HGM] this ws improperly cloned?\r
1629       }\r
1630 \r
1631       if( engineOutputDialog != NULL ) {\r
1632         SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo1,\r
1633           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
1634           MAKELPARAM(TRUE, 0));\r
1635         SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo2,\r
1636           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
1637           MAKELPARAM(TRUE, 0));\r
1638       }\r
1639 \r
1640       if (hwndConsole) {\r
1641         ChangedConsoleFont();\r
1642       }\r
1643 \r
1644       for (i=0; i<NUM_FONTS; i++)\r
1645         DeleteObject(&workFont[i].hf);\r
1646 \r
1647       return TRUE;\r
1648 \r
1649     case IDCANCEL:\r
1650       for (i=0; i<NUM_FONTS; i++)\r
1651         DeleteObject(&workFont[i].hf);\r
1652       EndDialog(hDlg, FALSE);\r
1653       return TRUE;\r
1654 \r
1655     case OPT_ChooseClockFont:\r
1656       MyCreateFont(hDlg, &workFont[CLOCK_FONT]);\r
1657       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1658       break;\r
1659 \r
1660     case OPT_ChooseMessageFont:\r
1661       MyCreateFont(hDlg, &workFont[MESSAGE_FONT]);\r
1662       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1663       break;\r
1664 \r
1665     case OPT_ChooseCoordFont:\r
1666       MyCreateFont(hDlg, &workFont[COORD_FONT]);\r
1667       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1668       break;\r
1669 \r
1670     case OPT_ChooseTagFont:\r
1671       MyCreateFont(hDlg, &workFont[EDITTAGS_FONT]);\r
1672       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1673       break;\r
1674 \r
1675     case OPT_ChooseCommentsFont:\r
1676       MyCreateFont(hDlg, &workFont[COMMENT_FONT]);\r
1677       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1678       break;\r
1679 \r
1680     case OPT_ChooseConsoleFont:\r
1681       MyCreateFont(hDlg, &workFont[CONSOLE_FONT]);\r
1682       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1683       break;\r
1684 \r
1685     case OPT_ChooseMoveHistoryFont:\r
1686       MyCreateFont(hDlg, &workFont[MOVEHISTORY_FONT]);\r
1687       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1688       break;\r
1689 \r
1690     case OPT_DefaultFonts:\r
1691       for (i=0; i<NUM_FONTS; i++) {\r
1692         DeleteObject(&workFont[i].hf);\r
1693         ParseFontName(font[boardSize][i]->def, &workFont[i].mfp);\r
1694         CreateFontInMF(&workFont[i]);\r
1695       }\r
1696       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1697       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1698       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1699       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1700       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1701       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1702       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1703       break;\r
1704     }\r
1705   }\r
1706   return FALSE;\r
1707 }\r
1708 \r
1709 VOID\r
1710 FontsOptionsPopup(HWND hwnd)\r
1711 {\r
1712   FARPROC lpProc = MakeProcInstance((FARPROC)FontOptionsDialog, hInst);\r
1713   DialogBox(hInst, MAKEINTRESOURCE(DLG_Fonts), hwnd,\r
1714           (DLGPROC) lpProc);\r
1715   FreeProcInstance(lpProc);\r
1716 }\r
1717 \r
1718 /*---------------------------------------------------------------------------*\\r
1719  *\r
1720  * Sounds Dialog functions\r
1721  *\r
1722 \*---------------------------------------------------------------------------*/\r
1723 \r
1724 \r
1725 SoundComboData soundComboData[] = {\r
1726   {"Move", NULL},\r
1727   {"Bell", NULL},\r
1728   {"ICS Alarm", NULL},\r
1729   {"ICS Win", NULL},\r
1730   {"ICS Loss", NULL},\r
1731   {"ICS Draw", NULL},\r
1732   {"ICS Unfinished", NULL},\r
1733   {"Shout", NULL},\r
1734   {"SShout/CShout", NULL},\r
1735   {"Channel 1", NULL},\r
1736   {"Channel", NULL},\r
1737   {"Kibitz", NULL},\r
1738   {"Tell", NULL},\r
1739   {"Challenge", NULL},\r
1740   {"Request", NULL},\r
1741   {"Seek", NULL},\r
1742   {NULL, NULL},\r
1743 };\r
1744 \r
1745 \r
1746 void\r
1747 InitSoundComboData(SoundComboData *scd)\r
1748 {\r
1749   SoundClass sc;\r
1750   ColorClass cc;\r
1751   int index;\r
1752 \r
1753   /* copy current sound settings to combo array */\r
1754 \r
1755   for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
1756     scd[sc].name = strdup(sounds[sc].name);\r
1757   }\r
1758   for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
1759     index = (int)cc + (int)NSoundClasses;\r
1760     scd[index].name = strdup(textAttribs[cc].sound.name);\r
1761   }\r
1762 }\r
1763 \r
1764 \r
1765 void\r
1766 ResetSoundComboData(SoundComboData *scd)\r
1767 {\r
1768   while (scd->label) {\r
1769     if (scd->name != NULL) {\r
1770       free (scd->name);\r
1771       scd->name = NULL;\r
1772     }\r
1773     scd++;\r
1774   }\r
1775 }\r
1776 \r
1777 void\r
1778 InitSoundCombo(HWND hwndCombo, SoundComboData *scd)\r
1779 {\r
1780   char buf[255];\r
1781   DWORD err;\r
1782   DWORD cnt = 0;\r
1783   SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
1784 \r
1785   /* send the labels to the combo box */\r
1786   while (scd->label) {\r
1787     err = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) scd->label);\r
1788     if (err != cnt++) {\r
1789       sprintf(buf, "InitSoundCombo(): err '%d', cnt '%d'\n",\r
1790           (int)err, (int)cnt);\r
1791       MessageBox(NULL, buf, NULL, MB_OK);\r
1792     }\r
1793     scd++;\r
1794   }\r
1795   SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
1796 }\r
1797 \r
1798 int\r
1799 SoundDialogWhichRadio(HWND hDlg)\r
1800 {\r
1801   if (IsDlgButtonChecked(hDlg, OPT_NoSound)) return OPT_NoSound;\r
1802   if (IsDlgButtonChecked(hDlg, OPT_DefaultBeep)) return OPT_DefaultBeep;\r
1803   if (IsDlgButtonChecked(hDlg, OPT_BuiltInSound)) return OPT_BuiltInSound;\r
1804   if (IsDlgButtonChecked(hDlg, OPT_WavFile)) return OPT_WavFile;\r
1805   return -1;\r
1806 }\r
1807 \r
1808 VOID\r
1809 SoundDialogSetEnables(HWND hDlg, int radio)\r
1810 {\r
1811   EnableWindow(GetDlgItem(hDlg, OPT_BuiltInSoundName),\r
1812                radio == OPT_BuiltInSound);\r
1813   EnableWindow(GetDlgItem(hDlg, OPT_WavFileName), radio == OPT_WavFile);\r
1814   EnableWindow(GetDlgItem(hDlg, OPT_BrowseSound), radio == OPT_WavFile);\r
1815 }\r
1816 \r
1817 char *\r
1818 SoundDialogGetName(HWND hDlg, int radio)\r
1819 {\r
1820   static char buf[MSG_SIZ], buf2[MSG_SIZ], buf3[MSG_SIZ];\r
1821   char *dummy, *ret;\r
1822   switch (radio) {\r
1823   case OPT_NoSound:\r
1824   default:\r
1825     return "";\r
1826   case OPT_DefaultBeep:\r
1827     return "$";\r
1828   case OPT_BuiltInSound:\r
1829     buf[0] = '!';\r
1830     GetDlgItemText(hDlg, OPT_BuiltInSoundName, buf + 1, sizeof(buf) - 1);\r
1831     return buf;\r
1832   case OPT_WavFile:\r
1833     GetDlgItemText(hDlg, OPT_WavFileName, buf, sizeof(buf));\r
1834     GetCurrentDirectory(MSG_SIZ, buf3);\r
1835     SetCurrentDirectory(installDir);\r
1836     if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
1837       ret = buf2;\r
1838     } else {\r
1839       ret = buf;\r
1840     }\r
1841     SetCurrentDirectory(buf3);\r
1842     return ret;\r
1843   }\r
1844 }\r
1845 \r
1846 void\r
1847 DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name)\r
1848 {\r
1849   int radio;\r
1850   /* \r
1851    * I think it's best to clear the combo and edit boxes. It looks stupid\r
1852    * to have a value from another sound event sitting there grayed out.\r
1853    */\r
1854   SetDlgItemText(hDlg, OPT_WavFileName, "");\r
1855   SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
1856 \r
1857   if (appData.debugMode)\r
1858       fprintf(debugFP, "DisplaySelectedSound(,,'%s'):\n", name);\r
1859   switch (name[0]) {\r
1860   case NULLCHAR:\r
1861     radio = OPT_NoSound;\r
1862     break;\r
1863   case '$':\r
1864     if (name[1] == NULLCHAR) {\r
1865       radio = OPT_DefaultBeep;\r
1866     } else {\r
1867       radio = OPT_WavFile;\r
1868       SetDlgItemText(hDlg, OPT_WavFileName, name);\r
1869     }\r
1870     break;\r
1871   case '!':\r
1872     if (name[1] == NULLCHAR) {\r
1873       radio = OPT_NoSound;\r
1874     } else {\r
1875       radio = OPT_BuiltInSound;\r
1876       if (SendMessage(hCombo, CB_SELECTSTRING, (WPARAM) -1, \r
1877                       (LPARAM) (name + 1)) == CB_ERR) {\r
1878         SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
1879         SendMessage(hCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) (name + 1));\r
1880       }\r
1881     }\r
1882     break;\r
1883   default:\r
1884     radio = OPT_WavFile;\r
1885     SetDlgItemText(hDlg, OPT_WavFileName, name);\r
1886     break;\r
1887   }\r
1888   SoundDialogSetEnables(hDlg, radio);\r
1889   CheckRadioButton(hDlg, OPT_NoSound, OPT_WavFile, radio);\r
1890 }\r
1891     \r
1892 \r
1893 char *builtInSoundNames[] = BUILT_IN_SOUND_NAMES;\r
1894 \r
1895 LRESULT CALLBACK\r
1896 SoundOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1897 {\r
1898   static HWND hSoundCombo;\r
1899   static DWORD index;\r
1900   static HWND hBISN;\r
1901   int radio;\r
1902   MySound tmp;\r
1903   FILE *f;\r
1904   char buf[MSG_SIZ];\r
1905   char *newName;\r
1906   SoundClass sc;\r
1907   ColorClass cc;\r
1908   SoundComboData *scd;\r
1909   int oldMute;\r
1910 \r
1911   switch (message) {\r
1912   case WM_INITDIALOG:\r
1913     /* Center the dialog over the application window */\r
1914     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
1915 \r
1916     /* Initialize the built-in sounds combo */\r
1917     hBISN = GetDlgItem(hDlg, OPT_BuiltInSoundName);\r
1918      InitComboStrings(hBISN, builtInSoundNames);\r
1919 \r
1920     /* Initialize the  sound events combo */\r
1921     index = 0;\r
1922     InitSoundComboData(soundComboData);\r
1923     hSoundCombo = GetDlgItem(hDlg, CBO_Sounds);\r
1924     InitSoundCombo(hSoundCombo, soundComboData);\r
1925 \r
1926     /* update the dialog */\r
1927     DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
1928     return TRUE;\r
1929 \r
1930   case WM_COMMAND: /* message: received a command */\r
1931 \r
1932     if (((HWND)lParam == hSoundCombo) && \r
1933         (HIWORD(wParam) == CBN_SELCHANGE)) {\r
1934       /* \r
1935        * the user has selected a new sound event. We must store the name for\r
1936        * the previously selected event, then retrieve the name for the\r
1937        * newly selected event and update the dialog. \r
1938        */\r
1939       radio = SoundDialogWhichRadio(hDlg);\r
1940       newName = strdup(SoundDialogGetName(hDlg, radio));\r
1941       \r
1942       if (strcmp(newName, soundComboData[index].name) != 0) {\r
1943         free(soundComboData[index].name);\r
1944         soundComboData[index].name = newName;\r
1945       } else {\r
1946         free(newName);\r
1947         newName = NULL;\r
1948       }\r
1949       /* now get the settings for the newly selected event */\r
1950       index = SendMessage(hSoundCombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);\r
1951       DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
1952       \r
1953       return TRUE;\r
1954     }\r
1955     switch (LOWORD(wParam)) {\r
1956     case IDOK:\r
1957       /* \r
1958        * save the name for the currently selected sound event \r
1959        */\r
1960       radio = SoundDialogWhichRadio(hDlg);\r
1961       newName = strdup(SoundDialogGetName(hDlg, radio));\r
1962 \r
1963       if (strcmp(soundComboData[index].name, newName) != 0) {\r
1964         free(soundComboData[index].name);\r
1965         soundComboData[index].name = newName;\r
1966       } else {\r
1967         free(newName);\r
1968         newName = NULL;\r
1969       }\r
1970 \r
1971       /* save all the sound names that changed and load the sounds */\r
1972 \r
1973       for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
1974         if (strcmp(soundComboData[sc].name, sounds[sc].name) != 0) {\r
1975           free(sounds[sc].name);\r
1976           sounds[sc].name = strdup(soundComboData[sc].name);\r
1977           MyLoadSound(&sounds[sc]);\r
1978         }\r
1979       }\r
1980       for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
1981         index = (int)cc + (int)NSoundClasses;\r
1982         if (strcmp(soundComboData[index].name, \r
1983                    textAttribs[cc].sound.name) != 0) {\r
1984           free(textAttribs[cc].sound.name);\r
1985           textAttribs[cc].sound.name = strdup(soundComboData[index].name);\r
1986           MyLoadSound(&textAttribs[cc].sound);\r
1987         }\r
1988       }\r
1989 \r
1990         mute = FALSE; // [HGM] mute: switch sounds automatically on if we select one\r
1991       CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds,MF_BYCOMMAND|MF_UNCHECKED);\r
1992       ResetSoundComboData(soundComboData);\r
1993       EndDialog(hDlg, TRUE);\r
1994       return TRUE;\r
1995 \r
1996     case IDCANCEL:\r
1997       ResetSoundComboData(soundComboData);\r
1998       EndDialog(hDlg, FALSE);\r
1999       return TRUE;\r
2000 \r
2001     case OPT_DefaultSounds:\r
2002       /* can't use SetDefaultSounds() because we need to be able to "undo" if\r
2003        * user selects "Cancel" later on. So we do it the hard way here.\r
2004        */\r
2005       scd = &soundComboData[0];\r
2006       while (scd->label != NULL) {\r
2007         if (scd->name != NULL) free(scd->name);\r
2008         scd->name = strdup("");\r
2009         scd++;\r
2010       }\r
2011       free(soundComboData[(int)SoundBell].name);\r
2012       soundComboData[(int)SoundBell].name = strdup(SOUND_BELL);\r
2013       DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
2014       break;\r
2015 \r
2016     case OPT_PlaySound:\r
2017       radio = SoundDialogWhichRadio(hDlg);\r
2018       tmp.name = strdup(SoundDialogGetName(hDlg, radio));\r
2019       tmp.data = NULL;\r
2020       MyLoadSound(&tmp);\r
2021         oldMute = mute; mute = FALSE; // [HGM] mute: always sound when user presses play, ignorig mute setting\r
2022       MyPlaySound(&tmp);\r
2023         mute = oldMute;\r
2024       if (tmp.data  != NULL) FreeResource(tmp.data); // technically obsolete fn, but tmp.data is NOT malloc'd mem\r
2025       if (tmp.name != NULL) free(tmp.name);\r
2026       return TRUE;\r
2027 \r
2028     case OPT_BrowseSound:\r
2029       f = OpenFileDialog(hDlg, "rb", NULL, "wav", SOUND_FILT,\r
2030         "Browse for Sound File", NULL, NULL, buf);\r
2031       if (f != NULL) {\r
2032         fclose(f);\r
2033         SetDlgItemText(hDlg, OPT_WavFileName, buf);\r
2034       }\r
2035       return TRUE;\r
2036 \r
2037     default:\r
2038       radio = SoundDialogWhichRadio(hDlg);\r
2039       SoundDialogSetEnables(hDlg, radio);\r
2040       break;\r
2041     }\r
2042     break;\r
2043   }\r
2044   return FALSE;\r
2045 }\r
2046 \r
2047 \r
2048 VOID SoundOptionsPopup(HWND hwnd)\r
2049 {\r
2050   FARPROC lpProc;\r
2051 \r
2052   lpProc = MakeProcInstance((FARPROC)SoundOptionsDialog, hInst);\r
2053   DialogBox(hInst, MAKEINTRESOURCE(DLG_Sound), hwnd, (DLGPROC)lpProc);\r
2054   FreeProcInstance(lpProc);\r
2055 }\r
2056 \r
2057 \r
2058 /*---------------------------------------------------------------------------*\\r
2059  *\r
2060  * Comm Port dialog functions\r
2061  *\r
2062 \*---------------------------------------------------------------------------*/\r
2063 \r
2064 \r
2065 #define FLOW_NONE   0\r
2066 #define FLOW_XOFF   1\r
2067 #define FLOW_CTS    2\r
2068 #define FLOW_DSR    3\r
2069 \r
2070 #define PORT_NONE\r
2071 \r
2072 ComboData cdPort[]     = { {"None", PORT_NONE}, {"COM1", 1}, {"COM2", 2},\r
2073                            {"COM3", 3}, {"COM4", 4}, {NULL, 0} };\r
2074 ComboData cdDataRate[] = { {"110", 110}, {"300", 300}, {"600", 600}, {"1200", 1200},\r
2075                            {"2400", 2400}, {"4800", 4800}, {"9600", 9600}, {"19200", 19200},\r
2076                            {"38400", 38400}, {NULL, 0} };\r
2077 ComboData cdDataBits[] = { {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {NULL, 0} };\r
2078 ComboData cdParity[]   = { {"None", NOPARITY}, {"Odd", ODDPARITY}, {"Even", EVENPARITY},\r
2079                            {"Mark", MARKPARITY}, {"Space", SPACEPARITY}, {NULL, 0} };\r
2080 ComboData cdStopBits[] = { {"1", ONESTOPBIT}, {"1.5", ONE5STOPBITS},\r
2081                            {"2", TWOSTOPBITS}, {NULL, 0} };\r
2082 ComboData cdFlow[]     = { {"None", FLOW_NONE}, {"Xoff/Xon", FLOW_XOFF}, {"CTS", FLOW_CTS},\r
2083                            {"DSR", FLOW_DSR}, {NULL, 0} };\r
2084 \r
2085 \r
2086 VOID\r
2087 ParseCommSettings(char *arg, DCB *dcb)\r
2088 {\r
2089   int dataRate, count;\r
2090   char bits[MSG_SIZ], parity[MSG_SIZ], stopBits[MSG_SIZ], flow[MSG_SIZ];\r
2091   ComboData *cd;\r
2092   count = sscanf(arg, "%d%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]",\r
2093     &dataRate, bits, parity, stopBits, flow);\r
2094   if (count != 5) goto cant_parse;\r
2095   dcb->BaudRate = dataRate;\r
2096   cd = cdDataBits;\r
2097   while (cd->label != NULL) {\r
2098     if (StrCaseCmp(cd->label, bits) == 0) {\r
2099       dcb->ByteSize = cd->value;\r
2100       break;\r
2101     }\r
2102     cd++;\r
2103   }\r
2104   if (cd->label == NULL) goto cant_parse;\r
2105   cd = cdParity;\r
2106   while (cd->label != NULL) {\r
2107     if (StrCaseCmp(cd->label, parity) == 0) {\r
2108       dcb->Parity = cd->value;\r
2109       break;\r
2110     }\r
2111     cd++;\r
2112   }\r
2113   if (cd->label == NULL) goto cant_parse;\r
2114   cd = cdStopBits;\r
2115   while (cd->label != NULL) {\r
2116     if (StrCaseCmp(cd->label, stopBits) == 0) {\r
2117       dcb->StopBits = cd->value;\r
2118       break;\r
2119     }\r
2120     cd++;\r
2121   }\r
2122   cd = cdFlow;\r
2123   if (cd->label == NULL) goto cant_parse;\r
2124   while (cd->label != NULL) {\r
2125     if (StrCaseCmp(cd->label, flow) == 0) {\r
2126       switch (cd->value) {\r
2127       case FLOW_NONE:\r
2128         dcb->fOutX = FALSE;\r
2129         dcb->fOutxCtsFlow = FALSE;\r
2130         dcb->fOutxDsrFlow = FALSE;\r
2131         break;\r
2132       case FLOW_CTS:\r
2133         dcb->fOutX = FALSE;\r
2134         dcb->fOutxCtsFlow = TRUE;\r
2135         dcb->fOutxDsrFlow = FALSE;\r
2136         break;\r
2137       case FLOW_DSR:\r
2138         dcb->fOutX = FALSE;\r
2139         dcb->fOutxCtsFlow = FALSE;\r
2140         dcb->fOutxDsrFlow = TRUE;\r
2141         break;\r
2142       case FLOW_XOFF:\r
2143         dcb->fOutX = TRUE;\r
2144         dcb->fOutxCtsFlow = FALSE;\r
2145         dcb->fOutxDsrFlow = FALSE;\r
2146         break;\r
2147       }\r
2148       break;\r
2149     }\r
2150     cd++;\r
2151   }\r
2152   if (cd->label == NULL) goto cant_parse;\r
2153   return;\r
2154 cant_parse:\r
2155     ExitArgError("Can't parse com port settings", arg);\r
2156 }\r
2157 \r
2158 \r
2159 VOID PrintCommSettings(FILE *f, char *name, DCB *dcb)\r
2160 {\r
2161   char *flow = "??", *parity = "??", *stopBits = "??";\r
2162   ComboData *cd;\r
2163   \r
2164   cd = cdParity;\r
2165   while (cd->label != NULL) {\r
2166     if (dcb->Parity == cd->value) {\r
2167       parity = cd->label;\r
2168       break;\r
2169     }\r
2170     cd++;\r
2171   }\r
2172   cd = cdStopBits;\r
2173   while (cd->label != NULL) {\r
2174     if (dcb->StopBits == cd->value) {\r
2175       stopBits = cd->label;\r
2176       break;\r
2177     }\r
2178     cd++;\r
2179   }\r
2180   if (dcb->fOutX) {\r
2181     flow = cdFlow[FLOW_XOFF].label;\r
2182   } else if (dcb->fOutxCtsFlow) {\r
2183     flow = cdFlow[FLOW_CTS].label;\r
2184   } else if (dcb->fOutxDsrFlow) {\r
2185     flow = cdFlow[FLOW_DSR].label;\r
2186   } else {\r
2187     flow = cdFlow[FLOW_NONE].label;\r
2188   }\r
2189   fprintf(f, "/%s=%d,%d,%s,%s,%s\n", name,\r
2190     (int)dcb->BaudRate, dcb->ByteSize, parity, stopBits, flow);\r
2191 }\r
2192 \r
2193 \r
2194 void\r
2195 InitCombo(HANDLE hwndCombo, ComboData *cd)\r
2196 {\r
2197   SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
2198 \r
2199   while (cd->label != NULL) {\r
2200     SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) cd->label);\r
2201     cd++;\r
2202   }\r
2203 }\r
2204 \r
2205 void\r
2206 SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value)\r
2207 {\r
2208   int i;\r
2209 \r
2210   i = 0;\r
2211   while (cd->label != NULL) {\r
2212     if (cd->value == value) {\r
2213       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) i, (LPARAM) 0);\r
2214       return;\r
2215     }\r
2216     cd++;\r
2217     i++;\r
2218   }\r
2219 }\r
2220 \r
2221 LRESULT CALLBACK\r
2222 CommPortOptionsDialog(HWND hDlg, UINT message, WPARAM wParam,   LPARAM lParam)\r
2223 {\r
2224   char buf[MSG_SIZ];\r
2225   HANDLE hwndCombo;\r
2226   char *p;\r
2227   LRESULT index;\r
2228   unsigned value;\r
2229   int err;\r
2230 \r
2231   switch (message) {\r
2232   case WM_INITDIALOG: /* message: initialize dialog box */\r
2233     /* Center the dialog over the application window */\r
2234     CenterWindow (hDlg, GetWindow(hDlg, GW_OWNER));\r
2235     /* Initialize the dialog items */\r
2236     /* !! There should probably be some synchronization\r
2237        in accessing hCommPort and dcb.  Or does modal nature\r
2238        of this dialog box do it for us?\r
2239        */\r
2240     hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
2241     InitCombo(hwndCombo, cdPort);\r
2242     p = strrchr(appData.icsCommPort, '\\');\r
2243     if (p++ == NULL) p = appData.icsCommPort;\r
2244     if ((*p == '\0') ||\r
2245         (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) p) == CB_ERR)) {\r
2246       SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) "None");\r
2247     }\r
2248     EnableWindow(hwndCombo, hCommPort == NULL); /*!! don't allow change for now*/\r
2249 \r
2250     hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
2251     InitCombo(hwndCombo, cdDataRate);\r
2252     sprintf(buf, "%u", (int)dcb.BaudRate);\r
2253     if (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) buf) == CB_ERR) {\r
2254       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
2255       SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);\r
2256     }\r
2257 \r
2258     hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
2259     InitCombo(hwndCombo, cdDataBits);\r
2260     SelectComboValue(hwndCombo, cdDataBits, dcb.ByteSize);\r
2261 \r
2262     hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
2263     InitCombo(hwndCombo, cdParity);\r
2264     SelectComboValue(hwndCombo, cdParity, dcb.Parity);\r
2265 \r
2266     hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
2267     InitCombo(hwndCombo, cdStopBits);\r
2268     SelectComboValue(hwndCombo, cdStopBits, dcb.StopBits);\r
2269 \r
2270     hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
2271     InitCombo(hwndCombo, cdFlow);\r
2272     if (dcb.fOutX) {\r
2273       SelectComboValue(hwndCombo, cdFlow, FLOW_XOFF);\r
2274     } else if (dcb.fOutxCtsFlow) {\r
2275       SelectComboValue(hwndCombo, cdFlow, FLOW_CTS);\r
2276     } else if (dcb.fOutxDsrFlow) {\r
2277       SelectComboValue(hwndCombo, cdFlow, FLOW_DSR);\r
2278     } else {\r
2279       SelectComboValue(hwndCombo, cdFlow, FLOW_NONE);\r
2280     }\r
2281     return TRUE;\r
2282 \r
2283   case WM_COMMAND: /* message: received a command */\r
2284     switch (LOWORD(wParam)) {\r
2285     case IDOK:\r
2286       /* Read changed options from the dialog box */\r
2287 #ifdef NOTDEF\r
2288       /* !! Currently we can't change comm ports in midstream */\r
2289       hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
2290       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2291       if (index == PORT_NONE) {\r
2292         appData.icsCommPort = "";\r
2293         if (hCommPort != NULL) {\r
2294           CloseHandle(hCommPort);\r
2295           hCommPort = NULL;\r
2296         }\r
2297         EndDialog(hDlg, TRUE);\r
2298         return TRUE;\r
2299       }\r
2300       SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
2301       appData.icsCommPort = strdup(buf);\r
2302       if (hCommPort != NULL) {\r
2303         CloseHandle(hCommPort);\r
2304         hCommPort = NULL;\r
2305       }\r
2306       /* now what?? can't really do this; have to fix up the ChildProc\r
2307          and InputSource records for the comm port that we gave to the\r
2308          back end. */\r
2309 #endif /*NOTDEF*/\r
2310 \r
2311       hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
2312       SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
2313       if (sscanf(buf, "%u", &value) != 1) {\r
2314         MessageBox(hDlg, "Invalid data rate",\r
2315                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2316         return TRUE;\r
2317       }\r
2318       dcb.BaudRate = value;\r
2319 \r
2320       hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
2321       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2322       dcb.ByteSize = cdDataBits[index].value;\r
2323 \r
2324       hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
2325       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2326       dcb.Parity = cdParity[index].value;\r
2327 \r
2328       hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
2329       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2330       dcb.StopBits = cdStopBits[index].value;\r
2331 \r
2332       hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
2333       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2334       switch (cdFlow[index].value) {\r
2335       case FLOW_NONE:\r
2336         dcb.fOutX = FALSE;\r
2337         dcb.fOutxCtsFlow = FALSE;\r
2338         dcb.fOutxDsrFlow = FALSE;\r
2339         break;\r
2340       case FLOW_CTS:\r
2341         dcb.fOutX = FALSE;\r
2342         dcb.fOutxCtsFlow = TRUE;\r
2343         dcb.fOutxDsrFlow = FALSE;\r
2344         break;\r
2345       case FLOW_DSR:\r
2346         dcb.fOutX = FALSE;\r
2347         dcb.fOutxCtsFlow = FALSE;\r
2348         dcb.fOutxDsrFlow = TRUE;\r
2349         break;\r
2350       case FLOW_XOFF:\r
2351         dcb.fOutX = TRUE;\r
2352         dcb.fOutxCtsFlow = FALSE;\r
2353         dcb.fOutxDsrFlow = FALSE;\r
2354         break;\r
2355       }\r
2356       if (!SetCommState(hCommPort, (LPDCB) &dcb)) {\r
2357         err = GetLastError();\r
2358         switch(MessageBox(hDlg, \r
2359                          "Failed to set comm port state;\r\ninvalid options?",\r
2360                          "Option Error", MB_ABORTRETRYIGNORE|MB_ICONQUESTION)) {\r
2361         case IDABORT:\r
2362           DisplayFatalError("Failed to set comm port state", err, 1);\r
2363           exit(1);  /*is it ok to do this from here?*/\r
2364 \r
2365         case IDRETRY:\r
2366           return TRUE;\r
2367 \r
2368         case IDIGNORE:\r
2369           EndDialog(hDlg, TRUE);\r
2370           return TRUE;\r
2371         }\r
2372       }\r
2373 \r
2374       EndDialog(hDlg, TRUE);\r
2375       return TRUE;\r
2376 \r
2377     case IDCANCEL:\r
2378       EndDialog(hDlg, FALSE);\r
2379       return TRUE;\r
2380 \r
2381     default:\r
2382       break;\r
2383     }\r
2384     break;\r
2385   }\r
2386   return FALSE;\r
2387 }\r
2388 \r
2389 VOID\r
2390 CommPortOptionsPopup(HWND hwnd)\r
2391 {\r
2392   FARPROC lpProc = MakeProcInstance((FARPROC)CommPortOptionsDialog, hInst);\r
2393   DialogBox(hInst, MAKEINTRESOURCE(DLG_CommPort), hwnd, (DLGPROC) lpProc);\r
2394   FreeProcInstance(lpProc);\r
2395 }\r
2396 \r
2397 /*---------------------------------------------------------------------------*\\r
2398  *\r
2399  * Load Options dialog functions\r
2400  *\r
2401 \*---------------------------------------------------------------------------*/\r
2402 \r
2403 VOID\r
2404 SetLoadOptionEnables(HWND hDlg)\r
2405 {\r
2406   UINT state;\r
2407 \r
2408   state = IsDlgButtonChecked(hDlg, OPT_Autostep);\r
2409   EnableWindow(GetDlgItem(hDlg, OPT_ASTimeDelay), state);\r
2410   EnableWindow(GetDlgItem(hDlg, OPT_AStext1), state);\r
2411 }\r
2412 \r
2413 LRESULT CALLBACK\r
2414 LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2415 {\r
2416   char buf[MSG_SIZ];\r
2417   float fnumber;\r
2418 \r
2419   switch (message) {\r
2420   case WM_INITDIALOG: /* message: initialize dialog box */\r
2421     /* Center the dialog over the application window */\r
2422     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2423     /* Initialize the dialog items */\r
2424     if (appData.timeDelay >= 0.0) {\r
2425       CheckDlgButton(hDlg, OPT_Autostep, TRUE);\r
2426       sprintf(buf, "%.2g", appData.timeDelay);\r
2427       SetDlgItemText(hDlg, OPT_ASTimeDelay, buf);\r
2428     } else {\r
2429       CheckDlgButton(hDlg, OPT_Autostep, FALSE);\r
2430     }\r
2431     SetLoadOptionEnables(hDlg);\r
2432     return TRUE;\r
2433 \r
2434   case WM_COMMAND: /* message: received a command */\r
2435     switch (LOWORD(wParam)) {\r
2436     case IDOK:\r
2437       /* Read changed options from the dialog box */\r
2438       if (IsDlgButtonChecked(hDlg, OPT_Autostep)) {\r
2439         GetDlgItemText(hDlg, OPT_ASTimeDelay, buf, MSG_SIZ);\r
2440         if (sscanf(buf, "%f", &fnumber) != 1) {\r
2441           MessageBox(hDlg, "Invalid load game step rate",\r
2442                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2443           return FALSE;\r
2444         }\r
2445         appData.timeDelay = fnumber;\r
2446       } else {\r
2447         appData.timeDelay = (float) -1.0;\r
2448       }\r
2449       EndDialog(hDlg, TRUE);\r
2450       return TRUE;\r
2451 \r
2452     case IDCANCEL:\r
2453       EndDialog(hDlg, FALSE);\r
2454       return TRUE;\r
2455 \r
2456     default:\r
2457       SetLoadOptionEnables(hDlg);\r
2458       break;\r
2459     }\r
2460     break;\r
2461   }\r
2462   return FALSE;\r
2463 }\r
2464 \r
2465 \r
2466 VOID \r
2467 LoadOptionsPopup(HWND hwnd)\r
2468 {\r
2469   FARPROC lpProc = MakeProcInstance((FARPROC)LoadOptions, hInst);\r
2470   DialogBox(hInst, MAKEINTRESOURCE(DLG_LoadOptions), hwnd, (DLGPROC) lpProc);\r
2471   FreeProcInstance(lpProc);\r
2472 }\r
2473 \r
2474 /*---------------------------------------------------------------------------*\\r
2475  *\r
2476  * Save Options dialog functions\r
2477  *\r
2478 \*---------------------------------------------------------------------------*/\r
2479 \r
2480 VOID\r
2481 SetSaveOptionEnables(HWND hDlg)\r
2482 {\r
2483   UINT state;\r
2484 \r
2485   state = IsDlgButtonChecked(hDlg, OPT_Autosave);\r
2486   EnableWindow(GetDlgItem(hDlg, OPT_AVPrompt), state);\r
2487   EnableWindow(GetDlgItem(hDlg, OPT_AVToFile), state);\r
2488   if (state && !IsDlgButtonChecked(hDlg, OPT_AVPrompt) &&\r
2489       !IsDlgButtonChecked(hDlg, OPT_AVToFile)) {\r
2490     CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
2491   }\r
2492 \r
2493   state = state && IsDlgButtonChecked(hDlg, OPT_AVToFile);\r
2494   EnableWindow(GetDlgItem(hDlg, OPT_AVFilename), state);\r
2495   EnableWindow(GetDlgItem(hDlg, OPT_AVBrowse), state);\r
2496 }\r
2497 \r
2498 LRESULT CALLBACK\r
2499 SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2500 {\r
2501   char buf[MSG_SIZ];\r
2502   FILE *f;\r
2503 \r
2504   switch (message) {\r
2505   case WM_INITDIALOG: /* message: initialize dialog box */\r
2506     /* Center the dialog over the application window */\r
2507     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2508     /* Initialize the dialog items */\r
2509     if (*appData.saveGameFile != NULLCHAR) {\r
2510       CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
2511       CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVToFile);\r
2512       SetDlgItemText(hDlg, OPT_AVFilename, appData.saveGameFile);\r
2513     } else if (appData.autoSaveGames) {\r
2514       CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
2515       CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
2516     } else {\r
2517       CheckDlgButton(hDlg, OPT_Autosave, (UINT) FALSE);\r
2518     }\r
2519     if (appData.oldSaveStyle) {\r
2520       CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_Old);\r
2521     } else {\r
2522       CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_PGN);\r
2523     }\r
2524     CheckDlgButton( hDlg, OPT_OutOfBookInfo, appData.saveOutOfBookInfo );\r
2525     SetSaveOptionEnables(hDlg);\r
2526     return TRUE;\r
2527 \r
2528   case WM_COMMAND: /* message: received a command */\r
2529     switch (LOWORD(wParam)) {\r
2530     case IDOK:\r
2531       /* Read changed options from the dialog box */\r
2532       if (IsDlgButtonChecked(hDlg, OPT_Autosave)) {\r
2533         appData.autoSaveGames = TRUE;\r
2534         if (IsDlgButtonChecked(hDlg, OPT_AVPrompt)) {\r
2535           appData.saveGameFile = "";\r
2536         } else /*if (IsDlgButtonChecked(hDlg, OPT_AVToFile))*/ {\r
2537           GetDlgItemText(hDlg, OPT_AVFilename, buf, MSG_SIZ);\r
2538           if (*buf == NULLCHAR) {\r
2539             MessageBox(hDlg, "Invalid save game file name",\r
2540                        "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2541             return FALSE;\r
2542           }\r
2543           if ((isalpha(buf[0]) && buf[1] == ':') ||\r
2544             (buf[0] == '\\' && buf[1] == '\\')) {\r
2545             appData.saveGameFile = strdup(buf);\r
2546           } else {\r
2547             char buf2[MSG_SIZ], buf3[MSG_SIZ];\r
2548             char *dummy;\r
2549             GetCurrentDirectory(MSG_SIZ, buf3);\r
2550             SetCurrentDirectory(installDir);\r
2551             if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
2552               appData.saveGameFile = strdup(buf2);\r
2553             } else {\r
2554               appData.saveGameFile = strdup(buf);\r
2555             }\r
2556             SetCurrentDirectory(buf3);\r
2557           }\r
2558         }\r
2559       } else {\r
2560         appData.autoSaveGames = FALSE;\r
2561         appData.saveGameFile = "";\r
2562       }\r
2563       appData.oldSaveStyle = IsDlgButtonChecked(hDlg, OPT_Old);\r
2564       appData.saveOutOfBookInfo = IsDlgButtonChecked( hDlg, OPT_OutOfBookInfo );\r
2565       EndDialog(hDlg, TRUE);\r
2566       return TRUE;\r
2567 \r
2568     case IDCANCEL:\r
2569       EndDialog(hDlg, FALSE);\r
2570       return TRUE;\r
2571 \r
2572     case OPT_AVBrowse:\r
2573       f = OpenFileDialog(hDlg, "a", NULL, \r
2574                          appData.oldSaveStyle ? "gam" : "pgn", \r
2575                          GAME_FILT, "Browse for Auto Save File", \r
2576                          NULL, NULL, buf);\r
2577       if (f != NULL) {\r
2578         fclose(f);\r
2579         SetDlgItemText(hDlg, OPT_AVFilename, buf);\r
2580       }\r
2581       break;\r
2582 \r
2583     default:\r
2584       SetSaveOptionEnables(hDlg);\r
2585       break;\r
2586     }\r
2587     break;\r
2588   }\r
2589   return FALSE;\r
2590 }\r
2591 \r
2592 VOID\r
2593 SaveOptionsPopup(HWND hwnd)\r
2594 {\r
2595   FARPROC lpProc = MakeProcInstance((FARPROC)SaveOptionsDialog, hInst);\r
2596   DialogBox(hInst, MAKEINTRESOURCE(DLG_SaveOptions), hwnd, (DLGPROC) lpProc);\r
2597   FreeProcInstance(lpProc);\r
2598 }\r
2599 \r
2600 /*---------------------------------------------------------------------------*\\r
2601  *\r
2602  * Time Control Options dialog functions\r
2603  *\r
2604 \*---------------------------------------------------------------------------*/\r
2605 \r
2606 VOID\r
2607 SetTimeControlEnables(HWND hDlg)\r
2608 {\r
2609   UINT state;\r
2610 \r
2611   state = IsDlgButtonChecked(hDlg, OPT_TCUseMoves)\r
2612         + 2*IsDlgButtonChecked(hDlg, OPT_TCUseFixed);\r
2613   EnableWindow(GetDlgItem(hDlg, OPT_TCTime), state == 1);\r
2614   EnableWindow(GetDlgItem(hDlg, OPT_TCMoves), state == 1);\r
2615   EnableWindow(GetDlgItem(hDlg, OPT_TCtext1), state == 1);\r
2616   EnableWindow(GetDlgItem(hDlg, OPT_TCtext2), state == 1);\r
2617   EnableWindow(GetDlgItem(hDlg, OPT_TCTime2), !state);\r
2618   EnableWindow(GetDlgItem(hDlg, OPT_TCInc), !state);\r
2619   EnableWindow(GetDlgItem(hDlg, OPT_TCitext1), !state);\r
2620   EnableWindow(GetDlgItem(hDlg, OPT_TCitext2), !state);\r
2621   EnableWindow(GetDlgItem(hDlg, OPT_TCitext3), !state);\r
2622   EnableWindow(GetDlgItem(hDlg, OPT_TCFixed), state == 2);\r
2623   EnableWindow(GetDlgItem(hDlg, OPT_TCftext), state == 2);\r
2624 }\r
2625 \r
2626 \r
2627 LRESULT CALLBACK\r
2628 TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2629 {\r
2630   char buf[MSG_SIZ], *tc;\r
2631   int mps, increment, odds1, odds2, st;\r
2632   BOOL ok, ok2;\r
2633 \r
2634   switch (message) {\r
2635   case WM_INITDIALOG: /* message: initialize dialog box */\r
2636     /* Center the dialog over the application window */\r
2637     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2638     /* Initialize the dialog items */\r
2639     if (appData.clockMode && !appData.icsActive) {\r
2640       if (searchTime) {\r
2641         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2642                          OPT_TCUseFixed);\r
2643         SetDlgItemInt(hDlg, OPT_TCFixed, searchTime, FALSE);\r
2644       } else\r
2645       if (appData.timeIncrement == -1) {\r
2646         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2647                          OPT_TCUseMoves);\r
2648         SetDlgItemText(hDlg, OPT_TCTime, appData.timeControl);\r
2649         SetDlgItemInt(hDlg, OPT_TCMoves, appData.movesPerSession,\r
2650                       FALSE);\r
2651         SetDlgItemText(hDlg, OPT_TCTime2, "");\r
2652         SetDlgItemText(hDlg, OPT_TCInc, "");\r
2653       } else {\r
2654         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2655                          OPT_TCUseInc);\r
2656         SetDlgItemText(hDlg, OPT_TCTime, "");\r
2657         SetDlgItemText(hDlg, OPT_TCMoves, "");\r
2658         SetDlgItemText(hDlg, OPT_TCTime2, appData.timeControl);\r
2659         SetDlgItemInt(hDlg, OPT_TCInc, appData.timeIncrement, FALSE);\r
2660       }\r
2661       SetDlgItemInt(hDlg, OPT_TCOdds1, 1, FALSE);\r
2662       SetDlgItemInt(hDlg, OPT_TCOdds2, 1, FALSE);\r
2663       SetTimeControlEnables(hDlg);\r
2664     }\r
2665     return TRUE;\r
2666 \r
2667   case WM_COMMAND: /* message: received a command */\r
2668     switch (LOWORD(wParam)) {\r
2669     case IDOK:\r
2670       mps = appData.movesPerSession;\r
2671       increment = appData.timeIncrement;\r
2672       tc = appData.timeControl;\r
2673       st = 0;\r
2674       /* Read changed options from the dialog box */\r
2675       if (IsDlgButtonChecked(hDlg, OPT_TCUseFixed)) {\r
2676         st = GetDlgItemInt(hDlg, OPT_TCFixed, &ok, FALSE);\r
2677         if (!ok || st <= 0) {\r
2678           MessageBox(hDlg, "Invalid max time per move",\r
2679                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2680           return FALSE;\r
2681         }\r
2682       } else\r
2683       if (IsDlgButtonChecked(hDlg, OPT_TCUseMoves)) {\r
2684         increment = -1;\r
2685         mps = GetDlgItemInt(hDlg, OPT_TCMoves, &ok, FALSE);\r
2686         if (!ok || mps <= 0) {\r
2687           MessageBox(hDlg, "Invalid moves per time control",\r
2688                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2689           return FALSE;\r
2690         }\r
2691         GetDlgItemText(hDlg, OPT_TCTime, buf, MSG_SIZ);\r
2692         if (!ParseTimeControl(buf, increment, mps)) {\r
2693           MessageBox(hDlg, "Invalid minutes per time control",\r
2694                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2695           return FALSE;\r
2696         }\r
2697       tc = buf;\r
2698       } else {\r
2699         increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE);\r
2700         if (!ok || increment < 0) {\r
2701           MessageBox(hDlg, "Invalid increment",\r
2702                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2703           return FALSE;\r
2704         }\r
2705         GetDlgItemText(hDlg, OPT_TCTime2, buf, MSG_SIZ);\r
2706         if (!ParseTimeControl(buf, increment, mps)) {\r
2707           MessageBox(hDlg, "Invalid initial time",\r
2708                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2709           return FALSE;\r
2710         }\r
2711       tc = buf;\r
2712       }\r
2713       odds1 = GetDlgItemInt(hDlg, OPT_TCOdds1, &ok, FALSE);\r
2714       odds2 = GetDlgItemInt(hDlg, OPT_TCOdds2, &ok2, FALSE);\r
2715       if (!ok || !ok2 || odds1 <= 0 || odds2 <= 0) {\r
2716           MessageBox(hDlg, "Invalid time-odds factor",\r
2717                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2718           return FALSE;\r
2719       }\r
2720       searchTime = st;\r
2721       appData.timeControl = strdup(tc);\r
2722       appData.movesPerSession = mps;\r
2723       appData.timeIncrement = increment;\r
2724       appData.firstTimeOdds  = first.timeOdds  = odds1;\r
2725       appData.secondTimeOdds = second.timeOdds = odds2;\r
2726       Reset(TRUE, TRUE);\r
2727       EndDialog(hDlg, TRUE);\r
2728       return TRUE;\r
2729 \r
2730     case IDCANCEL:\r
2731       EndDialog(hDlg, FALSE);\r
2732       return TRUE;\r
2733 \r
2734     default:\r
2735       SetTimeControlEnables(hDlg);\r
2736       break;\r
2737     }\r
2738     break;\r
2739   }\r
2740   return FALSE;\r
2741 }\r
2742 \r
2743 VOID\r
2744 TimeControlOptionsPopup(HWND hwnd)\r
2745 {\r
2746   if (gameMode != BeginningOfGame) {\r
2747     DisplayError("Changing time control during a game is not implemented", 0);\r
2748   } else {\r
2749     FARPROC lpProc = MakeProcInstance((FARPROC)TimeControl, hInst);\r
2750     DialogBox(hInst, MAKEINTRESOURCE(DLG_TimeControl), hwnd, (DLGPROC) lpProc);\r
2751     FreeProcInstance(lpProc);\r
2752   }\r
2753 }\r
2754 \r
2755 /*---------------------------------------------------------------------------*\\r
2756  *\r
2757  * Engine Options Dialog functions\r
2758  *\r
2759 \*---------------------------------------------------------------------------*/\r
2760 #define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
2761 #define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
2762 \r
2763 #define INT_ABS( n )    ((n) >= 0 ? (n) : -(n))\r
2764 \r
2765 LRESULT CALLBACK EnginePlayOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2766 {\r
2767   switch (message) {\r
2768   case WM_INITDIALOG: /* message: initialize dialog box */\r
2769 \r
2770     /* Center the dialog over the application window */\r
2771     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2772 \r
2773     /* Initialize the dialog items */\r
2774     CHECK_BOX(IDC_EpPeriodicUpdates, appData.periodicUpdates);\r
2775     CHECK_BOX(IDC_EpPonder, appData.ponderNextMove);\r
2776     CHECK_BOX(IDC_EpShowThinking, appData.showThinking);\r
2777     CHECK_BOX(IDC_EpHideThinkingHuman, appData.hideThinkingFromHuman);\r
2778 \r
2779     CHECK_BOX(IDC_TestClaims, appData.testClaims);\r
2780     CHECK_BOX(IDC_DetectMates, appData.checkMates);\r
2781     CHECK_BOX(IDC_MaterialDraws, appData.materialDraws);\r
2782     CHECK_BOX(IDC_TrivialDraws, appData.trivialDraws);\r
2783 \r
2784     CHECK_BOX(IDC_ScoreAbs1, appData.firstScoreIsAbsolute);\r
2785     CHECK_BOX(IDC_ScoreAbs2, appData.secondScoreIsAbsolute);\r
2786 \r
2787     SetDlgItemInt( hDlg, IDC_EpDrawMoveCount, appData.adjudicateDrawMoves, TRUE );\r
2788     SendDlgItemMessage( hDlg, IDC_EpDrawMoveCount, EM_SETSEL, 0, -1 );\r
2789 \r
2790     SetDlgItemInt( hDlg, IDC_EpAdjudicationThreshold, INT_ABS(appData.adjudicateLossThreshold), TRUE );\r
2791     SendDlgItemMessage( hDlg, IDC_EpAdjudicationThreshold, EM_SETSEL, 0, -1 );\r
2792 \r
2793     SetDlgItemInt( hDlg, IDC_RuleMoves, appData.ruleMoves, TRUE );\r
2794     SendDlgItemMessage( hDlg, IDC_RuleMoves, EM_SETSEL, 0, -1 );\r
2795 \r
2796     SetDlgItemInt( hDlg, IDC_DrawRepeats, INT_ABS(appData.drawRepeats), TRUE );\r
2797     SendDlgItemMessage( hDlg, IDC_DrawRepeats, EM_SETSEL, 0, -1 );\r
2798 \r
2799     return TRUE;\r
2800 \r
2801   case WM_COMMAND: /* message: received a command */\r
2802     switch (LOWORD(wParam)) {\r
2803     case IDOK:\r
2804       /* Read changed options from the dialog box */\r
2805       PeriodicUpdatesEvent(          IS_CHECKED(IDC_EpPeriodicUpdates));\r
2806       PonderNextMoveEvent(           IS_CHECKED(IDC_EpPonder));\r
2807       appData.hideThinkingFromHuman= IS_CHECKED(IDC_EpHideThinkingHuman); // [HGM] thinking: moved up\r
2808       appData.showThinking   = IS_CHECKED(IDC_EpShowThinking);\r
2809       ShowThinkingEvent(); // [HGM] thinking: tests all options that need thinking output\r
2810       appData.testClaims    = IS_CHECKED(IDC_TestClaims);\r
2811       appData.checkMates    = IS_CHECKED(IDC_DetectMates);\r
2812       appData.materialDraws = IS_CHECKED(IDC_MaterialDraws);\r
2813       appData.trivialDraws  = IS_CHECKED(IDC_TrivialDraws);\r
2814 \r
2815       appData.adjudicateDrawMoves = GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, NULL, FALSE );\r
2816       appData.adjudicateLossThreshold = - (int) GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, NULL, FALSE );\r
2817       appData.ruleMoves = GetDlgItemInt(hDlg, IDC_RuleMoves, NULL, FALSE );\r
2818       appData.drawRepeats = (int) GetDlgItemInt(hDlg, IDC_DrawRepeats, NULL, FALSE );\r
2819 \r
2820       first.scoreIsAbsolute  = appData.firstScoreIsAbsolute  = IS_CHECKED(IDC_ScoreAbs1);\r
2821       second.scoreIsAbsolute = appData.secondScoreIsAbsolute = IS_CHECKED(IDC_ScoreAbs2);\r
2822 \r
2823       EndDialog(hDlg, TRUE);\r
2824       return TRUE;\r
2825 \r
2826     case IDCANCEL:\r
2827       EndDialog(hDlg, FALSE);\r
2828       return TRUE;\r
2829 \r
2830     case IDC_EpDrawMoveCount:\r
2831     case IDC_EpAdjudicationThreshold:\r
2832     case IDC_DrawRepeats:\r
2833     case IDC_RuleMoves:\r
2834         if( HIWORD(wParam) == EN_CHANGE ) {\r
2835             int n1_ok;\r
2836             int n2_ok;\r
2837             int n3_ok;\r
2838             int n4_ok;\r
2839 \r
2840             GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, &n1_ok, FALSE );\r
2841             GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, &n2_ok, FALSE );\r
2842             GetDlgItemInt(hDlg, IDC_RuleMoves, &n3_ok, FALSE );\r
2843             GetDlgItemInt(hDlg, IDC_DrawRepeats, &n4_ok, FALSE );\r
2844 \r
2845             EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok && n4_ok ? TRUE : FALSE );\r
2846         }\r
2847         return TRUE;\r
2848     }\r
2849     break;\r
2850   }\r
2851   return FALSE;\r
2852 }\r
2853 \r
2854 VOID EnginePlayOptionsPopup(HWND hwnd)\r
2855 {\r
2856   FARPROC lpProc;\r
2857 \r
2858   lpProc = MakeProcInstance((FARPROC)EnginePlayOptionsDialog, hInst);\r
2859   DialogBox(hInst, MAKEINTRESOURCE(DLG_EnginePlayOptions), hwnd, (DLGPROC) lpProc);\r
2860   FreeProcInstance(lpProc);\r
2861 }\r
2862 \r
2863 /*---------------------------------------------------------------------------*\\r
2864  *\r
2865  * UCI Options Dialog functions\r
2866  *\r
2867 \*---------------------------------------------------------------------------*/\r
2868 static BOOL BrowseForFolder( const char * title, char * path )\r
2869 {\r
2870     BOOL result = FALSE;\r
2871     BROWSEINFO bi;\r
2872     LPITEMIDLIST pidl;\r
2873 \r
2874     ZeroMemory( &bi, sizeof(bi) );\r
2875 \r
2876     bi.lpszTitle = title == 0 ? "Choose Folder" : title;\r
2877     bi.ulFlags = BIF_RETURNONLYFSDIRS;\r
2878 \r
2879     pidl = SHBrowseForFolder( &bi );\r
2880 \r
2881     if( pidl != 0 ) {\r
2882         IMalloc * imalloc = 0;\r
2883 \r
2884         if( SHGetPathFromIDList( pidl, path ) ) {\r
2885             result = TRUE;\r
2886         }\r
2887 \r
2888         if( SUCCEEDED( SHGetMalloc ( &imalloc ) ) ) {\r
2889             imalloc->lpVtbl->Free(imalloc,pidl);\r
2890             imalloc->lpVtbl->Release(imalloc);\r
2891         }\r
2892     }\r
2893 \r
2894     return result;\r
2895 }\r
2896 \r
2897 LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2898 {\r
2899   char buf[MAX_PATH];\r
2900   int oldCores;\r
2901 \r
2902   switch (message) {\r
2903   case WM_INITDIALOG: /* message: initialize dialog box */\r
2904 \r
2905     /* Center the dialog over the application window */\r
2906     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2907 \r
2908     /* Initialize the dialog items */\r
2909     SetDlgItemText( hDlg, IDC_PolyglotDir, appData.polyglotDir );\r
2910     SetDlgItemInt( hDlg, IDC_HashSize, appData.defaultHashSize, TRUE );\r
2911     SetDlgItemText( hDlg, IDC_PathToEGTB, appData.defaultPathEGTB );\r
2912     SetDlgItemInt( hDlg, IDC_SizeOfEGTB, appData.defaultCacheSizeEGTB, TRUE );\r
2913     CheckDlgButton( hDlg, IDC_UseBook, (BOOL) appData.usePolyglotBook );\r
2914     SetDlgItemText( hDlg, IDC_BookFile, appData.polyglotBook );\r
2915     // [HGM] smp: input field for nr of cores:\r
2916     SetDlgItemInt( hDlg, IDC_Cores, appData.smpCores, TRUE );\r
2917     // [HGM] book: tick boxes for own book use\r
2918     CheckDlgButton( hDlg, IDC_OwnBook1, (BOOL) appData.firstHasOwnBookUCI );\r
2919     CheckDlgButton( hDlg, IDC_OwnBook2, (BOOL) appData.secondHasOwnBookUCI );\r
2920 \r
2921     SendDlgItemMessage( hDlg, IDC_PolyglotDir, EM_SETSEL, 0, -1 );\r
2922 \r
2923     return TRUE;\r
2924 \r
2925   case WM_COMMAND: /* message: received a command */\r
2926     switch (LOWORD(wParam)) {\r
2927     case IDOK:\r
2928       GetDlgItemText( hDlg, IDC_PolyglotDir, buf, sizeof(buf) );\r
2929       appData.polyglotDir = strdup(buf);\r
2930       appData.defaultHashSize = GetDlgItemInt(hDlg, IDC_HashSize, NULL, FALSE );\r
2931       appData.defaultCacheSizeEGTB = GetDlgItemInt(hDlg, IDC_SizeOfEGTB, NULL, FALSE );\r
2932       GetDlgItemText( hDlg, IDC_PathToEGTB, buf, sizeof(buf) );\r
2933       appData.defaultPathEGTB = strdup(buf);\r
2934       GetDlgItemText( hDlg, IDC_BookFile, buf, sizeof(buf) );\r
2935       appData.polyglotBook = strdup(buf);\r
2936       appData.usePolyglotBook = (Boolean) IsDlgButtonChecked( hDlg, IDC_UseBook );\r
2937       // [HGM] smp: get nr of cores:\r
2938       oldCores = appData.smpCores;\r
2939       appData.smpCores = GetDlgItemInt(hDlg, IDC_Cores, NULL, FALSE );\r
2940       if(appData.smpCores != oldCores) NewSettingEvent(FALSE, "cores", appData.smpCores);\r
2941       // [HGM] book: read tick boxes for own book use\r
2942       appData.firstHasOwnBookUCI  = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook1 );\r
2943       appData.secondHasOwnBookUCI = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook2 );\r
2944 \r
2945       if(gameMode == BeginningOfGame) Reset(TRUE, TRUE);\r
2946       EndDialog(hDlg, TRUE);\r
2947       return TRUE;\r
2948 \r
2949     case IDCANCEL:\r
2950       EndDialog(hDlg, FALSE);\r
2951       return TRUE;\r
2952 \r
2953     case IDC_BrowseForBook:\r
2954       {\r
2955           char filter[] = { \r
2956               'A','l','l',' ','F','i','l','e','s', 0,\r
2957               '*','.','*', 0,\r
2958               'B','I','N',' ','F','i','l','e','s', 0,\r
2959               '*','.','b','i','n', 0,\r
2960               0 };\r
2961 \r
2962           OPENFILENAME ofn;\r
2963 \r
2964           strcpy( buf, "" );\r
2965 \r
2966           ZeroMemory( &ofn, sizeof(ofn) );\r
2967 \r
2968           ofn.lStructSize = sizeof(ofn);\r
2969           ofn.hwndOwner = hDlg;\r
2970           ofn.hInstance = hInst;\r
2971           ofn.lpstrFilter = filter;\r
2972           ofn.lpstrFile = buf;\r
2973           ofn.nMaxFile = sizeof(buf);\r
2974           ofn.lpstrTitle = "Choose Book";\r
2975           ofn.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_HIDEREADONLY;\r
2976 \r
2977           if( GetOpenFileName( &ofn ) ) {\r
2978               SetDlgItemText( hDlg, IDC_BookFile, buf );\r
2979           }\r
2980       }\r
2981       return TRUE;\r
2982 \r
2983     case IDC_BrowseForPolyglotDir:\r
2984       if( BrowseForFolder( "Choose Polyglot Directory", buf ) ) {\r
2985         SetDlgItemText( hDlg, IDC_PolyglotDir, buf );\r
2986 \r
2987         strcat( buf, "\\polyglot.exe" );\r
2988 \r
2989         if( GetFileAttributes(buf) == 0xFFFFFFFF ) {\r
2990             MessageBox( hDlg, "Polyglot was not found in the specified folder!", "Warning", MB_OK | MB_ICONWARNING );\r
2991         }\r
2992       }\r
2993       return TRUE;\r
2994 \r
2995     case IDC_BrowseForEGTB:\r
2996       if( BrowseForFolder( "Choose EGTB Directory:", buf ) ) {\r
2997         SetDlgItemText( hDlg, IDC_PathToEGTB, buf );\r
2998       }\r
2999       return TRUE;\r
3000 \r
3001     case IDC_HashSize:\r
3002     case IDC_SizeOfEGTB:\r
3003         if( HIWORD(wParam) == EN_CHANGE ) {\r
3004             int n1_ok;\r
3005             int n2_ok;\r
3006 \r
3007             GetDlgItemInt(hDlg, IDC_HashSize, &n1_ok, FALSE );\r
3008             GetDlgItemInt(hDlg, IDC_SizeOfEGTB, &n2_ok, FALSE );\r
3009 \r
3010             EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok ? TRUE : FALSE );\r
3011         }\r
3012         return TRUE;\r
3013     }\r
3014     break;\r
3015   }\r
3016   return FALSE;\r
3017 }\r
3018 \r
3019 VOID UciOptionsPopup(HWND hwnd)\r
3020 {\r
3021   FARPROC lpProc;\r
3022 \r
3023   lpProc = MakeProcInstance((FARPROC)UciOptionsDialog, hInst);\r
3024   DialogBox(hInst, MAKEINTRESOURCE(DLG_OptionsUCI), hwnd, (DLGPROC) lpProc);\r
3025   FreeProcInstance(lpProc);\r
3026 }\r