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