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