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