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