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