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