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