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