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