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