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