c4360fc2da29dbd52a047ef6f39f7041e67a1a4f
[xboard.git] / xboard.c
1 /*
2  * xboard.c -- X front end for XBoard
3  * $Id: xboard.c,v 2.2 2003/11/06 07:22:14 mann Exp $
4  *
5  * Copyright 1991 by Digital Equipment Corporation, Maynard,
6  * Massachusetts.  Enhancements Copyright
7  * 1992-2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software
8  * Foundation, Inc.
9  *
10  * The following terms apply to Digital Equipment Corporation's copyright
11  * interest in XBoard:
12  * ------------------------------------------------------------------------
13  * All Rights Reserved
14  *
15  * Permission to use, copy, modify, and distribute this software and its
16  * documentation for any purpose and without fee is hereby granted,
17  * provided that the above copyright notice appear in all copies and that
18  * both that copyright notice and this permission notice appear in
19  * supporting documentation, and that the name of Digital not be
20  * used in advertising or publicity pertaining to distribution of the
21  * software without specific, written prior permission.
22  *
23  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
25  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
26  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
27  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
28  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
29  * SOFTWARE.
30  * ------------------------------------------------------------------------
31  *
32  * The following terms apply to the enhanced version of XBoard
33  * distributed by the Free Software Foundation:
34  * ------------------------------------------------------------------------
35  *
36  * GNU XBoard is free software: you can redistribute it and/or modify
37  * it under the terms of the GNU General Public License as published by
38  * the Free Software Foundation, either version 3 of the License, or (at
39  * your option) any later version.
40  *
41  * GNU XBoard is distributed in the hope that it will be useful, but
42  * WITHOUT ANY WARRANTY; without even the implied warranty of
43  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44  * General Public License for more details.
45  *
46  * You should have received a copy of the GNU General Public License
47  * along with this program. If not, see http://www.gnu.org/licenses/.  *
48  *
49  *------------------------------------------------------------------------
50  ** See the file ChangeLog for a revision history.  */
51
52 #include "config.h"
53
54 #include <stdio.h>
55 #include <ctype.h>
56 #include <signal.h>
57 #include <errno.h>
58 #include <sys/types.h>
59 #include <sys/stat.h>
60 #include <pwd.h>
61
62 #if !OMIT_SOCKETS
63 # if HAVE_SYS_SOCKET_H
64 #  include <sys/socket.h>
65 #  include <netinet/in.h>
66 #  include <netdb.h>
67 # else /* not HAVE_SYS_SOCKET_H */
68 #  if HAVE_LAN_SOCKET_H
69 #   include <lan/socket.h>
70 #   include <lan/in.h>
71 #   include <lan/netdb.h>
72 #  else /* not HAVE_LAN_SOCKET_H */
73 #   define OMIT_SOCKETS 1
74 #  endif /* not HAVE_LAN_SOCKET_H */
75 # endif /* not HAVE_SYS_SOCKET_H */
76 #endif /* !OMIT_SOCKETS */
77
78 #if STDC_HEADERS
79 # include <stdlib.h>
80 # include <string.h>
81 #else /* not STDC_HEADERS */
82 extern char *getenv();
83 # if HAVE_STRING_H
84 #  include <string.h>
85 # else /* not HAVE_STRING_H */
86 #  include <strings.h>
87 # endif /* not HAVE_STRING_H */
88 #endif /* not STDC_HEADERS */
89
90 #if HAVE_SYS_FCNTL_H
91 # include <sys/fcntl.h>
92 #else /* not HAVE_SYS_FCNTL_H */
93 # if HAVE_FCNTL_H
94 #  include <fcntl.h>
95 # endif /* HAVE_FCNTL_H */
96 #endif /* not HAVE_SYS_FCNTL_H */
97
98 #if HAVE_SYS_SYSTEMINFO_H
99 # include <sys/systeminfo.h>
100 #endif /* HAVE_SYS_SYSTEMINFO_H */
101
102 #if TIME_WITH_SYS_TIME
103 # include <sys/time.h>
104 # include <time.h>
105 #else
106 # if HAVE_SYS_TIME_H
107 #  include <sys/time.h>
108 # else
109 #  include <time.h>
110 # endif
111 #endif
112
113 #if HAVE_UNISTD_H
114 # include <unistd.h>
115 #endif
116
117 #if HAVE_SYS_WAIT_H
118 # include <sys/wait.h>
119 #endif
120
121 #if HAVE_DIRENT_H
122 # include <dirent.h>
123 # define NAMLEN(dirent) strlen((dirent)->d_name)
124 # define HAVE_DIR_STRUCT
125 #else
126 # define dirent direct
127 # define NAMLEN(dirent) (dirent)->d_namlen
128 # if HAVE_SYS_NDIR_H
129 #  include <sys/ndir.h>
130 #  define HAVE_DIR_STRUCT
131 # endif
132 # if HAVE_SYS_DIR_H
133 #  include <sys/dir.h>
134 #  define HAVE_DIR_STRUCT
135 # endif
136 # if HAVE_NDIR_H
137 #  include <ndir.h>
138 #  define HAVE_DIR_STRUCT
139 # endif
140 #endif
141
142 #include <X11/Intrinsic.h>
143 #include <X11/StringDefs.h>
144 #include <X11/Shell.h>
145 #include <X11/cursorfont.h>
146 #include <X11/Xatom.h>
147 #if USE_XAW3D
148 #include <X11/Xaw3d/Dialog.h>
149 #include <X11/Xaw3d/Form.h>
150 #include <X11/Xaw3d/List.h>
151 #include <X11/Xaw3d/Label.h>
152 #include <X11/Xaw3d/SimpleMenu.h>
153 #include <X11/Xaw3d/SmeBSB.h>
154 #include <X11/Xaw3d/SmeLine.h>
155 #include <X11/Xaw3d/Box.h>
156 #include <X11/Xaw3d/MenuButton.h>
157 #include <X11/Xaw3d/Text.h>
158 #include <X11/Xaw3d/AsciiText.h>
159 #else
160 #include <X11/Xaw/Dialog.h>
161 #include <X11/Xaw/Form.h>
162 #include <X11/Xaw/List.h>
163 #include <X11/Xaw/Label.h>
164 #include <X11/Xaw/SimpleMenu.h>
165 #include <X11/Xaw/SmeBSB.h>
166 #include <X11/Xaw/SmeLine.h>
167 #include <X11/Xaw/Box.h>
168 #include <X11/Xaw/MenuButton.h>
169 #include <X11/Xaw/Text.h>
170 #include <X11/Xaw/AsciiText.h>
171 #endif
172
173 // [HGM] bitmaps: put before incuding the bitmaps / pixmaps, to know how many piece types there are.
174 #include "common.h"
175
176 #if HAVE_LIBXPM
177 #include <X11/xpm.h>
178 #include "pixmaps/pixmaps.h"
179 #define IMAGE_EXT "xpm"
180 #else
181 #define IMAGE_EXT "xim"
182 #include "bitmaps/bitmaps.h"
183 #endif
184
185 #include "bitmaps/icon_white.bm"
186 #include "bitmaps/icon_black.bm"
187 #include "bitmaps/checkmark.bm"
188
189 #include "frontend.h"
190 #include "backend.h"
191 #include "moves.h"
192 #include "xboard.h"
193 #include "childio.h"
194 #include "xgamelist.h"
195 #include "xhistory.h"
196 #include "xedittags.h"
197 #include "gettext.h"
198
199 // must be moved to xengineoutput.h
200
201 void EngineOutputProc P((Widget w, XEvent *event,
202  String *prms, Cardinal *nprms));
203
204 void EngineOutputPopDown();
205
206
207 #ifdef __EMX__
208 #ifndef HAVE_USLEEP
209 #define HAVE_USLEEP
210 #endif
211 #define usleep(t)   _sleep2(((t)+500)/1000)
212 #endif
213
214 #ifdef ENABLE_NLS
215 # define  _(s) gettext (s)
216 # define N_(s) gettext_noop (s)
217 #else
218 # define  _(s) (s)
219 # define N_(s)  s
220 #endif
221
222 typedef struct {
223     String string;
224     XtActionProc proc;
225 } MenuItem;
226
227 typedef struct {
228     String name;
229     MenuItem *mi;
230 } Menu;
231
232 int main P((int argc, char **argv));
233 RETSIGTYPE CmailSigHandler P((int sig));
234 RETSIGTYPE IntSigHandler P((int sig));
235 void CreateGCs P((void));
236 void CreateXIMPieces P((void));
237 void CreateXPMPieces P((void));
238 void CreatePieces P((void));
239 void CreatePieceMenus P((void));
240 Widget CreateMenuBar P((Menu *mb));
241 Widget CreateButtonBar P ((MenuItem *mi));
242 char *FindFont P((char *pattern, int targetPxlSize));
243 void PieceMenuPopup P((Widget w, XEvent *event,
244                        String *params, Cardinal *num_params));
245 static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
246 static void DropMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
247 void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[],
248                    u_int wreq, u_int hreq));
249 void CreateGrid P((void));
250 int EventToSquare P((int x, int limit));
251 void DrawSquare P((int row, int column, ChessSquare piece, int do_flash));
252 void EventProc P((Widget widget, caddr_t unused, XEvent *event));
253 void HandleUserMove P((Widget w, XEvent *event,
254                      String *prms, Cardinal *nprms));
255 void AnimateUserMove P((Widget w, XEvent * event,
256                      String * params, Cardinal * nParams));
257 void WhiteClock P((Widget w, XEvent *event,
258                    String *prms, Cardinal *nprms));
259 void BlackClock P((Widget w, XEvent *event,
260                    String *prms, Cardinal *nprms));
261 void DrawPositionProc P((Widget w, XEvent *event,
262                      String *prms, Cardinal *nprms));
263 void XDrawPosition P((Widget w, /*Boolean*/int repaint,
264                      Board board));
265 void CommentPopUp P((char *title, char *label));
266 void CommentPopDown P((void));
267 void CommentCallback P((Widget w, XtPointer client_data,
268                         XtPointer call_data));
269 void ICSInputBoxPopUp P((void));
270 void ICSInputBoxPopDown P((void));
271 void FileNamePopUp P((char *label, char *def,
272                       FileProc proc, char *openMode));
273 void FileNamePopDown P((void));
274 void FileNameCallback P((Widget w, XtPointer client_data,
275                          XtPointer call_data));
276 void FileNameAction P((Widget w, XEvent *event,
277                        String *prms, Cardinal *nprms));
278 void AskQuestionReplyAction P((Widget w, XEvent *event,
279                           String *prms, Cardinal *nprms));
280 void AskQuestionProc P((Widget w, XEvent *event,
281                           String *prms, Cardinal *nprms));
282 void AskQuestionPopDown P((void));
283 void PromotionPopUp P((void));
284 void PromotionPopDown P((void));
285 void PromotionCallback P((Widget w, XtPointer client_data,
286                           XtPointer call_data));
287 void EditCommentPopDown P((void));
288 void EditCommentCallback P((Widget w, XtPointer client_data,
289                             XtPointer call_data));
290 void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
291 void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
292 void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
293 void LoadNextGameProc P((Widget w, XEvent *event, String *prms,
294                          Cardinal *nprms));
295 void LoadPrevGameProc P((Widget w, XEvent *event, String *prms,
296                          Cardinal *nprms));
297 void ReloadGameProc P((Widget w, XEvent *event, String *prms,
298                        Cardinal *nprms));
299 void LoadPositionProc P((Widget w, XEvent *event,
300                          String *prms, Cardinal *nprms));
301 void LoadNextPositionProc P((Widget w, XEvent *event, String *prms,
302                          Cardinal *nprms));
303 void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms,
304                          Cardinal *nprms));
305 void ReloadPositionProc P((Widget w, XEvent *event, String *prms,
306                        Cardinal *nprms));
307 void CopyPositionProc P((Widget w, XEvent *event, String *prms,
308                          Cardinal *nprms));
309 void PastePositionProc P((Widget w, XEvent *event, String *prms,
310                           Cardinal *nprms));
311 void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
312 void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
313 void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
314 void SavePositionProc P((Widget w, XEvent *event,
315                          String *prms, Cardinal *nprms));
316 void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
317 void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms,
318                             Cardinal *nprms));
319 void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
320 void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
321 void MachineBlackProc P((Widget w, XEvent *event, String *prms,
322                          Cardinal *nprms));
323 void MachineWhiteProc P((Widget w, XEvent *event,
324                          String *prms, Cardinal *nprms));
325 void AnalyzeModeProc P((Widget w, XEvent *event,
326                          String *prms, Cardinal *nprms));
327 void AnalyzeFileProc P((Widget w, XEvent *event,
328                          String *prms, Cardinal *nprms));
329 void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
330                         Cardinal *nprms));
331 void IcsClientProc P((Widget w, XEvent *event, String *prms,
332                       Cardinal *nprms));
333 void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
334 void EditPositionProc P((Widget w, XEvent *event,
335                          String *prms, Cardinal *nprms));
336 void TrainingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
337 void EditCommentProc P((Widget w, XEvent *event,
338                         String *prms, Cardinal *nprms));
339 void IcsInputBoxProc P((Widget w, XEvent *event,
340                         String *prms, Cardinal *nprms));
341 void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
342 void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
343 void RematchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
344 void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
345 void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
346 void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
347 void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
348 void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
349 void AdjuWhiteProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
350 void AdjuBlackProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
351 void AdjuDrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
352 void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
353 void StopObservingProc P((Widget w, XEvent *event, String *prms,
354                           Cardinal *nprms));
355 void StopExaminingProc P((Widget w, XEvent *event, String *prms,
356                           Cardinal *nprms));
357 void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
358 void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
359 void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
360 void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
361 void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
362 void TruncateGameProc P((Widget w, XEvent *event, String *prms,
363                          Cardinal *nprms));
364 void RetractMoveProc P((Widget w, XEvent *event, String *prms,
365                         Cardinal *nprms));
366 void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
367 void AlwaysQueenProc P((Widget w, XEvent *event, String *prms,
368                         Cardinal *nprms));
369 void AnimateDraggingProc P((Widget w, XEvent *event, String *prms,
370                          Cardinal *nprms));
371 void AnimateMovingProc P((Widget w, XEvent *event, String *prms,
372                          Cardinal *nprms));
373 void AutocommProc P((Widget w, XEvent *event, String *prms,
374                      Cardinal *nprms));
375 void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
376 void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
377 void AutobsProc P((Widget w, XEvent *event, String *prms,
378                         Cardinal *nprms));
379 void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
380 void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
381 void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
382 void FlashMovesProc P((Widget w, XEvent *event, String *prms,
383                        Cardinal *nprms));
384 void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
385 void GetMoveListProc P((Widget w, XEvent *event, String *prms,
386                         Cardinal *nprms));
387 void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
388                               Cardinal *nprms));
389 void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
390                               Cardinal *nprms));
391 void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
392 void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
393 void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
394                          Cardinal *nprms));
395 void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
396                          Cardinal *nprms));
397 void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
398                            Cardinal *nprms));
399 void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms,
400                         Cardinal *nprms));
401 void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
402                              Cardinal *nprms));
403 void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
404 void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
405 void ShowCoordsProc P((Widget w, XEvent *event, String *prms,
406                        Cardinal *nprms));
407 void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
408                          Cardinal *nprms));
409 void HideThinkingProc P((Widget w, XEvent *event, String *prms,
410                          Cardinal *nprms));
411 void TestLegalityProc P((Widget w, XEvent *event, String *prms,
412                           Cardinal *nprms));
413 void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
414 void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
415 void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
416 void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
417 void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
418 void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
419 void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
420 void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
421 void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
422 void DisplayMove P((int moveNumber));
423 void DisplayTitle P((char *title));
424 void ICSInitScript P((void));
425 int LoadGamePopUp P((FILE *f, int gameNumber, char *title));
426 void ErrorPopUp P((char *title, char *text, int modal));
427 void ErrorPopDown P((void));
428 static char *ExpandPathName P((char *path));
429 static void CreateAnimVars P((void));
430 static void DragPieceBegin P((int x, int y));
431 static void DragPieceMove P((int x, int y));
432 static void DragPieceEnd P((int x, int y));
433 static void DrawDragPiece P((void));
434 char *ModeToWidgetName P((GameMode mode));
435 void EngineOutputUpdate( FrontEndProgramStats * stats );
436 void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
437 void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
438 void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
439 void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
440 void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
441 void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
442 void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
443 void ShufflePopDown P(());
444 void EnginePopDown P(());
445 void UciPopDown P(());
446 void TimeControlPopDown P(());
447 void NewVariantPopDown P(());
448 void SettingsPopDown P(());
449 /*
450 * XBoard depends on Xt R4 or higher
451 */
452 int xtVersion = XtSpecificationRelease;
453
454 int xScreen;
455 Display *xDisplay;
456 Window xBoardWindow;
457 Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
458   jailSquareColor, highlightSquareColor, premoveHighlightColor;
459 GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,
460   bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
461   wjPieceGC, bjPieceGC, prelineGC, countGC;
462 Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
463 Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
464   whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16],
465   commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,
466   menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
467   ICSInputShell, fileNameShell, askQuestionShell;
468 XSegment gridSegments[(BOARD_SIZE + 1) * 2];
469 XSegment jailGridSegments[(BOARD_SIZE + 3) * 2];
470 Font clockFontID, coordFontID, countFontID;
471 XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
472 XtAppContext appContext;
473 char *layoutName;
474 char *oldICSInteractionTitle;
475
476 FileProc fileProc;
477 char *fileOpenMode;
478 char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion
479
480 Position commentX = -1, commentY = -1;
481 Dimension commentW, commentH;
482
483 int squareSize, smallLayout = 0, tinyLayout = 0,
484   marginW, marginH, // [HGM] for run-time resizing
485   fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,
486   ICSInputBoxUp = False, askQuestionUp = False,
487   filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,
488   editUp = False, errorUp = False, errorExitStatus = -1, lineGap;
489 Pixel timerForegroundPixel, timerBackgroundPixel;
490 Pixel buttonForegroundPixel, buttonBackgroundPixel;
491 char *chessDir, *programName, *programVersion,
492   *gameCopyFilename, *gamePasteFilename;
493
494 #define SOLID 0
495 #define OUTLINE 1
496 Pixmap pieceBitmap[2][(int)BlackPawn];
497 Pixmap xpmPieceBitmap[4][(int)BlackPawn];       /* LL, LD, DL, DD */
498 Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;
499 int useImages, useImageSqs;
500 XImage *ximPieceBitmap[4][(int)BlackPawn];      /* LL, LD, DL, DD */
501 Pixmap ximMaskPm[(int)BlackPawn];            /* clipmasks, used for XIM pieces */
502 XImage *ximLightSquare, *ximDarkSquare;
503 XImage *xim_Cross;
504
505 #define pieceToSolid(piece) &pieceBitmap[SOLID][((int)(piece)) % (int)BlackPawn]
506 #define pieceToOutline(piece) &pieceBitmap[OUTLINE][((int)(piece)) % (int)BlackPawn]
507
508 #define White(piece) ((int)(piece) < (int)BlackPawn)
509
510 /* Variables for doing smooth animation. This whole thing
511    would be much easier if the board was double-buffered,
512    but that would require a fairly major rewrite.       */
513
514 typedef struct {
515         Pixmap  saveBuf;
516         Pixmap  newBuf;
517         GC      blitGC, pieceGC, outlineGC;
518         XPoint  startSquare, prevFrame, mouseDelta;
519         int     startColor;
520         int     dragPiece;
521         Boolean dragActive;
522         int     startBoardX, startBoardY;
523     } AnimState;
524
525 /* There can be two pieces being animated at once: a player
526    can begin dragging a piece before the remote opponent has moved. */
527
528 static AnimState game, player;
529
530 /* Bitmaps for use as masks when drawing XPM pieces.
531    Need one for each black and white piece.             */
532 static Pixmap xpmMask[BlackKing + 1];
533
534 /* This magic number is the number of intermediate frames used
535    in each half of the animation. For short moves it's reduced
536    by 1. The total number of frames will be factor * 2 + 1.  */
537 #define kFactor    4
538
539 SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
540
541 MenuItem fileMenu[] = {
542     {N_("New Game"), ResetProc},
543     {N_("New Shuffle Game ..."), ShuffleMenuProc},
544     {N_("New Variant ..."), NewVariantProc},      // [HGM] variant: not functional yet
545     {"----", NothingProc},
546     {N_("Load Game"), LoadGameProc},
547     {N_("Load Next Game"), LoadNextGameProc},
548     {N_("Load Previous Game"), LoadPrevGameProc},
549     {N_("Reload Same Game"), ReloadGameProc},
550     {N_("Save Game"), SaveGameProc},
551     {"----", NothingProc},
552     {N_("Copy Game"), CopyGameProc},
553     {N_("Paste Game"), PasteGameProc},
554     {"----", NothingProc},
555     {N_("Load Position"), LoadPositionProc},
556     {N_("Load Next Position"), LoadNextPositionProc},
557     {N_("Load Previous Position"), LoadPrevPositionProc},
558     {N_("Reload Same Position"), ReloadPositionProc},
559     {N_("Save Position"), SavePositionProc},
560     {"----", NothingProc},
561     {N_("Copy Position"), CopyPositionProc},
562     {N_("Paste Position"), PastePositionProc},
563     {"----", NothingProc},
564     {N_("Mail Move"), MailMoveProc},
565     {N_("Reload CMail Message"), ReloadCmailMsgProc},
566     {"----", NothingProc},
567     {N_("Exit"), QuitProc},
568     {NULL, NULL}
569 };
570
571 MenuItem modeMenu[] = {
572     {N_("Machine White"), MachineWhiteProc},
573     {N_("Machine Black"), MachineBlackProc},
574     {N_("Two Machines"), TwoMachinesProc},
575     {N_("Analysis Mode"), AnalyzeModeProc},
576     {N_("Analyze File"), AnalyzeFileProc },
577     {N_("ICS Client"), IcsClientProc},
578     {N_("Edit Game"), EditGameProc},
579     {N_("Edit Position"), EditPositionProc},
580     {N_("Training"), TrainingProc},
581     {"----", NothingProc},
582     {N_("Show Engine Output"), EngineOutputProc},
583     {N_("Show Evaluation Graph"), NothingProc}, // [HGM] evalgr: not functional yet
584     {N_("Show Game List"), ShowGameListProc},
585     {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
586     {"----", NothingProc},
587     {N_("Edit Tags"), EditTagsProc},
588     {N_("Edit Comment"), EditCommentProc},
589     {N_("ICS Input Box"), IcsInputBoxProc},
590     {N_("Pause"), PauseProc},
591     {NULL, NULL}
592 };
593
594 MenuItem actionMenu[] = {
595     {N_("Accept"), AcceptProc},
596     {N_("Decline"), DeclineProc},
597     {N_("Rematch"), RematchProc},
598     {"----", NothingProc},
599     {N_("Call Flag"), CallFlagProc},
600     {N_("Draw"), DrawProc},
601     {N_("Adjourn"), AdjournProc},
602     {N_("Abort"), AbortProc},
603     {N_("Resign"), ResignProc},
604     {"----", NothingProc},
605     {N_("Stop Observing"), StopObservingProc},
606     {N_("Stop Examining"), StopExaminingProc},
607     {"----", NothingProc},
608     {N_("Adjudicate to White"), AdjuWhiteProc},
609     {N_("Adjudicate to Black"), AdjuBlackProc},
610     {N_("Adjudicate Draw"), AdjuDrawProc},
611     {NULL, NULL}
612 };
613
614 MenuItem stepMenu[] = {
615     {N_("Backward"), BackwardProc},
616     {N_("Forward"), ForwardProc},
617     {N_("Back to Start"), ToStartProc},
618     {N_("Forward to End"), ToEndProc},
619     {N_("Revert"), RevertProc},
620     {N_("Truncate Game"), TruncateGameProc},
621     {"----", NothingProc},
622     {N_("Move Now"), MoveNowProc},
623     {N_("Retract Move"), RetractMoveProc},
624     {NULL, NULL}
625 };
626
627 MenuItem optionsMenu[] = {
628     {N_("Flip View"), FlipViewProc},
629     {"----", NothingProc},
630     {N_("Adjudications ..."), EngineMenuProc},
631     {N_("General Settings ..."), UciMenuProc},
632     {N_("Engine #1 Settings ..."), FirstSettingsProc},
633     {N_("Engine #2 Settings ..."), SecondSettingsProc},
634     {N_("Time Control ..."), TimeControlProc},
635     {"----", NothingProc},
636     {N_("Always Queen"), AlwaysQueenProc},
637     {N_("Animate Dragging"), AnimateDraggingProc},
638     {N_("Animate Moving"), AnimateMovingProc},
639     {N_("Auto Comment"), AutocommProc},
640     {N_("Auto Flag"), AutoflagProc},
641     {N_("Auto Flip View"), AutoflipProc},
642     {N_("Auto Observe"), AutobsProc},
643     {N_("Auto Raise Board"), AutoraiseProc},
644     {N_("Auto Save"), AutosaveProc},
645     {N_("Blindfold"), BlindfoldProc},
646     {N_("Flash Moves"), FlashMovesProc},
647     {N_("Get Move List"), GetMoveListProc},
648 #if HIGHDRAG
649     {N_("Highlight Dragging"), HighlightDraggingProc},
650 #endif
651     {N_("Highlight Last Move"), HighlightLastMoveProc},
652     {N_("Move Sound"), MoveSoundProc},
653     {N_("ICS Alarm"), IcsAlarmProc},
654     {N_("Old Save Style"), OldSaveStyleProc},
655     {N_("Periodic Updates"), PeriodicUpdatesProc},
656     {N_("Ponder Next Move"), PonderNextMoveProc},
657     {N_("Popup Exit Message"), PopupExitMessageProc},
658     {N_("Popup Move Errors"), PopupMoveErrorsProc},
659     {N_("Premove"), PremoveProc},
660     {N_("Quiet Play"), QuietPlayProc},
661     {N_("Show Coords"), ShowCoordsProc},
662     {N_("Hide Thinking"), HideThinkingProc},
663     {N_("Test Legality"), TestLegalityProc},
664     {NULL, NULL}
665 };
666
667 MenuItem helpMenu[] = {
668     {N_("Info XBoard"), InfoProc},
669     {N_("Man XBoard"), ManProc},
670     {"----", NothingProc},
671     {N_("Hint"), HintProc},
672     {N_("Book"), BookProc},
673     {"----", NothingProc},
674     {N_("About XBoard"), AboutProc},
675     {NULL, NULL}
676 };
677
678 Menu menuBar[] = {
679     {N_("File"), fileMenu},
680     {N_("Mode"), modeMenu},
681     {N_("Action"), actionMenu},
682     {N_("Step"), stepMenu},
683     {N_("Options"), optionsMenu},
684     {N_("Help"), helpMenu},
685     {NULL, NULL}
686 };
687
688 #define PAUSE_BUTTON N_("P")
689 MenuItem buttonBar[] = {
690     {"<<", ToStartProc},
691     {"<", BackwardProc},
692     {PAUSE_BUTTON, PauseProc},
693     {">", ForwardProc},
694     {">>", ToEndProc},
695     {NULL, NULL}
696 };
697
698 #define PIECE_MENU_SIZE 11
699 String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
700     { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
701       N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
702     { N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
703       N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
704 };
705 /* must be in same order as PieceMenuStrings! */
706 ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
707     { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
708         WhiteRook, WhiteQueen, WhiteKing,
709         (ChessSquare) 0, EmptySquare, ClearBoard },
710     { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
711         BlackRook, BlackQueen, BlackKing,
712         (ChessSquare) 0, EmptySquare, ClearBoard },
713 };
714
715 #define DROP_MENU_SIZE 6
716 String dropMenuStrings[DROP_MENU_SIZE] = {
717     "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen")
718   };
719 /* must be in same order as PieceMenuStrings! */
720 ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
721     (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
722     WhiteRook, WhiteQueen
723 };
724
725 typedef struct {
726     char piece;
727     char* widget;
728 } DropMenuEnables;
729
730 DropMenuEnables dmEnables[] = {
731     { 'P', "Pawn" },
732     { 'N', "Knight" },
733     { 'B', "Bishop" },
734     { 'R', "Rook" },
735     { 'Q', "Queen" }
736 };
737
738 Arg shellArgs[] = {
739     { XtNwidth, 0 },
740     { XtNheight, 0 },
741     { XtNminWidth, 0 },
742     { XtNminHeight, 0 },
743     { XtNmaxWidth, 0 },
744     { XtNmaxHeight, 0 }
745 };
746
747 Arg layoutArgs[] = {
748     { XtNborderWidth, 0 },
749     { XtNdefaultDistance, 0 },
750 };
751
752 Arg formArgs[] = {
753     { XtNborderWidth, 0 },
754     { XtNresizable, (XtArgVal) True },
755 };
756
757 Arg boardArgs[] = {
758     { XtNborderWidth, 0 },
759     { XtNwidth, 0 },
760     { XtNheight, 0 }
761 };
762
763 Arg titleArgs[] = {
764     { XtNjustify, (XtArgVal) XtJustifyRight },
765     { XtNlabel, (XtArgVal) "..." },
766     { XtNresizable, (XtArgVal) True },
767     { XtNresize, (XtArgVal) False }
768 };
769
770 Arg messageArgs[] = {
771     { XtNjustify, (XtArgVal) XtJustifyLeft },
772     { XtNlabel, (XtArgVal) "..." },
773     { XtNresizable, (XtArgVal) True },
774     { XtNresize, (XtArgVal) False }
775 };
776
777 Arg timerArgs[] = {
778     { XtNborderWidth, 0 },
779     { XtNjustify, (XtArgVal) XtJustifyLeft }
780 };
781
782 XtResource clientResources[] = {
783     { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
784         XtOffset(AppDataPtr, whitePieceColor), XtRString,
785         WHITE_PIECE_COLOR },
786     { "blackPieceColor", "blackPieceColor", XtRString, sizeof(String),
787         XtOffset(AppDataPtr, blackPieceColor), XtRString,
788         BLACK_PIECE_COLOR },
789     { "lightSquareColor", "lightSquareColor", XtRString,
790         sizeof(String), XtOffset(AppDataPtr, lightSquareColor),
791         XtRString, LIGHT_SQUARE_COLOR },
792     { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),
793         XtOffset(AppDataPtr, darkSquareColor), XtRString,
794         DARK_SQUARE_COLOR },
795     { "highlightSquareColor", "highlightSquareColor", XtRString,
796         sizeof(String), XtOffset(AppDataPtr, highlightSquareColor),
797         XtRString, HIGHLIGHT_SQUARE_COLOR },
798     { "premoveHighlightColor", "premoveHighlightColor", XtRString,
799         sizeof(String), XtOffset(AppDataPtr, premoveHighlightColor),
800         XtRString, PREMOVE_HIGHLIGHT_COLOR },
801     { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),
802         XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
803         (XtPointer) MOVES_PER_SESSION },
804     { "timeIncrement", "timeIncrement", XtRInt, sizeof(int),
805         XtOffset(AppDataPtr, timeIncrement), XtRImmediate,
806         (XtPointer) TIME_INCREMENT },
807     { "initString", "initString", XtRString, sizeof(String),
808         XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },
809     { "secondInitString", "secondInitString", XtRString, sizeof(String),
810         XtOffset(AppDataPtr, secondInitString), XtRString, INIT_STRING },
811     { "firstComputerString", "firstComputerString", XtRString,
812         sizeof(String), XtOffset(AppDataPtr, firstComputerString), XtRString,
813       COMPUTER_STRING },
814     { "secondComputerString", "secondComputerString", XtRString,
815         sizeof(String), XtOffset(AppDataPtr, secondComputerString), XtRString,
816       COMPUTER_STRING },
817     { "firstChessProgram", "firstChessProgram", XtRString,
818         sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
819         XtRString, FIRST_CHESS_PROGRAM },
820     { "secondChessProgram", "secondChessProgram", XtRString,
821         sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
822         XtRString, SECOND_CHESS_PROGRAM },
823     { "firstPlaysBlack", "firstPlaysBlack", XtRBoolean,
824         sizeof(Boolean), XtOffset(AppDataPtr, firstPlaysBlack),
825         XtRImmediate, (XtPointer) False },
826     { "noChessProgram", "noChessProgram", XtRBoolean,
827         sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
828         XtRImmediate, (XtPointer) False },
829     { "firstHost", "firstHost", XtRString, sizeof(String),
830         XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },
831     { "secondHost", "secondHost", XtRString, sizeof(String),
832         XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
833     { "firstDirectory", "firstDirectory", XtRString, sizeof(String),
834         XtOffset(AppDataPtr, firstDirectory), XtRString, "." },
835     { "secondDirectory", "secondDirectory", XtRString, sizeof(String),
836         XtOffset(AppDataPtr, secondDirectory), XtRString, "." },
837     { "bitmapDirectory", "bitmapDirectory", XtRString,
838         sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),
839         XtRString, "" },
840     { "remoteShell", "remoteShell", XtRString, sizeof(String),
841         XtOffset(AppDataPtr, remoteShell), XtRString, REMOTE_SHELL },
842     { "remoteUser", "remoteUser", XtRString, sizeof(String),
843         XtOffset(AppDataPtr, remoteUser), XtRString, "" },
844     { "timeDelay", "timeDelay", XtRFloat, sizeof(float),
845         XtOffset(AppDataPtr, timeDelay), XtRString,
846         (XtPointer) TIME_DELAY_QUOTE },
847     { "timeControl", "timeControl", XtRString, sizeof(String),
848         XtOffset(AppDataPtr, timeControl), XtRString,
849         (XtPointer) TIME_CONTROL },
850     { "internetChessServerMode", "internetChessServerMode",
851         XtRBoolean, sizeof(Boolean),
852         XtOffset(AppDataPtr, icsActive), XtRImmediate,
853         (XtPointer) False },
854     { "internetChessServerHost", "internetChessServerHost",
855         XtRString, sizeof(String),
856         XtOffset(AppDataPtr, icsHost),
857         XtRString, (XtPointer) ICS_HOST },
858     { "internetChessServerPort", "internetChessServerPort",
859         XtRString, sizeof(String),
860         XtOffset(AppDataPtr, icsPort), XtRString,
861         (XtPointer) ICS_PORT },
862     { "internetChessServerCommPort", "internetChessServerCommPort",
863         XtRString, sizeof(String),
864         XtOffset(AppDataPtr, icsCommPort), XtRString,
865         ICS_COMM_PORT },
866     { "internetChessServerLogonScript", "internetChessServerLogonScript",
867         XtRString, sizeof(String),
868         XtOffset(AppDataPtr, icsLogon), XtRString,
869         ICS_LOGON },
870     { "internetChessServerHelper", "internetChessServerHelper",
871         XtRString, sizeof(String),
872         XtOffset(AppDataPtr, icsHelper), XtRString, "" },
873     { "internetChessServerInputBox", "internetChessServerInputBox",
874         XtRBoolean, sizeof(Boolean),
875         XtOffset(AppDataPtr, icsInputBox), XtRImmediate,
876         (XtPointer) False },
877     { "icsAlarm", "icsAlarm",
878         XtRBoolean, sizeof(Boolean),
879         XtOffset(AppDataPtr, icsAlarm), XtRImmediate,
880         (XtPointer) True },
881     { "icsAlarmTime", "icsAlarmTime",
882         XtRInt, sizeof(int),
883         XtOffset(AppDataPtr, icsAlarmTime), XtRImmediate,
884         (XtPointer) 5000 },
885     { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),
886         XtOffset(AppDataPtr, useTelnet), XtRImmediate,
887         (XtPointer) False },
888     { "telnetProgram", "telnetProgram", XtRString, sizeof(String),
889         XtOffset(AppDataPtr, telnetProgram), XtRString, TELNET_PROGRAM },
890     { "gateway", "gateway", XtRString, sizeof(String),
891         XtOffset(AppDataPtr, gateway), XtRString, "" },
892     { "loadGameFile", "loadGameFile", XtRString, sizeof(String),
893         XtOffset(AppDataPtr, loadGameFile), XtRString, "" },
894     { "loadGameIndex", "loadGameIndex",
895         XtRInt, sizeof(int),
896         XtOffset(AppDataPtr, loadGameIndex), XtRImmediate,
897         (XtPointer) 0 },
898     { "saveGameFile", "saveGameFile", XtRString, sizeof(String),
899         XtOffset(AppDataPtr, saveGameFile), XtRString, "" },
900     { "autoRaiseBoard", "autoRaiseBoard", XtRBoolean,
901         sizeof(Boolean), XtOffset(AppDataPtr, autoRaiseBoard),
902         XtRImmediate, (XtPointer) True },
903     { "autoSaveGames", "autoSaveGames", XtRBoolean,
904         sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
905         XtRImmediate, (XtPointer) False },
906     { "blindfold", "blindfold", XtRBoolean,
907         sizeof(Boolean), XtOffset(AppDataPtr, blindfold),
908         XtRImmediate, (XtPointer) False },
909     { "loadPositionFile", "loadPositionFile", XtRString,
910         sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
911         XtRString, "" },
912     { "loadPositionIndex", "loadPositionIndex",
913         XtRInt, sizeof(int),
914         XtOffset(AppDataPtr, loadPositionIndex), XtRImmediate,
915         (XtPointer) 1 },
916     { "savePositionFile", "savePositionFile", XtRString,
917         sizeof(String), XtOffset(AppDataPtr, savePositionFile),
918         XtRString, "" },
919     { "matchMode", "matchMode", XtRBoolean, sizeof(Boolean),
920         XtOffset(AppDataPtr, matchMode), XtRImmediate, (XtPointer) False },
921     { "matchGames", "matchGames", XtRInt, sizeof(int),
922         XtOffset(AppDataPtr, matchGames), XtRImmediate,
923         (XtPointer) 0 },
924     { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
925         XtOffset(AppDataPtr, monoMode), XtRImmediate,
926         (XtPointer) False },
927     { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
928         XtOffset(AppDataPtr, debugMode), XtRImmediate,
929         (XtPointer) False },
930     { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
931         XtOffset(AppDataPtr, clockMode), XtRImmediate,
932         (XtPointer) True },
933     { "boardSize", "boardSize", XtRString, sizeof(String),
934         XtOffset(AppDataPtr, boardSize), XtRString, "" },
935     { "searchTime", "searchTime", XtRString, sizeof(String),
936         XtOffset(AppDataPtr, searchTime), XtRString,
937         (XtPointer) "" },
938     { "searchDepth", "searchDepth", XtRInt, sizeof(int),
939         XtOffset(AppDataPtr, searchDepth), XtRImmediate,
940         (XtPointer) 0 },
941     { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
942         XtOffset(AppDataPtr, showCoords), XtRImmediate,
943         (XtPointer) False },
944     { "showJail", "showJail", XtRInt, sizeof(int),
945         XtOffset(AppDataPtr, showJail), XtRImmediate,
946         (XtPointer) 0 },
947     { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),
948         XtOffset(AppDataPtr, showThinking), XtRImmediate,
949         (XtPointer) True },
950     { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),
951         XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,
952         (XtPointer) True },
953     { "periodicUpdates", "periodicUpdates", XtRBoolean, sizeof(Boolean),
954         XtOffset(AppDataPtr, periodicUpdates), XtRImmediate,
955         (XtPointer) True },
956     { "clockFont", "clockFont", XtRString, sizeof(String),
957         XtOffset(AppDataPtr, clockFont), XtRString, CLOCK_FONT },
958     { "coordFont", "coordFont", XtRString, sizeof(String),
959         XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },
960     { "font", "font", XtRString, sizeof(String),
961         XtOffset(AppDataPtr, font), XtRString, DEFAULT_FONT },
962     { "ringBellAfterMoves", "ringBellAfterMoves",
963         XtRBoolean, sizeof(Boolean),
964         XtOffset(AppDataPtr, ringBellAfterMoves),
965         XtRImmediate, (XtPointer) False },
966     { "autoCallFlag", "autoCallFlag", XtRBoolean,
967         sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
968         XtRImmediate, (XtPointer) False },
969     { "autoFlipView", "autoFlipView", XtRBoolean,
970         sizeof(Boolean), XtOffset(AppDataPtr, autoFlipView),
971         XtRImmediate, (XtPointer) True },
972     { "autoObserve", "autoObserve", XtRBoolean,
973         sizeof(Boolean), XtOffset(AppDataPtr, autoObserve),
974         XtRImmediate, (XtPointer) False },
975     { "autoComment", "autoComment", XtRBoolean,
976         sizeof(Boolean), XtOffset(AppDataPtr, autoComment),
977         XtRImmediate, (XtPointer) False },
978     { "getMoveList", "getMoveList", XtRBoolean,
979         sizeof(Boolean), XtOffset(AppDataPtr, getMoveList),
980         XtRImmediate, (XtPointer) True },
981 #if HIGHDRAG
982     { "highlightDragging", "highlightDragging", XtRBoolean,
983         sizeof(Boolean), XtOffset(AppDataPtr, highlightDragging),
984         XtRImmediate, (XtPointer) False },
985 #endif
986     { "highlightLastMove", "highlightLastMove", XtRBoolean,
987         sizeof(Boolean), XtOffset(AppDataPtr, highlightLastMove),
988         XtRImmediate, (XtPointer) False },
989     { "premove", "premove", XtRBoolean,
990         sizeof(Boolean), XtOffset(AppDataPtr, premove),
991         XtRImmediate, (XtPointer) True },
992     { "testLegality", "testLegality", XtRBoolean,
993         sizeof(Boolean), XtOffset(AppDataPtr, testLegality),
994         XtRImmediate, (XtPointer) True },
995     { "flipView", "flipView", XtRBoolean,
996         sizeof(Boolean), XtOffset(AppDataPtr, flipView),
997         XtRImmediate, (XtPointer) False },
998     { "cmail", "cmailGameName", XtRString, sizeof(String),
999         XtOffset(AppDataPtr, cmailGameName), XtRString, "" },
1000     { "alwaysPromoteToQueen", "alwaysPromoteToQueen", XtRBoolean,
1001         sizeof(Boolean), XtOffset(AppDataPtr, alwaysPromoteToQueen),
1002         XtRImmediate, (XtPointer) False },
1003     { "oldSaveStyle", "oldSaveStyle", XtRBoolean,
1004         sizeof(Boolean), XtOffset(AppDataPtr, oldSaveStyle),
1005         XtRImmediate, (XtPointer) False },
1006     { "quietPlay", "quietPlay", XtRBoolean,
1007         sizeof(Boolean), XtOffset(AppDataPtr, quietPlay),
1008         XtRImmediate, (XtPointer) False },
1009     { "titleInWindow", "titleInWindow", XtRBoolean,
1010         sizeof(Boolean), XtOffset(AppDataPtr, titleInWindow),
1011         XtRImmediate, (XtPointer) False },
1012     { "localLineEditing", "localLineEditing", XtRBoolean,
1013         sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
1014         XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
1015 #ifdef ZIPPY
1016     { "zippyTalk", "zippyTalk", XtRBoolean,
1017         sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
1018         XtRImmediate, (XtPointer) ZIPPY_TALK },
1019     { "zippyPlay", "zippyPlay", XtRBoolean,
1020         sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),
1021         XtRImmediate, (XtPointer) ZIPPY_PLAY },
1022     { "zippyLines", "zippyLines", XtRString, sizeof(String),
1023         XtOffset(AppDataPtr, zippyLines), XtRString, ZIPPY_LINES },
1024     { "zippyPinhead", "zippyPinhead", XtRString, sizeof(String),
1025         XtOffset(AppDataPtr, zippyPinhead), XtRString, ZIPPY_PINHEAD },
1026     { "zippyPassword", "zippyPassword", XtRString, sizeof(String),
1027         XtOffset(AppDataPtr, zippyPassword), XtRString, ZIPPY_PASSWORD },
1028     { "zippyPassword2", "zippyPassword2", XtRString, sizeof(String),
1029         XtOffset(AppDataPtr, zippyPassword2), XtRString, ZIPPY_PASSWORD2 },
1030     { "zippyWrongPassword", "zippyWrongPassword", XtRString, sizeof(String),
1031         XtOffset(AppDataPtr, zippyWrongPassword), XtRString,
1032         ZIPPY_WRONG_PASSWORD },
1033     { "zippyAcceptOnly", "zippyAcceptOnly", XtRString, sizeof(String),
1034         XtOffset(AppDataPtr, zippyAcceptOnly), XtRString, ZIPPY_ACCEPT_ONLY },
1035     { "zippyUseI", "zippyUseI", XtRBoolean,
1036         sizeof(Boolean), XtOffset(AppDataPtr, zippyUseI),
1037         XtRImmediate, (XtPointer) ZIPPY_USE_I },
1038     { "zippyBughouse", "zippyBughouse", XtRInt,
1039         sizeof(int), XtOffset(AppDataPtr, zippyBughouse),
1040         XtRImmediate, (XtPointer) ZIPPY_BUGHOUSE },
1041     { "zippyNoplayCrafty", "zippyNoplayCrafty", XtRBoolean,
1042         sizeof(Boolean), XtOffset(AppDataPtr, zippyNoplayCrafty),
1043         XtRImmediate, (XtPointer) ZIPPY_NOPLAY_CRAFTY },
1044     { "zippyGameEnd", "zippyGameEnd", XtRString, sizeof(String),
1045         XtOffset(AppDataPtr, zippyGameEnd), XtRString, ZIPPY_GAME_END },
1046     { "zippyGameStart", "zippyGameStart", XtRString, sizeof(String),
1047         XtOffset(AppDataPtr, zippyGameStart), XtRString, ZIPPY_GAME_START },
1048     { "zippyAdjourn", "zippyAdjourn", XtRBoolean,
1049         sizeof(Boolean), XtOffset(AppDataPtr, zippyAdjourn),
1050         XtRImmediate, (XtPointer) ZIPPY_ADJOURN },
1051     { "zippyAbort", "zippyAbort", XtRBoolean,
1052         sizeof(Boolean), XtOffset(AppDataPtr, zippyAbort),
1053         XtRImmediate, (XtPointer) ZIPPY_ABORT },
1054     { "zippyVariants", "zippyVariants", XtRString, sizeof(String),
1055         XtOffset(AppDataPtr, zippyVariants), XtRString, ZIPPY_VARIANTS },
1056     { "zippyMaxGames", "zippyMaxGames", XtRInt, sizeof(int),
1057         XtOffset(AppDataPtr, zippyMaxGames), XtRImmediate,
1058         (XtPointer) ZIPPY_MAX_GAMES },
1059     { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),
1060         XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,
1061         (XtPointer) ZIPPY_REPLAY_TIMEOUT },
1062 #endif
1063     { "flashCount", "flashCount", XtRInt, sizeof(int),
1064         XtOffset(AppDataPtr, flashCount), XtRImmediate,
1065         (XtPointer) FLASH_COUNT  },
1066     { "flashRate", "flashRate", XtRInt, sizeof(int),
1067         XtOffset(AppDataPtr, flashRate), XtRImmediate,
1068         (XtPointer) FLASH_RATE },
1069     { "pixmapDirectory", "pixmapDirectory", XtRString,
1070         sizeof(String), XtOffset(AppDataPtr, pixmapDirectory),
1071         XtRString, "" },
1072     { "msLoginDelay", "msLoginDelay", XtRInt, sizeof(int),
1073         XtOffset(AppDataPtr, msLoginDelay), XtRImmediate,
1074         (XtPointer) MS_LOGIN_DELAY },
1075     { "colorizeMessages", "colorizeMessages", XtRBoolean,
1076         sizeof(Boolean), XtOffset(AppDataPtr, colorize),
1077         XtRImmediate, (XtPointer) False },
1078     { "colorShout", "colorShout", XtRString,
1079         sizeof(String), XtOffset(AppDataPtr, colorShout),
1080         XtRString, COLOR_SHOUT },
1081     { "colorSShout", "colorSShout", XtRString,
1082         sizeof(String), XtOffset(AppDataPtr, colorSShout),
1083         XtRString, COLOR_SSHOUT },
1084     { "colorChannel1", "colorChannel1", XtRString,
1085         sizeof(String), XtOffset(AppDataPtr, colorChannel1),
1086         XtRString, COLOR_CHANNEL1 },
1087     { "colorChannel", "colorChannel", XtRString,
1088         sizeof(String), XtOffset(AppDataPtr, colorChannel),
1089         XtRString, COLOR_CHANNEL },
1090     { "colorKibitz", "colorKibitz", XtRString,
1091         sizeof(String), XtOffset(AppDataPtr, colorKibitz),
1092         XtRString, COLOR_KIBITZ },
1093     { "colorTell", "colorTell", XtRString,
1094         sizeof(String), XtOffset(AppDataPtr, colorTell),
1095         XtRString, COLOR_TELL },
1096     { "colorChallenge", "colorChallenge", XtRString,
1097         sizeof(String), XtOffset(AppDataPtr, colorChallenge),
1098         XtRString, COLOR_CHALLENGE },
1099     { "colorRequest", "colorRequest", XtRString,
1100         sizeof(String), XtOffset(AppDataPtr, colorRequest),
1101         XtRString, COLOR_REQUEST },
1102     { "colorSeek", "colorSeek", XtRString,
1103         sizeof(String), XtOffset(AppDataPtr, colorSeek),
1104         XtRString, COLOR_SEEK },
1105     { "colorNormal", "colorNormal", XtRString,
1106         sizeof(String), XtOffset(AppDataPtr, colorNormal),
1107         XtRString, COLOR_NORMAL },
1108     { "soundProgram", "soundProgram", XtRString,
1109       sizeof(String), XtOffset(AppDataPtr, soundProgram),
1110       XtRString, "play" },
1111     { "soundShout", "soundShout", XtRString,
1112       sizeof(String), XtOffset(AppDataPtr, soundShout),
1113       XtRString, "" },
1114     { "soundSShout", "soundSShout", XtRString,
1115       sizeof(String), XtOffset(AppDataPtr, soundSShout),
1116       XtRString, "" },
1117     { "soundChannel1", "soundChannel1", XtRString,
1118       sizeof(String), XtOffset(AppDataPtr, soundChannel1),
1119       XtRString, "" },
1120     { "soundChannel", "soundChannel", XtRString,
1121       sizeof(String), XtOffset(AppDataPtr, soundChannel),
1122       XtRString, "" },
1123     { "soundKibitz", "soundKibitz", XtRString,
1124       sizeof(String), XtOffset(AppDataPtr, soundKibitz),
1125       XtRString, "" },
1126     { "soundTell", "soundTell", XtRString,
1127       sizeof(String), XtOffset(AppDataPtr, soundTell),
1128       XtRString, "" },
1129     { "soundChallenge", "soundChallenge", XtRString,
1130       sizeof(String), XtOffset(AppDataPtr, soundChallenge),
1131       XtRString, "" },
1132     { "soundRequest", "soundRequest", XtRString,
1133       sizeof(String), XtOffset(AppDataPtr, soundRequest),
1134       XtRString, "" },
1135     { "soundSeek", "soundSeek", XtRString,
1136       sizeof(String), XtOffset(AppDataPtr, soundSeek),
1137       XtRString, "" },
1138     { "soundMove", "soundMove", XtRString,
1139       sizeof(String), XtOffset(AppDataPtr, soundMove),
1140       XtRString, "$" },
1141     { "soundIcsWin", "soundIcsWin", XtRString,
1142       sizeof(String), XtOffset(AppDataPtr, soundIcsWin),
1143       XtRString, "" },
1144     { "soundIcsLoss", "soundIcsLoss", XtRString,
1145       sizeof(String), XtOffset(AppDataPtr, soundIcsLoss),
1146       XtRString, "" },
1147     { "soundIcsDraw", "soundIcsDraw", XtRString,
1148       sizeof(String), XtOffset(AppDataPtr, soundIcsDraw),
1149       XtRString, "" },
1150     { "soundIcsUnfinished", "soundIcsUnfinished", XtRString,
1151       sizeof(String), XtOffset(AppDataPtr, soundIcsUnfinished),
1152       XtRString, "" },
1153     { "soundIcsAlarm", "soundIcsAlarm", XtRString,
1154       sizeof(String), XtOffset(AppDataPtr, soundIcsAlarm),
1155       XtRString, "$" },
1156     { "reuseFirst", "reuseFirst", XtRBoolean,
1157         sizeof(Boolean), XtOffset(AppDataPtr, reuseFirst),
1158         XtRImmediate, (XtPointer) True },
1159     { "reuseSecond", "reuseSecond", XtRBoolean,
1160         sizeof(Boolean), XtOffset(AppDataPtr, reuseSecond),
1161         XtRImmediate, (XtPointer) True },
1162     { "animateDragging", "animateDragging", XtRBoolean,
1163         sizeof(Boolean), XtOffset(AppDataPtr, animateDragging),
1164         XtRImmediate, (XtPointer) True },
1165     { "animateMoving", "animateMoving", XtRBoolean,
1166         sizeof(Boolean), XtOffset(AppDataPtr, animate),
1167         XtRImmediate, (XtPointer) True },
1168     { "animateSpeed", "animateSpeed", XtRInt,
1169         sizeof(int), XtOffset(AppDataPtr, animSpeed),
1170         XtRImmediate, (XtPointer)10 },
1171     { "popupExitMessage", "popupExitMessage", XtRBoolean,
1172         sizeof(Boolean), XtOffset(AppDataPtr, popupExitMessage),
1173         XtRImmediate, (XtPointer) True },
1174     { "popupMoveErrors", "popupMoveErrors", XtRBoolean,
1175         sizeof(Boolean), XtOffset(AppDataPtr, popupMoveErrors),
1176         XtRImmediate, (XtPointer) False },
1177     { "fontSizeTolerance", "fontSizeTolerance", XtRInt,
1178         sizeof(int), XtOffset(AppDataPtr, fontSizeTolerance),
1179         XtRImmediate, (XtPointer)4 },
1180     { "initialMode", "initialMode", XtRString,
1181         sizeof(String), XtOffset(AppDataPtr, initialMode),
1182         XtRImmediate, (XtPointer) "" },
1183     { "variant", "variant", XtRString,
1184         sizeof(String), XtOffset(AppDataPtr, variant),
1185         XtRImmediate, (XtPointer) "normal" },
1186     { "firstProtocolVersion", "firstProtocolVersion", XtRInt,
1187         sizeof(int), XtOffset(AppDataPtr, firstProtocolVersion),
1188         XtRImmediate, (XtPointer)PROTOVER },
1189     { "secondProtocolVersion", "secondProtocolVersion", XtRInt,
1190         sizeof(int), XtOffset(AppDataPtr, secondProtocolVersion),
1191         XtRImmediate, (XtPointer)PROTOVER },
1192     { "showButtonBar", "showButtonBar", XtRBoolean,
1193         sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),
1194         XtRImmediate, (XtPointer) True },
1195     {"icsEngineAnalyze", "icsEngineAnalyze", XtRBoolean,        /* [DM] icsEngineAnalyze */
1196         sizeof(Boolean), XtOffset(AppDataPtr, icsEngineAnalyze),
1197         XtRImmediate, (XtPointer) False },
1198     { "firstScoreAbs", "firstScoreAbs", XtRBoolean,
1199         sizeof(Boolean), XtOffset(AppDataPtr, firstScoreIsAbsolute),
1200         XtRImmediate, (XtPointer) False },
1201     { "secondScoreAbs", "secondScoreAbs", XtRBoolean,
1202         sizeof(Boolean), XtOffset(AppDataPtr, secondScoreIsAbsolute),
1203         XtRImmediate, (XtPointer) False },
1204     { "pgnExtendedInfo", "pgnExtendedInfo", XtRBoolean,
1205         sizeof(Boolean), XtOffset(AppDataPtr, saveExtendedInfoInPGN),
1206         XtRImmediate, (XtPointer) False },
1207     { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,
1208         sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),
1209         XtRImmediate, (XtPointer) True },
1210     { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
1211         sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
1212         XtRImmediate, (XtPointer) 0},
1213     { "pgnEventHeader", "pgnEventHeader", XtRString,
1214         sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),
1215         XtRImmediate, (XtPointer) "Computer Chess Game" },
1216     { "defaultFrcPosition", "defaultFrcPositon", XtRInt,
1217         sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),
1218         XtRImmediate, (XtPointer) -1},
1219     { "gameListTags", "gameListTags", XtRString,
1220         sizeof(String), XtOffset(AppDataPtr, gameListTags),
1221         XtRImmediate, (XtPointer) GLT_DEFAULT_TAGS },
1222
1223     // [HGM] 4.3.xx options
1224     { "boardWidth", "boardWidth", XtRInt,
1225         sizeof(int), XtOffset(AppDataPtr, NrFiles),
1226         XtRImmediate, (XtPointer) -1},
1227     { "boardHeight", "boardHeight", XtRInt,
1228         sizeof(int), XtOffset(AppDataPtr, NrRanks),
1229         XtRImmediate, (XtPointer) -1},
1230     { "matchPause", "matchPause", XtRInt,
1231         sizeof(int), XtOffset(AppDataPtr, matchPause),
1232         XtRImmediate, (XtPointer) 10000},
1233     { "holdingsSize", "holdingsSize", XtRInt,
1234         sizeof(int), XtOffset(AppDataPtr, holdingsSize),
1235         XtRImmediate, (XtPointer) -1},
1236     { "flipBlack", "flipBlack", XtRBoolean,
1237         sizeof(Boolean), XtOffset(AppDataPtr, upsideDown),
1238         XtRImmediate, (XtPointer) False},
1239     { "allWhite", "allWhite", XtRBoolean,
1240         sizeof(Boolean), XtOffset(AppDataPtr, allWhite),
1241         XtRImmediate, (XtPointer) False},
1242     { "pieceToCharTable", "pieceToCharTable", XtRString,
1243         sizeof(String), XtOffset(AppDataPtr, pieceToCharTable),
1244         XtRImmediate, (XtPointer) 0},
1245     { "alphaRank", "alphaRank", XtRBoolean,
1246         sizeof(Boolean), XtOffset(AppDataPtr, alphaRank),
1247         XtRImmediate, (XtPointer) False},
1248     { "testClaims", "testClaims", XtRBoolean,
1249         sizeof(Boolean), XtOffset(AppDataPtr, testClaims),
1250         XtRImmediate, (XtPointer) True},
1251     { "checkMates", "checkMates", XtRBoolean,
1252         sizeof(Boolean), XtOffset(AppDataPtr, checkMates),
1253         XtRImmediate, (XtPointer) True},
1254     { "materialDraws", "materialDraws", XtRBoolean,
1255         sizeof(Boolean), XtOffset(AppDataPtr, materialDraws),
1256         XtRImmediate, (XtPointer) True},
1257     { "trivialDraws", "trivialDraws", XtRBoolean,
1258         sizeof(Boolean), XtOffset(AppDataPtr, trivialDraws),
1259         XtRImmediate, (XtPointer) False},
1260     { "ruleMoves", "ruleMoves", XtRInt,
1261         sizeof(int), XtOffset(AppDataPtr, ruleMoves),
1262         XtRImmediate, (XtPointer) 51},
1263     { "repeatsToDraw", "repeatsToDraw", XtRInt,
1264         sizeof(int), XtOffset(AppDataPtr, drawRepeats),
1265         XtRImmediate, (XtPointer) 6},
1266     { "engineDebugOutput", "engineDebugOutput", XtRInt,
1267         sizeof(int), XtOffset(AppDataPtr, engineComments),
1268         XtRImmediate, (XtPointer) 1},
1269     { "userName", "userName", XtRString,
1270         sizeof(int), XtOffset(AppDataPtr, userName),
1271         XtRImmediate, (XtPointer) 0},
1272     { "autoKibitz", "autoKibitz", XtRBoolean,
1273         sizeof(Boolean), XtOffset(AppDataPtr, autoKibitz),
1274         XtRImmediate, (XtPointer) False},
1275     { "firstTimeOdds", "firstTimeOdds", XtRInt,
1276         sizeof(int), XtOffset(AppDataPtr, firstTimeOdds),
1277         XtRImmediate, (XtPointer) 1},
1278     { "secondTimeOdds", "secondTimeOdds", XtRInt,
1279         sizeof(int), XtOffset(AppDataPtr, secondTimeOdds),
1280         XtRImmediate, (XtPointer) 1},
1281     { "timeOddsMode", "timeOddsMode", XtRInt,
1282         sizeof(int), XtOffset(AppDataPtr, timeOddsMode),
1283         XtRImmediate, (XtPointer) 0},
1284     { "firstAccumulateTC", "firstAccumulateTC", XtRInt,
1285         sizeof(int), XtOffset(AppDataPtr, firstAccumulateTC),
1286         XtRImmediate, (XtPointer) 1},
1287     { "secondAccumulateTC", "secondAccumulateTC", XtRInt,
1288         sizeof(int), XtOffset(AppDataPtr, secondAccumulateTC),
1289         XtRImmediate, (XtPointer) 1},
1290     { "firstNPS", "firstNPS", XtRInt,
1291         sizeof(int), XtOffset(AppDataPtr, firstNPS),
1292         XtRImmediate, (XtPointer) -1},
1293     { "secondNPS", "secondNPS", XtRInt,
1294         sizeof(int), XtOffset(AppDataPtr, secondNPS),
1295         XtRImmediate, (XtPointer) -1},
1296     { "serverMoves", "serverMoves", XtRString,
1297         sizeof(String), XtOffset(AppDataPtr, serverMovesName),
1298         XtRImmediate, (XtPointer) 0},
1299     { "serverPause", "serverPause", XtRInt,
1300         sizeof(int), XtOffset(AppDataPtr, serverPause),
1301         XtRImmediate, (XtPointer) 0},
1302     { "suppressLoadMoves", "suppressLoadMoves", XtRBoolean,
1303         sizeof(Boolean), XtOffset(AppDataPtr, suppressLoadMoves),
1304         XtRImmediate, (XtPointer) False},
1305     { "userName", "userName", XtRString,
1306         sizeof(String), XtOffset(AppDataPtr, userName),
1307         XtRImmediate, (XtPointer) 0},
1308     { "egtFormats", "egtFormats", XtRString,
1309         sizeof(String), XtOffset(AppDataPtr, egtFormats),
1310         XtRImmediate, (XtPointer) 0},
1311     { "rewindIndex", "rewindIndex", XtRInt,
1312         sizeof(int), XtOffset(AppDataPtr, rewindIndex),
1313         XtRImmediate, (XtPointer) 0},
1314     { "sameColorGames", "sameColorGames", XtRInt,
1315         sizeof(int), XtOffset(AppDataPtr, sameColorGames),
1316         XtRImmediate, (XtPointer) 0},
1317     { "smpCores", "smpCores", XtRInt,
1318         sizeof(int), XtOffset(AppDataPtr, smpCores),
1319         XtRImmediate, (XtPointer) 1},
1320     { "niceEngines", "niceEngines", XtRInt,
1321         sizeof(int), XtOffset(AppDataPtr, niceEngines),
1322         XtRImmediate, (XtPointer) 0},
1323     { "nameOfDebugFile", "nameOfDebugFile", XtRString,
1324         sizeof(String), XtOffset(AppDataPtr, nameOfDebugFile),
1325         XtRImmediate, (XtPointer) "xboard.debug"},
1326     { "engineDebugOutput", "engineDebugOutput", XtRInt,
1327         sizeof(int), XtOffset(AppDataPtr, engineComments),
1328         XtRImmediate, (XtPointer) 0},
1329     { "noGUI", "noGUI", XtRBoolean,
1330         sizeof(Boolean), XtOffset(AppDataPtr, noGUI),
1331         XtRImmediate, (XtPointer) 0},
1332     { "firstOptions", "firstOptions", XtRString,
1333         sizeof(String), XtOffset(AppDataPtr, firstOptions),
1334         XtRImmediate, (XtPointer) "" },
1335     { "secondOptions", "secondOptions", XtRString,
1336         sizeof(String), XtOffset(AppDataPtr, secondOptions),
1337         XtRImmediate, (XtPointer) "" },
1338     { "firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XtRString,
1339         sizeof(String), XtOffset(AppDataPtr, fenOverride1),
1340         XtRImmediate, (XtPointer) 0 },
1341     { "secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XtRString,
1342         sizeof(String), XtOffset(AppDataPtr, fenOverride2),
1343         XtRImmediate, (XtPointer) 0 },
1344
1345     // [HGM] Winboard_x UCI options
1346     { "firstIsUCI", "firstIsUCI", XtRBoolean,
1347         sizeof(Boolean), XtOffset(AppDataPtr, firstIsUCI),
1348         XtRImmediate, (XtPointer) False},
1349     { "secondIsUCI", "secondIsUCI", XtRBoolean,
1350         sizeof(Boolean), XtOffset(AppDataPtr, secondIsUCI),
1351         XtRImmediate, (XtPointer) False},
1352     { "firstHasOwnBookUCI", "firstHasOwnBookUCI", XtRBoolean,
1353         sizeof(Boolean), XtOffset(AppDataPtr, firstHasOwnBookUCI),
1354         XtRImmediate, (XtPointer) True},
1355     { "secondHasOwnBookUCI", "secondHasOwnBookUCI", XtRBoolean,
1356         sizeof(Boolean), XtOffset(AppDataPtr, secondHasOwnBookUCI),
1357         XtRImmediate, (XtPointer) True},
1358     { "usePolyglotBook", "usePolyglotBook", XtRBoolean,
1359         sizeof(Boolean), XtOffset(AppDataPtr, usePolyglotBook),
1360         XtRImmediate, (XtPointer) False},
1361     { "defaultHashSize", "defaultHashSize", XtRInt,
1362         sizeof(int), XtOffset(AppDataPtr, defaultHashSize),
1363         XtRImmediate, (XtPointer) 64},
1364     { "defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XtRInt,
1365         sizeof(int), XtOffset(AppDataPtr, defaultCacheSizeEGTB),
1366         XtRImmediate, (XtPointer) 4},
1367     { "polyglotDir", "polyglotDir", XtRString,
1368         sizeof(String), XtOffset(AppDataPtr, polyglotDir),
1369         XtRImmediate, (XtPointer) "." },
1370     { "polyglotBook", "polyglotBook", XtRString,
1371         sizeof(String), XtOffset(AppDataPtr, polyglotBook),
1372         XtRImmediate, (XtPointer) "" },
1373     { "defaultPathEGTB", "defaultPathEGTB", XtRString,
1374         sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),
1375         XtRImmediate, (XtPointer) "/usr/local/share/egtb"},
1376     { "delayBeforeQuit", "delayBeforeQuit", XtRInt,
1377         sizeof(int), XtOffset(AppDataPtr, delayBeforeQuit),
1378         XtRImmediate, (XtPointer) 0},
1379     { "delayAfterQuit", "delayAfterQuit", XtRInt,
1380         sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
1381         XtRImmediate, (XtPointer) 0},
1382 };
1383
1384 XrmOptionDescRec shellOptions[] = {
1385     { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
1386     { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
1387     { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
1388     { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
1389     { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },
1390     { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},
1391     { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
1392     { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
1393     { "-timeIncrement", "timeIncrement", XrmoptionSepArg, NULL },
1394     { "-inc", "timeIncrement", XrmoptionSepArg, NULL },
1395     { "-initString", "initString", XrmoptionSepArg, NULL },
1396     { "-firstInitString", "initString", XrmoptionSepArg, NULL },
1397     { "-secondInitString", "secondInitString", XrmoptionSepArg, NULL },
1398     { "-firstComputerString", "firstComputerString", XrmoptionSepArg, NULL },
1399     { "-secondComputerString", "secondComputerString", XrmoptionSepArg, NULL },
1400     { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
1401     { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
1402     { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
1403     { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
1404     { "-firstPlaysBlack", "firstPlaysBlack", XrmoptionSepArg, NULL },
1405     { "-fb", "firstPlaysBlack", XrmoptionNoArg, "True" },
1406     { "-xfb", "firstPlaysBlack", XrmoptionNoArg, "False" },
1407     { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
1408     { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },
1409     { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },
1410     { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
1411     { "-fh", "firstHost", XrmoptionSepArg, NULL },
1412     { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
1413     { "-sh", "secondHost", XrmoptionSepArg, NULL },
1414     { "-firstDirectory", "firstDirectory", XrmoptionSepArg, NULL },
1415     { "-fd", "firstDirectory", XrmoptionSepArg, NULL },
1416     { "-secondDirectory", "secondDirectory", XrmoptionSepArg, NULL },
1417     { "-sd", "secondDirectory", XrmoptionSepArg, NULL },
1418     { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },
1419     { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },
1420     { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
1421     { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
1422     { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },
1423     { "-ruser", "remoteUser", XrmoptionSepArg, NULL },
1424     { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
1425     { "-td", "timeDelay", XrmoptionSepArg, NULL },
1426     { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
1427     { "-tc", "timeControl", XrmoptionSepArg, NULL },
1428     { "-internetChessServerMode", "internetChessServerMode",
1429         XrmoptionSepArg, NULL },
1430     { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },
1431     { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },
1432     { "-internetChessServerHost", "internetChessServerHost",
1433         XrmoptionSepArg, NULL },
1434     { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
1435     { "-internetChessServerPort", "internetChessServerPort",
1436         XrmoptionSepArg, NULL },
1437     { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
1438     { "-internetChessServerCommPort", "internetChessServerCommPort",
1439         XrmoptionSepArg, NULL },
1440     { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },
1441     { "-internetChessServerLogonScript", "internetChessServerLogonScript",
1442         XrmoptionSepArg, NULL },
1443     { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },
1444     { "-internetChessServerHelper", "internetChessServerHelper",
1445         XrmoptionSepArg, NULL },
1446     { "-icshelper", "internetChessServerHelper", XrmoptionSepArg, NULL },
1447     { "-internetChessServerInputBox", "internetChessServerInputBox",
1448         XrmoptionSepArg, NULL },
1449     { "-icsinput", "internetChessServerInputBox", XrmoptionNoArg, "True" },
1450     { "-xicsinput", "internetChessServerInputBox", XrmoptionNoArg, "False" },
1451     { "-icsAlarm", "icsAlarm", XrmoptionSepArg, NULL },
1452     { "-alarm", "icsAlarm", XrmoptionNoArg, "True" },
1453     { "-xalarm", "icsAlarm", XrmoptionNoArg, "False" },
1454     { "-icsAlarmTime", "icsAlarmTime", XrmoptionSepArg, NULL },
1455     { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },
1456     { "-telnet", "useTelnet", XrmoptionNoArg, "True" },
1457     { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },
1458     { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },
1459     { "-gateway", "gateway", XrmoptionSepArg, NULL },
1460     { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
1461     { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
1462     { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },
1463     { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },
1464     { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
1465     { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
1466     { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
1467     { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },
1468     { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },
1469     { "-autoRaiseBoard", "autoRaiseBoard", XrmoptionSepArg, NULL },
1470     { "-autoraise", "autoRaiseBoard", XrmoptionNoArg, "True" },
1471     { "-xautoraise", "autoRaiseBoard", XrmoptionNoArg, "False" },
1472     { "-blindfold", "blindfold", XrmoptionSepArg, NULL },
1473     { "-blind", "blindfold", XrmoptionNoArg, "True" },
1474     { "-xblind", "blindfold", XrmoptionNoArg, "False" },
1475     { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
1476     { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
1477     { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },
1478     { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },
1479     { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
1480     { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
1481     { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
1482     { "-mm", "matchMode", XrmoptionNoArg, "True" },
1483     { "-xmm", "matchMode", XrmoptionNoArg, "False" },
1484     { "-matchGames", "matchGames", XrmoptionSepArg, NULL },
1485     { "-mg", "matchGames", XrmoptionSepArg, NULL },
1486     { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
1487     { "-mono", "monoMode", XrmoptionNoArg, "True" },
1488     { "-xmono", "monoMode", XrmoptionNoArg, "False" },
1489     { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
1490     { "-debug", "debugMode", XrmoptionNoArg, "True" },
1491     { "-xdebug", "debugMode", XrmoptionNoArg, "False" },
1492     { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
1493     { "-clock", "clockMode", XrmoptionNoArg, "True" },
1494     { "-xclock", "clockMode", XrmoptionNoArg, "False" },
1495     { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
1496     { "-size", "boardSize", XrmoptionSepArg, NULL },
1497     { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
1498     { "-st", "searchTime", XrmoptionSepArg, NULL },
1499     { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
1500     { "-depth", "searchDepth", XrmoptionSepArg, NULL },
1501     { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
1502     { "-coords", "showCoords", XrmoptionNoArg, "True" },
1503     { "-xcoords", "showCoords", XrmoptionNoArg, "False" },
1504 #if JAIL
1505     { "-showJail", "showJail", XrmoptionSepArg, NULL },
1506     { "-jail", "showJail", XrmoptionNoArg, "1" },
1507     { "-sidejail", "showJail", XrmoptionNoArg, "2" },
1508     { "-xjail", "showJail", XrmoptionNoArg, "0" },
1509 #endif
1510     { "-showThinking", "showThinking", XrmoptionSepArg, NULL },
1511     { "-thinking", "showThinking", XrmoptionNoArg, "True" },
1512     { "-xthinking", "showThinking", XrmoptionNoArg, "False" },
1513     { "-ponderNextMove", "ponderNextMove", XrmoptionSepArg, NULL },
1514     { "-ponder", "ponderNextMove", XrmoptionNoArg, "True" },
1515     { "-xponder", "ponderNextMove", XrmoptionNoArg, "False" },
1516     { "-periodicUpdates", "periodicUpdates", XrmoptionSepArg, NULL },
1517     { "-periodic", "periodicUpdates", XrmoptionNoArg, "True" },
1518     { "-xperiodic", "periodicUpdates", XrmoptionNoArg, "False" },
1519     { "-clockFont", "clockFont", XrmoptionSepArg, NULL },
1520     { "-coordFont", "coordFont", XrmoptionSepArg, NULL },
1521     { "-font", "font", XrmoptionSepArg, NULL },
1522     { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
1523     { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },
1524     { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },
1525     { "-movesound", "ringBellAfterMoves", XrmoptionNoArg, "True" },
1526     { "-xmovesound", "ringBellAfterMoves", XrmoptionNoArg, "False" },
1527     { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },
1528     { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },
1529     { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },
1530     { "-autoFlipView", "autoFlipView", XrmoptionSepArg, NULL },
1531     { "-autoflip", "autoFlipView", XrmoptionNoArg, "True" },
1532     { "-xautoflip", "autoFlipView", XrmoptionNoArg, "False" },
1533     { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },
1534     { "-autobs", "autoObserve", XrmoptionNoArg, "True" },
1535     { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },
1536     { "-autoComment", "autoComment", XrmoptionSepArg, NULL },
1537     { "-autocomm", "autoComment", XrmoptionNoArg, "True" },
1538     { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },
1539     { "-getMoveList", "getMoveList", XrmoptionSepArg, NULL },
1540     { "-moves", "getMoveList", XrmoptionNoArg, "True" },
1541     { "-xmoves", "getMoveList", XrmoptionNoArg, "False" },
1542 #if HIGHDRAG
1543     { "-highlightDragging", "highlightDragging", XrmoptionSepArg, NULL },
1544     { "-highdrag", "highlightDragging", XrmoptionNoArg, "True" },
1545     { "-xhighdrag", "highlightDragging", XrmoptionNoArg, "False" },
1546 #endif
1547     { "-highlightLastMove", "highlightLastMove", XrmoptionSepArg, NULL },
1548     { "-highlight", "highlightLastMove", XrmoptionNoArg, "True" },
1549     { "-xhighlight", "highlightLastMove", XrmoptionNoArg, "False" },
1550     { "-premove", "premove", XrmoptionSepArg, NULL },
1551     { "-pre", "premove", XrmoptionNoArg, "True" },
1552     { "-xpre", "premove", XrmoptionNoArg, "False" },
1553     { "-testLegality", "testLegality", XrmoptionSepArg, NULL },
1554     { "-legal", "testLegality", XrmoptionNoArg, "True" },
1555     { "-xlegal", "testLegality", XrmoptionNoArg, "False" },
1556     { "-flipView", "flipView", XrmoptionSepArg, NULL },
1557     { "-flip", "flipView", XrmoptionNoArg, "True" },
1558     { "-xflip", "flipView", XrmoptionNoArg, "False" },
1559     { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },
1560     { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",
1561         XrmoptionSepArg, NULL },
1562     { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },
1563     { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },
1564     { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },
1565     { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },
1566     { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },
1567     { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },
1568     { "-quiet", "quietPlay", XrmoptionNoArg, "True" },
1569     { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },
1570     { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },
1571     { "-title", "titleInWindow", XrmoptionNoArg, "True" },
1572     { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },
1573 #ifdef ZIPPY
1574     { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },
1575     { "-zt", "zippyTalk", XrmoptionNoArg, "True" },
1576     { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },
1577     { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },
1578     { "-zp", "zippyPlay", XrmoptionNoArg, "True" },
1579     { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },
1580     { "-zippyLines", "zippyLines", XrmoptionSepArg, NULL },
1581     { "-zippyPinhead", "zippyPinhead", XrmoptionSepArg, NULL },
1582     { "-zippyPassword", "zippyPassword", XrmoptionSepArg, NULL },
1583     { "-zippyPassword2", "zippyPassword2", XrmoptionSepArg, NULL },
1584     { "-zippyWrongPassword", "zippyWrongPassword", XrmoptionSepArg, NULL },
1585     { "-zippyAcceptOnly", "zippyAcceptOnly", XrmoptionSepArg, NULL },
1586     { "-zippyUseI", "zippyUseI", XrmoptionSepArg, NULL },
1587     { "-zui", "zippyUseI", XrmoptionNoArg, "True" },
1588     { "-xzui", "zippyUseI", XrmoptionNoArg, "False" },
1589     { "-zippyBughouse", "zippyBughouse", XrmoptionSepArg, NULL },
1590     { "-zippyNoplayCrafty", "zippyNoplayCrafty", XrmoptionSepArg, NULL },
1591     { "-znc", "zippyNoplayCrafty", XrmoptionNoArg, "True" },
1592     { "-xznc", "zippyNoplayCrafty", XrmoptionNoArg, "False" },
1593     { "-zippyGameEnd", "zippyGameEnd", XrmoptionSepArg, NULL },
1594     { "-zippyGameStart", "zippyGameStart", XrmoptionSepArg, NULL },
1595     { "-zippyAdjourn", "zippyAdjourn", XrmoptionSepArg, NULL },
1596     { "-zadj", "zippyAdjourn", XrmoptionNoArg, "True" },
1597     { "-xzadj", "zippyAdjourn", XrmoptionNoArg, "False" },
1598     { "-zippyAbort", "zippyAbort", XrmoptionSepArg, NULL },
1599     { "-zab", "zippyAbort", XrmoptionNoArg, "True" },
1600     { "-xzab", "zippyAbort", XrmoptionNoArg, "False" },
1601     { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },
1602     { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },
1603     { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },
1604 #endif
1605     { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
1606     { "-flash", "flashCount", XrmoptionNoArg, "3" },
1607     { "-xflash", "flashCount", XrmoptionNoArg, "0" },
1608     { "-flashRate", "flashRate", XrmoptionSepArg, NULL },
1609     { "-pixmapDirectory", "pixmapDirectory", XrmoptionSepArg, NULL },
1610     { "-msLoginDelay", "msLoginDelay", XrmoptionSepArg, NULL },
1611     { "-pixmap", "pixmapDirectory", XrmoptionSepArg, NULL },
1612     { "-colorizeMessages", "colorizeMessages", XrmoptionSepArg, NULL },
1613     { "-colorize", "colorizeMessages", XrmoptionNoArg, "True" },
1614     { "-xcolorize", "colorizeMessages", XrmoptionNoArg, "False" },
1615     { "-colorShout", "colorShout", XrmoptionSepArg, NULL },
1616     { "-colorSShout", "colorSShout", XrmoptionSepArg, NULL },
1617     { "-colorCShout", "colorSShout", XrmoptionSepArg, NULL }, /*FICS name*/
1618     { "-colorChannel1", "colorChannel1", XrmoptionSepArg, NULL },
1619     { "-colorChannel", "colorChannel", XrmoptionSepArg, NULL },
1620     { "-colorKibitz", "colorKibitz", XrmoptionSepArg, NULL },
1621     { "-colorTell", "colorTell", XrmoptionSepArg, NULL },
1622     { "-colorChallenge", "colorChallenge", XrmoptionSepArg, NULL },
1623     { "-colorRequest", "colorRequest", XrmoptionSepArg, NULL },
1624     { "-colorSeek", "colorSeek", XrmoptionSepArg, NULL },
1625     { "-colorNormal", "colorNormal", XrmoptionSepArg, NULL },
1626     { "-soundProgram", "soundProgram", XrmoptionSepArg, NULL },
1627     { "-soundShout", "soundShout", XrmoptionSepArg, NULL },
1628     { "-soundSShout", "soundSShout", XrmoptionSepArg, NULL },
1629     { "-soundCShout", "soundSShout", XrmoptionSepArg, NULL }, /*FICS name*/
1630     { "-soundChannel1", "soundChannel1", XrmoptionSepArg, NULL },
1631     { "-soundChannel", "soundChannel", XrmoptionSepArg, NULL },
1632     { "-soundKibitz", "soundKibitz", XrmoptionSepArg, NULL },
1633     { "-soundTell", "soundTell", XrmoptionSepArg, NULL },
1634     { "-soundChallenge", "soundChallenge", XrmoptionSepArg, NULL },
1635     { "-soundRequest", "soundRequest", XrmoptionSepArg, NULL },
1636     { "-soundSeek", "soundSeek", XrmoptionSepArg, NULL },
1637     { "-soundMove", "soundMove", XrmoptionSepArg, NULL },
1638     { "-soundIcsWin", "soundIcsWin", XrmoptionSepArg, NULL },
1639     { "-soundIcsLoss", "soundIcsLoss", XrmoptionSepArg, NULL },
1640     { "-soundIcsDraw", "soundIcsDraw", XrmoptionSepArg, NULL },
1641     { "-soundIcsUnfinished", "soundIcsUnfinished", XrmoptionSepArg, NULL },
1642     { "-soundIcsAlarm", "soundIcsAlarm", XrmoptionSepArg, NULL },
1643     { "-reuseFirst", "reuseFirst", XrmoptionSepArg, NULL },
1644     { "-reuseChessPrograms", "reuseFirst", XrmoptionSepArg, NULL }, /*compat*/
1645     { "-reuse", "reuseFirst", XrmoptionNoArg, "True" },
1646     { "-xreuse", "reuseFirst", XrmoptionNoArg, "False" },
1647     { "-reuseSecond", "reuseSecond", XrmoptionSepArg, NULL },
1648     { "-reuse2", "reuseSecond", XrmoptionNoArg, "True" },
1649     { "-xreuse2", "reuseSecond", XrmoptionNoArg, "False" },
1650     { "-animateMoving", "animateMoving", XrmoptionSepArg, NULL },
1651     { "-animate", "animateMoving", XrmoptionNoArg, "True" },
1652     { "-xanimate", "animateMoving", XrmoptionNoArg, "False" },
1653     { "-animateDragging", "animateDragging", XrmoptionSepArg, NULL },
1654     { "-drag", "animateDragging", XrmoptionNoArg, "True" },
1655     { "-xdrag", "animateDragging", XrmoptionNoArg, "False" },
1656     { "-animateSpeed", "animateSpeed", XrmoptionSepArg, NULL },
1657     { "-popupExitMessage", "popupExitMessage", XrmoptionSepArg, NULL },
1658     { "-exit", "popupExitMessage", XrmoptionNoArg, "True" },
1659     { "-xexit", "popupExitMessage", XrmoptionNoArg, "False" },
1660     { "-popupMoveErrors", "popupMoveErrors", XrmoptionSepArg, NULL },
1661     { "-popup", "popupMoveErrors", XrmoptionNoArg, "True" },
1662     { "-xpopup", "popupMoveErrors", XrmoptionNoArg, "False" },
1663     { "-fontSizeTolerance", "fontSizeTolerance", XrmoptionSepArg, NULL },
1664     { "-initialMode", "initialMode", XrmoptionSepArg, NULL },
1665     { "-mode", "initialMode", XrmoptionSepArg, NULL },
1666     { "-variant", "variant", XrmoptionSepArg, NULL },
1667     { "-firstProtocolVersion", "firstProtocolVersion", XrmoptionSepArg, NULL },
1668     { "-secondProtocolVersion","secondProtocolVersion",XrmoptionSepArg, NULL },
1669     { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },
1670     { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },
1671     { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },
1672     /* [AS,HR] New features */
1673     { "-firstScoreAbs", "firstScoreAbs", XrmoptionSepArg, NULL },
1674     { "-secondScoreAbs", "secondScoreAbs", XrmoptionSepArg, NULL },
1675     { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
1676     { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
1677     { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
1678     { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
1679     { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
1680     { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
1681     { "-fUCI", "firstIsUCI", XrmoptionNoArg, "True" },
1682     { "-sUCI", "secondIsUCI", XrmoptionNoArg, "True" },
1683     { "-firstHasOwnBookUCI", "firstHasOwnBookUCI", XrmoptionSepArg, NULL },
1684     { "-secondHasOwnBookUCI", "secondHasOwnBookUCI", XrmoptionSepArg, NULL },
1685     { "-fNoOwnBookUCI", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
1686     { "-sNoOwnBookUCI", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
1687     { "-firstXBook", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
1688     { "-secondXBook", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
1689     { "-polyglotDir", "polyglotDir", XrmoptionSepArg, NULL },
1690     { "-usePolyglotBook", "usePolyglotBook", XrmoptionSepArg, NULL },
1691     { "-polyglotBook", "polyglotBook", XrmoptionSepArg, NULL },
1692     { "-defaultHashSize", "defaultHashSize", XrmoptionSepArg, NULL },
1693     { "-defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XrmoptionSepArg, NULL },
1694     { "-defaultPathEGTB", "defaultPathEGTB", XrmoptionSepArg, NULL },
1695     { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },
1696     { "-gameListTags", "gameListTags", XrmoptionSepArg, NULL },
1697     // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c
1698
1699     /* [HGM,HR] User-selectable board size */
1700     { "-boardWidth", "boardWidth", XrmoptionSepArg, NULL },
1701     { "-boardHeight", "boardHeight", XrmoptionSepArg, NULL },
1702     { "-matchPause", "matchPause", XrmoptionSepArg, NULL },
1703
1704     /* [HGM] new arguments of 4.3.xx. All except first three are back-end options, which should work immediately */
1705     { "-holdingsSize", "holdingsSize", XrmoptionSepArg, NULL }, // requires extensive front-end changes to work
1706     { "-flipBlack", "flipBlack", XrmoptionSepArg, NULL },       // requires front-end changes to work
1707     { "-allWhite", "allWhite", XrmoptionSepArg, NULL },         // requires front-end changes to work
1708     { "-pieceToCharTable", "pieceToCharTable", XrmoptionSepArg, NULL },
1709     { "-alphaRank", "alphaRank", XrmoptionSepArg, NULL },
1710     { "-testClaims", "testClaims", XrmoptionSepArg, NULL },
1711     { "-checkMates", "checkMates", XrmoptionSepArg, NULL },
1712     { "-materialDraws", "materialDraws", XrmoptionSepArg, NULL },
1713     { "-trivialDraws", "trivialDraws", XrmoptionSepArg, NULL },
1714     { "-ruleMoves", "ruleMoves", XrmoptionSepArg, NULL },
1715     { "-repeatsToDraw", "repeatsToDraw", XrmoptionSepArg, NULL },
1716     { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
1717     { "-userName", "userName", XrmoptionSepArg, NULL },
1718     { "-autoKibitz", "autoKibitz", XrmoptionNoArg, "True" },
1719     { "-firstTimeOdds", "firstTimeOdds", XrmoptionSepArg, NULL },
1720     { "-secondTimeOdds", "secondTimeOdds", XrmoptionSepArg, NULL },
1721     { "-timeOddsMode", "timeOddsMode", XrmoptionSepArg, NULL },
1722     { "-firstAccumulateTC", "firstAccumulateTC", XrmoptionSepArg, NULL },
1723     { "-secondAccumulateTC", "secondAccumulateTC", XrmoptionSepArg, NULL },
1724     { "-firstNPS", "firstNPS", XrmoptionSepArg, NULL },
1725     { "-secondNPS", "secondNPS", XrmoptionSepArg, NULL },
1726     { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL },
1727     { "-serverPause", "serverPause", XrmoptionSepArg, NULL },
1728     { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL },
1729     { "-egtFormats", "egtFormats", XrmoptionSepArg, NULL },
1730     { "-userName", "userName", XrmoptionSepArg, NULL },
1731     { "-smpCores", "smpCores", XrmoptionSepArg, NULL },
1732     { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL },
1733     { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL },
1734     { "-niceEngines", "niceEngines", XrmoptionSepArg, NULL },
1735     { "-delayBeforeQuit", "delayBeforeQuit", XrmoptionSepArg, NULL },
1736     { "-delayAfterQuit", "delayAfterQuit", XrmoptionSepArg, NULL },
1737     { "-nameOfDebugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
1738     { "-debugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
1739     { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
1740     { "-noGUI", "noGUI", XrmoptionNoArg, "True" },
1741     { "-firstOptions", "firstOptions", XrmoptionSepArg, NULL },
1742     { "-secondOptions", "secondOptions", XrmoptionSepArg, NULL },
1743     { "-firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
1744     { "-secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
1745 };
1746
1747
1748 XtActionsRec boardActions[] = {
1749     { "DrawPosition", DrawPositionProc },
1750     { "HandleUserMove", HandleUserMove },
1751     { "AnimateUserMove", AnimateUserMove },
1752     { "FileNameAction", FileNameAction },
1753     { "AskQuestionProc", AskQuestionProc },
1754     { "AskQuestionReplyAction", AskQuestionReplyAction },
1755     { "PieceMenuPopup", PieceMenuPopup },
1756     { "WhiteClock", WhiteClock },
1757     { "BlackClock", BlackClock },
1758     { "Iconify", Iconify },
1759     { "ResetProc", ResetProc },
1760     { "LoadGameProc", LoadGameProc },
1761     { "LoadNextGameProc", LoadNextGameProc },
1762     { "LoadPrevGameProc", LoadPrevGameProc },
1763     { "LoadSelectedProc", LoadSelectedProc },
1764     { "ReloadGameProc", ReloadGameProc },
1765     { "LoadPositionProc", LoadPositionProc },
1766     { "LoadNextPositionProc", LoadNextPositionProc },
1767     { "LoadPrevPositionProc", LoadPrevPositionProc },
1768     { "ReloadPositionProc", ReloadPositionProc },
1769     { "CopyPositionProc", CopyPositionProc },
1770     { "PastePositionProc", PastePositionProc },
1771     { "CopyGameProc", CopyGameProc },
1772     { "PasteGameProc", PasteGameProc },
1773     { "SaveGameProc", SaveGameProc },
1774     { "SavePositionProc", SavePositionProc },
1775     { "MailMoveProc", MailMoveProc },
1776     { "ReloadCmailMsgProc", ReloadCmailMsgProc },
1777     { "QuitProc", QuitProc },
1778     { "MachineWhiteProc", MachineWhiteProc },
1779     { "MachineBlackProc", MachineBlackProc },
1780     { "AnalysisModeProc", AnalyzeModeProc },
1781     { "AnalyzeFileProc", AnalyzeFileProc },
1782     { "TwoMachinesProc", TwoMachinesProc },
1783     { "IcsClientProc", IcsClientProc },
1784     { "EditGameProc", EditGameProc },
1785     { "EditPositionProc", EditPositionProc },
1786     { "TrainingProc", EditPositionProc },
1787     { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
1788     { "ShowGameListProc", ShowGameListProc },
1789     { "ShowMoveListProc", HistoryShowProc},
1790     { "EditTagsProc", EditCommentProc },
1791     { "EditCommentProc", EditCommentProc },
1792     { "IcsAlarmProc", IcsAlarmProc },
1793     { "IcsInputBoxProc", IcsInputBoxProc },
1794     { "PauseProc", PauseProc },
1795     { "AcceptProc", AcceptProc },
1796     { "DeclineProc", DeclineProc },
1797     { "RematchProc", RematchProc },
1798     { "CallFlagProc", CallFlagProc },
1799     { "DrawProc", DrawProc },
1800     { "AdjournProc", AdjournProc },
1801     { "AbortProc", AbortProc },
1802     { "ResignProc", ResignProc },
1803     { "AdjuWhiteProc", AdjuWhiteProc },
1804     { "AdjuBlackProc", AdjuBlackProc },
1805     { "AdjuDrawProc", AdjuDrawProc },
1806     { "EnterKeyProc", EnterKeyProc },
1807     { "StopObservingProc", StopObservingProc },
1808     { "StopExaminingProc", StopExaminingProc },
1809     { "BackwardProc", BackwardProc },
1810     { "ForwardProc", ForwardProc },
1811     { "ToStartProc", ToStartProc },
1812     { "ToEndProc", ToEndProc },
1813     { "RevertProc", RevertProc },
1814     { "TruncateGameProc", TruncateGameProc },
1815     { "MoveNowProc", MoveNowProc },
1816     { "RetractMoveProc", RetractMoveProc },
1817     { "AlwaysQueenProc", AlwaysQueenProc },
1818     { "AnimateDraggingProc", AnimateDraggingProc },
1819     { "AnimateMovingProc", AnimateMovingProc },
1820     { "AutoflagProc", AutoflagProc },
1821     { "AutoflipProc", AutoflipProc },
1822     { "AutobsProc", AutobsProc },
1823     { "AutoraiseProc", AutoraiseProc },
1824     { "AutosaveProc", AutosaveProc },
1825     { "BlindfoldProc", BlindfoldProc },
1826     { "FlashMovesProc", FlashMovesProc },
1827     { "FlipViewProc", FlipViewProc },
1828     { "GetMoveListProc", GetMoveListProc },
1829 #if HIGHDRAG
1830     { "HighlightDraggingProc", HighlightDraggingProc },
1831 #endif
1832     { "HighlightLastMoveProc", HighlightLastMoveProc },
1833     { "IcsAlarmProc", IcsAlarmProc },
1834     { "MoveSoundProc", MoveSoundProc },
1835     { "OldSaveStyleProc", OldSaveStyleProc },
1836     { "PeriodicUpdatesProc", PeriodicUpdatesProc },
1837     { "PonderNextMoveProc", PonderNextMoveProc },
1838     { "PopupExitMessageProc", PopupExitMessageProc },
1839     { "PopupMoveErrorsProc", PopupMoveErrorsProc },
1840     { "PremoveProc", PremoveProc },
1841     { "QuietPlayProc", QuietPlayProc },
1842     { "ShowCoordsProc", ShowCoordsProc },
1843     { "ShowThinkingProc", ShowThinkingProc },
1844     { "HideThinkingProc", HideThinkingProc },
1845     { "TestLegalityProc", TestLegalityProc },
1846     { "InfoProc", InfoProc },
1847     { "ManProc", ManProc },
1848     { "HintProc", HintProc },
1849     { "BookProc", BookProc },
1850     { "AboutGameProc", AboutGameProc },
1851     { "AboutProc", AboutProc },
1852     { "DebugProc", DebugProc },
1853     { "NothingProc", NothingProc },
1854     { "CommentPopDown", (XtActionProc) CommentPopDown },
1855     { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
1856     { "TagsPopDown", (XtActionProc) TagsPopDown },
1857     { "ErrorPopDown", (XtActionProc) ErrorPopDown },
1858     { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
1859     { "AnalysisPopDown", (XtActionProc) AnalysisPopDown },
1860     { "FileNamePopDown", (XtActionProc) FileNamePopDown },
1861     { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
1862     { "GameListPopDown", (XtActionProc) GameListPopDown },
1863     { "PromotionPopDown", (XtActionProc) PromotionPopDown },
1864     { "HistoryPopDown", (XtActionProc) HistoryPopDown },
1865     { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
1866     { "ShufflePopDown", (XtActionProc) ShufflePopDown },
1867     { "EnginePopDown", (XtActionProc) EnginePopDown },
1868     { "UciPopDown", (XtActionProc) UciPopDown },
1869     { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
1870     { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
1871     { "SettingsPopDown", (XtActionProc) SettingsPopDown },
1872 };
1873
1874 char globalTranslations[] =
1875   ":<Key>R: ResignProc() \n \
1876    :<Key>r: ResetProc() \n \
1877    :<Key>g: LoadGameProc() \n \
1878    :<Key>N: LoadNextGameProc() \n \
1879    :<Key>P: LoadPrevGameProc() \n \
1880    :<Key>Q: QuitProc() \n \
1881    :<Key>F: ToEndProc() \n \
1882    :<Key>f: ForwardProc() \n \
1883    :<Key>B: ToStartProc() \n \
1884    :<Key>b: BackwardProc() \n \
1885    :<Key>p: PauseProc() \n \
1886    :<Key>d: DrawProc() \n \
1887    :<Key>t: CallFlagProc() \n \
1888    :<Key>i: Iconify() \n \
1889    :<Key>c: Iconify() \n \
1890    :<Key>v: FlipViewProc() \n \
1891    <KeyDown>Control_L: BackwardProc() \n \
1892    <KeyUp>Control_L: ForwardProc() \n \
1893    <KeyDown>Control_R: BackwardProc() \n \
1894    <KeyUp>Control_R: ForwardProc() \n \
1895    Shift<Key>1: AskQuestionProc(\"Direct command\",\
1896                                 \"Send to chess program:\",,1) \n \
1897    Shift<Key>2: AskQuestionProc(\"Direct command\",\
1898                                 \"Send to second chess program:\",,2) \n";
1899
1900 char boardTranslations[] =
1901    "<Btn1Down>: HandleUserMove() \n \
1902    <Btn1Up>: HandleUserMove() \n \
1903    <Btn1Motion>: AnimateUserMove() \n \
1904    Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
1905                  PieceMenuPopup(menuB) \n \
1906    Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
1907                  PieceMenuPopup(menuW) \n \
1908    Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
1909                  PieceMenuPopup(menuW) \n \
1910    Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
1911                  PieceMenuPopup(menuB) \n";
1912
1913 char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
1914 char blackTranslations[] = "<BtnDown>: BlackClock()\n";
1915
1916 char ICSInputTranslations[] =
1917     "<Key>Return: EnterKeyProc() \n";
1918
1919 String xboardResources[] = {
1920     "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
1921     "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
1922     "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
1923     NULL
1924   };
1925
1926
1927 /* Max possible square size */
1928 #define MAXSQSIZE 256
1929
1930 static int xpm_avail[MAXSQSIZE];
1931
1932 #ifdef HAVE_DIR_STRUCT
1933
1934 /* Extract piece size from filename */
1935 static int
1936 xpm_getsize(name, len, ext)
1937      char *name;
1938      int len;
1939      char *ext;
1940 {
1941     char *p, *d;
1942     char buf[10];
1943
1944     if (len < 4)
1945       return 0;
1946
1947     if ((p=strchr(name, '.')) == NULL ||
1948         StrCaseCmp(p+1, ext) != 0)
1949       return 0;
1950
1951     p = name + 3;
1952     d = buf;
1953
1954     while (*p && isdigit(*p))
1955       *(d++) = *(p++);
1956
1957     *d = 0;
1958     return atoi(buf);
1959 }
1960
1961 /* Setup xpm_avail */
1962 static int
1963 xpm_getavail(dirname, ext)
1964      char *dirname;
1965      char *ext;
1966 {
1967     DIR *dir;
1968     struct dirent *ent;
1969     int  i;
1970
1971     for (i=0; i<MAXSQSIZE; ++i)
1972       xpm_avail[i] = 0;
1973
1974     if (appData.debugMode)
1975       fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);
1976
1977     dir = opendir(dirname);
1978     if (!dir)
1979       {
1980           fprintf(stderr, _("%s: Can't access XPM directory %s\n"),
1981                   programName, dirname);
1982           exit(1);
1983       }
1984
1985     while ((ent=readdir(dir)) != NULL) {
1986         i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);
1987         if (i > 0 && i < MAXSQSIZE)
1988           xpm_avail[i] = 1;
1989     }
1990
1991     closedir(dir);
1992
1993     return 0;
1994 }
1995
1996 void
1997 xpm_print_avail(fp, ext)
1998      FILE *fp;
1999      char *ext;
2000 {
2001     int i;
2002
2003     fprintf(fp, _("Available `%s' sizes:\n"), ext);
2004     for (i=1; i<MAXSQSIZE; ++i) {
2005         if (xpm_avail[i])
2006           printf("%d\n", i);
2007     }
2008 }
2009
2010 /* Return XPM piecesize closest to size */
2011 int
2012 xpm_closest_to(dirname, size, ext)
2013      char *dirname;
2014      int size;
2015      char *ext;
2016 {
2017     int i;
2018     int sm_diff = MAXSQSIZE;
2019     int sm_index = 0;
2020     int diff;
2021
2022     xpm_getavail(dirname, ext);
2023
2024     if (appData.debugMode)
2025       xpm_print_avail(stderr, ext);
2026
2027     for (i=1; i<MAXSQSIZE; ++i) {
2028         if (xpm_avail[i]) {
2029             diff = size - i;
2030             diff = (diff<0) ? -diff : diff;
2031             if (diff < sm_diff) {
2032                 sm_diff = diff;
2033                 sm_index = i;
2034             }
2035         }
2036     }
2037
2038     if (!sm_index) {
2039         fprintf(stderr, _("Error: No `%s' files!\n"), ext);
2040         exit(1);
2041     }
2042
2043     return sm_index;
2044 }
2045 #else   /* !HAVE_DIR_STRUCT */
2046 /* If we are on a system without a DIR struct, we can't
2047    read the directory, so we can't collect a list of
2048    filenames, etc., so we can't do any size-fitting. */
2049 int
2050 xpm_closest_to(dirname, size, ext)
2051      char *dirname;
2052      int size;
2053      char *ext;
2054 {
2055     fprintf(stderr, _("\
2056 Warning: No DIR structure found on this system --\n\
2057          Unable to autosize for XPM/XIM pieces.\n\
2058    Please report this error to frankm@hiwaay.net.\n\
2059    Include system type & operating system in message.\n"));
2060     return size;
2061 }
2062 #endif /* HAVE_DIR_STRUCT */
2063
2064 static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
2065                              "magenta", "cyan", "white" };
2066 typedef struct {
2067     int attr, bg, fg;
2068 } TextColors;
2069 TextColors textColors[(int)NColorClasses];
2070
2071 /* String is: "fg, bg, attr". Which is 0, 1, 2 */
2072 static int
2073 parse_color(str, which)
2074      char *str;
2075      int which;
2076 {
2077     char *p, buf[100], *d;
2078     int i;
2079
2080     if (strlen(str) > 99)       /* watch bounds on buf */
2081       return -1;
2082
2083     p = str;
2084     d = buf;
2085     for (i=0; i<which; ++i) {
2086         p = strchr(p, ',');
2087         if (!p)
2088           return -1;
2089         ++p;
2090     }
2091
2092     /* Could be looking at something like:
2093        black, , 1
2094        .. in which case we want to stop on a comma also */
2095     while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
2096       ++p;
2097
2098     if (*p == ',') {
2099         return -1;              /* Use default for empty field */
2100     }
2101
2102     if (which == 2 || isdigit(*p))
2103       return atoi(p);
2104
2105     while (*p && isalpha(*p))
2106       *(d++) = *(p++);
2107
2108     *d = 0;
2109
2110     for (i=0; i<8; ++i) {
2111         if (!StrCaseCmp(buf, cnames[i]))
2112           return which? (i+40) : (i+30);
2113     }
2114     if (!StrCaseCmp(buf, "default")) return -1;
2115
2116     fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
2117     return -2;
2118 }
2119
2120 static int
2121 parse_cpair(cc, str)
2122      ColorClass cc;
2123      char *str;
2124 {
2125     if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
2126         fprintf(stderr, _("%s: can't parse foreground color in `%s'\n"),
2127                 programName, str);
2128         return -1;
2129     }
2130
2131     /* bg and attr are optional */
2132     textColors[(int)cc].bg = parse_color(str, 1);
2133     if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
2134         textColors[(int)cc].attr = 0;
2135     }
2136     return 0;
2137 }
2138
2139
2140 /* Arrange to catch delete-window events */
2141 Atom wm_delete_window;
2142 void
2143 CatchDeleteWindow(Widget w, String procname)
2144 {
2145   char buf[MSG_SIZ];
2146   XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);
2147   sprintf(buf, "<Message>WM_PROTOCOLS: %s() \n", procname);
2148   XtAugmentTranslations(w, XtParseTranslationTable(buf));
2149 }
2150
2151 void
2152 BoardToTop()
2153 {
2154   Arg args[16];
2155   XtSetArg(args[0], XtNiconic, False);
2156   XtSetValues(shellWidget, args, 1);
2157
2158   XtPopup(shellWidget, XtGrabNone); /* Raise if lowered  */
2159 }
2160
2161 #ifdef IDSIZES
2162   // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
2163 #else
2164 #define BoardSize int
2165 void InitDrawingSizes(BoardSize boardSize, int flags)
2166 {   // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
2167     Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
2168     Arg args[16];
2169     XtGeometryResult gres;
2170     int i;
2171
2172     if(!formWidget) return;
2173
2174     /*
2175      * Enable shell resizing.
2176      */
2177     shellArgs[0].value = (XtArgVal) &w;
2178     shellArgs[1].value = (XtArgVal) &h;
2179     XtGetValues(shellWidget, shellArgs, 2);
2180
2181     shellArgs[4].value = 2*w; shellArgs[2].value = 10;
2182     shellArgs[5].value = 2*h; shellArgs[3].value = 10;
2183     XtSetValues(shellWidget, &shellArgs[2], 4);
2184
2185     XtSetArg(args[0], XtNdefaultDistance, &sep);
2186     XtGetValues(formWidget, args, 1);
2187
2188     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
2189     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
2190     CreateGrid();
2191
2192     XtSetArg(args[0], XtNwidth, boardWidth);
2193     XtSetArg(args[1], XtNheight, boardHeight);
2194     XtSetValues(boardWidget, args, 2);
2195
2196     timerWidth = (boardWidth - sep) / 2;
2197     XtSetArg(args[0], XtNwidth, timerWidth);
2198     XtSetValues(whiteTimerWidget, args, 1);
2199     XtSetValues(blackTimerWidget, args, 1);
2200
2201     XawFormDoLayout(formWidget, False);
2202
2203     if (appData.titleInWindow) {
2204         i = 0;
2205         XtSetArg(args[i], XtNborderWidth, &bor); i++;
2206         XtSetArg(args[i], XtNheight, &h);  i++;
2207         XtGetValues(titleWidget, args, i);
2208         if (smallLayout) {
2209             w = boardWidth - 2*bor;
2210         } else {
2211             XtSetArg(args[0], XtNwidth, &w);
2212             XtGetValues(menuBarWidget, args, 1);
2213             w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE
2214         }
2215
2216         gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
2217         if (gres != XtGeometryYes && appData.debugMode) {
2218             fprintf(stderr,
2219                     _("%s: titleWidget geometry error %d %d %d %d %d\n"),
2220                     programName, gres, w, h, wr, hr);
2221         }
2222     }
2223
2224     XawFormDoLayout(formWidget, True);
2225
2226     /*
2227      * Inhibit shell resizing.
2228      */
2229     shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
2230     shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
2231     shellArgs[4].value = shellArgs[2].value = w;
2232     shellArgs[5].value = shellArgs[3].value = h;
2233     XtSetValues(shellWidget, &shellArgs[0], 6);
2234 }
2235 #endif
2236
2237 int
2238 main(argc, argv)
2239      int argc;
2240      char **argv;
2241 {
2242     int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
2243     XSetWindowAttributes window_attributes;
2244     Arg args[16];
2245     Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
2246     XrmValue vFrom, vTo;
2247     XtGeometryResult gres;
2248     char *p;
2249     XrmDatabase xdb;
2250     int forceMono = False;
2251 #define INDIRECTION
2252 #ifdef INDIRECTION
2253     // [HGM] before anything else, expand any indirection files amongst options
2254     char *argvCopy[1000]; // 1000 seems enough
2255     char newArgs[10000];  // holds actual characters
2256     int k = 0;
2257
2258     srandom(time(0)); // [HGM] book: make random truly random
2259
2260     j = 0;
2261     for(i=0; i<argc; i++) {
2262         if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2263 //fprintf(stderr, "arg %s\n", argv[i]);
2264         if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
2265             char c;
2266             FILE *f = fopen(argv[i]+1, "rb");
2267             if(f == NULL) { fprintf(stderr, _("ignore %s\n"), argv[i]); continue; } // do not expand non-existing
2268             argvCopy[j++] = newArgs + k; // get ready for first argument from file
2269             while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
2270                 if(c == '\n') {
2271                     if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2272                     newArgs[k++] = 0;  // terminate current arg
2273                     if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2274                     argvCopy[j++] = newArgs + k; // get ready for next
2275                 } else {
2276                     if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2277                     newArgs[k++] = c;
2278                 }
2279             }
2280             newArgs[k] = 0;
2281             j--;
2282             fclose(f);
2283         }
2284     }
2285     argvCopy[j] = NULL;
2286     argv = argvCopy;
2287     argc = j;
2288 #if 0
2289     if(appData.debugMode,1) { // OK, appData is not initialized here yet...
2290         for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
2291     }
2292 #endif
2293 #endif
2294
2295
2296     setbuf(stdout, NULL);
2297     setbuf(stderr, NULL);
2298     debugFP = stderr;
2299
2300     programName = strrchr(argv[0], '/');
2301     if (programName == NULL)
2302       programName = argv[0];
2303     else
2304       programName++;
2305
2306 #ifdef ENABLE_NLS
2307     XtSetLanguageProc(NULL, NULL, NULL);
2308     bindtextdomain(PRODUCT, LOCALEDIR);
2309     textdomain(PRODUCT);
2310 #endif
2311
2312     shellWidget =
2313       XtAppInitialize(&appContext, "XBoard", shellOptions,
2314                       XtNumber(shellOptions),
2315                       &argc, argv, xboardResources, NULL, 0);
2316     if (argc > 1) {
2317         fprintf(stderr, _("%s: unrecognized argument %s\n"),
2318                 programName, argv[1]);
2319         exit(2);
2320     }
2321
2322     if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
2323         chessDir = ".";
2324     } else {
2325         if (chdir(chessDir) != 0) {
2326             fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
2327             perror(chessDir);
2328             exit(1);
2329         }
2330     }
2331
2332     p = getenv("HOME");
2333     if (p == NULL) p = "/tmp";
2334     i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
2335     gameCopyFilename = (char*) malloc(i);
2336     gamePasteFilename = (char*) malloc(i);
2337     sprintf(gameCopyFilename, "%s/.xboard%05uc.pgn", p, getpid());
2338     sprintf(gamePasteFilename, "%s/.xboard%05up.pgn", p, getpid());
2339
2340     XtGetApplicationResources(shellWidget, (XtPointer) &appData,
2341                               clientResources, XtNumber(clientResources),
2342                               NULL, 0);
2343
2344     if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
2345         /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
2346         if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL)  {
2347            printf(_("Failed to open file '%s'\n"), appData.nameOfDebugFile);
2348            exit(errno);
2349         }
2350         setbuf(debugFP, NULL);
2351     }
2352
2353     /* [HGM,HR] make sure board size is acceptable */
2354     if(appData.NrFiles > BOARD_SIZE ||
2355        appData.NrRanks > BOARD_SIZE   )
2356          DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
2357
2358 #if !HIGHDRAG
2359     /* This feature does not work; animation needs a rewrite */
2360     appData.highlightDragging = FALSE;
2361 #endif
2362     InitBackEnd1();
2363
2364     xDisplay = XtDisplay(shellWidget);
2365     xScreen = DefaultScreen(xDisplay);
2366     wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
2367
2368         gameInfo.variant = StringToVariant(appData.variant);
2369         InitPosition(FALSE);
2370 #if 0
2371     /*
2372      * Determine boardSize
2373      */
2374     gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
2375
2376 //#ifndef IDSIZE
2377     // [HGM] as long as we have not created the possibility to change size while running, start with requested size
2378     gameInfo.boardWidth    = appData.NrFiles > 0 ? appData.NrFiles : 8;
2379     gameInfo.boardHeight   = appData.NrRanks > 0 ? appData.NrRanks : 8;
2380     gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
2381 #endif
2382
2383
2384 #ifdef IDSIZE
2385     InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
2386 #else
2387     if (isdigit(appData.boardSize[0])) {
2388         i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
2389                    &lineGap, &clockFontPxlSize, &coordFontPxlSize,
2390                    &fontPxlSize, &smallLayout, &tinyLayout);
2391         if (i == 0) {
2392             fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
2393                     programName, appData.boardSize);
2394             exit(2);
2395         }
2396         if (i < 7) {
2397             /* Find some defaults; use the nearest known size */
2398             SizeDefaults *szd, *nearest;
2399             int distance = 99999;
2400             nearest = szd = sizeDefaults;
2401             while (szd->name != NULL) {
2402                 if (abs(szd->squareSize - squareSize) < distance) {
2403                     nearest = szd;
2404                     distance = abs(szd->squareSize - squareSize);
2405                     if (distance == 0) break;
2406                 }
2407                 szd++;
2408             }
2409             if (i < 2) lineGap = nearest->lineGap;
2410             if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
2411             if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
2412             if (i < 5) fontPxlSize = nearest->fontPxlSize;
2413             if (i < 6) smallLayout = nearest->smallLayout;
2414             if (i < 7) tinyLayout = nearest->tinyLayout;
2415         }
2416     } else {
2417         SizeDefaults *szd = sizeDefaults;
2418         if (*appData.boardSize == NULLCHAR) {
2419             while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
2420                    DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
2421               szd++;
2422             }
2423             if (szd->name == NULL) szd--;
2424         } else {
2425             while (szd->name != NULL &&
2426                    StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
2427             if (szd->name == NULL) {
2428                 fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
2429                         programName, appData.boardSize);
2430                 exit(2);
2431             }
2432         }
2433         squareSize = szd->squareSize;
2434         lineGap = szd->lineGap;
2435         clockFontPxlSize = szd->clockFontPxlSize;
2436         coordFontPxlSize = szd->coordFontPxlSize;
2437         fontPxlSize = szd->fontPxlSize;
2438         smallLayout = szd->smallLayout;
2439         tinyLayout = szd->tinyLayout;
2440     }
2441
2442     /* Now, using squareSize as a hint, find a good XPM/XIM set size */
2443     if (strlen(appData.pixmapDirectory) > 0) {
2444         p = ExpandPathName(appData.pixmapDirectory);
2445         if (!p) {
2446             fprintf(stderr, _("Error expanding path name \"%s\"\n"),
2447                    appData.pixmapDirectory);
2448             exit(1);
2449         }
2450         if (appData.debugMode) {
2451           fprintf(stderr, _("\
2452 XBoard square size (hint): %d\n\
2453 %s fulldir:%s:\n"), squareSize, IMAGE_EXT, p);
2454         }
2455         squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
2456         if (appData.debugMode) {
2457             fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
2458         }
2459     }
2460
2461     /* [HR] height treated separately (hacked) */
2462     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
2463     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
2464     if (appData.showJail == 1) {
2465         /* Jail on top and bottom */
2466         XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2467         XtSetArg(boardArgs[2], XtNheight,
2468                  boardHeight + 2*(lineGap + squareSize));
2469     } else if (appData.showJail == 2) {
2470         /* Jail on sides */
2471         XtSetArg(boardArgs[1], XtNwidth,
2472                  boardWidth + 2*(lineGap + squareSize));
2473         XtSetArg(boardArgs[2], XtNheight, boardHeight);
2474     } else {
2475         /* No jail */
2476         XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2477         XtSetArg(boardArgs[2], XtNheight, boardHeight);
2478     }
2479
2480     /*
2481      * Determine what fonts to use.
2482      */
2483     appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
2484     clockFontID = XLoadFont(xDisplay, appData.clockFont);
2485     clockFontStruct = XQueryFont(xDisplay, clockFontID);
2486     appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
2487     coordFontID = XLoadFont(xDisplay, appData.coordFont);
2488     coordFontStruct = XQueryFont(xDisplay, coordFontID);
2489     appData.font = FindFont(appData.font, fontPxlSize);
2490     countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
2491     countFontStruct = XQueryFont(xDisplay, countFontID);
2492 //    appData.font = FindFont(appData.font, fontPxlSize);
2493
2494     xdb = XtDatabase(xDisplay);
2495     XrmPutStringResource(&xdb, "*font", appData.font);
2496
2497     /*
2498      * Detect if there are not enough colors available and adapt.
2499      */
2500     if (DefaultDepth(xDisplay, xScreen) <= 2) {
2501       appData.monoMode = True;
2502     }
2503
2504     if (!appData.monoMode) {
2505         vFrom.addr = (caddr_t) appData.lightSquareColor;
2506         vFrom.size = strlen(appData.lightSquareColor);
2507         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2508         if (vTo.addr == NULL) {
2509           appData.monoMode = True;
2510           forceMono = True;
2511         } else {
2512           lightSquareColor = *(Pixel *) vTo.addr;
2513         }
2514     }
2515     if (!appData.monoMode) {
2516         vFrom.addr = (caddr_t) appData.darkSquareColor;
2517         vFrom.size = strlen(appData.darkSquareColor);
2518         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2519         if (vTo.addr == NULL) {
2520           appData.monoMode = True;
2521           forceMono = True;
2522         } else {
2523           darkSquareColor = *(Pixel *) vTo.addr;
2524         }
2525     }
2526     if (!appData.monoMode) {
2527         vFrom.addr = (caddr_t) appData.whitePieceColor;
2528         vFrom.size = strlen(appData.whitePieceColor);
2529         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2530         if (vTo.addr == NULL) {
2531           appData.monoMode = True;
2532           forceMono = True;
2533         } else {
2534           whitePieceColor = *(Pixel *) vTo.addr;
2535         }
2536     }
2537     if (!appData.monoMode) {
2538         vFrom.addr = (caddr_t) appData.blackPieceColor;
2539         vFrom.size = strlen(appData.blackPieceColor);
2540         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2541         if (vTo.addr == NULL) {
2542           appData.monoMode = True;
2543           forceMono = True;
2544         } else {
2545           blackPieceColor = *(Pixel *) vTo.addr;
2546         }
2547     }
2548
2549     if (!appData.monoMode) {
2550         vFrom.addr = (caddr_t) appData.highlightSquareColor;
2551         vFrom.size = strlen(appData.highlightSquareColor);
2552         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2553         if (vTo.addr == NULL) {
2554           appData.monoMode = True;
2555           forceMono = True;
2556         } else {
2557           highlightSquareColor = *(Pixel *) vTo.addr;
2558         }
2559     }
2560
2561     if (!appData.monoMode) {
2562         vFrom.addr = (caddr_t) appData.premoveHighlightColor;
2563         vFrom.size = strlen(appData.premoveHighlightColor);
2564         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2565         if (vTo.addr == NULL) {
2566           appData.monoMode = True;
2567           forceMono = True;
2568         } else {
2569           premoveHighlightColor = *(Pixel *) vTo.addr;
2570         }
2571     }
2572
2573     if (forceMono) {
2574       fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
2575               programName);
2576     }
2577
2578     if (appData.monoMode && appData.debugMode) {
2579         fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
2580                 (unsigned long) XWhitePixel(xDisplay, xScreen),
2581                 (unsigned long) XBlackPixel(xDisplay, xScreen));
2582     }
2583
2584     if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
2585         parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
2586         parse_cpair(ColorChannel1, appData.colorChannel1) < 0  ||
2587         parse_cpair(ColorChannel, appData.colorChannel) < 0  ||
2588         parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
2589         parse_cpair(ColorTell, appData.colorTell) < 0 ||
2590         parse_cpair(ColorChallenge, appData.colorChallenge) < 0  ||
2591         parse_cpair(ColorRequest, appData.colorRequest) < 0  ||
2592         parse_cpair(ColorSeek, appData.colorSeek) < 0  ||
2593         parse_cpair(ColorNormal, appData.colorNormal) < 0)
2594       {
2595           if (appData.colorize) {
2596               fprintf(stderr,
2597                       _("%s: can't parse color names; disabling colorization\n"),
2598                       programName);
2599           }
2600           appData.colorize = FALSE;
2601       }
2602     textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
2603     textColors[ColorNone].attr = 0;
2604
2605     XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
2606
2607     /*
2608      * widget hierarchy
2609      */
2610     if (tinyLayout) {
2611         layoutName = "tinyLayout";
2612     } else if (smallLayout) {
2613         layoutName = "smallLayout";
2614     } else {
2615         layoutName = "normalLayout";
2616     }
2617     /* Outer layoutWidget is there only to provide a name for use in
2618        resources that depend on the layout style */
2619     layoutWidget =
2620       XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
2621                             layoutArgs, XtNumber(layoutArgs));
2622     formWidget =
2623       XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
2624                             formArgs, XtNumber(formArgs));
2625     XtSetArg(args[0], XtNdefaultDistance, &sep);
2626     XtGetValues(formWidget, args, 1);
2627
2628     j = 0;
2629     widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
2630     XtSetArg(args[0], XtNtop,    XtChainTop);
2631     XtSetArg(args[1], XtNbottom, XtChainTop);
2632     XtSetValues(menuBarWidget, args, 2);
2633
2634     widgetList[j++] = whiteTimerWidget =
2635       XtCreateWidget("whiteTime", labelWidgetClass,
2636                      formWidget, timerArgs, XtNumber(timerArgs));
2637     XtSetArg(args[0], XtNfont, clockFontStruct);
2638     XtSetArg(args[1], XtNtop,    XtChainTop);
2639     XtSetArg(args[2], XtNbottom, XtChainTop);
2640     XtSetValues(whiteTimerWidget, args, 3);
2641
2642     widgetList[j++] = blackTimerWidget =
2643       XtCreateWidget("blackTime", labelWidgetClass,
2644                      formWidget, timerArgs, XtNumber(timerArgs));
2645     XtSetArg(args[0], XtNfont, clockFontStruct);
2646     XtSetArg(args[1], XtNtop,    XtChainTop);
2647     XtSetArg(args[2], XtNbottom, XtChainTop);
2648     XtSetValues(blackTimerWidget, args, 3);
2649
2650     if (appData.titleInWindow) {
2651         widgetList[j++] = titleWidget =
2652           XtCreateWidget("title", labelWidgetClass, formWidget,
2653                          titleArgs, XtNumber(titleArgs));
2654         XtSetArg(args[0], XtNtop,    XtChainTop);
2655         XtSetArg(args[1], XtNbottom, XtChainTop);
2656         XtSetValues(titleWidget, args, 2);
2657     }
2658
2659     if (appData.showButtonBar) {
2660       widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
2661       XtSetArg(args[0], XtNleft,  XtChainRight); // [HGM] glue to right window edge
2662       XtSetArg(args[1], XtNright, XtChainRight); //       for good run-time sizing
2663       XtSetArg(args[2], XtNtop,    XtChainTop);
2664       XtSetArg(args[3], XtNbottom, XtChainTop);
2665       XtSetValues(buttonBarWidget, args, 4);
2666     }
2667
2668     widgetList[j++] = messageWidget =
2669       XtCreateWidget("message", labelWidgetClass, formWidget,
2670                      messageArgs, XtNumber(messageArgs));
2671     XtSetArg(args[0], XtNtop,    XtChainTop);
2672     XtSetArg(args[1], XtNbottom, XtChainTop);
2673     XtSetValues(messageWidget, args, 2);
2674
2675     widgetList[j++] = boardWidget =
2676       XtCreateWidget("board", widgetClass, formWidget, boardArgs,
2677                      XtNumber(boardArgs));
2678
2679     XtManageChildren(widgetList, j);
2680
2681     timerWidth = (boardWidth - sep) / 2;
2682     XtSetArg(args[0], XtNwidth, timerWidth);
2683     XtSetValues(whiteTimerWidget, args, 1);
2684     XtSetValues(blackTimerWidget, args, 1);
2685
2686     XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
2687     XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
2688     XtGetValues(whiteTimerWidget, args, 2);
2689
2690     if (appData.showButtonBar) {
2691       XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
2692       XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
2693       XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
2694     }
2695
2696     /*
2697      * formWidget uses these constraints but they are stored
2698      * in the children.
2699      */
2700     i = 0;
2701     XtSetArg(args[i], XtNfromHoriz, 0); i++;
2702     XtSetValues(menuBarWidget, args, i);
2703     if (appData.titleInWindow) {
2704         if (smallLayout) {
2705             i = 0;
2706             XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2707             XtSetValues(whiteTimerWidget, args, i);
2708             i = 0;
2709             XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2710             XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2711             XtSetValues(blackTimerWidget, args, i);
2712             i = 0;
2713             XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2714             XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
2715             XtSetValues(titleWidget, args, i);
2716             i = 0;
2717             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2718             XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2719             XtSetValues(messageWidget, args, i);
2720             if (appData.showButtonBar) {
2721               i = 0;
2722               XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2723               XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2724               XtSetValues(buttonBarWidget, args, i);
2725             }
2726         } else {
2727             i = 0;
2728             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2729             XtSetValues(whiteTimerWidget, args, i);
2730             i = 0;
2731             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2732             XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2733             XtSetValues(blackTimerWidget, args, i);
2734             i = 0;
2735             XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
2736             XtSetValues(titleWidget, args, i);
2737             i = 0;
2738             XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2739             XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2740             XtSetValues(messageWidget, args, i);
2741             if (appData.showButtonBar) {
2742               i = 0;
2743               XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2744               XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2745               XtSetValues(buttonBarWidget, args, i);
2746             }
2747         }
2748     } else {
2749         i = 0;
2750         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2751         XtSetValues(whiteTimerWidget, args, i);
2752         i = 0;
2753         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2754         XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2755         XtSetValues(blackTimerWidget, args, i);
2756         i = 0;
2757         XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2758         XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2759         XtSetValues(messageWidget, args, i);
2760         if (appData.showButtonBar) {
2761           i = 0;
2762           XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2763           XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2764           XtSetValues(buttonBarWidget, args, i);
2765         }
2766     }
2767     i = 0;
2768     XtSetArg(args[0], XtNfromVert, messageWidget);
2769     XtSetArg(args[1], XtNtop,    XtChainTop);
2770     XtSetArg(args[2], XtNbottom, XtChainBottom);
2771     XtSetArg(args[3], XtNleft,   XtChainLeft);
2772     XtSetArg(args[4], XtNright,  XtChainRight);
2773     XtSetValues(boardWidget, args, 5);
2774
2775     XtRealizeWidget(shellWidget);
2776
2777     /*
2778      * Correct the width of the message and title widgets.
2779      * It is not known why some systems need the extra fudge term.
2780      * The value "2" is probably larger than needed.
2781      */
2782     XawFormDoLayout(formWidget, False);
2783
2784 #define WIDTH_FUDGE 2
2785     i = 0;
2786     XtSetArg(args[i], XtNborderWidth, &bor);  i++;
2787     XtSetArg(args[i], XtNheight, &h);  i++;
2788     XtGetValues(messageWidget, args, i);
2789     if (appData.showButtonBar) {
2790       i = 0;
2791       XtSetArg(args[i], XtNwidth, &w);  i++;
2792       XtGetValues(buttonBarWidget, args, i);
2793       w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2794     } else {
2795       w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
2796     }
2797
2798     gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2799     if (gres != XtGeometryYes && appData.debugMode) {
2800       fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2801               programName, gres, w, h, wr, hr);
2802     }
2803
2804     /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
2805     /* The size used for the child widget in layout lags one resize behind
2806        its true size, so we resize a second time, 1 pixel smaller.  Yeech! */
2807     w--;
2808     gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2809     if (gres != XtGeometryYes && appData.debugMode) {
2810       fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2811               programName, gres, w, h, wr, hr);
2812     }
2813     /* !! end hack */
2814     XtSetArg(args[0], XtNleft,  XtChainLeft);  // [HGM] glue ends for good run-time sizing
2815     XtSetArg(args[1], XtNright, XtChainRight);
2816     XtSetValues(messageWidget, args, 2);
2817
2818     if (appData.titleInWindow) {
2819         i = 0;
2820         XtSetArg(args[i], XtNborderWidth, &bor); i++;
2821         XtSetArg(args[i], XtNheight, &h);  i++;
2822         XtGetValues(titleWidget, args, i);
2823         if (smallLayout) {
2824             w = boardWidth - 2*bor;
2825         } else {
2826             XtSetArg(args[0], XtNwidth, &w);
2827             XtGetValues(menuBarWidget, args, 1);
2828             w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2829         }
2830
2831         gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
2832         if (gres != XtGeometryYes && appData.debugMode) {
2833             fprintf(stderr,
2834                     _("%s: titleWidget geometry error %d %d %d %d %d\n"),
2835                     programName, gres, w, h, wr, hr);
2836         }
2837     }
2838     XawFormDoLayout(formWidget, True);
2839
2840     xBoardWindow = XtWindow(boardWidget);
2841
2842     // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
2843     //       not need to go into InitDrawingSizes().
2844 #endif
2845
2846     /*
2847      * Create X checkmark bitmap and initialize option menu checks.
2848      */
2849     ReadBitmap(&xMarkPixmap, "checkmark.bm",
2850                checkmark_bits, checkmark_width, checkmark_height);
2851     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
2852     if (appData.alwaysPromoteToQueen) {
2853         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
2854                     args, 1);
2855     }
2856     if (appData.animateDragging) {
2857         XtSetValues(XtNameToWidget(menuBarWidget,
2858                                    "menuOptions.Animate Dragging"),
2859                     args, 1);
2860     }
2861     if (appData.animate) {
2862         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
2863                     args, 1);
2864     }
2865     if (appData.autoComment) {
2866         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
2867                     args, 1);
2868     }
2869     if (appData.autoCallFlag) {
2870         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
2871                     args, 1);
2872     }
2873     if (appData.autoFlipView) {
2874         XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
2875                     args, 1);
2876     }
2877     if (appData.autoObserve) {
2878         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
2879                     args, 1);
2880     }
2881     if (appData.autoRaiseBoard) {
2882         XtSetValues(XtNameToWidget(menuBarWidget,
2883                                    "menuOptions.Auto Raise Board"), args, 1);
2884     }
2885     if (appData.autoSaveGames) {
2886         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
2887                     args, 1);
2888     }
2889     if (appData.saveGameFile[0] != NULLCHAR) {
2890         /* Can't turn this off from menu */
2891         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
2892                     args, 1);
2893         XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
2894                        False);
2895
2896     }
2897     if (appData.blindfold) {
2898         XtSetValues(XtNameToWidget(menuBarWidget,
2899                                    "menuOptions.Blindfold"), args, 1);
2900     }
2901     if (appData.flashCount > 0) {
2902         XtSetValues(XtNameToWidget(menuBarWidget,
2903                                    "menuOptions.Flash Moves"),
2904                     args, 1);
2905     }
2906     if (appData.getMoveList) {
2907         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
2908                     args, 1);
2909     }
2910 #if HIGHDRAG
2911     if (appData.highlightDragging) {
2912         XtSetValues(XtNameToWidget(menuBarWidget,
2913                                    "menuOptions.Highlight Dragging"),
2914                     args, 1);
2915     }
2916 #endif
2917     if (appData.highlightLastMove) {
2918         XtSetValues(XtNameToWidget(menuBarWidget,
2919                                    "menuOptions.Highlight Last Move"),
2920                     args, 1);
2921     }
2922     if (appData.icsAlarm) {
2923         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
2924                     args, 1);
2925     }
2926     if (appData.ringBellAfterMoves) {
2927         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
2928                     args, 1);
2929     }
2930     if (appData.oldSaveStyle) {
2931         XtSetValues(XtNameToWidget(menuBarWidget,
2932                                    "menuOptions.Old Save Style"), args, 1);
2933     }
2934     if (appData.periodicUpdates) {
2935         XtSetValues(XtNameToWidget(menuBarWidget,
2936                                    "menuOptions.Periodic Updates"), args, 1);
2937     }
2938     if (appData.ponderNextMove) {
2939         XtSetValues(XtNameToWidget(menuBarWidget,
2940                                    "menuOptions.Ponder Next Move"), args, 1);
2941     }
2942     if (appData.popupExitMessage) {
2943         XtSetValues(XtNameToWidget(menuBarWidget,
2944                                    "menuOptions.Popup Exit Message"), args, 1);
2945     }
2946     if (appData.popupMoveErrors) {
2947         XtSetValues(XtNameToWidget(menuBarWidget,
2948                                    "menuOptions.Popup Move Errors"), args, 1);
2949     }
2950     if (appData.premove) {
2951         XtSetValues(XtNameToWidget(menuBarWidget,
2952                                    "menuOptions.Premove"), args, 1);
2953     }
2954     if (appData.quietPlay) {
2955         XtSetValues(XtNameToWidget(menuBarWidget,
2956                                    "menuOptions.Quiet Play"), args, 1);
2957     }
2958     if (appData.showCoords) {
2959         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
2960                     args, 1);
2961     }
2962     if (appData.hideThinkingFromHuman) {
2963         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
2964                     args, 1);
2965     }
2966     if (appData.testLegality) {
2967         XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
2968                     args, 1);
2969     }
2970
2971     /*
2972      * Create an icon.
2973      */
2974     ReadBitmap(&wIconPixmap, "icon_white.bm",
2975                icon_white_bits, icon_white_width, icon_white_height);
2976     ReadBitmap(&bIconPixmap, "icon_black.bm",
2977                icon_black_bits, icon_black_width, icon_black_height);
2978     iconPixmap = wIconPixmap;
2979     i = 0;
2980     XtSetArg(args[i], XtNiconPixmap, iconPixmap);  i++;
2981     XtSetValues(shellWidget, args, i);
2982
2983     /*
2984      * Create a cursor for the board widget.
2985      */
2986     window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
2987     XChangeWindowAttributes(xDisplay, xBoardWindow,
2988                             CWCursor, &window_attributes);
2989
2990     /*
2991      * Inhibit shell resizing.
2992      */
2993     shellArgs[0].value = (XtArgVal) &w;
2994     shellArgs[1].value = (XtArgVal) &h;
2995     XtGetValues(shellWidget, shellArgs, 2);
2996     shellArgs[4].value = shellArgs[2].value = w;
2997     shellArgs[5].value = shellArgs[3].value = h;
2998     XtSetValues(shellWidget, &shellArgs[2], 4);
2999     marginW =  w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
3000     marginH =  h - boardHeight;
3001
3002     CatchDeleteWindow(shellWidget, "QuitProc");
3003
3004     CreateGCs();
3005     CreateGrid();
3006 #if HAVE_LIBXPM
3007     if (appData.bitmapDirectory[0] != NULLCHAR) {
3008       CreatePieces();
3009     } else {
3010       CreateXPMPieces();
3011     }
3012 #else
3013     CreateXIMPieces();
3014     /* Create regular pieces */
3015     if (!useImages) CreatePieces();
3016 #endif
3017
3018     CreatePieceMenus();
3019
3020     if (appData.animate || appData.animateDragging)
3021       CreateAnimVars();
3022
3023     XtAugmentTranslations(formWidget,
3024                           XtParseTranslationTable(globalTranslations));
3025     XtAugmentTranslations(boardWidget,
3026                           XtParseTranslationTable(boardTranslations));
3027     XtAugmentTranslations(whiteTimerWidget,
3028                           XtParseTranslationTable(whiteTranslations));
3029     XtAugmentTranslations(blackTimerWidget,
3030                           XtParseTranslationTable(blackTranslations));
3031
3032     /* Why is the following needed on some versions of X instead
3033      * of a translation? */
3034     XtAddEventHandler(boardWidget, ExposureMask, False,
3035                       (XtEventHandler) EventProc, NULL);
3036     /* end why */
3037
3038     InitBackEnd2();
3039
3040     if (errorExitStatus == -1) {
3041         if (appData.icsActive) {
3042             /* We now wait until we see "login:" from the ICS before
3043                sending the logon script (problems with timestamp otherwise) */
3044             /*ICSInitScript();*/
3045             if (appData.icsInputBox) ICSInputBoxPopUp();
3046         }
3047
3048         signal(SIGINT, IntSigHandler);
3049         signal(SIGTERM, IntSigHandler);
3050         if (*appData.cmailGameName != NULLCHAR) {
3051             signal(SIGUSR1, CmailSigHandler);
3052         }
3053     }
3054         InitPosition(TRUE);
3055
3056     XtAppMainLoop(appContext);
3057     if (appData.debugMode) fclose(debugFP); // [DM] debug
3058     return 0;
3059 }
3060
3061 void
3062 ShutDownFrontEnd()
3063 {
3064     if (appData.icsActive && oldICSInteractionTitle != NULL) {
3065         DisplayIcsInteractionTitle(oldICSInteractionTitle);
3066     }
3067     unlink(gameCopyFilename);
3068     unlink(gamePasteFilename);
3069 }
3070
3071 RETSIGTYPE
3072 IntSigHandler(sig)
3073      int sig;
3074 {
3075     ExitEvent(sig);
3076 }
3077
3078 RETSIGTYPE
3079 CmailSigHandler(sig)
3080      int sig;
3081 {
3082     int dummy = 0;
3083     int error;
3084
3085     signal(SIGUSR1, SIG_IGN);   /* suspend handler     */
3086
3087     /* Activate call-back function CmailSigHandlerCallBack()             */
3088     OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
3089
3090     signal(SIGUSR1, CmailSigHandler); /* re-activate handler */
3091 }
3092
3093 void
3094 CmailSigHandlerCallBack(isr, closure, message, count, error)
3095      InputSourceRef isr;
3096      VOIDSTAR closure;
3097      char *message;
3098      int count;
3099      int error;
3100 {
3101     BoardToTop();
3102     ReloadCmailMsgEvent(TRUE);  /* Reload cmail msg  */
3103 }
3104 /**** end signal code ****/
3105
3106
3107 void
3108 ICSInitScript()
3109 {
3110     FILE *f;
3111     char buf[MSG_SIZ];
3112     char *p;
3113
3114     f = fopen(appData.icsLogon, "r");
3115     if (f == NULL) {
3116         p = getenv("HOME");
3117         if (p != NULL) {
3118             strcpy(buf, p);
3119             strcat(buf, "/");
3120             strcat(buf, appData.icsLogon);
3121             f = fopen(buf, "r");
3122         }
3123     }
3124     if (f != NULL)
3125       ProcessICSInitScript(f);
3126 }
3127
3128 void
3129 ResetFrontEnd()
3130 {
3131     CommentPopDown();
3132     EditCommentPopDown();
3133     TagsPopDown();
3134     return;
3135 }
3136
3137 typedef struct {
3138     char *name;
3139     Boolean value;
3140 } Enables;
3141
3142 void
3143 SetMenuEnables(enab)
3144      Enables *enab;
3145 {
3146   Widget w;
3147   if (!menuBarWidget) return;
3148   while (enab->name != NULL) {
3149     w = XtNameToWidget(menuBarWidget, enab->name);
3150     if (w == NULL) {
3151       DisplayError(enab->name, 0);
3152     } else {
3153       XtSetSensitive(w, enab->value);
3154     }
3155     enab++;
3156   }
3157 }
3158
3159 Enables icsEnables[] = {
3160     { "menuFile.Mail Move", False },
3161     { "menuFile.Reload CMail Message", False },
3162     { "menuMode.Machine Black", False },
3163     { "menuMode.Machine White", False },
3164     { "menuMode.Analysis Mode", False },
3165     { "menuMode.Analyze File", False },
3166     { "menuMode.Two Machines", False },
3167 #ifndef ZIPPY
3168     { "menuHelp.Hint", False },
3169     { "menuHelp.Book", False },
3170     { "menuStep.Move Now", False },
3171     { "menuOptions.Periodic Updates", False },
3172     { "menuOptions.Hide Thinking", False },
3173     { "menuOptions.Ponder Next Move", False },
3174 #endif
3175     { NULL, False }
3176 };
3177
3178 Enables ncpEnables[] = {
3179     { "menuFile.Mail Move", False },
3180     { "menuFile.Reload CMail Message", False },
3181     { "menuMode.Machine White", False },
3182     { "menuMode.Machine Black", False },
3183     { "menuMode.Analysis Mode", False },
3184     { "menuMode.Analyze File", False },
3185     { "menuMode.Two Machines", False },
3186     { "menuMode.ICS Client", False },
3187     { "menuMode.ICS Input Box", False },
3188     { "Action", False },
3189     { "menuStep.Revert", False },
3190     { "menuStep.Move Now", False },
3191     { "menuStep.Retract Move", False },
3192     { "menuOptions.Auto Comment", False },
3193     { "menuOptions.Auto Flag", False },
3194     { "menuOptions.Auto Flip View", False },
3195     { "menuOptions.Auto Observe", False },
3196     { "menuOptions.Auto Raise Board", False },
3197     { "menuOptions.Get Move List", False },
3198     { "menuOptions.ICS Alarm", False },
3199     { "menuOptions.Move Sound", False },
3200     { "menuOptions.Quiet Play", False },
3201     { "menuOptions.Hide Thinking", False },
3202     { "menuOptions.Periodic Updates", False },
3203     { "menuOptions.Ponder Next Move", False },
3204     { "menuHelp.Hint", False },
3205     { "menuHelp.Book", False },
3206     { NULL, False }
3207 };
3208
3209 Enables gnuEnables[] = {
3210     { "menuMode.ICS Client", False },
3211     { "menuMode.ICS Input Box", False },
3212     { "menuAction.Accept", False },
3213     { "menuAction.Decline", False },
3214     { "menuAction.Rematch", False },
3215     { "menuAction.Adjourn", False },
3216     { "menuAction.Stop Examining", False },
3217     { "menuAction.Stop Observing", False },
3218     { "menuStep.Revert", False },
3219     { "menuOptions.Auto Comment", False },
3220     { "menuOptions.Auto Observe", False },
3221     { "menuOptions.Auto Raise Board", False },
3222     { "menuOptions.Get Move List", False },
3223     { "menuOptions.Premove", False },
3224     { "menuOptions.Quiet Play", False },
3225
3226     /* The next two options rely on SetCmailMode being called *after*    */
3227     /* SetGNUMode so that when GNU is being used to give hints these     */
3228     /* menu options are still available                                  */
3229
3230     { "menuFile.Mail Move", False },
3231     { "menuFile.Reload CMail Message", False },
3232     { NULL, False }
3233 };
3234
3235 Enables cmailEnables[] = {
3236     { "Action", True },
3237     { "menuAction.Call Flag", False },
3238     { "menuAction.Draw", True },
3239     { "menuAction.Adjourn", False },
3240     { "menuAction.Abort", False },
3241     { "menuAction.Stop Observing", False },
3242     { "menuAction.Stop Examining", False },
3243     { "menuFile.Mail Move", True },
3244     { "menuFile.Reload CMail Message", True },
3245     { NULL, False }
3246 };
3247
3248 Enables trainingOnEnables[] = {
3249   { "menuMode.Edit Comment", False },
3250   { "menuMode.Pause", False },
3251   { "menuStep.Forward", False },
3252   { "menuStep.Backward", False },
3253   { "menuStep.Forward to End", False },
3254   { "menuStep.Back to Start", False },
3255   { "menuStep.Move Now", False },
3256   { "menuStep.Truncate Game", False },
3257   { NULL, False }
3258 };
3259
3260 Enables trainingOffEnables[] = {
3261   { "menuMode.Edit Comment", True },
3262   { "menuMode.Pause", True },
3263   { "menuStep.Forward", True },
3264   { "menuStep.Backward", True },
3265   { "menuStep.Forward to End", True },
3266   { "menuStep.Back to Start", True },
3267   { "menuStep.Move Now", True },
3268   { "menuStep.Truncate Game", True },
3269   { NULL, False }
3270 };
3271
3272 Enables machineThinkingEnables[] = {
3273   { "menuFile.Load Game", False },
3274   { "menuFile.Load Next Game", False },
3275   { "menuFile.Load Previous Game", False },
3276   { "menuFile.Reload Same Game", False },
3277   { "menuFile.Paste Game", False },
3278   { "menuFile.Load Position", False },
3279   { "menuFile.Load Next Position", False },
3280   { "menuFile.Load Previous Position", False },
3281   { "menuFile.Reload Same Position", False },
3282   { "menuFile.Paste Position", False },
3283   { "menuMode.Machine White", False },
3284   { "menuMode.Machine Black", False },
3285   { "menuMode.Two Machines", False },
3286   { "menuStep.Retract Move", False },
3287   { NULL, False }
3288 };
3289
3290 Enables userThinkingEnables[] = {
3291   { "menuFile.Load Game", True },
3292   { "menuFile.Load Next Game", True },
3293   { "menuFile.Load Previous Game", True },
3294   { "menuFile.Reload Same Game", True },
3295   { "menuFile.Paste Game", True },
3296   { "menuFile.Load Position", True },
3297   { "menuFile.Load Next Position", True },
3298   { "menuFile.Load Previous Position", True },
3299   { "menuFile.Reload Same Position", True },
3300   { "menuFile.Paste Position", True },
3301   { "menuMode.Machine White", True },
3302   { "menuMode.Machine Black", True },
3303   { "menuMode.Two Machines", True },
3304   { "menuStep.Retract Move", True },
3305   { NULL, False }
3306 };
3307
3308 void SetICSMode()
3309 {
3310   SetMenuEnables(icsEnables);
3311
3312 #ifdef ZIPPY
3313   if (appData.zippyPlay && !appData.noChessProgram)   /* [DM] icsEngineAnalyze */
3314      XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
3315 #endif
3316 }
3317
3318 void
3319 SetNCPMode()
3320 {
3321   SetMenuEnables(ncpEnables);
3322 }
3323
3324 void
3325 SetGNUMode()
3326 {
3327   SetMenuEnables(gnuEnables);
3328 }
3329
3330 void
3331 SetCmailMode()
3332 {
3333   SetMenuEnables(cmailEnables);
3334 }
3335
3336 void
3337 SetTrainingModeOn()
3338 {
3339   SetMenuEnables(trainingOnEnables);
3340   if (appData.showButtonBar) {
3341     XtSetSensitive(buttonBarWidget, False);
3342   }
3343   CommentPopDown();
3344 }
3345
3346 void
3347 SetTrainingModeOff()
3348 {
3349   SetMenuEnables(trainingOffEnables);
3350   if (appData.showButtonBar) {
3351     XtSetSensitive(buttonBarWidget, True);
3352   }
3353 }
3354
3355 void
3356 SetUserThinkingEnables()
3357 {
3358   if (appData.noChessProgram) return;
3359   SetMenuEnables(userThinkingEnables);
3360 }
3361
3362 void
3363 SetMachineThinkingEnables()
3364 {
3365   if (appData.noChessProgram) return;
3366   SetMenuEnables(machineThinkingEnables);
3367   switch (gameMode) {
3368   case MachinePlaysBlack:
3369   case MachinePlaysWhite:
3370   case TwoMachinesPlay:
3371     XtSetSensitive(XtNameToWidget(menuBarWidget,
3372                                   ModeToWidgetName(gameMode)), True);
3373     break;
3374   default:
3375     break;
3376   }
3377 }
3378
3379 #define Abs(n) ((n)<0 ? -(n) : (n))
3380
3381 /*
3382  * Find a font that matches "pattern" that is as close as
3383  * possible to the targetPxlSize.  Prefer fonts that are k
3384  * pixels smaller to fonts that are k pixels larger.  The
3385  * pattern must be in the X Consortium standard format,
3386  * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
3387  * The return value should be freed with XtFree when no
3388  * longer needed.
3389  */
3390 char *FindFont(pattern, targetPxlSize)
3391      char *pattern;
3392      int targetPxlSize;
3393 {
3394     char **fonts, *p, *best, *scalable, *scalableTail;
3395     int i, j, nfonts, minerr, err, pxlSize;
3396
3397 #ifdef ENABLE_NLS
3398     char **missing_list;
3399     int missing_count;
3400     char *def_string, *base_fnt_lst, strInt[3];
3401     XFontSet fntSet;
3402     XFontStruct **fnt_list;
3403
3404     base_fnt_lst = calloc(1, strlen(pattern) + 3);
3405     sprintf(strInt, "%d", targetPxlSize);
3406     p = strstr(pattern, "--");
3407     strncpy(base_fnt_lst, pattern, p - pattern + 2);
3408     strcat(base_fnt_lst, strInt);
3409     strcat(base_fnt_lst, strchr(p + 2, '-'));
3410
3411     if ((fntSet = XCreateFontSet(xDisplay,
3412                                  base_fnt_lst,
3413                                  &missing_list,
3414                                  &missing_count,
3415                                  &def_string)) == NULL) {
3416
3417        fprintf(stderr, _("Unable to create font set.\n"));
3418        exit (2);
3419     }
3420
3421     nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
3422 #else
3423     fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
3424     if (nfonts < 1) {
3425         fprintf(stderr, _("%s: no fonts match pattern %s\n"),
3426                 programName, pattern);
3427         exit(2);
3428     }
3429 #endif
3430
3431     best = fonts[0];
3432     scalable = NULL;
3433     minerr = 999999;
3434     for (i=0; i<nfonts; i++) {
3435         j = 0;
3436         p = fonts[i];
3437         if (*p != '-') continue;
3438         while (j < 7) {
3439             if (*p == NULLCHAR) break;
3440             if (*p++ == '-') j++;
3441         }
3442         if (j < 7) continue;
3443         pxlSize = atoi(p);
3444         if (pxlSize == 0) {
3445             scalable = fonts[i];
3446             scalableTail = p;
3447         } else {
3448             err = pxlSize - targetPxlSize;
3449             if (Abs(err) < Abs(minerr) ||
3450                 (minerr > 0 && err < 0 && -err == minerr)) {
3451                 best = fonts[i];
3452                 minerr = err;
3453             }
3454         }
3455     }
3456     if (scalable && Abs(minerr) > appData.fontSizeTolerance) {
3457         /* If the error is too big and there is a scalable font,
3458            use the scalable font. */
3459         int headlen = scalableTail - scalable;
3460         p = (char *) XtMalloc(strlen(scalable) + 10);
3461         while (isdigit(*scalableTail)) scalableTail++;
3462         sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
3463     } else {
3464         p = (char *) XtMalloc(strlen(best) + 1);
3465         strcpy(p, best);
3466     }
3467     if (appData.debugMode) {
3468         fprintf(debugFP, _("resolved %s at pixel size %d\n  to %s\n"),
3469                 pattern, targetPxlSize, p);
3470     }
3471 #ifdef ENABLE_NLS
3472     if (missing_count > 0)
3473        XFreeStringList(missing_list);
3474     XFreeFontSet(xDisplay, fntSet);
3475 #else
3476      XFreeFontNames(fonts);
3477 #endif
3478     return p;
3479 }
3480
3481 void CreateGCs()
3482 {
3483     XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
3484       | GCBackground | GCFunction | GCPlaneMask;
3485     XGCValues gc_values;
3486     GC copyInvertedGC;
3487
3488     gc_values.plane_mask = AllPlanes;
3489     gc_values.line_width = lineGap;
3490     gc_values.line_style = LineSolid;
3491     gc_values.function = GXcopy;
3492
3493     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3494     gc_values.background = XBlackPixel(xDisplay, xScreen);
3495     lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3496
3497     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3498     gc_values.background = XWhitePixel(xDisplay, xScreen);
3499     coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
3500     XSetFont(xDisplay, coordGC, coordFontID);
3501
3502     // [HGM] make font for holdings counts (white on black0
3503     gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3504     gc_values.background = XBlackPixel(xDisplay, xScreen);
3505     countGC = XtGetGC(shellWidget, value_mask, &gc_values);
3506     XSetFont(xDisplay, countGC, countFontID);
3507
3508     if (appData.monoMode) {
3509         gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3510         gc_values.background = XWhitePixel(xDisplay, xScreen);
3511         highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3512
3513         gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3514         gc_values.background = XBlackPixel(xDisplay, xScreen);
3515         lightSquareGC = wbPieceGC
3516           = XtGetGC(shellWidget, value_mask, &gc_values);
3517
3518         gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3519         gc_values.background = XWhitePixel(xDisplay, xScreen);
3520         darkSquareGC = bwPieceGC
3521           = XtGetGC(shellWidget, value_mask, &gc_values);
3522
3523         if (DefaultDepth(xDisplay, xScreen) == 1) {
3524             /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
3525             gc_values.function = GXcopyInverted;
3526             copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
3527             gc_values.function = GXcopy;
3528             if (XBlackPixel(xDisplay, xScreen) == 1) {
3529                 bwPieceGC = darkSquareGC;
3530                 wbPieceGC = copyInvertedGC;
3531             } else {
3532                 bwPieceGC = copyInvertedGC;
3533                 wbPieceGC = lightSquareGC;
3534             }