Implement Grand Chess
[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_VariantGrand,\r
823     OPT_VariantSpartan, // Spartan\r
824     -2 // sentinel\r
825 };\r
826 \r
827 VariantClass\r
828 VariantWhichRadio(HWND hDlg)\r
829 {\r
830   int i=0, j;\r
831   while((j = radioButton[i++]) != -2) {\r
832         if(j == -1) continue; // no menu button\r
833         if(IsDlgButtonChecked(hDlg, j) &&\r
834            (appData.noChessProgram || strstr(first.variants, VariantName(i-1)))) return (VariantClass) i-1;\r
835   }\r
836   return gameInfo.variant; // If no button checked, keep old\r
837 }\r
838 \r
839 void\r
840 VariantShowRadio(HWND hDlg)\r
841 {\r
842   int i=0, j;\r
843   CheckDlgButton(hDlg, radioButton[gameInfo.variant], TRUE);\r
844   while((j = radioButton[i++]) != -2) {\r
845         if(j == -1) continue; // no menu button\r
846         EnableWindow(GetDlgItem(hDlg, j), appData.noChessProgram || strstr(first.variants, VariantName(i-1)));\r
847   }\r
848 }\r
849 \r
850 LRESULT CALLBACK\r
851 NewVariantDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
852 {\r
853   static VariantClass v;\r
854   static int n1_ok, n2_ok, n3_ok;\r
855 \r
856   switch (message) {\r
857   case WM_INITDIALOG: /* message: initialize dialog box */\r
858     /* Center the dialog over the application window */\r
859     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
860     Translate(hDlg, DLG_NewVariant);\r
861 \r
862     /* Initialize the dialog items */\r
863     VariantShowRadio(hDlg);\r
864 \r
865     SetDlgItemInt( hDlg, IDC_Files, -1, TRUE );\r
866     SendDlgItemMessage( hDlg, IDC_Files, EM_SETSEL, 0, -1 );\r
867 \r
868     SetDlgItemInt( hDlg, IDC_Ranks, -1, TRUE );\r
869     SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );\r
870 \r
871     SetDlgItemInt( hDlg, IDC_Holdings, -1, TRUE );\r
872     SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );\r
873 \r
874     n1_ok = n2_ok = n3_ok = FALSE;\r
875 \r
876     return TRUE;\r
877 \r
878   case WM_COMMAND: /* message: received a command */\r
879     switch (LOWORD(wParam)) {\r
880     case IDOK:\r
881       /*\r
882        * if we call EndDialog() after the call to ChangeBoardSize(),\r
883        * then ChangeBoardSize() does not take effect, although the new\r
884        * boardSize is saved. Go figure...\r
885        */\r
886       EndDialog(hDlg, TRUE);\r
887 \r
888       v = VariantWhichRadio(hDlg);\r
889       if(!appData.noChessProgram) {\r
890         char *name = VariantName(v), buf[MSG_SIZ];\r
891         if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) {\r
892           /* [HGM] in protocol 2 we check if variant is suported by engine */\r
893           snprintf(buf, MSG_SIZ, _("Variant %s not supported by %s"), name, first.tidy);\r
894           DisplayError(buf, 0);\r
895           return TRUE; /* treat as _("Cancel") if first engine does not support it */\r
896         } else\r
897         if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) {\r
898           snprintf(buf, MSG_SIZ, _("Warning: second engine (%s) does not support this!"), second.tidy);\r
899           DisplayError(buf, 0);   /* use of second engine is optional; only warn user */\r
900         }\r
901       }\r
902 \r
903       gameInfo.variant = v;\r
904       appData.variant = VariantName(v);\r
905 \r
906       appData.NrFiles = (int) GetDlgItemInt(hDlg, IDC_Files, NULL, FALSE );\r
907       appData.NrRanks = (int) GetDlgItemInt(hDlg, IDC_Ranks, NULL, FALSE );\r
908       appData.holdingsSize = (int) GetDlgItemInt(hDlg, IDC_Holdings, NULL, FALSE );\r
909 \r
910       if(!n1_ok) appData.NrFiles = -1;\r
911       if(!n2_ok) appData.NrRanks = -1;\r
912       if(!n3_ok) appData.holdingsSize = -1;\r
913 \r
914       shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */\r
915       startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */\r
916       appData.pieceToCharTable = NULL;\r
917       Reset(TRUE, TRUE);\r
918 \r
919       return TRUE;\r
920 \r
921     case IDCANCEL:\r
922       EndDialog(hDlg, FALSE);\r
923       return TRUE;\r
924 \r
925     case IDC_Ranks:\r
926     case IDC_Files:\r
927     case IDC_Holdings:\r
928         if( HIWORD(wParam) == EN_CHANGE ) {\r
929 \r
930             GetDlgItemInt(hDlg, IDC_Files, &n1_ok, FALSE );\r
931             GetDlgItemInt(hDlg, IDC_Ranks, &n2_ok, FALSE );\r
932             GetDlgItemInt(hDlg, IDC_Holdings, &n3_ok, FALSE );\r
933 \r
934             /*EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok ? TRUE : FALSE );*/\r
935         }\r
936         return TRUE;\r
937     }\r
938     break;\r
939   }\r
940   return FALSE;\r
941 }\r
942 \r
943 \r
944 VOID\r
945 NewVariantPopup(HWND hwnd)\r
946 {\r
947   FARPROC lpProc = MakeProcInstance((FARPROC)NewVariantDialog, hInst);\r
948   DialogBox(hInst, MAKEINTRESOURCE(DLG_NewVariant), hwnd,\r
949           (DLGPROC) lpProc);\r
950   FreeProcInstance(lpProc);\r
951 }\r
952 \r
953 /*---------------------------------------------------------------------------*\\r
954  *\r
955  * ICS Options Dialog functions\r
956  *\r
957 \*---------------------------------------------------------------------------*/\r
958 \r
959 BOOL APIENTRY\r
960 MyCreateFont(HWND hwnd, MyFont *font)\r
961 {\r
962   CHOOSEFONT cf;\r
963   HFONT hf;\r
964 \r
965   /* Initialize members of the CHOOSEFONT structure. */\r
966   cf.lStructSize = sizeof(CHOOSEFONT);\r
967   cf.hwndOwner = hwnd;\r
968   cf.hDC = (HDC)NULL;\r
969   cf.lpLogFont = &font->lf;\r
970   cf.iPointSize = 0;\r
971   cf.Flags = CF_SCREENFONTS|/*CF_ANSIONLY|*/CF_INITTOLOGFONTSTRUCT;\r
972   cf.rgbColors = RGB(0,0,0);\r
973   cf.lCustData = 0L;\r
974   cf.lpfnHook = (LPCFHOOKPROC)NULL;\r
975   cf.lpTemplateName = (LPSTR)NULL;\r
976   cf.hInstance = (HINSTANCE) NULL;\r
977   cf.lpszStyle = (LPSTR)NULL;\r
978   cf.nFontType = SCREEN_FONTTYPE;\r
979   cf.nSizeMin = 0;\r
980   cf.nSizeMax = 0;\r
981 \r
982   /* Display the CHOOSEFONT common-dialog box. */\r
983   if (!ChooseFont(&cf)) {\r
984     return FALSE;\r
985   }\r
986 \r
987   /* Create a logical font based on the user's   */\r
988   /* selection and return a handle identifying   */\r
989   /* that font. */\r
990   hf = CreateFontIndirect(cf.lpLogFont);\r
991   if (hf == NULL) {\r
992     return FALSE;\r
993   }\r
994 \r
995   font->hf = hf;\r
996   font->mfp.pointSize = (float) (cf.iPointSize / 10.0);\r
997   font->mfp.bold = (font->lf.lfWeight >= FW_BOLD);\r
998   font->mfp.italic = font->lf.lfItalic;\r
999   font->mfp.underline = font->lf.lfUnderline;\r
1000   font->mfp.strikeout = font->lf.lfStrikeOut;\r
1001   font->mfp.charset = font->lf.lfCharSet;\r
1002   safeStrCpy(font->mfp.faceName, font->lf.lfFaceName, sizeof(font->mfp.faceName)/sizeof(font->mfp.faceName[0]) );\r
1003   return TRUE;\r
1004 }\r
1005 \r
1006 \r
1007 VOID\r
1008 UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca)\r
1009 {\r
1010   CHARFORMAT cf;\r
1011   cf.cbSize = sizeof(CHARFORMAT);\r
1012   cf.dwMask =\r
1013     CFM_COLOR|CFM_CHARSET|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE;\r
1014   cf.crTextColor = mca->color;\r
1015   cf.dwEffects = mca->effects;\r
1016   safeStrCpy(cf.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName, sizeof(cf.szFaceName)/sizeof(cf.szFaceName[0]) );\r
1017   /*\r
1018    * The 20.0 below is in fact documented. yHeight is expressed in twips.\r
1019    * A twip is 1/20 of a font's point size. See documentation of CHARFORMAT.\r
1020    * --msw\r
1021    */\r
1022   cf.yHeight = (int)(font[boardSize][CONSOLE_FONT]->mfp.pointSize * 20.0 + 0.5);\r
1023   cf.bCharSet = DEFAULT_CHARSET; /* should be ignored anyway */\r
1024   cf.bPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;\r
1025   SendDlgItemMessage(hDlg, id, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
1026 }\r
1027 \r
1028 LRESULT CALLBACK\r
1029 ColorizeTextDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1030 {\r
1031   static MyColorizeAttribs mca;\r
1032   static ColorClass cc;\r
1033   COLORREF background = (COLORREF)0;\r
1034 \r
1035   switch (message) {\r
1036   case WM_INITDIALOG:\r
1037     cc = (ColorClass)lParam;\r
1038     mca = colorizeAttribs[cc];\r
1039     /* Center the dialog over the application window */\r
1040     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
1041     Translate(hDlg, DLG_Colorize);\r
1042     /* Initialize the dialog items */\r
1043     CheckDlgButton(hDlg, OPT_Bold, (mca.effects & CFE_BOLD) != 0);\r
1044     CheckDlgButton(hDlg, OPT_Italic, (mca.effects & CFE_ITALIC) != 0);\r
1045     CheckDlgButton(hDlg, OPT_Underline, (mca.effects & CFE_UNDERLINE) != 0);\r
1046     CheckDlgButton(hDlg, OPT_Strikeout, (mca.effects & CFE_STRIKEOUT) != 0);\r
1047 \r
1048     /* get the current background color from the parent window */\r
1049     SendMessage(GetWindow(hDlg, GW_OWNER),WM_COMMAND,\r
1050                 (WPARAM)WM_USER_GetConsoleBackground,\r
1051                 (LPARAM)&background);\r
1052 \r
1053     /* set the background color */\r
1054     SendDlgItemMessage(hDlg, OPT_Sample, EM_SETBKGNDCOLOR, FALSE, background);\r
1055 \r
1056     SetDlgItemText(hDlg, OPT_Sample, T_(mca.name));\r
1057     UpdateSampleText(hDlg, OPT_Sample, &mca);\r
1058     return TRUE;\r
1059 \r
1060   case WM_COMMAND: /* message: received a command */\r
1061     switch (LOWORD(wParam)) {\r
1062     case IDOK:\r
1063       /* Read changed options from the dialog box */\r
1064       colorizeAttribs[cc] = mca;\r
1065       textAttribs[cc].color = mca.color;\r
1066       textAttribs[cc].effects = mca.effects;\r
1067       Colorize(currentColorClass, TRUE);\r
1068       if (cc == ColorNormal) {\r
1069         CHARFORMAT cf;\r
1070         cf.cbSize = sizeof(CHARFORMAT);\r
1071         cf.dwMask = CFM_COLOR;\r
1072         cf.crTextColor = mca.color;\r
1073         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput,\r
1074           EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
1075       }\r
1076       EndDialog(hDlg, TRUE);\r
1077       return TRUE;\r
1078 \r
1079     case IDCANCEL:\r
1080       EndDialog(hDlg, FALSE);\r
1081       return TRUE;\r
1082 \r
1083     case OPT_ChooseColor:\r
1084       ChangeColor(hDlg, &mca.color);\r
1085       UpdateSampleText(hDlg, OPT_Sample, &mca);\r
1086       return TRUE;\r
1087 \r
1088     default:\r
1089       mca.effects =\r
1090         (IsDlgButtonChecked(hDlg, OPT_Bold) ? CFE_BOLD : 0) |\r
1091         (IsDlgButtonChecked(hDlg, OPT_Italic) ? CFE_ITALIC : 0) |\r
1092         (IsDlgButtonChecked(hDlg, OPT_Underline) ? CFE_UNDERLINE : 0) |\r
1093         (IsDlgButtonChecked(hDlg, OPT_Strikeout) ? CFE_STRIKEOUT : 0);\r
1094       UpdateSampleText(hDlg, OPT_Sample, &mca);\r
1095       break;\r
1096     }\r
1097     break;\r
1098   }\r
1099   return FALSE;\r
1100 }\r
1101 \r
1102 VOID\r
1103 ColorizeTextPopup(HWND hwnd, ColorClass cc)\r
1104 {\r
1105   FARPROC lpProc;\r
1106 \r
1107   lpProc = MakeProcInstance((FARPROC)ColorizeTextDialog, hInst);\r
1108   DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_Colorize),\r
1109     hwnd, (DLGPROC)lpProc, (LPARAM) cc);\r
1110   FreeProcInstance(lpProc);\r
1111 }\r
1112 \r
1113 VOID\r
1114 SetIcsOptionEnables(HWND hDlg)\r
1115 {\r
1116 #define ENABLE_DLG_ITEM(x,y) EnableWindow(GetDlgItem(hDlg,(x)), (y))\r
1117 \r
1118   UINT state = IsDlgButtonChecked(hDlg, OPT_Premove);\r
1119   ENABLE_DLG_ITEM(OPT_PremoveWhite, state);\r
1120   ENABLE_DLG_ITEM(OPT_PremoveWhiteText, state);\r
1121   ENABLE_DLG_ITEM(OPT_PremoveBlack, state);\r
1122   ENABLE_DLG_ITEM(OPT_PremoveBlackText, state);\r
1123 \r
1124   ENABLE_DLG_ITEM(OPT_IcsAlarmTime, IsDlgButtonChecked(hDlg, OPT_IcsAlarm));\r
1125 \r
1126 #undef ENABLE_DLG_ITEM\r
1127 }\r
1128 \r
1129 \r
1130 LRESULT CALLBACK\r
1131 IcsOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1132 {\r
1133   char buf[MSG_SIZ];\r
1134   int number;\r
1135   int i;\r
1136   static COLORREF cbc;\r
1137   static MyColorizeAttribs *mca;\r
1138   COLORREF *colorref;\r
1139 \r
1140   switch (message) {\r
1141   case WM_INITDIALOG: /* message: initialize dialog box */\r
1142 \r
1143     mca = colorizeAttribs;\r
1144 \r
1145     for (i=0; i < NColorClasses - 1; i++) {\r
1146       mca[i].color   = textAttribs[i].color;\r
1147       mca[i].effects = textAttribs[i].effects;\r
1148     }\r
1149     cbc = consoleBackgroundColor;\r
1150 \r
1151     /* Center the dialog over the application window */\r
1152     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
1153     Translate(hDlg, DLG_IcsOptions);\r
1154 \r
1155     /* Initialize the dialog items */\r
1156 #define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
1157 \r
1158     CHECK_BOX(OPT_AutoKibitz, appData.autoKibitz);\r
1159     CHECK_BOX(OPT_AutoComment, appData.autoComment);\r
1160     CHECK_BOX(OPT_AutoObserve, appData.autoObserve);\r
1161     CHECK_BOX(OPT_GetMoveList, appData.getMoveList);\r
1162     CHECK_BOX(OPT_LocalLineEditing, appData.localLineEditing);\r
1163     CHECK_BOX(OPT_QuietPlay, appData.quietPlay);\r
1164     CHECK_BOX(OPT_SeekGraph, appData.seekGraph);\r
1165     CHECK_BOX(OPT_AutoRefresh, appData.autoRefresh);\r
1166     CHECK_BOX(OPT_BgObserve, appData.bgObserve);\r
1167     CHECK_BOX(OPT_DualBoard, appData.dualBoard);\r
1168     CHECK_BOX(OPT_SmartMove, appData.oneClick);\r
1169     CHECK_BOX(OPT_Premove, appData.premove);\r
1170     CHECK_BOX(OPT_PremoveWhite, appData.premoveWhite);\r
1171     CHECK_BOX(OPT_PremoveBlack, appData.premoveBlack);\r
1172     CHECK_BOX(OPT_IcsAlarm, appData.icsAlarm);\r
1173     CHECK_BOX(OPT_DontColorize, !appData.colorize);\r
1174 \r
1175 #undef CHECK_BOX\r
1176 \r
1177     snprintf(buf, MSG_SIZ, "%d", appData.icsAlarmTime / 1000);\r
1178     SetDlgItemText(hDlg, OPT_IcsAlarmTime, buf);\r
1179     SetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText);\r
1180     SetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText);\r
1181     SetDlgItemText(hDlg, OPT_StartupChatBoxes, appData.chatBoxes);\r
1182 \r
1183     SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
1184     SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
1185     SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
1186     SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
1187     SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
1188     SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
1189     SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
1190     SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
1191     SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
1192     SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
1193 \r
1194     SetDlgItemText(hDlg, OPT_SampleShout,     T_(mca[ColorShout].name));\r
1195     SetDlgItemText(hDlg, OPT_SampleSShout,    T_(mca[ColorSShout].name));\r
1196     SetDlgItemText(hDlg, OPT_SampleChannel1,  T_(mca[ColorChannel1].name));\r
1197     SetDlgItemText(hDlg, OPT_SampleChannel,   T_(mca[ColorChannel].name));\r
1198     SetDlgItemText(hDlg, OPT_SampleKibitz,    T_(mca[ColorKibitz].name));\r
1199     SetDlgItemText(hDlg, OPT_SampleTell,      T_(mca[ColorTell].name));\r
1200     SetDlgItemText(hDlg, OPT_SampleChallenge, T_(mca[ColorChallenge].name));\r
1201     SetDlgItemText(hDlg, OPT_SampleRequest,   T_(mca[ColorRequest].name));\r
1202     SetDlgItemText(hDlg, OPT_SampleSeek,      T_(mca[ColorSeek].name));\r
1203     SetDlgItemText(hDlg, OPT_SampleNormal,    T_(mca[ColorNormal].name));\r
1204 \r
1205     UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
1206     UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
1207     UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
1208     UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
1209     UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
1210     UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
1211     UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
1212     UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
1213     UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
1214     UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
1215 \r
1216     SetIcsOptionEnables(hDlg);\r
1217     return TRUE;\r
1218 \r
1219   case WM_COMMAND: /* message: received a command */\r
1220     switch (LOWORD(wParam)) {\r
1221 \r
1222     case WM_USER_GetConsoleBackground:\r
1223       /* the ColorizeTextDialog needs the current background color */\r
1224       colorref = (COLORREF *)lParam;\r
1225       *colorref = cbc;\r
1226       return FALSE;\r
1227 \r
1228     case IDOK:\r
1229       /* Read changed options from the dialog box */\r
1230       GetDlgItemText(hDlg, OPT_IcsAlarmTime, buf, MSG_SIZ);\r
1231       if (sscanf(buf, "%d", &number) != 1 || (number < 0)){\r
1232           MessageBox(hDlg, _("Invalid ICS Alarm Time"),\r
1233                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
1234           return FALSE;\r
1235       }\r
1236 \r
1237 #define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
1238 \r
1239       appData.icsAlarm         = IS_CHECKED(OPT_IcsAlarm);\r
1240       appData.premove          = IS_CHECKED(OPT_Premove);\r
1241       appData.premoveWhite     = IS_CHECKED(OPT_PremoveWhite);\r
1242       appData.premoveBlack     = IS_CHECKED(OPT_PremoveBlack);\r
1243       appData.autoKibitz       = IS_CHECKED(OPT_AutoKibitz);\r
1244       appData.autoComment      = IS_CHECKED(OPT_AutoComment);\r
1245       appData.autoObserve      = IS_CHECKED(OPT_AutoObserve);\r
1246       appData.getMoveList      = IS_CHECKED(OPT_GetMoveList);\r
1247       appData.localLineEditing = IS_CHECKED(OPT_LocalLineEditing);\r
1248       appData.quietPlay        = IS_CHECKED(OPT_QuietPlay);\r
1249       appData.seekGraph        = IS_CHECKED(OPT_SeekGraph);\r
1250       appData.autoRefresh      = IS_CHECKED(OPT_AutoRefresh);\r
1251       appData.bgObserve        = IS_CHECKED(OPT_BgObserve);\r
1252       appData.dualBoard        = IS_CHECKED(OPT_DualBoard);\r
1253       appData.oneClick         = IS_CHECKED(OPT_SmartMove);\r
1254 \r
1255 #undef IS_CHECKED\r
1256 \r
1257       appData.icsAlarmTime = number * 1000;\r
1258       GetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText, 5);\r
1259       GetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText, 5);\r
1260       GetDlgItemText(hDlg, OPT_StartupChatBoxes, buf, sizeof(buf));\r
1261       buf[sizeof(buf)-1] = NULLCHAR; appData.chatBoxes = StrSave(buf); // memory leak\r
1262 \r
1263       if (appData.localLineEditing) {\r
1264         DontEcho();\r
1265         EchoOn();\r
1266       } else {\r
1267         DoEcho();\r
1268         EchoOff();\r
1269       }\r
1270 \r
1271       appData.colorize =\r
1272         (Boolean)!IsDlgButtonChecked(hDlg, OPT_DontColorize);\r
1273 \r
1274     ChangedConsoleFont();\r
1275 \r
1276     if (!appData.colorize) {\r
1277         CHARFORMAT cf;\r
1278         COLORREF background = ParseColorName(COLOR_BKGD);\r
1279         /*\r
1280         SetDefaultTextAttribs();\r
1281         Colorize(currentColorClass);\r
1282         */\r
1283         cf.cbSize = sizeof(CHARFORMAT);\r
1284         cf.dwMask = CFM_COLOR;\r
1285         cf.crTextColor = ParseColorName(COLOR_NORMAL);\r
1286 \r
1287         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput,\r
1288           EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
1289         SendDlgItemMessage(hwndConsole, OPT_ConsoleText,\r
1290           EM_SETBKGNDCOLOR, FALSE, background);\r
1291         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput,\r
1292           EM_SETBKGNDCOLOR, FALSE, background);\r
1293       }\r
1294 \r
1295       if (cbc != consoleBackgroundColor) {\r
1296         consoleBackgroundColor = cbc;\r
1297         if (appData.colorize) {\r
1298           SendDlgItemMessage(hwndConsole, OPT_ConsoleText,\r
1299             EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
1300           SendDlgItemMessage(hwndConsole, OPT_ConsoleInput,\r
1301             EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
1302         }\r
1303       }\r
1304 \r
1305       for (i=0; i < NColorClasses - 1; i++) {\r
1306         textAttribs[i].color   = mca[i].color;\r
1307         textAttribs[i].effects = mca[i].effects;\r
1308       }\r
1309 \r
1310       EndDialog(hDlg, TRUE);\r
1311       return TRUE;\r
1312 \r
1313     case IDCANCEL:\r
1314       EndDialog(hDlg, FALSE);\r
1315       return TRUE;\r
1316 \r
1317     case OPT_ChooseShoutColor:\r
1318       ColorizeTextPopup(hDlg, ColorShout);\r
1319       UpdateSampleText(hDlg, OPT_SampleShout, &mca[ColorShout]);\r
1320       break;\r
1321 \r
1322     case OPT_ChooseSShoutColor:\r
1323       ColorizeTextPopup(hDlg, ColorSShout);\r
1324       UpdateSampleText(hDlg, OPT_SampleSShout, &mca[ColorSShout]);\r
1325       break;\r
1326 \r
1327     case OPT_ChooseChannel1Color:\r
1328       ColorizeTextPopup(hDlg, ColorChannel1);\r
1329       UpdateSampleText(hDlg, OPT_SampleChannel1,\r
1330                        &colorizeAttribs[ColorChannel1]);\r
1331       break;\r
1332 \r
1333     case OPT_ChooseChannelColor:\r
1334       ColorizeTextPopup(hDlg, ColorChannel);\r
1335       UpdateSampleText(hDlg, OPT_SampleChannel, &mca[ColorChannel]);\r
1336       break;\r
1337 \r
1338     case OPT_ChooseKibitzColor:\r
1339       ColorizeTextPopup(hDlg, ColorKibitz);\r
1340       UpdateSampleText(hDlg, OPT_SampleKibitz, &mca[ColorKibitz]);\r
1341       break;\r
1342 \r
1343     case OPT_ChooseTellColor:\r
1344       ColorizeTextPopup(hDlg, ColorTell);\r
1345       UpdateSampleText(hDlg, OPT_SampleTell, &mca[ColorTell]);\r
1346       break;\r
1347 \r
1348     case OPT_ChooseChallengeColor:\r
1349       ColorizeTextPopup(hDlg, ColorChallenge);\r
1350       UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
1351       break;\r
1352 \r
1353     case OPT_ChooseRequestColor:\r
1354       ColorizeTextPopup(hDlg, ColorRequest);\r
1355       UpdateSampleText(hDlg, OPT_SampleRequest, &mca[ColorRequest]);\r
1356       break;\r
1357 \r
1358     case OPT_ChooseSeekColor:\r
1359       ColorizeTextPopup(hDlg, ColorSeek);\r
1360       UpdateSampleText(hDlg, OPT_SampleSeek, &mca[ColorSeek]);\r
1361       break;\r
1362 \r
1363     case OPT_ChooseNormalColor:\r
1364       ColorizeTextPopup(hDlg, ColorNormal);\r
1365       UpdateSampleText(hDlg, OPT_SampleNormal, &mca[ColorNormal]);\r
1366       break;\r
1367 \r
1368     case OPT_ChooseBackgroundColor:\r
1369       if (ChangeColor(hDlg, &cbc)) {\r
1370         SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
1371         SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
1372         SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
1373         SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
1374         SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
1375         SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
1376         SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
1377         SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
1378         SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
1379         SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
1380       }\r
1381       break;\r
1382 \r
1383     case OPT_DefaultColors:\r
1384       for (i=0; i < NColorClasses - 1; i++)\r
1385         ParseAttribs(&mca[i].color,\r
1386                      &mca[i].effects,\r
1387                      defaultTextAttribs[i]);\r
1388 \r
1389       cbc = ParseColorName(COLOR_BKGD);\r
1390       SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
1391       SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
1392       SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
1393       SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
1394       SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
1395       SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
1396       SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
1397       SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
1398       SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
1399       SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
1400 \r
1401       UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
1402       UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
1403       UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
1404       UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
1405       UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
1406       UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
1407       UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
1408       UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
1409       UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
1410       UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
1411       break;\r
1412 \r
1413     default:\r
1414       SetIcsOptionEnables(hDlg);\r
1415       break;\r
1416     }\r
1417     break;\r
1418   }\r
1419   return FALSE;\r
1420 }\r
1421 \r
1422 VOID\r
1423 IcsOptionsPopup(HWND hwnd)\r
1424 {\r
1425   FARPROC lpProc = MakeProcInstance((FARPROC)IcsOptionsDialog, hInst);\r
1426   DialogBox(hInst, MAKEINTRESOURCE(DLG_IcsOptions), hwnd,\r
1427             (DLGPROC) lpProc);\r
1428   FreeProcInstance(lpProc);\r
1429 }\r
1430 \r
1431 /*---------------------------------------------------------------------------*\\r
1432  *\r
1433  * Fonts Dialog functions\r
1434  *\r
1435 \*---------------------------------------------------------------------------*/\r
1436 \r
1437 VOID\r
1438 SetSampleFontText(HWND hwnd, int id, const MyFont *mf)\r
1439 {\r
1440   char buf[MSG_SIZ];\r
1441   HWND hControl;\r
1442   HDC hdc;\r
1443   CHARFORMAT cf;\r
1444   SIZE size;\r
1445   RECT rectClient, rectFormat;\r
1446   HFONT oldFont;\r
1447   POINT center;\r
1448   int len;\r
1449 \r
1450   len = snprintf(buf, MSG_SIZ, "%.0f pt. %s%s%s\n",\r
1451                  mf->mfp.pointSize, mf->mfp.faceName,\r
1452                  mf->mfp.bold ? " bold" : "",\r
1453                  mf->mfp.italic ? " italic" : "");\r
1454   SetDlgItemText(hwnd, id, buf);\r
1455 \r
1456   hControl = GetDlgItem(hwnd, id);\r
1457   hdc = GetDC(hControl);\r
1458   SetMapMode(hdc, MM_TEXT);     /* 1 pixel == 1 logical unit */\r
1459   oldFont = SelectObject(hdc, mf->hf);\r
1460 \r
1461   /* get number of logical units necessary to display font name */\r
1462   GetTextExtentPoint32(hdc, buf, len, &size);\r
1463 \r
1464   /* calculate formatting rectangle in the rich edit control.\r
1465    * May be larger or smaller than the actual control.\r
1466    */\r
1467   GetClientRect(hControl, &rectClient);\r
1468   center.x = (rectClient.left + rectClient.right) / 2;\r
1469   center.y = (rectClient.top  + rectClient.bottom) / 2;\r
1470   rectFormat.top    = center.y - (size.cy / 2) - 1;\r
1471   rectFormat.bottom = center.y + (size.cy / 2) + 1;\r
1472   rectFormat.left   = center.x - (size.cx / 2) - 1;\r
1473   rectFormat.right  = center.x + (size.cx / 2) + 1;\r
1474 \r
1475   cf.cbSize = sizeof(CHARFORMAT);\r
1476   cf.dwMask = CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_BOLD|CFM_ITALIC;\r
1477   cf.dwEffects = 0;\r
1478   if (mf->lf.lfWeight == FW_BOLD) cf.dwEffects |= CFE_BOLD;\r
1479   if (mf->lf.lfItalic) cf.dwEffects |= CFE_ITALIC;\r
1480   safeStrCpy(cf.szFaceName, mf->mfp.faceName, sizeof(cf.szFaceName)/sizeof(cf.szFaceName[0]) );\r
1481   /*\r
1482    * yHeight is expressed in twips.  A twip is 1/20 of a font's point\r
1483    * size. See documentation of CHARFORMAT.  --msw\r
1484    */\r
1485   cf.yHeight = (int)(mf->mfp.pointSize * 20.0 + 0.5);\r
1486   cf.bCharSet = mf->lf.lfCharSet;\r
1487   cf.bPitchAndFamily = mf->lf.lfPitchAndFamily;\r
1488 \r
1489   /* format the text in the rich edit control */\r
1490   SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf);\r
1491   SendMessage(hControl, EM_SETRECT, (WPARAM)0, (LPARAM) &rectFormat);\r
1492 \r
1493   /* clean up */\r
1494   SelectObject(hdc, oldFont);\r
1495   ReleaseDC(hControl, hdc);\r
1496 }\r
1497 \r
1498 VOID\r
1499 CopyFont(MyFont *dest, const MyFont *src)\r
1500 {\r
1501   dest->mfp.pointSize = src->mfp.pointSize;\r
1502   dest->mfp.bold      = src->mfp.bold;\r
1503   dest->mfp.italic    = src->mfp.italic;\r
1504   dest->mfp.underline = src->mfp.underline;\r
1505   dest->mfp.strikeout = src->mfp.strikeout;\r
1506   dest->mfp.charset   = src->mfp.charset;\r
1507   safeStrCpy(dest->mfp.faceName, src->mfp.faceName, sizeof(dest->mfp.faceName)/sizeof(dest->mfp.faceName[0]) );\r
1508   CreateFontInMF(dest);\r
1509 }\r
1510 \r
1511 \r
1512 LRESULT CALLBACK\r
1513 FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1514 {\r
1515   static MyFont workFont[NUM_FONTS];\r
1516   static BOOL firstPaint;\r
1517   int i;\r
1518   RECT rect;\r
1519 \r
1520   switch (message) {\r
1521   case WM_INITDIALOG:\r
1522 \r
1523     /* copy the current font settings into a working copy */\r
1524     for (i=0; i < NUM_FONTS; i++)\r
1525       CopyFont(&workFont[i], font[boardSize][i]);\r
1526 \r
1527     Translate(hDlg, DLG_Fonts);\r
1528     if (!appData.icsActive)\r
1529       EnableWindow(GetDlgItem(hDlg, OPT_ChooseConsoleFont), FALSE);\r
1530 \r
1531     firstPaint = TRUE;  /* see rant below */\r
1532 \r
1533     /* If I don't call SetFocus(), the dialog won't respond to the keyboard\r
1534      * when first drawn. Why is this the only dialog that behaves this way? Is\r
1535      * is the WM_PAINT stuff below?? Sigh...\r
1536      */\r
1537     SetFocus(GetDlgItem(hDlg, IDOK));\r
1538     break;\r
1539 \r
1540   case WM_PAINT:\r
1541     /* This should not be necessary. However, if SetSampleFontText() is called\r
1542      * in response to WM_INITDIALOG, the strings are not properly centered in\r
1543      * the controls when the dialog first appears. I can't figure out why, so\r
1544      * this is the workaround.  --msw\r
1545      */\r
1546     if (firstPaint) {\r
1547       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1548       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1549       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1550       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1551       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1552       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1553       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1554       firstPaint = FALSE;\r
1555     }\r
1556     break;\r
1557 \r
1558   case WM_COMMAND: /* message: received a command */\r
1559     switch (LOWORD(wParam)) {\r
1560 \r
1561     case IDOK:\r
1562       /* again, it seems to avoid redraw problems if we call EndDialog first */\r
1563       EndDialog(hDlg, FALSE);\r
1564 \r
1565       /* copy modified settings back to the fonts array */\r
1566       for (i=0; i < NUM_FONTS; i++)\r
1567         CopyFont(font[boardSize][i], &workFont[i]);\r
1568 \r
1569       /* a sad necessity due to the original design of having a separate\r
1570        * console font, tags font, and comment font for each board size.  IMHO\r
1571        * these fonts should not be dependent on the current board size.  I'm\r
1572        * running out of time, so I am doing this hack rather than redesign the\r
1573        * data structure. Besides, I think if I redesigned the data structure, I\r
1574        * might break backwards compatibility with old winboard.ini files.\r
1575        * --msw\r
1576        */\r
1577       for (i=0; i < NUM_SIZES; i++) {\r
1578         CopyFont(font[i][EDITTAGS_FONT], &workFont[EDITTAGS_FONT]);\r
1579         CopyFont(font[i][CONSOLE_FONT],  &workFont[CONSOLE_FONT]);\r
1580         CopyFont(font[i][COMMENT_FONT],  &workFont[COMMENT_FONT]);\r
1581         CopyFont(font[i][MOVEHISTORY_FONT],  &workFont[MOVEHISTORY_FONT]);\r
1582       }\r
1583       /* end sad necessity */\r
1584 \r
1585       InitDrawingSizes(boardSize, 0);\r
1586       InvalidateRect(hwndMain, NULL, TRUE);\r
1587 \r
1588       if (commentDialog) {\r
1589         SendDlgItemMessage(commentDialog, OPT_CommentText,\r
1590           WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf,\r
1591           MAKELPARAM(TRUE, 0));\r
1592         GetClientRect(GetDlgItem(commentDialog, OPT_CommentText), &rect);\r
1593         InvalidateRect(commentDialog, &rect, TRUE);\r
1594       }\r
1595 \r
1596       if (editTagsDialog) {\r
1597         SendDlgItemMessage(editTagsDialog, OPT_TagsText,\r
1598           WM_SETFONT, (WPARAM)font[boardSize][EDITTAGS_FONT]->hf,\r
1599           MAKELPARAM(TRUE, 0));\r
1600         GetClientRect(GetDlgItem(editTagsDialog, OPT_TagsText), &rect);\r
1601         InvalidateRect(editTagsDialog, &rect, TRUE);\r
1602       }\r
1603 \r
1604       if( moveHistoryDialog != NULL ) {\r
1605         SendDlgItemMessage(moveHistoryDialog, IDC_MoveHistory,\r
1606           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf,\r
1607           MAKELPARAM(TRUE, 0));\r
1608         SendMessage( moveHistoryDialog, WM_INITDIALOG, 0, 0 );\r
1609 //      InvalidateRect(editTagsDialog, NULL, TRUE); // [HGM] this ws improperly cloned?\r
1610       }\r
1611 \r
1612       if( engineOutputDialog != NULL ) {\r
1613         SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo1,\r
1614           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf,\r
1615           MAKELPARAM(TRUE, 0));\r
1616         SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo2,\r
1617           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf,\r
1618           MAKELPARAM(TRUE, 0));\r
1619       }\r
1620 \r
1621       if (hwndConsole) {\r
1622         ChangedConsoleFont();\r
1623       }\r
1624 \r
1625       for (i=0; i<NUM_FONTS; i++)\r
1626         DeleteObject(&workFont[i].hf);\r
1627 \r
1628       return TRUE;\r
1629 \r
1630     case IDCANCEL:\r
1631       for (i=0; i<NUM_FONTS; i++)\r
1632         DeleteObject(&workFont[i].hf);\r
1633       EndDialog(hDlg, FALSE);\r
1634       return TRUE;\r
1635 \r
1636     case OPT_ChooseClockFont:\r
1637       MyCreateFont(hDlg, &workFont[CLOCK_FONT]);\r
1638       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1639       break;\r
1640 \r
1641     case OPT_ChooseMessageFont:\r
1642       MyCreateFont(hDlg, &workFont[MESSAGE_FONT]);\r
1643       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1644       break;\r
1645 \r
1646     case OPT_ChooseCoordFont:\r
1647       MyCreateFont(hDlg, &workFont[COORD_FONT]);\r
1648       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1649       break;\r
1650 \r
1651     case OPT_ChooseTagFont:\r
1652       MyCreateFont(hDlg, &workFont[EDITTAGS_FONT]);\r
1653       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1654       break;\r
1655 \r
1656     case OPT_ChooseCommentsFont:\r
1657       MyCreateFont(hDlg, &workFont[COMMENT_FONT]);\r
1658       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1659       break;\r
1660 \r
1661     case OPT_ChooseConsoleFont:\r
1662       MyCreateFont(hDlg, &workFont[CONSOLE_FONT]);\r
1663       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1664       break;\r
1665 \r
1666     case OPT_ChooseMoveHistoryFont:\r
1667       MyCreateFont(hDlg, &workFont[MOVEHISTORY_FONT]);\r
1668       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1669       break;\r
1670 \r
1671     case OPT_DefaultFonts:\r
1672       for (i=0; i<NUM_FONTS; i++) {\r
1673         DeleteObject(&workFont[i].hf);\r
1674         ParseFontName(font[boardSize][i]->def, &workFont[i].mfp);\r
1675         CreateFontInMF(&workFont[i]);\r
1676       }\r
1677       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1678       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1679       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1680       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1681       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1682       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1683       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1684       break;\r
1685     }\r
1686   }\r
1687   return FALSE;\r
1688 }\r
1689 \r
1690 VOID\r
1691 FontsOptionsPopup(HWND hwnd)\r
1692 {\r
1693   FARPROC lpProc = MakeProcInstance((FARPROC)FontOptionsDialog, hInst);\r
1694   DialogBox(hInst, MAKEINTRESOURCE(DLG_Fonts), hwnd,\r
1695           (DLGPROC) lpProc);\r
1696   FreeProcInstance(lpProc);\r
1697 }\r
1698 \r
1699 /*---------------------------------------------------------------------------*\\r
1700  *\r
1701  * Sounds Dialog functions\r
1702  *\r
1703 \*---------------------------------------------------------------------------*/\r
1704 \r
1705 \r
1706 SoundComboData soundComboData[] = {\r
1707   {N_("Move"), NULL},\r
1708   {N_("Bell"), NULL},\r
1709   {N_("ICS Alarm"), NULL},\r
1710   {N_("ICS Win"), NULL},\r
1711   {N_("ICS Loss"), NULL},\r
1712   {N_("ICS Draw"), NULL},\r
1713   {N_("ICS Unfinished"), NULL},\r
1714   {N_("Shout"), NULL},\r
1715   {N_("SShout/CShout"), NULL},\r
1716   {N_("Channel 1"), NULL},\r
1717   {N_("Channel"), NULL},\r
1718   {N_("Kibitz"), NULL},\r
1719   {N_("Tell"), NULL},\r
1720   {N_("Challenge"), NULL},\r
1721   {N_("Request"), NULL},\r
1722   {N_("Seek"), NULL},\r
1723   {NULL, NULL},\r
1724 };\r
1725 \r
1726 \r
1727 void\r
1728 InitSoundComboData(SoundComboData *scd)\r
1729 {\r
1730   SoundClass sc;\r
1731   ColorClass cc;\r
1732   int index;\r
1733 \r
1734   /* copy current sound settings to combo array */\r
1735 \r
1736   for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
1737     scd[sc].name = strdup(sounds[sc].name);\r
1738   }\r
1739   for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
1740     index = (int)cc + (int)NSoundClasses;\r
1741     scd[index].name = strdup(textAttribs[cc].sound.name);\r
1742   }\r
1743 }\r
1744 \r
1745 \r
1746 void\r
1747 ResetSoundComboData(SoundComboData *scd)\r
1748 {\r
1749   while (scd->label) {\r
1750     if (scd->name != NULL) {\r
1751       free (scd->name);\r
1752       scd->name = NULL;\r
1753     }\r
1754     scd++;\r
1755   }\r
1756 }\r
1757 \r
1758 void\r
1759 InitSoundCombo(HWND hwndCombo, SoundComboData *scd)\r
1760 {\r
1761   char buf[255];\r
1762   DWORD err;\r
1763   DWORD cnt = 0;\r
1764   SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
1765 \r
1766   /* send the labels to the combo box */\r
1767   while (scd->label) {\r
1768     err = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) T_(scd->label));\r
1769     if (err != cnt++) {\r
1770       snprintf(buf, MSG_SIZ,  "InitSoundCombo(): err '%d', cnt '%d'\n",\r
1771           (int)err, (int)cnt);\r
1772       MessageBox(NULL, buf, NULL, MB_OK);\r
1773     }\r
1774     scd++;\r
1775   }\r
1776   SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
1777 }\r
1778 \r
1779 int\r
1780 SoundDialogWhichRadio(HWND hDlg)\r
1781 {\r
1782   if (IsDlgButtonChecked(hDlg, OPT_NoSound)) return OPT_NoSound;\r
1783   if (IsDlgButtonChecked(hDlg, OPT_DefaultBeep)) return OPT_DefaultBeep;\r
1784   if (IsDlgButtonChecked(hDlg, OPT_BuiltInSound)) return OPT_BuiltInSound;\r
1785   if (IsDlgButtonChecked(hDlg, OPT_WavFile)) return OPT_WavFile;\r
1786   return -1;\r
1787 }\r
1788 \r
1789 VOID\r
1790 SoundDialogSetEnables(HWND hDlg, int radio)\r
1791 {\r
1792   EnableWindow(GetDlgItem(hDlg, OPT_BuiltInSoundName),\r
1793                radio == OPT_BuiltInSound);\r
1794   EnableWindow(GetDlgItem(hDlg, OPT_WavFileName), radio == OPT_WavFile);\r
1795   EnableWindow(GetDlgItem(hDlg, OPT_BrowseSound), radio == OPT_WavFile);\r
1796 }\r
1797 \r
1798 char *\r
1799 SoundDialogGetName(HWND hDlg, int radio)\r
1800 {\r
1801   static char buf[MSG_SIZ], buf2[MSG_SIZ], buf3[MSG_SIZ];\r
1802   char *dummy, *ret;\r
1803   switch (radio) {\r
1804   case OPT_NoSound:\r
1805   default:\r
1806     return "";\r
1807   case OPT_DefaultBeep:\r
1808     return "$";\r
1809   case OPT_BuiltInSound:\r
1810     buf[0] = '!';\r
1811     GetDlgItemText(hDlg, OPT_BuiltInSoundName, buf + 1, sizeof(buf) - 1);\r
1812     return buf;\r
1813   case OPT_WavFile:\r
1814     GetDlgItemText(hDlg, OPT_WavFileName, buf, sizeof(buf));\r
1815     GetCurrentDirectory(MSG_SIZ, buf3);\r
1816     SetCurrentDirectory(installDir);\r
1817     if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
1818       ret = buf2;\r
1819     } else {\r
1820       ret = buf;\r
1821     }\r
1822     SetCurrentDirectory(buf3);\r
1823     return ret;\r
1824   }\r
1825 }\r
1826 \r
1827 void\r
1828 DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name)\r
1829 {\r
1830   int radio;\r
1831   /*\r
1832    * I think it's best to clear the combo and edit boxes. It looks stupid\r
1833    * to have a value from another sound event sitting there grayed out.\r
1834    */\r
1835   SetDlgItemText(hDlg, OPT_WavFileName, "");\r
1836   SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
1837 \r
1838   if (appData.debugMode)\r
1839       fprintf(debugFP, "DisplaySelectedSound(,,'%s'):\n", name);\r
1840   switch (name[0]) {\r
1841   case NULLCHAR:\r
1842     radio = OPT_NoSound;\r
1843     break;\r
1844   case '$':\r
1845     if (name[1] == NULLCHAR) {\r
1846       radio = OPT_DefaultBeep;\r
1847     } else {\r
1848       radio = OPT_WavFile;\r
1849       SetDlgItemText(hDlg, OPT_WavFileName, name);\r
1850     }\r
1851     break;\r
1852   case '!':\r
1853     if (name[1] == NULLCHAR) {\r
1854       radio = OPT_NoSound;\r
1855     } else {\r
1856       radio = OPT_BuiltInSound;\r
1857       if (SendMessage(hCombo, CB_SELECTSTRING, (WPARAM) -1,\r
1858                       (LPARAM) (name + 1)) == CB_ERR) {\r
1859         SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
1860         SendMessage(hCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) (name + 1));\r
1861       }\r
1862     }\r
1863     break;\r
1864   default:\r
1865     radio = OPT_WavFile;\r
1866     SetDlgItemText(hDlg, OPT_WavFileName, name);\r
1867     break;\r
1868   }\r
1869   SoundDialogSetEnables(hDlg, radio);\r
1870   CheckRadioButton(hDlg, OPT_NoSound, OPT_WavFile, radio);\r
1871 }\r
1872 \r
1873 \r
1874 char *builtInSoundNames[] = BUILT_IN_SOUND_NAMES;\r
1875 \r
1876 LRESULT CALLBACK\r
1877 SoundOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1878 {\r
1879   static HWND hSoundCombo;\r
1880   static DWORD index;\r
1881   static HWND hBISN;\r
1882   int radio;\r
1883   MySound tmp;\r
1884   FILE *f;\r
1885   char buf[MSG_SIZ];\r
1886   char *newName;\r
1887   SoundClass sc;\r
1888   ColorClass cc;\r
1889   SoundComboData *scd;\r
1890   int oldMute;\r
1891 \r
1892   switch (message) {\r
1893   case WM_INITDIALOG:\r
1894     /* Center the dialog over the application window */\r
1895     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
1896     Translate(hDlg, DLG_Sound);\r
1897 \r
1898     /* Initialize the built-in sounds combo */\r
1899     hBISN = GetDlgItem(hDlg, OPT_BuiltInSoundName);\r
1900      InitComboStrings(hBISN, builtInSoundNames);\r
1901 \r
1902     /* Initialize the  sound events combo */\r
1903     index = 0;\r
1904     InitSoundComboData(soundComboData);\r
1905     hSoundCombo = GetDlgItem(hDlg, CBO_Sounds);\r
1906     InitSoundCombo(hSoundCombo, soundComboData);\r
1907 \r
1908     /* update the dialog */\r
1909     DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
1910     return TRUE;\r
1911 \r
1912   case WM_COMMAND: /* message: received a command */\r
1913 \r
1914     if (((HWND)lParam == hSoundCombo) &&\r
1915         (HIWORD(wParam) == CBN_SELCHANGE)) {\r
1916       /*\r
1917        * the user has selected a new sound event. We must store the name for\r
1918        * the previously selected event, then retrieve the name for the\r
1919        * newly selected event and update the dialog.\r
1920        */\r
1921       radio = SoundDialogWhichRadio(hDlg);\r
1922       newName = strdup(SoundDialogGetName(hDlg, radio));\r
1923 \r
1924       if (strcmp(newName, soundComboData[index].name) != 0) {\r
1925         free(soundComboData[index].name);\r
1926         soundComboData[index].name = newName;\r
1927       } else {\r
1928         free(newName);\r
1929         newName = NULL;\r
1930       }\r
1931       /* now get the settings for the newly selected event */\r
1932       index = SendMessage(hSoundCombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);\r
1933       DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
1934 \r
1935       return TRUE;\r
1936     }\r
1937     switch (LOWORD(wParam)) {\r
1938     case IDOK:\r
1939       /*\r
1940        * save the name for the currently selected sound event\r
1941        */\r
1942       radio = SoundDialogWhichRadio(hDlg);\r
1943       newName = strdup(SoundDialogGetName(hDlg, radio));\r
1944 \r
1945       if (strcmp(soundComboData[index].name, newName) != 0) {\r
1946         free(soundComboData[index].name);\r
1947         soundComboData[index].name = newName;\r
1948       } else {\r
1949         free(newName);\r
1950         newName = NULL;\r
1951       }\r
1952 \r
1953       /* save all the sound names that changed and load the sounds */\r
1954 \r
1955       for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
1956         if (strcmp(soundComboData[sc].name, sounds[sc].name) != 0) {\r
1957           free(sounds[sc].name);\r
1958           sounds[sc].name = strdup(soundComboData[sc].name);\r
1959           MyLoadSound(&sounds[sc]);\r
1960         }\r
1961       }\r
1962       for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
1963         index = (int)cc + (int)NSoundClasses;\r
1964         if (strcmp(soundComboData[index].name,\r
1965                    textAttribs[cc].sound.name) != 0) {\r
1966           free(textAttribs[cc].sound.name);\r
1967           textAttribs[cc].sound.name = strdup(soundComboData[index].name);\r
1968           MyLoadSound(&textAttribs[cc].sound);\r
1969         }\r
1970       }\r
1971 \r
1972         mute = FALSE; // [HGM] mute: switch sounds automatically on if we select one\r
1973       CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds,MF_BYCOMMAND|MF_UNCHECKED);\r
1974       ResetSoundComboData(soundComboData);\r
1975       EndDialog(hDlg, TRUE);\r
1976       return TRUE;\r
1977 \r
1978     case IDCANCEL:\r
1979       ResetSoundComboData(soundComboData);\r
1980       EndDialog(hDlg, FALSE);\r
1981       return TRUE;\r
1982 \r
1983     case OPT_DefaultSounds:\r
1984       /* can't use SetDefaultSounds() because we need to be able to "undo" if\r
1985        * user selects "Cancel" later on. So we do it the hard way here.\r
1986        */\r
1987       scd = &soundComboData[0];\r
1988       while (scd->label != NULL) {\r
1989         if (scd->name != NULL) free(scd->name);\r
1990         scd->name = strdup("");\r
1991         scd++;\r
1992       }\r
1993       free(soundComboData[(int)SoundBell].name);\r
1994       soundComboData[(int)SoundBell].name = strdup(SOUND_BELL);\r
1995       DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
1996       break;\r
1997 \r
1998     case OPT_PlaySound:\r
1999       radio = SoundDialogWhichRadio(hDlg);\r
2000       tmp.name = strdup(SoundDialogGetName(hDlg, radio));\r
2001       tmp.data = NULL;\r
2002       MyLoadSound(&tmp);\r
2003         oldMute = mute; mute = FALSE; // [HGM] mute: always sound when user presses play, ignorig mute setting\r
2004       MyPlaySound(&tmp);\r
2005         mute = oldMute;\r
2006       if (tmp.data  != NULL) FreeResource(tmp.data); // technically obsolete fn, but tmp.data is NOT malloc'd mem\r
2007       if (tmp.name != NULL) free(tmp.name);\r
2008       return TRUE;\r
2009 \r
2010     case OPT_BrowseSound:\r
2011       f = OpenFileDialog(hDlg, "rb", NULL, "wav", SOUND_FILT,\r
2012         _("Browse for Sound File"), NULL, NULL, buf);\r
2013       if (f != NULL) {\r
2014         fclose(f);\r
2015         SetDlgItemText(hDlg, OPT_WavFileName, buf);\r
2016       }\r
2017       return TRUE;\r
2018 \r
2019     default:\r
2020       radio = SoundDialogWhichRadio(hDlg);\r
2021       SoundDialogSetEnables(hDlg, radio);\r
2022       break;\r
2023     }\r
2024     break;\r
2025   }\r
2026   return FALSE;\r
2027 }\r
2028 \r
2029 \r
2030 VOID SoundOptionsPopup(HWND hwnd)\r
2031 {\r
2032   FARPROC lpProc;\r
2033 \r
2034   lpProc = MakeProcInstance((FARPROC)SoundOptionsDialog, hInst);\r
2035   DialogBox(hInst, MAKEINTRESOURCE(DLG_Sound), hwnd, (DLGPROC)lpProc);\r
2036   FreeProcInstance(lpProc);\r
2037 }\r
2038 \r
2039 \r
2040 /*---------------------------------------------------------------------------*\\r
2041  *\r
2042  * Comm Port dialog functions\r
2043  *\r
2044 \*---------------------------------------------------------------------------*/\r
2045 \r
2046 \r
2047 #define FLOW_NONE   0\r
2048 #define FLOW_XOFF   1\r
2049 #define FLOW_CTS    2\r
2050 #define FLOW_DSR    3\r
2051 \r
2052 #define PORT_NONE\r
2053 \r
2054 ComboData cdPort[]     = { {"None", PORT_NONE}, {"COM1", 1}, {"COM2", 2},\r
2055                            {"COM3", 3}, {"COM4", 4}, {NULL, 0} };\r
2056 ComboData cdDataRate[] = { {"110", 110}, {"300", 300}, {"600", 600}, {"1200", 1200},\r
2057                            {"2400", 2400}, {"4800", 4800}, {"9600", 9600}, {"19200", 19200},\r
2058                            {"38400", 38400}, {NULL, 0} };\r
2059 ComboData cdDataBits[] = { {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {NULL, 0} };\r
2060 ComboData cdParity[]   = { {"None", NOPARITY}, {"Odd", ODDPARITY}, {"Even", EVENPARITY},\r
2061                            {"Mark", MARKPARITY}, {"Space", SPACEPARITY}, {NULL, 0} };\r
2062 ComboData cdStopBits[] = { {"1", ONESTOPBIT}, {"1.5", ONE5STOPBITS},\r
2063                            {"2", TWOSTOPBITS}, {NULL, 0} };\r
2064 ComboData cdFlow[]     = { {"None", FLOW_NONE}, {"Xoff/Xon", FLOW_XOFF}, {"CTS", FLOW_CTS},\r
2065                            {"DSR", FLOW_DSR}, {NULL, 0} };\r
2066 \r
2067 \r
2068 VOID\r
2069 ParseCommSettings(char *arg, DCB *dcb)\r
2070 {\r
2071   int dataRate, count;\r
2072   char bits[MSG_SIZ], parity[MSG_SIZ], stopBits[MSG_SIZ], flow[MSG_SIZ];\r
2073   ComboData *cd;\r
2074   count = sscanf(arg, "%d%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]",\r
2075     &dataRate, bits, parity, stopBits, flow);\r
2076   if (count != 5) goto cant_parse;\r
2077   dcb->BaudRate = dataRate;\r
2078   cd = cdDataBits;\r
2079   while (cd->label != NULL) {\r
2080     if (StrCaseCmp(cd->label, bits) == 0) {\r
2081       dcb->ByteSize = cd->value;\r
2082       break;\r
2083     }\r
2084     cd++;\r
2085   }\r
2086   if (cd->label == NULL) goto cant_parse;\r
2087   cd = cdParity;\r
2088   while (cd->label != NULL) {\r
2089     if (StrCaseCmp(cd->label, parity) == 0) {\r
2090       dcb->Parity = cd->value;\r
2091       break;\r
2092     }\r
2093     cd++;\r
2094   }\r
2095   if (cd->label == NULL) goto cant_parse;\r
2096   cd = cdStopBits;\r
2097   while (cd->label != NULL) {\r
2098     if (StrCaseCmp(cd->label, stopBits) == 0) {\r
2099       dcb->StopBits = cd->value;\r
2100       break;\r
2101     }\r
2102     cd++;\r
2103   }\r
2104   cd = cdFlow;\r
2105   if (cd->label == NULL) goto cant_parse;\r
2106   while (cd->label != NULL) {\r
2107     if (StrCaseCmp(cd->label, flow) == 0) {\r
2108       switch (cd->value) {\r
2109       case FLOW_NONE:\r
2110         dcb->fOutX = FALSE;\r
2111         dcb->fOutxCtsFlow = FALSE;\r
2112         dcb->fOutxDsrFlow = FALSE;\r
2113         break;\r
2114       case FLOW_CTS:\r
2115         dcb->fOutX = FALSE;\r
2116         dcb->fOutxCtsFlow = TRUE;\r
2117         dcb->fOutxDsrFlow = FALSE;\r
2118         break;\r
2119       case FLOW_DSR:\r
2120         dcb->fOutX = FALSE;\r
2121         dcb->fOutxCtsFlow = FALSE;\r
2122         dcb->fOutxDsrFlow = TRUE;\r
2123         break;\r
2124       case FLOW_XOFF:\r
2125         dcb->fOutX = TRUE;\r
2126         dcb->fOutxCtsFlow = FALSE;\r
2127         dcb->fOutxDsrFlow = FALSE;\r
2128         break;\r
2129       }\r
2130       break;\r
2131     }\r
2132     cd++;\r
2133   }\r
2134   if (cd->label == NULL) goto cant_parse;\r
2135   return;\r
2136 cant_parse:\r
2137     ExitArgError(_("Can't parse com port settings"), arg, TRUE);\r
2138 }\r
2139 \r
2140 \r
2141 VOID PrintCommSettings(FILE *f, char *name, DCB *dcb)\r
2142 {\r
2143   char *flow = "??", *parity = "??", *stopBits = "??";\r
2144   ComboData *cd;\r
2145 \r
2146   cd = cdParity;\r
2147   while (cd->label != NULL) {\r
2148     if (dcb->Parity == cd->value) {\r
2149       parity = cd->label;\r
2150       break;\r
2151     }\r
2152     cd++;\r
2153   }\r
2154   cd = cdStopBits;\r
2155   while (cd->label != NULL) {\r
2156     if (dcb->StopBits == cd->value) {\r
2157       stopBits = cd->label;\r
2158       break;\r
2159     }\r
2160     cd++;\r
2161   }\r
2162   if (dcb->fOutX) {\r
2163     flow = cdFlow[FLOW_XOFF].label;\r
2164   } else if (dcb->fOutxCtsFlow) {\r
2165     flow = cdFlow[FLOW_CTS].label;\r
2166   } else if (dcb->fOutxDsrFlow) {\r
2167     flow = cdFlow[FLOW_DSR].label;\r
2168   } else {\r
2169     flow = cdFlow[FLOW_NONE].label;\r
2170   }\r
2171   fprintf(f, "/%s=%d,%d,%s,%s,%s\n", name,\r
2172     (int)dcb->BaudRate, dcb->ByteSize, parity, stopBits, flow);\r
2173 }\r
2174 \r
2175 \r
2176 void\r
2177 InitCombo(HANDLE hwndCombo, ComboData *cd)\r
2178 {\r
2179   SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
2180 \r
2181   while (cd->label != NULL) {\r
2182     SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) cd->label);\r
2183     cd++;\r
2184   }\r
2185 }\r
2186 \r
2187 void\r
2188 SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value)\r
2189 {\r
2190   int i;\r
2191 \r
2192   i = 0;\r
2193   while (cd->label != NULL) {\r
2194     if (cd->value == value) {\r
2195       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) i, (LPARAM) 0);\r
2196       return;\r
2197     }\r
2198     cd++;\r
2199     i++;\r
2200   }\r
2201 }\r
2202 \r
2203 LRESULT CALLBACK\r
2204 CommPortOptionsDialog(HWND hDlg, UINT message, WPARAM wParam,   LPARAM lParam)\r
2205 {\r
2206   char buf[MSG_SIZ];\r
2207   HANDLE hwndCombo;\r
2208   char *p;\r
2209   LRESULT index;\r
2210   unsigned value;\r
2211   int err;\r
2212 \r
2213   switch (message) {\r
2214   case WM_INITDIALOG: /* message: initialize dialog box */\r
2215     /* Center the dialog over the application window */\r
2216     CenterWindow (hDlg, GetWindow(hDlg, GW_OWNER));\r
2217     Translate(hDlg, DLG_CommPort);\r
2218     /* Initialize the dialog items */\r
2219     /* !! There should probably be some synchronization\r
2220        in accessing hCommPort and dcb.  Or does modal nature\r
2221        of this dialog box do it for us?\r
2222        */\r
2223     hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
2224     InitCombo(hwndCombo, cdPort);\r
2225     p = strrchr(appData.icsCommPort, '\\');\r
2226     if (p++ == NULL) p = appData.icsCommPort;\r
2227     if ((*p == '\0') ||\r
2228         (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) p) == CB_ERR)) {\r
2229       SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) "None");\r
2230     }\r
2231     EnableWindow(hwndCombo, hCommPort == NULL); /*!! don't allow change for now*/\r
2232 \r
2233     hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
2234     InitCombo(hwndCombo, cdDataRate);\r
2235     snprintf(buf, MSG_SIZ, "%u", (int)dcb.BaudRate);\r
2236     if (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) buf) == CB_ERR) {\r
2237       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
2238       SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);\r
2239     }\r
2240 \r
2241     hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
2242     InitCombo(hwndCombo, cdDataBits);\r
2243     SelectComboValue(hwndCombo, cdDataBits, dcb.ByteSize);\r
2244 \r
2245     hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
2246     InitCombo(hwndCombo, cdParity);\r
2247     SelectComboValue(hwndCombo, cdParity, dcb.Parity);\r
2248 \r
2249     hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
2250     InitCombo(hwndCombo, cdStopBits);\r
2251     SelectComboValue(hwndCombo, cdStopBits, dcb.StopBits);\r
2252 \r
2253     hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
2254     InitCombo(hwndCombo, cdFlow);\r
2255     if (dcb.fOutX) {\r
2256       SelectComboValue(hwndCombo, cdFlow, FLOW_XOFF);\r
2257     } else if (dcb.fOutxCtsFlow) {\r
2258       SelectComboValue(hwndCombo, cdFlow, FLOW_CTS);\r
2259     } else if (dcb.fOutxDsrFlow) {\r
2260       SelectComboValue(hwndCombo, cdFlow, FLOW_DSR);\r
2261     } else {\r
2262       SelectComboValue(hwndCombo, cdFlow, FLOW_NONE);\r
2263     }\r
2264     return TRUE;\r
2265 \r
2266   case WM_COMMAND: /* message: received a command */\r
2267     switch (LOWORD(wParam)) {\r
2268     case IDOK:\r
2269       /* Read changed options from the dialog box */\r
2270 #ifdef NOTDEF\r
2271       /* !! Currently we can't change comm ports in midstream */\r
2272       hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
2273       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2274       if (index == PORT_NONE) {\r
2275         appData.icsCommPort = "";\r
2276         if (hCommPort != NULL) {\r
2277           CloseHandle(hCommPort);\r
2278           hCommPort = NULL;\r
2279         }\r
2280         EndDialog(hDlg, TRUE);\r
2281         return TRUE;\r
2282       }\r
2283       SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
2284       appData.icsCommPort = strdup(buf);\r
2285       if (hCommPort != NULL) {\r
2286         CloseHandle(hCommPort);\r
2287         hCommPort = NULL;\r
2288       }\r
2289       /* now what?? can't really do this; have to fix up the ChildProc\r
2290          and InputSource records for the comm port that we gave to the\r
2291          back end. */\r
2292 #endif /*NOTDEF*/\r
2293 \r
2294       hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
2295       SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
2296       if (sscanf(buf, "%u", &value) != 1) {\r
2297         MessageBox(hDlg, _("Invalid data rate"),\r
2298                    _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2299         return TRUE;\r
2300       }\r
2301       dcb.BaudRate = value;\r
2302 \r
2303       hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
2304       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2305       dcb.ByteSize = cdDataBits[index].value;\r
2306 \r
2307       hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
2308       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2309       dcb.Parity = cdParity[index].value;\r
2310 \r
2311       hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
2312       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2313       dcb.StopBits = cdStopBits[index].value;\r
2314 \r
2315       hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
2316       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2317       switch (cdFlow[index].value) {\r
2318       case FLOW_NONE:\r
2319         dcb.fOutX = FALSE;\r
2320         dcb.fOutxCtsFlow = FALSE;\r
2321         dcb.fOutxDsrFlow = FALSE;\r
2322         break;\r
2323       case FLOW_CTS:\r
2324         dcb.fOutX = FALSE;\r
2325         dcb.fOutxCtsFlow = TRUE;\r
2326         dcb.fOutxDsrFlow = FALSE;\r
2327         break;\r
2328       case FLOW_DSR:\r
2329         dcb.fOutX = FALSE;\r
2330         dcb.fOutxCtsFlow = FALSE;\r
2331         dcb.fOutxDsrFlow = TRUE;\r
2332         break;\r
2333       case FLOW_XOFF:\r
2334         dcb.fOutX = TRUE;\r
2335         dcb.fOutxCtsFlow = FALSE;\r
2336         dcb.fOutxDsrFlow = FALSE;\r
2337         break;\r
2338       }\r
2339       if (!SetCommState(hCommPort, (LPDCB) &dcb)) {\r
2340         err = GetLastError();\r
2341         switch(MessageBox(hDlg,\r
2342                          "Failed to set comm port state;\r\ninvalid options?",\r
2343                          _("Option Error"), MB_ABORTRETRYIGNORE|MB_ICONQUESTION)) {\r
2344         case IDABORT:\r
2345           DisplayFatalError(_("Failed to set comm port state"), err, 1);\r
2346           exit(1);  /*is it ok to do this from here?*/\r
2347 \r
2348         case IDRETRY:\r
2349           return TRUE;\r
2350 \r
2351         case IDIGNORE:\r
2352           EndDialog(hDlg, TRUE);\r
2353           return TRUE;\r
2354         }\r
2355       }\r
2356 \r
2357       EndDialog(hDlg, TRUE);\r
2358       return TRUE;\r
2359 \r
2360     case IDCANCEL:\r
2361       EndDialog(hDlg, FALSE);\r
2362       return TRUE;\r
2363 \r
2364     default:\r
2365       break;\r
2366     }\r
2367     break;\r
2368   }\r
2369   return FALSE;\r
2370 }\r
2371 \r
2372 VOID\r
2373 CommPortOptionsPopup(HWND hwnd)\r
2374 {\r
2375   FARPROC lpProc = MakeProcInstance((FARPROC)CommPortOptionsDialog, hInst);\r
2376   DialogBox(hInst, MAKEINTRESOURCE(DLG_CommPort), hwnd, (DLGPROC) lpProc);\r
2377   FreeProcInstance(lpProc);\r
2378 }\r
2379 \r
2380 /*---------------------------------------------------------------------------*\\r
2381  *\r
2382  * Load Options dialog functions\r
2383  *\r
2384 \*---------------------------------------------------------------------------*/\r
2385 \r
2386 VOID\r
2387 SetLoadOptionEnables(HWND hDlg)\r
2388 {\r
2389   UINT state;\r
2390 \r
2391   state = IsDlgButtonChecked(hDlg, OPT_Autostep);\r
2392   EnableWindow(GetDlgItem(hDlg, OPT_ASTimeDelay), state);\r
2393   EnableWindow(GetDlgItem(hDlg, OPT_AStext1), state);\r
2394 }\r
2395 \r
2396 LRESULT CALLBACK\r
2397 LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2398 {\r
2399   char buf[MSG_SIZ];\r
2400   float fnumber;\r
2401 \r
2402   switch (message) {\r
2403   case WM_INITDIALOG: /* message: initialize dialog box */\r
2404     /* Center the dialog over the application window */\r
2405     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2406     Translate(hDlg, DLG_LoadOptions);\r
2407     /* Initialize the dialog items */\r
2408     if (appData.timeDelay >= 0.0) {\r
2409       CheckDlgButton(hDlg, OPT_Autostep, TRUE);\r
2410       snprintf(buf, MSG_SIZ, "%.2g", appData.timeDelay);\r
2411       SetDlgItemText(hDlg, OPT_ASTimeDelay, buf);\r
2412     } else {\r
2413       CheckDlgButton(hDlg, OPT_Autostep, FALSE);\r
2414     }\r
2415     SetLoadOptionEnables(hDlg);\r
2416     return TRUE;\r
2417 \r
2418   case WM_COMMAND: /* message: received a command */\r
2419     switch (LOWORD(wParam)) {\r
2420     case IDOK:\r
2421       /* Read changed options from the dialog box */\r
2422       if (IsDlgButtonChecked(hDlg, OPT_Autostep)) {\r
2423         GetDlgItemText(hDlg, OPT_ASTimeDelay, buf, MSG_SIZ);\r
2424         if (sscanf(buf, "%f", &fnumber) != 1) {\r
2425           MessageBox(hDlg, _("Invalid load game step rate"),\r
2426                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2427           return FALSE;\r
2428         }\r
2429         appData.timeDelay = fnumber;\r
2430       } else {\r
2431         appData.timeDelay = (float) -1.0;\r
2432       }\r
2433       EndDialog(hDlg, TRUE);\r
2434       return TRUE;\r
2435 \r
2436     case IDCANCEL:\r
2437       EndDialog(hDlg, FALSE);\r
2438       return TRUE;\r
2439 \r
2440     default:\r
2441       SetLoadOptionEnables(hDlg);\r
2442       break;\r
2443     }\r
2444     break;\r
2445   }\r
2446   return FALSE;\r
2447 }\r
2448 \r
2449 \r
2450 VOID\r
2451 LoadOptionsPopup(HWND hwnd)\r
2452 {\r
2453   FARPROC lpProc = MakeProcInstance((FARPROC)LoadOptions, hInst);\r
2454   DialogBox(hInst, MAKEINTRESOURCE(DLG_LoadOptions), hwnd, (DLGPROC) lpProc);\r
2455   FreeProcInstance(lpProc);\r
2456 }\r
2457 \r
2458 /*---------------------------------------------------------------------------*\\r
2459  *\r
2460  * Save Options dialog functions\r
2461  *\r
2462 \*---------------------------------------------------------------------------*/\r
2463 \r
2464 VOID\r
2465 SetSaveOptionEnables(HWND hDlg)\r
2466 {\r
2467   UINT state;\r
2468 \r
2469   state = IsDlgButtonChecked(hDlg, OPT_Autosave);\r
2470   EnableWindow(GetDlgItem(hDlg, OPT_AVPrompt), state);\r
2471   EnableWindow(GetDlgItem(hDlg, OPT_AVToFile), state);\r
2472   if (state && !IsDlgButtonChecked(hDlg, OPT_AVPrompt) &&\r
2473       !IsDlgButtonChecked(hDlg, OPT_AVToFile)) {\r
2474     CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
2475   }\r
2476 \r
2477   state = state && IsDlgButtonChecked(hDlg, OPT_AVToFile);\r
2478   EnableWindow(GetDlgItem(hDlg, OPT_AVFilename), state);\r
2479   EnableWindow(GetDlgItem(hDlg, OPT_AVBrowse), state);\r
2480 }\r
2481 \r
2482 LRESULT CALLBACK\r
2483 SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2484 {\r
2485   char buf[MSG_SIZ];\r
2486   FILE *f;\r
2487 \r
2488   switch (message) {\r
2489   case WM_INITDIALOG: /* message: initialize dialog box */\r
2490     /* Center the dialog over the application window */\r
2491     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2492     Translate(hDlg, DLG_SaveOptions);\r
2493     /* Initialize the dialog items */\r
2494     if (*appData.saveGameFile != NULLCHAR) {\r
2495       CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
2496       CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVToFile);\r
2497       SetDlgItemText(hDlg, OPT_AVFilename, appData.saveGameFile);\r
2498     } else if (appData.autoSaveGames) {\r
2499       CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
2500       CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
2501     } else {\r
2502       CheckDlgButton(hDlg, OPT_Autosave, (UINT) FALSE);\r
2503     }\r
2504     if (appData.oldSaveStyle) {\r
2505       CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_Old);\r
2506     } else {\r
2507       CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_PGN);\r
2508     }\r
2509     CheckDlgButton( hDlg, OPT_OutOfBookInfo, appData.saveOutOfBookInfo );\r
2510     SetSaveOptionEnables(hDlg);\r
2511     return TRUE;\r
2512 \r
2513   case WM_COMMAND: /* message: received a command */\r
2514     switch (LOWORD(wParam)) {\r
2515     case IDOK:\r
2516       /* Read changed options from the dialog box */\r
2517       if (IsDlgButtonChecked(hDlg, OPT_Autosave)) {\r
2518         appData.autoSaveGames = TRUE;\r
2519         if (IsDlgButtonChecked(hDlg, OPT_AVPrompt)) {\r
2520           ASSIGN(appData.saveGameFile, ""); // [HGM] make sure value is ALWAYS in allocated memory\r
2521         } else /*if (IsDlgButtonChecked(hDlg, OPT_AVToFile))*/ {\r
2522           GetDlgItemText(hDlg, OPT_AVFilename, buf, MSG_SIZ);\r
2523           if (*buf == NULLCHAR) {\r
2524             MessageBox(hDlg, _("Invalid save game file name"),\r
2525                        _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2526             return FALSE;\r
2527           }\r
2528           FREE(appData.saveGameFile);\r
2529           appData.saveGameFile = InterpretFileName(buf, homeDir);\r
2530         }\r
2531       } else {\r
2532         appData.autoSaveGames = FALSE;\r
2533         ASSIGN(appData.saveGameFile, "");\r
2534       }\r
2535       appData.oldSaveStyle = IsDlgButtonChecked(hDlg, OPT_Old);\r
2536       appData.saveOutOfBookInfo = IsDlgButtonChecked( hDlg, OPT_OutOfBookInfo );\r
2537       EndDialog(hDlg, TRUE);\r
2538       return TRUE;\r
2539 \r
2540     case IDCANCEL:\r
2541       EndDialog(hDlg, FALSE);\r
2542       return TRUE;\r
2543 \r
2544     case OPT_AVBrowse:\r
2545       f = OpenFileDialog(hDlg, "a", NULL,\r
2546                          appData.oldSaveStyle ? "gam" : "pgn",\r
2547                          GAME_FILT, _("Browse for Auto Save File"),\r
2548                          NULL, NULL, buf);\r
2549       if (f != NULL) {\r
2550         fclose(f);\r
2551         SetDlgItemText(hDlg, OPT_AVFilename, buf);\r
2552       }\r
2553       break;\r
2554 \r
2555     default:\r
2556       SetSaveOptionEnables(hDlg);\r
2557       break;\r
2558     }\r
2559     break;\r
2560   }\r
2561   return FALSE;\r
2562 }\r
2563 \r
2564 VOID\r
2565 SaveOptionsPopup(HWND hwnd)\r
2566 {\r
2567   FARPROC lpProc = MakeProcInstance((FARPROC)SaveOptionsDialog, hInst);\r
2568   DialogBox(hInst, MAKEINTRESOURCE(DLG_SaveOptions), hwnd, (DLGPROC) lpProc);\r
2569   FreeProcInstance(lpProc);\r
2570 }\r
2571 \r
2572 /*---------------------------------------------------------------------------*\\r
2573  *\r
2574  * Time Control Options dialog functions\r
2575  *\r
2576 \*---------------------------------------------------------------------------*/\r
2577 \r
2578 VOID\r
2579 SetTimeControlEnables(HWND hDlg)\r
2580 {\r
2581   UINT state;\r
2582 \r
2583   state = IsDlgButtonChecked(hDlg, OPT_TCUseMoves)\r
2584         + 2*IsDlgButtonChecked(hDlg, OPT_TCUseFixed);\r
2585   EnableWindow(GetDlgItem(hDlg, OPT_TCTime), state == 1);\r
2586   EnableWindow(GetDlgItem(hDlg, OPT_TCMoves), state == 1);\r
2587   EnableWindow(GetDlgItem(hDlg, OPT_TCtext1), state == 1);\r
2588   EnableWindow(GetDlgItem(hDlg, OPT_TCtext2), state == 1);\r
2589   EnableWindow(GetDlgItem(hDlg, OPT_TCTime2), !state);\r
2590   EnableWindow(GetDlgItem(hDlg, OPT_TCInc), !state);\r
2591   EnableWindow(GetDlgItem(hDlg, OPT_TCitext1), !state);\r
2592   EnableWindow(GetDlgItem(hDlg, OPT_TCitext2), !state);\r
2593   EnableWindow(GetDlgItem(hDlg, OPT_TCitext3), !state);\r
2594   EnableWindow(GetDlgItem(hDlg, OPT_TCFixed), state == 2);\r
2595   EnableWindow(GetDlgItem(hDlg, OPT_TCftext), state == 2);\r
2596 }\r
2597 \r
2598 \r
2599 LRESULT CALLBACK\r
2600 TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2601 {\r
2602   char buf[MSG_SIZ], *tc;\r
2603   int mps, increment, odds1, odds2, st;\r
2604   BOOL ok, ok2;\r
2605 \r
2606   switch (message) {\r
2607   case WM_INITDIALOG: /* message: initialize dialog box */\r
2608     /* Center the dialog over the application window */\r
2609     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2610     Translate(hDlg, DLG_TimeControl);\r
2611     /* Initialize the dialog items */\r
2612     if (appData.clockMode && !appData.icsActive) {\r
2613       if (searchTime) {\r
2614         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2615                          OPT_TCUseFixed);\r
2616         SetDlgItemInt(hDlg, OPT_TCFixed, searchTime, FALSE);\r
2617       } else\r
2618       if (appData.timeIncrement == -1) {\r
2619         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2620                          OPT_TCUseMoves);\r
2621         SetDlgItemText(hDlg, OPT_TCTime, appData.timeControl);\r
2622         SetDlgItemInt(hDlg, OPT_TCMoves, appData.movesPerSession,\r
2623                       FALSE);\r
2624         SetDlgItemText(hDlg, OPT_TCTime2, "");\r
2625         SetDlgItemText(hDlg, OPT_TCInc, "");\r
2626       } else {\r
2627         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2628                          OPT_TCUseInc);\r
2629         SetDlgItemText(hDlg, OPT_TCTime, "");\r
2630         SetDlgItemText(hDlg, OPT_TCMoves, "");\r
2631         SetDlgItemText(hDlg, OPT_TCTime2, appData.timeControl);\r
2632         SetDlgItemInt(hDlg, OPT_TCInc, appData.timeIncrement, FALSE);\r
2633       }\r
2634       SetDlgItemInt(hDlg, OPT_TCOdds1, 1, FALSE);\r
2635       SetDlgItemInt(hDlg, OPT_TCOdds2, 1, FALSE);\r
2636       SetTimeControlEnables(hDlg);\r
2637     }\r
2638     return TRUE;\r
2639 \r
2640   case WM_COMMAND: /* message: received a command */\r
2641     switch (LOWORD(wParam)) {\r
2642     case IDOK:\r
2643       mps = appData.movesPerSession;\r
2644       increment = appData.timeIncrement;\r
2645       tc = appData.timeControl;\r
2646       st = 0;\r
2647       /* Read changed options from the dialog box */\r
2648       if (IsDlgButtonChecked(hDlg, OPT_TCUseFixed)) {\r
2649         st = GetDlgItemInt(hDlg, OPT_TCFixed, &ok, FALSE);\r
2650         if (!ok || st <= 0) {\r
2651           MessageBox(hDlg, _("Invalid max time per move"),\r
2652                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2653           return FALSE;\r
2654         }\r
2655       } else\r
2656       if (IsDlgButtonChecked(hDlg, OPT_TCUseMoves)) {\r
2657         increment = -1;\r
2658         mps = GetDlgItemInt(hDlg, OPT_TCMoves, &ok, FALSE);\r
2659         if (!ok || mps <= 0) {\r
2660           MessageBox(hDlg, _("Invalid moves per time control"),\r
2661                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2662           return FALSE;\r
2663         }\r
2664         GetDlgItemText(hDlg, OPT_TCTime, buf, MSG_SIZ);\r
2665         if (!ParseTimeControl(buf, increment, mps)) {\r
2666           MessageBox(hDlg, _("Invalid minutes per time control"),\r
2667                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2668           return FALSE;\r
2669         }\r
2670       tc = buf;\r
2671       } else {\r
2672         increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE);\r
2673         if (!ok || increment < 0) {\r
2674           MessageBox(hDlg, _("Invalid increment"),\r
2675                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2676           return FALSE;\r
2677         }\r
2678         GetDlgItemText(hDlg, OPT_TCTime2, buf, MSG_SIZ);\r
2679         if (!ParseTimeControl(buf, increment, mps)) {\r
2680           MessageBox(hDlg, _("Invalid initial time"),\r
2681                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2682           return FALSE;\r
2683         }\r
2684       tc = buf;\r
2685       }\r
2686       odds1 = GetDlgItemInt(hDlg, OPT_TCOdds1, &ok, FALSE);\r
2687       odds2 = GetDlgItemInt(hDlg, OPT_TCOdds2, &ok2, FALSE);\r
2688       if (!ok || !ok2 || odds1 <= 0 || odds2 <= 0) {\r
2689           MessageBox(hDlg, _("Invalid time-odds factor"),\r
2690                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2691           return FALSE;\r
2692       }\r
2693       searchTime = st;\r
2694       appData.timeControl = strdup(tc);\r
2695       appData.movesPerSession = mps;\r
2696       appData.timeIncrement = increment;\r
2697       appData.firstTimeOdds  = first.timeOdds  = odds1;\r
2698       appData.secondTimeOdds = second.timeOdds = odds2;\r
2699       Reset(TRUE, TRUE);\r
2700       EndDialog(hDlg, TRUE);\r
2701       return TRUE;\r
2702 \r
2703     case IDCANCEL:\r
2704       EndDialog(hDlg, FALSE);\r
2705       return TRUE;\r
2706 \r
2707     default:\r
2708       SetTimeControlEnables(hDlg);\r
2709       break;\r
2710     }\r
2711     break;\r
2712   }\r
2713   return FALSE;\r
2714 }\r
2715 \r
2716 VOID\r
2717 TimeControlOptionsPopup(HWND hwnd)\r
2718 {\r
2719   if (gameMode != BeginningOfGame) {\r
2720     DisplayError(_("Changing time control during a game is not implemented"), 0);\r
2721   } else {\r
2722     FARPROC lpProc = MakeProcInstance((FARPROC)TimeControl, hInst);\r
2723     DialogBox(hInst, MAKEINTRESOURCE(DLG_TimeControl), hwnd, (DLGPROC) lpProc);\r
2724     FreeProcInstance(lpProc);\r
2725   }\r
2726 }\r
2727 \r
2728 /*---------------------------------------------------------------------------*\\r
2729  *\r
2730  * Engine Options Dialog functions\r
2731  *\r
2732 \*---------------------------------------------------------------------------*/\r
2733 #define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
2734 #define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
2735 \r
2736 #define INT_ABS( n )    ((n) >= 0 ? (n) : -(n))\r
2737 \r
2738 LRESULT CALLBACK EnginePlayOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2739 {\r
2740   switch (message) {\r
2741   case WM_INITDIALOG: /* message: initialize dialog box */\r
2742 \r
2743     /* Center the dialog over the application window */\r
2744     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2745     Translate(hDlg, DLG_EnginePlayOptions);\r
2746 \r
2747     /* Initialize the dialog items */\r
2748     CHECK_BOX(IDC_EpPeriodicUpdates, appData.periodicUpdates);\r
2749     CHECK_BOX(IDC_EpPonder, appData.ponderNextMove);\r
2750     CHECK_BOX(IDC_EpShowThinking, appData.showThinking);\r
2751     CHECK_BOX(IDC_EpHideThinkingHuman, appData.hideThinkingFromHuman);\r
2752 \r
2753     CHECK_BOX(IDC_TestClaims, appData.testClaims);\r
2754     CHECK_BOX(IDC_DetectMates, appData.checkMates);\r
2755     CHECK_BOX(IDC_MaterialDraws, appData.materialDraws);\r
2756     CHECK_BOX(IDC_TrivialDraws, appData.trivialDraws);\r
2757 \r
2758     CHECK_BOX(IDC_ScoreAbs1, appData.firstScoreIsAbsolute);\r
2759     CHECK_BOX(IDC_ScoreAbs2, appData.secondScoreIsAbsolute);\r
2760 \r
2761     SetDlgItemInt( hDlg, IDC_EpDrawMoveCount, appData.adjudicateDrawMoves, TRUE );\r
2762     SendDlgItemMessage( hDlg, IDC_EpDrawMoveCount, EM_SETSEL, 0, -1 );\r
2763 \r
2764     SetDlgItemInt( hDlg, IDC_EpAdjudicationThreshold, INT_ABS(appData.adjudicateLossThreshold), TRUE );\r
2765     SendDlgItemMessage( hDlg, IDC_EpAdjudicationThreshold, EM_SETSEL, 0, -1 );\r
2766 \r
2767     SetDlgItemInt( hDlg, IDC_RuleMoves, appData.ruleMoves, TRUE );\r
2768     SendDlgItemMessage( hDlg, IDC_RuleMoves, EM_SETSEL, 0, -1 );\r
2769 \r
2770     SetDlgItemInt( hDlg, IDC_DrawRepeats, INT_ABS(appData.drawRepeats), TRUE );\r
2771     SendDlgItemMessage( hDlg, IDC_DrawRepeats, EM_SETSEL, 0, -1 );\r
2772 \r
2773     return TRUE;\r
2774 \r
2775   case WM_COMMAND: /* message: received a command */\r
2776     switch (LOWORD(wParam)) {\r
2777     case IDOK:\r
2778       /* Read changed options from the dialog box */\r
2779       PeriodicUpdatesEvent(          IS_CHECKED(IDC_EpPeriodicUpdates));\r
2780       PonderNextMoveEvent(           IS_CHECKED(IDC_EpPonder));\r
2781       appData.hideThinkingFromHuman= IS_CHECKED(IDC_EpHideThinkingHuman); // [HGM] thinking: moved up\r
2782       appData.showThinking   = IS_CHECKED(IDC_EpShowThinking);\r
2783       ShowThinkingEvent(); // [HGM] thinking: tests all options that need thinking output\r
2784       appData.testClaims    = IS_CHECKED(IDC_TestClaims);\r
2785       appData.checkMates    = IS_CHECKED(IDC_DetectMates);\r
2786       appData.materialDraws = IS_CHECKED(IDC_MaterialDraws);\r
2787       appData.trivialDraws  = IS_CHECKED(IDC_TrivialDraws);\r
2788 \r
2789       appData.adjudicateDrawMoves = GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, NULL, FALSE );\r
2790       appData.adjudicateLossThreshold = - (int) GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, NULL, FALSE );\r
2791       appData.ruleMoves = GetDlgItemInt(hDlg, IDC_RuleMoves, NULL, FALSE );\r
2792       appData.drawRepeats = (int) GetDlgItemInt(hDlg, IDC_DrawRepeats, NULL, FALSE );\r
2793 \r
2794       first.scoreIsAbsolute  = appData.firstScoreIsAbsolute  = IS_CHECKED(IDC_ScoreAbs1);\r
2795       second.scoreIsAbsolute = appData.secondScoreIsAbsolute = IS_CHECKED(IDC_ScoreAbs2);\r
2796 \r
2797       EndDialog(hDlg, TRUE);\r
2798       return TRUE;\r
2799 \r
2800     case IDCANCEL:\r
2801       EndDialog(hDlg, FALSE);\r
2802       return TRUE;\r
2803 \r
2804     case IDC_EpDrawMoveCount:\r
2805     case IDC_EpAdjudicationThreshold:\r
2806     case IDC_DrawRepeats:\r
2807     case IDC_RuleMoves:\r
2808         if( HIWORD(wParam) == EN_CHANGE ) {\r
2809             int n1_ok;\r
2810             int n2_ok;\r
2811             int n3_ok;\r
2812             int n4_ok;\r
2813 \r
2814             GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, &n1_ok, FALSE );\r
2815             GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, &n2_ok, FALSE );\r
2816             GetDlgItemInt(hDlg, IDC_RuleMoves, &n3_ok, FALSE );\r
2817             GetDlgItemInt(hDlg, IDC_DrawRepeats, &n4_ok, FALSE );\r
2818 \r
2819             EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok && n4_ok ? TRUE : FALSE );\r
2820         }\r
2821         return TRUE;\r
2822     }\r
2823     break;\r
2824   }\r
2825   return FALSE;\r
2826 }\r
2827 \r
2828 VOID EnginePlayOptionsPopup(HWND hwnd)\r
2829 {\r
2830   FARPROC lpProc;\r
2831 \r
2832   lpProc = MakeProcInstance((FARPROC)EnginePlayOptionsDialog, hInst);\r
2833   DialogBox(hInst, MAKEINTRESOURCE(DLG_EnginePlayOptions), hwnd, (DLGPROC) lpProc);\r
2834   FreeProcInstance(lpProc);\r
2835 }\r
2836 \r
2837 /*---------------------------------------------------------------------------*\\r
2838  *\r
2839  * UCI Options Dialog functions\r
2840  *\r
2841 \*---------------------------------------------------------------------------*/\r
2842 BOOL BrowseForFolder( const char * title, char * path )\r
2843 {\r
2844     BOOL result = FALSE;\r
2845     BROWSEINFO bi;\r
2846     LPITEMIDLIST pidl;\r
2847 \r
2848     ZeroMemory( &bi, sizeof(bi) );\r
2849 \r
2850     bi.lpszTitle = title == 0 ? _("Choose Folder") : title;\r
2851     bi.ulFlags = BIF_RETURNONLYFSDIRS;\r
2852 \r
2853     pidl = SHBrowseForFolder( &bi );\r
2854 \r
2855     if( pidl != 0 ) {\r
2856         IMalloc * imalloc = 0;\r
2857 \r
2858         if( SHGetPathFromIDList( pidl, path ) ) {\r
2859             result = TRUE;\r
2860         }\r
2861 \r
2862         if( SUCCEEDED( SHGetMalloc ( &imalloc ) ) ) {\r
2863             imalloc->lpVtbl->Free(imalloc,pidl);\r
2864             imalloc->lpVtbl->Release(imalloc);\r
2865         }\r
2866     }\r
2867 \r
2868     return result;\r
2869 }\r
2870 \r
2871 LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2872 {\r
2873   char buf[MAX_PATH];\r
2874   int oldCores;\r
2875 \r
2876   switch (message) {\r
2877   case WM_INITDIALOG: /* message: initialize dialog box */\r
2878 \r
2879     /* Center the dialog over the application window */\r
2880     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2881     Translate(hDlg, DLG_OptionsUCI);\r
2882 \r
2883     /* Initialize the dialog items */\r
2884     SetDlgItemText( hDlg, IDC_PolyglotDir, appData.polyglotDir );\r
2885     SetDlgItemInt( hDlg, IDC_HashSize, appData.defaultHashSize, TRUE );\r
2886     SetDlgItemText( hDlg, IDC_PathToEGTB, appData.defaultPathEGTB );\r
2887     SetDlgItemInt( hDlg, IDC_SizeOfEGTB, appData.defaultCacheSizeEGTB, TRUE );\r
2888     CheckDlgButton( hDlg, IDC_UseBook, (BOOL) appData.usePolyglotBook );\r
2889     SetDlgItemText( hDlg, IDC_BookFile, appData.polyglotBook );\r
2890     // [HGM] smp: input field for nr of cores:\r
2891     SetDlgItemInt( hDlg, IDC_Cores, appData.smpCores, TRUE );\r
2892     // [HGM] book: tick boxes for own book use\r
2893     CheckDlgButton( hDlg, IDC_OwnBook1, (BOOL) appData.firstHasOwnBookUCI );\r
2894     CheckDlgButton( hDlg, IDC_OwnBook2, (BOOL) appData.secondHasOwnBookUCI );\r
2895     SetDlgItemInt( hDlg, IDC_BookDep, appData.bookDepth, TRUE );\r
2896     SetDlgItemInt( hDlg, IDC_BookStr, appData.bookStrength, TRUE );\r
2897     SetDlgItemInt( hDlg, IDC_Games, appData.defaultMatchGames, TRUE );\r
2898 \r
2899     SendDlgItemMessage( hDlg, IDC_PolyglotDir, EM_SETSEL, 0, -1 );\r
2900 \r
2901     return TRUE;\r
2902 \r
2903   case WM_COMMAND: /* message: received a command */\r
2904     switch (LOWORD(wParam)) {\r
2905     case IDOK:\r
2906       GetDlgItemText( hDlg, IDC_PolyglotDir, buf, sizeof(buf) );\r
2907       appData.polyglotDir = strdup(buf);\r
2908       appData.defaultHashSize = GetDlgItemInt(hDlg, IDC_HashSize, NULL, FALSE );\r
2909       appData.defaultCacheSizeEGTB = GetDlgItemInt(hDlg, IDC_SizeOfEGTB, NULL, FALSE );\r
2910       GetDlgItemText( hDlg, IDC_PathToEGTB, buf, sizeof(buf) );\r
2911       appData.defaultPathEGTB = strdup(buf);\r
2912       GetDlgItemText( hDlg, IDC_BookFile, buf, sizeof(buf) );\r
2913       appData.polyglotBook = strdup(buf);\r
2914       appData.usePolyglotBook = (Boolean) IsDlgButtonChecked( hDlg, IDC_UseBook );\r
2915       // [HGM] smp: get nr of cores:\r
2916       oldCores = appData.smpCores;\r
2917       appData.smpCores = GetDlgItemInt(hDlg, IDC_Cores, NULL, FALSE );\r
2918       if(appData.smpCores != oldCores) NewSettingEvent(FALSE, &(first.maxCores), "cores", appData.smpCores);\r
2919       // [HGM] book: read tick boxes for own book use\r
2920       appData.firstHasOwnBookUCI  = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook1 );\r
2921       appData.secondHasOwnBookUCI = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook2 );\r
2922       appData.bookDepth = GetDlgItemInt(hDlg, IDC_BookDep, NULL, FALSE );\r
2923       appData.bookStrength = GetDlgItemInt(hDlg, IDC_BookStr, NULL, FALSE );\r
2924       appData.defaultMatchGames = GetDlgItemInt(hDlg, IDC_Games, NULL, FALSE );\r
2925 \r
2926       if(gameMode == BeginningOfGame) Reset(TRUE, TRUE);\r
2927       EndDialog(hDlg, TRUE);\r
2928       return TRUE;\r
2929 \r
2930     case IDCANCEL:\r
2931       EndDialog(hDlg, FALSE);\r
2932       return TRUE;\r
2933 \r
2934     case IDC_BrowseForBook:\r
2935       {\r
2936           char filter[] = {\r
2937               'A','l','l',' ','F','i','l','e','s', 0,\r
2938               '*','.','*', 0,\r
2939               'B','I','N',' ','F','i','l','e','s', 0,\r
2940               '*','.','b','i','n', 0,\r
2941               0 };\r
2942 \r
2943           OPENFILENAME ofn;\r
2944 \r
2945           safeStrCpy( buf, "" , sizeof( buf)/sizeof( buf[0]) );\r
2946 \r
2947           ZeroMemory( &ofn, sizeof(ofn) );\r
2948 \r
2949           ofn.lStructSize = sizeof(ofn);\r
2950           ofn.hwndOwner = hDlg;\r
2951           ofn.hInstance = hInst;\r
2952           ofn.lpstrFilter = filter;\r
2953           ofn.lpstrFile = buf;\r
2954           ofn.nMaxFile = sizeof(buf);\r
2955           ofn.lpstrTitle = _("Choose Book");\r
2956           ofn.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_HIDEREADONLY;\r
2957 \r
2958           if( GetOpenFileName( &ofn ) ) {\r
2959               SetDlgItemText( hDlg, IDC_BookFile, buf );\r
2960           }\r
2961       }\r
2962       return TRUE;\r
2963 \r
2964     case IDC_BrowseForPolyglotDir:\r
2965       if( BrowseForFolder( _("Choose Polyglot Directory"), buf ) ) {\r
2966         SetDlgItemText( hDlg, IDC_PolyglotDir, buf );\r
2967 \r
2968         strcat( buf, "\\polyglot.exe" );\r
2969 \r
2970         if( GetFileAttributes(buf) == 0xFFFFFFFF ) {\r
2971             MessageBox( hDlg, _("Polyglot was not found in the specified folder!"), "Warning", MB_OK | MB_ICONWARNING );\r
2972         }\r
2973       }\r
2974       return TRUE;\r
2975 \r
2976     case IDC_BrowseForEGTB:\r
2977       if( BrowseForFolder( _("Choose EGTB Directory:"), buf ) ) {\r
2978         SetDlgItemText( hDlg, IDC_PathToEGTB, buf );\r
2979       }\r
2980       return TRUE;\r
2981 \r
2982     case IDC_HashSize:\r
2983     case IDC_SizeOfEGTB:\r
2984         if( HIWORD(wParam) == EN_CHANGE ) {\r
2985             int n1_ok;\r
2986             int n2_ok;\r
2987 \r
2988             GetDlgItemInt(hDlg, IDC_HashSize, &n1_ok, FALSE );\r
2989             GetDlgItemInt(hDlg, IDC_SizeOfEGTB, &n2_ok, FALSE );\r
2990 \r
2991             EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok ? TRUE : FALSE );\r
2992         }\r
2993         return TRUE;\r
2994     }\r
2995     break;\r
2996   }\r
2997   return FALSE;\r
2998 }\r
2999 \r
3000 VOID UciOptionsPopup(HWND hwnd)\r
3001 {\r
3002   FARPROC lpProc;\r
3003 \r
3004   lpProc = MakeProcInstance((FARPROC)UciOptionsDialog, hInst);\r
3005   DialogBox(hInst, MAKEINTRESOURCE(DLG_OptionsUCI), hwnd, (DLGPROC) lpProc);\r
3006   FreeProcInstance(lpProc);\r
3007 }\r