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