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