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