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