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