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