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