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