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