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