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