94da5b8402c0e1cc5fc14a362a255a5b9ae2ddd7
[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       SetSampleFontText(hDlg, OPT_SampleGameListFont, &workFont[GAMELIST_FONT]);\r
1555       firstPaint = FALSE;\r
1556     }\r
1557     break;\r
1558 \r
1559   case WM_COMMAND: /* message: received a command */\r
1560     switch (LOWORD(wParam)) {\r
1561 \r
1562     case IDOK:\r
1563       /* again, it seems to avoid redraw problems if we call EndDialog first */\r
1564       EndDialog(hDlg, FALSE);\r
1565 \r
1566       /* copy modified settings back to the fonts array */\r
1567       for (i=0; i < NUM_FONTS; i++)\r
1568         CopyFont(font[boardSize][i], &workFont[i]);\r
1569 \r
1570       /* a sad necessity due to the original design of having a separate\r
1571        * console font, tags font, and comment font for each board size.  IMHO\r
1572        * these fonts should not be dependent on the current board size.  I'm\r
1573        * running out of time, so I am doing this hack rather than redesign the\r
1574        * data structure. Besides, I think if I redesigned the data structure, I\r
1575        * might break backwards compatibility with old winboard.ini files.\r
1576        * --msw\r
1577        */\r
1578       for (i=0; i < NUM_SIZES; i++) {\r
1579         CopyFont(font[i][EDITTAGS_FONT], &workFont[EDITTAGS_FONT]);\r
1580         CopyFont(font[i][CONSOLE_FONT],  &workFont[CONSOLE_FONT]);\r
1581         CopyFont(font[i][COMMENT_FONT],  &workFont[COMMENT_FONT]);\r
1582         CopyFont(font[i][MOVEHISTORY_FONT],  &workFont[MOVEHISTORY_FONT]);\r
1583         CopyFont(font[i][GAMELIST_FONT],  &workFont[GAMELIST_FONT]);\r
1584       }\r
1585       /* end sad necessity */\r
1586 \r
1587       InitDrawingSizes(boardSize, 0);\r
1588       InvalidateRect(hwndMain, NULL, TRUE);\r
1589 \r
1590       if (commentDialog) {\r
1591         SendDlgItemMessage(commentDialog, OPT_CommentText,\r
1592           WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf,\r
1593           MAKELPARAM(TRUE, 0));\r
1594         GetClientRect(GetDlgItem(commentDialog, OPT_CommentText), &rect);\r
1595         InvalidateRect(commentDialog, &rect, TRUE);\r
1596       }\r
1597 \r
1598       if (editTagsDialog) {\r
1599         SendDlgItemMessage(editTagsDialog, OPT_TagsText,\r
1600           WM_SETFONT, (WPARAM)font[boardSize][EDITTAGS_FONT]->hf,\r
1601           MAKELPARAM(TRUE, 0));\r
1602         GetClientRect(GetDlgItem(editTagsDialog, OPT_TagsText), &rect);\r
1603         InvalidateRect(editTagsDialog, &rect, TRUE);\r
1604       }\r
1605 \r
1606       if( moveHistoryDialog != NULL ) {\r
1607         SendDlgItemMessage(moveHistoryDialog, IDC_MoveHistory,\r
1608           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf,\r
1609           MAKELPARAM(TRUE, 0));\r
1610         SendMessage( moveHistoryDialog, WM_INITDIALOG, 0, 0 );\r
1611 //      InvalidateRect(editTagsDialog, NULL, TRUE); // [HGM] this ws improperly cloned?\r
1612       }\r
1613 \r
1614       if( engineOutputDialog != NULL ) {\r
1615         SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo1,\r
1616           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf,\r
1617           MAKELPARAM(TRUE, 0));\r
1618         SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo2,\r
1619           WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf,\r
1620           MAKELPARAM(TRUE, 0));\r
1621       }\r
1622 \r
1623       if (hwndConsole) {\r
1624         ChangedConsoleFont();\r
1625       }\r
1626 \r
1627       for (i=0; i<NUM_FONTS; i++)\r
1628         DeleteObject(&workFont[i].hf);\r
1629 \r
1630       return TRUE;\r
1631 \r
1632     case IDCANCEL:\r
1633       for (i=0; i<NUM_FONTS; i++)\r
1634         DeleteObject(&workFont[i].hf);\r
1635       EndDialog(hDlg, FALSE);\r
1636       return TRUE;\r
1637 \r
1638     case OPT_ChooseClockFont:\r
1639       MyCreateFont(hDlg, &workFont[CLOCK_FONT]);\r
1640       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1641       break;\r
1642 \r
1643     case OPT_ChooseMessageFont:\r
1644       MyCreateFont(hDlg, &workFont[MESSAGE_FONT]);\r
1645       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1646       break;\r
1647 \r
1648     case OPT_ChooseCoordFont:\r
1649       MyCreateFont(hDlg, &workFont[COORD_FONT]);\r
1650       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1651       break;\r
1652 \r
1653     case OPT_ChooseTagFont:\r
1654       MyCreateFont(hDlg, &workFont[EDITTAGS_FONT]);\r
1655       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1656       break;\r
1657 \r
1658     case OPT_ChooseCommentsFont:\r
1659       MyCreateFont(hDlg, &workFont[COMMENT_FONT]);\r
1660       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1661       break;\r
1662 \r
1663     case OPT_ChooseConsoleFont:\r
1664       MyCreateFont(hDlg, &workFont[CONSOLE_FONT]);\r
1665       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1666       break;\r
1667 \r
1668     case OPT_ChooseMoveHistoryFont:\r
1669       MyCreateFont(hDlg, &workFont[MOVEHISTORY_FONT]);\r
1670       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1671       break;\r
1672 \r
1673     case OPT_ChooseGameListFont:\r
1674       MyCreateFont(hDlg, &workFont[GAMELIST_FONT]);\r
1675       SetSampleFontText(hDlg, OPT_SampleGameListFont, &workFont[GAMELIST_FONT]);\r
1676       break;\r
1677 \r
1678     case OPT_DefaultFonts:\r
1679       for (i=0; i<NUM_FONTS; i++) {\r
1680         DeleteObject(&workFont[i].hf);\r
1681         ParseFontName(font[boardSize][i]->def, &workFont[i].mfp);\r
1682         CreateFontInMF(&workFont[i]);\r
1683       }\r
1684       SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
1685       SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
1686       SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
1687       SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
1688       SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
1689       SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
1690       SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
1691       SetSampleFontText(hDlg, OPT_SampleGameListFont, &workFont[GAMELIST_FONT]);\r
1692       break;\r
1693     }\r
1694   }\r
1695   return FALSE;\r
1696 }\r
1697 \r
1698 VOID\r
1699 FontsOptionsPopup(HWND hwnd)\r
1700 {\r
1701   FARPROC lpProc = MakeProcInstance((FARPROC)FontOptionsDialog, hInst);\r
1702   DialogBox(hInst, MAKEINTRESOURCE(DLG_Fonts), hwnd,\r
1703           (DLGPROC) lpProc);\r
1704   FreeProcInstance(lpProc);\r
1705 }\r
1706 \r
1707 /*---------------------------------------------------------------------------*\\r
1708  *\r
1709  * Sounds Dialog functions\r
1710  *\r
1711 \*---------------------------------------------------------------------------*/\r
1712 \r
1713 \r
1714 SoundComboData soundComboData[] = {\r
1715   {N_("Move"), NULL},\r
1716   {N_("Bell"), NULL},\r
1717   {N_("ICS Alarm"), NULL},\r
1718   {N_("ICS Win"), NULL},\r
1719   {N_("ICS Loss"), NULL},\r
1720   {N_("ICS Draw"), NULL},\r
1721   {N_("ICS Unfinished"), NULL},\r
1722   {N_("Shout"), NULL},\r
1723   {N_("SShout/CShout"), NULL},\r
1724   {N_("Channel 1"), NULL},\r
1725   {N_("Channel"), NULL},\r
1726   {N_("Kibitz"), NULL},\r
1727   {N_("Tell"), NULL},\r
1728   {N_("Challenge"), NULL},\r
1729   {N_("Request"), NULL},\r
1730   {N_("Seek"), NULL},\r
1731   {NULL, NULL},\r
1732 };\r
1733 \r
1734 \r
1735 void\r
1736 InitSoundComboData(SoundComboData *scd)\r
1737 {\r
1738   SoundClass sc;\r
1739   ColorClass cc;\r
1740   int index;\r
1741 \r
1742   /* copy current sound settings to combo array */\r
1743 \r
1744   for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
1745     scd[sc].name = strdup(sounds[sc].name);\r
1746   }\r
1747   for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
1748     index = (int)cc + (int)NSoundClasses;\r
1749     scd[index].name = strdup(textAttribs[cc].sound.name);\r
1750   }\r
1751 }\r
1752 \r
1753 \r
1754 void\r
1755 ResetSoundComboData(SoundComboData *scd)\r
1756 {\r
1757   while (scd->label) {\r
1758     if (scd->name != NULL) {\r
1759       free (scd->name);\r
1760       scd->name = NULL;\r
1761     }\r
1762     scd++;\r
1763   }\r
1764 }\r
1765 \r
1766 void\r
1767 InitSoundCombo(HWND hwndCombo, SoundComboData *scd)\r
1768 {\r
1769   char buf[255];\r
1770   DWORD err;\r
1771   DWORD cnt = 0;\r
1772   SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
1773 \r
1774   /* send the labels to the combo box */\r
1775   while (scd->label) {\r
1776     err = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) T_(scd->label));\r
1777     if (err != cnt++) {\r
1778       snprintf(buf, MSG_SIZ,  "InitSoundCombo(): err '%d', cnt '%d'\n",\r
1779           (int)err, (int)cnt);\r
1780       MessageBox(NULL, buf, NULL, MB_OK);\r
1781     }\r
1782     scd++;\r
1783   }\r
1784   SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
1785 }\r
1786 \r
1787 int\r
1788 SoundDialogWhichRadio(HWND hDlg)\r
1789 {\r
1790   if (IsDlgButtonChecked(hDlg, OPT_NoSound)) return OPT_NoSound;\r
1791   if (IsDlgButtonChecked(hDlg, OPT_DefaultBeep)) return OPT_DefaultBeep;\r
1792   if (IsDlgButtonChecked(hDlg, OPT_BuiltInSound)) return OPT_BuiltInSound;\r
1793   if (IsDlgButtonChecked(hDlg, OPT_WavFile)) return OPT_WavFile;\r
1794   return -1;\r
1795 }\r
1796 \r
1797 VOID\r
1798 SoundDialogSetEnables(HWND hDlg, int radio)\r
1799 {\r
1800   EnableWindow(GetDlgItem(hDlg, OPT_BuiltInSoundName),\r
1801                radio == OPT_BuiltInSound);\r
1802   EnableWindow(GetDlgItem(hDlg, OPT_WavFileName), radio == OPT_WavFile);\r
1803   EnableWindow(GetDlgItem(hDlg, OPT_BrowseSound), radio == OPT_WavFile);\r
1804 }\r
1805 \r
1806 char *\r
1807 SoundDialogGetName(HWND hDlg, int radio)\r
1808 {\r
1809   static char buf[MSG_SIZ], buf2[MSG_SIZ], buf3[MSG_SIZ];\r
1810   char *dummy, *ret;\r
1811   switch (radio) {\r
1812   case OPT_NoSound:\r
1813   default:\r
1814     return "";\r
1815   case OPT_DefaultBeep:\r
1816     return "$";\r
1817   case OPT_BuiltInSound:\r
1818     buf[0] = '!';\r
1819     GetDlgItemText(hDlg, OPT_BuiltInSoundName, buf + 1, sizeof(buf) - 1);\r
1820     return buf;\r
1821   case OPT_WavFile:\r
1822     GetDlgItemText(hDlg, OPT_WavFileName, buf, sizeof(buf));\r
1823     GetCurrentDirectory(MSG_SIZ, buf3);\r
1824     SetCurrentDirectory(installDir);\r
1825     if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
1826       ret = buf2;\r
1827     } else {\r
1828       ret = buf;\r
1829     }\r
1830     SetCurrentDirectory(buf3);\r
1831     return ret;\r
1832   }\r
1833 }\r
1834 \r
1835 void\r
1836 DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name)\r
1837 {\r
1838   int radio;\r
1839   /*\r
1840    * I think it's best to clear the combo and edit boxes. It looks stupid\r
1841    * to have a value from another sound event sitting there grayed out.\r
1842    */\r
1843   SetDlgItemText(hDlg, OPT_WavFileName, "");\r
1844   SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
1845 \r
1846   if (appData.debugMode)\r
1847       fprintf(debugFP, "DisplaySelectedSound(,,'%s'):\n", name);\r
1848   switch (name[0]) {\r
1849   case NULLCHAR:\r
1850     radio = OPT_NoSound;\r
1851     break;\r
1852   case '$':\r
1853     if (name[1] == NULLCHAR) {\r
1854       radio = OPT_DefaultBeep;\r
1855     } else {\r
1856       radio = OPT_WavFile;\r
1857       SetDlgItemText(hDlg, OPT_WavFileName, name);\r
1858     }\r
1859     break;\r
1860   case '!':\r
1861     if (name[1] == NULLCHAR) {\r
1862       radio = OPT_NoSound;\r
1863     } else {\r
1864       radio = OPT_BuiltInSound;\r
1865       if (SendMessage(hCombo, CB_SELECTSTRING, (WPARAM) -1,\r
1866                       (LPARAM) (name + 1)) == CB_ERR) {\r
1867         SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
1868         SendMessage(hCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) (name + 1));\r
1869       }\r
1870     }\r
1871     break;\r
1872   default:\r
1873     radio = OPT_WavFile;\r
1874     SetDlgItemText(hDlg, OPT_WavFileName, name);\r
1875     break;\r
1876   }\r
1877   SoundDialogSetEnables(hDlg, radio);\r
1878   CheckRadioButton(hDlg, OPT_NoSound, OPT_WavFile, radio);\r
1879 }\r
1880 \r
1881 \r
1882 char *builtInSoundNames[] = BUILT_IN_SOUND_NAMES;\r
1883 \r
1884 LRESULT CALLBACK\r
1885 SoundOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
1886 {\r
1887   static HWND hSoundCombo;\r
1888   static DWORD index;\r
1889   static HWND hBISN;\r
1890   int radio;\r
1891   MySound tmp;\r
1892   FILE *f;\r
1893   char buf[MSG_SIZ];\r
1894   char *newName;\r
1895   SoundClass sc;\r
1896   ColorClass cc;\r
1897   SoundComboData *scd;\r
1898   int oldMute;\r
1899 \r
1900   switch (message) {\r
1901   case WM_INITDIALOG:\r
1902     /* Center the dialog over the application window */\r
1903     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
1904     Translate(hDlg, DLG_Sound);\r
1905 \r
1906     /* Initialize the built-in sounds combo */\r
1907     hBISN = GetDlgItem(hDlg, OPT_BuiltInSoundName);\r
1908      InitComboStrings(hBISN, builtInSoundNames);\r
1909 \r
1910     /* Initialize the  sound events combo */\r
1911     index = 0;\r
1912     InitSoundComboData(soundComboData);\r
1913     hSoundCombo = GetDlgItem(hDlg, CBO_Sounds);\r
1914     InitSoundCombo(hSoundCombo, soundComboData);\r
1915 \r
1916     /* update the dialog */\r
1917     DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
1918     return TRUE;\r
1919 \r
1920   case WM_COMMAND: /* message: received a command */\r
1921 \r
1922     if (((HWND)lParam == hSoundCombo) &&\r
1923         (HIWORD(wParam) == CBN_SELCHANGE)) {\r
1924       /*\r
1925        * the user has selected a new sound event. We must store the name for\r
1926        * the previously selected event, then retrieve the name for the\r
1927        * newly selected event and update the dialog.\r
1928        */\r
1929       radio = SoundDialogWhichRadio(hDlg);\r
1930       newName = strdup(SoundDialogGetName(hDlg, radio));\r
1931 \r
1932       if (strcmp(newName, soundComboData[index].name) != 0) {\r
1933         free(soundComboData[index].name);\r
1934         soundComboData[index].name = newName;\r
1935       } else {\r
1936         free(newName);\r
1937         newName = NULL;\r
1938       }\r
1939       /* now get the settings for the newly selected event */\r
1940       index = SendMessage(hSoundCombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);\r
1941       DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
1942 \r
1943       return TRUE;\r
1944     }\r
1945     switch (LOWORD(wParam)) {\r
1946     case IDOK:\r
1947       /*\r
1948        * save the name for the currently selected sound event\r
1949        */\r
1950       radio = SoundDialogWhichRadio(hDlg);\r
1951       newName = strdup(SoundDialogGetName(hDlg, radio));\r
1952 \r
1953       if (strcmp(soundComboData[index].name, newName) != 0) {\r
1954         free(soundComboData[index].name);\r
1955         soundComboData[index].name = newName;\r
1956       } else {\r
1957         free(newName);\r
1958         newName = NULL;\r
1959       }\r
1960 \r
1961       /* save all the sound names that changed and load the sounds */\r
1962 \r
1963       for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
1964         if (strcmp(soundComboData[sc].name, sounds[sc].name) != 0) {\r
1965           free(sounds[sc].name);\r
1966           sounds[sc].name = strdup(soundComboData[sc].name);\r
1967           MyLoadSound(&sounds[sc]);\r
1968         }\r
1969       }\r
1970       for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
1971         index = (int)cc + (int)NSoundClasses;\r
1972         if (strcmp(soundComboData[index].name,\r
1973                    textAttribs[cc].sound.name) != 0) {\r
1974           free(textAttribs[cc].sound.name);\r
1975           textAttribs[cc].sound.name = strdup(soundComboData[index].name);\r
1976           MyLoadSound(&textAttribs[cc].sound);\r
1977         }\r
1978       }\r
1979 \r
1980         mute = FALSE; // [HGM] mute: switch sounds automatically on if we select one\r
1981       CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds,MF_BYCOMMAND|MF_UNCHECKED);\r
1982       ResetSoundComboData(soundComboData);\r
1983       EndDialog(hDlg, TRUE);\r
1984       return TRUE;\r
1985 \r
1986     case IDCANCEL:\r
1987       ResetSoundComboData(soundComboData);\r
1988       EndDialog(hDlg, FALSE);\r
1989       return TRUE;\r
1990 \r
1991     case OPT_DefaultSounds:\r
1992       /* can't use SetDefaultSounds() because we need to be able to "undo" if\r
1993        * user selects "Cancel" later on. So we do it the hard way here.\r
1994        */\r
1995       scd = &soundComboData[0];\r
1996       while (scd->label != NULL) {\r
1997         if (scd->name != NULL) free(scd->name);\r
1998         scd->name = strdup("");\r
1999         scd++;\r
2000       }\r
2001       free(soundComboData[(int)SoundBell].name);\r
2002       soundComboData[(int)SoundBell].name = strdup(SOUND_BELL);\r
2003       DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
2004       break;\r
2005 \r
2006     case OPT_PlaySound:\r
2007       radio = SoundDialogWhichRadio(hDlg);\r
2008       tmp.name = strdup(SoundDialogGetName(hDlg, radio));\r
2009       tmp.data = NULL;\r
2010       MyLoadSound(&tmp);\r
2011         oldMute = mute; mute = FALSE; // [HGM] mute: always sound when user presses play, ignorig mute setting\r
2012       MyPlaySound(&tmp);\r
2013         mute = oldMute;\r
2014       if (tmp.data  != NULL) FreeResource(tmp.data); // technically obsolete fn, but tmp.data is NOT malloc'd mem\r
2015       if (tmp.name != NULL) free(tmp.name);\r
2016       return TRUE;\r
2017 \r
2018     case OPT_BrowseSound:\r
2019       f = OpenFileDialog(hDlg, "rb", NULL, "wav", SOUND_FILT,\r
2020         _("Browse for Sound File"), NULL, NULL, buf);\r
2021       if (f != NULL) {\r
2022         fclose(f);\r
2023         SetDlgItemText(hDlg, OPT_WavFileName, buf);\r
2024       }\r
2025       return TRUE;\r
2026 \r
2027     default:\r
2028       radio = SoundDialogWhichRadio(hDlg);\r
2029       SoundDialogSetEnables(hDlg, radio);\r
2030       break;\r
2031     }\r
2032     break;\r
2033   }\r
2034   return FALSE;\r
2035 }\r
2036 \r
2037 \r
2038 VOID SoundOptionsPopup(HWND hwnd)\r
2039 {\r
2040   FARPROC lpProc;\r
2041 \r
2042   lpProc = MakeProcInstance((FARPROC)SoundOptionsDialog, hInst);\r
2043   DialogBox(hInst, MAKEINTRESOURCE(DLG_Sound), hwnd, (DLGPROC)lpProc);\r
2044   FreeProcInstance(lpProc);\r
2045 }\r
2046 \r
2047 \r
2048 /*---------------------------------------------------------------------------*\\r
2049  *\r
2050  * Comm Port dialog functions\r
2051  *\r
2052 \*---------------------------------------------------------------------------*/\r
2053 \r
2054 \r
2055 #define FLOW_NONE   0\r
2056 #define FLOW_XOFF   1\r
2057 #define FLOW_CTS    2\r
2058 #define FLOW_DSR    3\r
2059 \r
2060 #define PORT_NONE\r
2061 \r
2062 ComboData cdPort[]     = { {"None", PORT_NONE}, {"COM1", 1}, {"COM2", 2},\r
2063                            {"COM3", 3}, {"COM4", 4}, {NULL, 0} };\r
2064 ComboData cdDataRate[] = { {"110", 110}, {"300", 300}, {"600", 600}, {"1200", 1200},\r
2065                            {"2400", 2400}, {"4800", 4800}, {"9600", 9600}, {"19200", 19200},\r
2066                            {"38400", 38400}, {NULL, 0} };\r
2067 ComboData cdDataBits[] = { {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {NULL, 0} };\r
2068 ComboData cdParity[]   = { {"None", NOPARITY}, {"Odd", ODDPARITY}, {"Even", EVENPARITY},\r
2069                            {"Mark", MARKPARITY}, {"Space", SPACEPARITY}, {NULL, 0} };\r
2070 ComboData cdStopBits[] = { {"1", ONESTOPBIT}, {"1.5", ONE5STOPBITS},\r
2071                            {"2", TWOSTOPBITS}, {NULL, 0} };\r
2072 ComboData cdFlow[]     = { {"None", FLOW_NONE}, {"Xoff/Xon", FLOW_XOFF}, {"CTS", FLOW_CTS},\r
2073                            {"DSR", FLOW_DSR}, {NULL, 0} };\r
2074 \r
2075 \r
2076 VOID\r
2077 ParseCommSettings(char *arg, DCB *dcb)\r
2078 {\r
2079   int dataRate, count;\r
2080   char bits[MSG_SIZ], parity[MSG_SIZ], stopBits[MSG_SIZ], flow[MSG_SIZ];\r
2081   ComboData *cd;\r
2082   count = sscanf(arg, "%d%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]",\r
2083     &dataRate, bits, parity, stopBits, flow);\r
2084   if (count != 5) goto cant_parse;\r
2085   dcb->BaudRate = dataRate;\r
2086   cd = cdDataBits;\r
2087   while (cd->label != NULL) {\r
2088     if (StrCaseCmp(cd->label, bits) == 0) {\r
2089       dcb->ByteSize = cd->value;\r
2090       break;\r
2091     }\r
2092     cd++;\r
2093   }\r
2094   if (cd->label == NULL) goto cant_parse;\r
2095   cd = cdParity;\r
2096   while (cd->label != NULL) {\r
2097     if (StrCaseCmp(cd->label, parity) == 0) {\r
2098       dcb->Parity = cd->value;\r
2099       break;\r
2100     }\r
2101     cd++;\r
2102   }\r
2103   if (cd->label == NULL) goto cant_parse;\r
2104   cd = cdStopBits;\r
2105   while (cd->label != NULL) {\r
2106     if (StrCaseCmp(cd->label, stopBits) == 0) {\r
2107       dcb->StopBits = cd->value;\r
2108       break;\r
2109     }\r
2110     cd++;\r
2111   }\r
2112   cd = cdFlow;\r
2113   if (cd->label == NULL) goto cant_parse;\r
2114   while (cd->label != NULL) {\r
2115     if (StrCaseCmp(cd->label, flow) == 0) {\r
2116       switch (cd->value) {\r
2117       case FLOW_NONE:\r
2118         dcb->fOutX = FALSE;\r
2119         dcb->fOutxCtsFlow = FALSE;\r
2120         dcb->fOutxDsrFlow = FALSE;\r
2121         break;\r
2122       case FLOW_CTS:\r
2123         dcb->fOutX = FALSE;\r
2124         dcb->fOutxCtsFlow = TRUE;\r
2125         dcb->fOutxDsrFlow = FALSE;\r
2126         break;\r
2127       case FLOW_DSR:\r
2128         dcb->fOutX = FALSE;\r
2129         dcb->fOutxCtsFlow = FALSE;\r
2130         dcb->fOutxDsrFlow = TRUE;\r
2131         break;\r
2132       case FLOW_XOFF:\r
2133         dcb->fOutX = TRUE;\r
2134         dcb->fOutxCtsFlow = FALSE;\r
2135         dcb->fOutxDsrFlow = FALSE;\r
2136         break;\r
2137       }\r
2138       break;\r
2139     }\r
2140     cd++;\r
2141   }\r
2142   if (cd->label == NULL) goto cant_parse;\r
2143   return;\r
2144 cant_parse:\r
2145     ExitArgError(_("Can't parse com port settings"), arg, TRUE);\r
2146 }\r
2147 \r
2148 \r
2149 VOID PrintCommSettings(FILE *f, char *name, DCB *dcb)\r
2150 {\r
2151   char *flow = "??", *parity = "??", *stopBits = "??";\r
2152   ComboData *cd;\r
2153 \r
2154   cd = cdParity;\r
2155   while (cd->label != NULL) {\r
2156     if (dcb->Parity == cd->value) {\r
2157       parity = cd->label;\r
2158       break;\r
2159     }\r
2160     cd++;\r
2161   }\r
2162   cd = cdStopBits;\r
2163   while (cd->label != NULL) {\r
2164     if (dcb->StopBits == cd->value) {\r
2165       stopBits = cd->label;\r
2166       break;\r
2167     }\r
2168     cd++;\r
2169   }\r
2170   if (dcb->fOutX) {\r
2171     flow = cdFlow[FLOW_XOFF].label;\r
2172   } else if (dcb->fOutxCtsFlow) {\r
2173     flow = cdFlow[FLOW_CTS].label;\r
2174   } else if (dcb->fOutxDsrFlow) {\r
2175     flow = cdFlow[FLOW_DSR].label;\r
2176   } else {\r
2177     flow = cdFlow[FLOW_NONE].label;\r
2178   }\r
2179   fprintf(f, "/%s=%d,%d,%s,%s,%s\n", name,\r
2180     (int)dcb->BaudRate, dcb->ByteSize, parity, stopBits, flow);\r
2181 }\r
2182 \r
2183 \r
2184 void\r
2185 InitCombo(HANDLE hwndCombo, ComboData *cd)\r
2186 {\r
2187   SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
2188 \r
2189   while (cd->label != NULL) {\r
2190     SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) cd->label);\r
2191     cd++;\r
2192   }\r
2193 }\r
2194 \r
2195 void\r
2196 SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value)\r
2197 {\r
2198   int i;\r
2199 \r
2200   i = 0;\r
2201   while (cd->label != NULL) {\r
2202     if (cd->value == value) {\r
2203       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) i, (LPARAM) 0);\r
2204       return;\r
2205     }\r
2206     cd++;\r
2207     i++;\r
2208   }\r
2209 }\r
2210 \r
2211 LRESULT CALLBACK\r
2212 CommPortOptionsDialog(HWND hDlg, UINT message, WPARAM wParam,   LPARAM lParam)\r
2213 {\r
2214   char buf[MSG_SIZ];\r
2215   HANDLE hwndCombo;\r
2216   char *p;\r
2217   LRESULT index;\r
2218   unsigned value;\r
2219   int err;\r
2220 \r
2221   switch (message) {\r
2222   case WM_INITDIALOG: /* message: initialize dialog box */\r
2223     /* Center the dialog over the application window */\r
2224     CenterWindow (hDlg, GetWindow(hDlg, GW_OWNER));\r
2225     Translate(hDlg, DLG_CommPort);\r
2226     /* Initialize the dialog items */\r
2227     /* !! There should probably be some synchronization\r
2228        in accessing hCommPort and dcb.  Or does modal nature\r
2229        of this dialog box do it for us?\r
2230        */\r
2231     hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
2232     InitCombo(hwndCombo, cdPort);\r
2233     p = strrchr(appData.icsCommPort, '\\');\r
2234     if (p++ == NULL) p = appData.icsCommPort;\r
2235     if ((*p == '\0') ||\r
2236         (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) p) == CB_ERR)) {\r
2237       SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) "None");\r
2238     }\r
2239     EnableWindow(hwndCombo, hCommPort == NULL); /*!! don't allow change for now*/\r
2240 \r
2241     hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
2242     InitCombo(hwndCombo, cdDataRate);\r
2243     snprintf(buf, MSG_SIZ, "%u", (int)dcb.BaudRate);\r
2244     if (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) buf) == CB_ERR) {\r
2245       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
2246       SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);\r
2247     }\r
2248 \r
2249     hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
2250     InitCombo(hwndCombo, cdDataBits);\r
2251     SelectComboValue(hwndCombo, cdDataBits, dcb.ByteSize);\r
2252 \r
2253     hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
2254     InitCombo(hwndCombo, cdParity);\r
2255     SelectComboValue(hwndCombo, cdParity, dcb.Parity);\r
2256 \r
2257     hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
2258     InitCombo(hwndCombo, cdStopBits);\r
2259     SelectComboValue(hwndCombo, cdStopBits, dcb.StopBits);\r
2260 \r
2261     hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
2262     InitCombo(hwndCombo, cdFlow);\r
2263     if (dcb.fOutX) {\r
2264       SelectComboValue(hwndCombo, cdFlow, FLOW_XOFF);\r
2265     } else if (dcb.fOutxCtsFlow) {\r
2266       SelectComboValue(hwndCombo, cdFlow, FLOW_CTS);\r
2267     } else if (dcb.fOutxDsrFlow) {\r
2268       SelectComboValue(hwndCombo, cdFlow, FLOW_DSR);\r
2269     } else {\r
2270       SelectComboValue(hwndCombo, cdFlow, FLOW_NONE);\r
2271     }\r
2272     return TRUE;\r
2273 \r
2274   case WM_COMMAND: /* message: received a command */\r
2275     switch (LOWORD(wParam)) {\r
2276     case IDOK:\r
2277       /* Read changed options from the dialog box */\r
2278 #ifdef NOTDEF\r
2279       /* !! Currently we can't change comm ports in midstream */\r
2280       hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
2281       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2282       if (index == PORT_NONE) {\r
2283         appData.icsCommPort = "";\r
2284         if (hCommPort != NULL) {\r
2285           CloseHandle(hCommPort);\r
2286           hCommPort = NULL;\r
2287         }\r
2288         EndDialog(hDlg, TRUE);\r
2289         return TRUE;\r
2290       }\r
2291       SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
2292       appData.icsCommPort = strdup(buf);\r
2293       if (hCommPort != NULL) {\r
2294         CloseHandle(hCommPort);\r
2295         hCommPort = NULL;\r
2296       }\r
2297       /* now what?? can't really do this; have to fix up the ChildProc\r
2298          and InputSource records for the comm port that we gave to the\r
2299          back end. */\r
2300 #endif /*NOTDEF*/\r
2301 \r
2302       hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
2303       SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
2304       if (sscanf(buf, "%u", &value) != 1) {\r
2305         MessageBox(hDlg, _("Invalid data rate"),\r
2306                    _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2307         return TRUE;\r
2308       }\r
2309       dcb.BaudRate = value;\r
2310 \r
2311       hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
2312       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2313       dcb.ByteSize = cdDataBits[index].value;\r
2314 \r
2315       hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
2316       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2317       dcb.Parity = cdParity[index].value;\r
2318 \r
2319       hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
2320       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2321       dcb.StopBits = cdStopBits[index].value;\r
2322 \r
2323       hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
2324       index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
2325       switch (cdFlow[index].value) {\r
2326       case FLOW_NONE:\r
2327         dcb.fOutX = FALSE;\r
2328         dcb.fOutxCtsFlow = FALSE;\r
2329         dcb.fOutxDsrFlow = FALSE;\r
2330         break;\r
2331       case FLOW_CTS:\r
2332         dcb.fOutX = FALSE;\r
2333         dcb.fOutxCtsFlow = TRUE;\r
2334         dcb.fOutxDsrFlow = FALSE;\r
2335         break;\r
2336       case FLOW_DSR:\r
2337         dcb.fOutX = FALSE;\r
2338         dcb.fOutxCtsFlow = FALSE;\r
2339         dcb.fOutxDsrFlow = TRUE;\r
2340         break;\r
2341       case FLOW_XOFF:\r
2342         dcb.fOutX = TRUE;\r
2343         dcb.fOutxCtsFlow = FALSE;\r
2344         dcb.fOutxDsrFlow = FALSE;\r
2345         break;\r
2346       }\r
2347       if (!SetCommState(hCommPort, (LPDCB) &dcb)) {\r
2348         err = GetLastError();\r
2349         switch(MessageBox(hDlg,\r
2350                          "Failed to set comm port state;\r\ninvalid options?",\r
2351                          _("Option Error"), MB_ABORTRETRYIGNORE|MB_ICONQUESTION)) {\r
2352         case IDABORT:\r
2353           DisplayFatalError(_("Failed to set comm port state"), err, 1);\r
2354           exit(1);  /*is it ok to do this from here?*/\r
2355 \r
2356         case IDRETRY:\r
2357           return TRUE;\r
2358 \r
2359         case IDIGNORE:\r
2360           EndDialog(hDlg, TRUE);\r
2361           return TRUE;\r
2362         }\r
2363       }\r
2364 \r
2365       EndDialog(hDlg, TRUE);\r
2366       return TRUE;\r
2367 \r
2368     case IDCANCEL:\r
2369       EndDialog(hDlg, FALSE);\r
2370       return TRUE;\r
2371 \r
2372     default:\r
2373       break;\r
2374     }\r
2375     break;\r
2376   }\r
2377   return FALSE;\r
2378 }\r
2379 \r
2380 VOID\r
2381 CommPortOptionsPopup(HWND hwnd)\r
2382 {\r
2383   FARPROC lpProc = MakeProcInstance((FARPROC)CommPortOptionsDialog, hInst);\r
2384   DialogBox(hInst, MAKEINTRESOURCE(DLG_CommPort), hwnd, (DLGPROC) lpProc);\r
2385   FreeProcInstance(lpProc);\r
2386 }\r
2387 \r
2388 /*---------------------------------------------------------------------------*\\r
2389  *\r
2390  * Load Options dialog functions\r
2391  *\r
2392 \*---------------------------------------------------------------------------*/\r
2393 \r
2394 int\r
2395 LoadOptionsWhichRadio(HWND hDlg)\r
2396 {\r
2397   return (IsDlgButtonChecked(hDlg, OPT_Exact) ? 1 :\r
2398          (IsDlgButtonChecked(hDlg, OPT_Subset) ? 2 :\r
2399          (IsDlgButtonChecked(hDlg, OPT_Struct) ? 3 :\r
2400          (IsDlgButtonChecked(hDlg, OPT_Material) ? 4 : -1))));\r
2401 }\r
2402 \r
2403 VOID\r
2404 SetLoadOptionEnables(HWND hDlg)\r
2405 {\r
2406   UINT state;\r
2407 \r
2408   state = IsDlgButtonChecked(hDlg, OPT_Autostep);\r
2409   EnableWindow(GetDlgItem(hDlg, OPT_ASTimeDelay), state);\r
2410   EnableWindow(GetDlgItem(hDlg, OPT_AStext1), state);\r
2411 }\r
2412 \r
2413 LRESULT CALLBACK\r
2414 LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2415 {\r
2416   char buf[MSG_SIZ];\r
2417   float fnumber;\r
2418   int ok;\r
2419 \r
2420   switch (message) {\r
2421   case WM_INITDIALOG: /* message: initialize dialog box */\r
2422     /* Center the dialog over the application window */\r
2423     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2424     Translate(hDlg, DLG_LoadOptions);\r
2425     /* Initialize the dialog items */\r
2426     if (appData.timeDelay >= 0.0) {\r
2427       CheckDlgButton(hDlg, OPT_Autostep, TRUE);\r
2428       snprintf(buf, MSG_SIZ, "%.2g", appData.timeDelay);\r
2429       SetDlgItemText(hDlg, OPT_ASTimeDelay, buf);\r
2430     } else {\r
2431       CheckDlgButton(hDlg, OPT_Autostep, FALSE);\r
2432     }\r
2433     SetLoadOptionEnables(hDlg);\r
2434     SetDlgItemInt(hDlg, OPT_elo1, appData.eloThreshold1, FALSE);\r
2435     SetDlgItemInt(hDlg, OPT_elo2, appData.eloThreshold2, FALSE);\r
2436     SetDlgItemInt(hDlg, OPT_date, appData.dateThreshold, FALSE);\r
2437     switch (appData.searchMode) {\r
2438     case 1:\r
2439       CheckDlgButton(hDlg, OPT_Exact, TRUE);\r
2440       break;\r
2441     case 2:\r
2442       CheckDlgButton(hDlg, OPT_Subset, TRUE);\r
2443       break;\r
2444     case 3:\r
2445       CheckDlgButton(hDlg, OPT_Struct, TRUE);\r
2446       break;\r
2447     case 4:\r
2448       CheckDlgButton(hDlg, OPT_Material, TRUE);\r
2449       break;\r
2450     }\r
2451     return TRUE;\r
2452 \r
2453   case WM_COMMAND: /* message: received a command */\r
2454     switch (LOWORD(wParam)) {\r
2455     case IDOK:\r
2456       /* Read changed options from the dialog box */\r
2457       if (IsDlgButtonChecked(hDlg, OPT_Autostep)) {\r
2458         GetDlgItemText(hDlg, OPT_ASTimeDelay, buf, MSG_SIZ);\r
2459         if (sscanf(buf, "%f", &fnumber) != 1) {\r
2460           MessageBox(hDlg, _("Invalid load game step rate"),\r
2461                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2462           return FALSE;\r
2463         }\r
2464         appData.timeDelay = fnumber;\r
2465       } else {\r
2466         appData.timeDelay = (float) -1.0;\r
2467       }\r
2468       appData.eloThreshold1 = GetDlgItemInt(hDlg, OPT_elo1, &ok, FALSE);\r
2469       appData.eloThreshold2 = GetDlgItemInt(hDlg, OPT_elo2, &ok, FALSE);\r
2470       appData.dateThreshold = GetDlgItemInt(hDlg, OPT_date, &ok, FALSE);\r
2471       appData.searchMode = LoadOptionsWhichRadio(hDlg);\r
2472       EndDialog(hDlg, TRUE);\r
2473       return TRUE;\r
2474 \r
2475     case IDCANCEL:\r
2476       EndDialog(hDlg, FALSE);\r
2477       return TRUE;\r
2478 \r
2479     default:\r
2480       SetLoadOptionEnables(hDlg);\r
2481       break;\r
2482     }\r
2483     break;\r
2484   }\r
2485   return FALSE;\r
2486 }\r
2487 \r
2488 \r
2489 VOID\r
2490 LoadOptionsPopup(HWND hwnd)\r
2491 {\r
2492   FARPROC lpProc = MakeProcInstance((FARPROC)LoadOptions, hInst);\r
2493   DialogBox(hInst, MAKEINTRESOURCE(DLG_LoadOptions), hwnd, (DLGPROC) lpProc);\r
2494   FreeProcInstance(lpProc);\r
2495 }\r
2496 \r
2497 /*---------------------------------------------------------------------------*\\r
2498  *\r
2499  * Save Options dialog functions\r
2500  *\r
2501 \*---------------------------------------------------------------------------*/\r
2502 \r
2503 VOID\r
2504 SetSaveOptionEnables(HWND hDlg)\r
2505 {\r
2506   UINT state;\r
2507 \r
2508   state = IsDlgButtonChecked(hDlg, OPT_Autosave);\r
2509   EnableWindow(GetDlgItem(hDlg, OPT_AVPrompt), state);\r
2510   EnableWindow(GetDlgItem(hDlg, OPT_AVToFile), state);\r
2511   if (state && !IsDlgButtonChecked(hDlg, OPT_AVPrompt) &&\r
2512       !IsDlgButtonChecked(hDlg, OPT_AVToFile)) {\r
2513     CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
2514   }\r
2515 \r
2516   state = state && IsDlgButtonChecked(hDlg, OPT_AVToFile);\r
2517   EnableWindow(GetDlgItem(hDlg, OPT_AVFilename), state);\r
2518   EnableWindow(GetDlgItem(hDlg, OPT_AVBrowse), state);\r
2519 }\r
2520 \r
2521 LRESULT CALLBACK\r
2522 SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2523 {\r
2524   char buf[MSG_SIZ];\r
2525   FILE *f;\r
2526 \r
2527   switch (message) {\r
2528   case WM_INITDIALOG: /* message: initialize dialog box */\r
2529     /* Center the dialog over the application window */\r
2530     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2531     Translate(hDlg, DLG_SaveOptions);\r
2532     /* Initialize the dialog items */\r
2533     if (*appData.saveGameFile != NULLCHAR) {\r
2534       CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
2535       CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVToFile);\r
2536       SetDlgItemText(hDlg, OPT_AVFilename, appData.saveGameFile);\r
2537     } else if (appData.autoSaveGames) {\r
2538       CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
2539       CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
2540     } else {\r
2541       CheckDlgButton(hDlg, OPT_Autosave, (UINT) FALSE);\r
2542     }\r
2543     if (appData.oldSaveStyle) {\r
2544       CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_Old);\r
2545     } else {\r
2546       CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_PGN);\r
2547     }\r
2548     CheckDlgButton( hDlg, OPT_OutOfBookInfo, appData.saveOutOfBookInfo );\r
2549     SetSaveOptionEnables(hDlg);\r
2550     return TRUE;\r
2551 \r
2552   case WM_COMMAND: /* message: received a command */\r
2553     switch (LOWORD(wParam)) {\r
2554     case IDOK:\r
2555       /* Read changed options from the dialog box */\r
2556       if (IsDlgButtonChecked(hDlg, OPT_Autosave)) {\r
2557         appData.autoSaveGames = TRUE;\r
2558         if (IsDlgButtonChecked(hDlg, OPT_AVPrompt)) {\r
2559           ASSIGN(appData.saveGameFile, ""); // [HGM] make sure value is ALWAYS in allocated memory\r
2560         } else /*if (IsDlgButtonChecked(hDlg, OPT_AVToFile))*/ {\r
2561           GetDlgItemText(hDlg, OPT_AVFilename, buf, MSG_SIZ);\r
2562           if (*buf == NULLCHAR) {\r
2563             MessageBox(hDlg, _("Invalid save game file name"),\r
2564                        _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2565             return FALSE;\r
2566           }\r
2567           FREE(appData.saveGameFile);\r
2568           appData.saveGameFile = InterpretFileName(buf, homeDir);\r
2569         }\r
2570       } else {\r
2571         appData.autoSaveGames = FALSE;\r
2572         ASSIGN(appData.saveGameFile, "");\r
2573       }\r
2574       appData.oldSaveStyle = IsDlgButtonChecked(hDlg, OPT_Old);\r
2575       appData.saveOutOfBookInfo = IsDlgButtonChecked( hDlg, OPT_OutOfBookInfo );\r
2576       EndDialog(hDlg, TRUE);\r
2577       return TRUE;\r
2578 \r
2579     case IDCANCEL:\r
2580       EndDialog(hDlg, FALSE);\r
2581       return TRUE;\r
2582 \r
2583     case OPT_AVBrowse:\r
2584       f = OpenFileDialog(hDlg, "a", NULL,\r
2585                          appData.oldSaveStyle ? "gam" : "pgn",\r
2586                          GAME_FILT, _("Browse for Auto Save File"),\r
2587                          NULL, NULL, buf);\r
2588       if (f != NULL) {\r
2589         fclose(f);\r
2590         SetDlgItemText(hDlg, OPT_AVFilename, buf);\r
2591       }\r
2592       break;\r
2593 \r
2594     default:\r
2595       SetSaveOptionEnables(hDlg);\r
2596       break;\r
2597     }\r
2598     break;\r
2599   }\r
2600   return FALSE;\r
2601 }\r
2602 \r
2603 VOID\r
2604 SaveOptionsPopup(HWND hwnd)\r
2605 {\r
2606   FARPROC lpProc = MakeProcInstance((FARPROC)SaveOptionsDialog, hInst);\r
2607   DialogBox(hInst, MAKEINTRESOURCE(DLG_SaveOptions), hwnd, (DLGPROC) lpProc);\r
2608   FreeProcInstance(lpProc);\r
2609 }\r
2610 \r
2611 /*---------------------------------------------------------------------------*\\r
2612  *\r
2613  * Time Control Options dialog functions\r
2614  *\r
2615 \*---------------------------------------------------------------------------*/\r
2616 \r
2617 VOID\r
2618 SetTimeControlEnables(HWND hDlg)\r
2619 {\r
2620   UINT state;\r
2621 \r
2622   state = IsDlgButtonChecked(hDlg, OPT_TCUseMoves)\r
2623         + 2*IsDlgButtonChecked(hDlg, OPT_TCUseFixed);\r
2624   EnableWindow(GetDlgItem(hDlg, OPT_TCTime), state == 1);\r
2625   EnableWindow(GetDlgItem(hDlg, OPT_TCMoves), state == 1);\r
2626   EnableWindow(GetDlgItem(hDlg, OPT_TCtext1), state == 1);\r
2627   EnableWindow(GetDlgItem(hDlg, OPT_TCtext2), state == 1);\r
2628   EnableWindow(GetDlgItem(hDlg, OPT_TCTime2), !state);\r
2629   EnableWindow(GetDlgItem(hDlg, OPT_TCInc), !state);\r
2630   EnableWindow(GetDlgItem(hDlg, OPT_TCitext1), !state);\r
2631   EnableWindow(GetDlgItem(hDlg, OPT_TCitext2), !state);\r
2632   EnableWindow(GetDlgItem(hDlg, OPT_TCitext3), !state);\r
2633   EnableWindow(GetDlgItem(hDlg, OPT_TCFixed), state == 2);\r
2634   EnableWindow(GetDlgItem(hDlg, OPT_TCftext), state == 2);\r
2635 }\r
2636 \r
2637 \r
2638 LRESULT CALLBACK\r
2639 TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2640 {\r
2641   char buf[MSG_SIZ], *tc;\r
2642   int mps, increment, odds1, odds2, st;\r
2643   BOOL ok, ok2;\r
2644 \r
2645   switch (message) {\r
2646   case WM_INITDIALOG: /* message: initialize dialog box */\r
2647     /* Center the dialog over the application window */\r
2648     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2649     Translate(hDlg, DLG_TimeControl);\r
2650     /* Initialize the dialog items */\r
2651     if (appData.clockMode && !appData.icsActive) {\r
2652       if (searchTime) {\r
2653         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2654                          OPT_TCUseFixed);\r
2655         SetDlgItemInt(hDlg, OPT_TCFixed, searchTime, FALSE);\r
2656       } else\r
2657       if (appData.timeIncrement == -1) {\r
2658         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2659                          OPT_TCUseMoves);\r
2660         SetDlgItemText(hDlg, OPT_TCTime, appData.timeControl);\r
2661         SetDlgItemInt(hDlg, OPT_TCMoves, appData.movesPerSession,\r
2662                       FALSE);\r
2663         SetDlgItemText(hDlg, OPT_TCTime2, "");\r
2664         SetDlgItemText(hDlg, OPT_TCInc, "");\r
2665       } else {\r
2666         CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
2667                          OPT_TCUseInc);\r
2668         SetDlgItemText(hDlg, OPT_TCTime, "");\r
2669         SetDlgItemText(hDlg, OPT_TCMoves, "");\r
2670         SetDlgItemText(hDlg, OPT_TCTime2, appData.timeControl);\r
2671         SetDlgItemInt(hDlg, OPT_TCInc, appData.timeIncrement, FALSE);\r
2672       }\r
2673       SetDlgItemInt(hDlg, OPT_TCOdds1, 1, FALSE);\r
2674       SetDlgItemInt(hDlg, OPT_TCOdds2, 1, FALSE);\r
2675       SetTimeControlEnables(hDlg);\r
2676     }\r
2677     return TRUE;\r
2678 \r
2679   case WM_COMMAND: /* message: received a command */\r
2680     switch (LOWORD(wParam)) {\r
2681     case IDOK:\r
2682       mps = appData.movesPerSession;\r
2683       increment = appData.timeIncrement;\r
2684       tc = appData.timeControl;\r
2685       st = 0;\r
2686       /* Read changed options from the dialog box */\r
2687       if (IsDlgButtonChecked(hDlg, OPT_TCUseFixed)) {\r
2688         st = GetDlgItemInt(hDlg, OPT_TCFixed, &ok, FALSE);\r
2689         if (!ok || st <= 0) {\r
2690           MessageBox(hDlg, _("Invalid max time per move"),\r
2691                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2692           return FALSE;\r
2693         }\r
2694       } else\r
2695       if (IsDlgButtonChecked(hDlg, OPT_TCUseMoves)) {\r
2696         increment = -1;\r
2697         mps = GetDlgItemInt(hDlg, OPT_TCMoves, &ok, FALSE);\r
2698         if (!ok || mps <= 0) {\r
2699           MessageBox(hDlg, _("Invalid moves per time control"),\r
2700                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2701           return FALSE;\r
2702         }\r
2703         GetDlgItemText(hDlg, OPT_TCTime, buf, MSG_SIZ);\r
2704         if (!ParseTimeControl(buf, increment, mps)) {\r
2705           MessageBox(hDlg, _("Invalid minutes per time control"),\r
2706                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2707           return FALSE;\r
2708         }\r
2709       tc = buf;\r
2710       } else {\r
2711         increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE);\r
2712         if (!ok || increment < 0) {\r
2713           MessageBox(hDlg, _("Invalid increment"),\r
2714                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2715           return FALSE;\r
2716         }\r
2717         GetDlgItemText(hDlg, OPT_TCTime2, buf, MSG_SIZ);\r
2718         if (!ParseTimeControl(buf, increment, mps)) {\r
2719           MessageBox(hDlg, _("Invalid initial time"),\r
2720                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2721           return FALSE;\r
2722         }\r
2723       tc = buf;\r
2724       }\r
2725       odds1 = GetDlgItemInt(hDlg, OPT_TCOdds1, &ok, FALSE);\r
2726       odds2 = GetDlgItemInt(hDlg, OPT_TCOdds2, &ok2, FALSE);\r
2727       if (!ok || !ok2 || odds1 <= 0 || odds2 <= 0) {\r
2728           MessageBox(hDlg, _("Invalid time-odds factor"),\r
2729                      _("Option Error"), MB_OK|MB_ICONEXCLAMATION);\r
2730           return FALSE;\r
2731       }\r
2732       searchTime = st;\r
2733       appData.timeControl = strdup(tc);\r
2734       appData.movesPerSession = mps;\r
2735       appData.timeIncrement = increment;\r
2736       appData.firstTimeOdds  = first.timeOdds  = odds1;\r
2737       appData.secondTimeOdds = second.timeOdds = odds2;\r
2738       Reset(TRUE, TRUE);\r
2739       EndDialog(hDlg, TRUE);\r
2740       return TRUE;\r
2741 \r
2742     case IDCANCEL:\r
2743       EndDialog(hDlg, FALSE);\r
2744       return TRUE;\r
2745 \r
2746     default:\r
2747       SetTimeControlEnables(hDlg);\r
2748       break;\r
2749     }\r
2750     break;\r
2751   }\r
2752   return FALSE;\r
2753 }\r
2754 \r
2755 VOID\r
2756 TimeControlOptionsPopup(HWND hwnd)\r
2757 {\r
2758   if (gameMode != BeginningOfGame) {\r
2759     DisplayError(_("Changing time control during a game is not implemented"), 0);\r
2760   } else {\r
2761     FARPROC lpProc = MakeProcInstance((FARPROC)TimeControl, hInst);\r
2762     DialogBox(hInst, MAKEINTRESOURCE(DLG_TimeControl), hwnd, (DLGPROC) lpProc);\r
2763     FreeProcInstance(lpProc);\r
2764   }\r
2765 }\r
2766 \r
2767 /*---------------------------------------------------------------------------*\\r
2768  *\r
2769  * Engine Options Dialog functions\r
2770  *\r
2771 \*---------------------------------------------------------------------------*/\r
2772 #define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
2773 #define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
2774 \r
2775 #define INT_ABS( n )    ((n) >= 0 ? (n) : -(n))\r
2776 \r
2777 LRESULT CALLBACK EnginePlayOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2778 {\r
2779   switch (message) {\r
2780   case WM_INITDIALOG: /* message: initialize dialog box */\r
2781 \r
2782     /* Center the dialog over the application window */\r
2783     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2784     Translate(hDlg, DLG_EnginePlayOptions);\r
2785 \r
2786     /* Initialize the dialog items */\r
2787     CHECK_BOX(IDC_EpPeriodicUpdates, appData.periodicUpdates);\r
2788     CHECK_BOX(IDC_EpPonder, appData.ponderNextMove);\r
2789     CHECK_BOX(IDC_EpShowThinking, appData.showThinking);\r
2790     CHECK_BOX(IDC_EpHideThinkingHuman, appData.hideThinkingFromHuman);\r
2791 \r
2792     CHECK_BOX(IDC_TestClaims, appData.testClaims);\r
2793     CHECK_BOX(IDC_DetectMates, appData.checkMates);\r
2794     CHECK_BOX(IDC_MaterialDraws, appData.materialDraws);\r
2795     CHECK_BOX(IDC_TrivialDraws, appData.trivialDraws);\r
2796 \r
2797     CHECK_BOX(IDC_ScoreAbs1, appData.firstScoreIsAbsolute);\r
2798     CHECK_BOX(IDC_ScoreAbs2, appData.secondScoreIsAbsolute);\r
2799 \r
2800     SetDlgItemInt( hDlg, IDC_EpDrawMoveCount, appData.adjudicateDrawMoves, TRUE );\r
2801     SendDlgItemMessage( hDlg, IDC_EpDrawMoveCount, EM_SETSEL, 0, -1 );\r
2802 \r
2803     SetDlgItemInt( hDlg, IDC_EpAdjudicationThreshold, INT_ABS(appData.adjudicateLossThreshold), TRUE );\r
2804     SendDlgItemMessage( hDlg, IDC_EpAdjudicationThreshold, EM_SETSEL, 0, -1 );\r
2805 \r
2806     SetDlgItemInt( hDlg, IDC_RuleMoves, appData.ruleMoves, TRUE );\r
2807     SendDlgItemMessage( hDlg, IDC_RuleMoves, EM_SETSEL, 0, -1 );\r
2808 \r
2809     SetDlgItemInt( hDlg, IDC_DrawRepeats, INT_ABS(appData.drawRepeats), TRUE );\r
2810     SendDlgItemMessage( hDlg, IDC_DrawRepeats, EM_SETSEL, 0, -1 );\r
2811 \r
2812     return TRUE;\r
2813 \r
2814   case WM_COMMAND: /* message: received a command */\r
2815     switch (LOWORD(wParam)) {\r
2816     case IDOK:\r
2817       /* Read changed options from the dialog box */\r
2818       PeriodicUpdatesEvent(          IS_CHECKED(IDC_EpPeriodicUpdates));\r
2819       PonderNextMoveEvent(           IS_CHECKED(IDC_EpPonder));\r
2820       appData.hideThinkingFromHuman= IS_CHECKED(IDC_EpHideThinkingHuman); // [HGM] thinking: moved up\r
2821       appData.showThinking   = IS_CHECKED(IDC_EpShowThinking);\r
2822       ShowThinkingEvent(); // [HGM] thinking: tests all options that need thinking output\r
2823       appData.testClaims    = IS_CHECKED(IDC_TestClaims);\r
2824       appData.checkMates    = IS_CHECKED(IDC_DetectMates);\r
2825       appData.materialDraws = IS_CHECKED(IDC_MaterialDraws);\r
2826       appData.trivialDraws  = IS_CHECKED(IDC_TrivialDraws);\r
2827 \r
2828       appData.adjudicateDrawMoves = GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, NULL, FALSE );\r
2829       appData.adjudicateLossThreshold = - (int) GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, NULL, FALSE );\r
2830       appData.ruleMoves = GetDlgItemInt(hDlg, IDC_RuleMoves, NULL, FALSE );\r
2831       appData.drawRepeats = (int) GetDlgItemInt(hDlg, IDC_DrawRepeats, NULL, FALSE );\r
2832 \r
2833       first.scoreIsAbsolute  = appData.firstScoreIsAbsolute  = IS_CHECKED(IDC_ScoreAbs1);\r
2834       second.scoreIsAbsolute = appData.secondScoreIsAbsolute = IS_CHECKED(IDC_ScoreAbs2);\r
2835 \r
2836       EndDialog(hDlg, TRUE);\r
2837       return TRUE;\r
2838 \r
2839     case IDCANCEL:\r
2840       EndDialog(hDlg, FALSE);\r
2841       return TRUE;\r
2842 \r
2843     case IDC_EpDrawMoveCount:\r
2844     case IDC_EpAdjudicationThreshold:\r
2845     case IDC_DrawRepeats:\r
2846     case IDC_RuleMoves:\r
2847         if( HIWORD(wParam) == EN_CHANGE ) {\r
2848             int n1_ok;\r
2849             int n2_ok;\r
2850             int n3_ok;\r
2851             int n4_ok;\r
2852 \r
2853             GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, &n1_ok, FALSE );\r
2854             GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, &n2_ok, FALSE );\r
2855             GetDlgItemInt(hDlg, IDC_RuleMoves, &n3_ok, FALSE );\r
2856             GetDlgItemInt(hDlg, IDC_DrawRepeats, &n4_ok, FALSE );\r
2857 \r
2858             EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok && n4_ok ? TRUE : FALSE );\r
2859         }\r
2860         return TRUE;\r
2861     }\r
2862     break;\r
2863   }\r
2864   return FALSE;\r
2865 }\r
2866 \r
2867 VOID EnginePlayOptionsPopup(HWND hwnd)\r
2868 {\r
2869   FARPROC lpProc;\r
2870 \r
2871   lpProc = MakeProcInstance((FARPROC)EnginePlayOptionsDialog, hInst);\r
2872   DialogBox(hInst, MAKEINTRESOURCE(DLG_EnginePlayOptions), hwnd, (DLGPROC) lpProc);\r
2873   FreeProcInstance(lpProc);\r
2874 }\r
2875 \r
2876 /*---------------------------------------------------------------------------*\\r
2877  *\r
2878  * UCI Options Dialog functions\r
2879  *\r
2880 \*---------------------------------------------------------------------------*/\r
2881 BOOL BrowseForFolder( const char * title, char * path )\r
2882 {\r
2883     BOOL result = FALSE;\r
2884     BROWSEINFO bi;\r
2885     LPITEMIDLIST pidl;\r
2886 \r
2887     ZeroMemory( &bi, sizeof(bi) );\r
2888 \r
2889     bi.lpszTitle = title == 0 ? _("Choose Folder") : title;\r
2890     bi.ulFlags = BIF_RETURNONLYFSDIRS;\r
2891 \r
2892     pidl = SHBrowseForFolder( &bi );\r
2893 \r
2894     if( pidl != 0 ) {\r
2895         IMalloc * imalloc = 0;\r
2896 \r
2897         if( SHGetPathFromIDList( pidl, path ) ) {\r
2898             result = TRUE;\r
2899         }\r
2900 \r
2901         if( SUCCEEDED( SHGetMalloc ( &imalloc ) ) ) {\r
2902             imalloc->lpVtbl->Free(imalloc,pidl);\r
2903             imalloc->lpVtbl->Release(imalloc);\r
2904         }\r
2905     }\r
2906 \r
2907     return result;\r
2908 }\r
2909 \r
2910 LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2911 {\r
2912   char buf[MAX_PATH];\r
2913   int oldCores;\r
2914 \r
2915   switch (message) {\r
2916   case WM_INITDIALOG: /* message: initialize dialog box */\r
2917 \r
2918     /* Center the dialog over the application window */\r
2919     CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
2920     Translate(hDlg, DLG_OptionsUCI);\r
2921 \r
2922     /* Initialize the dialog items */\r
2923     SetDlgItemText( hDlg, IDC_PolyglotDir, appData.polyglotDir );\r
2924     SetDlgItemInt( hDlg, IDC_HashSize, appData.defaultHashSize, TRUE );\r
2925     SetDlgItemText( hDlg, IDC_PathToEGTB, appData.defaultPathEGTB );\r
2926     SetDlgItemInt( hDlg, IDC_SizeOfEGTB, appData.defaultCacheSizeEGTB, TRUE );\r
2927     CheckDlgButton( hDlg, IDC_UseBook, (BOOL) appData.usePolyglotBook );\r
2928     SetDlgItemText( hDlg, IDC_BookFile, appData.polyglotBook );\r
2929     // [HGM] smp: input field for nr of cores:\r
2930     SetDlgItemInt( hDlg, IDC_Cores, appData.smpCores, TRUE );\r
2931     // [HGM] book: tick boxes for own book use\r
2932     CheckDlgButton( hDlg, IDC_OwnBook1, (BOOL) appData.firstHasOwnBookUCI );\r
2933     CheckDlgButton( hDlg, IDC_OwnBook2, (BOOL) appData.secondHasOwnBookUCI );\r
2934     SetDlgItemInt( hDlg, IDC_BookDep, appData.bookDepth, TRUE );\r
2935     SetDlgItemInt( hDlg, IDC_BookStr, appData.bookStrength, TRUE );\r
2936     SetDlgItemInt( hDlg, IDC_Games, appData.defaultMatchGames, TRUE );\r
2937 \r
2938     SendDlgItemMessage( hDlg, IDC_PolyglotDir, EM_SETSEL, 0, -1 );\r
2939 \r
2940     return TRUE;\r
2941 \r
2942   case WM_COMMAND: /* message: received a command */\r
2943     switch (LOWORD(wParam)) {\r
2944     case IDOK:\r
2945       GetDlgItemText( hDlg, IDC_PolyglotDir, buf, sizeof(buf) );\r
2946       appData.polyglotDir = strdup(buf);\r
2947       appData.defaultHashSize = GetDlgItemInt(hDlg, IDC_HashSize, NULL, FALSE );\r
2948       appData.defaultCacheSizeEGTB = GetDlgItemInt(hDlg, IDC_SizeOfEGTB, NULL, FALSE );\r
2949       GetDlgItemText( hDlg, IDC_PathToEGTB, buf, sizeof(buf) );\r
2950       appData.defaultPathEGTB = strdup(buf);\r
2951       GetDlgItemText( hDlg, IDC_BookFile, buf, sizeof(buf) );\r
2952       appData.polyglotBook = strdup(buf);\r
2953       appData.usePolyglotBook = (Boolean) IsDlgButtonChecked( hDlg, IDC_UseBook );\r
2954       // [HGM] smp: get nr of cores:\r
2955       oldCores = appData.smpCores;\r
2956       appData.smpCores = GetDlgItemInt(hDlg, IDC_Cores, NULL, FALSE );\r
2957       if(appData.smpCores != oldCores) NewSettingEvent(FALSE, &(first.maxCores), "cores", appData.smpCores);\r
2958       // [HGM] book: read tick boxes for own book use\r
2959       appData.firstHasOwnBookUCI  = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook1 );\r
2960       appData.secondHasOwnBookUCI = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook2 );\r
2961       appData.bookDepth = GetDlgItemInt(hDlg, IDC_BookDep, NULL, FALSE );\r
2962       appData.bookStrength = GetDlgItemInt(hDlg, IDC_BookStr, NULL, FALSE );\r
2963       appData.defaultMatchGames = GetDlgItemInt(hDlg, IDC_Games, NULL, FALSE );\r
2964 \r
2965       if(gameMode == BeginningOfGame) Reset(TRUE, TRUE);\r
2966       EndDialog(hDlg, TRUE);\r
2967       return TRUE;\r
2968 \r
2969     case IDCANCEL:\r
2970       EndDialog(hDlg, FALSE);\r
2971       return TRUE;\r
2972 \r
2973     case IDC_BrowseForBook:\r
2974       {\r
2975           char filter[] = {\r
2976               'A','l','l',' ','F','i','l','e','s', 0,\r
2977               '*','.','*', 0,\r
2978               'B','I','N',' ','F','i','l','e','s', 0,\r
2979               '*','.','b','i','n', 0,\r
2980               0 };\r
2981 \r
2982           OPENFILENAME ofn;\r
2983 \r
2984           safeStrCpy( buf, "" , sizeof( buf)/sizeof( buf[0]) );\r
2985 \r
2986           ZeroMemory( &ofn, sizeof(ofn) );\r
2987 \r
2988           ofn.lStructSize = sizeof(ofn);\r
2989           ofn.hwndOwner = hDlg;\r
2990           ofn.hInstance = hInst;\r
2991           ofn.lpstrFilter = filter;\r
2992           ofn.lpstrFile = buf;\r
2993           ofn.nMaxFile = sizeof(buf);\r
2994           ofn.lpstrTitle = _("Choose Book");\r
2995           ofn.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_HIDEREADONLY;\r
2996 \r
2997           if( GetOpenFileName( &ofn ) ) {\r
2998               SetDlgItemText( hDlg, IDC_BookFile, buf );\r
2999           }\r
3000       }\r
3001       return TRUE;\r
3002 \r
3003     case IDC_BrowseForPolyglotDir:\r
3004       if( BrowseForFolder( _("Choose Polyglot Directory"), buf ) ) {\r
3005         SetDlgItemText( hDlg, IDC_PolyglotDir, buf );\r
3006 \r
3007         strcat( buf, "\\polyglot.exe" );\r
3008 \r
3009         if( GetFileAttributes(buf) == 0xFFFFFFFF ) {\r
3010             MessageBox( hDlg, _("Polyglot was not found in the specified folder!"), "Warning", MB_OK | MB_ICONWARNING );\r
3011         }\r
3012       }\r
3013       return TRUE;\r
3014 \r
3015     case IDC_BrowseForEGTB:\r
3016       if( BrowseForFolder( _("Choose EGTB Directory:"), buf ) ) {\r
3017         SetDlgItemText( hDlg, IDC_PathToEGTB, buf );\r
3018       }\r
3019       return TRUE;\r
3020 \r
3021     case IDC_HashSize:\r
3022     case IDC_SizeOfEGTB:\r
3023         if( HIWORD(wParam) == EN_CHANGE ) {\r
3024             int n1_ok;\r
3025             int n2_ok;\r
3026 \r
3027             GetDlgItemInt(hDlg, IDC_HashSize, &n1_ok, FALSE );\r
3028             GetDlgItemInt(hDlg, IDC_SizeOfEGTB, &n2_ok, FALSE );\r
3029 \r
3030             EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok ? TRUE : FALSE );\r
3031         }\r
3032         return TRUE;\r
3033     }\r
3034     break;\r
3035   }\r
3036   return FALSE;\r
3037 }\r
3038 \r
3039 VOID UciOptionsPopup(HWND hwnd)\r
3040 {\r
3041   FARPROC lpProc;\r
3042 \r
3043   lpProc = MakeProcInstance((FARPROC)UciOptionsDialog, hInst);\r
3044   DialogBox(hInst, MAKEINTRESOURCE(DLG_OptionsUCI), hwnd, (DLGPROC) lpProc);\r
3045   FreeProcInstance(lpProc);\r
3046 }\r