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