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