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