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