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