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