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