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