Updated docs for Engine-Settings menu
[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
1339     // [HGM] Winboard_x UCI options
1340     { "firstIsUCI", "firstIsUCI", XtRBoolean,
1341         sizeof(Boolean), XtOffset(AppDataPtr, firstIsUCI),
1342         XtRImmediate, (XtPointer) False},
1343     { "secondIsUCI", "secondIsUCI", XtRBoolean,
1344         sizeof(Boolean), XtOffset(AppDataPtr, secondIsUCI),
1345         XtRImmediate, (XtPointer) False},
1346     { "firstHasOwnBookUCI", "firstHasOwnBookUCI", XtRBoolean,
1347         sizeof(Boolean), XtOffset(AppDataPtr, firstHasOwnBookUCI),
1348         XtRImmediate, (XtPointer) True},
1349     { "secondHasOwnBookUCI", "secondHasOwnBookUCI", XtRBoolean,
1350         sizeof(Boolean), XtOffset(AppDataPtr, secondHasOwnBookUCI),
1351         XtRImmediate, (XtPointer) True},
1352     { "usePolyglotBook", "usePolyglotBook", XtRBoolean,
1353         sizeof(Boolean), XtOffset(AppDataPtr, usePolyglotBook),
1354         XtRImmediate, (XtPointer) False},
1355     { "defaultHashSize", "defaultHashSize", XtRInt,
1356         sizeof(int), XtOffset(AppDataPtr, defaultHashSize),
1357         XtRImmediate, (XtPointer) 64},
1358     { "defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XtRInt,
1359         sizeof(int), XtOffset(AppDataPtr, defaultCacheSizeEGTB),
1360         XtRImmediate, (XtPointer) 4},
1361     { "polyglotDir", "polyglotDir", XtRString,
1362         sizeof(String), XtOffset(AppDataPtr, polyglotDir),
1363         XtRImmediate, (XtPointer) "." },
1364     { "polyglotBook", "polyglotBook", XtRString,
1365         sizeof(String), XtOffset(AppDataPtr, polyglotBook),
1366         XtRImmediate, (XtPointer) "" },
1367     { "defaultPathEGTB", "defaultPathEGTB", XtRString,
1368         sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),
1369         XtRImmediate, (XtPointer) "/usr/local/share/egtb"},
1370     { "delayBeforeQuit", "delayBeforeQuit", XtRInt,
1371         sizeof(int), XtOffset(AppDataPtr, delayBeforeQuit),
1372         XtRImmediate, (XtPointer) 0},
1373     { "delayAfterQuit", "delayAfterQuit", XtRInt,
1374         sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
1375         XtRImmediate, (XtPointer) 0},
1376 };
1377
1378 XrmOptionDescRec shellOptions[] = {
1379     { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
1380     { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
1381     { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
1382     { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
1383     { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },
1384     { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},
1385     { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
1386     { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
1387     { "-timeIncrement", "timeIncrement", XrmoptionSepArg, NULL },
1388     { "-inc", "timeIncrement", XrmoptionSepArg, NULL },
1389     { "-initString", "initString", XrmoptionSepArg, NULL },
1390     { "-firstInitString", "initString", XrmoptionSepArg, NULL },
1391     { "-secondInitString", "secondInitString", XrmoptionSepArg, NULL },
1392     { "-firstComputerString", "firstComputerString", XrmoptionSepArg, NULL },
1393     { "-secondComputerString", "secondComputerString", XrmoptionSepArg, NULL },
1394     { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
1395     { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
1396     { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
1397     { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
1398     { "-firstPlaysBlack", "firstPlaysBlack", XrmoptionSepArg, NULL },
1399     { "-fb", "firstPlaysBlack", XrmoptionNoArg, "True" },
1400     { "-xfb", "firstPlaysBlack", XrmoptionNoArg, "False" },
1401     { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
1402     { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },
1403     { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },
1404     { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
1405     { "-fh", "firstHost", XrmoptionSepArg, NULL },
1406     { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
1407     { "-sh", "secondHost", XrmoptionSepArg, NULL },
1408     { "-firstDirectory", "firstDirectory", XrmoptionSepArg, NULL },
1409     { "-fd", "firstDirectory", XrmoptionSepArg, NULL },
1410     { "-secondDirectory", "secondDirectory", XrmoptionSepArg, NULL },
1411     { "-sd", "secondDirectory", XrmoptionSepArg, NULL },
1412     { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },
1413     { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },
1414     { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
1415     { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
1416     { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },
1417     { "-ruser", "remoteUser", XrmoptionSepArg, NULL },
1418     { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
1419     { "-td", "timeDelay", XrmoptionSepArg, NULL },
1420     { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
1421     { "-tc", "timeControl", XrmoptionSepArg, NULL },
1422     { "-internetChessServerMode", "internetChessServerMode",
1423         XrmoptionSepArg, NULL },
1424     { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },
1425     { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },
1426     { "-internetChessServerHost", "internetChessServerHost",
1427         XrmoptionSepArg, NULL },
1428     { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
1429     { "-internetChessServerPort", "internetChessServerPort",
1430         XrmoptionSepArg, NULL },
1431     { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
1432     { "-internetChessServerCommPort", "internetChessServerCommPort",
1433         XrmoptionSepArg, NULL },
1434     { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },
1435     { "-internetChessServerLogonScript", "internetChessServerLogonScript",
1436         XrmoptionSepArg, NULL },
1437     { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },
1438     { "-internetChessServerHelper", "internetChessServerHelper",
1439         XrmoptionSepArg, NULL },
1440     { "-icshelper", "internetChessServerHelper", XrmoptionSepArg, NULL },
1441     { "-internetChessServerInputBox", "internetChessServerInputBox",
1442         XrmoptionSepArg, NULL },
1443     { "-icsinput", "internetChessServerInputBox", XrmoptionNoArg, "True" },
1444     { "-xicsinput", "internetChessServerInputBox", XrmoptionNoArg, "False" },
1445     { "-icsAlarm", "icsAlarm", XrmoptionSepArg, NULL },
1446     { "-alarm", "icsAlarm", XrmoptionNoArg, "True" },
1447     { "-xalarm", "icsAlarm", XrmoptionNoArg, "False" },
1448     { "-icsAlarmTime", "icsAlarmTime", XrmoptionSepArg, NULL },
1449     { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },
1450     { "-telnet", "useTelnet", XrmoptionNoArg, "True" },
1451     { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },
1452     { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },
1453     { "-gateway", "gateway", XrmoptionSepArg, NULL },
1454     { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
1455     { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
1456     { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },
1457     { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },
1458     { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
1459     { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
1460     { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
1461     { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },
1462     { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },
1463     { "-autoRaiseBoard", "autoRaiseBoard", XrmoptionSepArg, NULL },
1464     { "-autoraise", "autoRaiseBoard", XrmoptionNoArg, "True" },
1465     { "-xautoraise", "autoRaiseBoard", XrmoptionNoArg, "False" },
1466     { "-blindfold", "blindfold", XrmoptionSepArg, NULL },
1467     { "-blind", "blindfold", XrmoptionNoArg, "True" },
1468     { "-xblind", "blindfold", XrmoptionNoArg, "False" },
1469     { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
1470     { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
1471     { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },
1472     { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },
1473     { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
1474     { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
1475     { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
1476     { "-mm", "matchMode", XrmoptionNoArg, "True" },
1477     { "-xmm", "matchMode", XrmoptionNoArg, "False" },
1478     { "-matchGames", "matchGames", XrmoptionSepArg, NULL },
1479     { "-mg", "matchGames", XrmoptionSepArg, NULL },
1480     { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
1481     { "-mono", "monoMode", XrmoptionNoArg, "True" },
1482     { "-xmono", "monoMode", XrmoptionNoArg, "False" },
1483     { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
1484     { "-debug", "debugMode", XrmoptionNoArg, "True" },
1485     { "-xdebug", "debugMode", XrmoptionNoArg, "False" },
1486     { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
1487     { "-clock", "clockMode", XrmoptionNoArg, "True" },
1488     { "-xclock", "clockMode", XrmoptionNoArg, "False" },
1489     { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
1490     { "-size", "boardSize", XrmoptionSepArg, NULL },
1491     { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
1492     { "-st", "searchTime", XrmoptionSepArg, NULL },
1493     { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
1494     { "-depth", "searchDepth", XrmoptionSepArg, NULL },
1495     { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
1496     { "-coords", "showCoords", XrmoptionNoArg, "True" },
1497     { "-xcoords", "showCoords", XrmoptionNoArg, "False" },
1498 #if JAIL
1499     { "-showJail", "showJail", XrmoptionSepArg, NULL },
1500     { "-jail", "showJail", XrmoptionNoArg, "1" },
1501     { "-sidejail", "showJail", XrmoptionNoArg, "2" },
1502     { "-xjail", "showJail", XrmoptionNoArg, "0" },
1503 #endif
1504     { "-showThinking", "showThinking", XrmoptionSepArg, NULL },
1505     { "-thinking", "showThinking", XrmoptionNoArg, "True" },
1506     { "-xthinking", "showThinking", XrmoptionNoArg, "False" },
1507     { "-ponderNextMove", "ponderNextMove", XrmoptionSepArg, NULL },
1508     { "-ponder", "ponderNextMove", XrmoptionNoArg, "True" },
1509     { "-xponder", "ponderNextMove", XrmoptionNoArg, "False" },
1510     { "-periodicUpdates", "periodicUpdates", XrmoptionSepArg, NULL },
1511     { "-periodic", "periodicUpdates", XrmoptionNoArg, "True" },
1512     { "-xperiodic", "periodicUpdates", XrmoptionNoArg, "False" },
1513     { "-clockFont", "clockFont", XrmoptionSepArg, NULL },
1514     { "-coordFont", "coordFont", XrmoptionSepArg, NULL },
1515     { "-font", "font", XrmoptionSepArg, NULL },
1516     { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
1517     { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },
1518     { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },
1519     { "-movesound", "ringBellAfterMoves", XrmoptionNoArg, "True" },
1520     { "-xmovesound", "ringBellAfterMoves", XrmoptionNoArg, "False" },
1521     { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },
1522     { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },
1523     { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },
1524     { "-autoFlipView", "autoFlipView", XrmoptionSepArg, NULL },
1525     { "-autoflip", "autoFlipView", XrmoptionNoArg, "True" },
1526     { "-xautoflip", "autoFlipView", XrmoptionNoArg, "False" },
1527     { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },
1528     { "-autobs", "autoObserve", XrmoptionNoArg, "True" },
1529     { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },
1530     { "-autoComment", "autoComment", XrmoptionSepArg, NULL },
1531     { "-autocomm", "autoComment", XrmoptionNoArg, "True" },
1532     { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },
1533     { "-getMoveList", "getMoveList", XrmoptionSepArg, NULL },
1534     { "-moves", "getMoveList", XrmoptionNoArg, "True" },
1535     { "-xmoves", "getMoveList", XrmoptionNoArg, "False" },
1536 #if HIGHDRAG
1537     { "-highlightDragging", "highlightDragging", XrmoptionSepArg, NULL },
1538     { "-highdrag", "highlightDragging", XrmoptionNoArg, "True" },
1539     { "-xhighdrag", "highlightDragging", XrmoptionNoArg, "False" },
1540 #endif
1541     { "-highlightLastMove", "highlightLastMove", XrmoptionSepArg, NULL },
1542     { "-highlight", "highlightLastMove", XrmoptionNoArg, "True" },
1543     { "-xhighlight", "highlightLastMove", XrmoptionNoArg, "False" },
1544     { "-premove", "premove", XrmoptionSepArg, NULL },
1545     { "-pre", "premove", XrmoptionNoArg, "True" },
1546     { "-xpre", "premove", XrmoptionNoArg, "False" },
1547     { "-testLegality", "testLegality", XrmoptionSepArg, NULL },
1548     { "-legal", "testLegality", XrmoptionNoArg, "True" },
1549     { "-xlegal", "testLegality", XrmoptionNoArg, "False" },
1550     { "-flipView", "flipView", XrmoptionSepArg, NULL },
1551     { "-flip", "flipView", XrmoptionNoArg, "True" },
1552     { "-xflip", "flipView", XrmoptionNoArg, "False" },
1553     { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },
1554     { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",
1555         XrmoptionSepArg, NULL },
1556     { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },
1557     { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },
1558     { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },
1559     { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },
1560     { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },
1561     { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },
1562     { "-quiet", "quietPlay", XrmoptionNoArg, "True" },
1563     { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },
1564     { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },
1565     { "-title", "titleInWindow", XrmoptionNoArg, "True" },
1566     { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },
1567 #ifdef ZIPPY
1568     { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },
1569     { "-zt", "zippyTalk", XrmoptionNoArg, "True" },
1570     { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },
1571     { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },
1572     { "-zp", "zippyPlay", XrmoptionNoArg, "True" },
1573     { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },
1574     { "-zippyLines", "zippyLines", XrmoptionSepArg, NULL },
1575     { "-zippyPinhead", "zippyPinhead", XrmoptionSepArg, NULL },
1576     { "-zippyPassword", "zippyPassword", XrmoptionSepArg, NULL },
1577     { "-zippyPassword2", "zippyPassword2", XrmoptionSepArg, NULL },
1578     { "-zippyWrongPassword", "zippyWrongPassword", XrmoptionSepArg, NULL },
1579     { "-zippyAcceptOnly", "zippyAcceptOnly", XrmoptionSepArg, NULL },
1580     { "-zippyUseI", "zippyUseI", XrmoptionSepArg, NULL },
1581     { "-zui", "zippyUseI", XrmoptionNoArg, "True" },
1582     { "-xzui", "zippyUseI", XrmoptionNoArg, "False" },
1583     { "-zippyBughouse", "zippyBughouse", XrmoptionSepArg, NULL },
1584     { "-zippyNoplayCrafty", "zippyNoplayCrafty", XrmoptionSepArg, NULL },
1585     { "-znc", "zippyNoplayCrafty", XrmoptionNoArg, "True" },
1586     { "-xznc", "zippyNoplayCrafty", XrmoptionNoArg, "False" },
1587     { "-zippyGameEnd", "zippyGameEnd", XrmoptionSepArg, NULL },
1588     { "-zippyGameStart", "zippyGameStart", XrmoptionSepArg, NULL },
1589     { "-zippyAdjourn", "zippyAdjourn", XrmoptionSepArg, NULL },
1590     { "-zadj", "zippyAdjourn", XrmoptionNoArg, "True" },
1591     { "-xzadj", "zippyAdjourn", XrmoptionNoArg, "False" },
1592     { "-zippyAbort", "zippyAbort", XrmoptionSepArg, NULL },
1593     { "-zab", "zippyAbort", XrmoptionNoArg, "True" },
1594     { "-xzab", "zippyAbort", XrmoptionNoArg, "False" },
1595     { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },
1596     { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },
1597     { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },
1598 #endif
1599     { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
1600     { "-flash", "flashCount", XrmoptionNoArg, "3" },
1601     { "-xflash", "flashCount", XrmoptionNoArg, "0" },
1602     { "-flashRate", "flashRate", XrmoptionSepArg, NULL },
1603     { "-pixmapDirectory", "pixmapDirectory", XrmoptionSepArg, NULL },
1604     { "-msLoginDelay", "msLoginDelay", XrmoptionSepArg, NULL },
1605     { "-pixmap", "pixmapDirectory", XrmoptionSepArg, NULL },
1606     { "-colorizeMessages", "colorizeMessages", XrmoptionSepArg, NULL },
1607     { "-colorize", "colorizeMessages", XrmoptionNoArg, "True" },
1608     { "-xcolorize", "colorizeMessages", XrmoptionNoArg, "False" },
1609     { "-colorShout", "colorShout", XrmoptionSepArg, NULL },
1610     { "-colorSShout", "colorSShout", XrmoptionSepArg, NULL },
1611     { "-colorCShout", "colorSShout", XrmoptionSepArg, NULL }, /*FICS name*/
1612     { "-colorChannel1", "colorChannel1", XrmoptionSepArg, NULL },
1613     { "-colorChannel", "colorChannel", XrmoptionSepArg, NULL },
1614     { "-colorKibitz", "colorKibitz", XrmoptionSepArg, NULL },
1615     { "-colorTell", "colorTell", XrmoptionSepArg, NULL },
1616     { "-colorChallenge", "colorChallenge", XrmoptionSepArg, NULL },
1617     { "-colorRequest", "colorRequest", XrmoptionSepArg, NULL },
1618     { "-colorSeek", "colorSeek", XrmoptionSepArg, NULL },
1619     { "-colorNormal", "colorNormal", XrmoptionSepArg, NULL },
1620     { "-soundProgram", "soundProgram", XrmoptionSepArg, NULL },
1621     { "-soundShout", "soundShout", XrmoptionSepArg, NULL },
1622     { "-soundSShout", "soundSShout", XrmoptionSepArg, NULL },
1623     { "-soundCShout", "soundSShout", XrmoptionSepArg, NULL }, /*FICS name*/
1624     { "-soundChannel1", "soundChannel1", XrmoptionSepArg, NULL },
1625     { "-soundChannel", "soundChannel", XrmoptionSepArg, NULL },
1626     { "-soundKibitz", "soundKibitz", XrmoptionSepArg, NULL },
1627     { "-soundTell", "soundTell", XrmoptionSepArg, NULL },
1628     { "-soundChallenge", "soundChallenge", XrmoptionSepArg, NULL },
1629     { "-soundRequest", "soundRequest", XrmoptionSepArg, NULL },
1630     { "-soundSeek", "soundSeek", XrmoptionSepArg, NULL },
1631     { "-soundMove", "soundMove", XrmoptionSepArg, NULL },
1632     { "-soundIcsWin", "soundIcsWin", XrmoptionSepArg, NULL },
1633     { "-soundIcsLoss", "soundIcsLoss", XrmoptionSepArg, NULL },
1634     { "-soundIcsDraw", "soundIcsDraw", XrmoptionSepArg, NULL },
1635     { "-soundIcsUnfinished", "soundIcsUnfinished", XrmoptionSepArg, NULL },
1636     { "-soundIcsAlarm", "soundIcsAlarm", XrmoptionSepArg, NULL },
1637     { "-reuseFirst", "reuseFirst", XrmoptionSepArg, NULL },
1638     { "-reuseChessPrograms", "reuseFirst", XrmoptionSepArg, NULL }, /*compat*/
1639     { "-reuse", "reuseFirst", XrmoptionNoArg, "True" },
1640     { "-xreuse", "reuseFirst", XrmoptionNoArg, "False" },
1641     { "-reuseSecond", "reuseSecond", XrmoptionSepArg, NULL },
1642     { "-reuse2", "reuseSecond", XrmoptionNoArg, "True" },
1643     { "-xreuse2", "reuseSecond", XrmoptionNoArg, "False" },
1644     { "-animateMoving", "animateMoving", XrmoptionSepArg, NULL },
1645     { "-animate", "animateMoving", XrmoptionNoArg, "True" },
1646     { "-xanimate", "animateMoving", XrmoptionNoArg, "False" },
1647     { "-animateDragging", "animateDragging", XrmoptionSepArg, NULL },
1648     { "-drag", "animateDragging", XrmoptionNoArg, "True" },
1649     { "-xdrag", "animateDragging", XrmoptionNoArg, "False" },
1650     { "-animateSpeed", "animateSpeed", XrmoptionSepArg, NULL },
1651     { "-popupExitMessage", "popupExitMessage", XrmoptionSepArg, NULL },
1652     { "-exit", "popupExitMessage", XrmoptionNoArg, "True" },
1653     { "-xexit", "popupExitMessage", XrmoptionNoArg, "False" },
1654     { "-popupMoveErrors", "popupMoveErrors", XrmoptionSepArg, NULL },
1655     { "-popup", "popupMoveErrors", XrmoptionNoArg, "True" },
1656     { "-xpopup", "popupMoveErrors", XrmoptionNoArg, "False" },
1657     { "-fontSizeTolerance", "fontSizeTolerance", XrmoptionSepArg, NULL },
1658     { "-initialMode", "initialMode", XrmoptionSepArg, NULL },
1659     { "-mode", "initialMode", XrmoptionSepArg, NULL },
1660     { "-variant", "variant", XrmoptionSepArg, NULL },
1661     { "-firstProtocolVersion", "firstProtocolVersion", XrmoptionSepArg, NULL },
1662     { "-secondProtocolVersion","secondProtocolVersion",XrmoptionSepArg, NULL },
1663     { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },
1664     { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },
1665     { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },
1666     /* [AS,HR] New features */
1667     { "-firstScoreAbs", "firstScoreAbs", XrmoptionSepArg, NULL },
1668     { "-secondScoreAbs", "secondScoreAbs", XrmoptionSepArg, NULL },
1669     { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
1670     { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
1671     { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
1672     { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
1673     { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
1674     { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
1675     { "-fUCI", "firstIsUCI", XrmoptionNoArg, "True" },
1676     { "-sUCI", "secondIsUCI", XrmoptionNoArg, "True" },
1677     { "-firstHasOwnBookUCI", "firstHasOwnBookUCI", XrmoptionSepArg, NULL },
1678     { "-secondHasOwnBookUCI", "secondHasOwnBookUCI", XrmoptionSepArg, NULL },
1679     { "-fNoOwnBookUCI", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
1680     { "-sNoOwnBookUCI", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
1681     { "-firstXBook", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
1682     { "-secondXBook", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
1683     { "-polyglotDir", "polyglotDir", XrmoptionSepArg, NULL },
1684     { "-usePolyglotBook", "usePolyglotBook", XrmoptionSepArg, NULL },
1685     { "-polyglotBook", "polyglotBook", XrmoptionSepArg, NULL },
1686     { "-defaultHashSize", "defaultHashSize", XrmoptionSepArg, NULL },
1687     { "-defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XrmoptionSepArg, NULL },
1688     { "-defaultPathEGTB", "defaultPathEGTB", XrmoptionSepArg, NULL },
1689     { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },
1690     { "-gameListTags", "gameListTags", XrmoptionSepArg, NULL },
1691     // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c
1692
1693     /* [HGM,HR] User-selectable board size */
1694     { "-boardWidth", "boardWidth", XrmoptionSepArg, NULL },
1695     { "-boardHeight", "boardHeight", XrmoptionSepArg, NULL },
1696     { "-matchPause", "matchPause", XrmoptionSepArg, NULL },
1697
1698     /* [HGM] new arguments of 4.3.xx. All except first three are back-end options, which should work immediately */
1699     { "-holdingsSize", "holdingsSize", XrmoptionSepArg, NULL }, // requires extensive front-end changes to work
1700     { "-flipBlack", "flipBlack", XrmoptionSepArg, NULL },       // requires front-end changes to work
1701     { "-allWhite", "allWhite", XrmoptionSepArg, NULL },         // requires front-end changes to work
1702     { "-pieceToCharTable", "pieceToCharTable", XrmoptionSepArg, NULL },
1703     { "-alphaRank", "alphaRank", XrmoptionSepArg, NULL },
1704     { "-testClaims", "testClaims", XrmoptionSepArg, NULL },
1705     { "-checkMates", "checkMates", XrmoptionSepArg, NULL },
1706     { "-materialDraws", "materialDraws", XrmoptionSepArg, NULL },
1707     { "-trivialDraws", "trivialDraws", XrmoptionSepArg, NULL },
1708     { "-ruleMoves", "ruleMoves", XrmoptionSepArg, NULL },
1709     { "-repeatsToDraw", "repeatsToDraw", XrmoptionSepArg, NULL },
1710     { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
1711     { "-userName", "userName", XrmoptionSepArg, NULL },
1712     { "-autoKibitz", "autoKibitz", XrmoptionNoArg, "True" },
1713     { "-firstTimeOdds", "firstTimeOdds", XrmoptionSepArg, NULL },
1714     { "-secondTimeOdds", "secondTimeOdds", XrmoptionSepArg, NULL },
1715     { "-timeOddsMode", "timeOddsMode", XrmoptionSepArg, NULL },
1716     { "-firstAccumulateTC", "firstAccumulateTC", XrmoptionSepArg, NULL },
1717     { "-secondAccumulateTC", "secondAccumulateTC", XrmoptionSepArg, NULL },
1718     { "-firstNPS", "firstNPS", XrmoptionSepArg, NULL },
1719     { "-secondNPS", "secondNPS", XrmoptionSepArg, NULL },
1720     { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL },
1721     { "-serverPause", "serverPause", XrmoptionSepArg, NULL },
1722     { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL },
1723     { "-egtFormats", "egtFormats", XrmoptionSepArg, NULL },
1724     { "-userName", "userName", XrmoptionSepArg, NULL },
1725     { "-smpCores", "smpCores", XrmoptionSepArg, NULL },
1726     { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL },
1727     { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL },
1728     { "-niceEngines", "niceEngines", XrmoptionSepArg, NULL },
1729     { "-delayBeforeQuit", "delayBeforeQuit", XrmoptionSepArg, NULL },
1730     { "-delayAfterQuit", "delayAfterQuit", XrmoptionSepArg, NULL },
1731     { "-nameOfDebugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
1732     { "-debugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
1733     { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
1734     { "-noGUI", "noGUI", XrmoptionNoArg, "True" },
1735     { "-firstOptions", "firstOptions", XrmoptionSepArg, NULL },
1736     { "-secondOptions", "secondOptions", XrmoptionSepArg, NULL },
1737 };
1738
1739
1740 XtActionsRec boardActions[] = {
1741     { "DrawPosition", DrawPositionProc },
1742     { "HandleUserMove", HandleUserMove },
1743     { "AnimateUserMove", AnimateUserMove },
1744     { "FileNameAction", FileNameAction },
1745     { "AskQuestionProc", AskQuestionProc },
1746     { "AskQuestionReplyAction", AskQuestionReplyAction },
1747     { "PieceMenuPopup", PieceMenuPopup },
1748     { "WhiteClock", WhiteClock },
1749     { "BlackClock", BlackClock },
1750     { "Iconify", Iconify },
1751     { "ResetProc", ResetProc },
1752     { "LoadGameProc", LoadGameProc },
1753     { "LoadNextGameProc", LoadNextGameProc },
1754     { "LoadPrevGameProc", LoadPrevGameProc },
1755     { "LoadSelectedProc", LoadSelectedProc },
1756     { "ReloadGameProc", ReloadGameProc },
1757     { "LoadPositionProc", LoadPositionProc },
1758     { "LoadNextPositionProc", LoadNextPositionProc },
1759     { "LoadPrevPositionProc", LoadPrevPositionProc },
1760     { "ReloadPositionProc", ReloadPositionProc },
1761     { "CopyPositionProc", CopyPositionProc },
1762     { "PastePositionProc", PastePositionProc },
1763     { "CopyGameProc", CopyGameProc },
1764     { "PasteGameProc", PasteGameProc },
1765     { "SaveGameProc", SaveGameProc },
1766     { "SavePositionProc", SavePositionProc },
1767     { "MailMoveProc", MailMoveProc },
1768     { "ReloadCmailMsgProc", ReloadCmailMsgProc },
1769     { "QuitProc", QuitProc },
1770     { "MachineWhiteProc", MachineWhiteProc },
1771     { "MachineBlackProc", MachineBlackProc },
1772     { "AnalysisModeProc", AnalyzeModeProc },
1773     { "AnalyzeFileProc", AnalyzeFileProc },
1774     { "TwoMachinesProc", TwoMachinesProc },
1775     { "IcsClientProc", IcsClientProc },
1776     { "EditGameProc", EditGameProc },
1777     { "EditPositionProc", EditPositionProc },
1778     { "TrainingProc", EditPositionProc },
1779     { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
1780     { "ShowGameListProc", ShowGameListProc },
1781     { "ShowMoveListProc", HistoryShowProc},
1782     { "EditTagsProc", EditCommentProc },
1783     { "EditCommentProc", EditCommentProc },
1784     { "IcsAlarmProc", IcsAlarmProc },
1785     { "IcsInputBoxProc", IcsInputBoxProc },
1786     { "PauseProc", PauseProc },
1787     { "AcceptProc", AcceptProc },
1788     { "DeclineProc", DeclineProc },
1789     { "RematchProc", RematchProc },
1790     { "CallFlagProc", CallFlagProc },
1791     { "DrawProc", DrawProc },
1792     { "AdjournProc", AdjournProc },
1793     { "AbortProc", AbortProc },
1794     { "ResignProc", ResignProc },
1795     { "AdjuWhiteProc", AdjuWhiteProc },
1796     { "AdjuBlackProc", AdjuBlackProc },
1797     { "AdjuDrawProc", AdjuDrawProc },
1798     { "EnterKeyProc", EnterKeyProc },
1799     { "StopObservingProc", StopObservingProc },
1800     { "StopExaminingProc", StopExaminingProc },
1801     { "BackwardProc", BackwardProc },
1802     { "ForwardProc", ForwardProc },
1803     { "ToStartProc", ToStartProc },
1804     { "ToEndProc", ToEndProc },
1805     { "RevertProc", RevertProc },
1806     { "TruncateGameProc", TruncateGameProc },
1807     { "MoveNowProc", MoveNowProc },
1808     { "RetractMoveProc", RetractMoveProc },
1809     { "AlwaysQueenProc", AlwaysQueenProc },
1810     { "AnimateDraggingProc", AnimateDraggingProc },
1811     { "AnimateMovingProc", AnimateMovingProc },
1812     { "AutoflagProc", AutoflagProc },
1813     { "AutoflipProc", AutoflipProc },
1814     { "AutobsProc", AutobsProc },
1815     { "AutoraiseProc", AutoraiseProc },
1816     { "AutosaveProc", AutosaveProc },
1817     { "BlindfoldProc", BlindfoldProc },
1818     { "FlashMovesProc", FlashMovesProc },
1819     { "FlipViewProc", FlipViewProc },
1820     { "GetMoveListProc", GetMoveListProc },
1821 #if HIGHDRAG
1822     { "HighlightDraggingProc", HighlightDraggingProc },
1823 #endif
1824     { "HighlightLastMoveProc", HighlightLastMoveProc },
1825     { "IcsAlarmProc", IcsAlarmProc },
1826     { "MoveSoundProc", MoveSoundProc },
1827     { "OldSaveStyleProc", OldSaveStyleProc },
1828     { "PeriodicUpdatesProc", PeriodicUpdatesProc },
1829     { "PonderNextMoveProc", PonderNextMoveProc },
1830     { "PopupExitMessageProc", PopupExitMessageProc },
1831     { "PopupMoveErrorsProc", PopupMoveErrorsProc },
1832     { "PremoveProc", PremoveProc },
1833     { "QuietPlayProc", QuietPlayProc },
1834     { "ShowCoordsProc", ShowCoordsProc },
1835     { "ShowThinkingProc", ShowThinkingProc },
1836     { "HideThinkingProc", HideThinkingProc },
1837     { "TestLegalityProc", TestLegalityProc },
1838     { "InfoProc", InfoProc },
1839     { "ManProc", ManProc },
1840     { "HintProc", HintProc },
1841     { "BookProc", BookProc },
1842     { "AboutGameProc", AboutGameProc },
1843     { "AboutProc", AboutProc },
1844     { "DebugProc", DebugProc },
1845     { "NothingProc", NothingProc },
1846     { "CommentPopDown", (XtActionProc) CommentPopDown },
1847     { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
1848     { "TagsPopDown", (XtActionProc) TagsPopDown },
1849     { "ErrorPopDown", (XtActionProc) ErrorPopDown },
1850     { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
1851     { "AnalysisPopDown", (XtActionProc) AnalysisPopDown },
1852     { "FileNamePopDown", (XtActionProc) FileNamePopDown },
1853     { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
1854     { "GameListPopDown", (XtActionProc) GameListPopDown },
1855     { "PromotionPopDown", (XtActionProc) PromotionPopDown },
1856     { "HistoryPopDown", (XtActionProc) HistoryPopDown },
1857     { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
1858     { "ShufflePopDown", (XtActionProc) ShufflePopDown },
1859     { "EnginePopDown", (XtActionProc) EnginePopDown },
1860     { "UciPopDown", (XtActionProc) UciPopDown },
1861     { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
1862     { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
1863     { "SettingsPopDown", (XtActionProc) SettingsPopDown },
1864 };
1865
1866 char globalTranslations[] =
1867   ":<Key>R: ResignProc() \n \
1868    :<Key>r: ResetProc() \n \
1869    :<Key>g: LoadGameProc() \n \
1870    :<Key>N: LoadNextGameProc() \n \
1871    :<Key>P: LoadPrevGameProc() \n \
1872    :<Key>Q: QuitProc() \n \
1873    :<Key>F: ToEndProc() \n \
1874    :<Key>f: ForwardProc() \n \
1875    :<Key>B: ToStartProc() \n \
1876    :<Key>b: BackwardProc() \n \
1877    :<Key>p: PauseProc() \n \
1878    :<Key>d: DrawProc() \n \
1879    :<Key>t: CallFlagProc() \n \
1880    :<Key>i: Iconify() \n \
1881    :<Key>c: Iconify() \n \
1882    :<Key>v: FlipViewProc() \n \
1883    <KeyDown>Control_L: BackwardProc() \n \
1884    <KeyUp>Control_L: ForwardProc() \n \
1885    <KeyDown>Control_R: BackwardProc() \n \
1886    <KeyUp>Control_R: ForwardProc() \n \
1887    Shift<Key>1: AskQuestionProc(\"Direct command\",\
1888                                 \"Send to chess program:\",,1) \n \
1889    Shift<Key>2: AskQuestionProc(\"Direct command\",\
1890                                 \"Send to second chess program:\",,2) \n";
1891
1892 char boardTranslations[] =
1893    "<Btn1Down>: HandleUserMove() \n \
1894    <Btn1Up>: HandleUserMove() \n \
1895    <Btn1Motion>: AnimateUserMove() \n \
1896    Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
1897                  PieceMenuPopup(menuB) \n \
1898    Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
1899                  PieceMenuPopup(menuW) \n \
1900    Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
1901                  PieceMenuPopup(menuW) \n \
1902    Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
1903                  PieceMenuPopup(menuB) \n";
1904
1905 char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
1906 char blackTranslations[] = "<BtnDown>: BlackClock()\n";
1907
1908 char ICSInputTranslations[] =
1909     "<Key>Return: EnterKeyProc() \n";
1910
1911 String xboardResources[] = {
1912     "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
1913     "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
1914     "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
1915     NULL
1916   };
1917
1918
1919 /* Max possible square size */
1920 #define MAXSQSIZE 256
1921
1922 static int xpm_avail[MAXSQSIZE];
1923
1924 #ifdef HAVE_DIR_STRUCT
1925
1926 /* Extract piece size from filename */
1927 static int
1928 xpm_getsize(name, len, ext)
1929      char *name;
1930      int len;
1931      char *ext;
1932 {
1933     char *p, *d;
1934     char buf[10];
1935
1936     if (len < 4)
1937       return 0;
1938
1939     if ((p=strchr(name, '.')) == NULL ||
1940         StrCaseCmp(p+1, ext) != 0)
1941       return 0;
1942
1943     p = name + 3;
1944     d = buf;
1945
1946     while (*p && isdigit(*p))
1947       *(d++) = *(p++);
1948
1949     *d = 0;
1950     return atoi(buf);
1951 }
1952
1953 /* Setup xpm_avail */
1954 static int
1955 xpm_getavail(dirname, ext)
1956      char *dirname;
1957      char *ext;
1958 {
1959     DIR *dir;
1960     struct dirent *ent;
1961     int  i;
1962
1963     for (i=0; i<MAXSQSIZE; ++i)
1964       xpm_avail[i] = 0;
1965
1966     if (appData.debugMode)
1967       fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);
1968
1969     dir = opendir(dirname);
1970     if (!dir)
1971       {
1972           fprintf(stderr, _("%s: Can't access XPM directory %s\n"),
1973                   programName, dirname);
1974           exit(1);
1975       }
1976
1977     while ((ent=readdir(dir)) != NULL) {
1978         i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);
1979         if (i > 0 && i < MAXSQSIZE)
1980           xpm_avail[i] = 1;
1981     }
1982
1983     closedir(dir);
1984
1985     return 0;
1986 }
1987
1988 void
1989 xpm_print_avail(fp, ext)
1990      FILE *fp;
1991      char *ext;
1992 {
1993     int i;
1994
1995     fprintf(fp, _("Available `%s' sizes:\n"), ext);
1996     for (i=1; i<MAXSQSIZE; ++i) {
1997         if (xpm_avail[i])
1998           printf("%d\n", i);
1999     }
2000 }
2001
2002 /* Return XPM piecesize closest to size */
2003 int
2004 xpm_closest_to(dirname, size, ext)
2005      char *dirname;
2006      int size;
2007      char *ext;
2008 {
2009     int i;
2010     int sm_diff = MAXSQSIZE;
2011     int sm_index = 0;
2012     int diff;
2013
2014     xpm_getavail(dirname, ext);
2015
2016     if (appData.debugMode)
2017       xpm_print_avail(stderr, ext);
2018
2019     for (i=1; i<MAXSQSIZE; ++i) {
2020         if (xpm_avail[i]) {
2021             diff = size - i;
2022             diff = (diff<0) ? -diff : diff;
2023             if (diff < sm_diff) {
2024                 sm_diff = diff;
2025                 sm_index = i;
2026             }
2027         }
2028     }
2029
2030     if (!sm_index) {
2031         fprintf(stderr, _("Error: No `%s' files!\n"), ext);
2032         exit(1);
2033     }
2034
2035     return sm_index;
2036 }
2037 #else   /* !HAVE_DIR_STRUCT */
2038 /* If we are on a system without a DIR struct, we can't
2039    read the directory, so we can't collect a list of
2040    filenames, etc., so we can't do any size-fitting. */
2041 int
2042 xpm_closest_to(dirname, size, ext)
2043      char *dirname;
2044      int size;
2045      char *ext;
2046 {
2047     fprintf(stderr, _("\
2048 Warning: No DIR structure found on this system --\n\
2049          Unable to autosize for XPM/XIM pieces.\n\
2050    Please report this error to frankm@hiwaay.net.\n\
2051    Include system type & operating system in message.\n"));
2052     return size;
2053 }
2054 #endif /* HAVE_DIR_STRUCT */
2055
2056 static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
2057                              "magenta", "cyan", "white" };
2058 typedef struct {
2059     int attr, bg, fg;
2060 } TextColors;
2061 TextColors textColors[(int)NColorClasses];
2062
2063 /* String is: "fg, bg, attr". Which is 0, 1, 2 */
2064 static int
2065 parse_color(str, which)
2066      char *str;
2067      int which;
2068 {
2069     char *p, buf[100], *d;
2070     int i;
2071
2072     if (strlen(str) > 99)       /* watch bounds on buf */
2073       return -1;
2074
2075     p = str;
2076     d = buf;
2077     for (i=0; i<which; ++i) {
2078         p = strchr(p, ',');
2079         if (!p)
2080           return -1;
2081         ++p;
2082     }
2083
2084     /* Could be looking at something like:
2085        black, , 1
2086        .. in which case we want to stop on a comma also */
2087     while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
2088       ++p;
2089
2090     if (*p == ',') {
2091         return -1;              /* Use default for empty field */
2092     }
2093
2094     if (which == 2 || isdigit(*p))
2095       return atoi(p);
2096
2097     while (*p && isalpha(*p))
2098       *(d++) = *(p++);
2099
2100     *d = 0;
2101
2102     for (i=0; i<8; ++i) {
2103         if (!StrCaseCmp(buf, cnames[i]))
2104           return which? (i+40) : (i+30);
2105     }
2106     if (!StrCaseCmp(buf, "default")) return -1;
2107
2108     fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
2109     return -2;
2110 }
2111
2112 static int
2113 parse_cpair(cc, str)
2114      ColorClass cc;
2115      char *str;
2116 {
2117     if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
2118         fprintf(stderr, _("%s: can't parse foreground color in `%s'\n"),
2119                 programName, str);
2120         return -1;
2121     }
2122
2123     /* bg and attr are optional */
2124     textColors[(int)cc].bg = parse_color(str, 1);
2125     if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
2126         textColors[(int)cc].attr = 0;
2127     }
2128     return 0;
2129 }
2130
2131
2132 /* Arrange to catch delete-window events */
2133 Atom wm_delete_window;
2134 void
2135 CatchDeleteWindow(Widget w, String procname)
2136 {
2137   char buf[MSG_SIZ];
2138   XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);
2139   sprintf(buf, "<Message>WM_PROTOCOLS: %s() \n", procname);
2140   XtAugmentTranslations(w, XtParseTranslationTable(buf));
2141 }
2142
2143 void
2144 BoardToTop()
2145 {
2146   Arg args[16];
2147   XtSetArg(args[0], XtNiconic, False);
2148   XtSetValues(shellWidget, args, 1);
2149
2150   XtPopup(shellWidget, XtGrabNone); /* Raise if lowered  */
2151 }
2152
2153 #ifdef IDSIZES
2154   // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
2155 #else
2156 #define BoardSize int
2157 void InitDrawingSizes(BoardSize boardSize, int flags)
2158 {   // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
2159     Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
2160     Arg args[16];
2161     XtGeometryResult gres;
2162     int i;
2163
2164     if(!formWidget) return;
2165
2166     /*
2167      * Enable shell resizing.
2168      */
2169     shellArgs[0].value = (XtArgVal) &w;
2170     shellArgs[1].value = (XtArgVal) &h;
2171     XtGetValues(shellWidget, shellArgs, 2);
2172
2173     shellArgs[4].value = 2*w; shellArgs[2].value = 10;
2174     shellArgs[5].value = 2*h; shellArgs[3].value = 10;
2175     XtSetValues(shellWidget, &shellArgs[2], 4);
2176
2177     XtSetArg(args[0], XtNdefaultDistance, &sep);
2178     XtGetValues(formWidget, args, 1);
2179
2180     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
2181     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
2182     CreateGrid();
2183
2184     XtSetArg(args[0], XtNwidth, boardWidth);
2185     XtSetArg(args[1], XtNheight, boardHeight);
2186     XtSetValues(boardWidget, args, 2);
2187
2188     timerWidth = (boardWidth - sep) / 2;
2189     XtSetArg(args[0], XtNwidth, timerWidth);
2190     XtSetValues(whiteTimerWidget, args, 1);
2191     XtSetValues(blackTimerWidget, args, 1);
2192
2193     XawFormDoLayout(formWidget, False);
2194
2195     if (appData.titleInWindow) {
2196         i = 0;
2197         XtSetArg(args[i], XtNborderWidth, &bor); i++;
2198         XtSetArg(args[i], XtNheight, &h);  i++;
2199         XtGetValues(titleWidget, args, i);
2200         if (smallLayout) {
2201             w = boardWidth - 2*bor;
2202         } else {
2203             XtSetArg(args[0], XtNwidth, &w);
2204             XtGetValues(menuBarWidget, args, 1);
2205             w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE
2206         }
2207
2208         gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
2209         if (gres != XtGeometryYes && appData.debugMode) {
2210             fprintf(stderr,
2211                     _("%s: titleWidget geometry error %d %d %d %d %d\n"),
2212                     programName, gres, w, h, wr, hr);
2213         }
2214     }
2215
2216     XawFormDoLayout(formWidget, True);
2217
2218     /*
2219      * Inhibit shell resizing.
2220      */
2221     shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
2222     shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
2223     shellArgs[4].value = shellArgs[2].value = w;
2224     shellArgs[5].value = shellArgs[3].value = h;
2225     XtSetValues(shellWidget, &shellArgs[0], 6);
2226 }
2227 #endif
2228
2229 int
2230 main(argc, argv)
2231      int argc;
2232      char **argv;
2233 {
2234     int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
2235     XSetWindowAttributes window_attributes;
2236     Arg args[16];
2237     Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
2238     XrmValue vFrom, vTo;
2239     XtGeometryResult gres;
2240     char *p;
2241     XrmDatabase xdb;
2242     int forceMono = False;
2243 #define INDIRECTION
2244 #ifdef INDIRECTION
2245     // [HGM] before anything else, expand any indirection files amongst options
2246     char *argvCopy[1000]; // 1000 seems enough
2247     char newArgs[10000];  // holds actual characters
2248     int k = 0;
2249
2250     srandom(time(0)); // [HGM] book: make random truly random
2251
2252     j = 0;
2253     for(i=0; i<argc; i++) {
2254         if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2255 //fprintf(stderr, "arg %s\n", argv[i]);
2256         if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
2257             char c;
2258             FILE *f = fopen(argv[i]+1, "rb");
2259             if(f == NULL) { fprintf(stderr, _("ignore %s\n"), argv[i]); continue; } // do not expand non-existing
2260             argvCopy[j++] = newArgs + k; // get ready for first argument from file
2261             while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
2262                 if(c == '\n') {
2263                     if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2264                     newArgs[k++] = 0;  // terminate current arg
2265                     if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2266                     argvCopy[j++] = newArgs + k; // get ready for next
2267                 } else {
2268                     if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2269                     newArgs[k++] = c;
2270                 }
2271             }
2272             newArgs[k] = 0;
2273             j--;
2274             fclose(f);
2275         }
2276     }
2277     argvCopy[j] = NULL;
2278     argv = argvCopy;
2279     argc = j;
2280 #if 0
2281     if(appData.debugMode,1) { // OK, appData is not initialized here yet...
2282         for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
2283     }
2284 #endif
2285 #endif
2286
2287
2288     setbuf(stdout, NULL);
2289     setbuf(stderr, NULL);
2290     debugFP = stderr;
2291
2292     programName = strrchr(argv[0], '/');
2293     if (programName == NULL)
2294       programName = argv[0];
2295     else
2296       programName++;
2297
2298 #ifdef ENABLE_NLS
2299     XtSetLanguageProc(NULL, NULL, NULL);
2300     bindtextdomain(PRODUCT, LOCALEDIR);
2301     textdomain(PRODUCT);
2302 #endif
2303
2304     shellWidget =
2305       XtAppInitialize(&appContext, "XBoard", shellOptions,
2306                       XtNumber(shellOptions),
2307                       &argc, argv, xboardResources, NULL, 0);
2308     if (argc > 1) {
2309         fprintf(stderr, _("%s: unrecognized argument %s\n"),
2310                 programName, argv[1]);
2311         exit(2);
2312     }
2313
2314     if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
2315         chessDir = ".";
2316     } else {
2317         if (chdir(chessDir) != 0) {
2318             fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
2319             perror(chessDir);
2320             exit(1);
2321         }
2322     }
2323
2324     p = getenv("HOME");
2325     if (p == NULL) p = "/tmp";
2326     i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
2327     gameCopyFilename = (char*) malloc(i);
2328     gamePasteFilename = (char*) malloc(i);
2329     sprintf(gameCopyFilename, "%s/.xboard%05uc.pgn", p, getpid());
2330     sprintf(gamePasteFilename, "%s/.xboard%05up.pgn", p, getpid());
2331
2332     XtGetApplicationResources(shellWidget, (XtPointer) &appData,
2333                               clientResources, XtNumber(clientResources),
2334                               NULL, 0);
2335
2336     if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
2337         /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
2338         if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL)  {
2339            printf(_("Failed to open file '%s'\n"), appData.nameOfDebugFile);
2340            exit(errno);
2341         }
2342         setbuf(debugFP, NULL);
2343     }
2344
2345     /* [HGM,HR] make sure board size is acceptable */
2346     if(appData.NrFiles > BOARD_SIZE ||
2347        appData.NrRanks > BOARD_SIZE   )
2348          DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
2349
2350 #if !HIGHDRAG
2351     /* This feature does not work; animation needs a rewrite */
2352     appData.highlightDragging = FALSE;
2353 #endif
2354     InitBackEnd1();
2355
2356     xDisplay = XtDisplay(shellWidget);
2357     xScreen = DefaultScreen(xDisplay);
2358     wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
2359
2360         gameInfo.variant = StringToVariant(appData.variant);
2361         InitPosition(FALSE);
2362 #if 0
2363     /*
2364      * Determine boardSize
2365      */
2366     gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
2367
2368 //#ifndef IDSIZE
2369     // [HGM] as long as we have not created the possibility to change size while running, start with requested size
2370     gameInfo.boardWidth    = appData.NrFiles > 0 ? appData.NrFiles : 8;
2371     gameInfo.boardHeight   = appData.NrRanks > 0 ? appData.NrRanks : 8;
2372     gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
2373 #endif
2374
2375
2376 #ifdef IDSIZE
2377     InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
2378 #else
2379     if (isdigit(appData.boardSize[0])) {
2380         i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
2381                    &lineGap, &clockFontPxlSize, &coordFontPxlSize,
2382                    &fontPxlSize, &smallLayout, &tinyLayout);
2383         if (i == 0) {
2384             fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
2385                     programName, appData.boardSize);
2386             exit(2);
2387         }
2388         if (i < 7) {
2389             /* Find some defaults; use the nearest known size */
2390             SizeDefaults *szd, *nearest;
2391             int distance = 99999;
2392             nearest = szd = sizeDefaults;
2393             while (szd->name != NULL) {
2394                 if (abs(szd->squareSize - squareSize) < distance) {
2395                     nearest = szd;
2396                     distance = abs(szd->squareSize - squareSize);
2397                     if (distance == 0) break;
2398                 }
2399                 szd++;
2400             }
2401             if (i < 2) lineGap = nearest->lineGap;
2402             if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
2403             if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
2404             if (i < 5) fontPxlSize = nearest->fontPxlSize;
2405             if (i < 6) smallLayout = nearest->smallLayout;
2406             if (i < 7) tinyLayout = nearest->tinyLayout;
2407         }
2408     } else {
2409         SizeDefaults *szd = sizeDefaults;
2410         if (*appData.boardSize == NULLCHAR) {
2411             while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
2412                    DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
2413               szd++;
2414             }
2415             if (szd->name == NULL) szd--;
2416         } else {
2417             while (szd->name != NULL &&
2418                    StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
2419             if (szd->name == NULL) {
2420                 fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
2421                         programName, appData.boardSize);
2422                 exit(2);
2423             }
2424         }
2425         squareSize = szd->squareSize;
2426         lineGap = szd->lineGap;
2427         clockFontPxlSize = szd->clockFontPxlSize;
2428         coordFontPxlSize = szd->coordFontPxlSize;
2429         fontPxlSize = szd->fontPxlSize;
2430         smallLayout = szd->smallLayout;
2431         tinyLayout = szd->tinyLayout;
2432     }
2433
2434     /* Now, using squareSize as a hint, find a good XPM/XIM set size */
2435     if (strlen(appData.pixmapDirectory) > 0) {
2436         p = ExpandPathName(appData.pixmapDirectory);
2437         if (!p) {
2438             fprintf(stderr, _("Error expanding path name \"%s\"\n"),
2439                    appData.pixmapDirectory);
2440             exit(1);
2441         }
2442         if (appData.debugMode) {
2443           fprintf(stderr, _("\
2444 XBoard square size (hint): %d\n\
2445 %s fulldir:%s:\n"), squareSize, IMAGE_EXT, p);
2446         }
2447         squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
2448         if (appData.debugMode) {
2449             fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
2450         }
2451     }
2452
2453     /* [HR] height treated separately (hacked) */
2454     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
2455     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
2456     if (appData.showJail == 1) {
2457         /* Jail on top and bottom */
2458         XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2459         XtSetArg(boardArgs[2], XtNheight,
2460                  boardHeight + 2*(lineGap + squareSize));
2461     } else if (appData.showJail == 2) {
2462         /* Jail on sides */
2463         XtSetArg(boardArgs[1], XtNwidth,
2464                  boardWidth + 2*(lineGap + squareSize));
2465         XtSetArg(boardArgs[2], XtNheight, boardHeight);
2466     } else {
2467         /* No jail */
2468         XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2469         XtSetArg(boardArgs[2], XtNheight, boardHeight);
2470     }
2471
2472     /*
2473      * Determine what fonts to use.
2474      */
2475     appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
2476     clockFontID = XLoadFont(xDisplay, appData.clockFont);
2477     clockFontStruct = XQueryFont(xDisplay, clockFontID);
2478     appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
2479     coordFontID = XLoadFont(xDisplay, appData.coordFont);
2480     coordFontStruct = XQueryFont(xDisplay, coordFontID);
2481     appData.font = FindFont(appData.font, fontPxlSize);
2482     countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
2483     countFontStruct = XQueryFont(xDisplay, countFontID);
2484 //    appData.font = FindFont(appData.font, fontPxlSize);
2485
2486     xdb = XtDatabase(xDisplay);
2487     XrmPutStringResource(&xdb, "*font", appData.font);
2488
2489     /*
2490      * Detect if there are not enough colors available and adapt.
2491      */
2492     if (DefaultDepth(xDisplay, xScreen) <= 2) {
2493       appData.monoMode = True;
2494     }
2495
2496     if (!appData.monoMode) {
2497         vFrom.addr = (caddr_t) appData.lightSquareColor;
2498         vFrom.size = strlen(appData.lightSquareColor);
2499         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2500         if (vTo.addr == NULL) {
2501           appData.monoMode = True;
2502           forceMono = True;
2503         } else {
2504           lightSquareColor = *(Pixel *) vTo.addr;
2505         }
2506     }
2507     if (!appData.monoMode) {
2508         vFrom.addr = (caddr_t) appData.darkSquareColor;
2509         vFrom.size = strlen(appData.darkSquareColor);
2510         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2511         if (vTo.addr == NULL) {
2512           appData.monoMode = True;
2513           forceMono = True;
2514         } else {
2515           darkSquareColor = *(Pixel *) vTo.addr;
2516         }
2517     }
2518     if (!appData.monoMode) {
2519         vFrom.addr = (caddr_t) appData.whitePieceColor;
2520         vFrom.size = strlen(appData.whitePieceColor);
2521         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2522         if (vTo.addr == NULL) {
2523           appData.monoMode = True;
2524           forceMono = True;
2525         } else {
2526           whitePieceColor = *(Pixel *) vTo.addr;
2527         }
2528     }
2529     if (!appData.monoMode) {
2530         vFrom.addr = (caddr_t) appData.blackPieceColor;
2531         vFrom.size = strlen(appData.blackPieceColor);
2532         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2533         if (vTo.addr == NULL) {
2534           appData.monoMode = True;
2535           forceMono = True;
2536         } else {
2537           blackPieceColor = *(Pixel *) vTo.addr;
2538         }
2539     }
2540
2541     if (!appData.monoMode) {
2542         vFrom.addr = (caddr_t) appData.highlightSquareColor;
2543         vFrom.size = strlen(appData.highlightSquareColor);
2544         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2545         if (vTo.addr == NULL) {
2546           appData.monoMode = True;
2547           forceMono = True;
2548         } else {
2549           highlightSquareColor = *(Pixel *) vTo.addr;
2550         }
2551     }
2552
2553     if (!appData.monoMode) {
2554         vFrom.addr = (caddr_t) appData.premoveHighlightColor;
2555         vFrom.size = strlen(appData.premoveHighlightColor);
2556         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2557         if (vTo.addr == NULL) {
2558           appData.monoMode = True;
2559           forceMono = True;
2560         } else {
2561           premoveHighlightColor = *(Pixel *) vTo.addr;
2562         }
2563     }
2564
2565     if (forceMono) {
2566       fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
2567               programName);
2568     }
2569
2570     if (appData.monoMode && appData.debugMode) {
2571         fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
2572                 (unsigned long) XWhitePixel(xDisplay, xScreen),
2573                 (unsigned long) XBlackPixel(xDisplay, xScreen));
2574     }
2575
2576     if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
2577         parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
2578         parse_cpair(ColorChannel1, appData.colorChannel1) < 0  ||
2579         parse_cpair(ColorChannel, appData.colorChannel) < 0  ||
2580         parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
2581         parse_cpair(ColorTell, appData.colorTell) < 0 ||
2582         parse_cpair(ColorChallenge, appData.colorChallenge) < 0  ||
2583         parse_cpair(ColorRequest, appData.colorRequest) < 0  ||
2584         parse_cpair(ColorSeek, appData.colorSeek) < 0  ||
2585         parse_cpair(ColorNormal, appData.colorNormal) < 0)
2586       {
2587           if (appData.colorize) {
2588               fprintf(stderr,
2589                       _("%s: can't parse color names; disabling colorization\n"),
2590                       programName);
2591           }
2592           appData.colorize = FALSE;
2593       }
2594     textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
2595     textColors[ColorNone].attr = 0;
2596
2597     XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
2598
2599     /*
2600      * widget hierarchy
2601      */
2602     if (tinyLayout) {
2603         layoutName = "tinyLayout";
2604     } else if (smallLayout) {
2605         layoutName = "smallLayout";
2606     } else {
2607         layoutName = "normalLayout";
2608     }
2609     /* Outer layoutWidget is there only to provide a name for use in
2610        resources that depend on the layout style */
2611     layoutWidget =
2612       XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
2613                             layoutArgs, XtNumber(layoutArgs));
2614     formWidget =
2615       XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
2616                             formArgs, XtNumber(formArgs));
2617     XtSetArg(args[0], XtNdefaultDistance, &sep);
2618     XtGetValues(formWidget, args, 1);
2619
2620     j = 0;
2621     widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
2622     XtSetArg(args[0], XtNtop,    XtChainTop);
2623     XtSetArg(args[1], XtNbottom, XtChainTop);
2624     XtSetValues(menuBarWidget, args, 2);
2625
2626     widgetList[j++] = whiteTimerWidget =
2627       XtCreateWidget("whiteTime", labelWidgetClass,
2628                      formWidget, timerArgs, XtNumber(timerArgs));
2629     XtSetArg(args[0], XtNfont, clockFontStruct);
2630     XtSetArg(args[1], XtNtop,    XtChainTop);
2631     XtSetArg(args[2], XtNbottom, XtChainTop);
2632     XtSetValues(whiteTimerWidget, args, 3);
2633
2634     widgetList[j++] = blackTimerWidget =
2635       XtCreateWidget("blackTime", 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(blackTimerWidget, args, 3);
2641
2642     if (appData.titleInWindow) {
2643         widgetList[j++] = titleWidget =
2644           XtCreateWidget("title", labelWidgetClass, formWidget,
2645                          titleArgs, XtNumber(titleArgs));
2646         XtSetArg(args[0], XtNtop,    XtChainTop);
2647         XtSetArg(args[1], XtNbottom, XtChainTop);
2648         XtSetValues(titleWidget, args, 2);
2649     }
2650
2651     if (appData.showButtonBar) {
2652       widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
2653       XtSetArg(args[0], XtNleft,  XtChainRight); // [HGM] glue to right window edge
2654       XtSetArg(args[1], XtNright, XtChainRight); //       for good run-time sizing
2655       XtSetArg(args[2], XtNtop,    XtChainTop);
2656       XtSetArg(args[3], XtNbottom, XtChainTop);
2657       XtSetValues(buttonBarWidget, args, 4);
2658     }
2659
2660     widgetList[j++] = messageWidget =
2661       XtCreateWidget("message", labelWidgetClass, formWidget,
2662                      messageArgs, XtNumber(messageArgs));
2663     XtSetArg(args[0], XtNtop,    XtChainTop);
2664     XtSetArg(args[1], XtNbottom, XtChainTop);
2665     XtSetValues(messageWidget, args, 2);
2666
2667     widgetList[j++] = boardWidget =
2668       XtCreateWidget("board", widgetClass, formWidget, boardArgs,
2669                      XtNumber(boardArgs));
2670
2671     XtManageChildren(widgetList, j);
2672
2673     timerWidth = (boardWidth - sep) / 2;
2674     XtSetArg(args[0], XtNwidth, timerWidth);
2675     XtSetValues(whiteTimerWidget, args, 1);
2676     XtSetValues(blackTimerWidget, args, 1);
2677
2678     XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
2679     XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
2680     XtGetValues(whiteTimerWidget, args, 2);
2681
2682     if (appData.showButtonBar) {
2683       XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
2684       XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
2685       XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
2686     }
2687
2688     /*
2689      * formWidget uses these constraints but they are stored
2690      * in the children.
2691      */
2692     i = 0;
2693     XtSetArg(args[i], XtNfromHoriz, 0); i++;
2694     XtSetValues(menuBarWidget, args, i);
2695     if (appData.titleInWindow) {
2696         if (smallLayout) {
2697             i = 0;
2698             XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2699             XtSetValues(whiteTimerWidget, args, i);
2700             i = 0;
2701             XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2702             XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2703             XtSetValues(blackTimerWidget, args, i);
2704             i = 0;
2705             XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2706             XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
2707             XtSetValues(titleWidget, args, i);
2708             i = 0;
2709             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2710             XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2711             XtSetValues(messageWidget, args, i);
2712             if (appData.showButtonBar) {
2713               i = 0;
2714               XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2715               XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2716               XtSetValues(buttonBarWidget, args, i);
2717             }
2718         } else {
2719             i = 0;
2720             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2721             XtSetValues(whiteTimerWidget, args, i);
2722             i = 0;
2723             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2724             XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2725             XtSetValues(blackTimerWidget, args, i);
2726             i = 0;
2727             XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
2728             XtSetValues(titleWidget, args, i);
2729             i = 0;
2730             XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2731             XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2732             XtSetValues(messageWidget, args, i);
2733             if (appData.showButtonBar) {
2734               i = 0;
2735               XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2736               XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2737               XtSetValues(buttonBarWidget, args, i);
2738             }
2739         }
2740     } else {
2741         i = 0;
2742         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2743         XtSetValues(whiteTimerWidget, args, i);
2744         i = 0;
2745         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2746         XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2747         XtSetValues(blackTimerWidget, args, i);
2748         i = 0;
2749         XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2750         XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2751         XtSetValues(messageWidget, args, i);
2752         if (appData.showButtonBar) {
2753           i = 0;
2754           XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2755           XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2756           XtSetValues(buttonBarWidget, args, i);
2757         }
2758     }
2759     i = 0;
2760     XtSetArg(args[0], XtNfromVert, messageWidget);
2761     XtSetArg(args[1], XtNtop,    XtChainTop);
2762     XtSetArg(args[2], XtNbottom, XtChainBottom);
2763     XtSetArg(args[3], XtNleft,   XtChainLeft);
2764     XtSetArg(args[4], XtNright,  XtChainRight);
2765     XtSetValues(boardWidget, args, 5);
2766
2767     XtRealizeWidget(shellWidget);
2768
2769     /*
2770      * Correct the width of the message and title widgets.
2771      * It is not known why some systems need the extra fudge term.
2772      * The value "2" is probably larger than needed.
2773      */
2774     XawFormDoLayout(formWidget, False);
2775
2776 #define WIDTH_FUDGE 2
2777     i = 0;
2778     XtSetArg(args[i], XtNborderWidth, &bor);  i++;
2779     XtSetArg(args[i], XtNheight, &h);  i++;
2780     XtGetValues(messageWidget, args, i);
2781     if (appData.showButtonBar) {
2782       i = 0;
2783       XtSetArg(args[i], XtNwidth, &w);  i++;
2784       XtGetValues(buttonBarWidget, args, i);
2785       w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2786     } else {
2787       w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
2788     }
2789
2790     gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2791     if (gres != XtGeometryYes && appData.debugMode) {
2792       fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2793               programName, gres, w, h, wr, hr);
2794     }
2795
2796     /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
2797     /* The size used for the child widget in layout lags one resize behind
2798        its true size, so we resize a second time, 1 pixel smaller.  Yeech! */
2799     w--;
2800     gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2801     if (gres != XtGeometryYes && appData.debugMode) {
2802       fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2803               programName, gres, w, h, wr, hr);
2804     }
2805     /* !! end hack */
2806     XtSetArg(args[0], XtNleft,  XtChainLeft);  // [HGM] glue ends for good run-time sizing
2807     XtSetArg(args[1], XtNright, XtChainRight);
2808     XtSetValues(messageWidget, args, 2);
2809
2810     if (appData.titleInWindow) {
2811         i = 0;
2812         XtSetArg(args[i], XtNborderWidth, &bor); i++;
2813         XtSetArg(args[i], XtNheight, &h);  i++;
2814         XtGetValues(titleWidget, args, i);
2815         if (smallLayout) {
2816             w = boardWidth - 2*bor;
2817         } else {
2818             XtSetArg(args[0], XtNwidth, &w);
2819             XtGetValues(menuBarWidget, args, 1);
2820             w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2821         }
2822
2823         gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
2824         if (gres != XtGeometryYes && appData.debugMode) {
2825             fprintf(stderr,
2826                     _("%s: titleWidget geometry error %d %d %d %d %d\n"),
2827                     programName, gres, w, h, wr, hr);
2828         }
2829     }
2830     XawFormDoLayout(formWidget, True);
2831
2832     xBoardWindow = XtWindow(boardWidget);
2833
2834     // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
2835     //       not need to go into InitDrawingSizes().
2836 #endif
2837
2838     /*
2839      * Create X checkmark bitmap and initialize option menu checks.
2840      */
2841     ReadBitmap(&xMarkPixmap, "checkmark.bm",
2842                checkmark_bits, checkmark_width, checkmark_height);
2843     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
2844     if (appData.alwaysPromoteToQueen) {
2845         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
2846                     args, 1);
2847     }
2848     if (appData.animateDragging) {
2849         XtSetValues(XtNameToWidget(menuBarWidget,
2850                                    "menuOptions.Animate Dragging"),
2851                     args, 1);
2852     }
2853     if (appData.animate) {
2854         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
2855                     args, 1);
2856     }
2857     if (appData.autoComment) {
2858         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
2859                     args, 1);
2860     }
2861     if (appData.autoCallFlag) {
2862         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
2863                     args, 1);
2864     }
2865     if (appData.autoFlipView) {
2866         XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
2867                     args, 1);
2868     }
2869     if (appData.autoObserve) {
2870         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
2871                     args, 1);
2872     }
2873     if (appData.autoRaiseBoard) {
2874         XtSetValues(XtNameToWidget(menuBarWidget,
2875                                    "menuOptions.Auto Raise Board"), args, 1);
2876     }
2877     if (appData.autoSaveGames) {
2878         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
2879                     args, 1);
2880     }
2881     if (appData.saveGameFile[0] != NULLCHAR) {
2882         /* Can't turn this off from menu */
2883         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
2884                     args, 1);
2885         XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
2886                        False);
2887
2888     }
2889     if (appData.blindfold) {
2890         XtSetValues(XtNameToWidget(menuBarWidget,
2891                                    "menuOptions.Blindfold"), args, 1);
2892     }
2893     if (appData.flashCount > 0) {
2894         XtSetValues(XtNameToWidget(menuBarWidget,
2895                                    "menuOptions.Flash Moves"),
2896                     args, 1);
2897     }
2898     if (appData.getMoveList) {
2899         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
2900                     args, 1);
2901     }
2902 #if HIGHDRAG
2903     if (appData.highlightDragging) {
2904         XtSetValues(XtNameToWidget(menuBarWidget,
2905                                    "menuOptions.Highlight Dragging"),
2906                     args, 1);
2907     }
2908 #endif
2909     if (appData.highlightLastMove) {
2910         XtSetValues(XtNameToWidget(menuBarWidget,
2911                                    "menuOptions.Highlight Last Move"),
2912                     args, 1);
2913     }
2914     if (appData.icsAlarm) {
2915         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
2916                     args, 1);
2917     }
2918     if (appData.ringBellAfterMoves) {
2919         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
2920                     args, 1);
2921     }
2922     if (appData.oldSaveStyle) {
2923         XtSetValues(XtNameToWidget(menuBarWidget,
2924                                    "menuOptions.Old Save Style"), args, 1);
2925     }
2926     if (appData.periodicUpdates) {
2927         XtSetValues(XtNameToWidget(menuBarWidget,
2928                                    "menuOptions.Periodic Updates"), args, 1);
2929     }
2930     if (appData.ponderNextMove) {
2931         XtSetValues(XtNameToWidget(menuBarWidget,
2932                                    "menuOptions.Ponder Next Move"), args, 1);
2933     }
2934     if (appData.popupExitMessage) {
2935         XtSetValues(XtNameToWidget(menuBarWidget,
2936                                    "menuOptions.Popup Exit Message"), args, 1);
2937     }
2938     if (appData.popupMoveErrors) {
2939         XtSetValues(XtNameToWidget(menuBarWidget,
2940                                    "menuOptions.Popup Move Errors"), args, 1);
2941     }
2942     if (appData.premove) {
2943         XtSetValues(XtNameToWidget(menuBarWidget,
2944                                    "menuOptions.Premove"), args, 1);
2945     }
2946     if (appData.quietPlay) {
2947         XtSetValues(XtNameToWidget(menuBarWidget,
2948                                    "menuOptions.Quiet Play"), args, 1);
2949     }
2950     if (appData.showCoords) {
2951         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
2952                     args, 1);
2953     }
2954     if (appData.hideThinkingFromHuman) {
2955         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
2956                     args, 1);
2957     }
2958     if (appData.testLegality) {
2959         XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
2960                     args, 1);
2961     }
2962
2963     /*
2964      * Create an icon.
2965      */
2966     ReadBitmap(&wIconPixmap, "icon_white.bm",
2967                icon_white_bits, icon_white_width, icon_white_height);
2968     ReadBitmap(&bIconPixmap, "icon_black.bm",
2969                icon_black_bits, icon_black_width, icon_black_height);
2970     iconPixmap = wIconPixmap;
2971     i = 0;
2972     XtSetArg(args[i], XtNiconPixmap, iconPixmap);  i++;
2973     XtSetValues(shellWidget, args, i);
2974
2975     /*
2976      * Create a cursor for the board widget.
2977      */
2978     window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
2979     XChangeWindowAttributes(xDisplay, xBoardWindow,
2980                             CWCursor, &window_attributes);
2981
2982     /*
2983      * Inhibit shell resizing.
2984      */
2985     shellArgs[0].value = (XtArgVal) &w;
2986     shellArgs[1].value = (XtArgVal) &h;
2987     XtGetValues(shellWidget, shellArgs, 2);
2988     shellArgs[4].value = shellArgs[2].value = w;
2989     shellArgs[5].value = shellArgs[3].value = h;
2990     XtSetValues(shellWidget, &shellArgs[2], 4);
2991     marginW =  w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
2992     marginH =  h - boardHeight;
2993
2994     CatchDeleteWindow(shellWidget, "QuitProc");
2995
2996     CreateGCs();
2997     CreateGrid();
2998 #if HAVE_LIBXPM
2999     if (appData.bitmapDirectory[0] != NULLCHAR) {
3000       CreatePieces();
3001     } else {
3002       CreateXPMPieces();
3003     }
3004 #else
3005     CreateXIMPieces();
3006     /* Create regular pieces */
3007     if (!useImages) CreatePieces();
3008 #endif
3009
3010     CreatePieceMenus();
3011
3012     if (appData.animate || appData.animateDragging)
3013       CreateAnimVars();
3014
3015     XtAugmentTranslations(formWidget,
3016                           XtParseTranslationTable(globalTranslations));
3017     XtAugmentTranslations(boardWidget,
3018                           XtParseTranslationTable(boardTranslations));
3019     XtAugmentTranslations(whiteTimerWidget,
3020                           XtParseTranslationTable(whiteTranslations));
3021     XtAugmentTranslations(blackTimerWidget,
3022                           XtParseTranslationTable(blackTranslations));
3023
3024     /* Why is the following needed on some versions of X instead
3025      * of a translation? */
3026     XtAddEventHandler(boardWidget, ExposureMask, False,
3027                       (XtEventHandler) EventProc, NULL);
3028     /* end why */
3029
3030     InitBackEnd2();
3031
3032     if (errorExitStatus == -1) {
3033         if (appData.icsActive) {
3034             /* We now wait until we see "login:" from the ICS before
3035                sending the logon script (problems with timestamp otherwise) */
3036             /*ICSInitScript();*/
3037             if (appData.icsInputBox) ICSInputBoxPopUp();
3038         }
3039
3040         signal(SIGINT, IntSigHandler);
3041         signal(SIGTERM, IntSigHandler);
3042         if (*appData.cmailGameName != NULLCHAR) {
3043             signal(SIGUSR1, CmailSigHandler);
3044         }
3045     }
3046         InitPosition(TRUE);
3047
3048     XtAppMainLoop(appContext);
3049     if (appData.debugMode) fclose(debugFP); // [DM] debug
3050     return 0;
3051 }
3052
3053 void
3054 ShutDownFrontEnd()
3055 {
3056     if (appData.icsActive && oldICSInteractionTitle != NULL) {
3057         DisplayIcsInteractionTitle(oldICSInteractionTitle);
3058     }
3059     unlink(gameCopyFilename);
3060     unlink(gamePasteFilename);
3061 }
3062
3063 RETSIGTYPE
3064 IntSigHandler(sig)
3065      int sig;
3066 {
3067     ExitEvent(sig);
3068 }
3069
3070 RETSIGTYPE
3071 CmailSigHandler(sig)
3072      int sig;
3073 {
3074     int dummy = 0;
3075     int error;
3076
3077     signal(SIGUSR1, SIG_IGN);   /* suspend handler     */
3078
3079     /* Activate call-back function CmailSigHandlerCallBack()             */
3080     OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
3081
3082     signal(SIGUSR1, CmailSigHandler); /* re-activate handler */
3083 }
3084
3085 void
3086 CmailSigHandlerCallBack(isr, closure, message, count, error)
3087      InputSourceRef isr;
3088      VOIDSTAR closure;
3089      char *message;
3090      int count;
3091      int error;
3092 {
3093     BoardToTop();
3094     ReloadCmailMsgEvent(TRUE);  /* Reload cmail msg  */
3095 }
3096 /**** end signal code ****/
3097
3098
3099 void
3100 ICSInitScript()
3101 {
3102     FILE *f;
3103     char buf[MSG_SIZ];
3104     char *p;
3105
3106     f = fopen(appData.icsLogon, "r");
3107     if (f == NULL) {
3108         p = getenv("HOME");
3109         if (p != NULL) {
3110             strcpy(buf, p);
3111             strcat(buf, "/");
3112             strcat(buf, appData.icsLogon);
3113             f = fopen(buf, "r");
3114         }
3115     }
3116     if (f != NULL)
3117       ProcessICSInitScript(f);
3118 }
3119
3120 void
3121 ResetFrontEnd()
3122 {
3123     CommentPopDown();
3124     EditCommentPopDown();
3125     TagsPopDown();
3126     return;
3127 }
3128
3129 typedef struct {
3130     char *name;
3131     Boolean value;
3132 } Enables;
3133
3134 void
3135 SetMenuEnables(enab)
3136      Enables *enab;
3137 {
3138   Widget w;
3139   if (!menuBarWidget) return;
3140   while (enab->name != NULL) {
3141     w = XtNameToWidget(menuBarWidget, enab->name);
3142     if (w == NULL) {
3143       DisplayError(enab->name, 0);
3144     } else {
3145       XtSetSensitive(w, enab->value);
3146     }
3147     enab++;
3148   }
3149 }
3150
3151 Enables icsEnables[] = {
3152     { "menuFile.Mail Move", False },
3153     { "menuFile.Reload CMail Message", False },
3154     { "menuMode.Machine Black", False },
3155     { "menuMode.Machine White", False },
3156     { "menuMode.Analysis Mode", False },
3157     { "menuMode.Analyze File", False },
3158     { "menuMode.Two Machines", False },
3159 #ifndef ZIPPY
3160     { "menuHelp.Hint", False },
3161     { "menuHelp.Book", False },
3162     { "menuStep.Move Now", False },
3163     { "menuOptions.Periodic Updates", False },
3164     { "menuOptions.Hide Thinking", False },
3165     { "menuOptions.Ponder Next Move", False },
3166 #endif
3167     { NULL, False }
3168 };
3169
3170 Enables ncpEnables[] = {
3171     { "menuFile.Mail Move", False },
3172     { "menuFile.Reload CMail Message", False },
3173     { "menuMode.Machine White", False },
3174     { "menuMode.Machine Black", False },
3175     { "menuMode.Analysis Mode", False },
3176     { "menuMode.Analyze File", False },
3177     { "menuMode.Two Machines", False },
3178     { "menuMode.ICS Client", False },
3179     { "menuMode.ICS Input Box", False },
3180     { "Action", False },
3181     { "menuStep.Revert", False },
3182     { "menuStep.Move Now", False },
3183     { "menuStep.Retract Move", False },
3184     { "menuOptions.Auto Comment", False },
3185     { "menuOptions.Auto Flag", False },
3186     { "menuOptions.Auto Flip View", False },
3187     { "menuOptions.Auto Observe", False },
3188     { "menuOptions.Auto Raise Board", False },
3189     { "menuOptions.Get Move List", False },
3190     { "menuOptions.ICS Alarm", False },
3191     { "menuOptions.Move Sound", False },
3192     { "menuOptions.Quiet Play", False },
3193     { "menuOptions.Hide Thinking", False },
3194     { "menuOptions.Periodic Updates", False },
3195     { "menuOptions.Ponder Next Move", False },
3196     { "menuHelp.Hint", False },
3197     { "menuHelp.Book", False },
3198     { NULL, False }
3199 };
3200
3201 Enables gnuEnables[] = {
3202     { "menuMode.ICS Client", False },
3203     { "menuMode.ICS Input Box", False },
3204     { "menuAction.Accept", False },
3205     { "menuAction.Decline", False },
3206     { "menuAction.Rematch", False },
3207     { "menuAction.Adjourn", False },
3208     { "menuAction.Stop Examining", False },
3209     { "menuAction.Stop Observing", False },
3210     { "menuStep.Revert", False },
3211     { "menuOptions.Auto Comment", False },
3212     { "menuOptions.Auto Observe", False },
3213     { "menuOptions.Auto Raise Board", False },
3214     { "menuOptions.Get Move List", False },
3215     { "menuOptions.Premove", False },
3216     { "menuOptions.Quiet Play", False },
3217
3218     /* The next two options rely on SetCmailMode being called *after*    */
3219     /* SetGNUMode so that when GNU is being used to give hints these     */
3220     /* menu options are still available                                  */
3221
3222     { "menuFile.Mail Move", False },
3223     { "menuFile.Reload CMail Message", False },
3224     { NULL, False }
3225 };
3226
3227 Enables cmailEnables[] = {
3228     { "Action", True },
3229     { "menuAction.Call Flag", False },
3230     { "menuAction.Draw", True },
3231     { "menuAction.Adjourn", False },
3232     { "menuAction.Abort", False },
3233     { "menuAction.Stop Observing", False },
3234     { "menuAction.Stop Examining", False },
3235     { "menuFile.Mail Move", True },
3236     { "menuFile.Reload CMail Message", True },
3237     { NULL, False }
3238 };
3239
3240 Enables trainingOnEnables[] = {
3241   { "menuMode.Edit Comment", False },
3242   { "menuMode.Pause", False },
3243   { "menuStep.Forward", False },
3244   { "menuStep.Backward", False },
3245   { "menuStep.Forward to End", False },
3246   { "menuStep.Back to Start", False },
3247   { "menuStep.Move Now", False },
3248   { "menuStep.Truncate Game", False },
3249   { NULL, False }
3250 };
3251
3252 Enables trainingOffEnables[] = {
3253   { "menuMode.Edit Comment", True },
3254   { "menuMode.Pause", True },
3255   { "menuStep.Forward", True },
3256   { "menuStep.Backward", True },
3257   { "menuStep.Forward to End", True },
3258   { "menuStep.Back to Start", True },
3259   { "menuStep.Move Now", True },
3260   { "menuStep.Truncate Game", True },
3261   { NULL, False }
3262 };
3263
3264 Enables machineThinkingEnables[] = {
3265   { "menuFile.Load Game", False },
3266   { "menuFile.Load Next Game", False },
3267   { "menuFile.Load Previous Game", False },
3268   { "menuFile.Reload Same Game", False },
3269   { "menuFile.Paste Game", False },
3270   { "menuFile.Load Position", False },
3271   { "menuFile.Load Next Position", False },
3272   { "menuFile.Load Previous Position", False },
3273   { "menuFile.Reload Same Position", False },
3274   { "menuFile.Paste Position", False },
3275   { "menuMode.Machine White", False },
3276   { "menuMode.Machine Black", False },
3277   { "menuMode.Two Machines", False },
3278   { "menuStep.Retract Move", False },
3279   { NULL, False }
3280 };
3281
3282 Enables userThinkingEnables[] = {
3283   { "menuFile.Load Game", True },
3284   { "menuFile.Load Next Game", True },
3285   { "menuFile.Load Previous Game", True },
3286   { "menuFile.Reload Same Game", True },
3287   { "menuFile.Paste Game", True },
3288   { "menuFile.Load Position", True },
3289   { "menuFile.Load Next Position", True },
3290   { "menuFile.Load Previous Position", True },
3291   { "menuFile.Reload Same Position", True },
3292   { "menuFile.Paste Position", True },
3293   { "menuMode.Machine White", True },
3294   { "menuMode.Machine Black", True },
3295   { "menuMode.Two Machines", True },
3296   { "menuStep.Retract Move", True },
3297   { NULL, False }
3298 };
3299
3300 void SetICSMode()
3301 {
3302   SetMenuEnables(icsEnables);
3303
3304 #ifdef ZIPPY
3305   if (appData.zippyPlay && !appData.noChessProgram)   /* [DM] icsEngineAnalyze */
3306      XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
3307 #endif
3308 }
3309
3310 void
3311 SetNCPMode()
3312 {
3313   SetMenuEnables(ncpEnables);
3314 }
3315
3316 void
3317 SetGNUMode()
3318 {
3319   SetMenuEnables(gnuEnables);
3320 }
3321
3322 void
3323 SetCmailMode()
3324 {
3325   SetMenuEnables(cmailEnables);
3326 }
3327
3328 void
3329 SetTrainingModeOn()
3330 {
3331   SetMenuEnables(trainingOnEnables);
3332   if (appData.showButtonBar) {
3333     XtSetSensitive(buttonBarWidget, False);
3334   }
3335   CommentPopDown();
3336 }
3337
3338 void
3339 SetTrainingModeOff()
3340 {
3341   SetMenuEnables(trainingOffEnables);
3342   if (appData.showButtonBar) {
3343     XtSetSensitive(buttonBarWidget, True);
3344   }
3345 }
3346
3347 void
3348 SetUserThinkingEnables()
3349 {
3350   if (appData.noChessProgram) return;
3351   SetMenuEnables(userThinkingEnables);
3352 }
3353
3354 void
3355 SetMachineThinkingEnables()
3356 {
3357   if (appData.noChessProgram) return;
3358   SetMenuEnables(machineThinkingEnables);
3359   switch (gameMode) {
3360   case MachinePlaysBlack:
3361   case MachinePlaysWhite:
3362   case TwoMachinesPlay:
3363     XtSetSensitive(XtNameToWidget(menuBarWidget,
3364                                   ModeToWidgetName(gameMode)), True);
3365     break;
3366   default:
3367     break;
3368   }
3369 }
3370
3371 #define Abs(n) ((n)<0 ? -(n) : (n))
3372
3373 /*
3374  * Find a font that matches "pattern" that is as close as
3375  * possible to the targetPxlSize.  Prefer fonts that are k
3376  * pixels smaller to fonts that are k pixels larger.  The
3377  * pattern must be in the X Consortium standard format,
3378  * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
3379  * The return value should be freed with XtFree when no
3380  * longer needed.
3381  */
3382 char *FindFont(pattern, targetPxlSize)
3383      char *pattern;
3384      int targetPxlSize;
3385 {
3386     char **fonts, *p, *best, *scalable, *scalableTail;
3387     int i, j, nfonts, minerr, err, pxlSize;
3388
3389 #ifdef ENABLE_NLS
3390     char **missing_list;
3391     int missing_count;
3392     char *def_string, *base_fnt_lst, strInt[3];
3393     XFontSet fntSet;
3394     XFontStruct **fnt_list;
3395
3396     base_fnt_lst = calloc(1, strlen(pattern) + 3);
3397     sprintf(strInt, "%d", targetPxlSize);
3398     p = strstr(pattern, "--");
3399     strncpy(base_fnt_lst, pattern, p - pattern + 2);
3400     strcat(base_fnt_lst, strInt);
3401     strcat(base_fnt_lst, strchr(p + 2, '-'));
3402
3403     if ((fntSet = XCreateFontSet(xDisplay,
3404                                  base_fnt_lst,
3405                                  &missing_list,
3406                                  &missing_count,
3407                                  &def_string)) == NULL) {
3408
3409        fprintf(stderr, _("Unable to create font set.\n"));
3410        exit (2);
3411     }
3412
3413     nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
3414 #else
3415     fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
3416     if (nfonts < 1) {
3417         fprintf(stderr, _("%s: no fonts match pattern %s\n"),
3418                 programName, pattern);
3419         exit(2);
3420     }
3421 #endif
3422
3423     best = fonts[0];
3424     scalable = NULL;
3425     minerr = 999999;
3426     for (i=0; i<nfonts; i++) {
3427         j = 0;
3428         p = fonts[i];
3429         if (*p != '-') continue;
3430         while (j < 7) {
3431             if (*p == NULLCHAR) break;
3432             if (*p++ == '-') j++;
3433         }
3434         if (j < 7) continue;
3435         pxlSize = atoi(p);
3436         if (pxlSize == 0) {
3437             scalable = fonts[i];
3438             scalableTail = p;
3439         } else {
3440             err = pxlSize - targetPxlSize;
3441             if (Abs(err) < Abs(minerr) ||
3442                 (minerr > 0 && err < 0 && -err == minerr)) {
3443                 best = fonts[i];
3444                 minerr = err;
3445             }
3446         }
3447     }
3448     if (scalable && Abs(minerr) > appData.fontSizeTolerance) {
3449         /* If the error is too big and there is a scalable font,
3450            use the scalable font. */
3451         int headlen = scalableTail - scalable;
3452         p = (char *) XtMalloc(strlen(scalable) + 10);
3453         while (isdigit(*scalableTail)) scalableTail++;
3454         sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
3455     } else {
3456         p = (char *) XtMalloc(strlen(best) + 1);
3457         strcpy(p, best);
3458     }
3459     if (appData.debugMode) {
3460         fprintf(debugFP, _("resolved %s at pixel size %d\n  to %s\n"),
3461                 pattern, targetPxlSize, p);
3462     }
3463 #ifdef ENABLE_NLS
3464     if (missing_count > 0)
3465        XFreeStringList(missing_list);
3466     XFreeFontSet(xDisplay, fntSet);
3467 #else
3468      XFreeFontNames(fonts);
3469 #endif
3470     return p;
3471 }
3472
3473 void CreateGCs()
3474 {
3475     XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
3476       | GCBackground | GCFunction | GCPlaneMask;
3477     XGCValues gc_values;
3478     GC copyInvertedGC;
3479
3480     gc_values.plane_mask = AllPlanes;
3481     gc_values.line_width = lineGap;
3482     gc_values.line_style = LineSolid;
3483     gc_values.function = GXcopy;
3484
3485     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3486     gc_values.background = XBlackPixel(xDisplay, xScreen);
3487     lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3488
3489     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3490     gc_values.background = XWhitePixel(xDisplay, xScreen);
3491     coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
3492     XSetFont(xDisplay, coordGC, coordFontID);
3493
3494     // [HGM] make font for holdings counts (white on black0
3495     gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3496     gc_values.background = XBlackPixel(xDisplay, xScreen);
3497     countGC = XtGetGC(shellWidget, value_mask, &gc_values);
3498     XSetFont(xDisplay, countGC, countFontID);
3499
3500     if (appData.monoMode) {
3501         gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3502         gc_values.background = XWhitePixel(xDisplay, xScreen);
3503         highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3504
3505         gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3506         gc_values.background = XBlackPixel(xDisplay, xScreen);
3507         lightSquareGC = wbPieceGC
3508           = XtGetGC(shellWidget, value_mask, &gc_values);
3509
3510         gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3511         gc_values.background = XWhitePixel(xDisplay, xScreen);
3512         darkSquareGC = bwPieceGC
3513           = XtGetGC(shellWidget, value_mask, &gc_values);
3514
3515         if (DefaultDepth(xDisplay, xScreen) == 1) {
3516             /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
3517             gc_values.function = GXcopyInverted;
3518             copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
3519             gc_values.function = GXcopy;
3520             if (XBlackPixel(xDisplay, xScreen) == 1) {
3521                 bwPieceGC = darkSquareGC;
3522                 wbPieceGC = copyInvertedGC;
3523             } else {
3524                 bwPieceGC = copyInvertedGC;
3525                 wbPieceGC = lightSquareGC;
3526             }
3527         }
3528     } else {
3529         gc_values.foreground = highlightSquareColor;
3530         gc_values.background = highlightSquareColor;
3531         highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);