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