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