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