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