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