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