Fix typos in html help file
[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_AutoKibitz, appData.autoKibitz);\r
1181     CHECK_BOX(OPT_AutoComment, appData.autoComment);\r
1182     CHECK_BOX(OPT_AutoObserve, appData.autoObserve);\r
1183     CHECK_BOX(OPT_GetMoveList, appData.getMoveList);\r
1184     CHECK_BOX(OPT_LocalLineEditing, appData.localLineEditing);\r
1185     CHECK_BOX(OPT_QuietPlay, appData.quietPlay);\r
1186     CHECK_BOX(OPT_SeekGraph, appData.seekGraph);\r
1187     CHECK_BOX(OPT_AutoRefresh, appData.autoRefresh);\r
1188     CHECK_BOX(OPT_BgObserve, appData.bgObserve);\r
1189     CHECK_BOX(OPT_DualBoard, appData.dualBoard);\r
1190     CHECK_BOX(OPT_SmartMove, appData.oneClick);\r
1191     CHECK_BOX(OPT_Premove, appData.premove);\r
1192     CHECK_BOX(OPT_PremoveWhite, appData.premoveWhite);\r
1193     CHECK_BOX(OPT_PremoveBlack, appData.premoveBlack);\r
1194     CHECK_BOX(OPT_IcsAlarm, appData.icsAlarm);\r
1195     CHECK_BOX(OPT_DontColorize, !appData.colorize);\r
1196 \r
1197 #undef CHECK_BOX\r
1198 \r
1199     sprintf(buf, "%d", appData.icsAlarmTime / 1000);\r
1200     SetDlgItemText(hDlg, OPT_IcsAlarmTime, buf);\r
1201     SetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText);\r
1202     SetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText);\r
1203     SetDlgItemText(hDlg, OPT_StartupChatBoxes, appData.chatBoxes);\r
1204 \r
1205     SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
1206     SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
1207     SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
1208     SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
1209     SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
1210     SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
1211     SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
1212     SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
1213     SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
1214     SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
1215 \r
1216     SetDlgItemText(hDlg, OPT_SampleShout,     mca[ColorShout].name);\r
1217     SetDlgItemText(hDlg, OPT_SampleSShout,    mca[ColorSShout].name);\r
1218     SetDlgItemText(hDlg, OPT_SampleChannel1,  mca[ColorChannel1].name);\r
1219     SetDlgItemText(hDlg, OPT_SampleChannel,   mca[ColorChannel].name);\r
1220     SetDlgItemText(hDlg, OPT_SampleKibitz,    mca[ColorKibitz].name);\r
1221     SetDlgItemText(hDlg, OPT_SampleTell,      mca[ColorTell].name);\r
1222     SetDlgItemText(hDlg, OPT_SampleChallenge, mca[ColorChallenge].name);\r
1223     SetDlgItemText(hDlg, OPT_SampleRequest,   mca[ColorRequest].name);\r
1224     SetDlgItemText(hDlg, OPT_SampleSeek,      mca[ColorSeek].name);\r
1225     SetDlgItemText(hDlg, OPT_SampleNormal,    mca[ColorNormal].name);\r
1226 \r
1227     UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
1228     UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
1229     UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
1230     UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
1231     UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
1232     UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
1233     UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
1234     UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
1235     UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
1236     UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
1237 \r
1238     SetIcsOptionEnables(hDlg);\r
1239     return TRUE;\r
1240 \r
1241   case WM_COMMAND: /* message: received a command */\r
1242     switch (LOWORD(wParam)) {\r
1243 \r
1244     case WM_USER_GetConsoleBackground: \r
1245       /* the ColorizeTextDialog needs the current background color */\r
1246       colorref = (COLORREF *)lParam;\r
1247       *colorref = cbc;\r
1248       return FALSE;\r
1249 \r
1250     case IDOK:\r
1251       /* Read changed options from the dialog box */\r
1252       GetDlgItemText(hDlg, OPT_IcsAlarmTime, buf, MSG_SIZ);\r
1253       if (sscanf(buf, "%d", &number) != 1 || (number < 0)){\r
1254           MessageBox(hDlg, "Invalid ICS Alarm Time",\r
1255                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
1256           return FALSE;\r
1257       }\r
1258 \r
1259 #define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
1260 \r
1261       appData.icsAlarm         = IS_CHECKED(OPT_IcsAlarm);\r
1262       appData.premove          = IS_CHECKED(OPT_Premove);\r
1263       appData.premoveWhite     = IS_CHECKED(OPT_PremoveWhite);\r
1264       appData.premoveBlack     = IS_CHECKED(OPT_PremoveBlack);\r
1265       appData.autoKibitz       = IS_CHECKED(OPT_AutoKibitz);\r
1266       appData.autoComment      = IS_CHECKED(OPT_AutoComment);\r
1267       appData.autoObserve      = IS_CHECKED(OPT_AutoObserve);\r
1268       appData.getMoveList      = IS_CHECKED(OPT_GetMoveList);\r
1269       appData.localLineEditing = IS_CHECKED(OPT_LocalLineEditing);\r
1270       appData.quietPlay        = IS_CHECKED(OPT_QuietPlay);\r
1271       appData.seekGraph        = IS_CHECKED(OPT_SeekGraph);\r
1272       appData.autoRefresh      = IS_CHECKED(OPT_AutoRefresh);\r
1273       appData.bgObserve        = IS_CHECKED(OPT_BgObserve);\r
1274       appData.dualBoard        = IS_CHECKED(OPT_DualBoard);\r
1275       appData.oneClick         = IS_CHECKED(OPT_SmartMove);\r
1276 \r
1277 #undef IS_CHECKED\r
1278 \r
1279       appData.icsAlarmTime = number * 1000;\r
1280       GetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText, 5);\r
1281       GetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText, 5);\r
1282       GetDlgItemText(hDlg, OPT_StartupChatBoxes, buf, sizeof(buf));\r
1283       buf[sizeof(buf)-1] = NULLCHAR; appData.chatBoxes = StrSave(buf); // memory leak\r
1284 \r
1285       if (appData.localLineEditing) {\r
1286         DontEcho();\r
1287         EchoOn();\r
1288       } else {\r
1289         DoEcho();\r
1290         EchoOff();\r
1291       }\r
1292 \r
1293       appData.colorize =\r
1294         (Boolean)!IsDlgButtonChecked(hDlg, OPT_DontColorize);\r
1295 \r
1296     ChangedConsoleFont();\r
1297 \r
1298     if (!appData.colorize) {\r
1299         CHARFORMAT cf;\r
1300         COLORREF background = ParseColorName(COLOR_BKGD);\r
1301         /*\r
1302         SetDefaultTextAttribs();\r
1303         Colorize(currentColorClass);\r
1304         */\r
1305         cf.cbSize = sizeof(CHARFORMAT);\r
1306         cf.dwMask = CFM_COLOR;\r
1307         cf.crTextColor = ParseColorName(COLOR_NORMAL);\r
1308 \r
1309         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
1310           EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
1311         SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
1312           EM_SETBKGNDCOLOR, FALSE, background);\r
1313         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
1314           EM_SETBKGNDCOLOR, FALSE, background);\r
1315       }\r
1316 \r
1317       if (cbc != consoleBackgroundColor) {\r
1318         consoleBackgroundColor = cbc;\r
1319         if (appData.colorize) {\r
1320           SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
1321             EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
1322           SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
1323             EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
1324         }\r
1325       }\r
1326 \r
1327       for (i=0; i < NColorClasses - 1; i++) {\r
1328         textAttribs[i].color   = mca[i].color;\r
1329         textAttribs[i].effects = mca[i].effects;\r
1330       }\r
1331 \r
1332       EndDialog(hDlg, TRUE);\r
1333       return TRUE;\r
1334 \r
1335     case IDCANCEL:\r
1336       EndDialog(hDlg, FALSE);\r
1337       return TRUE;\r
1338 \r
1339     case OPT_ChooseShoutColor:\r
1340       ColorizeTextPopup(hDlg, ColorShout);\r
1341       UpdateSampleText(hDlg, OPT_SampleShout, &mca[ColorShout]);\r
1342       break;\r
1343 \r
1344     case OPT_ChooseSShoutColor:\r
1345       ColorizeTextPopup(hDlg, ColorSShout);\r
1346       UpdateSampleText(hDlg, OPT_SampleSShout, &mca[ColorSShout]);\r
1347       break;\r
1348 \r
1349     case OPT_ChooseChannel1Color:\r
1350       ColorizeTextPopup(hDlg, ColorChannel1);\r
1351       UpdateSampleText(hDlg, OPT_SampleChannel1, \r
1352                        &colorizeAttribs[ColorChannel1]);\r
1353       break;\r
1354 \r
1355     case OPT_ChooseChannelColor:\r
1356       ColorizeTextPopup(hDlg, ColorChannel);\r
1357       UpdateSampleText(hDlg, OPT_SampleChannel, &mca[ColorChannel]);\r
1358       break;\r
1359 \r
1360     case OPT_ChooseKibitzColor:\r
1361       ColorizeTextPopup(hDlg, ColorKibitz);\r
1362       UpdateSampleText(hDlg, OPT_SampleKibitz, &mca[ColorKibitz]);\r
1363       break;\r
1364 \r
1365     case OPT_ChooseTellColor:\r
1366       ColorizeTextPopup(hDlg, ColorTell);\r
1367       UpdateSampleText(hDlg, OPT_SampleTell, &mca[ColorTell]);\r
1368       break;\r
1369 \r
1370     case OPT_ChooseChallengeColor:\r
1371       ColorizeTextPopup(hDlg, ColorChallenge);\r
1372       UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
1373       break;\r
1374 \r
1375     case OPT_ChooseRequestColor:\r
1376       ColorizeTextPopup(hDlg, ColorRequest);\r
1377       UpdateSampleText(hDlg, OPT_SampleRequest, &mca[ColorRequest]);\r
1378       break;\r
1379 \r
1380     case OPT_ChooseSeekColor:\r
1381       ColorizeTextPopup(hDlg, ColorSeek);\r
1382       UpdateSampleText(hDlg, OPT_SampleSeek, &mca[ColorSeek]);\r
1383       break;\r
1384 \r
1385     case OPT_ChooseNormalColor:\r
1386       ColorizeTextPopup(hDlg, ColorNormal);\r
1387       UpdateSampleText(hDlg, OPT_SampleNormal, &mca[ColorNormal]);\r
1388       break;\r
1389 \r
1390     case OPT_ChooseBackgroundColor:\r
1391       if (ChangeColor(hDlg, &cbc)) {\r
1392         SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
1393         SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
1394         SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
1395         SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
1396         SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
1397         SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
1398         SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
1399         SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
1400         SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
1401         SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
1402       }\r
1403       break;\r
1404 \r
1405     case OPT_DefaultColors:\r
1406       for (i=0; i < NColorClasses - 1; i++)\r
1407         ParseAttribs(&mca[i].color, \r
1408                      &mca[i].effects,\r
1409                      defaultTextAttribs[i]);\r
1410 \r
1411       cbc = ParseColorName(COLOR_BKGD);\r
1412       SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
1413       SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
1414       SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
1415       SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
1416       SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
1417       SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
1418       SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
1419       SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
1420       SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
1421       SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
1422 \r
1423       UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
1424       UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
1425       UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
1426       UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
1427       UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
1428       UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
1429       UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
1430       UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
1431       UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
1432       UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
1433       break;\r
1434 \r
1435     default:\r
1436       SetIcsOptionEnables(hDlg);\r
1437       break;\r
1438     }\r
1439     break;\r
1440   }\r
1441   return FALSE;\r
1442 }\r
1443 \r
1444 VOID\r
1445 IcsOptionsPopup(HWND hwnd)\r
1446 {\r
1447   FARPROC lpProc = MakeProcInstance((FARPROC)IcsOptionsDialog, hInst);\r
1448   DialogBox(hInst, MAKEINTRESOURCE(DLG_IcsOptions), hwnd,\r
1449             (DLGPROC) lpProc);\r
1450   FreeProcInstance(lpProc);\r
1451 }\r
1452 \r
1453 /*---------------------------------------------------------------------------*\\r
1454  *\r
1455  * Fonts Dialog functions\r
1456  *\r
1457 \*---------------------------------------------------------------------------*/\r
1458 \r
1459 VOID\r
1460 SetSampleFontText(HWND hwnd, int id, const MyFont *mf)\r
1461 {\r
1462   char buf[MSG_SIZ];\r
1463   HWND hControl;\r
1464   HDC hdc;\r
1465   CHARFORMAT cf;\r
1466   SIZE size;\r
1467   RECT rectClient, rectFormat;\r
1468   HFONT oldFont;\r
1469   POINT center;\r
1470   int len;\r
1471 \r
1472   len = sprintf(buf, "%.0f pt. %s%s%s\n",\r
1473                 mf->mfp.pointSize, mf->mfp.faceName,\r
1474                 mf->mfp.bold ? " bold" : "",\r
1475                 mf->mfp.italic ? " italic" : "");\r
1476   SetDlgItemText(hwnd, id, buf);\r
1477 \r
1478   hControl = GetDlgItem(hwnd, id);\r
1479   hdc = GetDC(hControl);\r
1480   SetMapMode(hdc, MM_TEXT);     /* 1 pixel == 1 logical unit */\r
1481   oldFont = SelectObject(hdc, mf->hf);\r
1482   \r
1483   /* get number of logical units necessary to display font name */\r
1484   GetTextExtentPoint32(hdc, buf, len, &size);\r
1485 \r
1486   /* calculate formatting rectangle in the rich edit control.  \r
1487    * May be larger or smaller than the actual control.\r
1488    */\r
1489   GetClientRect(hControl, &rectClient);\r
1490   center.x = (rectClient.left + rectClient.right) / 2;\r
1491   center.y = (rectClient.top  + rectClient.bottom) / 2;\r
1492   rectFormat.top    = center.y - (size.cy / 2) - 1;\r
1493   rectFormat.bottom = center.y + (size.cy / 2) + 1;\r
1494   rectFormat.left   = center.x - (size.cx / 2) - 1;\r
1495   rectFormat.right  = center.x + (size.cx / 2) + 1;\r
1496 \r
1497   cf.cbSize = sizeof(CHARFORMAT);\r
1498   cf.dwMask = CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_BOLD|CFM_ITALIC;\r
1499   cf.dwEffects = 0;\r
1500   if (mf->lf.lfWeight == FW_BOLD) cf.dwEffects |= CFE_BOLD;\r
1501   if (mf->lf.lfItalic) cf.dwEffects |= CFE_ITALIC;\r
1502   strcpy(cf.szFaceName, mf->mfp.faceName);\r
1503   /*\r
1504    * yHeight is expressed in twips.  A twip is 1/20 of a font's point\r
1505    * size. See documentation of CHARFORMAT.  --msw\r
1506    */\r
1507   cf.yHeight = (int)(mf->mfp.pointSize * 20.0 + 0.5);\r
1508   cf.bCharSet = mf->lf.lfCharSet;\r
1509   cf.bPitchAndFamily = mf->lf.lfPitchAndFamily;\r
1510 \r
1511   /* format the text in the rich edit control */\r
1512   SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf);\r
1513   SendMessage(hControl, EM_SETRECT, (WPARAM)0, (LPARAM) &rectFormat);\r
1514 \r
1515   /* clean up */\r
1516   SelectObject(hdc, oldFont);\r
1517   ReleaseDC(hControl, hdc);\r
1518 }\r
1519 \r
1520 VOID\r
1521 CopyFont(MyFont *dest, const MyFont *src)\r
1522 {\r
1523   dest->mfp.pointSize = src->mfp.pointSize;\r
1524   dest->mfp.bold      = src->mfp.bold;\r
1525   dest->mfp.italic    = src->mfp.italic;\r
1526   dest->mfp.underline = src->mfp.underline;\r
1527   dest->mfp.strikeout = src->mfp.strikeout;\r
1528   dest->mfp.charset   = src->mfp.charset;\r
1529   lstrcpy(dest->mfp.faceName, src->mfp.faceName);\r
1530   CreateFontInMF(dest);\r
1531 }\r
1532 \r
1533 \r
1534 LRESULT CALLBACK\r
1535 FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1536 {\r
1537   static MyFont workFont[NUM_FONTS];\r
1538   static BOOL firstPaint;\r
1539   int i;\r
1540   RECT rect;\r
1541 \r
1542   switch (message) {\r
1543   case WM_INITDIALOG:\r
1544 \r
1545     /* copy the current font settings into a working copy */\r
1546     for (i=0; i < NUM_FONTS; i++)\r
1547       CopyFont(&workFont[i], font[boardSize][i]);\r
1548 \r
1549     if (!appData.icsActive)\r
1550       EnableWindow(GetDlgItem(hDlg, OPT_ChooseConsoleFont), FALSE);\r
1551 \r
1552     firstPaint = TRUE;  /* see rant below */\r
1553 \r
1554     /* If I don't call SetFocus(), the dialog won't respond to the keyboard\r
1555      * when first drawn. Why is this the only dialog that behaves this way? Is\r
1556      * is the WM_PAINT stuff below?? Sigh...\r
1557      */\r
1558     SetFocus(GetDlgItem(hDlg, IDOK));\r
1559     break;\r
1560 \r
1561   case WM_PAINT:\r
1562     /* This should not be necessary. However, if SetSampleFontText() is called\r
1563      * in response to WM_INITDIALOG, the strings are not properly centered in\r
1564      * the controls when the dialog first appears. I can't figure out why, so\r
1565      * this is the workaround.  --msw\r
1566      */\r
1567     if (firstPaint) {\r
1568       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1569       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1570       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1571       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1572       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1573       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1574       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1575       firstPaint = FALSE;\r
1576     }\r
1577     break;\r
1578 \r
1579   case WM_COMMAND: /* message: received a command */\r
1580     switch (LOWORD(wParam)) {\r
1581 \r
1582     case IDOK:\r
1583       /* again, it seems to avoid redraw problems if we call EndDialog first */\r
1584       EndDialog(hDlg, FALSE);\r
1585 \r
1586       /* copy modified settings back to the fonts array */\r
1587       for (i=0; i < NUM_FONTS; i++)\r
1588         CopyFont(font[boardSize][i], &workFont[i]);\r
1589 \r
1590       /* a sad necessity due to the original design of having a separate\r
1591        * console font, tags font, and comment font for each board size.  IMHO\r
1592        * these fonts should not be dependent on the current board size.  I'm\r
1593        * running out of time, so I am doing this hack rather than redesign the\r
1594        * data structure. Besides, I think if I redesigned the data structure, I\r
1595        * might break backwards compatibility with old winboard.ini files.\r
1596        * --msw\r
1597        */\r
1598       for (i=0; i < NUM_SIZES; i++) {\r
1599         CopyFont(font[i][EDITTAGS_FONT], &workFont[EDITTAGS_FONT]);\r
1600         CopyFont(font[i][CONSOLE_FONT],  &workFont[CONSOLE_FONT]);\r
1601         CopyFont(font[i][COMMENT_FONT],  &workFont[COMMENT_FONT]);\r
1602         CopyFont(font[i][MOVEHISTORY_FONT],  &workFont[MOVEHISTORY_FONT]);\r
1603       }\r
1604       /* end sad necessity */\r
1605 \r
1606       InitDrawingSizes(boardSize, 0);\r
1607       InvalidateRect(hwndMain, NULL, TRUE);\r
1608 \r
1609       if (commentDialog) {\r
1610         SendDlgItemMessage(commentDialog, OPT_CommentText,\r
1611           WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf, \r
1612           MAKELPARAM(TRUE, 0));\r
1613         GetClientRect(GetDlgItem(commentDialog, OPT_CommentText), &rect);\r
1614         InvalidateRect(commentDialog, &rect, TRUE);\r
1615       }\r
1616 \r
1617       if (editTagsDialog) {\r
1618         SendDlgItemMessage(editTagsDialog, OPT_TagsText,\r
1619           WM_SETFONT, (WPARAM)font[boardSize][EDITTAGS_FONT]->hf, \r
1620           MAKELPARAM(TRUE, 0));\r
1621         GetClientRect(GetDlgItem(editTagsDialog, OPT_TagsText), &rect);\r
1622         InvalidateRect(editTagsDialog, &rect, TRUE);\r
1623       }\r
1624 \r
1625       if( moveHistoryDialog != NULL ) {\r
1626         SendDlgItemMessage(moveHistoryDialog, IDC_MoveHistory,\r
1627           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
1628           MAKELPARAM(TRUE, 0));\r
1629         SendMessage( moveHistoryDialog, WM_INITDIALOG, 0, 0 );\r
1630 //      InvalidateRect(editTagsDialog, NULL, TRUE); // [HGM] this ws improperly cloned?\r
1631       }\r
1632 \r
1633       if( engineOutputDialog != NULL ) {\r
1634         SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo1,\r
1635           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
1636           MAKELPARAM(TRUE, 0));\r
1637         SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo2,\r
1638           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
1639           MAKELPARAM(TRUE, 0));\r
1640       }\r
1641 \r
1642       if (hwndConsole) {\r
1643         ChangedConsoleFont();\r
1644       }\r
1645 \r
1646       for (i=0; i<NUM_FONTS; i++)\r
1647         DeleteObject(&workFont[i].hf);\r
1648 \r
1649       return TRUE;\r
1650 \r
1651     case IDCANCEL:\r
1652       for (i=0; i<NUM_FONTS; i++)\r
1653         DeleteObject(&workFont[i].hf);\r
1654       EndDialog(hDlg, FALSE);\r
1655       return TRUE;\r
1656 \r
1657     case OPT_ChooseClockFont:\r
1658       MyCreateFont(hDlg, &workFont[CLOCK_FONT]);\r
1659       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1660       break;\r
1661 \r
1662     case OPT_ChooseMessageFont:\r
1663       MyCreateFont(hDlg, &workFont[MESSAGE_FONT]);\r
1664       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1665       break;\r
1666 \r
1667     case OPT_ChooseCoordFont:\r
1668       MyCreateFont(hDlg, &workFont[COORD_FONT]);\r
1669       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1670       break;\r
1671 \r
1672     case OPT_ChooseTagFont:\r
1673       MyCreateFont(hDlg, &workFont[EDITTAGS_FONT]);\r
1674       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1675       break;\r
1676 \r
1677     case OPT_ChooseCommentsFont:\r
1678       MyCreateFont(hDlg, &workFont[COMMENT_FONT]);\r
1679       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1680       break;\r
1681 \r
1682     case OPT_ChooseConsoleFont:\r
1683       MyCreateFont(hDlg, &workFont[CONSOLE_FONT]);\r
1684       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1685       break;\r
1686 \r
1687     case OPT_ChooseMoveHistoryFont:\r
1688       MyCreateFont(hDlg, &workFont[MOVEHISTORY_FONT]);\r
1689       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1690       break;\r
1691 \r
1692     case OPT_DefaultFonts:\r
1693       for (i=0; i<NUM_FONTS; i++) {\r
1694         DeleteObject(&workFont[i].hf);\r
1695         ParseFontName(font[boardSize][i]->def, &workFont[i].mfp);\r
1696         CreateFontInMF(&workFont[i]);\r
1697       }\r
1698       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1699       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1700       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1701       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1702       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1703       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1704       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1705       break;\r
1706     }\r
1707   }\r
1708   return FALSE;\r
1709 }\r
1710 \r
1711 VOID\r
1712 FontsOptionsPopup(HWND hwnd)\r
1713 {\r
1714   FARPROC lpProc = MakeProcInstance((FARPROC)FontOptionsDialog, hInst);\r
1715   DialogBox(hInst, MAKEINTRESOURCE(DLG_Fonts), hwnd,\r
1716           (DLGPROC) lpProc);\r
1717   FreeProcInstance(lpProc);\r
1718 }\r
1719 \r
1720 /*---------------------------------------------------------------------------*\\r
1721  *\r
1722  * Sounds Dialog functions\r
1723  *\r
1724 \*---------------------------------------------------------------------------*/\r
1725 \r
1726 \r
1727 SoundComboData soundComboData[] = {\r
1728   {"Move", NULL},\r
1729   {"Bell", NULL},\r
1730   {"ICS Alarm", NULL},\r
1731   {"ICS Win", NULL},\r
1732   {"ICS Loss", NULL},\r
1733   {"ICS Draw", NULL},\r
1734   {"ICS Unfinished", NULL},\r
1735   {"Shout", NULL},\r
1736   {"SShout/CShout", NULL},\r
1737   {"Channel 1", NULL},\r
1738   {"Channel", NULL},\r
1739   {"Kibitz", NULL},\r
1740   {"Tell", NULL},\r
1741   {"Challenge", NULL},\r
1742   {"Request", NULL},\r
1743   {"Seek", NULL},\r
1744   {NULL, NULL},\r
1745 };\r
1746 \r
1747 \r
1748 void\r
1749 InitSoundComboData(SoundComboData *scd)\r
1750 {\r
1751   SoundClass sc;\r
1752   ColorClass cc;\r
1753   int index;\r
1754 \r
1755   /* copy current sound settings to combo array */\r
1756 \r
1757   for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
1758     scd[sc].name = strdup(sounds[sc].name);\r
1759   }\r
1760   for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
1761     index = (int)cc + (int)NSoundClasses;\r
1762     scd[index].name = strdup(textAttribs[cc].sound.name);\r
1763   }\r
1764 }\r
1765 \r
1766 \r
1767 void\r
1768 ResetSoundComboData(SoundComboData *scd)\r
1769 {\r
1770   while (scd->label) {\r
1771     if (scd->name != NULL) {\r
1772       free (scd->name);\r
1773       scd->name = NULL;\r
1774     }\r
1775     scd++;\r
1776   }\r
1777 }\r
1778 \r
1779 void\r
1780 InitSoundCombo(HWND hwndCombo, SoundComboData *scd)\r
1781 {\r
1782   char buf[255];\r
1783   DWORD err;\r
1784   DWORD cnt = 0;\r
1785   SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
1786 \r
1787   /* send the labels to the combo box */\r
1788   while (scd->label) {\r
1789     err = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) scd->label);\r
1790     if (err != cnt++) {\r
1791       sprintf(buf, "InitSoundCombo(): err '%d', cnt '%d'\n",\r
1792           (int)err, (int)cnt);\r
1793       MessageBox(NULL, buf, NULL, MB_OK);\r
1794     }\r
1795     scd++;\r
1796   }\r
1797   SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
1798 }\r
1799 \r
1800 int\r
1801 SoundDialogWhichRadio(HWND hDlg)\r
1802 {\r
1803   if (IsDlgButtonChecked(hDlg, OPT_NoSound)) return OPT_NoSound;\r
1804   if (IsDlgButtonChecked(hDlg, OPT_DefaultBeep)) return OPT_DefaultBeep;\r
1805   if (IsDlgButtonChecked(hDlg, OPT_BuiltInSound)) return OPT_BuiltInSound;\r
1806   if (IsDlgButtonChecked(hDlg, OPT_WavFile)) return OPT_WavFile;\r
1807   return -1;\r
1808 }\r
1809 \r
1810 VOID\r
1811 SoundDialogSetEnables(HWND hDlg, int radio)\r
1812 {\r
1813   EnableWindow(GetDlgItem(hDlg, OPT_BuiltInSoundName),\r
1814                radio == OPT_BuiltInSound);\r
1815   EnableWindow(GetDlgItem(hDlg, OPT_WavFileName), radio == OPT_WavFile);\r
1816   EnableWindow(GetDlgItem(hDlg, OPT_BrowseSound), radio == OPT_WavFile);\r
1817 }\r
1818 \r
1819 char *\r
1820 SoundDialogGetName(HWND hDlg, int radio)\r
1821 {\r
1822   static char buf[MSG_SIZ], buf2[MSG_SIZ], buf3[MSG_SIZ];\r
1823   char *dummy, *ret;\r
1824   switch (radio) {\r
1825   case OPT_NoSound:\r
1826   default:\r
1827     return "";\r
1828   case OPT_DefaultBeep:\r
1829     return "$";\r
1830   case OPT_BuiltInSound:\r
1831     buf[0] = '!';\r
1832     GetDlgItemText(hDlg, OPT_BuiltInSoundName, buf + 1, sizeof(buf) - 1);\r
1833     return buf;\r
1834   case OPT_WavFile:\r
1835     GetDlgItemText(hDlg, OPT_WavFileName, buf, sizeof(buf));\r
1836     GetCurrentDirectory(MSG_SIZ, buf3);\r
1837     SetCurrentDirectory(installDir);\r
1838     if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
1839       ret = buf2;\r
1840     } else {\r
1841       ret = buf;\r
1842     }\r
1843     SetCurrentDirectory(buf3);\r
1844     return ret;\r
1845   }\r
1846 }\r
1847 \r
1848 void\r
1849 DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name)\r
1850 {\r
1851   int radio;\r
1852   /* \r
1853    * I think it's best to clear the combo and edit boxes. It looks stupid\r
1854    * to have a value from another sound event sitting there grayed out.\r
1855    */\r
1856   SetDlgItemText(hDlg, OPT_WavFileName, "");\r
1857   SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
1858 \r
1859   if (appData.debugMode)\r
1860       fprintf(debugFP, "DisplaySelectedSound(,,'%s'):\n", name);\r
1861   switch (name[0]) {\r
1862   case NULLCHAR:\r
1863     radio = OPT_NoSound;\r
1864     break;\r
1865   case '$':\r
1866     if (name[1] == NULLCHAR) {\r
1867       radio = OPT_DefaultBeep;\r
1868     } else {\r
1869       radio = OPT_WavFile;\r
1870       SetDlgItemText(hDlg, OPT_WavFileName, name);\r
1871     }\r
1872     break;\r
1873   case '!':\r
1874     if (name[1] == NULLCHAR) {\r
1875       radio = OPT_NoSound;\r
1876     } else {\r
1877       radio = OPT_BuiltInSound;\r
1878       if (SendMessage(hCombo, CB_SELECTSTRING, (WPARAM) -1, \r
1879                       (LPARAM) (name + 1)) == CB_ERR) {\r
1880         SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
1881         SendMessage(hCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) (name + 1));\r
1882       }\r
1883     }\r
1884     break;\r
1885   default:\r
1886     radio = OPT_WavFile;\r
1887     SetDlgItemText(hDlg, OPT_WavFileName, name);\r
1888     break;\r
1889   }\r
1890   SoundDialogSetEnables(hDlg, radio);\r
1891   CheckRadioButton(hDlg, OPT_NoSound, OPT_WavFile, radio);\r
1892 }\r
1893     \r
1894 \r
1895 char *builtInSoundNames[] = BUILT_IN_SOUND_NAMES;\r
1896 \r
1897 LRESULT CALLBACK\r
1898 SoundOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1899 {\r
1900   static HWND hSoundCombo;\r
1901   static DWORD index;\r
1902   static HWND hBISN;\r
1903   int radio;\r
1904   MySound tmp;\r
1905   FILE *f;\r
1906   char buf[MSG_SIZ];\r
1907   char *newName;\r
1908   SoundClass sc;\r
1909   ColorClass cc;\r
1910   SoundComboData *scd;\r
1911   int oldMute;\r
1912 \r
1913   switch (message) {\r
1914   case WM_INITDIALOG:\r
1915     /* Center the dialog over the application window */\r
1916     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
1917 \r
1918     /* Initialize the built-in sounds combo */\r
1919     hBISN = GetDlgItem(hDlg, OPT_BuiltInSoundName);\r
1920      InitComboStrings(hBISN, builtInSoundNames);\r
1921 \r
1922     /* Initialize the  sound events combo */\r
1923     index = 0;\r
1924     InitSoundComboData(soundComboData);\r
1925     hSoundCombo = GetDlgItem(hDlg, CBO_Sounds);\r
1926     InitSoundCombo(hSoundCombo, soundComboData);\r
1927 \r
1928     /* update the dialog */\r
1929     DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
1930     return TRUE;\r
1931 \r
1932   case WM_COMMAND: /* message: received a command */\r
1933 \r
1934     if (((HWND)lParam == hSoundCombo) && \r
1935         (HIWORD(wParam) == CBN_SELCHANGE)) {\r
1936       /* \r
1937        * the user has selected a new sound event. We must store the name for\r
1938        * the previously selected event, then retrieve the name for the\r
1939        * newly selected event and update the dialog. \r
1940        */\r
1941       radio = SoundDialogWhichRadio(hDlg);\r
1942       newName = strdup(SoundDialogGetName(hDlg, radio));\r
1943       \r
1944       if (strcmp(newName, soundComboData[index].name) != 0) {\r
1945         free(soundComboData[index].name);\r
1946         soundComboData[index].name = newName;\r
1947       } else {\r
1948         free(newName);\r
1949         newName = NULL;\r
1950       }\r
1951       /* now get the settings for the newly selected event */\r
1952       index = SendMessage(hSoundCombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);\r
1953       DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
1954       \r
1955       return TRUE;\r
1956     }\r
1957     switch (LOWORD(wParam)) {\r
1958     case IDOK:\r
1959       /* \r
1960        * save the name for the currently selected sound event \r
1961        */\r
1962       radio = SoundDialogWhichRadio(hDlg);\r
1963       newName = strdup(SoundDialogGetName(hDlg, radio));\r
1964 \r
1965       if (strcmp(soundComboData[index].name, newName) != 0) {\r
1966         free(soundComboData[index].name);\r
1967         soundComboData[index].name = newName;\r
1968       } else {\r
1969         free(newName);\r
1970         newName = NULL;\r
1971       }\r
1972 \r
1973       /* save all the sound names that changed and load the sounds */\r
1974 \r
1975       for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
1976         if (strcmp(soundComboData[sc].name, sounds[sc].name) != 0) {\r
1977           free(sounds[sc].name);\r
1978           sounds[sc].name = strdup(soundComboData[sc].name);\r
1979           MyLoadSound(&sounds[sc]);\r
1980         }\r
1981       }\r
1982       for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
1983         index = (int)cc + (int)NSoundClasses;\r
1984         if (strcmp(soundComboData[index].name, \r
1985                    textAttribs[cc].sound.name) != 0) {\r
1986           free(textAttribs[cc].sound.name);\r
1987           textAttribs[cc].sound.name = strdup(soundComboData[index].name);\r
1988           MyLoadSound(&textAttribs[cc].sound);\r
1989         }\r
1990       }\r
1991 \r
1992         mute = FALSE; // [HGM] mute: switch sounds automatically on if we select one\r
1993       CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds,MF_BYCOMMAND|MF_UNCHECKED);\r
1994       ResetSoundComboData(soundComboData);\r
1995       EndDialog(hDlg, TRUE);\r
1996       return TRUE;\r
1997 \r
1998     case IDCANCEL:\r
1999       ResetSoundComboData(soundComboData);\r
2000       EndDialog(hDlg, FALSE);\r
2001       return TRUE;\r
2002 \r
2003     case OPT_DefaultSounds:\r
2004       /* can't use SetDefaultSounds() because we need to be able to "undo" if\r
2005        * user selects "Cancel" later on. So we do it the hard way here.\r
2006        */\r
2007       scd = &soundComboData[0];\r
2008       while (scd->label != NULL) {\r
2009         if (scd->name != NULL) free(scd->name);\r
2010         scd->name = strdup("");\r
2011         scd++;\r
2012       }\r
2013       free(soundComboData[(int)SoundBell].name);\r
2014       soundComboData[(int)SoundBell].name = strdup(SOUND_BELL);\r
2015       DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
2016       break;\r
2017 \r
2018     case OPT_PlaySound:\r
2019       radio = SoundDialogWhichRadio(hDlg);\r
2020       tmp.name = strdup(SoundDialogGetName(hDlg, radio));\r
2021       tmp.data = NULL;\r
2022       MyLoadSound(&tmp);\r
2023         oldMute = mute; mute = FALSE; // [HGM] mute: always sound when user presses play, ignorig mute setting\r
2024       MyPlaySound(&tmp);\r
2025         mute = oldMute;\r
2026       if (tmp.data  != NULL) FreeResource(tmp.data); // technically obsolete fn, but tmp.data is NOT malloc'd mem\r
2027       if (tmp.name != NULL) free(tmp.name);\r
2028       return TRUE;\r
2029 \r
2030     case OPT_BrowseSound:\r
2031       f = OpenFileDialog(hDlg, "rb", NULL, "wav", SOUND_FILT,\r
2032         "Browse for Sound File", NULL, NULL, buf);\r
2033       if (f != NULL) {\r
2034         fclose(f);\r
2035         SetDlgItemText(hDlg, OPT_WavFileName, buf);\r
2036       }\r
2037       return TRUE;\r
2038 \r
2039     default:\r
2040       radio = SoundDialogWhichRadio(hDlg);\r
2041       SoundDialogSetEnables(hDlg, radio);\r
2042       break;\r
2043     }\r
2044     break;\r
2045   }\r
2046   return FALSE;\r
2047 }\r
2048 \r
2049 \r
2050 VOID SoundOptionsPopup(HWND hwnd)\r
2051 {\r
2052   FARPROC lpProc;\r
2053 \r
2054   lpProc = MakeProcInstance((FARPROC)SoundOptionsDialog, hInst);\r
2055   DialogBox(hInst, MAKEINTRESOURCE(DLG_Sound), hwnd, (DLGPROC)lpProc);\r
2056   FreeProcInstance(lpProc);\r
2057 }\r
2058 \r
2059 \r
2060 /*---------------------------------------------------------------------------*\\r
2061  *\r
2062  * Comm Port dialog functions\r
2063  *\r
2064 \*---------------------------------------------------------------------------*/\r
2065 \r
2066 \r
2067 #define FLOW_NONE   0\r
2068 #define FLOW_XOFF   1\r
2069 #define FLOW_CTS    2\r
2070 #define FLOW_DSR    3\r
2071 \r
2072 #define PORT_NONE\r
2073 \r
2074 ComboData cdPort[]     = { {"None", PORT_NONE}, {"COM1", 1}, {"COM2", 2},\r
2075                            {"COM3", 3}, {"COM4", 4}, {NULL, 0} };\r
2076 ComboData cdDataRate[] = { {"110", 110}, {"300", 300}, {"600", 600}, {"1200", 1200},\r
2077                            {"2400", 2400}, {"4800", 4800}, {"9600", 9600}, {"19200", 19200},\r
2078                            {"38400", 38400}, {NULL, 0} };\r
2079 ComboData cdDataBits[] = { {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {NULL, 0} };\r
2080 ComboData cdParity[]   = { {"None", NOPARITY}, {"Odd", ODDPARITY}, {"Even", EVENPARITY},\r
2081                            {"Mark", MARKPARITY}, {"Space", SPACEPARITY}, {NULL, 0} };\r
2082 ComboData cdStopBits[] = { {"1", ONESTOPBIT}, {"1.5", ONE5STOPBITS},\r
2083                            {"2", TWOSTOPBITS}, {NULL, 0} };\r
2084 ComboData cdFlow[]     = { {"None", FLOW_NONE}, {"Xoff/Xon", FLOW_XOFF}, {"CTS", FLOW_CTS},\r
2085                            {"DSR", FLOW_DSR}, {NULL, 0} };\r
2086 \r
2087 \r
2088 VOID\r
2089 ParseCommSettings(char *arg, DCB *dcb)\r
2090 {\r
2091   int dataRate, count;\r
2092   char bits[MSG_SIZ], parity[MSG_SIZ], stopBits[MSG_SIZ], flow[MSG_SIZ];\r
2093   ComboData *cd;\r
2094   count = sscanf(arg, "%d%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]",\r
2095     &dataRate, bits, parity, stopBits, flow);\r
2096   if (count != 5) goto cant_parse;\r
2097   dcb->BaudRate = dataRate;\r
2098   cd = cdDataBits;\r
2099   while (cd->label != NULL) {\r
2100     if (StrCaseCmp(cd->label, bits) == 0) {\r
2101       dcb->ByteSize = cd->value;\r
2102       break;\r
2103     }\r
2104     cd++;\r
2105   }\r
2106   if (cd->label == NULL) goto cant_parse;\r
2107   cd = cdParity;\r
2108   while (cd->label != NULL) {\r
2109     if (StrCaseCmp(cd->label, parity) == 0) {\r
2110       dcb->Parity = cd->value;\r
2111       break;\r
2112     }\r
2113     cd++;\r
2114   }\r
2115   if (cd->label == NULL) goto cant_parse;\r
2116   cd = cdStopBits;\r
2117   while (cd->label != NULL) {\r
2118     if (StrCaseCmp(cd->label, stopBits) == 0) {\r
2119       dcb->StopBits = cd->value;\r
2120       break;\r
2121     }\r
2122     cd++;\r
2123   }\r
2124   cd = cdFlow;\r
2125   if (cd->label == NULL) goto cant_parse;\r
2126   while (cd->label != NULL) {\r
2127     if (StrCaseCmp(cd->label, flow) == 0) {\r
2128       switch (cd->value) {\r
2129       case FLOW_NONE:\r
2130         dcb->fOutX = FALSE;\r
2131         dcb->fOutxCtsFlow = FALSE;\r
2132         dcb->fOutxDsrFlow = FALSE;\r
2133         break;\r
2134       case FLOW_CTS:\r
2135         dcb->fOutX = FALSE;\r
2136         dcb->fOutxCtsFlow = TRUE;\r
2137         dcb->fOutxDsrFlow = FALSE;\r
2138         break;\r
2139       case FLOW_DSR:\r
2140         dcb->fOutX = FALSE;\r
2141         dcb->fOutxCtsFlow = FALSE;\r
2142         dcb->fOutxDsrFlow = TRUE;\r
2143         break;\r
2144       case FLOW_XOFF:\r
2145         dcb->fOutX = TRUE;\r
2146         dcb->fOutxCtsFlow = FALSE;\r
2147         dcb->fOutxDsrFlow = FALSE;\r
2148         break;\r
2149       }\r
2150       break;\r
2151     }\r
2152     cd++;\r
2153   }\r
2154   if (cd->label == NULL) goto cant_parse;\r
2155   return;\r
2156 cant_parse:\r
2157     ExitArgError("Can't parse com port settings", arg);\r
2158 }\r
2159 \r
2160 \r
2161 VOID PrintCommSettings(FILE *f, char *name, DCB *dcb)\r
2162 {\r
2163   char *flow = "??", *parity = "??", *stopBits = "??";\r
2164   ComboData *cd;\r
2165   \r
2166   cd = cdParity;\r
2167   while (cd->label != NULL) {\r
2168     if (dcb->Parity == cd->value) {\r
2169       parity = cd->label;\r
2170       break;\r
2171     }\r
2172     cd++;\r
2173   }\r
2174   cd = cdStopBits;\r
2175   while (cd->label != NULL) {\r
2176     if (dcb->StopBits == cd->value) {\r
2177       stopBits = cd->label;\r
2178       break;\r
2179     }\r
2180     cd++;\r
2181   }\r
2182   if (dcb->fOutX) {\r
2183     flow = cdFlow[FLOW_XOFF].label;\r
2184   } else if (dcb->fOutxCtsFlow) {\r
2185     flow = cdFlow[FLOW_CTS].label;\r
2186   } else if (dcb->fOutxDsrFlow) {\r
2187     flow = cdFlow[FLOW_DSR].label;\r
2188   } else {\r
2189     flow = cdFlow[FLOW_NONE].label;\r
2190   }\r
2191   fprintf(f, "/%s=%d,%d,%s,%s,%s\n", name,\r
2192     (int)dcb->BaudRate, dcb->ByteSize, parity, stopBits, flow);\r
2193 }\r
2194 \r
2195 \r
2196 void\r
2197 InitCombo(HANDLE hwndCombo, ComboData *cd)\r
2198 {\r
2199   SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
2200 \r
2201   while (cd->label != NULL) {\r
2202     SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) cd->label);\r
2203     cd++;\r
2204   }\r
2205 }\r
2206 \r
2207 void\r
2208 SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value)\r
2209 {\r
2210   int i;\r
2211 \r
2212   i = 0;\r
2213   while (cd->label != NULL) {\r
2214     if (cd->value == value) {\r
2215       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) i, (LPARAM) 0);\r
2216       return;\r
2217     }\r
2218     cd++;\r
2219     i++;\r
2220   }\r
2221 }\r
2222 \r
2223 LRESULT CALLBACK\r
2224 CommPortOptionsDialog(HWND hDlg, UINT message, WPARAM wParam,   LPARAM lParam)\r
2225 {\r
2226   char buf[MSG_SIZ];\r
2227   HANDLE hwndCombo;\r
2228   char *p;\r
2229   LRESULT index;\r
2230   unsigned value;\r
2231   int err;\r
2232 \r
2233   switch (message) {\r
2234   case WM_INITDIALOG: /* message: initialize dialog box */\r
2235     /* Center the dialog over the application window */\r
2236     CenterWindow (hDlg, GetWindow(hDlg, GW_OWNER));\r
2237     /* Initialize the dialog items */\r
2238     /* !! There should probably be some synchronization\r
2239        in accessing hCommPort and dcb.  Or does modal nature\r
2240        of this dialog box do it for us?\r
2241        */\r
2242     hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
2243     InitCombo(hwndCombo, cdPort);\r
2244     p = strrchr(appData.icsCommPort, '\\');\r
2245     if (p++ == NULL) p = appData.icsCommPort;\r
2246     if ((*p == '\0') ||\r
2247         (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) p) == CB_ERR)) {\r
2248       SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) "None");\r
2249     }\r
2250     EnableWindow(hwndCombo, hCommPort == NULL); /*!! don't allow change for now*/\r
2251 \r
2252     hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
2253     InitCombo(hwndCombo, cdDataRate);\r
2254     sprintf(buf, "%u", (int)dcb.BaudRate);\r
2255     if (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) buf) == CB_ERR) {\r
2256       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
2257       SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);\r
2258     }\r
2259 \r
2260     hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
2261     InitCombo(hwndCombo, cdDataBits);\r
2262     SelectComboValue(hwndCombo, cdDataBits, dcb.ByteSize);\r
2263 \r
2264     hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
2265     InitCombo(hwndCombo, cdParity);\r
2266     SelectComboValue(hwndCombo, cdParity, dcb.Parity);\r
2267 \r
2268     hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
2269     InitCombo(hwndCombo, cdStopBits);\r
2270     SelectComboValue(hwndCombo, cdStopBits, dcb.StopBits);\r
2271 \r
2272     hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
2273     InitCombo(hwndCombo, cdFlow);\r
2274     if (dcb.fOutX) {\r
2275       SelectComboValue(hwndCombo, cdFlow, FLOW_XOFF);\r
2276     } else if (dcb.fOutxCtsFlow) {\r
2277       SelectComboValue(hwndCombo, cdFlow, FLOW_CTS);\r
2278     } else if (dcb.fOutxDsrFlow) {\r
2279       SelectComboValue(hwndCombo, cdFlow, FLOW_DSR);\r
2280     } else {\r
2281       SelectComboValue(hwndCombo, cdFlow, FLOW_NONE);\r
2282     }\r
2283     return TRUE;\r
2284 \r
2285   case WM_COMMAND: /* message: received a command */\r
2286     switch (LOWORD(wParam)) {\r
2287     case IDOK:\r
2288       /* Read changed options from the dialog box */\r
2289 #ifdef NOTDEF\r
2290       /* !! Currently we can't change comm ports in midstream */\r
2291       hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
2292       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2293       if (index == PORT_NONE) {\r
2294         appData.icsCommPort = "";\r
2295         if (hCommPort != NULL) {\r
2296           CloseHandle(hCommPort);\r
2297           hCommPort = NULL;\r
2298         }\r
2299         EndDialog(hDlg, TRUE);\r
2300         return TRUE;\r
2301       }\r
2302       SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
2303       appData.icsCommPort = strdup(buf);\r
2304       if (hCommPort != NULL) {\r
2305         CloseHandle(hCommPort);\r
2306         hCommPort = NULL;\r
2307       }\r
2308       /* now what?? can't really do this; have to fix up the ChildProc\r
2309          and InputSource records for the comm port that we gave to the\r
2310          back end. */\r
2311 #endif /*NOTDEF*/\r
2312 \r
2313       hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
2314       SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
2315       if (sscanf(buf, "%u", &value) != 1) {\r
2316         MessageBox(hDlg, "Invalid data rate",\r
2317                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2318         return TRUE;\r
2319       }\r
2320       dcb.BaudRate = value;\r
2321 \r
2322       hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
2323       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2324       dcb.ByteSize = cdDataBits[index].value;\r
2325 \r
2326       hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
2327       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2328       dcb.Parity = cdParity[index].value;\r
2329 \r
2330       hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
2331       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2332       dcb.StopBits = cdStopBits[index].value;\r
2333 \r
2334       hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
2335       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2336       switch (cdFlow[index].value) {\r
2337       case FLOW_NONE:\r
2338         dcb.fOutX = FALSE;\r
2339         dcb.fOutxCtsFlow = FALSE;\r
2340         dcb.fOutxDsrFlow = FALSE;\r
2341         break;\r
2342       case FLOW_CTS:\r
2343         dcb.fOutX = FALSE;\r
2344         dcb.fOutxCtsFlow = TRUE;\r
2345         dcb.fOutxDsrFlow = FALSE;\r
2346         break;\r
2347       case FLOW_DSR:\r
2348         dcb.fOutX = FALSE;\r
2349         dcb.fOutxCtsFlow = FALSE;\r
2350         dcb.fOutxDsrFlow = TRUE;\r
2351         break;\r
2352       case FLOW_XOFF:\r
2353         dcb.fOutX = TRUE;\r
2354         dcb.fOutxCtsFlow = FALSE;\r
2355         dcb.fOutxDsrFlow = FALSE;\r
2356         break;\r
2357       }\r
2358       if (!SetCommState(hCommPort, (LPDCB) &dcb)) {\r
2359         err = GetLastError();\r
2360         switch(MessageBox(hDlg, \r
2361                          "Failed to set comm port state;\r\ninvalid options?",\r
2362                          "Option Error", MB_ABORTRETRYIGNORE|MB_ICONQUESTION)) {\r
2363         case IDABORT:\r
2364           DisplayFatalError("Failed to set comm port state", err, 1);\r
2365           exit(1);  /*is it ok to do this from here?*/\r
2366 \r
2367         case IDRETRY:\r
2368           return TRUE;\r
2369 \r
2370         case IDIGNORE:\r
2371           EndDialog(hDlg, TRUE);\r
2372           return TRUE;\r
2373         }\r
2374       }\r
2375 \r
2376       EndDialog(hDlg, TRUE);\r
2377       return TRUE;\r
2378 \r
2379     case IDCANCEL:\r
2380       EndDialog(hDlg, FALSE);\r
2381       return TRUE;\r
2382 \r
2383     default:\r
2384       break;\r
2385     }\r
2386     break;\r
2387   }\r
2388   return FALSE;\r
2389 }\r
2390 \r
2391 VOID\r
2392 CommPortOptionsPopup(HWND hwnd)\r
2393 {\r
2394   FARPROC lpProc = MakeProcInstance((FARPROC)CommPortOptionsDialog, hInst);\r
2395   DialogBox(hInst, MAKEINTRESOURCE(DLG_CommPort), hwnd, (DLGPROC) lpProc);\r
2396   FreeProcInstance(lpProc);\r
2397 }\r
2398 \r
2399 /*---------------------------------------------------------------------------*\\r
2400  *\r
2401  * Load Options dialog functions\r
2402  *\r
2403 \*---------------------------------------------------------------------------*/\r
2404 \r
2405 VOID\r
2406 SetLoadOptionEnables(HWND hDlg)\r
2407 {\r
2408   UINT state;\r
2409 \r
2410   state = IsDlgButtonChecked(hDlg, OPT_Autostep);\r
2411   EnableWindow(GetDlgItem(hDlg, OPT_ASTimeDelay), state);\r
2412   EnableWindow(GetDlgItem(hDlg, OPT_AStext1), state);\r
2413 }\r
2414 \r
2415 LRESULT CALLBACK\r
2416 LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2417 {\r
2418   char buf[MSG_SIZ];\r
2419   float fnumber;\r
2420 \r
2421   switch (message) {\r
2422   case WM_INITDIALOG: /* message: initialize dialog box */\r
2423     /* Center the dialog over the application window */\r
2424     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2425     /* Initialize the dialog items */\r
2426     if (appData.timeDelay >= 0.0) {\r
2427       CheckDlgButton(hDlg, OPT_Autostep, TRUE);\r
2428       sprintf(buf, "%.2g", appData.timeDelay);\r
2429       SetDlgItemText(hDlg, OPT_ASTimeDelay, buf);\r
2430     } else {\r
2431       CheckDlgButton(hDlg, OPT_Autostep, FALSE);\r
2432     }\r
2433     SetLoadOptionEnables(hDlg);\r
2434     return TRUE;\r
2435 \r
2436   case WM_COMMAND: /* message: received a command */\r
2437     switch (LOWORD(wParam)) {\r
2438     case IDOK:\r
2439       /* Read changed options from the dialog box */\r
2440       if (IsDlgButtonChecked(hDlg, OPT_Autostep)) {\r
2441         GetDlgItemText(hDlg, OPT_ASTimeDelay, buf, MSG_SIZ);\r
2442         if (sscanf(buf, "%f", &fnumber) != 1) {\r
2443           MessageBox(hDlg, "Invalid load game step rate",\r
2444                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2445           return FALSE;\r
2446         }\r
2447         appData.timeDelay = fnumber;\r
2448       } else {\r
2449         appData.timeDelay = (float) -1.0;\r
2450       }\r
2451       EndDialog(hDlg, TRUE);\r
2452       return TRUE;\r
2453 \r
2454     case IDCANCEL:\r
2455       EndDialog(hDlg, FALSE);\r
2456       return TRUE;\r
2457 \r
2458     default:\r
2459       SetLoadOptionEnables(hDlg);\r
2460       break;\r
2461     }\r
2462     break;\r
2463   }\r
2464   return FALSE;\r
2465 }\r
2466 \r
2467 \r
2468 VOID \r
2469 LoadOptionsPopup(HWND hwnd)\r
2470 {\r
2471   FARPROC lpProc = MakeProcInstance((FARPROC)LoadOptions, hInst);\r
2472   DialogBox(hInst, MAKEINTRESOURCE(DLG_LoadOptions), hwnd, (DLGPROC) lpProc);\r
2473   FreeProcInstance(lpProc);\r
2474 }\r
2475 \r
2476 /*---------------------------------------------------------------------------*\\r
2477  *\r
2478  * Save Options dialog functions\r
2479  *\r
2480 \*---------------------------------------------------------------------------*/\r
2481 \r
2482 VOID\r
2483 SetSaveOptionEnables(HWND hDlg)\r
2484 {\r
2485   UINT state;\r
2486 \r
2487   state = IsDlgButtonChecked(hDlg, OPT_Autosave);\r
2488   EnableWindow(GetDlgItem(hDlg, OPT_AVPrompt), state);\r
2489   EnableWindow(GetDlgItem(hDlg, OPT_AVToFile), state);\r
2490   if (state && !IsDlgButtonChecked(hDlg, OPT_AVPrompt) &&\r
2491       !IsDlgButtonChecked(hDlg, OPT_AVToFile)) {\r
2492     CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
2493   }\r
2494 \r
2495   state = state && IsDlgButtonChecked(hDlg, OPT_AVToFile);\r
2496   EnableWindow(GetDlgItem(hDlg, OPT_AVFilename), state);\r
2497   EnableWindow(GetDlgItem(hDlg, OPT_AVBrowse), state);\r
2498 }\r
2499 \r
2500 LRESULT CALLBACK\r
2501 SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2502 {\r
2503   char buf[MSG_SIZ];\r
2504   FILE *f;\r
2505 \r
2506   switch (message) {\r
2507   case WM_INITDIALOG: /* message: initialize dialog box */\r
2508     /* Center the dialog over the application window */\r
2509     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2510     /* Initialize the dialog items */\r
2511     if (*appData.saveGameFile != NULLCHAR) {\r
2512       CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
2513       CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVToFile);\r
2514       SetDlgItemText(hDlg, OPT_AVFilename, appData.saveGameFile);\r
2515     } else if (appData.autoSaveGames) {\r
2516       CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
2517       CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
2518     } else {\r
2519       CheckDlgButton(hDlg, OPT_Autosave, (UINT) FALSE);\r
2520     }\r
2521     if (appData.oldSaveStyle) {\r
2522       CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_Old);\r
2523     } else {\r
2524       CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_PGN);\r
2525     }\r
2526     CheckDlgButton( hDlg, OPT_OutOfBookInfo, appData.saveOutOfBookInfo );\r
2527     SetSaveOptionEnables(hDlg);\r
2528     return TRUE;\r
2529 \r
2530   case WM_COMMAND: /* message: received a command */\r
2531     switch (LOWORD(wParam)) {\r
2532     case IDOK:\r
2533       /* Read changed options from the dialog box */\r
2534       if (IsDlgButtonChecked(hDlg, OPT_Autosave)) {\r
2535         appData.autoSaveGames = TRUE;\r
2536         if (IsDlgButtonChecked(hDlg, OPT_AVPrompt)) {\r
2537           appData.saveGameFile = "";\r
2538         } else /*if (IsDlgButtonChecked(hDlg, OPT_AVToFile))*/ {\r
2539           GetDlgItemText(hDlg, OPT_AVFilename, buf, MSG_SIZ);\r
2540           if (*buf == NULLCHAR) {\r
2541             MessageBox(hDlg, "Invalid save game file name",\r
2542                        "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2543             return FALSE;\r
2544           }\r
2545           if ((isalpha(buf[0]) && buf[1] == ':') ||\r
2546             (buf[0] == '\\' && buf[1] == '\\')) {\r
2547             appData.saveGameFile = strdup(buf);\r
2548           } else {\r
2549             char buf2[MSG_SIZ], buf3[MSG_SIZ];\r
2550             char *dummy;\r
2551             GetCurrentDirectory(MSG_SIZ, buf3);\r
2552             SetCurrentDirectory(installDir);\r
2553             if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
2554               appData.saveGameFile = strdup(buf2);\r
2555             } else {\r
2556               appData.saveGameFile = strdup(buf);\r
2557             }\r
2558             SetCurrentDirectory(buf3);\r
2559           }\r
2560         }\r
2561       } else {\r
2562         appData.autoSaveGames = FALSE;\r
2563         appData.saveGameFile = "";\r
2564       }\r
2565       appData.oldSaveStyle = IsDlgButtonChecked(hDlg, OPT_Old);\r
2566       appData.saveOutOfBookInfo = IsDlgButtonChecked( hDlg, OPT_OutOfBookInfo );\r
2567       EndDialog(hDlg, TRUE);\r
2568       return TRUE;\r
2569 \r
2570     case IDCANCEL:\r
2571       EndDialog(hDlg, FALSE);\r
2572       return TRUE;\r
2573 \r
2574     case OPT_AVBrowse:\r
2575       f = OpenFileDialog(hDlg, "a", NULL, \r
2576                          appData.oldSaveStyle ? "gam" : "pgn", \r
2577                          GAME_FILT, "Browse for Auto Save File", \r
2578                          NULL, NULL, buf);\r
2579       if (f != NULL) {\r
2580         fclose(f);\r
2581         SetDlgItemText(hDlg, OPT_AVFilename, buf);\r
2582       }\r
2583       break;\r
2584 \r
2585     default:\r
2586       SetSaveOptionEnables(hDlg);\r
2587       break;\r
2588     }\r
2589     break;\r
2590   }\r
2591   return FALSE;\r
2592 }\r
2593 \r
2594 VOID\r
2595 SaveOptionsPopup(HWND hwnd)\r
2596 {\r
2597   FARPROC lpProc = MakeProcInstance((FARPROC)SaveOptionsDialog, hInst);\r
2598   DialogBox(hInst, MAKEINTRESOURCE(DLG_SaveOptions), hwnd, (DLGPROC) lpProc);\r
2599   FreeProcInstance(lpProc);\r
2600 }\r
2601 \r
2602 /*---------------------------------------------------------------------------*\\r
2603  *\r
2604  * Time Control Options dialog functions\r
2605  *\r
2606 \*---------------------------------------------------------------------------*/\r
2607 \r
2608 VOID\r
2609 SetTimeControlEnables(HWND hDlg)\r
2610 {\r
2611   UINT state;\r
2612 \r
2613   state = IsDlgButtonChecked(hDlg, OPT_TCUseMoves)\r
2614         + 2*IsDlgButtonChecked(hDlg, OPT_TCUseFixed);\r
2615   EnableWindow(GetDlgItem(hDlg, OPT_TCTime), state == 1);\r
2616   EnableWindow(GetDlgItem(hDlg, OPT_TCMoves), state == 1);\r
2617   EnableWindow(GetDlgItem(hDlg, OPT_TCtext1), state == 1);\r
2618   EnableWindow(GetDlgItem(hDlg, OPT_TCtext2), state == 1);\r
2619   EnableWindow(GetDlgItem(hDlg, OPT_TCTime2), !state);\r
2620   EnableWindow(GetDlgItem(hDlg, OPT_TCInc), !state);\r
2621   EnableWindow(GetDlgItem(hDlg, OPT_TCitext1), !state);\r
2622   EnableWindow(GetDlgItem(hDlg, OPT_TCitext2), !state);\r
2623   EnableWindow(GetDlgItem(hDlg, OPT_TCitext3), !state);\r
2624   EnableWindow(GetDlgItem(hDlg, OPT_TCFixed), state == 2);\r
2625   EnableWindow(GetDlgItem(hDlg, OPT_TCftext), state == 2);\r
2626 }\r
2627 \r
2628 \r
2629 LRESULT CALLBACK\r
2630 TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2631 {\r
2632   char buf[MSG_SIZ], *tc;\r
2633   int mps, increment, odds1, odds2, st;\r
2634   BOOL ok, ok2;\r
2635 \r
2636   switch (message) {\r
2637   case WM_INITDIALOG: /* message: initialize dialog box */\r
2638     /* Center the dialog over the application window */\r
2639     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2640     /* Initialize the dialog items */\r
2641     if (appData.clockMode && !appData.icsActive) {\r
2642       if (searchTime) {\r
2643         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2644                          OPT_TCUseFixed);\r
2645         SetDlgItemInt(hDlg, OPT_TCFixed, searchTime, FALSE);\r
2646       } else\r
2647       if (appData.timeIncrement == -1) {\r
2648         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2649                          OPT_TCUseMoves);\r
2650         SetDlgItemText(hDlg, OPT_TCTime, appData.timeControl);\r
2651         SetDlgItemInt(hDlg, OPT_TCMoves, appData.movesPerSession,\r
2652                       FALSE);\r
2653         SetDlgItemText(hDlg, OPT_TCTime2, "");\r
2654         SetDlgItemText(hDlg, OPT_TCInc, "");\r
2655       } else {\r
2656         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2657                          OPT_TCUseInc);\r
2658         SetDlgItemText(hDlg, OPT_TCTime, "");\r
2659         SetDlgItemText(hDlg, OPT_TCMoves, "");\r
2660         SetDlgItemText(hDlg, OPT_TCTime2, appData.timeControl);\r
2661         SetDlgItemInt(hDlg, OPT_TCInc, appData.timeIncrement, FALSE);\r
2662       }\r
2663       SetDlgItemInt(hDlg, OPT_TCOdds1, 1, FALSE);\r
2664       SetDlgItemInt(hDlg, OPT_TCOdds2, 1, FALSE);\r
2665       SetTimeControlEnables(hDlg);\r
2666     }\r
2667     return TRUE;\r
2668 \r
2669   case WM_COMMAND: /* message: received a command */\r
2670     switch (LOWORD(wParam)) {\r
2671     case IDOK:\r
2672       mps = appData.movesPerSession;\r
2673       increment = appData.timeIncrement;\r
2674       tc = appData.timeControl;\r
2675       st = 0;\r
2676       /* Read changed options from the dialog box */\r
2677       if (IsDlgButtonChecked(hDlg, OPT_TCUseFixed)) {\r
2678         st = GetDlgItemInt(hDlg, OPT_TCFixed, &ok, FALSE);\r
2679         if (!ok || st <= 0) {\r
2680           MessageBox(hDlg, "Invalid max time per move",\r
2681                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2682           return FALSE;\r
2683         }\r
2684       } else\r
2685       if (IsDlgButtonChecked(hDlg, OPT_TCUseMoves)) {\r
2686         increment = -1;\r
2687         mps = GetDlgItemInt(hDlg, OPT_TCMoves, &ok, FALSE);\r
2688         if (!ok || mps <= 0) {\r
2689           MessageBox(hDlg, "Invalid moves per time control",\r
2690                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2691           return FALSE;\r
2692         }\r
2693         GetDlgItemText(hDlg, OPT_TCTime, buf, MSG_SIZ);\r
2694         if (!ParseTimeControl(buf, increment, mps)) {\r
2695           MessageBox(hDlg, "Invalid minutes per time control",\r
2696                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2697           return FALSE;\r
2698         }\r
2699       tc = buf;\r
2700       } else {\r
2701         increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE);\r
2702         if (!ok || increment < 0) {\r
2703           MessageBox(hDlg, "Invalid increment",\r
2704                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2705           return FALSE;\r
2706         }\r
2707         GetDlgItemText(hDlg, OPT_TCTime2, buf, MSG_SIZ);\r
2708         if (!ParseTimeControl(buf, increment, mps)) {\r
2709           MessageBox(hDlg, "Invalid initial time",\r
2710                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2711           return FALSE;\r
2712         }\r
2713       tc = buf;\r
2714       }\r
2715       odds1 = GetDlgItemInt(hDlg, OPT_TCOdds1, &ok, FALSE);\r
2716       odds2 = GetDlgItemInt(hDlg, OPT_TCOdds2, &ok2, FALSE);\r
2717       if (!ok || !ok2 || odds1 <= 0 || odds2 <= 0) {\r
2718           MessageBox(hDlg, "Invalid time-odds factor",\r
2719                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
2720           return FALSE;\r
2721       }\r
2722       searchTime = st;\r
2723       appData.timeControl = strdup(tc);\r
2724       appData.movesPerSession = mps;\r
2725       appData.timeIncrement = increment;\r
2726       appData.firstTimeOdds  = first.timeOdds  = odds1;\r
2727       appData.secondTimeOdds = second.timeOdds = odds2;\r
2728       Reset(TRUE, TRUE);\r
2729       EndDialog(hDlg, TRUE);\r
2730       return TRUE;\r
2731 \r
2732     case IDCANCEL:\r
2733       EndDialog(hDlg, FALSE);\r
2734       return TRUE;\r
2735 \r
2736     default:\r
2737       SetTimeControlEnables(hDlg);\r
2738       break;\r
2739     }\r
2740     break;\r
2741   }\r
2742   return FALSE;\r
2743 }\r
2744 \r
2745 VOID\r
2746 TimeControlOptionsPopup(HWND hwnd)\r
2747 {\r
2748   if (gameMode != BeginningOfGame) {\r
2749     DisplayError("Changing time control during a game is not implemented", 0);\r
2750   } else {\r
2751     FARPROC lpProc = MakeProcInstance((FARPROC)TimeControl, hInst);\r
2752     DialogBox(hInst, MAKEINTRESOURCE(DLG_TimeControl), hwnd, (DLGPROC) lpProc);\r
2753     FreeProcInstance(lpProc);\r
2754   }\r
2755 }\r
2756 \r
2757 /*---------------------------------------------------------------------------*\\r
2758  *\r
2759  * Engine Options Dialog functions\r
2760  *\r
2761 \*---------------------------------------------------------------------------*/\r
2762 #define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
2763 #define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
2764 \r
2765 #define INT_ABS( n )    ((n) >= 0 ? (n) : -(n))\r
2766 \r
2767 LRESULT CALLBACK EnginePlayOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2768 {\r
2769   switch (message) {\r
2770   case WM_INITDIALOG: /* message: initialize dialog box */\r
2771 \r
2772     /* Center the dialog over the application window */\r
2773     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2774 \r
2775     /* Initialize the dialog items */\r
2776     CHECK_BOX(IDC_EpPeriodicUpdates, appData.periodicUpdates);\r
2777     CHECK_BOX(IDC_EpPonder, appData.ponderNextMove);\r
2778     CHECK_BOX(IDC_EpShowThinking, appData.showThinking);\r
2779     CHECK_BOX(IDC_EpHideThinkingHuman, appData.hideThinkingFromHuman);\r
2780 \r
2781     CHECK_BOX(IDC_TestClaims, appData.testClaims);\r
2782     CHECK_BOX(IDC_DetectMates, appData.checkMates);\r
2783     CHECK_BOX(IDC_MaterialDraws, appData.materialDraws);\r
2784     CHECK_BOX(IDC_TrivialDraws, appData.trivialDraws);\r
2785 \r
2786     CHECK_BOX(IDC_ScoreAbs1, appData.firstScoreIsAbsolute);\r
2787     CHECK_BOX(IDC_ScoreAbs2, appData.secondScoreIsAbsolute);\r
2788 \r
2789     SetDlgItemInt( hDlg, IDC_EpDrawMoveCount, appData.adjudicateDrawMoves, TRUE );\r
2790     SendDlgItemMessage( hDlg, IDC_EpDrawMoveCount, EM_SETSEL, 0, -1 );\r
2791 \r
2792     SetDlgItemInt( hDlg, IDC_EpAdjudicationThreshold, INT_ABS(appData.adjudicateLossThreshold), TRUE );\r
2793     SendDlgItemMessage( hDlg, IDC_EpAdjudicationThreshold, EM_SETSEL, 0, -1 );\r
2794 \r
2795     SetDlgItemInt( hDlg, IDC_RuleMoves, appData.ruleMoves, TRUE );\r
2796     SendDlgItemMessage( hDlg, IDC_RuleMoves, EM_SETSEL, 0, -1 );\r
2797 \r
2798     SetDlgItemInt( hDlg, IDC_DrawRepeats, INT_ABS(appData.drawRepeats), TRUE );\r
2799     SendDlgItemMessage( hDlg, IDC_DrawRepeats, EM_SETSEL, 0, -1 );\r
2800 \r
2801     return TRUE;\r
2802 \r
2803   case WM_COMMAND: /* message: received a command */\r
2804     switch (LOWORD(wParam)) {\r
2805     case IDOK:\r
2806       /* Read changed options from the dialog box */\r
2807       PeriodicUpdatesEvent(          IS_CHECKED(IDC_EpPeriodicUpdates));\r
2808       PonderNextMoveEvent(           IS_CHECKED(IDC_EpPonder));\r
2809       appData.hideThinkingFromHuman= IS_CHECKED(IDC_EpHideThinkingHuman); // [HGM] thinking: moved up\r
2810       appData.showThinking   = IS_CHECKED(IDC_EpShowThinking);\r
2811       ShowThinkingEvent(); // [HGM] thinking: tests all options that need thinking output\r
2812       appData.testClaims    = IS_CHECKED(IDC_TestClaims);\r
2813       appData.checkMates    = IS_CHECKED(IDC_DetectMates);\r
2814       appData.materialDraws = IS_CHECKED(IDC_MaterialDraws);\r
2815       appData.trivialDraws  = IS_CHECKED(IDC_TrivialDraws);\r
2816 \r
2817       appData.adjudicateDrawMoves = GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, NULL, FALSE );\r
2818       appData.adjudicateLossThreshold = - (int) GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, NULL, FALSE );\r
2819       appData.ruleMoves = GetDlgItemInt(hDlg, IDC_RuleMoves, NULL, FALSE );\r
2820       appData.drawRepeats = (int) GetDlgItemInt(hDlg, IDC_DrawRepeats, NULL, FALSE );\r
2821 \r
2822       first.scoreIsAbsolute  = appData.firstScoreIsAbsolute  = IS_CHECKED(IDC_ScoreAbs1);\r
2823       second.scoreIsAbsolute = appData.secondScoreIsAbsolute = IS_CHECKED(IDC_ScoreAbs2);\r
2824 \r
2825       EndDialog(hDlg, TRUE);\r
2826       return TRUE;\r
2827 \r
2828     case IDCANCEL:\r
2829       EndDialog(hDlg, FALSE);\r
2830       return TRUE;\r
2831 \r
2832     case IDC_EpDrawMoveCount:\r
2833     case IDC_EpAdjudicationThreshold:\r
2834     case IDC_DrawRepeats:\r
2835     case IDC_RuleMoves:\r
2836         if( HIWORD(wParam) == EN_CHANGE ) {\r
2837             int n1_ok;\r
2838             int n2_ok;\r
2839             int n3_ok;\r
2840             int n4_ok;\r
2841 \r
2842             GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, &n1_ok, FALSE );\r
2843             GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, &n2_ok, FALSE );\r
2844             GetDlgItemInt(hDlg, IDC_RuleMoves, &n3_ok, FALSE );\r
2845             GetDlgItemInt(hDlg, IDC_DrawRepeats, &n4_ok, FALSE );\r
2846 \r
2847             EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok && n4_ok ? TRUE : FALSE );\r
2848         }\r
2849         return TRUE;\r
2850     }\r
2851     break;\r
2852   }\r
2853   return FALSE;\r
2854 }\r
2855 \r
2856 VOID EnginePlayOptionsPopup(HWND hwnd)\r
2857 {\r
2858   FARPROC lpProc;\r
2859 \r
2860   lpProc = MakeProcInstance((FARPROC)EnginePlayOptionsDialog, hInst);\r
2861   DialogBox(hInst, MAKEINTRESOURCE(DLG_EnginePlayOptions), hwnd, (DLGPROC) lpProc);\r
2862   FreeProcInstance(lpProc);\r
2863 }\r
2864 \r
2865 /*---------------------------------------------------------------------------*\\r
2866  *\r
2867  * UCI Options Dialog functions\r
2868  *\r
2869 \*---------------------------------------------------------------------------*/\r
2870 static BOOL BrowseForFolder( const char * title, char * path )\r
2871 {\r
2872     BOOL result = FALSE;\r
2873     BROWSEINFO bi;\r
2874     LPITEMIDLIST pidl;\r
2875 \r
2876     ZeroMemory( &bi, sizeof(bi) );\r
2877 \r
2878     bi.lpszTitle = title == 0 ? "Choose Folder" : title;\r
2879     bi.ulFlags = BIF_RETURNONLYFSDIRS;\r
2880 \r
2881     pidl = SHBrowseForFolder( &bi );\r
2882 \r
2883     if( pidl != 0 ) {\r
2884         IMalloc * imalloc = 0;\r
2885 \r
2886         if( SHGetPathFromIDList( pidl, path ) ) {\r
2887             result = TRUE;\r
2888         }\r
2889 \r
2890         if( SUCCEEDED( SHGetMalloc ( &imalloc ) ) ) {\r
2891             imalloc->lpVtbl->Free(imalloc,pidl);\r
2892             imalloc->lpVtbl->Release(imalloc);\r
2893         }\r
2894     }\r
2895 \r
2896     return result;\r
2897 }\r
2898 \r
2899 LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2900 {\r
2901   char buf[MAX_PATH];\r
2902   int oldCores;\r
2903 \r
2904   switch (message) {\r
2905   case WM_INITDIALOG: /* message: initialize dialog box */\r
2906 \r
2907     /* Center the dialog over the application window */\r
2908     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2909 \r
2910     /* Initialize the dialog items */\r
2911     SetDlgItemText( hDlg, IDC_PolyglotDir, appData.polyglotDir );\r
2912     SetDlgItemInt( hDlg, IDC_HashSize, appData.defaultHashSize, TRUE );\r
2913     SetDlgItemText( hDlg, IDC_PathToEGTB, appData.defaultPathEGTB );\r
2914     SetDlgItemInt( hDlg, IDC_SizeOfEGTB, appData.defaultCacheSizeEGTB, TRUE );\r
2915     CheckDlgButton( hDlg, IDC_UseBook, (BOOL) appData.usePolyglotBook );\r
2916     SetDlgItemText( hDlg, IDC_BookFile, appData.polyglotBook );\r
2917     // [HGM] smp: input field for nr of cores:\r
2918     SetDlgItemInt( hDlg, IDC_Cores, appData.smpCores, TRUE );\r
2919     // [HGM] book: tick boxes for own book use\r
2920     CheckDlgButton( hDlg, IDC_OwnBook1, (BOOL) appData.firstHasOwnBookUCI );\r
2921     CheckDlgButton( hDlg, IDC_OwnBook2, (BOOL) appData.secondHasOwnBookUCI );\r
2922 \r
2923     SendDlgItemMessage( hDlg, IDC_PolyglotDir, EM_SETSEL, 0, -1 );\r
2924 \r
2925     return TRUE;\r
2926 \r
2927   case WM_COMMAND: /* message: received a command */\r
2928     switch (LOWORD(wParam)) {\r
2929     case IDOK:\r
2930       GetDlgItemText( hDlg, IDC_PolyglotDir, buf, sizeof(buf) );\r
2931       appData.polyglotDir = strdup(buf);\r
2932       appData.defaultHashSize = GetDlgItemInt(hDlg, IDC_HashSize, NULL, FALSE );\r
2933       appData.defaultCacheSizeEGTB = GetDlgItemInt(hDlg, IDC_SizeOfEGTB, NULL, FALSE );\r
2934       GetDlgItemText( hDlg, IDC_PathToEGTB, buf, sizeof(buf) );\r
2935       appData.defaultPathEGTB = strdup(buf);\r
2936       GetDlgItemText( hDlg, IDC_BookFile, buf, sizeof(buf) );\r
2937       appData.polyglotBook = strdup(buf);\r
2938       appData.usePolyglotBook = (Boolean) IsDlgButtonChecked( hDlg, IDC_UseBook );\r
2939       // [HGM] smp: get nr of cores:\r
2940       oldCores = appData.smpCores;\r
2941       appData.smpCores = GetDlgItemInt(hDlg, IDC_Cores, NULL, FALSE );\r
2942       if(appData.smpCores != oldCores) NewSettingEvent(FALSE, "cores", appData.smpCores);\r
2943       // [HGM] book: read tick boxes for own book use\r
2944       appData.firstHasOwnBookUCI  = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook1 );\r
2945       appData.secondHasOwnBookUCI = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook2 );\r
2946 \r
2947       if(gameMode == BeginningOfGame) Reset(TRUE, TRUE);\r
2948       EndDialog(hDlg, TRUE);\r
2949       return TRUE;\r
2950 \r
2951     case IDCANCEL:\r
2952       EndDialog(hDlg, FALSE);\r
2953       return TRUE;\r
2954 \r
2955     case IDC_BrowseForBook:\r
2956       {\r
2957           char filter[] = { \r
2958               'A','l','l',' ','F','i','l','e','s', 0,\r
2959               '*','.','*', 0,\r
2960               'B','I','N',' ','F','i','l','e','s', 0,\r
2961               '*','.','b','i','n', 0,\r
2962               0 };\r
2963 \r
2964           OPENFILENAME ofn;\r
2965 \r
2966           strcpy( buf, "" );\r
2967 \r
2968           ZeroMemory( &ofn, sizeof(ofn) );\r
2969 \r
2970           ofn.lStructSize = sizeof(ofn);\r
2971           ofn.hwndOwner = hDlg;\r
2972           ofn.hInstance = hInst;\r
2973           ofn.lpstrFilter = filter;\r
2974           ofn.lpstrFile = buf;\r
2975           ofn.nMaxFile = sizeof(buf);\r
2976           ofn.lpstrTitle = "Choose Book";\r
2977           ofn.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_HIDEREADONLY;\r
2978 \r
2979           if( GetOpenFileName( &ofn ) ) {\r
2980               SetDlgItemText( hDlg, IDC_BookFile, buf );\r
2981           }\r
2982       }\r
2983       return TRUE;\r
2984 \r
2985     case IDC_BrowseForPolyglotDir:\r
2986       if( BrowseForFolder( "Choose Polyglot Directory", buf ) ) {\r
2987         SetDlgItemText( hDlg, IDC_PolyglotDir, buf );\r
2988 \r
2989         strcat( buf, "\\polyglot.exe" );\r
2990 \r
2991         if( GetFileAttributes(buf) == 0xFFFFFFFF ) {\r
2992             MessageBox( hDlg, "Polyglot was not found in the specified folder!", "Warning", MB_OK | MB_ICONWARNING );\r
2993         }\r
2994       }\r
2995       return TRUE;\r
2996 \r
2997     case IDC_BrowseForEGTB:\r
2998       if( BrowseForFolder( "Choose EGTB Directory:", buf ) ) {\r
2999         SetDlgItemText( hDlg, IDC_PathToEGTB, buf );\r
3000       }\r
3001       return TRUE;\r
3002 \r
3003     case IDC_HashSize:\r
3004     case IDC_SizeOfEGTB:\r
3005         if( HIWORD(wParam) == EN_CHANGE ) {\r
3006             int n1_ok;\r
3007             int n2_ok;\r
3008 \r
3009             GetDlgItemInt(hDlg, IDC_HashSize, &n1_ok, FALSE );\r
3010             GetDlgItemInt(hDlg, IDC_SizeOfEGTB, &n2_ok, FALSE );\r
3011 \r
3012             EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok ? TRUE : FALSE );\r
3013         }\r
3014         return TRUE;\r
3015     }\r
3016     break;\r
3017   }\r
3018   return FALSE;\r
3019 }\r
3020 \r
3021 VOID UciOptionsPopup(HWND hwnd)\r
3022 {\r
3023   FARPROC lpProc;\r
3024 \r
3025   lpProc = MakeProcInstance((FARPROC)UciOptionsDialog, hInst);\r
3026   DialogBox(hInst, MAKEINTRESOURCE(DLG_OptionsUCI), hwnd, (DLGPROC) lpProc);\r
3027   FreeProcInstance(lpProc);\r
3028 }\r