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